1 #include "g_sntptest.h"
4 #include "networking.h"
5 #include "ntp_stdlib.h"
11 // Hacks into the key database.
15 class packetProcessingTest : public sntptest {
22 void PrepareAuthenticationTest(int key_id,
25 const void* key_seq) {
29 ActivateOption("-a", ss.str().c_str());
34 key_ptr->key_id = key_id;
35 key_ptr->key_len = key_len;
36 memcpy(key_ptr->type, "MD5", 3);
38 ASSERT_TRUE(key_len < sizeof(key_ptr->key_seq));
40 memcpy(key_ptr->key_seq, key_seq, key_ptr->key_len);
44 void PrepareAuthenticationTest(int key_id,
46 const void* key_seq) {
47 PrepareAuthenticationTest(key_id, key_len, "MD5", key_seq);
50 virtual void SetUp() {
53 /* Initialize the test packet and socket,
54 * so they contain at least some valid data. */
55 testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING, NTP_VERSION,
57 testpkt.stratum = STRATUM_REFCLOCK;
58 memcpy(&testpkt.refid, "GPS\0", 4);
60 /* Set the origin timestamp of the received packet to the
61 * same value as the transmit timestamp of the sent packet. */
66 HTONL_FP(&tmp, &testpkt.org);
67 HTONL_FP(&tmp, &testspkt.xmt);
70 virtual void TearDown() {
79 TEST_F(packetProcessingTest, TooShortLength) {
80 EXPECT_EQ(PACKET_UNUSEABLE,
81 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC - 1,
82 MODE_SERVER, &testspkt, "UnitTest"));
83 EXPECT_EQ(PACKET_UNUSEABLE,
84 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC - 1,
85 MODE_BROADCAST, &testspkt, "UnitTest"));
88 TEST_F(packetProcessingTest, LengthNotMultipleOfFour) {
89 EXPECT_EQ(PACKET_UNUSEABLE,
90 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC + 6,
91 MODE_SERVER, &testspkt, "UnitTest"));
92 EXPECT_EQ(PACKET_UNUSEABLE,
93 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC + 3,
94 MODE_BROADCAST, &testspkt, "UnitTest"));
97 TEST_F(packetProcessingTest, TooShortExtensionFieldLength) {
98 /* The lower 16-bits are the length of the extension field.
99 * This lengths must be multiples of 4 bytes, which gives
100 * a minimum of 4 byte extension field length. */
101 testpkt.exten[7] = htonl(3); // 3 bytes is too short.
103 /* We send in a pkt_len of header size + 4 byte extension
104 * header + 24 byte MAC, this prevents the length error to
105 * be caught at an earlier stage */
106 int pkt_len = LEN_PKT_NOMAC + 4 + 24;
108 EXPECT_EQ(PACKET_UNUSEABLE,
109 process_pkt(&testpkt, &testsock, pkt_len,
110 MODE_SERVER, &testspkt, "UnitTest"));
113 TEST_F(packetProcessingTest, UnauthenticatedPacketReject) {
114 // Activate authentication option
115 ActivateOption("-a", "123");
116 ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
118 int pkt_len = LEN_PKT_NOMAC;
120 // We demand authentication, but no MAC header is present.
121 EXPECT_EQ(SERVER_AUTH_FAIL,
122 process_pkt(&testpkt, &testsock, pkt_len,
123 MODE_SERVER, &testspkt, "UnitTest"));
126 TEST_F(packetProcessingTest, CryptoNAKPacketReject) {
127 // Activate authentication option
128 ActivateOption("-a", "123");
129 ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
131 int pkt_len = LEN_PKT_NOMAC + 4; // + 4 byte MAC = Crypto-NAK
133 EXPECT_EQ(SERVER_AUTH_FAIL,
134 process_pkt(&testpkt, &testsock, pkt_len,
135 MODE_SERVER, &testspkt, "UnitTest"));
138 TEST_F(packetProcessingTest, AuthenticatedPacketInvalid) {
139 // Activate authentication option
140 PrepareAuthenticationTest(50, 9, "123456789");
141 ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
143 // Prepare the packet.
144 int pkt_len = LEN_PKT_NOMAC;
146 testpkt.exten[0] = htonl(50);
147 int mac_len = make_mac((char*)&testpkt, pkt_len,
148 MAX_MD5_LEN, key_ptr,
149 (char*)&testpkt.exten[1]);
151 pkt_len += 4 + mac_len;
153 // Now, alter the MAC so it becomes invalid.
154 testpkt.exten[1] += 1;
156 EXPECT_EQ(SERVER_AUTH_FAIL,
157 process_pkt(&testpkt, &testsock, pkt_len,
158 MODE_SERVER, &testspkt, "UnitTest"));
161 TEST_F(packetProcessingTest, AuthenticatedPacketUnknownKey) {
162 // Activate authentication option
163 PrepareAuthenticationTest(30, 9, "123456789");
164 ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
166 // Prepare the packet. Observe that the Key-ID expected is 30,
167 // but the packet has a key id of 50.
168 int pkt_len = LEN_PKT_NOMAC;
170 testpkt.exten[0] = htonl(50);
171 int mac_len = make_mac((char*)&testpkt, pkt_len,
172 MAX_MD5_LEN, key_ptr,
173 (char*)&testpkt.exten[1]);
174 pkt_len += 4 + mac_len;
176 EXPECT_EQ(SERVER_AUTH_FAIL,
177 process_pkt(&testpkt, &testsock, pkt_len,
178 MODE_SERVER, &testspkt, "UnitTest"));
181 TEST_F(packetProcessingTest, ServerVersionTooOld) {
182 ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
184 testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
187 ASSERT_LT(PKT_VERSION(testpkt.li_vn_mode), NTP_OLDVERSION);
189 int pkt_len = LEN_PKT_NOMAC;
191 EXPECT_EQ(SERVER_UNUSEABLE,
192 process_pkt(&testpkt, &testsock, pkt_len,
193 MODE_SERVER, &testspkt, "UnitTest"));
196 TEST_F(packetProcessingTest, ServerVersionTooNew) {
197 ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
199 testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
202 ASSERT_GT(PKT_VERSION(testpkt.li_vn_mode), NTP_VERSION);
204 int pkt_len = LEN_PKT_NOMAC;
206 EXPECT_EQ(SERVER_UNUSEABLE,
207 process_pkt(&testpkt, &testsock, pkt_len,
208 MODE_SERVER, &testspkt, "UnitTest"));
211 TEST_F(packetProcessingTest, NonWantedMode) {
212 ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
214 testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
218 // The packet has a mode of MODE_CLIENT, but process_pkt expects MODE_SERVER
220 EXPECT_EQ(SERVER_UNUSEABLE,
221 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
222 MODE_SERVER, &testspkt, "UnitTest"));
226 TEST_F(packetProcessingTest, KoDRate) {
227 ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
229 testpkt.stratum = STRATUM_PKT_UNSPEC;
230 memcpy(&testpkt.refid, "RATE", 4);
233 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
234 MODE_SERVER, &testspkt, "UnitTest"));
237 TEST_F(packetProcessingTest, KoDDeny) {
238 ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
240 testpkt.stratum = STRATUM_PKT_UNSPEC;
241 memcpy(&testpkt.refid, "DENY", 4);
243 EXPECT_EQ(KOD_DEMOBILIZE,
244 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
245 MODE_SERVER, &testspkt, "UnitTest"));
248 TEST_F(packetProcessingTest, RejectUnsyncedServer) {
249 ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
251 testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC,
255 EXPECT_EQ(SERVER_UNUSEABLE,
256 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
257 MODE_SERVER, &testspkt, "UnitTest"));
260 TEST_F(packetProcessingTest, RejectWrongResponseServerMode) {
261 ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
266 HTONL_FP(&tmp, &testpkt.org);
270 HTONL_FP(&tmp, &testspkt.xmt);
272 EXPECT_EQ(PACKET_UNUSEABLE,
273 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
274 MODE_SERVER, &testspkt, "UnitTest"));
277 TEST_F(packetProcessingTest, AcceptNoSentPacketBroadcastMode) {
278 ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
280 testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
284 EXPECT_EQ(LEN_PKT_NOMAC,
285 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
286 MODE_BROADCAST, NULL, "UnitTest"));
289 TEST_F(packetProcessingTest, CorrectUnauthenticatedPacket) {
290 ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
292 EXPECT_EQ(LEN_PKT_NOMAC,
293 process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
294 MODE_SERVER, &testspkt, "UnitTest"));
297 TEST_F(packetProcessingTest, CorrectAuthenticatedPacketMD5) {
298 PrepareAuthenticationTest(10, 15, "123456789abcdef");
299 ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
301 int pkt_len = LEN_PKT_NOMAC;
303 // Prepare the packet.
304 testpkt.exten[0] = htonl(10);
305 int mac_len = make_mac((char*)&testpkt, pkt_len,
306 MAX_MD5_LEN, key_ptr,
307 (char*)&testpkt.exten[1]);
309 pkt_len += 4 + mac_len;
312 process_pkt(&testpkt, &testsock, pkt_len,
313 MODE_SERVER, &testspkt, "UnitTest"));
317 TEST_F(packetProcessingTest, CorrectAuthenticatedPacketSHA1) {
318 PrepareAuthenticationTest(20, 15, "SHA1", "abcdefghijklmno");
319 ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
321 int pkt_len = LEN_PKT_NOMAC;
323 // Prepare the packet.
324 testpkt.exten[0] = htonl(20);
325 int mac_len = make_mac((char*)&testpkt, pkt_len,
326 MAX_MAC_LEN, key_ptr,
327 (char*)&testpkt.exten[1]);
329 pkt_len += 4 + mac_len;
332 process_pkt(&testpkt, &testsock, pkt_len,
333 MODE_SERVER, &testspkt, "UnitTest"));