mavenOptions = [
17 | '--update-snapshots',
18 | "-Dmaven.repo.local=$m2repo",
19 | '-Dmaven.test.failure.ignore',
20 | "-Dset.changelist",
21 | "-Djava.security.egd=file:/dev/./urandom",
22 | "clean install"
23 | ]
24 |
25 | infra.runMaven(mavenOptions, jdk)
26 | }
27 | }
28 | post {
29 | always {
30 | /*
31 | archiveArtifacts(allowEmptyArchive: true,
32 | artifacts: "** /target/trilead*.jar",
33 | onlyIfSuccessful: false)
34 | */
35 | junit(allowEmptyResults: true,
36 | keepLongStdio: true,
37 | testResults: "**/target/surefire-reports/**/*.xml")
38 | script {
39 | def m2repo = "${pwd tmp: true}/m2repo"
40 | // No easy way to load both of these in one command: https://stackoverflow.com/q/23521889/12916
41 | String version = sh script: 'mvn -Dset.changelist -Dexpression=project.version -q -DforceStdout help:evaluate', returnStdout: true
42 | echo "Collecting $version from $m2repo for possible Incrementals publishing"
43 | dir(m2repo) {
44 | archiveArtifacts "org/jenkins-ci/trilead-ssh2/$version/*$version*"
45 | }
46 | infra.maybePublishIncrementals()
47 | }
48 | }
49 | }
50 | }
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/README.txt:
--------------------------------------------------------------------------------
1 |
2 | Trilead SSH-2 for Java - build 212
3 | ==================================
4 |
5 | http://www.trilead.com
6 |
7 | Trilead SSH-2 for Java is a library which implements the SSH-2 protocol in pure Java
8 | (minimum required JRE: 1.4.2). It allows one to connect to SSH servers from within
9 | Java programs. It supports SSH sessions (remote command execution and shell access),
10 | local and remote port forwarding, local stream forwarding, X11 forwarding, SCP and SFTP.
11 | There are no dependencies on any JCE provider, as all crypto functionality is included.
12 |
13 | This distribution contains the source code, examples, javadoc and the FAQ.
14 | It also includes a pre-compiled jar version of the library which is ready to use.
15 |
16 | - Please read the included LICENCE.txt
17 | - Latest changes can be found in HISTORY.txt
18 |
19 | The latest version of the FAQ is available on the website.
20 |
21 | Please feel free to contact us. We welcome feedback of any kind!
22 | Contact: support@trilead.com or go to the public forum at http://www.trilead.com
23 |
24 | Zurich, March 2008
25 |
26 | ## Algorithm filters
27 |
28 | The algorithm filters can be used to restrict the algorithms that are used by the library.
29 | The filters will remove the algorithms you specify from the SSH algorithms negotiation between client and server.
30 | The library supports the following algorithm filters:
31 | * Kex (Key Exchange) algorithm filter
32 | * Host Key algorithm filter
33 | * Encryption algorithm filter
34 | * MAC algorithm filter
35 |
36 | To filter algorithms enable the filters using the following System properties:
37 |
38 |
39 | * com.trilead.ssh2.jenkins.FilterKexAlgorithms.enabled (default: true)
40 | * com.trilead.ssh2.jenkins.FilterHostKeyAlgorithms.enabled (default: true)
41 | * com.trilead.ssh2.jenkins.FilterMacAlgorithms.enabled (default: true)
42 | * com.trilead.ssh2.jenkins.FilterEncrytionAlgorithms.enabled (default: true)
43 |
44 | The algorithms are specified as a comma separated list of algorithm names.
45 | To configure the algorithm filters, use the following System properties:
46 |
47 | * com.trilead.ssh2.jenkins.FilterKexAlgorithms.algorithms
48 | * com.trilead.ssh2.jenkins.FilterHostKeyAlgorithms.algorithms
49 | * com.trilead.ssh2.jenkins.FilterMacAlgorithms.algorithms
50 | * com.trilead.ssh2.jenkins.FilterEncrytionAlgorithms.algorithms
51 |
52 | Example
53 | ```bash
54 | java -Dcom.trilead.ssh2.jenkins.FilterKexAlgorithms.enabled=true \
55 | -Dcom.trilead.ssh2.jenkins.FilterKexAlgorithms.algorithms=diffie-hellman-group-exchange-sha256 \
56 | -jar jenkins.war
57 | ```
58 |
59 | To check the algorithms filtered by the library, check the `Filter*` classes at the package [`com.trilead.ssh2.jenkins`](src/com/trilead/ssh2/jenkins).
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/ChannelCondition.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2;
3 |
4 | /**
5 | * Contains constants that can be used to specify what conditions to wait for on
6 | * a SSH-2 channel (e.g., represented by a {@link Session}).
7 | *
8 | * @see Session#waitForCondition(int, long)
9 | *
10 | * @author Christian Plattner, plattner@trilead.com
11 | * @version $Id: ChannelCondition.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
12 | */
13 |
14 | public abstract interface ChannelCondition
15 | {
16 | /**
17 | * A timeout has occurred, none of your requested conditions is fulfilled.
18 | * However, other conditions may be true - therefore, NEVER use the "=="
19 | * operator to test for this (or any other) condition. Always use
20 | * something like ((cond & ChannelCondition.CLOSED) != 0)
.
21 | */
22 | public static final int TIMEOUT = 1;
23 |
24 | /**
25 | * The underlying SSH-2 channel, however not necessarily the whole connection,
26 | * has been closed. This implies EOF
. Note that there may still
27 | * be unread stdout or stderr data in the local window, i.e, STDOUT_DATA
28 | * or/and STDERR_DATA
may be set at the same time.
29 | */
30 | public static final int CLOSED = 2;
31 |
32 | /**
33 | * There is stdout data available that is ready to be consumed.
34 | */
35 | public static final int STDOUT_DATA = 4;
36 |
37 | /**
38 | * There is stderr data available that is ready to be consumed.
39 | */
40 | public static final int STDERR_DATA = 8;
41 |
42 | /**
43 | * EOF on has been reached, no more _new_ stdout or stderr data will arrive
44 | * from the remote server. However, there may be unread stdout or stderr
45 | * data, i.e, STDOUT_DATA
or/and STDERR_DATA
46 | * may be set at the same time.
47 | */
48 | public static final int EOF = 16;
49 |
50 | /**
51 | * The exit status of the remote process is available.
52 | * Some servers never send the exist status, or occasionally "forget" to do so.
53 | */
54 | public static final int EXIT_STATUS = 32;
55 |
56 | /**
57 | * The exit signal of the remote process is available.
58 | */
59 | public static final int EXIT_SIGNAL = 64;
60 |
61 | }
62 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/ConnectionInfo.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2;
3 |
4 | /**
5 | * In most cases you probably do not need the information contained in here.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: ConnectionInfo.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
9 | */
10 | public class ConnectionInfo
11 | {
12 | /**
13 | * The used key exchange (KEX) algorithm in the latest key exchange.
14 | */
15 | public String keyExchangeAlgorithm;
16 |
17 | /**
18 | * The currently used crypto algorithm for packets from to the client to the
19 | * server.
20 | */
21 | public String clientToServerCryptoAlgorithm;
22 | /**
23 | * The currently used crypto algorithm for packets from to the server to the
24 | * client.
25 | */
26 | public String serverToClientCryptoAlgorithm;
27 |
28 | /**
29 | * The currently used MAC algorithm for packets from to the client to the
30 | * server.
31 | */
32 | public String clientToServerMACAlgorithm;
33 | /**
34 | * The currently used MAC algorithm for packets from to the server to the
35 | * client.
36 | */
37 | public String serverToClientMACAlgorithm;
38 |
39 | /**
40 | * The type of the server host key
41 | */
42 | public String serverHostKeyAlgorithm;
43 | /**
44 | * The server host key that was sent during the latest key exchange.
45 | */
46 | public byte[] serverHostKey;
47 |
48 | /**
49 | * Number of kex exchanges performed on this connection so far.
50 | */
51 | public int keyExchangeCounter = 0;
52 | }
53 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/ConnectionMonitor.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2;
3 |
4 | /**
5 | * A ConnectionMonitor
is used to get notified when the
6 | * underlying socket of a connection is closed.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: ConnectionMonitor.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
10 | */
11 |
12 | public interface ConnectionMonitor
13 | {
14 | /**
15 | * This method is called after the connection's underlying
16 | * socket has been closed. E.g., due to the {@link Connection#close()} request of the
17 | * user, if the peer closed the connection, due to a fatal error during connect()
18 | * (also if the socket cannot be established) or if a fatal error occured on
19 | * an established connection.
20 | *
21 | * This is an experimental feature.
22 | *
23 | * You MUST NOT make any assumption about the thread that invokes this method.
24 | *
25 | * Please note: if the connection is not connected (e.g., there was no successful
26 | * connect() call), then the invocation of {@link Connection#close()} will NOT trigger
27 | * this method.
28 | *
29 | * @see Connection#addConnectionMonitor(ConnectionMonitor)
30 | *
31 | * @param reason Includes an indication why the socket was closed.
32 | */
33 | public void connectionLost(Throwable reason);
34 | }
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/DebugLogger.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2;
2 |
3 | /**
4 | * An interface which needs to be implemented if you
5 | * want to capture debugging messages.
6 | *
7 | * @see Connection#enableDebugging(boolean, DebugLogger)
8 | *
9 | * @author Christian Plattner, plattner@trilead.com
10 | * @version $Id: DebugLogger.java,v 1.1 2008/03/03 07:01:36 cplattne Exp $
11 | * @deprecated
12 | * Logging all goes to JDK java.util.logging
13 | */
14 | public interface DebugLogger
15 | {
16 |
17 | /**
18 | * Log a debug message.
19 | *
20 | * @param level 0-99, 99 is a the most verbose level
21 | * @param className the class that generated the message
22 | * @param message the debug message
23 | */
24 | public void log(int level, String className, String message);
25 | }
26 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/ExtendedServerHostKeyVerifier.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2;
2 |
3 | import java.util.List;
4 |
5 | /**
6 | * This extends the {@link ServerHostKeyVerifier} interface by allowing the remote server to indicate it has multiple
7 | * server key algorithms available. After authentication, the {@link #getKnownKeyAlgorithmsForHost(String, int)} method
8 | * may be called and compared against the list of server-controller keys. If a key algorithm has been added then
9 | * {@link #addServerHostKey(String, int, String, byte[])} will be called. If a key algorithm has been removed, then
10 | * {@link #removeServerHostKey(String, int, String, byte[])} will be called.
11 | *
12 | * @author Kenny Root
13 | */
14 | public abstract class ExtendedServerHostKeyVerifier implements ServerHostKeyVerifier {
15 | /**
16 | * Called during connection to determine which keys are known for this host.
17 | *
18 | * @param hostname the hostname used to create the {@link Connection} object
19 | * @param port the server's remote TCP port
20 | * @return list of hostkey algorithms for the given hostname
and port
combination
21 | * or {@code null} if none are known.
22 | */
23 | public abstract List getKnownKeyAlgorithmsForHost(String hostname, int port);
24 |
25 | /**
26 | * After authentication, if the server indicates it no longer uses this key, this method will be called
27 | * for the app to remove its record of it.
28 | *
29 | * @param hostname the hostname used to create the {@link Connection} object
30 | * @param port the server's remote TCP port
31 | * @param serverHostKeyAlgorithm key algorithm of removed key
32 | * @param serverHostKey key data of removed key
33 | */
34 | public abstract void removeServerHostKey(String hostname, int port, String serverHostKeyAlgorithm,
35 | byte[] serverHostKey);
36 |
37 | /**
38 | * After authentication, if the server indicates it has another keyAlgorithm
, this method will be
39 | * called for the app to add it to its record of known keys for this hostname
.
40 | *
41 | * @param hostname the hostname used to create the {@link Connection} object
42 | * @param port the server's remote TCP port
43 | * @param keyAlgorithm SSH standard name for the key to be added
44 | * @param serverHostKey SSH encoding of the key data for the key to be added
45 | */
46 | public abstract void addServerHostKey(String hostname, int port, String keyAlgorithm, byte[] serverHostKey);
47 | }
48 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/HTTPProxyException.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2;
3 |
4 | import java.io.IOException;
5 |
6 | /**
7 | * May be thrown upon connect() if a HTTP proxy is being used.
8 | *
9 | * @see Connection#connect()
10 | * @see Connection#setProxyData(ProxyData)
11 | *
12 | * @author Christian Plattner, plattner@trilead.com
13 | * @version $Id: HTTPProxyException.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
14 | */
15 |
16 | public class HTTPProxyException extends IOException
17 | {
18 | private static final long serialVersionUID = 2241537397104426186L;
19 |
20 | public final String httpResponse;
21 | public final int httpErrorCode;
22 |
23 | public HTTPProxyException(String httpResponse, int httpErrorCode)
24 | {
25 | super("HTTP Proxy Error (" + httpErrorCode + " " + httpResponse + ")");
26 | this.httpResponse = httpResponse;
27 | this.httpErrorCode = httpErrorCode;
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/IOWarningException.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2;
2 |
3 | import java.io.IOException;
4 |
5 | /**
6 | * @author Thomas Singer
7 | */
8 | public final class IOWarningException extends IOException {
9 |
10 | private static final long serialVersionUID = 1L;
11 |
12 | // Setup ==================================================================
13 |
14 | public IOWarningException(String message) {
15 | super(message);
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/InteractiveCallback.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2;
3 |
4 | /**
5 | * An InteractiveCallback
is used to respond to challenges sent
6 | * by the server if authentication mode "keyboard-interactive" is selected.
7 | *
8 | * @see Connection#authenticateWithKeyboardInteractive(String,
9 | * String[], InteractiveCallback)
10 | *
11 | * @author Christian Plattner, plattner@trilead.com
12 | * @version $Id: InteractiveCallback.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
13 | */
14 |
15 | public interface InteractiveCallback
16 | {
17 | /**
18 | * This callback interface is used during a "keyboard-interactive"
19 | * authentication. Every time the server sends a set of challenges (however,
20 | * most often just one challenge at a time), this callback function will be
21 | * called to give your application a chance to talk to the user and to
22 | * determine the response(s).
23 | *
24 | * Some copy-paste information from the standard: a command line interface
25 | * (CLI) client SHOULD print the name and instruction (if non-empty), adding
26 | * newlines. Then for each prompt in turn, the client SHOULD display the
27 | * prompt and read the user input. The name and instruction fields MAY be
28 | * empty strings, the client MUST be prepared to handle this correctly. The
29 | * prompt field(s) MUST NOT be empty strings.
30 | *
31 | * Please refer to draft-ietf-secsh-auth-kbdinteract-XX.txt for the details.
32 | *
33 | * Note: clients SHOULD use control character filtering as discussed in
34 | * RFC4251 to avoid attacks by including
35 | * terminal control characters in the fields to be displayed.
36 | *
37 | * @param name
38 | * the name String sent by the server.
39 | * @param instruction
40 | * the instruction String sent by the server.
41 | * @param numPrompts
42 | * number of prompts - may be zero (in this case, you should just
43 | * return a String array of length zero).
44 | * @param prompt
45 | * an array (length numPrompts
) of Strings
46 | * @param echo
47 | * an array (length numPrompts
) of booleans. For
48 | * each prompt, the corresponding echo field indicates whether or
49 | * not the user input should be echoed as characters are typed.
50 | * @return an array of reponses - the array size must match the parameter
51 | * numPrompts
.
52 | * @throws Exception exception
53 | */
54 | public String[] replyToChallenge(String name, String instruction, int numPrompts, String[] prompt, boolean[] echo)
55 | throws Exception;
56 | }
57 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/LocalPortForwarder.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2;
3 |
4 | import java.io.IOException;
5 | import java.net.InetSocketAddress;
6 |
7 | import com.trilead.ssh2.channel.ChannelManager;
8 | import com.trilead.ssh2.channel.LocalAcceptThread;
9 |
10 |
11 | /**
12 | * A LocalPortForwarder
forwards TCP/IP connections to a local
13 | * port via the secure tunnel to another host (which may or may not be identical
14 | * to the remote SSH-2 server). Checkout {@link Connection#createLocalPortForwarder(int, String, int)}
15 | * on how to create one.
16 | *
17 | * @author Christian Plattner, plattner@trilead.com
18 | * @version $Id: LocalPortForwarder.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
19 | */
20 | public class LocalPortForwarder
21 | {
22 | ChannelManager cm;
23 |
24 | String host_to_connect;
25 |
26 | int port_to_connect;
27 |
28 | LocalAcceptThread lat;
29 |
30 | LocalPortForwarder(ChannelManager cm, int local_port, String host_to_connect, int port_to_connect)
31 | throws IOException
32 | {
33 | this.cm = cm;
34 | this.host_to_connect = host_to_connect;
35 | this.port_to_connect = port_to_connect;
36 |
37 | lat = new LocalAcceptThread(cm, local_port, host_to_connect, port_to_connect);
38 | lat.setDaemon(true);
39 | lat.start();
40 | }
41 |
42 | LocalPortForwarder(ChannelManager cm, InetSocketAddress addr, String host_to_connect, int port_to_connect)
43 | throws IOException
44 | {
45 | this.cm = cm;
46 | this.host_to_connect = host_to_connect;
47 | this.port_to_connect = port_to_connect;
48 |
49 | lat = new LocalAcceptThread(cm, addr, host_to_connect, port_to_connect);
50 | lat.setDaemon(true);
51 | lat.start();
52 | }
53 |
54 | /**
55 | * Stop TCP/IP forwarding of newly arriving connections.
56 | *
57 | * @throws IOException the io exception
58 | */
59 | public void close() throws IOException
60 | {
61 | lat.stopWorking();
62 | }
63 |
64 | public int getLocalPort()
65 | {
66 | return lat.getLocalPort();
67 | }
68 |
69 | }
70 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/LocalStreamForwarder.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2;
3 |
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 | import java.io.OutputStream;
7 |
8 | import com.trilead.ssh2.channel.Channel;
9 | import com.trilead.ssh2.channel.ChannelManager;
10 | import com.trilead.ssh2.channel.LocalAcceptThread;
11 |
12 |
13 | /**
14 | * A LocalStreamForwarder
forwards an Input- and Outputstream
15 | * pair via the secure tunnel to another host (which may or may not be identical
16 | * to the remote SSH-2 server).
17 | *
18 | * @author Christian Plattner, plattner@trilead.com
19 | * @version $Id: LocalStreamForwarder.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
20 | */
21 | public class LocalStreamForwarder
22 | {
23 | ChannelManager cm;
24 |
25 | String host_to_connect;
26 | int port_to_connect;
27 | LocalAcceptThread lat;
28 |
29 | Channel cn;
30 |
31 | LocalStreamForwarder(ChannelManager cm, String host_to_connect, int port_to_connect) throws IOException
32 | {
33 | this.cm = cm;
34 | this.host_to_connect = host_to_connect;
35 | this.port_to_connect = port_to_connect;
36 |
37 | cn = cm.openDirectTCPIPChannel(host_to_connect, port_to_connect, "127.0.0.1", 0);
38 | }
39 |
40 | /**
41 | * @return An InputStream
object.
42 | * @throws IOException the io exception
43 | */
44 | public InputStream getInputStream() throws IOException
45 | {
46 | return cn.getStdoutStream();
47 | }
48 |
49 | /**
50 | * Get the OutputStream. Please be aware that the implementation MAY use an
51 | * internal buffer. To make sure that the buffered data is sent over the
52 | * tunnel, you have to call the flush
method of the
53 | * OutputStream
. To signal EOF, please use the
54 | * close
method of the OutputStream
.
55 | *
56 | * @return An OutputStream
object.
57 | * @throws IOException the io exception
58 | */
59 | public OutputStream getOutputStream() throws IOException
60 | {
61 | return cn.getStdinStream();
62 | }
63 |
64 | /**
65 | * Close the underlying SSH forwarding channel and free up resources.
66 | * You can also use this method to force the shutdown of the underlying
67 | * forwarding channel. Pending output (OutputStream not flushed) will NOT
68 | * be sent. Pending input (InputStream) can still be read. If the shutdown
69 | * operation is already in progress (initiated from either side), then this
70 | * call is a no-op.
71 | *
72 | * @throws IOException the io exception
73 | */
74 | public void close() throws IOException
75 | {
76 | cm.closeChannel(cn, "Closed due to user request.", true);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/ProxyData.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2;
3 |
4 | /**
5 | * An abstract marker interface implemented by all proxy data implementations.
6 | *
7 | * @see HTTPProxyData
8 | *
9 | * @author Christian Plattner, plattner@trilead.com
10 | * @version $Id: ProxyData.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
11 | */
12 |
13 | public abstract interface ProxyData
14 | {
15 | }
16 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/RandomFactory.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2;
2 |
3 | import java.security.NoSuchAlgorithmException;
4 | import java.security.SecureRandom;
5 |
6 | /**
7 | * Creates {@link SecureRandom}
8 | *
9 | * @author Kohsuke Kawaguchi
10 | */
11 | public class RandomFactory {
12 | public static SecureRandom create() {
13 | try {
14 | // JENKINS-20108
15 | // on Unix, "new SecureRandom()" uses NativePRNG that uses a VM-wide lock, which results in
16 | // SecureRandom.nextInt() contention when there are lots of concurrent connections.
17 | // SHA1PRNG avoids this problem. This PRNG still gets seeded from (blocking) /dev/random,
18 | // which assures security.
19 | //
20 | // note that SHA1PRNG is not a standard. See http://security.stackexchange.com/questions/47871/
21 | //
22 | // there's also http://coding.tocea.com/scertify-code/dont-use-the-sha1-prng-randomness-generator/
23 | // which claims SHA1PRNG has "statistical defects" without details. I discount the credibility of
24 | // this claim based on the lack of details, and that this is not reported as a vulnerability upstream.
25 | return SecureRandom.getInstance("SHA1PRNG");
26 | } catch (NoSuchAlgorithmException e) {
27 | // fall back
28 | return new SecureRandom();
29 | }
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/SFTPException.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2;
3 |
4 | import java.io.IOException;
5 |
6 | import com.trilead.ssh2.sftp.ErrorCodes;
7 |
8 |
9 | /**
10 | * Used in combination with the SFTPv3Client. This exception wraps
11 | * error messages sent by the SFTP server.
12 | *
13 | * @author Christian Plattner, plattner@trilead.com
14 | * @version $Id: SFTPException.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
15 | */
16 |
17 | public class SFTPException extends IOException
18 | {
19 | private static final long serialVersionUID = 578654644222421811L;
20 |
21 | private final String sftpErrorMessage;
22 | private final int sftpErrorCode;
23 |
24 | private static String constructMessage(String s, int errorCode)
25 | {
26 | String[] detail = ErrorCodes.getDescription(errorCode);
27 |
28 | if (detail == null)
29 | return s + " (UNKNOW SFTP ERROR CODE)";
30 |
31 | return s + " (" + detail[0] + ": " + detail[1] + ")";
32 | }
33 |
34 | SFTPException(String msg, int errorCode)
35 | {
36 | super(constructMessage(msg, errorCode));
37 | sftpErrorMessage = msg;
38 | sftpErrorCode = errorCode;
39 | }
40 |
41 | /**
42 | * Get the error message sent by the server. Often, this
43 | * message does not help a lot (e.g., "failure").
44 | *
45 | * @return the plain string as sent by the server.
46 | */
47 | public String getServerErrorMessage()
48 | {
49 | return sftpErrorMessage;
50 | }
51 |
52 | /**
53 | * Get the error code sent by the server.
54 | *
55 | * @return an error code as defined in the SFTP specs.
56 | */
57 | public int getServerErrorCode()
58 | {
59 | return sftpErrorCode;
60 | }
61 |
62 | /**
63 | * Get the symbolic name of the error code as given in the SFTP specs.
64 | *
65 | * @return e.g., "SSH_FX_INVALID_FILENAME".
66 | */
67 | public String getServerErrorCodeSymbol()
68 | {
69 | String[] detail = ErrorCodes.getDescription(sftpErrorCode);
70 |
71 | if (detail == null)
72 | return "UNKNOW SFTP ERROR CODE " + sftpErrorCode;
73 |
74 | return detail[0];
75 | }
76 |
77 | /**
78 | * Get the description of the error code as given in the SFTP specs.
79 | *
80 | * @return e.g., "The filename is not valid."
81 | */
82 | public String getServerErrorCodeVerbose()
83 | {
84 | String[] detail = ErrorCodes.getDescription(sftpErrorCode);
85 |
86 | if (detail == null)
87 | return "The error code " + sftpErrorCode + " is unknown.";
88 |
89 | return detail[1];
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/SFTPv3DirectoryEntry.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2;
3 |
4 | /**
5 | * A SFTPv3DirectoryEntry
as returned by {@link SFTPv3Client#ls(String)}.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: SFTPv3DirectoryEntry.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
9 | */
10 |
11 | public class SFTPv3DirectoryEntry
12 | {
13 | /**
14 | * A relative name within the directory, without any path components.
15 | */
16 | public String filename;
17 |
18 | /**
19 | * An expanded format for the file name, similar to what is returned by
20 | * "ls -l" on Un*x systems.
21 | *
22 | * The format of this field is unspecified by the SFTP v3 protocol.
23 | * It MUST be suitable for use in the output of a directory listing
24 | * command (in fact, the recommended operation for a directory listing
25 | * command is to simply display this data). However, clients SHOULD NOT
26 | * attempt to parse the longname field for file attributes; they SHOULD
27 | * use the attrs field instead.
28 | *
29 | * The recommended format for the longname field is as follows:
30 | * -rwxr-xr-x 1 mjos staff 348911 Mar 25 14:29 t-filexfer
31 | */
32 | public String longEntry;
33 |
34 | /**
35 | * The attributes of this entry.
36 | */
37 | public SFTPv3FileAttributes attributes;
38 | }
39 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/SFTPv3FileHandle.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2;
3 |
4 | /**
5 | * A SFTPv3FileHandle
.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: SFTPv3FileHandle.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
9 | */
10 |
11 | public class SFTPv3FileHandle
12 | {
13 | final SFTPv3Client client;
14 | final byte[] fileHandle;
15 | boolean isClosed = false;
16 |
17 | /* The constructor is NOT public */
18 |
19 | SFTPv3FileHandle(SFTPv3Client client, byte[] h)
20 | {
21 | this.client = client;
22 | this.fileHandle = h;
23 | }
24 |
25 | /**
26 | * Get the SFTPv3Client instance which created this handle.
27 | *
28 | * @return A SFTPv3Client instance.
29 | */
30 | public SFTPv3Client getClient()
31 | {
32 | return client;
33 | }
34 |
35 | /**
36 | * Check if this handle was closed with the {@link SFTPv3Client#closeFile(SFTPv3FileHandle)} method
37 | * of the SFTPv3Client
instance which created the handle.
38 | *
39 | * @return if the handle is closed.
40 | */
41 | public boolean isClosed()
42 | {
43 | return isClosed;
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/ServerHostKeyVerifier.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2;
3 |
4 | /**
5 | * A callback interface used to implement a client specific method of checking
6 | * server host keys.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: ServerHostKeyVerifier.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
10 | */
11 |
12 | public interface ServerHostKeyVerifier
13 | {
14 | /**
15 | * The actual verifier method, it will be called by the key exchange code
16 | * on EVERY key exchange - this can happen several times during the lifetime
17 | * of a connection.
18 | *
19 | * Note: SSH-2 servers are allowed to change their hostkey at ANY time.
20 | *
21 | * @param hostname the hostname used to create the {@link Connection} object
22 | * @param port the remote TCP port
23 | * @param serverHostKeyAlgorithm the public key algorithm
24 | * @param serverHostKey the server's public key blob
25 | * @return if the client wants to accept the server's host key - if not, the
26 | * connection will be closed.
27 | * @throws Exception Will be wrapped with an IOException, extended version of returning false =)
28 | */
29 | public boolean verifyServerHostKey(String hostname, int port, String serverHostKeyAlgorithm, byte[] serverHostKey)
30 | throws Exception;
31 | }
32 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/auth/AgentIdentity.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.auth;
2 |
3 | public interface AgentIdentity {
4 | public String getAlgName();
5 | public byte[] getPublicKeyBlob();
6 | public byte[] sign(byte[] data);
7 | }
8 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/auth/AgentProxy.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.auth;
2 |
3 | import java.util.Collection;
4 |
5 | public interface AgentProxy {
6 | public Collection/**/ getIdentities();
7 | }
8 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/channel/ChannelInputStream.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.channel;
3 |
4 | import java.io.IOException;
5 | import java.io.InputStream;
6 |
7 | /**
8 | * ChannelInputStream.
9 | *
10 | * @author Christian Plattner, plattner@trilead.com
11 | * @version $Id: ChannelInputStream.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
12 | */
13 | public final class ChannelInputStream extends InputStream
14 | {
15 | Channel c;
16 |
17 | boolean isClosed = false;
18 | boolean isEOF = false;
19 | boolean extendedFlag = false;
20 |
21 | ChannelInputStream(Channel c, boolean isExtended)
22 | {
23 | this.c = c;
24 | this.extendedFlag = isExtended;
25 | }
26 |
27 | public int available() throws IOException
28 | {
29 | if (isEOF)
30 | return 0;
31 |
32 | int avail = c.cm.getAvailable(c, extendedFlag);
33 |
34 | /* We must not return -1 on EOF */
35 |
36 | return (avail > 0) ? avail : 0;
37 | }
38 |
39 | public void close() throws IOException
40 | {
41 | isClosed = true;
42 | }
43 |
44 | public int read(byte[] b, int off, int len) throws IOException
45 | {
46 | if (b == null)
47 | throw new NullPointerException();
48 |
49 | if ((off < 0) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0) || (off > b.length))
50 | throw new IndexOutOfBoundsException();
51 |
52 | if (len == 0)
53 | return 0;
54 |
55 | if (isEOF)
56 | return -1;
57 |
58 | int ret = c.cm.getChannelData(c, extendedFlag, b, off, len);
59 |
60 | if (ret == -1)
61 | {
62 | isEOF = true;
63 | }
64 |
65 | return ret;
66 | }
67 |
68 | public int read(byte[] b) throws IOException
69 | {
70 | return read(b, 0, b.length);
71 | }
72 |
73 | public int read() throws IOException
74 | {
75 | /* Yes, this stream is pure and unbuffered, a single byte read() is slow */
76 |
77 | final byte b[] = new byte[1];
78 |
79 | int ret = read(b, 0, 1);
80 |
81 | if (ret != 1)
82 | return -1;
83 |
84 | return b[0] & 0xff;
85 | }
86 | }
87 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/channel/ChannelOutputStream.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.channel;
2 |
3 | import java.io.IOException;
4 | import java.io.OutputStream;
5 |
6 | /**
7 | * ChannelOutputStream.
8 | *
9 | * @author Christian Plattner, plattner@trilead.com
10 | * @version $Id: ChannelOutputStream.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
11 | */
12 | public final class ChannelOutputStream extends OutputStream
13 | {
14 | Channel c;
15 |
16 | boolean isClosed = false;
17 |
18 | ChannelOutputStream(Channel c)
19 | {
20 | this.c = c;
21 | }
22 |
23 | public void write(int b) throws IOException
24 | {
25 | byte[] buff = new byte[1];
26 |
27 | buff[0] = (byte) b;
28 |
29 | write(buff, 0, 1);
30 | }
31 |
32 | public void close() throws IOException
33 | {
34 | if (isClosed == false)
35 | {
36 | isClosed = true;
37 | c.cm.sendEOF(c);
38 | }
39 | }
40 |
41 | public void flush() throws IOException
42 | {
43 | if (isClosed)
44 | throw new IOException("This OutputStream is closed.");
45 |
46 | /* This is a no-op, since this stream is unbuffered */
47 | }
48 |
49 | public void write(byte[] b, int off, int len) throws IOException
50 | {
51 | if (isClosed)
52 | throw new IOException("This OutputStream is closed.");
53 |
54 | if (b == null)
55 | throw new NullPointerException();
56 |
57 | if ((off < 0) || (len < 0) || ((off + len) > b.length) || ((off + len) < 0) || (off > b.length))
58 | throw new IndexOutOfBoundsException();
59 |
60 | if (len == 0)
61 | return;
62 |
63 | c.cm.sendData(c, b, off, len);
64 | }
65 |
66 | public void write(byte[] b) throws IOException
67 | {
68 | write(b, 0, b.length);
69 | }
70 | }
71 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/channel/IChannelWorkerThread.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.channel;
3 |
4 | /**
5 | * IChannelWorkerThread.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: IChannelWorkerThread.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
9 | */
10 | interface IChannelWorkerThread
11 | {
12 | public void stopWorking();
13 | }
14 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/channel/RemoteAcceptThread.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.channel;
3 |
4 | import java.io.IOException;
5 | import java.io.InterruptedIOException;
6 | import java.net.Socket;
7 |
8 | import com.trilead.ssh2.log.Logger;
9 |
10 |
11 | /**
12 | * RemoteAcceptThread.
13 | *
14 | * @author Christian Plattner, plattner@trilead.com
15 | * @version $Id: RemoteAcceptThread.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
16 | */
17 | public class RemoteAcceptThread extends Thread
18 | {
19 | private static final Logger log = Logger.getLogger(RemoteAcceptThread.class);
20 |
21 | Channel c;
22 |
23 | String remoteConnectedAddress;
24 | int remoteConnectedPort;
25 | String remoteOriginatorAddress;
26 | int remoteOriginatorPort;
27 | String targetAddress;
28 | int targetPort;
29 |
30 | Socket s;
31 |
32 | public RemoteAcceptThread(Channel c, String remoteConnectedAddress, int remoteConnectedPort,
33 | String remoteOriginatorAddress, int remoteOriginatorPort, String targetAddress, int targetPort)
34 | {
35 | this.c = c;
36 | this.remoteConnectedAddress = remoteConnectedAddress;
37 | this.remoteConnectedPort = remoteConnectedPort;
38 | this.remoteOriginatorAddress = remoteOriginatorAddress;
39 | this.remoteOriginatorPort = remoteOriginatorPort;
40 | this.targetAddress = targetAddress;
41 | this.targetPort = targetPort;
42 |
43 | if (log.isEnabled())
44 | log.log(30, "RemoteAcceptThread: " + remoteConnectedAddress + "/" + remoteConnectedPort + ", R: "
45 | + remoteOriginatorAddress + "/" + remoteOriginatorPort);
46 | }
47 |
48 | public void run()
49 | {
50 | try
51 | {
52 | c.cm.sendOpenConfirmation(c);
53 |
54 | s = new Socket(targetAddress, targetPort);
55 |
56 | StreamForwarder r2l = new StreamForwarder(c, null, null, c.getStdoutStream(), s.getOutputStream(),
57 | "RemoteToLocal");
58 | StreamForwarder l2r = new StreamForwarder(c, null, null, s.getInputStream(), c.getStdinStream(),
59 | "LocalToRemote");
60 |
61 | /* No need to start two threads, one can be executed in the current thread */
62 |
63 | r2l.setDaemon(true);
64 | r2l.start();
65 | l2r.run();
66 |
67 | while (r2l.isAlive())
68 | {
69 | try
70 | {
71 | r2l.join();
72 | }
73 | catch (InterruptedException e)
74 | {
75 | throw new InterruptedIOException();
76 | }
77 | }
78 |
79 | /* If the channel is already closed, then this is a no-op */
80 |
81 | c.cm.closeChannel(c, "EOF on both streams reached.", true);
82 | s.close();
83 | }
84 | catch (IOException e)
85 | {
86 | log.log(50, "IOException in proxy code",e);
87 |
88 | try
89 | {
90 | c.cm.closeChannel(c, "IOException in proxy code (" + e.getMessage() + ")", true);
91 | }
92 | catch (IOException e1)
93 | {
94 | }
95 | try
96 | {
97 | if (s != null)
98 | s.close();
99 | }
100 | catch (IOException e1)
101 | {
102 | }
103 | }
104 | }
105 | }
106 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/channel/RemoteForwardingData.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.channel;
3 |
4 | /**
5 | * RemoteForwardingData. Data about a requested remote forwarding.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: RemoteForwardingData.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
9 | */
10 | public class RemoteForwardingData
11 | {
12 | public String bindAddress;
13 | public int bindPort;
14 |
15 | String targetAddress;
16 | int targetPort;
17 | }
18 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/channel/StreamForwarder.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.channel;
2 |
3 | import java.io.IOException;
4 | import java.io.InputStream;
5 | import java.io.OutputStream;
6 | import java.net.Socket;
7 |
8 | /**
9 | * A StreamForwarder forwards data between two given streams.
10 | * If two StreamForwarder threads are used (one for each direction)
11 | * then one can be configured to shutdown the underlying channel/socket
12 | * if both threads have finished forwarding (EOF).
13 | *
14 | * @author Christian Plattner, plattner@trilead.com
15 | * @version $Id: StreamForwarder.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
16 | */
17 | public class StreamForwarder extends Thread
18 | {
19 | OutputStream os;
20 | InputStream is;
21 | byte[] buffer;
22 | Channel c;
23 | StreamForwarder sibling;
24 | Socket s;
25 | String mode;
26 |
27 | StreamForwarder(Channel c, StreamForwarder sibling, Socket s, InputStream is, OutputStream os, String mode)
28 | throws IOException
29 | {
30 | this.is = is;
31 | this.os = os;
32 | this.mode = mode;
33 | this.c = c;
34 | this.sibling = sibling;
35 | this.s = s;
36 | // window size is for the other side of the network with some latency.
37 | // we don't need such a big buffer for a copy stream tight loop
38 | this.buffer = new byte[8192/*c.channelBufferSize*/];
39 | }
40 |
41 | public void run()
42 | {
43 | try
44 | {
45 | while (true)
46 | {
47 | int len = is.read(buffer);
48 | if (len <= 0)
49 | break;
50 | os.write(buffer, 0, len);
51 | os.flush();
52 | }
53 | }
54 | catch (IOException ignore)
55 | {
56 | try
57 | {
58 | c.cm.closeChannel(c, "Closed due to exception in StreamForwarder (" + mode + "): "
59 | + ignore.getMessage(), true);
60 | }
61 | catch (IOException e)
62 | {
63 | }
64 | }
65 | finally
66 | {
67 | try
68 | {
69 | os.close();
70 | }
71 | catch (IOException e1)
72 | {
73 | }
74 | try
75 | {
76 | is.close();
77 | }
78 | catch (IOException e2)
79 | {
80 | }
81 |
82 | if (sibling != null)
83 | {
84 | while (sibling.isAlive())
85 | {
86 | try
87 | {
88 | sibling.join();
89 | }
90 | catch (InterruptedException e)
91 | {
92 | }
93 | }
94 |
95 | try
96 | {
97 | c.cm.closeChannel(c, "StreamForwarder (" + mode + ") is cleaning up the connection", true);
98 | }
99 | catch (IOException e3)
100 | {
101 | }
102 |
103 | try
104 | {
105 | if (s != null)
106 | s.close();
107 | }
108 | catch (IOException e1)
109 | {
110 | }
111 | }
112 | }
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/channel/X11ServerData.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.channel;
3 |
4 | /**
5 | * X11ServerData. Data regarding an x11 forwarding target.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: X11ServerData.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
9 | *
10 | */
11 | public class X11ServerData
12 | {
13 | public String hostname;
14 | public int port;
15 | public byte[] x11_magic_cookie; /* not the remote (fake) one, the local (real) one */
16 | }
17 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/CertificateDecoder.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.crypto;
2 |
3 | import java.io.IOException;
4 | import java.security.KeyPair;
5 |
6 | /**
7 | * @author Michael Clarke
8 | */
9 | public abstract class CertificateDecoder {
10 |
11 | public abstract String getStartLine();
12 |
13 | public abstract String getEndLine();
14 |
15 | public KeyPair createKeyPair(PEMStructure pemStructure, String password) throws IOException {
16 | return createKeyPair(pemStructure);
17 | }
18 |
19 | protected abstract KeyPair createKeyPair(PEMStructure pemStructure) throws IOException;
20 | }
21 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/CryptoWishList.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.crypto;
3 |
4 | import com.trilead.ssh2.crypto.cipher.BlockCipherFactory;
5 | import com.trilead.ssh2.crypto.digest.MessageMac;
6 | import com.trilead.ssh2.jenkins.FilterEncrytionAlgorithms;
7 | import com.trilead.ssh2.jenkins.FilterHostKeyAlgorithms;
8 | import com.trilead.ssh2.jenkins.FilterKexAlgorithms;
9 | import com.trilead.ssh2.jenkins.FilterMacAlgorithms;
10 | import com.trilead.ssh2.transport.KexManager;
11 |
12 |
13 | /**
14 | * CryptoWishList.
15 | *
16 | * @author Christian Plattner, plattner@trilead.com
17 | * @version $Id: CryptoWishList.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
18 | */
19 | public class CryptoWishList
20 | {
21 | public String[] kexAlgorithms = FilterKexAlgorithms.filter(KexManager.getDefaultKexAlgorithmList());
22 | public String[] serverHostKeyAlgorithms = FilterHostKeyAlgorithms.filter(KexManager.getDefaultServerHostkeyAlgorithmList());
23 | public String[] c2s_enc_algos = FilterEncrytionAlgorithms.filter(BlockCipherFactory.getDefaultCipherList());
24 | public String[] s2c_enc_algos = FilterEncrytionAlgorithms.filter(BlockCipherFactory.getDefaultCipherList());
25 | public String[] c2s_mac_algos = FilterMacAlgorithms.filter(MessageMac.getMacs());
26 | public String[] s2c_mac_algos = FilterMacAlgorithms.filter(MessageMac.getMacs());
27 | }
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/KeyMaterial.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.crypto;
3 |
4 |
5 | import java.math.BigInteger;
6 |
7 | import com.trilead.ssh2.crypto.digest.HashForSSH2Types;
8 |
9 | /**
10 | * Establishes key material for iv/key/mac (both directions).
11 | *
12 | * @author Christian Plattner, plattner@trilead.com
13 | * @version $Id: KeyMaterial.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
14 | */
15 | public class KeyMaterial
16 | {
17 | public byte[] initial_iv_client_to_server;
18 | public byte[] initial_iv_server_to_client;
19 | public byte[] enc_key_client_to_server;
20 | public byte[] enc_key_server_to_client;
21 | public byte[] integrity_key_client_to_server;
22 | public byte[] integrity_key_server_to_client;
23 |
24 | private static byte[] calculateKey(HashForSSH2Types sh, BigInteger K, byte[] H, byte type, byte[] SessionID,
25 | int keyLength)
26 | {
27 | byte[] res = new byte[keyLength];
28 |
29 | int dglen = sh.getDigestLength();
30 | int numRounds = (keyLength + dglen - 1) / dglen;
31 |
32 | byte[][] tmp = new byte[numRounds][];
33 |
34 | sh.reset();
35 | sh.updateBigInt(K);
36 | sh.updateBytes(H);
37 | sh.updateByte(type);
38 | sh.updateBytes(SessionID);
39 |
40 | tmp[0] = sh.getDigest();
41 |
42 | int off = 0;
43 | int produced = Math.min(dglen, keyLength);
44 |
45 | System.arraycopy(tmp[0], 0, res, off, produced);
46 |
47 | keyLength -= produced;
48 | off += produced;
49 |
50 | for (int i = 1; i < numRounds; i++)
51 | {
52 | sh.updateBigInt(K);
53 | sh.updateBytes(H);
54 |
55 | for (int j = 0; j < i; j++)
56 | sh.updateBytes(tmp[j]);
57 |
58 | tmp[i] = sh.getDigest();
59 |
60 | produced = Math.min(dglen, keyLength);
61 | System.arraycopy(tmp[i], 0, res, off, produced);
62 | keyLength -= produced;
63 | off += produced;
64 | }
65 |
66 | return res;
67 | }
68 |
69 | public static KeyMaterial create(String hashType, byte[] H, BigInteger K, byte[] SessionID, int keyLengthCS,
70 | int blockSizeCS, int macLengthCS, int keyLengthSC, int blockSizeSC, int macLengthSC)
71 | throws IllegalArgumentException
72 | {
73 | KeyMaterial km = new KeyMaterial();
74 |
75 | HashForSSH2Types sh = new HashForSSH2Types(hashType);
76 |
77 | km.initial_iv_client_to_server = calculateKey(sh, K, H, (byte) 'A', SessionID, blockSizeCS);
78 |
79 | km.initial_iv_server_to_client = calculateKey(sh, K, H, (byte) 'B', SessionID, blockSizeSC);
80 |
81 | km.enc_key_client_to_server = calculateKey(sh, K, H, (byte) 'C', SessionID, keyLengthCS);
82 |
83 | km.enc_key_server_to_client = calculateKey(sh, K, H, (byte) 'D', SessionID, keyLengthSC);
84 |
85 | km.integrity_key_client_to_server = calculateKey(sh, K, H, (byte) 'E', SessionID, macLengthCS);
86 |
87 | km.integrity_key_server_to_client = calculateKey(sh, K, H, (byte) 'F', SessionID, macLengthSC);
88 |
89 | return km;
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/PEMStructure.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.crypto;
3 |
4 | import java.util.Arrays;
5 | import java.util.Objects;
6 |
7 | /**
8 | * Parsed PEM structure.
9 | *
10 | * @author Christian Plattner, plattner@trilead.com
11 | * @version $Id: PEMStructure.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
12 | */
13 |
14 | public class PEMStructure
15 | {
16 | int pemType;
17 | String[] dekInfo;
18 | String procType[];
19 | byte[] data;
20 |
21 | public byte[] getData() {
22 | return data;
23 | }
24 |
25 | @Override
26 | public boolean equals(Object o) {
27 | if (this == o)
28 | return true;
29 | if (o == null || getClass() != o.getClass())
30 | return false;
31 | PEMStructure that = (PEMStructure) o;
32 | return pemType == that.pemType
33 | && Arrays.equals(dekInfo, that.dekInfo)
34 | && Arrays.equals(procType, that.procType)
35 | && Arrays.equals(data, that.data);
36 | }
37 |
38 | @Override
39 | public int hashCode() {
40 | int result = Objects.hash(pemType);
41 | result = 31 * result + Arrays.hashCode(dekInfo);
42 | result = 31 * result + Arrays.hashCode(procType);
43 | result = 31 * result + Arrays.hashCode(data);
44 | return result;
45 | }
46 |
47 | @Override
48 | public String toString() {
49 | final StringBuilder sb = new StringBuilder("PEMStructure{");
50 | sb.append("pemType=").append(pemType);
51 | sb.append(", dekInfo=").append(Arrays.toString(dekInfo));
52 | sb.append(", procType=").append(Arrays.toString(procType));
53 | sb.append(", data=").append(java.util.Base64.getEncoder().encodeToString(data));
54 | sb.append(", data.length=").append(data.length);
55 | sb.append('}');
56 | return sb.toString();
57 | }
58 | }
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/cipher/BlockCipher.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.crypto.cipher;
2 |
3 | /**
4 | * BlockCipher.
5 | *
6 | * @author Christian Plattner, plattner@trilead.com
7 | * @version $Id: BlockCipher.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
8 | */
9 | public interface BlockCipher
10 | {
11 | public void init(boolean forEncryption, byte[] key);
12 |
13 | public int getBlockSize();
14 |
15 | public void transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff);
16 | }
17 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/cipher/CBCMode.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.crypto.cipher;
2 |
3 | /**
4 | * CBCMode.
5 | *
6 | * @author Christian Plattner, plattner@trilead.com
7 | * @version $Id: CBCMode.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
8 | */
9 | public class CBCMode implements BlockCipher
10 | {
11 | BlockCipher tc;
12 | int blockSize;
13 | boolean doEncrypt;
14 |
15 | byte[] cbc_vector;
16 | byte[] tmp_vector;
17 |
18 | public void init(boolean forEncryption, byte[] key)
19 | {
20 | }
21 |
22 | public CBCMode(BlockCipher tc, byte[] iv, boolean doEncrypt)
23 | throws IllegalArgumentException
24 | {
25 | this.tc = tc;
26 | this.blockSize = tc.getBlockSize();
27 | this.doEncrypt = doEncrypt;
28 |
29 | if (this.blockSize != iv.length)
30 | throw new IllegalArgumentException("IV must be " + blockSize
31 | + " bytes long! (currently " + iv.length + ")");
32 |
33 | this.cbc_vector = new byte[blockSize];
34 | this.tmp_vector = new byte[blockSize];
35 | System.arraycopy(iv, 0, cbc_vector, 0, blockSize);
36 | }
37 |
38 | public int getBlockSize()
39 | {
40 | return blockSize;
41 | }
42 |
43 | private void encryptBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
44 | {
45 | for (int i = 0; i < blockSize; i++)
46 | cbc_vector[i] ^= src[srcoff + i];
47 |
48 | tc.transformBlock(cbc_vector, 0, dst, dstoff);
49 |
50 | System.arraycopy(dst, dstoff, cbc_vector, 0, blockSize);
51 | }
52 |
53 | private void decryptBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
54 | {
55 | /* Assume the worst, src and dst are overlapping... */
56 |
57 | System.arraycopy(src, srcoff, tmp_vector, 0, blockSize);
58 |
59 | tc.transformBlock(src, srcoff, dst, dstoff);
60 |
61 | for (int i = 0; i < blockSize; i++)
62 | dst[dstoff + i] ^= cbc_vector[i];
63 |
64 | /* ...that is why we need a tmp buffer. */
65 |
66 | byte[] swap = cbc_vector;
67 | cbc_vector = tmp_vector;
68 | tmp_vector = swap;
69 | }
70 |
71 | public void transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
72 | {
73 | if (doEncrypt)
74 | encryptBlock(src, srcoff, dst, dstoff);
75 | else
76 | decryptBlock(src, srcoff, dst, dstoff);
77 | }
78 | }
79 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/cipher/CTRMode.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.crypto.cipher;
3 |
4 | /**
5 | * This is CTR mode as described in draft-ietf-secsh-newmodes-XY.txt
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: CTRMode.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
9 | */
10 | public class CTRMode implements BlockCipher
11 | {
12 | byte[] X;
13 | byte[] Xenc;
14 |
15 | BlockCipher bc;
16 | int blockSize;
17 | boolean doEncrypt;
18 |
19 | int count = 0;
20 |
21 | public void init(boolean forEncryption, byte[] key)
22 | {
23 | }
24 |
25 | public CTRMode(BlockCipher tc, byte[] iv, boolean doEnc) throws IllegalArgumentException
26 | {
27 | bc = tc;
28 | blockSize = bc.getBlockSize();
29 | doEncrypt = doEnc;
30 |
31 | if (blockSize != iv.length)
32 | throw new IllegalArgumentException("IV must be " + blockSize + " bytes long! (currently " + iv.length + ")");
33 |
34 | X = new byte[blockSize];
35 | Xenc = new byte[blockSize];
36 |
37 | System.arraycopy(iv, 0, X, 0, blockSize);
38 | }
39 |
40 | public final int getBlockSize()
41 | {
42 | return blockSize;
43 | }
44 |
45 | public final void transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
46 | {
47 | bc.transformBlock(X, 0, Xenc, 0);
48 |
49 | for (int i = 0; i < blockSize; i++)
50 | {
51 | dst[dstoff + i] = (byte) (src[srcoff + i] ^ Xenc[i]);
52 | }
53 |
54 | for (int i = (blockSize - 1); i >= 0; i--)
55 | {
56 | X[i]++;
57 | if (X[i] != 0)
58 | break;
59 |
60 | }
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/cipher/NullCipher.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.crypto.cipher;
2 |
3 | /**
4 | * NullCipher.
5 | *
6 | * @author Christian Plattner, plattner@trilead.com
7 | * @version $Id: NullCipher.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
8 | */
9 | public class NullCipher implements BlockCipher
10 | {
11 | private int blockSize = 8;
12 |
13 | public NullCipher()
14 | {
15 | }
16 |
17 | public NullCipher(int blockSize)
18 | {
19 | this.blockSize = blockSize;
20 | }
21 |
22 | public void init(boolean forEncryption, byte[] key)
23 | {
24 | }
25 |
26 | public int getBlockSize()
27 | {
28 | return blockSize;
29 | }
30 |
31 | public void transformBlock(byte[] src, int srcoff, byte[] dst, int dstoff)
32 | {
33 | System.arraycopy(src, srcoff, dst, dstoff, blockSize);
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/dh/Curve25519Exchange.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.crypto.dh;
2 |
3 | import com.google.crypto.tink.subtle.X25519;
4 |
5 | import java.io.IOException;
6 | import java.math.BigInteger;
7 | import java.security.InvalidKeyException;
8 |
9 | /**
10 | * Created by Kenny Root on 1/23/16.
11 | */
12 | public class Curve25519Exchange extends GenericDhExchange {
13 | public static final String NAME = "curve25519-sha256";
14 | public static final String ALT_NAME = "curve25519-sha256@libssh.org";
15 | public static final int KEY_SIZE = 32;
16 |
17 | private byte[] clientPublic;
18 | private byte[] clientPrivate;
19 | private byte[] serverPublic;
20 |
21 | public Curve25519Exchange() {
22 | super();
23 | }
24 |
25 | /*
26 | * Used to test known vectors.
27 | */
28 | public Curve25519Exchange(byte[] secret) throws InvalidKeyException {
29 | if (secret.length != KEY_SIZE) {
30 | throw new AssertionError("secret must be key size");
31 | }
32 | clientPrivate = secret.clone();
33 | }
34 |
35 | @Override
36 | public void init(String name) throws IOException {
37 | if (!NAME.equals(name) && !ALT_NAME.equals(name)) {
38 | throw new IOException("Invalid name " + name);
39 | }
40 |
41 | clientPrivate = X25519.generatePrivateKey();
42 | try {
43 | clientPublic = X25519.publicFromPrivate(clientPrivate);
44 | } catch (InvalidKeyException e) {
45 | throw new IOException(e);
46 | }
47 | }
48 |
49 | @Override
50 | public byte[] getE() {
51 | return clientPublic.clone();
52 | }
53 |
54 | @Override
55 | protected byte[] getServerE() {
56 | return serverPublic.clone();
57 | }
58 |
59 | @Override
60 | public void setF(byte[] f) throws IOException {
61 | if (f.length != KEY_SIZE) {
62 | throw new IOException("Server sent invalid key length " + f.length + " (expected " +
63 | KEY_SIZE + ")");
64 | }
65 | serverPublic = f.clone();
66 | try {
67 | byte[] sharedSecretBytes = X25519.computeSharedSecret(clientPrivate, serverPublic);
68 | int allBytes = 0;
69 | for (int i = 0; i < sharedSecretBytes.length; i++) {
70 | allBytes |= sharedSecretBytes[i];
71 | }
72 | if (allBytes == 0) {
73 | throw new IOException("Invalid key computed; all zeroes");
74 | }
75 | sharedSecret = new BigInteger(1, sharedSecretBytes);
76 | } catch (InvalidKeyException e) {
77 | throw new IOException(e);
78 | }
79 | }
80 |
81 | @Override
82 | public String getHashAlgo() {
83 | return "SHA-256";
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/dh/DhGroupExchange.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.crypto.dh;
3 |
4 | import java.math.BigInteger;
5 | import java.security.SecureRandom;
6 |
7 | import com.trilead.ssh2.DHGexParameters;
8 | import com.trilead.ssh2.crypto.digest.HashForSSH2Types;
9 |
10 |
11 | /**
12 | * DhGroupExchange.
13 | *
14 | * @author Christian Plattner, plattner@trilead.com
15 | * @version $Id: DhGroupExchange.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
16 | */
17 | public class DhGroupExchange
18 | {
19 | /* Given by the standard */
20 |
21 | private BigInteger p;
22 | private BigInteger g;
23 |
24 | /* Client public and private */
25 |
26 | private BigInteger e;
27 | private BigInteger x;
28 |
29 | /* Server public */
30 |
31 | private BigInteger f;
32 |
33 | /* Shared secret */
34 |
35 | private BigInteger k;
36 |
37 | public DhGroupExchange(BigInteger p, BigInteger g)
38 | {
39 | this.p = p;
40 | this.g = g;
41 | }
42 |
43 | public void init(SecureRandom rnd)
44 | {
45 | k = null;
46 |
47 | x = new BigInteger(p.bitLength() - 1, rnd);
48 | e = g.modPow(x, p);
49 | }
50 |
51 | /**
52 | * @return Returns the e.
53 | */
54 | public BigInteger getE()
55 | {
56 | if (e == null)
57 | throw new IllegalStateException("Not initialized!");
58 |
59 | return e;
60 | }
61 |
62 | /**
63 | * @return Returns the shared secret k.
64 | */
65 | public BigInteger getK()
66 | {
67 | if (k == null)
68 | throw new IllegalStateException("Shared secret not yet known, need f first!");
69 |
70 | return k;
71 | }
72 |
73 | /**
74 | * Sets f and calculates the shared secret.
75 | * @param f f.
76 | */
77 | public void setF(BigInteger f)
78 | {
79 | if (e == null)
80 | throw new IllegalStateException("Not initialized!");
81 |
82 | BigInteger zero = BigInteger.valueOf(0);
83 |
84 | if (zero.compareTo(f) >= 0 || p.compareTo(f) <= 0)
85 | throw new IllegalArgumentException("Invalid f specified!");
86 |
87 | this.f = f;
88 | this.k = f.modPow(x, p);
89 | }
90 |
91 | public byte[] calculateH(String hashAlgo, byte[] clientversion, byte[] serverversion,
92 | byte[] clientKexPayload, byte[] serverKexPayload, byte[] hostKey, DHGexParameters para)
93 | {
94 | HashForSSH2Types hash = new HashForSSH2Types(hashAlgo);
95 |
96 | hash.updateByteString(clientversion);
97 | hash.updateByteString(serverversion);
98 | hash.updateByteString(clientKexPayload);
99 | hash.updateByteString(serverKexPayload);
100 | hash.updateByteString(hostKey);
101 | if (para.getMin_group_len() > 0)
102 | hash.updateUINT32(para.getMin_group_len());
103 | hash.updateUINT32(para.getPref_group_len());
104 | if (para.getMax_group_len() > 0)
105 | hash.updateUINT32(para.getMax_group_len());
106 | hash.updateBigInt(p);
107 | hash.updateBigInt(g);
108 | hash.updateBigInt(e);
109 | hash.updateBigInt(f);
110 | hash.updateBigInt(k);
111 |
112 | return hash.getDigest();
113 | }
114 | }
115 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/dh/GenericDhExchange.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.crypto.dh;
3 |
4 | import java.io.IOException;
5 | import java.io.UnsupportedEncodingException;
6 | import java.math.BigInteger;
7 | import java.security.SecureRandom;
8 |
9 | import com.trilead.ssh2.crypto.digest.HashForSSH2Types;
10 | import com.trilead.ssh2.log.Logger;
11 |
12 |
13 | /**
14 | * DhExchange.
15 | *
16 | * @author Christian Plattner, plattner@trilead.com
17 | * @version $Id: DhExchange.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
18 | */
19 | public abstract class GenericDhExchange
20 | {
21 | private static final Logger log = Logger.getLogger(GenericDhExchange.class);
22 |
23 | /* Shared secret */
24 |
25 | BigInteger sharedSecret;
26 |
27 | protected GenericDhExchange()
28 | {
29 | }
30 |
31 | public static GenericDhExchange getInstance(String algo) {
32 | if (Curve25519Exchange.NAME.equals(algo) || Curve25519Exchange.ALT_NAME.equals(algo)) {
33 | return new Curve25519Exchange();
34 | }
35 | if (algo.startsWith("ecdh-sha2-")) {
36 | return new EcDhExchange();
37 | } else {
38 | return new DhExchange();
39 | }
40 | }
41 |
42 | public abstract void init(String name) throws IOException;
43 |
44 | /**
45 | * @return Returns the e (public value)
46 | * @throws IllegalStateException
47 | */
48 | public abstract byte[] getE();
49 |
50 | /**
51 | * @return Returns the server's e (public value)
52 | * @throws IllegalStateException
53 | */
54 | protected abstract byte[] getServerE();
55 |
56 | /**
57 | * @return Returns the shared secret k.
58 | * @throws IllegalStateException
59 | */
60 | public BigInteger getK()
61 | {
62 | if (sharedSecret == null)
63 | throw new IllegalStateException("Shared secret not yet known, need f first!");
64 |
65 | return sharedSecret;
66 | }
67 |
68 | /**
69 | * @param f
70 | */
71 | public abstract void setF(byte[] f) throws IOException;
72 |
73 | public byte[] calculateH(byte[] clientversion, byte[] serverversion, byte[] clientKexPayload,
74 | byte[] serverKexPayload, byte[] hostKey) throws UnsupportedEncodingException
75 | {
76 | HashForSSH2Types hash = new HashForSSH2Types(getHashAlgo());
77 |
78 | if (log.isEnabled())
79 | {
80 | log.log(90, "Client: '" + new String(clientversion) + "'");
81 | log.log(90, "Server: '" + new String(serverversion) + "'");
82 | }
83 |
84 | hash.updateByteString(clientversion);
85 | hash.updateByteString(serverversion);
86 | hash.updateByteString(clientKexPayload);
87 | hash.updateByteString(serverKexPayload);
88 | hash.updateByteString(hostKey);
89 | hash.updateByteString(getE());
90 | hash.updateByteString(getServerE());
91 | hash.updateBigInt(sharedSecret);
92 |
93 | return hash.getDigest();
94 | }
95 |
96 | public abstract String getHashAlgo();
97 |
98 | }
99 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/digest/Digest.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.crypto.digest;
3 |
4 | /**
5 | * Digest.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: Digest.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
9 | */
10 | public interface Digest
11 | {
12 | public int getDigestLength();
13 |
14 | public void update(byte b);
15 |
16 | public void update(byte[] b);
17 |
18 | public void update(byte b[], int off, int len);
19 |
20 | public void reset();
21 |
22 | public void digest(byte[] out);
23 |
24 | public void digest(byte[] out, int off);
25 | }
26 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/digest/HMAC.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.crypto.digest;
3 |
4 | /**
5 | * HMAC.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: HMAC.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
9 | */
10 | @Deprecated
11 | public final class HMAC implements Digest
12 | {
13 | Digest md;
14 | byte[] k_xor_ipad;
15 | byte[] k_xor_opad;
16 |
17 | byte[] tmp;
18 |
19 | int size;
20 |
21 | public HMAC(Digest md, byte[] key, int size)
22 | {
23 | this.md = md;
24 | this.size = size;
25 |
26 | tmp = new byte[md.getDigestLength()];
27 |
28 | final int BLOCKSIZE = 64;
29 |
30 | k_xor_ipad = new byte[BLOCKSIZE];
31 | k_xor_opad = new byte[BLOCKSIZE];
32 |
33 | if (key.length > BLOCKSIZE)
34 | {
35 | md.reset();
36 | md.update(key);
37 | md.digest(tmp);
38 | key = tmp;
39 | }
40 |
41 | System.arraycopy(key, 0, k_xor_ipad, 0, key.length);
42 | System.arraycopy(key, 0, k_xor_opad, 0, key.length);
43 |
44 | for (int i = 0; i < BLOCKSIZE; i++)
45 | {
46 | k_xor_ipad[i] ^= 0x36;
47 | k_xor_opad[i] ^= 0x5C;
48 | }
49 | md.update(k_xor_ipad);
50 | }
51 |
52 | public final int getDigestLength()
53 | {
54 | return size;
55 | }
56 |
57 | public final void update(byte b)
58 | {
59 | md.update(b);
60 | }
61 |
62 | public final void update(byte[] b)
63 | {
64 | md.update(b);
65 | }
66 |
67 | public final void update(byte[] b, int off, int len)
68 | {
69 | md.update(b, off, len);
70 | }
71 |
72 | public final void reset()
73 | {
74 | md.reset();
75 | md.update(k_xor_ipad);
76 | }
77 |
78 | public final void digest(byte[] out)
79 | {
80 | digest(out, 0);
81 | }
82 |
83 | public final void digest(byte[] out, int off)
84 | {
85 | md.digest(tmp);
86 |
87 | md.update(k_xor_opad);
88 | md.update(tmp);
89 |
90 | md.digest(tmp);
91 |
92 | System.arraycopy(tmp, 0, out, off, size);
93 |
94 | md.update(k_xor_ipad);
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/digest/HashForSSH2Types.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.crypto.digest;
3 |
4 | import java.math.BigInteger;
5 | import java.security.GeneralSecurityException;
6 | import java.security.MessageDigest;
7 |
8 | /**
9 | * HashForSSH2Types.
10 | *
11 | * @author Christian Plattner, plattner@trilead.com
12 | * @version $Id: HashForSSH2Types.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
13 | */
14 | public class HashForSSH2Types
15 | {
16 |
17 | /**
18 | * Overwriting this value will not cause the result of the
19 | * digest to change
20 | * @deprecated the actual message digest is held in a private field
21 | */
22 | @Deprecated
23 | Digest md;
24 |
25 | private final Digest messageDigest;
26 |
27 |
28 |
29 | public HashForSSH2Types(Digest md)
30 | {
31 | super();
32 | this.md = md;
33 | this.messageDigest = md;
34 | }
35 |
36 | public HashForSSH2Types(String type)
37 | {
38 | this(new JreMessageDigestWrapper(createMessageDigest(type)));
39 | }
40 |
41 | private static MessageDigest createMessageDigest(String algorithm) {
42 | try {
43 | return MessageDigest.getInstance(algorithm);
44 | } catch (GeneralSecurityException ex) {
45 | throw new IllegalArgumentException("Could not get Message digest instance", ex);
46 | }
47 | }
48 |
49 | public void updateByte(byte b)
50 | {
51 | /* HACK - to test it with J2ME */
52 | byte[] tmp = new byte[1];
53 | tmp[0] = b;
54 | messageDigest.update(tmp);
55 | }
56 |
57 | public void updateBytes(byte[] b)
58 | {
59 | messageDigest.update(b);
60 | }
61 |
62 | public void updateUINT32(int v)
63 | {
64 | messageDigest.update((byte) (v >> 24));
65 | messageDigest.update((byte) (v >> 16));
66 | messageDigest.update((byte) (v >> 8));
67 | messageDigest.update((byte) (v));
68 | }
69 |
70 | public void updateByteString(byte[] b)
71 | {
72 | updateUINT32(b.length);
73 | updateBytes(b);
74 | }
75 |
76 | public void updateBigInt(BigInteger b)
77 | {
78 | updateByteString(b.toByteArray());
79 | }
80 |
81 | public void reset()
82 | {
83 | messageDigest.reset();
84 | }
85 |
86 | public int getDigestLength()
87 | {
88 | return messageDigest.getDigestLength();
89 | }
90 |
91 | public byte[] getDigest()
92 | {
93 | byte[] tmp = new byte[messageDigest.getDigestLength()];
94 | getDigest(tmp);
95 | return tmp;
96 | }
97 |
98 | public void getDigest(byte[] out)
99 | {
100 | getDigest(out, 0);
101 | }
102 |
103 | public void getDigest(byte[] out, int off)
104 | {
105 | messageDigest.digest(out, off);
106 | }
107 | }
108 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/crypto/digest/JreMessageDigestWrapper.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.crypto.digest;
2 |
3 | import java.security.MessageDigest;
4 |
5 | /**
6 | * @author Michael Clarke
7 | */
8 | public class JreMessageDigestWrapper implements Digest {
9 |
10 | private final MessageDigest digest;
11 |
12 | public JreMessageDigestWrapper(MessageDigest digest) {
13 | super();
14 | this.digest = digest;
15 | }
16 |
17 | public int getDigestLength() {
18 | return digest.getDigestLength();
19 | }
20 |
21 | public void update(byte b) {
22 | digest.update(b);
23 | }
24 |
25 | public void update(byte[] b) {
26 | digest.update(b);
27 | }
28 |
29 | public void update(byte[] b, int off, int len) {
30 | digest.update(b, off, len);
31 | }
32 |
33 | public void reset() {
34 | digest.reset();
35 | }
36 |
37 | public void digest(byte[] out) {
38 | byte[] output = digest.digest();
39 | System.arraycopy(output, 0, out, 0, out.length);
40 | }
41 |
42 | public void digest(byte[] out, int off) {
43 | byte[] output = digest.digest();
44 | System.arraycopy(output, 0, out, off, out.length);
45 |
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/jenkins/FilterEncrytionAlgorithms.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.jenkins;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collection;
5 | import java.util.Collections;
6 | import java.util.List;
7 |
8 | import com.trilead.ssh2.log.Logger;
9 |
10 | /**
11 | * Filter encryption algorithms.
12 | * The reason for this filter is that some algorithms have security issues.
13 | * The filter can be disabled by setting the system property
14 | * com.trilead.ssh2.jenkins.FilterEncrytionAlgorithms.enabled to false.
15 | * The list of algorithms to filter can be set by setting the system property
16 | * com.trilead.ssh2.jenkins.FilterEncrytionAlgorithms.algorithms (e.g. type01,type02,type03).
17 | */
18 | public class FilterEncrytionAlgorithms {
19 | /*
20 | * The list of algorithms to filter by default.
21 | */
22 | private static final List filteredAlgorithms = Collections.emptyList();
23 |
24 | /**
25 | * Filter algorithms.
26 | * @param algorithms The algorithms to filter.
27 | * @return The filtered algorithms.
28 | */
29 | public static String[] filter(String[] algorithms) {
30 | FilterAlgorithms filter = new FilterAlgorithms(FilterEncrytionAlgorithms.class.getName(), filteredAlgorithms);
31 | return filter.filter(algorithms);
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/jenkins/FilterHostKeyAlgorithms.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.jenkins;
2 |
3 | import java.util.ArrayList;
4 | import java.util.Collections;
5 | import java.util.List;
6 |
7 | import com.trilead.ssh2.log.Logger;
8 |
9 | /**
10 | * Filter host key algorithms.
11 | * The reason for this filter is that some algorithms have security issues.
12 | * The filter can be disabled by setting the system property
13 | * com.trilead.ssh2.jenkins.FilterHostKeyAlgorithms.enabled to false.
14 | * The list of algorithms to filter can be set by setting the system property
15 | * com.trilead.ssh2.jenkins.FilterHostKeyAlgorithms.algorithms (e.g. type01,type02,type03).
16 | */
17 | public class FilterHostKeyAlgorithms {
18 | /*
19 | * The list of algorithms to filter.
20 | */
21 | private static final List filteredAlgorithms = Collections.emptyList();
22 |
23 | /**
24 | * Filter algorithms.
25 | * @param algorithms The algorithms to filter.
26 | * @return The filtered algorithms.
27 | */
28 | public static String[] filter(String[] algorithms) {
29 | FilterAlgorithms filter = new FilterAlgorithms(FilterHostKeyAlgorithms.class.getName(), filteredAlgorithms);
30 | return filter.filter(algorithms);
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/jenkins/FilterKexAlgorithms.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.jenkins;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import com.trilead.ssh2.log.Logger;
7 |
8 | /**
9 | * Filter KEX algorithms.
10 | * The reason for this filter is that some algorithms have security issues.
11 | * The filter can be disabled by setting the system property
12 | * com.trilead.ssh2.jenkins.FilterKexAlgorithms.enabled to false.
13 | * The list of algorithms to filter can be set by setting the system property
14 | * com.trilead.ssh2.jenkins.FilterKexAlgorithms.algorithms (e.g. type01,type02,type03).
15 | */
16 | public class FilterKexAlgorithms {
17 | /*
18 | * The list of algorithms to filter.
19 | */
20 | private static final List filteredAlgorithms = new ArrayList<>(
21 | List.of(
22 | // Terrapin attack see https://en.wikipedia.org/wiki/Terrapin_attack
23 | "chacha20-poly1305@openssh.com"));
24 |
25 | /**
26 | * Filter algorithms.
27 | * @param algorithms The algorithms to filter.
28 | * @return The filtered algorithms.
29 | */
30 | public static String[] filter(String[] algorithms) {
31 | FilterAlgorithms filter = new FilterAlgorithms(FilterKexAlgorithms.class.getName(), filteredAlgorithms);
32 | return filter.filter(algorithms);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/jenkins/FilterMacAlgorithms.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.jenkins;
2 |
3 | import java.util.ArrayList;
4 | import java.util.List;
5 |
6 | import com.trilead.ssh2.log.Logger;
7 |
8 | /**
9 | * Filter host key algorithms.
10 | * The reason for this filter is that some algorithms have security issues.
11 | * The filter can be disabled by setting the system property
12 | * com.trilead.ssh2.jenkins.FilterHostKeyAlgorithms.enabled to false.
13 | * The list of algorithms to filter can be set by setting the system property
14 | * com.trilead.ssh2.jenkins.FilterHostKeyAlgorithms.algorithms (e.g. type01,type02,type03).
15 | */
16 | public class FilterMacAlgorithms {
17 | /*
18 | * The list of algorithms to filter.
19 | */
20 | private static final List filteredAlgorithms = new ArrayList<>(
21 | List.of(
22 | // Terrapin attack see https://en.wikipedia.org/wiki/Terrapin_attack
23 | "hmac-sha2-512-etm@openssh.com",
24 | // Terrapin attack see https://en.wikipedia.org/wiki/Terrapin_attack
25 | "hmac-sha2-256-etm@openssh.com"));
26 |
27 | /**
28 | * Filter algorithms.
29 | * @param algorithms The algorithms to filter.
30 | * @return The filtered algorithms.
31 | */
32 | public static String[] filter(String[] algorithms) {
33 | FilterAlgorithms filter = new FilterAlgorithms(FilterMacAlgorithms.class.getName(), filteredAlgorithms);
34 | return filter.filter(algorithms);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/log/Logger.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.log;
3 |
4 | import com.trilead.ssh2.DebugLogger;
5 |
6 | import java.util.logging.Level;
7 |
8 | /**
9 | * Logger - a very simple logger, mainly used during development.
10 | * Is not based on log4j (to reduce external dependencies).
11 | * However, if needed, something like log4j could easily be
12 | * hooked in.
13 | *
14 | * For speed reasons, the static variables are not protected
15 | * with semaphores. In other words, if you dynamicaly change the
16 | * logging settings, then some threads may still use the old setting.
17 | *
18 | * @author Christian Plattner, plattner@trilead.com
19 | * @version $Id: Logger.java,v 1.2 2008/03/03 07:01:36 cplattne Exp $
20 | */
21 |
22 | public class Logger
23 | {
24 | public static boolean enabled = false;
25 | public static DebugLogger logger = null;
26 |
27 | private java.util.logging.Logger log;
28 |
29 | public final static Logger getLogger(Class x)
30 | {
31 | return new Logger(x);
32 | }
33 |
34 | public Logger(Class x)
35 | {
36 | this.log = java.util.logging.Logger.getLogger(x.getName());
37 | }
38 |
39 | public final boolean isEnabled()
40 | {
41 | return true;
42 | }
43 |
44 | public final void log(int lv, String message)
45 | {
46 | log.log(level(lv),message);
47 | }
48 |
49 | public final void log(int lv, String message, Throwable cause)
50 | {
51 | log.log(level(lv),message,cause);
52 | }
53 |
54 | private Level level(int lv) {
55 | if (lv<=20) return Level.FINE;
56 | if (lv<=50) return Level.FINER;
57 | return Level.FINEST;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketChannelOpenConfirmation.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | import java.io.IOException;
4 |
5 | /**
6 | * PacketChannelOpenConfirmation.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: PacketChannelOpenConfirmation.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
10 | */
11 | public class PacketChannelOpenConfirmation
12 | {
13 | byte[] payload;
14 |
15 | public int recipientChannelID;
16 | public int senderChannelID;
17 | public int initialWindowSize;
18 | public int maxPacketSize;
19 |
20 | public PacketChannelOpenConfirmation(int recipientChannelID, int senderChannelID, int initialWindowSize,
21 | int maxPacketSize)
22 | {
23 | this.recipientChannelID = recipientChannelID;
24 | this.senderChannelID = senderChannelID;
25 | this.initialWindowSize = initialWindowSize;
26 | this.maxPacketSize = maxPacketSize;
27 | }
28 |
29 | public PacketChannelOpenConfirmation(byte payload[], int off, int len) throws IOException
30 | {
31 | this.payload = new byte[len];
32 | System.arraycopy(payload, off, this.payload, 0, len);
33 |
34 | TypesReader tr = new TypesReader(payload, off, len);
35 |
36 | int packet_type = tr.readByte();
37 |
38 | if (packet_type != Packets.SSH_MSG_CHANNEL_OPEN_CONFIRMATION)
39 | throw new IOException(
40 | "This is not a SSH_MSG_CHANNEL_OPEN_CONFIRMATION! ("
41 | + packet_type + ")");
42 |
43 | recipientChannelID = tr.readUINT32();
44 | senderChannelID = tr.readUINT32();
45 | initialWindowSize = tr.readUINT32();
46 | maxPacketSize = tr.readUINT32();
47 |
48 | if (tr.remain() != 0)
49 | throw new IOException("Padding in SSH_MSG_CHANNEL_OPEN_CONFIRMATION packet!");
50 | }
51 |
52 | public byte[] getPayload()
53 | {
54 | if (payload == null)
55 | {
56 | TypesWriter tw = new TypesWriter();
57 | tw.writeByte(Packets.SSH_MSG_CHANNEL_OPEN_CONFIRMATION);
58 | tw.writeUINT32(recipientChannelID);
59 | tw.writeUINT32(senderChannelID);
60 | tw.writeUINT32(initialWindowSize);
61 | tw.writeUINT32(maxPacketSize);
62 | payload = tw.getBytes();
63 | }
64 | return payload;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketChannelOpenFailure.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | import java.io.IOException;
4 |
5 | /**
6 | * PacketChannelOpenFailure.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: PacketChannelOpenFailure.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
10 | */
11 | public class PacketChannelOpenFailure
12 | {
13 | byte[] payload;
14 |
15 | public int recipientChannelID;
16 | public int reasonCode;
17 | public String description;
18 | public String languageTag;
19 |
20 | public PacketChannelOpenFailure(int recipientChannelID, int reasonCode, String description,
21 | String languageTag)
22 | {
23 | this.recipientChannelID = recipientChannelID;
24 | this.reasonCode = reasonCode;
25 | this.description = description;
26 | this.languageTag = languageTag;
27 | }
28 |
29 | public PacketChannelOpenFailure(byte payload[], int off, int len) throws IOException
30 | {
31 | this.payload = new byte[len];
32 | System.arraycopy(payload, off, this.payload, 0, len);
33 |
34 | TypesReader tr = new TypesReader(payload, off, len);
35 |
36 | int packet_type = tr.readByte();
37 |
38 | if (packet_type != Packets.SSH_MSG_CHANNEL_OPEN_FAILURE)
39 | throw new IOException(
40 | "This is not a SSH_MSG_CHANNEL_OPEN_FAILURE! ("
41 | + packet_type + ")");
42 |
43 | recipientChannelID = tr.readUINT32();
44 | reasonCode = tr.readUINT32();
45 | description = tr.readString();
46 | languageTag = tr.readString();
47 |
48 | if (tr.remain() != 0)
49 | throw new IOException("Padding in SSH_MSG_CHANNEL_OPEN_FAILURE packet!");
50 | }
51 |
52 | public byte[] getPayload()
53 | {
54 | if (payload == null)
55 | {
56 | TypesWriter tw = new TypesWriter();
57 | tw.writeByte(Packets.SSH_MSG_CHANNEL_OPEN_FAILURE);
58 | tw.writeUINT32(recipientChannelID);
59 | tw.writeUINT32(reasonCode);
60 | tw.writeString(description);
61 | tw.writeString(languageTag);
62 | payload = tw.getBytes();
63 | }
64 | return payload;
65 | }
66 | }
67 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketChannelTrileadPing.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | /**
5 | * PacketChannelTrileadPing.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: PacketChannelTrileadPing.java,v 1.1 2008/03/03 07:01:36
9 | * cplattne Exp $
10 | */
11 | public class PacketChannelTrileadPing
12 | {
13 | byte[] payload;
14 |
15 | public int recipientChannelID;
16 |
17 | public PacketChannelTrileadPing(int recipientChannelID)
18 | {
19 | this.recipientChannelID = recipientChannelID;
20 | }
21 |
22 | public byte[] getPayload()
23 | {
24 | if (payload == null)
25 | {
26 | TypesWriter tw = new TypesWriter();
27 | tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
28 | tw.writeUINT32(recipientChannelID);
29 | tw.writeString("trilead-ping");
30 | tw.writeBoolean(true);
31 | payload = tw.getBytes();
32 | }
33 | return payload;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketChannelWindowAdjust.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | import java.io.IOException;
4 |
5 | /**
6 | * PacketChannelWindowAdjust.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: PacketChannelWindowAdjust.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
10 | */
11 | public class PacketChannelWindowAdjust
12 | {
13 | byte[] payload;
14 |
15 | public int recipientChannelID;
16 | public int windowChange;
17 |
18 | public PacketChannelWindowAdjust(int recipientChannelID, int windowChange)
19 | {
20 | this.recipientChannelID = recipientChannelID;
21 | this.windowChange = windowChange;
22 | }
23 |
24 | public PacketChannelWindowAdjust(byte payload[], int off, int len) throws IOException
25 | {
26 | this.payload = new byte[len];
27 | System.arraycopy(payload, off, this.payload, 0, len);
28 |
29 | TypesReader tr = new TypesReader(payload, off, len);
30 |
31 | int packet_type = tr.readByte();
32 |
33 | if (packet_type != Packets.SSH_MSG_CHANNEL_WINDOW_ADJUST)
34 | throw new IOException(
35 | "This is not a SSH_MSG_CHANNEL_WINDOW_ADJUST! ("
36 | + packet_type + ")");
37 |
38 | recipientChannelID = tr.readUINT32();
39 | windowChange = tr.readUINT32();
40 |
41 | if (tr.remain() != 0)
42 | throw new IOException("Padding in SSH_MSG_CHANNEL_WINDOW_ADJUST packet!");
43 | }
44 |
45 | public byte[] getPayload()
46 | {
47 | if (payload == null)
48 | {
49 | TypesWriter tw = new TypesWriter();
50 | tw.writeByte(Packets.SSH_MSG_CHANNEL_WINDOW_ADJUST);
51 | tw.writeUINT32(recipientChannelID);
52 | tw.writeUINT32(windowChange);
53 | payload = tw.getBytes();
54 | }
55 | return payload;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketDisconnect.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | import java.io.IOException;
5 |
6 | /**
7 | * PacketDisconnect.
8 | *
9 | * @author Christian Plattner, plattner@trilead.com
10 | * @version $Id: PacketDisconnect.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
11 | */
12 | public class PacketDisconnect
13 | {
14 | byte[] payload;
15 |
16 | int reason;
17 | String desc;
18 | String lang;
19 |
20 | public PacketDisconnect(byte payload[], int off, int len) throws IOException
21 | {
22 | this.payload = new byte[len];
23 | System.arraycopy(payload, off, this.payload, 0, len);
24 |
25 | TypesReader tr = new TypesReader(payload, off, len);
26 |
27 | int packet_type = tr.readByte();
28 |
29 | if (packet_type != Packets.SSH_MSG_DISCONNECT)
30 | throw new IOException("This is not a Disconnect Packet! (" + packet_type + ")");
31 |
32 | reason = tr.readUINT32();
33 | desc = tr.readString();
34 | lang = tr.readString();
35 | }
36 |
37 | public PacketDisconnect(int reason, String desc, String lang)
38 | {
39 | this.reason = reason;
40 | this.desc = desc;
41 | this.lang = lang;
42 | }
43 |
44 | public byte[] getPayload()
45 | {
46 | if (payload == null)
47 | {
48 | TypesWriter tw = new TypesWriter();
49 | tw.writeByte(Packets.SSH_MSG_DISCONNECT);
50 | tw.writeUINT32(reason);
51 | tw.writeString(desc);
52 | tw.writeString(lang);
53 | payload = tw.getBytes();
54 | }
55 | return payload;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketGlobalCancelForwardRequest.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | /**
5 | * PacketGlobalCancelForwardRequest.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: PacketGlobalCancelForwardRequest.java,v 1.1 2007/10/15 12:49:55
9 | * cplattne Exp $
10 | */
11 | public class PacketGlobalCancelForwardRequest
12 | {
13 | byte[] payload;
14 |
15 | public boolean wantReply;
16 | public String bindAddress;
17 | public int bindPort;
18 |
19 | public PacketGlobalCancelForwardRequest(boolean wantReply, String bindAddress, int bindPort)
20 | {
21 | this.wantReply = wantReply;
22 | this.bindAddress = bindAddress;
23 | this.bindPort = bindPort;
24 | }
25 |
26 | public byte[] getPayload()
27 | {
28 | if (payload == null)
29 | {
30 | TypesWriter tw = new TypesWriter();
31 | tw.writeByte(Packets.SSH_MSG_GLOBAL_REQUEST);
32 |
33 | tw.writeString("cancel-tcpip-forward");
34 | tw.writeBoolean(wantReply);
35 | tw.writeString(bindAddress);
36 | tw.writeUINT32(bindPort);
37 |
38 | payload = tw.getBytes();
39 | }
40 | return payload;
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketGlobalForwardRequest.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | /**
5 | * PacketGlobalForwardRequest.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: PacketGlobalForwardRequest.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
9 | */
10 | public class PacketGlobalForwardRequest
11 | {
12 | byte[] payload;
13 |
14 | public boolean wantReply;
15 | public String bindAddress;
16 | public int bindPort;
17 |
18 | public PacketGlobalForwardRequest(boolean wantReply, String bindAddress, int bindPort)
19 | {
20 | this.wantReply = wantReply;
21 | this.bindAddress = bindAddress;
22 | this.bindPort = bindPort;
23 | }
24 |
25 | public byte[] getPayload()
26 | {
27 | if (payload == null)
28 | {
29 | TypesWriter tw = new TypesWriter();
30 | tw.writeByte(Packets.SSH_MSG_GLOBAL_REQUEST);
31 |
32 | tw.writeString("tcpip-forward");
33 | tw.writeBoolean(wantReply);
34 | tw.writeString(bindAddress);
35 | tw.writeUINT32(bindPort);
36 |
37 | payload = tw.getBytes();
38 | }
39 | return payload;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketGlobalTrileadPing.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | /**
5 | * PacketGlobalTrileadPing.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: PacketGlobalTrileadPing.java,v 1.1 2008/03/03 07:01:36 cplattne Exp $
9 | */
10 | public class PacketGlobalTrileadPing
11 | {
12 | byte[] payload;
13 |
14 | public PacketGlobalTrileadPing()
15 | {
16 | }
17 |
18 | public byte[] getPayload()
19 | {
20 | if (payload == null)
21 | {
22 | TypesWriter tw = new TypesWriter();
23 | tw.writeByte(Packets.SSH_MSG_GLOBAL_REQUEST);
24 |
25 | tw.writeString("trilead-ping");
26 | tw.writeBoolean(true);
27 |
28 | payload = tw.getBytes();
29 | }
30 | return payload;
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketIgnore.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | import java.io.IOException;
5 |
6 | /**
7 | * PacketIgnore.
8 | *
9 | * @author Christian Plattner, plattner@trilead.com
10 | * @version $Id: PacketIgnore.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
11 | */
12 | public class PacketIgnore
13 | {
14 | byte[] payload;
15 |
16 | byte[] data;
17 |
18 | public void setData(byte[] data)
19 | {
20 | this.data = data;
21 | payload = null;
22 | }
23 |
24 | public PacketIgnore()
25 | {
26 | }
27 |
28 | public PacketIgnore(byte payload[], int off, int len) throws IOException
29 | {
30 | this.payload = new byte[len];
31 | System.arraycopy(payload, off, this.payload, 0, len);
32 |
33 | TypesReader tr = new TypesReader(payload, off, len);
34 |
35 | int packet_type = tr.readByte();
36 |
37 | if (packet_type != Packets.SSH_MSG_IGNORE)
38 | throw new IOException("This is not a SSH_MSG_IGNORE packet! (" + packet_type + ")");
39 |
40 | /* Could parse String body */
41 | }
42 |
43 | public byte[] getPayload()
44 | {
45 | if (payload == null)
46 | {
47 | TypesWriter tw = new TypesWriter();
48 | tw.writeByte(Packets.SSH_MSG_IGNORE);
49 |
50 | if (data != null)
51 | tw.writeString(data, 0, data.length);
52 | else
53 | tw.writeString("");
54 |
55 | payload = tw.getBytes();
56 | }
57 | return payload;
58 | }
59 | }
60 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketKexDHInit.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | /**
4 | * PacketKexDHInit.
5 | *
6 | * @author Christian Plattner, plattner@trilead.com
7 | * @version $Id: PacketKexDHInit.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
8 | */
9 | public class PacketKexDHInit
10 | {
11 | byte[] payload;
12 |
13 | byte[] publicKey;
14 |
15 | public PacketKexDHInit(byte[] publicKey)
16 | {
17 | this.publicKey = publicKey;
18 | }
19 |
20 | public byte[] getPayload()
21 | {
22 | if (payload == null)
23 | {
24 | TypesWriter tw = new TypesWriter();
25 | tw.writeByte(Packets.SSH_MSG_KEXDH_INIT);
26 | tw.writeString(publicKey, 0, publicKey.length);
27 | payload = tw.getBytes();
28 | }
29 | return payload;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketKexDHReply.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | import java.io.IOException;
4 |
5 |
6 | /**
7 | * PacketKexDHReply.
8 | *
9 | * @author Christian Plattner, plattner@trilead.com
10 | * @version $Id: PacketKexDHReply.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
11 | */
12 | public class PacketKexDHReply
13 | {
14 | byte[] payload;
15 |
16 | byte[] hostKey;
17 | byte [] publicKey;
18 | byte[] signature;
19 |
20 | public PacketKexDHReply(byte payload[], int off, int len) throws IOException
21 | {
22 | this.payload = new byte[len];
23 | System.arraycopy(payload, off, this.payload, 0, len);
24 |
25 | TypesReader tr = new TypesReader(payload, off, len);
26 |
27 | int packet_type = tr.readByte();
28 |
29 | if (packet_type != Packets.SSH_MSG_KEXDH_REPLY)
30 | throw new IOException("This is not a SSH_MSG_KEXDH_REPLY! ("
31 | + packet_type + ")");
32 |
33 | hostKey = tr.readByteString();
34 | publicKey = tr.readByteString();
35 | signature = tr.readByteString();
36 |
37 | if (tr.remain() != 0) throw new IOException("PADDING IN SSH_MSG_KEXDH_REPLY!");
38 | }
39 |
40 | public byte[] getF()
41 | {
42 | return publicKey;
43 |
44 | }
45 |
46 | public byte[] getHostKey()
47 | {
48 | return hostKey;
49 | }
50 |
51 | public byte[] getSignature()
52 | {
53 | return signature;
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketKexDhGexGroup.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | import java.io.IOException;
4 |
5 | import java.math.BigInteger;
6 |
7 | /**
8 | * PacketKexDhGexGroup.
9 | *
10 | * @author Christian Plattner, plattner@trilead.com
11 | * @version $Id: PacketKexDhGexGroup.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
12 | */
13 | public class PacketKexDhGexGroup
14 | {
15 | byte[] payload;
16 |
17 | BigInteger p;
18 | BigInteger g;
19 |
20 | public PacketKexDhGexGroup(byte payload[], int off, int len) throws IOException
21 | {
22 | this.payload = new byte[len];
23 | System.arraycopy(payload, off, this.payload, 0, len);
24 |
25 | TypesReader tr = new TypesReader(payload, off, len);
26 |
27 | int packet_type = tr.readByte();
28 |
29 | if (packet_type != Packets.SSH_MSG_KEX_DH_GEX_GROUP)
30 | throw new IllegalArgumentException(
31 | "This is not a SSH_MSG_KEX_DH_GEX_GROUP! (" + packet_type
32 | + ")");
33 |
34 | p = tr.readMPINT();
35 | g = tr.readMPINT();
36 |
37 | if (tr.remain() != 0)
38 | throw new IOException("PADDING IN SSH_MSG_KEX_DH_GEX_GROUP!");
39 | }
40 |
41 | public BigInteger getG()
42 | {
43 | return g;
44 | }
45 |
46 | public BigInteger getP()
47 | {
48 | return p;
49 | }
50 | }
51 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketKexDhGexInit.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | import java.math.BigInteger;
4 |
5 | /**
6 | * PacketKexDhGexInit.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: PacketKexDhGexInit.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
10 | */
11 | public class PacketKexDhGexInit
12 | {
13 | byte[] payload;
14 |
15 | BigInteger e;
16 |
17 | public PacketKexDhGexInit(BigInteger e)
18 | {
19 | this.e = e;
20 | }
21 |
22 | public byte[] getPayload()
23 | {
24 | if (payload == null)
25 | {
26 | TypesWriter tw = new TypesWriter();
27 | tw.writeByte(Packets.SSH_MSG_KEX_DH_GEX_INIT);
28 | tw.writeMPInt(e);
29 | payload = tw.getBytes();
30 | }
31 | return payload;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketKexDhGexReply.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | import java.io.IOException;
5 |
6 | import java.math.BigInteger;
7 |
8 | /**
9 | * PacketKexDhGexReply.
10 | *
11 | * @author Christian Plattner, plattner@trilead.com
12 | * @version $Id: PacketKexDhGexReply.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
13 | */
14 | public class PacketKexDhGexReply
15 | {
16 | byte[] payload;
17 |
18 | byte[] hostKey;
19 | BigInteger f;
20 | byte[] signature;
21 |
22 | public PacketKexDhGexReply(byte payload[], int off, int len) throws IOException
23 | {
24 | this.payload = new byte[len];
25 | System.arraycopy(payload, off, this.payload, 0, len);
26 |
27 | TypesReader tr = new TypesReader(payload, off, len);
28 |
29 | int packet_type = tr.readByte();
30 |
31 | if (packet_type != Packets.SSH_MSG_KEX_DH_GEX_REPLY)
32 | throw new IOException("This is not a SSH_MSG_KEX_DH_GEX_REPLY! (" + packet_type + ")");
33 |
34 | hostKey = tr.readByteString();
35 | f = tr.readMPINT();
36 | signature = tr.readByteString();
37 |
38 | if (tr.remain() != 0)
39 | throw new IOException("PADDING IN SSH_MSG_KEX_DH_GEX_REPLY!");
40 | }
41 |
42 | public BigInteger getF()
43 | {
44 | return f;
45 | }
46 |
47 | public byte[] getHostKey()
48 | {
49 | return hostKey;
50 | }
51 |
52 | public byte[] getSignature()
53 | {
54 | return signature;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketKexDhGexRequest.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | import com.trilead.ssh2.DHGexParameters;
4 |
5 | /**
6 | * PacketKexDhGexRequest.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: PacketKexDhGexRequest.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
10 | */
11 | public class PacketKexDhGexRequest
12 | {
13 | byte[] payload;
14 |
15 | int min;
16 | int n;
17 | int max;
18 |
19 | public PacketKexDhGexRequest(DHGexParameters para)
20 | {
21 | this.min = para.getMin_group_len();
22 | this.n = para.getPref_group_len();
23 | this.max = para.getMax_group_len();
24 | }
25 |
26 | public byte[] getPayload()
27 | {
28 | if (payload == null)
29 | {
30 | TypesWriter tw = new TypesWriter();
31 | tw.writeByte(Packets.SSH_MSG_KEX_DH_GEX_REQUEST);
32 | tw.writeUINT32(min);
33 | tw.writeUINT32(n);
34 | tw.writeUINT32(max);
35 | payload = tw.getBytes();
36 | }
37 | return payload;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketKexDhGexRequestOld.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | import com.trilead.ssh2.DHGexParameters;
5 |
6 | /**
7 | * PacketKexDhGexRequestOld.
8 | *
9 | * @author Christian Plattner, plattner@trilead.com
10 | * @version $Id: PacketKexDhGexRequestOld.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
11 | */
12 | public class PacketKexDhGexRequestOld
13 | {
14 | byte[] payload;
15 |
16 | int n;
17 |
18 | public PacketKexDhGexRequestOld(DHGexParameters para)
19 | {
20 | this.n = para.getPref_group_len();
21 | }
22 |
23 | public byte[] getPayload()
24 | {
25 | if (payload == null)
26 | {
27 | TypesWriter tw = new TypesWriter();
28 | tw.writeByte(Packets.SSH_MSG_KEX_DH_GEX_REQUEST_OLD);
29 | tw.writeUINT32(n);
30 | payload = tw.getBytes();
31 | }
32 | return payload;
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketNewKeys.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | import java.io.IOException;
4 |
5 | /**
6 | * PacketNewKeys.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: PacketNewKeys.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
10 | */
11 | public class PacketNewKeys
12 | {
13 | byte[] payload;
14 |
15 | public PacketNewKeys()
16 | {
17 | }
18 |
19 | public PacketNewKeys(byte payload[], int off, int len) throws IOException
20 | {
21 | this.payload = new byte[len];
22 | System.arraycopy(payload, off, this.payload, 0, len);
23 |
24 | TypesReader tr = new TypesReader(payload, off, len);
25 |
26 | int packet_type = tr.readByte();
27 |
28 | if (packet_type != Packets.SSH_MSG_NEWKEYS)
29 | throw new IOException("This is not a SSH_MSG_NEWKEYS! ("
30 | + packet_type + ")");
31 |
32 | if (tr.remain() != 0)
33 | throw new IOException("Padding in SSH_MSG_NEWKEYS packet!");
34 | }
35 |
36 | public byte[] getPayload()
37 | {
38 | if (payload == null)
39 | {
40 | TypesWriter tw = new TypesWriter();
41 | tw.writeByte(Packets.SSH_MSG_NEWKEYS);
42 | payload = tw.getBytes();
43 | }
44 | return payload;
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketOpenDirectTCPIPChannel.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 |
4 | /**
5 | * PacketOpenDirectTCPIPChannel.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: PacketOpenDirectTCPIPChannel.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
9 | */
10 | public class PacketOpenDirectTCPIPChannel
11 | {
12 | byte[] payload;
13 |
14 | int channelID;
15 | int initialWindowSize;
16 | int maxPacketSize;
17 |
18 | String host_to_connect;
19 | int port_to_connect;
20 | String originator_IP_address;
21 | int originator_port;
22 |
23 | public PacketOpenDirectTCPIPChannel(int channelID, int initialWindowSize, int maxPacketSize,
24 | String host_to_connect, int port_to_connect, String originator_IP_address,
25 | int originator_port)
26 | {
27 | this.channelID = channelID;
28 | this.initialWindowSize = initialWindowSize;
29 | this.maxPacketSize = maxPacketSize;
30 | this.host_to_connect = host_to_connect;
31 | this.port_to_connect = port_to_connect;
32 | this.originator_IP_address = originator_IP_address;
33 | this.originator_port = originator_port;
34 | }
35 |
36 | public byte[] getPayload()
37 | {
38 | if (payload == null)
39 | {
40 | TypesWriter tw = new TypesWriter();
41 |
42 | tw.writeByte(Packets.SSH_MSG_CHANNEL_OPEN);
43 | tw.writeString("direct-tcpip");
44 | tw.writeUINT32(channelID);
45 | tw.writeUINT32(initialWindowSize);
46 | tw.writeUINT32(maxPacketSize);
47 | tw.writeString(host_to_connect);
48 | tw.writeUINT32(port_to_connect);
49 | tw.writeString(originator_IP_address);
50 | tw.writeUINT32(originator_port);
51 |
52 | payload = tw.getBytes();
53 | }
54 | return payload;
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketOpenSessionChannel.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | import java.io.IOException;
4 |
5 | /**
6 | * PacketOpenSessionChannel.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: PacketOpenSessionChannel.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
10 | */
11 | public class PacketOpenSessionChannel
12 | {
13 | byte[] payload;
14 |
15 | int channelID;
16 | int initialWindowSize;
17 | int maxPacketSize;
18 |
19 | public PacketOpenSessionChannel(int channelID, int initialWindowSize,
20 | int maxPacketSize)
21 | {
22 | this.channelID = channelID;
23 | this.initialWindowSize = initialWindowSize;
24 | this.maxPacketSize = maxPacketSize;
25 | }
26 |
27 | public PacketOpenSessionChannel(byte payload[], int off, int len) throws IOException
28 | {
29 | this.payload = new byte[len];
30 | System.arraycopy(payload, off, this.payload, 0, len);
31 |
32 | TypesReader tr = new TypesReader(payload);
33 |
34 | int packet_type = tr.readByte();
35 |
36 | if (packet_type != Packets.SSH_MSG_CHANNEL_OPEN)
37 | throw new IOException("This is not a SSH_MSG_CHANNEL_OPEN! ("
38 | + packet_type + ")");
39 |
40 | channelID = tr.readUINT32();
41 | initialWindowSize = tr.readUINT32();
42 | maxPacketSize = tr.readUINT32();
43 |
44 | if (tr.remain() != 0)
45 | throw new IOException("Padding in SSH_MSG_CHANNEL_OPEN packet!");
46 | }
47 |
48 | public byte[] getPayload()
49 | {
50 | if (payload == null)
51 | {
52 | TypesWriter tw = new TypesWriter();
53 | tw.writeByte(Packets.SSH_MSG_CHANNEL_OPEN);
54 | tw.writeString("session");
55 | tw.writeUINT32(channelID);
56 | tw.writeUINT32(initialWindowSize);
57 | tw.writeUINT32(maxPacketSize);
58 | payload = tw.getBytes();
59 | }
60 | return payload;
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketServiceAccept.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | import java.io.IOException;
5 |
6 | /**
7 | * PacketServiceAccept.
8 | *
9 | * @author Christian Plattner, plattner@trilead.com
10 | * @version $Id: PacketServiceAccept.java,v 1.2 2008/04/01 12:38:09 cplattne Exp $
11 | */
12 | public class PacketServiceAccept
13 | {
14 | byte[] payload;
15 |
16 | String serviceName;
17 |
18 | public PacketServiceAccept(String serviceName)
19 | {
20 | this.serviceName = serviceName;
21 | }
22 |
23 | public PacketServiceAccept(byte payload[], int off, int len) throws IOException
24 | {
25 | this.payload = new byte[len];
26 | System.arraycopy(payload, off, this.payload, 0, len);
27 |
28 | TypesReader tr = new TypesReader(payload, off, len);
29 |
30 | int packet_type = tr.readByte();
31 |
32 | if (packet_type != Packets.SSH_MSG_SERVICE_ACCEPT)
33 | throw new IOException("This is not a SSH_MSG_SERVICE_ACCEPT! (" + packet_type + ")");
34 |
35 | /* Be clever in case the server is not. Some servers seem to violate RFC4253 */
36 |
37 | if (tr.remain() > 0)
38 | {
39 | serviceName = tr.readString();
40 | }
41 | else
42 | {
43 | serviceName = "";
44 | }
45 |
46 | if (tr.remain() != 0)
47 | throw new IOException("Padding in SSH_MSG_SERVICE_ACCEPT packet!");
48 | }
49 |
50 | public byte[] getPayload()
51 | {
52 | if (payload == null)
53 | {
54 | TypesWriter tw = new TypesWriter();
55 | tw.writeByte(Packets.SSH_MSG_SERVICE_ACCEPT);
56 | tw.writeString(serviceName);
57 | payload = tw.getBytes();
58 | }
59 | return payload;
60 | }
61 | }
62 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketServiceRequest.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | import java.io.IOException;
4 |
5 | /**
6 | * PacketServiceRequest.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: PacketServiceRequest.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
10 | */
11 | public class PacketServiceRequest
12 | {
13 | byte[] payload;
14 |
15 | String serviceName;
16 |
17 | public PacketServiceRequest(String serviceName)
18 | {
19 | this.serviceName = serviceName;
20 | }
21 |
22 | public PacketServiceRequest(byte payload[], int off, int len) throws IOException
23 | {
24 | this.payload = new byte[len];
25 | System.arraycopy(payload, off, this.payload, 0, len);
26 |
27 | TypesReader tr = new TypesReader(payload, off, len);
28 |
29 | int packet_type = tr.readByte();
30 |
31 | if (packet_type != Packets.SSH_MSG_SERVICE_REQUEST)
32 | throw new IOException("This is not a SSH_MSG_SERVICE_REQUEST! ("
33 | + packet_type + ")");
34 |
35 | serviceName = tr.readString();
36 |
37 | if (tr.remain() != 0)
38 | throw new IOException("Padding in SSH_MSG_SERVICE_REQUEST packet!");
39 | }
40 |
41 | public byte[] getPayload()
42 | {
43 | if (payload == null)
44 | {
45 | TypesWriter tw = new TypesWriter();
46 | tw.writeByte(Packets.SSH_MSG_SERVICE_REQUEST);
47 | tw.writeString(serviceName);
48 | payload = tw.getBytes();
49 | }
50 | return payload;
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketSessionExecCommand.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 |
4 | /**
5 | * PacketSessionExecCommand.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: PacketSessionExecCommand.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
9 | */
10 | public class PacketSessionExecCommand
11 | {
12 | byte[] payload;
13 |
14 | public int recipientChannelID;
15 | public boolean wantReply;
16 | public String command;
17 |
18 | public PacketSessionExecCommand(int recipientChannelID, boolean wantReply, String command)
19 | {
20 | this.recipientChannelID = recipientChannelID;
21 | this.wantReply = wantReply;
22 | this.command = command;
23 | }
24 |
25 | public byte[] getPayload()
26 | {
27 | if (payload == null)
28 | {
29 | TypesWriter tw = new TypesWriter();
30 | tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
31 | tw.writeUINT32(recipientChannelID);
32 | tw.writeString("exec");
33 | tw.writeBoolean(wantReply);
34 | tw.writeString(command);
35 | payload = tw.getBytes();
36 | }
37 | return payload;
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketSessionPtyRequest.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 |
4 | /**
5 | * PacketSessionPtyRequest.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: PacketSessionPtyRequest.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
9 | */
10 | public class PacketSessionPtyRequest
11 | {
12 | byte[] payload;
13 |
14 | public int recipientChannelID;
15 | public boolean wantReply;
16 | public String term;
17 | public int character_width;
18 | public int character_height;
19 | public int pixel_width;
20 | public int pixel_height;
21 | public byte[] terminal_modes;
22 |
23 | public PacketSessionPtyRequest(int recipientChannelID, boolean wantReply, String term,
24 | int character_width, int character_height, int pixel_width, int pixel_height,
25 | byte[] terminal_modes)
26 | {
27 | this.recipientChannelID = recipientChannelID;
28 | this.wantReply = wantReply;
29 | this.term = term;
30 | this.character_width = character_width;
31 | this.character_height = character_height;
32 | this.pixel_width = pixel_width;
33 | this.pixel_height = pixel_height;
34 | this.terminal_modes = terminal_modes;
35 | }
36 |
37 | public byte[] getPayload()
38 | {
39 | if (payload == null)
40 | {
41 | TypesWriter tw = new TypesWriter();
42 | tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
43 | tw.writeUINT32(recipientChannelID);
44 | tw.writeString("pty-req");
45 | tw.writeBoolean(wantReply);
46 | tw.writeString(term);
47 | tw.writeUINT32(character_width);
48 | tw.writeUINT32(character_height);
49 | tw.writeUINT32(pixel_width);
50 | tw.writeUINT32(pixel_height);
51 | tw.writeString(terminal_modes, 0, terminal_modes.length);
52 |
53 | payload = tw.getBytes();
54 | }
55 | return payload;
56 | }
57 | }
58 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketSessionStartShell.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | /**
5 | * PacketSessionStartShell.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: PacketSessionStartShell.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
9 | */
10 | public class PacketSessionStartShell
11 | {
12 | byte[] payload;
13 |
14 | public int recipientChannelID;
15 | public boolean wantReply;
16 |
17 | public PacketSessionStartShell(int recipientChannelID, boolean wantReply)
18 | {
19 | this.recipientChannelID = recipientChannelID;
20 | this.wantReply = wantReply;
21 | }
22 |
23 | public byte[] getPayload()
24 | {
25 | if (payload == null)
26 | {
27 | TypesWriter tw = new TypesWriter();
28 | tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
29 | tw.writeUINT32(recipientChannelID);
30 | tw.writeString("shell");
31 | tw.writeBoolean(wantReply);
32 | payload = tw.getBytes();
33 | }
34 | return payload;
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketSessionSubsystemRequest.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 |
4 | /**
5 | * PacketSessionSubsystemRequest.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: PacketSessionSubsystemRequest.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
9 | */
10 | public class PacketSessionSubsystemRequest
11 | {
12 | byte[] payload;
13 |
14 | public int recipientChannelID;
15 | public boolean wantReply;
16 | public String subsystem;
17 |
18 | public PacketSessionSubsystemRequest(int recipientChannelID, boolean wantReply, String subsystem)
19 | {
20 | this.recipientChannelID = recipientChannelID;
21 | this.wantReply = wantReply;
22 | this.subsystem = subsystem;
23 | }
24 |
25 | public byte[] getPayload()
26 | {
27 | if (payload == null)
28 | {
29 | TypesWriter tw = new TypesWriter();
30 | tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
31 | tw.writeUINT32(recipientChannelID);
32 | tw.writeString("subsystem");
33 | tw.writeBoolean(wantReply);
34 | tw.writeString(subsystem);
35 | payload = tw.getBytes();
36 | tw.getBytes(payload);
37 | }
38 | return payload;
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketSessionX11Request.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | /**
5 | * PacketSessionX11Request.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: PacketSessionX11Request.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
9 | */
10 | public class PacketSessionX11Request
11 | {
12 | byte[] payload;
13 |
14 | public int recipientChannelID;
15 | public boolean wantReply;
16 |
17 | public boolean singleConnection;
18 | String x11AuthenticationProtocol;
19 | String x11AuthenticationCookie;
20 | int x11ScreenNumber;
21 |
22 | public PacketSessionX11Request(int recipientChannelID, boolean wantReply, boolean singleConnection,
23 | String x11AuthenticationProtocol, String x11AuthenticationCookie, int x11ScreenNumber)
24 | {
25 | this.recipientChannelID = recipientChannelID;
26 | this.wantReply = wantReply;
27 |
28 | this.singleConnection = singleConnection;
29 | this.x11AuthenticationProtocol = x11AuthenticationProtocol;
30 | this.x11AuthenticationCookie = x11AuthenticationCookie;
31 | this.x11ScreenNumber = x11ScreenNumber;
32 | }
33 |
34 | public byte[] getPayload()
35 | {
36 | if (payload == null)
37 | {
38 | TypesWriter tw = new TypesWriter();
39 | tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
40 | tw.writeUINT32(recipientChannelID);
41 | tw.writeString("x11-req");
42 | tw.writeBoolean(wantReply);
43 |
44 | tw.writeBoolean(singleConnection);
45 | tw.writeString(x11AuthenticationProtocol);
46 | tw.writeString(x11AuthenticationCookie);
47 | tw.writeUINT32(x11ScreenNumber);
48 |
49 | payload = tw.getBytes();
50 | }
51 | return payload;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketSignal.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | import java.util.HashMap;
4 | import java.util.Map;
5 |
6 | /**
7 | * Delivers a signal from client to server.
8 | *
9 | * See section 6.9 of RFC 4254.
10 | *
11 | * @author Kohsuke Kawaguchi
12 | */
13 | public class PacketSignal {
14 | byte[] payload;
15 |
16 | public int recipientChannelID;
17 | public String signalName;
18 |
19 | public PacketSignal(int recipientChannelID, String signalName) {
20 | this.recipientChannelID = recipientChannelID;
21 |
22 | if (signalName.startsWith("SIG")) signalName=signalName.substring(3);
23 | this.signalName = signalName;
24 | }
25 |
26 | public byte[] getPayload()
27 | {
28 | if (payload == null)
29 | {
30 | TypesWriter tw = new TypesWriter();
31 | tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
32 | tw.writeUINT32(recipientChannelID);
33 | tw.writeString("signal");
34 | tw.writeBoolean(false);
35 | tw.writeString(signalName);
36 |
37 | payload = tw.getBytes();
38 | }
39 | return payload;
40 | }
41 |
42 | private static final Map SIGNALS = new HashMap();
43 |
44 | public static String strsignal(int i) {
45 | return SIGNALS.get(i);
46 | }
47 |
48 | static {
49 | SIGNALS.put(14,"ALRM");
50 | SIGNALS.put( 1,"HUP");
51 | SIGNALS.put( 2,"INT");
52 | SIGNALS.put( 9,"KILL");
53 | SIGNALS.put(13,"PIPE");
54 | SIGNALS.put(15,"TERM");
55 | SIGNALS.put( 6,"ABRT");
56 | SIGNALS.put( 8,"FPE");
57 | SIGNALS.put( 4,"ILL");
58 | SIGNALS.put( 3,"QUIT");
59 | SIGNALS.put(11,"SEGV");
60 | SIGNALS.put( 5,"TRAP");
61 | }
62 | }
63 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketUserauthBanner.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | import java.io.IOException;
4 |
5 | /**
6 | * PacketUserauthBanner.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: PacketUserauthBanner.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
10 | */
11 | public class PacketUserauthBanner
12 | {
13 | byte[] payload;
14 |
15 | String message;
16 | String language;
17 |
18 | public PacketUserauthBanner(String message, String language)
19 | {
20 | this.message = message;
21 | this.language = language;
22 | }
23 |
24 | public String getBanner()
25 | {
26 | return message;
27 | }
28 |
29 | public PacketUserauthBanner(byte payload[], int off, int len) throws IOException
30 | {
31 | this.payload = new byte[len];
32 | System.arraycopy(payload, off, this.payload, 0, len);
33 |
34 | TypesReader tr = new TypesReader(payload, off, len);
35 |
36 | int packet_type = tr.readByte();
37 |
38 | if (packet_type != Packets.SSH_MSG_USERAUTH_BANNER)
39 | throw new IOException("This is not a SSH_MSG_USERAUTH_BANNER! (" + packet_type + ")");
40 |
41 | message = tr.readString("UTF-8");
42 | language = tr.readString();
43 |
44 | if (tr.remain() != 0)
45 | throw new IOException("Padding in SSH_MSG_USERAUTH_REQUEST packet!");
46 | }
47 |
48 | public byte[] getPayload()
49 | {
50 | if (payload == null)
51 | {
52 | TypesWriter tw = new TypesWriter();
53 | tw.writeByte(Packets.SSH_MSG_USERAUTH_BANNER);
54 | tw.writeString(message);
55 | tw.writeString(language);
56 | payload = tw.getBytes();
57 | }
58 | return payload;
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketUserauthFailure.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | import java.io.IOException;
5 |
6 | /**
7 | * PacketUserauthBanner.
8 | *
9 | * @author Christian Plattner, plattner@trilead.com
10 | * @version $Id: PacketUserauthFailure.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
11 | */
12 | public class PacketUserauthFailure
13 | {
14 | byte[] payload;
15 |
16 | String[] authThatCanContinue;
17 | boolean partialSuccess;
18 |
19 | public PacketUserauthFailure(String[] authThatCanContinue, boolean partialSuccess)
20 | {
21 | this.authThatCanContinue = authThatCanContinue;
22 | this.partialSuccess = partialSuccess;
23 | }
24 |
25 | public PacketUserauthFailure(byte payload[], int off, int len) throws IOException
26 | {
27 | this.payload = new byte[len];
28 | System.arraycopy(payload, off, this.payload, 0, len);
29 |
30 | TypesReader tr = new TypesReader(payload, off, len);
31 |
32 | int packet_type = tr.readByte();
33 |
34 | if (packet_type != Packets.SSH_MSG_USERAUTH_FAILURE)
35 | throw new IOException("This is not a SSH_MSG_USERAUTH_FAILURE! (" + packet_type + ")");
36 |
37 | authThatCanContinue = tr.readNameList();
38 | partialSuccess = tr.readBoolean();
39 |
40 | if (tr.remain() != 0)
41 | throw new IOException("Padding in SSH_MSG_USERAUTH_FAILURE packet!");
42 | }
43 |
44 | public String[] getAuthThatCanContinue()
45 | {
46 | return authThatCanContinue;
47 | }
48 |
49 | public boolean isPartialSuccess()
50 | {
51 | return partialSuccess;
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketUserauthInfoRequest.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | import java.io.IOException;
5 |
6 | /**
7 | * PacketUserauthInfoRequest.
8 | *
9 | * @author Christian Plattner, plattner@trilead.com
10 | * @version $Id: PacketUserauthInfoRequest.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
11 | */
12 | public class PacketUserauthInfoRequest
13 | {
14 | byte[] payload;
15 |
16 | String name;
17 | String instruction;
18 | String languageTag;
19 | int numPrompts;
20 |
21 | String prompt[];
22 | boolean echo[];
23 |
24 | public PacketUserauthInfoRequest(byte payload[], int off, int len) throws IOException
25 | {
26 | this.payload = new byte[len];
27 | System.arraycopy(payload, off, this.payload, 0, len);
28 |
29 | TypesReader tr = new TypesReader(payload, off, len);
30 |
31 | int packet_type = tr.readByte();
32 |
33 | if (packet_type != Packets.SSH_MSG_USERAUTH_INFO_REQUEST)
34 | throw new IOException("This is not a SSH_MSG_USERAUTH_INFO_REQUEST! (" + packet_type + ")");
35 |
36 | name = tr.readString();
37 | instruction = tr.readString();
38 | languageTag = tr.readString();
39 |
40 | numPrompts = tr.readUINT32();
41 |
42 | prompt = new String[numPrompts];
43 | echo = new boolean[numPrompts];
44 |
45 | for (int i = 0; i < numPrompts; i++)
46 | {
47 | prompt[i] = tr.readString();
48 | echo[i] = tr.readBoolean();
49 | }
50 |
51 | if (tr.remain() != 0)
52 | throw new IOException("Padding in SSH_MSG_USERAUTH_INFO_REQUEST packet!");
53 | }
54 |
55 | public boolean[] getEcho()
56 | {
57 | return echo;
58 | }
59 |
60 | public String getInstruction()
61 | {
62 | return instruction;
63 | }
64 |
65 | public String getLanguageTag()
66 | {
67 | return languageTag;
68 | }
69 |
70 | public String getName()
71 | {
72 | return name;
73 | }
74 |
75 | public int getNumPrompts()
76 | {
77 | return numPrompts;
78 | }
79 |
80 | public String[] getPrompt()
81 | {
82 | return prompt;
83 | }
84 | }
85 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketUserauthInfoResponse.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.packets;
3 |
4 | /**
5 | * PacketUserauthInfoResponse.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: PacketUserauthInfoResponse.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
9 | */
10 | public class PacketUserauthInfoResponse
11 | {
12 | byte[] payload;
13 |
14 | String[] responses;
15 |
16 | public PacketUserauthInfoResponse(String[] responses)
17 | {
18 | this.responses = responses;
19 | }
20 |
21 | public byte[] getPayload()
22 | {
23 | if (payload == null)
24 | {
25 | TypesWriter tw = new TypesWriter();
26 | tw.writeByte(Packets.SSH_MSG_USERAUTH_INFO_RESPONSE);
27 | tw.writeUINT32(responses.length);
28 | for (int i = 0; i < responses.length; i++)
29 | tw.writeString(responses[i]);
30 |
31 | payload = tw.getBytes();
32 | }
33 | return payload;
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketUserauthRequestGssapiWithMic.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | public class PacketUserauthRequestGssapiWithMic {
4 |
5 | private static final String GSSAPI_WITH_MIC = "gssapi-with-mic";
6 |
7 | private static final String SSH_CONNECTION = "ssh-connection";
8 |
9 | byte[][] supported_oid={
10 | // OID 1.2.840.113554.1.2.2 in DER
11 | {(byte)0x6,(byte)0x9,(byte)0x2a,(byte)0x86,(byte)0x48,
12 | (byte)0x86,(byte)0xf7,(byte)0x12,(byte)0x1,(byte)0x2,
13 | (byte)0x2}
14 | };
15 |
16 | byte[] payload;
17 |
18 | private String user;
19 |
20 | public PacketUserauthRequestGssapiWithMic(String user)
21 | {
22 | this.user = user;
23 | }
24 |
25 | public byte[] getPayload()
26 | {
27 | if (payload == null)
28 | {
29 | TypesWriter tw = new TypesWriter();
30 | tw.writeByte(Packets.SSH_MSG_USERAUTH_REQUEST);
31 | tw.writeString(user);
32 | tw.writeString(SSH_CONNECTION);
33 | tw.writeString(GSSAPI_WITH_MIC);
34 | tw.writeUINT32(supported_oid.length);
35 | for(int i=0; i 1) //take the first generated token and send it to the server
53 | break;
54 | } catch (GSSException | SecurityException e)
55 | {
56 | if (LOGGER.isEnabled()) {
57 | LOGGER.log(50, "Could not get token", e);
58 | }
59 | }
60 | }
61 |
62 | TypesWriter tw = new TypesWriter();
63 | tw.writeByte(Packets.SSH_MSG_USERAUTH_INFO_RESPONSE);
64 | tw.writeString(token,0,token.length);
65 | payload = tw.getBytes();
66 | }
67 | return payload;
68 | }
69 |
70 | public byte[] getMicPayload(byte[] sessionIdentifier) {
71 |
72 | payload = null;
73 |
74 | TypesWriter tw = new TypesWriter();
75 |
76 | tw.writeString(sessionIdentifier, 0, sessionIdentifier.length);
77 | tw.writeByte(Packets.SSH_MSG_USERAUTH_REQUEST);
78 | tw.writeString(user);
79 | tw.writeString(SSH_CONNECTION);
80 | tw.writeString(GSSAPI_WITH_MIC);
81 |
82 | byte[] message = tw.getBytes();
83 | byte[] mic;
84 | try
85 | {
86 | mic = context.getMIC(message, 0, message.length);
87 | } catch (GSSException e)
88 | {
89 | if (LOGGER.isEnabled()) {
90 | LOGGER.log(50, "Could not get MIC", e);
91 | }
92 | mic = null;
93 | }
94 |
95 | if(mic==null)
96 | {
97 | return null;
98 | }
99 |
100 | tw = new TypesWriter();
101 | tw.writeByte(Packets.SSH_MSG_USERAUTH_GSSAPI_MIC);
102 | tw.writeString(mic, 0, mic.length);
103 |
104 | payload = tw.getBytes();
105 |
106 | return payload;
107 | }
108 |
109 | }
110 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/packets/PacketWindowChange.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.packets;
2 |
3 | /**
4 | * Indicates that that size of the terminal (window) size has changed on the client side.
5 | *
6 | * See section 6.7 of RFC 4254.
7 | *
8 | * @author Kohsuke Kawaguchi
9 | */
10 | public class PacketWindowChange {
11 | byte[] payload;
12 |
13 | public int recipientChannelID;
14 | public int character_width;
15 | public int character_height;
16 | public int pixel_width;
17 | public int pixel_height;
18 |
19 | public PacketWindowChange(int recipientChannelID,
20 | int character_width, int character_height, int pixel_width, int pixel_height)
21 | {
22 | this.recipientChannelID = recipientChannelID;
23 | this.character_width = character_width;
24 | this.character_height = character_height;
25 | this.pixel_width = pixel_width;
26 | this.pixel_height = pixel_height;
27 | }
28 |
29 | public byte[] getPayload()
30 | {
31 | if (payload == null)
32 | {
33 | TypesWriter tw = new TypesWriter();
34 | tw.writeByte(Packets.SSH_MSG_CHANNEL_REQUEST);
35 | tw.writeUINT32(recipientChannelID);
36 | tw.writeString("window-change");
37 | tw.writeBoolean(false);
38 | tw.writeUINT32(character_width);
39 | tw.writeUINT32(character_height);
40 | tw.writeUINT32(pixel_width);
41 | tw.writeUINT32(pixel_height);
42 |
43 | payload = tw.getBytes();
44 | }
45 | return payload;
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/sftp/AttrTextHints.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.sftp;
3 |
4 | /**
5 | *
6 | * Values for the 'text-hint' field in the SFTP ATTRS data type.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: AttrTextHints.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
10 | *
11 | */
12 | public class AttrTextHints
13 | {
14 | /**
15 | * The server knows the file is a text file, and should be opened
16 | * using the SSH_FXF_ACCESS_TEXT_MODE flag.
17 | */
18 | public static final int SSH_FILEXFER_ATTR_KNOWN_TEXT = 0x00;
19 |
20 | /**
21 | * The server has applied a heuristic or other mechanism and
22 | * believes that the file should be opened with the
23 | * SSH_FXF_ACCESS_TEXT_MODE flag.
24 | */
25 | public static final int SSH_FILEXFER_ATTR_GUESSED_TEXT = 0x01;
26 |
27 | /**
28 | * The server knows the file has binary content.
29 | */
30 | public static final int SSH_FILEXFER_ATTR_KNOWN_BINARY = 0x02;
31 |
32 | /**
33 | * The server has applied a heuristic or other mechanism and
34 | * believes has binary content, and should not be opened with the
35 | * SSH_FXF_ACCESS_TEXT_MODE flag.
36 | */
37 | public static final int SSH_FILEXFER_ATTR_GUESSED_BINARY = 0x03;
38 | }
39 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/sftp/AttribPermissions.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.sftp;
3 |
4 | /**
5 | *
6 | * Permissions for the 'permissions' field in the SFTP ATTRS data type.
7 | *
8 | * "The 'permissions' field contains a bit mask specifying file permissions.
9 | * These permissions correspond to the st_mode field of the stat structure
10 | * defined by POSIX [IEEE.1003-1.1996]."
11 | *
12 | * @author Christian Plattner, plattner@trilead.com
13 | * @version $Id: AttribPermissions.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
14 | *
15 | */
16 | public class AttribPermissions
17 | {
18 | /* Octal values! */
19 |
20 | public static final int S_IRUSR = 0400;
21 | public static final int S_IWUSR = 0200;
22 | public static final int S_IXUSR = 0100;
23 | public static final int S_IRGRP = 0040;
24 | public static final int S_IWGRP = 0020;
25 | public static final int S_IXGRP = 0010;
26 | public static final int S_IROTH = 0004;
27 | public static final int S_IWOTH = 0002;
28 | public static final int S_IXOTH = 0001;
29 | public static final int S_ISUID = 04000;
30 | public static final int S_ISGID = 02000;
31 | public static final int S_ISVTX = 01000;
32 | }
33 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/sftp/AttribTypes.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.sftp;
3 |
4 | /**
5 | *
6 | * Types for the 'type' field in the SFTP ATTRS data type.
7 | *
8 | * "On a POSIX system, these values would be derived from the mode field
9 | * of the stat structure. SPECIAL should be used for files that are of
10 | * a known type which cannot be expressed in the protocol. UNKNOWN
11 | * should be used if the type is not known."
12 | *
13 | * @author Christian Plattner, plattner@trilead.com
14 | * @version $Id: AttribTypes.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
15 | *
16 | */
17 | public class AttribTypes
18 | {
19 | public static final int SSH_FILEXFER_TYPE_REGULAR = 1;
20 | public static final int SSH_FILEXFER_TYPE_DIRECTORY = 2;
21 | public static final int SSH_FILEXFER_TYPE_SYMLINK = 3;
22 | public static final int SSH_FILEXFER_TYPE_SPECIAL = 4;
23 | public static final int SSH_FILEXFER_TYPE_UNKNOWN = 5;
24 | public static final int SSH_FILEXFER_TYPE_SOCKET = 6;
25 | public static final int SSH_FILEXFER_TYPE_CHAR_DEVICE = 7;
26 | public static final int SSH_FILEXFER_TYPE_BLOCK_DEVICE = 8;
27 | public static final int SSH_FILEXFER_TYPE_FIFO = 9;
28 | }
29 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/sftp/Packet.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.sftp;
3 |
4 | /**
5 | *
6 | * SFTP Paket Types
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: Packet.java,v 1.1 2007/10/15 12:49:55 cplattne Exp $
10 | *
11 | */
12 | public class Packet
13 | {
14 | public static final int SSH_FXP_INIT = 1;
15 | public static final int SSH_FXP_VERSION = 2;
16 | public static final int SSH_FXP_OPEN = 3;
17 | public static final int SSH_FXP_CLOSE = 4;
18 | public static final int SSH_FXP_READ = 5;
19 | public static final int SSH_FXP_WRITE = 6;
20 | public static final int SSH_FXP_LSTAT = 7;
21 | public static final int SSH_FXP_FSTAT = 8;
22 | public static final int SSH_FXP_SETSTAT = 9;
23 | public static final int SSH_FXP_FSETSTAT = 10;
24 | public static final int SSH_FXP_OPENDIR = 11;
25 | public static final int SSH_FXP_READDIR = 12;
26 | public static final int SSH_FXP_REMOVE = 13;
27 | public static final int SSH_FXP_MKDIR = 14;
28 | public static final int SSH_FXP_RMDIR = 15;
29 | public static final int SSH_FXP_REALPATH = 16;
30 | public static final int SSH_FXP_STAT = 17;
31 | public static final int SSH_FXP_RENAME = 18;
32 | public static final int SSH_FXP_READLINK = 19;
33 | public static final int SSH_FXP_SYMLINK = 20;
34 |
35 | public static final int SSH_FXP_STATUS = 101;
36 | public static final int SSH_FXP_HANDLE = 102;
37 | public static final int SSH_FXP_DATA = 103;
38 | public static final int SSH_FXP_NAME = 104;
39 | public static final int SSH_FXP_ATTRS = 105;
40 |
41 | public static final int SSH_FXP_EXTENDED = 200;
42 | public static final int SSH_FXP_EXTENDED_REPLY = 201;
43 | }
44 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/signature/DSAPrivateKey.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.signature;
2 |
3 | import java.math.BigInteger;
4 |
5 | /**
6 | * DSAPrivateKey.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: DSAPrivateKey.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
10 | * @deprecated use {@link java.security.interfaces.DSAPrivateKey}
11 | * @see java.security.interfaces.DSAPrivateKey
12 | */
13 | @Deprecated
14 | public class DSAPrivateKey
15 | {
16 | private BigInteger p;
17 | private BigInteger q;
18 | private BigInteger g;
19 | private BigInteger x;
20 | private BigInteger y;
21 |
22 | public DSAPrivateKey(BigInteger p, BigInteger q, BigInteger g,
23 | BigInteger y, BigInteger x)
24 | {
25 | this.p = p;
26 | this.q = q;
27 | this.g = g;
28 | this.y = y;
29 | this.x = x;
30 | }
31 |
32 | public BigInteger getP()
33 | {
34 | return p;
35 | }
36 |
37 | public BigInteger getQ()
38 | {
39 | return q;
40 | }
41 |
42 | public BigInteger getG()
43 | {
44 | return g;
45 | }
46 |
47 | public BigInteger getY()
48 | {
49 | return y;
50 | }
51 |
52 | public BigInteger getX()
53 | {
54 | return x;
55 | }
56 |
57 | public DSAPublicKey getPublicKey()
58 | {
59 | return new DSAPublicKey(p, q, g, y);
60 | }
61 | }
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/signature/DSAPublicKey.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.signature;
2 |
3 | import java.math.BigInteger;
4 |
5 | /**
6 | * DSAPublicKey.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: DSAPublicKey.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
10 | * @deprecated use {@link java.security.interfaces.DSAPublicKey}
11 | * @see java.security.interfaces.DSAPublicKey
12 | */
13 | public class DSAPublicKey
14 | {
15 | private BigInteger p;
16 | private BigInteger q;
17 | private BigInteger g;
18 | private BigInteger y;
19 |
20 | public DSAPublicKey(BigInteger p, BigInteger q, BigInteger g, BigInteger y)
21 | {
22 | this.p = p;
23 | this.q = q;
24 | this.g = g;
25 | this.y = y;
26 | }
27 |
28 | public BigInteger getP()
29 | {
30 | return p;
31 | }
32 |
33 | public BigInteger getQ()
34 | {
35 | return q;
36 | }
37 |
38 | public BigInteger getG()
39 | {
40 | return g;
41 | }
42 |
43 | public BigInteger getY()
44 | {
45 | return y;
46 | }
47 | }
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/signature/DSASignature.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.signature;
2 |
3 | import java.math.BigInteger;
4 |
5 | /**
6 | * DSASignature.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: DSASignature.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
10 | * @deprecated signatures are now stored in ray byte[] form.
11 | */
12 | @Deprecated
13 | public class DSASignature
14 | {
15 | private BigInteger r;
16 | private BigInteger s;
17 |
18 | public DSASignature(BigInteger r, BigInteger s)
19 | {
20 | this.r = r;
21 | this.s = s;
22 | }
23 |
24 | public BigInteger getR()
25 | {
26 | return r;
27 | }
28 |
29 | public BigInteger getS()
30 | {
31 | return s;
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/signature/KeyAlgorithm.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.signature;
2 |
3 | import com.trilead.ssh2.crypto.CertificateDecoder;
4 |
5 | import java.io.IOException;
6 | import java.security.GeneralSecurityException;
7 | import java.security.PrivateKey;
8 | import java.security.Provider;
9 | import java.security.PublicKey;
10 | import java.security.SecureRandom;
11 | import java.security.Signature;
12 | import java.util.List;
13 |
14 | /**
15 | * @author Michael Clarke
16 | */
17 | public abstract class KeyAlgorithm {
18 |
19 | private final String signatureAlgorithm;
20 | private final String keyFormat;
21 | private final Class keyType;
22 | private final Provider provider;
23 |
24 | protected KeyAlgorithm(String signatureAlgorithm, String keyFormat, Class keyType) {
25 | this(signatureAlgorithm, keyFormat, keyType, null);
26 | }
27 |
28 | protected KeyAlgorithm(String signatureAlgorithm, String keyFormat, Class keyType, Provider provider) {
29 | super();
30 | this.signatureAlgorithm = signatureAlgorithm;
31 | this.keyFormat = keyFormat;
32 | this.keyType = keyType;
33 | this.provider = provider;
34 | }
35 |
36 | public byte[] generateSignature(byte[] message, R pk, SecureRandom rnd) throws IOException {
37 | try {
38 | Signature signature = (null == provider ? Signature.getInstance(signatureAlgorithm) : Signature.getInstance(signatureAlgorithm, provider));
39 | signature.initSign(pk, rnd);
40 | signature.update(message);
41 | return signature.sign();
42 | } catch (GeneralSecurityException ex) {
43 | throw new IOException("Could not generate signature", ex);
44 | }
45 | }
46 |
47 | public boolean verifySignature(byte[] message, byte[] ds, U dpk) throws IOException {
48 | try {
49 | Signature signature = (null == provider ? Signature.getInstance(signatureAlgorithm) : Signature.getInstance(signatureAlgorithm, provider));
50 | signature.initVerify(dpk);
51 | signature.update(message);
52 | return signature.verify(ds);
53 | } catch (GeneralSecurityException ex) {
54 | throw new IOException("Could not verify signature", ex);
55 | }
56 | }
57 |
58 | public String getKeyFormat() {
59 | return keyFormat;
60 | }
61 |
62 | public abstract byte[] encodeSignature(byte[] signature) throws IOException;
63 |
64 | public abstract byte[] decodeSignature(byte[] encodedSignature) throws IOException;
65 |
66 | public abstract byte[] encodePublicKey(U publicKey) throws IOException;
67 |
68 | public abstract PublicKey decodePublicKey(byte[] encodedPublicKey) throws IOException;
69 |
70 | public abstract List getCertificateDecoders();
71 |
72 | public boolean supportsKey(PrivateKey key) {
73 | return keyType.isAssignableFrom(key.getClass());
74 | }
75 |
76 |
77 |
78 | }
79 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/signature/KeyAlgorithmManager.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.signature;
2 |
3 | import java.security.GeneralSecurityException;
4 | import java.security.KeyFactory;
5 | import java.security.PrivateKey;
6 | import java.security.PublicKey;
7 | import java.util.ArrayList;
8 | import java.util.Collection;
9 | import java.util.Collections;
10 | import java.util.List;
11 |
12 | /**
13 | * @author Michael Clarke
14 | */
15 | public final class KeyAlgorithmManager {
16 |
17 | private static final Collection> supportedAlgorithms = buildSupportAlgorithmsList();
18 |
19 | private KeyAlgorithmManager() {
20 | super();
21 | // static access only
22 | }
23 |
24 | public static Collection> getSupportedAlgorithms() {
25 | return supportedAlgorithms;
26 | }
27 |
28 | private static Collection> buildSupportAlgorithmsList() {
29 | List> algorithms = new ArrayList<>();
30 | algorithms.add(new ED25519KeyAlgorithm());
31 |
32 | try {
33 | KeyFactory.getInstance("EC");
34 | algorithms.add(new ECDSAKeyAlgorithm.ECDSASha2Nistp521());
35 | algorithms.add(new ECDSAKeyAlgorithm.ECDSASha2Nistp384());
36 | algorithms.add(new ECDSAKeyAlgorithm.ECDSASha2Nistp256());
37 | } catch (GeneralSecurityException ex) {
38 | // we don't use ECDSA algorithms in this case
39 | }
40 | // https://tools.ietf.org/html/rfc8332
41 | algorithms.add(new RSAKeyAlgorithm("SHA256withRSA", "rsa-sha2-256"));
42 | algorithms.add(new RSAKeyAlgorithm("SHA512withRSA", "rsa-sha2-512"));
43 |
44 |
45 | // TODO: remove SHA-1 support soon
46 | algorithms.add(new RSAKeyAlgorithm());
47 | algorithms.add(new DSAKeyAlgorithm());
48 |
49 | return (Collection) Collections.unmodifiableCollection(algorithms);
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/signature/RSAPrivateKey.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.signature;
2 |
3 | import java.math.BigInteger;
4 | import java.security.KeyPair;
5 | import java.security.KeyFactory;
6 | import java.security.NoSuchAlgorithmException;
7 | import java.security.GeneralSecurityException;
8 | import java.security.spec.RSAPublicKeySpec;
9 | import java.security.spec.RSAPrivateKeySpec;
10 | import java.security.spec.InvalidKeySpecException;
11 |
12 | /**
13 | * RSAPrivateKey.
14 | *
15 | * @author Christian Plattner, plattner@trilead.com
16 | * @version $Id: RSAPrivateKey.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
17 | * @deprecated use {@link java.security.interfaces.RSAPrivateKey}
18 | * @see java.security.interfaces.RSAPrivateKey
19 | */
20 | public class RSAPrivateKey
21 | {
22 | private BigInteger d;
23 | private BigInteger e;
24 | private BigInteger n;
25 |
26 | public RSAPrivateKey(BigInteger d, BigInteger e, BigInteger n)
27 | {
28 | this.d = d;
29 | this.e = e;
30 | this.n = n;
31 | }
32 |
33 | public BigInteger getD()
34 | {
35 | return d;
36 | }
37 |
38 | public BigInteger getE()
39 | {
40 | return e;
41 | }
42 |
43 | public BigInteger getN()
44 | {
45 | return n;
46 | }
47 |
48 | public RSAPublicKey getPublicKey()
49 | {
50 | return new RSAPublicKey(e, n);
51 | }
52 |
53 | /**
54 | * Converts this to a JCE API representation of the RSA key pair.
55 | *
56 | * @return the key pair
57 | * @throws GeneralSecurityException the general security exception
58 | */
59 | public KeyPair toJCEKeyPair() throws GeneralSecurityException {
60 | KeyFactory kf = KeyFactory.getInstance("RSA");
61 | return new KeyPair(
62 | kf.generatePublic(new RSAPublicKeySpec(getN(), getE())),
63 | kf.generatePrivate(new RSAPrivateKeySpec(getN(), getD())));
64 | }
65 | }
66 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/signature/RSAPublicKey.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.signature;
2 |
3 | import java.math.BigInteger;
4 |
5 | /**
6 | * RSAPublicKey.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id: RSAPublicKey.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
10 | * @deprecated use {@link java.security.interfaces.RSAPublicKey}
11 | * @see java.security.interfaces.RSAPublicKey
12 | */
13 | public class RSAPublicKey
14 | {
15 | BigInteger e;
16 | BigInteger n;
17 |
18 | public RSAPublicKey(BigInteger e, BigInteger n)
19 | {
20 | this.e = e;
21 | this.n = n;
22 | }
23 |
24 | public BigInteger getE()
25 | {
26 | return e;
27 | }
28 |
29 | public BigInteger getN()
30 | {
31 | return n;
32 | }
33 | }
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/signature/RSASignature.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.signature;
3 |
4 | import java.math.BigInteger;
5 |
6 |
7 | /**
8 | * RSASignature.
9 | *
10 | * @author Christian Plattner, plattner@trilead.com
11 | * @version $Id: RSASignature.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
12 | * @deprecated signatures are now stored as raw byte arrays
13 | */
14 | @Deprecated
15 | public class RSASignature
16 | {
17 | BigInteger s;
18 |
19 | public BigInteger getS()
20 | {
21 | return s;
22 | }
23 |
24 | public RSASignature(BigInteger s)
25 | {
26 | this.s = s;
27 | }
28 | }
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/transport/Acceptor.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.transport;
2 |
3 | import java.io.IOException;
4 | import java.net.SocketTimeoutException;
5 | import java.net.Socket;
6 | import java.net.ServerSocket;
7 |
8 | import com.trilead.ssh2.Connection;
9 | import com.trilead.ssh2.ConnectionInfo;
10 | import com.trilead.ssh2.ServerHostKeyVerifier;
11 |
12 | /**
13 | * This class is similar to {@link Connection} but is
14 | * used to accept incoming connections from clients.
15 | * Example use-cases are 'NETCONF Call Home' or
16 | * 'reverse SSH'.
17 | *
18 | */
19 | public class Acceptor extends Connection{
20 |
21 | /**
22 | * Constuctor
23 | * @param hostname is the hostname that this class is running on.
24 | * @param port is the port that is used for incoming connections.
25 | */
26 | public Acceptor(String hostname,int port){
27 | super(hostname,port);
28 | }
29 | /**
30 | * This method reuses most of methods for {@link Connection#connect(ServerHostKeyVerifier, int, int, int)}. Parameters and descriptions applies here too.
31 | * The main difference between
32 | * this class and {@link Connection} is that we use {@link ServerSocket} and we bind with the port specified in constructor. The {@link ServerSocket#accept()}
33 | * will wait (blocks) for an incoming connection for max {@param connectTimeout} . If connection is completed a {@link Socket} is returned and we set a timeout of this socket using
34 | * {@param readTimeout}.
35 | *
36 | * @throws SocketTimeoutException If there is no incoming connection within {@param connectTimeout}.
37 | *
38 | */
39 | public ConnectionInfo accept(ServerHostKeyVerifier verifier, int connectTimeout, int readTimeout, int kexTimeout) throws IOException{
40 | if (tm != null) {
41 | throw new IOException("Connection to " + hostname + " is already in connected state!");
42 | }
43 | if (connectTimeout < 0)
44 | throw new IllegalArgumentException("connectTimeout must be non-negative!");
45 |
46 | if (kexTimeout < 0)
47 | throw new IllegalArgumentException("kexTimeout must be non-negative!");
48 |
49 | tm = new TransportManager(hostname, port);
50 | tm.setEnabledCallHomeSSH(true);
51 |
52 | tm.setConnectionMonitors(connectionMonitors);
53 | try {
54 | tm.initialize(cryptoWishList, verifier, dhgexpara, connectTimeout, readTimeout, getOrCreateSecureRND(),
55 | proxyData);
56 | } catch (SocketTimeoutException ste) {
57 | throw (SocketTimeoutException) new SocketTimeoutException(
58 | "The accept() operation on the socket timed out.").initCause(ste);
59 | }
60 |
61 | tm.setTcpNoDelay(tcpNoDelay);
62 |
63 | /* Wait until first KEX has finished */
64 | return tm.getConnectionInfo(1);
65 | }
66 |
67 | }
68 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/transport/KexParameters.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.transport;
2 |
3 | /**
4 | * KexParameters.
5 | *
6 | * @author Christian Plattner, plattner@trilead.com
7 | * @version $Id: KexParameters.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
8 | */
9 | public class KexParameters
10 | {
11 | public byte[] cookie;
12 | public String[] kex_algorithms;
13 | public String[] server_host_key_algorithms;
14 | public String[] encryption_algorithms_client_to_server;
15 | public String[] encryption_algorithms_server_to_client;
16 | public String[] mac_algorithms_client_to_server;
17 | public String[] mac_algorithms_server_to_client;
18 | public String[] compression_algorithms_client_to_server;
19 | public String[] compression_algorithms_server_to_client;
20 | public String[] languages_client_to_server;
21 | public String[] languages_server_to_client;
22 | public boolean first_kex_packet_follows;
23 | public int reserved_field1;
24 | }
25 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/transport/KexState.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.transport;
2 |
3 |
4 | import java.math.BigInteger;
5 |
6 | import com.trilead.ssh2.DHGexParameters;
7 | import com.trilead.ssh2.crypto.dh.DhGroupExchange;
8 | import com.trilead.ssh2.crypto.dh.GenericDhExchange;
9 | import com.trilead.ssh2.packets.PacketKexInit;
10 |
11 | /**
12 | * KexState.
13 | *
14 | * @author Christian Plattner, plattner@trilead.com
15 | * @version $Id: KexState.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
16 | */
17 | public class KexState
18 | {
19 | public PacketKexInit localKEX;
20 | public PacketKexInit remoteKEX;
21 | public NegotiatedParameters np;
22 | public int state = 0;
23 |
24 | public BigInteger K;
25 | public byte[] H;
26 |
27 | public byte[] hostkey;
28 |
29 | public GenericDhExchange dhx;
30 | public DhGroupExchange dhgx;
31 | public DHGexParameters dhgexParameters;
32 | private String hashAlgorithm;
33 |
34 | public void setHashAlgorithm(String hashAlgorithm) {
35 | this.hashAlgorithm = hashAlgorithm;
36 | }
37 |
38 | public String getHashAlgorithm() {
39 | return hashAlgorithm;
40 | }
41 | }
42 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/transport/MessageHandler.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.transport;
2 |
3 | import java.io.IOException;
4 |
5 | /**
6 | * MessageHandler.
7 | *
8 | * @author Christian Plattner, plattner@trilead.com
9 | * @version $Id : MessageHandler.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
10 | */
11 | public interface MessageHandler
12 | {
13 | /**
14 | * Handle message.
15 | *
16 | * @param msg the msg
17 | * @param msglen the msglen
18 | * @throws IOException the io exception
19 | */
20 | public void handleMessage(byte[] msg, int msglen) throws IOException;
21 |
22 | /**
23 | * Called to inform that no more messages will be delivered.
24 | *
25 | * @param cause For diagnosis, the reason that caused the transport to close down.
26 | * @throws IOException the io exception
27 | */
28 | public void handleEndMessage(Throwable cause) throws IOException;
29 | }
30 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/transport/NegotiateException.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.transport;
2 |
3 | /**
4 | * NegotiateException.
5 | *
6 | * @author Christian Plattner, plattner@trilead.com
7 | * @version $Id: NegotiateException.java,v 1.1 2007/10/15 12:49:56 cplattne Exp $
8 | */
9 | public class NegotiateException extends Exception
10 | {
11 | public NegotiateException(String message) {
12 | super(message);
13 | }
14 |
15 | private static final long serialVersionUID = 3689910669428143157L;
16 | }
17 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/transport/NegotiatedParameters.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.transport;
2 |
3 | /**
4 | * NegotiatedParameters.
5 | *
6 | * @author Christian Plattner, plattner@trilead.com
7 | * @version $Id: NegotiatedParameters.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
8 | */
9 | public class NegotiatedParameters
10 | {
11 | public boolean guessOK;
12 | public String kex_algo;
13 | public String server_host_key_algo;
14 | public String enc_algo_client_to_server;
15 | public String enc_algo_server_to_client;
16 | public String mac_algo_client_to_server;
17 | public String mac_algo_server_to_client;
18 | public String comp_algo_client_to_server;
19 | public String comp_algo_server_to_client;
20 | public String lang_client_to_server;
21 | public String lang_server_to_client;
22 | }
23 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/util/IOUtils.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.util;
2 |
3 | import java.io.Closeable;
4 | import java.io.IOException;
5 |
6 | /**
7 | * @author Kohsuke Kawaguchi
8 | */
9 | public class IOUtils {
10 | public static void closeQuietly(Closeable c) {
11 | try {
12 | c.close();
13 | } catch (IOException e) {
14 | // ignore error
15 | }
16 | }
17 | }
18 |
--------------------------------------------------------------------------------
/src/com/trilead/ssh2/util/Tokenizer.java:
--------------------------------------------------------------------------------
1 |
2 | package com.trilead.ssh2.util;
3 |
4 | /**
5 | * Tokenizer. Why? Because StringTokenizer is not available in J2ME.
6 | *
7 | * @author Christian Plattner, plattner@trilead.com
8 | * @version $Id: Tokenizer.java,v 1.1 2007/10/15 12:49:57 cplattne Exp $
9 | */
10 | public class Tokenizer
11 | {
12 | /**
13 | * Exists because StringTokenizer is not available in J2ME.
14 | * Returns an array with at least 1 entry.
15 | *
16 | * @param source must be non-null
17 | * @param delimiter delimiter
18 | * @return an array of Strings
19 | */
20 | public static String[] parseTokens(String source, char delimiter)
21 | {
22 | int numtoken = 1;
23 |
24 | for (int i = 0; i < source.length(); i++)
25 | {
26 | if (source.charAt(i) == delimiter)
27 | numtoken++;
28 | }
29 |
30 | String list[] = new String[numtoken];
31 | int nextfield = 0;
32 |
33 | for (int i = 0; i < numtoken; i++)
34 | {
35 | if (nextfield >= source.length())
36 | {
37 | list[i] = "";
38 | }
39 | else
40 | {
41 | int idx = source.indexOf(delimiter, nextfield);
42 | if (idx == -1)
43 | idx = source.length();
44 | list[i] = source.substring(nextfield, idx);
45 | nextfield = idx + 1;
46 | }
47 | }
48 |
49 | return list;
50 | }
51 | }
52 |
--------------------------------------------------------------------------------
/src/spotbugs/excludesFilter.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
--------------------------------------------------------------------------------
/test/Receiver.java:
--------------------------------------------------------------------------------
1 | import com.trilead.ssh2.Connection;
2 | import com.trilead.ssh2.Session;
3 | import com.trilead.ssh2.channel.ConnectionRule;
4 |
5 | import java.io.DataInputStream;
6 | import java.util.concurrent.TimeUnit;
7 |
8 | /**
9 | * Test the throughput of the data retrieval.
10 | *
11 | * @author Kohsuke Kawaguchi
12 | */
13 | public class Receiver {
14 | public static void main(String[] args) throws Exception {
15 | Connection connection = new ConnectionRule().getConnection();
16 | final Session session = connection.openSession();
17 |
18 | session.execCommand("cat /dev/zero");
19 | session.getStdin().close();
20 | session.getStderr().close();
21 |
22 | byte[] buf = new byte[10*1024*1024];
23 | DataInputStream in = new DataInputStream(session.getStdout());
24 |
25 | int j=0;
26 | while (true) {
27 | for (int i=0; i<5; i++) {
28 | long start = System.nanoTime();
29 | in.readFully(buf);
30 | long end = System.nanoTime();
31 | System.out.println("Took "+ TimeUnit.NANOSECONDS.toMillis(end-start));
32 | }
33 |
34 | int sz = 1024 * 1024 * (j++ % 2 == 0 ? 4 : 1);
35 | session.setWindowSize(sz);
36 | System.out.println("Adjusting size to "+sz);
37 | }
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/test/Sender.java:
--------------------------------------------------------------------------------
1 | import com.trilead.ssh2.Connection;
2 | import com.trilead.ssh2.Session;
3 | import com.trilead.ssh2.channel.ConnectionRule;
4 |
5 | import java.util.Random;
6 | import java.util.concurrent.TimeUnit;
7 |
8 | /**
9 | * Test the throughput of the data transmission.
10 | *
11 | * @author Kohsuke Kawaguchi
12 | */
13 | public class Sender {
14 | public static void main(String[] args) throws Exception {
15 | Connection connection = new ConnectionRule().getConnection();
16 | final Session session = connection.openSession();
17 |
18 | session.execCommand("cat > /dev/null");
19 | session.getStdout().close();
20 | session.getStderr().close();
21 |
22 | Random r = new Random();
23 | byte[] buf = new byte[10*1024*1024];
24 |
25 | while (true) {
26 | r.nextBytes(buf);
27 | long start = System.nanoTime();
28 | session.getStdin().write(buf);
29 | long end = System.nanoTime();
30 | System.out.println("Took "+TimeUnit.NANOSECONDS.toMillis(end-start));
31 | }
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/test/com/trilead/ssh2/KerberosTest.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2;
2 |
3 | import org.junit.Before;
4 | import org.junit.Test;
5 |
6 | import java.io.IOException;
7 |
8 | import static org.junit.Assert.assertFalse;
9 | import static org.junit.Assert.assertTrue;
10 |
11 | /*
12 | This is a test class for the Kerberos authentication, it requires an Kerberos environment
13 | it was tested with the environment defined here https://github.com/criteo/kerberos-docker.git
14 |
15 | "KRB5_HOST=krb5-service-instance-com"
16 | "KRB5_USER=bob"
17 |
18 | @author Kuisathaverat
19 | */
20 | public class KerberosTest {
21 |
22 | @Before
23 | public void beforeMethod() {
24 | org.junit.Assume.assumeTrue(System.getenv("KRB5_HOST") != null);
25 | org.junit.Assume.assumeTrue(System.getenv("KRB5_USER") != null);
26 | }
27 |
28 | @Test
29 | public void testConnection() throws IOException {
30 | String host = System.getenv("KRB5_HOST");
31 | String user = System.getenv("KRB5_USER");
32 | Connection con = new Connection(host);
33 | con.connect();
34 | assertTrue(con.authenticateWithGssapiWithMic(user));
35 | }
36 |
37 | @Test
38 | public void testConnectionFAIL() throws IOException {
39 | String host = System.getenv("KRB5_HOST");
40 | String user = System.getenv("KRB5_USER");
41 | Connection con = new Connection(host);
42 | con.connect();
43 | assertFalse(con.authenticateWithGssapiWithMic(user + "NotExists"));
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/test/com/trilead/ssh2/SFTPClientTest.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2;
2 |
3 | import com.trilead.ssh2.channel.ConnectionRule;
4 | import com.trilead.ssh2.jenkins.SFTPClient;
5 | import org.apache.commons.io.IOUtils;
6 | import org.junit.Rule;
7 | import org.junit.Test;
8 |
9 | import java.io.InputStream;
10 | import java.io.OutputStream;
11 |
12 | import static org.junit.Assert.assertNotNull;
13 | import static org.junit.Assert.assertTrue;
14 |
15 | public class SFTPClientTest {
16 | public static final String TMP_TEST = "/tmp/test";
17 | public static final String PATH_FILE = TMP_TEST + "/file";
18 | public static final int POSIX_PERMISSION = 0700;
19 | public static final String FILE_CONTENT = "test";
20 |
21 | @Rule
22 | public ConnectionRule con = new ConnectionRule();
23 |
24 | @Test
25 | public void connectionTest() throws Exception {
26 | SFTPClient sftpClient = new SFTPClient(con.getConnection());
27 | sftpClient.mkdirs(TMP_TEST, POSIX_PERMISSION);
28 |
29 | OutputStream out = sftpClient.writeToFile(PATH_FILE);
30 | assertNotNull(out);
31 | IOUtils.write(FILE_CONTENT, out);
32 | out.close();
33 |
34 | InputStream in = sftpClient.read(PATH_FILE);
35 | assertNotNull(in);
36 | assertNotNull(IOUtils.readLines(in));
37 | in.close();
38 |
39 | sftpClient.chmod(PATH_FILE, POSIX_PERMISSION);
40 | assertTrue(sftpClient.exists(PATH_FILE));
41 | sftpClient.close();
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/test/com/trilead/ssh2/channel/ConnectionRule.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.channel;
2 |
3 | import com.trilead.ssh2.Connection;
4 | import org.apache.commons.io.IOUtils;
5 | import org.junit.Rule;
6 | import org.junit.rules.ExternalResource;
7 | import org.testcontainers.containers.GenericContainer;
8 |
9 | import static org.junit.Assert.assertTrue;
10 |
11 | /**
12 | * Connect to a remote SSH server
13 | *
14 | * @author Kohsuke Kawaguchi
15 | */
16 | public class ConnectionRule extends ExternalResource {
17 | public static final String USER = "jenkins";
18 | public static final int SSH_PORT = 22;
19 |
20 | @Rule
21 | public GenericContainer sshContainer = new GenericContainer("jenkins/ssh-agent");
22 |
23 | private Connection connection;
24 |
25 | public Connection getConnection() throws Exception {
26 | if (connection==null) // in case this is used outside JUnit
27 | before();
28 | return connection;
29 | }
30 |
31 | @Override
32 | public void before() throws Exception {
33 | String publicKey = IOUtils.toString(getClass().getResourceAsStream("../crypto/cipher/key.pem.pub"));
34 | String privateKey = IOUtils.toString(getClass().getResourceAsStream("../crypto/cipher/key.pem"));
35 | sshContainer.withEnv("JENKINS_AGENT_SSH_PUBKEY", publicKey)
36 | .withExposedPorts(SSH_PORT)
37 | .start();
38 |
39 | int port = sshContainer.getMappedPort(SSH_PORT);
40 | String ip = sshContainer.getContainerIpAddress();
41 |
42 | connection = new Connection(ip, port);
43 | connection.enableDebugging(true, null);
44 | connection.setTCPNoDelay(true);
45 | connection.connect();
46 |
47 | connection.authenticateWithPublicKey(USER, privateKey.toCharArray(),null);
48 | assertTrue(connection.isAuthenticationComplete());
49 | }
50 |
51 | @Override
52 | public void after() {
53 | if (connection!=null)
54 | connection.close();
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/test/com/trilead/ssh2/channel/RoundtripTest.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.channel;
2 |
3 | import com.trilead.ssh2.Session;
4 | import org.apache.commons.io.IOUtils;
5 | import org.junit.Assert;
6 | import org.junit.Rule;
7 | import org.junit.Test;
8 |
9 | import java.io.ByteArrayOutputStream;
10 | import java.util.Random;
11 | import java.util.concurrent.Callable;
12 | import java.util.concurrent.ExecutorService;
13 | import java.util.concurrent.Executors;
14 | import java.util.concurrent.Future;
15 |
16 | /**
17 | * @author Kohsuke Kawaguchi
18 | */
19 | public class RoundtripTest {
20 | @Rule
21 | public ConnectionRule con = new ConnectionRule();
22 |
23 | @Test
24 | public void dataXfer() throws Exception {
25 | final Session s = con.getConnection().openSession();
26 | s.execCommand("cat");
27 |
28 | s.getStderr().close();
29 |
30 | ExecutorService es = Executors.newFixedThreadPool(1);
31 | Future reader = es.submit(new Callable() {
32 | public byte[] call() throws Exception {
33 | ByteArrayOutputStream baos = new ByteArrayOutputStream();
34 | IOUtils.copy(s.getStdout(), baos);
35 | return baos.toByteArray();
36 | }
37 | });
38 |
39 | byte[] data = new byte[10*1024*1024];
40 | Random r = new Random();
41 | r.nextBytes(data);
42 |
43 | int inc;
44 | for (int i=0; i
13 | * org.slf4j
14 | * slf4j-jdk14
15 | * 2.0.0
16 | *
17 | * }
18 | * This class only setup JUL and then configures logging
19 | * to console.
20 | *
21 | *
22 | */
23 | class JULLoggerSetup {
24 | public static void setupJULLogger() {
25 | Logger rootLogger = Logger.getLogger("");
26 | rootLogger.setLevel(Level.ALL); // Set global logging level
27 |
28 | // Remove default handlers
29 | for (var handler : rootLogger.getHandlers()) {
30 | rootLogger.removeHandler(handler);
31 | }
32 |
33 | // Add a ConsoleHandler for JUL to print logs to the console
34 | ConsoleHandler consoleHandler = new ConsoleHandler();
35 | consoleHandler.setLevel(Level.ALL); // Log everything
36 | consoleHandler.setFormatter(new SimpleFormatter()); // Use simple log format
37 |
38 | // Add the new handler to the root logger
39 | rootLogger.addHandler(consoleHandler);
40 | }
41 |
42 | }
43 |
--------------------------------------------------------------------------------
/test/com/trilead/ssh2/transport/JulLogConsumer.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.transport;
2 |
3 | import org.testcontainers.containers.output.OutputFrame;
4 | import org.testcontainers.containers.output.OutputFrame.OutputType;
5 | import com.trilead.ssh2.log.Logger;
6 | import java.util.function.Consumer;
7 |
8 | /**
9 | * Consumer used to get logging for testcontainers.
10 | */
11 | class JulLogConsumer implements Consumer {
12 | private final Logger logger;
13 |
14 | // Constructor to initialize the JUL Logger
15 | public JulLogConsumer(Logger logger) {
16 | this.logger = logger;
17 | }
18 |
19 | @Override
20 | public void accept(OutputFrame outputFrame) {
21 | if (outputFrame != null) {
22 | String message = outputFrame.getUtf8String().trim(); // Get log message
23 | OutputType type = outputFrame.getType(); // Get output type (STDOUT, STDERR)
24 |
25 | // Map OutputFrame types to appropriate log levels
26 | if (type == OutputType.STDOUT) {
27 | logger.log(800,message); // Standard output as INFO logs
28 | } else if (type == OutputType.STDERR) {
29 | logger.log(900,message); // Standard error as WARNING logs
30 | } else if (type == OutputType.END) {
31 | logger.log(1000,"Container log stream closed.");
32 | }
33 | }
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/test/com/trilead/ssh2/transport/MyServerHostKeyVerifierImpl.java:
--------------------------------------------------------------------------------
1 | package com.trilead.ssh2.transport;
2 |
3 | import com.trilead.ssh2.ServerHostKeyVerifier;
4 |
5 | class MyServerHostKeyVerifierImpl implements ServerHostKeyVerifier{
6 |
7 | @Override
8 | public boolean verifyServerHostKey(String hostname, int port, String serverHostKeyAlgorithm, byte[] serverHostKey) {
9 | // Always accept any host key (Fake verifier)
10 | System.out.println("Fake HostKeyVerifier: Host " + hostname + " accepted without verification.");
11 | return true;
12 | }
13 |
14 | }
15 |
--------------------------------------------------------------------------------
/test/docker/nacm.xml:
--------------------------------------------------------------------------------
1 |
2 | false
3 |
4 |
--------------------------------------------------------------------------------
/test/docker/ssh_callhome.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | default-client
5 |
6 |
7 | ssh-default
8 |
9 |
10 | localhost
11 |
12 |
13 |
14 |
15 | default-key
16 |
17 | genkey
18 |
19 |
20 |
21 |
22 | default-ssh
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/test/docker/ssh_listen.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | default-ssh
6 |
7 |
8 | 0.0.0.0
9 |
10 |
11 |
12 |
13 | default-key
14 |
15 | genkey
16 |
17 |
18 |
19 |
20 |
21 |
22 | netconf
23 | $0$netconf
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/test/krb5_test.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 | #
3 | # The script is used to provision a Kerberos environment an run some authentication tests againts it.
4 | # it use the enviroment defined in https://github.com/criteo/kerberos-docker.git
5 | # Author: Kuisathaverat
6 | #
7 |
8 | git clone https://github.com/criteo/kerberos-docker.git
9 | cd kerberos-docker
10 | make install
11 | cd ..
12 | docker cp . krb5-machine-instance-com:/root/trilead-ssh2
13 | docker exec -it -w "/root/trilead-ssh2" -e "KRB5_HOST=krb5-service-instance-com" -e "KRB5_USER=bob" krb5-machine-instance-com mvn clean test -Dtest=KerberosTest
--------------------------------------------------------------------------------
/workflows/cd.yaml:
--------------------------------------------------------------------------------
1 | # Note: additional setup is required, see https://www.jenkins.io/redirect/continuous-delivery-of-plugins
2 |
3 | name: cd
4 | on:
5 | workflow_dispatch:
6 | check_run:
7 | types:
8 | - completed
9 |
10 | jobs:
11 | validate:
12 | runs-on: ubuntu-latest
13 | outputs:
14 | should_release: ${{ steps.verify-ci-status.outputs.result == 'success' && steps.interesting-categories.outputs.interesting == 'true' }}
15 | steps:
16 | - name: Verify CI status
17 | uses: jenkins-infra/verify-ci-status-action@v1.2.0
18 | id: verify-ci-status
19 | with:
20 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
21 | output_result: true
22 |
23 | - name: Release Drafter
24 | uses: release-drafter/release-drafter@v5
25 | if: steps.verify-ci-status.outputs.result == 'success'
26 | with:
27 | name: next
28 | tag: next
29 | version: next
30 | env:
31 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
32 |
33 | - name: Check interesting categories
34 | uses: jenkins-infra/interesting-category-action@v1.0.0
35 | id: interesting-categories
36 | if: steps.verify-ci-status.outputs.result == 'success'
37 | with:
38 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
39 |
40 | release:
41 | runs-on: ubuntu-latest
42 | needs: [validate]
43 | if: needs.validate.outputs.should_release == 'true'
44 | steps:
45 | - name: Check out
46 | uses: actions/checkout@v2.3.4
47 | with:
48 | fetch-depth: 0
49 | - name: Set up JDK 8
50 | uses: actions/setup-java@v2
51 | with:
52 | distribution: 'adopt'
53 | java-version: 8
54 | - name: Release
55 | uses: jenkins-infra/jenkins-maven-cd-action@v1.2.0
56 | with:
57 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
58 | MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
59 | MAVEN_TOKEN: ${{ secrets.MAVEN_TOKEN }}
--------------------------------------------------------------------------------