diff options
author | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
---|---|---|
committer | Taru Karttunen <taruti@taruti.net> | 2011-03-30 15:46:40 +0300 |
commit | e5888a1ffdae813d7575f5fb02275c6bb07e5199 (patch) | |
tree | d8d51eac403f07814b9e936eed0c9a79195e2450 /sys/src/cmd/auth/lib |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/cmd/auth/lib')
-rwxr-xr-x | sys/src/cmd/auth/lib/error.c | 20 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/fs.c | 10 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/getauthkey.c | 27 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/getexpiration.c | 77 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/keyfmt.c | 29 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/log.c | 45 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/mkfile | 30 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/netcheck.c | 111 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/okpasswd.c | 42 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/querybio.c | 66 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/rdbio.c | 58 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/readarg.c | 23 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/readln.c | 115 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/readn.c | 20 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/readwrite.c | 90 | ||||
-rwxr-xr-x | sys/src/cmd/auth/lib/wrbio.c | 40 |
16 files changed, 803 insertions, 0 deletions
diff --git a/sys/src/cmd/auth/lib/error.c b/sys/src/cmd/auth/lib/error.c new file mode 100755 index 000000000..71bf63df1 --- /dev/null +++ b/sys/src/cmd/auth/lib/error.c @@ -0,0 +1,20 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include "authcmdlib.h" + +void +error(char *fmt, ...) +{ + char buf[8192], *s; + va_list arg; + + s = buf; + s += sprint(s, "%s: ", argv0); + va_start(arg, fmt); + s = vseprint(s, buf + sizeof(buf), fmt, arg); + va_end(arg); + *s++ = '\n'; + write(2, buf, s - buf); + exits(buf); +} diff --git a/sys/src/cmd/auth/lib/fs.c b/sys/src/cmd/auth/lib/fs.c new file mode 100755 index 000000000..43f7db845 --- /dev/null +++ b/sys/src/cmd/auth/lib/fs.c @@ -0,0 +1,10 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include "authcmdlib.h" + +Fs fs[3] = +{ +[Plan9] { "/mnt/keys", "plan 9 key", "/adm/keys.who", 0 }, +[Securenet] { "/mnt/netkeys", "network access key", "/adm/netkeys.who", 0 }, +}; diff --git a/sys/src/cmd/auth/lib/getauthkey.c b/sys/src/cmd/auth/lib/getauthkey.c new file mode 100755 index 000000000..1ae8d4e87 --- /dev/null +++ b/sys/src/cmd/auth/lib/getauthkey.c @@ -0,0 +1,27 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> +#include <bio.h> +#include "authcmdlib.h" + +static int +getkey(char *authkey) +{ + Nvrsafe safe; + + if(readnvram(&safe, 0) < 0) + return -1; + memmove(authkey, safe.machkey, DESKEYLEN); + memset(&safe, 0, sizeof safe); + return 0; +} + +int +getauthkey(char *authkey) +{ + if(getkey(authkey) == 0) + return 1; + print("can't read NVRAM, please enter machine key\n"); + getpass(authkey, nil, 0, 1); + return 1; +} diff --git a/sys/src/cmd/auth/lib/getexpiration.c b/sys/src/cmd/auth/lib/getexpiration.c new file mode 100755 index 000000000..fb07d261e --- /dev/null +++ b/sys/src/cmd/auth/lib/getexpiration.c @@ -0,0 +1,77 @@ +#include <u.h> +#include <libc.h> +#include <ctype.h> +#include <bio.h> +#include "authcmdlib.h" + +/* + * get the date in the format yyyymmdd + */ +Tm +getdate(char *d) +{ + Tm date; + int i; + + date.year = date.mon = date.mday = 0; + date.hour = date.min = date.sec = 0; + for(i = 0; i < 8; i++) + if(!isdigit(d[i])) + return date; + date.year = (d[0]-'0')*1000 + (d[1]-'0')*100 + (d[2]-'0')*10 + d[3]-'0'; + date.year -= 1900; + d += 4; + date.mon = (d[0]-'0')*10 + d[1]-'0' - 1; + d += 2; + date.mday = (d[0]-'0')*10 + d[1]-'0'; + date.yday = 0; + return date; +} + +long +getexpiration(char *db, char *u) +{ + char buf[Maxpath]; + char prompt[128]; + char cdate[32]; + Tm date; + ulong secs, now; + int n, fd; + + /* read current expiration (if any) */ + snprint(buf, sizeof buf, "%s/%s/expire", db, u); + fd = open(buf, OREAD); + buf[0] = 0; + if(fd >= 0){ + n = read(fd, buf, sizeof(buf)-1); + if(n > 0) + buf[n-1] = 0; + close(fd); + } + + if(buf[0]){ + if(strncmp(buf, "never", 5)){ + secs = atoi(buf); + memmove(&date, localtime(secs), sizeof(date)); + sprint(buf, "%4.4d%2.2d%2.2d", date.year+1900, date.mon+1, date.mday); + } else + buf[5] = 0; + } else + strcpy(buf, "never"); + sprint(prompt, "Expiration date (YYYYMMDD or never)[return = %s]: ", buf); + + now = time(0); + for(;;){ + readln(prompt, cdate, sizeof cdate, 0); + if(*cdate == 0) + return -1; + if(strcmp(cdate, "never") == 0) + return 0; + date = getdate(cdate); + secs = tm2sec(&date); + if(secs > now && secs < now + 2*365*24*60*60) + break; + print("expiration time must fall between now and 2 years from now\n"); + } + return secs; +} diff --git a/sys/src/cmd/auth/lib/keyfmt.c b/sys/src/cmd/auth/lib/keyfmt.c new file mode 100755 index 000000000..86c2378a3 --- /dev/null +++ b/sys/src/cmd/auth/lib/keyfmt.c @@ -0,0 +1,29 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include "authcmdlib.h" + +/* + * print a key in des standard form + */ +int +keyfmt(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; +} diff --git a/sys/src/cmd/auth/lib/log.c b/sys/src/cmd/auth/lib/log.c new file mode 100755 index 000000000..bd4eaf1a3 --- /dev/null +++ b/sys/src/cmd/auth/lib/log.c @@ -0,0 +1,45 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> +#include <bio.h> +#include "authcmdlib.h" + +static void +record(char *db, char *user, char *msg) +{ + char buf[Maxpath]; + int fd; + + snprint(buf, sizeof buf, "%s/%s/log", db, user); + fd = open(buf, OWRITE); + if(fd < 0) + return; + write(fd, msg, strlen(msg)); + close(fd); + return; +} + +void +logfail(char *user) +{ + if(!user) + return; + record(KEYDB, user, "bad"); + record(NETKEYDB, user, "bad"); +} + +void +succeed(char *user) +{ + if(!user) + return; + record(KEYDB, user, "good"); + record(NETKEYDB, user, "good"); +} + +void +fail(char *user) +{ + logfail(user); + exits("failure"); +} diff --git a/sys/src/cmd/auth/lib/mkfile b/sys/src/cmd/auth/lib/mkfile new file mode 100755 index 000000000..9e54d35fc --- /dev/null +++ b/sys/src/cmd/auth/lib/mkfile @@ -0,0 +1,30 @@ +</$objtype/mkfile + + +LIB=../lib.$O.a +OFILES=\ + keyfmt.$O\ + netcheck.$O\ + okpasswd.$O\ + readwrite.$O\ + readarg.$O\ + readln.$O\ + getauthkey.$O\ + log.$O\ + error.$O\ + fs.$O\ + rdbio.$O\ + querybio.$O\ + wrbio.$O\ + getexpiration.$O\ + + +HFILES=/sys/include/auth.h /sys/include/authsrv.h ../authcmdlib.h + +UPDATE=\ + mkfile\ + $HFILES\ + ${OFILES:%.$O=%.c}\ + +</sys/src/cmd/mksyslib +CFLAGS=$CFLAGS -I.. diff --git a/sys/src/cmd/auth/lib/netcheck.c b/sys/src/cmd/auth/lib/netcheck.c new file mode 100755 index 000000000..5e4220c25 --- /dev/null +++ b/sys/src/cmd/auth/lib/netcheck.c @@ -0,0 +1,111 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include "authcmdlib.h" + +/* + * compute the key verification checksum + */ +void +checksum(char key[], char csum[]) { + uchar buf[8]; + + memset(buf, 0, 8); + encrypt(key, buf, 8); + sprint(csum, "C %.2ux%.2ux%.2ux%.2ux", buf[0], buf[1], buf[2], buf[3]); +} + +/* + * compute the proper response. We encrypt the ascii of + * challenge number, with trailing binary zero fill. + * This process was derived empirically. + * this was copied from inet's guard. + */ +char * +netresp(char *key, long chal, char *answer) +{ + uchar buf[8]; + + memset(buf, 0, 8); + sprint((char *)buf, "%lud", chal); + if(encrypt(key, buf, 8) < 0) + error("can't encrypt response"); + chal = (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3]; + sprint(answer, "%.8lux", chal); + + return answer; +} + +char * +netdecimal(char *answer) +{ + int i; + + for(i = 0; answer[i]; i++) + switch(answer[i]){ + case 'a': case 'b': case 'c': + answer[i] = '2'; + break; + case 'd': case 'e': case 'f': + answer[i] = '3'; + break; + } + return answer; +} + +int +netcheck(void *key, long chal, char *response) +{ + char answer[32], *p; + int i; + + if(smartcheck(key, chal, response)) + return 1; + + if(p = strchr(response, '\n')) + *p = '\0'; + netresp(key, chal, answer); + + /* + * check for hex response -- securenet mode 1 or 5 + */ + for(i = 0; response[i]; i++) + if(response[i] >= 'A' && response[i] <= 'Z') + response[i] -= 'A' - 'a'; + if(strcmp(answer, response) == 0) + return 1; + + /* + * check for decimal response -- securenet mode 0 or 4 + */ + return strcmp(netdecimal(answer), response) == 0; +} + +int +smartcheck(void *key, long chal, char *response) +{ + uchar buf[2*8]; + int i, c, cslo, cshi; + + sprint((char*)buf, "%lud ", chal); + cslo = 0x52; + cshi = cslo; + for(i = 0; i < 8; i++){ + c = buf[i]; + if(c >= '0' && c <= '9') + c -= '0'; + cslo += c; + if(cslo > 0xff) + cslo -= 0xff; + cshi += cslo; + if(cshi > 0xff) + cshi -= 0xff; + buf[i] = c | (cshi & 0xf0); + } + + encrypt(key, buf, 8); + for(i = 0; i < 8; i++) + if(response[i] != buf[i] % 10 + '0') + return 0; + return 1; +} diff --git a/sys/src/cmd/auth/lib/okpasswd.c b/sys/src/cmd/auth/lib/okpasswd.c new file mode 100755 index 000000000..b904db5aa --- /dev/null +++ b/sys/src/cmd/auth/lib/okpasswd.c @@ -0,0 +1,42 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> +#include <bio.h> +#include "authcmdlib.h" + +char *trivial[] = { + "login", + "guest", + "change me", + "passwd", + "no passwd", + "anonymous", + 0 +}; + +char* +okpasswd(char *p) +{ + char passwd[ANAMELEN]; + char back[ANAMELEN]; + int i, n; + + strncpy(passwd, p, sizeof passwd - 1); + passwd[sizeof passwd - 1] = '\0'; + n = strlen(passwd); + while(passwd[n - 1] == ' ') + n--; + passwd[n] = '\0'; + for(i = 0; i < n; i++) + back[i] = passwd[n - 1 - i]; + back[n] = '\0'; + if(n < 8) + return "password must be at least 8 chars"; + + for(i = 0; trivial[i]; i++) + if(strcmp(passwd, trivial[i]) == 0 + || strcmp(back, trivial[i]) == 0) + return "trivial password"; + + return 0; +} diff --git a/sys/src/cmd/auth/lib/querybio.c b/sys/src/cmd/auth/lib/querybio.c new file mode 100755 index 000000000..97218a6dc --- /dev/null +++ b/sys/src/cmd/auth/lib/querybio.c @@ -0,0 +1,66 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <ctype.h> +#include "authcmdlib.h" + + +#define TABLEN 8 + +static char* +defreadln(char *prompt, char *def, int must, int *changed) +{ + char pr[512]; + char reply[256]; + + do { + if(def && *def){ + if(must) + snprint(pr, sizeof pr, "%s[return = %s]: ", prompt, def); + else + snprint(pr, sizeof pr, "%s[return = %s, space = none]: ", prompt, def); + } else + snprint(pr, sizeof pr, "%s: ", prompt); + readln(pr, reply, sizeof(reply), 0); + switch(*reply){ + case ' ': + break; + case 0: + return def; + default: + *changed = 1; + if(def) + free(def); + return strdup(reply); + } + } while(must); + + if(def){ + *changed = 1; + free(def); + } + return 0; +} + +/* + * get bio from stdin + */ +int +querybio(char *file, char *user, Acctbio *a) +{ + int i; + int changed; + + rdbio(file, user, a); + a->postid = defreadln("Post id", a->postid, 0, &changed); + a->name = defreadln("User's full name", a->name, 1, &changed); + a->dept = defreadln("Department #", a->dept, 1, &changed); + a->email[0] = defreadln("User's email address", a->email[0], 1, &changed); + a->email[1] = defreadln("Sponsor's email address", a->email[1], 0, &changed); + for(i = 2; i < Nemail; i++){ + if(a->email[i-1] == 0) + break; + a->email[i] = defreadln("other email address", a->email[i], 0, &changed); + } + return changed; +} diff --git a/sys/src/cmd/auth/lib/rdbio.c b/sys/src/cmd/auth/lib/rdbio.c new file mode 100755 index 000000000..7363e4284 --- /dev/null +++ b/sys/src/cmd/auth/lib/rdbio.c @@ -0,0 +1,58 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <ctype.h> +#include "authcmdlib.h" + +void +clrbio(Acctbio *a) +{ + int i; + + if(a->user) + free(a->user); + if(a->postid) + free(a->postid); + if(a->name) + free(a->name); + if(a->dept) + free(a->dept); + for(i = 0; i < Nemail; i++) + if(a->email[i]) + free(a->email[i]); + memset(a, 0, sizeof(Acctbio)); +} + +void +rdbio(char *file, char *user, Acctbio *a) +{ + int i,n; + Biobuf *b; + char *p; + char *field[20]; + + memset(a, 0, sizeof(Acctbio)); + b = Bopen(file, OREAD); + if(b == 0) + return; + while(p = Brdline(b, '\n')){ + p[Blinelen(b)-1] = 0; + n = getfields(p, field, nelem(field), 0, "|"); + if(n < 4) + continue; + if(strcmp(field[0], user) != 0) + continue; + + clrbio(a); + + a->postid = strdup(field[1]); + a->name = strdup(field[2]); + a->dept = strdup(field[3]); + if(n-4 >= Nemail) + n = Nemail-4; + for(i = 4; i < n; i++) + a->email[i-4] = strdup(field[i]); + } + a->user = strdup(user); + Bterm(b); +} diff --git a/sys/src/cmd/auth/lib/readarg.c b/sys/src/cmd/auth/lib/readarg.c new file mode 100755 index 000000000..cce957db9 --- /dev/null +++ b/sys/src/cmd/auth/lib/readarg.c @@ -0,0 +1,23 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include "authcmdlib.h" + +int +readarg(int fd, char *arg, int len) +{ + char buf[1]; + int i; + + i = 0; + memset(arg, 0, len); + while(read(fd, buf, 1) == 1){ + if(i < len - 1) + arg[i++] = *buf; + if(*buf == '\0'){ + arg[i] = '\0'; + return 0; + } + } + return -1; +} diff --git a/sys/src/cmd/auth/lib/readln.c b/sys/src/cmd/auth/lib/readln.c new file mode 100755 index 000000000..ee470a52c --- /dev/null +++ b/sys/src/cmd/auth/lib/readln.c @@ -0,0 +1,115 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> +#include <bio.h> +#include "authcmdlib.h" + +void +getpass(char *key, char *pass, int check, int confirm) +{ + char rpass[32], npass[32]; + char *err; + + if(pass == nil) + pass = npass; + + for(;;){ + readln("Password: ", pass, sizeof npass, 1); + if(confirm){ + readln("Confirm password: ", rpass, sizeof rpass, 1); + if(strcmp(pass, rpass) != 0){ + print("mismatch, try again\n"); + continue; + } + } + if(!passtokey(key, pass)){ + print("bad password, try again\n"); + continue; + } + if(check) + if(err = okpasswd(pass)){ + print("%s, try again\n", err); + continue; + } + break; + } +} + +int +getsecret(int passvalid, char *p9pass) +{ + char answer[32]; + + readln("assign Inferno/POP secret? (y/n) ", answer, sizeof answer, 0); + if(*answer != 'y' && *answer != 'Y') + return 0; + + if(passvalid){ + readln("make it the same as the plan 9 password? (y/n) ", + answer, sizeof answer, 0); + if(*answer == 'y' || *answer == 'Y') + return 1; + } + + for(;;){ + readln("Secret(0 to 256 characters): ", p9pass, + sizeof answer, 1); + readln("Confirm: ", answer, sizeof answer, 1); + if(strcmp(p9pass, answer) == 0) + break; + print("mismatch, try again\n"); + } + return 1; +} + +void +readln(char *prompt, char *line, int len, int raw) +{ + char *p; + int fdin, fdout, ctl, n, nr; + + fdin = open("/dev/cons", OREAD); + fdout = open("/dev/cons", OWRITE); + fprint(fdout, "%s", prompt); + if(raw){ + ctl = open("/dev/consctl", OWRITE); + if(ctl < 0) + error("couldn't set raw mode"); + write(ctl, "rawon", 5); + } else + ctl = -1; + nr = 0; + p = line; + for(;;){ + n = read(fdin, p, 1); + if(n < 0){ + close(ctl); + error("can't read cons\n"); + } + if(*p == 0x7f) + exits(0); + if(n == 0 || *p == '\n' || *p == '\r'){ + *p = '\0'; + if(raw){ + write(ctl, "rawoff", 6); + write(fdout, "\n", 1); + } + close(ctl); + return; + } + if(*p == '\b'){ + if(nr > 0){ + nr--; + p--; + } + }else{ + nr++; + p++; + } + if(nr == len){ + fprint(fdout, "line too long; try again\n"); + nr = 0; + p = line; + } + } +} diff --git a/sys/src/cmd/auth/lib/readn.c b/sys/src/cmd/auth/lib/readn.c new file mode 100755 index 000000000..6f9324958 --- /dev/null +++ b/sys/src/cmd/auth/lib/readn.c @@ -0,0 +1,20 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include "authcmdlib.h" + +/* + * read exactly len bytes + */ +int +readn(int fd, char *buf, int len) +{ + int m, n; + + for(n = 0; n < len; n += m){ + m = read(fd, buf+n, len-n); + if(m <= 0) + return -1; + } + return n; +} diff --git a/sys/src/cmd/auth/lib/readwrite.c b/sys/src/cmd/auth/lib/readwrite.c new file mode 100755 index 000000000..54f494eb4 --- /dev/null +++ b/sys/src/cmd/auth/lib/readwrite.c @@ -0,0 +1,90 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> +#include <bio.h> +#include "authcmdlib.h" + +int +readfile(char *file, char *buf, int n) +{ + int fd; + + fd = open(file, OREAD); + if(fd < 0){ + werrstr("%s: %r", file); + return -1; + } + n = read(fd, buf, n); + close(fd); + return n; +} + +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; +} + +char* +findkey(char *db, char *user, char *key) +{ + int n; + char filename[Maxpath]; + + snprint(filename, sizeof filename, "%s/%s/key", db, user); + n = readfile(filename, key, DESKEYLEN); + if(n != DESKEYLEN) + return 0; + else + return key; +} + +char* +findsecret(char *db, char *user, char *secret) +{ + int n; + char filename[Maxpath]; + + snprint(filename, sizeof filename, "%s/%s/secret", db, user); + n = readfile(filename, secret, SECRETLEN-1); + secret[n]=0; + if(n <= 0) + return 0; + else + return secret; +} + +char* +setkey(char *db, char *user, char *key) +{ + int n; + char filename[Maxpath]; + + snprint(filename, sizeof filename, "%s/%s/key", db, user); + n = writefile(filename, key, DESKEYLEN); + if(n != DESKEYLEN) + return 0; + else + return key; +} + +char* +setsecret(char *db, char *user, char *secret) +{ + int n; + char filename[Maxpath]; + + snprint(filename, sizeof filename, "%s/%s/secret", db, user); + n = writefile(filename, secret, strlen(secret)); + if(n != strlen(secret)) + return 0; + else + return secret; +} diff --git a/sys/src/cmd/auth/lib/wrbio.c b/sys/src/cmd/auth/lib/wrbio.c new file mode 100755 index 000000000..e50ca500b --- /dev/null +++ b/sys/src/cmd/auth/lib/wrbio.c @@ -0,0 +1,40 @@ +#include <u.h> +#include <libc.h> +#include <bio.h> +#include <ctype.h> +#include "authcmdlib.h" + +void +wrbio(char *file, Acctbio *a) +{ + char buf[1024]; + int i, fd, n; + + fd = open(file, OWRITE); + if(fd < 0) + error("can't open %s", file); + if(seek(fd, 0, 2) < 0) + error("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); +} |