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