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/11/26 06:33:02 UTC
[01/10] mina-sshd git commit: [SSHD-599] Allow per-session override
of KEX and authentication related configuration
Repository: mina-sshd
Updated Branches:
refs/heads/master f83908366 -> b07095c9b
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java
index 05206b7..479159a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSessionImpl.java
@@ -38,7 +38,7 @@ import org.apache.sshd.common.io.IoWriteFuture;
import org.apache.sshd.common.kex.KexProposalOption;
import org.apache.sshd.common.kex.KexState;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
-import org.apache.sshd.common.session.AbstractSession;
+import org.apache.sshd.common.session.SessionListener;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
@@ -50,28 +50,25 @@ import org.apache.sshd.server.ServerFactoryManager;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public class ServerSessionImpl extends AbstractSession implements ServerSession {
+public class ServerSessionImpl extends AbstractServerSession {
protected static final long MAX_PACKETS = 1L << 31;
private long maxBytes = 1024 * 1024 * 1024; // 1 GB
private long maxKeyInterval = 60 * 60 * 1000; // 1 hour
public ServerSessionImpl(ServerFactoryManager server, IoSession ioSession) throws Exception {
- super(true, server, ioSession);
+ super(server, ioSession);
maxBytes = Math.max(32, PropertyResolverUtils.getLongProperty(this, ServerFactoryManager.REKEY_BYTES_LIMIT, maxBytes));
maxKeyInterval = PropertyResolverUtils.getLongProperty(this, ServerFactoryManager.REKEY_TIME_LIMIT, maxKeyInterval);
- log.info("Server session created from {}", ioSession.getRemoteAddress());
- sendServerIdentification();
- }
+ if (log.isDebugEnabled()) {
+ log.debug("Server session created {}", ioSession);
+ }
- @Override
- public ServerFactoryManager getFactoryManager() {
- return (ServerFactoryManager) super.getFactoryManager();
- }
+ // Inform the listener of the newly created session
+ SessionListener listener = getSessionListenerProxy();
+ listener.sessionCreated(this);
- @Override
- protected void checkKeys() {
- // nothing
+ sendServerIdentification();
}
@Override
@@ -126,11 +123,10 @@ public class ServerSessionImpl extends AbstractSession implements ServerSession
/*
* Make sure we can provide key(s) for the available signatures
*/
- ServerFactoryManager manager = getFactoryManager();
- ValidateUtils.checkTrue(proposedManager == manager, "Mismatched signatures proposed factory manager");
+ ValidateUtils.checkTrue(proposedManager == getFactoryManager(), "Mismatched signatures proposed factory manager");
- KeyPairProvider kpp = manager.getKeyPairProvider();
- Collection<String> supported = NamedResource.Utils.getNameList(manager.getSignatureFactories());
+ KeyPairProvider kpp = getKeyPairProvider();
+ Collection<String> supported = NamedResource.Utils.getNameList(getSignatureFactories());
Iterable<String> provided = (kpp == null) ? null : kpp.getKeyTypes();
if ((provided == null) || GenericUtils.isEmpty(supported)) {
return resolveEmptySignaturesProposal(supported, provided);
@@ -217,8 +213,7 @@ public class ServerSessionImpl extends AbstractSession implements ServerSession
@Override
public KeyPair getHostKey() {
String value = getNegotiatedKexParameter(KexProposalOption.SERVERKEYS);
- ServerFactoryManager manager = getFactoryManager();
- KeyPairProvider provider = ValidateUtils.checkNotNull(manager.getKeyPairProvider(), "No host keys provider");
+ KeyPairProvider provider = ValidateUtils.checkNotNull(getKeyPairProvider(), "No host keys provider");
return provider.loadKey(value);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 493ef4d..dcded35 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
@@ -35,6 +35,7 @@ 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.closeable.AbstractCloseable;
+import org.apache.sshd.server.ServerAuthenticationManager;
import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.auth.UserAuth;
import org.apache.sshd.server.auth.UserAuthNoneFactory;
@@ -62,16 +63,16 @@ public class ServerUserAuthService extends AbstractCloseable implements Service,
}
this.session = (ServerSession) s;
- maxAuthRequests = PropertyResolverUtils.getIntProperty(session, ServerFactoryManager.MAX_AUTH_REQUESTS, ServerFactoryManager.DEFAULT_MAX_AUTH_REQUESTS);
+ maxAuthRequests = PropertyResolverUtils.getIntProperty(session, ServerAuthenticationManager.MAX_AUTH_REQUESTS, ServerAuthenticationManager.DEFAULT_MAX_AUTH_REQUESTS);
- ServerFactoryManager manager = getFactoryManager();
- userAuthFactories = new ArrayList<>(manager.getUserAuthFactories());
+ List<NamedFactory<UserAuth>> factories = session.getUserAuthFactories();
+ userAuthFactories = new ArrayList<>(factories);
// Get authentication methods
authMethods = new ArrayList<>();
String mths = PropertyResolverUtils.getString(session, ServerFactoryManager.AUTH_METHODS);
if (GenericUtils.isEmpty(mths)) {
- for (NamedFactory<UserAuth> uaf : manager.getUserAuthFactories()) {
+ for (NamedFactory<UserAuth> uaf : factories) {
authMethods.add(new ArrayList<>(Collections.singletonList(uaf.getName())));
}
} else {
@@ -114,7 +115,6 @@ public class ServerUserAuthService extends AbstractCloseable implements Service,
Boolean authed = Boolean.FALSE;
if (cmd == SshConstants.SSH_MSG_USERAUTH_REQUEST) {
- log.debug("Received SSH_MSG_USERAUTH_REQUEST");
if (this.currentAuth != null) {
this.currentAuth.destroy();
this.currentAuth = null;
@@ -123,6 +123,11 @@ public class ServerUserAuthService extends AbstractCloseable implements Service,
String username = buffer.getString();
String service = buffer.getString();
String method = buffer.getString();
+ if (log.isDebugEnabled()) {
+ log.debug("process({}) Received SSH_MSG_USERAUTH_REQUEST user={}, service={}, method={}",
+ getServerSession(), username, service, method);
+ }
+
if (this.authUserName == null || this.authService == null) {
this.authUserName = username;
this.authService = service;
@@ -141,7 +146,8 @@ public class ServerUserAuthService extends AbstractCloseable implements Service,
}
if (log.isDebugEnabled()) {
- log.debug("Authenticating user '{}' with service '{}' and method '{}'", username, service, method);
+ log.debug("process({}) Authenticating user '{}' with service '{}' and method '{}'",
+ getServerSession(), username, service, method);
}
NamedFactory<UserAuth> factory = NamedResource.Utils.findByName(method, String.CASE_INSENSITIVE_ORDER, userAuthFactories);
@@ -150,24 +156,30 @@ public class ServerUserAuthService extends AbstractCloseable implements Service,
try {
authed = currentAuth.auth(session, username, service, buffer);
} catch (Exception e) {
- // Continue
- log.debug("Authentication failed: {}", e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("process({}) Failed ({}) to authenticate using method={}: {}",
+ getServerSession(), e.getClass().getSimpleName(), method, e.getMessage());
+ }
}
}
} else {
if (this.currentAuth == null) {
// This should not happen
- throw new IllegalStateException("No current authentication mechanism for cmd=" + (cmd & 0xFF));
+ throw new IllegalStateException("No current authentication mechanism for cmd=" + SshConstants.getCommandMessageName(cmd));
}
if (log.isDebugEnabled()) {
- log.debug("Received authentication message {}", Integer.valueOf(cmd & 0xFF));
+ log.debug("process({}) Received authentication message={} for mechanism={}",
+ getServerSession(), SshConstants.getCommandMessageName(cmd), currentAuth.getName());
}
buffer.rpos(buffer.rpos() - 1);
try {
authed = currentAuth.next(buffer);
} catch (Exception e) {
// Continue
- log.debug("Failed ({}) to authenticate: {}", e.getClass().getSimpleName(), e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("process({}) Failed ({}) to authenticate using method={}: {}",
+ getServerSession(), e.getClass().getSimpleName(), currentAuth.getName(), e.getMessage());
+ }
}
}
@@ -183,14 +195,16 @@ public class ServerUserAuthService extends AbstractCloseable implements Service,
protected void handleAuthenticationInProgress(int cmd, Buffer buffer) throws Exception {
String username = (currentAuth == null) ? null : currentAuth.getUsername();
if (log.isDebugEnabled()) {
- log.debug("handleAuthenticationInProgress({}@{})", username, session);
+ log.debug("handleAuthenticationInProgress({}@{}) {}",
+ username, session, SshConstants.getCommandMessageName(cmd));
}
}
protected void handleAuthenticationSuccess(int cmd, Buffer buffer) throws Exception {
String username = ValidateUtils.checkNotNull(currentAuth, "No current auth").getUsername();
if (log.isDebugEnabled()) {
- log.debug("handleAuthenticationSuccess({}@{})", username, session);
+ log.debug("handleAuthenticationSuccess({}@{}) {}",
+ username, session, SshConstants.getCommandMessageName(cmd));
}
boolean success = false;
@@ -264,7 +278,8 @@ public class ServerUserAuthService extends AbstractCloseable implements Service,
protected void handleAuthenticationFailure(int cmd, Buffer buffer) throws Exception {
String username = (currentAuth == null) ? null : currentAuth.getUsername();
if (log.isDebugEnabled()) {
- log.debug("handleAuthenticationFailure({}@{})", username, session);
+ log.debug("handleAuthenticationFailure({}@{}) {}",
+ username, session, SshConstants.getCommandMessageName(cmd));
}
buffer = session.prepareBuffer(SshConstants.SSH_MSG_USERAUTH_FAILURE, BufferUtils.clear(buffer));
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/test/java/org/apache/sshd/WelcomeBannerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/WelcomeBannerTest.java b/sshd-core/src/test/java/org/apache/sshd/WelcomeBannerTest.java
index 12843e7..cc8e780 100644
--- a/sshd-core/src/test/java/org/apache/sshd/WelcomeBannerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/WelcomeBannerTest.java
@@ -68,6 +68,11 @@ public class WelcomeBannerTest extends BaseTestSupport {
final AtomicReference<ClientSession> sessionHolder = new AtomicReference<>(null);
client.setUserInteraction(new UserInteraction() {
@Override
+ public boolean isInteractionAllowed(ClientSession session) {
+ return true;
+ }
+
+ @Override
public void welcome(ClientSession session, String banner, String lang) {
validateSession("welcome", session);
assertNull("Multiple banner invocations", welcomeHolder.getAndSet(banner));
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/test/java/org/apache/sshd/client/ClientSessionListenerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/ClientSessionListenerTest.java b/sshd-core/src/test/java/org/apache/sshd/client/ClientSessionListenerTest.java
new file mode 100644
index 0000000..b2aec0d
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/client/ClientSessionListenerTest.java
@@ -0,0 +1,188 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.net.SocketAddress;
+import java.security.PublicKey;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.sshd.client.auth.UserInteraction;
+import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.cipher.Cipher;
+import org.apache.sshd.common.kex.KexProposalOption;
+import org.apache.sshd.common.kex.KeyExchange;
+import org.apache.sshd.common.mac.Mac;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.session.SessionListener;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.server.SshServer;
+import org.apache.sshd.util.test.BaseTestSupport;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class ClientSessionListenerTest extends BaseTestSupport {
+ private SshServer sshd;
+ private SshClient client;
+ private int port;
+
+ public ClientSessionListenerTest() {
+ super();
+ }
+
+ @Before
+ public void setUp() throws Exception {
+ client = setupTestClient();
+ sshd = setupTestServer();
+ sshd.start();
+ port = sshd.getPort();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (sshd != null) {
+ sshd.stop(true);
+ }
+ if (client != null) {
+ client.stop();
+ }
+ }
+
+ @Test
+ public void testSessionListenerCanModifyKEXNegotiation() throws Exception {
+ final Map<KexProposalOption, NamedFactory<?>> kexParams = new EnumMap<>(KexProposalOption.class);
+ kexParams.put(KexProposalOption.ALGORITHMS, getLeastFavorite(KeyExchange.class, client.getKeyExchangeFactories()));
+ kexParams.put(KexProposalOption.C2SENC, getLeastFavorite(Cipher.class, client.getCipherFactories()));
+ kexParams.put(KexProposalOption.C2SMAC, getLeastFavorite(Mac.class, client.getMacFactories()));
+
+ client.addSessionListener(new SessionListener() {
+ @Override
+ @SuppressWarnings("unchecked")
+ public void sessionCreated(Session session) {
+ session.setKeyExchangeFactories(Collections.singletonList((NamedFactory<KeyExchange>) kexParams.get(KexProposalOption.ALGORITHMS)));
+ session.setCipherFactories(Collections.singletonList((NamedFactory<Cipher>) kexParams.get(KexProposalOption.C2SENC)));
+ session.setMacFactories(Collections.singletonList((NamedFactory<Mac>) kexParams.get(KexProposalOption.C2SMAC)));
+ }
+
+ @Override
+ public void sessionEvent(Session session, Event event) {
+ // ignored
+ }
+
+ @Override
+ public void sessionClosed(Session session) {
+ // ignored
+ }
+ });
+
+ client.start();
+ try (ClientSession session = createTestClientSession()) {
+ for (Map.Entry<KexProposalOption, ? extends NamedResource> ke : kexParams.entrySet()) {
+ KexProposalOption option = ke.getKey();
+ String expected = ke.getValue().getName();
+ String actual = session.getNegotiatedKexParameter(option);
+ assertEquals("Mismatched values for KEX=" + option, expected, actual);
+ }
+ } finally {
+ client.stop();
+ }
+ }
+
+ @Test
+ public void testSessionListenerCanInfluenceAuthentication() throws IOException {
+ final AtomicInteger verificationCount = new AtomicInteger();
+ final ServerKeyVerifier verifier = new ServerKeyVerifier() {
+ @Override
+ public boolean verifyServerKey(ClientSession sshClientSession, SocketAddress remoteAddress, PublicKey serverKey) {
+ verificationCount.incrementAndGet();
+ return true;
+ }
+ };
+
+ client.addSessionListener(new SessionListener() {
+ @Override
+ public void sessionCreated(Session session) {
+ // ignored
+ }
+
+ @Override
+ public void sessionEvent(Session session, Event event) {
+ if ((!session.isAuthenticated()) && (session instanceof ClientSession) && Event.KexCompleted.equals(event)) {
+ ClientSession clientSession = (ClientSession) session;
+ clientSession.setServerKeyVerifier(verifier);
+ clientSession.setUserInteraction(UserInteraction.NONE);
+ }
+ }
+
+ @Override
+ public void sessionClosed(Session session) {
+ // ignored
+ }
+ });
+
+ client.start();
+ try (ClientSession session = createTestClientSession()) {
+ assertNotSame("Invalid default user interaction", UserInteraction.NONE, client.getUserInteraction());
+ assertNotSame("Invalid default server key verifier", verifier, client.getServerKeyVerifier());
+ assertSame("Mismatched session user interaction", UserInteraction.NONE, session.getUserInteraction());
+ assertSame("Mismatched session server key verifier", verifier, session.getServerKeyVerifier());
+ assertEquals("Mismatched verification count", 1, verificationCount.get());
+ } finally {
+ client.stop();
+ }
+ }
+
+ private static <V> NamedFactory<V> getLeastFavorite(Class<V> type, List<? extends NamedFactory<V>> factories) {
+ int numFactories = GenericUtils.size(factories);
+ assertTrue("No factories for " + type.getSimpleName(), numFactories > 0);
+ return factories.get(numFactories - 1);
+ }
+
+ private ClientSession createTestClientSession() throws IOException {
+ ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession();
+ try {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(5L, TimeUnit.SECONDS);
+
+ ClientSession returnValue = session;
+ session = null; // avoid 'finally' close
+ return returnValue;
+ } finally {
+ if (session != null) {
+ session.close();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 cb92ec1..32b32e0 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
@@ -1136,6 +1136,11 @@ public class ClientTest extends BaseTestSupport {
private final String[] BAD_RESPONSE = { "bad" };
@Override
+ public boolean isInteractionAllowed(ClientSession session) {
+ return true;
+ }
+
+ @Override
public void welcome(ClientSession session, String banner, String lang) {
validateSession("welcome", session);
}
@@ -1161,7 +1166,7 @@ public class ClientTest extends BaseTestSupport {
});
final int MAX_PROMPTS = 3;
- PropertyResolverUtils.updateProperty(client, ClientFactoryManager.PASSWORD_PROMPTS, MAX_PROMPTS);
+ PropertyResolverUtils.updateProperty(client, ClientAuthenticationManager.PASSWORD_PROMPTS, MAX_PROMPTS);
client.start();
@@ -1183,7 +1188,7 @@ public class ClientTest extends BaseTestSupport {
public void testDefaultKeyboardInteractiveInSessionUserInteractive() throws Exception {
final AtomicInteger count = new AtomicInteger();
final int MAX_PROMPTS = 3;
- PropertyResolverUtils.updateProperty(client, ClientFactoryManager.PASSWORD_PROMPTS, MAX_PROMPTS);
+ PropertyResolverUtils.updateProperty(client, ClientAuthenticationManager.PASSWORD_PROMPTS, MAX_PROMPTS);
client.setUserAuthFactories(Collections.<NamedFactory<UserAuth>>singletonList(UserAuthKeyboardInteractiveFactory.INSTANCE));
client.start();
@@ -1192,6 +1197,11 @@ public class ClientTest extends BaseTestSupport {
assertNotNull("Client session creation not signalled", clientSessionHolder.get());
session.setUserInteraction(new UserInteraction() {
@Override
+ public boolean isInteractionAllowed(ClientSession session) {
+ return true;
+ }
+
+ @Override
public void welcome(ClientSession clientSession, String banner, String lang) {
assertSame("Mismatched welcome session", session, clientSession);
}
@@ -1225,7 +1235,7 @@ public class ClientTest extends BaseTestSupport {
public void testKeyboardInteractiveInSessionUserInteractiveFailure() throws Exception {
final AtomicInteger count = new AtomicInteger();
final int MAX_PROMPTS = 3;
- PropertyResolverUtils.updateProperty(client, ClientFactoryManager.PASSWORD_PROMPTS, MAX_PROMPTS);
+ PropertyResolverUtils.updateProperty(client, ClientAuthenticationManager.PASSWORD_PROMPTS, MAX_PROMPTS);
client.setUserAuthFactories(Collections.<NamedFactory<UserAuth>>singletonList(UserAuthKeyboardInteractiveFactory.INSTANCE));
client.start();
@@ -1233,6 +1243,11 @@ public class ClientTest extends BaseTestSupport {
assertNotNull("Client session creation not signalled", clientSessionHolder.get());
session.setUserInteraction(new UserInteraction() {
@Override
+ public boolean isInteractionAllowed(ClientSession session) {
+ return true;
+ }
+
+ @Override
public void welcome(ClientSession clientSession, String banner, String lang) {
assertSame("Mismatched welcome session", session, clientSession);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java b/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
index b0c9029..5c1e160 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/config/hosts/HostConfigEntryResolverTest.java
@@ -236,16 +236,17 @@ public class HostConfigEntryResolverTest extends BaseTestSupport {
PropertyResolverUtils.updateProperty(client, ClientFactoryManager.IGNORE_INVALID_IDENTITIES, false);
final Collection<KeyPair> clientIdentities = Collections.singletonList(defaultIdentity);
- client.setKeyPairProvider(new AbstractKeyPairProvider() {
+ KeyPairProvider provider = new AbstractKeyPairProvider() {
@Override
public Iterable<KeyPair> loadKeys() {
return clientIdentities;
}
- });
+ };
+ client.setKeyPairProvider(provider);
client.start();
try(ClientSession session = client.connect(entry).verify(7L, TimeUnit.SECONDS).getSession()) {
- assertNull("Unexpected session key pairs provider", session.getKeyPairProvider());
+ assertSame("Unexpected session key pairs provider", provider, session.getKeyPairProvider());
session.auth().verify(5L, TimeUnit.SECONDS);
assertFalse("Unexpected default client identity attempted", defaultClientIdentityAttempted.get());
assertNull("Default client identity auto-added", session.removePublicKeyIdentity(defaultIdentity));
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionImplTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionImplTest.java b/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionImplTest.java
index 507a9e9..8dd5d66 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionImplTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/session/ClientSessionImplTest.java
@@ -29,11 +29,15 @@ import java.util.List;
import org.apache.sshd.client.ClientFactoryManager;
import org.apache.sshd.common.Factory;
import org.apache.sshd.common.ServiceFactory;
+import org.apache.sshd.common.channel.Channel;
+import org.apache.sshd.common.channel.ChannelListener;
import org.apache.sshd.common.forward.DefaultTcpipForwarderFactory;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.random.JceRandomFactory;
import org.apache.sshd.common.random.Random;
import org.apache.sshd.common.random.SingletonRandomFactory;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.session.SessionListener;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.util.test.BaseTestSupport;
import org.junit.FixMethodOrder;
@@ -54,7 +58,43 @@ public class ClientSessionImplTest extends BaseTestSupport {
public void testAddRemoveIdentities() throws Exception {
ClientFactoryManager client = Mockito.mock(ClientFactoryManager.class);
Mockito.when(client.getTcpipForwarderFactory()).thenReturn(DefaultTcpipForwarderFactory.INSTANCE);
+ Mockito.when(client.getSessionListenerProxy()).thenReturn(new SessionListener() {
+ @Override
+ public void sessionEvent(Session session, Event event) {
+ // ignored
+ }
+
+ @Override
+ public void sessionCreated(Session session) {
+ // ignored
+ }
+ @Override
+ public void sessionClosed(Session session) {
+ // ignored
+ }
+ });
+ Mockito.when(client.getChannelListenerProxy()).thenReturn(new ChannelListener() {
+ @Override
+ public void channelOpenSuccess(Channel channel) {
+ // ignored
+ }
+
+ @Override
+ public void channelOpenFailure(Channel channel, Throwable reason) {
+ // ignored
+ }
+
+ @Override
+ public void channelInitialized(Channel channel) {
+ // ignored
+ }
+
+ @Override
+ public void channelClosed(Channel channel) {
+ // ignored
+ }
+ });
Factory<Random> randomFactory = new SingletonRandomFactory(JceRandomFactory.INSTANCE);
Mockito.when(client.getRandomFactory()).thenReturn(randomFactory);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java b/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
index 0b873da..3831897 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
@@ -185,6 +185,11 @@ public class AuthenticationTest extends BaseTestSupport {
final AtomicInteger updatesCount = new AtomicInteger(0);
client.setUserInteraction(new UserInteraction() {
@Override
+ public boolean isInteractionAllowed(ClientSession session) {
+ return true;
+ }
+
+ @Override
public void welcome(ClientSession session, String banner, String lang) {
// ignored
}
@@ -399,6 +404,11 @@ public class AuthenticationTest extends BaseTestSupport {
final AtomicInteger interactiveCount = new AtomicInteger(0);
client.setUserInteraction(new UserInteraction() {
@Override
+ public boolean isInteractionAllowed(ClientSession session) {
+ return true;
+ }
+
+ @Override
public void welcome(ClientSession session, String banner, String lang) {
// ignored
}
@@ -466,6 +476,11 @@ public class AuthenticationTest extends BaseTestSupport {
final AtomicInteger updatesCount = new AtomicInteger(0);
client.setUserInteraction(new UserInteraction() {
@Override
+ public boolean isInteractionAllowed(ClientSession session) {
+ return true;
+ }
+
+ @Override
public void welcome(ClientSession session, String banner, String lang) {
// ignored
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 f13b939..8ef9592 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
@@ -102,9 +102,9 @@ public class ClientUserAuthServiceOld extends AbstractCloseable implements Servi
String welcome = buffer.getString();
String lang = buffer.getString();
log.debug("Welcome banner[{}]: {}", lang, welcome);
- UserInteraction ui = UserInteraction.Utils.resolveUserInteraction(session);
- if (ui != null) {
- ui.welcome(getSession(), welcome, lang);
+ UserInteraction ui = session.getUserInteraction();
+ if ((ui != null) && ui.isInteractionAllowed(session)) {
+ ui.welcome(session, welcome, lang);
}
} else {
buffer.rpos(buffer.rpos() - 1);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 5d82258..0732e06 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
@@ -84,8 +84,8 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
} else if (num == 1 && password != null && !echo[0] && prompt[0].toLowerCase().startsWith("password:")) {
rep = new String[]{password};
} else {
- UserInteraction ui = session.getFactoryManager().getUserInteraction();
- if (ui != null) {
+ UserInteraction ui = session.getUserInteraction();
+ if ((ui != null) && ui.isInteractionAllowed(session)) {
rep = ui.interactive(session, name, instruction, language_tag, prompt, echo);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 9c4e3c7..e23fad6 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
@@ -23,7 +23,6 @@ import java.security.KeyPair;
import org.apache.sshd.client.auth.UserAuthPublicKeyFactory;
import org.apache.sshd.client.session.ClientSession;
-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;
@@ -61,9 +60,8 @@ public class UserAuthPublicKey extends AbstractUserAuth {
buffer.putString(alg);
buffer.putPublicKey(key.getPublic());
- FactoryManager manager = session.getFactoryManager();
Signature verif =
- ValidateUtils.checkNotNull(NamedFactory.Utils.create(manager.getSignatureFactories(), alg),
+ ValidateUtils.checkNotNull(NamedFactory.Utils.create(session.getSignatureFactories(), alg),
"No signature factory located for algorithm=%s",
alg);
verif.initSigner(key.getPrivate());
@@ -79,9 +77,10 @@ public class UserAuthPublicKey extends AbstractUserAuth {
bs.putPublicKey(key.getPublic());
verif.update(bs.array(), bs.rpos(), bs.available());
- bs = new ByteArrayBuffer();
+ byte[] signature = verif.sign();
+ bs = new ByteArrayBuffer(alg.length() + signature.length + Long.SIZE);
bs.putString(alg);
- bs.putBytes(verif.sign());
+ bs.putBytes(signature);
buffer.putBytes(bs.array(), bs.rpos(), bs.available());
session.writePacket(buffer);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/test/java/org/apache/sshd/server/ServerSessionListenerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/ServerSessionListenerTest.java b/sshd-core/src/test/java/org/apache/sshd/server/ServerSessionListenerTest.java
new file mode 100644
index 0000000..4ca7a76
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/server/ServerSessionListenerTest.java
@@ -0,0 +1,259 @@
+/*
+ * 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;
+
+import java.io.IOException;
+import java.net.SocketAddress;
+import java.util.Collections;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+import java.util.TreeMap;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicInteger;
+
+import org.apache.sshd.client.SshClient;
+import org.apache.sshd.client.session.ClientSession;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.cipher.Cipher;
+import org.apache.sshd.common.io.IoSession;
+import org.apache.sshd.common.kex.KexProposalOption;
+import org.apache.sshd.common.kex.KeyExchange;
+import org.apache.sshd.common.mac.Mac;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.session.SessionListener;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.server.auth.UserAuth;
+import org.apache.sshd.server.auth.keyboard.KeyboardInteractiveAuthenticator;
+import org.apache.sshd.server.auth.password.PasswordAuthenticator;
+import org.apache.sshd.server.auth.password.PasswordChangeRequiredException;
+import org.apache.sshd.server.session.ServerSession;
+import org.apache.sshd.util.test.BaseTestSupport;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.FixMethodOrder;
+import org.junit.Test;
+import org.junit.runners.MethodSorters;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+@FixMethodOrder(MethodSorters.NAME_ASCENDING)
+public class ServerSessionListenerTest extends BaseTestSupport {
+ private SshServer sshd;
+ private SshClient client;
+ private int port;
+
+ public ServerSessionListenerTest() {
+ super();
+ }
+ @Before
+ public void setUp() throws Exception {
+ sshd = setupTestServer();
+ sshd.start();
+ port = sshd.getPort();
+
+ client = setupTestClient();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (sshd != null) {
+ sshd.stop(true);
+ }
+ if (client != null) {
+ client.stop();
+ }
+ }
+
+ @Test // see https://issues.apache.org/jira/browse/SSHD-456
+ public void testServerStillListensIfSessionListenerThrowsException() throws Exception {
+ final Map<String, SocketAddress> eventsMap = new TreeMap<String, SocketAddress>(String.CASE_INSENSITIVE_ORDER);
+ final Logger log = LoggerFactory.getLogger(getClass());
+ sshd.addSessionListener(new SessionListener() {
+ @Override
+ public void sessionCreated(Session session) {
+ throwException("SessionCreated", session);
+ }
+
+ @Override
+ public void sessionEvent(Session session, Event event) {
+ throwException("SessionEvent", session);
+ }
+
+ @Override
+ public void sessionClosed(Session session) {
+ throwException("SessionClosed", session);
+ }
+
+ private void throwException(String phase, Session session) {
+ IoSession ioSession = session.getIoSession();
+ SocketAddress addr = ioSession.getRemoteAddress();
+ synchronized (eventsMap) {
+ if (eventsMap.put(phase, addr) != null) {
+ return; // already generated an event for this phase
+ }
+ }
+
+ RuntimeException e = new RuntimeException("Synthetic exception at phase=" + phase + ": " + addr);
+ log.info(e.getMessage());
+ throw e;
+ }
+ });
+
+ client.start();
+
+ int curCount = 0;
+ for (int retryCount = 0; retryCount < Byte.SIZE; retryCount++) {
+ synchronized (eventsMap) {
+ if ((curCount = eventsMap.size()) >= 3) {
+ return;
+ }
+ }
+
+ try {
+ try (ClientSession s = createTestClientSession()) {
+ log.info("Retry #" + retryCount + " successful");
+ }
+
+ synchronized (eventsMap) {
+ assertTrue("Unexpected premature success at retry # " + retryCount + ": " + eventsMap, eventsMap.size() >= 3);
+ }
+ } catch (IOException e) {
+ // expected - ignored
+ synchronized (eventsMap) {
+ int nextCount = eventsMap.size();
+ assertTrue("No session event generated at retry #" + retryCount, nextCount > curCount);
+ }
+ }
+ }
+
+ fail("No success to authenticate");
+ }
+
+ @Test
+ public void testSessionListenerCanModifyKEXNegotiation() throws Exception {
+ final Map<KexProposalOption, NamedFactory<?>> kexParams = new EnumMap<>(KexProposalOption.class);
+ kexParams.put(KexProposalOption.ALGORITHMS, getLeastFavorite(KeyExchange.class, sshd.getKeyExchangeFactories()));
+ kexParams.put(KexProposalOption.S2CENC, getLeastFavorite(Cipher.class, sshd.getCipherFactories()));
+ kexParams.put(KexProposalOption.S2CMAC, getLeastFavorite(Mac.class, sshd.getMacFactories()));
+
+ sshd.addSessionListener(new SessionListener() {
+ @Override
+ @SuppressWarnings("unchecked")
+ public void sessionCreated(Session session) {
+ session.setKeyExchangeFactories(Collections.singletonList((NamedFactory<KeyExchange>) kexParams.get(KexProposalOption.ALGORITHMS)));
+ session.setCipherFactories(Collections.singletonList((NamedFactory<Cipher>) kexParams.get(KexProposalOption.S2CENC)));
+ session.setMacFactories(Collections.singletonList((NamedFactory<Mac>) kexParams.get(KexProposalOption.S2CMAC)));
+ }
+
+ @Override
+ public void sessionEvent(Session session, Event event) {
+ // ignored
+ }
+
+ @Override
+ public void sessionClosed(Session session) {
+ // ignored
+ }
+ });
+
+ client.start();
+ try (ClientSession session = createTestClientSession()) {
+ for (Map.Entry<KexProposalOption, ? extends NamedResource> ke : kexParams.entrySet()) {
+ KexProposalOption option = ke.getKey();
+ String expected = ke.getValue().getName();
+ String actual = session.getNegotiatedKexParameter(option);
+ assertEquals("Mismatched values for KEX=" + option, expected, actual);
+ }
+ } finally {
+ client.stop();
+ }
+ }
+
+ @Test
+ public void testSessionListenerCanModifyAuthentication() throws Exception {
+ final AtomicInteger passCount = new AtomicInteger(0);
+ final PasswordAuthenticator defaultPassAuth = sshd.getPasswordAuthenticator();
+ final PasswordAuthenticator passAuth = new PasswordAuthenticator() {
+ @Override
+ public boolean authenticate(String username, String password, ServerSession session) throws PasswordChangeRequiredException {
+ passCount.incrementAndGet();
+ return defaultPassAuth.authenticate(username, password, session);
+ }
+ };
+ sshd.addSessionListener(new SessionListener() {
+ @Override
+ public void sessionCreated(Session session) {
+ if ((!session.isAuthenticated()) && (session instanceof ServerSession)) {
+ ServerSession serverSession = (ServerSession) session;
+ serverSession.setPasswordAuthenticator(passAuth);
+ serverSession.setUserAuthFactories(
+ Collections.<NamedFactory<UserAuth>>singletonList(
+ ServerAuthenticationManager.Utils.DEFAULT_USER_AUTH_PASSWORD_FACTORY));
+ }
+ }
+
+ @Override
+ public void sessionEvent(Session session, Event event) {
+ // ignored
+ }
+
+ @Override
+ public void sessionClosed(Session session) {
+ // ignored
+ }
+ });
+
+ client.start();
+ try (ClientSession session = createTestClientSession()) {
+ assertNotSame("Mismatched default password authenticator", passAuth, sshd.getPasswordAuthenticator());
+ assertNotSame("Mismatched default kb authenticator", KeyboardInteractiveAuthenticator.NONE, sshd.getKeyboardInteractiveAuthenticator());
+ assertEquals("Authenticator override not invoked", 1, passCount.get());
+ } finally {
+ client.stop();
+ }
+ }
+
+ private static <V> NamedFactory<V> getLeastFavorite(Class<V> type, List<? extends NamedFactory<V>> factories) {
+ int numFactories = GenericUtils.size(factories);
+ assertTrue("No factories for " + type.getSimpleName(), numFactories > 0);
+ return factories.get(numFactories - 1);
+ }
+
+ private ClientSession createTestClientSession() throws Exception {
+ ClientSession session = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession();
+ try {
+ session.addPasswordIdentity(getCurrentTestName());
+ session.auth().verify(11L, TimeUnit.SECONDS);
+
+ ClientSession returnValue = session;
+ session = null; // avoid 'finally' close
+ return returnValue;
+ } finally {
+ if (session != null) {
+ session.close();
+ }
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java b/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
index 32d77fe..bfdb958 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/ServerTest.java
@@ -25,7 +25,6 @@ import java.io.OutputStream;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.StreamCorruptedException;
-import java.net.SocketAddress;
import java.nio.charset.StandardCharsets;
import java.util.Arrays;
import java.util.Collection;
@@ -74,7 +73,6 @@ import org.junit.Before;
import org.junit.FixMethodOrder;
import org.junit.Test;
import org.junit.runners.MethodSorters;
-import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
@@ -84,7 +82,6 @@ import org.slf4j.LoggerFactory;
*/
@FixMethodOrder(MethodSorters.NAME_ASCENDING)
public class ServerTest extends BaseTestSupport {
-
private SshServer sshd;
private SshClient client;
private int port;
@@ -121,7 +118,7 @@ public class ServerTest extends BaseTestSupport {
@Test
public void testFailAuthenticationWithWaitFor() throws Exception {
final int MAX_AUTH_REQUESTS = 10;
- PropertyResolverUtils.updateProperty(sshd, ServerFactoryManager.MAX_AUTH_REQUESTS, MAX_AUTH_REQUESTS);
+ PropertyResolverUtils.updateProperty(sshd, ServerAuthenticationManager.MAX_AUTH_REQUESTS, MAX_AUTH_REQUESTS);
client.setServiceFactories(Arrays.asList(
new ClientUserAuthServiceOld.Factory(),
@@ -150,7 +147,7 @@ public class ServerTest extends BaseTestSupport {
@Test
public void testFailAuthenticationWithFuture() throws Exception {
final int MAX_AUTH_REQUESTS = 10;
- PropertyResolverUtils.updateProperty(sshd, ServerFactoryManager.MAX_AUTH_REQUESTS, MAX_AUTH_REQUESTS);
+ PropertyResolverUtils.updateProperty(sshd, ServerAuthenticationManager.MAX_AUTH_REQUESTS, MAX_AUTH_REQUESTS);
client.setServiceFactories(Arrays.asList(
new ClientUserAuthServiceOld.Factory(),
@@ -407,71 +404,6 @@ public class ServerTest extends BaseTestSupport {
}
}
- @Test // see https://issues.apache.org/jira/browse/SSHD-456
- public void testServerStillListensIfSessionListenerThrowsException() throws Exception {
- final Map<String, SocketAddress> eventsMap = new TreeMap<String, SocketAddress>(String.CASE_INSENSITIVE_ORDER);
- final Logger log = LoggerFactory.getLogger(getClass());
- sshd.addSessionListener(new SessionListener() {
- @Override
- public void sessionCreated(Session session) {
- throwException("SessionCreated", session);
- }
-
- @Override
- public void sessionEvent(Session session, Event event) {
- throwException("SessionEvent", session);
- }
-
- @Override
- public void sessionClosed(Session session) {
- throwException("SessionClosed", session);
- }
-
- private void throwException(String phase, Session session) {
- IoSession ioSession = session.getIoSession();
- SocketAddress addr = ioSession.getRemoteAddress();
- synchronized (eventsMap) {
- if (eventsMap.put(phase, addr) != null) {
- return; // already generated an event for this phase
- }
- }
-
- RuntimeException e = new RuntimeException("Synthetic exception at phase=" + phase + ": " + addr);
- log.info(e.getMessage());
- throw e;
- }
- });
-
- client.start();
-
- int curCount = 0;
- for (int retryCount = 0; retryCount < Byte.SIZE; retryCount++) {
- synchronized (eventsMap) {
- if ((curCount = eventsMap.size()) >= 3) {
- return;
- }
- }
-
- try {
- try (ClientSession s = createTestClientSession()) {
- log.info("Retry #" + retryCount + " successful");
- }
-
- synchronized (eventsMap) {
- assertTrue("Unexpected premature success at retry # " + retryCount + ": " + eventsMap, eventsMap.size() >= 3);
- }
- } catch (IOException e) {
- // expected - ignored
- synchronized (eventsMap) {
- int nextCount = eventsMap.size();
- assertTrue("No session event generated at retry #" + retryCount, nextCount > curCount);
- }
- }
- }
-
- fail("No success to authenticate");
- }
-
@Test
public void testEnvironmentVariablesPropagationToServer() throws Exception {
final AtomicReference<Environment> envHolder = new AtomicReference<Environment>(null);
[09/10] mina-sshd git commit: [SSHD-600] Propagate actual
authentication error to the AuthFuture
Posted by lg...@apache.org.
[SSHD-600] Propagate actual authentication error to the AuthFuture
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/be8428a0
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/be8428a0
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/be8428a0
Branch: refs/heads/master
Commit: be8428a03d93447c0daecc90c32198e29a119d45
Parents: af0e783
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Thu Nov 26 07:32:13 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Thu Nov 26 07:32:13 2015 +0200
----------------------------------------------------------------------
.../sshd/client/session/ClientSessionImpl.java | 21 ++++++++--
.../sshd/common/auth/AuthenticationTest.java | 41 ++++++++++++++++++++
2 files changed, 59 insertions(+), 3 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/be8428a0/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
index 58eee3d..103925f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
@@ -59,7 +59,7 @@ import org.apache.sshd.common.util.buffer.Buffer;
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public class ClientSessionImpl extends AbstractClientSession {
- protected AuthFuture authFuture;
+ private AuthFuture authFuture;
/**
* For clients to store their own metadata
@@ -126,12 +126,27 @@ public class ClientSessionImpl extends AbstractClientSession {
ClientUserAuthService authService = getUserAuthService();
synchronized (lock) {
- authFuture = authService.auth(getRegisteredIdentities(), nextServiceName());
+ String serviceName = nextServiceName();
+ authFuture = ValidateUtils.checkNotNull(
+ authService.auth(getRegisteredIdentities(), serviceName),
+ "No auth future generated by service=%s",
+ serviceName);
return authFuture;
}
}
- private String nextServiceName() {
+ @Override
+ public void exceptionCaught(Throwable t) {
+ synchronized (lock) {
+ if (!authFuture.isDone()) {
+ authFuture.setException(t);
+ }
+ }
+
+ super.exceptionCaught(t);
+ }
+
+ protected String nextServiceName() {
synchronized (lock) {
return nextServiceFactory.getName();
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/be8428a0/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java b/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
index 3831897..3aec0e7 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/auth/AuthenticationTest.java
@@ -40,6 +40,8 @@ import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.session.SessionListener;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
@@ -513,6 +515,45 @@ public class AuthenticationTest extends BaseTestSupport {
}
}
+ @Test // see SSHD-600
+ public void testAuthExceptionPropagation() throws Exception {
+ try (SshClient client = setupTestClient()) {
+ final RuntimeException expected = new RuntimeException("Synthetic exception");
+ final AtomicInteger invocations = new AtomicInteger(0);
+ client.addSessionListener(new SessionListener() {
+ @Override
+ public void sessionCreated(Session session) {
+ // ignored
+ }
+
+ @Override
+ public void sessionEvent(Session session, Event event) {
+ assertEquals("Mismatched invocations count", 1, invocations.incrementAndGet());
+ throw expected;
+ }
+
+ @Override
+ public void sessionClosed(Session session) {
+ // ignored
+ }
+ });
+
+ client.start();
+ try (ClientSession s = client.connect(getCurrentTestName(), TEST_LOCALHOST, port).verify(7L, TimeUnit.SECONDS).getSession()) {
+ s.addPasswordIdentity(getCurrentTestName());
+
+ AuthFuture future = s.auth();
+ assertTrue("Failed to complete auth in allocated time", future.await(11L, TimeUnit.SECONDS));
+ assertFalse("Unexpected authentication success", future.isSuccess());
+
+ Throwable actual = future.getException();
+ assertSame("Mismatched authentication failure reason", expected, actual);
+ } finally {
+ client.stop();
+ }
+ }
+ }
+
private static void assertAuthenticationResult(String message, AuthFuture future, boolean expected) throws IOException {
assertTrue(message + ": failed to get result on time", future.await(5L, TimeUnit.SECONDS));
assertEquals(message + ": mismatched authentication result", expected, future.isSuccess());
[03/10] mina-sshd git commit: [SSHD-599] Allow per-session override
of KEX and authentication related configuration
Posted by lg...@apache.org.
[SSHD-599] Allow per-session override of KEX and authentication related configuration
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/e9dd7f47
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/e9dd7f47
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/e9dd7f47
Branch: refs/heads/master
Commit: e9dd7f4757556bc5e4464647b259fe8a6cdd0b24
Parents: f839083
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Thu Nov 26 07:19:03 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Thu Nov 26 07:19:03 2015 +0200
----------------------------------------------------------------------
.../client/ClientAuthenticationManager.java | 76 ++++
.../sshd/client/ClientFactoryManager.java | 59 +--
.../java/org/apache/sshd/client/SshClient.java | 107 ++++--
.../auth/UserAuthKeyboardInteractive.java | 12 +-
.../sshd/client/auth/UserAuthPassword.java | 8 +-
.../sshd/client/auth/UserAuthPublicKey.java | 43 ++-
.../sshd/client/auth/UserInteraction.java | 73 ++--
.../client/auth/pubkey/KeyPairIdentity.java | 6 +-
.../keys/BuiltinClientIdentitiesWatcher.java | 14 +
.../config/keys/ClientIdentitiesWatcher.java | 32 +-
.../config/keys/ClientIdentityFileWatcher.java | 30 +-
.../keys/DefaultClientIdentitiesWatcher.java | 19 +
.../org/apache/sshd/client/kex/DHGClient.java | 4 +-
.../org/apache/sshd/client/kex/DHGEXClient.java | 4 +-
.../client/session/AbstractClientSession.java | 378 +++++++++++++++++++
.../sshd/client/session/ClientSession.java | 19 +-
.../sshd/client/session/ClientSessionImpl.java | 337 +----------------
.../client/session/ClientUserAuthService.java | 57 ++-
.../sshd/common/AbstractFactoryManager.java | 73 +---
.../org/apache/sshd/common/FactoryManager.java | 43 +--
.../auth/AbstractUserAuthMethodFactory.java | 5 +
.../common/kex/AbstractKexFactoryManager.java | 137 +++++++
.../sshd/common/kex/KexFactoryManager.java | 75 ++++
.../keyprovider/KeyPairProviderHolder.java | 1 +
.../sshd/common/session/AbstractSession.java | 49 ++-
.../common/session/AbstractSessionFactory.java | 7 -
.../org/apache/sshd/common/session/Session.java | 4 +-
.../apache/sshd/common/util/GenericUtils.java | 20 +
.../org/apache/sshd/common/util/Supplier.java | 29 ++
.../server/ServerAuthenticationManager.java | 166 ++++++++
.../sshd/server/ServerFactoryManager.java | 68 +---
.../java/org/apache/sshd/server/SshServer.java | 58 +--
.../auth/UserAuthKeyboardInteractive.java | 7 +-
.../sshd/server/auth/UserAuthPassword.java | 6 +-
.../sshd/server/auth/UserAuthPublicKey.java | 12 +-
.../sshd/server/auth/gss/UserAuthGSS.java | 32 +-
...DefaultKeyboardInteractiveAuthenticator.java | 8 +-
.../KeyboardInteractiveAuthenticator.java | 20 +
.../org/apache/sshd/server/kex/DHGEXServer.java | 3 +-
.../org/apache/sshd/server/kex/DHGServer.java | 4 +-
.../server/session/AbstractServerSession.java | 107 ++++++
.../sshd/server/session/ServerSession.java | 3 +-
.../sshd/server/session/ServerSessionImpl.java | 33 +-
.../server/session/ServerUserAuthService.java | 43 ++-
.../java/org/apache/sshd/WelcomeBannerTest.java | 5 +
.../sshd/client/ClientSessionListenerTest.java | 188 +++++++++
.../java/org/apache/sshd/client/ClientTest.java | 21 +-
.../hosts/HostConfigEntryResolverTest.java | 7 +-
.../client/session/ClientSessionImplTest.java | 40 ++
.../sshd/common/auth/AuthenticationTest.java | 15 +
.../deprecated/ClientUserAuthServiceOld.java | 6 +-
.../deprecated/UserAuthKeyboardInteractive.java | 4 +-
.../sshd/deprecated/UserAuthPublicKey.java | 9 +-
.../sshd/server/ServerSessionListenerTest.java | 259 +++++++++++++
.../java/org/apache/sshd/server/ServerTest.java | 72 +---
55 files changed, 1988 insertions(+), 929 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/client/ClientAuthenticationManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/ClientAuthenticationManager.java b/sshd-core/src/main/java/org/apache/sshd/client/ClientAuthenticationManager.java
new file mode 100644
index 0000000..de41b9a
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/client/ClientAuthenticationManager.java
@@ -0,0 +1,76 @@
+/*
+ * 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;
+
+import java.util.List;
+
+import org.apache.sshd.client.auth.UserAuth;
+import org.apache.sshd.client.auth.UserInteraction;
+import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
+import org.apache.sshd.common.NamedFactory;
+
+/**
+ * Holds information required for the client to perform authentication with the server
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface ClientAuthenticationManager {
+
+ /**
+ * Ordered comma separated list of authentications methods.
+ * Authentications methods accepted by the server will be tried in the given order.
+ * If not configured or {@code null}/empty, then the session's {@link #getUserAuthFactories()}
+ * is used as-is
+ */
+ String PREFERRED_AUTHS = "preferred-auths";
+
+ /**
+ * Specifies the number of interactive prompts before giving up.
+ * The argument to this keyword must be an integer.
+ */
+ String PASSWORD_PROMPTS = "password-prompts";
+
+ /**
+ * Default value for {@link #PASSWORD_PROMPTS} if none configured
+ */
+ int DEFAULT_PASSWORD_PROMPTS = 3;
+
+ /**
+ * Retrieve the server key verifier to be used to check the key when connecting
+ * to an SSH server.
+ *
+ * @return the {@link ServerKeyVerifier} to use - never {@code null}
+ */
+ ServerKeyVerifier getServerKeyVerifier();
+ void setServerKeyVerifier(ServerKeyVerifier serverKeyVerifier);
+
+ /**
+ * @return A {@link UserInteraction} object to communicate with the user
+ * (may be {@code null} to indicate that no such communication is allowed)
+ */
+ UserInteraction getUserInteraction();
+ void setUserInteraction(UserInteraction userInteraction);
+
+ /**
+ * @return a {@link List} of {@link UserAuth} {@link NamedFactory}-ies - never
+ * {@code null}/empty
+ */
+ List<NamedFactory<UserAuth>> getUserAuthFactories();
+ void setUserAuthFactories(List<NamedFactory<UserAuth>> userAuthFactories);
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java
index 11000d2..c9337e5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/ClientFactoryManager.java
@@ -18,15 +18,9 @@
*/
package org.apache.sshd.client;
-import java.util.List;
-
-import org.apache.sshd.client.auth.UserAuth;
-import org.apache.sshd.client.auth.UserInteraction;
import org.apache.sshd.client.config.hosts.HostConfigEntryResolver;
import org.apache.sshd.client.config.keys.ClientIdentityLoader;
-import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
/**
@@ -35,12 +29,12 @@ import org.apache.sshd.common.config.keys.FilePasswordProvider;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface ClientFactoryManager extends FactoryManager {
-
+public interface ClientFactoryManager extends FactoryManager, ClientAuthenticationManager {
/**
* Key used to set the heartbeat interval in milliseconds (0 to disable = default)
*/
String HEARTBEAT_INTERVAL = "hearbeat-interval";
+
/**
* Default value for {@link #HEARTBEAT_INTERVAL} if none configured
*/
@@ -50,30 +44,13 @@ public interface ClientFactoryManager extends FactoryManager {
* Key used to check the heartbeat request that should be sent to the server
*/
String HEARTBEAT_REQUEST = "heartbeat-request";
+
/**
* Default value for {@link ClientFactoryManager#HEARTBEAT_REQUEST} is none configured
*/
String DEFAULT_KEEP_ALIVE_HEARTBEAT_STRING = "keepalive@sshd.apache.org";
/**
- * Ordered comma separated list of authentications methods.
- * Authentications methods accepted by the server will be tried in the given order.
- * If not configured or {@code null}/empty, then the session's {@link #getUserAuthFactories()}
- * is used as-is
- */
- String PREFERRED_AUTHS = "preferred-auths";
-
- /**
- * Specifies the number of interactive prompts before giving up.
- * The argument to this keyword must be an integer.
- */
- String PASSWORD_PROMPTS = "password-prompts";
- /**
- * Default value for {@link #PASSWORD_PROMPTS} if none configured
- */
- int DEFAULT_PASSWORD_PROMPTS = 3;
-
- /**
* Whether to ignore invalid identities files when pre-initializing
* the client session
* @see ClientIdentityLoader#isValidLocation(String)
@@ -86,40 +63,24 @@ public interface ClientFactoryManager extends FactoryManager {
boolean DEFAULT_IGNORE_INVALID_IDENTITIES = true;
/**
- * Retrieve the server key verifier to be used to check the key when connecting
- * to an ssh server.
- *
- * @return the server key verifier to use
- */
- ServerKeyVerifier getServerKeyVerifier();
-
- /**
- * @return A {@link UserInteraction} object to communicate with the user
- * (may be {@code null} to indicate that no such communication is allowed)
- */
- UserInteraction getUserInteraction();
-
- /**
- * @return a {@link List} of {@link UserAuth} {@link NamedFactory}-ies - never
- * {@code null}/empty
- */
- List<NamedFactory<UserAuth>> getUserAuthFactories();
-
- /**
* @return The {@link HostConfigEntryResolver} to use in order to resolve the
- * effective session parameters
+ * effective session parameters - never {@code null}
*/
HostConfigEntryResolver getHostConfigEntryResolver();
+ void setHostConfigEntryResolver(HostConfigEntryResolver resolver);
/**
* @return The {@link ClientIdentityLoader} to use in order to load client
- * key pair identities
+ * key pair identities - never {@code null}
*/
ClientIdentityLoader getClientIdentityLoader();
+ void setClientIdentityLoader(ClientIdentityLoader loader);
/**
* @return The {@link FilePasswordProvider} to use if need to load encrypted
- * identities keys
+ * identities keys - never {@code null}
+ * @see FilePasswordProvider#EMPTY
*/
FilePasswordProvider getFilePasswordProvider();
+ void setFilePasswordProvider(FilePasswordProvider provider);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
index fdb4dbb..02f7db2 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/SshClient.java
@@ -66,7 +66,6 @@ import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
import org.apache.sshd.client.session.ClientConnectionServiceFactory;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.client.session.ClientSessionCreator;
-import org.apache.sshd.client.session.ClientSessionImpl;
import org.apache.sshd.client.session.ClientUserAuthServiceFactory;
import org.apache.sshd.client.session.SessionFactory;
import org.apache.sshd.client.simple.AbstractSimpleClientSessionCreator;
@@ -85,12 +84,14 @@ import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.future.SshFutureListener;
import org.apache.sshd.common.io.IoConnectFuture;
import org.apache.sshd.common.io.IoConnector;
+import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.keyprovider.AbstractFileKeyPairProvider;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.session.AbstractSession;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.OsUtils;
import org.apache.sshd.common.util.SecurityUtils;
+import org.apache.sshd.common.util.Supplier;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.common.util.io.NoCloseInputStream;
@@ -194,8 +195,9 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
return serverKeyVerifier;
}
+ @Override
public void setServerKeyVerifier(ServerKeyVerifier serverKeyVerifier) {
- this.serverKeyVerifier = serverKeyVerifier;
+ this.serverKeyVerifier = ValidateUtils.checkNotNull(serverKeyVerifier, "No server key verifier");
}
@Override
@@ -203,8 +205,9 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
return hostConfigEntryResolver;
}
+ @Override
public void setHostConfigEntryResolver(HostConfigEntryResolver resolver) {
- this.hostConfigEntryResolver = resolver;
+ this.hostConfigEntryResolver = ValidateUtils.checkNotNull(resolver, "No host configuration entry resolver");
}
@Override
@@ -212,8 +215,9 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
return filePasswordProvider;
}
+ @Override
public void setFilePasswordProvider(FilePasswordProvider provider) {
- this.filePasswordProvider = provider;
+ this.filePasswordProvider = ValidateUtils.checkNotNull(provider, "No file password provider");
}
@Override
@@ -221,8 +225,9 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
return clientIdentityLoader;
}
+ @Override
public void setClientIdentityLoader(ClientIdentityLoader loader) {
- this.clientIdentityLoader = loader;
+ this.clientIdentityLoader = ValidateUtils.checkNotNull(loader, "No client identity loader");
}
@Override
@@ -230,6 +235,7 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
return userInteraction;
}
+ @Override
public void setUserInteraction(UserInteraction userInteraction) {
this.userInteraction = userInteraction;
}
@@ -239,8 +245,9 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
return userAuthFactories;
}
+ @Override
public void setUserAuthFactories(List<NamedFactory<UserAuth>> userAuthFactories) {
- this.userAuthFactories = userAuthFactories;
+ this.userAuthFactories = ValidateUtils.checkNotNullAndNotEmpty(userAuthFactories, "No user auth factories");
}
@Override
@@ -256,7 +263,19 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
// if no client identities override use the default
KeyPairProvider defaultIdentities = getKeyPairProvider();
if (defaultIdentities == null) {
- setKeyPairProvider(new DefaultClientIdentitiesWatcher(getClientIdentityLoader(), getFilePasswordProvider()));
+ setKeyPairProvider(new DefaultClientIdentitiesWatcher(
+ new Supplier<ClientIdentityLoader>() {
+ @Override
+ public ClientIdentityLoader get() {
+ return getClientIdentityLoader();
+ }
+ },
+ new Supplier<FilePasswordProvider>() {
+ @Override
+ public FilePasswordProvider get() {
+ return getFilePasswordProvider();
+ }
+ }));
}
// Register the additional agent forwarding channel if needed
@@ -453,38 +472,63 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
final ConnectFuture connectFuture, final String username, final SocketAddress address,
final Collection<? extends KeyPair> identities, final boolean useDefaultIdentities) {
return new SshFutureListener<IoConnectFuture>() {
- @SuppressWarnings("synthetic-access")
@Override
+ @SuppressWarnings("synthetic-access")
public void operationComplete(IoConnectFuture future) {
if (future.isCanceled()) {
connectFuture.cancel();
- } else if (future.getException() != null) {
- connectFuture.setException(future.getException());
- } else {
- ClientSessionImpl session = (ClientSessionImpl) AbstractSession.getSession(future.getSession());
- session.setUsername(username);
+ return;
+ }
- if (useDefaultIdentities) {
- session.setKeyPairProvider(getKeyPairProvider());
+ Throwable t = future.getException();
+ if (t != null) {
+ if (log.isDebugEnabled()) {
+ log.debug("operationComplete({}@{}) failed ({}): {}",
+ username, address, t.getClass().getSimpleName(), t.getMessage());
}
+ connectFuture.setException(t);
+ } else {
+ onConnectOperationComplete(future.getSession(), connectFuture, username, address, identities, useDefaultIdentities);
+ }
+ }
+ };
+ }
- int numIds = GenericUtils.size(identities);
- if (numIds > 0) {
- if (log.isDebugEnabled()) {
- log.debug("doConnect({}@{}) adding {} identities", username, address, numIds);
- }
- for (KeyPair kp : identities) {
- if (log.isTraceEnabled()) {
- log.trace("doConnect({}@{}) add identity type={}, fingerprint={}",
- username, address, KeyUtils.getKeyType(kp), KeyUtils.getFingerPrint(kp.getPublic()));
- }
- session.addPublicKeyIdentity(kp);
- }
+ protected void onConnectOperationComplete(IoSession ioSession, ConnectFuture connectFuture,
+ String username, SocketAddress address, Collection<? extends KeyPair> identities, boolean useDefaultIdentities) {
+ ClientSession session = (ClientSession) AbstractSession.getSession(ioSession);
+ session.setUsername(username);
+
+ if (useDefaultIdentities) {
+ // check if session listener intervened
+ KeyPairProvider kpSession = session.getKeyPairProvider();
+ KeyPairProvider kpClient = ValidateUtils.checkNotNull(getKeyPairProvider(), "No default key-pair provider");
+ if (kpSession == null) {
+ session.setKeyPairProvider(kpClient);
+ } else {
+ if (kpSession != kpClient) {
+ if (log.isDebugEnabled()) {
+ log.debug("onConnectOperationComplete({}) key-pair provider override", session);
}
- connectFuture.setSession(session);
}
}
- };
+ }
+
+ int numIds = GenericUtils.size(identities);
+ if (numIds > 0) {
+ if (log.isDebugEnabled()) {
+ log.debug("onConnectOperationComplete({}@{}) adding {} identities", username, address, numIds);
+ }
+ for (KeyPair kp : identities) {
+ if (log.isTraceEnabled()) {
+ log.trace("onConnectOperationComplete({}@{}) add identity type={}, fingerprint={}",
+ username, address, KeyUtils.getKeyType(kp), KeyUtils.getFingerPrint(kp.getPublic()));
+ }
+ session.addPublicKeyIdentity(kp);
+ }
+ }
+
+ connectFuture.setSession(session);
}
protected IoConnector createConnector() {
@@ -699,6 +743,11 @@ public class SshClient extends AbstractFactoryManager implements ClientFactoryMa
client.start();
client.setUserInteraction(new UserInteraction() {
@Override
+ public boolean isInteractionAllowed(ClientSession session) {
+ return true;
+ }
+
+ @Override
public void welcome(ClientSession clientSession, String banner, String lang) {
stdout.println(banner);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 34ba100..553a544 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
@@ -24,7 +24,7 @@ import java.util.Collection;
import java.util.Iterator;
import java.util.List;
-import org.apache.sshd.client.ClientFactoryManager;
+import org.apache.sshd.client.ClientAuthenticationManager;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.SshConstants;
@@ -94,7 +94,7 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
}
}
passwords = pwds.iterator();
- maxTrials = PropertyResolverUtils.getIntProperty(session, ClientFactoryManager.PASSWORD_PROMPTS, ClientFactoryManager.DEFAULT_PASSWORD_PROMPTS);
+ maxTrials = PropertyResolverUtils.getIntProperty(session, ClientAuthenticationManager.PASSWORD_PROMPTS, ClientAuthenticationManager.DEFAULT_PASSWORD_PROMPTS);
ValidateUtils.checkTrue(maxTrials > 0, "Non-positive max. trials: %d", maxTrials);
}
@@ -184,7 +184,9 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
session.writePacket(buffer);
return true;
}
- throw new IllegalStateException("process(" + session + ")[" + service + ") received unknown packet: cmd=" + cmd);
+
+ throw new IllegalStateException("process(" + session + ")[" + service + ")"
+ + " received unknown packet: cmd=" + SshConstants.getCommandMessageName(cmd));
}
protected String getExchangeLanguageTag(ClientSession session) {
@@ -229,8 +231,8 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
return new String[]{candidate};
} else {
ClientSession session = getClientSession();
- UserInteraction ui = UserInteraction.Utils.resolveUserInteraction(session);
- if (ui != null) {
+ UserInteraction ui = session.getUserInteraction();
+ if ((ui != null) && ui.isInteractionAllowed(session)) {
return ui.interactive(session, name, instruction, lang, prompt, echo);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 4924f0c..450c915 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
@@ -81,9 +81,8 @@ public class UserAuthPassword extends AbstractUserAuth {
if (cmd == SshConstants.SSH_MSG_USERAUTH_PASSWD_CHANGEREQ) {
String prompt = buffer.getString();
String lang = buffer.getString();
- UserInteraction ui = UserInteraction.Utils.resolveUserInteraction(session);
-
- if (ui != null) {
+ UserInteraction ui = session.getUserInteraction();
+ if ((ui != null) && ui.isInteractionAllowed(session)) {
String password = ui.getUpdatedPassword(session, prompt, lang);
if (GenericUtils.isEmpty(password)) {
if (log.isDebugEnabled()) {
@@ -104,7 +103,8 @@ public class UserAuthPassword extends AbstractUserAuth {
return false;
}
- throw new IllegalStateException("process(" + username + "@" + session + ")[" + service + "] received unknown packet: cmd=" + cmd);
+ throw new IllegalStateException("process(" + username + "@" + session + ")[" + service + "]"
+ + " received unknown packet: cmd=" + SshConstants.getCommandMessageName(cmd));
}
/**
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 525eb43..d4b0db4 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
@@ -37,7 +37,9 @@ import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.kex.KeyExchange;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.Pair;
+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;
@@ -65,16 +67,24 @@ public class UserAuthPublicKey extends AbstractUserAuth {
List<PublicKeyIdentity> ids = new ArrayList<>();
for (Object o : identities) {
if (o instanceof KeyPair) {
- ids.add(new KeyPairIdentity(session.getFactoryManager(), (KeyPair) o));
+ ids.add(new KeyPairIdentity(session, (KeyPair) o));
}
}
- FactoryManager manager = session.getFactoryManager();
+ FactoryManager manager = ValidateUtils.checkNotNull(session.getFactoryManager(), "No session factory manager");
SshAgentFactory factory = manager.getAgentFactory();
if (factory != null) {
- this.agent = factory.createClient(manager);
- for (Pair<PublicKey, String> pair : agent.getIdentities()) {
- ids.add(new KeyAgentIdentity(agent, pair.getFirst()));
+ this.agent = ValidateUtils.checkNotNull(factory.createClient(manager), "No agent created");
+ Collection<Pair<PublicKey, String>> agentKeys = agent.getIdentities();
+ if (GenericUtils.size(agentKeys) > 0) {
+ for (Pair<PublicKey, String> pair : agentKeys) {
+ PublicKey key = pair.getFirst();
+ if (log.isDebugEnabled()) {
+ log.debug("init({}) add agent public key type={}: comment={}, fingerprint={}",
+ session, pair.getSecond(), KeyUtils.getKeyType(key), KeyUtils.getFingerPrint(key));
+ }
+ ids.add(new KeyAgentIdentity(agent, key));
+ }
}
} else {
this.agent = null;
@@ -82,8 +92,12 @@ public class UserAuthPublicKey extends AbstractUserAuth {
KeyPairProvider provider = session.getKeyPairProvider();
if (provider != null) {
- for (KeyPair pair : provider.loadKeys()) {
- ids.add(new KeyPairIdentity(manager, pair));
+ for (KeyPair kp : provider.loadKeys()) {
+ if (log.isDebugEnabled()) {
+ log.debug("init({}) add provider public key type={}: {}",
+ session, KeyUtils.getKeyType(kp), KeyUtils.getFingerPrint(kp.getPublic()));
+ }
+ ids.add(new KeyPairIdentity(session, kp));
}
}
this.keys = ids.iterator();
@@ -103,8 +117,8 @@ public class UserAuthPublicKey extends AbstractUserAuth {
String algo = KeyUtils.getKeyType(key);
String name = getName();
if (log.isDebugEnabled()) {
- log.debug("process({}@{})[{}] Send SSH_MSG_USERAUTH_REQUEST request {} algo={}",
- username, session, service, name, algo);
+ log.debug("process({}@{})[{}] Send SSH_MSG_USERAUTH_REQUEST request {} type={} - fingerprint={}",
+ username, session, service, name, algo, KeyUtils.getFingerPrint(key));
}
buffer = session.createBuffer(SshConstants.SSH_MSG_USERAUTH_REQUEST);
@@ -130,8 +144,8 @@ public class UserAuthPublicKey extends AbstractUserAuth {
String algo = KeyUtils.getKeyType(key);
String name = getName();
if (log.isDebugEnabled()) {
- log.debug("process({}@{})[{}] Send SSH_MSG_USERAUTH_REQUEST reply {} algo={}",
- username, session, service, name, algo);
+ log.debug("process({}@{})[{}] Send SSH_MSG_USERAUTH_REQUEST reply {} type={} - fingerprint={}",
+ username, session, service, name, algo, KeyUtils.getFingerPrint(key));
}
buffer = session.prepareBuffer(SshConstants.SSH_MSG_USERAUTH_REQUEST, BufferUtils.clear(buffer));
@@ -154,7 +168,7 @@ public class UserAuthPublicKey extends AbstractUserAuth {
bs.putPublicKey(key);
byte[] sig = current.sign(bs.getCompactData());
- bs = new ByteArrayBuffer();
+ bs = new ByteArrayBuffer(algo.length() + sig.length + Long.SIZE);
bs.putString(algo);
bs.putBytes(sig);
buffer.putBytes(bs.array(), bs.rpos(), bs.available());
@@ -163,7 +177,8 @@ public class UserAuthPublicKey extends AbstractUserAuth {
return true;
}
- throw new IllegalStateException("process(" + username + "@" + session + ")[" + service + "] received unknown packet: cmd=" + cmd);
+ throw new IllegalStateException("process(" + username + "@" + session + ")[" + service + "]"
+ + " received unknown packet: cmd=" + SshConstants.getCommandMessageName(cmd));
}
@Override
@@ -173,6 +188,8 @@ public class UserAuthPublicKey extends AbstractUserAuth {
agent.close();
} catch (IOException e) {
throw new RuntimeException("Failed (" + e.getClass().getSimpleName() + ") to close agent: " + e.getMessage(), e);
+ } finally {
+ agent = null;
}
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/client/auth/UserInteraction.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserInteraction.java b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserInteraction.java
index a05dfbc..700055a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/auth/UserInteraction.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/auth/UserInteraction.java
@@ -18,7 +18,6 @@
*/
package org.apache.sshd.client.auth;
-import org.apache.sshd.client.ClientFactoryManager;
import org.apache.sshd.client.session.ClientSession;
/**
@@ -28,6 +27,44 @@ import org.apache.sshd.client.session.ClientSession;
* @see <a href="https://www.ietf.org/rfc/rfc4256.txt">RFC 4256</A>
*/
public interface UserInteraction {
+ /**
+ * A useful "placeholder" that indicates that no interaction is expected.
+ * <B>Note:</B> throws {@link IllegalStateException} is any of the interaction
+ * methods is called
+ */
+ UserInteraction NONE = new UserInteraction() {
+ @Override
+ public boolean isInteractionAllowed(ClientSession session) {
+ return false;
+ }
+
+ @Override
+ public void welcome(ClientSession session, String banner, String lang) {
+ // ignored
+ }
+
+ @Override
+ public String[] interactive(ClientSession session, String name, String instruction, String lang, String[] prompt, boolean[] echo) {
+ throw new IllegalStateException("interactive(" + session + ")[" + name + "] unexpected call");
+ }
+
+ @Override
+ public String getUpdatedPassword(ClientSession session, String prompt, String lang) {
+ throw new IllegalStateException("getUpdatedPassword(" + session + ")[" + prompt + "] unexpected call");
+ }
+
+ @Override
+ public String toString() {
+ return "NONE";
+ }
+ };
+
+ /**
+ *
+ * @param session The {@link ClientSession}
+ * @return {@code true} if user interaction allowed for this session
+ */
+ boolean isInteractionAllowed(ClientSession session);
/**
* Displays the welcome banner to the user.
@@ -70,38 +107,4 @@ public interface UserInteraction {
* be it other passwords, public keys, etc...)
*/
String getUpdatedPassword(ClientSession session, String prompt, String lang);
-
- // CHECKSTYLE:OFF
- final class Utils {
- // CHECKSTYLE:ON
-
- private Utils() {
- throw new UnsupportedOperationException("No instance allowed");
- }
-
- /**
- * Checks which {@link UserInteraction} instance to use - if the session
- * has a specific one, then it is used. Otherwise, the {@link ClientFactoryManager}
- * (if any is available) is consulted.
- *
- * @param session The {@link ClientSession}
- * @return The resolved user interaction instance
- * @see ClientSession#getUserInteraction()
- * @see ClientSession#getFactoryManager()
- * @see ClientFactoryManager#getUserInteraction()
- */
- public static UserInteraction resolveUserInteraction(ClientSession session) {
- if (session == null) {
- return null;
- }
-
- UserInteraction ui = session.getUserInteraction();
- if (ui == null) {
- ClientFactoryManager manager = session.getFactoryManager();
- ui = (manager == null) ? null : manager.getUserInteraction();
- }
-
- return ui;
- }
- }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 40b3837..e84195f 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
@@ -21,9 +21,9 @@ package org.apache.sshd.client.auth.pubkey;
import java.security.KeyPair;
import java.security.PublicKey;
-import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.kex.KexFactoryManager;
import org.apache.sshd.common.signature.Signature;
import org.apache.sshd.common.util.ValidateUtils;
@@ -34,9 +34,9 @@ import org.apache.sshd.common.util.ValidateUtils;
*/
public class KeyPairIdentity implements PublicKeyIdentity {
private final KeyPair pair;
- private final FactoryManager manager;
+ private final KexFactoryManager manager;
- public KeyPairIdentity(FactoryManager manager, KeyPair pair) {
+ public KeyPairIdentity(KexFactoryManager manager, KeyPair pair) {
this.manager = ValidateUtils.checkNotNull(manager, "No manager");
this.pair = ValidateUtils.checkNotNull(pair, "No key pair");
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java
index 694b1dd..fb104b4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/BuiltinClientIdentitiesWatcher.java
@@ -32,6 +32,7 @@ import org.apache.sshd.common.config.keys.BuiltinIdentities;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Supplier;
import org.apache.sshd.common.util.ValidateUtils;
/**
@@ -47,6 +48,19 @@ public class BuiltinClientIdentitiesWatcher extends ClientIdentitiesWatcher {
public BuiltinClientIdentitiesWatcher(Path keysFolder, Collection<String> ids, boolean supportedOnly,
ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
+ this(keysFolder, ids, supportedOnly,
+ GenericUtils.supplierOf(ValidateUtils.checkNotNull(loader, "No client identity loader")),
+ GenericUtils.supplierOf(ValidateUtils.checkNotNull(provider, "No password provider")),
+ strict);
+ }
+
+ public BuiltinClientIdentitiesWatcher(Path keysFolder, boolean supportedOnly,
+ Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider, boolean strict) {
+ this(keysFolder, NamedResource.Utils.getNameList(BuiltinIdentities.VALUES), supportedOnly, loader, provider, strict);
+ }
+
+ public BuiltinClientIdentitiesWatcher(Path keysFolder, Collection<String> ids, boolean supportedOnly,
+ Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider, boolean strict) {
super(getBuiltinIdentitiesPaths(keysFolder, ids), loader, provider, strict);
this.supportedOnly = supportedOnly;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java
index aa26b8b..e0d930a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentitiesWatcher.java
@@ -30,6 +30,8 @@ import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Supplier;
+import org.apache.sshd.common.util.ValidateUtils;
/**
* Watches over a group of files that contains client identities
@@ -39,11 +41,26 @@ import org.apache.sshd.common.util.GenericUtils;
public class ClientIdentitiesWatcher extends AbstractKeyPairProvider implements KeyPairProvider {
private final Collection<ClientIdentityProvider> providers;
- public ClientIdentitiesWatcher(Collection<? extends Path> paths, ClientIdentityLoader loader, FilePasswordProvider provider) {
+ public ClientIdentitiesWatcher(Collection<? extends Path> paths,
+ ClientIdentityLoader loader, FilePasswordProvider provider) {
this(paths, loader, provider, true);
}
- public ClientIdentitiesWatcher(Collection<? extends Path> paths, ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
+ public ClientIdentitiesWatcher(Collection<? extends Path> paths,
+ ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
+ this(paths,
+ GenericUtils.supplierOf(ValidateUtils.checkNotNull(loader, "No client identity loader")),
+ GenericUtils.supplierOf(ValidateUtils.checkNotNull(provider, "No password provider")),
+ strict);
+ }
+
+ public ClientIdentitiesWatcher(Collection<? extends Path> paths,
+ Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider) {
+ this(paths, loader, provider, true);
+ }
+
+ public ClientIdentitiesWatcher(Collection<? extends Path> paths,
+ Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider, boolean strict) {
this(buildProviders(paths, loader, provider, strict));
}
@@ -77,7 +94,16 @@ public class ClientIdentitiesWatcher extends AbstractKeyPairProvider implements
return keys;
}
- public static List<ClientIdentityProvider> buildProviders(Collection<? extends Path> paths, ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
+ public static List<ClientIdentityProvider> buildProviders(
+ Collection<? extends Path> paths, ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
+ return buildProviders(paths,
+ GenericUtils.supplierOf(ValidateUtils.checkNotNull(loader, "No client identity loader")),
+ GenericUtils.supplierOf(ValidateUtils.checkNotNull(provider, "No password provider")),
+ strict);
+ }
+
+ public static List<ClientIdentityProvider> buildProviders(
+ Collection<? extends Path> paths, Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider, boolean strict) {
if (GenericUtils.isEmpty(paths)) {
return Collections.emptyList();
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java
index bdd2bf5..2923ba2 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/ClientIdentityFileWatcher.java
@@ -27,7 +27,9 @@ import java.util.concurrent.atomic.AtomicReference;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.Pair;
+import org.apache.sshd.common.util.Supplier;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.common.util.io.ModifiableFileWatcher;
@@ -40,8 +42,8 @@ import org.apache.sshd.common.util.io.ModifiableFileWatcher;
*/
public class ClientIdentityFileWatcher extends ModifiableFileWatcher implements ClientIdentityProvider {
private final AtomicReference<KeyPair> identityHolder = new AtomicReference<>(null);
- private final ClientIdentityLoader loader;
- private final FilePasswordProvider provider;
+ private final Supplier<ClientIdentityLoader> loaderHolder;
+ private final Supplier<FilePasswordProvider> providerHolder;
private final boolean strict;
public ClientIdentityFileWatcher(Path path, ClientIdentityLoader loader, FilePasswordProvider provider) {
@@ -49,9 +51,20 @@ public class ClientIdentityFileWatcher extends ModifiableFileWatcher implements
}
public ClientIdentityFileWatcher(Path path, ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
+ this(path,
+ GenericUtils.supplierOf(ValidateUtils.checkNotNull(loader, "No client identity loader")),
+ GenericUtils.supplierOf(ValidateUtils.checkNotNull(provider, "No password provider")),
+ strict);
+ }
+
+ public ClientIdentityFileWatcher(Path path, Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider) {
+ this(path, loader, provider, true);
+ }
+
+ public ClientIdentityFileWatcher(Path path, Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider, boolean strict) {
super(path);
- this.loader = ValidateUtils.checkNotNull(loader, "No client identity loader");
- this.provider = ValidateUtils.checkNotNull(provider, "No password provided");
+ this.loaderHolder = ValidateUtils.checkNotNull(loader, "No client identity loader");
+ this.providerHolder = ValidateUtils.checkNotNull(provider, "No password provider");
this.strict = strict;
}
@@ -60,11 +73,11 @@ public class ClientIdentityFileWatcher extends ModifiableFileWatcher implements
}
public final ClientIdentityLoader getClientIdentityLoader() {
- return loader;
+ return loaderHolder.get();
}
public final FilePasswordProvider getFilePasswordProvider() {
- return provider;
+ return providerHolder.get();
}
@Override
@@ -101,14 +114,15 @@ public class ClientIdentityFileWatcher extends ModifiableFileWatcher implements
}
String location = path.toString();
- ClientIdentityLoader idLoader = getClientIdentityLoader();
+ ClientIdentityLoader idLoader = ValidateUtils.checkNotNull(getClientIdentityLoader(), "No client identity loader");
if (idLoader.isValidLocation(location)) {
- return idLoader.loadClientIdentity(location, getFilePasswordProvider());
+ return idLoader.loadClientIdentity(location, ValidateUtils.checkNotNull(getFilePasswordProvider(), "No file password provider"));
}
if (log.isDebugEnabled()) {
log.debug("reloadClientIdentity({}) invalid location", location);
}
+
return null;
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java
index a689599..ba1719f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/config/keys/DefaultClientIdentitiesWatcher.java
@@ -24,6 +24,9 @@ import java.util.List;
import org.apache.sshd.common.config.keys.FilePasswordProvider;
import org.apache.sshd.common.config.keys.PublicKeyEntry;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Supplier;
+import org.apache.sshd.common.util.ValidateUtils;
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
@@ -38,6 +41,22 @@ public class DefaultClientIdentitiesWatcher extends BuiltinClientIdentitiesWatch
}
public DefaultClientIdentitiesWatcher(boolean supportedOnly, ClientIdentityLoader loader, FilePasswordProvider provider, boolean strict) {
+ this(supportedOnly,
+ GenericUtils.supplierOf(ValidateUtils.checkNotNull(loader, "No client identity loader")),
+ GenericUtils.supplierOf(ValidateUtils.checkNotNull(provider, "No password provider")),
+ strict);
+ }
+
+ public DefaultClientIdentitiesWatcher(Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider) {
+ this(loader, provider, true);
+ }
+
+ public DefaultClientIdentitiesWatcher(Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider, boolean strict) {
+ this(true, loader, provider, strict);
+ }
+
+ public DefaultClientIdentitiesWatcher(boolean supportedOnly,
+ Supplier<ClientIdentityLoader> loader, Supplier<FilePasswordProvider> provider, boolean strict) {
super(PublicKeyEntry.getDefaultKeysFolderPath(), supportedOnly, loader, provider, strict);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 95af92c..9ffdb9c 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
@@ -18,7 +18,6 @@
*/
package org.apache.sshd.client.kex;
-import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshException;
@@ -130,8 +129,7 @@ public class DHGClient extends AbstractDHClientKeyExchange {
hash.update(buffer.array(), 0, buffer.available());
h = hash.digest();
- FactoryManager manager = session.getFactoryManager();
- Signature verif = ValidateUtils.checkNotNull(NamedFactory.Utils.create(manager.getSignatureFactories(), keyAlg),
+ Signature verif = ValidateUtils.checkNotNull(NamedFactory.Utils.create(session.getSignatureFactories(), keyAlg),
"No verifier located for algorithm=%s",
keyAlg);
verif.initVerifier(serverKey);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 ac00fe3..cff00d8 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
@@ -21,7 +21,6 @@ package org.apache.sshd.client.kex;
import java.math.BigInteger;
-import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshException;
@@ -159,9 +158,8 @@ public class DHGEXClient extends AbstractDHClientKeyExchange {
hash.update(buffer.array(), 0, buffer.available());
h = hash.digest();
- FactoryManager manager = session.getFactoryManager();
Signature verif = ValidateUtils.checkNotNull(
- NamedFactory.Utils.create(manager.getSignatureFactories(), keyAlg),
+ NamedFactory.Utils.create(session.getSignatureFactories(), keyAlg),
"No verifier located for algorithm=%s",
keyAlg);
verif.initVerifier(serverKey);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java b/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
new file mode 100644
index 0000000..76d042b
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/AbstractClientSession.java
@@ -0,0 +1,378 @@
+/*
+ * 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.session;
+
+import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.security.KeyPair;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+import org.apache.sshd.client.ClientFactoryManager;
+import org.apache.sshd.client.auth.UserAuth;
+import org.apache.sshd.client.auth.UserInteraction;
+import org.apache.sshd.client.channel.ChannelDirectTcpip;
+import org.apache.sshd.client.channel.ChannelExec;
+import org.apache.sshd.client.channel.ChannelSubsystem;
+import org.apache.sshd.client.channel.ClientChannel;
+import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
+import org.apache.sshd.client.scp.DefaultScpClient;
+import org.apache.sshd.client.scp.ScpClient;
+import org.apache.sshd.client.subsystem.sftp.DefaultSftpClient;
+import org.apache.sshd.client.subsystem.sftp.SftpClient;
+import org.apache.sshd.client.subsystem.sftp.SftpFileSystem;
+import org.apache.sshd.client.subsystem.sftp.SftpFileSystemProvider;
+import org.apache.sshd.client.subsystem.sftp.SftpVersionSelector;
+import org.apache.sshd.common.FactoryManager;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.SshdSocketAddress;
+import org.apache.sshd.common.config.keys.KeyUtils;
+import org.apache.sshd.common.forward.TcpipForwarder;
+import org.apache.sshd.common.io.IoSession;
+import org.apache.sshd.common.scp.ScpTransferEventListener;
+import org.apache.sshd.common.session.AbstractSession;
+import org.apache.sshd.common.session.ConnectionService;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractClientSession extends AbstractSession implements ClientSession {
+ /**
+ * Compares 2 password identities - returns zero ONLY if <U>both</U> compared
+ * objects are {@link String}s and equal to each other
+ */
+ public static final Comparator<Object> PASSWORD_IDENTITY_COMPARATOR = new Comparator<Object>() {
+ @Override
+ public int compare(Object o1, Object o2) {
+ if (!(o1 instanceof String) || !(o2 instanceof String)) {
+ return -1;
+ } else {
+ return ((String) o1).compareTo((String) o2);
+ }
+ }
+ };
+
+ /**
+ * Compares 2 {@link KeyPair} identities - returns zero ONLY if <U>both</U> compared
+ * objects are {@link KeyPair}s and equal to each other
+ */
+ public static final Comparator<Object> KEYPAIR_IDENTITY_COMPARATOR = new Comparator<Object>() {
+ @Override
+ public int compare(Object o1, Object o2) {
+ if ((!(o1 instanceof KeyPair)) || (!(o2 instanceof KeyPair))) {
+ return -1;
+ } else if (KeyUtils.compareKeyPairs((KeyPair) o1, (KeyPair) o2)) {
+ return 0;
+ } else {
+ return 1;
+ }
+ }
+ };
+
+ private final List<Object> identities = new ArrayList<>();
+ private ServerKeyVerifier serverKeyVerifier;
+ private UserInteraction userInteraction;
+ private List<NamedFactory<UserAuth>> userAuthFactories;
+ private ScpTransferEventListener scpListener;
+
+ protected AbstractClientSession(ClientFactoryManager factoryManager, IoSession ioSession) {
+ super(false, factoryManager, ioSession);
+ }
+
+ @Override
+ public ClientFactoryManager getFactoryManager() {
+ return (ClientFactoryManager) super.getFactoryManager();
+ }
+
+ @Override
+ public ServerKeyVerifier getServerKeyVerifier() {
+ return resolveEffectiveProvider(ServerKeyVerifier.class, serverKeyVerifier, getFactoryManager().getServerKeyVerifier());
+ }
+
+ @Override
+ public void setServerKeyVerifier(ServerKeyVerifier serverKeyVerifier) {
+ this.serverKeyVerifier = serverKeyVerifier; // OK if null - inherit from parent
+ }
+
+ @Override
+ public UserInteraction getUserInteraction() {
+ return resolveEffectiveProvider(UserInteraction.class, userInteraction, getFactoryManager().getUserInteraction());
+ }
+
+ @Override
+ public void setUserInteraction(UserInteraction userInteraction) {
+ this.userInteraction = userInteraction; // OK if null - inherit from parent
+ }
+
+ @Override
+ public List<NamedFactory<UserAuth>> getUserAuthFactories() {
+ return resolveEffectiveFactories(UserAuth.class, userAuthFactories, getFactoryManager().getUserAuthFactories());
+ }
+
+ @Override
+ public void setUserAuthFactories(List<NamedFactory<UserAuth>> userAuthFactories) {
+ this.userAuthFactories = userAuthFactories; // OK if null/empty - inherit from parent
+ }
+
+ protected List<Object> getRegisteredIdentities() {
+ return identities;
+ }
+
+ @Override
+ public void addPasswordIdentity(String password) {
+ identities.add(ValidateUtils.checkNotNullAndNotEmpty(password, "No password provided"));
+ if (log.isDebugEnabled()) { // don't show the password in the log
+ log.debug("addPasswordIdentity({}) {}", this, KeyUtils.getFingerPrint(password));
+ }
+ }
+
+ @Override
+ public String removePasswordIdentity(String password) {
+ if (GenericUtils.isEmpty(password)) {
+ return null;
+ }
+
+ int index = findIdentityIndex(PASSWORD_IDENTITY_COMPARATOR, password);
+ if (index >= 0) {
+ return (String) identities.remove(index);
+ } else {
+ return null;
+ }
+ }
+
+ @Override
+ public void addPublicKeyIdentity(KeyPair kp) {
+ ValidateUtils.checkNotNull(kp, "No key-pair to add");
+ ValidateUtils.checkNotNull(kp.getPublic(), "No public key");
+ ValidateUtils.checkNotNull(kp.getPrivate(), "No private key");
+
+ identities.add(kp);
+
+ if (log.isDebugEnabled()) {
+ log.debug("addPublicKeyIdentity({}) {}", this, KeyUtils.getFingerPrint(kp.getPublic()));
+ }
+ }
+
+ @Override
+ public KeyPair removePublicKeyIdentity(KeyPair kp) {
+ if (kp == null) {
+ return null;
+ }
+
+ int index = findIdentityIndex(KEYPAIR_IDENTITY_COMPARATOR, kp);
+ if (index >= 0) {
+ return (KeyPair) identities.remove(index);
+ } else {
+ return null;
+ }
+ }
+
+ protected int findIdentityIndex(Comparator<? super Object> comp, Object target) {
+ for (int index = 0; index < identities.size(); index++) {
+ Object value = identities.get(index);
+ if (comp.compare(value, target) == 0) {
+ return index;
+ }
+ }
+
+ return -1;
+ }
+
+ @Override
+ public ClientChannel createChannel(String type) throws IOException {
+ return createChannel(type, null);
+ }
+
+ @Override
+ public ClientChannel createChannel(String type, String subType) throws IOException {
+ if (ClientChannel.CHANNEL_SHELL.equals(type)) {
+ return createShellChannel();
+ } else if (ClientChannel.CHANNEL_EXEC.equals(type)) {
+ return createExecChannel(subType);
+ } else if (ClientChannel.CHANNEL_SUBSYSTEM.equals(type)) {
+ return createSubsystemChannel(subType);
+ } else {
+ throw new IllegalArgumentException("Unsupported channel type " + type);
+ }
+ }
+
+ @Override
+ public ChannelExec createExecChannel(String command) throws IOException {
+ ChannelExec channel = new ChannelExec(command);
+ ConnectionService service = getConnectionService();
+ int id = service.registerChannel(channel);
+ if (log.isDebugEnabled()) {
+ log.debug("createExecChannel({})[{}] created id={}", this, command, id);
+ }
+ return channel;
+ }
+
+ @Override
+ public ChannelSubsystem createSubsystemChannel(String subsystem) throws IOException {
+ ChannelSubsystem channel = new ChannelSubsystem(subsystem);
+ ConnectionService service = getConnectionService();
+ int id = service.registerChannel(channel);
+ if (log.isDebugEnabled()) {
+ log.debug("createSubsystemChannel({})[{}] created id={}", this, subsystem, id);
+ }
+ return channel;
+ }
+
+ @Override
+ public ChannelDirectTcpip createDirectTcpipChannel(SshdSocketAddress local, SshdSocketAddress remote) throws IOException {
+ ChannelDirectTcpip channel = new ChannelDirectTcpip(local, remote);
+ ConnectionService service = getConnectionService();
+ int id = service.registerChannel(channel);
+ if (log.isDebugEnabled()) {
+ log.debug("createDirectTcpipChannel({})[{} => {}] created id={}", this, local, remote, id);
+ }
+ return channel;
+ }
+
+ protected ClientUserAuthService getUserAuthService() {
+ return getService(ClientUserAuthService.class);
+ }
+
+ protected ConnectionService getConnectionService() {
+ return getService(ConnectionService.class);
+ }
+
+ @Override
+ public ScpTransferEventListener getScpTransferEventListener() {
+ return scpListener;
+ }
+
+ @Override
+ public void setScpTransferEventListener(ScpTransferEventListener listener) {
+ scpListener = listener;
+ }
+
+ @Override
+ public ScpClient createScpClient() {
+ return createScpClient(getScpTransferEventListener());
+ }
+
+ @Override
+ public ScpClient createScpClient(ScpTransferEventListener listener) {
+ return new DefaultScpClient(this, listener);
+ }
+
+ @Override // TODO make this a default method in JDK-8
+ public SftpClient createSftpClient() throws IOException {
+ return createSftpClient(SftpVersionSelector.CURRENT);
+ }
+
+ @Override // TODO make this a default method in JDK-8
+ public SftpClient createSftpClient(final int version) throws IOException {
+ return createSftpClient(SftpVersionSelector.Utils.fixedVersionSelector(version));
+ }
+
+ @Override
+ public SftpClient createSftpClient(SftpVersionSelector selector) throws IOException {
+ DefaultSftpClient client = new DefaultSftpClient(this);
+ client.negotiateVersion(selector);
+ return client;
+ }
+
+ @Override
+ public FileSystem createSftpFileSystem() throws IOException {
+ return createSftpFileSystem(SftpVersionSelector.CURRENT);
+ }
+
+ @Override
+ public FileSystem createSftpFileSystem(int version) throws IOException {
+ return createSftpFileSystem(SftpVersionSelector.Utils.fixedVersionSelector(version));
+ }
+
+ @Override
+ public FileSystem createSftpFileSystem(SftpVersionSelector selector) throws IOException {
+ return createSftpFileSystem(selector, SftpClient.DEFAULT_READ_BUFFER_SIZE, SftpClient.DEFAULT_WRITE_BUFFER_SIZE);
+ }
+
+ @Override
+ public FileSystem createSftpFileSystem(int version, int readBufferSize, int writeBufferSize) throws IOException {
+ return createSftpFileSystem(SftpVersionSelector.Utils.fixedVersionSelector(version), readBufferSize, writeBufferSize);
+ }
+
+ @Override
+ public FileSystem createSftpFileSystem(int readBufferSize, int writeBufferSize) throws IOException {
+ return createSftpFileSystem(SftpVersionSelector.CURRENT, readBufferSize, writeBufferSize);
+ }
+
+ @Override
+ public FileSystem createSftpFileSystem(SftpVersionSelector selector, int readBufferSize, int writeBufferSize) throws IOException {
+ SftpFileSystemProvider provider = new SftpFileSystemProvider((org.apache.sshd.client.SshClient) getFactoryManager(), selector);
+ SftpFileSystem fs = provider.newFileSystem(this);
+ fs.setReadBufferSize(readBufferSize);
+ fs.setWriteBufferSize(writeBufferSize);
+ return fs;
+ }
+
+ @Override
+ public SshdSocketAddress startLocalPortForwarding(SshdSocketAddress local, SshdSocketAddress remote) throws IOException {
+ return getTcpipForwarder().startLocalPortForwarding(local, remote);
+ }
+
+ @Override
+ public void stopLocalPortForwarding(SshdSocketAddress local) throws IOException {
+ getTcpipForwarder().stopLocalPortForwarding(local);
+ }
+
+ @Override
+ public SshdSocketAddress startRemotePortForwarding(SshdSocketAddress remote, SshdSocketAddress local) throws IOException {
+ return getTcpipForwarder().startRemotePortForwarding(remote, local);
+ }
+
+ @Override
+ public void stopRemotePortForwarding(SshdSocketAddress remote) throws IOException {
+ getTcpipForwarder().stopRemotePortForwarding(remote);
+ }
+
+ @Override
+ public SshdSocketAddress startDynamicPortForwarding(SshdSocketAddress local) throws IOException {
+ return getTcpipForwarder().startDynamicPortForwarding(local);
+ }
+
+ @Override
+ public void stopDynamicPortForwarding(SshdSocketAddress local) throws IOException {
+ getTcpipForwarder().stopDynamicPortForwarding(local);
+ }
+
+ protected TcpipForwarder getTcpipForwarder() {
+ ConnectionService service = ValidateUtils.checkNotNull(getConnectionService(), "No connection service");
+ return ValidateUtils.checkNotNull(service.getTcpipForwarder(), "No forwarder");
+ }
+
+ @Override
+ protected String resolveAvailableSignaturesProposal(FactoryManager manager) {
+ // the client does not have to provide keys for the available signatures
+ ValidateUtils.checkTrue(manager == getFactoryManager(), "Mismatched factory manager instances");
+ return NamedResource.Utils.getNames(getSignatureFactories());
+ }
+
+ @Override
+ public void startService(String name) throws Exception {
+ throw new IllegalStateException("Starting services is not supported on the client side: " + name);
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
index 87e50f5..6ffb863 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
@@ -25,8 +25,8 @@ import java.util.Collection;
import java.util.Map;
import java.util.Set;
+import org.apache.sshd.client.ClientAuthenticationManager;
import org.apache.sshd.client.ClientFactoryManager;
-import org.apache.sshd.client.auth.UserInteraction;
import org.apache.sshd.client.channel.ChannelDirectTcpip;
import org.apache.sshd.client.channel.ChannelExec;
import org.apache.sshd.client.channel.ChannelShell;
@@ -70,7 +70,7 @@ import org.apache.sshd.common.session.Session;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface ClientSession extends Session, KeyPairProviderHolder {
+public interface ClientSession extends Session, KeyPairProviderHolder, ClientAuthenticationManager {
enum ClientSessionEvent {
TIMEOUT,
CLOSED,
@@ -105,21 +105,6 @@ public interface ClientSession extends Session, KeyPairProviderHolder {
KeyPair removePublicKeyIdentity(KeyPair kp);
/**
- * @return The <U>specific</U> {@link UserInteraction} for this
- * session. May be {@code null} indicating that the
- * {@link ClientFactoryManager#getUserInteraction()} (if any) should
- * be used
- */
- UserInteraction getUserInteraction();
-
- /**
- * @param userInteraction The <U>specific</U> {@link UserInteraction} for this
- * session. May be {@code null} indicating that the
- * {@link ClientFactoryManager#getUserInteraction()} (if any) should be used
- */
- void setUserInteraction(UserInteraction userInteraction);
-
- /**
* Starts the authentication process.
* User identities will be tried until the server successfully authenticate the user.
* User identities must be provided before calling this method using
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
index 0c9de7c..58eee3d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSessionImpl.java
@@ -20,12 +20,8 @@ package org.apache.sshd.client.session;
import java.io.IOException;
import java.net.SocketAddress;
-import java.nio.file.FileSystem;
-import java.security.KeyPair;
-import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
-import java.util.Comparator;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.HashMap;
@@ -34,42 +30,23 @@ import java.util.Map;
import java.util.Set;
import org.apache.sshd.client.ClientFactoryManager;
-import org.apache.sshd.client.auth.UserInteraction;
-import org.apache.sshd.client.channel.ChannelDirectTcpip;
-import org.apache.sshd.client.channel.ChannelExec;
import org.apache.sshd.client.channel.ChannelShell;
-import org.apache.sshd.client.channel.ChannelSubsystem;
-import org.apache.sshd.client.channel.ClientChannel;
import org.apache.sshd.client.future.AuthFuture;
import org.apache.sshd.client.future.DefaultAuthFuture;
import org.apache.sshd.client.keyverifier.ServerKeyVerifier;
-import org.apache.sshd.client.scp.DefaultScpClient;
-import org.apache.sshd.client.scp.ScpClient;
-import org.apache.sshd.client.subsystem.sftp.DefaultSftpClient;
-import org.apache.sshd.client.subsystem.sftp.SftpClient;
-import org.apache.sshd.client.subsystem.sftp.SftpFileSystem;
-import org.apache.sshd.client.subsystem.sftp.SftpFileSystemProvider;
-import org.apache.sshd.client.subsystem.sftp.SftpVersionSelector;
import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.Service;
import org.apache.sshd.common.ServiceFactory;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshException;
-import org.apache.sshd.common.SshdSocketAddress;
import org.apache.sshd.common.cipher.BuiltinCiphers;
import org.apache.sshd.common.cipher.CipherNone;
-import org.apache.sshd.common.config.keys.KeyUtils;
-import org.apache.sshd.common.forward.TcpipForwarder;
import org.apache.sshd.common.future.DefaultKeyExchangeFuture;
import org.apache.sshd.common.future.KeyExchangeFuture;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.kex.KexProposalOption;
import org.apache.sshd.common.kex.KexState;
-import org.apache.sshd.common.keyprovider.KeyPairProvider;
-import org.apache.sshd.common.scp.ScpTransferEventListener;
import org.apache.sshd.common.session.AbstractConnectionService;
-import org.apache.sshd.common.session.AbstractSession;
import org.apache.sshd.common.session.ConnectionService;
import org.apache.sshd.common.session.SessionListener;
import org.apache.sshd.common.util.GenericUtils;
@@ -81,39 +58,7 @@ import org.apache.sshd.common.util.buffer.Buffer;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public class ClientSessionImpl extends AbstractSession implements ClientSession {
- /**
- * Compares 2 password identities - returns zero ONLY if <U>both</U> compared
- * objects are {@link String}s and equal to each other
- */
- public static final Comparator<Object> PASSWORD_IDENTITY_COMPARATOR = new Comparator<Object>() {
- @Override
- public int compare(Object o1, Object o2) {
- if (!(o1 instanceof String) || !(o2 instanceof String)) {
- return -1;
- } else {
- return ((String) o1).compareTo((String) o2);
- }
- }
- };
-
- /**
- * Compares 2 {@link KeyPair} identities - returns zero ONLY if <U>both</U> compared
- * objects are {@link KeyPair}s and equal to each other
- */
- public static final Comparator<Object> KEYPAIR_IDENTITY_COMPARATOR = new Comparator<Object>() {
- @Override
- public int compare(Object o1, Object o2) {
- if ((!(o1 instanceof KeyPair)) || (!(o2 instanceof KeyPair))) {
- return -1;
- } else if (KeyUtils.compareKeyPairs((KeyPair) o1, (KeyPair) o2)) {
- return 0;
- } else {
- return 1;
- }
- }
- };
-
+public class ClientSessionImpl extends AbstractClientSession {
protected AuthFuture authFuture;
/**
@@ -126,14 +71,12 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
private ServiceFactory currentServiceFactory;
private Service nextService;
private ServiceFactory nextServiceFactory;
- private final List<Object> identities = new ArrayList<>();
- private UserInteraction userInteraction;
- private ScpTransferEventListener scpListener;
- private KeyPairProvider keyPairProvider;
public ClientSessionImpl(ClientFactoryManager client, IoSession session) throws Exception {
- super(false, client, session);
- log.debug("Client session created: {}", session);
+ super(client, session);
+ if (log.isDebugEnabled()) {
+ log.debug("Client session created: {}", session);
+ }
// Need to set the initial service early as calling code likes to start trying to
// manipulate it before the connection has even been established. For instance, to
// set the authPassword.
@@ -152,6 +95,11 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
authFuture = new DefaultAuthFuture(lock);
authFuture.setAuthed(false);
+
+ // Inform the listener of the newly created session
+ SessionListener listener = getSessionListenerProxy();
+ listener.sessionCreated(this);
+
sendClientIdentification();
kexState.set(KexState.INIT);
sendKexInit();
@@ -171,90 +119,6 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
}
@Override
- public ClientFactoryManager getFactoryManager() {
- return (ClientFactoryManager) super.getFactoryManager();
- }
-
- @Override
- public KeyPairProvider getKeyPairProvider() {
- return keyPairProvider;
- }
-
- public void setKeyPairProvider(KeyPairProvider keyPairProvider) {
- this.keyPairProvider = keyPairProvider;
- }
-
- @Override
- public void addPasswordIdentity(String password) {
- identities.add(ValidateUtils.checkNotNullAndNotEmpty(password, "No password provided"));
- if (log.isDebugEnabled()) { // don't show the password in the log
- log.debug("addPasswordIdentity({}) {}", this, KeyUtils.getFingerPrint(password));
- }
- }
-
- @Override
- public String removePasswordIdentity(String password) {
- if (GenericUtils.isEmpty(password)) {
- return null;
- }
-
- int index = findIdentityIndex(PASSWORD_IDENTITY_COMPARATOR, password);
- if (index >= 0) {
- return (String) identities.remove(index);
- } else {
- return null;
- }
- }
-
- @Override
- public void addPublicKeyIdentity(KeyPair kp) {
- ValidateUtils.checkNotNull(kp, "No key-pair to add");
- ValidateUtils.checkNotNull(kp.getPublic(), "No public key");
- ValidateUtils.checkNotNull(kp.getPrivate(), "No private key");
-
- identities.add(kp);
-
- if (log.isDebugEnabled()) {
- log.debug("addPublicKeyIdentity({}) {}", this, KeyUtils.getFingerPrint(kp.getPublic()));
- }
- }
-
- @Override
- public KeyPair removePublicKeyIdentity(KeyPair kp) {
- if (kp == null) {
- return null;
- }
-
- int index = findIdentityIndex(KEYPAIR_IDENTITY_COMPARATOR, kp);
- if (index >= 0) {
- return (KeyPair) identities.remove(index);
- } else {
- return null;
- }
- }
-
- protected int findIdentityIndex(Comparator<? super Object> comp, Object target) {
- for (int index = 0; index < identities.size(); index++) {
- Object value = identities.get(index);
- if (comp.compare(value, target) == 0) {
- return index;
- }
- }
-
- return -1;
- }
-
- @Override
- public UserInteraction getUserInteraction() {
- return userInteraction;
- }
-
- @Override
- public void setUserInteraction(UserInteraction userInteraction) {
- this.userInteraction = userInteraction;
- }
-
- @Override
public AuthFuture auth() throws IOException {
if (username == null) {
throw new IllegalStateException("No username specified when the session was created");
@@ -262,7 +126,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
ClientUserAuthService authService = getUserAuthService();
synchronized (lock) {
- authFuture = authService.auth(identities, nextServiceName());
+ authFuture = authService.auth(getRegisteredIdentities(), nextServiceName());
return authFuture;
}
}
@@ -350,24 +214,6 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
}
@Override
- public ClientChannel createChannel(String type) throws IOException {
- return createChannel(type, null);
- }
-
- @Override
- public ClientChannel createChannel(String type, String subType) throws IOException {
- if (ClientChannel.CHANNEL_SHELL.equals(type)) {
- return createShellChannel();
- } else if (ClientChannel.CHANNEL_EXEC.equals(type)) {
- return createExecChannel(subType);
- } else if (ClientChannel.CHANNEL_SUBSYSTEM.equals(type)) {
- return createSubsystemChannel(subType);
- } else {
- throw new IllegalArgumentException("Unsupported channel type " + type);
- }
- }
-
- @Override
public ChannelShell createShellChannel() throws IOException {
if ((inCipher instanceof CipherNone) || (outCipher instanceof CipherNone)) {
throw new IllegalStateException("Interactive channels are not supported with none cipher");
@@ -382,153 +228,6 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
}
@Override
- public ChannelExec createExecChannel(String command) throws IOException {
- ChannelExec channel = new ChannelExec(command);
- ConnectionService service = getConnectionService();
- int id = service.registerChannel(channel);
- if (log.isDebugEnabled()) {
- log.debug("createExecChannel({})[{}] created id={}", this, command, id);
- }
- return channel;
- }
-
- @Override
- public ChannelSubsystem createSubsystemChannel(String subsystem) throws IOException {
- ChannelSubsystem channel = new ChannelSubsystem(subsystem);
- ConnectionService service = getConnectionService();
- int id = service.registerChannel(channel);
- if (log.isDebugEnabled()) {
- log.debug("createSubsystemChannel({})[{}] created id={}", this, subsystem, id);
- }
- return channel;
- }
-
- @Override
- public ChannelDirectTcpip createDirectTcpipChannel(SshdSocketAddress local, SshdSocketAddress remote) throws IOException {
- ChannelDirectTcpip channel = new ChannelDirectTcpip(local, remote);
- ConnectionService service = getConnectionService();
- int id = service.registerChannel(channel);
- if (log.isDebugEnabled()) {
- log.debug("createDirectTcpipChannel({})[{} => {}] created id={}", this, local, remote, id);
- }
- return channel;
- }
-
- private ClientUserAuthService getUserAuthService() {
- return getService(ClientUserAuthService.class);
- }
-
- private ConnectionService getConnectionService() {
- return getService(ConnectionService.class);
- }
-
- @Override
- public ScpTransferEventListener getScpTransferEventListener() {
- return scpListener;
- }
-
- @Override
- public void setScpTransferEventListener(ScpTransferEventListener listener) {
- scpListener = listener;
- }
-
- @Override
- public ScpClient createScpClient() {
- return createScpClient(getScpTransferEventListener());
- }
-
- @Override
- public ScpClient createScpClient(ScpTransferEventListener listener) {
- return new DefaultScpClient(this, listener);
- }
-
- @Override // TODO make this a default method in JDK-8
- public SftpClient createSftpClient() throws IOException {
- return createSftpClient(SftpVersionSelector.CURRENT);
- }
-
- @Override // TODO make this a default method in JDK-8
- public SftpClient createSftpClient(final int version) throws IOException {
- return createSftpClient(SftpVersionSelector.Utils.fixedVersionSelector(version));
- }
-
- @Override
- public SftpClient createSftpClient(SftpVersionSelector selector) throws IOException {
- DefaultSftpClient client = new DefaultSftpClient(this);
- client.negotiateVersion(selector);
- return client;
- }
-
- @Override
- public FileSystem createSftpFileSystem() throws IOException {
- return createSftpFileSystem(SftpVersionSelector.CURRENT);
- }
-
- @Override
- public FileSystem createSftpFileSystem(int version) throws IOException {
- return createSftpFileSystem(SftpVersionSelector.Utils.fixedVersionSelector(version));
- }
-
- @Override
- public FileSystem createSftpFileSystem(SftpVersionSelector selector) throws IOException {
- return createSftpFileSystem(selector, SftpClient.DEFAULT_READ_BUFFER_SIZE, SftpClient.DEFAULT_WRITE_BUFFER_SIZE);
- }
-
- @Override
- public FileSystem createSftpFileSystem(int version, int readBufferSize, int writeBufferSize) throws IOException {
- return createSftpFileSystem(SftpVersionSelector.Utils.fixedVersionSelector(version), readBufferSize, writeBufferSize);
- }
-
- @Override
- public FileSystem createSftpFileSystem(int readBufferSize, int writeBufferSize) throws IOException {
- return createSftpFileSystem(SftpVersionSelector.CURRENT, readBufferSize, writeBufferSize);
- }
-
- @Override
- public FileSystem createSftpFileSystem(SftpVersionSelector selector, int readBufferSize, int writeBufferSize) throws IOException {
- SftpFileSystemProvider provider = new SftpFileSystemProvider((org.apache.sshd.client.SshClient) getFactoryManager(), selector);
- SftpFileSystem fs = provider.newFileSystem(this);
- fs.setReadBufferSize(readBufferSize);
- fs.setWriteBufferSize(writeBufferSize);
- return fs;
- }
-
- @Override
- public SshdSocketAddress startLocalPortForwarding(SshdSocketAddress local, SshdSocketAddress remote) throws IOException {
- return getTcpipForwarder().startLocalPortForwarding(local, remote);
- }
-
- @Override
- public void stopLocalPortForwarding(SshdSocketAddress local) throws IOException {
- getTcpipForwarder().stopLocalPortForwarding(local);
- }
-
- @Override
- public SshdSocketAddress startRemotePortForwarding(SshdSocketAddress remote, SshdSocketAddress local) throws IOException {
- return getTcpipForwarder().startRemotePortForwarding(remote, local);
- }
-
- @Override
- public void stopRemotePortForwarding(SshdSocketAddress remote) throws IOException {
- getTcpipForwarder().stopRemotePortForwarding(remote);
- }
-
- @Override
- public SshdSocketAddress startDynamicPortForwarding(SshdSocketAddress local) throws IOException {
- return getTcpipForwarder().startDynamicPortForwarding(local);
- }
-
- @Override
- public void stopDynamicPortForwarding(SshdSocketAddress local) throws IOException {
- getTcpipForwarder().stopDynamicPortForwarding(local);
- }
-
- protected TcpipForwarder getTcpipForwarder() {
- ConnectionService service = ValidateUtils.checkNotNull(getConnectionService(), "No connection service");
- return ValidateUtils.checkNotNull(service.getTcpipForwarder(), "No forwarder");
- }
-
- @Override
protected void handleMessage(Buffer buffer) throws Exception {
synchronized (lock) {
super.handleMessage(buffer);
@@ -639,12 +338,6 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
}
@Override
- protected String resolveAvailableSignaturesProposal(FactoryManager manager) {
- // the client does not have to provide keys for the available signatures
- return NamedResource.Utils.getNames(manager.getSignatureFactories());
- }
-
- @Override
protected void receiveKexInit(Map<KexProposalOption, String> proposal, byte[] seed) throws IOException {
mergeProposals(serverProposal, proposal);
i_s = seed;
@@ -652,8 +345,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
@Override
protected void checkKeys() throws SshException {
- ClientFactoryManager manager = getFactoryManager();
- ServerKeyVerifier serverKeyVerifier = manager.getServerKeyVerifier();
+ ServerKeyVerifier serverKeyVerifier = ValidateUtils.checkNotNull(getServerKeyVerifier(), "No server key verifier");
SocketAddress remoteAddress = ioSession.getRemoteAddress();
if (!serverKeyVerifier.verifyServerKey(this, remoteAddress, kex.getServerKey())) {
@@ -692,11 +384,6 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
}
@Override
- public void startService(String name) throws Exception {
- throw new IllegalStateException("Starting services is not supported on the client side: " + name);
- }
-
- @Override
public Map<Object, Object> getMetadataMap() {
return metadataMap;
}
[07/10] mina-sshd git commit: Added the capability to write debug
output messages from a test
Posted by lg...@apache.org.
Added the capability to write debug output messages from a test
* Disabled by default - can be activated via -Dorg.apache.sshd.test.outputDebugMessages=true
* Used to add information to tests that seem to fail from time to time without any obvious reason
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/88a30f56
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/88a30f56
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/88a30f56
Branch: refs/heads/master
Commit: 88a30f562aa0ded9c9ff19f37579e43e72139910
Parents: fd3cb93
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Thu Nov 26 07:26:52 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Thu Nov 26 07:26:52 2015 +0200
----------------------------------------------------------------------
.../java/org/apache/sshd/KeyReExchangeTest.java | 10 +++---
.../org/apache/sshd/client/scp/ScpTest.java | 17 +++++++---
.../subsystem/sftp/SftpFileSystemTest.java | 35 ++++++++++----------
.../sshd/client/subsystem/sftp/SftpTest.java | 6 ++--
.../apache/sshd/util/test/BaseTestSupport.java | 13 ++++++++
5 files changed, 52 insertions(+), 29 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/88a30f56/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java b/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
index f8619bb..077e531 100644
--- a/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/KeyReExchangeTest.java
@@ -329,8 +329,9 @@ public class KeyReExchangeTest extends BaseTestSupport {
@Override
public void sessionEvent(Session session, Event event) {
- if (event == Event.KeyEstablished) {
- exchanges.incrementAndGet();
+ if (Event.KeyEstablished.equals(event)) {
+ int count = exchanges.incrementAndGet();
+ outputDebugMessage("Key established for %s - count=%d", session, count);
}
}
@@ -409,8 +410,9 @@ public class KeyReExchangeTest extends BaseTestSupport {
@Override
public void sessionEvent(Session session, Event event) {
- if (event == Event.KeyEstablished) {
- exchanges.incrementAndGet();
+ if (Event.KeyEstablished.equals(event)) {
+ int count = exchanges.incrementAndGet();
+ outputDebugMessage("Key established for %s - count=%d", session, count);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/88a30f56/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java b/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
index 7d6ed21..1fd8194 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
@@ -372,6 +372,7 @@ public class ScpTest extends BaseTestSupport {
String localOutPath = localOutFile.toString();
String remoteOutPath = Utils.resolveRelativeRemotePath(parentPath, remoteOutFile);
+ outputDebugMessage("Expect upload failure %s => %s", localOutPath, remoteOutPath);
try {
scp.upload(localOutPath, remoteOutPath);
fail("Expected IOException for 1st time " + remoteOutPath);
@@ -380,15 +381,20 @@ public class ScpTest extends BaseTestSupport {
}
assertHierarchyTargetFolderExists(remoteDir);
+ outputDebugMessage("Expect upload success %s => %s", localOutPath, remoteOutPath);
scp.upload(localOutPath, remoteOutPath);
assertFileLength(remoteOutFile, data.length(), TimeUnit.SECONDS.toMillis(5L));
Path secondLocal = localDir.resolve(localOutFile.getFileName());
- scp.download(remoteOutPath, Utils.resolveRelativeRemotePath(parentPath, secondLocal));
+ String downloadTarget = Utils.resolveRelativeRemotePath(parentPath, secondLocal);
+ outputDebugMessage("Expect download success %s => %s", remoteOutPath, downloadTarget);
+ scp.download(remoteOutPath, downloadTarget);
assertFileLength(secondLocal, data.length(), TimeUnit.SECONDS.toMillis(5L));
Path localPath = localDir.resolve("file-path.txt");
- scp.download(remoteOutPath, Utils.resolveRelativeRemotePath(parentPath, localPath));
+ downloadTarget = Utils.resolveRelativeRemotePath(parentPath, localPath);
+ outputDebugMessage("Expect download success %s => %s", remoteOutPath, downloadTarget);
+ scp.download(remoteOutPath, downloadTarget);
assertFileLength(localPath, data.length(), TimeUnit.SECONDS.toMillis(5L));
} finally {
client.stop();
@@ -795,9 +801,10 @@ public class ScpTest extends BaseTestSupport {
final Connection conn = new Connection(TEST_LOCALHOST, port);
try {
ConnectionInfo info = conn.connect(null, (int) TimeUnit.SECONDS.toMillis(5L), (int) TimeUnit.SECONDS.toMillis(11L));
- System.out.println("Connected: kex=" + info.keyExchangeAlgorithm + ", key-type=" + info.serverHostKeyAlgorithm
- + ", c2senc=" + info.clientToServerCryptoAlgorithm + ", s2cenc=" + info.serverToClientCryptoAlgorithm
- + ", c2mac=" + info.clientToServerMACAlgorithm + ", s2cmac=" + info.serverToClientMACAlgorithm);
+ outputDebugMessage("Connected: kex=%s, key-type=%s, c2senc=%s, s2cenc=%s, c2mac=%s, s2cmac=%s",
+ info.keyExchangeAlgorithm, info.serverHostKeyAlgorithm,
+ info.clientToServerCryptoAlgorithm, info.serverToClientCryptoAlgorithm,
+ info.clientToServerMACAlgorithm, info.serverToClientMACAlgorithm);
conn.authenticateWithPassword(getCurrentTestName(), getCurrentTestName());
final SCPClient scp_client = new SCPClient(conn);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/88a30f56/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java
index b41841c..cb00f99 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/subsystem/sftp/SftpFileSystemTest.java
@@ -231,7 +231,7 @@ public class SftpFileSystemTest extends BaseTestSupport {
SftpFileSystem actual = provider.getFileSystem(id);
assertSame("Mismatched cached instances for " + id, expected, actual);
- System.out.println("Created file system id: " + id);
+ outputDebugMessage("Created file system id: %s", id);
}
for (SftpFileSystem fs : fsList) {
@@ -316,7 +316,7 @@ public class SftpFileSystemTest extends BaseTestSupport {
String name = child.getFileName().toString();
assertNotEquals("Unexpected dot name", ".", name);
assertNotEquals("Unexpected dotdot name", "..", name);
- System.out.append('\t').append('[').append(rootName).append("] ").println(child);
+ outputDebugMessage("[%s] %s", rootName, child);
}
} catch (IOException | RuntimeException e) {
// TODO on Windows one might get share problems for *.sys files
@@ -335,7 +335,7 @@ public class SftpFileSystemTest extends BaseTestSupport {
Utils.deleteRecursive(lclSftp);
Path current = fs.getPath(".").toRealPath().normalize();
- System.out.append("CWD: ").println(current);
+ outputDebugMessage("CWD: %s", current);
Path parentPath = targetPath.getParent();
Path clientFolder = lclSftp.resolve("client");
@@ -345,20 +345,24 @@ public class SftpFileSystemTest extends BaseTestSupport {
String expected = "Hello world: " + getCurrentTestName();
{
+ outputDebugMessage("Write initial data to %s", file1);
Files.write(file1, expected.getBytes(StandardCharsets.UTF_8));
String buf = new String(Files.readAllBytes(file1), StandardCharsets.UTF_8);
assertEquals("Mismatched read test data", expected, buf);
}
if (version >= SftpConstants.SFTP_V4) {
+ outputDebugMessage("getFileAttributeView(%s)", file1);
AclFileAttributeView aclView = Files.getFileAttributeView(file1, AclFileAttributeView.class, LinkOption.NOFOLLOW_LINKS);
assertNotNull("No ACL view for " + file1, aclView);
Map<String, ?> attrs = Files.readAttributes(file1, "acl:*", LinkOption.NOFOLLOW_LINKS);
+ outputDebugMessage("readAttributes(%s) %s", file1, attrs);
assertEquals("Mismatched owner for " + file1, aclView.getOwner(), attrs.get("owner"));
@SuppressWarnings("unchecked")
List<AclEntry> acl = (List<AclEntry>) attrs.get("acl");
+ outputDebugMessage("acls(%s) %s", file1, acl);
assertListEquals("Mismatched ACLs for " + file1, aclView.getAcl(), acl);
}
@@ -367,6 +371,7 @@ public class SftpFileSystemTest extends BaseTestSupport {
String remFile3Path = Utils.resolveRelativeRemotePath(parentPath, clientFolder.resolve("file-3.txt"));
Path file3 = fs.getPath(remFile3Path);
try {
+ outputDebugMessage("Move with failure expected %s => %s", file2, file3);
Files.move(file2, file3, LinkOption.NOFOLLOW_LINKS);
fail("Unexpected success in moving " + file2 + " => " + file3);
} catch (NoSuchFileException e) {
@@ -375,48 +380,44 @@ public class SftpFileSystemTest extends BaseTestSupport {
Files.write(file2, "h".getBytes(StandardCharsets.UTF_8));
try {
+ outputDebugMessage("Move with failure expected %s => %s", file1, file2);
Files.move(file1, file2, LinkOption.NOFOLLOW_LINKS);
fail("Unexpected success in moving " + file1 + " => " + file2);
} catch (FileAlreadyExistsException e) {
// expected
}
- System.out.append('\t').append("Move ").append(file1.toString()).append(" => ").println(file2);
+
+ outputDebugMessage("Move with success expected %s => %s", file1, file2);
Files.move(file1, file2, LinkOption.NOFOLLOW_LINKS, StandardCopyOption.REPLACE_EXISTING);
- System.out.append('\t').append("Move ").append(file2.toString()).append(" => ").println(file1);
+ outputDebugMessage("Move with success expected %s => %s", file2, file1);
Files.move(file2, file1, LinkOption.NOFOLLOW_LINKS);
Map<String, Object> attrs = Files.readAttributes(file1, "*");
- System.out.append('\t').append(file1.toString()).append(" attributes: ").println(attrs);
-
- // TODO: symbolic links only work for absolute files
-// Path link = fs.getPath("target/sftp/client/test2.txt");
-// Files.createSymbolicLink(link, link.relativize(file));
-// assertTrue(Files.isSymbolicLink(link));
-// assertEquals("test.txt", Files.readSymbolicLink(link).toString());
+ outputDebugMessage("%s attributes: %s", file1, attrs);
// TODO there are many issues with symbolic links on Windows
if (OsUtils.isUNIX()) {
Path link = fs.getPath(remFile2Path);
Path linkParent = link.getParent();
Path relPath = linkParent.relativize(file1);
- System.out.append('\t').append("Create symlink ").append(link.toString()).append(" => ").println(relPath);
+ outputDebugMessage("Create symlink %s => %s", link, relPath);
Files.createSymbolicLink(link, relPath);
assertTrue("Not a symbolic link: " + link, Files.isSymbolicLink(link));
Path symLink = Files.readSymbolicLink(link);
assertEquals("mismatched symbolic link name", relPath.toString(), symLink.toString());
- System.out.append('\t').append("Delete symlink ").println(link);
+
+ outputDebugMessage("Delete symlink %s", link);
Files.delete(link);
}
attrs = Files.readAttributes(file1, "*", LinkOption.NOFOLLOW_LINKS);
- System.out.append('\t').append(file1.toString()).append(" no-follow attributes: ").println(attrs);
-
+ outputDebugMessage("%s no-follow attributes: %s", file1, attrs);
assertEquals("Mismatched symlink data", expected, new String(Files.readAllBytes(file1)));
try (FileChannel channel = FileChannel.open(file1)) {
try (FileLock lock = channel.lock()) {
- System.out.append('\t').append("Lock ").append(file1.toString()).append(": ").println(lock.toString());
+ outputDebugMessage("Lock %s: %s", file1, lock);
try (FileChannel channel2 = FileChannel.open(file1)) {
try (FileLock lock2 = channel2.lock()) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/88a30f56/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 fd9791e..c1d8f0c 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
@@ -856,7 +856,7 @@ public class SftpTest extends AbstractSftpClientTestSupport {
}
for (Object f : res) {
- System.out.append('\t').println(f);
+ outputDebugMessage("LsEntry: %s", f);
ChannelSftp.LsEntry entry = (ChannelSftp.LsEntry) f;
String name = entry.getFilename();
@@ -949,7 +949,7 @@ public class SftpTest extends AbstractSftpClientTestSupport {
for (Map.Entry<String, ?> de : data.entrySet()) {
String extName = de.getKey();
Object extValue = de.getValue();
- System.out.append('\t').append(extName).append(": ").println(extValue);
+ outputDebugMessage("%s: %s", extName, extValue);
if (SftpConstants.EXT_SUPPORTED.equalsIgnoreCase(extName)) {
assertSupportedExtensions(extName, ((Supported) extValue).extensionNames);
} else if (SftpConstants.EXT_SUPPORTED2.equalsIgnoreCase(extName)) {
@@ -1204,7 +1204,7 @@ public class SftpTest extends AbstractSftpClientTestSupport {
}
assertFalse("Target link exists before linking: " + linkPath, Files.exists(linkPath, options));
- System.out.append('\t').append("Symlink ").append(remLinkPath).append(" => ").println(remSrcPath);
+ outputDebugMessage("Symlink %s => %s", remLinkPath, remSrcPath);
c.symlink(remSrcPath, remLinkPath);
assertTrue("Symlink not created: " + linkPath, Files.exists(linkPath, options));
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/88a30f56/sshd-core/src/test/java/org/apache/sshd/util/test/BaseTestSupport.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/test/BaseTestSupport.java b/sshd-core/src/test/java/org/apache/sshd/util/test/BaseTestSupport.java
index 7409ebb..2e7d32b 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/test/BaseTestSupport.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/test/BaseTestSupport.java
@@ -67,6 +67,7 @@ public abstract class BaseTestSupport extends Assert {
public static final String TEMP_SUBFOLDER_NAME = "temp";
// can be used to override the 'localhost' with an address other than 127.0.0.1 in case it is required
public static final String TEST_LOCALHOST = System.getProperty("org.apache.sshd.test.localhost", SshdSocketAddress.LOCALHOST_IP);
+ public static final boolean OUTPUT_DEBUG_MESSAGES = Boolean.parseBoolean(System.getProperty("org.apache.sshd.test.outputDebugMessages", "false"));
// useful test sizes for keys
@SuppressWarnings("boxing")
@@ -519,4 +520,16 @@ public abstract class BaseTestSupport extends Assert {
return false;
}
+
+ public static void outputDebugMessage(String format, Object ... args) {
+ if (OUTPUT_DEBUG_MESSAGES) {
+ outputDebugMessage(String.format(format, args));
+ }
+ }
+
+ public static void outputDebugMessage(Object message) {
+ if (OUTPUT_DEBUG_MESSAGES) {
+ System.out.append("===[DEBUG]=== ").println(message);
+ }
+ }
}
[05/10] mina-sshd git commit: Provide a better hint to the allocated
message buffer size
Posted by lg...@apache.org.
Provide a better hint to the allocated message buffer size
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/5e733958
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/5e733958
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/5e733958
Branch: refs/heads/master
Commit: 5e7339584733ddb42fca41cf2394067674be8cd1
Parents: 1ceea03
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Thu Nov 26 07:20:53 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Thu Nov 26 07:20:53 2015 +0200
----------------------------------------------------------------------
.../apache/sshd/client/subsystem/sftp/AbstractSftpClient.java | 6 +++---
.../org/apache/sshd/common/forward/DefaultTcpipForwarder.java | 2 +-
.../org/apache/sshd/server/forward/TcpipServerChannel.java | 2 +-
.../java/org/apache/sshd/server/x11/X11ForwardSupport.java | 2 +-
4 files changed, 6 insertions(+), 6 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/5e733958/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
index d648b2b..009d48a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
@@ -975,7 +975,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
throw new IOException("canonicalPath(" + path + ") client is closed");
}
- Buffer buffer = new ByteArrayBuffer();
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE);
buffer.putString(path);
return checkOneName(SftpConstants.SSH_FXP_REALPATH, buffer);
}
@@ -986,7 +986,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
throw new IOException("stat(" + path + ") client is closed");
}
- Buffer buffer = new ByteArrayBuffer();
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE);
buffer.putString(path);
int version = getVersion();
@@ -1003,7 +1003,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
throw new IOException("lstat(" + path + ") client is closed");
}
- Buffer buffer = new ByteArrayBuffer();
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE);
buffer.putString(path);
int version = getVersion();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/5e733958/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java b/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java
index 524e804..0a239c0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java
@@ -413,7 +413,7 @@ public class DefaultTcpipForwarder extends AbstractInnerCloseable implements Tcp
@Override
public void messageReceived(IoSession session, Readable message) throws Exception {
TcpipClientChannel channel = (TcpipClientChannel) session.getAttribute(TcpipClientChannel.class);
- Buffer buffer = new ByteArrayBuffer();
+ Buffer buffer = new ByteArrayBuffer(message.available() + Long.SIZE);
buffer.putBuffer(message);
channel.waitFor(EnumSet.of(ClientChannel.ClientChannelEvent.OPENED, ClientChannel.ClientChannelEvent.CLOSED), Long.MAX_VALUE);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/5e733958/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
index 2641601..dbfd767 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
@@ -152,7 +152,7 @@ public class TcpipServerChannel extends AbstractServerChannel {
log.debug("doInit({}) Ignoring write to channel in CLOSING state", TcpipServerChannel.this);
}
} else {
- Buffer buffer = new ByteArrayBuffer();
+ Buffer buffer = new ByteArrayBuffer(message.available() + Long.SIZE);
buffer.putBuffer(message);
out.write(buffer.array(), buffer.rpos(), buffer.available());
out.flush();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/5e733958/sshd-core/src/main/java/org/apache/sshd/server/x11/X11ForwardSupport.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/x11/X11ForwardSupport.java b/sshd-core/src/main/java/org/apache/sshd/server/x11/X11ForwardSupport.java
index 5bea64a..55f8b45 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/x11/X11ForwardSupport.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/x11/X11ForwardSupport.java
@@ -166,7 +166,7 @@ public class X11ForwardSupport extends AbstractInnerCloseable implements IoHandl
@Override
public void messageReceived(IoSession session, Readable message) throws Exception {
ChannelForwardedX11 channel = (ChannelForwardedX11) session.getAttribute(ChannelForwardedX11.class);
- Buffer buffer = new ByteArrayBuffer();
+ Buffer buffer = new ByteArrayBuffer(message.available() + Long.SIZE);
buffer.putBuffer(message);
OutputStream outputStream = channel.getInvertedIn();
[10/10] mina-sshd git commit: Added more informative log messages in
cases where exceptions are caught and logged
Posted by lg...@apache.org.
Added more informative log messages in cases where exceptions are caught and logged
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/b07095c9
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/b07095c9
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/b07095c9
Branch: refs/heads/master
Commit: b07095c9bc7142afb816718251360643ce758f17
Parents: be8428a
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Thu Nov 26 07:32:41 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Thu Nov 26 07:32:41 2015 +0200
----------------------------------------------------------------------
.../exit/AbstractChannelExitRequestHandler.java | 10 ++++--
.../sshd/common/channel/AbstractChannel.java | 16 ++++++---
.../sshd/common/io/nio2/Nio2Acceptor.java | 14 ++++++--
.../sshd/common/io/nio2/Nio2ServiceFactory.java | 5 ++-
.../session/AbstractConnectionService.java | 9 +++--
.../sshd/common/session/AbstractSession.java | 11 ++++--
.../server/channel/AbstractServerChannel.java | 3 ++
.../sshd/server/channel/ChannelSession.java | 3 ++
.../sshd/server/forward/TcpipServerChannel.java | 3 ++
.../org/apache/sshd/server/kex/DHGEXServer.java | 4 ++-
.../AbstractGeneratorHostKeyProvider.java | 36 +++++++++++++-------
.../sshd/server/shell/InvertedShellWrapper.java | 10 +++++-
.../apache/sshd/server/shell/ProcessShell.java | 6 +++-
.../server/subsystem/sftp/SftpSubsystem.java | 14 +++++++-
.../org/apache/sshd/client/scp/ScpTest.java | 2 ++
.../common/channel/TestChannelListener.java | 3 ++
.../server/subsystem/sftp/SshFsMounter.java | 3 ++
17 files changed, 120 insertions(+), 32 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/AbstractChannelExitRequestHandler.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/AbstractChannelExitRequestHandler.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/AbstractChannelExitRequestHandler.java
index 3040c4a..3a25f2b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/AbstractChannelExitRequestHandler.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/exit/AbstractChannelExitRequestHandler.java
@@ -102,10 +102,16 @@ public abstract class AbstractChannelExitRequestHandler<V> extends AbstractChann
try {
notifier.notifyEvent(event);
if (log.isDebugEnabled()) {
- log.debug("notifyStateChanged({})", event);
+ log.debug("notifyStateChanged({})[{}] event={}", channel, request, event);
}
} catch (Exception e) {
- log.warn("Failed (" + e.getClass().getSimpleName() + ") to notify event=" + event + ": " + e.getMessage());
+ log.warn("notifyStateChanged({})[{}] Failed ({}) to notify event={}: {}",
+ channel, request, e.getClass().getSimpleName(), event, e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("notifyStateChanged(" + channel + ")[" + request + "]"
+ + " event=" + event + " notification failure details",
+ e);
+ }
if (e instanceof RuntimeException) {
throw (RuntimeException) e;
} else {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java b/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
index 549b42d..2165ee5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/channel/AbstractChannel.java
@@ -175,16 +175,22 @@ public abstract class AbstractChannel
try {
result = handler.process(this, req, wantReply, buffer);
} catch (Exception e) {
- log.warn("handleRequest({}) {} while {}#process({}): {}",
- this, e.getClass().getSimpleName(), handler.getClass().getSimpleName(), req, e.getMessage());
+ log.warn("handleRequest({}) {} while {}#process({})[want-reply={}]: {}",
+ this, e.getClass().getSimpleName(), handler.getClass().getSimpleName(),
+ req, wantReply, e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("handleRequest(" + this + ") request=" + req
+ + "[want-reply=" + wantReply + "] processing failure details",
+ e);
+ }
result = RequestHandler.Result.ReplyFailure;
}
// if Unsupported then check the next handler in line
if (RequestHandler.Result.Unsupported.equals(result)) {
if (log.isTraceEnabled()) {
- log.trace("handleRequest({})[{}#process({})]: {}",
- this, handler.getClass().getSimpleName(), req, result);
+ log.trace("handleRequest({})[{}#process({})[want-reply={}]]: {}",
+ this, handler.getClass().getSimpleName(), req, wantReply, result);
}
} else {
sendResponse(buffer, req, result, wantReply);
@@ -193,7 +199,7 @@ public abstract class AbstractChannel
}
// none of the handlers processed the request
- log.warn("handleRequest({}) Unknown channel request: {}", this, req);
+ log.warn("handleRequest({}) Unknown channel request: {}[want-reply={}]", this, req, wantReply);
sendResponse(buffer, req, RequestHandler.Result.Unsupported, wantReply);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
index 836f41d..ebc590d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Acceptor.java
@@ -86,13 +86,21 @@ public class Nio2Acceptor extends Nio2Service implements IoAcceptor {
AsynchronousServerSocketChannel channel = channels.remove(address);
if (channel != null) {
try {
- log.trace("unbind({})", address);
+ if (log.isTraceEnabled()) {
+ log.trace("unbind({})", address);
+ }
channel.close();
} catch (IOException e) {
- log.warn("Error unbinding channel for " + address, e);
+ log.warn("unbind({}) {} while unbinding channel: {}",
+ address, e.getClass().getSimpleName(), e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("unbind(" + address + ") failure details", e);
+ }
}
} else {
- log.trace("No active channel to unbind {}", address);
+ if (log.isTraceEnabled()) {
+ log.trace("No active channel to unbind {}", address);
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java
index 2a91b79..5fb773f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2ServiceFactory.java
@@ -44,7 +44,10 @@ public class Nio2ServiceFactory extends AbstractIoServiceFactory {
try {
group = AsynchronousChannelGroup.withThreadPool(ThreadUtils.protectExecutorServiceShutdown(getExecutorService(), isShutdownOnExit()));
} catch (IOException e) {
- log.warn("Failed (" + e.getClass().getSimpleName() + " to start async. channel group: " + e.getMessage(), e);
+ log.warn("Failed (" + e.getClass().getSimpleName() + " to start async. channel group: " + e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("Start async. channel group failure details", e);
+ }
throw new RuntimeSshException(e);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/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 8e4943a..1cd68e4 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
@@ -433,14 +433,19 @@ public abstract class AbstractConnectionService extends AbstractInnerCloseable i
try {
result = handler.process(this, req, wantReply, buffer);
} catch (Exception e) {
- log.warn("Error processing global request " + req, e);
+ log.warn("globalRequest({})[want-reply={}] failed ({}) to process: {}",
+ req, wantReply, e.getClass().getSimpleName(), e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("globalRequest(" + req + ")[want-reply=" + wantReply + "] failure details", e);
+ }
result = RequestHandler.Result.ReplyFailure;
}
// if Unsupported then check the next handler in line
if (RequestHandler.Result.Unsupported.equals(result)) {
if (log.isTraceEnabled()) {
- log.trace("{}#process({}): {}", handler.getClass().getSimpleName(), req, result);
+ log.trace("{}#process({})[want-reply={}] : {}",
+ handler.getClass().getSimpleName(), req, wantReply, result);
}
} else {
sendResponse(buffer, req, result, wantReply);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/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 7d90d11..d25b524 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
@@ -578,7 +578,11 @@ public abstract class AbstractSession extends AbstractKexFactoryManager implemen
return;
}
}
- log.warn("Exception caught", t);
+ log.warn("exceptionCaught({}) {}: {}", this, t.getClass().getSimpleName(), t.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("execeptionCaught(" + this + ") details", t);
+ }
+
if (t instanceof SshException) {
int code = ((SshException) t).getDisconnectCode();
if (code > 0) {
@@ -623,7 +627,10 @@ public abstract class AbstractSession extends AbstractKexFactoryManager implemen
listener.sessionClosed(this);
} catch (RuntimeException t) {
Throwable e = GenericUtils.peelException(t);
- log.warn(e.getClass().getSimpleName() + " while signal session " + toString() + " closed: " + e.getMessage(), e);
+ log.warn(e.getClass().getSimpleName() + " while signal session " + toString() + " closed: " + e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("preClose exception details", e);
+ }
} finally {
// clear the listeners since we are closing the session (quicker GC)
this.sessionListeners.clear();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java
index 45d074b..1cd47a7 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/AbstractServerChannel.java
@@ -82,6 +82,9 @@ public abstract class AbstractServerChannel extends AbstractChannel implements S
} catch (Throwable ignored) {
log.warn("doInit({}) failed ({}) to inform listener of open failure={}: {}",
this, ignored.getClass().getSimpleName(), e.getClass().getSimpleName(), ignored.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("doInit(" + this + ") listener inform failure details", ignored);
+ }
}
f.setException(e);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
index 985ac7c..e3b422e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
@@ -166,6 +166,9 @@ public class ChannelSession extends AbstractServerChannel {
} catch (Exception e) {
log.warn("doCloseImmediately({}) failed ({}) to destroy command: {}",
this, e.getClass().getSimpleName(), e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("doCloseImmediately(" + this + ") command destruction failure details", e);
+ }
} finally {
command = null;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
index a47a3e0..6519555 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
@@ -205,6 +205,9 @@ public class TcpipServerChannel extends AbstractServerChannel {
} catch (Throwable ignored) {
log.warn("handleChannelConnectResult({})[exception] failed ({}) to inform listener of open failure={}: {}",
this, ignored.getClass().getSimpleName(), e.getClass().getSimpleName(), ignored.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("handleChannelConnectResult(" + this + ")[exception] listener exception details", ignored);
+ }
}
f.setException(e);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/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 4509ae5..667db11 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
@@ -300,7 +300,9 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
}
}
- log.debug("Loaded moduli groups from {}", moduliStr);
+ if (log.isDebugEnabled()) {
+ log.debug("Loaded moduli groups from {}", moduliStr);
+ }
return groups;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java b/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
index dc0ca54..de00461 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/keyprovider/AbstractGeneratorHostKeyProvider.java
@@ -32,6 +32,7 @@ import java.security.KeyPairGenerator;
import java.security.spec.AlgorithmParameterSpec;
import java.util.Collections;
+import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.keyprovider.AbstractKeyPairProvider;
import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.common.util.io.IoUtils;
@@ -114,10 +115,11 @@ public abstract class AbstractGeneratorHostKeyProvider extends AbstractKeyPairPr
try {
keyPair = readKeyPair(keyPath, IoUtils.EMPTY_OPEN_OPTIONS);
} catch (Exception e) {
- log.warn("Failed (" + e.getClass().getSimpleName() + ")"
- + " to load from " + keyPath
- + ": " + e.getMessage(),
- e);
+ log.warn("Failed ({}) to load from {}: {}",
+ e.getClass().getSimpleName(), keyPath, e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("loadKeys(" + keyPath + ") failure details", e);
+ }
}
}
}
@@ -128,19 +130,22 @@ public abstract class AbstractGeneratorHostKeyProvider extends AbstractKeyPairPr
try {
keyPair = generateKeyPair(alg);
} catch (Exception e) {
- log.warn("Failed (" + e.getClass().getSimpleName() + ")"
- + " to generate " + alg + " keys: " + e.getMessage(),
- e);
+ log.warn("loadKeys({})[{}] Failed ({}) to generate {} key-pair: {}",
+ keyPath, alg, e.getClass().getSimpleName(), alg, e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("loadKeys(" + keyPath + ")[" + alg + "] key-pair generation failure details", e);
+ }
}
if ((keyPair != null) && (keyPath != null)) {
try {
writeKeyPair(keyPair, keyPath);
} catch (Exception e) {
- log.warn("Failed (" + e.getClass().getSimpleName() + ")"
- + " to write to " + keyPath
- + ": " + e.getMessage(),
- e);
+ log.warn("loadKeys({})[{}] Failed ({}) to write {} key: {}",
+ alg, keyPath, e.getClass().getSimpleName(), alg, e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("loadKeys(" + keyPath + ")[" + alg + "] writefailure details", e);
+ }
}
}
}
@@ -165,10 +170,15 @@ public abstract class AbstractGeneratorHostKeyProvider extends AbstractKeyPairPr
try (OutputStream os = Files.newOutputStream(keyPath, options)) {
doWriteKeyPair(keyPath.toString(), kp, os);
} catch (Exception e) {
- log.warn("Unable to write key {}: {}", path, e);
+ log.warn("writeKeyPair({}) failed ({}) to write key {}: {}",
+ keyPath, e.getClass().getSimpleName(), e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("writeKeyPair(" + keyPath + ") write failure details", e);
+ }
}
} else {
- log.error("Overwriting key ({}) is disabled: using throwaway {}", keyPath, kp);
+ log.error("Overwriting key ({}) is disabled: using throwaway {}: {}",
+ keyPath, KeyUtils.getKeyType(kp), KeyUtils.getFingerPrint((kp == null) ? null : kp.getPublic()));
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java
index 43155ff..d9bb8ad 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/InvertedShellWrapper.java
@@ -165,6 +165,9 @@ public class InvertedShellWrapper extends AbstractLoggingBean implements Command
} catch (Exception e) {
log.warn("destroy({}) failed ({}) to destroy shell: {}",
this, e.getClass().getSimpleName(), e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("destroy(" + this + ") shell destruction failure details", e);
+ }
err = GenericUtils.accumulateException(err, e);
}
@@ -174,6 +177,9 @@ public class InvertedShellWrapper extends AbstractLoggingBean implements Command
} catch (Exception e) {
log.warn("destroy({}) failed ({}) to shut down executor: {}",
this, e.getClass().getSimpleName(), e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("destroy(" + this + ") executor shutdown failure details", e);
+ }
err = GenericUtils.accumulateException(err, e);
}
}
@@ -219,7 +225,9 @@ public class InvertedShellWrapper extends AbstractLoggingBean implements Command
} catch (Exception err) {
log.warn("pumpStreams({}) failed ({}) to destroy shell: {}",
this, e.getClass().getSimpleName(), e.getMessage());
- err = GenericUtils.accumulateException(err, e);
+ if (log.isDebugEnabled()) {
+ log.debug("pumpStreams(" + this + ") shell destruction failure details", err);
+ }
}
int exitValue = shell.exitValue();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShell.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShell.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShell.java
index dbe47a7..78492b7 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShell.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/ProcessShell.java
@@ -95,7 +95,11 @@ public class ProcessShell extends AbstractLoggingBean implements InvertedShell,
Map<String, String> procEnv = builder.environment();
procEnv.putAll(varsMap);
} catch (Exception e) {
- log.warn("Could not set environment for command=" + cmdValue, e);
+ log.warn("start() - Failed ({}) to set environment for command={}: {}",
+ e.getClass().getSimpleName(), cmdValue, e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("start(" + cmdValue + ") failure details", e);
+ }
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/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 850c5fe..17e00f0 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
@@ -2785,6 +2785,10 @@ public class SftpSubsystem
}
protected Map<String, Object> handleReadFileAttributesException(Path file, String view, LinkOption[] options, IOException e) throws IOException {
+ if (log.isTraceEnabled()) {
+ log.trace("handleReadFileAttributesException(" + file + ")[" + view + "] details", e);
+ }
+
switch (unsupportedAttributePolicy) {
case Ignore:
break;
@@ -2990,6 +2994,10 @@ public class SftpSubsystem
}
protected void handleUserPrincipalLookupServiceException(Class<? extends Principal> principalType, String name, IOException e) throws IOException {
+ if (log.isTraceEnabled()) {
+ log.trace("handleUserPrincipalLookupServiceException(" + principalType.getSimpleName() + "[" + name + "]) details", e);
+ }
+
/* According to Javadoc:
*
* "Where an implementation does not support any notion of group
@@ -3080,7 +3088,11 @@ public class SftpSubsystem
SftpEventListener listener = getSftpEventListenerProxy();
listener.destroying(getServerSession());
} catch (Exception e) {
- log.warn("Failed (" + e.getClass().getSimpleName() + ") to announce destruction event: " + e.getMessage(), e);
+ log.warn("destroy({}) Failed ({}) to announce destruction event: {}",
+ getServerSession(), e.getClass().getSimpleName(), e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("destroy(" + getServerSession() + ") destruction announcement failure details", e);
+ }
}
// if thread has not completed, cancel it
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java b/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
index 1fd8194..fc34111 100644
--- a/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/client/scp/ScpTest.java
@@ -691,12 +691,14 @@ public class ScpTest extends BaseTestSupport {
Path remoteFile = remoteDir.resolve("file.txt");
String remotePath = Utils.resolveRelativeRemotePath(parentPath, remoteFile);
byte[] data = (getClass().getName() + "#" + getCurrentTestName()).getBytes(StandardCharsets.UTF_8);
+ outputDebugMessage("Upload data to %s", remotePath);
scp.upload(data, remotePath, EnumSet.allOf(PosixFilePermission.class), null);
assertFileLength(remoteFile, data.length, TimeUnit.SECONDS.toMillis(5L));
byte[] uploaded = Files.readAllBytes(remoteFile);
assertArrayEquals("Mismatched uploaded data", data, uploaded);
+ outputDebugMessage("Download data from %s", remotePath);
byte[] downloaded = scp.downloadBytes(remotePath);
assertArrayEquals("Mismatched downloaded data", uploaded, downloaded);
} finally {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/sshd-core/src/test/java/org/apache/sshd/common/channel/TestChannelListener.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/channel/TestChannelListener.java b/sshd-core/src/test/java/org/apache/sshd/common/channel/TestChannelListener.java
index 780374d..153eee9 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/channel/TestChannelListener.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/channel/TestChannelListener.java
@@ -88,6 +88,9 @@ public class TestChannelListener extends AbstractLoggingBean implements ChannelL
Assert.assertTrue("Same channel instance re-failed: " + channel, failedChannels.add(channel));
modificationsCounter.release();
log.warn("channelOpenFailure({}) {} : {}", channel, reason.getClass().getSimpleName(), reason.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("channelOpenFailure(" + channel + ") details", reason);
+ }
}
@Override
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/b07095c9/sshd-core/src/test/java/org/apache/sshd/server/subsystem/sftp/SshFsMounter.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/server/subsystem/sftp/SshFsMounter.java b/sshd-core/src/test/java/org/apache/sshd/server/subsystem/sftp/SshFsMounter.java
index 2218a7a..7195e7f 100644
--- a/sshd-core/src/test/java/org/apache/sshd/server/subsystem/sftp/SshFsMounter.java
+++ b/sshd-core/src/test/java/org/apache/sshd/server/subsystem/sftp/SshFsMounter.java
@@ -189,6 +189,9 @@ public class SshFsMounter {
log.info("destroy(" + username + ")[" + command + "] stdin closed");
} catch (IOException e) {
log.warn("destroy(" + username + ")[" + command + "] failed (" + e.getClass().getSimpleName() + ") to close stdin: " + e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("destroy(" + username + ")[" + command + "] failure details", e);
+ }
} finally {
stdin = null;
}
[04/10] mina-sshd git commit: Added more informative log messages to
some classes
Posted by lg...@apache.org.
Added more informative log messages to some classes
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/1ceea031
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/1ceea031
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/1ceea031
Branch: refs/heads/master
Commit: 1ceea031f4dce7ed0da94470da3add619168855b
Parents: e9dd7f4
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Thu Nov 26 07:20:26 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Thu Nov 26 07:20:26 2015 +0200
----------------------------------------------------------------------
.../apache/sshd/agent/SshAgentConstants.java | 26 +++++++++
.../sshd/agent/common/AbstractAgentClient.java | 60 ++++++++++----------
.../org/apache/sshd/agent/local/AgentImpl.java | 11 +++-
.../sshd/agent/unix/AgentServerProxy.java | 4 +-
.../apache/sshd/common/io/nio2/Nio2Session.java | 9 ++-
.../session/AbstractConnectionService.java | 4 +-
.../apache/sshd/server/command/ScpCommand.java | 5 +-
.../server/subsystem/sftp/SftpSubsystem.java | 4 +-
8 files changed, 85 insertions(+), 38 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1ceea031/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentConstants.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentConstants.java b/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentConstants.java
index e91554d..3587f51 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentConstants.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentConstants.java
@@ -18,6 +18,11 @@
*/
package org.apache.sshd.agent;
+import java.util.Map;
+
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.logging.LoggingUtils;
+
public final class SshAgentConstants {
public static final byte SSH_AGENT_SUCCESS = 6;
@@ -33,4 +38,25 @@ public final class SshAgentConstants {
private SshAgentConstants() {
}
+ private static class LazyMessagesMapHolder {
+ private static final Map<Integer, String> MESSAGES_MAP =
+ LoggingUtils.generateMnemonicMap(SshAgentConstants.class, "SSH2_AGENT");
+ }
+
+ /**
+ * Converts a command value to a user-friendly name
+ *
+ * @param cmd The command value
+ * @return The user-friendly name - if not one of the defined {@code SSH2_AGENT}
+ * values then returns the string representation of the command's value
+ */
+ public static String getCommandMessageName(int cmd) {
+ @SuppressWarnings("synthetic-access")
+ String name = LazyMessagesMapHolder.MESSAGES_MAP.get(cmd);
+ if (GenericUtils.isEmpty(name)) {
+ return Integer.toString(cmd);
+ } else {
+ return name;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1ceea031/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 4c10fe1..d000510 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
@@ -24,6 +24,7 @@ import java.security.PublicKey;
import java.util.List;
import org.apache.sshd.agent.SshAgent;
+import org.apache.sshd.agent.SshAgentConstants;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.util.Pair;
import org.apache.sshd.common.util.ValidateUtils;
@@ -32,16 +33,6 @@ import org.apache.sshd.common.util.buffer.BufferUtils;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENTC_ADD_IDENTITY;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENTC_REMOVE_ALL_IDENTITIES;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENTC_REMOVE_IDENTITY;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENTC_REQUEST_IDENTITIES;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENTC_SIGN_REQUEST;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENT_FAILURE;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENT_IDENTITIES_ANSWER;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENT_SIGN_RESPONSE;
-import static org.apache.sshd.agent.SshAgentConstants.SSH_AGENT_SUCCESS;
-
public abstract class AbstractAgentClient extends AbstractLoggingBean {
private final Buffer buffer = new ByteArrayBuffer();
@@ -57,7 +48,7 @@ public abstract class AbstractAgentClient extends AbstractLoggingBean {
if (avail < 4) {
if (log.isTraceEnabled()) {
log.trace("Received message total length ({}) below minuimum ({})",
- Integer.valueOf(avail), Integer.valueOf(4));
+ Integer.valueOf(avail), Integer.valueOf(4));
}
return;
}
@@ -65,12 +56,12 @@ public abstract class AbstractAgentClient extends AbstractLoggingBean {
int rpos = buffer.rpos();
int len = buffer.getInt();
buffer.rpos(rpos);
-
+
avail = buffer.available();
if (avail < (len + 4)) {
if (log.isTraceEnabled()) {
log.trace("Received request length ({}) below minuimum ({})",
- Integer.valueOf(avail), Integer.valueOf(len + 4));
+ Integer.valueOf(avail), Integer.valueOf(len + 4));
}
return;
}
@@ -79,7 +70,7 @@ public abstract class AbstractAgentClient extends AbstractLoggingBean {
Buffer rep = BufferUtils.clear(message);
rep.putInt(0);
rep.rpos(rep.wpos());
-
+
Buffer req = new ByteArrayBuffer(buffer.getBytes());
int cmd = -1;
try {
@@ -94,26 +85,29 @@ public abstract class AbstractAgentClient extends AbstractLoggingBean {
rep.putInt(0);
rep.rpos(rep.wpos());
rep.putInt(1);
- rep.putByte(SSH2_AGENT_FAILURE);
+ rep.putByte(SshAgentConstants.SSH2_AGENT_FAILURE);
}
reply(prepare(rep));
}
protected void process(int cmd, Buffer req, Buffer rep) throws Exception {
if (log.isDebugEnabled()) {
- log.debug("process(cmd={})", Integer.valueOf(cmd));
+ log.debug("process(cmd={})", SshAgentConstants.getCommandMessageName(cmd));
}
switch (cmd) {
- case SSH2_AGENTC_REQUEST_IDENTITIES:
+ case SshAgentConstants.SSH2_AGENTC_REQUEST_IDENTITIES:
+ {
List<Pair<PublicKey, String>> keys = agent.getIdentities();
- rep.putByte(SSH2_AGENT_IDENTITIES_ANSWER);
+ rep.putByte(SshAgentConstants.SSH2_AGENT_IDENTITIES_ANSWER);
rep.putInt(keys.size());
for (Pair<PublicKey, String> key : keys) {
rep.putPublicKey(key.getFirst());
rep.putString(key.getSecond());
}
break;
- case SSH2_AGENTC_SIGN_REQUEST:
+ }
+ case SshAgentConstants.SSH2_AGENTC_SIGN_REQUEST:
+ {
PublicKey signingKey = req.getPublicKey();
byte[] data = req.getBytes();
int flags = req.getInt();
@@ -125,34 +119,40 @@ public abstract class AbstractAgentClient extends AbstractLoggingBean {
KeyUtils.getKeyType(signingKey),
"Cannot resolve key type of %s",
signingKey.getClass().getSimpleName());
- Buffer sig = new ByteArrayBuffer();
+ byte[] signature = agent.sign(signingKey, data);
+ Buffer sig = new ByteArrayBuffer(keyType.length() + signature.length + Long.SIZE);
sig.putString(keyType);
- sig.putBytes(agent.sign(signingKey, data));
- rep.putByte(SSH2_AGENT_SIGN_RESPONSE);
+ sig.putBytes(signature);
+ rep.putByte(SshAgentConstants.SSH2_AGENT_SIGN_RESPONSE);
rep.putBytes(sig.array(), sig.rpos(), sig.available());
break;
- case SSH2_AGENTC_ADD_IDENTITY:
+ }
+ case SshAgentConstants.SSH2_AGENTC_ADD_IDENTITY:
+ {
KeyPair keyToAdd = req.getKeyPair();
String comment = req.getString();
log.debug("SSH2_AGENTC_ADD_IDENTITY comment={}", comment);
agent.addIdentity(keyToAdd, comment);
- rep.putByte(SSH_AGENT_SUCCESS);
+ rep.putByte(SshAgentConstants.SSH_AGENT_SUCCESS);
break;
- case SSH2_AGENTC_REMOVE_IDENTITY:
+ }
+ case SshAgentConstants.SSH2_AGENTC_REMOVE_IDENTITY:
+ {
PublicKey keyToRemove = req.getPublicKey();
log.debug("SSH2_AGENTC_REMOVE_IDENTITY {}", keyToRemove.getClass().getSimpleName());
agent.removeIdentity(keyToRemove);
- rep.putByte(SSH_AGENT_SUCCESS);
+ rep.putByte(SshAgentConstants.SSH_AGENT_SUCCESS);
break;
- case SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
+ }
+ case SshAgentConstants.SSH2_AGENTC_REMOVE_ALL_IDENTITIES:
agent.removeAllIdentities();
- rep.putByte(SSH_AGENT_SUCCESS);
+ rep.putByte(SshAgentConstants.SSH_AGENT_SUCCESS);
break;
default:
if (log.isDebugEnabled()) {
- log.debug("Unknown command: {}", Integer.valueOf(cmd));
+ log.debug("Unknown command: {}", SshAgentConstants.getCommandMessageName(cmd));
}
- rep.putByte(SSH2_AGENT_FAILURE);
+ rep.putByte(SshAgentConstants.SSH2_AGENT_FAILURE);
break;
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1ceea031/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 b99bd3a..cb562a6 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
@@ -25,6 +25,7 @@ import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.ECPublicKey;
import java.security.interfaces.RSAPublicKey;
import java.util.ArrayList;
+import java.util.Collection;
import java.util.List;
import java.util.concurrent.atomic.AtomicBoolean;
@@ -33,6 +34,7 @@ import org.apache.sshd.common.SshException;
import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.signature.BuiltinSignatures;
import org.apache.sshd.common.signature.Signature;
+import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.Pair;
import org.apache.sshd.common.util.ValidateUtils;
@@ -103,7 +105,7 @@ public class AgentImpl implements SshAgent {
if (!isOpen()) {
throw new SshException("Agent closed");
}
- keys.add(new Pair<>(key, comment));
+ keys.add(new Pair<>(ValidateUtils.checkNotNull(key, "No key"), comment));
}
@Override
@@ -111,6 +113,7 @@ public class AgentImpl implements SshAgent {
if (!isOpen()) {
throw new SshException("Agent closed");
}
+
Pair<KeyPair, String> kp = getKeyPair(keys, key);
if (kp == null) {
throw new SshException("Key not found");
@@ -133,7 +136,11 @@ public class AgentImpl implements SshAgent {
}
}
- protected static Pair<KeyPair, String> getKeyPair(List<Pair<KeyPair, String>> keys, PublicKey key) {
+ protected static Pair<KeyPair, String> getKeyPair(Collection<Pair<KeyPair, String>> keys, PublicKey key) {
+ if (GenericUtils.isEmpty(keys) || (key == null)) {
+ return null;
+ }
+
for (Pair<KeyPair, String> k : keys) {
KeyPair kp = k.getFirst();
if (KeyUtils.compareKeys(key, kp.getPublic())) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1ceea031/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
index 05e9ccf..5c1e9af 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/unix/AgentServerProxy.java
@@ -111,7 +111,9 @@ public class AgentServerProxy extends AbstractLoggingBean implements SshAgentSer
channel.open().verify(PropertyResolverUtils.getLongProperty(session, CHANNEL_OPEN_TIMEOUT_PROP, DEFAULT_CHANNEL_OPEN_TIMEOUT));
} catch (Exception e) {
if (isOpen()) {
- log.info(e.getClass().getSimpleName() + " while authentication forwarding: " + e.getMessage(), e);
+ if (log.isDebugEnabled()) {
+ log.debug(e.getClass().getSimpleName() + " while authentication forwarding: " + e.getMessage(), e);
+ }
}
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1ceea031/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
index d37403d..5629d63 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/io/nio2/Nio2Session.java
@@ -133,10 +133,15 @@ public class Nio2Session extends AbstractCloseable implements IoSession {
close(true);
} else {
try {
- log.debug("Caught exception, now calling handler");
+ if (log.isDebugEnabled()) {
+ log.debug("Caught {}[{}] - calling handler", exc.getClass().getSimpleName(), exc.getMessage());
+ }
handler.exceptionCaught(this, exc);
} catch (Throwable t) {
- log.info("Exception handler threw exception, closing the session", t);
+ if (log.isDebugEnabled()) {
+ log.debug("Exception handler threw {}, closing the session: {}",
+ t.getClass().getSimpleName(), t.getMessage());
+ }
close(true);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1ceea031/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 1e51b6f..8e4943a 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
@@ -271,7 +271,9 @@ public abstract class AbstractConnectionService extends AbstractInnerCloseable i
Channel channel = getChannel(buffer);
channel.handleWindowAdjust(buffer);
} catch (SshException e) {
- log.info("channelWindowAdjust error: {}", e.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug("channelWindowAdjust {} error: {}", e.getClass().getSimpleName(), e.getMessage());
+ }
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1ceea031/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java b/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java
index 424de53..549a767 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/command/ScpCommand.java
@@ -245,7 +245,10 @@ public class ScpCommand extends AbstractLoggingBean implements Command, Runnable
} catch (IOException e2) {
// Ignore
}
- log.info("Error in scp command=" + name, e);
+
+ if (log.isDebugEnabled()) {
+ log.debug("Error ({}) in scp command={}: {}", e.getClass().getSimpleName(), name, e.getMessage());
+ }
} finally {
if (callback != null) {
callback.onExit(exitValue, GenericUtils.trimToEmpty(exitMessage));
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/1ceea031/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 6c739d2..5aa6d5f 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
@@ -562,7 +562,9 @@ public class SftpSubsystem
doSpaceAvailable(buffer, id);
break;
default:
- log.info("executeExtendedCommand({}) received unsupported SSH_FXP_EXTENDED({})", getServerSession(), extension);
+ if (log.isDebugEnabled()) {
+ log.debug("executeExtendedCommand({}) received unsupported SSH_FXP_EXTENDED({})", getServerSession(), extension);
+ }
sendStatus(BufferUtils.clear(buffer), id, SftpConstants.SSH_FX_OP_UNSUPPORTED, "Command SSH_FXP_EXTENDED(" + extension + ") is unsupported or not implemented");
break;
}
[02/10] mina-sshd git commit: [SSHD-599] Allow per-session override
of KEX and authentication related configuration
Posted by lg...@apache.org.
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 8ea0788..0e2fe5c 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
@@ -23,7 +23,7 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
-import org.apache.sshd.client.ClientFactoryManager;
+import org.apache.sshd.client.ClientAuthenticationManager;
import org.apache.sshd.client.auth.UserAuth;
import org.apache.sshd.client.auth.UserInteraction;
import org.apache.sshd.client.future.AuthFuture;
@@ -70,18 +70,19 @@ public class ClientUserAuthService extends AbstractCloseable implements Service,
}
session = (ClientSessionImpl) s;
authFuture = new DefaultAuthFuture(session.getLock());
- ClientFactoryManager manager = session.getFactoryManager();
- authFactories = manager.getUserAuthFactories();
+ authFactories = session.getUserAuthFactories();
clientMethods = new ArrayList<>();
- String prefs = PropertyResolverUtils.getString(session, ClientFactoryManager.PREFERRED_AUTHS);
+ String prefs = PropertyResolverUtils.getString(session, ClientAuthenticationManager.PREFERRED_AUTHS);
if (!GenericUtils.isEmpty(prefs)) {
for (String pref : prefs.split(",")) {
NamedFactory<UserAuth> factory = NamedResource.Utils.findByName(pref, String.CASE_INSENSITIVE_ORDER, authFactories);
if (factory != null) {
clientMethods.add(pref);
} else {
- log.debug("Skip unknown prefered authentication method: {}", pref);
+ if (log.isDebugEnabled()) {
+ log.debug("ClientUserAuthService({}) skip unknown prefered authentication method: {}", s, pref);
+ }
}
}
} else {
@@ -107,11 +108,12 @@ public class ClientUserAuthService extends AbstractCloseable implements Service,
}
public AuthFuture auth(List<Object> identities, String service) throws IOException {
- log.debug("Start authentication");
this.identities = new ArrayList<>(identities);
this.service = service;
- log.debug("Send SSH_MSG_USERAUTH_REQUEST for none");
+ if (log.isDebugEnabled()) {
+ log.debug("auth({})[{}] Send SSH_MSG_USERAUTH_REQUEST for 'none'", getClientSession(), service);
+ }
String username = session.getUsername();
Buffer buffer = session.createBuffer(SshConstants.SSH_MSG_USERAUTH_REQUEST, username.length() + service.length() + Integer.SIZE);
buffer.putString(session.getUsername());
@@ -128,16 +130,19 @@ public class ClientUserAuthService extends AbstractCloseable implements Service,
throw new IllegalStateException("UserAuth message delivered to authenticated client");
} else if (this.authFuture.isDone()) {
if (log.isDebugEnabled()) {
- log.debug("Ignoring random message - cmd={}", cmd);
+ log.debug("process({}) Ignoring random message - cmd={}",
+ session, SshConstants.getCommandMessageName(cmd));
}
// ignore for now; TODO: random packets
} else if (cmd == SshConstants.SSH_MSG_USERAUTH_BANNER) {
String welcome = buffer.getString();
String lang = buffer.getString();
- log.debug("Welcome banner(lang={}): {}", lang, welcome);
+ if (log.isDebugEnabled()) {
+ log.debug("process({}) Welcome banner(lang={}): {}", session, lang, welcome);
+ }
- UserInteraction ui = UserInteraction.Utils.resolveUserInteraction(session);
- if (ui != null) {
+ UserInteraction ui = session.getUserInteraction();
+ if ((ui != null) && ui.isInteractionAllowed(session)) {
ui.welcome(session, welcome, lang);
}
} else {
@@ -147,15 +152,18 @@ public class ClientUserAuthService extends AbstractCloseable implements Service,
}
/**
- * execute one step in user authentication.
+ * Execute one step in user authentication.
*
- * @param buffer
- * @throws java.io.IOException
+ * @param buffer The input {@link Buffer}
+ * @throws Exception If failed to process
*/
- private void processUserAuth(Buffer buffer) throws Exception {
+ protected void processUserAuth(Buffer buffer) throws Exception {
int cmd = buffer.getUByte();
if (cmd == SshConstants.SSH_MSG_USERAUTH_SUCCESS) {
- log.debug("SSH_MSG_USERAUTH_SUCCESS Succeeded with {}", userAuth);
+ if (log.isDebugEnabled()) {
+ log.debug("processUserAuth({}) SSH_MSG_USERAUTH_SUCCESS Succeeded with {}",
+ getClientSession(), userAuth);
+ }
if (userAuth != null) {
userAuth.destroy();
userAuth = null;
@@ -170,7 +178,8 @@ public class ClientUserAuthService extends AbstractCloseable implements Service,
String mths = buffer.getString();
boolean partial = buffer.getBoolean();
if (log.isDebugEnabled()) {
- log.debug("Received SSH_MSG_USERAUTH_FAILURE - partial={}, methods={}", partial, mths);
+ log.debug("processUserAuth({}) Received SSH_MSG_USERAUTH_FAILURE - partial={}, methods={}",
+ getClientSession(), partial, mths);
}
if (partial || (serverMethods == null)) {
serverMethods = Arrays.asList(GenericUtils.split(mths, ','));
@@ -191,7 +200,7 @@ public class ClientUserAuthService extends AbstractCloseable implements Service,
}
}
- private void tryNext() throws Exception {
+ protected void tryNext() throws Exception {
// Loop until we find something to try
while (true) {
if (userAuth == null) {
@@ -202,19 +211,29 @@ public class ClientUserAuthService extends AbstractCloseable implements Service,
} else {
return;
}
+
while (currentMethod < clientMethods.size() && !serverMethods.contains(clientMethods.get(currentMethod))) {
currentMethod++;
}
+
if (currentMethod >= clientMethods.size()) {
- // Failure
+ if (log.isDebugEnabled()) {
+ log.debug("tryNext({}) exhausted all methods", getClientSession());
+ }
+
authFuture.setAuthed(false);
return;
}
+
String method = clientMethods.get(currentMethod);
userAuth = NamedFactory.Utils.create(authFactories, method);
if (userAuth == null) {
throw new UnsupportedOperationException("Failed to find a user-auth factory for method=" + method);
}
+ if (log.isDebugEnabled()) {
+ log.debug("tryNext({}) attempting method={}", getClientSession(), method);
+ }
+
userAuth.init(session, service, identities);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java
index 3cd9a19..ffb3883 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/AbstractFactoryManager.java
@@ -31,27 +31,20 @@ import org.apache.sshd.agent.SshAgentFactory;
import org.apache.sshd.common.channel.Channel;
import org.apache.sshd.common.channel.ChannelListener;
import org.apache.sshd.common.channel.RequestHandler;
-import org.apache.sshd.common.cipher.Cipher;
-import org.apache.sshd.common.compression.Compression;
import org.apache.sshd.common.config.VersionProperties;
import org.apache.sshd.common.file.FileSystemFactory;
import org.apache.sshd.common.forward.TcpipForwarderFactory;
import org.apache.sshd.common.io.DefaultIoServiceFactoryFactory;
import org.apache.sshd.common.io.IoServiceFactory;
import org.apache.sshd.common.io.IoServiceFactoryFactory;
-import org.apache.sshd.common.kex.KeyExchange;
-import org.apache.sshd.common.keyprovider.KeyPairProvider;
-import org.apache.sshd.common.keyprovider.KeyPairProviderHolder;
-import org.apache.sshd.common.mac.Mac;
+import org.apache.sshd.common.kex.AbstractKexFactoryManager;
import org.apache.sshd.common.random.Random;
import org.apache.sshd.common.session.AbstractSessionFactory;
import org.apache.sshd.common.session.ConnectionService;
import org.apache.sshd.common.session.SessionListener;
import org.apache.sshd.common.session.SessionTimeoutListener;
-import org.apache.sshd.common.signature.Signature;
import org.apache.sshd.common.util.EventListenerUtils;
import org.apache.sshd.common.util.ValidateUtils;
-import org.apache.sshd.common.util.closeable.AbstractInnerCloseable;
import org.apache.sshd.common.util.threads.ThreadUtils;
import org.apache.sshd.server.forward.ForwardingFilter;
@@ -60,17 +53,10 @@ import org.apache.sshd.server.forward.ForwardingFilter;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public abstract class AbstractFactoryManager
- extends AbstractInnerCloseable
- implements FactoryManager, KeyPairProviderHolder {
+public abstract class AbstractFactoryManager extends AbstractKexFactoryManager implements FactoryManager {
protected IoServiceFactoryFactory ioServiceFactoryFactory;
protected IoServiceFactory ioServiceFactory;
- protected List<NamedFactory<KeyExchange>> keyExchangeFactories;
- protected List<NamedFactory<Cipher>> cipherFactories;
- protected List<NamedFactory<Compression>> compressionFactories;
- protected List<NamedFactory<Mac>> macFactories;
- protected List<NamedFactory<Signature>> signatureFactories;
protected Factory<Random> randomFactory;
protected List<NamedFactory<Channel>> channelFactories;
protected SshAgentFactory agentFactory;
@@ -89,7 +75,6 @@ public abstract class AbstractFactoryManager
protected final ChannelListener channelListenerProxy;
private final Map<String, Object> properties = new ConcurrentHashMap<>();
- private KeyPairProvider keyPairProvider;
protected AbstractFactoryManager() {
ClassLoader loader = getClass().getClassLoader();
@@ -116,51 +101,6 @@ public abstract class AbstractFactoryManager
}
@Override
- public List<NamedFactory<KeyExchange>> getKeyExchangeFactories() {
- return keyExchangeFactories;
- }
-
- public void setKeyExchangeFactories(List<NamedFactory<KeyExchange>> keyExchangeFactories) {
- this.keyExchangeFactories = keyExchangeFactories;
- }
-
- @Override
- public List<NamedFactory<Cipher>> getCipherFactories() {
- return cipherFactories;
- }
-
- public void setCipherFactories(List<NamedFactory<Cipher>> cipherFactories) {
- this.cipherFactories = cipherFactories;
- }
-
- @Override
- public List<NamedFactory<Compression>> getCompressionFactories() {
- return compressionFactories;
- }
-
- public void setCompressionFactories(List<NamedFactory<Compression>> compressionFactories) {
- this.compressionFactories = compressionFactories;
- }
-
- @Override
- public List<NamedFactory<Mac>> getMacFactories() {
- return macFactories;
- }
-
- public void setMacFactories(List<NamedFactory<Mac>> macFactories) {
- this.macFactories = macFactories;
- }
-
- @Override
- public List<NamedFactory<Signature>> getSignatureFactories() {
- return signatureFactories;
- }
-
- public void setSignatureFactories(List<NamedFactory<Signature>> signatureFactories) {
- this.signatureFactories = signatureFactories;
- }
-
- @Override
public Factory<Random> getRandomFactory() {
return randomFactory;
}
@@ -170,15 +110,6 @@ public abstract class AbstractFactoryManager
}
@Override
- public KeyPairProvider getKeyPairProvider() {
- return keyPairProvider;
- }
-
- public void setKeyPairProvider(KeyPairProvider keyPairProvider) {
- this.keyPairProvider = keyPairProvider;
- }
-
- @Override
public Map<String, Object> getProperties() {
return properties;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
index 14f688c..0e2ff1f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/FactoryManager.java
@@ -26,17 +26,13 @@ import org.apache.sshd.agent.SshAgentFactory;
import org.apache.sshd.common.channel.Channel;
import org.apache.sshd.common.channel.ChannelListenerManager;
import org.apache.sshd.common.channel.RequestHandler;
-import org.apache.sshd.common.cipher.Cipher;
-import org.apache.sshd.common.compression.Compression;
import org.apache.sshd.common.file.FileSystemFactory;
import org.apache.sshd.common.forward.TcpipForwarderFactory;
import org.apache.sshd.common.io.IoServiceFactory;
-import org.apache.sshd.common.kex.KeyExchange;
-import org.apache.sshd.common.mac.Mac;
+import org.apache.sshd.common.kex.KexFactoryManager;
import org.apache.sshd.common.random.Random;
import org.apache.sshd.common.session.ConnectionService;
import org.apache.sshd.common.session.SessionListenerManager;
-import org.apache.sshd.common.signature.Signature;
import org.apache.sshd.server.forward.ForwardingFilter;
/**
@@ -45,7 +41,7 @@ import org.apache.sshd.server.forward.ForwardingFilter;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface FactoryManager extends SessionListenerManager, ChannelListenerManager, PropertyResolver {
+public interface FactoryManager extends KexFactoryManager, SessionListenerManager, ChannelListenerManager, PropertyResolver {
/**
* Key used to retrieve the value of the channel window size in the
@@ -213,41 +209,6 @@ public interface FactoryManager extends SessionListenerManager, ChannelListenerM
IoServiceFactory getIoServiceFactory();
/**
- * Retrieve the list of named factories for <code>KeyExchange</code>.
- *
- * @return a list of named <code>KeyExchange</code> factories, never {@code null}
- */
- List<NamedFactory<KeyExchange>> getKeyExchangeFactories();
-
- /**
- * Retrieve the list of named factories for <code>Cipher</code>.
- *
- * @return a list of named <code>Cipher</code> factories, never {@code null}
- */
- List<NamedFactory<Cipher>> getCipherFactories();
-
- /**
- * Retrieve the list of named factories for <code>Compression</code>.
- *
- * @return a list of named <code>Compression</code> factories, never {@code null}
- */
- List<NamedFactory<Compression>> getCompressionFactories();
-
- /**
- * Retrieve the list of named factories for <code>Mac</code>.
- *
- * @return a list of named <code>Mac</code> factories, never {@code null}
- */
- List<NamedFactory<Mac>> getMacFactories();
-
- /**
- * Retrieve the list of named factories for <code>Signature</code>.
- *
- * @return a list of named <code>Signature</code> factories, never {@code null}
- */
- List<NamedFactory<Signature>> getSignatureFactories();
-
- /**
* Retrieve the <code>Random</code> factory to be used.
*
* @return the <code>Random</code> factory, never {@code null}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/common/auth/AbstractUserAuthMethodFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/auth/AbstractUserAuthMethodFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/auth/AbstractUserAuthMethodFactory.java
index cb9cefe..73e8015 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/auth/AbstractUserAuthMethodFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/auth/AbstractUserAuthMethodFactory.java
@@ -37,4 +37,9 @@ public abstract class AbstractUserAuthMethodFactory<M> extends AbstractLoggingBe
public final String getName() {
return name;
}
+
+ @Override
+ public String toString() {
+ return getClass().getSimpleName() + "[" + getName() + "]";
+ }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractKexFactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractKexFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractKexFactoryManager.java
new file mode 100644
index 0000000..e86e579
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractKexFactoryManager.java
@@ -0,0 +1,137 @@
+/*
+ * 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.kex;
+
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.cipher.Cipher;
+import org.apache.sshd.common.compression.Compression;
+import org.apache.sshd.common.keyprovider.KeyPairProvider;
+import org.apache.sshd.common.mac.Mac;
+import org.apache.sshd.common.signature.Signature;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.closeable.AbstractInnerCloseable;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractKexFactoryManager
+ extends AbstractInnerCloseable
+ implements KexFactoryManager {
+ private KexFactoryManager parent;
+ private List<NamedFactory<KeyExchange>> keyExchangeFactories;
+ private List<NamedFactory<Cipher>> cipherFactories;
+ private List<NamedFactory<Compression>> compressionFactories;
+ private List<NamedFactory<Mac>> macFactories;
+ private List<NamedFactory<Signature>> signatureFactories;
+ private KeyPairProvider keyPairProvider;
+
+ protected AbstractKexFactoryManager() {
+ this(null);
+ }
+
+ protected AbstractKexFactoryManager(KexFactoryManager parent) {
+ this.parent = parent;
+ }
+
+ @Override
+ public List<NamedFactory<KeyExchange>> getKeyExchangeFactories() {
+ return resolveEffectiveFactories(KeyExchange.class, keyExchangeFactories,
+ (parent == null) ? Collections.<NamedFactory<KeyExchange>>emptyList() : parent.getKeyExchangeFactories());
+ }
+
+ @Override
+ public void setKeyExchangeFactories(List<NamedFactory<KeyExchange>> keyExchangeFactories) {
+ this.keyExchangeFactories = keyExchangeFactories;
+ }
+
+ @Override
+ public List<NamedFactory<Cipher>> getCipherFactories() {
+ return resolveEffectiveFactories(Cipher.class, cipherFactories,
+ (parent == null) ? Collections.<NamedFactory<Cipher>>emptyList() : parent.getCipherFactories());
+ }
+
+ @Override
+ public void setCipherFactories(List<NamedFactory<Cipher>> cipherFactories) {
+ this.cipherFactories = cipherFactories;
+ }
+
+ @Override
+ public List<NamedFactory<Compression>> getCompressionFactories() {
+ return resolveEffectiveFactories(Compression.class, compressionFactories,
+ (parent == null) ? Collections.<NamedFactory<Compression>>emptyList() : parent.getCompressionFactories());
+ }
+
+ @Override
+ public void setCompressionFactories(List<NamedFactory<Compression>> compressionFactories) {
+ this.compressionFactories = compressionFactories;
+ }
+
+ @Override
+ public List<NamedFactory<Mac>> getMacFactories() {
+ return resolveEffectiveFactories(Mac.class, macFactories,
+ (parent == null) ? Collections.<NamedFactory<Mac>>emptyList() : parent.getMacFactories());
+ }
+
+ @Override
+ public void setMacFactories(List<NamedFactory<Mac>> macFactories) {
+ this.macFactories = macFactories;
+ }
+
+ @Override
+ public List<NamedFactory<Signature>> getSignatureFactories() {
+ return resolveEffectiveFactories(Signature.class, signatureFactories,
+ (parent == null) ? Collections.<NamedFactory<Signature>>emptyList() : parent.getSignatureFactories());
+ }
+
+ @Override
+ public void setSignatureFactories(List<NamedFactory<Signature>> signatureFactories) {
+ this.signatureFactories = signatureFactories;
+ }
+
+ @Override
+ public KeyPairProvider getKeyPairProvider() {
+ return resolveEffectiveProvider(KeyPairProvider.class, keyPairProvider,
+ (parent == null) ? null : parent.getKeyPairProvider());
+ }
+
+ @Override
+ public void setKeyPairProvider(KeyPairProvider keyPairProvider) {
+ this.keyPairProvider = keyPairProvider;
+ }
+
+ protected <V> List<NamedFactory<V>> resolveEffectiveFactories(Class<V> factoryType, List<NamedFactory<V>> local, List<NamedFactory<V>> inherited) {
+ if (GenericUtils.isEmpty(local)) {
+ return inherited;
+ } else {
+ return local;
+ }
+ }
+
+ protected <V> V resolveEffectiveProvider(Class<V> providerType, V local, V inherited) {
+ if (local == null) {
+ return inherited;
+ } else {
+ return local;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/common/kex/KexFactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/KexFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/KexFactoryManager.java
new file mode 100644
index 0000000..60dcf57
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/KexFactoryManager.java
@@ -0,0 +1,75 @@
+/*
+ * 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.kex;
+
+import java.util.List;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.cipher.Cipher;
+import org.apache.sshd.common.compression.Compression;
+import org.apache.sshd.common.keyprovider.KeyPairProviderHolder;
+import org.apache.sshd.common.mac.Mac;
+import org.apache.sshd.common.signature.Signature;
+
+/**
+ * Holds KEX negotiation stage configuration
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface KexFactoryManager extends KeyPairProviderHolder {
+ /**
+ * Retrieve the list of named factories for <code>KeyExchange</code>.
+ *
+ * @return a list of named <code>KeyExchange</code> factories, never {@code null}
+ */
+ List<NamedFactory<KeyExchange>> getKeyExchangeFactories();
+ void setKeyExchangeFactories(List<NamedFactory<KeyExchange>> keyExchangeFactories);
+
+ /**
+ * Retrieve the list of named factories for <code>Cipher</code>.
+ *
+ * @return a list of named <code>Cipher</code> factories, never {@code null}
+ */
+ List<NamedFactory<Cipher>> getCipherFactories();
+ void setCipherFactories(List<NamedFactory<Cipher>> cipherFactories);
+
+ /**
+ * Retrieve the list of named factories for <code>Compression</code>.
+ *
+ * @return a list of named <code>Compression</code> factories, never {@code null}
+ */
+ List<NamedFactory<Compression>> getCompressionFactories();
+ void setCompressionFactories(List<NamedFactory<Compression>> compressionFactories);
+
+ /**
+ * Retrieve the list of named factories for <code>Mac</code>.
+ *
+ * @return a list of named <code>Mac</code> factories, never {@code null}
+ */
+ List<NamedFactory<Mac>> getMacFactories();
+ void setMacFactories(List<NamedFactory<Mac>> macFactories);
+
+ /**
+ * Retrieve the list of named factories for <code>Signature</code>.
+ *
+ * @return a list of named <code>Signature</code> factories, never {@code null}
+ */
+ List<NamedFactory<Signature>> getSignatureFactories();
+ void setSignatureFactories(List<NamedFactory<Signature>> signatureFactories);
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProviderHolder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProviderHolder.java b/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProviderHolder.java
index fbd5d22..b5826f6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProviderHolder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/keyprovider/KeyPairProviderHolder.java
@@ -30,4 +30,5 @@ public interface KeyPairProviderHolder {
* @return the <code>KeyPairProvider</code>, never {@code null}
*/
KeyPairProvider getKeyPairProvider();
+ void setKeyPairProvider(KeyPairProvider keyPairProvider);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 e092a32..ad1e74b 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
@@ -54,6 +54,7 @@ import org.apache.sshd.common.future.KeyExchangeFuture;
import org.apache.sshd.common.future.SshFutureListener;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.IoWriteFuture;
+import org.apache.sshd.common.kex.AbstractKexFactoryManager;
import org.apache.sshd.common.kex.KexProposalOption;
import org.apache.sshd.common.kex.KexState;
import org.apache.sshd.common.kex.KeyExchange;
@@ -67,7 +68,6 @@ 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.closeable.AbstractInnerCloseable;
/**
* <P>
@@ -84,7 +84,7 @@ import org.apache.sshd.common.util.closeable.AbstractInnerCloseable;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public abstract class AbstractSession extends AbstractInnerCloseable implements Session {
+public abstract class AbstractSession extends AbstractKexFactoryManager implements Session {
/**
* Name of the property where this session is stored in the attributes of the
* underlying MINA session. See {@link #getSession(IoSession, boolean)}
@@ -196,15 +196,19 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
* @param ioSession the underlying MINA session
*/
protected AbstractSession(boolean isServer, FactoryManager factoryManager, IoSession ioSession) {
+ super(ValidateUtils.checkNotNull(factoryManager, "No factory manager provided"));
this.isServer = isServer;
- this.factoryManager = ValidateUtils.checkNotNull(factoryManager, "No factory manager provided", GenericUtils.EMPTY_OBJECT_ARRAY);
+ this.factoryManager = factoryManager;
this.ioSession = ioSession;
ClassLoader loader = getClass().getClassLoader();
sessionListenerProxy = EventListenerUtils.proxyWrapper(SessionListener.class, loader, sessionListeners);
channelListenerProxy = EventListenerUtils.proxyWrapper(ChannelListener.class, loader, channelListeners);
-
random = ValidateUtils.checkNotNull(factoryManager.getRandomFactory(), "No random factory").create();
+
+ // Delegate the task of further notifications to the session
+ addSessionListener(factoryManager.getSessionListenerProxy());
+ addChannelListener(factoryManager.getChannelListenerProxy());
}
/**
@@ -507,7 +511,7 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
Map<KexProposalOption, String> result = negotiate();
String kexAlgorithm = result.get(KexProposalOption.ALGORITHMS);
- kex = ValidateUtils.checkNotNull(NamedFactory.Utils.create(factoryManager.getKeyExchangeFactories(), kexAlgorithm),
+ kex = ValidateUtils.checkNotNull(NamedFactory.Utils.create(getKeyExchangeFactories(), kexAlgorithm),
"Unknown negotiated KEX algorithm: %s",
kexAlgorithm);
kex.init(this, serverVersion.getBytes(StandardCharsets.UTF_8), clientVersion.getBytes(StandardCharsets.UTF_8), i_s, i_c);
@@ -689,7 +693,9 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
@Override
public void run() {
Throwable t = new TimeoutException("Timeout writing packet: " + timeout + " " + unit);
- log.info(t.getMessage());
+ if (log.isDebugEnabled()) {
+ log.debug(t.getMessage());
+ }
future.setValue(t);
}
}, timeout, unit);
@@ -787,7 +793,7 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
if (buffer.rpos() < 5) {
log.warn("Performance cost: when sending a packet, ensure that "
+ "5 bytes are available in front of the buffer");
- Buffer nb = new ByteArrayBuffer();
+ Buffer nb = new ByteArrayBuffer(buffer.available() + Long.SIZE);
nb.wpos(5);
nb.putBuffer(buffer);
buffer = nb;
@@ -800,7 +806,7 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
log.trace("Sending packet #{}: {}", Long.valueOf(seqo), buffer.printHex());
}
// Compress the packet if needed
- if (outCompression != null && (authed || !outCompression.isDelayed())) {
+ if ((outCompression != null) && (authed || !outCompression.isDelayed())) {
outCompression.compress(buffer);
len = buffer.available();
}
@@ -1026,18 +1032,23 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
*/
protected Map<KexProposalOption, String> createProposal(String hostKeyTypes) {
Map<KexProposalOption, String> proposal = new EnumMap<>(KexProposalOption.class);
- proposal.put(KexProposalOption.ALGORITHMS, NamedResource.Utils.getNames(factoryManager.getKeyExchangeFactories()));
+ proposal.put(KexProposalOption.ALGORITHMS,
+ NamedResource.Utils.getNames(
+ ValidateUtils.checkNotNullAndNotEmpty(getKeyExchangeFactories(), "No KEX factories")));
proposal.put(KexProposalOption.SERVERKEYS, hostKeyTypes);
- String ciphers = NamedResource.Utils.getNames(factoryManager.getCipherFactories());
+ String ciphers = NamedResource.Utils.getNames(
+ ValidateUtils.checkNotNullAndNotEmpty(getCipherFactories(), "No cipher factories"));
proposal.put(KexProposalOption.S2CENC, ciphers);
proposal.put(KexProposalOption.C2SENC, ciphers);
- String macs = NamedResource.Utils.getNames(factoryManager.getMacFactories());
+ String macs = NamedResource.Utils.getNames(
+ ValidateUtils.checkNotNullAndNotEmpty(getMacFactories(), "No MAC factories"));
proposal.put(KexProposalOption.S2CMAC, macs);
proposal.put(KexProposalOption.C2SMAC, macs);
- String compressions = NamedResource.Utils.getNames(factoryManager.getCompressionFactories());
+ String compressions = NamedResource.Utils.getNames(
+ ValidateUtils.checkNotNullAndNotEmpty(getCompressionFactories(), "No compression factories"));
proposal.put(KexProposalOption.S2CCOMP, compressions);
proposal.put(KexProposalOption.C2SCOMP, compressions);
@@ -1209,30 +1220,30 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
String value;
value = getNegotiatedKexParameter(KexProposalOption.S2CENC);
- s2ccipher = ValidateUtils.checkNotNull(NamedFactory.Utils.create(factoryManager.getCipherFactories(), value), "Unknown s2c cipher: %s", value);
+ s2ccipher = ValidateUtils.checkNotNull(NamedFactory.Utils.create(getCipherFactories(), value), "Unknown s2c cipher: %s", value);
e_s2c = resizeKey(e_s2c, s2ccipher.getBlockSize(), hash, k, h);
s2ccipher.init(isServer ? Cipher.Mode.Encrypt : Cipher.Mode.Decrypt, e_s2c, iv_s2c);
value = getNegotiatedKexParameter(KexProposalOption.S2CMAC);
- s2cmac = ValidateUtils.checkNotNull(NamedFactory.Utils.create(factoryManager.getMacFactories(), value), "Unknown s2c mac: %s", value);
+ s2cmac = ValidateUtils.checkNotNull(NamedFactory.Utils.create(getMacFactories(), value), "Unknown s2c mac: %s", value);
mac_s2c = resizeKey(mac_s2c, s2cmac.getBlockSize(), hash, k, h);
s2cmac.init(mac_s2c);
value = getNegotiatedKexParameter(KexProposalOption.S2CCOMP);
- s2ccomp = NamedFactory.Utils.create(factoryManager.getCompressionFactories(), value);
+ s2ccomp = NamedFactory.Utils.create(getCompressionFactories(), value);
value = getNegotiatedKexParameter(KexProposalOption.C2SENC);
- c2scipher = ValidateUtils.checkNotNull(NamedFactory.Utils.create(factoryManager.getCipherFactories(), value), "Unknown c2s cipher: %s", value);
+ c2scipher = ValidateUtils.checkNotNull(NamedFactory.Utils.create(getCipherFactories(), value), "Unknown c2s cipher: %s", value);
e_c2s = resizeKey(e_c2s, c2scipher.getBlockSize(), hash, k, h);
c2scipher.init(isServer ? Cipher.Mode.Decrypt : Cipher.Mode.Encrypt, e_c2s, iv_c2s);
value = getNegotiatedKexParameter(KexProposalOption.C2SMAC);
- c2smac = ValidateUtils.checkNotNull(NamedFactory.Utils.create(factoryManager.getMacFactories(), value), "Unknown c2s mac: %s", value);
+ c2smac = ValidateUtils.checkNotNull(NamedFactory.Utils.create(getMacFactories(), value), "Unknown c2s mac: %s", value);
mac_c2s = resizeKey(mac_c2s, c2smac.getBlockSize(), hash, k, h);
c2smac.init(mac_c2s);
value = getNegotiatedKexParameter(KexProposalOption.C2SCOMP);
- c2scomp = NamedFactory.Utils.create(factoryManager.getCompressionFactories(), value);
+ c2scomp = NamedFactory.Utils.create(getCompressionFactories(), value);
if (isServer) {
outCipher = s2ccipher;
@@ -1521,7 +1532,7 @@ public abstract class AbstractSession extends AbstractInnerCloseable implements
@Override
public KeyExchangeFuture reExchangeKeys() throws IOException {
if (kexState.compareAndSet(KexState.DONE, KexState.INIT)) {
- log.info("Initiating key re-exchange");
+ log.info("reExchangeKeys({}) Initiating key re-exchange", this);
sendKexInit();
DefaultKeyExchangeFuture kexFuture = kexFutureHolder.getAndSet(new DefaultKeyExchangeFuture(null));
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionFactory.java
index c4afdfd..5dc01d8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/AbstractSessionFactory.java
@@ -48,13 +48,6 @@ public abstract class AbstractSessionFactory<M extends FactoryManager, S extends
protected abstract S doCreateSession(IoSession ioSession) throws Exception;
protected S setupSession(S session) throws Exception {
- FactoryManager listenersManager = getFactoryManager();
- SessionListener sessionListener = listenersManager.getSessionListenerProxy();
- // Inform the listener of the newly created session
- sessionListener.sessionCreated(session);
- // Delegate the task of further notifications to the session
- session.addSessionListener(sessionListener);
- session.addChannelListener(listenersManager.getChannelListenerProxy());
return session;
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
index f16949a..0ac2705 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
@@ -30,6 +30,7 @@ import org.apache.sshd.common.channel.ChannelListenerManager;
import org.apache.sshd.common.future.KeyExchangeFuture;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.IoWriteFuture;
+import org.apache.sshd.common.kex.KexFactoryManager;
import org.apache.sshd.common.kex.KexProposalOption;
import org.apache.sshd.common.kex.KeyExchange;
import org.apache.sshd.common.util.buffer.Buffer;
@@ -41,7 +42,8 @@ import org.apache.sshd.common.util.buffer.Buffer;
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public interface Session
- extends SessionListenerManager,
+ extends KexFactoryManager,
+ SessionListenerManager,
ChannelListenerManager,
PropertyResolver,
Closeable,
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
index db8a930..39c08d2 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/GenericUtils.java
@@ -565,4 +565,24 @@ public final class GenericUtils {
current.addSuppressed(extra);
return current;
}
+
+ /**
+ * Wraps a value into a {@link Supplier}
+ * @param <T> Type of value being supplied
+ * @param value The value to be supplied
+ * @return The supplier wrapper
+ */
+ public static <T> Supplier<T> supplierOf(final T value) {
+ return new Supplier<T>() {
+ @Override
+ public T get() {
+ return value;
+ }
+
+ @Override
+ public String toString() {
+ return Supplier.class.getSimpleName() + "[" + value + "]";
+ }
+ };
+ }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/common/util/Supplier.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/Supplier.java b/sshd-core/src/main/java/org/apache/sshd/common/util/Supplier.java
new file mode 100644
index 0000000..c40a175
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/Supplier.java
@@ -0,0 +1,29 @@
+/*
+ * 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;
+
+/**
+ * Same as in Java 8
+ * @param <T> Type of object being supplied
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface Supplier<T> {
+ T get();
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java b/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java
new file mode 100644
index 0000000..e889392
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/ServerAuthenticationManager.java
@@ -0,0 +1,166 @@
+/*
+ * 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;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.server.auth.UserAuth;
+import org.apache.sshd.server.auth.UserAuthKeyboardInteractiveFactory;
+import org.apache.sshd.server.auth.UserAuthPasswordFactory;
+import org.apache.sshd.server.auth.UserAuthPublicKeyFactory;
+import org.apache.sshd.server.auth.gss.GSSAuthenticator;
+import org.apache.sshd.server.auth.gss.UserAuthGSSFactory;
+import org.apache.sshd.server.auth.keyboard.KeyboardInteractiveAuthenticator;
+import org.apache.sshd.server.auth.password.PasswordAuthenticator;
+import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
+
+/**
+ * Holds providers and helpers related to the server side authentication process
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public interface ServerAuthenticationManager {
+ /**
+ * Key used to retrieve the value in the configuration properties map
+ * of the maximum number of failed authentication requests before the
+ * server closes the connection.
+ * @see #DEFAULT_MAX_AUTH_REQUESTS
+ */
+ String MAX_AUTH_REQUESTS = "max-auth-requests";
+
+ /**
+ * Default value for {@link #MAX_AUTH_REQUESTS} if none configured
+ */
+ int DEFAULT_MAX_AUTH_REQUESTS = 20;
+
+ /**
+ * Retrieve the list of named factories for <code>UserAuth</code> objects.
+ *
+ * @return a list of named <code>UserAuth</code> factories, never {@code null}/empty
+ */
+ List<NamedFactory<UserAuth>> getUserAuthFactories();
+ void setUserAuthFactories(List<NamedFactory<UserAuth>> userAuthFactories);
+
+ /**
+ * Retrieve the <code>PublickeyAuthenticator</code> to be used by SSH server.
+ * If no authenticator has been configured (i.e. this method returns
+ * {@code null}), then client authentication requests based on keys will be
+ * rejected.
+ *
+ * @return the <code>PublickeyAuthenticator</code> or {@code null}
+ */
+ PublickeyAuthenticator getPublickeyAuthenticator();
+ void setPasswordAuthenticator(PasswordAuthenticator passwordAuthenticator);
+
+ /**
+ * Retrieve the <code>PasswordAuthenticator</code> to be used by the SSH server.
+ * If no authenticator has been configured (i.e. this method returns
+ * {@code null}), then client authentication requests based on passwords
+ * will be rejected.
+ *
+ * @return the <code>PasswordAuthenticator</code> or {@code null}
+ */
+ PasswordAuthenticator getPasswordAuthenticator();
+ void setPublickeyAuthenticator(PublickeyAuthenticator publickeyAuthenticator);
+
+ /**
+ * Retrieve the <code>KeyboardInteractiveAuthenticator</code> to be used by
+ * the SSH server. If no authenticator has been configured (i.e. this method returns
+ * {@code null}), then client authentication requests based on this method
+ * will be rejected.
+ *
+ * @return The {@link KeyboardInteractiveAuthenticator} or {@code null}
+ */
+ KeyboardInteractiveAuthenticator getKeyboardInteractiveAuthenticator();
+ void setKeyboardInteractiveAuthenticator(KeyboardInteractiveAuthenticator interactiveAuthenticator);
+
+ /**
+ * Retrieve the <code>GSSAuthenticator</code> to be used by the SSH server.
+ * If no authenticator has been configured (i.e. this method returns
+ * {@code null}), then client authentication requests based on gssapi
+ * will be rejected.
+ *
+ * @return the <code>GSSAuthenticator</code> or {@code null}
+ */
+ GSSAuthenticator getGSSAuthenticator();
+ void setGSSAuthenticator(GSSAuthenticator gssAuthenticator);
+
+ // CHECKSTYLE:OFF
+ final class Utils {
+ // CHECKSTYLE:ON
+ public static final UserAuthPublicKeyFactory DEFAULT_USER_AUTH_PUBLIC_KEY_FACTORY =
+ UserAuthPublicKeyFactory.INSTANCE;
+
+ public static final UserAuthGSSFactory DEFAULT_USER_AUTH_GSS_FACTORY =
+ UserAuthGSSFactory.INSTANCE;
+
+ public static final UserAuthPasswordFactory DEFAULT_USER_AUTH_PASSWORD_FACTORY =
+ UserAuthPasswordFactory.INSTANCE;
+
+ public static final UserAuthKeyboardInteractiveFactory DEFAULT_USER_AUTH_KB_INTERACTIVE_FACTORY =
+ UserAuthKeyboardInteractiveFactory.INSTANCE;
+
+ private Utils() {
+ throw new UnsupportedOperationException("No instance allowed");
+ }
+
+ /**
+ * If user authentication factories already set, then simply returns them. Otherwise,
+ * builds the factories list from the individual authenticators set - password,
+ * public key, keyboard-interactive, GSS, etc...
+ *
+ * @param manager The {@link ServerAuthenticationManager} - ignored if {@code null}
+ * @return The resolved {@link List} of {@link NamedFactory} for the {@link UserAuth}s
+ */
+ public static List<NamedFactory<UserAuth>> resolveUserAuthFactories(ServerAuthenticationManager manager) {
+ if (manager == null) {
+ return Collections.emptyList();
+ } else {
+ return resolveUserAuthFactories(manager, manager.getUserAuthFactories());
+ }
+ }
+
+ public static List<NamedFactory<UserAuth>> resolveUserAuthFactories(
+ ServerAuthenticationManager manager, List<NamedFactory<UserAuth>> userFactories) {
+ if (GenericUtils.size(userFactories) > 0) {
+ return userFactories;
+ }
+
+ List<NamedFactory<UserAuth>> factories = new ArrayList<>();
+ if (manager.getPasswordAuthenticator() != null) {
+ factories.add(DEFAULT_USER_AUTH_PASSWORD_FACTORY);
+ factories.add(DEFAULT_USER_AUTH_KB_INTERACTIVE_FACTORY);
+ }
+
+ if (manager.getPublickeyAuthenticator() != null) {
+ factories.add(DEFAULT_USER_AUTH_PUBLIC_KEY_FACTORY);
+ }
+
+ if (manager.getGSSAuthenticator() != null) {
+ factories.add(DEFAULT_USER_AUTH_GSS_FACTORY);
+ }
+
+ return factories;
+ }
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
index ca806fd..92fd295 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
@@ -24,12 +24,6 @@ import java.util.concurrent.TimeUnit;
import org.apache.sshd.common.Factory;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.NamedFactory;
-import org.apache.sshd.common.keyprovider.KeyPairProviderHolder;
-import org.apache.sshd.server.auth.UserAuth;
-import org.apache.sshd.server.auth.gss.GSSAuthenticator;
-import org.apache.sshd.server.auth.keyboard.KeyboardInteractiveAuthenticator;
-import org.apache.sshd.server.auth.password.PasswordAuthenticator;
-import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
/**
* The <code>ServerFactoryManager</code> enable the retrieval of additional
@@ -37,7 +31,7 @@ import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface ServerFactoryManager extends FactoryManager, KeyPairProviderHolder {
+public interface ServerFactoryManager extends FactoryManager, ServerAuthenticationManager {
/**
* Key used to retrieve the value of the maximum concurrent open session count per username.
* If not set, then unlimited
@@ -50,19 +44,6 @@ public interface ServerFactoryManager extends FactoryManager, KeyPairProviderHol
String SERVER_IDENTIFICATION = "server-identification";
/**
- * Key used to retrieve the value in the configuration properties map
- * of the maximum number of failed authentication requests before the
- * server closes the connection.
- * @see #DEFAULT_MAX_AUTH_REQUESTS
- */
- String MAX_AUTH_REQUESTS = "max-auth-requests";
-
- /**
- * Default value for {@link #MAX_AUTH_REQUESTS} if none configured
- */
- int DEFAULT_MAX_AUTH_REQUESTS = 20;
-
- /**
* Key used to retrieve the value of welcome banner that will be displayed
* when a user connects to the server. If {@code null}/empty then no banner
* will be sent.
@@ -130,53 +111,6 @@ public interface ServerFactoryManager extends FactoryManager, KeyPairProviderHol
String MODULI_URL = "moduli-url";
/**
- * Retrieve the list of named factories for <code>UserAuth</code> objects.
- *
- * @return a list of named <code>UserAuth</code> factories, never {@code null}
- */
- List<NamedFactory<UserAuth>> getUserAuthFactories();
-
- /**
- * Retrieve the <code>PublickeyAuthenticator</code> to be used by SSH server.
- * If no authenticator has been configured (i.e. this method returns
- * {@code null}), then client authentication requests based on keys will be
- * rejected.
- *
- * @return the <code>PublickeyAuthenticato</code> or {@code null}
- */
- PublickeyAuthenticator getPublickeyAuthenticator();
-
- /**
- * Retrieve the <code>PasswordAuthenticator</code> to be used by the SSH server.
- * If no authenticator has been configured (i.e. this method returns
- * {@code null}), then client authentication requests based on passwords
- * will be rejected.
- *
- * @return the <code>PasswordAuthenticator</code> or {@code null}
- */
- PasswordAuthenticator getPasswordAuthenticator();
-
- /**
- * Retrieve the <code>KeyboardInteractiveAuthenticator</code> to be used by
- * the SSH server. If no authenticator has been configured (i.e. this method returns
- * {@code null}), then client authentication requests based on this method
- * will be rejected.
- *
- * @return The {@link KeyboardInteractiveAuthenticator} or {@code null}
- */
- KeyboardInteractiveAuthenticator getKeyboardInteractiveAuthenticator();
-
- /**
- * Retrieve the <code>GSSAuthenticator</code> to be used by the SSH server.
- * If no authenticator has been configured (i.e. this method returns
- * {@code null}), then client authentication requests based on gssapi
- * will be rejected.
- *
- * @return the <code>GSSAuthenticator</code> or {@code null}
- */
- GSSAuthenticator getGSSAuthenticator();
-
- /**
* Retrieve the <code>ShellFactory</code> object to be used to create shells.
*
* @return a valid <code>ShellFactory</code> object or {@code null} if shells
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
index 6a50428..5df5346 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/SshServer.java
@@ -45,11 +45,7 @@ import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.server.auth.UserAuth;
-import org.apache.sshd.server.auth.UserAuthKeyboardInteractiveFactory;
-import org.apache.sshd.server.auth.UserAuthPasswordFactory;
-import org.apache.sshd.server.auth.UserAuthPublicKeyFactory;
import org.apache.sshd.server.auth.gss.GSSAuthenticator;
-import org.apache.sshd.server.auth.gss.UserAuthGSSFactory;
import org.apache.sshd.server.auth.keyboard.KeyboardInteractiveAuthenticator;
import org.apache.sshd.server.auth.password.PasswordAuthenticator;
import org.apache.sshd.server.auth.pubkey.AcceptAllPublickeyAuthenticator;
@@ -107,31 +103,20 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
ServerUserAuthServiceFactory.INSTANCE,
ServerConnectionServiceFactory.INSTANCE
));
- public static final UserAuthPublicKeyFactory DEFAULT_USER_AUTH_PUBLIC_KEY_FACTORY =
- UserAuthPublicKeyFactory.INSTANCE;
-
- public static final UserAuthGSSFactory DEFAULT_USER_AUTH_GSS_FACTORY =
- UserAuthGSSFactory.INSTANCE;
-
- public static final UserAuthPasswordFactory DEFAULT_USER_AUTH_PASSWORD_FACTORY =
- UserAuthPasswordFactory.INSTANCE;
-
- public static final UserAuthKeyboardInteractiveFactory DEFAULT_USER_AUTH_KB_INTERACTIVE_FACTORY =
- UserAuthKeyboardInteractiveFactory.INSTANCE;
protected IoAcceptor acceptor;
protected String host;
protected int port;
- protected List<NamedFactory<UserAuth>> userAuthFactories;
- protected Factory<Command> shellFactory;
- protected SessionFactory sessionFactory;
- protected CommandFactory commandFactory;
- protected List<NamedFactory<Command>> subsystemFactories;
- protected PasswordAuthenticator passwordAuthenticator;
- protected PublickeyAuthenticator publickeyAuthenticator;
- protected KeyboardInteractiveAuthenticator interactiveAuthenticator;
- protected GSSAuthenticator gssAuthenticator;
+ private Factory<Command> shellFactory;
+ private SessionFactory sessionFactory;
+ private CommandFactory commandFactory;
+ private List<NamedFactory<Command>> subsystemFactories;
+ private List<NamedFactory<UserAuth>> userAuthFactories;
+ private PasswordAuthenticator passwordAuthenticator;
+ private PublickeyAuthenticator publickeyAuthenticator;
+ private KeyboardInteractiveAuthenticator interactiveAuthenticator;
+ private GSSAuthenticator gssAuthenticator;
public SshServer() {
super();
@@ -163,6 +148,7 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
return userAuthFactories;
}
+ @Override
public void setUserAuthFactories(List<NamedFactory<UserAuth>> userAuthFactories) {
this.userAuthFactories = userAuthFactories;
}
@@ -207,6 +193,7 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
return passwordAuthenticator;
}
+ @Override
public void setPasswordAuthenticator(PasswordAuthenticator passwordAuthenticator) {
this.passwordAuthenticator = passwordAuthenticator;
}
@@ -216,6 +203,7 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
return publickeyAuthenticator;
}
+ @Override
public void setPublickeyAuthenticator(PublickeyAuthenticator publickeyAuthenticator) {
this.publickeyAuthenticator = publickeyAuthenticator;
}
@@ -225,6 +213,7 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
return interactiveAuthenticator;
}
+ @Override
public void setKeyboardInteractiveAuthenticator(KeyboardInteractiveAuthenticator interactiveAuthenticator) {
this.interactiveAuthenticator = interactiveAuthenticator;
}
@@ -234,6 +223,7 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
return gssAuthenticator;
}
+ @Override
public void setGSSAuthenticator(GSSAuthenticator gssAuthenticator) {
this.gssAuthenticator = gssAuthenticator;
}
@@ -249,24 +239,8 @@ public class SshServer extends AbstractFactoryManager implements ServerFactoryMa
ValidateUtils.checkTrue(getPort() >= 0 /* zero means not set yet */, "Bad port number: %d", Integer.valueOf(getPort()));
- if (GenericUtils.isEmpty(getUserAuthFactories())) {
- List<NamedFactory<UserAuth>> factories = new ArrayList<>();
- if (getPasswordAuthenticator() != null) {
- factories.add(DEFAULT_USER_AUTH_PASSWORD_FACTORY);
- factories.add(DEFAULT_USER_AUTH_KB_INTERACTIVE_FACTORY);
- }
-
- if (getPublickeyAuthenticator() != null) {
- factories.add(DEFAULT_USER_AUTH_PUBLIC_KEY_FACTORY);
- }
-
- if (getGSSAuthenticator() != null) {
- factories.add(DEFAULT_USER_AUTH_GSS_FACTORY);
- }
-
- ValidateUtils.checkTrue(factories.size() > 0, "UserAuthFactories not set");
- setUserAuthFactories(factories);
- }
+ List<NamedFactory<UserAuth>> authFactories = ServerAuthenticationManager.Utils.resolveUserAuthFactories(this);
+ setUserAuthFactories(ValidateUtils.checkNotNullAndNotEmpty(authFactories, "UserAuthFactories not set"));
ValidateUtils.checkNotNullAndNotEmpty(getChannelFactories(), "ChannelFactories not set");
ValidateUtils.checkNotNull(getKeyPairProvider(), "HostKeyProvider not set");
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 f9b8737..a384520 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
@@ -24,10 +24,8 @@ import java.util.List;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshException;
-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.server.ServerFactoryManager;
import org.apache.sshd.server.auth.keyboard.InteractiveChallenge;
import org.apache.sshd.server.auth.keyboard.KeyboardInteractiveAuthenticator;
import org.apache.sshd.server.session.ServerSession;
@@ -47,8 +45,7 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
@Override
protected Boolean doAuth(Buffer buffer, boolean init) throws Exception {
ServerSession session = getServerSession();
- ServerFactoryManager manager = ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
- KeyboardInteractiveAuthenticator auth = manager.getKeyboardInteractiveAuthenticator();
+ KeyboardInteractiveAuthenticator auth = session.getKeyboardInteractiveAuthenticator();
if (init) {
String lang = buffer.getString();
String subMethods = buffer.getString();
@@ -75,7 +72,7 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
} else {
int cmd = buffer.getUByte();
if (cmd != SshConstants.SSH_MSG_USERAUTH_INFO_RESPONSE) {
- throw new SshException("Received unexpected message: " + cmd);
+ throw new SshException("Received unexpected message: " + SshConstants.getCommandMessageName(cmd));
}
int num = buffer.getInt();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPassword.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPassword.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPassword.java
index 3dc7fd5..d59720b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPassword.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPassword.java
@@ -21,7 +21,6 @@ package org.apache.sshd.server.auth;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
-import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.auth.password.PasswordAuthenticator;
import org.apache.sshd.server.auth.password.PasswordChangeRequiredException;
import org.apache.sshd.server.session.ServerSession;
@@ -69,10 +68,7 @@ public class UserAuthPassword extends AbstractUserAuth {
* @see #handleServerPasswordChangeRequest(Buffer, ServerSession, String, String, PasswordChangeRequiredException)
*/
protected Boolean checkPassword(Buffer buffer, ServerSession session, String username, String password) throws Exception {
- ServerFactoryManager manager = ValidateUtils.checkNotNull(
- session.getFactoryManager(),
- "No ServerFactoryManager configured");
- PasswordAuthenticator auth = manager.getPasswordAuthenticator();
+ PasswordAuthenticator auth = session.getPasswordAuthenticator();
if (auth == null) {
if (log.isDebugEnabled()) {
log.debug("checkPassword({}) no password authenticator", session);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
index 5285e40..5299a84 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
@@ -22,12 +22,12 @@ import java.security.PublicKey;
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.signature.Signature;
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.server.ServerFactoryManager;
import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
import org.apache.sshd.server.session.ServerSession;
@@ -55,17 +55,21 @@ public class UserAuthPublicKey extends AbstractUserAuth {
buffer.wpos(buffer.rpos() + len);
ServerSession session = getServerSession();
- ServerFactoryManager manager = ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
PublicKey key = buffer.getRawPublicKey();
+ if (log.isDebugEnabled()) {
+ log.debug("doAuth({}) verify key type={}, fingerprint={}",
+ session, alg, KeyUtils.getFingerPrint(key));
+ }
+
Signature verifier = ValidateUtils.checkNotNull(
- NamedFactory.Utils.create(manager.getSignatureFactories(), alg),
+ NamedFactory.Utils.create(session.getSignatureFactories(), alg),
"No verifier located for algorithm=%s",
alg);
verifier.initVerifier(key);
buffer.wpos(oldLim);
byte[] sig = hasSig ? buffer.getBytes() : null;
- PublickeyAuthenticator authenticator = manager.getPublickeyAuthenticator();
+ PublickeyAuthenticator authenticator = session.getPublickeyAuthenticator();
if (authenticator == null) {
if (log.isDebugEnabled()) {
log.debug("doAuth({}) no authenticator", session);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 3a96e00..706b278 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
@@ -24,7 +24,6 @@ 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.ByteArrayBuffer;
-import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.auth.AbstractUserAuth;
import org.apache.sshd.server.session.ServerSession;
import org.ietf.jgss.GSSContext;
@@ -63,7 +62,7 @@ public class UserAuthGSS extends AbstractUserAuth {
@Override
protected Boolean doAuth(Buffer buffer, boolean initial) throws Exception {
ServerSession session = getServerSession();
- GSSAuthenticator auth = getAuthenticator(session);
+ GSSAuthenticator auth = ValidateUtils.checkNotNull(session.getGSSAuthenticator(), "No GSSAuthenticator configured");
if (initial) {
// Get mechanism count from buffer and look for Kerberos 5.
@@ -74,7 +73,9 @@ public class UserAuthGSS extends AbstractUserAuth {
Oid oid = new Oid(buffer.getBytes());
if (oid.equals(KRB5_MECH)) {
- log.debug("UserAuthGSS: found Kerberos 5");
+ if (log.isDebugEnabled()) {
+ log.debug("doAuth({}@{}) found Kerberos 5", getUsername(), session);
+ }
// Validate initial user before proceeding
@@ -110,11 +111,11 @@ public class UserAuthGSS extends AbstractUserAuth {
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,
- "Packet not supported by user authentication method: " + msg);
+ "Packet not supported by user authentication method: " + SshConstants.getCommandMessageName(msg));
}
if (log.isDebugEnabled()) {
- log.debug("doAuth({}@{}) In krb5.next: msg = {}", getUsername(), session, msg);
+ log.debug("doAuth({}@{}) In krb5.next: msg = {}", getUsername(), session, SshConstants.getCommandMessageName(msg));
}
// If the context is established, this must be a MIC message
@@ -145,7 +146,10 @@ public class UserAuthGSS extends AbstractUserAuth {
}
return Boolean.TRUE;
} catch (GSSException e) {
- log.info("doAuth({}@{}) GSS verification error: {}", getUsername(), session, e.toString());
+ if (log.isDebugEnabled()) {
+ log.debug("doAuth({}@{}) GSS verification {} error: {}",
+ getUsername(), session, e.getClass().getSimpleName(), e.getMessage());
+ }
return Boolean.FALSE;
}
} else {
@@ -161,7 +165,7 @@ public class UserAuthGSS extends AbstractUserAuth {
if (established && (identity == null)) {
identity = context.getSrcName().toString();
if (log.isDebugEnabled()) {
- log.info("GSS identity is {}", identity);
+ log.debug("doAuth({}@{}) GSS identity is {}", getUsername(), session, identity);
}
if (!auth.validateIdentity(session, identity)) {
@@ -208,24 +212,12 @@ public class UserAuthGSS extends AbstractUserAuth {
}
/**
- * Utility to get the configured GSS authenticator for the server, throwing an exception if none is available.
- *
- * @param session The current {@link ServerSession}
- * @return The {@link GSSAuthenticator} - never {@code null}
- * @throws Exception If no GSS authenticator is defined
- */
- protected GSSAuthenticator getAuthenticator(ServerSession session) throws Exception {
- ServerFactoryManager manager = session.getFactoryManager();
- return ValidateUtils.checkNotNull(manager.getGSSAuthenticator(), "No GSSAuthenticator configured");
- }
-
- /**
* Utility to construct an Oid from a string, ignoring the annoying exception.
*
* @param rep The string form
* @return The Oid
*/
- private static Oid createOID(String rep) {
+ public static Oid createOID(String rep) {
try {
return new Oid(rep);
} catch (GSSException e) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/DefaultKeyboardInteractiveAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/DefaultKeyboardInteractiveAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/DefaultKeyboardInteractiveAuthenticator.java
index 0e3f971..92bf59b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/DefaultKeyboardInteractiveAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/DefaultKeyboardInteractiveAuthenticator.java
@@ -24,9 +24,7 @@ import java.util.List;
import org.apache.sshd.common.PropertyResolverUtils;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
-import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.auth.password.PasswordAuthenticator;
import org.apache.sshd.server.session.ServerSession;
@@ -59,8 +57,7 @@ public class DefaultKeyboardInteractiveAuthenticator
@Override
public InteractiveChallenge generateChallenge(ServerSession session, String username, String lang, String subMethods) {
- ServerFactoryManager manager = ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
- PasswordAuthenticator auth = manager.getPasswordAuthenticator();
+ PasswordAuthenticator auth = session.getPasswordAuthenticator();
if (auth == null) {
if (log.isDebugEnabled()) {
log.debug("generateChallenge({}) no password authenticator", session);
@@ -78,8 +75,7 @@ public class DefaultKeyboardInteractiveAuthenticator
@Override
public boolean authenticate(ServerSession session, String username, List<String> responses) throws Exception {
- ServerFactoryManager manager = ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
- PasswordAuthenticator auth = manager.getPasswordAuthenticator();
+ PasswordAuthenticator auth = session.getPasswordAuthenticator();
if (auth == null) {
if (log.isDebugEnabled()) {
log.debug("authenticate({}) no password authenticator", session);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/KeyboardInteractiveAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/KeyboardInteractiveAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/KeyboardInteractiveAuthenticator.java
index 80c94f1..cdf2928 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/KeyboardInteractiveAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/keyboard/KeyboardInteractiveAuthenticator.java
@@ -31,6 +31,26 @@ import org.apache.sshd.server.session.ServerSession;
*/
public interface KeyboardInteractiveAuthenticator {
/**
+ * An authenticator that rejects any attempt to use it
+ */
+ KeyboardInteractiveAuthenticator NONE = new KeyboardInteractiveAuthenticator() {
+ @Override
+ public InteractiveChallenge generateChallenge(ServerSession session, String username, String lang, String subMethods) {
+ return null;
+ }
+
+ @Override
+ public boolean authenticate(ServerSession session, String username, List<String> responses) throws Exception {
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "NONE";
+ }
+ };
+
+ /**
* Generates the interactive "challenge" to send to the client
*
* @param session The {@link ServerSession} through which the request was received
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 3a0c4c5..4509ae5 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
@@ -171,9 +171,8 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
byte[] k_s;
KeyPair kp = ValidateUtils.checkNotNull(session.getHostKey(), "No server key pair available");
String algo = session.getNegotiatedKexParameter(KexProposalOption.SERVERKEYS);
- FactoryManager manager = ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
Signature sig = ValidateUtils.checkNotNull(
- NamedFactory.Utils.create(manager.getSignatureFactories(), algo),
+ NamedFactory.Utils.create(session.getSignatureFactories(), algo),
"Unknown negotiated server keys: %s",
algo);
sig.initSigner(kp.getPrivate());
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/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 4a45cd5..7e1757c 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
@@ -20,7 +20,6 @@ package org.apache.sshd.server.kex;
import java.security.KeyPair;
-import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshException;
@@ -98,9 +97,8 @@ public class DHGServer extends AbstractDHServerKeyExchange {
KeyPair kp = ValidateUtils.checkNotNull(session.getHostKey(), "No server key pair available");
String algo = session.getNegotiatedKexParameter(KexProposalOption.SERVERKEYS);
- FactoryManager manager = ValidateUtils.checkNotNull(session.getFactoryManager(), "No factory manager");
Signature sig = ValidateUtils.checkNotNull(
- NamedFactory.Utils.create(manager.getSignatureFactories(), algo),
+ NamedFactory.Utils.create(session.getSignatureFactories(), algo),
"Unknown negotiated server keys: %s",
algo);
sig.initSigner(kp.getPrivate());
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
new file mode 100644
index 0000000..2e76a7a
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/AbstractServerSession.java
@@ -0,0 +1,107 @@
+/*
+ * 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.session;
+
+import java.util.List;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.io.IoSession;
+import org.apache.sshd.common.session.AbstractSession;
+import org.apache.sshd.server.ServerFactoryManager;
+import org.apache.sshd.server.auth.UserAuth;
+import org.apache.sshd.server.auth.gss.GSSAuthenticator;
+import org.apache.sshd.server.auth.keyboard.KeyboardInteractiveAuthenticator;
+import org.apache.sshd.server.auth.password.PasswordAuthenticator;
+import org.apache.sshd.server.auth.pubkey.PublickeyAuthenticator;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class AbstractServerSession extends AbstractSession implements ServerSession {
+ private PasswordAuthenticator passwordAuthenticator;
+ private PublickeyAuthenticator publickeyAuthenticator;
+ private KeyboardInteractiveAuthenticator interactiveAuthenticator;
+ private GSSAuthenticator gssAuthenticator;
+ private List<NamedFactory<UserAuth>> userAuthFactories;
+
+ protected AbstractServerSession(ServerFactoryManager factoryManager, IoSession ioSession) {
+ super(true, factoryManager, ioSession);
+ }
+
+ @Override
+ public ServerFactoryManager getFactoryManager() {
+ return (ServerFactoryManager) super.getFactoryManager();
+ }
+
+ @Override
+ public PasswordAuthenticator getPasswordAuthenticator() {
+ return resolveEffectiveProvider(PasswordAuthenticator.class, passwordAuthenticator, getFactoryManager().getPasswordAuthenticator());
+ }
+
+ @Override
+ public void setPasswordAuthenticator(PasswordAuthenticator passwordAuthenticator) {
+ this.passwordAuthenticator = passwordAuthenticator; // OK if null - inherit from parent
+ }
+
+ @Override
+ public PublickeyAuthenticator getPublickeyAuthenticator() {
+ return resolveEffectiveProvider(PublickeyAuthenticator.class, publickeyAuthenticator, getFactoryManager().getPublickeyAuthenticator());
+ }
+
+ @Override
+ public void setPublickeyAuthenticator(PublickeyAuthenticator publickeyAuthenticator) {
+ this.publickeyAuthenticator = publickeyAuthenticator; // OK if null - inherit from parent
+ }
+
+ @Override
+ public KeyboardInteractiveAuthenticator getKeyboardInteractiveAuthenticator() {
+ return resolveEffectiveProvider(KeyboardInteractiveAuthenticator.class, interactiveAuthenticator, getFactoryManager().getKeyboardInteractiveAuthenticator());
+ }
+
+ @Override
+ public void setKeyboardInteractiveAuthenticator(KeyboardInteractiveAuthenticator interactiveAuthenticator) {
+ this.interactiveAuthenticator = interactiveAuthenticator; // OK if null - inherit from parent
+ }
+
+ @Override
+ public GSSAuthenticator getGSSAuthenticator() {
+ return resolveEffectiveProvider(GSSAuthenticator.class, gssAuthenticator, getFactoryManager().getGSSAuthenticator());
+ }
+
+ @Override
+ public void setGSSAuthenticator(GSSAuthenticator gssAuthenticator) {
+ this.gssAuthenticator = gssAuthenticator; // OK if null - inherit from parent
+ }
+
+ @Override
+ public List<NamedFactory<UserAuth>> getUserAuthFactories() {
+ return resolveEffectiveFactories(UserAuth.class, userAuthFactories, getFactoryManager().getUserAuthFactories());
+ }
+
+ @Override
+ public void setUserAuthFactories(List<NamedFactory<UserAuth>> userAuthFactories) {
+ this.userAuthFactories = userAuthFactories; // OK if null/empty - inherit from parent
+ }
+
+ @Override
+ protected void checkKeys() {
+ // nothing
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/e9dd7f47/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java
index a53d2ba..bf85c97 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerSession.java
@@ -22,12 +22,13 @@ package org.apache.sshd.server.session;
import java.security.KeyPair;
import org.apache.sshd.common.session.Session;
+import org.apache.sshd.server.ServerAuthenticationManager;
import org.apache.sshd.server.ServerFactoryManager;
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface ServerSession extends Session {
+public interface ServerSession extends Session, ServerAuthenticationManager {
/**
* @return The {@link ServerFactoryManager} for this session
*/
[08/10] mina-sshd git commit: Allow controlling whether to run the
core tests with JCE and/or MINA I/O
Posted by lg...@apache.org.
Allow controlling whether to run the core tests with JCE and/or MINA I/O
* Enabled by default - can be disabled by using mvn -P!test-jce,!test-mina (or either one alone)
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/af0e7838
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/af0e7838
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/af0e7838
Branch: refs/heads/master
Commit: af0e7838982cf80297d178b183f676ad9d8132a9
Parents: 88a30f5
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Thu Nov 26 07:27:54 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Thu Nov 26 07:27:54 2015 +0200
----------------------------------------------------------------------
sshd-core/pom.xml | 87 +++++++++++++++++++++++++++++++++-----------------
1 file changed, 57 insertions(+), 30 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/af0e7838/sshd-core/pom.xml
----------------------------------------------------------------------
diff --git a/sshd-core/pom.xml b/sshd-core/pom.xml
index b86aa5b..865646a 100644
--- a/sshd-core/pom.xml
+++ b/sshd-core/pom.xml
@@ -142,46 +142,73 @@
<redirectTestOutputToFile>true</redirectTestOutputToFile>
<reportsDirectory>${project.build.directory}/surefire-reports-nio2</reportsDirectory>
<systemProperties>
- <org.apache.sshd.common.io.IoServiceFactory>org.apache.sshd.common.io.nio2.Nio2ServiceFactory
- </org.apache.sshd.common.io.IoServiceFactory>
+ <org.apache.sshd.common.io.IoServiceFactory>org.apache.sshd.common.io.nio2.Nio2ServiceFactory</org.apache.sshd.common.io.IoServiceFactory>
</systemProperties>
<excludes>
<exclude>**/*LoadTest.java</exclude>
</excludes>
</configuration>
- <executions>
- <execution>
- <id>mina</id>
- <goals>
- <goal>test</goal>
- </goals>
- <configuration>
- <reportsDirectory>${project.build.directory}/surefire-reports-mina</reportsDirectory>
- <systemProperties>
- <org.apache.sshd.common.io.IoServiceFactory>
- org.apache.sshd.common.io.mina.MinaServiceFactory
- </org.apache.sshd.common.io.IoServiceFactory>
- </systemProperties>
- </configuration>
- </execution>
- <execution>
- <id>jce</id>
- <goals>
- <goal>test</goal>
- </goals>
- <configuration>
- <reportsDirectory>${project.build.directory}/surefire-reports-jce</reportsDirectory>
- <systemProperties>
- <org.apache.sshd.registerBouncyCastle>false</org.apache.sshd.registerBouncyCastle>
- </systemProperties>
- </configuration>
- </execution>
- </executions>
</plugin>
</plugins>
</build>
<profiles>
+ <profile>
+ <id>test-jce</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>jce</id>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ <configuration>
+ <reportsDirectory>${project.build.directory}/surefire-reports-jce</reportsDirectory>
+ <systemProperties>
+ <org.apache.sshd.registerBouncyCastle>false</org.apache.sshd.registerBouncyCastle>
+ </systemProperties>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
+ <profile>
+ <id>test-mina</id>
+ <activation>
+ <activeByDefault>true</activeByDefault>
+ </activation>
+ <build>
+ <plugins>
+ <plugin>
+ <groupId>org.apache.maven.plugins</groupId>
+ <artifactId>maven-surefire-plugin</artifactId>
+ <executions>
+ <execution>
+ <id>mina</id>
+ <goals>
+ <goal>test</goal>
+ </goals>
+ <configuration>
+ <reportsDirectory>${project.build.directory}/surefire-reports-mina</reportsDirectory>
+ <systemProperties>
+ <org.apache.sshd.common.io.IoServiceFactory>org.apache.sshd.common.io.mina.MinaServiceFactory</org.apache.sshd.common.io.IoServiceFactory>
+ </systemProperties>
+ </configuration>
+ </execution>
+ </executions>
+ </plugin>
+ </plugins>
+ </build>
+ </profile>
<profile>
<id>load-test</id>
<build>
[06/10] mina-sshd git commit: Add option to inform ByteArrayBuffer
not to automatically round up the buffer size to nearest power of 2
Posted by lg...@apache.org.
Add option to inform ByteArrayBuffer not to automatically round up the buffer size to nearest power of 2
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/fd3cb93f
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/fd3cb93f
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/fd3cb93f
Branch: refs/heads/master
Commit: fd3cb93fa575bfd93661c8506038c11675a32dc7
Parents: 5e73395
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Thu Nov 26 07:24:23 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Thu Nov 26 07:24:23 2015 +0200
----------------------------------------------------------------------
.../apache/sshd/agent/SshAgentConstants.java | 54 +++++++++++++--
.../sshd/agent/common/AbstractAgentClient.java | 2 +-
.../sshd/agent/common/AbstractAgentProxy.java | 71 +++++++++++---------
.../sshd/client/auth/UserAuthPublicKey.java | 2 +-
.../channel/PtyCapableChannelSession.java | 2 +-
.../subsystem/sftp/AbstractSftpClient.java | 38 +++++------
.../subsystem/sftp/DefaultSftpClient.java | 6 +-
.../impl/AbstractSftpClientExtension.java | 2 +-
.../common/forward/DefaultTcpipForwarder.java | 2 +-
.../apache/sshd/common/forward/SocksProxy.java | 6 +-
.../sshd/common/session/AbstractSession.java | 2 +-
.../common/util/buffer/ByteArrayBuffer.java | 6 +-
.../sshd/server/channel/ChannelSession.java | 2 +-
.../sshd/server/forward/TcpipServerChannel.java | 2 +-
.../sshd/server/shell/TtyFilterInputStream.java | 4 +-
.../server/subsystem/sftp/SftpSubsystem.java | 2 +-
.../sshd/server/x11/X11ForwardSupport.java | 2 +-
.../sshd/deprecated/UserAuthPublicKey.java | 2 +-
18 files changed, 133 insertions(+), 74 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentConstants.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentConstants.java b/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentConstants.java
index 3587f51..e533cb0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentConstants.java
+++ b/sshd-core/src/main/java/org/apache/sshd/agent/SshAgentConstants.java
@@ -18,29 +18,75 @@
*/
package org.apache.sshd.agent;
+import java.lang.reflect.Field;
import java.util.Map;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.Predicate;
import org.apache.sshd.common.util.logging.LoggingUtils;
+/**
+ * @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.agent">OpenSSH agent protocol</A>
+ */
public final class SshAgentConstants {
-
+ // Generic replies from agent to client
+ public static final byte SSH_AGENT_FAILURE = 5;
public static final byte SSH_AGENT_SUCCESS = 6;
+
+ // Replies from agent to client for protocol 1 key operations
+ public static final byte SSH_AGENT_RSA_IDENTITIES_ANSWER = 2;
+ public static final byte SSH_AGENT_RSA_RESPONSE = 4;
+
+ // Requests from client to agent for protocol 1 key operations
+ public static final byte SSH_AGENTC_REQUEST_RSA_IDENTITIES = 1;
+ public static final byte SSH_AGENTC_RSA_CHALLENGE = 3;
+ public static final byte SSH_AGENTC_ADD_RSA_IDENTITY = 7;
+ public static final byte SSH_AGENTC_REMOVE_RSA_IDENTITY = 8;
+ public static final byte SSH_AGENTC_REMOVE_ALL_RSA_IDENTITIES = 9;
+ public static final byte SSH_AGENTC_ADD_RSA_ID_CONSTRAINED = 24;
+
+ // Requests from client to agent for protocol 2 key operations
public static final byte SSH2_AGENTC_REQUEST_IDENTITIES = 11;
- public static final byte SSH2_AGENT_IDENTITIES_ANSWER = 12;
public static final byte SSH2_AGENTC_SIGN_REQUEST = 13;
- public static final byte SSH2_AGENT_SIGN_RESPONSE = 14;
public static final byte SSH2_AGENTC_ADD_IDENTITY = 17;
public static final byte SSH2_AGENTC_REMOVE_IDENTITY = 18;
public static final byte SSH2_AGENTC_REMOVE_ALL_IDENTITIES = 19;
+ public static final byte SSH2_AGENTC_ADD_ID_CONSTRAINED = 25;
+
+ // Key-type independent requests from client to agent
+ public static final byte SSH_AGENTC_ADD_SMARTCARD_KEY = 20;
+ public static final byte SSH_AGENTC_REMOVE_SMARTCARD_KEY = 21;
+ public static final byte SSH_AGENTC_LOCK = 22;
+ public static final byte SSH_AGENTC_UNLOCK = 23;
+ public static final byte SSH_AGENTC_ADD_SMARTCARD_KEY_CONSTRAINED = 26;
+
public static final byte SSH2_AGENT_FAILURE = 30;
+ // Replies from agent to client for protocol 2 key operations
+ public static final byte SSH2_AGENT_IDENTITIES_ANSWER = 12;
+ public static final byte SSH2_AGENT_SIGN_RESPONSE = 14;
+
+ // Key constraint identifiers
+ public static final byte SSH_AGENT_CONSTRAIN_LIFETIME = 1;
+ public static final byte SSH_AGENT_CONSTRAIN_CONFIRM = 2;
+
private SshAgentConstants() {
}
private static class LazyMessagesMapHolder {
private static final Map<Integer, String> MESSAGES_MAP =
- LoggingUtils.generateMnemonicMap(SshAgentConstants.class, "SSH2_AGENT");
+ LoggingUtils.generateMnemonicMap(SshAgentConstants.class, new Predicate<Field>() {
+ @Override
+ public boolean evaluate(Field f) {
+ String name = f.getName();
+ if (name.startsWith("SSH_AGENT_CONSTRAIN")) {
+ return false;
+ }
+
+ return name.startsWith("SSH_AGENT") || name.startsWith("SSH2_AGENT");
+ }
+ });
}
/**
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/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 d000510..770f967 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
@@ -120,7 +120,7 @@ public abstract class AbstractAgentClient extends AbstractLoggingBean {
"Cannot resolve key type of %s",
signingKey.getClass().getSimpleName());
byte[] signature = agent.sign(signingKey, data);
- Buffer sig = new ByteArrayBuffer(keyType.length() + signature.length + Long.SIZE);
+ Buffer sig = new ByteArrayBuffer(keyType.length() + signature.length + Long.SIZE, false);
sig.putString(keyType);
sig.putBytes(signature);
rep.putByte(SshAgentConstants.SSH2_AGENT_SIGN_RESPONSE);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/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 d67db09..57088dd 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
@@ -27,7 +27,9 @@ import java.util.List;
import java.util.concurrent.ExecutorService;
import org.apache.sshd.agent.SshAgent;
+import org.apache.sshd.agent.SshAgentConstants;
import org.apache.sshd.common.SshException;
+import org.apache.sshd.common.config.keys.KeyUtils;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.Pair;
import org.apache.sshd.common.util.buffer.Buffer;
@@ -36,15 +38,9 @@ import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
import org.apache.sshd.common.util.threads.ExecutorServiceConfigurer;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENTC_ADD_IDENTITY;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENTC_REMOVE_ALL_IDENTITIES;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENTC_REMOVE_IDENTITY;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENTC_REQUEST_IDENTITIES;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENTC_SIGN_REQUEST;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENT_IDENTITIES_ANSWER;
-import static org.apache.sshd.agent.SshAgentConstants.SSH2_AGENT_SIGN_RESPONSE;
-import static org.apache.sshd.agent.SshAgentConstants.SSH_AGENT_SUCCESS;
-
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
public abstract class AbstractAgentProxy extends AbstractLoggingBean implements SshAgent, ExecutorServiceConfigurer {
private ExecutorService executor;
private boolean shutdownExecutor;
@@ -75,11 +71,11 @@ public abstract class AbstractAgentProxy extends AbstractLoggingBean implements
@Override
public List<Pair<PublicKey, String>> getIdentities() throws IOException {
- Buffer buffer = createBuffer(SSH2_AGENTC_REQUEST_IDENTITIES);
+ Buffer buffer = createBuffer(SshAgentConstants.SSH2_AGENTC_REQUEST_IDENTITIES, 1);
buffer = request(prepare(buffer));
int type = buffer.getUByte();
- if (type != SSH2_AGENT_IDENTITIES_ANSWER) {
- throw new SshException("Bad agent identities answer: " + type);
+ if (type != SshAgentConstants.SSH2_AGENT_IDENTITIES_ANSWER) {
+ throw new SshException("Bad agent identities answer: " + SshAgentConstants.getCommandMessageName(type));
}
int nbIdentities = buffer.getInt();
@@ -90,70 +86,79 @@ public abstract class AbstractAgentProxy extends AbstractLoggingBean implements
List<Pair<PublicKey, String>> keys = new ArrayList<>(nbIdentities);
for (int i = 0; i < nbIdentities; i++) {
PublicKey key = buffer.getPublicKey();
- keys.add(new Pair<>(key, buffer.getString()));
+ String comment = buffer.getString();
+ if (log.isDebugEnabled()) {
+ log.debug("getIdentities() key type={}, comment={}, fingerprint={}",
+ KeyUtils.getKeyType(key), comment, KeyUtils.getFingerPrint(key));
+ }
+ keys.add(new Pair<>(key, comment));
}
+
return keys;
}
@Override
public byte[] sign(PublicKey key, byte[] data) throws IOException {
- Buffer buffer = createBuffer(SSH2_AGENTC_SIGN_REQUEST);
+ Buffer buffer = createBuffer(SshAgentConstants.SSH2_AGENTC_SIGN_REQUEST);
buffer.putPublicKey(key);
buffer.putBytes(data);
buffer.putInt(0);
buffer = request(prepare(buffer));
int responseType = buffer.getUByte();
- if (responseType != SSH2_AGENT_SIGN_RESPONSE) {
- throw new SshException("Bad signing response type: " + (responseType & 0xFF));
+ if (responseType != SshAgentConstants.SSH2_AGENT_SIGN_RESPONSE) {
+ throw new SshException("Bad signing response type: " + SshAgentConstants.getCommandMessageName(responseType));
}
+
Buffer buf = new ByteArrayBuffer(buffer.getBytes());
String algorithm = buf.getString();
byte[] signature = buf.getBytes();
if (log.isDebugEnabled()) {
- log.debug("sign(" + algorithm + "): " + BufferUtils.printHex(':', signature));
+ log.debug("sign({})[{}] {}: {}",
+ KeyUtils.getKeyType(key), KeyUtils.getFingerPrint(key),
+ algorithm, BufferUtils.printHex(':', signature));
}
return signature;
}
@Override
- public void addIdentity(KeyPair key, String comment) throws IOException {
- Buffer buffer = createBuffer(SSH2_AGENTC_ADD_IDENTITY);
- buffer.putKeyPair(key);
+ public void addIdentity(KeyPair kp, String comment) throws IOException {
+ Buffer buffer = createBuffer(SshAgentConstants.SSH2_AGENTC_ADD_IDENTITY);
+ buffer.putKeyPair(kp);
buffer.putString(comment);
if (log.isDebugEnabled()) {
- log.debug("addIdentity(" + comment + "): " + key.getPublic().getAlgorithm());
+ log.debug("addIdentity({})[{}]: {}", KeyUtils.getKeyType(kp), comment, KeyUtils.getFingerPrint(kp.getPublic()));
}
buffer = request(prepare(buffer));
int available = buffer.available();
int response = (available >= 1) ? buffer.getUByte() : -1;
- if ((available != 1) || (response != SSH_AGENT_SUCCESS)) {
- throw new SshException("Bad addIdentity response (" + (response & 0xFF) + ") - available=" + available);
+ if ((available != 1) || (response != SshAgentConstants.SSH_AGENT_SUCCESS)) {
+ throw new SshException("Bad addIdentity response (" + SshAgentConstants.getCommandMessageName(response) + ") - available=" + available);
}
}
@Override
public void removeIdentity(PublicKey key) throws IOException {
- Buffer buffer = createBuffer(SSH2_AGENTC_REMOVE_IDENTITY);
+ Buffer buffer = createBuffer(SshAgentConstants.SSH2_AGENTC_REMOVE_IDENTITY);
buffer.putPublicKey(key);
if (log.isDebugEnabled()) {
- log.debug("removeIdentity: " + key.getAlgorithm());
+ log.debug("removeIdentity({}) {}", KeyUtils.getKeyType(key), KeyUtils.getFingerPrint(key));
}
buffer = request(prepare(buffer));
int available = buffer.available();
int response = (available >= 1) ? buffer.getUByte() : -1;
- if ((available != 1) || (response != SSH_AGENT_SUCCESS)) {
- throw new SshException("Bad removeIdentity response (" + (response & 0xFF) + ") - available=" + available);
+ if ((available != 1) || (response != SshAgentConstants.SSH_AGENT_SUCCESS)) {
+ throw new SshException("Bad removeIdentity response (" + SshAgentConstants.getCommandMessageName(response) + ") - available=" + available);
}
}
@Override
public void removeAllIdentities() throws IOException {
- Buffer buffer = createBuffer(SSH2_AGENTC_REMOVE_ALL_IDENTITIES);
+ Buffer buffer = createBuffer(SshAgentConstants.SSH2_AGENTC_REMOVE_ALL_IDENTITIES, 1);
if (log.isDebugEnabled()) {
log.debug("removeAllIdentities");
}
@@ -161,8 +166,8 @@ public abstract class AbstractAgentProxy extends AbstractLoggingBean implements
int available = buffer.available();
int response = (available >= 1) ? buffer.getUByte() : -1;
- if ((available != 1) || (response != SSH_AGENT_SUCCESS)) {
- throw new SshException("Bad removeAllIdentities response (" + (response & 0xFF) + ") - available=" + available);
+ if ((available != 1) || (response != SshAgentConstants.SSH_AGENT_SUCCESS)) {
+ throw new SshException("Bad removeAllIdentities response (" + SshAgentConstants.getCommandMessageName(response) + ") - available=" + available);
}
}
@@ -178,7 +183,11 @@ public abstract class AbstractAgentProxy extends AbstractLoggingBean implements
}
protected Buffer createBuffer(byte cmd) {
- Buffer buffer = new ByteArrayBuffer();
+ return createBuffer(cmd, 0);
+ }
+
+ protected Buffer createBuffer(byte cmd, int extraLen) {
+ Buffer buffer = new ByteArrayBuffer((extraLen <= 0) ? ByteArrayBuffer.DEFAULT_SIZE : extraLen + Byte.SIZE, false);
buffer.putInt(0);
buffer.putByte(cmd);
return buffer;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/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 d4b0db4..db84aaf 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
@@ -168,7 +168,7 @@ public class UserAuthPublicKey extends AbstractUserAuth {
bs.putPublicKey(key);
byte[] sig = current.sign(bs.getCompactData());
- bs = new ByteArrayBuffer(algo.length() + sig.length + Long.SIZE);
+ bs = new ByteArrayBuffer(algo.length() + sig.length + Long.SIZE, false);
bs.putString(algo);
bs.putBytes(sig);
buffer.putBytes(bs.array(), bs.rpos(), bs.available());
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
index 1928188..75ce2a4 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/channel/PtyCapableChannelSession.java
@@ -252,7 +252,7 @@ public class PtyCapableChannelSession extends ChannelSession {
buffer.putInt(ptyHeight);
buffer.putInt(ptyWidth);
- Buffer modes = new ByteArrayBuffer(GenericUtils.size(ptyModes) * (1 + (Integer.SIZE / Byte.SIZE)) + Byte.SIZE);
+ Buffer modes = new ByteArrayBuffer(GenericUtils.size(ptyModes) * (1 + (Integer.SIZE / Byte.SIZE)) + Long.SIZE, false);
for (Map.Entry<PtyMode, ? extends Number> modeEntry : ptyModes.entrySet()) {
PtyMode mode = modeEntry.getKey();
Number value = modeEntry.getValue();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
index 009d48a..662866d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/AbstractSftpClient.java
@@ -631,7 +631,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
options = EnumSet.of(OpenMode.Read);
}
- Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */, false);
buffer.putString(path);
int version = getVersion();
int mode = 0;
@@ -707,7 +707,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
}
byte[] id = ValidateUtils.checkNotNull(handle, "No handle").getIdentifier();
- Buffer buffer = new ByteArrayBuffer(id.length + Long.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(id.length + Long.SIZE /* some extra fields */, false);
buffer.putBytes(id);
checkStatus(SftpConstants.SSH_FXP_CLOSE, buffer);
}
@@ -722,7 +722,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
log.debug("remove({}) {}", getClientSession(), path);
}
- Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */, false);
buffer.putString(path);
checkStatus(SftpConstants.SSH_FXP_REMOVE, buffer);
}
@@ -737,7 +737,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
log.debug("rename({}) {} => {}", getClientSession(), oldPath, newPath);
}
- Buffer buffer = new ByteArrayBuffer(oldPath.length() + newPath.length() + Long.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(oldPath.length() + newPath.length() + Long.SIZE /* some extra fields */, false);
buffer.putString(oldPath);
buffer.putString(newPath);
@@ -773,7 +773,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
}
byte[] id = handle.getIdentifier();
- Buffer buffer = new ByteArrayBuffer(id.length + Long.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(id.length + Long.SIZE /* some extra fields */, false);
buffer.putBytes(id);
buffer.putLong(fileOffset);
buffer.putInt(len);
@@ -842,7 +842,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
}
byte[] id = handle.getIdentifier();
- Buffer buffer = new ByteArrayBuffer(id.length + len + Long.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(id.length + len + Long.SIZE /* some extra fields */, false);
buffer.putBytes(id);
buffer.putLong(fileOffset);
buffer.putBytes(src, srcOffset, len);
@@ -859,7 +859,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
log.debug("mkdir({}) {}", getClientSession(), path);
}
- Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */, false);
buffer.putString(path);
buffer.putInt(0);
@@ -881,7 +881,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
log.debug("rmdir({}) {}", getClientSession(), path);
}
- Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */, false);
buffer.putString(path);
checkStatus(SftpConstants.SSH_FXP_RMDIR, buffer);
}
@@ -892,7 +892,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
throw new IOException("openDir(" + path + ") client is closed");
}
- Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */, false);
buffer.putString(path);
CloseableHandle handle = new DefaultCloseableHandle(this, checkHandle(SftpConstants.SSH_FXP_OPENDIR, buffer));
@@ -910,7 +910,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
}
byte[] id = handle.getIdentifier();
- Buffer buffer = new ByteArrayBuffer(id.length + Byte.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(id.length + Byte.SIZE /* some extra fields */, false);
buffer.putBytes(id);
return checkDir(receive(send(SftpConstants.SSH_FXP_READDIR, buffer)));
}
@@ -975,7 +975,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
throw new IOException("canonicalPath(" + path + ") client is closed");
}
- Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE);
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE, false);
buffer.putString(path);
return checkOneName(SftpConstants.SSH_FXP_REALPATH, buffer);
}
@@ -986,7 +986,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
throw new IOException("stat(" + path + ") client is closed");
}
- Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE);
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE, false);
buffer.putString(path);
int version = getVersion();
@@ -1003,7 +1003,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
throw new IOException("lstat(" + path + ") client is closed");
}
- Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE);
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE, false);
buffer.putString(path);
int version = getVersion();
@@ -1021,7 +1021,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
}
byte[] id = handle.getIdentifier();
- Buffer buffer = new ByteArrayBuffer(id.length + Byte.SIZE /* a bit extra */);
+ Buffer buffer = new ByteArrayBuffer(id.length + Byte.SIZE /* a bit extra */, false);
buffer.putBytes(id);
int version = getVersion();
@@ -1058,7 +1058,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
log.debug("setStat({})[{}]: {}", getClientSession(), handle, attributes);
}
byte[] id = handle.getIdentifier();
- Buffer buffer = new ByteArrayBuffer(id.length + (2 * Long.SIZE) /* some extras */);
+ Buffer buffer = new ByteArrayBuffer(id.length + (2 * Long.SIZE) /* some extras */, false);
buffer.putBytes(id);
writeAttributes(buffer, attributes);
checkStatus(SftpConstants.SSH_FXP_FSETSTAT, buffer);
@@ -1070,7 +1070,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
throw new IOException("readLink(" + path + ") client is closed");
}
- Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(path.length() + Long.SIZE /* some extra fields */, false);
buffer.putString(path);
return checkOneName(SftpConstants.SSH_FXP_READLINK, buffer);
}
@@ -1085,7 +1085,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
log.debug("link({})[symbolic={}] {} => {}", getClientSession(), symbolic, linkPath, targetPath);
}
- Buffer buffer = new ByteArrayBuffer(linkPath.length() + targetPath.length() + Long.SIZE /* some extra fields */);
+ Buffer buffer = new ByteArrayBuffer(linkPath.length() + targetPath.length() + Long.SIZE /* some extra fields */, false);
int version = getVersion();
if (version < SftpConstants.SFTP_V6) {
if (!symbolic) {
@@ -1114,7 +1114,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
}
byte[] id = handle.getIdentifier();
- Buffer buffer = new ByteArrayBuffer(id.length + Long.SIZE /* a bit extra */);
+ Buffer buffer = new ByteArrayBuffer(id.length + Long.SIZE /* a bit extra */, false);
buffer.putBytes(id);
buffer.putLong(offset);
buffer.putLong(length);
@@ -1133,7 +1133,7 @@ public abstract class AbstractSftpClient extends AbstractLoggingBean implements
}
byte[] id = handle.getIdentifier();
- Buffer buffer = new ByteArrayBuffer(id.length + Long.SIZE /* a bit extra */);
+ Buffer buffer = new ByteArrayBuffer(id.length + Long.SIZE /* a bit extra */, false);
buffer.putBytes(id);
buffer.putLong(offset);
buffer.putLong(length);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/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 8c5bb4d..858b866 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
@@ -197,7 +197,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
* @throws IOException if failed to process the buffer
*/
protected void process(Buffer incoming) throws IOException {
- Buffer buffer = new ByteArrayBuffer(incoming.available());
+ Buffer buffer = new ByteArrayBuffer(incoming.available() + Long.SIZE, false);
buffer.putBuffer(incoming);
buffer.rpos(5);
int id = buffer.getInt();
@@ -257,7 +257,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
}
// TODO in jdk-8 use Integer.BYTES
- Buffer buffer = new ByteArrayBuffer(length + (Integer.SIZE / Byte.SIZE));
+ Buffer buffer = new ByteArrayBuffer(length + (Integer.SIZE / Byte.SIZE), false);
buffer.putInt(length);
int nb = length;
while (nb > 0) {
@@ -359,7 +359,7 @@ public class DefaultSftpClient extends AbstractSftpClient {
String verVal = String.valueOf(selected);
Buffer buffer = new ByteArrayBuffer((Integer.SIZE / Byte.SIZE) + SftpConstants.EXT_VERSION_SELECT.length() // extension name
- + (Integer.SIZE / Byte.SIZE) + verVal.length());
+ + (Integer.SIZE / Byte.SIZE) + verVal.length(), false);
buffer.putString(SftpConstants.EXT_VERSION_SELECT);
buffer.putString(verVal);
checkStatus(SftpConstants.SSH_FXP_EXTENDED, buffer);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractSftpClientExtension.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractSftpClientExtension.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractSftpClientExtension.java
index 2b0427a..5b1b099 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractSftpClientExtension.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractSftpClientExtension.java
@@ -161,7 +161,7 @@ public abstract class AbstractSftpClientExtension extends AbstractLoggingBean im
*/
protected Buffer getCommandBuffer(int extraSize) {
String opcode = getName();
- Buffer buffer = new ByteArrayBuffer((Integer.SIZE / Byte.SIZE) + GenericUtils.length(opcode) + extraSize + Byte.SIZE);
+ Buffer buffer = new ByteArrayBuffer((Integer.SIZE / Byte.SIZE) + GenericUtils.length(opcode) + extraSize + Byte.SIZE, false);
buffer.putString(opcode);
return buffer;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java b/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java
index 0a239c0..f84523e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/forward/DefaultTcpipForwarder.java
@@ -413,7 +413,7 @@ public class DefaultTcpipForwarder extends AbstractInnerCloseable implements Tcp
@Override
public void messageReceived(IoSession session, Readable message) throws Exception {
TcpipClientChannel channel = (TcpipClientChannel) session.getAttribute(TcpipClientChannel.class);
- Buffer buffer = new ByteArrayBuffer(message.available() + Long.SIZE);
+ Buffer buffer = new ByteArrayBuffer(message.available() + Long.SIZE, false);
buffer.putBuffer(message);
channel.waitFor(EnumSet.of(ClientChannel.ClientChannelEvent.OPENED, ClientChannel.ClientChannelEvent.CLOSED), Long.MAX_VALUE);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/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 b8365da..36b664b 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
@@ -66,7 +66,7 @@ public class SocksProxy extends AbstractCloseable implements IoHandler {
@Override
public void messageReceived(final IoSession session, org.apache.sshd.common.util.Readable message) throws Exception {
- Buffer buffer = new ByteArrayBuffer(message.available());
+ Buffer buffer = new ByteArrayBuffer(message.available() + Long.SIZE, false);
buffer.putBuffer(message);
Proxy proxy = proxies.get(session);
if (proxy == null) {
@@ -167,7 +167,7 @@ public class SocksProxy extends AbstractCloseable implements IoHandler {
@SuppressWarnings("synthetic-access")
protected void onChannelOpened(OpenFuture future) {
- Buffer buffer = new ByteArrayBuffer(8);
+ Buffer buffer = new ByteArrayBuffer(Long.SIZE, false);
buffer.putByte((byte) 0x00);
Throwable t = future.getException();
if (t != null) {
@@ -219,7 +219,7 @@ public class SocksProxy extends AbstractCloseable implements IoHandler {
for (int i = 0; i < nbAuthMethods; i++) {
foundNoAuth |= authMethods[i] == 0;
}
- buffer = new ByteArrayBuffer(8);
+ buffer = new ByteArrayBuffer(Byte.SIZE, false);
buffer.putByte((byte) 0x05);
buffer.putByte((byte) (foundNoAuth ? 0x00 : 0xFF));
session.write(buffer);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/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 ad1e74b..7d90d11 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
@@ -793,7 +793,7 @@ public abstract class AbstractSession extends AbstractKexFactoryManager implemen
if (buffer.rpos() < 5) {
log.warn("Performance cost: when sending a packet, ensure that "
+ "5 bytes are available in front of the buffer");
- Buffer nb = new ByteArrayBuffer(buffer.available() + Long.SIZE);
+ Buffer nb = new ByteArrayBuffer(buffer.available() + Long.SIZE, false);
nb.wpos(5);
nb.putBuffer(buffer);
buffer = nb;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java
index 932e3cb..650af18 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/buffer/ByteArrayBuffer.java
@@ -43,7 +43,11 @@ public final class ByteArrayBuffer extends Buffer {
}
public ByteArrayBuffer(int size) {
- this(new byte[BufferUtils.getNextPowerOf2(size)], false);
+ this(size, true);
+ }
+
+ public ByteArrayBuffer(int size, boolean roundOff) {
+ this(new byte[roundOff ? BufferUtils.getNextPowerOf2(size) : size], false);
}
public ByteArrayBuffer(byte[] data) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
index ced8f62..985ac7c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
@@ -217,7 +217,7 @@ public class ChannelSession extends AbstractServerChannel {
}
} else {
if (tempBuffer == null) {
- tempBuffer = new ByteArrayBuffer(len);
+ tempBuffer = new ByteArrayBuffer(len + Long.SIZE, false);
}
tempBuffer.putRawBytes(data, off, len);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
index dbfd767..a47a3e0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/forward/TcpipServerChannel.java
@@ -152,7 +152,7 @@ public class TcpipServerChannel extends AbstractServerChannel {
log.debug("doInit({}) Ignoring write to channel in CLOSING state", TcpipServerChannel.this);
}
} else {
- Buffer buffer = new ByteArrayBuffer(message.available() + Long.SIZE);
+ Buffer buffer = new ByteArrayBuffer(message.available() + Long.SIZE, false);
buffer.putBuffer(message);
out.write(buffer.array(), buffer.rpos(), buffer.available());
out.flush();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/sshd-core/src/main/java/org/apache/sshd/server/shell/TtyFilterInputStream.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/shell/TtyFilterInputStream.java b/sshd-core/src/main/java/org/apache/sshd/server/shell/TtyFilterInputStream.java
index e17cbf0..95ac4e5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/shell/TtyFilterInputStream.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/shell/TtyFilterInputStream.java
@@ -43,7 +43,7 @@ public class TtyFilterInputStream extends FilterInputStream {
Collections.unmodifiableSet(EnumSet.of(PtyMode.ONLCR, PtyMode.OCRNL, PtyMode.ONLRET, PtyMode.ONOCR));
private final Set<PtyMode> ttyOptions;
- private Buffer buffer = new ByteArrayBuffer(32);
+ private Buffer buffer = new ByteArrayBuffer(Integer.SIZE, false);
private int lastChar = -1;
public TtyFilterInputStream(InputStream in, Map<PtyMode, ?> modes) {
@@ -123,7 +123,7 @@ public class TtyFilterInputStream extends FilterInputStream {
org.rpos(readPos - 1);
return org;
} else {
- Buffer buf = new ByteArrayBuffer(org.available() + 1);
+ Buffer buf = new ByteArrayBuffer(org.available() + Byte.SIZE, false);
buf.putByte((byte) c);
buf.putBuffer(org);
return buf;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/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 5aa6d5f..850c5fe 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
@@ -394,7 +394,7 @@ public class SftpSubsystem
int length = BufferUtils.readInt(in, workBuf, 0, workBuf.length);
ValidateUtils.checkTrue(length >= ((Integer.SIZE / Byte.SIZE) + 1 /* command */), "Bad length to read: %d", length);
- Buffer buffer = new ByteArrayBuffer(length + (Integer.SIZE / Byte.SIZE) /* the length */);
+ Buffer buffer = new ByteArrayBuffer(length + (Integer.SIZE / Byte.SIZE) + Long.SIZE /* a bit extra */, false);
buffer.putInt(length);
for (int remainLen = length; remainLen > 0;) {
int l = in.read(buffer.array(), buffer.wpos(), remainLen);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/sshd-core/src/main/java/org/apache/sshd/server/x11/X11ForwardSupport.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/x11/X11ForwardSupport.java b/sshd-core/src/main/java/org/apache/sshd/server/x11/X11ForwardSupport.java
index 55f8b45..afa8735 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/x11/X11ForwardSupport.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/x11/X11ForwardSupport.java
@@ -166,7 +166,7 @@ public class X11ForwardSupport extends AbstractInnerCloseable implements IoHandl
@Override
public void messageReceived(IoSession session, Readable message) throws Exception {
ChannelForwardedX11 channel = (ChannelForwardedX11) session.getAttribute(ChannelForwardedX11.class);
- Buffer buffer = new ByteArrayBuffer(message.available() + Long.SIZE);
+ Buffer buffer = new ByteArrayBuffer(message.available() + Long.SIZE, false);
buffer.putBuffer(message);
OutputStream outputStream = channel.getInvertedIn();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/fd3cb93f/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 e23fad6..43b8cfc 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
@@ -78,7 +78,7 @@ public class UserAuthPublicKey extends AbstractUserAuth {
verif.update(bs.array(), bs.rpos(), bs.available());
byte[] signature = verif.sign();
- bs = new ByteArrayBuffer(alg.length() + signature.length + Long.SIZE);
+ bs = new ByteArrayBuffer(alg.length() + signature.length + Long.SIZE, false);
bs.putString(alg);
bs.putBytes(signature);
buffer.putBytes(bs.array(), bs.rpos(), bs.available());