packetProcessing.c revision 290000
1#include "config.h" 2#include "sntptest.h" 3#include "networking.h" 4#include "ntp_stdlib.h" 5#include "unity.h" 6 7 8const char * Version = "stub unit test Version string"; 9 10// Hacks into the key database. 11extern struct key* key_ptr; 12extern int key_cnt; 13 14 15void PrepareAuthenticationTest(int key_id,int key_len,const char* type,const void* key_seq); 16void PrepareAuthenticationTestMD5(int key_id,int key_len,const void* key_seq); 17void setUp(void); 18void tearDown(void); 19void test_TooShortLength(void); 20void test_LengthNotMultipleOfFour(void); 21void test_TooShortExtensionFieldLength(void); 22void test_UnauthenticatedPacketReject(void); 23void test_CryptoNAKPacketReject(void); 24void test_AuthenticatedPacketInvalid(void); 25void test_AuthenticatedPacketUnknownKey(void); 26void test_ServerVersionTooOld(void); 27void test_ServerVersionTooNew(void); 28void test_NonWantedMode(void); 29void test_KoDRate(void); 30void test_KoDDeny(void); 31void test_RejectUnsyncedServer(void); 32void test_RejectWrongResponseServerMode(void); 33void test_AcceptNoSentPacketBroadcastMode(void); 34void test_CorrectUnauthenticatedPacket(void); 35void test_CorrectAuthenticatedPacketMD5(void); 36void test_CorrectAuthenticatedPacketSHA1(void); 37 38 39static struct pkt testpkt; 40static struct pkt testspkt; 41static sockaddr_u testsock; 42bool restoreKeyDb; 43 44 45void 46PrepareAuthenticationTest(int key_id, 47 int key_len, 48 const char* type, 49 const void* key_seq) { 50 char str[25]; 51 snprintf(str, 25, "%d", key_id); 52 ActivateOption("-a", str); 53 54 key_cnt = 1; 55 key_ptr = emalloc(sizeof(struct key)); 56 key_ptr->next = NULL; 57 key_ptr->key_id = key_id; 58 key_ptr->key_len = key_len; 59 memcpy(key_ptr->type, "MD5", 3); 60 61 TEST_ASSERT_TRUE(key_len < sizeof(key_ptr->key_seq)); 62 63 memcpy(key_ptr->key_seq, key_seq, key_ptr->key_len); 64 restoreKeyDb = true; 65} 66 67 68void 69PrepareAuthenticationTestMD5(int key_id, 70 int key_len, 71 const void* key_seq) { 72 PrepareAuthenticationTest(key_id, key_len, "MD5", key_seq); 73} 74 75 76void 77setUp(void) { 78 79 sntptest(); 80 restoreKeyDb = false; 81 82 /* Initialize the test packet and socket, 83 * 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