hrr_rb_ssh 0.2.1 → 0.2.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.
Files changed (31) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +6 -2
  3. data/demo/server.rb +1 -1
  4. data/hrr_rb_ssh.gemspec +1 -0
  5. data/lib/hrr_rb_ssh.rb +6 -4
  6. data/lib/hrr_rb_ssh/algorithm/publickey.rb +4 -14
  7. data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519.rb +61 -0
  8. data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/openssh_private_key.rb +29 -0
  9. data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/openssh_private_key_content.rb +26 -0
  10. data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/pkey.rb +158 -0
  11. data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/public_key_blob.rb +23 -0
  12. data/lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/signature.rb +23 -0
  13. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm.rb +1 -0
  14. data/lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_ed25519.rb +21 -0
  15. data/lib/hrr_rb_ssh/codable.rb +2 -1
  16. data/lib/hrr_rb_ssh/connection/channel/channel_type.rb +3 -14
  17. data/lib/hrr_rb_ssh/connection/channel/channel_type/session/request_type.rb +3 -14
  18. data/lib/hrr_rb_ssh/connection/request_handler/reference_pty_req_request_handler.rb +5 -11
  19. data/lib/hrr_rb_ssh/data_type.rb +10 -144
  20. data/lib/hrr_rb_ssh/data_type/boolean.rb +37 -0
  21. data/lib/hrr_rb_ssh/data_type/byte.rb +31 -0
  22. data/lib/hrr_rb_ssh/data_type/mpint.rb +56 -0
  23. data/lib/hrr_rb_ssh/data_type/name_list.rb +38 -0
  24. data/lib/hrr_rb_ssh/data_type/string.rb +34 -0
  25. data/lib/hrr_rb_ssh/data_type/uint32.rb +31 -0
  26. data/lib/hrr_rb_ssh/data_type/uint64.rb +31 -0
  27. data/lib/hrr_rb_ssh/subclass_without_preference_listable.rb +25 -0
  28. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm.rb +1 -0
  29. data/lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_ed25519.rb +20 -0
  30. data/lib/hrr_rb_ssh/version.rb +1 -1
  31. metadata +32 -2
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 61d3c0613da093138597cc6a8e7ba24168e7374b0fffd31d26d58efabc234224
4
- data.tar.gz: 60c45a6fb8eedc3cdadfa42bb79f686a42bbe955623637199e08bce44272d805
3
+ metadata.gz: 0c8f4e84817663132562929cf774d32295eb62df8820d7c08aa621672ae6a002
4
+ data.tar.gz: 783f325e4514b69f5bc2c9936ad012d07d263e1c93aa813393afb773ee72c4c9
5
5
  SHA512:
6
- metadata.gz: bde652be2f850130028aecca6f6dc401e334198aa73f7fa28dcd88fa059a79378bf2e0b1d075c134fc49403aad491b6d49d4d4cbc53098bd12459f27829293b1
7
- data.tar.gz: acf3496654c007e03ef390cfd1057b99ba85d0f82c965eea31647ea8bd919b4362783039405922bcb3243ab2ff0fc269e53a4faf05ebde8a0039210ebecffd15
6
+ metadata.gz: b08a544e2085ea9399564ae5a0ce654ba81adbcf5eaa28b17dbea438d29dadeafb89a450d7cf3151115cce29d1e32a3dada2c14e96efe1f47516fad75076c551
7
+ data.tar.gz: 204b40938e402920729b2e96261faf2be13851b9ee4e2b0de996db9bba17363b169bfb107bc951917008c9950fc314a53807c1ea639d8512378ecc9711540e21
data/README.md CHANGED
@@ -7,6 +7,8 @@
7
7
 
8
8
  hrr_rb_ssh is a pure Ruby SSH 2.0 server implementation.
9
9
 
10
+ With hrr_rb_ssh, it is possible to write an SSH server easily, and also possible to write an original server side application on secure connection provided by SSH protocol.
11
+
10
12
  ## Table of Contents
11
13
 
12
14
  - [Installation](#installation)
@@ -299,9 +301,9 @@ p HrrRbSsh::Transport::EncryptionAlgorithm.list_preferred
299
301
  # => ["aes128-ctr", "aes192-ctr", "aes256-ctr", "aes128-cbc", "3des-cbc", "blowfish-cbc", "cast128-cbc", "aes192-cbc", "aes256-cbc", "arcfour"]
300
302
 
301
303
  p HrrRbSsh::Transport::ServerHostKeyAlgorithm.list_supported
302
- # => ["ssh-dss", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521"]
304
+ # => ["ssh-dss", "ssh-rsa", "ecdsa-sha2-nistp256", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp521", "ssh-ed25519"]
303
305
  p HrrRbSsh::Transport::ServerHostKeyAlgorithm.list_preferred
304
- # => ["ecdsa-sha2-nistp521", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp256", "ssh-rsa", "ssh-dss"]
306
+ # => ["ssh-ed25519", "ecdsa-sha2-nistp521", "ecdsa-sha2-nistp384", "ecdsa-sha2-nistp256", "ssh-rsa", "ssh-dss"]
305
307
 
306
308
  p HrrRbSsh::Transport::KexAlgorithm.list_supported
307
309
  # => ["diffie-hellman-group1-sha1", "diffie-hellman-group14-sha1", "diffie-hellman-group-exchange-sha1", "diffie-hellman-group-exchange-sha256", "diffie-hellman-group14-sha256", "diffie-hellman-group15-sha512", "diffie-hellman-group16-sha512", "diffie-hellman-group17-sha512", "diffie-hellman-group18-sha512", "ecdh-sha2-nistp256", "ecdh-sha2-nistp384", "ecdh-sha2-nistp521"]
@@ -346,6 +348,7 @@ The following features are currently supported.
346
348
  - ecdsa-sha2-nistp256
347
349
  - ecdsa-sha2-nistp384
348
350
  - ecdsa-sha2-nistp521
351
+ - ssh-ed25519
349
352
  - Keyboard interactive (generic interactive / challenge response) authentication
350
353
 
351
354
  ### Transport layer
@@ -368,6 +371,7 @@ The following features are currently supported.
368
371
  - ecdsa-sha2-nistp256
369
372
  - ecdsa-sha2-nistp384
370
373
  - ecdsa-sha2-nistp521
374
+ - ssh-ed25519
371
375
  - Kex algorithm
372
376
  - diffie-hellman-group1-sha1
373
377
  - diffie-hellman-group14-sha1
data/demo/server.rb CHANGED
@@ -18,7 +18,7 @@ def start_service io, logger=nil
18
18
  HrrRbSsh::Logger.initialize logger if logger
19
19
 
20
20
  tran_preferred_encryption_algorithms = %w(aes128-ctr aes192-ctr aes256-ctr aes128-cbc 3des-cbc blowfish-cbc cast128-cbc aes192-cbc aes256-cbc arcfour)
21
- tran_preferred_server_host_key_algorithms = %w(ecdsa-sha2-nistp521 ecdsa-sha2-nistp384 ecdsa-sha2-nistp256 ssh-rsa ssh-dss)
21
+ tran_preferred_server_host_key_algorithms = %w(ssh-ed25519 ecdsa-sha2-nistp521 ecdsa-sha2-nistp384 ecdsa-sha2-nistp256 ssh-rsa ssh-dss)
22
22
  tran_preferred_kex_algorithms = %w(ecdh-sha2-nistp521 ecdh-sha2-nistp384 ecdh-sha2-nistp256 diffie-hellman-group14-sha1 diffie-hellman-group1-sha1)
23
23
  tran_preferred_mac_algorithms = %w(hmac-sha2-512 hmac-sha2-256 hmac-sha1 hmac-md5 hmac-sha1-96 hmac-md5-96)
24
24
  tran_preferred_compression_algorithms = %w(none zlib)
data/hrr_rb_ssh.gemspec CHANGED
@@ -20,6 +20,7 @@ Gem::Specification.new do |spec|
20
20
 
21
21
  spec.required_ruby_version = '>= 2.0.0'
22
22
 
23
+ spec.add_dependency "ed25519", "~> 1.2"
23
24
  spec.add_development_dependency "bundler", "~> 1.16"
24
25
  spec.add_development_dependency "rake", "~> 10.0"
25
26
  spec.add_development_dependency "rspec", "~> 3.0"
data/lib/hrr_rb_ssh.rb CHANGED
@@ -1,6 +1,12 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
+
5
+
6
+ # HrrRbSsh is a pure Ruby SSH 2.0 implementation.
7
+ module HrrRbSsh
8
+ end
9
+
4
10
  require "hrr_rb_ssh/version"
5
11
  require "hrr_rb_ssh/compat"
6
12
  require "hrr_rb_ssh/logger"
@@ -11,7 +17,3 @@ require "hrr_rb_ssh/transport"
11
17
  require "hrr_rb_ssh/authentication"
12
18
  require "hrr_rb_ssh/connection"
13
19
  require "hrr_rb_ssh/server"
14
-
15
- module HrrRbSsh
16
- # Your code goes here...
17
- end
@@ -1,25 +1,14 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
+ require 'hrr_rb_ssh/subclass_without_preference_listable'
5
+
4
6
  module HrrRbSsh
5
7
  module Algorithm
6
8
  class Publickey
7
9
  @subclass_list = Array.new
8
10
  class << self
9
- def inherited klass
10
- @subclass_list.push klass if @subclass_list
11
- end
12
-
13
- def [] key
14
- __subclass_list__(__method__).find{ |klass| klass::NAME == key }
15
- end
16
-
17
- def __subclass_list__ method_name
18
- send(:method_missing, method_name) unless @subclass_list
19
- @subclass_list
20
- end
21
-
22
- private :__subclass_list__
11
+ include SubclassWithoutPreferenceListable
23
12
  end
24
13
  end
25
14
  end
@@ -30,3 +19,4 @@ require 'hrr_rb_ssh/algorithm/publickey/ssh_rsa'
30
19
  require 'hrr_rb_ssh/algorithm/publickey/ecdsa_sha2_nistp256'
31
20
  require 'hrr_rb_ssh/algorithm/publickey/ecdsa_sha2_nistp384'
32
21
  require 'hrr_rb_ssh/algorithm/publickey/ecdsa_sha2_nistp521'
22
+ require 'hrr_rb_ssh/algorithm/publickey/ssh_ed25519'
@@ -0,0 +1,61 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/logger'
5
+
6
+ module HrrRbSsh
7
+ module Algorithm
8
+ class Publickey
9
+ class SshEd25519 < Publickey
10
+ NAME = 'ssh-ed25519'
11
+
12
+ def initialize arg
13
+ begin
14
+ new_by_key_str arg
15
+ rescue PKey::Error
16
+ new_by_public_key_blob arg
17
+ end
18
+ end
19
+
20
+ def new_by_key_str key_str
21
+ @publickey = PKey.new(key_str)
22
+ end
23
+
24
+ def new_by_public_key_blob public_key_blob
25
+ public_key_blob_h = PublicKeyBlob.decode(public_key_blob)
26
+ @publickey = PKey.new
27
+ @publickey.set_public_key(public_key_blob_h[:key])
28
+ end
29
+
30
+ def to_pem
31
+ @publickey.public_key.to_pem
32
+ end
33
+
34
+ def to_public_key_blob
35
+ public_key_blob_h = {
36
+ :'public key algorithm name' => self.class::NAME,
37
+ :'key' => @publickey.public_key.key_str,
38
+ }
39
+ PublicKeyBlob.encode(public_key_blob_h)
40
+ end
41
+
42
+ def sign signature_blob
43
+ signature_h = {
44
+ :'public key algorithm name' => self.class::NAME,
45
+ :'signature blob' => @publickey.sign(signature_blob),
46
+ }
47
+ Signature.encode signature_h
48
+ end
49
+
50
+ def verify signature, signature_blob
51
+ signature_h = Signature.decode signature
52
+ signature_h[:'public key algorithm name'] == self.class::NAME && @publickey.public_key.verify(signature_h[:'signature blob'], signature_blob)
53
+ end
54
+ end
55
+ end
56
+ end
57
+ end
58
+
59
+ require 'hrr_rb_ssh/algorithm/publickey/ssh_ed25519/pkey'
60
+ require 'hrr_rb_ssh/algorithm/publickey/ssh_ed25519/public_key_blob'
61
+ require 'hrr_rb_ssh/algorithm/publickey/ssh_ed25519/signature'
@@ -0,0 +1,29 @@
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 Algorithm
9
+ class Publickey
10
+ class SshEd25519
11
+ module OpenSSHPrivateKey
12
+ class << self
13
+ include Codable
14
+ end
15
+ DEFINITION = [
16
+ [DataType::String, :'cipher'],
17
+ [DataType::String, :'kdfname'],
18
+ [DataType::Uint32, :'kdfopts'],
19
+ [DataType::Uint32, :'number of public keys'],
20
+ [DataType::Uint32, :'first public key length'],
21
+ [DataType::String, :'name'],
22
+ [DataType::String, :'public key'],
23
+ [DataType::String, :'content'],
24
+ ]
25
+ end
26
+ end
27
+ end
28
+ end
29
+ end
@@ -0,0 +1,26 @@
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 Algorithm
9
+ class Publickey
10
+ class SshEd25519
11
+ module OpenSSHPrivateKeyContent
12
+ class << self
13
+ include Codable
14
+ end
15
+ DEFINITION = [
16
+ [DataType::Uint64, :'unknown'],
17
+ [DataType::String, :'name'],
18
+ [DataType::String, :'public key'],
19
+ [DataType::String, :'key pair'],
20
+ [DataType::String, :'padding'],
21
+ ]
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,158 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'stringio'
5
+ require 'base64'
6
+ require 'ed25519'
7
+
8
+ module HrrRbSsh
9
+ module Algorithm
10
+ class Publickey
11
+ class SshEd25519
12
+ class PKey
13
+ class Error < ::StandardError
14
+ end
15
+
16
+ def initialize arg=nil
17
+ case arg
18
+ when ::Ed25519::SigningKey, ::Ed25519::VerifyKey
19
+ @key = arg
20
+ when ::String
21
+ @key = load_key_str arg
22
+ when nil
23
+ # do nothing
24
+ end
25
+ end
26
+
27
+ def load_key_str key_str
28
+ begin
29
+ load_openssh_key key_str
30
+ rescue
31
+ begin
32
+ load_openssl_key key_str
33
+ rescue
34
+ raise Error
35
+ end
36
+ end
37
+ end
38
+
39
+ def load_openssh_key key_str
40
+ begin_marker = "-----BEGIN OPENSSH PRIVATE KEY-----\n"
41
+ end_marker = "-----END OPENSSH PRIVATE KEY-----\n"
42
+ magic = "openssh-key-v1"
43
+
44
+ raise Error unless key_str.start_with? begin_marker
45
+ raise Error unless key_str.end_with? end_marker
46
+ decoded_key_str = Base64.decode64(key_str[begin_marker.size...-end_marker.size])
47
+ raise Error unless decoded_key_str[0,14] == magic
48
+
49
+ private_key_h = OpenSSHPrivateKey.decode decoded_key_str[15..-1]
50
+ private_key_content_h = OpenSSHPrivateKeyContent.decode private_key_h[:'content']
51
+ key_pair = private_key_content_h[:'key pair']
52
+
53
+ ::Ed25519::SigningKey.new(key_pair[0,32])
54
+ end
55
+
56
+ def load_openssl_key key_str
57
+ private_key_begin_marker = "-----BEGIN PRIVATE KEY-----\n"
58
+ public_key_begin_marker = "-----BEGIN PUBLIC KEY-----\n"
59
+ if key_str.start_with? private_key_begin_marker
60
+ begin_marker = "-----BEGIN PRIVATE KEY-----\n"
61
+ end_marker = "-----END PRIVATE KEY-----\n"
62
+
63
+ raise Error unless key_str.start_with? begin_marker
64
+ raise Error unless key_str.end_with? end_marker
65
+
66
+ decoded_key_str = Base64.decode64(key_str[begin_marker.size...-end_marker.size])
67
+ key_der = OpenSSL::ASN1.decode decoded_key_str
68
+
69
+ ::Ed25519::SigningKey.new(key_der.value[2].value[2..-1])
70
+ elsif key_str.start_with? public_key_begin_marker
71
+ begin_marker = "-----BEGIN PUBLIC KEY-----\n"
72
+ end_marker = "-----END PUBLIC KEY-----\n"
73
+
74
+ raise Error unless key_str.start_with? begin_marker
75
+ raise Error unless key_str.end_with? end_marker
76
+
77
+ decoded_key_str = Base64.decode64(key_str[begin_marker.size...-end_marker.size])
78
+ key_der = OpenSSL::ASN1.decode decoded_key_str
79
+
80
+ ::Ed25519::VerifyKey.new(key_der.value[1].value)
81
+ else
82
+ raise Error
83
+ end
84
+ end
85
+
86
+ def set_public_key key_str
87
+ @key = ::Ed25519::VerifyKey.new(key_str)
88
+ end
89
+
90
+ def to_pem
91
+ ed25519_object_id = '1.3.101.112'
92
+ case @key
93
+ =begin
94
+ when ::Ed25519::SigningKey
95
+ begin_marker = "-----BEGIN PRIVATE KEY-----\n"
96
+ end_marker = "-----END PRIVATE KEY-----\n"
97
+ key_asn1 = OpenSSL::ASN1::Sequence.new(
98
+ [
99
+ OpenSSL::ASN1::Integer.new(OpenSSL::BN.new(0)),
100
+ OpenSSL::ASN1::Sequence.new(
101
+ [
102
+ OpenSSL::ASN1::ObjectId.new(ed25519_object_id),
103
+ ]
104
+ ),
105
+ OpenSSL::ASN1::OctetString.new(@key.to_bytes),
106
+ ]
107
+ )
108
+ =end
109
+ when ::Ed25519::VerifyKey
110
+ begin_marker = "-----BEGIN PUBLIC KEY-----\n"
111
+ end_marker = "-----END PUBLIC KEY-----\n"
112
+ key_asn1 = OpenSSL::ASN1::Sequence.new(
113
+ [
114
+ OpenSSL::ASN1::Sequence.new(
115
+ [
116
+ OpenSSL::ASN1::ObjectId.new(ed25519_object_id),
117
+ ]
118
+ ),
119
+ OpenSSL::ASN1::BitString.new(@key.to_bytes),
120
+ ]
121
+ )
122
+ end
123
+ pem_str = Base64.encode64(key_asn1.to_der)
124
+ begin_marker + pem_str + end_marker
125
+ end
126
+
127
+ def public_key
128
+ case @key
129
+ when ::Ed25519::SigningKey
130
+ self.class.new @key.verify_key
131
+ when ::Ed25519::VerifyKey
132
+ self
133
+ end
134
+ end
135
+
136
+ def key_str
137
+ @key.to_bytes
138
+ end
139
+
140
+ def sign data
141
+ @key.sign data
142
+ end
143
+
144
+ def verify signature, data
145
+ begin
146
+ @key.verify signature, data
147
+ rescue ::Ed25519::VerifyError
148
+ false
149
+ end
150
+ end
151
+ end
152
+ end
153
+ end
154
+ end
155
+ end
156
+
157
+ require 'hrr_rb_ssh/algorithm/publickey/ssh_ed25519/openssh_private_key'
158
+ require 'hrr_rb_ssh/algorithm/publickey/ssh_ed25519/openssh_private_key_content'
@@ -0,0 +1,23 @@
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 Algorithm
9
+ class Publickey
10
+ class SshEd25519
11
+ module PublicKeyBlob
12
+ class << self
13
+ include Codable
14
+ end
15
+ DEFINITION = [
16
+ [DataType::String, :'public key algorithm name'],
17
+ [DataType::String, :'key'],
18
+ ]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,23 @@
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 Algorithm
9
+ class Publickey
10
+ class SshEd25519
11
+ module Signature
12
+ class << self
13
+ include Codable
14
+ end
15
+ DEFINITION = [
16
+ [DataType::String, :'public key algorithm name'],
17
+ [DataType::String, :'signature blob'],
18
+ ]
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -23,3 +23,4 @@ require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa'
23
23
  require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp256'
24
24
  require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp384'
25
25
  require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ecdsa_sha2_nistp521'
26
+ require 'hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_ed25519'
@@ -0,0 +1,21 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'hrr_rb_ssh/authentication/method/publickey/algorithm/functionable'
5
+
6
+ module HrrRbSsh
7
+ class Authentication
8
+ class Method
9
+ class Publickey
10
+ class Algorithm
11
+ class SshEd25519 < Algorithm
12
+ NAME = 'ssh-ed25519'
13
+ PREFERENCE = 60
14
+
15
+ include Functionable
16
+ end
17
+ end
18
+ end
19
+ end
20
+ end
21
+ end
@@ -14,10 +14,11 @@ module HrrRbSsh
14
14
  end
15
15
 
16
16
  def conditional_definition message
17
+ return [] unless self.const_defined? :CONDITIONAL_DEFINITION
17
18
  message.inject([]){ |a, (k,v)|
18
19
  field_name = k
19
20
  field_value = if v.instance_of? ::Proc then v.call else v end
20
- a + ((self::CONDITIONAL_DEFINITION rescue {}).fetch(field_name, {})[field_value] || [])
21
+ a + (self::CONDITIONAL_DEFINITION.fetch(field_name, {})[field_value] || [])
21
22
  }
22
23
  end
23
24
 
@@ -1,26 +1,15 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
+ require 'hrr_rb_ssh/subclass_without_preference_listable'
5
+
4
6
  module HrrRbSsh
5
7
  class Connection
6
8
  class Channel
7
9
  class ChannelType
8
10
  @subclass_list = Array.new
9
11
  class << self
10
- def inherited klass
11
- @subclass_list.push klass if @subclass_list
12
- end
13
-
14
- def [] key
15
- __subclass_list__(__method__).find{ |klass| klass::NAME == key }
16
- end
17
-
18
- def __subclass_list__ method_name
19
- send(:method_missing, method_name) unless @subclass_list
20
- @subclass_list
21
- end
22
-
23
- private :__subclass_list__
12
+ include SubclassWithoutPreferenceListable
24
13
  end
25
14
  end
26
15
  end
@@ -1,6 +1,8 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
+ require 'hrr_rb_ssh/subclass_without_preference_listable'
5
+
4
6
  module HrrRbSsh
5
7
  class Connection
6
8
  class Channel
@@ -9,20 +11,7 @@ module HrrRbSsh
9
11
  class RequestType
10
12
  @subclass_list = Array.new
11
13
  class << self
12
- def inherited klass
13
- @subclass_list.push klass if @subclass_list
14
- end
15
-
16
- def [] key
17
- __subclass_list__(__method__).find{ |klass| klass::NAME == key }
18
- end
19
-
20
- def __subclass_list__ method_name
21
- send(:method_missing, method_name) unless @subclass_list
22
- @subclass_list
23
- end
24
-
25
- private :__subclass_list__
14
+ include SubclassWithoutPreferenceListable
26
15
  end
27
16
  end
28
17
  end
@@ -67,19 +67,13 @@ module HrrRbSsh
67
67
  }
