1 2277c5d7 2004-03-21 devnull #include "std.h"
2 2277c5d7 2004-03-21 devnull #include "dat.h"
5 2277c5d7 2004-03-21 devnull * Factotum RPC
7 2277c5d7 2004-03-21 devnull * Must be paired write/read cycles on /mnt/factotum/rpc.
8 2277c5d7 2004-03-21 devnull * The format of a request is verb, single space, data.
9 2277c5d7 2004-03-21 devnull * Data format is verb-dependent; in particular, it can be binary.
10 2277c5d7 2004-03-21 devnull * The format of a response is the same. The write only sets up
11 2277c5d7 2004-03-21 devnull * the RPC. The read tries to execute it. If the /mnt/factotum/key
12 2277c5d7 2004-03-21 devnull * file is open, we ask for new keys using that instead of returning
13 2277c5d7 2004-03-21 devnull * an error in the RPC. This means the read blocks.
14 2277c5d7 2004-03-21 devnull * Textual arguments are parsed with tokenize, so rc-style quoting
15 2277c5d7 2004-03-21 devnull * rules apply.
17 2277c5d7 2004-03-21 devnull * Only authentication protocol messages go here. Configuration
18 2277c5d7 2004-03-21 devnull * is still via ctl (below).
20 2277c5d7 2004-03-21 devnull * Request RPCs are:
21 2277c5d7 2004-03-21 devnull * start attrs - initializes protocol for authentication, can fail.
22 2277c5d7 2004-03-21 devnull * returns "ok read" or "ok write" on success.
23 2277c5d7 2004-03-21 devnull * read - execute protocol read
24 2277c5d7 2004-03-21 devnull * write - execute protocol write
25 2277c5d7 2004-03-21 devnull * authinfo - if the protocol is finished, return the AI if any
26 2277c5d7 2004-03-21 devnull * attr - return protocol information
27 2277c5d7 2004-03-21 devnull * Return values are:
28 2277c5d7 2004-03-21 devnull * error message - an error happened.
29 2277c5d7 2004-03-21 devnull * ok [data] - success, possible data is request dependent.
30 2277c5d7 2004-03-21 devnull * needkey attrs - request aborted, get me this key and try again
31 2277c5d7 2004-03-21 devnull * badkey attrs - request aborted, this key might be bad
32 2277c5d7 2004-03-21 devnull * done [haveai] - authentication is done [haveai: you can get an ai with authinfo]
35 2277c5d7 2004-03-21 devnull char *rpcname[] =
37 2277c5d7 2004-03-21 devnull "unknown",
38 2277c5d7 2004-03-21 devnull "authinfo",
45 2277c5d7 2004-03-21 devnull static int
46 2277c5d7 2004-03-21 devnull classify(char *s)
50 2277c5d7 2004-03-21 devnull for(i=1; i<nelem(rpcname); i++)
51 2277c5d7 2004-03-21 devnull if(strcmp(s, rpcname[i]) == 0)
52 2277c5d7 2004-03-21 devnull return i;
53 2277c5d7 2004-03-21 devnull return RpcUnknown;
57 2277c5d7 2004-03-21 devnull rpcwrite(Conv *c, void *data, int count)
60 2277c5d7 2004-03-21 devnull uchar *p;
62 2277c5d7 2004-03-21 devnull if(count >= MaxRpc){
63 2277c5d7 2004-03-21 devnull werrstr("rpc too large");
64 2277c5d7 2004-03-21 devnull return -1;
67 2277c5d7 2004-03-21 devnull /* cancel any current rpc */
68 2277c5d7 2004-03-21 devnull c->rpc.op = RpcUnknown;
69 2277c5d7 2004-03-21 devnull c->nreply = 0;
71 2277c5d7 2004-03-21 devnull /* parse new rpc */
72 2277c5d7 2004-03-21 devnull memmove(c->rpcbuf, data, count);
73 2277c5d7 2004-03-21 devnull c->rpcbuf[count] = 0;
74 2277c5d7 2004-03-21 devnull if(p = (uchar*)strchr((char*)c->rpcbuf, ' ')){
75 2277c5d7 2004-03-21 devnull *p++ = '\0';
76 2277c5d7 2004-03-21 devnull c->rpc.data = p;
77 2277c5d7 2004-03-21 devnull c->rpc.count = count - (p - (uchar*)c->rpcbuf);
79 2277c5d7 2004-03-21 devnull c->rpc.data = "";
80 2277c5d7 2004-03-21 devnull c->rpc.count = 0;
82 2277c5d7 2004-03-21 devnull op = classify(c->rpcbuf);
83 2277c5d7 2004-03-21 devnull if(op == RpcUnknown){
84 2277c5d7 2004-03-21 devnull werrstr("bad rpc verb: %s", c->rpcbuf);
85 2277c5d7 2004-03-21 devnull return -1;
88 2277c5d7 2004-03-21 devnull c->rpc.op = op;
89 2277c5d7 2004-03-21 devnull return 0;
93 2277c5d7 2004-03-21 devnull convthread(void *v)
97 2277c5d7 2004-03-21 devnull char *role, *proto;
98 2277c5d7 2004-03-21 devnull Proto *p;
102 2277c5d7 2004-03-21 devnull a = parseattr(c->rpc.data);
103 2277c5d7 2004-03-21 devnull if(a == nil){
104 2277c5d7 2004-03-21 devnull werrstr("empty attr");
105 2277c5d7 2004-03-21 devnull goto out;
107 2277c5d7 2004-03-21 devnull c->attr = a;
108 2277c5d7 2004-03-21 devnull proto = strfindattr(a, "proto");
109 2277c5d7 2004-03-21 devnull role = strfindattr(a, "role");
111 2277c5d7 2004-03-21 devnull if(proto == nil){
112 2277c5d7 2004-03-21 devnull werrstr("no proto in attrs");
113 2277c5d7 2004-03-21 devnull goto out;
115 2277c5d7 2004-03-21 devnull if(role == nil){
116 2277c5d7 2004-03-21 devnull werrstr("no role in attrs");
117 2277c5d7 2004-03-21 devnull goto out;
120 2277c5d7 2004-03-21 devnull p = protolookup(proto);
121 2277c5d7 2004-03-21 devnull if(p == nil){
122 2277c5d7 2004-03-21 devnull werrstr("unknown proto %s", proto);
123 2277c5d7 2004-03-21 devnull goto out;
126 2277c5d7 2004-03-21 devnull c->proto = p;
127 2277c5d7 2004-03-21 devnull for(r=p->roles; r->name; r++){
128 2277c5d7 2004-03-21 devnull if(strcmp(r->name, role) != 0)
129 2277c5d7 2004-03-21 devnull continue;
130 2277c5d7 2004-03-21 devnull rpcrespond(c, "ok");
131 2277c5d7 2004-03-21 devnull c->active = 1;
132 2277c5d7 2004-03-21 devnull if((*r->fn)(c) == 0){
133 2277c5d7 2004-03-21 devnull c->done = 1;
134 2277c5d7 2004-03-21 devnull werrstr("protocol finished");
136 2277c5d7 2004-03-21 devnull werrstr("%s %s %s: %r", p->name, r->name, c->state);
137 2277c5d7 2004-03-21 devnull goto out;
139 2277c5d7 2004-03-21 devnull werrstr("unknown role");
142 2277c5d7 2004-03-21 devnull c->active = 0;
143 2277c5d7 2004-03-21 devnull c->state = 0;
144 2277c5d7 2004-03-21 devnull rerrstr(c->err, sizeof c->err);
145 2277c5d7 2004-03-21 devnull rpcrespond(c, "error %r");
146 2277c5d7 2004-03-21 devnull convclose(c);
149 2277c5d7 2004-03-21 devnull static uchar* convAI2M(uchar *p, int n, char *cuid, char *suid, char *cap, char *hex);
152 2277c5d7 2004-03-21 devnull rpcexec(Conv *c)
154 2277c5d7 2004-03-21 devnull uchar *p;
156 2277c5d7 2004-03-21 devnull switch(c->rpc.op){
157 2277c5d7 2004-03-21 devnull case RpcRead:
158 2277c5d7 2004-03-21 devnull if(c->rpc.count > 0){
159 2277c5d7 2004-03-21 devnull rpcrespond(c, "error read takes no parameters");
162 2277c5d7 2004-03-21 devnull /* fall through */
163 2277c5d7 2004-03-21 devnull default:
164 2277c5d7 2004-03-21 devnull if(!c->active){
165 2277c5d7 2004-03-21 devnull if(c->done)
166 2277c5d7 2004-03-21 devnull rpcrespond(c, "done");
168 2277c5d7 2004-03-21 devnull rpcrespond(c, "error %s", c->err);
171 2277c5d7 2004-03-21 devnull nbsendp(c->rpcwait, 0);
173 2277c5d7 2004-03-21 devnull case RpcUnknown:
175 2277c5d7 2004-03-21 devnull case RpcAuthinfo:
176 2277c5d7 2004-03-21 devnull /* deprecated */
177 2277c5d7 2004-03-21 devnull if(c->active)
178 2277c5d7 2004-03-21 devnull rpcrespond(c, "error conversation still active");
179 2277c5d7 2004-03-21 devnull else if(!c->done)
180 2277c5d7 2004-03-21 devnull rpcrespond(c, "error conversation not successful");
182 2277c5d7 2004-03-21 devnull /* make up an auth info using the attr */
183 2277c5d7 2004-03-21 devnull p = convAI2M((uchar*)c->reply+3, sizeof c->reply-3,
184 2277c5d7 2004-03-21 devnull strfindattr(c->attr, "cuid"),
185 2277c5d7 2004-03-21 devnull strfindattr(c->attr, "suid"),
186 2277c5d7 2004-03-21 devnull strfindattr(c->attr, "cap"),
187 2277c5d7 2004-03-21 devnull strfindattr(c->attr, "secret"));
188 2277c5d7 2004-03-21 devnull if(p == nil)
189 2277c5d7 2004-03-21 devnull rpcrespond(c, "error %r");
191 2277c5d7 2004-03-21 devnull rpcrespondn(c, "ok", c->reply+3, p-(uchar*)(c->reply+3));
194 2277c5d7 2004-03-21 devnull case RpcAttr:
195 2277c5d7 2004-03-21 devnull rpcrespond(c, "ok %A", c->attr);
197 2277c5d7 2004-03-21 devnull case RpcStart:
198 2277c5d7 2004-03-21 devnull convreset(c);
199 2277c5d7 2004-03-21 devnull c->ref++;
200 2277c5d7 2004-03-21 devnull threadcreate(convthread, c, STACK);
206 2277c5d7 2004-03-21 devnull rpcrespond(Conv *c, char *fmt, ...)
208 2277c5d7 2004-03-21 devnull va_list arg;
210 2277c5d7 2004-03-21 devnull if(c->hangup)
213 2277c5d7 2004-03-21 devnull if(fmt == nil)
214 2277c5d7 2004-03-21 devnull fmt = "";
216 2277c5d7 2004-03-21 devnull va_start(arg, fmt);
217 2277c5d7 2004-03-21 devnull c->nreply = vsnprint(c->reply, sizeof c->reply, fmt, arg);
218 2277c5d7 2004-03-21 devnull va_end(arg);
219 2277c5d7 2004-03-21 devnull (*c->kickreply)(c);
220 2277c5d7 2004-03-21 devnull c->rpc.op = RpcUnknown;
224 2277c5d7 2004-03-21 devnull rpcrespondn(Conv *c, char *verb, void *data, int count)
226 2277c5d7 2004-03-21 devnull char *p;
228 2277c5d7 2004-03-21 devnull if(c->hangup)
231 2277c5d7 2004-03-21 devnull if(strlen(verb)+1+count > sizeof c->reply){
232 2277c5d7 2004-03-21 devnull print("RPC response too large; caller %#lux", getcallerpc(&c));
236 2277c5d7 2004-03-21 devnull strcpy(c->reply, verb);
237 2277c5d7 2004-03-21 devnull p = c->reply + strlen(c->reply);
238 2277c5d7 2004-03-21 devnull *p++ = ' ';
239 2277c5d7 2004-03-21 devnull memmove(p, data, count);
240 2277c5d7 2004-03-21 devnull c->nreply = count + (p - c->reply);
241 2277c5d7 2004-03-21 devnull (*c->kickreply)(c);
242 2277c5d7 2004-03-21 devnull c->rpc.op = RpcUnknown;
245 2277c5d7 2004-03-21 devnull /* deprecated */
246 2277c5d7 2004-03-21 devnull static uchar*
247 2277c5d7 2004-03-21 devnull pstring(uchar *p, uchar *e, char *s)
251 2277c5d7 2004-03-21 devnull if(p == nil)
252 2277c5d7 2004-03-21 devnull return nil;
253 2277c5d7 2004-03-21 devnull if(s == nil)
255 2277c5d7 2004-03-21 devnull n = strlen(s);
256 2277c5d7 2004-03-21 devnull if(p+n+BIT16SZ >= e)
257 2277c5d7 2004-03-21 devnull return nil;
258 2277c5d7 2004-03-21 devnull PBIT16(p, n);
259 2277c5d7 2004-03-21 devnull p += BIT16SZ;
260 2277c5d7 2004-03-21 devnull memmove(p, s, n);
262 2277c5d7 2004-03-21 devnull return p;
265 2277c5d7 2004-03-21 devnull static uchar*
266 2277c5d7 2004-03-21 devnull pcarray(uchar *p, uchar *e, uchar *s, uint n)
268 2277c5d7 2004-03-21 devnull if(p == nil)
269 2277c5d7 2004-03-21 devnull return nil;
270 2277c5d7 2004-03-21 devnull if(s == nil){
271 2277c5d7 2004-03-21 devnull if(n > 0)
272 2277c5d7 2004-03-21 devnull sysfatal("pcarray");
273 2277c5d7 2004-03-21 devnull s = (uchar*)"";
275 2277c5d7 2004-03-21 devnull if(p+n+BIT16SZ >= e)
276 2277c5d7 2004-03-21 devnull return nil;
277 2277c5d7 2004-03-21 devnull PBIT16(p, n);
278 2277c5d7 2004-03-21 devnull p += BIT16SZ;
279 2277c5d7 2004-03-21 devnull memmove(p, s, n);
281 2277c5d7 2004-03-21 devnull return p;
284 2277c5d7 2004-03-21 devnull static uchar*
285 2277c5d7 2004-03-21 devnull convAI2M(uchar *p, int n, char *cuid, char *suid, char *cap, char *hex)
287 2277c5d7 2004-03-21 devnull uchar *e = p+n;
288 2277c5d7 2004-03-21 devnull uchar *secret;
289 2277c5d7 2004-03-21 devnull int nsecret;
291 2277c5d7 2004-03-21 devnull if(cuid == nil)
292 2277c5d7 2004-03-21 devnull cuid = "";
293 2277c5d7 2004-03-21 devnull if(suid == nil)
294 2277c5d7 2004-03-21 devnull suid = "";
295 2277c5d7 2004-03-21 devnull if(cap == nil)
296 2277c5d7 2004-03-21 devnull cap = "";
297 2277c5d7 2004-03-21 devnull if(hex == nil)
298 2277c5d7 2004-03-21 devnull hex = "";
299 2277c5d7 2004-03-21 devnull nsecret = strlen(hex)/2;
300 2277c5d7 2004-03-21 devnull secret = emalloc(nsecret);
301 2277c5d7 2004-03-21 devnull if(hexparse(hex, secret, nsecret) < 0){
302 2277c5d7 2004-03-21 devnull werrstr("hexparse %s failed", hex); /* can't happen */
303 2277c5d7 2004-03-21 devnull free(secret);
304 2277c5d7 2004-03-21 devnull return nil;
306 2277c5d7 2004-03-21 devnull p = pstring(p, e, cuid);
307 2277c5d7 2004-03-21 devnull p = pstring(p, e, suid);
308 2277c5d7 2004-03-21 devnull p = pstring(p, e, cap);
309 2277c5d7 2004-03-21 devnull p = pcarray(p, e, secret, nsecret);
310 2277c5d7 2004-03-21 devnull free(secret);
311 2277c5d7 2004-03-21 devnull if(p == nil)
312 2277c5d7 2004-03-21 devnull werrstr("authinfo too big");
313 2277c5d7 2004-03-21 devnull return p;