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