/*
* Copyright 2005 Huawei Technologies Co.,Ltd. All rights reserved.
*/
package com.huawei.cloudcube.rds.jcommon.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import ch.ethz.ssh2.Connection;
import ch.ethz.ssh2.InteractiveCallback;
import ch.ethz.ssh2.KnownHosts;
import ch.ethz.ssh2.ServerHostKeyVerifier;
import ch.ethz.ssh2.Session;
import ch.ethz.ssh2.StreamGobbler;
/**
* 在远程主机上执行shell命令
* @version 1.0 2011-4-28
* @author Name ID
*/
public final class ExecuteRemoteShell
{
/**
* hostname
*/
String hostname;
/**
* username
*/
String username;
/**
* hostpwd
*/
String hostpwd;
/**
* execmdline
*/
String execmdline;
/**
* @param hostname the hostname to set
*/
public void setHostname(String hostname)
{
this.hostname = hostname;
}
/**
* @param username the username to set
*/
public void setUsername(String username)
{
this.username = username;
}
/**
* @param hostpwd the hostpwd to set
*/
public void setHostpwd(String hostpwd)
{
this.hostpwd = hostpwd;
}
/**
* @param execmdline the execmdline to set
*/
public void setExecmdline(String execmdline)
{
this.execmdline = execmdline;
}
/**
* @param hostname
* @param username
* @param hostpwd
* @param execmdline
*/
public ExecuteRemoteShell(String hostname, String username, String hostpwd,
String execmdline)
{
this.hostname = hostname;
this.username = username;
this.hostpwd = hostpwd;
this.execmdline = execmdline;
}
public void exec()
{
ConnectionThread connectionThread = new ConnectionThread();
connectionThread.run();
}
/**
* The SSH-2 connection is established in this thread.
* If we would not use a separate thread (e.g., put this code in
* the event handler of the "Login" button) then the GUI would not
* be responsive (missing window repaints if you move the window etc.)
*/
class ConnectionThread
{
public void run()
{
Connection conn = new Connection(hostname);
try
{
/*
*
* CONNECT AND VERIFY SERVER HOST KEY (with callback)
*
*/
String[] hostkeyAlgos = database
.getPreferredServerHostkeyAlgorithmOrder(hostname);
if (hostkeyAlgos != null)
conn.setServerHostKeyAlgorithms(hostkeyAlgos);
conn.connect(new AdvancedVerifier());
/*
*
* AUTHENTICATION PHASE
*
*/
boolean enableKeyboardInteractive = true;
boolean enableDSA = true;
boolean enableRSA = true;
String lastError = null;
while (true)
{
if ((enableDSA || enableRSA)
&& conn.isAuthMethodAvailable(username, "publickey"))
{
//如果启用了DSA
if (enableDSA)
{
File key = new File(idDSAPath);
if (key.exists())
{
/*EnterSomethingDialog esd = new EnterSomethingDialog(loginFrame, "DSA Authentication",
new String[] { lastError, "Enter DSA private key password:" }, true);
esd.setVisible(true);*/
boolean res = conn.authenticateWithPublicKey(
username, key, hostpwd);
if (res == true)
break;
lastError = "DSA authentication failed.";
}
enableDSA = false; // do not try again
}
//如果启用了RSA
if (enableRSA)
{
File key = new File(idRSAPath);
if (key.exists())
{
boolean res = conn.authenticateWithPublicKey(
username, key, hostpwd);
if (res == true)
break;
lastError = "RSA authentication failed.";
}
enableRSA = false; // do not try again
}
continue;
}
if (enableKeyboardInteractive
&& conn.isAuthMethodAvailable(username,
"keyboard-interactive"))
{
InteractiveLogic il = new InteractiveLogic(lastError,
hostpwd);
boolean res = conn.authenticateWithKeyboardInteractive(
username, il);
if (res == true)
break;
if (il.getPromptCount() == 0)
{
// aha. the server announced that it supports "keyboard-interactive", but when
// we asked for it, it just denied the request without sending us any prompt.
// That happens with some server versions/configurations.
// We just disable the "keyboard-interactive" method and notify the user.
lastError = "Keyboard-interactive does not work.";
enableKeyboardInteractive = false; // do not try this again
}
else
{
lastError = "Keyboard-interactive auth failed."; // try again, if possible
}
continue;
}
if (conn.isAuthMethodAvailable(username, "password"))
{
if (hostpwd == null)
throw new IOException("Login aborted by user");
boolean res = conn.authenticateWithPassword(username,
hostpwd);
if (res == true)
break;
lastError = "Password authentication failed."; // try again, if possible
continue;
}
throw new IOException(
"No supported authentication methods available.");
}
/*
*
* AUTHENTICATION OK. DO SOMETHING.
*
*/
Session sess = conn.openSession();
sess.execCommand(execmdline);
System.out
.println("Here is some information about the remote host:");
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(
stdout));
评论0
最新资源