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