diff --git a/sdk/core/azure-core/CHANGELOG.md b/sdk/core/azure-core/CHANGELOG.md index cf790f7ee..e83562afe 100644 --- a/sdk/core/azure-core/CHANGELOG.md +++ b/sdk/core/azure-core/CHANGELOG.md @@ -5,6 +5,7 @@ ### Features Added - When a `RequestFailedException` exception is thrown, the `what()` method now includes information about the HTTP request which failed. +- Adding option `WinHttpTransportOptions.IgnoreUnknownServerCert`. It can be used to disable verifying server certificate for the `WinHttpTransport`. ### Other Changes diff --git a/sdk/core/azure-core/inc/azure/core/http/win_http_transport.hpp b/sdk/core/azure-core/inc/azure/core/http/win_http_transport.hpp index abb03da0d..07375fbda 100644 --- a/sdk/core/azure-core/inc/azure/core/http/win_http_transport.hpp +++ b/sdk/core/azure-core/inc/azure/core/http/win_http_transport.hpp @@ -128,7 +128,11 @@ namespace Azure { namespace Core { namespace Http { */ struct WinHttpTransportOptions final { - // Empty struct reserved for future options. + /** + * @brief When `true`, allows an invalid certificate authority. If this flag is set, the + * application does not receive a WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA callback. + */ + bool IgnoreUnknownServerCert = false; }; /** diff --git a/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp b/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp index 8c26b0ca7..ffeff1787 100644 --- a/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp +++ b/sdk/core/azure-core/src/http/winhttp/win_http_transport.cpp @@ -347,6 +347,16 @@ void WinHttpTransport::CreateRequestHandle(std::unique_ptr<_detail::HandleManage GetErrorAndThrow("Error while setting client cert context to ignore.."); } } + + if (m_options.IgnoreUnknownServerCert) + { + auto option = SECURITY_FLAG_IGNORE_UNKNOWN_CA; + if (!WinHttpSetOption( + handleManager->m_requestHandle, WINHTTP_OPTION_SECURITY_FLAGS, &option, sizeof(option))) + { + GetErrorAndThrow("Error while setting ignore unknown server certificate.."); + } + } } // For PUT/POST requests, send additional data using WinHttpWriteData. diff --git a/sdk/core/perf/inc/azure/perf/base_test.hpp b/sdk/core/perf/inc/azure/perf/base_test.hpp index 42e8ce8c3..18a0e9ee9 100644 --- a/sdk/core/perf/inc/azure/perf/base_test.hpp +++ b/sdk/core/perf/inc/azure/perf/base_test.hpp @@ -38,9 +38,31 @@ namespace Azure { namespace Perf { std::string m_recordId; std::string m_proxy; bool m_isPlayBackMode = false; + bool m_isInsecureEnabled = false; + /** + * @brief Updates the performance test to use a test-proxy for running. + * + * @note A tes-proxy is not a general proxy in the middle of the test and a server. This is an + * SDK specific tool https://github.com/Azure/azure-sdk-tools/tree/main/tools/test-proxy that + * provides record and playback features to a performance test. Do not use a general purpose + * proxy for the test. + * + * @param proxy A test-proxy server url. + */ void SetTestProxy(std::string const& proxy) { m_proxy = proxy; } + /** + * @brief Set the performance test to run insecure. + * + * @details Running insecure means that for an SSL connection, the server certificate won't be + * validated to be a known certificate. Use this to stablish conversation with Https servers + * using self-signed certificates. + * + * @param value Boolean value use to set the insecure mode ON of OFF. + */ + void AllowInsecureConnections(bool value) { m_isInsecureEnabled = value; } + /** * @brief Define actions to run after test set up and before the actual test. * @@ -59,12 +81,7 @@ namespace Azure { namespace Perf { */ void PreCleanUp(); - /** - * @brief Set the client options depending on the test options. - * - * @param clientOptions ref to the client options that contains the http pipeline policies. - */ - void ConfigureCoreClientOptions(Azure::Core::_internal::ClientOptions* clientOptions); + void ConfigureInsecureConnection(Azure::Core::_internal::ClientOptions& clientOptions); protected: Azure::Perf::TestOptions m_options; @@ -127,17 +144,11 @@ namespace Azure { namespace Perf { virtual void GlobalCleanup() {} /** - * @brief Update an existing \p clientOptions with the test configuration set by the - * environment. + * @brief Set the client options depending on the test options. * - * @note If test proxy env var is set, the proxy policy is added to the \p clientOptions. - * - * @param clientOptions Ref to the client options that contains the Http client policies. + * @param clientOptions ref to the client options that contains the http pipeline policies. */ - template void ConfigureClientOptions(T* clientOptions) - { - ConfigureCoreClientOptions(clientOptions); - } + void ConfigureClientOptions(Azure::Core::_internal::ClientOptions& clientOptions); /** * @brief Create and return client options with test configuration set in the environment. @@ -147,7 +158,7 @@ namespace Azure { namespace Perf { template T InitClientOptions() { T options; - ConfigureClientOptions(&options); + ConfigureClientOptions(options); return options; } }; diff --git a/sdk/core/perf/src/arg_parser.cpp b/sdk/core/perf/src/arg_parser.cpp index e75f76614..5080128fb 100644 --- a/sdk/core/perf/src/arg_parser.cpp +++ b/sdk/core/perf/src/arg_parser.cpp @@ -60,7 +60,7 @@ Azure::Perf::GlobalTestOptions Azure::Perf::Program::ArgParser::Parse( } if (parsedArgs["Insecure"]) { - options.Insecure = parsedArgs["Insecure"].as(); + options.Insecure = true; } if (parsedArgs["Iterations"]) { diff --git a/sdk/core/perf/src/base_test.cpp b/sdk/core/perf/src/base_test.cpp index eae539906..09195d2cc 100644 --- a/sdk/core/perf/src/base_test.cpp +++ b/sdk/core/perf/src/base_test.cpp @@ -2,8 +2,15 @@ // SPDX-License-Identifier: MIT #include "azure/perf/base_test.hpp" -#include "azure/core/http/policies/policy.hpp" -#include "azure/core/internal/http/pipeline.hpp" + +#if defined(BUILD_CURL_HTTP_TRANSPORT_ADAPTER) +#include +#endif +#if defined(BUILD_TRANSPORT_WINHTTP_ADAPTER) +#include +#endif +#include +#include #include #include @@ -96,12 +103,36 @@ public: namespace Azure { namespace Perf { - void BaseTest::ConfigureCoreClientOptions(Azure::Core::_internal::ClientOptions* clientOptions) + void BaseTest::ConfigureInsecureConnection(Azure::Core::_internal::ClientOptions& clientOptions) + { + // NOTE: perf-fm is injecting the SSL config and transport here for the client options + // If the test overrides the options/transport, this can be undone. +#if defined(BUILD_CURL_HTTP_TRANSPORT_ADAPTER) + if (m_isInsecureEnabled) + { + Azure::Core::Http::CurlTransportOptions curlOptions; + curlOptions.SslVerifyPeer = false; + clientOptions.Transport.Transport + = std::make_shared(curlOptions); + } +#elif defined(BUILD_TRANSPORT_WINHTTP_ADAPTER) + Azure::Core::Http::WinHttpTransportOptions winHttpOptions; + winHttpOptions.IgnoreUnknownServerCert = true; + clientOptions.Transport.Transport + = std::make_shared(winHttpOptions); +#else + // avoid the variable not used warning + (void)clientOptions; +#endif + } + + void BaseTest::ConfigureClientOptions(Azure::Core::_internal::ClientOptions& clientOptions) { if (!m_proxy.empty()) { - clientOptions->PerRetryPolicies.push_back(std::make_unique(this)); + clientOptions.PerRetryPolicies.push_back(std::make_unique(this)); } + ConfigureInsecureConnection(clientOptions); } void BaseTest::PostSetUp() @@ -111,6 +142,7 @@ namespace Azure { namespace Perf { { Azure::Core::_internal::ClientOptions clientOp; clientOp.Retry.MaxRetries = 0; + ConfigureInsecureConnection(clientOp); std::vector> policiesOp; std::vector> policiesRe; Azure::Core::Http::_internal::HttpPipeline pipeline( @@ -180,6 +212,7 @@ namespace Azure { namespace Perf { { Azure::Core::_internal::ClientOptions clientOp; clientOp.Retry.MaxRetries = 0; + ConfigureInsecureConnection(clientOp); std::vector> policiesOp; std::vector> policiesRe; Azure::Core::Http::_internal::HttpPipeline pipeline( diff --git a/sdk/core/perf/src/options.cpp b/sdk/core/perf/src/options.cpp index b0b35c004..ad404fe20 100644 --- a/sdk/core/perf/src/options.cpp +++ b/sdk/core/perf/src/options.cpp @@ -66,7 +66,7 @@ std::vector Azure::Perf::GlobalTestOptions::GetOptionMe "Duration of the test in seconds. Default to 10 seconds.", 1}, {"Host", {"--host"}, "Host to redirect HTTP requests. No redirection by default.", 1}, - {"Insecure", {"--insecure"}, "Allow untrusted SSL certs. Default to false.", 1}, + {"Insecure", {"--insecure"}, "Allow untrusted SSL certs. Default to false.", 0}, {"Iterations", {"-i", "--iterations"}, "Number of iterations of main test loop. Default to 1.", diff --git a/sdk/core/perf/src/program.cpp b/sdk/core/perf/src/program.cpp index a634fb58b..e56af9027 100644 --- a/sdk/core/perf/src/program.cpp +++ b/sdk/core/perf/src/program.cpp @@ -320,6 +320,10 @@ void Azure::Perf::Program::Run( // Take the corresponding proxy from the list in round robin parallelTest[i]->SetTestProxy(options.TestProxies[i % options.TestProxies.size()]); } + if (options.Insecure) + { + parallelTest[i]->AllowInsecureConnections(true); + } } /******************** Global Set up ******************************/