Skip to content

Commit

Permalink
Add tests for device activation using multiple VKs.
Browse files Browse the repository at this point in the history
  • Loading branch information
danzatt authored and mbroz committed Jan 16, 2024
1 parent dc7006d commit 98d9473
Show file tree
Hide file tree
Showing 3 changed files with 273 additions and 7 deletions.
150 changes: 148 additions & 2 deletions tests/api-test-2.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ typedef int32_t key_serial_t;
#define TEST_KEY_VK_LOGON "cs_api_test_prefix:api_test_logon_vk1"
#define TEST_KEY_VK_LOGON_NAME "\%logon:" TEST_KEY_VK_LOGON
#define TEST_KEY_VK_USER2 "api_test_user_vk2"
#define TEST_KEY_VK_USER2_NAME "\%user:" TEST_KEY_VK_USER
#define TEST_KEY_VK_USER2_NAME "\%user:" TEST_KEY_VK_USER2
#define TEST_KEY_VK_LOGON2 "cs_api_test_prefix:api_test_logon_vk2"
#define TEST_KEY_VK_LOGON2_NAME "\%logon:" TEST_KEY_VK_LOGON

Expand Down Expand Up @@ -5267,7 +5267,7 @@ static void KeyslotContextAndKeyringLink(void)
#ifdef KERNEL_KEYRING
const char *cipher = "aes";
const char *cipher_mode = "xts-plain64";
struct crypt_keyslot_context *kc;
struct crypt_keyslot_context *kc, *kc2;
uint64_t r_payload_offset;
char key[128];
size_t key_size = 128;
Expand Down Expand Up @@ -5318,6 +5318,7 @@ static void KeyslotContextAndKeyringLink(void)
NOTFAIL_(keyring_in_session_id, "Test or kernel keyring are broken.");

// test passphrase
EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, NULL, CRYPT_ANY_SLOT, NULL, 0), -EINVAL);
OK_(crypt_keyslot_context_init_by_passphrase(cd, PASSPHRASE, strlen(PASSPHRASE), &kc));
EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), 0);
crypt_keyslot_context_free(kc);
Expand Down Expand Up @@ -5570,8 +5571,153 @@ static void KeyslotContextAndKeyringLink(void)
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 0);
NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
FAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "VK was not linked to custom keyring.");
OK_(crypt_deactivate(cd, CDEVICE_1));
CRYPT_FREE(cd);

// Reenncryption: test reactivation using linked keys
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "cbc-essiv:sha256", NULL, NULL, 32, &params2));
OK_(crypt_set_pbkdf_type(cd, &pbkdf));
EQ_(crypt_keyslot_add_by_volume_key(cd, 1, NULL, 64, PASSPHRASE, strlen(PASSPHRASE)), 1);
EQ_(crypt_keyslot_add_by_key(cd, 0, NULL, 32, PASSPHRASE, strlen(PASSPHRASE), CRYPT_VOLUME_KEY_NO_SEGMENT), 0);
rparams.flags = CRYPT_REENCRYPT_INITIALIZE_ONLY;

EQ_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 1, 0, "aes", "xts-plain64", &rparams), 2);
EQ_(crypt_set_keyring_to_link(cd, TEST_KEY_VK_USER, TEST_KEY_VK_USER2, "user", keyring_in_user_str_id), 0);
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 0);
NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
NOTFAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "VK was not linked to custom keyring.");
OK_(crypt_deactivate(cd, CDEVICE_1));
OK_(crypt_keyslot_context_init_by_vk_in_keyring(cd, TEST_KEY_VK_USER_NAME , &kc));
OK_(crypt_keyslot_context_init_by_vk_in_keyring(cd, TEST_KEY_VK_USER2_NAME, &kc2));

EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0), -ENOKEY);
EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc2, CRYPT_ANY_SLOT, NULL, 0), -ENOKEY);
EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, NULL, CRYPT_ANY_SLOT, kc, 0), -EINVAL);
EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, NULL, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);

EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
OK_(crypt_deactivate(cd, CDEVICE_1));

OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_user_id, "user"));
OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER2, keyring_in_user_id, "user"));
EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);

EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 0);
NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
NOTFAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "VK was not linked to custom keyring.");
OK_(crypt_deactivate(cd, CDEVICE_1));

EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
OK_(crypt_deactivate(cd, CDEVICE_1));
GE_((vk_len = keyctl_read(linked_kid, vk_buf, sizeof(vk_buf))), 0);
vk_buf[0] = ~vk_buf[0];
OK_(keyctl_update(linked_kid, vk_buf, vk_len));
EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);

OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_user_id, "user"));
OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER2, keyring_in_user_id, "user"));
CRYPT_FREE(cd);

// Decryption: test reactivation using linked keys
OK_(crypt_init(&cd, DMDIR L_DEVICE_OK));
OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "cbc-essiv:sha256", NULL, NULL, 32, &params2));
OK_(crypt_set_pbkdf_type(cd, &pbkdf));
EQ_(crypt_keyslot_add_by_volume_key(cd, 1, NULL, 64, PASSPHRASE, strlen(PASSPHRASE)), 1);
rparams.flags = CRYPT_REENCRYPT_INITIALIZE_ONLY;
rparams.mode = CRYPT_REENCRYPT_DECRYPT;
EQ_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), 1, CRYPT_ANY_SLOT, NULL, NULL, &rparams), 0);
EQ_(crypt_set_keyring_to_link(cd, TEST_KEY_VK_USER, TEST_KEY_VK_USER2, "user", keyring_in_user_str_id), 0);
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 1);
NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
FAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "second VK was linked to custom keyring.");
OK_(crypt_deactivate(cd, CDEVICE_1));

OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0));
OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc, 0));
// lazy evaluation, if the first context supplies key and only one key is required, the second (invalid) context is not invoked
OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0));
// first context takes precedence, if t fails, the second is not tried
EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc2, CRYPT_ANY_SLOT, kc, 0), -EINVAL);

EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
OK_(crypt_deactivate(cd, CDEVICE_1));

OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_user_id, "user"));
EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);

EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 1);
NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
FAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "VK was not linked to custom keyring.");
OK_(crypt_deactivate(cd, CDEVICE_1));

EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
OK_(crypt_deactivate(cd, CDEVICE_1));
GE_((vk_len = keyctl_read(linked_kid, vk_buf, sizeof(vk_buf))), 0);
vk_buf[0] = ~vk_buf[0];
OK_(keyctl_update(linked_kid, vk_buf, vk_len));
EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);

OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_user_id, "user"));
CRYPT_FREE(cd);

// Encryption: test reactivation using linked keys
_cleanup_dmdevices();
OK_(create_dmdevice_over_loop(H_DEVICE, r_header_size));
OK_(create_dmdevice_over_loop(L_DEVICE_OK, 12*1024*2));

OK_(crypt_init(&cd, DMDIR H_DEVICE));

memset(&rparams, 0, sizeof(rparams));
params2.sector_size = 512;
params2.data_device = DMDIR L_DEVICE_OK;
rparams.mode = CRYPT_REENCRYPT_ENCRYPT;
rparams.luks2 = &params2;
rparams.flags = CRYPT_REENCRYPT_INITIALIZE_ONLY;
rparams.resilience = "checksum";
rparams.hash = "sha256";
OK_(crypt_format(cd, CRYPT_LUKS2, "aes", "xts-plain64", NULL, NULL, 64, &params2));
EQ_(crypt_keyslot_add_by_volume_key(cd, 1, NULL, 64, PASSPHRASE, strlen(PASSPHRASE)), 1);
EQ_(crypt_reencrypt_init_by_passphrase(cd, NULL, PASSPHRASE, strlen(PASSPHRASE), CRYPT_ANY_SLOT, 1, "aes", "xts-plain64", &rparams), 0);

EQ_(crypt_set_keyring_to_link(cd, TEST_KEY_VK_USER, TEST_KEY_VK_USER2, "user", keyring_in_user_str_id), 0);
EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 1);
NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
FAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "second VK was linked to custom keyring.");
OK_(crypt_deactivate(cd, CDEVICE_1));

OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, NULL, 0));
OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc, 0));
// lazy evaluation, if the first context supplies key and only one key is required, the second (invalid) context is not invoked
OK_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0));
// first context takes precedence, if t fails, the second is not tried
EQ_(crypt_activate_by_keyslot_context(cd, NULL, CRYPT_ANY_SLOT, kc2, CRYPT_ANY_SLOT, kc, 0), -EINVAL);

EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
OK_(crypt_deactivate(cd, CDEVICE_1));

OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_user_id, "user"));
EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);

EQ_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, PASSPHRASE, strlen(PASSPHRASE), 0), 1);
NOTFAIL_((linked_kid = request_key("user", TEST_KEY_VK_USER, NULL, 0)), "VK was not linked to custom keyring.");
FAIL_((linked_kid2 = request_key("user", TEST_KEY_VK_USER2, NULL, 0)), "VK was not linked to custom keyring.");
OK_(crypt_deactivate(cd, CDEVICE_1));

EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), 0);
OK_(crypt_deactivate(cd, CDEVICE_1));
GE_((vk_len = keyctl_read(linked_kid, vk_buf, sizeof(vk_buf))), 0);
vk_buf[0] = ~vk_buf[0];
OK_(keyctl_update(linked_kid, vk_buf, vk_len));
EQ_(crypt_activate_by_keyslot_context(cd, CDEVICE_1, CRYPT_ANY_SLOT, kc, CRYPT_ANY_SLOT, kc2, 0), -EINVAL);

OK_(_drop_keyring_key_from_keyring_name(TEST_KEY_VK_USER, keyring_in_user_id, "user"));
CRYPT_FREE(cd);

crypt_keyslot_context_free(kc);
crypt_keyslot_context_free(kc2);

