mirror of
https://github.com/systemd/systemd.git
synced 2025-01-26 14:04:03 +03:00
tty-ask-pwd-agent: move ask_password_plymouth() in ask-password-api.c
This commit is contained in:
parent
87c4444ac9
commit
6b2faba764
@ -34,6 +34,7 @@
|
||||
#include "memory-util.h"
|
||||
#include "missing.h"
|
||||
#include "mkdir.h"
|
||||
#include "plymouth-util.h"
|
||||
#include "process-util.h"
|
||||
#include "random-util.h"
|
||||
#include "signal-util.h"
|
||||
@ -211,6 +212,186 @@ static int backspace_string(int ttyfd, const char *str) {
|
||||
return backspace_chars(ttyfd, m);
|
||||
}
|
||||
|
||||
int ask_password_plymouth(
|
||||
const char *message,
|
||||
usec_t until,
|
||||
AskPasswordFlags flags,
|
||||
const char *flag_file,
|
||||
char ***ret) {
|
||||
|
||||
static const union sockaddr_union sa = PLYMOUTH_SOCKET;
|
||||
_cleanup_close_ int fd = -1, notify = -1;
|
||||
_cleanup_free_ char *packet = NULL;
|
||||
ssize_t k;
|
||||
int r, n;
|
||||
struct pollfd pollfd[2] = {};
|
||||
char buffer[LINE_MAX];
|
||||
size_t p = 0;
|
||||
enum {
|
||||
POLL_SOCKET,
|
||||
POLL_INOTIFY
|
||||
};
|
||||
|
||||
assert(ret);
|
||||
|
||||
if (flag_file) {
|
||||
notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
|
||||
if (notify < 0)
|
||||
return -errno;
|
||||
|
||||
r = inotify_add_watch(notify, flag_file, IN_ATTRIB); /* for the link count */
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
if (flags & ASK_PASSWORD_ACCEPT_CACHED) {
|
||||
packet = strdup("c");
|
||||
n = 1;
|
||||
} else if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0)
|
||||
packet = NULL;
|
||||
if (!packet)
|
||||
return -ENOMEM;
|
||||
|
||||
r = loop_write(fd, packet, n + 1, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
pollfd[POLL_SOCKET].fd = fd;
|
||||
pollfd[POLL_SOCKET].events = POLLIN;
|
||||
pollfd[POLL_INOTIFY].fd = notify;
|
||||
pollfd[POLL_INOTIFY].events = POLLIN;
|
||||
|
||||
for (;;) {
|
||||
int sleep_for = -1, j;
|
||||
|
||||
if (until > 0) {
|
||||
usec_t y;
|
||||
|
||||
y = now(CLOCK_MONOTONIC);
|
||||
|
||||
if (y > until) {
|
||||
r = -ETIME;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
sleep_for = (int) ((until - y) / USEC_PER_MSEC);
|
||||
}
|
||||
|
||||
if (flag_file && access(flag_file, F_OK) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0)
|
||||
(void) flush_fd(notify);
|
||||
|
||||
if (pollfd[POLL_SOCKET].revents == 0)
|
||||
continue;
|
||||
|
||||
k = read(fd, buffer + p, sizeof(buffer) - p);
|
||||
if (k < 0) {
|
||||
if (IN_SET(errno, EINTR, EAGAIN))
|
||||
continue;
|
||||
|
||||
r = -errno;
|
||||
goto finish;
|
||||
} else if (k == 0) {
|
||||
r = -EIO;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
p += k;
|
||||
|
||||
if (p < 1)
|
||||
continue;
|
||||
|
||||
if (buffer[0] == 5) {
|
||||
|
||||
if (flags & ASK_PASSWORD_ACCEPT_CACHED) {
|
||||
/* Hmm, first try with cached
|
||||
* passwords failed, so let's retry
|
||||
* with a normal password request */
|
||||
packet = mfree(packet);
|
||||
|
||||
if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = loop_write(fd, packet, n+1, true);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
|
||||
p = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* No password, because UI not shown */
|
||||
r = -ENOENT;
|
||||
goto finish;
|
||||
|
||||
} else if (IN_SET(buffer[0], 2, 9)) {
|
||||
uint32_t size;
|
||||
char **l;
|
||||
|
||||
/* One or more answers */
|
||||
if (p < 5)
|
||||
continue;
|
||||
|
||||
memcpy(&size, buffer+1, sizeof(size));
|
||||
size = le32toh(size);
|
||||
if (size + 5 > sizeof(buffer)) {
|
||||
r = -EIO;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (p-5 < size)
|
||||
continue;
|
||||
|
||||
l = strv_parse_nulstr(buffer + 5, size);
|
||||
if (!l) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
*ret = l;
|
||||
break;
|
||||
|
||||
} else {
|
||||
/* Unknown packet */
|
||||
r = -EIO;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
r = 0;
|
||||
|
||||
finish:
|
||||
explicit_bzero_safe(buffer, sizeof(buffer));
|
||||
return r;
|
||||
}
|
||||
|
||||
int ask_password_tty(
|
||||
int ttyfd,
|
||||
const char *message,
|
||||
|
@ -16,5 +16,6 @@ typedef enum AskPasswordFlags {
|
||||
} AskPasswordFlags;
|
||||
|
||||
int ask_password_tty(int tty_fd, const char *message, const char *keyname, usec_t until, AskPasswordFlags flags, const char *flag_file, char ***ret);
|
||||
int ask_password_plymouth(const char *message, usec_t until, AskPasswordFlags flags, const char *flag_file, char ***ret);
|
||||
int ask_password_agent(const char *message, const char *icon, const char *id, const char *keyname, usec_t until, AskPasswordFlags flag, char ***ret);
|
||||
int ask_password_auto(const char *message, const char *icon, const char *id, const char *keyname, usec_t until, AskPasswordFlags flag, char ***ret);
|
||||
|
@ -36,7 +36,6 @@
|
||||
#include "memory-util.h"
|
||||
#include "mkdir.h"
|
||||
#include "path-util.h"
|
||||
#include "plymouth-util.h"
|
||||
#include "pretty-print.h"
|
||||
#include "process-util.h"
|
||||
#include "set.h"
|
||||
@ -58,186 +57,6 @@ static bool arg_plymouth = false;
|
||||
static bool arg_console = false;
|
||||
static const char *arg_device = NULL;
|
||||
|
||||
static int ask_password_plymouth(
|
||||
const char *message,
|
||||
usec_t until,
|
||||
AskPasswordFlags flags,
|
||||
const char *flag_file,
|
||||
char ***ret) {
|
||||
|
||||
static const union sockaddr_union sa = PLYMOUTH_SOCKET;
|
||||
_cleanup_close_ int fd = -1, notify = -1;
|
||||
_cleanup_free_ char *packet = NULL;
|
||||
ssize_t k;
|
||||
int r, n;
|
||||
struct pollfd pollfd[2] = {};
|
||||
char buffer[LINE_MAX];
|
||||
size_t p = 0;
|
||||
enum {
|
||||
POLL_SOCKET,
|
||||
POLL_INOTIFY
|
||||
};
|
||||
|
||||
assert(ret);
|
||||
|
||||
if (flag_file) {
|
||||
notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
|
||||
if (notify < 0)
|
||||
return -errno;
|
||||
|
||||
r = inotify_add_watch(notify, flag_file, IN_ATTRIB); /* for the link count */
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
}
|
||||
|
||||
fd = socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
|
||||
if (fd < 0)
|
||||
return -errno;
|
||||
|
||||
r = connect(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un));
|
||||
if (r < 0)
|
||||
return -errno;
|
||||
|
||||
if (flags & ASK_PASSWORD_ACCEPT_CACHED) {
|
||||
packet = strdup("c");
|
||||
n = 1;
|
||||
} else if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0)
|
||||
packet = NULL;
|
||||
if (!packet)
|
||||
return -ENOMEM;
|
||||
|
||||
r = loop_write(fd, packet, n + 1, true);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
pollfd[POLL_SOCKET].fd = fd;
|
||||
pollfd[POLL_SOCKET].events = POLLIN;
|
||||
pollfd[POLL_INOTIFY].fd = notify;
|
||||
pollfd[POLL_INOTIFY].events = POLLIN;
|
||||
|
||||
for (;;) {
|
||||
int sleep_for = -1, j;
|
||||
|
||||
if (until > 0) {
|
||||
usec_t y;
|
||||
|
||||
y = now(CLOCK_MONOTONIC);
|
||||
|
||||
if (y > until) {
|
||||
r = -ETIME;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
sleep_for = (int) ((until - y) / USEC_PER_MSEC);
|
||||
}
|
||||
|
||||
if (flag_file && access(flag_file, F_OK) < 0) {
|
||||
r = -errno;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0)
|
||||
(void) flush_fd(notify);
|
||||
|
||||
if (pollfd[POLL_SOCKET].revents == 0)
|
||||
continue;
|
||||
|
||||
k = read(fd, buffer + p, sizeof(buffer) - p);
|
||||
if (k < 0) {
|
||||
if (IN_SET(errno, EINTR, EAGAIN))
|
||||
continue;
|
||||
|
||||
r = -errno;
|
||||
goto finish;
|
||||
} else if (k == 0) {
|
||||
r = -EIO;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
p += k;
|
||||
|
||||
if (p < 1)
|
||||
continue;
|
||||
|
||||
if (buffer[0] == 5) {
|
||||
|
||||
if (flags & ASK_PASSWORD_ACCEPT_CACHED) {
|
||||
/* Hmm, first try with cached
|
||||
* passwords failed, so let's retry
|
||||
* with a normal password request */
|
||||
packet = mfree(packet);
|
||||
|
||||
if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = loop_write(fd, packet, n+1, true);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
|
||||
flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
|
||||
p = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* No password, because UI not shown */
|
||||
r = -ENOENT;
|
||||
goto finish;
|
||||
|
||||
} else if (IN_SET(buffer[0], 2, 9)) {
|
||||
uint32_t size;
|
||||
char **l;
|
||||
|
||||
/* One or more answers */
|
||||
if (p < 5)
|
||||
continue;
|
||||
|
||||
memcpy(&size, buffer+1, sizeof(size));
|
||||
size = le32toh(size);
|
||||
if (size + 5 > sizeof(buffer)) {
|
||||
r = -EIO;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (p-5 < size)
|
||||
continue;
|
||||
|
||||
l = strv_parse_nulstr(buffer + 5, size);
|
||||
if (!l) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
*ret = l;
|
||||
break;
|
||||
|
||||
} else {
|
||||
/* Unknown packet */
|
||||
r = -EIO;
|
||||
goto finish;
|
||||
}
|
||||
}
|
||||
|
||||
r = 0;
|
||||
|
||||
finish:
|
||||
explicit_bzero_safe(buffer, sizeof(buffer));
|
||||
return r;
|
||||
}
|
||||
|
||||
static int send_passwords(const char *socket_name, char **passwords) {
|
||||
_cleanup_(erase_and_freep) char *packet = NULL;
|
||||
_cleanup_close_ int socket_fd = -1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user