summaryrefslogtreecommitdiffstats
path: root/src/ask-password
diff options
context:
space:
mode:
Diffstat (limited to 'src/ask-password')
-rw-r--r--src/ask-password/ask-password.c188
1 files changed, 188 insertions, 0 deletions
diff --git a/src/ask-password/ask-password.c b/src/ask-password/ask-password.c
new file mode 100644
index 0000000..4637c32
--- /dev/null
+++ b/src/ask-password/ask-password.c
@@ -0,0 +1,188 @@
+/* SPDX-License-Identifier: LGPL-2.1+ */
+
+#include <errno.h>
+#include <getopt.h>
+#include <stddef.h>
+#include <unistd.h>
+
+#include "ask-password-api.h"
+#include "def.h"
+#include "log.h"
+#include "macro.h"
+#include "main-func.h"
+#include "pretty-print.h"
+#include "strv.h"
+
+static const char *arg_icon = NULL;
+static const char *arg_id = NULL;
+static const char *arg_keyname = NULL;
+static char *arg_message = NULL;
+static usec_t arg_timeout = DEFAULT_TIMEOUT_USEC;
+static bool arg_multiple = false;
+static bool arg_no_output = false;
+static AskPasswordFlags arg_flags = ASK_PASSWORD_PUSH_CACHE;
+
+STATIC_DESTRUCTOR_REGISTER(arg_message, freep);
+
+static int help(void) {
+ _cleanup_free_ char *link = NULL;
+ int r;
+
+ r = terminal_urlify_man("systemd-ask-password", "1", &link);
+ if (r < 0)
+ return log_oom();
+
+ 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"
+ " --id=ID Query identifier (e.g. \"cryptsetup:/dev/sda5\")\n"
+ " --keyname=NAME Kernel key name for caching passwords (e.g. \"cryptsetup\")\n"
+ " --timeout=SEC Timeout in seconds\n"
+ " --echo Do not mask input (useful for usernames)\n"
+ " --no-tty Ask question via agent even on TTY\n"
+ " --accept-cached Accept cached passwords\n"
+ " --multiple List multiple passwords if available\n"
+ " --no-output Do not print password to standard output\n"
+ "\nSee the %s for details.\n"
+ , program_invocation_short_name
+ , link
+ );
+
+ return 0;
+}
+
+static int parse_argv(int argc, char *argv[]) {
+
+ enum {
+ ARG_ICON = 0x100,
+ ARG_TIMEOUT,
+ ARG_ECHO,
+ ARG_NO_TTY,
+ ARG_ACCEPT_CACHED,
+ ARG_MULTIPLE,
+ ARG_ID,
+ ARG_KEYNAME,
+ ARG_NO_OUTPUT,
+ ARG_VERSION,
+ };
+
+ static const struct option options[] = {
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, ARG_VERSION },
+ { "icon", required_argument, NULL, ARG_ICON },
+ { "timeout", required_argument, NULL, ARG_TIMEOUT },
+ { "echo", no_argument, NULL, ARG_ECHO },
+ { "no-tty", no_argument, NULL, ARG_NO_TTY },
+ { "accept-cached", no_argument, NULL, ARG_ACCEPT_CACHED },
+ { "multiple", no_argument, NULL, ARG_MULTIPLE },
+ { "id", required_argument, NULL, ARG_ID },
+ { "keyname", required_argument, NULL, ARG_KEYNAME },
+ { "no-output", no_argument, NULL, ARG_NO_OUTPUT },
+ {}
+ };
+
+ int c;
+
+ assert(argc >= 0);
+ assert(argv);
+
+ while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0)
+
+ switch (c) {
+
+ case 'h':
+ return help();
+
+ case ARG_VERSION:
+ return version();
+
+ case ARG_ICON:
+ arg_icon = optarg;
+ break;
+
+ case ARG_TIMEOUT:
+ if (parse_sec(optarg, &arg_timeout) < 0)
+ return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
+ "Failed to parse --timeout parameter %s",
+ optarg);
+ break;
+
+ case ARG_ECHO:
+ arg_flags |= ASK_PASSWORD_ECHO;
+ break;
+
+ case ARG_NO_TTY:
+ arg_flags |= ASK_PASSWORD_NO_TTY;
+ break;
+
+ case ARG_ACCEPT_CACHED:
+ arg_flags |= ASK_PASSWORD_ACCEPT_CACHED;
+ break;
+
+ case ARG_MULTIPLE:
+ arg_multiple = true;
+ break;
+
+ case ARG_ID:
+ arg_id = optarg;
+ break;
+
+ case ARG_KEYNAME:
+ arg_keyname = optarg;
+ break;
+
+ case ARG_NO_OUTPUT:
+ arg_no_output = true;
+ break;
+
+ case '?':
+ return -EINVAL;
+
+ default:
+ assert_not_reached("Unhandled option");
+ }
+
+ if (argc > optind) {
+ arg_message = strv_join(argv + optind, " ");
+ if (!arg_message)
+ return log_oom();
+ }
+
+ return 1;
+}
+
+static int run(int argc, char *argv[]) {
+ _cleanup_strv_free_erase_ char **l = NULL;
+ usec_t timeout;
+ char **p;
+ int r;
+
+ log_parse_environment();
+ log_open();
+
+ r = parse_argv(argc, argv);
+ if (r <= 0)
+ return r;
+
+ if (arg_timeout > 0)
+ timeout = now(CLOCK_MONOTONIC) + arg_timeout;
+ else
+ timeout = 0;
+
+ r = ask_password_auto(arg_message, arg_icon, arg_id, arg_keyname, timeout, arg_flags, &l);
+ if (r < 0)
+ return log_error_errno(r, "Failed to query password: %m");
+
+ STRV_FOREACH(p, l) {
+ if (!arg_no_output)
+ puts(*p);
+
+ if (!arg_multiple)
+ break;
+ }
+
+ return 0;
+}
+
+DEFINE_MAIN_FUNCTION(run);