return this->label_mode;
}
+METHOD(child_cfg_t, select_label, bool,
+ private_child_cfg_t *this, linked_list_t *labels, bool log,
+ sec_label_t **label, bool *exact_out)
+{
+ enumerator_t *enumerator;
+ sec_label_t *current, *match = NULL;
+ bool exact = FALSE;
+
+ if (labels && labels->get_count(labels))
+ {
+ if (!this->label)
+ {
+ DBG2(DBG_CFG, "peer proposed a security label, but none expected");
+ return FALSE;
+ }
+ if (log)
+ {
+ DBG2(DBG_CFG, "selecting security label matching '%s':",
+ this->label->get_string(this->label));
+ }
+ enumerator = labels->create_enumerator(labels);
+ while (enumerator->enumerate(enumerator, ¤t))
+ {
+ if (this->label->equals(this->label, current))
+ {
+ if (log)
+ {
+ DBG2(DBG_CFG, " %s => matches exactly",
+ current->get_string(current));
+ }
+ match = current;
+ exact = TRUE;
+ break;
+ }
+ else if (this->label_mode == SEC_LABEL_MODE_SELINUX &&
+ this->label->matches(this->label, current))
+ {
+ if (log)
+ {
+ DBG2(DBG_CFG, " %s => matches%s",
+ current->get_string(current), match ? ", ignored" : "");
+ }
+ /* return the first match if we don't find an exact one */
+ if (!match)
+ {
+ match = current;
+ }
+ }
+ else if (log)
+ {
+ DBG2(DBG_CFG, " %s => no match", current->get_string(current));
+ }
+ }
+ enumerator->destroy(enumerator);
+ if (!match)
+ {
+ DBG2(DBG_CFG, "none of the proposed security labels match the "
+ "configured label '%s'", this->label->get_string(this->label));
+ return FALSE;
+ }
+ }
+ else if (this->label)
+ {
+ DBG2(DBG_CFG, "peer didn't propose any security labels, we expect one "
+ "matching '%s'", this->label->get_string(this->label));
+ return FALSE;
+ }
+
+ if (label)
+ {
+ *label = match;
+ }
+ if (exact_out)
+ {
+ *exact_out = exact;
+ }
+ return TRUE;
+}
+
METHOD(child_cfg_t, get_tfc, uint32_t,
private_child_cfg_t *this)
{
.get_set_mark = _get_set_mark,
.get_label = _get_label,
.get_label_mode = _get_label_mode,
+ .select_label = _select_label,
.get_tfc = _get_tfc,
.get_manual_prio = _get_manual_prio,
.get_interface = _get_interface,
*/
sec_label_mode_t (*get_label_mode)(child_cfg_t *this);
+ /**
+ * Select a security label from the given list that matches the configured
+ * label.
+ *
+ * This fails under the following conditions:
+ * - a label is configured but no labels are provided
+ * - no label is configured but at least one label is provided
+ * - the configured and provided labels don't match
+ *
+ * If no label is configured and none are provided, that's considered a
+ * success and label will be set to NULL.
+ *
+ * @param labels list of labels to match
+ * @param log FALSE to avoid logging details about the selection
+ * @param label[out] selected label or NULL if no label necessary
+ * @param exact[out] TRUE if there was an exact match
+ * @return FALSE on failure
+ */
+ bool (*select_label)(child_cfg_t *this, linked_list_t *labels, bool log,
+ sec_label_t **label, bool *exact);
+
/**
* Get the TFC padding value to use for CHILD_SA.
*