Changeset 220583 in webkit
- Timestamp:
- Aug 11, 2017 3:06:12 AM (7 years ago)
- Location:
- trunk
- Files:
-
- 7 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/WebCore/ChangeLog
r220577 r220583 1 2017-08-11 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [Soup] Cannot access HTTPS sites using a HTTP proxy that requires authentication 4 https://bugs.webkit.org/show_bug.cgi?id=175378 5 6 Reviewed by Sergio Villar Senin. 7 8 Bring back part of the code removed in r206732, to keep a reference to the SoupMessage in the 9 AuthenticationChallenge since it can be different to the resource message. 10 11 * platform/network/soup/AuthenticationChallenge.h: 12 (WebCore::AuthenticationChallenge::AuthenticationChallenge): Deleted. 13 (WebCore::AuthenticationChallenge::authenticationClient const): Deleted. 14 (WebCore::AuthenticationChallenge::soupAuth const): Deleted. 15 (WebCore::AuthenticationChallenge::setProposedCredential): Deleted. 16 * platform/network/soup/AuthenticationChallengeSoup.cpp: 17 (WebCore::AuthenticationChallenge::AuthenticationChallenge): 18 (WebCore::AuthenticationChallenge::platformCompare): 19 1 20 2017-08-10 Dan Bernstein <mitz@apple.com> 2 21 -
trunk/Source/WebCore/platform/network/soup/AuthenticationChallenge.h
r206732 r220583 23 23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 24 */ 25 #ifndef AuthenticationChallenge_h 26 # define AuthenticationChallenge_h25 26 #pragma once 27 27 28 28 #include "AuthenticationChallengeBase.h" … … 34 34 namespace WebCore { 35 35 36 class AuthenticationChallenge : public AuthenticationChallengeBase {36 class AuthenticationChallenge final : public AuthenticationChallengeBase { 37 37 public: 38 38 AuthenticationChallenge() … … 47 47 AuthenticationChallenge(SoupMessage*, SoupAuth*, bool retrying, AuthenticationClient* = nullptr); 48 48 AuthenticationClient* authenticationClient() const { return m_authenticationClient.get(); } 49 SoupMessage* soupMessage() const { return m_soupMessage.get(); } 49 50 SoupAuth* soupAuth() const { return m_soupAuth.get(); } 50 51 void setProposedCredential(const Credential& credential) { m_proposedCredential = credential; } … … 54 55 static bool platformCompare(const AuthenticationChallenge&, const AuthenticationChallenge&); 55 56 57 GRefPtr<SoupMessage> m_soupMessage; 56 58 GRefPtr<SoupAuth> m_soupAuth; 57 59 RefPtr<AuthenticationClient> m_authenticationClient; 58 60 }; 59 61 60 } 62 } // namespace WebCore 61 63 62 #endif -
trunk/Source/WebCore/platform/network/soup/AuthenticationChallengeSoup.cpp
r206732 r220583 73 73 soupMessage, // failureResponse 74 74 ResourceError::authenticationError(soupMessage)) 75 , m_soupMessage(soupMessage) 75 76 , m_soupAuth(soupAuth) 76 77 , m_authenticationClient(client) … … 80 81 bool AuthenticationChallenge::platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b) 81 82 { 82 return a.soup Auth() == b.soupAuth();83 return a.soupMessage() == b.soupMessage() && a.soupAuth() == b.soupAuth(); 83 84 } 84 85 -
trunk/Source/WebKit/ChangeLog
r220581 r220583 1 2017-08-11 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [Soup] Cannot access HTTPS sites using a HTTP proxy that requires authentication 4 https://bugs.webkit.org/show_bug.cgi?id=175378 5 6 Reviewed by Sergio Villar Senin. 7 8 In case of HTTPS resource with a proxy, libsoup uses a tunnel internally, that uses its own SoupMessage during 9 the proxy authentication. We were ignoring authentication requests for other messages. 10 11 * NetworkProcess/soup/NetworkDataTaskSoup.cpp: 12 (WebKit::NetworkDataTaskSoup::authenticateCallback): Only return early if the message does't match and it's not 13 HTTPS resource over a proxy. 14 (WebKit::NetworkDataTaskSoup::authenticate): Use the soup message from the authentication challenge. 15 (WebKit::NetworkDataTaskSoup::continueAuthenticate): Ditto. 16 1 17 2017-08-10 Carlos Garcia Campos <cgarcia@igalia.com> 2 18 -
trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp
r219954 r220583 446 446 { 447 447 ASSERT(session == static_cast<NetworkSessionSoup&>(task->m_session.get()).soupSession()); 448 if (soupMessage != task->m_soupMessage.get()) 448 449 // We don't return early here in case the given soupMessage is different to m_soupMessage when 450 // it's proxy authentication and the request URL is HTTPS, because in that case libsoup uses a 451 // tunnel internally and the SoupMessage used for the authentication is the tunneling one. 452 // See https://bugs.webkit.org/show_bug.cgi?id=175378. 453 if (soupMessage != task->m_soupMessage.get() && (soupMessage->status_code != SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED || !task->m_currentRequest.url().protocolIs("https"))) 449 454 return; 450 455 … … 488 493 } 489 494 490 soup_session_pause_message(static_cast<NetworkSessionSoup&>(m_session.get()).soupSession(), m_soupMessage.get());495 soup_session_pause_message(static_cast<NetworkSessionSoup&>(m_session.get()).soupSession(), challenge.soupMessage()); 491 496 492 497 // We could also do this before we even start the request, but that would be at the expense … … 542 547 } 543 548 544 soup_session_unpause_message(static_cast<NetworkSessionSoup&>(m_session.get()).soupSession(), m_soupMessage.get());549 soup_session_unpause_message(static_cast<NetworkSessionSoup&>(m_session.get()).soupSession(), challenge.soupMessage()); 545 550 }); 546 551 } -
trunk/Tools/ChangeLog
r220582 r220583 1 2017-08-11 Carlos Garcia Campos <cgarcia@igalia.com> 2 3 [Soup] Cannot access HTTPS sites using a HTTP proxy that requires authentication 4 https://bugs.webkit.org/show_bug.cgi?id=175378 5 6 Reviewed by Sergio Villar Senin. 7 8 Add two test cases to check proxy authentication. 9 10 * TestWebKitAPI/Tests/WebKitGLib/TestAuthentication.cpp: 11 (Tunnel::Tunnel): 12 (Tunnel::~Tunnel): 13 (Tunnel::connect): 14 (Tunnel::connected): 15 (serverCallback): 16 (ProxyAuthenticationTest::ProxyAuthenticationTest): 17 (ProxyAuthenticationTest::~ProxyAuthenticationTest): 18 (ProxyAuthenticationTest::proxyServerPortAsString): 19 (testWebViewAuthenticationProxy): 20 (testWebViewAuthenticationProxyHTTPS): 21 (beforeAll): 22 1 23 2017-08-11 Xabier Rodriguez Calvar <calvaris@igalia.com> 2 24 -
trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestAuthentication.cpp
r218685 r220583 253 253 } 254 254 255 static void serverCallback(SoupServer*, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, void*) 256 { 255 class Tunnel { 256 public: 257 Tunnel(SoupServer* server, SoupMessage* message) 258 : m_server(server) 259 , m_message(message) 260 { 261 soup_server_pause_message(m_server.get(), m_message.get()); 262 } 263 264 ~Tunnel() 265 { 266 soup_server_unpause_message(m_server.get(), m_message.get()); 267 } 268 269 void connect(Function<void (const char*)>&& completionHandler) 270 { 271 m_completionHandler = WTFMove(completionHandler); 272 GRefPtr<GSocketClient> client = adoptGRef(g_socket_client_new()); 273 auto* uri = soup_message_get_uri(m_message.get()); 274 g_socket_client_connect_to_host_async(client.get(), uri->host, uri->port, nullptr, [](GObject* source, GAsyncResult* result, gpointer userData) { 275 auto* tunnel = static_cast<Tunnel*>(userData); 276 GUniqueOutPtr<GError> error; 277 GRefPtr<GSocketConnection> connection = adoptGRef(g_socket_client_connect_to_host_finish(G_SOCKET_CLIENT(source), result, &error.outPtr())); 278 tunnel->connected(!connection ? error->message : nullptr); 279 }, this); 280 } 281 282 void connected(const char* errorMessage) 283 { 284 auto completionHandler = std::exchange(m_completionHandler, nullptr); 285 completionHandler(errorMessage); 286 } 287 288 GRefPtr<SoupServer> m_server; 289 GRefPtr<SoupMessage> m_message; 290 Function<void (const char*)> m_completionHandler; 291 }; 292 293 unsigned gProxyServerPort; 294 295 static void serverCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext* context, void*) 296 { 297 if (message->method == SOUP_METHOD_CONNECT) { 298 g_assert_cmpuint(soup_server_get_port(server), ==, gProxyServerPort); 299 auto tunnel = std::make_unique<Tunnel>(server, message); 300 auto* tunnelPtr = tunnel.get(); 301 tunnelPtr->connect([tunnel = WTFMove(tunnel)](const char* errorMessage) { 302 if (errorMessage) { 303 soup_message_set_status(tunnel->m_message.get(), SOUP_STATUS_BAD_GATEWAY); 304 soup_message_set_response(tunnel->m_message.get(), "text/plain", SOUP_MEMORY_COPY, errorMessage, strlen(errorMessage)); 305 } else { 306 soup_message_headers_append(tunnel->m_message->response_headers, "Proxy-Authenticate", "Basic realm=\"Proxy realm\""); 307 soup_message_set_status(tunnel->m_message.get(), SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED); 308 } 309 }); 310 return; 311 } 312 257 313 if (message->method != SOUP_METHOD_GET) { 258 314 soup_message_set_status(message, SOUP_STATUS_NOT_IMPLEMENTED); … … 260 316 } 261 317 262 if (!strcmp(path, "/auth-test.html") || !strcmp(path, "/empty-realm.html")) { 318 if (g_str_has_suffix(path, "/auth-test.html") || g_str_has_suffix(path, "/empty-realm.html")) { 319 bool isProxy = g_str_has_prefix(path, "/proxy"); 320 if (isProxy) 321 g_assert_cmpuint(soup_server_get_port(server), ==, gProxyServerPort); 322 263 323 const char* authorization = soup_message_headers_get_one(message->request_headers, "Authorization"); 264 324 // Require authentication. … … 270 330 } else if (++AuthenticationTest::authenticationRetries < 3) { 271 331 // No or invalid authorization header provided by the client, request authentication twice then fail. 272 soup_message_set_status(message, SOUP_STATUS_UNAUTHORIZED);332 soup_message_set_status(message, isProxy ? SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED : SOUP_STATUS_UNAUTHORIZED); 273 333 if (!strcmp(path, "/empty-realm.html")) 274 334 soup_message_headers_append(message->response_headers, "WWW-Authenticate", "Basic"); 275 335 else 276 soup_message_headers_append(message->response_headers, "WWW-Authenticate","Basic realm=\"my realm\"");336 soup_message_headers_append(message->response_headers, isProxy ? "Proxy-Authenticate" : "WWW-Authenticate", isProxy ? "Basic realm=\"Proxy realm\"" : "Basic realm=\"my realm\""); 277 337 // Include a failure message in case the user attempts to proceed without authentication. 278 338 soup_message_body_append(message->response_body, SOUP_MEMORY_STATIC, authFailureHTMLString, strlen(authFailureHTMLString)); … … 288 348 } 289 349 350 class ProxyAuthenticationTest : public AuthenticationTest { 351 public: 352 MAKE_GLIB_TEST_FIXTURE(ProxyAuthenticationTest); 353 354 ProxyAuthenticationTest() 355 { 356 m_proxyServer.run(serverCallback); 357 g_assert(m_proxyServer.baseURI()); 358 gProxyServerPort = soup_uri_get_port(m_proxyServer.baseURI()); 359 GUniquePtr<char> proxyURI(soup_uri_to_string(m_proxyServer.baseURI(), FALSE)); 360 WebKitNetworkProxySettings* settings = webkit_network_proxy_settings_new(proxyURI.get(), nullptr); 361 webkit_web_context_set_network_proxy_settings(m_webContext.get(), WEBKIT_NETWORK_PROXY_MODE_CUSTOM, settings); 362 webkit_network_proxy_settings_free(settings); 363 } 364 365 ~ProxyAuthenticationTest() 366 { 367 gProxyServerPort = 0; 368 } 369 370 GUniquePtr<char> proxyServerPortAsString() 371 { 372 GUniquePtr<char> port(g_strdup_printf("%u", soup_uri_get_port(m_proxyServer.baseURI()))); 373 return port; 374 } 375 376 WebKitTestServer m_proxyServer; 377 }; 378 379 static void testWebViewAuthenticationProxy(ProxyAuthenticationTest* test, gconstpointer) 380 { 381 test->loadURI(kServer->getURIForPath("/proxy/auth-test.html").data()); 382 WebKitAuthenticationRequest* request = test->waitForAuthenticationRequest(); 383 // FIXME: the uri and host should the proxy ones, not the requested ones. 384 g_assert_cmpstr(webkit_authentication_request_get_host(request), ==, soup_uri_get_host(kServer->baseURI())); 385 g_assert_cmpuint(webkit_authentication_request_get_port(request), ==, soup_uri_get_port(kServer->baseURI())); 386 g_assert_cmpstr(webkit_authentication_request_get_realm(request), ==, "Proxy realm"); 387 g_assert(webkit_authentication_request_get_scheme(request) == WEBKIT_AUTHENTICATION_SCHEME_HTTP_BASIC); 388 g_assert(webkit_authentication_request_is_for_proxy(request)); 389 g_assert(!webkit_authentication_request_is_retry(request)); 390 } 391 392 static void testWebViewAuthenticationProxyHTTPS(ProxyAuthenticationTest* test, gconstpointer) 393 { 394 auto httpsServer = std::make_unique<WebKitTestServer>(WebKitTestServer::ServerHTTPS); 395 httpsServer->run(serverCallback); 396 397 test->loadURI(httpsServer->getURIForPath("/proxy/auth-test.html").data()); 398 WebKitAuthenticationRequest* request = test->waitForAuthenticationRequest(); 399 // FIXME: the uri and host should the proxy ones, not the requested ones. 400 g_assert_cmpstr(webkit_authentication_request_get_host(request), ==, soup_uri_get_host(httpsServer->baseURI())); 401 g_assert_cmpuint(webkit_authentication_request_get_port(request), ==, soup_uri_get_port(httpsServer->baseURI())); 402 g_assert_cmpstr(webkit_authentication_request_get_realm(request), ==, "Proxy realm"); 403 g_assert(webkit_authentication_request_get_scheme(request) == WEBKIT_AUTHENTICATION_SCHEME_HTTP_BASIC); 404 g_assert(webkit_authentication_request_is_for_proxy(request)); 405 g_assert(!webkit_authentication_request_is_retry(request)); 406 } 407 290 408 void beforeAll() 291 409 { … … 301 419 AuthenticationTest::add("WebKitWebView", "authentication-storage", testWebViewAuthenticationStorage); 302 420 AuthenticationTest::add("WebKitWebView", "authentication-empty-realm", testWebViewAuthenticationEmptyRealm); 421 ProxyAuthenticationTest::add("WebKitWebView", "authentication-proxy", testWebViewAuthenticationProxy); 422 ProxyAuthenticationTest::add("WebKitWebView", "authentication-proxy-https", testWebViewAuthenticationProxyHTTPS); 303 423 } 304 424
Note: See TracChangeset
for help on using the changeset viewer.