Welcome to mirror list, hosted at ThFree Co, Russian Federation.

gitlab.com/gitlab-org/gitaly.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/ruby/lib
diff options
context:
space:
mode:
authorJacob Vosmaer <jacob@gitlab.com>2019-11-06 12:45:58 +0300
committerZeger-Jan van de Weg <git@zjvandeweg.nl>2019-11-06 12:45:58 +0300
commitdafab928e8e4f43e39bf15f8f50f41a624a2cb11 (patch)
treef09c3246862b0872e90a66709a96d223d9f37e40 /ruby/lib
parentd509fbe28c14fe55f3e421e7a8abd56ffd981c5a (diff)
Stricter SSH argument checks
Diffstat (limited to 'ruby/lib')
-rw-r--r--ruby/lib/gitlab/git/ssh_auth.rb45
1 files changed, 33 insertions, 12 deletions
diff --git a/ruby/lib/gitlab/git/ssh_auth.rb b/ruby/lib/gitlab/git/ssh_auth.rb
index 80cb6401c..07cff31bc 100644
--- a/ruby/lib/gitlab/git/ssh_auth.rb
+++ b/ruby/lib/gitlab/git/ssh_auth.rb
@@ -1,3 +1,5 @@
+require 'shellwords'
+
module Gitlab
module Git
# SshAuth writes custom identity and known_hosts files to temporary files
@@ -9,6 +11,31 @@ module Gitlab
# # Run commands here with the provided environment
# end
class SshAuth
+ class Option
+ def initialize(key, value)
+ if key.include?('=') || needs_escape?(key)
+ raise ArgumentError, "invalid SSH config key: #{key.inspect}"
+ end
+
+ if needs_escape?(value)
+ raise ArgumentError, "invalid SSH config value: #{value.inspect}"
+ end
+
+ @key = key
+ @value = value
+ end
+
+ def to_s
+ "-o#{@key}=#{@value}"
+ end
+
+ private
+
+ def needs_escape?(str)
+ Shellwords.shellescape(str) != str
+ end
+ end
+
attr_reader :ssh_key, :known_hosts
def self.from_gitaly(request)
@@ -21,20 +48,20 @@ module Gitlab
end
def setup
- options = {}
+ options = []
if ssh_key.present?
key_file = write_tempfile('gitlab-shell-key-file', 0o400, ssh_key)
- options['IdentityFile'] = key_file.path
- options['IdentitiesOnly'] = 'yes'
+ options << Option.new('IdentityFile', key_file.path)
+ options << Option.new('IdentitiesOnly', 'yes')
end
if known_hosts.present?
known_hosts_file = write_tempfile('gitlab-shell-known-hosts', 0o400, known_hosts)
- options['StrictHostKeyChecking'] = 'yes'
- options['UserKnownHostsFile'] = known_hosts_file.path
+ options << Option.new('StrictHostKeyChecking', 'yes')
+ options << Option.new('UserKnownHostsFile', known_hosts_file.path)
end
yield custom_environment(options)
@@ -57,16 +84,10 @@ module Gitlab
# Constructs an environment that will make SSH, as invoked by git, respect
# the given options. To achieve this, we use the GIT_SSH_COMMAND envvar.
- #
- # Options are expanded as `'-oKey="Value"'`, so SSH will correctly
- # interpret paths with spaces in them. We trust the rest of this file not
- # to embed single or double quotes in the key or value.
def custom_environment(options)
return {} unless options.present?
- args = options.map { |k, v| %('-o#{k}="#{v}"') }
-
- { 'GIT_SSH_COMMAND' => %(ssh #{args.join(' ')}) }
+ { 'GIT_SSH_COMMAND' => %(ssh #{options.join(' ')}) }
end
end
end