ikev1: Accept reauthentication attempts with a keep unique policy from same host
authorMartin Willi <martin@revosec.ch>
Wed, 18 Sep 2013 12:11:40 +0000 (14:11 +0200)
committerMartin Willi <martin@revosec.ch>
Mon, 30 Sep 2013 11:51:12 +0000 (13:51 +0200)
When we have a "keep" unique policy in place, we have to be less strict in
rejecting Main/Aggressive Modes to enforce it. If the host/port equals to
that of an existing ISAKMP SA, we assume it is a reauthentication attempt
and accept the new SA (to replace the old).

src/libcharon/sa/ike_sa_manager.c

index 7366420..7f16595 100644 (file)
@@ -1766,6 +1766,15 @@ static void adopt_children(ike_sa_t *old, ike_sa_t *new)
 }
 
 /**
+ * Check if the replaced IKE_SA might get reauthenticated from host
+ */
+static bool is_ikev1_reauth(ike_sa_t *duplicate, host_t *host)
+{
+       return duplicate->get_version(duplicate) == IKEV1 &&
+                  host->equals(host, duplicate->get_other_host(duplicate));
+}
+
+/**
  * Delete an existing IKE_SA due to a unique replace policy
  */
 static status_t enforce_replace(private_ike_sa_manager_t *this,
@@ -1774,8 +1783,7 @@ static status_t enforce_replace(private_ike_sa_manager_t *this,
 {
        charon->bus->alert(charon->bus, ALERT_UNIQUE_REPLACE);
 
-       if (duplicate->get_version(duplicate) == IKEV1 &&
-               host->equals(host, duplicate->get_other_host(duplicate)))
+       if (is_ikev1_reauth(duplicate, host))
        {
                /* looks like a reauthentication attempt */
                adopt_children(duplicate, new);
@@ -1846,10 +1854,13 @@ METHOD(ike_sa_manager_t, check_uniqueness, bool,
                                                                                                         other, other_host);
                                                        break;
                                                case UNIQUE_KEEP:
-                                                       cancel = TRUE;
-                                                       /* we keep the first IKE_SA and delete all
-                                                        * other duplicates that might exist */
-                                                       policy = UNIQUE_REPLACE;
+                                                       if (!is_ikev1_reauth(duplicate, other_host))
+                                                       {
+                                                               cancel = TRUE;
+                                                               /* we keep the first IKE_SA and delete all
+                                                                * other duplicates that might exist */
+                                                               policy = UNIQUE_REPLACE;
+                                                       }
                                                        break;
                                                default:
                                                        break;