1 /* $FreeBSD$ */ 2 /* $KAME: test-policy.c,v 1.13 2000/05/07 05:25:03 itojun 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 struct req_t { 50 int result; /* expected result; 0:ok 1:ng */ 51 char *str; 52 } reqs[] = { 53 { 0, "out ipsec" }, 54 { 1, "must_error" }, 55 { 1, "in ipsec must_error" }, 56 { 1, "out ipsec esp/must_error" }, 57 { 1, "out discard" }, 58 { 1, "out none" }, 59 { 0, "in entrust" }, 60 { 0, "out entrust" }, 61 { 1, "out ipsec esp" }, 62 { 0, "in ipsec ah/transport" }, 63 { 1, "in ipsec ah/tunnel" }, 64 { 0, "out ipsec ah/transport/" }, 65 { 1, "out ipsec ah/tunnel/" }, 66 { 0, "in ipsec esp / transport / 10.0.0.1-10.0.0.2" }, 67 { 0, "in ipsec esp/tunnel/::1-::2" }, 68 { 1, "in ipsec esp/tunnel/10.0.0.1-::2" }, 69 { 0, "in ipsec esp/tunnel/::1-::2/require" }, 70 { 0, "out ipsec ah/transport//use" }, 71 { 1, "out ipsec ah/transport esp/use" }, 72 { 1, "in ipsec ah/transport esp/tunnel" }, 73 { 0, "in ipsec ah/transport esp/tunnel/::1-::1" }, 74 { 0, "in ipsec 75 ah / transport 76 esp / tunnel / ::1-::2" }, 77 { 0, "out ipsec 78 ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require 79 ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require 80 ah/transport/::1-::2 esp/tunnel/::3-::4/use ah/transport/::5-::6/require 81 " }, 82 { 0, "out ipsec esp/transport/fec0::10-fec0::11/use" }, 83 }; 84 85 int test1 __P((void)); 86 int test1sub1 __P((struct req_t *)); 87 int test1sub2 __P((char *, int)); 88 int test2 __P((void)); 89 int test2sub __P((int)); 90 91 int 92 main(ac, av) 93 int ac; 94 char **av; 95 { 96 test1(); 97 test2(); 98 99 exit(0); 100 } 101 102 int 103 test1() 104 { 105 int i; 106 int result; 107 108 printf("TEST1\n"); 109 for (i = 0; i < sizeof(reqs)/sizeof(reqs[0]); i++) { 110 printf("#%d [%s]\n", i + 1, reqs[i].str); 111 112 result = test1sub1(&reqs[i]); 113 if (result == 0 && reqs[i].result == 1) { 114 errx(1, "ERROR: expecting failure.\n"); 115 } else if (result == 1 && reqs[i].result == 0) { 116 errx(1, "ERROR: expecting success.\n"); 117 } 118 } 119 120 return 0; 121 } 122 123 int 124 test1sub1(req) 125 struct req_t *req; 126 { 127 char *buf; 128 129 buf = ipsec_set_policy(req->str, strlen(req->str)); 130 if (buf == NULL) { 131 printf("ipsec_set_policy: %s\n", ipsec_strerror()); 132 return 1; 133 } 134 135 if (test1sub2(buf, PF_INET) != 0 136 || test1sub2(buf, PF_INET6) != 0) { 137 free(buf); 138 return 1; 139 } 140 #if 0 141 kdebug_sadb_x_policy((struct sadb_ext *)buf); 142 #endif 143 144 free(buf); 145 return 0; 146 } 147 148 int 149 test1sub2(policy, family) 150 char *policy; 151 int family; 152 { 153 int so; 154 int proto = 0, optname = 0; 155 int len; 156 char getbuf[1024]; 157 158 switch (family) { 159 case PF_INET: 160 proto = IPPROTO_IP; 161 optname = IP_IPSEC_POLICY; 162 break; 163 case PF_INET6: 164 proto = IPPROTO_IPV6; 165 optname = IPV6_IPSEC_POLICY; 166 break; 167 } 168 169 if ((so = socket(family, SOCK_DGRAM, 0)) < 0) 170 err(1, "socket"); 171 172 len = ipsec_get_policylen(policy); 173 #if 0 174 printf("\tsetlen:%d\n", len); 175 #endif 176 177 if (setsockopt(so, proto, optname, policy, len) < 0) { 178 printf("fail to set sockopt; %s\n", strerror(errno)); 179 close(so); 180 return 1; 181 } 182 183 memset(getbuf, 0, sizeof(getbuf)); 184 memcpy(getbuf, policy, sizeof(struct sadb_x_policy)); 185 if (getsockopt(so, proto, optname, getbuf, &len) < 0) { 186 printf("fail to get sockopt; %s\n", strerror(errno)); 187 close(so); 188 return 1; 189 } 190 191 { 192 char *buf = NULL; 193 194 #if 0 195 printf("\tgetlen:%d\n", len); 196 #endif 197 198 if ((buf = ipsec_dump_policy(getbuf, NULL)) == NULL) { 199 printf("%s\n", ipsec_strerror()); 200 close(so); 201 return 1; 202 } 203 #if 0 204 printf("\t[%s]\n", buf); 205 #endif 206 free(buf); 207 } 208 209 close (so); 210 return 0; 211 } 212 213 char addr[] = { 214 28, 28, 0, 0, 215 0, 0, 0, 0, 216 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 217 0, 0, 0, 0, 218 }; 219 220 int 221 test2() 222 { 223 int so; 224 char *pol1 = "out ipsec"; 225 char *pol2 = "out ipsec ah/transport//use"; 226 char *sp1, *sp2; 227 int splen1, splen2; 228 int spid; 229 struct sadb_msg *m; 230 231 printf("TEST2\n"); 232 if (getuid() != 0) 233 errx(1, "root privilege required.\n"); 234 235 sp1 = ipsec_set_policy(pol1, strlen(pol1)); 236 splen1 = ipsec_get_policylen(sp1); 237 sp2 = ipsec_set_policy(pol2, strlen(pol2)); 238 splen2 = ipsec_get_policylen(sp2); 239 240 if ((so = pfkey_open()) < 0) 241 errx(1, "ERROR: %s\n", ipsec_strerror()); 242 243 printf("spdflush()\n"); 244 if (pfkey_send_spdflush(so) < 0) 245 errx(1, "ERROR: %s\n", ipsec_strerror()); 246 m = pfkey_recv(so); 247 free(m); 248 249 printf("spdsetidx()\n"); 250 if (pfkey_send_spdsetidx(so, (struct sockaddr *)addr, 128, 251 (struct sockaddr *)addr, 128, 252 255, sp1, splen1, 0) < 0) 253 errx(1, "ERROR: %s\n", ipsec_strerror()); 254 m = pfkey_recv(so); 255 free(m); 256 257 printf("spdupdate()\n"); 258 if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128, 259 (struct sockaddr *)addr, 128, 260 255, sp2, splen2, 0) < 0) 261 errx(1, "ERROR: %s\n", ipsec_strerror()); 262 m = pfkey_recv(so); 263 free(m); 264 265 printf("spddelete()\n"); 266 if (pfkey_send_spddelete(so, (struct sockaddr *)addr, 128, 267 (struct sockaddr *)addr, 128, 268 255, sp1, splen1, 0) < 0) 269 errx(1, "ERROR: %s\n", ipsec_strerror()); 270 m = pfkey_recv(so); 271 free(m); 272 273 printf("spdadd()\n"); 274 if (pfkey_send_spdadd(so, (struct sockaddr *)addr, 128, 275 (struct sockaddr *)addr, 128, 276 255, sp2, splen2, 0) < 0) 277 errx(1, "ERROR: %s\n", ipsec_strerror()); 278 spid = test2sub(so); 279 280 printf("spdget(%u)\n", spid); 281 if (pfkey_send_spdget(so, spid) < 0) 282 errx(1, "ERROR: %s\n", ipsec_strerror()); 283 m = pfkey_recv(so); 284 free(m); 285 286 printf("spddelete2()\n"); 287 if (pfkey_send_spddelete2(so, spid) < 0) 288 errx(1, "ERROR: %s\n", ipsec_strerror()); 289 m = pfkey_recv(so); 290 free(m); 291 292 /* expecting failure */ 293 printf("spdupdate()\n"); 294 if (pfkey_send_spdupdate(so, (struct sockaddr *)addr, 128, 295 (struct sockaddr *)addr, 128, 296 255, sp2, splen2, 0) == 0) { 297 errx(1, "ERROR: expecting failure.\n"); 298 } 299 300 return 0; 301 } 302 303 int 304 test2sub(so) 305 int so; 306 { 307 struct sadb_msg *msg; 308 caddr_t mhp[SADB_EXT_MAX + 1]; 309 310 if ((msg = pfkey_recv(so)) == NULL) 311 errx(1, "ERROR: pfkey_recv failure.\n"); 312 if (pfkey_align(msg, mhp) < 0) 313 errx(1, "ERROR: pfkey_align failure.\n"); 314 315 return ((struct sadb_x_policy *)mhp[SADB_X_EXT_POLICY])->sadb_x_policy_id; 316 } 317 318