From 09db444fdbf647c95de698d243425a7700b91b2f Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Wed, 1 Feb 2006 11:44:28 +0000 Subject: http-fetch: Fix object list corruption in fill_active_slots(). In fill_active_slots() -- if we find an object which has already arrived, say as part of a pack, /don't/ remove it from the list. It's already been prefetched and someone will ask for it later. Just label it as done and carry blithely on. (As it was, the code would dereference a freed object to continue through the list anyway.) Signed-off-by: Mark Wooding Signed-off-by: Junio C Hamano diff --git a/http-fetch.c b/http-fetch.c index 72edf28..7b1b2a0 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -311,7 +311,7 @@ void fill_active_slots(void) while (active_requests < max_requests && obj_req != NULL) { if (obj_req->state == WAITING) { if (has_sha1_file(obj_req->sha1)) - release_object_request(obj_req); + obj_req->state = COMPLETE; else start_object_request(obj_req); curl_multi_perform(curlm, &num_transfers); -- cgit v0.10.2-6-g49f6 From 7b934ec015363dd8881d249838ab3623a2d345fd Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Wed, 1 Feb 2006 11:44:35 +0000 Subject: http-fetch: Fix message reporting rename of object file. move_temp_to_file returns 0 or -1. This is not a good thing to pass to strerror(3). Fortunately, someone already reported the error, so don't worry too much. Signed-off-by: Mark Wooding Signed-off-by: Junio C Hamano diff --git a/http-fetch.c b/http-fetch.c index 7b1b2a0..555e95d 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -822,9 +822,8 @@ static int fetch_object(struct alt_base *repo, unsigned char *sha1) } else if (memcmp(obj_req->sha1, obj_req->real_sha1, 20)) { ret = error("File %s has bad hash\n", hex); } else if (obj_req->rename < 0) { - ret = error("unable to write sha1 filename %s: %s", - obj_req->filename, - strerror(obj_req->rename)); + ret = error("unable to write sha1 filename %s", + obj_req->filename); } release_object_request(obj_req); -- cgit v0.10.2-6-g49f6 From 7982d74e1ca846e6ab9b1bfb1fcd9c34e3fd534f Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Wed, 1 Feb 2006 11:44:37 +0000 Subject: http: Turn on verbose Curl messages if GIT_CURL_VERBOSE set in environment Signed-off-by: Mark Wooding Signed-off-by: Junio C Hamano diff --git a/http.c b/http.c index eefb0f0..632c2c5 100644 --- a/http.c +++ b/http.c @@ -192,6 +192,9 @@ static CURL* get_curl_handle(void) curl_easy_setopt(result, CURLOPT_FOLLOWLOCATION, 1); + if (getenv("GIT_CURL_VERBOSE")) + curl_easy_setopt(result, CURLOPT_VERBOSE, 1); + return result; } -- cgit v0.10.2-6-g49f6 From a3f583cbf7929f290a47dc0a952ee6b0faa9d279 Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Wed, 1 Feb 2006 11:44:39 +0000 Subject: http-fetch: Tidy control flow in process_alternate_response It's a bit convoluted. Tidy it up. Signed-off-by: Mark Wooding Signed-off-by: Junio C Hamano diff --git a/http-fetch.c b/http-fetch.c index 555e95d..bddbd6b 100644 --- a/http-fetch.c +++ b/http-fetch.c @@ -468,13 +468,11 @@ static void process_alternates_response(void *callback_data) alt_req->url); active_requests++; slot->in_use = 1; - if (start_active_slot(slot)) { - return; - } else { + if (!start_active_slot(slot)) { got_alternates = -1; slot->in_use = 0; - return; } + return; } } else if (slot->curl_result != CURLE_OK) { if (slot->http_code != 404 && -- cgit v0.10.2-6-g49f6 From 363f24c93695d26f5af584e99093689077b1c7dd Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Fri, 3 Feb 2006 23:50:55 -0800 Subject: daemon: do not forbid user relative paths unconditionally under --base-path Using base-path to relocate the server public space does not have anything to do with allowing or forbidding user relative paths. Signed-off-by: Junio C Hamano diff --git a/daemon.c b/daemon.c index 532bb0c..324bb04 100644 --- a/daemon.c +++ b/daemon.c @@ -145,13 +145,17 @@ static char *path_ok(char *dir) if (base_path) { static char rpath[PATH_MAX]; - if (*dir != '/') { - /* Forbid possible base-path evasion using ~paths. */ + if (!strict_paths && *dir == '~') + ; /* allow user relative paths */ + else if (*dir != '/') { + /* otherwise allow only absolute */ logerror("'%s': Non-absolute path denied (base-path active)", dir); return NULL; } - snprintf(rpath, PATH_MAX, "%s%s", base_path, dir); - dir = rpath; + else { + snprintf(rpath, PATH_MAX, "%s%s", base_path, dir); + dir = rpath; + } } path = enter_repo(dir, strict_paths); -- cgit v0.10.2-6-g49f6 From 1955fabf4194f3629e028778d0081bb2aa16c06c Mon Sep 17 00:00:00 2001 From: Mark Wooding Date: Fri, 3 Feb 2006 20:27:04 +0000 Subject: daemon: Set SO_REUSEADDR on listening sockets. Without this, you can silently lose the ability to receive IPv4 connections if you stop and restart the daemon. [jc: tweaked code organization a bit and made this controllable from a command line option.] Signed-off-by: Mark Wooding Signed-off-by: Junio C Hamano diff --git a/daemon.c b/daemon.c index 324bb04..dab8c2c 100644 --- a/daemon.c +++ b/daemon.c @@ -13,11 +13,12 @@ static int log_syslog; static int verbose; +static int reuseaddr; static const char daemon_usage[] = "git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n" " [--timeout=n] [--init-timeout=n] [--strict-paths]\n" -" [--base-path=path] [directory...]"; +" [--base-path=path] [--reuseaddr] [directory...]"; /* List of acceptable pathname prefixes */ static char **ok_paths = NULL; @@ -451,6 +452,16 @@ static void child_handler(int signo) } } +static int set_reuse_addr(int sockfd) +{ + int on = 1; + + if (!reuseaddr) + return 0; + return setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, + &on, sizeof(on)); +} + #ifndef NO_IPV6 static int socksetup(int port, int **socklist_p) @@ -495,6 +506,11 @@ static int socksetup(int port, int **socklist_p) } #endif + if (set_reuse_addr(sockfd)) { + close(sockfd); + return 0; /* not fatal */ + } + if (bind(sockfd, ai->ai_addr, ai->ai_addrlen) < 0) { close(sockfd); continue; /* not fatal */ @@ -537,6 +553,11 @@ static int socksetup(int port, int **socklist_p) sin.sin_addr.s_addr = htonl(INADDR_ANY); sin.sin_port = htons(port); + if (set_reuse_addr(sockfd)) { + close(sockfd); + return 0; + } + if ( bind(sockfd, (struct sockaddr *)&sin, sizeof sin) < 0 ) { close(sockfd); return 0; @@ -663,6 +684,10 @@ int main(int argc, char **argv) base_path = arg+12; continue; } + if (!strcmp(arg, "--reuseaddr")) { + reuseaddr = 1; + continue; + } if (!strcmp(arg, "--")) { ok_paths = &argv[i+1]; break; -- cgit v0.10.2-6-g49f6 From 603968d22b19d1b98ff355cc32575a4d9845c151 Mon Sep 17 00:00:00 2001 From: Junio C Hamano Date: Sat, 4 Feb 2006 22:27:29 -0800 Subject: daemon: extend user-relative path notation. Earlier, we made --base-path to automatically forbid user-relative paths, which was probably a mistake. This introduces --user-path (or --user-path=path) option to control the use of user-relative paths independently. The latter form of the option can be used to restrict accesses to a part of each user's home directory, similar to "public_html" some webservers supports. If we're invoked with --user-path=FOO option, then a URL of the form git://~USER/PATH/... resolves to the path HOME/FOO/PATH/..., where HOME is USER's home directory. [jc: This is much reworked by me so bugs are mine, but the original patch was done by Mark Wooding.] Signed-off-by: Junio C Hamano diff --git a/Documentation/git-daemon.txt b/Documentation/git-daemon.txt index a20e053..2cc6075 100644 --- a/Documentation/git-daemon.txt +++ b/Documentation/git-daemon.txt @@ -10,7 +10,8 @@ SYNOPSIS [verse] 'git-daemon' [--verbose] [--syslog] [--inetd | --port=n] [--export-all] [--timeout=n] [--init-timeout=n] [--strict-paths] - [--base-path=path] [directory...] + [--base-path=path] [--user-path | --user-path=path] + [directory...] DESCRIPTION ----------- @@ -42,8 +43,7 @@ OPTIONS This is sort of "GIT root" - if you run git-daemon with '--base-path=/srv/git' on example.com, then if you later try to pull 'git://example.com/hello.git', `git-daemon` will interpret the path - as '/srv/git/hello.git'. Home directories (the '~login' notation) - access is disabled. + as '/srv/git/hello.git'. --export-all:: Allow pulling from all directories that look like GIT repositories @@ -70,6 +70,15 @@ OPTIONS Log to syslog instead of stderr. Note that this option does not imply --verbose, thus by default only error conditions will be logged. +--user-path, --user-path=path:: + Allow ~user notation to be used in requests. When + specified with no parameter, requests to + git://host/~alice/foo is taken as a request to access + 'foo' repository in the home directory of user `alice`. + If `--user-path=path` is specified, the same request is + taken as a request to access `path/foo` repository in + the home directory of user `alice`. + --verbose:: Log details about the incoming connections and requested files. diff --git a/daemon.c b/daemon.c index dab8c2c..a1ccda3 100644 --- a/daemon.c +++ b/daemon.c @@ -18,7 +18,8 @@ static int reuseaddr; static const char daemon_usage[] = "git-daemon [--verbose] [--syslog] [--inetd | --port=n] [--export-all]\n" " [--timeout=n] [--init-timeout=n] [--strict-paths]\n" -" [--base-path=path] [--reuseaddr] [directory...]"; +" [--base-path=path] [--user-path | --user-path=path]\n" +" [--reuseaddr] [directory...]"; /* List of acceptable pathname prefixes */ static char **ok_paths = NULL; @@ -30,6 +31,12 @@ static int export_all_trees = 0; /* Take all paths relative to this one if non-NULL */ static char *base_path = NULL; +/* If defined, ~user notation is allowed and the string is inserted + * after ~user/. E.g. a request to git://host/~alice/frotz would + * go to /home/alice/pub_git/frotz with --user-path=pub_git. + */ +static char *user_path = NULL; + /* Timeout, and initial timeout */ static unsigned int timeout = 0; static unsigned int init_timeout = 0; @@ -137,6 +144,7 @@ static int avoid_alias(char *p) static char *path_ok(char *dir) { + static char rpath[PATH_MAX]; char *path; if (avoid_alias(dir)) { @@ -144,12 +152,31 @@ static char *path_ok(char *dir) return NULL; } - if (base_path) { - static char rpath[PATH_MAX]; - if (!strict_paths && *dir == '~') - ; /* allow user relative paths */ - else if (*dir != '/') { - /* otherwise allow only absolute */ + if (*dir == '~') { + if (!user_path) { + logerror("'%s': User-path not allowed", dir); + return NULL; + } + if (*user_path) { + /* Got either "~alice" or "~alice/foo"; + * rewrite them to "~alice/%s" or + * "~alice/%s/foo". + */ + int namlen, restlen = strlen(dir); + char *slash = strchr(dir, '/'); + if (!slash) + slash = dir + restlen; + namlen = slash - dir; + restlen -= namlen; + loginfo("userpath <%s>, request <%s>, namlen %d, restlen %d, slash <%s>", user_path, dir, namlen, restlen, slash); + snprintf(rpath, PATH_MAX, "%.*s/%s%.*s", + namlen, dir, user_path, restlen, slash); + dir = rpath; + } + } + else if (base_path) { + if (*dir != '/') { + /* Allow only absolute */ logerror("'%s': Non-absolute path denied (base-path active)", dir); return NULL; } @@ -688,6 +715,14 @@ int main(int argc, char **argv) reuseaddr = 1; continue; } + if (!strcmp(arg, "--user-path")) { + user_path = ""; + continue; + } + if (!strncmp(arg, "--user-path=", 12)) { + user_path = arg + 12; + continue; + } if (!strcmp(arg, "--")) { ok_paths = &argv[i+1]; break; -- cgit v0.10.2-6-g49f6