]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - contrib/ntp/sntp/tests/g_packetProcessing.cpp
Fix a regression with SA-15:24 patch that prevented NIS from
[FreeBSD/releng/10.2.git] / contrib / ntp / sntp / tests / g_packetProcessing.cpp
1 #include "g_sntptest.h"
2
3 extern "C" {
4 #include "networking.h"
5 #include "ntp_stdlib.h"
6 };
7
8 #include <sstream>
9 #include <string>
10
11 // Hacks into the key database.
12 extern key* key_ptr;
13 extern int key_cnt;
14
15 class packetProcessingTest : public sntptest {
16 protected:
17         pkt testpkt;
18         pkt testspkt;
19         sockaddr_u testsock;
20         bool restoreKeyDb;
21
22         void PrepareAuthenticationTest(int key_id,
23                                                                    int key_len,
24                                                                    const char* type,
25                                                                    const void* key_seq) {
26                 std::stringstream ss;
27                 ss << key_id;
28
29                 ActivateOption("-a", ss.str().c_str());
30
31                 key_cnt = 1;
32                 key_ptr = new key;
33                 key_ptr->next = NULL;
34                 key_ptr->key_id = key_id;
35                 key_ptr->key_len = key_len;
36                 memcpy(key_ptr->type, "MD5", 3);
37
38                 ASSERT_TRUE(key_len < sizeof(key_ptr->key_seq));
39
40                 memcpy(key_ptr->key_seq, key_seq, key_ptr->key_len);
41                 restoreKeyDb = true;
42         }
43
44         void PrepareAuthenticationTest(int key_id,
45                                                                    int key_len,
46                                                                    const void* key_seq) {
47                 PrepareAuthenticationTest(key_id, key_len, "MD5", key_seq);
48         }
49
50         virtual void SetUp() {
51                 restoreKeyDb = false;
52
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,
56                                                                                         MODE_SERVER);
57                 testpkt.stratum = STRATUM_REFCLOCK;
58                 memcpy(&testpkt.refid, "GPS\0", 4);
59
60                 /* Set the origin timestamp of the received packet to the
61                  * same value as the transmit timestamp of the sent packet. */
62                 l_fp tmp;
63                 tmp.l_ui = 1000UL;
64                 tmp.l_uf = 0UL;
65
66                 HTONL_FP(&tmp, &testpkt.org);
67                 HTONL_FP(&tmp, &testspkt.xmt);
68         }
69
70         virtual void TearDown() {
71                 if (restoreKeyDb) {
72                         key_cnt = 0;
73                         delete key_ptr;
74                         key_ptr = NULL;
75                 }
76         }
77 };
78
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"));
86 }
87
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"));
95 }
96
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.
102
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;
107
108         EXPECT_EQ(PACKET_UNUSEABLE,
109                           process_pkt(&testpkt, &testsock, pkt_len,
110                                                   MODE_SERVER, &testspkt, "UnitTest"));
111 }
112
113 TEST_F(packetProcessingTest, UnauthenticatedPacketReject) {
114         // Activate authentication option
115         ActivateOption("-a", "123");
116         ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
117
118         int pkt_len = LEN_PKT_NOMAC;
119
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"));
124 }
125
126 TEST_F(packetProcessingTest, CryptoNAKPacketReject) {
127         // Activate authentication option
128         ActivateOption("-a", "123");
129         ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
130
131         int pkt_len = LEN_PKT_NOMAC + 4; // + 4 byte MAC = Crypto-NAK
132
133         EXPECT_EQ(SERVER_AUTH_FAIL,
134                           process_pkt(&testpkt, &testsock, pkt_len,
135                                                   MODE_SERVER, &testspkt, "UnitTest"));
136 }
137
138 TEST_F(packetProcessingTest, AuthenticatedPacketInvalid) {
139         // Activate authentication option
140         PrepareAuthenticationTest(50, 9, "123456789");
141         ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
142         
143         // Prepare the packet.
144         int pkt_len = LEN_PKT_NOMAC;
145
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]);
150
151         pkt_len += 4 + mac_len;
152
153         // Now, alter the MAC so it becomes invalid.
154         testpkt.exten[1] += 1;
155
156         EXPECT_EQ(SERVER_AUTH_FAIL,
157                           process_pkt(&testpkt, &testsock, pkt_len,
158                                                   MODE_SERVER, &testspkt, "UnitTest"));
159 }
160
161 TEST_F(packetProcessingTest, AuthenticatedPacketUnknownKey) {
162         // Activate authentication option
163         PrepareAuthenticationTest(30, 9, "123456789");
164         ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
165         
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;
169
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;
175
176         EXPECT_EQ(SERVER_AUTH_FAIL,
177                           process_pkt(&testpkt, &testsock, pkt_len,
178                                                   MODE_SERVER, &testspkt, "UnitTest"));
179 }
180
181 TEST_F(packetProcessingTest, ServerVersionTooOld) {
182         ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
183
184         testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
185                                                                                 NTP_OLDVERSION - 1,
186                                                                                 MODE_CLIENT);
187         ASSERT_LT(PKT_VERSION(testpkt.li_vn_mode), NTP_OLDVERSION);
188
189         int pkt_len = LEN_PKT_NOMAC;
190         
191         EXPECT_EQ(SERVER_UNUSEABLE,
192                           process_pkt(&testpkt, &testsock, pkt_len,
193                                                   MODE_SERVER, &testspkt, "UnitTest"));
194 }
195
196 TEST_F(packetProcessingTest, ServerVersionTooNew) {
197         ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
198
199         testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
200                                                                                 NTP_VERSION + 1,
201                                                                                 MODE_CLIENT);
202         ASSERT_GT(PKT_VERSION(testpkt.li_vn_mode), NTP_VERSION);
203
204         int pkt_len = LEN_PKT_NOMAC;
205
206         EXPECT_EQ(SERVER_UNUSEABLE,
207                           process_pkt(&testpkt, &testsock, pkt_len,
208                                                   MODE_SERVER, &testspkt, "UnitTest"));
209 }
210
211 TEST_F(packetProcessingTest, NonWantedMode) {
212         ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
213
214         testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
215                                                                                 NTP_VERSION,
216                                                                                 MODE_CLIENT);
217
218         // The packet has a mode of MODE_CLIENT, but process_pkt expects MODE_SERVER
219
220         EXPECT_EQ(SERVER_UNUSEABLE,
221                           process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
222                                                   MODE_SERVER, &testspkt, "UnitTest"));
223 }
224
225 /* Tests bug 1597 */
226 TEST_F(packetProcessingTest, KoDRate) {
227         ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
228
229         testpkt.stratum = STRATUM_PKT_UNSPEC;
230         memcpy(&testpkt.refid, "RATE", 4);
231
232         EXPECT_EQ(KOD_RATE,
233                           process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
234                                                   MODE_SERVER, &testspkt, "UnitTest"));
235 }
236
237 TEST_F(packetProcessingTest, KoDDeny) {
238         ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
239
240         testpkt.stratum = STRATUM_PKT_UNSPEC;
241         memcpy(&testpkt.refid, "DENY", 4);
242
243         EXPECT_EQ(KOD_DEMOBILIZE,
244                           process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
245                                                   MODE_SERVER, &testspkt, "UnitTest"));
246 }
247
248 TEST_F(packetProcessingTest, RejectUnsyncedServer) {
249         ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
250
251         testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOTINSYNC,
252                                                                                 NTP_VERSION,
253                                                                                 MODE_SERVER);
254
255         EXPECT_EQ(SERVER_UNUSEABLE,
256                           process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
257                                                   MODE_SERVER, &testspkt, "UnitTest"));
258 }
259
260 TEST_F(packetProcessingTest, RejectWrongResponseServerMode) {
261         ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
262
263         l_fp tmp;
264         tmp.l_ui = 1000UL;
265         tmp.l_uf = 0UL;
266         HTONL_FP(&tmp, &testpkt.org);
267
268         tmp.l_ui = 2000UL;
269         tmp.l_uf = 0UL;
270         HTONL_FP(&tmp, &testspkt.xmt);
271
272         EXPECT_EQ(PACKET_UNUSEABLE,
273                           process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
274                                                   MODE_SERVER, &testspkt, "UnitTest"));
275 }
276
277 TEST_F(packetProcessingTest, AcceptNoSentPacketBroadcastMode) {
278         ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
279
280         testpkt.li_vn_mode = PKT_LI_VN_MODE(LEAP_NOWARNING,
281                                             NTP_VERSION,
282                                             MODE_BROADCAST);
283
284         EXPECT_EQ(LEN_PKT_NOMAC,
285                   process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
286                               MODE_BROADCAST, NULL, "UnitTest"));
287 }
288
289 TEST_F(packetProcessingTest, CorrectUnauthenticatedPacket) {
290         ASSERT_FALSE(ENABLED_OPT(AUTHENTICATION));
291
292         EXPECT_EQ(LEN_PKT_NOMAC,
293                           process_pkt(&testpkt, &testsock, LEN_PKT_NOMAC,
294                                                   MODE_SERVER, &testspkt, "UnitTest"));
295 }
296
297 TEST_F(packetProcessingTest, CorrectAuthenticatedPacketMD5) {
298         PrepareAuthenticationTest(10, 15, "123456789abcdef");
299         ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
300
301         int pkt_len = LEN_PKT_NOMAC;
302
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]);
308
309         pkt_len += 4 + mac_len;
310
311         EXPECT_EQ(pkt_len,
312                           process_pkt(&testpkt, &testsock, pkt_len,
313                                                   MODE_SERVER, &testspkt, "UnitTest"));
314
315 }
316
317 TEST_F(packetProcessingTest, CorrectAuthenticatedPacketSHA1) {
318         PrepareAuthenticationTest(20, 15, "SHA1", "abcdefghijklmno");
319         ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION));
320
321         int pkt_len = LEN_PKT_NOMAC;
322
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]);
328
329         pkt_len += 4 + mac_len;
330
331         EXPECT_EQ(pkt_len,
332                           process_pkt(&testpkt, &testsock, pkt_len,
333                                                   MODE_SERVER, &testspkt, "UnitTest"));
334 }