From 1f0cf9fdd6e9b396fb5657fd3b44549497315f0c Mon Sep 17 00:00:00 2001 From: Busslina Date: Tue, 7 Jan 2025 15:29:46 +0100 Subject: [PATCH 1/2] Providing `SSHClient` on `onAuthenticated` callback Before this, I have to do this trick with a `Completer`: ```dart final socket = await SSHSocket.connect(_remoteSshHost, 22); final authenticatedCompleter = Completer(); final client = SSHClient( socket, username: _remoteSshUser, identities: SSHKeyPair.fromPem( cc.read(sshPrivateKeyFileCapsule).readAsStringSync(), ), onAuthenticated: () { authenticatedCompleter.complete(); }, ); print('Authenticating to SSH repository'); await authenticatedCompleter.future; ``` --- lib/src/ssh_client.dart | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/src/ssh_client.dart b/lib/src/ssh_client.dart index 9ddc183..85b5077 100644 --- a/lib/src/ssh_client.dart +++ b/lib/src/ssh_client.dart @@ -36,7 +36,7 @@ typedef SSHUserInfoRequestHandler = FutureOr?> Function( /// https://datatracker.ietf.org/doc/html/rfc4252#section-5.4 typedef SSHUserauthBannerHandler = void Function(String banner); -typedef SSHAuthenticatedHandler = void Function(); +typedef SSHAuthenticatedHandler = void Function(SSHClient); typedef SSHRemoteConnectionFilter = bool Function(String host, int port); @@ -559,7 +559,7 @@ class SSHClient { printTrace?.call('<- $socket: SSH_Message_Userauth_Success'); printDebug?.call('SSHClient._handleUserauthSuccess'); _authenticated.complete(); - onAuthenticated?.call(); + onAuthenticated?.call(this); _keepAlive?.start(); } From c984829d2e4d2d0a259b3cf94d053b4fe1d384f3 Mon Sep 17 00:00:00 2001 From: Busslina Date: Tue, 7 Jan 2025 15:55:59 +0100 Subject: [PATCH 2/2] Environment variables feature Sending a map of environment variables on channel creation --- lib/src/ssh_client.dart | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/lib/src/ssh_client.dart b/lib/src/ssh_client.dart index 85b5077..b942727 100644 --- a/lib/src/ssh_client.dart +++ b/lib/src/ssh_client.dart @@ -125,6 +125,8 @@ class SSHClient { /// method. Set this to null to disable automatic keep-alive messages. final Duration? keepAliveInterval; + final Map environmentVariables; + /// Function called when additional host keys are received. This is an OpenSSH /// extension. May not be called if the server does not support the extension. // final SSHHostKeysHandler? onHostKeys; @@ -151,6 +153,7 @@ class SSHClient { this.onUserauthBanner, this.onAuthenticated, this.keepAliveInterval = const Duration(seconds: 10), + this.environmentVariables = const {}, }) { _transport = SSHTransport( socket, @@ -951,12 +954,20 @@ class SSHClient { throw SSHStateError('Unexpected channel confirmation'); } - return _acceptChannel( + final channelController = _acceptChannel( localChannelId: localChannelId, remoteChannelId: reply.senderChannel, remoteInitialWindowSize: reply.initialWindowSize, remoteMaximumPacketSize: reply.maximumPacketSize, ); + + // Sending environment variables + for (final environmentVariable in environmentVariables.entries) { + channelController.sendEnv( + environmentVariable.key, environmentVariable.value); + } + + return channelController; } SSHChannelController _acceptChannel({