1 /* $OpenBSD: udp_encap.c,v 1.23 2015/08/20 22:02:21 deraadt Exp $ */ 2 3 /* 4 * Copyright (c) 1998, 1999, 2001 Niklas Hallqvist. All rights reserved. 5 * Copyright (c) 2000 Angelos D. Keromytis. All rights reserved. 6 * Copyright (c) 2004 H�kan Olsson. 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 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include <sys/types.h> 30 #include <sys/ioctl.h> 31 #include <sys/socket.h> 32 #include <sys/sockio.h> 33 #include <net/if.h> 34 #include <netinet/in.h> 35 #include <arpa/inet.h> 36 #include <ctype.h> 37 #include <limits.h> 38 #include <netdb.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <unistd.h> 42 43 #include "conf.h" 44 #include "if.h" 45 #include "ipsec_doi.h" 46 #include "isakmp.h" 47 #include "log.h" 48 #include "message.h" 49 #include "monitor.h" 50 #include "transport.h" 51 #include "udp.h" 52 #include "udp_encap.h" 53 #include "util.h" 54 #include "virtual.h" 55 56 #define UDP_SIZE 65536 57 58 /* If a system doesn't have SO_REUSEPORT, SO_REUSEADDR will have to do. */ 59 #ifndef SO_REUSEPORT 60 #define SO_REUSEPORT SO_REUSEADDR 61 #endif 62 63 /* Reused, from udp.c */ 64 struct transport *udp_clone(struct transport *, struct sockaddr *); 65 int udp_fd_set(struct transport *, fd_set *, int); 66 int udp_fd_isset(struct transport *, fd_set *); 67 void udp_get_dst(struct transport *, struct sockaddr **); 68 void udp_get_src(struct transport *, struct sockaddr **); 69 char *udp_decode_ids(struct transport *); 70 void udp_remove(struct transport *); 71 72 static struct transport *udp_encap_create(char *); 73 static void udp_encap_report(struct transport *); 74 static void udp_encap_handle_message(struct transport *); 75 static struct transport *udp_encap_make(struct sockaddr *); 76 static int udp_encap_send_message(struct message *, 77 struct transport *); 78 79 static struct transport_vtbl udp_encap_transport_vtbl = { 80 { 0 }, "udp_encap", 81 udp_encap_create, 82 0, 83 udp_remove, 84 udp_encap_report, 85 udp_fd_set, 86 udp_fd_isset, 87 udp_encap_handle_message, 88 udp_encap_send_message, 89 udp_get_dst, 90 udp_get_src, 91 udp_decode_ids, 92 udp_clone, 93 0 94 }; 95 96 char *udp_encap_default_port = 0; 97 98 void 99 udp_encap_init(void) 100 { 101 transport_method_add(&udp_encap_transport_vtbl); 102 } 103 104 /* Create a UDP transport structure bound to LADDR just for listening. */ 105 static struct transport * 106 udp_encap_make(struct sockaddr *laddr) 107 { 108 struct udp_transport *t = 0; 109 int s, on, wildcardaddress = 0; 110 char *tstr; 111 112 t = calloc(1, sizeof *t); 113 if (!t) { 114 log_print("udp_encap_make: malloc(%lu) failed", 115 (unsigned long)sizeof *t); 116 free(laddr); 117 return 0; 118 } 119 t->src = laddr; 120 121 s = socket(laddr->sa_family, SOCK_DGRAM, IPPROTO_UDP); 122 if (s == -1) { 123 log_error("udp_encap_make: socket (%d, %d, %d)", 124 laddr->sa_family, SOCK_DGRAM, IPPROTO_UDP); 125 goto err; 126 } 127 128 /* Make sure we don't get our traffic encrypted. */ 129 if (sysdep_cleartext(s, laddr->sa_family) == -1) 130 goto err; 131 132 /* Wildcard address ? */ 133 switch (laddr->sa_family) { 134 case AF_INET: 135 if (((struct sockaddr_in *)laddr)->sin_addr.s_addr 136 == INADDR_ANY) 137 wildcardaddress = 1; 138 break; 139 case AF_INET6: 140 if (IN6_IS_ADDR_UNSPECIFIED(&((struct sockaddr_in6 *)laddr)->sin6_addr)) 141 wildcardaddress = 1; 142 break; 143 } 144 145 /* 146 * In order to have several bound specific address-port combinations 147 * with the same port SO_REUSEADDR is needed. 148 * If this is a wildcard socket and we are not listening there, but 149 * only sending from it make sure it is entirely reuseable with 150 * SO_REUSEPORT. 151 */ 152 on = 1; 153 if (setsockopt(s, SOL_SOCKET, 154 wildcardaddress ? SO_REUSEPORT : SO_REUSEADDR, 155 (void *)&on, sizeof on) == -1) { 156 log_error("udp_encap_make: setsockopt (%d, %d, %d, %p, %lu)", 157 s, SOL_SOCKET, 158 wildcardaddress ? SO_REUSEPORT : SO_REUSEADDR, &on, 159 (unsigned long)sizeof on); 160 goto err; 161 } 162 163 t->transport.vtbl = &udp_encap_transport_vtbl; 164 if (monitor_bind(s, t->src, SA_LEN(t->src))) { 165 if (sockaddr2text(t->src, &tstr, 0)) 166 log_error("udp_encap_make: bind (%d, %p, %lu)", s, 167 &t->src, (unsigned long)sizeof t->src); 168 else { 169 log_error("udp_encap_make: bind (%d, %s, %lu)", s, 170 tstr, (unsigned long)sizeof t->src); 171 free(tstr); 172 } 173 goto err; 174 } 175 176 t->s = s; 177 if (sockaddr2text(t->src, &tstr, 0)) 178 LOG_DBG((LOG_MISC, 20, "udp_encap_make: " 179 "transport %p socket %d family %d", t, s, 180 t->src->sa_family == AF_INET ? 4 : 6)); 181 else { 182 LOG_DBG((LOG_MISC, 20, "udp_encap_make: " 183 "transport %p socket %d ip %s port %d", t, s, 184 tstr, ntohs(sockaddr_port(t->src)))); 185 free(tstr); 186 } 187 transport_setup(&t->transport, 0); 188 t->transport.flags |= TRANSPORT_LISTEN; 189 return &t->transport; 190 191 err: 192 if (s >= 0) 193 close (s); 194 if (t) { 195 /* Already closed. */ 196 t->s = -1; 197 udp_remove(&t->transport); 198 } 199 return 0; 200 } 201 202 /* 203 * Initialize an object of the UDP transport class. Fill in the local 204 * IP address and port information and create a server socket bound to 205 * that specific port. Add the polymorphic transport structure to the 206 * system-wide pools of known ISAKMP transports. 207 */ 208 struct transport * 209 udp_encap_bind(const struct sockaddr *addr) 210 { 211 struct sockaddr *src; 212 213 src = malloc(SA_LEN(addr)); 214 if (!src) 215 return 0; 216 217 memcpy(src, addr, SA_LEN(addr)); 218 return udp_encap_make(src); 219 } 220 221 /* 222 * NAME is a section name found in the config database. Setup and return 223 * a transport useable to talk to the peer specified by that name. 224 */ 225 static struct transport * 226 udp_encap_create(char *name) 227 { 228 struct virtual_transport *v; 229 struct udp_transport *u; 230 struct transport *rv, *t; 231 struct sockaddr *dst, *addr; 232 struct conf_list *addr_list = 0; 233 struct conf_list_node *addr_node; 234 char *addr_str, *port_str; 235 236 port_str = conf_get_str(name, "Port"); /* XXX "Encap-port" ? */ 237 if (!port_str) 238 port_str = udp_encap_default_port; 239 if (!port_str) 240 port_str = UDP_ENCAP_DEFAULT_PORT_STR; 241 242 addr_str = conf_get_str(name, "Address"); 243 if (!addr_str) { 244 log_print("udp_encap_create: no address configured " 245 "for \"%s\"", name); 246 return 0; 247 } 248 if (text2sockaddr(addr_str, port_str, &dst, 0, 0)) { 249 log_print("udp_encap_create: address \"%s\" not understood", 250 addr_str); 251 return 0; 252 } 253 254 addr_str = conf_get_str(name, "Local-address"); 255 if (!addr_str) 256 addr_list = conf_get_list("General", "Listen-on"); 257 if (!addr_str && !addr_list) { 258 v = virtual_get_default(dst->sa_family); 259 u = (struct udp_transport *)v->encap; 260 261 if (!u) { 262 log_print("udp_encap_create: no default transport"); 263 rv = 0; 264 goto ret; 265 } else { 266 rv = udp_clone((struct transport *)u, dst); 267 if (rv) 268 rv->vtbl = &udp_encap_transport_vtbl; 269 goto ret; 270 } 271 } 272 273 if (addr_list) { 274 for (addr_node = TAILQ_FIRST(&addr_list->fields); 275 addr_node; addr_node = TAILQ_NEXT(addr_node, link)) 276 if (text2sockaddr(addr_node->field, port_str, 277 &addr, 0, 0) == 0) { 278 v = virtual_listen_lookup(addr); 279 free(addr); 280 if (v) { 281 addr_str = addr_node->field; 282 break; 283 } 284 } 285 if (!addr_str) { 286 log_print("udp_encap_create: " 287 "no matching listener found"); 288 rv = 0; 289 goto ret; 290 } 291 } 292 if (text2sockaddr(addr_str, port_str, &addr, 0, 0)) { 293 log_print("udp_encap_create: " 294 "address \"%s\" not understood", addr_str); 295 rv = 0; 296 goto ret; 297 } 298 v = virtual_listen_lookup(addr); 299 free(addr); 300 if (!v) { 301 log_print("udp_encap_create: " 302 "%s:%s must exist as a listener too", addr_str, port_str); 303 rv = 0; 304 goto ret; 305 } 306 t = (struct transport *)v; 307 rv = udp_clone(v->encap, dst); 308 if (rv) 309 rv->vtbl = &udp_encap_transport_vtbl; 310 311 ret: 312 if (addr_list) 313 conf_free_list(addr_list); 314 free(dst); 315 return rv; 316 } 317 318 /* Report transport-method specifics of the T transport. */ 319 void 320 udp_encap_report(struct transport *t) 321 { 322 struct udp_transport *u = (struct udp_transport *)t; 323 char *src = NULL, *dst = NULL; 324 in_port_t sport, dport; 325 326 if (sockaddr2text(u->src, &src, 0)) 327 return; 328 sport = sockaddr_port(u->src); 329 330 if (!u->dst || sockaddr2text(u->dst, &dst, 0)) 331 dst = 0; 332 dport = dst ? sockaddr_port(u->dst) : 0; 333 334 LOG_DBG ((LOG_REPORT, 0, "udp_encap_report: fd %d src %s:%u dst %s:%u", 335 u->s, src, ntohs(sport), dst ? dst : "*", ntohs(dport))); 336 337 free(dst); 338 free(src); 339 } 340 341 /* 342 * A message has arrived on transport T's socket. If T is single-ended, 343 * clone it into a double-ended transport which we will use from now on. 344 * Package the message as we want it and continue processing in the message 345 * module. 346 */ 347 static void 348 udp_encap_handle_message(struct transport *t) 349 { 350 struct udp_transport *u = (struct udp_transport *)t; 351 struct sockaddr_storage from; 352 struct message *msg; 353 u_int32_t len = sizeof from; 354 ssize_t n; 355 u_int8_t buf[UDP_SIZE]; 356 357 n = recvfrom(u->s, buf, UDP_SIZE, 0, (struct sockaddr *)&from, &len); 358 if (n == -1) { 359 log_error("recvfrom (%d, %p, %d, %d, %p, %p)", u->s, buf, 360 UDP_SIZE, 0, &from, &len); 361 return; 362 } 363 364 if (t->virtual == (struct transport *)virtual_get_default(AF_INET) || 365 t->virtual == (struct transport *)virtual_get_default(AF_INET6)) { 366 t->virtual->vtbl->reinit(); 367 368 /* 369 * As we don't know the actual destination address of the 370 * packet, we can't really deal with it. So, just ignore it 371 * and hope we catch the retransmission. 372 */ 373 return; 374 } 375 376 /* 377 * Make a specialized UDP transport structure out of the incoming 378 * transport and the address information we got from recvfrom(2). 379 */ 380 t = t->virtual->vtbl->clone(t->virtual, (struct sockaddr *)&from); 381 if (!t) 382 return; 383 384 /* Check NULL-ESP marker. */ 385 if (n < (ssize_t)sizeof(u_int32_t) || *(u_int32_t *)buf != 0) { 386 /* Should never happen. */ 387 log_print("udp_encap_handle_message: " 388 "Null-ESP marker not NULL or short message"); 389 return; 390 } 391 392 /* NAT-Keepalive messages should not be processed further. */ 393 n -= sizeof(u_int32_t); 394 if (n == 1 && buf[sizeof(u_int32_t)] == 0xFF) 395 return; 396 397 msg = message_alloc(t, buf + sizeof (u_int32_t), n); 398 if (!msg) { 399 log_error("failed to allocate message structure, dropping " 400 "packet received on transport %p", u); 401 return; 402 } 403 404 msg->flags |= MSG_NATT; 405 406 message_recv(msg); 407 } 408 409 /* 410 * Physically send the message MSG over its associated transport. 411 * Special: if 'msg' is NULL, send a NAT-T keepalive message. 412 */ 413 static int 414 udp_encap_send_message(struct message *msg, struct transport *t) 415 { 416 struct udp_transport *u = (struct udp_transport *)t; 417 struct msghdr m; 418 struct iovec *new_iov = 0, keepalive; 419 ssize_t n; 420 u_int32_t marker = 0; /* NULL-ESP Marker */ 421 422 if (msg) { 423 /* Construct new iov array, prefixing NULL-ESP Marker. */ 424 new_iov = calloc(msg->iovlen + 1, sizeof *new_iov); 425 if (!new_iov) { 426 log_error ("udp_encap_send_message: " 427 "calloc(%lu, %lu) failed", 428 (unsigned long)msg->iovlen + 1, 429 (unsigned long)sizeof *new_iov); 430 return -1; 431 } 432 new_iov[0].iov_base = ▮ 433 new_iov[0].iov_len = IPSEC_SPI_SIZE; 434 memcpy (new_iov + 1, msg->iov, msg->iovlen * sizeof *new_iov); 435 } else { 436 marker = ~marker; 437 keepalive.iov_base = ▮ 438 keepalive.iov_len = 1; 439 } 440 441 /* 442 * Sending on connected sockets requires that no destination address is 443 * given, or else EISCONN will occur. 444 */ 445 m.msg_name = (caddr_t)u->dst; 446 m.msg_namelen = SA_LEN(u->dst); 447 m.msg_iov = msg ? new_iov : &keepalive; 448 m.msg_iovlen = msg ? msg->iovlen + 1 : 1; 449 m.msg_control = 0; 450 m.msg_controllen = 0; 451 m.msg_flags = 0; 452 n = sendmsg (u->s, &m, 0); 453 if (msg) 454 free (new_iov); 455 if (n == -1) { 456 /* XXX We should check whether the address has gone away */ 457 log_error ("sendmsg (%d, %p, %d)", u->s, &m, 0); 458 return -1; 459 } 460 return 0; 461 } 462