diff options
Diffstat (limited to 'src/tty-ask-password-agent/tty-ask-password-agent.c')
-rw-r--r-- | src/tty-ask-password-agent/tty-ask-password-agent.c | 136 |
1 files changed, 69 insertions, 67 deletions
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 40d594896b..fc165ffc01 100644 --- a/src/tty-ask-password-agent/tty-ask-password-agent.c +++ b/src/tty-ask-password-agent/tty-ask-password-agent.c @@ -30,8 +30,10 @@ #include "hashmap.h" #include "io-util.h" #include "macro.h" +#include "main-func.h" #include "mkdir.h" #include "path-util.h" +#include "pretty-print.h" #include "process-util.h" #include "signal-util.h" #include "socket-util.h" @@ -228,21 +230,25 @@ static int ask_password_plymouth( r = 0; finish: - explicit_bzero(buffer, sizeof(buffer)); + explicit_bzero_safe(buffer, sizeof(buffer)); return r; } static int send_passwords(const char *socket_name, char **passwords) { _cleanup_free_ char *packet = NULL; _cleanup_close_ int socket_fd = -1; - union sockaddr_union sa = { .un.sun_family = AF_UNIX }; + union sockaddr_union sa = {}; size_t packet_length = 1; char **p, *d; ssize_t n; - int r; + int r, salen; assert(socket_name); + salen = sockaddr_un_set_path(&sa.un, socket_name); + if (salen < 0) + return salen; + STRV_FOREACH(p, passwords) packet_length += strlen(*p) + 1; @@ -262,9 +268,7 @@ static int send_passwords(const char *socket_name, char **passwords) { goto finish; } - strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path)); - - n = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, SOCKADDR_UN_LEN(sa.un)); + n = sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, salen); if (n < 0) { r = log_debug_errno(errno, "sendto(): %m"); goto finish; @@ -273,7 +277,7 @@ static int send_passwords(const char *socket_name, char **passwords) { r = (int) n; finish: - explicit_bzero(packet, packet_length); + explicit_bzero_safe(packet, packet_length); return r; } @@ -304,10 +308,9 @@ static int parse_password(const char *filename, char **wall) { if (r < 0) return r; - if (!socket_name) { - log_error("Invalid password file %s", filename); - return -EBADMSG; - } + if (!socket_name) + return log_error_errno(SYNTHETIC_ERRNO(EBADMSG), + "Invalid password file %s", filename); if (not_after > 0 && now(CLOCK_MONOTONIC) > not_after) return 0; @@ -323,7 +326,7 @@ static int parse_password(const char *filename, char **wall) { if (asprintf(&_wall, "%s%sPassword entry required for \'%s\' (PID %u).\r\n" - "Please enter password with the systemd-tty-ask-password-agent tool!", + "Please enter password with the systemd-tty-ask-password-agent tool:", strempty(*wall), *wall ? "\r\n\r\n" : "", message, @@ -348,7 +351,6 @@ static int parse_password(const char *filename, char **wall) { if (arg_plymouth) r = ask_password_plymouth(message, not_after, accept_cached ? ASK_PASSWORD_ACCEPT_CACHED : 0, filename, &passwords); else { - char *password = NULL; int tty_fd = -1; if (arg_console) { @@ -366,18 +368,12 @@ static int parse_password(const char *filename, char **wall) { r = ask_password_tty(tty_fd, message, NULL, not_after, (echo ? ASK_PASSWORD_ECHO : 0) | (arg_console ? ASK_PASSWORD_CONSOLE_COLOR : 0), - filename, &password); + filename, &passwords); if (arg_console) { tty_fd = safe_close(tty_fd); release_terminal(); } - - if (r >= 0) - r = strv_push(&passwords, password); - - if (r < 0) - string_free_erase(password); } /* If the query went away, that's OK */ @@ -524,8 +520,12 @@ static int watch_passwords(void) { if (notify < 0) return log_error_errno(errno, "Failed to allocate directory watch: %m"); - if (inotify_add_watch(notify, "/run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0) - return log_error_errno(errno, "Failed to add /run/systemd/ask-password to directory watch: %m"); + if (inotify_add_watch(notify, "/run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0) { + if (errno == ENOSPC) + return log_error_errno(errno, "Failed to add /run/systemd/ask-password to directory watch: inotify watch limit reached"); + else + return log_error_errno(errno, "Failed to add /run/systemd/ask-password to directory watch: %m"); + } assert_se(sigemptyset(&mask) >= 0); assert_se(sigset_add_many(&mask, SIGINT, SIGTERM, -1) >= 0); @@ -562,7 +562,14 @@ static int watch_passwords(void) { return 0; } -static void help(void) { +static int help(void) { + _cleanup_free_ char *link = NULL; + int r; + + r = terminal_urlify_man("systemd-tty-ask-password-agent", "1", &link); + if (r < 0) + return log_oom(); + printf("%s [OPTIONS...]\n\n" "Process system password requests.\n\n" " -h --help Show this help\n" @@ -572,8 +579,13 @@ static void help(void) { " --watch Continuously process password requests\n" " --wall Continuously forward password requests to wall\n" " --plymouth Ask question with Plymouth instead of on TTY\n" - " --console Ask question on /dev/console instead of current TTY\n", - program_invocation_short_name); + " --console Ask question on /dev/console instead of current TTY\n" + "\nSee the %s for details.\n" + , program_invocation_short_name + , link + ); + + return 0; } static int parse_argv(int argc, char *argv[]) { @@ -610,8 +622,7 @@ static int parse_argv(int argc, char *argv[]) { switch (c) { case 'h': - help(); - return 0; + return help(); case ARG_VERSION: return version(); @@ -640,10 +651,9 @@ static int parse_argv(int argc, char *argv[]) { arg_console = true; if (optarg) { - if (isempty(optarg)) { - log_error("Empty console device path is not allowed."); - return -EINVAL; - } + if (isempty(optarg)) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Empty console device path is not allowed."); arg_device = optarg; } @@ -656,22 +666,19 @@ static int parse_argv(int argc, char *argv[]) { assert_not_reached("Unhandled option"); } - if (optind != argc) { - log_error("%s takes no arguments.", program_invocation_short_name); - return -EINVAL; - } + if (optind != argc) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "%s takes no arguments.", program_invocation_short_name); if (arg_plymouth || arg_console) { - if (!IN_SET(arg_action, ACTION_QUERY, ACTION_WATCH)) { - log_error("Options --query and --watch conflict."); - return -EINVAL; - } + if (!IN_SET(arg_action, ACTION_QUERY, ACTION_WATCH)) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Options --query and --watch conflict."); - if (arg_plymouth && arg_console) { - log_error("Options --plymouth and --console conflict."); - return -EINVAL; - } + if (arg_plymouth && arg_console) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Options --plymouth and --console conflict."); } return 1; @@ -826,42 +833,37 @@ static int ask_on_consoles(int argc, char *argv[]) { return 0; } -int main(int argc, char *argv[]) { +static int run(int argc, char *argv[]) { int r; - log_set_target(LOG_TARGET_AUTO); - log_parse_environment(); - log_open(); + log_setup_service(); umask(0022); r = parse_argv(argc, argv); if (r <= 0) - goto finish; + return r; if (arg_console && !arg_device) /* - * Spawn for each console device a separate process. + * Spawn a separate process for each console device. */ - r = ask_on_consoles(argc, argv); - else { - - if (arg_device) { - /* - * Later on, a controlling terminal will be acquired, - * therefore the current process has to become a session - * leader and should not have a controlling terminal already. - */ - (void) setsid(); - (void) release_terminal(); - } + return ask_on_consoles(argc, argv); - if (IN_SET(arg_action, ACTION_WATCH, ACTION_WALL)) - r = watch_passwords(); - else - r = show_passwords(); + if (arg_device) { + /* + * Later on, a controlling terminal will be acquired, + * therefore the current process has to become a session + * leader and should not have a controlling terminal already. + */ + (void) setsid(); + (void) release_terminal(); } -finish: - return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; + if (IN_SET(arg_action, ACTION_WATCH, ACTION_WALL)) + return watch_passwords(); + else + return show_passwords(); } + +DEFINE_MAIN_FUNCTION(run); |