tty-ask-password-agent: modernization
This commit is contained in:
parent
601185b43d
commit
1d749d044b
|
@ -1977,10 +1977,7 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) {
|
|||
}
|
||||
|
||||
void manager_send_unit_plymouth(Manager *m, Unit *u) {
|
||||
union sockaddr_union sa = {
|
||||
.un.sun_family = AF_UNIX,
|
||||
.un.sun_path = "\0/org/freedesktop/plymouthd",
|
||||
};
|
||||
union sockaddr_union sa = PLYMOUTH_SOCKET;
|
||||
|
||||
int n = 0;
|
||||
_cleanup_free_ char *message = NULL;
|
||||
|
|
|
@ -73,6 +73,11 @@
|
|||
#define UNIX_USER_BUS_FMT "unix:path=%s/bus"
|
||||
#define KERNEL_USER_BUS_FMT "kernel:path=/dev/kdbus/"UID_FMT"-user/bus"
|
||||
|
||||
#define PLYMOUTH_SOCKET { \
|
||||
.un.sun_family = AF_UNIX, \
|
||||
.un.sun_path = "\0/org/freedesktop/plymouthd", \
|
||||
}
|
||||
|
||||
#ifndef TTY_GID
|
||||
#define TTY_GID 5
|
||||
#endif
|
||||
|
|
|
@ -41,6 +41,7 @@
|
|||
#include "ask-password-api.h"
|
||||
#include "strv.h"
|
||||
#include "build.h"
|
||||
#include "def.h"
|
||||
|
||||
static enum {
|
||||
ACTION_LIST,
|
||||
|
@ -59,9 +60,9 @@ static int ask_password_plymouth(
|
|||
bool accept_cached,
|
||||
char ***_passphrases) {
|
||||
|
||||
int fd = -1, notify = -1;
|
||||
union sockaddr_union sa = {};
|
||||
char *packet = NULL;
|
||||
_cleanup_close_ int fd = -1, notify = -1;
|
||||
union sockaddr_union sa = PLYMOUTH_SOCKET;
|
||||
_cleanup_free_ char *packet = NULL;
|
||||
ssize_t k;
|
||||
int r, n;
|
||||
struct pollfd pollfd[2] = {};
|
||||
|
@ -75,28 +76,23 @@ static int ask_password_plymouth(
|
|||
assert(_passphrases);
|
||||
|
||||
if (flag_file) {
|
||||
if ((notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
|
||||
if (notify < 0)
|
||||
return -errno;
|
||||
|
||||
if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
r = inotify_add_watch(notify, flag_file, IN_ATTRIB); /* for the link count */
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if ((fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0)) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
sa.sa.sa_family = AF_UNIX;
|
||||
strncpy(sa.un.sun_path+1, "/org/freedesktop/plymouthd", sizeof(sa.un.sun_path)-1);
|
||||
if (connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1)) < 0) {
|
||||
r = connect(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + 1 + strlen(sa.un.sun_path+1));
|
||||
if (r < 0) {
|
||||
log_error("Failed to connect to Plymouth: %m");
|
||||
r = -errno;
|
||||
goto finish;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (accept_cached) {
|
||||
|
@ -106,15 +102,12 @@ static int ask_password_plymouth(
|
|||
message, &n) < 0)
|
||||
packet = NULL;
|
||||
|
||||
if (!packet) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
if (!packet)
|
||||
return log_oom();
|
||||
|
||||
if ((k = loop_write(fd, packet, n+1, true)) != n+1) {
|
||||
r = k < 0 ? (int) k : -EIO;
|
||||
goto finish;
|
||||
}
|
||||
k = loop_write(fd, packet, n + 1, true);
|
||||
if (k != n + 1)
|
||||
return k < 0 ? (int) k : -EIO;
|
||||
|
||||
pollfd[POLL_SOCKET].fd = fd;
|
||||
pollfd[POLL_SOCKET].events = POLLIN;
|
||||
|
@ -129,31 +122,23 @@ static int ask_password_plymouth(
|
|||
|
||||
y = now(CLOCK_MONOTONIC);
|
||||
|
||||
if (y > until) {
|
||||
r = -ETIME;
|
||||
goto finish;
|
||||
}
|
||||
if (y > until)
|
||||
return -ETIME;
|
||||
|
||||
sleep_for = (int) ((until - y) / USEC_PER_MSEC);
|
||||
}
|
||||
|
||||
if (flag_file)
|
||||
if (access(flag_file, F_OK) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if ((j = poll(pollfd, notify > 0 ? 2 : 1, sleep_for)) < 0) {
|
||||
if (flag_file && access(flag_file, F_OK) < 0)
|
||||
return -errno;
|
||||
|
||||
j = poll(pollfd, notify > 0 ? 2 : 1, sleep_for);
|
||||
if (j < 0) {
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
r = -errno;
|
||||
goto finish;
|
||||
} else if (j == 0) {
|
||||
r = -ETIME;
|
||||
goto finish;
|
||||
}
|
||||
return -errno;
|
||||
} else if (j == 0)
|
||||
return -ETIME;
|
||||
|
||||
if (notify > 0 && pollfd[POLL_INOTIFY].revents != 0)
|
||||
flush_fd(notify);
|
||||
|
@ -161,10 +146,9 @@ static int ask_password_plymouth(
|
|||
if (pollfd[POLL_SOCKET].revents == 0)
|
||||
continue;
|
||||
|
||||
if ((k = read(fd, buffer + p, sizeof(buffer) - p)) <= 0) {
|
||||
r = k < 0 ? -errno : -EIO;
|
||||
goto finish;
|
||||
}
|
||||
k = read(fd, buffer + p, sizeof(buffer) - p);
|
||||
if (k <= 0)
|
||||
return r = k < 0 ? -errno : -EIO;
|
||||
|
||||
p += k;
|
||||
|
||||
|
@ -180,15 +164,12 @@ static int ask_password_plymouth(
|
|||
free(packet);
|
||||
packet = NULL;
|
||||
|
||||
if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0)
|
||||
return -ENOMEM;
|
||||
|
||||
if ((k = loop_write(fd, packet, n+1, true)) != n+1) {
|
||||
r = k < 0 ? (int) k : -EIO;
|
||||
goto finish;
|
||||
}
|
||||
k = loop_write(fd, packet, n+1, true);
|
||||
if (k != n + 1)
|
||||
return k < 0 ? (int) k : -EIO;
|
||||
|
||||
accept_cached = false;
|
||||
p = 0;
|
||||
|
@ -196,8 +177,7 @@ static int ask_password_plymouth(
|
|||
}
|
||||
|
||||
/* No password, because UI not shown */
|
||||
r = -ENOENT;
|
||||
goto finish;
|
||||
return -ENOENT;
|
||||
|
||||
} else if (buffer[0] == 2 || buffer[0] == 9) {
|
||||
uint32_t size;
|
||||
|
@ -209,38 +189,25 @@ static int ask_password_plymouth(
|
|||
|
||||
memcpy(&size, buffer+1, sizeof(size));
|
||||
size = le32toh(size);
|
||||
if (size+5 > sizeof(buffer)) {
|
||||
r = -EIO;
|
||||
goto finish;
|
||||
}
|
||||
if (size + 5 > sizeof(buffer))
|
||||
return -EIO;
|
||||
|
||||
if (p-5 < size)
|
||||
continue;
|
||||
|
||||
if (!(l = strv_parse_nulstr(buffer + 5, size))) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
l = strv_parse_nulstr(buffer + 5, size);
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
*_passphrases = l;
|
||||
break;
|
||||
|
||||
} else {
|
||||
} else
|
||||
/* Unknown packet */
|
||||
r = -EIO;
|
||||
goto finish;
|
||||
}
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
|
||||
finish:
|
||||
safe_close(notify);
|
||||
safe_close(fd);
|
||||
|
||||
free(packet);
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_password(const char *filename, char **wall) {
|
||||
|
@ -255,7 +222,7 @@ static int parse_password(const char *filename, char **wall) {
|
|||
{ "Ask", "Message", config_parse_string, 0, &message },
|
||||
{ "Ask", "PID", config_parse_unsigned, 0, &pid },
|
||||
{ "Ask", "AcceptCached", config_parse_bool, 0, &accept_cached },
|
||||
{ NULL, NULL, NULL, 0, NULL }
|
||||
{}
|
||||
};
|
||||
|
||||
int r;
|
||||
|
@ -328,13 +295,12 @@ static int parse_password(const char *filename, char **wall) {
|
|||
if (!packet)
|
||||
r = -ENOMEM;
|
||||
else {
|
||||
char *d;
|
||||
|
||||
packet[0] = '+';
|
||||
d = packet+1;
|
||||
char *d = packet + 1;
|
||||
|
||||
STRV_FOREACH(p, passwords)
|
||||
d = stpcpy(d, *p) + 1;
|
||||
|
||||
packet[0] = '+';
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,7 +333,7 @@ static int parse_password(const char *filename, char **wall) {
|
|||
}
|
||||
}
|
||||
|
||||
if (r == -ETIME || r == -ENOENT)
|
||||
if (IN_SET(r, -ETIME, -ENOENT))
|
||||
/* If the query went away, that's OK */
|
||||
return 0;
|
||||
|
||||
|
@ -397,7 +363,7 @@ static int parse_password(const char *filename, char **wall) {
|
|||
}
|
||||
|
||||
static int wall_tty_block(void) {
|
||||
char *p;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
int fd, r;
|
||||
dev_t devnr;
|
||||
|
||||
|
@ -412,8 +378,6 @@ static int wall_tty_block(void) {
|
|||
mkfifo(p, 0600);
|
||||
|
||||
fd = open(p, O_RDONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
|
||||
free(p);
|
||||
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
|
@ -421,21 +385,15 @@ static int wall_tty_block(void) {
|
|||
}
|
||||
|
||||
static bool wall_tty_match(const char *path) {
|
||||
int fd, k;
|
||||
char *p;
|
||||
int fd, r;
|
||||
struct stat st;
|
||||
_cleanup_free_ char *p = NULL;
|
||||
|
||||
if (path_is_absolute(path))
|
||||
k = lstat(path, &st);
|
||||
else {
|
||||
if (asprintf(&p, "/dev/%s", path) < 0)
|
||||
return true;
|
||||
if (!path_is_absolute(path))
|
||||
path = strappenda("/dev/", path);
|
||||
|
||||
k = lstat(p, &st);
|
||||
free(p);
|
||||
}
|
||||
|
||||
if (k < 0)
|
||||
r = lstat(path, &st);
|
||||
if (r < 0)
|
||||
return true;
|
||||
|
||||
if (!S_ISCHR(st.st_mode))
|
||||
|
@ -453,8 +411,6 @@ static bool wall_tty_match(const char *path) {
|
|||
return true;
|
||||
|
||||
fd = open(p, O_WRONLY|O_CLOEXEC|O_NONBLOCK|O_NOCTTY);
|
||||
free(p);
|
||||
|
||||
if (fd < 0)
|
||||
return true;
|
||||
|
||||
|
@ -464,11 +420,12 @@ static bool wall_tty_match(const char *path) {
|
|||
}
|
||||
|
||||
static int show_passwords(void) {
|
||||
DIR *d;
|
||||
_cleanup_closedir_ DIR *d;
|
||||
struct dirent *de;
|
||||
int r = 0;
|
||||
|
||||
if (!(d = opendir("/run/systemd/ask-password"))) {
|
||||
d = opendir("/run/systemd/ask-password");
|
||||
if (!d) {
|
||||
if (errno == ENOENT)
|
||||
return 0;
|
||||
|
||||
|
@ -477,9 +434,8 @@ static int show_passwords(void) {
|
|||
}
|
||||
|
||||
while ((de = readdir(d))) {
|
||||
char *p;
|
||||
_cleanup_free_ char *p = NULL, *wall = NULL;
|
||||
int q;
|
||||
char *wall;
|
||||
|
||||
/* We only support /dev on tmpfs, hence we can rely on
|
||||
* d_type to be reliable */
|
||||
|
@ -493,27 +449,18 @@ static int show_passwords(void) {
|
|||
if (!startswith(de->d_name, "ask."))
|
||||
continue;
|
||||
|
||||
if (!(p = strappend("/run/systemd/ask-password/", de->d_name))) {
|
||||
r = log_oom();
|
||||
goto finish;
|
||||
}
|
||||
p = strappend("/run/systemd/ask-password/", de->d_name);
|
||||
if (!p)
|
||||
return log_oom();
|
||||
|
||||
wall = NULL;
|
||||
if ((q = parse_password(p, &wall)) < 0)
|
||||
q = parse_password(p, &wall);
|
||||
if (q < 0 && r == 0)
|
||||
r = q;
|
||||
|
||||
free(p);
|
||||
|
||||
if (wall) {
|
||||
if (wall)
|
||||
utmp_wall(wall, NULL, wall_tty_match);
|
||||
free(wall);
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
if (d)
|
||||
closedir(d);
|
||||
|
||||
return r;
|
||||
}
|
||||
|
||||
|
@ -524,7 +471,7 @@ static int watch_passwords(void) {
|
|||
_FD_MAX
|
||||
};
|
||||
|
||||
int notify = -1, signal_fd = -1, tty_block_fd = -1;
|
||||
_cleanup_close_ int notify = -1, signal_fd = -1, tty_block_fd = -1;
|
||||
struct pollfd pollfd[_FD_MAX] = {};
|
||||
sigset_t mask;
|
||||
int r;
|
||||
|
@ -533,25 +480,20 @@ static int watch_passwords(void) {
|
|||
|
||||
mkdir_p_label("/run/systemd/ask-password", 0755);
|
||||
|
||||
if ((notify = inotify_init1(IN_CLOEXEC)) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
notify = inotify_init1(IN_CLOEXEC);
|
||||
if (notify < 0)
|
||||
return -errno;
|
||||
|
||||
if (inotify_add_watch(notify, "/run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
if (inotify_add_watch(notify, "/run/systemd/ask-password", IN_CLOSE_WRITE|IN_MOVED_TO) < 0)
|
||||
return -errno;
|
||||
|
||||
assert_se(sigemptyset(&mask) == 0);
|
||||
sigset_add_many(&mask, SIGINT, SIGTERM, -1);
|
||||
assert_se(sigprocmask(SIG_SETMASK, &mask, NULL) == 0);
|
||||
|
||||
if ((signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC)) < 0) {
|
||||
log_error("signalfd(): %m");
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
|
||||
if (signal_fd < 0)
|
||||
return -errno;
|
||||
|
||||
pollfd[FD_INOTIFY].fd = notify;
|
||||
pollfd[FD_INOTIFY].events = POLLIN;
|
||||
|
@ -559,16 +501,15 @@ static int watch_passwords(void) {
|
|||
pollfd[FD_SIGNAL].events = POLLIN;
|
||||
|
||||
for (;;) {
|
||||
if ((r = show_passwords()) < 0)
|
||||
r = show_passwords();
|
||||
if (r < 0)
|
||||
log_error("Failed to show password: %s", strerror(-r));
|
||||
|
||||
if (poll(pollfd, _FD_MAX, -1) < 0) {
|
||||
|
||||
if (errno == EINTR)
|
||||
continue;
|
||||
|
||||
r = -errno;
|
||||
goto finish;
|
||||
return -errno;
|
||||
}
|
||||
|
||||
if (pollfd[FD_INOTIFY].revents != 0)
|
||||
|
@ -578,14 +519,7 @@ static int watch_passwords(void) {
|
|||
break;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
|
||||
finish:
|
||||
safe_close(notify);
|
||||
safe_close(signal_fd);
|
||||
safe_close(tty_block_fd);
|
||||
|
||||
return r;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void help(void) {
|
||||
|
@ -692,7 +626,8 @@ int main(int argc, char *argv[]) {
|
|||
|
||||
umask(0022);
|
||||
|
||||
if ((r = parse_argv(argc, argv)) <= 0)
|
||||
r = parse_argv(argc, argv);
|
||||
if (r <= 0)
|
||||
goto finish;
|
||||
|
||||
if (arg_console) {
|
||||
|
@ -700,8 +635,7 @@ int main(int argc, char *argv[]) {
|
|||
release_terminal();
|
||||
}
|
||||
|
||||
if (arg_action == ACTION_WATCH ||
|
||||
arg_action == ACTION_WALL)
|
||||
if (IN_SET(arg_action, ACTION_WATCH, ACTION_WALL))
|
||||
r = watch_passwords();
|
||||
else
|
||||
r = show_passwords();
|
||||
|
|
Loading…
Reference in a new issue