commit 989bc1c744d8fe03a58692410a6d68ad00a872c8
Author: pancake@dazo <unknown>
Date: Mon, 14 Dec 2009 01:02:07 +0100
* Initial import of 'sup' into mercurial
Diffstat:
A | Makefile | | | 31 | +++++++++++++++++++++++++++++++ |
A | TODO | | | 1 | + |
A | config.def.h | | | 18 | ++++++++++++++++++ |
A | sup.1 | | | 23 | +++++++++++++++++++++++ |
A | 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");
+}