net-ssh 5.0.0.beta1 → 5.0.0.beta2

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 (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
@@ -3,114 +3,117 @@ require 'net/ssh/transport/ctr.rb'
3
3
  require 'net/ssh/transport/key_expander'
4
4
  require 'net/ssh/transport/identity_cipher'
5
5
 
6
- module Net; module SSH; module Transport
7
-
8
- # Implements a factory of OpenSSL cipher algorithms.
9
- class CipherFactory
10
- # Maps the SSH name of a cipher to it's corresponding OpenSSL name
11
- SSH_TO_OSSL = {
12
- "3des-cbc" => "des-ede3-cbc",
13
- "blowfish-cbc" => "bf-cbc",
14
- "aes256-cbc" => "aes-256-cbc",
15
- "aes192-cbc" => "aes-192-cbc",
16
- "aes128-cbc" => "aes-128-cbc",
17
- "idea-cbc" => "idea-cbc",
18
- "cast128-cbc" => "cast-cbc",
19
- "rijndael-cbc@lysator.liu.se" => "aes-256-cbc",
20
- "arcfour128" => "rc4",
21
- "arcfour256" => "rc4",
22
- "arcfour512" => "rc4",
23
- "arcfour" => "rc4",
24
-
25
- "3des-ctr" => "des-ede3",
26
- "blowfish-ctr" => "bf-ecb",
27
-
28
- "aes256-ctr" => "aes-256-ctr",
29
- "aes192-ctr" => "aes-192-ctr",
30
- "aes128-ctr" => "aes-128-ctr",
31
- "cast128-ctr" => "cast5-ecb",
32
-
33
- "none" => "none",
34
- }
35
-
36
- # Ruby's OpenSSL bindings always return a key length of 16 for RC4 ciphers
37
- # resulting in the error: OpenSSL::CipherError: key length too short.
38
- # The following ciphers will override this key length.
39
- KEY_LEN_OVERRIDE = {
40
- "arcfour256" => 32,
41
- "arcfour512" => 64
42
- }
43
-
44
-
45
- # Returns true if the underlying OpenSSL library supports the given cipher,
46
- # and false otherwise.
47
- def self.supported?(name)
48
- ossl_name = SSH_TO_OSSL[name] or raise NotImplementedError, "unimplemented cipher `#{name}'"
49
- return true if ossl_name == "none"
50
- return OpenSSL::Cipher.ciphers.include?(ossl_name)
51
- end
52
-
53
- # Retrieves a new instance of the named algorithm. The new instance
54
- # will be initialized using an iv and key generated from the given
55
- # iv, key, shared, hash and digester values. Additionally, the
56
- # cipher will be put into encryption or decryption mode, based on the
57
- # value of the +encrypt+ parameter.
58
- def self.get(name, options={})
59
- ossl_name = SSH_TO_OSSL[name] or raise NotImplementedError, "unimplemented cipher `#{name}'"
60
- return IdentityCipher if ossl_name == "none"
61
- cipher = OpenSSL::Cipher.new(ossl_name)
62
-
63
- cipher.send(options[:encrypt] ? :encrypt : :decrypt)
64
-
65
- cipher.padding = 0
66
-
67
- if name =~ /-ctr(@openssh.org)?$/
68
- if ossl_name !~ /-ctr/
69
- cipher.extend(Net::SSH::Transport::CTR)
70
- else
71
- cipher = Net::SSH::Transport::OpenSSLAESCTR.new(cipher)
6
+ module Net
7
+ module SSH
8
+ module Transport
9
+
10
+ # Implements a factory of OpenSSL cipher algorithms.
11
+ class CipherFactory
12
+ # Maps the SSH name of a cipher to it's corresponding OpenSSL name
13
+ SSH_TO_OSSL = {
14
+ "3des-cbc" => "des-ede3-cbc",
15
+ "blowfish-cbc" => "bf-cbc",
16
+ "aes256-cbc" => "aes-256-cbc",
17
+ "aes192-cbc" => "aes-192-cbc",
18
+ "aes128-cbc" => "aes-128-cbc",
19
+ "idea-cbc" => "idea-cbc",
20
+ "cast128-cbc" => "cast-cbc",
21
+ "rijndael-cbc@lysator.liu.se" => "aes-256-cbc",
22
+ "arcfour128" => "rc4",
23
+ "arcfour256" => "rc4",
24
+ "arcfour512" => "rc4",
25
+ "arcfour" => "rc4",
26
+
27
+ "3des-ctr" => "des-ede3",
28
+ "blowfish-ctr" => "bf-ecb",
29
+
30
+ "aes256-ctr" => "aes-256-ctr",
31
+ "aes192-ctr" => "aes-192-ctr",
32
+ "aes128-ctr" => "aes-128-ctr",
33
+ "cast128-ctr" => "cast5-ecb",
34
+
35
+ "none" => "none"
36
+ }
37
+
38
+ # Ruby's OpenSSL bindings always return a key length of 16 for RC4 ciphers
39
+ # resulting in the error: OpenSSL::CipherError: key length too short.
40
+ # The following ciphers will override this key length.
41
+ KEY_LEN_OVERRIDE = {
42
+ "arcfour256" => 32,
43
+ "arcfour512" => 64
44
+ }
45
+
46
+ # Returns true if the underlying OpenSSL library supports the given cipher,
47
+ # and false otherwise.
48
+ def self.supported?(name)
49
+ ossl_name = SSH_TO_OSSL[name] or raise NotImplementedError, "unimplemented cipher `#{name}'"
50
+ return true if ossl_name == "none"
51
+ return OpenSSL::Cipher.ciphers.include?(ossl_name)
72
52
  end
73
- end
74
- cipher.iv = Net::SSH::Transport::KeyExpander.expand_key(cipher.iv_len, options[:iv], options) if ossl_name != "rc4"
75
-
76
- key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len
77
- cipher.key_len = key_len
78
- cipher.key = Net::SSH::Transport::KeyExpander.expand_key(key_len, options[:key], options)
79
- cipher.update(" " * 1536) if (ossl_name == "rc4" && name != "arcfour")
80
-
81
- return cipher
82
- end
83
-
84
- # Returns a two-element array containing the [ key-length,
85
- # block-size ] for the named cipher algorithm. If the cipher
86
- # algorithm is unknown, or is "none", 0 is returned for both elements
87
- # of the tuple.
88
- # if :iv_len option is supplied the third return value will be ivlen
89
- def self.get_lengths(name, options = {})
90
- ossl_name = SSH_TO_OSSL[name]
91
- if ossl_name.nil? || ossl_name == "none"
92
- result = [0, 0]
93
- result << 0 if options[:iv_len]
94
- else
95
- cipher = OpenSSL::Cipher.new(ossl_name)
96
- key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len
97
- cipher.key_len = key_len
98
-
99
- block_size =
100
- case ossl_name
101
- when "rc4"
102
- 8
103
- when /\-ctr/
104
- Net::SSH::Transport::OpenSSLAESCTR.block_size
53
+
54
+ # Retrieves a new instance of the named algorithm. The new instance
55
+ # will be initialized using an iv and key generated from the given
56
+ # iv, key, shared, hash and digester values. Additionally, the
57
+ # cipher will be put into encryption or decryption mode, based on the
58
+ # value of the +encrypt+ parameter.
59
+ def self.get(name, options={})
60
+ ossl_name = SSH_TO_OSSL[name] or raise NotImplementedError, "unimplemented cipher `#{name}'"
61
+ return IdentityCipher if ossl_name == "none"
62
+ cipher = OpenSSL::Cipher.new(ossl_name)
63
+
64
+ cipher.send(options[:encrypt] ? :encrypt : :decrypt)
65
+
66
+ cipher.padding = 0
67
+
68
+ if name =~ /-ctr(@openssh.org)?$/
69
+ if ossl_name !~ /-ctr/
70
+ cipher.extend(Net::SSH::Transport::CTR)
71
+ else
72
+ cipher = Net::SSH::Transport::OpenSSLAESCTR.new(cipher)
73
+ end
74
+ end
75
+ cipher.iv = Net::SSH::Transport::KeyExpander.expand_key(cipher.iv_len, options[:iv], options) if ossl_name != "rc4"
76
+
77
+ key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len
78
+ cipher.key_len = key_len
79
+ cipher.key = Net::SSH::Transport::KeyExpander.expand_key(key_len, options[:key], options)
80
+ cipher.update(" " * 1536) if (ossl_name == "rc4" && name != "arcfour")
81
+
82
+ return cipher
83
+ end
84
+
85
+ # Returns a two-element array containing the [ key-length,
86
+ # block-size ] for the named cipher algorithm. If the cipher
87
+ # algorithm is unknown, or is "none", 0 is returned for both elements
88
+ # of the tuple.
89
+ # if :iv_len option is supplied the third return value will be ivlen
90
+ def self.get_lengths(name, options = {})
91
+ ossl_name = SSH_TO_OSSL[name]
92
+ if ossl_name.nil? || ossl_name == "none"
93
+ result = [0, 0]
94
+ result << 0 if options[:iv_len]
105
95
  else
106
- cipher.block_size
96
+ cipher = OpenSSL::Cipher.new(ossl_name)
97
+ key_len = KEY_LEN_OVERRIDE[name] || cipher.key_len
98
+ cipher.key_len = key_len
99
+
100
+ block_size =
101
+ case ossl_name
102
+ when "rc4"
103
+ 8
104
+ when /\-ctr/
105
+ Net::SSH::Transport::OpenSSLAESCTR.block_size
106
+ else
107
+ cipher.block_size
108
+ end
109
+
110
+ result = [key_len, block_size]
111
+ result << cipher.iv_len if options[:iv_len]
107
112
  end
108
-
109
- result = [key_len, block_size]
110
- result << cipher.iv_len if options[:iv_len]
113
+ result
114
+ end
111
115
  end
112
- result
116
+
113
117
  end
114
118
  end
115
-
116
- end; end; end
119
+ end
@@ -1,32 +1,36 @@
1
- module Net; module SSH; module Transport
2
- module Constants
3
-
4
- #--
5
- # Transport layer generic messages
6
- #++
7
-
8
- DISCONNECT = 1
9
- IGNORE = 2
10
- UNIMPLEMENTED = 3
11
- DEBUG = 4
12
- SERVICE_REQUEST = 5
13
- SERVICE_ACCEPT = 6
14
-
15
- #--
16
- # Algorithm negotiation messages
17
- #++
18
-
19
- KEXINIT = 20
20
- NEWKEYS = 21
21
-
22
- #--
23
- # Key exchange method specific messages
24
- #++
25
-
26
- KEXDH_INIT = 30
27
- KEXDH_REPLY = 31
28
-
29
- KEXECDH_INIT = 30
30
- KEXECDH_REPLY = 31
1
+ module Net
2
+ module SSH
3
+ module Transport
4
+ module Constants
5
+
6
+ #--
7
+ # Transport layer generic messages
8
+ #++
9
+
10
+ DISCONNECT = 1
11
+ IGNORE = 2
12
+ UNIMPLEMENTED = 3
13
+ DEBUG = 4
14
+ SERVICE_REQUEST = 5
15
+ SERVICE_ACCEPT = 6
16
+
17
+ #--
18
+ # Algorithm negotiation messages
19
+ #++
20
+
21
+ KEXINIT = 20
22
+ NEWKEYS = 21
23
+
24
+ #--
25
+ # Key exchange method specific messages
26
+ #++
27
+
28
+ KEXDH_INIT = 30
29
+ KEXDH_REPLY = 31
30
+
31
+ KEXECDH_INIT = 30
32
+ KEXECDH_REPLY = 31
33
+ end
34
+ end
31
35
  end
32
- end; end; end
36
+ end
@@ -101,7 +101,7 @@ module Net::SSH::Transport
101
101
 
102
102
  def xor!(s1, s2)
103
103
  s = []
104
- s1.unpack('Q*').zip(s2.unpack('Q*')) {|a,b| s.push(a^b) }
104
+ s1.unpack('Q*').zip(s2.unpack('Q*')) {|a,b| s.push(a ^ b) }
105
105
  s.pack('Q*')
106
106
  end
107
107
  singleton_class.send(:private, :xor!)
@@ -21,7 +21,7 @@ module Net::SSH::Transport::HMAC
21
21
  'hmac-sha1-96' => SHA1_96,
22
22
  'hmac-ripemd160' => RIPEMD160,
23
23
  'hmac-ripemd160@openssh.com' => RIPEMD160,
24
- 'none' => None
24
+ 'none' => None
25
25
  }
