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