Commit | Line | Data |
---|---|---|
d2707bea TF |
1 | #!/usr/bin/perl |
2 | # | |
3 | # A very simple userv git-daemon wrapper. | |
4 | # | |
5 | # This reads the first packet-line of the protocol, checks the syntax | |
6 | # of the user, pathname, and hostname, then uses userv to invoke the | |
7 | # real git daemon as the target user with safe arguments. | |
8 | # | |
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/ | |
12 | ||
13 | use strict; | |
14 | use warnings; | |
15 | ||
16 | use POSIX; | |
17 | ||
18 | my $USER = qr{[0-9a-z]+}; | |
19 | my $PATH = qr{[-+,._/0-9A-Za-z]+}; | |
20 | my $HOST = qr{[-.0-9A-Za-z]+}; | |
21 | ||
22 | sub xread { | |
23 | my $length = shift; | |
24 | my $buffer = ""; | |
25 | my $count = 0; | |
26 | while ($length > length $buffer) { | |
27 | my $data; | |
28 | my $ret = sysread STDIN, $data, $len | |
29 | while not defined $ret and ($! == EINTR or $! == EAGAIN); | |
30 | die "read" unless defined $ret; | |
31 | die "short read: expected $length bytes, got $count\n" if $ret == 0; | |
32 | $buffer .= $data; | |
33 | $count += $ret; | |
34 | } | |
35 | return $buffer; | |
36 | } | |
37 | ||
38 | my $len_hex = xread 4; | |
39 | die "bad packet length" unless $len_hex =~ m{^[0-9a-zA-Z]{4}$}; | |
40 | my $len = hex $len; | |
41 | ||
42 | my $line = xread $len; | |
43 | $line =~ m{^git-upload-pack ~($USER)/($PATH[.]git)\0host=($HOST)\0$}; | |
44 | my ($user,$path,$host) = ($1,$2,$3); | |
45 | ||
46 | # child's output will go directly to inetd | |
47 | open CHILD, '-|', 'userv', $user, | |
48 | qw(git daemon --inetd --strict-paths | |
49 | --user-path=public-git --forbid-override=receive-pack) | |
50 | or die "open pipe to userv: $!\n"; | |
51 | ||
52 | # proxy command line to child | |
53 | syswrite CHILD, $len_hex.$line | |
54 | or die "write to userv: $!\n"; | |
55 | ||
56 | # relay stdin to child | |
57 | open STDOUT, ">&CHILD" | |
58 | or die "dup: $!\n"; | |
59 | exec 'cat' | |
60 | or die "exec: $!\n"; | |
61 | ||
62 | die |