3 # A git daemon with an added userv security boundary.
5 # This reads the first packet-line of the protocol, checks the syntax
6 # of the pathname and hostname, then uses userv to invoke the
7 # git-upload-pack as the target user with safe arguments.
9 # This was written by Tony Finch <dot@dotat.at>
10 # You may do anything with it, at your own risk.
11 # http://creativecommons.org/publicdomain/zero/1.0/
24 if (defined $sockaddr) {
25 my ($port,$addr) = sockaddr_in
$sockaddr;
26 $addr = inet_ntoa
$addr;
27 return ($addr,$port,"[$addr]:$port");
29 return (undef,undef,"[?.?.?.?]:?");
33 my ($client_addr,$client_port,$client) = ntoa
getpeername STDIN
;
34 my ($server_addr,$server_port,$server) = ntoa
getsockname STDIN
;
36 openlog
'userv-git-daemon', 'pid', 'daemon';
39 syslog
'err', "$client @_";
46 local $SIG{ALRM
} = sub { fail
"timeout" };
48 while ($length > length $buffer) {
49 my $ret = sysread STDIN
, $buffer, $length, length $buffer;
50 fail
"short read: expected $length bytes, got " . length $buffer
51 if defined $ret and $ret == 0;
52 fail
"read: $!" if not defined $ret and $! != EINTR
and $! != EAGAIN
;
53 $ret = 0 if not defined $ret;
59 my $len_hex = xread
4;
60 fail
"non-hex packet length" unless $len_hex =~ m{^[0-9a-fA-F]{4}$};
61 my $line = xread
hex $len_hex;
62 unless ($line =~ m{^git-upload-pack ([!-~]+)\0host=([!-~]+)\0$}) {
63 $line =~ s/[^ -~]+/ /g;
64 fail
"could not parse \"$line\""
66 my ($path,$host) = ($1,$2);
68 $_ = my $uri = "git://$host/$path";
70 my ($user,$repo) = do "git-daemon-urlmap.pl";
71 fail
"no user configured for $uri" unless defined $user;
72 syslog
'info', "$client userv $user git-upload-pack $uri";
75 REQUEST_HOST
=> $host,
76 REQUEST_PATH
=> $path,
78 CLIENT_ADDR
=> $client_addr,
79 CLIENT_PORT
=> $client_port,
80 SERVER_ADDR
=> $server_addr,
81 SERVER_PORT
=> $server_port,
83 my @opts = map "-D$_=$vars{$_}", grep defined $vars{$_}, sort keys %vars;
85 no warnings
; # suppress errors to stderr
86 exec 'userv', @opts, $user, 'git-upload-pack'
87 or fail
"exec userv @opts $user git-upload-pack: $!";