net-ssh 5.0.0.beta1 → 5.0.0.beta2

Sign up to get free protection for your applications and to get access to all the features.
Files changed (87) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.rubocop_todo.yml +98 -258
  5. data/CHANGES.txt +8 -0
  6. data/Gemfile +1 -3
  7. data/Rakefile +37 -39
  8. data/lib/net/ssh.rb +26 -25
  9. data/lib/net/ssh/authentication/agent.rb +228 -225
  10. data/lib/net/ssh/authentication/certificate.rb +166 -164
  11. data/lib/net/ssh/authentication/constants.rb +17 -14
  12. data/lib/net/ssh/authentication/ed25519.rb +107 -104
  13. data/lib/net/ssh/authentication/ed25519_loader.rb +32 -28
  14. data/lib/net/ssh/authentication/key_manager.rb +5 -3
  15. data/lib/net/ssh/authentication/methods/abstract.rb +53 -47
  16. data/lib/net/ssh/authentication/methods/hostbased.rb +32 -33
  17. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +2 -4
  18. data/lib/net/ssh/authentication/methods/none.rb +10 -10
  19. data/lib/net/ssh/authentication/methods/password.rb +13 -13
  20. data/lib/net/ssh/authentication/methods/publickey.rb +54 -55
  21. data/lib/net/ssh/authentication/pageant.rb +468 -465
  22. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +44 -0
  23. data/lib/net/ssh/authentication/session.rb +127 -123
  24. data/lib/net/ssh/buffer.rb +305 -303
  25. data/lib/net/ssh/buffered_io.rb +163 -162
  26. data/lib/net/ssh/config.rb +230 -227
  27. data/lib/net/ssh/connection/channel.rb +659 -654
  28. data/lib/net/ssh/connection/constants.rb +30 -26
  29. data/lib/net/ssh/connection/event_loop.rb +108 -104
  30. data/lib/net/ssh/connection/keepalive.rb +54 -50
  31. data/lib/net/ssh/connection/session.rb +677 -678
  32. data/lib/net/ssh/connection/term.rb +180 -176
  33. data/lib/net/ssh/errors.rb +101 -99
  34. data/lib/net/ssh/key_factory.rb +108 -108
  35. data/lib/net/ssh/known_hosts.rb +148 -154
  36. data/lib/net/ssh/loggable.rb +56 -54
  37. data/lib/net/ssh/packet.rb +82 -78
  38. data/lib/net/ssh/prompt.rb +55 -53
  39. data/lib/net/ssh/proxy/command.rb +103 -102
  40. data/lib/net/ssh/proxy/errors.rb +12 -8
  41. data/lib/net/ssh/proxy/http.rb +92 -91
  42. data/lib/net/ssh/proxy/https.rb +42 -39
  43. data/lib/net/ssh/proxy/jump.rb +50 -47
  44. data/lib/net/ssh/proxy/socks4.rb +0 -2
  45. data/lib/net/ssh/proxy/socks5.rb +11 -11
  46. data/lib/net/ssh/ruby_compat.rb +1 -0
  47. data/lib/net/ssh/service/forward.rb +364 -362
  48. data/lib/net/ssh/test.rb +85 -83
  49. data/lib/net/ssh/test/channel.rb +146 -142
  50. data/lib/net/ssh/test/extensions.rb +148 -146
  51. data/lib/net/ssh/test/kex.rb +35 -31
  52. data/lib/net/ssh/test/local_packet.rb +48 -44
  53. data/lib/net/ssh/test/packet.rb +87 -84
  54. data/lib/net/ssh/test/remote_packet.rb +35 -31
  55. data/lib/net/ssh/test/script.rb +173 -171
  56. data/lib/net/ssh/test/socket.rb +59 -55
  57. data/lib/net/ssh/transport/algorithms.rb +413 -412
  58. data/lib/net/ssh/transport/cipher_factory.rb +108 -105
  59. data/lib/net/ssh/transport/constants.rb +35 -31
  60. data/lib/net/ssh/transport/ctr.rb +1 -1
  61. data/lib/net/ssh/transport/hmac.rb +1 -1
  62. data/lib/net/ssh/transport/hmac/abstract.rb +67 -64
  63. data/lib/net/ssh/transport/hmac/sha2_256_96.rb +1 -1
  64. data/lib/net/ssh/transport/hmac/sha2_512_96.rb +1 -1
  65. data/lib/net/ssh/transport/identity_cipher.rb +55 -51
  66. data/lib/net/ssh/transport/kex.rb +2 -4
  67. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +47 -40
  68. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +201 -197
  69. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +53 -56
  70. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +94 -87
  71. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp384.rb +17 -10
  72. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp521.rb +17 -10
  73. data/lib/net/ssh/transport/key_expander.rb +29 -25
  74. data/lib/net/ssh/transport/openssl.rb +17 -30
  75. data/lib/net/ssh/transport/packet_stream.rb +193 -192
  76. data/lib/net/ssh/transport/server_version.rb +64 -66
  77. data/lib/net/ssh/transport/session.rb +286 -284
  78. data/lib/net/ssh/transport/state.rb +198 -196
  79. data/lib/net/ssh/verifiers/lenient.rb +29 -25
  80. data/lib/net/ssh/verifiers/null.rb +13 -9
  81. data/lib/net/ssh/verifiers/secure.rb +45 -45
  82. data/lib/net/ssh/verifiers/strict.rb +20 -16
  83. data/lib/net/ssh/version.rb +55 -53
  84. data/net-ssh.gemspec +4 -4
  85. data/support/ssh_tunnel_bug.rb +2 -2
  86. metadata +25 -24
  87. metadata.gz.sig +0 -0
