summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorflorian <florian@openbsd.org>2019-04-01 03:31:55 +0000
committerflorian <florian@openbsd.org>2019-04-01 03:31:55 +0000
commit3461bfbe26fa73f3bbe2417f40539d34ecb631c5 (patch)
treec91e57ca843638531297ab271606beba65363651
parentdeprecate TASKQ_CANTSLEEP since nothing uses it anymore (diff)
downloadwireguard-openbsd-3461bfbe26fa73f3bbe2417f40539d34ecb631c5.tar.xz
wireguard-openbsd-3461bfbe26fa73f3bbe2417f40539d34ecb631c5.zip
Implement "Authentication Domain Names" configuration as per RFC 8310
section 7.1 for DoT servers. We are setting the CA cert bundle path (/etc/ssl/cert.pem) directly in libunbound so we need to losen pledge(2) a bit and allow rpath. At the same time we unveil only /etc/ssl/cert.pem. We can drop the chroot(2) since pledge(2) and unveil(2) give us more fine grained isolation. prodding by tb@. p.s. for portable it might be necessary to pass in a file descriptor from the parent, slurp in the file and then use X509_STORE_load_mem() (pointed out by sthen) in the guts of libunbound.
-rw-r--r--sbin/unwind/parse.y70
-rw-r--r--sbin/unwind/printconf.c27
-rw-r--r--sbin/unwind/resolver.c19
-rw-r--r--sbin/unwind/unwind.conf.58
4 files changed, 103 insertions, 21 deletions
diff --git a/sbin/unwind/parse.y b/sbin/unwind/parse.y
index 5691b9d7a36..8d813589cd2 100644
--- a/sbin/unwind/parse.y
+++ b/sbin/unwind/parse.y
@@ -1,4 +1,4 @@
-/* $OpenBSD: parse.y,v 1.1 2019/03/01 08:02:25 florian Exp $ */
+/* $OpenBSD: parse.y,v 1.2 2019/04/01 03:31:55 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -100,7 +100,7 @@ typedef struct {
%token STRICT YES NO INCLUDE ERROR
%token FORWARDER DOT PORT CAPTIVE PORTAL URL EXPECTED RESPONSE
-%token STATUS AUTO
+%token STATUS AUTO AUTHENTICATION NAME
%token <v.string> STRING
%token <v.number> NUMBER
@@ -359,6 +359,70 @@ forwarderoptsl : STRING {
&conf->uw_dot_forwarder_list, uw_forwarder,
entry);
}
+ | STRING AUTHENTICATION NAME STRING DOT {
+ int ret;
+ struct sockaddr_storage *ss;
+ if ((ss = host_ip($1)) == NULL) {
+ yyerror("%s is not an ip-address", $1);
+ free($1);
+ YYERROR;
+ }
+ free(ss);
+
+ if ((uw_forwarder = calloc(1,
+ sizeof(*uw_forwarder))) == NULL)
+ err(1, NULL);
+
+ ret = snprintf(uw_forwarder->name,
+ sizeof(uw_forwarder->name), "%s#%s", $1,
+ $4);
+ if (ret == -1 || (size_t)ret >=
+ sizeof(uw_forwarder->name)) {
+ free(uw_forwarder);
+ yyerror("forwarder %s too long", $1);
+ free($1);
+ YYERROR;
+ }
+
+ SIMPLEQ_INSERT_TAIL(
+ &conf->uw_dot_forwarder_list, uw_forwarder,
+ entry);
+ }
+ | STRING PORT NUMBER AUTHENTICATION NAME STRING DOT {
+ int ret;
+ struct sockaddr_storage *ss;
+ if ((ss = host_ip($1)) == NULL) {
+ yyerror("%s is not an ip-address", $1);
+ free($1);
+ YYERROR;
+ }
+ free(ss);
+
+ if ($3 <= 0 || $3 > (int)USHRT_MAX) {
+ yyerror("invalid port: %lld", $3);
+ free($1);
+ YYERROR;
+ }
+
+ if ((uw_forwarder = calloc(1,
+ sizeof(*uw_forwarder))) == NULL)
+ err(1, NULL);
+
+ ret = snprintf(uw_forwarder->name,
+ sizeof(uw_forwarder->name), "%s@%d#%s", $1,
+ (int)$3, $6);
+ if (ret == -1 || (size_t)ret >=
+ sizeof(uw_forwarder->name)) {
+ free(uw_forwarder);
+ yyerror("forwarder %s too long", $1);
+ free($1);
+ YYERROR;
+ }
+
+ SIMPLEQ_INSERT_TAIL(
+ &conf->uw_dot_forwarder_list, uw_forwarder,
+ entry);
+ }
;
%%
@@ -395,12 +459,14 @@ lookup(char *s)
/* This has to be sorted always. */
static const struct keywords keywords[] = {
{"DoT", DOT},
+ {"authentication", AUTHENTICATION},
{"auto", AUTO},
{"captive", CAPTIVE},
{"dot", DOT},
{"expected", EXPECTED},
{"forwarder", FORWARDER},
{"include", INCLUDE},
+ {"name", NAME},
{"no", NO},
{"port", PORT},
{"portal", PORTAL},
diff --git a/sbin/unwind/printconf.c b/sbin/unwind/printconf.c
index 1e2747e29a0..78dcdab2824 100644
--- a/sbin/unwind/printconf.c
+++ b/sbin/unwind/printconf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: printconf.c,v 1.6 2019/02/17 14:49:15 florian Exp $ */
+/* $OpenBSD: printconf.c,v 1.7 2019/04/01 03:31:55 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -38,17 +38,28 @@ yesno(int flag)
void
print_forwarder(char *name)
{
- char *pos;
+ char *port_pos, *name_pos;
- pos = strchr(name, '@');
+ port_pos = strchr(name, '@');
+ name_pos = strchr(name, '#');
- if (pos != NULL) {
- *pos = '\0';
- printf("%s port %s", name, pos + 1);
- *pos = '@';
+ if (port_pos != NULL) {
+ *port_pos = '\0';
+ if (name_pos != NULL) {
+ *name_pos = '\0';
+ printf("%s port %s authentication name %s", name,
+ port_pos + 1, name_pos + 1);
+ *name_pos = '#';
+ } else {
+ printf("%s port %s", name, port_pos + 1);
+ }
+ *port_pos = '@';
+ } else if (name_pos != NULL) {
+ *name_pos = '\0';
+ printf("%s authentication name %s", name, name_pos + 1);
+ *name_pos = '#';
} else
printf("%s", name);
-
}
void
diff --git a/sbin/unwind/resolver.c b/sbin/unwind/resolver.c
index 74fdfefcc4c..9932c5fd6a0 100644
--- a/sbin/unwind/resolver.c
+++ b/sbin/unwind/resolver.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: resolver.c,v 1.30 2019/03/31 00:57:41 tedu Exp $ */
+/* $OpenBSD: resolver.c,v 1.31 2019/04/01 03:31:55 florian Exp $ */
/*
* Copyright (c) 2018 Florian Obser <florian@openbsd.org>
@@ -35,6 +35,7 @@
#include <stdlib.h>
#include <string.h>
#include <time.h>
+#include <tls.h>
#include <unistd.h>
#include "libunbound/config.h"
@@ -183,11 +184,6 @@ resolver(int debug, int verbose)
if ((pw = getpwnam(UNWIND_USER)) == NULL)
fatal("getpwnam");
- if (chroot(pw->pw_dir) == -1)
- fatal("chroot");
- if (chdir("/") == -1)
- fatal("chdir(\"/\")");
-
uw_process = PROC_RESOLVER;
setproctitle("%s", log_procnames[uw_process]);
log_procinit(log_procnames[uw_process]);
@@ -197,7 +193,10 @@ resolver(int debug, int verbose)
setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid))
fatal("can't drop privileges");
- if (pledge("stdio inet dns recvfd", NULL) == -1)
+ if (unveil(tls_default_ca_cert_file(), "r") == -1)
+ fatal("unveil");
+
+ if (pledge("stdio inet dns rpath recvfd", NULL) == -1)
fatal("pledge");
ev_base = event_init();
@@ -573,7 +572,7 @@ resolver_dispatch_main(int fd, short event, void *bula)
event_add(&iev_captiveportal->ev, NULL);
break;
case IMSG_STARTUP:
- if (pledge("stdio inet dns", NULL) == -1)
+ if (pledge("stdio inet dns rpath", NULL) == -1)
fatal("pledge");
break;
case IMSG_RECONF_CONF:
@@ -861,6 +860,8 @@ new_static_dot_forwarders(void)
static_dot_forwarder = create_resolver(STATIC_DOT_FORWARDER);
set_forwarders(static_dot_forwarder,
&resolver_conf->uw_dot_forwarder_list);
+ ub_ctx_set_option(static_dot_forwarder->ctx, "tls-cert-bundle:",
+ tls_default_ca_cert_file());
ub_ctx_set_tls(static_dot_forwarder->ctx, 1);
check_resolver(static_dot_forwarder);
@@ -995,6 +996,8 @@ check_resolver(struct uw_resolver *res)
case STATIC_DOT_FORWARDER:
set_forwarders(check_res,
&resolver_conf->uw_dot_forwarder_list);
+ ub_ctx_set_option(check_res->ctx, "tls-cert-bundle:",
+ tls_default_ca_cert_file());
ub_ctx_set_tls(check_res->ctx, 1);
break;
case RESOLVER_NONE:
diff --git a/sbin/unwind/unwind.conf.5 b/sbin/unwind/unwind.conf.5
index 3a7f48549b0..b2b1f7d88a3 100644
--- a/sbin/unwind/unwind.conf.5
+++ b/sbin/unwind/unwind.conf.5
@@ -1,4 +1,4 @@
-.\" $OpenBSD: unwind.conf.5,v 1.7 2019/02/05 19:39:19 jmc Exp $
+.\" $OpenBSD: unwind.conf.5,v 1.8 2019/04/01 03:31:56 florian Exp $
.\"
.\" Copyright (c) 2018 Florian Obser <florian@openbsd.org>
.\" Copyright (c) 2005 Esben Norby <norby@openbsd.org>
@@ -18,7 +18,7 @@
.\" ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
.\" OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
.\"
-.Dd $Mdocdate: February 5 2019 $
+.Dd $Mdocdate: April 1 2019 $
.Dt UNWIND.CONF 5
.Os
.Sh NAME
@@ -63,12 +63,14 @@ forwarder { $fwd1 $fwd2 }
.Ed
.Sh GLOBAL CONFIGURATION
.Bl -tag -width Ds
-.It Ic forwarder Brq Ar address Oo Ic port Ar number Oc Oo Ic DoT Oc ...
+.It Ic forwarder Brq Ar address Oo Ic port Ar number Oc Oo Oo Ic authentication name Ar name Oc Ic DoT Oc ...
A list of addresses of DNS name servers to forward queries to.
If
.Ic DoT
is specified, use DNS over TLS when sending queries to the server at
.Ar address .
+.Ar name
+validates the certificate of the DNS over TLS server.
.El
.Pp
.Nm unwind