1 6e527fbc 2005-02-13 devnull #include "std.h"
2 6e527fbc 2005-02-13 devnull #include "dat.h"
5 6e527fbc 2005-02-13 devnull * Factotum RPC
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.
17 6e527fbc 2005-02-13 devnull * Only authentication protocol messages go here. Configuration
18 6e527fbc 2005-02-13 devnull * is still via ctl (below).
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]
35 fa325e9b 2020-01-10 cross char *rpcname[] =
37 6e527fbc 2005-02-13 devnull "unknown",
38 6e527fbc 2005-02-13 devnull "authinfo",
43 ce94dbe6 2005-02-13 devnull "readhex",
44 cbeb0b26 2006-04-01 devnull "writehex"
47 6e527fbc 2005-02-13 devnull static int
48 6e527fbc 2005-02-13 devnull classify(char *s)
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;
59 6e527fbc 2005-02-13 devnull rpcwrite(Conv *c, void *data, int count)
62 6e527fbc 2005-02-13 devnull uchar *p;
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;
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;
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);
81 6e527fbc 2005-02-13 devnull c->rpc.data = "";
82 6e527fbc 2005-02-13 devnull c->rpc.count = 0;
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;
90 6e527fbc 2005-02-13 devnull c->rpc.op = op;
91 6e527fbc 2005-02-13 devnull return 0;
95 6e527fbc 2005-02-13 devnull convthread(void *v)
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;
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;
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;
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;
121 6e527fbc 2005-02-13 devnull c->proto = p;
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;
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");
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;
141 6e527fbc 2005-02-13 devnull werrstr("unknown role");
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);
151 6e527fbc 2005-02-13 devnull static uchar* convAI2M(uchar *p, int n, char *cuid, char *suid, char *cap, char *hex);
154 6e527fbc 2005-02-13 devnull rpcexec(Conv *c)
156 6e527fbc 2005-02-13 devnull uchar *p;
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");
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");
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");
184 6e527fbc 2005-02-13 devnull rpcrespond(c, "error %s", c->err);
187 6e527fbc 2005-02-13 devnull nbsendp(c->rpcwait, 0);
189 6e527fbc 2005-02-13 devnull case RpcUnknown:
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");
198 6e527fbc 2005-02-13 devnull /* make up an auth info using the attr */
199 fa325e9b 2020-01-10 cross 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");
207 6e527fbc 2005-02-13 devnull rpcrespondn(c, "ok", c->reply+3, p-(uchar*)(c->reply+3));
210 6e527fbc 2005-02-13 devnull case RpcAttr:
211 6e527fbc 2005-02-13 devnull rpcrespond(c, "ok %A", c->attr);
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);
222 6e527fbc 2005-02-13 devnull rpcrespond(Conv *c, char *fmt, ...)
224 6e527fbc 2005-02-13 devnull va_list arg;
226 6e527fbc 2005-02-13 devnull if(c->hangup)
229 6e527fbc 2005-02-13 devnull if(fmt == nil)
230 6e527fbc 2005-02-13 devnull fmt = "";
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;
240 6e527fbc 2005-02-13 devnull rpcrespondn(Conv *c, char *verb, void *data, int count)
242 6e527fbc 2005-02-13 devnull char *p;
243 ce94dbe6 2005-02-13 devnull int need, hex;
245 6e527fbc 2005-02-13 devnull if(c->hangup)
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;
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));
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;
266 ce94dbe6 2005-02-13 devnull memmove(p, data, count);
267 ce94dbe6 2005-02-13 devnull p += count;
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;
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)
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)
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);
291 6e527fbc 2005-02-13 devnull return p;
294 6e527fbc 2005-02-13 devnull static uchar*
295 6e527fbc 2005-02-13 devnull pcarray(uchar *p, uchar *e, uchar *s, uint n)
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*)"";
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);
310 6e527fbc 2005-02-13 devnull return p;
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)
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;
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;
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;