resolved: introduce a dnssec_mode setting per scope

The setting controls which kind of DNSSEC validation is done: none at
all, trusting the AD bit, or client-side validation.

For now, no validation is implemented, hence the setting doesn't do much
yet, except of toggling the CD bit in the generated messages if full
client-side validation is requested.
This commit is contained in:
Lennart Poettering 2015-12-03 19:51:04 +01:00
parent 896c567247
commit 24710c48ed
11 changed files with 73 additions and 6 deletions

View File

@ -234,6 +234,41 @@ int config_parse_support(
return 0; return 0;
} }
int config_parse_dnssec(
const char *unit,
const char *filename,
unsigned line,
const char *section,
unsigned section_line,
const char *lvalue,
int ltype,
const char *rvalue,
void *data,
void *userdata) {
Manager *m = data;
DnssecMode mode;
int r;
assert(filename);
assert(lvalue);
assert(rvalue);
mode = dnssec_mode_from_string(rvalue);
if (mode < 0) {
r = parse_boolean(rvalue);
if (r < 0) {
log_syntax(unit, LOG_ERR, filename, line, r, "Failed to parse DNSSEC mode '%s'. Ignoring.", rvalue);
return 0;
}
mode = r ? DNSSEC_YES : DNSSEC_NO;
}
m->unicast_scope->dnssec_mode = mode;
return 0;
}
int manager_parse_config_file(Manager *m) { int manager_parse_config_file(Manager *m) {
int r; int r;

View File

@ -36,3 +36,4 @@ const struct ConfigPerfItem* resolved_gperf_lookup(const char *key, unsigned len
int config_parse_dns_servers(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_dns_servers(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_search_domains(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_search_domains(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_support(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata); int config_parse_support(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);
int config_parse_dnssec(const char *unit, const char *filename, unsigned line, const char *section, unsigned section_line, const char *lvalue, int ltype, const char *rvalue, void *data, void *userdata);

View File

@ -25,6 +25,7 @@
#include "dns-domain.h" #include "dns-domain.h"
#include "resolved-dns-dnssec.h" #include "resolved-dns-dnssec.h"
#include "resolved-dns-packet.h" #include "resolved-dns-packet.h"
#include "string-table.h"
/* Open question: /* Open question:
* *
@ -697,3 +698,10 @@ finish:
gcry_md_close(md); gcry_md_close(md);
return r; return r;
} }
static const char* const dnssec_mode_table[_DNSSEC_MODE_MAX] = {
[DNSSEC_NO] = "no",
[DNSSEC_TRUST] = "trust",
[DNSSEC_YES] = "yes",
};
DEFINE_STRING_TABLE_LOOKUP(dnssec_mode, DnssecMode);

View File

@ -21,10 +21,26 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>. along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/ ***/
typedef enum DnssecMode DnssecMode;
#include "dns-domain.h" #include "dns-domain.h"
#include "resolved-dns-answer.h" #include "resolved-dns-answer.h"
#include "resolved-dns-rr.h" #include "resolved-dns-rr.h"
enum DnssecMode {
/* No DNSSEC validation is done */
DNSSEC_NO,
/* Trust the AD bit sent by the server. UNSAFE! */
DNSSEC_TRUST,
/* Validate locally, if the server knows DO, but if not, don't. Don't trust the AD bit */
DNSSEC_YES,
_DNSSEC_MODE_MAX,
_DNSSEC_MODE_INVALID = -1
};
enum { enum {
DNSSEC_VERIFIED, DNSSEC_VERIFIED,
DNSSEC_INVALID, DNSSEC_INVALID,
@ -33,7 +49,6 @@ enum {
DNSSEC_SIGNATURE_EXPIRED, DNSSEC_SIGNATURE_EXPIRED,
}; };
#define DNSSEC_CANONICAL_HOSTNAME_MAX (DNS_HOSTNAME_MAX + 2) #define DNSSEC_CANONICAL_HOSTNAME_MAX (DNS_HOSTNAME_MAX + 2)
int dnssec_rrsig_match_dnskey(DnsResourceRecord *rrsig, DnsResourceRecord *dnskey); int dnssec_rrsig_match_dnskey(DnsResourceRecord *rrsig, DnsResourceRecord *dnskey);
@ -47,3 +62,6 @@ int dnssec_verify_dnskey(DnsResourceRecord *dnskey, DnsResourceRecord *ds);
uint16_t dnssec_keytag(DnsResourceRecord *dnskey); uint16_t dnssec_keytag(DnsResourceRecord *dnskey);
int dnssec_canonicalize(const char *n, char *buffer, size_t buffer_max); int dnssec_canonicalize(const char *n, char *buffer, size_t buffer_max);
const char* dnssec_mode_to_string(DnssecMode m) _const_;
DnssecMode dnssec_mode_from_string(const char *s) _pure_;

View File

@ -65,7 +65,7 @@ int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
return 0; return 0;
} }
int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu) { int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu, bool dnssec_checking_disabled) {
DnsPacket *p; DnsPacket *p;
DnsPacketHeader *h; DnsPacketHeader *h;
int r; int r;
@ -96,7 +96,7 @@ int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
1 /* rd (ask for recursion) */, 1 /* rd (ask for recursion) */,
0 /* ra */, 0 /* ra */,
0 /* ad */, 0 /* ad */,
0 /* cd */, dnssec_checking_disabled /* cd */,
0 /* rcode */)); 0 /* rcode */));
*ret = p; *ret = p;

View File

@ -144,7 +144,7 @@ static inline unsigned DNS_PACKET_RRCOUNT(DnsPacket *p) {
} }
int dns_packet_new(DnsPacket **p, DnsProtocol protocol, size_t mtu); int dns_packet_new(DnsPacket **p, DnsProtocol protocol, size_t mtu);
int dns_packet_new_query(DnsPacket **p, DnsProtocol protocol, size_t mtu); int dns_packet_new_query(DnsPacket **p, DnsProtocol protocol, size_t mtu, bool dnssec_checking_disabled);
DnsPacket *dns_packet_ref(DnsPacket *p); DnsPacket *dns_packet_ref(DnsPacket *p);
DnsPacket *dns_packet_unref(DnsPacket *p); DnsPacket *dns_packet_unref(DnsPacket *p);

View File

@ -26,6 +26,7 @@
typedef struct DnsScope DnsScope; typedef struct DnsScope DnsScope;
#include "resolved-dns-cache.h" #include "resolved-dns-cache.h"
#include "resolved-dns-dnssec.h"
#include "resolved-dns-packet.h" #include "resolved-dns-packet.h"
#include "resolved-dns-server.h" #include "resolved-dns-server.h"
#include "resolved-dns-zone.h" #include "resolved-dns-zone.h"
@ -44,6 +45,7 @@ struct DnsScope {
DnsProtocol protocol; DnsProtocol protocol;
int family; int family;
DnssecMode dnssec_mode;
Link *link; Link *link;

View File

@ -61,10 +61,11 @@ struct DnsServer {
int family; int family;
union in_addr_union address; union in_addr_union address;
bool marked:1;
usec_t resend_timeout; usec_t resend_timeout;
usec_t max_rtt; usec_t max_rtt;
bool marked:1;
DnsServerFeatureLevel verified_features; DnsServerFeatureLevel verified_features;
DnsServerFeatureLevel possible_features; DnsServerFeatureLevel possible_features;
size_t received_udp_packet_max; size_t received_udp_packet_max;

View File

@ -598,7 +598,7 @@ static int dns_transaction_make_packet(DnsTransaction *t) {
if (t->sent) if (t->sent)
return 0; return 0;
r = dns_packet_new_query(&p, t->scope->protocol, 0); r = dns_packet_new_query(&p, t->scope->protocol, 0, t->scope->dnssec_mode == DNSSEC_YES);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -18,3 +18,4 @@ Resolve.DNS, config_parse_dns_servers, DNS_SERVER_SYSTEM, 0
Resolve.FallbackDNS, config_parse_dns_servers, DNS_SERVER_FALLBACK, 0 Resolve.FallbackDNS, config_parse_dns_servers, DNS_SERVER_FALLBACK, 0
Resolve.Domains, config_parse_search_domains, 0, 0 Resolve.Domains, config_parse_search_domains, 0, 0
Resolve.LLMNR, config_parse_support, 0, offsetof(Manager, llmnr_support) Resolve.LLMNR, config_parse_support, 0, offsetof(Manager, llmnr_support)
Resolve.DNSSEC, config_parse_dnssec, 0, 0

View File

@ -16,3 +16,4 @@
#FallbackDNS=@DNS_SERVERS@ #FallbackDNS=@DNS_SERVERS@
#Domains= #Domains=
#LLMNR=yes #LLMNR=yes
#DNSSEC=no