diff options
Diffstat (limited to 'daemon.c')
-rw-r--r-- | daemon.c | 115 |
1 files changed, 51 insertions, 64 deletions
@@ -1,7 +1,12 @@ -#include "cache.h" +#include "git-compat-util.h" +#include "abspath.h" #include "config.h" +#include "environment.h" +#include "path.h" #include "pkt-line.h" +#include "protocol.h" #include "run-command.h" +#include "setup.h" #include "strbuf.h" #include "string-list.h" @@ -137,42 +142,6 @@ static void NORETURN daemon_die(const char *err, va_list params) exit(1); } -struct expand_path_context { - const char *directory; - struct hostinfo *hostinfo; -}; - -static size_t expand_path(struct strbuf *sb, const char *placeholder, void *ctx) -{ - struct expand_path_context *context = ctx; - struct hostinfo *hi = context->hostinfo; - - switch (placeholder[0]) { - case 'H': - strbuf_addbuf(sb, &hi->hostname); - return 1; - case 'C': - if (placeholder[1] == 'H') { - strbuf_addstr(sb, get_canon_hostname(hi)); - return 2; - } - break; - case 'I': - if (placeholder[1] == 'P') { - strbuf_addstr(sb, get_ip_address(hi)); - return 2; - } - break; - case 'P': - strbuf_addbuf(sb, &hi->tcp_port); - return 1; - case 'D': - strbuf_addstr(sb, context->directory); - return 1; - } - return 0; -} - static const char *path_ok(const char *directory, struct hostinfo *hi) { static char rpath[PATH_MAX]; @@ -216,10 +185,7 @@ static const char *path_ok(const char *directory, struct hostinfo *hi) } else if (interpolated_path && hi->saw_extended_args) { struct strbuf expanded_path = STRBUF_INIT; - struct expand_path_context context; - - context.directory = directory; - context.hostinfo = hi; + const char *format = interpolated_path; if (*dir != '/') { /* Allow only absolute */ @@ -227,8 +193,24 @@ static const char *path_ok(const char *directory, struct hostinfo *hi) return NULL; } - strbuf_expand(&expanded_path, interpolated_path, - expand_path, &context); + while (strbuf_expand_step(&expanded_path, &format)) { + if (skip_prefix(format, "%", &format)) + strbuf_addch(&expanded_path, '%'); + else if (skip_prefix(format, "H", &format)) + strbuf_addbuf(&expanded_path, &hi->hostname); + else if (skip_prefix(format, "CH", &format)) + strbuf_addstr(&expanded_path, + get_canon_hostname(hi)); + else if (skip_prefix(format, "IP", &format)) + strbuf_addstr(&expanded_path, + get_ip_address(hi)); + else if (skip_prefix(format, "P", &format)) + strbuf_addbuf(&expanded_path, &hi->tcp_port); + else if (skip_prefix(format, "D", &format)) + strbuf_addstr(&expanded_path, directory); + else + strbuf_addch(&expanded_path, '%'); + } rlen = strlcpy(interp_path, expanded_path.buf, sizeof(interp_path)); @@ -279,7 +261,7 @@ static const char *path_ok(const char *directory, struct hostinfo *hi) /* The validation is done on the paths after enter_repo * appends optional {.git,.git/.git} and friends, but * it does not use getcwd(). So if your /pub is - * a symlink to /mnt/pub, you can whitelist /pub and + * a symlink to /mnt/pub, you can include /pub and * do not have to say /mnt/pub. * Do not say /pub/. */ @@ -298,7 +280,7 @@ static const char *path_ok(const char *directory, struct hostinfo *hi) return path; } - logerror("'%s': not in whitelist", path); + logerror("'%s': not in directory list", path); return NULL; /* Fallthrough. Deny by default */ } @@ -403,7 +385,7 @@ static int run_service(const char *dir, struct daemon_service *service, * a "git-daemon-export-ok" flag that says that the other side * is ok with us doing this. * - * path_ok() uses enter_repo() and does whitelist checking. + * path_ok() uses enter_repo() and checks for included directories. * We only need to make sure the repository is exported. */ @@ -928,7 +910,7 @@ static void handle(int incoming, struct sockaddr *addr, socklen_t addrlen) add_child(&cld, addr, addrlen); } -static void child_handler(int signo) +static void child_handler(int signo UNUSED) { /* * Otherwise empty handler because systemcalls will get interrupted @@ -1261,19 +1243,20 @@ static int serve(struct string_list *listen_addr, int listen_port, int cmd_main(int argc, const char **argv) { int listen_port = 0; - struct string_list listen_addr = STRING_LIST_INIT_NODUP; + struct string_list listen_addr = STRING_LIST_INIT_DUP; int serve_mode = 0, inetd_mode = 0; const char *pid_file = NULL, *user_name = NULL, *group_name = NULL; int detach = 0; struct credentials *cred = NULL; int i; + int ret; for (i = 1; i < argc; i++) { const char *arg = argv[i]; const char *v; if (skip_prefix(arg, "--listen=", &v)) { - string_list_append(&listen_addr, xstrdup_tolower(v)); + string_list_append_nodup(&listen_addr, xstrdup_tolower(v)); continue; } if (skip_prefix(arg, "--port=", &v)) { @@ -1444,7 +1427,7 @@ int cmd_main(int argc, const char **argv) cred = prepare_credentials(user_name, group_name); if (strict_paths && (!ok_paths || !*ok_paths)) - die("option --strict-paths requires a whitelist"); + die("option --strict-paths requires '<directory>' arguments"); if (base_path && !is_directory(base_path)) die("base-path '%s' does not exist or is not a directory", @@ -1455,22 +1438,26 @@ int cmd_main(int argc, const char **argv) die_errno("failed to redirect stderr to /dev/null"); } - if (inetd_mode || serve_mode) - return execute(); + if (inetd_mode || serve_mode) { + ret = execute(); + } else { + if (detach) { + if (daemonize()) + die("--detach not supported on this platform"); + } - if (detach) { - if (daemonize()) - die("--detach not supported on this platform"); - } + if (pid_file) + write_file(pid_file, "%"PRIuMAX, (uintmax_t) getpid()); - if (pid_file) - write_file(pid_file, "%"PRIuMAX, (uintmax_t) getpid()); + /* prepare argv for serving-processes */ + strvec_push(&cld_argv, argv[0]); /* git-daemon */ + strvec_push(&cld_argv, "--serve"); + for (i = 1; i < argc; ++i) + strvec_push(&cld_argv, argv[i]); - /* prepare argv for serving-processes */ - strvec_push(&cld_argv, argv[0]); /* git-daemon */ - strvec_push(&cld_argv, "--serve"); - for (i = 1; i < argc; ++i) - strvec_push(&cld_argv, argv[i]); + ret = serve(&listen_addr, listen_port, cred); + } - return serve(&listen_addr, listen_port, cred); + string_list_clear(&listen_addr, 0); + return ret; } |