X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=blobdiff_plain;f=src%2Fask-password-api.c;h=dd54fb6abf22a0680f0849b67fd31f138a5a180a;hb=c0f9c7da07fccafed646e0a15df9bc132e3fc7fb;hp=e4ee8adb4f51aa3a3bcf8c03a94a0dc440f24673;hpb=bd1db33fb9ef740272fa4bcbdb034b134ea5e911;p=elogind.git diff --git a/src/ask-password-api.c b/src/ask-password-api.c index e4ee8adb4..dd54fb6ab 100644 --- a/src/ask-password-api.c +++ b/src/ask-password-api.c @@ -32,6 +32,7 @@ #include #include "util.h" +#include "strv.h" #include "ask-password-api.h" @@ -110,7 +111,7 @@ int ask_password_tty( y = now(CLOCK_MONOTONIC); if (y > until) { - r = -ETIMEDOUT; + r = -ETIME; goto finish; } @@ -131,7 +132,7 @@ int ask_password_tty( r = -errno; goto finish; } else if (k == 0) { - r = -ETIMEDOUT; + r = -ETIME; goto finish; } @@ -179,7 +180,6 @@ int ask_password_tty( } if (ttyfd >= 0) - loop_write(ttyfd, "\n", 1, false); passphrase[p] = 0; @@ -195,8 +195,11 @@ finish: close_nointr_nofail(notify); if (ttyfd >= 0) { - if (reset_tty) + + if (reset_tty) { + loop_write(ttyfd, "\n", 1, false); tcsetattr(ttyfd, TCSADRAIN, &old_termios); + } close_nointr_nofail(ttyfd); } @@ -251,12 +254,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 +276,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 +315,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) @@ -368,7 +375,7 @@ int ask_password_agent( goto finish; } - if ((k = poll(pollfd, _FD_MAX, until-t/USEC_PER_MSEC)) < 0) { + if ((k = poll(pollfd, _FD_MAX, (until-t)/USEC_PER_MSEC)) < 0) { if (errno == EINTR) continue; @@ -384,8 +391,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 +404,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 +444,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; @@ -480,3 +497,27 @@ finish: return r; } + +int ask_password_auto(const char *message, const char *icon, usec_t until, bool accept_cached, char ***_passphrases) { + assert(message); + assert(_passphrases); + + 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); +}