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
@@ -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