summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorOtto Moerbeek <otto@cvs.openbsd.org>2019-11-03 09:46:12 +0000
committerOtto Moerbeek <otto@cvs.openbsd.org>2019-11-03 09:46:12 +0000
commit8b07dc0fe8e83736cf424aeffb8b17a5b94cc6f5 (patch)
tree3be1f7580b6067426933854ddb36b9268cefef7c /sbin
parentff3bc23473a6fea8f54fec74889028717f84dafe (diff)
*** empty log message ***
Diffstat (limited to 'sbin')
-rw-r--r--sbin/unwind/parse.y61
-rw-r--r--sbin/unwind/resolver.c155
-rw-r--r--sbin/unwind/resolver.h3
-rw-r--r--sbin/unwind/unwind.h3
4 files changed, 172 insertions, 50 deletions
diff --git a/sbin/unwind/parse.y b/sbin/unwind/parse.y
index af81e630cd7..654b1c202bd 100644
--- a/sbin/unwind/parse.y
+++ b/sbin/unwind/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.12 2019/10/31 12:51:43 florian Exp $ */
+/* $OpenBSD: parse.y,v 1.13 2019/11/03 09:46:11 otto Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -84,7 +84,6 @@ int check_pref_uniq(enum uw_resolver_type);
static struct uw_conf *conf;
static int errors;
-static struct uw_forwarder *uw_forwarder;
void clear_config(struct uw_conf *xconf);
struct sockaddr_storage *host_ip(const char *);
@@ -287,7 +286,9 @@ forwarderopts_l : forwarderopts_l forwarderoptsl optnl
forwarderoptsl : STRING port authname dot {
int ret, port;
+ struct uw_forwarder *uw_fwd;
struct sockaddr_storage *ss;
+
if ((ss = host_ip($1)) == NULL) {
yyerror("%s is not an ip-address", $1);
free($1);
@@ -305,37 +306,53 @@ forwarderoptsl : STRING port authname dot {
else
port = $2;
- if ((uw_forwarder = calloc(1,
- sizeof(*uw_forwarder))) == NULL)
+ if ($3 != NULL && $4 == 0) {
+ yyerror("authentication name can only "
+ "be used with DoT");
+ free($1);
+ YYERROR;
+ }
+
+
+ if ((uw_fwd = calloc(1,
+ sizeof(*uw_fwd))) == NULL)
err(1, NULL);
- if ($3 == NULL)
- ret = snprintf(uw_forwarder->name,
- sizeof(uw_forwarder->name),
- "%s@%d", $1, port);
- else
- ret = snprintf(uw_forwarder->name,
- sizeof(uw_forwarder->name),
- "%s@%d#%s", $1, port, $3);
+ if ($4 == DOT) {
+ if ($3 == NULL)
+ ret = snprintf(uw_fwd->name,
+ sizeof(uw_fwd->name),
+ "%s@%d", $1, port);
+ else
+ ret = snprintf(uw_fwd->name,
+ sizeof(uw_fwd->name),
+ "%s@%d#%s", $1, port, $3);
+ } else {
+ uw_fwd->port = $2;
+ /* complete string will be done later */
+ ret = snprintf(uw_fwd->name,
+ sizeof(uw_fwd->name), "%s", $1);
+ }
if (ret < 0 || (size_t)ret >=
- sizeof(uw_forwarder->name)) {
- free(uw_forwarder);
+ sizeof(uw_fwd->name)) {
+ free(uw_fwd);
yyerror("forwarder %s too long", $1);
free($1);
YYERROR;
}
- free($1);
if ($4 == DOT)
SIMPLEQ_INSERT_TAIL(
&conf->uw_dot_forwarder_list,
- uw_forwarder, entry);
- else
+ uw_fwd, entry);
+ else {
SIMPLEQ_INSERT_TAIL(
&conf->uw_forwarder_list,
- uw_forwarder, entry);
+ uw_fwd, entry);
+ }
+ free($1);
}
- ;
+ ;
port : PORT NUMBER { $$ = $2; }
| /* empty */ { $$ = 0; }
@@ -874,12 +891,14 @@ symget(const char *nam)
void
clear_config(struct uw_conf *xconf)
{
- while((uw_forwarder = SIMPLEQ_FIRST(&xconf->uw_forwarder_list)) !=
+ struct uw_forwarder *uw_forwarder;
+
+ while ((uw_forwarder = SIMPLEQ_FIRST(&xconf->uw_forwarder_list)) !=
NULL) {
SIMPLEQ_REMOVE_HEAD(&xconf->uw_forwarder_list, entry);
free(uw_forwarder);
}
- while((uw_forwarder = SIMPLEQ_FIRST(&xconf->uw_dot_forwarder_list)) !=
+ while ((uw_forwarder = SIMPLEQ_FIRST(&xconf->uw_dot_forwarder_list)) !=
NULL) {
SIMPLEQ_REMOVE_HEAD(&xconf->uw_dot_forwarder_list, entry);
free(uw_forwarder);
diff --git a/sbin/unwind/resolver.c b/sbin/unwind/resolver.c
index 2e77c2b792e..cec582de1b7 100644
--- a/sbin/unwind/resolver.c
+++ b/sbin/unwind/resolver.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolver.c,v 1.50 2019/11/02 20:05:39 florian Exp $ */
+/* $OpenBSD: resolver.c,v 1.51 2019/11/03 09:46:11 otto Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -85,6 +85,7 @@ struct uw_resolver {
int stop;
enum uw_resolver_state state;
enum uw_resolver_type type;
+ int oppdot;
char *why_bogus;
int64_t histogram[nitems(histogram_limits)];
};
@@ -107,14 +108,16 @@ void asr_resolve_done(struct asr_result *, void *);
void check_asr_resolver_done(struct asr_result *, void *);
void parse_dhcp_forwarders(char *);
void new_recursor(void);
-void new_forwarders(void);
+void new_forwarders(int);
void new_asr_forwarders(void);
-void new_static_forwarders(void);
+void new_static_forwarders(int);
void new_static_dot_forwarders(void);
-struct uw_resolver *create_resolver(enum uw_resolver_type);
+struct uw_resolver *create_resolver(enum uw_resolver_type, int);
void free_resolver(struct uw_resolver *);
void set_forwarders(struct uw_resolver *,
struct uw_forwarder_head *);
+void set_forwarders_oppdot(struct uw_resolver *,
+ struct uw_forwarder_head *, int);
void resolver_check_timo(int, short, void *);
void resolver_free_timo(int, short, void *);
void check_resolver(struct uw_resolver *);
@@ -400,9 +403,9 @@ resolver_dispatch_frontend(int fd, short event, void *bula)
log_debug("%s: IMSG_NEW_TAS_DONE", __func__);
if (merge_tas(&new_trust_anchors, &trust_anchors)) {
new_recursor();
- new_forwarders();
+ new_forwarders(0);
new_asr_forwarders();
- new_static_forwarders();
+ new_static_forwarders(0);
new_static_dot_forwarders();
}
break;
@@ -606,7 +609,7 @@ resolver_dispatch_main(int fd, short event, void *bula)
nconf = NULL;
if (forwarders_changed) {
log_debug("static forwarders changed");
- new_static_forwarders();
+ new_static_forwarders(0);
}
if (dot_forwarders_changed) {
log_debug("static DoT forwarders changed");
@@ -767,7 +770,7 @@ parse_dhcp_forwarders(char *forwarders)
if (forwarders != NULL) {
while((ns = strsep(&forwarders, ",")) != NULL) {
log_debug("%s: %s", __func__, ns);
- if ((uw_forwarder = malloc(sizeof(struct
+ if ((uw_forwarder = calloc(1, sizeof(struct
uw_forwarder))) == NULL)
fatal(NULL);
if (strlcpy(uw_forwarder->name, ns,
@@ -782,7 +785,7 @@ parse_dhcp_forwarders(char *forwarders)
if (check_forwarders_changed(&new_forwarder_list,
&dhcp_forwarder_list)) {
replace_forwarders(&new_forwarder_list, &dhcp_forwarder_list);
- new_forwarders();
+ new_forwarders(0);
new_asr_forwarders();
if (resolver_conf->captive_portal_auto)
check_captive_portal(1);
@@ -805,12 +808,12 @@ new_recursor(void)
if (TAILQ_EMPTY(&trust_anchors))
return;
- resolvers[UW_RES_RECURSOR] = create_resolver(UW_RES_RECURSOR);
+ resolvers[UW_RES_RECURSOR] = create_resolver(UW_RES_RECURSOR, 0);
check_resolver(resolvers[UW_RES_RECURSOR]);
}
void
-new_forwarders(void)
+new_forwarders(int oppdot)
{
free_resolver(resolvers[UW_RES_DHCP]);
resolvers[UW_RES_DHCP] = NULL;
@@ -822,7 +825,7 @@ new_forwarders(void)
return;
log_debug("%s: create_resolver", __func__);
- resolvers[UW_RES_DHCP] = create_resolver(UW_RES_DHCP);
+ resolvers[UW_RES_DHCP] = create_resolver(UW_RES_DHCP, oppdot);
check_resolver(resolvers[UW_RES_DHCP]);
}
@@ -837,13 +840,13 @@ new_asr_forwarders(void)
return;
log_debug("%s: create_resolver", __func__);
- resolvers[UW_RES_ASR] = create_resolver(UW_RES_ASR);
+ resolvers[UW_RES_ASR] = create_resolver(UW_RES_ASR, 0);
check_resolver(resolvers[UW_RES_ASR]);
}
void
-new_static_forwarders(void)
+new_static_forwarders(int oppdot)
{
free_resolver(resolvers[UW_RES_FORWARDER]);
resolvers[UW_RES_FORWARDER] = NULL;
@@ -855,7 +858,7 @@ new_static_forwarders(void)
return;
log_debug("%s: create_resolver", __func__);
- resolvers[UW_RES_FORWARDER] = create_resolver(UW_RES_FORWARDER);
+ resolvers[UW_RES_FORWARDER] = create_resolver(UW_RES_FORWARDER, oppdot);
check_resolver(resolvers[UW_RES_FORWARDER]);
}
@@ -873,13 +876,13 @@ new_static_dot_forwarders(void)
return;
log_debug("%s: create_resolver", __func__);
- resolvers[UW_RES_DOT] = create_resolver(UW_RES_DOT);
+ resolvers[UW_RES_DOT] = create_resolver(UW_RES_DOT, 0);
check_resolver(resolvers[UW_RES_DOT]);
}
struct uw_resolver *
-create_resolver(enum uw_resolver_type type)
+create_resolver(enum uw_resolver_type type, int oppdot)
{
struct uw_resolver *res;
struct trust_anchor *ta;
@@ -984,10 +987,26 @@ create_resolver(enum uw_resolver_type type)
case UW_RES_RECURSOR:
break;
case UW_RES_DHCP:
- set_forwarders(res, &dhcp_forwarder_list);
+ res->oppdot = oppdot;
+ if (oppdot) {
+ set_forwarders_oppdot(res, &dhcp_forwarder_list, 853);
+ ub_ctx_set_option(res->ctx, "tls-cert-bundle:",
+ tls_default_ca_cert_file());
+ ub_ctx_set_tls(res->ctx, 1);
+ } else
+ set_forwarders_oppdot(res, &dhcp_forwarder_list, 53);
break;
case UW_RES_FORWARDER:
- set_forwarders(res, &resolver_conf->uw_forwarder_list);
+ res->oppdot = oppdot;
+ if (oppdot) {
+ set_forwarders_oppdot(res,
+ &resolver_conf->uw_forwarder_list, 853);
+ ub_ctx_set_option(res->ctx, "tls-cert-bundle:",
+ tls_default_ca_cert_file());
+ ub_ctx_set_tls(res->ctx, 1);
+ } else
+ set_forwarders_oppdot(res,
+ &resolver_conf->uw_forwarder_list, 53);
break;
case UW_RES_DOT:
set_forwarders(res, &resolver_conf->uw_dot_forwarder_list);
@@ -1033,6 +1052,22 @@ set_forwarders(struct uw_resolver *res, struct uw_forwarder_head
}
void
+set_forwarders_oppdot(struct uw_resolver *res, struct uw_forwarder_head
+ *uw_forwarder_list, int def_port)
+{
+ struct uw_forwarder *uw_forwarder;
+
+ SIMPLEQ_FOREACH(uw_forwarder, uw_forwarder_list, entry) {
+ char name[1024];
+ int port = uw_forwarder->port;
+ if (port == 0)
+ port = def_port;
+ snprintf(name, sizeof(name), "%s@%d", uw_forwarder->name, port);
+ ub_ctx_set_fwd(res->ctx, name);
+ }
+}
+
+void
resolver_check_timo(int fd, short events, void *arg)
{
check_resolver((struct uw_resolver *)arg);
@@ -1052,7 +1087,7 @@ check_resolver(struct uw_resolver *res)
int err;
log_debug("%s: create_resolver", __func__);
- if ((check_res = create_resolver(res->type)) == NULL)
+ if ((check_res = create_resolver(res->type, 0)) == NULL)
fatal("%s", __func__);
if ((data = malloc(sizeof(*data))) == NULL)
fatal("%s", __func__);
@@ -1075,6 +1110,36 @@ check_resolver(struct uw_resolver *res)
uw_resolver_type_str[data->res->type],
uw_resolver_state_str[data->res->state]);
}
+
+ if (!(res->type == UW_RES_DHCP || res->type == UW_RES_FORWARDER))
+ return;
+
+ log_debug("%s: create_resolver for oppdot", __func__);
+ if ((check_res = create_resolver(res->type, 1)) == NULL)
+ fatal("%s", __func__);
+ if ((data = malloc(sizeof(*data))) == NULL)
+ fatal("%s", __func__);
+
+ resolver_ref(check_res);
+ resolver_ref(res);
+ data->check_res = check_res;
+ data->res = res;
+
+ if ((err = resolve(check_res, ".", LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN,
+ data, 1, NULL)) != 0) {
+ log_debug("check oppdot failed");
+ /* do not overwrite normal DNS state, it might work */
+ resolver_unref(check_res);
+ resolver_unref(res);
+
+ res->check_tv.tv_sec = RESOLVER_CHECK_SEC;
+ evtimer_add(&res->check_ev, &res->check_tv);
+
+ log_debug("%s: evtimer_add: %lld - %s: %s", __func__,
+ data->res->check_tv.tv_sec,
+ uw_resolver_type_str[data->res->type],
+ uw_resolver_state_str[data->res->state]);
+ }
}
void
@@ -1088,7 +1153,8 @@ check_resolver_done(void *arg, int rcode, void *answer_packet, int answer_len,
data = (struct check_resolver_data *)arg;
- log_debug("%s: rcode: %d", __func__, rcode);
+ log_debug("%s: %s rcode: %d", __func__,
+ uw_resolver_type_str[data->res->type], rcode);
prev_state = data->res->state;
@@ -1099,10 +1165,39 @@ check_resolver_done(void *arg, int rcode, void *answer_packet, int answer_len,
}
if (rcode == LDNS_RCODE_SERVFAIL) {
- data->res->state = DEAD;
+ if (data->check_res->oppdot == data->res->oppdot) {
+ data->res->state = DEAD;
+ if (data->res->oppdot) {
+ /* downgrade from opportunistic DoT */
+ switch (data->res->type) {
+ case UW_RES_DHCP:
+ new_forwarders(0);
+ break;
+ case UW_RES_FORWARDER:
+ new_static_forwarders(0);
+ break;
+ default:
+ break;
+ }
+ }
+ }
goto out;
}
+ if (data->check_res->oppdot && !data->res->oppdot) {
+ /* upgrade to opportunistic DoT */
+ switch (data->res->type) {
+ case UW_RES_DHCP:
+ new_forwarders(1);
+ break;
+ case UW_RES_FORWARDER:
+ new_static_forwarders(1);
+ break;
+ default:
+ break;
+ }
+ }
+
if ((str = sldns_wire2str_pkt(answer_packet, answer_len)) != NULL) {
log_debug("%s", str);
free(str);
@@ -1260,7 +1355,7 @@ best_resolver(void)
struct uw_resolver *res = NULL;
int i;
- log_debug("%s: %s: %s, %s: %s, %s: %s, %s: %s, %s: %s, "
+ log_debug("%s: %s: %s, %s: %s%s, %s: %s%s, %s: %s, %s: %s, "
"captive_portal: %s",
__func__,
uw_resolver_type_str[UW_RES_RECURSOR], resolvers[UW_RES_RECURSOR]
@@ -1268,9 +1363,13 @@ best_resolver(void)
: "NA",
uw_resolver_type_str[UW_RES_DHCP], resolvers[UW_RES_DHCP] != NULL ?
uw_resolver_state_str[resolvers[UW_RES_DHCP]->state] : "NA",
+ resolvers[UW_RES_DHCP] != NULL &&
+ resolvers[UW_RES_DHCP]->oppdot ? " (OppDot)" : "",
uw_resolver_type_str[UW_RES_FORWARDER],
resolvers[UW_RES_FORWARDER] != NULL ?
uw_resolver_state_str[resolvers[UW_RES_FORWARDER]->state] : "NA",
+ resolvers[UW_RES_FORWARDER] != NULL &&
+ resolvers[UW_RES_FORWARDER]->oppdot ? " (OppDot)" : "",
uw_resolver_type_str[UW_RES_DOT],
resolvers[UW_RES_DOT] != NULL ?
uw_resolver_state_str[resolvers[UW_RES_DOT]->state] : "NA",
@@ -1295,8 +1394,9 @@ best_resolver(void)
resolvers[resolver_conf->res_pref[i]]) < 0)
res = resolvers[resolver_conf->res_pref[i]];
out:
- log_debug("%s: %s state: %s", __func__, uw_resolver_type_str[res->type],
- uw_resolver_state_str[res->state]);
+ log_debug("%s: %s state: %s%s", __func__,
+ uw_resolver_type_str[res->type],
+ uw_resolver_state_str[res->state], res->oppdot ? " (OppDoT)" : "");
return (res);
}
@@ -1325,9 +1425,9 @@ restart_resolvers(void)
log_debug("%s: %d", __func__, verbose);
new_recursor();
- new_static_forwarders();
+ new_static_forwarders(0);
new_static_dot_forwarders();
- new_forwarders();
+ new_forwarders(0);
new_asr_forwarders();
}
@@ -1376,6 +1476,7 @@ send_resolver_info(struct uw_resolver *res, int selected, pid_t pid)
cri.state = res->state;
cri.type = res->type;
cri.selected = selected;
+ cri.oppdot = res->oppdot;
resolver_imsg_compose_frontend(IMSG_CTL_RESOLVER_INFO, pid, &cri,
sizeof(cri));
}
diff --git a/sbin/unwind/resolver.h b/sbin/unwind/resolver.h
index 53b384bfb41..cb0e166381c 100644
--- a/sbin/unwind/resolver.h
+++ b/sbin/unwind/resolver.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolver.h,v 1.6 2019/04/02 07:47:23 florian Exp $ */
+/* $OpenBSD: resolver.h,v 1.7 2019/11/03 09:46:11 otto Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -51,6 +51,7 @@ struct ctl_resolver_info {
enum uw_resolver_state state;
enum uw_resolver_type type;
int selected;
+ int oppdot;
};
void resolver(int, int);
diff --git a/sbin/unwind/unwind.h b/sbin/unwind/unwind.h
index d3fdd6442a5..7c146634f3e 100644
--- a/sbin/unwind/unwind.h
+++ b/sbin/unwind/unwind.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: unwind.h,v 1.20 2019/10/31 12:54:40 florian Exp $ */
+/* $OpenBSD: unwind.h,v 1.21 2019/11/03 09:46:11 otto Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -126,6 +126,7 @@ enum imsg_type {
struct uw_forwarder {
SIMPLEQ_ENTRY(uw_forwarder) entry;
char name[1024]; /* XXX */
+ uint16_t port;
};
SIMPLEQ_HEAD(uw_forwarder_head, uw_forwarder);