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