hrr_rb_ssh 0.3.0.pre1 → 0.4.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.gitignore +0 -3
- data/.travis.yml +1 -0
- data/README.md +208 -46
- data/demo/client.rb +71 -0
- data/demo/echo_server.rb +8 -3
- data/demo/more_flexible_auth.rb +105 -0
- data/demo/multi_step_auth.rb +99 -0
- data/demo/server.rb +10 -4
- data/demo/subsystem_echo_server.rb +8 -3
- data/hrr_rb_ssh.gemspec +6 -6
- data/lib/hrr_rb_ssh.rb +1 -1
- data/lib/hrr_rb_ssh/algorithm/publickey.rb +0 -1
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2.rb +12 -9
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2/ecdsa_signature_blob.rb +2 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2/public_key_blob.rb +2 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2/signature.rb +2 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_dss.rb +10 -7
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_dss/public_key_blob.rb +2 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_dss/signature.rb +2 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa.rb +9 -6
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa/public_key_blob.rb +2 -4
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa/signature.rb +2 -4
- data/lib/hrr_rb_ssh/authentication.rb +103 -22
- data/lib/hrr_rb_ssh/authentication/constant.rb +14 -0
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive.rb +44 -7
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/context.rb +16 -9
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/info_request.rb +7 -6
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/info_response.rb +5 -2
- data/lib/hrr_rb_ssh/authentication/method/none.rb +23 -7
- data/lib/hrr_rb_ssh/authentication/method/none/context.rb +15 -7
- data/lib/hrr_rb_ssh/authentication/method/password.rb +28 -7
- data/lib/hrr_rb_ssh/authentication/method/password/context.rb +16 -7
- data/lib/hrr_rb_ssh/authentication/method/publickey.rb +63 -10
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm.rb +0 -1
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/functionable.rb +32 -8
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/signature_blob.rb +2 -4
- data/lib/hrr_rb_ssh/authentication/method/publickey/context.rb +11 -2
- data/lib/hrr_rb_ssh/client.rb +234 -0
- data/lib/hrr_rb_ssh/codable.rb +15 -13
- data/lib/hrr_rb_ssh/compat/ruby.rb +0 -1
- data/lib/hrr_rb_ssh/connection.rb +145 -75
- data/lib/hrr_rb_ssh/connection/channel.rb +342 -109
- data/lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb +24 -19
- data/lib/hrr_rb_ssh/connection/channel/channel_type/forwarded_tcpip.rb +24 -19
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session.rb +19 -12
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain.rb +0 -2
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/proc_chain/chain_context.rb +0 -3
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env.rb +2 -5
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/env/context.rb +5 -4
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec.rb +2 -5
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/exec/context.rb +5 -4
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req.rb +2 -5
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/pty_req/context.rb +5 -4
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell.rb +2 -5
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/shell/context.rb +5 -4
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem.rb +2 -5
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/subsystem/context.rb +5 -4
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change.rb +2 -5
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type/window_change/context.rb +5 -4
- data/lib/hrr_rb_ssh/connection/global_request_handler.rb +14 -12
- data/lib/hrr_rb_ssh/connection/request_handler.rb +1 -3
- data/lib/hrr_rb_ssh/connection/request_handler/reference_env_request_handler.rb +0 -2
- data/lib/hrr_rb_ssh/connection/request_handler/reference_exec_request_handler.rb +4 -6
- data/lib/hrr_rb_ssh/connection/request_handler/reference_pty_req_request_handler.rb +10 -12
- data/lib/hrr_rb_ssh/connection/request_handler/reference_shell_request_handler.rb +4 -6
- data/lib/hrr_rb_ssh/connection/request_handler/reference_window_change_request_handler.rb +0 -2
- data/lib/hrr_rb_ssh/error/closed_authentication.rb +1 -1
- data/lib/hrr_rb_ssh/error/closed_connection.rb +1 -1
- data/lib/hrr_rb_ssh/error/closed_transport.rb +1 -1
- data/lib/hrr_rb_ssh/loggable.rb +42 -0
- data/lib/hrr_rb_ssh/message/001_ssh_msg_disconnect.rb +2 -4
- data/lib/hrr_rb_ssh/message/002_ssh_msg_ignore.rb +2 -4
- data/lib/hrr_rb_ssh/message/003_ssh_msg_unimplemented.rb +2 -4
- data/lib/hrr_rb_ssh/message/004_ssh_msg_debug.rb +2 -4
- data/lib/hrr_rb_ssh/message/005_ssh_msg_service_request.rb +2 -4
- data/lib/hrr_rb_ssh/message/006_ssh_msg_service_accept.rb +2 -4
- data/lib/hrr_rb_ssh/message/020_ssh_msg_kexinit.rb +2 -4
- data/lib/hrr_rb_ssh/message/021_ssh_msg_newkeys.rb +2 -4
- data/lib/hrr_rb_ssh/message/030_ssh_msg_kex_dh_gex_request_old.rb +2 -4
- data/lib/hrr_rb_ssh/message/030_ssh_msg_kexdh_init.rb +2 -4
- data/lib/hrr_rb_ssh/message/030_ssh_msg_kexecdh_init.rb +2 -4
- data/lib/hrr_rb_ssh/message/031_ssh_msg_kex_dh_gex_group.rb +2 -4
- data/lib/hrr_rb_ssh/message/031_ssh_msg_kexdh_reply.rb +2 -4
- data/lib/hrr_rb_ssh/message/031_ssh_msg_kexecdh_reply.rb +2 -4
- data/lib/hrr_rb_ssh/message/032_ssh_msg_kex_dh_gex_init.rb +2 -4
- data/lib/hrr_rb_ssh/message/033_ssh_msg_kex_dh_gex_reply.rb +2 -4
- data/lib/hrr_rb_ssh/message/034_ssh_msg_kex_dh_gex_request.rb +2 -4
- data/lib/hrr_rb_ssh/message/050_ssh_msg_userauth_request.rb +2 -4
- data/lib/hrr_rb_ssh/message/051_ssh_msg_userauth_failure.rb +2 -4
- data/lib/hrr_rb_ssh/message/052_ssh_msg_userauth_success.rb +2 -4
- data/lib/hrr_rb_ssh/message/060_ssh_msg_userauth_info_request.rb +2 -4
- data/lib/hrr_rb_ssh/message/060_ssh_msg_userauth_pk_ok.rb +2 -4
- data/lib/hrr_rb_ssh/message/061_ssh_msg_userauth_info_response.rb +2 -4
- data/lib/hrr_rb_ssh/message/080_ssh_msg_global_request.rb +2 -4
- data/lib/hrr_rb_ssh/message/081_ssh_msg_request_success.rb +2 -4
- data/lib/hrr_rb_ssh/message/082_ssh_msg_request_failure.rb +2 -4
- data/lib/hrr_rb_ssh/message/090_ssh_msg_channel_open.rb +2 -4
- data/lib/hrr_rb_ssh/message/091_ssh_msg_channel_open_confirmation.rb +2 -4
- data/lib/hrr_rb_ssh/message/092_ssh_msg_channel_open_failure.rb +2 -4
- data/lib/hrr_rb_ssh/message/093_ssh_msg_channel_window_adjust.rb +2 -4
- data/lib/hrr_rb_ssh/message/094_ssh_msg_channel_data.rb +2 -4
- data/lib/hrr_rb_ssh/message/095_ssh_msg_channel_extended_data.rb +2 -4
- data/lib/hrr_rb_ssh/message/096_ssh_msg_channel_eof.rb +2 -4
- data/lib/hrr_rb_ssh/message/097_ssh_msg_channel_close.rb +2 -4
- data/lib/hrr_rb_ssh/message/098_ssh_msg_channel_request.rb +3 -5
- data/lib/hrr_rb_ssh/message/099_ssh_msg_channel_success.rb +2 -4
- data/lib/hrr_rb_ssh/message/100_ssh_msg_channel_failure.rb +2 -4
- data/lib/hrr_rb_ssh/server.rb +16 -10
- data/lib/hrr_rb_ssh/transport.rb +113 -77
- data/lib/hrr_rb_ssh/transport/compression_algorithm/functionable.rb +5 -3
- data/lib/hrr_rb_ssh/transport/compression_algorithm/unfunctionable.rb +5 -3
- data/lib/hrr_rb_ssh/transport/encryption_algorithm/functionable.rb +5 -3
- data/lib/hrr_rb_ssh/transport/encryption_algorithm/unfunctionable.rb +5 -3
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman.rb +43 -37
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman/h0.rb +2 -4
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb +87 -52
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange/h0.rb +2 -4
- data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman.rb +43 -37
- data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman/h0.rb +2 -4
- data/lib/hrr_rb_ssh/transport/mac_algorithm/functionable.rb +5 -3
- data/lib/hrr_rb_ssh/transport/mac_algorithm/unfunctionable.rb +5 -3
- data/lib/hrr_rb_ssh/transport/receiver.rb +8 -7
- data/lib/hrr_rb_ssh/transport/sender.rb +5 -3
- data/lib/hrr_rb_ssh/transport/sequence_number.rb +0 -4
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm.rb +0 -1
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/functionable.rb +5 -3
- data/lib/hrr_rb_ssh/version.rb +1 -1
- metadata +18 -51
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519.rb +0 -61
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/openssh_private_key.rb +0 -29
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/openssh_private_key_content.rb +0 -26
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/pkey.rb +0 -158
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/public_key_blob.rb +0 -23
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/signature.rb +0 -23
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_ed25519.rb +0 -21
- data/lib/hrr_rb_ssh/compat/ruby/array.rb +0 -14
- data/lib/hrr_rb_ssh/logger.rb +0 -56
- data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_ed25519.rb +0 -20
@@ -6,10 +6,8 @@ require 'hrr_rb_ssh/codable'
|
|
6
6
|
|
7
7
|
module HrrRbSsh
|
8
8
|
module Message
|
9
|
-
|
10
|
-
|
11
|
-
include Codable
|
12
|
-
end
|
9
|
+
class SSH_MSG_CHANNEL_OPEN_CONFIRMATION
|
10
|
+
include Codable
|
13
11
|
|
14
12
|
ID = self.name.split('::').last
|
15
13
|
VALUE = 91
|
@@ -6,7 +6,7 @@ require 'hrr_rb_ssh/codable'
|
|
6
6
|
|
7
7
|
module HrrRbSsh
|
8
8
|
module Message
|
9
|
-
|
9
|
+
class SSH_MSG_CHANNEL_OPEN_FAILURE
|
10
10
|
module ReasonCode
|
11
11
|
SSH_OPEN_ADMINISTRATIVELY_PROHIBITED = 1
|
12
12
|
SSH_OPEN_CONNECT_FAILED = 2
|
@@ -14,9 +14,7 @@ module HrrRbSsh
|
|
14
14
|
SSH_OPEN_RESOURCE_SHORTAGE = 4
|
15
15
|
end
|
16
16
|
|
17
|
-
|
18
|
-
include Codable
|
19
|
-
end
|
17
|
+
include Codable
|
20
18
|
|
21
19
|
ID = self.name.split('::').last
|
22
20
|
VALUE = 92
|
@@ -6,10 +6,8 @@ require 'hrr_rb_ssh/codable'
|
|
6
6
|
|
7
7
|
module HrrRbSsh
|
8
8
|
module Message
|
9
|
-
|
10
|
-
|
11
|
-
include Codable
|
12
|
-
end
|
9
|
+
class SSH_MSG_CHANNEL_WINDOW_ADJUST
|
10
|
+
include Codable
|
13
11
|
|
14
12
|
ID = self.name.split('::').last
|
15
13
|
VALUE = 93
|
@@ -6,14 +6,12 @@ require 'hrr_rb_ssh/codable'
|
|
6
6
|
|
7
7
|
module HrrRbSsh
|
8
8
|
module Message
|
9
|
-
|
9
|
+
class SSH_MSG_CHANNEL_EXTENDED_DATA
|
10
10
|
module DataTypeCode
|
11
11
|
SSH_EXTENDED_DATA_STDERR = 1
|
12
12
|
end
|
13
13
|
|
14
|
-
|
15
|
-
include Codable
|
16
|
-
end
|
14
|
+
include Codable
|
17
15
|
|
18
16
|
ID = self.name.split('::').last
|
19
17
|
VALUE = 95
|
@@ -6,7 +6,7 @@ require 'hrr_rb_ssh/codable'
|
|
6
6
|
|
7
7
|
module HrrRbSsh
|
8
8
|
module Message
|
9
|
-
|
9
|
+
class SSH_MSG_CHANNEL_REQUEST
|
10
10
|
module SignalName
|
11
11
|
ABRT = 'ABRT'
|
12
12
|
ALRM = 'ALRM'
|
@@ -82,14 +82,12 @@ module HrrRbSsh
|
|
82
82
|
TTY_OP_OSPEED = 129
|
83
83
|
end
|
84
84
|
|
85
|
-
|
86
|
-
include Codable
|
87
|
-
end
|
85
|
+
include Codable
|
88
86
|
|
89
87
|
ID = self.name.split('::').last
|
90
88
|
VALUE = 98
|
91
89
|
|
92
|
-
TERMINAL_MODE_INV = TerminalMode.constants.map{|c| [TerminalMode.const_get(c), c.to_s]}.
|
90
|
+
TERMINAL_MODE_INV = TerminalMode.constants.map{|c| [TerminalMode.const_get(c), c.to_s]}.inject(Hash.new){ |h, (k, v)| h.update({k => v}) }
|
93
91
|
|
94
92
|
DEFINITION = [
|
95
93
|
#[DataType, Field Name]
|
data/lib/hrr_rb_ssh/server.rb
CHANGED
@@ -1,29 +1,35 @@
|
|
1
1
|
# coding: utf-8
|
2
2
|
# vim: et ts=2 sw=2
|
3
3
|
|
4
|
-
require 'hrr_rb_ssh/
|
4
|
+
require 'hrr_rb_ssh/loggable'
|
5
5
|
require 'hrr_rb_ssh/transport'
|
6
6
|
require 'hrr_rb_ssh/authentication'
|
7
7
|
require 'hrr_rb_ssh/connection'
|
8
8
|
|
9
9
|
module HrrRbSsh
|
10
10
|
class Server
|
11
|
-
|
12
|
-
|
11
|
+
include Loggable
|
12
|
+
|
13
|
+
def self.start io, options={}, logger: nil
|
14
|
+
server = self.new options, logger: logger
|
13
15
|
server.start io
|
14
16
|
end
|
15
17
|
|
16
|
-
def initialize options={}
|
17
|
-
|
18
|
+
def initialize options={}, logger: nil
|
19
|
+
self.logger = logger
|
18
20
|
@options = options
|
19
21
|
end
|
20
22
|
|
21
23
|
def start io
|
22
|
-
|
23
|
-
transport =
|
24
|
-
authentication =
|
25
|
-
connection =
|
26
|
-
|
24
|
+
log_info { "start server service" }
|
25
|
+
transport = Transport.new io, Mode::SERVER, @options, logger: logger
|
26
|
+
authentication = Authentication.new transport, Mode::SERVER, @options, logger: logger
|
27
|
+
connection = Connection.new authentication, Mode::SERVER, @options, logger: logger
|
28
|
+
begin
|
29
|
+
connection.start
|
30
|
+
rescue Error::ClosedConnection
|
31
|
+
end
|
32
|
+
log_info { "server service finished" }
|
27
33
|
end
|
28
34
|
end
|
29
35
|
end
|
data/lib/hrr_rb_ssh/transport.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'monitor'
|
5
5
|
require 'hrr_rb_ssh/version'
|
6
|
-
require 'hrr_rb_ssh/
|
6
|
+
require 'hrr_rb_ssh/loggable'
|
7
7
|
require 'hrr_rb_ssh/data_type'
|
8
8
|
require 'hrr_rb_ssh/message'
|
9
9
|
require 'hrr_rb_ssh/error/closed_transport'
|
@@ -20,10 +20,12 @@ require 'hrr_rb_ssh/transport/compression_algorithm'
|
|
20
20
|
|
21
21
|
module HrrRbSsh
|
22
22
|
class Transport
|
23
|
+
include Loggable
|
23
24
|
include Constant
|
24
25
|
|
25
26
|
attr_reader \
|
26
27
|
:io,
|
28
|
+
:mode,
|
27
29
|
:supported_encryption_algorithms,
|
28
30
|
:supported_server_host_key_algorithms,
|
29
31
|
:supported_kex_algorithms,
|
@@ -49,20 +51,19 @@ module HrrRbSsh
|
|
49
51
|
:i_s,
|
50
52
|
:session_id
|
51
53
|
|
52
|
-
def initialize io, mode, options={}
|
54
|
+
def initialize io, mode, options={}, logger: nil
|
55
|
+
self.logger = logger
|
56
|
+
|
53
57
|
@io = io
|
54
58
|
@mode = mode
|
55
59
|
@options = options
|
56
60
|
|
57
|
-
@logger = Logger.new self.class.name
|
58
|
-
|
59
61
|
@closed = nil
|
60
|
-
@disconnected = nil
|
61
62
|
|
62
63
|
@in_kex = false
|
63
64
|
|
64
|
-
@sender = Sender.new
|
65
|
-
@receiver = Receiver.new
|
65
|
+
@sender = Sender.new logger: logger
|
66
|
+
@receiver = Receiver.new logger: logger
|
66
67
|
|
67
68
|
@sender_monitor = Monitor.new
|
68
69
|
@receiver_monitor = Monitor.new
|
@@ -86,15 +87,16 @@ module HrrRbSsh
|
|
86
87
|
end
|
87
88
|
|
88
89
|
def send payload
|
90
|
+
raise Error::ClosedTransport if @closed
|
89
91
|
@sender_monitor.synchronize do
|
90
92
|
begin
|
91
93
|
@sender.send self, payload
|
92
|
-
rescue
|
93
|
-
|
94
|
+
rescue IOError, SystemCallError => e
|
95
|
+
log_info { "#{e.message} (#{e.class})" }
|
94
96
|
close
|
95
97
|
raise Error::ClosedTransport
|
96
98
|
rescue => e
|
97
|
-
|
99
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
98
100
|
close
|
99
101
|
raise Error::ClosedTransport
|
100
102
|
end
|
@@ -108,25 +110,24 @@ module HrrRbSsh
|
|
108
110
|
payload = @receiver.receive self
|
109
111
|
case payload[0,1].unpack("C")[0]
|
110
112
|
when Message::SSH_MSG_DISCONNECT::VALUE
|
111
|
-
|
112
|
-
|
113
|
-
@disconnected = true
|
113
|
+
log_info { "received disconnect message" }
|
114
|
+
message = Message::SSH_MSG_DISCONNECT.new(logger: logger).decode payload
|
114
115
|
close
|
115
116
|
raise Error::ClosedTransport
|
116
117
|
when Message::SSH_MSG_IGNORE::VALUE
|
117
|
-
|
118
|
-
|
118
|
+
log_info { "received ignore message" }
|
119
|
+
message = Message::SSH_MSG_IGNORE.new(logger: logger).decode payload
|
119
120
|
receive
|
120
121
|
when Message::SSH_MSG_UNIMPLEMENTED::VALUE
|
121
|
-
|
122
|
-
|
122
|
+
log_info { "received unimplemented message" }
|
123
|
+
message = Message::SSH_MSG_UNIMPLEMENTED.new(logger: logger).decode payload
|
123
124
|
receive
|
124
125
|
when Message::SSH_MSG_DEBUG::VALUE
|
125
|
-
|
126
|
-
|
126
|
+
log_info { "received debug message" }
|
127
|
+
message = Message::SSH_MSG_DEBUG.new(logger: logger).decode payload
|
127
128
|
receive
|
128
129
|
when Message::SSH_MSG_KEXINIT::VALUE
|
129
|
-
|
130
|
+
log_info { "received kexinit message" }
|
130
131
|
if @in_kex
|
131
132
|
payload
|
132
133
|
else
|
@@ -137,20 +138,13 @@ module HrrRbSsh
|
|
137
138
|
payload
|
138
139
|
end
|
139
140
|
rescue Error::ClosedTransport
|
140
|
-
raise
|
141
|
-
rescue EOFError => e
|
142
|
-
|
143
|
-
raise Error::ClosedTransport
|
144
|
-
rescue IOError => e
|
145
|
-
@logger.warn { "IO is closed" }
|
146
|
-
close
|
147
|
-
raise Error::ClosedTransport
|
148
|
-
rescue Errno::ECONNRESET => e
|
149
|
-
@logger.warn { "IO is RESET" }
|
141
|
+
raise
|
142
|
+
rescue EOFError, IOError, SystemCallError => e
|
143
|
+
log_info { "#{e.message} (#{e.class})" }
|
150
144
|
close
|
151
145
|
raise Error::ClosedTransport
|
152
146
|
rescue => e
|
153
|
-
|
147
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
154
148
|
close
|
155
149
|
raise Error::ClosedTransport
|
156
150
|
end
|
@@ -158,36 +152,47 @@ module HrrRbSsh
|
|
158
152
|
end
|
159
153
|
|
160
154
|
def start
|
161
|
-
|
162
|
-
|
155
|
+
log_info { "start transport" }
|
163
156
|
begin
|
164
157
|
exchange_version
|
165
158
|
exchange_key
|
166
|
-
|
167
159
|
case @mode
|
168
160
|
when Mode::SERVER
|
169
161
|
verify_service_request
|
162
|
+
when Mode::CLIENT
|
163
|
+
send_service_request
|
170
164
|
end
|
171
|
-
|
172
165
|
@closed = false
|
173
|
-
rescue
|
166
|
+
rescue Error::ClosedTransport
|
167
|
+
raise
|
168
|
+
rescue EOFError, IOError, SystemCallError => e
|
169
|
+
log_info { "#{e.message} (#{e.class})" }
|
174
170
|
close
|
171
|
+
raise Error::ClosedTransport
|
175
172
|
rescue => e
|
176
|
-
|
173
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
177
174
|
close
|
175
|
+
raise Error::ClosedTransport
|
178
176
|
else
|
179
|
-
|
177
|
+
log_info { "transport started" }
|
180
178
|
end
|
181
179
|
end
|
182
180
|
|
183
181
|
def close
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
188
|
-
|
189
|
-
|
190
|
-
|
182
|
+
@sender_monitor.synchronize do
|
183
|
+
return if @closed
|
184
|
+
log_info { "close transport" }
|
185
|
+
begin
|
186
|
+
disconnect
|
187
|
+
@incoming_compression_algorithm.close
|
188
|
+
@outgoing_compression_algorithm.close
|
189
|
+
rescue => e
|
190
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
191
|
+
ensure
|
192
|
+
@closed = true
|
193
|
+
log_info { "transport closed" }
|
194
|
+
end
|
195
|
+
end
|
191
196
|
end
|
192
197
|
|
193
198
|
def closed?
|
@@ -195,17 +200,9 @@ module HrrRbSsh
|
|
195
200
|
end
|
196
201
|
|
197
202
|
def disconnect
|
198
|
-
|
199
|
-
|
200
|
-
|
201
|
-
begin
|
202
|
-
send_disconnect
|
203
|
-
rescue IOError
|
204
|
-
@logger.warn { "IO is closed" }
|
205
|
-
rescue => e
|
206
|
-
@logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
207
|
-
end
|
208
|
-
@logger.info { "transport disconnected" }
|
203
|
+
log_info { "disconnect transport" }
|
204
|
+
send_disconnect
|
205
|
+
log_info { "transport disconnected" }
|
209
206
|
end
|
210
207
|
|
211
208
|
def exchange_version
|
@@ -235,7 +232,7 @@ module HrrRbSsh
|
|
235
232
|
end
|
236
233
|
|
237
234
|
def start_kex_algorithm
|
238
|
-
@kex_algorithm.start self
|
235
|
+
@kex_algorithm.start self
|
239
236
|
end
|
240
237
|
|
241
238
|
def verify_service_request
|
@@ -314,10 +311,10 @@ module HrrRbSsh
|
|
314
311
|
if str_io.string[-2..-1] == "#{CR}#{LF}"
|
315
312
|
if str_io.string[0..3] == "SSH-"
|
316
313
|
@remote_version = str_io.string[0..-3]
|
317
|
-
|
314
|
+
log_info { "received remote version string: #{@remote_version}" }
|
318
315
|
break
|
319
316
|
else
|
320
|
-
|
317
|
+
log_info { "received message before remote version string: #{str_io.string}" }
|
321
318
|
str_io.rewind
|
322
319
|
str_io.truncate(0)
|
323
320
|
end
|
@@ -343,8 +340,16 @@ module HrrRbSsh
|
|
343
340
|
:'description' => "disconnected by user",
|
344
341
|
:'language tag' => ""
|
345
342
|
}
|
346
|
-
payload = Message::SSH_MSG_DISCONNECT.encode message
|
347
|
-
|
343
|
+
payload = Message::SSH_MSG_DISCONNECT.new(logger: logger).encode message
|
344
|
+
@sender_monitor.synchronize do
|
345
|
+
begin
|
346
|
+
@sender.send self, payload
|
347
|
+
rescue IOError, SystemCallError => e
|
348
|
+
log_info { "#{e.message} (#{e.class})" }
|
349
|
+
rescue => e
|
350
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
351
|
+
end
|
352
|
+
end
|
348
353
|
end
|
349
354
|
|
350
355
|
def send_kexinit
|
@@ -364,7 +369,7 @@ module HrrRbSsh
|
|
364
369
|
:'first_kex_packet_follows' => false,
|
365
370
|
:'0 (reserved for future extension)' => 0,
|
366
371
|
}
|
367
|
-
payload = Message::SSH_MSG_KEXINIT.encode message
|
372
|
+
payload = Message::SSH_MSG_KEXINIT.new(logger: logger).encode message
|
368
373
|
send payload
|
369
374
|
|
370
375
|
case @mode
|
@@ -382,7 +387,7 @@ module HrrRbSsh
|
|
382
387
|
when Mode::CLIENT
|
383
388
|
@i_s = payload
|
384
389
|
end
|
385
|
-
message = Message::SSH_MSG_KEXINIT.decode payload
|
390
|
+
message = Message::SSH_MSG_KEXINIT.new(logger: logger).decode payload
|
386
391
|
update_remote_algorithms message
|
387
392
|
end
|
388
393
|
|
@@ -390,28 +395,38 @@ module HrrRbSsh
|
|
390
395
|
message = {
|
391
396
|
:'message number' => Message::SSH_MSG_NEWKEYS::VALUE,
|
392
397
|
}
|
393
|
-
payload = Message::SSH_MSG_NEWKEYS.encode message
|
398
|
+
payload = Message::SSH_MSG_NEWKEYS.new(logger: logger).encode message
|
394
399
|
send payload
|
395
400
|
end
|
396
401
|
|
397
402
|
def receive_newkeys payload
|
398
|
-
message = Message::SSH_MSG_NEWKEYS.decode payload
|
403
|
+
message = Message::SSH_MSG_NEWKEYS.new(logger: logger).decode payload
|
399
404
|
end
|
400
405
|
|
401
|
-
def
|
406
|
+
def send_service_request
|
407
|
+
message = {
|
408
|
+
:'message number' => Message::SSH_MSG_SERVICE_REQUEST::VALUE,
|
409
|
+
:'service name' => 'ssh-userauth',
|
410
|
+
}
|
411
|
+
payload = Message::SSH_MSG_SERVICE_REQUEST.new(logger: logger).encode message
|
412
|
+
send payload
|
413
|
+
|
402
414
|
payload = @receiver.receive self
|
403
|
-
message = Message::
|
415
|
+
message = Message::SSH_MSG_SERVICE_ACCEPT.new(logger: logger).decode payload
|
416
|
+
end
|
404
417
|
|
405
|
-
|
418
|
+
def receive_service_request
|
419
|
+
payload = @receiver.receive self
|
420
|
+
message = Message::SSH_MSG_SERVICE_REQUEST.new(logger: logger).decode payload
|
406
421
|
end
|
407
422
|
|
408
423
|
def send_service_accept service_name
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
|
413
|
-
|
414
|
-
|
424
|
+
message = {
|
425
|
+
:'message number' => Message::SSH_MSG_SERVICE_ACCEPT::VALUE,
|
426
|
+
:'service name' => service_name,
|
427
|
+
}
|
428
|
+
payload = Message::SSH_MSG_SERVICE_ACCEPT.new(logger: logger).encode message
|
429
|
+
send payload
|
415
430
|
end
|
416
431
|
|
417
432
|
def update_remote_algorithms message
|
@@ -430,14 +445,14 @@ module HrrRbSsh
|
|
430
445
|
when Mode::SERVER
|
431
446
|
kex_algorithm_name = @remote_kex_algorithms.find{ |a| @local_kex_algorithms.include? a } or raise
|
432
447
|
server_host_key_algorithm_name = @remote_server_host_key_algorithms.find{ |a| @local_server_host_key_algorithms.include? a } or raise
|
448
|
+
server_secret_host_key = @options.fetch('transport_server_secret_host_keys', {}).fetch(server_host_key_algorithm_name, nil)
|
433
449
|
when Mode::CLIENT
|
434
450
|
kex_algorithm_name = @local_kex_algorithms.find{ |a| @remote_kex_algorithms.include? a } or raise
|
435
451
|
server_host_key_algorithm_name = @local_server_host_key_algorithms.find{ |a| @remote_server_host_key_algorithms.include? a } or raise
|
452
|
+
server_secret_host_key = nil
|
436
453
|
end
|
437
|
-
|
438
|
-
server_secret_host_key = @options.fetch('transport_server_secret_host_keys', {}).fetch(server_host_key_algorithm_name, nil)
|
439
|
-
@kex_algorithm = KexAlgorithm[kex_algorithm_name].new
|
440
454
|
@server_host_key_algorithm = ServerHostKeyAlgorithm[server_host_key_algorithm_name].new server_secret_host_key
|
455
|
+
@kex_algorithm = KexAlgorithm[kex_algorithm_name].new
|
441
456
|
end
|
442
457
|
|
443
458
|
def update_encryption_mac_compression_algorithms
|
@@ -458,6 +473,15 @@ module HrrRbSsh
|
|
458
473
|
outgoing_crpt_iv = @kex_algorithm.iv_s_to_c self, outgoing_encryption_algorithm_name
|
459
474
|
incoming_crpt_key = @kex_algorithm.key_c_to_s self, incoming_encryption_algorithm_name
|
460
475
|
outgoing_crpt_key = @kex_algorithm.key_s_to_c self, outgoing_encryption_algorithm_name
|
476
|
+
when Mode::CLIENT
|
477
|
+
encryption_algorithm_s_to_c_name = @local_encryption_algorithms_server_to_client.find{ |a| @remote_encryption_algorithms_server_to_client.include? a } or raise
|
478
|
+
encryption_algorithm_c_to_s_name = @local_encryption_algorithms_client_to_server.find{ |a| @remote_encryption_algorithms_client_to_server.include? a } or raise
|
479
|
+
incoming_encryption_algorithm_name = encryption_algorithm_s_to_c_name
|
480
|
+
outgoing_encryption_algorithm_name = encryption_algorithm_c_to_s_name
|
481
|
+
incoming_crpt_iv = @kex_algorithm.iv_s_to_c self, incoming_encryption_algorithm_name
|
482
|
+
outgoing_crpt_iv = @kex_algorithm.iv_c_to_s self, outgoing_encryption_algorithm_name
|
483
|
+
incoming_crpt_key = @kex_algorithm.key_s_to_c self, incoming_encryption_algorithm_name
|
484
|
+
outgoing_crpt_key = @kex_algorithm.key_c_to_s self, outgoing_encryption_algorithm_name
|
461
485
|
end
|
462
486
|
@incoming_encryption_algorithm = EncryptionAlgorithm[incoming_encryption_algorithm_name].new Direction::INCOMING, incoming_crpt_iv, incoming_crpt_key
|
463
487
|
@outgoing_encryption_algorithm = EncryptionAlgorithm[outgoing_encryption_algorithm_name].new Direction::OUTGOING, outgoing_crpt_iv, outgoing_crpt_key
|
@@ -472,6 +496,13 @@ module HrrRbSsh
|
|
472
496
|
outgoing_mac_algorithm_name = mac_algorithm_s_to_c_name
|
473
497
|
incoming_mac_key = @kex_algorithm.mac_c_to_s self, incoming_mac_algorithm_name
|
474
498
|
outgoing_mac_key = @kex_algorithm.mac_s_to_c self, outgoing_mac_algorithm_name
|
499
|
+
when Mode::CLIENT
|
500
|
+
mac_algorithm_s_to_c_name = @local_mac_algorithms_server_to_client.find{ |a| @remote_mac_algorithms_server_to_client.include? a } or raise
|
501
|
+
mac_algorithm_c_to_s_name = @local_mac_algorithms_client_to_server.find{ |a| @remote_mac_algorithms_client_to_server.include? a } or raise
|
502
|
+
incoming_mac_algorithm_name = mac_algorithm_s_to_c_name
|
503
|
+
outgoing_mac_algorithm_name = mac_algorithm_c_to_s_name
|
504
|
+
incoming_mac_key = @kex_algorithm.mac_s_to_c self, incoming_mac_algorithm_name
|
505
|
+
outgoing_mac_key = @kex_algorithm.mac_c_to_s self, outgoing_mac_algorithm_name
|
475
506
|
end
|
476
507
|
@incoming_mac_algorithm = MacAlgorithm[incoming_mac_algorithm_name].new incoming_mac_key
|
477
508
|
@outgoing_mac_algorithm = MacAlgorithm[outgoing_mac_algorithm_name].new outgoing_mac_key
|
@@ -484,6 +515,11 @@ module HrrRbSsh
|
|
484
515
|
compression_algorithm_s_to_c_name = @remote_compression_algorithms_server_to_client.find{ |a| @local_compression_algorithms_server_to_client.include? a } or raise
|
485
516
|
incoming_compression_algorithm_name = compression_algorithm_c_to_s_name
|
486
517
|
outgoing_compression_algorithm_name = compression_algorithm_s_to_c_name
|
518
|
+
when Mode::CLIENT
|
519
|
+
compression_algorithm_s_to_c_name = @local_compression_algorithms_server_to_client.find{ |a| @remote_compression_algorithms_server_to_client.include? a } or raise
|
520
|
+
compression_algorithm_c_to_s_name = @local_compression_algorithms_client_to_server.find{ |a| @remote_compression_algorithms_client_to_server.include? a } or raise
|
521
|
+
incoming_compression_algorithm_name = compression_algorithm_s_to_c_name
|
522
|
+
outgoing_compression_algorithm_name = compression_algorithm_c_to_s_name
|
487
523
|
end
|
488
524
|
@incoming_compression_algorithm.close
|
489
525
|
@outgoing_compression_algorithm.close
|