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