alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Glassfish example source code file (SSHLauncher.java)

This example Glassfish source code file (SSHLauncher.java) is included in the DevDaily.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Java - Glassfish tags/keywords

bytearrayoutputstream, connection, file, file, interruptedexception, io, ioexception, ioexception, log, logging, outputstream, pumpthread, sftpclient, ssh, ssh, string, string, util

The Glassfish SSHLauncher.java source code

/*
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
 *
 * Copyright (c) 1997-2010 Oracle and/or its affiliates. All rights reserved.
 *
 * The contents of this file are subject to the terms of either the GNU
 * General Public License Version 2 only ("GPL") or the Common Development
 * and Distribution License("CDDL") (collectively, the "License").  You
 * may not use this file except in compliance with the License.  You can
 * obtain a copy of the License at
 * https://glassfish.dev.java.net/public/CDDL+GPL_1_1.html
 * or packager/legal/LICENSE.txt.  See the License for the specific
 * language governing permissions and limitations under the License.
 *
 * When distributing the software, include this License Header Notice in each
 * file and include the License file at packager/legal/LICENSE.txt.
 *
 * GPL Classpath Exception:
 * Oracle designates this particular file as subject to the "Classpath"
 * exception as provided by Oracle in the GPL Version 2 section of the License
 * file that accompanied this code.
 *
 * Modifications:
 * If applicable, add the following below the License Header, with the fields
 * enclosed by brackets [] replaced by your own identifying information:
 * "Portions Copyright [year] [name of copyright owner]"
 *
 * Contributor(s):
 * If you wish your version of this file to be governed by only the CDDL or
 * only the GPL Version 2, indicate your decision by adding "[Contributor]
 * elects to include this software in this distribution under the [CDDL or GPL
 * Version 2] license."  If you don't indicate a single choice of license, a
 * recipient has the option to distribute your version of this file under
 * either the CDDL, the GPL Version 2 or to extend the choice of license to
 * its licensees as provided above.  However, if you add GPL Version 2 code
 * and therefore, elected the GPL Version 2 license, then the option applies
 * only if the new code is made subject to such option by the copyright
 * holder.
 */

package org.glassfish.cluster.ssh.launcher;

import com.trilead.ssh2.ChannelCondition;
import com.trilead.ssh2.Session;
import java.io.*;

import com.sun.enterprise.util.StringUtils;
import com.sun.enterprise.util.OS;
import com.sun.enterprise.util.io.FileUtils;

import com.sun.enterprise.universal.process.ProcessManager;
import com.sun.enterprise.universal.process.ProcessManagerException;
import com.sun.enterprise.universal.process.ProcessUtils;

import com.trilead.ssh2.Connection;
import com.trilead.ssh2.KnownHosts;
import com.trilead.ssh2.SCPClient;
import org.glassfish.internal.api.RelativePathResolver;
import org.glassfish.cluster.ssh.util.HostVerifier;
import org.glassfish.cluster.ssh.util.SSHUtil;
import org.jvnet.hk2.annotations.Inject;
import org.jvnet.hk2.annotations.Service;
import org.jvnet.hk2.annotations.Scoped;
import org.jvnet.hk2.component.Habitat;
import org.jvnet.hk2.component.PerLookup;
import com.sun.enterprise.config.serverbeans.SshConnector;
import com.sun.enterprise.config.serverbeans.SshAuth;
import com.sun.enterprise.config.serverbeans.Node;
import org.glassfish.cluster.ssh.sftp.SFTPClient;

import java.io.OutputStream;
import java.io.File;
import java.io.IOException;
import java.io.FileNotFoundException;
import java.util.Arrays;
import java.util.List;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 * @author Rajiv Mordani
 */


@Service(name="SSHLauncher")
@Scoped(PerLookup.class)
public class SSHLauncher {

