1 /*
2  * Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
3  * 2006-2009 Bjorn Andersson <flex@kryo.se>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 
18 #include <sys/types.h>
19 #include <sys/socket.h>
20 #include <netinet/in.h>
21 #include <sys/stat.h>
22 #include <arpa/nameser.h>
23 #ifdef DARWIN
24 #define BIND_8_COMPAT
25 #include <arpa/nameser_compat.h>
26 #endif
27 #include <stdio.h>
28 #include <stdint.h>
29 #include <stdlib.h>
30 #include <string.h>
31 #include <check.h>
32 
33 #include "common.h"
34 #include "encoding.h"
35 #include "dns.h"
36 #include "read.h"
37 #include "test.h"
38 
START_TEST(test_read_putshort)39 START_TEST(test_read_putshort)
40 {
41 	unsigned short k;
42 	unsigned short l;
43 	char* p;
44 	int i;
45 
46 	for (i = 0; i < 65536; i++) {
47 		p = (char*)&k;
48 		putshort(&p, i);
49 		fail_unless(ntohs(k) == i,
50 				"Bad value on putshort for %d: %d != %d",
51 					i, ntohs(k), i);
52 
53 		p = (char*)&k;
54 		readshort(NULL, &p, &l);
55 		fail_unless(l == i,
56 				"Bad value on readshort for %d: %d != %d",
57 					i, l, i);
58 	}
59 }
60 END_TEST
61 
START_TEST(test_read_putlong)62 START_TEST(test_read_putlong)
63 {
64 	uint32_t k;
65 	uint32_t l;
66 	char* p;
67 	int i;
68 	int j;
69 
70 	for (i = 0; i < 32; i++) {
71 		p = (char*)&k;
72 		j = 0xf << i;
73 
74 		putlong(&p, j);
75 
76 		fail_unless(ntohl(k) == j,
77 				"Bad value on putlong for %d: %d != %d", i, ntohl(j), j);
78 
79 		p = (char*)&k;
80 		readlong(NULL, &p, &l);
81 
82 		fail_unless(l == j,
83 				"Bad value on readlong for %d: %d != %d", i, l, j);
84 	}
85 }
86 END_TEST
87 
START_TEST(test_read_name_empty_loop)88 START_TEST(test_read_name_empty_loop)
89 {
90 	unsigned char emptyloop[] = {
91 		'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
92 		0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01 };
93 	char buf[1024];
94 	char *data;
95 	int rv;
96 
97 	memset(buf, 0, sizeof(buf));
98 	data = (char*) emptyloop + sizeof(HEADER);
99 	buf[1023] = 'A';
100 	rv = readname((char *) emptyloop, sizeof(emptyloop), &data, buf, 1023);
101 	fail_unless(rv == 0);
102 	fail_unless(buf[1023] == 'A');
103 }
104 END_TEST
105 
START_TEST(test_read_name_inf_loop)106 START_TEST(test_read_name_inf_loop)
107 {
108 	unsigned char infloop[] = {
109 		'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
110 		0x01, 'A', 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01 };
111 	char buf[1024];
112 	char *data;
113 	int rv;
114 
115 	memset(buf, 0, sizeof(buf));
116 	data = (char*) infloop + sizeof(HEADER);
117 	buf[4] = '\a';
118 	rv = readname((char*) infloop, sizeof(infloop), &data, buf, 4);
119 	fail_unless(rv == 3);
120 	fail_unless(buf[4] == '\a');
121 }
122 END_TEST
123 
START_TEST(test_read_name_longname)124 START_TEST(test_read_name_longname)
125 {
126 	unsigned char longname[] =
127 		"AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
128 		"\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
129 		"\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
130 		"\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
131 		"\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
132 		"\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
133 		"\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
134 		"\x00\x00\x01\x00\x01";
135 	char buf[1024];
136 	char *data;
137 	int rv;
138 
139 	memset(buf, 0, sizeof(buf));
140 	data = (char*) longname + sizeof(HEADER);
141 	buf[256] = '\a';
142 	rv = readname((char*) longname, sizeof(longname), &data, buf, 256);
143 	fail_unless(rv == 256);
144 	fail_unless(buf[256] == '\a');
145 }
146 END_TEST
147 
START_TEST(test_read_name_onejump)148 START_TEST(test_read_name_onejump)
149 {
150 	unsigned char onejump[] =
151 		"AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
152 		"\x02hh\xc0\x15\x00\x01\x00\x01\x05zBCDE\x00";
153 	char buf[1024];
154 	char *data;
155 	int rv;
156 
157 	memset(buf, 0, sizeof(buf));
158 	data = (char*) onejump + sizeof(HEADER);
159 	rv = readname((char*) onejump, sizeof(onejump), &data, buf, 256);
160 	fail_unless(rv == 9);
161 }
162 END_TEST
163 
START_TEST(test_read_name_badjump_start)164 START_TEST(test_read_name_badjump_start)
165 {
166 	unsigned char badjump[] = {
167 		'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
168 		0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
169 	unsigned char *jumper;
170 	char buf[1024];
171 	char *data;
172 	int rv;
173 
174 	/* This test uses malloc to cause segfault if jump is executed */
175 	memset(buf, 0, sizeof(buf));
176 	jumper = malloc(sizeof(badjump));
177 	if (jumper) {
178 		memcpy(jumper, badjump, sizeof(badjump));
179 		data = (char*) jumper + sizeof(HEADER);
180 		rv = readname((char*) jumper, sizeof(badjump), &data, buf, 256);
181 
182 		fail_unless(rv == 0);
183 		fail_unless(buf[0] == 0);
184 	}
185 	free(jumper);
186 }
187 END_TEST
188 
START_TEST(test_read_name_badjump_second)189 START_TEST(test_read_name_badjump_second)
190 {
191 	unsigned char badjump2[] = {
192 		'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
193 		0x02, 'B', 'A', 0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
194 	unsigned char *jumper;
195 	char buf[1024];
196 	char *data;
197 	int rv;
198 
199 	/* This test uses malloc to cause segfault if jump is executed */
200 	memset(buf, 0, sizeof(buf));
201 	jumper = malloc(sizeof(badjump2));
202 	if (jumper) {
203 		memcpy(jumper, badjump2, sizeof(badjump2));
204 		data = (char*) jumper + sizeof(HEADER);
205 		rv = readname((char*) jumper, sizeof(badjump2), &data, buf, 256);
206 
207 		fail_unless(rv == 4);
208 		fail_unless(strcmp("BA.", buf) == 0,
209 				"buf is not BA: %s", buf);
210 	}
211 	free(jumper);
212 }
213 END_TEST
214 
START_TEST(test_putname)215 START_TEST(test_putname)
216 {
217 	char out[] = "\x06" "BADGER\x06" "BADGER\x04" "KRYO\x02" "SE\x00";
218 	char buf[256];
219 	char *domain = "BADGER.BADGER.KRYO.SE";
220 	char *b;
221 	int ret;
222 
223 	memset(buf, 0, 256);
224 	b = buf;
225 	ret = putname(&b, 256, domain);
226 
227 	fail_unless(ret == strlen(domain) + 1);
228 	fail_unless(strncmp(buf, out, ret) == 0, "Happy flow failed");
229 }
230 END_TEST
231 
START_TEST(test_putname_nodot)232 START_TEST(test_putname_nodot)
233 {
234 	char buf[256];
235 	char *nodot =
236 		"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
237 		"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";
238 	char *b;
239 	int ret;
240 
241 	memset(buf, 0, 256);
242 	b = buf;
243 	ret = putname(&b, 256, nodot);
244 
245 	fail_unless(ret == -1);
246 	fail_unless(b == buf);
247 }
248 END_TEST
249 
START_TEST(test_putname_toolong)250 START_TEST(test_putname_toolong)
251 {
252 	char buf[256];
253 	char *toolong =
254 		"ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
255 		"ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
256 		"ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
257 		"ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
258 		"ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
259 		"ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.";
260 	char *b;
261 	int ret;
262 
263 	memset(buf, 0, 256);
264 	b = buf;
265 	ret = putname(&b, 256, toolong);
266 
267 	fail_unless(ret == -1);
268 	fail_unless(b == buf);
269 }
270 END_TEST
271 
272 
273 TCase *
test_read_create_tests()274 test_read_create_tests()
275 {
276 	TCase *tc;
277 
278 	tc = tcase_create("Read");
279 	tcase_set_timeout(tc, 60);
280 	tcase_add_test(tc, test_read_putshort);
281 	tcase_add_test(tc, test_read_putlong);
282 	tcase_add_test(tc, test_read_name_empty_loop);
283 	tcase_add_test(tc, test_read_name_inf_loop);
284 	tcase_add_test(tc, test_read_name_longname);
285 	tcase_add_test(tc, test_read_name_onejump);
286 	tcase_add_test(tc, test_read_name_badjump_start);
287 	tcase_add_test(tc, test_read_name_badjump_second);
288 	tcase_add_test(tc, test_putname);
289 	tcase_add_test(tc, test_putname_nodot);
290 	tcase_add_test(tc, test_putname_toolong);
291 
292 	return tc;
293 }
294