summaryrefslogtreecommitdiff
path: root/lib/net/ssh/authentication/methods
diff options
context:
space:
mode:
authorZdenek Zambersky <zzambers@redhat.com>2021-05-06 13:50:20 +0200
committerFlorian Wininger <fw.centrale@gmail.com>2021-10-25 15:59:19 +0200
commit91254c72586179469ee59e4b0bd1d54960ce8d88 (patch)
tree2a2b52c5bf7ac31804d1d6f018a4b5ddf805ca79 /lib/net/ssh/authentication/methods
parent0150d054f0cd0beacd4ba1000c6df6d8636a2c18 (diff)
downloadnet-ssh-rsa-sha2.tar.gz
Added support for RSA client authentication with SHA-2rsa-sha2
Diffstat (limited to 'lib/net/ssh/authentication/methods')
-rw-r--r--lib/net/ssh/authentication/methods/abstract.rb10
-rw-r--r--lib/net/ssh/authentication/methods/publickey.rb66
2 files changed, 64 insertions, 12 deletions
diff --git a/lib/net/ssh/authentication/methods/abstract.rb b/lib/net/ssh/authentication/methods/abstract.rb
index 07aa5f3..f023011 100644
--- a/lib/net/ssh/authentication/methods/abstract.rb
+++ b/lib/net/ssh/authentication/methods/abstract.rb
@@ -20,12 +20,22 @@ module Net
# this.
attr_reader :key_manager
+ # So far only affects algorithms used for rsa keys, but can be
+ # extended to other keys, e.g after reading of
+ # PubkeyAcceptedAlgorithms option from ssh_config file is implemented.
+ attr_reader :pubkey_algorithms
+
# Instantiates a new authentication method.
def initialize(session, options = {})
@session = session
@key_manager = options[:key_manager]
@options = options
@prompt = options[:password_prompt]
+ @pubkey_algorithms = options[:pubkey_algorithms] \
+ || %w[rsa-sha2-256-cert-v01@openssh.com
+ ssh-rsa-cert-v01@openssh.com
+ rsa-sha2-256
+ ssh-rsa]
self.logger = session.logger
end
diff --git a/lib/net/ssh/authentication/methods/publickey.rb b/lib/net/ssh/authentication/methods/publickey.rb
index eb4d740..48a56ab 100644
--- a/lib/net/ssh/authentication/methods/publickey.rb
+++ b/lib/net/ssh/authentication/methods/publickey.rb
@@ -26,41 +26,40 @@ module Net
# Builds a packet that contains the request formatted for sending
# a public-key request to the server.
- def build_request(pub_key, username, next_service, has_sig)
+ def build_request(pub_key, username, next_service, alg, has_sig)
blob = Net::SSH::Buffer.new
blob.write_key pub_key
userauth_request(username, next_service, "publickey", has_sig,
- pub_key.ssh_type, blob.to_s)
+ alg, blob.to_s)
end
# Builds and sends a request formatted for a public-key
# authentication request.
- def send_request(pub_key, username, next_service, signature = nil)
- msg = build_request(pub_key, username, next_service, !signature.nil?)
+ def send_request(pub_key, username, next_service, alg, signature = nil)
+ msg = build_request(pub_key, username, next_service, alg,
+ !signature.nil?)
msg.write_string(signature) if signature
send_message(msg)
end
- # Attempts to perform public-key authentication for the given
- # username, with the given identity (public key). Returns +true+ if
- # successful, or +false+ otherwise.
- def authenticate_with(identity, next_service, username)
+ def authenticate_with_alg(identity, next_service, username, alg, sig_alg = nil)
debug { "trying publickey (#{identity.fingerprint})" }
- send_request(identity, username, next_service)
+ send_request(identity, username, next_service, alg)
message = session.next_message
case message.type
when USERAUTH_PK_OK
- buffer = build_request(identity, username, next_service, true)
+ buffer = build_request(identity, username, next_service, alg,
+ true)
sig_data = Net::SSH::Buffer.new
sig_data.write_string(session_id)
sig_data.append(buffer.to_s)
- sig_blob = key_manager.sign(identity, sig_data)
+ sig_blob = key_manager.sign(identity, sig_data, sig_alg)
- send_request(identity, username, next_service, sig_blob.to_s)
+ send_request(identity, username, next_service, alg, sig_blob.to_s)
message = session.next_message
case message.type
@@ -88,6 +87,49 @@ module Net
raise Net::SSH::Exception, "unexpected reply to USERAUTH_REQUEST: #{message.type} (#{message.inspect})"
end
end
+
+ # Attempts to perform public-key authentication for the given
+ # username, with the given identity (public key). Returns +true+ if
+ # successful, or +false+ otherwise.
+ def authenticate_with(identity, next_service, username)
+ type = identity.ssh_type
+ if type == "ssh-rsa"
+ pubkey_algorithms.each do |pk_alg|
+ case pk_alg
+ when "rsa-sha2-512", "rsa-sha2-256", "ssh-rsa"
+ if authenticate_with_alg(identity, next_service, username, pk_alg, pk_alg)
+ # success
+ return true
+ end
+ end
+ end
+ elsif type == "ssh-rsa-cert-v01@openssh.com"
+ pubkey_algorithms.each do |pk_alg|
+ case pk_alg
+ when "rsa-sha2-512-cert-v01@openssh.com"
+ if authenticate_with_alg(identity, next_service, username, pk_alg, "rsa-sha2-512")
+ # success
+ return true
+ end
+ when "rsa-sha2-256-cert-v01@openssh.com"
+ if authenticate_with_alg(identity, next_service, username, pk_alg, "rsa-sha2-256")
+ # success
+ return true
+ end
+ when "ssh-rsa-cert-v01@openssh.com"
+ if authenticate_with_alg(identity, next_service, username, pk_alg)
+ # success
+ return true
+ end
+ end
+ end
+ elsif authenticate_with_alg(identity, next_service, username, type)
+ # success
+ return true
+ end
+ # failure
+ return false
+ end
end
end
end