]> git.ipfire.org Git - thirdparty/systemd.git/blame - src/shared/ask-password-api.c
Add SPDX license identifiers to source files under the LGPL
[thirdparty/systemd.git] / src / shared / ask-password-api.c
CommitLineData
53e1b683 1/* SPDX-License-Identifier: LGPL-2.1+ */
7f4e0805
LP
2/***
3 This file is part of systemd.
4
5 Copyright 2010 Lennart Poettering
6
7 systemd is free software; you can redistribute it and/or modify it
5430f7f2
LP
8 under the terms of the GNU Lesser General Public License as published by
9 the Free Software Foundation; either version 2.1 of the License, or
7f4e0805
LP
10 (at your option) any later version.
11
12 systemd is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
5430f7f2 15 Lesser General Public License for more details.
7f4e0805 16
5430f7f2 17 You should have received a copy of the GNU Lesser General Public License
7f4e0805
LP
18 along with systemd; If not, see <http://www.gnu.org/licenses/>.
19***/
00843602 20
7f4e0805
LP
21#include <errno.h>
22#include <fcntl.h>
a8fbdf54
TA
23#include <inttypes.h>
24#include <limits.h>
00843602 25#include <poll.h>
a8fbdf54 26#include <signal.h>
00843602 27#include <stdbool.h>
7f4e0805 28#include <stddef.h>
a8fbdf54
TA
29#include <stdint.h>
30#include <stdio.h>
31#include <stdlib.h>
00843602
LP
32#include <string.h>
33#include <sys/inotify.h>
7f4e0805 34#include <sys/signalfd.h>
00843602 35#include <sys/socket.h>
a8fbdf54
TA
36#include <sys/stat.h>
37#include <sys/time.h>
38#include <sys/uio.h>
00843602
LP
39#include <sys/un.h>
40#include <termios.h>
41#include <unistd.h>
7f4e0805 42
b5efdb8a 43#include "alloc-util.h"
3ffd4af2
LP
44#include "ask-password-api.h"
45#include "fd-util.h"
0d39fa9c 46#include "fileio.h"
f97b34a6 47#include "format-util.h"
c004493c 48#include "io-util.h"
a8fbdf54
TA
49#include "log.h"
50#include "macro.h"
e287086b 51#include "missing.h"
49e942b2 52#include "mkdir.h"
df0ff127 53#include "process-util.h"
3df3e884 54#include "random-util.h"
24882e06 55#include "signal-util.h"
00843602 56#include "socket-util.h"
07630cea 57#include "string-util.h"
00843602
LP
58#include "strv.h"
59#include "terminal-util.h"
a8fbdf54 60#include "time-util.h"
affb60b1 61#include "umask-util.h"
f3149d57 62#include "utf8.h"
00843602 63#include "util.h"
7f4e0805 64
e287086b
LP
65#define KEYRING_TIMEOUT_USEC ((5 * USEC_PER_MINUTE) / 2)
66
67static int lookup_key(const char *keyname, key_serial_t *ret) {
68 key_serial_t serial;
69
70 assert(keyname);
71 assert(ret);
72
73 serial = request_key("user", keyname, NULL, 0);
74 if (serial == -1)
9c4615fb 75 return negative_errno();
e287086b
LP
76
77 *ret = serial;
78 return 0;
79}
80
81static int retrieve_key(key_serial_t serial, char ***ret) {
82 _cleanup_free_ char *p = NULL;
83 long m = 100, n;
84 char **l;
85
86 assert(ret);
87
88 for (;;) {
89 p = new(char, m);
90 if (!p)
91 return -ENOMEM;
92
93 n = keyctl(KEYCTL_READ, (unsigned long) serial, (unsigned long) p, (unsigned long) m, 0);
94 if (n < 0)
95 return -errno;
96
97 if (n < m)
98 break;
99
2d26d8e0 100 explicit_bzero(p, n);
e287086b
LP
101 free(p);
102 m *= 2;
103 }
104
105 l = strv_parse_nulstr(p, n);
106 if (!l)
107 return -ENOMEM;
108
2d26d8e0 109 explicit_bzero(p, n);
1602b008 110
e287086b
LP
111 *ret = l;
112 return 0;
113}
114
115static int add_to_keyring(const char *keyname, AskPasswordFlags flags, char **passwords) {
ab84f5b9 116 _cleanup_strv_free_erase_ char **l = NULL;
e287086b
LP
117 _cleanup_free_ char *p = NULL;
118 key_serial_t serial;
119 size_t n;
120 int r;
121
122 assert(keyname);
123 assert(passwords);
124
125 if (!(flags & ASK_PASSWORD_PUSH_CACHE))
126 return 0;
127
128 r = lookup_key(keyname, &serial);
129 if (r >= 0) {
130 r = retrieve_key(serial, &l);
131 if (r < 0)
132 return r;
133 } else if (r != -ENOKEY)
134 return r;
135
136 r = strv_extend_strv(&l, passwords, true);
137 if (r <= 0)
138 return r;
139
140 r = strv_make_nulstr(l, &p, &n);
141 if (r < 0)
142 return r;
143
b60df13b 144 serial = add_key("user", keyname, p, n, KEY_SPEC_USER_KEYRING);
2d26d8e0 145 explicit_bzero(p, n);
e287086b
LP
146 if (serial == -1)
147 return -errno;
148
149 if (keyctl(KEYCTL_SET_TIMEOUT,
150 (unsigned long) serial,
151 (unsigned long) DIV_ROUND_UP(KEYRING_TIMEOUT_USEC, USEC_PER_SEC), 0, 0) < 0)
152 log_debug_errno(errno, "Failed to adjust timeout: %m");
153
154 log_debug("Added key to keyring as %" PRIi32 ".", serial);
155
156 return 1;
157}
158
159static int add_to_keyring_and_log(const char *keyname, AskPasswordFlags flags, char **passwords) {
160 int r;
161
162 assert(keyname);
163 assert(passwords);
164
165 r = add_to_keyring(keyname, flags, passwords);
166 if (r < 0)
167 return log_debug_errno(r, "Failed to add password to keyring: %m");
168
169 return 0;
170}
171
172int ask_password_keyring(const char *keyname, AskPasswordFlags flags, char ***ret) {
173
174 key_serial_t serial;
175 int r;
176
177 assert(keyname);
178 assert(ret);
179
180 if (!(flags & ASK_PASSWORD_ACCEPT_CACHED))
181 return -EUNATCH;
182
183 r = lookup_key(keyname, &serial);
184 if (r == -ENOSYS) /* when retrieving the distinction doesn't matter */
185 return -ENOKEY;
186 if (r < 0)
187 return r;
188
189 return retrieve_key(serial, ret);
190}
191
58fc840b
LP
192static void backspace_chars(int ttyfd, size_t p) {
193
194 if (ttyfd < 0)
195 return;
196
197 while (p > 0) {
198 p--;
199
200 loop_write(ttyfd, "\b \b", 3, false);
201 }
202}
203
7f4e0805
LP
204int ask_password_tty(
205 const char *message,
e287086b 206 const char *keyname,
7f4e0805 207 usec_t until,
e287086b 208 AskPasswordFlags flags,
7f4e0805 209 const char *flag_file,
e287086b 210 char **ret) {
7f4e0805
LP
211
212 struct termios old_termios, new_termios;
f3149d57
ZJS
213 char passphrase[LINE_MAX + 1] = {}, *x;
214 size_t p = 0, codepoint = 0;
981e4cd3
LP
215 int r;
216 _cleanup_close_ int ttyfd = -1, notify = -1;
7f4e0805
LP
217 struct pollfd pollfd[2];
218 bool reset_tty = false;
441dfe09 219 bool dirty = false;
7f4e0805
LP
220 enum {
221 POLL_TTY,
222 POLL_INOTIFY
223 };
224
e287086b
LP
225 assert(ret);
226
227 if (flags & ASK_PASSWORD_NO_TTY)
228 return -EUNATCH;
229
230 if (!message)
231 message = "Password:";
7f4e0805
LP
232
233 if (flag_file) {
981e4cd3
LP
234 notify = inotify_init1(IN_CLOEXEC|IN_NONBLOCK);
235 if (notify < 0) {
7f4e0805
LP
236 r = -errno;
237 goto finish;
238 }
239
240 if (inotify_add_watch(notify, flag_file, IN_ATTRIB /* for the link count */) < 0) {
241 r = -errno;
242 goto finish;
243 }
244 }
245
981e4cd3
LP
246 ttyfd = open("/dev/tty", O_RDWR|O_NOCTTY|O_CLOEXEC);
247 if (ttyfd >= 0) {
7f4e0805
LP
248
249 if (tcgetattr(ttyfd, &old_termios) < 0) {
250 r = -errno;
251 goto finish;
252 }
253
7565bb98
LP
254 if (colors_enabled())
255 loop_write(ttyfd, ANSI_HIGHLIGHT, strlen(ANSI_HIGHLIGHT), false);
7f4e0805 256 loop_write(ttyfd, message, strlen(message), false);
bd1db33f 257 loop_write(ttyfd, " ", 1, false);
7565bb98
LP
258 if (colors_enabled())
259 loop_write(ttyfd, ANSI_NORMAL, strlen(ANSI_NORMAL), false);
7f4e0805
LP
260
261 new_termios = old_termios;
262 new_termios.c_lflag &= ~(ICANON|ECHO);
263 new_termios.c_cc[VMIN] = 1;
264 new_termios.c_cc[VTIME] = 0;
265
266 if (tcsetattr(ttyfd, TCSADRAIN, &new_termios) < 0) {
267 r = -errno;
268 goto finish;
269 }
270
271 reset_tty = true;
272 }
273
274 zero(pollfd);
7f4e0805
LP
275 pollfd[POLL_TTY].fd = ttyfd >= 0 ? ttyfd : STDIN_FILENO;
276 pollfd[POLL_TTY].events = POLLIN;
277 pollfd[POLL_INOTIFY].fd = notify;
278 pollfd[POLL_INOTIFY].events = POLLIN;
279
280 for (;;) {
281 char c;
282 int sleep_for = -1, k;
283 ssize_t n;
284
285 if (until > 0) {
286 usec_t y;
287
288 y = now(CLOCK_MONOTONIC);
289
290 if (y > until) {
7ded2e28 291 r = -ETIME;
7f4e0805
LP
292 goto finish;
293 }
294
295 sleep_for = (int) ((until - y) / USEC_PER_MSEC);
296 }
297
298 if (flag_file)
299 if (access(flag_file, F_OK) < 0) {
300 r = -errno;
301 goto finish;
302 }
303
e287086b 304 k = poll(pollfd, notify >= 0 ? 2 : 1, sleep_for);
981e4cd3 305 if (k < 0) {
7f4e0805
LP
306 if (errno == EINTR)
307 continue;
308
309 r = -errno;
310 goto finish;
311 } else if (k == 0) {
ccc80078 312 r = -ETIME;
7f4e0805
LP
313 goto finish;
314 }
315
e287086b 316 if (notify >= 0 && pollfd[POLL_INOTIFY].revents != 0)
7f4e0805
LP
317 flush_fd(notify);
318
319 if (pollfd[POLL_TTY].revents == 0)
320 continue;
321
981e4cd3
LP
322 n = read(ttyfd >= 0 ? ttyfd : STDIN_FILENO, &c, 1);
323 if (n < 0) {
3742095b 324 if (IN_SET(errno, EINTR, EAGAIN))
7f4e0805
LP
325 continue;
326
327 r = -errno;
328 goto finish;
329
330 } else if (n == 0)
331 break;
332
333 if (c == '\n')
334 break;
58fc840b 335 else if (c == 21) { /* C-u */
7f4e0805 336
e287086b 337 if (!(flags & ASK_PASSWORD_SILENT))
58fc840b
LP
338 backspace_chars(ttyfd, p);
339 p = 0;
7f4e0805 340
4c701096 341 } else if (IN_SET(c, '\b', 127)) {
58fc840b
LP
342
343 if (p > 0) {
344
e287086b 345 if (!(flags & ASK_PASSWORD_SILENT))
58fc840b
LP
346 backspace_chars(ttyfd, 1);
347
7f4e0805 348 p--;
e287086b 349 } else if (!dirty && !(flags & ASK_PASSWORD_SILENT)) {
441dfe09 350
e287086b 351 flags |= ASK_PASSWORD_SILENT;
441dfe09
LP
352
353 /* There are two ways to enter silent
354 * mode. Either by pressing backspace
e287086b
LP
355 * as first key (and only as first
356 * key), or ... */
441dfe09
LP
357 if (ttyfd >= 0)
358 loop_write(ttyfd, "(no echo) ", 10, false);
359
58fc840b
LP
360 } else if (ttyfd >= 0)
361 loop_write(ttyfd, "\a", 1, false);
7f4e0805 362
e287086b 363 } else if (c == '\t' && !(flags & ASK_PASSWORD_SILENT)) {
58fc840b
LP
364
365 backspace_chars(ttyfd, p);
e287086b 366 flags |= ASK_PASSWORD_SILENT;
58fc840b 367
441dfe09
LP
368 /* ... or by pressing TAB at any time. */
369
58fc840b
LP
370 if (ttyfd >= 0)
371 loop_write(ttyfd, "(no echo) ", 10, false);
7f4e0805 372 } else {
036eeac5
LP
373 if (p >= sizeof(passphrase)-1) {
374 loop_write(ttyfd, "\a", 1, false);
375 continue;
376 }
377
7f4e0805
LP
378 passphrase[p++] = c;
379
f3149d57
ZJS
380 if (!(flags & ASK_PASSWORD_SILENT) && ttyfd >= 0) {
381 n = utf8_encoded_valid_unichar(passphrase + codepoint);
382 if (n >= 0) {
383 codepoint = p;
384 loop_write(ttyfd, (flags & ASK_PASSWORD_ECHO) ? &c : "*", 1, false);
385 }
386 }
441dfe09
LP
387
388 dirty = true;
7f4e0805 389 }
1602b008
LP
390
391 c = 'x';
7f4e0805
LP
392 }
393
981e4cd3 394 x = strndup(passphrase, p);
2d26d8e0 395 explicit_bzero(passphrase, p);
981e4cd3 396 if (!x) {
7f4e0805
LP
397 r = -ENOMEM;
398 goto finish;
399 }
400
e287086b
LP
401 if (keyname)
402 (void) add_to_keyring_and_log(keyname, flags, STRV_MAKE(x));
403
404 *ret = x;
7f4e0805
LP
405 r = 0;
406
407finish:
981e4cd3
LP
408 if (ttyfd >= 0 && reset_tty) {
409 loop_write(ttyfd, "\n", 1, false);
410 tcsetattr(ttyfd, TCSADRAIN, &old_termios);
7f4e0805
LP
411 }
412
413 return r;
414}
415
416static int create_socket(char **name) {
00843602 417 union sockaddr_union sa = {
b92bea5d
ZJS
418 .un.sun_family = AF_UNIX,
419 };
00843602
LP
420 _cleanup_close_ int fd = -1;
421 static const int one = 1;
7f4e0805 422 char *c;
00843602 423 int r;
7f4e0805
LP
424
425 assert(name);
426
e62d8c39 427 fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0);
4a62c710 428 if (fd < 0)
00843602 429 return -errno;
7f4e0805 430
9bf3b535 431 snprintf(sa.un.sun_path, sizeof(sa.un.sun_path)-1, "/run/systemd/ask-password/sck.%" PRIx64, random_u64());
7f4e0805 432
5c0d398d 433 RUN_WITH_UMASK(0177) {
fc2fffe7 434 if (bind(fd, &sa.sa, SOCKADDR_UN_LEN(sa.un)) < 0)
00843602 435 return -errno;
5c0d398d 436 }
1d6702e8 437
00843602
LP
438 if (setsockopt(fd, SOL_SOCKET, SO_PASSCRED, &one, sizeof(one)) < 0)
439 return -errno;
7f4e0805 440
e62d8c39 441 c = strdup(sa.un.sun_path);
00843602
LP
442 if (!c)
443 return -ENOMEM;
7f4e0805
LP
444
445 *name = c;
7f4e0805 446
00843602
LP
447 r = fd;
448 fd = -1;
7f4e0805
LP
449
450 return r;
451}
452
7f4e0805
LP
453int ask_password_agent(
454 const char *message,
455 const char *icon,
9fa1de96 456 const char *id,
e287086b 457 const char *keyname,
7f4e0805 458 usec_t until,
e287086b
LP
459 AskPasswordFlags flags,
460 char ***ret) {
7f4e0805
LP
461
462 enum {
463 FD_SOCKET,
464 FD_SIGNAL,
465 _FD_MAX
466 };
467
e287086b 468 _cleanup_close_ int socket_fd = -1, signal_fd = -1, fd = -1;
2b583ce6 469 char temp[] = "/run/systemd/ask-password/tmp.XXXXXX";
7f4e0805 470 char final[sizeof(temp)] = "";
981e4cd3 471 _cleanup_free_ char *socket_name = NULL;
e287086b
LP
472 _cleanup_strv_free_ char **l = NULL;
473 _cleanup_fclose_ FILE *f = NULL;
7f4e0805 474 struct pollfd pollfd[_FD_MAX];
e287086b 475 sigset_t mask, oldmask;
981e4cd3 476 int r;
7f4e0805 477
e287086b 478 assert(ret);
21bc923a 479
e287086b
LP
480 if (flags & ASK_PASSWORD_NO_AGENT)
481 return -EUNATCH;
00843602 482
72c0a2c2
LP
483 assert_se(sigemptyset(&mask) >= 0);
484 assert_se(sigset_add_many(&mask, SIGINT, SIGTERM, -1) >= 0);
485 assert_se(sigprocmask(SIG_BLOCK, &mask, &oldmask) >= 0);
f9b72cd8 486
00843602 487 (void) mkdir_p_label("/run/systemd/ask-password", 0755);
7f4e0805 488
646853bd 489 fd = mkostemp_safe(temp);
1d6702e8 490 if (fd < 0) {
709f6e46 491 r = fd;
7f4e0805
LP
492 goto finish;
493 }
494
00843602 495 (void) fchmod(fd, 0644);
7f4e0805 496
981e4cd3
LP
497 f = fdopen(fd, "w");
498 if (!f) {
00843602 499 r = -errno;
7f4e0805
LP
500 goto finish;
501 }
502
503 fd = -1;
504
981e4cd3
LP
505 signal_fd = signalfd(-1, &mask, SFD_NONBLOCK|SFD_CLOEXEC);
506 if (signal_fd < 0) {
00843602 507 r = -errno;
7f4e0805
LP
508 goto finish;
509 }
510
981e4cd3
LP
511 socket_fd = create_socket(&socket_name);
512 if (socket_fd < 0) {
7f4e0805
LP
513 r = socket_fd;
514 goto finish;
515 }
516
517 fprintf(f,
518 "[Ask]\n"
de0671ee 519 "PID="PID_FMT"\n"
7f4e0805 520 "Socket=%s\n"
21bc923a 521 "AcceptCached=%i\n"
64845bdc 522 "Echo=%i\n"
de0671ee 523 "NotAfter="USEC_FMT"\n",
df0ff127 524 getpid_cached(),
7f4e0805 525 socket_name,
e287086b
LP
526 (flags & ASK_PASSWORD_ACCEPT_CACHED) ? 1 : 0,
527 (flags & ASK_PASSWORD_ECHO) ? 1 : 0,
de0671ee 528 until);
7f4e0805
LP
529
530 if (message)
531 fprintf(f, "Message=%s\n", message);
532
533 if (icon)
534 fprintf(f, "Icon=%s\n", icon);
535
9fa1de96
DH
536 if (id)
537 fprintf(f, "Id=%s\n", id);
538
dacd6cee 539 r = fflush_and_check(f);
00843602 540 if (r < 0)
7f4e0805 541 goto finish;
7f4e0805
LP
542
543 memcpy(final, temp, sizeof(temp));
544
545 final[sizeof(final)-11] = 'a';
546 final[sizeof(final)-10] = 's';
547 final[sizeof(final)-9] = 'k';
548
549 if (rename(temp, final) < 0) {
00843602 550 r = -errno;
7f4e0805
LP
551 goto finish;
552 }
553
554 zero(pollfd);
555 pollfd[FD_SOCKET].fd = socket_fd;
556 pollfd[FD_SOCKET].events = POLLIN;
557 pollfd[FD_SIGNAL].fd = signal_fd;
558 pollfd[FD_SIGNAL].events = POLLIN;
559
560 for (;;) {
561 char passphrase[LINE_MAX+1];
562 struct msghdr msghdr;
563 struct iovec iovec;
564 struct ucred *ucred;
565 union {
566 struct cmsghdr cmsghdr;
567 uint8_t buf[CMSG_SPACE(sizeof(struct ucred))];
568 } control;
569 ssize_t n;
570 int k;
571 usec_t t;
572
573 t = now(CLOCK_MONOTONIC);
574
7dcda352 575 if (until > 0 && until <= t) {
7f4e0805
LP
576 r = -ETIME;
577 goto finish;
578 }
579
981e4cd3
LP
580 k = poll(pollfd, _FD_MAX, until > 0 ? (int) ((until-t)/USEC_PER_MSEC) : -1);
581 if (k < 0) {
7f4e0805
LP
582 if (errno == EINTR)
583 continue;
584
00843602 585 r = -errno;
7f4e0805
LP
586 goto finish;
587 }
588
589 if (k <= 0) {
7f4e0805
LP
590 r = -ETIME;
591 goto finish;
592 }
593
21bc923a
LP
594 if (pollfd[FD_SIGNAL].revents & POLLIN) {
595 r = -EINTR;
596 goto finish;
597 }
7f4e0805
LP
598
599 if (pollfd[FD_SOCKET].revents != POLLIN) {
7f4e0805
LP
600 r = -EIO;
601 goto finish;
602 }
603
604 zero(iovec);
605 iovec.iov_base = passphrase;
21bc923a 606 iovec.iov_len = sizeof(passphrase);
7f4e0805
LP
607
608 zero(control);
609 zero(msghdr);
610 msghdr.msg_iov = &iovec;
611 msghdr.msg_iovlen = 1;
612 msghdr.msg_control = &control;
613 msghdr.msg_controllen = sizeof(control);
614
981e4cd3
LP
615 n = recvmsg(socket_fd, &msghdr, 0);
616 if (n < 0) {
3742095b 617 if (IN_SET(errno, EAGAIN, EINTR))
7f4e0805
LP
618 continue;
619
00843602 620 r = -errno;
7f4e0805
LP
621 goto finish;
622 }
623
1c8da044
LP
624 cmsg_close_all(&msghdr);
625
7f4e0805 626 if (n <= 0) {
00843602 627 log_debug("Message too short");
7f4e0805
LP
628 continue;
629 }
630
631 if (msghdr.msg_controllen < CMSG_LEN(sizeof(struct ucred)) ||
632 control.cmsghdr.cmsg_level != SOL_SOCKET ||
633 control.cmsghdr.cmsg_type != SCM_CREDENTIALS ||
634 control.cmsghdr.cmsg_len != CMSG_LEN(sizeof(struct ucred))) {
00843602 635 log_debug("Received message without credentials. Ignoring.");
7f4e0805
LP
636 continue;
637 }
638
639 ucred = (struct ucred*) CMSG_DATA(&control.cmsghdr);
640 if (ucred->uid != 0) {
00843602 641 log_debug("Got request from unprivileged user. Ignoring.");
7f4e0805
LP
642 continue;
643 }
644
645 if (passphrase[0] == '+') {
e287086b 646 /* An empty message refers to the empty password */
8254a475
LP
647 if (n == 1)
648 l = strv_new("", NULL);
649 else
650 l = strv_parse_nulstr(passphrase+1, n-1);
2d26d8e0 651 explicit_bzero(passphrase, n);
8254a475 652 if (!l) {
7f4e0805
LP
653 r = -ENOMEM;
654 goto finish;
655 }
656
21bc923a 657 if (strv_length(l) <= 0) {
e287086b 658 l = strv_free(l);
00843602 659 log_debug("Invalid packet");
21bc923a
LP
660 continue;
661 }
662
e287086b
LP
663 break;
664 }
21bc923a 665
e287086b 666 if (passphrase[0] == '-') {
7f4e0805
LP
667 r = -ECANCELED;
668 goto finish;
7f4e0805
LP
669 }
670
e287086b 671 log_debug("Invalid packet");
7f4e0805
LP
672 }
673
e287086b
LP
674 if (keyname)
675 (void) add_to_keyring_and_log(keyname, flags, l);
676
677 *ret = l;
678 l = NULL;
7f4e0805
LP
679 r = 0;
680
681finish:
981e4cd3 682 if (socket_name)
00843602 683 (void) unlink(socket_name);
7f4e0805 684
00843602 685 (void) unlink(temp);
7f4e0805
LP
686
687 if (final[0])
00843602 688 (void) unlink(final);
7f4e0805 689
f9b72cd8 690 assert_se(sigprocmask(SIG_SETMASK, &oldmask, NULL) == 0);
7f4e0805
LP
691 return r;
692}
260ab287 693
00843602
LP
694int ask_password_auto(
695 const char *message,
696 const char *icon,
697 const char *id,
e287086b 698 const char *keyname,
00843602 699 usec_t until,
e287086b
LP
700 AskPasswordFlags flags,
701 char ***ret) {
00843602
LP
702
703 int r;
704
e287086b 705 assert(ret);
21bc923a 706
e287086b
LP
707 if ((flags & ASK_PASSWORD_ACCEPT_CACHED) && keyname) {
708 r = ask_password_keyring(keyname, flags, ret);
709 if (r != -ENOKEY)
710 return r;
711 }
712
713 if (!(flags & ASK_PASSWORD_NO_TTY) && isatty(STDIN_FILENO)) {
21bc923a
LP
714 char *s = NULL, **l = NULL;
715
e287086b 716 r = ask_password_tty(message, keyname, until, flags, NULL, &s);
981e4cd3 717 if (r < 0)
21bc923a
LP
718 return r;
719
1602b008
LP
720 r = strv_push(&l, s);
721 if (r < 0) {
722 string_erase(s);
723 free(s);
00843602 724 return -ENOMEM;
1602b008 725 }
21bc923a 726
e287086b 727 *ret = l;
00843602
LP
728 return 0;
729 }
730
e287086b
LP
731 if (!(flags & ASK_PASSWORD_NO_AGENT))
732 return ask_password_agent(message, icon, id, keyname, until, flags, ret);
733
734 return -EUNATCH;
260ab287 735}