hrr_rb_ssh 0.2.0 → 0.2.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +32 -1
- data/demo/server.rb +17 -3
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/context.rb +36 -0
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/info_request.rb +45 -0
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive/info_response.rb +29 -0
- data/lib/hrr_rb_ssh/authentication/method/keyboard_interactive.rb +32 -0
- data/lib/hrr_rb_ssh/authentication/method/none.rb +1 -1
- data/lib/hrr_rb_ssh/authentication/method/password.rb +1 -1
- data/lib/hrr_rb_ssh/authentication/method/publickey.rb +1 -1
- data/lib/hrr_rb_ssh/authentication/method.rb +1 -0
- data/lib/hrr_rb_ssh/authentication.rb +1 -1
- data/lib/hrr_rb_ssh/message/050_ssh_msg_userauth_request.rb +10 -2
- data/lib/hrr_rb_ssh/message/060_ssh_msg_userauth_info_request.rb +43 -0
- data/lib/hrr_rb_ssh/message/061_ssh_msg_userauth_info_response.rb +39 -0
- data/lib/hrr_rb_ssh/message.rb +2 -0
- data/lib/hrr_rb_ssh/version.rb +1 -1
- metadata +8 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 61d3c0613da093138597cc6a8e7ba24168e7374b0fffd31d26d58efabc234224
|
4
|
+
data.tar.gz: 60c45a6fb8eedc3cdadfa42bb79f686a42bbe955623637199e08bce44272d805
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: bde652be2f850130028aecca6f6dc401e334198aa73f7fa28dcd88fa059a79378bf2e0b1d075c134fc49403aad491b6d49d4d4cbc53098bd12459f27829293b1
|
7
|
+
data.tar.gz: acf3496654c007e03ef390cfd1057b99ba85d0f82c965eea31647ea8bd919b4362783039405922bcb3243ab2ff0fc269e53a4faf05ebde8a0039210ebecffd15
|
data/README.md
CHANGED
@@ -19,6 +19,7 @@ hrr_rb_ssh is a pure Ruby SSH 2.0 server implementation.
|
|
19
19
|
- [Defining authentications](#defining-authentications)
|
20
20
|
- [Password authentication](#password-authentication)
|
21
21
|
- [Publickey authentication](#publickey-authentication)
|
22
|
+
- [Keyboard-interactive authentication](#keyboard-interactive-authentication)
|
22
23
|
- [None authentication (NOT recomended)](#none-authentication-not-recomended)
|
23
24
|
- [Handling session channel requests](#handling-session-channel-requests)
|
24
25
|
- [Reference request handlers](#reference-request-handlers)
|
@@ -180,9 +181,38 @@ The `context` variable in public key authentication context provides the `#verif
|
|
180
181
|
|
181
182
|
And public keys that is in OpenSSH public key format is now available. To use OpenSSH public keys, it is easy to use $USER_HOME/.ssh/authorized_keys file.
|
182
183
|
|
184
|
+
##### Keyboard-interactive authentication
|
185
|
+
|
186
|
+
The third one is keyboard-interactive authentication. This is also known as challenge-response authentication.
|
187
|
+
|
188
|
+
To define a keyboard-interactive authentication, the `HrrRbSsh::Authentication::Authenticator.new { |context| ... }` block is used as well. When the block returns `true`, then the authentication succeeded as well. However, `context` variable behaves differently.
|
189
|
+
|
190
|
+
```ruby
|
191
|
+
auth_keyboard_interactive = HrrRbSsh::Authentication::Authenticator.new { |context|
|
192
|
+
user_name = 'user1'
|
193
|
+
req_name = 'demo keyboard interactive authentication'
|
194
|
+
req_instruction = 'demo instruction'
|
195
|
+
req_language_tag = ''
|
196
|
+
req_prompts = [
|
197
|
+
#[prompt[n], echo[n]]
|
198
|
+
['Password1: ', false],
|
199
|
+
['Password2: ', true],
|
200
|
+
]
|
201
|
+
info_response = context.info_request req_name, req_instruction, req_language_tag, req_prompts
|
202
|
+
context.username == user_name && info_response.responses == ['password1', 'password2']
|
203
|
+
}
|
204
|
+
options['authentication_keyboard_interactive_authenticator'] = auth_keyboard_interactive
|
205
|
+
```
|
206
|
+
|
207
|
+
The `context` variable in keyboard-interactive authentication context does NOT provides the `#verify` method. Instead, `#info_request` method is available. Since keyboard-interactive authentication has multiple times interactions between server and client, the values in responses needs to be verified respectively.
|
208
|
+
|
209
|
+
The `#info_request` method takes four arguments: name, instruction, language tag, and prompts. The name, instruction, and language tag can be empty string. The prompts needs to have at least one charactor for prompt message, and `true` or `false` value to specify whether echo back is enabled or not.
|
210
|
+
|
211
|
+
The responses are listed in the same order as request prompts.
|
212
|
+
|
183
213
|
##### None authentication (NOT recomended)
|
184
214
|
|
185
|
-
The
|
215
|
+
The last one is none authentication. None authentication is usually NOT used.
|
186
216
|
|
187
217
|
To define a none authentication, the `HrrRbSsh::Authentication::Authenticator.new { |context| ... }` block is used as well. When the block returns `true`, then the authentication succeeded as well. However, `context` variable behaves differently.
|
188
218
|
|
@@ -316,6 +346,7 @@ The following features are currently supported.
|
|
316
346
|
- ecdsa-sha2-nistp256
|
317
347
|
- ecdsa-sha2-nistp384
|
318
348
|
- ecdsa-sha2-nistp521
|
349
|
+
- Keyboard interactive (generic interactive / challenge response) authentication
|
319
350
|
|
320
351
|
### Transport layer
|
321
352
|
|
data/demo/server.rb
CHANGED
@@ -46,6 +46,19 @@ def start_service io, logger=nil
|
|
46
46
|
context.verify user, pass
|
47
47
|
}
|
48
48
|
}
|
49
|
+
auth_keyboard_interactive = HrrRbSsh::Authentication::Authenticator.new { |context|
|
50
|
+
user_name = 'user1'
|
51
|
+
req_name = 'demo keyboard interactive authentication'
|
52
|
+
req_instruction = 'demo instruction'
|
53
|
+
req_language_tag = ''
|
54
|
+
req_prompts = [
|
55
|
+
#[prompt[n], echo[n]]
|
56
|
+
['Password1: ', false],
|
57
|
+
['Password2: ', true],
|
58
|
+
]
|
59
|
+
info_response = context.info_request req_name, req_instruction, req_language_tag, req_prompts
|
60
|
+
context.username == user_name && info_response.responses == ['password1', 'password2']
|
61
|
+
}
|
49
62
|
|
50
63
|
|
51
64
|
options = {}
|
@@ -65,9 +78,10 @@ OfeosJOO9twerD7pPhmXREkygblPsEXaVA==
|
|
65
78
|
-----END EC PRIVATE KEY-----
|
66
79
|
EOB
|
67
80
|
|
68
|
-
options['authentication_none_authenticator']
|
69
|
-
options['authentication_publickey_authenticator']
|
70
|
-
options['authentication_password_authenticator']
|
81
|
+
options['authentication_none_authenticator'] = auth_none
|
82
|
+
options['authentication_publickey_authenticator'] = auth_publickey
|
83
|
+
options['authentication_password_authenticator'] = auth_password
|
84
|
+
options['authentication_keyboard_interactive_authenticator'] = auth_keyboard_interactive
|
71
85
|
|
72
86
|
options['connection_channel_request_pty_req'] = HrrRbSsh::Connection::RequestHandler::ReferencePtyReqRequestHandler.new
|
73
87
|
options['connection_channel_request_env'] = HrrRbSsh::Connection::RequestHandler::ReferenceEnvRequestHandler.new
|
@@ -0,0 +1,36 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_ssh/logger'
|
5
|
+
require 'hrr_rb_ssh/authentication/method/keyboard_interactive/info_request'
|
6
|
+
require 'hrr_rb_ssh/authentication/method/keyboard_interactive/info_response'
|
7
|
+
|
8
|
+
module HrrRbSsh
|
9
|
+
class Authentication
|
10
|
+
class Method
|
11
|
+
class KeyboardInteractive
|
12
|
+
class Context
|
13
|
+
attr_reader \
|
14
|
+
:username,
|
15
|
+
:submethods,
|
16
|
+
:info_response
|
17
|
+
|
18
|
+
def initialize transport, username, submethods
|
19
|
+
@transport = transport
|
20
|
+
@username = username
|
21
|
+
@submethods = submethods
|
22
|
+
|
23
|
+
@logger = Logger.new self.class.name
|
24
|
+
end
|
25
|
+
|
26
|
+
def info_request name, instruction, language_tag, prompts
|
27
|
+
@logger.info { "send userauth info request" }
|
28
|
+
@transport.send InfoRequest.new(name, instruction, language_tag, prompts).to_payload
|
29
|
+
@logger.info { "receive userauth info response" }
|
30
|
+
@info_response = InfoResponse.new @transport.receive
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
35
|
+
end
|
36
|
+
end
|
@@ -0,0 +1,45 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_ssh/logger'
|
5
|
+
require 'hrr_rb_ssh/message'
|
6
|
+
|
7
|
+
module HrrRbSsh
|
8
|
+
class Authentication
|
9
|
+
class Method
|
10
|
+
class KeyboardInteractive
|
11
|
+
class InfoRequest
|
12
|
+
def initialize name, instruction, language_tag, prompts
|
13
|
+
@name = name
|
14
|
+
@instruction = instruction
|
15
|
+
@language_tag = language_tag
|
16
|
+
@prompts = prompts
|
17
|
+
|
18
|
+
@logger = Logger.new self.class.name
|
19
|
+
end
|
20
|
+
|
21
|
+
def to_message
|
22
|
+
message = {
|
23
|
+
:'message number' => Message::SSH_MSG_USERAUTH_INFO_REQUEST::VALUE,
|
24
|
+
:'name' => @name,
|
25
|
+
:'instruction' => @instruction,
|
26
|
+
:'language tag' => @language_tag,
|
27
|
+
:'num-prompts' => @prompts.size,
|
28
|
+
}
|
29
|
+
message_prompts = @prompts.map.with_index{ |(prompt, echo), i|
|
30
|
+
[
|
31
|
+
[:"prompt[#{i+1}]", prompt],
|
32
|
+
[:"echo[#{i+1}]", echo],
|
33
|
+
].to_h
|
34
|
+
}.inject(Hash.new){ |a, b| a.merge(b) }
|
35
|
+
message.merge(message_prompts)
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_payload
|
39
|
+
Message::SSH_MSG_USERAUTH_INFO_REQUEST.encode self.to_message
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_ssh/message'
|
5
|
+
|
6
|
+
module HrrRbSsh
|
7
|
+
class Authentication
|
8
|
+
class Method
|
9
|
+
class KeyboardInteractive
|
10
|
+
class InfoResponse
|
11
|
+
attr_reader \
|
12
|
+
:num_responses,
|
13
|
+
:responses
|
14
|
+
|
15
|
+
def initialize payload
|
16
|
+
case payload[0,1].unpack("C")[0]
|
17
|
+
when Message::SSH_MSG_USERAUTH_INFO_RESPONSE::VALUE
|
18
|
+
message = Message::SSH_MSG_USERAUTH_INFO_RESPONSE.decode payload
|
19
|
+
@num_responses = message[:'num-responses']
|
20
|
+
@responses = Array.new(message[:'num-responses']){ |i| message[:"response[#{i+1}]"] }
|
21
|
+
else
|
22
|
+
raise "Expected SSH_MSG_USERAUTH_INFO_RESPONSE, but got message number #{payload[0,1].unpack("C")[0]}"
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_ssh/logger'
|
5
|
+
|
6
|
+
module HrrRbSsh
|
7
|
+
class Authentication
|
8
|
+
class Method
|
9
|
+
class KeyboardInteractive < Method
|
10
|
+
NAME = 'keyboard-interactive'
|
11
|
+
PREFERENCE = 30
|
12
|
+
|
13
|
+
def initialize transport, options
|
14
|
+
@logger = Logger.new(self.class.name)
|
15
|
+
@transport = transport
|
16
|
+
@authenticator = options.fetch( 'authentication_keyboard_interactive_authenticator', Authenticator.new { false } )
|
17
|
+
end
|
18
|
+
|
19
|
+
def authenticate userauth_request_message
|
20
|
+
@logger.info { "authenticate" }
|
21
|
+
@logger.debug { "userauth request: " + userauth_request_message.inspect }
|
22
|
+
username = userauth_request_message[:'user name']
|
23
|
+
submethods = userauth_request_message[:'submethods']
|
24
|
+
context = Context.new(@transport, username, submethods)
|
25
|
+
@authenticator.authenticate context
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
|
32
|
+
require 'hrr_rb_ssh/authentication/method/keyboard_interactive/context'
|
@@ -10,7 +10,7 @@ module HrrRbSsh
|
|
10
10
|
NAME = 'none'
|
11
11
|
PREFERENCE = 0
|
12
12
|
|
13
|
-
def initialize options
|
13
|
+
def initialize transport, options
|
14
14
|
@logger = Logger.new(self.class.name)
|
15
15
|
@authenticator = options.fetch( 'authentication_none_authenticator', Authenticator.new { false } )
|
16
16
|
end
|
@@ -10,7 +10,7 @@ module HrrRbSsh
|
|
10
10
|
NAME = 'password'
|
11
11
|
PREFERENCE = 10
|
12
12
|
|
13
|
-
def initialize options
|
13
|
+
def initialize transport, options
|
14
14
|
@logger = Logger.new(self.class.name)
|
15
15
|
@authenticator = options.fetch( 'authentication_password_authenticator', Authenticator.new { false } )
|
16
16
|
end
|
@@ -10,7 +10,7 @@ module HrrRbSsh
|
|
10
10
|
NAME = 'publickey'
|
11
11
|
PREFERENCE = 20
|
12
12
|
|
13
|
-
def initialize options
|
13
|
+
def initialize transport, options
|
14
14
|
@logger = Logger.new(self.class.name)
|
15
15
|
@session_id = options['session id']
|
16
16
|
@authenticator = options.fetch( 'authentication_publickey_authenticator', Authenticator.new { false } )
|
@@ -69,7 +69,7 @@ module HrrRbSsh
|
|
69
69
|
when Message::SSH_MSG_USERAUTH_REQUEST::VALUE
|
70
70
|
userauth_request_message = Message::SSH_MSG_USERAUTH_REQUEST.decode payload
|
71
71
|
method_name = userauth_request_message[:'method name']
|
72
|
-
method = Method[method_name].new({'session id' => @transport.session_id}.merge(@options))
|
72
|
+
method = Method[method_name].new(@transport, {'session id' => @transport.session_id}.merge(@options))
|
73
73
|
result = method.authenticate(userauth_request_message)
|
74
74
|
case result
|
75
75
|
when TrueClass
|
@@ -43,11 +43,19 @@ module HrrRbSsh
|
|
43
43
|
[DataType::String, :'plaintext password'],
|
44
44
|
]
|
45
45
|
|
46
|
+
KEYBOARD_INTERACTIVE_DEFINITION = [
|
47
|
+
#[DataType, Field Name]
|
48
|
+
#[DataType::String, :'method name' : "keyboard-interactive"],
|
49
|
+
[DataType::String, :'language tag'],
|
50
|
+
[DataType::String, :'submethods'],
|
51
|
+
]
|
52
|
+
|
46
53
|
CONDITIONAL_DEFINITION = {
|
47
54
|
# Field Name => {Field Value => Conditional Definition}
|
48
55
|
:'method name' => {
|
49
|
-
"publickey"
|
50
|
-
"password"
|
56
|
+
"publickey" => PUBLICKEY_DEFINITION,
|
57
|
+
"password" => PASSWORD_DEFINITION,
|
58
|
+
"keyboard-interactive" => KEYBOARD_INTERACTIVE_DEFINITION,
|
51
59
|
},
|
52
60
|
:'with signature' => {
|
53
61
|
true => PUBLICKEY_SIGNATURE_DEFINITION,
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_ssh/data_type'
|
5
|
+
require 'hrr_rb_ssh/codable'
|
6
|
+
|
7
|
+
module HrrRbSsh
|
8
|
+
module Message
|
9
|
+
module SSH_MSG_USERAUTH_INFO_REQUEST
|
10
|
+
class << self
|
11
|
+
include Codable
|
12
|
+
end
|
13
|
+
|
14
|
+
ID = self.name.split('::').last
|
15
|
+
VALUE = 60
|
16
|
+
|
17
|
+
DEFINITION = [
|
18
|
+
#[DataType, Field Name]
|
19
|
+
[DataType::Byte, :'message number'],
|
20
|
+
[DataType::String, :'name'],
|
21
|
+
[DataType::String, :'instruction'],
|
22
|
+
[DataType::String, :'language tag'],
|
23
|
+
[DataType::Uint32, :'num-prompts'],
|
24
|
+
]
|
25
|
+
|
26
|
+
PER_NUM_PROMPTS_DEFINITION = Hash.new{ |hash, key|
|
27
|
+
Array.new(key){ |i|
|
28
|
+
[
|
29
|
+
#[DataType, Field Name]
|
30
|
+
#[DataType::String, :'num-prompts' : "> 0"],
|
31
|
+
[DataType::String, :"prompt[#{i+1}]"],
|
32
|
+
[DataType::Boolean, :"echo[#{i+1}]"],
|
33
|
+
]
|
34
|
+
}.inject(:+)
|
35
|
+
}
|
36
|
+
|
37
|
+
CONDITIONAL_DEFINITION = {
|
38
|
+
# Field Name => {Field Value => Conditional Definition}
|
39
|
+
:'num-prompts' => PER_NUM_PROMPTS_DEFINITION,
|
40
|
+
}
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
# vim: et ts=2 sw=2
|
3
|
+
|
4
|
+
require 'hrr_rb_ssh/data_type'
|
5
|
+
require 'hrr_rb_ssh/codable'
|
6
|
+
|
7
|
+
module HrrRbSsh
|
8
|
+
module Message
|
9
|
+
module SSH_MSG_USERAUTH_INFO_RESPONSE
|
10
|
+
class << self
|
11
|
+
include Codable
|
12
|
+
end
|
13
|
+
|
14
|
+
ID = self.name.split('::').last
|
15
|
+
VALUE = 61
|
16
|
+
|
17
|
+
DEFINITION = [
|
18
|
+
#[DataType, Field Name]
|
19
|
+
[DataType::Byte, :'message number'],
|
20
|
+
[DataType::Uint32, :'num-responses'],
|
21
|
+
]
|
22
|
+
|
23
|
+
PER_NUM_RESPONSES_DEFINITION = Hash.new{ |hash, key|
|
24
|
+
Array.new(key){ |i|
|
25
|
+
[
|
26
|
+
#[DataType, Field Name]
|
27
|
+
#[DataType::String, :'num-responses' : "> 0"],
|
28
|
+
[DataType::String, :"response[#{i+1}]"],
|
29
|
+
]
|
30
|
+
}.inject(:+)
|
31
|
+
}
|
32
|
+
|
33
|
+
CONDITIONAL_DEFINITION = {
|
34
|
+
# Field Name => {Field Value => Conditional Definition}
|
35
|
+
:'num-responses' => PER_NUM_RESPONSES_DEFINITION,
|
36
|
+
}
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
data/lib/hrr_rb_ssh/message.rb
CHANGED
@@ -22,6 +22,8 @@ require 'hrr_rb_ssh/message/050_ssh_msg_userauth_request'
|
|
22
22
|
require 'hrr_rb_ssh/message/051_ssh_msg_userauth_failure'
|
23
23
|
require 'hrr_rb_ssh/message/052_ssh_msg_userauth_success'
|
24
24
|
require 'hrr_rb_ssh/message/060_ssh_msg_userauth_pk_ok'
|
25
|
+
require 'hrr_rb_ssh/message/060_ssh_msg_userauth_info_request'
|
26
|
+
require 'hrr_rb_ssh/message/061_ssh_msg_userauth_info_response'
|
25
27
|
require 'hrr_rb_ssh/message/080_ssh_msg_global_request.rb'
|
26
28
|
require 'hrr_rb_ssh/message/081_ssh_msg_request_success.rb'
|
27
29
|
require 'hrr_rb_ssh/message/082_ssh_msg_request_failure.rb'
|
data/lib/hrr_rb_ssh/version.rb
CHANGED
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: hrr_rb_ssh
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.2.
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- hirura
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-05-
|
11
|
+
date: 2018-05-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|
@@ -104,6 +104,10 @@ files:
|
|
104
104
|
- lib/hrr_rb_ssh/authentication.rb
|
105
105
|
- lib/hrr_rb_ssh/authentication/authenticator.rb
|
106
106
|
- lib/hrr_rb_ssh/authentication/method.rb
|
107
|
+
- lib/hrr_rb_ssh/authentication/method/keyboard_interactive.rb
|
108
|
+
- lib/hrr_rb_ssh/authentication/method/keyboard_interactive/context.rb
|
109
|
+
- lib/hrr_rb_ssh/authentication/method/keyboard_interactive/info_request.rb
|
110
|
+
- lib/hrr_rb_ssh/authentication/method/keyboard_interactive/info_response.rb
|
107
111
|
- lib/hrr_rb_ssh/authentication/method/none.rb
|
108
112
|
- lib/hrr_rb_ssh/authentication/method/none/context.rb
|
109
113
|
- lib/hrr_rb_ssh/authentication/method/password.rb
|
@@ -183,7 +187,9 @@ files:
|
|
183
187
|
- lib/hrr_rb_ssh/message/050_ssh_msg_userauth_request.rb
|
184
188
|
- lib/hrr_rb_ssh/message/051_ssh_msg_userauth_failure.rb
|
185
189
|
- lib/hrr_rb_ssh/message/052_ssh_msg_userauth_success.rb
|
190
|
+
- lib/hrr_rb_ssh/message/060_ssh_msg_userauth_info_request.rb
|
186
191
|
- lib/hrr_rb_ssh/message/060_ssh_msg_userauth_pk_ok.rb
|
192
|
+
- lib/hrr_rb_ssh/message/061_ssh_msg_userauth_info_response.rb
|
187
193
|
- lib/hrr_rb_ssh/message/080_ssh_msg_global_request.rb
|
188
194
|
- lib/hrr_rb_ssh/message/081_ssh_msg_request_success.rb
|
189
195
|
- lib/hrr_rb_ssh/message/082_ssh_msg_request_failure.rb
|