void main(int argc, char *argv[]) { char buf[32], pass[32], key[DESKEYLEN]; char *s; int n; ARGBEGIN{ default: usage(); }ARGEND if(argc) usage(); s = getenv("service"); if(s && strcmp(s, "cpu") == 0){ fprint(2, "netkey must not be run on the cpu server\n"); exits("boofhead"); } readln("Password: "******"challenge: "); n = read(0, buf, sizeof buf - 1); if(n <= 0) exits(0); buf[n] = '\0'; n = strtol(buf, 0, 10); snprint(buf, sizeof buf, "%d", n); netcrypt(key, buf); print("response: %s\n", buf); } }
AuthInfo* auth_userpasswd(char *user, char *passwd) { char key[DESKEYLEN], resp[16]; AuthInfo *ai; Chalstate *ch; /* * Probably we should have a factotum protocol * to check a raw password. For now, we use * p9cr, which is simplest to speak. */ if((ch = auth_challenge("user=%q proto=p9cr role=server", user)) == nil) return nil; passtokey(key, passwd); netresp(key, atol(ch->chal), resp); memset(key, 0, sizeof key); ch->resp = resp; ch->nresp = strlen(resp); ai = auth_response(ch); auth_freechal(ch); return ai; }
int conslock(void) { char *ln; char nkey1[DESKEYLEN]; static char zeroes[DESKEYLEN]; if(memcmp(nvr.machkey, zeroes, DESKEYLEN) == 0) { print("no password set\n"); return 0; } for(;;) { print("%s password:"******"Bad password\n"); delay(1000); } return 1; }
void http(Ticketreq *tr) { Ticket t; char tbuf[TICKETLEN+1]; char key[DESKEYLEN]; char *p; Biobuf *b; int n; n = strlen(tr->uid); b = Bopen("/sys/lib/httppasswords", OREAD); if(b == nil){ replyerror("no password file", raddr); return; } /* find key */ for(;;){ p = Brdline(b, '\n'); if(p == nil) break; p[Blinelen(b)-1] = 0; if(strncmp(p, tr->uid, n) == 0) if(p[n] == ' ' || p[n] == '\t'){ p += n; break; } } Bterm(b); if(p == nil) { randombytes((uchar*)key, DESKEYLEN); } else { while(*p == ' ' || *p == '\t') p++; passtokey(key, p); } /* send back a ticket encrypted with the key */ randombytes((uchar*)t.chal, CHALLEN); mkkey(t.key); tbuf[0] = AuthOK; t.num = AuthHr; safecpy(t.cuid, tr->uid, sizeof(t.cuid)); safecpy(t.suid, tr->uid, sizeof(t.suid)); convT2M(&t, tbuf+1, key); write(1, tbuf, sizeof(tbuf)); }
int httpauth(char *name, char *password) { int afd; Ticketreq tr; Ticket t; char key[DESKEYLEN]; char buf[512]; afd = authdial(nil, nil); if(afd < 0) return -1; /* send ticket request to AS */ memset(&tr, 0, sizeof(tr)); strcpy(tr.uid, name); tr.type = AuthHttp; convTR2M(&tr, buf); if(write(afd, buf, TICKREQLEN) != TICKREQLEN){ close(afd); return -1; } if(_asrdresp(afd, buf, TICKETLEN) < 0){ close(afd); return -1; } close(afd); /* * use password and try to decrypt the * ticket. If it doesn't work we've got a bad password, * give up. */ passtokey(key, password); convM2T(buf, &t, key); if(t.num != AuthHr || strcmp(t.cuid, tr.uid)) return -1; return 0; }
/* * 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: can'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) werrstr(""); 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 && nvrfile != nil) fprint(2, "can't open %s: %r\n", nvrfile); else if(loc.fd < 0){ /* this will have been printed above */ // fprint(2, "can't find nvram: %r\n"); }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 authentication password"); // err |= check(safe->config, CONFIGLEN, safe->configsum, // "bad secstore password"); 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); for(;;){ if(readcons("auth password", nil, 1, in, sizeof in) == nil) goto Out; if(passtokey(safe->machkey, in)) break; } readcons("secstore password", nil, 1, safe->config, sizeof safe->config); } // 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) werrstr(""); 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; }
/* * 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) { char buf[1024], in[128], *cputype, *nvrfile, *nvrlen, *nvroff, *v[2]; int fd, err, i, safeoff, safelen; Nvrsafe *safe; err = 0; memset(safep, 0, sizeof(*safep)); nvrfile = getenv("nvram"); cputype = getenv("cputype"); if(cputype == nil) cputype = "mips"; if(strcmp(cputype, "386")==0 || strcmp(cputype, "alpha")==0) cputype = "pc"; fd = -1; safeoff = -1; safelen = -1; if(nvrfile != nil){ /* accept device and device!file */ i = gettokens(nvrfile, v, nelem(v), "!"); fd = open(v[0], ORDWR); 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){ close(fd); fd = -1; } } free(nvrfile); if(nvrlen != nil) free(nvrlen); if(nvroff != nil) free(nvroff); }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){ close(fd); fd = -1; continue; } } break; } } if(fd < 0 || seek(fd, safeoff, 0) < 0 || read(fd, buf, safelen) != safelen){ err = 1; if(flag&(NVwrite|NVwriteonerr)) fprint(2, "can't read nvram: %r\n"); memset(safep, 0, sizeof(*safep)); safe = safep; }else{ memmove(safep, buf, sizeof *safep); safe = safep; 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((flag&NVwrite) || (err && (flag&NVwriteonerr))){ xreadcons("authid", nil, 0, safe->authid, sizeof(safe->authid)); xreadcons("authdom", nil, 0, safe->authdom, sizeof(safe->authdom)); xreadcons("secstore key", nil, 1, safe->config, sizeof(safe->config)); for(;;){ if(xreadcons("password", nil, 1, in, sizeof in) == nil) goto Out; if(passtokey(safe->machkey, in)) break; } 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)); memmove(buf, safe, sizeof *safe); if(seek(fd, safeoff, 0) < 0 || write(fd, buf, safelen) != safelen){ fprint(2, "can't write key to nvram: %r\n"); err = 1; }else err = 0; } Out: close(fd); return err ? -1 : 0; }
AuthInfo* p9any(int fd) { char buf[1024], buf2[1024], cchal[CHALLEN], *bbuf, *p, *dom, *u; char *pass; char tbuf[TICKETLEN+TICKETLEN+AUTHENTLEN], trbuf[TICKREQLEN]; char authkey[DESKEYLEN]; Authenticator auth; int afd, i, n, v2; Ticketreq tr; Ticket t; AuthInfo *ai; if((afd = open("/mnt/factotum/ctl", ORDWR)) >= 0) return p9anyfactotum(fd, afd); if(readstr(fd, buf, sizeof buf) < 0) fatal(1, "cannot read p9any negotiation"); bbuf = buf; v2 = 0; if(strncmp(buf, "v.2 ", 4) == 0){ v2 = 1; bbuf += 4; } if((p = strchr(bbuf, ' '))) *p = 0; p = bbuf; if((dom = strchr(p, '@')) == nil) fatal(1, "bad p9any domain"); *dom++ = 0; if(strcmp(p, "p9sk1") != 0) fatal(1, "server did not offer p9sk1"); sprint(buf2, "%s %s", p, dom); if(write(fd, buf2, strlen(buf2)+1) != strlen(buf2)+1) fatal(1, "cannot write user/domain choice in p9any"); if(v2){ if(readstr(fd, buf, sizeof buf) != 3) fatal(1, "cannot read OK in p9any"); if(memcmp(buf, "OK\0", 3) != 0) fatal(1, "did not get OK in p9any"); } for(i=0; i<CHALLEN; i++) cchal[i] = fastrand(); if(write(fd, cchal, 8) != 8) fatal(1, "cannot write p9sk1 challenge"); if(readn(fd, trbuf, TICKREQLEN) != TICKREQLEN) fatal(1, "cannot read ticket request in p9sk1"); convM2TR(trbuf, &tr); u = user; pass = findkey(&u, tr.authdom); if(pass == nil) again: pass = getkey(u, tr.authdom); if(pass == nil) fatal(1, "no password"); passtokey(authkey, pass); memset(pass, 0, strlen(pass)); tr.type = AuthTreq; strecpy(tr.hostid, tr.hostid+sizeof tr.hostid, u); strecpy(tr.uid, tr.uid+sizeof tr.uid, u); convTR2M(&tr, trbuf); if(gettickets(&tr, authkey, trbuf, tbuf) < 0) fatal(1, "cannot get auth tickets in p9sk1"); convM2T(tbuf, &t, authkey); if(t.num != AuthTc){ print("?password mismatch with auth server\n"); goto again; } memmove(tbuf, tbuf+TICKETLEN, TICKETLEN); auth.num = AuthAc; memmove(auth.chal, tr.chal, CHALLEN); auth.id = 0; convA2M(&auth, tbuf+TICKETLEN, t.key); if(write(fd, tbuf, TICKETLEN+AUTHENTLEN) != TICKETLEN+AUTHENTLEN) fatal(1, "cannot send ticket and authenticator back in p9sk1"); if((n=readn(fd, tbuf, AUTHENTLEN)) != AUTHENTLEN || memcmp(tbuf, "cpu:", 4) == 0){ if(n <= 4) fatal(1, "cannot read authenticator in p9sk1"); /* * didn't send back authenticator: * sent back fatal error message. */ memmove(buf, tbuf, n); i = readn(fd, buf+n, sizeof buf-n-1); if(i > 0) n += i; buf[n] = 0; werrstr(""); fatal(0, "server says: %s", buf); } convM2A(tbuf, &auth, t.key); if(auth.num != AuthAs || memcmp(auth.chal, cchal, CHALLEN) != 0 || auth.id != 0){ print("?you and auth server agree about password.\n"); print("?server is confused.\n"); fatal(0, "server lies got %llux.%d want %llux.%d", *(int64_t*)auth.chal, auth.id, *(int64_t*)cchal, 0); } //print("i am %s there.\n", t.suid); ai = mallocz(sizeof(AuthInfo), 1); ai->secret = mallocz(8, 1); des56to64((uint8_t*)t.key, ai->secret); ai->nsecret = 8; ai->suid = strdup(t.suid); ai->cuid = strdup(t.cuid); memset(authkey, 0, sizeof authkey); return ai; }
void changepasswd(Ticketreq *tr) { Ticket t; char tbuf[TICKETLEN+1]; char prbuf[PASSREQLEN]; Passwordreq pr; char okey[DESKEYLEN], nkey[DESKEYLEN]; char *err; if(findkey(KEYDB, tr->uid, okey) == 0){ /* make one up so caller doesn't know it was wrong */ mkkey(okey); syslog(0, AUTHLOG, "cp-fail uid %s", raddr); } /* send back a ticket with a new key */ memmove(t.chal, tr->chal, CHALLEN); mkkey(t.key); tbuf[0] = AuthOK; t.num = AuthTp; safecpy(t.cuid, tr->uid, sizeof(t.cuid)); safecpy(t.suid, tr->uid, sizeof(t.suid)); convT2M(&t, tbuf+1, okey); write(1, tbuf, sizeof(tbuf)); /* loop trying passwords out */ for(;;){ if(readn(0, prbuf, PASSREQLEN) < 0) exits(0); convM2PR(prbuf, &pr, t.key); if(pr.num != AuthPass){ replyerror("protocol botch1: %s", raddr); exits(0); } passtokey(nkey, pr.old); if(memcmp(nkey, okey, DESKEYLEN)){ replyerror("protocol botch2: %s", raddr); continue; } if(*pr.new){ err = okpasswd(pr.new); if(err){ replyerror("%s %s", err, raddr); continue; } passtokey(nkey, pr.new); } if(pr.changesecret && setsecret(KEYDB, tr->uid, pr.secret) == 0){ replyerror("can't write secret %s", raddr); continue; } if(*pr.new && setkey(KEYDB, tr->uid, nkey) == 0){ replyerror("can't write key %s", raddr); continue; } break; } prbuf[0] = AuthOK; write(1, prbuf, 1); succeed(tr->uid); return; }