1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* lib/krb5/krb/t_parse_host_string.c - k5_parse_host_string() unit tests */
3 /*
4 * Copyright (C) 2015 by the Massachusetts Institute of Technology.
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 *
11 * * Redistributions of source code must retain the above copyright
12 * notice, this list of conditions and the following disclaimer.
13 *
14 * * Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in
16 * the documentation and/or other materials provided with the
17 * distribution.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
22 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
23 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
24 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
26 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
28 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
30 * OF THE POSSIBILITY OF SUCH DAMAGE.
31 */
32
33 #include "k5-int.h"
34 #include "k5-cmocka.h"
35
36 /* Call k5_parse_host_string() and check the result against the expected code,
37 * hostname, and port. */
38 static void
call_k5_parse_host_string(const char * host,int default_port,krb5_error_code e_code,const char * e_host,int e_port)39 call_k5_parse_host_string(const char *host, int default_port,
40 krb5_error_code e_code, const char *e_host,
41 int e_port)
42 {
43 krb5_error_code code;
44 char *host_out = NULL;
45 int port_out = -1;
46
47 code = k5_parse_host_string(host, default_port, &host_out, &port_out);
48
49 assert_int_equal(code, e_code);
50
51 /* Only check the port if the function was expected to be successful. */
52 if (!e_code)
53 assert_int_equal(port_out, e_port);
54
55 /* If the expected code is a failure then host_out should be NULL. */
56 if (e_code != 0 || e_host == NULL)
57 assert_null(host_out);
58 else
59 assert_string_equal(e_host, host_out);
60
61 free(host_out);
62 }
63
64 /* k5_parse_host_string() tests */
65
66 static void
test_named_host_only(void ** state)67 test_named_host_only(void **state)
68 {
69 call_k5_parse_host_string("test.example", 50, 0, "test.example", 50);
70 }
71
72 static void
test_named_host_w_port(void ** state)73 test_named_host_w_port(void **state)
74 {
75 call_k5_parse_host_string("test.example:75", 0, 0, "test.example", 75);
76 }
77
78 static void
test_ipv4_only(void ** state)79 test_ipv4_only(void **state)
80 {
81 call_k5_parse_host_string("192.168.1.1", 100, 0, "192.168.1.1", 100);
82 }
83
84 static void
test_ipv4_w_port(void ** state)85 test_ipv4_w_port(void **state)
86 {
87 call_k5_parse_host_string("192.168.1.1:150", 0, 0, "192.168.1.1", 150);
88 }
89
90 static void
test_ipv6_only(void ** state)91 test_ipv6_only(void **state)
92 {
93 call_k5_parse_host_string("[BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE]", 200,
94 0, "BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE",
95 200);
96 }
97
98 static void
test_ipv6_w_port(void ** state)99 test_ipv6_w_port(void **state)
100 {
101 call_k5_parse_host_string("[BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE]:250",
102 0, 0, "BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE",
103 250);
104 }
105
106 static void
test_ipv6_w_zone(void ** state)107 test_ipv6_w_zone(void **state)
108 {
109 call_k5_parse_host_string("[BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE%eth0]",
110 275, 0,
111 "BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE%eth0",
112 275);
113 }
114
115 static void
test_invalid_ipv6(void ** state)116 test_invalid_ipv6(void **state)
117 {
118 call_k5_parse_host_string("BEEF:CAFE:FEED:FACE:DEAD:BEEF:DEAF:BABE", 1,
119 EINVAL, NULL, 0);
120 }
121
122 static void
test_no_host_port(void ** state)123 test_no_host_port(void **state)
124 {
125 call_k5_parse_host_string(":300", 0, EINVAL, NULL, 300);
126 }
127
128 static void
test_port_only(void ** state)129 test_port_only(void **state)
130 {
131 call_k5_parse_host_string("350", 0, 0, NULL, 350);
132 }
133
134 static void
test_null_host(void ** state)135 test_null_host(void **state)
136 {
137 call_k5_parse_host_string(NULL, 400, EINVAL, NULL, 400);
138 }
139
140 static void
test_empty_host(void ** state)141 test_empty_host(void **state)
142 {
143 call_k5_parse_host_string("", 450, EINVAL, NULL, 450);
144 }
145
146 static void
test_port_out_of_range(void ** state)147 test_port_out_of_range(void **state)
148 {
149 call_k5_parse_host_string("70000", 1, EINVAL, NULL, 0);
150 }
151
152 static void
test_port_invalid_characters(void ** state)153 test_port_invalid_characters(void **state)
154 {
155 call_k5_parse_host_string("test.example:F101", 1, EINVAL, NULL, 0);
156 }
157
158 static void
test_invalid_default_port(void ** state)159 test_invalid_default_port(void **state)
160 {
161 call_k5_parse_host_string("test.example", 70000, EINVAL, NULL, 0);
162 }
163
164 /* k5_is_string_numeric() tests */
165
166 static void
test_numeric_single_digit(void ** state)167 test_numeric_single_digit(void **state)
168 {
169 assert_true(k5_is_string_numeric("0"));
170 }
171
172 static void
test_numeric_all_digits(void ** state)173 test_numeric_all_digits(void **state)
174 {
175 assert_true(k5_is_string_numeric("0123456789"));
176 }
177
178 static void
test_numeric_alpha(void ** state)179 test_numeric_alpha(void **state)
180 {
181 assert_false(k5_is_string_numeric("012345F6789"));
182 }
183
184 static void
test_numeric_period(void ** state)185 test_numeric_period(void **state)
186 {
187 assert_false(k5_is_string_numeric("123.456"));
188 }
189
190 static void
test_numeric_negative(void ** state)191 test_numeric_negative(void **state)
192 {
193 assert_false(k5_is_string_numeric("-123"));
194 }
195
196 static void
test_numeric_empty(void ** state)197 test_numeric_empty(void **state)
198 {
199 assert_false(k5_is_string_numeric(""));
200 }
201
202 static void
test_numeric_whitespace(void ** state)203 test_numeric_whitespace(void **state)
204 {
205 assert_false(k5_is_string_numeric("123 456"));
206 }
207
208 int
main(void)209 main(void)
210 {
211 int ret;
212
213 const struct CMUnitTest k5_parse_host_string_tests[] = {
214 cmocka_unit_test(test_named_host_only),
215 cmocka_unit_test(test_named_host_w_port),
216 cmocka_unit_test(test_ipv4_only),
217 cmocka_unit_test(test_ipv4_w_port),
218 cmocka_unit_test(test_ipv6_only),
219 cmocka_unit_test(test_ipv6_w_port),
220 cmocka_unit_test(test_ipv6_w_zone),
221 cmocka_unit_test(test_invalid_ipv6),
222 cmocka_unit_test(test_no_host_port),
223 cmocka_unit_test(test_port_only),
224 cmocka_unit_test(test_null_host),
225 cmocka_unit_test(test_empty_host),
226 cmocka_unit_test(test_port_out_of_range),
227 cmocka_unit_test(test_port_invalid_characters),
228 cmocka_unit_test(test_invalid_default_port)
229 };
230
231 const struct CMUnitTest k5_is_string_numeric_tests[] = {
232 cmocka_unit_test(test_numeric_single_digit),
233 cmocka_unit_test(test_numeric_all_digits),
234 cmocka_unit_test(test_numeric_alpha),
235 cmocka_unit_test(test_numeric_period),
236 cmocka_unit_test(test_numeric_negative),
237 cmocka_unit_test(test_numeric_empty),
238 cmocka_unit_test(test_numeric_whitespace)
239 };
240
241 ret = cmocka_run_group_tests_name("k5_parse_host_string",
242 k5_parse_host_string_tests, NULL, NULL);
243 ret += cmocka_run_group_tests_name("k5_is_string_numeric",
244 k5_is_string_numeric_tests, NULL, NULL);
245
246 return ret;
247 }
248