diff options
author | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2015-04-15 12:40:30 +0000 |
---|---|---|
committer | Dmitriy Zaporozhets <dmitriy.zaporozhets@gmail.com> | 2015-04-15 12:40:30 +0000 |
commit | 345e32d332fd06e3c99b21660d3bf2939ba62ce5 (patch) | |
tree | c3f11a0fb904f458ecf0e44686ed79c093bd532d | |
parent | d2a895dad80b5f7e12bb930fc92750d6848f7b21 (diff) | |
parent | 076494646d30cefd396e0d6a0ae879a31aecb454 (diff) | |
download | gitlab-ce-345e32d332fd06e3c99b21660d3bf2939ba62ce5.tar.gz |
Merge branch 'sstanovnik-openssh_fix' into 'master'
Fix generating SSH key fingerprints with OpenSSH 6.8.
Replaces https://github.com/gitlabhq/gitlabhq/pull/9008.
Fixes gitlab-org/gitlab-ce#1289.
cc @jacobvosmaer
See merge request !519
-rw-r--r-- | CHANGELOG | 3 | ||||
-rw-r--r-- | app/models/key.rb | 20 | ||||
-rw-r--r-- | lib/gitlab/key_fingerprint.rb | 55 | ||||
-rw-r--r-- | spec/lib/gitlab/key_fingerprint_spec.rb | 12 |
4 files changed, 74 insertions, 16 deletions
diff --git a/CHANGELOG b/CHANGELOG index a034d249d7b..00b3255ce2d 100644 --- a/CHANGELOG +++ b/CHANGELOG @@ -19,6 +19,9 @@ v 7.10.0 (unreleased) - Set Application controller default URL options to ensure all url_for calls are consistent (Stan Hu) - Allow HTML tags in Markdown input - Fix code unfold not working on Compare commits page (Stan Hu) + - Fix generating SSH key fingerprints with OpenSSH 6.8. (Sašo Stanovnik) + - Include missing events and fix save functionality in admin service template settings form (Stan Hu) + - Fix "Import projects from" button to show the correct instructions (Stan Hu) - Fix dots in Wiki slugs causing errors (Stan Hu) - Make maximum attachment size configurable via Application Settings (Stan Hu) - Update poltergeist to version 1.6.0 to support PhantomJS 2.0 (Zeger-Jan van de Weg) diff --git a/app/models/key.rb b/app/models/key.rb index e2e59296eed..016eee86992 100644 --- a/app/models/key.rb +++ b/app/models/key.rb @@ -16,7 +16,6 @@ require 'digest/md5' class Key < ActiveRecord::Base include Sortable - include Gitlab::Popen belongs_to :user @@ -79,20 +78,9 @@ class Key < ActiveRecord::Base def generate_fingerprint self.fingerprint = nil - return unless key.present? - - cmd_status = 0 - cmd_output = '' - Tempfile.open('gitlab_key_file') do |file| - file.puts key - file.rewind - cmd_output, cmd_status = popen(%W(ssh-keygen -lf #{file.path}), '/tmp') - end - - if cmd_status.zero? - cmd_output.gsub /(\h{2}:)+\h{2}/ do |match| - self.fingerprint = match - end - end + + return unless self.key.present? + + self.fingerprint = Gitlab::KeyFingerprint.new(self.key).fingerprint end end diff --git a/lib/gitlab/key_fingerprint.rb b/lib/gitlab/key_fingerprint.rb new file mode 100644 index 00000000000..baf52ff750d --- /dev/null +++ b/lib/gitlab/key_fingerprint.rb @@ -0,0 +1,55 @@ +module Gitlab + class KeyFingerprint + include Gitlab::Popen + + attr_accessor :key + + def initialize(key) + @key = key + end + + def fingerprint + cmd_status = 0 + cmd_output = '' + + Tempfile.open('gitlab_key_file') do |file| + file.puts key + file.rewind + + cmd = [] + cmd.push *%W(ssh-keygen) + cmd.push *%W(-E md5) if explicit_fingerprint_algorithm? + cmd.push *%W(-lf #{file.path}) + + cmd_output, cmd_status = popen(cmd, '/tmp') + end + + return nil unless cmd_status.zero? + + # 16 hex bytes separated by ':', optionally starting with "MD5:" + fingerprint_matches = cmd_output.match(/(MD5:)?(?<fingerprint>(\h{2}:){15}\h{2})/) + return nil unless fingerprint_matches + + fingerprint_matches[:fingerprint] + end + + private + + def explicit_fingerprint_algorithm? + # OpenSSH 6.8 introduces a new default output format for fingerprints. + # Check the version and decide which command to use. + + version_output, version_status = popen(%W(ssh -V)) + return false unless version_status.zero? + + version_matches = version_output.match(/OpenSSH_(?<major>\d+)\.(?<minor>\d+)/) + return false unless version_matches + + version_info = Gitlab::VersionInfo.new(version_matches[:major].to_i, version_matches[:minor].to_i) + + required_version_info = Gitlab::VersionInfo.new(6, 8) + + version_info >= required_version_info + end + end +end diff --git a/spec/lib/gitlab/key_fingerprint_spec.rb b/spec/lib/gitlab/key_fingerprint_spec.rb new file mode 100644 index 00000000000..266eab6e793 --- /dev/null +++ b/spec/lib/gitlab/key_fingerprint_spec.rb @@ -0,0 +1,12 @@ +require "spec_helper" + +describe Gitlab::KeyFingerprint do + let(:key) { "ssh-rsa AAAAB3NzaC1yc2EAAAABJQAAAIEAiPWx6WM4lhHNedGfBpPJNPpZ7yKu+dnn1SJejgt4596k6YjzGGphH2TUxwKzxcKDKKezwkpfnxPkSMkuEspGRt/aZZ9wa++Oi7Qkr8prgHc4soW6NUlfDzpvZK2H5E7eQaSeP3SAwGmQKUFHCddNaP0L+hM7zhFNzjFvpaMgJw0=" } + 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(Gitlab::KeyFingerprint.new(key).fingerprint).to eq(fingerprint) + end + end +end |