hrr_rb_ssh 0.2.1 → 0.2.2

Sign up to get free protection for your applications and to get access to all the features.
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