7 static int gotnvr; /* flag: nvr contains nvram; it could be bad */
16 * we shouldn't be writing nvram any more.
17 * the secstore/config field is now just secstore key.
18 * we still use authid, authdom and machkey for authentication.
26 if (readnvram(&nvr, NVread) < 0) {
27 print("nvrcheck: can't read nvram\n");
33 csum = nvcsum(nvr.machkey, sizeof nvr.machkey);
34 if(csum != nvr.machsum) {
35 print("\n\n ** NVR key checksum is incorrect **\n");
36 print(" ** set password to allow attaches **\n\n");
37 memset(nvr.machkey, 0, sizeof nvr.machkey);
45 nvrsetconfig(char* word)
47 /* config block is on device `word' */
56 char nkey1[DESKEYLEN];
57 static char zeroes[DESKEYLEN];
59 if(memcmp(nvr.machkey, zeroes, DESKEYLEN) == 0) {
60 print("no password set\n");
65 print("%s password:", service);
66 /* could turn off echo here */
68 if ((ln = Brdline(&bin, '\n')) == nil)
70 ln[Blinelen(&bin)-1] = '\0';
72 /* could turn on echo here */
73 memset(nkey1, 0, DESKEYLEN);
75 if(memcmp(nkey1, nvr.machkey, DESKEYLEN) == 0) {
80 print("Bad password\n");
87 * authentication specific to 9P2000
90 /* authentication states */
105 [HaveProtos] "HaveProtos",
106 [NeedProto] "NeedProto",
108 [NeedCchal] "NeedCchal",
109 [HaveSinfo] "HaveSinfo",
110 [NeedTicket] "NeedTicket",
111 [HaveSauthenticator] "HaveSauthenticator",
112 [SSuccess] "SSuccess",
115 /* authentication structure */
119 char uname[NAMELEN]; /* requestor's remote user name */
120 char aname[NAMELEN]; /* requested aname */
121 Userid uid; /* uid decided on */
124 char tbuf[TICKETLEN+AUTHENTLEN]; /* server ticket */
135 auths = malloc(conf.nauth * sizeof(*auths));
139 failure(Auth *s, char *why)
143 if(*why)print("authentication failed: %s: %s\n", phasename[s->phase], why);
144 srand((uintptr)s + time(nil));
145 for(i = 0; i < CHALLEN; i++)
146 s->tr.chal[i] = nrand(256);
148 strncpy(s->tr.authid, nvr.authid, NAMELEN);
149 strncpy(s->tr.authdom, nvr.authdom, DOMLEN);
150 memmove(s->cchal, s->tr.chal, sizeof(s->cchal));
151 s->phase = HaveProtos;
156 authnew(char *uname, char *aname)
165 if(i < 0 || i >= conf.nauth){
176 strncpy(s->uname, uname, NAMELEN-1);
177 strncpy(s->aname, aname, NAMELEN-1);
196 authread(File* file, uchar* data, int n)
207 return failure(s, "unexpected phase");
209 m = snprint((char*)data, n, "v.2 p9sk1@%s", nvr.authdom) + 1;
210 s->phase = NeedProto;
215 return failure(s, "read too short");
216 strcpy((char*)data, "OK");
217 s->phase = NeedCchal;
222 return failure(s, "read too short");
223 convTR2M(&s->tr, (char*)data);
224 s->phase = NeedTicket;
226 case HaveSauthenticator:
229 return failure(s, "read too short");
230 memmove(data, s->tbuf+TICKETLEN, m);
238 authwrite(File* file, uchar *data, int n)
251 return failure(s, "unknown phase");
255 return failure(s, "proto missing terminator");
258 return failure(s, "proto missing separator");
260 if(strcmp(p, "p9sk1") != 0)
261 return failure(s, "unknown proto");
262 if(strcmp(d, nvr.authdom) != 0)
263 return failure(s, "unknown domain");
270 return failure(s, "client challenge too short");
271 memmove(s->cchal, data, sizeof(s->cchal));
272 s->phase = HaveSinfo;
275 m = TICKETLEN+AUTHENTLEN;
277 return failure(s, "ticket+auth too short");
279 convM2T((char*)data, &s->t, nvr.machkey);
280 if(s->t.num != AuthTs
281 || memcmp(s->t.chal, s->tr.chal, sizeof(s->t.chal)) != 0)
282 return failure(s, "bad ticket");
284 convM2A((char*)data+TICKETLEN, &a, s->t.key);
286 || memcmp(a.chal, s->tr.chal, sizeof(a.chal)) != 0
288 return failure(s, "bad authenticator");
290 /* at this point, we're convinced */
291 s->uid = strtouid(s->t.suid);
293 return failure(s, "unknown user");
294 if(cons.flags & authdebugflag)
295 print("user %s = %d authenticated\n",
298 /* create an authenticator to send back */
300 memmove(a.chal, s->cchal, sizeof(a.chal));
302 convA2M(&a, s->tbuf+TICKETLEN, s->t.key);
304 s->phase = HaveSauthenticator;