我已经安装了git和gitosis,当有内容被推送到仓库时,我需要添加一个检查来验证用户名是否有效。
我认为pre-receive hook是正确的挂钩点,但我无法从环境变量中找到gitosis输入到仓库中的真实用户名和电子邮件地址(由git config user.name和git config user.email设置)。LOGNAME和USER都是“git”。gitosis如何检测这些信息,并且我能否在pre-receive hook中找到它们?
根据githooks(5)
,pre-receive
钩子会从stdin
中获取更新的引用。
#!/bin/sh
while read old new name; do
email=$(git log -1 --pretty=format:%ae $new)
# check email
done
您需要检查电子邮件地址(可能有多行数据),并相应地退出脚本,例如成功时使用exit 0
,失败时使用exit 1
。
好的,我们成功完成了工作,Bombe在上面的回复帮了很大的忙。以下是完成方法:
os.environ['GITOSIS_USER'] = user
并重新安装了它。
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;
这意味着用户名称必须与用于创建gitosis密钥环的ssh密钥相同。
这个脚本有几个问题。首先,open()行被截断了。在我修复了这个问题之后,脚本进入了第一个while()的无限循环,甚至没有尝试调用git-rev-list。
在我的朋友的帮助下,我成功地改善了它:
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;
您可以检查<gitosis-path>/.ssh/authorized_keys
并查看:
command="gitosis-serve name@server",...
阅读sshd
的手册,发现:在command="command"
之后,您可以添加environment="NAME=value"
选项来设置所需用户名称以使用公共ssh密钥。无需编辑Gitosis/Serve.py
。
默认情况下禁用环境处理,并通过PermitUserEnvironment
选项进行控制:
sudo echo "PermitUserEnvironment yes" >> /etc/ssh/sshd_config