summaryrefslogtreecommitdiff
path: root/src/cryptsetup
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-10-14 22:40:23 +0200
committerLennart Poettering <lennart@poettering.net>2015-10-19 23:13:07 +0200
commit1602b008531ba6e0c704588cb2643daef26b71d9 (patch)
tree20cfee002c72138337da1822654af4e9266f4937 /src/cryptsetup
parent0245cf8167d34e483955b90da7f5d5f154ca57ef (diff)
downloadsystemd-1602b008531ba6e0c704588cb2643daef26b71d9.tar.gz
tree-wide: whenever we deal with passwords, erase them from memory after use
A bit snake-oilish, but can't hurt.
Diffstat (limited to 'src/cryptsetup')
-rw-r--r--src/cryptsetup/cryptsetup.c71
1 files changed, 43 insertions, 28 deletions
diff --git a/src/cryptsetup/cryptsetup.c b/src/cryptsetup/cryptsetup.c
index cc03ad3ca8..c9be17446b 100644
--- a/src/cryptsetup/cryptsetup.c
+++ b/src/cryptsetup/cryptsetup.c
@@ -312,15 +312,16 @@ static char *disk_mount_point(const char *label) {
return NULL;
}
-static int get_password(const char *vol, const char *src, usec_t until, bool accept_cached, char ***passwords) {
+static int get_password(const char *vol, const char *src, usec_t until, bool accept_cached, char ***ret) {
_cleanup_free_ char *description = NULL, *name_buffer = NULL, *mount_point = NULL, *maj_min = NULL, *text = NULL, *escaped_name = NULL;
+ _cleanup_strv_free_ char **passwords = NULL, **passwords2 = NULL;
const char *name = NULL;
char **p, *id;
int r = 0;
assert(vol);
assert(src);
- assert(passwords);
+ assert(ret);
description = disk_description(src);
mount_point = disk_mount_point(vol);
@@ -360,57 +361,74 @@ static int get_password(const char *vol, const char *src, usec_t until, bool acc
id = strjoina("cryptsetup:", escaped_name);
- r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", until, ASK_PASSWORD_PUSH_CACHE|(accept_cached ? ASK_PASSWORD_ACCEPT_CACHED : 0), passwords);
+ r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", until, ASK_PASSWORD_PUSH_CACHE|(accept_cached ? ASK_PASSWORD_ACCEPT_CACHED : 0), &passwords);
if (r < 0)
return log_error_errno(r, "Failed to query password: %m");
if (arg_verify) {
- _cleanup_strv_free_ char **passwords2 = NULL;
+ assert(strv_length(passwords) == 1);
- assert(strv_length(*passwords) == 1);
-
- if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0)
- return log_oom();
+ if (asprintf(&text, "Please enter passphrase for disk %s! (verification)", name) < 0) {
+ r = log_oom();
+ goto finish;
+ }
id = strjoina("cryptsetup-verification:", escaped_name);
r = ask_password_auto(text, "drive-harddisk", id, "cryptsetup", until, ASK_PASSWORD_PUSH_CACHE, &passwords2);
- if (r < 0)
- return log_error_errno(r, "Failed to query verification password: %m");
+ if (r < 0) {
+ log_error_errno(r, "Failed to query verification password: %m");
+ goto finish;
+ }
assert(strv_length(passwords2) == 1);
- if (!streq(*passwords[0], passwords2[0])) {
+ if (!streq(passwords[0], passwords2[0])) {
log_warning("Passwords did not match, retrying.");
- return -EAGAIN;
+ r = -EAGAIN;
+ goto finish;
}
}
- strv_uniq(*passwords);
+ strv_uniq(passwords);
- STRV_FOREACH(p, *passwords) {
+ STRV_FOREACH(p, passwords) {
char *c;
if (strlen(*p)+1 >= arg_key_size)
continue;
/* Pad password if necessary */
- if (!(c = new(char, arg_key_size)))
- return log_oom();
+ c = new(char, arg_key_size);
+ if (!c) {
+ r = -ENOMEM;
+ goto finish;
+ }
strncpy(c, *p, arg_key_size);
free(*p);
*p = c;
}
- return 0;
+ *ret = passwords;
+ passwords = NULL;
+
+ r = 0;
+
+finish:
+ strv_erase(passwords);
+ strv_erase(passwords2);
+
+ return r;
}
-static int attach_tcrypt(struct crypt_device *cd,
- const char *name,
- const char *key_file,
- char **passwords,
- uint32_t flags) {
+static int attach_tcrypt(
+ struct crypt_device *cd,
+ const char *name,
+ const char *key_file,
+ char **passwords,
+ uint32_t flags) {
+
int r = 0;
_cleanup_free_ char *passphrase = NULL;
struct crypt_params_tcrypt params = {
@@ -520,8 +538,7 @@ static int attach_luks_or_plain(struct crypt_device *cd,
* it just configures encryption
* parameters when used for plain
* mode. */
- r = crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode,
- NULL, NULL, arg_keyfile_size, &params);
+ r = crypt_format(cd, CRYPT_PLAIN, cipher, cipher_mode, NULL, NULL, arg_keyfile_size, &params);
/* hash == NULL implies the user passed "plain" */
pass_volume_key = (params.hash == NULL);
@@ -537,9 +554,7 @@ static int attach_luks_or_plain(struct crypt_device *cd,
crypt_get_device_name(cd));
if (key_file) {
- r = crypt_activate_by_keyfile_offset(cd, name, arg_key_slot,
- key_file, arg_keyfile_size,
- arg_keyfile_offset, flags);
+ r = crypt_activate_by_keyfile_offset(cd, name, arg_key_slot, key_file, arg_keyfile_size, arg_keyfile_offset, flags);
if (r < 0) {
log_error_errno(r, "Failed to activate with key file '%s': %m", key_file);
return -EAGAIN;
@@ -631,7 +646,6 @@ int main(int argc, char *argv[]) {
k = crypt_init(&cd, arg_header);
} else
k = crypt_init(&cd, argv[3]);
-
if (k) {
log_error_errno(k, "crypt_init() failed: %m");
goto finish;
@@ -688,6 +702,7 @@ int main(int argc, char *argv[]) {
arg_header ? argv[3] : NULL,
passwords,
flags);
+ strv_erase(passwords);
if (k >= 0)
break;
else if (k == -EAGAIN) {