]> git.saurik.com Git - apple/network_cmds.git/blobdiff - racoon.tproj/isakmp_inf.c
network_cmds-245.19.tar.gz
[apple/network_cmds.git] / racoon.tproj / isakmp_inf.c
index 0bf9a2f4554d6a8a4291586afebf333ed477704b..4174255dc5bf126064042f4dc119a2338b30ca70 100644 (file)
@@ -1,4 +1,4 @@
-/*     $KAME: isakmp_inf.c,v 1.78 2001/12/19 18:29:39 sakane Exp $     */
+/*     $KAME: isakmp_inf.c,v 1.81 2002/04/15 01:58:37 itojun Exp $     */
 
 /*
  * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
@@ -34,7 +34,6 @@
 #include <sys/socket.h>
 
 #include <net/pfkeyv2.h>
-#include <netkey/keydb.h>
 #include <netkey/key_var.h>
 #include <netinet/in.h>
 #ifdef IPV6_INRIA_VERSION
@@ -136,10 +135,82 @@ isakmp_info_recv(iph1, msg0)
 
        isakmp = (struct isakmp *)msg->v;
        gen = (struct isakmp_gen *)((caddr_t)isakmp + sizeof(struct isakmp));
-       if (isakmp->np == ISAKMP_NPTYPE_HASH)
-               np = gen->np;
-       else
-               np = isakmp->np;
+
+
+       if (isakmp->np != ISAKMP_NPTYPE_HASH) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                   "ignore information because the message has no hash payload.\n");
+               goto end;
+       }
+
+       if (iph1->status != PHASE1ST_ESTABLISHED) {
+               plog(LLV_ERROR, LOCATION, NULL,
+                   "ignore information because ISAKMP-SA has not been established yet.\n");
+               goto end;
+       }
+
+       np = gen->np;
+
+       {
+               void *p;
+               vchar_t *hash, *payload;
+               struct isakmp_gen *nd;
+
+               /*
+                * XXX: gen->len includes isakmp header length
+                */
+               p = (caddr_t) gen + sizeof(struct isakmp_gen);
+               nd = (struct isakmp_gen *) ((caddr_t) gen + ntohs(gen->len));
+
+               /* nd length check */
+               if (ntohs(nd->len) > msg->l - (sizeof(struct isakmp) + ntohs(gen->len))) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                                "too long payload length (broken message?)\n");
+                       goto end;
+               }
+
+               payload = vmalloc(ntohs(nd->len));
+               if (payload == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "cannot allocate memory\n");
+                       goto end;
+               }
+
+               memcpy(payload->v, (caddr_t) nd, ntohs(nd->len));
+
+               /* compute HASH */
+               hash = oakley_compute_hash1(iph1, isakmp->msgid, payload);
+               if (hash == NULL) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "cannot compute hash\n");
+
+                       vfree(payload);
+                       goto end;
+               }
+               
+               if (ntohs(gen->len) - sizeof(struct isakmp_gen) != hash->l) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "ignore information due to hash length mismatch\n");
+
+                       vfree(hash);
+                       vfree(payload);
+                       goto end;
+               }
+
+               if (memcmp(p, hash->v, hash->l) != 0) {
+                       plog(LLV_ERROR, LOCATION, NULL,
+                           "ignore information due to hash mismatch\n");
+
+                       vfree(hash);
+                       vfree(payload);
+                       goto end;
+               }
+
+               plog(LLV_DEBUG, LOCATION, NULL, "hash validated.\n");
+
+               vfree(hash);
+               vfree(payload);
+       }
                
        /* make sure the packet were encrypted. */
        if (!encrypted) {
@@ -1062,10 +1133,13 @@ info_recv_initialcontact(iph1)
                 * racoon only deletes SA which is matched both the
                 * source address and the destination accress.
                 */
-               if ((cmpsaddrwop(iph1->local, src) &&
-                    cmpsaddrwop(iph1->remote, dst)) ||
-                   (cmpsaddrwop(iph1->remote, src) &&
-                    cmpsaddrwop(iph1->local, dst))) {
+               if (cmpsaddrwop(iph1->local, src) == 0 &&
+                   cmpsaddrwop(iph1->remote, dst) == 0)
+                       ;
+               else if (cmpsaddrwop(iph1->remote, src) == 0 &&
+                   cmpsaddrwop(iph1->local, dst) == 0)
+                       ;
+               else {
                        msg = next;
                        continue;
                }