diff options
| author | Sam Varshavchik | 2019-12-05 07:17:29 -0500 |
|---|---|---|
| committer | Sam Varshavchik | 2019-12-05 07:17:29 -0500 |
| commit | a16b12fc62d7deb1ac288eddf6ff826da69787f3 (patch) | |
| tree | d6f9ac0c490963430c2b2458e20093636fbb4cde /tcpd | |
| parent | 8214452162033fea2102557605aa1c7893b08df2 (diff) | |
| download | courier-libs-a16b12fc62d7deb1ac288eddf6ff826da69787f3.tar.bz2 | |
Use UTF-8 for IDNs.
Diffstat (limited to 'tcpd')
| -rw-r--r-- | tcpd/libcouriergnutls.c | 53 |
1 files changed, 45 insertions, 8 deletions
diff --git a/tcpd/libcouriergnutls.c b/tcpd/libcouriergnutls.c index 6bc35e7..65c34cb 100644 --- a/tcpd/libcouriergnutls.c +++ b/tcpd/libcouriergnutls.c @@ -18,6 +18,7 @@ #include <stdlib.h> #include <ctype.h> #include <netdb.h> +#include <idna.h> #if HAVE_DIRENT_H #include <dirent.h> #define NAMLEN(dirent) strlen((dirent)->d_name) @@ -553,6 +554,27 @@ static int chk_error(int rc, ssl_handle ssl, int fd, fd_set *r, fd_set *w, return 0; } +static int name_check(ssl_handle ssl, + gnutls_x509_crt_t cert) +{ + char *idn_domain; + const char *p; + int rc; + + if (idna_to_unicode_8z8z(ssl->info_cpy.peer_verify_domain, + &idn_domain, 0) != IDNA_SUCCESS) + idn_domain=0; + + p=idn_domain ? idn_domain:ssl->info_cpy.peer_verify_domain; + + rc=gnutls_x509_crt_check_hostname(cert, p); + + if (idn_domain) + free(idn_domain); + return rc; +} + + static int verify_client(ssl_handle ssl, int fd) { unsigned int status; @@ -646,10 +668,7 @@ static int verify_client(ssl_handle ssl, int fd) if (ssl->info_cpy.peer_verify_domain && *ssl->info_cpy.peer_verify_domain && - !gnutls_x509_crt_check_hostname(cert, - ssl->info_cpy - .peer_verify_domain - )) + !name_check(ssl, cert)) { char hostname[256]; size_t hostname_size=sizeof(hostname); @@ -1293,6 +1312,27 @@ static gnutls_datum_t db_retrieve_func(void *dummy, gnutls_datum_t key) return drs.ret; } +static int name_set(ssl_handle ssl, ssl_context ctx) +{ + char *idn_domain; + const char *p; + int rc; + + if (idna_to_unicode_8z8z(ctx->info_cpy.peer_verify_domain, + &idn_domain, 0) != IDNA_SUCCESS) + idn_domain=0; + + p=idn_domain ? idn_domain:ctx->info_cpy.peer_verify_domain; + + + rc=gnutls_server_name_set(ssl->session, GNUTLS_NAME_DNS, + p, strlen(p)); + + if (idn_domain) + free(idn_domain); + return rc; +} + ssl_handle tls_connect(ssl_context ctx, int fd) { ssl_handle ssl=malloc(sizeof(struct ssl_handle_t)); @@ -1434,10 +1474,7 @@ RT | ssl->xcred) < 0 || (ctx->info_cpy.peer_verify_domain && - gnutls_server_name_set(ssl->session, GNUTLS_NAME_DNS, - ctx->info_cpy.peer_verify_domain, - strlen(ctx->info_cpy.peer_verify_domain)) - < 0) + name_set(ssl, ctx) < 0) ) { tls_free_session(ssl); |
