diff --git a/xpinstall/src/Makefile.in b/xpinstall/src/Makefile.in index 97ec520f36b..a37008cbfd4 100644 --- a/xpinstall/src/Makefile.in +++ b/xpinstall/src/Makefile.in @@ -88,6 +88,8 @@ REQUIRES = xpcom \ chrome \ extensions \ embed_base \ + pipnss \ + pipboot \ $(ZLIB_REQUIRES) \ $(NULL) diff --git a/xpinstall/src/nsXPInstallManager.cpp b/xpinstall/src/nsXPInstallManager.cpp index 8ee6c86f126..89e81219a58 100644 --- a/xpinstall/src/nsXPInstallManager.cpp +++ b/xpinstall/src/nsXPInstallManager.cpp @@ -21,6 +21,7 @@ * * Contributor(s): * Daniel Veditz + * Dave Townsend * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), @@ -80,6 +81,10 @@ #include "nsISupportsPrimitives.h" #include "nsIObserverService.h" +#include "nsISSLStatusProvider.h" +#include "nsISSLStatus.h" +#include "nsIX509Cert.h" + #include "nsIPrefService.h" #include "nsIPrefBranch.h" @@ -110,7 +115,7 @@ inline PRBool nsXPInstallManager::TimeToUpdate(PRTime now) nsXPInstallManager::nsXPInstallManager() : mTriggers(0), mItem(0), mNextItem(0), mNumJars(0), mChromeType(NOT_CHROME), mContentLength(0), mDialogOpen(PR_FALSE), mCancelled(PR_FALSE), - mSelectChrome(PR_FALSE), mNeedsShutdown(PR_FALSE) + mSelectChrome(PR_FALSE), mNeedsShutdown(PR_FALSE), mFromChrome(PR_FALSE) { // we need to own ourself because we have a longer // lifetime than the scriptlet that created us. @@ -132,7 +137,7 @@ nsXPInstallManager::~nsXPInstallManager() } -NS_IMPL_THREADSAFE_ISUPPORTS9( nsXPInstallManager, +NS_IMPL_THREADSAFE_ISUPPORTS11(nsXPInstallManager, nsIXPIListener, nsIXPIDialogService, nsIXPInstallManager, @@ -141,6 +146,8 @@ NS_IMPL_THREADSAFE_ISUPPORTS9( nsXPInstallManager, nsIProgressEventSink, nsIInterfaceRequestor, nsPICertNotification, + nsIBadCertListener, + nsIChannelEventSink, nsISupportsWeakReference) NS_IMETHODIMP @@ -197,6 +204,8 @@ nsXPInstallManager::InitManagerWithHashes(const PRUnichar **aURLs, return rv; } + mFromChrome = PR_TRUE; + rv = Observe(aListener, XPI_PROGRESS_TOPIC, NS_LITERAL_STRING("open").get()); if (NS_FAILED(rv)) Shutdown(); @@ -975,7 +984,51 @@ nsXPInstallManager::GetDestinationFile(nsString& url, nsILocalFile* *file) return rv; } - +nsresult +nsXPInstallManager::CheckCert(nsIChannel* aChannel) +{ + nsCOMPtr uri; + nsresult rv = aChannel->GetOriginalURI(getter_AddRefs(uri)); + NS_ENSURE_SUCCESS(rv, rv); + nsCAutoString scheme; + rv = uri->GetScheme(scheme); + NS_ENSURE_SUCCESS(rv, rv); + if (!scheme.Equals(NS_LITERAL_CSTRING("https"))) + return NS_OK; + + nsCOMPtr security; + rv = aChannel->GetSecurityInfo(getter_AddRefs(security)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr statusProvider(do_QueryInterface(security)); + NS_ENSURE_TRUE(statusProvider, NS_ERROR_FAILURE); + + rv = statusProvider->GetSSLStatus(getter_AddRefs(security)); + NS_ENSURE_SUCCESS(rv, rv); + nsCOMPtr status(do_QueryInterface(security)); + NS_ENSURE_TRUE(status, NS_ERROR_FAILURE); + nsCOMPtr cert; + rv = status->GetServerCert(getter_AddRefs(cert)); + NS_ENSURE_SUCCESS(rv, rv); + + nsCOMPtr issuer; + rv = cert->GetIssuer(getter_AddRefs(issuer)); + NS_ENSURE_SUCCESS(rv, rv); + PRBool equal; + while (issuer && NS_SUCCEEDED(cert->Equals(issuer, &equal)) && !equal) { + cert = issuer; + rv = cert->GetIssuer(getter_AddRefs(issuer)); + NS_ENSURE_SUCCESS(rv, rv); + } + + if (issuer) { + nsAutoString tokenName; + rv = issuer->GetTokenName(tokenName); + NS_ENSURE_SUCCESS(rv ,rv); + if (tokenName.Equals(NS_LITERAL_STRING("Builtin Object Token"))) + return NS_OK; + } + return NS_ERROR_FAILURE; +} NS_IMETHODIMP nsXPInstallManager::OnStartRequest(nsIRequest* request, nsISupports *ctxt) @@ -986,6 +1039,11 @@ nsXPInstallManager::OnStartRequest(nsIRequest* request, nsISupports *ctxt) // download failures. nsCOMPtr httpChan = do_QueryInterface(request); if (httpChan) { + // If we were chrome lauched check the certificate on the request + if (mFromChrome && NS_FAILED(CheckCert(httpChan))) { + request->Cancel(NS_BINDING_ABORTED); + return NS_OK; + } PRBool succeeded; if (NS_SUCCEEDED(httpChan->GetRequestSucceeded(&succeeded)) && !succeeded) { // HTTP response is not a 2xx! @@ -1168,9 +1226,52 @@ nsXPInstallManager::GetInterface(const nsIID & eventSinkIID, void* *_retval) *_retval = p; return NS_OK; } + else if (eventSinkIID.Equals(NS_GET_IID(nsIBadCertListener))) { + // If we aren't chrome triggered fall back to the default dialogs + if (!mFromChrome) + return NS_ERROR_NO_INTERFACE; + } return QueryInterface(eventSinkIID, (void**)_retval); } +// nsIChannelEventSink method +NS_IMETHODIMP +nsXPInstallManager::OnChannelRedirect(nsIChannel *oldChannel, nsIChannel *newChannel, PRUint32 flags) +{ + // Chrome triggered installs need to have their certificates checked + if (mFromChrome) + return CheckCert(oldChannel); + return NS_OK; +} + +// nsIBadCertListener methods +NS_IMETHODIMP +nsXPInstallManager::ConfirmUnknownIssuer(nsIInterfaceRequestor *socketInfo, nsIX509Cert *cert, PRInt16 *certAddType, PRBool *_retval) +{ + *_retval = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsXPInstallManager::ConfirmMismatchDomain(nsIInterfaceRequestor *socketInfo, const nsACString & targetURL, nsIX509Cert *cert, PRBool *_retval) +{ + *_retval = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsXPInstallManager::ConfirmCertExpired(nsIInterfaceRequestor *socketInfo, nsIX509Cert *cert, PRBool *_retval) +{ + *_retval = PR_FALSE; + return NS_OK; +} + +NS_IMETHODIMP +nsXPInstallManager::NotifyCrlNextupdate(nsIInterfaceRequestor *socketInfo, const nsACString & targetURL, nsIX509Cert *cert) +{ + return NS_OK; +} + // IXPIListener methods PRInt32 diff --git a/xpinstall/src/nsXPInstallManager.h b/xpinstall/src/nsXPInstallManager.h index 6fde82fae19..dea006ec401 100644 --- a/xpinstall/src/nsXPInstallManager.h +++ b/xpinstall/src/nsXPInstallManager.h @@ -56,6 +56,8 @@ #include "nsIChromeRegistry.h" #include "nsIDOMWindowInternal.h" #include "nsIObserver.h" +#include "nsIBadCertListener.h" +#include "nsIChannelEventSink.h" #include "nsISoftwareUpdate.h" @@ -83,6 +85,8 @@ class nsXPInstallManager : public nsIXPIListener, public nsIProgressEventSink, public nsIInterfaceRequestor, public nsPICertNotification, + public nsIBadCertListener, + public nsIChannelEventSink, public nsSupportsWeakReference { public: @@ -99,6 +103,8 @@ class nsXPInstallManager : public nsIXPIListener, NS_DECL_NSIREQUESTOBSERVER NS_DECL_NSIINTERFACEREQUESTOR NS_DECL_NSPICERTNOTIFICATION + NS_DECL_NSIBADCERTLISTENER + NS_DECL_NSICHANNELEVENTSINK NS_IMETHOD InitManager(nsIScriptGlobalObject* aGlobalObject, nsXPITriggerInfo* aTrigger, PRUint32 aChromeType ); @@ -114,6 +120,7 @@ class nsXPInstallManager : public nsIXPIListener, PRBool TimeToUpdate(PRTime now); PRBool VerifyHash(nsXPITriggerItem* aItem); PRInt32 GetIndexFromURL(const PRUnichar* aUrl); + nsresult CheckCert(nsIChannel* aChannel); nsXPITriggerInfo* mTriggers; nsXPITriggerItem* mItem; @@ -127,6 +134,7 @@ class nsXPInstallManager : public nsIXPIListener, PRBool mCancelled; PRBool mSelectChrome; PRBool mNeedsShutdown; + PRBool mFromChrome; nsCOMPtr mDlg; nsCOMPtr mInstallSvc;