1121572Sume/* $KAME: test-policy.c,v 1.16 2003/08/26 03:24:08 itojun Exp $ */ 262583Sitojun 355505Sshin/* 455505Sshin * Copyright (C) 1995, 1996, 1997, 1998, and 1999 WIDE Project. 555505Sshin * All rights reserved. 655505Sshin * 755505Sshin * Redistribution and use in source and binary forms, with or without 855505Sshin * modification, are permitted provided that the following conditions 955505Sshin * are met: 1055505Sshin * 1. Redistributions of source code must retain the above copyright 1155505Sshin * notice, this list of conditions and the following disclaimer. 1255505Sshin * 2. Redistributions in binary form must reproduce the above copyright 1355505Sshin * notice, this list of conditions and the following disclaimer in the 1455505Sshin * documentation and/or other materials provided with the distribution. 1555505Sshin * 3. Neither the name of the project nor the names of its contributors 1655505Sshin * may be used to endorse or promote products derived from this software 1755505Sshin * without specific prior written permission. 1855505Sshin * 1955505Sshin * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 2055505Sshin * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2155505Sshin * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2255505Sshin * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 2355505Sshin * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2455505Sshin * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2555505Sshin * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2655505Sshin * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 2755505Sshin * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 2855505Sshin * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 2955505Sshin * SUCH DAMAGE. 3055505Sshin */ 3155505Sshin 3284208Sdillon#include <sys/cdefs.h> 3384208Sdillon__FBSDID("$FreeBSD: releng/10.3/lib/libipsec/test-policy.c 248314 2013-03-15 09:19:19Z glebius $"); 3484208Sdillon 3555505Sshin#include <sys/types.h> 3655505Sshin#include <sys/param.h> 3755505Sshin#include <sys/socket.h> 3855505Sshin 3955505Sshin#include <netinet/in.h> 4057855Sshin#include <net/pfkeyv2.h> 41171135Sgnn#include <netipsec/key_debug.h> 42171135Sgnn#include <netipsec/ipsec.h> 4355505Sshin 4455505Sshin#include <stdio.h> 4555505Sshin#include <stdlib.h> 4655505Sshin#include <unistd.h> 4755505Sshin#include <string.h> 4862583Sitojun#include <errno.h> 4955505Sshin#include <err.h> 5055505Sshin 5178064Sume#include "libpfkey.h" 5278064Sume 5362583Sitojunstruct req_t { 5462583Sitojun int result; /* expected result; 0:ok 1:ng */ 5562583Sitojun char *str; 5662583Sitojun} reqs[] = { 5762583Sitojun{ 0, "out ipsec" }, 5862583Sitojun{ 1, "must_error" }, 5962583Sitojun{ 1, "in ipsec must_error" }, 6062583Sitojun{ 1, "out ipsec esp/must_error" }, 6162583Sitojun{ 1, "out discard" }, 6262583Sitojun{ 1, "out none" }, 6362583Sitojun{ 0, "in entrust" }, 6462583Sitojun{ 0, "out entrust" }, 6562583Sitojun{ 1, "out ipsec esp" }, 6662583Sitojun{ 0, "in ipsec ah/transport" }, 6762583Sitojun{ 1, "in ipsec ah/tunnel" }, 6862583Sitojun{ 0, "out ipsec ah/transport/" }, 6962583Sitojun{ 1, "out ipsec ah/tunnel/" }, 7062583Sitojun{ 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" }, 7162583Sitojun{ 0, "in ipsec esp/tunnel/::1-::2" }, 7262583Sitojun{ 1, "in ipsec esp/tunnel/10.0.0.1-::2" }, 7362583Sitojun{ 0, "in ipsec esp/tunnel/::1-::2/require" }, 7462583Sitojun{ 0, "out ipsec ah/transport//use" }, 7562583Sitojun{ 1, "out ipsec ah/transport esp/use" }, 7662583Sitojun{ 1, "in ipsec ah/transport esp/tunnel" }, 7762583Sitojun{ 0, "in ipsec ah/transport esp/tunnel/::1-::1" }, 78248314Sglebius{ 0, "in ipsec\n" 79248314Sglebius "ah / transport\n" 80248314Sglebius "esp / tunnel / ::1-::2" }, 81248314Sglebius{ 0, "out ipsec\n" 82248314Sglebius "ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require\n" 83248314Sglebius "ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require\n" 84248314Sglebius "ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require\n" }, 8562583Sitojun{ 0, "out ipsec esp/transport/fec0::10-fec0::11/use" }, 8655505Sshin}; 8755505Sshin 8892917Sobrienint test1(void); 8992917Sobrienint test1sub1(struct req_t *); 9092917Sobrienint test1sub2(char *, int); 9192917Sobrienint test2(void); 9292917Sobrienint test2sub(int); 9355505Sshin 9455505Sshinint 9555505Sshinmain(ac, av) 9655505Sshin int ac; 9755505Sshin char **av; 9855505Sshin{ 9962583Sitojun test1(); 10062583Sitojun test2(); 10162583Sitojun 10262583Sitojun exit(0); 10362583Sitojun} 10462583Sitojun 10562583Sitojunint 10662583Sitojuntest1() 10762583Sitojun{ 10855505Sshin int i; 10962583Sitojun int result; 11055505Sshin 11162583Sitojun printf("TEST1\n"); 11262583Sitojun for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) { 11362583Sitojun printf("#%d [%s]\n", i + 1, reqs[i].str); 11455505Sshin 11562583Sitojun result = test1sub1(&reqs[i]); 11662583Sitojun if (result == 0 && reqs[i].result == 1) { 117121572Sume warnx("ERROR: expecting failure."); 11862583Sitojun } else if (result == 1 && reqs[i].result == 0) { 119121572Sume warnx("ERROR: expecting success."); 12055505Sshin } 12162583Sitojun } 12255505Sshin 12362583Sitojun return 0; 12462583Sitojun} 12555505Sshin 12662583Sitojunint 12762583Sitojuntest1sub1(req) 12862583Sitojun struct req_t *req; 12962583Sitojun{ 13062583Sitojun char *buf; 13155505Sshin 13262583Sitojun buf = ipsec_set_policy(req->str, strlen(req->str)); 13362583Sitojun if (buf == NULL) { 13462583Sitojun printf("ipsec_set_policy: %s\n", ipsec_strerror()); 13562583Sitojun return 1; 13662583Sitojun } 13762583Sitojun 13862583Sitojun if (test1sub2(buf, PF_INET) != 0 13962583Sitojun || test1sub2(buf, PF_INET6) != 0) { 14055505Sshin free(buf); 14162583Sitojun return 1; 14255505Sshin } 14362583Sitojun#if 0 14462583Sitojun kdebug_sadb_x_policy((struct sadb_ext *)buf); 14562583Sitojun#endif 14655505Sshin 14762583Sitojun free(buf); 14855505Sshin return 0; 14955505Sshin} 15055505Sshin 15155505Sshinint 15262583Sitojuntest1sub2(policy, family) 15355505Sshin char *policy; 15455505Sshin int family; 15555505Sshin{ 15662583Sitojun int so; 15762583Sitojun int proto = 0, optname = 0; 15855505Sshin int len; 15955505Sshin char getbuf[1024]; 16055505Sshin 16155505Sshin switch (family) { 16255505Sshin case PF_INET: 16355505Sshin proto = IPPROTO_IP; 16455505Sshin optname = IP_IPSEC_POLICY; 16555505Sshin break; 16655505Sshin case PF_INET6: 16755505Sshin proto = IPPROTO_IPV6; 16855505Sshin optname = IPV6_IPSEC_POLICY; 16955505Sshin break; 17055505Sshin } 17155505Sshin 17255505Sshin if ((so = socket(family, SOCK_DGRAM, 0)) < 0) 17355505Sshin err(1, "socket"); 17455505Sshin 17555505Sshin len = ipsec_get_policylen(policy); 17662583Sitojun#if 0 17762583Sitojun printf("\tsetlen:%d\n", len); 17862583Sitojun#endif 17962583Sitojun 18055505Sshin if (setsockopt(so, proto, optname, policy, len) < 0) { 18162583Sitojun printf("fail to set sockopt; %s\n", strerror(errno)); 18262583Sitojun close(so); 18362583Sitojun return 1; 18455505Sshin } 18555505Sshin 18655505Sshin memset(getbuf, 0, sizeof(getbuf)); 18762583Sitojun memcpy(getbuf, policy, sizeof(struct sadb_x_policy)); 18855505Sshin if (getsockopt(so, proto, optname, getbuf, &len) < 0) { 18962583Sitojun printf("fail to get sockopt; %s\n", strerror(errno)); 19062583Sitojun close(so); 19162583Sitojun return 1; 19255505Sshin } 19355505Sshin 19455505Sshin { 19555505Sshin char *buf = NULL; 19655505Sshin 19762583Sitojun#if 0 19855505Sshin printf("\tgetlen:%d\n", len); 19962583Sitojun#endif 20055505Sshin 20155505Sshin if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) { 20255505Sshin printf("%s\n", ipsec_strerror()); 20362583Sitojun close(so); 20462583Sitojun return 1; 20555505Sshin } 20662583Sitojun#if 0 20762583Sitojun printf("\t[%s]\n", buf); 20862583Sitojun#endif 20962583Sitojun free(buf); 21055505Sshin } 21155505Sshin 21255505Sshin close (so); 21362583Sitojun return 0; 21462583Sitojun} 21555505Sshin 21662583Sitojunchar addr[] = { 21762583Sitojun 28, 28, 0, 0, 21862583Sitojun 0, 0, 0, 0, 21962583Sitojun 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 22062583Sitojun 0, 0, 0, 0, 22162583Sitojun}; 22262583Sitojun 22362583Sitojunint 22462583Sitojuntest2() 22562583Sitojun{ 22662583Sitojun int so; 22762583Sitojun char *pol1 = "out ipsec"; 22862583Sitojun char *pol2 = "out ipsec ah/transport//use"; 22962583Sitojun char *sp1, *sp2; 23062583Sitojun int splen1, splen2; 23162583Sitojun int spid; 23262583Sitojun struct sadb_msg *m; 23362583Sitojun 23462583Sitojun printf("TEST2\n"); 23562583Sitojun if (getuid() != 0) 236121572Sume errx(1, "root privilege required."); 23762583Sitojun 23862583Sitojun sp1 = ipsec_set_policy(pol1, strlen(pol1)); 23962583Sitojun splen1 = ipsec_get_policylen(sp1); 24062583Sitojun sp2 = ipsec_set_policy(pol2, strlen(pol2)); 24162583Sitojun splen2 = ipsec_get_policylen(sp2); 24262583Sitojun 24362583Sitojun if ((so = pfkey_open()) < 0) 244121572Sume errx(1, "ERROR: %s", ipsec_strerror()); 24562583Sitojun 24662583Sitojun printf("spdflush()\n"); 24762583Sitojun if (pfkey_send_spdflush(so) < 0) 248121572Sume errx(1, "ERROR: %s", ipsec_strerror()); 24962583Sitojun m = pfkey_recv(so); 25062583Sitojun free(m); 25178064Sume 25262583Sitojun printf("spdsetidx()\n"); 25362583Sitojun if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128, 25462583Sitojun (struct sockaddr *)addr, 128, 25562583Sitojun 255, sp1, splen1, 0) < 0) 256121572Sume errx(1, "ERROR: %s", ipsec_strerror()); 25762583Sitojun m = pfkey_recv(so); 25862583Sitojun free(m); 25962583Sitojun 26062583Sitojun printf("spdupdate()\n"); 26162583Sitojun if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128, 26262583Sitojun (struct sockaddr *)addr, 128, 26362583Sitojun 255, sp2, splen2, 0) < 0) 264121572Sume errx(1, "ERROR: %s", ipsec_strerror()); 26562583Sitojun m = pfkey_recv(so); 26662583Sitojun free(m); 26762583Sitojun 268121572Sume printf("sleep(4)\n"); 26978064Sume sleep(4); 27078064Sume 27162583Sitojun printf("spddelete()\n"); 27262583Sitojun if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128, 27362583Sitojun (struct sockaddr *)addr, 128, 27462583Sitojun 255, sp1, splen1, 0) < 0) 275121572Sume errx(1, "ERROR: %s", ipsec_strerror()); 27662583Sitojun m = pfkey_recv(so); 27762583Sitojun free(m); 27862583Sitojun 27962583Sitojun printf("spdadd()\n"); 28062583Sitojun if (pfkey_send_spdadd(so, (struct sockaddr *)addr, 128, 28162583Sitojun (struct sockaddr *)addr, 128, 28262583Sitojun 255, sp2, splen2, 0) < 0) 283121572Sume errx(1, "ERROR: %s", ipsec_strerror()); 28462583Sitojun spid = test2sub(so); 28562583Sitojun 28662583Sitojun printf("spdget(%u)\n", spid); 28762583Sitojun if (pfkey_send_spdget(so, spid) < 0) 288121572Sume errx(1, "ERROR: %s", ipsec_strerror()); 28962583Sitojun m = pfkey_recv(so); 29062583Sitojun free(m); 29162583Sitojun 292121572Sume printf("sleep(4)\n"); 29378064Sume sleep(4); 29478064Sume 29562583Sitojun printf("spddelete2()\n"); 29662583Sitojun if (pfkey_send_spddelete2(so, spid) < 0) 297121572Sume errx(1, "ERROR: %s", ipsec_strerror()); 29862583Sitojun m = pfkey_recv(so); 29962583Sitojun free(m); 30062583Sitojun 30178064Sume printf("spdadd() with lifetime's 10(s)\n"); 30278064Sume if (pfkey_send_spdadd2(so, (struct sockaddr *)addr, 128, 30378064Sume (struct sockaddr *)addr, 128, 30478064Sume 255, 0, 10, sp2, splen2, 0) < 0) 305121572Sume errx(1, "ERROR: %s", ipsec_strerror()); 30678064Sume spid = test2sub(so); 30778064Sume 30862583Sitojun /* expecting failure */ 30962583Sitojun printf("spdupdate()\n"); 31062583Sitojun if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128, 31162583Sitojun (struct sockaddr *)addr, 128, 31262583Sitojun 255, sp2, splen2, 0) == 0) { 313121572Sume warnx("ERROR: expecting failure."); 31462583Sitojun } 31562583Sitojun 31655505Sshin return 0; 31755505Sshin} 31855505Sshin 31962583Sitojunint 32062583Sitojuntest2sub(so) 32162583Sitojun int so; 32262583Sitojun{ 32362583Sitojun struct sadb_msg *msg; 32462583Sitojun caddr_t mhp[SADB_EXT_MAX + 1]; 32562583Sitojun 32662583Sitojun if ((msg = pfkey_recv(so)) == NULL) 327121572Sume errx(1, "ERROR: pfkey_recv failure."); 32862583Sitojun if (pfkey_align(msg, mhp) < 0) 329121572Sume errx(1, "ERROR: pfkey_align failure."); 33062583Sitojun 33162583Sitojun return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id; 33262583Sitojun} 33362583Sitojun 334