net-ssh 6.2.0.rc2 → 6.3.0.beta1

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