26
26
 
27
27
  # add mapping to sha2 hmac algorithms if they're available
@@ -1,79 +1,82 @@
1
1
  require 'openssl'
2
2
  require 'openssl/digest'
3
3
 
4
- module Net; module SSH; module Transport; module HMAC
4
+ module Net
5
+ module SSH
6
+ module Transport
7
+ module HMAC
5
8
 
6
- # The base class of all OpenSSL-based HMAC algorithm wrappers.
7
- class Abstract
9
+ # The base class of all OpenSSL-based HMAC algorithm wrappers.
10
+ class Abstract
11
+ class <<self
12
+ def key_length(*v)
13
+ @key_length = nil if !defined?(@key_length)
14
+ if v.empty?
15
+ @key_length = superclass.key_length if @key_length.nil? && superclass.respond_to?(:key_length)
16
+ return @key_length
17
+ elsif v.length == 1
18
+ @key_length = v.first
19
+ else
20
+ raise ArgumentError, "wrong number of arguments (#{v.length} for 1)"
21
+ end
22
+ end
8
23
 
9
- class <<self
10
- def key_length(*v)
11
- @key_length = nil if !defined?(@key_length)
12
- if v.empty?
13
- @key_length = superclass.key_length if @key_length.nil? && superclass.respond_to?(:key_length)
14
- return @key_length
15
- elsif v.length == 1
16
- @key_length = v.first
17
- else
18
- raise ArgumentError, "wrong number of arguments (#{v.length} for 1)"
19
- end
20
- end
24
+ def mac_length(*v)
25
+ @mac_length = nil if !defined?(@mac_length)
26
+ if v.empty?
27
+ @mac_length = superclass.mac_length if @mac_length.nil? && superclass.respond_to?(:mac_length)
28
+ return @mac_length
29
+ elsif v.length == 1
30
+ @mac_length = v.first
31
+ else
32
+ raise ArgumentError, "wrong number of arguments (#{v.length} for 1)"
33
+ end
34
+ end
21
35
 