@@ -6,7 +6,7 @@ module Net::SSH::Transport::HMAC
6
6
  # The SHA256-96 HMAC algorithm. This returns only the first 12 bytes of
7
7
  # the digest.
8
8
  class SHA2_256_96 < SHA2_256
9
- mac_length 12
9
+ mac_length 12
10
10
  end
11
11
  end
12
12
 
@@ -6,7 +6,7 @@ module Net::SSH::Transport::HMAC
6
6
  # The SHA2-512-96 HMAC algorithm. This returns only the first 12 bytes of
7
7
  # the digest.
8
8
  class SHA2_512_96 < SHA2_512
9
- mac_length 12
9
+ mac_length 12
10
10
  end
11
11
  end
12
12
 
@@ -1,55 +1,59 @@
1
- module Net; module SSH; module Transport
2
-
3
- # A cipher that does nothing but pass the data through, unchanged. This
4
- # keeps things in the code nice and clean when a cipher has not yet been
5
- # determined (i.e., during key exchange).
6
- class IdentityCipher
7
- class <<self
8
- # A default block size of 8 is required by the SSH2 protocol.
9
- def block_size
10
- 8
11
- end
12
-
13
- # Returns an arbitrary integer.
14
- def iv_len
15
- 4
16
- end
17
-
18
- # Does nothing. Returns self.
19
- def encrypt
20
- self
21
- end
22
-
23
- # Does nothing. Returns self.
24
- def decrypt
25
- self
26
- end
27
-
28
- # Passes its single argument through unchanged.
29
- def update(text)
30
- text
1
+ module Net
2
+ module SSH
3
+ module Transport
4
+
5
+ # A cipher that does nothing but pass the data through, unchanged. This
6
+ # keeps things in the code nice and clean when a cipher has not yet been
7
+ # determined (i.e., during key exchange).
8
+ class IdentityCipher
9
+ class <<self
10
+ # A default block size of 8 is required by the SSH2 protocol.
11
+ def block_size
12
+ 8
13
+ end
14
+
15
+ # Returns an arbitrary integer.
16
+ def iv_len
17
+ 4
18
+ end
19
+
20
+ # Does nothing. Returns self.
21
+ def encrypt
22
+ self
23
+ end
24
+
25
+ # Does nothing. Returns self.
26
+ def decrypt
27
+ self
28
+ end
29
+
30
+ # Passes its single argument through unchanged.
31
+ def update(text)
32
+ text
33
+ end
34
+
35
+ # Returns the empty string.
36
+ def final
37
+ ""
38
+ end
39
+
40
+ # The name of this cipher, which is "identity".
41
+ def name
42
+ "identity"
43
+ end
44
+
45
+ # Does nothing. Returns nil.
46
+ def iv=(v)
47
+ nil
48
+ end
49
+
50
+ # Does nothing. Returns self.
51
+ def reset
52
+ self
53
+ end
54
+ end
31
55
  end
32
56
 
33
- # Returns the empty string.
34
- def final
35
- ""
36
- end
37
-
38
- # The name of this cipher, which is "identity".
39
- def name
40
- "identity"
41
- end
42
-
43
- # Does nothing. Returns nil.
44
- def iv=(v)
45
- nil
46
- end
47
-
48
- # Does nothing. Returns self.
49
- def reset
50
- self
51
- end
52
57
  end
