hrr_rb_ssh 0.1.9 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.travis.yml +12 -2
- data/README.md +11 -9
- data/demo/echo_server.rb +50 -42
- data/demo/server.rb +81 -62
- data/demo/subsystem_echo_server.rb +54 -47
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm/ecdsa_sha2_nistp521 → algorithm/publickey/ecdsa_sha2}/ecdsa_signature_blob.rb +3 -3
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm/ecdsa_sha2_nistp256 → algorithm/publickey/ecdsa_sha2}/public_key_blob.rb +5 -6
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm/ecdsa_sha2_nistp256 → algorithm/publickey/ecdsa_sha2}/signature.rb +5 -5
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2.rb +85 -0
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2_nistp256.rb +19 -0
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2_nistp384.rb +19 -0
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2_nistp521.rb +19 -0
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm → algorithm/publickey}/ssh_dss/public_key_blob.rb +3 -3
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm → algorithm/publickey}/ssh_dss/signature.rb +4 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_dss.rb +90 -0
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm → algorithm/publickey}/ssh_rsa/public_key_blob.rb +3 -4
- data/lib/hrr_rb_ssh/{transport/server_host_key_algorithm → algorithm/publickey}/ssh_rsa/signature.rb +4 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa.rb +67 -0
- data/lib/hrr_rb_ssh/algorithm/publickey.rb +32 -0
- data/lib/hrr_rb_ssh/algorithm.rb +9 -0
- data/lib/hrr_rb_ssh/authentication/method/none/context.rb +1 -1
- data/lib/hrr_rb_ssh/authentication/method/none.rb +1 -1
- data/lib/hrr_rb_ssh/authentication/method/password/context.rb +1 -1
- data/lib/hrr_rb_ssh/authentication/method/password.rb +1 -1
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256.rb +2 -65
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384.rb +2 -65
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521.rb +2 -65
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/functionable.rb +54 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/signature_blob.rb +31 -0
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss.rb +2 -73
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa.rb +2 -55
- data/lib/hrr_rb_ssh/authentication/method/publickey.rb +3 -3
- data/lib/hrr_rb_ssh/authentication.rb +15 -15
- data/lib/hrr_rb_ssh/codable.rb +1 -1
- data/lib/hrr_rb_ssh/compat/openssh/public_key.rb +3 -40
- data/lib/hrr_rb_ssh/compat/ruby/array.rb +14 -0
- data/lib/hrr_rb_ssh/compat/ruby/openssl/bn.rb +20 -0
- data/lib/hrr_rb_ssh/compat/ruby/openssl.rb +4 -0
- data/lib/hrr_rb_ssh/compat/ruby/queue.rb +38 -0
- data/lib/hrr_rb_ssh/compat/ruby.rb +6 -0
- data/lib/hrr_rb_ssh/compat.rb +1 -63
- data/lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/forwarded_tcpip.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain/chain_context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change/context.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session.rb +1 -1
- data/lib/hrr_rb_ssh/connection/channel.rb +22 -22
- data/lib/hrr_rb_ssh/connection/global_request_handler.rb +1 -1
- data/lib/hrr_rb_ssh/connection/request_handler/reference_env_request_handler.rb +1 -1
- data/lib/hrr_rb_ssh/connection/request_handler/reference_exec_request_handler.rb +3 -56
- data/lib/hrr_rb_ssh/connection/request_handler/reference_pty_req_request_handler.rb +50 -13
- data/lib/hrr_rb_ssh/connection/request_handler/reference_shell_request_handler.rb +3 -56
- data/lib/hrr_rb_ssh/connection/request_handler/reference_window_change_request_handler.rb +1 -1
- data/lib/hrr_rb_ssh/connection/request_handler.rb +1 -1
- data/lib/hrr_rb_ssh/connection.rb +40 -40
- data/lib/hrr_rb_ssh/data_type.rb +0 -3
- data/lib/hrr_rb_ssh/error/closed_authentication.rb +9 -0
- data/lib/hrr_rb_ssh/{closed_transport_error.rb → error/closed_connection.rb} +3 -1
- data/lib/hrr_rb_ssh/{closed_authentication_error.rb → error/closed_transport.rb} +3 -1
- data/lib/hrr_rb_ssh/error.rb +11 -0
- data/lib/hrr_rb_ssh/{closed_connection_error.rb → mode.rb} +3 -1
- data/lib/hrr_rb_ssh/server.rb +23 -0
- data/lib/hrr_rb_ssh/transport/compression_algorithm/functionable.rb +1 -1
- data/lib/hrr_rb_ssh/transport/compression_algorithm/unfunctionable.rb +1 -1
- data/lib/hrr_rb_ssh/transport/encryption_algorithm/functionable.rb +3 -3
- data/lib/hrr_rb_ssh/transport/encryption_algorithm/unfunctionable.rb +1 -1
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman.rb +8 -48
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb +11 -51
- data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman.rb +8 -48
- data/lib/hrr_rb_ssh/transport/kex_algorithm/iv_computable.rb +57 -0
- data/lib/hrr_rb_ssh/transport/mac_algorithm/functionable.rb +2 -2
- data/lib/hrr_rb_ssh/transport/mac_algorithm/unfunctionable.rb +1 -1
- data/lib/hrr_rb_ssh/transport/receiver.rb +1 -1
- data/lib/hrr_rb_ssh/transport/sender.rb +1 -1
- data/lib/hrr_rb_ssh/transport/sequence_number.rb +1 -1
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp256.rb +2 -56
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384.rb +2 -56
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521.rb +2 -56
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/functionable.rb +29 -0
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_dss.rb +2 -50
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa.rb +2 -31
- data/lib/hrr_rb_ssh/transport.rb +83 -81
- data/lib/hrr_rb_ssh/version.rb +1 -1
- data/lib/hrr_rb_ssh.rb +4 -0
- metadata +32 -37
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/ecdsa_signature_blob.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/public_key_blob.rb +0 -28
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/signature.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256/signature_blob.rb +0 -33
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/ecdsa_signature_blob.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/public_key_blob.rb +0 -28
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/signature.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384/signature_blob.rb +0 -33
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/ecdsa_signature_blob.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/public_key_blob.rb +0 -28
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/signature.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521/signature_blob.rb +0 -33
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/public_key_blob.rb +0 -30
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/signature.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss/signature_blob.rb +0 -33
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/public_key_blob.rb +0 -28
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/signature.rb +0 -27
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa/signature_blob.rb +0 -33
- data/lib/hrr_rb_ssh/transport/mode.rb +0 -11
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp256/ecdsa_signature_blob.rb +0 -23
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384/ecdsa_signature_blob.rb +0 -23
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384/public_key_blob.rb +0 -25
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384/signature.rb +0 -23
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521/public_key_blob.rb +0 -25
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521/signature.rb +0 -23
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
# vim: et ts=2 sw=2
|
|
3
3
|
|
|
4
4
|
require 'hrr_rb_ssh/logger'
|
|
5
|
-
require 'hrr_rb_ssh/
|
|
5
|
+
require 'hrr_rb_ssh/error/closed_connection'
|
|
6
6
|
require 'hrr_rb_ssh/connection/global_request_handler'
|
|
7
7
|
require 'hrr_rb_ssh/connection/channel'
|
|
8
8
|
|
|
@@ -13,7 +13,7 @@ module HrrRbSsh
|
|
|
13
13
|
:options
|
|
14
14
|
|
|
15
15
|
def initialize authentication, options={}
|
|
16
|
-
@logger =
|
|
16
|
+
@logger = Logger.new self.class.name
|
|
17
17
|
|
|
18
18
|
@authentication = authentication
|
|
19
19
|
@options = options
|
|
@@ -25,11 +25,11 @@ module HrrRbSsh
|
|
|
25
25
|
end
|
|
26
26
|
|
|
27
27
|
def send payload
|
|
28
|
-
raise
|
|
28
|
+
raise Error::ClosedConnection if @closed
|
|
29
29
|
begin
|
|
30
30
|
@authentication.send payload
|
|
31
|
-
rescue
|
|
32
|
-
raise
|
|
31
|
+
rescue Error::ClosedAuthentication
|
|
32
|
+
raise Error::ClosedConnection
|
|
33
33
|
end
|
|
34
34
|
end
|
|
35
35
|
|
|
@@ -71,27 +71,27 @@ module HrrRbSsh
|
|
|
71
71
|
loop do
|
|
72
72
|
begin
|
|
73
73
|
payload = @authentication.receive
|
|
74
|
-
rescue
|
|
74
|
+
rescue Error::ClosedAuthentication => e
|
|
75
75
|
@logger.info { "closing connection loop" }
|
|
76
76
|
break
|
|
77
77
|
end
|
|
78
78
|
@username ||= @authentication.username
|
|
79
79
|
case payload[0,1].unpack("C")[0]
|
|
80
|
-
when
|
|
80
|
+
when Message::SSH_MSG_GLOBAL_REQUEST::VALUE
|
|
81
81
|
global_request payload
|
|
82
|
-
when
|
|
82
|
+
when Message::SSH_MSG_CHANNEL_OPEN::VALUE
|
|
83
83
|
channel_open payload
|
|
84
|
-
when
|
|
84
|
+
when Message::SSH_MSG_CHANNEL_OPEN_CONFIRMATION::VALUE
|
|
85
85
|
channel_open_confirmation payload
|
|
86
|
-
when
|
|
86
|
+
when Message::SSH_MSG_CHANNEL_REQUEST::VALUE
|
|
87
87
|
channel_request payload
|
|
88
|
-
when
|
|
88
|
+
when Message::SSH_MSG_CHANNEL_WINDOW_ADJUST::VALUE
|
|
89
89
|
channel_window_adjust payload
|
|
90
|
-
when
|
|
90
|
+
when Message::SSH_MSG_CHANNEL_DATA::VALUE
|
|
91
91
|
channel_data payload
|
|
92
|
-
when
|
|
92
|
+
when Message::SSH_MSG_CHANNEL_EOF::VALUE
|
|
93
93
|
channel_eof payload
|
|
94
|
-
when
|
|
94
|
+
when Message::SSH_MSG_CHANNEL_CLOSE::VALUE
|
|
95
95
|
channel_close payload
|
|
96
96
|
else
|
|
97
97
|
@logger.warn { "received unsupported message: id: #{payload[0,1].unpack("C")[0]}" }
|
|
@@ -103,8 +103,8 @@ module HrrRbSsh
|
|
|
103
103
|
end
|
|
104
104
|
|
|
105
105
|
def global_request payload
|
|
106
|
-
@logger.info { 'received ' +
|
|
107
|
-
message =
|
|
106
|
+
@logger.info { 'received ' + Message::SSH_MSG_GLOBAL_REQUEST::ID }
|
|
107
|
+
message = Message::SSH_MSG_GLOBAL_REQUEST.decode payload
|
|
108
108
|
begin
|
|
109
109
|
@global_request_handler.request message
|
|
110
110
|
rescue
|
|
@@ -124,7 +124,7 @@ module HrrRbSsh
|
|
|
124
124
|
@channels[channel.local_channel] = channel
|
|
125
125
|
@logger.info { 'channel opened' }
|
|
126
126
|
message = {
|
|
127
|
-
:'message number' =>
|
|
127
|
+
:'message number' => Message::SSH_MSG_CHANNEL_OPEN::VALUE,
|
|
128
128
|
:'channel type' => "forwarded-tcpip",
|
|
129
129
|
:'sender channel' => channel.local_channel,
|
|
130
130
|
:'initial window size' => channel.local_window_size,
|
|
@@ -138,8 +138,8 @@ module HrrRbSsh
|
|
|
138
138
|
end
|
|
139
139
|
|
|
140
140
|
def channel_open payload
|
|
141
|
-
@logger.info { 'received ' +
|
|
142
|
-
message =
|
|
141
|
+
@logger.info { 'received ' + Message::SSH_MSG_CHANNEL_OPEN::ID }
|
|
142
|
+
message = Message::SSH_MSG_CHANNEL_OPEN.decode payload
|
|
143
143
|
begin
|
|
144
144
|
channel = Channel.new self, message
|
|
145
145
|
@channels[channel.local_channel] = channel
|
|
@@ -152,45 +152,45 @@ module HrrRbSsh
|
|
|
152
152
|
end
|
|
153
153
|
|
|
154
154
|
def channel_open_confirmation payload
|
|
155
|
-
@logger.info { 'received ' +
|
|
156
|
-
message =
|
|
155
|
+
@logger.info { 'received ' + Message::SSH_MSG_CHANNEL_OPEN_CONFIRMATION::ID }
|
|
156
|
+
message = Message::SSH_MSG_CHANNEL_OPEN_CONFIRMATION.decode payload
|
|
157
157
|
channel = @channels[message[:'recipient channel']]
|
|
158
158
|
channel.set_remote_parameters message
|
|
159
159
|
channel.start
|
|
160
160
|
end
|
|
161
161
|
|
|
162
162
|
def channel_request payload
|
|
163
|
-
@logger.info { 'received ' +
|
|
164
|
-
message =
|
|
163
|
+
@logger.info { 'received ' + Message::SSH_MSG_CHANNEL_REQUEST::ID }
|
|
164
|
+
message = Message::SSH_MSG_CHANNEL_REQUEST.decode payload
|
|
165
165
|
local_channel = message[:'recipient channel']
|
|
166
166
|
@channels[local_channel].receive_message_queue.enq message
|
|
167
167
|
end
|
|
168
168
|
|
|
169
169
|
def channel_window_adjust payload
|
|
170
|
-
@logger.info { 'received ' +
|
|
171
|
-
message =
|
|
170
|
+
@logger.info { 'received ' + Message::SSH_MSG_CHANNEL_WINDOW_ADJUST::ID }
|
|
171
|
+
message = Message::SSH_MSG_CHANNEL_WINDOW_ADJUST.decode payload
|
|
172
172
|
local_channel = message[:'recipient channel']
|
|
173
173
|
@channels[local_channel].receive_message_queue.enq message
|
|
174
174
|
end
|
|
175
175
|
|
|
176
176
|
def channel_data payload
|
|
177
|
-
@logger.info { 'received ' +
|
|
178
|
-
message =
|
|
177
|
+
@logger.info { 'received ' + Message::SSH_MSG_CHANNEL_DATA::ID }
|
|
178
|
+
message = Message::SSH_MSG_CHANNEL_DATA.decode payload
|
|
179
179
|
local_channel = message[:'recipient channel']
|
|
180
180
|
@channels[local_channel].receive_message_queue.enq message
|
|
181
181
|
end
|
|
182
182
|
|
|
183
183
|
def channel_eof payload
|
|
184
|
-
@logger.info { 'received ' +
|
|
185
|
-
message =
|
|
184
|
+
@logger.info { 'received ' + Message::SSH_MSG_CHANNEL_EOF::ID }
|
|
185
|
+
message = Message::SSH_MSG_CHANNEL_EOF.decode payload
|
|
186
186
|
local_channel = message[:'recipient channel']
|
|
187
187
|
channel = @channels[local_channel]
|
|
188
188
|
channel.receive_message_queue.close
|
|
189
189
|
end
|
|
190
190
|
|
|
191
191
|
def channel_close payload
|
|
192
|
-
@logger.info { 'received ' +
|
|
193
|
-
message =
|
|
192
|
+
@logger.info { 'received ' + Message::SSH_MSG_CHANNEL_CLOSE::ID }
|
|
193
|
+
message = Message::SSH_MSG_CHANNEL_CLOSE.decode payload
|
|
194
194
|
local_channel = message[:'recipient channel']
|
|
195
195
|
channel = @channels[local_channel]
|
|
196
196
|
channel.close
|
|
@@ -201,47 +201,47 @@ module HrrRbSsh
|
|
|
201
201
|
|
|
202
202
|
def send_request_success
|
|
203
203
|
message = {
|
|
204
|
-
:'message number' =>
|
|
204
|
+
:'message number' => Message::SSH_MSG_REQUEST_SUCCESS::VALUE,
|
|
205
205
|
}
|
|
206
|
-
payload =
|
|
206
|
+
payload = Message::SSH_MSG_REQUEST_SUCCESS.encode message
|
|
207
207
|
@authentication.send payload
|
|
208
208
|
end
|
|
209
209
|
|
|
210
210
|
def send_request_failure
|
|
211
211
|
message = {
|
|
212
|
-
:'message number' =>
|
|
212
|
+
:'message number' => Message::SSH_MSG_REQUEST_FAILURE::VALUE,
|
|
213
213
|
}
|
|
214
|
-
payload =
|
|
214
|
+
payload = Message::SSH_MSG_REQUEST_FAILURE.encode message
|
|
215
215
|
@authentication.send payload
|
|
216
216
|
end
|
|
217
217
|
|
|
218
218
|
def send_channel_open message
|
|
219
|
-
payload =
|
|
219
|
+
payload = Message::SSH_MSG_CHANNEL_OPEN.encode message
|
|
220
220
|
@authentication.send payload
|
|
221
221
|
end
|
|
222
222
|
|
|
223
223
|
def send_channel_open_confirmation channel
|
|
224
224
|
message = {
|
|
225
|
-
:'message number' =>
|
|
225
|
+
:'message number' => Message::SSH_MSG_CHANNEL_OPEN_CONFIRMATION::VALUE,
|
|
226
226
|
:'channel type' => channel.channel_type,
|
|
227
227
|
:'recipient channel' => channel.remote_channel,
|
|
228
228
|
:'sender channel' => channel.local_channel,
|
|
229
229
|
:'initial window size' => channel.local_window_size,
|
|
230
230
|
:'maximum packet size' => channel.local_maximum_packet_size,
|
|
231
231
|
}
|
|
232
|
-
payload =
|
|
232
|
+
payload = Message::SSH_MSG_CHANNEL_OPEN_CONFIRMATION.encode message
|
|
233
233
|
@authentication.send payload
|
|
234
234
|
end
|
|
235
235
|
|
|
236
236
|
def send_channel_open_failure recipient_channel, reason_code, description
|
|
237
237
|
message = {
|
|
238
|
-
:'message number' =>
|
|
238
|
+
:'message number' => Message::SSH_MSG_CHANNEL_OPEN_FAILURE::VALUE,
|
|
239
239
|
:'recipient channel' => recipient_channel,
|
|
240
240
|
:'reason code' => reason_code,
|
|
241
241
|
:'description' => description,
|
|
242
242
|
:'language tag' => "",
|
|
243
243
|
}
|
|
244
|
-
payload =
|
|
244
|
+
payload = Message::SSH_MSG_CHANNEL_OPEN_FAILURE.encode message
|
|
245
245
|
@authentication.send payload
|
|
246
246
|
end
|
|
247
247
|
end
|
data/lib/hrr_rb_ssh/data_type.rb
CHANGED
|
@@ -93,9 +93,6 @@ module HrrRbSsh
|
|
|
93
93
|
unless arg.kind_of? ::Integer
|
|
94
94
|
raise ArgumentError, "must be a kind of Integer, but got #{arg.inspect}"
|
|
95
95
|
end
|
|
96
|
-
if arg.size > 0xffff_ffff
|
|
97
|
-
raise ArgumentError, "must be shorter than or equal to #{0xffff_ffff}, but got length #{arg.size}"
|
|
98
|
-
end
|
|
99
96
|
bn = ::OpenSSL::BN.new(arg)
|
|
100
97
|
if bn < 0
|
|
101
98
|
# get 2's complement
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
# coding: utf-8
|
|
2
|
+
# vim: et ts=2 sw=2
|
|
3
|
+
|
|
4
|
+
require 'hrr_rb_ssh/logger'
|
|
5
|
+
require 'hrr_rb_ssh/transport'
|
|
6
|
+
require 'hrr_rb_ssh/authentication'
|
|
7
|
+
require 'hrr_rb_ssh/connection'
|
|
8
|
+
|
|
9
|
+
module HrrRbSsh
|
|
10
|
+
class Server
|
|
11
|
+
def initialize io, options={}
|
|
12
|
+
@logger = Logger.new self.class.name
|
|
13
|
+
@transport = HrrRbSsh::Transport.new io, HrrRbSsh::Mode::SERVER, options
|
|
14
|
+
@authentication = HrrRbSsh::Authentication.new @transport, options
|
|
15
|
+
@connection = HrrRbSsh::Connection.new @authentication, options
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def start
|
|
19
|
+
@logger.info { "start server service" }
|
|
20
|
+
@connection.start
|
|
21
|
+
end
|
|
22
|
+
end
|
|
23
|
+
end
|
|
@@ -9,7 +9,7 @@ module HrrRbSsh
|
|
|
9
9
|
class CompressionAlgorithm
|
|
10
10
|
module Functionable
|
|
11
11
|
def initialize direction
|
|
12
|
-
@logger =
|
|
12
|
+
@logger = Logger.new(self.class.name)
|
|
13
13
|
case direction
|
|
14
14
|
when Direction::OUTGOING
|
|
15
15
|
@deflator = ::Zlib::Deflate.new
|
|
@@ -14,12 +14,12 @@ module HrrRbSsh
|
|
|
14
14
|
end
|
|
15
15
|
|
|
16
16
|
def initialize direction, iv, key
|
|
17
|
-
@logger =
|
|
17
|
+
@logger = Logger.new(self.class.name)
|
|
18
18
|
@cipher = OpenSSL::Cipher.new(self.class::CIPHER_NAME)
|
|
19
19
|
case direction
|
|
20
|
-
when
|
|
20
|
+
when Direction::OUTGOING
|
|
21
21
|
@cipher.encrypt
|
|
22
|
-
when
|
|
22
|
+
when Direction::INCOMING
|
|
23
23
|
@cipher.decrypt
|
|
24
24
|
end
|
|
25
25
|
@cipher.padding = 0
|
|
@@ -4,13 +4,16 @@
|
|
|
4
4
|
require 'openssl'
|
|
5
5
|
require 'hrr_rb_ssh/logger'
|
|
6
6
|
require 'hrr_rb_ssh/data_type'
|
|
7
|
+
require 'hrr_rb_ssh/transport/kex_algorithm/iv_computable'
|
|
7
8
|
|
|
8
9
|
module HrrRbSsh
|
|
9
10
|
class Transport
|
|
10
11
|
class KexAlgorithm
|
|
11
12
|
module DiffieHellman
|
|
13
|
+
include IvComputable
|
|
14
|
+
|
|
12
15
|
def initialize
|
|
13
|
-
@logger =
|
|
16
|
+
@logger = Logger.new(self.class.name)
|
|
14
17
|
@dh = OpenSSL::PKey::DH.new
|
|
15
18
|
if @dh.respond_to?(:set_pqg)
|
|
16
19
|
@dh.set_pqg OpenSSL::BN.new(self.class::P, 16), nil, OpenSSL::BN.new(self.class::G)
|
|
@@ -23,7 +26,7 @@ module HrrRbSsh
|
|
|
23
26
|
|
|
24
27
|
def start transport, mode
|
|
25
28
|
case mode
|
|
26
|
-
when
|
|
29
|
+
when Mode::SERVER
|
|
27
30
|
receive_kexdh_init transport.receive
|
|
28
31
|
send_kexdh_reply transport
|
|
29
32
|
else
|
|
@@ -72,62 +75,19 @@ module HrrRbSsh
|
|
|
72
75
|
s
|
|
73
76
|
end
|
|
74
77
|
|
|
75
|
-
def build_key(_k, h, _x, session_id, key_length)
|
|
76
|
-
k = DataType::Mpint.encode _k
|
|
77
|
-
x = DataType::Byte.encode _x
|
|
78
|
-
|
|
79
|
-
key = OpenSSL::Digest.digest(self.class::DIGEST, k + h + x + session_id)
|
|
80
|
-
|
|
81
|
-
while key.length < key_length
|
|
82
|
-
key = key + OpenSSL::Digest.digest(self.class::DIGEST, k + h + key )
|
|
83
|
-
end
|
|
84
|
-
|
|
85
|
-
key[0, key_length]
|
|
86
|
-
end
|
|
87
|
-
|
|
88
|
-
def iv_c_to_s transport, encryption_algorithm_c_to_s_name
|
|
89
|
-
key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_c_to_s_name]::IV_LENGTH
|
|
90
|
-
build_key(shared_secret, hash(transport), 'A'.ord, transport.session_id, key_length)
|
|
91
|
-
end
|
|
92
|
-
|
|
93
|
-
def iv_s_to_c transport, encryption_algorithm_s_to_c_name
|
|
94
|
-
key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_s_to_c_name]::IV_LENGTH
|
|
95
|
-
build_key(shared_secret, hash(transport), 'B'.ord, transport.session_id, key_length)
|
|
96
|
-
end
|
|
97
|
-
|
|
98
|
-
def key_c_to_s transport, encryption_algorithm_c_to_s_name
|
|
99
|
-
key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_c_to_s_name]::KEY_LENGTH
|
|
100
|
-
build_key(shared_secret, hash(transport), 'C'.ord, transport.session_id, key_length)
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def key_s_to_c transport, encryption_algorithm_s_to_c_name
|
|
104
|
-
key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_s_to_c_name]::KEY_LENGTH
|
|
105
|
-
build_key(shared_secret, hash(transport), 'D'.ord, transport.session_id, key_length)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def mac_c_to_s transport, mac_algorithm_c_to_s_name
|
|
109
|
-
key_length = HrrRbSsh::Transport::MacAlgorithm[mac_algorithm_c_to_s_name]::KEY_LENGTH
|
|
110
|
-
build_key(shared_secret, hash(transport), 'E'.ord, transport.session_id, key_length)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def mac_s_to_c transport, mac_algorithm_s_to_c_name
|
|
114
|
-
key_length = HrrRbSsh::Transport::MacAlgorithm[mac_algorithm_s_to_c_name]::KEY_LENGTH
|
|
115
|
-
build_key(shared_secret, hash(transport), 'F'.ord, transport.session_id, key_length)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
78
|
def receive_kexdh_init payload
|
|
119
|
-
message =
|
|
79
|
+
message = Message::SSH_MSG_KEXDH_INIT.decode payload
|
|
120
80
|
set_e message[:'e']
|
|
121
81
|
end
|
|
122
82
|
|
|
123
83
|
def send_kexdh_reply transport
|
|
124
84
|
message = {
|
|
125
|
-
:'message number' =>
|
|
85
|
+
:'message number' => Message::SSH_MSG_KEXDH_REPLY::VALUE,
|
|
126
86
|
:'server public host key and certificates (K_S)' => transport.server_host_key_algorithm.server_public_host_key,
|
|
127
87
|
:'f' => pub_key,
|
|
128
88
|
:'signature of H' => sign(transport),
|
|
129
89
|
}
|
|
130
|
-
payload =
|
|
90
|
+
payload = Message::SSH_MSG_KEXDH_REPLY.encode message
|
|
131
91
|
transport.send payload
|
|
132
92
|
end
|
|
133
93
|
end
|
|
@@ -4,18 +4,21 @@
|
|
|
4
4
|
require 'openssl'
|
|
5
5
|
require 'hrr_rb_ssh/logger'
|
|
6
6
|
require 'hrr_rb_ssh/data_type'
|
|
7
|
+
require 'hrr_rb_ssh/transport/kex_algorithm/iv_computable'
|
|
7
8
|
|
|
8
9
|
module HrrRbSsh
|
|
9
10
|
class Transport
|
|
10
11
|
class KexAlgorithm
|
|
11
12
|
module DiffieHellmanGroupExchange
|
|
13
|
+
include IvComputable
|
|
14
|
+
|
|
12
15
|
def initialize
|
|
13
|
-
@logger =
|
|
16
|
+
@logger = Logger.new(self.class.name)
|
|
14
17
|
end
|
|
15
18
|
|
|
16
19
|
def start transport, mode
|
|
17
20
|
case mode
|
|
18
|
-
when
|
|
21
|
+
when Mode::SERVER
|
|
19
22
|
receive_kex_dh_gex_request transport.receive
|
|
20
23
|
set_dh
|
|
21
24
|
send_kex_dh_gex_group transport
|
|
@@ -87,51 +90,8 @@ module HrrRbSsh
|
|
|
87
90
|
s
|
|
88
91
|
end
|
|
89
92
|
|
|
90
|
-
def build_key(_k, h, _x, session_id, key_length)
|
|
91
|
-
k = DataType::Mpint.encode _k
|
|
92
|
-
x = DataType::Byte.encode _x
|
|
93
|
-
|
|
94
|
-
key = OpenSSL::Digest.digest(self.class::DIGEST, k + h + x + session_id)
|
|
95
|
-
|
|
96
|
-
while key.length < key_length
|
|
97
|
-
key = key + OpenSSL::Digest.digest(self.class::DIGEST, k + h + key )
|
|
98
|
-
end
|
|
99
|
-
|
|
100
|
-
key[0, key_length]
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
def iv_c_to_s transport, encryption_algorithm_c_to_s_name
|
|
104
|
-
key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_c_to_s_name]::IV_LENGTH
|
|
105
|
-
build_key(shared_secret, hash(transport), 'A'.ord, transport.session_id, key_length)
|
|
106
|
-
end
|
|
107
|
-
|
|
108
|
-
def iv_s_to_c transport, encryption_algorithm_s_to_c_name
|
|
109
|
-
key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_s_to_c_name]::IV_LENGTH
|
|
110
|
-
build_key(shared_secret, hash(transport), 'B'.ord, transport.session_id, key_length)
|
|
111
|
-
end
|
|
112
|
-
|
|
113
|
-
def key_c_to_s transport, encryption_algorithm_c_to_s_name
|
|
114
|
-
key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_c_to_s_name]::KEY_LENGTH
|
|
115
|
-
build_key(shared_secret, hash(transport), 'C'.ord, transport.session_id, key_length)
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
def key_s_to_c transport, encryption_algorithm_s_to_c_name
|
|
119
|
-
key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_s_to_c_name]::KEY_LENGTH
|
|
120
|
-
build_key(shared_secret, hash(transport), 'D'.ord, transport.session_id, key_length)
|
|
121
|
-
end
|
|
122
|
-
|
|
123
|
-
def mac_c_to_s transport, mac_algorithm_c_to_s_name
|
|
124
|
-
key_length = HrrRbSsh::Transport::MacAlgorithm[mac_algorithm_c_to_s_name]::KEY_LENGTH
|
|
125
|
-
build_key(shared_secret, hash(transport), 'E'.ord, transport.session_id, key_length)
|
|
126
|
-
end
|
|
127
|
-
|
|
128
|
-
def mac_s_to_c transport, mac_algorithm_s_to_c_name
|
|
129
|
-
key_length = HrrRbSsh::Transport::MacAlgorithm[mac_algorithm_s_to_c_name]::KEY_LENGTH
|
|
130
|
-
build_key(shared_secret, hash(transport), 'F'.ord, transport.session_id, key_length)
|
|
131
|
-
end
|
|
132
|
-
|
|
133
93
|
def receive_kex_dh_gex_request payload
|
|
134
|
-
message =
|
|
94
|
+
message = Message::SSH_MSG_KEX_DH_GEX_REQUEST.decode payload
|
|
135
95
|
@min = message[:'min']
|
|
136
96
|
@n = message[:'n']
|
|
137
97
|
@max = message[:'max']
|
|
@@ -139,27 +99,27 @@ module HrrRbSsh
|
|
|
139
99
|
|
|
140
100
|
def send_kex_dh_gex_group transport
|
|
141
101
|
message = {
|
|
142
|
-
:'message number' =>
|
|
102
|
+
:'message number' => Message::SSH_MSG_KEX_DH_GEX_GROUP::VALUE,
|
|
143
103
|
:'p' => @dh.p.to_i,
|
|
144
104
|
:'g' => @dh.g.to_i,
|
|
145
105
|
}
|
|
146
|
-
payload =
|
|
106
|
+
payload = Message::SSH_MSG_KEX_DH_GEX_GROUP.encode message
|
|
147
107
|
transport.send payload
|
|
148
108
|
end
|
|
149
109
|
|
|
150
110
|
def receive_kex_dh_gex_init payload
|
|
151
|
-
message =
|
|
111
|
+
message = Message::SSH_MSG_KEX_DH_GEX_INIT.decode payload
|
|
152
112
|
set_e message[:'e']
|
|
153
113
|
end
|
|
154
114
|
|
|
155
115
|
def send_kex_dh_gex_reply transport
|
|
156
116
|
message = {
|
|
157
|
-
:'message number' =>
|
|
117
|
+
:'message number' => Message::SSH_MSG_KEX_DH_GEX_REPLY::VALUE,
|
|
158
118
|
:'server public host key and certificates (K_S)' => transport.server_host_key_algorithm.server_public_host_key,
|
|
159
119
|
:'f' => pub_key,
|
|
160
120
|
:'signature of H' => sign(transport),
|
|
161
121
|
}
|
|
162
|
-
payload =
|
|
122
|
+
payload = Message::SSH_MSG_KEX_DH_GEX_REPLY.encode message
|
|
163
123
|
transport.send payload
|
|
164
124
|
end
|
|
165
125
|
end
|
|
@@ -4,20 +4,23 @@
|
|
|
4
4
|
require 'openssl'
|
|
5
5
|
require 'hrr_rb_ssh/logger'
|
|
6
6
|
require 'hrr_rb_ssh/data_type'
|
|
7
|
+
require 'hrr_rb_ssh/transport/kex_algorithm/iv_computable'
|
|
7
8
|
|
|
8
9
|
module HrrRbSsh
|
|
9
10
|
class Transport
|
|
10
11
|
class KexAlgorithm
|
|
11
12
|
module EllipticCurveDiffieHellman
|
|
13
|
+
include IvComputable
|
|
14
|
+
|
|
12
15
|
def initialize
|
|
13
|
-
@logger =
|
|
16
|
+
@logger = Logger.new(self.class.name)
|
|
14
17
|
@dh = OpenSSL::PKey::EC.new(self.class::CURVE_NAME)
|
|
15
18
|
@dh.generate_key
|
|
16
19
|
end
|
|
17
20
|
|
|
18
21
|
def start transport, mode
|
|
19
22
|
case mode
|
|
20
|
-
when
|
|
23
|
+
when Mode::SERVER
|
|
21
24
|
receive_kexecdh_init transport.receive
|
|
22
25
|
send_kexecdh_reply transport
|
|
23
26
|
else
|
|
@@ -66,62 +69,19 @@ module HrrRbSsh
|
|
|
66
69
|
s
|
|
67
70
|
end
|
|
68
71
|
|
|
69
|
-
def build_key(_k, h, _x, session_id, key_length)
|
|
70
|
-
k = DataType::Mpint.encode _k
|
|
71
|
-
x = DataType::Byte.encode _x
|
|
72
|
-
|
|
73
|
-
key = OpenSSL::Digest.digest(self.class::DIGEST, k + h + x + session_id)
|
|
74
|
-
|
|
75
|
-
while key.length < key_length
|
|
76
|
-
key = key + OpenSSL::Digest.digest(self.class::DIGEST, k + h + key )
|
|
77
|
-
end
|
|
78
|
-
|
|
79
|
-
key[0, key_length]
|
|
80
|
-
end
|
|
81
|
-
|
|
82
|
-
def iv_c_to_s transport, encryption_algorithm_c_to_s_name
|
|
83
|
-
key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_c_to_s_name]::IV_LENGTH
|
|
84
|
-
build_key(shared_secret, hash(transport), 'A'.ord, transport.session_id, key_length)
|
|
85
|
-
end
|
|
86
|
-
|
|
87
|
-
def iv_s_to_c transport, encryption_algorithm_s_to_c_name
|
|
88
|
-
key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_s_to_c_name]::IV_LENGTH
|
|
89
|
-
build_key(shared_secret, hash(transport), 'B'.ord, transport.session_id, key_length)
|
|
90
|
-
end
|
|
91
|
-
|
|
92
|
-
def key_c_to_s transport, encryption_algorithm_c_to_s_name
|
|
93
|
-
key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_c_to_s_name]::KEY_LENGTH
|
|
94
|
-
build_key(shared_secret, hash(transport), 'C'.ord, transport.session_id, key_length)
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
def key_s_to_c transport, encryption_algorithm_s_to_c_name
|
|
98
|
-
key_length = HrrRbSsh::Transport::EncryptionAlgorithm[encryption_algorithm_s_to_c_name]::KEY_LENGTH
|
|
99
|
-
build_key(shared_secret, hash(transport), 'D'.ord, transport.session_id, key_length)
|
|
100
|
-
end
|
|
101
|
-
|
|
102
|
-
def mac_c_to_s transport, mac_algorithm_c_to_s_name
|
|
103
|
-
key_length = HrrRbSsh::Transport::MacAlgorithm[mac_algorithm_c_to_s_name]::KEY_LENGTH
|
|
104
|
-
build_key(shared_secret, hash(transport), 'E'.ord, transport.session_id, key_length)
|
|
105
|
-
end
|
|
106
|
-
|
|
107
|
-
def mac_s_to_c transport, mac_algorithm_s_to_c_name
|
|
108
|
-
key_length = HrrRbSsh::Transport::MacAlgorithm[mac_algorithm_s_to_c_name]::KEY_LENGTH
|
|
109
|
-
build_key(shared_secret, hash(transport), 'F'.ord, transport.session_id, key_length)
|
|
110
|
-
end
|
|
111
|
-
|
|
112
72
|
def receive_kexecdh_init payload
|
|
113
|
-
message =
|
|
73
|
+
message = Message::SSH_MSG_KEXECDH_INIT.decode payload
|
|
114
74
|
set_q_c message[:'Q_C']
|
|
115
75
|
end
|
|
116
76
|
|
|
117
77
|
def send_kexecdh_reply transport
|
|
118
78
|
message = {
|
|
119
|
-
:'message number' =>
|
|
79
|
+
:'message number' => Message::SSH_MSG_KEXECDH_REPLY::VALUE,
|
|
120
80
|
:'K_S' => transport.server_host_key_algorithm.server_public_host_key,
|
|
121
81
|
:'Q_S' => public_key,
|
|
122
82
|
:'signature of H' => sign(transport),
|
|
123
83
|
}
|
|
124
|
-
payload =
|
|
84
|
+
payload = Message::SSH_MSG_KEXECDH_REPLY.encode message
|
|
125
85
|
transport.send payload
|
|
126
86
|
end
|
|
127
87
|
end
|