68
68
  chain.call_next
69
69
  ensure
70
+ context.logger.info { "closing pty-req request handler chain_proc" }
70
71
  context.vars[:ptm].close rescue nil
71
72
  context.vars[:pts].close rescue nil
72
- begin
73
- ptm_read_thread.join
74
- rescue => e
75
- context.logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
76
- end
77
- begin
78
- ptm_write_thread.exit
79
- ptm_write_thread.join
80
- rescue => e
81
- context.logger.error { [e.backtrace[0], ": ", e.message, " (", e.class.to_s, ")\n\t", e.backtrace[1..-1].join("\n\t")].join }
82
- end
73
+ ptm_read_thread.join
74
+ ptm_write_thread.exit
75
+ ptm_write_thread.join
76
+ context.logger.info { "pty-req request handler chain_proc closed" }
83
77
  end
84
78
  }
85
79
  rescue => e
@@ -1,150 +1,16 @@
1
1
  # coding: utf-8
2
2
  # vim: et ts=2 sw=2
3
3
 
4
- require 'openssl'
5
-
6
4
  module HrrRbSsh
7
- module DataType
8
- class Byte
9
- def self.encode arg
10
- case arg
11
- when 0x00..0xff
12
- [arg].pack("C")
13
- else
14
- raise ArgumentError, "must be in #{0x00}..#{0xff}, but got #{arg.inspect}"
15
- end
16
- end
17
-
18
- def self.decode io
19
- io.read(1).unpack("C")[0]
20
- end
21
- end
22
-
23
- class Boolean
24
- def self.encode arg
25
- case arg
26
- when false
27
- [0].pack("C")
28
- when true
29
- [1].pack("C")
30
- else
31
- raise ArgumentError, "must be #{true} or #{false}, but got #{arg.inspect}"
32
- end
33
- end
34
-
35
- def self.decode io
36
- if 0 == io.read(1).unpack("C")[0]
37
- false
38
- else
39
- true
40
- end
41
- end
42
- end
43
-
44
- class Uint32
45
- def self.encode arg
46
- case arg
47
- when 0x0000_0000..0xffff_ffff
48
- [arg].pack("N")
49
- else
50
- raise ArgumentError, "must be in #{0x0000_0000}..#{0xffff_ffff}, but got #{arg.inspect}"
51
- end
52
- end
53
-
54
- def self.decode io
55
- io.read(4).unpack("N")[0]
56
- end
57
- end
58
-
59
- class Uint64
60
- def self.encode arg
61
- case arg
62
- when 0x0000_0000_0000_0000..0xffff_ffff_ffff_ffff
63
- [arg >> 32].pack("N") + [arg & 0x0000_0000_ffff_ffff].pack("N")
64
- else
65
- raise ArgumentError, "must be in #{0x0000_0000_0000_0000}..#{0xffff_ffff_ffff_ffff}, but got #{arg.inspect}"
66
- end
67
- end
68
-
69
- def self.decode io
70
- (io.read(4).unpack("N")[0] << 32) + (io.read(4).unpack("N")[0])
71
- end
72
- end
73
-
74
- class String
75
- def self.encode arg
76
- unless arg.kind_of? ::String
77
- raise ArgumentError, "must be a kind of String, but got #{arg.inspect}"
78
- end
79
- if arg.length > 0xffff_ffff
80
- raise ArgumentError, "must be shorter than or equal to #{0xffff_ffff}, but got length #{arg.length}"
81
- end
82
- [arg.length, arg].pack("Na*")
83
- end
84
-
85
- def self.decode io
86
- length = io.read(4).unpack("N")[0]
87
- io.read(length).unpack("a*")[0]
88
- end
89
- end
90
-
91
- class Mpint
92
- def self.encode arg
93
- unless arg.kind_of? ::Integer
94
- raise ArgumentError, "must be a kind of Integer, but got #{arg.inspect}"
95
- end
96
- bn = ::OpenSSL::BN.new(arg)
97
- if bn < 0
98
- # get 2's complement
99
- tc = bn.to_i & ((1 << (bn.num_bytes * 8)) - 1)
100
- # get hex representation
101
- hex_str = "%x" % tc
102
-
103
- if tc[(bn.num_bytes * 8) - 1] == 1
104
- [bn.num_bytes, hex_str].pack("NH*")
105
- else
106
- [bn.num_bytes + 1, "ff" + hex_str].pack("NH*")
107
- end
108
- else
109
- bn.to_s(0)
110
- end
111
- end
112
-
113
- def self.decode io
114
- length = io.read(4).unpack("N")[0]
115
- hex_str = io.read(length).unpack("H*")[0]
116
- # get temporal integer value
117
- value = hex_str.hex
118
- if length == 0
119
- 0
120
- elsif value[(length * 8) - 1] == 0
121
- value
122
- else
123
- num_bytes = if hex_str.start_with?("ff") then length - 1 else length end
124
- - (((~ value) & ((1 << (num_bytes * 8)) - 1)) + 1)
125
- end
126
- end
127
- end
128
-
129
- class NameList
130
- def self.encode arg
131
- unless arg.kind_of? Array
132
- raise ArgumentError, "must be a kind of Array, but got #{arg.inspect}"
133
- end
134
- unless (arg.map(&:class) - [::String]).empty?
135
- raise ArgumentError, "must be with all elements of String, but got #{arg.inspect}"
136
- end
137
- joined_arg = arg.join(',')
138
- if joined_arg.length > 0xffff_ffff
139
- raise ArgumentError, "must be shorter than or equal to #{0xffff_ffff}, but got length #{joined_arg.length}"
140
- end
141
- [joined_arg.length, joined_arg].pack("Na*")
142
- end
143
-
144
- def self.decode io
145
- length = io.read(4).unpack("N")[0]
146
- io.read(length).unpack("a*")[0].split(',')
147
- end
148
- end
5
+ # DataType is a parent class of classes that provide methods to convert value and binary string each other.
6
+ class DataType
149
7
  end
