net-ssh 6.1.0 → 7.0.1

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 (106) hide show
  1. checksums.yaml +4 -4
  2. checksums.yaml.gz.sig +0 -0
  3. data/.dockerignore +6 -0
  4. data/.github/config/rubocop_linter_action.yml +4 -0
  5. data/.github/workflows/ci-with-docker.yml +44 -0
  6. data/.github/workflows/ci.yml +87 -0
  7. data/.github/workflows/rubocop.yml +13 -0
  8. data/.gitignore +2 -0
  9. data/.rubocop.yml +12 -1
  10. data/.rubocop_todo.yml +474 -375
  11. data/CHANGES.txt +16 -3
  12. data/Dockerfile +27 -0
  13. data/Dockerfile.openssl3 +17 -0
  14. data/Gemfile +2 -0
  15. data/Gemfile.noed25519 +2 -0
  16. data/README.md +9 -3
  17. data/Rakefile +5 -0
  18. data/docker-compose.yml +23 -0
  19. data/lib/net/ssh/authentication/agent.rb +29 -13
  20. data/lib/net/ssh/authentication/certificate.rb +12 -9
  21. data/lib/net/ssh/authentication/constants.rb +0 -1
  22. data/lib/net/ssh/authentication/ed25519.rb +11 -7
  23. data/lib/net/ssh/authentication/ed25519_loader.rb +4 -7
  24. data/lib/net/ssh/authentication/key_manager.rb +46 -34
  25. data/lib/net/ssh/authentication/methods/abstract.rb +12 -3
  26. data/lib/net/ssh/authentication/methods/hostbased.rb +3 -5
  27. data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +2 -2
  28. data/lib/net/ssh/authentication/methods/none.rb +6 -9
  29. data/lib/net/ssh/authentication/methods/password.rb +2 -3
  30. data/lib/net/ssh/authentication/methods/publickey.rb +56 -16
  31. data/lib/net/ssh/authentication/pageant.rb +97 -97
  32. data/lib/net/ssh/authentication/pub_key_fingerprint.rb +2 -2
  33. data/lib/net/ssh/authentication/session.rb +18 -17
  34. data/lib/net/ssh/buffer.rb +50 -30
  35. data/lib/net/ssh/buffered_io.rb +24 -25
  36. data/lib/net/ssh/config.rb +33 -20
  37. data/lib/net/ssh/connection/channel.rb +84 -82
  38. data/lib/net/ssh/connection/constants.rb +0 -4
  39. data/lib/net/ssh/connection/event_loop.rb +30 -24
  40. data/lib/net/ssh/connection/keepalive.rb +12 -12
  41. data/lib/net/ssh/connection/session.rb +108 -107
  42. data/lib/net/ssh/connection/term.rb +56 -58
  43. data/lib/net/ssh/errors.rb +12 -12
  44. data/lib/net/ssh/key_factory.rb +7 -8
  45. data/lib/net/ssh/known_hosts.rb +84 -15
  46. data/lib/net/ssh/loggable.rb +8 -9
  47. data/lib/net/ssh/packet.rb +1 -1
  48. data/lib/net/ssh/prompt.rb +9 -11
  49. data/lib/net/ssh/proxy/command.rb +1 -1
  50. data/lib/net/ssh/proxy/errors.rb +2 -4
  51. data/lib/net/ssh/proxy/http.rb +18 -20
  52. data/lib/net/ssh/proxy/https.rb +8 -10
  53. data/lib/net/ssh/proxy/jump.rb +8 -10
  54. data/lib/net/ssh/proxy/socks4.rb +2 -4
  55. data/lib/net/ssh/proxy/socks5.rb +3 -5
  56. data/lib/net/ssh/service/forward.rb +7 -7
  57. data/lib/net/ssh/test/channel.rb +24 -26
  58. data/lib/net/ssh/test/extensions.rb +35 -35
  59. data/lib/net/ssh/test/kex.rb +6 -8
  60. data/lib/net/ssh/test/local_packet.rb +0 -2
  61. data/lib/net/ssh/test/packet.rb +3 -3
  62. data/lib/net/ssh/test/remote_packet.rb +6 -8
  63. data/lib/net/ssh/test/script.rb +25 -27
  64. data/lib/net/ssh/test/socket.rb +12 -15
  65. data/lib/net/ssh/test.rb +4 -5
  66. data/lib/net/ssh/transport/algorithms.rb +17 -14
  67. data/lib/net/ssh/transport/cipher_factory.rb +28 -28
  68. data/lib/net/ssh/transport/constants.rb +3 -3
  69. data/lib/net/ssh/transport/ctr.rb +7 -7
  70. data/lib/net/ssh/transport/hmac/abstract.rb +4 -5
  71. data/lib/net/ssh/transport/hmac/md5.rb +0 -2
  72. data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
  73. data/lib/net/ssh/transport/hmac/none.rb +0 -2
  74. data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
  75. data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
  76. data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
  77. data/lib/net/ssh/transport/hmac.rb +12 -12
  78. data/lib/net/ssh/transport/identity_cipher.rb +11 -13
  79. data/lib/net/ssh/transport/kex/abstract.rb +12 -5
  80. data/lib/net/ssh/transport/kex/abstract5656.rb +1 -1
  81. data/lib/net/ssh/transport/kex/curve25519_sha256.rb +2 -1
  82. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +4 -4
  83. data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
  84. data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +21 -21
  85. data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +1 -2
  86. data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +2 -2
  87. data/lib/net/ssh/transport/kex.rb +8 -6
  88. data/lib/net/ssh/transport/key_expander.rb +7 -8
  89. data/lib/net/ssh/transport/openssl.rb +51 -26
  90. data/lib/net/ssh/transport/packet_stream.rb +2 -3
  91. data/lib/net/ssh/transport/server_version.rb +17 -16
  92. data/lib/net/ssh/transport/session.rb +9 -7
  93. data/lib/net/ssh/transport/state.rb +43 -43
  94. data/lib/net/ssh/verifiers/accept_new.rb +0 -2
  95. data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +1 -2
  96. data/lib/net/ssh/verifiers/always.rb +6 -4
  97. data/lib/net/ssh/verifiers/never.rb +0 -2
  98. data/lib/net/ssh/version.rb +3 -3
  99. data/lib/net/ssh.rb +4 -5
  100. data/net-ssh-public_cert.pem +8 -8
  101. data/net-ssh.gemspec +2 -2
  102. data/support/ssh_tunnel_bug.rb +3 -3
  103. data.tar.gz.sig +1 -3
  104. metadata +23 -15
  105. metadata.gz.sig +0 -0
  106. data/.travis.yml +0 -52
