summaryrefslogtreecommitdiff
path: root/sbin
diff options
context:
space:
mode:
authorFlorian Obser <florian@cvs.openbsd.org>2019-11-14 08:34:18 +0000
committerFlorian Obser <florian@cvs.openbsd.org>2019-11-14 08:34:18 +0000
commitae13959e0b5998b509c62aeaffdd8f4cda26519b (patch)
treec10268378de62937809b954208720024fd6dd5d3 /sbin
parent41dff51c79fd37dda973dd31745e0ad6cbb65357 (diff)
With the stub resolver we have since some time we can resolve the
captive portal host internaly via the resolver process. deraadt and me observed weird captive portal checking hangs inside of unwind if only 127.0.0.1 was listed as a nameserver in resolv.conf with the old code.
Diffstat (limited to 'sbin')
-rw-r--r--sbin/unwind/resolver.c75
-rw-r--r--sbin/unwind/unwind.c90
-rw-r--r--sbin/unwind/unwind.h4
3 files changed, 104 insertions, 65 deletions
diff --git a/sbin/unwind/resolver.c b/sbin/unwind/resolver.c
index c525e72e55a..e17e3487186 100644
--- a/sbin/unwind/resolver.c
+++ b/sbin/unwind/resolver.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolver.c,v 1.64 2019/11/14 08:32:30 florian Exp $ */
+/* $OpenBSD: resolver.c,v 1.65 2019/11/14 08:34:17 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -151,6 +151,8 @@ void check_captive_portal(int);
void check_captive_portal_timo(int, short, void *);
int check_captive_portal_changed(struct uw_conf *,
struct uw_conf *);
+void captive_portal_resolve_done(struct uw_resolver *,
+ void *, int, void *, int, int, char *);
void trust_anchor_resolve(void);
void trust_anchor_timo(int, short, void *);
void trust_anchor_resolve_done(struct uw_resolver *, void *,
@@ -1704,6 +1706,8 @@ check_captive_portal_timo(int fd, short events, void *arg)
void
check_captive_portal(int timer_reset)
{
+ struct uw_resolver *res;
+
log_debug("%s", __func__);
if (resolver_conf->captive_portal_host == NULL) {
@@ -1713,11 +1717,6 @@ check_captive_portal(int timer_reset)
return;
}
- if (resolvers[UW_RES_DHCP] == NULL) {
- log_debug("%s no DHCP nameservers known", __func__);
- return;
- }
-
if (timer_reset)
captive_portal_check_tv.tv_sec = PORTAL_CHECK_SEC;
@@ -1725,7 +1724,69 @@ check_captive_portal(int timer_reset)
captive_portal_state = PORTAL_UNKNOWN;
- resolver_imsg_compose_main(IMSG_RESOLVE_CAPTIVE_PORTAL, 0, NULL, 0);
+ if ((res = best_resolver()) == NULL)
+ return;
+
+ resolve(res, resolver_conf->captive_portal_host,
+ LDNS_RR_TYPE_A, LDNS_RR_CLASS_IN, NULL,
+ captive_portal_resolve_done);
+}
+
+void
+captive_portal_resolve_done(struct uw_resolver *res, void *arg, int rcode,
+ void *answer_packet, int answer_len, int sec, char *why_bogus)
+{
+ struct ub_result *result;
+ sldns_buffer *buf = NULL;
+ struct regional *region = NULL;
+ struct in_addr *in;
+ int i;
+ char *str, rdata_buf[sizeof("xxx.xxx.xxx.xxx")];
+
+ if ((result = calloc(1, sizeof(*result))) == NULL)
+ goto out;
+
+ log_debug("%s: rcode: %d", __func__, rcode);
+ if ((str = sldns_wire2str_pkt(answer_packet, answer_len)) != NULL) {
+ log_debug("%s", str);
+ free(str);
+ }
+
+ if ((buf = sldns_buffer_new(answer_len)) == NULL)
+ goto out;
+ if ((region = regional_create()) == NULL)
+ goto out;
+ result->rcode = LDNS_RCODE_SERVFAIL;
+
+ sldns_buffer_clear(buf);
+ sldns_buffer_write(buf, answer_packet, answer_len);
+ sldns_buffer_flip(buf);
+ libworker_enter_result(result, buf, region, sec);
+ result->answer_packet = NULL;
+ result->answer_len = 0;
+
+ if (result->rcode != LDNS_RCODE_NOERROR) {
+ log_debug("%s: result->rcode: %d", __func__,
+ result->rcode);
+ goto out;
+ }
+
+ i = 0;
+ while(result->data[i] != NULL) {
+ if (result->len[i] == 4) {
+ in = (struct in_addr*) result->data[i];
+ log_debug("%s: %s", __func__, inet_ntop(AF_INET,
+ in, rdata_buf, sizeof(rdata_buf)));
+ resolver_imsg_compose_main(
+ IMSG_CONNECT_CAPTIVE_PORTAL_HOST, 0, in,
+ sizeof(*in));
+ }
+ i++;
+ }
+ out:
+ sldns_buffer_free(buf);
+ regional_destroy(region);
+ ub_resolve_free(result);
}
int
diff --git a/sbin/unwind/unwind.c b/sbin/unwind/unwind.c
index a04a17858d4..317df549975 100644
--- a/sbin/unwind/unwind.c
+++ b/sbin/unwind/unwind.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: unwind.c,v 1.35 2019/11/11 05:51:06 florian Exp $ */
+/* $OpenBSD: unwind.c,v 1.36 2019/11/14 08:34:17 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -74,8 +74,7 @@ int main_sendall(enum imsg_type, void *, uint16_t);
void open_dhcp_lease(int);
void open_ports(void);
void solicit_dns_proposals(void);
-void resolve_captive_portal(void);
-void resolve_captive_portal_done(struct asr_result *, void *);
+void connect_captive_portal_host(struct in_addr *);
void send_blocklist_fd(void);
struct uw_conf *main_conf;
@@ -319,7 +318,7 @@ main(int argc, char *argv[])
if (main_conf->blocklist_file != NULL)
send_blocklist_fd();
- if (pledge("stdio inet dns rpath sendfd", NULL) == -1)
+ if (pledge("stdio inet rpath sendfd", NULL) == -1)
fatal("pledge");
main_imsg_compose_frontend(IMSG_STARTUP, 0, NULL, 0);
@@ -494,6 +493,7 @@ main_dispatch_resolver(int fd, short event, void *bula)
struct imsgev *iev = bula;
struct imsgbuf *ibuf;
struct imsg imsg;
+ struct in_addr *in;
ssize_t n;
int shut = 0;
@@ -519,8 +519,13 @@ main_dispatch_resolver(int fd, short event, void *bula)
break;
switch (imsg.hdr.type) {
- case IMSG_RESOLVE_CAPTIVE_PORTAL:
- resolve_captive_portal();
+ case IMSG_CONNECT_CAPTIVE_PORTAL_HOST:
+ if (IMSG_DATA_SIZE(imsg) != sizeof(*in))
+ fatalx("%s: IMSG_CONNECT_CAPTIVE_PORTAL_HOST "
+ "wrong length: %lu", __func__,
+ IMSG_DATA_SIZE(imsg));
+ in = (struct in_addr *)imsg.data;
+ connect_captive_portal_host(in);
break;
default:
log_debug("%s: error handling imsg %d", __func__,
@@ -988,62 +993,35 @@ solicit_dns_proposals(void)
}
void
-resolve_captive_portal(void)
+connect_captive_portal_host(struct in_addr *in)
{
- struct addrinfo hints;
- void *as;
-
- if (main_conf->captive_portal_host == NULL)
- return;
-
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = PF_INET;
- hints.ai_socktype = SOCK_STREAM;
-
- log_debug("%s: %s", __func__, main_conf->captive_portal_host);
-
- if ((as = getaddrinfo_async(main_conf->captive_portal_host, "www",
- &hints, NULL)) != NULL)
- event_asr_run(as, resolve_captive_portal_done, NULL);
- else
- log_warn("%s: getaddrinfo_async", __func__);
-
-}
-
-void
-resolve_captive_portal_done(struct asr_result *ar, void *arg)
-{
- struct addrinfo *res;
- int httpsock;
-
- if (ar->ar_gai_errno) {
- log_warnx("%s: %s", __func__, gai_strerror(ar->ar_gai_errno));
+ struct sockaddr *sa;
+ struct sockaddr_in sin;
+ int httpsock;
+
+ sa = (struct sockaddr *)&sin;
+ memset(&sin, 0, sizeof(sin));
+ sin.sin_len = sizeof(sin);
+ sin.sin_family = AF_INET;
+ sin.sin_addr = *in;
+ sin.sin_port = htons(80);
+ log_debug("%s: ip_port: %s", __func__, ip_port(sa));
+
+ if ((httpsock = socket(AF_INET, SOCK_STREAM |
+ SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) == -1) {
+ log_warn("%s: socket", __func__);
return;
}
-
- for (res = ar->ar_addrinfo; res; res = res->ai_next) {
- if (res->ai_family != PF_INET)
- continue;
- log_debug("%s: ip_port: %s", __func__,
- ip_port(res->ai_addr));
-
- if ((httpsock = socket(AF_INET, SOCK_STREAM |
- SOCK_CLOEXEC | SOCK_NONBLOCK, 0)) == -1) {
- log_warn("%s: socket", __func__);
- break;
- }
- if (connect(httpsock, res->ai_addr, res->ai_addrlen) == -1) {
- if (errno != EINPROGRESS) {
- log_warn("%s: connect", __func__);
- close(httpsock);
- break;
- }
+ if (connect(httpsock, sa, sizeof(sin)) == -1) {
+ if (errno != EINPROGRESS) {
+ log_warn("%s: connect", __func__);
+ close(httpsock);
+ return;
}
- main_imsg_compose_captiveportal_fd(IMSG_HTTPSOCK, 0,
- httpsock);
}
- freeaddrinfo(ar->ar_addrinfo);
+ main_imsg_compose_captiveportal_fd(IMSG_HTTPSOCK, 0,
+ httpsock);
}
void
diff --git a/sbin/unwind/unwind.h b/sbin/unwind/unwind.h
index 7079ec3ed72..2b64c071c30 100644
--- a/sbin/unwind/unwind.h
+++ b/sbin/unwind/unwind.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: unwind.h,v 1.27 2019/11/14 08:30:10 florian Exp $ */
+/* $OpenBSD: unwind.h,v 1.28 2019/11/14 08:34:17 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -119,7 +119,7 @@ enum imsg_type {
IMSG_NEW_TAS_ABORT,
IMSG_NEW_TAS_DONE,
IMSG_RECHECK_RESOLVERS,
- IMSG_RESOLVE_CAPTIVE_PORTAL,
+ IMSG_CONNECT_CAPTIVE_PORTAL_HOST,
IMSG_BLFD,
IMSG_ADD_DNS,
IMSG_REMOVE_DNS,