150
8
  end
9
+
10
+ require 'hrr_rb_ssh/data_type/byte'
11
+ require 'hrr_rb_ssh/data_type/boolean'
12
+ require 'hrr_rb_ssh/data_type/uint32'
13
+ require 'hrr_rb_ssh/data_type/uint64'
14
+ require 'hrr_rb_ssh/data_type/string'
15
+ require 'hrr_rb_ssh/data_type/mpint'
16
+ require 'hrr_rb_ssh/data_type/name_list'
@@ -0,0 +1,37 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ module HrrRbSsh
5
+ class DataType
6
+ # Boolean provides methods to convert boolean value and 8-bit unsigned binary string each other.
7
+ class Boolean < DataType
8
+ # Convert boolean value into 8-bit unsigned binary string.
9
+ #
10
+ # @param [::Boolean] arg boolean value to be converted
11
+ # @raise [::ArgumentError] when arg is not true nor false
12
+ # @return [::String] converted 8-bit unsigned binary string
13
+ def self.encode arg
14
+ case arg
15
+ when false
16
+ [0].pack("C")
17
+ when true
18
+ [1].pack("C")
19
+ else
20
+ raise ArgumentError, "must be #{true} or #{false}, but got #{arg.inspect}"
21
+ end
22
+ end
23
+
24
+ # Convert 8-bit unsigned binary into boolean value.
25
+ #
26
+ # @param [::IO] io IO instance that has buffer to be read
27
+ # @return [::Boolean] converted boolean value
28
+ def self.decode io
29
+ if 0 == io.read(1).unpack("C")[0]
30
+ false
31
+ else
32
+ true
33
+ end
34
+ end
35
+ end
36
+ end
37
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ module HrrRbSsh
5
+ class DataType
6
+ # Byte provides methods to convert integer value and 8-bit unsigned binary string each other.
7
+ class Byte < DataType
8
+ # Convert integer value into 8-bit unsigned binary string.
9
+ #
10
+ # @param [::Integer] arg integer value to be converted
11
+ # @raise [::ArgumentError] when arg is not between 0x00 and 0xff
12
+ # @return [::String] converted 8-bit unsigned binary string
13
+ def self.encode arg
14
+ case arg
15
+ when 0x00..0xff
16
+ [arg].pack("C")
17
+ else
18
+ raise ArgumentError, "must be in #{0x00}..#{0xff}, but got #{arg.inspect}"
19
+ end
20
+ end
21
+
22
+ # Convert 8-bit unsigned binary into Integer value.
23
+ #
24
+ # @param [::IO] io IO instance that has buffer to be read
25
+ # @return [::Integer] converted integer value
26
+ def self.decode io
27
+ io.read(1).unpack("C")[0]
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,56 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'openssl'
5
+
6
+ module HrrRbSsh
7
+ class DataType
8
+ # Mpint provides methods to convert integer value and multiple precision integer in two's complement as binary string each other.
9
+ class Mpint < DataType
10
+ # Convert integer value into multiple precision integer in two's complement as binary string.
11
+ #
12
+ # @param [::Integer] arg integer value to be converted
13
+ # @raise [::ArgumentError] when arg is not an integer value
14
+ # @return [::String] converted multiple precision integer in two's complement as binary string
15
+ def self.encode arg
16
+ unless arg.kind_of? ::Integer
17
+ raise ArgumentError, "must be a kind of Integer, but got #{arg.inspect}"
18
+ end
19
+ bn = ::OpenSSL::BN.new(arg)
20
+ if bn < 0
21
+ # get 2's complement
22
+ tc = bn.to_i & ((1 << (bn.num_bytes * 8)) - 1)
23
+ # get hex representation
24
+ hex_str = "%x" % tc
25
+
26
+ if tc[(bn.num_bytes * 8) - 1] == 1
27
+ [bn.num_bytes, hex_str].pack("NH*")
28
+ else
29
+ [bn.num_bytes + 1, "ff" + hex_str].pack("NH*")
30
+ end
31
+ else
32
+ bn.to_s(0)
33
+ end
34
+ end
35
+
36
+ # Convert multiple precision integer in two's complement as binary string into integer value.
37
+ #
38
+ # @param [::IO] io IO instance that has buffer to be read
39
+ # @return [::Integer] converted integer value
40
+ def self.decode io
41
+ length = io.read(4).unpack("N")[0]
42
+ hex_str = io.read(length).unpack("H*")[0]
43
+ # get temporal integer value
44
+ value = hex_str.hex
45
+ if length == 0
46
+ 0
47
+ elsif value[(length * 8) - 1] == 0
48
+ value
49
+ else
50
+ num_bytes = if hex_str.start_with?("ff") then length - 1 else length end
51
+ - (((~ value) & ((1 << (num_bytes * 8)) - 1)) + 1)
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ module HrrRbSsh
5
+ class DataType
6
+ # NameList provides methods to convert a comma-separated list of names and binary string each other.
7
+ class NameList < DataType
8
+ # Convert a comma-separated list of names into binary string.
9
+ #
10
+ # @param [::Array] arg an array that containes names to be converted
11
+ # @raise [::ArgumentError] when arg is not an array
12
+ # @raise [::ArgumentError] when arg array containes an instance of not string
13
+ # @return [::String] converted binary string
14
+ def self.encode arg
15
+ unless arg.kind_of? ::Array
16
+ raise ArgumentError, "must be a kind of Array, but got #{arg.inspect}"
17
+ end
18
+ unless arg.all?{ |e| e.kind_of? ::String }
19
+ raise ArgumentError, "must be with all elements of String, but got #{arg.inspect}"
20
+ end
21
+ joined_arg = arg.join(',')
22
+ if joined_arg.length > 0xffff_ffff
23
+ raise ArgumentError, "must be shorter than or equal to #{0xffff_ffff}, but got length #{joined_arg.length}"
24
+ end
25
+ [joined_arg.length, joined_arg].pack("Na*")
26
+ end
27
+
28
+ # Convert binary string into a comma-separated list of names.
29
+ #
30
+ # @param [::IO] io IO instance that has buffer to be read
31
+ # @return [::Array] converted a comma-separated list of names
32
+ def self.decode io
33
+ length = io.read(4).unpack("N")[0]
34
+ io.read(length).unpack("a*")[0].split(',')
35
+ end
36
+ end
37
+ end
38
+ end
@@ -0,0 +1,34 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ module HrrRbSsh
5
+ class DataType
6
+ # String provides methods to convert Ruby's string value and binary string each other.
7
+ class String < DataType
8
+ # Convert Ruby's string value into binary string.
9
+ #
10
+ # @param [::String] arg Ruby's string value to be converted
11
+ # @raise [::ArgumentError] when arg is not string
12
+ # @raise [::ArgumentError] when length of arg is longer than 0xffff_ffff
13
+ # @return [::String] converted binary string
14
+ def self.encode arg
15
+ unless arg.kind_of? ::String
16
+ raise ArgumentError, "must be a kind of String, but got #{arg.inspect}"
17
+ end
18
+ if arg.length > 0xffff_ffff
19
+ raise ArgumentError, "must be shorter than or equal to #{0xffff_ffff}, but got length #{arg.length}"
20
+ end
21
+ [arg.length, arg].pack("Na*")
22
+ end
23
+
24
+ # Convert binary string into Ruby's string value.
25
+ #
26
+ # @param [::IO] io IO instance that has buffer to be read
27
+ # @return [::String] converted Ruby's string value
28
+ def self.decode io
29
+ length = io.read(4).unpack("N")[0]
30
+ io.read(length).unpack("a*")[0]
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ module HrrRbSsh
5
+ class DataType
6
+ # Uint32 provides methods to convert integer value and 32-bit unsigned binary string each other.
7
+ class Uint32 < DataType
8
+ # Convert integer value into 32-bit unsigned binary string.
9
+ #
10
+ # @param [::Integer] arg integer value to be converted
11
+ # @raise [::ArgumentError] when arg is not between 0x0000_0000 and 0xffff_ffff
12
+ # @return [::String] converted 32-bit unsigned binary string
13
+ def self.encode arg
14
+ case arg
15
+ when 0x0000_0000..0xffff_ffff
16
+ [arg].pack("N")
17
+ else
18
+ raise ArgumentError, "must be in #{0x0000_0000}..#{0xffff_ffff}, but got #{arg.inspect}"
19
+ end
20
+ end
21
+
22
+ # Convert 32-bit unsigned binary into Integer value.
23
+ #
24
+ # @param [::IO] io IO instance that has buffer to be read
25
+ # @return [::Integer] converted integer value
26
+ def self.decode io
27
+ io.read(4).unpack("N")[0]
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,31 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ module HrrRbSsh
5
+ class DataType
6
+ # Uint64 provides methods to convert integer value and 64-bit unsigned binary string each other.
7
+ class Uint64 < DataType
8
+ # Convert integer value into 64-bit unsigned binary string.
9
+ #
10
+ # @param [::Integer] arg integer value to be converted
11
+ # @raise [::ArgumentError] when arg is not between 0x0000_0000_0000_0000 and 0xffff_ffff_ffff_ffff
12
+ # @return [::String] converted 64-bit unsigned binary string
13
+ def self.encode arg
14
+ case arg
15
+ when 0x0000_0000_0000_0000..0xffff_ffff_ffff_ffff
16
+ [arg >> 32].pack("N") + [arg & 0x0000_0000_ffff_ffff].pack("N")
17
+ else
18
+ raise ArgumentError, "must be in #{0x0000_0000_0000_0000}..#{0xffff_ffff_ffff_ffff}, but got #{arg.inspect}"
19
+ end
20
+ end
21
+
22
+ # Convert 64-bit unsigned binary into Integer value.
23
+ #
24
+ # @param [::IO] io IO instance that has buffer to be read
25
+ # @return [::Integer] converted integer value
26
+ def self.decode io
27
+ (io.read(4).unpack("N")[0] << 32) + (io.read(4).unpack("N")[0])
28
+ end
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,25 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ module HrrRbSsh
5
+ module SubclassWithoutPreferenceListable
6
+ def inherited klass
7
+ @subclass_list.push klass if @subclass_list
8
+ end
9
+
10
+ def [] key
11
+ __subclass_list__(__method__).find{ |klass| klass::NAME == key }
12
+ end
13
+
14
+ def list_supported
15
+ __subclass_list__(__method__).map{ |klass| klass::NAME }
16
+ end
17
+
18
+ def __subclass_list__ method_name
19
+ send(:method_missing, method_name) unless @subclass_list
20
+ @subclass_list
21
+ end
22
+
23
+ private :__subclass_list__
24
+ end
25
+ end
@@ -19,3 +19,4 @@ require 'hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa'
19
19
  require 'hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp256'
20
20
  require 'hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp384'
21
21
  require 'hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521'
22
+ require 'hrr_rb_ssh/transport/server_host_key_algorithm/ssh_ed25519'
@@ -0,0 +1,20 @@
1
+ # coding: utf-8
2
+ # vim: et ts=2 sw=2
3
+
4
+ require 'ed25519'
5
+ require 'hrr_rb_ssh/openssl_secure_random'
6
+ require 'hrr_rb_ssh/transport/server_host_key_algorithm/functionable'
7
+
8
+ module HrrRbSsh
9
+ class Transport
10
+ class ServerHostKeyAlgorithm
11
+ class SshEd25519 < ServerHostKeyAlgorithm
12
+ NAME = 'ssh-ed25519'
13
+ PREFERENCE = 60
14
+ SECRET_KEY = ::Ed25519::SigningKey.generate
15
+
16
+ include Functionable
17
+ end
18
+ end
19
+ end
20
+ end
@@ -2,5 +2,5 @@
2
2
  # vim: et ts=2 sw=2
3
3
 
4
4
  module HrrRbSsh
5
- VERSION = "0.2.1"
5
+ VERSION = "0.2.2"
6
6
  end
metadata CHANGED
@@ -1,15 +1,29 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: hrr_rb_ssh
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.1
4
+ version: 0.2.2
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-27 00:00:00.000000000 Z
11
+ date: 2018-08-30 00:00:00.000000000 Z
12
12
  dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: ed25519
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.2'
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.2'
13
27
  - !ruby/object:Gem::Dependency
