KnownHosts
class is a handy tool to verify received server hostkeys based on the information in known_hosts
files (the ones used by OpenSSH). It offers basically an in-memory database for known_hosts entries, as well as some helper functions. Entries from a known_hosts
file can be loaded at construction time. It is also possible to add more keys later (e.g., one can parse different known_hosts
files).
It is a thread safe implementation, therefore, you need only to instantiate one
KnownHosts
for your whole application.
@author Christian Plattner, plattner@inf.ethz.ch
@version $Id: KnownHosts.java,v 1.5 2006/07/30 21:59:29 cplattne Exp $
try
{
/* Create a connection instance */
Connection conn = new Connection(hostname);
/* We want to connect through a HTTP proxy */
conn.setProxyData(new HTTPProxyData(proxyHost, proxyPort));
// if the proxy requires basic authentication:
// conn.setProxyData(new HTTPProxyData(proxyHost, proxyPort, "username", "secret"));
/* Now connect (through the proxy) */
conn.connect();
/* Authenticate.
* If you get an IOException saying something like
* "Authentication method password not supported by the server at this stage."
* then please check the FAQ.
*/
boolean isAuthenticated = conn.authenticateWithPassword(username, password);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
/* Create a session */
Session sess = conn.openSession();
sess.execCommand("uname -a && date && uptime && who");
System.out.println("Here is some information about the remote host:");
/*
* This basic example does not handle stderr, which is sometimes dangerous
* (please read the FAQ).
*/
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
while (true)
{
String line = br.readLine();
if (line == null)
break;
System.out.println(line);
}
/* Show exit status, if available (otherwise "null") */
System.out.println("ExitCode: " + sess.getExitStatus());
/* Close this session */
sess.close();
/* Close the connection */
conn.close();
}
catch (IOException e)
{
e.printStackTrace(System.err);
try
{
/* Create a connection instance */
Connection conn = new Connection(hostname);
/* Now connect */
conn.connect();
/* Authenticate */
boolean isAuthenticated = conn.authenticateWithPassword(username, password);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
/* Create a session */
Session sess = conn.openSession();
sess.execCommand("echo \"Huge amounts of text on STDOUT\"; echo \"Huge amounts of text on STDERR\" >&2");
/*
* Advanced:
* The following is a demo on how one can read from stdout and
* stderr without having to use two parallel worker threads (i.e.,
* we don't use the Streamgobblers here) and at the same time not
* risking a deadlock (due to a filled SSH2 channel window, caused
* by the stream which you are currently NOT reading from =).
*/
/* Don't wrap these streams and don't let other threads work on
* these streams while you work with Session.waitForCondition()!!!
*/
InputStream stdout = sess.getStdout();
InputStream stderr = sess.getStderr();
byte[] buffer = new byte[8192];
while (true)
{
if ((stdout.available() == 0) && (stderr.available() == 0))
{
/* Even though currently there is no data available, it may be that new data arrives
* and the session's underlying channel is closed before we call waitForCondition().
* This means that EOF and STDOUT_DATA (or STDERR_DATA, or both) may
* be set together.
*/
int conditions = sess.waitForCondition(ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA
| ChannelCondition.EOF, 2000);
/* Wait no longer than 2 seconds (= 2000 milliseconds) */
if ((conditions & ChannelCondition.TIMEOUT) != 0)
{
/* A timeout occured. */
throw new IOException("Timeout while waiting for data from peer.");
}
/* Here we do not need to check separately for CLOSED, since CLOSED implies EOF */
if ((conditions & ChannelCondition.EOF) != 0)
{
/* The remote side won't send us further data... */
if ((conditions & (ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA)) == 0)
{
/* ... and we have consumed all data in the local arrival window. */
break;
}
}
/* OK, either STDOUT_DATA or STDERR_DATA (or both) is set. */
// You can be paranoid and check that the library is not going nuts:
// if ((conditions & (ChannelCondition.STDOUT_DATA | ChannelCondition.STDERR_DATA)) == 0)
// throw new IllegalStateException("Unexpected condition result (" + conditions + ")");
}
/* If you below replace "while" with "if", then the way the output appears on the local
* stdout and stder streams is more "balanced". Addtionally reducing the buffer size
* will also improve the interleaving, but performance will slightly suffer.
* OKOK, that all matters only if you get HUGE amounts of stdout and stderr data =)
*/
while (stdout.available() > 0)
{
int len = stdout.read(buffer);
if (len > 0) // this check is somewhat paranoid
System.out.write(buffer, 0, len);
}
while (stderr.available() > 0)
{
int len = stderr.read(buffer);
if (len > 0) // this check is somewhat paranoid
System.err.write(buffer, 0, len);
}
}
/* Close this session */
sess.close();
/* Close the connection */
conn.close();
}
catch (IOException e)
{
e.printStackTrace(System.err);
this.username = username;
}
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"))
{
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, esd.answer);
if (res == true)
break;
lastError = "DSA authentication failed.";
}
enableDSA = false; // do not try again
}
if (enableRSA)
{
File key = new File(idRSAPath);
if (key.exists())
{
EnterSomethingDialog esd = new EnterSomethingDialog(loginFrame, "RSA Authentication",
new String[] { lastError, "Enter RSA private key password:" }, true);
esd.setVisible(true);
boolean res = conn.authenticateWithPublicKey(username, key, esd.answer);
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);
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"))
{
final EnterSomethingDialog esd = new EnterSomethingDialog(loginFrame,
"Password Authentication",
new String[] { lastError, "Enter password for " + username }, true);
esd.setVisible(true);
if (esd.answer == null)
throw new IOException("Login aborted by user");
boolean res = conn.authenticateWithPassword(username, esd.answer);
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();
int x_width = 90;
int y_width = 30;
sess.requestPTY("dumb", x_width, y_width, 0, 0, null);
sess.startShell();
TerminalDialog td = new TerminalDialog(loginFrame, username + "@" + hostname, sess, x_width, y_width);
/* The following call blocks until the dialog has been closed */
td.setVisible(true);
}
catch (IOException e)
{
//e.printStackTrace();
JOptionPane.showMessageDialog(loginFrame, "Exception: " + e.getMessage());
}
/*
*
* CLOSE THE CONNECTION.
*
*/
conn.close();
/*
*
* CLOSE THE LOGIN FRAME - APPLICATION WILL BE EXITED (no more frames)
*
try
{
/* Create a connection instance */
Connection conn = new Connection(hostname);
/* Now connect */
conn.connect();
/* Authenticate */
boolean isAuthenticated = conn.authenticateWithPublicKey(username, keyfile, keyfilePass);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
/* ===== OK, now let's establish some local port forwardings ===== */
/* Example Port Forwarding: -L 8080:www.ethz.ch:80 (OpenSSH notation)
*
* This works by allocating a socket to listen on 8080 on the local interface (127.0.0.1).
* Whenever a connection is made to this port (127.0.0.1:8080), the connection is forwarded
* over the secure channel, and a connection is made to www.ethz.ch:80 from the remote
* machine (i.e., the ssh server).
*
* (the above text is based partially on the OpenSSH man page)
*/
/* You can create as many of them as you want */
LocalPortForwarder lpf1 = conn.createLocalPortForwarder(8080, "www.ethz.ch", 80);
/* Now simply point your webbrowser to 127.0.0.1:8080 */
/* (on the host where you execute this program) */
/* ===== OK, now let's establish some remote port forwardings ===== */
/* Example Port Forwarding: -R 127.0.0.1:8080:www.ganymed.ethz.ch:80 (OpenSSH notation)
*
* Specifies that the port 127.0.0.1:8080 on the remote server is to be forwarded to the
* given host and port on the local side. This works by allocating a socket to listen to port
* 8080 on the remote side (the ssh server), and whenever a connection is made to this port, the
* connection is forwarded over the secure channel, and a connection is made to
* www.ganymed.ethz.ch:80 by the Ganymed SSH-2 library.
*
* (the above text is based partially on the OpenSSH man page)
*/
/* You can create as many of them as you want */
conn.requestRemotePortForwarding("127.0.0.1", 8080, "www.ganymed.ethz.ch", 80);
/* Now, on the ssh server, if you connect to 127.0.0.1:8080, then the connection is forwarded
* through the secure tunnel to the library, which in turn will forward the connection
* to www.ganymed.ethz.ch:80. */
/* Sleep a bit... (30 seconds) */
sleepSomeTime(30000);
/* Stop accepting remote connections that are being forwarded to www.ganymed.ethz.ch:80 */
conn.cancelRemotePortForwarding(8080);
/* Sleep a bit... (20 seconds) */
sleepSomeTime(20000);
/* Stop accepting connections on 127.0.0.1:8080 that are being forwarded to www.ethz.ch:80 */
lpf1.close();
/* Close the connection */
conn.close();
}
catch (IOException e)
{
e.printStackTrace(System.err);
try
{
/* Create a connection instance */
Connection conn = new Connection(hostname);
/* Now connect */
conn.connect();
/* Authenticate.
* If you get an IOException saying something like
* "Authentication method password not supported by the server at this stage."
* then please check the FAQ.
*/
boolean isAuthenticated = conn.authenticateWithPassword(username, password);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
/* Create a session */
Session sess = conn.openSession();
sess.execCommand("uname -a && date && uptime && who");
System.out.println("Here is some information about the remote host:");
/*
* This basic example does not handle stderr, which is sometimes dangerous
* (please read the FAQ).
*/
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
while (true)
{
String line = br.readLine();
if (line == null)
break;
System.out.println(line);
}
/* Show exit status, if available (otherwise "null") */
System.out.println("ExitCode: " + sess.getExitStatus());
/* Close this session */
sess.close();
/* Close the connection */
conn.close();
}
catch (IOException e)
{
e.printStackTrace(System.err);
try
{
/* Create a connection instance */
Connection conn = new Connection(hostname);
/* Now connect */
conn.connect();
/* Authenticate */
boolean isAuthenticated = conn.authenticateWithPassword(username, password);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
/* Create a session */
Session sess = conn.openSession();
sess.execCommand("echo \"Text on STDOUT\"; echo \"Text on STDERR\" >&2");
InputStream stdout = new StreamGobbler(sess.getStdout());
InputStream stderr = new StreamGobbler(sess.getStderr());
BufferedReader stdoutReader = new BufferedReader(new InputStreamReader(stdout));
BufferedReader stderrReader = new BufferedReader(new InputStreamReader(stderr));
System.out.println("Here is the output from stdout:");
while (true)
{
String line = stdoutReader.readLine();
if (line == null)
break;
System.out.println(line);
}
System.out.println("Here is the output from stderr:");
while (true)
{
String line = stderrReader.readLine();
if (line == null)
break;
System.out.println(line);
}
/* Close this session */
sess.close();
/* Close the connection */
conn.close();
}
catch (IOException e)
{
e.printStackTrace(System.err);
if (knownHosts.exists())
database.addHostkeys(knownHosts);
/* Create a connection instance */
Connection conn = new Connection(hostname);
/* Now connect and use the SimpleVerifier */
conn.connect(new SimpleVerifier(database));
/* Authenticate */
boolean isAuthenticated = conn.authenticateWithPassword(username, password);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
/* Create a session */
Session sess = conn.openSession();
sess.execCommand("uname -a && date && uptime && who");
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
System.out.println("Here is some information about the remote host:");
while (true)
{
String line = br.readLine();
if (line == null)
break;
System.out.println(line);
}
/* Close this session */
sess.close();
/* Close the connection */
conn.close();
}
catch (IOException e)
{
e.printStackTrace(System.err);
try
{
/* Create a connection instance */
Connection conn = new Connection(hostname);
/* Now connect */
conn.connect();
/* Authenticate */
boolean isAuthenticated = conn.authenticateWithPublicKey(username, keyfile, keyfilePass);
if (isAuthenticated == false)
throw new IOException("Authentication failed.");
/* Create a session */
Session sess = conn.openSession();
sess.execCommand("uname -a && date && uptime && who");
InputStream stdout = new StreamGobbler(sess.getStdout());
BufferedReader br = new BufferedReader(new InputStreamReader(stdout));
System.out.println("Here is some information about the remote host:");
while (true)
{
String line = br.readLine();
if (line == null)
break;
System.out.println(line);
}
/* Close this session */
sess.close();
/* Close the connection */
conn.close();
}
catch (IOException e)
{
e.printStackTrace(System.err);
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::Connect";
try {
isConnected = false;
this.setSshConnection(new Connection(pstrHostName, pintPortNumber));
}
catch (Exception e) {
if (this.getSshConnection() != null)
try {
@SuppressWarnings("unused")
final String conMethodName = conClassName + "::Connect";
try {
isConnected = false;
this.setSshConnection(new Connection(objCO.getHost().Value(), objCO.getPort().value()));
if (objCO.getProxy_host().IsNotEmpty()) {
HTTPProxyData objProxy = null;
if (objCO.getProxy_user().IsEmpty()) {
objProxy = new HTTPProxyData(objCO.getProxy_host().Value(), objCO.getProxy_port().value());
Related Classes of ch.ethz.ssh2.KnownHosts
Copyright © 2018 www.massapicom. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.