    private static final String SSH_DIR = ".ssh" + File.separator;
    private static final String AUTH_KEY_FILE = "authorized_keys";
    private static final int DEFAULT_TIMEOUT_MSEC = 120000; // 2 minutes
    private static final String SSH_KEYGEN = "ssh-keygen";
    private static final char LINE_SEP = System.getProperty("line.separator").charAt(0);
    
  /**
     * Database of known hosts.
     */
    private static KnownHosts knownHostsDatabase = new KnownHosts();

  /**
     * The host name which to connect to via ssh
     */
    private String host;

  /**
     * The port on which the ssh daemon is running
     */
    private int port;

  /**
     * The user name to use for authenticating with the ssh daemon
     */
    private String userName;

  /**
     * The name of private key file.
     */
    private String keyFile;

  /**
     * The connection object that represents the connection to the host
     * via ssh
     */
    private Connection connection;

    private String authType;

    private String keyPassPhrase;

    private File knownHosts;

    private Logger logger;

    private String password;

    // Password before it has been expanded. Used for debugging.
    private String rawPassword = null;
    private String rawKeyPassPhrase = null;

    @Inject
    private Habitat habitat;

    public void init(Node node, Logger logger) {
        this.logger = logger;
        int port;
        String host;

        SshConnector connector = node.getSshConnector();

        host = connector.getSshHost();
        if (SSHUtil.checkString(host) != null) {
            this.host = host;
        } else {
            this.host = node.getNodeHost();
        }
        if (logger.isLoggable(Level.FINE)) {
	    logger.fine("Connecting to host " + host); 
        }

        //XXX Why do we need this again?  This is already done above and set to host
        String sshHost = connector.getSshHost();
        if (sshHost != null)
            this.host = sshHost;
        
        SshAuth sshAuth = connector.getSshAuth();
        String userName = null;
        if (sshAuth != null) {
            userName = sshAuth.getUserName();
            this.keyFile = sshAuth.getKeyfile();
            this.rawPassword = sshAuth.getPassword();
            this.rawKeyPassPhrase = sshAuth.getKeyPassphrase();
        }
        try {
            port = Integer.parseInt(connector.getSshPort());
        } catch(NumberFormatException nfe) {
            port = 22;
        }

        init(userName, this.host, port, this.rawPassword, keyFile,
                this.rawKeyPassPhrase, logger);

    }