@@ -4,19 +4,18 @@ module Net
4
4
  module SSH
5
5
  module Authentication
6
6
  module Methods
7
-
8
7
  # Implements the host-based SSH authentication method.
9
8
  class Hostbased < Abstract
10
9
  include Constants
11
10
 
12
11
  # Attempts to perform host-based authorization of the user by trying
13
12
  # all known keys.
14
- def authenticate(next_service, username, password=nil)
13
+ def authenticate(next_service, username, password = nil)
15
14
  return false unless key_manager
16
15
 
17
16
  key_manager.each_identity do |identity|
18
17
  return true if authenticate_with(identity, next_service,
19
- username, key_manager)
18
+ username, key_manager)
20
19
  end
21
20
 
22
21
  return false
@@ -64,10 +63,9 @@ module Net
64
63
  # Build the "core" hostbased request string.
65
64
  def build_request(identity, next_service, username, hostname, client_username)
66
65
  userauth_request(username, next_service, "hostbased", identity.ssh_type,
67
- Buffer.from(:key, identity).to_s, hostname, client_username).to_s
66
+ Buffer.from(:key, identity).to_s, hostname, client_username).to_s
68
67
  end
69
68
  end
70
-
71
69
  end
72
70
  end
73
71
  end
@@ -5,14 +5,13 @@ module Net
5
5
  module SSH
6
6
  module Authentication
7
7
  module Methods
8
-
9
8
  # Implements the "keyboard-interactive" SSH authentication method.
10
9
  class KeyboardInteractive < Abstract
11
10
  USERAUTH_INFO_REQUEST = 60
12
11
  USERAUTH_INFO_RESPONSE = 61
13
12
 
14
13
  # Attempt to authenticate the given user for the given service.
