mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-10 01:08:21 +00:00
Bug 387480, Support network-fetched cert import in Web Sites tab of Cert Mgr Most code contributed by Johnathan Nightingale, some by me r=me, sr=rrelyea blocking1.9=beltzner
This commit is contained in:
parent
4826252f22
commit
4a67feba15
@ -39,7 +39,7 @@
|
||||
|
||||
<!ENTITY certmgr.tab.mine "Your Certificates">
|
||||
<!ENTITY certmgr.tab.others "Other People's">
|
||||
<!ENTITY certmgr.tab.websites "Web Sites">
|
||||
<!ENTITY certmgr.tab.websites2 "Internet Sites">
|
||||
<!ENTITY certmgr.tab.ca "Authorities">
|
||||
<!ENTITY certmgr.tab.orphan "Extra">
|
||||
|
||||
@ -128,3 +128,14 @@
|
||||
<!ENTITY certmgr.fields.accesskey "V">
|
||||
<!ENTITY certmgr.hierarchy.label "Certificate Hierarchy">
|
||||
<!ENTITY certmgr.hierarchy.accesskey "C">
|
||||
<!ENTITY certmgr.addException.label "Add Exception…">
|
||||
<!ENTITY certmgr.addException.accesskey "x">
|
||||
|
||||
<!ENTITY exceptionMgr.title "Add Security Exception">
|
||||
<!ENTITY exceptionMgr.exceptionButton "Confirm Security Exception">
|
||||
<!ENTITY exceptionMgr.supplementalWarning "Legitimate banks, stores, and other public sites will not ask you to do this.">
|
||||
<!ENTITY exceptionMgr.certlocation.caption "Internet Site">
|
||||
<!ENTITY exceptionMgr.certlocation.url "Location:">
|
||||
<!ENTITY exceptionMgr.certlocation.download "Get Certificate">
|
||||
<!ENTITY exceptionMgr.certstatus.caption "Certificate Status">
|
||||
<!ENTITY exceptionMgr.certstatus.viewCert "View…">
|
||||
|
@ -199,3 +199,20 @@ writeFileAccessDenied=Access denied
|
||||
writeFileIsLocked=File is locked
|
||||
writeFileNoDeviceSpace=No space left on device
|
||||
writeFileUnknownError=Unknown error
|
||||
|
||||
#Add Security Exception dialog
|
||||
addExceptionBrandedWarning=You are about to override how %S identifies sites.
|
||||
addExceptionInvalidHeader=This site attempts to identity itself with invalid information.
|
||||
addExceptionDomainMismatchShort=Wrong Site
|
||||
addExceptionDomainMismatchLong=Certificate belongs to a different site, which could indicate an identity theft.
|
||||
addExceptionExpiredShort=Outdated Information
|
||||
addExceptionExpiredLong=Certificate is not currently valid. It is impossible to verify whether this identity was reported as stolen or lost.
|
||||
addExceptionUnverifiedShort=Unknown Identity
|
||||
addExceptionUnverifiedLong=Certificate is not trusted, because it hasn't been verified by a recognized authority.
|
||||
addExceptionValidShort=Valid Certificate
|
||||
addExceptionValidLong=This site provides valid, verified identification. There is no need to add an exception.
|
||||
addExceptionCheckingShort=Checking Information
|
||||
addExceptionCheckingLong=Attempting to identify the site...
|
||||
addExceptionNoCertShort=No Information Available
|
||||
addExceptionNoCertLong=Unable to obtain identification status for the given site.
|
||||
addExceptionConnectionFailed=Connection Failed
|
||||
|
@ -100,6 +100,10 @@
|
||||
label="&certmgr.delete2.label;"
|
||||
accesskey="&certmgr.delete.accesskey;"
|
||||
disabled="true" oncommand="deleteCerts();"/>
|
||||
<button id="websites_exceptionButton"
|
||||
label="&certmgr.addException.label;"
|
||||
accesskey="&certmgr.addException.accesskey;"
|
||||
oncommand="addException();"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</overlay>
|
||||
|
@ -620,3 +620,16 @@ function addWebSiteCert()
|
||||
caTreeView.selection.clearSelection();
|
||||
}
|
||||
}
|
||||
|
||||
function addException()
|
||||
{
|
||||
window.openDialog('chrome://pippki/content/exceptionDialog.xul', "",
|
||||
'chrome,centerscreen,modal');
|
||||
var certcache = Components.classes[nsNSSCertCache].createInstance(nsINSSCertCache);
|
||||
certcache.cacheAllCerts();
|
||||
serverTreeView.loadCertsFromCache(certcache, nsIX509Cert.SERVER_CERT);
|
||||
serverTreeView.selection.clearSelection();
|
||||
orphanTreeView.loadCertsFromCache(certcache, nsIX509Cert.UNKNOWN_CERT);
|
||||
orphanTreeView.selection.clearSelection();
|
||||
}
|
||||
|
||||
|
@ -65,7 +65,7 @@
|
||||
<tabs id="certMgrTabbox">
|
||||
<tab id="mine_tab" label="&certmgr.tab.mine;"/>
|
||||
<tab id="others_tab" label="&certmgr.tab.others;"/>
|
||||
<tab id="websites_tab" label="&certmgr.tab.websites;"/>
|
||||
<tab id="websites_tab" label="&certmgr.tab.websites2;"/>
|
||||
<!-- FIXME Add selected="true" to ca_tab when 373525 gets fixed. -->
|
||||
<tab id="ca_tab" label="&certmgr.tab.ca;"/>
|
||||
<tab id="orphan_tab" label="&certmgr.tab.orphan;"/>
|
||||
|
294
security/manager/pki/resources/content/exceptionDialog.js
Normal file
294
security/manager/pki/resources/content/exceptionDialog.js
Normal file
@ -0,0 +1,294 @@
|
||||
/* ***** BEGIN LICENSE BLOCK *****
|
||||
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
*
|
||||
* The contents of this file are subject to the Mozilla Public License Version
|
||||
* 1.1 (the "License"); you may not use this file except in compliance with
|
||||
* the License. You may obtain a copy of the License at
|
||||
* http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS IS" basis,
|
||||
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
* for the specific language governing rights and limitations under the
|
||||
* License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is
|
||||
* Mozilla Corporation.
|
||||
* Portions created by the Initial Developer are Copyright (C) 2007
|
||||
* the Initial Developer. All Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Johnathan Nightingale <johnath@mozilla.com>
|
||||
*
|
||||
* Alternatively, the contents of this file may be used under the terms of
|
||||
* either 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
|
||||
* decision by deleting the provisions above and replace them with the notice
|
||||
* and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
* the provisions above, a recipient may use your version of this file under
|
||||
* the terms of any one of the MPL, the GPL or the LGPL.
|
||||
*
|
||||
* ***** END LICENSE BLOCK ***** */
|
||||
|
||||
|
||||
var gDialog;
|
||||
var gBundleBrand;
|
||||
var gPKIBundle;
|
||||
var gSSLStatus;
|
||||
var gCert;
|
||||
var gChecking;
|
||||
var gBroken;
|
||||
var gNeedReset;
|
||||
|
||||
function badCertListener() {}
|
||||
badCertListener.prototype = {
|
||||
getInterface: function (aIID) {
|
||||
return this.QueryInterface(aIID);
|
||||
},
|
||||
QueryInterface: function(aIID) {
|
||||
if (aIID.equals(Components.interfaces.nsIBadCertListener2) ||
|
||||
aIID.equals(Components.interfaces.nsIInterfaceRequestor) ||
|
||||
aIID.equals(Components.interfaces.nsISupports))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
},
|
||||
handle_test_result: function () {
|
||||
if (gSSLStatus)
|
||||
gCert = gSSLStatus.QueryInterface(Components.interfaces.nsISSLStatus).serverCert;
|
||||
},
|
||||
notifyCertProblem: function MSR_notifyCertProblem(socketInfo, sslStatus, targetHost) {
|
||||
gBroken = true;
|
||||
gSSLStatus = sslStatus;
|
||||
this.handle_test_result();
|
||||
return true; // suppress error UI
|
||||
}
|
||||
}
|
||||
|
||||
function initExceptionDialog() {
|
||||
gNeedReset = false;
|
||||
gDialog = document.documentElement;
|
||||
gBundleBrand = srGetStrBundle("chrome://branding/locale/brand.properties");
|
||||
gPKIBundle = srGetStrBundle("chrome://pippki/locale/pippki.properties");
|
||||
|
||||
var brandName = gBundleBrand.GetStringFromName("brandShortName");
|
||||
|
||||
setText("warningText", gPKIBundle.formatStringFromName("addExceptionBrandedWarning",
|
||||
[brandName], 1));
|
||||
gDialog.getButton("extra1").disabled = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempt to download the certificate for the location specified, and populate
|
||||
* the Certificate Status section with the result.
|
||||
*/
|
||||
function checkCert() {
|
||||
|
||||
gCert = null;
|
||||
gSSLStatus = null;
|
||||
gChecking = true;
|
||||
gBroken = false;
|
||||
updateCertStatus();
|
||||
|
||||
var req = new XMLHttpRequest();
|
||||
var uri = getURI();
|
||||
try {
|
||||
if(uri) {
|
||||
req.open('GET', uri.prePath, false);
|
||||
req.channel.notificationCallbacks = new badCertListener();
|
||||
req.send(null);
|
||||
}
|
||||
} catch (e) {
|
||||
// We *expect* exceptions if there are problems with the certificate
|
||||
// presented by the site. Log it, just in case, but we can proceed here,
|
||||
// with appropriate sanity checks
|
||||
Components.utils.reportError(e);
|
||||
} finally {
|
||||
gChecking = false;
|
||||
}
|
||||
|
||||
if(req.channel && req.channel.securityInfo) {
|
||||
const Ci = Components.interfaces;
|
||||
gSSLStatus = req.channel.securityInfo
|
||||
.QueryInterface(Ci.nsISSLStatusProvider).SSLStatus;
|
||||
gCert = gSSLStatus.QueryInterface(Ci.nsISSLStatus).serverCert;
|
||||
}
|
||||
updateCertStatus();
|
||||
}
|
||||
|
||||
/**
|
||||
* Build and return a URI, based on the information supplied in the
|
||||
* Certificate Location fields
|
||||
*/
|
||||
function getURI() {
|
||||
// Use fixup service instead of just ioservice's newURI since it's quite likely
|
||||
// that the host will be supplied without a protocol prefix, resulting in malformed
|
||||
// uri exceptions being thrown.
|
||||
var fus = Components.classes["@mozilla.org/docshell/urifixup;1"]
|
||||
.getService(Components.interfaces.nsIURIFixup);
|
||||
var uri = fus.createFixupURI(document.getElementById("locationTextBox").value, 0);
|
||||
|
||||
if(!uri)
|
||||
return null;
|
||||
|
||||
if(uri.scheme == "http")
|
||||
uri.scheme = "https";
|
||||
|
||||
if (uri.port == -1)
|
||||
uri.port = 443;
|
||||
|
||||
return uri;
|
||||
}
|
||||
|
||||
function resetDialog() {
|
||||
document.getElementById("viewCertButton").disabled = true;
|
||||
gDialog.getButton("extra1").disabled = true;
|
||||
setText("headerDescription", "");
|
||||
setText("statusDescription", "");
|
||||
setText("statusLongDescription", "");
|
||||
setText("status2Description", "");
|
||||
setText("status2LongDescription", "");
|
||||
setText("status3Description", "");
|
||||
setText("status3LongDescription", "");
|
||||
}
|
||||
|
||||
/**
|
||||
* Called by input textboxes to manage UI state
|
||||
*/
|
||||
function handleTextChange() {
|
||||
var checkCertButton = document.getElementById('checkCertButton');
|
||||
checkCertButton.disabled = !(document.getElementById("locationTextBox").value);
|
||||
if (gNeedReset) {
|
||||
gNeedReset = false;
|
||||
resetDialog();
|
||||
}
|
||||
}
|
||||
|
||||
function updateCertStatus() {
|
||||
var shortDesc, longDesc;
|
||||
var shortDesc2, longDesc2;
|
||||
var shortDesc3, longDesc3;
|
||||
var use2 = false;
|
||||
var use3 = false;
|
||||
if(gCert) {
|
||||
if(gBroken) {
|
||||
var mms = "addExceptionDomainMismatchShort";
|
||||
var mml = "addExceptionDomainMismatchLong";
|
||||
var exs = "addExceptionExpiredShort";
|
||||
var exl = "addExceptionExpiredLong";
|
||||
var uts = "addExceptionUnverifiedShort";
|
||||
var utl = "addExceptionUnverifiedLong";
|
||||
var use1 = false;
|
||||
if (gSSLStatus.isDomainMismatch) {
|
||||
use1 = true;
|
||||
shortDesc = mms;
|
||||
longDesc = mml;
|
||||
}
|
||||
if (gSSLStatus.isNotValidAtThisTime) {
|
||||
if (!use1) {
|
||||
use1 = true;
|
||||
shortDesc = exs;
|
||||
longDesc = exl;
|
||||
}
|
||||
else {
|
||||
use2 = true;
|
||||
shortDesc2 = exs;
|
||||
longDesc2 = exl;
|
||||
}
|
||||
}
|
||||
if (gSSLStatus.isUntrusted) {
|
||||
if (!use1) {
|
||||
use1 = true;
|
||||
shortDesc = uts;
|
||||
longDesc = utl;
|
||||
}
|
||||
else if (!use2) {
|
||||
use2 = true;
|
||||
shortDesc2 = uts;
|
||||
longDesc2 = utl;
|
||||
}
|
||||
else {
|
||||
use3 = true;
|
||||
shortDesc3 = uts;
|
||||
longDesc3 = utl;
|
||||
}
|
||||
}
|
||||
|
||||
// In these cases, we do want to enable the "Add Exception" button
|
||||
gDialog.getButton("extra1").disabled = false;
|
||||
setText("headerDescription", gPKIBundle.GetStringFromName("addExceptionInvalidHeader"));
|
||||
}
|
||||
else {
|
||||
shortDesc = "addExceptionValidShort";
|
||||
longDesc = "addExceptionValidLong";
|
||||
gDialog.getButton("extra1").disabled = true;
|
||||
}
|
||||
|
||||
document.getElementById("viewCertButton").disabled = false;
|
||||
}
|
||||
else if (gChecking) {
|
||||
shortDesc = "addExceptionCheckingShort";
|
||||
longDesc = "addExceptionCheckingLong";
|
||||
document.getElementById("viewCertButton").disabled = true;
|
||||
gDialog.getButton("extra1").disabled = true;
|
||||
}
|
||||
else {
|
||||
shortDesc = "addExceptionNoCertShort";
|
||||
longDesc = "addExceptionNoCertLong";
|
||||
document.getElementById("viewCertButton").disabled = true;
|
||||
gDialog.getButton("extra1").disabled = true;
|
||||
}
|
||||
|
||||
setText("statusDescription", gPKIBundle.GetStringFromName(shortDesc));
|
||||
setText("statusLongDescription", gPKIBundle.GetStringFromName(longDesc));
|
||||
|
||||
if (use2) {
|
||||
setText("status2Description", gPKIBundle.GetStringFromName(shortDesc2));
|
||||
setText("status2LongDescription", gPKIBundle.GetStringFromName(longDesc2));
|
||||
}
|
||||
|
||||
if (use3) {
|
||||
setText("status3Description", gPKIBundle.GetStringFromName(shortDesc3));
|
||||
setText("status3LongDescription", gPKIBundle.GetStringFromName(longDesc3));
|
||||
}
|
||||
|
||||
gNeedReset = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle user request to display certificate details
|
||||
*/
|
||||
function viewCertButtonClick() {
|
||||
if (gCert)
|
||||
viewCertHelper(this, gCert);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle user request to add an exception for the specified cert
|
||||
*/
|
||||
function addException() {
|
||||
if(!gCert || !gSSLStatus)
|
||||
return;
|
||||
|
||||
var overrideService = Components.classes["@mozilla.org/security/certoverride;1"]
|
||||
.getService(Components.interfaces.nsICertOverrideService);
|
||||
var flags = 0;
|
||||
if(gSSLStatus.isUntrusted)
|
||||
flags |= overrideService.ERROR_UNTRUSTED;
|
||||
if(gSSLStatus.isDomainMismatch)
|
||||
flags |= overrideService.ERROR_MISMATCH;
|
||||
if(gSSLStatus.isNotValidAtThisTime)
|
||||
flags |= overrideService.ERROR_TIME;
|
||||
|
||||
overrideService.rememberValidityOverride(
|
||||
getURI().hostPort,
|
||||
gCert,
|
||||
flags);
|
||||
gDialog.acceptDialog();
|
||||
}
|
106
security/manager/pki/resources/content/exceptionDialog.xul
Normal file
106
security/manager/pki/resources/content/exceptionDialog.xul
Normal file
@ -0,0 +1,106 @@
|
||||
<?xml version="1.0"?>
|
||||
<!-- ***** BEGIN LICENSE BLOCK *****
|
||||
- Version: MPL 1.1/GPL 2.0/LGPL 2.1
|
||||
-
|
||||
- The contents of this file are subject to the Mozilla Public License Version
|
||||
- 1.1 (the "License"); you may not use this file except in compliance with
|
||||
- the License. You may obtain a copy of the License at
|
||||
- http://www.mozilla.org/MPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS IS" basis,
|
||||
- WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
|
||||
- for the specific language governing rights and limitations under the
|
||||
- License.
|
||||
-
|
||||
- The Original Code is mozilla.org code.
|
||||
-
|
||||
- The Initial Developer of the Original Code is
|
||||
- Mozilla Corp
|
||||
- Portions created by the Initial Developer are Copyright (C) 2007
|
||||
- the Initial Developer. All Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- Kai Engert <kengert@redhat.com>
|
||||
- Johnathan Nightingale <johnath@mozilla.com>
|
||||
-
|
||||
- Alternatively, the contents of this file may be used under the terms of
|
||||
- either 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
|
||||
- decision by deleting the provisions above and replace them with the notice
|
||||
- and other provisions required by the GPL or the LGPL. If you do not delete
|
||||
- the provisions above, a recipient may use your version of this file under
|
||||
- the terms of any one of the MPL, the GPL or the LGPL.
|
||||
-
|
||||
- ***** END LICENSE BLOCK ***** -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<!DOCTYPE dialog SYSTEM "chrome://pippki/locale/certManager.dtd">
|
||||
|
||||
<dialog id="exceptiondialog"
|
||||
windowtype="mozilla:exceptiondialog"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
title="&exceptionMgr.title;"
|
||||
buttons="cancel,extra1"
|
||||
buttonlabelextra1="&exceptionMgr.exceptionButton;"
|
||||
style="width: 500px; height: 480px;"
|
||||
onload="initExceptionDialog();"
|
||||
ondialogextra1="addException();"
|
||||
persist="screenX screenY width height"
|
||||
defaultButton="null">
|
||||
|
||||
<script type="application/x-javascript" src="chrome://global/content/strres.js"/>
|
||||
<script type="application/x-javascript" src="chrome://pippki/content/pippki.js"/>
|
||||
<script type="application/x-javascript" src="chrome://pippki/content/exceptionDialog.js"/>
|
||||
|
||||
<hbox>
|
||||
<vbox>
|
||||
<image src="chrome://global/skin/icons/warning-large.png"/>
|
||||
<spacer flex="1"/>
|
||||
</vbox>
|
||||
<vbox flex="1">
|
||||
<description id="warningText"
|
||||
style="whitespace: -moz-pre-wrap"/>
|
||||
<description id="warningSupplemental"
|
||||
style="font-weight: bold; whitespace: -moz-pre-wrap;">
|
||||
&exceptionMgr.supplementalWarning;
|
||||
</description>
|
||||
</vbox>
|
||||
</hbox>
|
||||
|
||||
<groupbox id="locationGroupBox">
|
||||
<caption label="&exceptionMgr.certlocation.caption;"/>
|
||||
<hbox align="center">
|
||||
<label control="locationTextBox" value="&exceptionMgr.certlocation.url;"/>
|
||||
<textbox id="locationTextBox" flex="1" oninput="handleTextChange();" value="https://"/>
|
||||
<button id="checkCertButton" disabled="true"
|
||||
label="&exceptionMgr.certlocation.download;" onclick="checkCert();"/>
|
||||
</hbox>
|
||||
</groupbox>
|
||||
|
||||
<groupbox id="certStatusGroupBox" flex="1">
|
||||
<caption label="&exceptionMgr.certstatus.caption;"/>
|
||||
<hbox>
|
||||
<description id="headerDescription" style="whitespace: -moz-pre-wrap;"
|
||||
flex="1"/>
|
||||
<vbox>
|
||||
<button id="viewCertButton" label="&exceptionMgr.certstatus.viewCert;"
|
||||
disabled="true" onclick="viewCertButtonClick();"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
<description id="statusDescription"
|
||||
style="font-weight: bold; padding-bottom: 1em;"/>
|
||||
<description id="statusLongDescription" style="whitespace: -moz-pre-wrap;"/>
|
||||
<description id="status2Description"
|
||||
style="font-weight: bold; padding-bottom: 1em;"/>
|
||||
<description id="status2LongDescription" style="whitespace: -moz-pre-wrap;"/>
|
||||
<description id="status3Description"
|
||||
style="font-weight: bold; padding-bottom: 1em;"/>
|
||||
<description id="status3LongDescription" style="whitespace: -moz-pre-wrap;"/>
|
||||
<spacer flex="1"/>
|
||||
</groupbox>
|
||||
</dialog>
|
@ -31,6 +31,8 @@ pippki.jar:
|
||||
content/pippki/editemailcert.xul (content/editemailcert.xul)
|
||||
content/pippki/editsslcert.xul (content/editsslcert.xul)
|
||||
content/pippki/editcerts.js (content/editcerts.js)
|
||||
content/pippki/exceptionDialog.xul (content/exceptionDialog.xul)
|
||||
content/pippki/exceptionDialog.js (content/exceptionDialog.js)
|
||||
content/pippki/deletecert.xul (content/deletecert.xul)
|
||||
content/pippki/deletecert.js (content/deletecert.js)
|
||||
content/pippki/viewCertDetails.js (content/viewCertDetails.js)
|
||||
|
Loading…
x
Reference in New Issue
Block a user