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