1 /* $KAME: test-policy.c,v 1.16 2003/08/26 03:24:08 itojun Exp $ */
2
3 /*-
4 * SPDX-License-Identifier: BSD-3-Clause
5 *
6 * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions
11 * are met:
12 * 1. Redistributions of source code must retain the above copyright
13 * notice, this list of conditions and the following disclaimer.
14 * 2. Redistributions in binary form must reproduce the above copyright
15 * notice, this list of conditions and the following disclaimer in the
16 * documentation and/or other materials provided with the distribution.
17 * 3. Neither the name of the project nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34 #include <sys/cdefs.h>
35 __FBSDID("$FreeBSD$");
36
37 #include <sys/types.h>
38 #include <sys/param.h>
39 #include <sys/socket.h>
40
41 #include <netinet/in.h>
42 #include <net/pfkeyv2.h>
43 #include <netipsec/key_debug.h>
44 #include <netipsec/ipsec.h>
45
46 #include <stdio.h>
47 #include <stdlib.h>
48 #include <unistd.h>
49 #include <string.h>
50 #include <errno.h>
51 #include <err.h>
52
53 #include "libpfkey.h"
54
55 struct req_t {
56 int result; /* expected result; 0:ok 1:ng */
57 char *str;
58 } reqs[] = {
59 { 0, "out ipsec" },
60 { 1, "must_error" },
61 { 1, "in ipsec must_error" },
62 { 1, "out ipsec esp/must_error" },
63 { 1, "out discard" },
64 { 1, "out none" },
65 { 0, "in entrust" },
66 { 0, "out entrust" },
67 { 1, "out ipsec esp" },
68 { 0, "in ipsec ah/transport" },
69 { 1, "in ipsec ah/tunnel" },
70 { 0, "out ipsec ah/transport/" },
71 { 1, "out ipsec ah/tunnel/" },
72 { 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" },
73 { 0, "in ipsec esp/tunnel/::1-::2" },
74 { 1, "in ipsec esp/tunnel/10.0.0.1-::2" },
75 { 0, "in ipsec esp/tunnel/::1-::2/require" },
76 { 0, "out ipsec ah/transport//use" },
77 { 1, "out ipsec ah/transport esp/use" },
78 { 1, "in ipsec ah/transport esp/tunnel" },
79 { 0, "in ipsec ah/transport esp/tunnel/::1-::1" },
80 { 0, "in ipsec\n"
81 "ah / transport\n"
82 "esp / tunnel / ::1-::2" },
83 { 0, "out ipsec\n"
84 "ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require\n"
85 "ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require\n"
86 "ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require\n" },
87 { 0, "out ipsec esp/transport/fec0::10-fec0::11/use" },
88 };
89
90 int test1(void);
91 int test1sub1(struct req_t *);
92 int test1sub2(char *, int);
93 int test2(void);
94 int test2sub(int);
95
96 int
main(ac,av)97 main(ac, av)
98 int ac;
99 char **av;
100 {
101 test1();
102 test2();
103
104 exit(0);
105 }
106
107 int
test1()108 test1()
109 {
110 int i;
111 int result;
112
113 printf("TEST1\n");
114 for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) {
115 printf("#%d [%s]\n", i + 1, reqs[i].str);
116
117 result = test1sub1(&reqs[i]);
118 if (result == 0 && reqs[i].result == 1) {
119 warnx("ERROR: expecting failure.");
120 } else if (result == 1 && reqs[i].result == 0) {
121 warnx("ERROR: expecting success.");
122 }
123 }
124
125 return 0;
126 }
127
128 int
test1sub1(req)129 test1sub1(req)
130 struct req_t *req;
131 {
132 char *buf;
133
134 buf = ipsec_set_policy(req->str, strlen(req->str));
135 if (buf == NULL) {
136 printf("ipsec_set_policy: %s\n", ipsec_strerror());
137 return 1;
138 }
139
140 if (test1sub2(buf, PF_INET) != 0
141 || test1sub2(buf, PF_INET6) != 0) {
142 free(buf);
143 return 1;
144 }
145 #if 0
146 kdebug_sadb_x_policy((struct sadb_ext *)buf);
147 #endif
148
149 free(buf);
150 return 0;
151 }
152
153 int
test1sub2(policy,family)154 test1sub2(policy, family)
155 char *policy;
156 int family;
157 {
158 int so;
159 int proto = 0, optname = 0;
160 int len;
161 char getbuf[1024];
162
163 switch (family) {
164 case PF_INET:
165 proto = IPPROTO_IP;
166 optname = IP_IPSEC_POLICY;
167 break;
168 case PF_INET6:
169 proto = IPPROTO_IPV6;
170 optname = IPV6_IPSEC_POLICY;
171 break;
172 }
173
174 if ((so = socket(family, SOCK_DGRAM, 0)) < 0)
175 err(1, "socket");
176
177 len = ipsec_get_policylen(policy);
178 #if 0
179 printf("\tsetlen:%d\n", len);
180 #endif
181
182 if (setsockopt(so, proto, optname, policy, len) < 0) {
183 printf("fail to set sockopt; %s\n", strerror(errno));
184 close(so);
185 return 1;
186 }
187
188 memset(getbuf, 0, sizeof(getbuf));
189 memcpy(getbuf, policy, sizeof(struct sadb_x_policy));
190 if (getsockopt(so, proto, optname, getbuf, &len) < 0) {
191 printf("fail to get sockopt; %s\n", strerror(errno));
192 close(so);
193 return 1;
194 }
195
196 {
197 char *buf = NULL;
198
199 #if 0
200 printf("\tgetlen:%d\n", len);
201 #endif
202
203 if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) {
204 printf("%s\n", ipsec_strerror());
205 close(so);
206 return 1;
207 }
208 #if 0
209 printf("\t[%s]\n", buf);
210 #endif
211 free(buf);
212 }
213
214 close (so);
215 return 0;
216 }
217
218 char addr[] = {
219 28, 28, 0, 0,
220 0, 0, 0, 0,
221 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
222 0, 0, 0, 0,
223 };
224
225 int
test2()226 test2()
227 {
228 int so;
229 char *pol1 = "out ipsec";
230 char *pol2 = "out ipsec ah/transport//use";
231 char *sp1, *sp2;
232 int splen1, splen2;
233 int spid;
234 struct sadb_msg *m;
235
236 printf("TEST2\n");
237 if (getuid() != 0)
238 errx(1, "root privilege required.");
239
240 sp1 = ipsec_set_policy(pol1, strlen(pol1));
241 splen1 = ipsec_get_policylen(sp1);
242 sp2 = ipsec_set_policy(pol2, strlen(pol2));
243 splen2 = ipsec_get_policylen(sp2);
244
245 if ((so = pfkey_open()) < 0)
246 errx(1, "ERROR: %s", ipsec_strerror());
247
248 printf("spdflush()\n");
249 if (pfkey_send_spdflush(so) < 0)
250 errx(1, "ERROR: %s", ipsec_strerror());
251 m = pfkey_recv(so);
252 free(m);
253
254 printf("spdsetidx()\n");
255 if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128,
256 (struct sockaddr *)addr, 128,
257 255, sp1, splen1, 0) < 0)
258 errx(1, "ERROR: %s", ipsec_strerror());
259 m = pfkey_recv(so);
260 free(m);
261
262 printf("spdupdate()\n");
263 if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
264 (struct sockaddr *)addr, 128,
265 255, sp2, splen2, 0) < 0)
266 errx(1, "ERROR: %s", ipsec_strerror());
267 m = pfkey_recv(so);
268 free(m);
269
270 printf("sleep(4)\n");
271 sleep(4);
272
273 printf("spddelete()\n");
274 if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128,
275 (struct sockaddr *)addr, 128,
276 255, sp1, splen1, 0) < 0)
277 errx(1, "ERROR: %s", ipsec_strerror());
278 m = pfkey_recv(so);
279 free(m);
280
281 printf("spdadd()\n");
282 if (pfkey_send_spdadd(so, (struct sockaddr *)addr, 128,
283 (struct sockaddr *)addr, 128,
284 255, sp2, splen2, 0) < 0)
285 errx(1, "ERROR: %s", ipsec_strerror());
286 spid = test2sub(so);
287
288 printf("spdget(%u)\n", spid);
289 if (pfkey_send_spdget(so, spid) < 0)
290 errx(1, "ERROR: %s", ipsec_strerror());
291 m = pfkey_recv(so);
292 free(m);
293
294 printf("sleep(4)\n");
295 sleep(4);
296
297 printf("spddelete2()\n");
298 if (pfkey_send_spddelete2(so, spid) < 0)
299 errx(1, "ERROR: %s", ipsec_strerror());
300 m = pfkey_recv(so);
301 free(m);
302
303 printf("spdadd() with lifetime's 10(s)\n");
304 if (pfkey_send_spdadd2(so, (struct sockaddr *)addr, 128,
305 (struct sockaddr *)addr, 128,
306 255, 0, 10, sp2, splen2, 0) < 0)
307 errx(1, "ERROR: %s", ipsec_strerror());
308 spid = test2sub(so);
309
310 /* expecting failure */
311 printf("spdupdate()\n");
312 if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
313 (struct sockaddr *)addr, 128,
314 255, sp2, splen2, 0) == 0) {
315 warnx("ERROR: expecting failure.");
316 }
317
318 return 0;
319 }
320
321 int
test2sub(so)322 test2sub(so)
323 int so;
324 {
325 struct sadb_msg *msg;
326 caddr_t mhp[SADB_EXT_MAX + 1];
327
328 if ((msg = pfkey_recv(so)) == NULL)
329 errx(1, "ERROR: pfkey_recv failure.");
330 if (pfkey_align(msg, mhp) < 0)
331 errx(1, "ERROR: pfkey_align failure.");
332
333 return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id;
334 }
335
336