summaryrefslogtreecommitdiff
path: root/src/tty-ask-password-agent/tty-ask-password-agent.c
diff options
context:
space:
mode:
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.c136
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);