Merge branch 'vendor/FILE'
[dragonfly.git] / lib / libipsec / test-policy.c
1 /*      $FreeBSD: src/lib/libipsec/test-policy.c,v 1.2.2.2 2001/07/03 11:01:15 ume Exp $        */
2 /*      $DragonFly: src/lib/libipsec/test-policy.c,v 1.3 2003/11/12 20:21:30 eirikn Exp $       */
3 /*      $KAME: test-policy.c,v 1.14 2000/12/27 11:38:11 sakane Exp $    */
4
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/types.h>
35 #include <sys/param.h>
36 #include <sys/socket.h>
37
38 #include <netinet/in.h>
39 #include <net/pfkeyv2.h>
40 #include <netkey/key_debug.h>
41 #include <netinet6/ipsec.h>
42
43 #include <stdio.h>
44 #include <stdlib.h>
45 #include <unistd.h>
46 #include <string.h>
47 #include <errno.h>
48 #include <err.h>
49
50 #include "libpfkey.h"
51
52 struct req_t {
53         int result;     /* expected result; 0:ok 1:ng */
54         char *str;
55 } reqs[] = {
56 { 0, "out ipsec" },
57 { 1, "must_error" },
58 { 1, "in ipsec must_error" },
59 { 1, "out ipsec esp/must_error" },
60 { 1, "out discard" },
61 { 1, "out none" },
62 { 0, "in entrust" },
63 { 0, "out entrust" },
64 { 1, "out ipsec esp" },
65 { 0, "in ipsec ah/transport" },
66 { 1, "in ipsec ah/tunnel" },
67 { 0, "out ipsec ah/transport/" },
68 { 1, "out ipsec ah/tunnel/" },
69 { 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" },
70 { 0, "in ipsec esp/tunnel/::1-::2" },
71 { 1, "in ipsec esp/tunnel/10.0.0.1-::2" },
72 { 0, "in ipsec esp/tunnel/::1-::2/require" },
73 { 0, "out ipsec ah/transport//use" },
74 { 1, "out ipsec ah/transport esp/use" },
75 { 1, "in ipsec ah/transport esp/tunnel" },
76 { 0, "in ipsec ah/transport esp/tunnel/::1-::1" },
77 { 0, "in ipsec
78         ah / transport
79         esp / tunnel / ::1-::2" },
80 { 0, "out ipsec
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         ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require
84         " },
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.\n");
118                 } else if (result == 1 && reqs[i].result == 0) {
119                         warnx("ERROR: expecting success.\n");
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.\n");
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\n", ipsec_strerror());
245
246         printf("spdflush()\n");
247         if (pfkey_send_spdflush(so) < 0)
248                 errx(1, "ERROR: %s\n", ipsec_strerror());
249         m = pfkey_recv(so);
250         free(m);
251
252 #if 0
253         printf("spdsetidx()\n");
254         if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128,
255                                 (struct sockaddr *)addr, 128,
256                                 255, sp1, splen1, 0) < 0)
257                 errx(1, "ERROR: %s\n", ipsec_strerror());
258         m = pfkey_recv(so);
259         free(m);
260         
261         printf("spdupdate()\n");
262         if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
263                                 (struct sockaddr *)addr, 128,
264                                 255, sp2, splen2, 0) < 0)
265                 errx(1, "ERROR: %s\n", ipsec_strerror());
266         m = pfkey_recv(so);
267         free(m);
268
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\n", 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\n", 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\n", ipsec_strerror());
289         m = pfkey_recv(so);
290         free(m);
291
292         sleep(4);
293
294         printf("spddelete2()\n");
295         if (pfkey_send_spddelete2(so, spid) < 0)
296                 errx(1, "ERROR: %s\n", ipsec_strerror());
297         m = pfkey_recv(so);
298         free(m);
299 #endif
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\n", ipsec_strerror());
306         spid = test2sub(so);
307
308 #if 0
309         /* expecting failure */
310         printf("spdupdate()\n");
311         if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
312                                 (struct sockaddr *)addr, 128,
313                                 255, sp2, splen2, 0) == 0) {
314                 warnx("ERROR: expecting failure.\n");
315         }
316 #endif
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.\n");
330         if (pfkey_align(msg, mhp) < 0)
331                 errx(1, "ERROR: pfkey_align failure.\n");
332
333         return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id;
334 }
335