_cleanup_dmdevices();
#else
printf("WARNING: cryptsetup compiled with kernel keyring service disabled, skipping test.\n");
Expand Down
58 changes: 53 additions & 5 deletions tests/compat-test2
Original file line number Diff line number Diff line change
Expand Up @@ -316,7 +316,7 @@ test_vk_link() {

echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME || fail
keyctl search "$2" $KEY_TYPE $1 > /dev/null 2>&1 && fail "VK is linked to the specified keyring before resume with linking."
$CRYPTSETUP luksSuspend $DEV_NAME || fail
$CRYPTSETUP luksSuspend $DEV_NAME || fail
echo $PWD1 | $CRYPTSETUP luksResume $DEV_NAME --link-vk-to-keyring "$2"::"$KEY_DESC" || fail
keyctl search "$2" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after activation."
$CRYPTSETUP close $DEV_NAME
Expand Down Expand Up @@ -392,6 +392,44 @@ test_reencrypt_vk_link() {
keyctl unlink $KEYCTL_KEY_NAME2 "$3" || fail
}

# $1 first key name
# $2 second key name
# $3 keyring to link VK to
# $4 key type (optional)
test_reencrypt_vk_link_and_reactivate() {
KEY_TYPE=${4:-user}
if [ -z "$4" ]; then
KEY_DESC=$1
else
KEY_DESC="%$4:$1"
fi
if [ -z "$4" ]; then
KEY_DESC2=$2
else
KEY_DESC2="%$4:$2"
fi

KEYCTL_KEY_NAME="%$KEY_TYPE:$1"
KEYCTL_KEY_NAME2="%$KEY_TYPE:$2"

echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "$3"::"$KEY_DESC" --link-vk-to-keyring "$3"::"$KEY_DESC2" || fail
keyctl search "$3" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after activation."

keyctl search "$3" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after activation."
keyctl search "$3" $KEY_TYPE $2 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after activation."
$CRYPTSETUP close $DEV_NAME || fail
keyctl search "$3" $KEY_TYPE $1 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after deactivation."
keyctl search "$3" $KEY_TYPE $2 > /dev/null 2>&1 || fail "VK is not linked to the specified keyring after deactivation."

echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --volume-key-keyring "$KEY_DESC" --volume-key-keyring "$KEY_DESC2" || fail
$CRYPTSETUP close $DEV_NAME || fail

keyctl unlink $KEYCTL_KEY_NAME "$3" || fail
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --volume-key-keyring "$KEY_DESC" --volume-key-keyring "$KEY_DESC2" > /dev/null 2>&1 && fail
keyctl unlink $KEYCTL_KEY_NAME2 "$3" || fail
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --volume-key-keyring "$KEY_DESC" --volume-key-keyring "$KEY_DESC2" > /dev/null 2>&1 && fail
}

function expect_run()
{
export INFOSTRING="$(basename ${BASH_SOURCE[1]})-line-${BASH_LINENO[0]}"
Expand Down Expand Up @@ -1457,13 +1495,13 @@ if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@t::%blah:$KEY_NAME" > /dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@t::%userlogon:$KEY_NAME" > /dev/null 2>&1 && fail

# test that only one VK name is used, when the device is not in reencryption
# test that only one VK name is used, when the device is not in reencryption
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@u::%user:$KEY_NAME" --link-vk-to-keyring "@u::%user:$KEY_NAME2" > /dev/null 2>&1 || fail
keyctl unlink "%user:$KEY_NAME" @u || fail
keyctl unlink "%user:$KEY_NAME2" @u > /dev/null 2>&1 && fail
$CRYPTSETUP close $DEV_NAME || fail

# test linkning multiple VKs during reencryption
# test linkning multiple VKs during reencryption
echo $PWD1 | $CRYPTSETUP -q reencrypt $LOOPDEV --init-only

test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "@u"
Expand All @@ -1477,12 +1515,22 @@ if [ $HAVE_KEYRING -gt 0 -a -d /proc/sys/kernel/keys ]; then
# explicitly specify keyring key type
test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "%keyring:$TEST_KEYRING_NAME"

# the keyring and key type have to be the same for both keys
test_reencrypt_vk_link_and_reactivate $KEY_NAME $KEY_NAME2 "@u"
test_reencrypt_vk_link_and_reactivate $KEY_NAME $KEY_NAME2 "@u" "user"
[[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_reencrypt_vk_link_and_reactivate $KEY_NAME $KEY_NAME2 "@s"
[[ ! -z "$SESSION_KEYRING_WORKS" ]] && test_reencrypt_vk_link_and_reactivate $KEY_NAME $KEY_NAME2 "@s" "user"
test_reencrypt_vk_link_and_reactivate $KEY_NAME $KEY_NAME2 "%:$TEST_KEYRING_NAME"
test_reencrypt_vk_link_and_reactivate $KEY_NAME $KEY_NAME2 "%:$TEST_KEYRING_NAME" "user"

# explicitly specify keyring key type
test_reencrypt_vk_link $KEY_NAME $KEY_NAME2 "%keyring:$TEST_KEYRING_NAME"

# the keyring and key type have to be the same for both keys
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@s::%user:$KEY_NAME" --link-vk-to-keyring "@u::%user:$KEY_NAME2" > /dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@u::%logon:$KEY_NAME" --link-vk-to-keyring "@u::%user:$KEY_NAME2" > /dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@s::%logon:$KEY_NAME" --link-vk-to-keyring "@u::%user:$KEY_NAME2" > /dev/null 2>&1 && fail

# supply one/three key name(s) when two names are required
# supply one/three key name(s) when two names are required
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@s::%logon:$KEY_NAME" > /dev/null 2>&1 && fail
echo $PWD1 | $CRYPTSETUP open $LOOPDEV $DEV_NAME --link-vk-to-keyring "@s::%logon:$KEY_NAME" --link-vk-to-keyring "@s::%logon:$KEY_NAME2" --link-vk-to-keyring "@s::%logon:$KEY_NAME3" > /dev/null 2>&1 && fail
fi
Expand Down
Loading

0 comments on commit 98d9473

Please sign in to comment.