mirror of
https://github.com/morgan9e/systemd
synced 2026-04-14 08:25:20 +09:00
tty-ask-password-agent: minor modernizations
This commit is contained in:
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user