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