summaryrefslogtreecommitdiff
path: root/credential-cache--daemon.c
diff options
context:
space:
mode:
Diffstat (limited to 'credential-cache--daemon.c')
-rw-r--r--credential-cache--daemon.c53
1 files changed, 36 insertions, 17 deletions
diff --git a/credential-cache--daemon.c b/credential-cache--daemon.c
index cc65a9c0d3..1f14d56e98 100644
--- a/credential-cache--daemon.c
+++ b/credential-cache--daemon.c
@@ -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")) {
@@ -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;
}
@@ -215,7 +224,7 @@ static const char permissions_advice[] =
"users may be able to read your cached credentials. Consider running:\n"
"\n"
" chmod 0700 %s";
-static void check_socket_directory(const char *path)
+static void init_socket_directory(const char *path)
{
struct stat st;
char *path_copy = xstrdup(path);
@@ -224,20 +233,27 @@ 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;
+ } 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);
}
@@ -264,7 +280,10 @@ int main(int argc, const char **argv)
if (!socket_path)
usage_with_options(usage, options);
- check_socket_directory(socket_path);
+ if (!is_absolute_path(socket_path))
+ die("socket directory must be an absolute path");
+
+ init_socket_directory(socket_path);
register_tempfile(&socket_file, socket_path);
if (ignore_sighup)