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 * Factotum RPC
6 6e527fbc 2005-02-13 devnull *
7 6e527fbc 2005-02-13 devnull * Must be paired write/read cycles on /mnt/factotum/rpc.
8 6e527fbc 2005-02-13 devnull * The format of a request is verb, single space, data.
9 6e527fbc 2005-02-13 devnull * Data format is verb-dependent; in particular, it can be binary.
10 6e527fbc 2005-02-13 devnull * The format of a response is the same. The write only sets up
11 6e527fbc 2005-02-13 devnull * the RPC. The read tries to execute it. If the /mnt/factotum/key
12 6e527fbc 2005-02-13 devnull * file is open, we ask for new keys using that instead of returning
13 6e527fbc 2005-02-13 devnull * an error in the RPC. This means the read blocks.
14 6e527fbc 2005-02-13 devnull * Textual arguments are parsed with tokenize, so rc-style quoting
15 6e527fbc 2005-02-13 devnull * rules apply.
16 6e527fbc 2005-02-13 devnull *
17 6e527fbc 2005-02-13 devnull * Only authentication protocol messages go here. Configuration
18 6e527fbc 2005-02-13 devnull * is still via ctl (below).
19 6e527fbc 2005-02-13 devnull *
20 6e527fbc 2005-02-13 devnull * Request RPCs are:
21 6e527fbc 2005-02-13 devnull * start attrs - initializes protocol for authentication, can fail.
22 6e527fbc 2005-02-13 devnull * returns "ok read" or "ok write" on success.
23 6e527fbc 2005-02-13 devnull * read - execute protocol read
24 6e527fbc 2005-02-13 devnull * write - execute protocol write
25 6e527fbc 2005-02-13 devnull * authinfo - if the protocol is finished, return the AI if any
26 6e527fbc 2005-02-13 devnull * attr - return protocol information
27 6e527fbc 2005-02-13 devnull * Return values are:
28 6e527fbc 2005-02-13 devnull * error message - an error happened.
29 6e527fbc 2005-02-13 devnull * ok [data] - success, possible data is request dependent.
30 6e527fbc 2005-02-13 devnull * needkey attrs - request aborted, get me this key and try again
31 6e527fbc 2005-02-13 devnull * badkey attrs - request aborted, this key might be bad
32 6e527fbc 2005-02-13 devnull * done [haveai] - authentication is done [haveai: you can get an ai with authinfo]
33 6e527fbc 2005-02-13 devnull */
34 6e527fbc 2005-02-13 devnull
35 6e527fbc 2005-02-13 devnull char *rpcname[] =
36 6e527fbc 2005-02-13 devnull {
37 6e527fbc 2005-02-13 devnull "unknown",
38 6e527fbc 2005-02-13 devnull "authinfo",
39 6e527fbc 2005-02-13 devnull "attr",
40 6e527fbc 2005-02-13 devnull "read",
41 6e527fbc 2005-02-13 devnull "start",
42 6e527fbc 2005-02-13 devnull "write",
43 ce94dbe6 2005-02-13 devnull "readhex",
44 cbeb0b26 2006-04-01 devnull "writehex"
45 6e527fbc 2005-02-13 devnull };
46 6e527fbc 2005-02-13 devnull
47 6e527fbc 2005-02-13 devnull static int
48 6e527fbc 2005-02-13 devnull classify(char *s)
49 6e527fbc 2005-02-13 devnull {
50 6e527fbc 2005-02-13 devnull int i;
51 6e527fbc 2005-02-13 devnull
52 6e527fbc 2005-02-13 devnull for(i=1; i<nelem(rpcname); i++)
53 6e527fbc 2005-02-13 devnull if(strcmp(s, rpcname[i]) == 0)
54 6e527fbc 2005-02-13 devnull return i;
55 6e527fbc 2005-02-13 devnull return RpcUnknown;
56 6e527fbc 2005-02-13 devnull }
57 6e527fbc 2005-02-13 devnull
58 6e527fbc 2005-02-13 devnull int
59 6e527fbc 2005-02-13 devnull rpcwrite(Conv *c, void *data, int count)
60 6e527fbc 2005-02-13 devnull {
61 6e527fbc 2005-02-13 devnull int op;
62 6e527fbc 2005-02-13 devnull uchar *p;
63 6e527fbc 2005-02-13 devnull
64 6e527fbc 2005-02-13 devnull if(count >= MaxRpc){
65 6e527fbc 2005-02-13 devnull werrstr("rpc too large");
66 6e527fbc 2005-02-13 devnull return -1;
67 6e527fbc 2005-02-13 devnull }
68 6e527fbc 2005-02-13 devnull
69 6e527fbc 2005-02-13 devnull /* cancel any current rpc */
70 6e527fbc 2005-02-13 devnull c->rpc.op = RpcUnknown;
71 6e527fbc 2005-02-13 devnull c->nreply = 0;
72 6e527fbc 2005-02-13 devnull
73 6e527fbc 2005-02-13 devnull /* parse new rpc */
74 6e527fbc 2005-02-13 devnull memmove(c->rpcbuf, data, count);
75 6e527fbc 2005-02-13 devnull c->rpcbuf[count] = 0;
76 6e527fbc 2005-02-13 devnull if(p = (uchar*)strchr((char*)c->rpcbuf, ' ')){
77 6e527fbc 2005-02-13 devnull *p++ = '\0';
78 6e527fbc 2005-02-13 devnull c->rpc.data = p;
79 6e527fbc 2005-02-13 devnull c->rpc.count = count - (p - (uchar*)c->rpcbuf);
80 6e527fbc 2005-02-13 devnull }else{
81 6e527fbc 2005-02-13 devnull c->rpc.data = "";
82 6e527fbc 2005-02-13 devnull c->rpc.count = 0;
83 6e527fbc 2005-02-13 devnull }
84 6e527fbc 2005-02-13 devnull op = classify(c->rpcbuf);
85 6e527fbc 2005-02-13 devnull if(op == RpcUnknown){
86 6e527fbc 2005-02-13 devnull werrstr("bad rpc verb: %s", c->rpcbuf);
87 6e527fbc 2005-02-13 devnull return -1;
88 6e527fbc 2005-02-13 devnull }
89 6e527fbc 2005-02-13 devnull
90 6e527fbc 2005-02-13 devnull c->rpc.op = op;
91 6e527fbc 2005-02-13 devnull return 0;
92 6e527fbc 2005-02-13 devnull }
93 6e527fbc 2005-02-13 devnull
94 6e527fbc 2005-02-13 devnull void
95 6e527fbc 2005-02-13 devnull convthread(void *v)
96 6e527fbc 2005-02-13 devnull {
97 6e527fbc 2005-02-13 devnull Conv *c;
98 6e527fbc 2005-02-13 devnull Attr *a;
99 6e527fbc 2005-02-13 devnull char *role, *proto;
100 6e527fbc 2005-02-13 devnull Proto *p;
101 6e527fbc 2005-02-13 devnull Role *r;
102 6e527fbc 2005-02-13 devnull
103 6e527fbc 2005-02-13 devnull c = v;
104 6e527fbc 2005-02-13 devnull a = parseattr(c->rpc.data);
105 6e527fbc 2005-02-13 devnull if(a == nil){
106 6e527fbc 2005-02-13 devnull werrstr("empty attr");
107 6e527fbc 2005-02-13 devnull goto out;
108 6e527fbc 2005-02-13 devnull }
109 6e527fbc 2005-02-13 devnull c->attr = a;
110 6e527fbc 2005-02-13 devnull proto = strfindattr(a, "proto");
111 6e527fbc 2005-02-13 devnull if(proto == nil){
112 6e527fbc 2005-02-13 devnull werrstr("no proto in attrs");
113 6e527fbc 2005-02-13 devnull goto out;
114 6e527fbc 2005-02-13 devnull }
115 6e527fbc 2005-02-13 devnull
116 6e527fbc 2005-02-13 devnull p = protolookup(proto);
117 6e527fbc 2005-02-13 devnull if(p == nil){
118 6e527fbc 2005-02-13 devnull werrstr("unknown proto %s", proto);
119 6e527fbc 2005-02-13 devnull goto out;
120 6e527fbc 2005-02-13 devnull }
121 6e527fbc 2005-02-13 devnull c->proto = p;
122 0870ded1 2006-02-14 devnull
123 0870ded1 2006-02-14 devnull role = strfindattr(a, "role");
124 0870ded1 2006-02-14 devnull if(role == nil){
125 0870ded1 2006-02-14 devnull werrstr("no role in attrs");
126 0870ded1 2006-02-14 devnull goto out;
127 0870ded1 2006-02-14 devnull }
128 0870ded1 2006-02-14 devnull
129 6e527fbc 2005-02-13 devnull for(r=p->roles; r->name; r++){
130 6e527fbc 2005-02-13 devnull if(strcmp(r->name, role) != 0)
131 6e527fbc 2005-02-13 devnull continue;
132 6e527fbc 2005-02-13 devnull rpcrespond(c, "ok");
133 6e527fbc 2005-02-13 devnull c->active = 1;
134 6e527fbc 2005-02-13 devnull if((*r->fn)(c) == 0){
135 6e527fbc 2005-02-13 devnull c->done = 1;
136 6e527fbc 2005-02-13 devnull werrstr("protocol finished");
137 6e527fbc 2005-02-13 devnull }else
138 6e527fbc 2005-02-13 devnull werrstr("%s %s %s: %r", p->name, r->name, c->state);
139 6e527fbc 2005-02-13 devnull goto out;
140 6e527fbc 2005-02-13 devnull }
141 6e527fbc 2005-02-13 devnull werrstr("unknown role");
142 6e527fbc 2005-02-13 devnull
143 6e527fbc 2005-02-13 devnull out:
144 6e527fbc 2005-02-13 devnull c->active = 0;
145 6e527fbc 2005-02-13 devnull c->state = 0;
146 6e527fbc 2005-02-13 devnull rerrstr(c->err, sizeof c->err);
147 6e527fbc 2005-02-13 devnull rpcrespond(c, "error %r");
148 6e527fbc 2005-02-13 devnull convclose(c);
149 6e527fbc 2005-02-13 devnull }
150 6e527fbc 2005-02-13 devnull
151 6e527fbc 2005-02-13 devnull static uchar* convAI2M(uchar *p, int n, char *cuid, char *suid, char *cap, char *hex);
152 6e527fbc 2005-02-13 devnull
153 6e527fbc 2005-02-13 devnull void
154 6e527fbc 2005-02-13 devnull rpcexec(Conv *c)
155 6e527fbc 2005-02-13 devnull {
156 6e527fbc 2005-02-13 devnull uchar *p;
157 6e527fbc 2005-02-13 devnull
158 ce94dbe6 2005-02-13 devnull c->rpc.hex = 0;
159 6e527fbc 2005-02-13 devnull switch(c->rpc.op){
160 ce94dbe6 2005-02-13 devnull case RpcWriteHex:
161 ce94dbe6 2005-02-13 devnull c->rpc.op = RpcWrite;
162 ce94dbe6 2005-02-13 devnull if(dec16(c->rpc.data, c->rpc.count, c->rpc.data, c->rpc.count) != c->rpc.count/2){
163 ce94dbe6 2005-02-13 devnull rpcrespond(c, "bad hex");
164 ce94dbe6 2005-02-13 devnull break;
165 ce94dbe6 2005-02-13 devnull }
166 ce94dbe6 2005-02-13 devnull c->rpc.count /= 2;
167 ce94dbe6 2005-02-13 devnull goto Default;
168 ce94dbe6 2005-02-13 devnull case RpcReadHex:
169 ce94dbe6 2005-02-13 devnull c->rpc.hex = 1;
170 ce94dbe6 2005-02-13 devnull c->rpc.op = RpcRead;
171 ce94dbe6 2005-02-13 devnull /* fall through */
172 6e527fbc 2005-02-13 devnull case RpcRead:
173 6e527fbc 2005-02-13 devnull if(c->rpc.count > 0){
174 6e527fbc 2005-02-13 devnull rpcrespond(c, "error read takes no parameters");
175 6e527fbc 2005-02-13 devnull break;
176 6e527fbc 2005-02-13 devnull }
177 6e527fbc 2005-02-13 devnull /* fall through */
178 6e527fbc 2005-02-13 devnull default:
179 ce94dbe6 2005-02-13 devnull Default:
180 6e527fbc 2005-02-13 devnull if(!c->active){
181 6e527fbc 2005-02-13 devnull if(c->done)
182 6e527fbc 2005-02-13 devnull rpcrespond(c, "done");
183 6e527fbc 2005-02-13 devnull else
184 6e527fbc 2005-02-13 devnull rpcrespond(c, "error %s", c->err);
185 6e527fbc 2005-02-13 devnull break;
186 6e527fbc 2005-02-13 devnull }
187 6e527fbc 2005-02-13 devnull nbsendp(c->rpcwait, 0);
188 6e527fbc 2005-02-13 devnull break;
189 6e527fbc 2005-02-13 devnull case RpcUnknown:
190 6e527fbc 2005-02-13 devnull break;
191 6e527fbc 2005-02-13 devnull case RpcAuthinfo:
192 6e527fbc 2005-02-13 devnull /* deprecated */
193 6e527fbc 2005-02-13 devnull if(c->active)
194 6e527fbc 2005-02-13 devnull rpcrespond(c, "error conversation still active");
195 6e527fbc 2005-02-13 devnull else if(!c->done)
196 6e527fbc 2005-02-13 devnull rpcrespond(c, "error conversation not successful");
197 6e527fbc 2005-02-13 devnull else{
198 6e527fbc 2005-02-13 devnull /* make up an auth info using the attr */
199 6e527fbc 2005-02-13 devnull p = convAI2M((uchar*)c->reply+3, sizeof c->reply-3,
200 6e527fbc 2005-02-13 devnull strfindattr(c->attr, "cuid"),
201 6e527fbc 2005-02-13 devnull strfindattr(c->attr, "suid"),
202 6e527fbc 2005-02-13 devnull strfindattr(c->attr, "cap"),
203 6e527fbc 2005-02-13 devnull strfindattr(c->attr, "secret"));
204 6e527fbc 2005-02-13 devnull if(p == nil)
205 6e527fbc 2005-02-13 devnull rpcrespond(c, "error %r");
206 6e527fbc 2005-02-13 devnull else
207 6e527fbc 2005-02-13 devnull rpcrespondn(c, "ok", c->reply+3, p-(uchar*)(c->reply+3));
208 6e527fbc 2005-02-13 devnull }
209 6e527fbc 2005-02-13 devnull break;
210 6e527fbc 2005-02-13 devnull case RpcAttr:
211 6e527fbc 2005-02-13 devnull rpcrespond(c, "ok %A", c->attr);
212 6e527fbc 2005-02-13 devnull break;
213 6e527fbc 2005-02-13 devnull case RpcStart:
214 6e527fbc 2005-02-13 devnull convreset(c);
215 6e527fbc 2005-02-13 devnull c->ref++;
216 6e527fbc 2005-02-13 devnull threadcreate(convthread, c, STACK);
217 6e527fbc 2005-02-13 devnull break;
218 6e527fbc 2005-02-13 devnull }
219 6e527fbc 2005-02-13 devnull }
220 6e527fbc 2005-02-13 devnull
221 6e527fbc 2005-02-13 devnull void
222 6e527fbc 2005-02-13 devnull rpcrespond(Conv *c, char *fmt, ...)
223 6e527fbc 2005-02-13 devnull {
224 6e527fbc 2005-02-13 devnull va_list arg;
225 6e527fbc 2005-02-13 devnull
226 6e527fbc 2005-02-13 devnull if(c->hangup)
227 6e527fbc 2005-02-13 devnull return;
228 6e527fbc 2005-02-13 devnull
229 6e527fbc 2005-02-13 devnull if(fmt == nil)
230 6e527fbc 2005-02-13 devnull fmt = "";
231 6e527fbc 2005-02-13 devnull
232 6e527fbc 2005-02-13 devnull va_start(arg, fmt);
233 6e527fbc 2005-02-13 devnull c->nreply = vsnprint(c->reply, sizeof c->reply, fmt, arg);
234 6e527fbc 2005-02-13 devnull va_end(arg);
235 6e527fbc 2005-02-13 devnull (*c->kickreply)(c);
236 6e527fbc 2005-02-13 devnull c->rpc.op = RpcUnknown;
237 6e527fbc 2005-02-13 devnull }
238 6e527fbc 2005-02-13 devnull
239 6e527fbc 2005-02-13 devnull void
240 6e527fbc 2005-02-13 devnull rpcrespondn(Conv *c, char *verb, void *data, int count)
241 6e527fbc 2005-02-13 devnull {
242 6e527fbc 2005-02-13 devnull char *p;
243 ce94dbe6 2005-02-13 devnull int need, hex;
244 6e527fbc 2005-02-13 devnull
245 6e527fbc 2005-02-13 devnull if(c->hangup)
246 6e527fbc 2005-02-13 devnull return;
247 6e527fbc 2005-02-13 devnull
248 ce94dbe6 2005-02-13 devnull need = strlen(verb)+1+count;
249 ce94dbe6 2005-02-13 devnull hex = 0;
250 ce94dbe6 2005-02-13 devnull if(c->rpc.hex && strcmp(verb, "ok") == 0){
251 ce94dbe6 2005-02-13 devnull need += count;
252 ce94dbe6 2005-02-13 devnull hex = 1;
253 ce94dbe6 2005-02-13 devnull }
254 ce94dbe6 2005-02-13 devnull if(need > sizeof c->reply){
255 6e527fbc 2005-02-13 devnull print("RPC response too large; caller %#lux", getcallerpc(&c));
256 6e527fbc 2005-02-13 devnull return;
257 6e527fbc 2005-02-13 devnull }
258 6e527fbc 2005-02-13 devnull
259 6e527fbc 2005-02-13 devnull strcpy(c->reply, verb);
260 6e527fbc 2005-02-13 devnull p = c->reply + strlen(c->reply);
261 6e527fbc 2005-02-13 devnull *p++ = ' ';
262 ce94dbe6 2005-02-13 devnull if(hex){
263 e1a22963 2005-02-13 devnull enc16(p, 2*count+1, data, count);
264 ce94dbe6 2005-02-13 devnull p += 2*count;
265 ce94dbe6 2005-02-13 devnull }else{
266 ce94dbe6 2005-02-13 devnull memmove(p, data, count);
267 ce94dbe6 2005-02-13 devnull p += count;
268 ce94dbe6 2005-02-13 devnull }
269 ce94dbe6 2005-02-13 devnull c->nreply = p - c->reply;
270 6e527fbc 2005-02-13 devnull (*c->kickreply)(c);
271 6e527fbc 2005-02-13 devnull c->rpc.op = RpcUnknown;
272 6e527fbc 2005-02-13 devnull }
273 6e527fbc 2005-02-13 devnull
274 6e527fbc 2005-02-13 devnull /* deprecated */
275 6e527fbc 2005-02-13 devnull static uchar*
276 6e527fbc 2005-02-13 devnull pstring(uchar *p, uchar *e, char *s)
277 6e527fbc 2005-02-13 devnull {
278 6e527fbc 2005-02-13 devnull uint n;
279 6e527fbc 2005-02-13 devnull
280 6e527fbc 2005-02-13 devnull if(p == nil)
281 6e527fbc 2005-02-13 devnull return nil;
282 6e527fbc 2005-02-13 devnull if(s == nil)
283 6e527fbc 2005-02-13 devnull s = "";
284 6e527fbc 2005-02-13 devnull n = strlen(s);
285 6e527fbc 2005-02-13 devnull if(p+n+BIT16SZ >= e)
286 6e527fbc 2005-02-13 devnull return nil;
287 6e527fbc 2005-02-13 devnull PBIT16(p, n);
288 6e527fbc 2005-02-13 devnull p += BIT16SZ;
289 6e527fbc 2005-02-13 devnull memmove(p, s, n);
290 6e527fbc 2005-02-13 devnull p += n;
291 6e527fbc 2005-02-13 devnull return p;
292 6e527fbc 2005-02-13 devnull }
293 6e527fbc 2005-02-13 devnull
294 6e527fbc 2005-02-13 devnull static uchar*
295 6e527fbc 2005-02-13 devnull pcarray(uchar *p, uchar *e, uchar *s, uint n)
296 6e527fbc 2005-02-13 devnull {
297 6e527fbc 2005-02-13 devnull if(p == nil)
298 6e527fbc 2005-02-13 devnull return nil;
299 6e527fbc 2005-02-13 devnull if(s == nil){
300 6e527fbc 2005-02-13 devnull if(n > 0)
301 6e527fbc 2005-02-13 devnull sysfatal("pcarray");
302 6e527fbc 2005-02-13 devnull s = (uchar*)"";
303 6e527fbc 2005-02-13 devnull }
304 6e527fbc 2005-02-13 devnull if(p+n+BIT16SZ >= e)
305 6e527fbc 2005-02-13 devnull return nil;
306 6e527fbc 2005-02-13 devnull PBIT16(p, n);
307 6e527fbc 2005-02-13 devnull p += BIT16SZ;
308 6e527fbc 2005-02-13 devnull memmove(p, s, n);
309 6e527fbc 2005-02-13 devnull p += n;
310 6e527fbc 2005-02-13 devnull return p;
311 6e527fbc 2005-02-13 devnull }
312 6e527fbc 2005-02-13 devnull
313 6e527fbc 2005-02-13 devnull static uchar*
314 6e527fbc 2005-02-13 devnull convAI2M(uchar *p, int n, char *cuid, char *suid, char *cap, char *hex)
315 6e527fbc 2005-02-13 devnull {
316 6e527fbc 2005-02-13 devnull uchar *e = p+n;
317 6e527fbc 2005-02-13 devnull uchar *secret;
318 6e527fbc 2005-02-13 devnull int nsecret;
319 6e527fbc 2005-02-13 devnull
320 6e527fbc 2005-02-13 devnull if(cuid == nil)
321 6e527fbc 2005-02-13 devnull cuid = "";
322 6e527fbc 2005-02-13 devnull if(suid == nil)
323 6e527fbc 2005-02-13 devnull suid = "";
324 6e527fbc 2005-02-13 devnull if(cap == nil)
325 6e527fbc 2005-02-13 devnull cap = "";
326 6e527fbc 2005-02-13 devnull if(hex == nil)
327 6e527fbc 2005-02-13 devnull hex = "";
328 6e527fbc 2005-02-13 devnull nsecret = strlen(hex)/2;
329 6e527fbc 2005-02-13 devnull secret = emalloc(nsecret);
330 6e527fbc 2005-02-13 devnull if(hexparse(hex, secret, nsecret) < 0){
331 6e527fbc 2005-02-13 devnull werrstr("hexparse %s failed", hex); /* can't happen */
332 6e527fbc 2005-02-13 devnull free(secret);
333 6e527fbc 2005-02-13 devnull return nil;
334 6e527fbc 2005-02-13 devnull }
335 6e527fbc 2005-02-13 devnull p = pstring(p, e, cuid);
336 6e527fbc 2005-02-13 devnull p = pstring(p, e, suid);
337 6e527fbc 2005-02-13 devnull p = pstring(p, e, cap);
338 6e527fbc 2005-02-13 devnull p = pcarray(p, e, secret, nsecret);
339 6e527fbc 2005-02-13 devnull free(secret);
340 6e527fbc 2005-02-13 devnull if(p == nil)
341 6e527fbc 2005-02-13 devnull werrstr("authinfo too big");
342 6e527fbc 2005-02-13 devnull return p;
343 6e527fbc 2005-02-13 devnull }
344 6e527fbc 2005-02-13 devnull