53
58
  end
54
-
55
- end; end; end
59
+ end
@@ -10,11 +10,9 @@ module Net::SSH::Transport
10
10
  MAP = {
11
11
  'diffie-hellman-group-exchange-sha1' => DiffieHellmanGroupExchangeSHA1,
12
12
  'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1,
13
- 'diffie-hellman-group14-sha1' => DiffieHellmanGroup14SHA1,
13
+ 'diffie-hellman-group14-sha1' => DiffieHellmanGroup14SHA1
14
14
  }
15
- if defined?(DiffieHellmanGroupExchangeSHA256)
16
- MAP['diffie-hellman-group-exchange-sha256'] = DiffieHellmanGroupExchangeSHA256
17
- end
15
+ MAP['diffie-hellman-group-exchange-sha256'] = DiffieHellmanGroupExchangeSHA256 if defined?(DiffieHellmanGroupExchangeSHA256)
18
16
  if defined?(OpenSSL::PKey::EC)
19
17
  require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
20
18
  require 'net/ssh/transport/kex/ecdh_sha2_nistp384'
@@ -1,44 +1,51 @@
1
1
  require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
2
2
 
3
- module Net; module SSH; module Transport; module Kex
4
-
5
- # A key-exchange service implementing the "diffie-hellman-group14-sha1"
6
- # key-exchange algorithm. (defined in RFC 4253)
7
- class DiffieHellmanGroup14SHA1 < DiffieHellmanGroup1SHA1
8
- include Constants, Loggable
9
-
10
- # The value of 'P', as a string, in hexadecimal
11
- P_s = "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" +
12
- "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" +
13
- "020BBEA6" "3B139B22" "514A0879" "8E3404DD" +
14
- "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" +
15
- "4FE1356D" "6D51C245" "E485B576" "625E7EC6" +
16
- "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" +
17
- "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" +
18
- "49286651" "ECE45B3D" "C2007CB8" "A163BF05" +
19
- "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" +
20
- "83655D23" "DCA3AD96" "1C62F356" "208552BB" +
21
- "9ED52907" "7096966D" "670C354E" "4ABC9804" +
22
- "F1746C08" "CA18217C" "32905E46" "2E36CE3B" +
23
- "E39E772C" "180E8603" "9B2783A2" "EC07A28F" +
24
- "B5C55DF0" "6F4C52C9" "DE2BCBF6" "95581718" +
25
- "3995497C" "EA956AE5" "15D22618" "98FA0510" +
26
- "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"
27
-
28
- # The radix in which P_s represents the value of P
29
- P_r = 16
30
-
31
- # The group constant
32
- G = 2
33
-
34
- private
35
-
36
- def get_p
37
- OpenSSL::BN.new(P_s, P_r)
38
- end
39
-
40
- def get_g
41
- G
3
+ module Net
4
+ module SSH
5
+ module Transport
6
+ module Kex
7
+
8
+ # A key-exchange service implementing the "diffie-hellman-group14-sha1"
9
+ # key-exchange algorithm. (defined in RFC 4253)
10
+ class DiffieHellmanGroup14SHA1 < DiffieHellmanGroup1SHA1
11
+ include Loggable
12
+ include Constants
13
+
14
+ # The value of 'P', as a string, in hexadecimal
15
+ P_s = "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" +
16
+ "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" +
17
+ "020BBEA6" "3B139B22" "514A0879" "8E3404DD" +
18
+ "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" +
19
+ "4FE1356D" "6D51C245" "E485B576" "625E7EC6" +
20
+ "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" +
21
+ "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" +
22
+ "49286651" "ECE45B3D" "C2007CB8" "A163BF05" +
23
+ "98DA4836" "1C55D39A" "69163FA8" "FD24CF5F" +
24
+ "83655D23" "DCA3AD96" "1C62F356" "208552BB" +
25
+ "9ED52907" "7096966D" "670C354E" "4ABC9804" +
26
+ "F1746C08" "CA18217C" "32905E46" "2E36CE3B" +
27
+ "E39E772C" "180E8603" "9B2783A2" "EC07A28F" +
28
+ "B5C55DF0" "6F4C52C9" "DE2BCBF6" "95581718" +
29
+ "3995497C" "EA956AE5" "15D22618" "98FA0510" +
30
+ "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"
31
+
32
+ # The radix in which P_s represents the value of P
33
+ P_r = 16
34
+
35
+ # The group constant
36
+ G = 2
37
+
38
+ private
39
+
40
+ def get_p
41
+ OpenSSL::BN.new(P_s, P_r)
42
+ end
43
+
44
+ def get_g
45
+ G
46
+ end
47
+ end
48
+ end
42
49
  end
