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