Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2076396
  • 博文数量: 519
  • 博客积分: 10070
  • 博客等级: 上将
  • 技术积分: 3985
  • 用 户 组: 普通用户
  • 注册时间: 2006-05-29 14:05
个人简介

只问耕耘

文章分类

全部博文(519)

文章存档

2016年(1)

2013年(5)

2011年(46)

2010年(220)

2009年(51)

2008年(39)

2007年(141)

2006年(16)

我的朋友

分类: Java

2010-01-28 14:39:01

If you’ve worked with Linux or Unix you have undoubtedly encountered SSH. SSH, or secure shell, is defined on wikipedia as “a network protocol that allows data to be exchanged securely between two network devices.” SSH is used for many purposes, including:

A replacement for telnet and rlogin for executing shell commands
To execute a single command on a remote server using rsh
To copy files between servers using SCP
Used with SFTP to support secure FTP
Port forwarding or tunneling
Encrypted VPN, such as with OpenSSH
As a secure proxy with the SOCKS protocol
To create a secure file system using SSHFS
As a bit of background, SSH was created in 1995, but had security vulnerabilities that allowed for a “man in the middle” attack, so SSH-2 was released in 1996. In 2006, SSH-2 became a proposed Internet standard.

Encrypting the transmission of data between servers is very important, especially in current times in which almost every computer is connected to a network. And if you’re writing a Java application that needs to connect to a remote server and transfer sensitive data, it would be nice to take advantage of the work that went into integrating SSH with unix/linux operating systems. The Jakarta Commons Net classes provide support for Telnet, FTP, and a host of other protocols, but not for SSH.

Fortunately, there is a library called Ganymed SSH-2 for Java that implements SSH 2 using AES, Blowfish, and 3DES encryption ciphers in a BSD style license, and using it is very straightforward. Download Ganymed and add ganymed-ssh2-build210.jar (or the latest version) to your CLASSPATH and then implement the following steps:

Create a Connection object, passing it the host name or IP address (as a String) of the server you want to connect to
Call the Connection’s connect() method to connect to the server
Call authenticateWithPassword(), passing it your username and password
Open a Session by calling the Connection’s openSession()
Execute a command by calling the Session’s execCommand() method, passing it the command to execute
Consume the response of the command by invoking the sessions’ getStdOut() (or getStdErr() if you want the error stream), optionally using Ganymed’s StreamGobbler to help you
Close the session by calling the Session’s close() method
Close the connection by calling its close() method
Listing 1 shows the source code for a class called SSHAgent that provides the ability to execute commands on a remote computer using SSH.

Listing 1. SSHAgent.java
package com.javasrc.jolt.agent.ssh;

import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;

import com.javasrc.jolt.component.linux.model.FileSystem;

/**
 * The SSHAgent allows a Java application to execute commands on a remote server via SSH
 *
 * @author shaines
 *
 */
public class SSHAgent {
   
    /**
     * The hostname (or IP address) of the server to connect to
     */
    private String hostname;
   
    /**
     * The username of the user on that server
     */
    private String username;
   
    /**
     * The password of the user on that server
     */
    private String password;
   
    /**
     * A connection to the server
     */
    private Connection connection;
   
    /**
     * Creates a new SSHAgent
     *
     * @param hostname
     * @param username
     * @param password
     */
    public SSHAgent( String hostname, String username, String password )
    {
        this.hostname = hostname;
        this.username = username;
        this.password = password;
    }
   
    /**
     * Connects to the server
     *
     * @return        True if the connection succeeded, false otherwise
     */
    public boolean connect() throws SSHException
    {
        try
        {
            // Connect to the server
            connection = new Connection( hostname );
            connection.connect();
           
            // Authenticate
            boolean result = connection.authenticateWithPassword( username, password );
            System.out.println( "Connection result: " + result );
            return result;
        }
        catch( Exception e )
        {
            throw new SSHException( "An exception occurred while trying to connect to the host: " + hostname + ", Exception=" + e.getMessage(), e );
        }
    }
   
    /**
     * Executes the specified command and returns the response from the server
     * 
     * @param command        The command to execute
     * @return               The response that is returned from the server (or null)
     */
    public String executeCommand( String command ) throws SSHException
    {
        try
        {
            // Open a session
            Session session = connection.openSession();
           
            // Execute the command
            session.execCommand( command );
           
            // Read the results
            StringBuilder sb = new StringBuilder();
            InputStream stdout = new StreamGobbler( session.getStdout() );
            BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
            String line = br.readLine();
            while( line != null )
            {
                sb.append( line + "\n" );
                line = br.readLine();
            }

            // DEBUG: dump the exit code
            System.out.println( "ExitCode: " + session.getExitStatus() );

            // Close the session
            session.close();
           
            // Return the results to the caller
            return sb.toString();
        }
        catch( Exception e )
        {
            throw new SSHException( "An exception occurred while executing the following command: " + command + ". Exception = " + e.getMessage(), e );
        }
    }

    /**
     * Logs out from the server
     * @throws SSHException
     */
    public void logout() throws SSHException
    {
        try
        {
            connection.close();
        }
        catch( Exception e )
        {
            throw new SSHException( "An exception occurred while closing the SSH connection: " + e.getMessage(), e );
        }
    }
   
    /**
     * Returns true if the underlying authentication is complete, otherwise returns false
     * @return
     */
    public boolean isAuthenticationComplete()
    {
        return connection.isAuthenticationComplete();
    }
   
    public static void main( String[] args )
    {
        try
        {
            SSHAgent sshAgent = new SSHAgent( "192.168.2.3", "username", "mypassword" );
            if( sshAgent.connect() )
            {
                String diskInfo = sshAgent.executeCommand( "df -k" );
                System.out.println( "Disk info: " + diskInfo );
               
                String processInfo = sshAgent.executeCommand( "top -b -n 1" );
                System.out.println( "Process Info: " + processInfo );
               
                // Logout
                sshAgent.logout();
            }
        }
        catch( SSHException e )
        {
            e.printStackTrace();
        }
    }
}

阅读(1989) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~