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