diff --git a/contrib/real-users/gl-shell b/contrib/real-users/gl-shell new file mode 100755 index 0000000..08eaae6 --- /dev/null +++ b/contrib/real-users/gl-shell @@ -0,0 +1,46 @@ +#!/usr/bin/perl + +use strict; +use warnings; + +# ------------------------------------------------------------------------------ + +# site-local changes + +# the original login shell your users had. Set this to something like +# "/sbin/nologin" or "/bin/false" if you don't want them to have a normal +# shell (i.e., you created these accounts *only* to provide a password +# authentication passthru to gitolite) +my $shell = "/bin/bash"; + +# the gitolite hosting user you want to forward git commands to. Typically +# this will be 'git' or perhaps 'gitolite', but actually could be anything +my $hosting_user = "gitolite-test"; + +# ------------------------------------------------------------------------------ + +# process normal logins (the ones that *don't* get forwarded to the gitolite +# hosting user) + +# this is a normal login, not to be forwarded to the gitolite hosting user, if: +# - there are no arguments +exec($shell) unless @ARGV; +# - the first argument is not "-c" +exec($shell, @ARGV) unless $ARGV[0] eq '-c'; +# - the second argument does not fit what git usually sends +exec($shell, @ARGV) unless $ARGV[1] =~ /^(git-receive-pack|git-upload-pack|git-upload-archive) '(\S+)'$/; +# - there *is* a local directory with the same name as the second part of argument #2 +exec($shell, @ARGV) if -d $2; + +# ------------------------------------------------------------------------------ + +# if all that failed, it means we have to forward this to the hosting user + +# this message is important in debugging and trouble shooting; see documentation +print STDERR "[forwarding to $hosting_user\@localhost]\n"; + +# but first we check for rsa key +-f ".ssh/id_rsa" or die "ask your admin to add you to gitolite"; + +shift; # that pesky '-c'... +exec("ssh", "$hosting_user\@localhost", @ARGV); diff --git a/contrib/real-users/gl-shell-setup b/contrib/real-users/gl-shell-setup new file mode 100755 index 0000000..c5015b3 --- /dev/null +++ b/contrib/real-users/gl-shell-setup @@ -0,0 +1,110 @@ +#!/bin/bash + +# WARNING 1: probably contains bashisms galore. If you don't have bash, +# please install it. + +# NOTE 1: this script is initially run as root, then it calls itself with an +# "su" so it can run as the hosting user. + +# NOTE 2: if you'd rather do this manually, just do the first part as root, +# and the second part as the hosting user, with only the name of the user +# (alice) and her pub key (~alice/.ssh/id_rsa.pub) needing to be passed from +# root to the hosting user id. + +# ------------------------------------------------------------------------------ + +# site-local changes + +# the gitolite hosting user you want to forward git commands to. Typically +# this will be 'git' or perhaps 'gitolite', but actually could be anything +hosting_user="gitolite-test" + +# absolute path of the gitolite-admin repo +admin_repo="/home/gitolite-test/repositories/gitolite-admin.git" + +# the full path to the new login shell to replace these users' existing shell +new_shell="/usr/local/bin/gl-shell" + +my_chsh() { + # please replace with appropriate command for your OS/distro. This one is + # suitable at least for Fedora, maybe others also + chsh -s $new_shell $1 +} + +# remove these 2 lines after you have done your customisation +[ -f /tmp/done.gl-shell-setup ] || { echo please customise $0 before using; exit 1; } + +# ------------------------------------------------------------------------------ + +die() { echo "FATAL: $@" >&2; exit 1; } + +# ------------------------------------------------------------------------------ + +euid=$(perl -e 'print $>') +if [ "$euid" = "0" ] +then + + # -------------------------------------------------------------------------- + # stuff to be done as root + # -------------------------------------------------------------------------- + + [ -n "$1" ] || die "need a valid username" + user=$1 + id $user >/dev/null || die "need a valid username" + + # now fix up the user's login shell + my_chsh $user + + # drat... 'cd ~$user` doesn't work... + cd $(bash -c "echo ~$user") || die "can't cd to $user's home directory" + + # now set up her rsa key, creating it if needed + [ -d .ssh ] || { + mkdir .ssh + chown $user .ssh + chmod go-w .ssh + } + [ -f .ssh/id_rsa.pub ] || { + ssh-keygen -q -N "" -f .ssh/id_rsa + chown $user .ssh/id_rsa .ssh/id_rsa.pub + chmod go-rw .ssh/id_rsa + chmod go-w .ssh/id_rsa.pub + } + + # now run yourself as the hosting user, piping in the pubkey to STDIN, and + # passing the username whose key it is as argument 1. + cat .ssh/id_rsa.pub | su -l -c "$0 $user" $hosting_user + + # finally, as $user (alice) ssh to the hosting_user once so that the + # hostkey checking gets done and you get the correct hostkey in + # ~user/.ssh/known_hosts + su -c "ssh -o StrictHostKeyChecking=no $hosting_user@localhost info" - $user + + exit 0 + +else + + # -------------------------------------------------------------------------- + # stuff to be done as the hosting user + # -------------------------------------------------------------------------- + + user=$1 + + # make a temp dir and switch to it + export tmp=$(mktemp -d) + cd $tmp || die "could not cd to temp dir $tmp" + trap "rm -rf $tmp" 0 + + # clone the admin repo here + git clone $admin_repo . + # copy alice's pubkey, which was sent in via STDIN. We don't want to + # overwrite any *other* keys she may have, hence the @localhost part. + # (See "one user, many keys" in doc/3 for more on this @ part). + cat > keydir/$user@localhost.pub + # add commit push... + git add keydir/$user@localhost.pub + git diff --cached --quiet 2>/dev/null || git commit -am "$0: added/updated local key for $user" + gl-admin-push + # see doc for what/why this is + +fi diff --git a/contrib/real-users/password-access.mkd b/contrib/real-users/password-access.mkd new file mode 100644 index 0000000..9628268 --- /dev/null +++ b/contrib/real-users/password-access.mkd @@ -0,0 +1,145 @@ +# password access to gitolite + +## (a.k.a: turning real users into gitolite users) + + + +### problems + +*Problem 1*: Here's one type of problem some admins have: + + * Some of your users already have a real (unix) userid on the *same server* + as the gitolite hosting user. + * They don't all use ssh keys; some may still be using passwords and don't + want to change. + * They want to use this existing userid to access the gitolite served repos. + +This document has a solution to this problem! + +*Problem 2*: And here's a somewhat different one: + + * Some of your users are not willing to use ssh keys; they're only + comfortable with passwords. + * But gitolite *requires* ssh key-based access; it can't work if you use a + password to get access (because then there is no way to distinguish one + user from another). + +Well, as the math folks say, "reduce it to a known problem". Give them all +Unix userids on the same server as gitolite, with password access, so that +problem 2 reduces to problem 1 ;-) + +If you created these Unix accounts *only* to solve this +pesky password problem, and do not wish them to actually have shell access or +be able to do anything else on the server, don't worry -- that's easy to +handle too. + + + +### solution + +Briefly, the Unix userid is made to act like a "gitolite proxy". + +Here's a more detailed explanation. + +Normal gitolite flow, for a user called Alice, is like this: + + ssh key + alice ----------------------------------------> git + (workstation) (REQUIRED) (server) + +However, if Alice has her own real (unix) userid on the server, and the admin +sets things up according to this document, then Alice can do this: + + password + alice ------ OR -----> alice + (workstation) ssh key (server) + +The **important** thing to note here is that she doesn't need ssh keys; she +can use passwords if she wants to. + +Behind the scenes, the gitolite/git conversation is being transparently +forwarded to the gitolite hosting user, so it is *actually* like this: + + password ssh key + alice ------ OR -----> alice - - - - - - - > git + (workstation) ssh key (server) (REQUIRED) (localhost) + +The second connection is transparent to Alice; she still thinks she is talking +to her own userid. In git URL terms, she simply uses `alice@server:reponame`, +without realising that behind the scenes this is getting forwarded to +`git@server:reponame`. + +This second connection *does* require ssh keys, but since they're all on the +server, it's scriptable and automatable so the user doesn't have to deal with +these pesky ssh keys. + + + +### some hints, notes and caveats + + * This doesn't mean all your users have to be like this. You can have + normal users also. In fact, you can have users who give you a pub key + from their workstation the normal way, as well as use this method. + + * Special commands and ADCs will NOT work from the workstation for such + users; they have to log on to their own userid on the server and run the + appropriate command (such as `ssh git@localhost info`) from there. We could have handled the known special commands (info, + expand, setperms, etc.), but considering that an ADC could be called + *anything*, a general solution is impossible. + + * If you server's host key changes, you may have to manually fix up all the + host keys in all the user's `~/.ssh/known_hosts` files. Not too difficult + if you're sure they all have just the one host key, but if they have + multiple, you have to carefully delete and replace just the one line that + pertains to localhost. Scripts to do this cleanly are welcome... + + + +### what the 2 scripts actually do + + * `gl-shell` will become the new login shell for these users. This shell + will forward git clone/fetch/push requests to the gitolite server. + + This redirection is so transparent that I had to explicitly code a message + ("forwarding to git@server") to make troubleshooting easier. + + * `gl-shell-setup` is run by root, once for each user. (You can run it + multiple times; it's designed to be idempotent). As root, it changes the + user's shell to `gl-shell` (full path), then sets up an RSA key for the + user if one is not already present. Then it runs as `git` (or whatever + the hosting user is) and takes the pubkey and adds it as (to continue our + example) `alice@localhost.pub` in keydir of the admin repo, which is then + pushed. + + Notice the use of [this trick][oumk] to allow Alice to allow users to have + other (gitolite normal) keys as well, such as perhaps from a laptop. + + + +### setting it up + +Here's how to set this up. First, the **one-time** tasks: + + * Install gitolite as normal, if not already installed. This will require + you to use ssh keys for your (admin's) own access, but I assume that's ok. + + * As root, copy the program `contrib/real-users/gl-shell` to + `/usr/local/bin`. + + * As root, customise the program `/usr/local/bin/gl-shell`. You will need + to change only 2 variables at the top in a section clearly marked as + 'site-local changes'. + + * As root, copy `contrib/real-users/gl-shell-setup` to some place on root's + `$PATH` and customise it similarly to gl-shell. Note that there are many + more configurable values in this script. **NOTE** also that this includes + fixing the `chsh` command, which may be OS/distro dependent. The supplied + command is good for Fedora. + +Now, for each user 'alice' that has her own real (unix) userid, and also needs +to access gitolite *via* her own id, run the command `gl-shell-setup alice`. + +And that's really all there is to it. + +[oumk]: http://sitaramc.github.com/gitolite/doc/3-faq-tips-etc.html#_one_user_many_keys