mirror of
https://github.com/systemd/systemd.git
synced 2025-03-28 02:50:16 +03:00
ask-password: supported plymouth cached passwords
This commit is contained in:
parent
80758717a6
commit
21bc923aa3
21
README
21
README
@ -27,7 +27,7 @@ AUTHOR:
|
||||
Lennart Poettering with major support from Kay Sievers
|
||||
|
||||
REQUIREMENTS:
|
||||
Linux kernel >= 2.6.30 (with autofs4, devtmpfs, cgroups, ipv6)
|
||||
Linux kernel >= 2.6.30 (with devtmpfs, cgroups; optional but strongly recommended: autofs4, ipv6)
|
||||
libudev >= 163
|
||||
dbus >= 1.4.0
|
||||
libcap
|
||||
@ -47,10 +47,27 @@ REQUIREMENTS:
|
||||
automake
|
||||
autoconf
|
||||
libtool
|
||||
make, gcc, and similar tools
|
||||
|
||||
During runtime you need the following dependencies:
|
||||
|
||||
util-linux > v2.18 (requires fsck -l, agetty -s)
|
||||
sulogin (from sysvinit-tools)
|
||||
sulogin (from sysvinit-tools, optional but recommended)
|
||||
plymouth (optional)
|
||||
dracut (optional)
|
||||
|
||||
WARNINGS:
|
||||
systemd will warn you during boot if /etc/mtab is not a
|
||||
symlink to /proc/mounts. Please ensure that /etc/mtab is a
|
||||
proper symlink.
|
||||
|
||||
systemd will warn you during boot if /usr is on a different
|
||||
file system than /. While in systemd itself very little will
|
||||
break if /usr is on a seperate partition many of its
|
||||
dependencies very likely will break sooner or later in one
|
||||
form or another. For example udev rules tend to refer to
|
||||
binaries in /usr, binaries that link to libraries in /usr or
|
||||
binaries that refer to data files in /usr. Since these
|
||||
breakages are not always directly visible systemd will warn
|
||||
about this, since this kind of file system setup is not really
|
||||
supported anymore by the basic set of Linux OS components.
|
||||
|
6
TODO
6
TODO
@ -4,17 +4,11 @@ F15:
|
||||
|
||||
* isolate multi-user.target doesn't start a getty@tty1 if we run it from graphical.target
|
||||
|
||||
* when plymouth is disabled the console password entry stuff seems to be borked
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=655538
|
||||
|
||||
* increase password timeout
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=677962
|
||||
|
||||
* finish syslog socket stuff
|
||||
|
||||
* support caching password questions in plymouth and on the console
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=677438
|
||||
|
||||
* load EnvironmentFile= when starting services, not when reloading configuration
|
||||
https://bugzilla.redhat.com/show_bug.cgi?id=661282
|
||||
|
||||
|
@ -32,6 +32,7 @@
|
||||
#include <sys/signalfd.h>
|
||||
|
||||
#include "util.h"
|
||||
#include "strv.h"
|
||||
|
||||
#include "ask-password-api.h"
|
||||
|
||||
@ -251,12 +252,12 @@ fail:
|
||||
return r;
|
||||
}
|
||||
|
||||
|
||||
int ask_password_agent(
|
||||
const char *message,
|
||||
const char *icon,
|
||||
usec_t until,
|
||||
char **_passphrase) {
|
||||
bool accept_cached,
|
||||
char ***_passphrases) {
|
||||
|
||||
enum {
|
||||
FD_SOCKET,
|
||||
@ -273,6 +274,8 @@ int ask_password_agent(
|
||||
sigset_t mask;
|
||||
struct pollfd pollfd[_FD_MAX];
|
||||
|
||||
assert(_passphrases);
|
||||
|
||||
mkdir_p("/dev/.systemd/ask-password", 0755);
|
||||
|
||||
if ((fd = mkostemp(temp, O_CLOEXEC|O_CREAT|O_WRONLY)) < 0) {
|
||||
@ -310,9 +313,11 @@ int ask_password_agent(
|
||||
"[Ask]\n"
|
||||
"PID=%lu\n"
|
||||
"Socket=%s\n"
|
||||
"AcceptCached=%i\n"
|
||||
"NotAfter=%llu\n",
|
||||
(unsigned long) getpid(),
|
||||
socket_name,
|
||||
accept_cached ? 1 : 0,
|
||||
(unsigned long long) until);
|
||||
|
||||
if (message)
|
||||
@ -384,8 +389,10 @@ int ask_password_agent(
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (pollfd[FD_SIGNAL].revents & POLLIN)
|
||||
break;
|
||||
if (pollfd[FD_SIGNAL].revents & POLLIN) {
|
||||
r = -EINTR;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (pollfd[FD_SOCKET].revents != POLLIN) {
|
||||
log_error("Unexpected poll() event.");
|
||||
@ -395,7 +402,7 @@ int ask_password_agent(
|
||||
|
||||
zero(iovec);
|
||||
iovec.iov_base = passphrase;
|
||||
iovec.iov_len = sizeof(passphrase)-1;
|
||||
iovec.iov_len = sizeof(passphrase);
|
||||
|
||||
zero(control);
|
||||
zero(msghdr);
|
||||
@ -435,13 +442,21 @@ int ask_password_agent(
|
||||
}
|
||||
|
||||
if (passphrase[0] == '+') {
|
||||
passphrase[n] = 0;
|
||||
char **l;
|
||||
|
||||
if (!(*_passphrase = strdup(passphrase+1))) {
|
||||
if (!(l = strv_parse_nulstr(passphrase+1, n-1))) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (strv_length(l) <= 0) {
|
||||
strv_free(l);
|
||||
log_error("Invalid packet");
|
||||
continue;
|
||||
}
|
||||
|
||||
*_passphrases = l;
|
||||
|
||||
} else if (passphrase[0] == '-') {
|
||||
r = -ECANCELED;
|
||||
goto finish;
|
||||
@ -481,12 +496,26 @@ finish:
|
||||
return r;
|
||||
}
|
||||
|
||||
int ask_password_auto(const char *message, const char *icon, usec_t until, char **_passphrase) {
|
||||
int ask_password_auto(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases) {
|
||||
assert(message);
|
||||
assert(_passphrase);
|
||||
assert(_passphrases);
|
||||
|
||||
if (isatty(STDIN_FILENO))
|
||||
return ask_password_tty(message, until, NULL, _passphrase);
|
||||
else
|
||||
return ask_password_agent(message, icon, until, _passphrase);
|
||||
if (isatty(STDIN_FILENO)) {
|
||||
int r;
|
||||
char *s = NULL, **l = NULL;
|
||||
|
||||
if ((r = ask_password_tty(message, until, NULL, &s)) < 0)
|
||||
return r;
|
||||
|
||||
l = strv_new(s, NULL);
|
||||
free(s);
|
||||
|
||||
if (!l)
|
||||
return -ENOMEM;
|
||||
|
||||
*_passphrases = l;
|
||||
return r;
|
||||
|
||||
} else
|
||||
return ask_password_agent(message, icon, until, accept_cached, _passphrases);
|
||||
}
|
||||
|
@ -26,8 +26,8 @@
|
||||
|
||||
int ask_password_tty(const char *message, usec_t until, const char *flag_file, char **_passphrase);
|
||||
|
||||
int ask_password_agent(const char *message, const char *icon, usec_t until, char **_passphrase);
|
||||
int ask_password_agent(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases);
|
||||
|
||||
int ask_password_auto(const char *message, const char *icon, usec_t until, char **_passphrase);
|
||||
int ask_password_auto(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases);
|
||||
|
||||
#endif
|
||||
|
@ -38,21 +38,26 @@
|
||||
#include "log.h"
|
||||
#include "macro.h"
|
||||
#include "util.h"
|
||||
#include "strv.h"
|
||||
#include "ask-password-api.h"
|
||||
|
||||
static const char *arg_icon = NULL;
|
||||
static const char *arg_message = NULL;
|
||||
static bool arg_use_tty = true;
|
||||
static usec_t arg_timeout = 60 * USEC_PER_SEC;
|
||||
static bool arg_accept_cached = false;
|
||||
static bool arg_multiple = false;
|
||||
|
||||
static int help(void) {
|
||||
|
||||
printf("%s [OPTIONS...] MESSAGE\n\n"
|
||||
"Query the user for a system passphrase, via the TTY or an UI agent.\n\n"
|
||||
" -h --help Show this help\n"
|
||||
" --icon=NAME Icon name\n"
|
||||
" --timeout=SEC Timeout in sec\n"
|
||||
" --no-tty Ask question via agent even on TTY\n",
|
||||
" -h --help Show this help\n"
|
||||
" --icon=NAME Icon name\n"
|
||||
" --timeout=SEC Timeout in sec\n"
|
||||
" --no-tty Ask question via agent even on TTY\n"
|
||||
" --accept-cached Accept cached passwords\n"
|
||||
" --multiple List multiple passwords if available\n",
|
||||
program_invocation_short_name);
|
||||
|
||||
return 0;
|
||||
@ -63,15 +68,19 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
enum {
|
||||
ARG_ICON = 0x100,
|
||||
ARG_TIMEOUT,
|
||||
ARG_NO_TTY
|
||||
ARG_NO_TTY,
|
||||
ARG_ACCEPT_CACHED,
|
||||
ARG_MULTIPLE
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "icon", required_argument, NULL, ARG_ICON },
|
||||
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
|
||||
{ "no-tty", no_argument, NULL, ARG_NO_TTY },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "icon", required_argument, NULL, ARG_ICON },
|
||||
{ "timeout", required_argument, NULL, ARG_TIMEOUT },
|
||||
{ "no-tty", no_argument, NULL, ARG_NO_TTY },
|
||||
{ "accept-cached", no_argument, NULL, ARG_ACCEPT_CACHED },
|
||||
{ "multiple", no_argument, NULL, ARG_MULTIPLE },
|
||||
{ NULL, 0, NULL, 0 }
|
||||
};
|
||||
|
||||
int c;
|
||||
@ -102,6 +111,14 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
arg_use_tty = false;
|
||||
break;
|
||||
|
||||
case ARG_ACCEPT_CACHED:
|
||||
arg_accept_cached = true;
|
||||
break;
|
||||
|
||||
case ARG_MULTIPLE:
|
||||
arg_multiple = true;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@ -122,7 +139,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
int r;
|
||||
char *password = NULL;
|
||||
|
||||
log_parse_environment();
|
||||
log_open();
|
||||
@ -130,18 +146,32 @@ int main(int argc, char *argv[]) {
|
||||
if ((r = parse_argv(argc, argv)) <= 0)
|
||||
goto finish;
|
||||
|
||||
if (arg_use_tty && isatty(STDIN_FILENO))
|
||||
r = ask_password_tty(arg_message, now(CLOCK_MONOTONIC) + arg_timeout, NULL, &password);
|
||||
else
|
||||
r = ask_password_agent(arg_message, arg_icon, now(CLOCK_MONOTONIC) + arg_timeout, &password);
|
||||
if (arg_use_tty && isatty(STDIN_FILENO)) {
|
||||
char *password = NULL;
|
||||
|
||||
if (r >= 0) {
|
||||
fputs(password, stdout);
|
||||
fflush(stdout);
|
||||
if ((r = ask_password_tty(arg_message, now(CLOCK_MONOTONIC) + arg_timeout, NULL, &password)) >= 0) {
|
||||
puts(password);
|
||||
free(password);
|
||||
}
|
||||
|
||||
} else {
|
||||
char **l;
|
||||
|
||||
if ((r = ask_password_agent(arg_message, arg_icon, now(CLOCK_MONOTONIC) + arg_timeout, arg_accept_cached, &l)) >= 0) {
|
||||
char **p;
|
||||
|
||||
STRV_FOREACH(p, l) {
|
||||
puts(*p);
|
||||
|
||||
if (!arg_multiple)
|
||||
break;
|
||||
}
|
||||
|
||||
strv_free(l);
|
||||
}
|
||||
}
|
||||
|
||||
finish:
|
||||
free(password);
|
||||
|
||||
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
|
||||
#include "log.h"
|
||||
#include "util.h"
|
||||
#include "strv.h"
|
||||
#include "ask-password-api.h"
|
||||
|
||||
static const char *opt_type = NULL; /* LUKS1 or PLAIN */
|
||||
@ -179,7 +180,7 @@ finish:
|
||||
int main(int argc, char *argv[]) {
|
||||
int r = EXIT_FAILURE;
|
||||
struct crypt_device *cd = NULL;
|
||||
char *password = NULL, *truncated_cipher = NULL;
|
||||
char **passwords = NULL, *truncated_cipher = NULL;
|
||||
const char *cipher = NULL, *cipher_mode = NULL, *hash = NULL, *name = NULL;
|
||||
char *description = NULL;
|
||||
|
||||
@ -268,18 +269,19 @@ int main(int argc, char *argv[]) {
|
||||
for (try = 0; try < opt_tries; try++) {
|
||||
bool pass_volume_key = false;
|
||||
|
||||
free(password);
|
||||
password = NULL;
|
||||
strv_free(passwords);
|
||||
passwords = NULL;
|
||||
|
||||
if (!key_file) {
|
||||
char *text;
|
||||
char **p;
|
||||
|
||||
if (asprintf(&text, "Please enter passphrase for disk %s!", name) < 0) {
|
||||
log_error("Out of memory");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
k = ask_password_auto(text, "drive-harddisk", until, &password);
|
||||
k = ask_password_auto(text, "drive-harddisk", until, try == 0 && !opt_verify, &passwords);
|
||||
free(text);
|
||||
|
||||
if (k < 0) {
|
||||
@ -288,14 +290,16 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
if (opt_verify) {
|
||||
char *password2 = NULL;
|
||||
char **passwords2 = NULL;
|
||||
|
||||
assert(strv_length(passwords) == 1);
|
||||
|
||||
if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0) {
|
||||
log_error("Out of memory");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
k = ask_password_auto(text, "drive-harddisk", until, &password2);
|
||||
k = ask_password_auto(text, "drive-harddisk", until, false, &passwords2);
|
||||
free(text);
|
||||
|
||||
if (k < 0) {
|
||||
@ -303,28 +307,32 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (!streq(password, password2)) {
|
||||
assert(strv_length(passwords2) == 1);
|
||||
|
||||
if (!streq(passwords[0], passwords2[0])) {
|
||||
log_warning("Passwords did not match, retrying.");
|
||||
free(password2);
|
||||
strv_free(passwords2);
|
||||
continue;
|
||||
}
|
||||
|
||||
free(password2);
|
||||
strv_free(passwords2);
|
||||
}
|
||||
|
||||
if (strlen(password)+1 < opt_key_size) {
|
||||
STRV_FOREACH(p, passwords) {
|
||||
char *c;
|
||||
|
||||
/* Pad password if necessary */
|
||||
if (strlen(*p)+1 >= opt_key_size)
|
||||
continue;
|
||||
|
||||
/* Pad password if necessary */
|
||||
if (!(c = new(char, opt_key_size))) {
|
||||
log_error("Out of memory.");
|
||||
goto finish;
|
||||
}
|
||||
|
||||
strncpy(c, password, opt_key_size);
|
||||
free(password);
|
||||
password = c;
|
||||
strncpy(c, *p, opt_key_size);
|
||||
free(*p);
|
||||
*p = c;
|
||||
}
|
||||
}
|
||||
|
||||
@ -367,10 +375,20 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
if (key_file)
|
||||
k = crypt_activate_by_keyfile(cd, argv[2], CRYPT_ANY_SLOT, key_file, opt_key_size, flags);
|
||||
else if (pass_volume_key)
|
||||
k = crypt_activate_by_volume_key(cd, argv[2], password, opt_key_size, flags);
|
||||
else
|
||||
k = crypt_activate_by_passphrase(cd, argv[2], CRYPT_ANY_SLOT, password, strlen(password), flags);
|
||||
else {
|
||||
char **p;
|
||||
|
||||
STRV_FOREACH(p, passwords) {
|
||||
|
||||
if (pass_volume_key)
|
||||
k = crypt_activate_by_volume_key(cd, argv[2], *p, opt_key_size, flags);
|
||||
else
|
||||
k = crypt_activate_by_passphrase(cd, argv[2], CRYPT_ANY_SLOT, *p, strlen(*p), flags);
|
||||
|
||||
if (k >= 0)
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (k >= 0)
|
||||
break;
|
||||
@ -421,7 +439,7 @@ finish:
|
||||
|
||||
free(truncated_cipher);
|
||||
|
||||
free(password);
|
||||
strv_free(passwords);
|
||||
|
||||
free(description);
|
||||
|
||||
|
42
src/strv.c
42
src/strv.c
@ -577,3 +577,45 @@ char **strv_env_clean(char **l) {
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
char **strv_parse_nulstr(const char *s, size_t l) {
|
||||
const char *p;
|
||||
unsigned c = 0, i = 0;
|
||||
char **v;
|
||||
|
||||
assert(s || l <= 0);
|
||||
|
||||
if (l <= 0)
|
||||
return strv_new(NULL, NULL);
|
||||
|
||||
for (p = s; p < s + l; p++)
|
||||
if (*p == 0)
|
||||
c++;
|
||||
|
||||
if (s[l-1] != 0)
|
||||
c++;
|
||||
|
||||
if (!(v = new0(char*, c+1)))
|
||||
return NULL;
|
||||
|
||||
p = s;
|
||||
while (p < s + l) {
|
||||
const char *e;
|
||||
|
||||
e = memchr(p, 0, s + l - p);
|
||||
|
||||
if (!(v[i++] = strndup(p, e ? e - p : s + l - p))) {
|
||||
strv_free(v);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (!e)
|
||||
break;
|
||||
|
||||
p = e + 1;
|
||||
}
|
||||
|
||||
assert(i == c);
|
||||
|
||||
return v;
|
||||
}
|
||||
|
@ -65,6 +65,8 @@ char *strv_env_get(char **x, const char *n);
|
||||
|
||||
char **strv_env_clean(char **l);
|
||||
|
||||
char **strv_parse_nulstr(const char *s, size_t l);
|
||||
|
||||
#define STRV_FOREACH(s, l) \
|
||||
for ((s) = (l); (s) && *(s); (s)++)
|
||||
|
||||
|
@ -48,6 +48,14 @@ int main(int argc, char *argv[]) {
|
||||
};
|
||||
|
||||
char **i, **r, *t, **a, **b;
|
||||
const char nulstr[] = "fuck\0fuck2\0fuck3\0\0fuck5\0\0xxx";
|
||||
|
||||
a = strv_parse_nulstr(nulstr, sizeof(nulstr)-1);
|
||||
|
||||
STRV_FOREACH(i, a)
|
||||
printf("nulstr--%s\n", *i);
|
||||
|
||||
strv_free(a);
|
||||
|
||||
r = replace_env_argv((char**) line, (char**) env);
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
||||
#include "utmp-wtmp.h"
|
||||
#include "socket-util.h"
|
||||
#include "ask-password-api.h"
|
||||
#include "strv.h"
|
||||
|
||||
static enum {
|
||||
ACTION_LIST,
|
||||
@ -48,7 +49,13 @@ static enum {
|
||||
static bool arg_plymouth = false;
|
||||
static bool arg_console = false;
|
||||
|
||||
static int ask_password_plymouth(const char *message, usec_t until, const char *flag_file, char **_passphrase) {
|
||||
static int ask_password_plymouth(
|
||||
const char *message,
|
||||
usec_t until,
|
||||
const char *flag_file,
|
||||
bool accept_cached,
|
||||
char ***_passphrases) {
|
||||
|
||||
int fd = -1, notify = -1;
|
||||
union sockaddr_union sa;
|
||||
char *packet = NULL;
|
||||
@ -62,6 +69,8 @@ static int ask_password_plymouth(const char *message, usec_t until, const char *
|
||||
POLL_INOTIFY
|
||||
};
|
||||
|
||||
assert(_passphrases);
|
||||
|
||||
if (flag_file) {
|
||||
if ((notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK)) < 0) {
|
||||
r = -errno;
|
||||
@ -88,7 +97,13 @@ static int ask_password_plymouth(const char *message, usec_t until, const char *
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) {
|
||||
if (accept_cached) {
|
||||
packet = strdup("c");
|
||||
n = 1;
|
||||
} else
|
||||
asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n);
|
||||
|
||||
if (!packet) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
@ -155,15 +170,38 @@ static int ask_password_plymouth(const char *message, usec_t until, const char *
|
||||
continue;
|
||||
|
||||
if (buffer[0] == 5) {
|
||||
|
||||
if (accept_cached) {
|
||||
/* Hmm, first try with cached
|
||||
* passwords failed, so let's retry
|
||||
* with a normal password request */
|
||||
free(packet);
|
||||
packet = NULL;
|
||||
|
||||
if (asprintf(&packet, "*\002%c%s%n", (int) (strlen(message) + 1), message, &n) < 0) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if ((k = loop_write(fd, packet, n+1, true)) != n+1) {
|
||||
r = k < 0 ? (int) k : -EIO;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
accept_cached = false;
|
||||
p = 0;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* No password, because UI not shown */
|
||||
r = -ENOENT;
|
||||
goto finish;
|
||||
|
||||
} else if (buffer[0] == 2) {
|
||||
} else if (buffer[0] == 2 || buffer[0] == 9) {
|
||||
uint32_t size;
|
||||
char *s;
|
||||
char **l;
|
||||
|
||||
/* One answer */
|
||||
/* One ore more answers */
|
||||
if (p < 5)
|
||||
continue;
|
||||
|
||||
@ -176,13 +214,14 @@ static int ask_password_plymouth(const char *message, usec_t until, const char *
|
||||
if (p-5 < size)
|
||||
continue;
|
||||
|
||||
if (!(s = strndup(buffer + 5, size))) {
|
||||
if (!(l = strv_parse_nulstr(buffer + 5, size))) {
|
||||
r = -ENOMEM;
|
||||
goto finish;
|
||||
}
|
||||
|
||||
*_passphrase = s;
|
||||
*_passphrases = l;
|
||||
break;
|
||||
|
||||
} else {
|
||||
/* Unknown packet */
|
||||
r = -EIO;
|
||||
@ -209,12 +248,14 @@ static int parse_password(const char *filename, char **wall) {
|
||||
uint64_t not_after = 0;
|
||||
unsigned pid = 0;
|
||||
int socket_fd = -1;
|
||||
bool accept_cached = false;
|
||||
|
||||
const ConfigItem items[] = {
|
||||
{ "Socket", config_parse_string, &socket_name, "Ask" },
|
||||
{ "NotAfter", config_parse_uint64, ¬_after, "Ask" },
|
||||
{ "Message", config_parse_string, &message, "Ask" },
|
||||
{ "PID", config_parse_unsigned, &pid, "Ask" },
|
||||
{ "Socket", config_parse_string, &socket_name, "Ask" },
|
||||
{ "NotAfter", config_parse_uint64, ¬_after, "Ask" },
|
||||
{ "Message", config_parse_string, &message, "Ask" },
|
||||
{ "PID", config_parse_unsigned, &pid, "Ask" },
|
||||
{ "AcceptCached", config_parse_bool, &accept_cached, "Ask" },
|
||||
{ NULL, NULL, NULL, NULL }
|
||||
};
|
||||
|
||||
@ -274,7 +315,7 @@ static int parse_password(const char *filename, char **wall) {
|
||||
struct sockaddr sa;
|
||||
struct sockaddr_un un;
|
||||
} sa;
|
||||
char *password;
|
||||
size_t packet_length;
|
||||
|
||||
assert(arg_action == ACTION_QUERY ||
|
||||
arg_action == ACTION_WATCH);
|
||||
@ -288,10 +329,32 @@ static int parse_password(const char *filename, char **wall) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
if (arg_plymouth)
|
||||
r = ask_password_plymouth(message, not_after, filename, &password);
|
||||
else {
|
||||
if (arg_plymouth) {
|
||||
char **passwords;
|
||||
|
||||
if ((r = ask_password_plymouth(message, not_after, filename, accept_cached, &passwords)) >= 0) {
|
||||
char **p;
|
||||
|
||||
packet_length = 1;
|
||||
STRV_FOREACH(p, passwords)
|
||||
packet_length += strlen(*p) + 1;
|
||||
|
||||
if (!(packet = new(char, packet_length)))
|
||||
r = -ENOMEM;
|
||||
else {
|
||||
char *d;
|
||||
|
||||
packet[0] = '+';
|
||||
d = packet+1;
|
||||
|
||||
STRV_FOREACH(p, passwords)
|
||||
d = stpcpy(d, *p) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
} else {
|
||||
int tty_fd = -1;
|
||||
char *password;
|
||||
|
||||
if (arg_console)
|
||||
if ((tty_fd = acquire_terminal("/dev/console", false, false, false)) < 0) {
|
||||
@ -305,6 +368,11 @@ static int parse_password(const char *filename, char **wall) {
|
||||
close_nointr_nofail(tty_fd);
|
||||
release_terminal();
|
||||
}
|
||||
|
||||
asprintf(&packet, "+%s", password);
|
||||
free(password);
|
||||
|
||||
packet_length = strlen(packet);
|
||||
}
|
||||
|
||||
if (r < 0) {
|
||||
@ -312,9 +380,6 @@ static int parse_password(const char *filename, char **wall) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
asprintf(&packet, "+%s", password);
|
||||
free(password);
|
||||
|
||||
if (!packet) {
|
||||
log_error("Out of memory");
|
||||
r = -ENOMEM;
|
||||
@ -331,7 +396,7 @@ static int parse_password(const char *filename, char **wall) {
|
||||
sa.un.sun_family = AF_UNIX;
|
||||
strncpy(sa.un.sun_path, socket_name, sizeof(sa.un.sun_path));
|
||||
|
||||
if (sendto(socket_fd, packet, strlen(packet), MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0) {
|
||||
if (sendto(socket_fd, packet, packet_length, MSG_NOSIGNAL, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(socket_name)) < 0) {
|
||||
log_error("Failed to send: %m");
|
||||
r = -errno;
|
||||
goto finish;
|
||||
|
Loading…
x
Reference in New Issue
Block a user