    public void init(String userName, String host, int port, String password, String keyFile, String keyPassPhrase, Logger logger) {

        this.port = port == 0 ? 22 : port;

        this.host = host;
        this.keyFile = (keyFile == null) ? SSHUtil.getExistingKeyFile(): keyFile;
        this.logger = logger;

        this.userName = SSHUtil.checkString(userName) == null ?
                    System.getProperty("user.name") : userName;

        
        this.rawPassword = password;
        this.password = expandPasswordAlias(password);
        this.rawKeyPassPhrase = keyPassPhrase;
        this.keyPassPhrase = expandPasswordAlias(keyPassPhrase);

        if (knownHosts == null) {
            File home = new File(System.getProperty("user.home"));
            knownHosts = new File(home,".ssh/known_hosts");
        }
        if (knownHosts.exists()) {
            try {
                knownHostsDatabase.addHostkeys(knownHosts);
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
        if (logger.isLoggable(Level.FINER)) {
            logger.finer("SSH info is " + toString());
        }
    }


  /**
     * Opens the connection to the host and authenticates with public
     * key.
     * 
     */
    private void openConnection() throws IOException {

    boolean isAuthenticated = false;
    String message= "";
    connection = new Connection(host, port);

        connection.connect(new HostVerifier(knownHostsDatabase));
        if(SSHUtil.checkString(keyFile) == null && SSHUtil.checkString(password) == null) {
            message += "No key or password specified - trying default keys \n";
            if (logger.isLoggable(Level.FINE)) {
                logger.fine("keyfile and password are null. Will try to authenticate with default key file if available");
            }
            // check the default key locations if no authentication
            // method is explicitly configured.
            File home = new File(System.getProperty("user.home"));
            for (String keyName : Arrays.asList("id_rsa","id_dsa",
                                                "identity"))
            {
                message += "Tried to authenticate using " + keyName + "\n";
                File key = new File(home,".ssh/"+keyName);
                if (key.exists()) {
                    isAuthenticated =
                        connection.authenticateWithPublicKey(userName,
                                                             key, null);
                }
                if (isAuthenticated) {
                    if (logger.isLoggable(Level.FINE)) {
                        logger.fine("Authentication successful using key " + keyName);
                    }

                    message = null;

                    break;
                }

            }
        }

        if (!isAuthenticated && SSHUtil.checkString(password) != null) {
            if (logger.isLoggable(Level.FINE)) {
                logger.fine("Authenticating with password " + getPrintablePassword(password));
            }
            try {
              isAuthenticated = connection.authenticateWithPassword(userName, password);
            } catch (IOException iex) {
                   if (logger.isLoggable(Level.FINE)) {
                        logger.fine("Tried authenticating with password " + password);
                   }
            }
      }
      
        if (!isAuthenticated && SSHUtil.checkString(keyFile) != null) {
            if (logger.isLoggable(Level.FINER)) {
                logger.finer("Specified key file is " + keyFile);
            }
            File key = new File(keyFile);
            if (key.exists()) {
                if (logger.isLoggable(Level.FINER)) {
                    logger.finer("Specified key file exists at " + key);
                }
                try {
                  isAuthenticated = connection.authenticateWithPublicKey(
                                                      userName, key, keyPassPhrase);
                } catch (IOException ex){
                        if (logger.isLoggable(Level.FINE)) {
                            logger.fine("Tried authenticating with specified key at " + key);
                        }

                }

            }
        }



        if (!isAuthenticated && !connection.isAuthenticationComplete()) {
            connection.close();
            connection = null;
            if (logger.isLoggable(Level.FINE)) {
                logger.fine("Could not authenticate");
            }
            throw new IOException("Could not authenticate. " + message);
        }
        message = null;
        SSHUtil.register(connection);

    }

    /**
     * Executes a command on the remote system via ssh, optionally sending
     * lines of data to the remote process's System.in.
     *
     * @param command the command to execute in the form of an argv style list
     * @param os stream to receive the output from the command
     * @param stdinLines optional data to be sent to the process's System.in
     *        stream; null if no input should be sent
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    public int runCommand(List<String> command, OutputStream os,
            List<String> stdinLines) throws IOException,
                                            InterruptedException
    {
        return runCommand(commandListToQuotedString(command), os, stdinLines);
    }

    public int runCommand(List<String> command, OutputStream os)
                                            throws IOException,
                                            InterruptedException
    {
        return runCommand(command, os, null);
    }

    /**
     * WARNING! This method does not handle paths with spaces in them.
     * To use this method you must make sure all paths in the command string
     * are quoted correctly.  Otherwise use the methods that take command as
     * a list instead.
     */
    public int runCommand(String command, OutputStream os) throws IOException,
                                            InterruptedException
    {
        return runCommand(command, os, null);
    }

    /**
     * Executes a command on the remote system via ssh, optionally sending
     * lines of data to the remote process's System.in.
     *
     * WARNING! This method does not handle paths with spaces in them.
     * To use this method you must make sure all paths in the command string
     * are quoted correctly.  Otherwise use the methods that take command as
     * a list instead.
     *
     * @param command the command to execute
     * @param os stream to receive the output from the command
     * @param stdinLines optional data to be sent to the process's System.in stream; null if no input should be sent
     * @return
     * @throws IOException
     * @throws InterruptedException
     */
    public int runCommand(String command, OutputStream os,
            List<String> stdinLines) throws IOException,
                                            InterruptedException
    {
        command = SFTPClient.normalizePath(command);
        if (logger.isLoggable(Level.FINER)) {
            logger.finer("Running command " + command + " on host: " + this.host);
        }

        openConnection();
        final Session sess = connection.openSession();

        int status = exec(sess, command, os, listInputStream(stdinLines));

        // XXX: Should we close connection after each command or cache it
        // and re-use it?
        SSHUtil.unregister(connection);
        connection = null;
        return status;
    }

    private int exec(final Session session, final String command, final OutputStream os,
            final InputStream is)
            throws IOException, InterruptedException {
        try {
            session.execCommand(command);
            PumpThread t1 = new PumpThread(session.getStdout(), os);
            t1.start();
            PumpThread t2 = new PumpThread(session.getStderr(), os);
            t2.start();
            final OutputStream stdin = session.getStdin();
            if (is != null) {
                final PumpThread inputPump = new PumpThread(is,
                        stdin);
                inputPump.run();
            }
            stdin.close();
            t1.join();
            t2.join();

            // wait for some time since the delivery of the exit status often gets delayed
            session.waitForCondition(ChannelCondition.EXIT_STATUS,3000);
            Integer r = session.getExitStatus();
            if(r!=null) return r.intValue();
            return -1;
        } finally {
            session.close();
        }
    }

    private InputStream listInputStream(final List<String> stdinLines) throws IOException {
        if (stdinLines == null) {
            return null;
        }
        final ByteArrayOutputStream baos = new ByteArrayOutputStream();
        for (String line : stdinLines) {
            baos.write(line.getBytes());
            baos.write(LINE_SEP);
        }
        return new ByteArrayInputStream(baos.toByteArray());
    }

    /**
     * Pumps {@link InputStream} to {@link OutputStream}.
     *
     * @author Kohsuke Kawaguchi
     */
    private static final class PumpThread extends Thread {
        private final InputStream in;
        private final OutputStream out;

        public PumpThread(InputStream in, OutputStream out) {
            super("pump thread");
            this.in = in;
            this.out = out;
        }

        public void run() {
            byte[] buf = new byte[1024];
            try {
                while(true) {
                    int len = in.read(buf);
                    if(len<0) {
                        in.close();
                        return;
                    }
                    out.write(buf,0,len);
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    public void pingConnection() throws IOException, InterruptedException
    {
        logger.fine("Pinging connection for host: " + this.host);
        openConnection();
        SSHUtil.unregister(connection);
        connection = null;
    }

    /* validate user provided ars
     *          check connecton to host
     *          check that the install dir is correct
     *          landmarkPath must be relative to the installdir
     */

    public void validate(String host, int port,
                             String userName, String password,
                             String keyFile, String keyPassPhrase,
                             String installDir, String landmarkPath,
                             Logger logger) throws IOException
    {
        boolean validInstallDir = false;
        init(userName, host,  port, password, keyFile, keyPassPhrase, logger);

        openConnection();
        logger.fine("Connection settings valid");
        String testPath = installDir;
        if (StringUtils.ok(testPath)) {
            // Validate if installDir exists
            SFTPClient sftpClient = new SFTPClient(connection);
            if (sftpClient.exists(testPath)) {
                // installDir exists. Now check for landmark if provided
                if (StringUtils.ok(landmarkPath)) {                    
                    testPath = installDir + "/" + landmarkPath;
                }
                validInstallDir = sftpClient.exists(testPath);
            } else {
                validInstallDir = false;
            }
            SSHUtil.unregister(connection);
            connection = null;

            if (!validInstallDir) {
                String msg = "Invalid install directory: could not find " +
                        testPath + " on " + host;
                logger.warning(msg);
                throw new FileNotFoundException(msg);
            }
            logger.fine("Node home validated");
        }
    }

    public void validate(String host, int port,
                             String userName, String password,
                             String keyFile, String keyPassPhrase,
                             String installDir, Logger logger) throws IOException
    {
        // Validate with no landmark file
        validate(host, port, userName, password, keyFile, keyPassPhrase,
                             installDir, null, logger);
    }

    public SFTPClient getSFTPClient() throws IOException {
        openConnection();
        SFTPClient sftpClient = new SFTPClient(connection);
        return sftpClient;
    }

    public SCPClient getSCPClient() throws IOException {
        openConnection();
        return new SCPClient(connection);
    }

    public String expandPasswordAlias(String alias) {

        String expandedPassword = null;

        if (alias == null) {
            return null;
        }

        try {
            expandedPassword = RelativePathResolver.getRealPasswordFromAlias(alias);
        } catch (Exception e) {
            logger.warning(StringUtils.cat(": ", alias, e.getMessage()));
            return null;
        }

        return expandedPassword;
    }

    public boolean isPasswordAlias(String alias) {
        // Check if the passed string is specified using the alias syntax
        String aliasName = RelativePathResolver.getAlias(alias);
        return (aliasName != null);
    }

    /**
     * Return a version of the password that is printable.
     * @param p  password string
     * @return   printable version of password
     */
    private String getPrintablePassword(String p) {
        // We only display the password if it is an alias, else
        // we display "<concealed>".
        String printable = "null";
        if (p != null) {
            if (isPasswordAlias(p)) {
                printable = p;
            } else {
                printable = "<concealed>";
            }
        }
        return printable;
    }

     public void setupKey(String node, String pubKeyFile, boolean generateKey, String passwd)
             throws IOException, InterruptedException {
        boolean connected = false;

        File key = new File(keyFile);
        if(logger.isLoggable(Level.FINER))
            logger.finer("Key = " + keyFile);
        if (key.exists()) {
            if (checkConnection()) {
                throw new IOException("SSH public key authentication is already configured for " + userName + "@" + node);
            }            
        } else {
            if (generateKey) {
                if(!generateKeyPair()) {
                    throw new IOException("SSH key pair generation failed. Please generate key manually.");
                }
            } else {                
                throw new IOException("SSH key pair not present. Please generate a key pair manually or specify an existing one and re-run the command.");
            }
        }

        //password is must for key distribution
        if (passwd == null) {
            throw new IOException("SSH password is required for distributing the public key. You can specify the SSH password in a password file and pass it through --passwordfile option.");
        }
        try {
            connection = new Connection(node, port);
            connection.connect();
            connected = connection.authenticateWithPassword(userName, passwd);
        } catch (Exception ex) {
            //logger.printExceptionStackTrace(ex);
            throw new IOException("SSH password authentication failed for user " + userName + " on host " + node);
        }

        if(!connected) {
            throw new IOException("SSH password authentication failed for user " + userName + " on host " + node);
        }
        //initiate scp client
        SCPClient scp = new SCPClient(connection);
        SFTPClient sftp = new SFTPClient(connection);

        if (key.exists()) {

            //fixes .ssh file mode
            setupSSHDir();

            if (pubKeyFile == null) {
                pubKeyFile = keyFile + ".pub";
            }

            File pubKey = new File(pubKeyFile);
            if(!pubKey.exists()) {
                throw new IOException("Public key file " + pubKeyFile + " does not exist.");
            }

            try {
                if(!sftp.exists(SSH_DIR)) {
                    if(logger.isLoggable(Level.FINER)) {
                        logger.fine(SSH_DIR + " does not exist");
                    }
                    sftp.mkdirs(".ssh", 0700);
                }
            } catch (Exception e) {
                if(logger.isLoggable(Level.FINER)) {
                    e.printStackTrace();
                }
                throw new IOException("Error while creating .ssh directory on remote host:" + e.getMessage());
            }

            //copy over the public key to remote host
            scp.put(pubKey.getAbsolutePath(), ".ssh");            

            //append the public key file contents to authorized_keys file on remote host
            String mergeCommand = "cd .ssh; cat " + pubKey.getName() + " >> " + AUTH_KEY_FILE;
            if(logger.isLoggable(Level.FINER)) {
                logger.finer("mergeCommand = " + mergeCommand);
            }
            if(connection.exec(mergeCommand, new ByteArrayOutputStream())!=0) {
                throw new IOException("Failed to propogate the public key " + pubKeyFile + " to " + host);
            }
            logger.info("Copied keyfile " + pubKeyFile + " to " + userName + "@" + host);

            //remove the public key file on remote host
            //for some reason sftp.rm() hangs for MKS ssh
            if(connection.exec("rm .ssh/" + pubKey.getName(), new ByteArrayOutputStream())!=0) {
                logger.warning("WARNING: Failed to remove the public key file " + pubKey.getName()
                                + " on remote host " + host);
            }
            if(logger.isLoggable(Level.FINER)) {
                logger.finer("Removed the key file on remote host");
            }
            connection.close();
        }
    }

    public static byte[] toByteArray( InputStream input )
        throws IOException
    {
        ByteArrayOutputStream output = new ByteArrayOutputStream();
        byte[] buf = new byte[4096];
        int len;
        while ((len = input.read(buf)) >= 0) {
           output.write(buf, 0, len);
        }
        byte[] o = output.toByteArray();
        output.close();
        return o;
    }

    public boolean checkConnection() throws IOException {
        boolean status = false;
        Connection c = null;
        c = new Connection(host, port);
        c.connect();
        File f = new File(keyFile);
        if(logger.isLoggable(Level.FINER)) {
            logger.finer("Checking connection...");
        }
        status = c.authenticateWithPublicKey(userName, f, rawKeyPassPhrase);
        if (status) {
            logger.info("Successfully connected to " + userName + "@" + host + " using keyfile " + keyFile);
        }
        c.close();
        return status;
    }

    public boolean checkPasswordAuth() {
        boolean status = false;
        Connection c = null;
        try {
            c = new Connection(host, port);
            c.connect();
            if(logger.isLoggable(Level.FINER)) {
                logger.finer("Checking connection...");
            }
            status = c.authenticateWithPassword(userName, password);
            if (status) {
                logger.finer("Successfully connected to " + userName + "@" + host + " using password authentication");
            }
        } catch(IOException ioe) {
            //logger.printExceptionStackTrace(ioe);
            if (logger.isLoggable(Level.FINER)) {
                ioe.printStackTrace();
            }
        }
        c.close();
        return status;
    }

    /**
      * Invoke ssh-keygen using ProcessManager API
      */
    private boolean generateKeyPair() throws IOException {
        String keygenCmd = findSSHKeygen();
        if(logger.isLoggable(Level.FINER)) {
            logger.finer("Using " + keygenCmd + " to generate key pair");
        }

        setupSSHDir();

        StringBuffer k = new StringBuffer();
        List<String> cmdLine = new ArrayList();
        cmdLine.add(keygenCmd);
        k.append(keygenCmd);
        cmdLine.add("-t");
        k.append(" ").append("-t");
        cmdLine.add("rsa");
        k.append(" ").append("rsa");
        cmdLine.add("-N");
        k.append(" ").append("-N");

        if (rawKeyPassPhrase != null && rawKeyPassPhrase.length() > 0) {
            cmdLine.add(rawKeyPassPhrase);
            k.append(" ").append(getPrintablePassword(rawKeyPassPhrase));
        } else {
            //special handling for empty passphrase on Windows
            if(OS.isWindows()) {
                cmdLine.add("\"\"");
                k.append(" ").append("\"\"");
            } else {
                cmdLine.add("");
                k.append(" ").append("");
            }
        }
        cmdLine.add("-f");
        k.append(" ").append("-f");
        cmdLine.add(keyFile);
        k.append(" ").append(keyFile);
        //cmdLine.add("-vvv");

        ProcessManager pm = new ProcessManager(cmdLine);

        if(logger.isLoggable(Level.FINER)) {
            logger.finer("Command = " + k);
        }
        pm.setTimeoutMsec(DEFAULT_TIMEOUT_MSEC);

        if (logger.isLoggable(Level.FINER))
            pm.setEcho(true);
        else
            pm.setEcho(false);
        int exit;

        try {
            exit = pm.execute();            
        }
        catch (ProcessManagerException ex) {
            logger.fine("Error while executing ssh-keygen: " + ex.getMessage());
            exit = 1;
        }
        if (exit == 0){
            logger.info(keygenCmd + " successfully generated the identification " + keyFile);
        } else {
            if(logger.isLoggable(Level.FINER)) {
                logger.finer(pm.getStderr());
            }
            logger.info(keygenCmd + " failed");
        }

        return (exit == 0) ? true : false;
    }

    /**
     * Method to locate ssh-keygen. If found in path, return the same or else look
     * for it in a pre defined list of search paths.
     * @return ssh-keygen command
     */
    private String findSSHKeygen() {
        List<String> paths = new ArrayList(Arrays.asList(
                    "/usr/bin/",
                    "/usr/local/bin/"));

        if (OS.isWindows()) {
            paths.add("C:/cygwin/bin/");
            //Windows MKS Toolkit install path
            String mks = System.getenv("ROOTDIR");
            if (mks != null) {
                paths.add(mks + "/bin/");
            }
        }

        if (logger.isLoggable(Level.FINER)) {
            logger.finer("Paths = " + paths);
        }
        
        File exe = ProcessUtils.getExe(SSH_KEYGEN);
        if( exe != null){
            return exe.getPath();
        }

        for (String s :paths) {
            File f = new File(s + SSH_KEYGEN);
            if (f.canExecute()) {
                return f.getAbsolutePath();
            }
        }
        return SSH_KEYGEN;
    }

    /**
      * Create .ssh directory and set the permissions correctly
      */
    private void setupSSHDir() {
        File home = new File(System.getProperty("user.home"));
        File f = new File(home,SSH_DIR);

        if(!FileUtils.safeIsDirectory(f)) {
            f.mkdirs();
            logger.info("Created directory " + f.toString());
        }
        
        f.setWritable(false,false);
        f.setWritable(true, true);
        f.setReadable(false, false);
        f.setReadable(true, true);
        f.setExecutable(false, false);
        f.setExecutable(true, true);

        if(logger.isLoggable(Level.FINER)) {
            logger.finer("Fixed the .ssh directory permissions to 0700");
        }
    }
    
    @Override
    public String toString() {

        String knownHostsPath  = "null";
        if (knownHosts != null) {
            try {
                knownHostsPath = knownHosts.getCanonicalPath();
            } catch (IOException e) {
                knownHostsPath = knownHosts.getAbsolutePath();
            }
        }

        String displayPassword = getPrintablePassword(rawPassword);
        String displayKeyPassPhrase = getPrintablePassword(rawKeyPassPhrase);

        return String.format("host=%s port=%d user=%s password=%s keyFile=%s keyPassPhrase=%s authType=%s knownHostFile=%s",
            host, port, userName, displayPassword, keyFile,
            displayKeyPassPhrase, authType, knownHostsPath);
    }

    /**
     * Take a command in the form of a list and convert it to a command string.
     * If any string in the list has spaces then the string is quoted before
     * being added to the final command string.
     *
     * @param command
     * @return
     */
    private static String commandListToQuotedString(List<String> command) {
        StringBuilder commandBuilder  = new StringBuilder();
        boolean first = true;

        for (String s : command) {
            if (!first) {
                commandBuilder.append(" ");
            } else {
                first = false;
            }
            if (s.contains(" ")) {
                // Quote parts of the command that contain a space
                commandBuilder.append(FileUtils.quoteString(s));
            } else {
                commandBuilder.append(s);
            }
        }
        return commandBuilder.toString();
    }
}

Other Glassfish examples (source code examples)

Here is a short list of links related to this Glassfish SSHLauncher.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.