Home | History | Annotate | Download | only in libipsec
      1 /*	$NetBSD: test-policy.c,v 1.4 2006/09/09 16:22:09 manu Exp $	*/
      2 
      3 /*	$KAME: test-policy.c,v 1.16 2003/08/26 03:24:08 itojun 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 <netinet/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.");
    117 		} else if (result == 1 && reqs[i].result == 0) {
    118 			warnx("ERROR: expecting success.");
    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.");
    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", ipsec_strerror());
    244 
    245 	printf("spdflush()\n");
    246 	if (pfkey_send_spdflush(so) < 0)
    247 		errx(1, "ERROR: %s", ipsec_strerror());
    248 	m = pfkey_recv(so);
    249 	free(m);
    250 
    251 	printf("spdsetidx()\n");
    252 	if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128,
    253 				(struct sockaddr *)addr, 128,
    254 				255, sp1, splen1, 0) < 0)
    255 		errx(1, "ERROR: %s", ipsec_strerror());
    256 	m = pfkey_recv(so);
    257 	free(m);
    258 
    259 	printf("spdupdate()\n");
    260 	if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
    261 				(struct sockaddr *)addr, 128,
    262 				255, sp2, splen2, 0) < 0)
    263 		errx(1, "ERROR: %s", ipsec_strerror());
    264 	m = pfkey_recv(so);
    265 	free(m);
    266 
    267 	printf("sleep(4)\n");
    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", 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", 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", ipsec_strerror());
    288 	m = pfkey_recv(so);
    289 	free(m);
    290 
    291 	printf("sleep(4)\n");
    292 	sleep(4);
    293 
    294 	printf("spddelete2()\n");
    295 	if (pfkey_send_spddelete2(so, spid) < 0)
    296 		errx(1, "ERROR: %s", ipsec_strerror());
    297 	m = pfkey_recv(so);
    298 	free(m);
    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", ipsec_strerror());
    305 	spid = test2sub(so);
    306 
    307 	/* expecting failure */
    308 	printf("spdupdate()\n");
    309 	if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128,
    310 				(struct sockaddr *)addr, 128,
    311 				255, sp2, splen2, 0) == 0) {
    312 		warnx("ERROR: expecting failure.");
    313 	}
    314 
    315 	return 0;
    316 }
    317 
    318 int
    319 test2sub(so)
    320 	int so;
    321 {
    322 	struct sadb_msg *msg;
    323 	caddr_t mhp[SADB_EXT_MAX + 1];
    324 
    325 	if ((msg = pfkey_recv(so)) == NULL)
    326 		errx(1, "ERROR: pfkey_recv failure.");
    327 	if (pfkey_align(msg, mhp) < 0)
    328 		errx(1, "ERROR: pfkey_align failure.");
    329 
    330 	return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id;
    331 }
    332 
    333