packetProcessing.c revision 294904
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
14const char * Version = "stub unit test Version string";
15
16// Hacks into the key database.
17extern struct key* key_ptr;
18extern int key_cnt;
19
20
21void PrepareAuthenticationTest(int key_id,int key_len,const char* type,const void* key_seq);
22void PrepareAuthenticationTestMD5(int key_id,int key_len,const void* key_seq);
23void setUp(void);
24void tearDown(void);
25void test_TooShortLength(void);
26void test_LengthNotMultipleOfFour(void);
27void test_TooShortExtensionFieldLength(void);
28void test_UnauthenticatedPacketReject(void);
29void test_CryptoNAKPacketReject(void);
30void test_AuthenticatedPacketInvalid(void);
31void test_AuthenticatedPacketUnknownKey(void);
32void test_ServerVersionTooOld(void);
33void test_ServerVersionTooNew(void);
34void test_NonWantedMode(void);
35void test_KoDRate(void);
36void test_KoDDeny(void);
37void test_RejectUnsyncedServer(void);
38void test_RejectWrongResponseServerMode(void);
39void test_AcceptNoSentPacketBroadcastMode(void);
40void test_CorrectUnauthenticatedPacket(void);
41void test_CorrectAuthenticatedPacketMD5(void);
42void test_CorrectAuthenticatedPacketSHA1(void);
43
44
45static struct pkt testpkt;
46static struct pkt testspkt;
47static sockaddr_u testsock;
48bool restoreKeyDb;
49
50
51void
52PrepareAuthenticationTest(
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
77void
78PrepareAuthenticationTestMD5(
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
88void
89setUp(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
115void
116tearDown(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
128void
129test_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
140void
141test_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
152void
153test_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
173void
174test_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
189void
190test_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
204void
205test_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
230void
231test_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
254void
255test_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
272void
273test_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
290void
291test_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 */
309void
310test_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
323void
324test_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
337void
338test_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
352void
353test_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
372void
373test_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
387void
388test_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
398void
399test_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
420void
421test_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