diff options
| author | Mattias Andrée <maandree@kth.se> | 2023-06-23 19:15:49 +0200 | 
|---|---|---|
| committer | Mattias Andrée <maandree@kth.se> | 2023-06-23 19:15:49 +0200 | 
| commit | 7281ae7db4d9bc9eb2b59134e1dea1231013f1af (patch) | |
| tree | 14d15e56dea896c71b0b4576a9633ea759080d58 | |
| parent | Fix exit status (diff) | |
| download | key2root-7281ae7db4d9bc9eb2b59134e1dea1231013f1af.tar.gz key2root-7281ae7db4d9bc9eb2b59134e1dea1231013f1af.tar.bz2 key2root-7281ae7db4d9bc9eb2b59134e1dea1231013f1af.tar.xz | |
Use libar2simplified instead of crypt as crypt has a verily limited imput size, and add -h to key2root-addkey, and add key2root-crypt
Signed-off-by: Mattias Andrée <maandree@kth.se>
Diffstat (limited to '')
| -rw-r--r-- | .gitignore | 3 | ||||
| -rw-r--r-- | Makefile | 23 | ||||
| -rw-r--r-- | README | 4 | ||||
| -rw-r--r-- | config.mk | 7 | ||||
| -rw-r--r-- | crypt.c | 61 | ||||
| -rw-r--r-- | crypt.h | 13 | ||||
| -rw-r--r-- | key2root-addkey.8 | 21 | ||||
| -rw-r--r-- | key2root-addkey.c | 116 | ||||
| -rw-r--r-- | key2root-crypt.8 | 109 | ||||
| -rw-r--r-- | key2root-crypt.c | 78 | ||||
| -rw-r--r-- | key2root-lskeys.8 | 3 | ||||
| -rw-r--r-- | key2root-rmkey.8 | 3 | ||||
| -rw-r--r-- | key2root.8 | 1 | ||||
| -rw-r--r-- | key2root.c | 12 | 
14 files changed, 360 insertions, 94 deletions
| @@ -13,6 +13,7 @@  *.gcno  *.gcda  /key2root -/key2root-lskeys  /key2root-addkey +/key2root-crypt +/key2root-lskeys  /key2root-rmkey @@ -3,12 +3,12 @@  CONFIGFILE = config.mk  include $(CONFIGFILE) -BIN = key2root key2root-lskeys key2root-addkey key2root-rmkey +BIN = key2root key2root-lskeys key2root-addkey key2root-rmkey key2root-crypt -HDR = arg.h +HDR = arg.h crypt.h  MAN8 = $(BIN:=.8) -OBJ = $(BIN:=.o) +OBJ = $(BIN:=.o) crypt.o  all: $(BIN)  $(OBJ): $(HDR) @@ -16,11 +16,20 @@ $(OBJ): $(HDR)  .c.o:  	$(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS) -.o: -	$(CC) -o $@ $< $(LDFLAGS) +key2root: key2root.o crypt.o +	$(CC) -o $@ $@.o crypt.o $(LDFLAGS_CRYPT) -.c: -	$(CC) -o $@ $< $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) +key2root-lskeys: key2root-lskeys.o +	$(CC) -o $@ $@.o $(LDFLAGS) + +key2root-addkey: key2root-addkey.o crypt.o +	$(CC) -o $@ $@.o crypt.o $(LDFLAGS_CRYPT) + +key2root-rmkey: key2root-rmkey.o +	$(CC) -o $@ $@.o $(LDFLAGS) + +key2root-crypt: key2root-crypt.o crypt.o +	$(CC) -o $@ $@.o crypt.o $(LDFLAGS_CRYPT)  install: $(BIN)  	mkdir -p -- "$(DESTDIR)$(PREFIX)/bin" @@ -45,5 +45,5 @@ RATIONALE  	authenticated himself rather also requiring his password.  SEE ALSO -	key2root-addkey(8), key2root-lskeys(8), key2root-rmkey(8), asroot(8), -	sudo(8), doas(1), su(1) +	key2root-addkey(8), key2root-crypt(8), key2root-lskeys(8), +	key2root-rmkey(8), asroot(8), sudo(8), doas(1), su(1) @@ -5,6 +5,7 @@ KEYPATH = /etc/key2root  CC = cc -CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE -D'KEYPATH="$(KEYPATH)"' -CFLAGS   = -std=c99 -Wall -O2 -LDFLAGS  = -lcrypt +CPPFLAGS      = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE -D'KEYPATH="$(KEYPATH)"' +CFLAGS        = -std=c99 -Wall -O2 +LDFLAGS       = +LDFLAGS_CRYPT = $(LDFLAGS) -lar2simplified -lar2 -lblake -pthread @@ -0,0 +1,61 @@ +/* See LICENSE file for copyright and license details. */ +#include "crypt.h" +#include <errno.h> +#include <stdlib.h> +#include <stdio.h> +#include <string.h> +#include <libar2simplified.h> +#include <libar2.h> + +extern char *argv0; + + +char * +key2root_crypt(char *msg, size_t msglen, const char *paramstr, int autoerase) +{ +	struct libar2_argon2_parameters *params = NULL; +	char *end, *ret = NULL, *hash = NULL; +	size_t size; +	struct libar2_context ctx; + +	libar2simplified_init_context(&ctx); +	ctx.autoerase_message = (unsigned char)autoerase; + +	if (!paramstr) +		paramstr = libar2simplified_recommendation(0); + +	params = libar2simplified_decode_r(paramstr, NULL, &end, NULL, NULL); +	if (!params) { +		fprintf(stderr, "%s: libar2simplified_decode_r %s: %s\n", argv0, paramstr, strerror(errno)); +		return NULL; +	} +	if (*end) { +		fprintf(stderr, "%s: libar2simplified_decode_r %s: excess data at end parameter string: %s\n", argv0, paramstr, end); +		goto out; +	} + +	size = libar2_hash_buf_size(params); +	if (!size) +		abort(); +	if (!size || !(hash = malloc(size))) { +		fprintf(stderr, "%s: malloc %zu: %s\n", argv0, size, strerror(errno)); +		goto out; +	} + +	if (libar2_hash(hash, msg, msglen, params, &ctx)) { +		if (autoerase) +			libar2_erase(msg, msglen); +		fprintf(stderr, "%s: libar2simplified_hash %s: %s\n", argv0, paramstr, strerror(errno)); +		goto out; +	} + +	ret = libar2simplified_encode(params, hash); + +out: +	if (params) { +		libar2_erase(params->salt, params->saltlen); +		free(params); +	} +	free(hash); +	return ret; +} @@ -0,0 +1,13 @@ +/* See LICENSE file for copyright and license details. */ +#include <stddef.h> +#include <libar2.h> + +char *key2root_crypt(char *msg, size_t msglen, const char *paramstr, int autoerase); + + +#define explicit_bzero key2root_erase +static inline void +key2root_erase(void *msg, size_t msglen) +{ +	libar2_erase(msg, msglen); +} diff --git a/key2root-addkey.8 b/key2root-addkey.8 index 9faf335..1594d7f 100644 --- a/key2root-addkey.8 +++ b/key2root-addkey.8 @@ -6,9 +6,13 @@ key2root-addkey - add a keyfile for privilege escalation with key2root  .SH SYNOPSIS  .B key2root-addkey  [-r] -.I user +.RI (user  .I key-name  .RI [ crypt-parameters ] +| -h +.I user +.I key-name +.IR key-hash )  .SH DESCRIPTION  The @@ -45,19 +49,27 @@ The name the keyfile shall be given.  May not include whitespace characters.  .TP  .I crypt-parameters -crypt(3) parameters that the keyfile shall be hashed with. +.BR libar2simplified_crypt (3) +parameters that the keyfile shall be hashed with. +.TP +.I key-hash +.BR key2root-crypt (8) +hash of the keyfile.  .SH STDIN  The  .B key2root-addkey  utility reads the keyfile to add from standard input, -which must not be a TTY. +which must not be a TTY. However if the +.B -h +option is used, the standard input is not used and +may be a TTY.  .SH INPUT FILES  None.  .SH ENVIRONMENT VARIABLES -No following environment variable affects the execution of +No environment variables affect the execution of  .BR key2root-addkey .  .SH ASYNCHRONOUS EVENTS @@ -111,6 +123,7 @@ None.  .SH SEE ALSO  .BR key2root (8), +.BR key2root-crypt (8),  .BR key2root-lskeys (8),  .BR key2root-rmkey (8) diff --git a/key2root-addkey.c b/key2root-addkey.c index 989aa8f..cbb1d0e 100644 --- a/key2root-addkey.c +++ b/key2root-addkey.c @@ -1,6 +1,4 @@  /* See LICENSE file for copyright and license details. */ -#include <sys/auxv.h> -#include <sys/mman.h>  #include <sys/stat.h>  #include <errno.h>  #include <fcntl.h> @@ -11,6 +9,7 @@  #include <unistd.h>  #include "arg.h" +#include "crypt.h"  char *argv0; @@ -19,7 +18,7 @@ char *argv0;  static void  usage(void)  { -	fprintf(stderr, "usage: %s [-r] user key-name [crypt-parameters]\n", argv0); +	fprintf(stderr, "usage: %s [-r] (user key-name [crypt-parameters] | -h user key-name key-hash)\n", argv0);  	exit(1);  } @@ -119,27 +118,6 @@ loadandlocate(size_t *beginning_out, size_t *end_out, int fd, char **datap, size  } -static char * -mksalt(char *p) -{ -	uintptr_t rdata_addr; -	char *rdata; -	size_t i; - -	rdata_addr = (uintptr_t)getauxval(AT_RANDOM); /* address to 16 random bytes */ -	rdata = (void *)rdata_addr; -	if (!rdata) { -		fprintf(stderr, "%s: getauxval AT_RANDOM: %s\n", argv0, strerror(errno)); -		exit(1); -	} - -	for (i = 0; i < 16; i++) -		*p++ = "qwertyuiopasdfghjklzxcvbnmQWERTYUIOPASDFGHJKLZXCVBNM0123456789./"[*rdata++ & 63]; - -	return p; -} - -  int  main(int argc, char *argv[])  { @@ -153,6 +131,7 @@ main(int argc, char *argv[])  	size_t beginning = 0;  	size_t end = 0;  	int allow_replace = 0; +	int add_hash = 0;  	int failed = 0;  	int fd;  	char *key = NULL, *new; @@ -161,12 +140,13 @@ main(int argc, char *argv[])  	char *hash;  	size_t gap_size;  	size_t gap_increase; -#define HASH_PREFIX "$6$" -	char generated_parameters[sizeof(HASH_PREFIX"$") + 16];  	ssize_t r;  	size_t i;  	ARGBEGIN { +	case 'h': +		add_hash = 1; +		break;  	case 'r':  		allow_replace = 1;  		break; @@ -189,60 +169,64 @@ main(int argc, char *argv[])  		fprintf(stderr, "%s: bad key name specified: %s, includes whitespace\n", argv0, keyname);  		failed = 1;  	} -	if (isatty(STDIN_FILENO)) { +	if (!add_hash && isatty(STDIN_FILENO)) {  		fprintf(stderr, "%s: standard input must not be a TTY.\n", argv0);  		failed = 1;  	}  	if (failed)  		return 1; -	if (mlockall(MCL_CURRENT | MCL_FUTURE)) -		fprintf(stderr, "%s: mlockall MCL_CURRENT|MCL_FUTURE: %s\n", argv0, strerror(errno)); - -	if (!parameters) { -		stpcpy(mksalt(stpcpy(generated_parameters, HASH_PREFIX)), "$"); -		parameters = generated_parameters; -	} - -	for (;;) { -		if (key_len == key_size) { -			new = malloc(1 + (key_size += 1024)); -			if (!new) { +	if (add_hash) { +		for (i = 0; parameters[i]; i++) { +			if (parameters[i] <= ' ' || parameters[i] >= 127) { +				fprintf(stderr, "%s: key-hash may only contain printable ASCII characters\n", argv0); +				exit(1); +			} +		} +		key_size = key_len = strlen(keyname) + strlen(parameters) + 2; +		key = malloc(key_len + 1); +		if (!key) { +			fprintf(stderr, "%s: malloc: %s\n", argv0, strerror(errno)); +			exit(1); +		} +		stpcpy(stpcpy(stpcpy(stpcpy(key, keyname), " "), parameters), "\n"); +	} else { +		for (;;) { +			if (key_len == key_size) { +				new = malloc(1 + (key_size += 1024)); +				if (!new) { +					explicit_bzero(key, key_len); +					fprintf(stderr, "%s: read <stdin>: %s\n", argv0, strerror(errno)); +					exit(1); +				} +				memcpy(new, key, key_len); +				explicit_bzero(key, key_len); +				free(key); +				key = new; +			} +			r = read(STDIN_FILENO, &key[key_len], key_size - key_len); +			if (r <= 0) { +				if (!r) +					break;  				explicit_bzero(key, key_len);  				fprintf(stderr, "%s: read <stdin>: %s\n", argv0, strerror(errno));  				exit(1);  			} -			memcpy(new, key, key_len); -			explicit_bzero(key, key_len); -			free(key); -			key = new; +			key_len += (size_t)r;  		} -		r = read(STDIN_FILENO, &key[key_len], key_size - key_len); -		if (r <= 0) { -			if (!r) -				break; -			explicit_bzero(key, key_len); -			fprintf(stderr, "%s: read <stdin>: %s\n", argv0, strerror(errno)); +		hash = key2root_crypt(key, key_len, parameters, 1); +		if (!hash) +			exit(1); +		free(key); +		key_size = key_len = strlen(keyname) + strlen(hash) + 2; +		key = malloc(key_len + 1); +		if (!key) { +			fprintf(stderr, "%s: malloc: %s\n", argv0, strerror(errno));  			exit(1);  		} -		key_len += (size_t)r; -	} -	for (i = 0; i < key_len; i++) -		if (!key[i]) -			key[i] = (char)255; -	key[key_len] = '\0'; -	hash = crypt(key, parameters); -	if (!hash) -		fprintf(stderr, "%s: crypt <key> %s: %s\n", argv0, parameters, strerror(errno)); -	explicit_bzero(key, key_len); -	free(key); -	key_size = key_len = strlen(keyname) + strlen(hash) + 2; -	key = malloc(key_len + 1); -	if (!key) { -		fprintf(stderr, "%s: malloc: %s\n", argv0, strerror(errno)); -		exit(1); +		stpcpy(stpcpy(stpcpy(stpcpy(key, keyname), " "), hash), "\n"); +		free(hash);  	} -	stpcpy(stpcpy(stpcpy(stpcpy(key, keyname), " "), hash), "\n");  	path = malloc(sizeof(KEYPATH"/") + strlen(user));  	if (!path) { diff --git a/key2root-crypt.8 b/key2root-crypt.8 new file mode 100644 index 0000000..7e0bf33 --- /dev/null +++ b/key2root-crypt.8 @@ -0,0 +1,109 @@ +.TH KEY2ROOT 8 key2root-crypt + +.SH NAME +key2root-crypt - generate key hash for key2root + +.SH SYNOPSIS +.B key2root-crypt +.RI [ crypt-parameters ] + +.SH DESCRIPTION +The +.B key2root-crypt +utility takes a keyfile from the standard input and computes +its cryptographic as stored by the +.BR key2root-addkey (8) +utility. + +.SH OPTIONS +The +.B key2root-crypt +utility conforms to the Base Definitions volume of POSIX.1-2017, +.IR "Section 12.2" , +.IR "Utility Syntax Guidelines" . +.PP +No options are supported. + +.SH OPERANDS +The following operands are supported: +.TP +.I crypt-parameters +.BR libar2simplified_crypt (3) +parameters that the keyfile shall be hashed with. + +.SH STDIN +The +.B key2root-crypt +utility reads the keyfile to add from standard input. + +.SH INPUT FILES +None. + +.SH ENVIRONMENT VARIABLES +No environment variable affect the execution of +.BR key2root-crypt . + +.SH ASYNCHRONOUS EVENTS +Default. + +.SH STDOUT +The +.B key2root-crypt +utility prints the hash of the key files to the standard output, in the following format: +.RS +.nf + +\fB\(dq%s\en\(dq, \fP<\fIkey-hash\fP> +.fi +.RE + +.SH STDERR +The standard error is used for diagnostic messages. + +.SH OUTPUT FILES +None. + +.SH EXTENDED DESCRIPTION +None. + +.SH EXIT STATUS +If the +.B key2root-crypt +utility fails it will exit with one of the following statuses: +.TP +0 +Successful completion. +.TP +1 +A error occurred. + +.SH CONSEQUENCES OF ERRORS +Default. + +.SH APPLICATION USAGE +None. + +.SH EXAMPLES +None. + +.SH RATIONALE +None. + +.SH NOTES +None. + +.SH BUGS +None. + +.SH FUTURE DIRECTIONS +None. + +.SH SEE ALSO +.BR key2root (8), +.BR key2root-addkey (8), +.BR key2root-lskeys (8), +.BR key2root-rmkey (8) + +.SH AUTHORS +Mattias Andrée +.RI < maandree@kth.se > diff --git a/key2root-crypt.c b/key2root-crypt.c new file mode 100644 index 0000000..961e00c --- /dev/null +++ b/key2root-crypt.c @@ -0,0 +1,78 @@ +/* See LICENSE file for copyright and license details. */ +#include <errno.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include "arg.h" +#include "crypt.h" + + +char *argv0; + + +static void +usage(void) +{ +	fprintf(stderr, "usage: %s [crypt-parameters]\n", argv0); +	exit(1); +} + + +int +main(int argc, char *argv[]) +{ +	const char *parameters; +	char *key = NULL, *new; +	size_t key_len = 0; +	size_t key_size = 0; +	char *hash; +	ssize_t r; + +	ARGBEGIN { +	default: +		usage(); +	} ARGEND; + +	if (argc > 1) +		usage(); + +	parameters = argv[0]; + +	for (;;) { +		if (key_len == key_size) { +			new = malloc(1 + (key_size += 1024)); +			if (!new) { +				explicit_bzero(key, key_len); +				fprintf(stderr, "%s: read <stdin>: %s\n", argv0, strerror(errno)); +				exit(1); +			} +			memcpy(new, key, key_len); +			explicit_bzero(key, key_len); +			free(key); +			key = new; +		} +		r = read(STDIN_FILENO, &key[key_len], key_size - key_len); +		if (r <= 0) { +			if (!r) +				break; +			explicit_bzero(key, key_len); +			fprintf(stderr, "%s: read <stdin>: %s\n", argv0, strerror(errno)); +			exit(1); +		} +		key_len += (size_t)r; +	} +	hash = key2root_crypt(key, key_len, parameters, 1); +	if (!hash) +		exit(1); +	free(key); +	printf("%s\n", hash); +	free(hash); + +	if (fflush(stdout) || ferror(stdout) || fclose(stdout)) { +		fprintf(stderr, "%s: printf: %s\n", argv0, strerror(errno)); +		exit(1); +	} +	return 0; +} diff --git a/key2root-lskeys.8 b/key2root-lskeys.8 index f6f58cf..1df2713 100644 --- a/key2root-lskeys.8 +++ b/key2root-lskeys.8 @@ -45,7 +45,7 @@ utility does not use the standard input.  None.  .SH ENVIRONMENT VARIABLES -No following environment variable affects the execution of +No environment variables affect the execution of  .BR key2root-lskeys .  .SH ASYNCHRONOUS EVENTS @@ -111,6 +111,7 @@ None.  .SH SEE ALSO  .BR key2root (8),  .BR key2root-addkey (8), +.BR key2root-crypt (8),  .BR key2root-rmkey (8)  .SH AUTHORS diff --git a/key2root-rmkey.8 b/key2root-rmkey.8 index d79544c..ce93754 100644 --- a/key2root-rmkey.8 +++ b/key2root-rmkey.8 @@ -47,7 +47,7 @@ utility does not use the standard input.  None.  .SH ENVIRONMENT VARIABLES -No following environment variable affects the execution of +No environment variables affect the execution of  .BR key2root-rmkey .  .SH ASYNCHRONOUS EVENTS @@ -112,6 +112,7 @@ None.  .SH SEE ALSO  .BR key2root (8),  .BR key2root-addkey (8), +.BR key2root-crypt (8),  .BR key2root-lskeys (8)  .SH AUTHORS @@ -151,6 +151,7 @@ None.  .SH SEE ALSO  .BR key2root-addkey (8), +.BR key2root-crypt (8),  .BR key2root-lskeys (8),  .BR key2root-rmkey (8),  .BR asroot (8), @@ -12,6 +12,7 @@  #include <unistd.h>  #include "arg.h" +#include "crypt.h"  #define EXIT_AUTH   124 @@ -276,8 +277,9 @@ checkauth(char *data, size_t whead, size_t *rheadp, size_t *rhead2p, size_t *lin  		*rheadp += keyname_len + 1;  		*key_foundp = 1;  		data[(*rhead2p)++] = '\0'; -		hash = crypt(key, &data[*rheadp]); +		hash = key2root_crypt(key, key_len, &data[*rheadp], 0);  		match = hash && hashequal(hash, &data[*rheadp]); +		free(hash);  		*rheadp = *rhead2p;  		return match;  	} @@ -360,7 +362,6 @@ main(int argc, char *argv[])  	char path_user_id[sizeof(KEYPATH"/") + 3 * sizeof(uintmax_t)];  	char *path_user_name;  	struct passwd *pwd; -	size_t i;  	ARGBEGIN {  	case 'e': @@ -378,9 +379,6 @@ main(int argc, char *argv[])  	if (!argc)  		usage(); -	if (mlockall(MCL_CURRENT | MCL_FUTURE)) -		fprintf(stderr, "%s: mlockall MCL_CURRENT|MCL_FUTURE: %s\n", argv0, strerror(errno)); -  	sprintf(path_user_id, "%s/%ju", KEYPATH, (uintmax_t)getuid());  	errno = 0;  	pwd = getpwuid(getuid()); @@ -421,10 +419,6 @@ main(int argc, char *argv[])  		}  		key_len += (size_t)r;  	} -	for (i = 0; i < key_len; i++) -		if (!key[i]) -			key[i] = (char)255; -	key[key_len] = '\0';  	key_found = 0;  	if (!authenticate(path_user_id, key_name, key, key_len, &key_found) && | 
