Files
Termind/Frameworks/TermindRemoteInfrastructure/SSH/SSHConnectionOpener.swift
T

114 lines
4.8 KiB
Swift

import Foundation
import Logging
import TermindApplication
import TermindDomain
/// Connection-scoped entry point for socket routing, SSH handshake, host-key
/// verification, and authentication. Terminal, exec, SFTP, and forwarding
/// owners all use this boundary before opening their own Channels.
public nonisolated enum SSHConnectionOpener {
public static func openAuthenticatedConnection(
using configuration: SSHConnectionConfiguration,
timeout: TimeInterval,
progress: SSHRouteProgressHandler? = nil,
logger: Logger = ApplicationLogger.disabled("termind.ssh-authentication")
) throws -> SSHAuthenticatedConnection {
try SSHPTYChannelWorker.openAuthenticatedConnection(
using: configuration, timeout: timeout, progress: progress, logger: logger)
}
public static func openAuthenticatedConnection(
using request: SSHConnectionRequest,
timeout: TimeInterval,
progress: SSHRouteProgressHandler? = nil,
logger: Logger = ApplicationLogger.disabled("termind.ssh-authentication")
) async throws -> SSHAuthenticatedConnection {
try await SSHPTYChannelWorker.openAuthenticatedConnection(
using: request, timeout: timeout, progress: progress, logger: logger)
}
public static func installAuthorizedKey(
_ publicKey: String, named keyName: String, using request: SSHConnectionRequest,
logger: Logger = ApplicationLogger.disabled("termind.ssh-key-install"),
maxSessionsPolicy: SSHMaxSessionsPolicy = SSHMaxSessionsPolicy()
) async throws {
try await installAuthorizedKeys(
[SSHAuthorizedKeyInstall(publicKey: publicKey, name: keyName)],
using: request, logger: logger,
maxSessionsPolicy: maxSessionsPolicy
)
}
public static func installAuthorizedKeys(
_ keys: [SSHAuthorizedKeyInstall], using request: SSHConnectionRequest,
logger: Logger = ApplicationLogger.disabled("termind.ssh-key-install"),
maxSessionsPolicy: SSHMaxSessionsPolicy = SSHMaxSessionsPolicy()
) async throws {
try await SSHPTYChannelWorker.installAuthorizedKeys(
keys, using: request, logger: logger,
maxSessionsPolicy: maxSessionsPolicy)
}
public static func authorizedKeyInstallInput(publicKey: String, keyName: String) throws -> Data {
try SSHPTYChannelWorker.authorizedKeyInstallInput(
publicKey: publicKey, keyName: keyName)
}
public static func authenticate(
username: String, credentials: [SSHCredentials], libssh2Session: OpaquePointer,
keyboardInteractive: SSHKeyboardInteractiveExchange? = nil, socket: Int32 = -1
) throws -> String {
try SSHPTYChannelWorker.authenticate(
username: username, credentials: credentials, session: libssh2Session,
keyboardInteractive: keyboardInteractive, socket: socket)
}
public static func authenticate(
username: String, credentials: [SSHCredentials], libssh2Session: OpaquePointer,
afterHostKeyApproval: Bool,
keyboardInteractive: SSHKeyboardInteractiveExchange? = nil, socket: Int32 = -1
) throws -> String {
try SSHPTYChannelWorker.authenticate(
username: username, credentials: credentials, session: libssh2Session,
afterHostKeyApproval: afterHostKeyApproval,
keyboardInteractive: keyboardInteractive, socket: socket)
}
public static func observation(
host: String, port: Int, libssh2Session: OpaquePointer
) throws -> SSHHostKeyObservation {
try SSHPTYChannelWorker.observation(
host: host, port: port, session: libssh2Session)
}
public static func validateHostKey(
_ observed: SSHHostKeyObservation, expected: Set<SSHHostKeyIdentity>
) throws {
try SSHPTYChannelWorker.validateHostKey(observed, expected: expected)
}
public static func authorizeHostKey(
hostID: TermindDomain.Host.ID, observed: SSHHostKeyObservation,
expected: Set<SSHHostKeyIdentity>, constraint: SSHHostKeyConstraint? = nil,
authorizer: SSHHostKeyAuthorizer?
) async throws {
try await SSHPTYChannelWorker.authorizeHostKey(
hostID: hostID, observed: observed, expected: expected,
constraint: constraint, authorizer: authorizer)
}
public static func performHandshake(
_ libssh2Session: OpaquePointer, socket: Int32,
peer: String, timeout: TimeInterval = 20
) throws {
try SSHPTYChannelWorker.performHandshake(
libssh2Session, socket: socket, peer: peer, timeout: timeout)
}
public static func connectionError(
_ libssh2Session: OpaquePointer, prefix: String
) -> TermindSSHError {
SSHPTYChannelWorker.connectionError(libssh2Session, prefix: prefix)
}
}