wm: infra

Download patch

ref: 33ca14ef2f80efa8957aa9d11d09ba30822926ad
parent: e3d3899438ba1b2c899d46d6476e53c823b6b575
author: mkf <mkf@x230>
date: Wed Sep 6 23:26:18 EDT 2023

chusr: replace newuser, import functionality from authcmdlib.h

--- /dev/null
+++ b/chusr.c
@@ -1,0 +1,300 @@
+#include <u.h>
+#include <libc.h>
+#include <bio.h>
+#include <libsec.h>
+#include <authsrv.h>
+
+#define	KEYDB		"/mnt/keys"
+#define NETKEYDB	"/mnt/netkeys"
+#define KEYDBBUF	(sizeof NETKEYDB)	/* enough for any keydb prefix */
+#define AUTHLOG		"auth"
+
+enum{
+	MAXNETCHAL	= 100000,		/* max securenet challenge */
+	Maxpath		= 256,
+};
+
+enum
+{
+	Nemail		= 10,
+	Plan9		= 1,
+	Securenet	= 2,
+};
+
+typedef struct
+{
+	char	*user;
+	char	*postid;
+	char	*name;
+	char	*dept;
+	char	*email[Nemail];
+} Acctbio;
+
+typedef struct {
+	char	*keys;
+	char	*msg;
+	char	*who;
+	Biobuf 	*b;
+} Fs;
+
+Fs fs =	{ "/mnt/keys", "plan 9 key", "/adm/keys.who", 0 };
+
+static uchar zeros[16];
+
+
+void    install(char*, char*, Authkey*, long);
+int exists(char*, char*);
+void	private(void);
+int	setkey(char*, char*, Authkey*);
+char*	setdeskey(char*, char*, char*);
+uchar*	setaeskey(char*, char*, uchar*);
+char*	setsecret(char*, char*, char*);
+void	wrbio(char*, Acctbio*);
+int	writefile(char*, char*, int);
+int	deskeyfmt(Fmt*);
+
+void
+usage(void)
+{
+	fprint(2, "usage: %s [-d dept] [-e email] [-i postid] [-s sponsor\'s email] -p pass user\n", argv0);
+	exits("usage");
+}
+
+void
+main(int argc, char *argv[])
+{
+	char *u, *pass;
+	long t;
+	Authkey key;
+	Acctbio a;
+	Fs *f;
+
+	fmtinstall('K', deskeyfmt);
+
+	ARGBEGIN{
+    case 'd':
+        a.dept = EARGF(usage());
+        break;
+    case 'i':
+        a.postid = EARGF(usage());
+        break;
+    case 'e':
+        a.email[0] = EARGF(usage());
+        break;
+	case 'p':
+		pass = EARGF(usage());
+		break;
+    /* sponsor's email */
+    case 's':
+        // a->email[1] = EARGF(usage());
+        break;
+
+	default:
+		usage();
+	}ARGEND
+
+	if(argc < 3)
+		usage();
+	u = *argv;
+	if(memchr(u, '\0', ANAMELEN) == 0)
+		sysfatal("bad user name");
+
+	private();
+	t = 0;
+	a.user = 0;
+	memset(&key, 0, sizeof(key));
+	f = &fs;
+
+	passtokey(&key, pass);
+
+	install(f->keys, u, &key, t);
+
+	if(setsecret(KEYDB, u, pass) == 0)
+		sysfatal("error writing Inferno/POP secret");
+
+	wrbio(f->who, &a);
+
+	print("user %s installed for Plan 9\n", u);
+	syslog(0, AUTHLOG, "user %s installed for plan 9", u);
+
+	exits(0);
+}
+
+void
+install(char *db, char *u, Authkey *key, long t)
+{
+	char buf[KEYDBBUF+ANAMELEN+20];
+	int fd;
+
+	if(!exists(db, u)){
+		snprint(buf, sizeof(buf), "%s/%s", db, u);
+		fd = create(buf, OREAD, 0777|DMDIR);
+		if(fd < 0)
+			sysfatal("can't create user %s: %r", u);
+		close(fd);
+	}
+
+	if(!setkey(db, u, key))
+		sysfatal("can't set key: %r");
+
+	if(t == -1)
+		return;
+	snprint(buf, sizeof(buf), "%s/%s/expire", db, u);
+	fd = open(buf, OWRITE);
+	if(fd < 0 || fprint(fd, "%ld", t) < 0)
+		sysfatal("can't write expiration time");
+	close(fd);
+}
+
+int
+exists(char *db, char *u)
+{
+	char buf[KEYDBBUF+ANAMELEN+6];
+
+	snprint(buf, sizeof(buf), "%s/%s/expire", db, u);
+	if(access(buf, 0) < 0)
+		return 0;
+	return 1;
+}
+
+
+/* these functions are from /sys/src/cmd/auth/lib/ */
+
+int
+deskeyfmt(Fmt *f)
+{
+	uchar key[8];
+	char buf[32];
+	uchar *k;
+	int i;
+
+	k = va_arg(f->args, uchar*);
+	key[0] = 0;
+	for(i = 0; i < 7; i++){
+		key[i] |= k[i] >> i;
+		key[i] &= ~1;
+		key[i+1] = k[i] << (7 - i);
+	}
+	key[7] &= ~1;
+	sprint(buf, "%.3uo %.3uo %.3uo %.3uo %.3uo %.3uo %.3uo %.3uo",
+		key[0], key[1], key[2], key[3], key[4], key[5], key[6], key[7]);
+	fmtstrcpy(f, buf);
+	return 0;
+}
+
+/* don't allow other processes to debug us and steal keys */
+void
+private(void)
+{
+	int fd;
+	char buf[32];
+	static char pmsg[] = "Warning! %s can't protect itself from debugging: %r\n";
+	static char smsg[] = "Warning! %s can't turn off swapping: %r\n";
+
+	snprint(buf, sizeof(buf), "/proc/%d/ctl", getpid());
+	fd = open(buf, OWRITE|OCEXEC);
+	if(fd < 0){
+		fprint(2, pmsg, argv0);
+		return;
+	}
+	if(fprint(fd, "private") < 0)
+		fprint(2, pmsg, argv0);
+	if(fprint(fd, "noswap") < 0)
+		fprint(2, smsg, argv0);
+	close(fd);
+}
+
+int
+setkey(char *db, char *user, Authkey *key)
+{
+	int ret;
+
+	ret = setdeskey(db, user, key->des) != nil;
+	if(tsmemcmp(key->aes, zeros, AESKEYLEN) != 0)
+		ret |= setaeskey(db, user, key->aes) != nil;
+	return ret;
+}
+
+char*
+setdeskey(char *db, char *user, char *key)
+{
+	char filename[Maxpath];
+
+	snprint(filename, sizeof filename, "%s/%s/key", db, user);
+	if(writefile(filename, key, DESKEYLEN) != DESKEYLEN)
+		return nil;
+	return key;
+}
+
+uchar*
+setaeskey(char *db, char *user, uchar *key)
+{
+	char filename[Maxpath];
+
+	snprint(filename, sizeof filename, "%s/%s/aeskey", db, user);
+	if(writefile(filename, (char*)key, AESKEYLEN) != AESKEYLEN)
+		return nil;
+	return key;
+}
+
+char*
+setsecret(char *db, char *user, char *secret)
+{
+	char filename[Maxpath];
+
+	snprint(filename, sizeof filename, "%s/%s/secret", db, user);
+	if(writefile(filename, secret, strlen(secret)) != strlen(secret))
+		return nil;
+	return secret;
+}
+
+void
+wrbio(char *file, Acctbio *a)
+{
+	char buf[1024];
+	int i, fd, n;
+
+	fd = open(file, OWRITE);
+	if(fd < 0){
+		fd = create(file, OWRITE, 0660);
+		if(fd < 0)
+			sysfatal("can't create %s", file);
+	}
+	if(seek(fd, 0, 2) < 0)
+		sysfatal("can't seek %s", file);
+
+	if(a->postid == 0)
+		a->postid = "";
+	if(a->name == 0)
+		a->name = "";
+	if(a->dept == 0)
+		a->dept = "";
+	if(a->email[0] == 0)
+		a->email[0] = strdup(a->user);
+
+	n = 0;
+	n += snprint(buf+n, sizeof(buf)-n, "%s|%s|%s|%s",
+		a->user, a->postid, a->name, a->dept);
+	for(i = 0; i < Nemail; i++){
+		if(a->email[i] == 0)
+			break;
+		n += snprint(buf+n, sizeof(buf)-n, "|%s", a->email[i]);
+	}
+	n += snprint(buf+n, sizeof(buf)-n, "\n");
+
+	write(fd, buf, n);
+	close(fd);
+}
+
+int
+writefile(char *file, char *buf, int n)
+{
+	int fd;
+
+	fd = open(file, OWRITE);
+	if(fd < 0)
+		return -1;
+	n = write(fd, buf, n);
+	close(fd);
+	return n;
+}
--- a/newuser.c
+++ /dev/null
@@ -1,102 +1,0 @@
-#include <u.h>
-#include <libc.h>
-#include <bio.h>
-#include <libsec.h>
-#include <authsrv.h>
-#include "authcmdlib.h"
-
-void	install(char*, char*, Authkey*, long, int);
-int	exists(char*, char*);
-
-void
-usage(void)
-{
-	fprint(2, "usage: newuser [-p] user\n");
-	exits("usage");
-}
-
-void
-main(int argc, char *argv[])
-{
-	char *u, pass[32];
-	int newbio, dosecret;
-	long t;
-	Authkey key;
-	Acctbio a;
-	Fs *f;
-
-	fmtinstall('K', deskeyfmt);
-
-	ARGBEGIN{
-	case 'p':
-		pass = EARGF(usage());
-		break;
-	default:
-		usage();
-	}ARGEND
-	argv0 = "newuser";
-
-	if(argc != 1)
-		usage();
-	u = *argv;
-	if(memchr(u, '\0', ANAMELEN) == 0)
-		error("bad user name");
-
-	private();
-	newbio = 0;
-	t = 0;
-	a.user = 0;
-	memset(&key, 0, sizeof(key));
-	f = &fs[Plan9];
-	getpass(&key, pass, 1, 1);
-
-	install(f->keys, u, &key, t, newkey);
-
-	if(setsecret(KEYDB, u, pass) == 0)
-		error("error writing Inferno/POP secret");
-
-	if(querybio(f->who, u, &a))
-		wrbio(f->who, &a);
-
-	print("user %s installed for Plan 9\n", u);
-	syslog(0, AUTHLOG, "user %s installed for plan 9", u);
-
-	exits(0);
-}
-
-void
-install(char *db, char *u, Authkey *key, long t, int newkey)
-{
-	char buf[KEYDBBUF+ANAMELEN+20];
-	int fd;
-
-	if(!exists(db, u)){
-		snprint(buf, sizeof(buf), "%s/%s", db, u);
-		fd = create(buf, OREAD, 0777|DMDIR);
-		if(fd < 0)
-			error("can't create user %s: %r", u);
-		close(fd);
-	}
-
-	if(newkey && !setkey(db, u, key))
-		error("can't set key: %r");
-
-	if(t == -1)
-		return;
-	snprint(buf, sizeof(buf), "%s/%s/expire", db, u);
-	fd = open(buf, OWRITE);
-	if(fd < 0 || fprint(fd, "%ld", t) < 0)
-		error("can't write expiration time");
-	close(fd);
-}
-
-int
-exists(char *db, char *u)
-{
-	char buf[KEYDBBUF+ANAMELEN+6];
-
-	snprint(buf, sizeof(buf), "%s/%s/expire", db, u);
-	if(access(buf, 0) < 0)
-		return 0;
-	return 1;
-}