diff --git a/src/gitolite.pm b/src/gitolite.pm index c7276bd..71c0b0c 100644 --- a/src/gitolite.pm +++ b/src/gitolite.pm @@ -13,6 +13,35 @@ # - define a function that tells you where to find the rc file # - define a function that creates a new repo and give it our update hook +# ---------------------------------------------------------------------------- +# common definitions +# ---------------------------------------------------------------------------- + +$ABRT = "\n\t\t***** ABORTING *****\n "; +$WARN = "\n\t\t***** WARNING *****\n "; + +# commands we're expecting +$R_COMMANDS=qr/^(git[ -]upload-pack|git[ -]upload-archive)$/; +$W_COMMANDS=qr/^git[ -]receive-pack$/; + +# note that REPONAME_PATT allows a "/" also, which USERNAME_PATT doesn't +$REPONAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._/-]*$); # very simple pattern +$USERNAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._-]*$); # very simple pattern + +# ---------------------------------------------------------------------------- +# convenience subs +# ---------------------------------------------------------------------------- + +sub wrap_chdir { + chdir($_[0]) or die "$ABRT chdir $_[0] failed: $! at ", (caller)[1], " line ", (caller)[2], "\n"; +} + +sub wrap_open { + open (my $fh, $_[0], $_[1]) or die "$ABRT open $_[1] failed: $! at ", (caller)[1], " line ", (caller)[2], "\n" . + ( $_[2] || '' ); # suffix custom error message if given + return $fh; +} + # ---------------------------------------------------------------------------- # where is the rc file hiding? # ---------------------------------------------------------------------------- @@ -43,17 +72,9 @@ sub where_is_rc } } -$ABRT = "\n\t\t***** ABORTING *****\n "; -$WARN = "\n\t\t***** WARNING *****\n "; -sub wrap_chdir { - chdir($_[0]) or die "$ABRT chdir $_[0] failed: $! at ", (caller)[1], " line ", (caller)[2], "\n"; -} - -sub wrap_open { - open (my $fh, $_[0], $_[1]) or die "$ABRT open $_[1] failed: $! at ", (caller)[1], " line ", (caller)[2], "\n" . - ( $_[2] || '' ); # suffix custom error message if given - return $fh; -} +# ---------------------------------------------------------------------------- +# create a new repository +# ---------------------------------------------------------------------------- # NOTE: this sub will change your cwd; caller beware! sub new_repo @@ -71,4 +92,36 @@ sub new_repo chmod 0755, "hooks/update"; } +# ---------------------------------------------------------------------------- +# parse the compiled acl +# ---------------------------------------------------------------------------- + +sub parse_acl +{ + my $GL_CONF_COMPILED = shift; + die "parse $GL_CONF_COMPILED failed: " . ($! or $@) unless do $GL_CONF_COMPILED; +} + +# ---------------------------------------------------------------------------- +# print a report of $user's basic permissions +# ---------------------------------------------------------------------------- + +# basic means wildcards will be shown as wildcards; this is pretty much what +# got parsed by the compile script +sub report_basic +{ + my($GL_ADMINDIR, $GL_CONF_COMPILED, $user) = @_; + + &parse_acl($GL_CONF_COMPILED); + + # send back some useful info if no command was given + print "hello $user, the gitolite version here is "; + system("cat", "$GL_ADMINDIR/src/VERSION"); + print "\ryou have the following permissions:\n\r"; + for my $r (sort keys %repos) { + my $perm .= ( $repos{$r}{R}{'@all'} ? ' @' : ( $repos{$r}{R}{$user} ? ' R' : '' ) ); + $perm .= ( $repos{$r}{W}{'@all'} ? ' @' : ( $repos{$r}{W}{$user} ? ' W' : '' ) ); + print "$perm\t$r\n\r" if $perm; + } +} 1; diff --git a/src/gl-auth-command b/src/gl-auth-command index a135be6..86fec88 100755 --- a/src/gl-auth-command +++ b/src/gl-auth-command @@ -24,7 +24,10 @@ use warnings; # ---------------------------------------------------------------------------- +# these are set by the "rc" file our ($GL_LOGT, $GL_CONF_COMPILED, $REPO_BASE, $GIT_PATH, $GL_ADMINDIR); +# and these are set by gitolite.pm +our ($R_COMMANDS, $W_COMMANDS, $REPONAME_PATT); our %repos; # the common setup module is in the same directory as this running program is @@ -35,20 +38,10 @@ require "$bindir/gitolite.pm"; # ask where the rc file is, get it, and "do" it &where_is_rc(); die "parse $ENV{GL_RC} failed: " . ($! or $@) unless do $ENV{GL_RC}; -# then "do" the compiled config file, whose name we now know -die "parse $GL_CONF_COMPILED failed: " . ($! or $@) unless do $GL_CONF_COMPILED; # add a custom path for git binaries, if specified $ENV{PATH} .= ":$GIT_PATH" if $GIT_PATH; -# ---------------------------------------------------------------------------- -# definitions specific to this program -# ---------------------------------------------------------------------------- - -my $R_COMMANDS=qr/^(git[ -]upload-pack|git[ -]upload-archive)$/; -my $W_COMMANDS=qr/^git[ -]receive-pack$/; -my $REPONAME_PATT=qr(^[0-9a-zA-Z][0-9a-zA-Z._/-]*$); # very simple pattern - # ---------------------------------------------------------------------------- # start... # ---------------------------------------------------------------------------- @@ -62,15 +55,7 @@ my $user=$ENV{GL_USER}=shift; # there; now that's available everywhere! # SSH_ORIGINAL_COMMAND must exist; if not, we die with a nice message unless ($ENV{SSH_ORIGINAL_COMMAND}) { - # send back some useful info if no command was given - print "hello $user, the gitolite version here is "; - system("cat", "$GL_ADMINDIR/src/VERSION"); - print "\ryou have the following permissions:\n\r"; - for my $r (sort keys %repos) { - my $perm .= ( $repos{$r}{R}{'@all'} ? ' @' : ( $repos{$r}{R}{$user} ? ' R' : '' ) ); - $perm .= ( $repos{$r}{W}{'@all'} ? ' @' : ( $repos{$r}{W}{$user} ? ' W' : '' ) ); - print "$perm\t$r\n\r" if $perm; - } + &report_basic($GL_ADMINDIR, $GL_CONF_COMPILED, $user); exit 1; } @@ -93,6 +78,9 @@ die "bad command: $cmd. Make sure the repo name is exactly as in your config\n" # first level permissions check # ---------------------------------------------------------------------------- +# parse the compiled acl; goes into %repos (global) +&parse_acl($GL_CONF_COMPILED); + # we know the user and repo; we just need to know what perm he's trying my $perm = ($verb =~ $R_COMMANDS ? 'R' : 'W'); @@ -102,11 +90,12 @@ die "$perm access for $repo DENIED to $user\n" # create the repo if it doesn't already exist and the user has "W" access my $repo_base_abs = ( $REPO_BASE =~ m(^/) ? $REPO_BASE : "$ENV{HOME}/$REPO_BASE" ); -if ( ( $repos{$repo}{W}{$user} - or $repos{$repo}{W}{'@all'} ) and not -d "$repo_base_abs/$repo.git" ) { - wrap_chdir("$repo_base_abs"); - new_repo($repo, "$GL_ADMINDIR/src/hooks"); - wrap_chdir($ENV{HOME}); +if ( not -d "$repo_base_abs/$repo.git" ) { + if ( $repos{$repo}{W}{$user} or $repos{$repo}{W}{'@all'} ) { + wrap_chdir("$repo_base_abs"); + new_repo($repo, "$GL_ADMINDIR/src/hooks"); + wrap_chdir($ENV{HOME}); + } } # ---------------------------------------------------------------------------- diff --git a/src/gl-compile-conf b/src/gl-compile-conf index bbb2eb6..56b11ed 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -51,8 +51,10 @@ $Data::Dumper::Sortkeys = 1; # setup quiet mode if asked; please do not use this when running manually open STDOUT, ">", "/dev/null" if (@ARGV and shift eq '-q'); +# these are set by the "rc" file our ($GL_ADMINDIR, $GL_CONF, $GL_KEYDIR, $GL_CONF_COMPILED, $REPO_BASE, $REPO_UMASK, $PROJECTS_LIST, $GIT_PATH); -our ($ABRT, $WARN); +# and these are set by gitolite.pm +our ($REPONAME_PATT, $USERNAME_PATT, $AUTH_COMMAND, $AUTH_OPTIONS, $ABRT, $WARN); # the common setup module is in the same directory as this running program is my $bindir = $0; @@ -71,11 +73,8 @@ $ENV{PATH} .= ":$GIT_PATH" if $GIT_PATH; # ---------------------------------------------------------------------------- # command and options for authorized_keys -my $AUTH_COMMAND="$GL_ADMINDIR/src/gl-auth-command"; -my $AUTH_OPTIONS="no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty"; -# note that REPONAME_PATT allows a "/" also, which USERNAME_PATT doesn't -my $REPONAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._/-]*$); # very simple pattern -my $USERNAME_PATT=qr(^\@?[0-9a-zA-Z][0-9a-zA-Z._-]*$); # very simple pattern +$AUTH_COMMAND="$GL_ADMINDIR/src/gl-auth-command"; +$AUTH_OPTIONS="no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty"; # groups can now represent user groups or repo groups.