/* * 8c authsecrets.c * 8l -o authsecrets authsecrets.8 */ #include #include #include #include #include // from authcmdlib.h // copy /sys/src/cmd/auth/lib.8.a here to build.... #pragma lib "./lib.8.a" int getauthkey(char*); void getpass(char*, char*, int, int); char authkey[8]; char *userkeys; int usepass; int readusers(void); static void usage(void) { fprint(2, "usage: %s [-p] [keyfile]\n", argv0); exits("usage"); } void main(int argc, char *argv[]) { char *mntpt; int p[2]; mntpt = "/mnt/keys"; ARGBEGIN{ case 'p': usepass = 1; break; default: usage(); break; }ARGEND argv0 = "keyfs"; userkeys = "/adm/keys"; if(argc > 1) usage(); if(argc == 1) userkeys = argv[0]; if(usepass) { getpass(authkey, nil, 0, 0); } else { if(!getauthkey(authkey)) print("keyfs: warning: can't read NVRAM\n"); } readusers(); } void oldCBCdecrypt(char *key7, uchar *p, int len) { uchar ivec[8]; uchar key[8]; DESstate s; memset(ivec, 0, 8); des56to64((uchar*)key7, key); setupDESstate(&s, key, ivec); desCBCdecrypt((uchar*)p, len, &s); } int userok(char *user, int nu) { int i, n, rv; Rune r; char buf[ANAMELEN+1]; memset(buf, 0, sizeof buf); memmove(buf, user, ANAMELEN); if(buf[ANAMELEN-1] != 0){ fprint(2, "keyfs: %d: no termination: %W\n", nu, buf); return -1; } rv = 0; for(i = 0; buf[i]; i += n){ n = chartorune(&r, buf+i); if(r == Runeerror){ // fprint(2, "keyfs: name %W bad rune byte %d\n", buf, i); rv = -1; } else if(isascii(r) && iscntrl(r) || r == ' ' || r == '/'){ // fprint(2, "keyfs: name %W bad char %C\n", buf, r); rv = -1; } } if(i == 0){ fprint(2, "keyfs: %d: nil name\n", nu); return -1; } if(rv == -1) fprint(2, "keyfs: %d: bad syntax: %W\n", nu, buf); return rv; } int readusers(void) { int fd, i, n, nu; uchar *p, *buf, *ep; Dir *d; /* read file into an array */ fd = open(userkeys, OREAD); if(fd < 0) return 0; d = dirfstat(fd); if(d == nil){ close(fd); return 0; } buf = malloc(d->length); if(buf == 0){ close(fd); free(d); return 0; } n = readn(fd, buf, d->length); close(fd); free(d); if(n != d->length){ free(buf); return 0; } /* decrypt */ n -= n % KEYDBLEN; oldCBCdecrypt(authkey, buf, n); /* unpack */ nu = 0; for(i = KEYDBOFF; i < n; i += KEYDBLEN){ char key[DESKEYLEN]; char secret[SECRETLEN]; char status, warnings; uint expire; ep = buf + i; if(userok((char*)ep, i/KEYDBLEN) < 0) continue; memmove(key, ep + ANAMELEN, DESKEYLEN); p = ep + ANAMELEN + DESKEYLEN; status = *p++; warnings = *p++; if(status >= 2) fprint(2, "keyfs: warning: bad status in key file\n"); expire = p[0] + (p[1]<<8) + (p[2]<<16) + (p[3]<<24); p += 4; memmove(secret, p, SECRETLEN); secret[SECRETLEN-1] = 0; nu++; print("user: %s %s\n", ep, secret); } free(buf); print("%d keys read\n", nu); return 1; }