--- trilead-ssh2-6401.orig/debian/libtrilead-ssh2-java.jlibs
+++ trilead-ssh2-6401/debian/libtrilead-ssh2-java.jlibs
@@ -0,0 +1 @@
+trilead-ssh2.jar
--- trilead-ssh2-6401.orig/debian/compat
+++ trilead-ssh2-6401/debian/compat
@@ -0,0 +1 @@
+7
--- trilead-ssh2-6401.orig/debian/javabuild
+++ trilead-ssh2-6401/debian/javabuild
@@ -0,0 +1 @@
+trilead-ssh2.jar src
--- trilead-ssh2-6401.orig/debian/libtrilead-ssh2-java.javadoc
+++ trilead-ssh2-6401/debian/libtrilead-ssh2-java.javadoc
@@ -0,0 +1 @@
+internal
--- trilead-ssh2-6401.orig/debian/FAQ.html
+++ trilead-ssh2-6401/debian/FAQ.html
@@ -0,0 +1,389 @@
+
+
Trilead SSH-2 for Java FAQ
+
+
+
+Trilead SSH-2 for Java FAQ
+
+
+This FAQ includes information regarding topics that were discussed in e-mails between developers and users
+of the Trilead SSH-2 for Java library.
+
+
+Trilead homepage: http://www.trilead.ethz.ch
+Last update of FAQ: oct-15-2007.
+
+
+Please report bugs, typos and any kind of suggestions to support@trilead.com.
+Also, please visit our support forum.
+
+
+
+
+Sections:
+
+
+
+
+
+
When I start program XYZ with putty (or openssh, ..., whatever) then everything
+works. However, if I use "Session.execCommand", then XYZ behaves differently or does not work at all!
+
+Short answer:
+
+
+The most often source of problems when executing a command with Session.execCommand()
+are missing/wrong set environment variables on the remote machine. Make sure that the minimum needed
+environment for XYZ is the same, independentely on how the shell is being invoked.
+
+
+
+Example quickfix for bash users:
+
+
+
+
+- Define all your settings in the file ~/.bashrc
+- Make sure that the file ~/.bash_profile only contains the line source
+~/.bashrc.
+- Before executing Session.execCommand(), do NOT aquire any type of pseudo terminal in the
+session. Be prepared to consume stdout and stderr data.
+
+
+
+
+Note: If you really want to mimic the behavior of putty, then don't use Session.execCommand(),
+instead aquire a pty (pseudo terminal) and then start a shell (use Session.requestPTY() and
+Session.startShell()). You then have to communicate with the shell process at the other end
+through stdin and stdout. However, you also have to implement terminal logic (e.g., escape sequence
+handling (unless you use a "dumb" pty), "expect-send" logic (output parsing, shell prompt detection), etc.).
+
+
+Long answer:
+
+
+If you login by using putty, then putty will normally request a "xterm" pty and your assigned shell
+(e.g., bash) will be started (a so called "interactive login shell"). In contrast, if you use
+Session.execCommand() to start a command then (unless you ask for it) no pty will be aquired
+and the command will be given to the shell as an argument (with the shell's "-c" option).
+
+
+
+The way a shell is being invoked has an effect on the set of initialization files which will be read be the shell.
+
+
+
+To demonstrate the difference, try the following (from the command line, e.g., with an OpenSSH client):
+
+
+
+
+- Login interactively and print the environment with the "env" command:
+[user@host ~] ssh 127.0.0.1
+[user@host ~] env
+
+- Let the ssh server execute the "env" command (equivalent to using Session.executeCommand()):
+[user@host ~] ssh 127.0.0.1 "env"
+
+
+
+
+
+If you compare the two outputs, then you will (unless you have adjusted your shell's settings)
+observe different environments.
+
+
+
+If you are interested in the details, then please read the INVOCATION section in man page
+for the bash shell. You may notice that the definitions of "interactive" and "non-interactive"
+(and combinations with "login") are little bit tricky.
+
+
+[TOP]
+
+
My program sometimes hangs when I only read output from stdout!
+Or: can you explain me the story about the shared stdout/stderr window in the SSH-2 protocol?
+Or: what is this "StreamGobbler" thing all about?
+
+
+In the SSH-2 low level protocol, each channel (e.g., session) has a receive window. When the remote
+SSH daemon has filled up our receive window, it must wait until we have consumed the input and are ready to accept new data.
+
+
+
+Unfortunately, the SSH-2 protocol defines a shared window for stderr and stdout. As a consequence,
+if, for example, the remote process produces a lot of stderr data and you never consume it, then after
+some time the local receive window will be full and the sender is blocked. If you then try to read()
+from stdout, your call will be blocked: there is no stdout data (locally) available and the SSH daemon
+cannot send you any, since the receive window is full (you would have to read some stderr data first
+to "free" up space in the receive window).
+
+
+
+Fortunately, Trilead SSH-2 uses a 30KB window - the above described scenario should be very rare.
+
+
+
+Many other SSH-2 client implementations just blindly consume any remotely produced data into a buffer
+which gets automatically extended - however, this can lead to another problem: in the extreme case
+the remote side can overflow you with data (e.g., leading to out of memory errors).
+
+
+
+What can you do about this?
+
+
+
+
+- Bad: Do nothing - just work with stderr and stdout Inputstreams and hope that the 30KB
+window is enough for your application.
+
+- Better, recommended for most users: use two worker threads that consume remote stdout
+and stderr in parallel. Since you probably are not in the mood to program such a thing, you can use
+the StreamGobbler class supplied with Trilead SSH-2. The Streamgobbler is a special InputStream that
+uses an internal worker thread to read and buffer internally all data produced by another InputStream.
+It is very simple to use:
InputStream stdout = new StreamGobbler(mysession.getStdout());
+
+InputStream stderr = new StreamGobbler(mysession.getStderr());
+You then can access stdout and stderr in any order, in the background the StreamGobblers will
+automatically consume all data from the remote side and store in an internal buffer.
+
+- Advanced: you are paranoid and don't like programs that automatically extend buffers
+without asking you. You then have to implement a state machine. The condition wait facility offered by
+Session.waitForCondition() is exactly what you need: you can use it to wait until either stdout
+or stderr data has arrived and can be consumed with the two InputStreams. You can either use the return value
+of Session.waitForCondition() or check with InputStream.available()
+(for stdout and stderr) which InputStream has data available (i.e., a read() call will not block).
+Be careful when wrapping the InputStreams, also do not concurrently call read() on the InputStreams while calling
+Session.waitForCondition() (unless you know what you are doing).
Please have a look a the
+SingleThreadStdoutStderr.java example.
+
+- The lazy way: you don't mind if stdout and stderr data is being mixed into the same
+stream. Just allocate a "dumb" pty and the server will hopefully not send you any data on the stderr
+stream anymore. Note: by allocating a pty, the shell used to execute the command will probably
+behave differently in terms of initialization (see also this question).
+
+
+
+
+[TOP]
+
+
Why are the session's Input- and OutputStreams not buffered?
+
+
+If you need it, then this library offers quite a raw type of access to the SSH-2 protocol stack.
+Of course, many people don't need that kind of low level access. If you need buffered streams,
+then you should the do the same thing as you would probably do with the streams of a TCP socket:
+wrap them with instances of BufferedInputStream and BufferedOutputStream. In case you use
+StreamGobblers for the InputStreams, then you don't need any additional wrappers, since the
+StreamGobblers implement buffering already.
+
+
+This code snippet will probably work well for most people:
+
+
+
+
+InputStream stdout = new StreamGobbler(mysession.getStdout());
+InputStream stderr = new StreamGobbler(mysession.getStderr());
+OutputStream stdin = new BufferedOutputStream(mysession.getStdin(), 8192);
+
+
+
+
+[TOP]
+
+
Why can't I execute several commands in one single session?
+
+If you use Session.execCommand(), then you indeed can only execute only one command per session.
+This is not a restriction of the library, but rather an enforcement by the underlying SSH-2 protocol
+(a Session object models the underlying SSH-2 session).
+
+
+There are several solutions:
+
+
+
+- Simple: Execute several commands in one batch, e.g., something like Session.execCommand("echo
+Hello && echo again").
+- Simple: The intended way: simply open a new session for each command - once you have opened a
+connection, you can ask for as many sessions as you want, they are only a "virtual" construct.
+- Advanced: Don't use Session.execCommand(), but rather aquire a shell with
+Session.startShell(). See also this question.
+
+
+
+
+[TOP]
+
+
I cannot open more than 10 concurrent sessions (or SCP clients).
+
+You are probably using OpenSSH. By looking at their source code you will find out that there
+is a hard-coded constant called MAX_SESSIONS in the session.c file which is set to "10" by default.
+This is a per connection limit. Unfortunately, it is not a run-time tunable parameter.
+However, this limit has no effect on the number of concurrent port forwardings. Please note: this information
+is based on the OpenSSH 4.3 release.
+
+
+Possible solutions:
+
+- (a) Recompile your SSH daemon
+- (b) Try to live with this limit and keep the number of concurrent sessions <= 10.
+- (c) Distribute your sessions over multiple concurrent SSH connections.
+
+
+
+Just for completeness: starting from release 210, the thrown exception may look as follows:
+
+
+java.io.IOException: Could not open channel (The server refused to open the channel (SSH_OPEN_ADMINISTRATIVELY_PROHIBITED, 'open failed'))
+
+
+
+
+[TOP]
+
+
Password authentication fails, I get "Authentication method password
+not supported by the server at this stage".
+
+
+Many default SSH server installations are configured to refuse the authentication type "password".
+Often, they only accept "publickey" and "keyboard-interactive". You have different options:
+
+
+
+
+- Enable password authentication. E.g., in case of OpenSSH on Fedora, edit
+
/etc/sshd/sshd_config
and change the value of "PasswordAuthentication" to "yes",
+then send a HUP signal to the daemon so that it re-reads its configuration.
+- Switch to public-key authentication. Probably the best choice.
+- Try to use keyboard-interactive authentication. If you have a GUI that interacts with a user,
+then this is doable (check out the SwingShell.java example).
+
+
+
+
+In general it is a good idea to call either Connection.getRemainingAuthMethods()
+or Connection.isAuthMethodAvailable()
before using a certain authentication method.
+
+
+
+Please note that most servers let you in after one successful authentication step. However, in rare cases
+you may encounter servers that need several steps. I.e., if one of the Connection.authenticateWithXXX()
+methods returns false
and Connection.isAuthenticationPartialSuccess()
returns
+true
, then further authentication is needed. For each step, to find out which authentication methods
+may proceed, you can use either the Connection.getRemainingAuthMethods()
+or the Connection.isAuthMethodAvailable()
method. Again, please have a look into the
+SwingShell.java example.
+
+
+[TOP]
+
+
Why does public key authentication fail with my putty key?
+
+When using putty private keys (e.g., .ppk files) with public key authentication, you get a
+"Publickey authentication failed" exception. The reason is that the library currently is not able to
+directly handle private keys in the proprietary format used by putty. However, you can use the
+"puttygen" tool (from the putty website) to convert your key to the desired format: load your key,
+then go to the conversions menu and select "Save OpenSSH key" (which saves the key in openssl PEM format,
+e.g., call it "private.pem").
+
+
+[TOP]
+
+
I am sending data to a remote file using the "cat" method, but not all data is being written.
+
+Please read carefully the answer to the following question.
+
+
+[TOP]
+
+
+
I want to pump data into a remote file, but the amount of data to be sent
+is not known at the time the transfer starts.
+
+The SCP protocol communicates the amount of data to be sent at the start of the transfer,
+so SCP remains out of consideration. Possible other solutions:
+
+- Use the SFTP client. Recommended.
+- Execute "cat > filename.txt" on the remote side and pump the data into stdin. This method is NOT recommended (and won't work on Windows...).
+
+
+
+Be careful if you use the "cat" approach, as it may happen that not all your data will be
+written. If you close the stdin stream and immediatelly close the session (or the whole connection) then
+some SSH servers do not send the pending data to the process being executed ("cat" in this case).
+You have to wait until "cat" has received the EOF and terminates before closing the session. However,
+waiting for the termination may not always work, since SSH servers sometimes "forget" to send the exit code
+of the remote process. The following code MAY work:
+
+
+
+
+Session sess = conn.openSession();
+sess.execCommand("cat > test.txt");
+OutputStream stdin = sess.getStdin();
+
+... out.write(...) ... out.write(...) ...
+
+/* The following flush() is only needed if you wrap the */
+/* stdin stream (e.g., with a BufferedOutputStream). */
+out.flush();
+
+/* Now let's send EOF */
+out.close();
+
+/* Let's wait until cat has finished */
+sess.waitForCondition(ChannelCondition.EXIT_STATUS, 2000);
+/* Better: put the above statement into a while loop! */
+/* In ANY CASE: read the Javadocs for waitForCondition() */
+
+/* Show exit status, if available (otherwise "null") */
+System.out.println("ExitCode: " + sess.getExitStatus());
+/* Now its hopefully safe to close the session */
+sess.close();
+
+
+
+
+(Just a thought for another solution: execute cat > test.txt && echo "FINISHED"
+and wait until you get "FINISHED" on stdout... - try it on your own risk =)
+
+
+[TOP]
+
+
Do you have an example for the usage of feature XYZ?
+
+Please have at look at the examples section in the distribution, especially at the SwingShell.java example.
+
+
+[TOP]
+
+
+
+
--- trilead-ssh2-6401.orig/debian/README.txt
+++ trilead-ssh2-6401/debian/README.txt
@@ -0,0 +1,24 @@
+
+Trilead SSH-2 for Java - build 211
+==================================
+
+http://www.trilead.com
+
+Trilead SSH-2 for Java is a library which implements the SSH-2 protocol in pure Java
+(minimum required JRE: 1.4.2). It allows one to connect to SSH servers from within
+Java programs. It supports SSH sessions (remote command execution and shell access),
+local and remote port forwarding, local stream forwarding, X11 forwarding, SCP and SFTP.
+There are no dependencies on any JCE provider, as all crypto functionality is included.
+
+This distribution contains the source code, examples, javadoc and the FAQ.
+It also includes a pre-compiled jar version of the library which is ready to use.
+
+- Please read the included LICENCE.txt
+- Latest changes can be found in HISTORY.txt
+
+The latest version of the FAQ is available on the website.
+
+Please feel free to contact us. We welcome feedback of any kind!
+Contact: support@trilead.com or go to the public forum at http://www.trilead.com
+
+Zurich, October 2007
--- trilead-ssh2-6401.orig/debian/rules
+++ trilead-ssh2-6401/debian/rules
@@ -0,0 +1,10 @@
+#!/usr/bin/make -f
+
+# Uncomment this to turn on verbose mode.
+#export DH_VERBOSE=1
+
+export JAVA_HOME=/usr/lib/jvm/default-java
+
+%:
+ dh --with javahelper $@
+
--- trilead-ssh2-6401.orig/debian/changelog
+++ trilead-ssh2-6401/debian/changelog
@@ -0,0 +1,28 @@
+trilead-ssh2 (6401-1) unstable; urgency=low
+
+ * Switch upstream to svnkit
+ * New upstream release
+ * Version is svn revision from svnkit
+ * Import readme, faq and examples from old upstream
+
+ -- Matthew Johnson Sat, 20 Feb 2010 13:52:54 +0000
+
+trilead-ssh2 (211-3) unstable; urgency=low
+
+ * Use javahelper rather than dh_javadoc
+
+ -- Matthew Johnson Sat, 12 Dec 2009 10:33:09 +0000
+
+trilead-ssh2 (211-2) unstable; urgency=low
+
+ * Change to debhelper 7
+ * Add build-dep on gjdoc because that's where dh_javadoc is now
+ * Change to section java
+
+ -- Matthew Johnson Thu, 13 Aug 2009 00:12:29 +0100
+
+trilead-ssh2 (211-1) unstable; urgency=low
+
+ * Initial release. (Closes: #466694)
+
+ -- Matthew Johnson Wed, 20 Feb 2008 11:41:06 +0000
--- trilead-ssh2-6401.orig/debian/libtrilead-ssh2-java.docs
+++ trilead-ssh2-6401/debian/libtrilead-ssh2-java.docs
@@ -0,0 +1,3 @@
+debian/README.txt
+debian/examples
+debian/FAQ.html
--- trilead-ssh2-6401.orig/debian/control
+++ trilead-ssh2-6401/debian/control
@@ -0,0 +1,20 @@
+Source: trilead-ssh2
+Section: java
+Priority: optional
+Maintainer: Matthew Johnson
+Build-Depends: debhelper (>> 7), javahelper (>=0.25)
+Build-Depends-Indep: default-jdk
+Standards-Version: 3.7.3
+Homepage: http://svn.svnkit.com/repos/svnkit/tags/1.3.2/contrib/trilead/
+
+Package: libtrilead-ssh2-java
+Architecture: all
+Depends: ${java:Depends}, ${misc:Depends}
+Description: Java SSH libarary
+ Trilead SSH for Java is a freely available open-source library which
+ implements the SSH-2 protocol in pure Java (tested on J2SE 1.4.2 and 5.0). It
+ allows one to connect to SSH servers from within Java programs. It supports
+ SSH sessions (remote command execution and shell access), local and remote
+ port forwarding, local stream forwarding, X11 forwarding, SCP and SFTP. There
+ are no dependencies on any JCE provider, as all crypto functionality is
+ included.
--- trilead-ssh2-6401.orig/debian/copyright
+++ trilead-ssh2-6401/debian/copyright
@@ -0,0 +1,97 @@
+This package was Debianised by Matthew Johnson on Wed Feb 20 11:41:05 GMT 2008
+
+This package was originally downloaded from http://www.trilead.com/Download/Trilead-SSH-2-Java/,
+but now upstream is http://svn.svnkit.com/repos/svnkit/tags/1.3.2/contrib/trilead/
+
+Copyright (c) 2007 Trilead AG (http://www.trilead.com)
+
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+a.) Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+b.) Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+c.) Neither the name of Trilead nor the names of its contributors may
+ be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+Trilead SSH-2 for Java includes code that was written by Dr. Christian Plattner
+during his PhD at ETH Zurich. The license states the following:
+
+Copyright (c) 2005 - 2006 Swiss Federal Institute of Technology (ETH Zurich),
+ Department of Computer Science (http://www.inf.ethz.ch),
+ Christian Plattner. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions
+are met:
+
+a.) Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+b.) Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+c.) Neither the name of ETH Zurich nor the names of its contributors may
+ be used to endorse or promote products derived from this software
+ without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+
+The Java implementations of the AES, Blowfish and 3DES ciphers have been
+taken (and slightly modified) from the cryptography package released by
+"The Legion Of The Bouncy Castle".
+
+Their license states the following:
+
+Copyright (c) 2000 - 2004 The Legion Of The Bouncy Castle
+(http://www.bouncycastle.org)
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+
+
+The packaging is Copyright 2008 Matthew Johnson and is licenced
+under the terms of the BSD licence. On Debian systems the BSD licence can be
+found in /usr/share/common-licenses/BSD.
--- trilead-ssh2-6401.orig/debian/examples/PortForwarding.java
+++ trilead-ssh2-6401/debian/examples/PortForwarding.java
@@ -0,0 +1,116 @@
+import java.io.File;
+import java.io.IOException;
+
+import com.trilead.ssh2.Connection;
+import com.trilead.ssh2.LocalPortForwarder;
+
+/**
+ * This example shows how to deal with port forwardings.
+ *
+ * @author Christian Plattner, plattner@trilead.com
+ * @version $Id: PortForwarding.java,v 1.2 2007/10/15 12:49:57 cplattne Exp $
+ */
+public class PortForwarding
+{
+ public static void sleepSomeTime(long milliSeconds)
+ {
+ try
+ {
+ Thread.sleep(milliSeconds);
+ }
+ catch (InterruptedException e)
+ {
+ }
+ }
+
+ public static void main(String[] args)
+ {
+ String hostname = "127.0.0.1";
+ String username = "joe";
+
+ File keyfile = new File("~/.ssh/id_rsa"); // or "~/.ssh/id_dsa"
+ String keyfilePass = "joespass"; // will be ignored if not needed
+
+ 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.icann.org: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.icann.org: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.icann.org", 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.ripe.net: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.ripe.net:80 by the Trilead 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.ripe.net", 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.ripe.net:80. */
+
+ /* Sleep a bit... (30 seconds) */
+ sleepSomeTime(30000);
+
+ /* Stop accepting remote connections that are being forwarded to www.ripe.net: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.icann.org:80 */
+
+ lpf1.close();
+
+ /* Close the connection */
+
+ conn.close();
+
+ }
+ catch (IOException e)
+ {
+ e.printStackTrace(System.err);
+ System.exit(2);
+ }
+ }
+}
--- trilead-ssh2-6401.orig/debian/examples/PublicKeyAuthentication.java
+++ trilead-ssh2-6401/debian/examples/PublicKeyAuthentication.java
@@ -0,0 +1,80 @@
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import com.trilead.ssh2.Connection;
+import com.trilead.ssh2.Session;
+import com.trilead.ssh2.StreamGobbler;
+
+/**
+ * This example shows how to login using
+ * public key authentication.
+ *
+ * @author Christian Plattner, plattner@trilead.com
+ * @version $Id: PublicKeyAuthentication.java,v 1.2 2007/10/15 12:49:57 cplattne Exp $
+ */
+public class PublicKeyAuthentication
+{
+ public static void main(String[] args)
+ {
+ String hostname = "127.0.0.1";
+ String username = "joe";
+
+ File keyfile = new File("~/.ssh/id_rsa"); // or "~/.ssh/id_dsa"
+ String keyfilePass = "joespass"; // will be ignored if not needed
+
+ 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);
+ System.exit(2);
+ }
+ }
+}
--- trilead-ssh2-6401.orig/debian/examples/SwingShell.java
+++ trilead-ssh2-6401/debian/examples/SwingShell.java
@@ -0,0 +1,786 @@
+import java.awt.BorderLayout;
+import java.awt.Color;
+import java.awt.FlowLayout;
+import java.awt.Font;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.KeyAdapter;
+import java.awt.event.KeyEvent;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+
+import javax.swing.BoxLayout;
+import javax.swing.JButton;
+import javax.swing.JDialog;
+import javax.swing.JFrame;
+import javax.swing.JLabel;
+import javax.swing.JOptionPane;
+import javax.swing.JPanel;
+import javax.swing.JPasswordField;
+import javax.swing.JTextArea;
+import javax.swing.JTextField;
+import javax.swing.SwingUtilities;
+
+import com.trilead.ssh2.Connection;
+import com.trilead.ssh2.InteractiveCallback;
+import com.trilead.ssh2.KnownHosts;
+import com.trilead.ssh2.ServerHostKeyVerifier;
+import com.trilead.ssh2.Session;
+
+/**
+ * This is a very primitive SSH-2 dumb terminal (Swing based).
+ *
+ * The purpose of this class is to demonstrate:
+ *
+ * - Verifying server hostkeys with an existing known_hosts file
+ * - Displaying fingerprints of server hostkeys
+ * - Adding a server hostkey to a known_hosts file (+hashing the hostname for security)
+ * - Authentication with DSA, RSA, password and keyboard-interactive methods
+ *
+ *
+ * @author Christian Plattner, plattner@trilead.com
+ * @version $Id: SwingShell.java,v 1.10 2007/10/15 12:49:57 cplattne Exp $
+ *
+ */
+public class SwingShell
+{
+ /*
+ * NOTE: to get this feature to work, replace the "tilde" with your home directory,
+ * at least my JVM does not understand it. Need to check the specs.
+ */
+
+ static final String knownHostPath = "~/.ssh/known_hosts";
+ static final String idDSAPath = "~/.ssh/id_dsa";
+ static final String idRSAPath = "~/.ssh/id_rsa";
+
+ JFrame loginFrame = null;
+ JLabel hostLabel;
+ JLabel userLabel;
+ JTextField hostField;
+ JTextField userField;
+ JButton loginButton;
+
+ KnownHosts database = new KnownHosts();
+
+ public SwingShell()
+ {
+ File knownHostFile = new File(knownHostPath);
+ if (knownHostFile.exists())
+ {
+ try
+ {
+ database.addHostkeys(knownHostFile);
+ }
+ catch (IOException e)
+ {
+ }
+ }
+ }
+
+ /**
+ * This dialog displays a number of text lines and a text field.
+ * The text field can either be plain text or a password field.
+ */
+ class EnterSomethingDialog extends JDialog
+ {
+ private static final long serialVersionUID = 1L;
+
+ JTextField answerField;
+ JPasswordField passwordField;
+
+ final boolean isPassword;
+
+ String answer;
+
+ public EnterSomethingDialog(JFrame parent, String title, String content, boolean isPassword)
+ {
+ this(parent, title, new String[] { content }, isPassword);
+ }
+
+ public EnterSomethingDialog(JFrame parent, String title, String[] content, boolean isPassword)
+ {
+ super(parent, title, true);
+
+ this.isPassword = isPassword;
+
+ JPanel pan = new JPanel();
+ pan.setLayout(new BoxLayout(pan, BoxLayout.Y_AXIS));
+
+ for (int i = 0; i < content.length; i++)
+ {
+ if ((content[i] == null) || (content[i] == ""))
+ continue;
+ JLabel contentLabel = new JLabel(content[i]);
+ pan.add(contentLabel);
+
+ }
+
+ answerField = new JTextField(20);
+ passwordField = new JPasswordField(20);
+
+ if (isPassword)
+ pan.add(passwordField);
+ else
+ pan.add(answerField);
+
+ KeyAdapter kl = new KeyAdapter()
+ {
+ public void keyTyped(KeyEvent e)
+ {
+ if (e.getKeyChar() == '\n')
+ finish();
+ }
+ };
+
+ answerField.addKeyListener(kl);
+ passwordField.addKeyListener(kl);
+
+ getContentPane().add(BorderLayout.CENTER, pan);
+
+ setResizable(false);
+ pack();
+ setLocationRelativeTo(null);
+ }
+
+ private void finish()
+ {
+ if (isPassword)
+ answer = new String(passwordField.getPassword());
+ else
+ answer = answerField.getText();
+
+ dispose();
+ }
+ }
+
+ /**
+ * TerminalDialog is probably the worst terminal emulator ever written - implementing
+ * a real vt100 is left as an exercise to the reader, i.e., to you =)
+ *
+ */
+ class TerminalDialog extends JDialog
+ {
+ private static final long serialVersionUID = 1L;
+
+ JPanel botPanel;
+ JButton logoffButton;
+ JTextArea terminalArea;
+
+ Session sess;
+ InputStream in;
+ OutputStream out;
+
+ int x, y;
+
+ /**
+ * This thread consumes output from the remote server and displays it in
+ * the terminal window.
+ *
+ */
+ class RemoteConsumer extends Thread
+ {
+ char[][] lines = new char[y][];
+ int posy = 0;
+ int posx = 0;
+
+ private void addText(byte[] data, int len)
+ {
+ for (int i = 0; i < len; i++)
+ {
+ char c = (char) (data[i] & 0xff);
+
+ if (c == 8) // Backspace, VERASE
+ {
+ if (posx < 0)
+ continue;
+ posx--;
+ continue;
+ }
+
+ if (c == '\r')
+ {
+ posx = 0;
+ continue;
+ }
+
+ if (c == '\n')
+ {
+ posy++;
+ if (posy >= y)
+ {
+ for (int k = 1; k < y; k++)
+ lines[k - 1] = lines[k];
+ posy--;
+ lines[y - 1] = new char[x];
+ for (int k = 0; k < x; k++)
+ lines[y - 1][k] = ' ';
+ }
+ continue;
+ }
+
+ if (c < 32)
+ {
+ continue;
+ }
+
+ if (posx >= x)
+ {
+ posx = 0;
+ posy++;
+ if (posy >= y)
+ {
+ posy--;
+ for (int k = 1; k < y; k++)
+ lines[k - 1] = lines[k];
+ lines[y - 1] = new char[x];
+ for (int k = 0; k < x; k++)
+ lines[y - 1][k] = ' ';
+ }
+ }
+
+ if (lines[posy] == null)
+ {
+ lines[posy] = new char[x];
+ for (int k = 0; k < x; k++)
+ lines[posy][k] = ' ';
+ }
+
+ lines[posy][posx] = c;
+ posx++;
+ }
+
+ StringBuffer sb = new StringBuffer(x * y);
+
+ for (int i = 0; i < lines.length; i++)
+ {
+ if (i != 0)
+ sb.append('\n');
+
+ if (lines[i] != null)
+ {
+ sb.append(lines[i]);
+ }
+
+ }
+ setContent(sb.toString());
+ }
+
+ public void run()
+ {
+ byte[] buff = new byte[8192];
+
+ try
+ {
+ while (true)
+ {
+ int len = in.read(buff);
+ if (len == -1)
+ return;
+ addText(buff, len);
+ }
+ }
+ catch (Exception e)
+ {
+ }
+ }
+ }
+
+ public TerminalDialog(JFrame parent, String title, Session sess, int x, int y) throws IOException
+ {
+ super(parent, title, true);
+
+ this.sess = sess;
+
+ in = sess.getStdout();
+ out = sess.getStdin();
+
+ this.x = x;
+ this.y = y;
+
+ botPanel = new JPanel(new FlowLayout(FlowLayout.LEFT));
+
+ logoffButton = new JButton("Logout");
+ botPanel.add(logoffButton);
+
+ logoffButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(ActionEvent e)
+ {
+ /* Dispose the dialog, "setVisible(true)" method will return */
+ dispose();
+ }
+ });
+
+ Font f = new Font("Monospaced", Font.PLAIN, 16);
+
+ terminalArea = new JTextArea(y, x);
+ terminalArea.setFont(f);
+ terminalArea.setBackground(Color.BLACK);
+ terminalArea.setForeground(Color.ORANGE);
+ /* This is a hack. We cannot disable the caret,
+ * since setting editable to false also changes
+ * the meaning of the TAB key - and I want to use it in bash.
+ * Again - this is a simple DEMO terminal =)
+ */
+ terminalArea.setCaretColor(Color.BLACK);
+
+ KeyAdapter kl = new KeyAdapter()
+ {
+ public void keyTyped(KeyEvent e)
+ {
+ int c = e.getKeyChar();
+
+ try
+ {
+ out.write(c);
+ }
+ catch (IOException e1)
+ {
+ }
+ e.consume();
+ }
+ };
+
+ terminalArea.addKeyListener(kl);
+
+ getContentPane().add(terminalArea, BorderLayout.CENTER);
+ getContentPane().add(botPanel, BorderLayout.PAGE_END);
+
+ setResizable(false);
+ pack();
+ setLocationRelativeTo(parent);
+
+ new RemoteConsumer().start();
+ }
+
+ public void setContent(String lines)
+ {
+ // setText is thread safe, it does not have to be called from
+ // the Swing GUI thread.
+ terminalArea.setText(lines);
+ }
+ }
+
+ /**
+ * This ServerHostKeyVerifier asks the user on how to proceed if a key cannot be found
+ * in the in-memory database.
+ *
+ */
+ class AdvancedVerifier implements ServerHostKeyVerifier
+ {
+ public boolean verifyServerHostKey(String hostname, int port, String serverHostKeyAlgorithm,
+ byte[] serverHostKey) throws Exception
+ {
+ final String host = hostname;
+ final String algo = serverHostKeyAlgorithm;
+
+ String message;
+
+ /* Check database */
+
+ int result = database.verifyHostkey(hostname, serverHostKeyAlgorithm, serverHostKey);
+
+ switch (result)
+ {
+ case KnownHosts.HOSTKEY_IS_OK:
+ return true;
+
+ case KnownHosts.HOSTKEY_IS_NEW:
+ message = "Do you want to accept the hostkey (type " + algo + ") from " + host + " ?\n";
+ break;
+
+ case KnownHosts.HOSTKEY_HAS_CHANGED:
+ message = "WARNING! Hostkey for " + host + " has changed!\nAccept anyway?\n";
+ break;
+
+ default:
+ throw new IllegalStateException();
+ }
+
+ /* Include the fingerprints in the message */
+
+ String hexFingerprint = KnownHosts.createHexFingerprint(serverHostKeyAlgorithm, serverHostKey);
+ String bubblebabbleFingerprint = KnownHosts.createBubblebabbleFingerprint(serverHostKeyAlgorithm,
+ serverHostKey);
+
+ message += "Hex Fingerprint: " + hexFingerprint + "\nBubblebabble Fingerprint: " + bubblebabbleFingerprint;
+
+ /* Now ask the user */
+
+ int choice = JOptionPane.showConfirmDialog(loginFrame, message);
+
+ if (choice == JOptionPane.YES_OPTION)
+ {
+ /* Be really paranoid. We use a hashed hostname entry */
+
+ String hashedHostname = KnownHosts.createHashedHostname(hostname);
+
+ /* Add the hostkey to the in-memory database */
+
+ database.addHostkey(new String[] { hashedHostname }, serverHostKeyAlgorithm, serverHostKey);
+
+ /* Also try to add the key to a known_host file */
+
+ try
+ {
+ KnownHosts.addHostkeyToFile(new File(knownHostPath), new String[] { hashedHostname },
+ serverHostKeyAlgorithm, serverHostKey);
+ }
+ catch (IOException ignore)
+ {
+ }
+
+ return true;
+ }
+
+ if (choice == JOptionPane.CANCEL_OPTION)
+ {
+ throw new Exception("The user aborted the server hostkey verification.");
+ }
+
+ return false;
+ }
+ }
+
+ /**
+ * The logic that one has to implement if "keyboard-interactive" autentication shall be
+ * supported.
+ *
+ */
+ class InteractiveLogic implements InteractiveCallback
+ {
+ int promptCount = 0;
+ String lastError;
+
+ public InteractiveLogic(String lastError)
+ {
+ this.lastError = lastError;
+ }
+
+ /* the callback may be invoked several times, depending on how many questions-sets the server sends */
+
+ public String[] replyToChallenge(String name, String instruction, int numPrompts, String[] prompt,
+ boolean[] echo) throws IOException
+ {
+ String[] result = new String[numPrompts];
+
+ for (int i = 0; i < numPrompts; i++)
+ {
+ /* Often, servers just send empty strings for "name" and "instruction" */
+
+ String[] content = new String[] { lastError, name, instruction, prompt[i] };
+
+ if (lastError != null)
+ {
+ /* show lastError only once */
+ lastError = null;
+ }
+
+ EnterSomethingDialog esd = new EnterSomethingDialog(loginFrame, "Keyboard Interactive Authentication",
+ content, !echo[i]);
+
+ esd.setVisible(true);
+
+ if (esd.answer == null)
+ throw new IOException("Login aborted by user");
+
+ result[i] = esd.answer;
+ promptCount++;
+ }
+
+ return result;
+ }
+
+ /* We maintain a prompt counter - this enables the detection of situations where the ssh
+ * server is signaling "authentication failed" even though it did not send a single prompt.
+ */
+
+ public int getPromptCount()
+ {
+ return promptCount;
+ }
+ }
+
+ /**
+ * 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 extends Thread
+ {
+ String hostname;
+ String username;
+
+ public ConnectionThread(String hostname, String username)
+ {
+ this.hostname = hostname;
+ 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)
+ *
+ */
+
+ Runnable r = new Runnable()
+ {
+ public void run()
+ {
+ loginFrame.dispose();
+ }
+ };
+
+ SwingUtilities.invokeLater(r);
+ }
+ }
+
+ void loginPressed()
+ {
+ String hostname = hostField.getText().trim();
+ String username = userField.getText().trim();
+
+ if ((hostname.length() == 0) || (username.length() == 0))
+ {
+ JOptionPane.showMessageDialog(loginFrame, "Please fill out both fields!");
+ return;
+ }
+
+ loginButton.setEnabled(false);
+ hostField.setEnabled(false);
+ userField.setEnabled(false);
+
+ ConnectionThread ct = new ConnectionThread(hostname, username);
+
+ ct.start();
+ }
+
+ void showGUI()
+ {
+ loginFrame = new JFrame("Trilead SSH-2 for Java SwingShell");
+
+ hostLabel = new JLabel("Hostname:");
+ userLabel = new JLabel("Username:");
+
+ hostField = new JTextField("", 20);
+ userField = new JTextField("", 10);
+
+ loginButton = new JButton("Login");
+
+ loginButton.addActionListener(new ActionListener()
+ {
+ public void actionPerformed(java.awt.event.ActionEvent e)
+ {
+ loginPressed();
+ }
+ });
+
+ JPanel loginPanel = new JPanel();
+
+ loginPanel.add(hostLabel);
+ loginPanel.add(hostField);
+ loginPanel.add(userLabel);
+ loginPanel.add(userField);
+ loginPanel.add(loginButton);
+
+ loginFrame.getRootPane().setDefaultButton(loginButton);
+
+ loginFrame.getContentPane().add(loginPanel, BorderLayout.PAGE_START);
+ //loginFrame.getContentPane().add(textArea, BorderLayout.CENTER);
+
+ loginFrame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+ loginFrame.pack();
+ loginFrame.setResizable(false);
+ loginFrame.setLocationRelativeTo(null);
+ loginFrame.setVisible(true);
+ }
+
+ void startGUI()
+ {
+ Runnable r = new Runnable()
+ {
+ public void run()
+ {
+ showGUI();
+ }
+ };
+
+ SwingUtilities.invokeLater(r);
+
+ }
+
+ public static void main(String[] args)
+ {
+ SwingShell client = new SwingShell();
+ client.startGUI();
+ }
+}
--- trilead-ssh2-6401.orig/debian/examples/Basic.java
+++ trilead-ssh2-6401/debian/examples/Basic.java
@@ -0,0 +1,91 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import com.trilead.ssh2.Connection;
+import com.trilead.ssh2.Session;
+import com.trilead.ssh2.StreamGobbler;
+
+
+/**
+ * This is a very basic example that shows
+ * how one can login to a machine and execute a command.
+ *
+ * @author Christian Plattner, plattner@trilead.com
+ * @version $Id: Basic.java,v 1.4 2007/10/15 12:49:57 cplattne Exp $
+ */
+public class Basic
+{
+ public static void main(String[] args)
+ {
+ String hostname = "127.0.0.1";
+ String username = "joe";
+ String password = "joespass";
+
+ 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);
+ System.exit(2);
+ }
+ }
+}
--- trilead-ssh2-6401.orig/debian/examples/UsingKnownHosts.java
+++ trilead-ssh2-6401/debian/examples/UsingKnownHosts.java
@@ -0,0 +1,86 @@
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import com.trilead.ssh2.Connection;
+import com.trilead.ssh2.KnownHosts;
+import com.trilead.ssh2.Session;
+import com.trilead.ssh2.StreamGobbler;
+
+/**
+ * This example shows how to deal with "known_hosts" files.
+ *
+ * @author Christian Plattner, plattner@trilead.com
+ * @version $Id: UsingKnownHosts.java,v 1.2 2007/10/15 12:49:57 cplattne Exp $
+ */
+public class UsingKnownHosts
+{
+ static KnownHosts database = new KnownHosts();
+
+ public static void main(String[] args) throws IOException
+ {
+ String hostname = "somehost";
+ String username = "joe";
+ String password = "joespass";
+
+ File knownHosts = new File("~/.ssh/known_hosts");
+
+ try
+ {
+ /* Load known_hosts file into in-memory database */
+
+ 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);
+ System.exit(2);
+ }
+ }
+}
--- trilead-ssh2-6401.orig/debian/examples/BasicWithHTTPProxy.java
+++ trilead-ssh2-6401/debian/examples/BasicWithHTTPProxy.java
@@ -0,0 +1,102 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import com.trilead.ssh2.Connection;
+import com.trilead.ssh2.HTTPProxyData;
+import com.trilead.ssh2.Session;
+import com.trilead.ssh2.StreamGobbler;
+
+/**
+ * This is a very basic example that shows
+ * how one can login to a machine (via a HTTP proxy)
+ * and execute a command.
+ *
+ * @author Christian Plattner, plattner@trilead.com
+ * @version $Id: BasicWithHTTPProxy.java,v 1.3 2007/10/15 12:49:57 cplattne Exp $
+ */
+public class BasicWithHTTPProxy
+{
+ public static void main(String[] args)
+ {
+ String hostname = "my-ssh-server";
+ String username = "joe";
+ String password = "joespass";
+
+ String proxyHost = "192.168.1.1";
+ int proxyPort = 3128; // default port used by squid
+
+ 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);
+ System.exit(2);
+ }
+ }
+}
--- trilead-ssh2-6401.orig/debian/examples/SingleThreadStdoutStderr.java
+++ trilead-ssh2-6401/debian/examples/SingleThreadStdoutStderr.java
@@ -0,0 +1,142 @@
+import java.io.IOException;
+import java.io.InputStream;
+
+import com.trilead.ssh2.ChannelCondition;
+import com.trilead.ssh2.Connection;
+import com.trilead.ssh2.Session;
+
+/**
+ * This example shows how to use the Session.waitForCondition
+ * method to implement a state machine approach for
+ * proper stdout/stderr output handling in a single thread.
+ *
+ * @author Christian Plattner, plattner@trilead.com
+ * @version $Id: SingleThreadStdoutStderr.java,v 1.6 2007/10/15 12:49:57 cplattne Exp $
+ */
+public class SingleThreadStdoutStderr
+{
+ public static void main(String[] args)
+ {
+ String hostname = "127.0.0.1";
+ String username = "joe";
+ String password = "joespass";
+
+ 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);
+ System.exit(2);
+ }
+ }
+}
--- trilead-ssh2-6401.orig/debian/examples/StdoutAndStderr.java
+++ trilead-ssh2-6401/debian/examples/StdoutAndStderr.java
@@ -0,0 +1,93 @@
+import java.io.BufferedReader;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.InputStreamReader;
+
+import com.trilead.ssh2.Connection;
+import com.trilead.ssh2.Session;
+import com.trilead.ssh2.StreamGobbler;
+
+/**
+ * This example shows how to consume stdout/stderr output
+ * using two StreamGobblers. This is simpler to program
+ * than the state machine approach (see SingleThreadStdoutStderr.java),
+ * but you cannot control the amount of memory that is
+ * consumed by your application (i.e., in case the other
+ * side sends you lots of data).
+ *
+ * @author Christian Plattner, plattner@trilead.com
+ * @version $Id: StdoutAndStderr.java,v 1.2 2007/10/15 12:49:57 cplattne Exp $
+ */
+public class StdoutAndStderr
+{
+ public static void main(String[] args)
+ {
+ String hostname = "127.0.0.1";
+ String username = "joe";
+ String password = "joespass";
+
+ 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);
+ System.exit(2);
+ }
+ }
+}
--- trilead-ssh2-6401.orig/debian/examples/SimpleVerifier.java
+++ trilead-ssh2-6401/debian/examples/SimpleVerifier.java
@@ -0,0 +1,55 @@
+import com.trilead.ssh2.KnownHosts;
+import com.trilead.ssh2.ServerHostKeyVerifier;
+
+/**
+ * This example hostkey verifier is used by the
+ * UsingKnownHosts.java example.
+ *
+ * @author Christian Plattner, plattner@trilead.com
+ * @version $Id: SimpleVerifier.java,v 1.4 2007/10/15 12:49:57 cplattne Exp $
+ */
+class SimpleVerifier implements ServerHostKeyVerifier
+{
+ KnownHosts database;
+
+ public SimpleVerifier(KnownHosts database)
+ {
+ if (database == null)
+ throw new IllegalArgumentException();
+
+ this.database = database;
+ }
+
+ public boolean verifyServerHostKey(String hostname, int port, String serverHostKeyAlgorithm, byte[] serverHostKey)
+ throws Exception
+ {
+ int result = database.verifyHostkey(hostname, serverHostKeyAlgorithm, serverHostKey);
+
+ switch (result)
+ {
+ case KnownHosts.HOSTKEY_IS_OK:
+
+ return true; // We are happy
+
+ case KnownHosts.HOSTKEY_IS_NEW:
+
+ // Unknown host? Blindly accept the key and put it into the cache.
+ // Well, you definitely can do better (e.g., ask the user).
+
+ // The following call will ONLY put the key into the memory cache!
+ // To save it in a known hosts file, also call "KnownHosts.addHostkeyToFile(...)"
+ database.addHostkey(new String[] { hostname }, serverHostKeyAlgorithm, serverHostKey);
+
+ return true;
+
+ case KnownHosts.HOSTKEY_HAS_CHANGED:
+
+ // Close the connection if the hostkey has changed.
+ // Better: ask user and add new key to database.
+ return false;
+
+ default:
+ throw new IllegalStateException();
+ }
+ }
+}
\ No newline at end of file