commit 989bc1c744d8fe03a58692410a6d68ad00a872c8
Author: pancake@dazo <unknown>
Date:   Mon, 14 Dec 2009 01:02:07 +0100
* Initial import of 'sup' into mercurial
Diffstat:
| Makefile | | | 31 | +++++++++++++++++++++++++++++++ | 
| TODO | | | 1 | + | 
| config.def.h | | | 18 | ++++++++++++++++++ | 
| sup.1 | | | 23 | +++++++++++++++++++++++ | 
| sup.c | | | 72 | ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ | 
5 files changed, 145 insertions(+), 0 deletions(-)
diff --git a/Makefile b/Makefile
@@ -0,0 +1,31 @@
+CC?=gcc
+DESTDIR?=
+PREFIX?=/usr
+VERSION=0.1
+USER=root
+GROUP=root
+
+all: config.h sup
+
+config.h:
+	cp config.def.h config.h
+
+sup.o: config.h sup.c
+	${CC} -c sup.c
+
+sup: sup.o
+	${CC} sup.o -o sup
+
+clean:
+	rm -f sup.o sup
+
+mrproper: clean
+	rm -f config.h
+
+install:
+	mkdir -p ${DESTDIR}${PREFIX}/bin
+	cp sup ${DESTDIR}${PREFIX}/bin
+	chown ${USER}:${GROUP} ${DESTDIR}/${PREFIX}/bin/sup
+	chmod 4111 ${DESTDIR}${PREFIX}/bin/sup
+	sed s,VERSION,${VERSION}, sup.1 \
+	  > ${DESTDIR}${PREFIX}/share/man/man1/sup.1
diff --git a/TODO b/TODO
@@ -0,0 +1 @@
+* Enforce with checksums (sha1?)
diff --git a/config.def.h b/config.def.h
@@ -0,0 +1,18 @@
+#define USER 1000
+#define GROUP -1
+
+#define SETUID 0
+#define SETGID 0
+
+#define CHROOT "/"
+
+#define ENFORCE 1
+
+static struct rule_t rules[] = {
+	{ USER, GROUP, "whoami", "/usr/bin/whoami" },
+	{ USER, GROUP, "ifconfig", "/sbin/ifconfig" },
+	{ USER, GROUP, "ls", "/bin/ls" },
+	{ USER, GROUP, "wifi", "/root/wifi.sh" },
+	{ USER, GROUP, "", ""}, // allow to run any program
+	{ 0 },
+};
diff --git a/sup.1 b/sup.1
@@ -0,0 +1,23 @@
+.TH SUP 1 sup\-VERSION
+.SH NAME
+sup - scale user priviledges
+.SH SYNOPSIS
+.B sup
+.RB [ \-hlv ]
+.SH DESCRIPTION
+sup is a minimal priviledge scalation utility that allow normal
+users to run other programs as different user and group.
+.P
+The configuration is done in config.h at compile time.
+.SH OPTIONS
+.TP
+.B \-h
+print help message
+.TP
+.B \-l
+list command whitelist
+.TP
+.B \-v
+prints version information
+.SH AUTHOR
+pancake <nopcode.org>
diff --git a/sup.c b/sup.c
@@ -0,0 +1,72 @@
+/* pancake <nopcode.org> -- Copyleft 2009 */
+
+#include <stdio.h>
+#include <errno.h>
+#include <string.h>
+#include <sys/stat.h>
+
+#define HELP "sup [-hlv] [cmd ..]"
+#define VERSION "sup 0.1 pancake <nopcode.org> copyleft 2009"
+
+struct rule_t {
+	int uid;
+	int gid;
+	const char *cmd;
+	const char *path;
+};
+
+#include "config.h"
+
+static int die(int ret, const char *str) {
+	fprintf (stderr, "%s\n", str);
+	return ret;
+}
+
+int main(int argc, char **argv) {
+	char *cmd;
+	int i, uid, gid, ret;
+
+	if (argc < 2 || !strcmp (argv[1], "-h"))
+		return die (1, HELP);
+
+	if (!strcmp (argv[1], "-v"))
+		return die (1, VERSION);
+
+	if (!strcmp (argv[1], "-l")) {
+		for (i = 0; rules[i].cmd != NULL; i++)
+			printf ("%d %d %10s %s\n", rules[i].uid, rules[i].gid,
+				rules[i].cmd, rules[i].path);
+		return 0;
+	}
+
+	uid = getuid ();
+	gid = getgid ();
+
+	for (i = 0; rules[i].cmd != NULL; i++) {
+		if (!rules[i].cmd[0] || !strcmp (argv[1], rules[i].cmd)) {
+#if ENFORCE	
+			struct stat st;
+			lstat (rules[i].path, &st);
+			if (st.st_mode & 0222)
+				return die (1, "Cannot run writable binaries.");
+#endif
+			if (uid != SETUID && rules[i].uid != -1 && rules[i].uid != uid)
+				return die (1, "User does not match");
+
+			if (gid != SETGID && rules[i].gid != -1 && rules[i].gid != gid)
+				return die (1, "Group id does not match");
+
+			if (setuid (SETUID) == -1 || setgid (SETGID) == -1 ||
+			    seteuid (SETUID) == -1 || setegid (SETGID) == -1)
+				return die (1, strerror (errno));
+#ifdef CHROOT
+			if (chroot (CHROOT) == -1)
+				return die (1, strerror (errno));
+#endif
+			ret = execv (rules[i].path? rules[i].path:argv[1], argv+1);
+			return die (ret, strerror (errno));
+		}
+	}
+
+	return die (1, "Sorry");
+}