]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cryptsetup: add 'headless' parameter to skip password/pin query
authorLuca Boccassi <luca.boccassi@microsoft.com>
Fri, 9 Apr 2021 19:43:10 +0000 (20:43 +0100)
committerLuca Boccassi <bluca@debian.org>
Fri, 7 May 2021 20:36:27 +0000 (21:36 +0100)
On headless setups, in case other methods fail, asking for a password/pin
is not useful as there are no users on the terminal, and generates
unwanted noise. Add a parameter to /etc/crypttab to skip it.

man/crypttab.xml
man/systemd-cryptsetup@.service.xml
src/cryptsetup/cryptsetup-fido2.c
src/cryptsetup/cryptsetup-fido2.h
src/cryptsetup/cryptsetup-pkcs11.c
src/cryptsetup/cryptsetup-pkcs11.h
src/cryptsetup/cryptsetup.c
src/shared/pkcs11-util.c
src/shared/pkcs11-util.h

index 72fe2e692dadf34f7657ea2b4145252cf1988a6d..d3aa3b8fc1fe486765f78b1596789a830775c6c3 100644 (file)
         user is queried for a password indefinitely.</para></listitem>
       </varlistentry>
 
+      <varlistentry>
+        <term><option>headless=</option></term>
+
+        <listitem><para>Takes a boolean argument, defaults to false. If true, never query interactively
+        for the password/PIN. Useful for headless systems.</para></listitem>
+      </varlistentry>
+
       <varlistentry>
         <term><option>verify</option></term>
 
index 668208a01d35a8828ee1e3b3fccbedf6317226f8..1697ccc0f3cd2097196c59c0430bfdb616ddb3f3 100644 (file)
@@ -73,7 +73,8 @@
       <listitem><para>The kernel keyring is then checked for a suitable cached password from previous
       attempts.</para></listitem>
 
-      <listitem><para>Finally, the user is queried for a password, possibly multiple times.</para></listitem>
+      <listitem><para>Finally, the user is queried for a password, possibly multiple times, unless
+      the <varname>headless</varname> option is set.</para></listitem>
     </orderedlist>
 
     <para>If no suitable key may be acquired via any of the mechanisms describes above, volume activation fails.</para>
