1 /*
   2  * CDDL HEADER START
   3  *
   4  * The contents of this file are subject to the terms of the
   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  *
  26  * Copyright 2012 Jason King.
  27  * Copyright 2017 Joyent, Inc
  28  */
  29 
  30 #include <sys/types.h>
  31 #include <sys/socket.h>
  32 #include "defs.h"
  33 #include "config.h"
  34 #include "ikev2_sa.h"
  35 #include "ikev2_pkt.h"
  36 #include "worker.h"
  37 #include "inbound.h"
  38 #include "timer.h"
  39 #include "fromto.h"
  40 #include "ikev2_proto.h"
  41 #include "config.h"
  42 
  43 #define SPILOG(_level, _log, _msg, _src, _dest, _lspi, _rspi, ...)      \
  44         NETLOG(_level, _log, _msg, _src, _dest,                         \
  45         BUNYAN_T_UINT64, "local_spi", (_lspi),                          \
  46         BUNYAN_T_UINT64, "remote_spi", (_rspi),                         \
  47         ## __VA_ARGS__)
  48 
  49 #define PKT_PTR(pkt)    ((uchar_t *)(pkt)->pkt_raw)
  50 
  51 static void ikev2_retransmit(te_event_t, void *);
  52 static int select_socket(const ikev2_sa_t *, const struct sockaddr_storage *);
  53 
  54 /*
  55  * Find the IKEv2 SA for a given inbound packet (or create a new one if
  56  * an IKE_SA_INIT exchange) and send packet to worker.
  57  */
  58 void
  59 ikev2_dispatch(pkt_t *pkt, const struct sockaddr_storage *restrict l_addr,
  60     const struct sockaddr_storage *restrict r_addr)
  61 {
  62         ikev2_sa_t *i2sa = NULL;
  63         uint64_t local_spi = INBOUND_LOCAL_SPI(&pkt->pkt_header);
  64         uint64_t remote_spi = INBOUND_REMOTE_SPI(&pkt->pkt_header);
  65 
  66         i2sa = ikev2_sa_get(local_spi, remote_spi, l_addr, r_addr, pkt);
  67         if (i2sa != NULL)
  68                 goto dispatch;
  69 
  70         if (local_spi != 0) {
  71                 /*
  72                  * If the local SPI is set, we should be able to find it
  73                  * in our hash.
  74                  *
  75                  * XXX: Should we respond with a notificaiton?
  76                  *
  77                  * RFC5996 2.21.4 we may send an INVALID_IKE_SPI
  78                  * notification if we wish.
  79                  *
  80                  * For now, discard.
  81                  */
  82                 SPILOG(debug, log, "cannot find existing IKE SA with "
  83                     "matching local SPI value; discarding",
  84                     r_addr, l_addr, local_spi, remote_spi);
  85 
  86                 ikev2_pkt_free(pkt);
  87                 return;
  88         }
  89 
  90         if (remote_spi == 0) {
  91                 /*
  92                  * XXX: this might require special processing.
  93                  * Discard for now.
  94                  */
  95                 goto discard;
  96         }
  97 
  98         /*
  99          * If the local SPI == 0, this can only be an IKE SA INIT
 100          * exchange.  For all such exchanges, the msgid is always 0,
 101          * regardless of the the number of actual messages sent during
 102          * the exchange (RFC5996 2.2).
 103          */
 104         if (pkt->pkt_header.exch_type != IKEV2_EXCH_IKE_SA_INIT ||
 105             pkt->pkt_header.msgid != 0) {
 106                 SPILOG(debug, log, "received non IKE_SA_INIT message with "
 107                     "0 local spi; discarding", r_addr, l_addr, local_spi,
 108                     remote_spi,
 109                     BUNYAN_T_UINT32, "exch_type",
 110                     (uint32_t)pkt->pkt_header.exch_type,
 111                     BUNYAN_T_UINT32, "msgid", pkt->pkt_header.msgid);
 112                 goto discard;
 113         }
 114 
 115         /*
 116          * If there isn't an existing IKEv2 SA, the only
 117          * valid inbound packet is a request to start an
 118          * IKE_EXCH_IKE_SA_INIT exchange.
 119          */
 120         if (!(pkt->pkt_header.flags & IKEV2_FLAG_INITIATOR)) {
 121                 SPILOG(debug, log, "cannot find existing SA", r_addr, l_addr,
 122                     local_spi, remote_spi);
 123                 goto discard;
 124         }
 125 
 126         /* otherwise create a larval SA */
 127         i2sa = ikev2_sa_alloc(B_FALSE, pkt, l_addr, r_addr);
 128         if (i2sa == NULL) {
 129                 SPILOG(warn, log, "could not create IKEv2 SA", r_addr,
 130                     l_addr, local_spi, remote_spi);
 131                 goto discard;
 132         }
 133         local_spi = I2SA_LOCAL_SPI(i2sa);
 134 
 135 dispatch:
 136         pkt->pkt_sa = i2sa;
 137         if (worker_dispatch(EVT_PACKET, pkt, local_spi % nworkers))
 138                 return;
 139 
 140         SPILOG(info, log, "worker queue full; discarding packet",
 141             r_addr, l_addr, local_spi, remote_spi);
 142 
 143 discard:
 144         if (i2sa != NULL)
 145                 I2SA_REFRELE(i2sa);
 146         ikev2_pkt_free(pkt);
 147 }
 148 
 149 /*
 150  * Sends a packet out.  If pkt is an error reply, is_error should be
 151  * set so that it is not saved for possible retransmission.
 152  *
 153  */
 154 boolean_t
 155 ikev2_send(pkt_t *pkt, boolean_t is_error)
 156 {
 157         ikev2_sa_t *i2sa = pkt->pkt_sa;
 158         ssize_t len = 0;
 159         int s = -1;
 160         boolean_t initiator = !!(pkt->pkt_header.flags & IKEV2_FLAG_INITIATOR);
 161 
 162         if (initiator) {
 163                 /*
 164                  * We should not send out a new exchange while still waiting
 165                  * on a response from a previous request
 166                  */
 167                 ASSERT3P(sa->last_sent, ==, NULL);
 168                 pkt->pkt_header.msgid = i2sa->outmsgid;
 169         }
 170 
 171         if (!pkt_done(pkt)) {
 172                 I2SA_REFRELE(i2sa);
 173                 ikev2_pkt_free(pkt);
 174                 return (B_FALSE);
 175         }
 176 
 177         s = select_socket(i2sa, NULL);
 178         len = sendfromto(s, PKT_PTR(pkt), pkt_len(pkt), &i2sa->laddr,
 179             &i2sa->raddr);
 180         if (len == -1 && pkt != i2sa->init) {
 181                 /*
 182                  * If it failed, should we still save it and let
 183                  * ikev2_retransmit attempt?  For now, no.
 184                  *
 185                  * Note: sendfromto() should have logged any relevant errors
 186                  */
 187                 I2SA_REFRELE(i2sa);
 188                 ikev2_pkt_free(pkt);
 189                 return (B_FALSE);
 190         }
 191 
 192         PTH(pthread_mutex_lock(&i2sa->lock));
 193         if (initiator) {
 194                 /* XXX: bump & save for error messages? */
 195 
 196                 /*
 197                  * In a few instances (e.g. cookies) we explicitly re-send the
 198                  * last packet instead of waiting for the retransmit timeout
 199                  * to kick in.  In those instances, we don't want to bump
 200                  * the message since it's not a new exchange.
 201                  */
 202                 if (pkt != i2sa->last_sent)
 203                         i2sa->outmsgid++;
 204 
 205                 i2sa->last_sent = pkt;
 206 
 207                 if (!is_error) {
 208                         config_t *cfg = config_get();
 209                         VERIFY(schedule_timeout(TE_TRANSMIT, ikev2_retransmit,
 210                             pkt, cfg->cfg_retry_init));
 211                         CONFIG_REFRELE(cfg);
 212                 }
 213         } else {
 214                 i2sa->last_resp_sent = pkt;
 215         }
 216         PTH(pthread_mutex_unlock(&i2sa->lock));
 217 
 218         if (is_error) {
 219                 I2SA_REFRELE(i2sa);
 220                 ikev2_pkt_free(pkt);
 221         }
 222 
 223         return (B_TRUE);
 224 }
 225 
 226 /*
 227  * Retransmit callback
 228  */
 229 static void
 230 ikev2_retransmit(te_event_t event, void *data)
 231 {
 232         pkt_t *pkt = data;
 233         ikev2_sa_t *sa = pkt->pkt_sa;
 234         hrtime_t retry = 0;
 235         ssize_t len;
 236 
 237         PTH(pthread_mutex_lock(&sa->lock));
 238 
 239         /* XXX: what about condemned SAs */
 240         if (sa->outmsgid > pkt->pkt_header.msgid || sa->last_sent == NULL) {
 241                 /* already acknowledged */
 242                 PTH(pthread_mutex_unlock(&sa->lock));
 243                 ikev2_pkt_free(pkt);
 244                 return;
 245         }
 246 
 247         config_t *cfg = config_get();
 248         retry = cfg->cfg_retry_init * (1ULL << ++pkt->pkt_xmit);
 249         if (retry > cfg->cfg_retry_max || pkt->pkt_xmit > cfg->cfg_retry_max) {
 250                 PTH(pthread_mutex_unlock(&sa->lock));
 251                 ikev2_sa_condemn(sa);
 252                 ikev2_pkt_free(pkt);
 253                 CONFIG_REFRELE(cfg);
 254                 return;
 255         }
 256         PTH(pthread_mutex_unlock(&sa->lock));
 257         CONFIG_REFRELE(cfg);
 258 
 259         len = sendfromto(select_socket(sa, NULL), PKT_PTR(pkt), pkt_len(pkt),
 260             &sa->laddr, &sa->raddr);
 261         /* XXX: sendfromto() will log if it fails, do anything else? */
 262 
 263         VERIFY(schedule_timeout(TE_TRANSMIT, ikev2_retransmit, pkt, retry));
 264 }
 265 
 266 /*
 267  * Determine if the packet should be discarded, or retransmit our last
 268  * packet if appropriate
 269  * XXX better function name?
 270  */
 271 static boolean_t
 272 ikev2_discard_pkt(pkt_t *pkt)
 273 {
 274         ikev2_sa_t *sa = pkt->pkt_sa;
 275         uint32_t msgid = pkt->pkt_header.msgid;
 276         boolean_t discard = B_TRUE;
 277 
 278         PTH(pthread_mutex_lock(&sa->lock));
 279         if (sa->flags & I2SA_CONDEMNED)
 280                 goto done;
 281 
 282         if (pkt->pkt_header.flags & IKEV2_FLAG_RESPONSE) {
 283                 pkt_t *last = sa->last_sent;
 284 
 285                 if (msgid != sa->outmsgid) {
 286                         /*
 287                          * Not a response to our last message.
 288                          * XXX: Send INVALID_MESSAGE_ID notification in
 289                          * certain circumstances.  Drop for now.
 290                          */
 291                         goto done;
 292                 }
 293 
 294                 /* A response to our last message */
 295                 VERIFY3S(cancel_timeout(TE_TRANSMIT, last,
 296                     sa->i2sa_log), ==, 1);
 297 
 298                 /*
 299                  * Corner case: this isn't the actual response in the
 300                  * IKE_SA_INIT exchange, but a request to either use
 301                  * cookies or a different DH group.  In that case we don't
 302                  * want to treat it like a response (ending the exchange).
 303                  */
 304                 if (pkt->pkt_header.exch_type != IKEV2_EXCH_IKE_SA_INIT ||
 305                     pkt->pkt_header.responder_spi != 0)
 306                         sa->last_sent = NULL;
 307 
 308                 /* Keep the initial packet for duration of IKE SA */
 309                 if (last != sa->init)
 310                         ikev2_pkt_free(last);
 311                 discard = B_FALSE;
 312                 goto done;
 313         }
 314 
 315         ASSERT(pkt->pkt_header.flags & IKEV2_FLAG_INITIATOR);
 316 
 317         if (msgid == sa->inmsgid) {
 318                 pkt_t *resp = sa->last_resp_sent;
 319                 ssize_t len = 0;
 320 
 321                 if (resp == NULL) {
 322                         discard = B_FALSE;
 323                         goto done;
 324                 }
 325 
 326                 len = sendfromto(select_socket(sa, NULL), PKT_PTR(resp),
 327                     pkt_len(pkt), &sa->laddr, &sa->raddr);
 328                 goto done;
 329         }
 330 
 331         if (msgid != sa->inmsgid + 1) {
 332                 /*
 333                  * XXX: create new informational exchange, send
 334                  * INVALID_MESSAGE_ID notification?
 335                  */
 336                 goto done;
 337         }
 338 
 339         /* new exchange, free last response and get going */
 340         ikev2_pkt_free(sa->last_resp_sent);
 341         sa->last_resp_sent = NULL;
 342         sa->inmsgid++;
 343         discard = B_FALSE;
 344 
 345 done:
 346         PTH(pthread_mutex_unlock(&sa->lock));
 347         return (discard);
 348 }
 349 
 350 /*
 351  * Worker inbound function
 352  */
 353 void
 354 ikev2_inbound(pkt_t *pkt)
 355 {
 356         if (ikev2_discard_pkt(pkt))
 357                 return;
 358 
 359         switch (pkt->pkt_header.exch_type) {
 360         case IKEV2_EXCH_IKE_SA_INIT:
 361                 if (pkt->pkt_header.flags & IKEV2_FLAG_INITIATOR)
 362                         ikev2_sa_init_inbound_init(pkt);
 363                 else
 364                         ikev2_sa_init_inbound_resp(pkt);
 365                 break;
 366         case IKEV2_EXCH_IKE_AUTH:
 367         case IKEV2_EXCH_CREATE_CHILD_SA:
 368         case IKEV2_EXCH_INFORMATIONAL:
 369         case IKEV2_EXCH_IKE_SESSION_RESUME:
 370                 /* TODO */
 371                 bunyan_info(pkt->pkt_sa->i2sa_log,
 372                     "Exchange not implemented yet", BUNYAN_T_END);
 373                 ikev2_pkt_free(pkt);
 374                 break;
 375         default:
 376                 bunyan_error(pkt->pkt_sa->i2sa_log, "Unknown IKEV2 exchange",
 377                     BUNYAN_T_UINT32, "exchange",
 378                     (uint32_t)pkt->pkt_header.exch_type, BUNYAN_T_END);
 379                 ikev2_pkt_free(pkt);
 380         }
 381 }
 382 
 383 static int
 384 select_socket(const ikev2_sa_t *i2sa, const struct sockaddr_storage *local)
 385 {
 386         ASSERT((i2sa != NULL && local == NULL) ||
 387             (i2sa == NULL && local != NULL));
 388 
 389         if (i2sa != NULL)
 390                 local = &i2sa->laddr;
 391         if (local->ss_family == AF_INET6)
 392                 return (ikesock6);
 393         if (i2sa != NULL && I2SA_IS_NAT(i2sa))
 394                 return (nattsock);
 395         return (ikesock4);
 396 }
 397 
 398 void
 399 ikev2_no_proposal_chosen(ikev2_sa_t *restrict i2sa, const pkt_t *restrict src,
 400     ikev2_spi_proto_t proto, uint64_t spi)
 401 {
 402         pkt_t *resp = ikev2_pkt_new_response(src);
 403 
 404         if (resp == NULL)
 405                 return;
 406 
 407         if (!ikev2_add_notify(resp, proto, spi, IKEV2_N_NO_PROPOSAL_CHOSEN,
 408             NULL, 0)) {
 409                 ikev2_pkt_free(resp);
 410                 return;
 411         }
 412 
 413         /* Nothing can be done if send fails for this, so ignore return val */
 414         (void) ikev2_send(resp, B_TRUE);
 415 
 416         /* ikev2_send consumes packet, no need to free afterwards */
 417 }