From 89bf75c4efc496db445bedc93ccff6ecc6013aeb Mon Sep 17 00:00:00 2001 From: otto <> Date: Tue, 28 May 2019 06:49:46 +0000 Subject: [PATCH] A step in solving the bootstrap problem in a dnssec environement. If the time is wrong, we cannot validate dnssec, leading to failed DNS lookups, so we cannot adjust or set the time. Work around this by repeating a failed DNS lookup with a lookup with the DC (check disabled) bit set. ok florian@ --- src/usr.sbin/ntpd/config.c | 25 +++++++++++++++++++++++-- src/usr.sbin/ntpd/constraint.c | 7 +++++-- src/usr.sbin/ntpd/control.c | 10 +++++++--- src/usr.sbin/ntpd/ntp.c | 8 ++++++-- src/usr.sbin/ntpd/ntp_dns.c | 16 +++++++++++++--- src/usr.sbin/ntpd/ntpd.h | 3 ++- 6 files changed, 56 insertions(+), 13 deletions(-) diff --git a/src/usr.sbin/ntpd/config.c b/src/usr.sbin/ntpd/config.c index 25a92cf8..0594b01e 100644 --- a/src/usr.sbin/ntpd/config.c +++ b/src/usr.sbin/ntpd/config.c @@ -1,4 +1,4 @@ -/* $OpenBSD: config.c,v 1.29 2018/09/07 20:31:39 kn Exp $ */ +/* $OpenBSD: config.c,v 1.30 2019/05/28 06:49:46 otto Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -25,11 +25,13 @@ #include #include #include +#include #include #include "ntpd.h" struct ntp_addr *host_ip(const char *); +int host_dns1(const char *, struct ntp_addr **, int); static u_int32_t maxid = 0; static u_int32_t constraint_maxid = 0; @@ -85,7 +87,7 @@ host_dns_free(struct ntp_addr *hn) } int -host_dns(const char *s, struct ntp_addr **hn) +host_dns1(const char *s, struct ntp_addr **hn, int notauth) { struct addrinfo hints, *res0, *res; int error, cnt = 0; @@ -111,6 +113,7 @@ host_dns(const char *s, struct ntp_addr **hn) if ((h = calloc(1, sizeof(*h))) == NULL) fatal(NULL); memcpy(&h->ss, res->ai_addr, res->ai_addrlen); + h->notauth = notauth; h->next = hh; hh = h; @@ -122,6 +125,24 @@ host_dns(const char *s, struct ntp_addr **hn) return (cnt); } +int +host_dns(const char *s, struct ntp_addr **hn) +{ + int error, save_opts; + + log_debug("trying to resolve %s", s); + error = host_dns1(s, hn, 0); + if (error <= 0) { + log_debug("no luck, trying to resolve %s without checking", s); + save_opts = _res.options; + _res.options |= RES_USE_CD; + error = host_dns1(s, hn, 1); + _res.options = save_opts; + } + log_debug("resolve %s done: %d", s, error); + return error; +} + struct ntp_peer * new_peer(void) { diff --git a/src/usr.sbin/ntpd/constraint.c b/src/usr.sbin/ntpd/constraint.c index 841a2882..166e037f 100644 --- a/src/usr.sbin/ntpd/constraint.c +++ b/src/usr.sbin/ntpd/constraint.c @@ -1,4 +1,4 @@ -/* $OpenBSD: constraint.c,v 1.42 2019/01/21 11:08:37 jsing Exp $ */ +/* $OpenBSD: constraint.c,v 1.43 2019/05/28 06:49:46 otto Exp $ */ /* * Copyright (c) 2015 Reyk Floeter @@ -723,7 +723,7 @@ constraint_msg_dns(u_int32_t id, u_int8_t *data, size_t len) return; } - if ((len % sizeof(struct sockaddr_storage)) != 0) + if (len % (sizeof(struct sockaddr_storage) + sizeof(int)) != 0) fatalx("IMSG_CONSTRAINT_DNS len"); p = data; @@ -733,6 +733,9 @@ constraint_msg_dns(u_int32_t id, u_int8_t *data, size_t len) memcpy(&h->ss, p, sizeof(h->ss)); p += sizeof(h->ss); len -= sizeof(h->ss); + memcpy(&h->notauth, p, sizeof(int)); + p += sizeof(int); + len -= sizeof(int); if (ncstr == NULL || cstr->addr_head.pool) { ncstr = new_constraint(); diff --git a/src/usr.sbin/ntpd/control.c b/src/usr.sbin/ntpd/control.c index c47ba0ad..8cd383b4 100644 --- a/src/usr.sbin/ntpd/control.c +++ b/src/usr.sbin/ntpd/control.c @@ -1,4 +1,4 @@ -/* $OpenBSD: control.c,v 1.14 2019/01/14 16:30:21 florian Exp $ */ +/* $OpenBSD: control.c,v 1.15 2019/05/28 06:49:46 otto Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -339,13 +339,17 @@ build_show_peer(struct ctl_show_peer *cp, struct ntp_peer *p) { const char *a = "not resolved"; const char *pool = "", *addr_head_name = ""; + const char *auth = ""; u_int8_t shift, best, validdelaycnt, jittercnt; time_t now; now = getmonotime(); - if (p->addr) + if (p->addr) { a = log_sockaddr((struct sockaddr *)&p->addr->ss); + if (p->addr->notauth) + auth = " (non-dnssec lookup)"; + } if (p->addr_head.pool) pool = "from pool "; @@ -353,7 +357,7 @@ build_show_peer(struct ctl_show_peer *cp, struct ntp_peer *p) addr_head_name = p->addr_head.name; snprintf(cp->peer_desc, sizeof(cp->peer_desc), - "%s %s%s", a, pool, addr_head_name); + "%s %s%s%s", a, pool, addr_head_name, auth); validdelaycnt = best = 0; cp->offset = cp->delay = 0.0; diff --git a/src/usr.sbin/ntpd/ntp.c b/src/usr.sbin/ntpd/ntp.c index 9893d9e2..37522f62 100644 --- a/src/usr.sbin/ntpd/ntp.c +++ b/src/usr.sbin/ntpd/ntp.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntp.c,v 1.149 2019/01/07 20:33:40 tedu Exp $ */ +/* $OpenBSD: ntp.c,v 1.150 2019/05/28 06:49:46 otto Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -512,13 +512,17 @@ ntp_dispatch_imsg_dns(void) } p = (u_char *)imsg.data; - while (dlen >= sizeof(struct sockaddr_storage)) { + while (dlen >= sizeof(struct sockaddr_storage) + + sizeof(int)) { if ((h = calloc(1, sizeof(struct ntp_addr))) == NULL) fatal(NULL); memcpy(&h->ss, p, sizeof(h->ss)); p += sizeof(h->ss); dlen -= sizeof(h->ss); + memcpy(&h->notauth, p, sizeof(int)); + p += sizeof(int); + dlen -= sizeof(int); if (peer->addr_head.pool) { npeer = new_peer(); npeer->weight = peer->weight; diff --git a/src/usr.sbin/ntpd/ntp_dns.c b/src/usr.sbin/ntpd/ntp_dns.c index c1943243..1ac65a45 100644 --- a/src/usr.sbin/ntpd/ntp_dns.c +++ b/src/usr.sbin/ntpd/ntp_dns.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ntp_dns.c,v 1.20 2017/04/17 16:03:15 otto Exp $ */ +/* $OpenBSD: ntp_dns.c,v 1.21 2019/05/28 06:49:46 otto Exp $ */ /* * Copyright (c) 2003-2008 Henning Brauer @@ -20,6 +20,8 @@ #include #include +#include + #include #include #include @@ -28,6 +30,7 @@ #include #include #include +#include #include #include "ntpd.h" @@ -55,6 +58,7 @@ ntp_dns(struct ntpd_conf *nconf, struct passwd *pw) struct pollfd pfd[1]; int nfds, nullfd; + res_init(); if (setpriority(PRIO_PROCESS, 0, 0) == -1) log_warn("could not set priority"); @@ -164,15 +168,21 @@ dns_dispatch_imsg(void) break; buf = imsg_create(ibuf_dns, imsg.hdr.type, imsg.hdr.peerid, 0, - cnt * sizeof(struct sockaddr_storage)); + cnt * (sizeof(struct sockaddr_storage) + sizeof(int))); if (cnt > 0) { if (buf) { - for (h = hn; h != NULL; h = h->next) + for (h = hn; h != NULL; h = h->next) { if (imsg_add(buf, &h->ss, sizeof(h->ss)) == -1) { buf = NULL; break; } + if (imsg_add(buf, &h->notauth, + sizeof(int)) == -1) { + buf = NULL; + break; + } + } } host_dns_free(hn); hn = NULL; diff --git a/src/usr.sbin/ntpd/ntpd.h b/src/usr.sbin/ntpd/ntpd.h index 91d1e0fb..80071734 100644 --- a/src/usr.sbin/ntpd/ntpd.h +++ b/src/usr.sbin/ntpd/ntpd.h @@ -1,4 +1,4 @@ -/* $OpenBSD: ntpd.h,v 1.138 2019/01/14 16:30:21 florian Exp $ */ +/* $OpenBSD: ntpd.h,v 1.139 2019/05/28 06:49:46 otto Exp $ */ /* * Copyright (c) 2003, 2004 Henning Brauer @@ -108,6 +108,7 @@ struct listen_addr { struct ntp_addr { struct ntp_addr *next; struct sockaddr_storage ss; + int notauth; }; struct ntp_addr_wrap {