]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
homed: move fido2 device enumeration logic to shared code
authorLennart Poettering <lennart@poettering.net>
Wed, 25 Nov 2020 14:15:25 +0000 (15:15 +0100)
committerLennart Poettering <lennart@poettering.net>
Thu, 17 Dec 2020 18:59:50 +0000 (19:59 +0100)
src/home/homectl-fido2.c
src/home/homectl-fido2.h
src/home/homectl.c
src/shared/libfido2-util.c
src/shared/libfido2-util.h

index 983891e0e0a9ed7a17a6119bbc54efb80df23077..99a6bd5d9df9daeefe02d7b2b2edf55524ee23d9 100644 (file)
@@ -410,138 +410,3 @@ int identity_add_fido2_parameters(
                                "FIDO2 tokens not supported on this build.");
 #endif
 }
-
-int list_fido2_devices(void) {
-#if HAVE_LIBFIDO2
-        _cleanup_(table_unrefp) Table *t = NULL;
-        size_t allocated = 64, found = 0;
-        fido_dev_info_t *di = NULL;
-        int r;
-
-        r = dlopen_libfido2();
-        if (r < 0)
-                return log_error_errno(r, "FIDO2 token support is not installed.");
-
-        di = sym_fido_dev_info_new(allocated);
-        if (!di)
-                return log_oom();
-
-        r = sym_fido_dev_info_manifest(di, allocated, &found);
-        if (r == FIDO_ERR_INTERNAL || (r == FIDO_OK && found == 0)) {
-                /* The library returns FIDO_ERR_INTERNAL when no devices are found. I wish it wouldn't. */
-                log_info("No FIDO2 devices found.");
-                r = 0;
-                goto finish;
-        }
-        if (r != FIDO_OK) {
-                r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to enumerate FIDO2 devices: %s", sym_fido_strerr(r));
-                goto finish;
-        }
-
-        t = table_new("path", "manufacturer", "product");
-        if (!t) {
-                r = log_oom();
-                goto finish;
-        }
-
-        for (size_t i = 0; i < found; i++) {
-                const fido_dev_info_t *entry;
-
-                entry = sym_fido_dev_info_ptr(di, i);
-                if (!entry) {
-                        r = log_error_errno(SYNTHETIC_ERRNO(EIO),
-                                            "Failed to get device information for FIDO device %zu.", i);
-                        goto finish;
-                }
-
-                r = table_add_many(
-                                t,
-                                TABLE_PATH, sym_fido_dev_info_path(entry),
-                                TABLE_STRING, sym_fido_dev_info_manufacturer_string(entry),
-                                TABLE_STRING, sym_fido_dev_info_product_string(entry));
-                if (r < 0) {
-                        table_log_add_error(r);
-                        goto finish;
-                }
-        }
-
-        r = table_print(t, stdout);
-        if (r < 0) {
-                log_error_errno(r, "Failed to show device table: %m");
-                goto finish;
-        }
-
-        r = 0;
-
-finish:
-        sym_fido_dev_info_free(&di, allocated);
-        return r;
-#else
-        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
-                               "FIDO2 tokens not supported on this build.");
-#endif
-}
-
-int find_fido2_auto(char **ret) {
-#if HAVE_LIBFIDO2
-        _cleanup_free_ char *copy = NULL;
-        size_t di_size = 64, found = 0;
-        const fido_dev_info_t *entry;
-        fido_dev_info_t *di = NULL;
-        const char *path;
-        int r;
-
-        r = dlopen_libfido2();
-        if (r < 0)
-                return log_error_errno(r, "FIDO2 token support is not installed.");
-
-        di = sym_fido_dev_info_new(di_size);
-        if (!di)
-                return log_oom();
-
-        r = sym_fido_dev_info_manifest(di, di_size, &found);
-        if (r == FIDO_ERR_INTERNAL || (r == FIDO_OK && found == 0)) {
-                /* The library returns FIDO_ERR_INTERNAL when no devices are found. I wish it wouldn't. */
-                r = log_error_errno(SYNTHETIC_ERRNO(ENODEV), "No FIDO2 devices found.");
-                goto finish;
-        }
-        if (r != FIDO_OK) {
-                r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to enumerate FIDO2 devices: %s", sym_fido_strerr(r));
-                goto finish;
-        }
-        if (found > 1) {
-                r = log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ), "More than one FIDO2 device found.");
-                goto finish;
-        }
-
-        entry = sym_fido_dev_info_ptr(di, 0);
-        if (!entry) {
-                r = log_error_errno(SYNTHETIC_ERRNO(EIO),
-                                    "Failed to get device information for FIDO device 0.");
-                goto finish;
-        }
-
-        path = sym_fido_dev_info_path(entry);
-        if (!path) {
-                r = log_error_errno(SYNTHETIC_ERRNO(EIO),
-                                    "Failed to query FIDO device path.");
-                goto finish;
-        }
-
-        copy = strdup(path);
-        if (!copy) {
-                r = log_oom();
-                goto finish;
-        }
-
-        *ret = TAKE_PTR(copy);
-        r = 0;
-
-finish:
-        sym_fido_dev_info_free(&di, di_size);
-        return r;
-#else
-        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
-                               "FIDO2 tokens not supported on this build.");
-#endif
-}
index d0349f54050c33fa46e874436d799c88ff803271..7b8d9f60acd10dda6f8e22d0921943a6ab4eb909 100644 (file)
@@ -4,7 +4,3 @@
 #include "json.h"
 
 int identity_add_fido2_parameters(JsonVariant **v, const char *device);
