-
Notifications
You must be signed in to change notification settings - Fork 47
/
SSHChannelType.swift
131 lines (114 loc) · 4.99 KB
/
SSHChannelType.swift
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
//===----------------------------------------------------------------------===//
//
// This source file is part of the SwiftNIO open source project
//
// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors
// Licensed under Apache License v2.0
//
// See LICENSE.txt for license information
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
//
// SPDX-License-Identifier: Apache-2.0
//
//===----------------------------------------------------------------------===//
import NIO
/// `SSHChannelType` represents the type of a single SSH channel.
///
/// SSH Channels are always one of a number of types. The most common type is "session", which
/// encompasses remote execution of a program, whether that be a single binary, a shell, a subsystem,
/// or something else.
///
/// Other major types include X11 channels (not supported by swift-nio-ssh), direct TCP/IP (for
/// forwarding a connection from the SSH client to the SSH server) and forwarded TCP/IP (for forwarding
/// a connection from a socket the server was listening on on behalf the client).
///
/// Some channel types have associated metadata. That metadata can be retrieved from SSH channels using
/// channel options.
public enum SSHChannelType: Equatable {
/// A "session" is remote execution of a program.
case session
/// "Direct TCP/IP" is a request from the client to the server to open an outbound connection.
case directTCPIP(DirectTCPIP)
/// "Forwarded TCP/IP" is a connection that was accepted from a listening socket and is being forwarded to the client.
case forwardedTCPIP(ForwardedTCPIP)
}
extension SSHChannelType {
public struct DirectTCPIP: Equatable {
/// The target host for the forwarded TCP connection.
public var targetHost: String
/// The target port for the forwarded TCP connection.
public var targetPort: Int {
get {
Int(self._targetPort)
}
set {
self._targetPort = UInt16(newValue)
}
}
/// The address of the initiating peer.
public var originatorAddress: SocketAddress
fileprivate private(set) var _targetPort: UInt16
public init(targetHost: String, targetPort: Int, originatorAddress: SocketAddress) {
self.targetHost = targetHost
self._targetPort = UInt16(targetPort)
self.originatorAddress = originatorAddress
}
internal init(targetHost: String, targetPort: UInt16, originatorAddress: SocketAddress) {
self.targetHost = targetHost
self._targetPort = targetPort
self.originatorAddress = originatorAddress
}
}
}
extension SSHChannelType {
public struct ForwardedTCPIP: Equatable {
/// The host the remote peer connected to. This should be identical to the one that was requested.
public var listeningHost: String
/// The port on which the proxy is listening, and to which the remote peer connected.
public var listeningPort: Int {
get {
Int(self._listeningPort)
}
set {
self._listeningPort = UInt16(newValue)
}
}
/// The address of the remote peer.
public var originatorAddress: SocketAddress
fileprivate private(set) var _listeningPort: UInt16
public init(listeningHost: String, listeningPort: Int, originatorAddress: SocketAddress) {
self.originatorAddress = originatorAddress
self.listeningHost = listeningHost
self._listeningPort = UInt16(listeningPort)
}
internal init(listeningHost: String, listeningPort: UInt16, originatorAddress: SocketAddress) {
self.originatorAddress = originatorAddress
self.listeningHost = listeningHost
self._listeningPort = listeningPort
}
}
}
extension SSHChannelType {
internal init(_ message: SSHMessage.ChannelOpenMessage) {
switch message.type {
case .session:
self = .session
case .directTCPIP(let message):
self = .directTCPIP(.init(targetHost: message.hostToConnectTo, targetPort: message.portToConnectTo, originatorAddress: message.originatorAddress))
case .forwardedTCPIP(let message):
self = .forwardedTCPIP(.init(listeningHost: message.hostListening, listeningPort: message.portListening, originatorAddress: message.originatorAddress))
}
}
}
extension SSHMessage.ChannelOpenMessage.ChannelType {
internal init(_ type: SSHChannelType) {
switch type {
case .session:
self = .session
case .directTCPIP(let data):
self = .directTCPIP(.init(hostToConnectTo: data.targetHost, portToConnectTo: data._targetPort, originatorAddress: data.originatorAddress))
case .forwardedTCPIP(let data):
self = .forwardedTCPIP(.init(hostListening: data.listeningHost, portListening: data._listeningPort, originatorAddress: data.originatorAddress))
}
}
}