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
mkchallenge(Chan * cp)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
authorize(Chan * cp,Oldfcall * in,Oldfcall * ou)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