X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=credential-cache--daemon.c;h=ec1271f89ce08b3b117fe09715f61730c7943bea;hb=37901a2202e2b806539080bf8cf129d36e4bd003;hp=9365f2ce5c188d86b1b60029e4549e1bd844214f;hpb=bc01ef0d3f3f79fc2f1a9e5e1a6ac0049e7a3c26;p=platform%2Fupstream%2Fgit.git diff --git a/credential-cache--daemon.c b/credential-cache--daemon.c index 9365f2c..ec1271f 100644 --- a/credential-cache--daemon.c +++ b/credential-cache--daemon.c @@ -1,14 +1,13 @@ #include "cache.h" +#include "config.h" #include "tempfile.h" #include "credential.h" #include "unix-socket.h" #include "parse-options.h" -static struct tempfile socket_file; - struct credential_cache_entry { struct credential item; - unsigned long expiration; + timestamp_t expiration; }; static struct credential_cache_entry *entries; static int entries_nr; @@ -47,12 +46,12 @@ static void remove_credential(const struct credential *c) e->expiration = 0; } -static int check_expirations(void) +static timestamp_t check_expirations(void) { - static unsigned long wait_for_entry_until; + static timestamp_t wait_for_entry_until; int i = 0; - unsigned long now = time(NULL); - unsigned long next = (unsigned long)-1; + timestamp_t now = time(NULL); + timestamp_t next = TIME_MAX; /* * Initially give the client 30 seconds to actually contact us @@ -92,16 +91,17 @@ static int check_expirations(void) } static int read_request(FILE *fh, struct credential *c, - struct strbuf *action, int *timeout) { + struct strbuf *action, int *timeout) +{ static struct strbuf item = STRBUF_INIT; const char *p; - strbuf_getline(&item, fh, '\n'); + strbuf_getline_lf(&item, fh); if (!skip_prefix(item.buf, "action=", &p)) return error("client sent bogus action line: %s", item.buf); strbuf_addstr(action, p); - strbuf_getline(&item, fh, '\n'); + strbuf_getline_lf(&item, fh); if (!skip_prefix(item.buf, "timeout=", &p)) return error("client sent bogus timeout line: %s", item.buf); *timeout = atoi(p); @@ -126,8 +126,17 @@ static void serve_one_client(FILE *in, FILE *out) fprintf(out, "password=%s\n", e->item.password); } } - else if (!strcmp(action.buf, "exit")) + else if (!strcmp(action.buf, "exit")) { + /* + * It's important that we clean up our socket first, and then + * signal the client only once we have finished the cleanup. + * Calling exit() directly does this, because we clean up in + * our atexit() handler, and then signal the client when our + * process actually ends, which closes the socket and gives + * them EOF. + */ exit(0); + } else if (!strcmp(action.buf, "erase")) remove_credential(&c); else if (!strcmp(action.buf, "store")) { @@ -150,7 +159,7 @@ static void serve_one_client(FILE *in, FILE *out) static int serve_cache_loop(int fd) { struct pollfd pfd; - unsigned long wakeup; + timestamp_t wakeup; wakeup = check_expirations(); if (!wakeup) @@ -170,12 +179,12 @@ static int serve_cache_loop(int fd) client = accept(fd, NULL, NULL); if (client < 0) { - warning("accept failed: %s", strerror(errno)); + warning_errno("accept failed"); return 1; } client2 = dup(client); if (client2 < 0) { - warning("dup failed: %s", strerror(errno)); + warning_errno("dup failed"); close(client); return 1; } @@ -210,12 +219,12 @@ static void serve_cache(const char *socket_path, int debug) close(fd); } -static const char permissions_advice[] = +static const char permissions_advice[] = N_( "The permissions on your socket directory are too loose; other\n" "users may be able to read your cached credentials. Consider running:\n" "\n" -" chmod 0700 %s"; -static void check_socket_directory(const char *path) +" chmod 0700 %s"); +static void init_socket_directory(const char *path) { struct stat st; char *path_copy = xstrdup(path); @@ -223,26 +232,34 @@ static void check_socket_directory(const char *path) if (!stat(dir, &st)) { if (st.st_mode & 077) - die(permissions_advice, dir); - free(path_copy); - return; + die(_(permissions_advice), dir); + } else { + /* + * We must be sure to create the directory with the correct mode, + * not just chmod it after the fact; otherwise, there is a race + * condition in which somebody can chdir to it, sleep, then try to open + * our protected socket. + */ + if (safe_create_leading_directories_const(dir) < 0) + die_errno("unable to create directories for '%s'", dir); + if (mkdir(dir, 0700) < 0) + die_errno("unable to mkdir '%s'", dir); } - /* - * We must be sure to create the directory with the correct mode, - * not just chmod it after the fact; otherwise, there is a race - * condition in which somebody can chdir to it, sleep, then try to open - * our protected socket. - */ - if (safe_create_leading_directories_const(dir) < 0) - die_errno("unable to create directories for '%s'", dir); - if (mkdir(dir, 0700) < 0) - die_errno("unable to mkdir '%s'", dir); + if (chdir(dir)) + /* + * We don't actually care what our cwd is; we chdir here just to + * be a friendly daemon and avoid tying up our original cwd. + * If this fails, it's OK to just continue without that benefit. + */ + ; + free(path_copy); } -int main(int argc, const char **argv) +int cmd_main(int argc, const char **argv) { + struct tempfile *socket_file; const char *socket_path; int ignore_sighup = 0; static const char *usage[] = { @@ -264,8 +281,11 @@ int main(int argc, const char **argv) if (!socket_path) usage_with_options(usage, options); - check_socket_directory(socket_path); - register_tempfile(&socket_file, socket_path); + if (!is_absolute_path(socket_path)) + die("socket directory must be an absolute path"); + + init_socket_directory(socket_path); + socket_file = register_tempfile(socket_path); if (ignore_sighup) signal(SIGHUP, SIG_IGN);