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