net-ssh 6.2.0.rc2 → 6.3.0.beta1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (92) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data.tar.gz.sig +0 -0
  4. data/.github/workflows/ci.yml +27 -10
  5. data/.rubocop.yml +11 -1
  6. data/.rubocop_todo.yml +374 -173
  7. data/.travis.yml +10 -11
  8. data/CHANGES.txt +6 -0
  9. data/Gemfile +2 -0
  10. data/Gemfile.noed25519 +2 -0
  11. data/README.md +2 -2
  12. data/Rakefile +1 -0
  13. data/lib/net/ssh.rb +1 -2
  14. data/lib/net/ssh/authentication/agent.rb +4 -2
  15. data/lib/net/ssh/authentication/certificate.rb +3 -1
  16. data/lib/net/ssh/authentication/constants.rb +0 -1
  17. data/lib/net/ssh/authentication/ed25519.rb +6 -2
  18. data/lib/net/ssh/authentication/ed25519_loader.rb +4 -7
  19. data/lib/net/ssh/authentication/key_manager.rb +28 -29
  20. data/lib/net/ssh/authentication/methods/abstract.rb +0 -1
  21. data/lib/net/ssh/authentication/methods/hostbased.rb +0 -2
  22. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +1 -1
  23. data/lib/net/ssh/authentication/methods/none.rb +5 -8
  24. data/lib/net/ssh/authentication/methods/password.rb +1 -2
  25. data/lib/net/ssh/authentication/methods/publickey.rb +0 -2
  26. data/lib/net/ssh/authentication/pageant.rb +89 -89
  27. data/lib/net/ssh/authentication/session.rb +14 -15
  28. data/lib/net/ssh/buffer.rb +10 -5
  29. data/lib/net/ssh/buffered_io.rb +18 -19
  30. data/lib/net/ssh/config.rb +29 -16
  31. data/lib/net/ssh/connection/channel.rb +71 -69
  32. data/lib/net/ssh/connection/constants.rb +0 -4
  33. data/lib/net/ssh/connection/event_loop.rb +22 -16
  34. data/lib/net/ssh/connection/keepalive.rb +12 -12
  35. data/lib/net/ssh/connection/session.rb +95 -94
  36. data/lib/net/ssh/connection/term.rb +56 -58
  37. data/lib/net/ssh/errors.rb +10 -10
  38. data/lib/net/ssh/key_factory.rb +0 -1
  39. data/lib/net/ssh/known_hosts.rb +79 -11
  40. data/lib/net/ssh/loggable.rb +8 -9
  41. data/lib/net/ssh/packet.rb +1 -1
  42. data/lib/net/ssh/prompt.rb +8 -10
  43. data/lib/net/ssh/proxy/command.rb +1 -1
  44. data/lib/net/ssh/proxy/errors.rb +2 -4
  45. data/lib/net/ssh/proxy/http.rb +17 -19
  46. data/lib/net/ssh/proxy/https.rb +6 -8
  47. data/lib/net/ssh/proxy/jump.rb +8 -10
  48. data/lib/net/ssh/proxy/socks4.rb +1 -3
  49. data/lib/net/ssh/proxy/socks5.rb +2 -4
  50. data/lib/net/ssh/service/forward.rb +3 -3
  51. data/lib/net/ssh/test.rb +1 -2
  52. data/lib/net/ssh/test/channel.rb +20 -22
  53. data/lib/net/ssh/test/extensions.rb +29 -29
  54. data/lib/net/ssh/test/kex.rb +6 -8
  55. data/lib/net/ssh/test/local_packet.rb +0 -2
  56. data/lib/net/ssh/test/packet.rb +2 -2
  57. data/lib/net/ssh/test/remote_packet.rb +5 -7
  58. data/lib/net/ssh/test/script.rb +21 -23
  59. data/lib/net/ssh/test/socket.rb +11 -14
  60. data/lib/net/ssh/transport/algorithms.rb +2 -1
  61. data/lib/net/ssh/transport/cipher_factory.rb +13 -13
  62. data/lib/net/ssh/transport/constants.rb +3 -3
  63. data/lib/net/ssh/transport/ctr.rb +4 -4
  64. data/lib/net/ssh/transport/hmac/abstract.rb +0 -1
  65. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  66. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  67. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  68. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  69. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  70. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  71. data/lib/net/ssh/transport/identity_cipher.rb +10 -12
  72. data/lib/net/ssh/transport/kex.rb +2 -0
  73. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +1 -0
  74. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +4 -4
  75. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  76. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +0 -1
  77. data/lib/net/ssh/transport/key_expander.rb +6 -7
  78. data/lib/net/ssh/transport/openssl.rb +6 -11
  79. data/lib/net/ssh/transport/packet_stream.rb +1 -2
  80. data/lib/net/ssh/transport/server_version.rb +17 -16
  81. data/lib/net/ssh/transport/session.rb +3 -1
  82. data/lib/net/ssh/transport/state.rb +42 -42
  83. data/lib/net/ssh/verifiers/accept_new.rb +0 -2
  84. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +1 -2
  85. data/lib/net/ssh/verifiers/always.rb +6 -4
  86. data/lib/net/ssh/verifiers/never.rb +0 -2
  87. data/lib/net/ssh/version.rb +2 -2
  88. data/net-ssh-public_cert.pem +8 -8
  89. data/net-ssh.gemspec +2 -2
  90. data/support/ssh_tunnel_bug.rb +3 -3
  91. metadata +14 -13
  92. metadata.gz.sig +0 -0
