<commit_before>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.karaf.shell.ssh;

import org.apache.mina.util.Base64;
import org.apache.sshd.server.PublickeyAuthenticator;
import org.apache.sshd.server.session.ServerSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.util.*;

/**
 * A public key authenticator, which reads an OpenSSL2 <code>authorized_keys</code> file.
 */
public class KarafPublickeyAuthenticator implements PublickeyAuthenticator {

    private static final transient Logger LOGGER = LoggerFactory.getLogger(KarafPublickeyAuthenticator.class);

    private String authorizedKeys;
    private boolean active;

    public static final class AuthorizedKey {

        private final String alias;
        private final String format;
        private final PublicKey publicKey;

        public AuthorizedKey(String alias, String format, PublicKey publicKey) {
            super();
            this.alias = alias;
            this.format = format;
            this.publicKey = publicKey;
        }

        public String getAlias() {
            return this.alias;
        }
        
        public String getFormat() {
            return this.format;
        }

        public PublicKey getPublicKey() {
            return this.publicKey;
        }

    }

    private static final class PublicKeyComparator implements Comparator<PublicKey> {

        public int compare(PublicKey a, PublicKey b) {
            if (a instanceof DSAPublicKey) {
                if (b instanceof DSAPublicKey) {
                    DSAPublicKey da = (DSAPublicKey) a;
                    DSAPublicKey db = (DSAPublicKey) b;
                    int r = da.getParams().getG().compareTo(db.getParams().getG());
                    if (r != 0) {
                        return r;
                    }
                    r = da.getParams().getP().compareTo(db.getParams().getP());
                    if (r != 0) {
                        return r;
                    }
                    r = da.getParams().getQ().compareTo(db.getParams().getQ());
                    if (r != 0) {
                        return r;
                    }
                    return da.getY().compareTo(db.getY());
                } else {
                    return -1;
                }
            } else if (a instanceof RSAPublicKey) {
                if (b instanceof RSAPublicKey) {
                    RSAPublicKey da = (RSAPublicKey) a;
                    RSAPublicKey db = (RSAPublicKey) b;
                    int r = da.getPublicExponent().compareTo(db.getPublicExponent());
                    if (r != 0) {
                        return r;
                    }
                    return da.getModulus().compareTo(db.getModulus());
                } else {
                    return -1;
                }
            } else {
                throw new IllegalArgumentException("Only RSA and DAS keys are supported.");
            }
        }
    }

    private final class AuthorizedKeysProvider extends TimerTask {

        private Map<PublicKey, AuthorizedKey> keys;
        private Long lastModificationDate;
        private Boolean fileAvailable;