index 82b83ee47705ecbce7f0b7d89c9b1e2999a23817..8238e823cdf3e2d8de7cd86ef57a748b33c97469 100644 (file)
@@ -23,6 +23,7 @@ int acquire_fido2_key(
                 const void *key_data,
                 size_t key_data_size,
                 usec_t until,
+                bool headless,
                 void **ret_decrypted_key,
                 size_t *ret_decrypted_key_size) {
 
@@ -88,6 +89,9 @@ int acquire_fido2_key(
 
                 pins = strv_free_erase(pins);
 
+                if (headless)
+                        return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the '$PIN' environment variable.");
+
                 r = ask_password_auto("Please enter security token PIN:", "drive-harddisk", NULL, "fido2-pin", "cryptsetup.fido2-pin", until, flags, &pins);
                 if (r < 0)
                         return log_error_errno(r, "Failed to ask for user password: %m");
index 92093ba38bb5d607426831d78c32e13b6bda968a..d5c5ce59268bdf02db7d58f35f473cd7d81680f6 100644 (file)
@@ -22,6 +22,7 @@ int acquire_fido2_key(
                 const void *key_data,
                 size_t key_data_size,
                 usec_t until,
+                bool headless,
                 void **ret_decrypted_key,
                 size_t *ret_decrypted_key_size);
 
@@ -49,6 +50,7 @@ static inline int acquire_fido2_key(
                 const void *key_data,
                 size_t key_data_size,
                 usec_t until,
+                bool headless,
                 void **ret_decrypted_key,
                 size_t *ret_decrypted_key_size) {
 
index 6d7b01176cbe0960706efee68997b16903ed1525..67adf923cc064e512ee8b7db0410ea09678ea331 100644 (file)
@@ -32,6 +32,7 @@ struct pkcs11_callback_data {
         void *decrypted_key;
         size_t decrypted_key_size;
         bool free_encrypted_key;
+        bool headless;
 };
 
 static void pkcs11_callback_data_release(struct pkcs11_callback_data *data) {
@@ -72,6 +73,7 @@ static int pkcs11_callback(
                         "pkcs11-pin",
                         "cryptsetup.pkcs11-pin",
                         data->until,
+                        data->headless,
                         NULL);
         if (r < 0)
                 return r;
@@ -109,12 +111,14 @@ int decrypt_pkcs11_key(
                 const void *key_data,         /* … or key_data and key_data_size (for literal keys) */
                 size_t key_data_size,
                 usec_t until,
+                bool headless,
                 void **ret_decrypted_key,
                 size_t *ret_decrypted_key_size) {
 
         _cleanup_(pkcs11_callback_data_release) struct pkcs11_callback_data data = {
                 .friendly_name = friendly_name,
                 .until = until,
+                .headless = headless,
         };
         int r;
 
index 4cd82e0215fa31c77141ddd9d384a8fc85b1ea42..256c09a9b68d278409998223216654f5befd9ff7 100644 (file)
@@ -19,6 +19,7 @@ int decrypt_pkcs11_key(
                 const void *key_data,
                 size_t key_data_size,
                 usec_t until,
+                bool headless,
                 void **ret_decrypted_key,
                 size_t *ret_decrypted_key_size);
 
@@ -41,6 +42,7 @@ static inline int decrypt_pkcs11_key(
                 const void *key_data,
                 size_t key_data_size,
                 usec_t until,
+                bool headless,
                 void **ret_decrypted_key,
                 size_t *ret_decrypted_key_size) {
 
index c9cebb46378e9d227ab4cffd38fea881e40c4bad..7902377a25abce6dd5b007332c80a2897cc1269d 100644 (file)
@@ -79,6 +79,7 @@ static char *arg_fido2_rp_id = NULL;
 static char *arg_tpm2_device = NULL;
 static bool arg_tpm2_device_auto = false;
 static uint32_t arg_tpm2_pcr_mask = UINT32_MAX;
+static bool arg_headless = false;
 
 STATIC_DESTRUCTOR_REGISTER(arg_cipher, freep);
 STATIC_DESTRUCTOR_REGISTER(arg_hash, freep);
@@ -381,6 +382,17 @@ static int parse_one_option(const char *option) {
 
         } else if (streq(option, "try-empty-password"))
                 arg_try_empty_password = true;
+        else if ((val = startswith(option, "headless="))) {
+
+                r = parse_boolean(val);
+                if (r < 0) {
+                        log_error_errno(r, "Failed to parse %s, ignoring: %m", option);
+                        return 0;
+                }
+
+                arg_headless = r;
+        } else if (streq(option, "headless"))
+                arg_headless = true;
 
         else if (!streq(option, "x-initrd.attach"))
                 log_warning("Encountered unknown /etc/crypttab option '%s', ignoring.", option);
@@ -532,6 +544,9 @@ static int get_password(
         assert(src);
         assert(ret);
 
+        if (arg_headless)
+                return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "Password querying disabled via 'headless' option.");
+
         friendly = friendly_disk_name(src, vol);
         if (!friendly)
                 return log_oom();
@@ -775,6 +790,7 @@ static int attach_luks_or_plain_or_bitlk_by_fido2(
                                 key_file, arg_keyfile_size, arg_keyfile_offset,
                                 key_data, key_data_size,
                                 until,
+                                arg_headless,
                                 &decrypted_key, &decrypted_key_size);
                 if (r >= 0)
                         break;
@@ -895,6 +911,7 @@ static int attach_luks_or_plain_or_bitlk_by_pkcs11(
                                 key_file, arg_keyfile_size, arg_keyfile_offset,
                                 key_data, key_data_size,
                                 until,
+                                arg_headless,
                                 &decrypted_key, &decrypted_key_size);
                 if (r >= 0)
                         break;
index aff45ed868c426d1c7f071ea9f22cabba7f5647c..9fc577ca3cf1c7c4dd1f2fc2f262e6d71cc91181 100644 (file)
@@ -184,6 +184,7 @@ int pkcs11_token_login(
                 const char *key_name,
                 const char *credential_name,
                 usec_t until,
+                bool headless,
                 char **ret_used_pin) {
 
         _cleanup_free_ char *token_uri_string = NULL, *token_uri_escaped = NULL, *id = NULL, *token_label = NULL;
@@ -247,7 +248,9 @@ int pkcs11_token_login(
                         string_erase(e);
                         if (unsetenv("PIN") < 0)
                                 return log_error_errno(errno, "Failed to unset $PIN: %m");
-                } else {
+                } else if (headless)
+                        return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the 'PIN' environment variable.");
+                else {
                         _cleanup_free_ char *text = NULL;
 
                         if (FLAGS_SET(token_info->flags, CKF_USER_PIN_FINAL_TRY))
@@ -960,7 +963,7 @@ static int pkcs11_acquire_certificate_callback(
 
         /* Called for every token matching our URI */
 
-        r = pkcs11_token_login(m, session, slot_id, token_info, data->askpw_friendly_name, data->askpw_icon_name, "pkcs11-pin", "pkcs11-pin", UINT64_MAX, &pin_used);
+        r = pkcs11_token_login(m, session, slot_id, token_info, data->askpw_friendly_name, data->askpw_icon_name, "pkcs11-pin", "pkcs11-pin", UINT64_MAX, false, &pin_used);
         if (r < 0)
                 return r;
 
index c2c852f0ebe356b8fe965bdf2f3141d80325faba..f7f32d34d71bb56b7207f75da64b700554e6d7a8 100644 (file)
@@ -30,7 +30,7 @@ char *pkcs11_token_label(const CK_TOKEN_INFO *token_info);
 char *pkcs11_token_manufacturer_id(const CK_TOKEN_INFO *token_info);
 char *pkcs11_token_model(const CK_TOKEN_INFO *token_info);
 
-int pkcs11_token_login(CK_FUNCTION_LIST *m, CK_SESSION_HANDLE session, CK_SLOT_ID slotid, const CK_TOKEN_INFO *token_info, const char *friendly_name, const char *icon_name, const char *key_name, const char *credential_name, usec_t until, char **ret_used_pin);
+int pkcs11_token_login(CK_FUNCTION_LIST *m, CK_SESSION_HANDLE session, CK_SLOT_ID slotid, const CK_TOKEN_INFO *token_info, const char *friendly_name, const char *icon_name, const char *key_name, const char *credential_name, usec_t until, bool headless, char **ret_used_pin);
 
 int pkcs11_token_find_x509_certificate(CK_FUNCTION_LIST *m, CK_SESSION_HANDLE session, P11KitUri *search_uri, CK_OBJECT_HANDLE *ret_object);
 #if HAVE_OPENSSL