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/libauthsrv |
Import sources from 2011-03-30 iso image
Diffstat (limited to 'sys/src/libauthsrv')
-rwxr-xr-x | sys/src/libauthsrv/_asgetticket.c | 16 | ||||
-rwxr-xr-x | sys/src/libauthsrv/_asrdresp.c | 56 | ||||
-rwxr-xr-x | sys/src/libauthsrv/authdial.c | 36 | ||||
-rwxr-xr-x | sys/src/libauthsrv/convA2M.c | 25 | ||||
-rwxr-xr-x | sys/src/libauthsrv/convM2A.c | 23 | ||||
-rwxr-xr-x | sys/src/libauthsrv/convM2PR.c | 28 | ||||
-rwxr-xr-x | sys/src/libauthsrv/convM2T.c | 28 | ||||
-rwxr-xr-x | sys/src/libauthsrv/convM2TR.c | 28 | ||||
-rwxr-xr-x | sys/src/libauthsrv/convPR2M.c | 28 | ||||
-rwxr-xr-x | sys/src/libauthsrv/convT2M.c | 27 | ||||
-rwxr-xr-x | sys/src/libauthsrv/convTR2M.c | 27 | ||||
-rwxr-xr-x | sys/src/libauthsrv/mkfile | 30 | ||||
-rwxr-xr-x | sys/src/libauthsrv/nvcsum.c | 16 | ||||
-rwxr-xr-x | sys/src/libauthsrv/opasstokey.c | 29 | ||||
-rwxr-xr-x | sys/src/libauthsrv/passtokey.c | 32 | ||||
-rwxr-xr-x | sys/src/libauthsrv/readnvram.c | 454 |
16 files changed, 883 insertions, 0 deletions
diff --git a/sys/src/libauthsrv/_asgetticket.c b/sys/src/libauthsrv/_asgetticket.c new file mode 100755 index 000000000..ea9e0c9ef --- /dev/null +++ b/sys/src/libauthsrv/_asgetticket.c @@ -0,0 +1,16 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> + +static char *pbmsg = "AS protocol botch"; + +int +_asgetticket(int fd, char *trbuf, char *tbuf) +{ + if(write(fd, trbuf, TICKREQLEN) < 0){ + close(fd); + werrstr(pbmsg); + return -1; + } + return _asrdresp(fd, tbuf, 2*TICKETLEN); +} diff --git a/sys/src/libauthsrv/_asrdresp.c b/sys/src/libauthsrv/_asrdresp.c new file mode 100755 index 000000000..8a7daf8cc --- /dev/null +++ b/sys/src/libauthsrv/_asrdresp.c @@ -0,0 +1,56 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> + +static char *pbmsg = "AS protocol botch"; + +int +_asrdresp(int fd, char *buf, int len) +{ + int n; + char error[64]; + + if(read(fd, buf, 1) != 1){ + werrstr(pbmsg); + return -1; + } + + n = len; + switch(buf[0]){ + case AuthOK: + if(readn(fd, buf, len) != len){ + werrstr(pbmsg); + return -1; + } + break; + case AuthErr: + if(readn(fd, error, sizeof error) != sizeof error){ + werrstr(pbmsg); + return -1; + } + error[sizeof error-1] = '\0'; + werrstr("remote: %s", error); + return -1; + case AuthOKvar: + if(readn(fd, error, 5) != 5){ + werrstr(pbmsg); + return -1; + } + error[5] = 0; + n = atoi(error); + if(n <= 0 || n > len){ + werrstr(pbmsg); + return -1; + } + memset(buf, 0, len); + if(readn(fd, buf, n) != n){ + werrstr(pbmsg); + return -1; + } + break; + default: + werrstr(pbmsg); + return -1; + } + return n; +} diff --git a/sys/src/libauthsrv/authdial.c b/sys/src/libauthsrv/authdial.c new file mode 100755 index 000000000..c54803ba7 --- /dev/null +++ b/sys/src/libauthsrv/authdial.c @@ -0,0 +1,36 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> +#include <bio.h> +#include <ndb.h> + +int +authdial(char *netroot, char *dom) +{ + char *p; + int rv; + + if(dom == nil) + /* look for one relative to my machine */ + return dial(netmkaddr("$auth", netroot, "ticket"), 0, 0, 0); + + /* look up an auth server in an authentication domain */ + p = csgetvalue(netroot, "authdom", dom, "auth", nil); + + /* if that didn't work, just try the IP domain */ + if(p == nil) + p = csgetvalue(netroot, "dom", dom, "auth", nil); + /* + * if that didn't work, try p9auth.$dom. this is very helpful if + * you can't edit /lib/ndb. + */ + if(p == nil) + p = smprint("p9auth.%s", dom); + if(p == nil){ /* should no longer ever happen */ + werrstr("no auth server found for %s", dom); + return -1; + } + rv = dial(netmkaddr(p, netroot, "ticket"), 0, 0, 0); + free(p); + return rv; +} diff --git a/sys/src/libauthsrv/convA2M.c b/sys/src/libauthsrv/convA2M.c new file mode 100755 index 000000000..2799cbf56 --- /dev/null +++ b/sys/src/libauthsrv/convA2M.c @@ -0,0 +1,25 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> + +#define CHAR(x) *p++ = f->x +#define SHORT(x) p[0] = f->x; p[1] = f->x>>8; p += 2 +#define VLONG(q) p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4 +#define LONG(x) VLONG(f->x) +#define STRING(x,n) memmove(p, f->x, n); p += n + +int +convA2M(Authenticator *f, char *ap, char *key) +{ + int n; + uchar *p; + + p = (uchar*)ap; + CHAR(num); + STRING(chal, CHALLEN); + LONG(id); + n = p - (uchar*)ap; + if(key) + encrypt(key, ap, n); + return n; +} diff --git a/sys/src/libauthsrv/convM2A.c b/sys/src/libauthsrv/convM2A.c new file mode 100755 index 000000000..3d58f9b59 --- /dev/null +++ b/sys/src/libauthsrv/convM2A.c @@ -0,0 +1,23 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> + +#define CHAR(x) f->x = *p++ +#define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2 +#define VLONG(q) q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4 +#define LONG(x) VLONG(f->x) +#define STRING(x,n) memmove(f->x, p, n); p += n + +void +convM2A(char *ap, Authenticator *f, char *key) +{ + uchar *p; + + if(key) + decrypt(key, ap, AUTHENTLEN); + p = (uchar*)ap; + CHAR(num); + STRING(chal, CHALLEN); + LONG(id); + USED(p); +} diff --git a/sys/src/libauthsrv/convM2PR.c b/sys/src/libauthsrv/convM2PR.c new file mode 100755 index 000000000..21df5b508 --- /dev/null +++ b/sys/src/libauthsrv/convM2PR.c @@ -0,0 +1,28 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> + +#define CHAR(x) f->x = *p++ +#define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2 +#define VLONG(q) q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4 +#define LONG(x) VLONG(f->x) +#define STRING(x,n) memmove(f->x, p, n); p += n + +void +convM2PR(char *ap, Passwordreq *f, char *key) +{ + uchar *p; + + p = (uchar*)ap; + if(key) + decrypt(key, ap, PASSREQLEN); + CHAR(num); + STRING(old, ANAMELEN); + f->old[ANAMELEN-1] = 0; + STRING(new, ANAMELEN); + f->new[ANAMELEN-1] = 0; + CHAR(changesecret); + STRING(secret, SECRETLEN); + f->secret[SECRETLEN-1] = 0; + USED(p); +} diff --git a/sys/src/libauthsrv/convM2T.c b/sys/src/libauthsrv/convM2T.c new file mode 100755 index 000000000..372825a87 --- /dev/null +++ b/sys/src/libauthsrv/convM2T.c @@ -0,0 +1,28 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> + +#define CHAR(x) f->x = *p++ +#define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2 +#define VLONG(q) q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4 +#define LONG(x) VLONG(f->x) +#define STRING(x,n) memmove(f->x, p, n); p += n + +void +convM2T(char *ap, Ticket *f, char *key) +{ + uchar *p; + + if(key) + decrypt(key, ap, TICKETLEN); + p = (uchar*)ap; + CHAR(num); + STRING(chal, CHALLEN); + STRING(cuid, ANAMELEN); + f->cuid[ANAMELEN-1] = 0; + STRING(suid, ANAMELEN); + f->suid[ANAMELEN-1] = 0; + STRING(key, DESKEYLEN); + USED(p); +} + diff --git a/sys/src/libauthsrv/convM2TR.c b/sys/src/libauthsrv/convM2TR.c new file mode 100755 index 000000000..ffad75c77 --- /dev/null +++ b/sys/src/libauthsrv/convM2TR.c @@ -0,0 +1,28 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> + +#define CHAR(x) f->x = *p++ +#define SHORT(x) f->x = (p[0] | (p[1]<<8)); p += 2 +#define VLONG(q) q = (p[0] | (p[1]<<8) | (p[2]<<16) | (p[3]<<24)); p += 4 +#define LONG(x) VLONG(f->x) +#define STRING(x,n) memmove(f->x, p, n); p += n + +void +convM2TR(char *ap, Ticketreq *f) +{ + uchar *p; + + p = (uchar*)ap; + CHAR(type); + STRING(authid, ANAMELEN); + f->authid[ANAMELEN-1] = 0; + STRING(authdom, DOMLEN); + f->authdom[DOMLEN-1] = 0; + STRING(chal, CHALLEN); + STRING(hostid, ANAMELEN); + f->hostid[ANAMELEN-1] = 0; + STRING(uid, ANAMELEN); + f->uid[ANAMELEN-1] = 0; + USED(p); +} diff --git a/sys/src/libauthsrv/convPR2M.c b/sys/src/libauthsrv/convPR2M.c new file mode 100755 index 000000000..8b2422f1b --- /dev/null +++ b/sys/src/libauthsrv/convPR2M.c @@ -0,0 +1,28 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> + +#define CHAR(x) *p++ = f->x +#define SHORT(x) p[0] = f->x; p[1] = f->x>>8; p += 2 +#define VLONG(q) p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4 +#define LONG(x) VLONG(f->x) +#define STRING(x,n) memmove(p, f->x, n); p += n + +int +convPR2M(Passwordreq *f, char *ap, char *key) +{ + int n; + uchar *p; + + p = (uchar*)ap; + CHAR(num); + STRING(old, ANAMELEN); + STRING(new, ANAMELEN); + CHAR(changesecret); + STRING(secret, SECRETLEN); + n = p - (uchar*)ap; + if(key) + encrypt(key, ap, n); + return n; +} + diff --git a/sys/src/libauthsrv/convT2M.c b/sys/src/libauthsrv/convT2M.c new file mode 100755 index 000000000..810ba5c67 --- /dev/null +++ b/sys/src/libauthsrv/convT2M.c @@ -0,0 +1,27 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> + +#define CHAR(x) *p++ = f->x +#define SHORT(x) p[0] = f->x; p[1] = f->x>>8; p += 2 +#define VLONG(q) p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4 +#define LONG(x) VLONG(f->x) +#define STRING(x,n) memmove(p, f->x, n); p += n + +int +convT2M(Ticket *f, char *ap, char *key) +{ + int n; + uchar *p; + + p = (uchar*)ap; + CHAR(num); + STRING(chal, CHALLEN); + STRING(cuid, ANAMELEN); + STRING(suid, ANAMELEN); + STRING(key, DESKEYLEN); + n = p - (uchar*)ap; + if(key) + encrypt(key, ap, n); + return n; +} diff --git a/sys/src/libauthsrv/convTR2M.c b/sys/src/libauthsrv/convTR2M.c new file mode 100755 index 000000000..3a7610a71 --- /dev/null +++ b/sys/src/libauthsrv/convTR2M.c @@ -0,0 +1,27 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> + +#define CHAR(x) *p++ = f->x +#define SHORT(x) p[0] = f->x; p[1] = f->x>>8; p += 2 +#define VLONG(q) p[0] = (q); p[1] = (q)>>8; p[2] = (q)>>16; p[3] = (q)>>24; p += 4 +#define LONG(x) VLONG(f->x) +#define STRING(x,n) memmove(p, f->x, n); p += n + +int +convTR2M(Ticketreq *f, char *ap) +{ + int n; + uchar *p; + + p = (uchar*)ap; + CHAR(type); + STRING(authid, 28); /* BUG */ + STRING(authdom, DOMLEN); + STRING(chal, CHALLEN); + STRING(hostid, 28); /* BUG */ + STRING(uid, 28); /* BUG */ + n = p - (uchar*)ap; + return n; +} + diff --git a/sys/src/libauthsrv/mkfile b/sys/src/libauthsrv/mkfile new file mode 100755 index 000000000..2480c29c9 --- /dev/null +++ b/sys/src/libauthsrv/mkfile @@ -0,0 +1,30 @@ +</$objtype/mkfile + +LIB=/$objtype/lib/libauthsrv.a +OFILES=\ + _asgetticket.$O\ + _asrdresp.$O\ + authdial.$O\ + convA2M.$O\ + convM2A.$O\ + convM2PR.$O\ + convM2T.$O\ + convM2TR.$O\ + convPR2M.$O\ + convT2M.$O\ + convTR2M.$O\ + nvcsum.$O\ + opasstokey.$O\ + passtokey.$O\ + readnvram.$O\ + +HFILES=\ + /sys/include/authsrv.h\ + +UPDATE=\ + mkfile\ + $HFILES\ + ${OFILES:%.$O=%.c}\ + ${LIB:/$objtype/%=/386/%}\ + +</sys/src/cmd/mksyslib diff --git a/sys/src/libauthsrv/nvcsum.c b/sys/src/libauthsrv/nvcsum.c new file mode 100755 index 000000000..306d7f7ed --- /dev/null +++ b/sys/src/libauthsrv/nvcsum.c @@ -0,0 +1,16 @@ +#include <u.h> +#include <libc.h> +#include <auth.h> + +uchar +nvcsum(void *vmem, int n) +{ + uchar *mem, sum; + int i; + + sum = 9; + mem = vmem; + for(i = 0; i < n; i++) + sum += mem[i]; + return sum; +} diff --git a/sys/src/libauthsrv/opasstokey.c b/sys/src/libauthsrv/opasstokey.c new file mode 100755 index 000000000..d263d4b76 --- /dev/null +++ b/sys/src/libauthsrv/opasstokey.c @@ -0,0 +1,29 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> + +int +opasstokey(char *key, char *p) +{ + uchar t[10]; + int c, n; + + n = strlen(p); + memset(t, ' ', sizeof t); + if(n < 5) + return 0; + if(n > 10) + n = 10; + strncpy((char*)t, p, n); + if(n >= 9){ + c = p[8] & 0xf; + if(n == 10) + c += p[9] << 4; + for(n = 0; n < 8; n++) + if(c & (1 << n)) + t[n] -= ' '; + } + for(n = 0; n < 7; n++) + key[n] = (t[n] >> n) + (t[n+1] << (8 - (n+1))); + return 1; +} diff --git a/sys/src/libauthsrv/passtokey.c b/sys/src/libauthsrv/passtokey.c new file mode 100755 index 000000000..cde9a2422 --- /dev/null +++ b/sys/src/libauthsrv/passtokey.c @@ -0,0 +1,32 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> + +int +passtokey(char *key, char *p) +{ + uchar buf[ANAMELEN], *t; + int i, n; + + n = strlen(p); + if(n >= ANAMELEN) + n = ANAMELEN-1; + memset(buf, ' ', 8); + t = buf; + strncpy((char*)t, p, n); + t[n] = 0; + memset(key, 0, DESKEYLEN); + for(;;){ + for(i = 0; i < DESKEYLEN; i++) + key[i] = (t[i] >> i) + (t[i+1] << (8 - (i+1))); + if(n <= 8) + return 1; + n -= 8; + t += 8; + if(n < 8){ + t -= 8 - n; + n = 8; + } + encrypt(key, t, 8); + } +} diff --git a/sys/src/libauthsrv/readnvram.c b/sys/src/libauthsrv/readnvram.c new file mode 100755 index 000000000..3303ed613 --- /dev/null +++ b/sys/src/libauthsrv/readnvram.c @@ -0,0 +1,454 @@ +#include <u.h> +#include <libc.h> +#include <authsrv.h> + +static long finddosfile(int, char*); + +static int +check(void *x, int len, uchar sum, char *msg) +{ + if(nvcsum(x, len) == sum) + return 0; + memset(x, 0, len); + fprint(2, "%s\n", msg); + return 1; +} + +/* + * get key info out of nvram. since there isn't room in the PC's nvram use + * a disk partition there. + */ +static struct { + char *cputype; + char *file; + int off; + int len; +} nvtab[] = { + "sparc", "#r/nvram", 1024+850, sizeof(Nvrsafe), + "pc", "#S/sdC0/nvram", 0, sizeof(Nvrsafe), + "pc", "#S/sdC0/9fat", -1, sizeof(Nvrsafe), + "pc", "#S/sdC1/nvram", 0, sizeof(Nvrsafe), + "pc", "#S/sdC1/9fat", -1, sizeof(Nvrsafe), + "pc", "#S/sdD0/nvram", 0, sizeof(Nvrsafe), + "pc", "#S/sdD0/9fat", -1, sizeof(Nvrsafe), + "pc", "#S/sdE0/nvram", 0, sizeof(Nvrsafe), + "pc", "#S/sdE0/9fat", -1, sizeof(Nvrsafe), + "pc", "#S/sdF0/nvram", 0, sizeof(Nvrsafe), + "pc", "#S/sdF0/9fat", -1, sizeof(Nvrsafe), + "pc", "#S/sd00/nvram", 0, sizeof(Nvrsafe), + "pc", "#S/sd00/9fat", -1, sizeof(Nvrsafe), + "pc", "#S/sd01/nvram", 0, sizeof(Nvrsafe), + "pc", "#S/sd01/9fat", -1, sizeof(Nvrsafe), + "pc", "#S/sd10/nvram", 0, sizeof(Nvrsafe), + "pc", "#S/sd10/9fat", -1, sizeof(Nvrsafe), + "pc", "#f/fd0disk", -1, 512, /* 512: #f requires whole sector reads */ + "pc", "#f/fd1disk", -1, 512, + "mips", "#r/nvram", 1024+900, sizeof(Nvrsafe), + "power", "#F/flash/flash0", 0x440000, sizeof(Nvrsafe), + "power", "#F/flash/flash", 0x440000, sizeof(Nvrsafe), + "power", "#r/nvram", 4352, sizeof(Nvrsafe), /* OK for MTX-604e */ + "power", "/nvram", 0, sizeof(Nvrsafe), /* OK for Ucu */ + "arm", "#F/flash/flash0", 0x100000, sizeof(Nvrsafe), + "arm", "#F/flash/flash", 0x100000, sizeof(Nvrsafe), + "debug", "/tmp/nvram", 0, sizeof(Nvrsafe), +}; + +static char* +readcons(char *prompt, char *def, int raw, char *buf, int nbuf) +{ + int fdin, fdout, ctl, n, m; + char line[10]; + + fdin = open("/dev/cons", OREAD); + if(fdin < 0) + fdin = 0; + fdout = open("/dev/cons", OWRITE); + if(fdout < 0) + fdout = 1; + if(def != nil) + fprint(fdout, "%s[%s]: ", prompt, def); + else + fprint(fdout, "%s: ", prompt); + if(raw){ + ctl = open("/dev/consctl", OWRITE); + if(ctl >= 0) + write(ctl, "rawon", 5); + } else + ctl = -1; + + m = 0; + for(;;){ + n = read(fdin, line, 1); + if(n == 0){ + close(ctl); + werrstr("readcons: EOF"); + return nil; + } + if(n < 0){ + close(ctl); + werrstr("can't read cons"); + return nil; + } + if(line[0] == 0x7f) + exits(0); + if(n == 0 || line[0] == '\n' || line[0] == '\r'){ + if(raw){ + write(ctl, "rawoff", 6); + write(fdout, "\n", 1); + close(ctl); + } + buf[m] = '\0'; + if(buf[0]=='\0' && def) + strcpy(buf, def); + return buf; + } + if(line[0] == '\b'){ + if(m > 0) + m--; + }else if(line[0] == 0x15){ /* ^U: line kill */ + m = 0; + if(def != nil) + fprint(fdout, "%s[%s]: ", prompt, def); + else + fprint(fdout, "%s: ", prompt); + }else{ + if(m >= nbuf-1){ + fprint(fdout, "line too long\n"); + m = 0; + if(def != nil) + fprint(fdout, "%s[%s]: ", prompt, def); + else + fprint(fdout, "%s: ", prompt); + }else + buf[m++] = line[0]; + } + } +} + +typedef struct { + int fd; + int safeoff; + int safelen; +} Nvrwhere; + +static char *nvrfile = nil, *cputype = nil; + +/* returns with *locp filled in and locp->fd open, if possible */ +static void +findnvram(Nvrwhere *locp) +{ + char *nvrlen, *nvroff, *v[2]; + int fd, i, safeoff, safelen; + + if (nvrfile == nil) + nvrfile = getenv("nvram"); + if (cputype == nil) + cputype = getenv("cputype"); + if(cputype == nil) + cputype = strdup("mips"); + if(strcmp(cputype, "386")==0 || strcmp(cputype, "alpha")==0) { + free(cputype); + cputype = strdup("pc"); + } + + fd = -1; + safeoff = -1; + safelen = -1; + if(nvrfile != nil && *nvrfile != '\0'){ + /* accept device and device!file */ + i = gettokens(nvrfile, v, nelem(v), "!"); + if (i < 1) { + i = 1; + v[0] = ""; + v[1] = nil; + } + fd = open(v[0], ORDWR); + if (fd < 0) + fd = open(v[0], OREAD); + safelen = sizeof(Nvrsafe); + if(strstr(v[0], "/9fat") == nil) + safeoff = 0; + nvrlen = getenv("nvrlen"); + if(nvrlen != nil) + safelen = atoi(nvrlen); + nvroff = getenv("nvroff"); + if(nvroff != nil) + if(strcmp(nvroff, "dos") == 0) + safeoff = -1; + else + safeoff = atoi(nvroff); + if(safeoff < 0 && fd >= 0){ + safelen = 512; + safeoff = finddosfile(fd, i == 2? v[1]: "plan9.nvr"); + if(safeoff < 0){ /* didn't find plan9.nvr? */ + close(fd); + fd = -1; + } + } + free(nvroff); + free(nvrlen); + }else + for(i=0; i<nelem(nvtab); i++){ + if(strcmp(cputype, nvtab[i].cputype) != 0) + continue; + if((fd = open(nvtab[i].file, ORDWR)) < 0) + continue; + safeoff = nvtab[i].off; + safelen = nvtab[i].len; + if(safeoff == -1){ + safeoff = finddosfile(fd, "plan9.nvr"); + if(safeoff < 0){ /* didn't find plan9.nvr? */ + close(fd); + fd = -1; + continue; + } + } + break; + } + locp->fd = fd; + locp->safelen = safelen; + locp->safeoff = safeoff; +} + +/* + * get key info out of nvram. since there isn't room in the PC's nvram use + * a disk partition there. + */ +int +readnvram(Nvrsafe *safep, int flag) +{ + int err; + char buf[512], in[128]; /* 512 for floppy i/o */ + Nvrsafe *safe; + Nvrwhere loc; + + err = 0; + safe = (Nvrsafe*)buf; + memset(&loc, 0, sizeof loc); + findnvram(&loc); + if (loc.safelen < 0) + loc.safelen = sizeof *safe; + else if (loc.safelen > sizeof buf) + loc.safelen = sizeof buf; + if (loc.safeoff < 0) { + fprint(2, "readnvram: couldn't find nvram\n"); + if(!(flag&NVwritemem)) + memset(safep, 0, sizeof(*safep)); + safe = safep; + /* + * allow user to type the data for authentication, + * even if there's no nvram to store it in. + */ + } + + if(flag&NVwritemem) + safe = safep; + else { + memset(safep, 0, sizeof(*safep)); + if(loc.fd < 0 + || seek(loc.fd, loc.safeoff, 0) < 0 + || read(loc.fd, buf, loc.safelen) != loc.safelen){ + err = 1; + if(flag&(NVwrite|NVwriteonerr)) + if(loc.fd < 0) + fprint(2, "can't open %s: %r\n", nvrfile); + else if (seek(loc.fd, loc.safeoff, 0) < 0) + fprint(2, "can't seek %s to %d: %r\n", + nvrfile, loc.safeoff); + else + fprint(2, "can't read %d bytes from %s: %r\n", + loc.safelen, nvrfile); + /* start from scratch */ + memset(safep, 0, sizeof(*safep)); + safe = safep; + }else{ + *safep = *safe; /* overwrite arg with data read */ + safe = safep; + + /* verify data read */ + err |= check(safe->machkey, DESKEYLEN, safe->machsum, + "bad nvram key"); +// err |= check(safe->config, CONFIGLEN, safe->configsum, +// "bad secstore key"); + err |= check(safe->authid, ANAMELEN, safe->authidsum, + "bad authentication id"); + err |= check(safe->authdom, DOMLEN, safe->authdomsum, + "bad authentication domain"); + if(err == 0) + if(safe->authid[0]==0 || safe->authdom[0]==0){ + fprint(2, "empty nvram authid or authdom\n"); + err = 1; + } + } + } + + if((flag&(NVwrite|NVwritemem)) || (err && (flag&NVwriteonerr))){ + if (!(flag&NVwritemem)) { + readcons("authid", nil, 0, safe->authid, + sizeof safe->authid); + readcons("authdom", nil, 0, safe->authdom, + sizeof safe->authdom); + readcons("secstore key", nil, 1, safe->config, + sizeof safe->config); + for(;;){ + if(readcons("password", nil, 1, in, sizeof in) + == nil) + goto Out; + if(passtokey(safe->machkey, in)) + break; + } + } + + // safe->authsum = nvcsum(safe->authkey, DESKEYLEN); + safe->machsum = nvcsum(safe->machkey, DESKEYLEN); + safe->configsum = nvcsum(safe->config, CONFIGLEN); + safe->authidsum = nvcsum(safe->authid, sizeof safe->authid); + safe->authdomsum = nvcsum(safe->authdom, sizeof safe->authdom); + + *(Nvrsafe*)buf = *safe; + if(loc.fd < 0 + || seek(loc.fd, loc.safeoff, 0) < 0 + || write(loc.fd, buf, loc.safelen) != loc.safelen){ + fprint(2, "can't write key to nvram: %r\n"); + err = 1; + }else + err = 0; + } +Out: + if (loc.fd >= 0) + close(loc.fd); + return err? -1: 0; +} + +typedef struct Dosboot Dosboot; +struct Dosboot{ + uchar magic[3]; /* really an xx86 JMP instruction */ + uchar version[8]; + uchar sectsize[2]; + uchar clustsize; + uchar nresrv[2]; + uchar nfats; + uchar rootsize[2]; + uchar volsize[2]; + uchar mediadesc; + uchar fatsize[2]; + uchar trksize[2]; + uchar nheads[2]; + uchar nhidden[4]; + uchar bigvolsize[4]; + uchar driveno; + uchar reserved0; + uchar bootsig; + uchar volid[4]; + uchar label[11]; + uchar type[8]; +}; +#define GETSHORT(p) (((p)[1]<<8) | (p)[0]) +#define GETLONG(p) ((GETSHORT((p)+2) << 16) | GETSHORT((p))) + +typedef struct Dosdir Dosdir; +struct Dosdir +{ + char name[8]; + char ext[3]; + uchar attr; + uchar reserved[10]; + uchar time[2]; + uchar date[2]; + uchar start[2]; + uchar length[4]; +}; + +static char* +dosparse(char *from, char *to, int len) +{ + char c; + + memset(to, ' ', len); + if(from == 0) + return 0; + while(len-- > 0){ + c = *from++; + if(c == '.') + return from; + if(c == 0) + break; + if(c >= 'a' && c <= 'z') + *to++ = c + 'A' - 'a'; + else + *to++ = c; + } + return 0; +} + +/* + * return offset of first file block + * + * This is a very simplistic dos file system. It only + * works on floppies, only looks in the root, and only + * returns a pointer to the first block of a file. + * + * This exists for cpu servers that have no hard disk + * or nvram to store the key on. + * + * Please don't make this any smarter: it stays resident + * and I'ld prefer not to waste the space on something that + * runs only at boottime -- presotto. + */ +static long +finddosfile(int fd, char *file) +{ + uchar secbuf[512]; + char name[8]; + char ext[3]; + Dosboot *b; + Dosdir *root, *dp; + int nroot, sectsize, rootoff, rootsects, n; + + /* dos'ize file name */ + file = dosparse(file, name, 8); + dosparse(file, ext, 3); + + /* read boot block, check for sanity */ + b = (Dosboot*)secbuf; + if(read(fd, secbuf, sizeof(secbuf)) != sizeof(secbuf)) + return -1; + if(b->magic[0] != 0xEB || b->magic[1] != 0x3C || b->magic[2] != 0x90) + return -1; + sectsize = GETSHORT(b->sectsize); + if(sectsize != 512) + return -1; + rootoff = (GETSHORT(b->nresrv) + b->nfats*GETSHORT(b->fatsize)) * sectsize; + if(seek(fd, rootoff, 0) < 0) + return -1; + nroot = GETSHORT(b->rootsize); + rootsects = (nroot*sizeof(Dosdir)+sectsize-1)/sectsize; + if(rootsects <= 0 || rootsects > 64) + return -1; + + /* + * read root. it is contiguous to make stuff like + * this easier + */ + root = malloc(rootsects*sectsize); + if(read(fd, root, rootsects*sectsize) != rootsects*sectsize) + return -1; + n = -1; + for(dp = root; dp < &root[nroot]; dp++) + if(memcmp(name, dp->name, 8) == 0 && memcmp(ext, dp->ext, 3) == 0){ + n = GETSHORT(dp->start); + break; + } + free(root); + + if(n < 0) + return -1; + + /* + * dp->start is in cluster units, not sectors. The first + * cluster is cluster 2 which starts immediately after the + * root directory + */ + return rootoff + rootsects*sectsize + (n-2)*sectsize*b->clustsize; +} + |