diff --git a/tests/ssh-plugin-test b/tests/ssh-plugin-test index 9a96f1e9..70f04be1 100755 --- a/tests/ssh-plugin-test +++ b/tests/ssh-plugin-test @@ -10,6 +10,7 @@ IMG="ssh_test.img" MAP="sshtest" USER="sshtest" PASSWD="sshtest" +PASSWD2="sshtest2" LOOPDEV=$(losetup -f 2>/dev/null) SSH_OPTIONS="-o StrictHostKeyChecking=no" @@ -93,11 +94,15 @@ format() echo $PASSWD | $CRYPTSETUP luksFormat --type luks2 $FAST_PBKDF_OPT $LOOPDEV --force-password -q [ $? -ne 0 ] && fail "Format failed." + + echo -e "$PASSWD\n$PASSWD2" | $CRYPTSETUP luksAddKey $FAST_PBKDF_OPT $LOOPDEV -q + [ $? -ne 0 ] && fail "Add key failed." } check_dump() { dump=$1 + keyslot=$2 token=$(echo "$dump" | grep Tokens -A 1 | tail -1 | cut -d: -f2 | tr -d "\t\n ") [ "$token" = "ssh" ] || fail " token check from dump failed." @@ -113,6 +118,9 @@ check_dump() key_path=$(echo "$dump" | grep ssh_key_path | cut -d: -f2 | tr -d "\t\n ") [ "$key_path" = "$SSH_KEY_PATH" ] || fail " key_path check from dump failed." + + keyslot_dump=$(echo "$dump" | grep Keyslot: | cut -d: -f2 | tr -d "\t\n ") + [ "$keyslot_dump" = "$keyslot" ] || fail " keyslot check from dump failed." } [ $(id -u) != 0 ] && skip "WARNING: You must be root to run this test, test skipped." @@ -138,7 +146,7 @@ $CRYPTSETUP_SSH add $LOOPDEV --ssh-server $SSH_SERVER --ssh-user $USER --ssh-pat [ $? -ne 0 ] && fail "Failed to add SSH token to $LOOPDEV" out=$($CRYPTSETUP luksDump $LOOPDEV) -check_dump "$out" +check_dump "$out" 0 echo "[OK]" echo -n "Activating using SSH token: " @@ -148,5 +156,17 @@ $CRYPTSETUP luksOpen -r $LOOPDEV $MAP -q >/dev/null 2>&1 <&- [ $? -ne 0 ] && fail "Failed to open $LOOPDEV using SSH token" echo "[OK]" +# Remove the newly added token and test adding with --key-slot +$CRYPTSETUP token remove --token-id 0 $LOOPDEV || fail "Failed to remove token" + +echo -n "Adding SSH token with --key-slot: " + +$CRYPTSETUP_SSH add $LOOPDEV --ssh-server $SSH_SERVER --ssh-user $USER --ssh-path $SSH_PATH --ssh-keypath $SSH_KEY_PATH --key-slot 1 +[ $? -ne 0 ] && fail "Failed to add SSH token to $LOOPDEV" + +out=$($CRYPTSETUP luksDump $LOOPDEV) +check_dump "$out" 1 +echo "[OK]" + remove_mapping remove_user diff --git a/tokens/ssh/cryptsetup-ssh.c b/tokens/ssh/cryptsetup-ssh.c index efdd0b5d..6e95c340 100644 --- a/tokens/ssh/cryptsetup-ssh.c +++ b/tokens/ssh/cryptsetup-ssh.c @@ -46,6 +46,7 @@ #define OPT_KEY_PATH 4 #define OPT_DEBUG 5 #define OPT_DEBUG_JSON 6 +#define OPT_KEY_SLOT 7 void tools_cleanup(void) { @@ -140,6 +141,8 @@ static struct argp_option options[] = { {"ssh-user", OPT_SSH_USER, "STRING", 0, "Username used for the remote server" }, {"ssh-path", OPT_SSH_PATH, "STRING", 0, "Path to the key file on the remote server"}, {"ssh-keypath", OPT_KEY_PATH, "STRING", 0, "Path to the SSH key for connecting to the remote server" }, + {"key-slot", OPT_KEY_SLOT, "NUM", 0, "Keyslot to assing the token to. If not specified, token will "\ + "be assigned to the first keyslot matching provided passphrase."}, {0, 0, 0, 0, "Generic options:" }, {"verbose", 'v', 0, 0, "Shows more detailed error messages"}, {"debug", OPT_DEBUG, 0, 0, "Show debug messages"}, @@ -154,6 +157,7 @@ struct arguments { char *ssh_user; char *ssh_path; char *ssh_keypath; + int keyslot; int verbose; int debug; int debug_json; @@ -176,6 +180,9 @@ parse_opt (int key, char *arg, struct argp_state *state) { case OPT_KEY_PATH: arguments->ssh_keypath = arg; break; + case OPT_KEY_SLOT: + arguments->keyslot = atoi(arg); + break; case 'v': arguments->verbose = 1; break; @@ -230,7 +237,7 @@ void _log(int level, const char *msg, void *usrptr) } } -static int get_keyslot_for_passphrase(struct arguments *arguments, const char *pin, int *keyslot) +static int get_keyslot_for_passphrase(struct arguments *arguments, const char *pin) { int r = 0; ssh_key pkey; @@ -271,7 +278,7 @@ static int get_keyslot_for_passphrase(struct arguments *arguments, const char *p } /* now try again with the password */ - r = get_keyslot_for_passphrase(arguments, ssh_pass, keyslot); + r = get_keyslot_for_passphrase(arguments, ssh_pass); crypt_safe_free(ssh_pass); crypt_free(cd); @@ -323,7 +330,7 @@ static int get_keyslot_for_passphrase(struct arguments *arguments, const char *p return r; } - *keyslot = r; + arguments->keyslot = r; crypt_safe_memzero(password, password_len); free(password); @@ -335,8 +342,8 @@ static int get_keyslot_for_passphrase(struct arguments *arguments, const char *p int main(int argc, char *argv[]) { int ret = 0; - int keyslot = 0; struct arguments arguments = { 0 }; + arguments.keyslot = CRYPT_ANY_SLOT; ret = argp_parse (&argp, argc, argv, 0, 0, &arguments); if (ret != 0) { @@ -381,10 +388,12 @@ int main(int argc, char *argv[]) return EXIT_FAILURE; } - ret = get_keyslot_for_passphrase(&arguments, NULL, &keyslot); - if (ret != 0) { - printf("Failed open %s using provided credentials.\n", arguments.device); - return EXIT_FAILURE; + if (arguments.keyslot == CRYPT_ANY_SLOT) { + ret = get_keyslot_for_passphrase(&arguments, NULL); + if (ret != 0) { + printf("Failed open %s using provided credentials.\n", arguments.device); + return EXIT_FAILURE; + } } return token_add(arguments.device, @@ -392,7 +401,7 @@ int main(int argc, char *argv[]) arguments.ssh_user, arguments.ssh_path, arguments.ssh_keypath, - keyslot); + arguments.keyslot); } else { printf("Only 'add' action is currently supported by this plugin.\n"); return EXIT_FAILURE;