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/12/17 06:32:18 UTC
mina-sshd git commit: [SSHD-616] Added initial support for OpenSSH
"hostkeys-XXX" global requests
Repository: mina-sshd
Updated Branches:
refs/heads/master 68844229a -> 65ac5ba7c
[SSHD-616] Added initial support for OpenSSH "hostkeys-XXX" global requests
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/65ac5ba7
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/65ac5ba7
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/65ac5ba7
Branch: refs/heads/master
Commit: 65ac5ba7c5d8ca3917184e442301323a68f1020b
Parents: 6884422
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Thu Dec 17 07:32:06 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Thu Dec 17 07:32:06 2015 +0200
----------------------------------------------------------------------
.../org/apache/sshd/agent/local/AgentImpl.java | 2 +-
.../org/apache/sshd/client/ClientBuilder.java | 10 ++
.../client/auth/pubkey/KeyPairIdentity.java | 2 +-
.../client/global/OpenSshHostKeysHandler.java | 62 ++++++++++
.../org/apache/sshd/common/SshException.java | 23 ++--
.../sshd/common/config/keys/KeyUtils.java | 2 +-
.../global/AbstractOpenSshHostKeysHandler.java | 96 +++++++++++++++
.../common/keyprovider/KeyPairProvider.java | 5 +
.../session/AbstractConnectionService.java | 22 ++--
...AbstractConnectionServiceRequestHandler.java | 44 +++++++
.../ConnectionServiceRequestHandler.java | 1 -
.../apache/sshd/common/util/buffer/Buffer.java | 76 +++++-------
.../keys/AbstractBufferPublicKeyParser.java | 87 +++++++++++++
.../util/buffer/keys/BufferPublicKeyParser.java | 121 +++++++++++++++++++
.../buffer/keys/DSSBufferPublicKeyParser.java | 51 ++++++++
.../buffer/keys/ECBufferPublicKeyParser.java | 81 +++++++++++++
.../keys/ED25519BufferPublicKeyParser.java | 56 +++++++++
.../buffer/keys/RSABufferPublicKeyParser.java | 48 ++++++++
.../org/apache/sshd/server/ServerBuilder.java | 4 +-
.../global/CancelTcpipForwardHandler.java | 48 ++++----
.../sshd/server/global/KeepAliveHandler.java | 8 +-
.../server/global/NoMoreSessionsHandler.java | 8 +-
.../server/global/OpenSshHostKeysHandler.java | 100 +++++++++++++++
.../sshd/server/global/TcpipForwardHandler.java | 49 ++++----
.../org/apache/sshd/server/kex/DHGEXServer.java | 5 +-
.../org/apache/sshd/server/kex/DHGServer.java | 5 +-
26 files changed, 871 insertions(+), 145 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java
index cb562a6..3ccb551 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/local/AgentImpl.java
@@ -91,7 +91,7 @@ public class AgentImpl implements SshAgent {
throw new SshException("Unsupported key type: " + pubKey.getClass().getSimpleName());
}
verif.initSigner(kp.getPrivate());
- verif.update(data, 0, data.length);
+ verif.update(data);
return verif.sign();
} catch (IOException e) {
throw e;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/client/ClientBuilder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/ClientBuilder.java b/sshd-core/src/main/java/org/apache/sshd/client/ClientBuilder.java
index fe1deca..0129361 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/ClientBuilder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/ClientBuilder.java
@@ -26,6 +26,7 @@ import java.util.List;
import org.apache.sshd.client.config.hosts.DefaultConfigFileHostEntryResolver;
import org.apache.sshd.client.config.hosts.HostConfigEntryResolver;
import org.apache.sshd.client.config.keys.ClientIdentityLoader;
+import org.apache.sshd.client.global.OpenSshHostKeysHandler;
import org.apache.sshd.client.kex.DHGClient;
import org.apache.sshd.client.kex.DHGEXClient;
import org.apache.sshd.client.keyverifier.AcceptAllServerKeyVerifier;
@@ -33,9 +34,11 @@ import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
import org.apache.sshd.common.BaseBuilder;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.channel.Channel;
+import org.apache.sshd.common.channel.RequestHandler;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.kex.DHFactory;
import org.apache.sshd.common.kex.KeyExchange;
+import org.apache.sshd.common.session.ConnectionService;
import org.apache.sshd.common.util.Transformer;
import org.apache.sshd.server.forward.ForwardedTcpipFactory;
@@ -59,6 +62,9 @@ public class ClientBuilder extends BaseBuilder<SshClient, ClientBuilder> {
public static final List<NamedFactory<Channel>> DEFAULT_CHANNEL_FACTORIES =
Collections.unmodifiableList(Arrays.<NamedFactory<Channel>>asList(ForwardedTcpipFactory.INSTANCE));
+ public static final List<RequestHandler<ConnectionService>> DEFAULT_GLOBAL_REQUEST_HANDLERS =
+ Collections.unmodifiableList(Arrays.<RequestHandler<ConnectionService>>asList(
+ OpenSshHostKeysHandler.INSTANCE));
public static final ServerKeyVerifier DEFAULT_SERVER_KEY_VERIFIER = AcceptAllServerKeyVerifier.INSTANCE;
public static final HostConfigEntryResolver DEFAULT_HOST_CONFIG_ENTRY_RESOLVER = DefaultConfigFileHostEntryResolver.INSTANCE;
@@ -106,6 +112,10 @@ public class ClientBuilder extends BaseBuilder<SshClient, ClientBuilder> {
channelFactories = DEFAULT_CHANNEL_FACTORIES;
}
+ if (globalRequestHandlers == null) {
+ globalRequestHandlers = DEFAULT_GLOBAL_REQUEST_HANDLERS;
+ }
+
if (serverKeyVerifier == null) {
serverKeyVerifier = DEFAULT_SERVER_KEY_VERIFIER;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/KeyPairIdentity.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/KeyPairIdentity.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/KeyPairIdentity.java
index f24b65f..5f3e9e0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/KeyPairIdentity.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/pubkey/KeyPairIdentity.java
@@ -54,7 +54,7 @@ public class KeyPairIdentity implements PublicKeyIdentity {
"No signer could be located for key type=%s",
keyType);
verifier.initSigner(pair.getPrivate());
- verifier.update(data, 0, data.length);
+ verifier.update(data);
return verifier.sign();
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/client/global/OpenSshHostKeysHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/global/OpenSshHostKeysHandler.java b/sshd-core/src/main/java/org/apache/sshd/client/global/OpenSshHostKeysHandler.java
new file mode 100644
index 0000000..0e81b0e
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/client/global/OpenSshHostKeysHandler.java
@@ -0,0 +1,62 @@
+/*
+ * 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.client.global;
+
+import java.security.PublicKey;
+import java.util.Collection;
+
+import org.apache.sshd.common.global.AbstractOpenSshHostKeysHandler;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.buffer.keys.BufferPublicKeyParser;
+
+/**
+ * A handler for the "hostkeys-00@openssh.com" request - for now, only
+ * reads the presented host key.
+ *
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ * @see <a href="https://github.com/openssh/openssh-portable/blob/master/PROTOCOL">OpenSSH protocol - section 2.5</a>
+ */
+public class OpenSshHostKeysHandler extends AbstractOpenSshHostKeysHandler {
+ public static final String REQUEST = "hostkeys-00@openssh.com";
+ public static final OpenSshHostKeysHandler INSTANCE = new OpenSshHostKeysHandler();
+
+ public OpenSshHostKeysHandler() {
+ super(REQUEST);
+ }
+
+ public OpenSshHostKeysHandler(BufferPublicKeyParser<? extends PublicKey> parser) {
+ super(REQUEST, parser);
+ }
+
+ @Override
+ protected Result handleHostKeys(Session session, Collection<? extends PublicKey> keys, boolean wantReply, Buffer buffer) throws Exception {
+ // according to the spec, no reply should be required
+ ValidateUtils.checkTrue(!wantReply, "Unexpected reply required for the host keys of %s", session);
+ if (log.isDebugEnabled()) {
+ log.debug("handleHostKeys({})[want-reply={}] received {} keys",
+ session, wantReply, GenericUtils.size(keys));
+ }
+
+ return Result.Replied;
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/common/SshException.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/SshException.java b/sshd-core/src/main/java/org/apache/sshd/common/SshException.java
index e7cea6e..9f4b1d1 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/SshException.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/SshException.java
@@ -20,8 +20,11 @@ package org.apache.sshd.common;
import java.io.IOException;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+
/**
- * TODO Add javadoc
+ * Represents an SSH related exception
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
@@ -31,24 +34,20 @@ public class SshException extends IOException {
private final int disconnectCode;
- public SshException() {
- this(0, null, null);
+ public SshException(String message) {
+ this(message, null);
}
- public SshException(String message) {
- this(0, message, null);
+ public SshException(Throwable cause) {
+ this(ValidateUtils.checkNotNull(cause, "No cause").getMessage(), cause);
}
public SshException(String message, Throwable cause) {
this(0, message, cause);
}
- public SshException(Throwable cause) {
- this(0, null, cause);
- }
-
public SshException(int disconnectCode) {
- this(disconnectCode, null, null);
+ this(disconnectCode, SshConstants.getDisconnectReasonName(disconnectCode));
}
public SshException(int disconnectCode, String message) {
@@ -56,11 +55,11 @@ public class SshException extends IOException {
}
public SshException(int disconnectCode, Throwable cause) {
- this(disconnectCode, null, cause);
+ this(disconnectCode, SshConstants.getDisconnectReasonName(disconnectCode), cause);
}
public SshException(int disconnectCode, String message, Throwable cause) {
- super(message);
+ super(GenericUtils.isEmpty(message) ? SshConstants.getDisconnectReasonName(disconnectCode) : message);
this.disconnectCode = disconnectCode;
if (cause != null) {
initCause(cause);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
index 2acc7ad..9622a3a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
@@ -446,7 +446,7 @@ public final class KeyUtils {
* @see #getFingerPrint(Digest, PublicKey)
*/
public static String getFingerPrint(Factory<? extends Digest> f, PublicKey key) {
- return getFingerPrint(ValidateUtils.checkNotNull(f, "No digest factory").create(), key);
+ return (key == null) ? null : getFingerPrint(ValidateUtils.checkNotNull(f, "No digest factory").create(), key);
}
/**
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/common/global/AbstractOpenSshHostKeysHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/global/AbstractOpenSshHostKeysHandler.java b/sshd-core/src/main/java/org/apache/sshd/common/global/AbstractOpenSshHostKeysHandler.java
new file mode 100644
index 0000000..28cb4d5
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/global/AbstractOpenSshHostKeysHandler.java
@@ -0,0 +1,96 @@
+/*
+ * 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.global;
+
+import java.security.PublicKey;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.LinkedList;
+
+import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.session.AbstractConnectionServiceRequestHandler;
+import org.apache.sshd.common.session.ConnectionService;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.buffer.keys.BufferPublicKeyParser;
+import org.apache.sshd.common.util.buffer.keys.ED25519BufferPublicKeyParser;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractOpenSshHostKeysHandler extends AbstractConnectionServiceRequestHandler {
+
+ private final String request;
+ private final BufferPublicKeyParser<? extends PublicKey> parser;
+
+ protected AbstractOpenSshHostKeysHandler(String request) {
+ // TODO use only the default parser once ED25519 implementation is complete (see SSHD-440)
+ this(request, BufferPublicKeyParser.Utils.aggregate(Arrays.asList(
+ BufferPublicKeyParser.Utils.DEFAULT,
+ ED25519BufferPublicKeyParser.IGNORING
+ )));
+ }
+
+ protected AbstractOpenSshHostKeysHandler(String request, BufferPublicKeyParser<? extends PublicKey> parser) {
+ this.request = ValidateUtils.checkNotNullAndNotEmpty(request, "No request identifier");
+ this.parser = ValidateUtils.checkNotNull(parser, "No publick keys extractor");
+ }
+
+ public final String getRequestName() {
+ return request;
+ }
+
+ public BufferPublicKeyParser<? extends PublicKey> getPublicKeysParser() {
+ return parser;
+ }
+
+ @Override
+ public Result process(ConnectionService connectionService, String request, boolean wantReply, Buffer buffer) throws Exception {
+ String expected = getRequestName();
+ if (!expected.equals(request)) {
+ return super.process(connectionService, request, wantReply, buffer);
+ }
+
+ Collection<PublicKey> keys = new LinkedList<>();
+ BufferPublicKeyParser<? extends PublicKey> p = getPublicKeysParser();
+ if (p != null) {
+ while (buffer.available() > 0) {
+ PublicKey key = buffer.getPublicKey(p);
+ if (log.isDebugEnabled()) {
+ log.debug("process({})[{}] key type={}, fingerprint={}",
+ connectionService, request, KeyUtils.getKeyType(key), KeyUtils.getFingerPrint(key));
+ }
+ if (key != null) {
+ keys.add(key);
+ }
+ }
+ }
+
+ return handleHostKeys(connectionService.getSession(), keys, wantReply, buffer);
+ }
+
+ protected abstract Result handleHostKeys(Session session, Collection<? extends PublicKey> keys, boolean wantReply, Buffer buffer) throws Exception;
+
+ @Override
+ public String toString() {
+ return getRequestName();
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java b/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java
index b4e7256..2357d48 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProvider.java
@@ -42,6 +42,11 @@ public interface KeyPairProvider extends KeyIdentityProvider {
String SSH_DSS = "ssh-dss";
/**
+ * SSH identifier for ED25519 elliptic curve keys
+ */
+ String SSH_ED25519 = "ssh-ed25519";
+
+ /**
* SSH identifier for EC keys in NIST curve P-256
*/
String ECDSA_SHA2_NISTP256 = ECCurves.nistp256.getKeyType();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/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 176c867..4dd8cdd 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
@@ -493,19 +493,19 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
this, handler.getClass().getSimpleName(), req, wantReply, result);
}
} else {
- sendResponse(buffer, req, result, wantReply);
+ sendGlobalResponse(buffer, req, result, wantReply);
return;
}
}
}
log.warn("globalRequest({}) unknown global request: {}", this, req);
- sendResponse(buffer, req, RequestHandler.Result.Unsupported, wantReply);
+ sendGlobalResponse(buffer, req, RequestHandler.Result.Unsupported, wantReply);
}
- protected void sendResponse(Buffer buffer, String req, RequestHandler.Result result, boolean wantReply) throws IOException {
+ protected void sendGlobalResponse(Buffer buffer, String req, RequestHandler.Result result, boolean wantReply) throws IOException {
if (log.isDebugEnabled()) {
- log.debug("sendResponse({})[{}] result={}, want-reply={}", this, req, result, Boolean.valueOf(wantReply));
+ log.debug("sendGlobalResponse({})[{}] result={}, want-reply={}", this, req, result, wantReply);
}
if (RequestHandler.Result.Replied.equals(result) || (!wantReply)) {
@@ -513,15 +513,12 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
}
byte cmd = RequestHandler.Result.ReplySuccess.equals(result)
- ? SshConstants.SSH_MSG_CHANNEL_SUCCESS
- : SshConstants.SSH_MSG_CHANNEL_FAILURE;
- buffer.clear();
- // leave room for the SSH header
- buffer.ensureCapacity(5 + 1 + (Integer.SIZE / Byte.SIZE), RESPONSE_BUFFER_GROWTH_FACTOR);
- buffer.rpos(5);
- buffer.wpos(5);
+ ? SshConstants.SSH_MSG_REQUEST_SUCCESS
+ : SshConstants.SSH_MSG_REQUEST_FAILURE;
+ Session session = getSession();
+ buffer = session.prepareBuffer(cmd, BufferUtils.clear(buffer));
buffer.putByte(cmd);
- getSession().writePacket(buffer);
+ session.writePacket(buffer);
}
protected void requestSuccess(Buffer buffer) throws Exception {
@@ -536,5 +533,4 @@ public abstract class AbstractConnectionService<S extends AbstractSession> exten
public String toString() {
return getClass().getSimpleName() + "[" + getSession() + "]";
}
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionServiceRequestHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionServiceRequestHandler.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionServiceRequestHandler.java
new file mode 100644
index 0000000..d10786f
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractConnectionServiceRequestHandler.java
@@ -0,0 +1,44 @@
+/*
+ * 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.session;
+
+import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.logging.AbstractLoggingBean;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractConnectionServiceRequestHandler
+ extends AbstractLoggingBean
+ implements ConnectionServiceRequestHandler {
+
+ protected AbstractConnectionServiceRequestHandler() {
+ super();
+ }
+
+ @Override
+ public Result process(ConnectionService connectionService, String request, boolean wantReply, Buffer buffer) throws Exception {
+ if (log.isDebugEnabled()) {
+ log.debug("process({}) request={}, want-reply={}", connectionService, request, wantReply);
+ }
+
+ return Result.Unsupported;
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionServiceRequestHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionServiceRequestHandler.java b/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionServiceRequestHandler.java
index 029970f..3cf8481 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionServiceRequestHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/ConnectionServiceRequestHandler.java
@@ -33,5 +33,4 @@ public interface ConnectionServiceRequestHandler extends RequestHandler<Connecti
@Override
Result process(ConnectionService service, String request, boolean wantReply, Buffer buffer) throws Exception;
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/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 c7aa090..727f461 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
@@ -58,6 +58,8 @@ import org.apache.sshd.common.util.Int2IntFunction;
import org.apache.sshd.common.util.Readable;
import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.common.util.Transformer;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.keys.BufferPublicKeyParser;
/**
* Provides an abstract message buffer for encoding SSH messages
@@ -276,71 +278,51 @@ public abstract class Buffer implements Readable {
}
public PublicKey getPublicKey() throws SshException {
+ return getPublicKey(BufferPublicKeyParser.Utils.DEFAULT);
+ }
+
+ /**
+ * @param parser A {@link BufferPublicKeyParser} to extract the key from the buffer
+ * - never {@code null}
+ * @return The extracted {@link PublicKey} - may be {@code null} if the parser so decided
+ * @throws SshException If failed to extract the key
+ * @see #getRawPublicKey(BufferPublicKeyParser)
+ */
+ public PublicKey getPublicKey(BufferPublicKeyParser<? extends PublicKey> parser) throws SshException {
int ow = wpos();
int len = getInt();
wpos(rpos() + len);
try {
- return getRawPublicKey();
+ return getRawPublicKey(parser);
} finally {
wpos(ow);
}
}
public PublicKey getRawPublicKey() throws SshException {
- try {
- String keyAlg = getString();
- if (KeyPairProvider.SSH_RSA.equals(keyAlg)) {
- BigInteger e = getMPInt();
- BigInteger n = getMPInt();
- KeyFactory keyFactory = SecurityUtils.getKeyFactory("RSA");
- return keyFactory.generatePublic(new RSAPublicKeySpec(n, e));
- } else if (KeyPairProvider.SSH_DSS.equals(keyAlg)) {
- BigInteger p = getMPInt();
- BigInteger q = getMPInt();
- BigInteger g = getMPInt();
- BigInteger y = getMPInt();
- KeyFactory keyFactory = SecurityUtils.getKeyFactory("DSA");
- return keyFactory.generatePublic(new DSAPublicKeySpec(y, p, q, g));
- }
+ return getRawPublicKey(BufferPublicKeyParser.Utils.DEFAULT);
+ }
- ECCurves curve = ECCurves.fromKeyType(keyAlg);
- if (curve == null) {
- throw new NoSuchAlgorithmException("Unsupported raw public algorithm: " + keyAlg);
+ /**
+ * @param parser A {@link BufferPublicKeyParser} to extract the key from the buffer
+ * - never {@code null}
+ * @return The extracted {@link PublicKey} - may be {@code null} if the parser so decided
+ * @throws SshException If failed to extract the key
+ */
+ public PublicKey getRawPublicKey(BufferPublicKeyParser<? extends PublicKey> parser) throws SshException {
+ ValidateUtils.checkNotNull(parser, "No key data parser");
+ try {
+ String keyType = getString();
+ if (!parser.isKeyTypeSupported(keyType)) {
+ throw new NoSuchAlgorithmException("Key type=" + keyType + ") not supported by parser=" + parser);
}
- String curveName = curve.getName();
- ECParameterSpec params = curve.getParameters();
- return getRawECKey(curveName, params);
+ return parser.getRawPublicKey(keyType, this);
} catch (GeneralSecurityException e) {
throw new SshException(e);
}
}
- protected PublicKey getRawECKey(String expectedCurve, ECParameterSpec spec) throws GeneralSecurityException {
- String curveName = getString();
- if (!expectedCurve.equals(curveName)) {
- throw new InvalidKeySpecException("getRawECKey(" + expectedCurve + ") curve name does not match expected: " + curveName);
- }
-
- if (spec == null) {
- throw new InvalidKeySpecException("getRawECKey(" + expectedCurve + ") missing curve parameters");
- }
-
- byte[] octets = getBytes();
- ECPoint w;
- try {
- w = ECDSAPublicKeyEntryDecoder.octetStringToEcPoint(octets);
- } catch (RuntimeException e) {
- throw new InvalidKeySpecException("getRawECKey(" + expectedCurve + ")"
- + " cannot (" + e.getClass().getSimpleName() + ")"
- + " retrieve W value: " + e.getMessage(),
- e);
- }
-
- KeyFactory keyFactory = SecurityUtils.getKeyFactory("EC");
- return keyFactory.generatePublic(new ECPublicKeySpec(w, spec));
- }
-
public KeyPair getKeyPair() throws SshException {
try {
final PublicKey pub;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/AbstractBufferPublicKeyParser.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/AbstractBufferPublicKeyParser.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/AbstractBufferPublicKeyParser.java
new file mode 100644
index 0000000..40a238b
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/AbstractBufferPublicKeyParser.java
@@ -0,0 +1,87 @@
+/*
+ * 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.util.buffer.keys;
+
+import java.security.GeneralSecurityException;
+import java.security.KeyFactory;
+import java.security.PublicKey;
+import java.security.spec.InvalidKeySpecException;
+import java.security.spec.KeySpec;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.SecurityUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+
+/**
+ * @param <PUB> Type of {@link PublicKey} being extracted
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractBufferPublicKeyParser<PUB extends PublicKey> implements BufferPublicKeyParser<PUB> {
+ private final Class<PUB> keyClass;
+ private final Collection<String> supported;
+
+ protected AbstractBufferPublicKeyParser(Class<PUB> keyClass, String ... supported) {
+ this(keyClass, GenericUtils.isEmpty(supported) ? Collections.<String>emptyList() : Arrays.asList(supported));
+ }
+
+ protected AbstractBufferPublicKeyParser(Class<PUB> keyClass, Collection<String> supported) {
+ this.keyClass = ValidateUtils.checkNotNull(keyClass, "No key class");
+ this.supported = ValidateUtils.checkNotNullAndNotEmpty(supported, "No supported types for %s", keyClass.getSimpleName());
+ }
+
+ public Collection<String> getSupportedKeyTypes() {
+ return supported;
+ }
+
+ public final Class<PUB> getKeyClass() {
+ return keyClass;
+ }
+
+ @Override
+ public boolean isKeyTypeSupported(String keyType) {
+ Collection<String> keys = getSupportedKeyTypes();
+ return (GenericUtils.length(keyType) > 0)
+ && (GenericUtils.size(keys) > 0)
+ && keys.contains(keyType);
+ }
+
+ protected <S extends KeySpec> PUB generatePublicKey(String algorithm, S keySpec) throws GeneralSecurityException {
+ KeyFactory keyFactory = getKeyFactory(algorithm);
+ PublicKey key = keyFactory.generatePublic(keySpec);
+ Class<PUB> kc = getKeyClass();
+ if (!kc.isInstance(key)) {
+ throw new InvalidKeySpecException("Mismatched generated key types: expected=" + kc.getSimpleName() + ", actual=" + key);
+ }
+
+ return kc.cast(key);
+ }
+
+ protected KeyFactory getKeyFactory(String algorithm) throws GeneralSecurityException {
+ return SecurityUtils.getKeyFactory(algorithm);
+ }
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + " - supported=" + getSupportedKeyTypes();
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/BufferPublicKeyParser.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/BufferPublicKeyParser.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/BufferPublicKeyParser.java
new file mode 100644
index 0000000..bcd3173
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/BufferPublicKeyParser.java
@@ -0,0 +1,121 @@
+/*
+ * 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.util.buffer.keys;
+
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.buffer.Buffer;
+
+/**
+ * Parses a raw {@link PublicKey} from a {@link Buffer}
+ *
+ * @param <PUB> Type of {@link PublicKey} being extracted
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface BufferPublicKeyParser<PUB extends PublicKey> {
+ BufferPublicKeyParser<PublicKey> EMPTY = new BufferPublicKeyParser<PublicKey>() {
+ @Override
+ public boolean isKeyTypeSupported(String keyType) {
+ return false;
+ }
+
+ @Override
+ public PublicKey getRawPublicKey(String keyType, Buffer buffer) throws GeneralSecurityException {
+ throw new NoSuchAlgorithmException(keyType);
+ }
+
+ @Override
+ public String toString() {
+ return "EMPTY";
+ }
+ };
+
+ /**
+ * @param keyType The key type - e.g., "ssh-rsa", "ssh-dss"
+ * @return {@code true} if this key type is supported by the parser
+ */
+ boolean isKeyTypeSupported(String keyType);
+
+ /**
+ * @param keyType The key type - e.g., "ssh-rsa", "ssh-dss"
+ * @param buffer The {@link Buffer} containing the encoded raw public key
+ * @return The decoded {@link PublicKey}
+ * @throws GeneralSecurityException If failed to generate the key
+ */
+ PUB getRawPublicKey(String keyType, Buffer buffer) throws GeneralSecurityException;
+
+ /**
+ * A helper class for {@link BufferPublicKeyParser} related operations
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+ // CHECKSTYLE:OFF
+ final class Utils {
+ // CHECKSTYLE:ON
+ public static final BufferPublicKeyParser<PublicKey> DEFAULT = aggregate(
+ Arrays.asList(
+ RSABufferPublicKeyParser.INSTANCE,
+ DSSBufferPublicKeyParser.INSTANCE,
+ ECBufferPublicKeyParser.INSTANCE));
+
+ private Utils() {
+ throw new UnsupportedOperationException("No instance");
+ }
+
+ public static BufferPublicKeyParser<PublicKey> aggregate(final Collection<? extends BufferPublicKeyParser<? extends PublicKey>> parsers) {
+ if (GenericUtils.isEmpty(parsers)) {
+ return EMPTY;
+ }
+
+ return new BufferPublicKeyParser<PublicKey>() {
+ @Override
+ public boolean isKeyTypeSupported(String keyType) {
+ for (BufferPublicKeyParser<? extends PublicKey> p : parsers) {
+ if (p.isKeyTypeSupported(keyType)) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
+ @Override
+ public PublicKey getRawPublicKey(String keyType, Buffer buffer) throws GeneralSecurityException {
+ for (BufferPublicKeyParser<? extends PublicKey> p : parsers) {
+ if (p.isKeyTypeSupported(keyType)) {
+ return p.getRawPublicKey(keyType, buffer);
+ }
+ }
+
+ throw new NoSuchAlgorithmException("No aggregate matcher for " + keyType);
+ }
+
+ @Override
+ public String toString() {
+ return String.valueOf(parsers);
+ }
+ };
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/DSSBufferPublicKeyParser.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/DSSBufferPublicKeyParser.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/DSSBufferPublicKeyParser.java
new file mode 100644
index 0000000..af1b383
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/DSSBufferPublicKeyParser.java
@@ -0,0 +1,51 @@
+/*
+ * 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.util.buffer.keys;
+
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.interfaces.DSAPublicKey;
+import java.security.spec.DSAPublicKeySpec;
+
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.Buffer;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class DSSBufferPublicKeyParser extends AbstractBufferPublicKeyParser<DSAPublicKey> {
+ public static final DSSBufferPublicKeyParser INSTANCE = new DSSBufferPublicKeyParser();
+
+ public DSSBufferPublicKeyParser() {
+ super(DSAPublicKey.class, KeyPairProvider.SSH_DSS);
+ }
+
+ @Override
+ public DSAPublicKey getRawPublicKey(String keyType, Buffer buffer) throws GeneralSecurityException {
+ ValidateUtils.checkTrue(isKeyTypeSupported(keyType), "Unsupported key type: %s", keyType);
+ BigInteger p = buffer.getMPInt();
+ BigInteger q = buffer.getMPInt();
+ BigInteger g = buffer.getMPInt();
+ BigInteger y = buffer.getMPInt();
+ return generatePublicKey("DSA", new DSAPublicKeySpec(y, p, q, g));
+
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/ECBufferPublicKeyParser.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/ECBufferPublicKeyParser.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/ECBufferPublicKeyParser.java
new file mode 100644
index 0000000..71b80ff
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/ECBufferPublicKeyParser.java
@@ -0,0 +1,81 @@
+/*
+ * 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.util.buffer.keys;
+
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.security.interfaces.ECPublicKey;
+import java.security.spec.ECParameterSpec;
+import java.security.spec.ECPoint;
+import java.security.spec.ECPublicKeySpec;
+import java.security.spec.InvalidKeySpecException;
+
+import org.apache.sshd.common.cipher.ECCurves;
+import org.apache.sshd.common.config.keys.ECDSAPublicKeyEntryDecoder;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.Buffer;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class ECBufferPublicKeyParser extends AbstractBufferPublicKeyParser<ECPublicKey> {
+ public static final ECBufferPublicKeyParser INSTANCE = new ECBufferPublicKeyParser();
+
+ public ECBufferPublicKeyParser() {
+ super(ECPublicKey.class, ECCurves.KEY_TYPES);
+ }
+
+ @Override
+ public ECPublicKey getRawPublicKey(String keyType, Buffer buffer) throws GeneralSecurityException {
+ ValidateUtils.checkTrue(isKeyTypeSupported(keyType), "Unsupported key type: %s", keyType);
+ ECCurves curve = ECCurves.fromKeyType(keyType);
+ if (curve == null) {
+ throw new NoSuchAlgorithmException("Unsupported raw public algorithm: " + keyType);
+ }
+
+ String curveName = curve.getName();
+ ECParameterSpec params = curve.getParameters();
+ return getRawECKey(curveName, params, buffer);
+ }
+
+ protected ECPublicKey getRawECKey(String expectedCurve, ECParameterSpec spec, Buffer buffer) throws GeneralSecurityException {
+ String curveName = buffer.getString();
+ if (!expectedCurve.equals(curveName)) {
+ throw new InvalidKeySpecException("getRawECKey(" + expectedCurve + ") curve name does not match expected: " + curveName);
+ }
+
+ if (spec == null) {
+ throw new InvalidKeySpecException("getRawECKey(" + expectedCurve + ") missing curve parameters");
+ }
+
+ byte[] octets = buffer.getBytes();
+ ECPoint w;
+ try {
+ w = ECDSAPublicKeyEntryDecoder.octetStringToEcPoint(octets);
+ } catch (RuntimeException e) {
+ throw new InvalidKeySpecException("getRawECKey(" + expectedCurve + ")"
+ + " cannot (" + e.getClass().getSimpleName() + ")"
+ + " retrieve W value: " + e.getMessage(),
+ e);
+ }
+
+ return generatePublicKey("EC", new ECPublicKeySpec(w, spec));
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/ED25519BufferPublicKeyParser.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/ED25519BufferPublicKeyParser.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/ED25519BufferPublicKeyParser.java
new file mode 100644
index 0000000..a490c5a
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/ED25519BufferPublicKeyParser.java
@@ -0,0 +1,56 @@
+/*
+ * 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.util.buffer.keys;
+
+import java.security.GeneralSecurityException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PublicKey;
+
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.Buffer;
+
+/**
+ * TODO complete this when SSHD-440 is done
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class ED25519BufferPublicKeyParser extends AbstractBufferPublicKeyParser<PublicKey> {
+ // TODO define a (public) static (final) INSTANCE once completed
+ public static final ED25519BufferPublicKeyParser IGNORING = new ED25519BufferPublicKeyParser() {
+ @Override
+ protected PublicKey generatePublicKey(byte[] octets) throws GeneralSecurityException {
+ return null;
+ }
+ };
+
+ public ED25519BufferPublicKeyParser() {
+ super(PublicKey.class, KeyPairProvider.SSH_ED25519);
+ }
+
+ @Override
+ public PublicKey getRawPublicKey(String keyType, Buffer buffer) throws GeneralSecurityException {
+ ValidateUtils.checkTrue(isKeyTypeSupported(keyType), "Unsupported key type: %s", keyType);
+ return generatePublicKey(buffer.getBytes());
+ }
+
+ protected PublicKey generatePublicKey(byte[] octets) throws GeneralSecurityException {
+ throw new NoSuchAlgorithmException("Unsupported curve: " + KeyPairProvider.SSH_ED25519);
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/RSABufferPublicKeyParser.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/RSABufferPublicKeyParser.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/RSABufferPublicKeyParser.java
new file mode 100644
index 0000000..1c8119f
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/keys/RSABufferPublicKeyParser.java
@@ -0,0 +1,48 @@
+/*
+ * 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.util.buffer.keys;
+
+import java.math.BigInteger;
+import java.security.GeneralSecurityException;
+import java.security.interfaces.RSAPublicKey;
+import java.security.spec.RSAPublicKeySpec;
+
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.Buffer;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class RSABufferPublicKeyParser extends AbstractBufferPublicKeyParser<RSAPublicKey> {
+ public static final RSABufferPublicKeyParser INSTANCE = new RSABufferPublicKeyParser();
+
+ public RSABufferPublicKeyParser() {
+ super(RSAPublicKey.class, KeyPairProvider.SSH_RSA);
+ }
+
+ @Override
+ public RSAPublicKey getRawPublicKey(String keyType, Buffer buffer) throws GeneralSecurityException {
+ ValidateUtils.checkTrue(isKeyTypeSupported(keyType), "Unsupported key type: %s", keyType);
+ BigInteger e = buffer.getMPInt();
+ BigInteger n = buffer.getMPInt();
+ return generatePublicKey("RSA", new RSAPublicKeySpec(n, e));
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/server/ServerBuilder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ServerBuilder.java b/sshd-core/src/main/java/org/apache/sshd/server/ServerBuilder.java
index d2fd0ab..d65716e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/ServerBuilder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/ServerBuilder.java
@@ -40,6 +40,7 @@ import org.apache.sshd.server.forward.DirectTcpipFactory;
import org.apache.sshd.server.global.CancelTcpipForwardHandler;
import org.apache.sshd.server.global.KeepAliveHandler;
import org.apache.sshd.server.global.NoMoreSessionsHandler;
+import org.apache.sshd.server.global.OpenSshHostKeysHandler;
import org.apache.sshd.server.global.TcpipForwardHandler;
import org.apache.sshd.server.kex.DHGEXServer;
import org.apache.sshd.server.kex.DHGServer;
@@ -74,7 +75,8 @@ public class ServerBuilder extends BaseBuilder<SshServer, ServerBuilder> {
KeepAliveHandler.INSTANCE,
NoMoreSessionsHandler.INSTANCE,
TcpipForwardHandler.INSTANCE,
- CancelTcpipForwardHandler.INSTANCE
+ CancelTcpipForwardHandler.INSTANCE,
+ OpenSshHostKeysHandler.INSTANCE
));
public static final PublickeyAuthenticator DEFAULT_PUBLIC_KEY_AUTHENTICATOR = DefaultAuthorizedKeysAuthenticator.INSTANCE;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java
index 20e7a97..23724b5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/global/CancelTcpipForwardHandler.java
@@ -21,19 +21,19 @@ package org.apache.sshd.server.global;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshdSocketAddress;
import org.apache.sshd.common.forward.TcpipForwarder;
+import org.apache.sshd.common.session.AbstractConnectionServiceRequestHandler;
import org.apache.sshd.common.session.ConnectionService;
-import org.apache.sshd.common.session.ConnectionServiceRequestHandler;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.util.Int2IntFunction;
import org.apache.sshd.common.util.buffer.Buffer;
-import org.apache.sshd.common.util.logging.AbstractLoggingBean;
+import org.apache.sshd.common.util.buffer.BufferUtils;
/**
* Handler for cancel-tcpip-forward global request.
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public class CancelTcpipForwardHandler extends AbstractLoggingBean implements ConnectionServiceRequestHandler {
+public class CancelTcpipForwardHandler extends AbstractConnectionServiceRequestHandler {
public static final String REQUEST = "cancel-tcpip-forward";
/**
* Default growth factor function used to resize response buffers
@@ -48,34 +48,28 @@ public class CancelTcpipForwardHandler extends AbstractLoggingBean implements Co
@Override
public Result process(ConnectionService connectionService, String request, boolean wantReply, Buffer buffer) throws Exception {
- if (REQUEST.equals(request)) {
- String address = buffer.getString();
- int port = buffer.getInt();
- SshdSocketAddress socketAddress = new SshdSocketAddress(address, port);
- if (log.isDebugEnabled()) {
- log.debug("process(" + connectionService + ")[" + request + "] " + socketAddress + " reply=" + wantReply);
- }
-
- TcpipForwarder forwarder = connectionService.getTcpipForwarder();
- forwarder.localPortForwardingCancelled(socketAddress);
+ if (!REQUEST.equals(request)) {
+ return super.process(connectionService, request, wantReply, buffer);
+ }
- if (wantReply) {
- buffer.clear();
- // leave room for the SSH header
- buffer.ensureCapacity(5 + 1 + (Integer.SIZE / Byte.SIZE), RESPONSE_BUFFER_GROWTH_FACTOR);
- buffer.rpos(5);
- buffer.wpos(5);
- buffer.putByte(SshConstants.SSH_MSG_REQUEST_SUCCESS);
- buffer.putInt(port);
+ String address = buffer.getString();
+ int port = buffer.getInt();
+ SshdSocketAddress socketAddress = new SshdSocketAddress(address, port);
+ if (log.isDebugEnabled()) {
+ log.debug("process({})[{}] {} reply=" + wantReply,
+ connectionService, request, socketAddress, wantReply);
+ }
- Session session = connectionService.getSession();
- session.writePacket(buffer);
- }
+ TcpipForwarder forwarder = connectionService.getTcpipForwarder();
+ forwarder.localPortForwardingCancelled(socketAddress);
- return Result.Replied;
+ if (wantReply) {
+ Session session = connectionService.getSession();
+ buffer = session.prepareBuffer(SshConstants.SSH_MSG_REQUEST_SUCCESS, BufferUtils.clear(buffer));
+ buffer.putInt(port);
+ session.writePacket(buffer);
}
- return Result.Unsupported;
+ return Result.Replied;
}
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java
index b9a0818..65a6f2c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/global/KeepAliveHandler.java
@@ -18,8 +18,8 @@
*/
package org.apache.sshd.server.global;
+import org.apache.sshd.common.session.AbstractConnectionServiceRequestHandler;
import org.apache.sshd.common.session.ConnectionService;
-import org.apache.sshd.common.session.ConnectionServiceRequestHandler;
import org.apache.sshd.common.util.buffer.Buffer;
/**
@@ -27,7 +27,7 @@ import org.apache.sshd.common.util.buffer.Buffer;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public class KeepAliveHandler implements ConnectionServiceRequestHandler {
+public class KeepAliveHandler extends AbstractConnectionServiceRequestHandler {
public static final KeepAliveHandler INSTANCE = new KeepAliveHandler();
public KeepAliveHandler() {
@@ -38,8 +38,8 @@ public class KeepAliveHandler implements ConnectionServiceRequestHandler {
public Result process(ConnectionService connectionService, String request, boolean wantReply, Buffer buffer) throws Exception {
if (request.startsWith("keepalive@")) {
return Result.ReplyFailure;
+ } else {
+ return super.process(connectionService, request, wantReply, buffer);
}
- return Result.Unsupported;
}
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/server/global/NoMoreSessionsHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/NoMoreSessionsHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/NoMoreSessionsHandler.java
index ed2acca..d243da3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/global/NoMoreSessionsHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/global/NoMoreSessionsHandler.java
@@ -18,8 +18,8 @@
*/
package org.apache.sshd.server.global;
+import org.apache.sshd.common.session.AbstractConnectionServiceRequestHandler;
import org.apache.sshd.common.session.ConnectionService;
-import org.apache.sshd.common.session.ConnectionServiceRequestHandler;
import org.apache.sshd.common.util.buffer.Buffer;
/**
@@ -27,7 +27,7 @@ import org.apache.sshd.common.util.buffer.Buffer;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public class NoMoreSessionsHandler implements ConnectionServiceRequestHandler {
+public class NoMoreSessionsHandler extends AbstractConnectionServiceRequestHandler {
public static final NoMoreSessionsHandler INSTANCE = new NoMoreSessionsHandler();
public NoMoreSessionsHandler() {
@@ -39,8 +39,8 @@ public class NoMoreSessionsHandler implements ConnectionServiceRequestHandler {
if (request.startsWith("no-more-sessions@")) {
connectionService.setAllowMoreSessions(false);
return Result.ReplyFailure;
+ } else {
+ return super.process(connectionService, request, wantReply, buffer);
}
- return Result.Unsupported;
}
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/server/global/OpenSshHostKeysHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/OpenSshHostKeysHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/OpenSshHostKeysHandler.java
new file mode 100644
index 0000000..150b3d9
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/global/OpenSshHostKeysHandler.java
@@ -0,0 +1,100 @@
+/*
+ * 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.server.global;
+
+import java.security.KeyPair;
+import java.security.PublicKey;
+import java.util.Collection;
+
+import org.apache.sshd.common.FactoryManager;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.SshConstants;
+import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.global.AbstractOpenSshHostKeysHandler;
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.signature.Signature;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+import org.apache.sshd.common.util.buffer.Buffer;
+import org.apache.sshd.common.util.buffer.BufferUtils;
+import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.common.util.buffer.keys.BufferPublicKeyParser;
+
+/**
+ * An initial handler for "hostkeys-prove-00@openssh.com" request
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ * @see <a href="https://github.com/openssh/openssh-portable/blob/master/PROTOCOL">OpenSSH protocol - section 2.5</a>
+ */
+public class OpenSshHostKeysHandler extends AbstractOpenSshHostKeysHandler {
+ public static final String REQUEST = "hostkeys-prove-00@openssh.com";
+ public static final OpenSshHostKeysHandler INSTANCE = new OpenSshHostKeysHandler();
+
+ public OpenSshHostKeysHandler() {
+ super(REQUEST);
+ }
+
+ public OpenSshHostKeysHandler(BufferPublicKeyParser<? extends PublicKey> parser) {
+ super(REQUEST, parser);
+ }
+
+ @Override
+ protected Result handleHostKeys(Session session, Collection<? extends PublicKey> keys, boolean wantReply, Buffer buffer) throws Exception {
+ // according to the specification there MUST be reply required by the server
+ ValidateUtils.checkTrue(wantReply, "No reply required for host keys of %s", session);
+ if (log.isDebugEnabled()) {
+ log.debug("handleHostKeys({})[want-reply={}] received {} keys",
+ session, wantReply, GenericUtils.size(keys));
+ }
+
+ // generate the required signatures
+ buffer = session.prepareBuffer(SshConstants.SSH_MSG_REQUEST_SUCCESS, BufferUtils.clear(buffer));
+
+ Buffer buf = new ByteArrayBuffer();
+ byte[] sessionId = session.getSessionId();
+ FactoryManager manager = ValidateUtils.checkNotNull(session.getFactoryManager(), "No manager");
+ Collection<? extends NamedFactory<Signature>> factories = manager.getSignatureFactories();
+ KeyPairProvider kpp = ValidateUtils.checkNotNull(session.getKeyPairProvider(), "No server keys provider");
+ for (PublicKey k : keys) {
+ String keyType = KeyUtils.getKeyType(k);
+ Signature verifier = ValidateUtils.checkNotNull(
+ NamedFactory.Utils.create(factories, keyType),
+ "No signer could be located for key type=%s",
+ keyType);
+
+ KeyPair kp = ValidateUtils.checkNotNull(kpp.loadKey(keyType), "No key of type=%s available", keyType);
+ verifier.initSigner(kp.getPrivate());
+
+ buf.clear();
+ buf.putString(REQUEST);
+ buf.putBytes(sessionId);
+ buf.putPublicKey(k);
+
+ byte[] data = buf.getCompactData();
+ verifier.update(data);
+
+ byte[] signature = verifier.sign();
+ buffer.putBytes(signature);
+ }
+
+ session.writePacket(buffer);
+ return Result.Replied;
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java b/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java
index 6cde83b..8541276 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/global/TcpipForwardHandler.java
@@ -21,19 +21,19 @@ package org.apache.sshd.server.global;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshdSocketAddress;
import org.apache.sshd.common.forward.TcpipForwarder;
+import org.apache.sshd.common.session.AbstractConnectionServiceRequestHandler;
import org.apache.sshd.common.session.ConnectionService;
-import org.apache.sshd.common.session.ConnectionServiceRequestHandler;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.util.Int2IntFunction;
import org.apache.sshd.common.util.buffer.Buffer;
-import org.apache.sshd.common.util.logging.AbstractLoggingBean;
+import org.apache.sshd.common.util.buffer.BufferUtils;
/**
* Handler for tcpip-forward global request.
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public class TcpipForwardHandler extends AbstractLoggingBean implements ConnectionServiceRequestHandler {
+public class TcpipForwardHandler extends AbstractConnectionServiceRequestHandler {
public static final String REQUEST = "tcpip-forward";
/**
@@ -49,33 +49,28 @@ public class TcpipForwardHandler extends AbstractLoggingBean implements Connecti
@Override
public Result process(ConnectionService connectionService, String request, boolean wantReply, Buffer buffer) throws Exception {
- if (REQUEST.equals(request)) {
- String address = buffer.getString();
- int port = buffer.getInt();
- SshdSocketAddress socketAddress = new SshdSocketAddress(address, port);
- TcpipForwarder forwarder = connectionService.getTcpipForwarder();
- SshdSocketAddress bound = forwarder.localPortForwardingRequested(socketAddress);
- if (log.isDebugEnabled()) {
- log.debug("process(" + connectionService + ")[" + request + "] " + socketAddress + " => " + bound + ", reply=" + wantReply);
- }
+ if (!REQUEST.equals(request)) {
+ return super.process(connectionService, request, wantReply, buffer);
+ }
- port = bound.getPort();
- if (wantReply) {
- buffer.clear();
- // leave room for the SSH header
- buffer.ensureCapacity(5 + 1 + (Integer.SIZE / Byte.SIZE), RESPONSE_BUFFER_GROWTH_FACTOR);
- buffer.rpos(5);
- buffer.wpos(5);
- buffer.putByte(SshConstants.SSH_MSG_REQUEST_SUCCESS);
- buffer.putInt(port);
+ String address = buffer.getString();
+ int port = buffer.getInt();
+ SshdSocketAddress socketAddress = new SshdSocketAddress(address, port);
+ TcpipForwarder forwarder = connectionService.getTcpipForwarder();
+ SshdSocketAddress bound = forwarder.localPortForwardingRequested(socketAddress);
+ if (log.isDebugEnabled()) {
+ log.debug("process({})[{}] {} => {}, reply={}",
+ connectionService, request, socketAddress, bound, wantReply);
+ }
- Session session = connectionService.getSession();
- session.writePacket(buffer);
- }
- return Result.Replied;
+ port = bound.getPort();
+ if (wantReply) {
+ Session session = connectionService.getSession();
+ buffer = session.prepareBuffer(SshConstants.SSH_MSG_REQUEST_SUCCESS, BufferUtils.clear(buffer));
+ buffer.putInt(port);
+ session.writePacket(buffer);
}
- return Result.Unsupported;
+ return Result.Replied;
}
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/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 c2e0742..b05a763 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
@@ -205,14 +205,13 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
buffer.putMPInt(k);
hash.update(buffer.array(), 0, buffer.available());
h = hash.digest();
+ sig.update(h);
- byte[] sigH;
buffer.clear();
- sig.update(h, 0, h.length);
buffer.putString(algo);
buffer.putBytes(sig.sign());
- sigH = buffer.getCompactData();
+ byte[] sigH = buffer.getCompactData();
if (log.isTraceEnabled()) {
log.trace("next({})[{}][K_S]: {}", this, session, BufferUtils.printHex(k_s));
log.trace("next({})[{}][f]: {}", this, session, BufferUtils.printHex(f));
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/65ac5ba7/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 3cdcd17..dbc6cc8 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
@@ -122,14 +122,13 @@ public class DHGServer extends AbstractDHServerKeyExchange {
buffer.putMPInt(k);
hash.update(buffer.array(), 0, buffer.available());
h = hash.digest();
+ sig.update(h);
- byte[] sigH;
buffer.clear();
- sig.update(h, 0, h.length);
buffer.putString(algo);
buffer.putBytes(sig.sign());
- sigH = buffer.getCompactData();
+ byte[] sigH = buffer.getCompactData();
if (log.isTraceEnabled()) {
log.trace("next({})[{}][K_S]: {}", this, session, BufferUtils.printHex(k_s));
log.trace("next({})[{}][f]: {}", this, session, BufferUtils.printHex(f));