From ed2bf526f82eb2d281fb83e8126580b78223fa94 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sun, 13 Dec 2009 19:17:18 +0530 Subject: [PATCH 1/6] minor docfix --- doc/3-faq-tips-etc.mkd | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/doc/3-faq-tips-etc.mkd b/doc/3-faq-tips-etc.mkd index b6c65d9..0e3af99 100644 --- a/doc/3-faq-tips-etc.mkd +++ b/doc/3-faq-tips-etc.mkd @@ -101,10 +101,10 @@ normal way, since it's not empty anymore. So at least one of your clients needs to have a recent git. Once at least one commit has been made, older clients can also use it - * when you clone an empty repo, git seems to complain about the remote - hanging up or something. I have no idea what that is, but it doesn't seem - to hurt anything. This happens even in normal git, not just gitolite. - [Update 2009-09-14; this has been fixed in git 1.6.4.3] + * when you clone an empty repo, git seems to complain about `fatal: The + remote end hung up unexpectedly`. However, you can ignore this, since it + doesn't seem to hurt anything. [Update 2009-09-14; this has been fixed in + git 1.6.4.3] * gitweb not able to read your repos? You can change the umask for newly created repos to something more relaxed -- see the `~/.gitolite.rc` file From b7404aa772adee312483760da869497f6d2a64a2 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Tue, 15 Dec 2009 12:35:48 +0530 Subject: [PATCH 2/6] auth/install/pu-hook: pass ADMINDIR and BINDIR via ENV The admin repo's post-update hook needs to know where $GL_ADMINDIR is, and we had a weird way of doing that which depended on gl-install actually munging the hook code. We also always assumed the binaries are in GL_ADMINDIR/src. We now use an env var to pass both these values. This removes the weird dependency on gl-install that the post-update hook had, as well as make running other programs easier due to the new $GL_BINDIR env var. --- src/ga-post-update-hook | 7 ++----- src/gl-auth-command | 5 +++++ src/gl-compile-conf | 2 +- src/gl-easy-install | 2 +- src/gl-install | 2 -- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/ga-post-update-hook b/src/ga-post-update-hook index 8090b8a..91d2bfb 100755 --- a/src/ga-post-update-hook +++ b/src/ga-post-update-hook @@ -1,10 +1,7 @@ #!/bin/sh -# get this from your .gitolite.conf; and don't forget this is shell, while -# that is perl :-) -export GL_ADMINDIR; GL_ADMINDIR=$HOME/.gitolite - # checkout the master branch to $GL_ADMINDIR +# (the GL_ADMINDIR env var would have been set by gl-auth-command) GIT_WORK_TREE=$GL_ADMINDIR git checkout -f master # remove all fragments. otherwise, you get spurious error messages when you @@ -31,4 +28,4 @@ do done cd $GL_ADMINDIR -src/gl-compile-conf +$GL_BINDIR/gl-compile-conf diff --git a/src/gl-auth-command b/src/gl-auth-command index 86fec88..12b3234 100755 --- a/src/gl-auth-command +++ b/src/gl-auth-command @@ -39,6 +39,11 @@ require "$bindir/gitolite.pm"; &where_is_rc(); die "parse $ENV{GL_RC} failed: " . ($! or $@) unless do $ENV{GL_RC}; +# we need to pass GL_ADMINDIR and the bindir to the child hooks (well only the +# admin repo's post-update hook but still...) +$ENV{GL_ADMINDIR} = $GL_ADMINDIR; +$ENV{GL_BINDIR} = $bindir; + # add a custom path for git binaries, if specified $ENV{PATH} .= ":$GIT_PATH" if $GIT_PATH; diff --git a/src/gl-compile-conf b/src/gl-compile-conf index 138249d..ab1155c 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -73,7 +73,7 @@ $ENV{PATH} .= ":$GIT_PATH" if $GIT_PATH; # ---------------------------------------------------------------------------- # command and options for authorized_keys -$AUTH_COMMAND="$GL_ADMINDIR/src/gl-auth-command"; +$AUTH_COMMAND="$bindir/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. diff --git a/src/gl-easy-install b/src/gl-easy-install index db20e2f..d73c82d 100755 --- a/src/gl-easy-install +++ b/src/gl-easy-install @@ -48,7 +48,7 @@ main() { [[ $upgrade == 0 ]] && initial_conf_key # MANUAL: cd to $GL_ADMINDIR and run "src/gl-compile-conf" - ssh -p $port $user@$host "cd $GL_ADMINDIR; src/gl-compile-conf $quiet" + ssh -p $port $user@$host "cd $GL_ADMINDIR; \$PWD/src/gl-compile-conf $quiet" setup_pta diff --git a/src/gl-install b/src/gl-install index a4dc729..9494fc6 100755 --- a/src/gl-install +++ b/src/gl-install @@ -79,8 +79,6 @@ for my $repo (`find . -type d -name "*.git"`) { if ( -d "gitolite-admin.git/hooks" ) { print "copying post-update hook to gitolite-admin repo...\n"; system("cp $GL_ADMINDIR/src/ga-post-update-hook gitolite-admin.git/hooks/post-update"); - system("perl", "-i", "-p", "-e", "s(GL_ADMINDIR=.*)(GL_ADMINDIR=$GL_ADMINDIR)", - "gitolite-admin.git/hooks/post-update"); chmod 0755, "gitolite-admin.git/hooks/post-update"; } From 512fc4a0a547a3c29d1502e8caddd692ac880890 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Tue, 15 Dec 2009 16:11:21 +0530 Subject: [PATCH 3/6] auth: set umask when autoviv-ing repos Looks like I'd forgotten this when I did the autoviv code. Repos created via gl-compile (when you add a new repo to the config file and push) worked fine, but repos created via gl-auth (when you autoviv a repo, wild or not) did not. This *should* be merged into wildrepos soon after testing; wildrepos will have a lot more autoviv-ing than master. --- src/gl-auth-command | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/gl-auth-command b/src/gl-auth-command index 12b3234..463439e 100755 --- a/src/gl-auth-command +++ b/src/gl-auth-command @@ -23,9 +23,8 @@ use warnings; # common definitions # ---------------------------------------------------------------------------- - # these are set by the "rc" file -our ($GL_LOGT, $GL_CONF_COMPILED, $REPO_BASE, $GIT_PATH, $GL_ADMINDIR); +our ($GL_LOGT, $GL_CONF_COMPILED, $REPO_BASE, $GIT_PATH, $REPO_UMASK, $GL_ADMINDIR); # and these are set by gitolite.pm our ($R_COMMANDS, $W_COMMANDS, $REPONAME_PATT); our %repos; @@ -47,6 +46,9 @@ $ENV{GL_BINDIR} = $bindir; # add a custom path for git binaries, if specified $ENV{PATH} .= ":$GIT_PATH" if $GIT_PATH; +# set the umask before creating any files +umask($REPO_UMASK); + # ---------------------------------------------------------------------------- # start... # ---------------------------------------------------------------------------- From b679bbb56bdc1a44a316298c9c3f7fb0d52f13dc Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Fri, 18 Dec 2009 10:15:35 +0530 Subject: [PATCH 4/6] allow '+' as valid character in user/reponames --- src/gitolite.pm | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/gitolite.pm b/src/gitolite.pm index ee0fc77..d905a72 100644 --- a/src/gitolite.pm +++ b/src/gitolite.pm @@ -25,8 +25,8 @@ $R_COMMANDS=qr/^(git[ -]upload-pack|git[ -]upload-archive)$/; $W_COMMANDS=qr/^git[ -]receive-pack$/; # note that REPONAME_PATT allows "/", while USERNAME_PATT allows "@" -$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 +$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 From 75de6c0438090d0d4d4e593867739d638cb7f8d6 Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sat, 19 Dec 2009 20:52:30 +0530 Subject: [PATCH 5/6] auth: (WDITOT?) allow special users to get a shell ".../gl-auth-command username" is the normal command that authkeys forces, and this prevents that key from being used to get a shell. We now allow the user to get a shell if the forced command has a "-s" before the "username", like ".../gl-auth-command -s sitaram". (Now that a plain "ssh gitolite" gets you a shell, there's a new "info" command that such privileged keys can use to get basic access info). Thanks to Jesse Keating for the idea! I can't believe this never occurred to me before, but I guess I was so enamoured of my "innovation" in converting what used to be an error into some useful info I didn't think a bit more :/ --- src/gl-auth-command | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-) diff --git a/src/gl-auth-command b/src/gl-auth-command index 463439e..2de7d43 100755 --- a/src/gl-auth-command +++ b/src/gl-auth-command @@ -53,6 +53,14 @@ umask($REPO_UMASK); # start... # ---------------------------------------------------------------------------- +# if the first argument is a "-s", this user is allowed to get a shell using +# this key +my $shell_allowed = 0; +if ($ARGV[0] eq '-s') { + $shell_allowed = 1; + shift; +} + # first, fix the biggest gripe I have with gitosis, a 1-line change my $user=$ENV{GL_USER}=shift; # there; now that's available everywhere! @@ -60,13 +68,24 @@ my $user=$ENV{GL_USER}=shift; # there; now that's available everywhere! # sanity checks on SSH_ORIGINAL_COMMAND # ---------------------------------------------------------------------------- -# SSH_ORIGINAL_COMMAND must exist; if not, we die with a nice message +# print basic access info if SSH_ORIGINAL_COMMAND does not exist unless ($ENV{SSH_ORIGINAL_COMMAND}) { + # unless the user is allowed to use a shell + if ($shell_allowed) { + my $shell = $ENV{SHELL}; + $shell =~ s/.*\//-/; # change "/bin/bash" to "-bash" + exec { $ENV{SHELL} } $shell; + } &report_basic($GL_ADMINDIR, $GL_CONF_COMPILED, $user); exit 1; } my $cmd = $ENV{SSH_ORIGINAL_COMMAND}; +# people allowed to get a shell can get basic access info by asking nicely +if ($shell_allowed and $cmd eq 'info') { + &report_basic($GL_ADMINDIR, $GL_CONF_COMPILED, $user); + exit 1; +} # split into command and arguments; the pattern allows old style as well as # new style: "git-subcommand arg" or "git subcommand arg", just like gitosis @@ -77,9 +96,12 @@ my $cmd = $ENV{SSH_ORIGINAL_COMMAND}; # including the single quotes my ($verb, $repo) = ($cmd =~ /^\s*(git\s+\S+|\S+)\s+'\/?(.*?)(?:.git)?'/); -die "bad command: $cmd. Make sure the repo name is exactly as in your config\n" - unless ( $verb and ( $verb =~ $R_COMMANDS or $verb =~ $W_COMMANDS ) - and $repo and $repo =~ $REPONAME_PATT ); +unless ( $verb and ( $verb =~ $R_COMMANDS or $verb =~ $W_COMMANDS ) and $repo and $repo =~ $REPONAME_PATT ) { + # if the user is allowed a shell, just run the command + exec $ENV{SHELL}, "-c", $ENV{SSH_ORIGINAL_COMMAND} if $shell_allowed; + # otherwise, whine + die "bad command: $cmd\n"; +} # ---------------------------------------------------------------------------- # first level permissions check From 2cc19091ca53e38bf4458d6c39ca409a8c95979d Mon Sep 17 00:00:00 2001 From: Sitaram Chamarty Date: Sat, 19 Dec 2009 21:36:55 +0530 Subject: [PATCH 6/6] compile: gitolite key as good as shell key for users in @SHELL group done by inserting a "-s" into the authkey forced command. (They also lose the "no-pty" restriction, for good measure!) --- src/gl-compile-conf | 9 +++++++-- src/gl-easy-install | 3 +++ 2 files changed, 10 insertions(+), 2 deletions(-) diff --git a/src/gl-compile-conf b/src/gl-compile-conf index ab1155c..b8e8a1c 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -74,7 +74,8 @@ $ENV{PATH} .= ":$GIT_PATH" if $GIT_PATH; # command and options for authorized_keys $AUTH_COMMAND="$bindir/gl-auth-command"; -$AUTH_OPTIONS="no-port-forwarding,no-X11-forwarding,no-agent-forwarding,no-pty"; +$AUTH_OPTIONS="no-port-forwarding,no-X11-forwarding,no-agent-forwarding"; + # note, for most users there's also a "no-pty" added to this, see later # groups can now represent user groups or repo groups. @@ -441,7 +442,11 @@ for my $pubkey (glob("*")) print STDERR "WARNING: pubkey $pubkey exists but user $user not in config\n" unless $user_list{$user}; $user_list{$user} = 'has pubkey'; - print $newkeys_fh "command=\"$AUTH_COMMAND $user\",$AUTH_OPTIONS "; + if ($groups{'@SHELL'}{$user}) { + print $newkeys_fh "command=\"$AUTH_COMMAND -s $user\",$AUTH_OPTIONS "; + } else { + print $newkeys_fh "command=\"$AUTH_COMMAND $user\",$AUTH_OPTIONS,no-pty "; + } # apparently some pubkeys don't end in a newline... my $pubkey_content = `cat $pubkey`; $pubkey_content =~ s/\s*$/\n/; diff --git a/src/gl-easy-install b/src/gl-easy-install index d73c82d..b74621a 100755 --- a/src/gl-easy-install +++ b/src/gl-easy-install @@ -361,6 +361,7 @@ run_install() { # MANUAL: setup the initial config file. Edit $GL_ADMINDIR/conf/gitolite.conf # and add at least the following lines to it: +# @SHELL = sitaram # repo gitolite-admin # RW+ = sitaram @@ -368,6 +369,8 @@ initial_conf_key() { echo "#gitolite conf # please see conf/example.conf for details on syntax and features +@SHELL = $admin_name + repo gitolite-admin RW+ = $admin_name