Home | History | Annotate | Download | only in win
      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