Commit Diff


commit - a0a42860d214974f2706d2a47203af9bc884f512
commit + e50f85adcb432192b35cf7b878c9104d697ad1a3
blob - 5899f9eb3b260b49596daed011908e55a4c0c79b
blob + 8ef6c7047456ee63b92466d72f024cae809eb482
--- config.c
+++ config.c
@@ -136,6 +136,7 @@ config_purge(struct conf *conf)
 		if (addr->sock != -1) {
 			close(addr->sock);
 			event_del(&addr->evsock);
+			tls_free(addr->ctx);
 		}
 		free(addr);
 	}
@@ -548,6 +549,8 @@ config_recv(struct conf *conf, struct imsg *imsg)
 		addr->sock = imsg->fd;
 		event_set(&addr->evsock, addr->sock, EV_READ|EV_PERSIST,
 		    do_accept, addr);
+		if ((addr->ctx = tls_server()) == NULL)
+			fatal("tls_server failure");
 		TAILQ_INSERT_HEAD(&conf->addrs, addr, addrs);
 		break;
 
blob - 4978c2cab70a81f1a85fad0ae6cda0cddb76ddc8
blob + 708bb3b567fdc5f6b7b0ee61989a9a08a63886fc
--- ge.c
+++ ge.c
@@ -213,6 +213,9 @@ serve(struct conf *conf, const char *host, int port, c
 		event_set(&addr->evsock, addr->sock, EV_READ|EV_PERSIST,
 		    do_accept, addr);
 
+		if ((addr->ctx = tls_server()) == NULL)
+			fatal("tls_server failure");
+
 		TAILQ_INSERT_HEAD(&conf->addrs, addr, addrs);
 
 		acp = xcalloc(1, sizeof(*acp));
blob - 04fee36be9ee706b841a3e6f8fa81e7144deb242
blob + 93112f566737c542cda06a76be027897210654da
--- gmid.h
+++ gmid.h
@@ -119,6 +119,7 @@ struct address {
 	struct conf		*conf;
 	int			 sock;
 	struct event		 evsock; /* set if sock != -1 */
+	struct tls		*ctx;
 
 	TAILQ_ENTRY(address)	 addrs;
 };
blob - 30b67b88539f333766c01ab536aaa63251e9bb5d
blob + 80043e9473ff3be59346aa70e11e3cb8696c1f8c
--- server.c
+++ server.c
@@ -38,8 +38,6 @@
 #endif
 
 int shutting_down;
-
-static struct tls	*ctx;
 
 #ifdef SIGINFO
 static struct event siginfo;
@@ -1339,7 +1337,7 @@ do_accept(int sock, short et, void *d)
 	memcpy(&c->raddr, &raddr, sizeof(raddr));
 	c->raddrlen = len;
 
-	if (tls_accept_socket(ctx, &c->ctx, fd) == -1) {
+	if (tls_accept_socket(addr->ctx, &c->ctx, fd) == -1) {
 		log_warnx("failed to accept socket: %s", tls_error(c->ctx));
 		close(c->fd);
 		free(c);
@@ -1367,18 +1365,39 @@ handle_siginfo(int fd, short ev, void *d)
 }
 
 static void
-add_keypair(struct vhost *h, struct tls_config *conf)
+add_matching_kps(struct tls_config *tlsconf, struct address *addr,
+    struct conf *conf)
 {
-	if (h->ocsp == NULL) {
-		if (tls_config_add_keypair_mem(conf, h->cert, h->certlen,
-		    h->key, h->keylen) == -1)
-			fatalx("failed to load the keypair: %s",
-			    tls_config_error(conf));
-	} else {
-		if (tls_config_add_keypair_ocsp_mem(conf, h->cert, h->certlen,
-		    h->key, h->keylen, h->ocsp, h->ocsplen) == -1)
-			fatalx("failed to load the keypair: %s",
-			    tls_config_error(conf));
+	struct address	*vaddr;
+	struct vhost	*h;
+	int		 r, any = 0;
+
+	TAILQ_FOREACH(h, &conf->hosts, vhosts) {
+		TAILQ_FOREACH(vaddr, &h->addrs, addrs) {
+			if (addr->ai_flags != vaddr->ai_flags ||
+			    addr->ai_family != vaddr->ai_family ||
+			    addr->ai_socktype != vaddr->ai_socktype ||
+			    addr->ai_protocol != vaddr->ai_protocol ||
+			    addr->slen != vaddr->slen ||
+			    memcmp(&addr->ss, &vaddr->ss, addr->slen) != 0)
+				continue;
+
+			if (!any) {
+				any = 1;
+				r = tls_config_set_keypair_ocsp_mem(tlsconf,
+				    h->cert, h->certlen, h->key, h->keylen,
+				    h->ocsp, h->ocsplen);
+			} else {
+				r = tls_config_add_keypair_ocsp_mem(tlsconf,
+				    h->cert, h->certlen, h->key, h->keylen,
+				    h->ocsp, h->ocsplen);
+			}
+
+			if (r == -1)
+				fatalx("failed to load keypair"
+				    " for host %s: %s", h->domain,
+				    tls_config_error(tlsconf));
+		}
 	}
 }
 
@@ -1386,50 +1405,31 @@ static void
 setup_tls(struct conf *conf)
 {
 	struct tls_config	*tlsconf;
-	struct vhost		*h;
+	struct address		*addr;
 
-	if (ctx == NULL) {
-		if ((ctx = tls_server()) == NULL)
-			fatal("tls_server failure");
-	}
-
-	if ((tlsconf = tls_config_new()) == NULL)
-		fatal("tls_config_new");
+	TAILQ_FOREACH(addr, &conf->addrs, addrs) {
+		if ((tlsconf = tls_config_new()) == NULL)
+			fatal("tls_config_new");
 
-	if (conf->use_privsep_crypto)
-		tls_config_use_fake_private_key(tlsconf);
+		if (conf->use_privsep_crypto)
+			tls_config_use_fake_private_key(tlsconf);
 
-	/* optionally accept client certs, but don't try to verify them */
-	tls_config_verify_client_optional(tlsconf);
-	tls_config_insecure_noverifycert(tlsconf);
+		/* optionally accept client certs but don't verify */
+		tls_config_verify_client_optional(tlsconf);
+		tls_config_insecure_noverifycert(tlsconf);
 
-	if (tls_config_set_protocols(tlsconf, conf->protos) == -1)
-		fatalx("tls_config_set_protocols: %s",
-		    tls_config_error(tlsconf));
+		if (tls_config_set_protocols(tlsconf, conf->protos) == -1)
+			fatalx("tls_config_set_protocols: %s",
+			    tls_config_error(tlsconf));
 
-	h = TAILQ_FIRST(&conf->hosts);
+		add_matching_kps(tlsconf, addr, conf);
 
-	/* we need to set something, then we can add how many key we want */
-	if (tls_config_set_keypair_mem(tlsconf, h->cert, h->certlen,
-	    h->key, h->keylen) == -1)
-		fatalx("tls_config_set_keypair_mem failed: %s",
-		    tls_config_error(tlsconf));
+		tls_reset(addr->ctx);
+		if (tls_configure(addr->ctx, tlsconf) == -1)
+			fatalx("tls_configure: %s", tls_error(addr->ctx));
 
-	/* same for OCSP */
-	if (h->ocsp != NULL &&
-	    tls_config_set_ocsp_staple_mem(tlsconf, h->ocsp, h->ocsplen)
-	    == -1)
-		fatalx("tls_config_set_ocsp_staple_file failed: %s",
-		    tls_config_error(tlsconf));
-
-	while ((h = TAILQ_NEXT(h, vhosts)) != NULL)
-		add_keypair(h, tlsconf);
-
-	tls_reset(ctx);
-	if (tls_configure(ctx, tlsconf) == -1)
-		fatalx("tls_configure: %s", tls_error(ctx));
-
-	tls_config_free(tlsconf);
+		tls_config_free(tlsconf);
+	}
 }
 
 static void