xref: /freebsd/lib/libipsec/test-policy.c (revision 817420dc8eac7df799c78f5309b75092b7f7cd40)
1 /*	$FreeBSD$	*/
2 /*	$KAME: test-policy.c,v 1.13 2000/05/07 05:25:03 itojun 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 struct req_t {
50 	int result;	/* expected result; 0:ok 1:ng */
51 	char *str;
52 } reqs[] = {
53 { 0, "out ipsec" },
54 { 1, "must_error" },
55 { 1, "in ipsec must_error" },
56 { 1, "out ipsec esp/must_error" },
57 { 1, "out discard" },
58 { 1, "out none" },
59 { 0, "in entrust" },
60 { 0, "out entrust" },
61 { 1, "out ipsec esp" },
62 { 0, "in ipsec ah/transport" },
63 { 1, "in ipsec ah/tunnel" },
64 { 0, "out ipsec ah/transport/" },
65 { 1, "out ipsec ah/tunnel/" },
66 { 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" },
67 { 0, "in ipsec esp/tunnel/::1-::2" },
68 { 1, "in ipsec esp/tunnel/10.0.0.1-::2" },
69 { 0, "in ipsec esp/tunnel/::1-::2/require" },
70 { 0, "out ipsec ah/transport//use" },
71 { 1, "out ipsec ah/transport esp/use" },
72 { 1, "in ipsec ah/transport esp/tunnel" },
73 { 0, "in ipsec ah/transport esp/tunnel/::1-::1" },
74 { 0, "in ipsec
75 	ah / transport
76 	esp / tunnel / ::1-::2" },
77 { 0, "out ipsec
78 	ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
79 	ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
80 	ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
81 	" },
82 { 0, "out ipsec esp/transport/fec0::10-fec0::11/use" },
83 };
84 
85 int test1 __P((void));
86 int test1sub1 __P((struct req_t *));
87 int test1sub2 __P((char *, int));
88 int test2 __P((void));
89 int test2sub __P((int));
90 
91 int
92 main(ac, av)
93 	int ac;
94 	char **av;
95 {
96 	test1();
97 	test2();
98 
99 	exit(0);
100 }
101 
102 int
103 test1()
104 {
105 	int i;
106 	int result;
107 
108 	printf("TEST1\n");
109 	for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) {
110 		printf("#%d [%s]\n", i + 1, reqs[i].str);
111 
112 		result = test1sub1(&reqs[i]);
113 		if (result == 0 && reqs[i].result == 1) {
114 			errx(1, "ERROR: expecting failure.\n");
115 		} else if (result == 1 && reqs[i].result == 0) {
116 			errx(1, "ERROR: expecting success.\n");
117 		}
118 	}
119 
120 	return 0;
121 }
122 
123 int
124 test1sub1(req)
125 	struct req_t *req;
126 {
127 	char *buf;
128 
129 	buf = ipsec_set_policy(req->str, strlen(req->str));
130 	if (buf == NULL) {
131 		printf("ipsec_set_policy: %s\n", ipsec_strerror());
132 		return 1;
133 	}
134 
135 	if (test1sub2(buf, PF_INET) != 0
136 	 || test1sub2(buf, PF_INET6) != 0) {
137 		free(buf);
138 		return 1;
139 	}
140 #if 0
141 	kdebug_sadb_x_policy((struct sadb_ext *)buf);
142 #endif
143 
144 	free(buf);
145 	return 0;
146 }
147 
148 int
149 test1sub2(policy, family)
150 	char *policy;
151 	int family;
152 {
153 	int so;
154 	int proto = 0, optname = 0;
155 	int len;
156 	char getbuf[1024];
157 
158 	switch (family) {
159 	case PF_INET:
160 		proto = IPPROTO_IP;
161 		optname = IP_IPSEC_POLICY;
162 		break;
163 	case PF_INET6:
164 		proto = IPPROTO_IPV6;
165 		optname = IPV6_IPSEC_POLICY;
166 		break;
167 	}
168 
169 	if ((so = socket(family, SOCK_DGRAM, 0)) < 0)
170 		err(1, "socket");
171 
172 	len = ipsec_get_policylen(policy);
173 #if 0
174 	printf("\tsetlen:%d\n", len);
175 #endif
176 
177 	if (setsockopt(so, proto, optname, policy, len) < 0) {
178 		printf("fail to set sockopt; %s\n", strerror(errno));
179 		close(so);
180 		return 1;
181 	}
182 
183 	memset(getbuf, 0, sizeof(getbuf));
184 	memcpy(getbuf, policy, sizeof(struct sadb_x_policy));
185 	if (getsockopt(so, proto, optname, getbuf, &len) < 0) {
186 		printf("fail to get sockopt; %s\n", strerror(errno));
187 		close(so);
188 		return 1;
189 	}
190 
191     {
192 	char *buf = NULL;
193 
194 #if 0
195 	printf("\tgetlen:%d\n", len);
196 #endif
197 
198 	if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) {
199 		printf("%s\n", ipsec_strerror());
200 		close(so);
201 		return 1;
202 	}
203 #if 0
204 	printf("\t[%s]\n", buf);
205 #endif
206 	free(buf);
207     }
208 
209 	close (so);
210 	return 0;
211 }
212 
213 char addr[] = {
214 	28, 28, 0, 0,
215 	0, 0, 0, 0,
216 	0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1,
217 	0, 0, 0, 0,
218 };
219 
220 int
221 test2()
222 {
223 	int so;
224 	char *pol1 = "out ipsec";
225 	char *pol2 = "out ipsec ah/transport//use";
226 	char *sp1, *sp2;
227 	int splen1, splen2;
228 	int spid;
229 	struct sadb_msg *m;
230 
231 	printf("TEST2\n");
232 	if (getuid() != 0)
233 		errx(1, "root privilege required.\n");
234 
235 	sp1 = ipsec_set_policy(pol1, strlen(pol1));
236 	splen1 = ipsec_get_policylen(sp1);
237 	sp2 = ipsec_set_policy(pol2, strlen(pol2));
238 	splen2 = ipsec_get_policylen(sp2);
239 
240 	if ((so = pfkey_open()) < 0)
241 		errx(1, "ERROR: %s\n", ipsec_strerror());
242 
243 	printf("spdflush()\n");
244 	if (pfkey_send_spdflush(so) < 0)
245 		errx(1, "ERROR: %s\n", ipsec_strerror());
246 	m = pfkey_recv(so);
247 	free(m);
248 
249 	printf("spdsetidx()\n");
250 	if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128,
251 				(struct sockaddr *)addr, 128,
252 				255, sp1, splen1, 0) < 0)
253 		errx(1, "ERROR: %s\n", ipsec_strerror());
254 	m = pfkey_recv(so);
255 	free(m);
256 
257 	printf("spdupdate()\n");
258 	if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
259 				(struct sockaddr *)addr, 128,
260 				255, sp2, splen2, 0) < 0)
261 		errx(1, "ERROR: %s\n", ipsec_strerror());
262 	m = pfkey_recv(so);
263 	free(m);
264 
265 	printf("spddelete()\n");
266 	if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128,
267 				(struct sockaddr *)addr, 128,
268 				255, sp1, splen1, 0) < 0)
269 		errx(1, "ERROR: %s\n", ipsec_strerror());
270 	m = pfkey_recv(so);
271 	free(m);
272 
273 	printf("spdadd()\n");
274 	if (pfkey_send_spdadd(so, (struct sockaddr *)addr, 128,
275 				(struct sockaddr *)addr, 128,
276 				255, sp2, splen2, 0) < 0)
277 		errx(1, "ERROR: %s\n", ipsec_strerror());
278 	spid = test2sub(so);
279 
280 	printf("spdget(%u)\n", spid);
281 	if (pfkey_send_spdget(so, spid) < 0)
282 		errx(1, "ERROR: %s\n", ipsec_strerror());
283 	m = pfkey_recv(so);
284 	free(m);
285 
286 	printf("spddelete2()\n");
287 	if (pfkey_send_spddelete2(so, spid) < 0)
288 		errx(1, "ERROR: %s\n", ipsec_strerror());
289 	m = pfkey_recv(so);
290 	free(m);
291 
292 	/* expecting failure */
293 	printf("spdupdate()\n");
294 	if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
295 				(struct sockaddr *)addr, 128,
296 				255, sp2, splen2, 0) == 0) {
297 		errx(1, "ERROR: expecting failure.\n");
298 	}
299 
300 	return 0;
301 }
302 
303 int
304 test2sub(so)
305 	int so;
306 {
307 	struct sadb_msg *msg;
308 	caddr_t mhp[SADB_EXT_MAX + 1];
309 
310 	if ((msg = pfkey_recv(so)) == NULL)
311 		errx(1, "ERROR: pfkey_recv failure.\n");
312 	if (pfkey_align(msg, mhp) < 0)
313 		errx(1, "ERROR: pfkey_align failure.\n");
314 
315 	return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id;
316 }
317 
318