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:03 UTC
[02/10] mina-sshd git commit: [SSHD-599] Allow per-session override
of KEX and authentication related configuration
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
*/