Home | History | Annotate | Download | only in misc
      1 /*
      2  * e4crypt.c - ext4 encryption management utility
      3  *
      4  * Copyright (c) 2014 Google, Inc.
      5  *	SHA512 implementation from libtomcrypt.
      6  *
      7  * Authors: Michael Halcrow <mhalcrow (at) google.com>,
      8  *	Ildar Muslukhov <ildarm (at) google.com>
      9  */
     10 
     11 #ifndef _LARGEFILE_SOURCE
     12 #define _LARGEFILE_SOURCE
     13 #endif
     14 
     15 #ifndef _LARGEFILE64_SOURCE
     16 #define _LARGEFILE64_SOURCE
     17 #endif
     18 
     19 #ifndef _GNU_SOURCE
     20 #define _GNU_SOURCE
     21 #endif
     22 
     23 #include "config.h"
     24 #include <assert.h>
     25 #include <errno.h>
     26 #include <getopt.h>
     27 #include <dirent.h>
     28 #include <errno.h>
     29 #include <stdarg.h>
     30 #include <stdio.h>
     31 #include <stdlib.h>
     32 #include <string.h>
     33 #include <mntent.h>
     34 #include <sys/ioctl.h>
     35 #include <sys/stat.h>
     36 #include <sys/types.h>
     37 #include <fcntl.h>
     38 #include <termios.h>
     39 #include <unistd.h>
     40 #include <signal.h>
     41 #if !defined(HAVE_ADD_KEY) || !defined(HAVE_KEYCTL)
     42 #include <sys/syscall.h>
     43 #endif
     44 #ifdef HAVE_SYS_KEY_H
     45 #include <sys/key.h>
     46 #endif
     47 
     48 #include "ext2fs/ext2_fs.h"
     49 #include "ext2fs/ext2fs.h"
     50 #include "uuid/uuid.h"
     51 
     52 /* special process keyring shortcut IDs */
     53 #define KEY_SPEC_THREAD_KEYRING		-1
     54 #define KEY_SPEC_PROCESS_KEYRING	-2
     55 #define KEY_SPEC_SESSION_KEYRING	-3
     56 #define KEY_SPEC_USER_KEYRING		-4
     57 #define KEY_SPEC_USER_SESSION_KEYRING	-5
     58 #define KEY_SPEC_GROUP_KEYRING		-6
     59 
     60 #define KEYCTL_GET_KEYRING_ID		0
     61 #define KEYCTL_JOIN_SESSION_KEYRING	1
     62 #define KEYCTL_DESCRIBE			6
     63 #define KEYCTL_SEARCH			10
     64 #define KEYCTL_SESSION_TO_PARENT	18
     65 
     66 typedef __s32 key_serial_t;
     67 
     68 #define EXT4_KEY_REF_STR_BUF_SIZE ((EXT4_KEY_DESCRIPTOR_SIZE * 2) + 1)
     69 
     70 #ifndef EXT4_IOC_GET_ENCRYPTION_PWSALT
     71 #define EXT4_IOC_GET_ENCRYPTION_PWSALT	_IOW('f', 20, __u8[16])
     72 #endif
     73 
     74 #define OPT_VERBOSE	0x0001
     75 #define OPT_QUIET	0x0002
     76 
     77 int options;
     78 
     79 #ifndef HAVE_KEYCTL
     80 static long keyctl(int cmd, ...)
     81 {
     82 	va_list va;
     83 	unsigned long arg2, arg3, arg4, arg5;
     84 
     85 	va_start(va, cmd);
     86 	arg2 = va_arg(va, unsigned long);
     87 	arg3 = va_arg(va, unsigned long);
     88 	arg4 = va_arg(va, unsigned long);
     89 	arg5 = va_arg(va, unsigned long);
     90 	va_end(va);
     91 	return syscall(__NR_keyctl, cmd, arg2, arg3, arg4, arg5);
     92 }
     93 #endif
     94 
     95 #ifndef HAVE_ADD_KEY
     96 static key_serial_t add_key(const char *type, const char *description,
     97 			    const void *payload, size_t plen,
     98 			    key_serial_t keyring)
     99 {
    100 	return syscall(__NR_add_key, type, description, payload,
    101 		       plen, keyring);
    102 }
    103 #endif
    104 
    105 static const unsigned char *hexchars = (const unsigned char *) "0123456789abcdef";
    106 static const size_t hexchars_size = 16;
    107 
    108 #define SHA512_LENGTH 64
    109 #define EXT2FS_KEY_TYPE_LOGON "logon"
    110 #define EXT2FS_KEY_DESC_PREFIX "ext4:"
    111 #define EXT2FS_KEY_DESC_PREFIX_SIZE 5
    112 
    113 #define EXT4_IOC_SET_ENCRYPTION_POLICY      _IOR('f', 19, struct ext4_encryption_policy)
    114 #define EXT4_IOC_GET_ENCRYPTION_POLICY      _IOW('f', 21, struct ext4_encryption_policy)
    115 
    116 static int int_log2(int arg)
    117 {
    118 	int     l = 0;
    119 
    120 	arg >>= 1;
    121 	while (arg) {
    122 		l++;
    123 		arg >>= 1;
    124 	}
    125 	return l;
    126 }
    127 
    128 static void validate_paths(int argc, char *argv[], int path_start_index)
    129 {
    130 	int x;
    131 	int valid = 1;
    132 	struct stat st;
    133 
    134 	for (x = path_start_index; x < argc; x++) {
    135 		int ret = access(argv[x], W_OK);
    136 		if (ret) {
    137 		invalid:
    138 			perror(argv[x]);
    139 			valid = 0;
    140 			continue;
    141 		}
    142 		ret = stat(argv[x], &st);
    143 		if (ret < 0)
    144 			goto invalid;
    145 		if (!S_ISDIR(st.st_mode)) {
    146 			fprintf(stderr, "%s is not a directory\n", argv[x]);
    147 			goto invalid;
    148 		}
    149 	}
    150 	if (!valid)
    151 		exit(1);
    152 }
    153 
    154 static int hex2byte(const char *hex, size_t hex_size, unsigned char *bytes,
    155 		    size_t bytes_size)
    156 {
    157 	size_t x;
    158 	unsigned char *h, *l;
    159 
    160 	if (hex_size % 2)
    161 		return -EINVAL;
    162 	for (x = 0; x < hex_size; x += 2) {
    163 		h = memchr(hexchars, hex[x], hexchars_size);
    164 		if (!h)
    165 			return -EINVAL;
    166 		l = memchr(hexchars, hex[x + 1], hexchars_size);
    167 		if (!l)
    168 			return -EINVAL;
    169 		if ((x >> 1) >= bytes_size)
    170 			return -EINVAL;
    171 		bytes[x >> 1] = (((unsigned char)(h - hexchars) << 4) +
    172 				 (unsigned char)(l - hexchars));
    173 	}
    174 	return 0;
    175 }
    176 
    177 /*
    178  * Salt handling
    179  */
    180 struct salt {
    181 	unsigned char *salt;
    182 	char key_ref_str[EXT4_KEY_REF_STR_BUF_SIZE];
    183 	unsigned char key_desc[EXT4_KEY_DESCRIPTOR_SIZE];
    184 	unsigned char key[EXT4_MAX_KEY_SIZE];
    185 	size_t salt_len;
    186 };
    187 struct salt *salt_list;
    188 unsigned num_salt;
    189 unsigned max_salt;
    190 char in_passphrase[EXT4_MAX_PASSPHRASE_SIZE];
    191 
    192 static struct salt *find_by_salt(unsigned char *salt, size_t salt_len)
    193 {
    194 	unsigned int i;
    195 	struct salt *p;
    196 
    197 	for (i = 0, p = salt_list; i < num_salt; i++, p++)
    198 		if ((p->salt_len == salt_len) &&
    199 		    !memcmp(p->salt, salt, salt_len))
    200 			return p;
    201 	return NULL;
    202 }
    203 
    204 static void add_salt(unsigned char *salt, size_t salt_len)
    205 {
    206 	if (find_by_salt(salt, salt_len))
    207 		return;
    208 	if (num_salt >= max_salt) {
    209 		max_salt = num_salt + 10;
    210 		salt_list = realloc(salt_list, max_salt * sizeof(struct salt));
    211 		if (!salt_list) {
    212 			fprintf(stderr, "Couldn't allocate salt list\n");
    213 			exit(1);
    214 		}
    215 	}
    216 	salt_list[num_salt].salt = salt;
    217 	salt_list[num_salt].salt_len = salt_len;
    218 	num_salt++;
    219 }
    220 
    221 static void clear_secrets(void)
    222 {
    223 	if (salt_list) {
    224 		memset(salt_list, 0, sizeof(struct salt) * max_salt);
    225 		free(salt_list);
    226 		salt_list = NULL;
    227 	}
    228 	memset(in_passphrase, 0, sizeof(in_passphrase));
    229 }
    230 
    231 static void die_signal_handler(int signum EXT2FS_ATTR((unused)),
    232 			       siginfo_t *siginfo EXT2FS_ATTR((unused)),
    233 			       void *context EXT2FS_ATTR((unused)))
    234 {
    235 	clear_secrets();
    236 	exit(-1);
    237 }
    238 
    239 static void sigcatcher_setup(void)
    240 {
    241 	struct sigaction	sa;
    242 
    243 	memset(&sa, 0, sizeof(struct sigaction));
    244 	sa.sa_sigaction = die_signal_handler;
    245 	sa.sa_flags = SA_SIGINFO;
    246 
    247 	sigaction(SIGHUP, &sa, 0);
    248 	sigaction(SIGINT, &sa, 0);
    249 	sigaction(SIGQUIT, &sa, 0);
    250 	sigaction(SIGFPE, &sa, 0);
    251 	sigaction(SIGILL, &sa, 0);
    252 	sigaction(SIGBUS, &sa, 0);
    253 	sigaction(SIGSEGV, &sa, 0);
    254 	sigaction(SIGABRT, &sa, 0);
    255 	sigaction(SIGPIPE, &sa, 0);
    256 	sigaction(SIGALRM, &sa, 0);
    257 	sigaction(SIGTERM, &sa, 0);
    258 	sigaction(SIGUSR1, &sa, 0);
    259 	sigaction(SIGUSR2, &sa, 0);
    260 	sigaction(SIGPOLL, &sa, 0);
    261 	sigaction(SIGPROF, &sa, 0);
    262 	sigaction(SIGSYS, &sa, 0);
    263 	sigaction(SIGTRAP, &sa, 0);
    264 	sigaction(SIGVTALRM, &sa, 0);
    265 	sigaction(SIGXCPU, &sa, 0);
    266 	sigaction(SIGXFSZ, &sa, 0);
    267 }
    268 
    269 
    270 #define PARSE_FLAGS_NOTSUPP_OK	0x0001
    271 #define PARSE_FLAGS_FORCE_FN	0x0002
    272 
    273 static void parse_salt(char *salt_str, int flags)
    274 {
    275 	unsigned char buf[EXT4_MAX_SALT_SIZE];
    276 	char *cp = salt_str;
    277 	unsigned char *salt_buf;
    278 	int fd, ret, salt_len = 0;
    279 
    280 	if (flags & PARSE_FLAGS_FORCE_FN)
    281 		goto salt_from_filename;
    282 	if (strncmp(cp, "s:", 2) == 0) {
    283 		cp += 2;
    284 		salt_len = strlen(cp);
    285 		if (salt_len >= EXT4_MAX_SALT_SIZE)
    286 			goto invalid_salt;
    287 		strncpy((char *) buf, cp, sizeof(buf));
    288 	} else if (cp[0] == '/') {
    289 	salt_from_filename:
    290 		fd = open(cp, O_RDONLY | O_DIRECTORY);
    291 		if (fd == -1 && errno == ENOTDIR)
    292 			fd = open(cp, O_RDONLY);
    293 		if (fd == -1) {
    294 			perror(cp);
    295 			exit(1);
    296 		}
    297 		ret = ioctl(fd, EXT4_IOC_GET_ENCRYPTION_PWSALT, &buf);
    298 		close(fd);
    299 		if (ret < 0) {
    300 			if (flags & PARSE_FLAGS_NOTSUPP_OK)
    301 				return;
    302 			perror("EXT4_IOC_GET_ENCRYPTION_PWSALT");
    303 			exit(1);
    304 		}
    305 		if (options & OPT_VERBOSE) {
    306 			char tmp[80];
    307 			uuid_unparse(buf, tmp);
    308 			printf("%s has pw salt %s\n", cp, tmp);
    309 		}
    310 		salt_len = 16;
    311 	} else if (strncmp(cp, "f:", 2) == 0) {
    312 		cp += 2;
    313 		goto salt_from_filename;
    314 	} else if (strncmp(cp, "0x", 2) == 0) {
    315 		unsigned char *h, *l;
    316 
    317 		cp += 2;
    318 		if (strlen(cp) & 1)
    319 			goto invalid_salt;
    320 		while (*cp) {
    321 			if (salt_len >= EXT4_MAX_SALT_SIZE)
    322 				goto invalid_salt;
    323 			h = memchr(hexchars, *cp++, hexchars_size);
    324 			l = memchr(hexchars, *cp++, hexchars_size);
    325 			if (!h || !l)
    326 				goto invalid_salt;
    327 			buf[salt_len++] =
    328 				(((unsigned char)(h - hexchars) << 4) +
    329 				 (unsigned char)(l - hexchars));
    330 		}
    331 	} else if (uuid_parse(cp, buf) == 0) {
    332 		salt_len = 16;
    333 	} else {
    334 	invalid_salt:
    335 		fprintf(stderr, "Invalid salt: %s\n", salt_str);
    336 		exit(1);
    337 	}
    338 	salt_buf = malloc(salt_len);
    339 	if (!salt_buf) {
    340 		fprintf(stderr, "Couldn't allocate salt\n");
    341 		exit(1);
    342 	}
    343 	memcpy(salt_buf, buf, salt_len);
    344 	add_salt(salt_buf, salt_len);
    345 }
    346 
    347 static void set_policy(struct salt *set_salt, int pad,
    348 		       int argc, char *argv[], int path_start_index)
    349 {
    350 	struct salt *salt;
    351 	struct ext4_encryption_policy policy;
    352 	uuid_t	uu;
    353 	int fd;
    354 	int x;
    355 	int rc;
    356 
    357 	if ((pad != 4) && (pad != 8) &&
    358 		 (pad != 16) && (pad != 32)) {
    359 		fprintf(stderr, "Invalid padding %d\n", pad);
    360 		exit(1);
    361 	}
    362 
    363 	for (x = path_start_index; x < argc; x++) {
    364 		fd = open(argv[x], O_DIRECTORY);
    365 		if (fd == -1) {
    366 			perror(argv[x]);
    367 			exit(1);
    368 		}
    369 		if (set_salt)
    370 			salt = set_salt;
    371 		else {
    372 			if (ioctl(fd, EXT4_IOC_GET_ENCRYPTION_PWSALT,
    373 				  &uu) < 0) {
    374 				perror("EXT4_IOC_GET_ENCRYPTION_PWSALT");
    375 				exit(1);
    376 			}
    377 			salt = find_by_salt(uu, sizeof(uu));
    378 			if (!salt) {
    379 				fprintf(stderr, "Couldn't find salt!?!\n");
    380 				exit(1);
    381 			}
    382 		}
    383 		policy.version = 0;
    384 		policy.contents_encryption_mode =
    385 			EXT4_ENCRYPTION_MODE_AES_256_XTS;
    386 		policy.filenames_encryption_mode =
    387 			EXT4_ENCRYPTION_MODE_AES_256_CTS;
    388 		policy.flags = int_log2(pad >> 2);
    389 		memcpy(policy.master_key_descriptor, salt->key_desc,
    390 		       EXT4_KEY_DESCRIPTOR_SIZE);
    391 		rc = ioctl(fd, EXT4_IOC_SET_ENCRYPTION_POLICY, &policy);
    392 		close(fd);
    393 		if (rc) {
    394 			printf("Error [%s] setting policy.\nThe key descriptor "
    395 			       "[%s] may not match the existing encryption "
    396 			       "context for directory [%s].\n",
    397 			       strerror(errno), salt->key_ref_str, argv[x]);
    398 			continue;
    399 		}
    400 		printf("Key with descriptor [%s] applied to %s.\n",
    401 		       salt->key_ref_str, argv[x]);
    402 	}
    403 }
    404 
    405 static void pbkdf2_sha512(const char *passphrase, struct salt *salt,
    406 			  unsigned int count,
    407 			  unsigned char derived_key[EXT4_MAX_KEY_SIZE])
    408 {
    409 	size_t passphrase_size = strlen(passphrase);
    410 	unsigned char buf[SHA512_LENGTH + EXT4_MAX_PASSPHRASE_SIZE] = {0};
    411 	unsigned char tempbuf[SHA512_LENGTH] = {0};
    412 	char final[SHA512_LENGTH] = {0};
    413 	unsigned char saltbuf[EXT4_MAX_SALT_SIZE + EXT4_MAX_PASSPHRASE_SIZE] = {0};
    414 	int actual_buf_len = SHA512_LENGTH + passphrase_size;
    415 	int actual_saltbuf_len = EXT4_MAX_SALT_SIZE + passphrase_size;
    416 	unsigned int x, y;
    417 	__u32 *final_u32 = (__u32 *)final;
    418 	__u32 *temp_u32 = (__u32 *)tempbuf;
    419 
    420 	if (passphrase_size > EXT4_MAX_PASSPHRASE_SIZE) {
    421 		printf("Passphrase size is %zd; max is %d.\n", passphrase_size,
    422 		       EXT4_MAX_PASSPHRASE_SIZE);
    423 		exit(1);
    424 	}
    425 	if (salt->salt_len > EXT4_MAX_SALT_SIZE) {
    426 		printf("Salt size is %zd; max is %d.\n", salt->salt_len,
    427 		       EXT4_MAX_SALT_SIZE);
    428 		exit(1);
    429 	}
    430 	assert(EXT4_MAX_KEY_SIZE <= SHA512_LENGTH);
    431 
    432 	memcpy(saltbuf, salt->salt, salt->salt_len);
    433 	memcpy(&saltbuf[EXT4_MAX_SALT_SIZE], passphrase, passphrase_size);
    434 
    435 	memcpy(&buf[SHA512_LENGTH], passphrase, passphrase_size);
    436 
    437 	for (x = 0; x < count; ++x) {
    438 		if (x == 0) {
    439 			ext2fs_sha512(saltbuf, actual_saltbuf_len, tempbuf);
    440 		} else {
    441 			/*
    442 			 * buf: [previous hash || passphrase]
    443 			 */
    444 			memcpy(buf, tempbuf, SHA512_LENGTH);
    445 			ext2fs_sha512(buf, actual_buf_len, tempbuf);
    446 		}
    447 		for (y = 0; y < (sizeof(final) / sizeof(*final_u32)); ++y)
    448 			final_u32[y] = final_u32[y] ^ temp_u32[y];
    449 	}
    450 	memcpy(derived_key, final, EXT4_MAX_KEY_SIZE);
    451 }
    452 
    453 static int disable_echo(struct termios *saved_settings)
    454 {
    455 	struct termios current_settings;
    456 	int rc = 0;
    457 
    458 	rc = tcgetattr(0, &current_settings);
    459 	if (rc)
    460 		return rc;
    461 	*saved_settings = current_settings;
    462 	current_settings.c_lflag &= ~ECHO;
    463 	rc = tcsetattr(0, TCSANOW, &current_settings);
    464 
    465 	return rc;
    466 }
    467 
    468 static void get_passphrase(char *passphrase, int len)
    469 {
    470 	char *p;
    471 	struct termios current_settings;
    472 
    473 	assert(len > 0);
    474 	disable_echo(&current_settings);
    475 	p = fgets(passphrase, len, stdin);
    476 	tcsetattr(0, TCSANOW, &current_settings);
    477 	printf("\n");
    478 	if (!p) {
    479 		printf("Aborting.\n");
    480 		exit(1);
    481 	}
    482 	p = strrchr(passphrase, '\n');
    483 	if (!p)
    484 		p = passphrase + len - 1;
    485 	*p = '\0';
    486 }
    487 
    488 struct keyring_map {
    489 	char name[4];
    490 	size_t name_len;
    491 	int code;
    492 };
    493 
    494 static const struct keyring_map keyrings[] = {
    495 	{"@us", 3, KEY_SPEC_USER_SESSION_KEYRING},
    496 	{"@u", 2, KEY_SPEC_USER_KEYRING},
    497 	{"@s", 2, KEY_SPEC_SESSION_KEYRING},
    498 	{"@g", 2, KEY_SPEC_GROUP_KEYRING},
    499 	{"@p", 2, KEY_SPEC_PROCESS_KEYRING},
    500 	{"@t", 2, KEY_SPEC_THREAD_KEYRING},
    501 };
    502 
    503 static int get_keyring_id(const char *keyring)
    504 {
    505 	unsigned int x;
    506 	char *end;
    507 
    508 	/*
    509 	 * If no keyring is specified, by default use either the user
    510 	 * session key ring or the session keyring.  Fetching the
    511 	 * session keyring will return the user session keyring if no
    512 	 * session keyring has been set.
    513 	 *
    514 	 * We need to do this instead of simply adding the key to
    515 	 * KEY_SPEC_SESSION_KEYRING since trying to add a key to a
    516 	 * session keyring that does not yet exist will cause the
    517 	 * kernel to create a session keyring --- which wil then get
    518 	 * garbage collected as soon as e4crypt exits.
    519 	 *
    520 	 * The fact that the keyctl system call and the add_key system
    521 	 * call treats KEY_SPEC_SESSION_KEYRING differently when a
    522 	 * session keyring does not exist is very unfortunate and
    523 	 * confusing, but so it goes...
    524 	 */
    525 	if (keyring == NULL)
    526 		return keyctl(KEYCTL_GET_KEYRING_ID,
    527 			      KEY_SPEC_SESSION_KEYRING, 0);
    528 	for (x = 0; x < (sizeof(keyrings) / sizeof(keyrings[0])); ++x) {
    529 		if (strcmp(keyring, keyrings[x].name) == 0) {
    530 			return keyrings[x].code;
    531 		}
    532 	}
    533 	x = strtoul(keyring, &end, 10);
    534 	if (*end == '\0') {
    535 		if (keyctl(KEYCTL_DESCRIBE, x, NULL, 0) < 0)
    536 			return 0;
    537 		return x;
    538 	}
    539 	return 0;
    540 }
    541 
    542 static void generate_key_ref_str(struct salt *salt)
    543 {
    544 	unsigned char key_ref1[SHA512_LENGTH];
    545 	unsigned char key_ref2[SHA512_LENGTH];
    546 	int x;
    547 
    548 	ext2fs_sha512(salt->key, EXT4_MAX_KEY_SIZE, key_ref1);
    549 	ext2fs_sha512(key_ref1, SHA512_LENGTH, key_ref2);
    550 	memcpy(salt->key_desc, key_ref2, EXT4_KEY_DESCRIPTOR_SIZE);
    551 	for (x = 0; x < EXT4_KEY_DESCRIPTOR_SIZE; ++x) {
    552 		sprintf(&salt->key_ref_str[x * 2], "%02x",
    553 			salt->key_desc[x]);
    554 	}
    555 	salt->key_ref_str[EXT4_KEY_REF_STR_BUF_SIZE - 1] = '\0';
    556 }
    557 
    558 static void insert_key_into_keyring(const char *keyring, struct salt *salt)
    559 {
    560 	int keyring_id = get_keyring_id(keyring);
    561 	struct ext4_encryption_key key;
    562 	char key_ref_full[EXT2FS_KEY_DESC_PREFIX_SIZE +
    563 			  EXT4_KEY_REF_STR_BUF_SIZE];
    564 	int rc;
    565 
    566 	if (keyring_id == 0) {
    567 		printf("Invalid keyring [%s].\n", keyring);
    568 		exit(1);
    569 	}
    570 	sprintf(key_ref_full, "%s%s", EXT2FS_KEY_DESC_PREFIX,
    571 		salt->key_ref_str);
    572 	rc = keyctl(KEYCTL_SEARCH, keyring_id, EXT2FS_KEY_TYPE_LOGON,
    573 		    key_ref_full, 0);
    574 	if (rc != -1) {
    575 		if ((options & OPT_QUIET) == 0)
    576 			printf("Key with descriptor [%s] already exists\n",
    577 			       salt->key_ref_str);
    578 		return;
    579 	} else if ((rc == -1) && (errno != ENOKEY)) {
    580 		printf("keyctl_search failed: %s\n", strerror(errno));
    581 		if (errno == -EINVAL)
    582 			printf("Keyring [%s] is not available.\n", keyring);
    583 		exit(1);
    584 	}
    585 	key.mode = EXT4_ENCRYPTION_MODE_AES_256_XTS;
    586 	memcpy(key.raw, salt->key, EXT4_MAX_KEY_SIZE);
    587 	key.size = EXT4_MAX_KEY_SIZE;
    588 	rc = add_key(EXT2FS_KEY_TYPE_LOGON, key_ref_full, (void *)&key,
    589 		     sizeof(key), keyring_id);
    590 	if (rc == -1) {
    591 		if (errno == EDQUOT) {
    592 			printf("Error adding key to keyring; quota exceeded\n");
    593 		} else {
    594 			printf("Error adding key with key descriptor [%s]: "
    595 			       "%s\n", salt->key_ref_str, strerror(errno));
    596 		}
    597 		exit(1);
    598 	} else {
    599 		if ((options & OPT_QUIET) == 0)
    600 			printf("Added key with descriptor [%s]\n",
    601 			       salt->key_ref_str);
    602 	}
    603 }
    604 
    605 static void get_default_salts(void)
    606 {
    607 	FILE	*f = setmntent("/etc/mtab", "r");
    608 	struct mntent *mnt;
    609 
    610 	while (f && ((mnt = getmntent(f)) != NULL)) {
    611 		if (strcmp(mnt->mnt_type, "ext4") ||
    612 		    access(mnt->mnt_dir, R_OK))
    613 			continue;
    614 		parse_salt(mnt->mnt_dir, PARSE_FLAGS_NOTSUPP_OK);
    615 	}
    616 	endmntent(f);
    617 }
    618 
    619 /* Functions which implement user commands */
    620 
    621 struct cmd_desc {
    622 	const char *cmd_name;
    623 	void (*cmd_func)(int, char **, const struct cmd_desc *);
    624 	const char *cmd_desc;
    625 	const char *cmd_help;
    626 	int cmd_flags;
    627 };
    628 
    629 #define CMD_HIDDEN 	0x0001
    630 
    631 static void do_help(int argc, char **argv, const struct cmd_desc *cmd);
    632 
    633 #define add_key_desc "adds a key to the user's keyring"
    634 #define add_key_help \
    635 "e4crypt add_key -S salt [ -k keyring ] [-v] [-q] [ path ... ]\n\n" \
    636 "Prompts the user for a passphrase and inserts it into the specified\n" \
    637 "keyring.  If no keyring is specified, e4crypt will use the session\n" \
    638 "keyring if it exists or the user session keyring if it does not.\n\n" \
    639 "If one or more directory paths are specified, e4crypt will try to\n" \
    640 "set the policy of those directories to use the key just entered by\n" \
    641 "the user.\n"
    642 
    643 static void do_add_key(int argc, char **argv, const struct cmd_desc *cmd)
    644 {
    645 	struct salt *salt;
    646 	char *keyring = NULL;
    647 	int i, opt, pad = 4;
    648 	unsigned j;
    649 
    650 	while ((opt = getopt(argc, argv, "k:S:p:vq")) != -1) {
    651 		switch (opt) {
    652 		case 'k':
    653 			/* Specify a keyring. */
    654 			keyring = optarg;
    655 			break;
    656 		case 'p':
    657 			pad = atoi(optarg);
    658 			break;
    659 		case 'S':
    660 			/* Salt value for passphrase. */
    661 			parse_salt(optarg, 0);
    662 			break;
    663 		case 'v':
    664 			options |= OPT_VERBOSE;
    665 			break;
    666 		case 'q':
    667 			options |= OPT_QUIET;
    668 			break;
    669 		default:
    670 			fprintf(stderr, "Unrecognized option: %c\n", opt);
    671 		case '?':
    672 			fputs("USAGE:\n  ", stderr);
    673 			fputs(cmd->cmd_help, stderr);
    674 			exit(1);
    675 		}
    676 	}
    677 	if (num_salt == 0)
    678 		get_default_salts();
    679 	if (num_salt == 0) {
    680 		fprintf(stderr, "No salt values available\n");
    681 		exit(1);
    682 	}
    683 	validate_paths(argc, argv, optind);
    684 	for (i = optind; i < argc; i++)
    685 		parse_salt(argv[i], PARSE_FLAGS_FORCE_FN);
    686 	printf("Enter passphrase (echo disabled): ");
    687 	get_passphrase(in_passphrase, sizeof(in_passphrase));
    688 	for (j = 0, salt = salt_list; j < num_salt; j++, salt++) {
    689 		pbkdf2_sha512(in_passphrase, salt,
    690 			      EXT4_PBKDF2_ITERATIONS, salt->key);
    691 		generate_key_ref_str(salt);
    692 		insert_key_into_keyring(keyring, salt);
    693 	}
    694 	if (optind != argc)
    695 		set_policy(NULL, pad, argc, argv, optind);
    696 	clear_secrets();
    697 	exit(0);
    698 }
    699 
    700 #define set_policy_desc "sets a policy for directories"
    701 #define set_policy_help \
    702 "e4crypt set_policy policy path ... \n\n" \
    703 "Sets the policy for the directories specified on the command line.\n" \
    704 "All directories must be empty to set the policy; if the directory\n" \
    705 "already has a policy established, e4crypt will validate that it the\n" \
    706 "policy matches what was specified.  A policy is an encryption key\n" \
    707 "identifier consisting of 16 hexadecimal characters.\n"
    708 
    709 static void do_set_policy(int argc, char **argv, const struct cmd_desc *cmd)
    710 {
    711 	struct salt saltbuf;
    712 	int c, pad = 4;
    713 
    714 	while ((c = getopt (argc, argv, "p:")) != EOF) {
    715 		switch (c) {
    716 		case 'p':
    717 			pad = atoi(optarg);
    718 			break;
    719 		}
    720 	}
    721 
    722 	if (argc < optind + 2) {
    723 		fprintf(stderr, "Missing required argument(s).\n\n");
    724 		fputs("USAGE:\n  ", stderr);
    725 		fputs(cmd->cmd_help, stderr);
    726 		exit(1);
    727 	}
    728 
    729 	if ((strlen(argv[optind]) != (EXT4_KEY_DESCRIPTOR_SIZE * 2)) ||
    730 	    hex2byte(argv[optind], (EXT4_KEY_DESCRIPTOR_SIZE * 2),
    731 		     saltbuf.key_desc, EXT4_KEY_DESCRIPTOR_SIZE)) {
    732 		printf("Invalid key descriptor [%s]. Valid characters "
    733 		       "are 0-9 and a-f, lower case.  "
    734 		       "Length must be %d.\n",
    735 		       argv[optind], (EXT4_KEY_DESCRIPTOR_SIZE * 2));
    736 			exit(1);
    737 	}
    738 	validate_paths(argc, argv, optind+1);
    739 	strcpy(saltbuf.key_ref_str, argv[optind]);
    740 	set_policy(&saltbuf, pad, argc, argv, optind+1);
    741 	exit(0);
    742 }
    743 
    744 #define get_policy_desc "get the encryption for directories"
    745 #define get_policy_help \
    746 "e4crypt get_policy path ... \n\n" \
    747 "Gets the policy for the directories specified on the command line.\n"
    748 
    749 static void do_get_policy(int argc, char **argv, const struct cmd_desc *cmd)
    750 {
    751 	struct ext4_encryption_policy policy;
    752 	struct stat st;
    753 	int i, j, fd, rc;
    754 
    755 	if (argc < 2) {
    756 		fprintf(stderr, "Missing required argument(s).\n\n");
    757 		fputs("USAGE:\n  ", stderr);
    758 		fputs(cmd->cmd_help, stderr);
    759 		exit(1);
    760 	}
    761 
    762 	for (i = 1; i < argc; i++) {
    763 		if (stat(argv[i], &st) < 0) {
    764 			perror(argv[i]);
    765 			continue;
    766 		}
    767 		fd = open(argv[i],
    768 			  S_ISDIR(st.st_mode) ? O_DIRECTORY : O_RDONLY);
    769 		if (fd == -1) {
    770 			perror(argv[i]);
    771 			exit(1);
    772 		}
    773 		rc = ioctl(fd, EXT4_IOC_GET_ENCRYPTION_POLICY, &policy);
    774 		close(fd);
    775 		if (rc) {
    776 			printf("Error getting policy for %s: %s\n",
    777 			       argv[i], strerror(errno));
    778 			continue;
    779 		}
    780 		printf("%s: ", argv[i]);
    781 		for (j = 0; j < EXT4_KEY_DESCRIPTOR_SIZE; j++) {
    782 			printf("%02x", (unsigned char) policy.master_key_descriptor[j]);
    783 		}
    784 		fputc('\n', stdout);
    785 	}
    786 	exit(0);
    787 }
    788 
    789 #define new_session_desc "give the invoking process a new session keyring"
    790 #define new_session_help \
    791 "e4crypt new_session\n\n" \
    792 "Give the invoking process (typically a shell) a new session keyring,\n" \
    793 "discarding its old session keyring.\n"
    794 
    795 static void do_new_session(int argc, char **argv EXT2FS_ATTR((unused)),
    796 			   const struct cmd_desc *cmd)
    797 {
    798 	long keyid, ret;
    799 
    800 	if (argc > 1) {
    801 		fputs("Excess arguments\n\n", stderr);
    802 		fputs(cmd->cmd_help, stderr);
    803 		exit(1);
    804 	}
    805 	keyid = keyctl(KEYCTL_JOIN_SESSION_KEYRING, NULL);
    806 	if (keyid < 0) {
    807 		perror("KEYCTL_JOIN_SESSION_KEYRING");
    808 		exit(1);
    809 	}
    810 	ret = keyctl(KEYCTL_SESSION_TO_PARENT, NULL);
    811 	if (ret < 0) {
    812 		perror("KEYCTL_SESSION_TO_PARENT");
    813 		exit(1);
    814 	}
    815 	printf("Switched invoking process to new session keyring %ld\n", keyid);
    816 	exit(0);
    817 }
    818 
    819 #define CMD(name) { #name, do_##name, name##_desc, name##_help, 0 }
    820 #define _CMD(name) { #name, do_##name, NULL, NULL, CMD_HIDDEN }
    821 
    822 const struct cmd_desc cmd_list[] = {
    823 	_CMD(help),
    824 	CMD(add_key),
    825 	CMD(get_policy),
    826 	CMD(new_session),
    827 	CMD(set_policy),
    828 	{ NULL, NULL, NULL, NULL, 0 }
    829 };
    830 
    831 static void do_help(int argc, char **argv,
    832 		    const struct cmd_desc *cmd EXT2FS_ATTR((unused)))
    833 {
    834 	const struct cmd_desc *p;
    835 
    836 	if (argc > 1) {
    837 		for (p = cmd_list; p->cmd_name; p++) {
    838 			if (p->cmd_flags & CMD_HIDDEN)
    839 				continue;
    840 			if (strcmp(p->cmd_name, argv[1]) == 0) {
    841 				putc('\n', stdout);
    842 				fputs("USAGE:\n  ", stdout);
    843 				fputs(p->cmd_help, stdout);
    844 				exit(0);
    845 			}
    846 		}
    847 		printf("Unknown command: %s\n\n", argv[1]);
    848 	}
    849 
    850 	fputs("Available commands:\n", stdout);
    851 	for (p = cmd_list; p->cmd_name; p++) {
    852 		if (p->cmd_flags & CMD_HIDDEN)
    853 			continue;
    854 		printf("  %-20s %s\n", p->cmd_name, p->cmd_desc);
    855 	}
    856 	printf("\nTo get more information on a command, "
    857 	       "type 'e4crypt help cmd'\n");
    858 	exit(0);
    859 }
    860 
    861 int main(int argc, char *argv[])
    862 {
    863 	const struct cmd_desc *cmd;
    864 
    865 	if (argc < 2)
    866 		do_help(argc, argv, cmd_list);
    867 
    868 	sigcatcher_setup();
    869 	for (cmd = cmd_list; cmd->cmd_name; cmd++) {
    870 		if (strcmp(cmd->cmd_name, argv[1]) == 0) {
    871 			cmd->cmd_func(argc-1, argv+1, cmd);
    872 			exit(0);
    873 		}
    874 	}
    875 	printf("Unknown command: %s\n\n", argv[1]);
    876 	do_help(1, argv, cmd_list);
    877 	return 0;
    878 }
    879