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