From 352cd81960da283d21f4051bc1061f06f7ec746d Mon Sep 17 00:00:00 2001 From: Jan Venekamp <1422460+jan2000@users.noreply.github.com> Date: Thu, 22 Aug 2024 02:18:57 +0200 Subject: [PATCH] test2 --- .github/workflows/macos.yml | 207 ++++++++++++----------- lib/vtls/sectransp.c | 274 ++++++------------------------- tests/http/test_10_proxy.py | 10 ++ tests/http/test_13_proxy_auth.py | 4 + tests/http/test_17_ssl_use.py | 12 +- tests/http/test_20_websockets.py | 5 +- tests/http/testenv/client.py | 2 +- tests/http/testenv/env.py | 43 +++-- tests/http/testenv/httpd.py | 19 ++- 9 files changed, 233 insertions(+), 343 deletions(-) diff --git a/.github/workflows/macos.yml b/.github/workflows/macos.yml index 52edbc33a197ac..506a505fd4c40c 100644 --- a/.github/workflows/macos.yml +++ b/.github/workflows/macos.yml @@ -9,6 +9,7 @@ on: branches: - master - '*/ci' + - '*/ci-pytest' paths-ignore: - '**/*.md' - '.azure-pipelines.yml' @@ -68,84 +69,85 @@ jobs: fail-fast: false matrix: include: - - name: '!ssl !debug brotli zstd' - compiler: clang - install: brotli zstd - configure: --without-ssl --enable-websockets --with-brotli --with-zstd - macos-version-min: '10.9' - - name: '!ssl !debug' - compiler: gcc-12 - configure: --without-ssl --enable-websockets - macos-version-min: '10.9' - - name: '!ssl' - compiler: clang - configure: --enable-debug --without-ssl --enable-websockets - macos-version-min: '10.9' - - name: '!ssl libssh2 AppleIDN' - compiler: clang - configure: --enable-debug --with-libssh2=$(brew --prefix libssh2) --without-ssl --with-apple-idn --enable-websockets - macos-version-min: '10.9' - - name: 'OpenSSL libssh c-ares' - compiler: clang - install: libssh - configure: --enable-debug --with-libssh --with-openssl=$(brew --prefix openssl) --enable-ares --enable-websockets - macos-version-min: '10.9' - - name: 'OpenSSL libssh' - compiler: llvm@15 - install: libssh - configure: --enable-debug --with-libssh --with-openssl=$(brew --prefix openssl) --enable-websockets - macos-version-min: '10.9' - - name: '!ssl c-ares' - compiler: clang - configure: --enable-debug --enable-ares --without-ssl --enable-websockets - macos-version-min: '10.9' - - name: '!ssl HTTP-only' - compiler: clang - configure: | - --enable-debug \ - --disable-alt-svc --disable-dict --disable-file --disable-ftp --disable-gopher --disable-imap \ - --disable-ldap --disable-pop3 --disable-rtmp --disable-rtsp --disable-scp --disable-sftp \ - --disable-shared --disable-smb --disable-smtp --disable-telnet --disable-tftp --disable-unix-sockets \ - --without-brotli --without-gssapi --without-libidn2 --without-libpsl --without-librtmp --without-libssh2 \ - --without-nghttp2 --without-ntlm-auth --without-ssl --without-zlib --without-zstd - - macos-version-min: '10.15' # Catalina (2019) +# - name: '!ssl !debug brotli zstd' +# compiler: clang +# install: brotli zstd +# configure: --without-ssl --enable-websockets --with-brotli --with-zstd +# macos-version-min: '10.9' +# - name: '!ssl !debug' +# compiler: gcc-12 +# configure: --without-ssl --enable-websockets +# macos-version-min: '10.9' +# - name: '!ssl' +# compiler: clang +# configure: --enable-debug --without-ssl --enable-websockets +# macos-version-min: '10.9' +# - name: '!ssl libssh2 AppleIDN' +# compiler: clang +# configure: --enable-debug --with-libssh2=$(brew --prefix libssh2) --without-ssl --with-apple-idn --enable-websockets +# macos-version-min: '10.9' +# - name: 'OpenSSL libssh c-ares' +# compiler: clang +# install: libssh +# configure: --enable-debug --with-libssh --with-openssl=$(brew --prefix openssl) --enable-ares --enable-websockets +# macos-version-min: '10.9' +# - name: 'OpenSSL libssh' +# compiler: llvm@15 +# install: libssh +# configure: --enable-debug --with-libssh --with-openssl=$(brew --prefix openssl) --enable-websockets +# macos-version-min: '10.9' +# - name: '!ssl c-ares' +# compiler: clang +# configure: --enable-debug --enable-ares --without-ssl --enable-websockets +# macos-version-min: '10.9' +# - name: '!ssl HTTP-only' +# compiler: clang +# configure: | +# --enable-debug \ +# --disable-alt-svc --disable-dict --disable-file --disable-ftp --disable-gopher --disable-imap \ +# --disable-ldap --disable-pop3 --disable-rtmp --disable-rtsp --disable-scp --disable-sftp \ +# --disable-shared --disable-smb --disable-smtp --disable-telnet --disable-tftp --disable-unix-sockets \ +# --without-brotli --without-gssapi --without-libidn2 --without-libpsl --without-librtmp --without-libssh2 \ +# --without-nghttp2 --without-ntlm-auth --without-ssl --without-zlib --without-zstd +# +# macos-version-min: '10.15' # Catalina (2019) - name: 'SecureTransport libssh2' compiler: clang + install: httpd caddy vsftpd configure: --enable-debug --with-secure-transport --enable-websockets --with-libssh2=$(brew --prefix libssh2) macos-version-min: '10.8' - - name: 'SecureTransport libssh2 10.12' - compiler: clang - configure: --enable-debug --with-secure-transport --enable-websockets --with-libssh2=$(brew --prefix libssh2) - macos-version-min: '10.12' # for monotonic timers - cflags: '-Wno-deprecated-declarations' - - name: 'SecureTransport libssh2' - compiler: gcc-12 - configure: --enable-debug --with-secure-transport --enable-websockets --with-libssh2=$(brew --prefix libssh2) - macos-version-min: '10.8' - - name: 'LibreSSL' - compiler: clang - install: libressl - configure: --enable-debug --with-openssl=$(brew --prefix libressl) --enable-websockets - macos-version-min: '10.9' - - name: 'OpenSSL' - compiler: clang - configure: --enable-debug --with-openssl=$(brew --prefix openssl) --enable-websockets - macos-version-min: '10.9' - - name: 'OpenSSL torture !FTP' - compiler: clang - configure: --enable-debug --disable-shared --disable-threaded-resolver --with-openssl=$(brew --prefix openssl) --enable-websockets - tflags: -n -t --shallow=25 !FTP - macos-version-min: '10.9' - - name: 'OpenSSL torture FTP' - compiler: clang - configure: --enable-debug --disable-shared --disable-threaded-resolver --with-openssl=$(brew --prefix openssl) --enable-websockets - tflags: -n -t --shallow=20 FTP - macos-version-min: '10.9' - - name: 'OpenSSL libssh2 !ldap 10.15' - compiler: clang - configure: --enable-debug --disable-ldap --with-openssl=$(brew --prefix openssl) --enable-websockets - macos-version-min: '10.15' +# - name: 'SecureTransport libssh2 10.12' +# compiler: clang +# configure: --enable-debug --with-secure-transport --enable-websockets --with-libssh2=$(brew --prefix libssh2) +# macos-version-min: '10.12' # for monotonic timers +# cflags: '-Wno-deprecated-declarations' +# - name: 'SecureTransport libssh2' +# compiler: gcc-12 +# configure: --enable-debug --with-secure-transport --enable-websockets --with-libssh2=$(brew --prefix libssh2) +# macos-version-min: '10.8' +# - name: 'LibreSSL' +# compiler: clang +# install: libressl +# configure: --enable-debug --with-openssl=$(brew --prefix libressl) --enable-websockets +# macos-version-min: '10.9' +# - name: 'OpenSSL' +# compiler: clang +# configure: --enable-debug --with-openssl=$(brew --prefix openssl) --enable-websockets +# macos-version-min: '10.9' +# - name: 'OpenSSL torture !FTP' +# compiler: clang +# configure: --enable-debug --disable-shared --disable-threaded-resolver --with-openssl=$(brew --prefix openssl) --enable-websockets +# tflags: -n -t --shallow=25 !FTP +# macos-version-min: '10.9' +# - name: 'OpenSSL torture FTP' +# compiler: clang +# configure: --enable-debug --disable-shared --disable-threaded-resolver --with-openssl=$(brew --prefix openssl) --enable-websockets +# tflags: -n -t --shallow=20 FTP +# macos-version-min: '10.9' +# - name: 'OpenSSL libssh2 !ldap 10.15' +# compiler: clang +# configure: --enable-debug --disable-ldap --with-openssl=$(brew --prefix openssl) --enable-websockets +# macos-version-min: '10.15' steps: - name: 'brew install' # Run this command with retries because of spurious failures seen @@ -179,7 +181,7 @@ jobs: run: | python3 -m venv $HOME/venv source $HOME/venv/bin/activate - python3 -m pip install impacket + python3 -m pip install impacket pytest psutil websockets - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4 @@ -214,6 +216,9 @@ jobs: fi if [[ '${{ matrix.compiler }}' = 'llvm'* ]]; then options+=" --target=$(uname -m)-apple-darwin" + options+=" --with-test-httpd=$(brew --prefix httpd)" + options+=" --with-test-caddy=$(brew --prefix caddy)" + options+=" --with-test-vsftpd=$(brew --prefix vsftpd)" CC+=" --target=$(uname -m)-apple-darwin" fi if [ '${{ matrix.compiler }}' != 'clang' ]; then @@ -240,29 +245,39 @@ jobs: - name: 'curl version' run: bld/src/curl --disable --version - - name: 'make examples' - run: make -C bld V=1 examples - - - name: 'make tests' - run: make -C bld V=1 -C tests - - - name: 'run tests' +# - name: 'make examples' +# run: make -C bld V=1 examples +# +# - name: 'make tests' +# run: make -C bld V=1 -C tests +# +# - name: 'run tests' +# run: | +# export TFLAGS='${{ matrix.tflags }} -j10' +# if [[ '${{ matrix.compiler }}' = 'gcc'* ]]; then +# TFLAGS+=' ~RTSP' # 567 568 569 570 571 572 577 689 3100 +# TFLAGS+=' ~1156 ~1539' # HTTP Content-Range, Content-Length +# if [[ '${{ matrix.configure }}' = *'--with-secure-transport'* ]]; then +# TFLAGS+=' ~2100' # 2100:'HTTP GET using DoH' https://github.com/curl/curl/actions/runs/9942146678/job/27462937524#step:15:5059 +# TFLAGS+=' ~HTTP/2' # 2400 2401 2402 2403 2404 2406, SecureTransport + nghttp2 +# else +# TFLAGS+=' ~2402 ~2404' # non-SecureTransport + nghttp2 +# fi +# fi +# rm -f $HOME/.curlrc +# make -C bld V=1 test-ci + + - name: 'run pytest' run: | - export TFLAGS='${{ matrix.tflags }} -j10' - if [[ '${{ matrix.compiler }}' = 'gcc'* ]]; then - TFLAGS+=' ~RTSP' # 567 568 569 570 571 572 577 689 3100 - TFLAGS+=' ~1156 ~1539' # HTTP Content-Range, Content-Length - if [[ '${{ matrix.configure }}' = *'--with-secure-transport'* ]]; then - TFLAGS+=' ~2100' # 2100:'HTTP GET using DoH' https://github.com/curl/curl/actions/runs/9942146678/job/27462937524#step:15:5059 - TFLAGS+=' ~HTTP/2' # 2400 2401 2402 2403 2404 2406, SecureTransport + nghttp2 - else - TFLAGS+=' ~2402 ~2404' # non-SecureTransport + nghttp2 - fi - fi - rm -f $HOME/.curlrc - make -C bld V=1 test-ci + source $HOME/venv/bin/activate + python3 -m pytest -v tests -s + env: + BUILD_DIR: bld + TFLAGS: "${{ matrix.build.tflags }}" + CURL_CI: github cmake: + if: false name: 'CM ${{ matrix.compiler }} ${{ matrix.build.name }}' runs-on: 'macos-latest' timeout-minutes: 10 @@ -384,7 +399,7 @@ jobs: make -C bld test-ci combinations: # Test buildability with host OS, Xcode / SDK, compiler, target-OS, SecureTransport/not, built tool, combinations - if: true # Set to `true` to enable this test matrix. It runs quickly. + if: false # Set to `true` to enable this test matrix. It runs quickly. name: "${{ matrix.build == 'cmake' && 'CM' || 'AM' }} ${{ matrix.compiler }} ${{ matrix.image }} ${{ matrix.xcode }} ${{ matrix.config }}" runs-on: ${{ matrix.image }} timeout-minutes: 30 diff --git a/lib/vtls/sectransp.c b/lib/vtls/sectransp.c index 8cc551458ffa31..6b32ac6c57c933 100644 --- a/lib/vtls/sectransp.c +++ b/lib/vtls/sectransp.c @@ -718,134 +718,71 @@ CF_INLINE bool is_file(const char *filename) return false; } -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS -static CURLcode sectransp_version_from_curl(SSLProtocol *darwinver, - long ssl_version) -{ - switch(ssl_version) { - case CURL_SSLVERSION_TLSv1_0: - *darwinver = kTLSProtocol1; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_1: - *darwinver = kTLSProtocol11; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_2: - *darwinver = kTLSProtocol12; - return CURLE_OK; - case CURL_SSLVERSION_TLSv1_3: - /* TLS 1.3 support first appeared in iOS 11 and macOS 10.13 */ -#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && \ - defined(HAVE_BUILTIN_AVAILABLE) - if(__builtin_available(macOS 10.13, iOS 11.0, *)) { - *darwinver = kTLSProtocol13; - return CURLE_OK; - } -#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && - defined(HAVE_BUILTIN_AVAILABLE) */ - break; - } - return CURLE_SSL_CONNECT_ERROR; -} -#endif - -static CURLcode sectransp_set_ssl_version_min_max(struct Curl_cfilter *cf, - struct Curl_easy *data) +static CURLcode +sectransp_set_ssl_version_min_max(struct Curl_easy *data, + struct st_ssl_backend_data *backend, + struct ssl_primary_config *conn_config) { - struct ssl_connect_data *connssl = cf->ctx; - struct st_ssl_backend_data *backend = - (struct st_ssl_backend_data *)connssl->backend; - struct ssl_primary_config *conn_config = Curl_ssl_cf_get_primary_config(cf); - long ssl_version = conn_config->version; - long ssl_version_max = conn_config->version_max; - long max_supported_version_by_os; - - DEBUGASSERT(backend); - - /* macOS 10.5-10.7 supported TLS 1.0 only. - macOS 10.8 and later, and iOS 5 and later, added TLS 1.1 and 1.2. - macOS 10.13 and later, and iOS 11 and later, added TLS 1.3. */ -#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && \ - defined(HAVE_BUILTIN_AVAILABLE) - if(__builtin_available(macOS 10.13, iOS 11.0, *)) { - max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_3; - } - else { - max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2; - } +#if !CURL_BUILD_MAC_10_8 && !CURL_BUILD_IOS + (void) data, (void) conn_config; + /* old: only TLS 1.0 is suported, disable older SSL */ + SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false); + SSLSetProtocolVersionEnabled(backend->ssl_ctx, kTLSProtocol1, true); + return CURLE_OK; #else - max_supported_version_by_os = CURL_SSLVERSION_MAX_TLSv1_2; -#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && - defined(HAVE_BUILTIN_AVAILABLE) */ + OSStatus err; + SSLProtocol ver_min; + SSLProtocol ver_max; - switch(ssl_version) { + switch(conn_config->version) { case CURL_SSLVERSION_DEFAULT: case CURL_SSLVERSION_TLSv1: - ssl_version = CURL_SSLVERSION_TLSv1_0; + case CURL_SSLVERSION_TLSv1_0: + ver_min = kTLSProtocol1; + break; + case CURL_SSLVERSION_TLSv1_1: + ver_min = kTLSProtocol11; + break; + case CURL_SSLVERSION_TLSv1_2: + ver_min = kTLSProtocol12; break; + case CURL_SSLVERSION_TLSv1_3: + default: + failf(data, "SSL: unsupported minimum TLS version value"); + return CURLE_SSL_CONNECT_ERROR; } - switch(ssl_version_max) { - case CURL_SSLVERSION_MAX_NONE: + switch(conn_config->version_max) { case CURL_SSLVERSION_MAX_DEFAULT: - ssl_version_max = max_supported_version_by_os; + case CURL_SSLVERSION_MAX_NONE: + case CURL_SSLVERSION_MAX_TLSv1_3: + case CURL_SSLVERSION_MAX_TLSv1_2: + ver_max = kTLSProtocol12; + break; + case CURL_SSLVERSION_MAX_TLSv1_1: + ver_max = kTLSProtocol11; + break; + case CURL_SSLVERSION_MAX_TLSv1_0: + ver_max = kTLSProtocol1; break; + default: + failf(data, "SSL: unsupported maximum TLS version value"); + return CURLE_SSL_CONNECT_ERROR; } -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - if(&SSLSetProtocolVersionMax) { - SSLProtocol darwin_ver_min = kTLSProtocol1; - SSLProtocol darwin_ver_max = kTLSProtocol1; - CURLcode result = sectransp_version_from_curl(&darwin_ver_min, - ssl_version); - if(result) { - failf(data, "unsupported min version passed via CURLOPT_SSLVERSION"); - return result; - } - result = sectransp_version_from_curl(&darwin_ver_max, - ssl_version_max >> 16); - if(result) { - failf(data, "unsupported max version passed via CURLOPT_SSLVERSION"); - return result; - } - - (void)SSLSetProtocolVersionMin(backend->ssl_ctx, darwin_ver_min); - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, darwin_ver_max); - return result; + err = SSLSetProtocolVersionMin(backend->ssl_ctx, ver_min); + if(err != noErr) { + failf(data, "SSL: failed to set minimum TLS version"); + return CURLE_SSL_CONNECT_ERROR; } - else { -#if CURL_SUPPORT_MAC_10_8 - long i = ssl_version; - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocolAll, - false); - for(; i <= (ssl_version_max >> 16); i++) { - switch(i) { - case CURL_SSLVERSION_TLSv1_0: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol1, - true); - break; - case CURL_SSLVERSION_TLSv1_1: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol11, - true); - break; - case CURL_SSLVERSION_TLSv1_2: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol12, - true); - break; - case CURL_SSLVERSION_TLSv1_3: - failf(data, "Your version of the OS does not support TLSv1.3"); - return CURLE_SSL_CONNECT_ERROR; - } - } - return CURLE_OK; -#endif /* CURL_SUPPORT_MAC_10_8 */ + err = SSLSetProtocolVersionMax(backend->ssl_ctx, ver_max); + if(err != noErr) { + failf(data, "SSL: failed to set maximum TLS version"); + return CURLE_SSL_CONNECT_ERROR; } -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ - failf(data, "Secure Transport: cannot set SSL protocol"); - return CURLE_SSL_CONNECT_ERROR; + + return CURLE_OK; +#endif } static int sectransp_cipher_suite_get_str(uint16_t id, char *buf, @@ -1132,112 +1069,9 @@ static CURLcode sectransp_connect_step1(struct Curl_cfilter *cf, #endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ backend->ssl_write_buffered_length = 0UL; /* reset buffered write length */ - /* check to see if we have been told to use an explicit SSL/TLS version */ -#if CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS - if(&SSLSetProtocolVersionMax) { - switch(conn_config->version) { - case CURL_SSLVERSION_TLSv1: - (void)SSLSetProtocolVersionMin(backend->ssl_ctx, kTLSProtocol1); -#if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && \ - defined(HAVE_BUILTIN_AVAILABLE) - if(__builtin_available(macOS 10.13, iOS 11.0, *)) { - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol13); - } - else { - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12); - } -#else - (void)SSLSetProtocolVersionMax(backend->ssl_ctx, kTLSProtocol12); -#endif /* (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && - defined(HAVE_BUILTIN_AVAILABLE) */ - break; - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - case CURL_SSLVERSION_TLSv1_3: - result = sectransp_set_ssl_version_min_max(cf, data); - if(result != CURLE_OK) - return result; - break; - case CURL_SSLVERSION_SSLv3: - case CURL_SSLVERSION_SSLv2: - failf(data, "SSL versions not supported"); - return CURLE_NOT_BUILT_IN; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } - } - else { -#if CURL_SUPPORT_MAC_10_8 - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kSSLProtocolAll, - false); - switch(conn_config->version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol1, - true); - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol11, - true); - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol12, - true); - break; - case CURL_SSLVERSION_TLSv1_0: - case CURL_SSLVERSION_TLSv1_1: - case CURL_SSLVERSION_TLSv1_2: - case CURL_SSLVERSION_TLSv1_3: - result = sectransp_set_ssl_version_min_max(cf, data); - if(result != CURLE_OK) - return result; - break; - case CURL_SSLVERSION_SSLv3: - case CURL_SSLVERSION_SSLv2: - failf(data, "SSL versions not supported"); - return CURLE_NOT_BUILT_IN; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } -#endif /* CURL_SUPPORT_MAC_10_8 */ - } -#else - if(conn_config->version_max != CURL_SSLVERSION_MAX_NONE) { - failf(data, "Your version of the OS does not support to set maximum" - " SSL/TLS version"); - return CURLE_SSL_CONNECT_ERROR; - } - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, kSSLProtocolAll, false); - switch(conn_config->version) { - case CURL_SSLVERSION_DEFAULT: - case CURL_SSLVERSION_TLSv1: - case CURL_SSLVERSION_TLSv1_0: - (void)SSLSetProtocolVersionEnabled(backend->ssl_ctx, - kTLSProtocol1, - true); - break; - case CURL_SSLVERSION_TLSv1_1: - failf(data, "Your version of the OS does not support TLSv1.1"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_TLSv1_2: - failf(data, "Your version of the OS does not support TLSv1.2"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_TLSv1_3: - failf(data, "Your version of the OS does not support TLSv1.3"); - return CURLE_SSL_CONNECT_ERROR; - case CURL_SSLVERSION_SSLv2: - case CURL_SSLVERSION_SSLv3: - failf(data, "SSL versions not supported"); - return CURLE_NOT_BUILT_IN; - default: - failf(data, "Unrecognized parameter passed via CURLOPT_SSLVERSION"); - return CURLE_SSL_CONNECT_ERROR; - } -#endif /* CURL_BUILD_MAC_10_8 || CURL_BUILD_IOS */ + result = sectransp_set_ssl_version_min_max(data, backend, conn_config); + if(result != CURLE_OK) + return result; #if (CURL_BUILD_MAC_10_13 || CURL_BUILD_IOS_11) && \ defined(HAVE_BUILTIN_AVAILABLE) diff --git a/tests/http/test_10_proxy.py b/tests/http/test_10_proxy.py index dcc454e0d220c3..12c651cb0f9274 100644 --- a/tests/http/test_10_proxy.py +++ b/tests/http/test_10_proxy.py @@ -149,6 +149,8 @@ def test_10_05_proxytunnel_http(self, env: Env, httpd, proto, repeat): @pytest.mark.parametrize("tunnel", ['http/1.1', 'h2']) @pytest.mark.skipif(condition=not Env.have_nghttpx(), reason="no nghttpx available") def test_10_06_proxytunnel_https(self, env: Env, httpd, nghttpx_fwd, proto, tunnel, repeat): + if env.curl_uses_lib('SecureTransport') and tunnel == 'h2': + pytest.skip("TODO SecureTransport") if tunnel == 'h2' and not env.curl_uses_lib('nghttp2'): pytest.skip('only supported with nghttp2') curl = CurlClient(env=env) @@ -176,6 +178,8 @@ def test_10_06_proxytunnel_https(self, env: Env, httpd, nghttpx_fwd, proto, tunn @pytest.mark.skipif(condition=not Env.have_nghttpx(), reason="no nghttpx available") def test_10_07_pts_down_small(self, env: Env, httpd, nghttpx_fwd, proto, tunnel, fname, fcount, repeat): + if env.curl_uses_lib('SecureTransport') and tunnel == 'h2': + pytest.skip("TODO SecureTransport") if tunnel == 'h2' and not env.curl_uses_lib('nghttp2'): pytest.skip('only supported with nghttp2') count = fcount @@ -206,6 +210,8 @@ def test_10_07_pts_down_small(self, env: Env, httpd, nghttpx_fwd, proto, @pytest.mark.skipif(condition=not Env.have_nghttpx(), reason="no nghttpx available") def test_10_08_upload_seq_large(self, env: Env, httpd, nghttpx, proto, tunnel, fname, fcount, repeat): + if env.curl_uses_lib('SecureTransport') and tunnel == 'h2': + pytest.skip("TODO SecureTransport") if tunnel == 'h2' and not env.curl_uses_lib('nghttp2'): pytest.skip('only supported with nghttp2') count = fcount @@ -228,6 +234,8 @@ def test_10_08_upload_seq_large(self, env: Env, httpd, nghttpx, proto, @pytest.mark.parametrize("tunnel", ['http/1.1', 'h2']) @pytest.mark.skipif(condition=not Env.have_nghttpx(), reason="no nghttpx available") def test_10_09_reuse_ser(self, env: Env, httpd, nghttpx_fwd, tunnel, repeat): + if env.curl_uses_lib('SecureTransport') and tunnel == 'h2': + pytest.skip("TODO SecureTransport") if tunnel == 'h2' and not env.curl_uses_lib('nghttp2'): pytest.skip('only supported with nghttp2') curl = CurlClient(env=env) @@ -252,6 +260,8 @@ def test_10_09_reuse_ser(self, env: Env, httpd, nghttpx_fwd, tunnel, repeat): @pytest.mark.skipif(condition=not Env.have_nghttpx(), reason="no nghttpx available") def test_10_10_reuse_proxy(self, env: Env, httpd, nghttpx_fwd, tunnel, repeat): # url twice via https: proxy separated with '--next', will reuse + if env.curl_uses_lib('SecureTransport') and tunnel == 'h2': + pytest.skip("TODO SecureTransport") if tunnel == 'h2' and not env.curl_uses_lib('nghttp2'): pytest.skip('only supported with nghttp2') curl = CurlClient(env=env) diff --git a/tests/http/test_13_proxy_auth.py b/tests/http/test_13_proxy_auth.py index abeae0100e0a1f..9fcf1a363982c2 100644 --- a/tests/http/test_13_proxy_auth.py +++ b/tests/http/test_13_proxy_auth.py @@ -125,6 +125,8 @@ def test_13_06_tunnel_http_auth(self, env: Env, httpd, repeat): @pytest.mark.parametrize("proto", ['http/1.1', 'h2']) @pytest.mark.parametrize("tunnel", ['http/1.1', 'h2']) def test_13_07_tunnels_no_auth(self, env: Env, httpd, proto, tunnel, repeat): + if env.curl_uses_lib('SecureTransport') and tunnel == 'h2': + pytest.skip("TODO SecureTransport") if tunnel == 'h2' and not env.curl_uses_lib('nghttp2'): pytest.skip('only supported with nghttp2') curl = CurlClient(env=env) @@ -143,6 +145,8 @@ def test_13_07_tunnels_no_auth(self, env: Env, httpd, proto, tunnel, repeat): @pytest.mark.parametrize("proto", ['http/1.1', 'h2']) @pytest.mark.parametrize("tunnel", ['http/1.1', 'h2']) def test_13_08_tunnels_auth(self, env: Env, httpd, proto, tunnel, repeat): + if env.curl_uses_lib('SecureTransport') and tunnel == 'h2': + pytest.skip("TODO SecureTransport") if tunnel == 'h2' and not env.curl_uses_lib('nghttp2'): pytest.skip('only supported with nghttp2') curl = CurlClient(env=env) diff --git a/tests/http/test_17_ssl_use.py b/tests/http/test_17_ssl_use.py index c7dc2ad5f78de2..7ed338bf25d52a 100644 --- a/tests/http/test_17_ssl_use.py +++ b/tests/http/test_17_ssl_use.py @@ -78,6 +78,8 @@ def test_17_02_sslinfo_reconnect(self, env: Env, tls_max): exp_resumed = 'Initial' # 1.2 works in wolfSSL, but 1.3 does not, TODO if env.curl_uses_lib('rustls-ffi'): exp_resumed = 'Initial' # Rustls does not support sessions, TODO + if env.curl_uses_lib('SecureTransport') and tls_max == '1.3': + pytest.skip('SecureTransport does not support TLSv1.3') if env.curl_uses_lib('bearssl') and tls_max == '1.3': pytest.skip('BearSSL does not support TLSv1.3') if env.curl_uses_lib('mbedtls') and tls_max == '1.3': @@ -122,6 +124,8 @@ def test_17_03_trailing_dot(self, env: Env, proto): # use host name with double trailing dot, verify handshake @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) def test_17_04_double_dot(self, env: Env, proto): + if env.curl_uses_lib('SecureTransport'): + pytest.skip("TODO SecureTransport") if proto == 'h3' and not env.have_h3(): pytest.skip("h3 not supported") if proto == 'h3' and env.curl_uses_lib('wolfssl'): @@ -146,6 +150,8 @@ def test_17_04_double_dot(self, env: Env, proto): # use ip address for connect @pytest.mark.parametrize("proto", ['http/1.1', 'h2', 'h3']) def test_17_05_ip_addr(self, env: Env, proto): + if env.curl_uses_lib('SecureTransport'): + pytest.skip("TODO SecureTransport") if env.curl_uses_lib('bearssl'): pytest.skip("BearSSL does not support cert verification with IP addresses") if env.curl_uses_lib('mbedtls'): @@ -229,9 +235,11 @@ def test_17_07_ssl_ciphers(self, env: Env, httpd, tls_proto, ciphers13, ciphers1 if tls_proto == 'TLSv1.3': pytest.skip('BearSSL does not support TLSv1.3') tls_proto = 'TLSv1.2' - elif env.curl_uses_lib('sectransp'): # not in CI, so untested + elif env.curl_uses_lib('SecureTransport'): if tls_proto == 'TLSv1.3': pytest.skip('SecureTransport does not support TLSv1.3') + if ciphers12: + ciphers12 = [c.replace('CHACHA20-POLY1305', 'AES128-GCM-SHA256') for c in ciphers12] tls_proto = 'TLSv1.2' # test extra_args = ['--tls13-ciphers', ':'.join(ciphers13)] if ciphers13 else [] @@ -289,7 +297,7 @@ def test_17_09_ssl_min_max(self, env: Env, httpd, tls_proto, max_ver, min_ver): # SSL backend specifics if env.curl_uses_lib('bearssl'): supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', None] - elif env.curl_uses_lib('sectransp'): # not in CI, so untested + elif env.curl_uses_lib('SecureTransport'): supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', None] elif env.curl_uses_lib('gnutls'): supported = ['TLSv1', 'TLSv1.1', 'TLSv1.2', 'TLSv1.3'] diff --git a/tests/http/test_20_websockets.py b/tests/http/test_20_websockets.py index eb9df306b31c04..74128d24379e55 100644 --- a/tests/http/test_20_websockets.py +++ b/tests/http/test_20_websockets.py @@ -68,9 +68,8 @@ def ws_echo(self, env): self._rmrf(run_dir) self._mkpath(run_dir) - with open(err_file, 'w') as cerr: - cmd = os.path.join(env.project_dir, - 'tests/http/testenv/ws_echo_server.py') + with open(err_file, 'w+') as cerr: + cmd = os.path.normpath(f'{env.project_dir}/tests/http/testenv/ws_echo_server.py') args = [cmd, '--port', str(env.ws_port)] p = subprocess.Popen(args=args, cwd=run_dir, stderr=cerr, stdout=cerr) diff --git a/tests/http/testenv/client.py b/tests/http/testenv/client.py index 0a0030c75e3fdf..e5727533c42c03 100644 --- a/tests/http/testenv/client.py +++ b/tests/http/testenv/client.py @@ -48,7 +48,7 @@ def __init__(self, name: str, env: Env, run_dir: Optional[str] = None, timeout: Optional[float] = None, run_env: Optional[Dict[str,str]] = None): self.name = name - self.path = os.path.join(env.project_dir, f'tests/http/clients/{name}') + self.path = os.path.normpath(f'{env.build_dir}/tests/http/clients/{name}') self.env = env self._run_env = run_env self._timeout = timeout if timeout else env.test_timeout diff --git a/tests/http/testenv/env.py b/tests/http/testenv/env.py index 2cd6432364b304..cfb5678bd72ec0 100644 --- a/tests/http/testenv/env.py +++ b/tests/http/testenv/env.py @@ -52,22 +52,19 @@ def init_config_from(conf_path): return None -TESTS_HTTPD_PATH = os.path.dirname(os.path.dirname(__file__)) -DEF_CONFIG = init_config_from(os.path.join(TESTS_HTTPD_PATH, 'config.ini')) - -TOP_PATH = os.path.dirname(os.path.dirname(TESTS_HTTPD_PATH)) -CURL = os.path.join(TOP_PATH, 'src/curl') - - class EnvConfig: def __init__(self): - self.tests_dir = TESTS_HTTPD_PATH - self.gen_dir = os.path.join(self.tests_dir, 'gen') - self.project_dir = os.path.dirname(os.path.dirname(self.tests_dir)) - self.config = DEF_CONFIG - # check cur and its features - self.curl = CURL + project_dir = os.path.normpath(f'{os.path.dirname(__file__)}/../../../') + build_dir = project_dir + if 'BUILD_DIR' in os.environ: + build_dir = os.path.realpath(os.environ['BUILD_DIR']) + self.project_dir = project_dir + self.build_dir = build_dir + self.gen_dir = os.path.normpath(f'{build_dir}/tests/http/gen') + self.config = init_config_from(os.path.normpath(f'{build_dir}/tests/http/config.ini')) + # check curl and its features + self.curl = os.path.normpath(f'{build_dir}/src/curl') if 'CURL' in os.environ: self.curl = os.environ['CURL'] self.curl_props = { @@ -166,6 +163,7 @@ def __init__(self): log.debug(f'nghttpx -v: {p.stdout}') self.caddy = self.config['caddy']['caddy'] + print(f'CADDY: "{self.caddy}"') self._caddy_version = None if len(self.caddy.strip()) == 0: self.caddy = None @@ -173,6 +171,10 @@ def __init__(self): try: p = subprocess.run(args=[self.caddy, 'version'], capture_output=True, text=True) + print(f'CADDY {self.caddy} version') + print(f'stdout\n{p.stdout}') + print(f'stderr\n{p.stderr}') + print(f'ret {p.returncode}') if p.returncode != 0: # not a working caddy self.caddy = None @@ -181,15 +183,21 @@ def __init__(self): self._caddy_version = m.group(1) else: raise f'Unable to determine cadd version from: {p.stdout}' - except: + except Exception as e: + print(f'CADDY exception\n{e}') self.caddy = None self.vsftpd = self.config['vsftpd']['vsftpd'] + print(f'VSFTPD: "{self.vsftpd}"') self._vsftpd_version = None if self.vsftpd is not None: try: p = subprocess.run(args=[self.vsftpd, '-v'], capture_output=True, text=True) + print(f'VSFTPD {self.caddy} -v') + print(f'stdout\n{p.stdout}') + print(f'stderr\n{p.stderr}') + print(f'ret {p.returncode}') if p.returncode != 0: # not a working vsftpd self.vsftpd = None @@ -202,6 +210,7 @@ def __init__(self): else: raise Exception(f'Unable to determine VsFTPD version from: {p.stderr}') except Exception as e: + print(f'VSFTPD exception\n{e}') self.vsftpd = None self._tcpdump = shutil.which('tcpdump') @@ -439,6 +448,10 @@ def gen_dir(self) -> str: def project_dir(self) -> str: return self.CONFIG.project_dir + @property + def build_dir(self) -> str: + return self.CONFIG.build_dir + @property def ca(self): return self._ca @@ -575,7 +588,7 @@ def make_data_file(self, indir: str, fname: str, fsize: int) -> str: return fpath def make_clients(self): - client_dir = os.path.join(self.project_dir, 'tests/http/clients') + client_dir = os.path.normpath(f'{self.build_dir}/tests/http/clients/') p = subprocess.run(['make'], capture_output=True, text=True, cwd=client_dir) if p.returncode != 0: diff --git a/tests/http/testenv/httpd.py b/tests/http/testenv/httpd.py index 8cc2c34a5f1f08..68aeb02529b7da 100644 --- a/tests/http/testenv/httpd.py +++ b/tests/http/testenv/httpd.py @@ -149,6 +149,14 @@ def start(self): fd.write('start of server\n') with open(os.path.join(self._apache_dir, 'xxx'), 'a') as fd: fd.write('start of server\n') +# r = self._run(args=[self.env.apachectl, "-d", self._apache_dir, "-f", self._conf_file, "-t"]) +# print('******************************************************************************************************') +# print('APACHE CONFIG TEST') +# print('******************************************************************************************************') +# print(r.stderr) +# print('******************************************************************************************************') +# print(r.stdout) +# print('******************************************************************************************************') r = self._apachectl('start') if r.exit_code != 0: log.error(f'failed to start httpd: {r}') @@ -252,6 +260,7 @@ def _write_config(self): fd.write(f'LoadModule curltest_module \"{Httpd.MOD_CURLTEST}\"\n') conf = [ # base server config f'ServerRoot "{self._apache_dir}"', + f'ServerName localhost', f'DefaultRuntimeDir logs', f'PidFile httpd.pid', f'ErrorLog {self._error_log}', @@ -376,7 +385,6 @@ def _write_config(self): f'', f'', ]) - fd.write("\n".join(conf)) with open(os.path.join(self._conf_dir, 'mime.types'), 'w') as fd: fd.write("\n".join([ @@ -461,13 +469,12 @@ def _curltest_conf(self, servername) -> List[str]: def _init_curltest(self): if Httpd.MOD_CURLTEST is not None: return - local_dir = os.path.dirname(inspect.getfile(Httpd)) + # TODO should this be based self.env.build_dir ? + mod_dir = os.path.normpath(f'{os.path.dirname(__file__)}/mod_curltest/') p = subprocess.run([self.env.apxs, '-c', 'mod_curltest.c'], - capture_output=True, - cwd=os.path.join(local_dir, 'mod_curltest')) + capture_output=True, cwd=mod_dir) rv = p.returncode if rv != 0: log.error(f"compiling mod_curltest failed: {p.stderr}") raise Exception(f"compiling mod_curltest failed: {p.stderr}") - Httpd.MOD_CURLTEST = os.path.join( - local_dir, 'mod_curltest/.libs/mod_curltest.so') + Httpd.MOD_CURLTEST = os.path.normpath(f'{mod_dir}/.libs/mod_curltest.so')