From: Tomek Mrugalski Date: Thu, 25 Jun 2015 09:32:47 +0000 (+0200) Subject: packetProcessing.c: X-Git-Tag: NTP_4_2_8P3_RC3~24^2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3aa66b605ca7d4a4bcbe44399883cc269672a6fd;p=thirdparty%2Fntp.git packetProcessing.c: new file g_packetProcessing.cpp: Rename: sntp/tests/packetProcessing.cpp -> sntp/tests/g_packetProcessing.cpp packetProcessing.c: fixed array size, so that it doesn't crash on 64bit integer bk: 558bcabf3I_BuwVo6BUKWlzfZYlsyA --- diff --git a/sntp/tests/packetProcessing.cpp b/sntp/tests/g_packetProcessing.cpp similarity index 100% rename from sntp/tests/packetProcessing.cpp rename to sntp/tests/g_packetProcessing.cpp diff --git a/sntp/tests/packetProcessing.c b/sntp/tests/packetProcessing.c new file mode 100644 index 000000000..bdf2d00a9 --- /dev/null +++ b/sntp/tests/packetProcessing.c @@ -0,0 +1,331 @@ +#include "config.h" +#include "sntptest.h" +#include "networking.h" +#include "ntp_stdlib.h" +#include "unity.h" + +const char * Version = "stub unit test Version string"; + +// Hacks into the key database. +extern struct key* key_ptr; +extern int key_cnt; + + +static struct pkt testpkt; +static struct pkt testspkt; +static sockaddr_u testsock; +static bool restoreKeyDb; + +void PrepareAuthenticationTest(int key_id, + int key_len, + const char* type, + const void* key_seq) { + char str[25]; + sprintf(str, "%d", key_id); + ActivateOption("-a", str); + + key_cnt = 1; + key_ptr = malloc(sizeof(struct key)); + key_ptr->next = NULL; + key_ptr->key_id = key_id; + key_ptr->key_len = key_len; + memcpy(key_ptr->type, "MD5", 3); + + TEST_ASSERT_TRUE(key_len < sizeof(key_ptr->key_seq)); + + memcpy(key_ptr->key_seq, key_seq, key_ptr->key_len); + restoreKeyDb = true; +} + +void PrepareAuthenticationTestMD5(int key_id, + int key_len, + const void* key_seq) { + PrepareAuthenticationTest(key_id, key_len, "MD5", key_seq); +} + +void SetUp() { + restoreKeyDb = false; + + /* Initialize the test packet and socket, + * so they contain at least some valid data. */ + testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, NTP_VERSION, + MODE_SERVER); + testpkt.stratum = STRATUM_REFCLOCK; + memcpy(&testpkt.refid, "GPS\0", 4); + + /* Set the origin timestamp of the received packet to the + * same value as the transmit timestamp of the sent packet. */ + l_fp tmp; + tmp.l_ui = 1000UL; + tmp.l_uf = 0UL; + + HTONL_FP(&tmp, &testpkt.org); + HTONL_FP(&tmp, &testspkt.xmt); +} + +void TearDown() { + if (restoreKeyDb) { + key_cnt = 0; + free(key_ptr); + key_ptr = NULL; + } +} + + + +void test_TooShortLength(void) { + TEST_ASSERT_EQUAL(PACKET_UNUSEABLE, + process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC - 1, + MODE_SERVER, &testspkt, "UnitTest")); + TEST_ASSERT_EQUAL(PACKET_UNUSEABLE, + process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC - 1, + MODE_BROADCAST, &testspkt, "UnitTest")); +} + +void test_LengthNotMultipleOfFour(void) { + TEST_ASSERT_EQUAL(PACKET_UNUSEABLE, + process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC + 6, + MODE_SERVER, &testspkt, "UnitTest")); + TEST_ASSERT_EQUAL(PACKET_UNUSEABLE, + process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC + 3, + MODE_BROADCAST, &testspkt, "UnitTest")); +} + +void test_TooShortExtensionFieldLength(void) { + /* The lower 16-bits are the length of the extension field. + * This lengths must be multiples of 4 bytes, which gives + * a minimum of 4 byte extension field length. */ + testpkt.exten[7] = htonl(3); // 3 bytes is too short. + + /* We send in a pkt_len of header size + 4 byte extension + * header + 24 byte MAC, this prevents the length error to + * be caught at an earlier stage */ + int pkt_len = LEN_PKT_NOMAC + 4 + 24; + + TEST_ASSERT_EQUAL(PACKET_UNUSEABLE, + process_pkt(&testpkt, &testsock, pkt_len, + MODE_SERVER, &testspkt, "UnitTest")); +} + +void test_UnauthenticatedPacketReject(void) { + // Activate authentication option + ActivateOption("-a", "123"); + TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); + + int pkt_len = LEN_PKT_NOMAC; + + // We demand authentication, but no MAC header is present. + TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL, + process_pkt(&testpkt, &testsock, pkt_len, + MODE_SERVER, &testspkt, "UnitTest")); +} + +void test_CryptoNAKPacketReject(void) { + // Activate authentication option + ActivateOption("-a", "123"); + TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); + + int pkt_len = LEN_PKT_NOMAC + 4; // + 4 byte MAC = Crypto-NAK + + TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL, + process_pkt(&testpkt, &testsock, pkt_len, + MODE_SERVER, &testspkt, "UnitTest")); +} + +void test_AuthenticatedPacketInvalid(void) { + // Activate authentication option + PrepareAuthenticationTestMD5(50, 9, "123456789"); + TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); + + // Prepare the packet. + int pkt_len = LEN_PKT_NOMAC; + + testpkt.exten[0] = htonl(50); + int mac_len = make_mac((char*)&testpkt, pkt_len, + MAX_MD5_LEN, key_ptr, + (char*)&testpkt.exten[1]); + + pkt_len += 4 + mac_len; + + // Now, alter the MAC so it becomes invalid. + testpkt.exten[1] += 1; + + TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL, + process_pkt(&testpkt, &testsock, pkt_len, + MODE_SERVER, &testspkt, "UnitTest")); +} + +void test_AuthenticatedPacketUnknownKey(void) { + // Activate authentication option + PrepareAuthenticationTestMD5(30, 9, "123456789"); + TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); + + // Prepare the packet. Observe that the Key-ID expected is 30, + // but the packet has a key id of 50. + int pkt_len = LEN_PKT_NOMAC; + + testpkt.exten[0] = htonl(50); + int mac_len = make_mac((char*)&testpkt, pkt_len, + MAX_MD5_LEN, key_ptr, + (char*)&testpkt.exten[1]); + pkt_len += 4 + mac_len; + + TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL, + process_pkt(&testpkt, &testsock, pkt_len, + MODE_SERVER, &testspkt, "UnitTest")); +} + +void test_ServerVersionTooOld(void) { + TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); + + testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, + NTP_OLDVERSION - 1, + MODE_CLIENT); + TEST_ASSERT_TRUE(PKT_VERSION(testpkt.li_vn_mode) < NTP_OLDVERSION); + + int pkt_len = LEN_PKT_NOMAC; + + TEST_ASSERT_EQUAL(SERVER_UNUSEABLE, + process_pkt(&testpkt, &testsock, pkt_len, + MODE_SERVER, &testspkt, "UnitTest")); +} + +void test_ServerVersionTooNew(void) { + TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); + + testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, + NTP_VERSION + 1, + MODE_CLIENT); + TEST_ASSERT_TRUE(PKT_VERSION(testpkt.li_vn_mode) > NTP_VERSION); + + int pkt_len = LEN_PKT_NOMAC; + + TEST_ASSERT_EQUAL(SERVER_UNUSEABLE, + process_pkt(&testpkt, &testsock, pkt_len, + MODE_SERVER, &testspkt, "UnitTest")); +} + +void test_NonWantedMode(void) { + TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); + + testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, + NTP_VERSION, + MODE_CLIENT); + + // The packet has a mode of MODE_CLIENT, but process_pkt expects MODE_SERVER + + TEST_ASSERT_EQUAL(SERVER_UNUSEABLE, + process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, + MODE_SERVER, &testspkt, "UnitTest")); +} + +/* Tests bug 1597 */ +void test_KoDRate(void) { + TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); + + testpkt.stratum = STRATUM_PKT_UNSPEC; + memcpy(&testpkt.refid, "RATE", 4); + + TEST_ASSERT_EQUAL(KOD_RATE, + process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, + MODE_SERVER, &testspkt, "UnitTest")); +} + +void test_KoDDeny(void) { + TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); + + testpkt.stratum = STRATUM_PKT_UNSPEC; + memcpy(&testpkt.refid, "DENY", 4); + + TEST_ASSERT_EQUAL(KOD_DEMOBILIZE, + process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, + MODE_SERVER, &testspkt, "UnitTest")); +} + +void test_RejectUnsyncedServer(void) { + TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); + + testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC, + NTP_VERSION, + MODE_SERVER); + + TEST_ASSERT_EQUAL(SERVER_UNUSEABLE, + process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, + MODE_SERVER, &testspkt, "UnitTest")); +} + +void test_RejectWrongResponseServerMode(void) { + TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); + + l_fp tmp; + tmp.l_ui = 1000UL; + tmp.l_uf = 0UL; + HTONL_FP(&tmp, &testpkt.org); + + tmp.l_ui = 2000UL; + tmp.l_uf = 0UL; + HTONL_FP(&tmp, &testspkt.xmt); + + TEST_ASSERT_EQUAL(PACKET_UNUSEABLE, + process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, + MODE_SERVER, &testspkt, "UnitTest")); +} + +void test_AcceptNoSentPacketBroadcastMode(void) { + TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); + + testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, + NTP_VERSION, + MODE_BROADCAST); + + TEST_ASSERT_EQUAL(LEN_PKT_NOMAC, + process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, + MODE_BROADCAST, NULL, "UnitTest")); +} + +void test_CorrectUnauthenticatedPacket(void) { + TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); + + TEST_ASSERT_EQUAL(LEN_PKT_NOMAC, + process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, + MODE_SERVER, &testspkt, "UnitTest")); +} + +void test_CorrectAuthenticatedPacketMD5(void) { + PrepareAuthenticationTestMD5(10, 15, "123456789abcdef"); + TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); + + int pkt_len = LEN_PKT_NOMAC; + + // Prepare the packet. + testpkt.exten[0] = htonl(10); + int mac_len = make_mac((char*)&testpkt, pkt_len, + MAX_MD5_LEN, key_ptr, + (char*)&testpkt.exten[1]); + + pkt_len += 4 + mac_len; + + TEST_ASSERT_EQUAL(pkt_len, + process_pkt(&testpkt, &testsock, pkt_len, + MODE_SERVER, &testspkt, "UnitTest")); + +} + +void test_CorrectAuthenticatedPacketSHA1(void) { + PrepareAuthenticationTest(20, 15, "SHA1", "abcdefghijklmno"); + TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); + + int pkt_len = LEN_PKT_NOMAC; + + // Prepare the packet. + testpkt.exten[0] = htonl(20); + int mac_len = make_mac((char*)&testpkt, pkt_len, + MAX_MAC_LEN, key_ptr, + (char*)&testpkt.exten[1]); + + pkt_len += 4 + mac_len; + + TEST_ASSERT_EQUAL(pkt_len, + process_pkt(&testpkt, &testsock, pkt_len, + MODE_SERVER, &testspkt, "UnitTest")); +}