[ldns-users] [PATCH 1/3] Add an anchor keyword to the resolver configuration
Simon Vallet
svallet at genoscope.cns.fr
Mon May 14 10:16:00 UTC 2007
this one adds an anchor keyword to the resolver configuration, allowing
for trust anchors in ldns.
Simon
Index: ldns/resolver.h
===================================================================
--- ldns/resolver.h (revision 2344)
+++ ldns/resolver.h (working copy)
@@ -39,8 +39,9 @@
#define LDNS_RESOLV_SEARCH 2
#define LDNS_RESOLV_SORTLIST 3
#define LDNS_RESOLV_OPTIONS 4
+#define LDNS_RESOLV_ANCHOR 5
-#define LDNS_RESOLV_KEYWORDS 5
+#define LDNS_RESOLV_KEYWORDS 6
#define LDNS_RESOLV_INETANY 0
#define LDNS_RESOLV_INET 1
@@ -62,8 +63,8 @@
/** Number of nameservers in \c _nameservers */
size_t _nameserver_count; /* how many do we have */
- /** Round trip time; 0 -> infinity. Unit: ms? */
- size_t *_rtt;
+ /** Round trip time; 0 -> infinity. Unit: ms? */
+ size_t *_rtt;
/** Wether or not to be recursive */
bool _recursive;
@@ -89,6 +90,8 @@
bool _dnssec;
/** Whether to set the CD bit on DNSSEC requests */
bool _dnssec_cd;
+ /** Optional trust anchors for complete DNSSEC validation */
+ ldns_rr_list * _dnssec_anchors;
/** Whether to use tcp or udp (tcp if the value is true)*/
bool _usevc;
/** Whether to ignore the tc bit */
@@ -209,6 +212,12 @@
*/
bool ldns_resolver_dnssec_cd(const ldns_resolver *r);
/**
+ * Get the resolver's DNSSEC anchors
+ * \param[in] r the resolver
+ * \return an rr_list containg trusted DNSSEC anchors
+ */
+ldns_rr_list * ldns_resolver_dnssec_anchors(const ldns_resolver *r);
+/**
* Does the resolver ignore the TC bit (truncated)
* \param[in] r the resolver
* \return true: yes, false: no
@@ -409,6 +418,21 @@
*/
void ldns_resolver_set_dnssec_cd(ldns_resolver *r, bool b);
/**
+ * Set the resolver's DNSSEC anchor list directly. RRs should be of type DS or DNSKEY.
+ * \param[in] r the resolver
+ * \param[in] l the list of RRs to use as trust anchors
+ */
+void ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l);
+
+/**
+ * Push a new trust anchor to the resolver. It must be a DS or DNSKEY rr
+ * \param[in] r the resolver.
+ * \param[in] rr the RR to add as a trust anchor.
+ * \return a status
+ */
+ldns_status ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr);
+
+/**
* Set the resolver retrans timeout (in seconds)
* \param[in] r the resolver
* \param[in] re the retransmission interval in seconds
@@ -655,4 +679,20 @@
*/
void ldns_resolver_nameservers_randomize(ldns_resolver *r);
+/**
+ * Returns true if at least one of the provided keys is a trust anchor
+ * \param[in] r the current resolver
+ * \param[in] keys the keyset to check
+ * \param[out] trusted_keys the subset of trusted keys in the 'keys' rrset
+ * \return true if at least one of the provided keys is a configured trust anchor
+ */
+bool ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list * keys, ldns_rr_list * trusted_keys);
+
+/**
+ * Instantiates a DNSKEY or DS RR from file.
+ * \param[in] filename the file to read the record from
+ * \return the corresponding RR, or NULL if the parsing failed
+ */
+ldns_rr * ldns_read_anchor_file(const char *filename);
+
#endif /* LDNS_RESOLVER_H */
Index: resolver.c
===================================================================
--- resolver.c (revision 2344)
+++ resolver.c (working copy)
@@ -116,7 +116,34 @@
return r->_dnssec_cd;
}
+ldns_rr_list *
+ldns_resolver_dnssec_anchors(const ldns_resolver *r)
+{
+ return r->_dnssec_anchors;
+}
+
bool
+ldns_resolver_trusted_key(const ldns_resolver *r, ldns_rr_list * keys, ldns_rr_list * trusted_keys)
+{
+ unsigned int i; bool result = false;
+ ldns_rr_list * trust_anchors = ldns_resolver_dnssec_anchors(r);
+ ldns_rr * cur_rr;
+
+ if (!r || !trust_anchors || !keys) { return false; }
+
+ for (i=0; i< ldns_rr_list_rr_count(keys); i++) {
+
+ cur_rr = ldns_rr_list_rr(keys, i);
+ if (ldns_rr_list_contains_rr(trust_anchors, cur_rr)) {
+ if (trusted_keys) { ldns_rr_list_push_rr(trusted_keys, cur_rr); }
+ result = true;
+ }
+ }
+
+ return result;
+}
+
+bool
ldns_resolver_igntc(const ldns_resolver *r)
{
return r->_igntc;
@@ -316,6 +343,29 @@
}
void
+ldns_resolver_set_dnssec_anchors(ldns_resolver *r, ldns_rr_list * l)
+{
+ r->_dnssec_anchors = l;
+}
+
+ldns_status
+ldns_resolver_push_dnssec_anchor(ldns_resolver *r, ldns_rr *rr)
+{
+ ldns_rr_list * trust_anchors;
+
+ if ((!rr) || (ldns_rr_get_type(rr) != LDNS_RR_TYPE_DNSKEY)) {
+ return LDNS_STATUS_ERR;
+ }
+
+ if (!(trust_anchors = ldns_resolver_dnssec_anchors(r))) { /* Initialize */
+ trust_anchors = ldns_rr_list_new();
+ ldns_resolver_set_dnssec_anchors(r, trust_anchors);
+ }
+
+ return (ldns_rr_list_push_rr(trust_anchors, ldns_rr_clone(rr))) ? LDNS_STATUS_OK : LDNS_STATUS_ERR;
+}
+
+void
ldns_resolver_set_igntc(ldns_resolver *r, bool i)
{
r->_igntc = i;
@@ -519,6 +569,7 @@
ldns_resolver_set_edns_udp_size(r, 0);
ldns_resolver_set_dnssec(r, false);
ldns_resolver_set_dnssec_cd(r, false);
+ ldns_resolver_set_dnssec_anchors(r, NULL);
ldns_resolver_set_ip6(r, LDNS_RESOLV_INETANY);
/* randomize the nameserver to be queried
@@ -557,6 +608,7 @@
int8_t expect;
uint8_t i;
ldns_rdf *tmp;
+ ldns_rr *tmp_rr;
ssize_t gtr;
ldns_buffer *b;
@@ -574,6 +626,7 @@
/* these two are read but not used atm TODO */
keyword[LDNS_RESOLV_SORTLIST] = "sortlist";
keyword[LDNS_RESOLV_OPTIONS] = "options";
+ keyword[LDNS_RESOLV_ANCHOR] = "anchor";
expect = LDNS_RESOLV_KEYWORD;
r = ldns_resolver_new();
@@ -687,6 +740,18 @@
/* options not implemented atm */
expect = LDNS_RESOLV_KEYWORD;
break;
+ case LDNS_RESOLV_ANCHOR:
+ /* a file containing a DNSSEC trust anchor */
+ gtr = ldns_fget_token_l(fp, word, LDNS_PARSE_NORMAL, 0, line_nr);
+ if (gtr == 0) {
+ return LDNS_STATUS_SYNTAX_MISSING_VALUE_ERR;
+ }
+
+ tmp_rr = ldns_read_anchor_file(word);
+ ldns_resolver_push_dnssec_anchor(r, tmp_rr);
+ ldns_rr_free(tmp_rr);
+ expect = LDNS_RESOLV_KEYWORD;
+ break;
}
}
@@ -766,6 +831,9 @@
if (res->_rtt) {
LDNS_FREE(res->_rtt);
}
+ if (res->_dnssec_anchors) {
+ ldns_rr_list_deep_free(res->_dnssec_anchors);
+ }
LDNS_FREE(res);
}
}
@@ -1073,3 +1141,41 @@
}
ldns_resolver_set_nameservers(r, ns);
}
+
+ldns_rr *
+ldns_read_anchor_file(const char *filename)
+{
+ FILE *fp;
+ char line[LDNS_MAX_PACKETLEN];
+ int c;
+ size_t i = 0;
+ ldns_rr *r;
+ ldns_status status;
+
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Unable to open %s: %s\n", filename, strerror(errno));
+ return NULL;
+ }
+
+ while ((c = fgetc(fp)) && i < LDNS_MAX_PACKETLEN && c != EOF) {
+ line[i] = c;
+ i++;
+ }
+ line[i] = '\0';
+
+ fclose(fp);
+
+ if (i <= 0) {
+ fprintf(stderr, "nothing read from %s", filename);
+ return NULL;
+ } else {
+ status = ldns_rr_new_frm_str(&r, line, 0, NULL, NULL);
+ if (status == LDNS_STATUS_OK && (ldns_rr_get_type(r) == LDNS_RR_TYPE_DNSKEY || ldns_rr_get_type(r) == LDNS_RR_TYPE_DS)) {
+ return r;
+ } else {
+ fprintf(stderr, "Error creating DNSKEY or DS rr from %s: %s\n", filename, ldns_get_errorstr_by_id(status));
+ return NULL;
+ }
+ }
+}
More information about the ldns-users
mailing list