17c478bd9Sstevel@tonic-gate /* 27c478bd9Sstevel@tonic-gate * lib/krb5/krb/chk_trans.c 37c478bd9Sstevel@tonic-gate * 47c478bd9Sstevel@tonic-gate * Copyright 2001 by the Massachusetts Institute of Technology. 57c478bd9Sstevel@tonic-gate * All Rights Reserved. 67c478bd9Sstevel@tonic-gate * 77c478bd9Sstevel@tonic-gate * Export of this software from the United States of America may 87c478bd9Sstevel@tonic-gate * require a specific license from the United States Government. 97c478bd9Sstevel@tonic-gate * It is the responsibility of any person or organization contemplating 107c478bd9Sstevel@tonic-gate * export to obtain such a license before exporting. 117c478bd9Sstevel@tonic-gate * 127c478bd9Sstevel@tonic-gate * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and 137c478bd9Sstevel@tonic-gate * distribute this software and its documentation for any purpose and 147c478bd9Sstevel@tonic-gate * without fee is hereby granted, provided that the above copyright 157c478bd9Sstevel@tonic-gate * notice appear in all copies and that both that copyright notice and 167c478bd9Sstevel@tonic-gate * this permission notice appear in supporting documentation, and that 177c478bd9Sstevel@tonic-gate * the name of M.I.T. not be used in advertising or publicity pertaining 187c478bd9Sstevel@tonic-gate * to distribution of the software without specific, written prior 197c478bd9Sstevel@tonic-gate * permission. Furthermore if you modify this software you must label 207c478bd9Sstevel@tonic-gate * your software as modified software and not distribute it in such a 217c478bd9Sstevel@tonic-gate * fashion that it might be confused with the original M.I.T. software. 227c478bd9Sstevel@tonic-gate * M.I.T. makes no representations about the suitability of 237c478bd9Sstevel@tonic-gate * this software for any purpose. It is provided "as is" without express 247c478bd9Sstevel@tonic-gate * or implied warranty. 257c478bd9Sstevel@tonic-gate * 267c478bd9Sstevel@tonic-gate * 277c478bd9Sstevel@tonic-gate * krb5_check_transited_list() 287c478bd9Sstevel@tonic-gate */ 29*159d09a2SMark Phalan #include "k5-int.h" 307c478bd9Sstevel@tonic-gate #include <stdarg.h> 317c478bd9Sstevel@tonic-gate 32*159d09a2SMark Phalan #if defined (TEST) || defined (TEST2) 33*159d09a2SMark Phalan # undef DEBUG 34*159d09a2SMark Phalan # define DEBUG 35*159d09a2SMark Phalan #endif 36*159d09a2SMark Phalan 37*159d09a2SMark Phalan #ifdef DEBUG 38*159d09a2SMark Phalan #define verbose krb5int_chk_trans_verbose 39*159d09a2SMark Phalan static int verbose = 0; 40*159d09a2SMark Phalan # define Tprintf(ARGS) if (verbose) printf ARGS 41*159d09a2SMark Phalan #else 42*159d09a2SMark Phalan # define Tprintf(ARGS) (void)(0) 43*159d09a2SMark Phalan #endif 44*159d09a2SMark Phalan 457c478bd9Sstevel@tonic-gate #define MAXLEN 512 467c478bd9Sstevel@tonic-gate 477c478bd9Sstevel@tonic-gate static krb5_error_code 487c478bd9Sstevel@tonic-gate process_intermediates (krb5_error_code (*fn)(krb5_data *, void *), void *data, 497c478bd9Sstevel@tonic-gate const krb5_data *n1, const krb5_data *n2) { 507c478bd9Sstevel@tonic-gate unsigned int len1, len2, i; 517c478bd9Sstevel@tonic-gate char *p1, *p2; 527c478bd9Sstevel@tonic-gate 53*159d09a2SMark Phalan Tprintf (("process_intermediates(%.*s,%.*s)\n", 54*159d09a2SMark Phalan (int) n1->length, n1->data, (int) n2->length, n2->data)); 55*159d09a2SMark Phalan 567c478bd9Sstevel@tonic-gate len1 = n1->length; 577c478bd9Sstevel@tonic-gate len2 = n2->length; 587c478bd9Sstevel@tonic-gate 59*159d09a2SMark Phalan Tprintf (("(walking intermediates now)\n")); 607c478bd9Sstevel@tonic-gate /* Simplify... */ 617c478bd9Sstevel@tonic-gate if (len1 > len2) { 627c478bd9Sstevel@tonic-gate const krb5_data *p; 637c478bd9Sstevel@tonic-gate int tmp = len1; 647c478bd9Sstevel@tonic-gate len1 = len2; 657c478bd9Sstevel@tonic-gate len2 = tmp; 667c478bd9Sstevel@tonic-gate p = n1; 677c478bd9Sstevel@tonic-gate n1 = n2; 687c478bd9Sstevel@tonic-gate n2 = p; 697c478bd9Sstevel@tonic-gate } 707c478bd9Sstevel@tonic-gate /* Okay, now len1 is always shorter or equal. */ 717c478bd9Sstevel@tonic-gate if (len1 == len2) { 727c478bd9Sstevel@tonic-gate if (memcmp (n1->data, n2->data, len1)) { 73*159d09a2SMark Phalan Tprintf (("equal length but different strings in path: '%.*s' '%.*s'\n", 74*159d09a2SMark Phalan (int) n1->length, n1->data, (int) n2->length, n2->data)); 757c478bd9Sstevel@tonic-gate return KRB5KRB_AP_ERR_ILL_CR_TKT; 767c478bd9Sstevel@tonic-gate } 77*159d09a2SMark Phalan Tprintf (("(end intermediates)\n")); 787c478bd9Sstevel@tonic-gate return 0; 797c478bd9Sstevel@tonic-gate } 807c478bd9Sstevel@tonic-gate /* Now len1 is always shorter. */ 817c478bd9Sstevel@tonic-gate if (len1 == 0) 827c478bd9Sstevel@tonic-gate /* Shouldn't be possible. Internal error? */ 837c478bd9Sstevel@tonic-gate return KRB5KRB_AP_ERR_ILL_CR_TKT; 847c478bd9Sstevel@tonic-gate p1 = n1->data; 857c478bd9Sstevel@tonic-gate p2 = n2->data; 867c478bd9Sstevel@tonic-gate if (p1[0] == '/') { 877c478bd9Sstevel@tonic-gate /* X.500 style names, with common prefix. */ 887c478bd9Sstevel@tonic-gate if (p2[0] != '/') { 89*159d09a2SMark Phalan Tprintf (("mixed name formats in path: x500='%.*s' domain='%.*s'\n", 90*159d09a2SMark Phalan (int) len1, p1, (int) len2, p2)); 917c478bd9Sstevel@tonic-gate return KRB5KRB_AP_ERR_ILL_CR_TKT; 927c478bd9Sstevel@tonic-gate } 937c478bd9Sstevel@tonic-gate if (memcmp (p1, p2, len1)) { 94*159d09a2SMark Phalan Tprintf (("x500 names with different prefixes '%.*s' '%.*s'\n", 95*159d09a2SMark Phalan (int) len1, p1, (int) len2, p2)); 967c478bd9Sstevel@tonic-gate return KRB5KRB_AP_ERR_ILL_CR_TKT; 977c478bd9Sstevel@tonic-gate } 987c478bd9Sstevel@tonic-gate for (i = len1 + 1; i < len2; i++) 997c478bd9Sstevel@tonic-gate if (p2[i] == '/') { 1007c478bd9Sstevel@tonic-gate krb5_data d; 1017c478bd9Sstevel@tonic-gate krb5_error_code r; 1027c478bd9Sstevel@tonic-gate 1037c478bd9Sstevel@tonic-gate d.data = p2; 1047c478bd9Sstevel@tonic-gate d.length = i; 1057c478bd9Sstevel@tonic-gate r = (*fn) (&d, data); 1067c478bd9Sstevel@tonic-gate if (r) 1077c478bd9Sstevel@tonic-gate return r; 1087c478bd9Sstevel@tonic-gate } 1097c478bd9Sstevel@tonic-gate } else { 1107c478bd9Sstevel@tonic-gate /* Domain style names, with common suffix. */ 1117c478bd9Sstevel@tonic-gate if (p2[0] == '/') { 112*159d09a2SMark Phalan Tprintf (("mixed name formats in path: domain='%.*s' x500='%.*s'\n", 113*159d09a2SMark Phalan (int) len1, p1, (int) len2, p2)); 1147c478bd9Sstevel@tonic-gate return KRB5KRB_AP_ERR_ILL_CR_TKT; 1157c478bd9Sstevel@tonic-gate } 1167c478bd9Sstevel@tonic-gate if (memcmp (p1, p2 + (len2 - len1), len1)) { 117*159d09a2SMark Phalan Tprintf (("domain names with different suffixes '%.*s' '%.*s'\n", 118*159d09a2SMark Phalan (int) len1, p1, (int) len2, p2)); 1197c478bd9Sstevel@tonic-gate return KRB5KRB_AP_ERR_ILL_CR_TKT; 1207c478bd9Sstevel@tonic-gate } 1217c478bd9Sstevel@tonic-gate for (i = len2 - len1 - 1; i > 0; i--) { 122*159d09a2SMark Phalan Tprintf (("looking at '%.*s'\n", (int) (len2 - i), p2+i)); 1237c478bd9Sstevel@tonic-gate if (p2[i-1] == '.') { 1247c478bd9Sstevel@tonic-gate krb5_data d; 1257c478bd9Sstevel@tonic-gate krb5_error_code r; 1267c478bd9Sstevel@tonic-gate 1277c478bd9Sstevel@tonic-gate d.data = p2+i; 1287c478bd9Sstevel@tonic-gate d.length = len2 - i; 1297c478bd9Sstevel@tonic-gate r = (*fn) (&d, data); 1307c478bd9Sstevel@tonic-gate if (r) 1317c478bd9Sstevel@tonic-gate return r; 1327c478bd9Sstevel@tonic-gate } 1337c478bd9Sstevel@tonic-gate } 1347c478bd9Sstevel@tonic-gate } 135*159d09a2SMark Phalan Tprintf (("(end intermediates)\n")); 1367c478bd9Sstevel@tonic-gate return 0; 1377c478bd9Sstevel@tonic-gate } 1387c478bd9Sstevel@tonic-gate 1397c478bd9Sstevel@tonic-gate static krb5_error_code 1407c478bd9Sstevel@tonic-gate maybe_join (krb5_data *last, krb5_data *buf, int bufsiz) 1417c478bd9Sstevel@tonic-gate { 1427c478bd9Sstevel@tonic-gate if (buf->length == 0) 1437c478bd9Sstevel@tonic-gate return 0; 1447c478bd9Sstevel@tonic-gate if (buf->data[0] == '/') { 1457c478bd9Sstevel@tonic-gate if (last->length + buf->length > bufsiz) { 146*159d09a2SMark Phalan Tprintf (("too big: last=%d cur=%d max=%d\n", last->length, buf->length, bufsiz)); 1477c478bd9Sstevel@tonic-gate return KRB5KRB_AP_ERR_ILL_CR_TKT; 1487c478bd9Sstevel@tonic-gate } 1497c478bd9Sstevel@tonic-gate memmove (buf->data+last->length, buf->data, buf->length); 1507c478bd9Sstevel@tonic-gate memcpy (buf->data, last->data, last->length); 1517c478bd9Sstevel@tonic-gate buf->length += last->length; 1527c478bd9Sstevel@tonic-gate } else if (buf->data[buf->length-1] == '.') { 1537c478bd9Sstevel@tonic-gate /* We can ignore the case where the previous component was 1547c478bd9Sstevel@tonic-gate empty; the strcat will be a no-op. It should probably 1557c478bd9Sstevel@tonic-gate be an error case, but let's be flexible. */ 1567c478bd9Sstevel@tonic-gate if (last->length+buf->length > bufsiz) { 157*159d09a2SMark Phalan Tprintf (("too big\n")); 1587c478bd9Sstevel@tonic-gate return KRB5KRB_AP_ERR_ILL_CR_TKT; 1597c478bd9Sstevel@tonic-gate } 1607c478bd9Sstevel@tonic-gate memcpy (buf->data + buf->length, last->data, last->length); 1617c478bd9Sstevel@tonic-gate buf->length += last->length; 1627c478bd9Sstevel@tonic-gate } 1637c478bd9Sstevel@tonic-gate /* Otherwise, do nothing. */ 1647c478bd9Sstevel@tonic-gate return 0; 1657c478bd9Sstevel@tonic-gate } 1667c478bd9Sstevel@tonic-gate 1677c478bd9Sstevel@tonic-gate /* The input strings cannot contain any \0 bytes, according to the 1687c478bd9Sstevel@tonic-gate spec, but our API is such that they may not be \0 terminated 1697c478bd9Sstevel@tonic-gate either. Thus we keep on treating them as krb5_data objects instead 1707c478bd9Sstevel@tonic-gate of C strings. */ 1717c478bd9Sstevel@tonic-gate static krb5_error_code 1727c478bd9Sstevel@tonic-gate foreach_realm (krb5_error_code (*fn)(krb5_data *comp,void *data), void *data, 1737c478bd9Sstevel@tonic-gate const krb5_data *crealm, const krb5_data *srealm, 1747c478bd9Sstevel@tonic-gate const krb5_data *transit) 1757c478bd9Sstevel@tonic-gate { 1767c478bd9Sstevel@tonic-gate char buf[MAXLEN], last[MAXLEN]; 1777c478bd9Sstevel@tonic-gate char *p, *bufp; 1787c478bd9Sstevel@tonic-gate int next_lit, intermediates, l; 1797c478bd9Sstevel@tonic-gate krb5_data this_component; 1807c478bd9Sstevel@tonic-gate krb5_error_code r; 1817c478bd9Sstevel@tonic-gate krb5_data last_component; 1827c478bd9Sstevel@tonic-gate 1837c478bd9Sstevel@tonic-gate /* Invariants: 1847c478bd9Sstevel@tonic-gate - last_component points to last[] 1857c478bd9Sstevel@tonic-gate - this_component points to buf[] 1867c478bd9Sstevel@tonic-gate - last_component has length of last 1877c478bd9Sstevel@tonic-gate - this_component has length of buf when calling out 1887c478bd9Sstevel@tonic-gate Keep these consistent, and we should be okay. */ 1897c478bd9Sstevel@tonic-gate 1907c478bd9Sstevel@tonic-gate next_lit = 0; 1917c478bd9Sstevel@tonic-gate intermediates = 0; 1927c478bd9Sstevel@tonic-gate memset (buf, 0, sizeof (buf)); 1937c478bd9Sstevel@tonic-gate 1947c478bd9Sstevel@tonic-gate this_component.data = buf; 1957c478bd9Sstevel@tonic-gate last_component.data = last; 1967c478bd9Sstevel@tonic-gate last_component.length = 0; 1977c478bd9Sstevel@tonic-gate 198*159d09a2SMark Phalan #define print_data(fmt,d) Tprintf((fmt,(int)(d)->length,(d)->data)) 199*159d09a2SMark Phalan print_data ("client realm: %.*s\n", crealm); 200*159d09a2SMark Phalan print_data ("server realm: %.*s\n", srealm); 201*159d09a2SMark Phalan print_data ("transit enc.: %.*s\n", transit); 202*159d09a2SMark Phalan 2037c478bd9Sstevel@tonic-gate if (transit->length == 0) { 204*159d09a2SMark Phalan Tprintf (("no other realms transited\n")); 2057c478bd9Sstevel@tonic-gate return 0; 2067c478bd9Sstevel@tonic-gate } 2077c478bd9Sstevel@tonic-gate 2087c478bd9Sstevel@tonic-gate bufp = buf; 2097c478bd9Sstevel@tonic-gate for (p = transit->data, l = transit->length; l; p++, l--) { 2107c478bd9Sstevel@tonic-gate if (next_lit) { 2117c478bd9Sstevel@tonic-gate *bufp++ = *p; 2127c478bd9Sstevel@tonic-gate if (bufp == buf+sizeof(buf)) 2137c478bd9Sstevel@tonic-gate return KRB5KRB_AP_ERR_ILL_CR_TKT; 2147c478bd9Sstevel@tonic-gate next_lit = 0; 2157c478bd9Sstevel@tonic-gate } else if (*p == '\\') { 2167c478bd9Sstevel@tonic-gate next_lit = 1; 2177c478bd9Sstevel@tonic-gate } else if (*p == ',') { 2187c478bd9Sstevel@tonic-gate if (bufp != buf) { 2197c478bd9Sstevel@tonic-gate this_component.length = bufp - buf; 2207c478bd9Sstevel@tonic-gate r = maybe_join (&last_component, &this_component, sizeof(buf)); 2217c478bd9Sstevel@tonic-gate if (r) 2227c478bd9Sstevel@tonic-gate return r; 2237c478bd9Sstevel@tonic-gate r = (*fn) (&this_component, data); 2247c478bd9Sstevel@tonic-gate if (r) 2257c478bd9Sstevel@tonic-gate return r; 2267c478bd9Sstevel@tonic-gate if (intermediates) { 2277c478bd9Sstevel@tonic-gate if (p == transit->data) 2287c478bd9Sstevel@tonic-gate r = process_intermediates (fn, data, 2297c478bd9Sstevel@tonic-gate &this_component, crealm); 2307c478bd9Sstevel@tonic-gate else { 2317c478bd9Sstevel@tonic-gate r = process_intermediates (fn, data, &this_component, 2327c478bd9Sstevel@tonic-gate &last_component); 2337c478bd9Sstevel@tonic-gate } 2347c478bd9Sstevel@tonic-gate if (r) 2357c478bd9Sstevel@tonic-gate return r; 2367c478bd9Sstevel@tonic-gate } 2377c478bd9Sstevel@tonic-gate intermediates = 0; 2387c478bd9Sstevel@tonic-gate memcpy (last, buf, sizeof (buf)); 2397c478bd9Sstevel@tonic-gate last_component.length = this_component.length; 2407c478bd9Sstevel@tonic-gate memset (buf, 0, sizeof (buf)); 2417c478bd9Sstevel@tonic-gate bufp = buf; 2427c478bd9Sstevel@tonic-gate } else { 2437c478bd9Sstevel@tonic-gate intermediates = 1; 2447c478bd9Sstevel@tonic-gate if (p == transit->data) { 2457c478bd9Sstevel@tonic-gate if (crealm->length >= MAXLEN) 2467c478bd9Sstevel@tonic-gate return KRB5KRB_AP_ERR_ILL_CR_TKT; 2477c478bd9Sstevel@tonic-gate memcpy (last, crealm->data, crealm->length); 2487c478bd9Sstevel@tonic-gate last[crealm->length] = '\0'; 2497c478bd9Sstevel@tonic-gate last_component.length = crealm->length; 2507c478bd9Sstevel@tonic-gate } 2517c478bd9Sstevel@tonic-gate } 2527c478bd9Sstevel@tonic-gate } else if (*p == ' ' && bufp == buf) { 2537c478bd9Sstevel@tonic-gate /* This next component stands alone, even if it has a 2547c478bd9Sstevel@tonic-gate trailing dot or leading slash. */ 2557c478bd9Sstevel@tonic-gate memset (last, 0, sizeof (last)); 2567c478bd9Sstevel@tonic-gate last_component.length = 0; 2577c478bd9Sstevel@tonic-gate } else { 2587c478bd9Sstevel@tonic-gate /* Not a special character; literal. */ 2597c478bd9Sstevel@tonic-gate *bufp++ = *p; 2607c478bd9Sstevel@tonic-gate if (bufp == buf+sizeof(buf)) 2617c478bd9Sstevel@tonic-gate return KRB5KRB_AP_ERR_ILL_CR_TKT; 2627c478bd9Sstevel@tonic-gate } 2637c478bd9Sstevel@tonic-gate } 2647c478bd9Sstevel@tonic-gate /* At end. Must be normal state. */ 265*159d09a2SMark Phalan if (next_lit) 266*159d09a2SMark Phalan Tprintf (("ending in next-char-literal state\n")); 2677c478bd9Sstevel@tonic-gate /* Process trailing element or comma. */ 2687c478bd9Sstevel@tonic-gate if (bufp == buf) { 2697c478bd9Sstevel@tonic-gate /* Trailing comma. */ 2707c478bd9Sstevel@tonic-gate r = process_intermediates (fn, data, &last_component, srealm); 2717c478bd9Sstevel@tonic-gate } else { 2727c478bd9Sstevel@tonic-gate /* Trailing component. */ 2737c478bd9Sstevel@tonic-gate this_component.length = bufp - buf; 2747c478bd9Sstevel@tonic-gate r = maybe_join (&last_component, &this_component, sizeof(buf)); 2757c478bd9Sstevel@tonic-gate if (r) 2767c478bd9Sstevel@tonic-gate return r; 2777c478bd9Sstevel@tonic-gate r = (*fn) (&this_component, data); 2787c478bd9Sstevel@tonic-gate if (r) 2797c478bd9Sstevel@tonic-gate return r; 2807c478bd9Sstevel@tonic-gate if (intermediates) 2817c478bd9Sstevel@tonic-gate r = process_intermediates (fn, data, &this_component, 2827c478bd9Sstevel@tonic-gate &last_component); 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate if (r != 0) 2857c478bd9Sstevel@tonic-gate return r; 2867c478bd9Sstevel@tonic-gate return 0; 2877c478bd9Sstevel@tonic-gate } 2887c478bd9Sstevel@tonic-gate 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate struct check_data { 2917c478bd9Sstevel@tonic-gate krb5_context ctx; 2927c478bd9Sstevel@tonic-gate krb5_principal *tgs; 2937c478bd9Sstevel@tonic-gate }; 2947c478bd9Sstevel@tonic-gate 2957c478bd9Sstevel@tonic-gate static int 2967c478bd9Sstevel@tonic-gate same_data (krb5_data *d1, krb5_data *d2) 2977c478bd9Sstevel@tonic-gate { 2987c478bd9Sstevel@tonic-gate return (d1->length == d2->length 2997c478bd9Sstevel@tonic-gate && !memcmp (d1->data, d2->data, d1->length)); 3007c478bd9Sstevel@tonic-gate } 3017c478bd9Sstevel@tonic-gate 3027c478bd9Sstevel@tonic-gate static krb5_error_code 3037c478bd9Sstevel@tonic-gate check_realm_in_list (krb5_data *realm, void *data) 3047c478bd9Sstevel@tonic-gate { 3057c478bd9Sstevel@tonic-gate struct check_data *cdata = data; 3067c478bd9Sstevel@tonic-gate int i; 3077c478bd9Sstevel@tonic-gate 308*159d09a2SMark Phalan Tprintf ((".. checking '%.*s'\n", (int) realm->length, realm->data)); 3097c478bd9Sstevel@tonic-gate for (i = 0; cdata->tgs[i]; i++) { 3107c478bd9Sstevel@tonic-gate if (same_data (krb5_princ_realm (cdata->ctx, cdata->tgs[i]), realm)) 3117c478bd9Sstevel@tonic-gate return 0; 3127c478bd9Sstevel@tonic-gate } 313*159d09a2SMark Phalan Tprintf (("BAD!\n")); 3147c478bd9Sstevel@tonic-gate return KRB5KRB_AP_ERR_ILL_CR_TKT; 3157c478bd9Sstevel@tonic-gate } 3167c478bd9Sstevel@tonic-gate 3177c478bd9Sstevel@tonic-gate krb5_error_code 318505d05c7Sgtb krb5_check_transited_list (krb5_context ctx, const krb5_data *trans_in, 3197c478bd9Sstevel@tonic-gate const krb5_data *crealm, const krb5_data *srealm) 3207c478bd9Sstevel@tonic-gate { 3217c478bd9Sstevel@tonic-gate krb5_data trans; 3227c478bd9Sstevel@tonic-gate struct check_data cdata; 3237c478bd9Sstevel@tonic-gate krb5_error_code r; 3247c478bd9Sstevel@tonic-gate 3257c478bd9Sstevel@tonic-gate trans.length = trans_in->length; 3267c478bd9Sstevel@tonic-gate trans.data = (char *) trans_in->data; 3277c478bd9Sstevel@tonic-gate if (trans.length && (trans.data[trans.length-1] == '\0')) 3287c478bd9Sstevel@tonic-gate trans.length--; 3297c478bd9Sstevel@tonic-gate 330*159d09a2SMark Phalan Tprintf (("krb5_check_transited_list(trans=\"%.*s\", crealm=\"%.*s\", srealm=\"%.*s\")\n", 331*159d09a2SMark Phalan (int) trans.length, trans.data, 332*159d09a2SMark Phalan (int) crealm->length, crealm->data, 333*159d09a2SMark Phalan (int) srealm->length, srealm->data)); 3347c478bd9Sstevel@tonic-gate if (trans.length == 0) 3357c478bd9Sstevel@tonic-gate return 0; 3367c478bd9Sstevel@tonic-gate r = krb5_walk_realm_tree (ctx, crealm, srealm, &cdata.tgs, 3377c478bd9Sstevel@tonic-gate KRB5_REALM_BRANCH_CHAR); 3387c478bd9Sstevel@tonic-gate if (r) { 339*159d09a2SMark Phalan Tprintf (("error %ld\n", (long) r)); 3407c478bd9Sstevel@tonic-gate return r; 3417c478bd9Sstevel@tonic-gate } 3427c478bd9Sstevel@tonic-gate #ifdef DEBUG /* avoid compiler warning about 'd' unused */ 3437c478bd9Sstevel@tonic-gate { 3447c478bd9Sstevel@tonic-gate int i; 345*159d09a2SMark Phalan Tprintf (("tgs list = {\n")); 3467c478bd9Sstevel@tonic-gate for (i = 0; cdata.tgs[i]; i++) { 3477c478bd9Sstevel@tonic-gate char *name; 3487c478bd9Sstevel@tonic-gate r = krb5_unparse_name (ctx, cdata.tgs[i], &name); 349*159d09a2SMark Phalan Tprintf (("\t'%s'\n", name)); 3507c478bd9Sstevel@tonic-gate free (name); 3517c478bd9Sstevel@tonic-gate } 352*159d09a2SMark Phalan Tprintf (("}\n")); 3537c478bd9Sstevel@tonic-gate } 3547c478bd9Sstevel@tonic-gate #endif 3557c478bd9Sstevel@tonic-gate cdata.ctx = ctx; 3567c478bd9Sstevel@tonic-gate r = foreach_realm (check_realm_in_list, &cdata, crealm, srealm, &trans); 3577c478bd9Sstevel@tonic-gate krb5_free_realm_tree (ctx, cdata.tgs); 3587c478bd9Sstevel@tonic-gate return r; 3597c478bd9Sstevel@tonic-gate } 360*159d09a2SMark Phalan 361*159d09a2SMark Phalan #ifdef TEST 362*159d09a2SMark Phalan 363*159d09a2SMark Phalan static krb5_error_code 364*159d09a2SMark Phalan print_a_realm (krb5_data *realm, void *data) 365*159d09a2SMark Phalan { 366*159d09a2SMark Phalan printf ("%.*s\n", (int) realm->length, realm->data); 367*159d09a2SMark Phalan return 0; 368*159d09a2SMark Phalan } 369*159d09a2SMark Phalan 370*159d09a2SMark Phalan int main (int argc, char *argv[]) { 371*159d09a2SMark Phalan const char *me; 372*159d09a2SMark Phalan krb5_data crealm, srealm, transit; 373*159d09a2SMark Phalan krb5_error_code r; 374*159d09a2SMark Phalan int expand_only = 0; 375*159d09a2SMark Phalan 376*159d09a2SMark Phalan me = strrchr (argv[0], '/'); 377*159d09a2SMark Phalan me = me ? me+1 : argv[0]; 378*159d09a2SMark Phalan 379*159d09a2SMark Phalan while (argc > 3 && argv[1][0] == '-') { 380*159d09a2SMark Phalan if (!strcmp ("-v", argv[1])) 381*159d09a2SMark Phalan verbose++, argc--, argv++; 382*159d09a2SMark Phalan else if (!strcmp ("-x", argv[1])) 383*159d09a2SMark Phalan expand_only++, argc--, argv++; 384*159d09a2SMark Phalan else 385*159d09a2SMark Phalan goto usage; 386*159d09a2SMark Phalan } 387*159d09a2SMark Phalan 388*159d09a2SMark Phalan if (argc != 4) { 389*159d09a2SMark Phalan usage: 390*159d09a2SMark Phalan printf ("usage: %s [-v] [-x] clientRealm serverRealm transitEncoding\n", 391*159d09a2SMark Phalan me); 392*159d09a2SMark Phalan return 1; 393*159d09a2SMark Phalan } 394*159d09a2SMark Phalan 395*159d09a2SMark Phalan crealm.data = argv[1]; 396*159d09a2SMark Phalan crealm.length = strlen(argv[1]); 397*159d09a2SMark Phalan srealm.data = argv[2]; 398*159d09a2SMark Phalan srealm.length = strlen(argv[2]); 399*159d09a2SMark Phalan transit.data = argv[3]; 400*159d09a2SMark Phalan transit.length = strlen(argv[3]); 401*159d09a2SMark Phalan 402*159d09a2SMark Phalan if (expand_only) { 403*159d09a2SMark Phalan 404*159d09a2SMark Phalan printf ("client realm: %s\n", argv[1]); 405*159d09a2SMark Phalan printf ("server realm: %s\n", argv[2]); 406*159d09a2SMark Phalan printf ("transit enc.: %s\n", argv[3]); 407*159d09a2SMark Phalan 408*159d09a2SMark Phalan if (argv[3][0] == 0) { 409*159d09a2SMark Phalan printf ("no other realms transited\n"); 410*159d09a2SMark Phalan return 0; 411*159d09a2SMark Phalan } 412*159d09a2SMark Phalan 413*159d09a2SMark Phalan r = foreach_realm (print_a_realm, NULL, &crealm, &srealm, &transit); 414*159d09a2SMark Phalan if (r) 415*159d09a2SMark Phalan printf ("--> returned error %ld\n", (long) r); 416*159d09a2SMark Phalan return r != 0; 417*159d09a2SMark Phalan 418*159d09a2SMark Phalan } else { 419*159d09a2SMark Phalan 420*159d09a2SMark Phalan /* Actually check the values against the supplied krb5.conf file. */ 421*159d09a2SMark Phalan krb5_context ctx; 422*159d09a2SMark Phalan r = krb5_init_context (&ctx); 423*159d09a2SMark Phalan if (r) { 424*159d09a2SMark Phalan com_err (me, r, "initializing krb5 context"); 425*159d09a2SMark Phalan return 1; 426*159d09a2SMark Phalan } 427*159d09a2SMark Phalan r = krb5_check_transited_list (ctx, &transit, &crealm, &srealm); 428*159d09a2SMark Phalan if (r == KRB5KRB_AP_ERR_ILL_CR_TKT) { 429*159d09a2SMark Phalan printf ("NO\n"); 430*159d09a2SMark Phalan } else if (r == 0) { 431*159d09a2SMark Phalan printf ("YES\n"); 432*159d09a2SMark Phalan } else { 433*159d09a2SMark Phalan printf ("kablooey!\n"); 434*159d09a2SMark Phalan com_err (me, r, "checking transited-realm list"); 435*159d09a2SMark Phalan return 1; 436*159d09a2SMark Phalan } 437*159d09a2SMark Phalan return 0; 438*159d09a2SMark Phalan } 439*159d09a2SMark Phalan } 440*159d09a2SMark Phalan 441*159d09a2SMark Phalan #endif /* TEST */ 442