        @Override
        public void run() {
            try {
                File af = new File(KarafPublickeyAuthenticator.this.authorizedKeys);
                if (af.exists()) {
                    Long newModificationDate = Long.valueOf(af.lastModified());
                    if ((this.fileAvailable != null && !this.fileAvailable.booleanValue()) || !newModificationDate.equals(this.lastModificationDate)) {
                        LOGGER.info("Parsing authorized keys file {}...", KarafPublickeyAuthenticator.this.authorizedKeys);
                        this.fileAvailable = Boolean.TRUE;
                        this.lastModificationDate = newModificationDate;
                        Map<PublicKey, AuthorizedKey> newKeys = KarafPublickeyAuthenticator.parseAuthorizedKeys(new FileInputStream(af));
                        this.setKeys(newKeys);
                        LOGGER.info("Successfully parsed {} keys from file {}", newKeys.size(), KarafPublickeyAuthenticator.this.authorizedKeys);
                    }
                } else {
                    if (this.fileAvailable != null && this.fileAvailable.booleanValue()) {
                        LOGGER.info("Authorized keys file {} disappeared, will recheck every minute", KarafPublickeyAuthenticator.this.authorizedKeys);
                    } else if (this.fileAvailable == null) {
                        LOGGER.info("Authorized keys file {} does not exist, will recheck every minute", KarafPublickeyAuthenticator.this.authorizedKeys);
                    }<commit_msg>[KARAF-1388] Change the log level used in KarafPublickeyAuthenticator<commit_after>/*
 * Licensed to the Apache Software Foundation (ASF) under one
 * or more contributor license agreements.  See the NOTICE file
 * distributed with this work for additional information
 * regarding copyright ownership.  The ASF licenses this file
 * to you under the Apache License, Version 2.0 (the
 * "License"); you may not use this file except in compliance
 * with the License.  You may obtain a copy of the License at
 *
 *  http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing,
 * software distributed under the License is distributed on an
 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 * KIND, either express or implied.  See the License for the
 * specific language governing permissions and limitations
 * under the License.
 */
package org.apache.karaf.shell.ssh;

import org.apache.mina.util.Base64;
import org.apache.sshd.server.PublickeyAuthenticator;
import org.apache.sshd.server.session.ServerSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.math.BigInteger;
import java.security.KeyFactory;
import java.security.NoSuchAlgorithmException;
import java.security.PublicKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.security.spec.DSAPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPublicKeySpec;
import java.util.*;

/**
 * A public key authenticator, which reads an OpenSSL2 <code>authorized_keys</code> file.
 */
public class KarafPublickeyAuthenticator implements PublickeyAuthenticator {

    private static final transient Logger LOGGER = LoggerFactory.getLogger(KarafPublickeyAuthenticator.class);

    private String authorizedKeys;
    private boolean active;

    public static final class AuthorizedKey {

        private final String alias;
        private final String format;
        private final PublicKey publicKey;

        public AuthorizedKey(String alias, String format, PublicKey publicKey) {
            super();
            this.alias = alias;
            this.format = format;
            this.publicKey = publicKey;
        }

        public String getAlias() {
            return this.alias;
        }
        
        public String getFormat() {
            return this.format;
        }

        public PublicKey getPublicKey() {
            return this.publicKey;
        }

    }

    private static final class PublicKeyComparator implements Comparator<PublicKey> {

        public int compare(PublicKey a, PublicKey b) {
            if (a instanceof DSAPublicKey) {
                if (b instanceof DSAPublicKey) {
                    DSAPublicKey da = (DSAPublicKey) a;
                    DSAPublicKey db = (DSAPublicKey) b;
                    int r = da.getParams().getG().compareTo(db.getParams().getG());
                    if (r != 0) {
                        return r;
                    }
                    r = da.getParams().getP().compareTo(db.getParams().getP());
                    if (r != 0) {
                        return r;
                    }
                    r = da.getParams().getQ().compareTo(db.getParams().getQ());
                    if (r != 0) {
                        return r;
                    }
                    return da.getY().compareTo(db.getY());
                } else {
                    return -1;
                }
            } else if (a instanceof RSAPublicKey) {
                if (b instanceof RSAPublicKey) {
                    RSAPublicKey da = (RSAPublicKey) a;
                    RSAPublicKey db = (RSAPublicKey) b;
                    int r = da.getPublicExponent().compareTo(db.getPublicExponent());
                    if (r != 0) {
                        return r;
                    }
                    return da.getModulus().compareTo(db.getModulus());
                } else {
                    return -1;
                }
            } else {
                throw new IllegalArgumentException("Only RSA and DAS keys are supported.");
            }
        }
    }

    private final class AuthorizedKeysProvider extends TimerTask {

        private Map<PublicKey, AuthorizedKey> keys;
        private Long lastModificationDate;
        private Boolean fileAvailable;

        @Override
        public void run() {
            try {
                File af = new File(KarafPublickeyAuthenticator.this.authorizedKeys);
                if (af.exists()) {
                    Long newModificationDate = Long.valueOf(af.lastModified());
                    if ((this.fileAvailable != null && !this.fileAvailable.booleanValue()) || !newModificationDate.equals(this.lastModificationDate)) {
                        LOGGER.debug("Parsing authorized keys file {}...", KarafPublickeyAuthenticator.this.authorizedKeys);
                        this.fileAvailable = Boolean.TRUE;
                        this.lastModificationDate = newModificationDate;
                        Map<PublicKey, AuthorizedKey> newKeys = KarafPublickeyAuthenticator.parseAuthorizedKeys(new FileInputStream(af));
                        this.setKeys(newKeys);
                        LOGGER.debug("Successfully parsed {} keys from file {}", newKeys.size(), KarafPublickeyAuthenticator.this.authorizedKeys);
                    }
                } else {
                    if (this.fileAvailable != null && this.fileAvailable.booleanValue()) {
                        LOGGER.debug("Authorized keys file {} disappeared, will recheck every minute", KarafPublickeyAuthenticator.this.authorizedKeys);
                    } else if (this.fileAvailable == null) {
                        LOGGER.debug("Authorized keys file {} does not exist, will recheck every minute", KarafPublickeyAuthenticator.this.authorizedKeys);
                    }
{'fraction_non_alphanumeric': 0.08498224251648909, 'fraction_numerical': 0.0028750211398613224, 'mean_word_length': 1.9828499369482977, 'pattern_counts': {'":': 0, '<': 13, '<?xml version=': 0, '>': 13, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '6276065', 'n_tokens_mistral': 3005, 'n_tokens_neox': 2860, 'n_words': 813}