mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-30 08:12:05 +00:00
Bug 1124076 - Properly detect certs when loaded and prompt to import them. r=sworkman/dkeeler
--HG-- extra : rebase_source : 00240091ae66180390a76a9613a4215cf591401d
This commit is contained in:
parent
5841b01411
commit
3a94be560c
@ -38,6 +38,7 @@
|
||||
#include "mozilla/dom/asmjscache/AsmJSCache.h"
|
||||
#include "mozilla/dom/asmjscache/PAsmJSCacheEntryChild.h"
|
||||
#include "mozilla/dom/nsIContentChild.h"
|
||||
#include "mozilla/psm/PSMContentListener.h"
|
||||
#include "mozilla/hal_sandbox/PHalChild.h"
|
||||
#include "mozilla/ipc/BackgroundChild.h"
|
||||
#include "mozilla/ipc/FileDescriptorSetChild.h"
|
||||
@ -203,6 +204,7 @@ using namespace mozilla::ipc;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::net;
|
||||
using namespace mozilla::jsipc;
|
||||
using namespace mozilla::psm;
|
||||
using namespace mozilla::widget;
|
||||
#if defined(MOZ_WIDGET_GONK)
|
||||
using namespace mozilla::system;
|
||||
@ -1623,6 +1625,22 @@ ContentChild::DeallocPScreenManagerChild(PScreenManagerChild* aService)
|
||||
return true;
|
||||
}
|
||||
|
||||
PPSMContentDownloaderChild*
|
||||
ContentChild::AllocPPSMContentDownloaderChild(const uint32_t& aCertType)
|
||||
{
|
||||
// NB: We don't need aCertType in the child actor.
|
||||
nsRefPtr<PSMContentDownloaderChild> child = new PSMContentDownloaderChild();
|
||||
return child.forget().take();
|
||||
}
|
||||
|
||||
bool
|
||||
ContentChild::DeallocPPSMContentDownloaderChild(PPSMContentDownloaderChild* aListener)
|
||||
{
|
||||
auto* listener = static_cast<PSMContentDownloaderChild*>(aListener);
|
||||
nsRefPtr<PSMContentDownloaderChild> child = dont_AddRef(listener);
|
||||
return true;
|
||||
}
|
||||
|
||||
PExternalHelperAppChild*
|
||||
ContentChild::AllocPExternalHelperAppChild(const OptionalURIParams& uri,
|
||||
const nsCString& aMimeContentType,
|
||||
|
@ -232,6 +232,10 @@ public:
|
||||
bool* aSuccess) override;
|
||||
virtual bool DeallocPScreenManagerChild(PScreenManagerChild*) override;
|
||||
|
||||
virtual PPSMContentDownloaderChild* AllocPPSMContentDownloaderChild(
|
||||
const uint32_t& aCertType) override;
|
||||
virtual bool DeallocPPSMContentDownloaderChild(PPSMContentDownloaderChild* aDownloader) override;
|
||||
|
||||
virtual PExternalHelperAppChild *AllocPExternalHelperAppChild(
|
||||
const OptionalURIParams& uri,
|
||||
const nsCString& aMimeContentType,
|
||||
|
@ -156,6 +156,7 @@
|
||||
#include "prio.h"
|
||||
#include "private/pprio.h"
|
||||
#include "ContentProcessManager.h"
|
||||
#include "mozilla/psm/PSMContentListener.h"
|
||||
|
||||
#include "nsIBidiKeyboard.h"
|
||||
|
||||
@ -249,6 +250,7 @@ using namespace mozilla::ipc;
|
||||
using namespace mozilla::layers;
|
||||
using namespace mozilla::net;
|
||||
using namespace mozilla::jsipc;
|
||||
using namespace mozilla::psm;
|
||||
using namespace mozilla::widget;
|
||||
|
||||
#ifdef ENABLE_TESTS
|
||||
@ -3665,6 +3667,22 @@ ContentParent::DeallocPScreenManagerParent(PScreenManagerParent* aActor)
|
||||
return true;
|
||||
}
|
||||
|
||||
PPSMContentDownloaderParent*
|
||||
ContentParent::AllocPPSMContentDownloaderParent(const uint32_t& aCertType)
|
||||
{
|
||||
nsRefPtr<PSMContentDownloaderParent> downloader =
|
||||
new PSMContentDownloaderParent(aCertType);
|
||||
return downloader.forget().take();
|
||||
}
|
||||
|
||||
bool
|
||||
ContentParent::DeallocPPSMContentDownloaderParent(PPSMContentDownloaderParent* aListener)
|
||||
{
|
||||
auto* listener = static_cast<PSMContentDownloaderParent*>(aListener);
|
||||
nsRefPtr<PSMContentDownloaderParent> downloader = dont_AddRef(listener);
|
||||
return true;
|
||||
}
|
||||
|
||||
PExternalHelperAppParent*
|
||||
ContentParent::AllocPExternalHelperAppParent(const OptionalURIParams& uri,
|
||||
const nsCString& aMimeContentType,
|
||||
|
@ -606,6 +606,10 @@ private:
|
||||
|
||||
virtual bool DeallocPNeckoParent(PNeckoParent* necko) override;
|
||||
|
||||
virtual PPSMContentDownloaderParent* AllocPPSMContentDownloaderParent(
|
||||
const uint32_t& aCertType) override;
|
||||
virtual bool DeallocPPSMContentDownloaderParent(PPSMContentDownloaderParent* aDownloader) override;
|
||||
|
||||
virtual PExternalHelperAppParent* AllocPExternalHelperAppParent(
|
||||
const OptionalURIParams& aUri,
|
||||
const nsCString& aMimeContentType,
|
||||
|
@ -16,6 +16,7 @@ include protocol PContentPermissionRequest;
|
||||
include protocol PCycleCollectWithLogs;
|
||||
include protocol PCrashReporter;
|
||||
include protocol PDocAccessible;
|
||||
include protocol PPSMContentDownloader;
|
||||
include protocol PExternalHelperApp;
|
||||
include protocol PDeviceStorageRequest;
|
||||
include protocol PFileDescriptorSet;
|
||||
@ -388,6 +389,7 @@ prio(normal upto urgent) sync protocol PContent
|
||||
manages PDocAccessible;
|
||||
manages PDeviceStorageRequest;
|
||||
manages PFileSystemRequest;
|
||||
manages PPSMContentDownloader;
|
||||
manages PExternalHelperApp;
|
||||
manages PFileDescriptorSet;
|
||||
manages PFMRadio;
|
||||
@ -756,6 +758,8 @@ parent:
|
||||
|
||||
CloseAlert(nsString name, Principal principal);
|
||||
|
||||
PPSMContentDownloader(uint32_t aCertType);
|
||||
|
||||
PExternalHelperApp(OptionalURIParams uri,
|
||||
nsCString aMimeContentType,
|
||||
nsCString aContentDisposition,
|
||||
|
28
security/manager/ssl/src/PPSMContentDownloader.ipdl
Normal file
28
security/manager/ssl/src/PPSMContentDownloader.ipdl
Normal file
@ -0,0 +1,28 @@
|
||||
/* vim: set sw=2 sts=2 ts=2 et tw=80 ft=cpp: */
|
||||
/* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
||||
|
||||
include protocol PContent;
|
||||
include protocol PChannelDiverter;
|
||||
|
||||
namespace mozilla {
|
||||
namespace psm {
|
||||
|
||||
protocol PPSMContentDownloader
|
||||
{
|
||||
manager PContent;
|
||||
|
||||
parent:
|
||||
OnStartRequest(uint32_t contentLength);
|
||||
OnDataAvailable(nsCString data, uint64_t offset, uint32_t count);
|
||||
OnStopRequest(nsresult code);
|
||||
|
||||
DivertToParentUsing(PChannelDiverter diverter);
|
||||
|
||||
child:
|
||||
__delete__();
|
||||
};
|
||||
|
||||
} // namespace psm
|
||||
} // namespace mozilla
|
@ -1,4 +1,5 @@
|
||||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* vim: set sw=2 sts=2 ts=2 et tw=80:
|
||||
*
|
||||
* This Source Code Form is subject to the terms of the Mozilla Public
|
||||
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
||||
@ -6,16 +7,22 @@
|
||||
|
||||
#include "PSMContentListener.h"
|
||||
|
||||
#include "nsIDivertableChannel.h"
|
||||
#include "nsIStreamListener.h"
|
||||
#include "nsIX509CertDB.h"
|
||||
#include "nsIXULAppInfo.h"
|
||||
|
||||
#include "mozilla/Casting.h"
|
||||
#include "mozilla/Services.h"
|
||||
#include "mozilla/unused.h"
|
||||
|
||||
#include "mozilla/dom/ContentChild.h"
|
||||
#include "mozilla/net/ChannelDiverterParent.h"
|
||||
#include "mozilla/net/ChannelDiverterChild.h"
|
||||
|
||||
#include "nsCRT.h"
|
||||
#include "nsNetUtil.h"
|
||||
#include "nsNSSHelper.h"
|
||||
#include "nsNSSShutDown.h"
|
||||
|
||||
#include "prlog.h"
|
||||
|
||||
@ -27,139 +34,158 @@ namespace mozilla { namespace psm {
|
||||
|
||||
namespace {
|
||||
|
||||
class PSMContentDownloader : public nsIStreamListener
|
||||
{
|
||||
public:
|
||||
PSMContentDownloader() {NS_ASSERTION(false, "don't use this constructor."); }
|
||||
explicit PSMContentDownloader(uint32_t type);
|
||||
void setSilentDownload(bool flag);
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
enum {UNKNOWN_TYPE = 0};
|
||||
enum {X509_CA_CERT = 1};
|
||||
enum {X509_USER_CERT = 2};
|
||||
enum {X509_EMAIL_CERT = 3};
|
||||
enum {X509_SERVER_CERT = 4};
|
||||
|
||||
protected:
|
||||
virtual ~PSMContentDownloader();
|
||||
|
||||
char* mByteData;
|
||||
int32_t mBufferOffset;
|
||||
int32_t mBufferSize;
|
||||
uint32_t mType;
|
||||
nsCOMPtr<nsIURI> mURI;
|
||||
};
|
||||
|
||||
PSMContentDownloader::PSMContentDownloader(uint32_t type)
|
||||
: mByteData(nullptr),
|
||||
mType(type)
|
||||
{
|
||||
}
|
||||
|
||||
PSMContentDownloader::~PSMContentDownloader()
|
||||
{
|
||||
if (mByteData)
|
||||
free(mByteData);
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(PSMContentDownloader, nsIStreamListener, nsIRequestObserver)
|
||||
|
||||
const int32_t kDefaultCertAllocLength = 2048;
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentDownloader::OnStartRequest(nsIRequest* request, nsISupports* context)
|
||||
{
|
||||
nsresult rv;
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnStartRequest\n"));
|
||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
|
||||
if (!channel) return NS_ERROR_FAILURE;
|
||||
enum {
|
||||
UNKNOWN_TYPE = 0,
|
||||
X509_CA_CERT = 1,
|
||||
X509_USER_CERT = 2,
|
||||
X509_EMAIL_CERT = 3,
|
||||
X509_SERVER_CERT = 4
|
||||
};
|
||||
|
||||
// Get the URI //
|
||||
channel->GetURI(getter_AddRefs(mURI));
|
||||
/* other mime types that we should handle sometime:
|
||||
|
||||
application/x-pkcs7-mime
|
||||
application/pkcs7-signature
|
||||
application/pre-encrypted
|
||||
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
getPSMContentType(const char* aContentType)
|
||||
{
|
||||
// Don't forget to update the registration of content listeners in nsNSSModule.cpp
|
||||
// for every supported content type.
|
||||
|
||||
if (!nsCRT::strcasecmp(aContentType, "application/x-x509-ca-cert"))
|
||||
return X509_CA_CERT;
|
||||
if (!nsCRT::strcasecmp(aContentType, "application/x-x509-server-cert"))
|
||||
return X509_SERVER_CERT;
|
||||
if (!nsCRT::strcasecmp(aContentType, "application/x-x509-user-cert"))
|
||||
return X509_USER_CERT;
|
||||
if (!nsCRT::strcasecmp(aContentType, "application/x-x509-email-cert"))
|
||||
return X509_EMAIL_CERT;
|
||||
|
||||
return UNKNOWN_TYPE;
|
||||
}
|
||||
|
||||
int64_t
|
||||
ComputeContentLength(nsIRequest* request)
|
||||
{
|
||||
nsCOMPtr<nsIChannel> channel(do_QueryInterface(request));
|
||||
if (!channel) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t contentLength;
|
||||
rv = channel->GetContentLength(&contentLength);
|
||||
if (NS_FAILED(rv) || contentLength <= 0)
|
||||
contentLength = kDefaultCertAllocLength;
|
||||
if (contentLength > INT32_MAX)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mBufferOffset = 0;
|
||||
mBufferSize = 0;
|
||||
mByteData = (char*)moz_xmalloc(AssertedCast<size_t>(contentLength));
|
||||
if (!mByteData)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
mBufferSize = int32_t(contentLength);
|
||||
nsresult rv = channel->GetContentLength(&contentLength);
|
||||
if (NS_FAILED(rv) || contentLength <= 0) {
|
||||
return kDefaultCertAllocLength;
|
||||
}
|
||||
|
||||
if (contentLength > INT32_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
return contentLength;
|
||||
}
|
||||
|
||||
class ImportCertRunnable : public nsRunnable
|
||||
{
|
||||
public:
|
||||
ImportCertRunnable(PSMContentStreamListener* streamer)
|
||||
: mStreamer(streamer)
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHOD Run()
|
||||
{
|
||||
mStreamer->ImportCertificate();
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
private:
|
||||
nsRefPtr<PSMContentStreamListener> mStreamer;
|
||||
};
|
||||
|
||||
|
||||
} // unnamed namespace
|
||||
|
||||
/* ------------------------
|
||||
* PSMContentStreamListener
|
||||
* ------------------------ */
|
||||
|
||||
PSMContentStreamListener::PSMContentStreamListener(uint32_t type)
|
||||
: mType(type)
|
||||
{
|
||||
}
|
||||
|
||||
PSMContentStreamListener::~PSMContentStreamListener()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMPL_ISUPPORTS(PSMContentStreamListener, nsIStreamListener, nsIRequestObserver)
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentStreamListener::OnStartRequest(nsIRequest* request, nsISupports* context)
|
||||
{
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnStartRequest\n"));
|
||||
|
||||
int64_t contentLength = ComputeContentLength(request);
|
||||
if (contentLength < 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mByteData.SetCapacity(contentLength);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentDownloader::OnDataAvailable(nsIRequest* request,
|
||||
nsISupports* context,
|
||||
nsIInputStream *aIStream,
|
||||
uint64_t aSourceOffset,
|
||||
uint32_t aLength)
|
||||
PSMContentStreamListener::OnDataAvailable(nsIRequest* request,
|
||||
nsISupports* context,
|
||||
nsIInputStream* aIStream,
|
||||
uint64_t aSourceOffset,
|
||||
uint32_t aLength)
|
||||
{
|
||||
if (!mByteData)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
uint32_t amt;
|
||||
nsresult err;
|
||||
//Do a check to see if we need to allocate more memory.
|
||||
if ((mBufferOffset + (int32_t)aLength) > mBufferSize) {
|
||||
size_t newSize = (mBufferOffset + aLength) *2; // grow some more than needed
|
||||
char *newBuffer;
|
||||
newBuffer = (char*)moz_xrealloc(mByteData, newSize);
|
||||
if (!newBuffer) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
mByteData = newBuffer;
|
||||
mBufferSize = newSize;
|
||||
}
|
||||
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnDataAvailable\n"));
|
||||
do {
|
||||
err = aIStream->Read(mByteData+mBufferOffset,
|
||||
aLength, &amt);
|
||||
if (NS_FAILED(err)) return err;
|
||||
if (amt == 0) break;
|
||||
|
||||
aLength -= amt;
|
||||
mBufferOffset += amt;
|
||||
|
||||
} while (aLength > 0);
|
||||
|
||||
|
||||
nsCString chunk;
|
||||
nsresult rv = NS_ReadInputStreamToString(aIStream, chunk, aLength);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mByteData.Append(chunk);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentDownloader::OnStopRequest(nsIRequest* request,
|
||||
nsISupports* context,
|
||||
nsresult aStatus)
|
||||
PSMContentStreamListener::OnStopRequest(nsIRequest* request,
|
||||
nsISupports* context,
|
||||
nsresult aStatus)
|
||||
{
|
||||
nsNSSShutDownPreventionLock locker;
|
||||
//Check if the download succeeded - it might have failed due to
|
||||
//network issues, etc.
|
||||
if (NS_FAILED(aStatus)){
|
||||
return aStatus;
|
||||
}
|
||||
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("CertDownloader::OnStopRequest\n"));
|
||||
|
||||
// Because importing the cert can spin the event loop (via alerts), we can't
|
||||
// do it here. Do it off the event loop instead.
|
||||
nsCOMPtr<nsIRunnable> r = new ImportCertRunnable(this);
|
||||
MOZ_ALWAYS_TRUE(NS_SUCCEEDED(NS_DispatchToMainThread(r)));
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
void
|
||||
PSMContentStreamListener::ImportCertificate()
|
||||
{
|
||||
nsCOMPtr<nsIX509CertDB> certdb;
|
||||
|
||||
nsresult rv;
|
||||
nsCOMPtr<nsIInterfaceRequestor> ctx = new PipUIContext();
|
||||
|
||||
switch (mType) {
|
||||
case PSMContentDownloader::X509_CA_CERT:
|
||||
case PSMContentDownloader::X509_USER_CERT:
|
||||
case PSMContentDownloader::X509_EMAIL_CERT:
|
||||
case X509_CA_CERT:
|
||||
case X509_USER_CERT:
|
||||
case X509_EMAIL_CERT:
|
||||
certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
|
||||
break;
|
||||
|
||||
@ -167,48 +193,172 @@ PSMContentDownloader::OnStopRequest(nsIRequest* request,
|
||||
break;
|
||||
}
|
||||
|
||||
if (!certdb) {
|
||||
return;
|
||||
}
|
||||
|
||||
switch (mType) {
|
||||
case PSMContentDownloader::X509_CA_CERT:
|
||||
return certdb->ImportCertificates((uint8_t*)mByteData, mBufferOffset, mType, ctx);
|
||||
case PSMContentDownloader::X509_USER_CERT:
|
||||
return certdb->ImportUserCertificate((uint8_t*)mByteData, mBufferOffset, ctx);
|
||||
case PSMContentDownloader::X509_EMAIL_CERT:
|
||||
return certdb->ImportEmailCertificate((uint8_t*)mByteData, mBufferOffset, ctx);
|
||||
case X509_CA_CERT:
|
||||
certdb->ImportCertificates(reinterpret_cast<uint8_t*>(mByteData.BeginWriting()),
|
||||
mByteData.Length(), mType, ctx);
|
||||
break;
|
||||
|
||||
case X509_USER_CERT:
|
||||
certdb->ImportUserCertificate(reinterpret_cast<uint8_t*>(mByteData.BeginWriting()),
|
||||
mByteData.Length(), ctx);
|
||||
break;
|
||||
|
||||
case X509_EMAIL_CERT:
|
||||
certdb->ImportEmailCertificate(reinterpret_cast<uint8_t*>(mByteData.BeginWriting()),
|
||||
mByteData.Length(), ctx);
|
||||
break;
|
||||
|
||||
default:
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* ------------------------
|
||||
* PSMContentDownloaderParent
|
||||
* ------------------------ */
|
||||
|
||||
PSMContentDownloaderParent::PSMContentDownloaderParent(uint32_t type)
|
||||
: PSMContentStreamListener(type)
|
||||
, mIPCOpen(true)
|
||||
{
|
||||
}
|
||||
|
||||
PSMContentDownloaderParent::~PSMContentDownloaderParent()
|
||||
{
|
||||
}
|
||||
|
||||
bool
|
||||
PSMContentDownloaderParent::RecvOnStartRequest(const uint32_t& contentLength)
|
||||
{
|
||||
mByteData.SetCapacity(contentLength);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PSMContentDownloaderParent::RecvOnDataAvailable(const nsCString& data,
|
||||
const uint64_t& offset,
|
||||
const uint32_t& count)
|
||||
{
|
||||
mByteData.Append(data);
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
PSMContentDownloaderParent::RecvOnStopRequest(const nsresult& code)
|
||||
{
|
||||
if (NS_SUCCEEDED(code)) {
|
||||
// See also PSMContentStreamListener::OnStopRequest. In this case, we don't
|
||||
// have to dispatch ImportCertificate off of an event because we don't have
|
||||
// to worry about Necko sending "clean up" events and destroying us if
|
||||
// ImportCertificate spins the event loop.
|
||||
ImportCertificate();
|
||||
}
|
||||
|
||||
if (mIPCOpen) {
|
||||
mozilla::unused << Send__delete__(this);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentDownloaderParent::OnStopRequest(nsIRequest* request, nsISupports* context, nsresult code)
|
||||
{
|
||||
nsresult rv = PSMContentStreamListener::OnStopRequest(request, context, code);
|
||||
|
||||
if (mIPCOpen) {
|
||||
mozilla::unused << Send__delete__(this);
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* other mime types that we should handle sometime:
|
||||
|
||||
application/x-pkcs7-mime
|
||||
application/pkcs7-signature
|
||||
application/pre-encrypted
|
||||
|
||||
*/
|
||||
|
||||
uint32_t
|
||||
getPSMContentType(const char * aContentType)
|
||||
{
|
||||
// Don't forget to update the registration of content listeners in nsNSSModule.cpp
|
||||
// for every supported content type.
|
||||
|
||||
if (!nsCRT::strcasecmp(aContentType, "application/x-x509-ca-cert"))
|
||||
return PSMContentDownloader::X509_CA_CERT;
|
||||
else if (!nsCRT::strcasecmp(aContentType, "application/x-x509-server-cert"))
|
||||
return PSMContentDownloader::X509_SERVER_CERT;
|
||||
else if (!nsCRT::strcasecmp(aContentType, "application/x-x509-user-cert"))
|
||||
return PSMContentDownloader::X509_USER_CERT;
|
||||
else if (!nsCRT::strcasecmp(aContentType, "application/x-x509-email-cert"))
|
||||
return PSMContentDownloader::X509_EMAIL_CERT;
|
||||
|
||||
return PSMContentDownloader::UNKNOWN_TYPE;
|
||||
bool
|
||||
PSMContentDownloaderParent::RecvDivertToParentUsing(mozilla::net::PChannelDiverterParent* diverter)
|
||||
{
|
||||
MOZ_ASSERT(diverter);
|
||||
auto p = static_cast<mozilla::net::ChannelDiverterParent*>(diverter);
|
||||
p->DivertTo(this);
|
||||
mozilla::unused << p->Send__delete__(p);
|
||||
return true;
|
||||
}
|
||||
|
||||
} // unnamed namespace
|
||||
void
|
||||
PSMContentDownloaderParent::ActorDestroy(ActorDestroyReason why)
|
||||
{
|
||||
mIPCOpen = false;
|
||||
}
|
||||
|
||||
/* ------------------------
|
||||
* PSMContentDownloaderChild
|
||||
* ------------------------ */
|
||||
|
||||
NS_IMPL_ISUPPORTS(PSMContentDownloaderChild, nsIStreamListener)
|
||||
|
||||
PSMContentDownloaderChild::PSMContentDownloaderChild()
|
||||
{
|
||||
}
|
||||
|
||||
PSMContentDownloaderChild::~PSMContentDownloaderChild()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentDownloaderChild::OnStartRequest(nsIRequest* request, nsISupports* context)
|
||||
{
|
||||
nsCOMPtr<nsIDivertableChannel> divertable = do_QueryInterface(request);
|
||||
if (divertable) {
|
||||
mozilla::net::ChannelDiverterChild* diverter = nullptr;
|
||||
nsresult rv = divertable->DivertToParent(&diverter);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
MOZ_ASSERT(diverter);
|
||||
|
||||
return SendDivertToParentUsing(diverter) ? NS_OK : NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
int64_t contentLength = ComputeContentLength(request);
|
||||
if (contentLength < 0) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
mozilla::unused << SendOnStartRequest(contentLength);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentDownloaderChild::OnDataAvailable(nsIRequest* request,
|
||||
nsISupports* context,
|
||||
nsIInputStream* aIStream,
|
||||
uint64_t aSourceOffset,
|
||||
uint32_t aLength)
|
||||
{
|
||||
nsCString chunk;
|
||||
nsresult rv = NS_ReadInputStreamToString(aIStream, chunk, aLength);
|
||||
if (NS_FAILED(rv)) {
|
||||
return rv;
|
||||
}
|
||||
|
||||
mozilla::unused << SendOnDataAvailable(chunk, aSourceOffset, aLength);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentDownloaderChild::OnStopRequest(nsIRequest* request,
|
||||
nsISupports* context,
|
||||
nsresult aStatus)
|
||||
{
|
||||
mozilla::unused << SendOnStopRequest(aStatus);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* ------------------------
|
||||
* PSMContentListener
|
||||
* ------------------------ */
|
||||
|
||||
NS_IMPL_ISUPPORTS(PSMContentListener,
|
||||
nsIURIContentListener,
|
||||
@ -231,7 +381,7 @@ PSMContentListener::init()
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentListener::OnStartURIOpen(nsIURI *aURI, bool *aAbortOpen)
|
||||
PSMContentListener::OnStartURIOpen(nsIURI* aURI, bool* aAbortOpen)
|
||||
{
|
||||
//if we don't want to handle the URI, return true in
|
||||
//*aAbortOpen
|
||||
@ -239,73 +389,77 @@ PSMContentListener::OnStartURIOpen(nsIURI *aURI, bool *aAbortOpen)
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentListener::IsPreferred(const char * aContentType,
|
||||
char ** aDesiredContentType,
|
||||
bool * aCanHandleContent)
|
||||
PSMContentListener::IsPreferred(const char* aContentType,
|
||||
char** aDesiredContentType,
|
||||
bool* aCanHandleContent)
|
||||
{
|
||||
return CanHandleContent(aContentType, true,
|
||||
aDesiredContentType, aCanHandleContent);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentListener::CanHandleContent(const char * aContentType,
|
||||
PSMContentListener::CanHandleContent(const char* aContentType,
|
||||
bool aIsContentPreferred,
|
||||
char ** aDesiredContentType,
|
||||
bool * aCanHandleContent)
|
||||
char** aDesiredContentType,
|
||||
bool* aCanHandleContent)
|
||||
{
|
||||
uint32_t type;
|
||||
type = getPSMContentType(aContentType);
|
||||
if (type == PSMContentDownloader::UNKNOWN_TYPE) {
|
||||
*aCanHandleContent = false;
|
||||
} else {
|
||||
*aCanHandleContent = true;
|
||||
}
|
||||
uint32_t type = getPSMContentType(aContentType);
|
||||
*aCanHandleContent = (type != UNKNOWN_TYPE);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentListener::DoContent(const nsACString & aContentType,
|
||||
PSMContentListener::DoContent(const nsACString& aContentType,
|
||||
bool aIsContentPreferred,
|
||||
nsIRequest * aRequest,
|
||||
nsIStreamListener ** aContentHandler,
|
||||
bool * aAbortProcess)
|
||||
nsIRequest* aRequest,
|
||||
nsIStreamListener** aContentHandler,
|
||||
bool* aAbortProcess)
|
||||
{
|
||||
uint32_t type;
|
||||
type = getPSMContentType(PromiseFlatCString(aContentType).get());
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("PSMContentListener::DoContent\n"));
|
||||
if (type != PSMContentDownloader::UNKNOWN_TYPE) {
|
||||
nsRefPtr<PSMContentDownloader> downLoader = new PSMContentDownloader(type);
|
||||
downLoader.forget(aContentHandler);
|
||||
if (gPIPNSSLog) {
|
||||
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("PSMContentListener::DoContent\n"));
|
||||
}
|
||||
if (type != UNKNOWN_TYPE) {
|
||||
nsCOMPtr<nsIStreamListener> downloader;
|
||||
if (XRE_GetProcessType() == GeckoProcessType_Default) {
|
||||
downloader = new PSMContentStreamListener(type);
|
||||
} else {
|
||||
downloader = static_cast<PSMContentDownloaderChild*>(
|
||||
dom::ContentChild::GetSingleton()->SendPPSMContentDownloaderConstructor(type));
|
||||
}
|
||||
|
||||
downloader.forget(aContentHandler);
|
||||
return NS_OK;
|
||||
}
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentListener::GetLoadCookie(nsISupports * *aLoadCookie)
|
||||
PSMContentListener::GetLoadCookie(nsISupports** aLoadCookie)
|
||||
{
|
||||
*aLoadCookie = mLoadCookie;
|
||||
NS_IF_ADDREF(*aLoadCookie);
|
||||
nsCOMPtr<nsISupports> loadCookie(mLoadCookie);
|
||||
loadCookie.forget(aLoadCookie);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentListener::SetLoadCookie(nsISupports * aLoadCookie)
|
||||
PSMContentListener::SetLoadCookie(nsISupports* aLoadCookie)
|
||||
{
|
||||
mLoadCookie = aLoadCookie;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentListener::GetParentContentListener(nsIURIContentListener ** aContentListener)
|
||||
PSMContentListener::GetParentContentListener(nsIURIContentListener** aContentListener)
|
||||
{
|
||||
*aContentListener = mParentContentListener;
|
||||
NS_IF_ADDREF(*aContentListener);
|
||||
nsCOMPtr<nsIURIContentListener> listener(mParentContentListener);
|
||||
listener.forget(aContentListener);
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP
|
||||
PSMContentListener::SetParentContentListener(nsIURIContentListener * aContentListener)
|
||||
PSMContentListener::SetParentContentListener(nsIURIContentListener* aContentListener)
|
||||
{
|
||||
mParentContentListener = aContentListener;
|
||||
return NS_OK;
|
||||
|
@ -10,12 +10,84 @@
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsIURIContentListener.h"
|
||||
#include "nsWeakReference.h"
|
||||
#include "mozilla/psm/PPSMContentDownloaderChild.h"
|
||||
#include "mozilla/psm/PPSMContentDownloaderParent.h"
|
||||
|
||||
#define NS_PSMCONTENTLISTEN_CID {0xc94f4a30, 0x64d7, 0x11d4, {0x99, 0x60, 0x00, 0xb0, 0xd0, 0x23, 0x54, 0xa0}}
|
||||
#define NS_PSMCONTENTLISTEN_CONTRACTID "@mozilla.org/security/psmdownload;1"
|
||||
|
||||
namespace mozilla {
|
||||
namespace net {
|
||||
|
||||
class PChannelDiverterParent;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
namespace mozilla { namespace psm {
|
||||
|
||||
// PSMContentStreamListener for parent-process downloading.
|
||||
class PSMContentStreamListener : public nsIStreamListener
|
||||
{
|
||||
public:
|
||||
explicit PSMContentStreamListener(uint32_t type);
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
void ImportCertificate();
|
||||
|
||||
protected:
|
||||
virtual ~PSMContentStreamListener();
|
||||
|
||||
nsCString mByteData;
|
||||
uint32_t mType;
|
||||
};
|
||||
|
||||
// Parent actor for importing a remote cert when the load was started by the
|
||||
// child.
|
||||
class PSMContentDownloaderParent : public PPSMContentDownloaderParent
|
||||
, public PSMContentStreamListener
|
||||
{
|
||||
public:
|
||||
explicit PSMContentDownloaderParent(uint32_t type);
|
||||
|
||||
virtual bool RecvOnStartRequest(const uint32_t &contentLength) override;
|
||||
virtual bool RecvOnDataAvailable(const nsCString &data,
|
||||
const uint64_t &offset,
|
||||
const uint32_t &count) override;
|
||||
virtual bool RecvOnStopRequest(const nsresult &code) override;
|
||||
|
||||
// We inherit most of nsIStreamListener from PSMContentStreamListener, but
|
||||
// we have to override OnStopRequest to know when we're done with our IPC
|
||||
// ref.
|
||||
NS_IMETHOD OnStopRequest(nsIRequest *request, nsISupports *aContext, nsresult code) override;
|
||||
|
||||
virtual bool RecvDivertToParentUsing(mozilla::net::PChannelDiverterParent *diverter) override;
|
||||
|
||||
protected:
|
||||
virtual ~PSMContentDownloaderParent();
|
||||
|
||||
virtual void ActorDestroy(ActorDestroyReason why) override;
|
||||
bool mIPCOpen;
|
||||
};
|
||||
|
||||
// Child actor for importing a cert.
|
||||
class PSMContentDownloaderChild : public nsIStreamListener
|
||||
, public PPSMContentDownloaderChild
|
||||
{
|
||||
public:
|
||||
PSMContentDownloaderChild();
|
||||
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIREQUESTOBSERVER
|
||||
NS_DECL_NSISTREAMLISTENER
|
||||
|
||||
private:
|
||||
~PSMContentDownloaderChild();
|
||||
};
|
||||
|
||||
|
||||
class PSMContentListener : public nsIURIContentListener,
|
||||
public nsSupportsWeakReference
|
||||
{
|
||||
|
@ -23,6 +23,10 @@ EXPORTS.mozilla += [
|
||||
'PublicSSL.h',
|
||||
]
|
||||
|
||||
EXPORTS.mozilla.psm += [
|
||||
'PSMContentListener.h',
|
||||
]
|
||||
|
||||
UNIFIED_SOURCES += [
|
||||
'CryptoTask.cpp',
|
||||
'nsCertOverrideService.cpp',
|
||||
@ -74,6 +78,10 @@ SOURCES += [
|
||||
'nsNSSCertificateDB.cpp',
|
||||
]
|
||||
|
||||
IPDL_SOURCES += [
|
||||
'PPSMContentDownloader.ipdl',
|
||||
]
|
||||
|
||||
LOCAL_INCLUDES += [
|
||||
'/security/manager/boot/src',
|
||||
]
|
||||
|
@ -135,14 +135,20 @@ _InstanceClassChrome##Constructor(nsISupports *aOuter, REFNSIID aIID, \
|
||||
{ \
|
||||
nsresult rv; \
|
||||
\
|
||||
*aResult = nullptr; \
|
||||
if (nullptr != aOuter) { \
|
||||
*aResult = nullptr; \
|
||||
if (nullptr != aOuter) { \
|
||||
rv = NS_ERROR_NO_AGGREGATION; \
|
||||
return rv; \
|
||||
} \
|
||||
\
|
||||
if (!EnsureNSSInitialized(ensureOperator)) \
|
||||
if (!NS_IS_PROCESS_DEFAULT && \
|
||||
ensureOperator == nssEnsureChromeOrContent) { \
|
||||
if (!EnsureNSSInitializedChromeOrContent()) { \
|
||||
return NS_ERROR_FAILURE; \
|
||||
} \
|
||||
} else if (!EnsureNSSInitialized(ensureOperator)) { \
|
||||
return NS_ERROR_FAILURE; \
|
||||
} \
|
||||
\
|
||||
if (NS_IS_PROCESS_DEFAULT) \
|
||||
NS_NSS_INSTANTIATE_INIT(ensureOperator, \
|
||||
@ -182,7 +188,7 @@ NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsTLSSocketProvider)
|
||||
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsSecretDecoderRing)
|
||||
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsPK11TokenDB)
|
||||
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR(nssEnsure, nsPKCS11ModuleDB)
|
||||
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nssEnsure, PSMContentListener, init)
|
||||
NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(PSMContentListener, init)
|
||||
NS_NSS_GENERIC_FACTORY_CONSTRUCTOR_BYPROCESS(nssEnsureOnChromeOnly,
|
||||
nsNSSCertificate,
|
||||
nsNSSCertificateFakeTransport)
|
||||
|
Loading…
Reference in New Issue
Block a user