The Design and Implementation of the FreeBSD Operating System, Second Edition
Now available: The Design and Implementation of the FreeBSD Operating System (Second Edition)


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]

FreeBSD/Linux Kernel Cross Reference
sys/netkey/key.c

Version: -  FREEBSD  -  FREEBSD-13-STABLE  -  FREEBSD-13-0  -  FREEBSD-12-STABLE  -  FREEBSD-12-0  -  FREEBSD-11-STABLE  -  FREEBSD-11-0  -  FREEBSD-10-STABLE  -  FREEBSD-10-0  -  FREEBSD-9-STABLE  -  FREEBSD-9-0  -  FREEBSD-8-STABLE  -  FREEBSD-8-0  -  FREEBSD-7-STABLE  -  FREEBSD-7-0  -  FREEBSD-6-STABLE  -  FREEBSD-6-0  -  FREEBSD-5-STABLE  -  FREEBSD-5-0  -  FREEBSD-4-STABLE  -  FREEBSD-3-STABLE  -  FREEBSD22  -  l41  -  OPENBSD  -  linux-2.6  -  MK84  -  PLAN9  -  xnu-8792 
SearchContext: -  none  -  3  -  10 

    1 /*----------------------------------------------------------------------
    2   key.c :         Key Management Engine for BSD
    3 
    4   Copyright 1995 by Bao Phan,  Randall Atkinson, & Dan McDonald,
    5   All Rights Reserved.  All Rights have been assigned to the US
    6   Naval Research Laboratory (NRL).  The NRL Copyright Notice and
    7   License governs distribution and use of this software.
    8 
    9   Patents are pending on this technology.  NRL grants a license
   10   to use this technology at no cost under the terms below with
   11   the additional requirement that software, hardware, and 
   12   documentation relating to use of this technology must include
   13   the note that:
   14         This product includes technology developed at and
   15         licensed from the Information Technology Division, 
   16         US Naval Research Laboratory.
   17 
   18 ----------------------------------------------------------------------*/
   19 /*----------------------------------------------------------------------
   20 #       @(#)COPYRIGHT   1.1a (NRL) 17 August 1995
   21 
   22 COPYRIGHT NOTICE
   23 
   24 All of the documentation and software included in this software
   25 distribution from the US Naval Research Laboratory (NRL) are
   26 copyrighted by their respective developers.
   27 
   28 This software and documentation were developed at NRL by various
   29 people.  Those developers have each copyrighted the portions that they
   30 developed at NRL and have assigned All Rights for those portions to
   31 NRL.  Outside the USA, NRL also has copyright on the software
   32 developed at NRL. The affected files all contain specific copyright
   33 notices and those notices must be retained in any derived work.
   34 
   35 NRL LICENSE
   36 
   37 NRL grants permission for redistribution and use in source and binary
   38 forms, with or without modification, of the software and documentation
   39 created at NRL provided that the following conditions are met:
   40 
   41 1. Redistributions of source code must retain the above copyright
   42    notice, this list of conditions and the following disclaimer.
   43 2. Redistributions in binary form must reproduce the above copyright
   44    notice, this list of conditions and the following disclaimer in the
   45    documentation and/or other materials provided with the distribution.
   46 3. All advertising materials mentioning features or use of this software
   47    must display the following acknowledgement:
   48 
   49         This product includes software developed at the Information
   50         Technology Division, US Naval Research Laboratory.
   51 
   52 4. Neither the name of the NRL nor the names of its contributors
   53    may be used to endorse or promote products derived from this software
   54    without specific prior written permission.
   55 
   56 THE SOFTWARE PROVIDED BY NRL IS PROVIDED BY NRL AND CONTRIBUTORS ``AS
   57 IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
   58 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
   59 PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL NRL OR
   60 CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
   61 EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
   62 PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
   63 PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
   64 LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
   65 NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
   66 SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
   67 
   68 The views and conclusions contained in the software and documentation
   69 are those of the authors and should not be interpreted as representing
   70 official policies, either expressed or implied, of the US Naval
   71 Research Laboratory (NRL).
   72 
   73 ----------------------------------------------------------------------*/
   74 
   75 #include <sys/param.h>
   76 #include <sys/systm.h>
   77 #include <sys/kernel.h>
   78 #include <sys/domain.h>
   79 #include <sys/mbuf.h>
   80 #include <sys/proc.h>
   81 #include <sys/protosw.h>
   82 #include <sys/socket.h>
   83 #include <sys/socketvar.h>
   84 #include <sys/time.h>
   85 
   86 #include <net/raw_cb.h>
   87 #include <net/if.h>
   88 #include <net/if_types.h>
   89 #include <net/if_dl.h>
   90 #include <net/route.h>
   91 
   92 #include <netinet/in.h>
   93 #include <netinet/in_var.h>
   94 #include <netinet/if_ether.h>
   95 
   96 #ifdef INET6
   97 #include <netinet6/in6.h>
   98 #include <netinet6/in6_var.h>
   99 #endif /* INET6 */
  100 
  101 #include <netkey/key.h>
  102 #include <netkey/key_debug.h>
  103 
  104 #define SOCKADDR struct sockaddr
  105 
  106 #define KMALLOC(p, t, n) (p = (t) malloc((unsigned long)(n), M_SECA, M_DONTWAIT))
  107 #define KFREE(p) free((caddr_t)p, M_SECA);
  108 
  109 #define CRITICAL_DCL int critical_s;
  110 #define CRITICAL_START critical_s = splnet()
  111 #define CRITICAL_END splx(critical_s)
  112 
  113 #define TIME_SECONDS time.tv_sec
  114 #define CURRENT_PID curproc->p_pid
  115 
  116 #define DEFARGS(arglist, args) arglist args;
  117 #define AND ;
  118 
  119 #ifdef INET6
  120 #define MAXHASHKEYLEN (2 * sizeof(int) + 2 * sizeof(struct sockaddr_in6))
  121 #else
  122 #define MAXHASHKEYLEN (2 * sizeof(int) + 2 * sizeof(struct sockaddr_in))
  123 #endif
  124 
  125 
  126 /*
  127  *  Not clear whether these values should be 
  128  *  tweakable at kernel config time.
  129  */
  130 #define KEYTBLSIZE 61
  131 #define KEYALLOCTBLSIZE 61
  132 #define SO2SPITBLSIZE 61
  133 
  134 /*
  135  *  These values should be tweakable...
  136  *  perhaps by using sysctl
  137  */
  138 
  139 #define MAXLARVALTIME 240;   /* Lifetime of a larval key table entry */ 
  140 #define MAXKEYACQUIRE 1;     /* Max number of key acquire messages sent */
  141                              /*   per destination address               */
  142 #define MAXACQUIRETIME 15;   /* Lifetime of acquire message */
  143 
  144 /*
  145  *  Key engine tables and global variables
  146  */
  147 
  148 struct key_tblnode keytable[KEYTBLSIZE];
  149 struct key_allocnode keyalloctbl[KEYALLOCTBLSIZE];
  150 struct key_so2spinode so2spitbl[SO2SPITBLSIZE];
  151 
  152 struct keyso_cb keyso_cb;
  153 struct key_tblnode nullkeynode;
  154 struct key_registry *keyregtable;
  155 struct key_acquirelist *key_acquirelist;
  156 u_long maxlarvallifetime = MAXLARVALTIME;
  157 int maxkeyacquire = MAXKEYACQUIRE;
  158 u_long maxacquiretime = MAXACQUIRETIME;
  159 
  160 extern SOCKADDR key_addr;
  161 
  162 #define ROUNDUP(a) \
  163   ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
  164 #define ADVANCE(x, n) \
  165     { x += ROUNDUP(n); }
  166 
  167 static int my_addr __P((SOCKADDR *));
  168 static int key_sendup __P((struct socket *, struct key_msghdr *));
  169 
  170 /*----------------------------------------------------------------------
  171  * key_secassoc2msghdr(): 
  172  *      Copy info from a security association into a key message buffer.
  173  *      Assume message buffer is sufficiently large to hold all security
  174  *      association information including src, dst, from, key and iv.
  175  ----------------------------------------------------------------------*/
  176 int
  177 key_secassoc2msghdr(struct key_secassoc *secassoc,
  178                     struct key_msghdr *km,
  179                     struct key_msgdata *keyinfo)
  180 {
  181   char *cp;
  182   DPRINTF(IDL_FINISHED, ("Entering key_secassoc2msghdr\n"));
  183 
  184   if ((km == 0) || (keyinfo == 0) || (secassoc == 0))
  185     return(-1);
  186 
  187   km->type = secassoc->type;
  188   km->state = secassoc->state;
  189   km->label = secassoc->label;
  190   km->spi = secassoc->spi;
  191   km->keylen = secassoc->keylen;
  192   km->ivlen = secassoc->ivlen;
  193   km->algorithm = secassoc->algorithm;
  194   km->lifetype = secassoc->lifetype;
  195   km->lifetime1 = secassoc->lifetime1;
  196   km->lifetime2 = secassoc->lifetime2;
  197 
  198   /*
  199    *  Stuff src/dst/from/key/iv in buffer after
  200    *  the message header.
  201    */
  202   cp = (char *)(km + 1);
  203 
  204   DPRINTF(IDL_FINISHED, ("sa2msghdr: 1\n"));
  205   keyinfo->src = (SOCKADDR *)cp;
  206   if (secassoc->src->sa_len) {
  207     bcopy(secassoc->src, cp, secassoc->src->sa_len);
  208     ADVANCE(cp, secassoc->src->sa_len);
  209   } else {
  210     bzero(cp, MAX_SOCKADDR_SZ);
  211     ADVANCE(cp, MAX_SOCKADDR_SZ);
  212   }
  213 
  214   DPRINTF(IDL_FINISHED, ("sa2msghdr: 2\n"));
  215   keyinfo->dst = (SOCKADDR *)cp;
  216   if (secassoc->dst->sa_len) {
  217     bcopy(secassoc->dst, cp, secassoc->dst->sa_len);
  218     ADVANCE(cp, secassoc->dst->sa_len);
  219   } else {
  220     bzero(cp, MAX_SOCKADDR_SZ);
  221     ADVANCE(cp, MAX_SOCKADDR_SZ);
  222   }
  223 
  224   DPRINTF(IDL_FINISHED, ("sa2msghdr: 3\n"));
  225   keyinfo->from = (SOCKADDR *)cp;
  226   if (secassoc->from->sa_len) {
  227     bcopy(secassoc->from, cp, secassoc->from->sa_len);
  228     ADVANCE(cp, secassoc->from->sa_len);
  229   } else {
  230     bzero(cp, MAX_SOCKADDR_SZ);
  231     ADVANCE(cp, MAX_SOCKADDR_SZ);
  232   }
  233 
  234   DPRINTF(IDL_FINISHED, ("sa2msghdr: 4\n"));
  235 
  236   keyinfo->key = cp;
  237   keyinfo->keylen = secassoc->keylen;
  238   if (secassoc->keylen) {
  239     bcopy((char *)(secassoc->key), cp, secassoc->keylen);
  240     ADVANCE(cp, secassoc->keylen);
  241   }
  242 
  243   DPRINTF(IDL_FINISHED, ("sa2msghdr: 5\n"));
  244   keyinfo->iv = cp;
  245   keyinfo->ivlen = secassoc->ivlen;
  246   if (secassoc->ivlen) {
  247     bcopy((char *)(secassoc->iv), cp, secassoc->ivlen);
  248     ADVANCE(cp, secassoc->ivlen);
  249   }
  250 
  251   DDO(IDL_FINISHED,printf("msgbuf(len=%d):\n",(char *)cp - (char *)km));
  252   DDO(IDL_FINISHED,dump_buf((char *)km, (char *)cp - (char *)km));
  253   DPRINTF(IDL_FINISHED, ("sa2msghdr: 6\n"));
  254   return(0);
  255 }
  256 
  257 
  258 /*----------------------------------------------------------------------
  259  * key_msghdr2secassoc():
  260  *      Copy info from a key message buffer into a key_secassoc 
  261  *      structure
  262  ----------------------------------------------------------------------*/
  263 int
  264 key_msghdr2secassoc(struct key_secassoc *secassoc,
  265                     struct key_msghdr *km,
  266                     struct key_msgdata *keyinfo)
  267 {
  268   DPRINTF(IDL_FINISHED, ("Entering key_msghdr2secassoc\n"));
  269 
  270   if ((km == 0) || (keyinfo == 0) || (secassoc == 0))
  271     return(-1);
  272 
  273   secassoc->len = sizeof(*secassoc);
  274   secassoc->type = km->type;
  275   secassoc->state = km->state;
  276   secassoc->label = km->label;
  277   secassoc->spi = km->spi;
  278   secassoc->keylen = km->keylen;
  279   secassoc->ivlen = km->ivlen;
  280   secassoc->algorithm = km->algorithm;
  281   secassoc->lifetype = km->lifetype;
  282   secassoc->lifetime1 = km->lifetime1;
  283   secassoc->lifetime2 = km->lifetime2;
  284 
  285   if (keyinfo->src) {
  286     KMALLOC(secassoc->src, SOCKADDR *, keyinfo->src->sa_len);
  287     if (!secassoc->src) {
  288       DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for src\n"));
  289       return(-1);
  290     }
  291     bcopy((char *)keyinfo->src, (char *)secassoc->src,
  292           keyinfo->src->sa_len);
  293   } else
  294     secassoc->src = NULL;
  295 
  296   if (keyinfo->dst) {
  297     KMALLOC(secassoc->dst, SOCKADDR *, keyinfo->dst->sa_len);
  298     if (!secassoc->dst) {
  299       DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for dst\n"));
  300       return(-1);
  301     }
  302     bcopy((char *)keyinfo->dst, (char *)secassoc->dst,
  303           keyinfo->dst->sa_len);
  304   } else
  305     secassoc->dst = NULL;
  306 
  307   if (keyinfo->from) {
  308     KMALLOC(secassoc->from, SOCKADDR *, keyinfo->from->sa_len);
  309     if (!secassoc->from) {
  310       DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for from\n"));
  311       return(-1);
  312     }
  313     bcopy((char *)keyinfo->from, (char *)secassoc->from,
  314           keyinfo->from->sa_len);
  315   } else
  316     secassoc->from = NULL;
  317 
  318   /*
  319    *  Make copies of key and iv
  320    */
  321   if (secassoc->ivlen) {
  322     KMALLOC(secassoc->iv, caddr_t, secassoc->ivlen);
  323     if (secassoc->iv == 0) {
  324       DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for iv\n"));
  325       return(-1);
  326     }
  327     bcopy((char *)keyinfo->iv, (char *)secassoc->iv, secassoc->ivlen);
  328   } else
  329     secassoc->iv = NULL;
  330              
  331   if (secassoc->keylen) {
  332     KMALLOC(secassoc->key, caddr_t, secassoc->keylen);
  333     if (secassoc->key == 0) {
  334       DPRINTF(IDL_ERROR,("msghdr2secassoc: can't allocate mem for key\n"));
  335       if (secassoc->iv)
  336         KFREE(secassoc->iv);
  337       return(-1);
  338     }
  339     bcopy((char *)keyinfo->key, (char *)secassoc->key, secassoc->keylen);
  340   } else
  341     secassoc->key = NULL;
  342   return(0);
  343 }
  344 
  345 
  346 /*----------------------------------------------------------------------
  347  * addrpart_equal():
  348  *      Determine if the address portion of two sockaddrs are equal.
  349  *      Currently handles only AF_INET and AF_INET6 address families.
  350  ----------------------------------------------------------------------*/
  351 static int
  352 addrpart_equal(SOCKADDR *sa1, SOCKADDR *sa2)
  353 {
  354   if ((sa1->sa_family != sa2->sa_family) ||
  355       (sa1->sa_len != sa2->sa_len))
  356     return 0;
  357 
  358   switch(sa1->sa_family) {
  359   case AF_INET:
  360     return (((struct sockaddr_in *)sa1)->sin_addr.s_addr == 
  361             ((struct sockaddr_in *)sa2)->sin_addr.s_addr);
  362 #ifdef INET6
  363   case AF_INET6:
  364     return (IN6_ADDR_EQUAL(((struct sockaddr_in6 *)sa1)->sin6_addr, 
  365                            ((struct sockaddr_in6 *)sa2)->sin6_addr));
  366 #endif /* INET6 */
  367   }
  368   return(0);
  369 }
  370 
  371 /*----------------------------------------------------------------------
  372  * key_inittables():
  373  *      Allocate space and initialize key engine tables
  374  ----------------------------------------------------------------------*/
  375 int
  376 key_inittables(void)
  377 {
  378   int i;
  379 
  380   KMALLOC(keyregtable, struct key_registry *, sizeof(struct key_registry));
  381   if (!keyregtable)
  382     return -1;
  383   bzero((char *)keyregtable, sizeof(struct key_registry));
  384   KMALLOC(key_acquirelist, struct key_acquirelist *, 
  385            sizeof(struct key_acquirelist));
  386   if (!key_acquirelist)
  387     return -1;
  388   bzero((char *)key_acquirelist, sizeof(struct key_acquirelist));
  389   for (i = 0; i < KEYTBLSIZE; i++) 
  390     bzero((char *)&keytable[i], sizeof(struct key_tblnode));
  391   for (i = 0; i < KEYALLOCTBLSIZE; i++)
  392     bzero((char *)&keyalloctbl[i], sizeof(struct key_allocnode));
  393   for (i = 0; i < SO2SPITBLSIZE; i++)
  394     bzero((char *)&so2spitbl[i], sizeof(struct key_so2spinode));
  395 
  396   return 0;
  397 }
  398 
  399 static int
  400 key_freetables(void)
  401 {
  402   KFREE(keyregtable);
  403   keyregtable = NULL;
  404   KFREE(key_acquirelist);
  405   key_acquirelist = NULL;
  406   return 0;
  407 }
  408 
  409 /*----------------------------------------------------------------------
  410  * key_gethashval():
  411  *      Determine keytable hash value.
  412  ----------------------------------------------------------------------*/
  413 static int
  414 key_gethashval(char *buf, int len, int tblsize)
  415 {
  416   int i, j = 0;
  417 
  418   /* 
  419    * Todo: Use word size xor and check for alignment
  420    *       and zero pad if necessary.  Need to also pick 
  421    *       a good hash function and table size.
  422    */
  423   if (len <= 0) {
  424     DPRINTF(IDL_ERROR,("key_gethashval got bogus len!\n"));
  425     return(-1);
  426   }
  427   for(i = 0; i < len; i++) {
  428     j ^=  (u_int8_t)(*(buf + i));
  429   }
  430   return (j % tblsize);
  431 }
  432 
  433 
  434 /*----------------------------------------------------------------------
  435  * key_createkey():
  436  *      Create hash key for hash function
  437  *      key is: type+src+dst if keytype = 1
  438  *              type+src+dst+spi if keytype = 0
  439  *      Uses only the address portion of the src and dst sockaddrs to 
  440  *      form key.  Currently handles only AF_INET and AF_INET6 sockaddrs
  441  ----------------------------------------------------------------------*/
  442 static int
  443 key_createkey(char *buf, u_int type, SOCKADDR *src, SOCKADDR *dst,
  444               u_int32_t spi, u_int keytype)
  445 {
  446   char *cp, *p;
  447 
  448   DPRINTF(IDL_FINISHED,("Entering key_createkey\n"));
  449 
  450   if (!buf || !src || !dst)
  451     return(-1);
  452 
  453   cp = buf;
  454   bcopy((char *)&type, cp, sizeof(type));
  455   cp += sizeof(type);
  456 
  457 #ifdef INET6
  458   /*
  459    * Assume only IPv4 and IPv6 addresses.
  460    */
  461 #define ADDRPART(a) \
  462     ((a)->sa_family == AF_INET6) ? \
  463     (char *)&(((struct sockaddr_in6 *)(a))->sin6_addr) : \
  464     (char *)&(((struct sockaddr_in *)(a))->sin_addr)
  465 
  466 #define ADDRSIZE(a) \
  467     ((a)->sa_family == AF_INET6) ? sizeof(struct in_addr6) : \
  468     sizeof(struct in_addr)  
  469 #else /* INET6 */
  470 #define ADDRPART(a) (char *)&(((struct sockaddr_in *)(a))->sin_addr)
  471 #define ADDRSIZE(a) sizeof(struct in_addr)  
  472 #endif /* INET6 */
  473 
  474   DPRINTF(IDL_FINISHED,("src addr:\n"));
  475   DDO(IDL_FINISHED,dump_smart_sockaddr(src));
  476   DPRINTF(IDL_FINISHED,("dst addr:\n"));
  477   DDO(IDL_FINISHED,dump_smart_sockaddr(dst)); 
  478 
  479   p = ADDRPART(src);
  480   bcopy(p, cp, ADDRSIZE(src));
  481   cp += ADDRSIZE(src);
  482 
  483   p = ADDRPART(dst);
  484   bcopy(p, cp, ADDRSIZE(dst));
  485   cp += ADDRSIZE(dst);
  486 
  487 #undef ADDRPART
  488 #undef ADDRSIZE
  489 
  490   if (keytype == 0) {
  491     bcopy((char *)&spi, cp, sizeof(spi));
  492     cp += sizeof(spi);
  493   }
  494 
  495   DPRINTF(IDL_FINISHED,("hash key:\n"));
  496   DDO(IDL_FINISHED, dump_buf(buf, cp - buf));
  497   return(cp - buf);
  498 }
  499 
  500 
  501 /*----------------------------------------------------------------------
  502  * key_sosearch():
  503  *      Search the so2spi table for the security association allocated to 
  504  *      the socket.  Returns pointer to a struct key_so2spinode which can
  505  *      be used to locate the security association entry in the keytable.
  506  ----------------------------------------------------------------------*/
  507 static struct key_so2spinode *
  508 key_sosearch(u_int type, SOCKADDR *src, SOCKADDR *dst, struct socket *so)
  509 {
  510   struct key_so2spinode *np = 0;
  511 
  512   if (!(src && dst)) {
  513     DPRINTF(IDL_ERROR,("key_sosearch: got null src or dst pointer!\n"));
  514     return(NULL);
  515   }
  516 
  517   for (np = so2spitbl[((u_int32_t)so) % SO2SPITBLSIZE].next; np; np = np->next) {
  518     if ((so == np->socket) && (type == np->keynode->secassoc->type)
  519         && addrpart_equal(src, np->keynode->secassoc->src)
  520         && addrpart_equal(dst, np->keynode->secassoc->dst))
  521       return(np);
  522   }  
  523   return(NULL);
  524 }
  525 
  526 
  527 /*----------------------------------------------------------------------
  528  * key_sodelete():
  529  *      Delete entries from the so2spi table.
  530  *        flag = 1  purge all entries
  531  *        flag = 0  delete entries with socket pointer matching socket  
  532  ----------------------------------------------------------------------*/
  533 static void
  534 key_sodelete(struct socket *socket, int flag)
  535 {
  536   struct key_so2spinode *prevnp, *np;
  537   CRITICAL_DCL
  538 
  539   CRITICAL_START;
  540 
  541   DPRINTF(IDL_EVENT,("Entering keysodelete w/so=0x%x flag=%d\n",
  542                      (unsigned int)socket,flag));
  543 
  544   if (flag) {
  545     int i;
  546 
  547     for (i = 0; i < SO2SPITBLSIZE; i++)
  548       for(np = so2spitbl[i].next; np; np = np->next) {
  549         KFREE(np);
  550       }
  551     CRITICAL_END;
  552     return;
  553   }
  554 
  555   prevnp = &so2spitbl[((u_int32_t)socket) % SO2SPITBLSIZE];
  556   for(np = prevnp->next; np; np = np->next) {
  557     if (np->socket == socket) {
  558       struct socketlist *socklp, *prevsocklp;
  559 
  560       (np->keynode->alloc_count)--;
  561 
  562       /* 
  563        * If this socket maps to a unique secassoc,
  564        * we go ahead and delete the secassoc, since it
  565        * can no longer be allocated or used by any other 
  566        * socket.
  567        */
  568       if (np->keynode->secassoc->state & K_UNIQUE) {
  569         if (key_delete(np->keynode->secassoc) != 0)
  570           panic("key_sodelete");
  571         np = prevnp;
  572         continue;
  573       }
  574 
  575       /*
  576        * We traverse the socketlist and remove the entry
  577        * for this socket
  578        */
  579       DPRINTF(IDL_FINISHED,("keysodelete: deleting from socklist..."));
  580       prevsocklp = np->keynode->solist;
  581       for (socklp = prevsocklp->next; socklp; socklp = socklp->next) {
  582         if (socklp->socket == socket) {
  583           prevsocklp->next = socklp->next;
  584           KFREE(socklp);
  585           break;
  586         }
  587         prevsocklp = socklp;
  588       }
  589       DPRINTF(IDL_FINISHED,("done\n"));
  590       prevnp->next = np->next;
  591       KFREE(np);
  592       np = prevnp;
  593     }
  594     prevnp = np;  
  595   }
  596   CRITICAL_END;
  597 }
  598 
  599 
  600 /*----------------------------------------------------------------------
  601  * key_deleteacquire():
  602  *      Delete an entry from the key_acquirelist
  603  ----------------------------------------------------------------------*/
  604 static void
  605 key_deleteacquire(u_int type, SOCKADDR *target)
  606 {
  607   struct key_acquirelist *ap, *prev;
  608 
  609   prev = key_acquirelist;
  610   for(ap = key_acquirelist->next; ap; ap = ap->next) {
  611     if (addrpart_equal(target, (SOCKADDR *)&(ap->target)) &&
  612         (type == ap->type)) {
  613       DPRINTF(IDL_EVENT,("Deleting entry from acquire list!\n"));
  614       prev->next = ap->next;
  615       KFREE(ap);
  616       ap = prev;
  617     }
  618     prev = ap;
  619   }
  620 }
  621 
  622 
  623 /*----------------------------------------------------------------------
  624  * key_search():
  625  *      Search the key table for an entry with same type, src addr, dest
  626  *      addr, and spi.  Returns a pointer to struct key_tblnode if found
  627  *      else returns null.
  628  ----------------------------------------------------------------------*/
  629 static struct key_tblnode *
  630 key_search(u_int type, SOCKADDR *src, SOCKADDR *dst, u_int32_t spi, 
  631            int indx, struct key_tblnode **prevkeynode)
  632 {
  633   struct key_tblnode *keynode, *prevnode;
  634 
  635   if (indx > KEYTBLSIZE || indx < 0)
  636     return (NULL);
  637   if (!(&keytable[indx]))
  638     return (NULL);
  639 
  640 #define sec_type keynode->secassoc->type
  641 #define sec_spi keynode->secassoc->spi
  642 #define sec_src keynode->secassoc->src
  643 #define sec_dst keynode->secassoc->dst
  644 
  645   prevnode = &keytable[indx];
  646   for (keynode = keytable[indx].next; keynode; keynode = keynode->next) {
  647     if ((type == sec_type) && (spi == sec_spi) && 
  648         addrpart_equal(src, sec_src)
  649         && addrpart_equal(dst, sec_dst))
  650       break;
  651     prevnode = keynode;
  652   }
  653   *prevkeynode = prevnode;
  654   return(keynode);
  655 }
  656 
  657 
  658 /*----------------------------------------------------------------------
  659  * key_addnode():
  660  *      Insert a key_tblnode entry into the key table.  Returns a pointer 
  661  *      to the newly created key_tblnode.
  662  ----------------------------------------------------------------------*/
  663 static struct key_tblnode *
  664 key_addnode(int indx, struct key_secassoc *secassoc)
  665 {
  666   struct key_tblnode *keynode;
  667 
  668   DPRINTF(IDL_FINISHED,("Entering key_addnode w/indx=%d secassoc=0x%x\n",
  669                         indx, (unsigned int)secassoc));
  670 
  671   if (!(&keytable[indx]))
  672     return(NULL);
  673   if (!secassoc) {
  674     panic("key_addnode: Someone passed in a null secassoc!\n");
  675   }
  676 
  677   KMALLOC(keynode, struct key_tblnode *, sizeof(struct key_tblnode));
  678   if (keynode == 0)
  679     return(NULL);
  680   bzero((char *)keynode, sizeof(struct key_tblnode));
  681 
  682   KMALLOC(keynode->solist, struct socketlist *, sizeof(struct socketlist));
  683   if (keynode->solist == 0) {
  684     KFREE(keynode);
  685     return(NULL);
  686   }
  687   bzero((char *)(keynode->solist), sizeof(struct socketlist));
  688 
  689   keynode->secassoc = secassoc;
  690   keynode->solist->next = NULL;
  691   keynode->next = keytable[indx].next;
  692   keytable[indx].next = keynode;
  693   return(keynode);
  694 }
  695 
  696 
  697 /*----------------------------------------------------------------------
  698  * key_add():
  699  *      Add a new security association to the key table.  Caller is
  700  *      responsible for allocating memory for the key_secassoc as  
  701  *      well as the buffer space for the key,  iv.  Assumes the security 
  702  *      association passed in is well-formed.
  703  ----------------------------------------------------------------------*/
  704 int
  705 key_add(struct key_secassoc *secassoc)
  706 {
  707   char buf[MAXHASHKEYLEN];
  708   int len, indx;
  709   int inbound = 0;
  710   int outbound = 0;
  711   struct key_tblnode *keynode, *prevkeynode;
  712   struct key_allocnode *np = NULL;
  713   CRITICAL_DCL
  714 
  715   DPRINTF(IDL_FINISHED, ("Entering key_add w/secassoc=0x%x\n",
  716                          (unsigned int)secassoc));
  717 
  718   if (!secassoc) {
  719     panic("key_add: who the hell is passing me a null pointer");
  720   }
  721 
  722   /*
  723    * Should we allow a null key to be inserted into the table ? 
  724    * or can we use null key to indicate some policy action...
  725    */
  726 
  727 #if 0
  728   /*
  729    *  For esp using des-cbc or tripple-des we call 
  730    * des_set_odd_parity.
  731    */
  732   if (secassoc->key && (secassoc->type == KEY_TYPE_ESP) && 
  733       ((secassoc->algorithm == IPSEC_ALGTYPE_ESP_DES_CBC) ||
  734        (secassoc->algorithm == IPSEC_ALGTYPE_ESP_3DES)))
  735     des_set_odd_parity(secassoc->key);
  736 #endif /* 0 */
  737 
  738   /*
  739    *  Check if secassoc with same spi exists before adding
  740    */
  741   bzero((char *)&buf, sizeof(buf));
  742   len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
  743                       secassoc->dst, secassoc->spi, 0);
  744   indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
  745   DPRINTF(IDL_FINISHED,("keyadd: keytbl hash position=%d\n", indx));
  746   keynode = key_search(secassoc->type, secassoc->src, secassoc->dst,
  747                        secassoc->spi, indx, &prevkeynode);
  748   if (keynode) {
  749     DPRINTF(IDL_EVENT,("keyadd: secassoc already exists!\n"));
  750     return(-2);
  751   }
  752 
  753   inbound = my_addr(secassoc->dst);
  754   outbound = my_addr(secassoc->src);
  755   DPRINTF(IDL_FINISHED,("inbound=%d outbound=%d\n", inbound, outbound));
  756 
  757   /*
  758    * We allocate mem for an allocation entry if needed.
  759    * This is done here instead of in the allocaton code 
  760    * segment so that we can easily recover/cleanup from a 
  761    * memory allocation error.
  762    */
  763   if (outbound || (!inbound && !outbound)) {
  764     KMALLOC(np, struct key_allocnode *, sizeof(struct key_allocnode));
  765     if (np == 0) {
  766       DPRINTF(IDL_ERROR,("keyadd: can't allocate allocnode!\n"));
  767       return(-1);
  768     }
  769   }
  770 
  771   CRITICAL_START;
  772 
  773   if ((keynode = key_addnode(indx, secassoc)) == NULL) {
  774     DPRINTF(IDL_ERROR,("keyadd: key_addnode failed!\n"));
  775     if (np)
  776       KFREE(np);
  777     CRITICAL_END;
  778     return(-1);
  779   }
  780   DPRINTF(IDL_GROSS_EVENT,("Added new keynode:\n"));
  781   DDO(IDL_FINISHED, dump_keytblnode(keynode));
  782   DDO(IDL_FINISHED, dump_secassoc(keynode->secassoc));
  783  
  784   /*
  785    *  We add an entry to the allocation table for
  786    *  this secassoc if the interfaces are up, 
  787    *  the secassoc is outbound.  In the case 
  788    *  where the interfaces are not up, we go ahead
  789    * ,  do it anyways.  This wastes an allocation
  790    *  entry if the secassoc later turned out to be
  791    *  inbound when the interfaces are ifconfig up.
  792    */
  793   if (outbound || (!inbound && !outbound)) {
  794     len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
  795                         secassoc->dst, 0, 1);
  796     indx = key_gethashval((char *)&buf, len, KEYALLOCTBLSIZE);
  797     DPRINTF(IDL_FINISHED,("keyadd: keyalloc hash position=%d\n", indx));
  798     np->keynode = keynode;
  799     np->next = keyalloctbl[indx].next;
  800     keyalloctbl[indx].next = np;
  801   }
  802   if (inbound)
  803     secassoc->state |= K_INBOUND;
  804   if (outbound)
  805     secassoc->state |= K_OUTBOUND;
  806 
  807   key_deleteacquire(secassoc->type, secassoc->dst);
  808 
  809   CRITICAL_END;
  810   return 0;
  811 }
  812 
  813 
  814 /*----------------------------------------------------------------------
  815  * key_get():
  816  *      Get a security association from the key table.
  817  ----------------------------------------------------------------------*/
  818 int
  819 key_get(u_int type, SOCKADDR *src, SOCKADDR *dst, u_int32_t spi, 
  820         struct key_secassoc **secassoc)
  821 {
  822   char buf[MAXHASHKEYLEN];
  823   struct key_tblnode *keynode, *prevkeynode;
  824   int len, indx;
  825 
  826   bzero(&buf, sizeof(buf));
  827   *secassoc = NULL;
  828   len = key_createkey((char *)&buf, type, src, dst, spi, 0);
  829   indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
  830   DPRINTF(IDL_FINISHED,("keyget: indx=%d\n",indx));
  831   keynode = key_search(type, src, dst, spi, indx, &prevkeynode);
  832   if (keynode) {
  833     DPRINTF(IDL_GROSS_EVENT,("keyget: found it! keynode=0x%x",
  834                              (unsigned int)keynode));
  835     *secassoc = keynode->secassoc;
  836     return(0);
  837   } else
  838     return(-1);  /* Not found */
  839 }
  840 
  841 
  842 /*----------------------------------------------------------------------
  843  * key_dump():
  844  *      Dump all valid entries in the keytable to a pf_key socket.  Each
  845  *      security associaiton is sent one at a time in a pf_key message.  A
  846  *      message with seqno = 0 signifies the end of the dump transaction.
  847  ----------------------------------------------------------------------*/
  848 int
  849 key_dump(struct socket *so)
  850 {
  851   int len, i;
  852   int seq = 1;
  853   struct key_msgdata keyinfo;
  854   struct key_msghdr *km;
  855   struct key_tblnode *keynode;
  856 
  857   /*
  858    * Routine to dump the key table to a routing socket
  859    * Use for debugging only!
  860    */
  861 
  862   KMALLOC(km, struct key_msghdr *, sizeof(struct key_msghdr) +
  863           3 * MAX_SOCKADDR_SZ + MAX_KEY_SZ + MAX_IV_SZ);
  864   if (!km)
  865     return(ENOBUFS);
  866 
  867   DPRINTF(IDL_FINISHED,("Entering key_dump()"));
  868   /* 
  869    * We need to speed this up later.  Fortunately, key_dump 
  870    * messages are not sent often.
  871    */
  872   for (i = 0; i < KEYTBLSIZE; i++) {
  873     for (keynode = keytable[i].next; keynode; keynode = keynode->next) {
  874       /*
  875        * We exclude dead/larval/zombie security associations for now
  876        * but it may be useful to also send these up for debugging purposes
  877        */
  878       if (keynode->secassoc->state & (K_DEAD | K_LARVAL | K_ZOMBIE))
  879         continue;
  880 
  881       len = (sizeof(struct key_msghdr) +
  882              ROUNDUP(keynode->secassoc->src->sa_len) + 
  883              ROUNDUP(keynode->secassoc->dst->sa_len) +
  884              ROUNDUP(keynode->secassoc->from->sa_len) +
  885              ROUNDUP(keynode->secassoc->keylen) + 
  886              ROUNDUP(keynode->secassoc->ivlen));
  887 
  888       if (key_secassoc2msghdr(keynode->secassoc, km, &keyinfo) != 0)
  889         panic("key_dump");
  890 
  891       km->key_msglen = len;
  892       km->key_msgvers = KEY_VERSION;
  893       km->key_msgtype = KEY_DUMP;
  894       km->key_pid = CURRENT_PID;
  895       km->key_seq = seq++;
  896       km->key_errno = 0;
  897 
  898       key_sendup(so, km);
  899     }
  900   }
  901   bzero((char *)km, sizeof(struct key_msghdr));
  902   km->key_msglen = sizeof(struct key_msghdr);
  903   km->key_msgvers = KEY_VERSION;
  904   km->key_msgtype = KEY_DUMP;
  905   km->key_pid = CURRENT_PID;
  906   km->key_seq = 0;
  907   km->key_errno = 0;
  908 
  909   key_sendup(so, km);
  910   KFREE(km);
  911   DPRINTF(IDL_FINISHED,("Leaving key_dump()\n"));  
  912   return(0);
  913 }
  914 
  915 /*----------------------------------------------------------------------
  916  * key_delete():
  917  *      Delete a security association from the key table.
  918  ----------------------------------------------------------------------*/
  919 int
  920 key_delete(struct key_secassoc *secassoc)
  921 {
  922   char buf[MAXHASHKEYLEN];
  923   int len, indx;
  924   struct key_tblnode *keynode = 0;
  925   struct key_tblnode *prevkeynode = 0;
  926   struct socketlist *socklp, *deadsocklp;
  927   struct key_so2spinode *np, *prevnp;
  928   struct key_allocnode *ap, *prevap;
  929   CRITICAL_DCL
  930 
  931   DPRINTF(IDL_FINISHED,("Entering key_delete w/secassoc=0x%x\n",
  932                         (unsigned int)secassoc));
  933 
  934   bzero((char *)&buf, sizeof(buf));
  935   len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
  936                       secassoc->dst, secassoc->spi, 0);
  937   indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
  938   DPRINTF(IDL_FINISHED,("keydelete: keytbl hash position=%d\n", indx));
  939   keynode = key_search(secassoc->type, secassoc->src, secassoc->dst, 
  940                        secassoc->spi, indx, &prevkeynode); 
  941  
  942   if (keynode) {
  943     CRITICAL_START;
  944     DPRINTF(IDL_GROSS_EVENT,("keydelete: found keynode to delete\n"));
  945     keynode->secassoc->state |= K_DEAD;
  946 
  947     if (keynode->ref_count > 0) {
  948       DPRINTF(IDL_EVENT,("keydelete: secassoc still held, marking for deletion only!\n"));
  949       CRITICAL_END;
  950       return(0); 
  951     }
  952 
  953     prevkeynode->next = keynode->next;
  954     
  955     /*
  956      *  Walk the socketlist,  delete the
  957      *  entries mapping sockets to this secassoc
  958      *  from the so2spi table.
  959      */
  960     DPRINTF(IDL_FINISHED,("keydelete: deleting socklist..."));
  961     for(socklp = keynode->solist->next; socklp; ) {
  962       prevnp = &so2spitbl[((u_int32_t)(socklp->socket)) % SO2SPITBLSIZE];
  963       for(np = prevnp->next; np; np = np->next) {
  964         if ((np->socket == socklp->socket) && (np->keynode == keynode)) {
  965           prevnp->next = np->next;
  966           KFREE(np);
  967           break; 
  968         }
  969         prevnp = np;  
  970       }
  971       deadsocklp = socklp;
  972       socklp = socklp->next;
  973       KFREE(deadsocklp);
  974     }
  975     DPRINTF(IDL_FINISHED,("done\n"));
  976     /*
  977      * If an allocation entry exist for this
  978      * secassoc, delete it.
  979      */
  980     bzero((char *)&buf, sizeof(buf));
  981     len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
  982                         secassoc->dst, 0, 1);
  983     indx = key_gethashval((char *)&buf, len, KEYALLOCTBLSIZE);
  984     DPRINTF(IDL_FINISHED,("keydelete: alloctbl hash position=%d\n", indx));
  985     prevap = &keyalloctbl[indx];
  986     for (ap = prevap->next; ap; ap = ap->next) {
  987       if (ap->keynode == keynode) {
  988         prevap->next = ap->next;
  989         KFREE(ap);
  990         break; 
  991       }
  992       prevap = ap;
  993     }    
  994 
  995     if (keynode->secassoc->iv)
  996       KFREE(keynode->secassoc->iv);
  997     if (keynode->secassoc->key)
  998       KFREE(keynode->secassoc->key);
  999     KFREE(keynode->secassoc);
 1000     if (keynode->solist)
 1001       KFREE(keynode->solist);
 1002     KFREE(keynode);
 1003     CRITICAL_END;
 1004     return(0);
 1005   }
 1006   return(-1);
 1007 }
 1008 
 1009 
 1010 /*----------------------------------------------------------------------
 1011  * key_flush():
 1012  *      Delete all entries from the key table.
 1013  ----------------------------------------------------------------------*/
 1014 void
 1015 key_flush(void)
 1016 {
 1017   struct key_tblnode *keynode;
 1018   int i;
 1019 
 1020   /* 
 1021    * This is slow, but simple.
 1022    */
 1023   DPRINTF(IDL_FINISHED,("Flushing key table..."));
 1024   for (i = 0; i < KEYTBLSIZE; i++) {
 1025     while ((keynode = keytable[i].next))
 1026       if (key_delete(keynode->secassoc) != 0)
 1027         panic("key_flush");
 1028   }
 1029   DPRINTF(IDL_FINISHED,("done\n"));
 1030 }
 1031 
 1032 
 1033 /*----------------------------------------------------------------------
 1034  * key_getspi():
 1035  *      Get a unique spi value for a key management daemon/program.  The 
 1036  *      spi value, once assigned, cannot be assigned again (as long as the 
 1037  *      entry with that same spi value remains in the table).
 1038  ----------------------------------------------------------------------*/
 1039 int
 1040 key_getspi(u_int type, SOCKADDR *src, SOCKADDR *dst, u_int32_t lowval, 
 1041            u_int32_t highval, u_int32_t *spi)
 1042 {
 1043   struct key_secassoc *secassoc;
 1044   struct key_tblnode *keynode, *prevkeynode;
 1045   int count, done, len, indx;
 1046   int maxcount = 1000;
 1047   u_int32_t val;
 1048   char buf[MAXHASHKEYLEN];
 1049   CRITICAL_DCL
 1050   
 1051   DPRINTF(IDL_EVENT,("Entering getspi w/type=%d,low=%u,high=%u\n",
 1052                            type, lowval, highval));
 1053   if (!(src && dst))
 1054     return(EINVAL);
 1055 
 1056   if ((lowval == 0) || (highval == 0))
 1057     return(EINVAL);
 1058 
 1059   if (lowval > highval) {
 1060     u_int32_t temp;
 1061     temp = lowval;
 1062     lowval = highval;
 1063     highval = lowval;
 1064   }
 1065 
 1066   done = count = 0;
 1067   do {
 1068     count++;
 1069     /* 
 1070      *  This may not be "random enough".
 1071      */
 1072     val = lowval + (random() % (highval - lowval + 1));
 1073 
 1074     if (lowval == highval)
 1075       count = maxcount;
 1076     DPRINTF(IDL_FINISHED,("%u ",val));
 1077     if (val) {
 1078       DPRINTF(IDL_FINISHED,("\n"));
 1079       bzero(&buf, sizeof(buf));
 1080       len = key_createkey((char *)&buf, type, src, dst, val, 0);
 1081       indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
 1082       if (!key_search(type, src, dst, val, indx, &prevkeynode)) {
 1083         CRITICAL_START;
 1084         KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc));
 1085         if (secassoc == 0) {
 1086           DPRINTF(IDL_ERROR,("key_getspi: can't allocate memory\n"));
 1087           CRITICAL_END;
 1088           return(ENOBUFS);
 1089         }
 1090         bzero((char *)secassoc, sizeof(*secassoc));
 1091 
 1092         DPRINTF(IDL_FINISHED,("getspi: indx=%d\n",indx));
 1093         secassoc->len = sizeof(struct key_secassoc);
 1094         secassoc->type = type;
 1095         secassoc->spi = val;
 1096         secassoc->state |= K_LARVAL;
 1097         if (my_addr(secassoc->dst))
 1098           secassoc->state |= K_INBOUND;
 1099         if (my_addr(secassoc->src))
 1100           secassoc->state |= K_OUTBOUND;
 1101 
 1102         bcopy((char *)src, (char *)secassoc->src, src->sa_len);
 1103         bcopy((char *)dst, (char *)secassoc->dst, dst->sa_len);
 1104 
 1105         /* We fill this in with a plausable value now to insure
 1106            that other routines don't break. These will get
 1107            overwritten later with the correct values. */
 1108 #ifdef INET6
 1109         secassoc->from->sa_family = AF_INET6;
 1110         secassoc->from->sa_len = sizeof(struct sockaddr_in6);
 1111 #else /* INET6 */
 1112         secassoc->from->sa_family = AF_INET;
 1113         secassoc->from->sa_len = sizeof(struct sockaddr_in);
 1114 #endif /* INET6 */
 1115 
 1116         /* 
 1117          * We need to add code to age these larval key table
 1118          * entries so they don't linger forever waiting for
 1119          * a KEY_UPDATE message that may not come for various
 1120          * reasons.  This is another task that key_reaper can
 1121          * do once we have it coded.
 1122          */
 1123         secassoc->lifetime1 += TIME_SECONDS + maxlarvallifetime;
 1124 
 1125         if (!(keynode = key_addnode(indx, secassoc))) {
 1126           DPRINTF(IDL_ERROR,("key_getspi: can't add node\n"));
 1127           CRITICAL_END;
 1128           return(ENOBUFS);
 1129         } 
 1130         DPRINTF(IDL_FINISHED,("key_getspi: added node 0x%x\n",
 1131                               (unsigned int)keynode));
 1132         done++;
 1133         CRITICAL_END;
 1134       }
 1135     }
 1136   } while ((count < maxcount) && !done);
 1137   DPRINTF(IDL_EVENT,("getspi returns w/spi=%u,count=%d\n",val,count));
 1138   if (done) {
 1139     *spi = val;
 1140     return(0);
 1141   } else {
 1142     *spi = 0;
 1143     return(EADDRNOTAVAIL);
 1144   }
 1145 }
 1146 
 1147 
 1148 /*----------------------------------------------------------------------
 1149  * key_update():
 1150  *      Update a keytable entry that has an spi value assigned but is 
 1151  *      incomplete (e.g. no key/iv).
 1152  ----------------------------------------------------------------------*/
 1153 int
 1154 key_update(struct key_secassoc *secassoc)
 1155 {
 1156   struct key_tblnode *keynode, *prevkeynode;
 1157   struct key_allocnode *np = 0;
 1158   u_int8_t newstate;
 1159   int len, indx, inbound, outbound;
 1160   char buf[MAXHASHKEYLEN];
 1161   CRITICAL_DCL
 1162 
 1163   bzero(&buf, sizeof(buf));
 1164   len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
 1165                       secassoc->dst, secassoc->spi, 0);
 1166   indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
 1167   if(!(keynode = key_search(secassoc->type, secassoc->src, secassoc->dst, 
 1168                             secassoc->spi, indx, &prevkeynode))) {  
 1169     return(ESRCH);
 1170   }
 1171   if (keynode->secassoc->state & K_DEAD)
 1172     return(ESRCH);
 1173 
 1174   /* Should we also restrict updating of only LARVAL entries ? */
 1175 
 1176   CRITICAL_START;
 1177 
 1178   inbound = my_addr(secassoc->dst);
 1179   outbound = my_addr(secassoc->src);
 1180 
 1181   newstate = keynode->secassoc->state;
 1182   newstate &= ~K_LARVAL;
 1183 
 1184   if (inbound)
 1185     newstate |= K_INBOUND;
 1186   if (outbound)
 1187     newstate |= K_OUTBOUND;
 1188 
 1189   if (outbound || (!inbound && !outbound)) {
 1190     KMALLOC(np, struct key_allocnode *, sizeof(struct key_allocnode));
 1191     if (np == 0) {
 1192       DPRINTF(IDL_ERROR,("keyupdate: can't allocate allocnode!\n"));
 1193       CRITICAL_END;
 1194       return(ENOBUFS);
 1195     }
 1196   }
 1197 
 1198   /*
 1199    *  Free the old key,  iv if they're there.
 1200    */
 1201   if (keynode->secassoc->key)
 1202     KFREE(keynode->secassoc->key);
 1203   if (keynode->secassoc->iv)
 1204     KFREE(keynode->secassoc->iv);
 1205 
 1206   /*
 1207    *  We now copy the secassoc over. We don't need to copy
 1208    *  the key,  iv into new buffers since the calling routine
 1209    *  does that already.  
 1210    */
 1211 
 1212   *(keynode->secassoc) = *secassoc;
 1213   keynode->secassoc->state = newstate;
 1214 
 1215   /*
 1216    * Should we allow a null key to be inserted into the table ? 
 1217    * or can we use null key to indicate some policy action...
 1218    */
 1219 
 1220 #if 0  
 1221   if (keynode->secassoc->key &&
 1222        (keynode->secassoc->type == KEY_TYPE_ESP) &&
 1223        ((keynode->secassoc->algorithm == IPSEC_ALGTYPE_ESP_DES_CBC) ||
 1224         (keynode->secassoc->algorithm == IPSEC_ALGTYPE_ESP_3DES)))
 1225       des_set_odd_parity(keynode->secassoc->key);
 1226 #endif /* 0 */
 1227 
 1228   /*
 1229    *  We now add an entry to the allocation table for this 
 1230    *  updated key table entry.
 1231    */
 1232   if (outbound || (!inbound && !outbound)) {
 1233     len = key_createkey((char *)&buf, secassoc->type, secassoc->src,
 1234                         secassoc->dst, 0, 1);
 1235     indx = key_gethashval((char *)&buf, len, KEYALLOCTBLSIZE);
 1236     DPRINTF(IDL_FINISHED,("keyupdate: keyalloc hash position=%d\n", indx));
 1237     np->keynode = keynode;
 1238     np->next = keyalloctbl[indx].next;
 1239     keyalloctbl[indx].next = np;
 1240   }
 1241 
 1242   key_deleteacquire(secassoc->type, (SOCKADDR *)&(secassoc->dst));
 1243 
 1244   CRITICAL_END;
 1245   return(0);
 1246 }
 1247 
 1248 /*----------------------------------------------------------------------
 1249  * key_register():
 1250  *      Register a socket as one capable of acquiring security associations
 1251  *      for the kernel.
 1252  ----------------------------------------------------------------------*/
 1253 int
 1254 key_register(struct socket *socket, u_int type)
 1255 {
 1256   struct key_registry *p, *new;
 1257   CRITICAL_DCL
 1258 
 1259   CRITICAL_START;
 1260 
 1261   DPRINTF(IDL_EVENT,("Entering key_register w/so=0x%x,type=%d\n",
 1262                      (unsigned int)socket,type));
 1263 
 1264   if (!(keyregtable && socket))
 1265     panic("key_register");
 1266   
 1267   /*
 1268    * Make sure entry is not already in table
 1269    */
 1270   for(p = keyregtable->next; p; p = p->next) {
 1271     if ((p->type == type) && (p->socket == socket)) {
 1272       CRITICAL_END;
 1273       return(EEXIST);
 1274     }
 1275   }
 1276 
 1277   KMALLOC(new, struct key_registry *, sizeof(struct key_registry));  
 1278   if (new == 0) {
 1279     CRITICAL_END;
 1280     return(ENOBUFS);
 1281   }
 1282   new->type = type;
 1283   new->socket = socket;
 1284   new->next = keyregtable->next;
 1285   keyregtable->next = new;
 1286   CRITICAL_END;
 1287   return(0);
 1288 }
 1289 
 1290 /*----------------------------------------------------------------------
 1291  * key_unregister():
 1292  *      Delete entries from the registry list.
 1293  *         allflag = 1 : delete all entries with matching socket
 1294  *         allflag = 0 : delete only the entry matching socket,  type
 1295  ----------------------------------------------------------------------*/
 1296 void
 1297 key_unregister(struct socket *socket, u_int type, int allflag)
 1298 {
 1299   struct key_registry *p, *prev;
 1300   CRITICAL_DCL
 1301 
 1302   CRITICAL_START;
 1303 
 1304   DPRINTF(IDL_EVENT,("Entering key_unregister w/so=0x%x,type=%d,flag=%d\n",
 1305                      (unsigned int)socket, type, allflag));
 1306 
 1307   if (!(keyregtable && socket))
 1308     panic("key_register");
 1309   prev = keyregtable;
 1310   for(p = keyregtable->next; p; p = p->next) {
 1311     if ((allflag && (p->socket == socket)) ||
 1312         ((p->type == type) && (p->socket == socket))) {
 1313       prev->next = p->next;
 1314       KFREE(p);
 1315       p = prev;
 1316     }
 1317     prev = p;
 1318   }
 1319   CRITICAL_END;
 1320 }
 1321 
 1322 
 1323 /*----------------------------------------------------------------------
 1324  * key_acquire():
 1325  *      Send a key_acquire message to all registered key mgnt daemons 
 1326  *      capable of acquire security association of type type.
 1327  *
 1328  *      Return: 0 if succesfully called key mgnt. daemon(s)
 1329  *              -1 if not successfull.
 1330  ----------------------------------------------------------------------*/
 1331 int
 1332 key_acquire(u_int type, SOCKADDR *src, SOCKADDR *dst)
 1333 {
 1334   struct key_registry *p;
 1335   struct key_acquirelist *ap, *prevap;
 1336   int success = 0, created = 0;
 1337   u_int etype;
 1338   struct key_msghdr *km = NULL;
 1339   int len;
 1340 
 1341   DPRINTF(IDL_EVENT,("Entering key_acquire()\n"));
 1342 
 1343   if (!keyregtable || !src || !dst)
 1344     return (-1);
 1345 
 1346   /*
 1347    * We first check the acquirelist to see if a key_acquire
 1348    * message has been sent for this destination.
 1349    */
 1350   etype = type;
 1351   prevap = key_acquirelist;
 1352   for(ap = key_acquirelist->next; ap; ap = ap->next) {
 1353     if (addrpart_equal(dst, ap->target) &&
 1354         (etype == ap->type)) {
 1355       DPRINTF(IDL_EVENT,("acquire message previously sent!\n"));
 1356       if (ap->expiretime < TIME_SECONDS) {
 1357         DPRINTF(IDL_EVENT,("acquire message has expired!\n"));
 1358         ap->count = 0;
 1359         break;
 1360       }
 1361       if (ap->count < maxkeyacquire) {
 1362         DPRINTF(IDL_EVENT,("max acquire messages not yet exceeded!\n"));
 1363         break;
 1364       }
 1365       return(0);
 1366     } else if (ap->expiretime < TIME_SECONDS) {
 1367       /*
 1368        *  Since we're already looking at the list, we may as
 1369        *  well delete expired entries as we scan through the list.
 1370        *  This should really be done by a function like key_reaper()
 1371        *  but until we code key_reaper(), this is a quick,  dirty
 1372        *  hack.
 1373        */
 1374       DPRINTF(IDL_EVENT,("found an expired entry...deleting it!\n"));
 1375       prevap->next = ap->next;
 1376       KFREE(ap);
 1377       ap = prevap;
 1378     }
 1379     prevap = ap;
 1380   }
 1381 
 1382   /*
 1383    * Scan registry,  send KEY_ACQUIRE message to 
 1384    * appropriate key management daemons.
 1385    */  
 1386   for(p = keyregtable->next; p; p = p->next) {
 1387     if (p->type != type) 
 1388       continue;
 1389 
 1390     if (!created) {      
 1391       len = sizeof(struct key_msghdr) + ROUNDUP(src->sa_len) + 
 1392         ROUNDUP(dst->sa_len);
 1393       KMALLOC(km, struct key_msghdr *, len);
 1394       if (!km) {
 1395         DPRINTF(IDL_ERROR,("key_acquire: no memory\n"));
 1396         return(-1);
 1397       }
 1398       DPRINTF(IDL_FINISHED,("key_acquire/created: 1\n"));
 1399       bzero((char *)km, len);
 1400       km->key_msglen = len;
 1401       km->key_msgvers = KEY_VERSION;
 1402       km->key_msgtype = KEY_ACQUIRE;
 1403       km->type = type;
 1404       DPRINTF(IDL_FINISHED,("key_acquire/created: 2\n"));
 1405       /*
 1406        * This is inefficient,  slow.
 1407        */
 1408 
 1409       /*
 1410        * We zero out sin_zero here for AF_INET addresses because
 1411        * ip_output() currently does not do it for performance reasons.
 1412        */
 1413       if (src->sa_family == AF_INET)
 1414         bzero((char *)(((struct sockaddr_in *)src)->sin_zero),
 1415               sizeof(((struct sockaddr_in *)src)->sin_zero));
 1416       if (dst->sa_family == AF_INET)
 1417         bzero((char *)(((struct sockaddr_in *)dst)->sin_zero), 
 1418               sizeof(((struct sockaddr_in *)dst)->sin_zero));
 1419 
 1420       bcopy((char *)src, (char *)(km + 1), src->sa_len);
 1421       bcopy((char *)dst, (char *)((int)(km + 1) + ROUNDUP(src->sa_len)),
 1422             dst->sa_len);
 1423       DPRINTF(IDL_FINISHED,("key_acquire/created: 3\n"));
 1424       created++; 
 1425     }
 1426     if (key_sendup(p->socket, km))
 1427       success++;
 1428   }
 1429 
 1430   if (km)
 1431     KFREE(km);
 1432       
 1433   /*
 1434    *  Update the acquirelist 
 1435    */
 1436   if (success) {
 1437     if (!ap) {
 1438       DPRINTF(IDL_EVENT,("Adding new entry in acquirelist\n"));
 1439       KMALLOC(ap, struct key_acquirelist *, sizeof(struct key_acquirelist));
 1440       if (ap == 0)
 1441         return(success ? 0 : -1);
 1442       bzero((char *)ap, sizeof(struct key_acquirelist));
 1443       bcopy((char *)dst, (char *)ap->target, dst->sa_len);
 1444       ap->type = etype;
 1445       ap->next = key_acquirelist->next;
 1446       key_acquirelist->next = ap;
 1447     }
 1448     DPRINTF(IDL_GROSS_EVENT,("Updating acquire counter,  expiration time\n"));
 1449     ap->count++;
 1450     ap->expiretime = TIME_SECONDS + maxacquiretime;
 1451   }
 1452   DPRINTF(IDL_EVENT,("key_acquire: done! success=%d\n",success));
 1453   return(success ? 0 : -1);
 1454 }
 1455 
 1456 /*----------------------------------------------------------------------
 1457  * key_alloc():
 1458  *      Allocate a security association to a socket.  A socket requesting 
 1459  *      unique keying (per-socket keying) is assigned a security assocation
 1460  *      exclusively for its use.  Sockets not requiring unique keying are
 1461  *      assigned the first security association which may or may not be
 1462  *      used by another socket.
 1463  ----------------------------------------------------------------------*/
 1464 static int
 1465 key_alloc(u_int type, SOCKADDR *src, SOCKADDR *dst, struct socket *socket, 
 1466           u_int  unique_key, struct key_tblnode **keynodep)
 1467 {
 1468   struct key_tblnode *keynode;
 1469   char buf[MAXHASHKEYLEN];
 1470   struct key_allocnode *np, *prevnp;
 1471   struct key_so2spinode *newnp;
 1472   int len;
 1473   int indx;
 1474 
 1475   DPRINTF(IDL_FINISHED,("Entering key_alloc w/type=%u!\n",type));
 1476   if (!(src && dst)) {
 1477     DPRINTF(IDL_ERROR,("key_alloc: received null src or dst!\n"));
 1478     return(-1);
 1479   }
 1480 
 1481   /*
 1482    * Search key allocation table
 1483    */
 1484   bzero((char *)&buf, sizeof(buf));
 1485   len = key_createkey((char *)&buf, type, src, dst, 0, 1);
 1486   indx = key_gethashval((char *)&buf, len, KEYALLOCTBLSIZE);  
 1487 
 1488 #define np_type np->keynode->secassoc->type
 1489 #define np_state np->keynode->secassoc->state
 1490 #define np_src np->keynode->secassoc->src
 1491 #define np_dst np->keynode->secassoc->dst
 1492   
 1493   prevnp = &keyalloctbl[indx];
 1494   for (np = keyalloctbl[indx].next; np; np = np->next) {
 1495     if ((type == np_type) && addrpart_equal(src, np_src) &&
 1496         addrpart_equal(dst, np_dst) &&
 1497         !(np_state & (K_LARVAL | K_DEAD | K_UNIQUE))) {
 1498       if (!(unique_key))
 1499         break;
 1500       if (!(np_state & K_USED)) 
 1501         break;
 1502     }
 1503     prevnp = np;
 1504   }
 1505 
 1506   if (np) {
 1507     struct socketlist *newsp;
 1508     CRITICAL_DCL
 1509 
 1510     CRITICAL_START;
 1511 
 1512     DPRINTF(IDL_EVENT,("key_alloc: found node to allocate\n"));
 1513     keynode = np->keynode;
 1514 
 1515     KMALLOC(newnp, struct key_so2spinode *, sizeof(struct key_so2spinode));
 1516     if (newnp == 0) {
 1517       DPRINTF(IDL_ERROR,("key_alloc: Can't alloc mem for so2spi node!\n"));
 1518       CRITICAL_END;
 1519       return(ENOBUFS);
 1520     }
 1521     KMALLOC(newsp, struct socketlist *, sizeof(struct socketlist));
 1522     if (newsp == 0) {
 1523       DPRINTF(IDL_ERROR,("key_alloc: Can't alloc mem for socketlist!\n"));
 1524       if (newnp)
 1525         KFREE(newnp);
 1526       CRITICAL_END;
 1527       return(ENOBUFS);
 1528     }
 1529 
 1530     /*
 1531      * Add a hash entry into the so2spi table to
 1532      * map socket to allocated secassoc.
 1533      */
 1534     DPRINTF(IDL_FINISHED,("key_alloc: adding entry to so2spi table..."));
 1535     newnp->keynode = keynode;
 1536     newnp->socket = socket;
 1537     newnp->next = so2spitbl[((u_int32_t)socket) % SO2SPITBLSIZE].next; 
 1538     so2spitbl[((u_int32_t)socket) % SO2SPITBLSIZE].next = newnp;
 1539     DPRINTF(IDL_FINISHED,("done\n"));
 1540 
 1541     if (unique_key) {
 1542       /*
 1543        * Need to remove the allocation entry
 1544        * since the secassoc is now unique,  
 1545        * can't be allocated to any other socket
 1546        */
 1547       DPRINTF(IDL_EVENT,("key_alloc: making keynode unique..."));
 1548       keynode->secassoc->state |= K_UNIQUE;
 1549       prevnp->next = np->next;
 1550       KFREE(np);
 1551       DPRINTF(IDL_EVENT,("done\n"));
 1552     }
 1553     keynode->secassoc->state |= K_USED;
 1554     keynode->secassoc->state |= K_OUTBOUND;
 1555     keynode->alloc_count++;
 1556 
 1557     /*
 1558      * Add socket to list of socket using secassoc.
 1559      */
 1560     DPRINTF(IDL_FINISHED,("key_alloc: adding so to solist..."));
 1561     newsp->socket = socket;
 1562     newsp->next = keynode->solist->next;
 1563     keynode->solist->next = newsp;
 1564     DPRINTF(IDL_FINISHED,("done\n"));
 1565     *keynodep = keynode;
 1566     CRITICAL_END;
 1567     return(0);
 1568   } 
 1569   *keynodep = NULL;
 1570   return(0);
 1571 }
 1572 
 1573 
 1574 /*----------------------------------------------------------------------
 1575  * key_free():
 1576  *      Decrement the refcount for a key table entry.  If the entry is 
 1577  *      marked dead,,  the refcount is zero, we go ahead,  delete it.
 1578  ----------------------------------------------------------------------*/
 1579 void
 1580 key_free(struct key_tblnode *keynode)
 1581 {
 1582   DPRINTF(IDL_GROSS_EVENT,("Entering key_free w/keynode=0x%x\n",
 1583                            (unsigned int)keynode));
 1584   if (!keynode) {
 1585     DPRINTF(IDL_ERROR,("Warning: key_free got null pointer\n"));
 1586     return;
 1587   }
 1588   (keynode->ref_count)--;
 1589   if (keynode->ref_count < 0) {
 1590     DPRINTF(IDL_ERROR,("Warning: key_free decremented refcount to %d\n",keynode->ref_count));
 1591   }
 1592   if ((keynode->secassoc->state & K_DEAD) && (keynode->ref_count <= 0)) {
 1593     DPRINTF(IDL_GROSS_EVENT,("key_free: calling key_delete\n"));
 1594     key_delete(keynode->secassoc);
 1595   }
 1596 }
 1597 
 1598 /*----------------------------------------------------------------------
 1599  * getassocbyspi():
 1600  *      Get a security association for a given type, src, dst,,  spi.
 1601  *
 1602  *      Returns: 0 if sucessfull
 1603  *               -1 if error/not found
 1604  *
 1605  *      Caller must convert spi to host order.  Function assumes spi is  
 1606  *      in host order!
 1607  ----------------------------------------------------------------------*/
 1608 int
 1609 getassocbyspi(u_int type, SOCKADDR *src, SOCKADDR *dst, u_int32_t spi, 
 1610               struct key_tblnode **keyentry)
 1611 {
 1612   char buf[MAXHASHKEYLEN];
 1613   int len, indx;
 1614   struct key_tblnode *keynode, *prevkeynode = 0;
 1615 
 1616   DPRINTF(IDL_FINISHED,("Entering getassocbyspi w/type=%u spi=%u\n",type,spi));
 1617 
 1618   *keyentry = NULL;
 1619   bzero(&buf, sizeof(buf));
 1620   len = key_createkey((char *)&buf, type, src, dst, spi, 0);
 1621   indx = key_gethashval((char *)&buf, len, KEYTBLSIZE);
 1622   DPRINTF(IDL_FINISHED,("getassocbyspi: indx=%d\n",indx));
 1623   DDO(IDL_FINISHED,dump_sockaddr(src);dump_sockaddr(dst));
 1624   keynode = key_search(type, src, dst, spi, indx, &prevkeynode);
 1625   DPRINTF(IDL_FINISHED,("getassocbyspi: keysearch ret=0x%x\n",
 1626                         (unsigned int)keynode));
 1627   if (keynode && !(keynode->secassoc->state & (K_DEAD | K_LARVAL))) {
 1628     DPRINTF(IDL_GROSS_EVENT,("getassocbyspi: found secassoc!\n"));
 1629     (keynode->ref_count)++;
 1630     keynode->secassoc->state |= K_USED;
 1631     *keyentry = keynode;
 1632   } else {
 1633     DPRINTF(IDL_EVENT,("getassocbyspi: secassoc not found!\n"));
 1634     return (-1);
 1635   }
 1636   return(0);
 1637 }
 1638 
 1639 
 1640 /*----------------------------------------------------------------------
 1641  * getassocbysocket():
 1642  *      Get a security association for a given type, src, dst,,  socket.
 1643  *      If not found, try to allocate one.
 1644  *      Returns: 0 if successfull
 1645  *              -1 if error condition/secassoc not found (*keyentry = NULL)
 1646  *               1 if secassoc temporarily unavailable (*keynetry = NULL)
 1647  *                 (e.g., key mgnt. daemon(s) called)
 1648  ----------------------------------------------------------------------*/
 1649 int
 1650 getassocbysocket(u_int type, SOCKADDR *src, SOCKADDR *dst, 
 1651                  struct socket *socket, u_int unique_key, 
 1652                  struct key_tblnode **keyentry)
 1653 {
 1654   struct key_tblnode *keynode = 0;
 1655   struct key_so2spinode *np;
 1656   u_int realtype;
 1657  
 1658   DPRINTF(IDL_FINISHED,("Entering getassocbysocket w/type=%u so=0x%x\n",
 1659                         type,(unsigned int)socket));
 1660 
 1661   /*
 1662    *  We treat esp-transport mode,  esp-tunnel mode 
 1663    *  as a single type in the keytable.  This has a side
 1664    *  effect that socket using both esp-transport, 
 1665    *  esp-tunnel will use the same security association
 1666    *  for both modes.  Is this a problem?
 1667    */
 1668   realtype = type;
 1669   if ((np = key_sosearch(type, src, dst, socket))) {
 1670     if (np->keynode && np->keynode->secassoc && 
 1671         !(np->keynode->secassoc->state & (K_DEAD | K_LARVAL))) {
 1672       DPRINTF(IDL_FINISHED,("getassocbysocket: found secassoc!\n"));
 1673       (np->keynode->ref_count)++;
 1674       *keyentry = np->keynode;
 1675       return(0);
 1676     }
 1677   }
 1678 
 1679   /*
 1680    * No secassoc has been allocated to socket, 
 1681    * so allocate one, if available
 1682    */
 1683   DPRINTF(IDL_GROSS_EVENT,("getassocbyso: can't find it, trying to allocate!\n"));
 1684   if (key_alloc(realtype, src, dst, socket, unique_key, &keynode) == 0) {
 1685     if (keynode) {
 1686       DPRINTF(IDL_GROSS_EVENT,("getassocbyso: key_alloc found secassoc!\n"));
 1687       keynode->ref_count++;
 1688       *keyentry = keynode;
 1689       return(0);
 1690     } else {
 1691       /* 
 1692        * Kick key mgnt. daemon(s) 
 1693        * (this should be done in ipsec_output_policy() instead or
 1694        * selectively called based on a flag value)
 1695        */
 1696       DPRINTF(IDL_FINISHED,("getassocbyso: calling key mgnt daemons!\n"));
 1697       *keyentry = NULL;
 1698       if (key_acquire(realtype, src, dst) == 0)
 1699         return (1);
 1700       else
 1701         return(-1);
 1702     }
 1703   }
 1704   *keyentry = NULL;
 1705   return(-1);
 1706 }
 1707 
 1708 /*----------------------------------------------------------------------
 1709  * key_xdata():
 1710  *      Parse message buffer for src/dst/from/iv/key if parseflag = 0
 1711  *      else parse for src/dst only.
 1712  ----------------------------------------------------------------------*/
 1713 static int
 1714 key_xdata(struct key_msghdr *km, struct key_msgdata *kip, int parseflag)
 1715 {
 1716   char *cp, *cpmax;
 1717 
 1718   if (!km || (km->key_msglen <= 0))
 1719     return (-1);
 1720 
 1721   cp = (caddr_t)(km + 1);
 1722   cpmax = (caddr_t)km + km->key_msglen;
 1723 
 1724   /*
 1725    * Assumes user process passes message with 
 1726    * correct word alignment.
 1727    */
 1728 
 1729   /* 
 1730    * Need to clean up this code later.  
 1731    */
 1732 
 1733   /* Grab src addr */
 1734   kip->src = (SOCKADDR *)cp;
 1735   if (!kip->src->sa_len) {
 1736     DPRINTF(IDL_MAJOR_EVENT,("key_xdata couldn't parse src addr\n"));
 1737     return(-1);
 1738   }
 1739 
 1740   ADVANCE(cp, kip->src->sa_len);
 1741 
 1742   /* Grab dest addr */
 1743   kip->dst = (SOCKADDR *)cp;
 1744   if (!kip->dst->sa_len) {
 1745     DPRINTF(IDL_MAJOR_EVENT,("key_xdata couldn't parse dest addr\n"));
 1746     return(-1);
 1747   }
 1748 
 1749   ADVANCE(cp, kip->dst->sa_len);
 1750   if (parseflag == 1) {
 1751     kip->from = 0;
 1752     kip->key = kip->iv = 0;
 1753     kip->keylen = kip->ivlen = 0;
 1754     return(0);
 1755   }
 1756  
 1757   /* Grab from addr */
 1758   kip->from = (SOCKADDR *)cp;
 1759   if (!kip->from->sa_len) {
 1760     DPRINTF(IDL_MAJOR_EVENT,("key_xdata couldn't parse from addr\n"));
 1761     return(-1);
 1762   }
 1763 
 1764   ADVANCE(cp, kip->from->sa_len);
 1765  
 1766   /* Grab key */
 1767   if ((kip->keylen = km->keylen)) {
 1768     kip->key = cp;
 1769     ADVANCE(cp, km->keylen);
 1770   } else 
 1771     kip->key = 0;
 1772 
 1773   /* Grab iv */
 1774   if ((kip->ivlen = km->ivlen))
 1775     kip->iv = cp;
 1776   else
 1777     kip->iv = 0;
 1778 
 1779   return (0);
 1780 }
 1781 
 1782 
 1783 int
 1784 key_parse(struct key_msghdr **kmp, struct socket *so, int *dstfamily)
 1785 {
 1786   int error = 0, keyerror = 0;
 1787   struct key_msgdata keyinfo;
 1788   struct key_secassoc *secassoc = NULL;
 1789   struct key_msghdr *km = *kmp;
 1790 
 1791   DPRINTF(IDL_MAJOR_EVENT, ("Entering key_parse\n"));
 1792 
 1793 #define senderr(e) \
 1794   { error = (e); goto flush; }
 1795 
 1796   if (km->key_msgvers != KEY_VERSION) {
 1797     DPRINTF(IDL_CRITICAL,("keyoutput: Unsupported key message version!\n"));
 1798     senderr(EPROTONOSUPPORT);
 1799   }
 1800 
 1801   km->key_pid = CURRENT_PID;
 1802 
 1803   DDO(IDL_MAJOR_EVENT, printf("keymsghdr:\n"); dump_keymsghdr(km));
 1804 
 1805   /*
 1806    * Parse buffer for src addr, dest addr, from addr, key, iv
 1807    */
 1808   bzero((char *)&keyinfo, sizeof(keyinfo));
 1809 
 1810   switch (km->key_msgtype) {
 1811   case KEY_ADD:
 1812     DPRINTF(IDL_MAJOR_EVENT,("key_output got KEY_ADD msg\n"));
 1813 
 1814     if (key_xdata(km, &keyinfo, 0) < 0)
 1815       goto parsefail;
 1816 
 1817     /*
 1818      * Allocate the secassoc structure to insert 
 1819      * into key table here.
 1820      */
 1821     KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc)); 
 1822     if (secassoc == 0) {
 1823       DPRINTF(IDL_CRITICAL,("keyoutput: No more memory!\n"));
 1824       senderr(ENOBUFS);
 1825     }
 1826 
 1827     if (key_msghdr2secassoc(secassoc, km, &keyinfo) < 0) {
 1828       DPRINTF(IDL_CRITICAL,("keyoutput: key_msghdr2secassoc failed!\n"));
 1829       KFREE(secassoc);
 1830       senderr(EINVAL);
 1831     }
 1832     DPRINTF(IDL_MAJOR_EVENT,("secassoc to add:\n"));
 1833     DDO(IDL_MAJOR_EVENT,dump_secassoc(secassoc));
 1834 
 1835     if ((keyerror = key_add(secassoc)) != 0) {
 1836       DPRINTF(IDL_CRITICAL,("keyoutput: key_add failed\n"));
 1837       if (secassoc->key)
 1838         KFREE(secassoc->key);
 1839       if (secassoc->iv)
 1840         KFREE(secassoc->iv);
 1841       KFREE(secassoc);
 1842       if (keyerror == -2) {
 1843         senderr(EEXIST);
 1844       } else {
 1845         senderr(ENOBUFS);
 1846       }
 1847     }
 1848     break;
 1849   case KEY_DELETE:
 1850     DPRINTF(IDL_MAJOR_EVENT,("key_output got KEY_DELETE msg\n"));
 1851 
 1852     if (key_xdata(km, &keyinfo, 1) < 0)
 1853       goto parsefail;
 1854 
 1855     KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc)); 
 1856     if (secassoc == 0) {
 1857       senderr(ENOBUFS);
 1858     }
 1859     if (key_msghdr2secassoc(secassoc, km, &keyinfo) < 0) {
 1860       KFREE(secassoc);
 1861       senderr(EINVAL);
 1862     }
 1863     if (key_delete(secassoc) != 0) {
 1864       if (secassoc->iv)
 1865         KFREE(secassoc->iv);
 1866       if (secassoc->key)
 1867         KFREE(secassoc->key);
 1868       KFREE(secassoc);
 1869       senderr(ESRCH);
 1870     }
 1871     if (secassoc->iv)
 1872       KFREE(secassoc->iv);
 1873     if (secassoc->key)
 1874       KFREE(secassoc->key);
 1875     KFREE(secassoc);
 1876     break;
 1877   case KEY_UPDATE:
 1878     DPRINTF(IDL_EVENT,("key_output got KEY_UPDATE msg\n"));
 1879 
 1880     if (key_xdata(km, &keyinfo, 0) < 0)
 1881       goto parsefail;
 1882 
 1883     KMALLOC(secassoc, struct key_secassoc *, sizeof(struct key_secassoc)); 
 1884     if (secassoc == 0) {
 1885       senderr(ENOBUFS);
 1886     }
 1887     if (key_msghdr2secassoc(secassoc, km, &keyinfo) < 0) {
 1888       KFREE(secassoc);
 1889       senderr(EINVAL);
 1890     }
 1891     if ((keyerror = key_update(secassoc)) != 0) {
 1892       DPRINTF(IDL_CRITICAL,("Error updating key entry\n"));
 1893       if (secassoc->iv)
 1894         KFREE(secassoc->iv);
 1895       if (secassoc->key)
 1896         KFREE(secassoc->key);
 1897       KFREE(secassoc);
 1898       senderr(keyerror);
 1899     }
 1900     KFREE(secassoc);
 1901     break;
 1902   case KEY_GET:
 1903     DPRINTF(IDL_EVENT,("key_output got KEY_GET msg\n"));
 1904 
 1905     if (key_xdata(km, &keyinfo, 1) < 0)
 1906       goto parsefail;
 1907 
 1908     if (key_get(km->type, (SOCKADDR *)keyinfo.src, 
 1909                 (SOCKADDR *)keyinfo.dst, 
 1910                 km->spi, &secassoc) != 0) {
 1911       DPRINTF(IDL_EVENT,("keyoutput: can't get key\n"));
 1912       senderr(ESRCH);
 1913     }
 1914 
 1915     if (secassoc) {
 1916       int newlen;
 1917 
 1918       DPRINTF(IDL_EVENT,("keyoutput: Found secassoc!\n"));
 1919       newlen = sizeof(struct key_msghdr) + ROUNDUP(secassoc->src->sa_len) +
 1920         ROUNDUP(secassoc->dst->sa_len) + ROUNDUP(secassoc->from->sa_len) +
 1921           ROUNDUP(secassoc->keylen) + ROUNDUP(secassoc->ivlen);
 1922       DPRINTF(IDL_EVENT,("keyoutput: newlen=%d\n", newlen));
 1923       if (newlen > km->key_msglen) {
 1924         struct key_msghdr *newkm;
 1925 
 1926         DPRINTF(IDL_EVENT,("keyoutput: Allocating new buffer!\n"));
 1927         KMALLOC(newkm, struct key_msghdr *, newlen); 
 1928         if (newkm == 0) {
 1929           senderr(ENOBUFS);
 1930         }
 1931         bcopy((char *)km, (char *)newkm, km->key_msglen);
 1932         DPRINTF(IDL_FINISHED,("keyoutput: 1\n"));
 1933         KFREE(km);
 1934         *kmp = km = newkm;
 1935         DPRINTF(IDL_CRITICAL, ("km->key_msglen = %d, newlen = %d\n",
 1936                                km->key_msglen, newlen));
 1937         km->key_msglen = newlen;
 1938       }
 1939       DPRINTF(IDL_FINISHED,("keyoutput: 2\n"));
 1940       if (key_secassoc2msghdr(secassoc, km, &keyinfo)) {
 1941         DPRINTF(IDL_CRITICAL,("keyoutput: Can't create msghdr!\n"));
 1942         senderr(EINVAL);
 1943       }
 1944       DPRINTF(IDL_FINISHED,("keyoutput: 3\n"));
 1945     }
 1946     break;
 1947   case KEY_GETSPI:
 1948     DPRINTF(IDL_EVENT,("key_output got KEY_GETSPI msg\n"));
 1949 
 1950     if (key_xdata(km, &keyinfo, 1) < 0)
 1951       goto parsefail;
 1952 
 1953     if ((keyerror = key_getspi(km->type, keyinfo.src, keyinfo.dst, 
 1954                                km->lifetime1, km->lifetime2, 
 1955                                &(km->spi))) != 0) {
 1956       DPRINTF(IDL_CRITICAL,("keyoutput: getspi failed error=%d\n", keyerror));
 1957       senderr(keyerror);
 1958     }
 1959     break;
 1960   case KEY_REGISTER:
 1961     DPRINTF(IDL_EVENT,("key_output got KEY_REGISTER msg\n"));
 1962     key_register(so, km->type);
 1963     break;
 1964   case KEY_DUMP:
 1965     DPRINTF(IDL_EVENT,("key_output got KEY_DUMP msg\n"));
 1966     error = key_dump(so);
 1967     return(error);
 1968     break;
 1969   case KEY_FLUSH:
 1970     DPRINTF(IDL_EVENT,("key_output got KEY_FLUSH msg\n"));
 1971     key_flush();
 1972     break;
 1973   default:
 1974     DPRINTF(IDL_CRITICAL,("key_output got unsupported msg type=%d\n", 
 1975                              km->key_msgtype));
 1976     senderr(EOPNOTSUPP);
 1977   }
 1978 
 1979   goto flush;
 1980 
 1981 parsefail:
 1982   keyinfo.dst = NULL;
 1983   error = EINVAL;
 1984 
 1985 flush:
 1986   if (km)
 1987     km->key_errno = error;
 1988 
 1989   if (dstfamily)
 1990     *dstfamily = keyinfo.dst ? keyinfo.dst->sa_family : 0;
 1991 
 1992   DPRINTF(IDL_MAJOR_EVENT, ("key_parse exiting with error=%d\n", error));
 1993   return error;
 1994 }
 1995 
 1996 /*
 1997  * Definitions of protocols supported in the KEY domain.
 1998  */
 1999 
 2000 struct  sockaddr key_addr = { 2, PF_KEY, };
 2001 struct  sockproto key_proto = { PF_KEY, };
 2002 
 2003 #define KEYREAPERINT 120
 2004 
 2005 #define ROUNDUP(a) \
 2006   ((a) > 0 ? (1 + (((a) - 1) | (sizeof(long) - 1))) : sizeof(long))
 2007 
 2008 static int
 2009 key_sendup(s, km)
 2010         struct socket *s;
 2011         struct key_msghdr *km;
 2012 {
 2013   struct mbuf *m;
 2014   MGETHDR(m, M_WAIT, MT_DATA);
 2015   m->m_len = m->m_pkthdr.len = 0;
 2016   m->m_next = 0;
 2017   m->m_nextpkt = 0;
 2018   m->m_pkthdr.rcvif = 0;
 2019   m_copyback(m, 0, km->key_msglen, (caddr_t)km);
 2020   
 2021   if (sbappendaddr(&(s->so_rcv), &key_addr, m, NULL)) {
 2022     sorwakeup(s);
 2023     return 1;
 2024   } else 
 2025     m_freem(m);
 2026 
 2027   return(0);
 2028 }
 2029 
 2030 #ifdef notyet
 2031 /*----------------------------------------------------------------------
 2032  * key_reaper():
 2033  *      Scan key table,  nuke unwanted entries
 2034  ----------------------------------------------------------------------*/
 2035 static void
 2036 key_reaper(whocares)
 2037      void *whocares;
 2038 {
 2039   DPRINTF(IDL_GROSS_EVENT,("Entering key_reaper()\n"));
 2040 
 2041   timeout(key_reaper, NULL, KEYREAPERINT * HZ);
 2042 }
 2043 #endif /* notyet */
 2044 
 2045 /*----------------------------------------------------------------------
 2046  * key_init():
 2047  *      Init routine for key socket,  key engine
 2048  ----------------------------------------------------------------------*/
 2049 static void
 2050 key_init(void)
 2051 {
 2052   DPRINTF(IDL_EVENT,("Called key_init().\n"));
 2053   if (key_inittables())
 2054     panic("key_inittables failed!\n");
 2055 #ifdef notyet
 2056   timeout(key_reaper, NULL, HZ);
 2057 #endif /* notyet */
 2058   bzero((char *)&keyso_cb, sizeof(keyso_cb));
 2059 }
 2060 
 2061 /*----------------------------------------------------------------------
 2062  * my_addr():
 2063  *      Determine if an address belongs to one of my configured interfaces.
 2064  *      Currently handles only AF_INET,  AF_INET6 addresses.
 2065  ----------------------------------------------------------------------*/
 2066 static int
 2067 my_addr(sa)
 2068      SOCKADDR *sa;
 2069 {
 2070   struct in6_ifaddr *i6a = 0;
 2071   struct in_ifaddr *ia = 0;
 2072 
 2073   switch(sa->sa_family) {
 2074 #ifdef INET6
 2075   case AF_INET6:
 2076     for (i6a = in6_ifaddr; i6a; i6a = i6a->i6a_next) {
 2077       if (IN6_ADDR_EQUAL(((struct sockaddr_in6 *)sa)->sin6_addr, 
 2078                          i6a->i6a_addr.sin6_addr))
 2079         return(1);
 2080     }
 2081     break;
 2082 #endif /* INET6 */
 2083   case AF_INET:
 2084     for (ia = in_ifaddr; ia; ia = ia->ia_next) {
 2085       if (((struct sockaddr_in *)sa)->sin_addr.s_addr == 
 2086            ia->ia_addr.sin_addr.s_addr) 
 2087         return(1);
 2088     }
 2089     break;
 2090   }
 2091   return(0);
 2092 }
 2093 
 2094 /*----------------------------------------------------------------------
 2095  * key_output():
 2096  *      Process outbound pf_key message.
 2097  ----------------------------------------------------------------------*/
 2098 static int
 2099 key_output(struct mbuf *m, struct socket *so)
 2100 {
 2101   struct key_msghdr *km = 0;
 2102   caddr_t cp, cplimit;
 2103   int len;
 2104   int error = 0;
 2105   int dstfamily = 0;
 2106 
 2107   DPRINTF(IDL_EVENT,("key_output() got a message len=%d.\n", m->m_pkthdr.len));
 2108 
 2109 #undef senderr
 2110 #define senderr(e) \
 2111   { error = (e); if (km) km->key_errno = error; goto flush; }
 2112 
 2113   if (m == 0 || ((m->m_len < sizeof(long)) && 
 2114                  (m = m_pullup(m, sizeof(long))) == 0)) {
 2115     DPRINTF(IDL_CRITICAL,("key_output can't pullup mbuf\n"));
 2116     return (ENOBUFS);
 2117   }
 2118   if ((m->m_flags & M_PKTHDR) == 0)
 2119     panic("key_output");
 2120 
 2121   DDO(IDL_FINISHED,dump_mbuf(m));  
 2122   
 2123   len = m->m_pkthdr.len;
 2124   if (len < sizeof(*km) || len != mtod(m, struct key_msghdr *)->key_msglen) {
 2125     DPRINTF(IDL_CRITICAL,("keyout: Invalid length field/length mismatch!\n"));
 2126     senderr(EINVAL); 
 2127   }
 2128   KMALLOC(km, struct key_msghdr *, len); 
 2129   if (km == 0) {
 2130     DPRINTF(IDL_CRITICAL,("keyoutput: Can't malloc memory!\n"));
 2131     senderr(ENOBUFS);
 2132   }
 2133 
 2134   m_copydata(m, 0, len, (caddr_t)km);
 2135 
 2136   km->key_errno = error = key_parse(&km, so, &dstfamily);
 2137   DPRINTF(IDL_MAJOR_EVENT, ("Back from key_parse\n"));
 2138 flush:
 2139   key_sendup(so, km);
 2140 #if 0
 2141   {
 2142     struct rawcb *rp = 0;
 2143     struct mbuf *m;
 2144 
 2145     if ((so->so_options & SO_USELOOPBACK) == 0) {
 2146       if (keyso_cb.any_count <= 1) {
 2147         if (km)
 2148           KFREE(km);
 2149         return (error);
 2150       }
 2151       rp = sotorawcb(so);
 2152     }
 2153 
 2154   DPRINTF(IDL_MAJOR_EVENT, ("key_output: foo\n"));
 2155     key_proto.sp_protocol = dstfamily;
 2156 
 2157     if (km) {
 2158       m = m_devget(km, len, 0, NULL, NULL);
 2159       KFREE(km);
 2160     }
 2161 
 2162   DPRINTF(IDL_MAJOR_EVENT, ("key_output: bar\n"));
 2163     if (rp)
 2164       rp->rcb_proto.sp_family = 0;   /* Prevent us from receiving message */
 2165 
 2166     raw_input(m, &key_proto, &key_addr, &key_addr);
 2167 
 2168     if (rp)
 2169       rp->rcb_proto.sp_family = PF_KEY;
 2170   }
 2171   DPRINTF(IDL_MAJOR_EVENT, ("key_output: baz\n"));
 2172 #endif /* 0 */
 2173   return (error);
 2174 }
 2175 
 2176 
 2177 /*----------------------------------------------------------------------
 2178  * key_usrreq():
 2179  *      Handles PRU_* for pf_key sockets.
 2180  ----------------------------------------------------------------------*/
 2181 static int
 2182 key_usrreq(struct socket *so, int req, struct mbuf *m, struct mbuf *nam,
 2183            struct mbuf *control)
 2184 {
 2185   register int error = 0;
 2186   register struct rawcb *rp = sotorawcb(so);
 2187   int s;
 2188 
 2189   DPRINTF(IDL_EVENT,("Entering key_usrreq, req = %d.\n",req));
 2190 
 2191   if (req == PRU_ATTACH) {
 2192     MALLOC(rp, struct rawcb *, sizeof(*rp), M_PCB, M_WAITOK);
 2193     if (so->so_pcb = (caddr_t)rp)
 2194       bzero(so->so_pcb, sizeof(*rp));
 2195   }
 2196 
 2197   if (req == PRU_DETACH && rp) {
 2198     int af = rp->rcb_proto.sp_protocol;
 2199     if (af == AF_INET)
 2200       keyso_cb.ip4_count--;
 2201 #ifdef INET6
 2202     else if (af == AF_INET6)
 2203       keyso_cb.ip6_count--;
 2204 #endif /* INET6 */
 2205     keyso_cb.any_count--;
 2206   }
 2207   s = splnet();
 2208   error = raw_usrreq(so, req, m, nam, control);
 2209   rp = sotorawcb(so);
 2210 
 2211   if (req == PRU_ATTACH && rp) {
 2212     int af = rp->rcb_proto.sp_protocol;
 2213     if (error) {
 2214       free((caddr_t)rp, M_PCB);
 2215       splx(s);
 2216       return error;
 2217     }
 2218     if (af == AF_INET)
 2219       keyso_cb.ip4_count++;
 2220 #ifdef INET6
 2221     else if (af == AF_INET6)
 2222       keyso_cb.ip6_count++;
 2223 #endif /* INET6 */
 2224     keyso_cb.any_count++;
 2225     rp->rcb_faddr = &key_addr;
 2226     soisconnected(so);   /* Key socket, like routing socket, must be
 2227                             connected. */
 2228 
 2229     /* Possibly set other needed flags/options at creation time in here. */
 2230     so->so_options |= SO_USELOOPBACK; /* Like routing socket, we turn this */
 2231                                       /* on by default                     */
 2232   }
 2233   splx(s);
 2234   return error;
 2235 }
 2236 
 2237 /*----------------------------------------------------------------------
 2238  * key_cbinit():
 2239  *      Control block init routine for key socket
 2240  ----------------------------------------------------------------------*/
 2241 static void
 2242 key_cbinit(void)
 2243 {
 2244  /*
 2245   *  This is equivalent to raw_init for the routing socket. 
 2246   *  The key socket uses the same control block as the routing 
 2247   *  socket.
 2248   */
 2249   DPRINTF(IDL_EVENT,("Called key_cbinit().\n"));
 2250 }
 2251 
 2252 /*
 2253  * Protoswitch entry for pf_key 
 2254  */
 2255 
 2256 extern  struct domain keydomain;                /* or at least forward */
 2257 
 2258 struct protosw keysw[] = {
 2259 { SOCK_RAW,     &keydomain,     0,              PR_ATOMIC|PR_ADDR,
 2260   raw_input,    key_output,     raw_ctlinput,   0,
 2261   key_usrreq,
 2262   key_cbinit
 2263 }
 2264 };
 2265 
 2266 struct domain keydomain =
 2267     { PF_KEY, "key", key_init, 0, 0,
 2268       keysw, &keysw[sizeof(keysw)/sizeof(keysw[0])] };
 2269 
 2270 DOMAIN_SET(key)

Cache object: d52cf1147617ec37b2b65b63466b650b


[ source navigation ] [ diff markup ] [ identifier search ] [ freetext search ] [ file search ] [ list types ] [ track identifier ]


This page is part of the FreeBSD/Linux Linux Kernel Cross-Reference, and was automatically generated using a modified version of the LXR engine.