hrr_rb_ssh 0.2.0 → 0.2.1
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 +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
|