From 1f2b84c46c261c5209f782cfa4fe4a228af561df Mon Sep 17 00:00:00 2001 From: Petr Baudis Date: Fri, 25 Jul 2008 12:31:15 +0200 Subject: [PATCH] Introduce Girocco::ProjPerm::Hooks --- Girocco/Config.pm | 5 +++-- Girocco/ProjPerm.pm | 41 +++++++++++++++++++++++++++++++++++++++++ update-hook | 41 ++++++++++++++++++++++++++++++++++------- 3 files changed, 78 insertions(+), 9 deletions(-) diff --git a/Girocco/Config.pm b/Girocco/Config.pm index d30efb6..372611e 100644 --- a/Girocco/Config.pm +++ b/Girocco/Config.pm @@ -123,7 +123,7 @@ our $chrooted = $manage_users; # * 'Hooks' for a relaxed model: The directories are world-writable and push # permission control is purely hook-driven. This is INSECURE and works only # when you trust all your users; on the other hand, the attack vectors are -# mostly just DoS or fully-traceable tinkering. UNIMPLEMENTED too. +# mostly just DoS or fully-traceable tinkering. our $permission_control = 'Group'; @@ -134,7 +134,8 @@ our $permission_control = 'Group'; (not $mirror or $mirror_user) or die "Girocco::Config: \$mirror set but \$mirror_user is undef"; ($manage_users == $chrooted) or die "Girocco::Config: \$manage_users and \$chrooted must be set to the same value"; (not $chrooted or $permission_control ne 'ACL') or die "Girocco::Config: resolving uids for ACL not supported when using chroot"; -($permission_control eq 'Group') or die "Girocco::Config: \$permission_control must be set to Group for now"; +(grep { $permission_control eq $_ } qw(Group Hooks)) or die "Girocco::Config: \$permission_control must be set to Group or Hooks"; +($chrooted or not $mob) or die "Girocco::Config: mob user supported only in the chrooted mode"; 1; diff --git a/Girocco/ProjPerm.pm b/Girocco/ProjPerm.pm index aeaa562..1aa92fc 100644 --- a/Girocco/ProjPerm.pm +++ b/Girocco/ProjPerm.pm @@ -74,3 +74,44 @@ sub shared_mode { } 1; + + +package Girocco::ProjPerm::Hooks; + +# This is the "soft-security" permission model: we keep the repository +# world-writable and check if the user is allowed to push only within +# the update hook that will call our can_user_push() method. + +use strict; +use warnings; + +BEGIN { + use base qw(Girocco::ProjPerm); +} + +sub perm_initialize { + my ($proj) = @_; + 1; +} + +sub perm_user_add { + my ($proj, $username, $uid) = @_; + 1; +} + +sub perm_user_del { + my ($proj, $username, $uid) = @_; + 1; +} + +sub shared_mode { + my ($proj) = @_; + "0777"; +} + +sub can_user_push { + my ($proj, $username) = @_; + grep { $_ eq $username } $proj->{users}; +} + +1; diff --git a/update-hook b/update-hook index 98b419e..9e82949 100755 --- a/update-hook +++ b/update-hook @@ -6,16 +6,43 @@ # branches push permissions support. # +## Girocco::Config::basedir +basedir=/home/repo/repomgr + set -e -if [ -O /var/run/mob ]; then - if [ x"$1" != x"refs/heads/mob" ]; then - echo "The mob user can push only to the 'mob' branch, sorry" >&2 - exit 1 +if ! [ -x /usr/bin/perl ]; then + # We are INSIDE the chroot + + if [ -O /var/run/mob ]; then + if [ x"$1" != x"refs/heads/mob" ]; then + echo "The mob user can push only to the 'mob' branch, sorry" >&2 + exit 1 + fi + if [ x"$2" = x"0000000000000000000000000000000000000000" ]; then + echo "The mob user cannot _create_ the 'mob' branch, sorry" >&2 + exit 2 + fi fi - if [ x"$2" = x"0000000000000000000000000000000000000000" ]; then - echo "The mob user cannot _create_ the 'mob' branch, sorry" >&2 - exit 2 + + exit 0 +fi + +# We are NOT inside the chroot + +# Import all the variables from Girocco::Config to the local environment, +# prefixing them with 'cfg_'. E.g. $cfg_admin is admin's mail address now. +eval $(perl -I"$basedir" -MGirocco::Config -le 'foreach (keys %Girocco::Config::) { print "cfg_$_=\"".quotemeta(${$Girocco::Config::{$_}})."\""; }') + +if [ "$cfg_permission_control" = "Hooks" ]; then + # We have some permission control to do! + proj="$(pwd)" + proj="${proj#$cfg_reporoot}" + # XXX: Sanity check on project name and $USER here? Seems superfluous. + if ! perl -I"$basedir" -MGirocco::Project -le 'exit(1) unless Girocco::Project->load("'$proj'")->can_user_push("'$USER'")'; then + echo "The user '$USER' does not have push permissions for project '$proj'" >&2 + echo "You can adjust push permissions at $cfg_webadmurl/editproj.cgi?name=$proj" >&2 + exit 3 fi fi -- 2.11.4.GIT