15
- def authenticate(next_service, username, password=nil)
14
+ def authenticate(next_service, username, password = nil)
16
15
  debug { "trying keyboard-interactive" }
17
16
  send_message(userauth_request(username, next_service, "keyboard-interactive", "", ""))
18
17
 
@@ -32,6 +31,7 @@ module Net
32
31
  message[:authentications].split(/,/).include? 'keyboard-interactive'
33
32
 
34
33
  return false unless interactive?
34
+
35
35
  password = nil
36
36
  debug { "retrying keyboard-interactive" }
37
37
  send_message(userauth_request(username, next_service, "keyboard-interactive", "", ""))
@@ -5,32 +5,29 @@ module Net
5
5
  module SSH
6
6
  module Authentication
7
7
  module Methods
8
-
9
8
  # Implements the "none" SSH authentication method.
10
9
  class None < Abstract
11
10
  # Attempt to authenticate as "none"
12
- def authenticate(next_service, user="", password="")
13
- send_message(userauth_request(user, next_service, "none"))
11
+ def authenticate(next_service, user = "", password = "")
12
+ send_message(userauth_request(user, next_service, "none"))
14
13
  message = session.next_message
15
-
14
+
16
15
  case message.type
17
16
  when USERAUTH_SUCCESS
18
17
  debug { "none succeeded" }
19
18
  return true
20
19
  when USERAUTH_FAILURE
21
20
  debug { "none failed" }
22
-
21
+
23
22
  raise Net::SSH::Authentication::DisallowedMethod unless
24
23
  message[:authentications].split(/,/).include? 'none'
25
-
24
+
26
25
  return false
27
26
  else
28
27
  raise Net::SSH::Exception, "unexpected reply to USERAUTH_REQUEST: #{message.type} (#{message.inspect})"
29
- end
30
-
28
+ end
31
29
  end
32
30
  end
33
-
34
31
  end
35
32
  end
36
33
  end
@@ -6,12 +6,11 @@ module Net
6
6
  module SSH
7
7
  module Authentication
8
8
  module Methods
9
-
10
9
  # Implements the "password" SSH authentication method.
11
10
  class Password < Abstract
12
11
  # Attempt to authenticate the given user for the given service. If
13
12
  # the password parameter is nil, this will ask for password
14
- def authenticate(next_service, username, password=nil)
13
+ def authenticate(next_service, username, password = nil)
15
14
  clear_prompter!
16
15
  retries = 0
17
16
  max_retries = get_max_retries
@@ -29,6 +28,7 @@ module Net
29
28
 
30
29
  raise Net::SSH::Authentication::DisallowedMethod unless
31
30
  message[:authentications].split(/,/).include? 'password'
31
+
32
32
  password = nil
33
33
  end
34
34
  end until (message.type != USERAUTH_FAILURE || retries >= max_retries)
@@ -74,7 +74,6 @@ module Net
74
74
  options[:non_interactive] ? 0 : result
75
75
  end
76
76
  end
77
-
78
77
  end
79
78
  end
80
79
  end
@@ -6,14 +6,13 @@ module Net
6
6
  module SSH
7
7
  module Authentication
8
8
  module Methods
9
-
10
9
  # Implements the "publickey" SSH authentication method.
11
10
  class Publickey < Abstract
12
11
  # Attempts to perform public-key authentication for the given
13
12
  # username, trying each identity known to the key manager. If any of
14
13
  # them succeed, returns +true+, otherwise returns +false+. This
15
14
  # requires the presence of a key manager.
16
- def authenticate(next_service, username, password=nil)
15
+ def authenticate(next_service, username, password = nil)
17
16
  return false unless key_manager
18
17
 
19
18
  key_manager.each_identity do |identity|
@@ -27,41 +26,40 @@ module Net
27
26
 
28
27
  # Builds a packet that contains the request formatted for sending
29
28
  # a public-key request to the server.
30
- def build_request(pub_key, username, next_service, has_sig)
29
+ def build_request(pub_key, username, next_service, alg, has_sig)
31
30
  blob = Net::SSH::Buffer.new
32
31
  blob.write_key pub_key
33
32
 
34
33
  userauth_request(username, next_service, "publickey", has_sig,
35
- pub_key.ssh_type, blob.to_s)
34
+ alg, blob.to_s)
36
35
  end
37
36
 
