]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
creds: permit interactive polkit auth when encrypting/decrypting through IPC
authorMike Yuan <me@yhndnzj.com>
Wed, 22 Jan 2025 17:25:17 +0000 (18:25 +0100)
committerYu Watanabe <watanabe.yu+github@gmail.com>
Thu, 23 Jan 2025 20:08:12 +0000 (05:08 +0900)
man/systemd-creds.xml
shell-completion/bash/systemd-creds
src/creds/creds.c
src/shared/creds-util.c
src/shared/creds-util.h

index 55c5064b65a506906a5ad7985605385efdd81a39..fc3d753ac1f18a7a2ddc2c1475b605135c026171 100644 (file)
         <xi:include href="version-info.xml" xpointer="v250"/></listitem>
       </varlistentry>
 
+      <xi:include href="standard-options.xml" xpointer="no-ask-password" />
       <xi:include href="standard-options.xml" xpointer="help" />
       <xi:include href="standard-options.xml" xpointer="version" />
     </variablelist>
index c16619e94f0ca34dffc6166ada1a8f10da2d9f3a..3142954625b3d280017a4d123194f75c73afa309 100644 (file)
@@ -41,7 +41,7 @@ _systemd_creds() {
     local verb comps mode i
     local cur=${COMP_WORDS[COMP_CWORD]} prev=${COMP_WORDS[COMP_CWORD-1]} words cword
     local -A OPTS=(
-        [STANDALONE]='-h --help --version --no-pager --no-legend
+        [STANDALONE]='-h --help --version --no-pager --no-legend --no-ask-password
                       -H -T --system --user -p --pretty --allow-null'
         [ARG]='--tpm2-device
                --tpm2-device-key
@@ -77,6 +77,7 @@ _systemd_creds() {
                    --version
                    --no-pager
                    --no-legend
+                   --no-ask-password
                    --uid
                    --with-key
                    -H
@@ -94,6 +95,7 @@ _systemd_creds() {
                    --version
                    --no-pager
                    --no-legend
+                   --no-ask-password
                    --uid
                    --tpm2-device
                    --tpm2-pcrs
index b10c36e66f440d556a36d7b602419b72fc11de12..cd53c90ce354312741c70d3c0fb4ba629dcc312c 100644 (file)
@@ -65,6 +65,7 @@ static bool arg_quiet = false;
 static bool arg_varlink = false;
 static uid_t arg_uid = UID_INVALID;
 static bool arg_allow_null = false;
+static bool arg_ask_password = true;
 
 STATIC_DESTRUCTOR_REGISTER(arg_tpm2_public_key, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_tpm2_signature, freep);
@@ -586,16 +587,18 @@ static int verb_encrypt(int argc, char **argv, void *userdata) {
         if (arg_not_after != USEC_INFINITY && arg_not_after < timestamp)
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Credential is invalidated before it is valid.");
 
-        if (geteuid() != 0)
+        if (geteuid() != 0) {
+                (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password);
+
                 r = ipc_encrypt_credential(
                                 name,
                                 timestamp,
                                 arg_not_after,
                                 arg_uid,
                                 &plaintext,
-                                /* flags= */ 0,
+                                arg_ask_password ? CREDENTIAL_IPC_ALLOW_INTERACTIVE : 0,
                                 &output);
-        else
+        else
                 r = encrypt_credential_and_warn(
                                 arg_with_key,
                                 name,
@@ -690,15 +693,17 @@ static int verb_decrypt(int argc, char **argv, void *userdata) {
 
         timestamp = arg_timestamp != USEC_INFINITY ? arg_timestamp : now(CLOCK_REALTIME);
 
-        if (geteuid() != 0)
+        if (geteuid() != 0) {
+                (void) polkit_agent_open_if_enabled(BUS_TRANSPORT_LOCAL, arg_ask_password);
+
                 r = ipc_decrypt_credential(
                                 name,
                                 timestamp,
                                 arg_uid,
                                 &input,
-                                /* flags= */ 0,
+                                arg_ask_password ? CREDENTIAL_IPC_ALLOW_INTERACTIVE : 0,
                                 &plaintext);
-        else
+        else
                 r = decrypt_credential_and_warn(
                                 name,
                                 timestamp,
@@ -832,6 +837,7 @@ static int parse_argv(int argc, char *argv[]) {
                 ARG_USER,
                 ARG_UID,
                 ARG_ALLOW_NULL,
+                ARG_NO_ASK_PASSWORD,
         };
 
         static const struct option options[] = {
@@ -857,6 +863,7 @@ static int parse_argv(int argc, char *argv[]) {
                 { "user",                 no_argument,       NULL, ARG_USER                 },
                 { "uid",                  required_argument, NULL, ARG_UID                  },
                 { "allow-null",           no_argument,       NULL, ARG_ALLOW_NULL           },
+                { "no-ask-password",      no_argument,       NULL, ARG_NO_ASK_PASSWORD      },
                 {}
         };
 
@@ -1052,6 +1059,10 @@ static int parse_argv(int argc, char *argv[]) {
                         arg_allow_null = true;
                         break;
 
+                case ARG_NO_ASK_PASSWORD:
+                        arg_ask_password = false;
+                        break;
+
                 case 'q':
                         arg_quiet = true;
                         break;
index 5156c63fd3f06ad119130af868a84e2207dc863b..0f840ff61aeb337031e6071b15e2f107d554608c 100644 (file)
@@ -1572,7 +1572,8 @@ int ipc_encrypt_credential(const char *name, usec_t timestamp, usec_t not_after,
                         SD_JSON_BUILD_PAIR_CONDITION(timestamp != USEC_INFINITY, "timestamp", SD_JSON_BUILD_UNSIGNED(timestamp)),
                         SD_JSON_BUILD_PAIR_CONDITION(not_after != USEC_INFINITY, "notAfter",  SD_JSON_BUILD_UNSIGNED(not_after)),
                         SD_JSON_BUILD_PAIR_CONDITION(!FLAGS_SET(flags, CREDENTIAL_ANY_SCOPE), "scope", SD_JSON_BUILD_STRING(uid_is_valid(uid) ? "user" : "system")),
-                        SD_JSON_BUILD_PAIR_CONDITION(uid_is_valid(uid), "uid", SD_JSON_BUILD_UNSIGNED(uid)));
+                        SD_JSON_BUILD_PAIR_CONDITION(uid_is_valid(uid), "uid", SD_JSON_BUILD_UNSIGNED(uid)),
+                        SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", FLAGS_SET(flags, CREDENTIAL_IPC_ALLOW_INTERACTIVE)));
         if (r < 0)
                 return log_error_errno(r, "Failed to call Encrypt() varlink call.");
         if (!isempty(error_id)) {
@@ -1629,7 +1630,8 @@ int ipc_decrypt_credential(const char *validate_name, usec_t validate_timestamp,
                         SD_JSON_BUILD_PAIR("blob", SD_JSON_BUILD_VARIANT(jinput)),
                         SD_JSON_BUILD_PAIR_CONDITION(validate_timestamp != USEC_INFINITY, "timestamp", SD_JSON_BUILD_UNSIGNED(validate_timestamp)),
                         SD_JSON_BUILD_PAIR_CONDITION(!FLAGS_SET(flags, CREDENTIAL_ANY_SCOPE), "scope", SD_JSON_BUILD_STRING(uid_is_valid(uid) ? "user" : "system")),
-                        SD_JSON_BUILD_PAIR_CONDITION(uid_is_valid(uid), "uid", SD_JSON_BUILD_UNSIGNED(uid)));
+                        SD_JSON_BUILD_PAIR_CONDITION(uid_is_valid(uid), "uid", SD_JSON_BUILD_UNSIGNED(uid)),
+                        SD_JSON_BUILD_PAIR_BOOLEAN("allowInteractiveAuthentication", FLAGS_SET(flags, CREDENTIAL_IPC_ALLOW_INTERACTIVE)));
         if (r < 0)
                 return log_error_errno(r, "Failed to call Decrypt() varlink call.");
         if (!isempty(error_id))  {
index e096b6d4d41bebc4b7f59feed6dbef184df5bf83..3b9580850ccd969fa82e68903c91ea9f586c6ab2 100644 (file)
@@ -58,8 +58,11 @@ int get_credential_host_secret(CredentialSecretFlags flags, struct iovec *ret);
 int get_credential_user_password(const char *username, char **ret_password, bool *ret_is_hashed);
 
 typedef enum CredentialFlags {
-        CREDENTIAL_ALLOW_NULL = 1 << 0, /* allow decryption of NULL key, even if TPM is around */
-        CREDENTIAL_ANY_SCOPE  = 1 << 1, /* allow decryption of both system and user credentials */
+        CREDENTIAL_ALLOW_NULL            = 1 << 0, /* allow decryption of NULL key, even if TPM is around */
+        CREDENTIAL_ANY_SCOPE             = 1 << 1, /* allow decryption of both system and user credentials */
+
+        /* Only used by ipc_{encrypt,decrypt}_credential */
+        CREDENTIAL_IPC_ALLOW_INTERACTIVE = 1 << 2,
 } CredentialFlags;
 
 /* The four modes we support: keyed only by on-disk key, only by TPM2 HMAC key, and by the combination of