diff --git a/conf/example.gitolite.rc b/conf/example.gitolite.rc index e7df2dd..bda9d2d 100644 --- a/conf/example.gitolite.rc +++ b/conf/example.gitolite.rc @@ -75,19 +75,6 @@ $GIT_PATH=""; # -------------------------------------- -# if you want to give shell access to any gitolite user(s), name them here. -# Please see doc/6-ssh-troubleshooting.mkd for details on how this works. - -# Do not add people to this list indiscriminately. AUDITABILITY OF ACCESS -# CONTROL CHANGES (AND OF REPO ACCESSES) WILL BE COMPROMISED IF ADMINS CAN -# FIDDLE WITH THE ACTUAL (PLAIN TEXT) LOG FILES THAT GITOLITE KEEPS, WHICH -# THEY CAN EASILY DO IF THEY HAVE A SHELL. - -# syntax: space separated list of gitolite usernames in *one* string variable. -# $SHELL_USERS = "alice bob"; - -# -------------------------------------- - # ---------------------------------------------------------------------- diff --git a/doc/6-ssh-troubleshooting.mkd b/doc/6-ssh-troubleshooting.mkd index 976c6b6..826a5ff 100644 --- a/doc/6-ssh-troubleshooting.mkd +++ b/doc/6-ssh-troubleshooting.mkd @@ -386,32 +386,23 @@ instance if you have *two* gitolite servers you are administering)? We've managed (thanks to an idea from Jesse Keating) to make it possible for a single key to allow both gitolite access *and* shell access. -This is done by: +This is done by copying the pubkey (to which you want to give shell access) to +the server and running either - * (**on the server**) listing all such users in a variable called - `$SHELL_USERS` in the `~/.gitolite.rc` file. For example: + cd $HOME/.gitolite # assuming default $GL_ADMINDIR in ~/.gitolite.rc + src/gl-tool shell-add ~/foo.pub - $SHELL_USERS = "alice bob"; +or - (Note the syntax: a space separated list of users in one string variable). + gl-tool shell-add ~/foo.pub - * (**on your client**) make at least a dummy change to your clone of the - gitolite-admin repo and push it. +The first method is to be used if you used the **user-install** mode, while +the second method is for the **system-install followed by user-setup** mode +(see doc/0-INSTALL.mkd, section on "install methods", for more on this) -**IMPORTANT UPGRADE NOTE**: a previous implementation of this feature worked -by adding people to a special group (`@SHELL`) in the *config* file. This -meant that anyone with gitolite-admin repo write access could add himself to -the `@SHELL` group and push, thus obtaining shell. - -This is not a problem for most setups, but if someone wants to separate these -two privileges (the right to push the admin repo and the right to get a shell) -then it does pose a problem. Since the "rc" file can only be edited by -someone who already has shell access, we now use that instead, even though -this forces a change in the syntax. - -To migrate from the old scheme to the new one, add a new variable -`$SHELL_USERS` to `~/.gitolite.rc` on the server with the appropriate names in -it. **It is best to do this directly on the server *before* upgrading to this -version.** (After the upgrade is done and tested you can remove the `@SHELL` -lines from the gitolite config file). +**IMPORTANT UPGRADE NOTE**: previous implementations of this feature were +crap. There was no easy/elegant way to ensure that someone who had repo admin +access would not manage to get himself shell access. +Giving someone shell access requires that you should have shell access in the +first place, so the simplest way is to enable it from the server side only. diff --git a/src/gl-compile-conf b/src/gl-compile-conf index 1fb942b..786f19b 100755 --- a/src/gl-compile-conf +++ b/src/gl-compile-conf @@ -52,7 +52,7 @@ $Data::Dumper::Sortkeys = 1; 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, $SHELL_USERS, $GL_WILDREPOS, $GL_GITCONFIG_KEYS, $GL_PACKAGE_HOOKS); +our ($GL_ADMINDIR, $GL_CONF, $GL_KEYDIR, $GL_CONF_COMPILED, $REPO_BASE, $REPO_UMASK, $PROJECTS_LIST, $GIT_PATH, $GL_WILDREPOS, $GL_GITCONFIG_KEYS, $GL_PACKAGE_HOOKS); # and these are set by gitolite.pm our ($REPONAME_PATT, $REPOPATT_PATT, $USERNAME_PATT, $AUTH_COMMAND, $AUTH_OPTIONS, $ABRT, $WARN); @@ -537,11 +537,7 @@ for my $pubkey (glob("*")) print STDERR "WARNING: a pubkey file can only have one line (key); ignoring $pubkey\n"; next; } - if ($SHELL_USERS and $SHELL_USERS =~ /(^|\s)$user(\s|$)/) { - print $newkeys_fh "command=\"$AUTH_COMMAND -s $user\",$AUTH_OPTIONS "; - } else { - print $newkeys_fh "command=\"$AUTH_COMMAND $user\",$AUTH_OPTIONS,no-pty "; - } + print $newkeys_fh "command=\"$AUTH_COMMAND $user\",$AUTH_OPTIONS,no-pty "; print $newkeys_fh $pubkey_content; } # lint check 3; a little more severe than the first two I guess... diff --git a/src/gl-tool b/src/gl-tool new file mode 100755 index 0000000..f6a201a --- /dev/null +++ b/src/gl-tool @@ -0,0 +1,74 @@ +#!/bin/sh + +# BEGIN USAGE + +# $0 -- make some server side tasks easier + +# Usage: +# $0 [sub-command [args]] + +# Security notes: this program does not do any sanitisation of input. You're +# running it at the CLI on the server, so you already have the power to do +# whatever you want anyway. + +# current sub-commands: + +# (1) REPLACE THE OLD $SHELL_USERS MECHANISM + +# $0 shell-add foo.pub +# adds the pubkey in foo.pub into the authkeys file with "-s" argument (shell +# access) and user "foo". The line will be added *before* the "# gitolite +# start" section, so that a gitolite-admin push will not affect it. + +# Although there is no "shell-remove" sub-command, you can do that quite +# easily by editing ~/.ssh/authorized_keys and deleting the appropriate line. + +# END USAGE + + +die() { echo "$@"; exit 1; } + +if [ -z "$1" ] +then + perl -ne 's/\$0/$ARGV/ge; print if /BEGIN USAGE/../END USAGE/' $0 | grep -v USAGE | cut -c3- + exit 1 +fi + +if [ "$1" = "shell-add" ] +then + # sanity checks + [ -z "$2" ] && exec $0 + [ -f "$2" ] || die "$2 does not exist" + wc -l < $2 | grep '^1$' >/dev/null || die "$2 contains more than one line" + + # must be kept consistent with what's in src/gl-compile-conf; on the plus + # side, it's not likely to change anytime soon! + AUTH_OPTIONS="no-port-forwarding,no-X11-forwarding,no-agent-forwarding" + + bindir=`echo $0 | perl -lpe 's/^/$ENV{PWD}\// unless /^\//; s/\/[^\/]+$//;'` + + pubkey_file=$2 + user=`basename $pubkey_file .pub` + + authline="command=\"$bindir/gl-auth-command -s $user\",$AUTH_OPTIONS `cat $pubkey_file`"; + + authkeys=$HOME/.ssh/authorized_keys + + for i in 1 + do + perl -lne "last if /# gitolite start/; print unless /gl-auth-command -s $user/; " $authkeys + echo $authline + perl -lne "print if /# gitolite start/ .. 0; " $authkeys + done > $authkeys.new + + diff -u $authkeys $authkeys.new && die no change to authkey file + echo + echo If the above diff looks ok, press enter. Else press Ctrl-C. + read dummy + cat $authkeys > $authkeys.old + cat $authkeys.new > $authkeys + + exit 0 +fi + +die "could not understand command $1"