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