xref: /freebsd/lib/libipsec/test-policy.c (revision 19fae0f66023a97a9b464b3beeeabb2081f575b3)
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
97 main(ac, av)
98 	int ac;
99 	char **av;
100 {
101 	test1();
102 	test2();
103 
104 	exit(0);
105 }
106 
107 int
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
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
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
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
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