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/05/07 10:29:33 UTC
[1/2] mina-sshd git commit: [SSHD-454] Allow lenient parsing of
configuration values from ~/etc/sshd_config
Repository: mina-sshd
Updated Branches:
refs/heads/master 99ebcc951 -> cca7cc743
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java b/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java
index 7867d28..ead553d 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/mac/BuiltinMacsTest.java
@@ -20,9 +20,18 @@
package org.apache.sshd.common.mac;
import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.EnumSet;
+import java.util.List;
+import java.util.Random;
import java.util.Set;
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.mac.BuiltinMacs.ParseResult;
+import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.util.BaseTest;
import org.junit.Assert;
import org.junit.Test;
@@ -57,4 +66,40 @@ public class BuiltinMacsTest extends BaseTest {
Assert.assertEquals("Incomplete coverage", BuiltinMacs.VALUES, avail);
}
+
+ @Test
+ public void testParseMacsList() {
+ List<String> builtin=NamedResource.Utils.getNameList(BuiltinMacs.VALUES);
+ List<String> unknown=Arrays.asList(getClass().getPackage().getName(), getClass().getSimpleName(), getCurrentTestName());
+ Random rnd=new Random();
+ for (int index=0; index < (builtin.size() + unknown.size()); index++) {
+ Collections.shuffle(builtin, rnd);
+ Collections.shuffle(unknown, rnd);
+
+ List<String> weavedList=new ArrayList<String>(builtin.size() + unknown.size());
+ for (int bIndex=0, uIndex=0; (bIndex < builtin.size()) || (uIndex < unknown.size()); ) {
+ boolean useBuiltin=false;
+ if (bIndex < builtin.size()) {
+ useBuiltin = (uIndex < unknown.size()) ? rnd.nextBoolean() : true;
+ }
+
+ if (useBuiltin) {
+ weavedList.add(builtin.get(bIndex));
+ bIndex++;
+ } else if (uIndex < unknown.size()){
+ weavedList.add(unknown.get(uIndex));
+ uIndex++;
+ }
+ }
+
+ String fullList=GenericUtils.join(weavedList, ',');
+ ParseResult result=BuiltinMacs.parseMacsList(fullList);
+ List<String> parsed=NamedResource.Utils.getNameList(result.getParsedFactories());
+ List<String> missing=result.getUnsupportedFactories();
+
+ // makes sure not only that the contents are the same but also the order
+ assertListEquals(fullList + "[parsed]", builtin, parsed);
+ assertListEquals(fullList + "[unsupported]", unknown, missing);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java b/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java
index 99bd1d7..f61ad18 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/signature/BuiltinSignaturesTest.java
@@ -19,6 +19,16 @@
package org.apache.sshd.common.signature;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.Random;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.signature.BuiltinSignatures.ParseResult;
+import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.util.BaseTest;
import org.junit.Assert;
import org.junit.Test;
@@ -39,4 +49,40 @@ public class BuiltinSignaturesTest extends BaseTest {
Assert.assertSame(name, expected, actual);
}
}
+
+ @Test
+ public void testParseSignaturesList() {
+ List<String> builtin=NamedResource.Utils.getNameList(BuiltinSignatures.VALUES);
+ List<String> unknown=Arrays.asList(getClass().getPackage().getName(), getClass().getSimpleName(), getCurrentTestName());
+ Random rnd=new Random();
+ for (int index=0; index < (builtin.size() + unknown.size()); index++) {
+ Collections.shuffle(builtin, rnd);
+ Collections.shuffle(unknown, rnd);
+
+ List<String> weavedList=new ArrayList<String>(builtin.size() + unknown.size());
+ for (int bIndex=0, uIndex=0; (bIndex < builtin.size()) || (uIndex < unknown.size()); ) {
+ boolean useBuiltin=false;
+ if (bIndex < builtin.size()) {
+ useBuiltin = (uIndex < unknown.size()) ? rnd.nextBoolean() : true;
+ }
+
+ if (useBuiltin) {
+ weavedList.add(builtin.get(bIndex));
+ bIndex++;
+ } else if (uIndex < unknown.size()){
+ weavedList.add(unknown.get(uIndex));
+ uIndex++;
+ }
+ }
+
+ String fullList=GenericUtils.join(weavedList, ',');
+ ParseResult result=BuiltinSignatures.parseSignatureList(fullList);
+ List<String> parsed=NamedResource.Utils.getNameList(result.getParsedFactories());
+ List<String> missing=result.getUnsupportedFactories();
+
+ // makes sure not only that the contents are the same but also the order
+ assertListEquals(fullList + "[parsed]", builtin, parsed);
+ assertListEquals(fullList + "[unsupported]", unknown, missing);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/test/java/org/apache/sshd/common/util/ValidateUtilsTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/util/ValidateUtilsTest.java b/sshd-core/src/test/java/org/apache/sshd/common/util/ValidateUtilsTest.java
new file mode 100644
index 0000000..8e8b9a3
--- /dev/null
+++ b/sshd-core/src/test/java/org/apache/sshd/common/util/ValidateUtilsTest.java
@@ -0,0 +1,32 @@
+/*
+ * 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;
+
+import org.apache.sshd.util.BaseTest;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class ValidateUtilsTest extends BaseTest {
+ public ValidateUtilsTest() {
+ super();
+ }
+
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/test/java/org/apache/sshd/util/BaseTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/util/BaseTest.java b/sshd-core/src/test/java/org/apache/sshd/util/BaseTest.java
index 205c889..6b5d2ab 100644
--- a/sshd-core/src/test/java/org/apache/sshd/util/BaseTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/util/BaseTest.java
@@ -23,8 +23,10 @@ import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.File;
+import java.util.List;
import org.apache.sshd.common.util.GenericUtils;
+import org.junit.Assert;
import org.junit.Rule;
import org.junit.rules.TestName;
import org.junit.rules.TestWatcher;
@@ -100,4 +102,14 @@ public abstract class BaseTest extends TestWatcher {
fail(message + " - actual object type (" + actual.getName() + ") incompatible with expected (" + expected.getName() + ")");
}
}
+
+ public static <E> void assertListEquals(String message, List<? extends E> expected, List<? extends E> actual) {
+ int expSize=GenericUtils.size(expected), actSize=GenericUtils.size(actual);
+ Assert.assertEquals(message + "[size]", expSize, actSize);
+
+ for (int index=0; index < expSize; index++) {
+ E expValue=expected.get(index), actValue=actual.get(index);
+ Assert.assertEquals(message + "[" + index + "]", expValue, actValue);
+ }
+ }
}
[2/2] mina-sshd git commit: [SSHD-454] Allow lenient parsing of
configuration values from ~/etc/sshd_config
Posted by lg...@apache.org.
[SSHD-454] Allow lenient parsing of configuration values from ~/etc/sshd_config
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/cca7cc74
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/cca7cc74
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/cca7cc74
Branch: refs/heads/master
Commit: cca7cc743acbe2082b0fea5fb12d0b2f1630441d
Parents: 99ebcc9
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Thu May 7 11:29:20 2015 +0300
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Thu May 7 11:29:20 2015 +0300
----------------------------------------------------------------------
pom.xml | 2 +-
.../sshd/client/session/ClientSessionImpl.java | 3 +-
.../sshd/common/AbstractFactoryManager.java | 18 +++
.../java/org/apache/sshd/common/Factory.java | 5 +-
.../org/apache/sshd/common/NamedFactory.java | 33 ++--
.../org/apache/sshd/common/NamedResource.java | 37 +++++
.../sshd/common/cipher/BuiltinCiphers.java | 48 ++++--
.../common/config/FactoriesListParseResult.java | 49 ++++++
.../sshd/common/config/ListParseResult.java | 65 ++++++++
.../config/NamedFactoriesListParseResult.java | 45 ++++++
.../config/NamedResourceListParseResult.java | 57 +++++++
.../sshd/common/config/SshConfigFileReader.java | 127 ++++++++++-----
.../sshd/common/digest/BuiltinDigests.java | 2 +-
.../sshd/common/kex/BuiltinDHFactories.java | 59 +++++--
.../org/apache/sshd/common/mac/BuiltinMacs.java | 54 +++++--
.../sshd/common/session/AbstractSession.java | 33 ++--
.../common/signature/BuiltinSignatures.java | 47 ++++--
.../apache/sshd/common/util/ValidateUtils.java | 28 ++--
.../sshd/server/session/ServerSession.java | 6 +-
.../server/session/ServerUserAuthService.java | 6 +-
.../java/org/apache/sshd/SshBuilderTest.java | 3 +-
.../sshd/common/cipher/BuiltinCiphersTest.java | 44 +++++
.../common/config/SshConfigFileReaderTest.java | 161 +++++++++++++++++--
.../sshd/common/kex/BuiltinDHFactoriesTest.java | 44 +++++
.../apache/sshd/common/mac/BuiltinMacsTest.java | 45 ++++++
.../common/signature/BuiltinSignaturesTest.java | 46 ++++++
.../sshd/common/util/ValidateUtilsTest.java | 32 ++++
.../java/org/apache/sshd/util/BaseTest.java | 12 ++
28 files changed, 934 insertions(+), 177 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/pom.xml
----------------------------------------------------------------------
diff --git a/pom.xml b/pom.xml
index 7795da5..0a9d175 100644
--- a/pom.xml
+++ b/pom.xml
@@ -562,7 +562,7 @@
<goal>remove-project-artifact</goal>
</goals>
<configuration>
- <removeAll>true</removeAll>
+ <removeAll>false</removeAll>
</configuration>
</execution>
</executions>
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/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 0e14596..2b3b60a 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
@@ -45,6 +45,7 @@ import org.apache.sshd.client.sftp.DefaultSftpClient;
import org.apache.sshd.client.sftp.SftpFileSystem;
import org.apache.sshd.client.sftp.SftpFileSystemProvider;
import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.Service;
import org.apache.sshd.common.ServiceFactory;
import org.apache.sshd.common.SessionListener;
@@ -360,7 +361,7 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
}
protected void sendKexInit() throws IOException {
- String algs = NamedFactory.Utils.getNames(getFactoryManager().getSignatureFactories());
+ String algs = NamedResource.Utils.getNames(getFactoryManager().getSignatureFactories());
clientProposal = createProposal(algs);
I_C = sendKexInit(clientProposal);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/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 8b1ff41..22af67e 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
@@ -71,6 +71,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
loadVersion();
}
+ @Override
public IoServiceFactory getIoServiceFactory() {
synchronized (ioServiceFactoryFactory) {
if (ioServiceFactory == null) {
@@ -88,6 +89,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.ioServiceFactoryFactory = ioServiceFactory;
}
+ @Override
public List<NamedFactory<KeyExchange>> getKeyExchangeFactories() {
return keyExchangeFactories;
}
@@ -96,6 +98,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.keyExchangeFactories = keyExchangeFactories;
}
+ @Override
public List<NamedFactory<Cipher>> getCipherFactories() {
return cipherFactories;
}
@@ -104,6 +107,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.cipherFactories = cipherFactories;
}
+ @Override
public List<NamedFactory<Compression>> getCompressionFactories() {
return compressionFactories;
}
@@ -112,6 +116,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.compressionFactories = compressionFactories;
}
+ @Override
public List<NamedFactory<Mac>> getMacFactories() {
return macFactories;
}
@@ -120,6 +125,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.macFactories = macFactories;
}
+ @Override
public List<NamedFactory<Signature>> getSignatureFactories() {
return signatureFactories;
}
@@ -128,6 +134,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.signatureFactories = signatureFactories;
}
+ @Override
public Factory<Random> getRandomFactory() {
return randomFactory;
}
@@ -136,6 +143,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.randomFactory = randomFactory;
}
+ @Override
public KeyPairProvider getKeyPairProvider() {
return keyPairProvider;
}
@@ -144,6 +152,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.keyPairProvider = keyPairProvider;
}
+ @Override
public Map<String, String> getProperties() {
return properties;
}
@@ -152,6 +161,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.properties = properties;
}
+ @Override
public String getVersion() {
return version;
}
@@ -169,6 +179,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
}
}
+ @Override
public List<NamedFactory<Channel>> getChannelFactories() {
return channelFactories;
}
@@ -194,6 +205,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
}
}
+ @Override
public SshAgentFactory getAgentFactory() {
return agentFactory;
}
@@ -202,6 +214,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.agentFactory = agentFactory;
}
+ @Override
public ScheduledExecutorService getScheduledExecutorService() {
return executor;
}
@@ -215,6 +228,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.shutdownExecutor = shutdownExecutor;
}
+ @Override
public TcpipForwarderFactory getTcpipForwarderFactory() {
return tcpipForwarderFactory;
}
@@ -223,6 +237,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.tcpipForwarderFactory = tcpipForwarderFactory;
}
+ @Override
public ForwardingFilter getTcpipForwardingFilter() {
return tcpipForwardingFilter;
}
@@ -231,6 +246,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.tcpipForwardingFilter = tcpipForwardingFilter;
}
+ @Override
public FileSystemFactory getFileSystemFactory() {
return fileSystemFactory;
}
@@ -239,6 +255,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.fileSystemFactory = fileSystemFactory;
}
+ @Override
public List<ServiceFactory> getServiceFactories() {
return serviceFactories;
}
@@ -247,6 +264,7 @@ public abstract class AbstractFactoryManager extends CloseableUtils.AbstractInne
this.serviceFactories = serviceFactories;
}
+ @Override
public List<RequestHandler<ConnectionService>> getGlobalRequestHandlers() {
return globalRequestHandlers;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/Factory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/Factory.java b/sshd-core/src/main/java/org/apache/sshd/common/Factory.java
index 864dbd2..3d3590e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/Factory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/Factory.java
@@ -18,6 +18,7 @@
*/
package org.apache.sshd.common;
+
/**
* Fatory is a simple interface that is used to create other objects.
*
@@ -28,9 +29,7 @@ package org.apache.sshd.common;
public interface Factory<T> {
/**
- * Create a new instance
- * @return
+ * @return A new instance
*/
T create();
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java
index 77b8cdc..f12ca99 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/NamedFactory.java
@@ -20,7 +20,6 @@ package org.apache.sshd.common;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import org.apache.sshd.common.util.GenericUtils;
@@ -28,32 +27,23 @@ import org.apache.sshd.common.util.GenericUtils;
/**
* A named factory is a factory identified by a name.
* Such names are used mainly in the algorithm negotiation at the beginning of the SSH connection.
- *
- * @param <T>
- *
+ * @param <T> The create object instance type
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
public interface NamedFactory<T> extends Factory<T>, NamedResource {
/**
* Utility class to help using NamedFactories
*/
- public static class Utils {
+ public static final class Utils {
/**
* @param factories The named factories
* @return A {@link List} of all the factories names - in same order
* as they appear in the input collection
+ * @deprecated Use {@link NamedResource.Utils#getNameList(Collection)}
*/
+ @Deprecated
public static List<String> getNameList(Collection<? extends NamedFactory<?>> factories) {
- if (GenericUtils.isEmpty(factories)) {
- return Collections.emptyList();
- }
-
- List<String> names = new ArrayList<>(factories.size());
- for (NamedFactory<?> f : factories) {
- names.add(f.getName());
- }
-
- return names;
+ return NamedResource.Utils.getNameList(factories);
}
/**
@@ -79,16 +69,11 @@ public interface NamedFactory<T> extends Factory<T>, NamedResource {
*
* @param factories list of available factories
* @return a comma separated list of factory names
+ * @deprecated Use {@link NamedResource.Utils#getNames(Collection)}
*/
+ @Deprecated
public static String getNames(Collection<? extends NamedFactory<?>> factories) {
- StringBuilder sb = new StringBuilder();
- for (NamedFactory<?> f : factories) {
- if (sb.length() > 0) {
- sb.append(",");
- }
- sb.append(f.getName());
- }
- return sb.toString();
+ return NamedResource.Utils.getNames(factories);
}
/**
@@ -128,7 +113,6 @@ public interface NamedFactory<T> extends Factory<T>, NamedResource {
return null;
}
-
public static final <T,E extends NamedFactory<T> & OptionalFeature> List<NamedFactory<T>> setUpBuiltinFactories(
boolean ignoreUnsupported, Collection<? extends E> preferred) {
List<NamedFactory<T>> avail=new ArrayList<>(preferred.size());
@@ -141,4 +125,5 @@ public interface NamedFactory<T> extends Factory<T>, NamedResource {
return avail;
}
}
+
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/NamedResource.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/NamedResource.java b/sshd-core/src/main/java/org/apache/sshd/common/NamedResource.java
index 85f78a8..494a1a9 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/NamedResource.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/NamedResource.java
@@ -19,6 +19,13 @@
package org.apache.sshd.common;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import org.apache.sshd.common.util.GenericUtils;
+
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
@@ -27,4 +34,34 @@ public interface NamedResource {
* @return The resource name
*/
String getName();
+ /**
+ * Utility class to help using {@link NamedResource}s
+ */
+ public static final class Utils {
+ /**
+ * @param resources The named resources
+ * @return A {@link List} of all the factories names - in same order
+ * as they appear in the input collection
+ */
+ public static List<String> getNameList(Collection<? extends NamedResource> resources) {
+ if (GenericUtils.isEmpty(resources)) {
+ return Collections.emptyList();
+ }
+
+ List<String> names = new ArrayList<>(resources.size());
+ for (NamedResource r : resources) {
+ names.add(r.getName());
+ }
+
+ return names;
+ }
+
+ /**
+ * @param resources list of available resources
+ * @return A comma separated list of factory names
+ */
+ public static String getNames(Collection<? extends NamedResource> resources) {
+ return GenericUtils.join(getNameList(resources), ',');
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
index 2ff52a0..da8550d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BuiltinCiphers.java
@@ -30,8 +30,8 @@ import java.util.Set;
import org.apache.sshd.common.Cipher;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.OptionalFeature;
+import org.apache.sshd.common.config.NamedFactoriesListParseResult;
import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.ValidateUtils;
/**
* Provides easy access to the currently implemented ciphers
@@ -205,33 +205,51 @@ public enum BuiltinCiphers implements NamedFactory<Cipher>, OptionalFeature {
/**
* @param ciphers A comma-separated list of ciphers' names - ignored
* if {@code null}/empty
- * @return A {@link List} of all the {@link NamedFactory}-ies whose
- * name appears in the string and represent a built-in cipher. Any
- * unknown name is <U>ignored</U>. The order of the returned result
- * is the same as the original order - bar the unknown ciphers.
- * <B>Note:</B> it is up to caller to ensure that the list does not
- * contain duplicates
+ * @return A {@link ParseResult} containing the successfully parsed
+ * factories and the unknown ones. <B>Note:</B> it is up to caller to
+ * ensure that the lists do not contain duplicates
*/
- public static final List<NamedFactory<Cipher>> parseCiphersList(String ciphers) {
+ public static final ParseResult parseCiphersList(String ciphers) {
return parseCiphersList(GenericUtils.split(ciphers, ','));
}
- public static final List<NamedFactory<Cipher>> parseCiphersList(String ... ciphers) {
+ public static final ParseResult parseCiphersList(String ... ciphers) {
return parseCiphersList(GenericUtils.isEmpty((Object[]) ciphers) ? Collections.<String>emptyList() : Arrays.asList(ciphers));
}
- public static final List<NamedFactory<Cipher>> parseCiphersList(Collection<String> ciphers) {
+ public static final ParseResult parseCiphersList(Collection<String> ciphers) {
if (GenericUtils.isEmpty(ciphers)) {
- return Collections.emptyList();
+ return ParseResult.EMPTY;
}
- List<NamedFactory<Cipher>> result=new ArrayList<NamedFactory<Cipher>>(ciphers.size());
+ List<NamedFactory<Cipher>> factories=new ArrayList<NamedFactory<Cipher>>(ciphers.size());
+ List<String> unknown=Collections.<String>emptyList();
for (String name : ciphers) {
- BuiltinCiphers c=ValidateUtils.checkNotNull(fromFactoryName(name), "Bad factory name (%s) in %s", name, ciphers);
- result.add(c);
+ BuiltinCiphers c=fromFactoryName(name);
+ if (c != null) {
+ factories.add(c);
+ } else {
+ // replace the (unmodifiable) empty list with a real one
+ if (unknown.isEmpty()) {
+ unknown = new ArrayList<String>();
+ }
+ unknown.add(name);
+ }
}
- return result;
+ return new ParseResult(factories, unknown);
+ }
+
+ /**
+ * Holds the result of {@link BuiltinCiphers#parseCiphersList(String)}
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+ public static final class ParseResult extends NamedFactoriesListParseResult<Cipher,NamedFactory<Cipher>> {
+ public static final ParseResult EMPTY=new ParseResult(Collections.<NamedFactory<Cipher>>emptyList(), Collections.<String>emptyList());
+
+ public ParseResult(List<NamedFactory<Cipher>> parsed, List<String> unsupported) {
+ super(parsed, unsupported);
+ }
}
public static final class Constants {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/config/FactoriesListParseResult.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/FactoriesListParseResult.java b/sshd-core/src/main/java/org/apache/sshd/common/config/FactoriesListParseResult.java
new file mode 100644
index 0000000..853e16d
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/FactoriesListParseResult.java
@@ -0,0 +1,49 @@
+/*
+ * 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.config;
+
+import java.util.List;
+
+import org.apache.sshd.common.Factory;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class FactoriesListParseResult<T,F extends Factory<T>> extends ListParseResult<F> {
+ protected FactoriesListParseResult(List<F> parsed, List<String> unsupported) {
+ super(parsed, unsupported);
+ }
+
+ /**
+ * @return The {@link List} of successfully parsed {@link Factory} instances
+ * in the <U>same order</U> as they were encountered during parsing
+ */
+ public final List<F> getParsedFactories() {
+ return getParsedValues();
+ }
+
+ /**
+ * @return A {@link List} of unknown/unsupported configuration values for
+ * the factories
+ */
+ public List<String> getUnsupportedFactories() {
+ return getUnsupportedValues();
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/config/ListParseResult.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/ListParseResult.java b/sshd-core/src/main/java/org/apache/sshd/common/config/ListParseResult.java
new file mode 100644
index 0000000..bf39c89
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/ListParseResult.java
@@ -0,0 +1,65 @@
+/*
+ * 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.config;
+
+import java.util.List;
+
+import org.apache.sshd.common.util.GenericUtils;
+
+/**
+ * Used to hold the result of parsing a list of value. Such result contains known
+ * and unknown values - which are accessible via the respective {@link #getParsedValues()}
+ * and {@link #getUnsupportedValues()} methods. <B>Note:</B> the returned {@link List}s may
+ * be un-modifiable, so it is recommended to avoid attempting changing the, returned
+ * list(s)
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class ListParseResult<E> {
+ private final List<E> parsed;
+ private final List<String> unsupported;
+
+ protected ListParseResult(List<E> parsed, List<String> unsupported) {
+ this.parsed = parsed;
+ this.unsupported = unsupported;
+ }
+
+ /**
+ * @return The {@link List} of successfully parsed value instances
+ * in the <U>same order</U> as they were encountered during parsing
+ */
+ public final List<E> getParsedValues() {
+ return parsed;
+ }
+
+ /**
+ * @return A {@link List} of unknown/unsupported configuration values for
+ * the factories
+ */
+ public List<String> getUnsupportedValues() {
+ return unsupported;
+ }
+
+ @Override
+ public String toString() {
+ return "parsed=" + GenericUtils.join(getParsedValues(), ',')
+ + ";unsupported=" + GenericUtils.join(getUnsupportedValues(), ',')
+ ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/config/NamedFactoriesListParseResult.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/NamedFactoriesListParseResult.java b/sshd-core/src/main/java/org/apache/sshd/common/config/NamedFactoriesListParseResult.java
new file mode 100644
index 0000000..9e1b817
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/NamedFactoriesListParseResult.java
@@ -0,0 +1,45 @@
+/*
+ * 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.config;
+
+import java.util.List;
+
+import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.util.GenericUtils;
+
+/**
+ * Holds the result of parsing a list of {@link NamedFactory}ies
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class NamedFactoriesListParseResult<T,F extends NamedFactory<T>>
+ extends FactoriesListParseResult<T,F> {
+
+ protected NamedFactoriesListParseResult(List<F> parsed, List<String> unsupported) {
+ super(parsed, unsupported);
+ }
+
+ @Override
+ public String toString() {
+ return "parsed=" + NamedResource.Utils.getNames(getParsedFactories())
+ + ";unknown=" + GenericUtils.join(getUnsupportedFactories(), ',')
+ ;
+ }
+}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/config/NamedResourceListParseResult.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/NamedResourceListParseResult.java b/sshd-core/src/main/java/org/apache/sshd/common/config/NamedResourceListParseResult.java
new file mode 100644
index 0000000..03805ef
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/NamedResourceListParseResult.java
@@ -0,0 +1,57 @@
+/*
+ * 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.config;
+
+import java.util.List;
+
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.util.GenericUtils;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public abstract class NamedResourceListParseResult<R extends NamedResource> extends ListParseResult<R> {
+ protected NamedResourceListParseResult(List<R> parsed, List<String> unsupported) {
+ super(parsed, unsupported);
+ }
+
+ /**
+ * @return The {@link List} of successfully parsed {@link NamedResource} instances
+ * in the <U>same order</U> as they were encountered during parsing
+ */
+ public final List<R> getParsedResources() {
+ return getParsedValues();
+ }
+
+ /**
+ * @return A {@link List} of unknown/unsupported configuration values for
+ * the resources
+ */
+ public List<String> getUnsupportedResources() {
+ return getUnsupportedValues();
+ }
+
+ @Override
+ public String toString() {
+ return "parsed=" + NamedResource.Utils.getNames(getParsedResources())
+ + ";unknown=" + GenericUtils.join(getUnsupportedResources(), ',')
+ ;
+ }
+}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/config/SshConfigFileReader.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/SshConfigFileReader.java b/sshd-core/src/main/java/org/apache/sshd/common/config/SshConfigFileReader.java
index 45c7aff..38e0272 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/config/SshConfigFileReader.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/SshConfigFileReader.java
@@ -29,8 +29,8 @@ import java.io.Reader;
import java.io.StreamCorruptedException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
+import java.util.Collection;
import java.util.Collections;
-import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
@@ -347,23 +347,23 @@ public class SshConfigFileReader {
/**
* @param props The {@link Properties} - ignored if {@code null}/empty
- * @return A {@link List} of all the {@link NamedFactory}-ies whose
- * name appears in the string and represent a built-in cipher. Any
- * unknown name is <U>ignored</U>. The order of the returned result
+ * @return A {@BuiltinCiphers.ParseResult} of all the {@link NamedFactory}-ies
+ * whose name appears in the string and represent a built-in cipher.
+ * Any unknown name is <U>ignored</U>. The order of the returned result
* is the same as the original order - bar the unknown ciphers.
- * <B>Note:</B> it is up to caller to ensure that the list does not
+ * <B>Note:</B> it is up to caller to ensure that the lists do not
* contain duplicates
* @see #CIPHERS_CONFIG_PROP
* @see BuiltinCiphers#parseCiphersList(String)
*/
- public static final List<NamedFactory<Cipher>> getCiphers(Properties props) {
+ public static final BuiltinCiphers.ParseResult getCiphers(Properties props) {
return BuiltinCiphers.parseCiphersList((props == null) ? null : props.getProperty(CIPHERS_CONFIG_PROP));
}
/**
* @param props The {@link Properties} - ignored if {@code null}/empty
- * @return A {@link List} of all the {@link NamedFactory}-ies whose
- * name appears in the string and represent a built-in MAC. Any
+ * @return A {@link BuiltinMacs.ParseResult} of all the {@link NamedFactory}-ies
+ * whose name appears in the string and represent a built-in MAC. Any
* unknown name is <U>ignored</U>. The order of the returned result
* is the same as the original order - bar the unknown MACs.
* <B>Note:</B> it is up to caller to ensure that the list does not
@@ -371,37 +371,35 @@ public class SshConfigFileReader {
* @see #MACS_CONFIG_PROP
* @see BuiltinMacs#parseMacsList(String)
*/
- public static final List<NamedFactory<Mac>> getMacs(Properties props) {
+ public static final BuiltinMacs.ParseResult getMacs(Properties props) {
return BuiltinMacs.parseMacsList((props == null) ? null : props.getProperty(MACS_CONFIG_PROP));
}
/**
* @param props The {@link Properties} - ignored if {@code null}/empty
- * @return A {@link List} of all the {@link NamedFactory} whose
- * name appears in the string and represent a built-in signature. Any
- * unknown name is <U>ignored</I>. The order of the returned result
- * is the same as the original order - bar the unknown signatures.
- * <B>Note:</B> it is up to caller to ensure that the list does not
- * contain duplicates
+ * @return A {@link BuiltinSignatures.ParseResult} of all the {@link NamedFactory}
+ * whose name appears in the string and represent a built-in signature. Any
+ * unknown name is <U>ignored</I>. The order of the returned result is the
+ * same as the original order - bar the unknown signatures. <B>Note:</B> it
+ * is up to caller to ensure that the list does not contain duplicates
* @see #HOST_KEY_ALGORITHMS_CONFIG_PROP
* @see BuiltinSignatures#parseSignatureList(String)
*/
- public static final List<NamedFactory<Signature>> getSignatures(Properties props) {
+ public static final BuiltinSignatures.ParseResult getSignatures(Properties props) {
return BuiltinSignatures.parseSignatureList((props == null) ? null : props.getProperty(HOST_KEY_ALGORITHMS_CONFIG_PROP));
}
/**
* @param props The {@link Properties} - ignored if {@code null}/empty
- * @return A {@link List} of all the {@link DHFactory}-ies whose
- * name appears in the string and represent a built-in value. Any
- * unknown name is <U>ignored</U>. The order of the returned result
- * is the same as the original order - bar the unknown ones.
- * <B>Note:</B> it is up to caller to ensure that the list does not
- * contain duplicates
+ * @return A {@link BuiltinDHFactories.ParseResult} of all the {@link DHFactory}-ies
+ * whose name appears in the string and represent a built-in value. Any
+ * unknown name is <U>ignored</U>. The order of the returned result is the
+ * same as the original order - bar the unknown ones. <B>Note:</B> it is
+ * up to caller to ensure that the list does not contain duplicates
* @see #KEX_ALGORITHMS_CONFIG_PROP
* @see BuiltinDHFactories#parseDHFactoriesList(String)
*/
- public static final List<DHFactory> getKexFactories(Properties props) {
+ public static final BuiltinDHFactories.ParseResult getKexFactories(Properties props) {
return BuiltinDHFactories.parseDHFactoriesList((props == null) ? null : props.getProperty(KEX_ALGORITHMS_CONFIG_PROP));
}
@@ -427,32 +425,77 @@ public class SshConfigFileReader {
* @param props The {@link Properties} to use for configuration - <B>Note:</B>
* if any known configuration value has a default and does not appear in the
* properties, the default is used
+ * @param lenient If {@code true} then any unknown/unsupported configuration
+ * values are ignored. Otherwise an {@link IllegalArgumentException} is thrown
* @return The configured manager
*/
- public static final <M extends AbstractFactoryManager> M configure(M manager, Properties props) {
+ public static final <M extends AbstractFactoryManager> M configure(M manager, Properties props, boolean lenient) {
+ configureCiphers(manager, props, lenient);
+ configureSignatures(manager, props, lenient);
+ configureMacs(manager, props, lenient);
+ configureCompression(manager, props, lenient);
+
+ return manager;
+ }
+
+ public static final <M extends AbstractFactoryManager> M configureCiphers(M manager, Properties props, boolean lenient) {
+ ValidateUtils.checkNotNull(props, "No properties to configure", GenericUtils.EMPTY_OBJECT_ARRAY);
+ return configureCiphers(manager, props.getProperty(CIPHERS_CONFIG_PROP, DEFAULT_CIPHERS), lenient);
+ }
+
+ public static final <M extends AbstractFactoryManager> M configureCiphers(M manager, String value, boolean lenient) {
ValidateUtils.checkNotNull(manager, "No manager to configure", GenericUtils.EMPTY_OBJECT_ARRAY);
+
+ BuiltinCiphers.ParseResult result=BuiltinCiphers.parseCiphersList(value);
+ Collection<String> unsupported=result.getUnsupportedFactories();
+ ValidateUtils.checkTrue(lenient || GenericUtils.isEmpty(unsupported), "Unsupported cipher(s) (%s) in %s", unsupported, value);
+ manager.setCipherFactories(ValidateUtils.checkNotNullAndNotEmpty(result.getParsedFactories(), "No known ciphers(s): %s", value));
+ return manager;
+ }
+
+ public static final <M extends AbstractFactoryManager> M configureSignatures(M manager, Properties props, boolean lenient) {
ValidateUtils.checkNotNull(props, "No properties to configure", GenericUtils.EMPTY_OBJECT_ARRAY);
-
- {
- String value=props.getProperty(HOST_KEY_ALGORITHMS_CONFIG_PROP, DEFAULT_HOST_KEY_ALGORITHMS);
- manager.setSignatureFactories(ValidateUtils.checkNotNullAndNotEmpty(BuiltinSignatures.parseSignatureList(value), "Bad signatures: %s", value));
- }
+ return configureSignatures(manager, props.getProperty(HOST_KEY_ALGORITHMS_CONFIG_PROP, DEFAULT_HOST_KEY_ALGORITHMS), lenient);
+ }
- {
- String value=props.getProperty(MACS_CONFIG_PROP, DEFAULT_MACS);
- manager.setMacFactories(ValidateUtils.checkNotNullAndNotEmpty(BuiltinMacs.parseMacsList(value), "Bad MAC(s): %s", value));
- }
+ public static final <M extends AbstractFactoryManager> M configureSignatures(M manager, String value, boolean lenient) {
+ ValidateUtils.checkNotNull(manager, "No manager to configure", GenericUtils.EMPTY_OBJECT_ARRAY);
- {
- String value=props.getProperty(CIPHERS_CONFIG_PROP, DEFAULT_CIPHERS);
- manager.setCipherFactories(ValidateUtils.checkNotNullAndNotEmpty(BuiltinCiphers.parseCiphersList(value), "Bad ciphers(s): %s", value));
- }
+ BuiltinSignatures.ParseResult result=BuiltinSignatures.parseSignatureList(value);
+ Collection<String> unsupported=result.getUnsupportedFactories();
+ ValidateUtils.checkTrue(lenient || GenericUtils.isEmpty(unsupported), "Unsupported signatures (%s) in %s", unsupported, value);
+ manager.setSignatureFactories(ValidateUtils.checkNotNullAndNotEmpty(result.getParsedFactories(), "No known signatures: %s", value));
+ return manager;
+ }
+
+ public static final <M extends AbstractFactoryManager> M configureMacs(M manager, Properties props, boolean lenient) {
+ ValidateUtils.checkNotNull(props, "No properties to configure", GenericUtils.EMPTY_OBJECT_ARRAY);
+ return configureMacs(manager, props.getProperty(MACS_CONFIG_PROP, DEFAULT_MACS), lenient);
+ }
+
+ public static final <M extends AbstractFactoryManager> M configureMacs(M manager, String value, boolean lenient) {
+ ValidateUtils.checkNotNull(manager, "No manager to configure", GenericUtils.EMPTY_OBJECT_ARRAY);
+
+ BuiltinMacs.ParseResult result=BuiltinMacs.parseMacsList(value);
+ Collection<String> unsupported=result.getUnsupportedFactories();
+ ValidateUtils.checkTrue(lenient || GenericUtils.isEmpty(unsupported), "Unsupported MAC(s) (%s) in %s", unsupported, value);
+ manager.setMacFactories(ValidateUtils.checkNotNullAndNotEmpty(result.getParsedFactories(), "No known MAC(s): %s", value));
+ return manager;
+ }
+
+ // NOTE: if no compression is resolved it is OK since SSH can function without it
+ public static final <M extends AbstractFactoryManager> M configureCompression(M manager, Properties props, boolean lenient) {
+ ValidateUtils.checkNotNull(props, "No properties to configure", GenericUtils.EMPTY_OBJECT_ARRAY);
+ return configureCompression(manager, props.getProperty(COMPRESSION_PROP, DEFAULT_COMPRESSION), lenient);
+ }
+
+ public static final <M extends AbstractFactoryManager> M configureCompression(M manager, String value, boolean lenient) {
+ ValidateUtils.checkNotNull(manager, "No manager to configure", GenericUtils.EMPTY_OBJECT_ARRAY);
- {
- String value=props.getProperty(COMPRESSION_PROP, DEFAULT_COMPRESSION);
- manager.setCompressionFactories(
- Collections.<NamedFactory<Compression>>singletonList(
- ValidateUtils.checkNotNull(CompressionConfigValue.fromName(value), "Bad compression: %s", value)));
+ NamedFactory<Compression> factory=CompressionConfigValue.fromName(value);
+ ValidateUtils.checkTrue(lenient || (factory != null), "Unsupported compression value: %s", value);
+ if (factory != null) {
+ manager.setCompressionFactories(Collections.<NamedFactory<Compression>>singletonList(factory));
}
return manager;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/digest/BuiltinDigests.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/digest/BuiltinDigests.java b/sshd-core/src/main/java/org/apache/sshd/common/digest/BuiltinDigests.java
index 8b342ba..2b90287 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/digest/BuiltinDigests.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/digest/BuiltinDigests.java
@@ -135,7 +135,7 @@ public enum BuiltinDigests implements NamedFactory<Digest> {
return null;
}
- private static class Constants {
+ public static final class Constants {
public static final String MD5 = "md5";
public static final String SHA1 = "sha1";
public static final String SHA256 = "sha256";
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/kex/BuiltinDHFactories.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/BuiltinDHFactories.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/BuiltinDHFactories.java
index 452dc5f..be29fa2 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/kex/BuiltinDHFactories.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/BuiltinDHFactories.java
@@ -30,10 +30,10 @@ import java.util.Set;
import org.apache.sshd.common.OptionalFeature;
import org.apache.sshd.common.cipher.ECCurves;
+import org.apache.sshd.common.config.NamedResourceListParseResult;
import org.apache.sshd.common.digest.BuiltinDigests;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.SecurityUtils;
-import org.apache.sshd.common.util.ValidateUtils;
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
@@ -191,35 +191,64 @@ public enum BuiltinDHFactories implements DHFactory, OptionalFeature {
}
/**
- * @param factories A comma-separated list of ciphers' names - ignored
+ * @param dhList A comma-separated list of ciphers' names - ignored
* if {@code null}/empty
- * @return A {@link List} of all the {@link DHFactory}-ies whose
+ * @return A {@link ParseResult} of all the {@link DHFactory}-ies whose
* name appears in the string and represent a built-in value. Any
* unknown name is <U>ignored</U>. The order of the returned result
* is the same as the original order - bar the unknown ones.
* <B>Note:</B> it is up to caller to ensure that the list does not
* contain duplicates
*/
- public static final List<DHFactory> parseDHFactoriesList(String factories) {
- return parseDHFactoriesList(GenericUtils.split(factories, ','));
+ public static final ParseResult parseDHFactoriesList(String dhList) {
+ return parseDHFactoriesList(GenericUtils.split(dhList, ','));
}
- public static final List<DHFactory> parseDHFactoriesList(String ... factories) {
- return parseDHFactoriesList(GenericUtils.isEmpty((Object[]) factories) ? Collections.<String>emptyList() : Arrays.asList(factories));
+ public static final ParseResult parseDHFactoriesList(String ... dhList) {
+ return parseDHFactoriesList(GenericUtils.isEmpty((Object[]) dhList) ? Collections.<String>emptyList() : Arrays.asList(dhList));
}
- public static final List<DHFactory> parseDHFactoriesList(Collection<String> factories) {
- if (GenericUtils.isEmpty(factories)) {
- return Collections.emptyList();
+ public static final ParseResult parseDHFactoriesList(Collection<String> dhList) {
+ if (GenericUtils.isEmpty(dhList)) {
+ return ParseResult.EMPTY;
}
- List<DHFactory> result=new ArrayList<DHFactory>(factories.size());
- for (String name : factories) {
- DHFactory c=ValidateUtils.checkNotNull(fromFactoryName(name), "Unknown factory name (%s) in %s", name, factories);
- result.add(c);
+ List<DHFactory> factories=new ArrayList<DHFactory>(dhList.size());
+ List<String> unknown=Collections.<String>emptyList();
+ for (String name : dhList) {
+ DHFactory f=fromFactoryName(name);
+ if (f != null) {
+ factories.add(f);
+ } else {
+ // replace the (unmodifiable) empty list with a real one
+ if (unknown.isEmpty()) {
+ unknown = new ArrayList<String>();
+ }
+ unknown.add(name);
+ }
}
- return result;
+ return new ParseResult(factories, unknown);
+ }
+
+ /**
+ * Represents the result of {@link BuiltinDHFactories#parseDHFactoriesList(String)}
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+ public static final class ParseResult extends NamedResourceListParseResult<DHFactory> {
+ public static final ParseResult EMPTY=new ParseResult(Collections.<DHFactory>emptyList(), Collections.<String>emptyList());
+
+ public ParseResult(List<DHFactory> parsed, List<String> unsupported) {
+ super(parsed, unsupported);
+ }
+
+ public List<DHFactory> getParsedFactories() {
+ return getParsedResources();
+ }
+
+ public List<String> getUnsupportedFactories() {
+ return getUnsupportedResources();
+ }
}
public static final class Constants {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java b/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
index e8d9239..5756dc5 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/mac/BuiltinMacs.java
@@ -32,7 +32,6 @@ import org.apache.sshd.common.Mac;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.OptionalFeature;
import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.ValidateUtils;
/**
* Provides easy access to the currently implemented macs
@@ -156,33 +155,58 @@ public enum BuiltinMacs implements NamedFactory<Mac>, OptionalFeature {
/**
* @param macs A comma-separated list of MACs' names - ignored
* if {@code null}/empty
- * @return A {@link List} of all the {@link NamedFactory}-ies whose
- * name appears in the string and represent a built-in MAC. Any
- * unknown name is <U>ignored</U>. The order of the returned result
- * is the same as the original order - bar the unknown MACs.
- * <B>Note:</B> it is up to caller to ensure that the list does not
- * contain duplicates
+ * @return A {@link ParseResult} containing the successfully parsed
+ * factories and the unknown ones. <B>Note:</B> it is up to caller to
+ * ensure that the lists do not contain duplicates
*/
- public static final List<NamedFactory<Mac>> parseMacsList(String macs) {
+ public static final ParseResult parseMacsList(String macs) {
return parseMacsList(GenericUtils.split(macs, ','));
}
- public static final List<NamedFactory<Mac>> parseMacsList(String ... macs) {
+ public static final ParseResult parseMacsList(String ... macs) {
return parseMacsList(GenericUtils.isEmpty((Object[]) macs) ? Collections.<String>emptyList() : Arrays.asList(macs));
}
- public static final List<NamedFactory<Mac>> parseMacsList(Collection<String> macs) {
+ public static final ParseResult parseMacsList(Collection<String> macs) {
if (GenericUtils.isEmpty(macs)) {
- return Collections.emptyList();
+ return ParseResult.EMPTY;
}
- List<NamedFactory<Mac>> result=new ArrayList<NamedFactory<Mac>>(macs.size());
+ List<NamedFactory<Mac>> factories=new ArrayList<NamedFactory<Mac>>(macs.size());
+ List<String> unknown=Collections.<String>emptyList();
for (String name : macs) {
- BuiltinMacs m=ValidateUtils.checkNotNull(fromFactoryName(name), "Bad factory name (%s) in %s", name, macs);
- result.add(m);
+ BuiltinMacs m=fromFactoryName(name);
+ if (m != null) {
+ factories.add(m);
+ } else {
+ // replace the (unmodifiable) empty list with a real one
+ if (unknown.isEmpty()) {
+ unknown = new ArrayList<String>();
+ }
+ unknown.add(name);
+ }
}
- return result;
+ return new ParseResult(factories, unknown);
+ }
+
+ public static final class ParseResult {
+ public static final ParseResult EMPTY=new ParseResult(Collections.<NamedFactory<Mac>>emptyList(), Collections.<String>emptyList());
+ private final List<NamedFactory<Mac>> parsed;
+ private final List<String> unsupported;
+
+ public ParseResult(List<NamedFactory<Mac>> parsed, List<String> unsupported) {
+ this.parsed = parsed;
+ this.unsupported = unsupported;
+ }
+
+ public List<NamedFactory<Mac>> getParsedFactories() {
+ return parsed;
+ }
+
+ public List<String> getUnsupportedFactories() {
+ return unsupported;
+ }
}
public static final class Constants {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/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 15f01ba..0903c39 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
@@ -18,6 +18,15 @@
*/
package org.apache.sshd.common.session;
+import static org.apache.sshd.common.SshConstants.SSH_MSG_DEBUG;
+import static org.apache.sshd.common.SshConstants.SSH_MSG_DISCONNECT;
+import static org.apache.sshd.common.SshConstants.SSH_MSG_IGNORE;
+import static org.apache.sshd.common.SshConstants.SSH_MSG_KEXINIT;
+import static org.apache.sshd.common.SshConstants.SSH_MSG_NEWKEYS;
+import static org.apache.sshd.common.SshConstants.SSH_MSG_SERVICE_ACCEPT;
+import static org.apache.sshd.common.SshConstants.SSH_MSG_SERVICE_REQUEST;
+import static org.apache.sshd.common.SshConstants.SSH_MSG_UNIMPLEMENTED;
+
import java.io.IOException;
import java.io.InterruptedIOException;
import java.util.LinkedList;
@@ -39,6 +48,7 @@ import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.KeyExchange;
import org.apache.sshd.common.Mac;
import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.Random;
import org.apache.sshd.common.Service;
import org.apache.sshd.common.Session;
@@ -57,15 +67,6 @@ import org.apache.sshd.common.util.CloseableUtils;
import org.apache.sshd.common.util.EventListenerUtils;
import org.apache.sshd.common.util.Readable;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_DEBUG;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_DISCONNECT;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_IGNORE;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_KEXINIT;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_NEWKEYS;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_SERVICE_ACCEPT;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_SERVICE_REQUEST;
-import static org.apache.sshd.common.SshConstants.SSH_MSG_UNIMPLEMENTED;
-
/**
* The AbstractSession handles all the basic SSH protocol such as key exchange, authentication,
* encoding and decoding. Both server side and client side sessions should inherit from this
@@ -873,14 +874,14 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea
*/
protected String[] createProposal(String hostKeyTypes) {
return new String[] {
- NamedFactory.Utils.getNames(factoryManager.getKeyExchangeFactories()),
+ NamedResource.Utils.getNames(factoryManager.getKeyExchangeFactories()),
hostKeyTypes,
- NamedFactory.Utils.getNames(factoryManager.getCipherFactories()),
- NamedFactory.Utils.getNames(factoryManager.getCipherFactories()),
- NamedFactory.Utils.getNames(factoryManager.getMacFactories()),
- NamedFactory.Utils.getNames(factoryManager.getMacFactories()),
- NamedFactory.Utils.getNames(factoryManager.getCompressionFactories()),
- NamedFactory.Utils.getNames(factoryManager.getCompressionFactories()),
+ NamedResource.Utils.getNames(factoryManager.getCipherFactories()),
+ NamedResource.Utils.getNames(factoryManager.getCipherFactories()),
+ NamedResource.Utils.getNames(factoryManager.getMacFactories()),
+ NamedResource.Utils.getNames(factoryManager.getMacFactories()),
+ NamedResource.Utils.getNames(factoryManager.getCompressionFactories()),
+ NamedResource.Utils.getNames(factoryManager.getCompressionFactories()),
"",
""
};
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
index 2aee77d..23f72c0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/BuiltinSignatures.java
@@ -36,7 +36,6 @@ import org.apache.sshd.common.Signature;
import org.apache.sshd.common.cipher.ECCurves;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.SecurityUtils;
-import org.apache.sshd.common.util.ValidateUtils;
/**
* Provides easy access to the currently implemented signatures
@@ -179,32 +178,60 @@ public enum BuiltinSignatures implements NamedFactory<Signature>, OptionalFeatur
/**
* @param sigs A comma-separated list of signatures' names - ignored
* if {@code null}/empty
- * @return A {@link List} of all the {@link NamedFactory} whose
+ * @return A {@link ParseResult} of all the {@link NamedFactory} whose
* name appears in the string and represent a built-in signature. Any
* unknown name is <U>ignored</I>. The order of the returned result
* is the same as the original order - bar the unknown signatures.
* <B>Note:</B> it is up to caller to ensure that the list does not
* contain duplicates
*/
- public static final List<NamedFactory<Signature>> parseSignatureList(String sigs) {
+ public static final ParseResult parseSignatureList(String sigs) {
return parseSignatureList(GenericUtils.split(sigs, ','));
}
- public static final List<NamedFactory<Signature>> parseSignatureList(String ... sigs) {
+ public static final ParseResult parseSignatureList(String ... sigs) {
return parseSignatureList(GenericUtils.isEmpty((Object[]) sigs) ? Collections.<String>emptyList() : Arrays.asList(sigs));
}
- public static final List<NamedFactory<Signature>> parseSignatureList(Collection<String> sigs) {
+ public static final ParseResult parseSignatureList(Collection<String> sigs) {
if (GenericUtils.isEmpty(sigs)) {
- return Collections.emptyList();
+ return ParseResult.EMPTY;
}
- List<NamedFactory<Signature>> result=new ArrayList<NamedFactory<Signature>>(sigs.size());
+ List<NamedFactory<Signature>> factories=new ArrayList<NamedFactory<Signature>>(sigs.size());
+ List<String> unknown=Collections.<String>emptyList();
for (String name : sigs) {
- BuiltinSignatures s=ValidateUtils.checkNotNull(fromFactoryName(name), "Bad factory name (%s) in %s", name, sigs);
- result.add(s);
+ BuiltinSignatures s=fromFactoryName(name);
+ if (s != null) {
+ factories.add(s);
+ } else {
+ // replace the (unmodifiable) empty list with a real one
+ if (unknown.isEmpty()) {
+ unknown = new ArrayList<String>();
+ }
+ unknown.add(name);
+ }
}
- return result;
+ return new ParseResult(factories, unknown);
+ }
+
+ public static final class ParseResult {
+ public static final ParseResult EMPTY=new ParseResult(Collections.<NamedFactory<Signature>>emptyList(), Collections.<String>emptyList());
+ private final List<NamedFactory<Signature>> parsed;
+ private final List<String> unsupported;
+
+ public ParseResult(List<NamedFactory<Signature>> parsed, List<String> unsupported) {
+ this.parsed = parsed;
+ this.unsupported = unsupported;
+ }
+
+ public List<NamedFactory<Signature>> getParsedFactories() {
+ return parsed;
+ }
+
+ public List<String> getUnsupportedFactories() {
+ return unsupported;
+ }
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/main/java/org/apache/sshd/common/util/ValidateUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/ValidateUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/ValidateUtils.java
index f856ea9..9e270ab 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/ValidateUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/ValidateUtils.java
@@ -27,43 +27,37 @@ import java.util.Map;
*/
public class ValidateUtils {
public static final <T> T checkNotNull(T t, String message, Object ... args) {
- if (t == null) {
- throw new IllegalStateException(String.format(message, args));
- }
+ checkTrue(t != null, message, args);
return t;
}
public static final String checkNotNullAndNotEmpty(String t, String message, Object ... args) {
t = checkNotNull(t, message, args).trim();
- if (t.isEmpty()) {
- throw new IllegalArgumentException(String.format(message, args));
- }
+ checkTrue(GenericUtils.length(t) > 0, message, args);
return t;
}
public static final <K,V,M extends Map<K,V>> M checkNotNullAndNotEmpty(M t, String message, Object ... args) {
t = checkNotNull(t, message, args);
- if (GenericUtils.size(t) <= 0) {
- throw new IllegalArgumentException(String.format(message, args));
- }
-
+ checkTrue(GenericUtils.size(t) > 0, message, args);
return t;
}
public static final <T,C extends Collection<T>> C checkNotNullAndNotEmpty(C t, String message, Object ... args) {
t = checkNotNull(t, message, args);
- if (GenericUtils.size(t) <= 0) {
- throw new IllegalArgumentException(String.format(message, args));
- }
-
+ checkTrue(GenericUtils.size(t) > 0, message, args);
return t;
}
public static final <T> T[] checkNotNullAndNotEmpty(T[] t, String message, Object ... args) {
t = checkNotNull(t, message, args);
- if (GenericUtils.length(t) <= 0) {
- throw new IllegalArgumentException(String.format(message, t, args));
- }
+ checkTrue(GenericUtils.length(t) > 0, message, args);
return t;
}
+
+ public static final void checkTrue(boolean flag, String message, Object ... args) {
+ if (!flag) {
+ throw new IllegalArgumentException(String.format(message, args));
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/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 fa87cb4..0a779a7 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
@@ -25,7 +25,7 @@ import java.util.List;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.FactoryManagerUtils;
import org.apache.sshd.common.KeyPairProvider;
-import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.ServiceFactory;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshException;
@@ -109,8 +109,8 @@ public class ServerSession extends AbstractSession {
FactoryManager manager = getFactoryManager();
KeyPairProvider kpp = manager.getKeyPairProvider();
String hostKeyTypes = kpp.getKeyTypes();
- List<String> supported = NamedFactory.Utils.getNameList(manager.getSignatureFactories());
- String[] provided = hostKeyTypes.split(",");
+ List<String> supported = NamedResource.Utils.getNameList(manager.getSignatureFactories());
+ String[] provided = GenericUtils.split(hostKeyTypes, ',');
StringBuilder resolvedHostKeys = null;
for (int index = 0; index < provided.length; index++) {
String keyType = provided[index];
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/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 8929896..49d7712 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
@@ -28,6 +28,7 @@ import org.apache.sshd.SshServer;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.FactoryManagerUtils;
import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.Service;
import org.apache.sshd.common.ServiceFactory;
import org.apache.sshd.common.Session;
@@ -81,7 +82,7 @@ public class ServerUserAuthService extends CloseableUtils.AbstractCloseable impl
authMethods = new ArrayList<>();
ServerFactoryManager manager=getFactoryManager();
- String mths = FactoryManagerUtils.getString(manager, SshServer.AUTH_METHODS);
+ String mths = FactoryManagerUtils.getString(manager, ServerFactoryManager.AUTH_METHODS);
if (GenericUtils.isEmpty(mths)) {
for (NamedFactory<UserAuth> uaf : manager.getUserAuthFactories()) {
authMethods.add(new ArrayList<>(Collections.singletonList(uaf.getName())));
@@ -101,11 +102,12 @@ public class ServerUserAuthService extends CloseableUtils.AbstractCloseable impl
}
if (log.isDebugEnabled()) {
- log.debug("Authorized authentication methods: {}", NamedFactory.Utils.getNames(userAuthFactories));
+ log.debug("Authorized authentication methods: {}", NamedResource.Utils.getNames(userAuthFactories));
}
}
public void start() {
+ // do nothing
}
public ServerSession getSession() {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java b/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java
index 4046d15..d7204de 100644
--- a/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/SshBuilderTest.java
@@ -27,6 +27,7 @@ import java.util.Set;
import org.apache.sshd.SshBuilder.BaseBuilder;
import org.apache.sshd.common.Cipher;
import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.cipher.BuiltinCiphers;
import org.apache.sshd.common.kex.BuiltinDHFactories;
import org.apache.sshd.common.mac.BuiltinMacs;
@@ -114,7 +115,7 @@ public class SshBuilderTest extends BaseTest {
}
// make sure order is according to the default preference list
- List<String> cipherNames=NamedFactory.Utils.getNameList(ciphers);
+ List<String> cipherNames=NamedResource.Utils.getNameList(ciphers);
int nameIndex=0;
for (BuiltinCiphers c : BaseBuilder.DEFAULT_CIPHERS_PREFERENCE) {
if ((!c.isSupported()) && (!ignoreUnsupported)) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java b/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
index e90e64a..4a70140 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/cipher/BuiltinCiphersTest.java
@@ -20,11 +20,19 @@
package org.apache.sshd.common.cipher;
import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.EnumSet;
+import java.util.List;
+import java.util.Random;
import java.util.Set;
import org.apache.sshd.common.Cipher;
import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.cipher.BuiltinCiphers.ParseResult;
+import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.util.BaseTest;
import org.junit.Assert;
import org.junit.Test;
@@ -106,4 +114,40 @@ public class BuiltinCiphersTest extends BaseTest {
cipher.init(Cipher.Mode.Encrypt, key, iv);
}
}
+
+ @Test
+ public void testParseCiphersList() {
+ List<String> builtin=NamedResource.Utils.getNameList(BuiltinCiphers.VALUES);
+ List<String> unknown=Arrays.asList(getClass().getPackage().getName(), getClass().getSimpleName(), getCurrentTestName());
+ Random rnd=new Random();
+ for (int index=0; index < (builtin.size() + unknown.size()); index++) {
+ Collections.shuffle(builtin, rnd);
+ Collections.shuffle(unknown, rnd);
+
+ List<String> weavedList=new ArrayList<String>(builtin.size() + unknown.size());
+ for (int bIndex=0, uIndex=0; (bIndex < builtin.size()) || (uIndex < unknown.size()); ) {
+ boolean useBuiltin=false;
+ if (bIndex < builtin.size()) {
+ useBuiltin = (uIndex < unknown.size()) ? rnd.nextBoolean() : true;
+ }
+
+ if (useBuiltin) {
+ weavedList.add(builtin.get(bIndex));
+ bIndex++;
+ } else if (uIndex < unknown.size()){
+ weavedList.add(unknown.get(uIndex));
+ uIndex++;
+ }
+ }
+
+ String fullList=GenericUtils.join(weavedList, ',');
+ ParseResult result=BuiltinCiphers.parseCiphersList(fullList);
+ List<String> parsed=NamedResource.Utils.getNameList(result.getParsedFactories());
+ List<String> missing=result.getUnsupportedFactories();
+
+ // makes sure not only that the contents are the same but also the order
+ assertListEquals(fullList + "[parsed]", builtin, parsed);
+ assertListEquals(fullList + "[unsupported]", unknown, missing);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/test/java/org/apache/sshd/common/config/SshConfigFileReaderTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/config/SshConfigFileReaderTest.java b/sshd-core/src/test/java/org/apache/sshd/common/config/SshConfigFileReaderTest.java
index f47666e..e3cfcb3 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/config/SshConfigFileReaderTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/config/SshConfigFileReaderTest.java
@@ -22,11 +22,24 @@ package org.apache.sshd.common.config;
import java.io.IOException;
import java.net.URL;
import java.util.Collection;
+import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.apache.sshd.SshBuilder;
+import org.apache.sshd.common.AbstractFactoryManager;
+import org.apache.sshd.common.Cipher;
+import org.apache.sshd.common.Closeable;
+import org.apache.sshd.common.FactoryManager;
+import org.apache.sshd.common.Mac;
+import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.Signature;
+import org.apache.sshd.common.cipher.BuiltinCiphers;
+import org.apache.sshd.common.compression.Compression;
+import org.apache.sshd.common.kex.BuiltinDHFactories;
+import org.apache.sshd.common.mac.BuiltinMacs;
+import org.apache.sshd.common.signature.BuiltinSignatures;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.util.BaseTest;
import org.junit.Assert;
@@ -60,29 +73,33 @@ public class SshConfigFileReaderTest extends BaseTest {
@Test
public void testParseCiphersList() {
List<? extends NamedResource> expected=SshBuilder.BaseBuilder.DEFAULT_CIPHERS_PREFERENCE;
- Properties props=initProperties(SshConfigFileReader.CIPHERS_CONFIG_PROP, expected);
- testParsedFactoriesList(expected, SshConfigFileReader.getCiphers(props));
+ Properties props=initNamedResourceProperties(SshConfigFileReader.CIPHERS_CONFIG_PROP, expected);
+ BuiltinCiphers.ParseResult result=SshConfigFileReader.getCiphers(props);
+ testParsedFactoriesList(expected, result.getParsedFactories(), result.getUnsupportedFactories());
}
@Test
public void testParseMacsList() {
List<? extends NamedResource> expected=SshBuilder.BaseBuilder.DEFAULT_MAC_PREFERENCE;
- Properties props=initProperties(SshConfigFileReader.MACS_CONFIG_PROP, expected);
- testParsedFactoriesList(expected, SshConfigFileReader.getMacs(props));
+ Properties props=initNamedResourceProperties(SshConfigFileReader.MACS_CONFIG_PROP, expected);
+ BuiltinMacs.ParseResult result=SshConfigFileReader.getMacs(props);
+ testParsedFactoriesList(expected, result.getParsedFactories(), result.getUnsupportedFactories());
}
@Test
public void testParseSignaturesList() {
List<? extends NamedResource> expected=SshBuilder.BaseBuilder.DEFAULT_SIGNATURE_PREFERENCE;
- Properties props=initProperties(SshConfigFileReader.HOST_KEY_ALGORITHMS_CONFIG_PROP, expected);
- testParsedFactoriesList(expected, SshConfigFileReader.getSignatures(props));
+ Properties props=initNamedResourceProperties(SshConfigFileReader.HOST_KEY_ALGORITHMS_CONFIG_PROP, expected);
+ BuiltinSignatures.ParseResult result=SshConfigFileReader.getSignatures(props);
+ testParsedFactoriesList(expected, result.getParsedFactories(), result.getUnsupportedFactories());
}
@Test
public void testParseKexFactoriesList() {
List<? extends NamedResource> expected=SshBuilder.BaseBuilder.DEFAULT_KEX_PREFERENCE;
- Properties props=initProperties(SshConfigFileReader.KEX_ALGORITHMS_CONFIG_PROP, expected);
- testParsedFactoriesList(expected, SshConfigFileReader.getKexFactories(props));
+ Properties props=initNamedResourceProperties(SshConfigFileReader.KEX_ALGORITHMS_CONFIG_PROP, expected);
+ BuiltinDHFactories.ParseResult result=SshConfigFileReader.getKexFactories(props);
+ testParsedFactoriesList(expected, result.getParsedFactories(), result.getUnsupportedFactories());
}
@Test
@@ -97,7 +114,129 @@ public class SshConfigFileReaderTest extends BaseTest {
}
}
- private static <T extends NamedResource> List<T> testParsedFactoriesList(List<? extends NamedResource> expected, List<T> actual) {
+ @Test
+ public void testConfigureAbstractFactoryManagerWithDefaults() {
+ Properties props=new Properties(); // empty means use defaults
+ AbstractFactoryManager expected=new AbstractFactoryManager() {
+ @Override
+ protected Closeable getInnerCloseable() {
+ return null;
+ }
+ };
+ // must be lenient since we do not cover the full default spectrum
+ AbstractFactoryManager actual=SshConfigFileReader.configure(expected, props, true);
+ Assert.assertSame("Mismatched configured result", expected, actual);
+ validateAbstractFactoryManagerConfiguration(expected, props, true);
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testNonLenientCiphersConfiguration() {
+ FactoryManager manager=SshConfigFileReader.configureCiphers(
+ new AbstractFactoryManager() {
+ @Override
+ protected Closeable getInnerCloseable() {
+ return null;
+ }
+ },
+ getCurrentTestName(),
+ false);
+ Assert.fail("Unexpected success: " + NamedResource.Utils.getNames(manager.getCipherFactories()));
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testNonLenientSignaturesConfiguration() {
+ FactoryManager manager=SshConfigFileReader.configureSignatures(
+ new AbstractFactoryManager() {
+ @Override
+ protected Closeable getInnerCloseable() {
+ return null;
+ }
+ },
+ getCurrentTestName(),
+ false);
+ Assert.fail("Unexpected success: " + NamedResource.Utils.getNames(manager.getSignatureFactories()));
+ }
+
+ @Test(expected=IllegalArgumentException.class)
+ public void testNonLenientMacsConfiguration() {
+ FactoryManager manager=SshConfigFileReader.configureMacs(
+ new AbstractFactoryManager() {
+ @Override
+ protected Closeable getInnerCloseable() {
+ return null;
+ }
+ },
+ getCurrentTestName(),
+ false);
+ Assert.fail("Unexpected success: " + NamedResource.Utils.getNames(manager.getMacFactories()));
+ }
+
+ private static <M extends FactoryManager> M validateAbstractFactoryManagerConfiguration(M manager, Properties props, boolean lenient) {
+ validateFactoryManagerCiphers(manager, props);
+ validateFactoryManagerSignatures(manager, props);
+ validateFactoryManagerMacs(manager, props);
+ validateFactoryManagerCompressions(manager, props, lenient);
+ return manager;
+ }
+
+ private static <M extends FactoryManager> M validateFactoryManagerCiphers(M manager, Properties props) {
+ return validateFactoryManagerCiphers(manager, props.getProperty(SshConfigFileReader.CIPHERS_CONFIG_PROP, SshConfigFileReader.DEFAULT_CIPHERS));
+ }
+
+ private static <M extends FactoryManager> M validateFactoryManagerCiphers(M manager, String value) {
+ BuiltinCiphers.ParseResult result=BuiltinCiphers.parseCiphersList(value);
+ validateFactoryManagerFactories(Cipher.class, result.getParsedFactories(), manager.getCipherFactories());
+ return manager;
+ }
+
+ private static <M extends FactoryManager> M validateFactoryManagerSignatures(M manager, Properties props) {
+ return validateFactoryManagerSignatures(manager, props.getProperty(SshConfigFileReader.HOST_KEY_ALGORITHMS_CONFIG_PROP, SshConfigFileReader.DEFAULT_HOST_KEY_ALGORITHMS));
+ }
+
+ private static <M extends FactoryManager> M validateFactoryManagerSignatures(M manager, String value) {
+ BuiltinSignatures.ParseResult result=BuiltinSignatures.parseSignatureList(value);
+ validateFactoryManagerFactories(Signature.class, result.getParsedFactories(), manager.getSignatureFactories());
+ return manager;
+ }
+
+ private static <M extends FactoryManager> M validateFactoryManagerMacs(M manager, Properties props) {
+ return validateFactoryManagerMacs(manager, props.getProperty(SshConfigFileReader.MACS_CONFIG_PROP, SshConfigFileReader.DEFAULT_MACS));
+ }
+
+ private static <M extends FactoryManager> M validateFactoryManagerMacs(M manager, String value) {
+ BuiltinMacs.ParseResult result=BuiltinMacs.parseMacsList(value);
+ validateFactoryManagerFactories(Mac.class, result.getParsedFactories(), manager.getMacFactories());
+ return manager;
+ }
+
+ private static <M extends FactoryManager> M validateFactoryManagerCompressions(M manager, Properties props, boolean lenient) {
+ return validateFactoryManagerCompressions(manager, props.getProperty(SshConfigFileReader.COMPRESSION_PROP, SshConfigFileReader.DEFAULT_COMPRESSION), lenient);
+ }
+
+ private static <M extends FactoryManager> M validateFactoryManagerCompressions(M manager, String value, boolean lenient) {
+ NamedFactory<Compression> factory=CompressionConfigValue.fromName(value);
+ Assert.assertTrue("Unknown compression: " + value, lenient || (factory != null));
+ if (factory != null) {
+ validateFactoryManagerFactories(Compression.class, Collections.singletonList(factory), manager.getCompressionFactories());
+ }
+ return manager;
+ }
+
+ private static <T,F extends NamedFactory<T>> void validateFactoryManagerFactories(Class<T> type, List<? extends F> expected, List<? extends F> actual) {
+ validateFactoryManagerSettings(type, expected, actual);
+ }
+
+ private static <R extends NamedResource> void validateFactoryManagerSettings(Class<?> type, List<? extends R> expected, List<? extends R> actual) {
+ validateFactoryManagerSettings(type.getSimpleName(), expected, actual);
+ }
+
+ private static <R extends NamedResource> void validateFactoryManagerSettings(String type, List<? extends R> expected, List<? extends R> actual) {
+ assertListEquals(type, expected, actual);
+ }
+
+ private static <T extends NamedResource> List<T> testParsedFactoriesList(
+ List<? extends NamedResource> expected, List<T> actual, Collection<String> unsupported) {
+ Assert.assertTrue("Unexpected unsupported factories: " + unsupported, GenericUtils.isEmpty(unsupported));
Assert.assertEquals("Mismatched list size", expected.size(), GenericUtils.size(actual));
for (int index=0; index < expected.size(); index++) {
NamedResource e=expected.get(index), a=actual.get(index);
@@ -108,8 +247,8 @@ public class SshConfigFileReaderTest extends BaseTest {
return actual;
}
- private static Properties initProperties(String key, Collection<?> values) {
- return initProperties(key, GenericUtils.join(values, ','));
+ private static <R extends NamedResource> Properties initNamedResourceProperties(String key, Collection<? extends R> values) {
+ return initProperties(key, NamedResource.Utils.getNames(values));
}
private static Properties initProperties(String key, String value) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/cca7cc74/sshd-core/src/test/java/org/apache/sshd/common/kex/BuiltinDHFactoriesTest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/test/java/org/apache/sshd/common/kex/BuiltinDHFactoriesTest.java b/sshd-core/src/test/java/org/apache/sshd/common/kex/BuiltinDHFactoriesTest.java
index 61ebcf6..1dd77ce 100644
--- a/sshd-core/src/test/java/org/apache/sshd/common/kex/BuiltinDHFactoriesTest.java
+++ b/sshd-core/src/test/java/org/apache/sshd/common/kex/BuiltinDHFactoriesTest.java
@@ -20,9 +20,17 @@
package org.apache.sshd.common.kex;
import java.lang.reflect.Field;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
import java.util.EnumSet;
+import java.util.List;
+import java.util.Random;
import java.util.Set;
+import org.apache.sshd.common.NamedResource;
+import org.apache.sshd.common.kex.BuiltinDHFactories.ParseResult;
+import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.util.BaseTest;
import org.junit.Assert;
import org.junit.Test;
@@ -57,4 +65,40 @@ public class BuiltinDHFactoriesTest extends BaseTest {
Assert.assertEquals("Incomplete coverage", BuiltinDHFactories.VALUES, avail);
}
+
+ @Test
+ public void testParseDHFactorysList() {
+ List<String> builtin=NamedResource.Utils.getNameList(BuiltinDHFactories.VALUES);
+ List<String> unknown=Arrays.asList(getClass().getPackage().getName(), getClass().getSimpleName(), getCurrentTestName());
+ Random rnd=new Random();
+ for (int index=0; index < (builtin.size() + unknown.size()); index++) {
+ Collections.shuffle(builtin, rnd);
+ Collections.shuffle(unknown, rnd);
+
+ List<String> weavedList=new ArrayList<String>(builtin.size() + unknown.size());
+ for (int bIndex=0, uIndex=0; (bIndex < builtin.size()) || (uIndex < unknown.size()); ) {
+ boolean useBuiltin=false;
+ if (bIndex < builtin.size()) {
+ useBuiltin = (uIndex < unknown.size()) ? rnd.nextBoolean() : true;
+ }
+
+ if (useBuiltin) {
+ weavedList.add(builtin.get(bIndex));
+ bIndex++;
+ } else if (uIndex < unknown.size()){
+ weavedList.add(unknown.get(uIndex));
+ uIndex++;
+ }
+ }
+
+ String fullList=GenericUtils.join(weavedList, ',');
+ ParseResult result=BuiltinDHFactories.parseDHFactoriesList(fullList);
+ List<String> parsed=NamedResource.Utils.getNameList(result.getParsedFactories());
+ List<String> missing=result.getUnsupportedFactories();
+
+ // makes sure not only that the contents are the same but also the order
+ assertListEquals(fullList + "[parsed]", builtin, parsed);
+ assertListEquals(fullList + "[unsupported]", unknown, missing);
+ }
+ }
}