diff --git a/CMakeLists.txt b/CMakeLists.txt index bd0cabd04..a5e08fae9 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -164,6 +164,7 @@ if(OPENSSL_FOUND) check_function_exists_define(BIO_get_data) check_function_exists_define(RSA_get0_key) check_function_exists_define(ASN1_STRING_get0_data) + check_function_exists_define(SSL_set_alpn_protos) set(CMAKE_REQUIRED_LIBRARIES) endif(OPENSSL_FOUND) @@ -395,6 +396,7 @@ else(WIN32) check_function_exists_define(gnutls_certificate_set_verify_function) check_function_exists_define(gnutls_record_disable_padding) check_function_exists_define(gnutls_rnd) + check_function_exists_define(gnutls_alpn_set_protocols) set(CMAKE_REQUIRED_LIBRARIES) pkg_check_modules(NETTLEDEP gnutls) if (";${NETTLEDEP_STATIC_LIBRARIES};" MATCHES ";nettle;") diff --git a/configure.ac b/configure.ac index 88540ecaa..b24a85a1b 100644 --- a/configure.ac +++ b/configure.ac @@ -823,7 +823,7 @@ if test "$with_gnutls" = "yes"; then NETWORK_LIBS="$NETWORK_LIBS `libgnutls-config --libs`"] ) ACX_PUSH_LIBS("$NETWORK_LIBS") - AC_CHECK_FUNCS([gnutls_certificate_set_verify_function gnutls_record_disable_padding gnutls_rnd]) + AC_CHECK_FUNCS([gnutls_certificate_set_verify_function gnutls_record_disable_padding gnutls_rnd gnutls_alpn_set_protocols]) ACX_POP_LIBS if test "$gnutls_backend" = "unknown"; then gnutls_backend=gcrypt diff --git a/m4/check_openssl.m4 b/m4/check_openssl.m4 index 9617ff3fd..46caa0e8b 100644 --- a/m4/check_openssl.m4 +++ b/m4/check_openssl.m4 @@ -34,7 +34,7 @@ NETWORK_LIBS="$NETWORK_LIBS $OPENSSL_LIBS"], [found_ssl=no elif test x$found_ssl = xyes; then HAVE_OPENSSL=yes ACX_PUSH_LIBS("$NETWORK_LIBS") - AC_CHECK_FUNCS([BIO_get_data RSA_get0_key ASN1_STRING_get0_data]) + AC_CHECK_FUNCS([BIO_get_data RSA_get0_key ASN1_STRING_get0_data SSL_set_alpn_protos]) ACX_POP_LIBS AC_DEFINE(HAVE_OPENSSL, 1, [Define if you have the OpenSSL.]) else diff --git a/src/tds/tls.c b/src/tds/tls.c index ff8294969..f2d783ea1 100644 --- a/src/tds/tls.c +++ b/src/tds/tls.c @@ -115,6 +115,10 @@ BIO_get_data(const BIO *b) #define CONN2TDS(conn) ((TDSSOCKET *) conn) #endif +/* tds/8.0 */ +#define TDS8_ALPN_ARRAY 't', 'd', 's', '/', '8', '.', '0' +#define TDS8_ALPN_ARRAY_LEN 7 + static SSL_RET tds_pull_func_login(SSL_PULL_ARGS) { @@ -562,6 +566,14 @@ tds_ssl_init(TDSSOCKET *tds, bool full) if (ret != 0) goto cleanup; +#ifdef HAVE_GNUTLS_ALPN_SET_PROTOCOLS + if (IS_TDS80_PLUS(tds->conn)) { + static const unsigned char alpn[] = { TDS8_ALPN_ARRAY }; + static const gnutls_datum_t tds8_alpn = { (void*) alpn, sizeof(alpn) }; + gnutls_alpn_set_protocols(session, &tds8_alpn, 1, 0); + } +#endif + if (full) set_current_tds(tds->conn, tds); @@ -1067,6 +1079,15 @@ tds_ssl_init(TDSSOCKET *tds, bool full) SSL_set_options(con, SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS); #endif +#ifdef HAVE_SSL_SET_ALPN_PROTOS + if (IS_TDS80_PLUS(tds->conn)) { + static const unsigned char tds8_alpn[] = { + TDS8_ALPN_ARRAY_LEN, TDS8_ALPN_ARRAY + }; + SSL_set_alpn_protos(con, tds8_alpn, sizeof(tds8_alpn)); + } +#endif + if (full) set_current_tds(tds->conn, tds);