1178825Sdfr/*
2233294Sstas * Copyright (c) 2005 Kungliga Tekniska H��gskolan
3233294Sstas * (Royal Institute of Technology, Stockholm, Sweden).
4233294Sstas * All rights reserved.
5178825Sdfr *
6233294Sstas * Redistribution and use in source and binary forms, with or without
7233294Sstas * modification, are permitted provided that the following conditions
8233294Sstas * are met:
9178825Sdfr *
10233294Sstas * 1. Redistributions of source code must retain the above copyright
11233294Sstas *    notice, this list of conditions and the following disclaimer.
12178825Sdfr *
13233294Sstas * 2. Redistributions in binary form must reproduce the above copyright
14233294Sstas *    notice, this list of conditions and the following disclaimer in the
15233294Sstas *    documentation and/or other materials provided with the distribution.
16178825Sdfr *
17178825Sdfr * 3. Neither the name of KTH nor the names of its contributors may be
18178825Sdfr *    used to endorse or promote products derived from this software without
19178825Sdfr *    specific prior written permission.
20178825Sdfr *
21178825Sdfr * THIS SOFTWARE IS PROVIDED BY KTH AND ITS CONTRIBUTORS ``AS IS'' AND ANY
22178825Sdfr * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23178825Sdfr * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24178825Sdfr * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL KTH OR ITS CONTRIBUTORS BE
25178825Sdfr * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26178825Sdfr * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27178825Sdfr * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
28178825Sdfr * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
29178825Sdfr * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
30178825Sdfr * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
31178825Sdfr * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */
32178825Sdfr
33178825Sdfr#include "krb5_locl.h"
34178825Sdfr#include <err.h>
35178825Sdfr
36178825Sdfrstatic void
37178825Sdfrprint_addr(krb5_context context, const char *addr)
38178825Sdfr{
39178825Sdfr    krb5_addresses addresses;
40178825Sdfr    krb5_error_code ret;
41178825Sdfr    char buf[38];
42178825Sdfr    char buf2[1000];
43178825Sdfr    size_t len;
44178825Sdfr    int i;
45178825Sdfr
46178825Sdfr    ret = krb5_parse_address(context, addr, &addresses);
47178825Sdfr    if (ret)
48178825Sdfr	krb5_err(context, 1, ret, "krb5_parse_address");
49178825Sdfr
50178825Sdfr    if (addresses.len < 1)
51178825Sdfr	krb5_err(context, 1, ret, "too few addresses");
52233294Sstas
53178825Sdfr    for (i = 0; i < addresses.len; i++) {
54178825Sdfr	krb5_print_address(&addresses.val[i], buf, sizeof(buf), &len);
55178825Sdfr#if 0
56233294Sstas	printf("addr %d: %s (%d/%d)\n", i, buf, (int)len, (int)strlen(buf));
57178825Sdfr#endif
58178825Sdfr	if (strlen(buf) > sizeof(buf))
59233294Sstas	    krb5_err(context, 1, ret, "len %d larger then buf %d",
60233294Sstas		     (int)strlen(buf), (int)sizeof(buf));
61178825Sdfr	krb5_print_address(&addresses.val[i], buf2, sizeof(buf2), &len);
62178825Sdfr#if 0
63233294Sstas	printf("addr %d: %s (%d/%d)\n", i, buf2, (int)len, (int)strlen(buf2));
64178825Sdfr#endif
65178825Sdfr	if (strlen(buf2) > sizeof(buf2))
66233294Sstas	    krb5_err(context, 1, ret, "len %d larger then buf %d",
67233294Sstas		     (int)strlen(buf2), (int)sizeof(buf2));
68178825Sdfr
69178825Sdfr    }
70178825Sdfr    krb5_free_addresses(context, &addresses);
71178825Sdfr
72178825Sdfr}
73178825Sdfr
74178825Sdfrstatic void
75233294Sstastruncated_addr(krb5_context context, const char *addr,
76178825Sdfr	       size_t truncate_len, size_t outlen)
77178825Sdfr{
78178825Sdfr    krb5_addresses addresses;
79178825Sdfr    krb5_error_code ret;
80178825Sdfr    char *buf;
81178825Sdfr    size_t len;
82178825Sdfr
83178825Sdfr    buf = ecalloc(1, outlen + 1);
84178825Sdfr
85178825Sdfr    ret = krb5_parse_address(context, addr, &addresses);
86178825Sdfr    if (ret)
87178825Sdfr	krb5_err(context, 1, ret, "krb5_parse_address");
88178825Sdfr
89178825Sdfr    if (addresses.len != 1)
90178825Sdfr	krb5_err(context, 1, ret, "addresses should be one");
91233294Sstas
92178825Sdfr    krb5_print_address(&addresses.val[0], buf, truncate_len, &len);
93233294Sstas
94178825Sdfr#if 0
95233294Sstas    printf("addr %s (%d/%d) should be %d\n", buf, (int)len, (int)strlen(buf), (int)outlen);
96178825Sdfr#endif
97233294Sstas
98178825Sdfr    if (truncate_len > strlen(buf) + 1)
99233294Sstas	krb5_err(context, 1, ret, "%s truncate_len %d larger then strlen %d source %s",
100233294Sstas		 buf, (int)truncate_len, (int)strlen(buf), addr);
101233294Sstas
102178825Sdfr    if (outlen != len)
103233294Sstas	krb5_err(context, 1, ret, "%s: outlen %d != len %d",
104233294Sstas		 buf, (int)outlen, (int)strlen(buf));
105233294Sstas
106178825Sdfr    krb5_print_address(&addresses.val[0], buf, outlen + 1, &len);
107178825Sdfr
108178825Sdfr#if 0
109233294Sstas    printf("addr %s (%d/%d)\n", buf, (int)len, (int)strlen(buf));
110178825Sdfr#endif
111178825Sdfr
112178825Sdfr    if (len != outlen)
113178825Sdfr	abort();
114178825Sdfr    if (strlen(buf) != len)
115178825Sdfr	abort();
116178825Sdfr
117178825Sdfr    krb5_free_addresses(context, &addresses);
118178825Sdfr    free(buf);
119178825Sdfr}
120178825Sdfr
121178825Sdfrstatic void
122178825Sdfrcheck_truncation(krb5_context context, const char *addr)
123178825Sdfr{
124178825Sdfr    int i, len = strlen(addr);
125178825Sdfr
126233294Sstas    truncated_addr(context, addr, len, len);
127233294Sstas
128178825Sdfr    for (i = 0; i < len; i++)
129178825Sdfr	truncated_addr(context, addr, i, len);
130178825Sdfr}
131178825Sdfr
132178825Sdfrstatic void
133233294Sstasmatch_addr(krb5_context context, const char *range_addr,
134178825Sdfr	   const char *one_addr, int match)
135178825Sdfr{
136178825Sdfr    krb5_addresses range, one;
137178825Sdfr    krb5_error_code ret;
138178825Sdfr
139178825Sdfr    ret = krb5_parse_address(context, range_addr, &range);
140178825Sdfr    if (ret)
141178825Sdfr	krb5_err(context, 1, ret, "krb5_parse_address");
142178825Sdfr
143178825Sdfr    if (range.len != 1)
144178825Sdfr	krb5_err(context, 1, ret, "wrong num of addresses");
145233294Sstas
146178825Sdfr    ret = krb5_parse_address(context, one_addr, &one);
147178825Sdfr    if (ret)
148178825Sdfr	krb5_err(context, 1, ret, "krb5_parse_address");
149178825Sdfr
150178825Sdfr    if (one.len != 1)
151178825Sdfr	krb5_err(context, 1, ret, "wrong num of addresses");
152178825Sdfr
153178825Sdfr    if (krb5_address_order(context, &range.val[0], &one.val[0]) == 0) {
154178825Sdfr	if (!match)
155178825Sdfr	    krb5_errx(context, 1, "match when one shouldn't be");
156178825Sdfr    } else {
157178825Sdfr	if (match)
158178825Sdfr	    krb5_errx(context, 1, "no match when one should be");
159178825Sdfr    }
160178825Sdfr
161178825Sdfr    krb5_free_addresses(context, &range);
162178825Sdfr    krb5_free_addresses(context, &one);
163178825Sdfr}
164178825Sdfr
165233294Sstas#ifdef _MSC_VER
166233294Sstas
167233294Sstas/* For the truncation tests, calling strcpy_s() or strcat_s() with a
168233294Sstas   size of 0 results in the invalid parameter handler being invoked.
169233294Sstas   For the debug version, the runtime also throws an assert. */
170233294Sstas
171233294Sstasstatic void
172233294Sstasinv_param_handler(const wchar_t* expression,
173233294Sstas		  const wchar_t* function,
174233294Sstas		  const wchar_t* file,
175233294Sstas		  unsigned int line,
176233294Sstas		  uintptr_t pReserved)
177233294Sstas{
178233294Sstas    printf("Invalid parameter handler invoked for: %S in %S(%d) [%S]\n",
179233294Sstas	   function, file, line, expression);
180233294Sstas}
181233294Sstas
182233294Sstasstatic _invalid_parameter_handler _inv_old = NULL;
183233294Sstas
184233294Sstas#define SET_INVALID_PARAM_HANDLER _inv_old = _set_invalid_parameter_handler(inv_param_handler)
185233294Sstas
186233294Sstas#else
187233294Sstas
188233294Sstas#define SET_INVALID_PARAM_HANDLER ((void) 0)
189233294Sstas
190233294Sstas#endif
191233294Sstas
192178825Sdfrint
193178825Sdfrmain(int argc, char **argv)
194178825Sdfr{
195178825Sdfr    krb5_context context;
196178825Sdfr    krb5_error_code ret;
197178825Sdfr
198233294Sstas    SET_INVALID_PARAM_HANDLER;
199233294Sstas
200178825Sdfr    setprogname(argv[0]);
201178825Sdfr
202178825Sdfr    ret = krb5_init_context(&context);
203178825Sdfr    if (ret)
204178825Sdfr	errx (1, "krb5_init_context failed: %d", ret);
205178825Sdfr
206178825Sdfr    print_addr(context, "RANGE:127.0.0.0/8");
207178825Sdfr    print_addr(context, "RANGE:127.0.0.0/24");
208178825Sdfr    print_addr(context, "RANGE:IPv4:127.0.0.0-IPv4:127.0.0.255");
209178825Sdfr    print_addr(context, "RANGE:130.237.237.4/29");
210178825Sdfr#ifdef HAVE_IPV6
211233294Sstas    print_addr(context, "RANGE:2001:db8:1:2:3:4:1428:7ab/64");
212178825Sdfr    print_addr(context, "RANGE:IPv6:fe80::209:6bff:fea0:e522/64");
213178825Sdfr    print_addr(context, "RANGE:IPv6:fe80::-IPv6:fe80::ffff:ffff:ffff:ffff");
214178825Sdfr    print_addr(context, "RANGE:fe80::-fe80::ffff:ffff:ffff:ffff");
215178825Sdfr#endif
216178825Sdfr
217178825Sdfr    check_truncation(context, "IPv4:127.0.0.0");
218178825Sdfr    check_truncation(context, "RANGE:IPv4:127.0.0.0-IPv4:127.0.0.255");
219178825Sdfr#ifdef HAVE_IPV6
220233294Sstas    check_truncation(context, "IPv6:::");
221178825Sdfr    check_truncation(context, "IPv6:::1");
222233294Sstas    check_truncation(context, "IPv6:2001:db8:1:2:3:4:1428:7ab");
223233294Sstas    check_truncation(context, "IPv6:fe80::209:0:0:0");
224178825Sdfr    check_truncation(context, "IPv6:fe80::ffff:ffff:ffff:ffff");
225178825Sdfr#endif
226178825Sdfr
227178825Sdfr    match_addr(context, "RANGE:127.0.0.0/8", "inet:127.0.0.0", 1);
228178825Sdfr    match_addr(context, "RANGE:127.0.0.0/8", "inet:127.255.255.255", 1);
229178825Sdfr    match_addr(context, "RANGE:127.0.0.0/8", "inet:128.0.0.0", 0);
230178825Sdfr
231178825Sdfr    match_addr(context, "RANGE:130.237.237.8/29", "inet:130.237.237.7", 0);
232178825Sdfr    match_addr(context, "RANGE:130.237.237.8/29", "inet:130.237.237.8", 1);
233178825Sdfr    match_addr(context, "RANGE:130.237.237.8/29", "inet:130.237.237.15", 1);
234178825Sdfr    match_addr(context, "RANGE:130.237.237.8/29", "inet:130.237.237.16", 0);
235178825Sdfr
236178825Sdfr    krb5_free_context(context);
237178825Sdfr
238178825Sdfr    return 0;
239178825Sdfr}
240