--- a/xpinstall/src/nsXPInstallManager.cpp
+++ b/xpinstall/src/nsXPInstallManager.cpp
@@ -16,16 +16,17 @@
*
* The Initial Developer of the Original Code is
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Daniel Veditz <dveditz@netscape.com>
+ * Dave Townsend <dtownsend@oxymoronical.com>
*
* 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"),
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
@@ -75,16 +76,20 @@
#include "nsReadableUtils.h"
#include "nsProxiedService.h"
#include "nsIPromptService.h"
#include "nsIScriptGlobalObject.h"
#include "nsXPCOM.h"
#include "nsISupportsPrimitives.h"
#include "nsIObserverService.h"
+#include "nsISSLStatusProvider.h"
+#include "nsISSLStatus.h"
+#include "nsIX509Cert.h"
+
#include "nsIPrefService.h"
#include "nsIPrefBranch.h"
#include "CertReader.h"
#include "nsEmbedCID.h"
static NS_DEFINE_IID(kStringBundleServiceCID, NS_STRINGBUNDLESERVICE_CID);
@@ -105,17 +110,17 @@ inline PRBool nsXPInstallManager::TimeTo
return PR_TRUE;
}
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.
NS_ADDREF_THIS();
// initialize mLastUpdate to the current time
mLastUpdate = PR_Now();
@@ -127,25 +132,27 @@ nsXPInstallManager::nsXPInstallManager()
nsXPInstallManager::~nsXPInstallManager()
{
if (mTriggers)
delete mTriggers;
}
-NS_IMPL_THREADSAFE_ISUPPORTS9( nsXPInstallManager,
+NS_IMPL_THREADSAFE_ISUPPORTS11(nsXPInstallManager,
nsIXPIListener,
nsIXPIDialogService,
nsIXPInstallManager,
nsIObserver,
nsIStreamListener,
nsIProgressEventSink,
nsIInterfaceRequestor,
nsPICertNotification,
+ nsIBadCertListener,
+ nsIChannelEventSink,
nsISupportsWeakReference)
NS_IMETHODIMP
nsXPInstallManager::InitManagerFromChrome(const PRUnichar **aURLs,
PRUint32 aURLCount,
nsIXPIProgressDialog* aListener)
{
return InitManagerWithHashes(aURLs, nsnull, aURLCount, aListener);
@@ -192,16 +199,18 @@ nsXPInstallManager::InitManagerWithHashe
if (NS_FAILED(rv))
{
delete mTriggers;
mTriggers = nsnull;
Shutdown();
return rv;
}
+ mFromChrome = PR_TRUE;
+
rv = Observe(aListener, XPI_PROGRESS_TOPIC, NS_LITERAL_STRING("open").get());
if (NS_FAILED(rv))
Shutdown();
return rv;
}
NS_IMETHODIMP
@@ -970,27 +979,76 @@ nsXPInstallManager::GetDestinationFile(n
NS_IF_ADDREF(*file);
}
}
}
}
return rv;
}
-
+nsresult
+nsXPInstallManager::CheckCert(nsIChannel* aChannel)
+{
+ nsCOMPtr<nsIURI> 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<nsISupports> security;
+ rv = aChannel->GetSecurityInfo(getter_AddRefs(security));
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsISSLStatusProvider> statusProvider(do_QueryInterface(security));
+ NS_ENSURE_TRUE(statusProvider, NS_ERROR_FAILURE);
+
+ rv = statusProvider->GetSSLStatus(getter_AddRefs(security));
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsISSLStatus> status(do_QueryInterface(security));
+ NS_ENSURE_TRUE(status, NS_ERROR_FAILURE);
+ nsCOMPtr<nsIX509Cert> cert;
+ rv = status->GetServerCert(getter_AddRefs(cert));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIX509Cert> 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)
{
nsresult rv = NS_ERROR_FAILURE;
// If we are dealing with a HTTP request, then treat HTTP error pages as
// download failures.
nsCOMPtr<nsIHttpChannel> 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!
request->Cancel(NS_BINDING_ABORTED);
return NS_OK;
}
}
@@ -1163,19 +1221,62 @@ nsXPInstallManager::GetInterface(const n
rv = ww->GetNewAuthPrompter(nsnull, getter_AddRefs(prompt));
NS_ENSURE_SUCCESS(rv, rv);
nsIAuthPrompt *p = prompt.get();
NS_ADDREF(p);
*_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
nsXPInstallManager::GetIndexFromURL(const PRUnichar* aUrl)
{
// --- figure out which index corresponds to this URL
PRUint32 i;
for (i=0; i < mTriggers->Size(); i++)
--- a/xpinstall/src/nsXPInstallManager.h
+++ b/xpinstall/src/nsXPInstallManager.h
@@ -51,16 +51,18 @@
#include "nsIXPINotifier.h"
#include "nsIXPInstallManager.h"
#include "nsIXPIDialogService.h"
#include "nsXPITriggerInfo.h"
#include "nsIXPIProgressDialog.h"
#include "nsIChromeRegistry.h"
#include "nsIDOMWindowInternal.h"
#include "nsIObserver.h"
+#include "nsIBadCertListener.h"
+#include "nsIChannelEventSink.h"
#include "nsISoftwareUpdate.h"
#include "nsCOMPtr.h"
#include "nsIProgressEventSink.h"
#include "nsIInterfaceRequestor.h"
#include "nsIInterfaceRequestorUtils.h"
@@ -78,60 +80,66 @@
class nsXPInstallManager : public nsIXPIListener,
public nsIXPIDialogService,
public nsIXPInstallManager,
public nsIObserver,
public nsIStreamListener,
public nsIProgressEventSink,
public nsIInterfaceRequestor,
public nsPICertNotification,
+ public nsIBadCertListener,
+ public nsIChannelEventSink,
public nsSupportsWeakReference
{
public:
nsXPInstallManager();
virtual ~nsXPInstallManager();
NS_DECL_ISUPPORTS
NS_DECL_NSIXPILISTENER
NS_DECL_NSIXPIDIALOGSERVICE
NS_DECL_NSIXPINSTALLMANAGER
NS_DECL_NSIOBSERVER
NS_DECL_NSISTREAMLISTENER
NS_DECL_NSIPROGRESSEVENTSINK
NS_DECL_NSIREQUESTOBSERVER
NS_DECL_NSIINTERFACEREQUESTOR
NS_DECL_NSPICERTNOTIFICATION
+ NS_DECL_NSIBADCERTLISTENER
+ NS_DECL_NSICHANNELEVENTSINK
NS_IMETHOD InitManager(nsIScriptGlobalObject* aGlobalObject, nsXPITriggerInfo* aTrigger, PRUint32 aChromeType );
private:
nsresult InitManagerInternal();
NS_IMETHOD DownloadNext();
void Shutdown();
NS_IMETHOD GetDestinationFile(nsString& url, nsILocalFile* *file);
NS_IMETHOD LoadParams(PRUint32 aCount, const PRUnichar** aPackageList, nsIDialogParamBlock** aParams);
#ifdef ENABLE_SKIN_SIMPLE_INSTALLATION_UI
PRBool ConfirmChromeInstall(nsIDOMWindowInternal* aParentWindow, const PRUnichar** aPackage);
#endif
PRBool TimeToUpdate(PRTime now);
PRBool VerifyHash(nsXPITriggerItem* aItem);
PRInt32 GetIndexFromURL(const PRUnichar* aUrl);
+ nsresult CheckCert(nsIChannel* aChannel);
nsXPITriggerInfo* mTriggers;
nsXPITriggerItem* mItem;
PRTime mLastUpdate;
PRUint32 mNextItem;
PRInt32 mNumJars;
PRUint32 mChromeType;
PRInt32 mContentLength;
PRInt32 mOutstandingCertLoads;
PRBool mDialogOpen;
PRBool mCancelled;
PRBool mSelectChrome;
PRBool mNeedsShutdown;
+ PRBool mFromChrome;
nsCOMPtr<nsIXPIProgressDialog> mDlg;
nsCOMPtr<nsISoftwareUpdate> mInstallSvc;
nsCOMPtr<nsIDOMWindowInternal> mParentWindow;
};
#endif