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