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