38
37
  # Builds and sends a request formatted for a public-key
39
38
  # authentication request.
40
- def send_request(pub_key, username, next_service, signature=nil)
41
- msg = build_request(pub_key, username, next_service, !signature.nil?)
39
+ def send_request(pub_key, username, next_service, alg, signature = nil)
40
+ msg = build_request(pub_key, username, next_service, alg,
41
+ !signature.nil?)
42
42
  msg.write_string(signature) if signature
43
43
  send_message(msg)
44
44
  end
45
45
 
46
- # Attempts to perform public-key authentication for the given
47
- # username, with the given identity (public key). Returns +true+ if
48
- # successful, or +false+ otherwise.
49
- def authenticate_with(identity, next_service, username)
46
+ def authenticate_with_alg(identity, next_service, username, alg, sig_alg = nil)
50
47
  debug { "trying publickey (#{identity.fingerprint})" }
51
- send_request(identity, username, next_service)
48
+ send_request(identity, username, next_service, alg)
52
49
 
53
50
  message = session.next_message
54
51
 
55
52
  case message.type
56
53
  when USERAUTH_PK_OK
57
- buffer = build_request(identity, username, next_service, true)
54
+ buffer = build_request(identity, username, next_service, alg,
55
+ true)
58
56
  sig_data = Net::SSH::Buffer.new
59
57
  sig_data.write_string(session_id)
60
58
  sig_data.append(buffer.to_s)
61
59
 
62
- sig_blob = key_manager.sign(identity, sig_data)
60
+ sig_blob = key_manager.sign(identity, sig_data, sig_alg)
63
61
 
64
- send_request(identity, username, next_service, sig_blob.to_s)
62
+ send_request(identity, username, next_service, alg, sig_blob.to_s)
65
63
  message = session.next_message
66
64
 
67
65
  case message.type
@@ -77,7 +75,7 @@ module Net
77
75
  return false
78
76
  else
79
77
  raise Net::SSH::Exception,
80
- "unexpected server response to USERAUTH_REQUEST: #{message.type} (#{message.inspect})"
78
+ "unexpected server response to USERAUTH_REQUEST: #{message.type} (#{message.inspect})"
81
79
  end
82
80
 
83
81
  when USERAUTH_FAILURE
@@ -89,8 +87,50 @@ module Net
89
87
  raise Net::SSH::Exception, "unexpected reply to USERAUTH_REQUEST: #{message.type} (#{message.inspect})"
90
88
  end
91
89
  end
92
- end
93
90
 
91
+ # Attempts to perform public-key authentication for the given
92
+ # username, with the given identity (public key). Returns +true+ if
93
+ # successful, or +false+ otherwise.
94
+ def authenticate_with(identity, next_service, username)
95
+ type = identity.ssh_type
96
+ if type == "ssh-rsa"
97
+ pubkey_algorithms.each do |pk_alg|
98
+ case pk_alg
99
+ when "rsa-sha2-512", "rsa-sha2-256", "ssh-rsa"
100
+ if authenticate_with_alg(identity, next_service, username, pk_alg, pk_alg)
101
+ # success
102
+ return true
103
+ end
104
+ end
105
+ end
106
+ elsif type == "ssh-rsa-cert-v01@openssh.com"
107
+ pubkey_algorithms.each do |pk_alg|
108
+ case pk_alg
109
+ when "rsa-sha2-512-cert-v01@openssh.com"
110
+ if authenticate_with_alg(identity, next_service, username, pk_alg, "rsa-sha2-512")
111
+ # success
112
+ return true
113
+ end
114
+ when "rsa-sha2-256-cert-v01@openssh.com"
115
+ if authenticate_with_alg(identity, next_service, username, pk_alg, "rsa-sha2-256")
116
+ # success
117
+ return true
118
+ end
119
+ when "ssh-rsa-cert-v01@openssh.com"
120
+ if authenticate_with_alg(identity, next_service, username, pk_alg)
121
+ # success
122
+ return true
123
+ end
124
+ end
125
+ end
126
+ elsif authenticate_with_alg(identity, next_service, username, type)
127
+ # success
128
+ return true
129
+ end
130
+ # failure
131
+ return false
132
+ end
133
+ end
94
134
  end
95
135
  end
96
136
  end