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