43
50
  end
44
- end; end; end; end
51
+ end
@@ -4,224 +4,228 @@ require 'net/ssh/loggable'
4
4
  require 'net/ssh/transport/openssl'
5
5
  require 'net/ssh/transport/constants'
6
6
 
7
- module Net; module SSH; module Transport; module Kex
8
-
9
- # A key-exchange service implementing the "diffie-hellman-group1-sha1"
10
- # key-exchange algorithm.
11
- class DiffieHellmanGroup1SHA1
12
- include Constants, Loggable
13
-
14
- # The value of 'P', as a string, in hexadecimal
15
- P_s = "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" +
16
- "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" +
17
- "020BBEA6" "3B139B22" "514A0879" "8E3404DD" +
18
- "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" +
19
- "4FE1356D" "6D51C245" "E485B576" "625E7EC6" +
20
- "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" +
21
- "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" +
22
- "49286651" "ECE65381" "FFFFFFFF" "FFFFFFFF"
23
-
24
- # The radix in which P_s represents the value of P
25
- P_r = 16
26
-
27
- # The group constant
28
- G = 2
29
-
30
- attr_reader :p
31
- attr_reader :g
32
- attr_reader :digester
33
- attr_reader :algorithms
34
- attr_reader :connection
35
- attr_reader :data
36
- attr_reader :dh
37
-
38
- # Create a new instance of the DiffieHellmanGroup1SHA1 algorithm.
39
- # The data is a Hash of symbols representing information
40
- # required by this algorithm, which was acquired during earlier
41
- # processing.
42
- def initialize(algorithms, connection, data)
43
- @p = get_p
44
- @g = get_g
45
-
46
- @digester = OpenSSL::Digest::SHA1
47
- @algorithms = algorithms
48
- @connection = connection
49
-
50
- @data = data.dup
51
- @dh = generate_key
52
- @logger = @data.delete(:logger)
53
- end
7
+ module Net
8
+ module SSH
9
+ module Transport
10
+ module Kex
11
+
12
+ # A key-exchange service implementing the "diffie-hellman-group1-sha1"
13
+ # key-exchange algorithm.
14
+ class DiffieHellmanGroup1SHA1
15
+ include Loggable
16
+ include Constants
17
+
18
+ # The value of 'P', as a string, in hexadecimal
19
+ P_s = "FFFFFFFF" "FFFFFFFF" "C90FDAA2" "2168C234" +
20
+ "C4C6628B" "80DC1CD1" "29024E08" "8A67CC74" +
21
+ "020BBEA6" "3B139B22" "514A0879" "8E3404DD" +
22
+ "EF9519B3" "CD3A431B" "302B0A6D" "F25F1437" +
23
+ "4FE1356D" "6D51C245" "E485B576" "625E7EC6" +
24
+ "F44C42E9" "A637ED6B" "0BFF5CB6" "F406B7ED" +
25
+ "EE386BFB" "5A899FA5" "AE9F2411" "7C4B1FE6" +
26
+ "49286651" "ECE65381" "FFFFFFFF" "FFFFFFFF"
27
+
28
+ # The radix in which P_s represents the value of P
29
+ P_r = 16
30
+
31
+ # The group constant
32
+ G = 2
33
+
34
+ attr_reader :p
35
+ attr_reader :g
36
+ attr_reader :digester
37
+ attr_reader :algorithms
38
+ attr_reader :connection
39
+ attr_reader :data
40
+ attr_reader :dh
41
+
42
+ # Create a new instance of the DiffieHellmanGroup1SHA1 algorithm.
43
+ # The data is a Hash of symbols representing information
44
+ # required by this algorithm, which was acquired during earlier
45
+ # processing.
46
+ def initialize(algorithms, connection, data)
47
+ @p = get_p
48
+ @g = get_g
49
+
50
+ @digester = OpenSSL::Digest::SHA1
51
+ @algorithms = algorithms
52
+ @connection = connection
53
+
54
+ @data = data.dup
55
+ @dh = generate_key
56
+ @logger = @data.delete(:logger)
57
+ end
54
58
 
