dnscert: Add DNS CERT support for pubkey authentication

Add DNSSEC protected CERT RR delivered certificate authentication.
The new dnscert plugin is based on the ipseckey plugin and relies on the
existing PEM decoder as well as x509 and PGP parsers.  As such the plugin
expects PEM encoded PKIX(x509) or PGP(GPG) certificate payloads.

The plugin is targeted to improve interoperability with Racoon, which
supports this type of authentication, ignoring in-stream certificates
and using only DNS provided certificates for FQDN IDs.
This commit is contained in:
Ruslan N. Marchenko 2013-08-30 17:51:12 +02:00 committed by Tobias Brunner
parent 8ac54970f5
commit b638c131de
9 changed files with 832 additions and 0 deletions

View File

@ -136,6 +136,7 @@ ARG_DISBL_SET([pkcs12], [disable PKCS12 container support plugin.])
ARG_DISBL_SET([pgp], [disable PGP key decoding plugin.])
ARG_DISBL_SET([dnskey], [disable DNS RR key decoding plugin.])
ARG_DISBL_SET([sshkey], [disable SSH key decoding plugin.])
ARG_ENABL_SET([dnscert], [enable DNSCERT authentication plugin.])
ARG_ENABL_SET([ipseckey], [enable IPSECKEY authentication plugin.])
ARG_DISBL_SET([pem], [disable PEM decoding plugin.])
ARG_DISBL_SET([hmac], [disable HMAC crypto implementation plugin.])
@ -1015,6 +1016,7 @@ ADD_PLUGIN([pkcs12], [s charon scepclient pki scripts cmd])
ADD_PLUGIN([pgp], [s charon])
ADD_PLUGIN([dnskey], [s charon pki])
ADD_PLUGIN([sshkey], [s charon pki nm cmd])
ADD_PLUGIN([dnscert], [c charon])
ADD_PLUGIN([ipseckey], [c charon])
ADD_PLUGIN([pem], [s charon openac scepclient pki scripts manager medsrv attest nm cmd])
ADD_PLUGIN([padlock], [s charon])
@ -1181,6 +1183,7 @@ AM_CONDITIONAL(USE_ANDROID_LOG, test x$android_log = xtrue)
AM_CONDITIONAL(USE_MAEMO, test x$maemo = xtrue)
AM_CONDITIONAL(USE_SMP, test x$smp = xtrue)
AM_CONDITIONAL(USE_SQL, test x$sql = xtrue)
AM_CONDITIONAL(USE_DNSCERT, test x$dnscert = xtrue)
AM_CONDITIONAL(USE_IPSECKEY, test x$ipseckey = xtrue)
AM_CONDITIONAL(USE_UPDOWN, test x$updown = xtrue)
AM_CONDITIONAL(USE_DHCP, test x$dhcp = xtrue)
@ -1442,6 +1445,7 @@ AC_CONFIG_FILES([
src/libcharon/plugins/farp/Makefile
src/libcharon/plugins/smp/Makefile
src/libcharon/plugins/sql/Makefile
src/libcharon/plugins/dnscert/Makefile
src/libcharon/plugins/ipseckey/Makefile
src/libcharon/plugins/medsrv/Makefile
src/libcharon/plugins/medcli/Makefile

View File

@ -216,6 +216,13 @@ if MONOLITHIC
endif
endif
if USE_DNSCERT
SUBDIRS += plugins/dnscert
if MONOLITHIC
libcharon_la_LIBADD += plugins/dnscert/libstrongswan-dnscert.la
endif
endif
if USE_IPSECKEY
SUBDIRS += plugins/ipseckey
if MONOLITHIC

View File

@ -0,0 +1,20 @@
AM_CPPFLAGS = \
-I$(top_srcdir)/src/libstrongswan \
-I$(top_srcdir)/src/libhydra \
-I$(top_srcdir)/src/libcharon
AM_CFLAGS = \
-rdynamic
if MONOLITHIC
noinst_LTLIBRARIES = libstrongswan-dnscert.la
else
plugin_LTLIBRARIES = libstrongswan-dnscert.la
endif
libstrongswan_dnscert_la_SOURCES = \
dnscert_plugin.h dnscert_plugin.c \
dnscert_cred.h dnscert_cred.c \
dnscert.h dnscert.c
libstrongswan_dnscert_la_LDFLAGS = -module -avoid-version

View File

@ -0,0 +1,142 @@
/*
* Copyright (C) 2013 Ruslan Marchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "dnscert.h"
#include <library.h>
#include <utils/debug.h>
#include <bio/bio_reader.h>
typedef struct private_dnscert_t private_dnscert_t;
/**
* private data of the dnscert
*/
struct private_dnscert_t {
/**
* public functions
*/
dnscert_t public;
/**
* Certificate type
*/
u_int16_t cert_type;
/**
* Key tag
*/
u_int16_t key_tag;
/**
* Algorithm
*/
u_int8_t algorithm;
/**
* Certificate
*/
chunk_t certificate;
};
METHOD(dnscert_t, get_cert_type, dnscert_type_t,
private_dnscert_t *this)
{
return this->cert_type;
}
METHOD(dnscert_t, get_key_tag, u_int16_t,
private_dnscert_t *this)
{
return this->key_tag;
}
METHOD(dnscert_t, get_algorithm, dnscert_algorithm_t,
private_dnscert_t *this)
{
return this->algorithm;
}
METHOD(dnscert_t, get_certificate, chunk_t,
private_dnscert_t *this)
{
return this->certificate;
}
METHOD(dnscert_t, destroy, void,
private_dnscert_t *this)
{
chunk_free(&this->certificate);
free(this);
}
dnscert_t *dnscert_create_frm_rr(rr_t *rr)
{
private_dnscert_t *this;
bio_reader_t *reader = NULL;
INIT(this,
.public = {
.get_cert_type = _get_cert_type,
.get_key_tag = _get_key_tag,
.get_algorithm = _get_algorithm,
.get_certificate = _get_certificate,
.destroy = _destroy,
},
);
if (rr->get_type(rr) != RR_TYPE_CERT)
{
DBG1(DBG_CFG, "unable to create a dnscert out of an RR "
"whose type is not CERT");
free(this);
return NULL;
}
/**
* Parse the content (RDATA field) of the RR
* First - type/tag/algo fields and then cert body
*/
reader = bio_reader_create(rr->get_rdata(rr));
if (!reader->read_uint16(reader, &this->cert_type) ||
!reader->read_uint16(reader, &this->key_tag) ||
!reader->read_uint8(reader, &this->algorithm) )
{
DBG1(DBG_CFG, "CERT RR has a wrong format");
reader->destroy(reader);
free(this);
return NULL;
}
if (!reader->read_data(reader, reader->remaining(reader),
&this->certificate))
{
DBG1(DBG_CFG, "failed to read DNS certificate field");
reader->destroy(reader);
free(this);
return NULL;
}
this->certificate = chunk_clone(this->certificate);
reader->destroy(reader);
return &this->public;
}

View File

@ -0,0 +1,161 @@
/*
* Copyright (C) 2013 Ruslan Marchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @defgroup dnscert_i dnscert
* @{ @ingroup dnscert
*/
#ifndef DNSCERT_H_
#define DNSCERT_H_
typedef struct dnscert_t dnscert_t;
typedef enum dnscert_algorithm_t dnscert_algorithm_t;
typedef enum dnscert_type_t dnscert_type_t;
#include <library.h>
/**
* DNS CERT types as defined in RFC 4398.
*/
enum dnscert_type_t {
/** Reserved value */
DNSCERT_TYPE_RESERVED = 0,
/** An x509 PKIX certificate */
DNSCERT_TYPE_PKIX = 1,
/** A SKPI certificate */
DNSCERT_TYPE_SKPI = 2,
/** A PGP certificate */
DNSCERT_TYPE_PGP = 3,
/** An x509 PKIX cert URL */
DNSCERT_TYPE_IPKIX = 4,
/** A SKPI cert URL */
DNSCERT_TYPE_ISKPI = 5,
/** A PGP cert fingerprint and URL */
DNSCERT_TYPE_IPGP = 6,
/** An attribute Certificate */
DNSCERT_TYPE_ACPKIX = 7,
/** An attribute cert URL */
DNSCERT_TYPE_IACKPIX = 8
};
/**
* DNSCERT algorithms as defined in http://www.iana.org/assignments/
* dns-sec-alg-numbers/dns-sec-alg-numbers.xhtml#dns-sec-alg-numbers-1
*/
enum dnscert_algorithm_t {
/** No defined */
DNSCERT_ALGORITHM_UNDEFINED = 0,
/** RSA/MD5 */
DNSCERT_ALGORITHM_RSAMD5 = 1,
/** Diffie-Hellman */
DNSCERT_ALGORITHM_DH = 2,
/** DSA/SHA1 */
DNSCERT_ALGORITHM_DSASHA = 3,
/** Reserved */
DNSCERT_ALGORITHM_RSRVD4 = 4,
/** RSA/SHA1 */
DNSCERT_ALGORITHM_RSASHA = 5,
/** DSA/NSEC3/SHA */
DNSCERT_ALGORITHM_DSANSEC3 = 6,
/** RSA/NSEC3/SHA */
DNSCERT_ALGORITHM_RSANSEC3 = 7,
/** RSA/SHA256 */
DNSCERT_ALGORITHM_RSASHA256 = 8,
/** Reserved */
DNSCERT_ALGORITHM_RSRVD9 = 9,
/** RSA/SHA512 */
DNSCERT_ALGORITHM_RSASHA512 = 10,
};
/**
* DNS CERT RR as defined in RFC 4398.
*
* The CERT resource record (RR) has the structure given below. Its RR
* type code is 37.
*
* 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 3 3
* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | type | key tag |
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
* | algorithm | /
* +---------------+ certificate or CRL /
* / /
* +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-|
*/
struct dnscert_t {
/**
* Get the type of the certificate body.
*
* The certificate "type" determines the format of the body
* of the CERT data.
*
* @return certificate type
*/
dnscert_type_t (*get_cert_type)(dnscert_t *this);
/**
* Get the tag of the key part of the CERT.
*
* @return keytag
*/
u_int16_t (*get_key_tag)(dnscert_t *this);
/**
* Get the algorithm.
*
* The "algorithm" determines the format of the public key field
* of the DNS CERT.
*
* @return algorithm
*/
dnscert_algorithm_t (*get_algorithm)(dnscert_t *this);
/**
* Get the content of the certificate field as chunk.
*
* The format of the certificate depends on the type.
*
* The data pointed by the chunk is still owned by the DNSCERT.
* Clone it if necessary.
*
* @return certificate field as chunk
*/
chunk_t (*get_certificate)(dnscert_t *this);
/**
* Destroy the DNSCERT.
*/
void (*destroy) (dnscert_t *this);
};
/**
* Create a dnscert instance out of a resource record.
*
* @param rr resource record which contains a DNSCERT
* @return dnscert, NULL on failure
*/
dnscert_t *dnscert_create_frm_rr(rr_t *rr);
#endif /** DNSCERT_H_ @}*/

View File

@ -0,0 +1,214 @@
/*
* Copyright (C) 2013 Tobias Brunner
* Copyright (C) 2012 Reto Guadagnini
* 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.
*/
/*
* Copyright (C) 2013 Ruslan Marchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#define _GNU_SOURCE
#include <stdio.h>
#include <string.h>
#include "dnscert_cred.h"
#include "dnscert.h"
typedef struct private_dnscert_cred_t private_dnscert_cred_t;
/**
* Private data of an dnscert_cred_t object
*/
struct private_dnscert_cred_t {
/**
* Public part
*/
dnscert_cred_t public;
/**
* DNS resolver
*/
resolver_t *res;
};
/**
* enumerator over certificates
*/
typedef struct {
/** implements enumerator interface */
enumerator_t public;
/** inner enumerator (enumerates CERT resource records) */
enumerator_t *inner;
/** response of the DNS resolver which contains the CERTs */
resolver_response_t *response;
} cert_enumerator_t;
METHOD(enumerator_t, cert_enumerator_enumerate, bool,
cert_enumerator_t *this, certificate_t **cert)
{
dnscert_t *cur_crt;
rr_t *cur_rr;
chunk_t certificate;
/* Get the next supported CERT using the inner enumerator. */
while (this->inner->enumerate(this->inner, &cur_rr))
{
cur_crt = dnscert_create_frm_rr(cur_rr);
if (!cur_crt)
{
DBG1(DBG_CFG, " failed to parse CERT RR, skipping");
continue;
}
if (cur_crt->get_cert_type(cur_crt) != DNSCERT_TYPE_PKIX &&
cur_crt->get_cert_type(cur_crt) != DNSCERT_TYPE_PGP)
{
DBG1(DBG_CFG, " unsupported CERT type [%d], skipping",
cur_crt->get_cert_type(cur_crt));
cur_crt->destroy(cur_crt);
continue;
}
/* Try to parse PEM certificate container. Both x509 and PGP should
* presumably come as PEM encoded certs. */
certificate = cur_crt->get_certificate(cur_crt);
*cert = lib->creds->create(lib->creds, CRED_CERTIFICATE, CERT_ANY,
BUILD_BLOB_PEM, certificate,
BUILD_END);
if (*cert == NULL)
{
DBG1(DBG_CFG, " unable to parse certificate, skipping",
cur_crt->get_cert_type(cur_crt));
cur_crt->destroy(cur_crt);
continue;
}
cur_crt->destroy(cur_crt);
return TRUE;
}
return FALSE;
}
METHOD(enumerator_t, cert_enumerator_destroy, void,
cert_enumerator_t *this)
{
this->inner->destroy(this->inner);
this->response->destroy(this->response);
free(this);
}
METHOD(credential_set_t, create_cert_enumerator, enumerator_t*,
private_dnscert_cred_t *this, certificate_type_t cert, key_type_t key,
identification_t *id, bool trusted)
{
resolver_response_t *response;
cert_enumerator_t *e;
char *fqdn;
if (!id || id->get_type(id) != ID_FQDN)
{
return enumerator_create_empty();
}
/* query the DNS for the required CERT RRs */
if (asprintf(&fqdn, "%Y", id) <= 0)
{
DBG1(DBG_CFG, "failed to determine FQDN to retrieve CERT RRs");
return enumerator_create_empty();
}
DBG1(DBG_CFG, "performing a DNS query for CERT RRs of '%s'", fqdn);
response = this->res->query(this->res, fqdn, RR_CLASS_IN, RR_TYPE_CERT);
if (!response)
{
DBG1(DBG_CFG, " query for CERT RRs failed");
free(fqdn);
return enumerator_create_empty();
}
free(fqdn);
if (!response->has_data(response) ||
!response->query_name_exist(response))
{
DBG1(DBG_CFG, " unable to retrieve CERT RRs from the DNS");
response->destroy(response);
return enumerator_create_empty();
}
if (response->get_security_state(response) != SECURE)
{
DBG1(DBG_CFG, " DNSSEC state of CERT RRs is not secure");
response->destroy(response);
return enumerator_create_empty();
}
INIT(e,
.public = {
.enumerate = (void*)_cert_enumerator_enumerate,
.destroy = _cert_enumerator_destroy,
},
.inner = response->get_rr_set(response)->create_rr_enumerator(
response->get_rr_set(response)),
.response = response
);
return &e->public;
}
METHOD(dnscert_cred_t, destroy, void,
private_dnscert_cred_t *this)
{
this->res->destroy(this->res);
free(this);
}
/**
* Described in header.
*/
dnscert_cred_t *dnscert_cred_create(resolver_t *res)
{
private_dnscert_cred_t *this;
INIT(this,
.public = {
.set = {
.create_private_enumerator = (void*)return_null,
.create_cert_enumerator = _create_cert_enumerator,
.create_shared_enumerator = (void*)return_null,
.create_cdp_enumerator = (void*)return_null,
.cache_cert = (void*)nop,
},
.destroy = _destroy,
},
.res = res,
);
return &this->public;
}

View File

@ -0,0 +1,63 @@
/*
* Copyright (C) 2013 Ruslan Marchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @defgroup dnscert_cred_i dnscert_cred
* @{ @ingroup dnscert
*/
#ifndef DNSCERT_CRED_H_
#define DNSCERT_CRED_H_
#include <credentials/credential_set.h>
#include <resolver/resolver.h>
typedef struct dnscert_cred_t dnscert_cred_t;
/**
* DNSCERT credential set.
*
* The dnscert credential set contains CERT RRs as certificates.
*/
struct dnscert_cred_t {
/**
* Implements credential_set_t interface
*/
credential_set_t set;
/**
* Destroy the dnscert_cred.
*/
void (*destroy)(dnscert_cred_t *this);
};
/**
* Create a dnscert_cred instance which uses the given resolver
* to query the DNS for CERT resource records.
*
* @param res resolver to use (gets adopted)
* @return credential set
*/
dnscert_cred_t *dnscert_cred_create(resolver_t *res);
#endif /** DNSCERT_CRED_H_ @}*/

View File

@ -0,0 +1,166 @@
/*
* Copyright (C) 2013 Tobias Brunner
* Copyright (C) 2012 Reto Guadagnini
* 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.
*/
/*
* Copyright (C) 2013 Ruslan Marchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
#include "dnscert_plugin.h"
#include <daemon.h>
#include "dnscert_cred.h"
typedef struct private_dnscert_plugin_t private_dnscert_plugin_t;
/**
* private data of the dnscert plugin
*/
struct private_dnscert_plugin_t {
/**
* implements plugin interface
*/
dnscert_plugin_t public;
/**
* credential set
*/
dnscert_cred_t *cred;
/**
* DNSCERT based authentication enabled
*/
bool enabled;
};
METHOD(plugin_t, get_name, char*,
private_dnscert_plugin_t *this)
{
return "dnscert";
}
METHOD(plugin_t, reload, bool,
private_dnscert_plugin_t *this)
{
bool enabled = lib->settings->get_bool(lib->settings,
"%s.plugins.dnscert.enable", FALSE, charon->name);
if (enabled != this->enabled)
{
if (enabled)
{
lib->credmgr->add_set(lib->credmgr, &this->cred->set);
}
else
{
lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
}
this->enabled = enabled;
}
DBG1(DBG_CFG, "dnscert plugin is %sabled", this->enabled ? "en" : "dis");
return TRUE;
}
/**
* Create resolver and register credential set
*/
static bool plugin_cb(private_dnscert_plugin_t *this,
plugin_feature_t *feature, bool reg, void *cb_data)
{
if (reg)
{
resolver_t *res;
res = lib->resolver->create(lib->resolver);
if (!res)
{
DBG1(DBG_CFG, "failed to create a DNS resolver instance");
return FALSE;
}
this->cred = dnscert_cred_create(res);
reload(this);
}
else
{
if (this->enabled)
{
lib->credmgr->remove_set(lib->credmgr, &this->cred->set);
}
this->cred->destroy(this->cred);
}
return TRUE;
}
METHOD(plugin_t, get_features, int,
private_dnscert_plugin_t *this, plugin_feature_t *features[])
{
static plugin_feature_t f[] = {
PLUGIN_CALLBACK((plugin_feature_callback_t)plugin_cb, NULL),
PLUGIN_PROVIDE(CUSTOM, "dnscert"),
PLUGIN_DEPENDS(RESOLVER),
PLUGIN_DEPENDS(CERT_DECODE, CERT_ANY),
PLUGIN_SDEPEND(CERT_DECODE, CERT_X509),
PLUGIN_SDEPEND(CERT_DECODE, CERT_GPG),
};
*features = f;
return countof(f);
}
METHOD(plugin_t, destroy, void,
private_dnscert_plugin_t *this)
{
free(this);
}
/*
* see header file
*/
plugin_t *dnscert_plugin_create()
{
private_dnscert_plugin_t *this;
INIT(this,
.public = {
.plugin = {
.get_name = _get_name,
.get_features = _get_features,
.reload = _reload,
.destroy = _destroy,
},
},
);
return &this->public.plugin;
}

View File

@ -0,0 +1,55 @@
/*
* Copyright (C) 2013 Ruslan Marchenko
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
/**
* @defgroup dnscert dnscert
* @ingroup cplugins
*
* @defgroup dnscert_plugin dnscert_plugin
* @{ @ingroup dnscert
*/
#ifndef DNSCERT_PLUGIN_H_
#define DNSCERT_PLUGIN_H_
#include <plugins/plugin.h>
typedef struct dnscert_plugin_t dnscert_plugin_t;
/**
* DNSCERT plugin
*
* The DNSCERT plugin registers a credential set for CERT RRs.
*
* With this credential set it is possible to authenticate tunnel endpoints
* using CERT resource records which are retrieved from the DNS in a secure
* way (DNSSEC).
*/
struct dnscert_plugin_t {
/**
* implements plugin interface
*/
plugin_t plugin;
};
#endif /** DNSCERT_PLUGIN_H_ @}*/