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