### Simple Command Implementation Example Source: https://github.com/apache/mina-sshd/blob/master/docs/commands.md This example demonstrates a basic implementation of the `Command` interface, including setting up input/output streams, handling commands, and signaling completion via `ExitCallback`. Ensure the `start()` method spawns a new thread to avoid blocking the packet processing thread. ```java class MyCommand implements Command, Runnable { private InputStream in; private OutputStream out, err; private ExitCallback callback; public MyCommand() { super(); } @Override public void setInputStream(InputStream in) { this.in = in; } @Override public void setOutputStream(OutputStream out) { this.out = out; } @Override public void setErrorStream(OutputStream err) { this.err = err; } @Override public void setExitCallback(ExitCallback callback) { this.callback = callback; } @Override public void start(Environment env) throws IOException { spawnHandlerThread(this); } @Override public void run() { while(true) { try { String cmd = readCommand(in); if ("exit".equals(cmd)) { break; } handleCommand(cmd, out); } catch (Exception e) { writeError(err, e); callback.onExit(-1, e.getMessage()); return; } callback.onExit(0); } @Override public void destroy() throws Exception { ...release any allocated resources... } } ``` -------------------------------- ### Set up Default SSH Client and Connect Source: https://context7.com/apache/mina-sshd/llms.txt Creates and configures a default SshClient instance with sensible defaults. It's recommended to verify server identity against known_hosts and load private keys. The client must be started before connecting and stopped when the application exits. This example demonstrates password authentication. ```java import org.apache.sshd.client.SshClient; import org.apache.sshd.client.session.ClientSession; import org.apache.sshd.client.future.ConnectFuture; import org.apache.sshd.common.keyprovider.FileKeyPairProvider; import org.apache.sshd.client.keyverifier.KnownHostsServerKeyVerifier; import org.apache.sshd.client.keyverifier.AcceptAllServerKeyVerifier; import java.nio.file.Paths; import java.util.concurrent.TimeUnit; SshClient client = SshClient.setUpDefaultClient(); // Verify server identity against ~/.ssh/known_hosts (recommended) client.setServerKeyVerifier( new KnownHostsServerKeyVerifier(AcceptAllServerKeyVerifier.INSTANCE, Paths.get(System.getProperty("user.home"), ".ssh", "known_hosts")) ); // Load private key identity from file once, shared across all sessions FileKeyPairProvider keyProvider = new FileKeyPairProvider( Paths.get(System.getProperty("user.home"), ".ssh", "id_rsa") ); client.setKeyIdentityProvider(keyProvider); client.start(); try (ClientSession session = client.connect("alice", "example.com", 22) .verify(10, TimeUnit.SECONDS) .getSession()) { // Password authentication (alternative to key-based) session.addPasswordIdentity("s3cr3t"); session.auth().verify(10, TimeUnit.SECONDS); // Session is authenticated — use it for commands, SFTP, SCP, etc. System.out.println("Connected: " + session.isAuthenticated()); // true } finally { client.stop(); } ``` -------------------------------- ### Basic Server-Side SFTP Setup Source: https://github.com/apache/mina-sshd/blob/master/docs/sftp.md Configure the SFTP subsystem factory and set it on the SSH server. This is the minimal setup required to enable SFTP. ```java SftpSubsystemFactory factory = new SftpSubsystemFactory.Builder() ...with... ...with... .build(); server.setSubsystemFactories(Collections.singletonList(factory)); ``` -------------------------------- ### Custom HostConfigEntryResolver Setup Source: https://github.com/apache/mina-sshd/blob/master/docs/internals.md Demonstrates how to set up a custom HostConfigEntryResolver to intercept and modify connection parameters before establishing an SSH session. Ensure the client is started after setting the resolver. ```java SshClient client = SshClient.setUpDefaultClient(); client.setHostConfigEntryResolver(new MyHostConfigEntryResolver()); client.start(); /* * The resolver might decide to connect to some host2/port2 using user2 and password2 * (or maybe using some key instead of the password). */ try (ClientSession session = client.connect(user1, host1, port1).verify(...timeout...).getSession()) { session.addPasswordIdentity(...password1...); session.auth().verify(...timeout...); } ``` -------------------------------- ### Connect and Authenticate with SshClient Source: https://github.com/apache/mina-sshd/blob/master/docs/client-setup.md Demonstrates setting up an SshClient, starting it, establishing multiple client sessions with authentication (password or public key), and stopping the client. ```java SshClient client = SshClient.setUpDefaultClient(); // override any default configuration... client.setSomeConfiguration(...); client.setOtherConfiguration(...); client.start(); // using the client for multiple sessions... try (ClientSession session = client.connect(user, host, port) .verify(...timeout...) .getSession()) { session.addPasswordIdentity(...password..); // for password-based authentication // or session.addPublicKeyIdentity(...key-pair...); // for password-less authentication // Note: can add BOTH password AND public key identities - depends on the client/server security setup session.auth().verify(...timeout...); // start using the session to run commands, do SCP/SFTP, create local/remote port forwarding, etc... } // NOTE: this is just an example - one can open multiple concurrent sessions using the same client. // No need to close the previous session before establishing a new one try (ClientSession anotherSession = client.connect(otherUser, otherHost, port) .verify(...timeout...) .getSession()) { anotherSession.addPasswordIdentity(...password..); // for password-based authentication anotherSession.addPublicKeyIdentity(...key-pair...); // for password-less authentication anotherSession.auth().verify(...timeout...); // start using the session to run commands, do SCP/SFTP, create local/remote port forwarding, etc... } // exiting in an orderly fashion once the code no longer needs to establish SSH session // NOTE: this can/should be done when the application exits. client.stop(); ``` -------------------------------- ### SshServer.setUpDefaultServer() Source: https://context7.com/apache/mina-sshd/llms.txt Creates an `SshServer` instance with default security settings. Before starting the server, it must be configured with a `KeyPairProvider` (for host keys) and at least one authenticator. ```APIDOC ## SshServer.setUpDefaultServer() ### Description Embeds an SSH server using default security settings. Requires configuration of a `KeyPairProvider` (host keys) and at least one authenticator before calling `start()`. ### Method Signature ```java static SshServer setUpDefaultServer() ``` ### Configuration and Usage Example ```java import org.apache.sshd.server.SshServer; import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; import org.apache.sshd.server.auth.password.PasswordAuthenticator; import org.apache.sshd.server.shell.ProcessShellFactory; import org.apache.sshd.server.forward.AcceptAllForwardingFilter; import org.apache.sshd.server.auth.pubkey.DefaultAuthorizedKeysAuthenticator; import java.nio.file.Paths; SshServer sshd = SshServer.setUpDefaultServer(); sshd.setPort(2222); // Host key — auto-generated and persisted to disk sshd.setKeyPairProvider( new SimpleGeneratorHostKeyProvider(Paths.get("hostkey.ser"))); // Password authenticator (replace with real credential lookup) sshd.setPasswordAuthenticator( (PasswordAuthenticator) (username, password, session) -> "admin".equals(username) && "password".equals(password)); // Public key authenticator using authorized_keys file sshd.setPublickeyAuthenticator(new DefaultAuthorizedKeysAuthenticator(false)); // Allow an interactive shell (spawns /bin/sh) sshd.setShellFactory(new ProcessShellFactory("/bin/sh", "-i", "-l")); // Enable port forwarding sshd.setForwardingFilter(AcceptAllForwardingFilter.INSTANCE); sshd.start(); System.out.println("SSHD listening on port " + sshd.getPort()); // Graceful shutdown // sshd.stop(); ``` ``` -------------------------------- ### Embed SSH Server with Default Settings Source: https://context7.com/apache/mina-sshd/llms.txt Creates an SshServer instance with default security settings. Requires configuration of a KeyPairProvider (host keys) and at least one authenticator before starting. This example sets up password and public key authentication, allows interactive shells, and enables port forwarding. ```java import org.apache.sshd.server.SshServer; import org.apache.sshd.server.keyprovider.SimpleGeneratorHostKeyProvider; import org.apache.sshd.server.auth.password.PasswordAuthenticator; import org.apache.sshd.server.shell.ProcessShellFactory; import org.apache.sshd.server.forward.AcceptAllForwardingFilter; import java.nio.file.Paths; SshServer sshd = SshServer.setUpDefaultServer(); sshd.setPort(2222); // Host key — auto-generated and persisted to disk sshd.setKeyPairProvider( new SimpleGeneratorHostKeyProvider(Paths.get("hostkey.ser"))); // Password authenticator (replace with real credential lookup) sshd.setPasswordAuthenticator( (PasswordAuthenticator) (username, password, session) -> "admin".equals(username) && "password".equals(password)); // Public key authenticator using authorized_keys file sshd.setPublickeyAuthenticator(new DefaultAuthorizedKeysAuthenticator(false)); // Allow an interactive shell (spawns /bin/sh) sshd.setShellFactory(new ProcessShellFactory("/bin/sh", "-i", "-l")); // Enable port forwarding sshd.setForwardingFilter(AcceptAllForwardingFilter.INSTANCE); sshd.start(); System.out.println("SSHD listening on port " + sshd.getPort()); // Graceful shutdown // sshd.stop(); ``` -------------------------------- ### Build Apache MINA SSHD with Tests Source: https://github.com/apache/mina-sshd/blob/master/README.md Use this command to build the project including all tests. Ensure you have Maven installed. ```bash mvn clean install ``` -------------------------------- ### SshClient.setUpDefaultClient() Source: https://context7.com/apache/mina-sshd/llms.txt Creates and configures a default SshClient instance with sensible defaults. This client can be reused for multiple sessions. Remember to call start() before connecting and stop() when exiting. ```APIDOC ## SshClient.setUpDefaultClient() ### Description Creates an `SshClient` instance with sensible defaults for ciphers, MACs, key exchange, and signatures. A single client instance can be reused to open multiple concurrent sessions to different servers. Call `start()` before connecting, and `stop()` when the application exits. ### Method ```java SshClient client = SshClient.setUpDefaultClient(); // Verify server identity against ~/.ssh/known_hosts (recommended) client.setServerKeyVerifier( new KnownHostsServerKeyVerifier(AcceptAllServerKeyVerifier.INSTANCE, Paths.get(System.getProperty("user.home"), ".ssh", "known_hosts"))); // Load private key identity from file once, shared across all sessions FileKeyPairProvider keyProvider = new FileKeyPairProvider( Paths.get(System.getProperty("user.home"), ".ssh", "id_rsa"))); client.setKeyIdentityProvider(keyProvider); client.start(); try (ClientSession session = client.connect("alice", "example.com", 22) .verify(10, TimeUnit.SECONDS) .getSession()) { // Password authentication (alternative to key-based) session.addPasswordIdentity("s3cr3t"); session.auth().verify(10, TimeUnit.SECONDS); // Session is authenticated — use it for commands, SFTP, SCP, etc. System.out.println("Connected: " + session.isAuthenticated()); // true } finally { client.stop(); } ``` ``` -------------------------------- ### Configure SftpFileSystemClientSessionInitializer for Password-less Login Source: https://github.com/apache/mina-sshd/blob/master/docs/sftp.md Register a custom SftpFileSystemClientSessionInitializer to control the ClientSession used for SftpFileSystem creation. This example demonstrates setting up password-less login using a registered key-pair. ```java SftpFileSystemProvider provider = ... obtain/create a provider ... provider.setSftpFileSystemClientSessionInitializer(new SftpFileSystemClientSessionInitializer() { @Override public void authenticateClientSession( SftpFileSystemProvider provider, SftpInitializationContext context, ClientSession session) throws IOException { /* * Set up password-less login instead of password-based using the specified key * * Note: if SSH client and/or session already have a KeyPairProvider set up and the code * knows that these keys are already registered with the remote server, then no need to * add the public key identitiy - can simply call sesssion.auth().verify(context.getMaxAuthTime()). */ KeyPair kp = ... obtain a registered key-pair... session.addPublicKeyIdentity(kp); sesssion.auth().verify(context.getMaxAuthTime()); } }); ``` -------------------------------- ### Using a Custom SftpClientFactory Source: https://github.com/apache/mina-sshd/blob/master/docs/sftp.md Illustrates how to use a custom SftpClientFactory to create an SftpClient, allowing for overridden default behaviors. The example shows setting up an SSH client, connecting, authenticating, and then creating the SFTP client with a user-specific factory. ```java SshClient client = ... setup client... try (ClientSession session = client.connect(user, host, port).verify(timeout).getSession()) { session.addPasswordIdentity(password); session.auth.verify(timeout); // User-specific factory try (SftpClient sftp = MySpecialSessionSftpClientFactory.INSTANCE.createSftpClient(session)) { ... instance created through SpecialSessionSftpClientFactory ... } } ``` -------------------------------- ### ClientSession.createShellChannel() Source: https://context7.com/apache/mina-sshd/llms.txt Opens an interactive shell channel with separate stdin/stdout/stderr streams. Threads for reading output should be started before opening the channel as data can arrive immediately. ```APIDOC ## ClientSession.createShellChannel() ### Description Opens an interactive `shell` channel with separate stdin/stdout/stderr streams. Threads for reading output must be started **before** opening the channel, since data can arrive immediately. ### Method Signature ```java ChannelShell createShellChannel() ``` ### Usage Example ```java import org.apache.sshd.client.channel.ChannelShell; import org.apache.sshd.common.channel.PtyChannelConfiguration; import org.apache.sshd.common.enums.ClientChannelEvent; import java.io.PipedInputStream; import java.io.PipedOutputStream; import java.util.EnumSet; import java.util.concurrent.TimeUnit; try (ClientSession session = client.connect("alice", "example.com", 22) .verify(10, TimeUnit.SECONDS).getSession()) { session.addPasswordIdentity("s3cr3t"); session.auth().verify(10, TimeUnit.SECONDS); try (ChannelShell channel = session.createShellChannel()) { channel.open().verify(5, TimeUnit.SECONDS); // Use inverted streams to communicate with the shell // channel.getInvertedIn() → write commands to stdin // channel.getInvertedOut() → read shell stdout // channel.getInvertedErr() → read shell stderr Thread readerThread = new Thread(() -> { try { byte[] buf = new byte[1024]; int n; while ((n = channel.getInvertedOut().read(buf)) != -1) { System.out.write(buf, 0, n); } } catch (Exception e) { /* channel closed */ } }); readerThread.start(); // Send a command to the shell channel.getInvertedIn().write("echo hello\nexit\n".getBytes()); channel.getInvertedIn().flush(); channel.waitFor(EnumSet.of(ClientChannelEvent.CLOSED), 0L); readerThread.join(); } } ``` ``` -------------------------------- ### Local and Remote Port Forwarding Setup Source: https://context7.com/apache/mina-sshd/llms.txt Configure local and remote port forwarding using PortForwardingTracker. Requires a ForwardingFilter, such as AcceptAllForwardingFilter. The tracker automatically tears down tunnels when closed. ```java import org.apache.sshd.client.session.forward.PortForwardingTracker; import org.apache.sshd.server.forward.AcceptAllForwardingFilter; import org.apache.sshd.common.forward.PortForwardingEventListener; SshClient client = SshClient.setUpDefaultClient(); client.setForwardingFilter(AcceptAllForwardingFilter.INSTANCE); client.start(); try (ClientSession session = client.connect("alice", "example.com", 22) .verify(10, TimeUnit.SECONDS).getSession()) { session.addPasswordIdentity("s3cr3t"); session.auth().verify(10, TimeUnit.SECONDS); // Local forwarding: localhost:8080 → remote-db:5432 (via example.com) try (PortForwardingTracker localFwd = session.createLocalPortForwardingTracker( 8080, "remote-db.internal", 5432)) { System.out.println("Local port 8080 → remote-db:5432"); // Connect your JDBC driver to localhost:8080 here Thread.sleep(5000); } // tunnel torn down automatically // Remote forwarding: example.com:9090 → localhost:8443 try (PortForwardingTracker remoteFwd = session.createRemotePortForwardingTracker( new SshdSocketAddress("", 9090), new SshdSocketAddress("localhost", 8443))) { System.out.println("Remote port 9090 → localhost:8443"); Thread.sleep(5000); } } ``` -------------------------------- ### SSH Global Request Example (RFC 4254) Source: https://github.com/apache/mina-sshd/blob/master/docs/technical/global_requests.md Illustrates the order of global requests and their replies as specified by RFC 4254. Replies must be sent in the same order as the corresponding request messages. ```text SSH_MSG_GLOBAL_REQUEST "a" want-reply=true ... SSH_MSG_GLOBAL_REQUEST "b" want-reply=true ... ``` -------------------------------- ### Configure Server with Default Ciphers (Excluding CBC) Source: https://github.com/apache/mina-sshd/blob/master/docs/changes/2.13.0.md Example of how to build an SSH server that excludes CBC ciphers from its default proposal, aligning with modern security practices. Existing code explicitly setting cipher factories remains unaffected. ```java SshServer server = ServerBuilder.builder() ... .cipherFactories(BuiltinFactory.setUpFactories(false, BaseBuilder.DEFAULT_CIPHERS_PREFERENCES)); ... .build(); ``` -------------------------------- ### Server-side SCP Command Factory Setup Source: https://github.com/apache/mina-sshd/blob/master/docs/scp.md Initialize and set an ScpCommandFactory as the primary command factory on the SSH server. This allows SCP command interception and execution, with an option to delegate other commands to a separate factory. ```java ScpCommandFactory factory = new ScpCommandFactory.Builder() .withDelegate(new MyCommandDelegate()) .build(); SshServer sshd = ...create an instance... sshd.setCommandFactory(factory); ``` -------------------------------- ### Configuring SFTP File System with Parameters Source: https://github.com/apache/mina-sshd/blob/master/docs/sftp.md Illustrates how to provide custom configuration parameters when creating an SFTP file system, either through a map or URI query parameters. URI parameters override map parameters. ```java // Using explicit parameters Map params = new HashMap<>(); params.put("param1", value1); params.put("param2", value2); ...etc... URI uri = SftpFileSystemProvider.createFileSystemURI(host, port, username, password); try (FileSystem fs = FileSystems.newFileSystem(uri, params)) { Path remotePath = fs.getPath("/some/remote/path"); ... work with the remote path... } ``` ```java // Using URI parameters Path remotePath = Paths.get(new URI("sftp://user:password@host/some/remote/path?param1=value1¶m2=value2...")); // Releasing the file-system once no longer necessary try (FileSystem fs = remotePath.getFileSystem()) { ... work with the remote path... } ``` ```java Map params = new HashMap<>(); params.put("param1", value1); params.put("param2", value2); // The value of 'param1' is overridden in the URI try (FileSystem fs = FileSystems.newFileSystem( new URI("sftp://user:password@host/some/remote/path?param1=otherValue1", params)) { Path remotePath = fs.getPath("/some/remote/path"); ... work with the remote path... } ``` -------------------------------- ### Example of Future Usage with Timeout Source: https://github.com/apache/mina-sshd/blob/master/docs/changes/2.10.0.md Illustrates how a future's `verify(timeout)` method is used to wait for an operation to complete, potentially with a timeout. This example highlights a scenario where a timeout could previously lead to resource leaks. ```java ClientSession session = client.connect(user, host, port).verify(timeout).getSession(); ``` -------------------------------- ### SCP 3-way Copy Source: https://github.com/apache/mina-sshd/blob/master/docs/cli.md Example of performing a remote-to-remote (3-way) copy using the ScpCommandMain client. Supports both local and URI paths. ```bash scp -p -r -3 user1@server1:source user2@server2:destination ``` -------------------------------- ### Configure Subsystems Source: https://github.com/apache/mina-sshd/blob/master/docs/cli.md Specify which subsystems to use on the server, including disabling all subsystems, using the built-in SFTP subsystem, or enabling custom subsystems. ```bash # Disable all subsystems -o Subsystem=none ``` ```bash # Use the built-in SFTP subsystem -o Subsystem=sftp ``` ```bash # Use one or more custom subsystems -o Subsystem=Sub1,Sub2,Sub3 ``` -------------------------------- ### Set KeyIdentityProvider for SshClient Source: https://github.com/apache/mina-sshd/blob/master/docs/client-setup.md To apply key identities to all sessions, wrap loaded key pairs in a `KeyIdentityProvider` and set it on the `SshClient` before starting it. ```java Collection keys = ...load the keys ... SshClient client = ...setup client... client.setKeyIdentityProvider(KeyIdentityProvider.wrapKeyPairs(keys)); client.start(); ``` -------------------------------- ### Client Connect with Timeout Source: https://github.com/apache/mina-sshd/blob/master/docs/changes/2.10.0.md Demonstrates how to set a connection timeout when establishing an SSH client session using `ConnectFuture.verify()`. ```java ClientSession session = client.connect(user, host, port).verify(MY_TIMEOUT).getSession(); ``` -------------------------------- ### Custom Authenticator with PGPPublicRingWatcher Source: https://github.com/apache/mina-sshd/blob/master/docs/files-parsing.md An alternative to PGPAuthorizedEntriesTracker for supporting mixed PGP and SSH keys. This example demonstrates obtaining a PGPPublicRingWatcher and resolving entries. ```java public class MyAuthorizedKeysAuthenticatorWithBothPGPAndSsh extends AuthorizedKeysAuthenticator { ... constructor(s) ... @Override protected PublickeyAuthenticator createDelegateAuthenticator( String username, ServerSession session, Path path, Collection entries, PublicKeyEntryResolver fallbackResolver) throws IOException, GeneralSecurityException { PGPPublicRingWatcher watcher = ... obtain an instance ... // Note: need to catch the PGPException and transform it into either an IOException or a GeneralSecurityException Collection keys = watcher.resolveAuthorizedEntries(session, entries, fallbackResolver); if (GenericUtils.isEmpty(keys)) { return RejectAllPublickeyAuthenticator.INSTANCE; } else { return new KeySetPublickeyAuthenticator(id, keys); } } } ``` -------------------------------- ### Custom Authenticator with PGPAuthorizedEntriesTracker Source: https://github.com/apache/mina-sshd/blob/master/docs/files-parsing.md Extend AuthorizedKeysAuthenticator to support both PGP and SSH keys in the same file. This example shows how to obtain a PGPAuthorizedEntriesTracker instance and resolve entries. ```java public class MyAuthorizedKeysAuthenticatorWithBothPGPAndSsh extends AuthorizedKeysAuthenticator { ... constructor(s) ... @Override protected PublickeyAuthenticator createDelegateAuthenticator( String username, ServerSession session, Path path, Collection entries, PublicKeyEntryResolver fallbackResolver) throws IOException, GeneralSecurityException { PGPAuthorizedEntriesTracker tracker = ... obtain an instance ... // Note: need to catch the PGPException and transform it into either an IOException or a GeneralSecurityException Collection keys = tracker.resolveAuthorizedEntries(session, entries, fallbackResolver); if (GenericUtils.isEmpty(keys)) { return RejectAllPublickeyAuthenticator.INSTANCE; } else { return new KeySetPublickeyAuthenticator(id, keys); } } } ``` -------------------------------- ### Create Default SshServer Instance Source: https://github.com/apache/mina-sshd/blob/master/docs/server-setup.md Sets up a default SshServer instance with sensible defaults for ciphers, MACs, and key exchange algorithms. Consult the SshServer class for more configuration options. ```java SshServer sshd = SshServer.setUpDefaultServer(); ``` -------------------------------- ### Set IoServiceFactoryFactory for SshServer and SshClient Source: https://github.com/apache/mina-sshd/blob/master/docs/internals.md Demonstrates how to explicitly set a custom IoServiceFactoryFactory for both SshServer and SshClient instances. If not set, a factory is automatically detected on start. ```java SshServer server = ...create server instance... server.setIoServiceFactoryFactory(new MyIoServiceFactoryFactory()); SshClient client = ... create client instance ... client.setIoServiceFactoryFactory(new MyIoServiceFactoryFactory()); ``` -------------------------------- ### Using SftpClientDirectoryScanner Source: https://github.com/apache/mina-sshd/blob/master/docs/sftp.md Instantiate and use `SftpClientDirectoryScanner` with an SFTP client instance to scan directories based on a pattern. Requires an SFTP client instance and a base directory path. ```java SftpClient client = ... obtain a client instance ... Strinng basedir = "/some/remote/path"; SftpClientDirectoryScanner ds = new SftpClientDirectoryScanner(basedir, ...pattern...); Collection matches = ds.scan(client); ``` -------------------------------- ### Mounting an SFTP File System Source: https://github.com/apache/mina-sshd/blob/master/docs/sftp.md Demonstrates how to mount an SFTP file system using a URI. The SftpFileSystemProvider automatically registers for 'sftp://' URIs. Ensure the file system is closed to release the SFTP session. ```java // "Mounting" a file system URI uri = SftpFileSystemProvider.createFileSystemURI(host, port, username, password); try (FileSystem fs = FileSystems.newFileSystem(uri, Collections.emptyMap())) { Path remotePath = fs.getPath("/some/remote/path"); ... } ``` ```java // Full programmatic control SshClient client = ...setup and start the SshClient instance... SftpFileSystemProvider provider = new SftpFileSystemProvider(client); URI uri = SftpFileSystemProvider.createFileSystemURI(host, port, username, password); try (FileSystem fs = provider.newFileSystem(uri, Collections.emptyMap())) { Path remotePath = fs.getPath("/some/remote/path"); } ``` -------------------------------- ### Provide Password for SshClientMain Source: https://github.com/apache/mina-sshd/blob/master/docs/cli.md Illustrates how to provide a password directly on the command line for SshClientMain instead of being prompted. Ensure secure handling of passwords. ```java java -cp ... org.apache.sshd.cli.client.SshClientMain -l -w ...host... ``` -------------------------------- ### Local and Remote Port Forwarding Source: https://context7.com/apache/mina-sshd/llms.txt Demonstrates setting up SSH tunnel forwarding using `PortForwardingTracker` for both local and remote forwarding scenarios. ```APIDOC ## Port Forwarding ### Local and Remote Port Forwarding — `PortForwardingTracker` Sets up SSH tunnel forwarding per RFC 4254. Requires a `ForwardingFilter` to be installed; use `AcceptAllForwardingFilter` for permissive setups. A `PortForwardingTracker` automatically tears down the tunnel when closed. ```java import org.apache.sshd.client.session.forward.PortForwardingTracker; import org.apache.sshd.server.forward.AcceptAllForwardingFilter; import org.apache.sshd.common.forward.PortForwardingEventListener; SshClient client = SshClient.setUpDefaultClient(); client.setForwardingFilter(AcceptAllForwardingFilter.INSTANCE); client.start(); try (ClientSession session = client.connect("alice", "example.com", 22) .verify(10, TimeUnit.SECONDS).getSession()) { session.addPasswordIdentity("s3cr3t"); session.auth().verify(10, TimeUnit.SECONDS); // Local forwarding: localhost:8080 → remote-db:5432 (via example.com) try (PortForwardingTracker localFwd = session.createLocalPortForwardingTracker( 8080, "remote-db.internal", 5432)) { System.out.println("Local port 8080 → remote-db:5432"); // Connect your JDBC driver to localhost:8080 here Thread.sleep(5000); } // tunnel torn down automatically // Remote forwarding: example.com:9090 → localhost:8443 try (PortForwardingTracker remoteFwd = session.createRemotePortForwardingTracker( new SshdSocketAddress("", 9090), new SshdSocketAddress("localhost", 8443))) { System.out.println("Remote port 9090 → localhost:8443"); Thread.sleep(5000); } } ``` ``` -------------------------------- ### Configure Shell Factory for Interactive Shells Source: https://github.com/apache/mina-sshd/blob/master/docs/server-setup.md Sets the ShellFactory to create a new shell for each user login. This example uses ProcessShellFactory to launch a new interactive shell process. ```java sshd.setShellFactory(new ProcessShellFactory(new String[] { "/bin/sh", "-i", "-l" })); ``` -------------------------------- ### Get Long Property from String Value Source: https://github.com/apache/mina-sshd/blob/master/docs/internals.md Demonstrates retrieving a long property that was initially set as a String. The getLongProperty method automatically converts the string representation to a long value. ```java PropertyResolverUtils.updateProperty(client, "prop1", "7365"); // all will yield 7365 Long value = PropertyResolverUtils.getLongProperty(client, "prop1"); Integer value = PropertyResolverUtils.getLongProperty(client, "prop1"); ``` -------------------------------- ### Load PUTTY Key Files using PuttyKeyUtils Source: https://github.com/apache/mina-sshd/blob/master/docs/client-setup.md For PUTTY key files, include the `sshd-putty` module and use this specific loader. Requires `PuttyKeyUtils`. ```java Collection keys = PuttyKeyUtils.DEFAULT_INSTANCE.loadKeyPairs(null, filePath, passwordProvider); ``` -------------------------------- ### Implement Custom Server-Side Command Handler Source: https://context7.com/apache/mina-sshd/llms.txt Implement CommandFactory to handle arbitrary SSH 'exec' channel commands on the server. Each command must spawn a new thread in its start() method. ```java import org.apache.sshd.server.command.Command; import org.apache.sshd.server.command.CommandFactory; import org.apache.sshd.server.Environment; import org.apache.sshd.server.ExitCallback; import java.io.*; sshd.setCommandFactory((channel, command) -> new Command() { private OutputStream out, err; private ExitCallback exitCallback; @Override public void setInputStream(InputStream in) {} @Override public void setOutputStream(OutputStream out) { this.out = out; } @Override public void setErrorStream(OutputStream err) { this.err = err; } @Override public void setExitCallback(ExitCallback cb) { this.exitCallback = cb; } @Override public void start(ChannelSession channel, Environment env) throws IOException { new Thread(() -> { try { String response = "You ran: " + command + "\n"; out.write(response.getBytes()); out.flush(); exitCallback.onExit(0); } catch (IOException e) { exitCallback.onExit(1, e.getMessage()); } }).start(); } @Override public void destroy(ChannelSession channel) {} }); ``` -------------------------------- ### Force SFTP Protocol Version with SftpVersionSelector Source: https://context7.com/apache/mina-sshd/llms.txt Control SFTP protocol version negotiation using SftpVersionSelector. This is useful for compatibility with servers that have bugs in specific versions. The example forces version 3. ```java import org.apache.sshd.sftp.client.SftpVersionSelector; // Force SFTP version 3 (most compatible) SftpVersionSelector v3Selector = (session, initial, current, available) -> { System.out.println("Available SFTP versions: " + available + ", current=" + current); return available.contains(3) ? 3 : current; }; SftpClientFactory factory = SftpClientFactory.instance(); try (ClientSession session = client.connect("alice", "example.com", 22) .verify(10, TimeUnit.SECONDS).getSession()) { session.addPasswordIdentity("s3cr3t"); session.auth().verify(10, TimeUnit.SECONDS); try (SftpClient sftp = factory.createSftpClient(session, v3Selector)) { System.out.println("Negotiated SFTP version: " + sftp.getVersion()); // 3 // ... use sftp client ... } } ``` -------------------------------- ### Select IoServiceFactoryFactory for SshClientMain Source: https://github.com/apache/mina-sshd/blob/master/docs/cli.md Shows how to select a specific IoServiceFactoryFactory for the SshClientMain CLI client. Defaults to NIO2 if no value is provided. ```java java -cp ... org.apache.sshd.cli.client.SshClientMain -io ``` -------------------------------- ### Working with Remote SFTP Paths Source: https://github.com/apache/mina-sshd/blob/master/docs/sftp.md Shows how to perform standard file operations on a remote SFTP path obtained from a mounted file system. This includes reading from files and iterating through directory contents. ```java try (InputStream input = Files.newInputStream(remotePath)) { ...read from remote file... } ``` ```java try (DirectoryStream ds = Files.newDirectoryStream(remoteDir)) { for (Path remoteFile : ds) { if (Files.isRegularFile(remoteFile)) { System.out.println("Delete " + remoteFile + " size=" + Files.size(remoteFile)); Files.delete(remoteFile); } else if (Files.isDirectory(remoteFile)) { System.out.println(remoteFile + " - directory"); } } } ``` -------------------------------- ### Register OpenPGP Key Entry Data Resolvers Source: https://github.com/apache/mina-sshd/blob/master/docs/files-parsing.md Call this method once during main code setup to enable parsing of OpenPGP key references in authorized_keys files. This supports the format specified in OpenSSH PGP configuration. ```java PGPPublicKeyEntryDataResolver.registerDefaultKeyEntryDataResolvers(); ``` -------------------------------- ### Obtain SftpClient Instance Source: https://github.com/apache/mina-sshd/blob/master/docs/sftp.md Demonstrates how to obtain an SftpClient instance using an SftpClientFactory. The underlying session remains open after the client is closed. ```java try (ClientSession session = ...obtain session...) { SftpClientFactory factory = ...obtain factory... try (SftpClient client = factory.createSftpClient(session)) { ... use the SFTP client... } // NOTE: session is still alive here... } ``` -------------------------------- ### Get Long Property with Type Conversion Source: https://github.com/apache/mina-sshd/blob/master/docs/internals.md Illustrates retrieving a long property from a client instance, demonstrating automatic type conversion from compatible types like Long or String. The getLongProperty method handles these conversions. ```java PropertyResolverUtils.updateProperty(client, "prop1", 7365L); // all will yield 7365 converted to the relevant type Long value = PropertyResolverUtils.getLongProperty(client, "prop1"); Integer value = PropertyResolverUtils.getLongProperty(client, "prop1"); ``` -------------------------------- ### Configure Session Heartbeat for Idle Sessions Source: https://context7.com/apache/mina-sshd/llms.txt Keeps idle SSH sessions alive by sending either SSH_MSG_IGNORE null packets or 'keepalive@' global requests. Configure on the SshClient for all sessions or per ClientSession. Examples show both methods. ```java import org.apache.sshd.core.CoreModuleProperties; import org.apache.sshd.common.session.helpers.SessionHeartbeatController; import java.time.Duration; SshClient client = SshClient.setUpDefaultClient(); // Option 1: SSH_MSG_IGNORE null packets every 30 seconds client.setSessionHeartbeat( SessionHeartbeatController.HeartbeatType.IGNORE, Duration.ofSeconds(30)); // Option 2: keepalive@ global request with reply wait (also prevents client timeout) PropertyResolverUtils.updateProperty( client, CoreModuleProperties.HEARTBEAT_INTERVAL.getName(), Duration.ofSeconds(30).toMillis()); // interval in milliseconds PropertyResolverUtils.updateProperty( client, CoreModuleProperties.HEARTBEAT_REPLY_WAIT.getName(), Duration.ofSeconds(10).toMillis()); // wait up to 10s for server reply client.start(); // All sessions created through this client will now send heartbeats ```