packetProcessing.c revision 290000
1#include "config.h"
2#include "sntptest.h"
3#include "networking.h"
4#include "ntp_stdlib.h"
5#include "unity.h"
6
7
8const char * Version = "stub unit test Version string";
9
10// Hacks into the key database.
11extern struct key* key_ptr;
12extern int key_cnt;
13
14
15void PrepareAuthenticationTest(int key_id,int key_len,const char* type,const void* key_seq);
16void PrepareAuthenticationTestMD5(int key_id,int key_len,const void* key_seq);
17void setUp(void);
18void tearDown(void);
19void test_TooShortLength(void);
20void test_LengthNotMultipleOfFour(void);
21void test_TooShortExtensionFieldLength(void);
22void test_UnauthenticatedPacketReject(void);
23void test_CryptoNAKPacketReject(void);
24void test_AuthenticatedPacketInvalid(void);
25void test_AuthenticatedPacketUnknownKey(void);
26void test_ServerVersionTooOld(void);
27void test_ServerVersionTooNew(void);
28void test_NonWantedMode(void);
29void test_KoDRate(void);
30void test_KoDDeny(void);
31void test_RejectUnsyncedServer(void);
32void test_RejectWrongResponseServerMode(void);
33void test_AcceptNoSentPacketBroadcastMode(void);
34void test_CorrectUnauthenticatedPacket(void);
35void test_CorrectAuthenticatedPacketMD5(void);
36void test_CorrectAuthenticatedPacketSHA1(void);
37
38
39static struct pkt testpkt;
40static struct pkt testspkt;
41static sockaddr_u testsock;
42bool restoreKeyDb;
43
44
45void
46PrepareAuthenticationTest(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
68void
69PrepareAuthenticationTestMD5(int key_id,
70							   int key_len,
71							   const void* key_seq) {
72	PrepareAuthenticationTest(key_id, key_len, "MD5", key_seq);
73}
74
75
76void
77setUp(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
100void
101tearDown(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
114void
115test_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
125void
126test_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
136void
137test_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
154void
155test_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
170void
171test_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
184void
185test_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
209void
210test_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
231void
232test_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
248void
249test_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
265void
266test_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 */
282void
283test_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
295void
296test_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
308void
309test_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
322void
323test_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
341void
342test_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
355void
356test_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
365void
366test_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
387void
388test_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