diff --git a/man/cryptsetup.8 b/man/cryptsetup.8 index 7d356491..c54480ac 100644 --- a/man/cryptsetup.8 +++ b/man/cryptsetup.8 @@ -129,8 +129,8 @@ to unlock a keyslot (LUKS) or to derive a volume key again (plain mode). The kernel keyring is used by default for LUKS2 devices. With LUKS2 device additional \fB\fR can be [\-\-token\-id, \-\-token\-only, -\-\-key\-slot, \-\-key\-file, \-\-keyfile\-size, \-\-keyfile\-offset, \-\-timeout, -\-\-disable\-external\-tokens, \-\-disable\-locks, \-\-disable\-keyring]. +\-\-token-type, \-\-key\-slot, \-\-key\-file, \-\-keyfile\-size, \-\-keyfile\-offset, +\-\-timeout, \-\-disable\-external\-tokens, \-\-disable\-locks, \-\-disable\-keyring]. .PP \fIrefresh\fR @@ -320,8 +320,8 @@ the command prompts for it interactively. \fB\fR can be [\-\-key\-file, \-\-keyfile\-offset, \-\-keyfile\-size, \-\-readonly, \-\-test\-passphrase, \-\-allow\-discards, \-\-header, \-\-key-slot, \-\-master\-key\-file, \-\-token\-id, -\-\-token\-only, \-\-disable\-external\-tokens, \-\-disable\-keyring, \-\-disable\-locks, -\-\-type, \-\-refresh, \-\-serialize\-memory\-hard\-pbkdf]. +\-\-token\-only, \-\-token-type, \-\-disable\-external\-tokens, \-\-disable\-keyring, +\-\-disable\-locks, \-\-type, \-\-refresh, \-\-serialize\-memory\-hard\-pbkdf]. .PP \fIluksSuspend\fR .IP @@ -1349,6 +1349,10 @@ Do not proceed further with action (any of \fItoken\fR, \fIopen\fR or \fIresize\fR) if token activation failed. Without the option, action asks for passphrase to proceed further. .TP +.B "\-\-token\-type" +Restrict tokens eligible for operation to specific token type (name). Mostly +useful when no \-\-token\-id is specified. +.TP .B "\-\-sector\-size " Set sector size for use with disk encryption. It must be power of two and in range 512 - 4096 bytes. This option is available only in the LUKS2 diff --git a/src/cryptsetup.c b/src/cryptsetup.c index 87c80c89..792146ea 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -792,13 +792,14 @@ static int action_resize(void) } /* try load VK in kernel keyring using token */ - r = crypt_activate_by_token(cd, NULL, ARG_INT32(OPT_TOKEN_ID_ID), NULL, - CRYPT_ACTIVATE_KEYRING_KEY); + r = crypt_activate_by_token_pin(cd, NULL, ARG_STR(OPT_TOKEN_TYPE_ID), + ARG_INT32(OPT_TOKEN_ID_ID), NULL, 0, NULL, + CRYPT_ACTIVATE_KEYRING_KEY); tools_keyslot_msg(r, UNLOCKED); /* Token requires PIN, but ask only if there is no password query later */ if (ARG_SET(OPT_TOKEN_ONLY_ID) && r == -ENOANO) - r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID), NULL, NULL, CRYPT_ACTIVATE_KEYRING_KEY, 1); + r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID), NULL, ARG_STR(OPT_TOKEN_TYPE_ID), CRYPT_ACTIVATE_KEYRING_KEY, 1); if (r >= 0 || ARG_SET(OPT_TOKEN_ONLY_ID)) goto out; @@ -1576,12 +1577,13 @@ static int action_open_luks(void) r = crypt_activate_by_volume_key(cd, activated_name, key, keysize, activate_flags); } else { - r = crypt_activate_by_token(cd, activated_name, ARG_INT32(OPT_TOKEN_ID_ID), NULL, activate_flags); + r = crypt_activate_by_token_pin(cd, activated_name, ARG_STR(OPT_TOKEN_TYPE_ID), + ARG_INT32(OPT_TOKEN_ID_ID), NULL, 0, NULL, activate_flags); tools_keyslot_msg(r, UNLOCKED); /* Token requires PIN, but ask only if there is no password query later */ if (ARG_SET(OPT_TOKEN_ONLY_ID) && r == -ENOANO) - r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID), activated_name, NULL, activate_flags, _set_tries_tty()); + r = _try_token_pin_unlock(cd, ARG_INT32(OPT_TOKEN_ID_ID), activated_name, ARG_STR(OPT_TOKEN_TYPE_ID), activate_flags, _set_tries_tty()); if (r >= 0 || ARG_SET(OPT_TOKEN_ONLY_ID)) goto out; diff --git a/src/cryptsetup_arg_list.h b/src/cryptsetup_arg_list.h index ba80de22..491fe8f6 100644 --- a/src/cryptsetup_arg_list.h +++ b/src/cryptsetup_arg_list.h @@ -175,6 +175,8 @@ ARG(OPT_TOKEN_ID, '\0', POPT_ARG_STRING, N_("Token number (default: any)"), "INT ARG(OPT_TOKEN_ONLY, '\0', POPT_ARG_NONE, N_("Do not ask for passphrase if activation by token fails"), NULL, CRYPT_ARG_BOOL, {}, {}) +ARG(OPT_TOKEN_TYPE, '\0', POPT_ARG_STRING, N_("Restrict allowed token types used to retrieve LUKS2 key"), NULL, CRYPT_ARG_STRING, {}, {}) + ARG(OPT_TRIES, 'T', POPT_ARG_STRING, N_("How often the input of the passphrase can be retried"), "INT", CRYPT_ARG_UINT32, { .u32_value = 3 }, {}) ARG(OPT_TYPE, 'M', POPT_ARG_STRING, N_("Type of device metadata: luks, luks1, luks2, plain, loopaes, tcrypt, bitlk"), NULL, CRYPT_ARG_STRING, {}, {}) diff --git a/src/utils_arg_names.h b/src/utils_arg_names.h index b6865c06..d536d571 100644 --- a/src/utils_arg_names.h +++ b/src/utils_arg_names.h @@ -144,6 +144,7 @@ #define OPT_TIMEOUT "timeout" #define OPT_TOKEN_ID "token-id" #define OPT_TOKEN_ONLY "token-only" +#define OPT_TOKEN_TYPE "token-type" #define OPT_TRIES "tries" #define OPT_TYPE "type" #define OPT_UNBOUND "unbound" diff --git a/tests/compat-test2 b/tests/compat-test2 index c1d33242..26884a64 100755 --- a/tests/compat-test2 +++ b/tests/compat-test2 @@ -851,6 +851,14 @@ if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then $CRYPTSETUP open --token-only $LOOPDEV $DEV_NAME || fail $CRYPTSETUP status $DEV_NAME > /dev/null || fail $CRYPTSETUP close $DEV_NAME || fail + + # check --token-type sort of works (TODO: extend tests when native systemd tokens are available) + echo -n "$IMPORT_TOKEN" | $CRYPTSETUP token import $LOOPDEV --token-id 22 || fail + # this excludes keyring tokens from unlocking device + $CRYPTSETUP open --token-only --token-type some_type $LOOPDEV --test-passphrase && fail + $CRYPTSETUP open --token-only --token-type some_type $LOOPDEV $DEV_NAME && fail + $CRYPTSETUP status $DEV_NAME > /dev/null && fail + $CRYPTSETUP token remove --token-id 3 $LOOPDEV || fail $CRYPTSETUP luksDump $LOOPDEV | grep -q -e "3: luks2-keyring" && fail