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