Initial import from FreeBSD RELENG_4:
[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 /*      $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