769 lines
17 KiB
C
769 lines
17 KiB
C
/*
|
|
* Copyright (C) 2007-2009 Martin Willi
|
|
* Copyright (C) 2008 Tobias Brunner
|
|
* Hochschule fuer Technik Rapperswil
|
|
*
|
|
* This program is free software; you can redistribute it and/or modify it
|
|
* under the terms of the GNU General Public License as published by the
|
|
* Free Software Foundation; either version 2 of the License, or (at your
|
|
* option) any later version. See <http://www.fsf.org/copyleft/gpl.txt>.
|
|
*
|
|
* This program is distributed in the hope that it will be useful, but
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
|
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
|
* for more details.
|
|
*/
|
|
|
|
#include "auth_cfg.h"
|
|
|
|
#include <daemon.h>
|
|
#include <utils/linked_list.h>
|
|
#include <utils/identification.h>
|
|
#include <credentials/certificates/certificate.h>
|
|
|
|
ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_SUBJECT_HASH_URL,
|
|
"RULE_IDENTITY",
|
|
"RULE_AUTH_CLASS",
|
|
"RULE_EAP_IDENTITY",
|
|
"RULE_EAP_TYPE",
|
|
"RULE_EAP_VENDOR",
|
|
"RULE_CA_CERT",
|
|
"RULE_IM_CERT",
|
|
"RULE_SUBJECT_CERT",
|
|
"RULE_CRL_VALIDATION",
|
|
"RULE_OCSP_VALIDATION",
|
|
"RULE_AC_GROUP",
|
|
"HELPER_IM_CERT",
|
|
"HELPER_SUBJECT_CERT",
|
|
"HELPER_IM_HASH_URL",
|
|
"HELPER_SUBJECT_HASH_URL",
|
|
);
|
|
|
|
typedef struct private_auth_cfg_t private_auth_cfg_t;
|
|
|
|
/**
|
|
* private data of item_set
|
|
*/
|
|
struct private_auth_cfg_t {
|
|
|
|
/**
|
|
* public functions
|
|
*/
|
|
auth_cfg_t public;
|
|
|
|
/**
|
|
* list of entry_t
|
|
*/
|
|
linked_list_t *entries;
|
|
};
|
|
|
|
typedef struct entry_t entry_t;
|
|
|
|
struct entry_t {
|
|
/** rule type */
|
|
auth_rule_t type;
|
|
/** associated value */
|
|
void *value;
|
|
};
|
|
|
|
/**
|
|
* enumerator for auth_cfg_t.create_enumerator()
|
|
*/
|
|
typedef struct {
|
|
/** implements enumerator_t */
|
|
enumerator_t public;
|
|
/** inner enumerator from linked_list_t */
|
|
enumerator_t *inner;
|
|
/** current entry */
|
|
entry_t *current;
|
|
} entry_enumerator_t;
|
|
|
|
/**
|
|
* enumerate function for item_enumerator_t
|
|
*/
|
|
static bool enumerate(entry_enumerator_t *this, auth_rule_t *type, void **value)
|
|
{
|
|
entry_t *entry;
|
|
|
|
if (this->inner->enumerate(this->inner, &entry))
|
|
{
|
|
this->current = entry;
|
|
*type = entry->type;
|
|
*value = entry->value;
|
|
return TRUE;
|
|
}
|
|
return FALSE;
|
|
}
|
|
|
|
/**
|
|
* destroy function for item_enumerator_t
|
|
*/
|
|
static void entry_enumerator_destroy(entry_enumerator_t *this)
|
|
{
|
|
this->inner->destroy(this->inner);
|
|
free(this);
|
|
}
|
|
|
|
/**
|
|
* Implementation of auth_cfg_t.create_enumerator.
|
|
*/
|
|
static enumerator_t* create_enumerator(private_auth_cfg_t *this)
|
|
{
|
|
entry_enumerator_t *enumerator;
|
|
|
|
enumerator = malloc_thing(entry_enumerator_t);
|
|
enumerator->inner = this->entries->create_enumerator(this->entries);
|
|
enumerator->public.enumerate = (void*)enumerate;
|
|
enumerator->public.destroy = (void*)entry_enumerator_destroy;
|
|
enumerator->current = NULL;
|
|
return &enumerator->public;
|
|
}
|
|
|
|
/**
|
|
* Destroy the value associated with an entry
|
|
*/
|
|
static void destroy_entry_value(entry_t *entry)
|
|
{
|
|
switch (entry->type)
|
|
{
|
|
case AUTH_RULE_IDENTITY:
|
|
case AUTH_RULE_EAP_IDENTITY:
|
|
case AUTH_RULE_AC_GROUP:
|
|
{
|
|
identification_t *id = (identification_t*)entry->value;
|
|
id->destroy(id);
|
|
break;
|
|
}
|
|
case AUTH_RULE_CA_CERT:
|
|
case AUTH_RULE_IM_CERT:
|
|
case AUTH_RULE_SUBJECT_CERT:
|
|
case AUTH_HELPER_IM_CERT:
|
|
case AUTH_HELPER_SUBJECT_CERT:
|
|
{
|
|
certificate_t *cert = (certificate_t*)entry->value;
|
|
cert->destroy(cert);
|
|
break;
|
|
}
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
{
|
|
free(entry->value);
|
|
break;
|
|
}
|
|
case AUTH_RULE_AUTH_CLASS:
|
|
case AUTH_RULE_EAP_TYPE:
|
|
case AUTH_RULE_EAP_VENDOR:
|
|
case AUTH_RULE_CRL_VALIDATION:
|
|
case AUTH_RULE_OCSP_VALIDATION:
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implementation of auth_cfg_t.replace.
|
|
*/
|
|
static void replace(auth_cfg_t *this, entry_enumerator_t *enumerator,
|
|
auth_rule_t type, ...)
|
|
{
|
|
if (enumerator->current)
|
|
{
|
|
va_list args;
|
|
|
|
va_start(args, type);
|
|
|
|
destroy_entry_value(enumerator->current);
|
|
enumerator->current->type = type;
|
|
switch (type)
|
|
{
|
|
case AUTH_RULE_AUTH_CLASS:
|
|
case AUTH_RULE_EAP_TYPE:
|
|
case AUTH_RULE_EAP_VENDOR:
|
|
case AUTH_RULE_CRL_VALIDATION:
|
|
case AUTH_RULE_OCSP_VALIDATION:
|
|
/* integer type */
|
|
enumerator->current->value = (void*)(uintptr_t)va_arg(args, u_int);
|
|
break;
|
|
case AUTH_RULE_IDENTITY:
|
|
case AUTH_RULE_EAP_IDENTITY:
|
|
case AUTH_RULE_AC_GROUP:
|
|
case AUTH_RULE_CA_CERT:
|
|
case AUTH_RULE_IM_CERT:
|
|
case AUTH_RULE_SUBJECT_CERT:
|
|
case AUTH_HELPER_IM_CERT:
|
|
case AUTH_HELPER_SUBJECT_CERT:
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
/* pointer type */
|
|
enumerator->current->value = va_arg(args, void*);
|
|
break;
|
|
}
|
|
va_end(args);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implementation of auth_cfg_t.get.
|
|
*/
|
|
static void* get(private_auth_cfg_t *this, auth_rule_t type)
|
|
{
|
|
enumerator_t *enumerator;
|
|
void *current_value, *best_value = NULL;
|
|
auth_rule_t current_type;
|
|
bool found = FALSE;
|
|
|
|
enumerator = create_enumerator(this);
|
|
while (enumerator->enumerate(enumerator, ¤t_type, ¤t_value))
|
|
{
|
|
if (type == current_type)
|
|
{
|
|
if (type == AUTH_RULE_CRL_VALIDATION ||
|
|
type == AUTH_RULE_OCSP_VALIDATION)
|
|
{ /* for CRL/OCSP validation, always get() the highest value */
|
|
if (!found || current_value > best_value)
|
|
{
|
|
best_value = current_value;
|
|
}
|
|
found = TRUE;
|
|
continue;
|
|
}
|
|
best_value = current_value;
|
|
found = TRUE;
|
|
break;
|
|
}
|
|
}
|
|
enumerator->destroy(enumerator);
|
|
if (found)
|
|
{
|
|
return best_value;
|
|
}
|
|
switch (type)
|
|
{
|
|
/* use some sane defaults if we don't find an entry */
|
|
case AUTH_RULE_AUTH_CLASS:
|
|
return (void*)AUTH_CLASS_ANY;
|
|
case AUTH_RULE_EAP_TYPE:
|
|
return (void*)EAP_NAK;
|
|
case AUTH_RULE_EAP_VENDOR:
|
|
return (void*)0;
|
|
case AUTH_RULE_CRL_VALIDATION:
|
|
case AUTH_RULE_OCSP_VALIDATION:
|
|
return (void*)VALIDATION_FAILED;
|
|
case AUTH_RULE_IDENTITY:
|
|
case AUTH_RULE_EAP_IDENTITY:
|
|
case AUTH_RULE_AC_GROUP:
|
|
case AUTH_RULE_CA_CERT:
|
|
case AUTH_RULE_IM_CERT:
|
|
case AUTH_RULE_SUBJECT_CERT:
|
|
case AUTH_HELPER_IM_CERT:
|
|
case AUTH_HELPER_SUBJECT_CERT:
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
default:
|
|
return NULL;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implementation of auth_cfg_t.add.
|
|
*/
|
|
static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
|
|
{
|
|
entry_t *entry = malloc_thing(entry_t);
|
|
va_list args;
|
|
|
|
va_start(args, type);
|
|
entry->type = type;
|
|
switch (type)
|
|
{
|
|
case AUTH_RULE_AUTH_CLASS:
|
|
case AUTH_RULE_EAP_TYPE:
|
|
case AUTH_RULE_EAP_VENDOR:
|
|
case AUTH_RULE_CRL_VALIDATION:
|
|
case AUTH_RULE_OCSP_VALIDATION:
|
|
/* integer type */
|
|
entry->value = (void*)(uintptr_t)va_arg(args, u_int);
|
|
break;
|
|
case AUTH_RULE_IDENTITY:
|
|
case AUTH_RULE_EAP_IDENTITY:
|
|
case AUTH_RULE_AC_GROUP:
|
|
case AUTH_RULE_CA_CERT:
|
|
case AUTH_RULE_IM_CERT:
|
|
case AUTH_RULE_SUBJECT_CERT:
|
|
case AUTH_HELPER_IM_CERT:
|
|
case AUTH_HELPER_SUBJECT_CERT:
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
/* pointer type */
|
|
entry->value = va_arg(args, void*);
|
|
break;
|
|
}
|
|
va_end(args);
|
|
this->entries->insert_last(this->entries, entry);
|
|
}
|
|
|
|
/**
|
|
* Implementation of auth_cfg_t.complies.
|
|
*/
|
|
static bool complies(private_auth_cfg_t *this, auth_cfg_t *constraints,
|
|
bool log_error)
|
|
{
|
|
enumerator_t *e1, *e2;
|
|
bool success = TRUE;
|
|
auth_rule_t t1, t2;
|
|
void *value;
|
|
|
|
e1 = constraints->create_enumerator(constraints);
|
|
while (e1->enumerate(e1, &t1, &value))
|
|
{
|
|
switch (t1)
|
|
{
|
|
case AUTH_RULE_CA_CERT:
|
|
case AUTH_RULE_IM_CERT:
|
|
{
|
|
certificate_t *c1, *c2;
|
|
|
|
c1 = (certificate_t*)value;
|
|
|
|
success = FALSE;
|
|
e2 = create_enumerator(this);
|
|
while (e2->enumerate(e2, &t2, &c2))
|
|
{
|
|
if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
|
|
c1->equals(c1, c2))
|
|
{
|
|
success = TRUE;
|
|
}
|
|
}
|
|
e2->destroy(e2);
|
|
if (!success && log_error)
|
|
{
|
|
DBG1(DBG_CFG, "constraint check failed: peer not "
|
|
"authenticated by CA '%Y'.", c1->get_subject(c1));
|
|
}
|
|
break;
|
|
}
|
|
case AUTH_RULE_SUBJECT_CERT:
|
|
{
|
|
certificate_t *c1, *c2;
|
|
|
|
c1 = (certificate_t*)value;
|
|
c2 = get(this, AUTH_RULE_SUBJECT_CERT);
|
|
if (!c2 || !c1->equals(c1, c2))
|
|
{
|
|
success = FALSE;
|
|
if (log_error)
|
|
{
|
|
DBG1(DBG_CFG, "constraint check failed: peer not "
|
|
"authenticated with peer cert '%Y'.",
|
|
c1->get_subject(c1));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case AUTH_RULE_CRL_VALIDATION:
|
|
case AUTH_RULE_OCSP_VALIDATION:
|
|
{
|
|
cert_validation_t validated, required;
|
|
|
|
required = (uintptr_t)value;
|
|
validated = (uintptr_t)get(this, t1);
|
|
switch (required)
|
|
{
|
|
case VALIDATION_FAILED:
|
|
/* no constraint */
|
|
break;
|
|
case VALIDATION_SKIPPED:
|
|
if (validated == VALIDATION_SKIPPED)
|
|
{
|
|
break;
|
|
}
|
|
/* FALL */
|
|
case VALIDATION_GOOD:
|
|
if (validated == VALIDATION_GOOD)
|
|
{
|
|
break;
|
|
}
|
|
/* FALL */
|
|
default:
|
|
success = FALSE;
|
|
if (log_error)
|
|
{
|
|
DBG1(DBG_CFG, "constraint check failed: %N is %N, "
|
|
"but requires at least %N", auth_rule_names,
|
|
t1, cert_validation_names, validated,
|
|
cert_validation_names, required);
|
|
}
|
|
break;
|
|
}
|
|
break;
|
|
}
|
|
case AUTH_RULE_IDENTITY:
|
|
case AUTH_RULE_EAP_IDENTITY:
|
|
{
|
|
identification_t *id1, *id2;
|
|
|
|
id1 = (identification_t*)value;
|
|
id2 = get(this, t1);
|
|
if (!id2 || !id2->matches(id2, id1))
|
|
{
|
|
success = FALSE;
|
|
if (log_error)
|
|
{
|
|
DBG1(DBG_CFG, "constraint check failed: %sidentity '%Y'"
|
|
" required ", t1 == AUTH_RULE_IDENTITY ? "" :
|
|
"EAP ", id1);
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case AUTH_RULE_AUTH_CLASS:
|
|
{
|
|
if ((uintptr_t)value != AUTH_CLASS_ANY &&
|
|
(uintptr_t)value != (uintptr_t)get(this, t1))
|
|
{
|
|
success = FALSE;
|
|
if (log_error)
|
|
{
|
|
DBG1(DBG_CFG, "constraint requires %N authentication, "
|
|
"but %N was used", auth_class_names, (uintptr_t)value,
|
|
auth_class_names, (uintptr_t)get(this, t1));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case AUTH_RULE_EAP_TYPE:
|
|
{
|
|
if ((uintptr_t)value != (uintptr_t)get(this, t1))
|
|
{
|
|
success = FALSE;
|
|
if (log_error)
|
|
{
|
|
DBG1(DBG_CFG, "constraint requires %N, "
|
|
"but %N was used", eap_type_names, (uintptr_t)value,
|
|
eap_type_names, (uintptr_t)get(this, t1));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case AUTH_RULE_EAP_VENDOR:
|
|
{
|
|
if ((uintptr_t)value != (uintptr_t)get(this, t1))
|
|
{
|
|
success = FALSE;
|
|
if (log_error)
|
|
{
|
|
DBG1(DBG_CFG, "constraint requires EAP vendor %d, "
|
|
"but %d was used", (uintptr_t)value,
|
|
(uintptr_t)get(this, t1));
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
case AUTH_RULE_AC_GROUP:
|
|
{
|
|
success = FALSE;
|
|
if (log_error)
|
|
{
|
|
DBG1(DBG_CFG, "constraint check %N not implemented!",
|
|
auth_rule_names, t1);
|
|
}
|
|
break;
|
|
}
|
|
case AUTH_HELPER_IM_CERT:
|
|
case AUTH_HELPER_SUBJECT_CERT:
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
/* skip helpers */
|
|
continue;
|
|
}
|
|
if (!success)
|
|
{
|
|
break;
|
|
}
|
|
}
|
|
e1->destroy(e1);
|
|
return success;
|
|
}
|
|
|
|
/**
|
|
* Implementation of auth_cfg_t.merge.
|
|
*/
|
|
static void merge(private_auth_cfg_t *this, private_auth_cfg_t *other, bool copy)
|
|
{
|
|
if (!other)
|
|
{ /* nothing to merge */
|
|
return;
|
|
}
|
|
if (copy)
|
|
{
|
|
enumerator_t *enumerator;
|
|
auth_rule_t type;
|
|
void *value;
|
|
|
|
enumerator = create_enumerator(other);
|
|
while (enumerator->enumerate(enumerator, &type, &value))
|
|
{
|
|
switch (type)
|
|
{
|
|
case AUTH_RULE_CA_CERT:
|
|
case AUTH_RULE_IM_CERT:
|
|
case AUTH_RULE_SUBJECT_CERT:
|
|
case AUTH_HELPER_IM_CERT:
|
|
case AUTH_HELPER_SUBJECT_CERT:
|
|
{
|
|
certificate_t *cert = (certificate_t*)value;
|
|
|
|
add(this, type, cert->get_ref(cert));
|
|
break;
|
|
}
|
|
case AUTH_RULE_CRL_VALIDATION:
|
|
case AUTH_RULE_OCSP_VALIDATION:
|
|
case AUTH_RULE_AUTH_CLASS:
|
|
case AUTH_RULE_EAP_TYPE:
|
|
case AUTH_RULE_EAP_VENDOR:
|
|
{
|
|
add(this, type, (uintptr_t)value);
|
|
break;
|
|
}
|
|
case AUTH_RULE_IDENTITY:
|
|
case AUTH_RULE_EAP_IDENTITY:
|
|
case AUTH_RULE_AC_GROUP:
|
|
{
|
|
identification_t *id = (identification_t*)value;
|
|
|
|
add(this, type, id->clone(id));
|
|
break;
|
|
}
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
{
|
|
add(this, type, strdup((char*)value));
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
enumerator->destroy(enumerator);
|
|
}
|
|
else
|
|
{
|
|
entry_t *entry;
|
|
|
|
while (other->entries->remove_first(other->entries,
|
|
(void**)&entry) == SUCCESS)
|
|
{
|
|
this->entries->insert_last(this->entries, entry);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Implementation of auth_cfg_t.equals.
|
|
*/
|
|
static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
|
|
{
|
|
enumerator_t *e1, *e2;
|
|
entry_t *i1, *i2;
|
|
bool equal = TRUE, found;
|
|
|
|
if (this->entries->get_count(this->entries) !=
|
|
other->entries->get_count(other->entries))
|
|
{
|
|
return FALSE;
|
|
}
|
|
e1 = this->entries->create_enumerator(this->entries);
|
|
while (e1->enumerate(e1, &i1))
|
|
{
|
|
found = FALSE;
|
|
e2 = other->entries->create_enumerator(other->entries);
|
|
while (e2->enumerate(e2, &i2))
|
|
{
|
|
if (i1->type == i2->type)
|
|
{
|
|
switch (i1->type)
|
|
{
|
|
case AUTH_RULE_AUTH_CLASS:
|
|
case AUTH_RULE_EAP_TYPE:
|
|
case AUTH_RULE_EAP_VENDOR:
|
|
case AUTH_RULE_CRL_VALIDATION:
|
|
case AUTH_RULE_OCSP_VALIDATION:
|
|
{
|
|
if (i1->value == i2->value)
|
|
{
|
|
found = TRUE;
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
case AUTH_RULE_CA_CERT:
|
|
case AUTH_RULE_IM_CERT:
|
|
case AUTH_RULE_SUBJECT_CERT:
|
|
case AUTH_HELPER_IM_CERT:
|
|
case AUTH_HELPER_SUBJECT_CERT:
|
|
{
|
|
certificate_t *c1, *c2;
|
|
|
|
c1 = (certificate_t*)i1->value;
|
|
c2 = (certificate_t*)i2->value;
|
|
|
|
if (c1->equals(c1, c2))
|
|
{
|
|
found = TRUE;
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
case AUTH_RULE_IDENTITY:
|
|
case AUTH_RULE_EAP_IDENTITY:
|
|
case AUTH_RULE_AC_GROUP:
|
|
{
|
|
identification_t *id1, *id2;
|
|
|
|
id1 = (identification_t*)i1->value;
|
|
id2 = (identification_t*)i2->value;
|
|
|
|
if (id1->equals(id1, id2))
|
|
{
|
|
found = TRUE;
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
{
|
|
if (streq(i1->value, i2->value))
|
|
{
|
|
found = TRUE;
|
|
break;
|
|
}
|
|
continue;
|
|
}
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
e2->destroy(e2);
|
|
if (!found)
|
|
{
|
|
equal = FALSE;
|
|
break;
|
|
}
|
|
}
|
|
e1->destroy(e1);
|
|
return equal;
|
|
}
|
|
|
|
/**
|
|
* Implementation of auth_cfg_t.purge
|
|
*/
|
|
static void purge(private_auth_cfg_t *this, bool keep_ca)
|
|
{
|
|
entry_t *entry;
|
|
linked_list_t *cas;
|
|
|
|
cas = linked_list_create();
|
|
while (this->entries->remove_last(this->entries, (void**)&entry) == SUCCESS)
|
|
{
|
|
if (keep_ca && entry->type == AUTH_RULE_CA_CERT)
|
|
{
|
|
cas->insert_first(cas, entry);
|
|
}
|
|
else
|
|
{
|
|
destroy_entry_value(entry);
|
|
free(entry);
|
|
}
|
|
}
|
|
while (cas->remove_last(cas, (void**)&entry) == SUCCESS)
|
|
{
|
|
this->entries->insert_first(this->entries, entry);
|
|
}
|
|
cas->destroy(cas);
|
|
}
|
|
|
|
/**
|
|
* Implementation of auth_cfg_t.clone
|
|
*/
|
|
static auth_cfg_t* clone_(private_auth_cfg_t *this)
|
|
{
|
|
enumerator_t *enumerator;
|
|
auth_cfg_t *clone;
|
|
entry_t *entry;
|
|
|
|
clone = auth_cfg_create();
|
|
enumerator = this->entries->create_enumerator(this->entries);
|
|
while (enumerator->enumerate(enumerator, &entry))
|
|
{
|
|
switch (entry->type)
|
|
{
|
|
case AUTH_RULE_IDENTITY:
|
|
case AUTH_RULE_EAP_IDENTITY:
|
|
case AUTH_RULE_AC_GROUP:
|
|
{
|
|
identification_t *id = (identification_t*)entry->value;
|
|
clone->add(clone, entry->type, id->clone(id));
|
|
break;
|
|
}
|
|
case AUTH_RULE_CA_CERT:
|
|
case AUTH_RULE_IM_CERT:
|
|
case AUTH_RULE_SUBJECT_CERT:
|
|
case AUTH_HELPER_IM_CERT:
|
|
case AUTH_HELPER_SUBJECT_CERT:
|
|
{
|
|
certificate_t *cert = (certificate_t*)entry->value;
|
|
clone->add(clone, entry->type, cert->get_ref(cert));
|
|
break;
|
|
}
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
{
|
|
clone->add(clone, entry->type, strdup(entry->value));
|
|
break;
|
|
}
|
|
case AUTH_RULE_AUTH_CLASS:
|
|
case AUTH_RULE_EAP_TYPE:
|
|
case AUTH_RULE_EAP_VENDOR:
|
|
case AUTH_RULE_CRL_VALIDATION:
|
|
case AUTH_RULE_OCSP_VALIDATION:
|
|
clone->add(clone, entry->type, (uintptr_t)entry->value);
|
|
break;
|
|
}
|
|
}
|
|
enumerator->destroy(enumerator);
|
|
return clone;
|
|
}
|
|
|
|
/**
|
|
* Implementation of auth_cfg_t.destroy
|
|
*/
|
|
static void destroy(private_auth_cfg_t *this)
|
|
{
|
|
purge(this, FALSE);
|
|
this->entries->destroy(this->entries);
|
|
free(this);
|
|
}
|
|
|
|
/*
|
|
* see header file
|
|
*/
|
|
auth_cfg_t *auth_cfg_create()
|
|
{
|
|
private_auth_cfg_t *this = malloc_thing(private_auth_cfg_t);
|
|
|
|
this->public.add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add;
|
|
this->public.get = (void*(*)(auth_cfg_t*, auth_rule_t type))get;
|
|
this->public.create_enumerator = (enumerator_t*(*)(auth_cfg_t*))create_enumerator;
|
|
this->public.replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace;
|
|
this->public.complies = (bool(*)(auth_cfg_t*, auth_cfg_t *,bool))complies;
|
|
this->public.merge = (void(*)(auth_cfg_t*, auth_cfg_t *other,bool))merge;
|
|
this->public.purge = (void(*)(auth_cfg_t*,bool))purge;
|
|
this->public.equals = (bool(*)(auth_cfg_t*, auth_cfg_t *other))equals;
|
|
this->public.clone = (auth_cfg_t*(*)(auth_cfg_t*))clone_;
|
|
this->public.destroy = (void(*)(auth_cfg_t*))destroy;
|
|
|
|
this->entries = linked_list_create();
|
|
|
|
return &this->public;
|
|
}
|
|
|