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.
- checksums.yaml +4 -4
- checksums.yaml.gz.sig +0 -0
- data/.dockerignore +6 -0
- data/.github/config/rubocop_linter_action.yml +4 -0
- data/.github/workflows/ci-with-docker.yml +44 -0
- data/.github/workflows/ci.yml +87 -0
- data/.github/workflows/rubocop.yml +13 -0
- data/.gitignore +2 -0
- data/.rubocop.yml +12 -1
- data/.rubocop_todo.yml +474 -375
- data/CHANGES.txt +16 -3
- data/Dockerfile +27 -0
- data/Dockerfile.openssl3 +17 -0
- data/Gemfile +2 -0
- data/Gemfile.noed25519 +2 -0
- data/README.md +9 -3
- data/Rakefile +5 -0
- data/docker-compose.yml +23 -0
- data/lib/net/ssh/authentication/agent.rb +29 -13
- data/lib/net/ssh/authentication/certificate.rb +12 -9
- data/lib/net/ssh/authentication/constants.rb +0 -1
- data/lib/net/ssh/authentication/ed25519.rb +11 -7
- data/lib/net/ssh/authentication/ed25519_loader.rb +4 -7
- data/lib/net/ssh/authentication/key_manager.rb +46 -34
- data/lib/net/ssh/authentication/methods/abstract.rb +12 -3
- data/lib/net/ssh/authentication/methods/hostbased.rb +3 -5
- data/lib/net/ssh/authentication/methods/keyboard_interactive.rb +2 -2
- data/lib/net/ssh/authentication/methods/none.rb +6 -9
- data/lib/net/ssh/authentication/methods/password.rb +2 -3
- data/lib/net/ssh/authentication/methods/publickey.rb +56 -16
- data/lib/net/ssh/authentication/pageant.rb +97 -97
- data/lib/net/ssh/authentication/pub_key_fingerprint.rb +2 -2
- data/lib/net/ssh/authentication/session.rb +18 -17
- data/lib/net/ssh/buffer.rb +50 -30
- data/lib/net/ssh/buffered_io.rb +24 -25
- data/lib/net/ssh/config.rb +33 -20
- data/lib/net/ssh/connection/channel.rb +84 -82
- data/lib/net/ssh/connection/constants.rb +0 -4
- data/lib/net/ssh/connection/event_loop.rb +30 -24
- data/lib/net/ssh/connection/keepalive.rb +12 -12
- data/lib/net/ssh/connection/session.rb +108 -107
- data/lib/net/ssh/connection/term.rb +56 -58
- data/lib/net/ssh/errors.rb +12 -12
- data/lib/net/ssh/key_factory.rb +7 -8
- data/lib/net/ssh/known_hosts.rb +84 -15
- data/lib/net/ssh/loggable.rb +8 -9
- data/lib/net/ssh/packet.rb +1 -1
- data/lib/net/ssh/prompt.rb +9 -11
- data/lib/net/ssh/proxy/command.rb +1 -1
- data/lib/net/ssh/proxy/errors.rb +2 -4
- data/lib/net/ssh/proxy/http.rb +18 -20
- data/lib/net/ssh/proxy/https.rb +8 -10
- data/lib/net/ssh/proxy/jump.rb +8 -10
- data/lib/net/ssh/proxy/socks4.rb +2 -4
- data/lib/net/ssh/proxy/socks5.rb +3 -5
- data/lib/net/ssh/service/forward.rb +7 -7
- data/lib/net/ssh/test/channel.rb +24 -26
- data/lib/net/ssh/test/extensions.rb +35 -35
- data/lib/net/ssh/test/kex.rb +6 -8
- data/lib/net/ssh/test/local_packet.rb +0 -2
- data/lib/net/ssh/test/packet.rb +3 -3
- data/lib/net/ssh/test/remote_packet.rb +6 -8
- data/lib/net/ssh/test/script.rb +25 -27
- data/lib/net/ssh/test/socket.rb +12 -15
- data/lib/net/ssh/test.rb +4 -5
- data/lib/net/ssh/transport/algorithms.rb +17 -14
- data/lib/net/ssh/transport/cipher_factory.rb +28 -28
- data/lib/net/ssh/transport/constants.rb +3 -3
- data/lib/net/ssh/transport/ctr.rb +7 -7
- data/lib/net/ssh/transport/hmac/abstract.rb +4 -5
- data/lib/net/ssh/transport/hmac/md5.rb +0 -2
- data/lib/net/ssh/transport/hmac/md5_96.rb +0 -2
- data/lib/net/ssh/transport/hmac/none.rb +0 -2
- data/lib/net/ssh/transport/hmac/ripemd160.rb +0 -2
- data/lib/net/ssh/transport/hmac/sha1.rb +0 -2
- data/lib/net/ssh/transport/hmac/sha1_96.rb +0 -2
- data/lib/net/ssh/transport/hmac.rb +12 -12
- data/lib/net/ssh/transport/identity_cipher.rb +11 -13
- data/lib/net/ssh/transport/kex/abstract.rb +12 -5
- data/lib/net/ssh/transport/kex/abstract5656.rb +1 -1
- data/lib/net/ssh/transport/kex/curve25519_sha256.rb +2 -1
- data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha1.rb +4 -4
- data/lib/net/ssh/transport/kex/diffie_hellman_group14_sha256.rb +11 -0
- data/lib/net/ssh/transport/kex/diffie_hellman_group1_sha1.rb +21 -21
- data/lib/net/ssh/transport/kex/diffie_hellman_group_exchange_sha1.rb +1 -2
- data/lib/net/ssh/transport/kex/ecdh_sha2_nistp256.rb +2 -2
- data/lib/net/ssh/transport/kex.rb +8 -6
- data/lib/net/ssh/transport/key_expander.rb +7 -8
- data/lib/net/ssh/transport/openssl.rb +51 -26
- data/lib/net/ssh/transport/packet_stream.rb +2 -3
- data/lib/net/ssh/transport/server_version.rb +17 -16
- data/lib/net/ssh/transport/session.rb +9 -7
- data/lib/net/ssh/transport/state.rb +43 -43
- data/lib/net/ssh/verifiers/accept_new.rb +0 -2
- data/lib/net/ssh/verifiers/accept_new_or_local_tunnel.rb +1 -2
- data/lib/net/ssh/verifiers/always.rb +6 -4
- data/lib/net/ssh/verifiers/never.rb +0 -2
- data/lib/net/ssh/version.rb +3 -3
- data/lib/net/ssh.rb +4 -5
- data/net-ssh-public_cert.pem +8 -8
- data/net-ssh.gemspec +2 -2
- data/support/ssh_tunnel_bug.rb +3 -3
- data.tar.gz.sig +1 -3
- metadata +23 -15
- metadata.gz.sig +0 -0
- 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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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,
|
|
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
|
-
|
|
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
|