xref: /freebsd/crypto/krb5/src/lib/krb5/krb/t_parse_host_string.c (revision 7f2fe78b9dd5f51c821d771b63d2e096f6fd49e9)
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