int ticketrequest(Ticketreq *tr) { char akey[DESKEYLEN]; char hkey[DESKEYLEN]; Ticket t; char tbuf[2*TICKETLEN+1]; if(findkey(KEYDB, tr->authid, akey) == 0){ /* make one up so caller doesn't know it was wrong */ mkkey(akey); if(debug) syslog(0, AUTHLOG, "tr-fail authid %s", raddr); } if(findkey(KEYDB, tr->hostid, hkey) == 0){ /* make one up so caller doesn't know it was wrong */ mkkey(hkey); if(debug) syslog(0, AUTHLOG, "tr-fail hostid %s(%s)", tr->hostid, raddr); } memset(&t, 0, sizeof(t)); memmove(t.chal, tr->chal, CHALLEN); strcpy(t.cuid, tr->uid); if(speaksfor(tr->hostid, tr->uid)) strcpy(t.suid, tr->uid); else { mkkey(akey); mkkey(hkey); if(debug) syslog(0, AUTHLOG, "tr-fail %s@%s(%s) -> %s@%s no speaks for", tr->uid, tr->hostid, raddr, tr->uid, tr->authid); } mkkey(t.key); tbuf[0] = AuthOK; t.num = AuthTc; convT2M(&t, tbuf+1, hkey); t.num = AuthTs; convT2M(&t, tbuf+1+TICKETLEN, akey); if(write(1, tbuf, 2*TICKETLEN+1) < 0){ if(debug) syslog(0, AUTHLOG, "tr-fail %s@%s(%s): hangup", tr->uid, tr->hostid, raddr); exits(0); } if(debug) syslog(0, AUTHLOG, "tr-ok %s@%s(%s) -> %s@%s", tr->uid, tr->hostid, raddr, tr->uid, tr->authid); return 0; }
static int mkserverticket(Ticketreq *tr, char *authkey, char *tbuf) { int i; Ticket t; if(strcmp(tr->authid, tr->hostid) != 0) return -1; memset(&t, 0, sizeof(t)); memmove(t.chal, tr->chal, CHALLEN); strcpy(t.cuid, tr->uid); strcpy(t.suid, tr->uid); for(i=0; i<DESKEYLEN; i++) t.key[i] = fastrand(); t.num = AuthTc; convT2M(&t, tbuf, authkey); t.num = AuthTs; convT2M(&t, tbuf+TICKETLEN, authkey); return 0; }
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)); }
/* * reply with ticket and authenticator */ int tickauthreply(Ticketreq *tr, char *hkey) { Ticket t; Authenticator a; char buf[TICKETLEN+AUTHENTLEN+1]; memset(&t, 0, sizeof(t)); memmove(t.chal, tr->chal, CHALLEN); safecpy(t.cuid, tr->uid, sizeof t.cuid); safecpy(t.suid, tr->uid, sizeof t.suid); mkkey(t.key); buf[0] = AuthOK; t.num = AuthTs; convT2M(&t, buf+1, hkey); memmove(a.chal, t.chal, CHALLEN); a.num = AuthAc; a.id = 0; convA2M(&a, buf+TICKETLEN+1, t.key); if(write(1, buf, TICKETLEN+AUTHENTLEN+1) < 0) return -1; return 0; }
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; }