Public Access
Let a session's transport say what it negotiated
ISshConnection and ISftpSession both carry Cipher now — the server-to-client algorithm off SSH.NET's own ConnectionInfo, captured once because a rekey is not an event that library raises — and TerminalWorkspace.GetSessionFacts hands that plus the host key's algorithm back per session, without ever handing over the connection itself. Nothing reads either yet; the status bar that will is the next commit.
This commit is contained in:
@@ -265,6 +265,17 @@ public interface ISftpSession : IRemoteFileStore
|
||||
{
|
||||
/// <summary>The host key that was accepted for this session.</summary>
|
||||
HostKeyPresentation HostKey { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The negotiated server-to-client encryption algorithm, e.g. <c>aes256-gcm@openssh.com</c>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The same fact <see cref="ISshConnection.Cipher"/> is, read the same way — off SSH.NET's
|
||||
/// <c>ConnectionInfo.CurrentServerEncryption</c> once the handshake this session's own connect performed
|
||||
/// has finished — and for the same reason: <c>SftpClient</c> derives from <c>BaseClient</c> exactly as
|
||||
/// <c>SshClient</c> does, and rekeys are no more visible here than they are there. See that member's remark.
|
||||
/// </remarks>
|
||||
string Cipher { get; }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -98,6 +98,25 @@ public interface ISshConnection : IAsyncDisposable
|
||||
/// <summary>The host key that was accepted for this connection.</summary>
|
||||
HostKeyPresentation HostKey { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The negotiated server-to-client encryption algorithm, e.g. <c>aes256-gcm@openssh.com</c>.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// <para>
|
||||
/// Read once, immediately after the handshake, off SSH.NET's own <c>ConnectionInfo.CurrentServerEncryption</c>.
|
||||
/// The only event that could make this stale is a rekey, and SSH.NET raises no event for one and exposes no
|
||||
/// way to ask again — there is nothing behind this property to go and re-read. A captured value is therefore
|
||||
/// not a snapshot that might drift; it is the only value there has ever been a moment to observe.
|
||||
/// </para>
|
||||
/// <para>
|
||||
/// <b>Server-to-client, not client-to-server.</b> SSH negotiates the two directions independently and a
|
||||
/// server is free to choose differently for each, so the two can in principle disagree. This is the
|
||||
/// direction the bytes drawn on a terminal pane travelled in, which is the fact a status bar showing what
|
||||
/// the screen is made of should be naming.
|
||||
/// </para>
|
||||
/// </remarks>
|
||||
string Cipher { get; }
|
||||
|
||||
/// <summary>Opens an interactive shell with a pseudo-terminal.</summary>
|
||||
Task<ISshShellSession> OpenShellAsync(TerminalSize size, CancellationToken cancellationToken);
|
||||
}
|
||||
|
||||
@@ -274,6 +274,16 @@ internal sealed class SshNetConnection(SshClient client, HostKeyPresentation hos
|
||||
/// <inheritdoc />
|
||||
public HostKeyPresentation HostKey { get; } = hostKey;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>
|
||||
/// Read at construction rather than lazily: by the time an <see cref="SshNetConnection"/> exists,
|
||||
/// <see cref="SshNetConnectionFactory.ConnectAsync"/> has already awaited <c>client.ConnectAsync</c>, so
|
||||
/// <c>ConnectionInfo</c> is already populated and there is no earlier moment reading it would race. SSH.NET
|
||||
/// types the property as a non-nullable <c>string</c>, so this reads straight through rather than coalescing
|
||||
/// a null that the library's own contract says cannot occur.
|
||||
/// </remarks>
|
||||
public string Cipher { get; } = client.ConnectionInfo.CurrentServerEncryption;
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task<ISshShellSession> OpenShellAsync(TerminalSize size, CancellationToken cancellationToken)
|
||||
{
|
||||
|
||||
@@ -20,6 +20,14 @@ internal sealed class SshNetSftpSession(SftpClient client, HostKeyPresentation h
|
||||
/// <inheritdoc />
|
||||
public HostKeyPresentation HostKey { get; } = hostKey;
|
||||
|
||||
/// <inheritdoc />
|
||||
/// <remarks>
|
||||
/// Read at construction, the same way and for the same reason as <c>SshNetConnection.Cipher</c>: this type
|
||||
/// is only ever built after <c>SshNetConnectionFactory.OpenSftpAsync</c> has awaited <c>client.ConnectAsync</c>,
|
||||
/// so <c>ConnectionInfo</c> is already populated by the time there is a session to read it from.
|
||||
/// </remarks>
|
||||
public string Cipher { get; } = client.ConnectionInfo.CurrentServerEncryption;
|
||||
|
||||
/// <inheritdoc />
|
||||
public string HomeDirectory { get; } = homeDirectory;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user