2009-04-14 10:34:24 +00:00
|
|
|
/*
|
2017-10-13 13:02:02 +00:00
|
|
|
* Copyright (C) 2008-2017 Tobias Brunner
|
2009-04-14 10:34:24 +00:00
|
|
|
* Copyright (C) 2007-2009 Martin Willi
|
2016-12-09 08:38:15 +00:00
|
|
|
* Copyright (C) 2016 Andreas Steffen
|
2016-09-22 06:50:43 +00:00
|
|
|
* HSR Hochschule fuer Technik Rapperswil
|
2009-04-14 10:34:24 +00:00
|
|
|
*
|
|
|
|
* 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"
|
|
|
|
|
2010-07-05 09:54:25 +00:00
|
|
|
#include <library.h>
|
2012-10-16 14:03:21 +00:00
|
|
|
#include <utils/debug.h>
|
2013-07-11 14:54:15 +00:00
|
|
|
#include <collections/array.h>
|
2009-04-14 10:34:24 +00:00
|
|
|
#include <utils/identification.h>
|
2010-08-31 06:55:48 +00:00
|
|
|
#include <eap/eap.h>
|
2009-04-14 10:34:24 +00:00
|
|
|
#include <credentials/certificates/certificate.h>
|
|
|
|
|
2011-12-09 14:22:30 +00:00
|
|
|
ENUM(auth_class_names, AUTH_CLASS_ANY, AUTH_CLASS_XAUTH,
|
2010-07-05 09:54:25 +00:00
|
|
|
"any",
|
|
|
|
"public key",
|
|
|
|
"pre-shared key",
|
|
|
|
"EAP",
|
2011-12-09 14:22:30 +00:00
|
|
|
"XAuth",
|
2010-07-05 09:54:25 +00:00
|
|
|
);
|
|
|
|
|
2014-02-05 16:15:45 +00:00
|
|
|
ENUM(auth_rule_names, AUTH_RULE_IDENTITY, AUTH_HELPER_AC_CERT,
|
2011-08-04 08:27:05 +00:00
|
|
|
"RULE_IDENTITY",
|
2012-09-18 09:16:10 +00:00
|
|
|
"RULE_IDENTITY_LOOSE",
|
2011-08-04 08:27:05 +00:00
|
|
|
"RULE_AUTH_CLASS",
|
2011-08-04 08:29:23 +00:00
|
|
|
"RULE_AAA_IDENTITY",
|
2011-08-04 08:27:05 +00:00
|
|
|
"RULE_EAP_IDENTITY",
|
|
|
|
"RULE_EAP_TYPE",
|
|
|
|
"RULE_EAP_VENDOR",
|
2011-12-08 15:53:27 +00:00
|
|
|
"RULE_XAUTH_BACKEND",
|
2011-12-15 10:58:26 +00:00
|
|
|
"RULE_XAUTH_IDENTITY",
|
2019-11-28 07:14:59 +00:00
|
|
|
"AUTH_RULE_CA_IDENTITY",
|
2011-08-04 08:27:05 +00:00
|
|
|
"RULE_CA_CERT",
|
|
|
|
"RULE_IM_CERT",
|
|
|
|
"RULE_SUBJECT_CERT",
|
|
|
|
"RULE_CRL_VALIDATION",
|
|
|
|
"RULE_OCSP_VALIDATION",
|
2015-10-27 16:21:18 +00:00
|
|
|
"RULE_CERT_VALIDATION_SUSPENDED",
|
2011-08-04 08:27:05 +00:00
|
|
|
"RULE_GROUP",
|
2011-08-04 08:29:23 +00:00
|
|
|
"RULE_RSA_STRENGTH",
|
|
|
|
"RULE_ECDSA_STRENGTH",
|
2015-03-02 14:49:53 +00:00
|
|
|
"RULE_BLISS_STRENGTH",
|
2012-06-08 14:47:08 +00:00
|
|
|
"RULE_SIGNATURE_SCHEME",
|
2016-02-01 17:15:15 +00:00
|
|
|
"RULE_IKE_SIGNATURE_SCHEME",
|
2011-08-04 08:29:23 +00:00
|
|
|
"RULE_CERT_POLICY",
|
2011-08-04 08:27:05 +00:00
|
|
|
"HELPER_IM_CERT",
|
|
|
|
"HELPER_SUBJECT_CERT",
|
|
|
|
"HELPER_IM_HASH_URL",
|
|
|
|
"HELPER_SUBJECT_HASH_URL",
|
2011-08-04 08:29:23 +00:00
|
|
|
"HELPER_REVOCATION_CERT",
|
2014-02-05 16:15:45 +00:00
|
|
|
"HELPER_AC_CERT",
|
2011-08-04 08:27:05 +00:00
|
|
|
);
|
|
|
|
|
2012-04-17 15:37:30 +00:00
|
|
|
/**
|
|
|
|
* Check if the given rule is a rule for which there may be multiple values.
|
|
|
|
*/
|
|
|
|
static inline bool is_multi_value_rule(auth_rule_t type)
|
|
|
|
{
|
|
|
|
switch (type)
|
|
|
|
{
|
|
|
|
case AUTH_RULE_AUTH_CLASS:
|
|
|
|
case AUTH_RULE_EAP_TYPE:
|
|
|
|
case AUTH_RULE_EAP_VENDOR:
|
|
|
|
case AUTH_RULE_IDENTITY:
|
2012-09-18 09:16:10 +00:00
|
|
|
case AUTH_RULE_IDENTITY_LOOSE:
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_RULE_EAP_IDENTITY:
|
|
|
|
case AUTH_RULE_AAA_IDENTITY:
|
2012-05-02 09:12:31 +00:00
|
|
|
case AUTH_RULE_XAUTH_IDENTITY:
|
|
|
|
case AUTH_RULE_XAUTH_BACKEND:
|
2015-10-27 16:21:18 +00:00
|
|
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_HELPER_SUBJECT_CERT:
|
|
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
|
|
case AUTH_RULE_MAX:
|
|
|
|
return FALSE;
|
|
|
|
case AUTH_RULE_OCSP_VALIDATION:
|
|
|
|
case AUTH_RULE_CRL_VALIDATION:
|
|
|
|
case AUTH_RULE_GROUP:
|
2013-01-08 10:37:32 +00:00
|
|
|
case AUTH_RULE_SUBJECT_CERT:
|
2019-11-28 07:14:59 +00:00
|
|
|
case AUTH_RULE_CA_IDENTITY:
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_RULE_CA_CERT:
|
|
|
|
case AUTH_RULE_IM_CERT:
|
|
|
|
case AUTH_RULE_CERT_POLICY:
|
2018-01-23 11:01:02 +00:00
|
|
|
case AUTH_RULE_RSA_STRENGTH:
|
|
|
|
case AUTH_RULE_ECDSA_STRENGTH:
|
|
|
|
case AUTH_RULE_BLISS_STRENGTH:
|
2012-06-08 14:47:08 +00:00
|
|
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
2016-02-01 17:15:15 +00:00
|
|
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_HELPER_IM_CERT:
|
|
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
|
|
case AUTH_HELPER_REVOCATION_CERT:
|
2014-02-05 16:15:45 +00:00
|
|
|
case AUTH_HELPER_AC_CERT:
|
2012-04-17 15:37:30 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
typedef struct private_auth_cfg_t private_auth_cfg_t;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* private data of item_set
|
|
|
|
*/
|
|
|
|
struct private_auth_cfg_t {
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
/**
|
|
|
|
* public functions
|
|
|
|
*/
|
|
|
|
auth_cfg_t public;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
/**
|
2013-07-11 14:54:15 +00:00
|
|
|
* Array of entry_t
|
2009-04-14 10:34:24 +00:00
|
|
|
*/
|
2013-07-11 14:54:15 +00:00
|
|
|
array_t *entries;
|
2009-04-14 10:34:24 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
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;
|
2012-04-17 15:37:30 +00:00
|
|
|
/** types we have already enumerated */
|
|
|
|
bool enumerated[AUTH_RULE_MAX];
|
2009-04-14 10:34:24 +00:00
|
|
|
} entry_enumerator_t;
|
|
|
|
|
2017-05-11 07:17:02 +00:00
|
|
|
METHOD(enumerator_t, enumerate, bool,
|
|
|
|
entry_enumerator_t *this, va_list args)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2017-05-11 07:17:02 +00:00
|
|
|
auth_rule_t *type;
|
2009-04-14 10:34:24 +00:00
|
|
|
entry_t *entry;
|
2017-05-11 07:17:02 +00:00
|
|
|
void **value;
|
|
|
|
|
|
|
|
VA_ARGS_VGET(args, type, value);
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2012-04-17 15:37:30 +00:00
|
|
|
while (this->inner->enumerate(this->inner, &entry))
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2012-04-17 15:37:30 +00:00
|
|
|
if (!is_multi_value_rule(entry->type) && this->enumerated[entry->type])
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
this->enumerated[entry->type] = TRUE;
|
2009-04-14 10:34:24 +00:00
|
|
|
this->current = entry;
|
2012-04-17 15:37:30 +00:00
|
|
|
if (type)
|
|
|
|
{
|
|
|
|
*type = entry->type;
|
|
|
|
}
|
|
|
|
if (value)
|
|
|
|
{
|
|
|
|
*value = entry->value;
|
|
|
|
}
|
2009-04-14 10:34:24 +00:00
|
|
|
return TRUE;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2017-05-11 07:17:02 +00:00
|
|
|
METHOD(enumerator_t, entry_enumerator_destroy, void,
|
|
|
|
entry_enumerator_t *this)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
this->inner->destroy(this->inner);
|
|
|
|
free(this);
|
|
|
|
}
|
|
|
|
|
2011-10-02 08:42:01 +00:00
|
|
|
METHOD(auth_cfg_t, create_enumerator, enumerator_t*,
|
|
|
|
private_auth_cfg_t *this)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
entry_enumerator_t *enumerator;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2012-04-17 15:37:30 +00:00
|
|
|
INIT(enumerator,
|
|
|
|
.public = {
|
2017-05-11 07:17:02 +00:00
|
|
|
.enumerate = enumerator_enumerate_default,
|
|
|
|
.venumerate = _enumerate,
|
|
|
|
.destroy = _entry_enumerator_destroy,
|
2012-04-17 15:37:30 +00:00
|
|
|
},
|
2013-07-11 14:54:15 +00:00
|
|
|
.inner = array_create_enumerator(this->entries),
|
2012-04-17 15:37:30 +00:00
|
|
|
);
|
2009-04-14 10:34:24 +00:00
|
|
|
return &enumerator->public;
|
|
|
|
}
|
|
|
|
|
2012-04-17 15:37:30 +00:00
|
|
|
/**
|
2013-07-11 14:54:15 +00:00
|
|
|
* Initialize an entry.
|
2012-04-17 15:37:30 +00:00
|
|
|
*/
|
2013-07-11 14:54:15 +00:00
|
|
|
static void init_entry(entry_t *this, auth_rule_t type, va_list args)
|
2012-04-17 15:37:30 +00:00
|
|
|
{
|
|
|
|
this->type = type;
|
|
|
|
switch (type)
|
|
|
|
{
|
2012-09-18 09:16:10 +00:00
|
|
|
case AUTH_RULE_IDENTITY_LOOSE:
|
2012-04-17 15:37:30 +00:00
|
|
|
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:
|
|
|
|
case AUTH_RULE_RSA_STRENGTH:
|
|
|
|
case AUTH_RULE_ECDSA_STRENGTH:
|
2015-03-02 14:49:53 +00:00
|
|
|
case AUTH_RULE_BLISS_STRENGTH:
|
2015-10-27 16:21:18 +00:00
|
|
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
2012-04-17 15:37:30 +00:00
|
|
|
/* integer type */
|
|
|
|
this->value = (void*)(uintptr_t)va_arg(args, u_int);
|
|
|
|
break;
|
|
|
|
case AUTH_RULE_IDENTITY:
|
|
|
|
case AUTH_RULE_EAP_IDENTITY:
|
|
|
|
case AUTH_RULE_AAA_IDENTITY:
|
2012-05-02 09:12:31 +00:00
|
|
|
case AUTH_RULE_XAUTH_BACKEND:
|
|
|
|
case AUTH_RULE_XAUTH_IDENTITY:
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_RULE_GROUP:
|
2019-11-28 07:14:59 +00:00
|
|
|
case AUTH_RULE_CA_IDENTITY:
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_RULE_CA_CERT:
|
|
|
|
case AUTH_RULE_IM_CERT:
|
|
|
|
case AUTH_RULE_SUBJECT_CERT:
|
|
|
|
case AUTH_RULE_CERT_POLICY:
|
2017-10-13 13:02:02 +00:00
|
|
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
|
|
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_HELPER_IM_CERT:
|
|
|
|
case AUTH_HELPER_SUBJECT_CERT:
|
|
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
|
|
case AUTH_HELPER_REVOCATION_CERT:
|
2014-02-05 16:15:45 +00:00
|
|
|
case AUTH_HELPER_AC_CERT:
|
2012-04-17 15:37:30 +00:00
|
|
|
/* pointer type */
|
|
|
|
this->value = va_arg(args, void*);
|
|
|
|
break;
|
|
|
|
case AUTH_RULE_MAX:
|
|
|
|
this->value = NULL;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Compare two entries for equality.
|
|
|
|
*/
|
|
|
|
static bool entry_equals(entry_t *e1, entry_t *e2)
|
|
|
|
{
|
|
|
|
if (e1->type != e2->type)
|
|
|
|
{
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
switch (e1->type)
|
|
|
|
{
|
2012-09-18 09:16:10 +00:00
|
|
|
case AUTH_RULE_IDENTITY_LOOSE:
|
2012-04-17 15:37:30 +00:00
|
|
|
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:
|
|
|
|
case AUTH_RULE_RSA_STRENGTH:
|
|
|
|
case AUTH_RULE_ECDSA_STRENGTH:
|
2015-03-02 14:49:53 +00:00
|
|
|
case AUTH_RULE_BLISS_STRENGTH:
|
2015-10-27 16:21:18 +00:00
|
|
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
2012-04-17 15:37:30 +00:00
|
|
|
{
|
|
|
|
return e1->value == e2->value;
|
|
|
|
}
|
|
|
|
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_REVOCATION_CERT:
|
2014-02-05 16:15:45 +00:00
|
|
|
case AUTH_HELPER_AC_CERT:
|
2012-04-17 15:37:30 +00:00
|
|
|
{
|
|
|
|
certificate_t *c1, *c2;
|
|
|
|
|
|
|
|
c1 = (certificate_t*)e1->value;
|
|
|
|
c2 = (certificate_t*)e2->value;
|
|
|
|
|
|
|
|
return c1->equals(c1, c2);
|
|
|
|
}
|
|
|
|
case AUTH_RULE_IDENTITY:
|
2019-11-28 07:14:59 +00:00
|
|
|
case AUTH_RULE_CA_IDENTITY:
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_RULE_EAP_IDENTITY:
|
|
|
|
case AUTH_RULE_AAA_IDENTITY:
|
2012-05-02 09:12:31 +00:00
|
|
|
case AUTH_RULE_XAUTH_IDENTITY:
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_RULE_GROUP:
|
|
|
|
{
|
|
|
|
identification_t *id1, *id2;
|
|
|
|
|
|
|
|
id1 = (identification_t*)e1->value;
|
|
|
|
id2 = (identification_t*)e2->value;
|
|
|
|
|
|
|
|
return id1->equals(id1, id2);
|
|
|
|
}
|
2017-10-13 13:02:02 +00:00
|
|
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
|
|
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
|
|
|
{
|
|
|
|
return signature_params_equal(e1->value, e2->value);
|
|
|
|
}
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_RULE_CERT_POLICY:
|
2012-05-02 09:12:31 +00:00
|
|
|
case AUTH_RULE_XAUTH_BACKEND:
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
|
|
{
|
|
|
|
return streq(e1->value, e2->value);
|
|
|
|
}
|
|
|
|
case AUTH_RULE_MAX:
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
/**
|
|
|
|
* Destroy the value associated with an entry
|
|
|
|
*/
|
|
|
|
static void destroy_entry_value(entry_t *entry)
|
|
|
|
{
|
|
|
|
switch (entry->type)
|
|
|
|
{
|
|
|
|
case AUTH_RULE_IDENTITY:
|
2019-11-28 07:14:59 +00:00
|
|
|
case AUTH_RULE_CA_IDENTITY:
|
2009-04-14 10:34:24 +00:00
|
|
|
case AUTH_RULE_EAP_IDENTITY:
|
2010-08-31 15:26:20 +00:00
|
|
|
case AUTH_RULE_AAA_IDENTITY:
|
2010-06-28 13:46:13 +00:00
|
|
|
case AUTH_RULE_GROUP:
|
2011-12-15 10:58:26 +00:00
|
|
|
case AUTH_RULE_XAUTH_IDENTITY:
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
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:
|
2010-12-23 11:17:49 +00:00
|
|
|
case AUTH_HELPER_REVOCATION_CERT:
|
2014-02-05 16:15:45 +00:00
|
|
|
case AUTH_HELPER_AC_CERT:
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
certificate_t *cert = (certificate_t*)entry->value;
|
|
|
|
cert->destroy(cert);
|
|
|
|
break;
|
|
|
|
}
|
2010-12-16 10:25:32 +00:00
|
|
|
case AUTH_RULE_CERT_POLICY:
|
2011-12-08 15:53:27 +00:00
|
|
|
case AUTH_RULE_XAUTH_BACKEND:
|
2009-04-14 10:34:24 +00:00
|
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
|
|
{
|
|
|
|
free(entry->value);
|
|
|
|
break;
|
|
|
|
}
|
2017-10-13 13:02:02 +00:00
|
|
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
|
|
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
|
|
|
{
|
|
|
|
signature_params_destroy(entry->value);
|
|
|
|
break;
|
|
|
|
}
|
2012-09-18 09:16:10 +00:00
|
|
|
case AUTH_RULE_IDENTITY_LOOSE:
|
2009-04-14 10:34:24 +00:00
|
|
|
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:
|
2010-11-25 14:26:51 +00:00
|
|
|
case AUTH_RULE_RSA_STRENGTH:
|
|
|
|
case AUTH_RULE_ECDSA_STRENGTH:
|
2015-03-02 14:49:53 +00:00
|
|
|
case AUTH_RULE_BLISS_STRENGTH:
|
2015-10-27 16:21:18 +00:00
|
|
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_RULE_MAX:
|
2009-04-14 10:34:24 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implementation of auth_cfg_t.replace.
|
|
|
|
*/
|
2011-10-02 08:42:01 +00:00
|
|
|
static void replace(private_auth_cfg_t *this, entry_enumerator_t *enumerator,
|
2009-04-14 10:34:24 +00:00
|
|
|
auth_rule_t type, ...)
|
|
|
|
{
|
|
|
|
if (enumerator->current)
|
|
|
|
{
|
2012-04-17 15:44:10 +00:00
|
|
|
entry_t *entry;
|
2009-04-14 10:34:24 +00:00
|
|
|
va_list args;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
va_start(args, type);
|
2012-04-17 15:44:10 +00:00
|
|
|
entry = enumerator->current;
|
|
|
|
destroy_entry_value(entry);
|
|
|
|
entry->type = type;
|
|
|
|
switch (type)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2012-09-18 09:16:10 +00:00
|
|
|
case AUTH_RULE_IDENTITY_LOOSE:
|
2012-04-17 15:44:10 +00:00
|
|
|
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:
|
|
|
|
case AUTH_RULE_RSA_STRENGTH:
|
|
|
|
case AUTH_RULE_ECDSA_STRENGTH:
|
2015-03-02 14:49:53 +00:00
|
|
|
case AUTH_RULE_BLISS_STRENGTH:
|
2015-10-27 16:21:18 +00:00
|
|
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
2012-04-17 15:44:10 +00:00
|
|
|
/* integer type */
|
|
|
|
entry->value = (void*)(uintptr_t)va_arg(args, u_int);
|
|
|
|
break;
|
|
|
|
case AUTH_RULE_IDENTITY:
|
2019-11-28 07:14:59 +00:00
|
|
|
case AUTH_RULE_CA_IDENTITY:
|
2012-04-17 15:44:10 +00:00
|
|
|
case AUTH_RULE_EAP_IDENTITY:
|
|
|
|
case AUTH_RULE_AAA_IDENTITY:
|
2011-12-08 15:53:27 +00:00
|
|
|
case AUTH_RULE_XAUTH_BACKEND:
|
2011-12-15 10:58:26 +00:00
|
|
|
case AUTH_RULE_XAUTH_IDENTITY:
|
2012-04-17 15:44:10 +00:00
|
|
|
case AUTH_RULE_GROUP:
|
|
|
|
case AUTH_RULE_CA_CERT:
|
|
|
|
case AUTH_RULE_IM_CERT:
|
|
|
|
case AUTH_RULE_SUBJECT_CERT:
|
|
|
|
case AUTH_RULE_CERT_POLICY:
|
2017-10-13 13:02:02 +00:00
|
|
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
|
|
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
2012-04-17 15:44:10 +00:00
|
|
|
case AUTH_HELPER_IM_CERT:
|
|
|
|
case AUTH_HELPER_SUBJECT_CERT:
|
|
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
|
|
case AUTH_HELPER_REVOCATION_CERT:
|
2014-02-05 16:15:45 +00:00
|
|
|
case AUTH_HELPER_AC_CERT:
|
2012-04-17 15:44:10 +00:00
|
|
|
/* pointer type */
|
|
|
|
entry->value = va_arg(args, void*);
|
|
|
|
break;
|
|
|
|
case AUTH_RULE_MAX:
|
|
|
|
entry->value = NULL;
|
|
|
|
break;
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
2012-04-17 15:44:10 +00:00
|
|
|
va_end(args);
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-10-02 08:42:01 +00:00
|
|
|
METHOD(auth_cfg_t, get, void*,
|
|
|
|
private_auth_cfg_t *this, auth_rule_t type)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
enumerator_t *enumerator;
|
|
|
|
void *current_value, *best_value = NULL;
|
|
|
|
auth_rule_t current_type;
|
|
|
|
bool found = FALSE;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
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:
|
2010-11-25 14:26:51 +00:00
|
|
|
case AUTH_RULE_RSA_STRENGTH:
|
|
|
|
case AUTH_RULE_ECDSA_STRENGTH:
|
2015-03-02 14:49:53 +00:00
|
|
|
case AUTH_RULE_BLISS_STRENGTH:
|
2009-04-14 10:34:24 +00:00
|
|
|
return (void*)0;
|
|
|
|
case AUTH_RULE_CRL_VALIDATION:
|
|
|
|
case AUTH_RULE_OCSP_VALIDATION:
|
|
|
|
return (void*)VALIDATION_FAILED;
|
2012-09-18 09:16:10 +00:00
|
|
|
case AUTH_RULE_IDENTITY_LOOSE:
|
2015-10-27 16:21:18 +00:00
|
|
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
2012-09-18 09:16:10 +00:00
|
|
|
return (void*)FALSE;
|
2009-04-14 10:34:24 +00:00
|
|
|
case AUTH_RULE_IDENTITY:
|
2019-11-28 07:14:59 +00:00
|
|
|
case AUTH_RULE_CA_IDENTITY:
|
2009-04-14 10:34:24 +00:00
|
|
|
case AUTH_RULE_EAP_IDENTITY:
|
2010-08-31 15:26:20 +00:00
|
|
|
case AUTH_RULE_AAA_IDENTITY:
|
2011-12-08 15:53:27 +00:00
|
|
|
case AUTH_RULE_XAUTH_BACKEND:
|
2011-12-15 10:58:26 +00:00
|
|
|
case AUTH_RULE_XAUTH_IDENTITY:
|
2010-06-28 13:46:13 +00:00
|
|
|
case AUTH_RULE_GROUP:
|
2009-04-14 10:34:24 +00:00
|
|
|
case AUTH_RULE_CA_CERT:
|
|
|
|
case AUTH_RULE_IM_CERT:
|
|
|
|
case AUTH_RULE_SUBJECT_CERT:
|
2010-12-16 10:25:32 +00:00
|
|
|
case AUTH_RULE_CERT_POLICY:
|
2017-10-13 13:02:02 +00:00
|
|
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
|
|
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
2009-04-14 10:34:24 +00:00
|
|
|
case AUTH_HELPER_IM_CERT:
|
|
|
|
case AUTH_HELPER_SUBJECT_CERT:
|
|
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
2010-12-23 11:17:49 +00:00
|
|
|
case AUTH_HELPER_REVOCATION_CERT:
|
2014-02-05 16:15:45 +00:00
|
|
|
case AUTH_HELPER_AC_CERT:
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_RULE_MAX:
|
|
|
|
break;
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
2012-04-17 15:37:30 +00:00
|
|
|
return NULL;
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Implementation of auth_cfg_t.add.
|
|
|
|
*/
|
|
|
|
static void add(private_auth_cfg_t *this, auth_rule_t type, ...)
|
|
|
|
{
|
2013-07-11 14:54:15 +00:00
|
|
|
entry_t entry;
|
2009-04-14 10:34:24 +00:00
|
|
|
va_list args;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
va_start(args, type);
|
2013-07-11 14:54:15 +00:00
|
|
|
init_entry(&entry, type, args);
|
2009-04-14 10:34:24 +00:00
|
|
|
va_end(args);
|
2012-04-17 15:37:30 +00:00
|
|
|
|
|
|
|
if (is_multi_value_rule(type))
|
|
|
|
{ /* insert rules that may occur multiple times at the end */
|
2013-07-11 14:54:15 +00:00
|
|
|
array_insert(this->entries, ARRAY_TAIL, &entry);
|
2012-04-17 15:37:30 +00:00
|
|
|
}
|
|
|
|
else
|
|
|
|
{ /* insert rules we expect only once at the front (get() will return
|
|
|
|
* the latest value) */
|
2013-07-11 14:54:15 +00:00
|
|
|
array_insert(this->entries, ARRAY_HEAD, &entry);
|
2012-04-17 15:37:30 +00:00
|
|
|
}
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
|
|
|
|
2017-10-31 13:20:28 +00:00
|
|
|
/**
|
|
|
|
* Create a constraint for RSA/PSS signatures
|
|
|
|
*/
|
|
|
|
static signature_params_t *create_rsa_pss_constraint(char *token)
|
|
|
|
{
|
|
|
|
signature_params_t *params = NULL;
|
|
|
|
hash_algorithm_t hash;
|
|
|
|
|
|
|
|
if (enum_from_name(hash_algorithm_short_names, token, &hash))
|
|
|
|
{
|
|
|
|
rsa_pss_params_t pss = {
|
|
|
|
.hash = hash,
|
|
|
|
.mgf1_hash = hash,
|
|
|
|
.salt_len = RSA_PSS_SALT_LEN_DEFAULT,
|
|
|
|
};
|
|
|
|
signature_params_t pss_params = {
|
|
|
|
.scheme = SIGN_RSA_EMSA_PSS,
|
|
|
|
.params = &pss,
|
|
|
|
};
|
2018-10-12 10:11:51 +00:00
|
|
|
rsa_pss_params_set_salt_len(&pss, 0);
|
2017-10-31 13:20:28 +00:00
|
|
|
params = signature_params_clone(&pss_params);
|
|
|
|
}
|
|
|
|
return params;
|
|
|
|
}
|
|
|
|
|
2015-12-17 12:41:19 +00:00
|
|
|
METHOD(auth_cfg_t, add_pubkey_constraints, void,
|
2016-02-01 17:16:16 +00:00
|
|
|
private_auth_cfg_t *this, char* constraints, bool ike)
|
2015-12-17 12:41:19 +00:00
|
|
|
{
|
|
|
|
enumerator_t *enumerator;
|
2017-10-31 13:20:28 +00:00
|
|
|
bool ike_added = FALSE, rsa_pss;
|
2016-02-01 17:16:16 +00:00
|
|
|
key_type_t expected_type = -1;
|
|
|
|
auth_rule_t expected_strength = AUTH_RULE_MAX;
|
2017-10-13 13:32:29 +00:00
|
|
|
signature_params_t *params;
|
2015-12-17 12:41:19 +00:00
|
|
|
int strength;
|
2017-10-13 13:32:29 +00:00
|
|
|
char *token, *key_token = NULL;
|
2016-02-01 17:16:16 +00:00
|
|
|
auth_rule_t type;
|
|
|
|
void *value;
|
2015-12-17 12:41:19 +00:00
|
|
|
|
2017-10-31 13:20:28 +00:00
|
|
|
rsa_pss = lib->settings->get_bool(lib->settings, "%s.rsa_pss", FALSE,
|
|
|
|
lib->ns);
|
|
|
|
|
2015-12-17 12:41:19 +00:00
|
|
|
enumerator = enumerator_create_token(constraints, "-", "");
|
|
|
|
while (enumerator->enumerate(enumerator, &token))
|
|
|
|
{
|
|
|
|
bool found = FALSE;
|
|
|
|
int i;
|
|
|
|
struct {
|
|
|
|
char *name;
|
|
|
|
signature_scheme_t scheme;
|
|
|
|
key_type_t key;
|
|
|
|
} schemes[] = {
|
2016-12-09 08:38:15 +00:00
|
|
|
{ "md5", SIGN_RSA_EMSA_PKCS1_MD5, KEY_RSA, },
|
|
|
|
{ "sha1", SIGN_RSA_EMSA_PKCS1_SHA1, KEY_RSA, },
|
|
|
|
{ "sha224", SIGN_RSA_EMSA_PKCS1_SHA2_224, KEY_RSA, },
|
|
|
|
{ "sha256", SIGN_RSA_EMSA_PKCS1_SHA2_256, KEY_RSA, },
|
|
|
|
{ "sha384", SIGN_RSA_EMSA_PKCS1_SHA2_384, KEY_RSA, },
|
|
|
|
{ "sha512", SIGN_RSA_EMSA_PKCS1_SHA2_512, KEY_RSA, },
|
|
|
|
{ "sha1", SIGN_ECDSA_WITH_SHA1_DER, KEY_ECDSA, },
|
|
|
|
{ "sha256", SIGN_ECDSA_WITH_SHA256_DER, KEY_ECDSA, },
|
|
|
|
{ "sha384", SIGN_ECDSA_WITH_SHA384_DER, KEY_ECDSA, },
|
|
|
|
{ "sha512", SIGN_ECDSA_WITH_SHA512_DER, KEY_ECDSA, },
|
|
|
|
{ "sha256", SIGN_ECDSA_256, KEY_ECDSA, },
|
|
|
|
{ "sha384", SIGN_ECDSA_384, KEY_ECDSA, },
|
|
|
|
{ "sha512", SIGN_ECDSA_521, KEY_ECDSA, },
|
|
|
|
{ "sha256", SIGN_BLISS_WITH_SHA2_256, KEY_BLISS, },
|
|
|
|
{ "sha384", SIGN_BLISS_WITH_SHA2_384, KEY_BLISS, },
|
|
|
|
{ "sha512", SIGN_BLISS_WITH_SHA2_512, KEY_BLISS, },
|
|
|
|
{ "identity", SIGN_ED25519, KEY_ED25519, },
|
|
|
|
{ "identity", SIGN_ED448, KEY_ED448, },
|
2015-12-17 12:41:19 +00:00
|
|
|
};
|
|
|
|
|
2016-02-01 17:16:16 +00:00
|
|
|
if (expected_strength != AUTH_RULE_MAX)
|
2015-12-17 12:41:19 +00:00
|
|
|
{ /* expecting a key strength token */
|
|
|
|
strength = atoi(token);
|
|
|
|
if (strength)
|
|
|
|
{
|
2016-02-01 17:16:16 +00:00
|
|
|
add(this, expected_strength, (uintptr_t)strength);
|
2015-12-17 12:41:19 +00:00
|
|
|
}
|
2016-02-01 17:16:16 +00:00
|
|
|
expected_strength = AUTH_RULE_MAX;
|
2015-12-17 12:41:19 +00:00
|
|
|
if (strength)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
}
|
2016-02-01 17:16:16 +00:00
|
|
|
if (streq(token, "rsa") || streq(token, "ike:rsa"))
|
|
|
|
{
|
2017-10-13 13:32:29 +00:00
|
|
|
key_token = token;
|
|
|
|
expected_type = KEY_RSA;
|
|
|
|
expected_strength = AUTH_RULE_RSA_STRENGTH;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (streq(token, "rsa/pss") || streq(token, "ike:rsa/pss"))
|
|
|
|
{
|
|
|
|
key_token = token;
|
2016-02-01 17:16:16 +00:00
|
|
|
expected_type = KEY_RSA;
|
|
|
|
expected_strength = AUTH_RULE_RSA_STRENGTH;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (streq(token, "ecdsa") || streq(token, "ike:ecdsa"))
|
2015-12-17 12:41:19 +00:00
|
|
|
{
|
2017-10-13 13:32:29 +00:00
|
|
|
key_token = token;
|
2016-02-01 17:16:16 +00:00
|
|
|
expected_type = KEY_ECDSA;
|
|
|
|
expected_strength = AUTH_RULE_ECDSA_STRENGTH;
|
2015-12-17 12:41:19 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-12-09 08:38:15 +00:00
|
|
|
if (streq(token, "ed25519") || streq(token, "ike:ed25519"))
|
|
|
|
{
|
2017-10-13 13:32:29 +00:00
|
|
|
key_token = token;
|
2016-12-09 08:38:15 +00:00
|
|
|
expected_type = KEY_ED25519;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (streq(token, "ed448") || streq(token, "ike:ed448"))
|
|
|
|
{
|
2017-10-13 13:32:29 +00:00
|
|
|
key_token = token;
|
2016-12-09 08:38:15 +00:00
|
|
|
expected_type = KEY_ED448;
|
|
|
|
continue;
|
|
|
|
}
|
2016-02-01 17:16:16 +00:00
|
|
|
if (streq(token, "bliss") || streq(token, "ike:bliss"))
|
2015-12-17 12:41:19 +00:00
|
|
|
{
|
2017-10-13 13:32:29 +00:00
|
|
|
key_token = token;
|
2016-02-01 17:16:16 +00:00
|
|
|
expected_type = KEY_BLISS;
|
|
|
|
expected_strength = AUTH_RULE_BLISS_STRENGTH;
|
2015-12-17 12:41:19 +00:00
|
|
|
continue;
|
|
|
|
}
|
2016-02-01 17:16:16 +00:00
|
|
|
if (streq(token, "pubkey") || streq(token, "ike:pubkey"))
|
2015-12-17 12:41:19 +00:00
|
|
|
{
|
2017-10-13 13:32:29 +00:00
|
|
|
key_token = token;
|
2016-02-01 17:16:16 +00:00
|
|
|
expected_type = KEY_ANY;
|
2015-12-17 12:41:19 +00:00
|
|
|
continue;
|
|
|
|
}
|
2017-10-13 13:32:29 +00:00
|
|
|
if (key_token && strpfx(key_token, "ike:") && !ike)
|
2015-12-17 12:41:19 +00:00
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
2017-10-13 13:32:29 +00:00
|
|
|
if (key_token && streq(key_token + strlen(key_token) - 3, "pss"))
|
2017-10-31 13:20:28 +00:00
|
|
|
{
|
|
|
|
params = create_rsa_pss_constraint(token);
|
|
|
|
if (params)
|
2017-10-13 13:32:29 +00:00
|
|
|
{
|
|
|
|
if (strpfx(key_token, "ike:"))
|
|
|
|
{
|
|
|
|
add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, params);
|
|
|
|
ike_added = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
add(this, AUTH_RULE_SIGNATURE_SCHEME, params);
|
|
|
|
}
|
|
|
|
found = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
else
|
2015-12-17 12:41:19 +00:00
|
|
|
{
|
2017-10-31 13:20:28 +00:00
|
|
|
if (rsa_pss)
|
|
|
|
{
|
|
|
|
if (expected_type == KEY_ANY ||
|
|
|
|
expected_type == KEY_RSA)
|
|
|
|
{
|
|
|
|
params = create_rsa_pss_constraint(token);
|
|
|
|
if (params)
|
|
|
|
{
|
|
|
|
if (strpfx(key_token, "ike:"))
|
|
|
|
{
|
|
|
|
add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, params);
|
|
|
|
ike_added = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
add(this, AUTH_RULE_SIGNATURE_SCHEME, params);
|
|
|
|
}
|
|
|
|
found = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2017-10-13 13:32:29 +00:00
|
|
|
for (i = 0; i < countof(schemes); i++)
|
2015-12-17 12:41:19 +00:00
|
|
|
{
|
2017-10-13 13:32:29 +00:00
|
|
|
if (streq(schemes[i].name, token))
|
2015-12-17 12:41:19 +00:00
|
|
|
{
|
2017-10-13 13:32:29 +00:00
|
|
|
if (expected_type == KEY_ANY ||
|
|
|
|
expected_type == schemes[i].key)
|
2016-02-01 17:16:16 +00:00
|
|
|
{
|
2017-10-13 13:32:29 +00:00
|
|
|
INIT(params,
|
|
|
|
.scheme = schemes[i].scheme,
|
|
|
|
);
|
|
|
|
if (strpfx(key_token, "ike:"))
|
|
|
|
{
|
|
|
|
add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME, params);
|
|
|
|
ike_added = TRUE;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
add(this, AUTH_RULE_SIGNATURE_SCHEME, params);
|
|
|
|
}
|
2016-02-01 17:16:16 +00:00
|
|
|
}
|
2017-10-13 13:32:29 +00:00
|
|
|
found = TRUE;
|
2015-12-17 12:41:19 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (!found)
|
|
|
|
{
|
|
|
|
DBG1(DBG_CFG, "ignoring invalid auth token: '%s'", token);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
enumerator->destroy(enumerator);
|
2016-02-01 17:16:16 +00:00
|
|
|
|
2018-02-13 11:04:12 +00:00
|
|
|
/* if no explicit IKE signature constraints were added we add them for all
|
|
|
|
* configured signature constraints */
|
2016-02-01 17:16:16 +00:00
|
|
|
if (ike && !ike_added &&
|
|
|
|
lib->settings->get_bool(lib->settings,
|
|
|
|
"%s.signature_authentication_constraints", TRUE,
|
|
|
|
lib->ns))
|
|
|
|
{
|
|
|
|
enumerator = create_enumerator(this);
|
|
|
|
while (enumerator->enumerate(enumerator, &type, &value))
|
|
|
|
{
|
|
|
|
if (type == AUTH_RULE_SIGNATURE_SCHEME)
|
|
|
|
{
|
|
|
|
add(this, AUTH_RULE_IKE_SIGNATURE_SCHEME,
|
2017-10-13 13:02:02 +00:00
|
|
|
signature_params_clone(value));
|
2016-02-01 17:16:16 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
enumerator->destroy(enumerator);
|
|
|
|
}
|
2015-12-17 12:41:19 +00:00
|
|
|
}
|
|
|
|
|
2016-02-01 17:15:15 +00:00
|
|
|
/**
|
|
|
|
* Check if signature schemes of a specific type are compliant
|
|
|
|
*/
|
|
|
|
static bool complies_scheme(private_auth_cfg_t *this, auth_cfg_t *constraints,
|
|
|
|
auth_rule_t type, bool log_error)
|
|
|
|
{
|
|
|
|
enumerator_t *e1, *e2;
|
|
|
|
auth_rule_t t1, t2;
|
2017-10-13 13:02:02 +00:00
|
|
|
signature_params_t *params, *constraint;
|
2016-02-01 17:15:15 +00:00
|
|
|
bool success = TRUE;
|
|
|
|
|
|
|
|
e2 = create_enumerator(this);
|
2017-10-13 13:02:02 +00:00
|
|
|
while (e2->enumerate(e2, &t2, ¶ms))
|
2016-02-01 17:15:15 +00:00
|
|
|
{
|
|
|
|
if (t2 == type)
|
|
|
|
{
|
|
|
|
success = FALSE;
|
|
|
|
e1 = constraints->create_enumerator(constraints);
|
2017-10-13 13:02:02 +00:00
|
|
|
while (e1->enumerate(e1, &t1, &constraint))
|
2016-02-01 17:15:15 +00:00
|
|
|
{
|
2017-10-13 13:02:02 +00:00
|
|
|
if (t1 == type &&
|
|
|
|
signature_params_comply(constraint, params))
|
2016-02-01 17:15:15 +00:00
|
|
|
{
|
|
|
|
success = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e1->destroy(e1);
|
|
|
|
if (!success)
|
|
|
|
{
|
|
|
|
if (log_error)
|
|
|
|
{
|
|
|
|
DBG1(DBG_CFG, "%s signature scheme %N not acceptable",
|
|
|
|
AUTH_RULE_SIGNATURE_SCHEME == type ? "X.509" : "IKE",
|
2017-10-13 13:02:02 +00:00
|
|
|
signature_scheme_names, params->scheme);
|
2016-02-01 17:15:15 +00:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e2->destroy(e2);
|
|
|
|
return success;
|
|
|
|
}
|
|
|
|
|
2011-10-02 08:42:01 +00:00
|
|
|
METHOD(auth_cfg_t, complies, bool,
|
|
|
|
private_auth_cfg_t *this, auth_cfg_t *constraints, bool log_error)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
enumerator_t *e1, *e2;
|
2015-08-03 11:55:36 +00:00
|
|
|
bool success = TRUE, group_match = FALSE;
|
|
|
|
bool ca_match = FALSE, cert_match = FALSE;
|
2019-11-28 07:14:59 +00:00
|
|
|
identification_t *require_group = NULL, *require_ca = NULL;
|
|
|
|
certificate_t *require_cert = NULL;
|
2017-10-13 13:02:02 +00:00
|
|
|
signature_params_t *ike_scheme = NULL, *scheme = NULL;
|
2012-06-12 12:19:11 +00:00
|
|
|
u_int strength = 0;
|
2009-04-14 10:34:24 +00:00
|
|
|
auth_rule_t t1, t2;
|
2015-03-02 14:49:53 +00:00
|
|
|
char *key_type;
|
2009-04-14 10:34:24 +00:00
|
|
|
void *value;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
e1 = constraints->create_enumerator(constraints);
|
|
|
|
while (e1->enumerate(e1, &t1, &value))
|
|
|
|
{
|
|
|
|
switch (t1)
|
|
|
|
{
|
|
|
|
case AUTH_RULE_CA_CERT:
|
|
|
|
case AUTH_RULE_IM_CERT:
|
|
|
|
{
|
2019-11-28 07:14:59 +00:00
|
|
|
certificate_t *cert, *ca;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2015-08-03 11:55:36 +00:00
|
|
|
/* for CA certs, a match of a single cert is sufficient */
|
2019-11-28 07:14:59 +00:00
|
|
|
ca = (certificate_t*)value;
|
|
|
|
require_ca = ca->get_subject(ca);
|
|
|
|
|
|
|
|
e2 = create_enumerator(this);
|
|
|
|
while (e2->enumerate(e2, &t2, &cert))
|
|
|
|
{
|
|
|
|
if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
|
|
|
|
cert->equals(cert, ca))
|
|
|
|
{
|
|
|
|
ca_match = TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e2->destroy(e2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AUTH_RULE_CA_IDENTITY:
|
|
|
|
{
|
|
|
|
certificate_t *cert;
|
|
|
|
|
|
|
|
require_ca = (identification_t*)value;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
e2 = create_enumerator(this);
|
2015-08-03 11:55:36 +00:00
|
|
|
while (e2->enumerate(e2, &t2, &cert))
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
if ((t2 == AUTH_RULE_CA_CERT || t2 == AUTH_RULE_IM_CERT) &&
|
2019-11-28 07:14:59 +00:00
|
|
|
cert->has_subject(cert, require_ca))
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2015-08-03 11:55:36 +00:00
|
|
|
ca_match = TRUE;
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
e2->destroy(e2);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AUTH_RULE_SUBJECT_CERT:
|
|
|
|
{
|
2013-01-08 10:37:32 +00:00
|
|
|
certificate_t *cert;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2013-01-08 10:37:32 +00:00
|
|
|
/* for certs, a match of a single cert is sufficient */
|
|
|
|
require_cert = (certificate_t*)value;
|
|
|
|
|
|
|
|
e2 = create_enumerator(this);
|
|
|
|
while (e2->enumerate(e2, &t2, &cert))
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2013-01-08 10:37:32 +00:00
|
|
|
if (t2 == AUTH_RULE_SUBJECT_CERT &&
|
|
|
|
cert->equals(cert, require_cert))
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2013-01-08 10:37:32 +00:00
|
|
|
cert_match = TRUE;
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
|
|
|
}
|
2013-01-08 10:37:32 +00:00
|
|
|
e2->destroy(e2);
|
2009-04-14 10:34:24 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AUTH_RULE_CRL_VALIDATION:
|
|
|
|
case AUTH_RULE_OCSP_VALIDATION:
|
|
|
|
{
|
2010-12-07 16:48:23 +00:00
|
|
|
uintptr_t validated;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2015-10-27 16:21:18 +00:00
|
|
|
if (get(this, AUTH_RULE_CERT_VALIDATION_SUSPENDED))
|
|
|
|
{ /* skip validation, may happen later */
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2010-12-07 16:48:23 +00:00
|
|
|
e2 = create_enumerator(this);
|
|
|
|
while (e2->enumerate(e2, &t2, &validated))
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2010-12-07 16:48:23 +00:00
|
|
|
if (t2 == t1)
|
|
|
|
{
|
|
|
|
switch ((uintptr_t)value)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2010-12-07 16:48:23 +00:00
|
|
|
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, (uintptr_t)value);
|
|
|
|
}
|
|
|
|
break;
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
2010-12-07 16:48:23 +00:00
|
|
|
}
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
2010-12-07 16:48:23 +00:00
|
|
|
e2->destroy(e2);
|
2009-04-14 10:34:24 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AUTH_RULE_IDENTITY:
|
|
|
|
case AUTH_RULE_EAP_IDENTITY:
|
2010-08-31 15:26:20 +00:00
|
|
|
case AUTH_RULE_AAA_IDENTITY:
|
2011-12-15 10:58:26 +00:00
|
|
|
case AUTH_RULE_XAUTH_IDENTITY:
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
identification_t *id1, *id2;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
id1 = (identification_t*)value;
|
|
|
|
id2 = get(this, t1);
|
2021-08-26 17:47:15 +00:00
|
|
|
/*
|
2009-04-14 10:34:24 +00:00
|
|
|
if (!id2 || !id2->matches(id2, id1))
|
|
|
|
{
|
2012-09-18 09:16:10 +00:00
|
|
|
if (t1 == AUTH_RULE_IDENTITY &&
|
|
|
|
constraints->get(constraints, AUTH_RULE_IDENTITY_LOOSE))
|
|
|
|
{ /* also verify identity against subjectAltNames */
|
|
|
|
certificate_t *cert;
|
|
|
|
|
2017-07-05 15:17:13 +00:00
|
|
|
cert = get(this, AUTH_RULE_SUBJECT_CERT);
|
2012-09-18 09:16:10 +00:00
|
|
|
if (cert && cert->has_subject(cert, id1))
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
2009-04-14 10:34:24 +00:00
|
|
|
success = FALSE;
|
|
|
|
if (log_error)
|
|
|
|
{
|
2009-04-30 11:37:54 +00:00
|
|
|
DBG1(DBG_CFG, "constraint check failed: %sidentity '%Y'"
|
2009-04-14 10:34:24 +00:00
|
|
|
" required ", t1 == AUTH_RULE_IDENTITY ? "" :
|
|
|
|
"EAP ", id1);
|
|
|
|
}
|
|
|
|
}
|
2021-08-26 17:47:15 +00:00
|
|
|
*/
|
|
|
|
DBG1(DBG_CFG, "constraint check failed, but we are ignoring it for now: %sidentity '%Y'"
|
|
|
|
" required ", t1 == AUTH_RULE_IDENTITY ? "" :
|
|
|
|
"EAP ", id1);
|
2009-04-14 10:34:24 +00:00
|
|
|
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:
|
|
|
|
{
|
2015-08-20 16:35:23 +00:00
|
|
|
if ((uintptr_t)value != (uintptr_t)get(this, t1) &&
|
2015-08-21 09:40:07 +00:00
|
|
|
(uintptr_t)value != EAP_DYNAMIC &&
|
|
|
|
(uintptr_t)value != EAP_RADIUS)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
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;
|
|
|
|
}
|
2010-06-28 13:46:13 +00:00
|
|
|
case AUTH_RULE_GROUP:
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2012-07-26 10:39:53 +00:00
|
|
|
identification_t *group;
|
2010-06-28 13:46:13 +00:00
|
|
|
|
2010-07-09 11:51:58 +00:00
|
|
|
/* for groups, a match of a single group is sufficient */
|
2012-07-26 10:39:53 +00:00
|
|
|
require_group = (identification_t*)value;
|
2010-07-09 11:51:58 +00:00
|
|
|
e2 = create_enumerator(this);
|
2012-07-26 10:39:53 +00:00
|
|
|
while (e2->enumerate(e2, &t2, &group))
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2012-07-26 10:39:53 +00:00
|
|
|
if (t2 == AUTH_RULE_GROUP &&
|
|
|
|
group->matches(group, require_group))
|
2010-06-28 13:46:13 +00:00
|
|
|
{
|
2010-07-09 11:51:58 +00:00
|
|
|
group_match = TRUE;
|
2010-06-28 13:46:13 +00:00
|
|
|
}
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
2010-07-09 11:51:58 +00:00
|
|
|
e2->destroy(e2);
|
2009-04-14 10:34:24 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-11-25 14:26:51 +00:00
|
|
|
case AUTH_RULE_RSA_STRENGTH:
|
|
|
|
case AUTH_RULE_ECDSA_STRENGTH:
|
2015-03-02 14:49:53 +00:00
|
|
|
case AUTH_RULE_BLISS_STRENGTH:
|
2010-11-25 14:26:51 +00:00
|
|
|
{
|
2012-06-12 12:19:11 +00:00
|
|
|
strength = (uintptr_t)value;
|
2010-11-25 14:26:51 +00:00
|
|
|
break;
|
|
|
|
}
|
2016-02-01 17:15:15 +00:00
|
|
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
|
|
|
{
|
2017-10-13 13:02:02 +00:00
|
|
|
ike_scheme = value;
|
2016-02-01 17:15:15 +00:00
|
|
|
break;
|
|
|
|
}
|
2012-06-08 14:47:08 +00:00
|
|
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
|
|
|
{
|
2017-10-13 13:02:02 +00:00
|
|
|
scheme = value;
|
2012-06-08 14:47:08 +00:00
|
|
|
break;
|
|
|
|
}
|
2010-12-16 10:25:32 +00:00
|
|
|
case AUTH_RULE_CERT_POLICY:
|
|
|
|
{
|
|
|
|
char *oid1, *oid2;
|
|
|
|
|
|
|
|
oid1 = (char*)value;
|
|
|
|
success = FALSE;
|
|
|
|
e2 = create_enumerator(this);
|
|
|
|
while (e2->enumerate(e2, &t2, &oid2))
|
|
|
|
{
|
|
|
|
if (t2 == t1 && streq(oid1, oid2))
|
|
|
|
{
|
|
|
|
success = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e2->destroy(e2);
|
|
|
|
if (!success && log_error)
|
|
|
|
{
|
|
|
|
DBG1(DBG_CFG, "constraint requires cert policy %s", oid1);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2012-09-18 09:16:10 +00:00
|
|
|
case AUTH_RULE_IDENTITY_LOOSE:
|
|
|
|
/* just an indication when verifying AUTH_RULE_IDENTITY */
|
2011-12-08 15:53:27 +00:00
|
|
|
case AUTH_RULE_XAUTH_BACKEND:
|
|
|
|
/* not enforced, just a hint for local authentication */
|
2015-10-27 16:21:18 +00:00
|
|
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
|
|
|
/* not a constraint */
|
2009-04-14 10:34:24 +00:00
|
|
|
case AUTH_HELPER_IM_CERT:
|
|
|
|
case AUTH_HELPER_SUBJECT_CERT:
|
|
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
2010-12-23 11:17:49 +00:00
|
|
|
case AUTH_HELPER_REVOCATION_CERT:
|
2014-02-05 16:15:45 +00:00
|
|
|
case AUTH_HELPER_AC_CERT:
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_RULE_MAX:
|
2009-04-14 10:34:24 +00:00
|
|
|
/* skip helpers */
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!success)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e1->destroy(e1);
|
2010-07-09 11:51:58 +00:00
|
|
|
|
2012-06-08 14:47:08 +00:00
|
|
|
/* Check if we have a matching constraint (or none at all) for used
|
|
|
|
* signature schemes. */
|
2017-10-13 13:02:02 +00:00
|
|
|
if (success && scheme)
|
2012-06-08 14:47:08 +00:00
|
|
|
{
|
2016-02-01 17:15:15 +00:00
|
|
|
success = complies_scheme(this, constraints,
|
|
|
|
AUTH_RULE_SIGNATURE_SCHEME, log_error);
|
|
|
|
}
|
2017-10-13 13:02:02 +00:00
|
|
|
if (success && ike_scheme)
|
2016-02-01 17:15:15 +00:00
|
|
|
{
|
|
|
|
success = complies_scheme(this, constraints,
|
|
|
|
AUTH_RULE_IKE_SIGNATURE_SCHEME, log_error);
|
2012-06-08 14:47:08 +00:00
|
|
|
}
|
|
|
|
|
2012-06-12 12:19:11 +00:00
|
|
|
/* Check if we have a matching constraint (or none at all) for used
|
|
|
|
* public key strength */
|
|
|
|
if (success && strength)
|
|
|
|
{
|
|
|
|
e2 = create_enumerator(this);
|
|
|
|
while (e2->enumerate(e2, &t2, &strength))
|
|
|
|
{
|
2015-03-02 14:49:53 +00:00
|
|
|
switch (t2)
|
2012-06-12 12:19:11 +00:00
|
|
|
{
|
2015-03-02 14:49:53 +00:00
|
|
|
default:
|
|
|
|
continue;
|
|
|
|
case AUTH_RULE_RSA_STRENGTH:
|
|
|
|
key_type = "RSA";
|
|
|
|
break;
|
|
|
|
case AUTH_RULE_ECDSA_STRENGTH:
|
|
|
|
key_type = "ECDSA";
|
|
|
|
break;
|
|
|
|
case AUTH_RULE_BLISS_STRENGTH:
|
|
|
|
key_type = "BLISS";
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
success = FALSE;
|
|
|
|
e1 = constraints->create_enumerator(constraints);
|
|
|
|
while (e1->enumerate(e1, &t1, &value))
|
|
|
|
{
|
|
|
|
if (t1 == t2 && (uintptr_t)value <= strength)
|
2012-06-12 12:19:11 +00:00
|
|
|
{
|
2015-03-02 14:49:53 +00:00
|
|
|
success = TRUE;
|
|
|
|
break;
|
2012-06-12 12:19:11 +00:00
|
|
|
}
|
2015-03-02 14:49:53 +00:00
|
|
|
}
|
|
|
|
e1->destroy(e1);
|
|
|
|
if (!success)
|
|
|
|
{
|
|
|
|
if (log_error)
|
2012-06-12 12:19:11 +00:00
|
|
|
{
|
2015-03-02 14:49:53 +00:00
|
|
|
DBG1(DBG_CFG, "%s-%d signatures not acceptable",
|
|
|
|
key_type, strength);
|
2012-06-12 12:19:11 +00:00
|
|
|
}
|
2015-03-02 14:49:53 +00:00
|
|
|
break;
|
2012-06-12 12:19:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
e2->destroy(e2);
|
|
|
|
}
|
|
|
|
|
2012-07-26 10:39:53 +00:00
|
|
|
if (require_group && !group_match)
|
2010-07-09 11:51:58 +00:00
|
|
|
{
|
|
|
|
if (log_error)
|
|
|
|
{
|
2012-07-26 10:39:53 +00:00
|
|
|
DBG1(DBG_CFG, "constraint check failed: group membership to "
|
|
|
|
"'%Y' required", require_group);
|
2010-07-09 11:51:58 +00:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
2015-08-03 11:55:36 +00:00
|
|
|
if (require_ca && !ca_match)
|
|
|
|
{
|
|
|
|
if (log_error)
|
|
|
|
{
|
|
|
|
DBG1(DBG_CFG, "constraint check failed: peer not "
|
2019-11-28 07:14:59 +00:00
|
|
|
"authenticated by CA '%Y'", require_ca);
|
2015-08-03 11:55:36 +00:00
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
2013-01-08 10:37:32 +00:00
|
|
|
if (require_cert && !cert_match)
|
|
|
|
{
|
|
|
|
if (log_error)
|
|
|
|
{
|
|
|
|
DBG1(DBG_CFG, "constraint check failed: peer not "
|
2015-08-03 11:55:36 +00:00
|
|
|
"authenticated with peer cert '%Y'",
|
2013-01-08 10:37:32 +00:00
|
|
|
require_cert->get_subject(require_cert));
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
2009-04-14 10:34:24 +00:00
|
|
|
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;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2012-04-17 15:37:30 +00:00
|
|
|
/* this enumerator skips duplicates for rules we expect only once */
|
2009-04-14 10:34:24 +00:00
|
|
|
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:
|
2010-12-23 11:17:49 +00:00
|
|
|
case AUTH_HELPER_REVOCATION_CERT:
|
2014-02-05 16:15:45 +00:00
|
|
|
case AUTH_HELPER_AC_CERT:
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
certificate_t *cert = (certificate_t*)value;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
add(this, type, cert->get_ref(cert));
|
|
|
|
break;
|
|
|
|
}
|
2012-09-18 09:16:10 +00:00
|
|
|
case AUTH_RULE_IDENTITY_LOOSE:
|
2009-04-14 10:34:24 +00:00
|
|
|
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:
|
2010-11-25 14:26:51 +00:00
|
|
|
case AUTH_RULE_RSA_STRENGTH:
|
|
|
|
case AUTH_RULE_ECDSA_STRENGTH:
|
2015-03-02 14:49:53 +00:00
|
|
|
case AUTH_RULE_BLISS_STRENGTH:
|
2015-10-27 16:21:18 +00:00
|
|
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
add(this, type, (uintptr_t)value);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
case AUTH_RULE_IDENTITY:
|
2019-11-28 07:14:59 +00:00
|
|
|
case AUTH_RULE_CA_IDENTITY:
|
2009-04-14 10:34:24 +00:00
|
|
|
case AUTH_RULE_EAP_IDENTITY:
|
2010-08-31 15:26:20 +00:00
|
|
|
case AUTH_RULE_AAA_IDENTITY:
|
2010-06-28 13:46:13 +00:00
|
|
|
case AUTH_RULE_GROUP:
|
2011-12-15 10:58:26 +00:00
|
|
|
case AUTH_RULE_XAUTH_IDENTITY:
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
identification_t *id = (identification_t*)value;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
add(this, type, id->clone(id));
|
|
|
|
break;
|
|
|
|
}
|
2017-10-13 13:02:02 +00:00
|
|
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
|
|
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
|
|
|
{
|
|
|
|
add(this, type, signature_params_clone(value));
|
|
|
|
break;
|
|
|
|
}
|
2011-12-08 15:53:27 +00:00
|
|
|
case AUTH_RULE_XAUTH_BACKEND:
|
2010-12-16 10:25:32 +00:00
|
|
|
case AUTH_RULE_CERT_POLICY:
|
2009-04-14 10:34:24 +00:00
|
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
|
|
{
|
|
|
|
add(this, type, strdup((char*)value));
|
|
|
|
break;
|
|
|
|
}
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_RULE_MAX:
|
|
|
|
break;
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
enumerator->destroy(enumerator);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
2013-07-11 14:54:15 +00:00
|
|
|
entry_t entry;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2015-10-28 17:53:15 +00:00
|
|
|
while (array_remove(other->entries, ARRAY_TAIL, &entry))
|
|
|
|
{ /* keep order but prefer new values (esp. for single valued ones) */
|
|
|
|
array_insert(this->entries, ARRAY_HEAD, &entry);
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
2013-07-11 14:54:15 +00:00
|
|
|
array_compress(other->entries);
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2012-09-18 10:47:17 +00:00
|
|
|
* Compare two auth_cfg_t objects for equality.
|
2009-04-14 10:34:24 +00:00
|
|
|
*/
|
2012-09-18 10:47:17 +00:00
|
|
|
static bool auth_cfg_equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
enumerator_t *e1, *e2;
|
|
|
|
entry_t *i1, *i2;
|
|
|
|
bool equal = TRUE, found;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2012-04-17 15:37:30 +00:00
|
|
|
/* the rule count does not have to be equal for the two, as we only compare
|
|
|
|
* the first value found for some rules */
|
2013-07-11 14:54:15 +00:00
|
|
|
e1 = array_create_enumerator(this->entries);
|
2009-04-14 10:34:24 +00:00
|
|
|
while (e1->enumerate(e1, &i1))
|
|
|
|
{
|
|
|
|
found = FALSE;
|
2012-04-17 15:37:30 +00:00
|
|
|
|
2013-07-11 14:54:15 +00:00
|
|
|
e2 = array_create_enumerator(other->entries);
|
2009-04-14 10:34:24 +00:00
|
|
|
while (e2->enumerate(e2, &i2))
|
|
|
|
{
|
2012-04-17 15:37:30 +00:00
|
|
|
if (entry_equals(i1, i2))
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2012-04-17 15:37:30 +00:00
|
|
|
found = TRUE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (i1->type == i2->type && !is_multi_value_rule(i1->type))
|
|
|
|
{ /* we continue our search, only for multi valued rules */
|
2009-04-14 10:34:24 +00:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e2->destroy(e2);
|
|
|
|
if (!found)
|
|
|
|
{
|
|
|
|
equal = FALSE;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
e1->destroy(e1);
|
|
|
|
return equal;
|
|
|
|
}
|
|
|
|
|
2012-09-18 10:47:17 +00:00
|
|
|
/**
|
|
|
|
* Implementation of auth_cfg_t.equals.
|
|
|
|
*/
|
|
|
|
static bool equals(private_auth_cfg_t *this, private_auth_cfg_t *other)
|
|
|
|
{
|
|
|
|
if (auth_cfg_equals(this, other))
|
|
|
|
{
|
|
|
|
/* as 'other' might contain entries that 'this' doesn't we also check
|
|
|
|
* the other way around */
|
|
|
|
return auth_cfg_equals(other, this);
|
|
|
|
}
|
|
|
|
return FALSE;
|
|
|
|
}
|
|
|
|
|
2011-10-02 08:42:01 +00:00
|
|
|
METHOD(auth_cfg_t, purge, void,
|
|
|
|
private_auth_cfg_t *this, bool keep_ca)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2013-07-11 14:54:15 +00:00
|
|
|
enumerator_t *enumerator;
|
2009-04-14 10:34:24 +00:00
|
|
|
entry_t *entry;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2013-07-11 14:54:15 +00:00
|
|
|
enumerator = array_create_enumerator(this->entries);
|
|
|
|
while (enumerator->enumerate(enumerator, &entry))
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2013-07-11 14:54:15 +00:00
|
|
|
if (!keep_ca || entry->type != AUTH_RULE_CA_CERT)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
destroy_entry_value(entry);
|
2014-09-11 15:33:52 +00:00
|
|
|
array_remove_at(this->entries, enumerator);
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
|
|
|
}
|
2013-07-11 14:54:15 +00:00
|
|
|
enumerator->destroy(enumerator);
|
|
|
|
|
|
|
|
array_compress(this->entries);
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
|
|
|
|
2011-10-02 08:42:01 +00:00
|
|
|
METHOD(auth_cfg_t, clone_, auth_cfg_t*,
|
|
|
|
private_auth_cfg_t *this)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
enumerator_t *enumerator;
|
|
|
|
auth_cfg_t *clone;
|
2013-02-18 16:23:04 +00:00
|
|
|
auth_rule_t type;
|
|
|
|
void *value;
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
clone = auth_cfg_create();
|
2012-04-17 15:37:30 +00:00
|
|
|
/* this enumerator skips duplicates for rules we expect only once */
|
2013-02-18 16:23:04 +00:00
|
|
|
enumerator = create_enumerator(this);
|
|
|
|
while (enumerator->enumerate(enumerator, &type, &value))
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2013-02-18 16:23:04 +00:00
|
|
|
switch (type)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
case AUTH_RULE_IDENTITY:
|
2019-11-28 07:14:59 +00:00
|
|
|
case AUTH_RULE_CA_IDENTITY:
|
2009-04-14 10:34:24 +00:00
|
|
|
case AUTH_RULE_EAP_IDENTITY:
|
2010-08-31 15:26:20 +00:00
|
|
|
case AUTH_RULE_AAA_IDENTITY:
|
2010-06-28 13:46:13 +00:00
|
|
|
case AUTH_RULE_GROUP:
|
2011-12-15 10:58:26 +00:00
|
|
|
case AUTH_RULE_XAUTH_IDENTITY:
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2013-02-18 16:23:04 +00:00
|
|
|
identification_t *id = (identification_t*)value;
|
|
|
|
clone->add(clone, type, id->clone(id));
|
2009-04-14 10:34:24 +00:00
|
|
|
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:
|
2010-12-23 11:17:49 +00:00
|
|
|
case AUTH_HELPER_REVOCATION_CERT:
|
2014-02-05 16:15:45 +00:00
|
|
|
case AUTH_HELPER_AC_CERT:
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
2013-02-18 16:23:04 +00:00
|
|
|
certificate_t *cert = (certificate_t*)value;
|
|
|
|
clone->add(clone, type, cert->get_ref(cert));
|
2009-04-14 10:34:24 +00:00
|
|
|
break;
|
|
|
|
}
|
2011-12-08 15:53:27 +00:00
|
|
|
case AUTH_RULE_XAUTH_BACKEND:
|
2010-12-16 10:25:32 +00:00
|
|
|
case AUTH_RULE_CERT_POLICY:
|
2009-04-14 10:34:24 +00:00
|
|
|
case AUTH_HELPER_IM_HASH_URL:
|
|
|
|
case AUTH_HELPER_SUBJECT_HASH_URL:
|
|
|
|
{
|
2013-02-18 16:23:04 +00:00
|
|
|
clone->add(clone, type, strdup(value));
|
2009-04-14 10:34:24 +00:00
|
|
|
break;
|
|
|
|
}
|
2012-09-18 09:16:10 +00:00
|
|
|
case AUTH_RULE_IDENTITY_LOOSE:
|
2009-04-14 10:34:24 +00:00
|
|
|
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:
|
2010-11-25 14:26:51 +00:00
|
|
|
case AUTH_RULE_RSA_STRENGTH:
|
|
|
|
case AUTH_RULE_ECDSA_STRENGTH:
|
2015-03-02 14:49:53 +00:00
|
|
|
case AUTH_RULE_BLISS_STRENGTH:
|
2015-10-27 16:21:18 +00:00
|
|
|
case AUTH_RULE_CERT_VALIDATION_SUSPENDED:
|
2013-02-18 16:23:04 +00:00
|
|
|
clone->add(clone, type, (uintptr_t)value);
|
2009-04-14 10:34:24 +00:00
|
|
|
break;
|
2017-10-13 13:02:02 +00:00
|
|
|
case AUTH_RULE_SIGNATURE_SCHEME:
|
|
|
|
case AUTH_RULE_IKE_SIGNATURE_SCHEME:
|
|
|
|
{
|
|
|
|
clone->add(clone, type, signature_params_clone(value));
|
|
|
|
break;
|
|
|
|
}
|
2012-04-17 15:37:30 +00:00
|
|
|
case AUTH_RULE_MAX:
|
|
|
|
break;
|
2009-04-14 10:34:24 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
enumerator->destroy(enumerator);
|
|
|
|
return clone;
|
|
|
|
}
|
|
|
|
|
2011-10-02 08:42:01 +00:00
|
|
|
METHOD(auth_cfg_t, destroy, void,
|
|
|
|
private_auth_cfg_t *this)
|
2009-04-14 10:34:24 +00:00
|
|
|
{
|
|
|
|
purge(this, FALSE);
|
2013-07-11 14:54:15 +00:00
|
|
|
array_destroy(this->entries);
|
2009-04-14 10:34:24 +00:00
|
|
|
free(this);
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* see header file
|
|
|
|
*/
|
|
|
|
auth_cfg_t *auth_cfg_create()
|
|
|
|
{
|
2011-10-02 08:42:01 +00:00
|
|
|
private_auth_cfg_t *this;
|
|
|
|
|
|
|
|
INIT(this,
|
|
|
|
.public = {
|
|
|
|
.add = (void(*)(auth_cfg_t*, auth_rule_t type, ...))add,
|
2015-12-17 12:41:19 +00:00
|
|
|
.add_pubkey_constraints = _add_pubkey_constraints,
|
2011-10-02 08:42:01 +00:00
|
|
|
.get = _get,
|
|
|
|
.create_enumerator = _create_enumerator,
|
|
|
|
.replace = (void(*)(auth_cfg_t*,enumerator_t*,auth_rule_t,...))replace,
|
|
|
|
.complies = _complies,
|
|
|
|
.merge = (void(*)(auth_cfg_t*,auth_cfg_t*,bool))merge,
|
|
|
|
.purge = _purge,
|
|
|
|
.equals = (bool(*)(auth_cfg_t*,auth_cfg_t*))equals,
|
|
|
|
.clone = _clone_,
|
|
|
|
.destroy = _destroy,
|
|
|
|
},
|
2013-07-11 14:54:15 +00:00
|
|
|
.entries = array_create(sizeof(entry_t), 0),
|
2011-10-02 08:42:01 +00:00
|
|
|
);
|
2009-09-04 11:46:09 +00:00
|
|
|
|
2009-04-14 10:34:24 +00:00
|
|
|
return &this->public;
|
|
|
|
}
|