summaryrefslogtreecommitdiffstats
path: root/tcpd/libcouriergnutls.c
diff options
context:
space:
mode:
authorSam Varshavchik2019-12-05 23:21:07 -0500
committerSam Varshavchik2019-12-05 23:21:07 -0500
commit308ea8eb3eed15a4b32593346d38c82cbf919f4f (patch)
tree72382230f2d0efcfb501f0b53111ed50bfda2d64 /tcpd/libcouriergnutls.c
parenta16b12fc62d7deb1ac288eddf6ff826da69787f3 (diff)
downloadcourier-libs-308ea8eb3eed15a4b32593346d38c82cbf919f4f.tar.bz2
gnutls: UTF-8 and hostname fixes.
Diffstat (limited to 'tcpd/libcouriergnutls.c')
-rw-r--r--tcpd/libcouriergnutls.c89
1 files changed, 72 insertions, 17 deletions
diff --git a/tcpd/libcouriergnutls.c b/tcpd/libcouriergnutls.c
index 65c34cb..7a48ae3 100644
--- a/tcpd/libcouriergnutls.c
+++ b/tcpd/libcouriergnutls.c
@@ -1,5 +1,5 @@
/*
-** Copyright 2007-2018 Double Precision, Inc.
+** Copyright 2007-2019 Double Precision, Inc.
** See COPYING for distribution information.
*/
#include "config.h"
@@ -567,10 +567,21 @@ static int name_check(ssl_handle ssl,
p=idn_domain ? idn_domain:ssl->info_cpy.peer_verify_domain;
+ printf("Check %s\n", p);
rc=gnutls_x509_crt_check_hostname(cert, p);
if (idn_domain)
+ {
free(idn_domain);
+
+ /* Now try the ACE-encoded hostname for a filename. */
+
+ if (rc == 0)
+ {
+ p=ssl->info_cpy.peer_verify_domain;
+ rc=gnutls_x509_crt_check_hostname(cert, p);
+ }
+ }
return rc;
}
@@ -736,10 +747,10 @@ static int dohandshake(ssl_handle ssl, int fd, fd_set *r, fd_set *w)
return rc;
}
-static char *check_cert(const char *filename,
- gnutls_certificate_type_t cert_type,
- const char *req_dn,
- int isvirtual)
+static char *check_cert_unicode(const char *filename,
+ gnutls_certificate_type_t cert_type,
+ const char *req_dn,
+ int isvirtual)
{
if (!filename || !*filename)
return NULL;
@@ -766,6 +777,12 @@ static char *check_cert(const char *filename,
++req_dn;
}
+ /*
+ ** We're called with a hostname first. Don't check the defualt
+ ** filename, we'll be called again with an IP address
+ */
+
+ if (!isvirtual)
{
char *p=malloc(strlen(filename)+10);
@@ -782,6 +799,33 @@ static char *check_cert(const char *filename,
return NULL;
}
+static char *check_cert(const char *filename,
+ gnutls_certificate_type_t cert_type,
+ const char *req_dn,
+ int isvirtual)
+{
+ if (isvirtual)
+ {
+ char *p;
+ char *retfile;
+
+ if (idna_to_ascii_8z(req_dn, &p, 0) != IDNA_SUCCESS)
+ p=0;
+
+ if (p)
+ {
+ retfile=check_cert_unicode(filename, cert_type, p,
+ isvirtual);
+ free(p);
+
+ if (retfile)
+ return retfile;
+ }
+ }
+
+ return check_cert_unicode(filename, cert_type, req_dn, isvirtual);
+}
+
static char *check_key(const char *filename,
gnutls_certificate_type_t cert_type,
const char *req_dn,
@@ -952,39 +996,51 @@ static int get_server_cert(gnutls_session_t session,
++vhost_idx)
{
char *p;
+ char *utf8;
+ char *namebuf;
+
+ /* Convert to UTF8 */
+ if (idna_to_unicode_8z8z(vhost_buf, &utf8, 0)
+ != IDNA_SUCCESS)
+ utf8=0;
- for (p=vhost_buf; *p; p++)
+ namebuf=utf8 ? utf8:vhost_buf;
+
+ for (p=namebuf; *p; p++)
if (*p == '/')
*p='.'; /* Script kiddie check */
if (ssl->ctx->certfile)
certfilename=check_cert(ssl->ctx->certfile,
st->cert_type,
- vhost_buf, 1);
+ namebuf, 1);
if (ssl->ctx->keyfile)
keyfilename=check_key(ssl->ctx->keyfile,
st->cert_type,
- vhost_buf, 1);
+ namebuf, 1);
+ if (utf8)
+ free(utf8);
if (certfilename)
break;
}
if (!certfilename)
{
+ const char *ip=
+ safe_getenv(ssl->ctx,
+ "TCPLOCALIP", "");
+
+ if (strncmp(ip, "::ffff:", 7) == 0 && strchr(ip, '.'))
+ ip += 7;
+
if (ssl->ctx->certfile)
certfilename=check_cert(ssl->ctx->certfile,
- st->cert_type,
- safe_getenv(ssl->ctx,
- "TCPLOCALIP", ""),
- 0);
+ st->cert_type, ip, 0);
if (ssl->ctx->keyfile)
keyfilename=check_key(ssl->ctx->keyfile,
- st->cert_type,
- safe_getenv(ssl->ctx,
- "TCPLOCALIP", ""),
- 0);
+ st->cert_type, ip, 0);
}
if (!certfilename)
@@ -1324,7 +1380,6 @@ static int name_set(ssl_handle ssl, ssl_context ctx)
p=idn_domain ? idn_domain:ctx->info_cpy.peer_verify_domain;
-
rc=gnutls_server_name_set(ssl->session, GNUTLS_NAME_DNS,
p, strlen(p));