BigW Consortium Gitlab

Commit ac86b204 by Pablo Carranza Committed by James Edwards-Jones

Backport authorized_keys branch 'find-key-by-fingerprint'

Add find key by base64 key or fingerprint to the internal API See merge request !250 Squashed changes: Add unique index to fingerprint Add new index to schema Add internal api to get ssh key by fingerprint Change API endpoint to authorized_keys Add InsecureKeyFingerprint that calculates the fingerprint without shelling out Add require for gitlab key fingerprint Remove uniqueness of fingerprint index Remove unique option from migration Fix spec style in fingerprint test Fix rubocop complain Extract insecure key fingerprint to separate file Change migration to support building index concurrently Remove those hideous tabs
parent ae46ceaa
# rubocop:disable all
class AddFingerprintIndex < ActiveRecord::Migration
disable_ddl_transaction!
DOWNTIME = false
def change
args = [:keys, :fingerprint]
if Gitlab::Database.postgresql?
args << { algorithm: :concurrently }
end
add_index(*args)
end
end
......@@ -82,6 +82,18 @@ module API
end
#
# Get a ssh key using the fingerprint
#
get "/authorized_keys" do
fingerprint = params.fetch(:fingerprint) do
Gitlab::InsecureKeyFingerprint.new(params.fetch(:key)).fingerprint
end
key = Key.find_by(fingerprint: fingerprint)
not_found!("Key") if key.nil?
present key, with: Entities::SSHKey
end
#
# Discover user by ssh key or user id
#
get "/discover" do
......
module Gitlab
#
# Calculates the fingerprint of a given key without using
# openssh key validations. For this reason, only use
# for calculating the fingerprint to find the key with it.
#
# DO NOT use it for checking the validity of a ssh key.
#
class InsecureKeyFingerprint
attr_accessor :key
#
# Gets the base64 encoded string representing a rsa or dsa key
#
def initialize(key_base64)
@key = key_base64
end
def fingerprint
OpenSSL::Digest::MD5.hexdigest(Base64.decode64(@key)).scan(/../).join(':')
end
end
end
require 'spec_helper'
describe Gitlab::InsecureKeyFingerprint do
let(:key) do
'ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn' \
'1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qk' \
'r8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMg' \
'Jw0='
end
let(:fingerprint) { "3f:a2:ee:de:b5:de:53:c3:aa:2f:9c:45:24:4c:47:7b" }
describe "#fingerprint" do
it "generates the key's fingerprint" do
expect(described_class.new(key.split[1]).fingerprint).to eq(fingerprint)
end
end
end
......@@ -192,6 +192,54 @@ describe API::Internal do
end
end
describe "GET /internal/authorized_keys" do
context "unsing an existing key's fingerprint" do
it "finds the key" do
get(api('/internal/authorized_keys'), fingerprint: key.fingerprint, secret_token: secret_token)
expect(response.status).to eq(200)
expect(json_response["key"]).to eq(key.key)
end
end
context "non existing key's fingerprint" do
it "returns 404" do
get(api('/internal/authorized_keys'), fingerprint: "no:t-:va:li:d0", secret_token: secret_token)
expect(response.status).to eq(404)
end
end
context "using a partial fingerprint" do
it "returns 404" do
get(api('/internal/authorized_keys'), fingerprint: "#{key.fingerprint[0..5]}%", secret_token: secret_token)
expect(response.status).to eq(404)
end
end
context "sending the key" do
it "finds the key" do
get(api('/internal/authorized_keys'), key: key.key.split[1], secret_token: secret_token)
expect(response.status).to eq(200)
expect(json_response["key"]).to eq(key.key)
end
it "returns 404 with a partial key" do
get(api('/internal/authorized_keys'), key: key.key.split[1][0...-3], secret_token: secret_token)
expect(response.status).to eq(404)
end
it "returns 404 with an not valid base64 string" do
get(api('/internal/authorized_keys'), key: "whatever!", secret_token: secret_token)
expect(response.status).to eq(404)
end
end
end
describe "POST /internal/allowed", :clean_gitlab_redis_shared_state do
context "access granted" do
around do |example|
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment