Skip to content

Commit d5570f4

Browse files
peffgitster
authored andcommitted
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>
1 parent 703f05a commit d5570f4

File tree

2 files changed

+31
-4
lines changed

2 files changed

+31
-4
lines changed

Documentation/git-daemon.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -161,6 +161,16 @@ the facility of inet daemon to achieve the same before spawning
161161
repository configuration. By default, all the services
162162
are overridable.
163163

164+
--informative-errors::
165+
--no-informative-errors::
166+
When informative errors are turned on, git-daemon will report
167+
more verbose errors to the client, differentiating conditions
168+
like "no such repository" from "repository not exported". This
169+
is more convenient for clients, but may leak information about
170+
the existence of unexported repositories. When informative
171+
errors are not enabled, all errors report "access denied" to the
172+
client. The default is --no-informative-errors.
173+
164174
<directory>::
165175
A directory to add to the whitelist of allowed directories. Unless
166176
--strict-paths is specified this will also include subdirectories

daemon.c

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
static int log_syslog;
2121
static int verbose;
2222
static int reuseaddr;
23+
static int informative_errors;
2324

2425
static const char daemon_usage[] =
2526
"git daemon [--verbose] [--syslog] [--export-all]\n"
@@ -247,6 +248,14 @@ static int git_daemon_config(const char *var, const char *value, void *cb)
247248
return 0;
248249
}
249250

251+
static int daemon_error(const char *dir, const char *msg)
252+
{
253+
if (!informative_errors)
254+
msg = "access denied or repository not exported";
255+
packet_write(1, "ERR %s: %s", msg, dir);
256+
return -1;
257+
}
258+
250259
static int run_service(char *dir, struct daemon_service *service)
251260
{
252261
const char *path;
@@ -257,11 +266,11 @@ static int run_service(char *dir, struct daemon_service *service)
257266
if (!enabled && !service->overridable) {
258267
logerror("'%s': service not enabled.", service->name);
259268
errno = EACCES;
260-
return -1;
269+
return daemon_error(dir, "service not enabled");
261270
}
262271

263272
if (!(path = path_ok(dir)))
264-
return -1;
273+
return daemon_error(dir, "no such repository");
265274

266275
/*
267276
* Security on the cheap.
@@ -277,7 +286,7 @@ static int run_service(char *dir, struct daemon_service *service)
277286
if (!export_all_trees && access("git-daemon-export-ok", F_OK)) {
278287
logerror("'%s': repository not exported.", path);
279288
errno = EACCES;
280-
return -1;
289+
return daemon_error(dir, "repository not exported");
281290
}
282291

283292
if (service->overridable) {
@@ -291,7 +300,7 @@ static int run_service(char *dir, struct daemon_service *service)
291300
logerror("'%s': service not enabled for '%s'",
292301
service->name, path);
293302
errno = EACCES;
294-
return -1;
303+
return daemon_error(dir, "service not enabled");
295304
}
296305

297306
/*
@@ -1167,6 +1176,14 @@ int main(int argc, char **argv)
11671176
make_service_overridable(arg + 18, 0);
11681177
continue;
11691178
}
1179+
if (!prefixcmp(arg, "--informative-errors")) {
1180+
informative_errors = 1;
1181+
continue;
1182+
}
1183+
if (!prefixcmp(arg, "--no-informative-errors")) {
1184+
informative_errors = 0;
1185+
continue;
1186+
}
11701187
if (!strcmp(arg, "--")) {
11711188
ok_paths = &argv[i+1];
11721189
break;

0 commit comments

Comments
 (0)