xref: /plan9/sys/src/cmd/disk/kfs/auth.c (revision d9306527b4a7229dcf0cf3c58aed36bb9da82854)
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