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