net-ssh 6.1.0 → 7.0.1

Sign up to get free protection for your applications and to get access to all the features.
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