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