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