From: Lennart Poettering Date: Fri, 13 Sep 2024 09:06:28 +0000 (+0200) Subject: tty-ask-password-agent: minor modernizations X-Git-Tag: v257-rc1~175^2~7 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=5475c3dbe4d96c29b5ff7cdff71c2373fb1558b0;p=thirdparty%2Fsystemd.git tty-ask-password-agent: minor modernizations --- diff --git a/src/tty-ask-password-agent/tty-ask-password-agent.c b/src/tty-ask-password-agent/tty-ask-password-agent.c index df21f3d28fb..1e4eb9b7684 100644 --- a/src/tty-ask-password-agent/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent/tty-ask-password-agent.c @@ -55,40 +55,35 @@ static bool arg_console = false; static const char *arg_device = NULL; static int send_passwords(const char *socket_name, char **passwords) { - _cleanup_(erase_and_freep) char *packet = NULL; - _cleanup_close_ int socket_fd = -EBADF; - union sockaddr_union sa; - socklen_t sa_len; - size_t packet_length = 1; - char *d; - ssize_t n; int r; assert(socket_name); + union sockaddr_union sa; r = sockaddr_un_set_path(&sa.un, socket_name); if (r < 0) return r; - sa_len = r; + socklen_t sa_len = r; + size_t packet_length = 1; STRV_FOREACH(p, passwords) packet_length += strlen(*p) + 1; - packet = new(char, packet_length); + _cleanup_(erase_and_freep) char *packet = new(char, packet_length); if (!packet) return -ENOMEM; packet[0] = '+'; - d = packet + 1; + char *d = packet + 1; STRV_FOREACH(p, passwords) d = stpcpy(d, *p) + 1; - socket_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); + _cleanup_close_ int socket_fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0); if (socket_fd < 0) return log_debug_errno(errno, "socket(): %m"); - n = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, sa_len); + ssize_t n = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, sa_len); if (n < 0) return log_debug_errno(errno, "sendto(): %m"); @@ -96,12 +91,9 @@ static int send_passwords(const char *socket_name, char **passwords) { } static bool wall_tty_match(const char *path, bool is_local, void *userdata) { - _cleanup_free_ char *p = NULL; - _cleanup_close_ int fd = -EBADF; - struct stat st; - assert(path_is_absolute(path)); + struct stat st; if (lstat(path, &st) < 0) { log_debug_errno(errno, "Failed to stat %s: %m", path); return true; @@ -120,12 +112,13 @@ static bool wall_tty_match(const char *path, bool is_local, void *userdata) { * advantage that the block will automatically go away if the * process dies. */ + _cleanup_free_ char *p = NULL; if (asprintf(&p, "/run/systemd/ask-password-block/%u:%u", major(st.st_rdev), minor(st.st_rdev)) < 0) { - log_oom(); + log_oom_debug(); return true; } - fd = open(p, O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); + _cleanup_close_ int fd = open(p, O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY); if (fd < 0) { log_debug_errno(errno, "Failed to open the wall pipe: %m"); return 1; @@ -162,6 +155,7 @@ static int agent_ask_password_tty( r = ask_password_tty(tty_fd, &req, until, flags, flag_file, ret); if (arg_console) { + assert(tty_fd >= 0); tty_fd = safe_close(tty_fd); release_terminal(); @@ -172,7 +166,7 @@ static int agent_ask_password_tty( return r; } -static int process_one_password_file(const char *filename) { +static int process_one_password_file(const char *filename, FILE *f) { _cleanup_free_ char *socket_name = NULL, *message = NULL; bool accept_cached = false, echo = false, silent = false; uint64_t not_after = 0; @@ -192,13 +186,17 @@ static int process_one_password_file(const char *filename) { int r; assert(filename); - - r = config_parse(NULL, filename, NULL, - NULL, - config_item_table_lookup, items, + assert(f); + + r = config_parse(/* unit= */ NULL, + filename, + f, + /* sections= */ "Ask\0", + config_item_table_lookup, + items, CONFIG_PARSE_RELAXED|CONFIG_PARSE_WARN, - NULL, - NULL); + /* userdata= */ NULL, + /* ret_stat= */ NULL); if (r < 0) return r; @@ -299,7 +297,7 @@ static int wall_tty_block(void) { static int process_password_files(void) { _cleanup_closedir_ DIR *d = NULL; - int r = 0; + int ret = 0, r; d = opendir("/run/systemd/ask-password"); if (!d) { @@ -311,12 +309,8 @@ static int process_password_files(void) { FOREACH_DIRENT(de, d, return log_error_errno(errno, "Failed to read directory: %m")) { _cleanup_free_ char *p = NULL; - int q; - - /* We only support /run on tmpfs, hence we can rely on - * d_type to be reliable */ - if (de->d_type != DT_REG) + if (!IN_SET(de->d_type, DT_REG, DT_UNKNOWN)) continue; if (!startswith(de->d_name, "ask.")) @@ -326,12 +320,17 @@ static int process_password_files(void) { if (!p) return log_oom(); - q = process_one_password_file(p); - if (q < 0 && r == 0) - r = q; + _cleanup_fclose_ FILE *f = NULL; + r = xfopenat(dirfd(d), de->d_name, "re", O_NOFOLLOW, &f); + if (r < 0) { + log_warning_errno(r, "Failed to open '%s', ignoring: %m", p); + continue; + } + + RET_GATHER(ret, process_one_password_file(p, f)); } - return r; + return ret; } static int process_and_watch_password_files(bool watch) { @@ -377,18 +376,15 @@ static int process_and_watch_password_files(bool watch) { usec_t timeout = USEC_INFINITY; r = process_password_files(); - if (r < 0) { - if (r == -ECANCELED) - /* Disable poll() timeout since at least one password has - * been skipped and therefore one file remains and is - * unlikely to trigger any events. */ - timeout = 0; - else - /* FIXME: we should do something here since otherwise the service - * requesting the password won't notice the error and will wait - * indefinitely. */ - log_error_errno(r, "Failed to process password: %m"); - } + if (r == -ECANCELED) + /* Disable poll() timeout since at least one password has been skipped and therefore + * one file remains and is unlikely to trigger any events. */ + timeout = 0; + else if (r < 0) + /* FIXME: we should do something here since otherwise the service + * requesting the password won't notice the error and will wait + * indefinitely. */ + log_warning_errno(r, "Failed to process password, ignoring: %m"); if (!watch) break;