Diff
Modified: trunk/ChangeLog (279871 => 279872)
--- trunk/ChangeLog 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/ChangeLog 2021-07-13 14:19:38 UTC (rev 279872)
@@ -1,3 +1,15 @@
+2021-07-13 Carlos Garcia Campos <[email protected]>
+
+ [GTK][WPE] Expose support for client certificate auth
+ https://bugs.webkit.org/show_bug.cgi?id=200805
+
+ Reviewed by Michael Catanzaro.
+
+ Bump libsoup3 required version.
+
+ * Source/cmake/OptionsGTK.cmake:
+ * Source/cmake/OptionsWPE.cmake:
+
2021-06-24 Zan Dobersek <[email protected]>
REGRESSION(r236846): WPE shouldn't depend on OpenGL ES 3
Modified: trunk/Source/WebCore/ChangeLog (279871 => 279872)
--- trunk/Source/WebCore/ChangeLog 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebCore/ChangeLog 2021-07-13 14:19:38 UTC (rev 279872)
@@ -1,3 +1,36 @@
+2021-07-13 Carlos Garcia Campos <[email protected]>
+
+ [GTK][WPE] Expose support for client certificate auth
+ https://bugs.webkit.org/show_bug.cgi?id=200805
+
+ Reviewed by Michael Catanzaro.
+
+ * platform/Soup.cmake:
+ * platform/SourcesSoup.txt:
+ * platform/network/Credential.h:
+ * platform/network/ProtectionSpaceBase.cpp:
+ (WebCore::ProtectionSpaceBase::isPasswordBased const):
+ * platform/network/ProtectionSpaceBase.h:
+ * platform/network/soup/AuthenticationChallenge.h:
+ * platform/network/soup/AuthenticationChallengeSoup.cpp:
+ (WebCore::protectionSpaceForClientCertificate):
+ (WebCore::AuthenticationChallenge::AuthenticationChallenge):
+ (WebCore::protectionSpaceForClientCertificatePassword):
+ (WebCore::AuthenticationChallenge::platformCompare):
+ * platform/network/soup/CertificateInfoSoup.cpp:
+ (WebCore::CertificateInfo::isolatedCopy const):
+ * platform/network/soup/CredentialSoup.cpp: Added.
+ (WebCore::Credential::Credential):
+ (WebCore::m_certificate):
+ (WebCore::Credential::isEmpty const):
+ (WebCore::Credential::platformCompare):
+ * platform/network/soup/CredentialSoup.h: Added.
+ (WebCore::Credential::Credential):
+ (WebCore::Credential::encodingRequiresPlatformData const):
+ (WebCore::Credential::certificate const):
+ * platform/network/soup/NetworkStorageSessionSoup.cpp:
+ (WebCore::authTypeFromProtectionSpaceAuthenticationScheme):
+
2021-07-13 Martin Robinson <[email protected]>
RenderLayerScrollableArea::updateScrollPosition assumes that it can scroll to the targeted scroll position
Modified: trunk/Source/WebCore/platform/Soup.cmake (279871 => 279872)
--- trunk/Source/WebCore/platform/Soup.cmake 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebCore/platform/Soup.cmake 2021-07-13 14:19:38 UTC (rev 279872)
@@ -9,6 +9,7 @@
list(APPEND WebCore_PRIVATE_FRAMEWORK_HEADERS
platform/network/soup/AuthenticationChallenge.h
platform/network/soup/CertificateInfo.h
+ platform/network/soup/CredentialSoup.h
platform/network/soup/GUniquePtrSoup.h
platform/network/soup/ResourceError.h
platform/network/soup/ResourceRequest.h
Modified: trunk/Source/WebCore/platform/SourcesSoup.txt (279871 => 279872)
--- trunk/Source/WebCore/platform/SourcesSoup.txt 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebCore/platform/SourcesSoup.txt 2021-07-13 14:19:38 UTC (rev 279872)
@@ -25,6 +25,7 @@
platform/network/soup/CertificateInfoSoup.cpp
platform/network/soup/CookieSoup.cpp
platform/network/soup/CookieStorageSoup.cpp
+platform/network/soup/CredentialSoup.cpp
platform/network/soup/CredentialStorageSoup.cpp
platform/network/soup/NetworkStorageSessionSoup.cpp
platform/network/soup/ProxyServerSoup.cpp
Modified: trunk/Source/WebCore/platform/network/Credential.h (279871 => 279872)
--- trunk/Source/WebCore/platform/network/Credential.h 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebCore/platform/network/Credential.h 2021-07-13 14:19:38 UTC (rev 279872)
@@ -30,6 +30,8 @@
#if PLATFORM(COCOA)
#include "CredentialCocoa.h"
+#elif USE(SOUP)
+#include "CredentialSoup.h"
#else
#include "CredentialBase.h"
Modified: trunk/Source/WebCore/platform/network/ProtectionSpaceBase.cpp (279871 => 279872)
--- trunk/Source/WebCore/platform/network/ProtectionSpaceBase.cpp 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebCore/platform/network/ProtectionSpaceBase.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -109,6 +109,9 @@
case ProtectionSpaceAuthenticationSchemeNTLM:
case ProtectionSpaceAuthenticationSchemeNegotiate:
case ProtectionSpaceAuthenticationSchemeOAuth:
+#if USE(GLIB)
+ case ProtectionSpaceAuthenticationSchemeClientCertificatePINRequested:
+#endif
return true;
case ProtectionSpaceAuthenticationSchemeClientCertificateRequested:
case ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested:
Modified: trunk/Source/WebCore/platform/network/ProtectionSpaceBase.h (279871 => 279872)
--- trunk/Source/WebCore/platform/network/ProtectionSpaceBase.h 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebCore/platform/network/ProtectionSpaceBase.h 2021-07-13 14:19:38 UTC (rev 279872)
@@ -53,6 +53,9 @@
ProtectionSpaceAuthenticationSchemeClientCertificateRequested = 7,
ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested = 8,
ProtectionSpaceAuthenticationSchemeOAuth = 9,
+#if USE(GLIB)
+ ProtectionSpaceAuthenticationSchemeClientCertificatePINRequested = 10,
+#endif
ProtectionSpaceAuthenticationSchemeUnknown = 100
};
Modified: trunk/Source/WebCore/platform/network/soup/AuthenticationChallenge.h (279871 => 279872)
--- trunk/Source/WebCore/platform/network/soup/AuthenticationChallenge.h 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebCore/platform/network/soup/AuthenticationChallenge.h 2021-07-13 14:19:38 UTC (rev 279872)
@@ -28,6 +28,8 @@
#include "AuthenticationChallengeBase.h"
#include "AuthenticationClient.h"
+typedef struct _GTlsClientConnection GTlsClientConnection;
+typedef struct _GTlsPassword GTlsPassword;
typedef struct _SoupAuth SoupAuth;
typedef struct _SoupMessage SoupMessage;
@@ -45,13 +47,19 @@
}
AuthenticationChallenge(SoupMessage*, SoupAuth*, bool retrying);
+ AuthenticationChallenge(SoupMessage*, GTlsClientConnection*);
+ AuthenticationChallenge(SoupMessage*, GTlsPassword*);
AuthenticationClient* authenticationClient() const { RELEASE_ASSERT_NOT_REACHED(); }
#if USE(SOUP2)
SoupMessage* soupMessage() const { return m_soupMessage.get(); }
#endif
SoupAuth* soupAuth() const { return m_soupAuth.get(); }
+ GTlsPassword* tlsPassword() const { return m_tlsPassword.get(); }
void setProposedCredential(const Credential& credential) { m_proposedCredential = credential; }
+ uint32_t tlsPasswordFlags() const { return m_tlsPasswordFlags; }
+ void setTLSPasswordFlags(uint32_t tlsPasswordFlags) { m_tlsPasswordFlags = tlsPasswordFlags; }
+
private:
friend class AuthenticationChallengeBase;
static bool platformCompare(const AuthenticationChallenge&, const AuthenticationChallenge&);
@@ -60,6 +68,8 @@
GRefPtr<SoupMessage> m_soupMessage;
#endif
GRefPtr<SoupAuth> m_soupAuth;
+ GRefPtr<GTlsPassword> m_tlsPassword;
+ uint32_t m_tlsPasswordFlags { 0 };
};
} // namespace WebCore
Modified: trunk/Source/WebCore/platform/network/soup/AuthenticationChallengeSoup.cpp (279871 => 279872)
--- trunk/Source/WebCore/platform/network/soup/AuthenticationChallengeSoup.cpp 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebCore/platform/network/soup/AuthenticationChallengeSoup.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -90,11 +90,55 @@
{
}
+static ProtectionSpace protectionSpaceForClientCertificate(const URL& url)
+{
+ auto port = url.port();
+ if (!port)
+ port = defaultPortForProtocol(url.protocol());
+ return ProtectionSpace(url.host().toString(), static_cast<int>(port.value_or(0)), protectionSpaceServerTypeFromURL(url, false), { },
+ ProtectionSpaceAuthenticationSchemeClientCertificateRequested);
+}
+
+AuthenticationChallenge::AuthenticationChallenge(SoupMessage* soupMessage, GTlsClientConnection*)
+ : AuthenticationChallengeBase(protectionSpaceForClientCertificate(soupURIToURL(soup_message_get_uri(soupMessage)))
+ , Credential() // proposedCredentials
+ , 0 // previousFailureCount
+ , soupMessage // failureResponse
+ , ResourceError::authenticationError(soupMessage))
+{
+}
+
+static ProtectionSpace protectionSpaceForClientCertificatePassword(GTlsPassword* tlsPassword, const URL& url)
+{
+ auto port = url.port();
+ if (!port)
+ port = defaultPortForProtocol(url.protocol());
+ return ProtectionSpace(url.host().toString(), static_cast<int>(port.value_or(0)), protectionSpaceServerTypeFromURL(url, false),
+ String::fromUTF8(g_tls_password_get_description(tlsPassword)), ProtectionSpaceAuthenticationSchemeClientCertificatePINRequested);
+}
+
+AuthenticationChallenge::AuthenticationChallenge(SoupMessage* soupMessage, GTlsPassword* tlsPassword)
+ : AuthenticationChallengeBase(protectionSpaceForClientCertificatePassword(tlsPassword, soupURIToURL(soup_message_get_uri(soupMessage)))
+ , Credential() // proposedCredentials
+ , g_tls_password_get_flags(tlsPassword) & G_TLS_PASSWORD_RETRY ? 1 : 0 // previousFailureCount
+ , soupMessage // failureResponse
+ , ResourceError::authenticationError(soupMessage))
+ , m_tlsPassword(tlsPassword)
+ , m_tlsPasswordFlags(tlsPassword ? g_tls_password_get_flags(tlsPassword) : G_TLS_PASSWORD_NONE)
+{
+}
+
bool AuthenticationChallenge::platformCompare(const AuthenticationChallenge& a, const AuthenticationChallenge& b)
{
if (a.soupAuth() != b.soupAuth())
return false;
+ if (a.tlsPassword() != b.tlsPassword())
+ return false;
+
+ if (a.tlsPasswordFlags() != b.tlsPasswordFlags())
+ return false;
+
#if USE(SOUP2)
return a.soupMessage() == b.soupMessage();
#endif
Modified: trunk/Source/WebCore/platform/network/soup/CertificateInfoSoup.cpp (279871 => 279872)
--- trunk/Source/WebCore/platform/network/soup/CertificateInfoSoup.cpp 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebCore/platform/network/soup/CertificateInfoSoup.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -62,45 +62,43 @@
CertificateInfo::~CertificateInfo() = default;
-static GRefPtr<GTlsCertificate> createCertificate(GByteArray* bytes, GTlsCertificate* issuer)
-{
- gpointer cert = g_initable_new(g_tls_backend_get_certificate_type(g_tls_backend_get_default()),
- nullptr, nullptr,
- "certificate", bytes,
- "issuer", issuer,
- nullptr);
- RELEASE_ASSERT(cert);
- return adoptGRef(G_TLS_CERTIFICATE(cert));
-}
-
CertificateInfo CertificateInfo::isolatedCopy() const
{
- // We can only copy the public portions, so this can only be used for server certificates, not
- // for client certificates. Sadly, other ports don't have this restriction, and there is no way
- // to assert that we are not messing up here because we can't know how callers are using the
- // certificate. So be careful?
- //
- // We should add g_tls_certificate_copy() to GLib so that we can copy the private portion too.
+ if (!m_certificate)
+ return { };
- Vector<GRefPtr<GByteArray>> certificateBytes;
- GTlsCertificate* cert = m_certificate.get();
- if (!cert)
- return CertificateInfo();
+ Vector<GUniquePtr<char>> certificatesDataList;
+ for (auto* nextCertificate = m_certificate.get(); nextCertificate; nextCertificate = g_tls_certificate_get_issuer(nextCertificate)) {
+ GUniqueOutPtr<char> certificateData;
+ g_object_get(nextCertificate, "certificate-pem", &certificateData.outPtr(), nullptr);
+ certificatesDataList.append(certificateData.release());
+ }
- do {
- GRefPtr<GByteArray> der;
- g_object_get(cert, "certificate", &der.outPtr(), nullptr);
+#if GLIB_CHECK_VERSION(2, 69, 0)
+ GUniqueOutPtr<char> privateKey;
+ GUniqueOutPtr<char> privateKeyPKCS11Uri;
+ g_object_get(m_certificate.get(), "private-key-pem", &privateKey.outPtr(), "private-key-pkcs11-uri", &privateKeyPKCS11Uri.outPtr(), nullptr);
+#endif
- GRefPtr<GByteArray> copy = adoptGRef(g_byte_array_new());
- g_byte_array_append(copy.get(), der->data, der->len);
- certificateBytes.append(WTFMove(copy));
- } while ((cert = g_tls_certificate_get_issuer(cert)));
+ GType certificateType = g_tls_backend_get_certificate_type(g_tls_backend_get_default());
+ GRefPtr<GTlsCertificate> certificate;
+ GTlsCertificate* issuer = nullptr;
+ while (!certificatesDataList.isEmpty()) {
+ auto certificateData = certificatesDataList.takeLast();
+ certificate = adoptGRef(G_TLS_CERTIFICATE(g_initable_new(
+ certificateType, nullptr, nullptr,
+ "certificate-pem", certificateData.get(),
+ "issuer", issuer,
+#if GLIB_CHECK_VERSION(2, 69, 0)
+ "private-key-pem", certificatesDataList.isEmpty() ? privateKey.get() : nullptr,
+ "private-key-pkcs11-uri", certificatesDataList.isEmpty() ? privateKeyPKCS11Uri.get() : nullptr,
+#endif
+ nullptr)));
+ RELEASE_ASSERT(certificate);
+ issuer = certificate.get();
+ }
- auto finalCertificateIndex = certificateBytes.size() - 1;
- GRefPtr<GTlsCertificate> copy = createCertificate(certificateBytes[finalCertificateIndex].get(), nullptr);
- for (ssize_t i = finalCertificateIndex - 1; i >= 0; i--)
- copy = createCertificate(certificateBytes[i].get(), copy.get());
- return CertificateInfo(copy.get(), m_tlsErrors);
+ return CertificateInfo(certificate.get(), m_tlsErrors);
}
std::optional<CertificateSummary> CertificateInfo::summary() const
Added: trunk/Source/WebCore/platform/network/soup/CredentialSoup.cpp (0 => 279872)
--- trunk/Source/WebCore/platform/network/soup/CredentialSoup.cpp (rev 0)
+++ trunk/Source/WebCore/platform/network/soup/CredentialSoup.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -0,0 +1,53 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#include "config.h"
+#include "CredentialSoup.h"
+
+namespace WebCore {
+
+Credential::Credential(const Credential& original, CredentialPersistence persistence)
+ : CredentialBase(original, persistence)
+ , m_certificate(original.certificate())
+{
+}
+
+Credential::Credential(GTlsCertificate* certificate, CredentialPersistence persistence)
+ : CredentialBase({ }, { }, persistence)
+ , m_certificate(certificate)
+{
+}
+
+bool Credential::isEmpty() const
+{
+ return !m_certificate && CredentialBase::isEmpty();
+}
+
+bool Credential::platformCompare(const Credential& a, const Credential& b)
+{
+ return a.certificate() == b.certificate();
+}
+
+} // namespace WebCore
Added: trunk/Source/WebCore/platform/network/soup/CredentialSoup.h (0 => 279872)
--- trunk/Source/WebCore/platform/network/soup/CredentialSoup.h (rev 0)
+++ trunk/Source/WebCore/platform/network/soup/CredentialSoup.h 2021-07-13 14:19:38 UTC (rev 279872)
@@ -0,0 +1,63 @@
+/*
+ * Copyright (C) 2021 Igalia S.L.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+#pragma once
+
+#include "CredentialBase.h"
+#include <wtf/glib/GRefPtr.h>
+
+typedef struct _GTlsCertificate GTlsCertificate;
+
+namespace WebCore {
+
+class Credential : public CredentialBase {
+public:
+ Credential()
+ : CredentialBase()
+ {
+ }
+
+ Credential(const String& user, const String& password, CredentialPersistence persistence)
+ : CredentialBase(user, password, persistence)
+ {
+ }
+
+ Credential(const Credential&, CredentialPersistence);
+
+ WEBCORE_EXPORT Credential(GTlsCertificate*, CredentialPersistence);
+
+ WEBCORE_EXPORT bool isEmpty() const;
+
+ static bool platformCompare(const Credential&, const Credential&);
+
+ bool encodingRequiresPlatformData() const { return !!m_certificate; }
+
+ GTlsCertificate* certificate() const { return m_certificate.get(); }
+
+private:
+ GRefPtr<GTlsCertificate> m_certificate;
+};
+
+} // namespace WebCore
Modified: trunk/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp (279871 => 279872)
--- trunk/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebCore/platform/network/soup/NetworkStorageSessionSoup.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -125,6 +125,8 @@
case ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested:
ASSERT_NOT_REACHED();
break;
+ case ProtectionSpaceAuthenticationSchemeClientCertificatePINRequested:
+ return "Certificate PIN";
case ProtectionSpaceAuthenticationSchemeOAuth:
return "OAuth";
case ProtectionSpaceAuthenticationSchemeUnknown:
Modified: trunk/Source/WebKit/ChangeLog (279871 => 279872)
--- trunk/Source/WebKit/ChangeLog 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/ChangeLog 2021-07-13 14:19:38 UTC (rev 279872)
@@ -1,3 +1,45 @@
+2021-07-13 Carlos Garcia Campos <[email protected]>
+
+ [GTK][WPE] Expose support for client certificate auth
+ https://bugs.webkit.org/show_bug.cgi?id=200805
+
+ Reviewed by Michael Catanzaro.
+
+ Add new API to handle certificate and pin certificate authentication requests.
+
+ * NetworkProcess/soup/NetworkDataTaskSoup.cpp:
+ (WebKit::NetworkDataTaskSoup::createRequest):
+ (WebKit::NetworkDataTaskSoup::completeAuthentication):
+ (WebKit::NetworkDataTaskSoup::cancelAuthentication):
+ (WebKit::NetworkDataTaskSoup::authenticate):
+ (WebKit::NetworkDataTaskSoup::continueAuthenticate):
+ (WebKit::NetworkDataTaskSoup::requestCertificateCallback):
+ (WebKit::NetworkDataTaskSoup::requestCertificatePasswordCallback):
+ * NetworkProcess/soup/NetworkDataTaskSoup.h:
+ * Shared/WebCoreArgumentCoders.cpp:
+ (IPC::ArgumentCoder<AuthenticationChallenge>::encode):
+ (IPC::ArgumentCoder<AuthenticationChallenge>::decode):
+ * Shared/glib/ArgumentCodersGLib.cpp:
+ (IPC::ArgumentCoder<GRefPtr<GTlsCertificate>>::encode):
+ (IPC::ArgumentCoder<GRefPtr<GTlsCertificate>>::decode):
+ * Shared/soup/WebCoreArgumentCodersSoup.cpp:
+ (IPC::ArgumentCoder<Credential>::encodePlatformData):
+ (IPC::ArgumentCoder<Credential>::decodePlatformData):
+ * UIProcess/API/glib/WebKitAuthenticationRequest.cpp:
+ (webkit_authentication_request_get_certificate_pin_flags):
+ * UIProcess/API/glib/WebKitCredential.cpp:
+ (webkit_credential_new_for_certificate_pin):
+ (webkit_credential_new_for_certificate):
+ (webkit_credential_get_certificate):
+ * UIProcess/API/gtk/WebKitAuthenticationRequest.h:
+ * UIProcess/API/gtk/WebKitCredential.h:
+ * UIProcess/API/gtk/WebKitWebViewGtk.cpp:
+ (webkitWebViewAuthenticate):
+ * UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt:
+ * UIProcess/API/wpe/WebKitAuthenticationRequest.h:
+ * UIProcess/API/wpe/WebKitCredential.h:
+ * UIProcess/API/wpe/docs/wpe-1.0-sections.txt:
+
2021-07-13 Myles C. Maxfield <[email protected]>
Fix the Apple Internal iOS build
Modified: trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp (279871 => 279872)
--- trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -238,6 +238,8 @@
g_signal_connect(m_soupMessage.get(), "wrote-headers", G_CALLBACK(wroteHeadersCallback), this);
g_signal_connect(m_soupMessage.get(), "wrote-body", G_CALLBACK(wroteBodyCallback), this);
}
+ g_signal_connect(m_soupMessage.get(), "request-certificate", G_CALLBACK(requestCertificateCallback), this);
+ g_signal_connect(m_soupMessage.get(), "request-certificate-password", G_CALLBACK(requestCertificatePasswordCallback), this);
#endif
g_signal_connect(m_soupMessage.get(), "restarted", G_CALLBACK(restartedCallback), this);
g_signal_connect(m_soupMessage.get(), "starting", G_CALLBACK(startingCallback), this);
@@ -683,6 +685,73 @@
return httpStatusCode == SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED || httpStatusCode == SOUP_STATUS_UNAUTHORIZED;
}
+void NetworkDataTaskSoup::completeAuthentication(const AuthenticationChallenge& challenge, const Credential& credential)
+{
+ switch (challenge.protectionSpace().authenticationScheme()) {
+ case ProtectionSpaceAuthenticationSchemeDefault:
+ case ProtectionSpaceAuthenticationSchemeHTTPBasic:
+ case ProtectionSpaceAuthenticationSchemeHTTPDigest:
+ case ProtectionSpaceAuthenticationSchemeHTMLForm:
+ case ProtectionSpaceAuthenticationSchemeNTLM:
+ case ProtectionSpaceAuthenticationSchemeNegotiate:
+ case ProtectionSpaceAuthenticationSchemeOAuth:
+ soup_auth_authenticate(challenge.soupAuth(), credential.user().utf8().data(), credential.password().utf8().data());
+ break;
+ case ProtectionSpaceAuthenticationSchemeClientCertificatePINRequested: {
+#if USE(SOUP2)
+ ASSERT_NOT_REACHED();
+#else
+ CString password = credential.password().utf8();
+ g_tls_password_set_value(challenge.tlsPassword(), reinterpret_cast<const unsigned char*>(password.data()), password.length());
+ soup_message_tls_client_certificate_password_request_complete(m_soupMessage.get());
+#endif
+ break;
+ }
+ case ProtectionSpaceAuthenticationSchemeClientCertificateRequested:
+#if USE(SOUP2)
+ ASSERT_NOT_REACHED();
+#else
+ soup_message_set_tls_client_certificate(m_soupMessage.get(), credential.certificate());
+#endif
+ break;
+ case ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested:
+ case ProtectionSpaceAuthenticationSchemeUnknown:
+ break;
+ }
+}
+
+void NetworkDataTaskSoup::cancelAuthentication(const AuthenticationChallenge& challenge)
+{
+ switch (challenge.protectionSpace().authenticationScheme()) {
+ case ProtectionSpaceAuthenticationSchemeDefault:
+ case ProtectionSpaceAuthenticationSchemeHTTPBasic:
+ case ProtectionSpaceAuthenticationSchemeHTTPDigest:
+ case ProtectionSpaceAuthenticationSchemeHTMLForm:
+ case ProtectionSpaceAuthenticationSchemeNTLM:
+ case ProtectionSpaceAuthenticationSchemeNegotiate:
+ case ProtectionSpaceAuthenticationSchemeOAuth:
+ soup_auth_cancel(challenge.soupAuth());
+ break;
+ case ProtectionSpaceAuthenticationSchemeClientCertificatePINRequested:
+#if USE(SOUP2)
+ ASSERT_NOT_REACHED();
+#else
+ soup_message_tls_client_certificate_password_request_complete(m_soupMessage.get());
+#endif
+ break;
+ case ProtectionSpaceAuthenticationSchemeClientCertificateRequested:
+#if USE(SOUP2)
+ ASSERT_NOT_REACHED();
+#else
+ soup_message_set_tls_client_certificate(m_soupMessage.get(), nullptr);
+#endif
+ break;
+ case ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested:
+ case ProtectionSpaceAuthenticationSchemeUnknown:
+ break;
+ }
+}
+
void NetworkDataTaskSoup::authenticate(AuthenticationChallenge&& challenge)
{
ASSERT(m_soupMessage);
@@ -703,7 +772,8 @@
// Store the credential back, possibly adding it as a default for this directory.
m_session->networkStorageSession()->credentialStorage().set(m_partition, credential, challenge.protectionSpace(), challenge.failureResponse().url());
}
- soup_auth_authenticate(challenge.soupAuth(), credential.user().utf8().data(), credential.password().utf8().data());
+
+ completeAuthentication(challenge, credential);
return;
}
}
@@ -737,11 +807,13 @@
{
m_client->didReceiveChallenge(AuthenticationChallenge(challenge), NegotiatedLegacyTLS::No, [this, protectedThis = makeRef(*this), challenge](AuthenticationChallengeDisposition disposition, const Credential& credential) {
if (m_state == State::Canceling || m_state == State::Completed) {
+ cancelAuthentication(challenge);
clearRequest();
return;
}
if (disposition == AuthenticationChallengeDisposition::Cancel) {
+ cancelAuthentication(challenge);
cancel();
didFail(cancelledError(m_currentRequest));
return;
@@ -762,9 +834,9 @@
}
}
- soup_auth_authenticate(challenge.soupAuth(), credential.user().utf8().data(), credential.password().utf8().data());
+ completeAuthentication(challenge, credential);
} else
- soup_auth_cancel(challenge.soupAuth());
+ cancelAuthentication(challenge);
#if USE(SOUP2)
soup_session_unpause_message(static_cast<NetworkSessionSoup&>(*m_session).soupSession(), challenge.soupMessage());
@@ -1193,6 +1265,28 @@
task->m_networkLoadMetrics.responseBodyBytesReceived = soup_message_metrics_get_response_body_bytes_received(metrics);
task->m_networkLoadMetrics.responseBodyDecodedSize = soup_message_metrics_get_response_body_size(metrics);
}
+
+gboolean NetworkDataTaskSoup::requestCertificateCallback(SoupMessage* soupMessage, GTlsClientConnection* connection, NetworkDataTaskSoup* task)
+{
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) {
+ task->clearRequest();
+ return FALSE;
+ }
+ ASSERT(task->m_soupMessage.get() == soupMessage);
+ task->authenticate(AuthenticationChallenge(soupMessage, connection));
+ return TRUE;
+}
+
+gboolean NetworkDataTaskSoup::requestCertificatePasswordCallback(SoupMessage* soupMessage, GTlsPassword* tlsPassword, NetworkDataTaskSoup* task)
+{
+ if (task->state() == State::Canceling || task->state() == State::Completed || !task->m_client) {
+ task->clearRequest();
+ return FALSE;
+ }
+ ASSERT(task->m_soupMessage.get() == soupMessage);
+ task->authenticate(AuthenticationChallenge(soupMessage, tlsPassword));
+ return TRUE;
+}
#endif
#if USE(SOUP2)
Modified: trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h (279871 => 279872)
--- trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/NetworkProcess/soup/NetworkDataTaskSoup.h 2021-07-13 14:19:38 UTC (rev 279872)
@@ -102,6 +102,8 @@
#endif
void authenticate(WebCore::AuthenticationChallenge&&);
void continueAuthenticate(WebCore::AuthenticationChallenge&&);
+ void completeAuthentication(const WebCore::AuthenticationChallenge&, const WebCore::Credential&);
+ void cancelAuthentication(const WebCore::AuthenticationChallenge&);
static void skipInputStreamForRedirectionCallback(GInputStream*, GAsyncResult*, NetworkDataTaskSoup*);
void skipInputStreamForRedirection();
@@ -133,6 +135,8 @@
static void wroteHeadersCallback(SoupMessage*, NetworkDataTaskSoup*);
static void wroteBodyCallback(SoupMessage*, NetworkDataTaskSoup*);
static void gotBodyCallback(SoupMessage*, NetworkDataTaskSoup*);
+ static gboolean requestCertificateCallback(SoupMessage*, GTlsClientConnection*, NetworkDataTaskSoup*);
+ static gboolean requestCertificatePasswordCallback(SoupMessage*, GTlsPassword*, NetworkDataTaskSoup*);
#endif
void download();
Modified: trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp (279871 => 279872)
--- trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/Shared/WebCoreArgumentCoders.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -932,6 +932,9 @@
void ArgumentCoder<AuthenticationChallenge>::encode(Encoder& encoder, const AuthenticationChallenge& challenge)
{
encoder << challenge.protectionSpace() << challenge.proposedCredential() << challenge.previousFailureCount() << challenge.failureResponse() << challenge.error();
+#if USE(SOUP)
+ encoder << challenge.tlsPasswordFlags();
+#endif
}
bool ArgumentCoder<AuthenticationChallenge>::decode(Decoder& decoder, AuthenticationChallenge& challenge)
@@ -955,8 +958,18 @@
ResourceError error;
if (!decoder.decode(error))
return false;
-
+
+#if USE(SOUP)
+ uint32_t tlsPasswordFlags;
+ if (!decoder.decode(tlsPasswordFlags))
+ return false;
+#endif
+
challenge = AuthenticationChallenge(protectionSpace, proposedCredential, previousFailureCount, failureResponse, error);
+
+#if USE(SOUP)
+ challenge.setTLSPasswordFlags(tlsPasswordFlags);
+#endif
return true;
}
Modified: trunk/Source/WebKit/Shared/glib/ArgumentCodersGLib.cpp (279871 => 279872)
--- trunk/Source/WebKit/Shared/glib/ArgumentCodersGLib.cpp 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/Shared/glib/ArgumentCodersGLib.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -89,6 +89,14 @@
if (certificatesDataList.isEmpty())
return;
+#if GLIB_CHECK_VERSION(2, 69, 0)
+ GRefPtr<GByteArray> privateKey;
+ GUniqueOutPtr<char> privateKeyPKCS11Uri;
+ g_object_get(certificate.get(), "private-key", &privateKey.outPtr(), "private-key-pkcs11-uri", &privateKeyPKCS11Uri.outPtr(), nullptr);
+ encoder << IPC::DataReference(privateKey ? privateKey->data : nullptr, privateKey ? privateKey->len : 0);
+ encoder << CString(privateKeyPKCS11Uri.get());
+#endif
+
// Encode starting from the root certificate.
while (!certificatesDataList.isEmpty()) {
auto certificateData = certificatesDataList.takeLast();
@@ -105,6 +113,21 @@
if (!chainLength)
return GRefPtr<GTlsCertificate>();
+#if GLIB_CHECK_VERSION(2, 69, 0)
+ IPC::DataReference privateKeyData;
+ if (!decoder.decode(privateKeyData))
+ return std::nullopt;
+ GRefPtr<GByteArray> privateKey;
+ if (privateKeyData.size()) {
+ privateKey = adoptGRef(g_byte_array_sized_new(privateKeyData.size()));
+ g_byte_array_append(privateKey.get(), privateKeyData.data(), privateKeyData.size());
+ }
+
+ CString privateKeyPKCS11Uri;
+ if (!decoder.decode(privateKeyPKCS11Uri))
+ return std::nullopt;
+#endif
+
GType certificateType = g_tls_backend_get_certificate_type(g_tls_backend_get_default());
GRefPtr<GTlsCertificate> certificate;
GTlsCertificate* issuer = nullptr;
@@ -120,6 +143,10 @@
certificateType, nullptr, nullptr,
"certificate", certificateData.get(),
"issuer", issuer,
+#if GLIB_CHECK_VERSION(2, 69, 0)
+ "private-key", i == chainLength - 1 ? privateKey.get() : nullptr,
+ "private-key-pkcs11-uri", i == chainLength - 1 ? privateKeyPKCS11Uri.data() : nullptr,
+#endif
nullptr)));
issuer = certificate.get();
}
Modified: trunk/Source/WebKit/Shared/soup/WebCoreArgumentCodersSoup.cpp (279871 => 279872)
--- trunk/Source/WebKit/Shared/soup/WebCoreArgumentCodersSoup.cpp 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/Shared/soup/WebCoreArgumentCodersSoup.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -31,6 +31,7 @@
#include "ArgumentCodersGLib.h"
#include "DataReference.h"
#include <WebCore/CertificateInfo.h>
+#include <WebCore/Credential.h>
#include <WebCore/DictionaryPopupInfo.h>
#include <WebCore/Font.h>
#include <WebCore/FontAttributes.h>
@@ -181,15 +182,26 @@
return false;
}
-void ArgumentCoder<Credential>::encodePlatformData(Encoder&, const Credential&)
+void ArgumentCoder<Credential>::encodePlatformData(Encoder& encoder, const Credential& credential)
{
- ASSERT_NOT_REACHED();
+ GRefPtr<GTlsCertificate> certificate = credential.certificate();
+ encoder << certificate;
+ encoder << credential.persistence();
}
-bool ArgumentCoder<Credential>::decodePlatformData(Decoder&, Credential&)
+bool ArgumentCoder<Credential>::decodePlatformData(Decoder& decoder, Credential& credential)
{
- ASSERT_NOT_REACHED();
- return false;
+ std::optional<GRefPtr<GTlsCertificate>> certificate;
+ decoder >> certificate;
+ if (!certificate)
+ return false;
+
+ CredentialPersistence persistence;
+ if (!decoder.decode(persistence))
+ return false;
+
+ credential = Credential(certificate->get(), persistence);
+ return true;
}
void ArgumentCoder<FontAttributes>::encodePlatformData(Encoder&, const FontAttributes&)
Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitAuthenticationRequest.cpp (279871 => 279872)
--- trunk/Source/WebKit/UIProcess/API/glib/WebKitAuthenticationRequest.cpp 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitAuthenticationRequest.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -98,6 +98,8 @@
return WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED;
case WebCore::ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested:
return WEBKIT_AUTHENTICATION_SCHEME_SERVER_TRUST_EVALUATION_REQUESTED;
+ case WebCore::ProtectionSpaceAuthenticationSchemeClientCertificatePINRequested:
+ return WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_PIN_REQUESTED;
case WebCore::ProtectionSpaceAuthenticationSchemeUnknown:
return WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN;
default:
@@ -482,3 +484,20 @@
g_signal_emit(request, signals[CANCELLED], 0);
}
+
+/**
+ * webkit_authentication_request_get_certificate_pin_flags:
+ * @request: a #WebKitAuthenticationRequest
+ *
+ * Get the #GTlsPasswordFlags of the %WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_PIN_REQUESTED authentication challenge.
+ *
+ * Returns: a #GTlsPasswordFlags
+ *
+ * Since: 2.34
+ */
+GTlsPasswordFlags webkit_authentication_request_get_certificate_pin_flags(WebKitAuthenticationRequest* request)
+{
+ g_return_val_if_fail(WEBKIT_IS_AUTHENTICATION_REQUEST(request), G_TLS_PASSWORD_NONE);
+
+ return static_cast<GTlsPasswordFlags>(request->priv->authenticationChallenge->core().tlsPasswordFlags());
+}
Modified: trunk/Source/WebKit/UIProcess/API/glib/WebKitCredential.cpp (279871 => 279872)
--- trunk/Source/WebKit/UIProcess/API/glib/WebKitCredential.cpp 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/UIProcess/API/glib/WebKitCredential.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -103,6 +103,54 @@
}
/**
+ * webkit_credential_new_for_certificate_pin:
+ * @pin: The PIN for the new credential
+ * @persistence: The #WebKitCredentialPersistence of the new credential
+ *
+ * Create a new credential from the provided PIN and persistence mode.
+ * Note that %WEBKIT_CREDENTIAL_PERSISTENCE_PERMANENT is not supported for certificate pin credentials.
+ *
+ * Returns: (transfer full): A #WebKitCredential.
+ *
+ * Since: 2.34
+ */
+WebKitCredential* webkit_credential_new_for_certificate_pin(const gchar* pin, WebKitCredentialPersistence persistence)
+{
+ g_return_val_if_fail(pin, 0);
+
+ if (persistence == WEBKIT_CREDENTIAL_PERSISTENCE_PERMANENT) {
+ g_warning("Permanent persistence is not supported for certificate pin credentials. Session persistence will be used instead.");
+ persistence = WEBKIT_CREDENTIAL_PERSISTENCE_FOR_SESSION;
+ }
+
+ return webkitCredentialCreate(WebCore::Credential("", String::fromUTF8(pin), toWebCoreCredentialPersistence(persistence)));
+}
+
+/**
+ * webkit_credential_new_for_certificate:
+ * @certificate: (nullable): The #GTlsCertificate, or %NULL
+ * @persistence: The #WebKitCredentialPersistence of the new credential
+ *
+ * Create a new credential from the @certificate and persistence mode.
+ * Note that %WEBKIT_CREDENTIAL_PERSISTENCE_PERMANENT is not supported for certificate credentials.
+ *
+ * Returns: (transfer full): A #WebKitCredential.
+ *
+ * Since: 2.34
+ */
+WebKitCredential* webkit_credential_new_for_certificate(GTlsCertificate* certificate, WebKitCredentialPersistence persistence)
+{
+ g_return_val_if_fail(!certificate || G_IS_TLS_CERTIFICATE(certificate), nullptr);
+
+ if (persistence == WEBKIT_CREDENTIAL_PERSISTENCE_PERMANENT) {
+ g_warning("Permanent persistence is not supported for certificate credentials. Session persistence will be used instead.");
+ persistence = WEBKIT_CREDENTIAL_PERSISTENCE_FOR_SESSION;
+ }
+
+ return webkitCredentialCreate(WebCore::Credential(certificate, toWebCoreCredentialPersistence(persistence)));
+}
+
+/**
* webkit_credential_copy:
* @credential: a #WebKitCredential
*
@@ -191,6 +239,23 @@
}
/**
+ * webkit_credential_get_certificate:
+ * @credential: a #WebKitCredential
+ *
+ * Get the certificate currently held by this #WebKitCredential.
+ *
+ * Returns: (transfer none): a #GTlsCertificate, or %NULL
+ *
+ * Since: 2.34
+ */
+GTlsCertificate* webkit_credential_get_certificate(WebKitCredential* credential)
+{
+ g_return_val_if_fail(credential, NULL);
+
+ return credential->credential.certificate();
+}
+
+/**
* webkit_credential_get_persistence:
* @credential: a #WebKitCredential
*
Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitAuthenticationRequest.h (279871 => 279872)
--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitAuthenticationRequest.h 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitAuthenticationRequest.h 2021-07-13 14:19:38 UTC (rev 279872)
@@ -68,6 +68,7 @@
* @WEBKIT_AUTHENTICATION_SCHEME_NEGOTIATE: Negotiate (or SPNEGO) authentication scheme as defined in RFC 4559.
* @WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED: Client Certificate Authentication (see RFC 2246).
* @WEBKIT_AUTHENTICATION_SCHEME_SERVER_TRUST_EVALUATION_REQUESTED: Server Trust Authentication.
+ * @WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_PIN_REQUESTED: Client certificate PIN required for use. Since: 2.34
* @WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN: Authentication scheme unknown.
*
* Enum values representing the authentication scheme.
@@ -83,6 +84,7 @@
WEBKIT_AUTHENTICATION_SCHEME_NEGOTIATE = 6,
WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED = 7,
WEBKIT_AUTHENTICATION_SCHEME_SERVER_TRUST_EVALUATION_REQUESTED = 8,
+ WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_PIN_REQUESTED = 9,
WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN = 100,
} WebKitAuthenticationScheme;
@@ -132,6 +134,9 @@
WEBKIT_API void
webkit_authentication_request_cancel (WebKitAuthenticationRequest *request);
+WEBKIT_API GTlsPasswordFlags
+webkit_authentication_request_get_certificate_pin_flags (WebKitAuthenticationRequest* request);
+
G_END_DECLS
#endif
Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitCredential.h (279871 => 279872)
--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitCredential.h 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitCredential.h 2021-07-13 14:19:38 UTC (rev 279872)
@@ -25,6 +25,7 @@
#define WebKitCredential_h
#include <glib-object.h>
+#include <gio/gio.h>
#include <webkit2/WebKitDefines.h>
G_BEGIN_DECLS
@@ -50,30 +51,41 @@
} WebKitCredentialPersistence;
WEBKIT_API GType
-webkit_credential_get_type (void);
+webkit_credential_get_type (void);
WEBKIT_API WebKitCredential *
-webkit_credential_new (const gchar *username,
- const gchar *password,
- WebKitCredentialPersistence persistence);
+webkit_credential_new (const gchar *username,
+ const gchar *password,
+ WebKitCredentialPersistence persistence);
WEBKIT_API WebKitCredential *
-webkit_credential_copy (WebKitCredential *credential);
+webkit_credential_new_for_certificate_pin (const gchar *pin,
+ WebKitCredentialPersistence persistence);
+WEBKIT_API WebKitCredential *
+webkit_credential_new_for_certificate (GTlsCertificate *certificate,
+ WebKitCredentialPersistence persistence);
+
+WEBKIT_API WebKitCredential *
+webkit_credential_copy (WebKitCredential *credential);
+
WEBKIT_API void
-webkit_credential_free (WebKitCredential *credential);
+webkit_credential_free (WebKitCredential *credential);
WEBKIT_API const gchar *
-webkit_credential_get_username (WebKitCredential *credential);
+webkit_credential_get_username (WebKitCredential *credential);
WEBKIT_API const gchar *
-webkit_credential_get_password (WebKitCredential *credential);
+webkit_credential_get_password (WebKitCredential *credential);
WEBKIT_API gboolean
-webkit_credential_has_password (WebKitCredential *credential);
+webkit_credential_has_password (WebKitCredential *credential);
+WEBKIT_API GTlsCertificate *
+webkit_credential_get_certificate (WebKitCredential *credential);
+
WEBKIT_API WebKitCredentialPersistence
-webkit_credential_get_persistence (WebKitCredential *credential);
+webkit_credential_get_persistence (WebKitCredential *credential);
G_END_DECLS
Modified: trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewGtk.cpp (279871 => 279872)
--- trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewGtk.cpp 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/UIProcess/API/gtk/WebKitWebViewGtk.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -34,8 +34,24 @@
gboolean webkitWebViewAuthenticate(WebKitWebView* webView, WebKitAuthenticationRequest* request)
{
- CredentialStorageMode credentialStorageMode = webkit_authentication_request_can_save_credentials(request) ? AllowPersistentStorage : DisallowPersistentStorage;
- webkitWebViewBaseAddDialog(WEBKIT_WEB_VIEW_BASE(webView), webkitAuthenticationDialogNew(request, credentialStorageMode));
+ switch (webkit_authentication_request_get_scheme(request)) {
+ case WEBKIT_AUTHENTICATION_SCHEME_DEFAULT:
+ case WEBKIT_AUTHENTICATION_SCHEME_HTTP_BASIC:
+ case WEBKIT_AUTHENTICATION_SCHEME_HTTP_DIGEST:
+ case WEBKIT_AUTHENTICATION_SCHEME_HTML_FORM:
+ case WEBKIT_AUTHENTICATION_SCHEME_NTLM:
+ case WEBKIT_AUTHENTICATION_SCHEME_NEGOTIATE:
+ case WEBKIT_AUTHENTICATION_SCHEME_SERVER_TRUST_EVALUATION_REQUESTED:
+ case WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN: {
+ CredentialStorageMode credentialStorageMode = webkit_authentication_request_can_save_credentials(request) ? AllowPersistentStorage : DisallowPersistentStorage;
+ webkitWebViewBaseAddDialog(WEBKIT_WEB_VIEW_BASE(webView), webkitAuthenticationDialogNew(request, credentialStorageMode));
+ break;
+ }
+ case WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED:
+ case WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_PIN_REQUESTED:
+ webkit_authentication_request_authenticate(request, nullptr);
+ break;
+ }
return TRUE;
}
Modified: trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt (279871 => 279872)
--- trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/UIProcess/API/gtk/docs/webkit2gtk-4.0-sections.txt 2021-07-13 14:19:38 UTC (rev 279872)
@@ -357,6 +357,7 @@
webkit_authentication_request_set_proposed_credential
webkit_authentication_request_get_realm
webkit_authentication_request_get_scheme
+webkit_authentication_request_get_certificate_pin_flags
webkit_authentication_request_is_for_proxy
<SUBSECTION Standard>
@@ -378,6 +379,8 @@
WebKitCredential
WebKitCredentialPersistence
webkit_credential_new
+webkit_credential_new_for_certificate_pin
+webkit_credential_new_for_certificate
webkit_credential_copy
webkit_credential_free
webkit_credential_get_password
@@ -384,6 +387,7 @@
webkit_credential_get_persistence
webkit_credential_get_username
webkit_credential_has_password
+webkit_credential_get_certificate
</SECTION>
<SECTION>
Modified: trunk/Source/WebKit/UIProcess/API/wpe/WebKitAuthenticationRequest.h (279871 => 279872)
--- trunk/Source/WebKit/UIProcess/API/wpe/WebKitAuthenticationRequest.h 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/UIProcess/API/wpe/WebKitAuthenticationRequest.h 2021-07-13 14:19:38 UTC (rev 279872)
@@ -67,6 +67,7 @@
* @WEBKIT_AUTHENTICATION_SCHEME_NEGOTIATE: Negotiate (or SPNEGO) authentication scheme as defined in RFC 4559.
* @WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED: Client Certificate Authentication (see RFC 2246).
* @WEBKIT_AUTHENTICATION_SCHEME_SERVER_TRUST_EVALUATION_REQUESTED: Server Trust Authentication.
+ * @WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_PIN_REQUESTED: Client certificate PIN required for use. Since: 2.34
* @WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN: Authentication scheme unknown.
*
* Enum values representing the authentication scheme.
@@ -82,6 +83,7 @@
WEBKIT_AUTHENTICATION_SCHEME_NEGOTIATE = 6,
WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED = 7,
WEBKIT_AUTHENTICATION_SCHEME_SERVER_TRUST_EVALUATION_REQUESTED = 8,
+ WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_PIN_REQUESTED = 9,
WEBKIT_AUTHENTICATION_SCHEME_UNKNOWN = 100,
} WebKitAuthenticationScheme;
@@ -131,6 +133,9 @@
WEBKIT_API void
webkit_authentication_request_cancel (WebKitAuthenticationRequest *request);
+WEBKIT_API GTlsPasswordFlags
+webkit_authentication_request_get_certificate_pin_flags (WebKitAuthenticationRequest* request);
+
G_END_DECLS
#endif
Modified: trunk/Source/WebKit/UIProcess/API/wpe/WebKitCredential.h (279871 => 279872)
--- trunk/Source/WebKit/UIProcess/API/wpe/WebKitCredential.h 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/UIProcess/API/wpe/WebKitCredential.h 2021-07-13 14:19:38 UTC (rev 279872)
@@ -25,6 +25,7 @@
#define WebKitCredential_h
#include <glib-object.h>
+#include <gio/gio.h>
#include <wpe/WebKitDefines.h>
G_BEGIN_DECLS
@@ -53,27 +54,38 @@
webkit_credential_get_type (void);
WEBKIT_API WebKitCredential *
-webkit_credential_new (const gchar *username,
- const gchar *password,
- WebKitCredentialPersistence persistence);
+webkit_credential_new (const gchar *username,
+ const gchar *password,
+ WebKitCredentialPersistence persistence);
WEBKIT_API WebKitCredential *
-webkit_credential_copy (WebKitCredential *credential);
+webkit_credential_new_for_certificate_pin (const gchar *pin,
+ WebKitCredentialPersistence persistence);
+WEBKIT_API WebKitCredential *
+webkit_credential_new_for_certificate (GTlsCertificate *certificate,
+ WebKitCredentialPersistence persistence);
+
+WEBKIT_API WebKitCredential *
+webkit_credential_copy (WebKitCredential *credential);
+
WEBKIT_API void
-webkit_credential_free (WebKitCredential *credential);
+webkit_credential_free (WebKitCredential *credential);
WEBKIT_API const gchar *
-webkit_credential_get_username (WebKitCredential *credential);
+webkit_credential_get_username (WebKitCredential *credential);
WEBKIT_API const gchar *
-webkit_credential_get_password (WebKitCredential *credential);
+webkit_credential_get_password (WebKitCredential *credential);
WEBKIT_API gboolean
-webkit_credential_has_password (WebKitCredential *credential);
+webkit_credential_has_password (WebKitCredential *credential);
+WEBKIT_API GTlsCertificate *
+webkit_credential_get_certificate (WebKitCredential *credential);
+
WEBKIT_API WebKitCredentialPersistence
-webkit_credential_get_persistence (WebKitCredential *credential);
+webkit_credential_get_persistence (WebKitCredential *credential);
G_END_DECLS
Modified: trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt (279871 => 279872)
--- trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/WebKit/UIProcess/API/wpe/docs/wpe-1.0-sections.txt 2021-07-13 14:19:38 UTC (rev 279872)
@@ -360,6 +360,7 @@
webkit_authentication_request_set_proposed_credential
webkit_authentication_request_get_realm
webkit_authentication_request_get_scheme
+webkit_authentication_request_get_certificate_pin_flags
webkit_authentication_request_is_for_proxy
<SUBSECTION Standard>
@@ -381,6 +382,8 @@
WebKitCredential
WebKitCredentialPersistence
webkit_credential_new
+webkit_credential_new_for_certificate_pin
+webkit_credential_new_for_certificate
webkit_credential_copy
webkit_credential_free
webkit_credential_get_password
@@ -387,6 +390,7 @@
webkit_credential_get_persistence
webkit_credential_get_username
webkit_credential_has_password
+webkit_credential_get_certificate
</SECTION>
<SECTION>
Modified: trunk/Source/cmake/OptionsGTK.cmake (279871 => 279872)
--- trunk/Source/cmake/OptionsGTK.cmake 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/cmake/OptionsGTK.cmake 2021-07-13 14:19:38 UTC (rev 279872)
@@ -209,7 +209,7 @@
set(SOUP_MINIMUM_VERSION 2.54.0)
set(SOUP_API_VERSION 2.4)
else ()
- set(SOUP_MINIMUM_VERSION 2.99.8)
+ set(SOUP_MINIMUM_VERSION 2.99.9)
set(SOUP_API_VERSION 3.0)
set(ENABLE_SERVER_PRECONNECT ON)
endif ()
Modified: trunk/Source/cmake/OptionsWPE.cmake (279871 => 279872)
--- trunk/Source/cmake/OptionsWPE.cmake 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Source/cmake/OptionsWPE.cmake 2021-07-13 14:19:38 UTC (rev 279872)
@@ -124,7 +124,7 @@
set(WPE_API_VERSION 1.0)
set(WPE_API_DOC_VERSION 1.0)
else ()
- set(SOUP_MINIMUM_VERSION 2.99.8)
+ set(SOUP_MINIMUM_VERSION 2.99.9)
set(SOUP_API_VERSION 3.0)
set(WPE_API_VERSION 1.1)
# No API changes in 1.1, so keep using the same API documentation.
Modified: trunk/Tools/ChangeLog (279871 => 279872)
--- trunk/Tools/ChangeLog 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Tools/ChangeLog 2021-07-13 14:19:38 UTC (rev 279872)
@@ -1,3 +1,32 @@
+2021-07-13 Carlos Garcia Campos <[email protected]>
+
+ [GTK][WPE] Expose support for client certificate auth
+ https://bugs.webkit.org/show_bug.cgi?id=200805
+
+ Reviewed by Michael Catanzaro.
+
+ Add a simple implementation in MiniBrowser using a file chooser to ask for the certificate from a file and unit
+ tests for the client certificate request. Unfortunately we can't easily test pin certificates.
+
+ * MiniBrowser/gtk/BrowserTab.c:
+ (certificateDialogResponse):
+ (webViewAuthenticate):
+ (browserTabConstructed):
+ * TestWebKitAPI/Tests/WebKitGLib/TestSSL.cpp:
+ (ClientSideCertificateTest::acceptCertificateCallback):
+ (ClientSideCertificateTest::requestStartedCallback):
+ (ClientSideCertificateTest::authenticateCallback):
+ (ClientSideCertificateTest::ClientSideCertificateTest):
+ (ClientSideCertificateTest::~ClientSideCertificateTest):
+ (ClientSideCertificateTest::authenticate):
+ (ClientSideCertificateTest::acceptCertificate):
+ (ClientSideCertificateTest::waitForAuthenticationRequest):
+ (testClientSideCertificate):
+ (beforeAll):
+ * TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp:
+ * TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.h:
+ (WebKitTestServer::soupServer const):
+
2021-07-12 Filip Pizlo <[email protected]> and Yusuke Suzuki <[email protected]>
New malloc algorithm
Modified: trunk/Tools/MiniBrowser/gtk/BrowserTab.c (279871 => 279872)
--- trunk/Tools/MiniBrowser/gtk/BrowserTab.c 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Tools/MiniBrowser/gtk/BrowserTab.c 2021-07-13 14:19:38 UTC (rev 279872)
@@ -443,6 +443,61 @@
g_warning("WebProcess CRASHED");
}
+static void certificateDialogResponse(GtkDialog *dialog, int response, WebKitAuthenticationRequest *request)
+{
+ if (response == GTK_RESPONSE_ACCEPT) {
+ GFile *file = gtk_file_chooser_get_file(GTK_FILE_CHOOSER(dialog));
+ if (file) {
+ char *path = g_file_get_path(file);
+ GError *error = NULL;
+ GTlsCertificate *certificate = g_tls_certificate_new_from_file(path, &error);
+ if (certificate) {
+ WebKitCredential *credential = webkit_credential_new_for_certificate(certificate, WEBKIT_CREDENTIAL_PERSISTENCE_FOR_SESSION);
+ webkit_authentication_request_authenticate(request, credential);
+ webkit_credential_free(credential);
+ g_object_unref(certificate);
+ } else {
+ g_warning("Failed to create certificate for %s", path);
+ g_error_free(error);
+ }
+ g_free(path);
+ g_object_unref(file);
+ }
+ } else
+ webkit_authentication_request_authenticate(request, NULL);
+
+ g_object_unref(request);
+
+#if GTK_CHECK_VERSION(3, 98, 5)
+ gtk_window_destroy(GTK_WINDOW(dialog));
+#else
+ gtk_widget_destroy(GTK_WIDGET(dialog));
+#endif
+}
+
+static gboolean webViewAuthenticate(WebKitWebView *webView, WebKitAuthenticationRequest *request, BrowserTab *tab)
+{
+ if (webkit_authentication_request_get_scheme(request) != WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED)
+ return FALSE;
+
+#if GTK_CHECK_VERSION(3, 98, 5)
+ GtkWindow *window = GTK_WINDOW(gtk_widget_get_root(GTK_WIDGET(tab)));
+#else
+ GtkWindow *window = GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(tab)));
+#endif
+ GtkWidget *fileChooser = gtk_file_chooser_dialog_new("Certificate required", window, GTK_FILE_CHOOSER_ACTION_OPEN, "Cancel", GTK_RESPONSE_CANCEL, "Open", GTK_RESPONSE_ACCEPT, NULL);
+ GtkFileFilter *filter = gtk_file_filter_new();
+ gtk_file_filter_set_name(filter, "PEM Certificate");
+ gtk_file_filter_add_mime_type(filter, "application/x-x509-ca-cert");
+ gtk_file_filter_add_pattern(filter, "*.pem");
+ gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(fileChooser), filter);
+
+ g_signal_connect(fileChooser, "response", G_CALLBACK(certificateDialogResponse), g_object_ref(request));
+ gtk_widget_show(fileChooser);
+
+ return TRUE;
+}
+
static gboolean inspectorOpenedInWindow(WebKitWebInspector *inspector, BrowserTab *tab)
{
tab->inspectorIsVisible = TRUE;
@@ -653,6 +708,7 @@
g_signal_connect(tab->webView, "permission-request", G_CALLBACK(decidePermissionRequest), tab);
g_signal_connect(tab->webView, "run-color-chooser", G_CALLBACK(runColorChooserCallback), tab);
g_signal_connect(tab->webView, "web-process-terminated", G_CALLBACK(webProcessTerminatedCallback), NULL);
+ g_signal_connect(tab->webView, "authenticate", G_CALLBACK(webViewAuthenticate), tab);
g_object_bind_property(tab->webView, "is-playing-audio", tab->titleAudioButton, "visible", G_BINDING_DEFAULT | G_BINDING_SYNC_CREATE);
g_signal_connect(tab->webView, "notify::is-muted", G_CALLBACK(audioMutedChanged), tab);
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestSSL.cpp (279871 => 279872)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestSSL.cpp 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/TestSSL.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -477,6 +477,171 @@
g_assert_false(test->m_loadEvents.contains(LoadTrackingTest::LoadCommitted));
}
+#if !USE(SOUP2)
+class ClientSideCertificateTest : public LoadTrackingTest {
+public:
+ MAKE_GLIB_TEST_FIXTURE(ClientSideCertificateTest);
+
+ static gboolean acceptCertificateCallback(SoupServerMessage* message, GTlsCertificate* certificate, GTlsCertificateFlags errors, ClientSideCertificateTest* test)
+ {
+ bool acceptedCertificate = test->acceptCertificate(errors);
+ g_object_set_data_full(G_OBJECT(message), acceptedCertificate ? "accepted-certificate" : "rejected-certificate", g_object_ref(certificate), g_object_unref);
+ return acceptedCertificate;
+ }
+
+ static void requestStartedCallback(SoupServer*, SoupServerMessage* message, ClientSideCertificateTest* test)
+ {
+ g_signal_connect(message, "accept-certificate", G_CALLBACK(acceptCertificateCallback), test);
+ }
+
+ static gboolean authenticateCallback(WebKitWebView*, WebKitAuthenticationRequest* request, ClientSideCertificateTest* test)
+ {
+ test->authenticate(request);
+ return TRUE;
+ }
+
+ ClientSideCertificateTest()
+ {
+ CString resourcesDir = Test::getResourcesDir();
+ GUniquePtr<char> sslCertificateFile(g_build_filename(resourcesDir.data(), "test-cert.pem", nullptr));
+ GUniquePtr<char> sslKeyFile(g_build_filename(resourcesDir.data(), "test-key.pem", nullptr));
+ GUniqueOutPtr<GError> error;
+ m_clientCertificate = adoptGRef(g_tls_certificate_new_from_files(sslCertificateFile.get(), sslKeyFile.get(), &error.outPtr()));
+ g_assert_no_error(error.get());
+
+ soup_server_set_tls_auth_mode(kHttpsServer->soupServer(), G_TLS_AUTHENTICATION_REQUIRED);
+ g_signal_connect(kHttpsServer->soupServer(), "request-started", G_CALLBACK(requestStartedCallback), this);
+ g_signal_connect(m_webView, "authenticate", G_CALLBACK(authenticateCallback), this);
+ }
+
+ ~ClientSideCertificateTest()
+ {
+ soup_server_set_tls_auth_mode(kHttpsServer->soupServer(), G_TLS_AUTHENTICATION_NONE);
+ g_signal_handlers_disconnect_by_data(kHttpsServer->soupServer(), this);
+ }
+
+ void authenticate(WebKitAuthenticationRequest* request)
+ {
+ assertObjectIsDeletedWhenTestFinishes(G_OBJECT(request));
+ m_authenticationRequest = request;
+ g_main_loop_quit(m_mainLoop);
+ }
+
+ bool acceptCertificate(GTlsCertificateFlags errors)
+ {
+ if (m_rejectClientCertificates)
+ return false;
+
+ // We always expect errors because we are using a self-signed certificate,
+ // but only G_TLS_CERTIFICATE_UNKNOWN_CA flags should be present.
+ return !errors || errors == G_TLS_CERTIFICATE_UNKNOWN_CA;
+ }
+
+ WebKitAuthenticationRequest* waitForAuthenticationRequest()
+ {
+ m_authenticationRequest = nullptr;
+ g_main_loop_run(m_mainLoop);
+ return m_authenticationRequest.get();
+ }
+
+ GRefPtr<WebKitAuthenticationRequest> m_authenticationRequest;
+ GRefPtr<GTlsCertificate> m_clientCertificate;
+ bool m_rejectClientCertificates { false };
+};
+
+static void testClientSideCertificate(ClientSideCertificateTest* test, gconstpointer)
+{
+ // Ignore server certificate errors.
+ auto* websiteDataManager = webkit_web_context_get_website_data_manager(test->m_webContext.get());
+ WebKitTLSErrorsPolicy originalPolicy = webkit_website_data_manager_get_tls_errors_policy(websiteDataManager);
+ webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, WEBKIT_TLS_ERRORS_POLICY_IGNORE);
+
+ // Cancel the authentiation request.
+ test->loadURI(kHttpsServer->getURIForPath("/").data());
+ auto* request = test->waitForAuthenticationRequest();
+ g_assert_cmpstr(webkit_authentication_request_get_realm(request), ==, "");
+ g_assert_cmpint(webkit_authentication_request_get_scheme(request), ==, WEBKIT_AUTHENTICATION_SCHEME_CLIENT_CERTIFICATE_REQUESTED);
+ g_assert_false(webkit_authentication_request_is_for_proxy(request));
+ g_assert_false(webkit_authentication_request_is_retry(request));
+ auto* origin = webkit_authentication_request_get_security_origin(request);
+ g_assert_nonnull(origin);
+ ASSERT_CMP_CSTRING(webkit_security_origin_get_protocol(origin), ==, kHttpsServer->baseURL().protocol().toString().utf8());
+ ASSERT_CMP_CSTRING(webkit_security_origin_get_host(origin), ==, kHttpsServer->baseURL().host().toString().utf8());
+ g_assert_cmpuint(webkit_security_origin_get_port(origin), ==, kHttpsServer->port());
+ webkit_security_origin_unref(origin);
+ webkit_authentication_request_cancel(request);
+ test->waitUntilLoadFinished();
+ g_assert_cmpint(test->m_loadEvents.size(), ==, 3);
+ g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
+ g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::ProvisionalLoadFailed);
+ g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
+ g_assert_error(test->m_error.get(), WEBKIT_NETWORK_ERROR, WEBKIT_NETWORK_ERROR_CANCELLED);
+ test->m_loadEvents.clear();
+
+ // Complete the request with no credential.
+ test->loadURI(kHttpsServer->getURIForPath("/").data());
+ request = test->waitForAuthenticationRequest();
+ webkit_authentication_request_authenticate(request, nullptr);
+ test->waitUntilLoadFinished();
+ g_assert_cmpint(test->m_loadEvents.size(), ==, 3);
+ g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
+ g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::ProvisionalLoadFailed);
+ g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
+ // Sometimes glib-networking fails to report the error as certificate required and we end up
+ // with connection reset by peer because the server closes the connection.
+ if (!g_error_matches(test->m_error.get(), G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
+ g_assert_error(test->m_error.get(), G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED);
+ test->m_loadEvents.clear();
+
+ // Complete the request with a credential with no certificate.
+ test->loadURI(kHttpsServer->getURIForPath("/").data());
+ request = test->waitForAuthenticationRequest();
+ WebKitCredential* credential = webkit_credential_new_for_certificate(nullptr, WEBKIT_CREDENTIAL_PERSISTENCE_NONE);
+ webkit_authentication_request_authenticate(request, credential);
+ webkit_credential_free(credential);
+ test->waitUntilLoadFinished();
+ g_assert_cmpint(test->m_loadEvents.size(), ==, 3);
+ g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
+ g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::ProvisionalLoadFailed);
+ g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
+ if (!g_error_matches(test->m_error.get(), G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
+ g_assert_error(test->m_error.get(), G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED);
+ test->m_loadEvents.clear();
+
+ // Complete the request with a credential with an invalid certificate.
+ test->m_rejectClientCertificates = true;
+ test->loadURI(kHttpsServer->getURIForPath("/").data());
+ request = test->waitForAuthenticationRequest();
+ credential = webkit_credential_new_for_certificate(test->m_clientCertificate.get(), WEBKIT_CREDENTIAL_PERSISTENCE_NONE);
+ webkit_authentication_request_authenticate(request, credential);
+ webkit_credential_free(credential);
+ test->waitUntilLoadFinished();
+ g_assert_cmpint(test->m_loadEvents.size(), ==, 3);
+ g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
+ g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::ProvisionalLoadFailed);
+ g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
+ if (!g_error_matches(test->m_error.get(), G_IO_ERROR, G_IO_ERROR_CONNECTION_CLOSED))
+ g_assert_error(test->m_error.get(), G_TLS_ERROR, G_TLS_ERROR_CERTIFICATE_REQUIRED);
+ test->m_loadEvents.clear();
+ test->m_rejectClientCertificates = false;
+
+ // Complete the request with a credential with a valid certificate.
+ test->loadURI(kHttpsServer->getURIForPath("/").data());
+ request = test->waitForAuthenticationRequest();
+ credential = webkit_credential_new_for_certificate(test->m_clientCertificate.get(), WEBKIT_CREDENTIAL_PERSISTENCE_NONE);
+ webkit_authentication_request_authenticate(request, credential);
+ webkit_credential_free(credential);
+ test->waitUntilLoadFinished();
+ g_assert_cmpint(test->m_loadEvents.size(), ==, 3);
+ g_assert_cmpint(test->m_loadEvents[0], ==, LoadTrackingTest::ProvisionalLoadStarted);
+ g_assert_cmpint(test->m_loadEvents[1], ==, LoadTrackingTest::LoadCommitted);
+ g_assert_cmpint(test->m_loadEvents[2], ==, LoadTrackingTest::LoadFinished);
+ test->m_loadEvents.clear();
+
+ webkit_website_data_manager_set_tls_errors_policy(websiteDataManager, originalPolicy);
+}
+#endif
+
#if USE(SOUP2)
static void httpsServerCallback(SoupServer* server, SoupMessage* message, const char* path, GHashTable*, SoupClientContext*, gpointer)
#else
@@ -577,6 +742,9 @@
TLSErrorsTest::add("WebKitWebView", "load-failed-with-tls-errors", testLoadFailedWithTLSErrors);
WebSocketTest::add("WebKitWebView", "web-socket-tls-errors", testWebSocketTLSErrors);
EphemeralSSLTest::add("WebKitWebView", "ephemeral-tls-errors", testTLSErrorsEphemeral);
+#if !USE(SOUP2)
+ ClientSideCertificateTest::add("WebKitWebView", "client-side-certificate", testClientSideCertificate);
+#endif
}
void afterAll()
Modified: trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp (279871 => 279872)
--- trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Tools/TestWebKitAPI/Tests/WebKitGLib/WebExtensionTest.cpp 2021-07-13 14:19:38 UTC (rev 279872)
@@ -675,6 +675,9 @@
g_error("Failed to register object: %s\n", error->message);
g_object_set_data_full(G_OBJECT(userData), "dbus-connection", connection, g_object_unref);
+ g_signal_connect_object(connection, "closed", G_CALLBACK(+[](GDBusConnection*, gboolean, GError*, gpointer userData) {
+ g_object_set_data_full(G_OBJECT(userData), "dbus-connection", nullptr, nullptr);
+ }), userData, static_cast<GConnectFlags>(0));
while (delayedSignalsQueue.size()) {
DelayedSignal delayedSignal = delayedSignalsQueue.takeFirst();
switch (delayedSignal.type) {
Modified: trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.h (279871 => 279872)
--- trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.h 2021-07-13 12:54:02 UTC (rev 279871)
+++ trunk/Tools/TestWebKitAPI/glib/WebKitGLib/WebKitTestServer.h 2021-07-13 14:19:38 UTC (rev 279872)
@@ -40,6 +40,7 @@
WebKitTestServer(ServerOptions option)
: WebKitTestServer(ServerOptionsBitSet().set(option)) { }
+ SoupServer* soupServer() const { return m_soupServer.get(); }
const URL& baseURL() const { return m_baseURL; }
unsigned port() const;
CString getURIForPath(const char* path) const;