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;
-}