Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGES.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@

## Bug Fixes

* [GH-721](https://github.com/apache/mina-sshd/issues/721) SSH client: schedule session timeout checks on demand only
* [GH-807](https://github.com/apache/mina-sshd/issues/807) Handle "verified" flag for sk-* keys
* [GH-809](https://github.com/apache/mina-sshd/pull/809) Fix server-side authentication for FIDO/U2F sk-* keys with flags in `authorized_keys`
* [GH-827](https://github.com/apache/mina-sshd/issues/827) Don't fail on invalid `known_hosts` lines; log and skip them
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,7 @@
import org.apache.sshd.common.random.Random;
import org.apache.sshd.common.session.ConnectionService;
import org.apache.sshd.common.session.ReservedSessionMessagesHandler;
import org.apache.sshd.common.session.Session;
import org.apache.sshd.common.session.SessionDisconnectHandler;
import org.apache.sshd.common.session.SessionListener;
import org.apache.sshd.common.session.UnknownChannelReferenceHandler;
Expand Down Expand Up @@ -472,31 +473,58 @@ public void removePortForwardingEventListener(PortForwardingEventListener listen
}

protected void setupSessionTimeout(AbstractSessionFactory<?, ?> sessionFactory) {
// set up the the session timeout listener and schedule it
sessionTimeoutListener = createSessionTimeoutListener();
addSessionListener(sessionTimeoutListener);

timeoutListenerFuture = getScheduledExecutorService()
.scheduleAtFixedRate(sessionTimeoutListener, 1, 1, TimeUnit.SECONDS);
}

protected void removeSessionTimeout(AbstractSessionFactory<?, ?> sessionFactory) {
stopSessionTimeoutListener(sessionFactory);
}

protected SessionTimeoutListener createSessionTimeoutListener() {
return new SessionTimeoutListener();
return new SessionTimeoutListener() {

@Override
public void sessionCreated(Session session) {
synchronized (this) {
super.sessionCreated(session);
if (!sessions.isEmpty()) {
ensureTimeoutScheduled();
}
}
}

@Override
public void sessionClosed(Session s) {
synchronized (this) {
super.sessionClosed(s);
if (sessions.isEmpty()) {
cancelSessionTimeout();
}
}
}
};
}

protected void stopSessionTimeoutListener(AbstractSessionFactory<?, ?> sessionFactory) {
// cancel the timeout monitoring task
private void ensureTimeoutScheduled() {
if (timeoutListenerFuture == null) {
timeoutListenerFuture = getScheduledExecutorService().scheduleAtFixedRate(sessionTimeoutListener, 1, 1,
TimeUnit.SECONDS);
}
}

private void cancelSessionTimeout() {
if (timeoutListenerFuture != null) {
try {
timeoutListenerFuture.cancel(true);
} finally {
timeoutListenerFuture = null;
}
}
}

protected void stopSessionTimeoutListener(AbstractSessionFactory<?, ?> sessionFactory) {
cancelSessionTimeout();

// remove the sessionTimeoutListener completely; should the SSH server/client be restarted, a new one
// will be created.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ public class SftpFileSystemProvider extends FileSystemProvider {

protected final Logger log;

private final SshClient clientInstance;
private SshClient clientInstance;
private final SftpClientFactory factory;
private final SftpVersionSelector versionSelector;
private final SftpErrorDataHandler errorDataHandler;
Expand Down Expand Up @@ -183,11 +183,6 @@ public SftpFileSystemProvider(SshClient client, SftpClientFactory factory,
this.factory = factory;
this.versionSelector = selector;
this.errorDataHandler = errorDataHandler;
if (client == null) {
// TODO: make this configurable using system properties
client = SshClient.setUpDefaultClient();
client.start();
}
this.clientInstance = client;
}

Expand All @@ -204,10 +199,20 @@ public SftpErrorDataHandler getSftpErrorDataHandler() {
return errorDataHandler;
}

public final SshClient getClientInstance() {
public final synchronized SshClient getClientInstance() {
if (clientInstance == null) {
clientInstance = createClient();
}
return clientInstance;
}

private SshClient createClient() {
// TODO: make this configurable using system properties
SshClient client = SshClient.setUpDefaultClient();
client.start();
return client;
}

public SftpClientFactory getSftpClientFactory() {
return factory;
}
Expand Down Expand Up @@ -561,10 +566,30 @@ public SftpFileSystem getFileSystem(String id) {
}
}

private SftpFileSystem getOrCreateFileSystem(URI uri) throws IOException {
String id = getFileSystemIdentifier(uri);
synchronized (fileSystems) {
SftpFileSystem fs = fileSystems.get(id);
if (fs == null) {
fs = newFileSystem(uri, Collections.emptyMap());
}
return fs;
}
}

@Override
public Path getPath(URI uri) {
FileSystem fs = getFileSystem(uri);
return fs.getPath(uri.getPath());
if (!getScheme().equalsIgnoreCase(uri.getScheme())) {
throw new IllegalArgumentException("Not a " + getScheme() + " URI: " + uri);
}
try {
FileSystem fs = getOrCreateFileSystem(uri);
return fs.getPath(uri.getPath());
} catch (IOException e) {
FileSystemNotFoundException fe = new FileSystemNotFoundException("No file system for URI " + uri);
fe.initCause(e);
throw fe;
}
}

@Override
Expand Down