ddn.net.ssh.session
SSH client session implementation.
Drives the SSH protocol over a caller-supplied transport: the identification exchange first, then the packet layer and key exchange phases. The session implements the public ddn.api.net.ssh.SshSession contract; pumping is explicit and every potentially-blocking step reports progress instead of blocking.
The session is single-threaded and non-reentrant, owns all protocol state for the connection, and references - but does not own - the transport.
Types 13
Session limits and defaults from the support matrix.
Configurable rekey thresholds (RFC 4253 section 9).
The defaults mirror SshRekeyLimits; every threshold applies to the bytes and packets moved under one installed direction-key set and resets at each NEWKEYS boundary. timeoutSeconds bounds a single rekey exchange against a stalled peer.
ulong bytesRekey after this many bytes sent or received under one key setulong packetsRekey after this many packets sent or received in one directionlong intervalSecondsRekey after this much time since the keys were installedlong timeoutSecondsFail the session when a rekey exchange takes longer than thisSub-phases of the key-exchange state.
SSH-2 client session over a caller-supplied transport. An established remote-forward listener binding.
string bindAddressBind address requested from the server.ushort boundPortBound (possibly allocated) port.An incoming forwarded channel waiting for its accept decision.
SshChannelImpl channelThe buffered, not-yet-accepted channel.SshForwardedChannelInfo infoThe connection identity shown to the handler.Global-request-operation implementation driven by session pumping.
Replies arrive in request order without identifiers; the session keeps the FIFO that pairs them.
private Kind kind_private string bindAddress_private ushort requestedPort_private ushort boundPort_private bool done_private bool accepted_private bool cancelled_private SshError error_void completeGlobalReply(bool accepted, ushort allocatedPort)Completes the operation from the peer's reply.void cancel()this(Kind kind, string bindAddress, ushort requestedPort)Constructs a global request operation.KindGlobal request flavour for reply bookkeeping.private SshTransport transport_private SshAlgorithmPreferences prefs_private SshSessionState state_private SshError sessionError_private string ourIdentification_private string peerIdentification_private string peerSoftware_private ubyte[] bannerBuffer_private ubyte[] writeQueue_private size_t writePos_private size_t channelBacklogBytes_private SshChannelImpl[] channels_private size_t nextChannelPump_private uint nextChannelId_private SshAuthOperationImpl authOperation_private SshGlobalRequestOp[] globalRequestQueue_private SshForwardedChannelHandler forwardHandler_private ForwardBinding[] activeForwards_private PendingForwardAccept[] pendingForwardAccepts_private string authUsername_private bool serviceRequested_private bool authServiceAccepted_private uint authAttempts_private ubyte[] pendingWire_private SshKexPhase kexPhase_private SshKexInit ourKexInit_private SshKexInit peerKexInit_private SshNegotiationResult negotiation_private ubyte[32] exchangeHash_private ubyte[] sharedSecretMpint_private ubyte[32] sessionId_private bool sessionIdValid_private X25519 ecdh_private ubyte[32] ecdhPublic_private EcdhP256 ecdhP256_private ubyte[] ecdhP256Public_private DH dh_private DHPrivateKey dhPrivate_private ubyte[] dhPublic_private SshHostKeyVerifier hostVerifier_private SshHostKeyInfo hostKeyInfo_private SshParsedPublicKey hostKeyParsed_private SshParsedSignature hostSignature_private bool ourKexValueSent_private bool kexReplyAllowed_private bool hostKeyChecked_private bool newKeysSent_private bool newKeysReceived_private SshPacketReader clearReader_private SshPacketWriter clearWriter_private GcmPacketWriter gcmWriter_private GcmPacketReader gcmReader_private EtMPacketWriter etmWriter_private EtMPacketReader etmReader_private ChachaPolyPacketWriter chachaWriter_private ChachaPolyPacketReader chachaReader_private string serverSignatureAlgorithms_private bool strictKexActive_private bool initialKexDone_private bool rekeying_private bool rekeyRequested_private bool ourKexInitSentThisRound_private bool rekeyRoundFromPeer_private ulong bytesSent_private ulong bytesReceived_private ulong packetsSent_private ulong packetsReceived_private SshRekeyConfig rekeyConfig_private MonoTime rekeyStart_private bool sawPreKexinitTraffic_private bool discardNextKexPacket_private uint extInfoCount_private bool extInfoAfterNewKeysAllowed_private bool extInfoRequiresAuthSuccess_private Duration keepAliveInterval_private MonoTime lastTraffic_private MonoTime keepAliveSentAt_private SshGlobalRequestOp keepAliveOp_private uint keepAlivesUnanswered_private CryptoRandom rng_private MonoTime delegate() clock_private MonoTime phaseStart_private Duration handshakeTimeout_private size_t preBannerLinesCount_SshSessionImpl create(SshTransport transport,
SshAlgorithmPreferences preferences = SshAlgorithmPreferences
.recommended()) staticCreates a session over a transport.SshTransport transport() @propertyvoid setAlgorithmPreferences(scope const SshAlgorithmPreferences prefs)Sets algorithm preferences before the handshake starts.void validateNames(string category,
scope const string[] offered, scope const string[] supported) staticvoid setKeepAlive(Duration interval)Configures keepalive requests; the transport phase acts on them.void setRekeyLimits(SshRekeyConfig config)Configures automatic rekey thresholds; non-positive members revert that threshold to the default.SshProgress pump()Advances all session state machines by one step.bool nextDeadline(out MonoTime deadline) constComputes the nearest timer deadline the driver must observe.void requestRekey()Requests a key re-exchange at the next legal opportunity.void setHostKeyVerifier(SshHostKeyVerifier verifier)Installs the host-key verifier consulted during key exchange.SshAuthOperation authenticatePublicKey(SshSigner signer)Starts (or resumes) public-key authentication with an application-owned signer. While an attempt is pending the same operation is returned; protocol requests are never duplicated.SshAuthOperation authenticatePassword(SshPasswordProvider provider)Starts (or resumes) password authentication with an application-owned credential provider. While an attempt is pending the same operation is returned; protocol requests are never duplicated.SshAuthOperation authenticateKeyboardInteractive(
SshKeyboardInteractiveProvider provider)Starts (or resumes) keyboard-interactive authentication with a non-blocking, application-owned challenge provider.inout(ubyte[32]) sessionId() inout @safe pure nothrowReturns: the session identifier bytes for signed requests.void queueAuthPacket(const(ubyte)[] payload) @trustedQueues an authentication packet; a null payload is a no-op used when the request awaits an asynchronous credential.bool pendingAuthMismatch(bool nullCredential)void startAuth(SshAuthOperationImpl operation)SshChannelOpenOperation openSessionChannel(
scope const SshChannelOpenOptions options = SshChannelOpenOptions
.init)Opens a session channel for exec, shell, or subsystem requests.SshChannelOpenOperation openDirectTcpIpChannel(string host, ushort port,
string originatorAddress, ushort originatorPort,
scope const SshChannelOpenOptions options = SshChannelOpenOptions
.init)Opens a direct TCP/IP channel to a destination reachable from the server.void setForwardedChannelHandler(SshForwardedChannelHandler handler)SshRemoteForwardOperation requestRemoteForward(string bindAddress,
ushort bindPort)SshGlobalRequestOperation cancelRemoteForward(string bindAddress,
ushort bindPort)void disconnect(ushort reason, string description)Disconnects: sends nothing until the packet layer exists, then flushes pending writes and closes the transport.SshProgress pumpKeyExchange()Drives the whole key-exchange phase: KEXINIT exchange, ECDH, host verification, NEWKEYS transitions, and extension info.void sendOurKexInit()void queuePacket(const(ubyte)[] payload)void queueClearPacket(const(ubyte)[] payload)bool isKexMessage(ubyte message) static pure nothrow @safeReturns: whether a message belongs to key exchange.void handlePeerKexInit(const(ubyte)[] payload)void handleKexReply(SshWireReader reader)Handles the KEX reply message of the negotiated method.void handleNewKeys()void beginRekey(bool fromPeer)Starts a rekey round, optionally triggered by the peer's KEXINIT.void enforceNegotiatedHostKey(string keyAlgorithm,
string signatureAlgorithm)Binds the presented host key and signature to the negotiated host-key algorithm (RFC 4253 section 7.1).void wipeSharedSecret() @trustedErases the encoded shared secret after both directions derived their keys.void wipeBytes(ubyte[] bytes) static nothrow @nogc @trustedVolatile-wipes a secret byte array.void wipePacketProtection() nothrow @nogc @trustedWipes and releases every installed packet-protection object.void wipeWriteProtection() nothrow @nogc @trustedWipes and releases installed outbound packet protection.void wipeReadProtection() nothrow @nogc @trustedWipes and releases installed inbound packet protection.void cleanupSecrets() @trustedTerminal secret teardown: shared secrets, live agreement state, and any queued plaintext still holding credentials.void handleExtInfo(SshWireReader reader)void completeHostDecisionFlow()void deriveAndInstallWriteProtection()void installReadProtection()bool isEtmCipher(string cipher) static pure nothrow @safeReturns: whether the cipher uses the encrypt-then-MAC layout.bool isChachaCipher(string cipher) static pure nothrow @safeReturns: whether the cipher is the OpenSSH AEAD construction.EtMMac etmMacFor(string macName) staticMaps an encrypt-then-MAC wire name to its implementation.size_t etmMacKeyLength(EtMMac mac) static pure nothrow @nogc @safeParams: mac = MAC selection.void sendNewKeys()SshChannelOpenOperation openChannel(SshChannelType type,
scope const SshChannelOpenOptions options,
SshDirectTcpIpTarget target = SshDirectTcpIpTarget.init)Opens a channel of the given type.SshGlobalRequestOp failedGlobal(
SshGlobalRequestOp.Kind kind, string bindAddress, ushort bindPort,
SshError error) staticvoid queueGlobalForwardRequest(string name, string bindAddress,
ushort bindPort)Queues a reply-bearing forwarding global request (RFC 4254 7.1).bool bindingMatches(string aAddress, ushort aPort,
string bAddress, ushort bPort) static pure nothrowvoid refuseIncomingChannel(uint sender, uint reason,
string description)Refuses a peer-opened channel with a typed failure reason (RFC 4254 section 5.1.1).void finalizeForwardDecision(SshChannelImpl channel,
bool accept)Accepts or refuses an incoming forwarded channel once decided.void handleForwardedChannelOpen(uint sender, uint window,
uint maxPacket, SshWireReader reader)Dispatches an incoming forwarded-tcpip open (RFC 4254 7.2) to the caller's policy. Unsolicited opens are refused before the handler is consulted.void queueChannelPacket(const(ubyte)[] payload) @trustedQueues a channel message through the session packet path.void channelConsumed(SshChannelImpl channel, size_t bytes)Records receive-window consumption by a channel read and sends WINDOW_ADJUST when the threshold is reached.void grantReceiveCredit(SshChannelImpl channel)Sends an accumulated receive-window re-grant when the channel's pending consumption crossed the replenish threshold.void channelProtocolViolation(string message)Reports a channel flow-control violation to the session.bool canQueueChannelBytes(size_t n)Returns: whether a channel packet of n further bytes still fits into the session write-queue budget.void reserveChannelBacklog(size_t bytes)Records bytes accepted into a channel-owned backlog.void releaseChannelBacklog(size_t bytes)Records bytes moved out of a channel-owned backlog.string serverSignatureAlgorithms() const @propertyReturns: the server's advertised server-sig-algs list, or an empty string when the server did not send EXT_INFO.void pumpChannels()Advances all open channels: flush write backlogs bounded by the remote windows, fair round-robin.void handleAuthenticationMessage(ubyte message,
SshWireReader reader)Dispatches connection-protocol messages to their channels.void handleConnectionMessage(ubyte message,
SshWireReader reader)SshChannelImpl findLocal(uint localId)void ensureServiceRequested()Sends the ssh-userauth service request once, when authentication starts.SshProgress startIdentification()SshProgress pumpIdentification()void enforceBannerBounds()void parseIdentificationLine(const(ubyte)[] line)Validates one identification line: protocol version, software version, character set, and length. Marks the session failed on any violation.void throwProtocol(string message)void queueWrite(const(ubyte)[] data)Queues bytes for writing, enforcing the session queue bound.void pumpPackets()Moves pending wire bytes into the active packet reader one byte at a time, dispatching completed packets between bytes so a NEWKEYS mid-batch switches readers exactly at the boundary.void failTransport(string message) @trustedMarks the session failed with a transport-flavoured message.SshProgress pumpDisconnect()SshProgress fail(SshError error) @trustedMarks the session failed and returns the error progress.this(SshTransport transport,
SshAlgorithmPreferences preferences = SshAlgorithmPreferences
.recommended())Constructs a session over a transport.LineStatusLineEndConcrete authentication operation driven by session pumping.
Implements the public SshAuthOperation contract plus internal callbacks invoked by the session's message dispatch.
SshAuthMethod method_SshSigner signer_SshPasswordProvider passwordProvider_SshKeyboardInteractiveProvider keyboardProvider_private SshSessionImpl session_private SshAuthPhase phase_private SshError error_private bool succeeded_private bool partialSuccess_private bool cancelled_private bool passwordChangeRequired_private string[] availableMethods_private string banner_private bool serviceAccepted_private bool requestSent_private bool wireRequestPending_private bool publicKeyProbeAccepted_private bool discovered_private uint attempts_private SshSignResult signResult_private SshPasswordResult passwordResult_private const(ubyte)[] pendingSignedData_private SshKeyboardInteractiveChallenge keyboardChallenge_private SshKeyboardInteractiveResult keyboardResult_private uint keyboardRounds_void cancel()bool waitingCredential() constReturns: whether the attempt currently waits for an application credential (password, prompt answer, or signer transport).void retireWireReply()Retires the reply slot of a cancelled operation.void failPending(SshError error)Fails the attempt from session-level teardown.void pump()Advances one step: request the service, submit the method request, or poll asynchronous credentials.void onServiceAccepted()Marks the ssh-userauth service as accepted.void onFailure(string[] methods, bool partial)Handles a USERAUTH_FAILURE: record methods and finish the attempt, surfacing partial success distinctly.void onSuccess()Handles USERAUTH_SUCCESS.void onMethodSpecific(ref SshWireReader reader)Handles message 60 according to the active authentication method.void sendMethodRequest()void pollCredential()void onKeyboardChallenge(ref SshWireReader reader)void pollKeyboardProvider()void sendKeyboardAnswers()string signatureAlgorithmFor(string keyAlgorithm)string selectRsaSignature(string offered) staticSelects the RSA SHA-2 signature algorithm for a server's advertised capability list.bool listsAlgorithm(string list, string candidate) static pure @safeWhether a comma-separated algorithm list names the candidate.bool validSignatureAlgorithm(string returned,
string requested) static pure nothrow @safeWhether a signer's returned algorithm satisfies the request.bool verifySignerResult(scope const SshPublicKeyInfo keyInfo,
scope const(ubyte)[] signedData, scope const SshSignResult result,
string requestedAlgorithm)Verifies a signer result against the public key before transmission.this(SshSessionImpl session, SshAuthMethod method, Object credential)Constructs an operation for one authentication method.Internal phases of an authentication attempt.