xref: /netbsd-src/external/bsd/ntp/dist/sntp/tests/packetProcessing.c (revision d909946ca08dceb44d7d0f22ec9488679695d976)
1 /*	$NetBSD: packetProcessing.c,v 1.1.1.6 2016/05/01 15:57:23 christos Exp $	*/
2 
3 #include "config.h"
4 
5 /* need autokey for some of the tests, or the will create buffer overruns. */
6 #ifndef AUTOKEY
7 # define AUTOKEY 1
8 #endif
9 
10 #include "sntptest.h"
11 #include "networking.h"
12 #include "ntp_stdlib.h"
13 #include "unity.h"
14 
15 
16 const char * Version = "stub unit test Version string";
17 
18 // Hacks into the key database.
19 extern struct key* key_ptr;
20 extern int key_cnt;
21 
22 
23 void PrepareAuthenticationTest(int key_id,int key_len,const char* type,const void* key_seq);
24 void PrepareAuthenticationTestMD5(int key_id,int key_len,const void* key_seq);
25 void setUp(void);
26 void tearDown(void);
27 void test_TooShortLength(void);
28 void test_LengthNotMultipleOfFour(void);
29 void test_TooShortExtensionFieldLength(void);
30 void test_UnauthenticatedPacketReject(void);
31 void test_CryptoNAKPacketReject(void);
32 void test_AuthenticatedPacketInvalid(void);
33 void test_AuthenticatedPacketUnknownKey(void);
34 void test_ServerVersionTooOld(void);
35 void test_ServerVersionTooNew(void);
36 void test_NonWantedMode(void);
37 void test_KoDRate(void);
38 void test_KoDDeny(void);
39 void test_RejectUnsyncedServer(void);
40 void test_RejectWrongResponseServerMode(void);
41 void test_AcceptNoSentPacketBroadcastMode(void);
42 void test_CorrectUnauthenticatedPacket(void);
43 void test_CorrectAuthenticatedPacketMD5(void);
44 void test_CorrectAuthenticatedPacketSHA1(void);
45 
46 
47 static struct pkt testpkt;
48 static struct pkt testspkt;
49 static sockaddr_u testsock;
50 bool restoreKeyDb;
51 
52 
53 void
54 PrepareAuthenticationTest(
55 	int		key_id,
56 	int		key_len,
57 	const char *	type,
58 	const void *	key_seq
59 	)
60 {
61 	char str[25];
62 	snprintf(str, 25, "%d", key_id);
63 	ActivateOption("-a", str);
64 
65 	key_cnt = 1;
66 	key_ptr = emalloc(sizeof(struct key));
67 	key_ptr->next = NULL;
68 	key_ptr->key_id = key_id;
69 	key_ptr->key_len = key_len;
70 	memcpy(key_ptr->type, "MD5", 3);
71 
72 	TEST_ASSERT_TRUE(key_len < sizeof(key_ptr->key_seq));
73 
74 	memcpy(key_ptr->key_seq, key_seq, key_ptr->key_len);
75 	restoreKeyDb = true;
76 }
77 
78 
79 void
80 PrepareAuthenticationTestMD5(
81 	int 		key_id,
82 	int 		key_len,
83 	const void *	key_seq
84 	)
85 {
86 	PrepareAuthenticationTest(key_id, key_len, "MD5", key_seq);
87 }
88 
89 
90 void
91 setUp(void)
92 {
93 
94 	sntptest();
95 	restoreKeyDb = false;
96 
97 	/* Initialize the test packet and socket,
98 	 * so they contain at least some valid data.
99 	 */
100 	testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, NTP_VERSION,
101 										MODE_SERVER);
102 	testpkt.stratum = STRATUM_REFCLOCK;
103 	memcpy(&testpkt.refid, "GPS\0", 4);
104 
105 	/* Set the origin timestamp of the received packet to the
106 	 * same value as the transmit timestamp of the sent packet.
107 	 */
108 	l_fp tmp;
109 	tmp.l_ui = 1000UL;
110 	tmp.l_uf = 0UL;
111 
112 	HTONL_FP(&tmp, &testpkt.org);
113 	HTONL_FP(&tmp, &testspkt.xmt);
114 }
115 
116 
117 void
118 tearDown(void)
119 {
120 	if (restoreKeyDb) {
121 		key_cnt = 0;
122 		free(key_ptr);
123 		key_ptr = NULL;
124 	}
125 
126 	sntptest_destroy(); /* only on the final test!! if counter == 0 etc... */
127 }
128 
129 
130 void
131 test_TooShortLength(void)
132 {
133 	TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
134 			  process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC - 1,
135 				      MODE_SERVER, &testspkt, "UnitTest"));
136 	TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
137 			  process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC - 1,
138 				      MODE_BROADCAST, &testspkt, "UnitTest"));
139 }
140 
141 
142 void
143 test_LengthNotMultipleOfFour(void)
144 {
145 	TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
146 			  process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC + 6,
147 				      MODE_SERVER, &testspkt, "UnitTest"));
148 	TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
149 			  process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC + 3,
150 				      MODE_BROADCAST, &testspkt, "UnitTest"));
151 }
152 
153 
154 void
155 test_TooShortExtensionFieldLength(void)
156 {
157 	/* The lower 16-bits are the length of the extension field.
158 	 * This lengths must be multiples of 4 bytes, which gives
159 	 * a minimum of 4 byte extension field length.
160 	 */
161 	testpkt.exten[7] = htonl(3); /* 3 bytes is too short. */
162 
163 	/* We send in a pkt_len of header size + 4 byte extension
164 	 * header + 24 byte MAC, this prevents the length error to
165 	 * be caught at an earlier stage
166 	 */
167 	int pkt_len = LEN_PKT_NOMAC + 4 + 24;
168 
169 	TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
170 			  process_pkt(&testpkt, &testsock, pkt_len,
171 				      MODE_SERVER, &testspkt, "UnitTest"));
172 }
173 
174 
175 void
176 test_UnauthenticatedPacketReject(void)
177 {
178 	/* Activate authentication option */
179 	ActivateOption("-a", "123");
180 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
181 
182 	int pkt_len = LEN_PKT_NOMAC;
183 
184 	/* We demand authentication, but no MAC header is present. */
185 	TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL,
186 			  process_pkt(&testpkt, &testsock, pkt_len,
187 				      MODE_SERVER, &testspkt, "UnitTest"));
188 }
189 
190 
191 void
192 test_CryptoNAKPacketReject(void)
193 {
194 	/* Activate authentication option */
195 	ActivateOption("-a", "123");
196 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
197 
198 	int pkt_len = LEN_PKT_NOMAC + 4; /* + 4 byte MAC = Crypto-NAK */
199 
200 	TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL,
201 			  process_pkt(&testpkt, &testsock, pkt_len,
202 				      MODE_SERVER, &testspkt, "UnitTest"));
203 }
204 
205 
206 void
207 test_AuthenticatedPacketInvalid(void)
208 {
209 	/* Activate authentication option */
210 	PrepareAuthenticationTestMD5(50, 9, "123456789");
211 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
212 
213 	/* Prepare the packet. */
214 	int pkt_len = LEN_PKT_NOMAC;
215 
216 	testpkt.exten[0] = htonl(50);
217 	int mac_len = make_mac(&testpkt, pkt_len,
218 			       MAX_MD5_LEN, key_ptr,
219 			       &testpkt.exten[1]);
220 
221 	pkt_len += 4 + mac_len;
222 
223 	/* Now, alter the MAC so it becomes invalid. */
224 	testpkt.exten[1] += 1;
225 
226 	TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL,
227 			  process_pkt(&testpkt, &testsock, pkt_len,
228 				      MODE_SERVER, &testspkt, "UnitTest"));
229 }
230 
231 
232 void
233 test_AuthenticatedPacketUnknownKey(void)
234 {
235 	/* Activate authentication option */
236 	PrepareAuthenticationTestMD5(30, 9, "123456789");
237 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
238 
239 	/* Prepare the packet. Note that the Key-ID expected is 30, but
240 	 * the packet has a key id of 50.
241 	 */
242 	int pkt_len = LEN_PKT_NOMAC;
243 
244 	testpkt.exten[0] = htonl(50);
245 	int mac_len = make_mac(&testpkt, pkt_len,
246 			       MAX_MD5_LEN, key_ptr,
247 			       &testpkt.exten[1]);
248 	pkt_len += 4 + mac_len;
249 
250 	TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL,
251 			  process_pkt(&testpkt, &testsock, pkt_len,
252 				      MODE_SERVER, &testspkt, "UnitTest"));
253 }
254 
255 
256 void
257 test_ServerVersionTooOld(void)
258 {
259 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
260 
261 	testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
262 					    NTP_OLDVERSION - 1,
263 					    MODE_CLIENT);
264 	TEST_ASSERT_TRUE(PKT_VERSION(testpkt.li_vn_mode) < NTP_OLDVERSION);
265 
266 	int pkt_len = LEN_PKT_NOMAC;
267 
268 	TEST_ASSERT_EQUAL(SERVER_UNUSEABLE,
269 			  process_pkt(&testpkt, &testsock, pkt_len,
270 				      MODE_SERVER, &testspkt, "UnitTest"));
271 }
272 
273 
274 void
275 test_ServerVersionTooNew(void)
276 {
277 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
278 
279 	testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
280 					    NTP_VERSION + 1,
281 					    MODE_CLIENT);
282 	TEST_ASSERT_TRUE(PKT_VERSION(testpkt.li_vn_mode) > NTP_VERSION);
283 
284 	int pkt_len = LEN_PKT_NOMAC;
285 
286 	TEST_ASSERT_EQUAL(SERVER_UNUSEABLE,
287 			  process_pkt(&testpkt, &testsock, pkt_len,
288 				      MODE_SERVER, &testspkt, "UnitTest"));
289 }
290 
291 
292 void
293 test_NonWantedMode(void)
294 {
295 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
296 
297 	testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
298 					    NTP_VERSION,
299 					    MODE_CLIENT);
300 
301 	/* The packet has a mode of MODE_CLIENT, but process_pkt expects
302 	 * MODE_SERVER
303 	 */
304 	TEST_ASSERT_EQUAL(SERVER_UNUSEABLE,
305 			  process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
306 				      MODE_SERVER, &testspkt, "UnitTest"));
307 }
308 
309 
310 /* Tests bug 1597 */
311 void
312 test_KoDRate(void)
313 {
314 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
315 
316 	testpkt.stratum = STRATUM_PKT_UNSPEC;
317 	memcpy(&testpkt.refid, "RATE", 4);
318 
319 	TEST_ASSERT_EQUAL(KOD_RATE,
320 			  process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
321 				      MODE_SERVER, &testspkt, "UnitTest"));
322 }
323 
324 
325 void
326 test_KoDDeny(void)
327 {
328 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
329 
330 	testpkt.stratum = STRATUM_PKT_UNSPEC;
331 	memcpy(&testpkt.refid, "DENY", 4);
332 
333 	TEST_ASSERT_EQUAL(KOD_DEMOBILIZE,
334 			  process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
335 				      MODE_SERVER, &testspkt, "UnitTest"));
336 }
337 
338 
339 void
340 test_RejectUnsyncedServer(void)
341 {
342 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
343 
344 	testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC,
345 					    NTP_VERSION,
346 					    MODE_SERVER);
347 
348 	TEST_ASSERT_EQUAL(SERVER_UNUSEABLE,
349 			  process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
350 				      MODE_SERVER, &testspkt, "UnitTest"));
351 }
352 
353 
354 void
355 test_RejectWrongResponseServerMode(void)
356 {
357 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
358 
359 	l_fp tmp;
360 	tmp.l_ui = 1000UL;
361 	tmp.l_uf = 0UL;
362 	HTONL_FP(&tmp, &testpkt.org);
363 
364 	tmp.l_ui = 2000UL;
365 	tmp.l_uf = 0UL;
366 	HTONL_FP(&tmp, &testspkt.xmt);
367 
368 	TEST_ASSERT_EQUAL(PACKET_UNUSEABLE,
369 			  process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
370 				      MODE_SERVER, &testspkt, "UnitTest"));
371 }
372 
373 
374 void
375 test_AcceptNoSentPacketBroadcastMode(void)
376 {
377 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
378 
379 	testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
380 					    NTP_VERSION,
381 					    MODE_BROADCAST);
382 
383 	TEST_ASSERT_EQUAL(LEN_PKT_NOMAC,
384 		  process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
385 			      MODE_BROADCAST, NULL, "UnitTest"));
386 }
387 
388 
389 void
390 test_CorrectUnauthenticatedPacket(void)
391 {
392 	TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
393 
394 	TEST_ASSERT_EQUAL(LEN_PKT_NOMAC,
395 			  process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
396 				      MODE_SERVER, &testspkt, "UnitTest"));
397 }
398 
399 
400 void
401 test_CorrectAuthenticatedPacketMD5(void)
402 {
403 	PrepareAuthenticationTestMD5(10, 15, "123456789abcdef");
404 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
405 
406 	int pkt_len = LEN_PKT_NOMAC;
407 
408 	/* Prepare the packet. */
409 	testpkt.exten[0] = htonl(10);
410 	int mac_len = make_mac(&testpkt, pkt_len,
411 			       MAX_MD5_LEN, key_ptr,
412 			       &testpkt.exten[1]);
413 
414 	pkt_len += 4 + mac_len;
415 
416 	TEST_ASSERT_EQUAL(pkt_len,
417 			  process_pkt(&testpkt, &testsock, pkt_len,
418 				      MODE_SERVER, &testspkt, "UnitTest"));
419 }
420 
421 
422 void
423 test_CorrectAuthenticatedPacketSHA1(void)
424 {
425 	PrepareAuthenticationTest(20, 15, "SHA1", "abcdefghijklmno");
426 	TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
427 
428 	int pkt_len = LEN_PKT_NOMAC;
429 
430 	/* Prepare the packet. */
431 	testpkt.exten[0] = htonl(20);
432 	int mac_len = make_mac(&testpkt, pkt_len,
433 			       MAX_MAC_LEN, key_ptr,
434 			       &testpkt.exten[1]);
435 
436 	pkt_len += 4 + mac_len;
437 
438 	TEST_ASSERT_EQUAL(pkt_len,
439 			  process_pkt(&testpkt, &testsock, pkt_len,
440 				      MODE_SERVER, &testspkt, "UnitTest"));
441 }
442