From 0f8ec41b0ae522b73085fa1662461e6351ba7e54 Mon Sep 17 00:00:00 2001 From: rsc Date: Sun, 13 Feb 2005 05:58:45 +0000 Subject: moving to auth --- src/cmd/factotum/p9cr.c | 545 ------------------------------------------------ 1 file changed, 545 deletions(-) delete mode 100644 src/cmd/factotum/p9cr.c (limited to 'src/cmd/factotum/p9cr.c') diff --git a/src/cmd/factotum/p9cr.c b/src/cmd/factotum/p9cr.c deleted file mode 100644 index 7f53e447..00000000 --- a/src/cmd/factotum/p9cr.c +++ /dev/null @@ -1,545 +0,0 @@ -/* - * p9cr, vnc - one-sided challenge/response authentication - * - * Protocol: - * - * C -> S: user - * S -> C: challenge - * C -> S: response - * S -> C: ok or bad - * - * Note that this is the protocol between factotum and the local - * program, not between the two factotums. The information - * exchanged here is wrapped in other protocols by the local - * programs. - */ - -#include "std.h" -#include "dat.h" - -static int -p9crcheck(Key *k) -{ - if(!strfindattr(k->attr, "user") || !strfindattr(k->privattr, "!password")){ - werrstr("need user and !password attributes"); - return -1; - } - return 0; -} - -static int -p9crclient(Conv *c) -{ - char *chal, *pw, *res, *user; - int astype, nchal, npw, ntry, ret; - uchar resp[MD5dlen]; - Attr *attr; - DigestState *ds; - Key *k; - - chal = nil; - k = nil; - res = nil; - ret = -1; - attr = c->attr; - - if(c->proto == &p9cr){ - astype = AuthChal; - challen = NETCHLEN; - }else if(c->proto == &vnc){ - astype = AuthVnc; - challen = MAXCHAL; - }else{ - werrstr("bad proto"); - goto out; - } - - c->state = "find key"; - k = keyfetch(c, "%A %s", attr, c->proto->keyprompt); - if(k == nil) - goto out; - - for(ntry=1;; ntry++){ - if(c->attr != attr) - freeattr(c->attr); - c->attr = addattrs(copyattr(attr), k->attr); - if((pw = strfindattr(k->privattr, "!password")) == nil){ - werrstr("key has no !password (cannot happen)"); - goto out; - } - npw = strlen(pw); - - if((user = strfindattr(k->attr, "user")) == nil){ - werrstr("key has no user (cannot happen)"); - goto out; - } - - if(convprint(c, "%s", user) < 0) - goto out; - - if(convreadm(c, &chal) < 0) - goto out; - - if((nresp = (*response)(chal, resp)) < 0) - goto out; - - if(convwrite(c, resp, nresp) < 0) - goto out; - - if(convreadm(c, &res) < 0) - goto out; - - if(strcmp(res, "ok") == 0) - break; - - if((k = keyreplace(c, k, "%s", res)) == nil){ - c->state = "auth failed"; - werrstr("%s", res); - goto out; - } - } - - werrstr("succeeded"); - ret = 0; - -out: - keyclose(k); - free(chal); - if(c->attr != attr) - freeattr(attr); - return ret; -} - -static int -p9crserver(Conv *c) -{ - char chal[APOPCHALLEN], *user, *resp; - ServerState s; - int astype, ret; - Attr *a; - - ret = -1; - user = nil; - resp = nil; - memset(&s, 0, sizeof s); - s.asfd = -1; - - if(c->proto == &apop) - astype = AuthApop; - else if(c->proto == &cram) - astype = AuthCram; - else{ - werrstr("bad proto"); - goto out; - } - - c->state = "find key"; - if((s.k = plan9authkey(c->attr)) == nil) - goto out; - - a = copyattr(s.k->attr); - a = delattr(a, "proto"); - c->attr = addattrs(c->attr, a); - freeattr(a); - - c->state = "authdial"; - s.hostid = strfindattr(s.k->attr, "user"); - s.dom = strfindattr(s.k->attr, "dom"); - if((s.asfd = xioauthdial(nil, s.dom)) < 0){ - werrstr("authdial %s: %r", s.dom); - goto out; - } - - c->state = "authchal"; - if(p9crchal(&s, astype, chal) < 0) - goto out; - - c->state = "write challenge"; - if(convprint(c, "%s", chal) < 0) - goto out; - - for(;;){ - c->state = "read user"; - if(convreadm(c, &user) < 0) - goto out; - - c->state = "read response"; - if(convreadm(c, &resp) < 0) - goto out; - - c->state = "authwrite"; - switch(apopresp(&s, user, resp)){ - case -1: - goto out; - case 0: - c->state = "write status"; - if(convprint(c, "bad authentication failed") < 0) - goto out; - break; - case 1: - c->state = "write status"; - if(convprint(c, "ok") < 0) - goto out; - goto ok; - } - free(user); - free(resp); - user = nil; - resp = nil; - } - -ok: - ret = 0; - c->attr = addcap(c->attr, c->sysuser, &s.t); - -out: - keyclose(s.k); - free(user); - free(resp); -// xioclose(s.asfd); - return ret; -} - -enum -{ - MAXCHAL = 64, -}; - -typedef struct State State; -struct State -{ - Key *key; - int astype; - int asfd; - Ticket t; - Ticketreq tr; - char chal[MAXCHAL]; - int challen; - char resp[MAXCHAL]; - int resplen; -}; - -enum -{ - CNeedChal, - CHaveResp, - - SHaveChal, - SNeedResp, - - Maxphase, -}; - -static char *phasenames[Maxphase] = -{ -[CNeedChal] "CNeedChal", -[CHaveResp] "CHaveResp", - -[SHaveChal] "SHaveChal", -[SNeedResp] "SNeedResp", -}; - -static void -p9crclose(Fsstate *fss) -{ - State *s; - - s = fss->ps; - if(s->asfd >= 0){ - close(s->asfd); - s->asfd = -1; - } - free(s); -} - -static int getchal(State*, Fsstate*); - -static int -p9crinit(Proto *p, Fsstate *fss) -{ - int iscli, ret; - char *user; - State *s; - Attr *attr; - - if((iscli = isclient(_str_findattr(fss->attr, "role"))) < 0) - return failure(fss, nil); - - s = emalloc(sizeof(*s)); - s->asfd = -1; - if(p == &p9cr){ - s->astype = AuthChal; - s->challen = NETCHLEN; - }else if(p == &vnc){ - s->astype = AuthVNC; - s->challen = Maxchal; - }else - abort(); - - if(iscli){ - fss->phase = CNeedChal; - if(p == &p9cr) - attr = setattr(_copyattr(fss->attr), "proto=p9sk1"); - else - attr = nil; - ret = findkey(&s->key, fss, Kuser, 0, attr ? attr : fss->attr, - "role=client %s", p->keyprompt); - _freeattr(attr); - if(ret != RpcOk){ - free(s); - return ret; - } - fss->ps = s; - }else{ - if((ret = findp9authkey(&s->key, fss)) != RpcOk){ - free(s); - return ret; - } - if((user = _str_findattr(fss->attr, "user")) == nil){ - free(s); - return failure(fss, "no user name specified in start msg"); - } - if(strlen(user) >= sizeof s->tr.uid){ - free(s); - return failure(fss, "user name too long"); - } - fss->ps = s; - strcpy(s->tr.uid, user); - ret = getchal(s, fss); - if(ret != RpcOk){ - p9crclose(fss); /* frees s */ - fss->ps = nil; - } - } - fss->phasename = phasenames; - fss->maxphase = Maxphase; - return ret; -} - -static int -p9crread(Fsstate *fss, void *va, uint *n) -{ - int m; - State *s; - - s = fss->ps; - switch(fss->phase){ - default: - return phaseerror(fss, "read"); - - case CHaveResp: - if(s->resplen < *n) - *n = s->resplen; - memmove(va, s->resp, *n); - fss->phase = Established; - return RpcOk; - - case SHaveChal: - if(s->astype == AuthChal) - m = strlen(s->chal); /* ascii string */ - else - m = s->challen; /* fixed length binary */ - if(m > *n) - return toosmall(fss, m); - *n = m; - memmove(va, s->chal, m); - fss->phase = SNeedResp; - return RpcOk; - } -} - -static int -p9response(Fsstate *fss, State *s) -{ - char key[DESKEYLEN]; - uchar buf[8]; - ulong chal; - char *pw; - - pw = _str_findattr(s->key->privattr, "!password"); - if(pw == nil) - return failure(fss, "vncresponse cannot happen"); - passtokey(key, pw); - memset(buf, 0, 8); - sprint((char*)buf, "%d", atoi(s->chal)); - if(encrypt(key, buf, 8) < 0) - return failure(fss, "can't encrypt response"); - chal = (buf[0]<<24)+(buf[1]<<16)+(buf[2]<<8)+buf[3]; - s->resplen = snprint(s->resp, sizeof s->resp, "%.8lux", chal); - return RpcOk; -} - -static uchar tab[256]; - -/* VNC reverses the bits of each byte before using as a des key */ -static void -mktab(void) -{ - int i, j, k; - static int once; - - if(once) - return; - once = 1; - - for(i=0; i<256; i++) { - j=i; - tab[i] = 0; - for(k=0; k<8; k++) { - tab[i] = (tab[i]<<1) | (j&1); - j >>= 1; - } - } -} - -static int -vncaddkey(Key *k) -{ - uchar *p; - char *s; - - k->priv = emalloc(8+1); - if(s = _str_findattr(k->privattr, "!password")){ - mktab(); - memset(k->priv, 0, 8+1); - strncpy((char*)k->priv, s, 8); - for(p=k->priv; *p; p++) - *p = tab[*p]; - }else{ - werrstr("no key data"); - return -1; - } - return replacekey(k); -} - -static void -vncclosekey(Key *k) -{ - free(k->priv); -} - -static int -vncresponse(Fsstate*, State *s) -{ - DESstate des; - - memmove(s->resp, s->chal, sizeof s->chal); - setupDESstate(&des, s->key->priv, nil); - desECBencrypt((uchar*)s->resp, s->challen, &des); - s->resplen = s->challen; - return RpcOk; -} - -static int -p9crwrite(Fsstate *fss, void *va, uint n) -{ - char tbuf[TICKETLEN+AUTHENTLEN]; - State *s; - char *data = va; - Authenticator a; - char resp[Maxchal]; - int ret; - - s = fss->ps; - switch(fss->phase){ - default: - return phaseerror(fss, "write"); - - case CNeedChal: - if(n >= sizeof(s->chal)) - return failure(fss, Ebadarg); - memset(s->chal, 0, sizeof s->chal); - memmove(s->chal, data, n); - s->challen = n; - - if(s->astype == AuthChal) - ret = p9response(fss, s); - else - ret = vncresponse(fss, s); - if(ret != RpcOk) - return ret; - fss->phase = CHaveResp; - return RpcOk; - - case SNeedResp: - /* send response to auth server and get ticket */ - if(n > sizeof(resp)) - return failure(fss, Ebadarg); - memset(resp, 0, sizeof resp); - memmove(resp, data, n); - if(write(s->asfd, resp, s->challen) != s->challen) - return failure(fss, Easproto); - - /* get ticket plus authenticator from auth server */ - if(_asrdresp(s->asfd, tbuf, TICKETLEN+AUTHENTLEN) < 0) - return failure(fss, nil); - - /* check ticket */ - convM2T(tbuf, &s->t, s->key->priv); - if(s->t.num != AuthTs - || memcmp(s->t.chal, s->tr.chal, sizeof(s->t.chal)) != 0) - return failure(fss, Easproto); - convM2A(tbuf+TICKETLEN, &a, s->t.key); - if(a.num != AuthAc - || memcmp(a.chal, s->tr.chal, sizeof(a.chal)) != 0 - || a.id != 0) - return failure(fss, Easproto); - - fss->haveai = 1; - fss->ai.cuid = s->t.cuid; - fss->ai.suid = s->t.suid; - fss->ai.nsecret = 0; - fss->ai.secret = nil; - fss->phase = Established; - return RpcOk; - } -} - -static int -getchal(State *s, Fsstate *fss) -{ - char trbuf[TICKREQLEN]; - int n; - - safecpy(s->tr.hostid, _str_findattr(s->key->attr, "user"), sizeof(s->tr.hostid)); - safecpy(s->tr.authdom, _str_findattr(s->key->attr, "dom"), sizeof(s->tr.authdom)); - s->tr.type = s->astype; - convTR2M(&s->tr, trbuf); - - /* get challenge from auth server */ - s->asfd = _authdial(nil, _str_findattr(s->key->attr, "dom")); - if(s->asfd < 0) - return failure(fss, Easproto); - if(write(s->asfd, trbuf, TICKREQLEN) != TICKREQLEN) - return failure(fss, Easproto); - n = _asrdresp(s->asfd, s->chal, s->challen); - if(n <= 0){ - if(n == 0) - werrstr("_asrdresp short read"); - return failure(fss, nil); - } - s->challen = n; - fss->phase = SHaveChal; - return RpcOk; -} - -Proto p9cr = -{ -.name= "p9cr", -.init= p9crinit, -.write= p9crwrite, -.read= p9crread, -.close= p9crclose, -.keyprompt= "user? !password?", -}; - -Proto vnc = -{ -.name= "vnc", -.init= p9crinit, -.write= p9crwrite, -.read= p9crread, -.close= p9crclose, -.keyprompt= "!password?", -.addkey= vncaddkey, -}; -- cgit v1.2.3