From ebc0fb022c48ced5e690567b3fb4186a3dfbd937 Mon Sep 17 00:00:00 2001 From: Mattias Andrée Date: Fri, 23 Jun 2023 09:11:42 +0200 Subject: First commit MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Mattias Andrée --- .gitignore | 18 ++++++ LICENSE | 15 +++++ Makefile | 43 ++++++++++++++ README | 49 ++++++++++++++++ arg.h | 45 +++++++++++++++ config.mk | 8 +++ key2root-addkey.8 | 118 +++++++++++++++++++++++++++++++++++++++ key2root-addkey.c | 42 ++++++++++++++ key2root-lskeys.8 | 112 +++++++++++++++++++++++++++++++++++++ key2root-lskeys.c | 28 ++++++++++ key2root-rmkey.8 | 114 ++++++++++++++++++++++++++++++++++++++ key2root-rmkey.c | 31 +++++++++++ key2root.8 | 163 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ key2root.c | 42 ++++++++++++++ 14 files changed, 828 insertions(+) create mode 100644 .gitignore create mode 100644 LICENSE create mode 100644 Makefile create mode 100644 README create mode 100644 arg.h create mode 100644 config.mk create mode 100644 key2root-addkey.8 create mode 100644 key2root-addkey.c create mode 100644 key2root-lskeys.8 create mode 100644 key2root-lskeys.c create mode 100644 key2root-rmkey.8 create mode 100644 key2root-rmkey.c create mode 100644 key2root.8 create mode 100644 key2root.c diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..d941ef3 --- /dev/null +++ b/.gitignore @@ -0,0 +1,18 @@ +*\#* +*~ +*.o +*.a +*.lo +*.su +*.so +*.so.* +*.dll +*.dylib +*.gch +*.gcov +*.gcno +*.gcda +/key2root +/key2root-lskeys +/key2root-addkey +/key2root-rmkey diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..0be2ccf --- /dev/null +++ b/LICENSE @@ -0,0 +1,15 @@ +ISC License + +© 2023 Mattias Andrée + +Permission to use, copy, modify, and/or distribute this software for any +purpose with or without fee is hereby granted, provided that the above +copyright notice and this permission notice appear in all copies. + +THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..ceafda7 --- /dev/null +++ b/Makefile @@ -0,0 +1,43 @@ +.POSIX: + +CONFIGFILE = config.mk +include $(CONFIGFILE) + +BIN = key2root key2root-lskeys key2root-addkey key2root-rmkey + +HDR = arg.h + +MAN8 = $(BIN:=.8) +OBJ = $(BIN:=.o) + +all: $(BIN) +$(OBJ): $(HDR) + +.c.o: + $(CC) -c -o $@ $< $(CFLAGS) $(CPPFLAGS) + +.o: + $(CC) -o $@ $< $(LDFLAGS) + +.c: + $(CC) -o $@ $< $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) + +install: $(BIN) + mkdir -p -- "$(DESTDIR)$(PREFIX)/bin" + mkdir -p -- "$(DESTDIR)$(MANPREFIX)/man8/" + cp -- $(BIN) "$(DESTDIR)$(PREFIX)/bin/" + cd -- "$(DESTDIR)$(PREFIX)/bin/" && chmod -- 4755 key2root + cp -- $(MAN8) "$(DESTDIR)$(MANPREFIX)/man8/" + +uninstall: + -cd -- "$(DESTDIR)$(PREFIX)/bin/" && rm -f -- $(BIND) + -cd -- "$(DESTDIR)$(MANPREFIX)/man8/" && rm -f -- $(MAN8) + +clean: + -rm -f -- *.o *.a *.lo *.su *.so *.so.* *.gch *.gcov *.gcno *.gcda + -rm -f -- $(BIN) + +.SUFFIXES: +.SUFFIXES: .o .c + +.PHONY: all install uninstall clean diff --git a/README b/README new file mode 100644 index 0000000..a77dc65 --- /dev/null +++ b/README @@ -0,0 +1,49 @@ +NAME + key2root - authenticate with a keyfile and run a process as the root user + +SYNOPSIS + key2root [-k key-name] [-e] command [argument] ... + +DESCRIPTION + The key2root utility takes a keyfile from the standard input and uses + it to authenticate the user, and if the keyfile is recognised, runs the + specified command with sanitised and updated environment variables and + with the keyfile as the standard input. + +OPTIONS + The key2root utility conforms to the Base Definitions volume of + POSIX.1-2017, Section 12.2, Utility Syntax Guidelines. + + The following option is supported: + + -e Keep the environment variables as is. Neither sanitise nor + update them. + + -k key-name + Check the input keyfile against a specific known key, rather + than checking against all known keys. + +OPERANDS + The following operands are supported: + + command + The command that shall be run with as the root user. This will + be both the process image and the process's zeroth command line + argument. + + argument ... + Command line arguments for the command to run. + +STDIN + The key2root utility uses the standard input as the authentication key + and forwards it to the command it runs upon successful authentication. + +RATIONALE + key2root is useful for scripts that require both root access and a + keyfile: it lets the user write a script that can decrypt a keyfile + and the successful keyfile decryption to testify that the user has + 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) diff --git a/arg.h b/arg.h new file mode 100644 index 0000000..4f7b6c0 --- /dev/null +++ b/arg.h @@ -0,0 +1,45 @@ +/* + * Copy me if you can. + * by 20h + */ + +#ifndef ARG_H__ +#define ARG_H__ + +extern char *argv0; + +/* use main(int argc, char *argv[]) */ +#define ARGBEGIN for (argv0 = *argv, argv++, argc--;\ + argv[0] && argv[0][0] && argv[0][1];\ + argc--, argv++) {\ + char argc_;\ + char **argv_;\ + int brk_;\ + if (argv[0][0] == '-') {\ + if (argv[0][1] == '-' && argv[0][2] == '\0') {\ + argv++;\ + argc--;\ + break;\ + }\ + for (brk_ = 0, argv[0]++, argv_ = argv;\ + argv[0][0] && !brk_;\ + argv[0]++) {\ + if (argv_ != argv)\ + break;\ + argc_ = argv[0][0];\ + switch (argc_) + +#define ARGEND }\ + } else {\ + break;\ + }\ + } + +#define EARGF(x) ((argv[0][1] == '\0' && argv[1] == NULL)?\ + ((x), abort(), (char *)0) :\ + (brk_ = 1, (argv[0][1] != '\0')?\ + (&argv[0][1]) :\ + (argc--, argv++, argv[0]))) + + +#endif diff --git a/config.mk b/config.mk new file mode 100644 index 0000000..97a6f0f --- /dev/null +++ b/config.mk @@ -0,0 +1,8 @@ +PREFIX = /usr +MANPREFIX = $(PREFIX)/share/man + +CC = cc + +CPPFLAGS = -D_DEFAULT_SOURCE -D_BSD_SOURCE -D_XOPEN_SOURCE=700 -D_GNU_SOURCE +CFLAGS = -std=c99 -Wall -O2 +LDFLAGS = -lcrypt diff --git a/key2root-addkey.8 b/key2root-addkey.8 new file mode 100644 index 0000000..8f6eb7d --- /dev/null +++ b/key2root-addkey.8 @@ -0,0 +1,118 @@ +.TH KEY2ROOT 8 key2root-addkey + +.SH NAME +key2root-addkey - add a keyfile for privilege escalation with key2root + +.SH SYNOPSIS +.B key2root-addkey +[-r] +.I user +.I key-name +.RI [ crypt-parameters ] + +.SH DESCRIPTION +The +.B key2root-addkey +utility takes a keyfile from the standard input and it to +a database of keyfiles that may be used to authenticate the +specified +.I user +for privilege escalation with the +.BR key2root (8) +utility. + +.SH OPTIONS +The +.B key2root-addkey +utility conforms to the Base Definitions volume of POSIX.1-2017, +.IR "Section 12.2" , +.IR "Utility Syntax Guidelines" . +.PP +The following option is supported: +.TP +.B -r +Allow the keyfile to replace an existing keyfile with the same name. + +.SH OPERANDS +The following operands are supported: +.TP +.I user +The user the keyfile shall be added for. This can either +be a user ID or a user name. +.TP +.I key-name +The name the keyfile shall be given. +.TP +.I crypt-parameters +crypt(3) parameters that the keyfile shall be hashed with. + +.SH STDIN +The +.B key2root-addkey +utility reads the keyfile to add from standard input, +which must not be a TTY. + +.SH INPUT FILES +None. + +.SH ENVIRONMENT VARIABLES +No following environment variable affects the execution of +.BR key2root-addkey . + +.SH ASYNCHRONOUS EVENTS +Default. + +.SH STDOUT +The +.B key2root-addkey +utility does not use the standard output. + +.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-addkey +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-lskeys (8), +.BR key2root-rmkey (8) + +.SH AUTHORS +Mattias Andrée +.RI < maandree@kth.se > diff --git a/key2root-addkey.c b/key2root-addkey.c new file mode 100644 index 0000000..9dab78b --- /dev/null +++ b/key2root-addkey.c @@ -0,0 +1,42 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include +#include + +#include "arg.h" + + +char *argv0; + + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [-r] user key-name [crypt-parameters]\n", argv0); + exit(1); +} + + +int +main(int argc, char *argv[]) +{ + int allow_replace = 0; + + ARGBEGIN { + case 'r': + allow_replace = 1; + break; + default: + usage(); + } ARGEND; + + if (argc < 2 || argc > 3) + usage(); + + if (isatty(STDIN_FILENO)) { + fprintf(stderr, "%s: standard input must not be a TTY.\n", argv0); + exit(1); + } + + return 0; +} diff --git a/key2root-lskeys.8 b/key2root-lskeys.8 new file mode 100644 index 0000000..cfd0bd8 --- /dev/null +++ b/key2root-lskeys.8 @@ -0,0 +1,112 @@ +.TH KEY2ROOT 8 key2root-lskeys + +.SH NAME +key2root-lskeys - list keyfiles for privilege escalation with key2root + +.SH SYNOPSIS +.B key2root-lskeys +.RI [ user ]\ ... + +.SH DESCRIPTION +The +.B key2root-lskey +utility lists keyfiles that may be used to authenticate +for privilege escalation with the +.BR key2root (8) +utility. + +.SH OPTIONS +The +.B key2root-lskey +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 user +User whose keyfiles shall be listed. This can either +be a user ID or a user name. See +.BR NOTES . + +If no +.I user +is specified, all keyfiles in the database are list, for all users. + +.SH STDIN +The +.B key2root-lskeys +utility does not use the standard input. + +.SH INPUT FILES +None. + +.SH ENVIRONMENT VARIABLES +No following environment variable affects the execution of +.BR key2root-lskeys . + +.SH ASYNCHRONOUS EVENTS +Default. + +.SH STDOUT +The +.B key2root-lskeys +utility does not use the standard output. + +.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-lskeys +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 +Keyfiles added by user ID and by user names are stored separatedly. +If a keyfile was added with a user name specified, it is only +associated with the user name, and the user name must be specified +for it to be listed. Likewise if a keyfile was added with a user ID +specified, it is only associated with the user ID, and the user ID +must be specified for it to be listed. + +.SH BUGS +None. + +.SH FUTURE DIRECTIONS +None. + +.SH SEE ALSO +.BR key2root (8), +.BR key2root-addkey (8), +.BR key2root-rmkey (8) + +.SH AUTHORS +Mattias Andrée +.RI < maandree@kth.se > diff --git a/key2root-lskeys.c b/key2root-lskeys.c new file mode 100644 index 0000000..ee1732c --- /dev/null +++ b/key2root-lskeys.c @@ -0,0 +1,28 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include + +#include "arg.h" + + +char *argv0; + + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [user] ...\n", argv0); + exit(1); +} + + +int +main(int argc, char *argv[]) +{ + ARGBEGIN { + default: + usage(); + } ARGEND; + + return 0; +} diff --git a/key2root-rmkey.8 b/key2root-rmkey.8 new file mode 100644 index 0000000..fe01c93 --- /dev/null +++ b/key2root-rmkey.8 @@ -0,0 +1,114 @@ +.TH KEY2ROOT 8 key2root-rmkey + +.SH NAME +key2root-rmkey - remove keyfiles for privilege escalation with key2root + +.SH SYNOPSIS +.B key2root-rmkey +.I user +.IR key-name \ ... + +.SH DESCRIPTION +The +.B key2root-rmkey +utility removes a keyfile from the database of keyfiles that may +be used to authenticate the specified +.I user +for privilege escalation with the +.BR key2root (8) +utility. + +.SH OPTIONS +The +.B key2root-rmkey +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 user +The user the keyfile shall be removed for. This can either +be a user ID or a user name. See +.BR NOTES . +.TP +.I key-name +The name the keyfile to remove. + +.SH STDIN +The +.B key2root-rmkey +utility does not use the standard input. + +.SH INPUT FILES +None. + +.SH ENVIRONMENT VARIABLES +No following environment variable affects the execution of +.BR key2root-rmkey . + +.SH ASYNCHRONOUS EVENTS +Default. + +.SH STDOUT +The +.B key2root-rmkey +utility does not use the standard output. + +.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-rmkey +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 +Keyfiles added by user ID and by user names are stored separatedly. +If a keyfile was added with a user name specified, it is only +associated with the user name, and the user name must be specified +when removing it. Likewise if a keyfile was added with a user ID +specified, it is only associated with the user ID, and the user ID +must be specified when removing it. + +.SH BUGS +None. + +.SH FUTURE DIRECTIONS +None. + +.SH SEE ALSO +.BR key2root (8), +.BR key2root-addkey (8), +.BR key2root-lskeys (8) + +.SH AUTHORS +Mattias Andrée +.RI < maandree@kth.se > diff --git a/key2root-rmkey.c b/key2root-rmkey.c new file mode 100644 index 0000000..1050977 --- /dev/null +++ b/key2root-rmkey.c @@ -0,0 +1,31 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include + +#include "arg.h" + + +char *argv0; + + +static void +usage(void) +{ + fprintf(stderr, "usage: %s user key-name ...\n", argv0); + exit(1); +} + + +int +main(int argc, char *argv[]) +{ + ARGBEGIN { + default: + usage(); + } ARGEND; + + if (argc < 2) + usage(); + + return 0; +} diff --git a/key2root.8 b/key2root.8 new file mode 100644 index 0000000..9cb2652 --- /dev/null +++ b/key2root.8 @@ -0,0 +1,163 @@ +.TH KEY2ROOT 8 key2root + +.SH NAME +key2root - authenticate with a keyfile and run a process as the root user + +.SH SYNOPSIS +.B key2root +[-k +.IR key-name ] +[-e] +.I command +.RI [ argument ]\ ... + +.SH DESCRIPTION +The +.B key2root +utility takes a keyfile from the standard input and uses it +to authenticate the user, and if the keyfile is recognised, +runs the specified +.I command +with sanitised and updated environment variables and with +the keyfile as the standard input. + +.SH OPTIONS +The +.B key2root +utility conforms to the Base Definitions volume of POSIX.1-2017, +.IR "Section 12.2" , +.IR "Utility Syntax Guidelines" . +.PP +The following option is supported: +.TP +.B -e +Keep the environment variables as is. Neither +sanitise nor update them. +.TP +.BR -k \ \fIkey-name\fP +Check the input keyfile against a specific known key, rather +than checking against all known keys. + +.SH OPERANDS +The following operands are supported: +.TP +.I command +The command that shall be run with as the root user. +This will be both the process image and the process's +zeroth command line argument. +.TP +.IR argument \ ... +Command line arguments for the command to run. + +.SH STDIN +The +.B key2root +utility uses the standard input as the authentication +key and forwards it to the +.I command +it runs upon successful authentication. + +.SH INPUT FILES +None. + +.SH ENVIRONMENT VARIABLES +The following environment variables affects the execution of +.BR key2root : +.TP +.SH PATH +Default. See to the Base Definitions volume of +POSIX.1-2017, Section 8.3, Other Environment Variables. + +.SH ASYNCHRONOUS EVENTS +Default. + +.SH STDOUT +The +.B key2root +utility does not use the standard output, however the +.I command +it starts may. + +.SH STDERR +The standard error is used for diagnostic messages. The +.I command +the +.B key2root +utility starts may also use the standard error. + +.SH OUTPUT FILES +None. + +.SH EXTENDED DESCRIPTION +None. + +.SH EXIT STATUS +If the +.B key2root +utility fails it will exit with one of the following statuses: +.TP +124 +Authentication failed. +.TP +125 +A error occurred. +.TP +126 +The process failed to change process image. +.TP +127 +The specified command was not found. +.PP +If the +.B key2root +utility is successful, the exit status is defined by the +.I command +it starts. + +.SH CONSEQUENCES OF ERRORS +Default. + +.SH APPLICATION USAGE +None. + +.SH EXAMPLES +None. + +.SH RATIONALE +.B key2root +is useful for scripts that require both root access and a +keyfile: it lets the user write a script that can decrypt +a keyfile and the successful keyfile decryption to testify +that the user has authenticated himself rather also requiring +his password. + +.SH NOTES +The +.I PATH +environment variable will not be updated. +Updates environment variables are: +.IR HOME , +.IR LOGNAME , +.IR MAIL , +.IR SHEEL , +and +.IR USER . + +.SH BUGS +None. + +.SH FUTURE DIRECTIONS +None. + +.SH SEE ALSO +.BR key2root-addkey (8), +.BR key2root-lskeys (8), +.BR key2root-rmkey (8), +.BR asroot (8), +.BR sudo (8), +.BR doas (1), +.BR su (1) + +.SH AUTHORS +Mattias Andrée +.RI < maandree@kth.se > diff --git a/key2root.c b/key2root.c new file mode 100644 index 0000000..69b7dc6 --- /dev/null +++ b/key2root.c @@ -0,0 +1,42 @@ +/* See LICENSE file for copyright and license details. */ +#include +#include + +#include "arg.h" + + +char *argv0; + + +static void +usage(void) +{ + fprintf(stderr, "usage: %s [-k key-name] [-e] command [argument] ...\n", argv0); + exit(125); +} + + +int +main(int argc, char *argv[]) +{ + int keep_env = 0; + const char *key_name = NULL; + + ARGBEGIN { + case 'e': + keep_env = 1; + break; + case 'k': + if (key_name) + usage(); + key_name = EARGF(usage()); + break; + default: + usage(); + } ARGEND; + + if (!argc) + usage(); + + return 0; +} -- cgit v1.2.3-70-g09d2