ref: dfaaee1464be873eea263b02c90a3b05605e6fa8
dir: /auth.c/
#include <u.h> #include <libc.h> #include <auth.h> #include <fcall.h> #include <authsrv.h> #include <libsec.h> #include "drawcpu.h" char *authserver; // Likely unused AuthInfo* establish(Ticket *t, uchar *rand, int dp9ik) { AuthInfo *ai; ai = mallocz(sizeof(AuthInfo), 1); ai->suid = t->suid; ai->cuid = t->cuid; if(dp9ik){ static char info[] = "Plan 9 session secret"; ai->nsecret = 256; ai->secret = mallocz(ai->nsecret, 1); hkdf_x(rand, 2*NONCELEN, (uchar*)info, sizeof(info)-1, (uchar*)t->key, NONCELEN, ai->secret, ai->nsecret, hmac_sha2_256, SHA2_256dlen ); } else { ai->nsecret = 8; ai->secret = mallocz(ai->nsecret, 1); des56to64((uchar*)t->key, ai->secret); } return ai; } AuthInfo* auth_host(int fd, char *authdom, char *pass) { char *user; char cpd[ANAMELEN+DOMLEN+1], spd[2*DOMLEN+18], *proto, *dom; char trbuf[TICKREQLEN+PAKYLEN], abuf[MAXTICKETLEN+MAXAUTHENTLEN]; uchar srand[2*NONCELEN], cchal[CHALLEN], y[PAKYLEN]; Authkey key; Authenticator auth; AuthInfo *ai; PAKpriv p; Ticketreq tr; Ticket t; int afd; if((afd = open("/mnt/factotum/ctl", ORDWR)) >= 0) return auth_proxy(0, nil, "proto=p9any role=server"); int n, m, dp9ik = 0; /* Start p9any */ #if P9ANY_VERSION==2 n = sprintf(spd, "v.2 p9sk1@%s dp9ik@%s ", authdom, authdom); #else n = sprintf(spd, "p9sk1@%s dp9ik@%s ", authdom, authdom); #endif if(write(fd, spd, n+1) != n+1){ fprint(dbg, "short write on p9any\n"); return nil; } if(read(fd, cpd, ANAMELEN+DOMLEN+1) <= 0){ fprint(dbg, "short read on client proto\n"); return nil; } proto = strtok(cpd, " "); dom = strtok(NULL, " "); if(proto == NULL || dom == NULL){ fprint(dbg, "unable to read requested proto/dom pair\n"); return nil; } if(strcmp(proto, "dp9ik") == 0) dp9ik = 1; #if P9ANY_VERSION==2 if(write(fd, "OK\0", 3) != 3){ fprint(dbg, "short write on proto challenge OK"); return nil; } #endif /* p9any success, start selected protocol */ user = getenv("USER"); memset(&tr, 0, sizeof(tr)); tr.type = AuthTreq; strcpy(tr.authid, user); strcpy(tr.authdom, authdom); genrandom((uchar*)tr.chal, CHALLEN); if((n = readn(fd, cchal, CHALLEN)) != CHALLEN){ fprint(dbg, "Short read on p9sk1 challenge\n"); return nil; } m = TICKREQLEN; passtokey(&key, pass); if(dp9ik){ authpak_hash(&key, user); tr.type = AuthPAK; m += PAKYLEN; } n = convTR2M(&tr, trbuf, m); if(dp9ik) authpak_new(&p, &key, (uchar *)trbuf+n, 1); //print(trbuf); if(write(fd, trbuf, m) < m){ fprint(dbg, "short read sending ticket request\n"); return nil; } if(dp9ik){ if(readn(fd, y, PAKYLEN) < PAKYLEN){ fprint(dbg, "short read on client pk"); return nil; } if(authpak_finish(&p, &key, y)){ fprint(dbg, "unable to decrypt message in auth_host\n"); return nil; } } if((n = readn(fd, abuf, MAXTICKETLEN+MAXAUTHENTLEN)) != MAXTICKETLEN+MAXAUTHENTLEN){ fprint(dbg, "short read receiving ticket\n"); return nil; } m = convM2T(abuf, n, &t, &key); if(m <= 0 || convM2A(abuf+m, n-m, &auth, &t) <= 0){ fprint(dbg, "short read on ticket\n"); return nil; } if(dp9ik && t.form == 0){ fprint(dbg, "auth_host: auth protocol botch"); return nil; } if(t.num != AuthTs || tsmemcmp(t.chal, tr.chal, CHALLEN) != 0){ fprint(dbg, "auth protocol botch\n"); return nil; } if(auth.num != AuthAc || tsmemcmp(auth.chal, tr.chal, CHALLEN) != 0){ fprint(dbg, "auth portocol botch"); return nil; } memmove(srand, auth.rand, NONCELEN); genrandom(srand + NONCELEN, NONCELEN); auth.num = AuthAs; memmove(auth.chal, cchal, CHALLEN); memmove(auth.rand, srand + NONCELEN, NONCELEN); if((n = convA2M(&auth, abuf, sizeof(abuf), &t)) < 0){ fprint(dbg, "unable to convert authenticator to message\n"); return nil; } if(write(fd, abuf, n) != n){ fprint(dbg, "short write sending authenticator\n"); return nil; } ai = establish(&t, srand, dp9ik); memset(&key, 0, sizeof(key)); memset(&t, 0, sizeof(t)); memset(&auth, 0, sizeof(auth)); return ai; } int p9authsrv(char *authdom, char *pass) { AuthInfo *ai; TLSconn *conn; int fd = open("/dev/cons", O_RDWR); ai = auth_host(fd, authdom, pass); if(ai == nil){ fprint(dbg, "can't authenticate: %r\n"); return -1; } conn = mallocz(sizeof(TLSconn), 1); conn->pskID = "p9secret"; conn->psk = ai->secret; conn->psklen = ai->nsecret; fd = tlsServer(fd, conn); if(fd < 0){ fprint(dbg, "tlsServer: %r\n"); return -1; } auth_freeAI(ai); free(conn->sessionID); free(conn); return fd; }