@@ -3,66 +3,63 @@ require 'stringio'
3
3
  require 'net/ssh/test/extensions'
4
4
  require 'net/ssh/test/script'
5
5
 
6
- module Net
7
- module SSH
6
+ module Net
7
+ module SSH
8
8
  module Test
9
-
10
9
  # A mock socket implementation for use in testing. It implements the minimum
11
10
  # necessary interface for interacting with the rest of the Net::SSH::Test
12
11
  # system.
13
12
  class Socket < StringIO
14
13
  attr_reader :host, :port
15
-
14
+
16
15
  # The Net::SSH::Test::Script object in use by this socket. This is the
17
16
  # canonical script instance that should be used for any test depending on
18
17
  # this socket instance.
19
18
  attr_reader :script
20
-
19
+
21
20
  # Create a new test socket. This will also instantiate a new Net::SSH::Test::Script
22
21
  # and seed it with the necessary events to power the initialization of the
23
22
  # connection.
24
23
  def initialize
25
24
  extend(Net::SSH::Transport::PacketStream)
26
25
  super "SSH-2.0-Test\r\n"
27
-
26
+
28
27
  @script = Script.new
29
-
28
+
30
29
  script.sends(:kexinit)
31
30
  script.gets(:kexinit, 1, 2, 3, 4, "test", "ssh-rsa", "none", "none", "none", "none", "none", "none", "", "", false)
32
31
  script.sends(:newkeys)
33
32
  script.gets(:newkeys)
34
33
  end
35
-
34
+
36
35
  # This doesn't actually do anything, since we don't really care what gets
37
36
  # written.
38
37
  def write(data)
39
38
  # black hole, because we don't actually care about what gets written
40
39
  end
41
-
40
+
42
41
  # Allows the socket to also mimic a socket factory, simply returning
43
42
  # +self+.
44
43
  def open(host, port, options={})
45
44
  @host, @port = host, port
46
45
  self
47
46
  end
48
-
47
+
49
48
  # Returns a sockaddr struct for the port and host that were used when the
50
49
  # socket was instantiated.
51
50
  def getpeername
52
51
  ::Socket.sockaddr_in(port, host)
53
52
  end
54
-
53
+
55
54
  # Alias to #read, but never returns nil (returns an empty string instead).
56
55
  def recv(n)
57
56
  read(n) || ""
58
57
  end
59
-
58
+
60
59
  def readpartial(n)
61
60
  recv(n)
62
61
  end
63
-
64
62
  end
65
-
66
63
  end
67
64
  end
68
65
  end
@@ -41,6 +41,7 @@ module Net
41
41
  ecdh-sha2-nistp384
42
42
  ecdh-sha2-nistp256
43
43
  diffie-hellman-group-exchange-sha256
44
+ diffie-hellman-group14-sha256
44
45
  diffie-hellman-group14-sha1],
45
46
 
46
47
  encryption: %w[aes256-ctr aes192-ctr aes128-ctr],
@@ -277,7 +278,7 @@ module Net
277
278
  # existing known key for the host has preference.
278
279
 
