diff options
Diffstat (limited to 'tcpd')
| -rw-r--r-- | tcpd/configure.ac | 17 | ||||
| -rw-r--r-- | tcpd/libcouriergnutls.c | 20 | ||||
| -rw-r--r-- | tcpd/libcouriertls.c | 79 |
3 files changed, 99 insertions, 17 deletions
diff --git a/tcpd/configure.ac b/tcpd/configure.ac index 6ba8acf..447ba72 100644 --- a/tcpd/configure.ac +++ b/tcpd/configure.ac @@ -134,12 +134,12 @@ AC_SYS_LARGEFILE AC_CACHE_CHECK([for socklen_t], tcpd_cv_hassocklen_t, - + AC_COMPILE_IFELSE([ AC_LANG_SOURCE( [ #include <sys/types.h> #include <sys/socket.h> - + socklen_t sl_t; ],[ accept(0, 0, &sl_t); @@ -147,9 +147,9 @@ socklen_t sl_t; tcpd_cv_hassocklen_t=yes, tcpd_cv_hassocklen_t=no) ) - + socklen_t="int" - + if test $tcpd_cv_hassocklen_t = yes then : @@ -510,6 +510,15 @@ RAND_pseudo_bytes(dummy, 1); AC_CHECK_FUNCS(TLSv1_1_method TLSv1_2_method) LIBS="$save_LIBS" + AC_TRY_COMPILE( [ +#include <openssl/ssl.h> +], +[ +SSL_get_servername((SSL *)0, TLSEXT_NAMETYPE_host_name); +], [ + AC_DEFINE_UNQUOTED(HAVE_OPENSSL_SNI,1,[ When OpenSSL supports SNI ]) + ]) + TLSLIBRARY="$LIBCOURIERTLSOPENSSL" STARTTLS=couriertls$EXEEXT BUILDLIBCOURIERTLS=libcouriertls.la diff --git a/tcpd/libcouriergnutls.c b/tcpd/libcouriergnutls.c index 20823a9..38b70ab 100644 --- a/tcpd/libcouriergnutls.c +++ b/tcpd/libcouriergnutls.c @@ -718,7 +718,7 @@ static int verify_client(ssl_handle ssl, int fd) !gnutls_openpgp_key_check_hostname(cert, ssl->info_cpy .peer_verify_domain)) - + { char *hostname; size_t hostnamesiz=0; @@ -784,7 +784,7 @@ static int dohandshake(ssl_handle ssl, int fd, fd_set *r, fd_set *w) { ssl->info_cpy.connect_interrupted=0; - + if (verify_client(ssl, fd)) return -1; @@ -1003,7 +1003,7 @@ static int get_server_cert(gnutls_session_t session, for (p=vhost_buf; *p; p++) if (*p == '/') - *p='.'; + *p='.'; /* Script kiddie check */ if (ssl->ctx->certfile) certfilename=check_cert(ssl->ctx->certfile, @@ -1273,7 +1273,7 @@ static int do_cache_remove(void *rec, size_t recsize, int *doupdate, void *arg) } return 0; } - + static int db_remove_func(void *dummy, gnutls_datum_t key) { tls_cache_walk(((ssl_handle)dummy)->info_cpy.tlscache, @@ -1444,9 +1444,9 @@ ssl_handle tls_connect(ssl_context ctx, int fd) gnutls_session_set_ptr(ssl->session, ssl); gnutls_handshake_set_private_extensions(ssl->session, 1); - gnutls_certificate_set_verify_flags(ssl->xcred, + gnutls_certificate_set_verify_flags(ssl->xcred, GNUTLS_VERIFY_ALLOW_X509_V1_CA_CRT | - + /* GNUTLS_VERIFY_DO_NOT_ALLOW_SAME | GNUTLS_VERIFY_ALLOW_ANY_X509_V1_CA_C @@ -1567,7 +1567,7 @@ int tls_transfer(struct tls_transfer_info *t, ssl_handle ssl, int fd, return 1; } - + t->shutdown_interrupted=0; t->shutdown= -1; return -1; @@ -1717,7 +1717,7 @@ static const char *dump_dn(gnutls_x509_crt_t cert, free(oidname); return gnutls_strerror(rc); } - + vidx=0; while (bufsiz=0, @@ -1781,7 +1781,7 @@ static const char *dump_dn(gnutls_x509_crt_t cert, ++vidx; } } - + free(oidval); free(oidname); return NULL; @@ -1870,7 +1870,7 @@ static void dump_cipher_name(gnutls_session_t session, gnutls_compression_method_t comp; (*dump_func)(gnutls_kx_get_name(kx_algo), -1, dump_arg); - + (*dump_func)("-", 1, dump_arg); (*dump_func)(gnutls_certificate_type_get_name(gnutls_certificate_type_get(session)), -1, dump_arg); diff --git a/tcpd/libcouriertls.c b/tcpd/libcouriertls.c index 9252c05..985c76e 100644 --- a/tcpd/libcouriertls.c +++ b/tcpd/libcouriertls.c @@ -1,5 +1,5 @@ /* -** Copyright 2000-2014 Double Precision, Inc. +** Copyright 2000-2016 Double Precision, Inc. ** See COPYING for distribution information. */ #include "config.h" @@ -308,7 +308,24 @@ static void load_dh_params(SSL_CTX *ctx, const char *filename, DH_free(dh); } else - sslerror(info, filename, -1); + { + /* + ** If the certificate file does not have DH parameters, + ** swallow the error. + */ + + int err=ERR_peek_last_error(); + + if (ERR_GET_LIB(err) == ERR_LIB_PEM + && ERR_GET_REASON(err) == PEM_R_NO_START_LINE) + { + ERR_clear_error(); + } + else + { + sslerror(info, filename, -1); + } + } BIO_free(bio); } else @@ -476,6 +493,47 @@ static int client_cert_cb(ssl_handle ssl, X509 **x509, EVP_PKEY **pkey) return rc; } +static int server_cert_cb(ssl_handle ssl, int *ad, void *arg) +{ +#ifdef HAVE_OPENSSL_SNI + struct tls_info *info=(struct tls_info *)SSL_get_app_data(ssl); + const char *servername=SSL_get_servername(ssl, + TLSEXT_NAMETYPE_host_name); + const char *certfile=safe_getenv(info, "TLS_CERTFILE"); + int cert_file_flags=0; + char *buffer; + char *p; + + if (!servername || !certfile) + return SSL_TLSEXT_ERR_OK; + + buffer=malloc(strlen(certfile)+strlen(servername)+2); + if (!buffer) + { + nonsslerror(info, "malloc"); + exit(1); + } + + strcat(strcpy(buffer, certfile), "."); + + p=buffer + strlen(buffer); + + while ((*p=*servername) != 0) + { + if (*p == '/') + *p='.'; /* Script kiddie check */ + ++p; + ++servername; + } + + if (access(buffer, R_OK) == 0) + read_certfile(SSL_get_SSL_CTX(ssl), buffer, &cert_file_flags); + + free(buffer); +#endif + return SSL_TLSEXT_ERR_OK; +} + SSL_CTX *tls_create(int isserver, const struct tls_info *info) { SSL_CTX *ctx; @@ -691,8 +749,15 @@ SSL_CTX *tls_create(int isserver, const struct tls_info *info) } SSL_CTX_set_verify(ctx, get_peer_verify_level(info), ssl_verify_callback); - if (!isserver) + + if (isserver) + { + SSL_CTX_set_tlsext_servername_callback(ctx, server_cert_cb); + } + else + { SSL_CTX_set_client_cert_cb(ctx, client_cert_cb); + } return (ctx); } @@ -997,6 +1062,14 @@ SSL *tls_connect(SSL_CTX *ctx, int fd) { SSL_set_connect_state(ssl); +#ifdef HAVE_OPENSSL_SNI + if (info->peer_verify_domain) + { + fprintf(stderr, "Requesting %s\n", info->peer_verify_domain); + SSL_set_tlsext_host_name(ssl, info->peer_verify_domain); + } +#endif + if ((rc=SSL_connect(ssl)) > 0) { if (!verifypeer(info, ssl)) |
