I have installed git and gitosis and I need to add a check that the user name is valid when something is pushed into the repository.
I reckon the pre-receive hook is the correct hook to place this, but I'm unable to find the real user name and email address which gitosis enters into the repository (the ones set by git config user.name and git config user.email) from environment variables. LOGNAME and USER are both 'git'. How does gitosis detect this info and can I find it in the pre-receive hook as well?
Hmm, from what I gather from githooks(5)
the pre-receive
hook gets fed the updated refs on stdin
.
#!/bin/sh
while read old new name; do
email=$(git log -1 --pretty=format:%ae $new)
# check email
done
You would need to check the email addresses (there can be more than one line of data) and exit the script accordingly, i.e. exit 0
for success and e.g. exit 1
for failure.
OK, we managed to get the job done, Bombe's reply above helped a lot. This is how it was done:
- I added os.environ['GITOSIS_USER'] = user to Gitosis/Serve.py, function Main() and reinstalled it.
- I then created the following pre-receive script:
hooks/pre-receive
#!/usr/bin/perl
my $user = $ENV{'GITOSIS_USER'};
if ($user !~ m/^[^@]+@[^@]+$/ ) {
print STDERR "Unknown user. Not running under Gitosis?\n";
exit 1;
}
my $fail = 0;
while(<STDIN>) {
if (m/^([0-9a-f]+)\s+([0-9a-f]+)\s+(\S+)$/) {
my $oldver = $1;
my $curver = $2;
my $ref = $3;
my $ret = open (FH, "-|", "git", "rev-list", '--pretty=format:%H:%ae:%ce',$
if ($ret) {
# great and less brakets hidden in HTML: >FH<
while (<FH>) {
chomp;
my $line = $_;
if ($_ !~ m/commit /) {
my ($rev, $author, $committer) = split(":", $line);
if ( $author ne $user && $committer ne $user ) {
print STDERR "Unauthorized commit: $rev\n";
$fail++;
}
}
}
}
}
}
if ($fail) {
exit 1;
}
exit 0;
This means the user name has to be the same as the one used to create the ssh key for gitosis key ring.
That script is broken in several ways. First, the open() line is cut off. After I fixed that, the script went into an infinite loop on the first while(), not even attempting to call git-rev-list.
With a little help from my friends, I managed to spruce it up a bit:
hooks/pre-receive
#!/usr/bin/perl
my $user = $ENV{'GITOSIS_USER'};
if ($user !~ m/^[^@]+@[^@]+$/ ) {
print STDERR "Unknown user. Not running under Gitosis?\n";
exit 1;
}
my $fail = 0;
while(<STDIN>) {
if (m/^([0-9a-f]+)\s+([0-9a-f]+)\s+(\S+)$/) {
my $oldver = $1;
my $curver = $2;
my $ref = $3;
my $ret = open (FH, "-|", "git", "rev-list", '-- pretty=format:%H:%ae:%ce',"$oldver..$curver");
if ($ret) {
while (<FH>) {
chomp;
my $line = $_;
if ($_ !~ m/commit /) {
my ($rev, $author, $committer) = split(":", $line);
if ( $author ne $user && $committer ne $user ) {
print STDERR "Unauthorized commit: $rev\n";
print STDERR "You must specify Author and Committer.\n";
print STDERR "Specified a/c: $author / $committer\n";
print STDERR "Expected user: $user\n";
$fail++;
}
}
}
}
}
}
if ($fail) {
exit 1;
}
exit 0;
Adding os.environ['WHATVER_USER']=user at ~line 202 in serve.py should do the trick...
You can check <gitosis-path>/.ssh/authorized_keys
and see:
command="gitosis-serve name@server",...
Read man for sshd
and found: after command="command"
you can add environment="NAME=value"
option to set the desired user names for you public ssh keys. And no Gitosis/Serve.py
editing required.
Environment processing is disabled by default and is controlled via the PermitUserEnvironment
option:
sudo echo "PermitUserEnvironment yes" >> /etc/ssh/sshd_config
来源:https://stackoverflow.com/questions/824990/git-gitosis-how-to-check-validity-of-user-name-and-email