Wednesday, March 7, 2012

SSH library for Java


Does anyone know of a good library for SSH login from Java.



Thanks, Ronen.

5 comments:

  1. The Java Secure Channel (JSCH) is a very popular library, used by maven, ant and eclipse. It is open source with a BSD style license.

    ReplyDelete
  2. Update: The GSOC project and the code there isn't active, but this is: https://github.com/shikhar/sshj



    There was a GSOC project:

    http://code.google.com/p/commons-net-ssh/

    Code quality seem to be better than JSch, which, while a complete and working implementation, lacks documentation. Project page spots an upcoming beta release, last commit to the repository was mid-august.

    Compare the APIs:

    http://code.google.com/p/commons-net-ssh/

    SSHClient ssh = new SSHClient();
    //ssh.useCompression();
    ssh.loadKnownHosts();
    ssh.connect("localhost");
    try {
    ssh.authPublickey(System.getProperty("user.name"));
    new SCPDownloadClient(ssh).copy("ten", "/tmp");
    } finally {
    ssh.disconnect();
    }


    http://www.jcraft.com/jsch/

    Session session = null;
    Channel channel = null;

    try {

    JSch jsch = new JSch();
    session = jsch.getSession(username, host, 22);
    java.util.Properties config = new java.util.Properties();
    config.put("StrictHostKeyChecking", "no");
    session.setConfig(config);
    session.setPassword(password);
    session.connect();

    // exec 'scp -f rfile' remotely
    String command = "scp -f " + remoteFilename;
    channel = session.openChannel("exec");
    ((ChannelExec) channel).setCommand(command);

    // get I/O streams for remote scp
    OutputStream out = channel.getOutputStream();
    InputStream in = channel.getInputStream();

    channel.connect();

    byte[] buf = new byte[1024];

    // send '\0'
    buf[0] = 0;
    out.write(buf, 0, 1);
    out.flush();

    while (true) {
    int c = checkAck(in);
    if (c != 'C') {
    break;
    }

    // read '0644 '
    in.read(buf, 0, 5);

    long filesize = 0L;
    while (true) {
    if (in.read(buf, 0, 1) < 0) {
    // error
    break;
    }
    if (buf[0] == ' ') {
    break;
    }
    filesize = filesize * 10L + (long) (buf[0] - '0');
    }

    String file = null;
    for (int i = 0;; i++) {
    in.read(buf, i, 1);
    if (buf[i] == (byte) 0x0a) {
    file = new String(buf, 0, i);
    break;
    }
    }

    // send '\0'
    buf[0] = 0;
    out.write(buf, 0, 1);
    out.flush();

    // read a content of lfile
    FileOutputStream fos = null;

    fos = new FileOutputStream(localFilename);
    int foo;
    while (true) {
    if (buf.length < filesize) {
    foo = buf.length;
    } else {
    foo = (int) filesize;
    }
    foo = in.read(buf, 0, foo);
    if (foo < 0) {
    // error
    break;
    }
    fos.write(buf, 0, foo);
    filesize -= foo;
    if (filesize == 0L) {
    break;
    }
    }
    fos.close();
    fos = null;

    if (checkAck(in) != 0) {
    System.exit(0);
    }

    // send '\0'
    buf[0] = 0;
    out.write(buf, 0, 1);
    out.flush();

    channel.disconnect();
    session.disconnect();
    }

    } catch (JSchException jsche) {
    System.err.println(jsche.getLocalizedMessage());
    } catch (IOException ioe) {
    System.err.println(ioe.getLocalizedMessage());
    } finally {
    channel.disconnect();
    session.disconnect();
    }

    }

    ReplyDelete
  3. I just discovered sshj, which seems to have a much more concise API than JSCH (but it requires Java 6). The documentation is mostly by examples-in-the-repo at this point, and usually that's enough for me to look elsewhere, but it seems good enough for me to give it a shot on a project I just started.

    ReplyDelete
  4. Take a look at the very recently released SSHD, which is based on the Apache MINA project.

    ReplyDelete
  5. You can take a look at orion-ssh2: http://orion-ssh2.sourceforge.net/

    ReplyDelete