hrr_rb_ssh 0.3.0.pre1 → 0.4.2
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/.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
|