]> git.ipfire.org Git - thirdparty/strongswan.git/commitdiff
peer-cfg: Consider security labels when selecting child configs
authorTobias Brunner <tobias@strongswan.org>
Mon, 10 Jan 2022 17:31:34 +0000 (18:31 +0100)
committerTobias Brunner <tobias@strongswan.org>
Thu, 14 Apr 2022 16:42:01 +0000 (18:42 +0200)
src/libcharon/config/peer_cfg.c
src/libcharon/config/peer_cfg.h
src/libcharon/sa/ikev1/tasks/quick_mode.c
src/libcharon/sa/ikev2/tasks/child_create.c

index 2350ad50168bb1cc4e0a1717ff2df75ecc2b884f..1f2c5f10947ac875bc4894bcd3bb83bc344c9dcf 100644 (file)
@@ -386,13 +386,28 @@ METHOD(peer_cfg_t, create_child_cfg_enumerator, enumerator_t*,
 /**
  * Check how good a list of TS matches a given child config
  */
-static int get_ts_match(child_cfg_t *cfg, bool local,
-                                               linked_list_t *sup_list, linked_list_t *hosts)
+static u_int get_ts_match(child_cfg_t *cfg, bool local,
+                                                 linked_list_t *sup_list, linked_list_t *hosts,
+                                                 linked_list_t *sup_labels)
 {
        linked_list_t *cfg_list;
        enumerator_t *sup_enum, *cfg_enum;
        traffic_selector_t *sup_ts, *cfg_ts, *subset;
-       int match = 0, round;
+       sec_label_t *label;
+       u_int match = 0, round;
+       bool exact = FALSE;
+
+       if (cfg->select_label(cfg, sup_labels, TRUE, &label, &exact))
+       {
+               if (label)
+               {
+                       match += exact ? 500 : 100;
+               }
+       }
+       else
+       {       /* label config doesn't match, no need to check TS  */
+               return match;
+       }
 
        /* fetch configured TS list, narrowing dynamic TS */
        cfg_list = cfg->get_traffic_selectors(cfg, local, NULL, hosts, TRUE);
@@ -432,24 +447,29 @@ static int get_ts_match(child_cfg_t *cfg, bool local,
 
 METHOD(peer_cfg_t, select_child_cfg, child_cfg_t*,
        private_peer_cfg_t *this, linked_list_t *my_ts, linked_list_t *other_ts,
-       linked_list_t *my_hosts, linked_list_t *other_hosts)
+       linked_list_t *my_hosts, linked_list_t *other_hosts,
+       linked_list_t *my_labels, linked_list_t *other_labels)
 {
        child_cfg_t *current, *found = NULL;
        enumerator_t *enumerator;
-       int best = 0;
+       u_int best = 0;
 
        DBG2(DBG_CFG, "looking for a child config for %#R === %#R", my_ts, other_ts);
        enumerator = create_child_cfg_enumerator(this);
        while (enumerator->enumerate(enumerator, &current))
        {
-               int my_prio, other_prio;
-
-               my_prio = get_ts_match(current, TRUE, my_ts, my_hosts);
-               other_prio = get_ts_match(current, FALSE, other_ts, other_hosts);
+               u_int my_prio, other_prio;
 
-               if (my_prio && other_prio)
+               my_prio = get_ts_match(current, TRUE, my_ts, my_hosts, my_labels);
+               if (!my_prio)
+               {
+                       continue;
+               }
+               other_prio = get_ts_match(current, FALSE, other_ts, other_hosts,
+                                                                 other_labels);
+               if (other_prio)
                {
-                       DBG2(DBG_CFG, "  candidate \"%s\" with prio %d+%d",
+                       DBG2(DBG_CFG, "  candidate \"%s\" with prio %u+%u",
                                 current->get_name(current), my_prio, other_prio);
                        if (my_prio + other_prio > best)
                        {
index b80e809c2c2a52e22790dc3b7dc96da1af5a935a..da3d6a0cc5b7c6d70945e70d6db60d8cfd52a34c 100644 (file)
@@ -174,17 +174,20 @@ struct peer_cfg_t {
        enumerator_t* (*create_child_cfg_enumerator) (peer_cfg_t *this);
 
        /**
-        * Select a CHILD config from traffic selectors.
+        * Select a CHILD config from received traffic selectors.
         *
         * @param my_ts                 TS for local side
         * @param other_ts              TS for remote side
         * @param my_hosts              hosts to narrow down dynamic TS for local side
         * @param other_hosts   hosts to narrow down dynamic TS for remote side
-        * @return                              selected CHILD config, or NULL if no match found
+        * @param my_labels             optional local security labels
+        * @param other_labels  optional remove security labels
+        * @return                                      selected CHILD config, or NULL if no match found
         */
-       child_cfg_t* (*select_child_cfg) (peer_cfg_t *this,
+       child_cfg_t* (*select_child_cfg)(peer_cfg_t *this,
                                                        linked_list_t *my_ts, linked_list_t *other_ts,
-                                                       linked_list_t *my_hosts, linked_list_t *other_hosts);
+                                                       linked_list_t *my_hosts, linked_list_t *other_hosts,
+                                                       linked_list_t *my_labels, linked_list_t *other_labels);
 
        /**
         * Add an authentication config to the peer configuration.
index 6138efc97268a9581c69a627f0a4fef7a1ba729d..5e4bf8620b2594c2c7259ceca5261f01ea26f416 100644 (file)
@@ -1096,7 +1096,7 @@ METHOD(task_t, process_r, status_t,
                        hostsi = get_dynamic_hosts(this->ike_sa, FALSE);
                        hostsr = get_dynamic_hosts(this->ike_sa, TRUE);
                        this->config = peer_cfg->select_child_cfg(peer_cfg, tsr, tsi,
-                                                                                                         hostsr, hostsi);
+                                                                                                         hostsr, hostsi, NULL, NULL);
                        hostsi->destroy(hostsi);
                        hostsr->destroy(hostsr);
                        if (this->config)
index 83f3c7328ad005ac502f6e7e713e4f624bbe8675..092ac72a6a78b74f9737a27d7f601031c77958a2 100644 (file)
@@ -1414,7 +1414,7 @@ static child_cfg_t* select_child_cfg(private_child_create_t *this)
                listi = get_dynamic_hosts(this->ike_sa, FALSE);
                child_cfg = peer_cfg->select_child_cfg(peer_cfg,
                                                                                        tsr ?: this->tsr, tsi ?: this->tsi,
-                                                                                       listr, listi);
+                                                                                       listr, listi, NULL, NULL);
                if ((tsi || tsr) && child_cfg &&
                        child_cfg->get_mode(child_cfg) != MODE_TRANSPORT)
                {
@@ -1426,7 +1426,8 @@ static child_cfg_t* select_child_cfg(private_child_create_t *this)
                {
                        /* no match for the substituted NAT selectors, try it without */
                        child_cfg = peer_cfg->select_child_cfg(peer_cfg,
-                                                                                       this->tsr, this->tsi, listr, listi);
+                                                                                       this->tsr, this->tsi,
+                                                                                       listr, listi, NULL, NULL);
                }
                listr->destroy(listr);
                listi->destroy(listi);