You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@mina.apache.org by lg...@apache.org on 2015/12/01 08:05:49 UTC
[2/3] mina-sshd git commit: [SSHD-533] Add support for SHA-224
(builtin) digest
[SSHD-533] Add support for SHA-224 (builtin) digest
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/7b18b090
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/7b18b090
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/7b18b090
Branch: refs/heads/master
Commit: 7b18b090347ef95ace18679ed71d76dbd549a756
Parents: 5fd4fba
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Tue Dec 1 09:04:11 2015 +0200
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Tue Dec 1 09:04:11 2015 +0200
----------------------------------------------------------------------
.../org/apache/sshd/client/kex/DHGEXClient.java | 4 +-
.../subsystem/sftp/SftpVersionSelector.java | 3 +-
.../impl/AbstractMD5HashExtension.java | 3 +-
.../extensions/impl/CopyDataExtensionImpl.java | 6 +-
.../openssh/impl/OpenSSHFsyncExtensionImpl.java | 4 +-
.../org/apache/sshd/common/OptionalFeature.java | 84 +++-
.../apache/sshd/common/cipher/BaseCipher.java | 4 +-
.../apache/sshd/common/cipher/CipherNone.java | 4 +-
.../org/apache/sshd/common/cipher/ECCurves.java | 35 +-
.../keys/AbstractPublicKeyEntryDecoder.java | 3 +-
.../config/keys/ECDSAPublicKeyEntryDecoder.java | 6 +-
.../sshd/common/config/keys/KeyUtils.java | 15 +-
.../sshd/common/config/keys/PublicKeyEntry.java | 5 +-
.../apache/sshd/common/digest/BaseDigest.java | 14 +-
.../sshd/common/digest/BuiltinDigests.java | 25 +-
.../sshd/common/digest/DigestFactory.java | 10 +-
.../apache/sshd/common/digest/DigestUtils.java | 5 +-
.../org/apache/sshd/common/kex/AbstractDH.java | 4 +-
.../sshd/common/kex/BuiltinDHFactories.java | 14 +-
.../java/org/apache/sshd/common/kex/DHG.java | 6 +-
.../org/apache/sshd/common/mac/BuiltinMacs.java | 5 +-
.../org/apache/sshd/common/scp/ScpHelper.java | 2 +-
.../sshd/common/session/AbstractSession.java | 3 +-
.../common/signature/AbstractSignature.java | 6 +-
.../common/signature/BuiltinSignatures.java | 5 +-
.../sshd/common/signature/SignatureDSA.java | 6 +-
.../sftp/extensions/AbstractParser.java | 4 +-
.../org/apache/sshd/common/util/Base64.java | 4 +-
.../sshd/common/util/DirectoryScanner.java | 380 ------------------
.../apache/sshd/common/util/GenericUtils.java | 38 --
.../apache/sshd/common/util/NumberUtils.java | 149 +++++++-
.../org/apache/sshd/common/util/OsUtils.java | 90 ++++-
.../apache/sshd/common/util/SecurityUtils.java | 11 +
.../apache/sshd/common/util/ValidateUtils.java | 8 +-
.../apache/sshd/common/util/VersionInfo.java | 137 +++++++
.../sshd/common/util/buffer/BufferUtils.java | 25 +-
.../apache/sshd/common/util/io/DERParser.java | 4 +-
.../apache/sshd/common/util/io/DERWriter.java | 4 +-
.../sshd/common/util/io/DirectoryScanner.java | 382 +++++++++++++++++++
.../sshd/server/auth/gss/UserAuthGSS.java | 4 +-
.../server/subsystem/sftp/SftpSubsystem.java | 76 +++-
.../sshd/client/subsystem/sftp/SftpTest.java | 22 +-
.../impl/AbstractCheckFileExtensionTest.java | 15 +-
.../impl/AbstractMD5HashExtensionTest.java | 7 +
.../keys/KeyUtilsFingerprintGenerationTest.java | 14 +-
.../sshd/common/config/keys/KeyUtilsTest.java | 34 +-
.../sshd/common/digest/BuiltinDigestsTest.java | 62 +++
.../apache/sshd/common/util/OsUtilsTest.java | 132 +++++++
.../sshd/common/util/SecurityUtilsTest.java | 31 ++
.../sshd/common/util/VersionInfoTest.java | 49 +++
.../apache/sshd/common/util/io/IoUtilsTest.java | 4 +-
51 files changed, 1386 insertions(+), 581 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
index cff00d8..8548dff 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGEXClient.java
@@ -84,7 +84,9 @@ public class DHGEXClient extends AbstractDHClientKeyExchange {
@Override
public void init(AbstractSession s, byte[] v_s, byte[] v_c, byte[] i_s, byte[] i_c) throws Exception {
super.init(s, v_s, v_c, i_s, i_c);
- log.debug("Send SSH_MSG_KEX_DH_GEX_REQUEST");
+ if (log.isDebugEnabled()) {
+ log.debug("init({}) Send SSH_MSG_KEX_DH_GEX_REQUEST", s);
+ }
Buffer buffer = s.createBuffer(SshConstants.SSH_MSG_KEX_DH_GEX_REQUEST);
buffer.putInt(min);
buffer.putInt(prf);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java
index 240950e..ccdf3ce 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/SftpVersionSelector.java
@@ -23,6 +23,7 @@ import java.util.Collection;
import java.util.List;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
import org.apache.sshd.common.util.ValidateUtils;
/**
@@ -124,7 +125,7 @@ public interface SftpVersionSelector {
* the most preferred version that is also listed as available.
*/
public static SftpVersionSelector preferredVersionSelector(final int ... preferred) {
- return preferredVersionSelector(GenericUtils.asList(preferred));
+ return preferredVersionSelector(NumberUtils.asList(preferred));
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractMD5HashExtension.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractMD5HashExtension.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractMD5HashExtension.java
index 61acb73..5548c65 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractMD5HashExtension.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/AbstractMD5HashExtension.java
@@ -26,6 +26,7 @@ import java.util.Collection;
import org.apache.sshd.client.subsystem.sftp.RawSftpClient;
import org.apache.sshd.client.subsystem.sftp.SftpClient;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.BufferUtils;
@@ -38,7 +39,7 @@ public abstract class AbstractMD5HashExtension extends AbstractSftpClientExtensi
}
protected byte[] doGetHash(Object target, long offset, long length, byte[] quickHash) throws IOException {
- Buffer buffer = getCommandBuffer(target, Long.SIZE + 2 * (Long.SIZE / Byte.SIZE) + (Integer.SIZE / Byte.SIZE) + GenericUtils.length(quickHash));
+ Buffer buffer = getCommandBuffer(target, Long.SIZE + 2 * (Long.SIZE / Byte.SIZE) + (Integer.SIZE / Byte.SIZE) + NumberUtils.length(quickHash));
String opcode = getName();
putTarget(buffer, target);
buffer.putLong(offset);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/CopyDataExtensionImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/CopyDataExtensionImpl.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/CopyDataExtensionImpl.java
index 0bb19d6..0d4ad89 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/CopyDataExtensionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/impl/CopyDataExtensionImpl.java
@@ -27,7 +27,7 @@ import org.apache.sshd.client.subsystem.sftp.SftpClient;
import org.apache.sshd.client.subsystem.sftp.SftpClient.Handle;
import org.apache.sshd.client.subsystem.sftp.extensions.CopyDataExtension;
import org.apache.sshd.common.subsystem.sftp.SftpConstants;
-import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
import org.apache.sshd.common.util.buffer.Buffer;
/**
@@ -42,8 +42,8 @@ public class CopyDataExtensionImpl extends AbstractSftpClientExtension implement
public void copyData(Handle readHandle, long readOffset, long readLength, Handle writeHandle, long writeOffset) throws IOException {
byte[] srcId = readHandle.getIdentifier();
byte[] dstId = writeHandle.getIdentifier();
- Buffer buffer = getCommandBuffer((Integer.SIZE / Byte.SIZE) + GenericUtils.length(srcId)
- + (Integer.SIZE / Byte.SIZE) + GenericUtils.length(dstId)
+ Buffer buffer = getCommandBuffer((Integer.SIZE / Byte.SIZE) + NumberUtils.length(srcId)
+ + (Integer.SIZE / Byte.SIZE) + NumberUtils.length(dstId)
+ (3 * (Long.SIZE + (Integer.SIZE / Byte.SIZE))));
buffer.putBytes(srcId);
buffer.putLong(readOffset);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/openssh/impl/OpenSSHFsyncExtensionImpl.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/openssh/impl/OpenSSHFsyncExtensionImpl.java b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/openssh/impl/OpenSSHFsyncExtensionImpl.java
index 8c70880..c650c78 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/openssh/impl/OpenSSHFsyncExtensionImpl.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/subsystem/sftp/extensions/openssh/impl/OpenSSHFsyncExtensionImpl.java
@@ -28,7 +28,7 @@ import org.apache.sshd.client.subsystem.sftp.SftpClient.Handle;
import org.apache.sshd.client.subsystem.sftp.extensions.impl.AbstractSftpClientExtension;
import org.apache.sshd.client.subsystem.sftp.extensions.openssh.OpenSSHFsyncExtension;
import org.apache.sshd.common.subsystem.sftp.extensions.openssh.FsyncExtensionParser;
-import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
import org.apache.sshd.common.util.buffer.Buffer;
/**
@@ -42,7 +42,7 @@ public class OpenSSHFsyncExtensionImpl extends AbstractSftpClientExtension imple
@Override
public void fsync(Handle fileHandle) throws IOException {
byte[] handle = fileHandle.getIdentifier();
- Buffer buffer = getCommandBuffer((Integer.SIZE / Byte.SIZE) + GenericUtils.length(handle));
+ Buffer buffer = getCommandBuffer((Integer.SIZE / Byte.SIZE) + NumberUtils.length(handle));
buffer.putBytes(handle);
sendAndCheckExtendedCommandStatus(buffer);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/OptionalFeature.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/OptionalFeature.java b/sshd-core/src/main/java/org/apache/sshd/common/OptionalFeature.java
index 9c5e396..43497eb 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/OptionalFeature.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/OptionalFeature.java
@@ -19,9 +19,91 @@
package org.apache.sshd.common;
+import java.util.Collection;
+
+import org.apache.sshd.common.util.GenericUtils;
+
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface OptionalFeature {
+public interface OptionalFeature { // TODO define this as a @FunctionalInterface in Java 8
+ OptionalFeature TRUE = new OptionalFeature() {
+ @Override
+ public boolean isSupported() {
+ return true;
+ }
+
+ @Override
+ public String toString() {
+ return "TRUE";
+ }
+ };
+
+ OptionalFeature FALSE = new OptionalFeature() {
+ @Override
+ public boolean isSupported() {
+ return false;
+ }
+
+ @Override
+ public String toString() {
+ return "FALSE";
+ }
+ };
+
boolean isSupported();
+
+ /**
+ * Utility class to help using {@link OptionalFeature}s
+ */
+ // CHECKSTYLE:OFF
+ final class Utils {
+ // CHECKSTYLE:ON
+
+ private Utils() {
+ throw new UnsupportedOperationException("No instance allowed");
+ }
+
+ public static OptionalFeature of(boolean supported) {
+ return supported ? TRUE : FALSE;
+ }
+
+ public static OptionalFeature all(final Collection<? extends OptionalFeature> features) {
+ return new OptionalFeature() {
+ @Override
+ public boolean isSupported() {
+ if (GenericUtils.isEmpty(features)) {
+ return false;
+ }
+
+ for (OptionalFeature f : features) {
+ if (!f.isSupported()) {
+ return false;
+ }
+ }
+
+ return true;
+ }
+ };
+ }
+
+ public static OptionalFeature any(final Collection<? extends OptionalFeature> features) {
+ return new OptionalFeature() {
+ @Override
+ public boolean isSupported() {
+ if (GenericUtils.isEmpty(features)) {
+ return false;
+ }
+
+ for (OptionalFeature f : features) {
+ if (f.isSupported()) {
+ return true;
+ }
+ }
+
+ return false;
+ }
+ };
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/cipher/BaseCipher.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/BaseCipher.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BaseCipher.java
index c6b534b..381825d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/BaseCipher.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/BaseCipher.java
@@ -22,7 +22,7 @@ import javax.crypto.spec.IvParameterSpec;
import javax.crypto.spec.SecretKeySpec;
import org.apache.sshd.common.SshException;
-import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.common.util.ValidateUtils;
@@ -83,7 +83,7 @@ public class BaseCipher implements Cipher {
@Override
public void update(byte[] input) throws Exception {
- update(input, 0, GenericUtils.length(input));
+ update(input, 0, NumberUtils.length(input));
}
@Override
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherNone.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherNone.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherNone.java
index 7f2c863..616e305 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherNone.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/CipherNone.java
@@ -18,7 +18,7 @@
*/
package org.apache.sshd.common.cipher;
-import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
/**
@@ -61,7 +61,7 @@ public class CipherNone implements Cipher {
@Override
public void update(byte[] input) throws Exception {
- update(input, 0, GenericUtils.length(input));
+ update(input, 0, NumberUtils.length(input));
}
@Override
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/cipher/ECCurves.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/cipher/ECCurves.java b/sshd-core/src/main/java/org/apache/sshd/common/cipher/ECCurves.java
index 6855ed9..34587b7 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/cipher/ECCurves.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/cipher/ECCurves.java
@@ -33,6 +33,7 @@ import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.OptionalFeature;
import org.apache.sshd.common.digest.BuiltinDigests;
import org.apache.sshd.common.digest.Digest;
+import org.apache.sshd.common.digest.DigestFactory;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.common.util.ValidateUtils;
@@ -54,12 +55,8 @@ public enum ECCurves implements NamedResource, OptionalFeature {
new BigInteger("4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5", 16)),
new BigInteger("FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551", 16),
1),
- 32) {
- @Override
- public Digest getDigestForParams() {
- return BuiltinDigests.sha256.create();
- }
- },
+ 32,
+ BuiltinDigests.sha256),
nistp384(Constants.NISTP384,
new ECParameterSpec(
new EllipticCurve(
@@ -71,12 +68,8 @@ public enum ECCurves implements NamedResource, OptionalFeature {
new BigInteger("3617DE4A96262C6F5D9E98BF9292DC29F8F41DBD289A147CE9DA3113B5F0B8C00A60B1CE1D7E819D7A431D7C90EA0E5F", 16)),
new BigInteger("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFC7634D81F4372DDF581A0DB248B0A77AECEC196ACCC52973", 16),
1),
- 48) {
- @Override
- public Digest getDigestForParams() {
- return BuiltinDigests.sha384.create();
- }
- },
+ 48,
+ BuiltinDigests.sha384),
nistp521(Constants.NISTP521,
new ECParameterSpec(
new EllipticCurve(
@@ -94,12 +87,8 @@ public enum ECCurves implements NamedResource, OptionalFeature {
new BigInteger("01FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFA51868783BF2F966B"
+ "7FCC0148F709A5D03BB5C9B8899C47AEBB6FB71E91386409", 16),
1),
- 66) {
- @Override
- public Digest getDigestForParams() {
- return BuiltinDigests.sha512.create();
- }
- };
+ 66,
+ BuiltinDigests.sha512);
/**
* A {@link Set} of all the known curves
@@ -140,13 +129,15 @@ public enum ECCurves implements NamedResource, OptionalFeature {
private final ECParameterSpec params;
private final int keySize;
private final int numOctets;
+ private final DigestFactory digestFactory;
- ECCurves(String name, ECParameterSpec params, int numOctets) {
+ ECCurves(String name, ECParameterSpec params, int numOctets, DigestFactory digestFactory) {
this.name = ValidateUtils.checkNotNullAndNotEmpty(name, "No curve name");
this.keyType = Constants.ECDSA_SHA2_PREFIX + name;
this.params = ValidateUtils.checkNotNull(params, "No EC params for %s", name);
this.keySize = getCurveSize(params);
this.numOctets = numOctets;
+ this.digestFactory = ValidateUtils.checkNotNull(digestFactory, "No digestFactory");
}
@Override // The curve name
@@ -163,7 +154,7 @@ public enum ECCurves implements NamedResource, OptionalFeature {
@Override
public final boolean isSupported() {
- return SecurityUtils.hasEcc();
+ return SecurityUtils.hasEcc() && digestFactory.isSupported();
}
public final ECParameterSpec getParameters() {
@@ -187,7 +178,9 @@ public enum ECCurves implements NamedResource, OptionalFeature {
/**
* @return The {@link Digest} to use when hashing the curve's parameters
*/
- public abstract Digest getDigestForParams();
+ public final Digest getDigestForParams() {
+ return digestFactory.create();
+ }
/**
* @param type The key type value - ignored if {@code null}/empty
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java
index 1fb988b..e89a944 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/AbstractPublicKeyEntryDecoder.java
@@ -39,6 +39,7 @@ import java.security.spec.KeySpec;
import java.util.Collection;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.io.IoUtils;
@@ -123,7 +124,7 @@ public abstract class AbstractPublicKeyEntryDecoder<PUB extends PublicKey, PRV e
@Override
public PUB decodePublicKey(byte... keyData) throws IOException, GeneralSecurityException {
- return decodePublicKey(keyData, 0, GenericUtils.length(keyData));
+ return decodePublicKey(keyData, 0, NumberUtils.length(keyData));
}
@Override
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/config/keys/ECDSAPublicKeyEntryDecoder.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/ECDSAPublicKeyEntryDecoder.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/ECDSAPublicKeyEntryDecoder.java
index e2a0318..e85d600 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/ECDSAPublicKeyEntryDecoder.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/ECDSAPublicKeyEntryDecoder.java
@@ -44,7 +44,7 @@ import java.util.EnumSet;
import java.util.Set;
import org.apache.sshd.common.cipher.ECCurves;
-import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.BufferUtils;
@@ -184,7 +184,7 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC
}
public static ECPoint octetStringToEcPoint(byte... octets) {
- if (GenericUtils.isEmpty(octets)) {
+ if (NumberUtils.isEmpty(octets)) {
return null;
}
@@ -204,7 +204,7 @@ public class ECDSAPublicKeyEntryDecoder extends AbstractPublicKeyEntryDecoder<EC
}
private static int findFirstNonZeroIndex(byte... octets) {
- if (GenericUtils.isEmpty(octets)) {
+ if (NumberUtils.isEmpty(octets)) {
return -1;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
index be9e0e0..bac5a3a 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/KeyUtils.java
@@ -98,9 +98,9 @@ public final class KeyUtils {
* overridden by {@link #OPENSSH_KEY_FINGERPRINT_FACTORY_PROP} or
* {@link #setDefaultFingerPrintFactory(Factory)}
*/
- public static final Factory<Digest> DEFAULT_FINGERPRINT_DIGEST_FACTORY = BuiltinDigests.sha256;
+ public static final DigestFactory DEFAULT_FINGERPRINT_DIGEST_FACTORY = BuiltinDigests.sha256;
- private static final AtomicReference<Factory<? extends Digest>> DEFAULT_DIGEST_HOLDER = new AtomicReference<>();
+ private static final AtomicReference<DigestFactory> DEFAULT_DIGEST_HOLDER = new AtomicReference<>();
private static final Map<String, PublicKeyEntryDecoder<?, ?>> BY_KEY_TYPE_DECODERS_MAP =
new TreeMap<String, PublicKeyEntryDecoder<?, ?>>(String.CASE_INSENSITIVE_ORDER);
@@ -366,14 +366,14 @@ public final class KeyUtils {
}
/**
- * @return The default {@link Factory} of {@link Digest}s used
+ * @return The default {@link DigestFactory}
* by the {@link #getFingerPrint(PublicKey)} and {@link #getFingerPrint(String)}
* methods
* @see #KEY_FINGERPRINT_FACTORY_PROP
* @see #setDefaultFingerPrintFactory(Factory)
*/
- public static Factory<? extends Digest> getDefaultFingerPrintFactory() {
- Factory<? extends Digest> factory = null;
+ public static DigestFactory getDefaultFingerPrintFactory() {
+ DigestFactory factory = null;
synchronized (DEFAULT_DIGEST_HOLDER) {
factory = DEFAULT_DIGEST_HOLDER.get();
if (factory != null) {
@@ -387,6 +387,7 @@ public final class KeyUtils {
factory = ValidateUtils.checkNotNull(BuiltinDigests.fromFactoryName(propVal), "Unknown digest factory: %s", propVal);
}
+ ValidateUtils.checkTrue(factory.isSupported(), "Selected fingerprint digest not supported: %s", factory.getName());
DEFAULT_DIGEST_HOLDER.set(factory);
}
@@ -394,10 +395,10 @@ public final class KeyUtils {
}
/**
- * @param f The {@link Factory} of {@link Digest}s to be used - may
+ * @param f The {@link DigestFactory} of {@link Digest}s to be used - may
* not be {@code null}
*/
- public static void setDefaultFingerPrintFactory(Factory<? extends Digest> f) {
+ public static void setDefaultFingerPrintFactory(DigestFactory f) {
synchronized (DEFAULT_DIGEST_HOLDER) {
DEFAULT_DIGEST_HOLDER.set(ValidateUtils.checkNotNull(f, "No digest factory"));
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java
index d2388ea..5ea14aa 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/config/keys/PublicKeyEntry.java
@@ -32,6 +32,7 @@ import java.util.Objects;
import org.apache.sshd.common.util.Base64;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
/**
* <P>Represents a {@link PublicKey} whose data is formatted according to
@@ -161,7 +162,7 @@ public class PublicKeyEntry implements Serializable {
@Override
public String toString() {
byte[] data = getKeyData();
- return getKeyType() + " " + (GenericUtils.isEmpty(data) ? "<no-key>" : Base64.encodeToString(data));
+ return getKeyType() + " " + (NumberUtils.isEmpty(data) ? "<no-key>" : Base64.encodeToString(data));
}
/**
@@ -206,7 +207,7 @@ public class PublicKeyEntry implements Serializable {
String keyType = data.substring(0, startPos);
String b64Data = data.substring(startPos + 1, endPos).trim();
byte[] keyData = Base64.decodeString(b64Data);
- if (GenericUtils.isEmpty(keyData)) {
+ if (NumberUtils.isEmpty(keyData)) {
throw new IllegalArgumentException("Bad format (no BASE64 key data): " + data);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/digest/BaseDigest.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/digest/BaseDigest.java b/sshd-core/src/main/java/org/apache/sshd/common/digest/BaseDigest.java
index 2553fd6..793f571 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/digest/BaseDigest.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/digest/BaseDigest.java
@@ -22,6 +22,7 @@ import java.security.MessageDigest;
import java.util.Objects;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.common.util.ValidateUtils;
@@ -71,17 +72,24 @@ public class BaseDigest implements Digest {
@Override
public void update(byte[] data) throws Exception {
- update(data, 0, GenericUtils.length(data));
+ update(data, 0, NumberUtils.length(data));
}
@Override
public void update(byte[] data, int start, int len) throws Exception {
- md.update(data, start, len);
+ ValidateUtils.checkNotNull(md, "Digest not initialized").update(data, start, len);
+ }
+
+ /**
+ * @return The current {@link MessageDigest} - may be {@code null} if {@link #init()} not called
+ */
+ protected MessageDigest getMessageDigest() {
+ return md;
}
@Override
public byte[] digest() throws Exception {
- return md.digest();
+ return ValidateUtils.checkNotNull(md, "Digest not initialized").digest();
}
@Override
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/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 cf61a78..19cd28c 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
@@ -26,15 +26,30 @@ import java.util.Set;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.OsUtils;
+import org.apache.sshd.common.util.SecurityUtils;
+import org.apache.sshd.common.util.VersionInfo;
/**
* Provides easy access to the currently implemented digests
*
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public enum BuiltinDigests implements DigestInformation, DigestFactory {
+public enum BuiltinDigests implements DigestFactory {
md5(Constants.MD5, "MD5", 16),
sha1(Constants.SHA1, "SHA-1", 20),
+ sha224(Constants.SHA224, "SHA-224", 28) {
+ @Override
+ public boolean isSupported() {
+ if (SecurityUtils.isBouncyCastleRegistered()) {
+ return true;
+ }
+
+ // SHA-224 was introduced in Java-8
+ VersionInfo version = OsUtils.getJavaVersion();
+ return version.getMinorVersion() >= 8;
+ }
+ },
sha256(Constants.SHA256, "SHA-256", 32),
sha384(Constants.SHA384, "SHA-384", 48),
sha512(Constants.SHA512, "SHA-512", 64);
@@ -77,6 +92,11 @@ public enum BuiltinDigests implements DigestInformation, DigestFactory {
return new BaseDigest(getAlgorithm(), getBlockSize());
}
+ @Override
+ public boolean isSupported() {
+ return true;
+ }
+
/**
* @param s The {@link Enum}'s name - ignored if {@code null}/empty
* @return The matching {@link org.apache.sshd.common.digest.BuiltinDigests} whose {@link Enum#name()} matches
@@ -102,7 +122,7 @@ public enum BuiltinDigests implements DigestInformation, DigestFactory {
* (case <U>insensitive</U>) the digest factory name
* @see #fromFactoryName(String)
*/
- public static BuiltinDigests fromFactory(NamedFactory<Digest> factory) {
+ public static BuiltinDigests fromFactory(NamedFactory<? extends Digest> factory) {
if (factory == null) {
return null;
} else {
@@ -140,6 +160,7 @@ public enum BuiltinDigests implements DigestInformation, DigestFactory {
public static final class Constants {
public static final String MD5 = "md5";
public static final String SHA1 = "sha1";
+ public static final String SHA224 = "sha224";
public static final String SHA256 = "sha256";
public static final String SHA384 = "sha384";
public static final String SHA512 = "sha512";
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/digest/DigestFactory.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/digest/DigestFactory.java b/sshd-core/src/main/java/org/apache/sshd/common/digest/DigestFactory.java
index 0bff18f..f00e7ba 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/digest/DigestFactory.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/digest/DigestFactory.java
@@ -20,13 +20,13 @@
package org.apache.sshd.common.digest;
import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.OptionalFeature;
/**
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public interface DigestFactory extends NamedFactory<Digest> {
- /**
- * @return The underlying digest algorithm
- */
- String getAlgorithm();
+// CHECKSTYLE:OFF
+public interface DigestFactory extends DigestInformation, NamedFactory<Digest>, OptionalFeature {
+ // nothing extra
}
+// CHECKSTYLE:ON
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/digest/DigestUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/digest/DigestUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/digest/DigestUtils.java
index 30fc9bb..fdf9adc 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/digest/DigestUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/digest/DigestUtils.java
@@ -27,6 +27,7 @@ import java.util.Comparator;
import org.apache.sshd.common.Factory;
import org.apache.sshd.common.util.Base64;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.BufferUtils;
@@ -142,7 +143,7 @@ public final class DigestUtils {
* @see #getFingerPrint(Factory, byte[], int, int)
*/
public static String getFingerPrint(Factory<? extends Digest> f, byte... buf) throws Exception {
- return getFingerPrint(f, buf, 0, GenericUtils.length(buf));
+ return getFingerPrint(f, buf, 0, NumberUtils.length(buf));
}
/**
@@ -165,7 +166,7 @@ public final class DigestUtils {
* @see #getFingerPrint(Digest, byte[], int, int)
*/
public static String getFingerPrint(Digest d, byte... buf) throws Exception {
- return getFingerPrint(d, buf, 0, GenericUtils.length(buf));
+ return getFingerPrint(d, buf, 0, NumberUtils.length(buf));
}
/**
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java
index 087226b..251de67 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/AbstractDH.java
@@ -21,7 +21,7 @@ package org.apache.sshd.common.kex;
import java.math.BigInteger;
import org.apache.sshd.common.digest.Digest;
-import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
/**
* Base class for the Diffie-Hellman key agreement.
@@ -63,7 +63,7 @@ public abstract class AbstractDH {
* @see <A HREF="https://issues.apache.org/jira/browse/SSHD-330">SSHD-330</A>
*/
public static byte[] stripLeadingZeroes(byte[] x) {
- int length = GenericUtils.length(x);
+ int length = NumberUtils.length(x);
for (int i = 0; i < x.length; i++) {
if (x[i] == 0) {
continue;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/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 9428ee7..65af0b0 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
@@ -54,7 +54,7 @@ public enum BuiltinDHFactories implements DHFactory {
@Override // see https://tools.ietf.org/html/rfc4253#page-23
public boolean isSupported() {
- return SecurityUtils.isDHOakelyGroupSupported(1024);
+ return SecurityUtils.isDHOakelyGroupSupported(1024) && BuiltinDigests.sha1.isSupported();
}
},
dhg14(Constants.DIFFIE_HELLMAN_GROUP14_SHA1) {
@@ -68,7 +68,7 @@ public enum BuiltinDHFactories implements DHFactory {
@Override // see https://tools.ietf.org/html/rfc4253#page-23
public boolean isSupported() {
- return SecurityUtils.isDHOakelyGroupSupported(2048);
+ return SecurityUtils.isDHOakelyGroupSupported(2048) && BuiltinDigests.sha1.isSupported();
}
},
dhgex(Constants.DIFFIE_HELLMAN_GROUP_EXCHANGE_SHA1) {
@@ -89,7 +89,7 @@ public enum BuiltinDHFactories implements DHFactory {
@Override
public boolean isSupported() { // avoid "Prime size must be multiple of 64, and can only range from 512 to 2048 (inclusive)"
- return SecurityUtils.isDHGroupExchangeSupported();
+ return SecurityUtils.isDHGroupExchangeSupported() && BuiltinDigests.sha1.isSupported();
}
},
dhgex256(Constants.DIFFIE_HELLMAN_GROUP_EXCHANGE_SHA256) {
@@ -105,7 +105,7 @@ public enum BuiltinDHFactories implements DHFactory {
@Override
public boolean isSupported() { // avoid "Prime size must be multiple of 64, and can only range from 512 to 2048 (inclusive)"
- return SecurityUtils.isDHGroupExchangeSupported();
+ return SecurityUtils.isDHGroupExchangeSupported() && BuiltinDigests.sha256.isSupported();
}
@Override
@@ -124,7 +124,7 @@ public enum BuiltinDHFactories implements DHFactory {
@Override
public boolean isSupported() {
- return SecurityUtils.hasEcc();
+ return ECCurves.nistp256.isSupported();
}
},
ecdhp384(Constants.ECDH_SHA2_NISTP384) {
@@ -138,7 +138,7 @@ public enum BuiltinDHFactories implements DHFactory {
@Override
public boolean isSupported() {
- return SecurityUtils.hasEcc();
+ return ECCurves.nistp384.isSupported();
}
},
ecdhp521(Constants.ECDH_SHA2_NISTP521) {
@@ -152,7 +152,7 @@ public enum BuiltinDHFactories implements DHFactory {
@Override
public boolean isSupported() {
- return SecurityUtils.hasEcc();
+ return ECCurves.nistp521.isSupported();
}
};
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/kex/DHG.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/DHG.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/DHG.java
index 025fe46..6a7042f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/kex/DHG.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/DHG.java
@@ -45,13 +45,13 @@ public class DHG extends AbstractDH {
private BigInteger f; // your public key
private KeyPairGenerator myKpairGen;
private KeyAgreement myKeyAgree;
- private Factory<Digest> factory;
+ private Factory<? extends Digest> factory;
- public DHG(Factory<Digest> digestFactory) throws Exception {
+ public DHG(Factory<? extends Digest> digestFactory) throws Exception {
this(digestFactory, null, null);
}
- public DHG(Factory<Digest> digestFactory, BigInteger pValue, BigInteger gValue) throws Exception {
+ public DHG(Factory<? extends Digest> digestFactory, BigInteger pValue, BigInteger gValue) throws Exception {
myKpairGen = SecurityUtils.getKeyPairGenerator("DH");
myKeyAgree = SecurityUtils.getKeyAgreement("DH");
factory = digestFactory;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/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 8f55619..b501d69 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
@@ -33,7 +33,6 @@ import java.util.TreeMap;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.config.NamedFactoriesListParseResult;
-import org.apache.sshd.common.digest.Digest;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.ValidateUtils;
@@ -173,12 +172,12 @@ public enum BuiltinMacs implements MacFactory {
}
/**
- * @param factory The {@link org.apache.sshd.common.NamedFactory} for the Mac - ignored if {@code null}
+ * @param factory The {@link org.apache.sshd.common.NamedFactory} for the MAC - ignored if {@code null}
* @return The matching {@link org.apache.sshd.common.mac.BuiltinMacs} whose factory name matches
* (case <U>insensitive</U>) the digest factory name
* @see #fromFactoryName(String)
*/
- public static BuiltinMacs fromFactory(NamedFactory<Digest> factory) {
+ public static BuiltinMacs fromFactory(NamedFactory<Mac> factory) {
if (factory == null) {
return null;
} else {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java b/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
index b9fe6b7..988ef32 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/scp/ScpHelper.java
@@ -45,9 +45,9 @@ import java.util.concurrent.TimeUnit;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.file.util.MockPath;
import org.apache.sshd.common.scp.ScpTransferEventListener.FileOperation;
-import org.apache.sshd.common.util.DirectoryScanner;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.SelectorUtils;
+import org.apache.sshd.common.util.io.DirectoryScanner;
import org.apache.sshd.common.util.io.IoUtils;
import org.apache.sshd.common.util.io.LimitInputStream;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/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 71a3893..b7559ec 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
@@ -63,6 +63,7 @@ import org.apache.sshd.common.mac.Mac;
import org.apache.sshd.common.random.Random;
import org.apache.sshd.common.util.EventListenerUtils;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
import org.apache.sshd.common.util.Pair;
import org.apache.sshd.common.util.Readable;
import org.apache.sshd.common.util.ValidateUtils;
@@ -283,7 +284,7 @@ public abstract class AbstractSession extends AbstractKexFactoryManager implemen
@Override
public byte[] getSessionId() {
// return a clone to avoid anyone changing the internal value
- return GenericUtils.isEmpty(sessionId) ? sessionId : sessionId.clone();
+ return NumberUtils.isEmpty(sessionId) ? sessionId : sessionId.clone();
}
@Override
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
index a33204a..b033465 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/AbstractSignature.java
@@ -22,7 +22,7 @@ import java.nio.charset.StandardCharsets;
import java.security.PrivateKey;
import java.security.PublicKey;
-import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
import org.apache.sshd.common.util.Pair;
import org.apache.sshd.common.util.SecurityUtils;
import org.apache.sshd.common.util.ValidateUtils;
@@ -62,7 +62,7 @@ public abstract class AbstractSignature implements Signature {
@Override
public void update(byte[] hash) throws Exception {
- update(hash, 0, GenericUtils.length(hash));
+ update(hash, 0, NumberUtils.length(hash));
}
@Override
@@ -78,7 +78,7 @@ public abstract class AbstractSignature implements Signature {
* value is the data - {@code null} if not encoded
*/
protected Pair<String, byte[]> extractEncodedSignature(byte[] sig) {
- final int dataLen = GenericUtils.length(sig);
+ final int dataLen = NumberUtils.length(sig);
// if it is encoded then we must have at least 2 UINT32 values
if (dataLen < (2 * (Integer.SIZE / Byte.SIZE))) {
return null;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/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 7bc3a92..851987a 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
@@ -35,7 +35,6 @@ import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.NamedResource;
import org.apache.sshd.common.cipher.ECCurves;
import org.apache.sshd.common.config.NamedFactoriesListParseResult;
-import org.apache.sshd.common.digest.Digest;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
import org.apache.sshd.common.util.GenericUtils;
import org.apache.sshd.common.util.SecurityUtils;
@@ -197,12 +196,12 @@ public enum BuiltinSignatures implements SignatureFactory {
}
/**
- * @param factory The {@link org.apache.sshd.common.NamedFactory} for the cipher - ignored if {@code null}
+ * @param factory The {@link org.apache.sshd.common.NamedFactory} for the signature - ignored if {@code null}
* @return The matching {@link org.apache.sshd.common.signature.BuiltinSignatures} whose factory name matches
* (case <U>insensitive</U>) the digest factory name
* @see #fromFactoryName(String)
*/
- public static BuiltinSignatures fromFactory(NamedFactory<Digest> factory) {
+ public static BuiltinSignatures fromFactory(NamedFactory<Signature> factory) {
if (factory == null) {
return null;
} else {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java
index 8c16a7f..eca665d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/signature/SignatureDSA.java
@@ -23,7 +23,7 @@ import java.math.BigInteger;
import java.security.SignatureException;
import org.apache.sshd.common.keyprovider.KeyPairProvider;
-import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
import org.apache.sshd.common.util.Pair;
import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.BufferUtils;
@@ -90,7 +90,7 @@ public class SignatureDSA extends AbstractSignature {
@Override
public boolean verify(byte[] sig) throws Exception {
- int sigLen = GenericUtils.length(sig);
+ int sigLen = NumberUtils.length(sig);
byte[] data = sig;
if (sigLen != DSA_SIGNATURE_LENGTH) {
@@ -100,7 +100,7 @@ public class SignatureDSA extends AbstractSignature {
String keyType = encoding.getFirst();
ValidateUtils.checkTrue(KeyPairProvider.SSH_DSS.equals(keyType), "Mismatched key type: %s", keyType);
data = encoding.getSecond();
- sigLen = GenericUtils.length(data);
+ sigLen = NumberUtils.length(data);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/AbstractParser.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/AbstractParser.java b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/AbstractParser.java
index 41eba37..e4e1c9d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/AbstractParser.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/subsystem/sftp/extensions/AbstractParser.java
@@ -19,7 +19,7 @@
package org.apache.sshd.common.subsystem.sftp.extensions;
-import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.NumberUtils;
import org.apache.sshd.common.util.ValidateUtils;
/**
@@ -45,6 +45,6 @@ public abstract class AbstractParser<T> implements ExtensionParser<T> {
@Override // TODO in JDK-8 make this a default method
public T parse(byte[] input) {
- return parse(input, 0, GenericUtils.length(input));
+ return parse(input, 0, NumberUtils.length(input));
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/util/Base64.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/Base64.java b/sshd-core/src/main/java/org/apache/sshd/common/util/Base64.java
index 528bb16..c392420 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/Base64.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/Base64.java
@@ -354,7 +354,7 @@ public class Base64 {
base64Data = discardNonBase64(base64Data);
// handle the edge case, so we don't have to worry about it later
- if (GenericUtils.isEmpty(base64Data)) {
+ if (NumberUtils.isEmpty(base64Data)) {
return GenericUtils.EMPTY_BYTE_ARRAY;
}
@@ -454,7 +454,7 @@ public class Base64 {
* may be same as input if all data was base-64
*/
public static byte[] discardNonBase64(byte[] data) {
- if (GenericUtils.isEmpty(data)) {
+ if (NumberUtils.isEmpty(data)) {
return data;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/util/DirectoryScanner.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/DirectoryScanner.java b/sshd-core/src/main/java/org/apache/sshd/common/util/DirectoryScanner.java
deleted file mode 100644
index 43703ef..0000000
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/DirectoryScanner.java
+++ /dev/null
@@ -1,380 +0,0 @@
-/*
- * 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 java.io.File;
-import java.util.ArrayList;
-import java.util.List;
-
-/**
- * <p>Class for scanning a directory for files/directories which match certain
- * criteria.</p>
- *
- * <p>These criteria consist of selectors and patterns which have been specified.
- * With the selectors you can select which files you want to have included.
- * Files which are not selected are excluded. With patterns you can include
- * or exclude files based on their filename.</p>
- *
- * <p>The idea is simple. A given directory is recursively scanned for all files
- * and directories. Each file/directory is matched against a set of selectors,
- * including special support for matching against filenames with include and
- * and exclude patterns. Only files/directories which match at least one
- * pattern of the include pattern list or other file selector, and don't match
- * any pattern of the exclude pattern list or fail to match against a required
- * selector will be placed in the list of files/directories found.</p>
- *
- * <p>When no list of include patterns is supplied, "**" will be used, which
- * means that everything will be matched. When no list of exclude patterns is
- * supplied, an empty list is used, such that nothing will be excluded. When
- * no selectors are supplied, none are applied.</p>
- *
- * <p>The filename pattern matching is done as follows:
- * The name to be matched is split up in path segments. A path segment is the
- * name of a directory or file, which is bounded by
- * <code>File.separator</code> ('/' under UNIX, '\' under Windows).
- * For example, "abc/def/ghi/xyz.java" is split up in the segments "abc",
- * "def","ghi" and "xyz.java".
- * The same is done for the pattern against which should be matched.</p>
- *
- * <p>The segments of the name and the pattern are then matched against each
- * other. When '**' is used for a path segment in the pattern, it matches
- * zero or more path segments of the name.</p>
- *
- * <p>There is a special case regarding the use of <code>File.separator</code>s
- * at the beginning of the pattern and the string to match:<br>
- * When a pattern starts with a <code>File.separator</code>, the string
- * to match must also start with a <code>File.separator</code>.
- * When a pattern does not start with a <code>File.separator</code>, the
- * string to match may not start with a <code>File.separator</code>.
- * When one of these rules is not obeyed, the string will not
- * match.</p>
- *
- * <p>When a name path segment is matched against a pattern path segment, the
- * following special characters can be used:<br>
- * '*' matches zero or more characters<br>
- * '?' matches one character.</p>
- *
- * <p>Examples:
- * <br>
- * <code>"**\*.class"</code> matches all <code>.class</code> files/dirs in a directory tree.
- * <br>
- * <code>"test\a??.java"</code> matches all files/dirs which start with an 'a', then two
- * more characters and then <code>".java"</code>, in a directory called test.
- * <br>
- * <code>"**"</code> matches everything in a directory tree.
- * <br>
- * <code>"**\test\**\XYZ*"</code> matches all files/dirs which start with <code>"XYZ"</code> and where
- * there is a parent directory called test (e.g. <code>"abc\test\def\ghi\XYZ123"</code>).
- * </p>
- *
- * <p>Case sensitivity may be turned off if necessary. By default, it is
- * turned on.</p>
- *
- * <p>Example of usage:</p>
- * <pre>
- * String[] includes = {"**\\*.class"};
- * String[] excludes = {"modules\\*\\**"};
- * ds.setIncludes(includes);
- * ds.setExcludes(excludes);
- * ds.setBasedir(new File("test"));
- * ds.setCaseSensitive(true);
- * ds.scan();
- *
- * System.out.println("FILES:");
- * String[] files = ds.getIncludedFiles();
- * for (int i = 0; i < files.length; i++) {
- * System.out.println(files[i]);
- * }
- * </pre>
- * <p>This will scan a directory called test for .class files, but excludes all
- * files in all proper subdirectories of a directory called "modules".</p>
- *
- * @author Arnout J. Kuiper
- * <a href="mailto:ajkuiper@wxs.nl">ajkuiper@wxs.nl</a>
- * @author Magesh Umasankar
- * @author <a href="mailto:bruce@callenish.com">Bruce Atherton</a>
- * @author <a href="mailto:levylambert@tiscali-dsl.de">Antoine Levy-Lambert</a>
- */
-public class DirectoryScanner {
-
- /**
- * The base directory to be scanned.
- */
- protected File basedir;
-
- /**
- * The patterns for the files to be included.
- */
- protected String[] includes;
-
- /**
- * The files which matched at least one include and no excludes
- * and were selected.
- */
- protected List<String> filesIncluded;
-
- /**
- * Whether or not the file system should be treated as a case sensitive
- * one.
- */
- protected boolean isCaseSensitive = true;
-
- public DirectoryScanner() {
- }
-
- public DirectoryScanner(String basedir, String... includes) {
- setBasedir(basedir);
- setIncludes(includes);
- }
-
- /**
- * Sets the base directory to be scanned. This is the directory which is
- * scanned recursively. All '/' and '\' characters are replaced by
- * <code>File.separatorChar</code>, so the separator used need not match
- * <code>File.separatorChar</code>.
- *
- * @param basedir The base directory to scan.
- * Must not be {@code null}.
- */
- public void setBasedir(String basedir) {
- setBasedir(new File(basedir.replace('/', File.separatorChar).replace(
- '\\', File.separatorChar)));
- }
-
- /**
- * Sets the base directory to be scanned. This is the directory which is
- * scanned recursively.
- *
- * @param basedir The base directory for scanning.
- * Should not be {@code null}.
- */
- public void setBasedir(File basedir) {
- this.basedir = basedir;
- }
-
- /**
- * Returns the base directory to be scanned.
- * This is the directory which is scanned recursively.
- *
- * @return the base directory to be scanned
- */
- public File getBasedir() {
- return basedir;
- }
-
- /**
- * <p>Sets the list of include patterns to use. All '/' and '\' characters
- * are replaced by <code>File.separatorChar</code>, so the separator used
- * need not match <code>File.separatorChar</code>.</p>
- *
- * <p>When a pattern ends with a '/' or '\', "**" is appended.</p>
- *
- * @param includes A list of include patterns.
- * May be {@code null}, indicating that all files
- * should be included. If a non-{@code null}
- * list is given, all elements must be
- * non-{@code null}.
- */
- public void setIncludes(String[] includes) {
- if (includes == null) {
- this.includes = null;
- } else {
- this.includes = new String[includes.length];
- for (int i = 0; i < includes.length; i++) {
- this.includes[i] = normalizePattern(includes[i]);
- }
- }
- }
-
-
- /**
- * Scans the base directory for files which match at least one include
- * pattern and don't match any exclude patterns. If there are selectors
- * then the files must pass muster there, as well.
- *
- * @return the matching files
- * @throws IllegalStateException if the base directory was set
- * incorrectly (i.e. if it is {@code null}, doesn't exist,
- * or isn't a directory).
- */
- public String[] scan() throws IllegalStateException {
- if (basedir == null) {
- throw new IllegalStateException("No basedir set");
- }
- if (!basedir.exists()) {
- throw new IllegalStateException("basedir " + basedir
- + " does not exist");
- }
- if (!basedir.isDirectory()) {
- throw new IllegalStateException("basedir " + basedir
- + " is not a directory");
- }
- if (includes == null || includes.length == 0) {
- throw new IllegalStateException("No includes set ");
- }
-
- filesIncluded = new ArrayList<>();
-
- scandir(basedir, "");
-
- return getIncludedFiles();
- }
-
- /**
- * Scans the given directory for files and directories. Found files and
- * directories are placed in their respective collections, based on the
- * matching of includes, excludes, and the selectors. When a directory
- * is found, it is scanned recursively.
- *
- * @param dir The directory to scan. Must not be {@code null}.
- * @param vpath The path relative to the base directory (needed to
- * prevent problems with an absolute path when using
- * dir). Must not be {@code null}.
- */
- protected void scandir(File dir, String vpath) {
- String[] newfiles = dir.list();
- if (newfiles == null) {
- newfiles = new String[0];
- }
-
- for (String newfile : newfiles) {
- String name = vpath + newfile;
- File file = new File(dir, newfile);
- if (file.isDirectory()) {
- if (isIncluded(name)) {
- filesIncluded.add(name);
- scandir(file, name + File.separator);
- } else if (couldHoldIncluded(name)) {
- scandir(file, name + File.separator);
- }
- } else if (file.isFile()) {
- if (isIncluded(name)) {
- filesIncluded.add(name);
- }
- }
- }
- }
-
- /**
- * Returns the names of the files which matched at least one of the
- * include patterns and none of the exclude patterns.
- * The names are relative to the base directory.
- *
- * @return the names of the files which matched at least one of the
- * include patterns and none of the exclude patterns.
- */
- public String[] getIncludedFiles() {
- String[] files = new String[filesIncluded.size()];
- filesIncluded.toArray(files);
- return files;
- }
-
- /**
- * Tests whether or not a name matches against at least one include
- * pattern.
- *
- * @param name The name to match. Must not be {@code null}.
- * @return <code>true</code> when the name matches against at least one
- * include pattern, or <code>false</code> otherwise.
- */
- protected boolean isIncluded(String name) {
- for (String include : includes) {
- if (SelectorUtils.matchPath(include, name, isCaseSensitive)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Tests whether or not a name matches the start of at least one include
- * pattern.
- *
- * @param name The name to match. Must not be {@code null}.
- * @return <code>true</code> when the name matches against the start of at
- * least one include pattern, or <code>false</code> otherwise.
- */
- protected boolean couldHoldIncluded(String name) {
- for (String include : includes) {
- if (SelectorUtils.matchPatternStart(include, name, isCaseSensitive)) {
- return true;
- }
- }
- return false;
- }
-
- /**
- * Normalizes the pattern, e.g. converts forward and backward slashes to the platform-specific file separator.
- *
- * @param pattern The pattern to normalize, must not be {@code null}.
- * @return The normalized pattern, never {@code null}.
- */
- private String normalizePattern(String pattern) {
- pattern = pattern.trim();
-
- if (pattern.startsWith(SelectorUtils.REGEX_HANDLER_PREFIX)) {
- if (File.separatorChar == '\\') {
- pattern = replace(pattern, "/", "\\\\", -1);
- } else {
- pattern = replace(pattern, "\\\\", "/", -1);
- }
- } else {
- pattern = pattern.replace(File.separatorChar == '/' ? '\\' : '/', File.separatorChar);
-
- if (pattern.endsWith(File.separator)) {
- pattern += "**";
- }
- }
-
- return pattern;
- }
-
- /**
- * <p>Replace a String with another String inside a larger String,
- * for the first <code>max</code> values of the search String.</p>
- *
- * <p>A {@code null} reference passed to this method is a no-op.</p>
- *
- * @param text text to search and replace in
- * @param repl String to search for
- * @param with String to replace with
- * @param max maximum number of values to replace, or <code>-1</code> if no maximum
- * @return the text with any replacements processed
- */
- public static String replace(String text, String repl, String with, int max) {
- if ((text == null) || (repl == null) || (with == null) || (repl.length() == 0)) {
- return text;
- }
-
- StringBuilder buf = new StringBuilder(text.length());
- int start = 0;
- int end;
- while ((end = text.indexOf(repl, start)) != -1) {
- buf.append(text.substring(start, end)).append(with);
- start = end + repl.length();
-
- if (--max == 0) {
- break;
- }
- }
- buf.append(text.substring(start));
- return buf.toString();
- }
-
-}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/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 39c08d2..13fc270 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
@@ -226,30 +226,6 @@ public final class GenericUtils {
return size(m) <= 0;
}
- public static boolean isEmpty(byte[] a) {
- return length(a) <= 0;
- }
-
- public static boolean isEmpty(int[] a) {
- return length(a) <= 0;
- }
-
- public static boolean isEmpty(long[] a) {
- return length(a) <= 0;
- }
-
- public static int length(byte... a) {
- return a == null ? 0 : a.length;
- }
-
- public static int length(int... a) {
- return a == null ? 0 : a.length;
- }
-
- public static int length(long... a) {
- return a == null ? 0 : a.length;
- }
-
@SafeVarargs
public static <T> int length(T... a) {
return a == null ? 0 : a.length;
@@ -310,20 +286,6 @@ public final class GenericUtils {
}
}
- public static List<Integer> asList(int ... values) {
- int len = length(values);
- if (len <= 0) {
- return Collections.emptyList();
- }
-
- List<Integer> l = new ArrayList<>(len);
- for (int v : values) {
- l.add(Integer.valueOf(v));
- }
-
- return l;
- }
-
@SuppressWarnings({"unchecked", "rawtypes"})
public static <V extends Comparable<V>> Comparator<V> naturalComparator() {
// TODO for JDK-8 use Comparator.naturalOrder()
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/util/NumberUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/NumberUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/NumberUtils.java
index 686762f..0c61c03 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/NumberUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/NumberUtils.java
@@ -85,7 +85,7 @@ public final class NumberUtils {
}
public static int hashCode(long ... values) {
- if (GenericUtils.length(values) <= 0) {
+ if (NumberUtils.length(values) <= 0) {
return 0;
}
@@ -97,6 +97,19 @@ public final class NumberUtils {
return hash;
}
+ public static int hashCode(int ... values) {
+ if (NumberUtils.length(values) <= 0) {
+ return 0;
+ }
+
+ int hash = values[0];
+ for (int index = 1; index < values.length; index++) {
+ hash += 31 * hash + values[index];
+ }
+
+ return hash;
+ }
+
// TODO in JDK-8 use Long.hashCode(long)
public static int hashCode(long value) {
return (int) (value ^ (value >>> 32));
@@ -135,4 +148,138 @@ public final class NumberUtils {
return Integer.valueOf(n.intValue());
}
}
+
+ public static String join(CharSequence separator, long ... values) {
+ if (NumberUtils.isEmpty(values)) {
+ return "";
+ }
+
+ StringBuilder sb = new StringBuilder(values.length * Byte.SIZE);
+ for (long v : values) {
+ if (sb.length() > 0) {
+ sb.append(separator);
+ }
+ sb.append(v);
+ }
+
+ return sb.toString();
+ }
+
+ public static String join(char separator, long ... values) {
+ if (NumberUtils.isEmpty(values)) {
+ return "";
+ }
+
+ StringBuilder sb = new StringBuilder(values.length * Byte.SIZE);
+ for (long v : values) {
+ if (sb.length() > 0) {
+ sb.append(separator);
+ }
+ sb.append(v);
+ }
+
+ return sb.toString();
+ }
+
+ public static String join(CharSequence separator, boolean unsigned, byte ... values) {
+ if (NumberUtils.isEmpty(values)) {
+ return "";
+ }
+
+ StringBuilder sb = new StringBuilder(values.length * Byte.SIZE);
+ for (byte v : values) {
+ if (sb.length() > 0) {
+ sb.append(separator);
+ }
+ sb.append(unsigned ? (v & 0xFF) : v);
+ }
+
+ return sb.toString();
+ }
+
+ public static String join(char separator, boolean unsigned, byte ... values) {
+ if (NumberUtils.isEmpty(values)) {
+ return "";
+ }
+
+ StringBuilder sb = new StringBuilder(values.length * Byte.SIZE);
+ for (byte v : values) {
+ if (sb.length() > 0) {
+ sb.append(separator);
+ }
+ sb.append(unsigned ? (v & 0xFF) : v);
+ }
+
+ return sb.toString();
+ }
+
+ public static String join(CharSequence separator, int ... values) {
+ if (NumberUtils.isEmpty(values)) {
+ return "";
+ }
+
+ StringBuilder sb = new StringBuilder(values.length * Byte.SIZE);
+ for (int v : values) {
+ if (sb.length() > 0) {
+ sb.append(separator);
+ }
+ sb.append(v);
+ }
+
+ return sb.toString();
+ }
+
+ public static String join(char separator, int ... values) {
+ if (NumberUtils.isEmpty(values)) {
+ return "";
+ }
+
+ StringBuilder sb = new StringBuilder(values.length * Byte.SIZE);
+ for (int v : values) {
+ if (sb.length() > 0) {
+ sb.append(separator);
+ }
+ sb.append(v);
+ }
+
+ return sb.toString();
+ }
+
+ public static boolean isEmpty(byte[] a) {
+ return NumberUtils.length(a) <= 0;
+ }
+
+ public static boolean isEmpty(int[] a) {
+ return NumberUtils.length(a) <= 0;
+ }
+
+ public static boolean isEmpty(long[] a) {
+ return NumberUtils.length(a) <= 0;
+ }
+
+ public static int length(byte... a) {
+ return a == null ? 0 : a.length;
+ }
+
+ public static int length(int... a) {
+ return a == null ? 0 : a.length;
+ }
+
+ public static int length(long... a) {
+ return a == null ? 0 : a.length;
+ }
+
+ public static List<Integer> asList(int ... values) {
+ int len = length(values);
+ if (len <= 0) {
+ return Collections.emptyList();
+ }
+
+ List<Integer> l = new ArrayList<>(len);
+ for (int v : values) {
+ l.add(Integer.valueOf(v));
+ }
+
+ return l;
+ }
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/util/OsUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/OsUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/OsUtils.java
index 55cf1e0..fac8ad3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/OsUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/OsUtils.java
@@ -36,6 +36,18 @@ public final class OsUtils {
*/
public static final String CURRENT_USER_OVERRIDE_PROP = "org.apache.sshd.currentUser";
+ /**
+ * Property that can be used to override the reported value from {@link #getJavaVersion()}.
+ * If not set then "java.version" system property is used
+ */
+ public static final String JAVA_VERSION_OVERRIDE_PROP = "org.apache.sshd.javaVersion";
+
+ /**
+ * Property that can be used to override the reported value from {@link #isWin32()}.
+ * If not set then "os.name" system property is used
+ */
+ public static final String OS_TYPE_OVERRIDE_PROP = "org.apache.sshd.osType";
+
public static final String WINDOWS_SHELL_COMMAND_NAME = "cmd.exe";
public static final String LINUX_SHELL_COMMAND_NAME = "/bin/sh";
@@ -47,7 +59,8 @@ public final class OsUtils {
Collections.unmodifiableList(Collections.singletonList(WINDOWS_SHELL_COMMAND_NAME));
private static final AtomicReference<String> CURRENT_USER_HOLDER = new AtomicReference<>(null);
- private static final boolean WIN32 = GenericUtils.trimToEmpty(System.getProperty("os.name")).toLowerCase().contains("windows");
+ private static final AtomicReference<VersionInfo> JAVA_VERSION_HOLDER = new AtomicReference<>(null);
+ private static final AtomicReference<Boolean> OS_TYPE_HOLDER = new AtomicReference<>(null);
private OsUtils() {
throw new UnsupportedOperationException("No instance allowed");
@@ -57,14 +70,39 @@ public final class OsUtils {
* @return true if the host is a UNIX system (and not Windows).
*/
public static boolean isUNIX() {
- return !WIN32;
+ return !isWin32();
}
/**
* @return true if the host is Windows (and not UNIX).
+ * @see #OS_TYPE_OVERRIDE_PROP
+ * @see #setWin32(Boolean)
*/
public static boolean isWin32() {
- return WIN32;
+ Boolean typeValue;
+ synchronized (OS_TYPE_HOLDER) {
+ typeValue = OS_TYPE_HOLDER.get();
+ if (typeValue != null) { // is it the 1st time
+ return typeValue.booleanValue();
+ }
+
+ String value = System.getProperty(OS_TYPE_OVERRIDE_PROP, System.getProperty("os.name"));
+ typeValue = GenericUtils.trimToEmpty(value).toLowerCase().contains("windows");
+ OS_TYPE_HOLDER.set(typeValue);
+ }
+
+ return typeValue.booleanValue();
+ }
+
+ /**
+ * Can be used to enforce Win32 or Linux report from {@link #isWin32()} or {@link #isUNIX()}
+ * @param win32 The value to set - if {@code null} then O/S type is auto-detected
+ * @see #isWin32()
+ */
+ public static void setWin32(Boolean win32) {
+ synchronized (OS_TYPE_HOLDER) {
+ OS_TYPE_HOLDER.set(win32);
+ }
}
public static List<String> resolveDefaultInteractiveCommand() {
@@ -111,4 +149,50 @@ public final class OsUtils {
CURRENT_USER_HOLDER.set(username);
}
}
+
+ /**
+ * Resolves the reported Java version by consulting {@link #JAVA_VERSION_OVERRIDE_PROP}.
+ * If not set, then "java.version" property is used
+ * @return The resolved {@link VersionInfo} - never {@code null}
+ * @see #setJavaVersion(VersionInfo)
+ */
+ public static VersionInfo getJavaVersion() {
+ VersionInfo version;
+ synchronized (JAVA_VERSION_HOLDER) {
+ version = JAVA_VERSION_HOLDER.get();
+ if (version != null) { // first time ?
+ return version;
+ }
+
+ String value = System.getProperty(JAVA_VERSION_OVERRIDE_PROP, System.getProperty("java.version"));
+ // e.g.: 1.7.5_30
+ value = ValidateUtils.checkNotNullAndNotEmpty(value, "No configured Java version value").replace('_', '.');
+ // clean up any non-digits - in case something like 1.6.8_25-b323
+ for (int index = 0; index < value.length(); index++) {
+ char ch = value.charAt(index);
+ if ((ch == '.') || ((ch >= '0') && (ch <= '9'))) {
+ continue;
+ }
+
+ value = value.substring(0, index);
+ break;
+ }
+
+ version = ValidateUtils.checkNotNull(VersionInfo.parse(value), "No version parsed for %s", value);
+ JAVA_VERSION_HOLDER.set(version);
+ }
+
+ return version;
+ }
+
+ /**
+ * Set programmatically the reported Java version
+ * @param version The version - if {@code null} then it will be automatically resolved
+ */
+ public static void setJavaVersion(VersionInfo version) {
+ synchronized (JAVA_VERSION_HOLDER) {
+ JAVA_VERSION_HOLDER.set(version);
+ }
+ }
+
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/util/SecurityUtils.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/SecurityUtils.java b/sshd-core/src/main/java/org/apache/sshd/common/util/SecurityUtils.java
index 4a7012f..7e23452 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/util/SecurityUtils.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/SecurityUtils.java
@@ -198,6 +198,17 @@ public final class SecurityUtils {
return maxSupportedKeySize;
}
+ /**
+ * Set programmatically the reported value for {@link #getMaxDHGroupExchangeKeySize()}
+ * @param keySize The reported key size - if zero, then it will be auto-detected, if
+ * negative then DH group exchange will be disabled
+ */
+ public static void setMaxDHGroupExchangeKeySize(int keySize) {
+ synchronized (MAX_DHG_KEY_SIZE_HOLDER) {
+ MAX_DHG_KEY_SIZE_HOLDER.set(keySize);
+ }
+ }
+
public static boolean isDHGroupExchangeSupported(int maxKeySize) {
ValidateUtils.checkTrue(maxKeySize > Byte.SIZE, "Invalid max. key size: %d", maxKeySize);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/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 b48f811..3679471 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
@@ -82,25 +82,25 @@ public final class ValidateUtils {
public static byte[] checkNotNullAndNotEmpty(byte[] a, String message) {
a = checkNotNull(a, message);
- checkTrue(GenericUtils.length(a) > 0, message);
+ checkTrue(NumberUtils.length(a) > 0, message);
return a;
}
public static byte[] checkNotNullAndNotEmpty(byte[] a, String message, Object... args) {
a = checkNotNull(a, message, args);
- checkTrue(GenericUtils.length(a) > 0, message, args);
+ checkTrue(NumberUtils.length(a) > 0, message, args);
return a;
}
public static int[] checkNotNullAndNotEmpty(int[] a, String message) {
a = checkNotNull(a, message);
- checkTrue(GenericUtils.length(a) > 0, message);
+ checkTrue(NumberUtils.length(a) > 0, message);
return a;
}
public static int[] checkNotNullAndNotEmpty(int[] a, String message, Object... args) {
a = checkNotNull(a, message, args);
- checkTrue(GenericUtils.length(a) > 0, message, args);
+ checkTrue(NumberUtils.length(a) > 0, message, args);
return a;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/7b18b090/sshd-core/src/main/java/org/apache/sshd/common/util/VersionInfo.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/util/VersionInfo.java b/sshd-core/src/main/java/org/apache/sshd/common/util/VersionInfo.java
new file mode 100644
index 0000000..ed1aab7
--- /dev/null
+++ b/sshd-core/src/main/java/org/apache/sshd/common/util/VersionInfo.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.util;
+
+import java.io.Serializable;
+
+/**
+ * @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
+ */
+public class VersionInfo implements Serializable, Comparable<VersionInfo> {
+ private static final long serialVersionUID = -9127482432228413836L;
+
+ private final int majorVersion;
+ private final int minorVersion;
+ private final int release;
+ private final int buildNumber;
+
+ public VersionInfo(int major, int minor) {
+ this(major, minor, 0, 0);
+ }
+
+ public VersionInfo(int major, int minor, int release, int build) {
+ this.majorVersion = major;
+ this.minorVersion = minor;
+ this.release = release;
+ this.buildNumber = build;
+ }
+
+ public final int getMajorVersion() {
+ return majorVersion;
+ }
+
+ public final int getMinorVersion() {
+ return minorVersion;
+ }
+
+ public final int getRelease() {
+ return release;
+ }
+
+ public final int getBuildNumber() {
+ return buildNumber;
+ }
+
+ @Override
+ public int hashCode() {
+ return NumberUtils.hashCode(getMajorVersion(), getMinorVersion(), getRelease(), getBuildNumber());
+ }
+
+ @Override
+ public boolean equals(Object obj) {
+ if (obj == null) {
+ return false;
+ }
+ if (this == obj) {
+ return true;
+ }
+ if (getClass() != obj.getClass()) {
+ return false;
+ }
+ return compareTo((VersionInfo) obj) == 0;
+ }
+
+ @Override
+ public int compareTo(VersionInfo o) {
+ if (o == null) {
+ return -1; // push nulls to end
+ }
+ if (o == this) {
+ return 0;
+ }
+
+ int nRes = Integer.compare(getMajorVersion(), o.getMajorVersion());
+ if (nRes == 0) {
+ nRes = Integer.compare(getMinorVersion(), o.getMinorVersion());
+ }
+ if (nRes == 0) {
+ nRes = Integer.compare(getRelease(), o.getRelease());
+ }
+ if (nRes == 0) {
+ nRes = Integer.compare(getBuildNumber(), o.getBuildNumber());
+ }
+
+ return nRes;
+ }
+
+ @Override
+ public String toString() {
+ return NumberUtils.join('.', getMajorVersion(), getMinorVersion(), getRelease(), getBuildNumber());
+ }
+
+ /**
+ * Parses a version string - assumed to contain at most 4 non-negative
+ * components separated by a '.'. If less than 4 components are found, then
+ * the rest are assumed to be zero. If more than 4 components found, then
+ * only the 1st ones are parsed.
+ *
+ * @param version The version string - ignored if {@code null}/empty
+ * @return The parsed {@link VersionInfo} - or {@code null} if empty input
+ * @throws NumberFormatException If failed to parse any of the components
+ * @throws IllegalArgumentException If any of the parsed components is negative
+ */
+ public static VersionInfo parse(String version) throws NumberFormatException {
+ String[] comps = GenericUtils.split(version, '.');
+ if (GenericUtils.isEmpty(comps)) {
+ return null;
+ }
+
+ int[] values = new int[4];
+ int maxValues = Math.min(comps.length, values.length);
+ for (int index = 0; index < maxValues; index++) {
+ String c = comps[index];
+ int v = Integer.parseInt(c);
+ ValidateUtils.checkTrue(v >= 0, "Invalid version component in %s", version);
+ values[index] = v;
+ }
+
+ return new VersionInfo(values[0], values[1], values[2], values[3]);
+ }
+}