@@ -36,6 +36,8 @@ public sealed class SshSession(ILogger? logger = null) : IDisposable
3636 public SshConnectionStatus ConnectionStatus { get ; private set ; }
3737
3838 internal unsafe _LIBSSH2_SESSION * SessionPtr { get ; private set ; }
39+
40+ private readonly Dictionary < SshMethod , string > methodPreferences = new ( ) ;
3941
4042 private void EnsureInitialized ( )
4143 {
@@ -49,7 +51,7 @@ private void EnsureInitialized()
4951 var initResult = libssh2_init ( 0 ) ;
5052 logger ? . LogDebug ( "libssh2_init returned: {InitResult}" , initResult ) ;
5153
52- initResult . ThrowIfNotSuccessful ( "LibSSH2 initialization failed" ) ;
54+ initResult . ThrowIfNotSuccessful ( this , "LibSSH2 initialization failed" ) ;
5355 libraryInitialized = true ;
5456 }
5557 }
@@ -107,11 +109,29 @@ public unsafe void Connect(string host, int port)
107109 }
108110
109111 logger ? . LogDebug ( "Connected to server: '{Host}:{Port}'" , host , port ) ;
112+
113+ logger ? . LogDebug ( "Setting method preferences..." ) ;
114+
115+ foreach ( var ( method , pref ) in methodPreferences )
116+ {
117+ logger ? . LogDebug ( "Setting method preference for '{Method:G}' to '{Pref}'" , method , pref ) ;
118+
119+ using var prefBuffer = NativeBuffer . Allocate ( pref ) ;
120+
121+ var prefResult = libssh2_session_method_pref ( newSession , ( int ) method , prefBuffer . AsPointer < sbyte > ( ) ) ;
122+
123+ prefResult . ThrowIfNotSuccessful ( this , $ "Failed to set preference to '{ method : G} ' to '{ pref } '", also : ( ) =>
124+ {
125+ _ = libssh2_session_free ( newSession ) ;
126+ socket . Dispose ( ) ;
127+ } ) ;
128+ }
129+
110130 logger ? . LogDebug ( "Handshaking..." ) ;
111131
112132 var result = libssh2_session_handshake ( newSession , ( ulong ) socket . Handle ) ;
113133
114- result . ThrowIfNotSuccessful ( "Failed to handshake with server" , also : ( ) =>
134+ result . ThrowIfNotSuccessful ( this , "Failed to handshake with server" , also : ( ) =>
115135 {
116136 _ = libssh2_session_free ( newSession ) ;
117137 socket . Dispose ( ) ;
@@ -191,15 +211,15 @@ public unsafe SshHostKey GetHostKey()
191211 /// This method must be called before connecting to the server. The session must be in <see cref="SshConnectionStatus.Disconnected"/> status.
192212 /// Use <see cref="SetSecureMethodPreferences"/> to apply a predefined set of secure defaults.
193213 /// </remarks>
194- public unsafe void SetMethodPreferences ( SshMethod method , string preferences )
214+ public void SetMethodPreferences ( SshMethod method , string preferences )
195215 {
216+ if ( string . IsNullOrWhiteSpace ( preferences ) )
217+ throw new ArgumentException ( "Preferences cannot be empty" , nameof ( preferences ) ) ;
218+
196219 EnsureInitialized ( ) ;
197220 EnsureInStatus ( SshConnectionStatus . Disconnected ) ;
198221
199- using var preferencesBuffer = NativeBuffer . Allocate ( preferences ) ;
200-
201- var result = libssh2_session_method_pref ( SessionPtr , ( int ) method , preferencesBuffer . AsPointer < sbyte > ( ) ) ;
202- result . ThrowIfNotSuccessful ( "Failed to set preferences" ) ;
222+ methodPreferences [ method ] = preferences ;
203223 }
204224
205225 /// <summary>
@@ -368,7 +388,7 @@ public unsafe SshCommandResult ExecuteCommand(string command, CommandExecutionOp
368388 options . TerminalHeightPixels
369389 ) ;
370390
371- ptyResult . ThrowIfNotSuccessful ( "Failed to request PTY" , also : ( ) =>
391+ ptyResult . ThrowIfNotSuccessful ( this , "Failed to request PTY" , also : ( ) =>
372392 {
373393 libssh2_channel_close ( channel ) ;
374394 libssh2_channel_wait_closed ( channel ) ;
@@ -389,7 +409,7 @@ public unsafe SshCommandResult ExecuteCommand(string command, CommandExecutionOp
389409 ( uint ) commandBytes . Length
390410 ) ;
391411
392- processStartupResult . ThrowIfNotSuccessful ( "Unable to execute command" , also : ( ) =>
412+ processStartupResult . ThrowIfNotSuccessful ( this , "Unable to execute command" , also : ( ) =>
393413 {
394414 libssh2_channel_close ( channel ) ;
395415 libssh2_channel_wait_closed ( channel ) ;
0 commit comments