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