14
28
  name: bundler
15
29
  requirement: !ruby/object:Gem::Requirement
@@ -98,6 +112,12 @@ files:
98
112
  - lib/hrr_rb_ssh/algorithm/publickey/ssh_dss.rb
99
113
  - lib/hrr_rb_ssh/algorithm/publickey/ssh_dss/public_key_blob.rb
100
114
  - lib/hrr_rb_ssh/algorithm/publickey/ssh_dss/signature.rb
115
+ - lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519.rb
116
+ - lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/openssh_private_key.rb
117
+ - lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/openssh_private_key_content.rb
118
+ - lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/pkey.rb
119
+ - lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/public_key_blob.rb
120
+ - lib/hrr_rb_ssh/algorithm/publickey/ssh_ed25519/signature.rb
101
121
  - lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa.rb
102
122
  - lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa/public_key_blob.rb
103
123
  - lib/hrr_rb_ssh/algorithm/publickey/ssh_rsa/signature.rb
@@ -120,6 +140,7 @@ files:
120
140
  - lib/hrr_rb_ssh/authentication/method/publickey/algorithm/functionable.rb
121
141
  - lib/hrr_rb_ssh/authentication/method/publickey/algorithm/signature_blob.rb
122
142
  - lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_dss.rb
143
+ - lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_ed25519.rb
123
144
  - lib/hrr_rb_ssh/authentication/method/publickey/algorithm/ssh_rsa.rb
