diff options
Diffstat (limited to 'docs/examples')
-rw-r--r-- | docs/examples/Makefile | 17 | ||||
-rw-r--r-- | docs/examples/crypt_log_usage.c | 94 | ||||
-rw-r--r-- | docs/examples/crypt_luks_usage.c | 250 |
3 files changed, 361 insertions, 0 deletions
diff --git a/docs/examples/Makefile b/docs/examples/Makefile new file mode 100644 index 0000000..845b6cb --- /dev/null +++ b/docs/examples/Makefile @@ -0,0 +1,17 @@ +TARGETS=crypt_log_usage crypt_luks_usage +CFLAGS=-O0 -g -Wall -D_GNU_SOURCE +LDLIBS=-lcryptsetup +CC=gcc + +all: $(TARGETS) + +crypt_log_usage: crypt_log_usage.o + $(CC) -o $@ $^ $(LDLIBS) + +crypt_luks_usage: crypt_luks_usage.o + $(CC) -o $@ $^ $(LDLIBS) + +clean: + rm -f *.o *~ core $(TARGETS) + +.PHONY: clean diff --git a/docs/examples/crypt_log_usage.c b/docs/examples/crypt_log_usage.c new file mode 100644 index 0000000..b0cdd56 --- /dev/null +++ b/docs/examples/crypt_log_usage.c @@ -0,0 +1,94 @@ +/* + * libcryptsetup API log example + * + * Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved. + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <stdio.h> +#include <sys/types.h> +#include <syslog.h> +#include <unistd.h> +#include <libcryptsetup.h> + +/* + * This is an example of crypt_set_log_callback API callback. + * + */ +static void simple_syslog_wrapper(int level, const char *msg, void *usrptr) +{ + const char *prefix = (const char *)usrptr; + int priority; + + switch(level) { + 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) +{ + struct crypt_device *cd; + char usrprefix[] = "cslog_example"; + int r; + + if (geteuid()) { + printf("Using of libcryptsetup requires super user privileges.\n"); + return 1; + } + + openlog("cryptsetup", LOG_CONS | LOG_PID, LOG_USER); + + /* Initialize empty crypt device context */ + r = crypt_init(&cd, NULL); + if (r < 0) { + printf("crypt_init() failed.\n"); + return 2; + } + + /* crypt_set_log_callback() - register a log callback for crypt context */ + crypt_set_log_callback(cd, &simple_syslog_wrapper, (void *)usrprefix); + + /* 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"); + + /* release crypt context */ + crypt_free(cd); + + /* Initialize default (global) log callback */ + crypt_set_log_callback(NULL, &simple_syslog_wrapper, NULL); + + 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"); + + closelog(); + return 0; +} diff --git a/docs/examples/crypt_luks_usage.c b/docs/examples/crypt_luks_usage.c new file mode 100644 index 0000000..f99bfc7 --- /dev/null +++ b/docs/examples/crypt_luks_usage.c @@ -0,0 +1,250 @@ +/* + * libcryptsetup API - using LUKS device example + * + * Copyright (C) 2011-2021 Red Hat, Inc. All rights reserved. + * + * This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this file; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> +#include <inttypes.h> +#include <sys/types.h> +#include <libcryptsetup.h> + +static int format_and_add_keyslots(const char *path) +{ + struct crypt_device *cd; + int r; + + /* + * The crypt_init() call is used to initialize crypt_device context, + * The path parameter specifies a device path. + * + * For path, you can use either link to a file or block device. + * The loopback device will be detached automatically. + */ + + r = crypt_init(&cd, path); + if (r < 0) { + printf("crypt_init() failed for %s.\n", path); + return r; + } + + printf("Context is attached to block device %s.\n", crypt_get_device_name(cd)); + + /* + * So far, no data were written to the device. + */ + printf("Device %s will be formatted as a LUKS device after 5 seconds.\n" + "Press CTRL+C now if you want to cancel this operation.\n", path); + sleep(5); + + /* + * NULLs for uuid and volume_key means that these attributes will be + * generated during crypt_format(). + */ + r = crypt_format(cd, /* crypt context */ + CRYPT_LUKS2, /* LUKS2 is a new LUKS format; use CRYPT_LUKS1 for LUKS1 */ + "aes", /* used cipher */ + "xts-plain64", /* used block mode and IV */ + NULL, /* generate UUID */ + NULL, /* generate volume key from RNG */ + 512 / 8, /* 512bit key - here AES-256 in XTS mode, size is in bytes */ + NULL); /* default parameters */ + + if (r < 0) { + printf("crypt_format() failed on device %s\n", crypt_get_device_name(cd)); + crypt_free(cd); + return r; + } + + /* + * The device now contains a LUKS header, but there is no active keyslot. + * + * crypt_keyslot_add_* call stores the volume_key in the encrypted form into the keyslot. + * + * After format, the volume key is stored internally. + */ + 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; + } + + printf("The first keyslot is initialized.\n"); + + /* + * Add another keyslot, now authenticating with the first keyslot. + * It decrypts the volume key from the first keyslot and creates a new one with the specified passphrase. + */ + 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; + } + + printf("The second keyslot is initialized.\n"); + + crypt_free(cd); + 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; + + /* + * LUKS device activation example. + */ + r = crypt_init(&cd, path); + if (r < 0) { + printf("crypt_init() failed for %s.\n", path); + return r; + } + + /* + * crypt_load() is used to load existing LUKS header from a block device + */ + r = crypt_load(cd, /* crypt context */ + CRYPT_LUKS, /* requested type - here LUKS of any 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; + } + + /* + * Device activation creates a device-mapper device with the specified name. + */ + r = crypt_activate_by_passphrase(cd, /* crypt context */ + device_name, /* device name to activate */ + CRYPT_ANY_SLOT,/* the keyslot use (try all here) */ + "foo", 3, /* passphrase */ + CRYPT_ACTIVATE_READONLY); /* flags */ + if (r < 0) { + printf("Device %s activation failed.\n", device_name); + crypt_free(cd); + return r; + } + + printf("%s device %s/%s is active.\n", crypt_get_type(cd), 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)); + + /* + * Get info about the active device. + */ + 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; + } + + 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); + return 0; +} + +static int handle_active_device(const char *device_name) +{ + struct crypt_device *cd; + int r; + + /* + * crypt_init_by_name() initializes context by an active device-mapper name + */ + 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; + } + + /* + * crypt_deactivate() is used to deactivate a device + */ + 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 0; +} |