Blame


1 6e527fbc 2005-02-13 devnull #include "std.h"
2 6e527fbc 2005-02-13 devnull #include "dat.h"
3 6e527fbc 2005-02-13 devnull
4 6e527fbc 2005-02-13 devnull /*
5 6e527fbc 2005-02-13 devnull * p9any - protocol negotiator
6 6e527fbc 2005-02-13 devnull *
7 6e527fbc 2005-02-13 devnull * Protocol:
8 6e527fbc 2005-02-13 devnull * S->C: v.2 proto@dom proto@dom proto@dom... NUL
9 6e527fbc 2005-02-13 devnull * C->S: proto dom NUL
10 6e527fbc 2005-02-13 devnull * [negotiated proto continues]
11 6e527fbc 2005-02-13 devnull */
12 6e527fbc 2005-02-13 devnull
13 6e527fbc 2005-02-13 devnull extern Proto p9sk1, p9sk2, p9cr;
14 6e527fbc 2005-02-13 devnull
15 6e527fbc 2005-02-13 devnull static Proto* okproto[] =
16 6e527fbc 2005-02-13 devnull {
17 6e527fbc 2005-02-13 devnull &p9sk1,
18 cbeb0b26 2006-04-01 devnull nil
19 6e527fbc 2005-02-13 devnull };
20 6e527fbc 2005-02-13 devnull
21 6e527fbc 2005-02-13 devnull static int
22 6e527fbc 2005-02-13 devnull rolecall(Role *r, char *name, Conv *c)
23 6e527fbc 2005-02-13 devnull {
24 6e527fbc 2005-02-13 devnull for(; r->name; r++)
25 6e527fbc 2005-02-13 devnull if(strcmp(r->name, name) == 0)
26 6e527fbc 2005-02-13 devnull return (*r->fn)(c);
27 6e527fbc 2005-02-13 devnull werrstr("unknown role");
28 6e527fbc 2005-02-13 devnull return -1;
29 6e527fbc 2005-02-13 devnull }
30 6e527fbc 2005-02-13 devnull
31 6e527fbc 2005-02-13 devnull static int
32 6e527fbc 2005-02-13 devnull hasnul(void *v, int n)
33 6e527fbc 2005-02-13 devnull {
34 6e527fbc 2005-02-13 devnull char *c;
35 6e527fbc 2005-02-13 devnull
36 6e527fbc 2005-02-13 devnull c = v;
37 6e527fbc 2005-02-13 devnull if(n > 0 && c[n-1] == '\0')
38 6e527fbc 2005-02-13 devnull return n;
39 6e527fbc 2005-02-13 devnull else
40 6e527fbc 2005-02-13 devnull return AuthRpcMax;
41 6e527fbc 2005-02-13 devnull }
42 6e527fbc 2005-02-13 devnull
43 6e527fbc 2005-02-13 devnull static int
44 6e527fbc 2005-02-13 devnull p9anyserver(Conv *c)
45 6e527fbc 2005-02-13 devnull {
46 6e527fbc 2005-02-13 devnull char *s, *dom;
47 6e527fbc 2005-02-13 devnull int i, j, n, m, ret;
48 6e527fbc 2005-02-13 devnull char *tok[3];
49 6e527fbc 2005-02-13 devnull Attr *attr;
50 6e527fbc 2005-02-13 devnull Key *k;
51 6e527fbc 2005-02-13 devnull
52 6e527fbc 2005-02-13 devnull ret = -1;
53 6e527fbc 2005-02-13 devnull s = estrdup("v.2");
54 6e527fbc 2005-02-13 devnull n = 0;
55 6e527fbc 2005-02-13 devnull attr = delattr(copyattr(c->attr), "proto");
56 6e527fbc 2005-02-13 devnull
57 6e527fbc 2005-02-13 devnull for(i=0; i<ring.nkey; i++){
58 6e527fbc 2005-02-13 devnull k = ring.key[i];
59 6e527fbc 2005-02-13 devnull for(j=0; okproto[j]; j++)
60 6e527fbc 2005-02-13 devnull if(k->proto == okproto[j]
61 6e527fbc 2005-02-13 devnull && (dom = strfindattr(k->attr, "dom")) != nil
62 6e527fbc 2005-02-13 devnull && matchattr(attr, k->attr, k->privattr)){
63 6e527fbc 2005-02-13 devnull s = estrappend(s, " %s@%s", k->proto->name, dom);
64 6e527fbc 2005-02-13 devnull n++;
65 6e527fbc 2005-02-13 devnull }
66 6e527fbc 2005-02-13 devnull }
67 6e527fbc 2005-02-13 devnull
68 6e527fbc 2005-02-13 devnull if(n == 0){
69 6e527fbc 2005-02-13 devnull werrstr("no valid keys");
70 6e527fbc 2005-02-13 devnull goto out;
71 6e527fbc 2005-02-13 devnull }
72 6e527fbc 2005-02-13 devnull
73 6e527fbc 2005-02-13 devnull c->state = "write offer";
74 6e527fbc 2005-02-13 devnull if(convwrite(c, s, strlen(s)+1) < 0)
75 6e527fbc 2005-02-13 devnull goto out;
76 6e527fbc 2005-02-13 devnull free(s);
77 6e527fbc 2005-02-13 devnull s = nil;
78 6e527fbc 2005-02-13 devnull
79 6e527fbc 2005-02-13 devnull c->state = "read choice";
80 6e527fbc 2005-02-13 devnull if(convreadfn(c, hasnul, &s) < 0)
81 6e527fbc 2005-02-13 devnull goto out;
82 6e527fbc 2005-02-13 devnull
83 6e527fbc 2005-02-13 devnull m = tokenize(s, tok, nelem(tok));
84 6e527fbc 2005-02-13 devnull if(m != 2){
85 6e527fbc 2005-02-13 devnull werrstr("bad protocol message");
86 6e527fbc 2005-02-13 devnull goto out;
87 6e527fbc 2005-02-13 devnull }
88 6e527fbc 2005-02-13 devnull
89 6e527fbc 2005-02-13 devnull for(i=0; okproto[i]; i++)
90 6e527fbc 2005-02-13 devnull if(strcmp(okproto[i]->name, tok[0]) == 0)
91 6e527fbc 2005-02-13 devnull break;
92 6e527fbc 2005-02-13 devnull if(!okproto[i]){
93 6e527fbc 2005-02-13 devnull werrstr("bad chosen protocol %q", tok[0]);
94 6e527fbc 2005-02-13 devnull goto out;
95 6e527fbc 2005-02-13 devnull }
96 6e527fbc 2005-02-13 devnull
97 6e527fbc 2005-02-13 devnull c->state = "write ok";
98 6e527fbc 2005-02-13 devnull if(convwrite(c, "OK\0", 3) < 0)
99 6e527fbc 2005-02-13 devnull goto out;
100 6e527fbc 2005-02-13 devnull
101 6e527fbc 2005-02-13 devnull c->state = "start choice";
102 6e527fbc 2005-02-13 devnull attr = addattr(attr, "proto=%q dom=%q", tok[0], tok[1]);
103 6e527fbc 2005-02-13 devnull free(c->attr);
104 6e527fbc 2005-02-13 devnull c->attr = attr;
105 6e527fbc 2005-02-13 devnull attr = nil;
106 6e527fbc 2005-02-13 devnull c->proto = okproto[i];
107 6e527fbc 2005-02-13 devnull
108 6e527fbc 2005-02-13 devnull if(rolecall(c->proto->roles, "server", c) < 0){
109 6e527fbc 2005-02-13 devnull werrstr("%s: %r", tok[0]);
110 6e527fbc 2005-02-13 devnull goto out;
111 6e527fbc 2005-02-13 devnull }
112 6e527fbc 2005-02-13 devnull
113 6e527fbc 2005-02-13 devnull ret = 0;
114 6e527fbc 2005-02-13 devnull
115 6e527fbc 2005-02-13 devnull out:
116 6e527fbc 2005-02-13 devnull free(s);
117 6e527fbc 2005-02-13 devnull freeattr(attr);
118 6e527fbc 2005-02-13 devnull return ret;
119 6e527fbc 2005-02-13 devnull }
120 6e527fbc 2005-02-13 devnull
121 6e527fbc 2005-02-13 devnull static int
122 6e527fbc 2005-02-13 devnull p9anyclient(Conv *c)
123 6e527fbc 2005-02-13 devnull {
124 6e527fbc 2005-02-13 devnull char *s, **f, *tok[20], ok[3], *q, *user, *dom, *choice;
125 6e527fbc 2005-02-13 devnull int i, n, ret, version;
126 6e527fbc 2005-02-13 devnull Key *k;
127 6e527fbc 2005-02-13 devnull Attr *attr;
128 6e527fbc 2005-02-13 devnull Proto *p;
129 6e527fbc 2005-02-13 devnull
130 6e527fbc 2005-02-13 devnull ret = -1;
131 6e527fbc 2005-02-13 devnull s = nil;
132 6e527fbc 2005-02-13 devnull k = nil;
133 6e527fbc 2005-02-13 devnull
134 6e527fbc 2005-02-13 devnull user = strfindattr(c->attr, "user");
135 6e527fbc 2005-02-13 devnull dom = strfindattr(c->attr, "dom");
136 6e527fbc 2005-02-13 devnull
137 6e527fbc 2005-02-13 devnull /*
138 6e527fbc 2005-02-13 devnull * if the user is the factotum owner, any key will do.
139 6e527fbc 2005-02-13 devnull * if not, then if we have a speakfor key,
140 6e527fbc 2005-02-13 devnull * we will only vouch for the user's local identity.
141 6e527fbc 2005-02-13 devnull *
142 6e527fbc 2005-02-13 devnull * this logic is duplicated in p9sk1.c
143 6e527fbc 2005-02-13 devnull */
144 6e527fbc 2005-02-13 devnull attr = delattr(copyattr(c->attr), "role");
145 6e527fbc 2005-02-13 devnull attr = delattr(attr, "proto");
146 6e527fbc 2005-02-13 devnull if(strcmp(c->sysuser, owner) == 0)
147 6e527fbc 2005-02-13 devnull attr = addattr(attr, "role=client");
148 6e527fbc 2005-02-13 devnull else if(user==nil || strcmp(c->sysuser, user)==0){
149 6e527fbc 2005-02-13 devnull attr = delattr(attr, "user");
150 6e527fbc 2005-02-13 devnull attr = addattr(attr, "role=speakfor");
151 6e527fbc 2005-02-13 devnull }else{
152 6e527fbc 2005-02-13 devnull werrstr("will not authenticate for %q as %q", c->sysuser, user);
153 6e527fbc 2005-02-13 devnull goto out;
154 6e527fbc 2005-02-13 devnull }
155 6e527fbc 2005-02-13 devnull
156 6e527fbc 2005-02-13 devnull c->state = "read offer";
157 6e527fbc 2005-02-13 devnull if(convreadfn(c, hasnul, &s) < 0)
158 6e527fbc 2005-02-13 devnull goto out;
159 6e527fbc 2005-02-13 devnull
160 6e527fbc 2005-02-13 devnull c->state = "look for keys";
161 6e527fbc 2005-02-13 devnull n = tokenize(s, tok, nelem(tok));
162 6e527fbc 2005-02-13 devnull f = tok;
163 6e527fbc 2005-02-13 devnull version = 1;
164 6e527fbc 2005-02-13 devnull if(n > 0 && memcmp(f[0], "v.", 2) == 0){
165 6e527fbc 2005-02-13 devnull version = atoi(f[0]+2);
166 6e527fbc 2005-02-13 devnull if(version != 2){
167 6e527fbc 2005-02-13 devnull werrstr("unknown p9any version: %s", f[0]);
168 6e527fbc 2005-02-13 devnull goto out;
169 6e527fbc 2005-02-13 devnull }
170 6e527fbc 2005-02-13 devnull f++;
171 6e527fbc 2005-02-13 devnull n--;
172 6e527fbc 2005-02-13 devnull }
173 6e527fbc 2005-02-13 devnull
174 6e527fbc 2005-02-13 devnull /* look for keys that don't need confirmation */
175 6e527fbc 2005-02-13 devnull for(i=0; i<n; i++){
176 6e527fbc 2005-02-13 devnull if((q = strchr(f[i], '@')) == nil)
177 6e527fbc 2005-02-13 devnull continue;
178 6e527fbc 2005-02-13 devnull if(dom && strcmp(q+1, dom) != 0)
179 6e527fbc 2005-02-13 devnull continue;
180 6e527fbc 2005-02-13 devnull *q++ = '\0';
181 6e527fbc 2005-02-13 devnull if((k = keylookup("%A proto=%q dom=%q", attr, f[i], q))
182 6e527fbc 2005-02-13 devnull && strfindattr(k->attr, "confirm") == nil)
183 6e527fbc 2005-02-13 devnull goto found;
184 6e527fbc 2005-02-13 devnull *--q = '@';
185 6e527fbc 2005-02-13 devnull }
186 6e527fbc 2005-02-13 devnull
187 6e527fbc 2005-02-13 devnull /* look for any keys at all */
188 6e527fbc 2005-02-13 devnull for(i=0; i<n; i++){
189 6e527fbc 2005-02-13 devnull if((q = strchr(f[i], '@')) == nil)
190 6e527fbc 2005-02-13 devnull continue;
191 6e527fbc 2005-02-13 devnull if(dom && strcmp(q+1, dom) != 0)
192 6e527fbc 2005-02-13 devnull continue;
193 6e527fbc 2005-02-13 devnull *q++ = '\0';
194 6e527fbc 2005-02-13 devnull if(k = keylookup("%A proto=%q dom=%q", attr, f[i], q))
195 6e527fbc 2005-02-13 devnull goto found;
196 6e527fbc 2005-02-13 devnull *--q = '@';
197 6e527fbc 2005-02-13 devnull }
198 6e527fbc 2005-02-13 devnull
199 6e527fbc 2005-02-13 devnull /* ask for new keys */
200 6e527fbc 2005-02-13 devnull c->state = "ask for keys";
201 6e527fbc 2005-02-13 devnull for(i=0; i<n; i++){
202 6e527fbc 2005-02-13 devnull if((q = strchr(f[i], '@')) == nil)
203 6e527fbc 2005-02-13 devnull continue;
204 6e527fbc 2005-02-13 devnull if(dom && strcmp(q+1, dom) != 0)
205 6e527fbc 2005-02-13 devnull continue;
206 6e527fbc 2005-02-13 devnull *q++ = '\0';
207 6e527fbc 2005-02-13 devnull p = protolookup(f[i]);
208 6e527fbc 2005-02-13 devnull if(p == nil || p->keyprompt == nil){
209 6e527fbc 2005-02-13 devnull *--q = '@';
210 6e527fbc 2005-02-13 devnull continue;
211 6e527fbc 2005-02-13 devnull }
212 6e527fbc 2005-02-13 devnull if(k = keyfetch(c, "%A proto=%q dom=%q %s", attr, f[i], q, p->keyprompt))
213 6e527fbc 2005-02-13 devnull goto found;
214 6e527fbc 2005-02-13 devnull *--q = '@';
215 6e527fbc 2005-02-13 devnull }
216 6e527fbc 2005-02-13 devnull
217 6e527fbc 2005-02-13 devnull /* nothing worked */
218 6e527fbc 2005-02-13 devnull werrstr("unable to find common key");
219 6e527fbc 2005-02-13 devnull goto out;
220 6e527fbc 2005-02-13 devnull
221 6e527fbc 2005-02-13 devnull found:
222 6e527fbc 2005-02-13 devnull /* f[i] is the chosen protocol, q the chosen domain */
223 6e527fbc 2005-02-13 devnull attr = addattr(attr, "proto=%q dom=%q", f[i], q);
224 6e527fbc 2005-02-13 devnull c->state = "write choice";
225 6e527fbc 2005-02-13 devnull
226 6e527fbc 2005-02-13 devnull /* have a key: go for it */
227 6e527fbc 2005-02-13 devnull choice = estrappend(nil, "%q %q", f[i], q);
228 6e527fbc 2005-02-13 devnull if(convwrite(c, choice, strlen(choice)+1) < 0){
229 6e527fbc 2005-02-13 devnull free(choice);
230 6e527fbc 2005-02-13 devnull goto out;
231 6e527fbc 2005-02-13 devnull }
232 6e527fbc 2005-02-13 devnull free(choice);
233 6e527fbc 2005-02-13 devnull
234 6e527fbc 2005-02-13 devnull if(version == 2){
235 6e527fbc 2005-02-13 devnull c->state = "read ok";
236 6e527fbc 2005-02-13 devnull if(convread(c, ok, 3) < 0 || memcmp(ok, "OK\0", 3) != 0)
237 6e527fbc 2005-02-13 devnull goto out;
238 6e527fbc 2005-02-13 devnull }
239 6e527fbc 2005-02-13 devnull
240 6e527fbc 2005-02-13 devnull c->state = "start choice";
241 6e527fbc 2005-02-13 devnull c->proto = protolookup(f[i]);
242 6e527fbc 2005-02-13 devnull freeattr(c->attr);
243 6e527fbc 2005-02-13 devnull c->attr = attr;
244 6e527fbc 2005-02-13 devnull attr = nil;
245 6e527fbc 2005-02-13 devnull
246 6e527fbc 2005-02-13 devnull if(rolecall(c->proto->roles, "client", c) < 0){
247 6e527fbc 2005-02-13 devnull werrstr("%s: %r", c->proto->name);
248 6e527fbc 2005-02-13 devnull goto out;
249 6e527fbc 2005-02-13 devnull }
250 6e527fbc 2005-02-13 devnull
251 6e527fbc 2005-02-13 devnull ret = 0;
252 6e527fbc 2005-02-13 devnull
253 6e527fbc 2005-02-13 devnull out:
254 6e527fbc 2005-02-13 devnull keyclose(k);
255 6e527fbc 2005-02-13 devnull freeattr(attr);
256 6e527fbc 2005-02-13 devnull free(s);
257 6e527fbc 2005-02-13 devnull return ret;
258 6e527fbc 2005-02-13 devnull }
259 6e527fbc 2005-02-13 devnull
260 6e527fbc 2005-02-13 devnull static Role
261 6e527fbc 2005-02-13 devnull p9anyroles[] =
262 6e527fbc 2005-02-13 devnull {
263 6e527fbc 2005-02-13 devnull "client", p9anyclient,
264 6e527fbc 2005-02-13 devnull "server", p9anyserver,
265 6e527fbc 2005-02-13 devnull 0
266 6e527fbc 2005-02-13 devnull };
267 6e527fbc 2005-02-13 devnull
268 6e527fbc 2005-02-13 devnull Proto p9any = {
269 b3e7c026 2005-03-15 devnull "p9any",
270 cbeb0b26 2006-04-01 devnull p9anyroles
271 6e527fbc 2005-02-13 devnull };
272 6e527fbc 2005-02-13 devnull