You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2016/02/23 18:40:07 UTC
mina-sshd git commit: Added support for command line specification of
compression mode
Repository: mina-sshd
Updated Branches:
refs/heads/master 8803e1364 -> a4307d1cc
Added support for command line specification of compression mode
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/a4307d1c
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/a4307d1c
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/a4307d1c
Branch: refs/heads/master
Commit: a4307d1cc508f651c6c40915316befbd1f4d4c04
Parents: 8803e13
Author: Lyor Goldstein <ly...@gmail.com>
Authored: Tue Feb 23 19:40:50 2016 +0200
Committer: Lyor Goldstein <ly...@gmail.com>
Committed: Tue Feb 23 19:40:50 2016 +0200
----------------------------------------------------------------------
.../java/org/apache/sshd/client/SshClient.java | 154 ++++++++++++++-----
.../sshd/client/scp/DefaultScpClient.java | 5 +-
.../sshd/client/subsystem/sftp/SftpCommand.java | 2 +-
.../ReservedSessionMessagesHandlerTest.java | 2 +-
4 files changed, 124 insertions(+), 39 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a4307d1c/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
index 2fbdb11..6ae44d6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
@@ -97,6 +97,9 @@ import org.apache.sshd.common.ServiceFactory;
import org.apache.sshd.common.channel.Channel;
import org.apache.sshd.common.cipher.BuiltinCiphers;
import org.apache.sshd.common.cipher.Cipher;
+import org.apache.sshd.common.compression.BuiltinCompressions;
+import org.apache.sshd.common.compression.Compression;
+import org.apache.sshd.common.config.CompressionConfigValue;
import org.apache.sshd.common.config.SshConfigFileReader;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.config.keys.KeyUtils;
@@ -785,8 +788,8 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
// NOTE: ClientSession#getFactoryManager is the SshClient
public static ClientSession setupClientSession(
- String portOption, final BufferedReader stdin, final PrintStream stdout, final PrintStream stderr, String... args)
- throws Exception {
+ String portOption, BufferedReader stdin, PrintStream stdout, PrintStream stderr, String... args)
+ throws Exception {
int port = -1;
String host = null;
@@ -797,6 +800,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
Map<String, String> options = new LinkedHashMap<>();
List<NamedFactory<Cipher>> ciphers = null;
List<NamedFactory<Mac>> macs = null;
+ List<NamedFactory<Compression>> compressions = null;
int numArgs = GenericUtils.length(args);
for (int i = 0; (!error) && (i < numArgs); i++) {
String argName = args[i];
@@ -841,6 +845,16 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
}
} else if ("-i".equals(argName)) {
identities.add(new File(argVal));
+ } else if ("-C".equals(argName)) {
+ compressions = setupCompressions(argName,
+ GenericUtils.join(
+ Arrays.asList(
+ BuiltinCompressions.Constants.ZLIB, BuiltinCompressions.Constants.DELAYED_ZLIB), ','),
+ compressions, stderr);
+ if (GenericUtils.isEmpty(compressions)) {
+ error = true;
+ break;
+ }
} else if ("-o".equals(argName)) {
String opt = argVal;
int idx = opt.indexOf('=');
@@ -879,30 +893,71 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
error = showError(stderr, "Hostname not specified");
}
- if ((!error) && GenericUtils.isEmpty(ciphers)) {
+ if (error) {
+ return null;
+ }
+
+ SshClient client = setupClient(options, ciphers, macs, compressions, identities, stdin, stdout, stderr);
+ if (client == null) {
+ return null;
+ }
+
+ try {
+ client.start();
+
+ if (login == null) {
+ login = OsUtils.getCurrentUser();
+ }
+
+ if (port <= 0) {
+ port = SshConfigFileReader.DEFAULT_PORT;
+ }
+
+ // TODO use a configurable wait time
+ ClientSession session = client.connect(login, host, port).verify().getSession();
+ try {
+ if (GenericUtils.length(password) > 0) {
+ session.addPasswordIdentity(password);
+ }
+ session.auth().verify(FactoryManager.DEFAULT_AUTH_TIMEOUT); // TODO use a configurable wait time
+ return session;
+ } catch (Exception e) {
+ session.close(true);
+ throw e;
+ }
+ } catch (Exception e) {
+ client.close();
+ throw e;
+ }
+ }
+
+ // returns null if error encountered
+ public static SshClient setupClient(
+ Map<String, ?> options,
+ List<NamedFactory<Cipher>> ciphers,
+ List<NamedFactory<Mac>> macs,
+ List<NamedFactory<Compression>> compressions,
+ Collection<File> identities,
+ BufferedReader stdin, PrintStream stdout, PrintStream stderr) throws Exception {
+ if (GenericUtils.isEmpty(ciphers)) {
ciphers = setupCiphers(options, stderr);
if (ciphers == null) {
- error = true;
+ return null;
}
}
- if ((!error) && GenericUtils.isEmpty(macs)) {
+ if (GenericUtils.isEmpty(macs)) {
macs = setupMacs(options, stderr);
if (macs == null) {
- error = true;
+ return null;
}
}
- if (login == null) {
- login = OsUtils.getCurrentUser();
- }
-
- if (port <= 0) {
- port = SshConfigFileReader.DEFAULT_PORT;
- }
-
- if (error) {
- return null;
+ if (GenericUtils.isEmpty(compressions)) {
+ compressions = setupCompressions(options, stderr);
+ if (compressions == null) {
+ return null;
+ }
}
SshClient client = SshClient.setUpDefaultClient();
@@ -915,10 +970,14 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
client.setMacFactories(macs);
}
+ if (GenericUtils.size(compressions) > 0) {
+ client.setCompressionFactories(compressions);
+ }
+
try {
setupSessionIdentities(client, identities, stdin, stdout, stderr);
- } catch (Throwable t) {
- error = showError(stderr, t.getClass().getSimpleName() + " while loading user keys: " + t.getMessage());
+ } catch (Throwable t) { // show but do not fail the setup - maybe a password can be used
+ showError(stderr, t.getClass().getSimpleName() + " while loading user keys: " + t.getMessage());
}
setupServerKeyVerifier(client, options, stdin, stdout, stderr);
@@ -926,23 +985,11 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
Map<String, Object> props = client.getProperties();
props.putAll(options);
- client.start();
-
- // TODO use a configurable wait time
- ClientSession session = client.connect(login, host, port).verify().getSession();
- try {
- if (GenericUtils.length(password) > 0) {
- session.addPasswordIdentity(password);
- }
- session.auth().verify(FactoryManager.DEFAULT_AUTH_TIMEOUT); // TODO use a configurable wait time
- return session;
- } catch (Exception e) {
- session.close(true);
- throw e;
- }
- } catch (Exception e) {
+ return client;
+ } catch (Throwable t) {
+ showError(stderr, "Failed (" + t.getClass().getSimpleName() + ") to setup client: " + t.getMessage());
client.close();
- throw e;
+ return null;
}
}
@@ -1116,6 +1163,43 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
return stderr;
}
+ public static List<NamedFactory<Compression>> setupCompressions(Map<String, ?> options, PrintStream stderr) {
+ String argVal = PropertyResolverUtils.getString(options, SshConfigFileReader.COMPRESSION_PROP);
+ if (GenericUtils.isEmpty(argVal)) {
+ return Collections.<NamedFactory<Compression>>emptyList();
+ }
+
+ NamedFactory<Compression> value = CompressionConfigValue.fromName(argVal);
+ if (value == null) {
+ showError(stderr, "Unknown compression configuration value: " + argVal);
+ return null;
+ }
+
+ return Collections.singletonList(value);
+ }
+
+ public static List<NamedFactory<Compression>> setupCompressions(
+ String argName, String argVal, List<NamedFactory<Compression>> current, PrintStream stderr) {
+ if (GenericUtils.size(current) > 0) {
+ showError(stderr, argName + " option value re-specified: " + NamedResource.Utils.getNames(current));
+ return null;
+ }
+
+ BuiltinCompressions.ParseResult result = BuiltinCompressions.parseCompressionsList(argVal);
+ Collection<? extends NamedFactory<Compression>> available = result.getParsedFactories();
+ if (GenericUtils.isEmpty(available)) {
+ showError(stderr, "No known compressions in " + argVal);
+ return null;
+ }
+
+ Collection<String> unsupported = result.getUnsupportedFactories();
+ if (GenericUtils.size(unsupported) > 0) {
+ stderr.append("Ignored unsupported compressions: ").println(GenericUtils.join(unsupported, ','));
+ }
+
+ return new ArrayList<>(available);
+ }
+
public static List<NamedFactory<Mac>> setupMacs(Map<String, ?> options, PrintStream stderr) {
String argVal = PropertyResolverUtils.getString(options, SshConfigFileReader.MACS_CONFIG_PROP);
return GenericUtils.isEmpty(argVal)
@@ -1300,7 +1384,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
if (error) {
System.err.println("usage: ssh [-A|-a] [-v[v][v]] [-E logoutputfile] [-D socksPort]"
+ " [-l login] [" + SSH_CLIENT_PORT_OPTION + " port] [-o option=value]"
- + " [-w password] [-c cipherslist] [-m maclist]"
+ + " [-w password] [-c cipherslist] [-m maclist] [-C]"
+ " hostname/user@host [command]");
System.exit(-1);
return;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a4307d1c/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
index 4617c84..e184f76 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/scp/DefaultScpClient.java
@@ -195,7 +195,8 @@ public class DefaultScpClient extends AbstractScpClient {
effective.add(argName);
effective.add(args[++index]);
- } else if ("-r".equals(argName) || "-p".equals(argName) || "-q".equals(argName)
+ } else if ("-r".equals(argName) || "-p".equals(argName)
+ || "-q".equals(argName) || "-C".equals(argName)
|| "-v".equals(argName) || "-vv".equals(argName) || "-vvv".equals(argName)) {
effective.add(argName);
} else if (argName.charAt(0) == '-') {
@@ -255,7 +256,7 @@ public class DefaultScpClient extends AbstractScpClient {
if (session == null) {
stderr.println("usage: scp [" + SCP_PORT_OPTION + " port] [-i identity]"
+ " [-v[v][v]] [-E logoutput] [-r] [-p] [-q] [-o option=value]"
- + " [-c cipherlist] [-m maclist] [-w password] <source> <target>");
+ + " [-c cipherlist] [-m maclist] [-w password] [-C] <source> <target>");
stderr.println();
stderr.println("Where <source> or <target> are either 'user@host:file' or a local file path");
stderr.println("NOTE: exactly ONE of the source or target must be remote and the other one local");
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a4307d1c/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
index 0620b27..ff5cef4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpCommand.java
@@ -260,7 +260,7 @@ public class SftpCommand implements Channel {
if (session == null) {
System.err.println("usage: sftp [-v[v][v]] [-E logoutput] [-i identity]"
+ " [-l login] [" + SFTP_PORT_OPTION + " port] [-o option=value]"
- + " [-w password] [-c cipherlist] [-m maclist] hostname/user@host");
+ + " [-w password] [-c cipherlist] [-m maclist] [-C] hostname/user@host");
System.exit(-1);
return;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/a4307d1c/sshd-core/src/test/java/org/apache/sshd/common/session/ReservedSessionMessagesHandlerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/session/ReservedSessionMessagesHandlerTest.java b/sshd-core/src/test/java/org/apache/sshd/common/session/ReservedSessionMessagesHandlerTest.java
index 07e09e5..22f8cb3 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/session/ReservedSessionMessagesHandlerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/session/ReservedSessionMessagesHandlerTest.java
@@ -112,7 +112,7 @@ public class ReservedSessionMessagesHandlerTest extends BaseTestSupport {
testReservedSessionMessagesHandler(session, handler);
outputDebugMessage("Release test signal for %s", session);
signal.release();
- } catch(Throwable t) {
+ } catch (Throwable t) {
outputDebugMessage("Failed (%s) to run test: %s", t.getClass().getSimpleName(), t.getMessage());
session.exceptionCaught(t);
}