Commit f3ce02b5c944e5956eb7208506ec513623d092d8

Authored by Sytse Sijbrandij
1 parent 8f9a450e

Reject ssh keys that break gitolite.

Failing test.

Working check.
app/models/key.rb
@@ -18,7 +18,7 @@ class Key < ActiveRecord::Base @@ -18,7 +18,7 @@ class Key < ActiveRecord::Base
18 before_save :set_identifier 18 before_save :set_identifier
19 before_validation :strip_white_space 19 before_validation :strip_white_space
20 delegate :name, :email, to: :user, prefix: true 20 delegate :name, :email, to: :user, prefix: true
21 - validate :unique_key 21 + validate :unique_key, :fingerprintable_key
22 22
23 def strip_white_space 23 def strip_white_space
24 self.key = self.key.strip unless self.key.blank? 24 self.key = self.key.strip unless self.key.blank?
@@ -32,6 +32,21 @@ class Key < ActiveRecord::Base @@ -32,6 +32,21 @@ class Key < ActiveRecord::Base
32 end 32 end
33 end 33 end
34 34
  35 + def fingerprintable_key
  36 + return true unless key # Don't test if there is no key.
  37 + # `ssh-keygen -lf /dev/stdin <<< "#{key}"` errors with: redirection unexpected
  38 + file = Tempfile.new('key_file')
  39 + begin
  40 + file.puts key
  41 + file.rewind
  42 + fingerprint_output = `ssh-keygen -lf #{file.path} 2>&1` # Catch stderr.
  43 + ensure
  44 + file.close
  45 + file.unlink # deletes the temp file
  46 + end
  47 + errors.add(:key, "can't be fingerprinted") if fingerprint_output.match("failed")
  48 + end
  49 +
35 def set_identifier 50 def set_identifier
36 if is_deploy_key 51 if is_deploy_key
37 self.identifier = "deploy_" + Digest::MD5.hexdigest(key) 52 self.identifier = "deploy_" + Digest::MD5.hexdigest(key)
spec/factories.rb
@@ -83,11 +83,7 @@ FactoryGirl.define do @@ -83,11 +83,7 @@ FactoryGirl.define do
83 factory :key do 83 factory :key do
84 title 84 title
85 key do 85 key do
86 - """  
87 - ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4  
88 - 596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4  
89 - soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=  
90 - """ 86 + "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0="
91 end 87 end
92 88
93 factory :deploy_key do 89 factory :deploy_key do
@@ -97,6 +93,12 @@ FactoryGirl.define do @@ -97,6 +93,12 @@ FactoryGirl.define do
97 factory :personal_key do 93 factory :personal_key do
98 user 94 user
99 end 95 end
  96 +
  97 + factory :key_with_a_space_in_the_middle do
  98 + key do
  99 + "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa ++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0="
  100 + end
  101 + end
100 end 102 end
101 103
102 factory :milestone do 104 factory :milestone do
spec/models/key_spec.rb
@@ -46,4 +46,16 @@ describe Key do @@ -46,4 +46,16 @@ describe Key do
46 end 46 end
47 end 47 end
48 end 48 end
  49 +
  50 + context "validate it is a fingerprintable key" do
  51 + let(:user) { Factory.create(:user) }
  52 +
  53 + it "accepts the fingerprintable key" do
  54 + build(:key, user: user).should be_valid
  55 + end
  56 +
  57 + it "rejects the unfingerprintable key" do
  58 + build(:key_with_a_space_in_the_middle).should_not be_valid
  59 + end
  60 + end
49 end 61 end