]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
cryptsetup: before querying user for a PIN, check if a FIDO2 device is actually plugg...
authorLennart Poettering <lennart@poettering.net>
Fri, 8 Oct 2021 20:01:44 +0000 (22:01 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 11 Oct 2021 09:12:29 +0000 (11:12 +0200)
Before we'd already ask for a PIN just because we know we'll need it
when the token is plugged in. We'd only the try to talk to the device
and notice it actually isn't plugged in. This is quite confusing, as
querying for the PIN suggests we already had a device we are talking to.

Let's hence check if there's actually device before we ask the PIN
question. And if there is none, let's immediately inform the caller, so
that they watch udev and retry once a device has shown up.

src/cryptsetup/cryptsetup-fido2.c

index 3a870016d31202aaaf948069b10898c02d125c75..35d5dbe007568bde3b75ad93d7cece01d91b2d4e 100644 (file)
@@ -32,6 +32,7 @@ int acquire_fido2_key(
 
         _cleanup_strv_free_erase_ char **pins = NULL;
         _cleanup_free_ void *loaded_salt = NULL;
+        bool device_exists = false;
         const char *salt;
         size_t salt_size;
         char *e;
@@ -89,13 +90,29 @@ int acquire_fido2_key(
                                     -ENOANO,   /* needs pin */
                                     -ENOLCK))  /* pin incorrect */
                                 return r;
-                }
 
-                pins = strv_free_erase(pins);
+                        device_exists = true; /* that a PIN is needed/wasn't correct means that we managed to
+                                               * talk to a device */
+                }
 
                 if (headless)
                         return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option. Use the '$PIN' environment variable.");
 
+                if (!device_exists) {
+                        /* Before we inquire for the PIN we'll need, if we never talked to the device, check
+                         * if the device actually is plugged in. Otherwise we'll ask for the PIN already when
+                         * the device is not plugged in, which is confusing. */
+
+                        r = fido2_have_device(device);
+                        if (r < 0)
+                                return r;
+                        if (r == 0) /* no device found, return EAGAIN so that caller will wait/watch udev */
+                                return -EAGAIN;
+
+                        device_exists = true;  /* now we know for sure, a device exists, no need to ask again */
+                }
+
+                pins = strv_free_erase(pins);
                 r = ask_password_auto("Please enter security token PIN:", "drive-harddisk", NULL, "fido2-pin", "cryptsetup.fido2-pin", until, ask_password_flags, &pins);
                 if (r < 0)
                         return log_error_errno(r, "Failed to ask for user password: %m");