22
- def mac_length(*v)
23
- @mac_length = nil if !defined?(@mac_length)
24
- if v.empty?
25
- @mac_length = superclass.mac_length if @mac_length.nil? && superclass.respond_to?(:mac_length)
26
- return @mac_length
27
- elsif v.length == 1
28
- @mac_length = v.first
29
- else
30
- raise ArgumentError, "wrong number of arguments (#{v.length} for 1)"
31
- end
32
- end
36
+ def digest_class(*v)
37
+ @digest_class = nil if !defined?(@digest_class)
38
+ if v.empty?
39
+ @digest_class = superclass.digest_class if @digest_class.nil? && superclass.respond_to?(:digest_class)
40
+ return @digest_class
41
+ elsif v.length == 1
42
+ @digest_class = v.first
43
+ else
44
+ raise ArgumentError, "wrong number of arguments (#{v.length} for 1)"
45
+ end
46
+ end
47
+ end
33
48
 
34
- def digest_class(*v)
35
- @digest_class = nil if !defined?(@digest_class)
36
- if v.empty?
37
- @digest_class = superclass.digest_class if @digest_class.nil? && superclass.respond_to?(:digest_class)
38
- return @digest_class
39
- elsif v.length == 1
40
- @digest_class = v.first
41
- else
42
- raise ArgumentError, "wrong number of arguments (#{v.length} for 1)"
43
- end
44
- end
45
- end
49
+ def key_length
50
+ self.class.key_length
51
+ end
46
52
 
