Blame


1 2277c5d7 2004-03-21 devnull #include "std.h"
2 2277c5d7 2004-03-21 devnull #include "dat.h"
3 2277c5d7 2004-03-21 devnull
4 2277c5d7 2004-03-21 devnull /*
5 2277c5d7 2004-03-21 devnull * Factotum RPC
6 2277c5d7 2004-03-21 devnull *
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.
16 2277c5d7 2004-03-21 devnull *
17 2277c5d7 2004-03-21 devnull * Only authentication protocol messages go here. Configuration
18 2277c5d7 2004-03-21 devnull * is still via ctl (below).
19 2277c5d7 2004-03-21 devnull *
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]
33 2277c5d7 2004-03-21 devnull */
34 2277c5d7 2004-03-21 devnull
35 2277c5d7 2004-03-21 devnull char *rpcname[] =
36 2277c5d7 2004-03-21 devnull {
37 2277c5d7 2004-03-21 devnull "unknown",
38 2277c5d7 2004-03-21 devnull "authinfo",
39 2277c5d7 2004-03-21 devnull "attr",
40 2277c5d7 2004-03-21 devnull "read",
41 2277c5d7 2004-03-21 devnull "start",
42 2277c5d7 2004-03-21 devnull "write",
43 2277c5d7 2004-03-21 devnull };
44 2277c5d7 2004-03-21 devnull
45 2277c5d7 2004-03-21 devnull static int
46 2277c5d7 2004-03-21 devnull classify(char *s)
47 2277c5d7 2004-03-21 devnull {
48 2277c5d7 2004-03-21 devnull int i;
49 2277c5d7 2004-03-21 devnull
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;
54 2277c5d7 2004-03-21 devnull }
55 2277c5d7 2004-03-21 devnull
56 2277c5d7 2004-03-21 devnull int
57 2277c5d7 2004-03-21 devnull rpcwrite(Conv *c, void *data, int count)
58 2277c5d7 2004-03-21 devnull {
59 2277c5d7 2004-03-21 devnull int op;
60 2277c5d7 2004-03-21 devnull uchar *p;
61 2277c5d7 2004-03-21 devnull
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;
65 2277c5d7 2004-03-21 devnull }
66 2277c5d7 2004-03-21 devnull
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;
70 2277c5d7 2004-03-21 devnull
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);
78 2277c5d7 2004-03-21 devnull }else{
79 2277c5d7 2004-03-21 devnull c->rpc.data = "";
80 2277c5d7 2004-03-21 devnull c->rpc.count = 0;
81 2277c5d7 2004-03-21 devnull }
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;
86 2277c5d7 2004-03-21 devnull }
87 2277c5d7 2004-03-21 devnull
88 2277c5d7 2004-03-21 devnull c->rpc.op = op;
89 2277c5d7 2004-03-21 devnull return 0;
90 2277c5d7 2004-03-21 devnull }
91 2277c5d7 2004-03-21 devnull
92 2277c5d7 2004-03-21 devnull void
93 2277c5d7 2004-03-21 devnull convthread(void *v)
94 2277c5d7 2004-03-21 devnull {
95 2277c5d7 2004-03-21 devnull Conv *c;
96 2277c5d7 2004-03-21 devnull Attr *a;
97 2277c5d7 2004-03-21 devnull char *role, *proto;
98 2277c5d7 2004-03-21 devnull Proto *p;
99 2277c5d7 2004-03-21 devnull Role *r;
100 2277c5d7 2004-03-21 devnull
101 2277c5d7 2004-03-21 devnull c = v;
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;
106 2277c5d7 2004-03-21 devnull }
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");
110 2277c5d7 2004-03-21 devnull
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;
114 2277c5d7 2004-03-21 devnull }
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;
118 2277c5d7 2004-03-21 devnull }
119 2277c5d7 2004-03-21 devnull
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;
124 2277c5d7 2004-03-21 devnull }
125 2277c5d7 2004-03-21 devnull
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");
135 2277c5d7 2004-03-21 devnull }else
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;
138 2277c5d7 2004-03-21 devnull }
139 2277c5d7 2004-03-21 devnull werrstr("unknown role");
140 2277c5d7 2004-03-21 devnull
141 2277c5d7 2004-03-21 devnull out:
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);
147 2277c5d7 2004-03-21 devnull }
148 2277c5d7 2004-03-21 devnull
149 2277c5d7 2004-03-21 devnull static uchar* convAI2M(uchar *p, int n, char *cuid, char *suid, char *cap, char *hex);
150 2277c5d7 2004-03-21 devnull
151 2277c5d7 2004-03-21 devnull void
152 2277c5d7 2004-03-21 devnull rpcexec(Conv *c)
153 2277c5d7 2004-03-21 devnull {
154 2277c5d7 2004-03-21 devnull uchar *p;
155 2277c5d7 2004-03-21 devnull
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");
160 2277c5d7 2004-03-21 devnull break;
161 2277c5d7 2004-03-21 devnull }
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");
167 2277c5d7 2004-03-21 devnull else
168 2277c5d7 2004-03-21 devnull rpcrespond(c, "error %s", c->err);
169 2277c5d7 2004-03-21 devnull break;
170 2277c5d7 2004-03-21 devnull }
171 2277c5d7 2004-03-21 devnull nbsendp(c->rpcwait, 0);
172 2277c5d7 2004-03-21 devnull break;
173 2277c5d7 2004-03-21 devnull case RpcUnknown:
174 2277c5d7 2004-03-21 devnull break;
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");
181 2277c5d7 2004-03-21 devnull else{
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");
190 2277c5d7 2004-03-21 devnull else
191 2277c5d7 2004-03-21 devnull rpcrespondn(c, "ok", c->reply+3, p-(uchar*)(c->reply+3));
192 2277c5d7 2004-03-21 devnull }
193 2277c5d7 2004-03-21 devnull break;
194 2277c5d7 2004-03-21 devnull case RpcAttr:
195 2277c5d7 2004-03-21 devnull rpcrespond(c, "ok %A", c->attr);
196 2277c5d7 2004-03-21 devnull break;
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);
201 2277c5d7 2004-03-21 devnull break;
202 2277c5d7 2004-03-21 devnull }
203 2277c5d7 2004-03-21 devnull }
204 2277c5d7 2004-03-21 devnull
205 2277c5d7 2004-03-21 devnull void
206 2277c5d7 2004-03-21 devnull rpcrespond(Conv *c, char *fmt, ...)
207 2277c5d7 2004-03-21 devnull {
208 2277c5d7 2004-03-21 devnull va_list arg;
209 2277c5d7 2004-03-21 devnull
210 2277c5d7 2004-03-21 devnull if(c->hangup)
211 2277c5d7 2004-03-21 devnull return;
212 2277c5d7 2004-03-21 devnull
213 2277c5d7 2004-03-21 devnull if(fmt == nil)
214 2277c5d7 2004-03-21 devnull fmt = "";
215 2277c5d7 2004-03-21 devnull
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;
221 2277c5d7 2004-03-21 devnull }
222 2277c5d7 2004-03-21 devnull
223 2277c5d7 2004-03-21 devnull void
224 2277c5d7 2004-03-21 devnull rpcrespondn(Conv *c, char *verb, void *data, int count)
225 2277c5d7 2004-03-21 devnull {
226 2277c5d7 2004-03-21 devnull char *p;
227 2277c5d7 2004-03-21 devnull
228 2277c5d7 2004-03-21 devnull if(c->hangup)
229 2277c5d7 2004-03-21 devnull return;
230 2277c5d7 2004-03-21 devnull
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));
233 2277c5d7 2004-03-21 devnull return;
234 2277c5d7 2004-03-21 devnull }
235 2277c5d7 2004-03-21 devnull
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;
243 2277c5d7 2004-03-21 devnull }
244 2277c5d7 2004-03-21 devnull
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)
248 2277c5d7 2004-03-21 devnull {
249 2277c5d7 2004-03-21 devnull uint n;
250 2277c5d7 2004-03-21 devnull
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)
254 2277c5d7 2004-03-21 devnull s = "";
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);
261 2277c5d7 2004-03-21 devnull p += n;
262 2277c5d7 2004-03-21 devnull return p;
263 2277c5d7 2004-03-21 devnull }
264 2277c5d7 2004-03-21 devnull
265 2277c5d7 2004-03-21 devnull static uchar*
266 2277c5d7 2004-03-21 devnull pcarray(uchar *p, uchar *e, uchar *s, uint n)
267 2277c5d7 2004-03-21 devnull {
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*)"";
274 2277c5d7 2004-03-21 devnull }
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);
280 2277c5d7 2004-03-21 devnull p += n;
281 2277c5d7 2004-03-21 devnull return p;
282 2277c5d7 2004-03-21 devnull }
283 2277c5d7 2004-03-21 devnull
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)
286 2277c5d7 2004-03-21 devnull {
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;
290 2277c5d7 2004-03-21 devnull
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;
305 2277c5d7 2004-03-21 devnull }
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;
314 2277c5d7 2004-03-21 devnull }
315 2277c5d7 2004-03-21 devnull