From e8dd5526962b5d517bea8bdcc4c9813b9c507395 Mon Sep 17 00:00:00 2001 From: Tobias Taschner Date: Mon, 18 Jan 2021 18:10:36 +0100 Subject: [PATCH 1/6] Add webrequest sample to documentation Co-authored-by: PB --- docs/doxygen/mainpages/samples.h | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/docs/doxygen/mainpages/samples.h b/docs/doxygen/mainpages/samples.h index f7d7fd1b2e..81eaf04106 100644 --- a/docs/doxygen/mainpages/samples.h +++ b/docs/doxygen/mainpages/samples.h @@ -902,6 +902,15 @@ archives. @sampledir{webview} +@section page_samples_webrequest Web Request Sample + +This sample demonstrates the various capabilities of the +wxWebRequest class. It shows how to handle simple text HTTP and HTTPS requests, +downloading files, showing download progress and processing downloaded +data while it's being downloaded. + +@sampledir{webrequest} + @section page_samples_widgets Widgets Sample The widgets sample is the main presentation program for most simple and advanced @@ -962,4 +971,3 @@ other resources. From its menu or toolbar you can then run the following dialogs @sampledir{xrc} */ - From bf1b0716e00ff0bc7e45ba1d8c43a2837e672f88 Mon Sep 17 00:00:00 2001 From: Tobias Taschner Date: Mon, 18 Jan 2021 18:20:12 +0100 Subject: [PATCH 2/6] Add a note to use wxWebRequest in wxHTTP docs --- interface/wx/protocol/http.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/interface/wx/protocol/http.h b/interface/wx/protocol/http.h index 07295dde44..00ac194470 100644 --- a/interface/wx/protocol/http.h +++ b/interface/wx/protocol/http.h @@ -12,6 +12,9 @@ wxHTTP can thus be used to create a (basic) HTTP @b client. + @note If you want HTTPS, IPv6, Proxy detection, authentication, etc. + support consider using wxWebRequest instead. + @library{wxnet} @category{net} From 036b7f29a7f6f486ac8a86371a6ac64eac6bd83b Mon Sep 17 00:00:00 2001 From: Tobias Taschner Date: Tue, 19 Jan 2021 12:04:36 +0100 Subject: [PATCH 3/6] Add wxWebRequest::DisablePeerVerify() This method allows insecure HTTPS connections when required --- include/wx/private/webrequest.h | 5 +++++ include/wx/webrequest.h | 4 ++++ interface/wx/webrequest.h | 16 ++++++++++++++++ src/common/webrequest.cpp | 13 +++++++++++++ src/common/webrequest_curl.cpp | 3 +++ src/msw/webrequest_winhttp.cpp | 10 ++++++++++ src/osx/webrequest_urlsession.mm | 6 ++++++ tests/net/webrequest.cpp | 21 +++++++++++++++++++++ 8 files changed, 78 insertions(+) diff --git a/include/wx/private/webrequest.h b/include/wx/private/webrequest.h index b68c9c8b79..42ebf9c51e 100644 --- a/include/wx/private/webrequest.h +++ b/include/wx/private/webrequest.h @@ -96,6 +96,10 @@ public: virtual wxWebRequestHandle GetNativeHandle() const = 0; + void DisablePeerVerify(bool disable) { m_peerVerifyDisabled = disable; } + + bool IsPeerVerifyDisabled() { return m_peerVerifyDisabled; } + void SetState(wxWebRequest::State state, const wxString& failMsg = wxString()); void ReportDataReceived(size_t sizeReceived); @@ -110,6 +114,7 @@ protected: wxWebRequestHeaderMap m_headers; wxFileOffset m_dataSize; wxScopedPtr m_dataStream; + bool m_peerVerifyDisabled; wxWebRequestImpl(wxWebSession& session, wxWebSessionImpl& sessionImpl, diff --git a/include/wx/webrequest.h b/include/wx/webrequest.h index ffeabf7036..72034764a2 100644 --- a/include/wx/webrequest.h +++ b/include/wx/webrequest.h @@ -188,6 +188,10 @@ public: wxWebRequestHandle GetNativeHandle() const; + void DisablePeerVerify(bool disable = true); + + bool IsPeerVerifyDisabled(); + private: // Ctor is only used by wxWebSession. friend class wxWebSession; diff --git a/interface/wx/webrequest.h b/interface/wx/webrequest.h index 79ed1ac312..bf6b9f1168 100644 --- a/interface/wx/webrequest.h +++ b/interface/wx/webrequest.h @@ -391,6 +391,22 @@ public: server. */ void SetStorage(Storage storage); + + /** + Disable SSL certificate verification. + + This can be used to connect to self signed servers or other invalid + SSL connections. Disabling verification makes the communication + insecure. + */ + void DisablePeerVerify(bool disable = true); + + /** + Returns if peer verification has been disabled. + + @see DisablePeerVerify() + */ + bool IsPeerVerifyDisabled(); ///@} /** @name Progress methods diff --git a/src/common/webrequest.cpp b/src/common/webrequest.cpp index 50cae4b05f..e56e844239 100644 --- a/src/common/webrequest.cpp +++ b/src/common/webrequest.cpp @@ -62,6 +62,7 @@ wxWebRequestImpl::wxWebRequestImpl(wxWebSession& session, : m_storage(wxWebRequest::Storage_Memory), m_headers(sessionImpl.GetHeaders()), m_dataSize(0), + m_peerVerifyDisabled(false), m_session(session), m_handler(handler), m_id(id), @@ -516,6 +517,18 @@ wxWebRequestHandle wxWebRequest::GetNativeHandle() const return m_impl ? m_impl->GetNativeHandle() : NULL; } +void wxWebRequest::DisablePeerVerify(bool disable) +{ + m_impl->DisablePeerVerify(disable); +} + +bool wxWebRequest::IsPeerVerifyDisabled() +{ + return m_impl->IsPeerVerifyDisabled(); +} + + + // // wxWebAuthChallenge diff --git a/src/common/webrequest_curl.cpp b/src/common/webrequest_curl.cpp index 47264ff12b..e24d9300ed 100644 --- a/src/common/webrequest_curl.cpp +++ b/src/common/webrequest_curl.cpp @@ -247,6 +247,9 @@ void wxWebRequestCURL::Start() } curl_easy_setopt(m_handle, CURLOPT_HTTPHEADER, m_headerList); + if ( IsPeerVerifyDisabled() ) + curl_easy_setopt(m_handle, CURLOPT_SSL_VERIFYPEER, 0); + StartRequest(); } diff --git a/src/msw/webrequest_winhttp.cpp b/src/msw/webrequest_winhttp.cpp index 2a46cdf2d4..7c087a833b 100644 --- a/src/msw/webrequest_winhttp.cpp +++ b/src/msw/webrequest_winhttp.cpp @@ -364,6 +364,16 @@ void wxWebRequestWinHTTP::Start() return; } + if ( IsPeerVerifyDisabled() ) + { + wxWinHTTPSetOption(m_request, WINHTTP_OPTION_SECURITY_FLAGS, + SECURITY_FLAG_IGNORE_CERT_CN_INVALID | + SECURITY_FLAG_IGNORE_CERT_DATE_INVALID | + SECURITY_FLAG_IGNORE_UNKNOWN_CA | + SECURITY_FLAG_IGNORE_CERT_WRONG_USAGE + ); + } + SendRequest(); } diff --git a/src/osx/webrequest_urlsession.mm b/src/osx/webrequest_urlsession.mm index 43b1dcdcee..f522d41391 100644 --- a/src/osx/webrequest_urlsession.mm +++ b/src/osx/webrequest_urlsession.mm @@ -150,6 +150,12 @@ *request )); } + else if ( authMethod == NSURLAuthenticationMethodServerTrust ) + { + if (request->IsPeerVerifyDisabled()) + completionHandler(NSURLSessionAuthChallengeUseCredential, + [NSURLCredential credentialForTrust:challenge.protectionSpace.serverTrust]); + } completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil); } diff --git a/tests/net/webrequest.cpp b/tests/net/webrequest.cpp index 64cf7afcab..974a0d3b93 100644 --- a/tests/net/webrequest.cpp +++ b/tests/net/webrequest.cpp @@ -262,6 +262,27 @@ TEST_CASE_METHOD(RequestFixture, Run(wxWebRequest::State_Failed, 0); } +TEST_CASE_METHOD(RequestFixture, + "WebRequest::SSL::Error", "[net][webrequest][error]") +{ + if (!InitBaseURL()) + return; + + CreateAbs("https://self-signed.badssl.com/"); + Run(wxWebRequest::State_Failed, 0); +} + +TEST_CASE_METHOD(RequestFixture, + "WebRequest::SSL::Ignore", "[net][webrequest]") +{ + if (!InitBaseURL()) + return; + + CreateAbs("https://self-signed.badssl.com/"); + request.DisablePeerVerify(); + Run(wxWebRequest::State_Completed, 200); +} + TEST_CASE_METHOD(RequestFixture, "WebRequest::Post", "[net][webrequest]") { From d66b70f22462574b09db2b68a27ac9b88d1797b0 Mon Sep 17 00:00:00 2001 From: Tobias Taschner Date: Tue, 19 Jan 2021 15:20:09 +0100 Subject: [PATCH 4/6] Add a description of Apple Transport Security to wxWebRequest doc --- interface/wx/webrequest.h | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/interface/wx/webrequest.h b/interface/wx/webrequest.h index bf6b9f1168..d17aa13d82 100644 --- a/interface/wx/webrequest.h +++ b/interface/wx/webrequest.h @@ -61,6 +61,14 @@ request.Start(); @endcode + @section apple_http macOS and iOS App Transport Security + + Starting with macOS 10.11 and iOS 9 an application cannot create unsecure + connections (this includes HTTP and unverified HTTPS). You have to include + additional fields in your Info.plist to enable such connections. + For further details see the documentation on NSAppTransportSecurity + here + @section descriptions Implementation Descriptions The following APIs are used per platform, additional details From 457b213315e55a5f7d32089f431722bef46ec619 Mon Sep 17 00:00:00 2001 From: Tobias Taschner Date: Tue, 19 Jan 2021 19:42:55 +0100 Subject: [PATCH 5/6] Apply suggestions from code review Co-authored-by: VZ --- include/wx/private/webrequest.h | 2 +- include/wx/webrequest.h | 2 +- interface/wx/protocol/http.h | 5 ++--- interface/wx/webrequest.h | 2 +- src/common/webrequest.cpp | 2 +- 5 files changed, 6 insertions(+), 7 deletions(-) diff --git a/include/wx/private/webrequest.h b/include/wx/private/webrequest.h index 42ebf9c51e..0812304fac 100644 --- a/include/wx/private/webrequest.h +++ b/include/wx/private/webrequest.h @@ -98,7 +98,7 @@ public: void DisablePeerVerify(bool disable) { m_peerVerifyDisabled = disable; } - bool IsPeerVerifyDisabled() { return m_peerVerifyDisabled; } + bool IsPeerVerifyDisabled() const { return m_peerVerifyDisabled; } void SetState(wxWebRequest::State state, const wxString& failMsg = wxString()); diff --git a/include/wx/webrequest.h b/include/wx/webrequest.h index 72034764a2..349c0372a9 100644 --- a/include/wx/webrequest.h +++ b/include/wx/webrequest.h @@ -190,7 +190,7 @@ public: void DisablePeerVerify(bool disable = true); - bool IsPeerVerifyDisabled(); + bool IsPeerVerifyDisabled() const; private: // Ctor is only used by wxWebSession. diff --git a/interface/wx/protocol/http.h b/interface/wx/protocol/http.h index 00ac194470..e5ba4d5962 100644 --- a/interface/wx/protocol/http.h +++ b/interface/wx/protocol/http.h @@ -12,8 +12,8 @@ wxHTTP can thus be used to create a (basic) HTTP @b client. - @note If you want HTTPS, IPv6, Proxy detection, authentication, etc. - support consider using wxWebRequest instead. + @note In practice, for any but the most trivial cases, e.g. if you need HTTPS, HTTP/2 or IPv6, + proxy detection, authentication, etc. support please use wxWebRequest instead. @library{wxnet} @category{net} @@ -176,4 +176,3 @@ public: const wxString& data, const wxMBConv& conv = wxConvUTF8); }; - diff --git a/interface/wx/webrequest.h b/interface/wx/webrequest.h index d17aa13d82..98713392d8 100644 --- a/interface/wx/webrequest.h +++ b/interface/wx/webrequest.h @@ -414,7 +414,7 @@ public: @see DisablePeerVerify() */ - bool IsPeerVerifyDisabled(); + bool IsPeerVerifyDisabled() const; ///@} /** @name Progress methods diff --git a/src/common/webrequest.cpp b/src/common/webrequest.cpp index e56e844239..351a4b76ae 100644 --- a/src/common/webrequest.cpp +++ b/src/common/webrequest.cpp @@ -522,7 +522,7 @@ void wxWebRequest::DisablePeerVerify(bool disable) m_impl->DisablePeerVerify(disable); } -bool wxWebRequest::IsPeerVerifyDisabled() +bool wxWebRequest::IsPeerVerifyDisabled() const { return m_impl->IsPeerVerifyDisabled(); } From 47276935843c5e965aab7b44c8cbf4400e6418d7 Mon Sep 17 00:00:00 2001 From: Tobias Taschner Date: Tue, 19 Jan 2021 21:08:01 +0100 Subject: [PATCH 6/6] Silence harmless warning with wxWebWebRequest CURL --- src/common/webrequest_curl.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/webrequest_curl.cpp b/src/common/webrequest_curl.cpp index e24d9300ed..e9e2a135f3 100644 --- a/src/common/webrequest_curl.cpp +++ b/src/common/webrequest_curl.cpp @@ -471,7 +471,7 @@ wxThread::ExitCode wxWebSessionCURL::Entry() { // Handle cancelled requests { - wxCriticalSectionLocker lock(m_cancelled.cs); + wxCriticalSectionLocker cancelledLock(m_cancelled.cs); while ( !m_cancelled.requests.empty() ) { wxObjectDataPtr request(m_cancelled.requests.back());