From: Tony Finch Date: Mon, 29 Mar 2010 16:17:45 +0000 (+0000) Subject: git-daemon: move checking to more appropriate place. X-Git-Tag: userv/0.6.1~108 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ian/git?p=userv-utils.git;a=commitdiff_plain;h=6fe98f4a5ae10ba602534559e8685e7979f12be3 git-daemon: move checking to more appropriate place. Less checking in the daemon itself; instead check in the configuration which can be shared across the security boundary. --- diff --git a/git-daemon/git-daemon-urlmap.pl b/git-daemon/git-daemon-urlmap.pl new file mode 100644 index 0000000..18bf722 --- /dev/null +++ b/git-daemon/git-daemon-urlmap.pl @@ -0,0 +1,20 @@ +# Configuration file for the userv git daemon. +# +# This was written by Tony Finch +# You may do anything with it, at your own risk. +# http://creativecommons.org/publicdomain/zero/1.0/ + +use warnings; +use strict; + +my $g = qr{[0-9a-z_-]+[.]git}; +my $u = qr{[0-9a-z]+}; + +return "fanf" => "~fanf/public-git/$1" if m{^git://dotat[.]at/($g)$}; +return "webmaster" => "/u2/git-repos$1" if m{^git://git[.]chiark[.]greenend[.]org[.]uk/($g)$}; +return "$1" => "~$1/public-git/$2" if m{^git://git[.]chiark[.]greenend[.]org[.]uk/~($u)/($g)$}; +return "$1" => "~$1/cabal-git/$2" if m{^git://cabal[.]greenend[.]org[.]uk/~($u)/($g)$}; + +return undef; + +# end diff --git a/git-daemon/git-daemon-vhosts.pl b/git-daemon/git-daemon-vhosts.pl deleted file mode 100644 index 7c37b7a..0000000 --- a/git-daemon/git-daemon-vhosts.pl +++ /dev/null @@ -1,39 +0,0 @@ -# Configuration file for the userv git daemon. -# -# This was written by Tony Finch -# You may do anything with it, at your own risk. -# http://creativecommons.org/publicdomain/zero/1.0/ - -# The userv git daemon supports URLs of the forms: -# git://HOSTNAME/REPO.git -# git://HOSTNAME/~TILDE/REPO.git - -$HOSTNAME = qr{[-.0-9a-z]+}; -$TILDE = qr{[0-9a-z]+}; -$REPO = qr{[-+._0-9A-Za-z]+}; - -# The vhost_default_user hash specifies what user handles git requests -# for each virtual host, if the URL does not have a tilde part, or if -# the virtual hosts does not appear in either vhost_tilde hash. If a -# virtual host does not appear in this hash then it does not permit -# URLs without tilde parts. - -%vhost_default_user = ( - 'dotat.at' => 'fanf', -); - -# The vhost_tilde_is_user hash specifies which virtual hosts use the -# tilde part of a URL to specify the user that handles the request. - -%vhost_tilde_is_user = ( - 'chiark.greenend.org.uk' => 1, -); - -# The vhost_tilde_forbidden hash specifies which virtual hosts do not -# permit URLs with tilde parts. - -%vhost_tilde_forbidden = ( - 'dotat.at' => 1, -); - -# end diff --git a/git-daemon/git-daemon.pl b/git-daemon/git-daemon.pl index a17412f..8e15517 100755 --- a/git-daemon/git-daemon.pl +++ b/git-daemon/git-daemon.pl @@ -17,27 +17,26 @@ use POSIX; use Socket; use Sys::Syslog; -use vars qw{ $TILDE $REPO $HOSTNAME - %vhost_default_user %vhost_tilde_is_user %vhost_tilde_forbidden }; - use lib '/etc/userv'; -require 'git-daemon-vhosts.pl'; -my $peer = getpeername STDIN; -my ($port,$addr); -if (defined $peer) { - ($port,$addr) = sockaddr_in $peer; - $addr = inet_ntoa $addr; - $peer = "[$addr]:$port"; -} else { - $peer = "[?.?.?.?]:?"; - undef $!; +sub ntoa { + my $sockaddr = shift; + if (defined $sockaddr) { + my ($port,$addr) = sockaddr_in $sockaddr; + $addr = inet_ntoa $addr; + return ($addr,$port,"[$addr]:$port"); + } else { + return (undef,undef,"[?.?.?.?]:?"); + } } +my ($client_addr,$client_port,$client) = ntoa getpeername STDIN; +my ($server_addr,$server_port,$server) = ntoa getsockname STDIN; + openlog 'userv-git-daemon', 'pid', 'daemon'; sub fail { - syslog 'err', "$peer @_"; + syslog 'err', "$client @_"; exit; } @@ -58,25 +57,33 @@ sub xread { } my $len_hex = xread 4; -fail "non-hexadecimal packet length" unless $len_hex =~ m{^[0-9a-zA-Z]{4}$}; +fail "non-hex packet length" unless $len_hex =~ m{^[0-9a-fA-F]{4}$}; my $line = xread hex $len_hex; -unless ($line =~ m{^git-upload-pack (?:~($TILDE)/)?($REPO[.]git)\0host=($HOSTNAME)\0$}) { +unless ($line =~ m{^git-upload-pack ([!-~]+)\0host=([!-~]+)\0$}) { $line =~ s/[^ -~]+/ /g; fail "could not parse \"$line\"" } -my ($tilde,$repo,$host) = ($1,$2,$3); -my $url = $tilde ? "git://$host/~$tilde/$repo" : "git://$host/$repo"; +my ($path,$host) = ($1,$2); +$path =~ s|^/||; +$_ = my $uri = "git://$host/$path"; + +my ($user,$repo) = do "git-daemon-urlmap.pl"; +fail "no user configured for $uri" unless defined $user; +syslog 'info', "$client userv $user git-upload-pack $uri"; -fail "tilde forbidden for $url" if defined $tilde and $vhost_tilde_forbidden{$host}; -my $user = $vhost_tilde_is_user{$host} ? $tilde : $vhost_default_user{$host}; -fail "no user configured for $url" unless defined $user; -syslog 'info', "$peer $user $url"; +my %vars = ( + REQUEST_HOST => $host, + REQUEST_PATH => $path, + REQUEST_URI => $uri, + CLIENT_ADDR => $client_addr, + CLIENT_PORT => $client_port, + SERVER_ADDR => $server_addr, + SERVER_PORT => $server_port, +); +my @opts = map "-D$_=$vars{$_}", grep defined $vars{$_}, sort keys %vars; -my @opts = ("-DHOST=$host", "-DREPO=$repo"); -push @opts, "-DTILDE=$tilde" if defined $tilde; -push @opts, "-DCLIENT=$addr" if defined $addr; no warnings; # suppress errors to stderr exec 'userv', @opts, $user, 'git-upload-pack' - or fail "exec userv: $!"; + or fail "exec userv @opts $user git-upload-pack: $!"; # end