void NetworkStorageSession::saveCredentialToPersistentStorage(const ProtectionSpace& protectionSpace, const Credential& credential) { #if USE(LIBSECRET) if (m_sessionID.isEphemeral()) return; if (credential.isEmpty()) return; const String& realm = protectionSpace.realm(); if (realm.isEmpty()) return; GRefPtr<GHashTable> attributes = adoptGRef(secret_attributes_build(SECRET_SCHEMA_COMPAT_NETWORK, "domain", realm.utf8().data(), "server", protectionSpace.host().utf8().data(), "port", protectionSpace.port(), "protocol", schemeFromProtectionSpaceServerType(protectionSpace.serverType()), "authtype", authTypeFromProtectionSpaceAuthenticationScheme(protectionSpace.authenticationScheme()), nullptr)); if (!attributes) return; g_hash_table_insert(attributes.get(), g_strdup("user"), g_strdup(credential.user().utf8().data())); CString utf8Password = credential.password().utf8(); GRefPtr<SecretValue> newSecretValue = adoptGRef(secret_value_new(utf8Password.data(), utf8Password.length(), "text/plain")); secret_service_store(nullptr, SECRET_SCHEMA_COMPAT_NETWORK, attributes.get(), SECRET_COLLECTION_DEFAULT, _("WebKitGTK+ password"), newSecretValue.get(), nullptr, nullptr, nullptr); #else UNUSED_PARAM(protectionSpace); UNUSED_PARAM(credential); #endif }
void protectionSpaceToPlatformAuth(const ProtectionSpace& protectionSpace, NetworkRequest::AuthType& authType, NetworkRequest::AuthProtocol& authProtocol, NetworkRequest::AuthScheme& authScheme) { authScheme = NetworkRequest::AuthSchemeNone; switch (protectionSpace.authenticationScheme()) { case ProtectionSpaceAuthenticationSchemeDefault: authScheme = NetworkRequest::AuthSchemeDefault; break; case ProtectionSpaceAuthenticationSchemeHTTPBasic: authScheme = NetworkRequest::AuthSchemeHTTPBasic; break; case ProtectionSpaceAuthenticationSchemeHTTPDigest: authScheme = NetworkRequest::AuthSchemeHTTPDigest; break; case ProtectionSpaceAuthenticationSchemeNegotiate: authScheme = NetworkRequest::AuthSchemeNegotiate; break; case ProtectionSpaceAuthenticationSchemeNTLM: authScheme = NetworkRequest::AuthSchemeNTLM; break; default: ASSERT_NOT_REACHED(); break; } authType = NetworkRequest::AuthTypeNone; authProtocol = NetworkRequest::AuthProtocolNone; switch (protectionSpace.serverType()) { case ProtectionSpaceServerHTTP: authType = NetworkRequest::AuthTypeHost; authProtocol = NetworkRequest::AuthProtocolHTTP; break; case ProtectionSpaceServerHTTPS: authType = NetworkRequest::AuthTypeHost; authProtocol = NetworkRequest::AuthProtocolHTTPS; break; case ProtectionSpaceServerFTP: authType = NetworkRequest::AuthTypeHost; authProtocol = NetworkRequest::AuthProtocolFTP; break; case ProtectionSpaceServerFTPS: authType = NetworkRequest::AuthTypeHost; authProtocol = NetworkRequest::AuthProtocolFTPS; break; case ProtectionSpaceProxyHTTP: authType = NetworkRequest::AuthTypeProxy; authProtocol = NetworkRequest::AuthProtocolHTTP; break; case ProtectionSpaceProxyHTTPS: authType = NetworkRequest::AuthTypeProxy; authProtocol = NetworkRequest::AuthProtocolHTTPS; break; case ProtectionSpaceProxyFTP: authType = NetworkRequest::AuthTypeProxy; authProtocol = NetworkRequest::AuthProtocolFTP; break; default: ASSERT_NOT_REACHED(); break; } }
void ArgumentCoder<ProtectionSpace>::encode(ArgumentEncoder* encoder, const ProtectionSpace& space) { encoder->encode(space.host()); encoder->encode(space.port()); encoder->encodeEnum(space.serverType()); encoder->encode(space.realm()); encoder->encodeEnum(space.authenticationScheme()); }
Boolean SynchronousResourceHandleCFURLConnectionDelegate::canRespondToProtectionSpace(CFURLProtectionSpaceRef protectionSpace) { ASSERT(m_handle); LOG(Network, "CFNet - SynchronousResourceHandleCFURLConnectionDelegate::canRespondToProtectionSpace(handle=%p (%s)", m_handle, m_handle->firstRequest().url().string().utf8().data()); #if PLATFORM(IOS) ProtectionSpace coreProtectionSpace = ProtectionSpace(protectionSpace); if (coreProtectionSpace.authenticationScheme() == ProtectionSpaceAuthenticationSchemeUnknown) return false; return m_handle->canAuthenticateAgainstProtectionSpace(coreProtectionSpace); #else return m_handle->canAuthenticateAgainstProtectionSpace(core(protectionSpace)); #endif }
void CredentialStorage::set(const Credential& credential, const ProtectionSpace& protectionSpace, const KURL& url) { ASSERT(protectionSpace.isProxy() || url.protocolIsInHTTPFamily()); ASSERT(protectionSpace.isProxy() || url.isValid()); protectionSpaceToCredentialMap().set(protectionSpace, credential); if (!protectionSpace.isProxy()) { originsWithCredentials().add(originStringFromURL(url)); ProtectionSpaceAuthenticationScheme scheme = protectionSpace.authenticationScheme(); if (scheme == ProtectionSpaceAuthenticationSchemeHTTPBasic || scheme == ProtectionSpaceAuthenticationSchemeDefault) { // The map can contain both a path and its subpath - while redundant, this makes lookups faster. pathToDefaultProtectionSpaceMap().set(protectionSpaceMapKeyFromURL(url), protectionSpace); } } }
void NetworkLoad::canAuthenticateAgainstProtectionSpaceAsync(ResourceHandle* handle, const ProtectionSpace& protectionSpace) { ASSERT(RunLoop::isMain()); ASSERT_UNUSED(handle, handle == m_handle); // Handle server trust evaluation at platform-level if requested, for performance reasons. if (protectionSpace.authenticationScheme() == ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested && !NetworkProcess::singleton().canHandleHTTPSServerTrustEvaluation()) { continueCanAuthenticateAgainstProtectionSpace(false); return; } m_client.canAuthenticateAgainstProtectionSpaceAsync(protectionSpace); }
void NetworkResourceLoader::canAuthenticateAgainstProtectionSpaceAsync(ResourceHandle* handle, const ProtectionSpace& protectionSpace) { ASSERT(RunLoop::isMain()); ASSERT_UNUSED(handle, handle == m_handle); // Handle server trust evaluation at platform-level if requested, for performance reasons. if (protectionSpace.authenticationScheme() == ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested && !NetworkProcess::shared().canHandleHTTPSServerTrustEvaluation()) { continueCanAuthenticateAgainstProtectionSpace(false); return; } if (isSynchronous()) { // FIXME: We should ask the WebProcess like the asynchronous case below does. // This is currently impossible as the WebProcess is blocked waiting on this synchronous load. // It's possible that we can jump straight to the UI process to resolve this. continueCanAuthenticateAgainstProtectionSpace(true); return; } sendAbortingOnFailure(Messages::WebResourceLoader::CanAuthenticateAgainstProtectionSpace(protectionSpace)); }
void NetworkJob::notifyChallengeResult(const KURL& url, const ProtectionSpace& protectionSpace, AuthenticationChallengeResult result, const Credential& credential) { ASSERT(url.isValid()); ASSERT(url == m_response.url()); ASSERT(!protectionSpace.host().isEmpty()); if (m_isAuthenticationChallenging) { m_isAuthenticationChallenging = false; if (result == AuthenticationChallengeSuccess) cancelJob(); updateDeferLoadingCount(-1); } if (result != AuthenticationChallengeSuccess) return; if (m_handle->getInternal()->m_currentWebChallenge.isNull()) m_handle->getInternal()->m_currentWebChallenge = AuthenticationChallenge(protectionSpace, credential, 0, m_response, ResourceError()); ResourceRequest newRequest = m_handle->firstRequest(); newRequest.setURL(url); newRequest.setMustHandleInternally(true); m_newJobWithCredentialsStarted = startNewJobWithRequest(newRequest); }
void CredentialStorage::set(const Credential& credential, const ProtectionSpace& protectionSpace, const URL& url) { ASSERT(protectionSpace.isProxy() || protectionSpace.authenticationScheme() == ProtectionSpaceAuthenticationSchemeClientCertificateRequested || url.protocolIsInHTTPFamily()); ASSERT(protectionSpace.isProxy() || protectionSpace.authenticationScheme() == ProtectionSpaceAuthenticationSchemeClientCertificateRequested || url.isValid()); m_protectionSpaceToCredentialMap.set(protectionSpace, credential); #if PLATFORM(IOS) if (protectionSpace.authenticationScheme() != ProtectionSpaceAuthenticationSchemeClientCertificateRequested) saveToPersistentStorage(protectionSpace, credential); #endif if (!protectionSpace.isProxy() && protectionSpace.authenticationScheme() != ProtectionSpaceAuthenticationSchemeClientCertificateRequested) { m_originsWithCredentials.add(originStringFromURL(url)); ProtectionSpaceAuthenticationScheme scheme = protectionSpace.authenticationScheme(); if (scheme == ProtectionSpaceAuthenticationSchemeHTTPBasic || scheme == ProtectionSpaceAuthenticationSchemeDefault) { // The map can contain both a path and its subpath - while redundant, this makes lookups faster. m_pathToDefaultProtectionSpaceMap.set(protectionSpaceMapKeyFromURL(url), protectionSpace); } } }
CFURLProtectionSpaceRef createCF(const ProtectionSpace& coreSpace) { CFURLProtectionSpaceServerType serverType = kCFURLProtectionSpaceServerHTTP; switch (coreSpace.serverType()) { case ProtectionSpaceServerHTTP: serverType = kCFURLProtectionSpaceServerHTTP; break; case ProtectionSpaceServerHTTPS: serverType = kCFURLProtectionSpaceServerHTTPS; break; case ProtectionSpaceServerFTP: serverType = kCFURLProtectionSpaceServerFTP; break; case ProtectionSpaceServerFTPS: serverType = kCFURLProtectionSpaceServerFTPS; break; case ProtectionSpaceProxyHTTP: serverType = kCFURLProtectionSpaceProxyHTTP; break; case ProtectionSpaceProxyHTTPS: serverType = kCFURLProtectionSpaceProxyHTTPS; break; case ProtectionSpaceProxyFTP: serverType = kCFURLProtectionSpaceProxyFTP; break; case ProtectionSpaceProxySOCKS: serverType = kCFURLProtectionSpaceProxySOCKS; break; default: ASSERT_NOT_REACHED(); } CFURLProtectionSpaceAuthenticationScheme scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault; switch (coreSpace.authenticationScheme()) { case ProtectionSpaceAuthenticationSchemeDefault: scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault; break; case ProtectionSpaceAuthenticationSchemeHTTPBasic: scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPBasic; break; case ProtectionSpaceAuthenticationSchemeHTTPDigest: scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPDigest; break; case ProtectionSpaceAuthenticationSchemeHTMLForm: scheme = kCFURLProtectionSpaceAuthenticationSchemeHTMLForm; break; case ProtectionSpaceAuthenticationSchemeNTLM: scheme = kCFURLProtectionSpaceAuthenticationSchemeNTLM; break; case ProtectionSpaceAuthenticationSchemeNegotiate: scheme = kCFURLProtectionSpaceAuthenticationSchemeNegotiate; break; default: ASSERT_NOT_REACHED(); } CFStringRef host = coreSpace.host().createCFString(); CFStringRef realm = coreSpace.realm().createCFString(); CFURLProtectionSpaceRef result = CFURLProtectionSpaceCreate(0, host, coreSpace.port(), serverType, realm, scheme); CFRelease(host); CFRelease(realm); return result; }
bool operator==(const ProtectionSpace& a, const ProtectionSpace& b) { if (a.host() != b.host()) return false; if (a.port() != b.port()) return false; if (a.serverType() != b.serverType()) return false; // Ignore realm for proxies if (!a.isProxy() && a.realm() != b.realm()) return false; if (a.authenticationScheme() != b.authenticationScheme()) return false; return true; }
CFURLProtectionSpaceRef createCF(const ProtectionSpace& coreSpace) { CFURLProtectionSpaceServerType serverType = kCFURLProtectionSpaceServerHTTP; switch (coreSpace.serverType()) { case ProtectionSpaceServerHTTP: serverType = kCFURLProtectionSpaceServerHTTP; break; case ProtectionSpaceServerHTTPS: serverType = kCFURLProtectionSpaceServerHTTPS; break; case ProtectionSpaceServerFTP: serverType = kCFURLProtectionSpaceServerFTP; break; case ProtectionSpaceServerFTPS: serverType = kCFURLProtectionSpaceServerFTPS; break; case ProtectionSpaceProxyHTTP: serverType = kCFURLProtectionSpaceProxyHTTP; break; case ProtectionSpaceProxyHTTPS: serverType = kCFURLProtectionSpaceProxyHTTPS; break; case ProtectionSpaceProxyFTP: serverType = kCFURLProtectionSpaceProxyFTP; break; case ProtectionSpaceProxySOCKS: serverType = kCFURLProtectionSpaceProxySOCKS; break; default: ASSERT_NOT_REACHED(); } CFURLProtectionSpaceAuthenticationScheme scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault; switch (coreSpace.authenticationScheme()) { case ProtectionSpaceAuthenticationSchemeDefault: scheme = kCFURLProtectionSpaceAuthenticationSchemeDefault; break; case ProtectionSpaceAuthenticationSchemeHTTPBasic: scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPBasic; break; case ProtectionSpaceAuthenticationSchemeHTTPDigest: scheme = kCFURLProtectionSpaceAuthenticationSchemeHTTPDigest; break; case ProtectionSpaceAuthenticationSchemeHTMLForm: scheme = kCFURLProtectionSpaceAuthenticationSchemeHTMLForm; break; case ProtectionSpaceAuthenticationSchemeNTLM: scheme = kCFURLProtectionSpaceAuthenticationSchemeNTLM; break; case ProtectionSpaceAuthenticationSchemeNegotiate: scheme = kCFURLProtectionSpaceAuthenticationSchemeNegotiate; break; #if USE(PROTECTION_SPACE_AUTH_CALLBACK) case ProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested: scheme = kCFURLProtectionSpaceAuthenticationSchemeServerTrustEvaluationRequested; break; case ProtectionSpaceAuthenticationSchemeClientCertificateRequested: scheme = kCFURLProtectionSpaceAuthenticationSchemeClientCertificateRequested; break; #endif default: ASSERT_NOT_REACHED(); } CFStringRef host = coreSpace.host().createCFString(); CFStringRef realm = coreSpace.realm().createCFString(); CFURLProtectionSpaceRef result = CFURLProtectionSpaceCreate(0, host, coreSpace.port(), serverType, realm, scheme); CFRelease(host); CFRelease(realm); return result; }
void NetworkStorageSession::getCredentialFromPersistentStorage(const ProtectionSpace& protectionSpace, Function<void (Credential&&)> completionHandler) { #if USE(LIBSECRET) if (m_sessionID.isEphemeral()) { completionHandler({ }); return; } const String& realm = protectionSpace.realm(); if (realm.isEmpty()) { completionHandler({ }); return; } GRefPtr<GHashTable> attributes = adoptGRef(secret_attributes_build(SECRET_SCHEMA_COMPAT_NETWORK, "domain", realm.utf8().data(), "server", protectionSpace.host().utf8().data(), "port", protectionSpace.port(), "protocol", schemeFromProtectionSpaceServerType(protectionSpace.serverType()), "authtype", authTypeFromProtectionSpaceAuthenticationScheme(protectionSpace.authenticationScheme()), nullptr)); if (!attributes) { completionHandler({ }); return; } m_persisentStorageCancellable = adoptGRef(g_cancellable_new()); m_persisentStorageCompletionHandler = WTFMove(completionHandler); secret_service_search(nullptr, SECRET_SCHEMA_COMPAT_NETWORK, attributes.get(), static_cast<SecretSearchFlags>(SECRET_SEARCH_UNLOCK | SECRET_SEARCH_LOAD_SECRETS), m_persisentStorageCancellable.get(), [](GObject* source, GAsyncResult* result, gpointer userData) { GUniqueOutPtr<GError> error; GUniquePtr<GList> elements(secret_service_search_finish(SECRET_SERVICE(source), result, &error.outPtr())); if (g_error_matches (error.get(), G_IO_ERROR, G_IO_ERROR_CANCELLED)) return; NetworkStorageSession* session = static_cast<NetworkStorageSession*>(userData); auto completionHandler = std::exchange(session->m_persisentStorageCompletionHandler, nullptr); if (error || !elements || !elements->data) { completionHandler({ }); return; } GRefPtr<SecretItem> secretItem = adoptGRef(static_cast<SecretItem*>(elements->data)); GRefPtr<GHashTable> attributes = adoptGRef(secret_item_get_attributes(secretItem.get())); String user = String::fromUTF8(static_cast<const char*>(g_hash_table_lookup(attributes.get(), "user"))); if (user.isEmpty()) { completionHandler({ }); return; } size_t length; GRefPtr<SecretValue> secretValue = adoptGRef(secret_item_get_secret(secretItem.get())); const char* passwordData = secret_value_get(secretValue.get(), &length); completionHandler(Credential(user, String::fromUTF8(passwordData, length), CredentialPersistencePermanent)); }, this); #else UNUSED_PARAM(protectionSpace); completionHandler({ }); #endif }