6847060266
`allowed_key_types` is removed and the `minimum_<type>_bits` fields are renamed to `<tech>_key_restriction`. A special sentinel value (`-1`) signifies that the key type is disabled. This also feeds through to the UI - checkboxes per key type are out, inline selection of "forbidden" and "allowed" (i.e., no restrictions) are in. As with the previous model, unknown key types are disallowed, even if the underlying ssh daemon happens to support them. The defaults have also been changed from the lowest known bit size to "no restriction". So if someone does happen to have a 768-bit RSA key, it will continue to work on upgrade, at least until the administrator restricts them.
74 lines
1.6 KiB
Ruby
74 lines
1.6 KiB
Ruby
module Gitlab
|
|
class SSHPublicKey
|
|
Technology = Struct.new(:name, :key_class, :supported_sizes)
|
|
|
|
Technologies = [
|
|
Technology.new(:rsa, OpenSSL::PKey::RSA, [1024, 2048, 3072, 4096]),
|
|
Technology.new(:dsa, OpenSSL::PKey::DSA, [1024, 2048, 3072]),
|
|
Technology.new(:ecdsa, OpenSSL::PKey::EC, [256, 384, 521]),
|
|
Technology.new(:ed25519, Net::SSH::Authentication::ED25519::PubKey, [256])
|
|
].freeze
|
|
|
|
def self.technology(name)
|
|
Technologies.find { |tech| tech.name.to_s == name.to_s }
|
|
end
|
|
|
|
def self.supported_sizes(name)
|
|
technology(name)&.supported_sizes
|
|
end
|
|
|
|
attr_reader :key_text, :key
|
|
|
|
# Unqualified MD5 fingerprint for compatibility
|
|
delegate :fingerprint, to: :key, allow_nil: true
|
|
|
|
def initialize(key_text)
|
|
@key_text = key_text
|
|
|
|
@key =
|
|
begin
|
|
Net::SSH::KeyFactory.load_data_public_key(key_text)
|
|
rescue StandardError, NotImplementedError
|
|
end
|
|
end
|
|
|
|
def valid?
|
|
key.present?
|
|
end
|
|
|
|
def type
|
|
return unless valid?
|
|
|
|
technology.name
|
|
end
|
|
|
|
def bits
|
|
return unless valid?
|
|
|
|
case type
|
|
when :rsa
|
|
key.n.num_bits
|
|
when :dsa
|
|
key.p.num_bits
|
|
when :ecdsa
|
|
key.group.order.num_bits
|
|
when :ed25519
|
|
256
|
|
else
|
|
raise "Unsupported key type: #{type}"
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def technology
|
|
@technology ||=
|
|
begin
|
|
tech = Technologies.find { |tech| key.is_a?(tech.key_class) }
|
|
raise "Unsupported key type: #{key.class}" unless tech
|
|
|
|
tech
|
|
end
|
|
end
|
|
end
|
|
end
|