diff options
| author | Sam Varshavchik | 2019-12-05 23:21:07 -0500 |
|---|---|---|
| committer | Sam Varshavchik | 2019-12-05 23:21:07 -0500 |
| commit | 308ea8eb3eed15a4b32593346d38c82cbf919f4f (patch) | |
| tree | 72382230f2d0efcfb501f0b53111ed50bfda2d64 /tcpd/libcouriergnutls.c | |
| parent | a16b12fc62d7deb1ac288eddf6ff826da69787f3 (diff) | |
| download | courier-libs-308ea8eb3eed15a4b32593346d38c82cbf919f4f.tar.bz2 | |
gnutls: UTF-8 and hostname fixes.
Diffstat (limited to 'tcpd/libcouriergnutls.c')
| -rw-r--r-- | tcpd/libcouriergnutls.c | 89 |
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)); |