55
- # Perform the key-exchange for the given session, with the given
56
- # data. This method will return a hash consisting of the
57
- # following keys:
58
- #
59
- # * :session_id
60
- # * :server_key
61
- # * :shared_secret
62
- # * :hashing_algorithm
63
- #
64
- # The caller is expected to be able to understand how to use these
65
- # deliverables.
66
- def exchange_keys
67
- result = send_kexinit
68
- verify_server_key(result[:server_key])
69
- session_id = verify_signature(result)
70
- confirm_newkeys
71
-
72
- return { session_id: session_id,
73
- server_key: result[:server_key],
74
- shared_secret: result[:shared_secret],
75
- hashing_algorithm: digester }
76
- end
59
+ # Perform the key-exchange for the given session, with the given
60
+ # data. This method will return a hash consisting of the
61
+ # following keys:
62
+ #
63
+ # * :session_id
64
+ # * :server_key
65
+ # * :shared_secret
66
+ # * :hashing_algorithm
67
+ #
68
+ # The caller is expected to be able to understand how to use these
69
+ # deliverables.
70
+ def exchange_keys
71
+ result = send_kexinit
72
+ verify_server_key(result[:server_key])
73
+ session_id = verify_signature(result)
74
+ confirm_newkeys
75
+
76
+ return { session_id: session_id,
77
+ server_key: result[:server_key],
78
+ shared_secret: result[:shared_secret],
79
+ hashing_algorithm: digester }
80
+ end
77
81
 
78
- private
82
+ private
79
83
 
80
- def get_p
81
- OpenSSL::BN.new(P_s, P_r)
82
- end
83
-
84
- def get_g
85
- G
86
- end
84
+ def get_p
85
+ OpenSSL::BN.new(P_s, P_r)
86
+ end
87
87
 
88
- # Returns the DH key parameters for the current connection.
89
- def get_parameters
90
- [p, g]
91
- end
88
+ def get_g
89
+ G
90
+ end
92
91
 
93
- # Returns the INIT/REPLY constants used by this algorithm.
94
- def get_message_types
95
- [KEXDH_INIT, KEXDH_REPLY]
96
- end
92
+ # Returns the DH key parameters for the current connection.
93
+ def get_parameters
94
+ [p, g]
95
+ end
97
96
 
98
- # Build the signature buffer to use when verifying a signature from
99
- # the server.
100
- def build_signature_buffer(result)
101
- response = Net::SSH::Buffer.new
102
- response.write_string data[:client_version_string],
103
- data[:server_version_string],
104
- data[:client_algorithm_packet],
105
- data[:server_algorithm_packet],
106
- result[:key_blob]
107
- response.write_bignum dh.pub_key,
108
- result[:server_dh_pubkey],
109
- result[:shared_secret]
110
- response
111
- end
97
+ # Returns the INIT/REPLY constants used by this algorithm.
98
+ def get_message_types
99
+ [KEXDH_INIT, KEXDH_REPLY]
100
+ end
112
101
 
113
- # Generate a DH key with a private key consisting of the given
114
- # number of bytes.
115
- def generate_key #:nodoc:
116
- dh = OpenSSL::PKey::DH.new
102
+ # Build the signature buffer to use when verifying a signature from
103
+ # the server.
104
+ def build_signature_buffer(result)
105
+ response = Net::SSH::Buffer.new
106
+ response.write_string data[:client_version_string],
107
+ data[:server_version_string],
108
+ data[:client_algorithm_packet],
109
+ data[:server_algorithm_packet],
110
+ result[:key_blob]
111
+ response.write_bignum dh.pub_key,
112
+ result[:server_dh_pubkey],
113
+ result[:shared_secret]
114
+ response
115
+ end
117
116
 
118
- if dh.respond_to?(:set_pqg)
119
- p, g = get_parameters
120
- dh.set_pqg(p, nil, g)
121
- else
122
- dh.p, dh.g = get_parameters
123
- end
117
+ # Generate a DH key with a private key consisting of the given
118
+ # number of bytes.
119
+ def generate_key #:nodoc:
120
+ dh = OpenSSL::PKey::DH.new
121
+
122
+ if dh.respond_to?(:set_pqg)
123
+ p, g = get_parameters
124
+ dh.set_pqg(p, nil, g)
125
+ else
126
+ dh.p, dh.g = get_parameters
127
+ end
128
+
129
+ dh.generate_key!
130
+ until dh.valid? && dh.priv_key.num_bytes == data[:need_bytes]
131
+ if dh.respond_to?(:set_key)
132
+ dh.set_key(nil, OpenSSL::BN.rand(data[:need_bytes] * 8))
133
+ else
134
+ dh.priv_key = OpenSSL::BN.rand(data[:need_bytes] * 8)
135
+ end
136
+ dh.generate_key!
137
+ end
138
+ dh
139
+ end
124
140
 
