1 /* $NetBSD: nattraversal.c,v 1.4 2005/08/20 00:57:06 manu Exp $ */ 2 3 /* 4 * Copyright (C) 2004 SuSE Linux AG, Nuernberg, Germany. 5 * Contributed by: Michal Ludvig <mludvig@suse.cz>, SUSE Labs 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 "config.h" 34 35 #include <sys/types.h> 36 #include <sys/param.h> 37 38 #ifdef __linux__ 39 #include <linux/udp.h> 40 #endif 41 #if defined(__NetBSD__) || defined (__FreeBSD__) 42 #include <netinet/udp.h> 43 #endif 44 45 #include <stdlib.h> 46 #include <stdio.h> 47 #include <string.h> 48 #include <errno.h> 49 #include <ctype.h> 50 51 #include "var.h" 52 #include "misc.h" 53 #include "vmbuf.h" 54 #include "plog.h" 55 #include "debug.h" 56 57 #include "localconf.h" 58 #include "remoteconf.h" 59 #include "sockmisc.h" 60 #include "isakmp_var.h" 61 #include "isakmp.h" 62 #include "oakley.h" 63 #include "ipsec_doi.h" 64 #include "vendorid.h" 65 #include "handler.h" 66 #include "crypto_openssl.h" 67 #include "schedule.h" 68 #include "nattraversal.h" 69 #include "grabmyaddr.h" 70 71 struct natt_ka_addrs { 72 struct sockaddr *src; 73 struct sockaddr *dst; 74 unsigned in_use; 75 76 TAILQ_ENTRY(natt_ka_addrs) chain; 77 }; 78 79 static TAILQ_HEAD(_natt_ka_addrs, natt_ka_addrs) ka_tree; 80 81 /* 82 * check if the given vid is NAT-T. 83 */ 84 int 85 natt_vendorid (int vid) 86 { 87 return ( 88 #ifdef ENABLE_NATT_00 89 vid == VENDORID_NATT_00 || 90 #endif 91 #ifdef ENABLE_NATT_01 92 vid == VENDORID_NATT_01 || 93 #endif 94 #ifdef ENABLE_NATT_02 95 vid == VENDORID_NATT_02 || 96 vid == VENDORID_NATT_02_N || 97 #endif 98 #ifdef ENABLE_NATT_03 99 vid == VENDORID_NATT_03 || 100 #endif 101 #ifdef ENABLE_NATT_04 102 vid == VENDORID_NATT_04 || 103 #endif 104 #ifdef ENABLE_NATT_05 105 vid == VENDORID_NATT_05 || 106 #endif 107 #ifdef ENABLE_NATT_06 108 vid == VENDORID_NATT_06 || 109 #endif 110 #ifdef ENABLE_NATT_07 111 vid == VENDORID_NATT_07 || 112 #endif 113 #ifdef ENABLE_NATT_08 114 vid == VENDORID_NATT_08 || 115 #endif 116 /* Always enable NATT RFC if ENABLE_NATT 117 */ 118 vid == VENDORID_NATT_RFC); 119 } 120 121 vchar_t * 122 natt_hash_addr (struct ph1handle *iph1, struct sockaddr *addr) 123 { 124 vchar_t *natd; 125 vchar_t *buf; 126 char *ptr; 127 void *addr_ptr, *addr_port; 128 size_t buf_size, addr_size; 129 130 plog (LLV_INFO, LOCATION, addr, "Hashing %s with algo #%d %s\n", 131 saddr2str(addr), iph1->approval->hashtype, 132 (iph1->rmconf->nat_traversal == NATT_FORCE)?"(NAT-T forced)":""); 133 134 if (addr->sa_family == AF_INET) { 135 addr_size = sizeof (struct in_addr); /* IPv4 address */ 136 addr_ptr = &((struct sockaddr_in *)addr)->sin_addr; 137 addr_port = &((struct sockaddr_in *)addr)->sin_port; 138 } 139 else if (addr->sa_family == AF_INET6) { 140 addr_size = sizeof (struct in6_addr); /* IPv6 address */ 141 addr_ptr = &((struct sockaddr_in6 *)addr)->sin6_addr; 142 addr_port = &((struct sockaddr_in6 *)addr)->sin6_port; 143 } 144 else { 145 plog (LLV_ERROR, LOCATION, addr, "Unsupported address family #0x%x\n", addr->sa_family); 146 return NULL; 147 } 148 149 buf_size = 2 * sizeof (cookie_t); /* CKY-I + CKY+R */ 150 buf_size += addr_size + 2; /* Address + Port */ 151 152 if ((buf = vmalloc (buf_size)) == NULL) 153 return NULL; 154 155 ptr = buf->v; 156 157 /* Copy-in CKY-I */ 158 memcpy (ptr, iph1->index.i_ck, sizeof (cookie_t)); 159 ptr += sizeof (cookie_t); 160 161 /* Copy-in CKY-I */ 162 memcpy (ptr, iph1->index.r_ck, sizeof (cookie_t)); 163 ptr += sizeof (cookie_t); 164 165 /* Copy-in Address (or zeroes if NATT_FORCE) */ 166 if (iph1->rmconf->nat_traversal == NATT_FORCE) 167 memset (ptr, 0, addr_size); 168 else 169 memcpy (ptr, addr_ptr, addr_size); 170 ptr += addr_size; 171 172 /* Copy-in Port number */ 173 memcpy (ptr, addr_port, 2); 174 175 natd = oakley_hash (buf, iph1); 176 vfree(buf); 177 178 return natd; 179 } 180 181 int 182 natt_compare_addr_hash (struct ph1handle *iph1, vchar_t *natd_received, 183 int natd_seq) 184 { 185 vchar_t *natd_computed; 186 u_int32_t flag; 187 int verified = 0; 188 189 if (iph1->rmconf->nat_traversal == NATT_FORCE) 190 return verified; 191 192 if (natd_seq == 0) { 193 natd_computed = natt_hash_addr (iph1, iph1->local); 194 flag = NAT_DETECTED_ME; 195 } 196 else { 197 natd_computed = natt_hash_addr (iph1, iph1->remote); 198 flag = NAT_DETECTED_PEER; 199 } 200 201 if (natd_received->l == natd_computed->l && 202 memcmp (natd_received->v, natd_computed->v, natd_received->l) == 0) { 203 iph1->natt_flags &= ~flag; 204 verified = 1; 205 } 206 207 vfree (natd_computed); 208 209 return verified; 210 } 211 212 int 213 natt_udp_encap (int encmode) 214 { 215 return (encmode == IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC || 216 encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC || 217 encmode == IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT || 218 encmode == IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT); 219 } 220 221 int 222 natt_fill_options (struct ph1natt_options *opts, int version) 223 { 224 if (! opts) 225 return -1; 226 227 opts->version = version; 228 229 switch (version) { 230 case VENDORID_NATT_00: 231 case VENDORID_NATT_01: 232 opts->float_port = 0; /* No port floating for those drafts */ 233 opts->payload_nat_d = ISAKMP_NPTYPE_NATD_DRAFT; 234 opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_DRAFT; 235 opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT; 236 opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT; 237 opts->encaps_type = UDP_ENCAP_ESPINUDP_NON_IKE; 238 break; 239 240 case VENDORID_NATT_02: 241 case VENDORID_NATT_02_N: 242 case VENDORID_NATT_03: 243 opts->float_port = lcconf->port_isakmp_natt; 244 opts->payload_nat_d = ISAKMP_NPTYPE_NATD_DRAFT; 245 opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_DRAFT; 246 opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_DRAFT; 247 opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_DRAFT; 248 opts->encaps_type = UDP_ENCAP_ESPINUDP; 249 break; 250 case VENDORID_NATT_04: 251 case VENDORID_NATT_05: 252 case VENDORID_NATT_06: 253 case VENDORID_NATT_07: 254 case VENDORID_NATT_08: 255 opts->float_port = lcconf->port_isakmp_natt; 256 opts->payload_nat_d = ISAKMP_NPTYPE_NATD_BADDRAFT; 257 opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_BADDRAFT; 258 opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC; 259 opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC; 260 opts->encaps_type = UDP_ENCAP_ESPINUDP; 261 break; 262 case VENDORID_NATT_RFC: 263 opts->float_port = lcconf->port_isakmp_natt; 264 opts->payload_nat_d = ISAKMP_NPTYPE_NATD_RFC; 265 opts->payload_nat_oa = ISAKMP_NPTYPE_NATOA_RFC; 266 opts->mode_udp_tunnel = IPSECDOI_ATTR_ENC_MODE_UDPTUNNEL_RFC; 267 opts->mode_udp_transport = IPSECDOI_ATTR_ENC_MODE_UDPTRNS_RFC; 268 opts->encaps_type = UDP_ENCAP_ESPINUDP; 269 break; 270 default: 271 plog(LLV_ERROR, LOCATION, NULL, 272 "unsupported NAT-T version: %s\n", 273 vid_string_by_id(version)); 274 return -1; 275 } 276 277 opts->mode_udp_diff = opts->mode_udp_tunnel - IPSECDOI_ATTR_ENC_MODE_TUNNEL; 278 279 return 0; 280 } 281 282 void 283 natt_float_ports (struct ph1handle *iph1) 284 { 285 if (! (iph1->natt_flags && NAT_DETECTED) ) 286 return; 287 if (! iph1->natt_options->float_port){ 288 /* Drafts 00 / 01, just schedule keepalive */ 289 natt_keepalive_add_ph1 (iph1); 290 return; 291 } 292 293 set_port (iph1->local, iph1->natt_options->float_port); 294 set_port (iph1->remote, iph1->natt_options->float_port); 295 iph1->natt_flags |= NAT_PORTS_CHANGED | NAT_ADD_NON_ESP_MARKER; 296 297 natt_keepalive_add_ph1 (iph1); 298 } 299 300 void 301 natt_handle_vendorid (struct ph1handle *iph1, int vid_numeric) 302 { 303 if (! iph1->natt_options) 304 iph1->natt_options = racoon_calloc (1, sizeof (*iph1->natt_options)); 305 306 if (! iph1->natt_options) { 307 plog (LLV_ERROR, LOCATION, NULL, 308 "Allocating memory for natt_options failed!\n"); 309 return; 310 } 311 312 if (iph1->natt_options->version < vid_numeric) 313 if (natt_fill_options (iph1->natt_options, vid_numeric) == 0) 314 iph1->natt_flags |= NAT_ANNOUNCED; 315 } 316 317 /* NAT keepalive functions */ 318 static void 319 natt_keepalive_send (void *param) 320 { 321 struct natt_ka_addrs *ka, *next = NULL; 322 char keepalive_packet[] = { 0xff }; 323 size_t len; 324 int s; 325 326 for (ka = TAILQ_FIRST(&ka_tree); ka; ka = next) { 327 next = TAILQ_NEXT(ka, chain); 328 329 s = getsockmyaddr(ka->src); 330 if (s == -1) { 331 TAILQ_REMOVE (&ka_tree, ka, chain); 332 racoon_free (ka); 333 continue; 334 } 335 plog (LLV_DEBUG, LOCATION, NULL, "KA: %s\n", 336 saddr2str_fromto("%s->%s", ka->src, ka->dst)); 337 len = sendfromto(s, keepalive_packet, sizeof (keepalive_packet), 338 ka->src, ka->dst, 1); 339 if (len == -1) 340 plog(LLV_ERROR, LOCATION, NULL, "KA: sendfromto failed: %s\n", 341 strerror (errno)); 342 } 343 344 sched_new (lcconf->natt_ka_interval, natt_keepalive_send, NULL); 345 } 346 347 void 348 natt_keepalive_init (void) 349 { 350 TAILQ_INIT(&ka_tree); 351 352 /* To disable sending KAs set natt_ka_interval=0 */ 353 if (lcconf->natt_ka_interval > 0) 354 sched_new (lcconf->natt_ka_interval, natt_keepalive_send, NULL); 355 } 356 357 int 358 natt_keepalive_add (struct sockaddr *src, struct sockaddr *dst) 359 { 360 struct natt_ka_addrs *ka = NULL, *new_addr; 361 362 TAILQ_FOREACH (ka, &ka_tree, chain) { 363 if (cmpsaddrstrict(ka->src, src) == 0 && 364 cmpsaddrstrict(ka->dst, dst) == 0) { 365 ka->in_use++; 366 plog (LLV_INFO, LOCATION, NULL, "KA found: %s (in_use=%u)\n", 367 saddr2str_fromto("%s->%s", src, dst), ka->in_use); 368 return 0; 369 } 370 } 371 372 plog (LLV_INFO, LOCATION, NULL, "KA list add: %s\n", saddr2str_fromto("%s->%s", src, dst)); 373 374 new_addr = (struct natt_ka_addrs *)racoon_malloc(sizeof(*new_addr)); 375 if (! new_addr) { 376 plog (LLV_ERROR, LOCATION, NULL, "Can't allocate new KA list item\n"); 377 return -1; 378 } 379 380 new_addr->src = dupsaddr(src); 381 new_addr->dst = dupsaddr(dst); 382 new_addr->in_use = 1; 383 TAILQ_INSERT_TAIL(&ka_tree, new_addr, chain); 384 385 return 0; 386 } 387 388 int 389 natt_keepalive_add_ph1 (struct ph1handle *iph1) 390 { 391 int ret = 0; 392 393 /* Should only the NATed host send keepalives? 394 If yes, add '(iph1->natt_flags & NAT_DETECTED_ME)' 395 to the following condition. */ 396 if (iph1->natt_flags & NAT_DETECTED && 397 ! (iph1->natt_flags & NAT_KA_QUEUED)) { 398 ret = natt_keepalive_add (iph1->local, iph1->remote); 399 if (ret == 0) 400 iph1->natt_flags |= NAT_KA_QUEUED; 401 } 402 403 return ret; 404 } 405 406 void 407 natt_keepalive_remove (struct sockaddr *src, struct sockaddr *dst) 408 { 409 struct natt_ka_addrs *ka, *next = NULL; 410 411 plog (LLV_INFO, LOCATION, NULL, "KA remove: %s\n", saddr2str_fromto("%s->%s", src, dst)); 412 413 for (ka = TAILQ_FIRST(&ka_tree); ka; ka = next) { 414 next = TAILQ_NEXT(ka, chain); 415 416 plog (LLV_DEBUG, LOCATION, NULL, "KA tree dump: %s (in_use=%u)\n", 417 saddr2str_fromto("%s->%s", src, dst), ka->in_use); 418 419 if (cmpsaddrstrict(ka->src, src) == 0 && 420 cmpsaddrstrict(ka->dst, dst) == 0 && 421 -- ka->in_use <= 0) { 422 423 plog (LLV_DEBUG, LOCATION, NULL, "KA removing this one...\n"); 424 425 TAILQ_REMOVE (&ka_tree, ka, chain); 426 racoon_free (ka); 427 /* Should we break here? Every pair of addresses should 428 be inserted only once, but who knows :-) Lets traverse 429 the whole list... */ 430 } 431 } 432 } 433 434 static struct remoteconf * 435 natt_enabled_in_rmconf_stub (struct remoteconf *rmconf, void *data) 436 { 437 return (rmconf->nat_traversal ? rmconf : NULL); 438 } 439 440 int 441 natt_enabled_in_rmconf () 442 { 443 return foreachrmconf (natt_enabled_in_rmconf_stub, NULL) != NULL; 444 } 445 446 447 struct payload_list * 448 isakmp_plist_append_natt_vids (struct payload_list *plist, vchar_t *vid_natt[MAX_NATT_VID_COUNT]){ 449 int i, vid_natt_i = 0; 450 451 if(vid_natt == NULL) 452 return NULL; 453 454 for (i = 0; i < MAX_NATT_VID_COUNT; i++) 455 vid_natt[i]=NULL; 456 457 /* Puts the olders VIDs last, as some implementations may choose the first 458 * NATT VID given 459 */ 460 461 /* Always set RFC VID 462 */ 463 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_RFC)) != NULL) 464 vid_natt_i++; 465 #ifdef ENABLE_NATT_08 466 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_08)) != NULL) 467 vid_natt_i++; 468 #endif 469 #ifdef ENABLE_NATT_07 470 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_07)) != NULL) 471 vid_natt_i++; 472 #endif 473 #ifdef ENABLE_NATT_06 474 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_06)) != NULL) 475 vid_natt_i++; 476 #endif 477 #ifdef ENABLE_NATT_05 478 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_05)) != NULL) 479 vid_natt_i++; 480 #endif 481 #ifdef ENABLE_NATT_04 482 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_04)) != NULL) 483 vid_natt_i++; 484 #endif 485 #ifdef ENABLE_NATT_03 486 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_03)) != NULL) 487 vid_natt_i++; 488 #endif 489 #ifdef ENABLE_NATT_02 490 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02)) != NULL) 491 vid_natt_i++; 492 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_02_N)) != NULL) 493 vid_natt_i++; 494 #endif 495 #ifdef ENABLE_NATT_01 496 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_01)) != NULL) 497 vid_natt_i++; 498 #endif 499 #ifdef ENABLE_NATT_00 500 if ((vid_natt[vid_natt_i] = set_vendorid(VENDORID_NATT_00)) != NULL) 501 vid_natt_i++; 502 #endif 503 /* set VID payload for NAT-T */ 504 for (i = 0; i < vid_natt_i; i++) 505 plist = isakmp_plist_append(plist, vid_natt[i], ISAKMP_NPTYPE_VID); 506 507 return plist; 508 } 509