X-Git-Url: https://git.whamcloud.com/?a=blobdiff_plain;f=misc%2Fe4crypt.c;h=2ae6254a23cb57b0c16659d7820954484ed81617;hb=c67897f5e0a1df037b7d324b44ec3bfe332c38a3;hp=c186eb83a4100064626c0369eca0b973c2da4b47;hpb=74f2c4aa18f231830c29cdbd278674628956d20d;p=tools%2Fe2fsprogs.git diff --git a/misc/e4crypt.c b/misc/e4crypt.c index c186eb8..2ae6254 100644 --- a/misc/e4crypt.c +++ b/misc/e4crypt.c @@ -93,16 +93,16 @@ static long keyctl(int cmd, ...) #endif #ifndef HAVE_ADD_KEY -key_serial_t add_key(const char *type, const char *description, - const void *payload, size_t plen, - key_serial_t keyring) +static key_serial_t add_key(const char *type, const char *description, + const void *payload, size_t plen, + key_serial_t keyring) { return syscall(__NR_add_key, type, description, payload, plen, keyring); } #endif -static const char *hexchars = "0123456789abcdef"; +static const unsigned char *hexchars = (const unsigned char *) "0123456789abcdef"; static const size_t hexchars_size = 16; #define SHA512_LENGTH 64 @@ -151,11 +151,11 @@ static void validate_paths(int argc, char *argv[], int path_start_index) exit(1); } -static int hex2byte(const char *hex, size_t hex_size, char *bytes, +static int hex2byte(const char *hex, size_t hex_size, unsigned char *bytes, size_t bytes_size) { - int x; - char *h, *l; + size_t x; + unsigned char *h, *l; if (hex_size % 2) return -EINVAL; @@ -187,11 +187,11 @@ struct salt { struct salt *salt_list; unsigned num_salt; unsigned max_salt; -char passphrase[EXT4_MAX_PASSPHRASE_SIZE]; +char in_passphrase[EXT4_MAX_PASSPHRASE_SIZE]; static struct salt *find_by_salt(unsigned char *salt, size_t salt_len) { - int i; + unsigned int i; struct salt *p; for (i = 0, p = salt_list; i < num_salt; i++, p++) @@ -225,17 +225,18 @@ static void clear_secrets(void) free(salt_list); salt_list = NULL; } - memset(passphrase, 0, sizeof(passphrase)); + memset(in_passphrase, 0, sizeof(in_passphrase)); } -static void die_signal_handler(int signum, siginfo_t *siginfo, - void *context) +static void die_signal_handler(int signum EXT2FS_ATTR((unused)), + siginfo_t *siginfo EXT2FS_ATTR((unused)), + void *context EXT2FS_ATTR((unused))) { clear_secrets(); exit(-1); } -void sigcatcher_setup(void) +static void sigcatcher_setup(void) { struct sigaction sa; @@ -272,9 +273,9 @@ void sigcatcher_setup(void) static void parse_salt(char *salt_str, int flags) { unsigned char buf[EXT4_MAX_SALT_SIZE]; - unsigned char *salt_buf, *cp = salt_str; - char tmp[80]; - int i, fd, ret, salt_len = 0; + char *cp = salt_str; + unsigned char *salt_buf; + int fd, ret, salt_len = 0; if (flags & PARSE_FLAGS_FORCE_FN) goto salt_from_filename; @@ -283,7 +284,7 @@ static void parse_salt(char *salt_str, int flags) salt_len = strlen(cp); if (salt_len >= EXT4_MAX_SALT_SIZE) goto invalid_salt; - strncpy(buf, cp, sizeof(buf)); + strncpy((char *) buf, cp, sizeof(buf)); } else if (cp[0] == '/') { salt_from_filename: fd = open(cp, O_RDONLY | O_DIRECTORY); @@ -311,7 +312,7 @@ static void parse_salt(char *salt_str, int flags) cp += 2; goto salt_from_filename; } else if (strncmp(cp, "0x", 2) == 0) { - char *h, *l; + unsigned char *h, *l; cp += 2; if (strlen(cp) & 1) @@ -401,27 +402,28 @@ static void set_policy(struct salt *set_salt, int pad, } } -static void pbkdf2_sha512(const char *passphrase, struct salt *salt, int count, - char derived_key[EXT4_MAX_KEY_SIZE]) +static void pbkdf2_sha512(const char *passphrase, struct salt *salt, + unsigned int count, + unsigned char derived_key[EXT4_MAX_KEY_SIZE]) { size_t passphrase_size = strlen(passphrase); - char buf[SHA512_LENGTH + EXT4_MAX_PASSPHRASE_SIZE] = {0}; - char tempbuf[SHA512_LENGTH] = {0}; + unsigned char buf[SHA512_LENGTH + EXT4_MAX_PASSPHRASE_SIZE] = {0}; + unsigned char tempbuf[SHA512_LENGTH] = {0}; char final[SHA512_LENGTH] = {0}; - char saltbuf[EXT4_MAX_SALT_SIZE + EXT4_MAX_PASSPHRASE_SIZE] = {0}; + unsigned char saltbuf[EXT4_MAX_SALT_SIZE + EXT4_MAX_PASSPHRASE_SIZE] = {0}; int actual_buf_len = SHA512_LENGTH + passphrase_size; int actual_saltbuf_len = EXT4_MAX_SALT_SIZE + passphrase_size; - int x, y; + unsigned int x, y; __u32 *final_u32 = (__u32 *)final; __u32 *temp_u32 = (__u32 *)tempbuf; if (passphrase_size > EXT4_MAX_PASSPHRASE_SIZE) { - printf("Passphrase size is %d; max is %d.\n", passphrase_size, + printf("Passphrase size is %zd; max is %d.\n", passphrase_size, EXT4_MAX_PASSPHRASE_SIZE); exit(1); } if (salt->salt_len > EXT4_MAX_SALT_SIZE) { - printf("Salt size is %d; max is %d.\n", salt->salt_len, + printf("Salt size is %zd; max is %d.\n", salt->salt_len, EXT4_MAX_SALT_SIZE); exit(1); } @@ -463,7 +465,7 @@ static int disable_echo(struct termios *saved_settings) return rc; } -void get_passphrase(char *passphrase, int len) +static void get_passphrase(char *passphrase, int len) { char *p; struct termios current_settings; @@ -500,35 +502,23 @@ static const struct keyring_map keyrings[] = { static int get_keyring_id(const char *keyring) { - int x; + unsigned int x; char *end; /* * If no keyring is specified, by default use either the user - * session key ring or the session keyring. Fetching the + * session keyring or the session keyring. Fetching the * session keyring will return the user session keyring if no * session keyring has been set. - * - * We need to do this instead of simply adding the key to - * KEY_SPEC_SESSION_KEYRING since trying to add a key to a - * session keyring that does not yet exist will cause the - * kernel to create a session keyring --- which wil then get - * garbage collected as soon as e4crypt exits. - * - * The fact that the keyctl system call and the add_key system - * call treats KEY_SPEC_SESSION_KEYRING differently when a - * session keyring does not exist is very unfortunate and - * confusing, but so it goes... */ if (keyring == NULL) - return keyctl(KEYCTL_GET_KEYRING_ID, - KEY_SPEC_SESSION_KEYRING, 0); + return KEY_SPEC_SESSION_KEYRING; for (x = 0; x < (sizeof(keyrings) / sizeof(keyrings[0])); ++x) { if (strcmp(keyring, keyrings[x].name) == 0) { return keyrings[x].code; } } - x = strtol(keyring, &end, 10); + x = strtoul(keyring, &end, 10); if (*end == '\0') { if (keyctl(KEYCTL_DESCRIBE, x, NULL, 0) < 0) return 0; @@ -539,8 +529,8 @@ static int get_keyring_id(const char *keyring) static void generate_key_ref_str(struct salt *salt) { - char key_ref1[SHA512_LENGTH]; - char key_ref2[SHA512_LENGTH]; + unsigned char key_ref1[SHA512_LENGTH]; + unsigned char key_ref2[SHA512_LENGTH]; int x; ext2fs_sha512(salt->key, EXT4_MAX_KEY_SIZE, key_ref1); @@ -576,13 +566,34 @@ static void insert_key_into_keyring(const char *keyring, struct salt *salt) return; } else if ((rc == -1) && (errno != ENOKEY)) { printf("keyctl_search failed: %s\n", strerror(errno)); - if (errno == -EINVAL) + if (errno == EINVAL) printf("Keyring [%s] is not available.\n", keyring); exit(1); } key.mode = EXT4_ENCRYPTION_MODE_AES_256_XTS; memcpy(key.raw, salt->key, EXT4_MAX_KEY_SIZE); key.size = EXT4_MAX_KEY_SIZE; + + /* + * We need to do this instead of simply adding the key to + * KEY_SPEC_SESSION_KEYRING since trying to add a key to a + * session keyring that does not yet exist will cause the + * kernel to create a session keyring --- which will then get + * garbage collected as soon as e4crypt exits. + * + * The fact that the keyctl system call and the add_key system + * call treats KEY_SPEC_SESSION_KEYRING differently when a + * session keyring does not exist is very unfortunate and + * confusing, but so it goes... + */ + if (keyring_id == KEY_SPEC_SESSION_KEYRING) { + keyring_id = keyctl(KEYCTL_GET_KEYRING_ID, keyring_id, 0); + if (keyring_id < 0) { + printf("Error getting session keyring ID: %s\n", + strerror(errno)); + exit(1); + } + } rc = add_key(EXT2FS_KEY_TYPE_LOGON, key_ref_full, (void *)&key, sizeof(key), keyring_id); if (rc == -1) { @@ -600,12 +611,7 @@ static void insert_key_into_keyring(const char *keyring, struct salt *salt) } } -static int is_keyring_valid(const char *keyring) -{ - return (get_keyring_id(keyring) != 0); -} - -void get_default_salts(void) +static void get_default_salts(void) { FILE *f = setmntent("/etc/mtab", "r"); struct mntent *mnt; @@ -631,11 +637,11 @@ struct cmd_desc { #define CMD_HIDDEN 0x0001 -void do_help(int argc, char **argv, const struct cmd_desc *cmd); +static void do_help(int argc, char **argv, const struct cmd_desc *cmd); #define add_key_desc "adds a key to the user's keyring" #define add_key_help \ -"e4crypt add_key -S salt [ -k keyring ] [-v] [-q] [ path ... ]\n\n" \ +"e4crypt add_key -S salt [ -k keyring ] [-v] [-q] [ -p pad ] [ path ... ]\n\n" \ "Prompts the user for a passphrase and inserts it into the specified\n" \ "keyring. If no keyring is specified, e4crypt will use the session\n" \ "keyring if it exists or the user session keyring if it does not.\n\n" \ @@ -643,11 +649,12 @@ void do_help(int argc, char **argv, const struct cmd_desc *cmd); "set the policy of those directories to use the key just entered by\n" \ "the user.\n" -void do_add_key(int argc, char **argv, const struct cmd_desc *cmd) +static void do_add_key(int argc, char **argv, const struct cmd_desc *cmd) { struct salt *salt; char *keyring = NULL; int i, opt, pad = 4; + unsigned j; while ((opt = getopt(argc, argv, "k:S:p:vq")) != -1) { switch (opt) { @@ -669,8 +676,10 @@ void do_add_key(int argc, char **argv, const struct cmd_desc *cmd) options |= OPT_QUIET; break; default: - fprintf(stderr, "Unrecognized option: %c\n", opt); case '?': + if (opt != '?') + fprintf(stderr, "Unrecognized option: %c\n", + opt); fputs("USAGE:\n ", stderr); fputs(cmd->cmd_help, stderr); exit(1); @@ -686,9 +695,9 @@ void do_add_key(int argc, char **argv, const struct cmd_desc *cmd) for (i = optind; i < argc; i++) parse_salt(argv[i], PARSE_FLAGS_FORCE_FN); printf("Enter passphrase (echo disabled): "); - get_passphrase(passphrase, sizeof(passphrase)); - for (i = 0, salt = salt_list; i < num_salt; i++, salt++) { - pbkdf2_sha512(passphrase, salt, + get_passphrase(in_passphrase, sizeof(in_passphrase)); + for (j = 0, salt = salt_list; j < num_salt; j++, salt++) { + pbkdf2_sha512(in_passphrase, salt, EXT4_PBKDF2_ITERATIONS, salt->key); generate_key_ref_str(salt); insert_key_into_keyring(keyring, salt); @@ -701,20 +710,17 @@ void do_add_key(int argc, char **argv, const struct cmd_desc *cmd) #define set_policy_desc "sets a policy for directories" #define set_policy_help \ -"e4crypt set_policy policy path ... \n\n" \ +"e4crypt set_policy [ -p pad ] policy path ... \n\n" \ "Sets the policy for the directories specified on the command line.\n" \ "All directories must be empty to set the policy; if the directory\n" \ "already has a policy established, e4crypt will validate that it the\n" \ "policy matches what was specified. A policy is an encryption key\n" \ "identifier consisting of 16 hexadecimal characters.\n" -void do_set_policy(int argc, char **argv, const struct cmd_desc *cmd) +static void do_set_policy(int argc, char **argv, const struct cmd_desc *cmd) { - struct salt *salt, saltbuf; - char *key_ref_str = NULL; - char *keyring = NULL; - int add_passphrase = 0; - int i, c, opt, pad = 4; + struct salt saltbuf; + int c, pad = 4; while ((c = getopt (argc, argv, "p:")) != EOF) { switch (c) { @@ -731,10 +737,6 @@ void do_set_policy(int argc, char **argv, const struct cmd_desc *cmd) exit(1); } - printf("arg %s\n", argv[optind]); - exit(0); - - strcpy(saltbuf.key_ref_str, argv[optind]); if ((strlen(argv[optind]) != (EXT4_KEY_DESCRIPTOR_SIZE * 2)) || hex2byte(argv[optind], (EXT4_KEY_DESCRIPTOR_SIZE * 2), saltbuf.key_desc, EXT4_KEY_DESCRIPTOR_SIZE)) { @@ -745,6 +747,7 @@ void do_set_policy(int argc, char **argv, const struct cmd_desc *cmd) exit(1); } validate_paths(argc, argv, optind+1); + strcpy(saltbuf.key_ref_str, argv[optind]); set_policy(&saltbuf, pad, argc, argv, optind+1); exit(0); } @@ -754,10 +757,9 @@ void do_set_policy(int argc, char **argv, const struct cmd_desc *cmd) "e4crypt get_policy path ... \n\n" \ "Gets the policy for the directories specified on the command line.\n" -void do_get_policy(int argc, char **argv, const struct cmd_desc *cmd) +static void do_get_policy(int argc, char **argv, const struct cmd_desc *cmd) { struct ext4_encryption_policy policy; - struct stat st; int i, j, fd, rc; if (argc < 2) { @@ -768,12 +770,7 @@ void do_get_policy(int argc, char **argv, const struct cmd_desc *cmd) } for (i = 1; i < argc; i++) { - if (stat(argv[i], &st) < 0) { - perror(argv[i]); - continue; - } - fd = open(argv[i], - S_ISDIR(st.st_mode) ? O_DIRECTORY : O_RDONLY); + fd = open(argv[i], O_RDONLY); if (fd == -1) { perror(argv[i]); exit(1); @@ -794,13 +791,14 @@ void do_get_policy(int argc, char **argv, const struct cmd_desc *cmd) exit(0); } -#define new_session_desc "given the invoking process a new session keyring" +#define new_session_desc "give the invoking process a new session keyring" #define new_session_help \ -"e4crypt new_sessoin\n\n" \ +"e4crypt new_session\n\n" \ "Give the invoking process (typically a shell) a new session keyring,\n" \ "discarding its old session keyring.\n" -void do_new_session(int argc, char **argv, const struct cmd_desc *cmd) +static void do_new_session(int argc, char **argv EXT2FS_ATTR((unused)), + const struct cmd_desc *cmd) { long keyid, ret; @@ -832,10 +830,11 @@ const struct cmd_desc cmd_list[] = { CMD(get_policy), CMD(new_session), CMD(set_policy), - { NULL, NULL, NULL, NULL } + { NULL, NULL, NULL, NULL, 0 } }; -void do_help(int argc, char **argv, const struct cmd_desc *cmd) +static void do_help(int argc, char **argv, + const struct cmd_desc *cmd EXT2FS_ATTR((unused))) { const struct cmd_desc *p; @@ -859,7 +858,7 @@ void do_help(int argc, char **argv, const struct cmd_desc *cmd) continue; printf(" %-20s %s\n", p->cmd_name, p->cmd_desc); } - printf("\nTo get more information on a commnd, " + printf("\nTo get more information on a command, " "type 'e4crypt help cmd'\n"); exit(0); } @@ -871,6 +870,7 @@ int main(int argc, char *argv[]) if (argc < 2) do_help(argc, argv, cmd_list); + sigcatcher_setup(); for (cmd = cmd_list; cmd->cmd_name; cmd++) { if (strcmp(cmd->cmd_name, argv[1]) == 0) { cmd->cmd_func(argc-1, argv+1, cmd);