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