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