child-cfg: Add method to select a security label
This commit is contained in:
@@ -544,6 +544,85 @@ METHOD(child_cfg_t, get_label_mode, sec_label_mode_t,
|
|||||||
return this->label_mode;
|
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,
|
METHOD(child_cfg_t, get_tfc, uint32_t,
|
||||||
private_child_cfg_t *this)
|
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_set_mark = _get_set_mark,
|
||||||
.get_label = _get_label,
|
.get_label = _get_label,
|
||||||
.get_label_mode = _get_label_mode,
|
.get_label_mode = _get_label_mode,
|
||||||
|
.select_label = _select_label,
|
||||||
.get_tfc = _get_tfc,
|
.get_tfc = _get_tfc,
|
||||||
.get_manual_prio = _get_manual_prio,
|
.get_manual_prio = _get_manual_prio,
|
||||||
.get_interface = _get_interface,
|
.get_interface = _get_interface,
|
||||||
|
|||||||
@@ -261,6 +261,27 @@ struct child_cfg_t {
|
|||||||
*/
|
*/
|
||||||
sec_label_mode_t (*get_label_mode)(child_cfg_t *this);
|
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.
|
* Get the TFC padding value to use for CHILD_SA.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user