### Run Example Flows on PowerShell Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Shows how to set environment variables for the example flows script in Windows PowerShell before execution. ```powershell $env:SSH_HOST = 'test.rebex.net' $env:SSH_PORT = '22' $env:SSH_USERNAME = 'demo' $env:SSH_PASSWORD = 'password' dart run example/run_flows.dart --shell ``` -------------------------------- ### Run Example Flows Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Demonstrates the main execution flows of the library, including `run()`, `runWithResult()`, and `execute()`. Can optionally test `shell()` via a command-line argument. ```sh SSH_HOST=test.rebex.net SSH_PORT=22 SSH_USERNAME=demo SSH_PASSWORD=password dart run example/run_flows.dart ``` ```sh SSH_HOST=test.rebex.net SSH_PORT=22 SSH_USERNAME=demo SSH_PASSWORD=password dart run example/run_flows.dart --shell ``` -------------------------------- ### Start a Remote Process with I/O Streaming using SSHClient.execute Source: https://context7.com/terminalstudio/dartssh2/llms.txt Opens a session channel to start a remote process, providing streams for stdin, stdout, and stderr. Supports PTY requests, environment variables, and X11 forwarding. Can stream local files to remote stdin or kill processes with signals. ```dart import 'dart:convert'; import 'dart:io'; import 'package:dartssh2/dartssh2.dart'; void main() async { final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', ); // Stream a local file to the remote process stdin final session = await client.execute( 'cat > /tmp/uploaded.txt', environment: {'TERM': 'xterm-256color'}, ); await session.stdin.addStream(File('local.txt').openRead().cast()); await session.stdin.close(); // Send EOF await session.done; print('Exit code: ${session.exitCode}'); // 0 on success // Kill a long-running process with a signal final bg = await client.execute('sleep 60'); bg.kill(SSHSignal.KILL); await bg.done; print('Signal: ${bg.exitSignal?.signalName}'); // KILL client.close(); } ``` -------------------------------- ### SSHClient.execute - Start a remote process with I/O streaming Source: https://context7.com/terminalstudio/dartssh2/llms.txt Opens a session channel to start a remote process, returning an `SSHSession` with accessible stdin, stdout, and stderr streams. Supports PTY, environment variables, and X11 forwarding. ```APIDOC ## SSHClient.execute — Start a remote process with I/O streaming `execute()` opens a session channel and starts a remote process, returning an `SSHSession` whose `stdin`, `stdout`, and `stderr` are Dart streams. Optionally request a PTY, set environment variables, or enable X11 forwarding. ### Method ```dart Future execute( String command, {bool pty = false, Map environment = const {}, bool forwardAgent = false, bool forwardX11 = false} ) ``` ### Parameters - **command** (String) - The command to execute. - **pty** (bool, optional) - Whether to allocate a pseudo-terminal. Defaults to `false`. - **environment** (Map, optional) - Environment variables to set for the process. - **forwardAgent** (bool, optional) - Whether to forward the SSH agent. Defaults to `false`. - **forwardX11** (bool, optional) - Whether to forward X11 connections. Defaults to `false`. ### Request Example ```dart import 'dart:convert'; import 'dart:io'; import 'package:dartssh2/dartssh2.dart'; void main() async { final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', ); // Stream a local file to the remote process stdin final session = await client.execute( 'cat > /tmp/uploaded.txt', environment: {'TERM': 'xterm-256color'}, ); await session.stdin.addStream(File('local.txt').openRead().cast()); await session.stdin.close(); // Send EOF await session.done; print('Exit code: ${session.exitCode}'); // 0 on success // Kill a long-running process with a signal final bg = await client.execute('sleep 60'); bg.kill(SSHSignal.KILL); await bg.done; print('Signal: ${bg.exitSignal?.signalName}'); // KILL client.close(); } ``` ``` -------------------------------- ### Perform SFTP file and directory operations Source: https://context7.com/terminalstudio/dartssh2/llms.txt Demonstrates various SFTP operations including getting file attributes, changing permissions, creating/renaming/removing directories, creating symlinks, reading symlink targets, and retrieving filesystem statistics. Also shows how to read file content directly. ```dart import 'dart:typed_data'; import 'package:dartssh2/dartssh2.dart'; void main() async { final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', ); final sftp = await client.sftp(); // Get file attributes final attrs = await sftp.stat('/etc/hostname'); print('Size: ${attrs.size}, type: ${attrs.type}'); print('Is directory: ${attrs.isDirectory}'); print('Is symlink: ${attrs.isSymbolicLink}'); // Change file permissions await sftp.setStat( '/tmp/myfile.txt', SftpFileAttrs(mode: SftpFileMode(userRead: true, userWrite: true)), ); // Directory operations await sftp.mkdir('/tmp/new-dir'); await sftp.rename('/tmp/new-dir', '/tmp/renamed-dir'); await sftp.rmdir('/tmp/renamed-dir'); // Symlink operations await sftp.link('/tmp/mylink', '/etc/hostname'); // create symlink final target = await sftp.readlink('/tmp/mylink'); print('Link points to: $target'); // Filesystem stats (OpenSSH extension) final vfs = await sftp.statvfs('/home'); final totalBytes = vfs.blockSize * vfs.totalBlocks; final freeBytes = vfs.blockSize * vfs.freeBlocks; print('Total: ${totalBytes ~/ 1024 ~/ 1024} MB, Free: ${freeBytes ~/ 1024 ~/ 1024} MB'); // Read bytes directly final file = await sftp.open('/etc/hostname'); final content = await file.readBytes(); await file.close(); print('Hostname file: ${String.fromCharCodes(content).trim()}'); sftp.close(); client.close(); } ``` -------------------------------- ### Install and Use dartssh2 CLI Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Install the dartssh2 command-line interface globally and use it as a replacement for the standard ssh command. This includes examples for executing remote commands and connecting to non-standard ports. ```sh # Install the `dartssh` command. dart pub global activate dartssh2_cli # Then use `dartssh` as regular `ssh` command. dartssh user@example.com # Example: execute a command on remote host. dartssh user@example.com ls -al # Example: connect to a non-standard port. dartssh user@example.com: # Transfer files via SFTP. dartsftp user@example.com ``` -------------------------------- ### Get and set file attributes using SFTP Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Demonstrates retrieving file attributes using `stat` and setting them using `setStat`. Ensure you have the necessary permissions. ```dart void main() async { await sftp.stat('/path/to/file'); await sftp.setStat( '/path/to/file', SftpFileAttrs(mode: SftpFileMode(userRead: true)), ); } ``` -------------------------------- ### Start Remote Process and Stream Data Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Starts a process on the remote host and allows streaming data to its stdin. It's recommended to use `session.stdin.addStream()` for large data transfers. The session's exit code can be retrieved after it's done. ```dart void main() async { final session = await client.execute('cat > file.txt'); await session.stdin.addStream(File('local_file.txt').openRead().cast()); await session.stdin.close(); await session.done; print(session.exitCode); } ``` -------------------------------- ### SSHClient.forwardDynamic Source: https://context7.com/terminalstudio/dartssh2/llms.txt Starts a local SOCKS5 proxy server that routes outbound CONNECT requests through the SSH tunnel. This is equivalent to running `ssh -D`. ```APIDOC ## SSHClient.forwardDynamic — SOCKS5 dynamic forwarding `forwardDynamic()` starts a local SOCKS5 proxy server (equivalent to `ssh -D`) that routes outbound `CONNECT` requests through the SSH tunnel. Only available on platforms with `dart:io`. ### Parameters #### bindHost - **bindHost** (String) - The host to bind the SOCKS5 proxy server to. #### bindPort - **bindPort** (int) - The port to bind the SOCKS5 proxy server to. #### options - **options** (SSHDynamicForwardOptions) - Optional settings for the dynamic forward, such as timeouts and max connections. #### filter - **filter** (Function) - An optional filter function to control which connections are allowed through the proxy. ### Returns - **Future**: A future that completes with an object representing the active SOCKS5 proxy. ### Example ```dart import 'package:dartssh2/dartssh2.dart'; void main() async { final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', ); final proxy = await client.forwardDynamic( bindHost: '127.0.0.1', bindPort: 1080, options: const SSHDynamicForwardOptions( handshakeTimeout: Duration(seconds: 10), connectTimeout: Duration(seconds: 15), maxConnections: 64, ), filter: (host, port) { // Deny connections to internal ranges (example policy) if (host.startsWith('10.') || host.startsWith('192.168.')) return false; return true; }, ); print('SOCKS5 proxy active at ${proxy.host}:${proxy.port}'); // Verify: curl --proxy socks5h://127.0.0.1:1080 https://ifconfig.me } ``` ``` -------------------------------- ### Start Local SOCKS5 Proxy via SSH Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Initiates a SOCKS5 proxy on a local port that forwards traffic through an SSH tunnel. Requires dart:io and is not available on web runtimes. Supports SOCKS5 NO AUTH + CONNECT. ```dart void main() async { final dynamicForward = await client.forwardDynamic( bindHost: '127.0.0.1', bindPort: 1080, options: const SSHDynamicForwardOptions( handshakeTimeout: Duration(seconds: 10), connectTimeout: Duration(seconds: 15), maxConnections: 128, ), filter: (host, port) { // Optional allow/deny policy. return true; }, ); print('SOCKS5 proxy at ${dynamicForward.host}:${dynamicForward.port}'); } ``` ```sh curl --proxy socks5h://127.0.0.1:1080 https://ifconfig.me ``` -------------------------------- ### Start SOCKS5 Dynamic Forwarding with SSHClient Source: https://context7.com/terminalstudio/dartssh2/llms.txt Initiates a local SOCKS5 proxy server for routing traffic through an SSH tunnel. Requires `dart:io` platform availability. Configure handshake and connection timeouts, and optionally filter hosts/ports. ```dart import 'package:dartssh2/dartssh2.dart'; void main() async { final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', ); final proxy = await client.forwardDynamic( bindHost: '127.0.0.1', bindPort: 1080, options: const SSHDynamicForwardOptions( handshakeTimeout: Duration(seconds: 10), connectTimeout: Duration(seconds: 15), maxConnections: 64, ), filter: (host, port) { // Deny connections to internal ranges (example policy) if (host.startsWith('10.') || host.startsWith('192.168.')) return false; return true; }, ); print('SOCKS5 proxy active at ${proxy.host}:${proxy.port}'); // Verify: curl --proxy socks5h://127.0.0.1:1080 https://ifconfig.me } ``` -------------------------------- ### Get remote filesystem space using SFTP Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Retrieves information about the remote filesystem, including total and free blocks, to estimate space usage. ```dart void main() async { final sftp = await client.sftp(); final statvfs = await sftp.statvfs('/root'); print('total: ${statvfs.blockSize * statvfs.totalBlocks}'); print('free: ${statvfs.blockSize * statvfs.freeBlocks}'); } ``` -------------------------------- ### Configure SSH client with AES-GCM cipher Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Example of configuring the SSH client to use AES-GCM ciphers, including explicit fallbacks. AES-GCM is opt-in. ```dart void main() async { final client = SSHClient( await SSHSocket.connect('localhost', 22), username: '', onPasswordRequest: () => '', algorithms: const SSHAlgorithms( cipher: [ SSHCipherType.aes256gcm, SSHCipherType.aes128gcm, SSHCipherType.aes256ctr, SSHCipherType.aes128ctr, SSHCipherType.aes256cbc, SSHCipherType.aes128cbc, ], ), ); // Use the client... client.close(); } ``` -------------------------------- ### Get SSH Server Version Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Retrieves the remote SSH server's version string after establishing an authenticated connection. The version is available via the `remoteVersion` property. ```dart void main() async { await client.authenticated; print(client.remoteVersion); // SSH-2.0-OpenSSH_7.4p1 } ``` -------------------------------- ### Create and remove directories using SFTP Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Shows how to create a new directory and remove an existing directory on the remote filesystem using SFTP. ```dart void main() async { final sftp = await client.sftp(); await sftp.mkdir('/path/to/dir'); await sftp.rmdir('/path/to/dir'); } ``` -------------------------------- ### SSHClient - Create an SSH connection Source: https://context7.com/terminalstudio/dartssh2/llms.txt Demonstrates how to create an SSHClient instance by connecting to a server and authenticating using password authentication. It also shows how to access the remote version and close the connection. ```APIDOC ## SSHClient — Create an SSH connection `SSHClient` is the entry point for all SSH operations. It takes an `SSHSocket` and authentication credentials, then asynchronously negotiates the SSH handshake and user authentication before any session or forwarding call can proceed. ### Method ```dart SSHClient( SSHSocket socket, {required String username, required String Function() onPasswordRequest, Duration? keepAliveInterval, required bool Function(String type, String fingerprint)? onVerifyHostKey, void Function()? onAuthenticated} ) ``` ### Parameters - **socket** (SSHSocket) - The established SSH socket connection. - **username** (String) - The username for authentication. - **onPasswordRequest** (String Function()) - A callback function to provide the password when requested. - **keepAliveInterval** (Duration, optional) - The interval for sending keep-alive messages. - **onVerifyHostKey** (bool Function(String type, String fingerprint)?, optional) - A callback to verify the host key. Return `false` to reject. - **onAuthenticated** (void Function()?, optional) - A callback function executed upon successful authentication. ### Request Example ```dart import 'dart:convert'; import 'package:dartssh2/dartssh2.dart'; void main() async { // Connect with password authentication final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', keepAliveInterval: const Duration(seconds: 30), onVerifyHostKey: (type, fingerprint) { // Inspect the host key before accepting. Return false to reject. print('Host key type: $type'); return true; }, onAuthenticated: () => print('Authenticated!'), ); await client.authenticated; // Wait until login is complete print(client.remoteVersion); // e.g. SSH-2.0-OpenSSH_9.2p1 client.close(); } ``` ``` -------------------------------- ### Create a symbolic link using SFTP Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Creates a symbolic link on the remote filesystem, pointing from the 'to' path to the 'from' path. ```dart void main() async { final sftp = await client.sftp(); sftp.link('/from', '/to'); } ``` -------------------------------- ### Create an SSH Connection with SSHClient Source: https://context7.com/terminalstudio/dartssh2/llms.txt Establishes an SSH connection using password authentication. It includes host key verification and a callback for authenticated events. Ensure the host key is verified before proceeding. ```dart import 'dart:convert'; import 'package:dartssh2/dartssh2.dart'; void main() async { // Connect with password authentication final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', keepAliveInterval: const Duration(seconds: 30), onVerifyHostKey: (type, fingerprint) { // Inspect the host key before accepting. Return false to reject. print('Host key type: $type'); return true; }, onAuthenticated: () => print('Authenticated!'), ); await client.authenticated; // Wait until login is complete print(client.remoteVersion); // e.g. SSH-2.0-OpenSSH_9.2p1 client.close(); } ``` -------------------------------- ### Open SFTP Session and List Directory with SftpClient Source: https://context7.com/terminalstudio/dartssh2/llms.txt Opens an SFTP subsystem over an existing SSH connection to obtain an `SftpClient`. This client provides access to all SFTP operations, such as listing directory contents. ```dart import 'package:dartssh2/dartssh2.dart'; void main() async { final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', ); final sftp = await client.sftp(); // List root directory final items = await sftp.listdir('/'); for (final item in items) { print(item.longname); // e.g. drwxr-xr-x 2 root root 4096 Jan 1 00:00 etc } sftp.close(); client.close(); } ``` -------------------------------- ### Establish Jump Host (Bastion) Connection with SSHClient Source: https://context7.com/terminalstudio/dartssh2/llms.txt Connects to a target server behind a bastion host by chaining two `SSHClient` instances. The first client connects to the bastion, and its forwarded channel is used as the socket for the second client connecting to the target. ```dart import 'dart:convert'; import 'package:dartssh2/dartssh2.dart'; void main() async { // Step 1 — connect to the jump/bastion host final jump = SSHClient( await SSHSocket.connect('bastion.example.com', 22), username: 'alice', onPasswordRequest: () => 'bastion-pass', ); // Step 2 — tunnel through bastion to the target final target = SSHClient( await jump.forwardLocal('internal-server.lan', 22), username: 'bob', onPasswordRequest: () => 'target-pass', ); await target.authenticated; print(utf8.decode(await target.run('hostname'))); // → internal-server target.close(); jump.close(); } ``` -------------------------------- ### Create and truncate remote file for SFTP write Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Opens a remote file with flags to create it if it doesn't exist and truncate it if it does, preparing it for writing. ```dart void main() async { final file = await sftp.open('file.txt', mode: SftpFileOpenMode.create | SftpFileOpenMode.truncate | SftpFileOpenMode.write ); } ``` -------------------------------- ### Connect Through a Jump Server Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Establishes an SSH connection to a target server by first connecting to a jump server. This is useful for accessing internal networks through a bastion host. ```dart void main() async { final jumpServer = SSHClient( await SSHSocket.connect('', 22), username: '...', onPasswordRequest: () => '...', ); final client = SSHClient( await jumpServer.forwardLocal('', 22), username: '...', onPasswordRequest: () => '...', ); print(utf8.decode(await client.run('hostname'))); // -> hostname of } ``` -------------------------------- ### Upload a file using SFTP Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Opens a file in write mode and writes the content of a local file to it. Ensure the remote file is created or truncated as needed. ```dart void main() async { final sftp = await client.sftp(); final file = await sftp.open('file.txt', mode: SftpFileOpenMode.create | SftpFileOpenMode.write); await file.write(File('local_file.txt').openRead().cast()); } ``` -------------------------------- ### SSHClient.run - Execute a command and collect output Source: https://context7.com/terminalstudio/dartssh2/llms.txt Executes a command non-interactively and returns the combined stdout/stderr as bytes. Provides an option to suppress stderr. For detailed results including exit code, use `runWithResult()`. ```APIDOC ## SSHClient.run — Execute a command and collect output `run()` is a convenience method that executes a command non-interactively and returns the combined stdout/stderr bytes. Use `stderr: false` to suppress stderr. For exit-code and separate stream access, use `runWithResult()`. ### Method ```dart Future> run(String command, {bool stderr = true}) ``` ### Parameters - **command** (String) - The command to execute. - **stderr** (bool, optional) - Whether to include stderr in the output. Defaults to `true`. ### Request Example ```dart import 'dart:convert'; import 'package:dartssh2/dartssh2.dart'; void main() async { final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', ); // Simple run — returns combined output bytes final uptime = await client.run('uptime'); print(utf8.decode(uptime)); // e.g. 12:34:56 up 10 days, ... // Run with full result — separate stdout/stderr + exit metadata final result = await client.runWithResult( 'ls -la /tmp', stderr: true, environment: {'LC_ALL': 'C'}, ); print('exit: ${result.exitCode}'); print('stdout: ${utf8.decode(result.stdout)}'); print('stderr: ${utf8.decode(result.stderr)}'); client.close(); } ``` ``` -------------------------------- ### Execute a Command and Collect Output with SSHClient.run Source: https://context7.com/terminalstudio/dartssh2/llms.txt Executes a command non-interactively and returns combined stdout/stderr. Use `runWithResult` for separate streams and exit code. Environment variables can be set for the command. ```dart import 'dart:convert'; import 'package:dartssh2/dartssh2.dart'; void main() async { final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', ); // Simple run — returns combined output bytes final uptime = await client.run('uptime'); print(utf8.decode(uptime)); // e.g. 12:34:56 up 10 days, ... // Run with full result — separate stdout/stderr + exit metadata final result = await client.runWithResult( 'ls -la /tmp', stderr: true, environment: {'LC_ALL': 'C'}, ); print('exit: ${result.exitCode}'); print('stdout: ${utf8.decode(result.stdout)}'); print('stderr: ${utf8.decode(result.stderr)}'); client.close(); } ``` -------------------------------- ### SftpClient Source: https://context7.com/terminalstudio/dartssh2/llms.txt Opens an SFTP subsystem over an existing SSH connection and returns an `SftpClient` object, providing access to all SFTP operations. ```APIDOC ## SftpClient — Open an SFTP session `client.sftp()` opens an SFTP subsystem over the existing SSH connection and returns an `SftpClient`. All SFTP operations are available through this object. ### Returns - **Future**: A future that completes with an `SftpClient` instance. ### Example ```dart import 'package:dartssh2/dartssh2.dart'; void main() async { final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', ); final sftp = await client.sftp(); // List root directory final items = await sftp.listdir('/'); for (final item in items) { print(item.longname); // e.g. drwxr-xr-x 2 root root 4096 Jan 1 00:00 etc } sftp.close(); client.close(); } ``` ``` -------------------------------- ### Connect to SSH Server Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Establishes a direct native TCP connection to an SSH host. This method is not available in browser environments. ```dart await SSHSocket.connect('host', 22); ``` -------------------------------- ### Jump host (bastion) connection Source: https://context7.com/terminalstudio/dartssh2/llms.txt Chain two `SSHClient` instances to reach a server behind a bastion host. This is achieved by using the first client's `forwardLocal` channel as the socket for the second client. ```APIDOC ## Jump host (bastion) connection Chain two `SSHClient` instances to reach a server behind a bastion by using the first client's `forwardLocal` channel as the socket for the second client. ### Example ```dart import 'dart:convert'; import 'package:dartssh2/dartssh2.dart'; void main() async { // Step 1 — connect to the jump/bastion host final jump = SSHClient( await SSHSocket.connect('bastion.example.com', 22), username: 'alice', onPasswordRequest: () => 'bastion-pass', ); // Step 2 — tunnel through bastion to the target final target = SSHClient( await jump.forwardLocal('internal-server.lan', 22), username: 'bob', onPasswordRequest: () => 'target-pass', ); await target.authenticated; print(utf8.decode(await target.run('hostname'))); // → internal-server target.close(); jump.close(); } ``` ``` -------------------------------- ### Upload a file via stream using SftpFile.write Source: https://context7.com/terminalstudio/dartssh2/llms.txt Opens a remote file in create/write mode and uploads a local file using a stream. Supports pausing and resuming the upload process. Ensure the file exists locally and the remote path is accessible. ```dart import 'dart:io'; import 'package:dartssh2/dartssh2.dart'; void main() async { final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', ); final sftp = await client.sftp(); final remoteFile = await sftp.open( '/uploads/backup.tar.gz', mode: SftpFileOpenMode.create | SftpFileOpenMode.truncate | SftpFileOpenMode.write, ); final uploader = remoteFile.write( File('backup.tar.gz').openRead().cast(), onProgress: (total) => print('Uploaded $total bytes'), ); // Pause and resume example await Future.delayed(const Duration(seconds: 2)); await uploader.pause(); print('Paused'); await uploader.resume(); await uploader.done; // Wait for upload to complete await remoteFile.close(); sftp.close(); client.close(); } ``` -------------------------------- ### Spawn Interactive Shell with SSHClient.shell Source: https://context7.com/terminalstudio/dartssh2/llms.txt Opens a PTY-backed interactive shell session. Wire local terminal streams for a full terminal experience. Requires stdin, stdout, and stderr to have terminals. ```dart import 'dart:convert'; import 'dart:io'; import 'dart:typed_data'; import 'package:dartssh2/dartssh2.dart'; void main() async { final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', ); final shell = await client.shell( pty: const SSHPtyConfig( type: 'xterm-256color', width: 220, height: 50, ), environment: {'LANG': 'en_US.UTF-8'}, ); // Wire local terminal streams (CLI apps only) if (stdin.hasTerminal && stdout.hasTerminal) { stdout.addStream(shell.stdout); stderr.addStream(shell.stderr); stdin.cast().listen(shell.write); } await shell.done; client.close(); } ``` -------------------------------- ### Pause and resume SFTP file upload Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Demonstrates how to pause and resume an ongoing file upload. The `done` future completes when the upload is finished. ```dart void main() async { final uploader = await file.write(File('local_file.txt').openRead().cast()); // ... await uploader.pause(); // ... await uploader.resume(); await uploader.done; } ``` -------------------------------- ### SftpClient.download Source: https://context7.com/terminalstudio/dartssh2/llms.txt A high-level convenience API for downloading a remote file. It opens the remote file, streams it to a `StreamSink`, and closes the handle. Options for `chunkSize`, `maxPendingRequests`, and `onProgress` are available for tuning. ```APIDOC ## SftpClient.download — Download a remote file (high-level) `sftp.download()` is a one-liner convenience API that opens the remote file, streams it to a `StreamSink`, and closes the handle. Tune `chunkSize` and `maxPendingRequests` for high-latency or large-file scenarios. ### Parameters #### remoteFilePath - **remoteFilePath** (String) - The path to the file on the remote server. #### destinationSink - **destinationSink** (StreamSink>) - The sink to write the downloaded file content to. #### chunkSize - **chunkSize** (int, optional) - The size of chunks to download in bytes. Defaults to a reasonable value. #### maxPendingRequests - **maxPendingRequests** (int, optional) - The maximum number of pending download requests. Defaults to a reasonable value. #### closeDestination - **closeDestination** (bool, optional) - Whether to close the destination sink after downloading. Defaults to true. #### onProgress - **onProgress** (Function, optional) - A callback function that is called with the number of bytes downloaded so far. ### Returns - **Future**: A future that completes with the total number of bytes downloaded. ### Example ```dart import 'dart:io'; import 'package:dartssh2/dartssh2.dart'; void main() async { final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', ); final sftp = await client.sftp(); final bytes = await sftp.download( '/remote/large-file.tar.gz', File('local-large-file.tar.gz').openWrite(), chunkSize: 128 * 1024, maxPendingRequests: 64, closeDestination: true, onProgress: (n) => print('Downloaded $n bytes'), ); print('Done: $bytes bytes total'); sftp.close(); client.close(); } ``` ``` -------------------------------- ### List Remote Directory Contents via SFTP Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Lists the contents of a remote directory using the SFTP protocol. Iterates through the directory items and prints their long names. ```dart void main() async { final sftp = await client.sftp(); final items = await sftp.listdir('/'); for (final item in items) { print(item.longname); } } ``` -------------------------------- ### Authenticate SSH with Public Keys Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Connects to an SSH server using public key authentication. Loads private keys from a PEM file, which can contain multiple keys. ```dart void main() async { final client = SSHClient( socket, username: '', identities: [ // A single private key file may contain multiple keys. ...SSHKeyPair.fromPem(await File('path/to/id_rsa').readAsString()) ], ); } ``` -------------------------------- ### SftpClient — File and directory operations Source: https://context7.com/terminalstudio/dartssh2/llms.txt The SftpClient class provides access to the complete SFTPv3 operation set for managing files and directories on a remote server. ```APIDOC ## SftpClient — File and directory operations `SftpClient` exposes the complete SFTPv3 operation set: `stat`, `setStat`, `rename`, `remove`, `mkdir`, `rmdir`, `readlink`, `link`, `absolute`, and `statvfs`. ### Methods - **stat(String path)**: Get file attributes. - **setStat(String path, SftpFileAttrs attrs)**: Change file permissions. - **mkdir(String path)**: Create a directory. - **rename(String oldPath, String newPath)**: Rename a file or directory. - **rmdir(String path)**: Remove a directory. - **link(String path, String target)**: Create a symbolic link. - **readlink(String path)**: Read the target of a symbolic link. - **statvfs(String path)**: Get filesystem statistics (OpenSSH extension). - **open(String path, {SftpFileOpenMode mode = SftpFileOpenMode.read})**: Open a file for reading or writing. ### Request Example ```dart // Get file attributes final attrs = await sftp.stat('/etc/hostname'); print('Size: ${attrs.size}, type: ${attrs.type}'); // Change file permissions await sftp.setStat( '/tmp/myfile.txt', SftpFileAttrs(mode: SftpFileMode(userRead: true, userWrite: true)), ); // Directory operations await sftp.mkdir('/tmp/new-dir'); await sftp.rename('/tmp/new-dir', '/tmp/renamed-dir'); await sftp.rmdir('/tmp/renamed-dir'); // Symlink operations await sftp.link('/tmp/mylink', '/etc/hostname'); // create symlink final target = await sftp.readlink('/tmp/mylink'); print('Link points to: $target'); // Filesystem stats (OpenSSH extension) final vfs = await sftp.statvfs('/home'); final totalBytes = vfs.blockSize * vfs.totalBlocks; final freeBytes = vfs.blockSize * vfs.freeBlocks; print('Total: ${totalBytes ~/ 1024 ~/ 1024} MB, Free: ${freeBytes ~/ 1024 ~/ 1024} MB'); // Read bytes directly final file = await sftp.open('/etc/hostname'); final content = await file.readBytes(); await file.close(); print('Hostname file: ${String.fromCharCodes(content).trim()}'); ``` ``` -------------------------------- ### SSHKeyPair.fromPem Source: https://context7.com/terminalstudio/dartssh2/llms.txt Loads and uses private key authentication by decoding PEM-encoded private keys. Supports various key types and encrypted keys requiring a passphrase. ```APIDOC ## SSHKeyPair — Load and use private key authentication `SSHKeyPair.fromPem()` decodes PEM-encoded private keys (OpenSSH, RSA, ECDSA, Ed25519). Encrypted keys require a passphrase. Pass the resulting list to `SSHClient.identities`. ### Method ```dart static List fromPem(String pem, [String? passphrase]) ``` ### Parameters #### pem - **String** - Required - The PEM-encoded private key string. #### passphrase - **String** - Optional - The passphrase for encrypted private keys. ### Request Example ```dart final pemText = await File('~/.ssh/id_ed25519').readAsString(); final keys = SSHKeyPair.fromPem(pemText, 'my-passphrase'); ``` ### Response #### Success Response - **List** - A list of SSHKeyPair objects representing the loaded private keys. ``` -------------------------------- ### SSHClient.shell Source: https://context7.com/terminalstudio/dartssh2/llms.txt Spawns an interactive shell session over an SSH connection. The returned SSHSession can be connected to the local terminal's stdin and stdout for a full terminal experience. ```APIDOC ## SSHClient.shell — Spawn an interactive shell `shell()` opens a PTY-backed interactive shell session. The returned `SSHSession` can be wired to local terminal stdin/stdout for a full terminal experience. ### Method ```dart Future shell({ SSHPtyConfig? pty, Map? environment, }) ``` ### Parameters #### pty - **type** (String) - Optional - The type of the pseudo-terminal (e.g., 'xterm-256color'). - **width** (int) - Optional - The width of the pseudo-terminal in columns. - **height** (int) - Optional - The height of the pseudo-terminal in rows. #### environment - **Map** - Optional - A map of environment variables to set for the shell session. ### Request Example ```dart final shell = await client.shell( pty: const SSHPtyConfig( type: 'xterm-256color', width: 220, height: 50, ), environment: {'LANG': 'en_US.UTF-8'}, ); ``` ### Response #### Success Response - **SSHSession** - An object representing the interactive shell session. ``` -------------------------------- ### Use Encrypted PEM Files for SSH Authentication Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Handles encrypted PEM private keys by providing a passphrase. Includes a check for encryption status and demonstrates decryption using SSHKeyPair.fromPem. ```dart void main() async { // Test whether the private key is encrypted. final encrypted = SSHKeyPair.isEncrypted(await File('path/to/id_rsa').readAsString()); print(encrypted); // If the private key is encrypted, you need to provide the passphrase. final keys = SSHKeyPair.fromPem('', ''); print(keys); } ``` -------------------------------- ### Download Remote File with Tunable Pipelining Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Downloads a remote file with configurable chunk size and maximum pending requests for optimizing performance over high-latency links or for large files. ```dart void main() async { final sftp = await client.sftp(); final output = File('local_file.txt').openWrite(); await sftp.download( '/remote/file.txt', output, chunkSize: 64 * 1024, maxPendingRequests: 128, closeDestination: true, ); } ``` -------------------------------- ### Download Remote File via SFTP (High-Level API) Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Downloads a remote file to a local sink using the high-level `sftp.download` API. Includes optional progress reporting and automatically closes the destination. ```dart void main() async { final sftp = await client.sftp(); final output = File('local_file.txt').openWrite(); final bytes = await sftp.download( '/remote/file.txt', output, onProgress: (bytesRead) => print('downloaded: $bytesRead bytes'), closeDestination: true, ); print('download complete: $bytes bytes'); } ``` -------------------------------- ### Spawn Remote Shell Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Spawns an interactive shell on the remote host. It includes logic to attach local terminal streams (stdin, stdout, stderr) for CLI applications, but this should be skipped for GUI apps or environments without a terminal. ```dart void main() async { final shell = await client.shell(); final hasTerminal = stdin.hasTerminal && stdout.hasTerminal && stderr.hasTerminal; if (hasTerminal) { stdout.addStream(shell.stdout); stderr.addStream(shell.stderr); stdin.cast().listen(shell.write); } await shell.done; client.close(); } ``` -------------------------------- ### Download Remote File with SftpClient.download Source: https://context7.com/terminalstudio/dartssh2/llms.txt A high-level convenience API for downloading remote files. It streams the file content to a provided `StreamSink`. Tune `chunkSize` and `maxPendingRequests` for performance optimization in different network conditions. ```dart import 'dart:io'; import 'package:dartssh2/dartssh2.dart'; void main() async { final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', onPasswordRequest: () => 's3cr3t', ); final sftp = await client.sftp(); final bytes = await sftp.download( '/remote/large-file.tar.gz', File('local-large-file.tar.gz').openWrite(), chunkSize: 128 * 1024, maxPendingRequests: 64, closeDestination: true, onProgress: (n) => print('Downloaded $n bytes'), ); print('Done: $bytes bytes total'); sftp.close(); client.close(); } ``` -------------------------------- ### Write Remote File via SFTP Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Opens a remote file in write mode and writes a string to it after encoding it to UTF-8 bytes. ```dart void main() async { final sftp = await client.sftp(); final file = await sftp.open('file.txt', mode: SftpFileOpenMode.write); await file.writeBytes(utf8.encode('hello there!') as Uint8List); } ``` -------------------------------- ### Load and Use Private Key Authentication with SSHKeyPair Source: https://context7.com/terminalstudio/dartssh2/llms.txt Decodes PEM-encoded private keys and uses them for SSH client authentication. Handles both encrypted and unencrypted keys. Passphrase is required for encrypted keys. ```dart import 'dart:io'; import 'dart:convert'; import 'package:dartssh2/dartssh2.dart'; void main() async { final pemText = await File('~/.ssh/id_ed25519').readAsString(); // Check if the key is passphrase-protected final encrypted = SSHKeyPair.isEncryptedPem(pemText); print('Encrypted: $encrypted'); // true or false // Decode (with optional passphrase for encrypted keys) final keys = SSHKeyPair.fromPem(pemText, encrypted ? 'my-passphrase' : null); final client = SSHClient( await SSHSocket.connect('example.com', 22), username: 'alice', identities: keys, // Try each key in order ); await client.authenticated; print(utf8.decode(await client.run('whoami'))); // alice client.close(); } ``` -------------------------------- ### Execute Remote Command Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Executes a command on the remote host and returns the combined stdout and stderr as bytes. Use `client.runWithResult()` for separate streams and exit metadata. ```dart void main() async { final uptime = await client.run('uptime'); print(utf8.decode(uptime)); } ``` ```dart void main() async { final uptime = await client.run('uptime', stderr: false); print(utf8.decode(uptime)); } ``` -------------------------------- ### Execute Remote Command with Result Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Executes a command on the remote host and provides access to stdout, stderr, and exit code. This is useful when you need to inspect the command's output and termination status separately. ```dart void main() async { final result = await client.runWithResult('echo hello'); print('exitCode: ${result.exitCode}'); print('stdout: ${utf8.decode(result.stdout)}'); print('stderr: ${utf8.decode(result.stderr)}'); } ``` -------------------------------- ### Download Partial Remote File via SFTP Source: https://github.com/terminalstudio/dartssh2/blob/master/README.md Downloads a specific portion of a remote file using an existing SFTP file handle. Allows specifying an offset and length for partial downloads. ```dart void main() async { final sftp = await client.sftp(); final file = await sftp.open('/remote/file.txt'); final output = File('local_partial.bin').openWrite(); try { // Download bytes [1024, 1024 + 4096) using an existing open handle. await file.downloadTo( output, offset: 1024, length: 4096, closeDestination: true, ); } finally { await file.close(); } } ``` -------------------------------- ### SftpFile.write — Upload a file via stream Source: https://context7.com/terminalstudio/dartssh2/llms.txt Opens a remote file in create/write mode and uploads a file using a stream of bytes. The returned SftpFileWriter allows for pausing and resuming the upload process. ```APIDOC ## SftpFile.write — Upload a file via stream Open a remote file with `create | write` mode and call `file.write()` with a `Stream` to upload. The returned `SftpFileWriter` supports `pause()`, `resume()`, and awaiting `done`. ### Method ```dart Future write(Stream stream, {void Function(int)? onProgress}) ``` ### Parameters #### Request Body - **stream** (Stream) - Required - The stream of bytes to upload. - **onProgress** (void Function(int)?) - Optional - A callback function that is invoked with the total number of bytes uploaded so far. ### Request Example ```dart final uploader = remoteFile.write( File('backup.tar.gz').openRead().cast(), onProgress: (total) => print('Uploaded $total bytes'), ); // Pause and resume example await Future.delayed(const Duration(seconds: 2)); await uploader.pause(); print('Paused'); await uploader.resume(); await uploader.done; // Wait for upload to complete ``` ### Response #### Success Response - **SftpFileWriter** - An object that allows control over the upload process (pause, resume) and can be awaited for completion. ```