child-cfg: Add method to select a security label

This commit is contained in:
Tobias Brunner
2022-04-14 18:42:01 +02:00
parent ef72ac88c3
commit 63d4bd071f
2 changed files with 101 additions and 0 deletions
+80
View File
@@ -544,6 +544,85 @@ METHOD(child_cfg_t, get_label_mode, sec_label_mode_t,
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, &current))
{
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)
{
@@ -686,6 +765,7 @@ child_cfg_t *child_cfg_create(char *name, child_cfg_create_t *data)
.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,
+21
View File
@@ -261,6 +261,27 @@ struct child_cfg_t {
*/
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.
*