efb45b121491ea810a8321e65b680aed358d212d
3 # A git daemon with an added userv security boundary.
5 # This was written by Tony Finch <dot@dotat.at>
6 # You may do anything with it, at your own risk.
7 # http://creativecommons.org/publicdomain/zero/1.0/
18 if (defined $sockaddr) {
19 my ($port,$addr) = sockaddr_in
$sockaddr;
20 $addr = inet_ntoa
$addr;
21 return ($addr,$port,"[$addr]:$port");
23 return (undef,undef,"[?.?.?.?]:?");
27 my ($client_addr,$client_port,$client) = ntoa
getpeername STDIN
;
28 my ($server_addr,$server_port,$server) = ntoa
getsockname STDIN
;
30 openlog
'userv-git-daemon', 'pid', 'daemon';
33 syslog
'err', "$client @_";
40 local $SIG{ALRM
} = sub { fail
"timeout" };
42 while ($length > length $buffer) {
43 my $ret = sysread STDIN
, $buffer, $length, length $buffer;
44 fail
"short read: expected $length bytes, got " . length $buffer
45 if defined $ret and $ret == 0;
46 fail
"read: $!" if not defined $ret and $! != EINTR
and $! != EAGAIN
;
47 $ret = 0 if not defined $ret;
53 my $len_hex = xread
4;
54 fail
"non-hex packet length" unless $len_hex =~ m{^[0-9a-fA-F]{4}$};
55 my $line = xread
hex $len_hex;
56 unless ($line =~ m{^(git-[a-z-]+) ([!-~]+)\0host=([!-~]+)\0$}) {
57 $line =~ s/[^ -~]+/ /g;
58 fail
"could not parse \"$line\""
60 my ($service,$path,$host) = ($1,$2,3);
62 my $uri = $_ = "git://$host/$path";
67 $user = $u if defined $u;
69 fail
"no user configured for $uri" unless defined $user;
70 syslog
'info', "$client userv $user $service $uri";
73 REQUEST_SERVICE
=> $service,
74 REQUEST_HOST
=> $host,
75 REQUEST_PATH
=> $path,
78 CLIENT_ADDR
=> $client_addr,
79 CLIENT_PORT
=> $client_port,
81 SERVER_ADDR
=> $server_addr,
82 SERVER_PORT
=> $server_port,
84 my @opts = map "-D$_=$vars{$_}", grep defined $vars{$_}, sort keys %vars;
86 no warnings
; # suppress errors to stderr
87 exec 'userv', @opts, $user, $service
88 or fail
"exec userv @opts $user $service: $!";