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 2015/07/05 08:29:11 UTC
mina-sshd git commit: [SSHD-518] Add support for SFTP 'copy-file'
extension
Repository: mina-sshd
Updated Branches:
refs/heads/master ed92ebe89 -> 9d0662215
[SSHD-518] Add support for SFTP 'copy-file' extension
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/9d066221
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/9d066221
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/9d066221
Branch: refs/heads/master
Commit: 9d06622153a4121948e49a4c61282eb5636c3f42
Parents: ed92ebe
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Sun Jul 5 09:29:00 2015 +0300
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Sun Jul 5 09:29:00 2015 +0300
----------------------------------------------------------------------
sshd-core/key.pem | 12 ++
.../sshd/agent/common/AbstractAgentClient.java | 2 +-
.../sshd/agent/common/AbstractAgentProxy.java | 10 +-
.../auth/UserAuthKeyboardInteractive.java | 4 +-
.../sshd/client/auth/UserAuthPassword.java | 2 +-
.../sshd/client/auth/UserAuthPublicKey.java | 2 +-
.../org/apache/sshd/client/kex/DHGClient.java | 2 +-
.../org/apache/sshd/client/kex/DHGEXClient.java | 2 +-
.../client/session/ClientUserAuthService.java | 4 +-
.../subsystem/sftp/DefaultSftpClient.java | 18 +--
.../sshd/client/subsystem/sftp/SftpClient.java | 2 +-
.../java/org/apache/sshd/common/Service.java | 7 +-
.../apache/sshd/common/forward/SocksProxy.java | 16 +--
.../session/AbstractConnectionService.java | 4 +-
.../sshd/common/session/AbstractSession.java | 6 +-
.../common/subsystem/sftp/SftpConstants.java | 1 +
.../subsystem/sftp/extensions/ParserUtils.java | 4 +-
.../sftp/extensions/Supported2Parser.java | 91 +++++++++++++
.../sftp/extensions/SupportedParser.java | 80 ++++++++++++
.../apache/sshd/common/util/buffer/Buffer.java | 128 +++++++++++++++++--
.../org/apache/sshd/common/util/io/IoUtils.java | 2 +
.../auth/UserAuthKeyboardInteractive.java | 2 +-
.../sshd/server/auth/gss/UserAuthGSS.java | 2 +-
.../org/apache/sshd/server/kex/DHGEXServer.java | 2 +-
.../org/apache/sshd/server/kex/DHGServer.java | 2 +-
.../server/session/ServerUserAuthService.java | 2 +-
.../server/subsystem/sftp/SftpSubsystem.java | 64 +++++++---
.../test/java/org/apache/sshd/WindowTest.java | 2 +-
.../java/org/apache/sshd/client/ClientTest.java | 2 +-
.../sshd/client/subsystem/sftp/SftpTest.java | 32 ++++-
.../deprecated/ClientUserAuthServiceOld.java | 2 +-
.../apache/sshd/deprecated/UserAuthAgent.java | 4 +-
.../deprecated/UserAuthKeyboardInteractive.java | 6 +-
.../sshd/deprecated/UserAuthPassword.java | 2 +-
.../sshd/deprecated/UserAuthPublicKey.java | 4 +-
35 files changed, 441 insertions(+), 86 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/key.pem
----------------------------------------------------------------------
diff --git a/sshd-core/key.pem b/sshd-core/key.pem
new file mode 100644
index 0000000..0837e2e
--- /dev/null
+++ b/sshd-core/key.pem
@@ -0,0 +1,12 @@
+-----BEGIN DSA PRIVATE KEY-----
+MIIBugIBAAKBgQCssuzdF9+pjVpV+u5t9fYg52q74giD9EUvJ1YHDOsepVgJMgbi
+P8ECg1nGbXxpmVMakdchnZCZBQ84O1MngGBMH0TOa1ySwei0tceeSn/XxVgm0V/c
+X67x0ascNmKzJOvaVyvzsu7dQKxU/g6HhNapWl3JYLupWcMI2eYjSoENPQIVAIT4
+Urb8PSPDAXjy4eDouBluDFlBAoGAePjF+apIm2zWFoxjQ65guG0dc0UnxKIHgf2L
+FhYS129RWkCLQhimh9Z55g+vYLxzhHSnF+7IvlZdtUPoN2HDUEFc30XFA8d+ahjr
+kkLbVzOq7yOkSxO5+rTMWNXiTvvssIhsz6nCDBrViRKJJ8F3Au4W5THoJuLFAgho
+oZWKceICgYBTGx3tQocQnGXdV+D2Kg7A0x8Yi/T9ZET0kBhGVjQzYDOCtJvML3sD
+uA+iPMKt6lgULDL+czK5aOSRKBjo1hckUyEGQLfVo3nYq6EspIjrf47HQqmGSUzL
+P5gv99dWn0+dgzAlZZdeWtO9g/KqrgfdZhnLRCdU5TgMgjYlzckg5AIUR7iHDKCB
+1Whmb6WCKX67kWyc6PY=
+-----END DSA PRIVATE KEY-----
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java b/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java
index 548b411..6940bcd 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentClient.java
@@ -76,7 +76,7 @@ public abstract class AbstractAgentClient extends AbstractLoggingBean {
}
protected void process(Buffer req, Buffer rep) throws Exception {
- int cmd = req.getByte();
+ int cmd = req.getUByte();
switch (cmd) {
case SSH2_AGENTC_REQUEST_IDENTITIES: {
List<Pair<PublicKey,String>> keys = agent.getIdentities();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java b/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java
index a5a7304..b3dc062 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/common/AbstractAgentProxy.java
@@ -77,7 +77,7 @@ public abstract class AbstractAgentProxy extends AbstractLoggingBean implements
public List<Pair<PublicKey, String>> getIdentities() throws IOException {
Buffer buffer = createBuffer(SSH2_AGENTC_REQUEST_IDENTITIES);
buffer = request(prepare(buffer));
- int type = buffer.getByte();
+ int type = buffer.getUByte();
if (type != SSH2_AGENT_IDENTITIES_ANSWER) {
throw new SshException("Bad agent identities answer: " + type);
}
@@ -103,7 +103,7 @@ public abstract class AbstractAgentProxy extends AbstractLoggingBean implements
buffer.putInt(0);
buffer = request(prepare(buffer));
- byte responseType = buffer.getByte();
+ int responseType = buffer.getUByte();
if (responseType != SSH2_AGENT_SIGN_RESPONSE) {
throw new SshException("Bad signing response type: " + (responseType & 0xFF));
}
@@ -128,7 +128,7 @@ public abstract class AbstractAgentProxy extends AbstractLoggingBean implements
buffer = request(prepare(buffer));
int available = buffer.available();
- byte response = (available >= 1) ? buffer.getByte() : -1;
+ int response = (available >= 1) ? buffer.getUByte() : -1;
if ((available != 1) || (response != SSH_AGENT_SUCCESS)) {
throw new SshException("Bad addIdentity response (" + (response & 0xFF) + ") - available=" + available);
}
@@ -145,7 +145,7 @@ public abstract class AbstractAgentProxy extends AbstractLoggingBean implements
buffer = request(prepare(buffer));
int available = buffer.available();
- byte response = (available >= 1) ? buffer.getByte() : -1;
+ int response = (available >= 1) ? buffer.getUByte() : -1;
if ((available != 1) || (response != SSH_AGENT_SUCCESS)) {
throw new SshException("Bad removeIdentity response (" + (response & 0xFF) + ") - available=" + available);
}
@@ -160,7 +160,7 @@ public abstract class AbstractAgentProxy extends AbstractLoggingBean implements
buffer = request(prepare(buffer));
int available = buffer.available();
- byte response = (available >= 1) ? buffer.getByte() : -1;
+ int response = (available >= 1) ? buffer.getUByte() : -1;
if ((available != 1) || (response != SSH_AGENT_SUCCESS)) {
throw new SshException("Bad removeAllIdentities response (" + (response & 0xFF) + ") - available=" + available);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthKeyboardInteractive.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthKeyboardInteractive.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthKeyboardInteractive.java
index 100f0bd..f7f66c4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthKeyboardInteractive.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthKeyboardInteractive.java
@@ -91,7 +91,7 @@ public class UserAuthKeyboardInteractive extends AbstractLoggingBean implements
return true;
}
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd == SSH_MSG_USERAUTH_INFO_REQUEST) {
log.debug("Received SSH_MSG_USERAUTH_INFO_REQUEST");
String name = buffer.getString();
@@ -107,7 +107,7 @@ public class UserAuthKeyboardInteractive extends AbstractLoggingBean implements
for (int i = 0; i < num; i++) {
// according to RFC4256: "The prompt field(s) MUST NOT be empty strings."
prompt[i] = buffer.getString();
- echo[i] = (buffer.getByte() != 0);
+ echo[i] = buffer.getBoolean();
}
if (log.isDebugEnabled()) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPassword.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPassword.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPassword.java
index cfa9de4..7ca3170 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPassword.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPassword.java
@@ -75,7 +75,7 @@ public class UserAuthPassword extends AbstractLoggingBean implements UserAuth {
}
return false;
}
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd == SshConstants.SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) {
String prompt = buffer.getString();
String lang = buffer.getString();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java
index 7fb9954..4a8b881 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserAuthPublicKey.java
@@ -114,7 +114,7 @@ public class UserAuthPublicKey extends AbstractLoggingBean implements UserAuth {
return false;
}
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd == SshConstants.SSH_MSG_USERAUTH_PK_OK) {
PublicKey key = current.getPublicKey();
String algo = KeyUtils.getKeyType(key);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
index cdbf6a4..3d533fa 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
@@ -93,7 +93,7 @@ public class DHGClient extends AbstractDHClientKeyExchange {
@Override
public boolean next(Buffer buffer) throws Exception {
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd != SshConstants.SSH_MSG_KEXDH_REPLY) {
throw new SshException(SshConstants.SSH2_DISCONNECT_KEY_EXCHANGE_FAILED,
"Protocol error: expected packet SSH_MSG_KEXDH_REPLY, got " + cmd);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
index 79c1a4a..35dd0c3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
@@ -92,7 +92,7 @@ public class DHGEXClient extends AbstractDHClientKeyExchange {
@Override
public boolean next(Buffer buffer) throws Exception {
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd != expected) {
throw new SshException(SshConstants.SSH2_DISCONNECT_KEY_EXCHANGE_FAILED,
"Protocol error: expected packet " + expected + ", got " + cmd);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java
index c32fc8d..41a0d37 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientUserAuthService.java
@@ -115,7 +115,7 @@ public class ClientUserAuthService extends CloseableUtils.AbstractCloseable impl
}
@Override
- public void process(byte cmd, Buffer buffer) throws Exception {
+ public void process(int cmd, Buffer buffer) throws Exception {
if (this.authFuture.isSuccess()) {
throw new IllegalStateException("UserAuth message delivered to authenticated client");
} else if (this.authFuture.isDone()) {
@@ -143,7 +143,7 @@ public class ClientUserAuthService extends CloseableUtils.AbstractCloseable impl
* @throws java.io.IOException
*/
private void processUserAuth(Buffer buffer) throws Exception {
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd == SshConstants.SSH_MSG_USERAUTH_SUCCESS) {
log.info("Received SSH_MSG_USERAUTH_SUCCESS");
log.debug("Succeeded with {}", userAuth);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
index 2f743b9..9f064c0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/DefaultSftpClient.java
@@ -335,7 +335,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
}
int length = buffer.getInt();
- int type = buffer.getByte() & 0xFF;
+ int type = buffer.getUByte();
int id = buffer.getInt();
if (type == SSH_FXP_VERSION) {
if (id < SFTP_V3) {
@@ -364,7 +364,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
protected void checkStatus(Buffer buffer) throws IOException {
int length = buffer.getInt();
- int type = buffer.getByte();
+ int type = buffer.getUByte();
int id = buffer.getInt();
if (type == SSH_FXP_STATUS) {
int substatus = buffer.getInt();
@@ -384,7 +384,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
protected String checkHandle(Buffer buffer) throws IOException {
int length = buffer.getInt();
- int type = buffer.getByte();
+ int type = buffer.getUByte();
int id = buffer.getInt();
if (type == SSH_FXP_STATUS) {
int substatus = buffer.getInt();
@@ -404,7 +404,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
protected Attributes checkAttributes(Buffer buffer) throws IOException {
int length = buffer.getInt();
- int type = buffer.getByte();
+ int type = buffer.getUByte();
int id = buffer.getInt();
if (type == SSH_FXP_STATUS) {
int substatus = buffer.getInt();
@@ -423,7 +423,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
protected String checkOneName(Buffer buffer) throws IOException {
int length = buffer.getInt();
- int type = buffer.getByte();
+ int type = buffer.getUByte();
int id = buffer.getInt();
if (type == SSH_FXP_STATUS) {
int substatus = buffer.getInt();
@@ -475,7 +475,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
attrs.mtime = buffer.getInt();
}
} else if (version >= SFTP_V4) {
- attrs.type = buffer.getByte();
+ attrs.type = buffer.getUByte();
if ((flags & SSH_FILEXFER_ATTR_SIZE) != 0) {
attrs.flags.add(Attribute.Size);
attrs.size = buffer.getLong();
@@ -596,7 +596,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
}
}
buffer.putInt(flags);
- buffer.putByte(attributes.type);
+ buffer.putByte((byte) attributes.type);
if ((flags & SSH_FILEXFER_ATTR_SIZE) != 0) {
buffer.putLong(attributes.size);
}
@@ -757,7 +757,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
protected int checkData(Buffer buffer, int dstoff, byte[] dst) throws IOException {
int length = buffer.getInt();
- int type = buffer.getByte();
+ int type = buffer.getUByte();
int id = buffer.getInt();
if (type == SSH_FXP_STATUS) {
int substatus = buffer.getInt();
@@ -836,7 +836,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
protected DirEntry[] checkDir(Buffer buffer) throws IOException {
int length = buffer.getInt();
- int type = buffer.getByte();
+ int type = buffer.getUByte();
int id = buffer.getInt();
if (type == SSH_FXP_STATUS) {
int substatus = buffer.getInt();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClient.java
index 8b18c2f..d7ded06 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpClient.java
@@ -90,7 +90,7 @@ public interface SftpClient extends SubsystemClient {
public static class Attributes {
public final Set<Attribute> flags = EnumSet.noneOf(Attribute.class);
public long size;
- public byte type;
+ public int type;
public int uid;
public int gid;
public int perms;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/common/Service.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/Service.java b/sshd-core/src/main/java/org/apache/sshd/common/Service.java
index 2339c4c..a70de53 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/Service.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/Service.java
@@ -37,10 +37,11 @@ public interface Service extends Closeable {
/**
* Service the request.
- * @param buffer
- * @throws Exception
+ * @param cmd The incoming command type
+ * @param buffer The {@link Buffer} containing optional command parameters
+ * @throws Exception If failed to process the command
*/
- void process(byte cmd, Buffer buffer) throws Exception;
+ void process(int cmd, Buffer buffer) throws Exception;
/**
* Close the service.
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java b/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java
index 84b96a3..cb70913 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/forward/SocksProxy.java
@@ -69,7 +69,7 @@ public class SocksProxy extends CloseableUtils.AbstractCloseable implements IoHa
buffer.putBuffer(message);
Proxy proxy = proxies.get(session);
if (proxy == null) {
- int version = buffer.getByte();
+ int version = buffer.getUByte();
if (version == 0x04) {
proxy = new Socks4(session);
} else if (version == 0x05) {
@@ -112,11 +112,11 @@ public class SocksProxy extends CloseableUtils.AbstractCloseable implements IoHa
}
protected int getUByte(Buffer buffer) {
- return buffer.getByte() & 0xFF;
+ return buffer.getUByte();
}
protected int getUShort(Buffer buffer) {
- return (getUByte(buffer) << 8) + getUByte(buffer);
+ return (getUByte(buffer) << Byte.SIZE) + getUByte(buffer);
}
}
@@ -132,7 +132,7 @@ public class SocksProxy extends CloseableUtils.AbstractCloseable implements IoHa
@Override
protected void onMessage(Buffer buffer) throws IOException {
if (channel == null) {
- int cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd != 1) {
throw new IllegalStateException("Unsupported socks command: " + cmd);
}
@@ -233,16 +233,16 @@ public class SocksProxy extends CloseableUtils.AbstractCloseable implements IoHa
if (version != 0x05) {
throw new IllegalStateException("Unexpected version: " + version);
}
- int cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd != 1) { // establish a TCP/IP stream connection
throw new IllegalStateException("Unsupported socks command: " + cmd);
}
- final int res = buffer.getByte();
+ final int res = buffer.getUByte();
if (res != 0) {
- log.debug("No zero reserved value: " + (res & 0x00FF));
+ log.debug("No zero reserved value: " + res);
}
- int type = buffer.getByte();
+ int type = buffer.getUByte();
String host;
if (type == 0x01) {
host = Integer.toString(getUByte(buffer)) + "."
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
index ab52948..109ffb1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionService.java
@@ -155,7 +155,7 @@ public abstract class AbstractConnectionService extends CloseableUtils.AbstractI
}
@Override
- public void process(byte cmd, Buffer buffer) throws Exception {
+ public void process(int cmd, Buffer buffer) throws Exception {
switch (cmd) {
case SSH_MSG_CHANNEL_OPEN:
channelOpen(buffer);
@@ -320,7 +320,7 @@ public abstract class AbstractConnectionService extends CloseableUtils.AbstractI
Channel channel = channels.get(Integer.valueOf(recipient));
if (channel == null) {
buffer.rpos(buffer.rpos() - 5);
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
throw new SshException("Received " + cmd + " on unknown channel " + recipient);
}
return channel;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
index fd1655c..ed8aced 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSession.java
@@ -328,7 +328,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea
}
protected void doHandleMessage(Buffer buffer) throws Exception {
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
switch (cmd) {
case SSH_MSG_DISCONNECT: {
int code = buffer.getInt();
@@ -443,7 +443,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea
checkRekey();
}
- protected void validateKexState(byte cmd, KexState expected) {
+ protected void validateKexState(int cmd, KexState expected) {
KexState actual = kexState.get();
if (!expected.equals(actual)) {
throw new IllegalStateException("Received KEX command=" + cmd + " while in state=" + actual + " instead of " + expected);
@@ -778,7 +778,7 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea
// Increment incoming packet sequence number
seqi = (seqi + 1) & 0xffffffffL;
// Get padding
- byte pad = decoderBuffer.getByte();
+ int pad = decoderBuffer.getUByte();
Buffer buf;
int wpos = decoderBuffer.wpos();
// Decompress if needed
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpConstants.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpConstants.java b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpConstants.java
index 41c3a1a..431085a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpConstants.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/SftpConstants.java
@@ -228,6 +228,7 @@ public final class SftpConstants {
public static final String EXT_SUPPORTED = "supported";
public static final String EXT_SUPPORTED2 = "supported2";
public static final String EXT_VERSELECT = "version-select";
+ public static final String EXT_COPYFILE = "copy-file";
private SftpConstants() {
throw new UnsupportedOperationException("No instance");
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/ParserUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/ParserUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/ParserUtils.java
index 0dd33ea..d64bebc 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/ParserUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/ParserUtils.java
@@ -40,7 +40,9 @@ public final class ParserUtils {
Arrays.<ExtensionParser<?>>asList(
VendorIdParser.INSTANCE,
NewlineParser.INSTANCE,
- VersionsParser.INSTANCE
+ VersionsParser.INSTANCE,
+ SupportedParser.INSTANCE,
+ Supported2Parser.INSTANCE
));
private static final Map<String,ExtensionParser<?>> parsersMap = new TreeMap<String,ExtensionParser<?>>(String.CASE_INSENSITIVE_ORDER) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/Supported2Parser.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/Supported2Parser.java b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/Supported2Parser.java
new file mode 100644
index 0000000..f8e3fba
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/Supported2Parser.java
@@ -0,0 +1,91 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.common.subsystem.sftp.extensions;
+
+import java.util.Collection;
+
+import org.apache.sshd.common.subsystem.sftp.SftpConstants;
+import org.apache.sshd.common.subsystem.sftp.extensions.Supported2Parser.Supported2;
+import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+
+/**
+ * Parses the "supported2" extension as defined in
+ * <A HREF="https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#page-10">DRAFT 13 section 5.4</A>
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class Supported2Parser extends AbstractParser<Supported2> {
+ /**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ * @see <A HREF="https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#page-10">DRAFT 13 section 5.4</A>
+ */
+ public static class Supported2 {
+ public int supportedAttributeMask;
+ public int supportedAttributeBits;
+ public int supportedOpenFlags;
+ public int supportedAccessMask;
+ public int maxReadSize;
+ public short supportedOpenBlockVector;
+ public short supportedBlock;
+// uint32 attrib-extension-count
+ public Collection<String> attribExtensionNames;
+// uint32 extension-count
+ public Collection<String> extensionNames;
+
+ @Override
+ public String toString() {
+ return "attrsMask=0x" + Integer.toHexString(supportedAttributeMask)
+ + ",attrsBits=0x" + Integer.toHexString(supportedAttributeBits)
+ + ",openFlags=0x" + Integer.toHexString(supportedOpenFlags)
+ + ",accessMask=0x" + Integer.toHexString(supportedAccessMask)
+ + ",maxRead=" + maxReadSize
+ + ",openBlock=0x" + Integer.toHexString(supportedOpenBlockVector & 0xFFFF)
+ + ",block=" + Integer.toHexString(supportedBlock & 0xFFFF)
+ + ",attribs=" + attribExtensionNames
+ + ",exts=" + extensionNames
+ ;
+ }
+ }
+
+ public static final Supported2Parser INSTANCE = new Supported2Parser();
+
+ public Supported2Parser() {
+ super(SftpConstants.EXT_SUPPORTED2);
+ }
+
+ @Override
+ public Supported2 parse(byte[] input, int offset, int len) {
+ return parse(new ByteArrayBuffer(input, offset, len));
+ }
+
+ public Supported2 parse(Buffer buffer) {
+ Supported2 sup2 = new Supported2();
+ sup2.supportedAttributeMask = buffer.getInt();
+ sup2.supportedAttributeBits = buffer.getInt();
+ sup2.supportedOpenFlags = buffer.getInt();
+ sup2.supportedAccessMask = buffer.getInt();
+ sup2.maxReadSize = buffer.getInt();
+ sup2.supportedOpenBlockVector = buffer.getShort();
+ sup2.supportedBlock = buffer.getShort();
+ sup2.attribExtensionNames = buffer.getStringList(true);
+ sup2.extensionNames = buffer.getStringList(true);
+ return sup2;
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/SupportedParser.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/SupportedParser.java b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/SupportedParser.java
new file mode 100644
index 0000000..fc13c49
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/SupportedParser.java
@@ -0,0 +1,80 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.sshd.common.subsystem.sftp.extensions;
+
+import java.util.Collection;
+
+import org.apache.sshd.common.subsystem.sftp.SftpConstants;
+import org.apache.sshd.common.subsystem.sftp.extensions.SupportedParser.Supported;
+import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+
+/**
+ * Parses the "supported" extension as defined in
+ * <A HREF="http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-05.txt">DRAFT 05 - section 4.4</A>
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class SupportedParser extends AbstractParser<Supported> {
+ /**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ * @see <A HREF="http://tools.ietf.org/wg/secsh/draft-ietf-secsh-filexfer/draft-ietf-secsh-filexfer-05.txt">DRAFT 05 - section 4.4</A>
+ */
+ public static class Supported {
+ public int supportedAttributeMask;
+ public int supportedAttributeBits;
+ public int supportedOpenFlags;
+ public int supportedAccessMask;
+ public int maxReadSize;
+ public Collection<String> extensionNames;
+
+ @Override
+ public String toString() {
+ return "attrsMask=0x" + Integer.toHexString(supportedAttributeMask)
+ + ",attrsBits=0x" + Integer.toHexString(supportedAttributeBits)
+ + ",openFlags=0x" + Integer.toHexString(supportedOpenFlags)
+ + ",accessMask=0x" + Integer.toHexString(supportedAccessMask)
+ + ",maxReadSize=" + maxReadSize
+ + ",extensions=" + extensionNames
+ ;
+ }
+ }
+
+ public static final SupportedParser INSTANCE = new SupportedParser();
+
+ public SupportedParser() {
+ super(SftpConstants.EXT_SUPPORTED);
+ }
+
+ @Override
+ public Supported parse(byte[] input, int offset, int len) {
+ return parse(new ByteArrayBuffer(input, offset, len));
+ }
+
+ public Supported parse(Buffer buffer) {
+ Supported sup = new Supported();
+ sup.supportedAttributeMask = buffer.getInt();
+ sup.supportedAttributeBits = buffer.getInt();
+ sup.supportedOpenFlags = buffer.getInt();
+ sup.supportedAccessMask = buffer.getInt();
+ sup.maxReadSize = buffer.getInt();
+ sup.extensionNames = buffer.getStringList(false);
+ return sup;
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
index b4c507f..bada2de 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/Buffer.java
@@ -43,7 +43,11 @@ import java.security.spec.ECPublicKeySpec;
import java.security.spec.InvalidKeySpecException;
import java.security.spec.RSAPrivateCrtKeySpec;
import java.security.spec.RSAPublicKeySpec;
+import java.util.ArrayList;
import java.util.Collection;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
import java.util.Objects;
import org.apache.sshd.common.SshException;
@@ -104,6 +108,10 @@ public abstract class Buffer implements Readable {
Read methods
======================*/
+ public int getUByte() {
+ return getByte() & 0xFF;
+ }
+
public byte getByte() {
// TODO use Byte.BYTES for JDK-8
ensureAvailable(Byte.SIZE / Byte.SIZE);
@@ -111,6 +119,16 @@ public abstract class Buffer implements Readable {
return workBuf[0];
}
+ public short getShort() {
+ // TODO use Short.BYTES for JDK-8
+ ensureAvailable(Short.SIZE / Byte.SIZE);
+ getRawBytes(workBuf, 0, Short.SIZE / Byte.SIZE);
+ short v = (short) (((workBuf[1] << Byte.SIZE) & 0xFF00)
+ | ((workBuf[0] ) & 0xF))
+ ;
+ return v;
+ }
+
public int getInt() {
return (int) getUInt();
}
@@ -146,6 +164,89 @@ public abstract class Buffer implements Readable {
return getString(StandardCharsets.UTF_8);
}
+ /**
+ * @param usePrependedLength If {@code true} then there is a 32-bit
+ * value indicating the number of strings to read. Otherwise, the
+ * method will use a "greedy" reading of strings while more
+ * data available
+ * @return A {@link Collection} of the read strings
+ * @see #getStringList(boolean, Charset)
+ */
+ public Collection<String> getStringList(boolean usePrependedLength) {
+ return getStringList(usePrependedLength, StandardCharsets.UTF_8);
+ }
+
+ /**
+ * @param usePrependedLength If {@code true} then there is a 32-bit
+ * value indicating the number of strings to read. Otherwise, the
+ * method will use a "greedy" reading of strings while more
+ * data available
+ * @param charset The {@link Charset} to use for the string
+ * @return A {@link Collection} of the read strings
+ * @see {@link #getStringList(int, Charset)}
+ * @see {@link #getAvailableStrings()}
+ */
+ public Collection<String> getStringList(boolean usePrependedLength, Charset charset) {
+ if (usePrependedLength) {
+ int count = getInt();
+ return getStringList(count, charset);
+ } else {
+ return getAvailableStrings(charset);
+ }
+ }
+
+ /**
+ * @return The remaining data as a list of strings
+ * @see #getAvailableStrings(Charset)
+ */
+ public Collection<String> getAvailableStrings() {
+ return getAvailableStrings(StandardCharsets.UTF_8);
+ }
+
+ /**
+ * @param charset The {@link Charset} to use for the strings
+ * @return The remaining data as a list of strings
+ * @see #available()
+ * @see #getString(Charset)
+ */
+ public Collection<String> getAvailableStrings(Charset charset) {
+ Collection<String> list = new LinkedList<String>();
+ while(available() > 0) {
+ String s = getString(charset);
+ list.add(s);
+ }
+
+ return list;
+ }
+
+ /**
+ * @param count The <U>exact</V> number of strings to read - can be zero
+ * @return A {@link List} with the specified number of strings
+ * @see #getStringList(int, Charset)
+ */
+ public List<String> getStringList(int count) {
+ return getStringList(count, StandardCharsets.UTF_8);
+ }
+
+ /**
+ * @param count The <U>exact</V> number of strings to read - can be zero
+ * @param charset The {@link Charset} of the strings
+ * @return A {@link List} with the specified number of strings
+ */
+ public List<String> getStringList(int count, Charset charset) {
+ if (count == 0) {
+ return Collections.emptyList();
+ }
+
+ List<String> list = new ArrayList<String>(count);
+ for (int index = 0; index < count; index++) {
+ String s = getString(charset);
+ list.add(s);
+ }
+
+ return list;
+ }
+
public abstract String getString(Charset charset);
public BigInteger getMPInt() {
@@ -386,22 +487,33 @@ public abstract class Buffer implements Readable {
}
/**
- * Encodes the {@link Objects#toString(Object)} value of each member
- * @param objects The objects to be encoded in the buffer
- * @see #putStringList(Collection, Charset)
+ * Encodes the {@link Objects#toString(Object)} value of each member.
+ * @param objects The objects to be encoded in the buffer - OK if
+ * {@code null}/empty
+ * @param prependLength If {@code true} then the list is preceded by
+ * a 32-bit count of the number of members in the list
+ * @see #putStringList(Collection, Charset, boolean)
*/
- public void putStringList(Collection<?> objects) {
- putStringList(objects, StandardCharsets.UTF_8);
+ public void putStringList(Collection<?> objects, boolean prependLength) {
+ putStringList(objects, StandardCharsets.UTF_8, prependLength);
}
/**
* Encodes the {@link Objects#toString(Object)} value of each member
- * @param objects The objects to be encoded in the buffer
+ * @param objects The objects to be encoded in the buffer - OK if
+ * {@code null}/empty
* @param charset The {@link Charset} to use for encoding
+ * @param prependLength If {@code true} then the list is preceded by
+ * a 32-bit count of the number of members in the list
* @see #putString(String, Charset)
*/
- public void putStringList(Collection<?> objects, Charset charset) {
- if (GenericUtils.isEmpty(objects)) {
+ public void putStringList(Collection<?> objects, Charset charset, boolean prependLength) {
+ int numObjects = GenericUtils.size(objects);
+ if (prependLength) {
+ putInt(numObjects);
+ }
+
+ if (numObjects <= 0) {
return;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/common/util/io/IoUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/io/IoUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/io/IoUtils.java
index 4550433..7b37d50 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/io/IoUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/io/IoUtils.java
@@ -24,6 +24,7 @@ import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
+import java.nio.file.CopyOption;
import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.LinkOption;
@@ -47,6 +48,7 @@ import org.apache.sshd.common.util.OsUtils;
*/
public final class IoUtils {
public static final OpenOption[] EMPTY_OPEN_OPTIONS = new OpenOption[0];
+ public static final CopyOption[] EMPTY_COPY_OPTIONS = new CopyOption[0];
public static final LinkOption[] EMPTY_LINK_OPTIONS = new LinkOption[0];
private static final LinkOption[] NO_FOLLOW_OPTIONS = new LinkOption[] { LinkOption.NOFOLLOW_LINKS };
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthKeyboardInteractive.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthKeyboardInteractive.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthKeyboardInteractive.java
index 0bd506c..0396b35 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthKeyboardInteractive.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthKeyboardInteractive.java
@@ -63,7 +63,7 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
session.writePacket(buffer);
return null;
} else {
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd != SshConstants.SSH_MSG_USERAUTH_INFO_RESPONSE) {
throw new SshException("Received unexpected message: " + cmd);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java
index 9495c34..aab20d4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java
@@ -104,7 +104,7 @@ public class UserAuthGSS extends AbstractUserAuth {
}
else
{
- byte msg = buffer.getByte();
+ int msg = buffer.getUByte();
if (!((msg == SshConstants.SSH_MSG_USERAUTH_INFO_RESPONSE)
|| (msg == SshConstants.SSH_MSG_USERAUTH_GSSAPI_MIC) && context.isEstablished())) {
throw new SshException(SshConstants.SSH2_DISCONNECT_PROTOCOL_ERROR,
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
index c3800cc..99512ac 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
@@ -95,7 +95,7 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
@Override
public boolean next(Buffer buffer) throws Exception {
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd == SshConstants.SSH_MSG_KEX_DH_GEX_REQUEST_OLD && expected == SshConstants.SSH_MSG_KEX_DH_GEX_REQUEST) {
log.debug("Received SSH_MSG_KEX_DH_GEX_REQUEST_OLD");
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
index 75efab9..8edc61c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
@@ -81,7 +81,7 @@ public class DHGServer extends AbstractDHServerKeyExchange {
@Override
public boolean next(Buffer buffer) throws Exception {
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd != SshConstants.SSH_MSG_KEXDH_INIT) {
throw new SshException(SshConstants.SSH2_DISCONNECT_KEY_EXCHANGE_FAILED,
"Protocol error: expected packet " + SshConstants.SSH_MSG_KEXDH_INIT + ", got " + cmd);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/server/session/ServerUserAuthService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerUserAuthService.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerUserAuthService.java
index 0421c61..7f64dce 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerUserAuthService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerUserAuthService.java
@@ -105,7 +105,7 @@ public class ServerUserAuthService extends CloseableUtils.AbstractCloseable impl
}
@Override
- public void process(byte cmd, Buffer buffer) throws Exception {
+ public void process(int cmd, Buffer buffer) throws Exception {
Boolean authed = Boolean.FALSE;
if (cmd == SshConstants.SSH_MSG_USERAUTH_REQUEST) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
index f5c8ba9..0ee0421 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/subsystem/sftp/SftpSubsystem.java
@@ -145,7 +145,8 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
Collections.unmodifiableSet(
GenericUtils.asSortedSet(String.CASE_INSENSITIVE_ORDER,
Arrays.asList(
- SftpConstants.EXT_VERSELECT
+ SftpConstants.EXT_VERSELECT,
+ SftpConstants.EXT_COPYFILE
)));
static {
@@ -497,7 +498,7 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
protected void process(Buffer buffer) throws IOException {
int length = buffer.getInt();
- int type = buffer.getByte();
+ int type = buffer.getUByte();
int id = buffer.getInt();
if (log.isDebugEnabled()) {
log.debug("process(length={}, type={}, id={})",
@@ -598,6 +599,9 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
case SftpConstants.EXT_VERSELECT:
doVersionSelect(buffer, id);
break;
+ case SftpConstants.EXT_COPYFILE:
+ doCopyFile(buffer, id);
+ break;
default:
log.info("Received unsupported SSH_FXP_EXTENDED({})", extension);
sendStatus(id, SSH_FX_OP_UNSUPPORTED, "Command SSH_FXP_EXTENDED(" + extension + ") is unsupported or not implemented");
@@ -819,14 +823,14 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
oldPath, newPath, Integer.toHexString(flags));
}
+ List<CopyOption> opts = new ArrayList<>();
+ if ((flags & SSH_FXP_RENAME_ATOMIC) != 0) {
+ opts.add(StandardCopyOption.ATOMIC_MOVE);
+ }
+ if ((flags & SSH_FXP_RENAME_OVERWRITE) != 0) {
+ opts.add(StandardCopyOption.REPLACE_EXISTING);
+ }
try {
- List<CopyOption> opts = new ArrayList<>();
- if ((flags & SSH_FXP_RENAME_ATOMIC) != 0) {
- opts.add(StandardCopyOption.ATOMIC_MOVE);
- }
- if ((flags & SSH_FXP_RENAME_OVERWRITE) != 0) {
- opts.add(StandardCopyOption.REPLACE_EXISTING);
- }
Path o = resolveFile(oldPath);
Path n = resolveFile(newPath);
Files.move(o, n, opts.toArray(new CopyOption[opts.size()]));
@@ -836,6 +840,31 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
}
}
+ // see https://tools.ietf.org/html/draft-ietf-secsh-filexfer-extensions-00#section-6
+ protected void doCopyFile(Buffer buffer, int id) throws IOException {
+ String srcFile = buffer.getString();
+ String dstFile = buffer.getString();
+ boolean overwriteDestination = buffer.getBoolean();
+ if (log.isDebugEnabled()) {
+ log.debug("SSH_FXP_EXTENDED[{}] (src={}, dst={}, overwrite=0x{})",
+ SftpConstants.EXT_COPYFILE, srcFile, dstFile, Boolean.valueOf(overwriteDestination));
+ }
+
+ CopyOption[] opts = overwriteDestination
+ ? new CopyOption[] { StandardCopyOption.REPLACE_EXISTING }
+ : IoUtils.EMPTY_COPY_OPTIONS
+ ;
+
+ try {
+ Path src = resolveFile(srcFile);
+ Path dst = resolveFile(dstFile);
+ Files.copy(src, dst, opts);
+ sendStatus(id, SSH_FX_OK, "");
+ } catch (IOException e) {
+ sendStatus(id, e);
+ }
+ }
+
protected void doStat(Buffer buffer, int id) throws IOException {
String path = buffer.getString();
int flags = SSH_FILEXFER_ATTR_ALL;
@@ -877,7 +906,7 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
// Read control byte
int control = 0;
if (buffer.available() > 0) {
- control = buffer.getByte();
+ control = buffer.getUByte();
}
List<String> paths = new ArrayList<>();
while (buffer.available() > 0) {
@@ -1423,7 +1452,7 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
// max-read-size
buffer.putInt(0);
// supported extensions
- buffer.putStringList(extras);
+ buffer.putStringList(extras, false);
BufferUtils.updateLengthPlaceholder(buffer, lenPos);
}
@@ -1436,6 +1465,7 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
* @param extras The extra extensions that are available and can be reported
* - may be {@code null}/empty
* @see SftpConstants#EXT_SUPPORTED
+ * @see <A HREF="https://tools.ietf.org/html/draft-ietf-secsh-filexfer-13#page-10">DRAFT 13 section 5.4</A>
*/
protected void appendSupported2Extension(Buffer buffer, Collection<String> extras) {
buffer.putString(EXT_SUPPORTED2);
@@ -1459,12 +1489,10 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
buffer.putShort(0);
// supported-block-vector
buffer.putShort(0);
- // attrib-extension-count
- buffer.putInt(0);
- // extension-count
- buffer.putInt(0);
- // supported extensions
- buffer.putStringList(extras);
+ // attrib-extension-count + attributes name
+ buffer.putStringList(Collections.<String>emptyList(), true);
+ // extension-count + supported extensions
+ buffer.putStringList(extras, true);
BufferUtils.updateLengthPlaceholder(buffer, lenPos);
}
@@ -2044,7 +2072,7 @@ public class SftpSubsystem extends AbstractLoggingBean implements Command, Runna
Map<String, Object> attrs = new HashMap<>();
int flags = buffer.getInt();
if (version >= SFTP_V4) {
- byte type = buffer.getByte();
+ int type = buffer.getUByte();
switch (type) {
case SSH_FILEXFER_TYPE_REGULAR:
attrs.put("isRegular", Boolean.TRUE);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/test/java/org/apache/sshd/WindowTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/WindowTest.java b/sshd-core/src/test/java/org/apache/sshd/WindowTest.java
index a97c8a0..251ea64 100644
--- a/sshd-core/src/test/java/org/apache/sshd/WindowTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/WindowTest.java
@@ -105,7 +105,7 @@ public class WindowTest extends BaseTestSupport {
return new ServerUserAuthService(session) {
@SuppressWarnings("synthetic-access")
@Override
- public void process(byte cmd, Buffer buffer) throws Exception {
+ public void process(int cmd, Buffer buffer) throws Exception {
authLatch.await();
super.process(cmd, buffer);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java b/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
index 85fa7dc..4aebff8 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/ClientTest.java
@@ -143,7 +143,7 @@ public class ClientTest extends BaseTestSupport {
return new ServerUserAuthService(session) {
@SuppressWarnings("synthetic-access")
@Override
- public void process(byte cmd, Buffer buffer) throws Exception {
+ public void process(int cmd, Buffer buffer) throws Exception {
authLatch.await();
super.process(cmd, buffer);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
index b4a1cef..62a142b 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpTest.java
@@ -34,10 +34,12 @@ import java.nio.file.FileSystem;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.EnumSet;
import java.util.Map;
import java.util.Random;
+import java.util.Set;
import java.util.Vector;
import java.util.concurrent.TimeUnit;
@@ -49,6 +51,9 @@ import org.apache.sshd.common.file.root.RootedFileSystemProvider;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.subsystem.sftp.SftpConstants;
import org.apache.sshd.common.subsystem.sftp.extensions.ParserUtils;
+import org.apache.sshd.common.subsystem.sftp.extensions.Supported2Parser.Supported2;
+import org.apache.sshd.common.subsystem.sftp.extensions.SupportedParser.Supported;
+import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.OsUtils;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
import org.apache.sshd.common.util.io.IoUtils;
@@ -589,7 +594,7 @@ public class SftpTest extends BaseTestSupport {
Map<String,byte[]> extensions = sftp.getServerExtensions();
for (String name : new String[] {
SftpConstants.EXT_NEWLINE, SftpConstants.EXT_VERSIONS,
- // SftpConstants.EXT_VENDORID,
+ SftpConstants.EXT_VENDORID,
SftpConstants.EXT_SUPPORTED, SftpConstants.EXT_SUPPORTED2
}) {
assertTrue("Missing extension=" + name, extensions.containsKey(name));
@@ -597,9 +602,15 @@ public class SftpTest extends BaseTestSupport {
Map<String,?> data = ParserUtils.parse(extensions);
for (Map.Entry<String,?> de : data.entrySet()) {
- System.out.append('\t').append(de.getKey()).append(": ").println(de.getValue());
+ String extName = de.getKey();
+ Object extValue = de.getValue();
+ System.out.append('\t').append(extName).append(": ").println(extValue);
+ if (SftpConstants.EXT_SUPPORTED.equalsIgnoreCase(extName)) {
+ assertSupportedExtensions(extName, ((Supported) extValue).extensionNames);
+ } else if (SftpConstants.EXT_SUPPORTED2.equalsIgnoreCase(extName)) {
+ assertSupportedExtensions(extName, ((Supported2) extValue).extensionNames);
+ }
}
-
}
} finally {
client.stop();
@@ -607,6 +618,21 @@ public class SftpTest extends BaseTestSupport {
}
}
+ private static Set<String> EXPECTED_EXTENSIONS =
+ Collections.unmodifiableSet(
+ GenericUtils.asSortedSet(String.CASE_INSENSITIVE_ORDER,
+ Arrays.asList(
+ SftpConstants.EXT_VERSELECT,
+ SftpConstants.EXT_COPYFILE
+ )));
+ private static void assertSupportedExtensions(String extName, Collection<String> extensionNames) {
+ assertEquals(extName + "[count]", EXPECTED_EXTENSIONS.size(), GenericUtils.size(extensionNames));
+
+ for (String name : EXPECTED_EXTENSIONS) {
+ assertTrue(extName + " - missing " + name, extensionNames.contains(name));
+ }
+ }
+
@Test
public void testCreateSymbolicLink() throws Exception {
// Do not execute on windows as the file system does not support symlinks
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/test/java/org/apache/sshd/deprecated/ClientUserAuthServiceOld.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/deprecated/ClientUserAuthServiceOld.java b/sshd-core/src/test/java/org/apache/sshd/deprecated/ClientUserAuthServiceOld.java
index 42c4a5a..98602fa 100644
--- a/sshd-core/src/test/java/org/apache/sshd/deprecated/ClientUserAuthServiceOld.java
+++ b/sshd-core/src/test/java/org/apache/sshd/deprecated/ClientUserAuthServiceOld.java
@@ -91,7 +91,7 @@ public class ClientUserAuthServiceOld extends CloseableUtils.AbstractCloseable i
}
@Override
- public void process(byte cmd, Buffer buffer) throws Exception {
+ public void process(int cmd, Buffer buffer) throws Exception {
if (this.authFuture.isSuccess()) {
throw new IllegalStateException("UserAuth message delivered to authenticated client");
} else if (this.authFuture.isDone()) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthAgent.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthAgent.java b/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthAgent.java
index 74ce63b..e0f0b12 100644
--- a/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthAgent.java
+++ b/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthAgent.java
@@ -96,7 +96,7 @@ public class UserAuthAgent extends AbstractUserAuth {
return Result.Failure;
}
} else {
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd == SshConstants.SSH_MSG_USERAUTH_SUCCESS) {
log.info("Received SSH_MSG_USERAUTH_SUCCESS");
agent.close();
@@ -112,7 +112,7 @@ public class UserAuthAgent extends AbstractUserAuth {
}
} else {
// TODO: check packets
- log.info("Received unknown packet: {}", Byte.valueOf(cmd));
+ log.info("Received unknown packet: {}", Integer.valueOf(cmd));
return Result.Continued;
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthKeyboardInteractive.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthKeyboardInteractive.java b/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthKeyboardInteractive.java
index 3386428..947d125 100644
--- a/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthKeyboardInteractive.java
+++ b/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthKeyboardInteractive.java
@@ -59,7 +59,7 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
session.writePacket(buffer);
return Result.Continued;
} else {
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
switch (cmd) {
case SSH_MSG_USERAUTH_INFO_REQUEST:
log.debug("Received SSH_MSG_USERAUTH_INFO_REQUEST");
@@ -72,7 +72,7 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
boolean[] echo = new boolean[num];
for (int i = 0; i < num; i++) {
prompt[i] = buffer.getString();
- echo[i] = (buffer.getByte() != 0);
+ echo[i] = buffer.getBoolean();
}
log.debug("Promt: {}", Arrays.toString(prompt));
log.debug("Echo: {}", echo);
@@ -107,7 +107,7 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
log.debug("Received SSH_MSG_USERAUTH_FAILURE");
return Result.Failure;
default:
- log.debug("Received unknown packet {}", Byte.valueOf(cmd));
+ log.debug("Received unknown packet {}", Integer.valueOf(cmd));
return Result.Continued;
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPassword.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPassword.java b/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPassword.java
index 4dde6cc..53a77c8 100644
--- a/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPassword.java
+++ b/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPassword.java
@@ -50,7 +50,7 @@ public class UserAuthPassword extends AbstractUserAuth {
session.writePacket(buffer);
return Result.Continued;
} else {
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd == SshConstants.SSH_MSG_USERAUTH_SUCCESS) {
log.debug("Received SSH_MSG_USERAUTH_SUCCESS");
return Result.Success;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/9d066221/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPublicKey.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPublicKey.java b/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPublicKey.java
index f303017..c3fbae7 100644
--- a/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPublicKey.java
+++ b/sshd-core/src/test/java/org/apache/sshd/deprecated/UserAuthPublicKey.java
@@ -92,7 +92,7 @@ public class UserAuthPublicKey extends AbstractUserAuth {
throw (IOException) new IOException("Error performing public key authentication").initCause(e);
}
} else {
- byte cmd = buffer.getByte();
+ int cmd = buffer.getUByte();
if (cmd == SshConstants.SSH_MSG_USERAUTH_SUCCESS) {
log.debug("Received SSH_MSG_USERAUTH_SUCCESS");
return Result.Success;
@@ -100,7 +100,7 @@ public class UserAuthPublicKey extends AbstractUserAuth {
log.debug("Received SSH_MSG_USERAUTH_FAILURE");
return Result.Failure;
} else {
- log.debug("Received unknown packet {}", Byte.valueOf(cmd));
+ log.debug("Received unknown packet {}", Integer.valueOf(cmd));
// TODO: check packets
return Result.Continued;
}