mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-27 10:57:34 +09:00
Issue #1258 - Part 1: Import mailnews, ldap, and mork from comm-esr52.9.1
This commit is contained in:
parent
23e0d82436
commit
e400f4130a
1564 changed files with 510348 additions and 0 deletions
478
mailnews/extensions/smime/content/am-smime.js
Normal file
478
mailnews/extensions/smime/content/am-smime.js
Normal file
|
|
@ -0,0 +1,478 @@
|
|||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var nsIX509CertDB = Components.interfaces.nsIX509CertDB;
|
||||
var nsX509CertDBContractID = "@mozilla.org/security/x509certdb;1";
|
||||
var nsIX509Cert = Components.interfaces.nsIX509Cert;
|
||||
|
||||
var email_recipient_cert_usage = 5;
|
||||
var email_signing_cert_usage = 4;
|
||||
|
||||
var gIdentity;
|
||||
var gPref = null;
|
||||
var gEncryptionCertName = null;
|
||||
var gHiddenEncryptionPolicy = null;
|
||||
var gEncryptionChoices = null;
|
||||
var gSignCertName = null;
|
||||
var gSignMessages = null;
|
||||
var gEncryptAlways = null;
|
||||
var gNeverEncrypt = null;
|
||||
var gBundle = null;
|
||||
var gBrandBundle;
|
||||
var gSmimePrefbranch;
|
||||
var gEncryptionChoicesLocked;
|
||||
var gSigningChoicesLocked;
|
||||
var kEncryptionCertPref = "identity.encryption_cert_name";
|
||||
var kSigningCertPref = "identity.signing_cert_name";
|
||||
|
||||
function onInit()
|
||||
{
|
||||
smimeInitializeFields();
|
||||
}
|
||||
|
||||
function smimeInitializeFields()
|
||||
{
|
||||
// initialize all of our elements based on the current identity values....
|
||||
gEncryptionCertName = document.getElementById(kEncryptionCertPref);
|
||||
gHiddenEncryptionPolicy = document.getElementById("identity.encryptionpolicy");
|
||||
gEncryptionChoices = document.getElementById("encryptionChoices");
|
||||
gSignCertName = document.getElementById(kSigningCertPref);
|
||||
gSignMessages = document.getElementById("identity.sign_mail");
|
||||
gEncryptAlways = document.getElementById("encrypt_mail_always");
|
||||
gNeverEncrypt = document.getElementById("encrypt_mail_never");
|
||||
gBundle = document.getElementById("bundle_smime");
|
||||
gBrandBundle = document.getElementById("bundle_brand");
|
||||
|
||||
gEncryptionChoicesLocked = false;
|
||||
gSigningChoicesLocked = false;
|
||||
|
||||
if (!gIdentity) {
|
||||
// The user is going to create a new identity.
|
||||
// Set everything to default values.
|
||||
// Do not take over the values from gAccount.defaultIdentity
|
||||
// as the new identity is going to have a different mail address.
|
||||
|
||||
gEncryptionCertName.value = "";
|
||||
gEncryptionCertName.nickname = "";
|
||||
gEncryptionCertName.dbKey = "";
|
||||
gSignCertName.value = "";
|
||||
gSignCertName.nickname = "";
|
||||
gSignCertName.dbKey = "";
|
||||
|
||||
gEncryptAlways.setAttribute("disabled", true);
|
||||
gNeverEncrypt.setAttribute("disabled", true);
|
||||
gSignMessages.setAttribute("disabled", true);
|
||||
|
||||
gSignMessages.checked = false;
|
||||
gEncryptionChoices.value = 0;
|
||||
}
|
||||
else {
|
||||
var certdb = Components.classes[nsX509CertDBContractID].getService(nsIX509CertDB);
|
||||
var x509cert = null;
|
||||
|
||||
gEncryptionCertName.value = gIdentity.getUnicharAttribute("encryption_cert_name");
|
||||
gEncryptionCertName.dbKey = gIdentity.getCharAttribute("encryption_cert_dbkey");
|
||||
// If we succeed in looking up the certificate by the dbkey pref, then
|
||||
// append the serial number " [...]" to the display value, and remember the
|
||||
// nickname in a separate property.
|
||||
try {
|
||||
if (certdb && gEncryptionCertName.dbKey &&
|
||||
(x509cert = certdb.findCertByDBKey(gEncryptionCertName.dbKey))) {
|
||||
gEncryptionCertName.value = x509cert.nickname + " [" + x509cert.serialNumber + "]";
|
||||
gEncryptionCertName.nickname = x509cert.nickname;
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
gEncryptionChoices.value = gIdentity.getIntAttribute("encryptionpolicy");
|
||||
|
||||
if (!gEncryptionCertName.value) {
|
||||
gEncryptAlways.setAttribute("disabled", true);
|
||||
gNeverEncrypt.setAttribute("disabled", true);
|
||||
}
|
||||
else {
|
||||
enableEncryptionControls(true);
|
||||
}
|
||||
|
||||
gSignCertName.value = gIdentity.getUnicharAttribute("signing_cert_name");
|
||||
gSignCertName.dbKey = gIdentity.getCharAttribute("signing_cert_dbkey");
|
||||
x509cert = null;
|
||||
// same procedure as with gEncryptionCertName (see above)
|
||||
try {
|
||||
if (certdb && gSignCertName.dbKey &&
|
||||
(x509cert = certdb.findCertByDBKey(gSignCertName.dbKey))) {
|
||||
gSignCertName.value = x509cert.nickname + " [" + x509cert.serialNumber + "]";
|
||||
gSignCertName.nickname = x509cert.nickname;
|
||||
}
|
||||
} catch(e) {}
|
||||
|
||||
gSignMessages.checked = gIdentity.getBoolAttribute("sign_mail");
|
||||
if (!gSignCertName.value)
|
||||
{
|
||||
gSignMessages.setAttribute("disabled", true);
|
||||
}
|
||||
else {
|
||||
enableSigningControls(true);
|
||||
}
|
||||
}
|
||||
|
||||
// Always start with enabling signing and encryption cert select buttons.
|
||||
// This will keep the visibility of buttons in a sane state as user
|
||||
// jumps from security panel of one account to another.
|
||||
enableCertSelectButtons();
|
||||
|
||||
// Disable all locked elements on the panel
|
||||
if (gIdentity)
|
||||
onLockPreference();
|
||||
}
|
||||
|
||||
function onPreInit(account, accountValues)
|
||||
{
|
||||
gIdentity = account.defaultIdentity;
|
||||
}
|
||||
|
||||
function onSave()
|
||||
{
|
||||
smimeSave();
|
||||
}
|
||||
|
||||
function smimeSave()
|
||||
{
|
||||
// find out which radio for the encryption radio group is selected and set that on our hidden encryptionChoice pref....
|
||||
var newValue = gEncryptionChoices.value;
|
||||
gHiddenEncryptionPolicy.setAttribute('value', newValue);
|
||||
gIdentity.setIntAttribute("encryptionpolicy", newValue);
|
||||
gIdentity.setUnicharAttribute("encryption_cert_name",
|
||||
gEncryptionCertName.nickname || gEncryptionCertName.value);
|
||||
gIdentity.setCharAttribute("encryption_cert_dbkey", gEncryptionCertName.dbKey);
|
||||
|
||||
gIdentity.setBoolAttribute("sign_mail", gSignMessages.checked);
|
||||
gIdentity.setUnicharAttribute("signing_cert_name",
|
||||
gSignCertName.nickname || gSignCertName.value);
|
||||
gIdentity.setCharAttribute("signing_cert_dbkey", gSignCertName.dbKey);
|
||||
}
|
||||
|
||||
function smimeOnAcceptEditor()
|
||||
{
|
||||
try {
|
||||
if (!onOk())
|
||||
return false;
|
||||
}
|
||||
catch (ex) {}
|
||||
|
||||
smimeSave();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
function onLockPreference()
|
||||
{
|
||||
var initPrefString = "mail.identity";
|
||||
var finalPrefString;
|
||||
|
||||
var allPrefElements = [
|
||||
{ prefstring:"signingCertSelectButton", id:"signingCertSelectButton"},
|
||||
{ prefstring:"encryptionCertSelectButton", id:"encryptionCertSelectButton"},
|
||||
{ prefstring:"sign_mail", id:"identity.sign_mail"},
|
||||
{ prefstring:"encryptionpolicy", id:"encryptionChoices"}
|
||||
];
|
||||
|
||||
finalPrefString = initPrefString + "." + gIdentity.key + ".";
|
||||
gSmimePrefbranch = Services.prefs.getBranch(finalPrefString);
|
||||
|
||||
disableIfLocked( allPrefElements );
|
||||
}
|
||||
|
||||
|
||||
// Does the work of disabling an element given the array which contains xul id/prefstring pairs.
|
||||
// Also saves the id/locked state in an array so that other areas of the code can avoid
|
||||
// stomping on the disabled state indiscriminately.
|
||||
function disableIfLocked( prefstrArray )
|
||||
{
|
||||
var i;
|
||||
for (i=0; i<prefstrArray.length; i++) {
|
||||
var id = prefstrArray[i].id;
|
||||
var element = document.getElementById(id);
|
||||
if (gSmimePrefbranch.prefIsLocked(prefstrArray[i].prefstring)) {
|
||||
// If encryption choices radio group is locked, make sure the individual
|
||||
// choices in the group are locked. Set a global (gEncryptionChoicesLocked)
|
||||
// indicating the status so that locking can be maintained further.
|
||||
if (id == "encryptionChoices") {
|
||||
document.getElementById("encrypt_mail_never").setAttribute("disabled", "true");
|
||||
document.getElementById("encrypt_mail_always").setAttribute("disabled", "true");
|
||||
gEncryptionChoicesLocked = true;
|
||||
}
|
||||
// If option to sign mail is locked (with true/false set in config file), disable
|
||||
// the corresponding checkbox and set a global (gSigningChoicesLocked) in order to
|
||||
// honor the locking as user changes other elements on the panel.
|
||||
if (id == "identity.sign_mail") {
|
||||
document.getElementById("identity.sign_mail").setAttribute("disabled", "true");
|
||||
gSigningChoicesLocked = true;
|
||||
}
|
||||
else {
|
||||
element.setAttribute("disabled", "true");
|
||||
if (id == "signingCertSelectButton") {
|
||||
document.getElementById("signingCertClearButton").setAttribute("disabled", "true");
|
||||
}
|
||||
else if (id == "encryptionCertSelectButton") {
|
||||
document.getElementById("encryptionCertClearButton").setAttribute("disabled", "true");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function alertUser(message)
|
||||
{
|
||||
Services.prompt.alert(window,
|
||||
gBrandBundle.getString("brandShortName"),
|
||||
message);
|
||||
}
|
||||
|
||||
function askUser(message)
|
||||
{
|
||||
let button = Services.prompt.confirmEx(
|
||||
window,
|
||||
gBrandBundle.getString("brandShortName"),
|
||||
message,
|
||||
Services.prompt.STD_YES_NO_BUTTONS,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
null,
|
||||
{});
|
||||
// confirmEx returns button index:
|
||||
return (button == 0);
|
||||
}
|
||||
|
||||
function checkOtherCert(cert, pref, usage, msgNeedCertWantSame, msgWantSame, msgNeedCertWantToSelect, enabler)
|
||||
{
|
||||
var otherCertInfo = document.getElementById(pref);
|
||||
if (!otherCertInfo)
|
||||
return;
|
||||
|
||||
if (otherCertInfo.dbKey == cert.dbKey)
|
||||
// all is fine, same cert is now selected for both purposes
|
||||
return;
|
||||
|
||||
var certdb = Components.classes[nsX509CertDBContractID].getService(nsIX509CertDB);
|
||||
if (!certdb)
|
||||
return;
|
||||
|
||||
if (email_recipient_cert_usage == usage) {
|
||||
matchingOtherCert = certdb.findEmailEncryptionCert(cert.nickname);
|
||||
}
|
||||
else if (email_signing_cert_usage == usage) {
|
||||
matchingOtherCert = certdb.findEmailSigningCert(cert.nickname);
|
||||
}
|
||||
else
|
||||
return;
|
||||
|
||||
var userWantsSameCert = false;
|
||||
|
||||
if (!otherCertInfo.value.length) {
|
||||
if (matchingOtherCert && (matchingOtherCert.dbKey == cert.dbKey)) {
|
||||
userWantsSameCert = askUser(gBundle.getString(msgNeedCertWantSame));
|
||||
}
|
||||
else {
|
||||
if (askUser(gBundle.getString(msgNeedCertWantToSelect))) {
|
||||
smimeSelectCert(pref);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (matchingOtherCert && (matchingOtherCert.dbKey == cert.dbKey)) {
|
||||
userWantsSameCert = askUser(gBundle.getString(msgWantSame));
|
||||
}
|
||||
}
|
||||
|
||||
if (userWantsSameCert) {
|
||||
otherCertInfo.value = cert.nickname + " [" + cert.serialNumber + "]";
|
||||
otherCertInfo.nickname = cert.nickname;
|
||||
otherCertInfo.dbKey = cert.dbKey;
|
||||
enabler(true);
|
||||
}
|
||||
}
|
||||
|
||||
function smimeSelectCert(smime_cert)
|
||||
{
|
||||
var certInfo = document.getElementById(smime_cert);
|
||||
if (!certInfo)
|
||||
return;
|
||||
|
||||
var picker = Components.classes["@mozilla.org/user_cert_picker;1"]
|
||||
.createInstance(Components.interfaces.nsIUserCertPicker);
|
||||
var canceled = new Object;
|
||||
var x509cert = 0;
|
||||
var certUsage;
|
||||
var selectEncryptionCert;
|
||||
|
||||
if (smime_cert == kEncryptionCertPref) {
|
||||
selectEncryptionCert = true;
|
||||
certUsage = email_recipient_cert_usage;
|
||||
} else if (smime_cert == kSigningCertPref) {
|
||||
selectEncryptionCert = false;
|
||||
certUsage = email_signing_cert_usage;
|
||||
}
|
||||
|
||||
try {
|
||||
x509cert = picker.pickByUsage(window,
|
||||
certInfo.value,
|
||||
certUsage, // this is from enum SECCertUsage
|
||||
false, true,
|
||||
gIdentity.email,
|
||||
canceled);
|
||||
} catch(e) {
|
||||
canceled.value = false;
|
||||
x509cert = null;
|
||||
}
|
||||
|
||||
if (!canceled.value) {
|
||||
if (!x509cert) {
|
||||
if (gIdentity.email) {
|
||||
alertUser(gBundle.getFormattedString(selectEncryptionCert ?
|
||||
"NoEncryptionCertForThisAddress" :
|
||||
"NoSigningCertForThisAddress",
|
||||
[ gIdentity.email ]));
|
||||
} else {
|
||||
alertUser(gBundle.getString(selectEncryptionCert ?
|
||||
"NoEncryptionCert" : "NoSigningCert"));
|
||||
}
|
||||
}
|
||||
else {
|
||||
certInfo.removeAttribute("disabled");
|
||||
certInfo.value = x509cert.nickname + " [" + x509cert.serialNumber + "]";
|
||||
certInfo.nickname = x509cert.nickname;
|
||||
certInfo.dbKey = x509cert.dbKey;
|
||||
|
||||
if (selectEncryptionCert) {
|
||||
enableEncryptionControls(true);
|
||||
|
||||
checkOtherCert(x509cert,
|
||||
kSigningCertPref, email_signing_cert_usage,
|
||||
"signing_needCertWantSame",
|
||||
"signing_wantSame",
|
||||
"signing_needCertWantToSelect",
|
||||
enableSigningControls);
|
||||
} else {
|
||||
enableSigningControls(true);
|
||||
|
||||
checkOtherCert(x509cert,
|
||||
kEncryptionCertPref, email_recipient_cert_usage,
|
||||
"encryption_needCertWantSame",
|
||||
"encryption_wantSame",
|
||||
"encryption_needCertWantToSelect",
|
||||
enableEncryptionControls);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
enableCertSelectButtons();
|
||||
}
|
||||
|
||||
function enableEncryptionControls(do_enable)
|
||||
{
|
||||
if (gEncryptionChoicesLocked)
|
||||
return;
|
||||
|
||||
if (do_enable) {
|
||||
gEncryptAlways.removeAttribute("disabled");
|
||||
gNeverEncrypt.removeAttribute("disabled");
|
||||
gEncryptionCertName.removeAttribute("disabled");
|
||||
}
|
||||
else {
|
||||
gEncryptAlways.setAttribute("disabled", "true");
|
||||
gNeverEncrypt.setAttribute("disabled", "true");
|
||||
gEncryptionCertName.setAttribute("disabled", "true");
|
||||
gEncryptionChoices.value = 0;
|
||||
}
|
||||
}
|
||||
|
||||
function enableSigningControls(do_enable)
|
||||
{
|
||||
if (gSigningChoicesLocked)
|
||||
return;
|
||||
|
||||
if (do_enable) {
|
||||
gSignMessages.removeAttribute("disabled");
|
||||
gSignCertName.removeAttribute("disabled");
|
||||
}
|
||||
else {
|
||||
gSignMessages.setAttribute("disabled", "true");
|
||||
gSignCertName.setAttribute("disabled", "true");
|
||||
gSignMessages.checked = false;
|
||||
}
|
||||
}
|
||||
|
||||
function enableCertSelectButtons()
|
||||
{
|
||||
document.getElementById("signingCertSelectButton").removeAttribute("disabled");
|
||||
|
||||
if (document.getElementById('identity.signing_cert_name').value.length)
|
||||
document.getElementById("signingCertClearButton").removeAttribute("disabled");
|
||||
else
|
||||
document.getElementById("signingCertClearButton").setAttribute("disabled", "true");
|
||||
|
||||
document.getElementById("encryptionCertSelectButton").removeAttribute("disabled");
|
||||
|
||||
if (document.getElementById('identity.encryption_cert_name').value.length)
|
||||
document.getElementById("encryptionCertClearButton").removeAttribute("disabled");
|
||||
else
|
||||
document.getElementById("encryptionCertClearButton").setAttribute("disabled", "true");
|
||||
}
|
||||
|
||||
function smimeClearCert(smime_cert)
|
||||
{
|
||||
var certInfo = document.getElementById(smime_cert);
|
||||
if (!certInfo)
|
||||
return;
|
||||
|
||||
certInfo.setAttribute("disabled", "true");
|
||||
certInfo.value = "";
|
||||
certInfo.nickname = "";
|
||||
certInfo.dbKey = "";
|
||||
|
||||
if (smime_cert == kEncryptionCertPref) {
|
||||
enableEncryptionControls(false);
|
||||
} else if (smime_cert == kSigningCertPref) {
|
||||
enableSigningControls(false);
|
||||
}
|
||||
|
||||
enableCertSelectButtons();
|
||||
}
|
||||
|
||||
function openCertManager()
|
||||
{
|
||||
// Check for an existing certManager window and focus it; it's not
|
||||
// application modal.
|
||||
let lastCertManager = Services.wm.getMostRecentWindow("mozilla:certmanager");
|
||||
if (lastCertManager)
|
||||
lastCertManager.focus();
|
||||
else
|
||||
window.openDialog("chrome://pippki/content/certManager.xul", "",
|
||||
"centerscreen,resizable=yes,dialog=no");
|
||||
}
|
||||
|
||||
function openDeviceManager()
|
||||
{
|
||||
// Check for an existing deviceManager window and focus it; it's not
|
||||
// application modal.
|
||||
let lastCertManager = Services.wm.getMostRecentWindow("mozilla:devicemanager");
|
||||
if (lastCertManager)
|
||||
lastCertManager.focus();
|
||||
else
|
||||
window.openDialog("chrome://pippki/content/device_manager.xul", "",
|
||||
"centerscreen,resizable=yes,dialog=no");
|
||||
}
|
||||
|
||||
function smimeOnLoadEditor()
|
||||
{
|
||||
smimeInitializeFields();
|
||||
|
||||
document.documentElement.setAttribute("ondialogaccept",
|
||||
"return smimeOnAcceptEditor();");
|
||||
}
|
||||
|
||||
26
mailnews/extensions/smime/content/am-smime.xul
Normal file
26
mailnews/extensions/smime/content/am-smime.xul
Normal file
|
|
@ -0,0 +1,26 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://messenger/skin/accountManage.css" type="text/css"?>
|
||||
|
||||
<?xul-overlay href="chrome://messenger/content/am-smimeOverlay.xul"?>
|
||||
|
||||
<!DOCTYPE page SYSTEM "chrome://messenger/locale/am-smime.dtd">
|
||||
|
||||
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
class="color-dialog"
|
||||
onload="parent.onPanelLoaded('am-smime.xul');"
|
||||
ondialogaccept="smimeOnAcceptEditor();">
|
||||
|
||||
<vbox flex="1" style="overflow: auto;">
|
||||
<script type="application/javascript" src="chrome://messenger/content/AccountManager.js"/>
|
||||
<script type="application/javascript" src="chrome://messenger/content/am-smime.js"/>
|
||||
|
||||
<dialogheader title="&securityTitle.label;"/>
|
||||
|
||||
<vbox flex="1" id="smimeEditing"/>
|
||||
</vbox>
|
||||
|
||||
</page>
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://messenger/skin/accountManage.css"
|
||||
type="text/css"?>
|
||||
|
||||
<?xul-overlay href="chrome://messenger/content/am-smimeOverlay.xul"?>
|
||||
|
||||
<!DOCTYPE overlay SYSTEM "chrome://messenger/locale/am-smime.dtd">
|
||||
|
||||
<!--
|
||||
This is the overlay that adds the SMIME configurator
|
||||
to the identity editor of the account manager
|
||||
-->
|
||||
<overlay id="smimeAmIdEditOverlay"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://messenger/content/AccountManager.js"/>
|
||||
<script type="application/javascript"
|
||||
src="chrome://messenger/content/am-smime.js"/>
|
||||
|
||||
<tabs id="identitySettings">
|
||||
<tab label="&securityTab.label;"/>
|
||||
</tabs>
|
||||
|
||||
<tabpanels id="identityTabsPanels">
|
||||
<vbox flex="1" name="smimeEditingContent" id="smimeEditing"/>
|
||||
</tabpanels>
|
||||
|
||||
<script type="application/javascript">
|
||||
<![CDATA[
|
||||
window.addEventListener("load", smimeOnLoadEditor, false);
|
||||
]]>
|
||||
</script>
|
||||
</overlay>
|
||||
102
mailnews/extensions/smime/content/am-smimeOverlay.xul
Normal file
102
mailnews/extensions/smime/content/am-smimeOverlay.xul
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://messenger/skin/accountManage.css"
|
||||
type="text/css"?>
|
||||
|
||||
<!DOCTYPE overlay SYSTEM "chrome://messenger/locale/am-smime.dtd">
|
||||
|
||||
<overlay xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<vbox id="smimeEditing">
|
||||
|
||||
<stringbundleset>
|
||||
<stringbundle id="bundle_smime" src="chrome://messenger/locale/am-smime.properties"/>
|
||||
<stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
|
||||
</stringbundleset>
|
||||
|
||||
<label hidden="true" wsm_persist="true" id="identity.encryptionpolicy"/>
|
||||
|
||||
<description>&securityHeading.label;</description>
|
||||
|
||||
<groupbox id="signing.titlebox">
|
||||
<caption label="&signingGroupTitle.label;"/>
|
||||
|
||||
<label value="&signingCert.message;" control="identity.signing_cert_name"
|
||||
prefstring="mail.identity.%identitykey%.encryptionpolicy"/>
|
||||
|
||||
<hbox align="center">
|
||||
<textbox id="identity.signing_cert_name" wsm_persist="true" flex="1"
|
||||
prefstring="mail.identity.%identitykey%.signing_cert_name"
|
||||
readonly="true" disabled="true"/>
|
||||
|
||||
<button id="signingCertSelectButton"
|
||||
label="&digitalSign.certificate.button;"
|
||||
accesskey="&digitalSign.certificate.accesskey;"
|
||||
oncommand="smimeSelectCert('identity.signing_cert_name')"/>
|
||||
|
||||
<button id="signingCertClearButton"
|
||||
label="&digitalSign.certificate_clear.button;"
|
||||
accesskey="&digitalSign.certificate_clear.accesskey;"
|
||||
oncommand="smimeClearCert('identity.signing_cert_name')"/>
|
||||
</hbox>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
||||
<checkbox id="identity.sign_mail" wsm_persist="true"
|
||||
prefstring="mail.identity.%identitykey%.sign_mail"
|
||||
label="&signMessage.label;" accesskey="&signMessage.accesskey;"/>
|
||||
</groupbox>
|
||||
|
||||
<groupbox id="encryption.titlebox">
|
||||
<caption label="&encryptionGroupTitle.label;"/>
|
||||
|
||||
<label value="&encryptionCert.message;"
|
||||
control="identity.encryption_cert_name"/>
|
||||
|
||||
<hbox align="center">
|
||||
<textbox id="identity.encryption_cert_name" wsm_persist="true" flex="1"
|
||||
prefstring="mail.identity.%identitykey%.encryption_cert_name"
|
||||
readonly="true" disabled="true"/>
|
||||
|
||||
<button id="encryptionCertSelectButton"
|
||||
label="&encryption.certificate.button;"
|
||||
accesskey="&encryption.certificate.accesskey;"
|
||||
oncommand="smimeSelectCert('identity.encryption_cert_name')"/>
|
||||
|
||||
<button id="encryptionCertClearButton"
|
||||
label="&encryption.certificate_clear.button;"
|
||||
accesskey="&encryption.certificate_clear.accesskey;"
|
||||
oncommand="smimeClearCert('identity.encryption_cert_name')"/>
|
||||
</hbox>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
||||
<label value="&encryptionChoiceLabel.label;" control="encryptionChoices"/>
|
||||
|
||||
<radiogroup id="encryptionChoices">
|
||||
<radio id="encrypt_mail_never" wsm_persist="true" value="0"
|
||||
label="&neverEncrypt.label;"
|
||||
accesskey="&neverEncrypt.accesskey;"/>
|
||||
|
||||
<radio id="encrypt_mail_always" wsm_persist="true" value="2"
|
||||
label="&alwaysEncryptMessage.label;"
|
||||
accesskey="&alwaysEncryptMessage.accesskey;"/>
|
||||
</radiogroup>
|
||||
</groupbox>
|
||||
|
||||
<!-- Certificate manager -->
|
||||
<groupbox id="smimeCertificateManager" orient="horizontal">
|
||||
<caption label="&certificates.label;"/>
|
||||
<button id="openCertManagerButton" oncommand="openCertManager();"
|
||||
label="&manageCerts2.label;" accesskey="&manageCerts2.accesskey;"
|
||||
prefstring="security.disable_button.openCertManager"/>
|
||||
<button id="openDeviceManagerButton" oncommand="openDeviceManager();"
|
||||
label="&manageDevices.label;" accesskey="&manageDevices.accesskey;"
|
||||
prefstring="security.disable_button.openDeviceManager"/>
|
||||
</groupbox>
|
||||
</vbox>
|
||||
</overlay>
|
||||
265
mailnews/extensions/smime/content/certFetchingStatus.js
Normal file
265
mailnews/extensions/smime/content/certFetchingStatus.js
Normal file
|
|
@ -0,0 +1,265 @@
|
|||
/* 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/. */
|
||||
|
||||
/* We expect the following arguments:
|
||||
- pref name of LDAP directory to fetch from
|
||||
- array with email addresses
|
||||
|
||||
Display modal dialog with message and stop button.
|
||||
In onload, kick off binding to LDAP.
|
||||
When bound, kick off the searches.
|
||||
On finding certificates, import into permanent cert database.
|
||||
When all searches are finished, close the dialog.
|
||||
*/
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var nsIX509CertDB = Components.interfaces.nsIX509CertDB;
|
||||
var nsX509CertDB = "@mozilla.org/security/x509certdb;1";
|
||||
var CertAttribute = "usercertificate;binary";
|
||||
|
||||
var gEmailAddresses;
|
||||
var gDirectoryPref;
|
||||
var gLdapServerURL;
|
||||
var gLdapConnection;
|
||||
var gCertDB;
|
||||
var gLdapOperation;
|
||||
var gLogin;
|
||||
|
||||
function onLoad()
|
||||
{
|
||||
gDirectoryPref = window.arguments[0];
|
||||
gEmailAddresses = window.arguments[1];
|
||||
|
||||
if (!gEmailAddresses.length)
|
||||
{
|
||||
window.close();
|
||||
return;
|
||||
}
|
||||
|
||||
setTimeout(search, 1);
|
||||
}
|
||||
|
||||
function search()
|
||||
{
|
||||
// get the login to authenticate as, if there is one
|
||||
try {
|
||||
gLogin = Services.prefs.getComplexValue(gDirectoryPref + ".auth.dn", Components.interfaces.nsISupportsString).data;
|
||||
} catch (ex) {
|
||||
// if we don't have this pref, no big deal
|
||||
}
|
||||
|
||||
try {
|
||||
let url = Services.prefs.getCharPref(gDirectoryPref + ".uri");
|
||||
|
||||
gLdapServerURL = Services.io
|
||||
.newURI(url, null, null).QueryInterface(Components.interfaces.nsILDAPURL);
|
||||
|
||||
gLdapConnection = Components.classes["@mozilla.org/network/ldap-connection;1"]
|
||||
.createInstance().QueryInterface(Components.interfaces.nsILDAPConnection);
|
||||
|
||||
gLdapConnection.init(gLdapServerURL, gLogin, new boundListener(),
|
||||
null, Components.interfaces.nsILDAPConnection.VERSION3);
|
||||
|
||||
} catch (ex) {
|
||||
dump(ex);
|
||||
dump(" exception creating ldap connection\n");
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
|
||||
function stopFetching()
|
||||
{
|
||||
if (gLdapOperation) {
|
||||
try {
|
||||
gLdapOperation.abandon();
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
function importCert(ber_value)
|
||||
{
|
||||
if (!gCertDB) {
|
||||
gCertDB = Components.classes[nsX509CertDB].getService(nsIX509CertDB);
|
||||
}
|
||||
|
||||
var cert_length = new Object();
|
||||
var cert_bytes = ber_value.get(cert_length);
|
||||
|
||||
if (cert_bytes) {
|
||||
gCertDB.importEmailCertificate(cert_bytes, cert_length.value, null);
|
||||
}
|
||||
}
|
||||
|
||||
function getLDAPOperation()
|
||||
{
|
||||
gLdapOperation = Components.classes["@mozilla.org/network/ldap-operation;1"]
|
||||
.createInstance().QueryInterface(Components.interfaces.nsILDAPOperation);
|
||||
|
||||
gLdapOperation.init(gLdapConnection,
|
||||
new ldapMessageListener(),
|
||||
null);
|
||||
}
|
||||
|
||||
function getPassword()
|
||||
{
|
||||
// we only need a password if we are using credentials
|
||||
if (gLogin)
|
||||
{
|
||||
let authPrompter = Services.ww.getNewAuthPrompter(window.QueryInterface(Components.interfaces.nsIDOMWindow));
|
||||
let strBundle = document.getElementById('bundle_ldap');
|
||||
let password = { value: "" };
|
||||
|
||||
// nsLDAPAutocompleteSession uses asciiHost instead of host for the prompt text, I think we should be
|
||||
// consistent.
|
||||
if (authPrompter.promptPassword(strBundle.getString("authPromptTitle"),
|
||||
strBundle.getFormattedString("authPromptText", [gLdapServerURL.asciiHost]),
|
||||
gLdapServerURL.spec,
|
||||
authPrompter.SAVE_PASSWORD_PERMANENTLY,
|
||||
password))
|
||||
return password.value;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function kickOffBind()
|
||||
{
|
||||
try {
|
||||
getLDAPOperation();
|
||||
gLdapOperation.simpleBind(getPassword());
|
||||
}
|
||||
catch (e) {
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
|
||||
function kickOffSearch()
|
||||
{
|
||||
try {
|
||||
var prefix1 = "";
|
||||
var suffix1 = "";
|
||||
|
||||
var urlFilter = gLdapServerURL.filter;
|
||||
|
||||
if (urlFilter != null && urlFilter.length > 0 && urlFilter != "(objectclass=*)") {
|
||||
if (urlFilter.startsWith('(')) {
|
||||
prefix1 = "(&" + urlFilter;
|
||||
}
|
||||
else {
|
||||
prefix1 = "(&(" + urlFilter + ")";
|
||||
}
|
||||
suffix1 = ")";
|
||||
}
|
||||
|
||||
var prefix2 = "";
|
||||
var suffix2 = "";
|
||||
|
||||
if (gEmailAddresses.length > 1) {
|
||||
prefix2 = "(|";
|
||||
suffix2 = ")";
|
||||
}
|
||||
|
||||
var mailFilter = "";
|
||||
|
||||
for (var i = 0; i < gEmailAddresses.length; ++i) {
|
||||
mailFilter += "(mail=" + gEmailAddresses[i] + ")";
|
||||
}
|
||||
|
||||
var filter = prefix1 + prefix2 + mailFilter + suffix2 + suffix1;
|
||||
|
||||
var wanted_attributes = CertAttribute;
|
||||
|
||||
// Max search results =>
|
||||
// Double number of email addresses, because each person might have
|
||||
// multiple certificates listed. We expect at most two certificates,
|
||||
// one for signing, one for encrypting.
|
||||
// Maybe that number should be larger, to allow for deployments,
|
||||
// where even more certs can be stored per user???
|
||||
|
||||
var maxEntriesWanted = gEmailAddresses.length * 2;
|
||||
|
||||
getLDAPOperation();
|
||||
gLdapOperation.searchExt(gLdapServerURL.dn, gLdapServerURL.scope,
|
||||
filter, wanted_attributes, 0, maxEntriesWanted);
|
||||
}
|
||||
catch (e) {
|
||||
window.close();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
function boundListener() {
|
||||
}
|
||||
|
||||
boundListener.prototype.QueryInterface =
|
||||
function(iid) {
|
||||
if (iid.equals(Components.interfaces.nsISupports) ||
|
||||
iid.equals(Components.interfaces.nsILDAPMessageListener))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
boundListener.prototype.onLDAPMessage =
|
||||
function(aMessage) {
|
||||
}
|
||||
|
||||
boundListener.prototype.onLDAPInit =
|
||||
function(aConn, aStatus) {
|
||||
kickOffBind();
|
||||
}
|
||||
|
||||
|
||||
function ldapMessageListener() {
|
||||
}
|
||||
|
||||
ldapMessageListener.prototype.QueryInterface =
|
||||
function(iid) {
|
||||
if (iid.equals(Components.interfaces.nsISupports) ||
|
||||
iid.equals(Components.interfaces.nsILDAPMessageListener))
|
||||
return this;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
ldapMessageListener.prototype.onLDAPMessage =
|
||||
function(aMessage) {
|
||||
if (Components.interfaces.nsILDAPMessage.RES_SEARCH_RESULT == aMessage.type) {
|
||||
window.close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (Components.interfaces.nsILDAPMessage.RES_BIND == aMessage.type) {
|
||||
if (Components.interfaces.nsILDAPErrors.SUCCESS != aMessage.errorCode) {
|
||||
window.close();
|
||||
}
|
||||
else {
|
||||
kickOffSearch();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (Components.interfaces.nsILDAPMessage.RES_SEARCH_ENTRY == aMessage.type) {
|
||||
var outSize = new Object();
|
||||
try {
|
||||
var outBinValues = aMessage.getBinaryValues(CertAttribute, outSize);
|
||||
|
||||
var i;
|
||||
for (i=0; i < outSize.value; ++i) {
|
||||
importCert(outBinValues[i]);
|
||||
}
|
||||
}
|
||||
catch (e) {
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
ldapMessageListener.prototype.onLDAPInit =
|
||||
function(aConn, aStatus) {
|
||||
}
|
||||
24
mailnews/extensions/smime/content/certFetchingStatus.xul
Normal file
24
mailnews/extensions/smime/content/certFetchingStatus.xul
Normal file
|
|
@ -0,0 +1,24 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://messenger/skin/smime/certFetchingStatus.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE dialog SYSTEM "chrome://messenger-smime/locale/certFetchingStatus.dtd">
|
||||
|
||||
<dialog id="certFetchingStatus" title="&title.label;"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
style="width: 50em;"
|
||||
buttons="cancel"
|
||||
buttonlabelcancel="&stop.label;"
|
||||
ondialogcancel="return stopFetching();"
|
||||
onload="onLoad();">
|
||||
|
||||
<stringbundle id="bundle_ldap" src="chrome://mozldap/locale/ldap.properties"/>
|
||||
<script type="application/javascript" src="chrome://messenger-smime/content/certFetchingStatus.js"/>
|
||||
|
||||
<description>&info.message;</description>
|
||||
|
||||
</dialog>
|
||||
73
mailnews/extensions/smime/content/certpicker.js
Normal file
73
mailnews/extensions/smime/content/certpicker.js
Normal file
|
|
@ -0,0 +1,73 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* 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/. */
|
||||
"use strict";
|
||||
|
||||
const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
|
||||
|
||||
var dialogParams;
|
||||
var itemCount = 0;
|
||||
|
||||
function onLoad()
|
||||
{
|
||||
dialogParams = window.arguments[0].QueryInterface(nsIDialogParamBlock);
|
||||
|
||||
var selectElement = document.getElementById("nicknames");
|
||||
itemCount = dialogParams.GetInt(0);
|
||||
|
||||
var selIndex = dialogParams.GetInt(1);
|
||||
if (selIndex < 0) {
|
||||
selIndex = 0;
|
||||
}
|
||||
|
||||
for (let i = 0; i < itemCount; i++) {
|
||||
let menuItemNode = document.createElement("menuitem");
|
||||
let nick = dialogParams.GetString(i);
|
||||
menuItemNode.setAttribute("value", i);
|
||||
menuItemNode.setAttribute("label", nick); // This is displayed.
|
||||
selectElement.firstChild.appendChild(menuItemNode);
|
||||
|
||||
if (selIndex == i) {
|
||||
selectElement.selectedItem = menuItemNode;
|
||||
}
|
||||
}
|
||||
|
||||
dialogParams.SetInt(0, 0); // Set cancel return value.
|
||||
setDetails();
|
||||
}
|
||||
|
||||
function setDetails()
|
||||
{
|
||||
let selItem = document.getElementById("nicknames").value;
|
||||
if (selItem.length == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
let index = parseInt(selItem);
|
||||
let details = dialogParams.GetString(index + itemCount);
|
||||
document.getElementById("details").value = details;
|
||||
}
|
||||
|
||||
function onCertSelected()
|
||||
{
|
||||
setDetails();
|
||||
}
|
||||
|
||||
function doOK()
|
||||
{
|
||||
// Signal that the user accepted.
|
||||
dialogParams.SetInt(0, 1);
|
||||
|
||||
// Signal the index of the selected cert in the list of cert nicknames
|
||||
// provided.
|
||||
let index = parseInt(document.getElementById("nicknames").value);
|
||||
dialogParams.SetInt(1, index);
|
||||
return true;
|
||||
}
|
||||
|
||||
function doCancel()
|
||||
{
|
||||
dialogParams.SetInt(0, 0); // Signal that the user cancelled.
|
||||
return true;
|
||||
}
|
||||
38
mailnews/extensions/smime/content/certpicker.xul
Normal file
38
mailnews/extensions/smime/content/certpicker.xul
Normal file
|
|
@ -0,0 +1,38 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<!DOCTYPE dialog [
|
||||
<!ENTITY % amSMIMEDTD SYSTEM "chrome://messenger/locale/am-smime.dtd" >
|
||||
%amSMIMEDTD;
|
||||
]>
|
||||
|
||||
<dialog id="certPicker" title="&certPicker.title;"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
style="width: 50em;"
|
||||
buttons="accept,cancel"
|
||||
ondialogaccept="return doOK();"
|
||||
ondialogcancel="return doCancel();"
|
||||
onload="onLoad();">
|
||||
|
||||
<script type="application/javascript"
|
||||
src="chrome://messenger/content/certpicker.js"/>
|
||||
|
||||
<hbox align="center">
|
||||
<broadcaster id="certSelected" oncommand="onCertSelected();"/>
|
||||
<label id="pickerInfo" value="&certPicker.info;"/>
|
||||
<!-- The items in this menulist must never be sorted,
|
||||
but remain in the order filled by the application
|
||||
-->
|
||||
<menulist id="nicknames" observes="certSelected">
|
||||
<menupopup/>
|
||||
</menulist>
|
||||
</hbox>
|
||||
<separator class="thin"/>
|
||||
<label value="&certPicker.detailsLabel;"/>
|
||||
<textbox readonly="true" id="details" multiline="true"
|
||||
style="height: 12em;" flex="1"/>
|
||||
</dialog>
|
||||
357
mailnews/extensions/smime/content/msgCompSMIMEOverlay.js
Normal file
357
mailnews/extensions/smime/content/msgCompSMIMEOverlay.js
Normal file
|
|
@ -0,0 +1,357 @@
|
|||
/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
* 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/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
// Account encryption policy values:
|
||||
// const kEncryptionPolicy_Never = 0;
|
||||
// 'IfPossible' was used by ns4.
|
||||
// const kEncryptionPolicy_IfPossible = 1;
|
||||
var kEncryptionPolicy_Always = 2;
|
||||
|
||||
var gEncryptedURIService =
|
||||
Components.classes["@mozilla.org/messenger-smime/smime-encrypted-uris-service;1"]
|
||||
.getService(Components.interfaces.nsIEncryptedSMIMEURIsService);
|
||||
|
||||
var gNextSecurityButtonCommand = "";
|
||||
var gSMFields = null;
|
||||
var gEncryptOptionChanged;
|
||||
var gSignOptionChanged;
|
||||
|
||||
function onComposerLoad()
|
||||
{
|
||||
// Are we already set up ? Or are the required fields missing ?
|
||||
if (gSMFields || !gMsgCompose || !gMsgCompose.compFields)
|
||||
return;
|
||||
|
||||
gMsgCompose.compFields.securityInfo = null;
|
||||
|
||||
gSMFields = Components.classes["@mozilla.org/messenger-smime/composefields;1"]
|
||||
.createInstance(Components.interfaces.nsIMsgSMIMECompFields);
|
||||
if (!gSMFields)
|
||||
return;
|
||||
|
||||
gMsgCompose.compFields.securityInfo = gSMFields;
|
||||
|
||||
// Set up the intial security state.
|
||||
gSMFields.requireEncryptMessage =
|
||||
gCurrentIdentity.getIntAttribute("encryptionpolicy") == kEncryptionPolicy_Always;
|
||||
if (!gSMFields.requireEncryptMessage &&
|
||||
gEncryptedURIService &&
|
||||
gEncryptedURIService.isEncrypted(gMsgCompose.originalMsgURI))
|
||||
{
|
||||
// Override encryption setting if original is known as encrypted.
|
||||
gSMFields.requireEncryptMessage = true;
|
||||
}
|
||||
if (gSMFields.requireEncryptMessage)
|
||||
setEncryptionUI();
|
||||
else
|
||||
setNoEncryptionUI();
|
||||
|
||||
gSMFields.signMessage = gCurrentIdentity.getBoolAttribute("sign_mail");
|
||||
if (gSMFields.signMessage)
|
||||
setSignatureUI();
|
||||
else
|
||||
setNoSignatureUI();
|
||||
}
|
||||
|
||||
addEventListener("load", smimeComposeOnLoad, {capture: false, once: true});
|
||||
|
||||
// this function gets called multiple times
|
||||
function smimeComposeOnLoad()
|
||||
{
|
||||
onComposerLoad();
|
||||
|
||||
top.controllers.appendController(SecurityController);
|
||||
|
||||
addEventListener("compose-from-changed", onComposerFromChanged, true);
|
||||
addEventListener("compose-send-message", onComposerSendMessage, true);
|
||||
|
||||
addEventListener("unload", smimeComposeOnUnload, {capture: false, once: true});
|
||||
}
|
||||
|
||||
function smimeComposeOnUnload()
|
||||
{
|
||||
removeEventListener("compose-from-changed", onComposerFromChanged, true);
|
||||
removeEventListener("compose-send-message", onComposerSendMessage, true);
|
||||
|
||||
top.controllers.removeController(SecurityController);
|
||||
}
|
||||
|
||||
function showNeedSetupInfo()
|
||||
{
|
||||
let compSmimeBundle = document.getElementById("bundle_comp_smime");
|
||||
let brandBundle = document.getElementById("bundle_brand");
|
||||
if (!compSmimeBundle || !brandBundle)
|
||||
return;
|
||||
|
||||
let buttonPressed = Services.prompt.confirmEx(window,
|
||||
brandBundle.getString("brandShortName"),
|
||||
compSmimeBundle.getString("NeedSetup"),
|
||||
Services.prompt.STD_YES_NO_BUTTONS, 0, 0, 0, null, {});
|
||||
if (buttonPressed == 0)
|
||||
openHelp("sign-encrypt", "chrome://communicator/locale/help/suitehelp.rdf");
|
||||
}
|
||||
|
||||
function toggleEncryptMessage()
|
||||
{
|
||||
if (!gSMFields)
|
||||
return;
|
||||
|
||||
gSMFields.requireEncryptMessage = !gSMFields.requireEncryptMessage;
|
||||
|
||||
if (gSMFields.requireEncryptMessage)
|
||||
{
|
||||
// Make sure we have a cert.
|
||||
if (!gCurrentIdentity.getUnicharAttribute("encryption_cert_name"))
|
||||
{
|
||||
gSMFields.requireEncryptMessage = false;
|
||||
showNeedSetupInfo();
|
||||
return;
|
||||
}
|
||||
|
||||
setEncryptionUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
setNoEncryptionUI();
|
||||
}
|
||||
|
||||
gEncryptOptionChanged = true;
|
||||
}
|
||||
|
||||
function toggleSignMessage()
|
||||
{
|
||||
if (!gSMFields)
|
||||
return;
|
||||
|
||||
gSMFields.signMessage = !gSMFields.signMessage;
|
||||
|
||||
if (gSMFields.signMessage) // make sure we have a cert name...
|
||||
{
|
||||
if (!gCurrentIdentity.getUnicharAttribute("signing_cert_name"))
|
||||
{
|
||||
gSMFields.signMessage = false;
|
||||
showNeedSetupInfo();
|
||||
return;
|
||||
}
|
||||
|
||||
setSignatureUI();
|
||||
}
|
||||
else
|
||||
{
|
||||
setNoSignatureUI();
|
||||
}
|
||||
|
||||
gSignOptionChanged = true;
|
||||
}
|
||||
|
||||
function setSecuritySettings(menu_id)
|
||||
{
|
||||
if (!gSMFields)
|
||||
return;
|
||||
|
||||
document.getElementById("menu_securityEncryptRequire" + menu_id)
|
||||
.setAttribute("checked", gSMFields.requireEncryptMessage);
|
||||
document.getElementById("menu_securitySign" + menu_id)
|
||||
.setAttribute("checked", gSMFields.signMessage);
|
||||
}
|
||||
|
||||
function setNextCommand(what)
|
||||
{
|
||||
gNextSecurityButtonCommand = what;
|
||||
}
|
||||
|
||||
function doSecurityButton()
|
||||
{
|
||||
var what = gNextSecurityButtonCommand;
|
||||
gNextSecurityButtonCommand = "";
|
||||
|
||||
switch (what)
|
||||
{
|
||||
case "encryptMessage":
|
||||
toggleEncryptMessage();
|
||||
break;
|
||||
|
||||
case "signMessage":
|
||||
toggleSignMessage();
|
||||
break;
|
||||
|
||||
case "show":
|
||||
default:
|
||||
showMessageComposeSecurityStatus();
|
||||
}
|
||||
}
|
||||
|
||||
function setNoSignatureUI()
|
||||
{
|
||||
top.document.getElementById("securityStatus").removeAttribute("signing");
|
||||
top.document.getElementById("signing-status").collapsed = true;
|
||||
}
|
||||
|
||||
function setSignatureUI()
|
||||
{
|
||||
top.document.getElementById("securityStatus").setAttribute("signing", "ok");
|
||||
top.document.getElementById("signing-status").collapsed = false;
|
||||
}
|
||||
|
||||
function setNoEncryptionUI()
|
||||
{
|
||||
top.document.getElementById("securityStatus").removeAttribute("crypto");
|
||||
top.document.getElementById("encryption-status").collapsed = true;
|
||||
}
|
||||
|
||||
function setEncryptionUI()
|
||||
{
|
||||
top.document.getElementById("securityStatus").setAttribute("crypto", "ok");
|
||||
top.document.getElementById("encryption-status").collapsed = false;
|
||||
}
|
||||
|
||||
function showMessageComposeSecurityStatus()
|
||||
{
|
||||
Recipients2CompFields(gMsgCompose.compFields);
|
||||
|
||||
window.openDialog(
|
||||
"chrome://messenger-smime/content/msgCompSecurityInfo.xul",
|
||||
"",
|
||||
"chrome,modal,resizable,centerscreen",
|
||||
{
|
||||
compFields : gMsgCompose.compFields,
|
||||
subject : GetMsgSubjectElement().value,
|
||||
smFields : gSMFields,
|
||||
isSigningCertAvailable :
|
||||
gCurrentIdentity.getUnicharAttribute("signing_cert_name") != "",
|
||||
isEncryptionCertAvailable :
|
||||
gCurrentIdentity.getUnicharAttribute("encryption_cert_name") != "",
|
||||
currentIdentity : gCurrentIdentity
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
var SecurityController =
|
||||
{
|
||||
supportsCommand: function(command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case "cmd_viewSecurityStatus":
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
isCommandEnabled: function(command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case "cmd_viewSecurityStatus":
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function onComposerSendMessage()
|
||||
{
|
||||
let missingCount = new Object();
|
||||
let emailAddresses = new Object();
|
||||
|
||||
try
|
||||
{
|
||||
if (!gMsgCompose.compFields.securityInfo.requireEncryptMessage)
|
||||
return;
|
||||
|
||||
Components.classes["@mozilla.org/messenger-smime/smimejshelper;1"]
|
||||
.createInstance(Components.interfaces.nsISMimeJSHelper)
|
||||
.getNoCertAddresses(gMsgCompose.compFields,
|
||||
missingCount,
|
||||
emailAddresses);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (missingCount.value > 0)
|
||||
{
|
||||
// The rules here: If the current identity has a directoryServer set, then
|
||||
// use that, otherwise, try the global preference instead.
|
||||
|
||||
let autocompleteDirectory;
|
||||
|
||||
// Does the current identity override the global preference?
|
||||
if (gCurrentIdentity.overrideGlobalPref)
|
||||
{
|
||||
autocompleteDirectory = gCurrentIdentity.directoryServer;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Try the global one
|
||||
if (Services.prefs.getBoolPref("ldap_2.autoComplete.useDirectory"))
|
||||
autocompleteDirectory =
|
||||
Services.prefs.getCharPref("ldap_2.autoComplete.directoryServer");
|
||||
}
|
||||
|
||||
if (autocompleteDirectory)
|
||||
window.openDialog("chrome://messenger-smime/content/certFetchingStatus.xul",
|
||||
"",
|
||||
"chrome,modal,resizable,centerscreen",
|
||||
autocompleteDirectory,
|
||||
emailAddresses.value);
|
||||
}
|
||||
}
|
||||
|
||||
function onComposerFromChanged()
|
||||
{
|
||||
if (!gSMFields)
|
||||
return;
|
||||
|
||||
var encryptionPolicy = gCurrentIdentity.getIntAttribute("encryptionpolicy");
|
||||
var useEncryption = false;
|
||||
|
||||
if (!gEncryptOptionChanged)
|
||||
{
|
||||
// Encryption wasn't manually checked.
|
||||
// Set up the encryption policy from the setting of the new identity.
|
||||
|
||||
// 0 == never, 1 == if possible (ns4), 2 == always encrypt.
|
||||
useEncryption = (encryptionPolicy == kEncryptionPolicy_Always);
|
||||
}
|
||||
else
|
||||
{
|
||||
useEncryption = !!gCurrentIdentity.getUnicharAttribute("encryption_cert_name");
|
||||
}
|
||||
|
||||
gSMFields.requireEncryptMessage = useEncryption;
|
||||
if (useEncryption)
|
||||
setEncryptionUI();
|
||||
else
|
||||
setNoEncryptionUI();
|
||||
|
||||
// - If signing is disabled, we will not turn it on automatically.
|
||||
// - If signing is enabled, but the new account defaults to not sign, we will turn signing off.
|
||||
var signMessage = gCurrentIdentity.getBoolAttribute("sign_mail");
|
||||
var useSigning = false;
|
||||
|
||||
if (!gSignOptionChanged)
|
||||
{
|
||||
// Signing wasn't manually checked.
|
||||
// Set up the signing policy from the setting of the new identity.
|
||||
useSigning = signMessage;
|
||||
}
|
||||
else
|
||||
{
|
||||
useSigning = !!gCurrentIdentity.getUnicharAttribute("signing_cert_name");
|
||||
}
|
||||
gSMFields.signMessage = useSigning;
|
||||
if (useSigning)
|
||||
setSignatureUI();
|
||||
else
|
||||
setNoSignatureUI();
|
||||
}
|
||||
85
mailnews/extensions/smime/content/msgCompSMIMEOverlay.xul
Normal file
85
mailnews/extensions/smime/content/msgCompSMIMEOverlay.xul
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
|
||||
<?xml-stylesheet href="chrome://messenger/skin/smime/msgCompSMIMEOverlay.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE overlay SYSTEM "chrome://messenger-smime/locale/msgCompSMIMEOverlay.dtd">
|
||||
|
||||
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script type="application/javascript" src="chrome://messenger-smime/content/msgCompSMIMEOverlay.js"/>
|
||||
|
||||
<window id="msgcomposeWindow">
|
||||
<broadcaster id="securityStatus" crypto="" signing=""/>
|
||||
<observes element="securityStatus" attribute="crypto" />
|
||||
<observes element="securityStatus" attribute="signing" />
|
||||
<stringbundle id="bundle_comp_smime" src="chrome://messenger-smime/locale/msgCompSMIMEOverlay.properties"/>
|
||||
<stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
|
||||
</window>
|
||||
|
||||
<menupopup id="optionsMenuPopup"
|
||||
onpopupshowing="setSecuritySettings(1);">
|
||||
<menuseparator id="smimeOptionsSeparator"/>
|
||||
|
||||
<menuitem id="menu_securityEncryptRequire1"
|
||||
type="checkbox"
|
||||
label="&menu_securityEncryptRequire.label;"
|
||||
accesskey="&menu_securityEncryptRequire.accesskey;"
|
||||
oncommand="toggleEncryptMessage();"/>
|
||||
<menuitem id="menu_securitySign1"
|
||||
type="checkbox"
|
||||
label="&menu_securitySign.label;"
|
||||
accesskey="&menu_securitySign.accesskey;"
|
||||
oncommand="toggleSignMessage();"/>
|
||||
</menupopup>
|
||||
|
||||
<toolbarpalette id="MsgComposeToolbarPalette">
|
||||
<toolbarbutton id="button-security"
|
||||
type="menu-button"
|
||||
class="toolbarbutton-1"
|
||||
label="&securityButton.label;"
|
||||
tooltiptext="&securityButton.tooltip;"
|
||||
oncommand="doSecurityButton();">
|
||||
<menupopup onpopupshowing="setSecuritySettings(2);">
|
||||
<menuitem id="menu_securityEncryptRequire2"
|
||||
type="checkbox"
|
||||
label="&menu_securityEncryptRequire.label;"
|
||||
accesskey="&menu_securityEncryptRequire.accesskey;"
|
||||
oncommand="setNextCommand('encryptMessage');"/>
|
||||
<menuitem id="menu_securitySign2"
|
||||
type="checkbox"
|
||||
label="&menu_securitySign.label;"
|
||||
accesskey="&menu_securitySign.accesskey;"
|
||||
oncommand="setNextCommand('signMessage');"/>
|
||||
<menuseparator id="smimeToolbarButtonSeparator"/>
|
||||
<menuitem id="menu_securityStatus2"
|
||||
label="&menu_securityStatus.label;"
|
||||
accesskey="&menu_securityStatus.accesskey;"
|
||||
oncommand="setNextCommand('show');"/>
|
||||
</menupopup>
|
||||
</toolbarbutton>
|
||||
</toolbarpalette>
|
||||
|
||||
<statusbar id="status-bar">
|
||||
<statusbarpanel insertbefore="offline-status" class="statusbarpanel-iconic" collapsed="true"
|
||||
id="signing-status" oncommand="showMessageComposeSecurityStatus();"/>
|
||||
<statusbarpanel insertbefore="offline-status" class="statusbarpanel-iconic" collapsed="true"
|
||||
id="encryption-status" oncommand="showMessageComposeSecurityStatus();"/>
|
||||
</statusbar>
|
||||
|
||||
<commandset id="composeCommands">
|
||||
<command id="cmd_viewSecurityStatus" oncommand="showMessageComposeSecurityStatus();"/>
|
||||
</commandset>
|
||||
|
||||
<menupopup id="menu_View_Popup">
|
||||
<menuseparator id="viewMenuBeforeSecurityStatusSeparator"/>
|
||||
<menuitem id="menu_viewSecurityStatus"
|
||||
label="&menu_viewSecurityStatus.label;"
|
||||
accesskey="&menu_viewSecurityStatus.accesskey;"
|
||||
command="cmd_viewSecurityStatus"/>
|
||||
</menupopup>
|
||||
|
||||
</overlay>
|
||||
244
mailnews/extensions/smime/content/msgCompSecurityInfo.js
Normal file
244
mailnews/extensions/smime/content/msgCompSecurityInfo.js
Normal file
|
|
@ -0,0 +1,244 @@
|
|||
/* 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/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var gListBox;
|
||||
var gViewButton;
|
||||
var gBundle;
|
||||
|
||||
var gEmailAddresses;
|
||||
var gCertStatusSummaries;
|
||||
var gCertIssuedInfos;
|
||||
var gCertExpiresInfos;
|
||||
var gCerts;
|
||||
var gCount;
|
||||
|
||||
var gSMimeContractID = "@mozilla.org/messenger-smime/smimejshelper;1";
|
||||
var gISMimeJSHelper = Components.interfaces.nsISMimeJSHelper;
|
||||
var gIX509Cert = Components.interfaces.nsIX509Cert;
|
||||
var nsICertificateDialogs = Components.interfaces.nsICertificateDialogs;
|
||||
var nsCertificateDialogs = "@mozilla.org/nsCertificateDialogs;1"
|
||||
|
||||
function getStatusExplanation(value)
|
||||
{
|
||||
switch (value)
|
||||
{
|
||||
case gIX509Cert.VERIFIED_OK:
|
||||
return gBundle.getString("StatusValid");
|
||||
|
||||
case gIX509Cert.NOT_VERIFIED_UNKNOWN:
|
||||
case gIX509Cert.INVALID_CA:
|
||||
case gIX509Cert.USAGE_NOT_ALLOWED:
|
||||
return gBundle.getString("StatusInvalid");
|
||||
|
||||
case gIX509Cert.CERT_REVOKED:
|
||||
return gBundle.getString("StatusRevoked");
|
||||
|
||||
case gIX509Cert.CERT_EXPIRED:
|
||||
return gBundle.getString("StatusExpired");
|
||||
|
||||
case gIX509Cert.CERT_NOT_TRUSTED:
|
||||
case gIX509Cert.ISSUER_NOT_TRUSTED:
|
||||
case gIX509Cert.ISSUER_UNKNOWN:
|
||||
return gBundle.getString("StatusUntrusted");
|
||||
}
|
||||
|
||||
return "";
|
||||
}
|
||||
|
||||
function onLoad()
|
||||
{
|
||||
var params = window.arguments[0];
|
||||
if (!params)
|
||||
return;
|
||||
|
||||
var helper = Components.classes[gSMimeContractID].createInstance(gISMimeJSHelper);
|
||||
|
||||
if (!helper)
|
||||
return;
|
||||
|
||||
gListBox = document.getElementById("infolist");
|
||||
gViewButton = document.getElementById("viewCertButton");
|
||||
gBundle = document.getElementById("bundle_smime_comp_info");
|
||||
|
||||
gEmailAddresses = new Object();
|
||||
gCertStatusSummaries = new Object();
|
||||
gCertIssuedInfos = new Object();
|
||||
gCertExpiresInfos = new Object();
|
||||
gCerts = new Object();
|
||||
gCount = new Object();
|
||||
var canEncrypt = new Object();
|
||||
|
||||
var allow_ldap_cert_fetching = false;
|
||||
|
||||
try {
|
||||
if (params.compFields.securityInfo.requireEncryptMessage) {
|
||||
allow_ldap_cert_fetching = true;
|
||||
}
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
}
|
||||
|
||||
while (true)
|
||||
{
|
||||
try
|
||||
{
|
||||
helper.getRecipientCertsInfo(
|
||||
params.compFields,
|
||||
gCount,
|
||||
gEmailAddresses,
|
||||
gCertStatusSummaries,
|
||||
gCertIssuedInfos,
|
||||
gCertExpiresInfos,
|
||||
gCerts,
|
||||
canEncrypt);
|
||||
}
|
||||
catch (e)
|
||||
{
|
||||
dump(e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!allow_ldap_cert_fetching)
|
||||
break;
|
||||
|
||||
allow_ldap_cert_fetching = false;
|
||||
|
||||
var missing = new Array();
|
||||
|
||||
for (var j = gCount.value - 1; j >= 0; --j)
|
||||
{
|
||||
if (!gCerts.value[j])
|
||||
{
|
||||
missing[missing.length] = gEmailAddresses.value[j];
|
||||
}
|
||||
}
|
||||
|
||||
if (missing.length > 0)
|
||||
{
|
||||
var autocompleteLdap = Services.prefs
|
||||
.getBoolPref("ldap_2.autoComplete.useDirectory");
|
||||
|
||||
if (autocompleteLdap)
|
||||
{
|
||||
var autocompleteDirectory = null;
|
||||
if (params.currentIdentity.overrideGlobalPref) {
|
||||
autocompleteDirectory = params.currentIdentity.directoryServer;
|
||||
} else {
|
||||
autocompleteDirectory = Services.prefs
|
||||
.getCharPref("ldap_2.autoComplete.directoryServer");
|
||||
}
|
||||
|
||||
if (autocompleteDirectory)
|
||||
{
|
||||
window.openDialog('chrome://messenger-smime/content/certFetchingStatus.xul',
|
||||
'',
|
||||
'chrome,resizable=1,modal=1,dialog=1',
|
||||
autocompleteDirectory,
|
||||
missing
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (gBundle)
|
||||
{
|
||||
var yes_string = gBundle.getString("StatusYes");
|
||||
var no_string = gBundle.getString("StatusNo");
|
||||
var not_possible_string = gBundle.getString("StatusNotPossible");
|
||||
|
||||
var signed_element = document.getElementById("signed");
|
||||
var encrypted_element = document.getElementById("encrypted");
|
||||
|
||||
if (params.smFields.requireEncryptMessage)
|
||||
{
|
||||
if (params.isEncryptionCertAvailable && canEncrypt.value)
|
||||
{
|
||||
encrypted_element.value = yes_string;
|
||||
}
|
||||
else
|
||||
{
|
||||
encrypted_element.value = not_possible_string;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
encrypted_element.value = no_string;
|
||||
}
|
||||
|
||||
if (params.smFields.signMessage)
|
||||
{
|
||||
if (params.isSigningCertAvailable)
|
||||
{
|
||||
signed_element.value = yes_string;
|
||||
}
|
||||
else
|
||||
{
|
||||
signed_element.value = not_possible_string;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
signed_element.value = no_string;
|
||||
}
|
||||
}
|
||||
|
||||
var imax = gCount.value;
|
||||
|
||||
for (var i = 0; i < imax; ++i)
|
||||
{
|
||||
var listitem = document.createElement("listitem");
|
||||
|
||||
listitem.appendChild(createCell(gEmailAddresses.value[i]));
|
||||
|
||||
if (!gCerts.value[i])
|
||||
{
|
||||
listitem.appendChild(createCell(gBundle.getString("StatusNotFound")));
|
||||
}
|
||||
else
|
||||
{
|
||||
listitem.appendChild(createCell(getStatusExplanation(gCertStatusSummaries.value[i])));
|
||||
listitem.appendChild(createCell(gCertIssuedInfos.value[i]));
|
||||
listitem.appendChild(createCell(gCertExpiresInfos.value[i]));
|
||||
}
|
||||
|
||||
gListBox.appendChild(listitem);
|
||||
}
|
||||
}
|
||||
|
||||
function onSelectionChange(event)
|
||||
{
|
||||
gViewButton.disabled = !(gListBox.selectedItems.length == 1 &&
|
||||
certForRow(gListBox.selectedIndex));
|
||||
}
|
||||
|
||||
function viewCertHelper(parent, cert) {
|
||||
var cd = Components.classes[nsCertificateDialogs].getService(nsICertificateDialogs);
|
||||
cd.viewCert(parent, cert);
|
||||
}
|
||||
|
||||
function certForRow(aRowIndex) {
|
||||
return gCerts.value[aRowIndex];
|
||||
}
|
||||
|
||||
function viewSelectedCert()
|
||||
{
|
||||
if (!gViewButton.disabled)
|
||||
viewCertHelper(window, certForRow(gListBox.selectedIndex));
|
||||
}
|
||||
|
||||
function doHelpButton()
|
||||
{
|
||||
openHelp('compose_security', 'chrome://communicator/locale/help/suitehelp.rdf');
|
||||
}
|
||||
|
||||
function createCell(label)
|
||||
{
|
||||
var cell = document.createElement("listcell");
|
||||
cell.setAttribute("label", label)
|
||||
return cell;
|
||||
}
|
||||
68
mailnews/extensions/smime/content/msgCompSecurityInfo.xul
Normal file
68
mailnews/extensions/smime/content/msgCompSecurityInfo.xul
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://messenger/skin/smime/msgCompSecurityInfo.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE dialog SYSTEM "chrome://messenger-smime/locale/msgCompSecurityInfo.dtd">
|
||||
|
||||
<dialog id="msgCompSecurityInfo" title="&title.label;"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
style="width: 50em;"
|
||||
persist="width height"
|
||||
buttons="accept"
|
||||
onload="onLoad();">
|
||||
|
||||
<script type="application/javascript" src="chrome://messenger-smime/content/msgCompSecurityInfo.js"/>
|
||||
|
||||
<stringbundle id="bundle_smime_comp_info" src="chrome://messenger-smime/locale/msgCompSecurityInfo.properties"/>
|
||||
|
||||
<description>&subject.plaintextWarning;</description>
|
||||
<separator class="thin"/>
|
||||
<description>&status.heading;</description>
|
||||
<grid>
|
||||
<columns>
|
||||
<column/>
|
||||
<column/>
|
||||
</columns>
|
||||
<rows>
|
||||
<row>
|
||||
<label value="&status.signed;"/>
|
||||
<label id="signed"/>
|
||||
</row>
|
||||
<row>
|
||||
<label value="&status.encrypted;"/>
|
||||
<label id="encrypted"/>
|
||||
</row>
|
||||
</rows>
|
||||
</grid>
|
||||
|
||||
<separator class="thin"/>
|
||||
<label value="&status.certificates;" control="infolist"/>
|
||||
|
||||
<listbox id="infolist" flex="1"
|
||||
onselect="onSelectionChange(event);">
|
||||
<listcols>
|
||||
<listcol flex="3" width="0"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<listcol flex="1" width="0"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<listcol flex="2" width="0"/>
|
||||
<splitter class="tree-splitter"/>
|
||||
<listcol flex="2" width="0"/>
|
||||
</listcols>
|
||||
<listhead>
|
||||
<listheader label="&tree.recipient;"/>
|
||||
<listheader label="&tree.status;"/>
|
||||
<listheader label="&tree.issuedDate;"/>
|
||||
<listheader label="&tree.expiresDate;"/>
|
||||
</listhead>
|
||||
</listbox>
|
||||
<hbox pack="start">
|
||||
<button id="viewCertButton" disabled="true"
|
||||
label="&view.label;" accesskey="&view.accesskey;"
|
||||
oncommand="viewSelectedCert();"/>
|
||||
</hbox>
|
||||
</dialog>
|
||||
264
mailnews/extensions/smime/content/msgHdrViewSMIMEOverlay.js
Normal file
264
mailnews/extensions/smime/content/msgHdrViewSMIMEOverlay.js
Normal file
|
|
@ -0,0 +1,264 @@
|
|||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* 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/. */
|
||||
|
||||
var gSignedUINode = null;
|
||||
var gEncryptedUINode = null;
|
||||
var gSMIMEContainer = null;
|
||||
var gStatusBar = null;
|
||||
var gSignedStatusPanel = null;
|
||||
var gEncryptedStatusPanel = null;
|
||||
|
||||
var gEncryptedURIService = null;
|
||||
var gMyLastEncryptedURI = null;
|
||||
|
||||
var gSMIMEBundle = null;
|
||||
// var gBrandBundle; -- defined in mailWindow.js
|
||||
|
||||
// manipulates some globals from msgReadSMIMEOverlay.js
|
||||
|
||||
var nsICMSMessageErrors = Components.interfaces.nsICMSMessageErrors;
|
||||
|
||||
/// Get the necko URL for the message URI.
|
||||
function neckoURLForMessageURI(aMessageURI)
|
||||
{
|
||||
let msgSvc = Components.classes["@mozilla.org/messenger;1"]
|
||||
.createInstance(Components.interfaces.nsIMessenger)
|
||||
.messageServiceFromURI(aMessageURI);
|
||||
let neckoURI = {};
|
||||
msgSvc.GetUrlForUri(aMessageURI, neckoURI, null);
|
||||
return neckoURI.value.spec;
|
||||
}
|
||||
|
||||
var smimeHeaderSink =
|
||||
{
|
||||
maxWantedNesting: function()
|
||||
{
|
||||
return 1;
|
||||
},
|
||||
|
||||
signedStatus: function(aNestingLevel, aSignatureStatus, aSignerCert)
|
||||
{
|
||||
if (aNestingLevel > 1) {
|
||||
// we are not interested
|
||||
return;
|
||||
}
|
||||
|
||||
gSignatureStatus = aSignatureStatus;
|
||||
gSignerCert = aSignerCert;
|
||||
|
||||
gSMIMEContainer.collapsed = false;
|
||||
gSignedUINode.collapsed = false;
|
||||
gSignedStatusPanel.collapsed = false;
|
||||
|
||||
switch (aSignatureStatus) {
|
||||
case nsICMSMessageErrors.SUCCESS:
|
||||
gSignedUINode.setAttribute("signed", "ok");
|
||||
gStatusBar.setAttribute("signed", "ok");
|
||||
break;
|
||||
|
||||
case nsICMSMessageErrors.VERIFY_NOT_YET_ATTEMPTED:
|
||||
gSignedUINode.setAttribute("signed", "unknown");
|
||||
gStatusBar.setAttribute("signed", "unknown");
|
||||
break;
|
||||
|
||||
case nsICMSMessageErrors.VERIFY_CERT_WITHOUT_ADDRESS:
|
||||
case nsICMSMessageErrors.VERIFY_HEADER_MISMATCH:
|
||||
gSignedUINode.setAttribute("signed", "mismatch");
|
||||
gStatusBar.setAttribute("signed", "mismatch");
|
||||
break;
|
||||
|
||||
default:
|
||||
gSignedUINode.setAttribute("signed", "notok");
|
||||
gStatusBar.setAttribute("signed", "notok");
|
||||
break;
|
||||
}
|
||||
},
|
||||
|
||||
encryptionStatus: function(aNestingLevel, aEncryptionStatus, aRecipientCert)
|
||||
{
|
||||
if (aNestingLevel > 1) {
|
||||
// we are not interested
|
||||
return;
|
||||
}
|
||||
|
||||
gEncryptionStatus = aEncryptionStatus;
|
||||
gEncryptionCert = aRecipientCert;
|
||||
|
||||
gSMIMEContainer.collapsed = false;
|
||||
gEncryptedUINode.collapsed = false;
|
||||
gEncryptedStatusPanel.collapsed = false;
|
||||
|
||||
if (nsICMSMessageErrors.SUCCESS == aEncryptionStatus)
|
||||
{
|
||||
gEncryptedUINode.setAttribute("encrypted", "ok");
|
||||
gStatusBar.setAttribute("encrypted", "ok");
|
||||
}
|
||||
else
|
||||
{
|
||||
gEncryptedUINode.setAttribute("encrypted", "notok");
|
||||
gStatusBar.setAttribute("encrypted", "notok");
|
||||
}
|
||||
|
||||
if (gEncryptedURIService)
|
||||
{
|
||||
// Remember the message URI and the corresponding necko URI.
|
||||
gMyLastEncryptedURI = GetLoadedMessage();
|
||||
gEncryptedURIService.rememberEncrypted(gMyLastEncryptedURI);
|
||||
gEncryptedURIService.rememberEncrypted(
|
||||
neckoURLForMessageURI(gMyLastEncryptedURI));
|
||||
}
|
||||
|
||||
switch (aEncryptionStatus)
|
||||
{
|
||||
case nsICMSMessageErrors.SUCCESS:
|
||||
case nsICMSMessageErrors.ENCRYPT_INCOMPLETE:
|
||||
break;
|
||||
default:
|
||||
var brand = gBrandBundle.getString("brandShortName");
|
||||
var title = gSMIMEBundle.getString("CantDecryptTitle").replace(/%brand%/g, brand);
|
||||
var body = gSMIMEBundle.getString("CantDecryptBody").replace(/%brand%/g, brand);
|
||||
|
||||
// insert our message
|
||||
msgWindow.displayHTMLInMessagePane(title,
|
||||
"<html>\n" +
|
||||
"<body bgcolor=\"#fafaee\">\n" +
|
||||
"<center><br><br><br>\n" +
|
||||
"<table>\n" +
|
||||
"<tr><td>\n" +
|
||||
"<center><strong><font size=\"+3\">\n" +
|
||||
title+"</font></center><br>\n" +
|
||||
body+"\n" +
|
||||
"</td></tr></table></center></body></html>", false);
|
||||
}
|
||||
},
|
||||
|
||||
QueryInterface : function(iid)
|
||||
{
|
||||
if (iid.equals(Components.interfaces.nsIMsgSMIMEHeaderSink) || iid.equals(Components.interfaces.nsISupports))
|
||||
return this;
|
||||
throw Components.results.NS_NOINTERFACE;
|
||||
}
|
||||
};
|
||||
|
||||
function forgetEncryptedURI()
|
||||
{
|
||||
if (gMyLastEncryptedURI && gEncryptedURIService)
|
||||
{
|
||||
gEncryptedURIService.forgetEncrypted(gMyLastEncryptedURI);
|
||||
gEncryptedURIService.forgetEncrypted(
|
||||
neckoURLForMessageURI(gMyLastEncryptedURI));
|
||||
gMyLastEncryptedURI = null;
|
||||
}
|
||||
}
|
||||
|
||||
function onSMIMEStartHeaders()
|
||||
{
|
||||
gEncryptionStatus = -1;
|
||||
gSignatureStatus = -1;
|
||||
|
||||
gSignerCert = null;
|
||||
gEncryptionCert = null;
|
||||
|
||||
gSMIMEContainer.collapsed = true;
|
||||
|
||||
gSignedUINode.collapsed = true;
|
||||
gSignedUINode.removeAttribute("signed");
|
||||
gSignedStatusPanel.collapsed = true;
|
||||
gStatusBar.removeAttribute("signed");
|
||||
|
||||
gEncryptedUINode.collapsed = true;
|
||||
gEncryptedUINode.removeAttribute("encrypted");
|
||||
gEncryptedStatusPanel.collapsed = true;
|
||||
gStatusBar.removeAttribute("encrypted");
|
||||
|
||||
forgetEncryptedURI();
|
||||
}
|
||||
|
||||
function onSMIMEEndHeaders()
|
||||
{}
|
||||
|
||||
function onSmartCardChange()
|
||||
{
|
||||
// only reload encrypted windows
|
||||
if (gMyLastEncryptedURI && gEncryptionStatus != -1)
|
||||
ReloadMessage();
|
||||
}
|
||||
|
||||
function msgHdrViewSMIMEOnLoad(event)
|
||||
{
|
||||
window.crypto.enableSmartCardEvents = true;
|
||||
document.addEventListener("smartcard-insert", onSmartCardChange, false);
|
||||
document.addEventListener("smartcard-remove", onSmartCardChange, false);
|
||||
if (!gSMIMEBundle)
|
||||
gSMIMEBundle = document.getElementById("bundle_read_smime");
|
||||
|
||||
// we want to register our security header sink as an opaque nsISupports
|
||||
// on the msgHdrSink used by mail.....
|
||||
msgWindow.msgHeaderSink.securityInfo = smimeHeaderSink;
|
||||
|
||||
gSignedUINode = document.getElementById('signedHdrIcon');
|
||||
gEncryptedUINode = document.getElementById('encryptedHdrIcon');
|
||||
gSMIMEContainer = document.getElementById('smimeBox');
|
||||
gStatusBar = document.getElementById('status-bar');
|
||||
gSignedStatusPanel = document.getElementById('signed-status');
|
||||
gEncryptedStatusPanel = document.getElementById('encrypted-status');
|
||||
|
||||
// add ourself to the list of message display listeners so we get notified when we are about to display a
|
||||
// message.
|
||||
var listener = {};
|
||||
listener.onStartHeaders = onSMIMEStartHeaders;
|
||||
listener.onEndHeaders = onSMIMEEndHeaders;
|
||||
gMessageListeners.push(listener);
|
||||
|
||||
gEncryptedURIService =
|
||||
Components.classes["@mozilla.org/messenger-smime/smime-encrypted-uris-service;1"]
|
||||
.getService(Components.interfaces.nsIEncryptedSMIMEURIsService);
|
||||
}
|
||||
|
||||
function msgHdrViewSMIMEOnUnload(event)
|
||||
{
|
||||
window.crypto.enableSmartCardEvents = false;
|
||||
document.removeEventListener("smartcard-insert", onSmartCardChange, false);
|
||||
document.removeEventListener("smartcard-remove", onSmartCardChange, false);
|
||||
forgetEncryptedURI();
|
||||
removeEventListener("messagepane-loaded", msgHdrViewSMIMEOnLoad, true);
|
||||
removeEventListener("messagepane-unloaded", msgHdrViewSMIMEOnUnload, true);
|
||||
removeEventListener("messagepane-hide", msgHdrViewSMIMEOnMessagePaneHide, true);
|
||||
removeEventListener("messagepane-unhide", msgHdrViewSMIMEOnMessagePaneUnhide, true);
|
||||
}
|
||||
|
||||
function msgHdrViewSMIMEOnMessagePaneHide()
|
||||
{
|
||||
gSMIMEContainer.collapsed = true;
|
||||
gSignedUINode.collapsed = true;
|
||||
gSignedStatusPanel.collapsed = true;
|
||||
gEncryptedUINode.collapsed = true;
|
||||
gEncryptedStatusPanel.collapsed = true;
|
||||
}
|
||||
|
||||
function msgHdrViewSMIMEOnMessagePaneUnhide()
|
||||
{
|
||||
if (gEncryptionStatus != -1 || gSignatureStatus != -1)
|
||||
{
|
||||
gSMIMEContainer.collapsed = false;
|
||||
|
||||
if (gSignatureStatus != -1)
|
||||
{
|
||||
gSignedUINode.collapsed = false;
|
||||
gSignedStatusPanel.collapsed = false;
|
||||
}
|
||||
|
||||
if (gEncryptionStatus != -1)
|
||||
{
|
||||
gEncryptedUINode.collapsed = false;
|
||||
gEncryptedStatusPanel.collapsed = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
addEventListener('messagepane-loaded', msgHdrViewSMIMEOnLoad, true);
|
||||
addEventListener('messagepane-unloaded', msgHdrViewSMIMEOnUnload, true);
|
||||
addEventListener('messagepane-hide', msgHdrViewSMIMEOnMessagePaneHide, true);
|
||||
addEventListener('messagepane-unhide', msgHdrViewSMIMEOnMessagePaneUnhide, true);
|
||||
29
mailnews/extensions/smime/content/msgHdrViewSMIMEOverlay.xul
Normal file
29
mailnews/extensions/smime/content/msgHdrViewSMIMEOverlay.xul
Normal file
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://messenger/skin/smime/msgHdrViewSMIMEOverlay.css" type="text/css"?>
|
||||
|
||||
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script type="application/javascript" src="chrome://messenger-smime/content/msgHdrViewSMIMEOverlay.js"/>
|
||||
<!-- These stringbundles are already defined in msgReadSMIMEOverlay.xul!
|
||||
<stringbundleset id="stringbundleset">
|
||||
<stringbundle id="bundle_read_smime" src="chrome://messenger-smime/locale/msgReadSMIMEOverlay.properties"/>
|
||||
<stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
|
||||
</stringbundleset>
|
||||
-->
|
||||
|
||||
<hbox id="expandedHeaderView">
|
||||
<vbox id="smimeBox" insertafter="expandedHeaders" collapsed="true">
|
||||
<spacer flex="1"/>
|
||||
<image id="signedHdrIcon"
|
||||
onclick="showMessageReadSecurityInfo();" collapsed="true"/>
|
||||
<image id="encryptedHdrIcon"
|
||||
onclick="showMessageReadSecurityInfo();" collapsed="true"/>
|
||||
<spacer flex="1"/>
|
||||
</vbox>
|
||||
</hbox>
|
||||
</overlay>
|
||||
|
||||
102
mailnews/extensions/smime/content/msgReadSMIMEOverlay.js
Normal file
102
mailnews/extensions/smime/content/msgReadSMIMEOverlay.js
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
|
||||
/* 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/. */
|
||||
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
|
||||
var gEncryptionStatus = -1;
|
||||
var gSignatureStatus = -1;
|
||||
var gSignerCert = null;
|
||||
var gEncryptionCert = null;
|
||||
|
||||
addEventListener("load", smimeReadOnLoad, {capture: false, once: true});
|
||||
|
||||
function smimeReadOnLoad()
|
||||
{
|
||||
top.controllers.appendController(SecurityController);
|
||||
|
||||
addEventListener("unload", smimeReadOnUnload, {capture: false, once: true});
|
||||
}
|
||||
|
||||
function smimeReadOnUnload()
|
||||
{
|
||||
top.controllers.removeController(SecurityController);
|
||||
}
|
||||
|
||||
function showImapSignatureUnknown()
|
||||
{
|
||||
let readSmimeBundle = document.getElementById("bundle_read_smime");
|
||||
let brandBundle = document.getElementById("bundle_brand");
|
||||
if (!readSmimeBundle || !brandBundle)
|
||||
return;
|
||||
|
||||
if (Services.prompt.confirm(window, brandBundle.getString("brandShortName"),
|
||||
readSmimeBundle.getString("ImapOnDemand")))
|
||||
{
|
||||
gDBView.reloadMessageWithAllParts();
|
||||
}
|
||||
}
|
||||
|
||||
function showMessageReadSecurityInfo()
|
||||
{
|
||||
let gSignedUINode = document.getElementById("signedHdrIcon");
|
||||
if (gSignedUINode && gSignedUINode.getAttribute("signed") == "unknown")
|
||||
{
|
||||
showImapSignatureUnknown();
|
||||
return;
|
||||
}
|
||||
|
||||
let params = Components.classes["@mozilla.org/embedcomp/dialogparam;1"]
|
||||
.createInstance(Components.interfaces.nsIDialogParamBlock);
|
||||
params.objects = Components.classes["@mozilla.org/array;1"]
|
||||
.createInstance(Components.interfaces.nsIMutableArray);
|
||||
// Append even if null... the receiver must handle that.
|
||||
params.objects.appendElement(gSignerCert, false);
|
||||
params.objects.appendElement(gEncryptionCert, false);
|
||||
|
||||
// int array starts with index 0, but that is used for window exit status
|
||||
params.SetInt(1, gSignatureStatus);
|
||||
params.SetInt(2, gEncryptionStatus);
|
||||
|
||||
window.openDialog("chrome://messenger-smime/content/msgReadSecurityInfo.xul",
|
||||
"", "chrome,resizable,modal,dialog,centerscreen", params);
|
||||
}
|
||||
|
||||
var SecurityController =
|
||||
{
|
||||
supportsCommand: function(command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case "cmd_viewSecurityStatus":
|
||||
return true;
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
},
|
||||
|
||||
isCommandEnabled: function(command)
|
||||
{
|
||||
switch (command)
|
||||
{
|
||||
case "cmd_viewSecurityStatus":
|
||||
if (document.documentElement.getAttribute('windowtype') == "mail:messageWindow")
|
||||
return GetNumSelectedMessages() > 0;
|
||||
|
||||
if (GetNumSelectedMessages() > 0 && gDBView)
|
||||
{
|
||||
let enabled = {value: false};
|
||||
let checkStatus = {};
|
||||
gDBView.getCommandStatus(nsMsgViewCommandType.cmdRequiringMsgBody,
|
||||
enabled, checkStatus);
|
||||
return enabled.value;
|
||||
}
|
||||
// else: fall through.
|
||||
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
};
|
||||
34
mailnews/extensions/smime/content/msgReadSMIMEOverlay.xul
Normal file
34
mailnews/extensions/smime/content/msgReadSMIMEOverlay.xul
Normal file
|
|
@ -0,0 +1,34 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://messenger/skin/smime/msgReadSMIMEOverlay.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE overlay SYSTEM "chrome://messenger-smime/locale/msgReadSMIMEOverlay.dtd">
|
||||
|
||||
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script type="application/javascript" src="chrome://messenger-smime/content/msgReadSMIMEOverlay.js"/>
|
||||
|
||||
<commandset id="mailViewMenuItems">
|
||||
<command id="cmd_viewSecurityStatus" oncommand="showMessageReadSecurityInfo();" disabled="true"/>
|
||||
</commandset>
|
||||
|
||||
<menupopup id="menu_View_Popup">
|
||||
<menuitem insertafter="pageSourceMenuItem" label="&menu_securityStatus.label;"
|
||||
accesskey="&menu_securityStatus.accesskey;" command="cmd_viewSecurityStatus"/>
|
||||
</menupopup>
|
||||
|
||||
<statusbar id="status-bar">
|
||||
<statusbarpanel insertbefore="offline-status" class="statusbarpanel-iconic"
|
||||
id="signed-status" collapsed="true" oncommand="showMessageReadSecurityInfo();"/>
|
||||
<statusbarpanel insertbefore="offline-status" class="statusbarpanel-iconic"
|
||||
id="encrypted-status" collapsed="true" oncommand="showMessageReadSecurityInfo();"/>
|
||||
<stringbundle id="bundle_read_smime" src="chrome://messenger-smime/locale/msgReadSMIMEOverlay.properties"/>
|
||||
<!-- This stringbundle is already defined on top window level!
|
||||
<stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
|
||||
-->
|
||||
</statusbar>
|
||||
|
||||
</overlay>
|
||||
232
mailnews/extensions/smime/content/msgReadSecurityInfo.js
Normal file
232
mailnews/extensions/smime/content/msgReadSecurityInfo.js
Normal file
|
|
@ -0,0 +1,232 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
||||
/* 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/. */
|
||||
|
||||
var nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
|
||||
var nsIX509Cert = Components.interfaces.nsIX509Cert;
|
||||
var nsICMSMessageErrors = Components.interfaces.nsICMSMessageErrors;
|
||||
var nsICertificateDialogs = Components.interfaces.nsICertificateDialogs;
|
||||
var nsCertificateDialogs = "@mozilla.org/nsCertificateDialogs;1"
|
||||
|
||||
var gSignerCert = null;
|
||||
var gEncryptionCert = null;
|
||||
|
||||
var gSignatureStatus = -1;
|
||||
var gEncryptionStatus = -1;
|
||||
|
||||
function setText(id, value) {
|
||||
var element = document.getElementById(id);
|
||||
if (!element)
|
||||
return;
|
||||
if (element.hasChildNodes())
|
||||
element.firstChild.remove();
|
||||
var textNode = document.createTextNode(value);
|
||||
element.appendChild(textNode);
|
||||
}
|
||||
|
||||
function onLoad()
|
||||
{
|
||||
var paramBlock = window.arguments[0].QueryInterface(nsIDialogParamBlock);
|
||||
paramBlock.objects.QueryInterface(Components.interfaces.nsIMutableArray);
|
||||
try {
|
||||
gSignerCert = paramBlock.objects.queryElementAt(0, nsIX509Cert);
|
||||
} catch(e) { } // maybe null
|
||||
try {
|
||||
gEncryptionCert = paramBlock.objects.queryElementAt(1, nsIX509Cert);
|
||||
} catch(e) { } // maybe null
|
||||
|
||||
gSignatureStatus = paramBlock.GetInt(1);
|
||||
gEncryptionStatus = paramBlock.GetInt(2);
|
||||
|
||||
var bundle = document.getElementById("bundle_smime_read_info");
|
||||
|
||||
if (bundle) {
|
||||
var sigInfoLabel = null;
|
||||
var sigInfoHeader = null;
|
||||
var sigInfo = null;
|
||||
var sigInfo_clueless = false;
|
||||
|
||||
switch (gSignatureStatus) {
|
||||
case -1:
|
||||
case nsICMSMessageErrors.VERIFY_NOT_SIGNED:
|
||||
sigInfoLabel = "SINoneLabel";
|
||||
sigInfo = "SINone";
|
||||
break;
|
||||
|
||||
case nsICMSMessageErrors.SUCCESS:
|
||||
sigInfoLabel = "SIValidLabel";
|
||||
sigInfo = "SIValid";
|
||||
break;
|
||||
|
||||
|
||||
case nsICMSMessageErrors.VERIFY_BAD_SIGNATURE:
|
||||
case nsICMSMessageErrors.VERIFY_DIGEST_MISMATCH:
|
||||
sigInfoLabel = "SIInvalidLabel";
|
||||
sigInfoHeader = "SIInvalidHeader";
|
||||
sigInfo = "SIContentAltered";
|
||||
break;
|
||||
|
||||
case nsICMSMessageErrors.VERIFY_UNKNOWN_ALGO:
|
||||
case nsICMSMessageErrors.VERIFY_UNSUPPORTED_ALGO:
|
||||
sigInfoLabel = "SIInvalidLabel";
|
||||
sigInfoHeader = "SIInvalidHeader";
|
||||
sigInfo = "SIInvalidCipher";
|
||||
break;
|
||||
|
||||
case nsICMSMessageErrors.VERIFY_HEADER_MISMATCH:
|
||||
sigInfoLabel = "SIPartiallyValidLabel";
|
||||
sigInfoHeader = "SIPartiallyValidHeader";
|
||||
sigInfo = "SIHeaderMismatch";
|
||||
break;
|
||||
|
||||
case nsICMSMessageErrors.VERIFY_CERT_WITHOUT_ADDRESS:
|
||||
sigInfoLabel = "SIPartiallyValidLabel";
|
||||
sigInfoHeader = "SIPartiallyValidHeader";
|
||||
sigInfo = "SICertWithoutAddress";
|
||||
break;
|
||||
|
||||
case nsICMSMessageErrors.VERIFY_UNTRUSTED:
|
||||
sigInfoLabel = "SIInvalidLabel";
|
||||
sigInfoHeader = "SIInvalidHeader";
|
||||
sigInfo = "SIUntrustedCA";
|
||||
// XXX Need to extend to communicate better errors
|
||||
// might also be:
|
||||
// SIExpired SIRevoked SINotYetValid SIUnknownCA SIExpiredCA SIRevokedCA SINotYetValidCA
|
||||
break;
|
||||
|
||||
case nsICMSMessageErrors.VERIFY_NOT_YET_ATTEMPTED:
|
||||
case nsICMSMessageErrors.GENERAL_ERROR:
|
||||
case nsICMSMessageErrors.VERIFY_NO_CONTENT_INFO:
|
||||
case nsICMSMessageErrors.VERIFY_BAD_DIGEST:
|
||||
case nsICMSMessageErrors.VERIFY_NOCERT:
|
||||
case nsICMSMessageErrors.VERIFY_ERROR_UNVERIFIED:
|
||||
case nsICMSMessageErrors.VERIFY_ERROR_PROCESSING:
|
||||
case nsICMSMessageErrors.VERIFY_MALFORMED_SIGNATURE:
|
||||
sigInfoLabel = "SIInvalidLabel";
|
||||
sigInfoHeader = "SIInvalidHeader";
|
||||
sigInfo_clueless = true;
|
||||
break;
|
||||
default:
|
||||
Components.utils.reportError("Unexpected gSignatureStatus: " +
|
||||
gSignatureStatus);
|
||||
}
|
||||
|
||||
document.getElementById("signatureLabel").value =
|
||||
bundle.getString(sigInfoLabel);
|
||||
|
||||
var label;
|
||||
if (sigInfoHeader) {
|
||||
label = document.getElementById("signatureHeader");
|
||||
label.collapsed = false;
|
||||
label.value = bundle.getString(sigInfoHeader);
|
||||
}
|
||||
|
||||
var str;
|
||||
if (sigInfo) {
|
||||
str = bundle.getString(sigInfo);
|
||||
}
|
||||
else if (sigInfo_clueless) {
|
||||
str = bundle.getString("SIClueless") + " (" + gSignatureStatus + ")";
|
||||
}
|
||||
setText("signatureExplanation", str);
|
||||
|
||||
var encInfoLabel = null;
|
||||
var encInfoHeader = null;
|
||||
var encInfo = null;
|
||||
var encInfo_clueless = false;
|
||||
|
||||
switch (gEncryptionStatus) {
|
||||
case -1:
|
||||
encInfoLabel = "EINoneLabel2";
|
||||
encInfo = "EINone";
|
||||
break;
|
||||
|
||||
case nsICMSMessageErrors.SUCCESS:
|
||||
encInfoLabel = "EIValidLabel";
|
||||
encInfo = "EIValid";
|
||||
break;
|
||||
|
||||
case nsICMSMessageErrors.ENCRYPT_INCOMPLETE:
|
||||
encInfoLabel = "EIInvalidLabel";
|
||||
encInfo = "EIContentAltered";
|
||||
break;
|
||||
|
||||
case nsICMSMessageErrors.GENERAL_ERROR:
|
||||
encInfoLabel = "EIInvalidLabel";
|
||||
encInfoHeader = "EIInvalidHeader";
|
||||
encInfo_clueless = 1;
|
||||
break;
|
||||
default:
|
||||
Components.utils.reportError("Unexpected gEncryptionStatus: " +
|
||||
gEncryptionStatus);
|
||||
}
|
||||
|
||||
document.getElementById("encryptionLabel").value =
|
||||
bundle.getString(encInfoLabel);
|
||||
|
||||
if (encInfoHeader) {
|
||||
label = document.getElementById("encryptionHeader");
|
||||
label.collapsed = false;
|
||||
label.value = bundle.getString(encInfoHeader);
|
||||
}
|
||||
|
||||
if (encInfo) {
|
||||
str = bundle.getString(encInfo);
|
||||
}
|
||||
else if (encInfo_clueless) {
|
||||
str = bundle.getString("EIClueless");
|
||||
}
|
||||
setText("encryptionExplanation", str);
|
||||
}
|
||||
|
||||
if (gSignerCert) {
|
||||
document.getElementById("signatureCert").collapsed = false;
|
||||
if (gSignerCert.subjectName) {
|
||||
document.getElementById("signedBy").value = gSignerCert.commonName;
|
||||
}
|
||||
if (gSignerCert.emailAddress) {
|
||||
document.getElementById("signerEmail").value = gSignerCert.emailAddress;
|
||||
}
|
||||
if (gSignerCert.issuerName) {
|
||||
document.getElementById("sigCertIssuedBy").value = gSignerCert.issuerCommonName;
|
||||
}
|
||||
}
|
||||
|
||||
if (gEncryptionCert) {
|
||||
document.getElementById("encryptionCert").collapsed = false;
|
||||
if (gEncryptionCert.subjectName) {
|
||||
document.getElementById("encryptedFor").value = gEncryptionCert.commonName;
|
||||
}
|
||||
if (gEncryptionCert.emailAddress) {
|
||||
document.getElementById("recipientEmail").value = gEncryptionCert.emailAddress;
|
||||
}
|
||||
if (gEncryptionCert.issuerName) {
|
||||
document.getElementById("encCertIssuedBy").value = gEncryptionCert.issuerCommonName;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function viewCertHelper(parent, cert) {
|
||||
var cd = Components.classes[nsCertificateDialogs].getService(nsICertificateDialogs);
|
||||
cd.viewCert(parent, cert);
|
||||
}
|
||||
|
||||
function viewSignatureCert()
|
||||
{
|
||||
if (gSignerCert) {
|
||||
viewCertHelper(window, gSignerCert);
|
||||
}
|
||||
}
|
||||
|
||||
function viewEncryptionCert()
|
||||
{
|
||||
if (gEncryptionCert) {
|
||||
viewCertHelper(window, gEncryptionCert);
|
||||
}
|
||||
}
|
||||
|
||||
function doHelpButton()
|
||||
{
|
||||
openHelp('received_security');
|
||||
}
|
||||
68
mailnews/extensions/smime/content/msgReadSecurityInfo.xul
Normal file
68
mailnews/extensions/smime/content/msgReadSecurityInfo.xul
Normal file
|
|
@ -0,0 +1,68 @@
|
|||
<?xml version="1.0"?>
|
||||
<!-- 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/. -->
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
<?xml-stylesheet href="chrome://messenger/skin/smime/msgReadSecurityInfo.css" type="text/css"?>
|
||||
|
||||
<!DOCTYPE dialog SYSTEM "chrome://messenger-smime/locale/msgReadSecurityInfo.dtd">
|
||||
|
||||
<dialog id="msgReadSecurityInfo" title="&status.label;"
|
||||
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
style="width: 40em;"
|
||||
buttons="accept"
|
||||
onload="onLoad();">
|
||||
|
||||
<script type="application/javascript" src="chrome://messenger-smime/content/msgReadSecurityInfo.js"/>
|
||||
|
||||
<stringbundle id="bundle_smime_read_info" src="chrome://messenger-smime/locale/msgSecurityInfo.properties"/>
|
||||
|
||||
<vbox flex="1">
|
||||
<label id="signatureLabel"/>
|
||||
<label id="signatureHeader" collapsed="true"/>
|
||||
<description id="signatureExplanation"/>
|
||||
<vbox id="signatureCert" collapsed="true">
|
||||
<hbox>
|
||||
<label id="signedByLabel">&signer.name;</label>
|
||||
<description id="signedBy"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<label id="signerEmailLabel">&email.address;</label>
|
||||
<description id="signerEmail"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<label id="sigCertIssuedByLabel">&issuer.name;</label>
|
||||
<description id="sigCertIssuedBy"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<button id="signatureCertView" label="&signatureCert.label;"
|
||||
oncommand="viewSignatureCert()"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
|
||||
<separator/>
|
||||
|
||||
<label id="encryptionLabel"/>
|
||||
<label id="encryptionHeader" collapsed="true"/>
|
||||
<description id="encryptionExplanation"/>
|
||||
<vbox id="encryptionCert" collapsed="true">
|
||||
<hbox>
|
||||
<label id="encryptedForLabel">&recipient.name;</label>
|
||||
<description id="encryptedFor"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<label id="recipientEmailLabel">&email.address;</label>
|
||||
<description id="recipientEmail"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<label id="encCertIssuedByLabel">&issuer.name;</label>
|
||||
<description id="encCertIssuedBy"/>
|
||||
</hbox>
|
||||
<hbox>
|
||||
<button id="encryptionCertView" label="&encryptionCert.label;"
|
||||
oncommand="viewEncryptionCert()"/>
|
||||
</hbox>
|
||||
</vbox>
|
||||
</vbox>
|
||||
</dialog>
|
||||
14
mailnews/extensions/smime/content/smime.js
Normal file
14
mailnews/extensions/smime/content/smime.js
Normal file
|
|
@ -0,0 +1,14 @@
|
|||
/* 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/. */
|
||||
|
||||
/*
|
||||
Add any default pref values we want for smime
|
||||
*/
|
||||
|
||||
pref("mail.identity.default.encryption_cert_name","");
|
||||
pref("mail.identity.default.encryptionpolicy", 0);
|
||||
pref("mail.identity.default.signing_cert_name", "");
|
||||
pref("mail.identity.default.sign_mail", false);
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue