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