diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index db38582f4..af7ba3c94 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -41,3 +41,11 @@ The tests always log to the console. See the [Logging documentation](https://ssh ### Wireshark Wireshark is able to dissect initial connection packets, such as key exchange, before encryption happens. Enter "ssh" as the display filter. See https://wiki.wireshark.org/SSH.md for more information. + +The Debug build of SSH.NET has helpers to also allow dissection of the encrypted traffic by dumping the session keys in a format that Wireshark understands. Set a value for `SshNetLoggingConfiguration.WiresharkKeyLogFilePath` before connecting, and supply the same value to Wireshark in Edit -> Preferences -> Protocols -> SSH -> "Key log filename". + +```c# +using Renci.SshNet; + +SshNetLoggingConfiguration.WiresharkKeyLogFilePath = @"C:\tmp\sshkeylogfile.txt"; +``` diff --git a/src/Renci.SshNet/Session.cs b/src/Renci.SshNet/Session.cs index c5356db8e..800c0d5df 100644 --- a/src/Renci.SshNet/Session.cs +++ b/src/Renci.SshNet/Session.cs @@ -320,7 +320,7 @@ private set /// Gets the client init message. /// /// The client init message. - public Message ClientInitMessage { get; private set; } + public KeyExchangeInitMessage ClientInitMessage { get; private set; } /// /// Gets the server version string. @@ -1582,6 +1582,16 @@ internal void OnNewKeysReceived(NewKeysMessage message) _clientCompression = _keyExchange.CreateCompressor(); _serverDecompression = _keyExchange.CreateDecompressor(); +#if DEBUG + if (SshNetLoggingConfiguration.WiresharkKeyLogFilePath is string path + && _keyExchange is KeyExchange kex) + { + System.IO.File.AppendAllText( + path, + $"{ToHex(ClientInitMessage.Cookie)} SHARED_SECRET {ToHex(kex.SharedKey)}{Environment.NewLine}"); + } +#endif + // Dispose of old KeyExchange object as it is no longer needed. _keyExchange.HostKeyReceived -= KeyExchange_HostKeyReceived; _keyExchange.Dispose(); diff --git a/src/Renci.SshNet/SshNetLoggingConfiguration.cs b/src/Renci.SshNet/SshNetLoggingConfiguration.cs index 4add75c9f..fa8581b3b 100644 --- a/src/Renci.SshNet/SshNetLoggingConfiguration.cs +++ b/src/Renci.SshNet/SshNetLoggingConfiguration.cs @@ -22,5 +22,17 @@ public static void InitializeLogging(ILoggerFactory loggerFactory) ThrowHelper.ThrowIfNull(loggerFactory); LoggerFactory = loggerFactory; } + +#if DEBUG + /// + /// Gets or sets the path to which to write session secrets which + /// Wireshark can read and use to inspect encrypted traffic. + /// + /// + /// To configure in Wireshark, go to Edit -> Preferences -> Protocols + /// -> SSH and set the same value for "Key log filename". + /// + public static string? WiresharkKeyLogFilePath { get; set; } +#endif } }