daemon: give friendlier error messages to clients

When the git-daemon is asked about an inaccessible repository, it simply
hangs up the connection without saying anything further. This makes it
hard to distinguish between a repository we cannot access (e.g., due to
typo), and a service or network outage.

Instead, let's print an "ERR" line, which git clients understand since
v1.6.1 (2008-12-24).

Because there is a risk of leaking information about non-exported
repositories, by default all errors simply say "access denied or
repository not exported". Sites which don't have hidden repositories, or
don't care, can pass a flag to turn on more specific messages.

Signed-off-by: Jeff King <peff@peff.net>
Helped-by: Sitaram Chamarty <sitaramc@gmail.com>
Signed-off-by: Junio C Hamano <gitster@pobox.com>
This commit is contained in:
Jeff King
2011-10-14 17:19:21 -04:00
committed by Junio C Hamano
parent 703f05ad58
commit d5570f4d2c
2 changed files with 31 additions and 4 deletions

View File

@ -20,6 +20,7 @@
static int log_syslog;
static int verbose;
static int reuseaddr;
static int informative_errors;
static const char daemon_usage[] =
"git daemon [--verbose] [--syslog] [--export-all]\n"
@ -247,6 +248,14 @@ static int git_daemon_config(const char *var, const char *value, void *cb)
return 0;
}
static int daemon_error(const char *dir, const char *msg)
{
if (!informative_errors)
msg = "access denied or repository not exported";
packet_write(1, "ERR %s: %s", msg, dir);
return -1;
}
static int run_service(char *dir, struct daemon_service *service)
{
const char *path;
@ -257,11 +266,11 @@ static int run_service(char *dir, struct daemon_service *service)
if (!enabled && !service->overridable) {
logerror("'%s': service not enabled.", service->name);
errno = EACCES;
return -1;
return daemon_error(dir, "service not enabled");
}
if (!(path = path_ok(dir)))
return -1;
return daemon_error(dir, "no such repository");
/*
* Security on the cheap.
@ -277,7 +286,7 @@ static int run_service(char *dir, struct daemon_service *service)
if (!export_all_trees && access("git-daemon-export-ok", F_OK)) {
logerror("'%s': repository not exported.", path);
errno = EACCES;
return -1;
return daemon_error(dir, "repository not exported");
}
if (service->overridable) {
@ -291,7 +300,7 @@ static int run_service(char *dir, struct daemon_service *service)
logerror("'%s': service not enabled for '%s'",
service->name, path);
errno = EACCES;
return -1;
return daemon_error(dir, "service not enabled");
}
/*
@ -1167,6 +1176,14 @@ int main(int argc, char **argv)
make_service_overridable(arg + 18, 0);
continue;
}
if (!prefixcmp(arg, "--informative-errors")) {
informative_errors = 1;
continue;
}
if (!prefixcmp(arg, "--no-informative-errors")) {
informative_errors = 0;
continue;
}
if (!strcmp(arg, "--")) {
ok_paths = &argv[i+1];
break;