Compare commits

...

101 Commits

Author SHA1 Message Date
Shikhar Bhushan
80b164a299 [maven-release-plugin] prepare release v0.8.1 2012-07-08 09:55:22 -04:00
Shikhar Bhushan
75418f33b7 Next release to be 0.8.1 2012-07-08 09:50:43 -04:00
Shikhar Bhushan
732de2b605 make logs less chatty
#80
2012-07-05 00:10:40 +05:30
Shikhar Bhushan
4fb56b868f Per #77 use regex matching inside PasswordResponseProvider. Also remove the 'gaveAlready' state, we can leave such logic to the PasswordFinder to implement if needed. 2012-06-06 23:59:41 +01:00
Shikhar Bhushan
a877ec1448 AbstractChannel#close() should be no-op if already closed. Fixes #53. 2012-06-06 22:57:27 +01:00
Shikhar Bhushan
b44631ea97 Better naming for some AbstractChannel's lock/event members 2012-06-06 22:51:25 +01:00
Shikhar Bhushan
a50962ba2f Small cleanup 2012-05-19 11:18:30 +01:00
Shikhar Bhushan
e8215e4af2 Update NOTICE 2012-05-14 11:33:05 +02:00
Shikhar Bhushan
3c2bda3196 docfix - not part of the contract 2012-05-12 22:13:22 +01:00
Shikhar Bhushan
b13e22084b [maven-release-plugin] prepare for next development iteration 2012-05-12 21:48:45 +01:00
Shikhar Bhushan
e7ba0e1e26 [maven-release-plugin] prepare release v0.8.0 2012-05-12 21:48:39 +01:00
Shikhar Bhushan
f712720538 Update CONTRIBUTORS 2012-05-12 17:33:07 +02:00
Shikhar Bhushan
540708e540 Provide a preference SFTPFileTransfer.setPreserveAttributes() to not set file attributes post upload or download.
Should address issue #42 / pull request #43
2012-05-12 16:24:01 +01:00
Shikhar Bhushan
e4d3a1f866 Some documentation on the FileTransfer interface. 2012-05-12 16:03:57 +01:00
Shikhar Bhushan
33969340e2 small tweak 2012-05-12 14:37:07 +01:00
Shikhar Bhushan
d65df3c9bc - Move trailing slash removal from SFTPEngine.mkdirs() to PathHelper.getComponents()
- Try to make the PathHelper.getComponents() code clearer
- Added some tests for PathHelper.getComponents()
2012-05-12 14:28:28 +01:00
Shikhar Bhushan
d2b9248535 Decouple PathHelper and SFTPEngine, introduce Canonicalizer interface 2012-05-12 11:23:44 +01:00
Shikhar Bhushan
431be8e7c7 Lower the ceiling on max remote packet size (so we don't allocate huge buffers) & spell it out mor explicitly 2012-05-12 11:09:41 +01:00
Shikhar Bhushan
885c602ab8 Merge pull request #66 from UrsKR/trailingseparator
SFTP client no longer tries to create folders twice when path has trailing separator
2012-05-12 03:09:04 -07:00
Shikhar Bhushan
8262e8fc98 Update CONTRIBUTORS 2012-04-28 13:21:47 +02:00
Shikhar Bhushan
844c5d7f77 Merge pull request #73 from aledsage/Issue-72-Buffer-Too-Large
Issue 72: fix for infinite loop if allocate too large a buffer
2012-04-28 04:16:16 -07:00
Aled Sage
fb690c4fb0 Issue 72: fix for infinite loop if allocate too large a buffer (due to invalid packet size) 2012-04-26 11:43:29 +01:00
Shikhar Bhushan
ab04596a20 Merge pull request #69 from ludoza/patch-1
fixed simple example.
2012-04-15 03:00:18 -07:00
ludoza
9ffdc35f93 fixed simple example. 2012-04-11 18:02:40 +03:00
Shikhar Bhushan
93e23f4cfb Don't try to send a disconnect packet if never connected. Fixes GH-67. 2012-04-05 12:30:56 -04:00
Shikhar Bhushan
504637099d copyright 2012-04-05 12:30:55 -04:00
Shikhar Bhushan
cafd9217bf whitespace 2012-04-05 12:30:55 -04:00
Urs Reupke
c627fabebd MkDirs no longer tries to create folders twice when path has trailing slash. 2012-03-23 10:58:42 +01:00
Shikhar Bhushan
1c4781a65d Merge pull request #65 from ryantenney/logging-fix
Avoid string concatenation in log statements
2012-03-20 01:10:52 -07:00
Ryan Tenney
aac7af2827 Avoid string concatenation in log statements. 2012-03-19 13:34:38 -04:00
Shikhar Bhushan
11c286b9b9 . 2012-02-08 20:01:58 +00:00
Shikhar Bhushan
7fae513fd8 google group 2012-02-08 20:01:39 +00:00
Shikhar Bhushan
53ad9d2288 int->long 2012-02-06 23:36:18 +00:00
Shikhar Bhushan
ee07072846 Make window size a long, as it can be upto (2^32 - 1)
Fix for #57
2012-02-06 22:24:52 +00:00
Shikhar Bhushan
d38bbbcdf7 clearer... 2012-02-05 19:54:42 +00:00
Shikhar Bhushan
bc59c81dbc Refactor TransferListener interface to support thread-safe, immutable implementation.
Fix #56
2012-01-29 22:54:17 +00:00
Shikhar Bhushan
d70d37cf4e Version string update 2012-01-29 22:52:59 +00:00
Shikhar Bhushan
777d82912c Merge pull request #55 from hierynomus/default-tty
Set default tty to vt100, as specified in the javadoc
2012-01-26 13:52:39 -08:00
hierynomus
f5db3e1563 Set default tty to vt100, as specified in the javadoc 2012-01-19 10:19:19 +01:00
Shikhar Bhushan
7e524f5c6f Make disconnect() an operation that can be repeated without side-effects beyond the first call. 2012-01-08 10:20:46 +00:00
Shikhar Bhushan
dbb3f62e82 [maven-release-plugin] prepare for next development iteration 2012-01-08 09:32:47 +00:00
Shikhar Bhushan
16a363fef6 [maven-release-plugin] prepare release v0.7.0 2012-01-08 09:32:41 +00:00
Shikhar Bhushan
9b0d39a798 Remove the SFTPClient.getFileTansfer() method that has typo altogether as this is a simple change to make for clients. 2012-01-08 09:30:05 +00:00
Shikhar Bhushan
81e36153d7 wrapping 2012-01-08 09:10:07 +00:00
Shikhar Bhushan
3026be282a Refactored the local port forwarding API; give caller control over initializing and cleaning up the server socket used.
Also removed 'server socket factory' stuff from SocketClient.
2012-01-05 22:26:44 +00:00
Shikhar Bhushan
8eedeb25fa Merge pull request #50 from iocanel/master
Remove bouncycastle version range from OSGi metadata.
2012-01-02 06:52:50 -08:00
Ioannis Canellos
de11880648 Removed package version from bouncycastle imports 2012-01-02 15:04:12 +02:00
Shikhar Bhushan
1ff4772f3f update id string 2011-12-20 11:12:35 +00:00
Shikhar Bhushan
22a5ffe735 fix for #47 - should send data down rather than sitting around waiting for an adjustment if there is window space available 2011-12-20 10:41:49 +00:00
Shikhar Bhushan
7a77f85ced docfix 2011-12-20 10:37:32 +00:00
Shikhar Bhushan
0002fe8b40 Made some Buffer subclasses final 2011-12-19 22:52:41 +00:00
Shikhar Bhushan
3028e7f218 Fix logging of window adjustments 2011-12-19 21:56:44 +00:00
Shikhar Bhushan
333e1cb7b8 small cleanup 2011-12-04 19:10:34 +00:00
Shikhar Bhushan
945d430916 Removed deprecated Session.Command's methods - getOutputAsString() and getErrorAsString() 2011-12-04 18:26:05 +00:00
Shikhar Bhushan
73b903784a Next version will be 0.7.0 2011-12-04 18:24:00 +00:00
Shikhar Bhushan
7d53649a85 . 2011-12-04 18:23:15 +00:00
Shikhar Bhushan
e193db9a14 Fix example in SSHClient doc 2011-12-04 18:14:27 +00:00
Shikhar Bhushan
a942edb911 Add SFTPClient.getFileTransfer() and deprecate getFileTansfer() which has typo 2011-12-04 18:11:30 +00:00
Shikhar Bhushan
137a7f5956 (reformat) 2011-12-04 17:48:42 +00:00
Shikhar Bhushan
718ff503df Merge pull request #41 from hierynomus/known-hosts
OpenSSH Known hosts format re-implemented
2011-12-04 09:35:58 -08:00
Shikhar Bhushan
d933b2538e Upgrade maven-bundle-plugin to 2.3.6 to fix #37 [https://issues.apache.org/jira/browse/FELIX-3058] 2011-12-04 17:10:33 +00:00
Shikhar Bhushan
ea6f9ceed2 Correct version 2011-12-04 13:54:19 +00:00
rws
07c61b14e8 Change SocketClient to public so that SSHClient can be mocked for testing. 2011-12-04 21:51:58 +08:00
hierynomus
4b175e6938 Re-implemented OpenSSHKnownHostsVerifier to deal with the real format 2011-11-10 09:51:18 +01:00
Shikhar Bhushan
f7e47cffa0 [maven-release-plugin] prepare for next development iteration 2011-10-02 22:17:46 +01:00
Shikhar Bhushan
42dddc7f7e [maven-release-plugin] prepare release v0.6.1 2011-10-02 22:17:36 +01:00
Shikhar Bhushan
f1b3dbb102 Restore mutual exclusion of sendChannelRequest() and gotResponse() in AbstractChannel (but rather than make methods synchronized do it on the queue, which itself doesn't need to be thread-safe). Regression due to 1a2351c5ee. Fixes #35. 2011-10-02 09:47:49 +01:00
Shikhar Bhushan
f83bf2cd3f [maven-release-plugin] prepare for next development iteration 2011-09-26 12:41:23 +01:00
Shikhar Bhushan
be11cbb848 [maven-release-plugin] prepare release v0.6.0 2011-09-26 12:41:17 +01:00
Shikhar Bhushan
43b0599e1f let's make next release sshj 0.6.0 2011-09-26 12:37:21 +01:00
Shikhar Bhushan
b218186cae Merge pull request #34 from hierynomus/scp-filter-copy
Added upload filter capability to SCPUploadClient
2011-09-26 04:11:24 -07:00
hierynomus
184236c3d5 Added upload filter capability to SCPUploadClient 2011-09-26 11:49:07 +02:00
Shikhar Bhushan
cb1d773659 Merge branch 'master' of github.com:shikhar/sshj 2011-09-14 23:06:05 +01:00
Shikhar Bhushan
378665cb46 update contrib 2011-09-14 23:37:31 +02:00
Shikhar Bhushan
a5272dc413 Merge branch 'master' of github.com:shikhar/sshj 2011-09-14 22:11:29 +01:00
Shikhar Bhushan
60552fd001 Merge pull request #31 from hierynomus/filemode-typemask
Fixed bug in SFTP FileMode for AIX/Unix directory mask
2011-09-14 11:43:59 -07:00
hierynomus
ef082c668a Fixed bug in SFTP FileMode for AIX/Unix directory mask 2011-09-14 11:02:35 +02:00
Shikhar Bhushan
e66386eb1c Local window exhaustion -> ConnectionException 2011-09-07 21:45:44 +01:00
Shikhar Bhushan
0937ec9800 minor 2011-09-07 21:24:49 +01:00
Shikhar Bhushan
4b2f42804e Added version in pom.xml for maven-bundle-plugin 2011-08-29 16:49:49 +01:00
Shikhar Bhushan
01765d24d2 AbstractChannel - no reason for channel request response events to share the same underlying lock object. #27 2011-08-29 16:45:12 +01:00
Shikhar Bhushan
1a2351c5ee AbstractChannel - make chanReqResponseEvents a ConcurrentLinkedQueue, so don't have to have sendChannelRequest() & gotResponse() as synchronized methods. #27 2011-08-29 16:41:27 +01:00
Shikhar Bhushan
1cec011401 chown / chmod / chgrp in StatefulSFTPClient -- these all delegate to setattr which is overriden in StatefulSFTPClient to do cwdification. #28 2011-08-29 16:21:10 +01:00
Shikhar Bhushan
52338c13cb Merge pull request #28 from neilprosser/master
StatefulSFTPClient doesn't cwdify all commands
2011-08-27 04:23:07 -07:00
Neil Prosser
09cf21f61a Some stateful methods that needed cwdifying 2011-08-27 00:30:20 +01:00
Shikhar Bhushan
04c2e7b6b8 Client version string update 2011-07-27 19:52:27 +01:00
Shikhar Bhushan
822f196dd8 update contrib 2011-07-27 19:38:56 +01:00
Shikhar Bhushan
a88a574b10 [maven-release-plugin] prepare for next development iteration 2011-07-27 19:33:32 +01:00
Shikhar Bhushan
5cd6986355 [maven-release-plugin] prepare release v0.5.0 2011-07-27 19:33:26 +01:00
Shikhar Bhushan
b5d206bbcb Merge pull request #22 from iocanel/master
OSGi bundle for sshj
2011-07-25 12:22:43 -07:00
Ioannis Canellos
4eae26c551 OSGi-fied sshj 2011-07-25 06:29:20 -07:00
Shikhar Bhushan
b950f88f52 SSHClient implements Closeable 2011-07-24 20:50:01 +01:00
Shikhar Bhushan
3267860db4 mass auto-format 2011-07-24 20:48:00 +01:00
Shikhar Bhushan
d6eb5a040e Non-final ChannelOutputStream field may be null if we haven't received channel open confirmation or channel open failed. So do null-check. 2011-07-16 10:19:46 +01:00
Shikhar Bhushan
21da5b9f65 update contributor list 2011-07-03 14:50:43 -07:00
Shikhar Bhushan
6b66a952d4 Session#changeWindowDimensions was broken, wrong channel request.
Fix for #21
2011-07-03 10:59:40 +01:00
Shikhar Bhushan
aa4faf3f25 Merge pull request #20 from cloudera/forUpstream
Don't leak PrivateKeyStringResource private keys via toString()
2011-06-23 13:46:37 -07:00
Adar Dembo
4be02450dd Don't leak PrivateKeyStringResource private keys via toString() 2011-06-22 17:52:46 -07:00
Shikhar Bhushan
0cec27c28e Edited README.rst via GitHub 2011-06-20 11:44:56 -07:00
Shikhar Bhushan
4384367a1b point to issue tracker 2011-06-20 11:43:21 -07:00
Shikhar Bhushan
4549648a76 [maven-release-plugin] prepare for next development iteration 2011-06-19 18:32:36 +01:00
193 changed files with 1680 additions and 1099 deletions

View File

@@ -1,4 +1,11 @@
Shikhar Bhushan <shikhar@schmizz.net>
Cyril Ledru <cledru@keynectis.net>
Incendium <incendium@gmail.com>
Philip Langdale <philipl@cloudera.com>
Philip Langdale <philipl@cloudera.com>
Adar Dembo <adar@cloudera.com>
Ioannis Canellos <iocanel@gmail.com>
Neil Prosser <neil.prosser@gmail.com>
hierynomus <jeroen@hierynomus.com>
Ryan Tenney <ryan@10e.us>
Aled Sage <aled.sage@gmail.com>
Urs Reupke <ur@idos.de>

2
NOTICE
View File

@@ -1,5 +1,5 @@
sshj - SSHv2 library for Java
Copyright 2010-2011 sshj contributors
Copyright 2010-2012 sshj contributors
This product includes code derived from software developed at
The Apache Software Foundation (http://www.apache.org/):

View File

@@ -39,6 +39,15 @@ Dependencies
Java 6+. slf4j_ is required. bouncycastle_ is highly recommended and required for using some of the crypto algorithms. jzlib_ is required for using zlib compression.
Reporting bugs
----------------
`Issue tracker <https://github.com/shikhar/sshj/issues>`_
Discussion
------------
`Google Group <http://groups.google.com/group/sshj-users>`_
Contributing
------------

29
pom.xml
View File

@@ -5,8 +5,8 @@
<groupId>net.schmizz</groupId>
<artifactId>sshj</artifactId>
<packaging>jar</packaging>
<version>0.4.1</version>
<packaging>bundle</packaging>
<version>0.8.1</version>
<name>sshj</name>
<description>SSHv2 library for Java</description>
@@ -75,6 +75,12 @@
<version>0.9.29</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.mockito</groupId>
<artifactId>mockito-all</artifactId>
<version>1.9.0-rc1</version>
<scope>test</scope>
</dependency>
</dependencies>
@@ -160,6 +166,25 @@
</execution>
</executions>
</plugin>
<plugin>
<groupId>org.apache.felix</groupId>
<artifactId>maven-bundle-plugin</artifactId>
<version>2.3.6</version>
<extensions>true</extensions>
<configuration>
<instructions>
<Import-Package>
!net.schmizz.*,
javax.crypto*,
com.jcraft.jzlib*;version="[1.0,2)",
org.slf4j*;version="[1.6,2)",
org.bouncycastle*,
*
</Import-Package>
<Export-Package>net.schmizz.*</Export-Package>
</instructions>
</configuration>
</plugin>
</plugins>
</build>

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,9 +16,11 @@
package examples;
import net.schmizz.sshj.SSHClient;
import net.schmizz.sshj.connection.channel.direct.LocalPortForwarder;
import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
/**
* This example demonstrates local port forwarding, i.e. when we listen on a particular address and port; and forward
@@ -41,8 +43,16 @@ public class LocalPF {
* _We_ listen on localhost:8080 and forward all connections on to server, which then forwards it to
* google.com:80
*/
ssh.newLocalPortForwarder(new InetSocketAddress("localhost", 8080), "google.com", 80)
.listen();
final LocalPortForwarder.Parameters params
= new LocalPortForwarder.Parameters("0.0.0.0", 8080, "google.com", 80);
final ServerSocket ss = new ServerSocket();
ss.setReuseAddress(true);
ss.bind(new InetSocketAddress(params.getLocalHost(), params.getLocalPort()));
try {
ssh.newLocalPortForwarder(params, ss).listen();
} finally {
ss.close();
}
} finally {
ssh.disconnect();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -30,12 +30,12 @@ public class ErrorDeliveryUtil {
}
public static void alertEvents(Throwable x, Event... events) {
for (Event e: events)
for (Event e : events)
e.deliverError(x);
}
public static void alertEvents(Throwable x, Collection<? extends Event> events) {
for (Event e: events)
for (Event e : events)
e.deliverError(x);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -18,7 +18,8 @@ package net.schmizz.sshj;
import net.schmizz.sshj.transport.random.JCERandom;
import net.schmizz.sshj.transport.random.SingletonRandomFactory;
public class AndroidConfig extends DefaultConfig {
public class AndroidConfig
extends DefaultConfig {
@Override
protected void initRandomFactory(boolean ignored) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -31,6 +31,7 @@ import java.util.List;
* {@link Compression}, {@link MAC}, {@link Signature}, {@link Random}, and {@link FileKeyProvider}.
*/
public interface Config {
/**
* Retrieve the list of named factories for {@code Cipher}.
*

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -73,15 +73,20 @@ import java.util.List;
* A {@link Config} that is initialized as follows. Items marked with an asterisk are added to the config only if
* BouncyCastle is in the classpath.
* <p/>
* <ul> <li>{@link ConfigImpl#setKeyExchangeFactories Key exchange}: {@link DHG14}*, {@link DHG1}</li> <li>{@link
* ConfigImpl#setCipherFactories Ciphers} [1]: {@link AES128CTR}, {@link AES192CTR}, {@link AES256CTR}, {@link
* <ul>
* <li>{@link ConfigImpl#setKeyExchangeFactories Key exchange}: {@link DHG14}*, {@link DHG1}</li>
* <li>{@link ConfigImpl#setCipherFactories Ciphers} [1]: {@link AES128CTR}, {@link AES192CTR}, {@link AES256CTR},
* {@link
* AES128CBC}, {@link AES192CBC}, {@link AES256CBC}, {@link AES192CBC}, {@link TripleDESCBC}, {@link BlowfishCBC}</li>
* <li>{@link ConfigImpl#setMACFactories MAC}: {@link HMACSHA1}, {@link HMACSHA196}, {@link HMACMD5}, {@link
* HMACMD596}</li> <li>{@link ConfigImpl#setCompressionFactories Compression}: {@link NoneCompression}</li> <li>{@link
* ConfigImpl#setSignatureFactories Signature}: {@link SignatureRSA}, {@link SignatureDSA}</li> <li>{@link
* ConfigImpl#setRandomFactory PRNG}: {@link BouncyCastleRandom}* or {@link JCERandom}</li> <li>{@link
* ConfigImpl#setFileKeyProviderFactories Key file support}: {@link PKCS8KeyFile}*, {@link OpenSSHKeyFile}*</li>
* <li>{@link ConfigImpl#setVersion Client version}: {@code "NET_3_0"}</li> </ul>
* HMACMD596}</li>
* <li>{@link ConfigImpl#setCompressionFactories Compression}: {@link NoneCompression}</li>
* <li>{@link ConfigImpl#setSignatureFactories Signature}: {@link SignatureRSA}, {@link SignatureDSA}</li>
* <li>{@link ConfigImpl#setRandomFactory PRNG}: {@link BouncyCastleRandom}* or {@link JCERandom}</li>
* <li>{@link ConfigImpl#setFileKeyProviderFactories Key file support}: {@link PKCS8KeyFile}*, {@link
* OpenSSHKeyFile}*</li>
* <li>{@link ConfigImpl#setVersion Client version}: {@code "NET_3_0"}</li>
* </ul>
* <p/>
* [1] It is worth noting that Sun's JRE does not have the unlimited cryptography extension enabled by default. This
* prevents using ciphers with strength greater than 128.
@@ -91,7 +96,7 @@ public class DefaultConfig
private final Logger log = LoggerFactory.getLogger(getClass());
private static final String VERSION = "SSHJ_0_4_1";
private static final String VERSION = "SSHJ_0_8_1_SNAPSHOT";
public DefaultConfig() {
setVersion(VERSION);
@@ -113,7 +118,8 @@ public class DefaultConfig
}
protected void initRandomFactory(boolean bouncyCastleRegistered) {
setRandomFactory(new SingletonRandomFactory(bouncyCastleRegistered ? new BouncyCastleRandom.Factory() : new JCERandom.Factory()));
setRandomFactory(new SingletonRandomFactory(bouncyCastleRegistered
? new BouncyCastleRandom.Factory() : new JCERandom.Factory()));
}
protected void initFileKeyProviderFactories(boolean bouncyCastleRegistered) {
@@ -137,7 +143,7 @@ public class DefaultConfig
boolean warn = false;
// Ref. https://issues.apache.org/jira/browse/SSHD-24
// "AES256 and AES192 requires unlimited cryptography extension"
for (Iterator<Factory.Named<Cipher>> i = avail.iterator(); i.hasNext();) {
for (Iterator<Factory.Named<Cipher>> i = avail.iterator(); i.hasNext(); ) {
final Factory.Named<Cipher> f = i.next();
try {
final Cipher c = f.create();
@@ -161,7 +167,7 @@ public class DefaultConfig
protected void initMACFactories() {
setMACFactories(new HMACSHA1.Factory(), new HMACSHA196.Factory(), new HMACMD5.Factory(),
new HMACMD596.Factory());
new HMACMD596.Factory());
}
protected void initCompressionFactories() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -16,7 +16,6 @@
package net.schmizz.sshj;
import net.schmizz.sshj.common.DisconnectReason;
import net.schmizz.sshj.common.Factory;
import net.schmizz.sshj.common.SSHException;
import net.schmizz.sshj.common.SecurityUtils;
@@ -50,7 +49,6 @@ import net.schmizz.sshj.userauth.keyprovider.FileKeyProvider;
import net.schmizz.sshj.userauth.keyprovider.KeyPairWrapper;
import net.schmizz.sshj.userauth.keyprovider.KeyProvider;
import net.schmizz.sshj.userauth.keyprovider.KeyProviderUtil;
import net.schmizz.sshj.userauth.keyprovider.OpenSSHKeyFile;
import net.schmizz.sshj.userauth.method.AuthKeyboardInteractive;
import net.schmizz.sshj.userauth.method.AuthMethod;
import net.schmizz.sshj.userauth.method.AuthPassword;
@@ -63,11 +61,10 @@ import net.schmizz.sshj.xfer.scp.SCPFileTransfer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.Closeable;
import java.io.File;
import java.io.IOException;
import java.io.Reader;
import java.io.StringReader;
import java.net.SocketAddress;
import java.net.ServerSocket;
import java.security.KeyPair;
import java.security.PublicKey;
import java.util.Arrays;
@@ -95,8 +92,8 @@ import java.util.List;
* <em>A simple example:</em>
* <p/>
* <pre>
* client = new SSHClient();
* client.initUserKnownHosts();
* final SSHClient client = new SSHClient();
* client.loadKnownHosts();
* client.connect(&quot;hostname&quot;);
* try {
* client.authPassword(&quot;username&quot;, &quot;password&quot;);
@@ -106,8 +103,9 @@ import java.util.List;
* cmd.join(1, TimeUnit.SECONDS);
* } finally {
* session.close();
* } finally {
* client.disconnect();
* }
* } finally {
* client.disconnect();
* }
* </pre>
* <p/>
@@ -116,7 +114,7 @@ import java.util.List;
*/
public class SSHClient
extends SocketClient
implements SessionFactory {
implements Closeable, SessionFactory {
/** Default port for SSH */
public static final int DEFAULT_PORT = 22;
@@ -365,7 +363,6 @@ public class SSHClient
@Override
public void disconnect()
throws IOException {
assert isConnected();
trans.disconnect();
super.disconnect();
assert !isConnected();
@@ -444,7 +441,7 @@ public class SSHClient
/**
* Utility function for createing a {@link KeyProvider} instance from given location on the file system. Creates a
* one-off {@link PasswordFinder} using {@link PasswordUtils#createOneOff(char[])}, and calls {@link
* #loadKeys(String,PasswordFinder)}.
* #loadKeys(String, PasswordFinder)}.
*
* @param location location of the key file
* @param passphrase passphrase as a char-array
@@ -479,8 +476,8 @@ public class SSHClient
throws IOException {
final File loc = new File(location);
final FileKeyProvider.Format format = KeyProviderUtil.detectKeyFileFormat(loc);
final FileKeyProvider fkp = Factory.Named.Util.create(trans.getConfig().getFileKeyProviderFactories(), format
.toString());
final FileKeyProvider fkp =
Factory.Named.Util.create(trans.getConfig().getFileKeyProviderFactories(), format.toString());
if (fkp == null)
throw new SSHException("No provider available for " + format + " key file");
fkp.init(loc, passwordFinder);
@@ -505,8 +502,8 @@ public class SSHClient
}
/**
* Creates a {@link KeyProvider} instance from passed strings. Currently only PKCS8 format
* private key files are supported (OpenSSH uses this format).
* Creates a {@link KeyProvider} instance from passed strings. Currently only PKCS8 format private key files are
* supported (OpenSSH uses this format).
* <p/>
*
* @param privateKey the private key as a string
@@ -523,8 +520,8 @@ public class SSHClient
public KeyProvider loadKeys(String privateKey, String publicKey, PasswordFinder passwordFinder)
throws IOException {
final FileKeyProvider.Format format = KeyProviderUtil.detectKeyFileFormat(privateKey, publicKey != null);
final FileKeyProvider fkp = Factory.Named.Util.create(trans.getConfig().getFileKeyProviderFactories(), format
.toString());
final FileKeyProvider fkp =
Factory.Named.Util.create(trans.getConfig().getFileKeyProviderFactories(), format.toString());
if (fkp == null)
throw new SSHException("No provider available for " + format + " key file");
fkp.init(privateKey, publicKey, passwordFinder);
@@ -571,23 +568,21 @@ public class SSHClient
}
/**
* Create a {@link LocalPortForwarder} that will listen on {@code address} and forward incoming connections to the
* server; which will further forward them to {@code host:port}.
* Create a {@link LocalPortForwarder} that will listen based on {@code parameters} using the bound
* {@code serverSocket} and forward incoming connections to the server; which will further forward them to
* {@code host:port}.
* <p/>
* The returned forwarder's {@link LocalPortForwarder#listen() listen()} method should be called to actually start
* listening, this method just creates an instance.
*
* @param address defines where the {@link LocalPortForwarder} listens
* @param host hostname to which the server will forward
* @param port the port at {@code hostname} to which the server wil forward
* @param parameters parameters for the forwarding setup
* @param serverSocket bound server socket
*
* @return a {@link LocalPortForwarder}
*
* @throws IOException if there is an error opening a local server socket
*/
public LocalPortForwarder newLocalPortForwarder(SocketAddress address, String host, int port)
throws IOException {
return new LocalPortForwarder(getServerSocketFactory(), conn, address, host, port);
public LocalPortForwarder newLocalPortForwarder(LocalPortForwarder.Parameters parameters,
ServerSocket serverSocket) {
return new LocalPortForwarder(conn, parameters, serverSocket);
}
/**
@@ -688,7 +683,18 @@ public class SSHClient
final long start = System.currentTimeMillis();
trans.doKex();
log.info("Key exchange took {} seconds", (System.currentTimeMillis() - start) / 1000.0);
log.debug("Key exchange took {} seconds", (System.currentTimeMillis() - start) / 1000.0);
}
/**
* Same as {@link #disconnect()}.
*
* @throws IOException
*/
@Override
public void close()
throws IOException {
disconnect();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,7 +35,6 @@
*/
package net.schmizz.sshj;
import javax.net.ServerSocketFactory;
import javax.net.SocketFactory;
import java.io.IOException;
import java.io.InputStream;
@@ -44,8 +43,7 @@ import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.Socket;
abstract class SocketClient {
public abstract class SocketClient {
private final int defaultPort;
@@ -54,7 +52,6 @@ abstract class SocketClient {
private OutputStream output;
private SocketFactory socketFactory = SocketFactory.getDefault();
private ServerSocketFactory serverSocketFactory = ServerSocketFactory.getDefault();
private static final int DEFAULT_CONNECT_TIMEOUT = 0;
private int connectTimeout = DEFAULT_CONNECT_TIMEOUT;
@@ -158,17 +155,6 @@ abstract class SocketClient {
return socketFactory;
}
public void setServerSocketFactory(ServerSocketFactory factory) {
if (factory == null)
serverSocketFactory = ServerSocketFactory.getDefault();
else
serverSocketFactory = factory;
}
public ServerSocketFactory getServerSocketFactory() {
return serverSocketFactory;
}
public int getConnectTimeout() {
return connectTimeout;
}

View File

@@ -32,7 +32,8 @@ public class Base64 {
* @see Base64
* @since 1.3
*/
public static class InputStream extends java.io.FilterInputStream {
public static class InputStream
extends java.io.FilterInputStream {
private final boolean encode; // Encoding or decoding
private int position; // Current position in the buffer
@@ -99,7 +100,8 @@ public class Base64 {
* @since 1.3
*/
@Override
public int read() throws java.io.IOException {
public int read()
throws java.io.IOException {
// Do we need to get data?
if (position < 0)
@@ -197,7 +199,8 @@ public class Base64 {
* @since 1.3
*/
@Override
public int read(byte[] dest, int off, int len) throws java.io.IOException {
public int read(byte[] dest, int off, int len)
throws java.io.IOException {
int i;
int b;
for (i = 0; i < len; i++) {
@@ -222,7 +225,8 @@ public class Base64 {
* @see Base64
* @since 1.3
*/
public static class OutputStream extends java.io.FilterOutputStream {
public static class OutputStream
extends java.io.FilterOutputStream {
private final boolean encode;
private int position;
@@ -289,7 +293,8 @@ public class Base64 {
* @since 1.3
*/
@Override
public void close() throws java.io.IOException {
public void close()
throws java.io.IOException {
// 1. Ensure that pending characters are written
flush();
@@ -308,7 +313,8 @@ public class Base64 {
* @since 2.3
*/
@Override
public void flush() throws java.io.IOException {
public void flush()
throws java.io.IOException {
flushBase64();
super.flush();
}
@@ -318,7 +324,8 @@ public class Base64 {
*
* @throws java.io.IOException if there's an error.
*/
public void flushBase64() throws java.io.IOException {
public void flushBase64()
throws java.io.IOException {
if (position > 0)
if (encode) {
out.write(encode3to4(b4, buffer, position, options));
@@ -346,7 +353,8 @@ public class Base64 {
* @throws java.io.IOException if there's an error flushing
* @since 1.5.1
*/
public void suspendEncoding() throws java.io.IOException {
public void suspendEncoding()
throws java.io.IOException {
flushBase64();
suspendEncoding = true;
} // end suspendEncoding
@@ -361,7 +369,8 @@ public class Base64 {
* @since 1.3
*/
@Override
public void write(byte[] theBytes, int off, int len) throws java.io.IOException {
public void write(byte[] theBytes, int off, int len)
throws java.io.IOException {
// Encoding suspended?
if (suspendEncoding) {
super.out.write(theBytes, off, len);
@@ -383,7 +392,8 @@ public class Base64 {
* @since 1.3
*/
@Override
public void write(int theByte) throws java.io.IOException {
public void write(int theByte)
throws java.io.IOException {
// Encoding suspended?
if (suspendEncoding) {
super.out.write(theByte);
@@ -673,7 +683,8 @@ public class Base64 {
* @throws java.io.IOException If bogus characters exist in source data
* @since 1.3
*/
public static byte[] decode(byte[] source, int off, int len, int options) throws java.io.IOException {
public static byte[] decode(byte[] source, int off, int len, int options)
throws java.io.IOException {
// Lots of error checking and exception throwing
if (source == null)
@@ -725,7 +736,7 @@ public class Base64 {
else
// There's a bad input character in the Base64 stream.
throw new java.io.IOException(String.format("Bad Base64 input character '%c' in array position %d",
source[i], i));
source[i], i));
} // each input character
byte[] out = new byte[outBuffPosn];
@@ -743,7 +754,8 @@ public class Base64 {
* @throws java.io.IOException If there is a problem
* @since 1.4
*/
public static byte[] decode(String s) throws java.io.IOException {
public static byte[] decode(String s)
throws java.io.IOException {
return decode(s, NO_OPTIONS);
}
@@ -759,7 +771,8 @@ public class Base64 {
* @throws NullPointerException if <tt>s</tt> is null
* @since 1.4
*/
public static byte[] decode(String s, int options) throws java.io.IOException {
public static byte[] decode(String s, int options)
throws java.io.IOException {
if (s == null)
throw new NullPointerException("Input string was null.");
@@ -833,7 +846,8 @@ public class Base64 {
* @throws java.io.IOException if there is an error
* @since 2.2
*/
public static void decodeFileToFile(String infile, String outfile) throws java.io.IOException {
public static void decodeFileToFile(String infile, String outfile)
throws java.io.IOException {
byte[] decoded = Base64.decodeFromFile(infile);
java.io.OutputStream out = null;
@@ -864,7 +878,8 @@ public class Base64 {
* @throws java.io.IOException if there is an error
* @since 2.1
*/
public static byte[] decodeFromFile(String filename) throws java.io.IOException {
public static byte[] decodeFromFile(String filename)
throws java.io.IOException {
byte[] decodedData = null;
Base64.InputStream bis = null;
@@ -878,12 +893,12 @@ public class Base64 {
// Check for size of file
if (file.length() > Integer.MAX_VALUE)
throw new java.io.IOException("File is too big for this convenience method (" + file.length()
+ " bytes).");
+ " bytes).");
buffer = new byte[(int) file.length()];
// Open a stream
bis = new Base64.InputStream(new java.io.BufferedInputStream(new java.io.FileInputStream(file)),
Base64.DECODE);
Base64.DECODE);
// Read until done
while ((numBytes = bis.read(buffer, length, 4096)) >= 0)
@@ -918,7 +933,8 @@ public class Base64 {
* @throws java.io.IOException if there is an error
* @since 2.1
*/
public static void decodeToFile(String dataToDecode, String filename) throws java.io.IOException {
public static void decodeToFile(String dataToDecode, String filename)
throws java.io.IOException {
Base64.OutputStream bos = null;
try {
@@ -950,8 +966,9 @@ public class Base64 {
* @throws ClassNotFoundException if the decoded object is of a class that cannot be found by the JVM
* @since 1.5
*/
public static Object decodeToObject(String encodedObject) throws java.io.IOException,
java.lang.ClassNotFoundException {
public static Object decodeToObject(String encodedObject)
throws java.io.IOException,
java.lang.ClassNotFoundException {
// Decode and gunzip if necessary
byte[] objBytes = decode(encodedObject);
@@ -1078,7 +1095,8 @@ public class Base64 {
* @see Base64#DO_BREAK_LINES
* @since 2.0
*/
public static String encodeBytes(byte[] source, int options) throws java.io.IOException {
public static String encodeBytes(byte[] source, int options)
throws java.io.IOException {
return encodeBytes(source, 0, source.length, options);
} // end encodeBytes
@@ -1137,7 +1155,8 @@ public class Base64 {
* @see Base64#DO_BREAK_LINES
* @since 2.0
*/
public static String encodeBytes(byte[] source, int off, int len, int options) throws java.io.IOException {
public static String encodeBytes(byte[] source, int off, int len, int options)
throws java.io.IOException {
byte[] encoded = encodeBytesToBytes(source, off, len, options);
// Return value according to relevant encoding.
@@ -1189,7 +1208,8 @@ public class Base64 {
* @see Base64#DO_BREAK_LINES
* @since 2.3.1
*/
public static byte[] encodeBytesToBytes(byte[] source, int off, int len, int options) throws java.io.IOException {
public static byte[] encodeBytesToBytes(byte[] source, int off, int len, int options)
throws java.io.IOException {
if (source == null)
throw new NullPointerException("Cannot serialize a null array.");
@@ -1302,7 +1322,8 @@ public class Base64 {
* @throws java.io.IOException if there is an error
* @since 2.2
*/
public static void encodeFileToFile(String infile, String outfile) throws java.io.IOException {
public static void encodeFileToFile(String infile, String outfile)
throws java.io.IOException {
String encoded = Base64.encodeFromFile(infile);
java.io.OutputStream out = null;
@@ -1333,7 +1354,8 @@ public class Base64 {
* @throws java.io.IOException if there is an error
* @since 2.1
*/
public static String encodeFromFile(String filename) throws java.io.IOException {
public static String encodeFromFile(String filename)
throws java.io.IOException {
String encodedData = null;
Base64.InputStream bis = null;
@@ -1348,7 +1370,7 @@ public class Base64 {
// Open a stream
bis = new Base64.InputStream(new java.io.BufferedInputStream(new java.io.FileInputStream(file)),
Base64.ENCODE);
Base64.ENCODE);
// Read until done
while ((numBytes = bis.read(buffer, length, 4096)) >= 0)
@@ -1387,7 +1409,8 @@ public class Base64 {
* @throws NullPointerException if serializedObject is null
* @since 1.4
*/
public static String encodeObject(java.io.Serializable serializableObject) throws java.io.IOException {
public static String encodeObject(java.io.Serializable serializableObject)
throws java.io.IOException {
return encodeObject(serializableObject, NO_OPTIONS);
} // end encodeObject
@@ -1420,7 +1443,8 @@ public class Base64 {
* @see Base64#DO_BREAK_LINES
* @since 2.0
*/
public static String encodeObject(java.io.Serializable serializableObject, int options) throws java.io.IOException {
public static String encodeObject(java.io.Serializable serializableObject, int options)
throws java.io.IOException {
if (serializableObject == null)
throw new NullPointerException("Cannot serialize a null object.");
@@ -1481,7 +1505,8 @@ public class Base64 {
* @throws NullPointerException if dataToEncode is null
* @since 2.1
*/
public static void encodeToFile(byte[] dataToEncode, String filename) throws java.io.IOException {
public static void encodeToFile(byte[] dataToEncode, String filename)
throws java.io.IOException {
if (dataToEncode == null)
throw new NullPointerException("Data to encode was null.");

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,7 +51,7 @@ public class Buffer<T extends Buffer<T>> {
}
}
public static class PlainBuffer
public static final class PlainBuffer
extends Buffer<PlainBuffer> {
public PlainBuffer() {
@@ -74,10 +74,15 @@ public class Buffer<T extends Buffer<T>> {
/** The default size for a {@code Buffer} (256 bytes) */
public static final int DEFAULT_SIZE = 256;
/** The maximum valid size of buffer (i.e. biggest power of two that can be represented as an int - 2^30) */
public static final int MAX_SIZE = (1 << 30);
protected static int getNextPowerOf2(int i) {
int j = 1;
while (j < i)
while (j < i) {
j <<= 1;
if (j <= 0) throw new IllegalArgumentException("Cannot get next power of 2; "+i+" is too large");
}
return j;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,8 +35,6 @@
*/
package net.schmizz.sshj.common;
import java.util.Arrays;
/** Utility functions for byte arrays. */
public class ByteArrayUtils {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -22,6 +22,7 @@ public interface ErrorNotifiable {
/** Utility functions. */
class Util {
/** Notify all {@code notifiables} of given {@code error}. */
public static void alertAll(SSHException error, ErrorNotifiable... notifiables) {
for (ErrorNotifiable notifiable : notifiables)

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,7 +32,6 @@ public enum KeyType {
/** SSH identifier for RSA keys */
RSA("ssh-rsa") {
@Override
public PublicKey readPubKeyFromBuffer(String type, Buffer<?> buf)
throws GeneralSecurityException {
@@ -64,7 +63,6 @@ public enum KeyType {
/** SSH identifier for DSA keys */
DSA("ssh-dss") {
@Override
public PublicKey readPubKeyFromBuffer(String type, Buffer<?> buf)
throws GeneralSecurityException {
@@ -100,7 +98,6 @@ public enum KeyType {
/** Unrecognized */
UNKNOWN("unknown") {
@Override
public PublicKey readPubKeyFromBuffer(String type, Buffer<?> buf)
throws GeneralSecurityException {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -37,7 +37,7 @@ package net.schmizz.sshj.common;
import java.util.Arrays;
public class SSHPacket
public final class SSHPacket
extends Buffer<SSHPacket> {
public SSHPacket() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -58,14 +58,15 @@ import java.security.Signature;
public class SecurityUtils {
private static class BouncyCastleRegistration {
public void run()
throws Exception {
if (java.security.Security.getProvider(BOUNCY_CASTLE) == null) {
LOG.info("Trying to register BouncyCastle as a JCE provider");
LOG.debug("Trying to register BouncyCastle as a JCE provider");
java.security.Security.addProvider(new BouncyCastleProvider());
MessageDigest.getInstance("MD5", BOUNCY_CASTLE);
KeyAgreement.getInstance("DH", BOUNCY_CASTLE);
LOG.info("Registration succeeded");
LOG.info("BouncyCastle registration succeeded");
} else
LOG.info("BouncyCastle already registered as a JCE provider");
securityProvider = BOUNCY_CASTLE;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -107,7 +107,7 @@ public class StreamCopier {
log.debug("Done copying from {}", in);
doneEvent.set();
} catch (IOException ioe) {
log.error("In pipe from {} to {}: " + ioe.toString(), in, out);
log.error("In pipe from {} to {}: {}", new Object[] { in, out, ioe });
doneEvent.deliverError(ioe);
}
}
@@ -136,7 +136,7 @@ public class StreamCopier {
final double timeSeconds = (System.currentTimeMillis() - startTime) / 1000.0;
final double sizeKiB = count / 1024.0;
log.info(sizeKiB + " KiB transferred in {} seconds ({} KiB/s)", timeSeconds, (sizeKiB / timeSeconds));
log.debug("{} KiB transferred in {} seconds ({} KiB/s)", new Object[] { sizeKiB, timeSeconds, (sizeKiB / timeSeconds) });
if (length != -1 && read == -1)
throw new IOException("Encountered EOF, could not transfer " + length + " bytes");
@@ -154,4 +154,4 @@ public class StreamCopier {
return count;
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -89,13 +89,13 @@ public interface Connection {
* @param wantReply whether a reply is requested
* @param specifics {@link SSHPacket} containing fields specific to the request
*
* @return a {@link net.schmizz.concurrent.Promise} for the reply data (in case {@code wantReply} is true) which allows waiting on the
* reply, or {@code null} if a reply is not requested.
* @return a {@link net.schmizz.concurrent.Promise} for the reply data (in case {@code wantReply} is true) which
* allows waiting on the reply, or {@code null} if a reply is not requested.
*
* @throws TransportException if there is an error sending the request
*/
public Promise<SSHPacket, ConnectionException> sendGlobalRequest(String name, boolean wantReply,
byte[] specifics)
byte[] specifics)
throws TransportException;
/**
@@ -125,14 +125,14 @@ public interface Connection {
void setMaxPacketSize(int maxPacketSize);
/** @return the size for the local window this connection recommends to any {@link Channel}'s that ask for it. */
int getWindowSize();
long getWindowSize();
/**
* Set the size for the local window this connection recommends to any {@link Channel}'s that ask for it.
*
* @param windowSize window size in bytes
*/
void setWindowSize(int windowSize);
void setWindowSize(long windowSize);
/** @return the associated {@link Transport}. */
Transport getTransport();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -51,7 +51,7 @@ public class ConnectionImpl
private final Queue<Promise<SSHPacket, ConnectionException>> globalReqPromises = new LinkedList<Promise<SSHPacket, ConnectionException>>();
private int windowSize = 2048 * 1024;
private long windowSize = 2048 * 1024;
private int maxPacketSize = 32 * 1024;
/**
@@ -65,7 +65,7 @@ public class ConnectionImpl
@Override
public void attach(Channel chan) {
log.info("Attaching `{}` channel (#{})", chan.getType(), chan.getID());
log.debug("Attaching `{}` channel (#{})", chan.getType(), chan.getID());
channels.put(chan.getID(), chan);
}
@@ -81,7 +81,7 @@ public class ConnectionImpl
@Override
public void forget(Channel chan) {
log.info("Forgetting `{}` channel (#{})", chan.getType(), chan.getID());
log.debug("Forgetting `{}` channel (#{})", chan.getType(), chan.getID());
channels.remove(chan.getID());
synchronized (internalSynchronizer) {
if (channels.isEmpty())
@@ -91,13 +91,13 @@ public class ConnectionImpl
@Override
public void forget(ForwardedChannelOpener opener) {
log.info("Forgetting opener for `{}` channels: {}", opener.getChannelType(), opener);
log.debug("Forgetting opener for `{}` channels: {}", opener.getChannelType(), opener);
openers.remove(opener.getChannelType());
}
@Override
public void attach(ForwardedChannelOpener opener) {
log.info("Attaching opener for `{}` channels: {}", opener.getChannelType(), opener);
log.debug("Attaching opener for `{}` channels: {}", opener.getChannelType(), opener);
openers.put(opener.getChannelType(), opener);
}
@@ -159,12 +159,12 @@ public class ConnectionImpl
}
@Override
public int getWindowSize() {
public long getWindowSize() {
return windowSize;
}
@Override
public void setWindowSize(int windowSize) {
public void setWindowSize(long windowSize) {
this.windowSize = windowSize;
}
@@ -187,7 +187,7 @@ public class ConnectionImpl
byte[] specifics)
throws TransportException {
synchronized (globalReqPromises) {
log.info("Making global request for `{}`", name);
log.debug("Making global request for `{}`", name);
trans.write(new SSHPacket(Message.GLOBAL_REQUEST).putString(name)
.putBoolean(wantReply)
.putRawBytes(specifics));

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,8 +35,8 @@
*/
package net.schmizz.sshj.connection.channel;
import net.schmizz.concurrent.Event;
import net.schmizz.concurrent.ErrorDeliveryUtil;
import net.schmizz.concurrent.Event;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.ByteArrayUtils;
import net.schmizz.sshj.common.DisconnectReason;
@@ -61,6 +61,8 @@ import java.util.concurrent.locks.ReentrantLock;
public abstract class AbstractChannel
implements Channel {
private static final int REMOTE_MAX_PACKET_SIZE_CEILING = 1024 * 1024;
/** Logger */
protected final Logger log = LoggerFactory.getLogger(getClass());
@@ -79,11 +81,11 @@ public abstract class AbstractChannel
private final Queue<Event<ConnectionException>> chanReqResponseEvents = new LinkedList<Event<ConnectionException>>();
/* The lock used by to create the open & close events */
private final ReentrantLock lock = new ReentrantLock();
private final ReentrantLock openCloseLock = new ReentrantLock();
/** Channel open event */
protected final Event<ConnectionException> open;
protected final Event<ConnectionException> openEvent;
/** Channel close event */
protected final Event<ConnectionException> close;
protected final Event<ConnectionException> closeEvent;
/* Access to these fields should be synchronized using this object */
private boolean eofSent;
@@ -112,15 +114,15 @@ public abstract class AbstractChannel
lwin = new Window.Local(conn.getWindowSize(), conn.getMaxPacketSize());
in = new ChannelInputStream(this, trans, lwin);
open = new Event<ConnectionException>("chan#" + id + " / " + "open", ConnectionException.chainer, lock);
close = new Event<ConnectionException>("chan#" + id + " / " + "close", ConnectionException.chainer, lock);
openEvent = new Event<ConnectionException>("chan#" + id + " / " + "open", ConnectionException.chainer, openCloseLock);
closeEvent = new Event<ConnectionException>("chan#" + id + " / " + "close", ConnectionException.chainer, openCloseLock);
}
protected void init(int recipient, int remoteWinSize, int remoteMaxPacketSize) {
protected void init(int recipient, long remoteWinSize, long remoteMaxPacketSize) {
this.recipient = recipient;
rwin = new Window.Remote(remoteWinSize, remoteMaxPacketSize);
rwin = new Window.Remote(remoteWinSize, (int) Math.min(remoteMaxPacketSize, REMOTE_MAX_PACKET_SIZE_CEILING));
out = new ChannelOutputStream(this, trans, rwin);
log.info("Initialized - {}", this);
log.debug("Initialized - {}", this);
}
@Override
@@ -144,7 +146,7 @@ public abstract class AbstractChannel
}
@Override
public int getLocalWinSize() {
public long getLocalWinSize() {
return lwin.getSize();
}
@@ -164,7 +166,7 @@ public abstract class AbstractChannel
}
@Override
public int getRemoteWinSize() {
public long getRemoteWinSize() {
return rwin.getSize();
}
@@ -218,7 +220,7 @@ public abstract class AbstractChannel
private void gotClose()
throws TransportException {
log.info("Got close");
log.debug("Got close");
try {
closeAllStreams();
sendClose();
@@ -236,11 +238,12 @@ public abstract class AbstractChannel
public void notifyError(SSHException error) {
log.debug("Channel #{} got notified of {}", getID(), error.toString());
ErrorDeliveryUtil.alertEvents(error, open, close);
ErrorDeliveryUtil.alertEvents(error, openEvent, closeEvent);
ErrorDeliveryUtil.alertEvents(error, chanReqResponseEvents);
in.notifyError(error);
out.notifyError(error);
if (out != null)
out.notifyError(error);
finishOff();
}
@@ -253,35 +256,37 @@ public abstract class AbstractChannel
@Override
public void close()
throws ConnectionException, TransportException {
lock.lock();
openCloseLock.lock();
try {
try {
sendClose();
} catch (TransportException e) {
if (!close.inError())
throw e;
if (isOpen()) {
try {
sendClose();
} catch (TransportException e) {
if (!closeEvent.inError())
throw e;
}
closeEvent.await(conn.getTimeout(), TimeUnit.SECONDS);
}
close.await(conn.getTimeout(), TimeUnit.SECONDS);
} finally {
lock.unlock();
openCloseLock.unlock();
}
}
public void join()
throws ConnectionException {
close.await();
closeEvent.await();
}
public void join(int timeout, TimeUnit unit)
throws ConnectionException {
close.await(timeout, unit);
closeEvent.await(timeout, unit);
}
protected synchronized void sendClose()
throws TransportException {
try {
if (!closeRequested) {
log.info("Sending close");
log.debug("Sending close");
trans.write(newBuffer(Message.CHANNEL_CLOSE));
}
} finally {
@@ -291,11 +296,11 @@ public abstract class AbstractChannel
@Override
public synchronized boolean isOpen() {
lock.lock();
openCloseLock.lock();
try {
return open.isSet() && !close.isSet() && !closeRequested;
return openEvent.isSet() && !closeEvent.isSet() && !closeRequested;
} finally {
lock.unlock();
openCloseLock.unlock();
}
}
@@ -308,24 +313,25 @@ public abstract class AbstractChannel
} catch (Buffer.BufferException be) {
throw new ConnectionException(be);
}
log.info("Got chan request for `{}`", reqType);
log.debug("Got chan request for `{}`", reqType);
handleRequest(reqType, buf);
}
private void gotWindowAdjustment(SSHPacket buf) throws ConnectionException {
final int howMuch;
private void gotWindowAdjustment(SSHPacket buf)
throws ConnectionException {
final long howMuch;
try {
howMuch = buf.readUInt32AsInt();
howMuch = buf.readUInt32();
} catch (Buffer.BufferException be) {
throw new ConnectionException(be);
}
log.info("Received window adjustment for {} bytes", howMuch);
log.debug("Received window adjustment for {} bytes", howMuch);
rwin.expand(howMuch);
}
protected void finishOff() {
conn.forget(this);
close.set();
closeEvent.set();
}
protected void gotExtendedData(SSHPacket buf)
@@ -362,42 +368,46 @@ public abstract class AbstractChannel
stream.receive(buf.array(), buf.rpos(), len);
}
protected synchronized Event<ConnectionException> sendChannelRequest(String reqType, boolean wantReply,
Buffer.PlainBuffer reqSpecific)
protected Event<ConnectionException> sendChannelRequest(String reqType, boolean wantReply,
Buffer.PlainBuffer reqSpecific)
throws TransportException {
log.info("Sending channel request for `{}`", reqType);
trans.write(
newBuffer(Message.CHANNEL_REQUEST)
.putString(reqType)
.putBoolean(wantReply)
.putBuffer(reqSpecific)
);
log.debug("Sending channel request for `{}`", reqType);
synchronized (chanReqResponseEvents) {
trans.write(
newBuffer(Message.CHANNEL_REQUEST)
.putString(reqType)
.putBoolean(wantReply)
.putBuffer(reqSpecific)
);
Event<ConnectionException> responseEvent = null;
if (wantReply) {
responseEvent = new Event<ConnectionException>("chan#" + id + " / " + "chanreq for " + reqType, ConnectionException.chainer, lock);
chanReqResponseEvents.add(responseEvent);
Event<ConnectionException> responseEvent = null;
if (wantReply) {
responseEvent = new Event<ConnectionException>("chan#" + id + " / " + "chanreq for " + reqType,
ConnectionException.chainer);
chanReqResponseEvents.add(responseEvent);
}
return responseEvent;
}
return responseEvent;
}
private synchronized void gotResponse(boolean success)
private void gotResponse(boolean success)
throws ConnectionException {
final Event<ConnectionException> responseEvent = chanReqResponseEvents.poll();
if (responseEvent != null) {
if (success)
responseEvent.set();
else
responseEvent.deliverError(new ConnectionException("Request failed"));
} else
throw new ConnectionException(
DisconnectReason.PROTOCOL_ERROR,
"Received response to channel request when none was requested");
synchronized (chanReqResponseEvents) {
final Event<ConnectionException> responseEvent = chanReqResponseEvents.poll();
if (responseEvent != null) {
if (success)
responseEvent.set();
else
responseEvent.deliverError(new ConnectionException("Request failed"));
} else
throw new ConnectionException(DisconnectReason.PROTOCOL_ERROR,
"Received response to channel request when none was requested");
}
}
private synchronized void gotEOF()
throws TransportException {
log.info("Got EOF");
log.debug("Got EOF");
eofGot = true;
eofInputStreams();
if (eofSent)
@@ -414,7 +424,7 @@ public abstract class AbstractChannel
throws TransportException {
try {
if (!closeRequested && !eofSent) {
log.info("Sending EOF");
log.debug("Sending EOF");
trans.write(newBuffer(Message.CHANNEL_EOF));
if (eofGot)
sendClose();
@@ -428,7 +438,7 @@ public abstract class AbstractChannel
@Override
public String toString() {
return "< " + type + " channel: id=" + id + ", recipient=" + recipient + ", localWin=" + lwin + ", remoteWin="
+ rwin + " >";
+ rwin + " >";
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,6 +32,7 @@ public interface Channel
/** Direct channels are those that are initiated by us. */
interface Direct
extends Channel {
/**
* Request opening this channel from remote end.
*
@@ -98,7 +99,7 @@ public interface Channel
int getLocalMaxPacketSize();
/** @return the current local window size. */
int getLocalWinSize();
long getLocalWinSize();
/** @return an {@code OutputStream} for this channel. */
OutputStream getOutputStream();
@@ -110,7 +111,7 @@ public interface Channel
int getRemoteMaxPacketSize();
/** @return the current remote window size. */
int getRemoteWinSize();
long getRemoteWinSize();
/** @return the channel type identifier. */
String getType();

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -116,7 +116,7 @@ public final class ChannelInputStream
public int read(byte[] b, int off, int len)
throws IOException {
synchronized (buf) {
for (; ;) {
for (; ; ) {
if (buf.available() > 0)
break;
if (eof)
@@ -159,11 +159,11 @@ public final class ChannelInputStream
private void checkWindow()
throws TransportException {
synchronized (win) {
final int adjustment = win.neededAdjustment();
final long adjustment = win.neededAdjustment();
if (adjustment > 0) {
log.info("Sending SSH_MSG_CHANNEL_WINDOW_ADJUST to #{} for {} bytes", chan.getRecipient(), adjustment);
log.debug("Sending SSH_MSG_CHANNEL_WINDOW_ADJUST to #{} for {} bytes", chan.getRecipient(), adjustment);
trans.write(new SSHPacket(Message.CHANNEL_WINDOW_ADJUST)
.putUInt32(chan.getRecipient()).putUInt32(adjustment));
.putUInt32(chan.getRecipient()).putUInt32(adjustment));
win.expand(adjustment);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -35,12 +35,14 @@
*/
package net.schmizz.sshj.connection.channel;
import net.schmizz.sshj.common.Buffer;
import net.schmizz.sshj.common.ErrorNotifiable;
import net.schmizz.sshj.common.Message;
import net.schmizz.sshj.common.SSHException;
import net.schmizz.sshj.common.SSHPacket;
import net.schmizz.sshj.connection.ConnectionException;
import net.schmizz.sshj.transport.Transport;
import net.schmizz.sshj.transport.TransportException;
import java.io.IOException;
import java.io.OutputStream;
@@ -56,26 +58,92 @@ public final class ChannelOutputStream
private final Channel chan;
private final Transport trans;
private final Window.Remote win;
private final SSHPacket buffer = new SSHPacket();
private final DataBuffer buffer = new DataBuffer();
private final byte[] b = new byte[1];
private int bufferLength;
private boolean closed;
private SSHException error;
private final class DataBuffer {
private final int headerOffset;
private final int dataOffset;
private final SSHPacket packet = new SSHPacket(Message.CHANNEL_DATA);
private final Buffer.PlainBuffer leftOvers = new Buffer.PlainBuffer();
DataBuffer() {
headerOffset = packet.rpos();
packet.putUInt32(0); // recipient
packet.putUInt32(0); // data length
dataOffset = packet.wpos();
}
int write(byte[] data, int off, int len)
throws TransportException, ConnectionException {
final int bufferSize = packet.wpos() - dataOffset;
if (bufferSize >= win.getMaxPacketSize()) {
flush(bufferSize);
return 0;
} else {
final int n = Math.min(len - off, win.getMaxPacketSize() - bufferSize);
packet.putRawBytes(data, off, n);
return n;
}
}
void flush()
throws TransportException, ConnectionException {
flush(packet.wpos() - dataOffset);
}
void flush(int bufferSize)
throws TransportException, ConnectionException {
while (bufferSize > 0) {
long remoteWindowSize = win.getSize();
if (remoteWindowSize == 0)
remoteWindowSize = win.awaitExpansion(remoteWindowSize);
// We can only write the min. of
// a) how much data we have
// b) the max packet size
// c) what the current window size will allow
final int writeNow = Math.min(bufferSize, (int) Math.min(win.getMaxPacketSize(), remoteWindowSize));
packet.wpos(headerOffset);
packet.putMessageID(Message.CHANNEL_DATA);
packet.putUInt32(chan.getRecipient());
packet.putUInt32(writeNow);
packet.wpos(dataOffset + writeNow);
final int leftOverBytes = bufferSize - writeNow;
if (leftOverBytes > 0) {
leftOvers.putRawBytes(packet.array(), packet.wpos(), leftOverBytes);
}
trans.write(packet);
win.consume(writeNow);
packet.rpos(headerOffset);
packet.wpos(dataOffset);
if (leftOverBytes > 0) {
packet.putBuffer(leftOvers);
leftOvers.clear();
}
bufferSize = leftOverBytes;
}
}
}
public ChannelOutputStream(Channel chan, Transport trans, Window.Remote win) {
this.chan = chan;
this.trans = trans;
this.win = win;
prepBuffer();
}
private void prepBuffer() {
bufferLength = 0;
buffer.rpos(5);
buffer.wpos(5);
buffer.putMessageID(Message.CHANNEL_DATA);
buffer.putUInt32(0); // meant to be recipient
buffer.putUInt32(0); // meant to be data length
}
@Override
@@ -86,19 +154,13 @@ public final class ChannelOutputStream
}
@Override
public synchronized void write(byte[] data, int off, int len)
public synchronized void write(final byte[] data, int off, int len)
throws IOException {
checkClose();
while (len > 0) {
final int x = Math.min(len, win.getMaxPacketSize() - bufferLength);
if (x <= 0) {
flush();
continue;
}
buffer.putRawBytes(data, off, x);
bufferLength += x;
off += x;
len -= x;
final int n = buffer.write(data, off, len);
off += n;
len -= n;
}
}
@@ -107,55 +169,44 @@ public final class ChannelOutputStream
this.error = error;
}
private synchronized void checkClose()
private void checkClose()
throws SSHException {
if (closed)
if (closed) {
if (error != null)
throw error;
else
throw new ConnectionException("Stream closed");
}
}
@Override
public synchronized void close()
throws IOException {
if (!closed)
if (!closed) {
try {
flush();
buffer.flush();
chan.sendEOF();
} finally {
setClosed();
}
}
}
public synchronized void setClosed() {
closed = true;
}
/**
* Send all data currently buffered. If window space is exhausted in the process, this will block
* until it is expanded by the server.
*
* @throws IOException
*/
@Override
public synchronized void flush()
throws IOException {
checkClose();
if (bufferLength <= 0) // No data to send
return;
putRecipientAndLength();
try {
win.waitAndConsume(bufferLength);
trans.write(buffer);
} finally {
prepBuffer();
}
}
private void putRecipientAndLength() {
final int origPos = buffer.wpos();
buffer.wpos(6);
buffer.putUInt32(chan.getRecipient());
buffer.putUInt32(bufferLength);
buffer.wpos(origPos);
buffer.flush();
}
@Override

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -43,8 +43,8 @@ public class SocketStreamCopyMonitor
}
public static void monitor(final int frequency, final TimeUnit unit,
final Event<IOException> x, final Event<IOException> y,
final Channel channel, final Socket socket) {
final Event<IOException> x, final Event<IOException> y,
final Channel channel, final Socket socket) {
new SocketStreamCopyMonitor(new Runnable() {
public void run() {
try {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -28,17 +28,17 @@ public abstract class Window {
protected final int maxPacketSize;
protected int size;
protected long size;
public Window(int initialWinSize, int maxPacketSize) {
public Window(long initialWinSize, int maxPacketSize) {
size = initialWinSize;
this.maxPacketSize = maxPacketSize;
}
public void expand(int inc) {
public void expand(long inc) {
synchronized (lock) {
log.debug("Increasing by {} up to {}", inc, size);
size += inc;
log.debug("Increasing by {} up to {}", inc, size);
lock.notifyAll();
}
}
@@ -47,16 +47,19 @@ public abstract class Window {
return maxPacketSize;
}
public int getSize() {
return size;
public long getSize() {
synchronized (lock) {
return size;
}
}
public void consume(int dec) {
public void consume(long dec)
throws ConnectionException {
synchronized (lock) {
log.debug("Consuming by " + dec + " down to " + size);
size -= dec;
log.debug("Consuming by {} down to {}", dec, size);
if (size < 0)
throw new SSHRuntimeException("Window consumed to below 0");
throw new ConnectionException("Window consumed to below 0");
}
}
@@ -69,22 +72,30 @@ public abstract class Window {
public static final class Remote
extends Window {
public Remote(int initialWinSize, int maxPacketSize) {
public Remote(long initialWinSize, int maxPacketSize) {
super(initialWinSize, maxPacketSize);
}
public void waitAndConsume(int howMuch)
public long awaitExpansion(long was)
throws ConnectionException {
synchronized (lock) {
while (size < howMuch) {
log.debug("Waiting, need window space for {} bytes", howMuch);
while (size <= was) {
log.debug("Waiting, need size to grow from {} bytes", was);
try {
lock.wait();
} catch (InterruptedException ie) {
throw new ConnectionException(ie);
}
}
consume(howMuch);
return size;
}
}
public void consume(long howMuch) {
try {
super.consume(howMuch);
} catch (ConnectionException e) { // It's a bug if we consume more than remote allowed
throw new SSHRuntimeException(e);
}
}
@@ -94,18 +105,18 @@ public abstract class Window {
public static final class Local
extends Window {
private final int initialSize;
private final int threshold;
private final long initialSize;
private final long threshold;
public Local(int initialWinSize, int maxPacketSize) {
public Local(long initialWinSize, int maxPacketSize) {
super(initialWinSize, maxPacketSize);
this.initialSize = initialWinSize;
threshold = Math.min(maxPacketSize * 20, initialSize / 4);
}
public int neededAdjustment() {
public long neededAdjustment() {
synchronized (lock) {
return (size - threshold <= 0) ? (initialSize - size) : 0;
return (size <= threshold) ? (initialSize - size) : 0;
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -65,23 +65,23 @@ public abstract class AbstractDirectChannel
public void open()
throws ConnectionException, TransportException {
trans.write(buildOpenReq());
open.await(conn.getTimeout(), TimeUnit.SECONDS);
openEvent.await(conn.getTimeout(), TimeUnit.SECONDS);
}
private void gotOpenConfirmation(SSHPacket buf)
throws ConnectionException {
try {
init(buf.readUInt32AsInt(), buf.readUInt32AsInt(), buf.readUInt32AsInt());
init(buf.readUInt32AsInt(), buf.readUInt32(), buf.readUInt32());
} catch (Buffer.BufferException be) {
throw new ConnectionException(be);
}
open.set();
openEvent.set();
}
private void gotOpenFailure(SSHPacket buf)
throws ConnectionException {
try {
open.deliverError(new OpenFailException(getType(), buf.readUInt32AsInt(), buf.readString()));
openEvent.deliverError(new OpenFailException(getType(), buf.readUInt32AsInt(), buf.readString()));
} catch (Buffer.BufferException be) {
throw new ConnectionException(be);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,104 +19,104 @@ import net.schmizz.concurrent.Event;
import net.schmizz.sshj.common.SSHPacket;
import net.schmizz.sshj.common.StreamCopier;
import net.schmizz.sshj.connection.Connection;
import net.schmizz.sshj.connection.ConnectionException;
import net.schmizz.sshj.connection.channel.SocketStreamCopyMonitor;
import net.schmizz.sshj.transport.TransportException;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import javax.net.ServerSocketFactory;
import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketAddress;
import java.util.concurrent.TimeUnit;
public class LocalPortForwarder {
private class DirectTCPIPChannel
extends AbstractDirectChannel {
public static class Parameters {
private final Socket sock;
private final String localHost;
private final int localPort;
private final String remoteHost;
private final int remotePort;
private DirectTCPIPChannel(Connection conn, Socket sock) {
super(conn, "direct-tcpip");
this.sock = sock;
public Parameters(String localHost, int localPort, String remoteHost, int remotePort) {
this.localHost = localHost;
this.localPort = localPort;
this.remoteHost = remoteHost;
this.remotePort = remotePort;
}
private void start()
public String getRemoteHost() {
return remoteHost;
}
public int getRemotePort() {
return remotePort;
}
public String getLocalHost() {
return localHost;
}
public int getLocalPort() {
return localPort;
}
}
public static class DirectTCPIPChannel
extends AbstractDirectChannel {
protected final Socket socket;
protected final Parameters parameters;
public DirectTCPIPChannel(Connection conn, Socket socket, Parameters parameters) {
super(conn, "direct-tcpip");
this.socket = socket;
this.parameters = parameters;
}
protected void start()
throws IOException {
sock.setSendBufferSize(getLocalMaxPacketSize());
sock.setReceiveBufferSize(getRemoteMaxPacketSize());
final Event<IOException> soc2chan = new StreamCopier(sock.getInputStream(), getOutputStream())
socket.setSendBufferSize(getLocalMaxPacketSize());
socket.setReceiveBufferSize(getRemoteMaxPacketSize());
final Event<IOException> soc2chan = new StreamCopier(socket.getInputStream(), getOutputStream())
.bufSize(getRemoteMaxPacketSize())
.spawnDaemon("soc2chan");
final Event<IOException> chan2soc = new StreamCopier(getInputStream(), sock.getOutputStream())
final Event<IOException> chan2soc = new StreamCopier(getInputStream(), socket.getOutputStream())
.bufSize(getLocalMaxPacketSize())
.spawnDaemon("chan2soc");
SocketStreamCopyMonitor.monitor(5, TimeUnit.SECONDS, soc2chan, chan2soc, this, sock);
}
SocketStreamCopyMonitor.monitor(5, TimeUnit.SECONDS, soc2chan, chan2soc, this, socket);
}
@Override
protected SSHPacket buildOpenReq() {
return super.buildOpenReq()
.putString(host)
.putUInt32(port)
.putString(ss.getInetAddress().getHostAddress())
.putUInt32(ss.getLocalPort());
.putString(parameters.getRemoteHost())
.putUInt32(parameters.getRemotePort())
.putString(parameters.getLocalHost())
.putUInt32(parameters.getLocalPort());
}
}
private final Logger log = LoggerFactory.getLogger(getClass());
private final Logger log = LoggerFactory.getLogger(LocalPortForwarder.class);
private final Connection conn;
private final ServerSocket ss;
private final String host;
private final int port;
private final Parameters parameters;
private final ServerSocket serverSocket;
/**
* Create a local port forwarder with specified binding ({@code listeningAddr}. It does not, however, start
* listening unless {@link #listen() explicitly told to}. The {@link javax.net.ServerSocketFactory#getDefault()
* default} server socket factory is used.
*
* @param conn {@link Connection} implementation
* @param listeningAddr {@link SocketAddress} this forwarder will listen on, if {@code null} then an ephemeral port
* and valid local address will be picked to bind the server socket
* @param host what host the SSH server will further forward to
* @param port port on {@code toHost}
*
* @throws IOException if there is an error binding on specified {@code listeningAddr}
*/
public LocalPortForwarder(Connection conn, SocketAddress listeningAddr, String host, int port)
throws IOException {
this(ServerSocketFactory.getDefault(), conn, listeningAddr, host, port);
}
/**
* Create a local port forwarder with specified binding ({@code listeningAddr}. It does not, however, start
* listening unless {@link #listen() explicitly told to}.
*
* @param ssf factory to use for creating the server socket
* @param conn {@link Connection} implementation
* @param listeningAddr {@link SocketAddress} this forwarder will listen on, if {@code null} then an ephemeral port
* and valid local address will be picked to bind the server socket
* @param host what host the SSH server will further forward to
* @param port port on {@code toHost}
*
* @throws IOException if there is an error binding on specified {@code listeningAddr}
*/
public LocalPortForwarder(ServerSocketFactory ssf, Connection conn, SocketAddress listeningAddr, String host, int port)
throws IOException {
public LocalPortForwarder(Connection conn, Parameters parameters, ServerSocket serverSocket) {
this.conn = conn;
this.host = host;
this.port = port;
this.ss = ssf.createServerSocket();
ss.setReceiveBufferSize(conn.getMaxPacketSize());
ss.bind(listeningAddr);
this.parameters = parameters;
this.serverSocket = serverSocket;
}
/** @return the address to which this forwarder is bound for listening */
public SocketAddress getListeningAddress() {
return ss.getLocalSocketAddress();
protected DirectTCPIPChannel openChannel(Socket socket)
throws TransportException, ConnectionException {
final DirectTCPIPChannel chan = new DirectTCPIPChannel(conn, socket, parameters);
chan.open();
return chan;
}
/**
@@ -126,16 +126,13 @@ public class LocalPortForwarder {
*/
public void listen()
throws IOException {
log.info("Listening on {}", ss.getLocalSocketAddress());
Socket sock;
log.info("Listening on {}", serverSocket.getLocalSocketAddress());
while (!Thread.currentThread().isInterrupted()) {
sock = ss.accept();
log.info("Got connection from {}", sock.getRemoteSocketAddress());
DirectTCPIPChannel chan = new DirectTCPIPChannel(conn, sock);
chan.open();
chan.start();
final Socket socket = serverSocket.accept();
log.debug("Got connection from {}", socket.getRemoteSocketAddress());
openChannel(socket).start();
}
log.info("Interrupted!");
log.debug("Interrupted!");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,7 +19,6 @@ import net.schmizz.sshj.connection.ConnectionException;
import net.schmizz.sshj.connection.channel.Channel;
import net.schmizz.sshj.transport.TransportException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Map;
@@ -81,12 +80,6 @@ public interface Session
void signal(Signal signal)
throws TransportException;
@Deprecated
String getOutputAsString() throws IOException;
@Deprecated
String getErrorAsString() throws IOException;
}
/** Shell API. */
@@ -132,6 +125,7 @@ public interface Session
/** Subsystem API. */
interface Subsystem
extends Channel {
Integer getExitStatus();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -46,7 +46,6 @@ import net.schmizz.sshj.connection.ConnectionException;
import net.schmizz.sshj.connection.channel.ChannelInputStream;
import net.schmizz.sshj.transport.TransportException;
import java.io.IOException;
import java.io.InputStream;
import java.util.Collections;
import java.util.Map;
@@ -76,7 +75,7 @@ public class SessionChannel
@Override
public void allocateDefaultPTY()
throws ConnectionException, TransportException {
allocatePTY("dummy", 80, 24, 0, 0, Collections.<PTYMode, Integer>emptyMap());
allocatePTY("vt100", 80, 24, 0, 0, Collections.<PTYMode, Integer>emptyMap());
}
@Override
@@ -104,7 +103,7 @@ public class SessionChannel
public void changeWindowDimensions(int cols, int rows, int width, int height)
throws TransportException {
sendChannelRequest(
"pty-req",
"window-change",
false,
new Buffer.PlainBuffer()
.putUInt32(cols)
@@ -255,18 +254,4 @@ public class SessionChannel
throw new SSHRuntimeException("This session channel is all used up");
}
@Override
@Deprecated
public String getOutputAsString()
throws IOException {
return IOUtils.readFully(getInputStream()).toString();
}
@Override
@Deprecated
public String getErrorAsString()
throws IOException {
return IOUtils.readFully(getErrorStream()).toString();
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -54,8 +54,9 @@ public abstract class AbstractForwardedChannel
* First 2 args are standard; the others can be parsed from a CHANNEL_OPEN packet.
*/
protected AbstractForwardedChannel(Connection conn, String type, int recipient, int remoteWinSize,
int remoteMaxPacketSize, String origIP, int origPort) {
protected AbstractForwardedChannel(Connection conn, String type,
int recipient, long remoteWinSize, long remoteMaxPacketSize,
String origIP, int origPort) {
super(conn, type);
this.origIP = origIP;
this.origPort = origPort;
@@ -65,20 +66,20 @@ public abstract class AbstractForwardedChannel
@Override
public void confirm()
throws TransportException {
log.info("Confirming `{}` channel #{}", getType(), getID());
log.debug("Confirming `{}` channel #{}", getType(), getID());
// Must ensure channel is attached before confirming, data could start coming in immediately!
conn.attach(this);
trans.write(newBuffer(Message.CHANNEL_OPEN_CONFIRMATION)
.putUInt32(getID())
.putUInt32(getLocalWinSize())
.putUInt32(getLocalMaxPacketSize()));
open.set();
.putUInt32(getID())
.putUInt32(getLocalWinSize())
.putUInt32(getLocalMaxPacketSize()));
openEvent.set();
}
@Override
public void reject(Reason reason, String message)
throws TransportException {
log.info("Rejecting `{}` channel: {}", getType(), message);
log.debug("Rejecting `{}` channel: {}", getType(), message);
conn.sendOpenFailure(getRecipient(), reason, message);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,18 +39,18 @@ public class RemotePortForwarder
* address (or domain name) and port on which connections for forwarding
* are to be accepted. Some strings used for 'address to bind' have
* special-case semantics.
* <p/>
*
* o &quot;&quot; means that connections are to be accepted on all protocol
* families supported by the SSH implementation.
* <p/>
*
* o &quot;0.0.0.0&quot; means to listen on all IPv4 addresses.
* <p/>
*
* o &quot;::&quot; means to listen on all IPv6 addresses.
* <p/>
*
* o &quot;localhost&quot; means to listen on all protocol families supported by
* the SSH implementation on loopback addresses only ([RFC3330] and
* [RFC3513]).
* <p/>
*
* o &quot;127.0.0.1&quot; and &quot;::1&quot; indicate listening on the loopback
* interfaces for IPv4 and IPv6, respectively.
* </pre>
@@ -127,7 +127,8 @@ public class RemotePortForwarder
private final Forward fwd;
public ForwardedTCPIPChannel(Connection conn, int recipient, int remoteWinSize, int remoteMaxPacketSize,
public ForwardedTCPIPChannel(Connection conn,
int recipient, long remoteWinSize, long remoteMaxPacketSize,
Forward fwd, String origIP, int origPort) {
super(conn, TYPE, recipient, remoteWinSize, remoteMaxPacketSize, origIP, origPort);
this.fwd = fwd;
@@ -198,9 +199,9 @@ public class RemotePortForwarder
protected SSHPacket req(String reqName, Forward forward)
throws ConnectionException, TransportException {
final byte[] specifics = new Buffer.PlainBuffer().putString(forward.address).putUInt32(forward.port)
.getCompactData();
.getCompactData();
return conn.sendGlobalRequest(reqName, true, specifics)
.retrieve(conn.getTimeout(), TimeUnit.SECONDS);
.retrieve(conn.getTimeout(), TimeUnit.SECONDS);
}
/** @return the active forwards. */
@@ -217,7 +218,7 @@ public class RemotePortForwarder
throws ConnectionException, TransportException {
final ForwardedTCPIPChannel chan;
try {
chan = new ForwardedTCPIPChannel(conn, buf.readUInt32AsInt(), buf.readUInt32AsInt(), buf.readUInt32AsInt(),
chan = new ForwardedTCPIPChannel(conn, buf.readUInt32AsInt(), buf.readUInt32(), buf.readUInt32(),
new Forward(buf.readString(), buf.readUInt32AsInt()),
buf.readString(), buf.readUInt32AsInt());
} catch (Buffer.BufferException be) {
@@ -227,7 +228,7 @@ public class RemotePortForwarder
callListener(listeners.get(chan.getParentForward()), chan);
else
chan.reject(OpenFailException.Reason.ADMINISTRATIVELY_PROHIBITED, "Forwarding was not requested on `"
+ chan.getParentForward() + "`");
+ chan.getParentForward() + "`");
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -44,7 +44,7 @@ public class SocketForwardingConnectListener
@Override
public void gotConnect(Channel.Forwarded chan)
throws IOException {
log.info("New connection from " + chan.getOriginatorIP() + ":" + chan.getOriginatorPort());
log.debug("New connection from {}:{}", chan.getOriginatorIP(), chan.getOriginatorPort());
final Socket sock = new Socket();
sock.setSendBufferSize(chan.getLocalMaxPacketSize());
@@ -66,4 +66,4 @@ public class SocketForwardingConnectListener
SocketStreamCopyMonitor.monitor(5, TimeUnit.SECONDS, chan2soc, soc2chan, chan, sock);
}
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -34,8 +34,9 @@ public class X11Forwarder
public static final String TYPE = "x11";
public X11Channel(Connection conn, int recipient, int remoteWinSize, int remoteMaxPacketSize, String origIP,
int origPort) {
public X11Channel(Connection conn,
int recipient, long remoteWinSize, long remoteMaxPacketSize,
String origIP, int origPort) {
super(conn, TYPE, recipient, remoteWinSize, remoteMaxPacketSize, origIP, origPort);
}
@@ -58,8 +59,7 @@ public class X11Forwarder
throws ConnectionException, TransportException {
try {
callListener(listener, new X11Channel(conn,
buf.readUInt32AsInt(),
buf.readUInt32AsInt(), buf.readUInt32AsInt(),
buf.readUInt32AsInt(), buf.readUInt32(), buf.readUInt32(),
buf.readString(), buf.readUInt32AsInt()));
} catch (Buffer.BufferException be) {
throw new ConnectionException(be);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -74,7 +74,7 @@ public class FileMode {
}
public int getTypeMask() {
return mask & 0770000;
return mask & 0170000;
}
public int getPermissionsMask() {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -56,24 +56,25 @@ public class PacketReader
throws IOException {
readIntoBuffer(lenBuf, 0, lenBuf.length);
return (int) (lenBuf[0] << 24 & 0xff000000L
| lenBuf[1] << 16 & 0x00ff0000L
| lenBuf[2] << 8 & 0x0000ff00L
| lenBuf[3] & 0x000000ffL);
final long len = (lenBuf[0] << 24 & 0xff000000L
| lenBuf[1] << 16 & 0x00ff0000L
| lenBuf[2] << 8 & 0x0000ff00L
| lenBuf[3] & 0x000000ffL);
if (len > SFTPPacket.MAX_SIZE) {
throw new IllegalStateException("Invalid packet: indicated length "+len+" too large");
}
return (int) len;
}
public SFTPPacket<Response> readPacket()
throws IOException {
int len = getPacketLength();
packet.rpos(0);
packet.wpos(0);
final int len = getPacketLength();
packet.clear();
packet.ensureCapacity(len);
readIntoBuffer(packet.array(), 0, len);
packet.wpos(len);
return packet;
}
@@ -97,7 +98,7 @@ public class PacketReader
log.debug("Received {} packet", resp.getType());
if (promise == null)
throw new SFTPException("Received [" + resp.readType() + "] response for request-id " + resp.getRequestID()
+ ", no such request was made");
+ ", no such request was made");
else
promise.deliver(resp);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -19,15 +19,27 @@ import java.io.IOException;
public class PathHelper {
public interface Canonicalizer {
String canonicalize(String path)
throws IOException;
}
public static final String DEFAULT_PATH_SEPARATOR = "/";
private final SFTPEngine engine;
private final Canonicalizer canonicalizer;
private final String pathSep;
private String dotDir;
public PathHelper(SFTPEngine engine, String pathSep) {
this.engine = engine;
private synchronized String getDotDir() // cached
throws IOException {
return (dotDir != null) ? dotDir : (dotDir = canonicalizer.canonicalize("."));
}
public PathHelper(Canonicalizer canonicalizer, String pathSep) {
this.canonicalizer = canonicalizer;
this.pathSep = pathSep;
}
@@ -47,37 +59,33 @@ public class PathHelper {
return new PathComponents(parent, name, pathSep);
}
public PathComponents getComponents(String path)
/**
* Divide the path into {@code PathComponents(parent, name)} while making sure {@code name != "." && name != ".."}
*
* @param path to convert
*
* @return PathComponents
*
* @throws IOException
*/
public PathComponents getComponents(final String path)
throws IOException {
if (path.isEmpty() || path.equals("."))
if (path.equals(pathSep))
return getComponents("", "");
if (path.isEmpty() || path.equals(".") || path.equals("." + pathSep))
return getComponents(getDotDir());
final int lastSlash = path.lastIndexOf(pathSep);
final String withoutTrailSep = trimTrailingSeparator(path);
final int lastSep = withoutTrailSep.lastIndexOf(pathSep);
final String parent = (lastSep == -1) ? "" : withoutTrailSep.substring(0, lastSep);
final String name = (lastSep == -1) ? withoutTrailSep : withoutTrailSep.substring(lastSep + pathSep.length());
if (lastSlash == -1) // Relative path
if (path.equals(".."))
return getComponents(canon(path));
else
return getComponents(getDotDir(), path);
final String name = path.substring(lastSlash + pathSep.length());
if (name.equals(".") || name.equals(".."))
return getComponents(canon(path));
else {
final String parent = path.substring(0, lastSlash);
if (name.equals(".") || name.equals("..")) {
return getComponents(canonicalizer.canonicalize(path));
} else {
return getComponents(parent, name);
}
}
private synchronized String getDotDir()
throws IOException {
return (dotDir != null) ? dotDir : (dotDir = canon("."));
}
private String canon(String path)
throws IOException {
return engine.canonicalize(path);
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -32,7 +32,7 @@ public class RemoteDirectory
throws IOException {
List<RemoteResourceInfo> rri = new LinkedList<RemoteResourceInfo>();
loop:
for (; ;) {
for (; ; ) {
Response res = requester.doRequest(newRequest(PacketType.READDIR));
switch (res.getType()) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -39,8 +39,8 @@ public class RemoteFile
public FileAttributes fetchAttributes()
throws IOException {
return requester.doRequest(newRequest(PacketType.FSTAT))
.ensurePacketTypeIs(PacketType.ATTRS)
.readFileAttributes();
.ensurePacketTypeIs(PacketType.ATTRS)
.readFileAttributes();
}
public long length()
@@ -74,9 +74,9 @@ public class RemoteFile
public void write(long fileOffset, byte[] data, int off, int len)
throws IOException {
requester.doRequest(newRequest(PacketType.WRITE)
.putUInt64(fileOffset)
.putUInt32(len - off)
.putRawBytes(data, off, len)
.putUInt64(fileOffset)
.putUInt32(len - off)
.putRawBytes(data, off, len)
).ensureStatusPacketIsOK();
}
@@ -87,12 +87,12 @@ public class RemoteFile
public int getOutgoingPacketOverhead() {
return 1 + // packet type
4 + // request id
4 + // next length
handle.length() + // next
8 + // file offset
4 + // data length
4; // packet length
4 + // request id
4 + // next length
handle.length() + // next
8 + // file offset
4 + // data length
4; // packet length
}
public class RemoteFileOutputStream

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -48,7 +48,7 @@ public abstract class RemoteResource
@Override
public void close()
throws IOException {
log.info("Closing `{}`", this);
log.debug("Closing `{}`", this);
requester.doRequest(newRequest(PacketType.CLOSE)).ensureStatusPacketIsOK();
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@ package net.schmizz.sshj.sftp;
import net.schmizz.concurrent.Promise;
public class Request
public final class Request
extends SFTPPacket<Request> {
private final PacketType type;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -17,7 +17,7 @@ package net.schmizz.sshj.sftp;
import net.schmizz.sshj.common.Buffer;
public class Response
public final class Response
extends SFTPPacket<Response> {
public static enum StatusCode {
@@ -51,7 +51,8 @@ public class Response
private final PacketType type;
private final long reqID;
public Response(Buffer<Response> pk, int protocolVersion) throws SFTPException {
public Response(Buffer<Response> pk, int protocolVersion)
throws SFTPException {
super(pk);
this.protocolVersion = protocolVersion;
this.type = readType();
@@ -74,7 +75,8 @@ public class Response
return type;
}
public StatusCode readStatusCode() throws SFTPException {
public StatusCode readStatusCode()
throws SFTPException {
try {
return StatusCode.fromInt(readUInt32AsInt());
} catch (BufferException be) {

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ public class SFTPClient
return engine;
}
public SFTPFileTransfer getFileTansfer() {
public SFTPFileTransfer getFileTransfer() {
return xfer;
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -56,11 +56,18 @@ public class SFTPEngine
this(ssh, PathHelper.DEFAULT_PATH_SEPARATOR);
}
public SFTPEngine(SessionFactory ssh, String pathSep) throws SSHException {
public SFTPEngine(SessionFactory ssh, String pathSep)
throws SSHException {
sub = ssh.startSession().startSubsystem("sftp");
out = sub.getOutputStream();
reader = new PacketReader(this);
pathHelper = new PathHelper(this, pathSep);
pathHelper = new PathHelper(new PathHelper.Canonicalizer() {
@Override
public String canonicalize(String path)
throws IOException {
return SFTPEngine.this.canonicalize(path);
}
}, pathSep);
}
public SFTPEngine init()
@@ -74,7 +81,7 @@ public class SFTPEngine
throw new SFTPException("Expected INIT packet, received: " + type);
operativeVersion = response.readUInt32AsInt();
log.info("Server version {}", operativeVersion);
log.debug("Server version {}", operativeVersion);
if (MAX_SUPPORTED_VERSION < operativeVersion)
throw new SFTPException("Server reported incompatible protocol version: " + operativeVersion);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -38,15 +38,24 @@ public class SFTPFileTransfer
private volatile LocalFileFilter uploadFilter;
private volatile RemoteResourceFilter downloadFilter;
private volatile boolean preserveAttributes = true;
public SFTPFileTransfer(SFTPEngine engine) {
this.engine = engine;
}
public boolean getPreserveAttributes() {
return preserveAttributes;
}
public void setPreserveAttributes(boolean preserveAttributes) {
this.preserveAttributes = preserveAttributes;
}
@Override
public void upload(String source, String dest)
throws IOException {
new Uploader().upload(new FileSystemFile(source), dest);
upload(new FileSystemFile(source), dest);
}
@Override
@@ -58,7 +67,7 @@ public class SFTPFileTransfer
@Override
public void upload(LocalSourceFile localFile, String remotePath)
throws IOException {
new Uploader().upload(localFile, remotePath);
new Uploader().upload(getTransferListener(), localFile, remotePath);
}
@Override
@@ -66,7 +75,7 @@ public class SFTPFileTransfer
throws IOException {
final PathComponents pathComponents = engine.getPathHelper().getComponents(source);
final FileAttributes attributes = engine.stat(source);
new Downloader().download(new RemoteResourceInfo(pathComponents, attributes), dest);
new Downloader().download(getTransferListener(), new RemoteResourceInfo(pathComponents, attributes), dest);
}
public void setUploadFilter(LocalFileFilter uploadFilter) {
@@ -87,46 +96,47 @@ public class SFTPFileTransfer
private class Downloader {
private final TransferListener listener = getTransferListener();
private void download(final RemoteResourceInfo remote, final LocalDestFile local)
private void download(final TransferListener listener,
final RemoteResourceInfo remote,
final LocalDestFile local)
throws IOException {
final LocalDestFile adjustedFile;
switch (remote.getAttributes().getType()) {
case DIRECTORY:
listener.startedDir(remote.getName());
adjustedFile = downloadDir(remote, local);
listener.finishedDir();
adjustedFile = downloadDir(listener.directory(remote.getName()), remote, local);
break;
case UNKNOWN:
log.warn("Server did not supply information about the type of file at `{}` " +
"-- assuming it is a regular file!", remote.getPath());
case REGULAR:
listener.startedFile(remote.getName(), remote.getAttributes().getSize());
adjustedFile = downloadFile(remote, local);
listener.finishedFile();
adjustedFile = downloadFile(listener.file(remote.getName(), remote.getAttributes().getSize()),
remote, local);
break;
default:
throw new IOException(remote + " is not a regular file or directory");
}
copyAttributes(remote, adjustedFile);
if (getPreserveAttributes())
copyAttributes(remote, adjustedFile);
}
private LocalDestFile downloadDir(final RemoteResourceInfo remote, final LocalDestFile local)
private LocalDestFile downloadDir(final TransferListener listener,
final RemoteResourceInfo remote,
final LocalDestFile local)
throws IOException {
final LocalDestFile adjusted = local.getTargetDirectory(remote.getName());
final RemoteDirectory rd = engine.openDir(remote.getPath());
try {
for (RemoteResourceInfo rri : rd.scan(getDownloadFilter()))
download(rri, adjusted.getChild(rri.getName()));
download(listener, rri, adjusted.getChild(rri.getName()));
} finally {
rd.close();
}
return adjusted;
}
private LocalDestFile downloadFile(final RemoteResourceInfo remote, final LocalDestFile local)
private LocalDestFile downloadFile(final StreamCopier.Listener listener,
final RemoteResourceInfo remote,
final LocalDestFile local)
throws IOException {
final LocalDestFile adjusted = local.getTargetFile(remote.getName());
final RemoteFile rf = engine.open(remote.getPath());
@@ -161,33 +171,34 @@ public class SFTPFileTransfer
private class Uploader {
private final TransferListener listener = getTransferListener();
private void upload(LocalSourceFile local, String remote)
private void upload(final TransferListener listener,
final LocalSourceFile local,
final String remote)
throws IOException {
final String adjustedPath;
if (local.isDirectory()) {
listener.startedDir(local.getName());
adjustedPath = uploadDir(local, remote);
listener.finishedDir();
adjustedPath = uploadDir(listener.directory(local.getName()), local, remote);
} else if (local.isFile()) {
listener.startedFile(local.getName(), local.getLength());
adjustedPath = uploadFile(local, remote);
listener.finishedFile();
adjustedPath = uploadFile(listener.file(local.getName(), local.getLength()), local, remote);
} else
throw new IOException(local + " is not a file or directory");
engine.setAttributes(adjustedPath, getAttributes(local));
if (getPreserveAttributes())
engine.setAttributes(adjustedPath, getAttributes(local));
}
private String uploadDir(LocalSourceFile local, String remote)
private String uploadDir(final TransferListener listener,
final LocalSourceFile local,
final String remote)
throws IOException {
final String adjusted = prepareDir(local, remote);
for (LocalSourceFile f : local.getChildren(getUploadFilter()))
upload(f, adjusted);
upload(listener, f, adjusted);
return adjusted;
}
private String uploadFile(LocalSourceFile local, String remote)
private String uploadFile(final StreamCopier.Listener listener,
final LocalSourceFile local,
final String remote)
throws IOException {
final String adjusted = prepareFile(local, remote);
final RemoteFile rf = engine.open(adjusted, EnumSet.of(OpenMode.WRITE,
@@ -210,7 +221,7 @@ public class SFTPFileTransfer
return adjusted;
}
private String prepareDir(LocalSourceFile local, String remote)
private String prepareDir(final LocalSourceFile local, final String remote)
throws IOException {
final FileAttributes attrs;
try {
@@ -236,7 +247,7 @@ public class SFTPFileTransfer
throw new IOException(attrs.getMode().getType() + " file already exists at " + remote);
}
private String prepareFile(LocalSourceFile local, String remote)
private String prepareFile(final LocalSourceFile local, final String remote)
throws IOException {
final FileAttributes attrs;
try {
@@ -250,8 +261,7 @@ public class SFTPFileTransfer
}
if (attrs.getMode().getType() == FileMode.Type.DIRECTORY) {
log.debug("probeFile: {} was directory, path adjusted for {}", remote, local.getName());
remote = engine.getPathHelper().adjustForParent(remote, local.getName());
return remote;
return engine.getPathHelper().adjustForParent(remote, local.getName());
} else {
log.debug("probeFile: {} is a {} file that will be replaced", remote, attrs.getMode().getType());
return remote;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -15,6 +15,9 @@
*/
package net.schmizz.sshj.sftp;
import net.schmizz.sshj.xfer.LocalDestFile;
import net.schmizz.sshj.xfer.LocalSourceFile;
import java.io.IOException;
import java.util.List;
import java.util.Set;
@@ -28,7 +31,7 @@ public class StatefulSFTPClient
throws IOException {
super(engine);
this.cwd = getSFTPEngine().canonicalize(".");
log.info("Start dir = " + cwd);
log.debug("Start dir = {}", cwd);
}
private synchronized String cwdify(String path) {
@@ -41,7 +44,7 @@ public class StatefulSFTPClient
if (statExistence(cwd) == null) {
throw new SFTPException(cwd + ": does not exist");
}
log.info("CWD = " + cwd);
log.debug("CWD = {}", cwd);
}
public synchronized List<RemoteResourceInfo> ls()
@@ -178,10 +181,22 @@ public class StatefulSFTPClient
super.get(cwdify(source), dest);
}
@Override
public void get(String source, LocalDestFile dest)
throws IOException {
super.get(cwdify(source), dest);
}
@Override
public void put(String source, String dest)
throws IOException {
super.put(source, cwdify(dest));
}
@Override
public void put(LocalSourceFile source, String dest)
throws IOException {
super.put(source, cwdify(dest));
}
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -47,7 +47,7 @@ import net.schmizz.sshj.transport.mac.MAC;
* <p/>
* <pre>
* Each packet is in the following format:
* <p/>
*
* uint32 packet_length
* byte padding_length
* byte[n1] payload; n1 = packet_length - padding_length - 1

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -88,7 +88,7 @@ final class Decoder
int need;
/* Decoding loop */
for (; ;)
for (; ; )
if (packetLength == -1) // Waiting for beginning of packet
{
@@ -124,7 +124,7 @@ final class Decoder
if (log.isTraceEnabled())
log.trace("Received packet #{}: {}", seq, plain.printHex());
packetHandler.handle(plain.readMessageID(), plain); // Process the decoded packet //
packetHandler.handle(plain.readMessageID(), plain); // Process the decoded packet
inputBuffer.clear();
packetLength = -1;
@@ -166,7 +166,7 @@ final class Decoder
}
if (isInvalidPacketLength(len)) { // Check packet length validity
log.info("Error decoding packet (invalid length) {}", inputBuffer.printHex());
log.error("Error decoding packet (invalid length) {}", inputBuffer.printHex());
throw new TransportException(DisconnectReason.PROTOCOL_ERROR, "invalid packet length: " + len);
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -80,7 +80,7 @@ final class Heartbeater
while (!isInterrupted()) {
final int hi = getPositiveInterval();
if (trans.isRunning()) {
log.info("Sending heartbeat since {} seconds elapsed", hi);
log.debug("Sending heartbeat since {} seconds elapsed", hi);
trans.write(new SSHPacket(Message.IGNORE));
}
Thread.sleep(hi * 1000);

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -192,7 +192,7 @@ final class KeyExchanger
*/
private void sendKexInit()
throws TransportException {
log.info("Sending SSH_MSG_KEXINIT");
log.debug("Sending SSH_MSG_KEXINIT");
clientProposal = new Proposal(transport.getConfig());
transport.write(clientProposal.getPacket());
kexInitSent.set();
@@ -200,7 +200,7 @@ final class KeyExchanger
private void sendNewKeys()
throws TransportException {
log.info("Sending SSH_MSG_NEWKEYS");
log.debug("Sending SSH_MSG_NEWKEYS");
transport.write(new SSHPacket(Message.NEWKEYS));
}
@@ -354,7 +354,7 @@ final class KeyExchanger
case KEXINIT:
ensureReceivedMatchesExpected(msg, Message.KEXINIT);
log.info("Received SSH_MSG_KEXINIT");
log.debug("Received SSH_MSG_KEXINIT");
startKex(false); // Will start key exchange if not already on
/*
* We block on this event to prevent a race condition where we may have received a SSH_MSG_KEXINIT before
@@ -367,7 +367,7 @@ final class KeyExchanger
case FOLLOWUP:
ensureKexOngoing();
log.info("Received kex followup data");
log.debug("Received kex followup data");
try {
if (kex.next(msg, buf)) {
verifyHost(kex.getHostKey());
@@ -382,7 +382,7 @@ final class KeyExchanger
case NEWKEYS:
ensureReceivedMatchesExpected(msg, Message.NEWKEYS);
ensureKexOngoing();
log.info("Received SSH_MSG_NEWKEYS");
log.debug("Received SSH_MSG_NEWKEYS");
gotNewKeys();
setKexDone();
expected = Expected.KEXINIT;

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -92,15 +92,15 @@ public final class NegotiatedAlgorithms {
@Override
public String toString() {
return ("[ " + //
"kex=" + kex + "; " + //
"sig=" + sig + "; " + //
"c2sCipher=" + c2sCipher + "; " + //
"s2cCipher=" + s2cCipher + "; " + //
"c2sMAC=" + c2sMAC + "; " + //
"s2cMAC=" + s2cMAC + "; " + //
"c2sComp=" + c2sComp + "; " + //
"s2cComp=" + s2cComp + //
return ("[ " +
"kex=" + kex + "; " +
"sig=" + sig + "; " +
"c2sCipher=" + c2sCipher + "; " +
"s2cCipher=" + s2cCipher + "; " +
"c2sMAC=" + c2sMAC + "; " +
"s2cMAC=" + s2cMAC + "; " +
"c2sComp=" + c2sComp + "; " +
"s2cComp=" + s2cComp +
" ]");
}

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2010, 2011 sshj contributors
* Copyright 2010-2012 sshj contributors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -178,12 +178,14 @@ public interface Transport
*/
void join()
throws TransportException;
/**
* Joins the thread calling this method to the transport's death.
*
* @throws TransportException if the transport dies of an exception
*/
void join(int timeout, TimeUnit unit) throws TransportException;
void join(int timeout, TimeUnit unit)
throws TransportException;
/** Send a disconnection packet with reason as {@link DisconnectReason#BY_APPLICATION}, and closes this transport. */
void disconnect();
@@ -226,9 +228,7 @@ public interface Transport
*/
void setDisconnectListener(DisconnectListener listener);
/**
* @return the current disconnect listener.
*/
/** @return the current disconnect listener. */
DisconnectListener getDisconnectListener();
}

Some files were not shown because too many files have changed in this diff Show More