1 /*- 2 * Copyright (c) 2016 Andrey V. Elsukov <ae@FreeBSD.org> 3 * All rights reserved. 4 * 5 * Redistribution and use in source and binary forms, with or without 6 * modification, are permitted provided that the following conditions 7 * are met: 8 * 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 25 */ 26 27 #include <sys/cdefs.h> 28 __FBSDID("$FreeBSD$"); 29 30 #include "opt_inet.h" 31 #include "opt_inet6.h" 32 #include "opt_ipsec.h" 33 34 #include <sys/param.h> 35 #include <sys/systm.h> 36 #include <sys/kernel.h> 37 #include <sys/lock.h> 38 #include <sys/malloc.h> 39 #include <sys/mbuf.h> 40 #include <sys/priv.h> 41 #include <sys/socket.h> 42 #include <sys/sockopt.h> 43 #include <sys/syslog.h> 44 #include <sys/proc.h> 45 46 #include <netinet/in.h> 47 #include <netinet/in_pcb.h> 48 49 #include <netipsec/ipsec.h> 50 #include <netipsec/ipsec6.h> 51 #include <netipsec/ipsec_support.h> 52 #include <netipsec/key.h> 53 #include <netipsec/key_debug.h> 54 55 MALLOC_DEFINE(M_IPSEC_INPCB, "inpcbpolicy", "inpcb-resident ipsec policy"); 56 57 static void 58 ipsec_setsockaddrs_inpcb(struct inpcb *inp, union sockaddr_union *src, 59 union sockaddr_union *dst, u_int dir) 60 { 61 62 #ifdef INET6 63 if (inp->inp_vflag & INP_IPV6) { 64 struct sockaddr_in6 *sin6; 65 66 bzero(&src->sin6, sizeof(src->sin6)); 67 bzero(&dst->sin6, sizeof(dst->sin6)); 68 src->sin6.sin6_family = AF_INET6; 69 src->sin6.sin6_len = sizeof(struct sockaddr_in6); 70 dst->sin6.sin6_family = AF_INET6; 71 dst->sin6.sin6_len = sizeof(struct sockaddr_in6); 72 73 if (dir == IPSEC_DIR_OUTBOUND) 74 sin6 = &src->sin6; 75 else 76 sin6 = &dst->sin6; 77 sin6->sin6_addr = inp->in6p_laddr; 78 sin6->sin6_port = inp->inp_lport; 79 if (IN6_IS_SCOPE_LINKLOCAL(&inp->in6p_laddr)) { 80 /* XXXAE: use in6p_zoneid */ 81 sin6->sin6_addr.s6_addr16[1] = 0; 82 sin6->sin6_scope_id = ntohs( 83 inp->in6p_laddr.s6_addr16[1]); 84 } 85 86 if (dir == IPSEC_DIR_OUTBOUND) 87 sin6 = &dst->sin6; 88 else 89 sin6 = &src->sin6; 90 sin6->sin6_addr = inp->in6p_faddr; 91 sin6->sin6_port = inp->inp_fport; 92 if (IN6_IS_SCOPE_LINKLOCAL(&inp->in6p_faddr)) { 93 /* XXXAE: use in6p_zoneid */ 94 sin6->sin6_addr.s6_addr16[1] = 0; 95 sin6->sin6_scope_id = ntohs( 96 inp->in6p_faddr.s6_addr16[1]); 97 } 98 } 99 #endif 100 #ifdef INET 101 if (inp->inp_vflag & INP_IPV4) { 102 struct sockaddr_in *sin; 103 104 bzero(&src->sin, sizeof(src->sin)); 105 bzero(&dst->sin, sizeof(dst->sin)); 106 src->sin.sin_family = AF_INET; 107 src->sin.sin_len = sizeof(struct sockaddr_in); 108 dst->sin.sin_family = AF_INET; 109 dst->sin.sin_len = sizeof(struct sockaddr_in); 110 111 if (dir == IPSEC_DIR_OUTBOUND) 112 sin = &src->sin; 113 else 114 sin = &dst->sin; 115 sin->sin_addr = inp->inp_laddr; 116 sin->sin_port = inp->inp_lport; 117 118 if (dir == IPSEC_DIR_OUTBOUND) 119 sin = &dst->sin; 120 else 121 sin = &src->sin; 122 sin->sin_addr = inp->inp_faddr; 123 sin->sin_port = inp->inp_fport; 124 } 125 #endif 126 } 127 128 void 129 ipsec_setspidx_inpcb(struct inpcb *inp, struct secpolicyindex *spidx, 130 u_int dir) 131 { 132 133 ipsec_setsockaddrs_inpcb(inp, &spidx->src, &spidx->dst, dir); 134 #ifdef INET6 135 if (inp->inp_vflag & INP_IPV6) { 136 spidx->prefs = sizeof(struct in6_addr) << 3; 137 spidx->prefd = sizeof(struct in6_addr) << 3; 138 } 139 #endif 140 #ifdef INET 141 if (inp->inp_vflag & INP_IPV4) { 142 spidx->prefs = sizeof(struct in_addr) << 3; 143 spidx->prefd = sizeof(struct in_addr) << 3; 144 } 145 #endif 146 spidx->ul_proto = IPPROTO_TCP; /* XXX: currently only TCP uses this */ 147 spidx->dir = dir; 148 KEYDBG(IPSEC_DUMP, 149 printf("%s: ", __func__); kdebug_secpolicyindex(spidx, NULL)); 150 } 151 152 /* Initialize PCB policy. */ 153 int 154 ipsec_init_pcbpolicy(struct inpcb *inp) 155 { 156 157 IPSEC_ASSERT(inp != NULL, ("null inp")); 158 IPSEC_ASSERT(inp->inp_sp == NULL, ("inp_sp already initialized")); 159 160 inp->inp_sp = malloc(sizeof(struct inpcbpolicy), M_IPSEC_INPCB, 161 M_NOWAIT | M_ZERO); 162 if (inp->inp_sp == NULL) 163 return (ENOBUFS); 164 return (0); 165 } 166 167 /* Delete PCB policy. */ 168 int 169 ipsec_delete_pcbpolicy(struct inpcb *inp) 170 { 171 172 if (inp->inp_sp == NULL) 173 return (0); 174 175 if (inp->inp_sp->sp_in != NULL) 176 key_freesp(&inp->inp_sp->sp_in); 177 178 if (inp->inp_sp->sp_out != NULL) 179 key_freesp(&inp->inp_sp->sp_out); 180 181 free(inp->inp_sp, M_IPSEC_INPCB); 182 inp->inp_sp = NULL; 183 return (0); 184 } 185 186 /* Deep-copy a policy in PCB. */ 187 static struct secpolicy * 188 ipsec_deepcopy_pcbpolicy(struct secpolicy *src) 189 { 190 struct secpolicy *dst; 191 int i; 192 193 if (src == NULL) 194 return (NULL); 195 196 IPSEC_ASSERT(src->state == IPSEC_SPSTATE_PCB, ("SP isn't PCB")); 197 198 dst = key_newsp(); 199 if (dst == NULL) 200 return (NULL); 201 202 /* spidx is not copied here */ 203 dst->policy = src->policy; 204 dst->state = src->state; 205 dst->priority = src->priority; 206 /* Do not touch the refcnt field. */ 207 208 /* Copy IPsec request chain. */ 209 for (i = 0; i < src->tcount; i++) { 210 dst->req[i] = ipsec_newisr(); 211 if (dst->req[i] == NULL) { 212 key_freesp(&dst); 213 return (NULL); 214 } 215 bcopy(src->req[i], dst->req[i], sizeof(struct ipsecrequest)); 216 dst->tcount++; 217 } 218 KEYDBG(IPSEC_DUMP, 219 printf("%s: copied SP(%p) -> SP(%p)\n", __func__, src, dst); 220 kdebug_secpolicy(dst)); 221 return (dst); 222 } 223 224 /* 225 * Copy IPsec policy from old INPCB into new. 226 * It is expected that new INPCB has not configured policies. 227 */ 228 int 229 ipsec_copy_pcbpolicy(struct inpcb *old, struct inpcb *new) 230 { 231 struct secpolicy *sp; 232 233 /* 234 * old->inp_sp can be NULL if PCB was created when an IPsec 235 * support was unavailable. This is not an error, we don't have 236 * policies in this PCB, so nothing to copy. 237 */ 238 if (old->inp_sp == NULL) 239 return (0); 240 241 IPSEC_ASSERT(new->inp_sp != NULL, ("new inp_sp is NULL")); 242 IPSEC_ASSERT((new->inp_sp->flags & ( 243 INP_INBOUND_POLICY | INP_OUTBOUND_POLICY)) == 0, 244 ("new PCB already has configured policies")); 245 INP_WLOCK_ASSERT(new); 246 INP_LOCK_ASSERT(old); 247 248 if (old->inp_sp->flags & INP_INBOUND_POLICY) { 249 sp = ipsec_deepcopy_pcbpolicy(old->inp_sp->sp_in); 250 if (sp == NULL) 251 return (ENOBUFS); 252 ipsec_setspidx_inpcb(new, &sp->spidx, IPSEC_DIR_INBOUND); 253 if (new->inp_sp->sp_in != NULL) 254 key_freesp(&new->inp_sp->sp_in); 255 new->inp_sp->sp_in = sp; 256 new->inp_sp->flags |= INP_INBOUND_POLICY; 257 } 258 if (old->inp_sp->flags & INP_OUTBOUND_POLICY) { 259 sp = ipsec_deepcopy_pcbpolicy(old->inp_sp->sp_out); 260 if (sp == NULL) 261 return (ENOBUFS); 262 ipsec_setspidx_inpcb(new, &sp->spidx, IPSEC_DIR_OUTBOUND); 263 if (new->inp_sp->sp_out != NULL) 264 key_freesp(&new->inp_sp->sp_out); 265 new->inp_sp->sp_out = sp; 266 new->inp_sp->flags |= INP_OUTBOUND_POLICY; 267 } 268 return (0); 269 } 270 271 static int 272 ipsec_set_pcbpolicy(struct inpcb *inp, struct ucred *cred, 273 void *request, size_t len) 274 { 275 struct sadb_x_policy *xpl; 276 struct secpolicy **spp, *newsp; 277 int error, flags; 278 279 xpl = (struct sadb_x_policy *)request; 280 /* Select direction. */ 281 switch (xpl->sadb_x_policy_dir) { 282 case IPSEC_DIR_INBOUND: 283 case IPSEC_DIR_OUTBOUND: 284 break; 285 default: 286 ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__, 287 xpl->sadb_x_policy_dir)); 288 return (EINVAL); 289 } 290 /* 291 * Privileged sockets are allowed to set own security policy 292 * and configure IPsec bypass. Unprivileged sockets only can 293 * have ENTRUST policy. 294 */ 295 switch (xpl->sadb_x_policy_type) { 296 case IPSEC_POLICY_IPSEC: 297 case IPSEC_POLICY_BYPASS: 298 if (cred != NULL && 299 priv_check_cred(cred, PRIV_NETINET_IPSEC) != 0) 300 return (EACCES); 301 /* Allocate new SP entry. */ 302 newsp = key_msg2sp(xpl, len, &error); 303 if (newsp == NULL) 304 return (error); 305 newsp->state = IPSEC_SPSTATE_PCB; 306 newsp->spidx.ul_proto = IPSEC_ULPROTO_ANY; 307 #ifdef INET 308 if (inp->inp_vflag & INP_IPV4) { 309 newsp->spidx.src.sin.sin_family = 310 newsp->spidx.dst.sin.sin_family = AF_INET; 311 newsp->spidx.src.sin.sin_len = 312 newsp->spidx.dst.sin.sin_len = 313 sizeof(struct sockaddr_in); 314 } 315 #endif 316 #ifdef INET6 317 if (inp->inp_vflag & INP_IPV6) { 318 newsp->spidx.src.sin6.sin6_family = 319 newsp->spidx.dst.sin6.sin6_family = AF_INET6; 320 newsp->spidx.src.sin6.sin6_len = 321 newsp->spidx.dst.sin6.sin6_len = 322 sizeof(struct sockaddr_in6); 323 } 324 #endif 325 break; 326 case IPSEC_POLICY_ENTRUST: 327 /* We just use NULL pointer for ENTRUST policy */ 328 newsp = NULL; 329 break; 330 default: 331 /* Other security policy types aren't allowed for PCB */ 332 return (EINVAL); 333 } 334 335 INP_WLOCK(inp); 336 if (xpl->sadb_x_policy_dir == IPSEC_DIR_INBOUND) { 337 spp = &inp->inp_sp->sp_in; 338 flags = INP_INBOUND_POLICY; 339 } else { 340 spp = &inp->inp_sp->sp_out; 341 flags = INP_OUTBOUND_POLICY; 342 } 343 /* Clear old SP and set new SP. */ 344 if (*spp != NULL) 345 key_freesp(spp); 346 *spp = newsp; 347 KEYDBG(IPSEC_DUMP, 348 printf("%s: new SP(%p)\n", __func__, newsp)); 349 if (newsp == NULL) 350 inp->inp_sp->flags &= ~flags; 351 else { 352 inp->inp_sp->flags |= flags; 353 KEYDBG(IPSEC_DUMP, kdebug_secpolicy(newsp)); 354 } 355 INP_WUNLOCK(inp); 356 return (0); 357 } 358 359 static int 360 ipsec_get_pcbpolicy(struct inpcb *inp, void *request, size_t *len) 361 { 362 struct sadb_x_policy *xpl; 363 struct secpolicy *sp; 364 int error, flags; 365 366 xpl = (struct sadb_x_policy *)request; 367 368 INP_RLOCK(inp); 369 flags = inp->inp_sp->flags; 370 /* Select direction. */ 371 switch (xpl->sadb_x_policy_dir) { 372 case IPSEC_DIR_INBOUND: 373 sp = inp->inp_sp->sp_in; 374 flags &= INP_INBOUND_POLICY; 375 break; 376 case IPSEC_DIR_OUTBOUND: 377 sp = inp->inp_sp->sp_out; 378 flags &= INP_OUTBOUND_POLICY; 379 break; 380 default: 381 INP_RUNLOCK(inp); 382 ipseclog((LOG_ERR, "%s: invalid direction=%u\n", __func__, 383 xpl->sadb_x_policy_dir)); 384 return (EINVAL); 385 } 386 387 if (flags == 0) { 388 /* Return ENTRUST policy */ 389 INP_RUNLOCK(inp); 390 xpl->sadb_x_policy_exttype = SADB_X_EXT_POLICY; 391 xpl->sadb_x_policy_type = IPSEC_POLICY_ENTRUST; 392 xpl->sadb_x_policy_id = 0; 393 xpl->sadb_x_policy_priority = 0; 394 xpl->sadb_x_policy_len = PFKEY_UNIT64(sizeof(*xpl)); 395 *len = sizeof(*xpl); 396 return (0); 397 } 398 399 IPSEC_ASSERT(sp != NULL, 400 ("sp is NULL, but flags is 0x%04x", inp->inp_sp->flags)); 401 402 key_addref(sp); 403 INP_RUNLOCK(inp); 404 error = key_sp2msg(sp, request, len); 405 key_freesp(&sp); 406 if (error == EINVAL) 407 return (error); 408 /* 409 * We return "success", but user should check *len. 410 * *len will be set to size of valid data and 411 * sadb_x_policy_len will contain needed size. 412 */ 413 return (0); 414 } 415 416 /* Handle socket option control request for PCB */ 417 static int 418 ipsec_control_pcbpolicy(struct inpcb *inp, struct sockopt *sopt) 419 { 420 void *optdata; 421 size_t optlen; 422 int error; 423 424 if (inp->inp_sp == NULL) 425 return (ENOPROTOOPT); 426 427 /* Limit maximum request size to PAGE_SIZE */ 428 optlen = sopt->sopt_valsize; 429 if (optlen < sizeof(struct sadb_x_policy) || optlen > PAGE_SIZE) 430 return (EINVAL); 431 432 optdata = malloc(optlen, M_TEMP, sopt->sopt_td ? M_WAITOK: M_NOWAIT); 433 if (optdata == NULL) 434 return (ENOBUFS); 435 /* 436 * We need a hint from the user, what policy is requested - input 437 * or output? User should specify it in the buffer, even for 438 * setsockopt(). 439 */ 440 error = sooptcopyin(sopt, optdata, optlen, optlen); 441 if (error == 0) { 442 if (sopt->sopt_dir == SOPT_SET) 443 error = ipsec_set_pcbpolicy(inp, 444 sopt->sopt_td ? sopt->sopt_td->td_ucred: NULL, 445 optdata, optlen); 446 else { 447 error = ipsec_get_pcbpolicy(inp, optdata, &optlen); 448 if (error == 0) 449 error = sooptcopyout(sopt, optdata, optlen); 450 } 451 } 452 free(optdata, M_TEMP); 453 return (error); 454 } 455 456 #ifdef INET 457 /* 458 * IPSEC_PCBCTL() method implementation for IPv4. 459 */ 460 int 461 ipsec4_pcbctl(struct inpcb *inp, struct sockopt *sopt) 462 { 463 464 if (sopt->sopt_name != IP_IPSEC_POLICY) 465 return (ENOPROTOOPT); 466 return (ipsec_control_pcbpolicy(inp, sopt)); 467 } 468 #endif 469 470 #ifdef INET6 471 /* 472 * IPSEC_PCBCTL() method implementation for IPv6. 473 */ 474 int 475 ipsec6_pcbctl(struct inpcb *inp, struct sockopt *sopt) 476 { 477 478 if (sopt->sopt_name != IPV6_IPSEC_POLICY) 479 return (ENOPROTOOPT); 480 return (ipsec_control_pcbpolicy(inp, sopt)); 481 } 482 #endif 483 484