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/06/22 15:54:36 UTC
[2/2] mina-sshd git commit: [SSHD-499] Consolidate similar logic for
client and server sessions
[SSHD-499] Consolidate similar logic for client and server sessions
Project: http://git-wip-us.apache.org/repos/asf/mina-sshd/repo
Commit: http://git-wip-us.apache.org/repos/asf/mina-sshd/commit/6f8507a1
Tree: http://git-wip-us.apache.org/repos/asf/mina-sshd/tree/6f8507a1
Diff: http://git-wip-us.apache.org/repos/asf/mina-sshd/diff/6f8507a1
Branch: refs/heads/master
Commit: 6f8507a10afbb4314ac7714bfc52b0702e102bbc
Parents: 612a2f4
Author: Lyor Goldstein <lg...@vmware.com>
Authored: Mon Jun 22 16:54:21 2015 +0300
Committer: Lyor Goldstein <lg...@vmware.com>
Committed: Mon Jun 22 16:54:21 2015 +0300
----------------------------------------------------------------------
.../sshd/client/future/DefaultAuthFuture.java | 6 +-
.../client/future/DefaultConnectFuture.java | 10 +-
.../sshd/client/future/DefaultOpenFuture.java | 6 +-
.../org/apache/sshd/client/kex/DHGClient.java | 5 +-
.../org/apache/sshd/client/kex/DHGEXClient.java | 2 +-
.../sshd/client/session/ClientSession.java | 12 +-
.../sshd/client/session/ClientSessionImpl.java | 73 +++---
.../client/sftp/SftpFileSystemProvider.java | 94 ++++---
.../apache/sshd/common/file/util/BasePath.java | 11 +-
.../sshd/common/future/DefaultSshFuture.java | 38 +--
.../common/kex/dh/AbstractDHKeyExchange.java | 1 -
.../sshd/common/session/AbstractSession.java | 119 ++++++---
.../org/apache/sshd/common/session/Session.java | 42 +++-
.../apache/sshd/common/util/GenericUtils.java | 8 +
.../apache/sshd/common/util/ValidateUtils.java | 6 +
.../sshd/server/ServerFactoryManager.java | 18 +-
.../org/apache/sshd/server/SessionAware.java | 4 +-
.../sshd/server/auth/AbstractUserAuth.java | 4 +
.../auth/UserAuthKeyboardInteractive.java | 20 +-
.../apache/sshd/server/auth/UserAuthNone.java | 4 +
.../sshd/server/auth/UserAuthPassword.java | 21 +-
.../sshd/server/auth/UserAuthPublicKey.java | 8 +-
.../sshd/server/auth/gss/UserAuthGSS.java | 20 +-
.../sshd/server/channel/ChannelSession.java | 53 ++--
.../keys/AuthorizedKeysAuthenticator.java | 3 +-
.../server/jaas/JaasPasswordAuthenticator.java | 2 +-
.../server/kex/AbstractDHServerKeyExchange.java | 8 +-
.../org/apache/sshd/server/kex/DHGEXServer.java | 2 +-
.../org/apache/sshd/server/kex/DHGServer.java | 2 +-
.../server/session/ServerConnectionService.java | 9 +-
.../sshd/server/session/ServerSession.java | 213 ++--------------
.../sshd/server/session/ServerSessionImpl.java | 250 +++++++++++++++++++
.../server/session/ServerUserAuthService.java | 10 +-
.../sshd/server/session/SessionFactory.java | 18 +-
.../org/apache/sshd/AuthenticationTest.java | 8 +-
.../apache/sshd/SinglePublicKeyAuthTest.java | 6 +-
.../java/org/apache/sshd/client/ClientTest.java | 9 +-
.../client/session/ClientSessionImplTest.java | 5 +-
.../common/session/AbstractSessionTest.java | 19 +-
.../java/org/apache/sshd/git/util/Utils.java | 14 +-
40 files changed, 675 insertions(+), 488 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultAuthFuture.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultAuthFuture.java b/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultAuthFuture.java
index a9043d4..4fc29c6 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultAuthFuture.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultAuthFuture.java
@@ -22,6 +22,8 @@ import java.util.concurrent.TimeUnit;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.future.DefaultSshFuture;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
/**
@@ -88,9 +90,7 @@ public class DefaultAuthFuture extends DefaultSshFuture<AuthFuture> implements A
@Override
public void setException(Throwable exception) {
- if (exception == null) {
- throw new NullPointerException("exception");
- }
+ ValidateUtils.checkNotNull(exception, "No exception provided", GenericUtils.EMPTY_OBJECT_ARRAY);
setValue(exception);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultConnectFuture.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultConnectFuture.java b/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultConnectFuture.java
index 9dd3a12..bd02880 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultConnectFuture.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultConnectFuture.java
@@ -21,6 +21,8 @@ package org.apache.sshd.client.future;
import org.apache.sshd.client.session.ClientSession;
import org.apache.sshd.common.RuntimeSshException;
import org.apache.sshd.common.future.DefaultSshFuture;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
/**
* A default implementation of {@link ConnectFuture}.
@@ -66,17 +68,13 @@ public class DefaultConnectFuture extends DefaultSshFuture<ConnectFuture> implem
@Override
public void setSession(ClientSession session) {
- if (session == null) {
- throw new NullPointerException("session");
- }
+ ValidateUtils.checkNotNull(session, "No client session provided", GenericUtils.EMPTY_OBJECT_ARRAY);
setValue(session);
}
@Override
public void setException(Throwable exception) {
- if (exception == null) {
- throw new NullPointerException("exception");
- }
+ ValidateUtils.checkNotNull(exception, "No exception provided", GenericUtils.EMPTY_OBJECT_ARRAY);
setValue(exception);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultOpenFuture.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultOpenFuture.java b/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultOpenFuture.java
index 9baab23..7dc401f 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultOpenFuture.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/future/DefaultOpenFuture.java
@@ -22,6 +22,8 @@ import java.util.concurrent.TimeUnit;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.future.DefaultSshFuture;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
/**
* A default implementation of {@link OpenFuture}.
@@ -80,9 +82,7 @@ public class DefaultOpenFuture extends DefaultSshFuture<OpenFuture> implements O
@Override
public void setException(Throwable exception) {
- if (exception == null) {
- throw new NullPointerException("exception");
- }
+ ValidateUtils.checkNotNull(exception, "No exception provided", GenericUtils.EMPTY_OBJECT_ARRAY);
setValue(exception);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
index f4a21f9..0f1c1f8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/kex/DHGClient.java
@@ -107,7 +107,7 @@ public class DHGClient extends AbstractDHClientKeyExchange {
buffer = new ByteArrayBuffer(K_S);
serverKey = buffer.getRawPublicKey();
final String keyAlg = KeyUtils.getKeyType(serverKey);
- if (keyAlg == null) {
+ if (GenericUtils.isEmpty(keyAlg)) {
throw new SshException("Unsupported server key type");
}
@@ -130,8 +130,7 @@ public class DHGClient extends AbstractDHClientKeyExchange {
verif.initVerifier(serverKey);
verif.update(H);
if (!verif.verify(sig)) {
- throw new SshException(SshConstants.SSH2_DISCONNECT_KEY_EXCHANGE_FAILED,
- "KeyExchange signature verification failed");
+ throw new SshException(SshConstants.SSH2_DISCONNECT_KEY_EXCHANGE_FAILED, "KeyExchange signature verification failed");
}
return true;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/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 bcf4ba9..bd3f222 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
@@ -124,7 +124,7 @@ public class DHGEXClient extends AbstractDHClientKeyExchange {
buffer = new ByteArrayBuffer(K_S);
serverKey = buffer.getRawPublicKey();
final String keyAlg = KeyUtils.getKeyType(serverKey);
- if (keyAlg == null) {
+ if (GenericUtils.isEmpty(keyAlg)) {
throw new SshException("Unsupported server key type");
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
index 6a885d4..d694b75 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/session/ClientSession.java
@@ -35,7 +35,6 @@ import org.apache.sshd.client.future.AuthFuture;
import org.apache.sshd.client.scp.ScpClient;
import org.apache.sshd.client.sftp.SftpClient;
import org.apache.sshd.common.SshdSocketAddress;
-import org.apache.sshd.common.future.CloseFuture;
import org.apache.sshd.common.future.SshFuture;
import org.apache.sshd.common.scp.ScpTransferEventListener;
import org.apache.sshd.common.session.Session;
@@ -238,21 +237,14 @@ public interface ClientSession extends Session {
int waitFor(int mask, long timeout);
/**
- * Close this session.
- */
- @Override
- CloseFuture close(boolean immediately);
-
- /**
* Access to the metadata.
*/
Map<Object, Object> getMetadataMap();
/**
- * Return ClientFactoryManager for this session.
+ * @return The ClientFactoryManager for this session.
*/
- @Override
- ClientFactoryManager getFactoryManager();
+ @Override ClientFactoryManager getFactoryManager();
/**
* Switch to a none cipher for performance.
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/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 bc7cf74..50c0d5a 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
@@ -24,6 +24,7 @@ import java.nio.file.FileSystem;
import java.security.KeyPair;
import java.util.ArrayList;
import java.util.Comparator;
+import java.util.EnumMap;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
@@ -240,8 +241,10 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
if (username == null) {
throw new IllegalStateException("No username specified when the session was created");
}
+
+ ClientUserAuthService authService = getUserAuthService();
synchronized (lock) {
- return authFuture = getUserAuthService().auth(identities, nextServiceName());
+ return authFuture = authService.auth(identities, nextServiceName());
}
}
@@ -268,19 +271,27 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
@SuppressWarnings("rawtypes")
public SshFuture switchToNoneCipher() throws IOException {
if (!(currentService instanceof AbstractConnectionService)
- || !((AbstractConnectionService) currentService).getChannels().isEmpty()) {
+ || !((AbstractConnectionService) currentService).getChannels().isEmpty()) {
throw new IllegalStateException("The switch to the none cipher must be done immediately after authentication");
}
if (kexState.compareAndSet(KexState.DONE, KexState.INIT)) {
reexchangeFuture = new DefaultSshFuture(null);
- String c2sEncServer = serverProposal.get(KexProposalOption.C2SENC);
+ String c2sEncServer, s2cEncServer;
+ synchronized(serverProposal) {
+ c2sEncServer = serverProposal.get(KexProposalOption.C2SENC);
+ s2cEncServer = serverProposal.get(KexProposalOption.S2CENC);
+ }
boolean c2sEncServerNone = BuiltinCiphers.Constants.isNoneCipherIncluded(c2sEncServer);
- String s2cEncServer = serverProposal.get(KexProposalOption.S2CENC);
boolean s2cEncServerNone = BuiltinCiphers.Constants.isNoneCipherIncluded(s2cEncServer);
- String c2sEncClient = clientProposal.get(KexProposalOption.C2SENC);
+
+ String c2sEncClient, s2cEncClient;
+ synchronized(clientProposal) {
+ c2sEncClient = clientProposal.get(KexProposalOption.C2SENC);
+ s2cEncClient = clientProposal.get(KexProposalOption.S2CENC);
+ }
+
boolean c2sEncClientNone = BuiltinCiphers.Constants.isNoneCipherIncluded(c2sEncClient);
- String s2cEncClient = clientProposal.get(KexProposalOption.S2CENC);
boolean s2cEncClientNone = BuiltinCiphers.Constants.isNoneCipherIncluded(s2cEncClient);
if ((!c2sEncServerNone) || (!s2cEncServerNone)) {
@@ -289,9 +300,17 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
reexchangeFuture.setValue(new SshException("Client does not support none cipher"));
} else {
log.info("Switching to none cipher");
- clientProposal.put(KexProposalOption.C2SENC, BuiltinCiphers.Constants.NONE);
- clientProposal.put(KexProposalOption.S2CENC, BuiltinCiphers.Constants.NONE);
- I_C = sendKexInit(clientProposal);
+
+ Map<KexProposalOption,String> proposal = new EnumMap<KexProposalOption, String>(KexProposalOption.class);
+ synchronized(clientProposal) {
+ proposal.putAll(clientProposal);
+ }
+
+ proposal.put(KexProposalOption.C2SENC, BuiltinCiphers.Constants.NONE);
+ proposal.put(KexProposalOption.S2CENC, BuiltinCiphers.Constants.NONE);
+
+ byte[] seed = sendKexInit(proposal);
+ setKexSeed(seed);
}
return reexchangeFuture;
} else {
@@ -494,27 +513,26 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
}
@Override
- protected void sendKexInit() throws IOException {
- FactoryManager manager = getFactoryManager();
- String algs = NamedResource.Utils.getNames(manager.getSignatureFactories());
- Map<KexProposalOption,String> proposal = createProposal(algs);
- synchronized(clientProposal) {
- if (!clientProposal.isEmpty()) {
- clientProposal.clear(); // debug breakpoint
- }
-
- clientProposal.putAll(proposal);
- }
+ protected byte[] sendKexInit(Map<KexProposalOption,String> proposal) throws IOException {
+ mergeProposals(clientProposal, proposal);
+ return super.sendKexInit(proposal);
+ }
- I_C = sendKexInit(proposal);
+ @Override
+ protected void setKexSeed(byte... seed) {
+ I_C = ValidateUtils.checkNotNullAndNotEmpty(seed, "No KEX seed", GenericUtils.EMPTY_OBJECT_ARRAY);
}
@Override
- protected void receiveKexInit(Buffer buffer) throws IOException {
- if (!serverProposal.isEmpty()) {
- serverProposal.clear(); // debug breakpoint
- }
- I_S = receiveKexInit(buffer, serverProposal);
+ protected String resolveAvailableSignaturesProposal(FactoryManager manager) {
+ // the client does not have to provide keys for the available signatures
+ return NamedResource.Utils.getNames(manager.getSignatureFactories());
+ }
+
+ @Override
+ protected void receiveKexInit(Map<KexProposalOption,String> proposal, byte[] seed) throws IOException {
+ mergeProposals(serverProposal, proposal);
+ I_S = seed;
}
@Override
@@ -557,12 +575,11 @@ public class ClientSessionImpl extends AbstractSession implements ClientSession
@Override
public void startService(String name) throws Exception {
- throw new IllegalStateException("Starting services is not supported on the client side");
+ throw new IllegalStateException("Starting services is not supported on the client side: " + name);
}
@Override
public Map<Object, Object> getMetadataMap() {
return metadataMap;
}
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java b/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java
index 4f7b693..4c041bd 100644
--- a/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java
+++ b/sshd-core/src/main/java/org/apache/sshd/client/sftp/SftpFileSystemProvider.java
@@ -44,6 +44,7 @@ import java.nio.file.FileAlreadyExistsException;
import java.nio.file.FileStore;
import java.nio.file.FileSystem;
import java.nio.file.FileSystemAlreadyExistsException;
+import java.nio.file.FileSystemException;
import java.nio.file.FileSystemNotFoundException;
import java.nio.file.LinkOption;
import java.nio.file.NoSuchFileException;
@@ -180,7 +181,8 @@ public class SftpFileSystemProvider extends FileSystemProvider {
@Override
public Path getPath(URI uri) {
- return getFileSystem(uri).getPath(uri.getPath());
+ FileSystem fs = getFileSystem(uri);
+ return fs.getPath(uri.getPath());
}
@Override
@@ -229,12 +231,16 @@ public class SftpFileSystemProvider extends FileSystemProvider {
public DirectoryStream<Path> newDirectoryStream(Path dir, DirectoryStream.Filter<? super Path> filter) throws IOException {
final SftpPath p = toSftpPath(dir);
return new DirectoryStream<Path>() {
- final SftpClient sftp = p.getFileSystem().getClient();
- final Iterable<SftpClient.DirEntry> iter = sftp.readDir(p.toString());
+ private final SftpFileSystem fs = p.getFileSystem();
+ private final SftpClient sftp = fs.getClient();
+ private final Iterable<SftpClient.DirEntry> iter = sftp.readDir(p.toString());
+
@Override
public Iterator<Path> iterator() {
return new Iterator<Path>() {
- final Iterator<SftpClient.DirEntry> it = iter.iterator();
+ @SuppressWarnings("synthetic-access")
+ private final Iterator<SftpClient.DirEntry> it = iter.iterator();
+
@Override
public boolean hasNext() {
return it.hasNext();
@@ -263,7 +269,8 @@ public class SftpFileSystemProvider extends FileSystemProvider {
@Override
public void createDirectory(Path dir, FileAttribute<?>... attrs) throws IOException {
SftpPath p = toSftpPath(dir);
- try (SftpClient sftp = p.getFileSystem().getClient()) {
+ SftpFileSystem fs = p.getFileSystem();
+ try (SftpClient sftp = fs.getClient()) {
try {
sftp.mkdir(dir.toString());
} catch (SftpException e) {
@@ -293,7 +300,9 @@ public class SftpFileSystemProvider extends FileSystemProvider {
public void delete(Path path) throws IOException {
SftpPath p = toSftpPath(path);
checkAccess(p, AccessMode.WRITE);
- try (SftpClient sftp = p.getFileSystem().getClient()) {
+
+ SftpFileSystem fs = p.getFileSystem();
+ try (SftpClient sftp = fs.getClient()) {
BasicFileAttributes attributes = readAttributes(path, BasicFileAttributes.class);
if (attributes.isDirectory()) {
sftp.rmdir(path.toString());
@@ -308,7 +317,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
SftpPath src = toSftpPath(source);
SftpPath dst = toSftpPath(target);
if (src.getFileSystem() != dst.getFileSystem()) {
- throw new ProviderMismatchException("Mismatched file system providers");
+ throw new ProviderMismatchException("Mismatched file system providers for " + src + " vs. " + dst);
}
checkAccess(src);
@@ -323,9 +332,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
LinkOption[] linkOptions = IoUtils.getLinkOptions(!noFollowLinks);
// attributes of source file
- BasicFileAttributes attrs = readAttributes(source,
- BasicFileAttributes.class,
- linkOptions);
+ BasicFileAttributes attrs = readAttributes(source, BasicFileAttributes.class, linkOptions);
if (attrs.isSymbolicLink())
throw new IOException("Copying of symbolic links not supported");
@@ -357,9 +364,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
if (copyAttributes) {
BasicFileAttributeView view = getFileAttributeView(target, BasicFileAttributeView.class, linkOptions);
try {
- view.setTimes(attrs.lastModifiedTime(),
- attrs.lastAccessTime(),
- attrs.creationTime());
+ view.setTimes(attrs.lastModifiedTime(), attrs.lastAccessTime(), attrs.creationTime());
} catch (Throwable x) {
// rollback
try {
@@ -375,9 +380,11 @@ public class SftpFileSystemProvider extends FileSystemProvider {
@Override
public void move(Path source, Path target, CopyOption... options) throws IOException {
SftpPath src = toSftpPath(source);
+ SftpFileSystem fsSrc = src.getFileSystem();
SftpPath dst = toSftpPath(target);
+
if (src.getFileSystem() != dst.getFileSystem()) {
- throw new ProviderMismatchException();
+ throw new ProviderMismatchException("Mismatched file system providers for " + src + " vs. " + dst);
}
checkAccess(src);
@@ -392,11 +399,10 @@ public class SftpFileSystemProvider extends FileSystemProvider {
LinkOption[] linkOptions = IoUtils.getLinkOptions(noFollowLinks);
// attributes of source file
- BasicFileAttributes attrs = readAttributes(source,
- BasicFileAttributes.class,
- linkOptions);
- if (attrs.isSymbolicLink())
+ BasicFileAttributes attrs = readAttributes(source, BasicFileAttributes.class, linkOptions);
+ if (attrs.isSymbolicLink()) {
throw new IOException("Copying of symbolic links not supported");
+ }
// delete target if it exists and REPLACE_EXISTING is specified
Boolean status=IoUtils.checkFileExists(target, linkOptions);
@@ -406,10 +412,11 @@ public class SftpFileSystemProvider extends FileSystemProvider {
if (replaceExisting) {
deleteIfExists(target);
- } else if (status.booleanValue())
+ } else if (status.booleanValue()) {
throw new FileAlreadyExistsException(target.toString());
+ }
- try (SftpClient sftp = src.getFileSystem().getClient()) {
+ try (SftpClient sftp = fsSrc.getClient()) {
sftp.rename(src.toString(), dst.toString());
}
@@ -417,9 +424,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
if (copyAttributes) {
BasicFileAttributeView view = getFileAttributeView(target, BasicFileAttributeView.class, linkOptions);
try {
- view.setTimes(attrs.lastModifiedTime(),
- attrs.lastAccessTime(),
- attrs.creationTime());
+ view.setTimes(attrs.lastModifiedTime(), attrs.lastAccessTime(), attrs.creationTime());
} catch (Throwable x) {
// rollback
try {
@@ -437,7 +442,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {
SftpPath p1 = toSftpPath(path1);
SftpPath p2 = toSftpPath(path2);
if (p1.getFileSystem() != p2.getFileSystem()) {
- throw new ProviderMismatchException();
+ throw new ProviderMismatchException("Mismatched file system providers for " + p1 + " vs. " + p2);
}
checkAccess(p1);
checkAccess(p2);
@@ -451,17 +456,18 @@ public class SftpFileSystemProvider extends FileSystemProvider {
@Override
public FileStore getFileStore(Path path) throws IOException {
- throw new UnsupportedOperationException("getFileStore(" + path + ") N/A");
+ throw new FileSystemException(path.toString(), path.toString(), "getFileStore(" + path + ") N/A");
}
@Override
public void createSymbolicLink(Path link, Path target, FileAttribute<?>... attrs) throws IOException {
SftpPath l = toSftpPath(link);
+ SftpFileSystem fsLink = l.getFileSystem();
SftpPath t = toSftpPath(target);
- if (l.getFileSystem() != t.getFileSystem()) {
- throw new ProviderMismatchException();
+ if (fsLink != t.getFileSystem()) {
+ throw new ProviderMismatchException("Mismatched file system providers for " + l + " vs. " + t);
}
- try (SftpClient client = l.getFileSystem().getClient()) {
+ try (SftpClient client = fsLink.getClient()) {
client.symLink(l.toString(), t.toString());
}
}
@@ -469,8 +475,9 @@ public class SftpFileSystemProvider extends FileSystemProvider {
@Override
public Path readSymbolicLink(Path link) throws IOException {
SftpPath l = toSftpPath(link);
- try (SftpClient client = l.getFileSystem().getClient()) {
- return l.getFileSystem().getPath(client.readLink(l.toString()));
+ SftpFileSystem fsLink = l.getFileSystem();
+ try (SftpClient client = fsLink.getClient()) {
+ return fsLink.getPath(client.readLink(l.toString()));
}
}
@@ -500,7 +507,9 @@ public class SftpFileSystemProvider extends FileSystemProvider {
if ((attrs == null) && !(p.isAbsolute() && p.getNameCount() == 0)) {
throw new NoSuchFileException(path.toString());
}
- if (x || (w && p.getFileSystem().isReadOnly())) {
+
+ SftpFileSystem fs = p.getFileSystem();
+ if (x || (w && fs.isReadOnly())) {
throw new AccessDeniedException(path.toString());
}
}
@@ -519,8 +528,9 @@ public class SftpFileSystemProvider extends FileSystemProvider {
@Override
public PosixFileAttributes readAttributes() throws IOException {
SftpPath p = toSftpPath(path);
+ SftpFileSystem fs = p.getFileSystem();
final SftpClient.Attributes attributes;
- try (SftpClient client = p.getFileSystem().getClient()) {
+ try (SftpClient client =fs.getClient()) {
try {
if (followLinks(options)) {
attributes = client.stat(p.toString());
@@ -658,8 +668,10 @@ public class SftpFileSystemProvider extends FileSystemProvider {
attrs = attributes.substring(i);
}
SftpPath p = toSftpPath(path);
- if (!p.getFileSystem().supportedFileAttributeViews().contains(view)) {
- throw new UnsupportedOperationException("readAttributes(" + path + ")[" + attributes + "] view not supported: " + view);
+ SftpFileSystem fs = p.getFileSystem();
+ Collection<String> views = fs.supportedFileAttributeViews();
+ if (GenericUtils.isEmpty(views) || (!views.contains(view))) {
+ throw new UnsupportedOperationException("readAttributes(" + path + ")[" + attributes + "] view " + view + " not supported: " + views);
}
PosixFileAttributes v = readAttributes(path, PosixFileAttributes.class, options);
@@ -727,8 +739,10 @@ public class SftpFileSystemProvider extends FileSystemProvider {
attr = attribute.substring(i);
}
SftpPath p = toSftpPath(path);
- if (!p.getFileSystem().supportedFileAttributeViews().contains(view)) {
- throw new UnsupportedOperationException("setAttribute(" + path + ")[" + attribute + "=" + value + "] view not supported: " + view);
+ SftpFileSystem fs = p.getFileSystem();
+ Collection<String> views = fs.supportedFileAttributeViews();
+ if (GenericUtils.isEmpty(views) || (!view.contains(view))) {
+ throw new UnsupportedOperationException("setAttribute(" + path + ")[" + attribute + "=" + value + "] view " + view + " not supported: " + views);
}
SftpClient.Attributes attributes = new SftpClient.Attributes();
@@ -770,17 +784,15 @@ public class SftpFileSystemProvider extends FileSystemProvider {
}
}
- try (SftpClient client = p.getFileSystem().getClient()) {
+ try (SftpClient client = fs.getClient()) {
client.setStat(p.toString(), attributes);
}
}
private SftpPath toSftpPath(Path path) {
- if (path == null) {
- throw new NullPointerException();
- }
+ ValidateUtils.checkNotNull(path, "No path provided", GenericUtils.EMPTY_OBJECT_ARRAY);
if (!(path instanceof SftpPath)) {
- throw new ProviderMismatchException();
+ throw new ProviderMismatchException("Path is not SFTP: " + path);
}
return (SftpPath) path;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/common/file/util/BasePath.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/file/util/BasePath.java b/sshd-core/src/main/java/org/apache/sshd/common/file/util/BasePath.java
index a74b1c0..3286a8d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/file/util/BasePath.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/file/util/BasePath.java
@@ -38,6 +38,7 @@ import java.util.List;
import java.util.Objects;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
public abstract class BasePath<T extends BasePath<T, FS>, FS extends BaseFileSystem<T>> implements Path {
@@ -238,9 +239,7 @@ public abstract class BasePath<T extends BasePath<T, FS>, FS extends BaseFileSys
@Override
public Path resolveSibling(Path other) {
- if (other == null) {
- throw new NullPointerException("Missing sibling path argument");
- }
+ ValidateUtils.checkNotNull(other, "Missing sibling path argument", GenericUtils.EMPTY_OBJECT_ARRAY);
T parent = getParent();
return parent == null ? other : parent.resolve(other);
}
@@ -357,11 +356,9 @@ public abstract class BasePath<T extends BasePath<T, FS>, FS extends BaseFileSys
@SuppressWarnings("unchecked")
private T checkPath(Path paramPath) {
- if (paramPath == null) {
- throw new NullPointerException();
- }
+ ValidateUtils.checkNotNull(paramPath, "Missing path argument", GenericUtils.EMPTY_OBJECT_ARRAY);
if (paramPath.getClass() != getClass()) {
- throw new ProviderMismatchException();
+ throw new ProviderMismatchException("Path is not of this class: " + paramPath + "[" + paramPath.getClass().getSimpleName() + "]");
}
T t = (T) paramPath;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/common/future/DefaultSshFuture.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/future/DefaultSshFuture.java b/sshd-core/src/main/java/org/apache/sshd/common/future/DefaultSshFuture.java
index 0ee8afe..39ae862 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/future/DefaultSshFuture.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/future/DefaultSshFuture.java
@@ -21,6 +21,8 @@ package org.apache.sshd.common.future;
import java.lang.reflect.Array;
import java.util.concurrent.TimeUnit;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.logging.AbstractLoggingBean;
/**
@@ -46,9 +48,6 @@ public class DefaultSshFuture<T extends SshFuture> extends AbstractLoggingBean i
this.lock = lock != null ? lock : this;
}
- /**
- * {@inheritDoc}
- */
@Override
public T await() throws InterruptedException {
if (await0(Long.MAX_VALUE, true) == null) {
@@ -58,25 +57,16 @@ public class DefaultSshFuture<T extends SshFuture> extends AbstractLoggingBean i
return asT();
}
- /**
- * {@inheritDoc}
- */
@Override
public boolean await(long timeout, TimeUnit unit) throws InterruptedException {
return await(unit.toMillis(timeout));
}
- /**
- * {@inheritDoc}
- */
@Override
public boolean await(long timeoutMillis) throws InterruptedException {
return await0(timeoutMillis, true) != null;
}
- /**
- * {@inheritDoc}
- */
@Override
public T awaitUninterruptibly() {
try {
@@ -88,17 +78,11 @@ public class DefaultSshFuture<T extends SshFuture> extends AbstractLoggingBean i
return asT();
}
- /**
- * {@inheritDoc}
- */
@Override
public boolean awaitUninterruptibly(long timeout, TimeUnit unit) {
return awaitUninterruptibly(unit.toMillis(timeout));
}
- /**
- * {@inheritDoc}
- */
@Override
public boolean awaitUninterruptibly(long timeoutMillis) {
try {
@@ -144,9 +128,6 @@ public class DefaultSshFuture<T extends SshFuture> extends AbstractLoggingBean i
}
}
- /**
- * {@inheritDoc}
- */
@Override
public boolean isDone() {
synchronized (lock) {
@@ -180,15 +161,9 @@ public class DefaultSshFuture<T extends SshFuture> extends AbstractLoggingBean i
}
}
- /**
- * {@inheritDoc}
- */
@Override
public T addListener(SshFutureListener<T> listener) {
- if (listener == null) {
- throw new NullPointerException("listener");
- }
-
+ ValidateUtils.checkNotNull(listener, "Missing listener argument", GenericUtils.EMPTY_OBJECT_ARRAY);
boolean notifyNow = false;
synchronized (lock) {
if (result != null) {
@@ -215,14 +190,9 @@ public class DefaultSshFuture<T extends SshFuture> extends AbstractLoggingBean i
return asT();
}
- /**
- * {@inheritDoc}
- */
@Override
public T removeListener(SshFutureListener<T> listener) {
- if (listener == null) {
- throw new NullPointerException("listener");
- }
+ ValidateUtils.checkNotNull(listener, "No listener provided", GenericUtils.EMPTY_OBJECT_ARRAY);
synchronized (lock) {
if (result == null) {
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java b/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java
index 9abbaa4..67078b0 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/kex/dh/AbstractDHKeyExchange.java
@@ -64,5 +64,4 @@ public abstract class AbstractDHKeyExchange extends AbstractLoggingBean implemen
public byte[] getK() {
return K;
}
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/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 5b60279..1874494 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
@@ -239,30 +239,22 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea
return clientVersion;
}
+ @Override
public KeyExchange getKex() {
return kex;
}
- public byte [] getSessionId() {
- return sessionId;
+ @Override
+ public byte[] getSessionId() {
+ // return a clone to avoid anyone changing the internal value
+ return GenericUtils.isEmpty(sessionId) ? sessionId : sessionId.clone();
}
-
- /**
- * Retrieve the mina session
- *
- * @return the mina session
- */
@Override
public IoSession getIoSession() {
return ioSession;
}
- /**
- * Retrieve the factory manager
- *
- * @return the factory manager for this session
- */
@Override
public FactoryManager getFactoryManager() {
return factoryManager;
@@ -277,14 +269,12 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea
}
}
+ @Override
public boolean isAuthenticated() {
return authed;
}
- public void setUsername(String username) {
- this.username = username;
- }
-
+ @Override
public void setAuthenticated() throws IOException {
this.authed = true;
sendEvent(SessionListener.Event.Authenticated);
@@ -1183,21 +1173,13 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea
return E;
}
- /**
- * Send a disconnect packet with the given reason and message.
- * Once the packet has been sent, the session will be closed
- * asynchronously.
- *
- * @param reason the reason code for this disconnect
- * @param msg the text message
- * @throws IOException if an error occured sending the packet
- */
+ @Override
public void disconnect(int reason, String msg) throws IOException {
- log.info("Disconnecting: {}", msg);
+ log.info("Disconnecting: {} - {}", Integer.valueOf(reason), msg);
Buffer buffer = createBuffer(SshConstants.SSH_MSG_DISCONNECT);
buffer.putInt(reason);
buffer.putString(msg);
- buffer.putString("");
+ buffer.putString(""); // language...
// Write the packet with a timeout to ensure a timely close of the session
// in case the consumer does not read packets anymore.
writePacket(buffer, disconnectTimeoutMs, TimeUnit.MILLISECONDS).addListener(new SshFutureListener<IoWriteFuture>() {
@@ -1366,22 +1348,21 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea
return username;
}
+ @Override
+ public void setUsername(String username) {
+ this.username = username;
+ }
+
public Object getLock() {
return lock;
}
- /**
- * {@inheritDoc}
- */
@Override
public void addListener(SessionListener listener) {
ValidateUtils.checkNotNull(listener, "addListener(%s) null instance", this);
this.listeners.add(listener);
}
- /**
- * {@inheritDoc}
- */
@Override
public void removeListener(SessionListener listener) {
this.listeners.remove(listener);
@@ -1406,18 +1387,80 @@ public abstract class AbstractSession extends CloseableUtils.AbstractInnerClosea
// nothing
}
- protected abstract void sendKexInit() throws IOException;
+ protected byte[] sendKexInit() throws IOException {
+ String resolvedAlgorithms = resolveAvailableSignaturesProposal();
+ if (GenericUtils.isEmpty(resolvedAlgorithms)) {
+ throw new SshException(SshConstants.SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE,
+ "sendKexInit() no resolved signatures available");
+ }
+
+ Map<KexProposalOption,String> proposal = createProposal(resolvedAlgorithms);
+ byte[] seed = sendKexInit(proposal);
+ if (log.isDebugEnabled()) {
+ log.debug("sendKexInit(" + proposal + ") seed: " + BufferUtils.printHex(':', seed));
+ }
+ setKexSeed(seed);
+ return seed;
+ }
+
+ /**
+ * @param seed The result of the KEXINIT handshake - required for correct
+ * session key establishment
+ */
+ protected abstract void setKexSeed(byte ... seed);
+
+ /**
+ * @return A comma-separated list of all the signature protocols to be
+ * included in the proposal - {@code null}/empty if no proposal
+ * @see #getFactoryManager()
+ * @see #resolveAvailableSignaturesProposal(FactoryManager)
+ */
+ protected String resolveAvailableSignaturesProposal() {
+ return resolveAvailableSignaturesProposal(getFactoryManager());
+ }
+
+ /**
+ * @param manager The {@link FactoryManager}
+ * @return A comma-separated list of all the signature protocols to be
+ * included in the proposal - {@code null}/empty if no proposal
+ */
+ protected abstract String resolveAvailableSignaturesProposal(FactoryManager manager);
protected abstract void checkKeys() throws IOException;
- protected abstract void receiveKexInit(Buffer buffer) throws IOException;
+ protected void receiveKexInit(Buffer buffer) throws IOException {
+ Map<KexProposalOption,String> proposal = new EnumMap<KexProposalOption, String>(KexProposalOption.class);
+ byte[] seed = receiveKexInit(buffer, proposal);
+ receiveKexInit(proposal, seed);
+ }
+
+ protected abstract void receiveKexInit(Map<KexProposalOption,String> proposal, byte[] seed) throws IOException;
+
+ // returns the proposal argument
+ protected Map<KexProposalOption,String> mergeProposals(Map<KexProposalOption,String> current, Map<KexProposalOption,String> proposal) {
+ if (current == proposal) {
+ return proposal; // debug breakpoint
+ }
+
+ synchronized(current) {
+ if (!current.isEmpty()) {
+ current.clear(); // debug breakpoint
+ }
+
+ if (GenericUtils.isEmpty(proposal)) {
+ return proposal; // debug breakpoint
+ }
+
+ current.putAll(proposal);
+ }
+
+ return proposal;
+ }
protected void serviceAccept() throws IOException {
// nothing
}
- public abstract void startService(String name) throws Exception;
-
/**
* Checks whether the session has timed out (both auth and idle timeouts are checked). If the session has
* timed out, a DISCONNECT message will be sent.
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
index 6bda1ec..ededad2 100644
--- a/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
+++ b/sshd-core/src/main/java/org/apache/sshd/common/session/Session.java
@@ -28,6 +28,7 @@ import org.apache.sshd.common.future.SshFuture;
import org.apache.sshd.common.io.IoSession;
import org.apache.sshd.common.io.IoWriteFuture;
import org.apache.sshd.common.kex.KexProposalOption;
+import org.apache.sshd.common.kex.KeyExchange;
import org.apache.sshd.common.util.buffer.Buffer;
/**
@@ -70,6 +71,7 @@ public interface Session extends Closeable {
* @return the user name.
*/
String getUsername();
+ void setUsername(String username);
/**
* Retrieve the client version for this session.
@@ -86,9 +88,7 @@ public interface Session extends Closeable {
String getServerVersion();
/**
- * Retrieve the FactoryManager that has created this session
- *
- * @return the factory manager, can not be <tt>null</tt>.
+ * @return the {@link FactoryManager} that has created this session, can not be {@code null}
*/
FactoryManager getFactoryManager();
@@ -237,24 +237,44 @@ public interface Session extends Closeable {
}
}
- public void resetIdleTimeout();
+ void resetIdleTimeout();
/**
* Check if timeout has occurred.
* @return the timeout status, never <code>null</code>
*/
- public TimeoutStatus getTimeoutStatus();
+ TimeoutStatus getTimeoutStatus();
/**
- * What is timeout value in milliseconds for authentication stage
- * @return
+ * @return Timeout value in milliseconds for authentication stage
*/
- public long getAuthTimeout();
+ long getAuthTimeout();
/**
- * What is timeout value in milliseconds for communication
- * @return
+ * @return Timeout value in milliseconds for communication
*/
+ long getIdleTimeout();
+
+ boolean isAuthenticated();
+ void setAuthenticated() throws IOException;
+
+ byte[] getSessionId();
+ KeyExchange getKex();
- public long getIdleTimeout();
+ /**
+ * Send a disconnect packet with the given reason and message.
+ * Once the packet has been sent, the session will be closed
+ * asynchronously.
+ *
+ * @param reason the reason code for this disconnect
+ * @param msg the text message
+ * @throws IOException if an error occurred sending the packet
+ */
+ void disconnect(int reason, String msg) throws IOException;
+
+ /**
+ * @param name Service name
+ * @throws Exception If failed to start it
+ */
+ void startService(String name) throws Exception;
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/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 27cf000..a14bea8 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
@@ -199,6 +199,14 @@ public final class GenericUtils {
}
}
+ public static final boolean isEmpty(byte[] a) {
+ if (length(a) <= 0) {
+ return true;
+ } else {
+ return false;
+ }
+ }
+
public static final int length(byte ... a) {
if (a == null) {
return 0;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/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 0009a14..4432aa4 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
@@ -67,6 +67,12 @@ public final class ValidateUtils {
return t;
}
+ public static final byte[] checkNotNullAndNotEmpty(byte[] t, String message, Object ... args) {
+ t = checkNotNull(t, message, args);
+ checkTrue(GenericUtils.length(t) > 0, message, args);
+ return t;
+ }
+
public static final <T> T[] checkNotNullAndNotEmpty(T[] t, String message, Object ... args) {
t = checkNotNull(t, message, args);
checkTrue(GenericUtils.length(t) > 0, message, args);
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java b/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
index 99368f9..a86dce8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/ServerFactoryManager.java
@@ -35,23 +35,23 @@ public interface ServerFactoryManager extends FactoryManager {
/**
* Key used to retrieve the value of the maximum concurrent open session count per username
*/
- public static final String MAX_CONCURRENT_SESSIONS = "max-concurrent-sessions";
+ String MAX_CONCURRENT_SESSIONS = "max-concurrent-sessions";
/**
* Key used to retrieve the value of the server identification string if not default.
*/
- public static final String SERVER_IDENTIFICATION = "server-identification";
+ String SERVER_IDENTIFICATION = "server-identification";
/**
* Key used to retrieve the value in the configuration properties map
* of the maximum number of failed authentication requests before the
* server closes the connection.
*/
- public static final String MAX_AUTH_REQUESTS = "max-auth-requests";
+ String MAX_AUTH_REQUESTS = "max-auth-requests";
/**
* Key used to retrieve the value of welcome banner that will be displayed
* when a user connects to the server.
*/
- public static final String WELCOME_BANNER = "welcome-banner";
+ String WELCOME_BANNER = "welcome-banner";
/**
* This key is used when configuring multi-step authentications.
@@ -65,34 +65,34 @@ public interface ServerFactoryManager extends FactoryManager {
* stage, so for this example, it would not be possible to attempt
* password or keyboard-interactive authentication before public key.
*/
- public static final String AUTH_METHODS = "auth-methods";
+ String AUTH_METHODS = "auth-methods";
/**
* Key used to configure the timeout used when receiving a close request
* on a channel to wait until the command cleanly exits after setting
* an EOF on the input stream. In milliseconds.
*/
- public static final String COMMAND_EXIT_TIMEOUT = "command-exit-timeout";
+ String COMMAND_EXIT_TIMEOUT = "command-exit-timeout";
/**
* Key re-exchange will be automatically performed after the session
* has sent or received the given amount of bytes.
* The default value is 1 gigabyte.
*/
- public static final String REKEY_BYTES_LIMIT = "rekey-bytes-limit";
+ String REKEY_BYTES_LIMIT = "rekey-bytes-limit";
/**
* Key re-exchange will be automatically performed after the specified
* amount of time has elapsed since the last key exchange. In milliseconds.
* The default value is 1 hour.
*/
- public static final String REKEY_TIME_LIMIT = "rekey-time-limit";
+ String REKEY_TIME_LIMIT = "rekey-time-limit";
/**
* A URL pointing to the moduli file.
* If not specified, the default internal file will be used.
*/
- public static final String MODULI_URL = "moduli-url";
+ String MODULI_URL = "moduli-url";
/**
* Retrieve the list of named factories for <code>UserAuth</code> objects.
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/SessionAware.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/SessionAware.java b/sshd-core/src/main/java/org/apache/sshd/server/SessionAware.java
index d133363..b5b6d86 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/SessionAware.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/SessionAware.java
@@ -27,9 +27,7 @@ import org.apache.sshd.server.session.ServerSession;
public interface SessionAware {
/**
- * Set the server session in which this shell will be executed.
- *
- * @param session
+ * @param session The {@link ServerSession} in which this shell will be executed.
*/
void setSession(ServerSession session);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/auth/AbstractUserAuth.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/AbstractUserAuth.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/AbstractUserAuth.java
index d334edb..c766310 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/AbstractUserAuth.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/AbstractUserAuth.java
@@ -30,6 +30,10 @@ public abstract class AbstractUserAuth extends AbstractLoggingBean implements Us
protected String service;
protected String username;
+ protected AbstractUserAuth() {
+ super();
+ }
+
@Override
public String getUserName() {
return username;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthKeyboardInteractive.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthKeyboardInteractive.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthKeyboardInteractive.java
index 83db703..2972a9d 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthKeyboardInteractive.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthKeyboardInteractive.java
@@ -21,8 +21,11 @@ package org.apache.sshd.server.auth;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshException;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.server.PasswordAuthenticator;
+import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.UserAuth;
import org.apache.sshd.server.session.ServerSession;
@@ -51,6 +54,10 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
}
}
+ public UserAuthKeyboardInteractive() {
+ super();
+ }
+
@Override
protected Boolean doAuth(Buffer buffer, boolean init) throws Exception {
if (init) {
@@ -78,12 +85,13 @@ public class UserAuthKeyboardInteractive extends AbstractUserAuth {
}
}
- private boolean checkPassword(ServerSession session, String username, String password) throws Exception {
- PasswordAuthenticator auth = session.getFactoryManager().getPasswordAuthenticator();
- if (auth != null) {
- return auth.authenticate(username, password, session);
- }
- throw new Exception("No PasswordAuthenticator configured");
+ protected boolean checkPassword(ServerSession session, String username, String password) throws Exception {
+ ServerFactoryManager manager = session.getFactoryManager();
+ PasswordAuthenticator auth = ValidateUtils.checkNotNull(
+ manager.getPasswordAuthenticator(),
+ "No PasswordAuthenticator configured",
+ GenericUtils.EMPTY_BYTE_ARRAY);
+ return auth.authenticate(username, password, session);
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthNone.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthNone.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthNone.java
index 46d23f9..f25fd52 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthNone.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthNone.java
@@ -46,6 +46,10 @@ public class UserAuthNone extends AbstractUserAuth {
}
}
+ public UserAuthNone() {
+ super();
+ }
+
@Override
public Boolean doAuth(Buffer buffer, boolean init) {
return Boolean.TRUE;
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPassword.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPassword.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPassword.java
index 273b125..9168b99 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPassword.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPassword.java
@@ -19,8 +19,11 @@
package org.apache.sshd.server.auth;
import org.apache.sshd.common.NamedFactory;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.server.PasswordAuthenticator;
+import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.UserAuth;
import org.apache.sshd.server.session.ServerSession;
@@ -48,6 +51,10 @@ public class UserAuthPassword extends AbstractUserAuth {
}
}
+ public UserAuthPassword() {
+ super();
+ }
+
@Override
public Boolean doAuth(Buffer buffer, boolean init) throws Exception {
if (!init) {
@@ -61,12 +68,12 @@ public class UserAuthPassword extends AbstractUserAuth {
return Boolean.valueOf(checkPassword(session, username, password));
}
- private boolean checkPassword(ServerSession session, String username, String password) throws Exception {
- PasswordAuthenticator auth = session.getFactoryManager().getPasswordAuthenticator();
- if (auth != null) {
- return auth.authenticate(username, password, session);
- }
- throw new Exception("No PasswordAuthenticator configured");
+ protected boolean checkPassword(ServerSession session, String username, String password) throws Exception {
+ ServerFactoryManager manager = session.getFactoryManager();
+ PasswordAuthenticator auth = ValidateUtils.checkNotNull(
+ manager.getPasswordAuthenticator(),
+ "No PasswordAuthenticator configured",
+ GenericUtils.EMPTY_OBJECT_ARRAY);
+ return auth.authenticate(username, password, session);
}
-
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
index 9e7d269..1c468b3 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/UserAuthPublicKey.java
@@ -57,11 +57,13 @@ public class UserAuthPublicKey extends AbstractUserAuth {
}
}
+ public UserAuthPublicKey() {
+ super();
+ }
+
@Override
public Boolean doAuth(Buffer buffer, boolean init) throws Exception {
- if (!init) {
- throw new IllegalStateException();
- }
+ ValidateUtils.checkTrue(init, "Instance not initialized", GenericUtils.EMPTY_OBJECT_ARRAY);
boolean hasSig = buffer.getBoolean();
String alg = buffer.getString();
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java b/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java
index 5422cf0..7ed9ec8 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/auth/gss/UserAuthGSS.java
@@ -21,8 +21,11 @@ package org.apache.sshd.server.auth.gss;
import org.apache.sshd.common.NamedFactory;
import org.apache.sshd.common.SshConstants;
import org.apache.sshd.common.SshException;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.server.ServerFactoryManager;
import org.apache.sshd.server.UserAuth;
import org.apache.sshd.server.auth.AbstractUserAuth;
import org.apache.sshd.server.session.ServerSession;
@@ -124,7 +127,7 @@ public class UserAuthGSS extends AbstractUserAuth {
Buffer msgbuf = new ByteArrayBuffer();
- msgbuf.putBytes(session.getSessionId());
+ msgbuf.putBytes(ValidateUtils.checkNotNullAndNotEmpty(session.getSessionId(), "No current session ID", GenericUtils.EMPTY_OBJECT_ARRAY));
msgbuf.putByte(SshConstants.SSH_MSG_USERAUTH_REQUEST);
msgbuf.putString(username);
msgbuf.putString(service);
@@ -206,18 +209,13 @@ public class UserAuthGSS extends AbstractUserAuth {
/**
* Utility to get the configured GSS authenticator for the server, throwing an exception if none is available.
*
- * @param session The current session
- * @return The GSS authenticator
+ * @param session The current {@link ServerSession}
+ * @return The {@link GSSAuthenticator} - never {@code null)
* @throws Exception If no GSS authenticator is defined
*/
- private GSSAuthenticator getAuthenticator(ServerSession session) throws Exception {
- GSSAuthenticator ga = session.getFactoryManager().getGSSAuthenticator();
-
- if (ga == null) {
- throw new Exception("No GSSAuthenticator configured");
- } else {
- return ga;
- }
+ protected GSSAuthenticator getAuthenticator(ServerSession session) throws Exception {
+ ServerFactoryManager manager = session.getFactoryManager();
+ return ValidateUtils.checkNotNull(manager.getGSSAuthenticator(), "No GSSAuthenticator configured", GenericUtils.EMPTY_OBJECT_ARRAY);
}
/**
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
index 44069cb..7edc72e 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/channel/ChannelSession.java
@@ -34,6 +34,7 @@ import java.util.concurrent.TimeUnit;
import org.apache.sshd.agent.SshAgent;
import org.apache.sshd.agent.SshAgentFactory;
import org.apache.sshd.common.Closeable;
+import org.apache.sshd.common.Factory;
import org.apache.sshd.common.FactoryManager;
import org.apache.sshd.common.FactoryManagerUtils;
import org.apache.sshd.common.NamedFactory;
@@ -50,6 +51,7 @@ import org.apache.sshd.common.future.DefaultCloseFuture;
import org.apache.sshd.common.future.SshFutureListener;
import org.apache.sshd.common.util.CloseableUtils;
import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.common.util.buffer.Buffer;
import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
import org.apache.sshd.common.util.io.IoUtils;
@@ -57,6 +59,7 @@ import org.apache.sshd.common.util.io.LoggingFilterOutputStream;
import org.apache.sshd.server.AsyncCommand;
import org.apache.sshd.server.ChannelSessionAware;
import org.apache.sshd.server.Command;
+import org.apache.sshd.server.CommandFactory;
import org.apache.sshd.server.Environment;
import org.apache.sshd.server.ExitCallback;
import org.apache.sshd.server.ServerFactoryManager;
@@ -457,12 +460,22 @@ public class ChannelSession extends AbstractServerChannel {
protected boolean handleShell(Buffer buffer) throws IOException {
// If we're already closing, ignore incoming data
if (isClosing()) {
+ log.debug("handleShell - closing");
return false;
}
- if (((ServerSession) session).getFactoryManager().getShellFactory() == null) {
+
+ ServerFactoryManager manager = ((ServerSession) session).getFactoryManager();
+ Factory<Command> factory = manager.getShellFactory();
+ if (factory == null) {
+ log.debug("handleShell - no shell factory");
return false;
}
- command = ((ServerSession) session).getFactoryManager().getShellFactory().create();
+
+ if ((command = factory.create()) == null) {
+ log.debug("handleShell - no shell command");
+ return false;
+ }
+
prepareCommand();
command.start(getEnvironment());
return true;
@@ -474,17 +487,19 @@ public class ChannelSession extends AbstractServerChannel {
return false;
}
String commandLine = buffer.getString();
- if (((ServerSession) session).getFactoryManager().getCommandFactory() == null) {
- log.warn("Unsupported command: {}", commandLine);
+ ServerFactoryManager manager = ((ServerSession) session).getFactoryManager();
+ CommandFactory factory = manager.getCommandFactory();
+ if (factory == null) {
+ log.warn("No command factory for command: {}", commandLine);
return false;
}
if (log.isInfoEnabled()) {
log.info("Executing command: {}", commandLine);
}
try {
- command = ((ServerSession) session).getFactoryManager().getCommandFactory().createCommand(commandLine);
- } catch (IllegalArgumentException iae) {
- // TODO: Shouldn't we log errors on the server side?
+ command = factory.createCommand(commandLine);
+ } catch (RuntimeException iae) {
+ log.warn("Failed (" + iae.getClass().getSimpleName() + ") to execute " + commandLine + ": " + iae.getMessage());
return false;
}
prepareCommand();
@@ -495,13 +510,14 @@ public class ChannelSession extends AbstractServerChannel {
protected boolean handleSubsystem(Buffer buffer) throws IOException {
String subsystem = buffer.getString();
- List<NamedFactory<Command>> factories = ((ServerSession) session).getFactoryManager().getSubsystemFactories();
- if (factories == null) {
- log.warn("Unsupported subsystem: {}", subsystem);
+ ServerFactoryManager manager = ((ServerSession) session).getFactoryManager();
+ List<NamedFactory<Command>> factories = manager.getSubsystemFactories();
+ if (GenericUtils.isEmpty(factories)) {
+ log.warn("No factories for subsystem: {}", subsystem);
return false;
}
- command = NamedFactory.Utils.create(factories, subsystem);
- if (command == null) {
+
+ if ((command = NamedFactory.Utils.create(factories, subsystem)) == null) {
log.warn("Unsupported subsystem: {}", subsystem);
return false;
}
@@ -596,11 +612,11 @@ public class ChannelSession extends AbstractServerChannel {
}
protected boolean handleAgentForwarding(Buffer buffer) throws IOException {
- ServerSession server = (ServerSession) session;
- FactoryManager manager = server.getFactoryManager();
+ ValidateUtils.checkTrue(session instanceof ServerSession, "Session not a server one", GenericUtils.EMPTY_OBJECT_ARRAY);
+ FactoryManager manager = session.getFactoryManager();
ForwardingFilter filter = manager.getTcpipForwardingFilter();
SshAgentFactory factory = manager.getAgentFactory();
- if ((factory == null) || (filter == null) || (!filter.canForwardAgent(server))) {
+ if ((factory == null) || (filter == null) || (!filter.canForwardAgent(session))) {
if (log.isDebugEnabled()) {
log.debug("handleAgentForwarding(" + session + ")[haveFactory=" + (factory != null) + ",haveFilter=" + (filter != null) + "] filtered out");
}
@@ -613,9 +629,10 @@ public class ChannelSession extends AbstractServerChannel {
}
protected boolean handleX11Forwarding(Buffer buffer) throws IOException {
- ServerSession server = (ServerSession) session;
- ForwardingFilter filter = server.getFactoryManager().getTcpipForwardingFilter();
- if ((filter == null) || (!filter.canForwardX11(server))) {
+ ValidateUtils.checkTrue(session instanceof ServerSession, "Session not a server one", GenericUtils.EMPTY_OBJECT_ARRAY);
+ FactoryManager manager = session.getFactoryManager();
+ ForwardingFilter filter = manager.getTcpipForwardingFilter();
+ if ((filter == null) || (!filter.canForwardX11(session))) {
if (log.isDebugEnabled()) {
log.debug("handleX11Forwarding(" + session + ")[haveFilter=" + (filter != null) + "] filtered out");
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java
index 69d7107..6125a63 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/config/keys/AuthorizedKeysAuthenticator.java
@@ -96,7 +96,8 @@ public class AuthorizedKeysAuthenticator extends ModifiableFileWatcher implement
}
}
- protected PublickeyAuthenticator resolvePublickeyAuthenticator(String username, ServerSession session) throws IOException, GeneralSecurityException {
+ protected PublickeyAuthenticator resolvePublickeyAuthenticator(String username, ServerSession session)
+ throws IOException, GeneralSecurityException {
if (checkReloadRequired()) {
/* Start fresh - NOTE: if there is any error then we want to reject all attempts
* since we don't want to remain with the previous data - safer that way
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java b/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java
index 0f4ea2a..266801c 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/jaas/JaasPasswordAuthenticator.java
@@ -58,7 +58,7 @@ public class JaasPasswordAuthenticator extends AbstractLoggingBean implements Pa
}
@Override
- public boolean authenticate(final String username, final String password, final ServerSession session) {
+ public boolean authenticate(String username, String password, ServerSession session) {
return authenticate(username, password);
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java b/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java
index 169efe6..0b7076b 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/AbstractDHServerKeyExchange.java
@@ -23,6 +23,8 @@ import java.security.PublicKey;
import org.apache.sshd.common.kex.dh.AbstractDHKeyExchange;
import org.apache.sshd.common.session.AbstractSession;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
import org.apache.sshd.server.session.ServerSession;
/**
@@ -39,14 +41,12 @@ public abstract class AbstractDHServerKeyExchange extends AbstractDHKeyExchange
@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);
- if (!(s instanceof ServerSession)) {
- throw new IllegalStateException("Using a server side KeyExchange on a client");
- }
+ ValidateUtils.checkTrue(s instanceof ServerSession, "Using a server side KeyExchange on a client", GenericUtils.EMPTY_OBJECT_ARRAY);
session = (ServerSession) s;
}
@Override
public PublicKey getServerKey() {
- return session.getHostKey().getPublic();
+ return ValidateUtils.checkNotNull(session.getHostKey(), "No server key pair available", GenericUtils.EMPTY_OBJECT_ARRAY).getPublic();
}
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
index 7cc569e..3a8a194 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGEXServer.java
@@ -157,7 +157,7 @@ public class DHGEXServer extends AbstractDHServerKeyExchange {
byte[] K_S;
- KeyPair kp = session.getHostKey();
+ KeyPair kp = ValidateUtils.checkNotNull(session.getHostKey(), "No server key pair available", GenericUtils.EMPTY_OBJECT_ARRAY);
String algo = session.getNegotiatedKexParameter(KexProposalOption.SERVERKEYS);
FactoryManager manager = session.getFactoryManager();
Signature sig = ValidateUtils.checkNotNull(
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
index c88f902..b204615 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/kex/DHGServer.java
@@ -91,7 +91,7 @@ public class DHGServer extends AbstractDHServerKeyExchange {
K = dh.getK();
byte[] K_S;
- KeyPair kp = session.getHostKey();
+ KeyPair kp = ValidateUtils.checkNotNull(session.getHostKey(), "No server key pair available", GenericUtils.EMPTY_OBJECT_ARRAY);
String algo = session.getNegotiatedKexParameter(KexProposalOption.SERVERKEYS);
FactoryManager manager = session.getFactoryManager();
Signature sig = ValidateUtils.checkNotNull(
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java
----------------------------------------------------------------------
diff --git a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java
index fa10296..8051eca 100644
--- a/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java
+++ b/sshd-core/src/main/java/org/apache/sshd/server/session/ServerConnectionService.java
@@ -25,6 +25,8 @@ import org.apache.sshd.common.ServiceFactory;
import org.apache.sshd.common.SshException;
import org.apache.sshd.common.session.AbstractConnectionService;
import org.apache.sshd.common.session.Session;
+import org.apache.sshd.common.util.GenericUtils;
+import org.apache.sshd.common.util.ValidateUtils;
/**
* Server side <code>ssh-connection</code> service.
@@ -49,10 +51,9 @@ public class ServerConnectionService extends AbstractConnectionService {
protected ServerConnectionService(Session s) throws SshException {
super(s);
- if (!(s instanceof ServerSession)) {
- throw new IllegalStateException("Server side service used on client side");
- }
- ServerSession session = (ServerSession) s;
+
+ ValidateUtils.checkTrue(s instanceof ServerSession, "Server side service used on client side", GenericUtils.EMPTY_OBJECT_ARRAY);
+
if (!session.isAuthenticated()) {
throw new SshException("Session is not authenticated");
}
http://git-wip-us.apache.org/repos/asf/mina-sshd/blob/6f8507a1/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 d5b8364..4e07afc 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
@@ -16,216 +16,33 @@
* specific language governing permissions and limitations
* under the License.
*/
+
package org.apache.sshd.server.session;
-import java.io.IOException;
import java.security.KeyPair;
-import java.util.List;
-import java.util.Map;
-import java.util.Objects;
-import org.apache.sshd.common.FactoryManager;
-import org.apache.sshd.common.FactoryManagerUtils;
-import org.apache.sshd.common.NamedResource;
-import org.apache.sshd.common.ServiceFactory;
-import org.apache.sshd.common.SshConstants;
-import org.apache.sshd.common.SshException;
-import org.apache.sshd.common.future.SshFutureListener;
-import org.apache.sshd.common.io.IoService;
-import org.apache.sshd.common.io.IoSession;
-import org.apache.sshd.common.io.IoWriteFuture;
-import org.apache.sshd.common.kex.KexProposalOption;
-import org.apache.sshd.common.kex.KexState;
-import org.apache.sshd.common.keyprovider.KeyPairProvider;
-import org.apache.sshd.common.session.AbstractSession;
-import org.apache.sshd.common.util.GenericUtils;
-import org.apache.sshd.common.util.buffer.Buffer;
-import org.apache.sshd.common.util.buffer.ByteArrayBuffer;
+import org.apache.sshd.common.session.Session;
import org.apache.sshd.server.ServerFactoryManager;
/**
- *
- * TODO Add javadoc
- *
* @author <a href="mailto:dev@mina.apache.org">Apache MINA SSHD Project</a>
*/
-public class ServerSession extends AbstractSession {
- public static final String DEFAULT_SSH_VERSION_PREFIX="SSH-2.0-";
-
- protected static final long MAX_PACKETS = (1l << 31);
-
- private long maxBytes = 1024 * 1024 * 1024; // 1 GB
- private long maxKeyInterval = 60 * 60 * 1000; // 1 hour
-
- public ServerSession(ServerFactoryManager server, IoSession ioSession) throws Exception {
- super(true, server, ioSession);
- maxBytes = Math.max(32, getLongProperty(ServerFactoryManager.REKEY_BYTES_LIMIT, maxBytes));
- maxKeyInterval = getLongProperty(ServerFactoryManager.REKEY_TIME_LIMIT, maxKeyInterval);
- log.info("Server session created from {}", ioSession.getRemoteAddress());
- sendServerIdentification();
- }
-
- @Override
- public ServerFactoryManager getFactoryManager() {
- return (ServerFactoryManager) factoryManager;
- }
-
- @Override
- protected void checkKeys() {
- // nothing
- }
-
- @Override
- public void startService(String name) throws Exception {
- currentService = ServiceFactory.Utils.create(getFactoryManager().getServiceFactories(), name, this);
- }
-
- @Override
- protected void serviceAccept() throws IOException {
- // TODO: can services be initiated by the server-side ?
- disconnect(SshConstants.SSH2_DISCONNECT_PROTOCOL_ERROR, "Unsupported packet: SSH_MSG_SERVICE_ACCEPT");
- }
-
- @Override
- protected void checkRekey() throws IOException {
- if (KexState.DONE.equals(kexState.get())) {
- if ( inPackets > MAX_PACKETS || outPackets > MAX_PACKETS
- || inBytes > maxBytes || outBytes > maxBytes
- || maxKeyInterval > 0 && System.currentTimeMillis() - lastKeyTime > maxKeyInterval)
- {
- reExchangeKeys();
- }
- }
- }
-
- private void sendServerIdentification() {
- FactoryManager manager = getFactoryManager();
- String ident = FactoryManagerUtils.getString(manager, ServerFactoryManager.SERVER_IDENTIFICATION);
- if (GenericUtils.isEmpty(ident)) {
- serverVersion = DEFAULT_SSH_VERSION_PREFIX + manager.getVersion();
- } else {
- serverVersion = DEFAULT_SSH_VERSION_PREFIX + ident;
- }
- sendIdentification(serverVersion);
- }
-
- @Override
- protected void sendKexInit() throws IOException {
- /*
- * Make sure that the provided host keys have at least one supported signature factory
- */
- FactoryManager manager = getFactoryManager();
- KeyPairProvider kpp = manager.getKeyPairProvider();
- List<String> supported = NamedResource.Utils.getNameList(manager.getSignatureFactories());
- Iterable<String> provided = kpp.getKeyTypes();
- StringBuilder resolvedHostKeys = null;
- for (String keyType : provided) {
- if (!supported.contains(keyType)) {
- if (log.isDebugEnabled()) {
- log.debug("sendKexInit(" + provided + ") " + keyType + " not in list of supported: " + supported);
- }
- continue;
- }
-
- if (resolvedHostKeys == null) {
- resolvedHostKeys = new StringBuilder(supported.size() * 16 /* ecdsa-sha2-xxxx */);
- }
-
- if (resolvedHostKeys.length() > 0) {
- resolvedHostKeys.append(',');
- }
-
- resolvedHostKeys.append(keyType);
- }
-
- // make sure the new list has at least one supported AND provided key type
- if (GenericUtils.isEmpty(resolvedHostKeys)) {
- throw new SshException(SshConstants.SSH2_DISCONNECT_HOST_KEY_NOT_VERIFIABLE,
- "sendKexInit(" + provided + ") none of the keys appears in supported list: " + supported);
- }
-
- Map<KexProposalOption,String> proposal = createProposal(resolvedHostKeys.toString());
- synchronized(serverProposal) {
- if (!serverProposal.isEmpty()) {
- serverProposal.clear(); // debug breakpoint
- }
-
- serverProposal.putAll(proposal);
- }
-
- I_S = sendKexInit(proposal);
- }
-
- @Override
- protected boolean readIdentification(Buffer buffer) throws IOException {
- clientVersion = doReadIdentification(buffer, true);
- if (GenericUtils.isEmpty(clientVersion)) {
- return false;
- }
- log.debug("Client version string: {}", clientVersion);
- if (!clientVersion.startsWith(DEFAULT_SSH_VERSION_PREFIX)) {
- String msg = "Unsupported protocol version: " + clientVersion;
- ioSession.write(new ByteArrayBuffer((msg + "\n").getBytes())).addListener(new SshFutureListener<IoWriteFuture>() {
- @Override
- public void operationComplete(IoWriteFuture future) {
- close(true);
- }
- });
- throw new SshException(msg);
- } else {
- kexState.set(KexState.INIT);
- sendKexInit();
- }
- return true;
- }
-
- @Override
- protected void receiveKexInit(Buffer buffer) throws IOException {
- if (!clientProposal.isEmpty()) {
- clientProposal.clear(); // debug breakpoint
- }
- I_C = receiveKexInit(buffer, clientProposal);
- }
-
- public KeyPair getHostKey() {
- String value = getNegotiatedKexParameter(KexProposalOption.SERVERKEYS);
- return factoryManager.getKeyPairProvider().loadKey(value);
- }
+public interface ServerSession extends Session {
+ /**
+ * @return The {@link ServerFactoryManager} for this session
+ */
+ @Override ServerFactoryManager getFactoryManager();
+
+ /**
+ * @return The {@link KeyPair} representing the current session's used keys
+ * on KEX
+ */
+ KeyPair getHostKey();
/**
* Retrieve the current number of sessions active for a given username.
- * @param userName The name of the user
+ * @param userName The name of the user - ignored if {@code null}/empty
* @return The current number of live <code>SshSession</code> objects associated with the user
*/
- protected int getActiveSessionCountForUser(String userName) {
- IoService service = ioSession.getService();
- Map<?, IoSession> sessionsMap = service.getManagedSessions();
- if (GenericUtils.isEmpty(sessionsMap)) {
- return 0;
- }
-
- int totalCount = 0;
- for (IoSession is : sessionsMap.values()) {
- ServerSession session = (ServerSession) getSession(is, true);
- if (session == null) {
- continue;
- }
-
- String sessionUser = session.getUsername();
- if ((!GenericUtils.isEmpty(sessionUser)) && Objects.equals(sessionUser, userName)) {
- totalCount++;
- }
- }
-
- return totalCount;
- }
-
- /**
- * Returns the session id.
- *
- * @return The session id.
- */
- public long getId() {
- return ioSession.getId();
- }
+ int getActiveSessionCountForUser(String userName);
}