124
145
  - lib/hrr_rb_ssh/authentication/method/publickey/context.rb
125
146
  - lib/hrr_rb_ssh/codable.rb
@@ -161,6 +182,13 @@ files:
161
182
  - lib/hrr_rb_ssh/connection/request_handler/reference_shell_request_handler.rb
162
183
  - lib/hrr_rb_ssh/connection/request_handler/reference_window_change_request_handler.rb
163
184
  - lib/hrr_rb_ssh/data_type.rb
185
+ - lib/hrr_rb_ssh/data_type/boolean.rb
186
+ - lib/hrr_rb_ssh/data_type/byte.rb
187
+ - lib/hrr_rb_ssh/data_type/mpint.rb
188
+ - lib/hrr_rb_ssh/data_type/name_list.rb
189
+ - lib/hrr_rb_ssh/data_type/string.rb
190
+ - lib/hrr_rb_ssh/data_type/uint32.rb
191
+ - lib/hrr_rb_ssh/data_type/uint64.rb
164
192
  - lib/hrr_rb_ssh/error.rb
165
193
  - lib/hrr_rb_ssh/error/closed_authentication.rb
166
194
  - lib/hrr_rb_ssh/error/closed_connection.rb
@@ -208,6 +236,7 @@ files:
208
236
  - lib/hrr_rb_ssh/openssl_secure_random.rb
209
237
  - lib/hrr_rb_ssh/server.rb
210
238
  - lib/hrr_rb_ssh/subclass_with_preference_listable.rb
239
+ - lib/hrr_rb_ssh/subclass_without_preference_listable.rb
211
240
  - lib/hrr_rb_ssh/transport.rb
212
241
  - lib/hrr_rb_ssh/transport/compression_algorithm.rb
213
242
  - lib/hrr_rb_ssh/transport/compression_algorithm/functionable.rb
@@ -269,6 +298,7 @@ files:
269
298
  - lib/hrr_rb_ssh/transport/server_host_key_algorithm/ecdsa_sha2_nistp521.rb
270
299
  - lib/hrr_rb_ssh/transport/server_host_key_algorithm/functionable.rb
271
300
  - lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_dss.rb
301
+ - lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_ed25519.rb
272
302
  - lib/hrr_rb_ssh/transport/server_host_key_algorithm/ssh_rsa.rb
273
303
  - lib/hrr_rb_ssh/version.rb
274
304
  homepage: https://github.com/hirura/hrr_rb_ssh