diff options
author | Milan Broz <gmazyland@gmail.com> | 2011-10-09 20:58:10 +0000 |
---|---|---|
committer | Milan Broz <gmazyland@gmail.com> | 2011-10-09 20:58:10 +0000 |
commit | e640f5e00625bfed47660e6a5a1b5ba8750dee88 (patch) | |
tree | 9f56ffa036ea149aa01661effc46b512d99f93ac /docs | |
parent | cb7fa0b9c7fd21c488d9e9445b15743e77df2617 (diff) | |
download | cryptsetup-e640f5e00625bfed47660e6a5a1b5ba8750dee88.tar.gz cryptsetup-e640f5e00625bfed47660e6a5a1b5ba8750dee88.tar.bz2 cryptsetup-e640f5e00625bfed47660e6a5a1b5ba8750dee88.zip |
Rewrite examples to more simple format.
git-svn-id: https://cryptsetup.googlecode.com/svn/trunk@631 36d66b0a-2a48-0410-832c-cd162a569da5
Diffstat (limited to 'docs')
-rw-r--r-- | docs/examples/crypt_examples.h | 20 | ||||
-rw-r--r-- | docs/examples/crypt_log_usage.c | 88 | ||||
-rw-r--r-- | docs/examples/crypt_luks_usage.c | 390 |
3 files changed, 212 insertions, 286 deletions
diff --git a/docs/examples/crypt_examples.h b/docs/examples/crypt_examples.h deleted file mode 100644 index 1fdbf75..0000000 --- a/docs/examples/crypt_examples.h +++ /dev/null @@ -1,20 +0,0 @@ -#define EX_STEP(step_nr, format, args...) do { \ - printf("STEP_%02d: Entering "format"... ", step_nr, ##args); \ - } while(0) - -#define EX_FAIL(format, args...) do { \ - printf("FAIL\n"); \ - fprintf(stderr, "\t"format"\n", ##args); \ - } while(0) - -#define EX_SUCCESS(format, args...) do { \ - printf("OK\n\t"format"\n", ##args); \ - } while(0) - -#define EX_DELIM printf("-------------------------------\n") - -#define EX_PRESS_ENTER(msg, args...) do { \ - printf(msg "\nPress <ENTER> to continue: ", ##args); \ - getc(stdin); \ - } while(0) - diff --git a/docs/examples/crypt_log_usage.c b/docs/examples/crypt_log_usage.c index 778b0cb..15a8a0b 100644 --- a/docs/examples/crypt_log_usage.c +++ b/docs/examples/crypt_log_usage.c @@ -4,95 +4,73 @@ #include <unistd.h> #include <libcryptsetup.h> -#include "crypt_examples.h" - -#define LOG_PREFIX_CD "cslog_example_prefix" - -int log_ready = 0; - /* * This is an example of function that can be registered using crypt_set_log_callback API. * * Its prototype is void (*log)(int level, const char *msg, void *usrptr) as defined * in crypt_set_log_callback - * - * NOTE: that some syslog message levels may not be visible with respect to your - * syslog setings - * - * If your syslog daemon is turned off, messages should be printed to stderr */ static void simple_syslog_wrapper(int level, const char *msg, void *usrptr) { - if(!log_ready) { - openlog((char *)usrptr, LOG_CONS | LOG_PID, LOG_USER); - log_ready = 1; - } + const char *prefix = (const char *)usrptr; + int priority; + switch(level) { - case CRYPT_LOG_NORMAL: - syslog(LOG_NOTICE, msg); - break; - case CRYPT_LOG_ERROR: - syslog(LOG_ERR, msg); - break; - case CRYPT_LOG_VERBOSE: - syslog(LOG_INFO, msg); - break; - case CRYPT_LOG_DEBUG: - syslog(LOG_DEBUG, msg); - break; + case CRYPT_LOG_NORMAL: priority = LOG_NOTICE; break; + case CRYPT_LOG_ERROR: priority = LOG_ERR; break; + case CRYPT_LOG_VERBOSE: priority = LOG_INFO; break; + case CRYPT_LOG_DEBUG: priority = LOG_DEBUG; break; default: fprintf(stderr, "Unsupported log level requested!\n"); + return; } + + if (prefix) + syslog(priority, "%s:%s", prefix, msg); + else + syslog(priority, "%s", msg); } int main(void) { - int step = 0, r = 0; struct crypt_device *cd; + char usrprefix[] = "cslog_example"; + int r; + + if (geteuid()) { + printf("Using of libcryptsetup requires super user privileges.\n"); + return 1; + } - if (geteuid()) - fprintf(stderr, "WARN: Process doesn't have super user privileges. " - "Most of examples will fail because of that.\n"); + openlog("cryptsetup", LOG_CONS | LOG_PID, LOG_USER); - EX_STEP(++step, "crypt_init() to get an empty device context"); - if ((r = crypt_init(&cd, NULL))) { - EX_FAIL("crypt_init() failed."); - return r; + /* Initialize empty crypt device context */ + r = crypt_init(&cd, NULL); + if (r < 0) { + printf("crypt_init() failed.\n"); + return 2; } - EX_SUCCESS("crypt_init() successfull"); - EX_STEP(++step, "crypt_set_log_callback() to register a log function tied with context"); - crypt_set_log_callback(cd, &simple_syslog_wrapper, LOG_PREFIX_CD); - EX_SUCCESS(""); - EX_DELIM; + /* crypt_set_log_callback() - register a log function for crypt context */ + crypt_set_log_callback(cd, &simple_syslog_wrapper, (void *)usrprefix); - EX_STEP(++step, "multiple crypt_log() to send messages into the context set log function. " - "The messages should be prefixed with '" LOG_PREFIX_CD "'"); + /* send messages ithrough the crypt_log() interface */ crypt_log(cd, CRYPT_LOG_NORMAL, "This is normal log message"); crypt_log(cd, CRYPT_LOG_ERROR, "This is error log message"); crypt_log(cd, CRYPT_LOG_VERBOSE, "This is verbose log message"); crypt_log(cd, CRYPT_LOG_DEBUG, "This is debug message"); - EX_SUCCESS(""); - EX_DELIM; + /* release crypt context */ crypt_free(cd); - if (log_ready) - closelog(); - - log_ready = 0; - - EX_STEP(++step, "crypt_set_log_callback() to register a default (global) log function"); + /* Initialize default (global) log function */ crypt_set_log_callback(NULL, &simple_syslog_wrapper, NULL); - EX_SUCCESS(""); - EX_DELIM; - EX_STEP(++step, "multiple crypt_log() to send messages into default log"); crypt_log(NULL, CRYPT_LOG_NORMAL, "This is normal log message"); crypt_log(NULL, CRYPT_LOG_ERROR, "This is error log message"); crypt_log(NULL, CRYPT_LOG_VERBOSE, "This is verbose log message"); crypt_log(NULL, CRYPT_LOG_DEBUG, "This is debug message"); - EX_SUCCESS(""); - return r; + closelog(); + return 0; } diff --git a/docs/examples/crypt_luks_usage.c b/docs/examples/crypt_luks_usage.c index 08f691a..0663bec 100644 --- a/docs/examples/crypt_luks_usage.c +++ b/docs/examples/crypt_luks_usage.c @@ -6,56 +6,13 @@ #include <sys/types.h> #include <libcryptsetup.h> -#include "crypt_examples.h" - -#define KEY_SIZE 32 -#define EX_DEV_NAME "ex_crypt_dev" -#define DMDIR "/dev/mapper/" -#define SECTOR_SIZE 512 - -/* - * You can use this example with command line parameters as follows, - * but please note, that this example will not do any sophisticated parameters - * checking at all. - * - * ./crypt_luks_usage <path> - * - * where: - * <path> is either regular file or block device. DO NOT use your physical HDD - * with running system or another device containing valuable data otherwise you risk - * partial or complete loss of it. - */ -static void usage(const char *msg) +static int format_and_add_keyslots(const char *path) { - fprintf(stderr, "ERROR: %s\nusage: ./crypt_luks_usage <path>\n" - "The <path> can refer to either a regular file or a block device.\n", - msg ?: ""); -} - -int main(int argc, char **argv) -{ - char *answer = NULL, *cipher, *cipher_mode, *dev; - int step = 0, r; - size_t size = 0; - /* crypt device handle */ - struct crypt_active_device cad; struct crypt_device *cd; struct crypt_params_luks1 params; - - if (geteuid()) - fprintf(stderr, "WARN: Process doesn't have super user privileges. " - "Most of examples will fail because of that.\n"); - - if (argc != 2) { - usage("Wrong number of cmd line parameters."); - exit(1); - } - - dev = argv[1]; + int r; /* - * __STEP_01__ - * * crypt_init() call precedes most of operations of cryptsetup API. The call is used * to initialize crypt device context stored in structure referenced by _cd_ in * the example. Second parameter is used to pass underlaying device path. @@ -63,244 +20,255 @@ int main(int argc, char **argv) * Note: * If path refers to a regular file it'll be attached to a first free loop device. * crypt_init() operation fails in case there's no more loop device available. - * Also, loop device will have the AUTOCLEAR flag set, so the file will be - * detached after crypt_free() call on the concerned context. + * Also, loop device will have the AUTOCLEAR flag set, so the file loopback will + * be detached automatically. */ - EX_STEP(++step, "crypt_init()"); - if ((r = crypt_init(&cd, dev))) { - EX_FAIL("crypt_init() failed for '%s'\n", dev ?: "(not set)"); + + r = crypt_init(&cd, path); + if (r < 0 ) { + printf("crypt_init() failed for %s.\n", path); return r; } - EX_SUCCESS("crypt_init() on '%s' has been successful", dev); - if (strcmp(dev, crypt_get_device_name(cd))) - printf("\tFile '%s' has been attached to %s\n", dev, crypt_get_device_name(cd)); - EX_DELIM; + printf("Context is attached to block device %s.\n", crypt_get_device_name(cd)); + /* * So far no data were written on your device. This will change with call of * crypt_format() only if you specify CRYPT_LUKS1 as device type. */ - printf("8 initial sectors of the device will be overwritten\n" - "Are you sure you want to call crypt_format() over '%s'?\n" - "If you're absolutely sure the device doesn't contain any valuable data,\n" - "approve the operation by typing 'yes' in upper case: ", crypt_get_device_name(cd)); - - if ((r = getline(&answer, &size, stdin)) == -1) { - perror("getline"); - goto out; - } + printf("Device %s will be formatted to LUKS device after 5 seconds.\n" + "Press CTRL+C now if you want to cancel this operation.\n", path); + sleep(5); - if (strcmp(answer, "YES\n")) - goto out; - - /* Example of crypt_format() follows: */ /* - * cipher and cipher_mode: + * Prepare LUKS format parameters * - * you'll get more on _cipher_ and _cipher_mode_ in man page - * for cryptsetup userspace utility or at cryptsetup project - * documentation. + * hash parameter defines PBKDF2 hash algorithm used in LUKS header. + * For compatibility reason we use SHA1 here. */ - cipher = "aes"; - cipher_mode = "cbc-essiv:sha256"; params.hash = "sha1"; /* - * This parameter is relevant only in case of the luks header + * data_alignment parameter is relevant only in case of the luks header * and the payload are both stored on same device. * - * In this particular case, payload offset (which is - * computed internaly, according to volume key size) - * is aligned to 2048 sectors - * * if you set data_alignment = 0, cryptsetup will autodetect - * data_alignment from underlaying device topology. + * data_alignment according to underlaying device topology. */ - params.data_alignment = 2048; + params.data_alignment = 0; /* - * this parameter defines that no external device + * data_device parameter defines that no external device * for luks header will be used */ params.data_device = NULL; /* - * __STEP_02__ - * * NULLs for uuid and volume_key means that these attributes will be * generated during crypt_format(). Volume key is generated with respect * to key size parameter passed to function. * - * Note that in crypt_format() device is checked wheter it's large enough to - * store the luks header only. + * crypt_format() checks device size (LUKS header must fit there). */ - EX_STEP(++step, "crypt_format()"); - if((r = crypt_format(cd, CRYPT_LUKS1, cipher, cipher_mode, NULL, NULL, KEY_SIZE, ¶ms))) { - EX_FAIL("crypt_format() failed on device %s\n", crypt_get_device_name(cd)); - goto out; + r = crypt_format(cd, /* crypt context */ + CRYPT_LUKS1, /* LUKS1 is standard LUKS header */ + "aes", /* used cipher */ + "xts-plain64", /* used block mode and IV generator*/ + NULL, /* generate UUID */ + NULL, /* generate volume key from RNG */ + 256 / 8, /* 256bit key - here AES-128 in XTS mode, size is in bytes */ + ¶ms); /* parameters above */ + + if(r < 0) { + printf("crypt_format() failed on device %s\n", crypt_get_device_name(cd)); + crypt_free(cd); + return r; } - EX_SUCCESS("crypt_format() on device %s formated successfully. " - "The device now contains LUKS1 header, but there is no active keyslot with encrypted " - "volume key.", crypt_get_device_name(cd)); - EX_DELIM; /* - * __STEP_03__ - * - * This call is intended to store volume_key in encrypted form into structure called keyslot. + * The device now contains LUKS1 header, but there is + * no active keyslot with encrypted volume key yet. + */ + + /* + * cryptt_kesylot_add_* call stores volume_key in encrypted form into keyslot. * Without keyslot you can't manipulate with LUKS device after the context will be freed. * * To create a new keyslot you need to supply the existing one (to get the volume key from) or - * you need to supply the volume key. Now we have volume key stored internally and we have no active - * keyslot so this the only option. + * you need to supply the volume key. * + * After format, we have volume key stored internally in context so add new keyslot + * using this internal volume key. */ - printf("Going to create a new keyslot...\n"); - EX_STEP(++step, "crypt_keyslot_add_by_volume_key()"); - if ((r = crypt_keyslot_add_by_volume_key(cd, CRYPT_ANY_SLOT, NULL, 0, NULL, 0)) < 0) { - EX_FAIL("Adding keyslot failed."); - goto out; + r = crypt_keyslot_add_by_volume_key(cd, /* crypt context */ + CRYPT_ANY_SLOT, /* just use first free slot */ + NULL, /* use internal volume key */ + 0, /* unused (size of volume key) */ + "foo", /* passphrase - NULL means query*/ + 3); /* size of passphrase */ + + if (r < 0) { + printf("Adding keyslot failed.\n"); + crypt_free(cd); + return r; } - EX_SUCCESS("Keyslot nr. %d created successfully on device %s.", r, crypt_get_device_name(cd)); - EX_DELIM; + + printf("The first keyslot is initialized.\n"); /* - * __STEP_04__ - * - * This is the example of the second method mentioned in STEP 03. By supplying passphrase for - * the active keyslot you can create a new one. + * Add another keyslot, now using the first keyslot. + * It will decrypt volume key from the first keyslot and creates new one with another passphrase. */ - printf("Now let's try to add a keyslot using the existing active keyslot\n"); - EX_STEP(++step, "crypt_keyslot_add_by_passphrase()"); - if ((r = crypt_keyslot_add_by_passphrase(cd, CRYPT_ANY_SLOT, NULL, 0, NULL, 0)) < 0) { - EX_FAIL("Adding keyslot failed\n"); - goto out; + r = crypt_keyslot_add_by_passphrase(cd, /* crypt context */ + CRYPT_ANY_SLOT, /* just use first free slot */ + "foo", 3, /* passphrase for the old keyslot */ + "bar", 3); /* passphrase for the new kesylot */ + if (r < 0) { + printf("Adding keyslot failed.\n"); + crypt_free(cd); + return r; } - EX_SUCCESS("Keyslot nr. %d created successfully and written on device %s.", r, crypt_get_device_name(cd)); - EX_DELIM; + + printf("The second keyslot is initialized.\n"); crypt_free(cd); - cd = NULL; + return 0; +} + +static int activate_and_check_status(const char *path, const char *device_name) +{ + struct crypt_device *cd; + struct crypt_active_device cad; + int r; /* - * __STEP_05__ - * - * In previous steps the device was formatted (LUKS header was written to backing device) - * and keyslots were activated (volume key was written in two separate structures encrypted - * by two user supplied passwords). - * - * This example demonstrates typical use case for LUKS device activation. - * It's sequence of sub-steps: device initialization (crypt_init), LUKS header load (crypt_load()) - * and finally the device activation itself + * LUKS device activation example. + * It's sequence of sub-steps: device initialization, LUKS header load + * and the device activation itself. */ - EX_PRESS_ENTER("Device context going to be freed. New one will initialized to demonstrate activation process."); - EX_STEP(++step, "crypt_init()"); - if ((r = crypt_init(&cd, dev))) { - EX_FAIL("crypt_init() failed for '%s'!", dev); - goto out; + r = crypt_init(&cd, path); + if (r < 0 ) { + printf("crypt_init() failed for %s.\n", path); + return r; } - EX_SUCCESS("crypt_init() on '%s' has been successful.", dev); - if (strcmp(dev, crypt_get_device_name(cd))) - printf("\tFile '%s' has been attached to %s\n", dev, crypt_get_device_name(cd)); - EX_DELIM; - /* __STEP_05__ - * - * crypt_load() is used to load the LUKS header from backing block device - * into crypt_device context + + /* + * crypt_load() is used to load the LUKS header from block device + * into crypt_device context. */ - EX_PRESS_ENTER("Going to load LUKS header."); - EX_STEP(step, "crypt_load()"); - if ((r = crypt_load(cd, CRYPT_LUKS1, ¶ms))) { - EX_FAIL("crypt_load() failed on device '%s'!", crypt_get_device_name(cd)); - goto out; + r = crypt_load(cd, /* crypt context */ + CRYPT_LUKS1, /* requested type */ + NULL); /* additional parameters (not used) */ + + if (r < 0) { + printf("crypt_load() failed on device %s.\n", crypt_get_device_name(cd)); + crypt_free(cd); + return r; } - EX_SUCCESS("crypt_load() successful. The header has been read from %s.", crypt_get_device_name(cd)); - EX_DELIM; /* - * __STEP_05__ - * - * Device activation creates mapping in device-mapper with name EX_DEV_NAME. - * The volume key is stored into kernel mem. space and the encryption of backing - * device is now set in motion. + * Device activation creates device-mapper devie mapping with name device_name. */ - printf("Going to activate LUKS device\n"); - EX_STEP(step, "crypt_activate_by_passphrase()"); - if ((r = crypt_activate_by_passphrase(cd, EX_DEV_NAME, CRYPT_ANY_SLOT, NULL, 0, 0)) < 0) { - EX_FAIL("Device activation failed!"); - goto out; + r = crypt_activate_by_passphrase(cd, /* crypt context */ + device_name, /* device name to activate */ + CRYPT_ANY_SLOT,/* which slot use (ANY - try all) */ + "foo", 3, /* passphrase */ + CRYPT_ACTIVATE_READONLY); /* flags */ + if (r < 0) { + printf("Device %s activation failed.\n", device_name); + crypt_free(cd); + return r; } - EX_SUCCESS("Encrypted device is active on " DMDIR EX_DEV_NAME "."); - printf("\tThe cipher used in device context: '%s'\n", crypt_get_cipher(cd) ?: "(not set) !"); - printf("\tThe cipher mode used in device context: '%s'\n", crypt_get_cipher_mode(cd) ?: "(not set) !"); - printf("\tThe device UUID '%s'\n", crypt_get_uuid(cd) ?: "(not set) !"); - EX_DELIM; + + printf("LUKS device %s/%s is active.\n", crypt_get_dir(), device_name); + printf("\tcipher used: %s\n", crypt_get_cipher(cd)); + printf("\tcipher mode: %s\n", crypt_get_cipher_mode(cd)); + printf("\tdevice UUID: %s\n", crypt_get_uuid(cd)); /* - * __STEP_06__ - * * Get info about active device (query DM backend) */ - EX_PRESS_ENTER("Going to get active active device parameters."); - EX_STEP(++step, "crypt_get_active_device()"); - if ((r = crypt_get_active_device(cd, EX_DEV_NAME, &cad))) { - EX_FAIL("Get info about active device '%s' failed!", EX_DEV_NAME); - goto out; + r = crypt_get_active_device(cd, device_name, &cad); + if (r < 0) { + printf("Get info about active device %s failed.\n", device_name); + crypt_deactivate(cd, device_name); + crypt_free(cd); + return r; } - EX_SUCCESS("Active device parameters for " EX_DEV_NAME ":\n" - "\tPayload offset (in sectors): %" PRIu64 "\n" - "\tEncrypted payload area size in sectors: %" PRIu64 " and bytes: %" PRIu64 "\n" - "\tThe device has a read-only flag %sset", - cad.offset, cad.size, cad.size * SECTOR_SIZE, - cad.flags & CRYPT_ACTIVATE_READONLY ? "" : "not "); - EX_DELIM; + + printf("Active device parameters for %s:\n" + "\tDevice offset (in sectors): %" PRIu64 "\n" + "\tIV offset (in sectors) : %" PRIu64 "\n" + "\tdevice size (in sectors) : %" PRIu64 "\n" + "\tread-only flag : %s\n", + device_name, cad.offset, cad.iv_offset, cad.size, + cad.flags & CRYPT_ACTIVATE_READONLY ? "1" : "0"); crypt_free(cd); - cd = NULL; + return 0; +} + +static int handle_active_device(const char *device_name) +{ + struct crypt_device *cd; + int r; /* - * __STEP_07__ - * * crypt_init_by_name() initializes device context and loads LUKS header from backing device */ - EX_PRESS_ENTER("The context used in previous examples is going to be freed to demonstrate " - "how to initialize a device context from the active device."); - EX_STEP(++step, "crypt_init_by_name()"); - if ((r = crypt_init_by_name(&cd, EX_DEV_NAME))) { - EX_FAIL("crypt_init_by_name() failed for the device name: " EX_DEV_NAME); - goto out; + r = crypt_init_by_name(&cd, device_name); + if (r < 0) { + printf("crypt_init_by_name() failed for %s.\n", device_name); + return r; + } + + if (crypt_status(cd, device_name) == CRYPT_ACTIVE) + printf("Device %s is still active.\n", device_name); + else { + printf("Something failed perhaps, device %s is not active.\n", device_name); + crypt_free(cd); + return -1; } - EX_SUCCESS("A new context has been initialized, LUKS header has been restored" - "\n\tDevice UUID is '%s'", crypt_get_uuid(cd)); /* - * __STEP_08__ - * - * crypt_deactivate() is used to remove the volume_key from kernel mem. space and to remove the - * device nod associated with decrypted backing device. - * + * crypt_deactivate() is used to deactivate device */ - EX_PRESS_ENTER("\n\tGoing to deactivate the crypt device. Note that the device " - "won't be deactivated while it's opened with O_EXCL flag (e.g. mounted)."); - EX_STEP(++step, "crypt_deactivate()"); - //printf("\nPress <ENTER> to continue to device deactivation of the test device.\n" - // "Note that mounted device won't be deactivated. First unmount the device!"); - //getc(stdin); - while ((r = crypt_deactivate(cd, EX_DEV_NAME))) { - EX_FAIL("crypt_deactivate() failed. Most propably the device is still busy!"); - EX_PRESS_ENTER("Going to retry device deactivation"); - } - EX_SUCCESS("crypt_deactivate() successful. Device " DMDIR EX_DEV_NAME " is now deactivated"); - -out: - if (crypt_status(cd, EX_DEV_NAME) == CRYPT_ACTIVE) - crypt_deactivate(cd, EX_DEV_NAME); - if (answer) - free(answer); - /* always free context which is no longer used */ - if (cd) + r = crypt_deactivate(cd, device_name); + if (r < 0) { + printf("crypt_deactivate() failed.\n"); crypt_free(cd); + return r; + } + + printf("Device %s is now deactivated.\n", device_name); + + crypt_free(cd); + return 0; +} + +int main(int argc, char **argv) +{ + if (geteuid()) { + printf("Using of libcryptsetup requires super user privileges.\n"); + return 1; + } + + if (argc != 2) { + printf("usage: ./crypt_luks_usage <path>\n" + "<path> refers to either a regular file or a block device.\n" + " WARNING: the file or device will be wiped.\n"); + return 2; + } + + if (format_and_add_keyslots(argv[1])) + return 3; + + if (activate_and_check_status(argv[1], "example_device")) + return 4; + + if (handle_active_device("example_device")) + return 5; - return r; + return 0; } |