bug 1038913 - (1/4) move smart card event dispatching code to nsSmartCardMonitor.cpp r=briansmith

This commit is contained in:
David Keeler 2014-07-24 12:58:14 -07:00
parent 5375d3ad83
commit 3a2e57dd6c
3 changed files with 146 additions and 199 deletions

View File

@ -24,17 +24,7 @@
#include "mozilla/StaticPtr.h"
#ifndef MOZ_DISABLE_CRYPTOLEGACY
#include "nsIDOMNode.h"
#include "nsIDOMEvent.h"
#include "nsIDOMDocument.h"
#include "nsIDOMWindow.h"
#include "nsIDOMWindowCollection.h"
#include "nsIDocument.h"
#include "mozilla/dom/SmartCardEvent.h"
#include "nsSmartCardMonitor.h"
#include "nsIDOMCryptoLegacy.h"
#else
#include "nsIDOMCrypto.h"
#endif
#include "nsCRT.h"
@ -67,7 +57,6 @@
#include "p12plcy.h"
using namespace mozilla;
using namespace mozilla::dom;
using namespace mozilla::psm;
#ifdef PR_LOGGING
@ -76,53 +65,6 @@ PRLogModuleInfo* gPIPNSSLog = nullptr;
int nsNSSComponent::mInstanceCount = 0;
// XXX tmp callback for slot password
extern char* pk11PasswordPrompt(PK11SlotInfo* slot, PRBool retry, void* arg);
#ifndef MOZ_DISABLE_CRYPTOLEGACY
//This class is used to run the callback code
//passed to the event handlers for smart card notification
class nsTokenEventRunnable : public nsIRunnable {
public:
nsTokenEventRunnable(const nsAString& aType, const nsAString& aTokenName);
NS_IMETHOD Run ();
NS_DECL_THREADSAFE_ISUPPORTS
protected:
virtual ~nsTokenEventRunnable();
private:
nsString mType;
nsString mTokenName;
};
// ISuuports implementation for nsTokenEventRunnable
NS_IMPL_ISUPPORTS(nsTokenEventRunnable, nsIRunnable)
nsTokenEventRunnable::nsTokenEventRunnable(const nsAString& aType,
const nsAString& aTokenName)
: mType(aType)
, mTokenName(aTokenName)
{
}
nsTokenEventRunnable::~nsTokenEventRunnable() { }
//Implementation that runs the callback passed to
//crypto.generateCRMFRequest as an event.
NS_IMETHODIMP
nsTokenEventRunnable::Run()
{
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
nsresult rv;
nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(kNSSComponentCID, &rv));
if (NS_FAILED(rv))
return rv;
return nssComponent->DispatchEvent(mType, mTokenName);
}
#endif // MOZ_DISABLE_CRYPTOLEGACY
bool nsPSMInitPanic::isPanic = false;
// This function can be called from chrome or content processes
@ -336,121 +278,6 @@ nsNSSComponent::~nsNSSComponent()
PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsNSSComponent::dtor finished\n"));
}
#ifndef MOZ_DISABLE_CRYPTOLEGACY
NS_IMETHODIMP
nsNSSComponent::PostEvent(const nsAString& eventType,
const nsAString& tokenName)
{
nsCOMPtr<nsIRunnable> runnable =
new nsTokenEventRunnable(eventType, tokenName);
return NS_DispatchToMainThread(runnable);
}
NS_IMETHODIMP
nsNSSComponent::DispatchEvent(const nsAString& eventType,
const nsAString& tokenName)
{
// 'Dispatch' the event to all the windows. 'DispatchEventToWindow()' will
// first check to see if a given window has requested crypto events.
nsresult rv;
nsCOMPtr<nsIWindowWatcher> windowWatcher =
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsISimpleEnumerator> enumerator;
rv = windowWatcher->GetWindowEnumerator(getter_AddRefs(enumerator));
if (NS_FAILED(rv)) {
return rv;
}
bool hasMoreWindows;
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreWindows))
&& hasMoreWindows) {
nsCOMPtr<nsISupports> supports;
enumerator->GetNext(getter_AddRefs(supports));
nsCOMPtr<nsIDOMWindow> domWin(do_QueryInterface(supports));
if (domWin) {
nsresult rv2 = DispatchEventToWindow(domWin, eventType, tokenName);
if (NS_FAILED(rv2)) {
// return the last failure, don't let a single failure prevent
// continued delivery of events.
rv = rv2;
}
}
}
return rv;
}
nsresult
nsNSSComponent::DispatchEventToWindow(nsIDOMWindow* domWin,
const nsAString& eventType,
const nsAString& tokenName)
{
if (!domWin) {
return NS_OK;
}
// first walk the children and dispatch their events
nsresult rv;
nsCOMPtr<nsIDOMWindowCollection> frames;
rv = domWin->GetFrames(getter_AddRefs(frames));
if (NS_FAILED(rv)) {
return rv;
}
uint32_t length;
frames->GetLength(&length);
uint32_t i;
for (i = 0; i < length; i++) {
nsCOMPtr<nsIDOMWindow> childWin;
frames->Item(i, getter_AddRefs(childWin));
DispatchEventToWindow(childWin, eventType, tokenName);
}
// check if we've enabled smart card events on this window
// NOTE: it's not an error to say that we aren't going to dispatch
// the event.
nsCOMPtr<nsIDOMCrypto> crypto;
domWin->GetCrypto(getter_AddRefs(crypto));
if (!crypto) {
return NS_OK; // nope, it doesn't have a crypto property
}
bool boolrv;
crypto->GetEnableSmartCardEvents(&boolrv);
if (!boolrv) {
return NS_OK; // nope, it's not enabled.
}
// dispatch the event ...
// find the document
nsCOMPtr<nsIDOMDocument> doc;
rv = domWin->GetDocument(getter_AddRefs(doc));
if (!doc) {
return NS_FAILED(rv) ? rv : NS_ERROR_FAILURE;
}
nsCOMPtr<EventTarget> d = do_QueryInterface(doc);
SmartCardEventInit init;
init.mBubbles = false;
init.mCancelable = true;
init.mTokenName = tokenName;
nsRefPtr<SmartCardEvent> event = SmartCardEvent::Constructor(d, eventType, init);
event->SetTrusted(true);
return d->DispatchEvent(event, &boolrv);
}
#endif // MOZ_DISABLE_CRYPTOLEGACY
NS_IMETHODIMP
nsNSSComponent::PIPBundleFormatStringFromName(const char* name,
const char16_t** params,

View File

@ -44,10 +44,10 @@ MOZ_WARN_UNUSED_RESULT
//Define an interface that we can use to look up from the
//callbacks passed to NSS.
#define NS_INSSCOMPONENT_IID_STR "538c5093-7cfe-4f13-bc8e-e767766a2d4d"
#define NS_INSSCOMPONENT_IID_STR "e60602a8-97a3-4fe7-b5b7-56bc6ce87ab4"
#define NS_INSSCOMPONENT_IID \
{ 0x538c5093, 0x7cfe, 0x4f13, \
{ 0xbc, 0x8e, 0xe7, 0x67, 0x76, 0x6a, 0x2d, 0x4d } }
{ 0xe60602a8, 0x97a3, 0x4fe7, \
{ 0xb5, 0xb7, 0x56, 0xbc, 0x6c, 0xe8, 0x7a, 0xb4 } }
enum EnsureNSSOperator
{
@ -91,12 +91,6 @@ class NS_NO_VTABLE nsINSSComponent : public nsISupports {
NS_IMETHOD LaunchSmartCardThread(SECMODModule* module) = 0;
NS_IMETHOD ShutdownSmartCardThread(SECMODModule* module) = 0;
NS_IMETHOD PostEvent(const nsAString& eventType,
const nsAString& token) = 0;
NS_IMETHOD DispatchEvent(const nsAString& eventType,
const nsAString& token) = 0;
#endif
NS_IMETHOD IsNSSInitialized(bool* initialized) = 0;
@ -149,8 +143,6 @@ public:
#ifndef MOZ_DISABLE_CRYPTOLEGACY
NS_IMETHOD LaunchSmartCardThread(SECMODModule* module);
NS_IMETHOD ShutdownSmartCardThread(SECMODModule* module);
NS_IMETHOD PostEvent(const nsAString& eventType, const nsAString& token);
NS_IMETHOD DispatchEvent(const nsAString& eventType, const nsAString& token);
void LaunchSmartCardThreads();
void ShutdownSmartCardThreads();
nsresult DispatchEventToWindow(nsIDOMWindow* domWin,
@ -207,7 +199,6 @@ private:
nsNSSHttpInterface mHttpForNSS;
mozilla::RefPtr<mozilla::psm::SharedCertVerifier> mDefaultCertVerifier;
static PRStatus IdentityInfoInit(void);
};

View File

@ -3,13 +3,20 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nspr.h"
#include "pk11func.h"
#include "nsNSSComponent.h"
#include "nsSmartCardMonitor.h"
#include "nsServiceManagerUtils.h"
#include "mozilla/dom/SmartCardEvent.h"
#include "mozilla/unused.h"
#include "nsIDOMCryptoLegacy.h"
#include "nsIDOMDocument.h"
#include "nsIDOMWindow.h"
#include "nsIDOMWindowCollection.h"
#include "nsISimpleEnumerator.h"
#include "nsIWindowWatcher.h"
#include "nsServiceManagerUtils.h"
#include "nsSmartCardMonitor.h"
#include "pk11func.h"
using namespace mozilla;
using namespace mozilla::dom;
//
// The SmartCard monitoring thread should start up for each module we load
@ -26,6 +33,135 @@ using namespace mozilla;
// javascript).
//
//This class is used to run the callback code
//passed to the event handlers for smart card notification
class nsTokenEventRunnable : public nsIRunnable {
public:
nsTokenEventRunnable(const nsAString& aType, const nsAString& aTokenName);
NS_IMETHOD Run ();
NS_DECL_THREADSAFE_ISUPPORTS
protected:
virtual ~nsTokenEventRunnable();
private:
nsresult DispatchEventToWindow(nsIDOMWindow* domWin);
nsString mType;
nsString mTokenName;
};
// ISuuports implementation for nsTokenEventRunnable
NS_IMPL_ISUPPORTS(nsTokenEventRunnable, nsIRunnable)
nsTokenEventRunnable::nsTokenEventRunnable(const nsAString& aType,
const nsAString& aTokenName)
: mType(aType)
, mTokenName(aTokenName)
{
}
nsTokenEventRunnable::~nsTokenEventRunnable() { }
//Implementation that runs the callback passed to
//crypto.generateCRMFRequest as an event.
NS_IMETHODIMP
nsTokenEventRunnable::Run()
{
// 'Dispatch' the event to all the windows. 'DispatchEventToWindow()' will
// first check to see if a given window has requested crypto events.
nsresult rv;
nsCOMPtr<nsIWindowWatcher> windowWatcher =
do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
if (NS_FAILED(rv)) {
return rv;
}
nsCOMPtr<nsISimpleEnumerator> enumerator;
rv = windowWatcher->GetWindowEnumerator(getter_AddRefs(enumerator));
if (NS_FAILED(rv)) {
return rv;
}
bool hasMoreWindows;
while (NS_SUCCEEDED(enumerator->HasMoreElements(&hasMoreWindows))
&& hasMoreWindows) {
nsCOMPtr<nsISupports> supports;
enumerator->GetNext(getter_AddRefs(supports));
nsCOMPtr<nsIDOMWindow> domWin(do_QueryInterface(supports));
if (domWin) {
nsresult rv2 = DispatchEventToWindow(domWin);
if (NS_FAILED(rv2)) {
// return the last failure, don't let a single failure prevent
// continued delivery of events.
rv = rv2;
}
}
}
return rv;
}
nsresult
nsTokenEventRunnable::DispatchEventToWindow(nsIDOMWindow* domWin)
{
if (!domWin) {
return NS_OK;
}
// first walk the children and dispatch their events
nsresult rv;
nsCOMPtr<nsIDOMWindowCollection> frames;
rv = domWin->GetFrames(getter_AddRefs(frames));
if (NS_FAILED(rv)) {
return rv;
}
uint32_t length;
frames->GetLength(&length);
uint32_t i;
for (i = 0; i < length; i++) {
nsCOMPtr<nsIDOMWindow> childWin;
frames->Item(i, getter_AddRefs(childWin));
DispatchEventToWindow(childWin);
}
// check if we've enabled smart card events on this window
// NOTE: it's not an error to say that we aren't going to dispatch
// the event.
nsCOMPtr<nsIDOMCrypto> crypto;
domWin->GetCrypto(getter_AddRefs(crypto));
if (!crypto) {
return NS_OK; // nope, it doesn't have a crypto property
}
bool boolrv;
crypto->GetEnableSmartCardEvents(&boolrv);
if (!boolrv) {
return NS_OK; // nope, it's not enabled.
}
// dispatch the event ...
// find the document
nsCOMPtr<nsIDOMDocument> doc;
rv = domWin->GetDocument(getter_AddRefs(doc));
if (!doc) {
return NS_FAILED(rv) ? rv : NS_ERROR_FAILURE;
}
nsCOMPtr<EventTarget> d = do_QueryInterface(doc);
SmartCardEventInit init;
init.mBubbles = false;
init.mCancelable = true;
init.mTokenName = mTokenName;
nsRefPtr<SmartCardEvent> event = SmartCardEvent::Constructor(d, mType, init);
event->SetTrusted(true);
return d->DispatchEvent(event, &boolrv);
}
// self linking and removing double linked entry
// adopts the thread it is passed.
@ -234,17 +370,10 @@ nsresult
SmartCardMonitoringThread::SendEvent(const nsAString &eventType,
const char *tokenName)
{
static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
nsCOMPtr<nsIRunnable> runnable =
new nsTokenEventRunnable(eventType, NS_ConvertUTF8toUTF16(tokenName));
nsresult rv;
nsCOMPtr<nsINSSComponent>
nssComponent(do_GetService(kNSSComponentCID, &rv));
if (NS_FAILED(rv))
return rv;
// NSS returns actual UTF8, not ASCII
nssComponent->PostEvent(eventType, NS_ConvertUTF8toUTF16(tokenName));
return NS_OK;
return NS_DispatchToMainThread(runnable);
}
//