aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMattias Andrée <maandree@kth.se>2023-06-23 09:11:42 +0200
committerMattias Andrée <maandree@kth.se>2023-06-23 09:11:42 +0200
commitebc0fb022c48ced5e690567b3fb4186a3dfbd937 (patch)
tree82f32fb8b13d64a9a11257526e4b3413c6ae4022
downloadkey2root-ebc0fb022c48ced5e690567b3fb4186a3dfbd937.tar.gz
key2root-ebc0fb022c48ced5e690567b3fb4186a3dfbd937.tar.bz2
key2root-ebc0fb022c48ced5e690567b3fb4186a3dfbd937.tar.xz
First commit
Signed-off-by: Mattias Andrée <maandree@kth.se>
-rw-r--r--.gitignore18
-rw-r--r--LICENSE15
-rw-r--r--Makefile43
-rw-r--r--README49
-rw-r--r--arg.h45
-rw-r--r--config.mk8
-rw-r--r--key2root-addkey.8118
-rw-r--r--key2root-addkey.c42
-rw-r--r--key2root-lskeys.8112
-rw-r--r--key2root-lskeys.c28
-rw-r--r--key2root-rmkey.8114
-rw-r--r--key2root-rmkey.c31
-rw-r--r--key2root.8163
-rw-r--r--key2root.c42
14 files changed, 828 insertions, 0 deletions
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 <maandree@kth.se>
+
+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 <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+#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 <stdio.h>
+#include <stdlib.h>
+
+#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 <stdio.h>
+#include <stdlib.h>
+
+#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 <stdio.h>
+#include <stdlib.h>
+
+#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;
+}