1 /* 2 * Network listening authentication. 3 * This and all the other network-related 4 * code is due to Richard Miller. 5 */ 6 #include "all.h" 7 #include "9p1.h" 8 9 int allownone; 10 Nvrsafe nvr; 11 int didread; 12 13 /* 14 * create a challenge for a fid space 15 */ 16 void 17 mkchallenge(Chan *cp) 18 { 19 int i; 20 21 if(!didread && readnvram(&nvr, 0) >= 0) 22 didread = 1; 23 24 srand(truerand()); 25 for(i = 0; i < CHALLEN; i++) 26 cp->chal[i] = nrand(256); 27 28 cp->idoffset = 0; 29 cp->idvec = 0; 30 } 31 32 /* 33 * match a challenge from an attach 34 */ 35 Nvrsafe nvr; 36 37 int 38 authorize(Chan *cp, Oldfcall *in, Oldfcall *ou) 39 { 40 Ticket t; 41 Authenticator a; 42 int x; 43 ulong bit; 44 45 if (cp == cons.srvchan) /* local channel already safe */ 46 return 1; 47 48 if(wstatallow) /* set to allow entry during boot */ 49 return 1; 50 51 if(strcmp(in->uname, "none") == 0) 52 return allownone || cp->authed; 53 54 if(in->type == Toattach9p1) 55 return 0; 56 57 if(!didread) 58 return 0; 59 60 /* decrypt and unpack ticket */ 61 convM2T(in->ticket, &t, nvr.machkey); 62 if(t.num != AuthTs){ 63 print("bad AuthTs num\n"); 64 return 0; 65 } 66 67 /* decrypt and unpack authenticator */ 68 convM2A(in->auth, &a, t.key); 69 if(a.num != AuthAc){ 70 print("bad AuthAc num\n"); 71 return 0; 72 } 73 74 /* challenges must match */ 75 if(memcmp(a.chal, cp->chal, sizeof(a.chal)) != 0){ 76 print("bad challenge\n"); 77 return 0; 78 } 79 80 /* 81 * the id must be in a valid range. the range is specified by a 82 * lower bount (idoffset) and a bit vector (idvec) where a 83 * bit set to 1 means unusable 84 */ 85 lock(&cp->idlock); 86 x = a.id - cp->idoffset; 87 bit = 1<<x; 88 if(x < 0 || x > 31 || (bit&cp->idvec)){ 89 unlock(&cp->idlock); 90 return 0; 91 } 92 cp->idvec |= bit; 93 94 /* normalize the vector */ 95 while(cp->idvec&0xffff0001){ 96 cp->idvec >>= 1; 97 cp->idoffset++; 98 } 99 unlock(&cp->idlock); 100 101 /* ticket name and attach name must match */ 102 if(memcmp(in->uname, t.cuid, sizeof(in->uname)) != 0){ 103 print("names don't match\n"); 104 return 0; 105 } 106 107 /* copy translated name into input record */ 108 memmove(in->uname, t.suid, sizeof(in->uname)); 109 110 /* craft a reply */ 111 a.num = AuthAs; 112 memmove(a.chal, cp->rchal, CHALLEN); 113 convA2M(&a, ou->rauth, t.key); 114 115 cp->authed = 1; 116 return 1; 117 } 118