summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDouwe Maan <douwe@gitlab.com>2015-02-23 23:14:57 +0100
committerDouwe Maan <douwe@gitlab.com>2015-03-02 17:52:48 +0100
commitdd37a10df44bd1771aa8b163fd857628d03842d9 (patch)
treed03c778b2fcf3452a58aa678369390c5481d70a5
parent039fd3c5620823d2eab340e6c033954cdbd982eb (diff)
downloadgitlab-ce-dd37a10df44bd1771aa8b163fd857628d03842d9.tar.gz
Don't leak information about private project existence via Git-over-SSH/HTTP.
-rw-r--r--lib/api/internal.rb39
-rw-r--r--lib/gitlab/backend/grack_auth.rb52
2 files changed, 50 insertions, 41 deletions
diff --git a/lib/api/internal.rb b/lib/api/internal.rb
index ba3fe619b92..753d0fcbd98 100644
--- a/lib/api/internal.rb
+++ b/lib/api/internal.rb
@@ -16,6 +16,17 @@ module API
#
post "/allowed" do
status 200
+
+ actor = if params[:key_id]
+ Key.find_by(id: params[:key_id])
+ elsif params[:user_id]
+ User.find_by(id: params[:user_id])
+ end
+
+ unless actor
+ return Gitlab::GitAccessStatus.new(false, 'No such user or key')
+ end
+
project_path = params[:project]
# Check for *.wiki repositories.
@@ -32,26 +43,20 @@ module API
project = Project.find_with_namespace(project_path)
- unless project
- return Gitlab::GitAccessStatus.new(false, 'No such project')
+ if project
+ status = access.check(
+ actor,
+ params[:action],
+ project,
+ params[:changes]
+ )
end
- actor = if params[:key_id]
- Key.find_by(id: params[:key_id])
- elsif params[:user_id]
- User.find_by(id: params[:user_id])
- end
-
- unless actor
- return Gitlab::GitAccessStatus.new(false, 'No such user or key')
+ if project && status && status.allowed?
+ status
+ else
+ Gitlab::GitAccessStatus.new(false, 'No such project')
end
-
- access.check(
- actor,
- params[:action],
- project,
- params[:changes]
- )
end
#
diff --git a/lib/gitlab/backend/grack_auth.rb b/lib/gitlab/backend/grack_auth.rb
index dc4b945f9d4..ee877e099b1 100644
--- a/lib/gitlab/backend/grack_auth.rb
+++ b/lib/gitlab/backend/grack_auth.rb
@@ -10,8 +10,9 @@ module Grack
@request = Rack::Request.new(env)
@auth = Request.new(env)
- # Need this patch due to the rails mount
+ @gitlab_ci = false
+ # Need this patch due to the rails mount
# Need this if under RELATIVE_URL_ROOT
unless Gitlab.config.gitlab.relative_url_root.empty?
# If website is mounted using relative_url_root need to remove it first
@@ -22,8 +23,12 @@ module Grack
@env['SCRIPT_NAME'] = ""
- if project
- auth!
+ auth!
+
+ if project && authorized_request?
+ @app.call(env)
+ elsif @user.nil? && !@gitlab_ci
+ unauthorized
else
render_not_found
end
@@ -32,35 +37,30 @@ module Grack
private
def auth!
- if @auth.provided?
- return bad_request unless @auth.basic?
-
- # Authentication with username and password
- login, password = @auth.credentials
+ return unless @auth.provided?
- # Allow authentication for GitLab CI service
- # if valid token passed
- if gitlab_ci_request?(login, password)
- return @app.call(env)
- end
+ return bad_request unless @auth.basic?
- @user = authenticate_user(login, password)
+ # Authentication with username and password
+ login, password = @auth.credentials
- if @user
- Gitlab::ShellEnv.set_env(@user)
- @env['REMOTE_USER'] = @auth.username
- end
+ # Allow authentication for GitLab CI service
+ # if valid token passed
+ if gitlab_ci_request?(login, password)
+ @gitlab_ci = true
+ return
end
- if authorized_request?
- @app.call(env)
- else
- unauthorized
+ @user = authenticate_user(login, password)
+
+ if @user
+ Gitlab::ShellEnv.set_env(@user)
+ @env['REMOTE_USER'] = @auth.username
end
end
def gitlab_ci_request?(login, password)
- if login == "gitlab-ci-token" && project.gitlab_ci?
+ if login == "gitlab-ci-token" && project && project.gitlab_ci?
token = project.gitlab_ci_service.token
if token.present? && token == password && git_cmd == 'git-upload-pack'
@@ -107,6 +107,8 @@ module Grack
end
def authorized_request?
+ return true if @gitlab_ci
+
case git_cmd
when *Gitlab::GitAccess::DOWNLOAD_COMMANDS
if user
@@ -141,7 +143,9 @@ module Grack
end
def project
- @project ||= project_by_path(@request.path_info)
+ return @project if defined?(@project)
+
+ @project = project_by_path(@request.path_info)
end
def project_by_path(path)