1c19800e8SDoug Rabson /*
2*ae771770SStanislav Sedov * Copyright (c) 2006 Kungliga Tekniska Högskolan
3c19800e8SDoug Rabson * (Royal Institute of Technology, Stockholm, Sweden).
4c19800e8SDoug Rabson * All rights reserved.
5c19800e8SDoug Rabson *
6c19800e8SDoug Rabson * Redistribution and use in source and binary forms, with or without
7c19800e8SDoug Rabson * modification, are permitted provided that the following conditions
8c19800e8SDoug Rabson * are met:
9c19800e8SDoug Rabson *
10c19800e8SDoug Rabson * 1. Redistributions of source code must retain the above copyright
11c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer.
12c19800e8SDoug Rabson *
13c19800e8SDoug Rabson * 2. Redistributions in binary form must reproduce the above copyright
14c19800e8SDoug Rabson * notice, this list of conditions and the following disclaimer in the
15c19800e8SDoug Rabson * documentation and/or other materials provided with the distribution.
16c19800e8SDoug Rabson *
17c19800e8SDoug Rabson * 3. Neither the name of KTH nor the names of its contributors may be
18c19800e8SDoug Rabson * used to endorse or promote products derived from this software without
19c19800e8SDoug Rabson * specific prior written permission.
20c19800e8SDoug Rabson *
21c19800e8SDoug Rabson * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22c19800e8SDoug Rabson * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23c19800e8SDoug Rabson * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24c19800e8SDoug Rabson * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25c19800e8SDoug Rabson * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26c19800e8SDoug Rabson * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27c19800e8SDoug Rabson * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28c19800e8SDoug Rabson * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29c19800e8SDoug Rabson * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30c19800e8SDoug Rabson * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31c19800e8SDoug Rabson * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
32c19800e8SDoug Rabson */
33c19800e8SDoug Rabson
34c19800e8SDoug Rabson #include <common.h>
35*ae771770SStanislav Sedov RCSID("$Id$");
36c19800e8SDoug Rabson
37c19800e8SDoug Rabson static FILE *logfile;
38c19800e8SDoug Rabson
39c19800e8SDoug Rabson /*
40c19800e8SDoug Rabson *
41c19800e8SDoug Rabson */
42c19800e8SDoug Rabson
43c19800e8SDoug Rabson struct client {
44c19800e8SDoug Rabson char *name;
45c19800e8SDoug Rabson struct sockaddr *sa;
46c19800e8SDoug Rabson socklen_t salen;
47c19800e8SDoug Rabson krb5_storage *sock;
48c19800e8SDoug Rabson int32_t capabilities;
49c19800e8SDoug Rabson char *target_name;
50c19800e8SDoug Rabson char *moniker;
51c19800e8SDoug Rabson krb5_storage *logsock;
52c19800e8SDoug Rabson int have_log;
53c19800e8SDoug Rabson #ifdef ENABLE_PTHREAD_SUPPORT
54c19800e8SDoug Rabson pthread_t thr;
55c19800e8SDoug Rabson #else
56c19800e8SDoug Rabson pid_t child;
57c19800e8SDoug Rabson #endif
58c19800e8SDoug Rabson };
59c19800e8SDoug Rabson
60c19800e8SDoug Rabson static struct client **clients;
61c19800e8SDoug Rabson static int num_clients;
62c19800e8SDoug Rabson
63c19800e8SDoug Rabson static int
init_sec_context(struct client * client,int32_t * hContext,int32_t * hCred,int32_t flags,const char * targetname,const krb5_data * itoken,krb5_data * otoken)64c19800e8SDoug Rabson init_sec_context(struct client *client,
65c19800e8SDoug Rabson int32_t *hContext, int32_t *hCred,
66c19800e8SDoug Rabson int32_t flags,
67c19800e8SDoug Rabson const char *targetname,
68c19800e8SDoug Rabson const krb5_data *itoken, krb5_data *otoken)
69c19800e8SDoug Rabson {
70c19800e8SDoug Rabson int32_t val;
71c19800e8SDoug Rabson krb5_data_zero(otoken);
72c19800e8SDoug Rabson put32(client, eInitContext);
73c19800e8SDoug Rabson put32(client, *hContext);
74c19800e8SDoug Rabson put32(client, *hCred);
75c19800e8SDoug Rabson put32(client, flags);
76c19800e8SDoug Rabson putstring(client, targetname);
77c19800e8SDoug Rabson putdata(client, *itoken);
78c19800e8SDoug Rabson ret32(client, *hContext);
79c19800e8SDoug Rabson ret32(client, val);
80c19800e8SDoug Rabson retdata(client, *otoken);
81c19800e8SDoug Rabson return val;
82c19800e8SDoug Rabson }
83c19800e8SDoug Rabson
84c19800e8SDoug Rabson static int
accept_sec_context(struct client * client,int32_t * hContext,int32_t flags,const krb5_data * itoken,krb5_data * otoken,int32_t * hDelegCred)85c19800e8SDoug Rabson accept_sec_context(struct client *client,
86c19800e8SDoug Rabson int32_t *hContext,
87c19800e8SDoug Rabson int32_t flags,
88c19800e8SDoug Rabson const krb5_data *itoken,
89c19800e8SDoug Rabson krb5_data *otoken,
90c19800e8SDoug Rabson int32_t *hDelegCred)
91c19800e8SDoug Rabson {
92c19800e8SDoug Rabson int32_t val;
93c19800e8SDoug Rabson krb5_data_zero(otoken);
94c19800e8SDoug Rabson put32(client, eAcceptContext);
95c19800e8SDoug Rabson put32(client, *hContext);
96c19800e8SDoug Rabson put32(client, flags);
97c19800e8SDoug Rabson putdata(client, *itoken);
98c19800e8SDoug Rabson ret32(client, *hContext);
99c19800e8SDoug Rabson ret32(client, val);
100c19800e8SDoug Rabson retdata(client, *otoken);
101c19800e8SDoug Rabson ret32(client, *hDelegCred);
102c19800e8SDoug Rabson return val;
103c19800e8SDoug Rabson }
104c19800e8SDoug Rabson
105c19800e8SDoug Rabson static int
acquire_cred(struct client * client,const char * username,const char * password,int32_t flags,int32_t * hCred)106c19800e8SDoug Rabson acquire_cred(struct client *client,
107c19800e8SDoug Rabson const char *username,
108c19800e8SDoug Rabson const char *password,
109c19800e8SDoug Rabson int32_t flags,
110c19800e8SDoug Rabson int32_t *hCred)
111c19800e8SDoug Rabson {
112c19800e8SDoug Rabson int32_t val;
113c19800e8SDoug Rabson put32(client, eAcquireCreds);
114c19800e8SDoug Rabson putstring(client, username);
115c19800e8SDoug Rabson putstring(client, password);
116c19800e8SDoug Rabson put32(client, flags);
117c19800e8SDoug Rabson ret32(client, val);
118c19800e8SDoug Rabson ret32(client, *hCred);
119c19800e8SDoug Rabson return val;
120c19800e8SDoug Rabson }
121c19800e8SDoug Rabson
122c19800e8SDoug Rabson static int
toast_resource(struct client * client,int32_t hCred)123c19800e8SDoug Rabson toast_resource(struct client *client,
124c19800e8SDoug Rabson int32_t hCred)
125c19800e8SDoug Rabson {
126c19800e8SDoug Rabson int32_t val;
127c19800e8SDoug Rabson put32(client, eToastResource);
128c19800e8SDoug Rabson put32(client, hCred);
129c19800e8SDoug Rabson ret32(client, val);
130c19800e8SDoug Rabson return val;
131c19800e8SDoug Rabson }
132c19800e8SDoug Rabson
133c19800e8SDoug Rabson static int
goodbye(struct client * client)134c19800e8SDoug Rabson goodbye(struct client *client)
135c19800e8SDoug Rabson {
136c19800e8SDoug Rabson put32(client, eGoodBye);
137c19800e8SDoug Rabson return GSMERR_OK;
138c19800e8SDoug Rabson }
139c19800e8SDoug Rabson
140c19800e8SDoug Rabson static int
get_targetname(struct client * client,char ** target)141c19800e8SDoug Rabson get_targetname(struct client *client,
142c19800e8SDoug Rabson char **target)
143c19800e8SDoug Rabson {
144c19800e8SDoug Rabson put32(client, eGetTargetName);
145c19800e8SDoug Rabson retstring(client, *target);
146c19800e8SDoug Rabson return GSMERR_OK;
147c19800e8SDoug Rabson }
148c19800e8SDoug Rabson
149c19800e8SDoug Rabson static int32_t
encrypt_token(struct client * client,int32_t hContext,int32_t flags,krb5_data * in,krb5_data * out)150c19800e8SDoug Rabson encrypt_token(struct client *client, int32_t hContext, int32_t flags,
151c19800e8SDoug Rabson krb5_data *in, krb5_data *out)
152c19800e8SDoug Rabson {
153c19800e8SDoug Rabson int32_t val;
154c19800e8SDoug Rabson put32(client, eEncrypt);
155c19800e8SDoug Rabson put32(client, hContext);
156c19800e8SDoug Rabson put32(client, flags);
157c19800e8SDoug Rabson put32(client, 0);
158c19800e8SDoug Rabson putdata(client, *in);
159c19800e8SDoug Rabson ret32(client, val);
160c19800e8SDoug Rabson retdata(client, *out);
161c19800e8SDoug Rabson return val;
162c19800e8SDoug Rabson }
163c19800e8SDoug Rabson
164c19800e8SDoug Rabson static int32_t
decrypt_token(struct client * client,int32_t hContext,int flags,krb5_data * in,krb5_data * out)165c19800e8SDoug Rabson decrypt_token(struct client *client, int32_t hContext, int flags,
166c19800e8SDoug Rabson krb5_data *in, krb5_data *out)
167c19800e8SDoug Rabson {
168c19800e8SDoug Rabson int32_t val;
169c19800e8SDoug Rabson put32(client, eDecrypt);
170c19800e8SDoug Rabson put32(client, hContext);
171c19800e8SDoug Rabson put32(client, flags);
172c19800e8SDoug Rabson put32(client, 0);
173c19800e8SDoug Rabson putdata(client, *in);
174c19800e8SDoug Rabson ret32(client, val);
175c19800e8SDoug Rabson retdata(client, *out);
176c19800e8SDoug Rabson return val;
177c19800e8SDoug Rabson }
178c19800e8SDoug Rabson
179c19800e8SDoug Rabson static int32_t
wrap_token_ext(struct client * client,int32_t hContext,int32_t flags,int32_t bflags,krb5_data * header,krb5_data * in,krb5_data * trailer,krb5_data * out)180*ae771770SStanislav Sedov wrap_token_ext(struct client *client, int32_t hContext, int32_t flags,
181*ae771770SStanislav Sedov int32_t bflags, krb5_data *header, krb5_data *in, krb5_data *trailer,
182*ae771770SStanislav Sedov krb5_data *out)
183*ae771770SStanislav Sedov {
184*ae771770SStanislav Sedov int32_t val;
185*ae771770SStanislav Sedov put32(client, eWrapExt);
186*ae771770SStanislav Sedov put32(client, hContext);
187*ae771770SStanislav Sedov put32(client, flags);
188*ae771770SStanislav Sedov put32(client, bflags);
189*ae771770SStanislav Sedov putdata(client, *header);
190*ae771770SStanislav Sedov putdata(client, *in);
191*ae771770SStanislav Sedov putdata(client, *trailer);
192*ae771770SStanislav Sedov ret32(client, val);
193*ae771770SStanislav Sedov retdata(client, *out);
194*ae771770SStanislav Sedov return val;
195*ae771770SStanislav Sedov }
196*ae771770SStanislav Sedov
197*ae771770SStanislav Sedov static int32_t
unwrap_token_ext(struct client * client,int32_t hContext,int32_t flags,int32_t bflags,krb5_data * header,krb5_data * in,krb5_data * trailer,krb5_data * out)198*ae771770SStanislav Sedov unwrap_token_ext(struct client *client, int32_t hContext, int32_t flags,
199*ae771770SStanislav Sedov int32_t bflags, krb5_data *header, krb5_data *in, krb5_data *trailer,
200*ae771770SStanislav Sedov krb5_data *out)
201*ae771770SStanislav Sedov {
202*ae771770SStanislav Sedov int32_t val;
203*ae771770SStanislav Sedov put32(client, eUnwrapExt);
204*ae771770SStanislav Sedov put32(client, hContext);
205*ae771770SStanislav Sedov put32(client, flags);
206*ae771770SStanislav Sedov put32(client, bflags);
207*ae771770SStanislav Sedov putdata(client, *header);
208*ae771770SStanislav Sedov putdata(client, *in);
209*ae771770SStanislav Sedov putdata(client, *trailer);
210*ae771770SStanislav Sedov ret32(client, val);
211*ae771770SStanislav Sedov retdata(client, *out);
212*ae771770SStanislav Sedov return val;
213*ae771770SStanislav Sedov }
214*ae771770SStanislav Sedov
215*ae771770SStanislav Sedov static int32_t
get_mic(struct client * client,int32_t hContext,krb5_data * in,krb5_data * mic)216c19800e8SDoug Rabson get_mic(struct client *client, int32_t hContext,
217c19800e8SDoug Rabson krb5_data *in, krb5_data *mic)
218c19800e8SDoug Rabson {
219c19800e8SDoug Rabson int32_t val;
220c19800e8SDoug Rabson put32(client, eSign);
221c19800e8SDoug Rabson put32(client, hContext);
222c19800e8SDoug Rabson put32(client, 0);
223c19800e8SDoug Rabson put32(client, 0);
224c19800e8SDoug Rabson putdata(client, *in);
225c19800e8SDoug Rabson ret32(client, val);
226c19800e8SDoug Rabson retdata(client, *mic);
227c19800e8SDoug Rabson return val;
228c19800e8SDoug Rabson }
229c19800e8SDoug Rabson
230c19800e8SDoug Rabson static int32_t
verify_mic(struct client * client,int32_t hContext,krb5_data * in,krb5_data * mic)231c19800e8SDoug Rabson verify_mic(struct client *client, int32_t hContext,
232c19800e8SDoug Rabson krb5_data *in, krb5_data *mic)
233c19800e8SDoug Rabson {
234c19800e8SDoug Rabson int32_t val;
235c19800e8SDoug Rabson put32(client, eVerify);
236c19800e8SDoug Rabson put32(client, hContext);
237c19800e8SDoug Rabson put32(client, 0);
238c19800e8SDoug Rabson put32(client, 0);
239c19800e8SDoug Rabson putdata(client, *in);
240c19800e8SDoug Rabson putdata(client, *mic);
241c19800e8SDoug Rabson ret32(client, val);
242c19800e8SDoug Rabson return val;
243c19800e8SDoug Rabson }
244c19800e8SDoug Rabson
245c19800e8SDoug Rabson
246c19800e8SDoug Rabson static int32_t
get_version_capa(struct client * client,int32_t * version,int32_t * capa,char ** version_str)247c19800e8SDoug Rabson get_version_capa(struct client *client,
248c19800e8SDoug Rabson int32_t *version, int32_t *capa,
249c19800e8SDoug Rabson char **version_str)
250c19800e8SDoug Rabson {
251c19800e8SDoug Rabson put32(client, eGetVersionAndCapabilities);
252c19800e8SDoug Rabson ret32(client, *version);
253c19800e8SDoug Rabson ret32(client, *capa);
254c19800e8SDoug Rabson retstring(client, *version_str);
255c19800e8SDoug Rabson return GSMERR_OK;
256c19800e8SDoug Rabson }
257c19800e8SDoug Rabson
258c19800e8SDoug Rabson static int32_t
get_moniker(struct client * client,char ** moniker)259c19800e8SDoug Rabson get_moniker(struct client *client,
260c19800e8SDoug Rabson char **moniker)
261c19800e8SDoug Rabson {
262c19800e8SDoug Rabson put32(client, eGetMoniker);
263c19800e8SDoug Rabson retstring(client, *moniker);
264c19800e8SDoug Rabson return GSMERR_OK;
265c19800e8SDoug Rabson }
266c19800e8SDoug Rabson
267c19800e8SDoug Rabson static int
wait_log(struct client * c)268c19800e8SDoug Rabson wait_log(struct client *c)
269c19800e8SDoug Rabson {
270c19800e8SDoug Rabson int32_t port;
271c19800e8SDoug Rabson struct sockaddr_storage sast;
272c19800e8SDoug Rabson socklen_t salen = sizeof(sast);
273c19800e8SDoug Rabson int fd, fd2, ret;
274c19800e8SDoug Rabson
275c19800e8SDoug Rabson memset(&sast, 0, sizeof(sast));
276c19800e8SDoug Rabson
277c19800e8SDoug Rabson assert(sizeof(sast) >= c->salen);
278c19800e8SDoug Rabson
279c19800e8SDoug Rabson fd = socket(c->sa->sa_family, SOCK_STREAM, 0);
280c19800e8SDoug Rabson if (fd < 0)
281c19800e8SDoug Rabson err(1, "failed to build socket for %s's logging port", c->moniker);
282c19800e8SDoug Rabson
283c19800e8SDoug Rabson ((struct sockaddr *)&sast)->sa_family = c->sa->sa_family;
284c19800e8SDoug Rabson ret = bind(fd, (struct sockaddr *)&sast, c->salen);
285c19800e8SDoug Rabson if (ret < 0)
286c19800e8SDoug Rabson err(1, "failed to bind %s's logging port", c->moniker);
287c19800e8SDoug Rabson
288c19800e8SDoug Rabson if (listen(fd, SOMAXCONN) < 0)
289c19800e8SDoug Rabson err(1, "failed to listen %s's logging port", c->moniker);
290c19800e8SDoug Rabson
291c19800e8SDoug Rabson salen = sizeof(sast);
292c19800e8SDoug Rabson ret = getsockname(fd, (struct sockaddr *)&sast, &salen);
293c19800e8SDoug Rabson if (ret < 0)
294c19800e8SDoug Rabson err(1, "failed to get address of local socket for %s", c->moniker);
295c19800e8SDoug Rabson
296c19800e8SDoug Rabson port = socket_get_port((struct sockaddr *)&sast);
297c19800e8SDoug Rabson
298c19800e8SDoug Rabson put32(c, eSetLoggingSocket);
299c19800e8SDoug Rabson put32(c, ntohs(port));
300c19800e8SDoug Rabson
301c19800e8SDoug Rabson salen = sizeof(sast);
302c19800e8SDoug Rabson fd2 = accept(fd, (struct sockaddr *)&sast, &salen);
303c19800e8SDoug Rabson if (fd2 < 0)
304c19800e8SDoug Rabson err(1, "failed to accept local socket for %s", c->moniker);
305c19800e8SDoug Rabson close(fd);
306c19800e8SDoug Rabson
307c19800e8SDoug Rabson return fd2;
308c19800e8SDoug Rabson }
309c19800e8SDoug Rabson
310c19800e8SDoug Rabson
311c19800e8SDoug Rabson
312c19800e8SDoug Rabson
313c19800e8SDoug Rabson static int
build_context(struct client * ipeer,struct client * apeer,int32_t flags,int32_t hCred,int32_t * iContext,int32_t * aContext,int32_t * hDelegCred)314c19800e8SDoug Rabson build_context(struct client *ipeer, struct client *apeer,
315c19800e8SDoug Rabson int32_t flags, int32_t hCred,
316c19800e8SDoug Rabson int32_t *iContext, int32_t *aContext, int32_t *hDelegCred)
317c19800e8SDoug Rabson {
318c19800e8SDoug Rabson int32_t val = GSMERR_ERROR, ic = 0, ac = 0, deleg = 0;
319c19800e8SDoug Rabson krb5_data itoken, otoken;
320c19800e8SDoug Rabson int iDone = 0, aDone = 0;
321c19800e8SDoug Rabson int step = 0;
322c19800e8SDoug Rabson int first_call = 0x80;
323c19800e8SDoug Rabson
324c19800e8SDoug Rabson if (apeer->target_name == NULL)
325c19800e8SDoug Rabson errx(1, "apeer %s have no target name", apeer->name);
326c19800e8SDoug Rabson
327c19800e8SDoug Rabson krb5_data_zero(&itoken);
328c19800e8SDoug Rabson
329c19800e8SDoug Rabson while (!iDone || !aDone) {
330c19800e8SDoug Rabson
331c19800e8SDoug Rabson if (iDone) {
332c19800e8SDoug Rabson warnx("iPeer already done, aPeer want extra rtt");
333c19800e8SDoug Rabson val = GSMERR_ERROR;
334c19800e8SDoug Rabson goto out;
335c19800e8SDoug Rabson }
336c19800e8SDoug Rabson
337c19800e8SDoug Rabson val = init_sec_context(ipeer, &ic, &hCred, flags|first_call,
338c19800e8SDoug Rabson apeer->target_name, &itoken, &otoken);
339c19800e8SDoug Rabson step++;
340c19800e8SDoug Rabson switch(val) {
341c19800e8SDoug Rabson case GSMERR_OK:
342c19800e8SDoug Rabson iDone = 1;
343c19800e8SDoug Rabson if (aDone)
344c19800e8SDoug Rabson continue;
345c19800e8SDoug Rabson break;
346c19800e8SDoug Rabson case GSMERR_CONTINUE_NEEDED:
347c19800e8SDoug Rabson break;
348c19800e8SDoug Rabson default:
349c19800e8SDoug Rabson warnx("iPeer %s failed with %d (step %d)",
350c19800e8SDoug Rabson ipeer->name, (int)val, step);
351c19800e8SDoug Rabson goto out;
352c19800e8SDoug Rabson }
353c19800e8SDoug Rabson
354c19800e8SDoug Rabson if (aDone) {
355c19800e8SDoug Rabson warnx("aPeer already done, iPeer want extra rtt");
356c19800e8SDoug Rabson val = GSMERR_ERROR;
357c19800e8SDoug Rabson goto out;
358c19800e8SDoug Rabson }
359c19800e8SDoug Rabson
360c19800e8SDoug Rabson val = accept_sec_context(apeer, &ac, flags|first_call,
361c19800e8SDoug Rabson &otoken, &itoken, &deleg);
362c19800e8SDoug Rabson step++;
363c19800e8SDoug Rabson switch(val) {
364c19800e8SDoug Rabson case GSMERR_OK:
365c19800e8SDoug Rabson aDone = 1;
366c19800e8SDoug Rabson if (iDone)
367c19800e8SDoug Rabson continue;
368c19800e8SDoug Rabson break;
369c19800e8SDoug Rabson case GSMERR_CONTINUE_NEEDED:
370c19800e8SDoug Rabson break;
371c19800e8SDoug Rabson default:
372c19800e8SDoug Rabson warnx("aPeer %s failed with %d (step %d)",
373c19800e8SDoug Rabson apeer->name, (int)val, step);
374c19800e8SDoug Rabson val = GSMERR_ERROR;
375c19800e8SDoug Rabson goto out;
376c19800e8SDoug Rabson }
377c19800e8SDoug Rabson first_call = 0;
378c19800e8SDoug Rabson val = GSMERR_OK;
379c19800e8SDoug Rabson }
380c19800e8SDoug Rabson
381c19800e8SDoug Rabson if (iContext == NULL || val != GSMERR_OK) {
382c19800e8SDoug Rabson if (ic)
383c19800e8SDoug Rabson toast_resource(ipeer, ic);
384c19800e8SDoug Rabson if (iContext)
385c19800e8SDoug Rabson *iContext = 0;
386c19800e8SDoug Rabson } else
387c19800e8SDoug Rabson *iContext = ic;
388c19800e8SDoug Rabson
389c19800e8SDoug Rabson if (aContext == NULL || val != GSMERR_OK) {
390c19800e8SDoug Rabson if (ac)
391c19800e8SDoug Rabson toast_resource(apeer, ac);
392c19800e8SDoug Rabson if (aContext)
393c19800e8SDoug Rabson *aContext = 0;
394c19800e8SDoug Rabson } else
395c19800e8SDoug Rabson *aContext = ac;
396c19800e8SDoug Rabson
397c19800e8SDoug Rabson if (hDelegCred == NULL || val != GSMERR_OK) {
398c19800e8SDoug Rabson if (deleg)
399c19800e8SDoug Rabson toast_resource(apeer, deleg);
400c19800e8SDoug Rabson if (hDelegCred)
401c19800e8SDoug Rabson *hDelegCred = 0;
402c19800e8SDoug Rabson } else
403c19800e8SDoug Rabson *hDelegCred = deleg;
404c19800e8SDoug Rabson
405c19800e8SDoug Rabson out:
406c19800e8SDoug Rabson return val;
407c19800e8SDoug Rabson }
408c19800e8SDoug Rabson
409c19800e8SDoug Rabson static void
test_mic(struct client * c1,int32_t hc1,struct client * c2,int32_t hc2)410c19800e8SDoug Rabson test_mic(struct client *c1, int32_t hc1, struct client *c2, int32_t hc2)
411c19800e8SDoug Rabson {
412c19800e8SDoug Rabson krb5_data msg, mic;
413c19800e8SDoug Rabson int32_t val;
414c19800e8SDoug Rabson
415c19800e8SDoug Rabson msg.data = "foo";
416c19800e8SDoug Rabson msg.length = 3;
417c19800e8SDoug Rabson
418c19800e8SDoug Rabson krb5_data_zero(&mic);
419c19800e8SDoug Rabson
420c19800e8SDoug Rabson val = get_mic(c1, hc1, &msg, &mic);
421c19800e8SDoug Rabson if (val)
422c19800e8SDoug Rabson errx(1, "get_mic failed to host: %s", c1->moniker);
423c19800e8SDoug Rabson val = verify_mic(c2, hc2, &msg, &mic);
424c19800e8SDoug Rabson if (val)
425c19800e8SDoug Rabson errx(1, "verify_mic failed to host: %s", c2->moniker);
426c19800e8SDoug Rabson
427c19800e8SDoug Rabson krb5_data_free(&mic);
428c19800e8SDoug Rabson }
429c19800e8SDoug Rabson
430c19800e8SDoug Rabson static int32_t
test_wrap(struct client * c1,int32_t hc1,struct client * c2,int32_t hc2,int conf)431c19800e8SDoug Rabson test_wrap(struct client *c1, int32_t hc1, struct client *c2, int32_t hc2,
432c19800e8SDoug Rabson int conf)
433c19800e8SDoug Rabson {
434c19800e8SDoug Rabson krb5_data msg, wrapped, out;
435c19800e8SDoug Rabson int32_t val;
436c19800e8SDoug Rabson
437c19800e8SDoug Rabson msg.data = "foo";
438c19800e8SDoug Rabson msg.length = 3;
439c19800e8SDoug Rabson
440c19800e8SDoug Rabson krb5_data_zero(&wrapped);
441c19800e8SDoug Rabson krb5_data_zero(&out);
442c19800e8SDoug Rabson
443c19800e8SDoug Rabson val = encrypt_token(c1, hc1, conf, &msg, &wrapped);
444c19800e8SDoug Rabson if (val) {
445c19800e8SDoug Rabson warnx("encrypt_token failed to host: %s", c1->moniker);
446c19800e8SDoug Rabson return val;
447c19800e8SDoug Rabson }
448c19800e8SDoug Rabson val = decrypt_token(c2, hc2, conf, &wrapped, &out);
449c19800e8SDoug Rabson if (val) {
450c19800e8SDoug Rabson krb5_data_free(&wrapped);
451c19800e8SDoug Rabson warnx("decrypt_token failed to host: %s", c2->moniker);
452c19800e8SDoug Rabson return val;
453c19800e8SDoug Rabson }
454c19800e8SDoug Rabson
455c19800e8SDoug Rabson if (msg.length != out.length) {
456c19800e8SDoug Rabson warnx("decrypted'ed token have wrong length (%lu != %lu)",
457c19800e8SDoug Rabson (unsigned long)msg.length, (unsigned long)out.length);
458c19800e8SDoug Rabson val = GSMERR_ERROR;
459c19800e8SDoug Rabson } else if (memcmp(msg.data, out.data, msg.length) != 0) {
460c19800e8SDoug Rabson warnx("decryptd'ed token have wrong data");
461c19800e8SDoug Rabson val = GSMERR_ERROR;
462c19800e8SDoug Rabson }
463c19800e8SDoug Rabson
464c19800e8SDoug Rabson krb5_data_free(&wrapped);
465c19800e8SDoug Rabson krb5_data_free(&out);
466c19800e8SDoug Rabson return val;
467c19800e8SDoug Rabson }
468c19800e8SDoug Rabson
469c19800e8SDoug Rabson static int32_t
test_wrap_ext(struct client * c1,int32_t hc1,struct client * c2,int32_t hc2,int conf,int bflags)470*ae771770SStanislav Sedov test_wrap_ext(struct client *c1, int32_t hc1, struct client *c2, int32_t hc2,
471*ae771770SStanislav Sedov int conf, int bflags)
472*ae771770SStanislav Sedov {
473*ae771770SStanislav Sedov krb5_data header, msg, trailer, wrapped, out;
474*ae771770SStanislav Sedov int32_t val;
475*ae771770SStanislav Sedov
476*ae771770SStanislav Sedov header.data = "header";
477*ae771770SStanislav Sedov header.length = 6;
478*ae771770SStanislav Sedov
479*ae771770SStanislav Sedov msg.data = "0123456789abcdef"; /* padded for most enctypes */
480*ae771770SStanislav Sedov msg.length = 32;
481*ae771770SStanislav Sedov
482*ae771770SStanislav Sedov trailer.data = "trailer";
483*ae771770SStanislav Sedov trailer.length = 7;
484*ae771770SStanislav Sedov
485*ae771770SStanislav Sedov krb5_data_zero(&wrapped);
486*ae771770SStanislav Sedov krb5_data_zero(&out);
487*ae771770SStanislav Sedov
488*ae771770SStanislav Sedov val = wrap_token_ext(c1, hc1, conf, bflags, &header, &msg, &trailer, &wrapped);
489*ae771770SStanislav Sedov if (val) {
490*ae771770SStanislav Sedov warnx("encrypt_token failed to host: %s", c1->moniker);
491*ae771770SStanislav Sedov return val;
492*ae771770SStanislav Sedov }
493*ae771770SStanislav Sedov val = unwrap_token_ext(c2, hc2, conf, bflags, &header, &wrapped, &trailer, &out);
494*ae771770SStanislav Sedov if (val) {
495*ae771770SStanislav Sedov krb5_data_free(&wrapped);
496*ae771770SStanislav Sedov warnx("decrypt_token failed to host: %s", c2->moniker);
497*ae771770SStanislav Sedov return val;
498*ae771770SStanislav Sedov }
499*ae771770SStanislav Sedov
500*ae771770SStanislav Sedov if (msg.length != out.length) {
501*ae771770SStanislav Sedov warnx("decrypted'ed token have wrong length (%lu != %lu)",
502*ae771770SStanislav Sedov (unsigned long)msg.length, (unsigned long)out.length);
503*ae771770SStanislav Sedov val = GSMERR_ERROR;
504*ae771770SStanislav Sedov } else if (memcmp(msg.data, out.data, msg.length) != 0) {
505*ae771770SStanislav Sedov warnx("decryptd'ed token have wrong data");
506*ae771770SStanislav Sedov val = GSMERR_ERROR;
507*ae771770SStanislav Sedov }
508*ae771770SStanislav Sedov
509*ae771770SStanislav Sedov krb5_data_free(&wrapped);
510*ae771770SStanislav Sedov krb5_data_free(&out);
511*ae771770SStanislav Sedov return val;
512*ae771770SStanislav Sedov }
513*ae771770SStanislav Sedov
514*ae771770SStanislav Sedov
515*ae771770SStanislav Sedov static int32_t
test_token(struct client * c1,int32_t hc1,struct client * c2,int32_t hc2,int wrap_ext)516*ae771770SStanislav Sedov test_token(struct client *c1, int32_t hc1, struct client *c2, int32_t hc2, int wrap_ext)
517c19800e8SDoug Rabson {
518c19800e8SDoug Rabson int32_t val;
519c19800e8SDoug Rabson int i;
520c19800e8SDoug Rabson
521c19800e8SDoug Rabson for (i = 0; i < 10; i++) {
522*ae771770SStanislav Sedov /* mic */
523c19800e8SDoug Rabson test_mic(c1, hc1, c2, hc2);
524c19800e8SDoug Rabson test_mic(c2, hc2, c1, hc1);
525*ae771770SStanislav Sedov
526*ae771770SStanislav Sedov /* wrap */
527c19800e8SDoug Rabson val = test_wrap(c1, hc1, c2, hc2, 0);
528c19800e8SDoug Rabson if (val) return val;
529c19800e8SDoug Rabson val = test_wrap(c2, hc2, c1, hc1, 0);
530c19800e8SDoug Rabson if (val) return val;
531*ae771770SStanislav Sedov
532c19800e8SDoug Rabson val = test_wrap(c1, hc1, c2, hc2, 1);
533c19800e8SDoug Rabson if (val) return val;
534c19800e8SDoug Rabson val = test_wrap(c2, hc2, c1, hc1, 1);
535c19800e8SDoug Rabson if (val) return val;
536*ae771770SStanislav Sedov
537*ae771770SStanislav Sedov if (wrap_ext) {
538*ae771770SStanislav Sedov /* wrap ext */
539*ae771770SStanislav Sedov val = test_wrap_ext(c1, hc1, c2, hc2, 1, 0);
540*ae771770SStanislav Sedov if (val) return val;
541*ae771770SStanislav Sedov val = test_wrap_ext(c2, hc2, c1, hc1, 1, 0);
542*ae771770SStanislav Sedov if (val) return val;
543*ae771770SStanislav Sedov
544*ae771770SStanislav Sedov val = test_wrap_ext(c1, hc1, c2, hc2, 1, 1);
545*ae771770SStanislav Sedov if (val) return val;
546*ae771770SStanislav Sedov val = test_wrap_ext(c2, hc2, c1, hc1, 1, 1);
547*ae771770SStanislav Sedov if (val) return val;
548*ae771770SStanislav Sedov
549*ae771770SStanislav Sedov val = test_wrap_ext(c1, hc1, c2, hc2, 0, 0);
550*ae771770SStanislav Sedov if (val) return val;
551*ae771770SStanislav Sedov val = test_wrap_ext(c2, hc2, c1, hc1, 0, 0);
552*ae771770SStanislav Sedov if (val) return val;
553*ae771770SStanislav Sedov
554*ae771770SStanislav Sedov val = test_wrap_ext(c1, hc1, c2, hc2, 0, 1);
555*ae771770SStanislav Sedov if (val) return val;
556*ae771770SStanislav Sedov val = test_wrap_ext(c2, hc2, c1, hc1, 0, 1);
557*ae771770SStanislav Sedov if (val) return val;
558*ae771770SStanislav Sedov }
559c19800e8SDoug Rabson }
560c19800e8SDoug Rabson return GSMERR_OK;
561c19800e8SDoug Rabson }
562c19800e8SDoug Rabson
563c19800e8SDoug Rabson static int
log_function(void * ptr)564c19800e8SDoug Rabson log_function(void *ptr)
565c19800e8SDoug Rabson {
566c19800e8SDoug Rabson struct client *c = ptr;
567c19800e8SDoug Rabson int32_t cmd, line;
568c19800e8SDoug Rabson char *file, *string;
569c19800e8SDoug Rabson
570c19800e8SDoug Rabson while (1) {
571c19800e8SDoug Rabson if (krb5_ret_int32(c->logsock, &cmd))
572c19800e8SDoug Rabson goto out;
573c19800e8SDoug Rabson
574c19800e8SDoug Rabson switch (cmd) {
575c19800e8SDoug Rabson case eLogSetMoniker:
576c19800e8SDoug Rabson if (krb5_ret_string(c->logsock, &file))
577c19800e8SDoug Rabson goto out;
578c19800e8SDoug Rabson free(file);
579c19800e8SDoug Rabson break;
580c19800e8SDoug Rabson case eLogInfo:
581c19800e8SDoug Rabson case eLogFailure:
582c19800e8SDoug Rabson if (krb5_ret_string(c->logsock, &file))
583c19800e8SDoug Rabson goto out;
584c19800e8SDoug Rabson if (krb5_ret_int32(c->logsock, &line))
585c19800e8SDoug Rabson goto out;
586c19800e8SDoug Rabson if (krb5_ret_string(c->logsock, &string))
587c19800e8SDoug Rabson goto out;
588c19800e8SDoug Rabson printf("%s:%lu: %s\n",
589c19800e8SDoug Rabson file, (unsigned long)line, string);
590c19800e8SDoug Rabson fprintf(logfile, "%s:%lu: %s\n",
591c19800e8SDoug Rabson file, (unsigned long)line, string);
592c19800e8SDoug Rabson fflush(logfile);
593c19800e8SDoug Rabson free(file);
594c19800e8SDoug Rabson free(string);
595c19800e8SDoug Rabson if (krb5_store_int32(c->logsock, 0))
596c19800e8SDoug Rabson goto out;
597c19800e8SDoug Rabson break;
598c19800e8SDoug Rabson default:
599c19800e8SDoug Rabson errx(1, "client send bad log command: %d", (int)cmd);
600c19800e8SDoug Rabson }
601c19800e8SDoug Rabson }
602c19800e8SDoug Rabson out:
603c19800e8SDoug Rabson
604c19800e8SDoug Rabson return 0;
605c19800e8SDoug Rabson }
606c19800e8SDoug Rabson
607c19800e8SDoug Rabson static void
connect_client(const char * slave)608c19800e8SDoug Rabson connect_client(const char *slave)
609c19800e8SDoug Rabson {
610c19800e8SDoug Rabson char *name, *port;
611c19800e8SDoug Rabson struct client *c = ecalloc(1, sizeof(*c));
612c19800e8SDoug Rabson struct addrinfo hints, *res0, *res;
613c19800e8SDoug Rabson int ret, fd;
614c19800e8SDoug Rabson
615c19800e8SDoug Rabson name = estrdup(slave);
616c19800e8SDoug Rabson port = strchr(name, ':');
617c19800e8SDoug Rabson if (port == NULL)
618c19800e8SDoug Rabson errx(1, "port missing from %s", name);
619c19800e8SDoug Rabson *port++ = 0;
620c19800e8SDoug Rabson
621c19800e8SDoug Rabson c->name = estrdup(slave);
622c19800e8SDoug Rabson
623c19800e8SDoug Rabson memset(&hints, 0, sizeof(hints));
624c19800e8SDoug Rabson hints.ai_family = PF_UNSPEC;
625c19800e8SDoug Rabson hints.ai_socktype = SOCK_STREAM;
626c19800e8SDoug Rabson
627c19800e8SDoug Rabson ret = getaddrinfo(name, port, &hints, &res0);
628c19800e8SDoug Rabson if (ret)
629c19800e8SDoug Rabson errx(1, "error resolving %s", name);
630c19800e8SDoug Rabson
631c19800e8SDoug Rabson for (res = res0, fd = -1; res; res = res->ai_next) {
632c19800e8SDoug Rabson fd = socket(res->ai_family, res->ai_socktype, res->ai_protocol);
633c19800e8SDoug Rabson if (fd < 0)
634c19800e8SDoug Rabson continue;
635c19800e8SDoug Rabson if (connect(fd, res->ai_addr, res->ai_addrlen) < 0) {
636c19800e8SDoug Rabson close(fd);
637c19800e8SDoug Rabson fd = -1;
638c19800e8SDoug Rabson continue;
639c19800e8SDoug Rabson }
640c19800e8SDoug Rabson c->sa = ecalloc(1, res->ai_addrlen);
641c19800e8SDoug Rabson memcpy(c->sa, res->ai_addr, res->ai_addrlen);
642c19800e8SDoug Rabson c->salen = res->ai_addrlen;
643c19800e8SDoug Rabson break; /* okay we got one */
644c19800e8SDoug Rabson }
645c19800e8SDoug Rabson if (fd < 0)
646c19800e8SDoug Rabson err(1, "connect to host: %s", name);
647c19800e8SDoug Rabson freeaddrinfo(res);
648c19800e8SDoug Rabson
649c19800e8SDoug Rabson c->sock = krb5_storage_from_fd(fd);
650c19800e8SDoug Rabson close(fd);
651c19800e8SDoug Rabson if (c->sock == NULL)
652c19800e8SDoug Rabson errx(1, "krb5_storage_from_fd");
653c19800e8SDoug Rabson
654c19800e8SDoug Rabson {
655c19800e8SDoug Rabson int32_t version;
656c19800e8SDoug Rabson char *str = NULL;
657c19800e8SDoug Rabson get_version_capa(c, &version, &c->capabilities, &str);
658c19800e8SDoug Rabson if (str) {
659c19800e8SDoug Rabson free(str);
660c19800e8SDoug Rabson }
661c19800e8SDoug Rabson if (c->capabilities & HAS_MONIKER)
662c19800e8SDoug Rabson get_moniker(c, &c->moniker);
663c19800e8SDoug Rabson else
664c19800e8SDoug Rabson c->moniker = c->name;
665c19800e8SDoug Rabson if (c->capabilities & ISSERVER)
666c19800e8SDoug Rabson get_targetname(c, &c->target_name);
667c19800e8SDoug Rabson }
668c19800e8SDoug Rabson
669c19800e8SDoug Rabson if (logfile) {
670c19800e8SDoug Rabson int fd;
671c19800e8SDoug Rabson
672c19800e8SDoug Rabson printf("starting log socket to client %s\n", c->moniker);
673c19800e8SDoug Rabson
674c19800e8SDoug Rabson fd = wait_log(c);
675c19800e8SDoug Rabson
676c19800e8SDoug Rabson c->logsock = krb5_storage_from_fd(fd);
677c19800e8SDoug Rabson close(fd);
678c19800e8SDoug Rabson if (c->logsock == NULL)
679c19800e8SDoug Rabson errx(1, "failed to create log krb5_storage");
680c19800e8SDoug Rabson #ifdef ENABLE_PTHREAD_SUPPORT
681c19800e8SDoug Rabson pthread_create(&c->thr, NULL, log_function, c);
682c19800e8SDoug Rabson #else
683c19800e8SDoug Rabson c->child = fork();
684c19800e8SDoug Rabson if (c->child == -1)
685c19800e8SDoug Rabson errx(1, "failed to fork");
686c19800e8SDoug Rabson else if (c->child == 0) {
687c19800e8SDoug Rabson log_function(c);
688c19800e8SDoug Rabson fclose(logfile);
689c19800e8SDoug Rabson exit(0);
690c19800e8SDoug Rabson }
691c19800e8SDoug Rabson #endif
692c19800e8SDoug Rabson }
693c19800e8SDoug Rabson
694c19800e8SDoug Rabson
695c19800e8SDoug Rabson clients = erealloc(clients, (num_clients + 1) * sizeof(*clients));
696c19800e8SDoug Rabson
697c19800e8SDoug Rabson clients[num_clients] = c;
698c19800e8SDoug Rabson num_clients++;
699c19800e8SDoug Rabson
700c19800e8SDoug Rabson free(name);
701c19800e8SDoug Rabson }
702c19800e8SDoug Rabson
703c19800e8SDoug Rabson static struct client *
get_client(const char * slave)704c19800e8SDoug Rabson get_client(const char *slave)
705c19800e8SDoug Rabson {
706c19800e8SDoug Rabson size_t i;
707c19800e8SDoug Rabson for (i = 0; i < num_clients; i++)
708c19800e8SDoug Rabson if (strcmp(slave, clients[i]->name) == 0)
709c19800e8SDoug Rabson return clients[i];
710c19800e8SDoug Rabson errx(1, "failed to find client %s", slave);
711c19800e8SDoug Rabson }
712c19800e8SDoug Rabson
713c19800e8SDoug Rabson /*
714c19800e8SDoug Rabson *
715c19800e8SDoug Rabson */
716c19800e8SDoug Rabson
717c19800e8SDoug Rabson static int version_flag;
718c19800e8SDoug Rabson static int help_flag;
719*ae771770SStanislav Sedov static int wrap_ext = 0;
720c19800e8SDoug Rabson static char *logfile_str;
721c19800e8SDoug Rabson static getarg_strings principals;
722c19800e8SDoug Rabson static getarg_strings slaves;
723c19800e8SDoug Rabson
724c19800e8SDoug Rabson struct getargs args[] = {
725c19800e8SDoug Rabson { "principals", 0, arg_strings, &principals, "Test principal",
726c19800e8SDoug Rabson NULL },
727c19800e8SDoug Rabson { "slaves", 0, arg_strings, &slaves, "Slaves",
728c19800e8SDoug Rabson NULL },
729c19800e8SDoug Rabson { "log-file", 0, arg_string, &logfile_str, "Logfile",
730c19800e8SDoug Rabson NULL },
731*ae771770SStanislav Sedov { "wrap-ext", 0, arg_flag, &wrap_ext, "test wrap extended",
732*ae771770SStanislav Sedov NULL },
733c19800e8SDoug Rabson { "version", 0, arg_flag, &version_flag, "Print version",
734c19800e8SDoug Rabson NULL },
735c19800e8SDoug Rabson { "help", 0, arg_flag, &help_flag, NULL,
736c19800e8SDoug Rabson NULL }
737c19800e8SDoug Rabson };
738c19800e8SDoug Rabson
739c19800e8SDoug Rabson static void
usage(int ret)740c19800e8SDoug Rabson usage(int ret)
741c19800e8SDoug Rabson {
742c19800e8SDoug Rabson arg_printusage (args,
743c19800e8SDoug Rabson sizeof(args) / sizeof(args[0]),
744c19800e8SDoug Rabson NULL,
745c19800e8SDoug Rabson "");
746c19800e8SDoug Rabson exit (ret);
747c19800e8SDoug Rabson }
748c19800e8SDoug Rabson
749c19800e8SDoug Rabson int
main(int argc,char ** argv)750c19800e8SDoug Rabson main(int argc, char **argv)
751c19800e8SDoug Rabson {
752c19800e8SDoug Rabson int optidx= 0;
753c19800e8SDoug Rabson char *user;
754c19800e8SDoug Rabson char *password;
755c19800e8SDoug Rabson char ***list, **p;
756c19800e8SDoug Rabson size_t num_list, i, j, k;
757c19800e8SDoug Rabson int failed = 0;
758c19800e8SDoug Rabson
759c19800e8SDoug Rabson setprogname (argv[0]);
760c19800e8SDoug Rabson
761c19800e8SDoug Rabson if (getarg (args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
762c19800e8SDoug Rabson usage (1);
763c19800e8SDoug Rabson
764c19800e8SDoug Rabson if (help_flag)
765c19800e8SDoug Rabson usage (0);
766c19800e8SDoug Rabson
767c19800e8SDoug Rabson if (version_flag) {
768c19800e8SDoug Rabson print_version (NULL);
769c19800e8SDoug Rabson return 0;
770c19800e8SDoug Rabson }
771c19800e8SDoug Rabson
772c19800e8SDoug Rabson if (optidx != argc)
773c19800e8SDoug Rabson usage (1);
774c19800e8SDoug Rabson
775c19800e8SDoug Rabson if (principals.num_strings == 0)
776c19800e8SDoug Rabson errx(1, "no principals");
777c19800e8SDoug Rabson
778c19800e8SDoug Rabson user = estrdup(principals.strings[0]);
779c19800e8SDoug Rabson password = strchr(user, ':');
780c19800e8SDoug Rabson if (password == NULL)
781c19800e8SDoug Rabson errx(1, "password missing from %s", user);
782c19800e8SDoug Rabson *password++ = 0;
783c19800e8SDoug Rabson
784c19800e8SDoug Rabson if (slaves.num_strings == 0)
785c19800e8SDoug Rabson errx(1, "no principals");
786c19800e8SDoug Rabson
787c19800e8SDoug Rabson if (logfile_str) {
788c19800e8SDoug Rabson printf("open logfile %s\n", logfile_str);
789c19800e8SDoug Rabson logfile = fopen(logfile_str, "w+");
790c19800e8SDoug Rabson if (logfile == NULL)
791c19800e8SDoug Rabson err(1, "failed to open: %s", logfile_str);
792c19800e8SDoug Rabson }
793c19800e8SDoug Rabson
794c19800e8SDoug Rabson /*
795c19800e8SDoug Rabson *
796c19800e8SDoug Rabson */
797c19800e8SDoug Rabson
798c19800e8SDoug Rabson list = permutate_all(&slaves, &num_list);
799c19800e8SDoug Rabson
800c19800e8SDoug Rabson /*
801c19800e8SDoug Rabson * Set up connection to all clients
802c19800e8SDoug Rabson */
803c19800e8SDoug Rabson
804c19800e8SDoug Rabson printf("Connecting to slaves\n");
805c19800e8SDoug Rabson for (i = 0; i < slaves.num_strings; i++)
806c19800e8SDoug Rabson connect_client(slaves.strings[i]);
807c19800e8SDoug Rabson
808c19800e8SDoug Rabson /*
809c19800e8SDoug Rabson * Test acquire credentials
810c19800e8SDoug Rabson */
811c19800e8SDoug Rabson
812c19800e8SDoug Rabson printf("Test acquire credentials\n");
813c19800e8SDoug Rabson for (i = 0; i < slaves.num_strings; i++) {
814c19800e8SDoug Rabson int32_t hCred, val;
815c19800e8SDoug Rabson
816c19800e8SDoug Rabson val = acquire_cred(clients[i], user, password, 1, &hCred);
817c19800e8SDoug Rabson if (val != GSMERR_OK) {
818c19800e8SDoug Rabson warnx("Failed to acquire_cred on host %s: %d",
819c19800e8SDoug Rabson clients[i]->moniker, (int)val);
820c19800e8SDoug Rabson failed = 1;
821c19800e8SDoug Rabson } else
822c19800e8SDoug Rabson toast_resource(clients[i], hCred);
823c19800e8SDoug Rabson }
824c19800e8SDoug Rabson
825c19800e8SDoug Rabson if (failed)
826c19800e8SDoug Rabson goto out;
827c19800e8SDoug Rabson
828c19800e8SDoug Rabson /*
829c19800e8SDoug Rabson * First test if all slaves can build context to them-self.
830c19800e8SDoug Rabson */
831c19800e8SDoug Rabson
832c19800e8SDoug Rabson printf("Self context tests\n");
833c19800e8SDoug Rabson for (i = 0; i < num_clients; i++) {
834c19800e8SDoug Rabson int32_t hCred, val, delegCred;
835c19800e8SDoug Rabson int32_t clientC, serverC;
836c19800e8SDoug Rabson struct client *c = clients[i];
837c19800e8SDoug Rabson
838c19800e8SDoug Rabson if (c->target_name == NULL)
839c19800e8SDoug Rabson continue;
840c19800e8SDoug Rabson
841c19800e8SDoug Rabson printf("%s connects to self using %s\n",
842c19800e8SDoug Rabson c->moniker, c->target_name);
843c19800e8SDoug Rabson
844c19800e8SDoug Rabson val = acquire_cred(c, user, password, 1, &hCred);
845c19800e8SDoug Rabson if (val != GSMERR_OK)
846c19800e8SDoug Rabson errx(1, "failed to acquire_cred: %d", (int)val);
847c19800e8SDoug Rabson
848c19800e8SDoug Rabson val = build_context(c, c,
849c19800e8SDoug Rabson GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG|
850c19800e8SDoug Rabson GSS_C_INTEG_FLAG|GSS_C_CONF_FLAG|
851c19800e8SDoug Rabson GSS_C_DELEG_FLAG|GSS_C_MUTUAL_FLAG,
852c19800e8SDoug Rabson hCred, &clientC, &serverC, &delegCred);
853c19800e8SDoug Rabson if (val == GSMERR_OK) {
854*ae771770SStanislav Sedov test_token(c, clientC, c, serverC, wrap_ext);
855c19800e8SDoug Rabson toast_resource(c, clientC);
856c19800e8SDoug Rabson toast_resource(c, serverC);
857c19800e8SDoug Rabson if (delegCred)
858c19800e8SDoug Rabson toast_resource(c, delegCred);
859c19800e8SDoug Rabson } else {
860c19800e8SDoug Rabson warnx("build_context failed: %d", (int)val);
861c19800e8SDoug Rabson }
862c19800e8SDoug Rabson /*
863c19800e8SDoug Rabson *
864c19800e8SDoug Rabson */
865c19800e8SDoug Rabson
866c19800e8SDoug Rabson val = build_context(c, c,
867c19800e8SDoug Rabson GSS_C_INTEG_FLAG|GSS_C_CONF_FLAG,
868c19800e8SDoug Rabson hCred, &clientC, &serverC, &delegCred);
869c19800e8SDoug Rabson if (val == GSMERR_OK) {
870*ae771770SStanislav Sedov test_token(c, clientC, c, serverC, wrap_ext);
871c19800e8SDoug Rabson toast_resource(c, clientC);
872c19800e8SDoug Rabson toast_resource(c, serverC);
873c19800e8SDoug Rabson if (delegCred)
874c19800e8SDoug Rabson toast_resource(c, delegCred);
875c19800e8SDoug Rabson } else {
876c19800e8SDoug Rabson warnx("build_context failed: %d", (int)val);
877c19800e8SDoug Rabson }
878c19800e8SDoug Rabson
879c19800e8SDoug Rabson toast_resource(c, hCred);
880c19800e8SDoug Rabson }
881c19800e8SDoug Rabson /*
882c19800e8SDoug Rabson * Build contexts though all entries in each lists, including the
883c19800e8SDoug Rabson * step from the last entry to the first, ie treat the list as a
884c19800e8SDoug Rabson * circle.
885c19800e8SDoug Rabson *
886c19800e8SDoug Rabson * Only follow the delegated credential, but test "all"
887c19800e8SDoug Rabson * flags. (XXX only do deleg|mutual right now.
888c19800e8SDoug Rabson */
889c19800e8SDoug Rabson
890c19800e8SDoug Rabson printf("\"All\" permutation tests\n");
891c19800e8SDoug Rabson
892c19800e8SDoug Rabson for (i = 0; i < num_list; i++) {
893c19800e8SDoug Rabson int32_t hCred, val, delegCred = 0;
894c19800e8SDoug Rabson int32_t clientC = 0, serverC = 0;
895c19800e8SDoug Rabson struct client *client, *server;
896c19800e8SDoug Rabson
897c19800e8SDoug Rabson p = list[i];
898c19800e8SDoug Rabson
899c19800e8SDoug Rabson client = get_client(p[0]);
900c19800e8SDoug Rabson
901c19800e8SDoug Rabson val = acquire_cred(client, user, password, 1, &hCred);
902c19800e8SDoug Rabson if (val != GSMERR_OK)
903c19800e8SDoug Rabson errx(1, "failed to acquire_cred: %d", (int)val);
904c19800e8SDoug Rabson
905c19800e8SDoug Rabson for (j = 1; j < num_clients + 1; j++) {
906c19800e8SDoug Rabson server = get_client(p[j % num_clients]);
907c19800e8SDoug Rabson
908c19800e8SDoug Rabson if (server->target_name == NULL)
909c19800e8SDoug Rabson break;
910c19800e8SDoug Rabson
911c19800e8SDoug Rabson for (k = 1; k < j; k++)
912c19800e8SDoug Rabson printf("\t");
913c19800e8SDoug Rabson printf("%s -> %s\n", client->moniker, server->moniker);
914c19800e8SDoug Rabson
915c19800e8SDoug Rabson val = build_context(client, server,
916c19800e8SDoug Rabson GSS_C_REPLAY_FLAG|GSS_C_SEQUENCE_FLAG|
917c19800e8SDoug Rabson GSS_C_INTEG_FLAG|GSS_C_CONF_FLAG|
918c19800e8SDoug Rabson GSS_C_DELEG_FLAG|GSS_C_MUTUAL_FLAG,
919c19800e8SDoug Rabson hCred, &clientC, &serverC, &delegCred);
920c19800e8SDoug Rabson if (val != GSMERR_OK) {
921c19800e8SDoug Rabson warnx("build_context failed: %d", (int)val);
922c19800e8SDoug Rabson break;
923c19800e8SDoug Rabson }
924c19800e8SDoug Rabson
925*ae771770SStanislav Sedov val = test_token(client, clientC, server, serverC, wrap_ext);
926c19800e8SDoug Rabson if (val)
927c19800e8SDoug Rabson break;
928c19800e8SDoug Rabson
929c19800e8SDoug Rabson toast_resource(client, clientC);
930c19800e8SDoug Rabson toast_resource(server, serverC);
931c19800e8SDoug Rabson if (!delegCred) {
932c19800e8SDoug Rabson warnx("no delegated cred on %s", server->moniker);
933c19800e8SDoug Rabson break;
934c19800e8SDoug Rabson }
935c19800e8SDoug Rabson toast_resource(client, hCred);
936c19800e8SDoug Rabson hCred = delegCred;
937c19800e8SDoug Rabson client = server;
938c19800e8SDoug Rabson }
939c19800e8SDoug Rabson if (hCred)
940c19800e8SDoug Rabson toast_resource(client, hCred);
941c19800e8SDoug Rabson }
942c19800e8SDoug Rabson
943c19800e8SDoug Rabson /*
944c19800e8SDoug Rabson * Close all connections to clients
945c19800e8SDoug Rabson */
946c19800e8SDoug Rabson
947c19800e8SDoug Rabson out:
948c19800e8SDoug Rabson printf("sending goodbye and waiting for log sockets\n");
949c19800e8SDoug Rabson for (i = 0; i < num_clients; i++) {
950c19800e8SDoug Rabson goodbye(clients[i]);
951c19800e8SDoug Rabson if (clients[i]->logsock) {
952c19800e8SDoug Rabson #ifdef ENABLE_PTHREAD_SUPPORT
953c19800e8SDoug Rabson pthread_join(&clients[i]->thr, NULL);
954c19800e8SDoug Rabson #else
955c19800e8SDoug Rabson waitpid(clients[i]->child, NULL, 0);
956c19800e8SDoug Rabson #endif
957c19800e8SDoug Rabson }
958c19800e8SDoug Rabson }
959c19800e8SDoug Rabson
960c19800e8SDoug Rabson printf("done\n");
961c19800e8SDoug Rabson
962c19800e8SDoug Rabson return 0;
963c19800e8SDoug Rabson }
964