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