1 /* 2 * Copyright (C) 2010 Apple Inc. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' 14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS 17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 23 * THE POSSIBILITY OF SUCH DAMAGE. 24 */ 25 26 #include "config.h" 27 #include "InjectedBundle.h" 28 29 #include "WKBundleAPICast.h" 30 #include "WKBundleInitialize.h" 31 #include "WebCertificateInfo.h" 32 #include <WebCore/ResourceHandle.h> 33 #include <WebCore/SimpleFontData.h> 34 #include <wtf/text/CString.h> 35 36 #include <windows.h> 37 #include <winbase.h> 38 #include <shlobj.h> 39 #include <shlwapi.h> 40 41 #if USE(CFNETWORK) 42 #include <WebCore/CertificateCFWin.h> 43 #endif 44 45 using namespace WebCore; 46 47 namespace WebKit { 48 49 // FIXME: This should try and use <WebCore/FileSystem.h>. 50 51 static String pathGetFileName(const String& path) 52 { 53 return String(::PathFindFileName(String(path).charactersWithNullTermination())); 54 } 55 56 static String directoryName(const String& path) 57 { 58 String fileName = pathGetFileName(path); 59 String dirName = String(path); 60 dirName.truncate(dirName.length() - pathGetFileName(path).length()); 61 return dirName; 62 } 63 64 bool InjectedBundle::load(APIObject* initializationUserData) 65 { 66 WCHAR currentPath[MAX_PATH]; 67 if (!::GetCurrentDirectoryW(MAX_PATH, currentPath)) 68 return false; 69 70 String directorBundleResidesIn = directoryName(m_path); 71 if (!::SetCurrentDirectoryW(directorBundleResidesIn.charactersWithNullTermination())) 72 return false; 73 74 m_platformBundle = ::LoadLibraryExW(m_path.charactersWithNullTermination(), 0, LOAD_WITH_ALTERED_SEARCH_PATH); 75 if (!m_platformBundle) 76 return false; 77 78 // Reset the current directory. 79 if (!::SetCurrentDirectoryW(currentPath)) { 80 return false; 81 } 82 83 WKBundleInitializeFunctionPtr initializeFunction = reinterpret_cast<WKBundleInitializeFunctionPtr>(::GetProcAddress(m_platformBundle, "WKBundleInitialize")); 84 if (!initializeFunction) 85 return false; 86 87 initializeFunction(toAPI(this), toAPI(initializationUserData)); 88 return true; 89 } 90 91 void InjectedBundle::activateMacFontAscentHack() 92 { 93 SimpleFontData::setShouldApplyMacAscentHack(true); 94 } 95 96 void InjectedBundle::setHostAllowsAnyHTTPSCertificate(const String& host) 97 { 98 #if USE(CFNETWORK) 99 ResourceHandle::setHostAllowsAnyHTTPSCertificate(host); 100 #endif 101 } 102 103 void InjectedBundle::setClientCertificate(const String& host, const String& certificateSystemStoreName, const WebCertificateInfo* certificateInfo) 104 { 105 #if USE(CFNETWORK) 106 ASSERT_ARG(certificateInfo, certificateInfo); 107 if (!certificateInfo) 108 return; 109 110 const Vector<PCCERT_CONTEXT> certificateChain = certificateInfo->platformCertificateInfo().certificateChain(); 111 ASSERT(certificateChain.size() == 1); 112 if (certificateChain.size() != 1) 113 return; 114 115 ASSERT_ARG(certificateSystemStoreName, !certificateSystemStoreName.isEmpty()); 116 if (certificateSystemStoreName.isEmpty()) 117 return; 118 119 // The PCCERT_CONTEXT in the WebCertificateInfo we created using the message from the UI process doesn't contain enough information 120 // to actually use it in a request, we need to get the real certificate from the certificate store (which is typically the "MY" store). 121 String mutableCertificateSystemStoreName = certificateSystemStoreName; 122 HCERTSTORE certStore = ::CertOpenSystemStore(0, mutableCertificateSystemStoreName.charactersWithNullTermination()); 123 if (!certStore) { 124 LOG_ERROR("Could not open system certificate store %s", certificateSystemStoreName.ascii().data()); 125 return; 126 } 127 128 PCCERT_CONTEXT realCert = ::CertFindCertificateInStore(certStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_EXISTING, certificateChain.first(), 0); 129 if (!realCert) { 130 LOG_ERROR("Could not find certificate in system certificate store"); 131 return; 132 } 133 134 ResourceHandle::setClientCertificate(host, WebCore::copyCertificateToData(realCert).get()); 135 CertFreeCertificateContext(realCert); 136 137 // We can't close certStore here, since the certificate is still in use. 138 #endif 139 } 140 141 } // namespace WebKit 142