X-Git-Url: https://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fask-password.c;h=1d89eafa97b30f23f91a831d25958e3cd2623a8a;hb=8e9b7dd86b26e1fdfedcee221ec5537c18ca5d0c;hp=22dda974c5fac62e33c172cb11aaf98e804dd127;hpb=ad6ab0af1ed38e342aeeae1c5f7c1503fab11935;p=elogind.git diff --git a/src/ask-password.c b/src/ask-password.c index 22dda974c..1d89eafa9 100644 --- a/src/ask-password.c +++ b/src/ask-password.c @@ -33,6 +33,7 @@ #include #include #include +#include #include "log.h" #include "macro.h" @@ -61,9 +62,9 @@ static int create_socket(char **name) { zero(sa); sa.un.sun_family = AF_UNIX; - snprintf(sa.un.sun_path+1, sizeof(sa.un.sun_path)-1, "/org/freedesktop/systemd1/ask-password/%llu", random_ull()); + snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/dev/.systemd/ask-password/sck.%llu", random_ull()); - if (bind(fd, &sa.sa, sizeof(sa_family_t) + 1 + strlen(sa.un.sun_path+1)) < 0) { + if (bind(fd, &sa.sa, offsetof(struct sockaddr_un, sun_path) + strlen(sa.un.sun_path)) < 0) { r = -errno; log_error("bind() failed: %m"); goto fail; @@ -75,7 +76,7 @@ static int create_socket(char **name) { goto fail; } - if (!(c = strdup(sa.un.sun_path+1))) { + if (!(c = strdup(sa.un.sun_path))) { r = -ENOMEM; log_error("Out of memory"); goto fail; @@ -96,7 +97,7 @@ static int help(void) { "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=USEC Timeout in usec\n" + " --timeout=SEC Timeout in sec\n" " --no-tty Ask question via agent even on TTY\n", program_invocation_short_name); @@ -166,14 +167,23 @@ static int parse_argv(int argc, char *argv[]) { } static int ask_agent(void) { + enum { + FD_SOCKET, + FD_SIGNAL, + _FD_MAX + }; + char temp[] = "/dev/.systemd/ask-password/tmp.XXXXXX"; char final[sizeof(temp)] = ""; int fd = -1, r; FILE *f = NULL; char *socket_name = NULL; - int socket_fd, signal_fd; + int socket_fd = -1, signal_fd = -1; sigset_t mask; usec_t not_after; + struct pollfd pollfd[_FD_MAX]; + + mkdir_p("/dev/.systemd/ask-password", 0755); if ((fd = mkostemp(temp, O_CLOEXEC|O_CREAT|O_WRONLY)) < 0) { log_error("Failed to create password file: %m"); @@ -210,8 +220,10 @@ static int ask_agent(void) { fprintf(f, "[Ask]\n" + "PID=%lu\n" "Socket=%s\n" "NotAfter=%llu\n", + (unsigned long) getpid(), socket_name, (unsigned long long) not_after); @@ -241,13 +253,13 @@ static int ask_agent(void) { goto finish; } - for (;;) { - enum { - FD_SOCKET, - FD_SIGNAL, - _FD_MAX - }; + zero(pollfd); + pollfd[FD_SOCKET].fd = socket_fd; + pollfd[FD_SOCKET].events = POLLIN; + pollfd[FD_SIGNAL].fd = signal_fd; + pollfd[FD_SIGNAL].events = POLLIN; + for (;;) { char passphrase[LINE_MAX+1]; struct msghdr msghdr; struct iovec iovec; @@ -257,16 +269,9 @@ static int ask_agent(void) { uint8_t buf[CMSG_SPACE(sizeof(struct ucred))]; } control; ssize_t n; - struct pollfd pollfd[_FD_MAX]; int k; - zero(pollfd); - pollfd[FD_SOCKET].fd = socket_fd; - pollfd[FD_SOCKET].events = POLLIN; - pollfd[FD_SIGNAL].fd = signal_fd; - pollfd[FD_SIGNAL].events = POLLIN; - - if ((k = poll(pollfd, 2, arg_timeout/USEC_PER_MSEC)) < 0) { + if ((k = poll(pollfd, _FD_MAX, arg_timeout/USEC_PER_MSEC)) < 0) { if (errno == EINTR) continue; @@ -353,9 +358,17 @@ finish: if (fd >= 0) close_nointr_nofail(fd); + if (socket_name) { + unlink(socket_name); + free(socket_name); + } + if (socket_fd >= 0) close_nointr_nofail(socket_fd); + if (signal_fd >= 0) + close_nointr_nofail(signal_fd); + if (f) fclose(f); @@ -367,89 +380,6 @@ finish: return r; } -static int ask_tty(void) { - struct termios old_termios, new_termios; - char passphrase[LINE_MAX]; - FILE *ttyf; - - if (!(ttyf = fopen("/dev/tty", "w"))) { - log_error("Failed to open /dev/tty: %m"); - return -errno; - } - - fputs("\x1B[1m", ttyf); - fprintf(ttyf, "%s: ", arg_message); - fputs("\x1B[0m", ttyf); - fflush(ttyf); - - if (tcgetattr(STDIN_FILENO, &old_termios) >= 0) { - - new_termios = old_termios; - - new_termios.c_lflag &= ~(ICANON|ECHO); - new_termios.c_cc[VMIN] = 1; - new_termios.c_cc[VTIME] = 0; - - if (tcsetattr(STDIN_FILENO, TCSADRAIN, &new_termios) >= 0) { - size_t p = 0; - int r = 0; - - for (;;) { - size_t k; - char c; - - k = fread(&c, 1, 1, stdin); - - if (k <= 0) { - r = -EIO; - break; - } - - if (c == '\n') - break; - else if (c == '\b' || c == 127) { - if (p > 0) { - p--; - fputs("\b \b", ttyf); - } - } else { - passphrase[p++] = c; - fputc('*', ttyf); - } - - fflush(ttyf); - } - - fputc('\n', ttyf); - fclose(ttyf); - tcsetattr(STDIN_FILENO, TCSADRAIN, &old_termios); - - if (r < 0) - return -EIO; - - passphrase[p] = 0; - - fputs(passphrase, stdout); - fflush(stdout); - return 0; - } - - } - - fclose(ttyf); - - if (!fgets(passphrase, sizeof(passphrase), stdin)) { - log_error("Failed to read password."); - return -EIO; - } - - truncate_nl(passphrase); - fputs(passphrase, stdout); - fflush(stdout); - - return 0; -} - int main(int argc, char *argv[]) { int r; @@ -459,9 +389,16 @@ int main(int argc, char *argv[]) { if ((r = parse_argv(argc, argv)) <= 0) goto finish; - if (arg_use_tty && isatty(STDIN_FILENO)) - r = ask_tty(); - else + if (arg_use_tty && isatty(STDIN_FILENO)) { + char *password = NULL; + + if ((r = ask_password_tty(arg_message, now(CLOCK_MONOTONIC) + arg_timeout, NULL, &password)) >= 0) { + fputs(password, stdout); + fflush(stdout); + free(password); + } + + } else r = ask_agent(); finish: