1 /* 2 * Copyright (c) 2005 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 #include "krb5_locl.h" 34 #include <err.h> 35 36 static void 37 print_addr(krb5_context context, const char *addr) 38 { 39 krb5_addresses addresses; 40 krb5_error_code ret; 41 char buf[38]; 42 char buf2[1000]; 43 size_t len; 44 int i; 45 46 ret = krb5_parse_address(context, addr, &addresses); 47 if (ret) 48 krb5_err(context, 1, ret, "krb5_parse_address"); 49 50 if (addresses.len < 1) 51 krb5_err(context, 1, ret, "too few addresses"); 52 53 for (i = 0; i < addresses.len; i++) { 54 krb5_print_address(&addresses.val[i], buf, sizeof(buf), &len); 55 #if 0 56 printf("addr %d: %s (%d/%d)\n", i, buf, (int)len, (int)strlen(buf)); 57 #endif 58 if (strlen(buf) > sizeof(buf)) 59 krb5_err(context, 1, ret, "len %d larger then buf %d", 60 (int)strlen(buf), (int)sizeof(buf)); 61 krb5_print_address(&addresses.val[i], buf2, sizeof(buf2), &len); 62 #if 0 63 printf("addr %d: %s (%d/%d)\n", i, buf2, (int)len, (int)strlen(buf2)); 64 #endif 65 if (strlen(buf2) > sizeof(buf2)) 66 krb5_err(context, 1, ret, "len %d larger then buf %d", 67 (int)strlen(buf2), (int)sizeof(buf2)); 68 69 } 70 krb5_free_addresses(context, &addresses); 71 72 } 73 74 static void 75 truncated_addr(krb5_context context, const char *addr, 76 size_t truncate_len, size_t outlen) 77 { 78 krb5_addresses addresses; 79 krb5_error_code ret; 80 char *buf; 81 size_t len; 82 83 buf = ecalloc(1, outlen + 1); 84 85 ret = krb5_parse_address(context, addr, &addresses); 86 if (ret) 87 krb5_err(context, 1, ret, "krb5_parse_address"); 88 89 if (addresses.len != 1) 90 krb5_err(context, 1, ret, "addresses should be one"); 91 92 krb5_print_address(&addresses.val[0], buf, truncate_len, &len); 93 94 #if 0 95 printf("addr %s (%d/%d) should be %d\n", buf, (int)len, (int)strlen(buf), (int)outlen); 96 #endif 97 98 if (truncate_len > strlen(buf) + 1) 99 krb5_err(context, 1, ret, "%s truncate_len %d larger then strlen %d source %s", 100 buf, (int)truncate_len, (int)strlen(buf), addr); 101 102 if (outlen != len) 103 krb5_err(context, 1, ret, "%s: outlen %d != len %d", 104 buf, (int)outlen, (int)strlen(buf)); 105 106 krb5_print_address(&addresses.val[0], buf, outlen + 1, &len); 107 108 #if 0 109 printf("addr %s (%d/%d)\n", buf, (int)len, (int)strlen(buf)); 110 #endif 111 112 if (len != outlen) 113 abort(); 114 if (strlen(buf) != len) 115 abort(); 116 117 krb5_free_addresses(context, &addresses); 118 free(buf); 119 } 120 121 static void 122 check_truncation(krb5_context context, const char *addr) 123 { 124 int i, len = strlen(addr); 125 126 truncated_addr(context, addr, len, len); 127 128 for (i = 0; i < len; i++) 129 truncated_addr(context, addr, i, len); 130 } 131 132 static void 133 match_addr(krb5_context context, const char *range_addr, 134 const char *one_addr, int match) 135 { 136 krb5_addresses range, one; 137 krb5_error_code ret; 138 139 ret = krb5_parse_address(context, range_addr, &range); 140 if (ret) 141 krb5_err(context, 1, ret, "krb5_parse_address"); 142 143 if (range.len != 1) 144 krb5_err(context, 1, ret, "wrong num of addresses"); 145 146 ret = krb5_parse_address(context, one_addr, &one); 147 if (ret) 148 krb5_err(context, 1, ret, "krb5_parse_address"); 149 150 if (one.len != 1) 151 krb5_err(context, 1, ret, "wrong num of addresses"); 152 153 if (krb5_address_order(context, &range.val[0], &one.val[0]) == 0) { 154 if (!match) 155 krb5_errx(context, 1, "match when one shouldn't be"); 156 } else { 157 if (match) 158 krb5_errx(context, 1, "no match when one should be"); 159 } 160 161 krb5_free_addresses(context, &range); 162 krb5_free_addresses(context, &one); 163 } 164 165 #ifdef _MSC_VER 166 167 /* For the truncation tests, calling strcpy_s() or strcat_s() with a 168 size of 0 results in the invalid parameter handler being invoked. 169 For the debug version, the runtime also throws an assert. */ 170 171 static void 172 inv_param_handler(const wchar_t* expression, 173 const wchar_t* function, 174 const wchar_t* file, 175 unsigned int line, 176 uintptr_t pReserved) 177 { 178 printf("Invalid parameter handler invoked for: %S in %S(%d) [%S]\n", 179 function, file, line, expression); 180 } 181 182 static _invalid_parameter_handler _inv_old = NULL; 183 184 #define SET_INVALID_PARAM_HANDLER _inv_old = _set_invalid_parameter_handler(inv_param_handler) 185 186 #else 187 188 #define SET_INVALID_PARAM_HANDLER ((void) 0) 189 190 #endif 191 192 int 193 main(int argc, char **argv) 194 { 195 krb5_context context; 196 krb5_error_code ret; 197 198 SET_INVALID_PARAM_HANDLER; 199 200 setprogname(argv[0]); 201 202 ret = krb5_init_context(&context); 203 if (ret) 204 errx (1, "krb5_init_context failed: %d", ret); 205 206 print_addr(context, "RANGE:127.0.0.0/8"); 207 print_addr(context, "RANGE:127.0.0.0/24"); 208 print_addr(context, "RANGE:IPv4:127.0.0.0-IPv4:127.0.0.255"); 209 print_addr(context, "RANGE:130.237.237.4/29"); 210 #ifdef HAVE_IPV6 211 print_addr(context, "RANGE:2001:db8:1:2:3:4:1428:7ab/64"); 212 print_addr(context, "RANGE:IPv6:fe80::209:6bff:fea0:e522/64"); 213 print_addr(context, "RANGE:IPv6:fe80::-IPv6:fe80::ffff:ffff:ffff:ffff"); 214 print_addr(context, "RANGE:fe80::-fe80::ffff:ffff:ffff:ffff"); 215 #endif 216 217 check_truncation(context, "IPv4:127.0.0.0"); 218 check_truncation(context, "RANGE:IPv4:127.0.0.0-IPv4:127.0.0.255"); 219 #ifdef HAVE_IPV6 220 check_truncation(context, "IPv6:::"); 221 check_truncation(context, "IPv6:::1"); 222 check_truncation(context, "IPv6:2001:db8:1:2:3:4:1428:7ab"); 223 check_truncation(context, "IPv6:fe80::209:0:0:0"); 224 check_truncation(context, "IPv6:fe80::ffff:ffff:ffff:ffff"); 225 #endif 226 227 match_addr(context, "RANGE:127.0.0.0/8", "inet:127.0.0.0", 1); 228 match_addr(context, "RANGE:127.0.0.0/8", "inet:127.255.255.255", 1); 229 match_addr(context, "RANGE:127.0.0.0/8", "inet:128.0.0.0", 0); 230 231 match_addr(context, "RANGE:130.237.237.8/29", "inet:130.237.237.7", 0); 232 match_addr(context, "RANGE:130.237.237.8/29", "inet:130.237.237.8", 1); 233 match_addr(context, "RANGE:130.237.237.8/29", "inet:130.237.237.15", 1); 234 match_addr(context, "RANGE:130.237.237.8/29", "inet:130.237.237.16", 0); 235 236 krb5_free_context(context); 237 238 return 0; 239 } 240