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