hrr_rb_ssh 0.4.0.pre1 → 0.4.0.pre2
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/README.md +16 -8
- data/demo/client.rb +1 -3
- data/demo/echo_server.rb +1 -3
- data/demo/more_flexible_auth.rb +1 -3
- data/demo/multi_step_auth.rb +1 -3
- data/demo/server.rb +1 -3
- data/demo/subsystem_echo_server.rb +1 -3
- data/hrr_rb_ssh.gemspec +1 -1
- data/lib/hrr_rb_ssh/algorithm/publickey/ecdsa_sha2.rb +12 -9
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_dss.rb +10 -7
- data/lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa.rb +9 -6
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/context.rb +9 -8
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/info_request.rb +6 -5
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/info_response.rb +5 -2
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive.rb +12 -10
- data/lib/hrr_rb_ssh/authentication/method/none/context.rb +7 -6
- data/lib/hrr_rb_ssh/authentication/method/none.rb +10 -8
- data/lib/hrr_rb_ssh/authentication/method/password/context.rb +7 -6
- data/lib/hrr_rb_ssh/authentication/method/password.rb +10 -8
- data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/functionable.rb +13 -11
- data/lib/hrr_rb_ssh/authentication/method/publickey/context.rb +5 -2
- data/lib/hrr_rb_ssh/authentication/method/publickey.rb +16 -14
- data/lib/hrr_rb_ssh/authentication.rb +28 -27
- data/lib/hrr_rb_ssh/client.rb +58 -56
- data/lib/hrr_rb_ssh/codable.rb +20 -10
- data/lib/hrr_rb_ssh/connection/channel/channel_type/direct_tcpip.rb +20 -18
- data/lib/hrr_rb_ssh/connection/channel/channel_type/forwarded_tcpip.rb +20 -18
- 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/proc_chain.rb +0 -2
- 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/env.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/exec.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/pty_req.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/shell.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/subsystem.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/channel/channel_type/session/request_type/window_change.rb +2 -5
- data/lib/hrr_rb_ssh/connection/channel/channel_type/session.rb +14 -12
- data/lib/hrr_rb_ssh/connection/channel.rb +73 -71
- data/lib/hrr_rb_ssh/connection/global_request_handler.rb +14 -12
- 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/connection/request_handler.rb +1 -3
- data/lib/hrr_rb_ssh/connection.rb +53 -53
- data/lib/hrr_rb_ssh/loggable.rb +42 -0
- data/lib/hrr_rb_ssh/server.rb +11 -9
- 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 +9 -8
- data/lib/hrr_rb_ssh/transport/kex_algorithm/diffie_hellman_group_exchange.rb +13 -12
- data/lib/hrr_rb_ssh/transport/kex_algorithm/elliptic_curve_diffie_hellman.rb +9 -8
- 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/functionable.rb +5 -3
- data/lib/hrr_rb_ssh/transport.rb +41 -40
- data/lib/hrr_rb_ssh/version.rb +1 -1
- data/lib/hrr_rb_ssh.rb +0 -1
- metadata +6 -6
- data/lib/hrr_rb_ssh/logger.rb +0 -56
@@ -1,30 +1,32 @@
|
|
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
|
|
6
6
|
module HrrRbSsh
|
7
7
|
class Authentication
|
8
8
|
class Method
|
9
9
|
class Password < Method
|
10
|
+
include Loggable
|
11
|
+
|
10
12
|
NAME = 'password'
|
11
13
|
PREFERENCE = 10
|
12
14
|
|
13
|
-
def initialize transport, options, variables, authentication_methods
|
14
|
-
|
15
|
+
def initialize transport, options, variables, authentication_methods, logger: nil
|
16
|
+
self.logger = logger
|
15
17
|
@transport = transport
|
16
|
-
@authenticator = options.fetch( 'authentication_password_authenticator', Authenticator.new
|
18
|
+
@authenticator = options.fetch( 'authentication_password_authenticator', Authenticator.new{ false } )
|
17
19
|
@options = options
|
18
20
|
@variables = variables
|
19
21
|
@authentication_methods = authentication_methods
|
20
22
|
end
|
21
23
|
|
22
24
|
def authenticate userauth_request_message
|
23
|
-
|
24
|
-
|
25
|
+
log_info { "authenticate" }
|
26
|
+
log_debug { "userauth request: " + userauth_request_message.inspect }
|
25
27
|
username = userauth_request_message[:'user name']
|
26
28
|
password = userauth_request_message[:'plaintext password']
|
27
|
-
context = Context.new(username, password, @variables, @authentication_methods)
|
29
|
+
context = Context.new(username, password, @variables, @authentication_methods, logger: logger)
|
28
30
|
@authenticator.authenticate context
|
29
31
|
end
|
30
32
|
|
@@ -38,7 +40,7 @@ module HrrRbSsh
|
|
38
40
|
:"FALSE" => false,
|
39
41
|
:"plaintext password" => password,
|
40
42
|
}
|
41
|
-
payload = Message::SSH_MSG_USERAUTH_REQUEST.encode message
|
43
|
+
payload = Message::SSH_MSG_USERAUTH_REQUEST.encode message, logger: logger
|
42
44
|
@transport.send payload
|
43
45
|
|
44
46
|
payload = @transport.receive
|
@@ -1,7 +1,7 @@
|
|
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/algorithm/publickey'
|
6
6
|
|
7
7
|
module HrrRbSsh
|
@@ -10,16 +10,18 @@ module HrrRbSsh
|
|
10
10
|
class Publickey
|
11
11
|
class Algorithm
|
12
12
|
module Functionable
|
13
|
-
|
14
|
-
|
13
|
+
include Loggable
|
14
|
+
|
15
|
+
def initialize logger: nil
|
16
|
+
self.logger = logger
|
15
17
|
end
|
16
18
|
|
17
19
|
def verify_public_key public_key_algorithm_name, public_key, public_key_blob
|
18
20
|
begin
|
19
|
-
publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new public_key
|
21
|
+
publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new public_key, logger: logger
|
20
22
|
public_key_algorithm_name == self.class::NAME && public_key_blob == publickey.to_public_key_blob
|
21
23
|
rescue => e
|
22
|
-
|
24
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
23
25
|
false
|
24
26
|
end
|
25
27
|
end
|
@@ -36,22 +38,22 @@ module HrrRbSsh
|
|
36
38
|
:'public key algorithm name' => message[:'public key algorithm name'],
|
37
39
|
:'public key blob' => message[:'public key blob'],
|
38
40
|
}
|
39
|
-
signature_blob = SignatureBlob.encode signature_blob_h
|
40
|
-
publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new message[:'public key blob']
|
41
|
+
signature_blob = SignatureBlob.encode signature_blob_h, logger: logger
|
42
|
+
publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new message[:'public key blob'], logger: logger
|
41
43
|
publickey.verify message[:'signature'], signature_blob
|
42
44
|
rescue => e
|
43
|
-
|
45
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
44
46
|
false
|
45
47
|
end
|
46
48
|
end
|
47
49
|
|
48
50
|
def generate_public_key_blob secret_key
|
49
|
-
publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new secret_key
|
51
|
+
publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new secret_key, logger: logger
|
50
52
|
publickey.to_public_key_blob
|
51
53
|
end
|
52
54
|
|
53
55
|
def generate_signature session_id, username, service_name, method_name, secret_key
|
54
|
-
publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new secret_key
|
56
|
+
publickey = HrrRbSsh::Algorithm::Publickey[self.class::NAME].new secret_key, logger: logger
|
55
57
|
publickey_blob = publickey.to_public_key_blob
|
56
58
|
signature_blob_h = {
|
57
59
|
:'session identifier' => session_id,
|
@@ -63,7 +65,7 @@ module HrrRbSsh
|
|
63
65
|
:'public key algorithm name' => self.class::NAME,
|
64
66
|
:'public key blob' => publickey_blob
|
65
67
|
}
|
66
|
-
signature_blob = SignatureBlob.encode signature_blob_h
|
68
|
+
signature_blob = SignatureBlob.encode signature_blob_h, logger: logger
|
67
69
|
publickey.sign signature_blob
|
68
70
|
end
|
69
71
|
end
|
@@ -1,13 +1,15 @@
|
|
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
|
|
6
6
|
module HrrRbSsh
|
7
7
|
class Authentication
|
8
8
|
class Method
|
9
9
|
class Publickey
|
10
10
|
class Context
|
11
|
+
include Loggable
|
12
|
+
|
11
13
|
attr_reader \
|
12
14
|
:username,
|
13
15
|
:session_id,
|
@@ -22,7 +24,8 @@ module HrrRbSsh
|
|
22
24
|
:public_key_blob,
|
23
25
|
:signature
|
24
26
|
|
25
|
-
def initialize username, algorithm, session_id, message, variables, authentication_methods
|
27
|
+
def initialize username, algorithm, session_id, message, variables, authentication_methods, logger: nil
|
28
|
+
self.logger = logger
|
26
29
|
@username = username
|
27
30
|
@algorithm = algorithm
|
28
31
|
@session_id = session_id
|
@@ -1,21 +1,23 @@
|
|
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
|
|
6
6
|
module HrrRbSsh
|
7
7
|
class Authentication
|
8
8
|
class Method
|
9
9
|
class Publickey < Method
|
10
|
+
include Loggable
|
11
|
+
|
10
12
|
NAME = 'publickey'
|
11
13
|
PREFERENCE = 20
|
12
14
|
|
13
|
-
def initialize transport, options, variables, authentication_methods
|
14
|
-
|
15
|
+
def initialize transport, options, variables, authentication_methods, logger: nil
|
16
|
+
self.logger = logger
|
15
17
|
@transport = transport
|
16
18
|
@options = options
|
17
19
|
@session_id = options['session id']
|
18
|
-
@authenticator = options.fetch( 'authentication_publickey_authenticator', Authenticator.new
|
20
|
+
@authenticator = options.fetch( 'authentication_publickey_authenticator', Authenticator.new{ false } )
|
19
21
|
@variables = variables
|
20
22
|
@authentication_methods = authentication_methods
|
21
23
|
end
|
@@ -23,18 +25,18 @@ module HrrRbSsh
|
|
23
25
|
def authenticate userauth_request_message
|
24
26
|
public_key_algorithm_name = userauth_request_message[:'public key algorithm name']
|
25
27
|
unless Algorithm.list_preferred.include?(public_key_algorithm_name)
|
26
|
-
|
28
|
+
log_info { "unsupported public key algorithm: #{public_key_algorithm_name}" }
|
27
29
|
return false
|
28
30
|
end
|
29
31
|
unless userauth_request_message[:'with signature']
|
30
|
-
|
32
|
+
log_info { "public key algorithm is ok, require signature" }
|
31
33
|
public_key_blob = userauth_request_message[:'public key blob']
|
32
34
|
userauth_pk_ok_message public_key_algorithm_name, public_key_blob
|
33
35
|
else
|
34
|
-
|
36
|
+
log_info { "verify signature" }
|
35
37
|
username = userauth_request_message[:'user name']
|
36
|
-
algorithm = Algorithm[public_key_algorithm_name].new
|
37
|
-
context = Context.new(username, algorithm, @session_id, userauth_request_message, @variables, @authentication_methods)
|
38
|
+
algorithm = Algorithm[public_key_algorithm_name].new logger: logger
|
39
|
+
context = Context.new(username, algorithm, @session_id, userauth_request_message, @variables, @authentication_methods, logger: logger)
|
38
40
|
@authenticator.authenticate context
|
39
41
|
end
|
40
42
|
end
|
@@ -45,7 +47,7 @@ module HrrRbSsh
|
|
45
47
|
:'public key algorithm name from the request' => public_key_algorithm_name,
|
46
48
|
:'public key blob from the request' => public_key_blob,
|
47
49
|
}
|
48
|
-
payload = Message::SSH_MSG_USERAUTH_PK_OK.encode message
|
50
|
+
payload = Message::SSH_MSG_USERAUTH_PK_OK.encode message, logger: logger
|
49
51
|
end
|
50
52
|
|
51
53
|
def request_authentication username, service_name
|
@@ -62,7 +64,7 @@ module HrrRbSsh
|
|
62
64
|
end
|
63
65
|
|
64
66
|
def send_request_without_signature username, service_name, public_key_algorithm_name, secret_key
|
65
|
-
algorithm = Algorithm[public_key_algorithm_name].new
|
67
|
+
algorithm = Algorithm[public_key_algorithm_name].new logger: logger
|
66
68
|
public_key_blob = algorithm.generate_public_key_blob(secret_key)
|
67
69
|
message = {
|
68
70
|
:'message number' => Message::SSH_MSG_USERAUTH_REQUEST::VALUE,
|
@@ -73,12 +75,12 @@ module HrrRbSsh
|
|
73
75
|
:'public key algorithm name' => public_key_algorithm_name,
|
74
76
|
:'public key blob' => public_key_blob,
|
75
77
|
}
|
76
|
-
payload = Message::SSH_MSG_USERAUTH_REQUEST.encode message
|
78
|
+
payload = Message::SSH_MSG_USERAUTH_REQUEST.encode message, logger: logger
|
77
79
|
@transport.send payload
|
78
80
|
end
|
79
81
|
|
80
82
|
def send_request_with_signature username, service_name, public_key_algorithm_name, secret_key
|
81
|
-
algorithm = Algorithm[public_key_algorithm_name].new
|
83
|
+
algorithm = Algorithm[public_key_algorithm_name].new logger: logger
|
82
84
|
public_key_blob = algorithm.generate_public_key_blob(secret_key)
|
83
85
|
signature = algorithm.generate_signature(@session_id, username, service_name, 'publickey', secret_key)
|
84
86
|
message = {
|
@@ -91,7 +93,7 @@ module HrrRbSsh
|
|
91
93
|
:'public key blob' => public_key_blob,
|
92
94
|
:'signature' => signature,
|
93
95
|
}
|
94
|
-
payload = Message::SSH_MSG_USERAUTH_REQUEST.encode message
|
96
|
+
payload = Message::SSH_MSG_USERAUTH_REQUEST.encode message, logger: logger
|
95
97
|
@transport.send payload
|
96
98
|
end
|
97
99
|
end
|
@@ -1,7 +1,7 @@
|
|
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/message'
|
6
6
|
require 'hrr_rb_ssh/error/closed_authentication'
|
7
7
|
require 'hrr_rb_ssh/authentication/constant'
|
@@ -10,15 +10,16 @@ require 'hrr_rb_ssh/authentication/method'
|
|
10
10
|
|
11
11
|
module HrrRbSsh
|
12
12
|
class Authentication
|
13
|
+
include Loggable
|
13
14
|
include Constant
|
14
15
|
|
15
|
-
def initialize transport, mode, options={}
|
16
|
+
def initialize transport, mode, options={}, logger: nil
|
17
|
+
self.logger = logger
|
18
|
+
|
16
19
|
@transport = transport
|
17
20
|
@mode = mode
|
18
21
|
@options = options
|
19
22
|
|
20
|
-
@logger = Logger.new self.class.name
|
21
|
-
|
22
23
|
@transport.register_acceptable_service SERVICE_NAME
|
23
24
|
|
24
25
|
@closed = nil
|
@@ -81,42 +82,42 @@ module HrrRbSsh
|
|
81
82
|
|
82
83
|
def respond_to_authentication
|
83
84
|
authentication_methods = (@options['authentication_preferred_authentication_methods'].dup rescue nil) || Method.list_preferred # rescue nil.dup for Ruby version < 2.4
|
84
|
-
|
85
|
+
log_info { "preferred authentication methods: #{authentication_methods}" }
|
85
86
|
loop do
|
86
87
|
payload = @transport.receive
|
87
88
|
case payload[0,1].unpack("C")[0]
|
88
89
|
when Message::SSH_MSG_USERAUTH_REQUEST::VALUE
|
89
|
-
userauth_request_message = Message::SSH_MSG_USERAUTH_REQUEST.decode payload
|
90
|
+
userauth_request_message = Message::SSH_MSG_USERAUTH_REQUEST.decode payload, logger: logger
|
90
91
|
method_name = userauth_request_message[:'method name']
|
91
|
-
|
92
|
-
method = Method[method_name].new(@transport, {'session id' => @transport.session_id}.merge(@options), @variables, authentication_methods)
|
92
|
+
log_info { "authentication method: #{method_name}" }
|
93
|
+
method = Method[method_name].new(@transport, {'session id' => @transport.session_id}.merge(@options), @variables, authentication_methods, logger: logger)
|
93
94
|
result = method.authenticate(userauth_request_message)
|
94
95
|
case result
|
95
96
|
when true, SUCCESS
|
96
|
-
|
97
|
+
log_info { "verified" }
|
97
98
|
send_userauth_success
|
98
99
|
@username = userauth_request_message[:'user name']
|
99
100
|
@closed = false
|
100
101
|
break
|
101
102
|
when PARTIAL_SUCCESS
|
102
|
-
|
103
|
+
log_info { "partially verified" }
|
103
104
|
authentication_methods.delete method_name
|
104
|
-
|
105
|
+
log_debug { "authentication methods that can continue: #{authentication_methods}" }
|
105
106
|
if authentication_methods.empty?
|
106
|
-
|
107
|
+
log_info { "verified" }
|
107
108
|
send_userauth_success
|
108
109
|
@username = userauth_request_message[:'user name']
|
109
110
|
@closed = false
|
110
111
|
break
|
111
112
|
else
|
112
|
-
|
113
|
+
log_info { "continue" }
|
113
114
|
send_userauth_failure authentication_methods, true
|
114
115
|
end
|
115
116
|
when String
|
116
|
-
|
117
|
+
log_info { "send method specific message to continue" }
|
117
118
|
send_method_specific_message result
|
118
119
|
else # when false, FAILURE
|
119
|
-
|
120
|
+
log_info { "verify failed" }
|
120
121
|
send_userauth_failure authentication_methods, false
|
121
122
|
end
|
122
123
|
else
|
@@ -128,33 +129,33 @@ module HrrRbSsh
|
|
128
129
|
|
129
130
|
def request_authentication
|
130
131
|
authentication_methods = (@options['authentication_preferred_authentication_methods'].dup rescue nil) || Method.list_preferred # rescue nil.dup for Ruby version < 2.4
|
131
|
-
|
132
|
+
log_info { "preferred authentication methods: #{authentication_methods}" }
|
132
133
|
next_method_name = "none"
|
133
|
-
|
134
|
+
log_info { "authentication request begins with none method" }
|
134
135
|
loop do
|
135
|
-
|
136
|
-
method = Method[next_method_name].new(@transport, {'session id' => @transport.session_id}.merge(@options), @variables, authentication_methods)
|
136
|
+
log_info { "authentication method: #{next_method_name}" }
|
137
|
+
method = Method[next_method_name].new(@transport, {'session id' => @transport.session_id}.merge(@options), @variables, authentication_methods, logger: logger)
|
137
138
|
payload = method.request_authentication @options['username'], "ssh-connection"
|
138
139
|
case payload[0,1].unpack("C")[0]
|
139
140
|
when Message::SSH_MSG_USERAUTH_SUCCESS::VALUE
|
140
|
-
|
141
|
+
log_info { "verified" }
|
141
142
|
@username = @options['username']
|
142
143
|
@closed = false
|
143
144
|
break
|
144
145
|
when Message::SSH_MSG_USERAUTH_FAILURE::VALUE
|
145
|
-
message = Message::SSH_MSG_USERAUTH_FAILURE.decode payload
|
146
|
+
message = Message::SSH_MSG_USERAUTH_FAILURE.decode payload, logger: logger
|
146
147
|
partial_success = message[:'partial success']
|
147
148
|
if partial_success
|
148
|
-
|
149
|
+
log_info { "partially verified" }
|
149
150
|
end
|
150
151
|
authentication_methods_that_can_continue = message[:'authentications that can continue']
|
151
|
-
|
152
|
+
log_debug { "authentication methods that can continue: #{authentication_methods_that_can_continue}" }
|
152
153
|
next_method_name = authentication_methods.find{ |local_m| authentication_methods_that_can_continue.find{ |remote_m| local_m == remote_m } }
|
153
154
|
if next_method_name
|
154
155
|
authentication_methods.delete next_method_name
|
155
|
-
|
156
|
+
log_info { "continue" }
|
156
157
|
else
|
157
|
-
|
158
|
+
log_info { "no more available authentication methods" }
|
158
159
|
@closed = true
|
159
160
|
raise "failed authentication"
|
160
161
|
end
|
@@ -168,7 +169,7 @@ module HrrRbSsh
|
|
168
169
|
:'authentications that can continue' => authentication_methods,
|
169
170
|
:'partial success' => partial_success,
|
170
171
|
}
|
171
|
-
payload = Message::SSH_MSG_USERAUTH_FAILURE.encode message
|
172
|
+
payload = Message::SSH_MSG_USERAUTH_FAILURE.encode message, logger: logger
|
172
173
|
@transport.send payload
|
173
174
|
end
|
174
175
|
|
@@ -176,7 +177,7 @@ module HrrRbSsh
|
|
176
177
|
message = {
|
177
178
|
:'message number' => Message::SSH_MSG_USERAUTH_SUCCESS::VALUE,
|
178
179
|
}
|
179
|
-
payload = Message::SSH_MSG_USERAUTH_SUCCESS.encode message
|
180
|
+
payload = Message::SSH_MSG_USERAUTH_SUCCESS.encode message, logger: logger
|
180
181
|
@transport.send payload
|
181
182
|
end
|
182
183
|
|
data/lib/hrr_rb_ssh/client.rb
CHANGED
@@ -3,7 +3,7 @@
|
|
3
3
|
|
4
4
|
require 'socket'
|
5
5
|
require 'stringio'
|
6
|
-
require 'hrr_rb_ssh/
|
6
|
+
require 'hrr_rb_ssh/loggable'
|
7
7
|
require 'hrr_rb_ssh/mode'
|
8
8
|
require 'hrr_rb_ssh/transport'
|
9
9
|
require 'hrr_rb_ssh/authentication'
|
@@ -11,6 +11,8 @@ require 'hrr_rb_ssh/connection'
|
|
11
11
|
|
12
12
|
module HrrRbSsh
|
13
13
|
class Client
|
14
|
+
include Loggable
|
15
|
+
|
14
16
|
def self.start target, options={}
|
15
17
|
client = self.new target, options
|
16
18
|
client.start
|
@@ -26,7 +28,6 @@ module HrrRbSsh
|
|
26
28
|
end
|
27
29
|
|
28
30
|
def initialize target, tmp_options={}
|
29
|
-
@logger = Logger.new self.class.name
|
30
31
|
@closed = true
|
31
32
|
options = initialize_options tmp_options
|
32
33
|
io = case target
|
@@ -38,24 +39,25 @@ module HrrRbSsh
|
|
38
39
|
port = 22
|
39
40
|
io = TCPSocket.new target, port
|
40
41
|
end
|
41
|
-
transport = HrrRbSsh::Transport.new io, HrrRbSsh::Mode::CLIENT, options
|
42
|
-
authentication = HrrRbSsh::Authentication.new transport, HrrRbSsh::Mode::CLIENT, options
|
43
|
-
@connection = HrrRbSsh::Connection.new authentication, HrrRbSsh::Mode::CLIENT, options
|
42
|
+
transport = HrrRbSsh::Transport.new io, HrrRbSsh::Mode::CLIENT, options, logger: logger
|
43
|
+
authentication = HrrRbSsh::Authentication.new transport, HrrRbSsh::Mode::CLIENT, options, logger: logger
|
44
|
+
@connection = HrrRbSsh::Connection.new authentication, HrrRbSsh::Mode::CLIENT, options, logger: logger
|
44
45
|
end
|
45
46
|
|
46
47
|
def initialize_options tmp_options
|
47
48
|
tmp_options = Hash[tmp_options.map{|k, v| [k.to_s, v]}]
|
49
|
+
self.logger = tmp_options['logger']
|
48
50
|
options = {}
|
49
51
|
options['username'] = tmp_options['username']
|
50
52
|
options['authentication_preferred_authentication_methods'] = tmp_options['authentication_preferred_authentication_methods']
|
51
|
-
options['client_authentication_password']
|
52
|
-
options['client_authentication_publickey']
|
53
|
-
options['client_authentication_keyboard_interactive']
|
54
|
-
options['transport_preferred_encryption_algorithms']
|
55
|
-
options['transport_preferred_server_host_key_algorithms']
|
56
|
-
options['transport_preferred_kex_algorithms']
|
57
|
-
options['transport_preferred_mac_algorithms']
|
58
|
-
options['transport_preferred_compression_algorithms']
|
53
|
+
options['client_authentication_password'] = tmp_options['password']
|
54
|
+
options['client_authentication_publickey'] = tmp_options['publickey']
|
55
|
+
options['client_authentication_keyboard_interactive'] = tmp_options['keyboard_interactive']
|
56
|
+
options['transport_preferred_encryption_algorithms'] = tmp_options['transport_preferred_encryption_algorithms']
|
57
|
+
options['transport_preferred_server_host_key_algorithms'] = tmp_options['transport_preferred_server_host_key_algorithms']
|
58
|
+
options['transport_preferred_kex_algorithms'] = tmp_options['transport_preferred_kex_algorithms']
|
59
|
+
options['transport_preferred_mac_algorithms'] = tmp_options['transport_preferred_mac_algorithms']
|
60
|
+
options['transport_preferred_compression_algorithms'] = tmp_options['transport_preferred_compression_algorithms']
|
59
61
|
options
|
60
62
|
end
|
61
63
|
|
@@ -73,20 +75,20 @@ module HrrRbSsh
|
|
73
75
|
end
|
74
76
|
|
75
77
|
def close
|
76
|
-
|
78
|
+
log_debug { "closing client" }
|
77
79
|
@closed = true
|
78
80
|
@connection.close
|
79
|
-
|
81
|
+
log_debug { "client closed" }
|
80
82
|
end
|
81
83
|
|
82
84
|
def exec! command, pty: false, env: {}
|
83
|
-
|
85
|
+
log_debug { "start exec!: #{command}" }
|
84
86
|
out_buf = StringIO.new
|
85
87
|
err_buf = StringIO.new
|
86
88
|
begin
|
87
|
-
|
89
|
+
log_info { "Opning channel" }
|
88
90
|
channel = @connection.request_channel_open "session"
|
89
|
-
|
91
|
+
log_info { "Channel opened" }
|
90
92
|
if pty
|
91
93
|
channel.send_channel_request_pty_req 'xterm', 80, 24, 580, 336, ''
|
92
94
|
end
|
@@ -116,34 +118,34 @@ module HrrRbSsh
|
|
116
118
|
begin
|
117
119
|
t.join
|
118
120
|
rescue => e
|
119
|
-
|
121
|
+
log_warn { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
120
122
|
end
|
121
123
|
}
|
122
124
|
rescue => e
|
123
|
-
|
124
|
-
|
125
|
+
log_error { "Failed opening channel" }
|
126
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
125
127
|
raise "Error in exec!"
|
126
128
|
ensure
|
127
129
|
if channel
|
128
|
-
|
130
|
+
log_info { "closing channel IOs" }
|
129
131
|
channel.io.each{ |io| io.close rescue nil }
|
130
|
-
|
131
|
-
|
132
|
-
|
132
|
+
log_info { "channel IOs closed" }
|
133
|
+
log_info { "closing channel" }
|
134
|
+
log_info { "wait until threads closed in channel" }
|
133
135
|
channel.wait_until_closed
|
134
136
|
channel.close
|
135
|
-
|
137
|
+
log_info { "channel closed" }
|
136
138
|
end
|
137
139
|
end
|
138
140
|
[out_buf.string, err_buf.string]
|
139
141
|
end
|
140
142
|
|
141
143
|
def exec command, pty: false, env: {}
|
142
|
-
|
144
|
+
log_debug { "start exec: #{command}" }
|
143
145
|
begin
|
144
|
-
|
146
|
+
log_info { "Opning channel" }
|
145
147
|
channel = @connection.request_channel_open "session"
|
146
|
-
|
148
|
+
log_info { "Channel opened" }
|
147
149
|
if pty
|
148
150
|
channel.send_channel_request_pty_req 'xterm', 80, 24, 580, 336, ''
|
149
151
|
end
|
@@ -153,30 +155,30 @@ module HrrRbSsh
|
|
153
155
|
channel.send_channel_request_exec command
|
154
156
|
yield channel.io
|
155
157
|
rescue => e
|
156
|
-
|
157
|
-
|
158
|
+
log_error { "Failed opening channel" }
|
159
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
158
160
|
raise "Error in shell"
|
159
161
|
ensure
|
160
162
|
if channel
|
161
|
-
|
163
|
+
log_info { "closing channel IOs" }
|
162
164
|
channel.io.each{ |io| io.close rescue nil }
|
163
|
-
|
164
|
-
|
165
|
-
|
165
|
+
log_info { "channel IOs closed" }
|
166
|
+
log_info { "closing channel" }
|
167
|
+
log_info { "wait until threads closed in channel" }
|
166
168
|
channel.wait_until_closed
|
167
169
|
channel.close
|
168
|
-
|
170
|
+
log_info { "channel closed" }
|
169
171
|
end
|
170
172
|
end
|
171
173
|
channel_exit_status = channel.exit_status rescue nil
|
172
174
|
end
|
173
175
|
|
174
176
|
def shell env: {}
|
175
|
-
|
177
|
+
log_debug { "start shell" }
|
176
178
|
begin
|
177
|
-
|
179
|
+
log_info { "Opning channel" }
|
178
180
|
channel = @connection.request_channel_open "session"
|
179
|
-
|
181
|
+
log_info { "Channel opened" }
|
180
182
|
channel.send_channel_request_pty_req 'xterm', 80, 24, 580, 336, ''
|
181
183
|
env.each{ |variable_name, variable_value|
|
182
184
|
channel.send_channel_request_env variable_name, variable_value
|
@@ -184,46 +186,46 @@ module HrrRbSsh
|
|
184
186
|
channel.send_channel_request_shell
|
185
187
|
yield channel.io
|
186
188
|
rescue => e
|
187
|
-
|
188
|
-
|
189
|
+
log_error { "Failed opening channel" }
|
190
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
189
191
|
raise "Error in shell"
|
190
192
|
ensure
|
191
193
|
if channel
|
192
|
-
|
194
|
+
log_info { "closing channel IOs" }
|
193
195
|
channel.io.each{ |io| io.close rescue nil }
|
194
|
-
|
195
|
-
|
196
|
-
|
196
|
+
log_info { "channel IOs closed" }
|
197
|
+
log_info { "closing channel" }
|
198
|
+
log_info { "wait until threads closed in channel" }
|
197
199
|
channel.wait_until_closed
|
198
200
|
channel.close
|
199
|
-
|
201
|
+
log_info { "channel closed" }
|
200
202
|
end
|
201
203
|
end
|
202
204
|
channel_exit_status = channel.exit_status rescue nil
|
203
205
|
end
|
204
206
|
|
205
207
|
def subsystem name
|
206
|
-
|
208
|
+
log_debug { "start subsystem" }
|
207
209
|
begin
|
208
|
-
|
210
|
+
log_info { "Opning channel" }
|
209
211
|
channel = @connection.request_channel_open "session"
|
210
|
-
|
212
|
+
log_info { "Channel opened" }
|
211
213
|
channel.send_channel_request_subsystem name
|
212
214
|
yield channel.io
|
213
215
|
rescue => e
|
214
|
-
|
215
|
-
|
216
|
+
log_error { "Failed opening channel" }
|
217
|
+
log_error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
|
216
218
|
raise "Error in subsystem"
|
217
219
|
ensure
|
218
220
|
if channel
|
219
|
-
|
221
|
+
log_info { "closing channel IOs" }
|
220
222
|
channel.io.each{ |io| io.close rescue nil }
|
221
|
-
|
222
|
-
|
223
|
-
|
223
|
+
log_info { "channel IOs closed" }
|
224
|
+
log_info { "closing channel" }
|
225
|
+
log_info { "wait until threads closed in channel" }
|
224
226
|
channel.wait_until_closed
|
225
227
|
channel.close
|
226
|
-
|
228
|
+
log_info { "channel closed" }
|
227
229
|
end
|
228
230
|
end
|
229
231
|
channel_exit_status = channel.exit_status rescue nil
|