SSH

You are currently browsing articles tagged SSH.

This is example code to do a SFTP file copy using the JSCH Java library.  There are a few libraries in this arena, and all of them seem more complex than they are.  JSCH doesn’t have the best documentation along with it, but it is maintained and in the Maven repositories.

The key file just needs to be somewhere in the classpath for this to work.    The code is actually quite short.  In the actual version of this code, there is an object that has all of the values that is needed for this method and a verification routine to make sure that they are valid.

Note that the SFTP session is always connected regardless is the file to be copied doesn’t exists.  This is by design so that if there is an issue with the SSH server, an error will be received even if there is no file to copy.

JSch.setLogger(new JSCHLogger()); // More on this below
JSch jsch = new JSch();
Session session = null;
ChannelSftp channel = null;
FileInputStream localFileStream = null;

try
{
//Use key authentication if it is set, else use password auth
if (YOUR_KEY_FILE_NAME != null && YOUR_KEY_FILE_NAME != "")
{
URL keyFileURL = this.getClass().getClassLoader().getResource(YOUR_KEY_FILE_NAME);
if (keyFileURL == null)
{
throw new RuntimeException("Key file " + YOUR_KEY_FILE_NAME  + "not found in classpath");
}
URI keyFileURI = keyFileURL.toURI();

jsch.addIdentity(new File(keyFileURI).getAbsolutePath());
session = jsch.getSession(YOUR_SSH_SERVER_USER_NAME, YOUR_SSH_SERVER_NAME , YOUR_SSH_SERVER_PORT);
}
else if (YOUR_SSH_PASSWORD != null && YOUR_SSH_PASSWORD != "")
{
session = jsch.getSession(YOUR_SSH_SERVER_USER_NAME, YOUR_SSH_SERVER_NAME , YOUR_SSH_SERVER_PORT);
session.setPassword(YOUR_SSH_SERVER_PASSWORD);
}

//Make it so we do not do host key checking.  Enabling this would require some extra code and maintenance, but would increase security.
session.setConfig("StrictHostKeyChecking", "no");
session.setTimeout(15000);

session.connect();

channel = (ChannelSftp)session.openChannel("sftp");
channel.connect();

if (YOUR_SSH_SERVER_FILE_DIRECTORY != null && YOUR_SSH_SERVER_FILE_DIRECTORY != "")
{
channel.cd(YOUR_SSH_SERVER_FILE_DIRECTORY);
}

File localFile = new File (YOUR_LOCAL_FILE_TO_COPY + YOUR_LOCAL_FILE_TO_COPY);
if (localFile.exists())
{
localFileStream = new FileInputStream(localFile);

channel.put(localFileStream, YOUR_REMOTE_FILE_NAME));
}
else
{
log.warn("Local file not found " + localFile.getAbsolutePath());
}
}

There is one more thing that needs to be done.  JSCH has its own internal logging that isn’t automatically connected to the program’s logger.  This code ties them together.

public static class JSCHLogger implements com.jcraft.jsch.Logger
{

static java.util.Hashtable<Integer,String> name = new java.util.Hashtable <Integer,String> ();

static
{
name.put(new Integer(DEBUG), "DEBUG: ");
name.put(new Integer(INFO), "INFO: ");
name.put(new Integer(WARN), "WARN: ");
name.put(new Integer(ERROR), "ERROR: ");
name.put(new Integer(FATAL), "FATAL: ");
}

public boolean isEnabled(int level)
{
return true;
}

public void log(int level, String message)
{
if(level == DEBUG)
{
log.debug(message);
}
else if(level == INFO)
{
log.info(message);
}
else if(level == WARN)
{
log.warn(message);
}
else if(level == ERROR)
{
log.error(message);
}
else if(level == FATAL)
{
log.fatal(message);
}
}
} 

Tags: , ,