1/* 2 * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. 3 * Contributed by: Michal Ludvig <mludvig@suse.cz>, SUSE Labs 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 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 * 3. Neither the name of the project nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND 19 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE 22 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 */ 30 31#include "config.h" 32 33#include <sys/types.h> 34#include <sys/param.h> 35 36#include <netinet/udp.h> 37 38#include <stdlib.h> 39#include <stdio.h> 40#include <string.h> 41#include <errno.h> 42#include <ctype.h> 43 44#include "var.h" 45#include "misc.h" 46#include "vmbuf.h" 47#include "plog.h" 48#include "debug.h" 49 50#include "localconf.h" 51#include "remoteconf.h" 52#include "sockmisc.h" 53#include "isakmp_var.h" 54#include "isakmp.h" 55#include "oakley.h" 56#include "ipsec_doi.h" 57#include "vendorid.h" 58#include "handler.h" 59#include "crypto_openssl.h" 60#include "schedule.h" 61#include "nattraversal.h" 62#include "grabmyaddr.h" 63#include "ike_session.h" 64 65struct natt_ka_addrs { 66 struct sockaddr_storage *src; 67 struct sockaddr_storage *dst; 68 unsigned in_use; 69 70 TAILQ_ENTRY(natt_ka_addrs) chain; 71}; 72 73/* 74 * check if the given vid is NAT-T. 75 */ 76int 77natt_vendorid (int vid) 78{ 79 return ( 80#ifdef ENABLE_NATT_00 81 vid == VENDORID_NATT_00 || 82#endif 83#ifdef ENABLE_NATT_01 84 vid == VENDORID_NATT_01 || 85#endif 86#ifdef ENABLE_NATT_02 87 vid == VENDORID_NATT_02 || 88 vid == VENDORID_NATT_02_N || 89#endif 90#ifdef ENABLE_NATT_03 91 vid == VENDORID_NATT_03 || 92#endif 93#ifdef ENABLE_NATT_04 94 vid == VENDORID_NATT_04 || 95#endif 96#ifdef ENABLE_NATT_05 97 vid == VENDORID_NATT_05 || 98#endif 99#ifdef ENABLE_NATT_06 100 vid == VENDORID_NATT_06 || 101#endif 102#ifdef ENABLE_NATT_07 103 vid == VENDORID_NATT_07 || 104#endif 105#ifdef ENABLE_NATT_08 106 vid == VENDORID_NATT_08 || 107#endif 108#ifdef ENABLE_NATT_APPLE 109 vid == VENDORID_NATT_APPLE || 110#endif 111 /* Always enable NATT RFC if ENABLE_NATT 112 */ 113 vid == VENDORID_NATT_RFC); 114} 115 116vchar_t * 117natt_hash_addr (phase1_handle_t *iph1, struct sockaddr_storage *addr) 118{ 119 vchar_t *natd; 120 vchar_t *buf; 121 char *ptr; 122 void *addr_ptr, *addr_port; 123 size_t buf_size, addr_size; 124 125 if (iph1->approval) { 126 plog(ASL_LEVEL_INFO, "Hashing %s with algo #%d %s\n", 127 saddr2str((struct sockaddr *)addr), iph1->approval->hashtype, 128 (iph1->rmconf->nat_traversal == NATT_FORCE)?"(NAT-T forced)":""); 129 } 130 131 if (addr->ss_family == AF_INET) { 132 addr_size = sizeof (struct in_addr); /* IPv4 address */ 133 addr_ptr = &((struct sockaddr_in *)addr)->sin_addr; 134 addr_port = &((struct sockaddr_in *)addr)->sin_port; 135 } 136 else if (addr->ss_family == AF_INET6) { 137 addr_size = sizeof (struct in6_addr); /* IPv6 address */ 138 addr_ptr = &((struct sockaddr_in6 *)addr)->sin6_addr; 139 addr_port = &((struct sockaddr_in6 *)addr)->sin6_port; 140 } 141 else { 142 plog(ASL_LEVEL_ERR, "Unsupported address family #0x%x\n", addr->ss_family); 143 return NULL; 144 } 145 146 buf_size = 2 * sizeof (cookie_t); /* CKY-I + CKY+R */ 147 buf_size += addr_size + 2; /* Address + Port */ 148 149 if ((buf = vmalloc (buf_size)) == NULL) 150 return NULL; 151 152 ptr = buf->v; 153 154 /* Copy-in CKY-I */ 155 memcpy (ptr, iph1->index.i_ck, sizeof (cookie_t)); 156 ptr += sizeof (cookie_t); 157 158 /* Copy-in CKY-I */ 159 memcpy (ptr, iph1->index.r_ck, sizeof (cookie_t)); 160 ptr += sizeof (cookie_t); 161 162 /* Copy-in Address (or zeroes if NATT_FORCE) */ 163 if (iph1->rmconf->nat_traversal == NATT_FORCE) 164 memset (ptr, 0, addr_size); 165 else 166 memcpy (ptr, addr_ptr, addr_size); 167 ptr += addr_size; 168 169 /* Copy-in Port number */ 170 memcpy (ptr, addr_port, 2); 171 172 natd = oakley_hash (buf, iph1); 173 vfree(buf); 174 175 return natd; 176} 177 178int 179natt_compare_addr_hash (phase1_handle_t *iph1, vchar_t *natd_received, 180 int natd_seq) 181{ 182 vchar_t *natd_computed; 183 u_int32_t flag; 184 int verified = 0; 185 186 if (iph1->rmconf->nat_traversal == NATT_FORCE) 187 return verified; 188 189 /* old APPLE version sends natd payload in the wrong order */ 190 if (iph1->natt_options->version == VENDORID_NATT_APPLE) { 191 if (natd_seq == 0) { 192 natd_computed = natt_hash_addr (iph1, iph1->remote); 193 flag = NAT_DETECTED_PEER; 194 } 195 else { 196 natd_computed = natt_hash_addr (iph1, iph1->local); 197 flag = NAT_DETECTED_ME; 198 } 199 } else 200 { 201 if (natd_seq == 0) { 202 natd_computed = natt_hash_addr (iph1, iph1->local); 203 flag = NAT_DETECTED_ME; 204 } 205 else { 206 natd_computed = natt_hash_addr (iph1, iph1->remote); 207 flag = NAT_DETECTED_PEER; 208 } 209 } 210 211 if (natd_received->l == natd_computed->l && 212 memcmp (natd_received->v, natd_computed->v, natd_received->l) == 0) { 213 iph1->natt_flags &= ~flag; 214 verified = 1; 215 } 216 217 if (iph1->parent_session) 218 iph1->parent_session->natt_flags = iph1->natt_flags; 219 220 vfree (natd_computed); 221 222 return verified; 223} 224 225int 226natt_udp_encap (int encmode) 227{ 228 return (encmode == IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC || 229 encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC || 230 encmode == IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT || 231 encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT); 232} 233 234int 235natt_fill_options (struct ph1natt_options *opts, int version) 236{ 237 if (! opts) 238 return -1; 239 240 opts->version = version; 241 242 switch (version) { 243 case VENDORID_NATT_02: 244 case VENDORID_NATT_02_N: 245 case VENDORID_NATT_03: 246 opts->float_port = lcconf->port_isakmp_natt; 247 opts->payload_nat_d = ISAKMP_NPTYPE_NATD_DRAFT; 248 opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_DRAFT; 249 opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT; 250 opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT; 251 opts->encaps_type = UDP_ENCAP_ESPINUDP; 252 break; 253 case VENDORID_NATT_04: 254 case VENDORID_NATT_05: 255 case VENDORID_NATT_06: 256 case VENDORID_NATT_07: 257 case VENDORID_NATT_08: 258 case VENDORID_NATT_APPLE: 259 opts->float_port = lcconf->port_isakmp_natt; 260 opts->payload_nat_d = ISAKMP_NPTYPE_NATD_BADDRAFT; 261 opts->payload_nat_oa = ISAKMP_NPTYPE_NONE; 262 opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC; 263 opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC; 264 opts->encaps_type = UDP_ENCAP_ESPINUDP; 265 break; 266 case VENDORID_NATT_RFC: 267 opts->float_port = lcconf->port_isakmp_natt; 268 opts->payload_nat_d = ISAKMP_NPTYPE_NATD_RFC; 269 opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_RFC; 270 opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC; 271 opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC; 272 opts->encaps_type = UDP_ENCAP_ESPINUDP; 273 break; 274 default: 275 plog(ASL_LEVEL_ERR, 276 "unsupported NAT-T version: %s\n", 277 vid_string_by_id(version)); 278 return -1; 279 } 280 281 opts->mode_udp_diff = opts->mode_udp_tunnel - IPSECDOI_ATTR_ENC_MODE_TUNNEL; 282 283 return 0; 284} 285 286int 287create_natoa_payloads(phase2_handle_t *iph2, vchar_t **natoa_i, vchar_t **natoa_r) 288{ 289 int natoa_type = 0; 290 vchar_t *i; 291 vchar_t *r; 292 u_int8_t *p; 293 struct sockaddr_storage *i_addr; 294 struct sockaddr_storage *r_addr; 295 size_t i_size; 296 size_t r_size; 297 298 *natoa_i = *natoa_r = NULL; 299 300 301 /* create natoa payloads if natt being used */ 302 /* don't send if type == apple */ 303 if (!iph2->ph1->natt_options) 304 return 0; 305 306 natoa_type = iph2->ph1->natt_options->payload_nat_oa; 307 if (natoa_type == 0) 308 return 0; 309 310 if (iph2->side == INITIATOR) { 311 i_addr = iph2->src; 312 r_addr = iph2->dst; 313 } else { 314 i_addr = iph2->dst; 315 r_addr = iph2->src; 316 } 317 318 switch (i_addr->ss_family) { 319 case AF_INET: 320 i_size = sizeof(in_addr_t); 321 break; 322#ifdef INET6 323 case AF_INET6: 324 i_size = sizeof(struct in6_addr); 325 break; 326#endif 327 default: 328 plog(ASL_LEVEL_ERR, 329 "invalid address family: %d\n", i_addr->ss_family); 330 return -1; 331 } 332 333 switch (r_addr->ss_family) { 334 case AF_INET: 335 r_size = sizeof(in_addr_t); 336 break; 337#ifdef INET6 338 case AF_INET6: 339 r_size = sizeof(struct in6_addr); 340 break; 341#endif 342 default: 343 plog(ASL_LEVEL_ERR, 344 "invalid address family: %d\n", r_addr->ss_family); 345 return -1; 346 } 347 348 i = vmalloc(sizeof(struct isakmp_pl_natoa) + i_size - sizeof(struct isakmp_gen)); 349 if (i == NULL) { 350 plog(ASL_LEVEL_ERR, 351 "failed to get buffer for natoa payload.\n"); 352 return -1; 353 } 354 r = vmalloc(sizeof(struct isakmp_pl_natoa) + r_size - sizeof(struct isakmp_gen)); 355 if (r == NULL) { 356 vfree(i); 357 plog(ASL_LEVEL_ERR, 358 "failed to get buffer for natoa payload.\n"); 359 return -1; 360 } 361 362 /* copy src address */ 363 p = (__typeof__(p))i->v; 364 365 switch (i_addr->ss_family) { 366 case AF_INET: 367 *p = IPSECDOI_ID_IPV4_ADDR; 368 bcopy(&(((struct sockaddr_in *)i_addr)->sin_addr.s_addr), p + sizeof(u_int32_t), i_size); 369 break; 370#ifdef INET6 371 case AF_INET6: 372 *p = IPSECDOI_ID_IPV6_ADDR; 373 bcopy(&(((struct sockaddr_in6 *)i_addr)->sin6_addr), p + sizeof(u_int32_t), i_size); 374 break; 375#endif 376 } 377 378 /* copy dst address */ 379 p = (__typeof__(p))r->v; 380 381 switch (r_addr->ss_family) { 382 case AF_INET: 383 *p = IPSECDOI_ID_IPV4_ADDR; 384 bcopy(&(((struct sockaddr_in *)r_addr)->sin_addr.s_addr), p + sizeof(u_int32_t), r_size); 385 break; 386#ifdef INET6 387 case AF_INET6: 388 *p = IPSECDOI_ID_IPV6_ADDR; 389 bcopy(&(((struct sockaddr_in6 *)r_addr)->sin6_addr), p + sizeof(u_int32_t), r_size); 390 break; 391#endif 392 } 393 394 *natoa_i = i; 395 *natoa_r = r; 396 return natoa_type; 397} 398 399struct sockaddr_storage * 400process_natoa_payload(vchar_t *buf) 401{ 402 struct sockaddr_storage *saddr = NULL; 403 struct ipsecdoi_id_b *id_b = ALIGNED_CAST(struct ipsecdoi_id_b *)buf->v; 404 405 switch (id_b->type) { 406 case IPSECDOI_ID_IPV4_ADDR: 407 saddr = racoon_malloc(sizeof(struct sockaddr_in)); 408 if (!saddr) { 409 plog(ASL_LEVEL_ERR, 410 "error allocating addr for NAT-OA payload\n"); 411 return NULL; 412 } 413 saddr->ss_len = sizeof(struct sockaddr_in); 414 saddr->ss_family = AF_INET; 415 ((struct sockaddr_in *)saddr)->sin_port = IPSEC_PORT_ANY; 416 memcpy(&((struct sockaddr_in *)saddr)->sin_addr, 417 buf->v + sizeof(*id_b), sizeof(struct in_addr)); 418 break; 419#ifdef INET6 420 case IPSECDOI_ID_IPV6_ADDR: 421 saddr = racoon_malloc(sizeof(struct sockaddr_in6)); 422 if (!saddr) { 423 plog(ASL_LEVEL_ERR, 424 "error allocating addr for NAT-OA payload\n"); 425 return NULL; 426 } 427 saddr->ss_len = sizeof(struct sockaddr_in6); 428 saddr->ss_family = AF_INET6; 429 ((struct sockaddr_in6 *)saddr)->sin6_port = IPSEC_PORT_ANY; 430 memcpy(&((struct sockaddr_in6 *)saddr)->sin6_addr, 431 buf->v + sizeof(*id_b), sizeof(struct in6_addr)); 432 break; 433#endif 434 default: 435 plog(ASL_LEVEL_ERR, 436 "invalid NAT-OA payload %d\n", id_b->type); 437 return NULL; 438 } 439 return saddr; 440} 441 442void 443natt_float_ports (phase1_handle_t *iph1) 444{ 445 446 if (! (iph1->natt_flags & NAT_DETECTED) ) 447 return; 448 if (! iph1->natt_options->float_port){ 449 /* Drafts 00 / 01, just schedule keepalive */ 450 return; 451 } 452 453 /* 454 * Only switch ports if port == isakmp port. 455 * In the case where ports are set from policy or from 456 * remote config we could be talking to a device behind 457 * a nat using the translated port. 458 */ 459 if (*get_port_ptr(iph1->local) == htons(lcconf->port_isakmp)) 460 set_port (iph1->local, iph1->natt_options->float_port); 461 if (*get_port_ptr(iph1->remote) == htons(lcconf->port_isakmp)) 462 set_port (iph1->remote, iph1->natt_options->float_port); 463 iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER; 464 465 if (iph1->version == ISAKMP_VERSION_NUMBER_IKEV1) 466 ike_session_ikev1_float_ports(iph1); 467} 468 469void 470natt_handle_vendorid (phase1_handle_t *iph1, int vid_numeric) 471{ 472 int version; 473 474 if (! iph1->natt_options) 475 iph1->natt_options = racoon_calloc (1, sizeof (*iph1->natt_options)); 476 477 if (! iph1->natt_options) { 478 plog (ASL_LEVEL_ERR, 479 "Allocating memory for natt_options failed!\n"); 480 return; 481 } 482 483 // stick to the version we already selected on a previous phase1 484 version = ike_session_get_natt_version(iph1); 485 if (version) { 486 vid_numeric = version; 487 } 488 489 if (iph1->natt_options->version < vid_numeric) 490 if (natt_fill_options (iph1->natt_options, vid_numeric) == 0) 491 iph1->natt_flags |= NAT_ANNOUNCED; 492} 493 494static struct remoteconf * 495natt_enabled_in_rmconf_stub (struct remoteconf *rmconf, void *data) 496{ 497 return (rmconf->nat_traversal ? rmconf : NULL); 498} 499 500int 501natt_enabled_in_rmconf () 502{ 503 return foreachrmconf (natt_enabled_in_rmconf_stub, NULL) != NULL; 504} 505 506 507struct payload_list * 508isakmp_plist_append_natt_vids (struct payload_list *plist, vchar_t *vid_natt[MAX_NATT_VID_COUNT]){ 509 int i, vid_natt_i = 0; 510 511 if(vid_natt == NULL) 512 return NULL; 513 514 for (i = 0; i < MAX_NATT_VID_COUNT; i++) 515 vid_natt[i]=NULL; 516 517 /* Puts the olders VIDs last, as some implementations may choose the first 518 * NATT VID given 519 */ 520 521 /* Always set RFC VID 522 */ 523 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_RFC)) != NULL) 524 vid_natt_i++; 525#ifdef ENABLE_NATT_APPLE 526 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_APPLE)) != NULL) 527 vid_natt_i++; 528#endif 529#ifdef ENABLE_NATT_08 530 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_08)) != NULL) 531 vid_natt_i++; 532#endif 533#ifdef ENABLE_NATT_07 534 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_07)) != NULL) 535 vid_natt_i++; 536#endif 537#ifdef ENABLE_NATT_06 538 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_06)) != NULL) 539 vid_natt_i++; 540#endif 541#ifdef ENABLE_NATT_05 542 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_05)) != NULL) 543 vid_natt_i++; 544#endif 545#ifdef ENABLE_NATT_04 546 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_04)) != NULL) 547 vid_natt_i++; 548#endif 549#ifdef ENABLE_NATT_03 550 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_03)) != NULL) 551 vid_natt_i++; 552#endif 553#ifdef ENABLE_NATT_02 554 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02)) != NULL) 555 vid_natt_i++; 556 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02_N)) != NULL) 557 vid_natt_i++; 558#endif 559#ifdef ENABLE_NATT_01 560 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_01)) != NULL) 561 vid_natt_i++; 562#endif 563#ifdef ENABLE_NATT_00 564 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_00)) != NULL) 565 vid_natt_i++; 566#endif 567 /* set VID payload for NAT-T */ 568 for (i = 0; i < vid_natt_i; i++) 569 plist = isakmp_plist_append(plist, vid_natt[i], ISAKMP_NPTYPE_VID); 570 571 return plist; 572} 573