hrr_rb_ssh 0.1.9 → 0.2.0
Sign up to get free protection for your applications and to get access to all the features.
- 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
|