summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYorick Peterse <yorickpeterse@gmail.com>2016-03-29 13:32:17 +0000
committerYorick Peterse <yorickpeterse@gmail.com>2016-03-29 13:32:17 +0000
commitfda23577b96bc1fcb50e0b6e7c41df729ece68dd (patch)
tree1aa59a1778b367d406de919d1e20dc5e3eb13b21
parent91e722550b40bbd8214e54a01b2183b27b95bde1 (diff)
parent38b8600f93ebe40eb9211051ef64b1013d053132 (diff)
downloadgitlab-shell-fda23577b96bc1fcb50e0b6e7c41df729ece68dd.tar.gz
Merge branch 'use-ssh-key-internal-api' into 'master'
Use ssh key internal api to build the authorized-keys command on openssh 6.9 See merge request !42
-rw-r--r--CHANGELOG3
-rw-r--r--VERSION2
-rwxr-xr-xbin/authorized_keys25
-rw-r--r--lib/gitlab_authorized_keys.rb0
-rw-r--r--lib/gitlab_keys.rb26
-rw-r--r--lib/gitlab_net.rb7
-rw-r--r--spec/gitlab_net_spec.rb36
-rw-r--r--spec/vcr_cassettes/ssh-key-not-found.yml50
-rw-r--r--spec/vcr_cassettes/ssh-key-not-implemented.yml50
-rw-r--r--spec/vcr_cassettes/ssh-key-ok.yml40
10 files changed, 224 insertions, 15 deletions
diff --git a/CHANGELOG b/CHANGELOG
index b339938..31ada42 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -1,3 +1,6 @@
+v2.6.14
+ - Add support for ssh AuthorizedKeysCommand query by key
+
v2.6.13
- Add push-branches command
- Add delete-remote-branches command
diff --git a/VERSION b/VERSION
index 6ac04ca..ec4704a 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-2.6.13
+2.6.14
diff --git a/bin/authorized_keys b/bin/authorized_keys
new file mode 100755
index 0000000..6aab4a5
--- /dev/null
+++ b/bin/authorized_keys
@@ -0,0 +1,25 @@
+#!/usr/bin/env ruby
+
+#
+# GitLab shell authorized_keys. Query GitLab API to get the authorized command for a given ssh key fingerprint
+#
+# Ex.
+# /bin/authorized_keys BASE64-KEY
+#
+# Returns
+# command="/bin/gitlab-shell key-#",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty ssh-rsa AAAAB3NzaC1yc2EAAAADAQA...
+#
+
+key = ARGV[0]
+abort "# No key provided" if key.nil? || key.empty?
+
+require_relative "../lib/gitlab_init"
+require_relative "../lib/gitlab_net"
+require_relative "../lib/gitlab_keys"
+
+authorized_key = GitlabNet.new.authorized_key(key)
+if authorized_key.nil?
+ puts "# No key was found for #{key}"
+else
+ puts GitlabKey.new.key_line("key-#{authorized_key['id']}", authorized_key["key"])
+end
diff --git a/lib/gitlab_authorized_keys.rb b/lib/gitlab_authorized_keys.rb
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/lib/gitlab_authorized_keys.rb
diff --git a/lib/gitlab_keys.rb b/lib/gitlab_keys.rb
index 3710f96..f17e6b7 100644
--- a/lib/gitlab_keys.rb
+++ b/lib/gitlab_keys.rb
@@ -11,6 +11,7 @@ class GitlabKeys
@key_id = ARGV.shift
@key = ARGV.shift
@auth_file = GitlabConfig.new.auth_file
+ @gitlab_key = GitlabKey.new
end
def exec
@@ -32,7 +33,7 @@ class GitlabKeys
def add_key
lock do
$logger.info "Adding key #{@key_id} => #{@key.inspect}"
- auth_line = key_line(@key_id, @key)
+ auth_line = @gitlab_key.key_line(@key_id, @key)
open(auth_file, 'a') { |file| file.puts(auth_line) }
end
true
@@ -59,7 +60,7 @@ class GitlabKeys
abort("#{$0}: invalid input #{input.inspect}") unless tokens.count == 2
key_id, public_key = tokens
$logger.info "Adding key #{key_id} => #{public_key.inspect}"
- file.puts(key_line(key_id, public_key))
+ file.puts(@gitlab_key.key_line(key_id, public_key))
end
end
end
@@ -70,20 +71,12 @@ class GitlabKeys
$stdin
end
- def key_command(key_id)
- "#{ROOT_PATH}/bin/gitlab-shell #{key_id}"
- end
-
- def key_line(key_id, public_key)
- auth_line = "command=\"#{key_command(key_id)}\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty #{public_key}"
- end
-
def rm_key
lock do
$logger.info "Removing key #{@key_id}"
open(auth_file, 'r+') do |f|
while line = f.gets do
- next unless line.start_with?("command=\"#{key_command(@key_id)}\"")
+ next unless line.start_with?("command=\"#{@gitlab_key.command(@key_id)}\"")
f.seek(-line.length, IO::SEEK_CUR)
# Overwrite the line with #'s. Because the 'line' variable contains
# a terminating '\n', we write line.length - 1 '#' characters.
@@ -115,3 +108,14 @@ class GitlabKeys
@lock_file ||= auth_file + '.lock'
end
end
+
+
+class GitlabKey
+ def command(key_id)
+ "#{ROOT_PATH}/bin/gitlab-shell #{key_id}"
+ end
+
+ def key_line(key_id, public_key)
+ "command=\"#{command(key_id)}\",no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty #{public_key}"
+ end
+end
diff --git a/lib/gitlab_net.rb b/lib/gitlab_net.rb
index 71e113b..8b6d33b 100644
--- a/lib/gitlab_net.rb
+++ b/lib/gitlab_net.rb
@@ -56,6 +56,13 @@ class GitlabNet
get("#{host}/check", read_timeout: CHECK_TIMEOUT)
end
+ def authorized_key(key)
+ resp = get("#{host}/authorized_keys?key=#{URI.escape(key, '+/=')}")
+ JSON.parse(resp.body) if resp.code == "200"
+ rescue
+ nil
+ end
+
protected
def config
diff --git a/spec/gitlab_net_spec.rb b/spec/gitlab_net_spec.rb
index 2d9b544..e4dee33 100644
--- a/spec/gitlab_net_spec.rb
+++ b/spec/gitlab_net_spec.rb
@@ -8,8 +8,8 @@ describe GitlabNet, vcr: true do
let(:changes) { ['0000000000000000000000000000000000000000 92d0970eefd7acb6d548878925ce2208cfe2d2ec refs/heads/branch4'] }
before do
- gitlab_net.stub!(:host).and_return('https://dev.gitlab.org/api/v3/internal')
- gitlab_net.stub!(:secret_token).and_return('a123')
+ gitlab_net.stub(:host).and_return('https://dev.gitlab.org/api/v3/internal')
+ gitlab_net.stub(:secret_token).and_return('a123')
end
describe :check do
@@ -76,6 +76,36 @@ describe GitlabNet, vcr: true do
end
end
+ describe :authorized_key do
+ let (:ssh_key) { "AAAAB3NzaC1yc2EAAAADAQABAAACAQDPKPqqnqQ9PDFw65cO7iHXrKw6ucSZg8Bd2CZ150Yy1YRDPJOWeRNCnddS+M/Lk" }
+
+ it "should return nil when the resource is not implemented" do
+ VCR.use_cassette("ssh-key-not-implemented") do
+ result = gitlab_net.authorized_key("whatever")
+ result.should be_nil
+ end
+ end
+
+ it "should return nil when the fingerprint is not found" do
+ VCR.use_cassette("ssh-key-not-found") do
+ result = gitlab_net.authorized_key("whatever")
+ result.should be_nil
+ end
+ end
+
+ it "should return a ssh key with a valid fingerprint" do
+ VCR.use_cassette("ssh-key-ok") do
+ result = gitlab_net.authorized_key(ssh_key)
+ result.should eq({
+ "created_at" => "2016-03-04T18:27:36.959Z",
+ "id" => 2,
+ "key" => "ssh-rsa a-made=up-rsa-key dummy@gitlab.com",
+ "title" => "some key title"
+ })
+ end
+ end
+ end
+
describe :check_access do
context 'ssh key with access to project' do
it 'should allow pull access for dev.gitlab.org' do
@@ -142,7 +172,7 @@ describe GitlabNet, vcr: true do
describe :http_client_for do
subject { gitlab_net.send :http_client_for, URI('https://localhost/') }
before do
- gitlab_net.stub! :cert_store
+ gitlab_net.stub :cert_store
gitlab_net.send(:config).stub(:http_settings) { {'self_signed_cert' => true} }
end
diff --git a/spec/vcr_cassettes/ssh-key-not-found.yml b/spec/vcr_cassettes/ssh-key-not-found.yml
new file mode 100644
index 0000000..55e5b4f
--- /dev/null
+++ b/spec/vcr_cassettes/ssh-key-not-found.yml
@@ -0,0 +1,50 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: https://dev.gitlab.org/api/v3/internal/authorized_keys?key=whatever
+ body:
+ encoding: US-ASCII
+ string: secret_token=a123
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ Content-Type:
+ - application/x-www-form-urlencoded
+ response:
+ status:
+ code: 404
+ message: Not Found
+ headers:
+ Server:
+ - nginx
+ Date:
+ - Mon, 07 Mar 2016 12:09:59 GMT
+ Content-Type:
+ - text/html; charset=utf-8
+ Connection:
+ - keep-alive
+ Cache-Control:
+ - no-cache
+ Set-Cookie:
+ - _gitlab_session=a924e63729e538c9efe10fa8338077d7; path=/; expires=Mon, 14
+ Mar 2016 12:09:59 -0000; secure; HttpOnly
+ Status:
+ - 404 Not Found
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Request-Id:
+ - 275ad011-515f-4239-80be-e537fd7c9086
+ X-Runtime:
+ - '2.169401'
+ X-Xss-Protection:
+ - 1; mode=block
+ http_version:
+ recorded_at: Mon, 07 Mar 2016 12:10:00 GMT
+recorded_with: VCR 2.4.0
diff --git a/spec/vcr_cassettes/ssh-key-not-implemented.yml b/spec/vcr_cassettes/ssh-key-not-implemented.yml
new file mode 100644
index 0000000..98c3c00
--- /dev/null
+++ b/spec/vcr_cassettes/ssh-key-not-implemented.yml
@@ -0,0 +1,50 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: https://dev.gitlab.org/api/v3/internal/authorized_keys?key=whatever
+ body:
+ encoding: US-ASCII
+ string: secret_token=a123
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ Content-Type:
+ - application/x-www-form-urlencoded
+ response:
+ status:
+ code: 501
+ message: Not Implemented
+ headers:
+ Server:
+ - nginx
+ Date:
+ - Mon, 07 Mar 2016 12:09:59 GMT
+ Content-Type:
+ - text/html; charset=utf-8
+ Connection:
+ - keep-alive
+ Cache-Control:
+ - no-cache
+ Set-Cookie:
+ - _gitlab_session=a924e63729e538c9efe10fa8338077d7; path=/; expires=Mon, 14
+ Mar 2016 12:09:59 -0000; secure; HttpOnly
+ Status:
+ - 501 Not Implemented
+ X-Content-Type-Options:
+ - nosniff
+ X-Frame-Options:
+ - SAMEORIGIN
+ X-Request-Id:
+ - 275ad011-515f-4239-80be-e537fd7c9086
+ X-Runtime:
+ - '2.169401'
+ X-Xss-Protection:
+ - 1; mode=block
+ http_version:
+ recorded_at: Mon, 07 Mar 2016 12:10:00 GMT
+recorded_with: VCR 2.4.0
diff --git a/spec/vcr_cassettes/ssh-key-ok.yml b/spec/vcr_cassettes/ssh-key-ok.yml
new file mode 100644
index 0000000..87817d1
--- /dev/null
+++ b/spec/vcr_cassettes/ssh-key-ok.yml
@@ -0,0 +1,40 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: https://dev.gitlab.org/api/v3/internal/authorized_keys?key=AAAAB3NzaC1yc2EAAAADAQABAAACAQDPKPqqnqQ9PDFw65cO7iHXrKw6ucSZg8Bd2CZ150Yy1YRDPJOWeRNCnddS+M/Lk
+ body:
+ encoding: US-ASCII
+ string: secret_token=a123
+ headers:
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ User-Agent:
+ - Ruby
+ Content-Type:
+ - application/x-www-form-urlencoded
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Server:
+ - nginx/1.1.19
+ Date:
+ - Wed, 03 Sep 2014 11:27:35 GMT
+ Content-Type:
+ - application/json
+ Connection:
+ - keep-alive
+ Status:
+ - 200 OK
+ Cache-Control:
+ - max-age=0, private, must-revalidate
+ body:
+ encoding: UTF-8
+ string: '{"id":2, "title":"some key title", "key":"ssh-rsa a-made=up-rsa-key dummy@gitlab.com", "created_at":"2016-03-04T18:27:36.959Z"}'
+ http_version:
+ recorded_at: Mon, 07 Mar 2016 12:10:00 GMT
+recorded_with: VCR 2.4.0