Skip to content

Commit

Permalink
Cleaned up git-daemon virtual hosting support.
Browse files Browse the repository at this point in the history
Standardized on lowercase hostnames from client.

Added interpolation values for the IP address, port and
canonical hostname of the server as it is contacted and
named by the client and passed in via the extended args.

Added --listen=host_or_ipaddr option suport.  Renamed port
variable as "listen_port" correspondingly as well.

Documented mutual exclusivity of --inetd option with
    --user, --group, --listen and --port options.

Added compat/inet_pton.c from Paul Vixie as needed.

Small memory leaks need to be cleaned up still.

Signed-off-by: Jon Loeliger <jdl@jdl.com>
Signed-off-by: Junio C Hamano <junkio@cox.net>
  • Loading branch information
Jon Loeliger authored and Junio C Hamano committed Sep 28, 2006
1 parent a3f5d02 commit dd46762
Show file tree
Hide file tree
Showing 4 changed files with 389 additions and 28 deletions.
43 changes: 37 additions & 6 deletions Documentation/git-daemon.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,15 @@ git-daemon - A really simple server for git repositories
SYNOPSIS
--------
[verse]
'git-daemon' [--verbose] [--syslog] [--inetd | --port=n] [--export-all]
'git-daemon' [--verbose] [--syslog] [--export-all]
[--timeout=n] [--init-timeout=n] [--strict-paths]
[--base-path=path] [--user-path | --user-path=path]
[--interpolated-path=pathtemplate]
[--reuseaddr] [--detach] [--pid-file=file]
[--enable=service] [--disable=service]
[--allow-override=service] [--forbid-override=service]
[--reuseaddr] [--detach] [--pid-file=file]
[--user=user [--group=group]] [directory...]
[--inetd | [--listen=host_or_ipaddr] [--port=n] [--user=user [--group=group]]
[directory...]

DESCRIPTION
-----------
Expand Down Expand Up @@ -54,8 +55,12 @@ OPTIONS
--interpolated-path=pathtemplate::
To support virtual hosting, an interpolated path template can be
used to dynamically construct alternate paths. The template
supports %H for the target hostname as supplied by the client,
supports %H for the target hostname as supplied by the client but
converted to all lowercase, %CH for the canonical hostname,
%IP for the server's IP address, %P for the port number,
and %D for the absolute path of the named repository.
After interpolation, the path is validated against the directory
whitelist.

--export-all::
Allow pulling from all directories that look like GIT repositories
Expand All @@ -64,9 +69,17 @@ OPTIONS

--inetd::
Have the server run as an inetd service. Implies --syslog.
Incompatible with --port, --listen, --user and --group options.

--listen=host_or_ipaddr::
Listen on an a specific IP address or hostname. IP addresses can
be either an IPv4 address or an IPV6 address if supported. If IPv6
is not supported, then --listen=hostname is also not supported and
--listen must be given an IPv4 address.
Incompatible with '--inetd' option.

--port::
Listen on an alternative port.
--port=n::
Listen on an alternative port. Incompatible with '--inetd' option.

--init-timeout::
Timeout between the moment the connection is established and the
Expand Down Expand Up @@ -182,6 +195,24 @@ clients, a symlink from `/software` into the appropriate
default repository could be made as well.


git-daemon as regular daemon for virtual hosts::
To set up `git-daemon` as a regular, non-inetd service that
handles repositories for multiple virtual hosts based on
their IP addresses, start the daemon like this:
+
------------------------------------------------
git-daemon --verbose --export-all
--interpolated-path=/pub/%IP/%D
/pub/192.168.1.200/software
/pub/10.10.220.23/software
------------------------------------------------
+
In this example, the root-level directory `/pub` will contain
a subdirectory for each virtual host IP address supported.
Repositories can still be accessed by hostname though, assuming
they correspond to these IP addresses.


Author
------
Written by Linus Torvalds <torvalds@osdl.org>, YOSHIFUJI Hideaki
Expand Down
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -524,6 +524,9 @@ endif
ifdef NO_INET_NTOP
LIB_OBJS += compat/inet_ntop.o
endif
ifdef NO_INET_PTON
LIB_OBJS += compat/inet_pton.o
endif

ifdef NO_ICONV
ALL_CFLAGS += -DNO_ICONV
Expand Down
220 changes: 220 additions & 0 deletions compat/inet_pton.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,220 @@
/*
* Copyright (C) 1996-2001 Internet Software Consortium.
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM
* DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL
* INTERNET SOFTWARE CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT,
* INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING
* FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION
* WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/

#include <errno.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <stdio.h>
#include <string.h>

#ifndef NS_INT16SZ
#define NS_INT16SZ 2
#endif

#ifndef NS_INADDRSZ
#define NS_INADDRSZ 4
#endif

#ifndef NS_IN6ADDRSZ
#define NS_IN6ADDRSZ 16
#endif

/*
* WARNING: Don't even consider trying to compile this on a system where
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
*/

static int inet_pton4(const char *src, unsigned char *dst);
static int inet_pton6(const char *src, unsigned char *dst);

/* int
* inet_pton4(src, dst)
* like inet_aton() but without all the hexadecimal and shorthand.
* return:
* 1 if `src' is a valid dotted quad, else 0.
* notice:
* does not touch `dst' unless it's returning 1.
* author:
* Paul Vixie, 1996.
*/
static int
inet_pton4(const char *src, unsigned char *dst)
{
static const char digits[] = "0123456789";
int saw_digit, octets, ch;
unsigned char tmp[NS_INADDRSZ], *tp;

saw_digit = 0;
octets = 0;
*(tp = tmp) = 0;
while ((ch = *src++) != '\0') {
const char *pch;

if ((pch = strchr(digits, ch)) != NULL) {
unsigned int new = *tp * 10 + (pch - digits);

if (new > 255)
return (0);
*tp = new;
if (! saw_digit) {
if (++octets > 4)
return (0);
saw_digit = 1;
}
} else if (ch == '.' && saw_digit) {
if (octets == 4)
return (0);
*++tp = 0;
saw_digit = 0;
} else
return (0);
}
if (octets < 4)
return (0);
memcpy(dst, tmp, NS_INADDRSZ);
return (1);
}

/* int
* inet_pton6(src, dst)
* convert presentation level address to network order binary form.
* return:
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
* notice:
* (1) does not touch `dst' unless it's returning 1.
* (2) :: in a full address is silently ignored.
* credit:
* inspired by Mark Andrews.
* author:
* Paul Vixie, 1996.
*/

#ifndef NO_IPV6
static int
inet_pton6(const char *src, unsigned char *dst)
{
static const char xdigits_l[] = "0123456789abcdef",
xdigits_u[] = "0123456789ABCDEF";
unsigned char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
const char *xdigits, *curtok;
int ch, saw_xdigit;
unsigned int val;

memset((tp = tmp), '\0', NS_IN6ADDRSZ);
endp = tp + NS_IN6ADDRSZ;
colonp = NULL;
/* Leading :: requires some special handling. */
if (*src == ':')
if (*++src != ':')
return (0);
curtok = src;
saw_xdigit = 0;
val = 0;
while ((ch = *src++) != '\0') {
const char *pch;

if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
pch = strchr((xdigits = xdigits_u), ch);
if (pch != NULL) {
val <<= 4;
val |= (pch - xdigits);
if (val > 0xffff)
return (0);
saw_xdigit = 1;
continue;
}
if (ch == ':') {
curtok = src;
if (!saw_xdigit) {
if (colonp)
return (0);
colonp = tp;
continue;
}
if (tp + NS_INT16SZ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
saw_xdigit = 0;
val = 0;
continue;
}
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
inet_pton4(curtok, tp) > 0) {
tp += NS_INADDRSZ;
saw_xdigit = 0;
break; /* '\0' was seen by inet_pton4(). */
}
return (0);
}
if (saw_xdigit) {
if (tp + NS_INT16SZ > endp)
return (0);
*tp++ = (unsigned char) (val >> 8) & 0xff;
*tp++ = (unsigned char) val & 0xff;
}
if (colonp != NULL) {
/*
* Since some memmove()'s erroneously fail to handle
* overlapping regions, we'll do the shift by hand.
*/
const int n = tp - colonp;
int i;

for (i = 1; i <= n; i++) {
endp[- i] = colonp[n - i];
colonp[n - i] = 0;
}
tp = endp;
}
if (tp != endp)
return (0);
memcpy(dst, tmp, NS_IN6ADDRSZ);
return (1);
}
#endif

/* int
* isc_net_pton(af, src, dst)
* convert from presentation format (which usually means ASCII printable)
* to network format (which is usually some kind of binary format).
* return:
* 1 if the address was valid for the specified address family
* 0 if the address wasn't valid (`dst' is untouched in this case)
* -1 if some other error occurred (`dst' is untouched in this case, too)
* author:
* Paul Vixie, 1996.
*/
int
inet_pton(int af, const char *src, void *dst)
{
switch (af) {
case AF_INET:
return (inet_pton4(src, dst));
#ifndef NO_IPV6
case AF_INET6:
return (inet_pton6(src, dst));
#endif
default:
errno = EAFNOSUPPORT;
return (-1);
}
/* NOTREACHED */
}
Loading

0 comments on commit dd46762

Please sign in to comment.