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 Conv *conv;
5 6e527fbc 2005-02-13 devnull
6 6e527fbc 2005-02-13 devnull ulong taggen = 1;
7 6e527fbc 2005-02-13 devnull
8 6e527fbc 2005-02-13 devnull Conv*
9 6e527fbc 2005-02-13 devnull convalloc(char *sysuser)
10 6e527fbc 2005-02-13 devnull {
11 6e527fbc 2005-02-13 devnull Conv *c;
12 6e527fbc 2005-02-13 devnull
13 6e527fbc 2005-02-13 devnull c = mallocz(sizeof(Conv), 1);
14 6e527fbc 2005-02-13 devnull if(c == nil)
15 6e527fbc 2005-02-13 devnull return nil;
16 6e527fbc 2005-02-13 devnull c->ref = 1;
17 6e527fbc 2005-02-13 devnull c->tag = taggen++;
18 6e527fbc 2005-02-13 devnull c->next = conv;
19 6e527fbc 2005-02-13 devnull c->sysuser = estrdup(sysuser);
20 6e527fbc 2005-02-13 devnull c->state = "nascent";
21 6e527fbc 2005-02-13 devnull c->rpcwait = chancreate(sizeof(void*), 0);
22 6e527fbc 2005-02-13 devnull c->keywait = chancreate(sizeof(void*), 0);
23 6e527fbc 2005-02-13 devnull strcpy(c->err, "protocol has not started");
24 6e527fbc 2005-02-13 devnull conv = c;
25 6e527fbc 2005-02-13 devnull convreset(c);
26 6e527fbc 2005-02-13 devnull return c;
27 6e527fbc 2005-02-13 devnull }
28 6e527fbc 2005-02-13 devnull
29 6e527fbc 2005-02-13 devnull void
30 6e527fbc 2005-02-13 devnull convreset(Conv *c)
31 6e527fbc 2005-02-13 devnull {
32 6e527fbc 2005-02-13 devnull if(c->ref != 1){
33 6e527fbc 2005-02-13 devnull c->hangup = 1;
34 6e527fbc 2005-02-13 devnull nbsendp(c->rpcwait, 0);
35 6e527fbc 2005-02-13 devnull while(c->ref > 1)
36 6e527fbc 2005-02-13 devnull yield();
37 6e527fbc 2005-02-13 devnull c->hangup = 0;
38 6e527fbc 2005-02-13 devnull }
39 6e527fbc 2005-02-13 devnull c->state = "nascent";
40 6e527fbc 2005-02-13 devnull c->err[0] = '\0';
41 6e527fbc 2005-02-13 devnull freeattr(c->attr);
42 6e527fbc 2005-02-13 devnull c->attr = nil;
43 6e527fbc 2005-02-13 devnull c->proto = nil;
44 6e527fbc 2005-02-13 devnull c->rpc.op = 0;
45 6e527fbc 2005-02-13 devnull c->active = 0;
46 6e527fbc 2005-02-13 devnull c->done = 0;
47 6e527fbc 2005-02-13 devnull c->hangup = 0;
48 6e527fbc 2005-02-13 devnull }
49 6e527fbc 2005-02-13 devnull
50 6e527fbc 2005-02-13 devnull void
51 6e527fbc 2005-02-13 devnull convhangup(Conv *c)
52 6e527fbc 2005-02-13 devnull {
53 6e527fbc 2005-02-13 devnull c->hangup = 1;
54 6e527fbc 2005-02-13 devnull c->rpc.op = 0;
55 6e527fbc 2005-02-13 devnull (*c->kickreply)(c);
56 6e527fbc 2005-02-13 devnull nbsendp(c->rpcwait, 0);
57 6e527fbc 2005-02-13 devnull }
58 6e527fbc 2005-02-13 devnull
59 6e527fbc 2005-02-13 devnull void
60 6e527fbc 2005-02-13 devnull convclose(Conv *c)
61 6e527fbc 2005-02-13 devnull {
62 6e527fbc 2005-02-13 devnull Conv *p;
63 6e527fbc 2005-02-13 devnull
64 6e527fbc 2005-02-13 devnull if(c == nil)
65 6e527fbc 2005-02-13 devnull return;
66 6e527fbc 2005-02-13 devnull
67 6e527fbc 2005-02-13 devnull if(--c->ref > 0)
68 6e527fbc 2005-02-13 devnull return;
69 6e527fbc 2005-02-13 devnull
70 6e527fbc 2005-02-13 devnull if(c == conv){
71 6e527fbc 2005-02-13 devnull conv = c->next;
72 6e527fbc 2005-02-13 devnull goto free;
73 6e527fbc 2005-02-13 devnull }
74 6e527fbc 2005-02-13 devnull for(p=conv; p && p->next!=c; p=p->next)
75 6e527fbc 2005-02-13 devnull ;
76 6e527fbc 2005-02-13 devnull if(p == nil){
77 6e527fbc 2005-02-13 devnull print("cannot find conv in list\n");
78 6e527fbc 2005-02-13 devnull return;
79 6e527fbc 2005-02-13 devnull }
80 6e527fbc 2005-02-13 devnull p->next = c->next;
81 6e527fbc 2005-02-13 devnull
82 6e527fbc 2005-02-13 devnull free:
83 6e527fbc 2005-02-13 devnull c->next = nil;
84 6e527fbc 2005-02-13 devnull free(c);
85 6e527fbc 2005-02-13 devnull }
86 6e527fbc 2005-02-13 devnull
87 6e527fbc 2005-02-13 devnull static Rpc*
88 6e527fbc 2005-02-13 devnull convgetrpc(Conv *c, int want)
89 6e527fbc 2005-02-13 devnull {
90 6e527fbc 2005-02-13 devnull for(;;){
91 6e527fbc 2005-02-13 devnull if(c->hangup){
92 5f6612ba 2008-05-31 rsc flog("convgetrpc: hangup");
93 6e527fbc 2005-02-13 devnull werrstr("hangup");
94 6e527fbc 2005-02-13 devnull return nil;
95 6e527fbc 2005-02-13 devnull }
96 6e527fbc 2005-02-13 devnull if(c->rpc.op == RpcUnknown){
97 6e527fbc 2005-02-13 devnull recvp(c->rpcwait);
98 6e527fbc 2005-02-13 devnull if(c->hangup){
99 5f6612ba 2008-05-31 rsc flog("convgetrpc: hangup");
100 6e527fbc 2005-02-13 devnull werrstr("hangup");
101 6e527fbc 2005-02-13 devnull return nil;
102 6e527fbc 2005-02-13 devnull }
103 6e527fbc 2005-02-13 devnull if(c->rpc.op == RpcUnknown)
104 6e527fbc 2005-02-13 devnull continue;
105 6e527fbc 2005-02-13 devnull }
106 6e527fbc 2005-02-13 devnull if(want < 0 || c->rpc.op == want)
107 6e527fbc 2005-02-13 devnull return &c->rpc;
108 6e527fbc 2005-02-13 devnull rpcrespond(c, "phase in state '%s' want '%s'", c->state, rpcname[want]);
109 6e527fbc 2005-02-13 devnull }
110 bcac59d8 2005-08-11 devnull /* not reached */
111 6e527fbc 2005-02-13 devnull }
112 6e527fbc 2005-02-13 devnull
113 6e527fbc 2005-02-13 devnull /* read until the done function tells us that's enough */
114 6e527fbc 2005-02-13 devnull int
115 6e527fbc 2005-02-13 devnull convreadfn(Conv *c, int (*done)(void*, int), char **ps)
116 6e527fbc 2005-02-13 devnull {
117 6e527fbc 2005-02-13 devnull int n;
118 6e527fbc 2005-02-13 devnull Rpc *r;
119 6e527fbc 2005-02-13 devnull char *s;
120 6e527fbc 2005-02-13 devnull
121 6e527fbc 2005-02-13 devnull for(;;){
122 6e527fbc 2005-02-13 devnull r = convgetrpc(c, RpcWrite);
123 6e527fbc 2005-02-13 devnull if(r == nil)
124 6e527fbc 2005-02-13 devnull return -1;
125 6e527fbc 2005-02-13 devnull n = (*done)(r->data, r->count);
126 6e527fbc 2005-02-13 devnull if(n == r->count)
127 6e527fbc 2005-02-13 devnull break;
128 6e527fbc 2005-02-13 devnull rpcrespond(c, "toosmall %d", n);
129 6e527fbc 2005-02-13 devnull }
130 6e527fbc 2005-02-13 devnull
131 6e527fbc 2005-02-13 devnull s = emalloc(r->count+1);
132 6e527fbc 2005-02-13 devnull memmove(s, r->data, r->count);
133 6e527fbc 2005-02-13 devnull s[r->count] = 0;
134 6e527fbc 2005-02-13 devnull *ps = s;
135 6e527fbc 2005-02-13 devnull rpcrespond(c, "ok");
136 6e527fbc 2005-02-13 devnull return r->count;
137 6e527fbc 2005-02-13 devnull }
138 6e527fbc 2005-02-13 devnull
139 6e527fbc 2005-02-13 devnull /*
140 6e527fbc 2005-02-13 devnull * read until we get a non-zero write. assumes remote side
141 6e527fbc 2005-02-13 devnull * knows something about the protocol (is not auth_proxy).
142 6e527fbc 2005-02-13 devnull * the remote side typically won't bother with the zero-length
143 6e527fbc 2005-02-13 devnull * write to find out the length -- the loop is there only so the
144 6e527fbc 2005-02-13 devnull * test program can call auth_proxy on both sides of a pipe
145 6e527fbc 2005-02-13 devnull * to play a conversation.
146 6e527fbc 2005-02-13 devnull */
147 6e527fbc 2005-02-13 devnull int
148 6e527fbc 2005-02-13 devnull convreadm(Conv *c, char **ps)
149 6e527fbc 2005-02-13 devnull {
150 6e527fbc 2005-02-13 devnull char *s;
151 6e527fbc 2005-02-13 devnull Rpc *r;
152 6e527fbc 2005-02-13 devnull
153 6e527fbc 2005-02-13 devnull for(;;){
154 6e527fbc 2005-02-13 devnull r = convgetrpc(c, RpcWrite);
155 6e527fbc 2005-02-13 devnull if(r == nil)
156 6e527fbc 2005-02-13 devnull return -1;
157 6e527fbc 2005-02-13 devnull if(r->count > 0)
158 6e527fbc 2005-02-13 devnull break;
159 6e527fbc 2005-02-13 devnull rpcrespond(c, "toosmall %d", AuthRpcMax);
160 6e527fbc 2005-02-13 devnull }
161 6e527fbc 2005-02-13 devnull s = emalloc(r->count+1);
162 6e527fbc 2005-02-13 devnull memmove(s, r->data, r->count);
163 6e527fbc 2005-02-13 devnull s[r->count] = 0;
164 6e527fbc 2005-02-13 devnull *ps = s;
165 6e527fbc 2005-02-13 devnull rpcrespond(c, "ok");
166 6e527fbc 2005-02-13 devnull return r->count;
167 6e527fbc 2005-02-13 devnull }
168 6e527fbc 2005-02-13 devnull
169 6e527fbc 2005-02-13 devnull /* read exactly count bytes */
170 6e527fbc 2005-02-13 devnull int
171 6e527fbc 2005-02-13 devnull convread(Conv *c, void *data, int count)
172 6e527fbc 2005-02-13 devnull {
173 6e527fbc 2005-02-13 devnull Rpc *r;
174 6e527fbc 2005-02-13 devnull
175 6e527fbc 2005-02-13 devnull for(;;){
176 6e527fbc 2005-02-13 devnull r = convgetrpc(c, RpcWrite);
177 6e527fbc 2005-02-13 devnull if(r == nil)
178 6e527fbc 2005-02-13 devnull return -1;
179 6e527fbc 2005-02-13 devnull if(r->count == count)
180 6e527fbc 2005-02-13 devnull break;
181 6e527fbc 2005-02-13 devnull if(r->count < count)
182 6e527fbc 2005-02-13 devnull rpcrespond(c, "toosmall %d", count);
183 6e527fbc 2005-02-13 devnull else
184 6e527fbc 2005-02-13 devnull rpcrespond(c, "error too much data; want %d got %d", count, r->count);
185 6e527fbc 2005-02-13 devnull }
186 6e527fbc 2005-02-13 devnull memmove(data, r->data, count);
187 6e527fbc 2005-02-13 devnull rpcrespond(c, "ok");
188 6e527fbc 2005-02-13 devnull return 0;
189 6e527fbc 2005-02-13 devnull }
190 6e527fbc 2005-02-13 devnull
191 6e527fbc 2005-02-13 devnull /* write exactly count bytes */
192 6e527fbc 2005-02-13 devnull int
193 6e527fbc 2005-02-13 devnull convwrite(Conv *c, void *data, int count)
194 6e527fbc 2005-02-13 devnull {
195 6e527fbc 2005-02-13 devnull Rpc *r;
196 6e527fbc 2005-02-13 devnull
197 1f8a8072 2005-03-15 devnull r = convgetrpc(c, RpcRead);
198 1f8a8072 2005-03-15 devnull if(r == nil)
199 1f8a8072 2005-03-15 devnull return -1;
200 6e527fbc 2005-02-13 devnull rpcrespondn(c, "ok", data, count);
201 6e527fbc 2005-02-13 devnull return 0;
202 6e527fbc 2005-02-13 devnull }
203 6e527fbc 2005-02-13 devnull
204 6e527fbc 2005-02-13 devnull /* print to the conversation */
205 6e527fbc 2005-02-13 devnull int
206 6e527fbc 2005-02-13 devnull convprint(Conv *c, char *fmt, ...)
207 6e527fbc 2005-02-13 devnull {
208 6e527fbc 2005-02-13 devnull char *s;
209 6e527fbc 2005-02-13 devnull va_list arg;
210 6e527fbc 2005-02-13 devnull int ret;
211 6e527fbc 2005-02-13 devnull
212 6e527fbc 2005-02-13 devnull va_start(arg, fmt);
213 6e527fbc 2005-02-13 devnull s = vsmprint(fmt, arg);
214 6e527fbc 2005-02-13 devnull va_end(arg);
215 6e527fbc 2005-02-13 devnull if(s == nil)
216 6e527fbc 2005-02-13 devnull return -1;
217 6e527fbc 2005-02-13 devnull ret = convwrite(c, s, strlen(s));
218 6e527fbc 2005-02-13 devnull free(s);
219 6e527fbc 2005-02-13 devnull return ret;
220 6e527fbc 2005-02-13 devnull }
221 6e527fbc 2005-02-13 devnull
222 6e527fbc 2005-02-13 devnull /* ask for a key */
223 6e527fbc 2005-02-13 devnull int
224 6e527fbc 2005-02-13 devnull convneedkey(Conv *c, Attr *a)
225 6e527fbc 2005-02-13 devnull {
226 6e527fbc 2005-02-13 devnull /*
227 6e527fbc 2005-02-13 devnull * Piggyback key requests in the usual RPC channel.
228 6e527fbc 2005-02-13 devnull * Wait for the next RPC and then send a key request
229 6e527fbc 2005-02-13 devnull * in response. The keys get added out-of-band (via the
230 6e527fbc 2005-02-13 devnull * ctl file), so assume the key has been added when the
231 6e527fbc 2005-02-13 devnull * next request comes in.
232 5f6612ba 2008-05-31 rsc *
233 5f6612ba 2008-05-31 rsc * The convgetrpc seems dodgy, because we might be in
234 5f6612ba 2008-05-31 rsc * the middle of an rpc, and what about the one that comes
235 5f6612ba 2008-05-31 rsc * in later? It's all actually okay: convgetrpc is idempotent
236 5f6612ba 2008-05-31 rsc * until rpcrespond is called, so if we're in the middle of an rpc,
237 5f6612ba 2008-05-31 rsc * the first convgetrpc is a no-op, the rpcrespond sends back
238 5f6612ba 2008-05-31 rsc * the needkey, and then the client repeats the rpc we're in
239 5f6612ba 2008-05-31 rsc * the middle of. Otherwise, if we're not in the middle of an
240 5f6612ba 2008-05-31 rsc * rpc, the first convgetrpc waits for one, we respond needkey,
241 5f6612ba 2008-05-31 rsc * and then the second convgetrpc waits for another. Because
242 5f6612ba 2008-05-31 rsc * there is no second response, eventually the caller will get
243 5f6612ba 2008-05-31 rsc * around to asking for an rpc itself, at which point the already
244 5f6612ba 2008-05-31 rsc * gotten rpc will be returned again.
245 6e527fbc 2005-02-13 devnull */
246 6e527fbc 2005-02-13 devnull if(convgetrpc(c, -1) == nil)
247 6e527fbc 2005-02-13 devnull return -1;
248 a2f6b810 2011-01-02 rsc if(conv->proto)
249 a2f6b810 2011-01-02 rsc a = addattrs(parseattr(c->proto->keyprompt), a);
250 5f6612ba 2008-05-31 rsc flog("convneedkey %A", a);
251 6e527fbc 2005-02-13 devnull rpcrespond(c, "needkey %A", a);
252 6e527fbc 2005-02-13 devnull if(convgetrpc(c, -1) == nil)
253 6e527fbc 2005-02-13 devnull return -1;
254 5f6612ba 2008-05-31 rsc flog("convneedkey returning");
255 6e527fbc 2005-02-13 devnull return 0;
256 6e527fbc 2005-02-13 devnull }
257 6e527fbc 2005-02-13 devnull
258 6e527fbc 2005-02-13 devnull /* ask for a replacement for a bad key*/
259 6e527fbc 2005-02-13 devnull int
260 6e527fbc 2005-02-13 devnull convbadkey(Conv *c, Key *k, char *msg, Attr *a)
261 6e527fbc 2005-02-13 devnull {
262 6e527fbc 2005-02-13 devnull if(convgetrpc(c, -1) == nil)
263 6e527fbc 2005-02-13 devnull return -1;
264 5f6612ba 2008-05-31 rsc flog("convbadkey %A %N / %s / %A", k->attr, k->privattr, msg, a);
265 6e527fbc 2005-02-13 devnull rpcrespond(c, "badkey %A %N\n%s\n%A",
266 6e527fbc 2005-02-13 devnull k->attr, k->privattr, msg, a);
267 6e527fbc 2005-02-13 devnull if(convgetrpc(c, -1) == nil)
268 6e527fbc 2005-02-13 devnull return -1;
269 6e527fbc 2005-02-13 devnull return 0;
270 6e527fbc 2005-02-13 devnull }
271 6e527fbc 2005-02-13 devnull