/* * Network listening authentication. * This and all the other network-related * code is due to Richard Miller. */ #include "all.h" #include "9p1.h" int allownone; Nvrsafe nvr; int didread; /* * create a challenge for a fid space */ void mkchallenge(Chan *cp) { int i; if(!didread && readnvram(&nvr, 0) >= 0) didread = 1; srand(truerand()); for(i = 0; i < CHALLEN; i++) cp->chal[i] = nrand(256); cp->idoffset = 0; cp->idvec = 0; } /* * match a challenge from an attach */ Nvrsafe nvr; int authorize(Chan *cp, Oldfcall *in, Oldfcall *ou) { Ticket t; Authenticator a; int x; ulong bit; if (cp == cons.srvchan) /* local channel already safe */ return 1; if(wstatallow) /* set to allow entry during boot */ return 1; if(strcmp(in->uname, "none") == 0) return allownone || cp->authed; if(in->type == Toattach9p1) return 0; if(!didread) return 0; /* decrypt and unpack ticket */ convM2T(in->ticket, &t, nvr.machkey); if(t.num != AuthTs){ print("bad AuthTs num\n"); return 0; } /* decrypt and unpack authenticator */ convM2A(in->auth, &a, t.key); if(a.num != AuthAc){ print("bad AuthAc num\n"); return 0; } /* challenges must match */ if(memcmp(a.chal, cp->chal, sizeof(a.chal)) != 0){ print("bad challenge\n"); return 0; } /* * the id must be in a valid range. the range is specified by a * lower bount (idoffset) and a bit vector (idvec) where a * bit set to 1 means unusable */ lock(&cp->idlock); x = a.id - cp->idoffset; bit = 1< 31 || (bit&cp->idvec)){ unlock(&cp->idlock); return 0; } cp->idvec |= bit; /* normalize the vector */ while(cp->idvec&0xffff0001){ cp->idvec >>= 1; cp->idoffset++; } unlock(&cp->idlock); /* ticket name and attach name must match */ if(memcmp(in->uname, t.cuid, sizeof(in->uname)) != 0){ print("names don't match\n"); return 0; } /* copy translated name into input record */ memmove(in->uname, t.suid, sizeof(in->uname)); /* craft a reply */ a.num = AuthAs; memmove(a.chal, cp->rchal, CHALLEN); convA2M(&a, ou->rauth, t.key); cp->authed = 1; return 1; }