diff options
author | Nick Thomas <nick@gitlab.com> | 2017-08-03 13:19:11 +0100 |
---|---|---|
committer | Nick Thomas <nick@gitlab.com> | 2017-08-07 19:17:11 +0100 |
commit | da5262f4e6d9524b2af2ad8f6c8ebe10edf17169 (patch) | |
tree | a26da5b83832daea538b1a927403fc66422b8c48 /lib | |
parent | bfac6ce6e4a2415b76db1cd7321e312457c7ee89 (diff) | |
download | gitlab-ce-da5262f4e6d9524b2af2ad8f6c8ebe10edf17169.tar.gz |
Backport changes in https://gitlab.com/gitlab-org/gitlab-ee/merge_requests/2551 to CE
Diffstat (limited to 'lib')
-rw-r--r-- | lib/gitlab/key_fingerprint.rb | 71 | ||||
-rw-r--r-- | lib/gitlab/shell.rb | 24 |
2 files changed, 50 insertions, 45 deletions
diff --git a/lib/gitlab/key_fingerprint.rb b/lib/gitlab/key_fingerprint.rb index b75ae512d92..d9a79f7c291 100644 --- a/lib/gitlab/key_fingerprint.rb +++ b/lib/gitlab/key_fingerprint.rb @@ -1,55 +1,48 @@ module Gitlab class KeyFingerprint - include Gitlab::Popen + attr_reader :key, :ssh_key - attr_accessor :key + # Unqualified MD5 fingerprint for compatibility + delegate :fingerprint, to: :ssh_key, allow_nil: true 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('ssh-keygen') - cmd.push('-E', 'md5') if explicit_fingerprint_algorithm? - cmd.push('-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] + @ssh_key = + begin + Net::SSH::KeyFactory.load_data_public_key(key) + rescue Net::SSH::Exception, NotImplementedError + end 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? + def valid? + ssh_key.present? + end - version_matches = version_output.match(/OpenSSH_(?<major>\d+)\.(?<minor>\d+)/) - return false unless version_matches + def type + return unless valid? - version_info = Gitlab::VersionInfo.new(version_matches[:major].to_i, version_matches[:minor].to_i) + parts = ssh_key.ssh_type.split('-') + parts.shift if parts[0] == 'ssh' - required_version_info = Gitlab::VersionInfo.new(6, 8) + parts[0].upcase + end - version_info >= required_version_info + def bits + return unless valid? + + case type + when 'RSA' + ssh_key.n.num_bits + when 'DSS', 'DSA' + ssh_key.p.num_bits + when 'ECDSA' + ssh_key.group.order.num_bits + when 'ED25519' + 256 + else + raise "Unsupported key type: #{type}" + end end end end diff --git a/lib/gitlab/shell.rb b/lib/gitlab/shell.rb index 4366ff336ef..0cb28732402 100644 --- a/lib/gitlab/shell.rb +++ b/lib/gitlab/shell.rb @@ -105,12 +105,24 @@ module Gitlab # fetch_remote("gitlab/gitlab-ci", "upstream") # # Gitaly migration: https://gitlab.com/gitlab-org/gitaly/issues/387 - def fetch_remote(storage, name, remote, forced: false, no_tags: false) + def fetch_remote(storage, name, remote, ssh_auth: nil, forced: false, no_tags: false) args = [gitlab_shell_projects_path, 'fetch-remote', storage, "#{name}.git", remote, "#{Gitlab.config.gitlab_shell.git_timeout}"] args << '--force' if forced args << '--no-tags' if no_tags - gitlab_shell_fast_execute_raise_error(args) + vars = {} + + if ssh_auth&.ssh_import? + if ssh_auth.ssh_key_auth? && ssh_auth.ssh_private_key.present? + vars['GITLAB_SHELL_SSH_KEY'] = ssh_auth.ssh_private_key + end + + if ssh_auth.ssh_known_hosts.present? + vars['GITLAB_SHELL_KNOWN_HOSTS'] = ssh_auth.ssh_known_hosts + end + end + + gitlab_shell_fast_execute_raise_error(args, vars) end # Move repository @@ -293,15 +305,15 @@ module Gitlab false end - def gitlab_shell_fast_execute_raise_error(cmd) - output, status = gitlab_shell_fast_execute_helper(cmd) + def gitlab_shell_fast_execute_raise_error(cmd, vars = {}) + output, status = gitlab_shell_fast_execute_helper(cmd, vars) raise Error, output unless status.zero? true end - def gitlab_shell_fast_execute_helper(cmd) - vars = ENV.to_h.slice(*GITLAB_SHELL_ENV_VARS) + def gitlab_shell_fast_execute_helper(cmd, vars = {}) + vars.merge!(ENV.to_h.slice(*GITLAB_SHELL_ENV_VARS)) # Don't pass along the entire parent environment to prevent gitlab-shell # from wasting I/O by searching through GEM_PATH |