diff options
Diffstat (limited to 'src/libstrongswan/resolver')
-rw-r--r-- | src/libstrongswan/resolver/resolver.h | 58 | ||||
-rw-r--r-- | src/libstrongswan/resolver/resolver_manager.c | 90 | ||||
-rw-r--r-- | src/libstrongswan/resolver/resolver_manager.h | 72 | ||||
-rw-r--r-- | src/libstrongswan/resolver/resolver_response.h | 143 | ||||
-rw-r--r-- | src/libstrongswan/resolver/rr.h | 268 | ||||
-rw-r--r-- | src/libstrongswan/resolver/rr_set.c | 100 | ||||
-rw-r--r-- | src/libstrongswan/resolver/rr_set.h | 79 |
7 files changed, 810 insertions, 0 deletions
diff --git a/src/libstrongswan/resolver/resolver.h b/src/libstrongswan/resolver/resolver.h new file mode 100644 index 000000000..5be52b8b1 --- /dev/null +++ b/src/libstrongswan/resolver/resolver.h @@ -0,0 +1,58 @@ +/* + * Copyright (C) 2011-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. + */ + +/** + * @defgroup resolveri resolver + * @{ @ingroup resolver + */ + +#ifndef RESOLVER_H_ +#define RESOLVER_H_ + +typedef struct resolver_t resolver_t; + +/** + * Constructor function which creates DNS resolver instances. + */ +typedef resolver_t* (*resolver_constructor_t)(void); + +#include <resolver/resolver_response.h> +#include <resolver/rr_set.h> +#include <resolver/rr.h> + +/** + * Interface of a security-aware DNS resolver. + * + */ +struct resolver_t { + + /** + * Perform a DNS query. + * + * @param domain domain (FQDN) to query + * @param rr_class class of the desired RRs + * @param rr_type type of the desired RRs + * @return response to the query, NULL on failure + */ + resolver_response_t *(*query)(resolver_t *this, char *domain, + rr_class_t rr_class, rr_type_t rr_type); + + /** + * Destroy the resolver instance. + */ + void (*destroy)(resolver_t *this); +}; + +#endif /** RESOLVER_H_ @}*/ diff --git a/src/libstrongswan/resolver/resolver_manager.c b/src/libstrongswan/resolver/resolver_manager.c new file mode 100644 index 000000000..55531e157 --- /dev/null +++ b/src/libstrongswan/resolver/resolver_manager.c @@ -0,0 +1,90 @@ +/* + * Copyright (C) 2011-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. + */ + +#include "resolver_manager.h" + +#include <utils/debug.h> + +typedef struct private_resolver_manager_t private_resolver_manager_t; + +/** + * private data of resolver_manager + */ +struct private_resolver_manager_t { + + /** + * public functions + */ + resolver_manager_t public; + + /** + * constructor function to create resolver instances + */ + resolver_constructor_t constructor; +}; + +METHOD(resolver_manager_t, add_resolver, void, + private_resolver_manager_t *this, resolver_constructor_t constructor) +{ + if (!this->constructor) + { + this->constructor = constructor; + } +} + +METHOD(resolver_manager_t, remove_resolver, void, + private_resolver_manager_t *this, resolver_constructor_t constructor) +{ + if (this->constructor == constructor) + { + this->constructor = NULL; + } +} + +METHOD(resolver_manager_t, create, resolver_t*, + private_resolver_manager_t *this) +{ + if (this->constructor) + { + return this->constructor(); + } + return NULL; +} + +METHOD(resolver_manager_t, destroy, void, + private_resolver_manager_t *this) +{ + free(this); +} + +/* + * See header + */ +resolver_manager_t *resolver_manager_create() +{ + private_resolver_manager_t *this; + + INIT(this, + .public = { + .add_resolver = _add_resolver, + .remove_resolver = _remove_resolver, + .create = _create, + .destroy = _destroy, + }, + ); + + return &this->public; +} + diff --git a/src/libstrongswan/resolver/resolver_manager.h b/src/libstrongswan/resolver/resolver_manager.h new file mode 100644 index 000000000..6ea22aa24 --- /dev/null +++ b/src/libstrongswan/resolver/resolver_manager.h @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2011-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. + */ + +/** +* @defgroup resolver_manager resolver_manager +* @{ @ingroup resolver +*/ + +#ifndef RESOLVER_MANAGER_H_ +#define RESOLVER_MANAGER_H_ + +typedef struct resolver_manager_t resolver_manager_t; + +#include <resolver/resolver.h> + +/** + * The resolver_manager manages the resolver implementations and + * creates instances of them. + * + * A resolver plugin is registered by providing its constructor function + * to the manager. The manager creates instances of the resolver plugin + * using the registered constructor function. + */ +struct resolver_manager_t { + + /** + * Register a resolver implementation. + * + * @param constructor resolver constructor function + */ + void (*add_resolver)(resolver_manager_t *this, + resolver_constructor_t constructor); + + /** + * Unregister a previously registered resolver implementation. + * + * @param constructor resolver constructor function to unregister + */ + void (*remove_resolver)(resolver_manager_t *this, + resolver_constructor_t constructor); + + /** + * Get a new resolver instance. + * + * @return resolver instance. + */ + resolver_t* (*create)(resolver_manager_t *this); + + /** + * Destroy a resolver_manager instance. + */ + void (*destroy)(resolver_manager_t *this); +}; + +/** + * Create a resolver_manager instance. + */ +resolver_manager_t *resolver_manager_create(); + +#endif /** RESOLVER_MANAGER_H_ @}*/ diff --git a/src/libstrongswan/resolver/resolver_response.h b/src/libstrongswan/resolver/resolver_response.h new file mode 100644 index 000000000..e45fb6401 --- /dev/null +++ b/src/libstrongswan/resolver/resolver_response.h @@ -0,0 +1,143 @@ +/* + * 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. + */ + +/** + * @defgroup rsolver_response resolver_response + * @{ @ingroup resolver + */ + +#ifndef RESOLVER_RESPONSE_H_ +#define RESOLVER_RESPONSE_H_ + +typedef struct resolver_response_t resolver_response_t; +typedef enum dnssec_status_t dnssec_status_t; + +#include <library.h> +#include <resolver/rr_set.h> + +/** + * DNSSEC security state. + * + * DNSSEC security state, which a security aware resolver is able determine + * according to RFC 4033. + */ +enum dnssec_status_t { + /** + * The validating resolver has a trust anchor, has a chain of + * trust, and is able to verify all the signatures in the response. + * [RFC4033] + */ + SECURE, + /** + * The validating resolver has a trust anchor, a chain of + * trust, and, at some delegation point, signed proof of the + * non-existence of a DS record. This indicates that subsequent + * branches in the tree are provably insecure. A validating resolver + * may have a local policy to mark parts of the domain space as + * insecure. [RFC4033] + */ + INSECURE, + /** + * The validating resolver has a trust anchor and a secure + * delegation indicating that subsidiary data is signed, but the + * response fails to validate for some reason: missing signatures, + * expired signatures, signatures with unsupported algorithms, data + * missing that the relevant NSEC RR says should be present, and so + * forth. [RFC4033] + */ + BOGUS, + /** + * There is no trust anchor that would indicate that a + * specific portion of the tree is secure. This is the default + * operation mode. [RFC4033] + */ + INDETERMINATE, +}; + + +/** + * A response of the DNS resolver to a DNS query. + * + * A response represents the answer of the Domain Name System to a query. + * It contains the RRset with the queried Resource Records and additional + * information. + */ +struct resolver_response_t { + + /** + * Get the original question string. + * + * The string to which the returned pointer points, is still owned + * by the resolver_response. Clone it if necessary. + * + * @return the queried name + */ + char *(*get_query_name)(resolver_response_t *this); + + /** + * Get the canonical name of the result. + * + * The string to which the returned pointer points, is still owned + * by the resolver_response. Clone it if necessary. + * + * @return - canonical name of result + * - NULL, if result has no canonical name + */ + char *(*get_canon_name)(resolver_response_t *this); + + /** + * Does the RRset of this response contain some Resource Records? + * + * Returns TRUE if the RRset of this response contains some RRs + * (RRSIG Resource Records are ignored). + * + * @return + * - TRUE, if there are some RRs in the RRset + * - FALSE, otherwise + */ + bool (*has_data)(resolver_response_t *this); + + /** + * Does the queried name exist? + * + * @return + * - TRUE, if the queried name exists + * - FALSE, otherwise + */ + bool (*query_name_exist)(resolver_response_t *this); + + /** + * Get the DNSSEC security state of the response. + * + * @return DNSSEC security state + */ + dnssec_status_t (*get_security_state)(resolver_response_t *this); + + /** + * Get the RRset with all Resource Records of this response. + * + * @return - RRset + * - NULL if there is no data or the query name + * does not exist + */ + rr_set_t *(*get_rr_set)(resolver_response_t *this); + + /** + * Destroy this response. + */ + void (*destroy) (resolver_response_t *this); +}; + +#endif /** RR_SET_H_ @}*/ diff --git a/src/libstrongswan/resolver/rr.h b/src/libstrongswan/resolver/rr.h new file mode 100644 index 000000000..109ec5135 --- /dev/null +++ b/src/libstrongswan/resolver/rr.h @@ -0,0 +1,268 @@ +/* + * 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. + */ + +/** + * @defgroup rr rr + * @{ @ingroup resolver + */ + +#ifndef RR_H_ +#define RR_H_ + +typedef struct rr_t rr_t; +typedef enum rr_type_t rr_type_t; +typedef enum rr_class_t rr_class_t; + +#include <library.h> + +/** + * Resource Record types. + * + * According to www.iana.org/assignments/dns-parameters (version 2012-03-13). + */ +enum rr_type_t { + /** a host address */ + RR_TYPE_A = 1, + /** an authoritative name server */ + RR_TYPE_NS = 2, + //** a mail destination (OBSOLETE - use MX */ + RR_TYPE_MD = 3, + /** a mail forwarder (OBSOLETE - use MX) */ + RR_TYPE_MF = 4, + /** the canonical name for an alias */ + RR_TYPE_CNAME = 5, + /** marks the start of a zone of authority */ + RR_TYPE_SOA = 6, + /** a mailbox domain name (EXPERIMENTAL) */ + RR_TYPE_MB = 7, + /** a mail group member (EXPERIMENTAL) */ + RR_TYPE_MG = 8, + /** a mail rename domain name (EXPERIMENTAL) */ + RR_TYPE_MR = 9, + /** a null RR (EXPERIMENTAL) */ + RR_TYPE_NULL = 10, + /** a well known service description */ + RR_TYPE_WKS = 11, + /** a domain name pointer */ + RR_TYPE_PTR = 12, + /** host information */ + RR_TYPE_HINFO = 13, + /** mailbox or mail list information */ + RR_TYPE_MINFO = 14, + /** mail exchange */ + RR_TYPE_MX = 15, + /** text strings */ + RR_TYPE_TXT = 16, + /** for Responsible Person */ + RR_TYPE_RP = 17, + /** for AFS Data Base location */ + RR_TYPE_AFSDB = 18, + /** for X.25 PSDN address */ + RR_TYPE_X25 = 19, + /** for ISDN address */ + RR_TYPE_ISDN = 20, + /** for Route Through */ + RR_TYPE_RT = 21, + /** for NSAP address, NSAP style A record */ + RR_TYPE_NSAP = 22, + /** for domain name pointer, NSAP style */ + RR_TYPE_NSAP_PTR = 23, + /** for security signature */ + RR_TYPE_SIG = 24, + /** for security key */ + RR_TYPE_KEY = 25, + /** X.400 mail mapping information */ + RR_TYPE_PX = 26, + /** Geographical Position */ + RR_TYPE_GPOS = 27, + /** ipv6 address */ + RR_TYPE_AAAA = 28, + /** Location Information */ + RR_TYPE_LOC = 29, + /** Next Domain (OBSOLETE) */ + RR_TYPE_NXT = 30, + /** Endpoint Identifier */ + RR_TYPE_EID = 31, + /** Nimrod Locator */ + RR_TYPE_NIMLOC = 32, + /** Server Selection */ + RR_TYPE_SRV = 33, + /** ATM Address */ + RR_TYPE_ATMA = 34, + /** Naming Authority Pointer */ + RR_TYPE_NAPTR = 35, + /** Key Exchanger */ + RR_TYPE_KX = 36, + /** CERT */ + RR_TYPE_CERT = 37, + /** A6 (OBSOLETE - use AAAA) */ + RR_TYPE_A6 = 38, + /** DNAME */ + RR_TYPE_DNAME = 39, + /** SINK */ + RR_TYPE_SINK = 40, + /** OPT */ + RR_TYPE_OPT = 41, + /** APL */ + RR_TYPE_APL = 42, + /** Delegation Signer */ + RR_TYPE_DS = 43, + /** SSH Key Fingerprint */ + RR_TYPE_SSHFP = 44, + /** IPSECKEY */ + RR_TYPE_IPSECKEY = 45, + /** RRSIG */ + RR_TYPE_RRSIG = 46, + /** NSEC */ + RR_TYPE_NSEC = 47, + /** DNSKEY */ + RR_TYPE_DNSKEY = 48, + /** DHCID */ + RR_TYPE_DHCID = 49, + /** NSEC3 */ + RR_TYPE_NSEC3 = 50, + /** NSEC3PARAM */ + RR_TYPE_NSEC3PARAM = 51, + + /** Unassigned 52-54 */ + + /** Host Identity Protocol */ + RR_TYPE_HIP = 55, + /** NINFO */ + RR_TYPE_NINFO = 56, + /** RKEY */ + RR_TYPE_RKEY = 57, + /** Trust Anchor LINK */ + RR_TYPE_TALINK = 58, + /** Child DS */ + RR_TYPE_CDS = 59, + + /** Unassigned 60-98 */ + + /** SPF */ + RR_TYPE_SPF = 99, + /** UINFO */ + RR_TYPE_UINFO = 100, + /** UID */ + RR_TYPE_UID = 101, + /** GID */ + RR_TYPE_GID = 102, + /** UNSPEC */ + RR_TYPE_UNSPEC = 103, + + /** Unassigned 104-248 */ + + /** Transaction Key */ + RR_TYPE_TKEY = 249, + /** Transaction Signature */ + RR_TYPE_TSIG = 250, + /** incremental transfer */ + RR_TYPE_IXFR = 251, + /** transfer of an entire zone */ + RR_TYPE_AXFR = 252, + /** mailbox-related RRs (MB, MG or MR) */ + RR_TYPE_MAILB = 253, + /** mail agent RRs (OBSOLETE - see MX) */ + RR_TYPE_MAILA = 254, + /** A request for all records */ + RR_TYPE_ANY = 255, + /** URI */ + RR_TYPE_URI = 256, + /** Certification Authority Authorization */ + RR_TYPE_CAA = 257, + + /** Unassigned 258-32767 */ + + /** DNSSEC Trust Authorities */ + RR_TYPE_TA = 32768, + /** DNSSEC Lookaside Validation */ + RR_TYPE_DLV = 32769, + + /** Unassigned 32770-65279 */ + + /** Private use 65280-65534 */ + + /** Reserved 65535 */ +}; + + +/** + * Resource Record CLASSes + */ +enum rr_class_t { + /** Internet */ + RR_CLASS_IN = 1, + /** Chaos */ + RR_CLASS_CH = 3, + /** Hesiod */ + RR_CLASS_HS = 4, + /** further CLASSes: http://wwwiana.org/assignments/dns-parameters */ +}; + + +/** + * A DNS Resource Record. + * + * Represents a Resource Record of the Domain Name System + * as defined in RFC 1035. + * + */ +struct rr_t { + + /** + * Get the NAME of the owner of this RR. + * + * @return owner name as string + */ + char *(*get_name)(rr_t *this); + + /** + * Get the type of this RR. + * + * @return RR type + */ + rr_type_t (*get_type)(rr_t *this); + + /** + * Get the class of this RR. + * + * @return RR class + */ + rr_class_t (*get_class)(rr_t *this); + + /** + * Get the Time to Live (TTL) of this RR. + * + * @return Time to Live + */ + uint32_t (*get_ttl)(rr_t *this); + + /** + * Get the content of the RDATA field as chunk. + * + * The data pointed by the chunk is still owned by the RR. + * Clone it if needed. + * + * @return RDATA field as chunk + */ + chunk_t (*get_rdata)(rr_t *this); + + /** + * Destroy the Resource Record. + */ + void (*destroy) (rr_t *this); +}; + +#endif /** RR_H_ @}*/ diff --git a/src/libstrongswan/resolver/rr_set.c b/src/libstrongswan/resolver/rr_set.c new file mode 100644 index 000000000..dea5c4086 --- /dev/null +++ b/src/libstrongswan/resolver/rr_set.c @@ -0,0 +1,100 @@ +/* + * 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. + */ + +#include "rr_set.h" + +#include <library.h> +#include <utils/debug.h> + +typedef struct private_rr_set_t private_rr_set_t; + +/** +* private data of the rr_set +*/ +struct private_rr_set_t { + + /** + * public functions + */ + rr_set_t public; + + /** + * List of Resource Records which form the RRset + */ + linked_list_t *rr_list; + + /** + * List of the signatures (RRSIGs) of the Resource Records contained in + * this set + */ + linked_list_t *rrsig_list; +}; + +METHOD(rr_set_t, create_rr_enumerator, enumerator_t*, + private_rr_set_t *this) +{ + return this->rr_list->create_enumerator(this->rr_list); +} + +METHOD(rr_set_t, create_rrsig_enumerator, enumerator_t*, + private_rr_set_t *this) +{ + if (this->rrsig_list) + { + return this->rrsig_list->create_enumerator(this->rrsig_list); + } + return NULL; +} + +METHOD(rr_set_t, destroy, void, + private_rr_set_t *this) +{ + this->rr_list->destroy_offset(this->rr_list, + offsetof(rr_t, destroy)); + if (this->rrsig_list) + { + this->rrsig_list->destroy_offset(this->rrsig_list, + offsetof(rr_t, destroy)); + } + free(this); +} + +/* + * see header + */ +rr_set_t *rr_set_create(linked_list_t *list_of_rr, linked_list_t *list_of_rrsig) +{ + private_rr_set_t *this; + + INIT(this, + .public = { + .create_rr_enumerator = _create_rr_enumerator, + .create_rrsig_enumerator = _create_rrsig_enumerator, + .destroy = _destroy, + }, + ); + + if (list_of_rr == NULL) + { + DBG1(DBG_LIB, "could not create a rr_set without a list_of_rr"); + _destroy(this); + return NULL; + } + this->rr_list = list_of_rr; + this->rrsig_list = list_of_rrsig; + + return &this->public; +} + diff --git a/src/libstrongswan/resolver/rr_set.h b/src/libstrongswan/resolver/rr_set.h new file mode 100644 index 000000000..5a1737a05 --- /dev/null +++ b/src/libstrongswan/resolver/rr_set.h @@ -0,0 +1,79 @@ +/* + * 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. + */ + +/** + * @defgroup rr_set rr_set + * @{ @ingroup resolver + */ + +#ifndef RR_SET_H_ +#define RR_SET_H_ + +typedef struct rr_set_t rr_set_t; + +#include <library.h> +#include <collections/enumerator.h> +#include <collections/linked_list.h> + +/** + * A set of DNS Resource Records. + * + * Represents a RRset as defined in RFC 2181. This RRset consists of a set of + * Resource Records with the same label, class and type but different data. + * + * The DNSSEC signature Resource Records (RRSIGs) which sign the RRs of this set + * are also part of an object of this type. + */ +struct rr_set_t { + + /** + * Create an enumerator over all Resource Records of this RRset. + * + * @note The enumerator's position is invalid before the first call + * to enumerate(). + * + * @return enumerator over Resource Records + */ + enumerator_t *(*create_rr_enumerator)(rr_set_t *this); + + /** + * Create an enumerator over all RRSIGs of this RRset + * + * @note The enumerator's position is invalid before the first call + * to enumerate(). + * + * @return enumerator over RRSIG Resource Records, + * NULL if there are no RRSIGs for this RRset + */ + enumerator_t *(*create_rrsig_enumerator)(rr_set_t *this); + + /** + * Destroy this RRset with all its Resource Records. + */ + void (*destroy) (rr_set_t *this); +}; + +/** + * Create an rr_set instance. + * + * @param list_of_rr list of Resource Records which form this RRset + * @param list_of_rrsig list of the signatures (RRSIGs) of the + * Resource Records of this set + * @return Resource Record set, NULL on failure + */ +rr_set_t *rr_set_create(linked_list_t *list_of_rr, + linked_list_t *list_of_rrsig); + +#endif /** RR_SET_H_ @}*/ |