279
280
  existing_keys = session.host_keys
280
- host_keys = existing_keys.map { |key| key.ssh_type }.uniq
281
+ host_keys = existing_keys.flat_map { |key| key.respond_to?(:ssh_types) ? key.ssh_types : [key.ssh_type] }.uniq
281
282
  algorithms[:host_key].each do |name|
282
283
  host_keys << name unless host_keys.include?(name)
283
284
  end
@@ -3,10 +3,9 @@ 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
7
- module SSH
6
+ module Net
7
+ module SSH
8
8
  module Transport
9
-
10
9
  # Implements a factory of OpenSSL cipher algorithms.
11
10
  class CipherFactory
12
11
  # Maps the SSH name of a cipher to it's corresponding OpenSSL name
@@ -35,9 +34,10 @@ module Net
35
34
  def self.supported?(name)
36
35
  ossl_name = SSH_TO_OSSL[name] or raise NotImplementedError, "unimplemented cipher `#{name}'"
37
36
  return true if ossl_name == "none"
37
+
38
38
  return OpenSSL::Cipher.ciphers.include?(ossl_name)
39
39
  end
40
-
40
+
41
41
  # Retrieves a new instance of the named algorithm. The new instance
42
42
  # will be initialized using an iv and key generated from the given
43
43
  # iv, key, shared, hash and digester values. Additionally, the
@@ -46,12 +46,13 @@ module Net
46
46
  def self.get(name, options={})
47
47
  ossl_name = SSH_TO_OSSL[name] or raise NotImplementedError, "unimplemented cipher `#{name}'"
48
48
  return IdentityCipher if ossl_name == "none"
49
+
49
50
  cipher = OpenSSL::Cipher.new(ossl_name)
50
-
51
+
51
52
  cipher.send(options[:encrypt] ? :encrypt : :decrypt)
52
-
53
+
53
54
  cipher.padding = 0
54
-
55
+
55
56
  if name =~ /-ctr(@openssh.org)?$/
56
57
  if ossl_name !~ /-ctr/
57
58
  cipher.extend(Net::SSH::Transport::CTR)
@@ -60,14 +61,14 @@ module Net
60
61
  end
61
62
  end
62
63
  cipher.iv = Net::SSH::Transport::KeyExpander.expand_key(cipher.iv_len, options[:iv], options)
63
-
64
+
64
65
  key_len = cipher.key_len
65
66
  cipher.key_len = key_len
66
67
  cipher.key = Net::SSH::Transport::KeyExpander.expand_key(key_len, options[:key], options)
67
-
68
+
68
69
  return cipher
69
70
  end
70
-
71
+
71
72
  # Returns a two-element array containing the [ key-length,
72
73
  # block-size ] for the named cipher algorithm. If the cipher
73
74
  # algorithm is unknown, or is "none", 0 is returned for both elements
@@ -82,7 +83,7 @@ module Net
82
83
  cipher = OpenSSL::Cipher.new(ossl_name)
83
84
  key_len = cipher.key_len
84
85
  cipher.key_len = key_len
85
-
86
+
86
87
  block_size =
87
88
  case ossl_name
88
89
  when /\-ctr/
@@ -90,14 +91,13 @@ module Net
90
91
  else
91
92
  cipher.block_size
92
93
  end
93
-
94
+
94
95
  result = [key_len, block_size]
95
96
  result << cipher.iv_len if options[:iv_len]
96
97
  end
97
98
  result
98
99
  end
99
100
  end
100
-
101
101
  end
102
102
  end
103
103
  end
@@ -1,5 +1,5 @@
1
- module Net
2
- module SSH
1
+ module Net
2
+ module SSH
3
3
  module Transport
4
4
  module Constants
5
5
  #--
@@ -12,7 +12,7 @@ module Net
12
12
  DEBUG = 4
13
13
  SERVICE_REQUEST = 5
14
14
  SERVICE_ACCEPT = 6
15
-
15
+
16
16
  #--
17
17
  # Algorithm negotiation messages
18
18
  #++
@@ -32,7 +32,7 @@ module Net::SSH::Transport
32
32
  module CTR
33
33
  def self.extended(orig)