-
-int list_fido2_devices(void);
-
-int find_fido2_auto(char **ret);
index e10cfaf2a4705717d74fdf6f924c1e76fda769d7..c9e54b1e67f8fb8f3a889b16e78b97419855a1d0 100644 (file)
@@ -18,6 +18,7 @@
 #include "homectl-fido2.h"
 #include "homectl-pkcs11.h"
 #include "homectl-recovery-key.h"
+#include "libfido2-util.h"
 #include "locale-util.h"
 #include "main-func.h"
 #include "memory-util.h"
@@ -3184,7 +3185,7 @@ static int parse_argv(int argc, char *argv[]) {
                         const char *p;
 
                         if (streq(optarg, "list"))
-                                return list_fido2_devices();
+                                return fido2_list_devices();
 
                         FOREACH_STRING(p, "fido2HmacCredential", "fido2HmacSalt") {
                                 r = drop_from_identity(p);
@@ -3200,7 +3201,7 @@ static int parse_argv(int argc, char *argv[]) {
                         if (streq(optarg, "auto")) {
                                 _cleanup_free_ char *found = NULL;
 
-                                r = find_fido2_auto(&found);
+                                r = fido2_find_device_auto(&found);
                                 if (r < 0)
                                         return r;
 
index 281eb7537aa1ecd53e99f593063708282cb290ed..8358aa2fe3749f592dda209709aac6f1c387410b 100644 (file)
@@ -5,6 +5,8 @@
 #if HAVE_LIBFIDO2
 #include "alloc-util.h"
 #include "dlfcn-util.h"
+#include "format-table.h"
+#include "locale-util.h"
 #include "log.h"
 
 static void *libfido2_dl = NULL;
@@ -115,3 +117,138 @@ int dlopen_libfido2(void) {
         return 1;
 }
 #endif
+
+int fido2_list_devices(void) {
+#if HAVE_LIBFIDO2
+        _cleanup_(table_unrefp) Table *t = NULL;
+        size_t allocated = 64, found = 0;
+        fido_dev_info_t *di = NULL;
+        int r;
+
+        r = dlopen_libfido2();
+        if (r < 0)
+                return log_error_errno(r, "FIDO2 token support is not installed.");
+
+        di = sym_fido_dev_info_new(allocated);
+        if (!di)
+                return log_oom();
+
+        r = sym_fido_dev_info_manifest(di, allocated, &found);
+        if (r == FIDO_ERR_INTERNAL || (r == FIDO_OK && found == 0)) {
+                /* The library returns FIDO_ERR_INTERNAL when no devices are found. I wish it wouldn't. */
+                log_info("No FIDO2 devices found.");
+                r = 0;
+                goto finish;
+        }
+        if (r != FIDO_OK) {
+                r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to enumerate FIDO2 devices: %s", sym_fido_strerr(r));
+                goto finish;
+        }
+
+        t = table_new("path", "manufacturer", "product");
+        if (!t) {
+                r = log_oom();
+                goto finish;
+        }
+
+        for (size_t i = 0; i < found; i++) {
+                const fido_dev_info_t *entry;
+
+                entry = sym_fido_dev_info_ptr(di, i);
+                if (!entry) {
+                        r = log_error_errno(SYNTHETIC_ERRNO(EIO),
+                                            "Failed to get device information for FIDO device %zu.", i);
+                        goto finish;
+                }
+
+                r = table_add_many(
+                                t,
+                                TABLE_PATH, sym_fido_dev_info_path(entry),
+                                TABLE_STRING, sym_fido_dev_info_manufacturer_string(entry),
+                                TABLE_STRING, sym_fido_dev_info_product_string(entry));
+                if (r < 0) {
+                        table_log_add_error(r);
+                        goto finish;
+                }
+        }
+
+        r = table_print(t, stdout);
+        if (r < 0) {
+                log_error_errno(r, "Failed to show device table: %m");
+                goto finish;
+        }
+
+        r = 0;
+
+finish:
+        sym_fido_dev_info_free(&di, allocated);
+        return r;
+#else
+        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
+                               "FIDO2 tokens not supported on this build.");
+#endif
+}
+
+int fido2_find_device_auto(char **ret) {
+#if HAVE_LIBFIDO2
+        _cleanup_free_ char *copy = NULL;
+        size_t di_size = 64, found = 0;
+        const fido_dev_info_t *entry;
+        fido_dev_info_t *di = NULL;
+        const char *path;
+        int r;
+
+        r = dlopen_libfido2();
+        if (r < 0)
+                return log_error_errno(r, "FIDO2 token support is not installed.");
+
+        di = sym_fido_dev_info_new(di_size);
+        if (!di)
+                return log_oom();
+
+        r = sym_fido_dev_info_manifest(di, di_size, &found);
+        if (r == FIDO_ERR_INTERNAL || (r == FIDO_OK && found == 0)) {
+                /* The library returns FIDO_ERR_INTERNAL when no devices are found. I wish it wouldn't. */
+                r = log_error_errno(SYNTHETIC_ERRNO(ENODEV), "No FIDO devices found.");
+                goto finish;
+        }
+        if (r != FIDO_OK) {
+                r = log_error_errno(SYNTHETIC_ERRNO(EIO), "Failed to enumerate FIDO devices: %s", sym_fido_strerr(r));
+                goto finish;
+        }
+        if (found > 1) {
+                r = log_error_errno(SYNTHETIC_ERRNO(ENOTUNIQ), "More than one FIDO device found.");
+                goto finish;
+        }
+
+        entry = sym_fido_dev_info_ptr(di, 0);
+        if (!entry) {
+                r = log_error_errno(SYNTHETIC_ERRNO(EIO),
+                                    "Failed to get device information for FIDO device 0.");
+                goto finish;
+        }
+
+        path = sym_fido_dev_info_path(entry);
+        if (!path) {
+                r = log_error_errno(SYNTHETIC_ERRNO(EIO),
+                                    "Failed to query FIDO device path.");
+                goto finish;
+        }
+
+        copy = strdup(path);
+        if (!copy) {
+                r = log_oom();
+                goto finish;
+        }
+
+        *ret = TAKE_PTR(copy);
+        r = 0;
+
+finish:
+        sym_fido_dev_info_free(&di, di_size);
+        return r;
+#else
+        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
+                               "FIDO2 tokens not supported on this build.");
+#endif
+}
index baa5ee9212aebabcc4d2963dd66ad048725d2edb..37b2f921ff2577f83887c08c7054faf61519af13 100644 (file)
@@ -70,3 +70,6 @@ static inline void fido_cred_free_wrapper(fido_cred_t **p) {
 }
 
 #endif
+
+int fido2_list_devices(void);
+int fido2_find_device_auto(char **ret);