summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2015-12-03 19:51:04 +0100
committerLennart Poettering <lennart@poettering.net>2015-12-03 21:17:49 +0100
commit24710c48ed16be5fa461fbb303a744a907541daf (patch)
tree3331d39fd5762c7d5fe9babf50dd463a0151b011
parentresolved: add a limit on the max DNSSEC RRSIG expiry skew we allow (diff)
downloadsystemd-24710c48ed16be5fa461fbb303a744a907541daf.tar.xz
systemd-24710c48ed16be5fa461fbb303a744a907541daf.zip
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.
-rw-r--r--src/resolve/resolved-conf.c35
-rw-r--r--src/resolve/resolved-conf.h1
-rw-r--r--src/resolve/resolved-dns-dnssec.c8
-rw-r--r--src/resolve/resolved-dns-dnssec.h20
-rw-r--r--src/resolve/resolved-dns-packet.c4
-rw-r--r--src/resolve/resolved-dns-packet.h2
-rw-r--r--src/resolve/resolved-dns-scope.h2
-rw-r--r--src/resolve/resolved-dns-server.h3
-rw-r--r--src/resolve/resolved-dns-transaction.c2
-rw-r--r--src/resolve/resolved-gperf.gperf1
-rw-r--r--src/resolve/resolved.conf.in1
11 files changed, 73 insertions, 6 deletions
diff --git a/src/resolve/resolved-conf.c b/src/resolve/resolved-conf.c
index 3fc7d9ae3d..1b2f3e336e 100644
--- a/src/resolve/resolved-conf.c
+++ b/src/resolve/resolved-conf.c
@@ -234,6 +234,41 @@ int config_parse_support(
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 r;
diff --git a/src/resolve/resolved-conf.h b/src/resolve/resolved-conf.h
index 28d2549d35..668ea02bba 100644
--- a/src/resolve/resolved-conf.h
+++ b/src/resolve/resolved-conf.h
@@ -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_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_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);
diff --git a/src/resolve/resolved-dns-dnssec.c b/src/resolve/resolved-dns-dnssec.c
index 608a8a2191..bd3d2f5c58 100644
--- a/src/resolve/resolved-dns-dnssec.c
+++ b/src/resolve/resolved-dns-dnssec.c
@@ -25,6 +25,7 @@
#include "dns-domain.h"
#include "resolved-dns-dnssec.h"
#include "resolved-dns-packet.h"
+#include "string-table.h"
/* Open question:
*
@@ -697,3 +698,10 @@ finish:
gcry_md_close(md);
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);
diff --git a/src/resolve/resolved-dns-dnssec.h b/src/resolve/resolved-dns-dnssec.h
index 8f812bc1fb..f4cb58988a 100644
--- a/src/resolve/resolved-dns-dnssec.h
+++ b/src/resolve/resolved-dns-dnssec.h
@@ -21,10 +21,26 @@
along with systemd; If not, see <http://www.gnu.org/licenses/>.
***/
+typedef enum DnssecMode DnssecMode;
+
#include "dns-domain.h"
#include "resolved-dns-answer.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 {
DNSSEC_VERIFIED,
DNSSEC_INVALID,
@@ -33,7 +49,6 @@ enum {
DNSSEC_SIGNATURE_EXPIRED,
};
-
#define DNSSEC_CANONICAL_HOSTNAME_MAX (DNS_HOSTNAME_MAX + 2)
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);
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_;
diff --git a/src/resolve/resolved-dns-packet.c b/src/resolve/resolved-dns-packet.c
index 2a010ef507..ea776f7916 100644
--- a/src/resolve/resolved-dns-packet.c
+++ b/src/resolve/resolved-dns-packet.c
@@ -65,7 +65,7 @@ int dns_packet_new(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
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;
DnsPacketHeader *h;
int r;
@@ -96,7 +96,7 @@ int dns_packet_new_query(DnsPacket **ret, DnsProtocol protocol, size_t mtu) {
1 /* rd (ask for recursion) */,
0 /* ra */,
0 /* ad */,
- 0 /* cd */,
+ dnssec_checking_disabled /* cd */,
0 /* rcode */));
*ret = p;
diff --git a/src/resolve/resolved-dns-packet.h b/src/resolve/resolved-dns-packet.h
index a6b88e6c79..ffa6c44213 100644
--- a/src/resolve/resolved-dns-packet.h
+++ b/src/resolve/resolved-dns-packet.h
@@ -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_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_unref(DnsPacket *p);
diff --git a/src/resolve/resolved-dns-scope.h b/src/resolve/resolved-dns-scope.h
index b816e90cf1..15d9a1fd6f 100644
--- a/src/resolve/resolved-dns-scope.h
+++ b/src/resolve/resolved-dns-scope.h
@@ -26,6 +26,7 @@
typedef struct DnsScope DnsScope;
#include "resolved-dns-cache.h"
+#include "resolved-dns-dnssec.h"
#include "resolved-dns-packet.h"
#include "resolved-dns-server.h"
#include "resolved-dns-zone.h"
@@ -44,6 +45,7 @@ struct DnsScope {
DnsProtocol protocol;
int family;
+ DnssecMode dnssec_mode;
Link *link;
diff --git a/src/resolve/resolved-dns-server.h b/src/resolve/resolved-dns-server.h
index 00366a48c9..b07fc3af3d 100644
--- a/src/resolve/resolved-dns-server.h
+++ b/src/resolve/resolved-dns-server.h
@@ -61,10 +61,11 @@ struct DnsServer {
int family;
union in_addr_union address;
+ bool marked:1;
+
usec_t resend_timeout;
usec_t max_rtt;
- bool marked:1;
DnsServerFeatureLevel verified_features;
DnsServerFeatureLevel possible_features;
size_t received_udp_packet_max;
diff --git a/src/resolve/resolved-dns-transaction.c b/src/resolve/resolved-dns-transaction.c
index 7bef4be2ad..d22acf085b 100644
--- a/src/resolve/resolved-dns-transaction.c
+++ b/src/resolve/resolved-dns-transaction.c
@@ -598,7 +598,7 @@ static int dns_transaction_make_packet(DnsTransaction *t) {
if (t->sent)
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)
return r;
diff --git a/src/resolve/resolved-gperf.gperf b/src/resolve/resolved-gperf.gperf
index 50662656d5..c815eae850 100644
--- a/src/resolve/resolved-gperf.gperf
+++ b/src/resolve/resolved-gperf.gperf
@@ -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.Domains, config_parse_search_domains, 0, 0
Resolve.LLMNR, config_parse_support, 0, offsetof(Manager, llmnr_support)
+Resolve.DNSSEC, config_parse_dnssec, 0, 0
diff --git a/src/resolve/resolved.conf.in b/src/resolve/resolved.conf.in
index 39ecf83217..efc9c6733a 100644
--- a/src/resolve/resolved.conf.in
+++ b/src/resolve/resolved.conf.in
@@ -16,3 +16,4 @@
#FallbackDNS=@DNS_SERVERS@
#Domains=
#LLMNR=yes
+#DNSSEC=no