47
- def key_length
48
- self.class.key_length
49
- end
53
+ def mac_length
54
+ self.class.mac_length
55
+ end
50
56
 
51
- def mac_length
52
- self.class.mac_length
53
- end
57
+ def digest_class
58
+ self.class.digest_class
59
+ end
54
60
 
55
- def digest_class
56
- self.class.digest_class
57
- end
58
-
59
- # The key in use for this instance.
60
- attr_reader :key
61
+ # The key in use for this instance.
62
+ attr_reader :key
61
63
 
62
- def initialize(key=nil)
63
- self.key = key
64
- end
64
+ def initialize(key=nil)
65
+ self.key = key
66
+ end
65
67
 
66
- # Sets the key to the given value, truncating it so that it is the correct
67
- # length.
68
- def key=(value)
69
- @key = value ? value.to_s[0,key_length] : nil
70
- end
68
+ # Sets the key to the given value, truncating it so that it is the correct
69
+ # length.
70
+ def key=(value)
71
+ @key = value ? value.to_s[0,key_length] : nil
72
+ end
71
73
 
72
- # Compute the HMAC digest for the given data string.
73
- def digest(data)
74
- OpenSSL::HMAC.digest(digest_class.new, key, data)[0,mac_length]
74
+ # Compute the HMAC digest for the given data string.
75
+ def digest(data)
76
+ OpenSSL::HMAC.digest(digest_class.new, key, data)[0,mac_length]
77
+ end
78
+ end
79
+ end
75
80
  end
76
-
77
81
  end
78
-
79
- end; end; end; end
82
+ end