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