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