• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
pathGetFileName(const String & path)51 static String pathGetFileName(const String& path)
52 {
53     return String(::PathFindFileName(String(path).charactersWithNullTermination()));
54 }
55 
directoryName(const String & path)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 
load(APIObject * initializationUserData)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 
activateMacFontAscentHack()91 void InjectedBundle::activateMacFontAscentHack()
92 {
93     SimpleFontData::setShouldApplyMacAscentHack(true);
94 }
95 
setHostAllowsAnyHTTPSCertificate(const String & host)96 void InjectedBundle::setHostAllowsAnyHTTPSCertificate(const String& host)
97 {
98 #if USE(CFNETWORK)
99     ResourceHandle::setHostAllowsAnyHTTPSCertificate(host);
100 #endif
101 }
102 
setClientCertificate(const String & host,const String & certificateSystemStoreName,const WebCertificateInfo * certificateInfo)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