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