pwnt.be

Forcing User Names with SSH Git

It’s been a while since I posted something geeky, so here goes. I’ve been playing with Git, everybody’s new favorite RCS, these last couple of days. Setting up an SSH-enabled Git repository is really easy, but it kind of introduces some redundancy. Let’s try and sort it out.

If you’re using Gitosis with a single Git user, don’t bother reading this article. In my particular scenario, I have SSH login already set up using LDAP and git-shell, and I want to make sure that the logged in user is also the author of the Git objects being pushed.

Why this requirement? Our students, who have LDAP accounts, will be allowed—nay, required—to use the Git repository for a project. They will be doing so in groups, so it is imperative that we keep a close eye on who’s been committing what. Obviously, we want Git logs to reflect that. Sure, we could use public keys, but I think a password login is easier for most guys; I can always set up GPG later if needed.

So, if you thought git could talk to sshd, or even forcibly copy the $USER variable, guess again. As crab helped me understand on #git, a git push is basically a request to copy objects to the repository, and there is no way to change the commit. It’s kind of annoying, but makes total sense.

There’s a nice alternative, however. By setting up a pre-receive hook, we can inspect commits and refuse them if their contents aren’t to our liking. So we just create hooks/pre-receive in the repository directory, fill it with the code below, and make it executable.

#!/bin/bash

mismatch=0
while read old new ref; do
  author=`git show --pretty=format:%an $new | head -1`
  if test "$USER" != "$author"; then
    echo
    echo "ERROR: Invalid user data on object $new:"
    echo "       Expecting \"$USER\", got \"$author\""
    mismatch=1
  fi
done
if test $mismatch -eq 1; then
  echo
  echo "Please run the following commands and try again:"
  echo "> git config user.name \"$USER\""
  echo "> git config user.email \"<your-email>\""
  echo "> git commit --amend --author=\"$USER <your-email>\""
  echo
fi
test $mismatch -eq 0

The additional commit is necessary, since the configuration will only apply to future commits. If the user leaves it out, he’ll just get the same error. The last line makes sure the exit status of the script tells Git what to do.

Also note that, in our case, $USER contains the student’s full name, making it an excellent value for the user.name option. If the user’s name is stored somewhere else, you’ll need to introduce some mapping code.

30 euro gratis!
Disorientation
Continuity
Retributions
Simple Linear Regression with JFreeChart
Dan Moore, Nicolas Machado, Sascha, Tim, Sascha, Tim, Sascha
Bizar Hairdressing & Beyond
Ramona, jul, Hanne, Hanne, Ruxi, Wim, Tim, Sarina, Lies, Lynn, erwin, Ano, Frederick, Jacqueline, Wazaaa, Tim, Rebecca, Charlie
Open brief aan Belgacom Proximus
Tim, pvc, ben, Tim, Simon Allais, Tim, Hans Similon, Simon Allais, Lander Foquet, Shane Vandewalle
Proximus, Universiteit Gent, Kafka: schrappen wat niet past
WouterH, Tim, Bart Coppens, Tim, Steven, Tim, Femke
Redeprognostication
Cédric Verstraeten, Tim, Joyce, Menti
Colophonics