Detect old dm-crypt module and disable LUKS suspend/resume.

Fix apitest to work on older systems.

git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@205 36d66b0a-2a48-0410-832c-cd162a569da5
This commit is contained in:
Milan Broz
2010-04-30 12:03:41 +00:00
parent 346e1d1264
commit 1dcd5a3de5
4 changed files with 103 additions and 8 deletions

View File

@@ -1,3 +1,8 @@
2010-04-30 Milan Broz <mbroz@redhat.com>
* Try to use pkgconfig for device mapper library.
* Detect old dm-crypt module and disable LUKS suspend/resume.
* Fix apitest to work on older systems.
2010-04-12 Milan Broz <mbroz@redhat.com> 2010-04-12 Milan Broz <mbroz@redhat.com>
* Fix package config to use proper package version. * Fix package config to use proper package version.
* Avoid class C++ keyword in library header. * Avoid class C++ keyword in library header.

View File

@@ -18,6 +18,8 @@
#define DM_CRYPT_TARGET "crypt" #define DM_CRYPT_TARGET "crypt"
#define RETRY_COUNT 5 #define RETRY_COUNT 5
static int _dm_crypt_wipe_key_supported = 0;
static int _dm_use_count = 0; static int _dm_use_count = 0;
static struct crypt_device *_context = NULL; static struct crypt_device *_context = NULL;
@@ -61,16 +63,63 @@ static void set_dm_error(int level, const char *file, int line,
static int _dm_simple(int task, const char *name, int udev_wait); static int _dm_simple(int task, const char *name, int udev_wait);
static void _dm_set_crypt_compat(struct crypt_device *context,
int maj, int min, int patch)
{
log_dbg("Detected dm-crypt target of version %i.%i.%i.", maj, min, patch);
if (maj >= 1 && min >=2)
_dm_crypt_wipe_key_supported = 1;
else
log_dbg("Suspend and resume disabled, no wipe key support.");
}
static int _dm_check_versions(struct crypt_device *context)
{
int r = 0;
struct dm_task *dmt;
struct dm_versions *target, *last_target;
if (!(dmt = dm_task_create(DM_DEVICE_LIST_VERSIONS)))
goto fail_versions;
if (!dm_task_run(dmt)) {
dm_task_destroy(dmt);
goto fail_versions;
}
target = dm_task_get_versions(dmt);
do {
last_target = target;
if (!strcmp(DM_CRYPT_TARGET, target->name)) {
r = 1;
_dm_set_crypt_compat(context,
(int)target->version[0],
(int)target->version[1],
(int)target->version[2]);
}
target = (void *) target + target->next;
} while (last_target != target);
if (!r)
log_err(context, _("Cannot find compatible device-mapper kernel modules.\n"));
dm_task_destroy(dmt);
return r;
fail_versions:
log_err(context, _("Cannot initialize device-mapper. Is dm_mod kernel module loaded?\n"));
return 0;
}
int dm_init(struct crypt_device *context, int check_kernel) int dm_init(struct crypt_device *context, int check_kernel)
{ {
if (!_dm_use_count++) { if (!_dm_use_count++) {
log_dbg("Initialising device-mapper backend%s, UDEV is %sabled.", log_dbg("Initialising device-mapper backend%s, UDEV is %sabled.",
check_kernel ? "" : " (NO kernel check requested)", check_kernel ? "" : " (NO kernel check requested)",
_dm_use_udev() ? "en" : "dis"); _dm_use_udev() ? "en" : "dis");
if (check_kernel && !_dm_simple(DM_DEVICE_LIST_VERSIONS, NULL, 0)) { if (check_kernel && !_dm_check_versions(context))
log_err(context, _("Cannot initialize device-mapper. Is dm_mod kernel module loaded?\n"));
return -1; return -1;
}
if (getuid() || geteuid()) if (getuid() || geteuid())
log_dbg(("WARNING: Running as a non-root user. Functionality may be unavailable.")); log_dbg(("WARNING: Running as a non-root user. Functionality may be unavailable."));
dm_log_init(set_dm_error); dm_log_init(set_dm_error);
@@ -665,6 +714,9 @@ static int _dm_message(const char *name, const char *msg)
int dm_suspend_and_wipe_key(const char *name) int dm_suspend_and_wipe_key(const char *name)
{ {
if (!_dm_crypt_wipe_key_supported)
return -ENOTSUP;
if (!_dm_simple(DM_DEVICE_SUSPEND, name, 0)) if (!_dm_simple(DM_DEVICE_SUSPEND, name, 0))
return -EINVAL; return -EINVAL;
@@ -684,6 +736,9 @@ int dm_resume_and_reinstate_key(const char *name,
char *msg; char *msg;
int r = 0; int r = 0;
if (!_dm_crypt_wipe_key_supported)
return -ENOTSUP;
msg = safe_alloc(msg_size); msg = safe_alloc(msg_size);
if (!msg) if (!msg)
return -ENOMEM; return -ENOMEM;

View File

@@ -1304,7 +1304,9 @@ int crypt_suspend(struct crypt_device *cd,
} }
r = dm_suspend_and_wipe_key(name); r = dm_suspend_and_wipe_key(name);
if (r) if (r == -ENOTSUP)
log_err(cd, "Suspend is not supported for device %s.\n", name);
else if (r)
log_err(cd, "Error during suspending device %s.\n", name); log_err(cd, "Error during suspending device %s.\n", name);
out: out:
if (!cd) if (!cd)
@@ -1348,7 +1350,9 @@ int crypt_resume_by_passphrase(struct crypt_device *cd,
if (r >= 0) { if (r >= 0) {
keyslot = r; keyslot = r;
r = dm_resume_and_reinstate_key(name, mk->keyLength, mk->key); r = dm_resume_and_reinstate_key(name, mk->keyLength, mk->key);
if (r) if (r == -ENOTSUP)
log_err(cd, "Resume is not supported for device %s.\n", name);
else if (r)
log_err(cd, "Error during resuming device %s.\n", name); log_err(cd, "Error during resuming device %s.\n", name);
} else } else
r = keyslot; r = keyslot;

View File

@@ -58,6 +58,8 @@ static int _verbose = 1;
static char global_log[4096]; static char global_log[4096];
static int global_lines = 0; static int global_lines = 0;
static int gcrypt_compatible = 0;
// Helpers // Helpers
static int _prepare_keyfile(const char *name, const char *passphrase) static int _prepare_keyfile(const char *name, const char *passphrase)
{ {
@@ -585,13 +587,19 @@ static void UseLuksDevice(void)
static void SuspendDevice(void) static void SuspendDevice(void)
{ {
int suspend_status;
struct crypt_device *cd; struct crypt_device *cd;
OK_(crypt_init(&cd, DEVICE_1)); OK_(crypt_init(&cd, DEVICE_1));
OK_(crypt_load(cd, CRYPT_LUKS1, NULL)); OK_(crypt_load(cd, CRYPT_LUKS1, NULL));
OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0)); OK_(crypt_activate_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1), 0));
OK_(crypt_suspend(cd, CDEVICE_1)); suspend_status = crypt_suspend(cd, CDEVICE_1);
if (suspend_status == -ENOTSUP) {
printf("WARNING: Suspend/Resume not supported, skipping test.\n");
goto out;
}
OK_(suspend_status);
FAIL_(crypt_suspend(cd, CDEVICE_1), "already suspended"); FAIL_(crypt_suspend(cd, CDEVICE_1), "already suspended");
FAIL_(crypt_resume_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1)-1), "wrong key"); FAIL_(crypt_resume_by_passphrase(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEY1, strlen(KEY1)-1), "wrong key");
@@ -604,7 +612,7 @@ static void SuspendDevice(void)
OK_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0)); OK_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0));
FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0), "not suspended"); FAIL_(crypt_resume_by_keyfile(cd, CDEVICE_1, CRYPT_ANY_SLOT, KEYFILE1, 0), "not suspended");
_remove_keyfiles(); _remove_keyfiles();
out:
OK_(crypt_deactivate(cd, CDEVICE_1)); OK_(crypt_deactivate(cd, CDEVICE_1));
crypt_free(cd); crypt_free(cd);
} }
@@ -688,11 +696,34 @@ static void NonFIPSAlg(void)
char *cipher = "aes"; char *cipher = "aes";
char *cipher_mode = "cbc-essiv:sha256"; char *cipher_mode = "cbc-essiv:sha256";
if (!gcrypt_compatible) {
printf("WARNING: old libgcrypt, skipping test.\n");
return;
}
OK_(crypt_init(&cd, DEVICE_2)); OK_(crypt_init(&cd, DEVICE_2));
OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params)); OK_(crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, key, key_size, &params));
crypt_free(cd); crypt_free(cd);
} }
static void _gcrypt_compatible()
{
int maj, min, patch;
FILE *f;
if (!(f = popen("libgcrypt-config --version", "r")))
return;
if (fscanf(f, "%d.%d.%d", &maj, &min, &patch) == 2 &&
maj >= 1 && min >= 4)
gcrypt_compatible = 1;
if (_debug)
printf("libgcrypt version %d.%d.%d detected.\n", maj, min, patch);
(void)fclose(f);
return;
}
int main (int argc, char *argv[]) int main (int argc, char *argv[])
{ {
int i; int i;
@@ -711,6 +742,7 @@ int main (int argc, char *argv[])
_cleanup(); _cleanup();
_setup(); _setup();
_gcrypt_compatible();
crypt_set_debug_level(_debug ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE); crypt_set_debug_level(_debug ? CRYPT_DEBUG_ALL : CRYPT_DEBUG_NONE);
@@ -729,7 +761,6 @@ int main (int argc, char *argv[])
RUN_(UseLuksDevice, "Use pre-formated LUKS device"); RUN_(UseLuksDevice, "Use pre-formated LUKS device");
RUN_(SuspendDevice, "Suspend/Resume test"); RUN_(SuspendDevice, "Suspend/Resume test");
_cleanup(); _cleanup();
return 0; return 0;
} }