Commit 7735ef86 authored by Patricio Cano's avatar Patricio Cano

Only allow Git Access on the allowed protocol

parent ea9d910c
...@@ -162,7 +162,7 @@ class Projects::GitHttpController < Projects::ApplicationController ...@@ -162,7 +162,7 @@ class Projects::GitHttpController < Projects::ApplicationController
return false unless Gitlab.config.gitlab_shell.upload_pack return false unless Gitlab.config.gitlab_shell.upload_pack
if user if user
Gitlab::GitAccess.new(user, project).download_access_check.allowed? Gitlab::GitAccess.new(user, project, 'http').download_access_check.allowed?
else else
ci? || project.public? ci? || project.public?
end end
......
...@@ -47,9 +47,9 @@ module ApplicationSettingsHelper ...@@ -47,9 +47,9 @@ module ApplicationSettingsHelper
def enabled_project_tooltip(project, protocol) def enabled_project_tooltip(project, protocol)
case protocol case protocol
when 'ssh' when 'ssh'
sanitize_clone_button(ssh_clone_button(project)) sanitize_clone_button(ssh_clone_button(project, 'bottom'))
else else
sanitize_clone_button(http_clone_button(project)) sanitize_clone_button(http_clone_button(project, 'bottom'))
end end
end end
......
...@@ -40,7 +40,7 @@ module ButtonHelper ...@@ -40,7 +40,7 @@ module ButtonHelper
type: :button type: :button
end end
def http_clone_button(project) def http_clone_button(project, placement = 'right')
klass = 'http-selector' klass = 'http-selector'
klass << ' has-tooltip' if current_user.try(:require_password?) klass << ' has-tooltip' if current_user.try(:require_password?)
...@@ -51,13 +51,13 @@ module ButtonHelper ...@@ -51,13 +51,13 @@ module ButtonHelper
href: project.http_url_to_repo, href: project.http_url_to_repo,
data: { data: {
html: true, html: true,
placement: 'right', placement: placement,
container: 'body', container: 'body',
title: "Set a password on your account<br>to pull or push via #{protocol}" title: "Set a password on your account<br>to pull or push via #{protocol}"
} }
end end
def ssh_clone_button(project) def ssh_clone_button(project, placement = 'right')
klass = 'ssh-selector' klass = 'ssh-selector'
klass << ' has-tooltip' if current_user.try(:require_ssh_key?) klass << ' has-tooltip' if current_user.try(:require_ssh_key?)
...@@ -66,7 +66,7 @@ module ButtonHelper ...@@ -66,7 +66,7 @@ module ButtonHelper
href: project.ssh_url_to_repo, href: project.ssh_url_to_repo,
data: { data: {
html: true, html: true,
placement: 'right', placement: placement,
container: 'body', container: 'body',
title: 'Add an SSH key to your profile<br>to pull or push via SSH.' title: 'Add an SSH key to your profile<br>to pull or push via SSH.'
} }
......
...@@ -59,7 +59,8 @@ class ApplicationSetting < ActiveRecord::Base ...@@ -59,7 +59,8 @@ class ApplicationSetting < ActiveRecord::Base
presence: true, presence: true,
inclusion: { in: ->(_object) { Gitlab.config.repositories.storages.keys } } inclusion: { in: ->(_object) { Gitlab.config.repositories.storages.keys } }
validates_inclusion_of :enabled_git_access_protocols, in: %w(ssh http), allow_blank: true, allow_nil: true validates :enabled_git_access_protocols,
inclusion: { in: %w(ssh http), allow_blank: true, allow_nil: true }
validates_each :restricted_visibility_levels do |record, attr, value| validates_each :restricted_visibility_levels do |record, attr, value|
unless value.nil? unless value.nil?
......
...@@ -13,6 +13,7 @@ module API ...@@ -13,6 +13,7 @@ module API
# action - git action (git-upload-pack or git-receive-pack) # action - git action (git-upload-pack or git-receive-pack)
# ref - branch name # ref - branch name
# forced_push - forced_push # forced_push - forced_push
# protocol - Git access protocol being used, e.g. HTTP or SSH
# #
helpers do helpers do
...@@ -46,11 +47,13 @@ module API ...@@ -46,11 +47,13 @@ module API
User.find_by(id: params[:user_id]) User.find_by(id: params[:user_id])
end end
protocol = params[:protocol]
access = access =
if wiki? if wiki?
Gitlab::GitAccessWiki.new(actor, project) Gitlab::GitAccessWiki.new(actor, project, protocol)
else else
Gitlab::GitAccess.new(actor, project) Gitlab::GitAccess.new(actor, project, protocol)
end end
access_status = access.check(params[:action], params[:changes]) access_status = access.check(params[:action], params[:changes])
......
...@@ -34,7 +34,8 @@ module Gitlab ...@@ -34,7 +34,8 @@ module Gitlab
vars = { vars = {
'GL_ID' => gl_id, 'GL_ID' => gl_id,
'PWD' => repo_path 'PWD' => repo_path,
'PROTOCOL' => 'web'
} }
options = { options = {
......
...@@ -3,11 +3,12 @@ module Gitlab ...@@ -3,11 +3,12 @@ module Gitlab
DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive } DOWNLOAD_COMMANDS = %w{ git-upload-pack git-upload-archive }
PUSH_COMMANDS = %w{ git-receive-pack } PUSH_COMMANDS = %w{ git-receive-pack }
attr_reader :actor, :project attr_reader :actor, :project, :protocol
def initialize(actor, project) def initialize(actor, project, protocol = nil)
@actor = actor @actor = actor
@project = project @project = project
@protocol = protocol
end end
def user def user
...@@ -49,6 +50,8 @@ module Gitlab ...@@ -49,6 +50,8 @@ module Gitlab
end end
def check(cmd, changes = nil) def check(cmd, changes = nil)
return build_status_object(false, "Git access over #{protocol.upcase} is not allowed") unless protocol_allowed?
unless actor unless actor
return build_status_object(false, "No user or key was provided.") return build_status_object(false, "No user or key was provided.")
end end
...@@ -72,6 +75,8 @@ module Gitlab ...@@ -72,6 +75,8 @@ module Gitlab
end end
def download_access_check def download_access_check
return build_status_object(false, "Git access over #{protocol.upcase} is not allowed") unless protocol_allowed?
if user if user
user_download_access_check user_download_access_check
elsif deploy_key elsif deploy_key
...@@ -82,6 +87,8 @@ module Gitlab ...@@ -82,6 +87,8 @@ module Gitlab
end end
def push_access_check(changes) def push_access_check(changes)
return build_status_object(false, "Git access over #{protocol.upcase} is not allowed") unless protocol_allowed?
if user if user
user_push_access_check(changes) user_push_access_check(changes)
elsif deploy_key elsif deploy_key
...@@ -92,6 +99,8 @@ module Gitlab ...@@ -92,6 +99,8 @@ module Gitlab
end end
def user_download_access_check def user_download_access_check
return build_status_object(false, "Git access over #{protocol.upcase} is not allowed") unless protocol_allowed?
unless user.can?(:download_code, project) unless user.can?(:download_code, project)
return build_status_object(false, "You are not allowed to download code from this project.") return build_status_object(false, "You are not allowed to download code from this project.")
end end
...@@ -100,6 +109,8 @@ module Gitlab ...@@ -100,6 +109,8 @@ module Gitlab
end end
def user_push_access_check(changes) def user_push_access_check(changes)
return build_status_object(false, "Git access over #{protocol.upcase} is not allowed") unless protocol_allowed?
if changes.blank? if changes.blank?
return build_status_object(true) return build_status_object(true)
end end
...@@ -188,6 +199,10 @@ module Gitlab ...@@ -188,6 +199,10 @@ module Gitlab
Gitlab::UserAccess.allowed?(user) Gitlab::UserAccess.allowed?(user)
end end
def protocol_allowed?
protocol ? Gitlab::ProtocolAccess.allowed?(protocol) : true
end
def branch_name(ref) def branch_name(ref)
ref = ref.to_s ref = ref.to_s
if Gitlab::Git.branch_ref?(ref) if Gitlab::Git.branch_ref?(ref)
......
module Gitlab
module ProtocolAccess
def self.allowed?(protocol)
if protocol.to_s == 'web'
true
elsif !current_application_settings.enabled_git_access_protocols.present?
true
else
protocol.to_s == current_application_settings.enabled_git_access_protocols
end
end
end
end
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment