]> CyberLeo.Net >> Repos - FreeBSD/releng/10.2.git/blob - lib/libipsec/test-policy.c
- Copy stable/10@285827 to releng/10.2 in preparation for 10.2-RC1
[FreeBSD/releng/10.2.git] / lib / libipsec / test-policy.c
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