tty-ask-password-agent: minor modernizations

This commit is contained in:
Lennart Poettering
2024-09-13 11:06:28 +02:00
parent 298507b24d
commit 5475c3dbe4

View File

@@ -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);
assert(f);
r = config_parse(NULL, filename, NULL,
NULL,
config_item_table_lookup, items,
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;