125
- dh.generate_key!
126
- until dh.valid? && dh.priv_key.num_bytes == data[:need_bytes]
127
- if dh.respond_to?(:set_key)
128
- dh.set_key(nil, OpenSSL::BN.rand(data[:need_bytes] * 8))
129
- else
130
- dh.priv_key = OpenSSL::BN.rand(data[:need_bytes] * 8)
141
+ # Send the KEXDH_INIT message, and expect the KEXDH_REPLY. Return the
142
+ # resulting buffer.
143
+ #
144
+ # Parse the buffer from a KEXDH_REPLY message, returning a hash of
145
+ # the extracted values.
146
+ def send_kexinit #:nodoc:
147
+ init, reply = get_message_types
148
+
149
+ # send the KEXDH_INIT message
150
+ buffer = Net::SSH::Buffer.from(:byte, init, :bignum, dh.pub_key)
151
+ connection.send_message(buffer)
152
+
153
+ # expect the KEXDH_REPLY message
154
+ buffer = connection.next_message
155
+ raise Net::SSH::Exception, "expected REPLY" unless buffer.type == reply
156
+
157
+ result = Hash.new
158
+
159
+ result[:key_blob] = buffer.read_string
160
+ result[:server_key] = Net::SSH::Buffer.new(result[:key_blob]).read_key
161
+ result[:server_dh_pubkey] = buffer.read_bignum
162
+ result[:shared_secret] = OpenSSL::BN.new(dh.compute_key(result[:server_dh_pubkey]), 2)
163
+
164
+ sig_buffer = Net::SSH::Buffer.new(buffer.read_string)
165
+ sig_type = sig_buffer.read_string
166
+ if sig_type != algorithms.host_key
167
+ raise Net::SSH::Exception,
168
+ "host key algorithm mismatch for signature " +
169
+ "'#{sig_type}' != '#{algorithms.host_key}'"
170
+ end
171
+ result[:server_sig] = sig_buffer.read_string
172
+
173
+ return result
131
174
  end
132
- dh.generate_key!
133
- end
134
- dh
135
- end
136
175
 
137
- # Send the KEXDH_INIT message, and expect the KEXDH_REPLY. Return the
138
- # resulting buffer.
139
- #
140
- # Parse the buffer from a KEXDH_REPLY message, returning a hash of
141
- # the extracted values.
142
- def send_kexinit #:nodoc:
143
- init, reply = get_message_types
144
-
145
- # send the KEXDH_INIT message
146
- buffer = Net::SSH::Buffer.from(:byte, init, :bignum, dh.pub_key)
147
- connection.send_message(buffer)
148
-
149
- # expect the KEXDH_REPLY message
150
- buffer = connection.next_message
151
- raise Net::SSH::Exception, "expected REPLY" unless buffer.type == reply
152
-
153
- result = Hash.new
154
-
155
- result[:key_blob] = buffer.read_string
156
- result[:server_key] = Net::SSH::Buffer.new(result[:key_blob]).read_key
157
- result[:server_dh_pubkey] = buffer.read_bignum
158
- result[:shared_secret] = OpenSSL::BN.new(dh.compute_key(result[:server_dh_pubkey]), 2)
159
-
160
- sig_buffer = Net::SSH::Buffer.new(buffer.read_string)
161
- sig_type = sig_buffer.read_string
162
- if sig_type != algorithms.host_key
163
- raise Net::SSH::Exception,
164
- "host key algorithm mismatch for signature " +
165
- "'#{sig_type}' != '#{algorithms.host_key}'"
166
- end
167
- result[:server_sig] = sig_buffer.read_string
176
+ # Verify that the given key is of the expected type, and that it
177
+ # really is the key for the session's host. Raise Net::SSH::Exception
178
+ # if it is not.
179
+ def verify_server_key(key) #:nodoc:
180
+ if key.ssh_type != algorithms.host_key
181
+ raise Net::SSH::Exception,
182
+ "host key algorithm mismatch " +
183
+ "'#{key.ssh_type}' != '#{algorithms.host_key}'"
184
+ end
168
185
 