34
34
  orig.instance_eval {
35
- @remaining = ""
35
+ @remaining = String.new
36
36
  @counter = nil
37
37
  @counter_len = orig.block_size
38
38
  orig.encrypt
@@ -67,13 +67,13 @@ module Net::SSH::Transport
67
67
  end
68
68
 
69
69
  def reset
70
- @remaining = ""
70
+ @remaining = String.new
71
71
  end
72
72
 
73
73
  def update(data)
74
74
  @remaining += data
75
75
 
76
- encrypted = ""
76
+ encrypted = String.new
77
77
 
78
78
  offset = 0
79
79
  while (@remaining.bytesize - offset) >= block_size
@@ -89,7 +89,7 @@ module Net::SSH::Transport
89
89
 
90
90
  def final
91
91
  s = @remaining.empty? ? '' : xor!(@remaining, _update(@counter))
92
- @remaining = ""
92
+ @remaining = String.new
93
93
  s
94
94
  end
95
95
 
@@ -5,7 +5,6 @@ module Net
5
5
  module SSH
6
6
  module Transport
7
7
  module HMAC
8
-
9
8
  # The base class of all OpenSSL-based HMAC algorithm wrappers.
10
9
  class Abstract
11
10
  class <<self
@@ -1,12 +1,10 @@
1
1
  require 'net/ssh/transport/hmac/abstract'
2
2
 
3
3
  module Net::SSH::Transport::HMAC
4
-
5
4
  # The MD5 HMAC algorithm.
6
5
  class MD5 < Abstract
7
6
  mac_length 16
8
7
  key_length 16
9
8
  digest_class OpenSSL::Digest::MD5
10
9
  end
11
-
12
10
  end
@@ -1,11 +1,9 @@
1
1
  require 'net/ssh/transport/hmac/md5'
2
2
 
3
3
  module Net::SSH::Transport::HMAC
4
-
5
4
  # The MD5-96 HMAC algorithm. This returns only the first 12 bytes of
6
5
  # the digest.
7
6
  class MD5_96 < MD5
8
7
  mac_length 12
9
8
  end
10
-
11
9
  end
@@ -1,7 +1,6 @@
1
1
  require 'net/ssh/transport/hmac/abstract'
2
2
 
3
3
  module Net::SSH::Transport::HMAC
4
-
5
4
  # The "none" algorithm. This has a key and mac length of 0.
6
5
  class None < Abstract
7
6
  key_length 0
@@ -11,5 +10,4 @@ module Net::SSH::Transport::HMAC
11
10
  ""
12
11
  end
13
12
  end
14
-
15
13
  end
@@ -1,7 +1,6 @@
1
1
  require 'net/ssh/transport/hmac/abstract'
2
2
 
3
3
  module Net::SSH::Transport::HMAC
4
-
5
4
  # The RIPEMD-160 HMAC algorithm. This has a mac and key length of 20, and
6
5
  # uses the RIPEMD-160 digest algorithm.
7
6
  class RIPEMD160 < Abstract
@@ -9,5 +8,4 @@ module Net::SSH::Transport::HMAC
9
8
  key_length 20
10
9
  digest_class OpenSSL::Digest::RIPEMD160
11
10
  end
12
-
13
11
  end
@@ -1,7 +1,6 @@
1
1
  require 'net/ssh/transport/hmac/abstract'
2
2
 
3
3
  module Net::SSH::Transport::HMAC
4
-
5
4
  # The SHA1 HMAC algorithm. This has a mac and key length of 20, and
6
5
  # uses the SHA1 digest algorithm.
7
6
  class SHA1 < Abstract
@@ -9,5 +8,4 @@ module Net::SSH::Transport::HMAC
9
8
  key_length 20
10
9
  digest_class OpenSSL::Digest::SHA1
11
10
  end
12
-
13
11
  end
@@ -1,11 +1,9 @@
1
1
  require 'net/ssh/transport/hmac/sha1'
2
2
 
3
3
  module Net::SSH::Transport::HMAC
4
-
5
4
  # The SHA1-96 HMAC algorithm. This returns only the first 12 bytes of
6
5
  # the digest.
7
6
  class SHA1_96 < SHA1
8
7
  mac_length 12
9
8
  end
10
-
11
9
  end
@@ -1,7 +1,6 @@
1
- module Net
2
- module SSH
1
+ module Net
2
+ module SSH
3
3
  module Transport
4
-
5
4
  # A cipher that does nothing but pass the data through, unchanged. This
6
5
  # keeps things in the code nice and clean when a cipher has not yet been
7
6
  # determined (i.e., during key exchange).
@@ -11,49 +10,48 @@ module Net
11
10
  def block_size
12
11
  8
13
12
  end
14
-
13
+
15
14
  # Returns an arbitrary integer.
16
15
  def iv_len
17
16
  4
18
17
  end
19
-
18
+
20
19
  # Does nothing. Returns self.
21
20
  def encrypt
22
21
  self
23
22
  end
24
-
23
+
25
24
  # Does nothing. Returns self.
26
25
  def decrypt
27
26
  self
28
27
  end
29
-
28
+
30
29
  # Passes its single argument through unchanged.
31
30
  def update(text)
32
31
  text
33
32
  end
34
-
33
+
35
34
  # Returns the empty string.
36
35
  def final
37
36
  ""
38
37
  end
39
-
38
+
40
39
  # The name of this cipher, which is "identity".
41
40
  def name
42
41
  "identity"
43
42
  end
44
-
43
+
45
44
  # Does nothing. Returns nil.
46
45
  def iv=(v)
47
46
  nil
48
47
  end
49
-
48
+
50
49
  # Does nothing. Returns self.
51
50
  def reset
52
51
  self
53
52
  end
54
53
  end
55
54
  end
56
-
57
55
  end
58
56
  end
59
57
  end
@@ -1,5 +1,6 @@
1
1
  require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
2
2
  require 'net/ssh/transport/kex/diffie_hellman_group14_sha1'
3
+ require 'net/ssh/transport/kex/diffie_hellman_group14_sha256'
3
4
  require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha1'
4
5
  require 'net/ssh/transport/kex/diffie_hellman_group_exchange_sha256'
5
6
  require 'net/ssh/transport/kex/ecdh_sha2_nistp256'
@@ -14,6 +15,7 @@ module Net::SSH::Transport
14
15
  MAP = {
15
16
  'diffie-hellman-group1-sha1' => DiffieHellmanGroup1SHA1,
16
17
  'diffie-hellman-group14-sha1' => DiffieHellmanGroup14SHA1,
18
+ 'diffie-hellman-group14-sha256' => DiffieHellmanGroup14SHA256,
17
19
  'diffie-hellman-group-exchange-sha1' => DiffieHellmanGroupExchangeSHA1,
18
20
  'diffie-hellman-group-exchange-sha256' => DiffieHellmanGroupExchangeSHA256,
19
21
  'ecdh-sha2-nistp256' => EcdhSHA2NistP256,
@@ -1,6 +1,7 @@
1
1
  gem 'x25519' # raise if the gem x25519 is not installed
2
2
 
3
3
  require 'x25519'
4
+
4
5
  require 'net/ssh/transport/constants'
5
6
  require 'net/ssh/transport/kex/abstract5656'
6
7
 
@@ -1,8 +1,8 @@
1
1
  require 'net/ssh/transport/kex/diffie_hellman_group1_sha1'
2
2
 
3
- module Net
4
- module SSH
5
- module Transport
3
+ module Net
4
+ module SSH
5
+ module Transport
6
6
  module Kex
7
7
  # A key-exchange service implementing the "diffie-hellman-group14-sha1"
8
8
  # key-exchange algorithm. (defined in RFC 4253)
@@ -24,7 +24,7 @@ module Net
24
24
  "B5C55DF0" "6F4C52C9" "DE2BCBF6" "95581718" +
25
25
  "3995497C" "EA956AE5" "15D22618" "98FA0510" +
26
26
  "15728E5A" "8AACAA68" "FFFFFFFF" "FFFFFFFF"
27
-
27
+
28
28
  # The radix in which P_s represents the value of P
29
29
  P_r = 16
30
30
 
@@ -0,0 +1,11 @@
1
+ require 'net/ssh/transport/kex/diffie_hellman_group14_sha1'
2
+
3
+ module Net::SSH::Transport::Kex
4
+ # A key-exchange service implementing the "diffie-hellman-group14-sha256"
5
+ # key-exchange algorithm.
6
+ class DiffieHellmanGroup14SHA256 < DiffieHellmanGroup14SHA1
7
+ def digester
8
+ OpenSSL::Digest::SHA256
9
+ end
10
+ end
11
+ end