diff options
author | Tony Finch <dot@dotat.at> | 2010-03-26 16:43:09 +0000 |
---|---|---|
committer | Ian Jackson <ian@liberator.relativity.greenend.org.uk> | 2010-05-22 15:54:40 +0100 |
commit | d2707bea0310c99c773c06f2bfe9a1c1f84bbb9e (patch) | |
tree | 9520ea045bb9189d5501437c8c14d9e03e9d6db6 /git-daemon | |
parent | dea61a7704fce2bd948ccdf5547535af7f82ae14 (diff) | |
download | userv-utils-d2707bea0310c99c773c06f2bfe9a1c1f84bbb9e.tar.gz |
Initial pass at a git daemon for userv.
Diffstat (limited to 'git-daemon')
-rw-r--r-- | git-daemon/git-daemon.pl | 62 |
1 files changed, 62 insertions, 0 deletions
diff --git a/git-daemon/git-daemon.pl b/git-daemon/git-daemon.pl new file mode 100644 index 0000000..f18f6b9 --- /dev/null +++ b/git-daemon/git-daemon.pl @@ -0,0 +1,62 @@ +#!/usr/bin/perl +# +# A very simple userv git-daemon wrapper. +# +# This reads the first packet-line of the protocol, checks the syntax +# of the user, pathname, and hostname, then uses userv to invoke the +# real git daemon as the target user with safe arguments. +# +# This was written by Tony Finch <dot@dotat.at> +# You may do anything with it, at your own risk. +# http://creativecommons.org/publicdomain/zero/1.0/ + +use strict; +use warnings; + +use POSIX; + +my $USER = qr{[0-9a-z]+}; +my $PATH = qr{[-+,._/0-9A-Za-z]+}; +my $HOST = qr{[-.0-9A-Za-z]+}; + +sub xread { + my $length = shift; + my $buffer = ""; + my $count = 0; + while ($length > length $buffer) { + my $data; + my $ret = sysread STDIN, $data, $len + while not defined $ret and ($! == EINTR or $! == EAGAIN); + die "read" unless defined $ret; + die "short read: expected $length bytes, got $count\n" if $ret == 0; + $buffer .= $data; + $count += $ret; + } + return $buffer; +} + +my $len_hex = xread 4; +die "bad packet length" unless $len_hex =~ m{^[0-9a-zA-Z]{4}$}; +my $len = hex $len; + +my $line = xread $len; +$line =~ m{^git-upload-pack ~($USER)/($PATH[.]git)\0host=($HOST)\0$}; +my ($user,$path,$host) = ($1,$2,$3); + +# child's output will go directly to inetd +open CHILD, '-|', 'userv', $user, + qw(git daemon --inetd --strict-paths + --user-path=public-git --forbid-override=receive-pack) + or die "open pipe to userv: $!\n"; + +# proxy command line to child +syswrite CHILD, $len_hex.$line + or die "write to userv: $!\n"; + +# relay stdin to child +open STDOUT, ">&CHILD" + or die "dup: $!\n"; +exec 'cat' + or die "exec: $!\n"; + +die |