Commit 31916750 authored by Nico Josuttis's avatar Nico Josuttis

add feature AutoSendEncrypted (basic implementation)

parent c8a361a3
......@@ -61,8 +61,8 @@
<!ENTITY enigmail.moreOptions.label "Weitere Einstellungen">
<!ENTITY enigmail.encryptToSelf.label "Zusätzlich mit eigenem Schlüssel verschlüsseln">
<!ENTITY enigmail.encryptToSelf.tooltip "Auch Sie selbst können die Nachrichten wieder entschlüsseln und lesen.">
<!ENTITY enigmail.alwaysTrustSend.label "Schlüsseln immer vertrauen">
<!ENTITY enigmail.alwaysTrustSend.tooltip "Das &quot;Web of Trust&quot; nicht verwenden, um die Gültigkeit der Schlüssel zu bestimmen.">
<!ENTITY enigmail.alwaysTrustSend.label "Gültigen Schlüsseln immer vertrauen">
<!ENTITY enigmail.alwaysTrustSend.tooltip "Das &quot;Web of Trust&quot; nicht verwenden, um die Gültigkeit der Schlüssel zu bestimmen (außer für abgelaufene/widerrufene Schlüssel).">
<!ENTITY enigmail.useNonDefaultComment.label "Enigmail-Information zur OpenPGP-Signatur hinzufügen">
<!ENTITY enigmail.keyserver.label "Schlüsselserver">
<!ENTITY enigmail.keyserverDlg.label "Schlüsselserver auswählen">
......
......@@ -72,6 +72,29 @@ const NS_CREATE_FILE = 0x08;
const NS_TRUNCATE = 0x20;
const DEFAULT_FILE_PERMS = 0x180; // equals 0600
// trust flags according to GPG documentation:
// (http://www.gnupg.org/documentation/manuals/gnupg.pdf):
// - No ownertrust assigned / not yet calculated.
// e Trust calculation has failed; probably due to an expired key.
// q Not enough information for calculation.
// n Never trust this key.
// m Marginally trusted.
// f Fully trusted.
// u Ultimately trusted.
// with additional flags
// (see EnigGetTrustLabel() in ui/content/enigmailCommon.js):
// i: invalid
// d/D: disabled
// r: revoked
// g: group (???)
// and as it has been in the following string in old versions:
// o: ???
// trust level sorted by increasing level of trust
// - Note:
// - n (explicit mistrust) is considered to be more severe than "unknown")
const TRUSTLEVEL_SORTED = "oidreDn-qmfu"; // see also enigmailMsgComposeHelper.js, enigmailUserSelection.js
var gTxtConverter = null;
var EnigmailFuncs = {
......@@ -578,8 +601,6 @@ var EnigmailFuncs = {
if (! sortColumn) sortColumn = "userid";
if (! sortDirection) sortDirection = 1;
const TRUSTLEVEL_SORTED="oidreD-qnmfu"; // trust level sorted by increasing level of trust
var sortByKeyId = function (a, b) {
return (a.keyId < b.keyId) ? -sortDirection : sortDirection;
};
......
......@@ -129,7 +129,7 @@ var gStatusFlags = {GOODSIG: nsIEnigmail.GOOD_SIGNATURE,
UNKNOWN_ALGO: nsIEnigmail.UNKNOWN_ALGO,
SIG_CREATED: nsIEnigmail.SIG_CREATED,
END_ENCRYPTION : nsIEnigmail.END_ENCRYPTION,
INV_SGNR: 0x100000000
INV_SGNR: 0x100000000
};
///////////////////////////////////////////////////////////////////////////////
......@@ -1253,8 +1253,9 @@ Enigmail.prototype = {
},
encryptMessage: function (parent, uiFlags, plainText, fromMailAddr, toMailAddr, bccMailAddr,
sendFlags, exitCodeObj, statusFlagsObj, errorMsgObj) {
encryptMessage: function (parent, uiFlags, plainText, fromMailAddr, toMailAddr, bccMailAddr, sendFlags,
exitCodeObj, statusFlagsObj, errorMsgObj)
{
Ec.DEBUG_LOG("enigmail.js: Enigmail.encryptMessage: "+plainText.length+" bytes from "+fromMailAddr+" to "+toMailAddr+" ("+sendFlags+")\n");
exitCodeObj.value = -1;
......@@ -1293,10 +1294,10 @@ Enigmail.prototype = {
});
var proc = Ec.encryptMessageStart(parent, uiFlags, fromMailAddr, toMailAddr,
bccMailAddr, null, sendFlags,
listener, statusFlagsObj, errorMsgObj);
var proc = Ec.encryptMessageStart(parent, uiFlags,
fromMailAddr, toMailAddr, bccMailAddr,
null, sendFlags,
listener, statusFlagsObj, errorMsgObj);
if (! proc) {
exitCodeObj.value = -1;
return "";
......@@ -1307,9 +1308,9 @@ Enigmail.prototype = {
var retStatusObj = {};
exitCodeObj.value = Ec.encryptMessageEnd(getUnicodeData(listener.stderrData), listener.exitCode,
uiFlags, sendFlags,
listener.stdoutData.length,
retStatusObj);
uiFlags, sendFlags,
listener.stdoutData.length,
retStatusObj);
statusFlagsObj.value = retStatusObj.statusFlags;
errorMsgObj.value = retStatusObj.errorMsg;
......@@ -1320,13 +1321,11 @@ Enigmail.prototype = {
if (exitCodeObj.value == 0) {
// Normal return
return getUnicodeData(listener.stdoutData);
}
// Error processing
Ec.DEBUG_LOG("enigmail.js: Enigmail.encryptMessage: command execution exit code: "+exitCodeObj.value+"\n");
return "";
},
......
......@@ -145,6 +145,13 @@ pref("extensions.enigmail.quotedPrintableWarn",0);
// use http proxy settings as set in Mozilla/Thunderbird
pref("extensions.enigmail.respectHttpProxy",true);
// selection for automatic send encrypted if all keys valid
// 0: never
// 1: with full trust
// 2: with marginal trust
// 3: with unknown trust
pref("extensions.enigmail.autoSendEncrypted",0);
// selection of keys for unkown recipients
// 1: rules only
// 2: rules & email addresses (normal)
......
......@@ -139,7 +139,8 @@ const PGP_MIME_ALWAYS = 2;
const ENIG_POSSIBLE_PGPMIME = -2081;
const ENIG_PGP_DESKTOP_ATT = -2082;
var gUsePGPMimeOptionList = ["usePGPMimeNever", "usePGPMimePossible",
var gUsePGPMimeOptionList = ["usePGPMimeNever",
"usePGPMimePossible",
"usePGPMimeAlways"];
var gEnigRecipientsSelection = ["-",
......@@ -148,6 +149,11 @@ var gEnigRecipientsSelection = ["-",
"perEmailAddress",
"askRecipientsAlways"];
var gEnigAutoSendEncrypted = ["autoSendEncryptedNever",
"autoSendEncryptedWithFullTrust",
"autoSendEncryptedWithMarginalTrust",
"autoSendEncryptedWithUnknownTrust"];
const ENIG_BUTTON_POS_0 = 1;
const ENIG_BUTTON_POS_1 = 1 << 8;
const ENIG_BUTTON_POS_2 = 1 << 16;
......
......@@ -128,7 +128,6 @@ function enigmailBuildList(refresh) {
var keyListObj = {};
EnigLoadKeyList(refresh, keyListObj, getSortColumn(), getSortDirection());
gKeyList = keyListObj.keyList;
......@@ -1398,7 +1397,7 @@ function getSortColumn() {
case "keyCol": return "keyidshort";
case "typeCol": return "keytype";
case "validityCol": return "validity";
case "trustCol": return "trust";
case "trustCol": return "trust"; // ownerTrust
case "expCol": return "expiry";
case "fprCol": return "fpr";
default: return "?";
......
......@@ -265,6 +265,113 @@ Enigmail.hlp = {
return true;
},
/* try to find valid key to passed email address
* @return: list of all found key (with leading "0x") or null
*/
validKeysForAllRecipients: function (emailAddrs, minTrustLevel)
{
EnigmailCommon.DEBUG_LOG("enigmailMsgComposeHelper.js: validKeysForAllRecipients(): emailAddrs=\""+emailAddrs+"\" with minTrustLevel=\""+minTrustLevel+"\"\n");
const TRUSTLEVEL_SORTED="oidreDn-qmfu"; // trust level sorted by increasing level of trust (see commonFuncs.jsm)
var minTrustLevelIndex = TRUSTLEVEL_SORTED.indexOf(minTrustLevel);
var resultingArray = new Array; // resulting key list (if all valid)
try {
// get list of known keys
var keyListObj = {};
EnigmailFuncs.loadKeyList(window,
false, // do not refresh key infos,
keyListObj, // returned list
"trust", // ideally sorted acc. to trust
-1); // descending
var keyList = keyListObj.keyList;
var keySortList = keyListObj.keySortList;
// create array of address elements (email or key)
var addresses=EnigmailFuncs.stripEmail(emailAddrs).split(',');
// check whether each address is or has a key:
for (var i=0; i < addresses.length; i++) {
var addr = addresses[i];
// try to find current address in key list:
var found = false;
if (addr.indexOf('@') >= 0) {
// try email match:
var key = this.getValidKeyForRecipient (addr, minTrustLevelIndex, keyList, keySortList);
if (key) {
found = true;
resultingArray.push("0x"+key);
}
}
else {
// try key match:
var key = addr.substring(2); // key list has elements without leading "0x"
var keyObj = keyList[key];
var userId = keyObj.userId;
var keyTrust = keyObj.keyTrust;
var ownerTrust = keyObj.ownerTrust;
// if found, check whether the trust level is enough
if (TRUSTLEVEL_SORTED.indexOf(keyTrust) >= minTrustLevelIndex &&
TRUSTLEVEL_SORTED.indexOf(ownerTrust) >= minTrustLevelIndex) {
found = true;
resultingArray.push(addr);
}
}
if (! found) {
// no key for this address found
EnigmailCommon.DEBUG_LOG("enigmailMsgComposeHelper.js: validKeysForAllRecipients(): no valid key found for=\""+addr+"\" with minTrustLevel=\""+minTrustLevel+"\"\n");
return null;
}
}
}
catch (ex) {
EnigmailCommon.DEBUG_LOG("enigmailMsgComposeHelper.js: validKeysForAllRecipients(): exception: "+ex.description+"\n");
return null;
}
EnigmailCommon.DEBUG_LOG("enigmailMsgComposeHelper.js: validKeysForAllRecipients(): return: resultingArray=\""+resultingArray+"\"\n");
return resultingArray;
},
/* try to find valid key to passed email address
* @return: found key (without leading "0x") or null
*/
getValidKeyForRecipient: function (emailAddr, minTrustLevelIndex, keyList, keySortList)
{
EnigmailCommon.DEBUG_LOG("enigmailMsgComposeHelper.js: getValidKeyForRecipient(): emailAddr=\""+emailAddr+"\"\n");
const TRUSTLEVEL_SORTED="oidreDn-qmfu"; // trust level sorted by increasing level of trust (see commonFuncs.jsm)
for (var idx=0; idx<keySortList.length; idx++) { // fast as we have sorted acc. to ownerTrust
var keyObj = keyList[keySortList[idx].keyId];
var ownerTrust = keyObj.ownerTrust;
// end of loop (owner trust (our sort criterion) too low?
if (TRUSTLEVEL_SORTED.indexOf(ownerTrust) < minTrustLevelIndex) {
return null; // NOT FOUND (below requested trust level)
}
var userId = keyObj.userId;
var keyTrust = keyObj.keyTrust;
var expired = keyObj.expiry;
if (userId && userId.indexOf(emailAddr) >= 0
&& TRUSTLEVEL_SORTED.indexOf(keyTrust) >= minTrustLevelIndex) {
return keyObj.keyId; // FOUND
}
// check whether matching subkeys exist
// - Note: subkeys have NO owner trust
for (var subkey=0; subkey<keyObj.SubUserIds.length; subkey++) {
var subKeyObj = keyObj.SubUserIds[subkey];
var subUserId = subKeyObj.userId;
var subKeyTrust = subKeyObj.keyTrust;
var subExpired = subKeyObj.expiry;
if (subUserId && subUserId.indexOf(emailAddr) >= 0) {
if (TRUSTLEVEL_SORTED.indexOf(subKeyTrust) >= minTrustLevelIndex) {
return keyObj.keyId; // FOUND
}
}
}
}
return null; // not found
},
/**
* processConflicts
* - handle sign/encrypt/pgpMime conflicts if any
......@@ -295,7 +402,7 @@ Enigmail.hlp = {
flagsObj.encrypt = 0;
conflictFound = true;
}
if (interactive && conflictFound && (!EnigmailCommon.getPref("confirmBeforeSend"))) {
if (interactive && conflictFound) {
var sign = flagsObj.sign;
var encrypt = flagsObj.encrypt;
// process message about whether we still sign/encrypt
......
......@@ -1258,13 +1258,14 @@ Enigmail.msg = {
// - enableRules: rules not temporarily disabled
// REPLACES email addresses by keys in its result !!!
if (recipientsSelection != 3 && recipientsSelection != 4 && this.enableRules) {
var result = this.processRules (forceRecipientSettings, sendFlags, toAddr, bccAddr)
var result = this.processRules (forceRecipientSettings, sendFlags, optSendFlags, toAddr, bccAddr)
if (!result) {
return null;
}
sendFlags = result.sendFlags;
toAddr = result.toAddr; // replace email addresses with rules by the corresponding keys
bccAddr = result.bccAddr; // replace email addresses with rules by the corresponding keys
sendFlags = result.sendFlags;
optSendFlags = result.optSendFlags;
toAddr = result.toAddr; // replace email addresses with rules by the corresponding keys
bccAddr = result.bccAddr; // replace email addresses with rules by the corresponding keys
}
// if encryption is requested for the email:
......@@ -1304,12 +1305,13 @@ Enigmail.msg = {
*
* @forceRecipientSetting: force manual selection for each missing key?
* @sendFlags: INPUT/OUTPUT all current combined/processed send flags (incl. optSendFlags)
* @optSendFlags: INOUT/OUTPUT may only be SEND_ALWAYS_TRUST or SEND_ENCRYPT_TO_SELF
* @toAddr: INPUT/OUTPUT comma separated string of keys and unprocessed to/cc emails
* @bccAddr: INPUT/OUTPUT comma separated string of keys and unprocessed bcc emails
* @return: { sendFlags, toAddr, bccAddr }
* or null (cancel sending the email)
*/
processRules: function (forceRecipientSettings, sendFlags, toAddr, bccAddr)
processRules: function (forceRecipientSettings, sendFlags, optSendFlags, toAddr, bccAddr)
{
EnigmailCommon.DEBUG_LOG("enigmailMsgComposeOverlay.js: Enigmail.msg.processRules(): toAddr=\""+toAddr+"\" bccAddr=\""+bccAddr+"\" forceRecipientSettings="+forceRecipientSettings+"\n");
const nsIEnigmail = Components.interfaces.nsIEnigmail;
......@@ -1369,6 +1371,43 @@ Enigmail.msg = {
}
}
// if allowed, try to send automatically if all keys known
if (((sendFlags&ENCRYPT) == 0) && (!flagsObj.value || flagsObj.encrypt == 1) && bccAddr.length == 0) {
var autoSendEncrypted = EnigmailCommon.getPref("autoSendEncrypted");
if (autoSendEncrypted) {
EnigmailCommon.DEBUG_LOG("enigmailMsgComposeOverlay.js: Enigmail.msg.processRules(): autoSendEncrypted=\""+autoSendEncrypted+"\"\n");
var minTrustLevel;
switch (autoSendEncrypted) {
case 0: // EncNever
minTrustLevel = null;
break;
case 1: // EncWithFullTrust
minTrustLevel = "f";
break;
case 2: // EncWithMarginalTrust
minTrustLevel = "m";
break;
case 3: // EncWithUnknownTrust
minTrustLevel = "-";
break;
default: // EncNever
minTrustLevel = null;
break;
}
if (minTrustLevel != null) {
var keyList = Enigmail.hlp.validKeysForAllRecipients(toAddr,minTrustLevel);
if (keyList != null) {
toAddr = keyList.join(", ");
sendFlags |= ENCRYPT;
// in case we have the preference to "auto send encrypted with unknown trust"
// this overrules having preference "always trust" disabled
sendFlags |= nsIEnigmail.SEND_ALWAYS_TRUST;
optSendFlags |= nsIEnigmail.SEND_ALWAYS_TRUST;
}
}
}
}
// get keys for bcc addresses:
// - matchedKeysObj will contain the keys and the remaining bccAddr elements
// - NOTE: bcc recipients are ignored when in general computing whether to sign or encrypt or pgpMime
......@@ -1386,6 +1425,7 @@ Enigmail.msg = {
return {
sendFlags: sendFlags,
optSendFlags: optSendFlags,
toAddr: toAddr,
bccAddr: bccAddr
};
......@@ -1691,6 +1731,9 @@ Enigmail.msg = {
this.addRecipients(toAddrList, recList);
}
// special handling of bcc:
// - note: bcc and encryption is a problem
// - but bcc to the sender is fine
if (msgCompFields.bcc.length > 0) {
recList = splitRecipients(msgCompFields.bcc, true, arrLen);
......
......@@ -157,7 +157,8 @@ function getPubkeysFromSecretKeys(keyString) {
function enigmailBuildList(refresh) {
DEBUG_LOG("enigmailUserSelection.js: enigmailBuildList\n");
const TRUSTLEVEL_SORTED="oidre-qnmfu"; // trust level sorted by increasing level of trust
const TRUSTLEVEL_SORTED="oidreDn-qmfu"; // trust level sorted by increasing level of trust (see commonFuncs.jsm)
var sortUsers = function (a,b) {
var r = 0;
if ((a.activeState == 1 || b.activeState == 1) && (a.activeState != b.activeState)) {
......
......@@ -176,6 +176,9 @@ function prefOnLoad() {
}
EnigDisplayRadioPref("autoSendEncrypted", EnigGetPref("autoSendEncrypted"),
gEnigAutoSendEncrypted);
EnigDisplayRadioPref("recipientsSelection", EnigGetPref("recipientsSelection"),
gEnigRecipientsSelection);
......@@ -262,7 +265,9 @@ function resetPrefs() {
EnigSetPref("configuredVersion", EnigGetVersion());
EnigDisplayRadioPref("recipientsSelection", EnigGetPref("recipientsSelection"),
gEnigRecipientsSelection);
gEnigRecipientsSelection);
EnigDisplayRadioPref("autoSetEncrypted", EnigGetPref("autoSetEncrypted"),
gEnigAutoSetEncrypted);
}
......
......@@ -89,6 +89,18 @@
<tooltip id="confirmBeforeSend.tooltip">
<description>&enigmail.confirmBeforeSend.tooltip;</description>
</tooltip>
<tooltip id="autoSendEncryptedNever.tooltip">
<description>&enigmail.autoSendEncryptedNever.tooltip;</description>
</tooltip>
<tooltip id="autoSendEncryptedWithFullTrust.tooltip">
<description>&enigmail.autoSendEncryptedWithFullTrust.tooltip;</description>
</tooltip>
<tooltip id="autoSendEncryptedWithMarginalTrust.tooltip">
<description>&enigmail.autoSendEncryptedWithMarginalTrust.tooltip;</description>
</tooltip>
<tooltip id="autoSendEncryptedWithUnknownTrust.tooltip">
<description>&enigmail.autoSendEncryptedWithUnknownTrust.tooltip;</description>
</tooltip>
<tooltip id="perRecipientRules.tooltip">
<description>&enigmail.perRecipientRules.tooltip;</description>
</tooltip>
......@@ -248,6 +260,43 @@
<checkbox id="enigmail_confirmBeforeSend"
label="&enigmail.confirmBeforeSend.label;"
tooltip="confirmBeforeSend.tooltip"/>
<!-- options to automatically send encrypted -->
<groupbox>
<caption label="&enigmail.autoSendEncryptedOption.label;"/>
<radiogroup id="enigmail_autoSendEncrypted"
oncommand="activateRulesButton(this, 'openRulesEditor')"
pref="true"
preftype="int"
prefstring="extensions.enigmail.autoSendEncrypted">
<radio id="autoSendEncryptedNever"
value="0"
label="&enigmail.autoSendEncryptedNever.label;"
tooltip="autoSendEncryptedNever.tooltip"/>
<radio id="autoSendEncryptedWithFullTrust"
value="1"
label="&enigmail.autoSendEncryptedWithFullTrust.label;"
tooltip="autoSendEncryptedWithFullTrust.tooltip"/>
<radio id="autoSendEncryptedWithMarginalTrust"
value="2"
label="&enigmail.autoSendEncryptedWithMarginalTrust.label;"
tooltip="autoSendEncryptedWithMarginalTrust.tooltip"/>
<radio id="autoSendEncryptedWithUnknownTrust"
value="3"
label="&enigmail.autoSendEncryptedWithUnknownTrust.label;"
tooltip="autoSendEncryptedWithUnknownTrust.tooltip"/>
</radiogroup>
<separator/>
<vbox autostretch="always" align="end">
<button id="openKeysEditor"
label="open key editor" qqq="&enigmail.defineRules.label;"
tooltip="defineRules.tooltip"
oncommand="EnigKeysEditor();"/>
</vbox>
</groupbox>
</vbox>
<!-- "Key Selection" Tab -->
......
......@@ -75,8 +75,8 @@
<!ENTITY enigmail.whenSending.label "When sending mail">
<!ENTITY enigmail.moreOptions.label "More options">
<!ENTITY enigmail.alwaysTrustSend.label "Always trust people's keys">
<!ENTITY enigmail.alwaysTrustSend.tooltip "Do not use the Web of Trust to determine the validity of keys">
<!ENTITY enigmail.alwaysTrustSend.label "Always trust people's valid keys">
<!ENTITY enigmail.alwaysTrustSend.tooltip "Do not use the Web of Trust to determine the validity of keys (except for expired or revoked keys)">
<!ENTITY enigmail.useNonDefaultComment.label "Add Enigmail comment in OpenPGP signature">
<!ENTITY enigmail.keyserver.label "Keyserver">
......@@ -207,6 +207,16 @@
<!ENTITY enigmail.defaultEncryptionNone.label "No default encryption">
<!ENTITY enigmail.defaultNotSignedsend.label "Do not sign messages by default">
<!ENTITY enigmail.autoSendEncryptedOption.label "Automatically send encrypted when all keys are known and valid">
<!ENTITY enigmail.autoSendEncryptedNever.label "Never">
<!ENTITY enigmail.autoSendEncryptedNever.tooltip "Automatically send encrypted disabled (rules might still be defined to have this effect)">
<!ENTITY enigmail.autoSendEncryptedWithFullTrust.label "When all keys have full trust">
<!ENTITY enigmail.autoSendEncryptedWithFullTrust.tooltip "Automatically send encrypted when all keys are known with full trust">
<!ENTITY enigmail.autoSendEncryptedWithMarginalTrust.label "When all keys have at least marginal trust">
<!ENTITY enigmail.autoSendEncryptedWithMarginalTrust.tooltip "Automatically send encrypted when all keys are known with at least marginal trust">
<!ENTITY enigmail.autoSendEncryptedWithUnknownTrust.label "When no key has explicit mistrust">
<!ENTITY enigmail.autoSendEncryptedWithUnknownTrust.tooltip "Automatically send encrypted when all keys are known without explicit mistrust">
<!ENTITY enigmail.recipientsSelectionOption.label "How should we choose the keys?">
<!ENTITY enigmail.perRecipientRules.label "By pre-set rules only">
<!ENTITY enigmail.perRecipientRules.tooltip "Choose keys according to rules; prompt for creating new rules recipients without rules.">
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment