cryptenroll: add interactive mode and Varlink IPC API (#42380)
Replaces: #31096 Fixes: #36298
This commit is contained in:
+157
-35
@@ -746,6 +746,8 @@ int fido2_generate_hmac_hash(
|
||||
const char *user_icon,
|
||||
const char *askpw_icon,
|
||||
const char *askpw_credential,
|
||||
AskPasswordFlags askpw_flags,
|
||||
const char *pin,
|
||||
Fido2EnrollFlags lock_with,
|
||||
int cred_alg,
|
||||
const struct iovec *salt,
|
||||
@@ -920,48 +922,57 @@ int fido2_generate_hmac_hash(
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
|
||||
"Token asks for PIN but doesn't advertise 'clientPin' feature.");
|
||||
|
||||
AskPasswordFlags askpw_flags = ASK_PASSWORD_ACCEPT_CACHED;
|
||||
AskPasswordFlags pin_askpw_flags = askpw_flags | ASK_PASSWORD_ACCEPT_CACHED;
|
||||
|
||||
for (;;) {
|
||||
_cleanup_strv_free_erase_ char **pin = NULL;
|
||||
_cleanup_free_ char *ask_pin_msg = NULL;
|
||||
int pin_retries = -1;
|
||||
_cleanup_strv_free_erase_ char **pins = NULL;
|
||||
|
||||
r = sym_fido_dev_get_retry_count(d, &pin_retries);
|
||||
if (r != FIDO_OK) {
|
||||
log_warning("Failed to obtain number of retries before lock-out for PIN "
|
||||
"authentication, ignoring: %s", sym_fido_strerr(r));
|
||||
pin_retries = -1;
|
||||
}
|
||||
|
||||
if (pin_retries >= 0) {
|
||||
ask_pin_msg = asprintf_safe(_("Please enter security token PIN "
|
||||
"(remaining attempts before lock-out: %d):"),
|
||||
pin_retries);
|
||||
if (!ask_pin_msg)
|
||||
if (pin) {
|
||||
/* A PIN was supplied by the caller: use it directly, don't prompt. */
|
||||
pins = strv_new(pin);
|
||||
if (!pins)
|
||||
return log_oom();
|
||||
} else if (FLAGS_SET(askpw_flags, ASK_PASSWORD_HEADLESS))
|
||||
return log_error_errno(SYNTHETIC_ERRNO(ENOPKG), "PIN querying disabled via 'headless' option.");
|
||||
else {
|
||||
int pin_retries = -1;
|
||||
r = sym_fido_dev_get_retry_count(d, &pin_retries);
|
||||
if (r != FIDO_OK) {
|
||||
log_warning("Failed to obtain number of retries before lock-out for PIN "
|
||||
"authentication, ignoring: %s", sym_fido_strerr(r));
|
||||
pin_retries = -1;
|
||||
}
|
||||
|
||||
_cleanup_free_ char *ask_pin_msg = NULL;
|
||||
if (pin_retries >= 0) {
|
||||
ask_pin_msg = asprintf_safe(_("Please enter security token PIN "
|
||||
"(remaining attempts before lock-out: %d):"),
|
||||
pin_retries);
|
||||
if (!ask_pin_msg)
|
||||
return log_oom();
|
||||
}
|
||||
|
||||
AskPasswordRequest req = {
|
||||
.tty_fd = -EBADF,
|
||||
.message = pin_retries >= 0
|
||||
? ask_pin_msg
|
||||
: _("Please enter security token PIN:"),
|
||||
.icon = askpw_icon,
|
||||
.keyring = "fido2-pin",
|
||||
.credential = askpw_credential,
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_auto(&req, pin_askpw_flags, &pins);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to acquire user PIN: %m");
|
||||
|
||||
pin_askpw_flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
|
||||
}
|
||||
|
||||
AskPasswordRequest req = {
|
||||
.tty_fd = -EBADF,
|
||||
.message = pin_retries >= 0
|
||||
? ask_pin_msg
|
||||
: _("Please enter security token PIN:"),
|
||||
.icon = askpw_icon,
|
||||
.keyring = "fido2-pin",
|
||||
.credential = askpw_credential,
|
||||
.until = USEC_INFINITY,
|
||||
.hup_fd = -EBADF,
|
||||
};
|
||||
|
||||
r = ask_password_auto(&req, askpw_flags, &pin);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to acquire user PIN: %m");
|
||||
|
||||
askpw_flags &= ~ASK_PASSWORD_ACCEPT_CACHED;
|
||||
|
||||
r = FIDO_ERR_PIN_INVALID;
|
||||
STRV_FOREACH(i, pin) {
|
||||
STRV_FOREACH(i, pins) {
|
||||
if (isempty(*i)) {
|
||||
log_notice("PIN may not be empty.");
|
||||
continue;
|
||||
@@ -981,6 +992,11 @@ int fido2_generate_hmac_hash(
|
||||
if (r != FIDO_ERR_PIN_INVALID)
|
||||
break;
|
||||
|
||||
/* A caller-supplied PIN that's wrong won't get better by retrying: fail instead of
|
||||
* looping forever (we'd never prompt). */
|
||||
if (pin)
|
||||
break;
|
||||
|
||||
log_notice("PIN incorrect, please try again.");
|
||||
}
|
||||
}
|
||||
@@ -996,6 +1012,9 @@ int fido2_generate_hmac_hash(
|
||||
if (r == FIDO_ERR_UNSUPPORTED_ALGORITHM)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"Token doesn't support credential algorithm %s.", fido2_algorithm_to_string(cred_alg));
|
||||
if (r == FIDO_ERR_PIN_INVALID)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
"PIN incorrect.");
|
||||
if (r != FIDO_OK)
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EIO),
|
||||
"Failed to generate FIDO2 credential: %s", sym_fido_strerr(r));
|
||||
@@ -1300,6 +1319,109 @@ finish:
|
||||
#endif
|
||||
}
|
||||
|
||||
void fido2_device_info_done(Fido2DeviceInfo *d) {
|
||||
assert(d);
|
||||
|
||||
d->path = mfree(d->path);
|
||||
d->manufacturer = mfree(d->manufacturer);
|
||||
d->product = mfree(d->product);
|
||||
}
|
||||
|
||||
void fido2_device_info_free_many(Fido2DeviceInfo *a, size_t n) {
|
||||
FOREACH_ARRAY(i, a, n)
|
||||
fido2_device_info_done(i);
|
||||
|
||||
free(a);
|
||||
}
|
||||
|
||||
int fido2_enumerate_devices(Fido2DeviceInfo **ret, size_t *ret_n) {
|
||||
#if HAVE_LIBFIDO2
|
||||
Fido2DeviceInfo *devices = NULL;
|
||||
size_t n_devices = 0, allocated = 64, found = 0;
|
||||
fido_dev_info_t *di = NULL;
|
||||
int r;
|
||||
|
||||
CLEANUP_ARRAY(devices, n_devices, fido2_device_info_free_many);
|
||||
|
||||
assert(ret);
|
||||
assert(ret_n);
|
||||
|
||||
r = dlopen_libfido2(LOG_ERR);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
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. */
|
||||
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;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < found; i++) {
|
||||
bool has_rk, has_client_pin, has_up, has_uv, has_always_uv;
|
||||
const fido_dev_info_t *entry;
|
||||
const char *path;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
path = sym_fido_dev_info_path(entry);
|
||||
|
||||
r = check_device_is_fido2_with_hmac_secret(path, &has_rk, &has_client_pin, &has_up, &has_uv, &has_always_uv);
|
||||
if (r < 0)
|
||||
goto finish;
|
||||
if (r == 0) /* Not a FIDO2 device suitable for enrollment, skip it */
|
||||
continue;
|
||||
|
||||
if (!GREEDY_REALLOC(devices, n_devices + 1)) {
|
||||
r = log_oom();
|
||||
goto finish;
|
||||
}
|
||||
|
||||
Fido2DeviceInfo *d = devices + n_devices;
|
||||
*d = (Fido2DeviceInfo) {};
|
||||
|
||||
/* The manufacturer / product strings are optional (NULL when the device doesn't report
|
||||
* them), but a failure to duplicate any string is a genuine OOM and thus fatal. */
|
||||
if (strdup_to(&d->path, path) < 0 ||
|
||||
strdup_to(&d->manufacturer, empty_to_null(sym_fido_dev_info_manufacturer_string(entry))) < 0 ||
|
||||
strdup_to(&d->product, empty_to_null(sym_fido_dev_info_product_string(entry))) < 0) {
|
||||
fido2_device_info_done(d);
|
||||
r = log_oom();
|
||||
goto finish;
|
||||
}
|
||||
|
||||
n_devices++;
|
||||
}
|
||||
|
||||
r = 0;
|
||||
|
||||
finish:
|
||||
sym_fido_dev_info_free(&di, allocated);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret = TAKE_PTR(devices);
|
||||
*ret_n = n_devices;
|
||||
return 0;
|
||||
#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;
|
||||
|
||||
@@ -117,6 +117,8 @@ int fido2_generate_hmac_hash(
|
||||
const char *user_icon,
|
||||
const char *askpw_icon,
|
||||
const char *askpw_credential,
|
||||
AskPasswordFlags askpw_flags,
|
||||
const char *pin,
|
||||
Fido2EnrollFlags lock_with,
|
||||
int cred_alg,
|
||||
const struct iovec *salt,
|
||||
@@ -135,4 +137,17 @@ static inline int parse_fido2_algorithm(const char *s, int *ret) {
|
||||
int fido2_list_devices(void);
|
||||
int fido2_find_device_auto(char **ret);
|
||||
|
||||
typedef struct Fido2DeviceInfo {
|
||||
char *path;
|
||||
char *manufacturer; /* may be NULL if the device doesn't report it */
|
||||
char *product; /* may be NULL if the device doesn't report it */
|
||||
} Fido2DeviceInfo;
|
||||
|
||||
void fido2_device_info_done(Fido2DeviceInfo *d);
|
||||
void fido2_device_info_free_many(Fido2DeviceInfo *a, size_t n);
|
||||
|
||||
/* Enumerates the FIDO2 tokens that implement the 'hmac-secret' extension (i.e. are suitable for
|
||||
* enrollment), returning a newly allocated array. */
|
||||
int fido2_enumerate_devices(Fido2DeviceInfo **ret, size_t *ret_n);
|
||||
|
||||
int fido2_have_device(const char *device);
|
||||
|
||||
@@ -224,6 +224,7 @@ shared_sources = files(
|
||||
'varlink-io.systemd.AskPassword.c',
|
||||
'varlink-io.systemd.BootControl.c',
|
||||
'varlink-io.systemd.Credentials.c',
|
||||
'varlink-io.systemd.CryptEnroll.c',
|
||||
'varlink-io.systemd.FactoryReset.c',
|
||||
'varlink-io.systemd.Hostname.c',
|
||||
'varlink-io.systemd.Import.c',
|
||||
|
||||
@@ -213,6 +213,47 @@ int prompt_loop(
|
||||
}
|
||||
}
|
||||
|
||||
static int boolean_is_valid(const char *name, void *userdata) {
|
||||
return parse_boolean(name) >= 0;
|
||||
}
|
||||
|
||||
int prompt_loop_yes_no(const char *question, bool def, bool *ret) {
|
||||
int r;
|
||||
|
||||
assert(question);
|
||||
assert(ret);
|
||||
|
||||
char **l = STRV_MAKE("yes", "no");
|
||||
|
||||
_cleanup_free_ char *reply = NULL;
|
||||
r = prompt_loop(question,
|
||||
GLYPH_WARNING_SIGN,
|
||||
/* prefill= */ def ? "yes" : "no",
|
||||
/* menu= */ l,
|
||||
/* accepted= */ NULL,
|
||||
/* ellipsize_percentage= */ 20,
|
||||
/* n_columns= */ 2,
|
||||
/* column_width= */ 40,
|
||||
/* is_valid= */ boolean_is_valid,
|
||||
/* refresh= */ NULL,
|
||||
/* userdata= */ NULL,
|
||||
PROMPT_SHOW_MENU|PROMPT_MAY_SKIP|PROMPT_HIDE_MENU_HINT|PROMPT_HIDE_SKIP_HINT,
|
||||
&reply);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r == 0) { /* Skipped (empty input): fall back to the default. */
|
||||
*ret = def;
|
||||
return 0;
|
||||
}
|
||||
|
||||
r = parse_boolean(reply);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse reply: %s", reply);
|
||||
|
||||
*ret = r;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Default: bright white on blue background */
|
||||
#define ANSI_COLOR_CHROME "\x1B[0;44;1;37m"
|
||||
|
||||
@@ -371,11 +412,12 @@ static int vl_on_reply(sd_varlink *link, sd_json_variant *parameters, const char
|
||||
int mute_console(sd_varlink **ret_link) {
|
||||
int r;
|
||||
|
||||
assert(ret_link);
|
||||
|
||||
/* Talks to the MuteConsole service, and asks for output to the console to be muted, as long as the
|
||||
* connection is retained */
|
||||
|
||||
if (!ret_link)
|
||||
return 0;
|
||||
|
||||
_cleanup_(sd_varlink_flush_close_unrefp) sd_varlink *link = NULL;
|
||||
r = sd_varlink_connect_address(&link, "/run/systemd/io.systemd.MuteConsole");
|
||||
if (r < 0)
|
||||
|
||||
@@ -26,6 +26,8 @@ int prompt_loop(const char *text,
|
||||
PromptFlags flags,
|
||||
char **ret);
|
||||
|
||||
int prompt_loop_yes_no(const char *question, bool def, bool *ret);
|
||||
|
||||
int chrome_show(const char *top, const char *bottom);
|
||||
void chrome_hide(void);
|
||||
|
||||
|
||||
@@ -0,0 +1,108 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "bus-polkit.h"
|
||||
#include "varlink-io.systemd.CryptEnroll.h"
|
||||
|
||||
/* The credential types this interface knows about. The same enum is used for the 'mechanism' to enroll, for
|
||||
* the slot types to wipe, and for the slot types reported by ListSlots. Note that only password, recovery key
|
||||
* and fido2 may actually be *enrolled* via the Enroll() method; pkcs11 and tpm2 slots can be listed and wiped,
|
||||
* but enrolling them requires the systemd-cryptenroll command line. Enroll() rejects them with an
|
||||
* InvalidParameter error rather than via interface validation, so they are part of this enum. */
|
||||
static SD_VARLINK_DEFINE_ENUM_TYPE(
|
||||
EnrollMechanism,
|
||||
SD_VARLINK_FIELD_COMMENT("A regular passphrase"),
|
||||
SD_VARLINK_DEFINE_ENUM_VALUE(password),
|
||||
SD_VARLINK_FIELD_COMMENT("A randomly generated recovery key"),
|
||||
SD_VARLINK_DEFINE_ENUM_VALUE(recovery),
|
||||
SD_VARLINK_FIELD_COMMENT("A PKCS#11 security token (not enrollable via this interface)"),
|
||||
SD_VARLINK_DEFINE_ENUM_VALUE(pkcs11),
|
||||
SD_VARLINK_FIELD_COMMENT("A FIDO2 security token"),
|
||||
SD_VARLINK_DEFINE_ENUM_VALUE(fido2),
|
||||
SD_VARLINK_FIELD_COMMENT("A TPM2 device (not enrollable via this interface)"),
|
||||
SD_VARLINK_DEFINE_ENUM_VALUE(tpm2));
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD_FULL(
|
||||
Enroll,
|
||||
SD_VARLINK_SUPPORTS_MORE,
|
||||
SD_VARLINK_FIELD_COMMENT("Path to the LUKS2 block device or image to operate on."),
|
||||
SD_VARLINK_DEFINE_INPUT(node, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("Which kind of credential to enroll. Only 'password', 'recovery' and 'fido2' may be enrolled via this interface for now; 'pkcs11' and 'tpm2' are rejected with an InvalidParameter error, currently."),
|
||||
SD_VARLINK_DEFINE_INPUT_BY_TYPE(mechanism, EnrollMechanism, 0),
|
||||
|
||||
SD_VARLINK_FIELD_COMMENT("How to unlock the volume for the enrollment operation is inferred from which of the following fields are set: setting unlockPassword unlocks via that password, unlockKeyFile/unlockKeyFileDescriptor via a key file, unlockFido2Device via FIDO2, unlockTpm2Device via TPM2. Exactly one must be set."),
|
||||
SD_VARLINK_DEFINE_INPUT(unlockPassword, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Path to a key file to unlock the volume with."),
|
||||
SD_VARLINK_DEFINE_INPUT(unlockKeyFile, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Index into the file descriptors passed along with this call, identifying a key file to unlock the volume with."),
|
||||
SD_VARLINK_DEFINE_INPUT(unlockKeyFileDescriptor, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Path to a FIDO2 device to unlock the volume with. Leave the path empty to automatically discover a suitable device."),
|
||||
SD_VARLINK_DEFINE_INPUT(unlockFido2Device, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Path to a TPM2 device to unlock the volume with. Leave the path empty to automatically discover a suitable device."),
|
||||
SD_VARLINK_DEFINE_INPUT(unlockTpm2Device, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
|
||||
SD_VARLINK_FIELD_COMMENT("The passphrase to enroll, when mechanism is 'password'. Contains key material."),
|
||||
SD_VARLINK_DEFINE_INPUT(password, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
|
||||
SD_VARLINK_FIELD_COMMENT("Path to the FIDO2 device to enroll, when mechanism is 'fido2'. Leave empty to automatically discover a suitable device."),
|
||||
SD_VARLINK_DEFINE_INPUT(fido2Device, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The FIDO2 token PIN to use for enrollment. Contains key material."),
|
||||
SD_VARLINK_DEFINE_INPUT(fido2Pin, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether unlocking the FIDO2 enrollment shall require a client PIN. Defaults to true."),
|
||||
SD_VARLINK_DEFINE_INPUT(fido2WithClientPin, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether unlocking the FIDO2 enrollment shall require user presence (touch). Defaults to true."),
|
||||
SD_VARLINK_DEFINE_INPUT(fido2WithUserPresence, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Whether unlocking the FIDO2 enrollment shall require user verification. Defaults to false."),
|
||||
SD_VARLINK_DEFINE_INPUT(fido2WithUserVerification, SD_VARLINK_BOOL, SD_VARLINK_NULLABLE),
|
||||
|
||||
SD_VARLINK_FIELD_COMMENT("Explicit list of keyslot indexes to wipe after enrolling."),
|
||||
SD_VARLINK_DEFINE_INPUT(wipeSlots, SD_VARLINK_INT, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Wipe all already-enrolled slots of these types after enrolling."),
|
||||
SD_VARLINK_DEFINE_INPUT_BY_TYPE(wipeTypes, EnrollMechanism, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
|
||||
VARLINK_DEFINE_POLKIT_INPUT,
|
||||
|
||||
SD_VARLINK_FIELD_COMMENT("The keyslot the new credential was enrolled into. Set on the terminating reply only."),
|
||||
SD_VARLINK_DEFINE_OUTPUT(slot, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The keyslots wiped as part of this call, if any."),
|
||||
SD_VARLINK_DEFINE_OUTPUT(wipedSlots, SD_VARLINK_INT, SD_VARLINK_ARRAY|SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The generated recovery key, when mechanism is 'recoveryKey'. Contains key material."),
|
||||
SD_VARLINK_DEFINE_OUTPUT(recoveryKey, SD_VARLINK_STRING, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("Progress indicator, only sent on intermediate replies when 'more' was set. Currently the only value is 'touch', signalling that the FIDO2 token is waiting for a touch. Unset on the terminating reply."),
|
||||
SD_VARLINK_DEFINE_OUTPUT(state, SD_VARLINK_STRING, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_METHOD_FULL(
|
||||
ListSlots,
|
||||
SD_VARLINK_REQUIRES_MORE,
|
||||
SD_VARLINK_FIELD_COMMENT("Path to the LUKS2 block device or image to operate on."),
|
||||
SD_VARLINK_DEFINE_INPUT(node, SD_VARLINK_STRING, 0),
|
||||
SD_VARLINK_FIELD_COMMENT("A currently enrolled keyslot index."),
|
||||
SD_VARLINK_DEFINE_OUTPUT(slot, SD_VARLINK_INT, SD_VARLINK_NULLABLE),
|
||||
SD_VARLINK_FIELD_COMMENT("The type of the keyslot."),
|
||||
SD_VARLINK_DEFINE_OUTPUT_BY_TYPE(type, EnrollMechanism, SD_VARLINK_NULLABLE));
|
||||
|
||||
static SD_VARLINK_DEFINE_ERROR(VolumeUnderForeignManagement);
|
||||
static SD_VARLINK_DEFINE_ERROR(PasswordRequired);
|
||||
static SD_VARLINK_DEFINE_ERROR(PasswordIncorrect);
|
||||
static SD_VARLINK_DEFINE_ERROR(FidoDeviceNotFound);
|
||||
static SD_VARLINK_DEFINE_ERROR(FidoActionTimeout);
|
||||
|
||||
SD_VARLINK_DEFINE_INTERFACE(
|
||||
io_systemd_CryptEnroll,
|
||||
"io.systemd.CryptEnroll",
|
||||
SD_VARLINK_INTERFACE_COMMENT("API for enrolling credentials into LUKS2 volumes via systemd-cryptenroll."),
|
||||
SD_VARLINK_SYMBOL_COMMENT("The credential types this interface knows about, used both as the enrollment mechanism and as the slot type reported by ListSlots."),
|
||||
&vl_type_EnrollMechanism,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Enroll a credential into a LUKS2 volume. When enrolling a FIDO2 token that requires user presence, the call must be made with the 'more' flag, so that the server can report when a touch is required via a 'touch' state notification."),
|
||||
&vl_method_Enroll,
|
||||
SD_VARLINK_SYMBOL_COMMENT("Enumerate the keyslots currently enrolled in a LUKS2 volume, one per reply. Must be called with the 'more' flag."),
|
||||
&vl_method_ListSlots,
|
||||
SD_VARLINK_SYMBOL_COMMENT("The volume is managed by another subsystem (e.g. systemd-homed) and may not be enrolled into directly."),
|
||||
&vl_error_VolumeUnderForeignManagement,
|
||||
SD_VARLINK_SYMBOL_COMMENT("A password is required to unlock the volume, but none was provided."),
|
||||
&vl_error_PasswordRequired,
|
||||
SD_VARLINK_SYMBOL_COMMENT("The provided password did not unlock the volume."),
|
||||
&vl_error_PasswordIncorrect,
|
||||
SD_VARLINK_SYMBOL_COMMENT("No matching FIDO2 device was found."),
|
||||
&vl_error_FidoDeviceNotFound,
|
||||
SD_VARLINK_SYMBOL_COMMENT("The FIDO2 token was not interacted with in time."),
|
||||
&vl_error_FidoActionTimeout);
|
||||
@@ -0,0 +1,6 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
#pragma once
|
||||
|
||||
#include "sd-varlink-idl.h"
|
||||
|
||||
extern const sd_varlink_interface vl_interface_io_systemd_CryptEnroll;
|
||||
Reference in New Issue
Block a user