diff --git a/lib/libcryptsetup.h b/lib/libcryptsetup.h index 11340e14..3f6e3cbe 100644 --- a/lib/libcryptsetup.h +++ b/lib/libcryptsetup.h @@ -1145,7 +1145,11 @@ int crypt_keyfile_read(struct crypt_device *cd, const char *keyfile, char **key, size_t *key_size_read, size_t keyfile_offset, - size_t keyfile_size_max); + size_t keyfile_size_max, + uint32_t flags +); +/** No on-disk header (only hashes) */ +#define CRYPT_KEYFILE_STOP_EOL (1 << 0) #ifdef __cplusplus } diff --git a/lib/setup.c b/lib/setup.c index fa0a04bc..bf24f50c 100644 --- a/lib/setup.c +++ b/lib/setup.c @@ -1545,7 +1545,7 @@ int crypt_resume_by_keyfile_offset(struct crypt_device *cd, r = crypt_keyfile_read(cd, keyfile, &passphrase_read, &passphrase_size_read, - keyfile_offset, keyfile_size); + keyfile_offset, keyfile_size, 0); if (r < 0) goto out; @@ -1729,7 +1729,7 @@ int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd, } else { r = crypt_keyfile_read(cd, keyfile, &password, &passwordLen, - keyfile_offset, keyfile_size); + keyfile_offset, keyfile_size, 0); if (r < 0) goto out; @@ -1742,7 +1742,7 @@ int crypt_keyslot_add_by_keyfile_offset(struct crypt_device *cd, r = crypt_keyfile_read(cd, new_keyfile, &new_password, &new_passwordLen, - new_keyfile_offset, new_keyfile_size); + new_keyfile_offset, new_keyfile_size, 0); if (r < 0) goto out; @@ -1931,7 +1931,7 @@ int crypt_activate_by_keyfile_offset(struct crypt_device *cd, r = crypt_keyfile_read(cd, keyfile, &passphrase_read, &passphrase_size_read, - keyfile_offset, keyfile_size); + keyfile_offset, keyfile_size, 0); if (r < 0) goto out; @@ -1945,7 +1945,7 @@ int crypt_activate_by_keyfile_offset(struct crypt_device *cd, } else if (isLUKS(cd->type)) { r = crypt_keyfile_read(cd, keyfile, &passphrase_read, &passphrase_size_read, - keyfile_offset, keyfile_size); + keyfile_offset, keyfile_size, 0); if (r < 0) goto out; r = LUKS_open_key_with_hdr(keyslot, passphrase_read, @@ -1963,7 +1963,7 @@ int crypt_activate_by_keyfile_offset(struct crypt_device *cd, } else if (isLOOPAES(cd->type)) { r = crypt_keyfile_read(cd, keyfile, &passphrase_read, &passphrase_size_read, - keyfile_offset, keyfile_size); + keyfile_offset, keyfile_size, 0); if (r < 0) goto out; r = LOOPAES_parse_keyfile(cd, &vk, cd->u.loopaes.hdr.hash, &key_count, diff --git a/lib/utils_crypt.c b/lib/utils_crypt.c index a9b01eca..866ccb0c 100644 --- a/lib/utils_crypt.c +++ b/lib/utils_crypt.c @@ -194,7 +194,8 @@ static int keyfile_seek(int fd, size_t bytes) int crypt_keyfile_read(struct crypt_device *cd, const char *keyfile, char **key, size_t *key_size_read, - size_t keyfile_offset, size_t keyfile_size_max) + size_t keyfile_offset, size_t keyfile_size_max, + uint32_t flags) { int fd, regular_file, char_read, unlimited_read = 0; int r = -EINVAL, newline; @@ -226,7 +227,7 @@ int crypt_keyfile_read(struct crypt_device *cd, const char *keyfile, /* use 4k for buffer (page divisor but avoid huge pages) */ buflen = 4096 - sizeof(struct safe_allocation); regular_file = 0; - if(fd != STDIN_FILENO) { + if (keyfile) { if(stat(keyfile, &st) < 0) { log_err(cd, _("Failed to stat key file.\n")); goto out_err; @@ -281,7 +282,7 @@ int crypt_keyfile_read(struct crypt_device *cd, const char *keyfile, /* Stop on newline only if not requested read from keyfile */ if (char_read == 0) break; - if (!keyfile && pass[i] == '\n') { + if ((flags & CRYPT_KEYFILE_STOP_EOL) && pass[i] == '\n') { newline = 1; pass[i] = '\0'; break; diff --git a/src/cryptsetup.c b/src/cryptsetup.c index db51036b..76763ff1 100644 --- a/src/cryptsetup.c +++ b/src/cryptsetup.c @@ -761,6 +761,8 @@ static int action_open_luks(void) char *key = NULL; uint32_t activate_flags = 0; int r, keysize; + char *password = NULL; + size_t passwordLen; header_device = uuid_or_device_header(&data_device); @@ -794,15 +796,19 @@ static int action_open_luks(void) goto out; r = crypt_activate_by_volume_key(cd, activated_name, key, keysize, activate_flags); - } else if (opt_key_file) { - r = crypt_activate_by_keyfile_offset(cd, activated_name, - opt_key_slot, opt_key_file, opt_keyfile_size, - opt_keyfile_offset, activate_flags); - } else + } else { + r = tools_get_key(NULL, &password, &passwordLen, + opt_keyfile_offset, opt_keyfile_size, opt_key_file, + opt_timeout, _verify_passphrase(0), 0, cd); + if (r < 0) + goto out; + r = crypt_activate_by_passphrase(cd, activated_name, - opt_key_slot, NULL, 0, activate_flags); + opt_key_slot, password, passwordLen, activate_flags); + } out: crypt_safe_free(key); + crypt_safe_free(password); crypt_free(cd); return r; } @@ -1214,18 +1220,25 @@ static int action_luksSuspend(void) static int action_luksResume(void) { struct crypt_device *cd = NULL; + char *password = NULL; + size_t passwordLen; int r; if ((r = crypt_init_by_name_and_header(&cd, action_argv[0], uuid_or_device(opt_header_device)))) goto out; - if (opt_key_file) - r = crypt_resume_by_keyfile_offset(cd, action_argv[0], CRYPT_ANY_SLOT, - opt_key_file, opt_keyfile_size, opt_keyfile_offset); - else - r = crypt_resume_by_passphrase(cd, action_argv[0], CRYPT_ANY_SLOT, - NULL, 0); + if ((r = crypt_load(cd, CRYPT_LUKS1, NULL))) + goto out; + + r = tools_get_key(NULL, &password, &passwordLen, + opt_keyfile_offset, opt_keyfile_size, opt_key_file, + opt_timeout, _verify_passphrase(0), 0, cd); + if (r) + goto out; + + r = crypt_resume_by_passphrase(cd, action_argv[0], CRYPT_ANY_SLOT, password, passwordLen); out: + crypt_safe_free(password); crypt_free(cd); return r; } diff --git a/src/utils_password.c b/src/utils_password.c index 84463b58..d315bbcb 100644 --- a/src/utils_password.c +++ b/src/utils_password.c @@ -257,15 +257,21 @@ static int crypt_get_key(const char *prompt, struct crypt_device *cd) { int read_stdin; + uint32_t flags = 0; /* Passphrase read from stdin? */ read_stdin = (!key_file || !strcmp(key_file, "-")) ? 1 : 0; + if (!key_file) + flags |= CRYPT_KEYFILE_STOP_EOL; if (read_stdin && isatty(STDIN_FILENO)) { if (keyfile_offset) { log_err(_("Cannot use offset with terminal input.\n")); return -EINVAL; } + //FIXME:if (!prompt) "Enter passphrase for %s: " + if (!prompt) + prompt = "Enter passphrase:"; return crypt_get_key_tty(prompt, key, key_size, timeout, verify, cd); } @@ -274,7 +280,7 @@ static int crypt_get_key(const char *prompt, else log_dbg("File descriptor passphrase entry requested."); - return crypt_keyfile_read(cd, key_file, key, key_size, keyfile_offset, keyfile_size_max); + return crypt_keyfile_read(cd, read_stdin ? NULL : key_file, key, key_size, keyfile_offset, keyfile_size_max, flags); } int tools_get_key(const char *prompt,