packetProcessing.c revision 289997
1184610Salfred#include "config.h" 2184610Salfred#include "sntptest.h" 3184610Salfred#include "networking.h" 4184610Salfred#include "ntp_stdlib.h" 5184610Salfred#include "unity.h" 6184610Salfred 7184610Salfred 8184610Salfredconst char * Version = "stub unit test Version string"; 9184610Salfred 10184610Salfred// Hacks into the key database. 11184610Salfredextern struct key* key_ptr; 12184610Salfredextern int key_cnt; 13184610Salfred 14184610Salfred 15184610Salfredvoid PrepareAuthenticationTest(int key_id,int key_len,const char* type,const void* key_seq); 16184610Salfredvoid PrepareAuthenticationTestMD5(int key_id,int key_len,const void* key_seq); 17184610Salfredvoid setUp(void); 18184610Salfredvoid tearDown(void); 19184610Salfredvoid test_TooShortLength(void); 20184610Salfredvoid test_LengthNotMultipleOfFour(void); 21184610Salfredvoid test_TooShortExtensionFieldLength(void); 22184610Salfredvoid test_UnauthenticatedPacketReject(void); 23184610Salfredvoid test_CryptoNAKPacketReject(void); 24184610Salfredvoid test_AuthenticatedPacketInvalid(void); 25184610Salfredvoid test_AuthenticatedPacketUnknownKey(void); 26263291Shselaskyvoid test_ServerVersionTooOld(void); 27263291Shselaskyvoid test_ServerVersionTooNew(void); 28184610Salfredvoid test_NonWantedMode(void); 29184610Salfredvoid test_KoDRate(void); 30184610Salfredvoid test_KoDDeny(void); 31184610Salfredvoid test_RejectUnsyncedServer(void); 32184610Salfredvoid test_RejectWrongResponseServerMode(void); 33263291Shselaskyvoid test_AcceptNoSentPacketBroadcastMode(void); 34184610Salfredvoid test_CorrectUnauthenticatedPacket(void); 35184610Salfredvoid test_CorrectAuthenticatedPacketMD5(void); 36184610Salfredvoid test_CorrectAuthenticatedPacketSHA1(void); 37184610Salfred 38184610Salfred 39184610Salfredstatic struct pkt testpkt; 40184610Salfredstatic struct pkt testspkt; 41184610Salfredstatic sockaddr_u testsock; 42263291Shselaskybool restoreKeyDb; 43184610Salfred 44184610Salfred 45184610Salfredvoid 46184610SalfredPrepareAuthenticationTest(int key_id, 47184610Salfred int key_len, 48263291Shselasky const char* type, 49184610Salfred const void* key_seq) { 50184610Salfred char str[25]; 51184610Salfred snprintf(str, 25, "%d", key_id); 52184610Salfred ActivateOption("-a", str); 53184610Salfred 54184610Salfred key_cnt = 1; 55184610Salfred key_ptr = emalloc(sizeof(struct key)); 56184610Salfred key_ptr->next = NULL; 57184610Salfred key_ptr->key_id = key_id; 58184610Salfred key_ptr->key_len = key_len; 59184610Salfred memcpy(key_ptr->type, "MD5", 3); 60184610Salfred 61184610Salfred TEST_ASSERT_TRUE(key_len < sizeof(key_ptr->key_seq)); 62184610Salfred 63184610Salfred memcpy(key_ptr->key_seq, key_seq, key_ptr->key_len); 64184610Salfred restoreKeyDb = true; 65263291Shselasky} 66184610Salfred 67184610Salfred 68263291Shselaskyvoid 69184610SalfredPrepareAuthenticationTestMD5(int key_id, 70184610Salfred int key_len, 71184610Salfred const void* key_seq) { 72184610Salfred PrepareAuthenticationTest(key_id, key_len, "MD5", key_seq); 73184610Salfred} 74263291Shselasky 75184610Salfred 76184610Salfredvoid 77184610SalfredsetUp(void) { 78263291Shselasky 79184610Salfred sntptest(); 80184610Salfred restoreKeyDb = false; 81184610Salfred 82184610Salfred /* Initialize the test packet and socket, 83208291Suqs * so they contain at least some valid data. */ 84 testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, NTP_VERSION, 85 MODE_SERVER); 86 testpkt.stratum = STRATUM_REFCLOCK; 87 memcpy(&testpkt.refid, "GPS\0", 4); 88 89 /* Set the origin timestamp of the received packet to the 90 * same value as the transmit timestamp of the sent packet. */ 91 l_fp tmp; 92 tmp.l_ui = 1000UL; 93 tmp.l_uf = 0UL; 94 95 HTONL_FP(&tmp, &testpkt.org); 96 HTONL_FP(&tmp, &testspkt.xmt); 97} 98 99 100void 101tearDown(void) { 102 103 if (restoreKeyDb) { 104 key_cnt = 0; 105 free(key_ptr); 106 key_ptr = NULL; 107 } 108 109 sntptest_destroy(); //only on the final test!! if counter == 0 etc... 110} 111 112 113 114void 115test_TooShortLength(void) { 116 TEST_ASSERT_EQUAL(PACKET_UNUSEABLE, 117 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC - 1, 118 MODE_SERVER, &testspkt, "UnitTest")); 119 TEST_ASSERT_EQUAL(PACKET_UNUSEABLE, 120 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC - 1, 121 MODE_BROADCAST, &testspkt, "UnitTest")); 122} 123 124 125void 126test_LengthNotMultipleOfFour(void) { 127 TEST_ASSERT_EQUAL(PACKET_UNUSEABLE, 128 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC + 6, 129 MODE_SERVER, &testspkt, "UnitTest")); 130 TEST_ASSERT_EQUAL(PACKET_UNUSEABLE, 131 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC + 3, 132 MODE_BROADCAST, &testspkt, "UnitTest")); 133} 134 135 136void 137test_TooShortExtensionFieldLength(void) { 138 /* The lower 16-bits are the length of the extension field. 139 * This lengths must be multiples of 4 bytes, which gives 140 * a minimum of 4 byte extension field length. */ 141 testpkt.exten[7] = htonl(3); // 3 bytes is too short. 142 143 /* We send in a pkt_len of header size + 4 byte extension 144 * header + 24 byte MAC, this prevents the length error to 145 * be caught at an earlier stage */ 146 int pkt_len = LEN_PKT_NOMAC + 4 + 24; 147 148 TEST_ASSERT_EQUAL(PACKET_UNUSEABLE, 149 process_pkt(&testpkt, &testsock, pkt_len, 150 MODE_SERVER, &testspkt, "UnitTest")); 151} 152 153 154void 155test_UnauthenticatedPacketReject(void) { 156 //sntptest(); 157 // Activate authentication option 158 ActivateOption("-a", "123"); 159 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); 160 161 int pkt_len = LEN_PKT_NOMAC; 162 163 // We demand authentication, but no MAC header is present. 164 TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL, 165 process_pkt(&testpkt, &testsock, pkt_len, 166 MODE_SERVER, &testspkt, "UnitTest")); 167} 168 169 170void 171test_CryptoNAKPacketReject(void) { 172 // Activate authentication option 173 ActivateOption("-a", "123"); 174 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); 175 176 int pkt_len = LEN_PKT_NOMAC + 4; // + 4 byte MAC = Crypto-NAK 177 178 TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL, 179 process_pkt(&testpkt, &testsock, pkt_len, 180 MODE_SERVER, &testspkt, "UnitTest")); 181} 182 183 184void 185test_AuthenticatedPacketInvalid(void) { 186 // Activate authentication option 187 PrepareAuthenticationTestMD5(50, 9, "123456789"); 188 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); 189 190 // Prepare the packet. 191 int pkt_len = LEN_PKT_NOMAC; 192 193 testpkt.exten[0] = htonl(50); 194 int mac_len = make_mac((char*)&testpkt, pkt_len, 195 MAX_MD5_LEN, key_ptr, 196 (char*)&testpkt.exten[1]); 197 198 pkt_len += 4 + mac_len; 199 200 // Now, alter the MAC so it becomes invalid. 201 testpkt.exten[1] += 1; 202 203 TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL, 204 process_pkt(&testpkt, &testsock, pkt_len, 205 MODE_SERVER, &testspkt, "UnitTest")); 206} 207 208 209void 210test_AuthenticatedPacketUnknownKey(void) { 211 // Activate authentication option 212 PrepareAuthenticationTestMD5(30, 9, "123456789"); 213 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); 214 215 // Prepare the packet. Observe that the Key-ID expected is 30, 216 // but the packet has a key id of 50. 217 int pkt_len = LEN_PKT_NOMAC; 218 219 testpkt.exten[0] = htonl(50); 220 int mac_len = make_mac((char*)&testpkt, pkt_len, 221 MAX_MD5_LEN, key_ptr, 222 (char*)&testpkt.exten[1]); 223 pkt_len += 4 + mac_len; 224 225 TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL, 226 process_pkt(&testpkt, &testsock, pkt_len, 227 MODE_SERVER, &testspkt, "UnitTest")); 228} 229 230 231void 232test_ServerVersionTooOld(void) { 233 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); 234 235 testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, 236 NTP_OLDVERSION - 1, 237 MODE_CLIENT); 238 TEST_ASSERT_TRUE(PKT_VERSION(testpkt.li_vn_mode) < NTP_OLDVERSION); 239 240 int pkt_len = LEN_PKT_NOMAC; 241 242 TEST_ASSERT_EQUAL(SERVER_UNUSEABLE, 243 process_pkt(&testpkt, &testsock, pkt_len, 244 MODE_SERVER, &testspkt, "UnitTest")); 245} 246 247 248void 249test_ServerVersionTooNew(void) { 250 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); 251 252 testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, 253 NTP_VERSION + 1, 254 MODE_CLIENT); 255 TEST_ASSERT_TRUE(PKT_VERSION(testpkt.li_vn_mode) > NTP_VERSION); 256 257 int pkt_len = LEN_PKT_NOMAC; 258 259 TEST_ASSERT_EQUAL(SERVER_UNUSEABLE, 260 process_pkt(&testpkt, &testsock, pkt_len, 261 MODE_SERVER, &testspkt, "UnitTest")); 262} 263 264 265void 266test_NonWantedMode(void) { 267 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); 268 269 testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, 270 NTP_VERSION, 271 MODE_CLIENT); 272 273 // The packet has a mode of MODE_CLIENT, but process_pkt expects MODE_SERVER 274 275 TEST_ASSERT_EQUAL(SERVER_UNUSEABLE, 276 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, 277 MODE_SERVER, &testspkt, "UnitTest")); 278} 279 280 281/* Tests bug 1597 */ 282void 283test_KoDRate(void) { 284 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); 285 286 testpkt.stratum = STRATUM_PKT_UNSPEC; 287 memcpy(&testpkt.refid, "RATE", 4); 288 289 TEST_ASSERT_EQUAL(KOD_RATE, 290 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, 291 MODE_SERVER, &testspkt, "UnitTest")); 292} 293 294 295void 296test_KoDDeny(void) { 297 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); 298 299 testpkt.stratum = STRATUM_PKT_UNSPEC; 300 memcpy(&testpkt.refid, "DENY", 4); 301 302 TEST_ASSERT_EQUAL(KOD_DEMOBILIZE, 303 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, 304 MODE_SERVER, &testspkt, "UnitTest")); 305} 306 307 308void 309test_RejectUnsyncedServer(void) { 310 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); 311 312 testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC, 313 NTP_VERSION, 314 MODE_SERVER); 315 316 TEST_ASSERT_EQUAL(SERVER_UNUSEABLE, 317 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, 318 MODE_SERVER, &testspkt, "UnitTest")); 319} 320 321 322void 323test_RejectWrongResponseServerMode(void) { 324 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); 325 326 l_fp tmp; 327 tmp.l_ui = 1000UL; 328 tmp.l_uf = 0UL; 329 HTONL_FP(&tmp, &testpkt.org); 330 331 tmp.l_ui = 2000UL; 332 tmp.l_uf = 0UL; 333 HTONL_FP(&tmp, &testspkt.xmt); 334 335 TEST_ASSERT_EQUAL(PACKET_UNUSEABLE, 336 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, 337 MODE_SERVER, &testspkt, "UnitTest")); 338} 339 340 341void 342test_AcceptNoSentPacketBroadcastMode(void) { 343 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); 344 345 testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, 346 NTP_VERSION, 347 MODE_BROADCAST); 348 349 TEST_ASSERT_EQUAL(LEN_PKT_NOMAC, 350 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, 351 MODE_BROADCAST, NULL, "UnitTest")); 352} 353 354 355void 356test_CorrectUnauthenticatedPacket(void) { 357 TEST_ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION)); 358 359 TEST_ASSERT_EQUAL(LEN_PKT_NOMAC, 360 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC, 361 MODE_SERVER, &testspkt, "UnitTest")); 362} 363 364 365void 366test_CorrectAuthenticatedPacketMD5(void) { 367 PrepareAuthenticationTestMD5(10, 15, "123456789abcdef"); 368 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); 369 370 int pkt_len = LEN_PKT_NOMAC; 371 372 // Prepare the packet. 373 testpkt.exten[0] = htonl(10); 374 int mac_len = make_mac((char*)&testpkt, pkt_len, 375 MAX_MD5_LEN, key_ptr, 376 (char*)&testpkt.exten[1]); 377 378 pkt_len += 4 + mac_len; 379 380 TEST_ASSERT_EQUAL(pkt_len, 381 process_pkt(&testpkt, &testsock, pkt_len, 382 MODE_SERVER, &testspkt, "UnitTest")); 383 384} 385 386 387void 388test_CorrectAuthenticatedPacketSHA1(void) { 389 PrepareAuthenticationTest(20, 15, "SHA1", "abcdefghijklmno"); 390 TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); 391 392 int pkt_len = LEN_PKT_NOMAC; 393 394 // Prepare the packet. 395 testpkt.exten[0] = htonl(20); 396 int mac_len = make_mac((char*)&testpkt, pkt_len, 397 MAX_MAC_LEN, key_ptr, 398 (char*)&testpkt.exten[1]); 399 400 pkt_len += 4 + mac_len; 401 402 TEST_ASSERT_EQUAL(pkt_len, 403 process_pkt(&testpkt, &testsock, pkt_len, 404 MODE_SERVER, &testspkt, "UnitTest")); 405} 406