169
- return result
170
- end
186
+ blob, fingerprint = generate_key_fingerprint(key)
171
187
 
172
- # Verify that the given key is of the expected type, and that it
173
- # really is the key for the session's host. Raise Net::SSH::Exception
174
- # if it is not.
175
- def verify_server_key(key) #:nodoc:
176
- if key.ssh_type != algorithms.host_key
177
- raise Net::SSH::Exception,
178
- "host key algorithm mismatch " +
179
- "'#{key.ssh_type}' != '#{algorithms.host_key}'"
180
- end
188
+ raise Net::SSH::Exception, "host key verification failed" unless connection.host_key_verifier.verify(key: key, key_blob: blob, fingerprint: fingerprint, session: connection)
189
+ end
181
190
 
182
- blob, fingerprint = generate_key_fingerprint(key)
191
+ def generate_key_fingerprint(key)
192
+ blob = Net::SSH::Buffer.from(:key, key).to_s
183
193
 
184
- unless connection.host_key_verifier.verify(key: key, key_blob: blob, fingerprint: fingerprint, session: connection)
185
- raise Net::SSH::Exception, "host key verification failed"
186
- end
187
- end
194
+ fingerprint = Net::SSH::Authentication::PubKeyFingerprint.fingerprint(blob, @connection.options[:fingerprint_hash] || 'SHA256')
188
195
 
189
- def generate_key_fingerprint(key)
190
- blob = Net::SSH::Buffer.from(:key, key).to_s
191
- fingerprint = OpenSSL::Digest::MD5.hexdigest(blob).scan(/../).join(":")
196
+ [blob, fingerprint]
197
+ rescue ::Exception => e
198
+ [nil, "(could not generate fingerprint: #{e.message})"]
199
+ end
192
200
 
193
- [blob, fingerprint]
194
- rescue ::Exception => e
195
- [nil, "(could not generate fingerprint: #{e.message})"]
196
- end
201
+ # Verify the signature that was received. Raise Net::SSH::Exception
202
+ # if the signature could not be verified. Otherwise, return the new
203
+ # session-id.
204
+ def verify_signature(result) #:nodoc:
205
+ response = build_signature_buffer(result)
197
206
 
198
- # Verify the signature that was received. Raise Net::SSH::Exception
199
- # if the signature could not be verified. Otherwise, return the new
200
- # session-id.
201
- def verify_signature(result) #:nodoc:
202
- response = build_signature_buffer(result)
207
+ hash = @digester.digest(response.to_s)
203
208
 
204
- hash = @digester.digest(response.to_s)
209
+ raise Net::SSH::Exception, "could not verify server signature" unless result[:server_key].ssh_do_verify(result[:server_sig], hash)
205
210
 
206
- unless result[:server_key].ssh_do_verify(result[:server_sig], hash)
207
- raise Net::SSH::Exception, "could not verify server signature"
208
- end
211
+ return hash
212
+ end
209
213
 
210
- return hash
211
- end
214
+ # Send the NEWKEYS message, and expect the NEWKEYS message in
215
+ # reply.
216
+ def confirm_newkeys #:nodoc:
217
+ # send own NEWKEYS message first (the wodSSHServer won't send first)
218
+ response = Net::SSH::Buffer.new
219
+ response.write_byte(NEWKEYS)
220
+ connection.send_message(response)
221
+
222
+ # wait for the server's NEWKEYS message
223
+ buffer = connection.next_message
224
+ raise Net::SSH::Exception, "expected NEWKEYS" unless buffer.type == NEWKEYS
225
+ end
226
+ end
212
227
 
213
- # Send the NEWKEYS message, and expect the NEWKEYS message in
214
- # reply.
215
- def confirm_newkeys #:nodoc:
216
- # send own NEWKEYS message first (the wodSSHServer won't send first)
217
- response = Net::SSH::Buffer.new
218
- response.write_byte(NEWKEYS)
219
- connection.send_message(response)
220
-
221
- # wait for the server's NEWKEYS message
222
- buffer = connection.next_message
223
- raise Net::SSH::Exception, "expected NEWKEYS" unless buffer.type == NEWKEYS
224
228
  end
229
+ end
225
230
  end
226
-
227
- end; end; end; end
231
+ end