165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch/*
265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Copyright (C) 2010 Apple Inc. All rights reserved.
365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * Redistribution and use in source and binary forms, with or without
565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * modification, are permitted provided that the following conditions
665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * are met:
765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 1. Redistributions of source code must retain the above copyright
865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    notice, this list of conditions and the following disclaimer.
965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * 2. Redistributions in binary form must reproduce the above copyright
1065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    notice, this list of conditions and the following disclaimer in the
1165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *    documentation and/or other materials provided with the distribution.
1265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch *
1365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
1465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
1565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
1665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
1765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
1865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
1965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
2065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
2165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
2265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
2365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch * THE POSSIBILITY OF SUCH DAMAGE.
2465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch */
2565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
262fc2651226baac27029e38c9d6ef883fa32084dbSteve Block#include "config.h"
2765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "InjectedBundle.h"
2865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
2965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WKBundleAPICast.h"
3065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include "WKBundleInitialize.h"
312bde8e466a4451c7319e3a072d118917957d6554Steve Block#include "WebCertificateInfo.h"
322bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <WebCore/ResourceHandle.h>
3365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <WebCore/SimpleFontData.h>
342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch#include <wtf/text/CString.h>
3565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
3665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <windows.h>
3765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <winbase.h>
3865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <shlobj.h>
3965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch#include <shlwapi.h>
4065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
412bde8e466a4451c7319e3a072d118917957d6554Steve Block#if USE(CFNETWORK)
422bde8e466a4451c7319e3a072d118917957d6554Steve Block#include <WebCore/CertificateCFWin.h>
432bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
442bde8e466a4451c7319e3a072d118917957d6554Steve Block
4565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochusing namespace WebCore;
4665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochnamespace WebKit {
4865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
4965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch// FIXME: This should try and use <WebCore/FileSystem.h>.
5065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic String pathGetFileName(const String& path)
5265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
5365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return String(::PathFindFileName(String(path).charactersWithNullTermination()));
5465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
5565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
5665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochstatic String directoryName(const String& path)
5765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
5865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    String fileName = pathGetFileName(path);
5965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    String dirName = String(path);
6065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    dirName.truncate(dirName.length() - pathGetFileName(path).length());
6165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return dirName;
6265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
6365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
6465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochbool InjectedBundle::load(APIObject* initializationUserData)
6565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
6665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    WCHAR currentPath[MAX_PATH];
6765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!::GetCurrentDirectoryW(MAX_PATH, currentPath))
6865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
6965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    String directorBundleResidesIn = directoryName(m_path);
7165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!::SetCurrentDirectoryW(directorBundleResidesIn.charactersWithNullTermination()))
7265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
7365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    m_platformBundle = ::LoadLibraryExW(m_path.charactersWithNullTermination(), 0, LOAD_WITH_ALTERED_SEARCH_PATH);
7565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!m_platformBundle)
7665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
7765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
7865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    // Reset the current directory.
7965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!::SetCurrentDirectoryW(currentPath)) {
8065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
8165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    }
8265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
8365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    WKBundleInitializeFunctionPtr initializeFunction = reinterpret_cast<WKBundleInitializeFunctionPtr>(::GetProcAddress(m_platformBundle, "WKBundleInitialize"));
8465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    if (!initializeFunction)
8565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch        return false;
8665f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
8765f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    initializeFunction(toAPI(this), toAPI(initializationUserData));
8865f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    return true;
8965f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
9065f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
9165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdochvoid InjectedBundle::activateMacFontAscentHack()
9265f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch{
9365f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch    SimpleFontData::setShouldApplyMacAscentHack(true);
9465f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch}
9565f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch
962bde8e466a4451c7319e3a072d118917957d6554Steve Blockvoid InjectedBundle::setHostAllowsAnyHTTPSCertificate(const String& host)
972bde8e466a4451c7319e3a072d118917957d6554Steve Block{
982bde8e466a4451c7319e3a072d118917957d6554Steve Block#if USE(CFNETWORK)
992bde8e466a4451c7319e3a072d118917957d6554Steve Block    ResourceHandle::setHostAllowsAnyHTTPSCertificate(host);
1002bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
1012bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1022bde8e466a4451c7319e3a072d118917957d6554Steve Block
1032daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdochvoid InjectedBundle::setClientCertificate(const String& host, const String& certificateSystemStoreName, const WebCertificateInfo* certificateInfo)
1042bde8e466a4451c7319e3a072d118917957d6554Steve Block{
1052bde8e466a4451c7319e3a072d118917957d6554Steve Block#if USE(CFNETWORK)
1062daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT_ARG(certificateInfo, certificateInfo);
1072bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (!certificateInfo)
1082bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
1092bde8e466a4451c7319e3a072d118917957d6554Steve Block
1102bde8e466a4451c7319e3a072d118917957d6554Steve Block    const Vector<PCCERT_CONTEXT> certificateChain = certificateInfo->platformCertificateInfo().certificateChain();
1112bde8e466a4451c7319e3a072d118917957d6554Steve Block    ASSERT(certificateChain.size() == 1);
1122bde8e466a4451c7319e3a072d118917957d6554Steve Block    if (certificateChain.size() != 1)
1132bde8e466a4451c7319e3a072d118917957d6554Steve Block        return;
1142bde8e466a4451c7319e3a072d118917957d6554Steve Block
1152daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ASSERT_ARG(certificateSystemStoreName, !certificateSystemStoreName.isEmpty());
1162daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (certificateSystemStoreName.isEmpty())
1172daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return;
1182daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1192daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // The PCCERT_CONTEXT in the WebCertificateInfo we created using the message from the UI process doesn't contain enough information
1202daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // to actually use it in a request, we need to get the real certificate from the certificate store (which is typically the "MY" store).
1212daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    String mutableCertificateSystemStoreName = certificateSystemStoreName;
1222daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    HCERTSTORE certStore = ::CertOpenSystemStore(0, mutableCertificateSystemStoreName.charactersWithNullTermination());
1232daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!certStore) {
1242daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        LOG_ERROR("Could not open system certificate store %s", certificateSystemStoreName.ascii().data());
1252daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return;
1262daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
1272daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1282daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    PCCERT_CONTEXT realCert = ::CertFindCertificateInStore(certStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0, CERT_FIND_EXISTING, certificateChain.first(), 0);
1292daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    if (!realCert) {
1302daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        LOG_ERROR("Could not find certificate in system certificate store");
1312daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch        return;
1322daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    }
1332daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1342daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    ResourceHandle::setClientCertificate(host, WebCore::copyCertificateToData(realCert).get());
1352daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    CertFreeCertificateContext(realCert);
1362daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch
1372daae5fd11344eaa88a0d92b0f6d65f8d2255c00Ben Murdoch    // We can't close certStore here, since the certificate is still in use.
1382bde8e466a4451c7319e3a072d118917957d6554Steve Block#endif
1392bde8e466a4451c7319e3a072d118917957d6554Steve Block}
1402bde8e466a4451c7319e3a072d118917957d6554Steve Block
14165f03d4f644ce73618e5f4f50dd694b26f55ae12Ben Murdoch} // namespace WebKit
142