All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.ow2.petals.bc.sftp.authentication.SshPublicKeyAuthentication Maven / Gradle / Ivy

There is a newer version: 1.3.0
Show newest version
/**
 * Copyright (c) 2009-2012 EBM WebSourcing, 2012-2016 Linagora
 * 
 * This program/library is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License as published by
 * the Free Software Foundation, either version 2.1 of the License, or (at your
 * option) any later version.
 * 
 * This program/library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
 * for more details.
 * 
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program/library; If not, see http://www.gnu.org/licenses/
 * for the GNU Lesser General Public License version 2.1.
 */
package org.ow2.petals.bc.sftp.authentication;

import java.io.File;
import java.io.IOException;

import org.ow2.petals.bc.sftp.authentication.exception.AuthenticationException;
import org.ow2.petals.bc.sftp.authentication.exception.PassphraseMissingException;
import org.ow2.petals.bc.sftp.authentication.exception.PrivateKeyFileMissingException;

import com.ebmwebsourcing.easycommons.lang.StringHelper;
import com.sshtools.j2ssh.authentication.PublicKeyAuthenticationClient;
import com.sshtools.j2ssh.authentication.SshAuthenticationClient;
import com.sshtools.j2ssh.transport.publickey.InvalidSshKeyException;
import com.sshtools.j2ssh.transport.publickey.SshPrivateKey;
import com.sshtools.j2ssh.transport.publickey.SshPrivateKeyFile;

/**
 * Utility class used to authenticate a client onto a SSH server using a public
 * key.
 * 
 * NOTE : This method of authentication uses public-key cryptography to verify
 * the user's identity. The user can access an account on an SSH server by
 * proving that they possess a private key. The key is authorized if it is
 * contained within the user's authorization file.
 * 
 * NOTE : when using this authentication method, key MUST be stored on the same
 * server as PEtALS. We can attach private key with XML message, but this is not
 * a good solution, since private key might not be private anymore.
 * 
 * @author Charles Casadei - EBM WebSourcing
 */
public final class SshPublicKeyAuthentication extends SshAuthentication {

    /**
     * Path to the private key file.
     */
    private final String pathToPrivateKeyFile;

    /**
     * Passphrase associated to the private key.
     */
    private final String passphrase;

    /**
     * Default constructor. Initialize the user the private key and the
     * passphrase holded by an instance of this class with the given values
     * 
     * @param user
     *            the username used for SSH user / private key authentication
     * @param pathToPrivateKey
     *            the PrivateKey used for SSH user / private key authentication
     * @param passphrase
     *            the optional passphrase used for SSH user / private key
     *            authentication
     * @throws AuthenticationException
     */
    public SshPublicKeyAuthentication(final String user, final String pathToPrivateKey,
            final String passphrase) throws AuthenticationException {
        super(user);

        // Sets the path to the private key
        this.pathToPrivateKeyFile = pathToPrivateKey;

        // Sets the passphrase
        this.passphrase = passphrase;

        // Validates the configuration
        this.validate();
    }

    /**
     * Builds the object used by the SFTPClientPool to perform the
     * authentication on the SSH server.
     * 
     * @return an object used by the SFTPClientPool to perform the
     *         authentication
     * @throws SshAuthenticationException
     */
    @Override
    public final SshAuthenticationClient getAuthenticationClient() throws IOException {

        // Instanciate a new public key
        PublicKeyAuthenticationClient publicKeyAuth = new PublicKeyAuthenticationClient();

        // Sets the username of the public key
        publicKeyAuth.setUsername(this.getUser());

        // Gets the private key using the given path to the private key file
        SshPrivateKeyFile sshPrivateKey = null;
        final File sshPrivateKeyFile = new File(this.pathToPrivateKeyFile);
        try {
            sshPrivateKey = SshPrivateKeyFile.parse(sshPrivateKeyFile);
        } catch (InvalidSshKeyException ex) {
            StringBuilder errorSB = new StringBuilder();
            errorSB.append("Invalid SSH key : ");
            throw new IOException(errorSB.toString(), ex);
        } catch (IOException ex) {
            StringBuilder errorSB = new StringBuilder();
            errorSB.append("Private key location: [" + sshPrivateKeyFile.getAbsolutePath()
                    + "]. IO Exception : ");
            throw new IOException(errorSB.toString(), ex);
        }

        // If there is a passphrase
        if (!StringHelper.isNullOrEmpty(this.passphrase)) {
            // Try to match passphrase & private key
            SshPrivateKey key = null;
            try {
                key = sshPrivateKey.toPrivateKey(this.passphrase);
            } catch (InvalidSshKeyException ex) {
                StringBuilder errorSB = new StringBuilder();
                errorSB.append("Invalid SSH key (passphrase does not match) : ");
                throw new IOException(errorSB.toString(), ex);
            }

            // Try to build the public key
            if (key != null) {
                publicKeyAuth.setKey(key);
            } else { // We theoriticaly can't end up there...but who knows :-)
                StringBuilder errorSB = new StringBuilder();
                errorSB.append("No valid private key found");
                throw new IOException(errorSB.toString());
            }
        }

        return publicKeyAuth;
    }

    /**
     * Builds & returns a portion of the key used by the SFTPClientPool to
     * identify a SSH session.
     * 
     * @return a portion of the key used by the SFTPClientPool
     */
    @Override
    public final String getKey() {
        return this.getUser() + this.pathToPrivateKeyFile + this.passphrase;
    }

    /**
     * Return the object content as String (Overrides the toString method).
     * 
     * @return the object content as String
     */
    @Override
    public final String toString() {
        return super.toString() + "pathToPrivateKey=" + this.pathToPrivateKeyFile
                + " ; passphrase=" + this.passphrase + ")";
    }

    /**
     * Checks if the given informations are OK.
     * 
     * @throws AuthenticationException
     *             if the configuration is not valid
     */
    private final void validate() throws AuthenticationException {

        // Checks if there is a private key
        if (StringHelper.isNullOrEmpty(this.pathToPrivateKeyFile)) {
            throw new PrivateKeyFileMissingException();
        }

        // Checks if there is a passphrase
        if ((StringHelper.isNullOrEmpty(this.passphrase))) {
            throw new PassphraseMissingException();
        }
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy