net-ssh 7.3.3 → 7.3.4
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/.rubocop_todo.yml +2 -0
- data/CHANGES.txt +4 -0
- data/lib/net/ssh/known_hosts.rb +42 -0
- data/lib/net/ssh/verifiers/always.rb +43 -8
- data/lib/net/ssh/version.rb +1 -1
- data.tar.gz.sig +0 -0
- metadata +2 -2
- metadata.gz.sig +0 -0
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 266fc4529dfdc0019be7f3f24cad0a04fc227a9a928331fbe308fc9b6e61dd2d
|
|
4
|
+
data.tar.gz: b17aca117814cbe3076639b016f316b35ecbdd32e7f31b8ef1693cddb0292604
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: a2dab75570a4fc5173a97b6622fc4420da55b56b93ab75e984017d57162b23b8d3cca677f8abddb24169e82ddd3c24984e193a1aa914a3e6f76e2088e67f3031
|
|
7
|
+
data.tar.gz: 76f38fb763930c2d88faaac257920c7c648d20e3fde474ac16cf2aad02b2cf4244cb0cdb52ae4467379491d3c8cf9e8ad3cc322af1902a49a90f5d3920fcea2f
|
checksums.yaml.gz.sig
CHANGED
|
Binary file
|
data/.rubocop_todo.yml
CHANGED
|
@@ -758,10 +758,12 @@ Style/OpenStructUse:
|
|
|
758
758
|
Exclude:
|
|
759
759
|
- 'test/authentication/test_ed25519.rb'
|
|
760
760
|
- 'test/common.rb'
|
|
761
|
+
- 'test/test_known_hosts.rb'
|
|
761
762
|
- 'test/transport/kex/test_curve25519_sha256.rb'
|
|
762
763
|
- 'test/transport/kex/test_diffie_hellman_group1_sha1.rb'
|
|
763
764
|
- 'test/transport/kex/test_ecdh_sha2_nistp256.rb'
|
|
764
765
|
- 'test/verifiers/test_always.rb'
|
|
766
|
+
- 'test/verifiers/test_cert_authority_checks.rb'
|
|
765
767
|
|
|
766
768
|
# Offense count: 16
|
|
767
769
|
# Configuration parameters: AllowedMethods.
|
data/CHANGES.txt
CHANGED
|
@@ -1,3 +1,7 @@
|
|
|
1
|
+
=== 7.3.4
|
|
2
|
+
|
|
3
|
+
* Verify @cert-authority host certificate constraints — principals (shell-glob, matching OpenSSH), validity window, host type, and critical options — instead of trusting any CA-signed certificate for any host [#1010]
|
|
4
|
+
|
|
1
5
|
=== 7.3.3
|
|
2
6
|
|
|
3
7
|
* Support .pub file as IdentityFile to filter/prioritize agent keys (1Password SSH agent use case) [#942]
|
data/lib/net/ssh/known_hosts.rb
CHANGED
|
@@ -61,6 +61,37 @@ module Net
|
|
|
61
61
|
false
|
|
62
62
|
end
|
|
63
63
|
end
|
|
64
|
+
|
|
65
|
+
# Returns true if the certificate lists no principals (unrestricted) or
|
|
66
|
+
# if the given hostname matches a listed principal. Host-certificate
|
|
67
|
+
# principals are shell-glob patterns, matching OpenSSH, whose
|
|
68
|
+
# sshkey_cert_check_host passes wildcard_pattern=1 so principals like
|
|
69
|
+
# "*.example.com" are matched with match_pattern rather than strcmp.
|
|
70
|
+
def matches_principal?(server_key, hostname)
|
|
71
|
+
server_key.valid_principals.empty? ||
|
|
72
|
+
server_key.valid_principals.any? { |principal| File.fnmatch(principal, hostname) }
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
# Returns true if the certificate's validity window covers the current time.
|
|
76
|
+
def matches_validity?(server_key)
|
|
77
|
+
return false if server_key.valid_after && server_key.valid_after > Time.now
|
|
78
|
+
return false if server_key.valid_before && server_key.valid_before < Time.now
|
|
79
|
+
|
|
80
|
+
true
|
|
81
|
+
end
|
|
82
|
+
|
|
83
|
+
# Returns true if the certificate is a host certificate. A user
|
|
84
|
+
# certificate (type :user) must never authenticate a host.
|
|
85
|
+
def matches_type?(server_key)
|
|
86
|
+
server_key.type == :host
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
# Returns true if every critical option in the certificate is one we can
|
|
90
|
+
# enforce. net-ssh enforces none, so any critical option is unsupported
|
|
91
|
+
# and, as OpenSSH does, must cause the certificate to be rejected.
|
|
92
|
+
def critical_options_supported?(server_key)
|
|
93
|
+
server_key.critical_options.empty?
|
|
94
|
+
end
|
|
64
95
|
end
|
|
65
96
|
end
|
|
66
97
|
|
|
@@ -89,6 +120,17 @@ module Net
|
|
|
89
120
|
def empty?
|
|
90
121
|
@host_keys.empty?
|
|
91
122
|
end
|
|
123
|
+
|
|
124
|
+
# Returns the bare hostname, stripping port and IP portions from the
|
|
125
|
+
# comma-separated host string used internally.
|
|
126
|
+
#
|
|
127
|
+
# Examples:
|
|
128
|
+
# "server.example.com" => "server.example.com"
|
|
129
|
+
# "server.example.com,1.2.3.4" => "server.example.com"
|
|
130
|
+
# "[server.example.com]:2222" => "server.example.com"
|
|
131
|
+
def hostname
|
|
132
|
+
@host.split(",").first.gsub(/\[|\]:\d+/, "")
|
|
133
|
+
end
|
|
92
134
|
end
|
|
93
135
|
|
|
94
136
|
# Searches an OpenSSH-style known-host file for a given host, and returns all
|
|
@@ -19,10 +19,8 @@ module Net
|
|
|
19
19
|
# We've never seen this host before, so raise an exception.
|
|
20
20
|
process_cache_miss(host_keys, arguments, HostKeyUnknown, "is unknown") if host_keys.empty?
|
|
21
21
|
|
|
22
|
-
#
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
found = host_keys.any? do |key|
|
|
22
|
+
# Find the known-hosts entry whose key matches the presented certificate.
|
|
23
|
+
found_key = host_keys.find do |key|
|
|
26
24
|
if key.respond_to?(:matches_key?)
|
|
27
25
|
key.matches_key?(arguments[:key])
|
|
28
26
|
else
|
|
@@ -30,11 +28,17 @@ module Net
|
|
|
30
28
|
end
|
|
31
29
|
end
|
|
32
30
|
|
|
33
|
-
#
|
|
34
|
-
|
|
35
|
-
|
|
31
|
+
# No matching entry found — key is not recognized.
|
|
32
|
+
process_cache_miss(host_keys, arguments, HostKeyMismatch, "does not match") unless found_key
|
|
33
|
+
|
|
34
|
+
# For @cert-authority entries, enforce the certificate constraints
|
|
35
|
+
# OpenSSH checks in sshkey_cert_check_authority. A certificate signed by
|
|
36
|
+
# the trusted CA but failing any of these is rejected with
|
|
37
|
+
# HostKeyMismatch (not HostKeyUnknown) so AcceptNew does not swallow the
|
|
38
|
+
# failure and remember the rejected certificate.
|
|
39
|
+
verify_certificate!(found_key, host_keys, arguments)
|
|
36
40
|
|
|
37
|
-
|
|
41
|
+
true
|
|
38
42
|
end
|
|
39
43
|
|
|
40
44
|
def verify_signature(&block)
|
|
@@ -43,6 +47,37 @@ module Net
|
|
|
43
47
|
|
|
44
48
|
private
|
|
45
49
|
|
|
50
|
+
# Enforces the @cert-authority certificate constraints for entries that
|
|
51
|
+
# implement them (Net::SSH::HostKeyEntries::CertAuthority). Non-certificate
|
|
52
|
+
# entries do not respond to these predicates and are left untouched.
|
|
53
|
+
def verify_certificate!(entry, host_keys, arguments)
|
|
54
|
+
cert = arguments[:key]
|
|
55
|
+
|
|
56
|
+
if entry.respond_to?(:matches_validity?) && !entry.matches_validity?(cert)
|
|
57
|
+
reason = if cert.valid_before && cert.valid_before < Time.now
|
|
58
|
+
"Certificate has expired"
|
|
59
|
+
else
|
|
60
|
+
"Certificate is not yet valid"
|
|
61
|
+
end
|
|
62
|
+
process_cache_miss(host_keys, arguments, HostKeyMismatch, reason)
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
if entry.respond_to?(:matches_principal?) && !entry.matches_principal?(cert, host_keys.hostname)
|
|
66
|
+
process_cache_miss(host_keys, arguments, HostKeyMismatch,
|
|
67
|
+
"Certificate invalid: name is not a listed principal")
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
if entry.respond_to?(:matches_type?) && !entry.matches_type?(cert)
|
|
71
|
+
process_cache_miss(host_keys, arguments, HostKeyMismatch,
|
|
72
|
+
"Certificate invalid: not a host certificate")
|
|
73
|
+
end
|
|
74
|
+
|
|
75
|
+
return unless entry.respond_to?(:critical_options_supported?) && !entry.critical_options_supported?(cert)
|
|
76
|
+
|
|
77
|
+
process_cache_miss(host_keys, arguments, HostKeyMismatch,
|
|
78
|
+
"Certificate invalid: unsupported critical option")
|
|
79
|
+
end
|
|
80
|
+
|
|
46
81
|
def process_cache_miss(host_keys, args, exc_class, message)
|
|
47
82
|
exception = exc_class.new("fingerprint #{args[:fingerprint]} " +
|
|
48
83
|
"#{message} for #{host_keys.host.inspect}")
|
data/lib/net/ssh/version.rb
CHANGED
data.tar.gz.sig
CHANGED
|
Binary file
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: net-ssh
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 7.3.
|
|
4
|
+
version: 7.3.4
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Jamis Buck
|
|
@@ -32,7 +32,7 @@ cert_chain:
|
|
|
32
32
|
ufHf4AX2UIkJbh7zCPkiNCqIr7MSWLNFG/9lOlHYsEJM8XujT1ofPobYx6YSFx/C
|
|
33
33
|
7HBrI7UX7awt6UvBZebhcHzyMHxg/B5PVQllPA==
|
|
34
34
|
-----END CERTIFICATE-----
|
|
35
|
-
date: 2026-
|
|
35
|
+
date: 2026-10-04 00:00:00.000000000 Z
|
|
36
36
|
dependencies:
|
|
37
37
|
- !ruby/object:Gem::Dependency
|
|
38
38
|
name: bcrypt_pbkdf
|
metadata.gz.sig
CHANGED
|
Binary file
|