2
The contents of this file are subject to the Mozilla Public
3
License Version 1.1 (the "MPL"); you may not use this file
4
except in compliance with the MPL. You may obtain a copy of
5
the MPL at http://www.mozilla.org/MPL/
7
Software distributed under the MPL is distributed on an "AS
8
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
9
implied. See the MPL for the specific language governing
10
rights and limitations under the MPL.
12
The Original Code is Enigmail.
14
The Initial Developer of the Original Code is Ramalingam Saravanan.
15
Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
16
Copyright (C) 2001 Ramalingam Saravanan. All Rights Reserved.
19
Patrick Brunschwig <patrick.brunschwig@gmx.net>
21
Alternatively, the contents of this file may be used under the
22
terms of the GNU General Public License (the "GPL"), in which case
23
the provisions of the GPL are applicable instead of
24
those above. If you wish to allow use of your version of this
25
file only under the terms of the GPL and not to allow
26
others to use your version of this file under the MPL, indicate
27
your decision by deleting the provisions above and replace them
28
with the notice and other provisions required by the GPL.
29
If you do not delete the provisions above, a recipient
30
may use your version of this file under either the MPL or the
34
// Uses: chrome://enigmail/content/enigmailCommon.js
36
// Initialize enigmailCommon
38
EnigInitCommon("enigmailMessengerOverlay");
39
Components.utils.import("resource://app/modules/gloda/mimemsg.js");
41
var gEnigCreatedURIs = [];
43
var gEnigDecryptedMessage;
44
var gEnigSecurityInfo = null;
45
var gEnigLastSaveDir = "";
47
var gEnigMessagePane = null;
48
var gEnigNoShowReload = false;
49
var gEnigLastEncryptedMsgKey = null;
50
var gEnigDecryptButton = null;
51
var gEnigIpcRequest = null;
53
var gEnigRemoveListener = false;
55
var gEnigHeadersList = ["content-type", "content-transfer-encoding",
56
"x-enigmail-version"];
57
var gEnigSavedHeaders = null;
59
var gShowHeadersObj = {"viewallheaders":2,
60
"viewnormalheaders":1,
61
"viewbriefheaders":0};
63
window.addEventListener("load", enigMessengerStartup, false);
64
window.addEventListener("unload", enigMessengerFinish, false);
66
var gEnigTreeController = {
67
supportsCommand: function(command) {
68
// DEBUG_LOG("enigmailMessengerOverlay.js: treeCtrl: supportsCommand: "+command+"\n");
70
case "button_enigmail_decrypt":
75
isCommandEnabled: function(command) {
76
// DEBUG_LOG("enigmailMessengerOverlay.js: treeCtrl: isCommandEnabled: "+command+"\n");
78
if (gFolderDisplay.messageDisplay.visible) {
79
if (gFolderDisplay.selectedCount != 1) enigStatusBarHide();
80
return (gFolderDisplay.selectedCount == 1);
87
doCommand: function(command) {
88
//DEBUG_LOG("enigmailMessengerOverlay.js: treeCtrl: doCommand: "+command+"\n");
91
onEvent: function(event) {
92
// DEBUG_LOG("enigmailMessengerOverlay.js: treeCtrl: onEvent: "+command+"\n");
97
function enigMessengerStartup() {
98
DEBUG_LOG("enigmailMessengerOverlay.js: Startup\n");
100
gEnigMessagePane = document.getElementById("messagepane");
102
if (gEnigMessagePane == null) return; // TB 2.0 on Mac OS X calls this twice -- once far too early
104
// enigUpdateOptionsDisplay();
107
var viewSecurityCmd = document.getElementById("cmd_viewSecurityStatus");
108
if (viewSecurityCmd) {
109
viewSecurityCmd.setAttribute("oncommand", "enigViewSecurityInfo(null, true);");
112
// Override print command
113
var printElementIds = ["cmd_print", "cmd_printpreview", "key_print", "button-print",
114
"mailContext-print", "mailContext-printpreview"];
116
EnigOverrideAttribute( printElementIds, "oncommand",
117
"enigMsgPrint('", "');");
119
enigOverrideLayoutChange();
121
gEnigSavedHeaders = null;
123
gEnigDecryptButton = document.getElementById("button-enigmail-decrypt");
125
var toolbarElem = document.getElementById("mail-bar2");
126
if (toolbarElem && EnigGetOS() == "Darwin") {
127
toolbarElem.setAttribute("platform", "macos");
130
enigMessageFrameLoad();
132
// Need to add event listener to gEnigMessagePane to make it work
133
// Adding to msgFrame doesn't seem to work
134
gEnigMessagePane.addEventListener("unload", enigMessageFrameUnload, true);
135
gEnigMessagePane.addEventListener("load", enigMessageFrameLoad, true);
137
if (EnigGetPref("handleDoubleClick")) {
138
// ovveride function for double clicking an attachment
139
EnigOverrideAttribute(["attachmentList"], "onclick",
140
"enigAttachmentListClick('", "', event);");
143
top.controllers.appendController(gEnigTreeController);
146
function enigMessengerFinish() {
147
DEBUG_LOG("enigmailMessengerOverlay.js: Finish\n");
151
function enigViewSecurityInfo(event, displaySmimeMsg) {
152
DEBUG_LOG("enigmailMessengerOverlay.js: enigViewSecurityInfo\n");
154
if (event && event.button != 0)
157
if (gSignatureStatus >= 0 || gEncryptionStatus >= 0) {
158
showMessageReadSecurityInfo()
161
if (gEnigSecurityInfo)
162
enigViewOpenpgpInfo()
164
showMessageReadSecurityInfo();
168
function enigViewOpenpgpInfo() {
169
if (gEnigSecurityInfo) {
170
EnigLongAlert(EnigGetString("securityInfo")+gEnigSecurityInfo.statusInfo);
175
function enigDisplayMimeMessage() {
176
DEBUG_LOG("enigmailMessengerOverlay.js: enigDisplayMimeMessage\n");
178
var charset = msgWindow ? msgWindow.mailCharacterSet : "";
179
var contentEncoding = "";
181
if ("content-transfer-encoding" in gEnigSavedHeaders) {
182
contentEncoding = gEnigSavedHeaders["content-transfer-encoding"];
185
enigMsgDirect(true, false, contentEncoding, charset, "", 0, "", "", enigDisplayMimeCallback)
188
function enigDisplayMimeCallback(msgText) {
189
DEBUG_LOG("enigmailMessengerOverlay.js: enigDisplayMimeCallback\n");
194
var enigmailSvc = GetEnigmailSvc();
202
var errorMsgObj = new Object();
203
var keyIdObj = new Object();
204
var exitCodeObj = new Object();
205
var statusFlagsObj = new Object();
206
var userIdObj = new Object();
207
var sigDetailsObj = new Object();
208
var blockSeparationObj = new Object();
209
var signatureObj = new Object();
210
var uiFlags = nsIEnigmail.UI_INTERACTIVE;
212
plainText = enigmailSvc.decryptMessage(window, uiFlags, msgText,
213
signatureObj, exitCodeObj, statusFlagsObj,
214
keyIdObj, userIdObj, sigDetailsObj, errorMsgObj, blockSeparationObj);
217
if (interactive && gEnigSecurityInfo && gEnigSecurityInfo.statusInfo)
218
EnigLongAlert(gEnigSecurityInfo.statusInfo);
222
if (blockSeparationObj.value.indexOf(" ")>=0) {
223
var blocks = blockSeparationObj.value.split(/ /);
224
var blockInfo = blocks[0].split(/:/);
225
plainText = EnigGetString("notePartEncrypted") + "\n\n" + plainText.substr(0, blockInfo[1]) + "\n\n" + EnigGetString("noteCutMessage");
227
EnigLongAlert(EnigGetString("securityInfo")+gEnigSecurityInfo.statusInfo+"\n---------------------------------\n"+plainText);
230
function enigMessageReload(noShowReload) {
231
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageReload: "+noShowReload+"\n");
233
gEnigNoShowReload = noShowReload;
238
function enigmailReloadCompleteMsg() {
239
gDBView.reloadMessageWithAllParts();
243
function enigMessageCleanup() {
244
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageCleanup\n");
246
var enigmailBox = document.getElementById("enigmailBox");
248
if (enigmailBox && !enigmailBox.collapsed) {
249
enigmailBox.setAttribute("collapsed", "true");
251
var statusText = document.getElementById("expandedEnigmailStatusText");
257
if (gEnigCreatedURIs.length) {
258
// Cleanup messages belonging to this window (just in case)
259
var enigmailSvc = GetEnigmailSvc();
261
DEBUG_LOG("enigmailMessengerOverlay.js: Cleanup: Deleting messages\n");
262
for (var index=0; index < gEnigCreatedURIs.length; index++) {
263
enigmailSvc.deleteMessageURI(gEnigCreatedURIs[index]);
265
gEnigCreatedURIs = [];
269
gEnigDecryptedMessage = null;
270
gEnigSecurityInfo = null;
273
function enigMimeInit() {
274
DEBUG_LOG("enigmailMessengerOverlay.js: *****enigMimeInit\n");
277
const ENIG_ENIGCONTENTHANDLER_CID =
278
Components.ID("{847b3a51-7ab1-11d4-8f02-006008948af5}");
280
const ENIG_ENIGENCRYPTEDHANDLER_CONTRACTID = "@mozilla.org/mimecth;1?type=multipart/encrypted";
282
var compMgr = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
284
var enigContentHandlerCID = compMgr.contractIDToCID(ENIG_ENIGENCRYPTEDHANDLER_CONTRACTID);
286
var handlePGPMime = (enigContentHandlerCID.toString() ==
287
ENIG_ENIGCONTENTHANDLER_CID);
289
DEBUG_LOG("enigmailMessengerOverlay.js: *****enigMimeInit: handlePGPMime="+handlePGPMime+"\n");
293
if (gEnigRemoveListener) {
294
gEnigMessagePane.removeEventListener("load", enigMimeInit, true);
295
gEnigRemoveListener = false;
298
var enigmailSvc = GetEnigmailSvc();
302
if (enigmailSvc.mimeInitialized()) {
303
// Reload message ONLY if enigMimeService has been initialized;
304
// enigMimeInit is only called if enigMimeService was not initialized;
305
// this prevents looping.
306
DEBUG_LOG("enigmailMessengerOverlay.js: *****enigMimeInit: RELOADING MESSAGE\n");
308
enigMessageReload(false);
311
// Error in MIME initialization; forget saved headers (to avoid looping)
312
gEnigSavedHeaders = null;
313
ERROR_LOG("enigmailMessengerOverlay.js: *****enigMimeInit: Error in MIME initialization\n");
317
function enigMessageFrameLoad() {
318
// called before a message is displayed
319
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageFrameLoad\n");
320
// not used anymore (-> gEnigTreeController)
324
function enigMessageFrameUnload() {
325
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageFrameUnload\n");
327
if (gEnigNoShowReload) {
328
gEnigNoShowReload = false;
331
gEnigSavedHeaders = null;
333
enigMessageCleanup();
337
function enigThreadPaneOnClick() {
338
DEBUG_LOG("enigmailMessengerOverlay.js: enigThreadPaneOnClick\n");
341
function enigOverrideLayoutChange() {
342
DEBUG_LOG("enigmailMessengerOverlay.js: enigOverrideLayoutChange\n");
343
var viewTypeElementIds = ["messagePaneVertical",
344
"messagePaneClassic",
346
for (var i = 0; i < viewTypeElementIds.length; i++) {
347
var elementId = viewTypeElementIds[i];
348
var element = document.getElementById(elementId);
351
var oldValue = element.getAttribute("oncommand").replace(/;/g, "");
352
var arg=oldValue.replace(/^(.*)(\(.*\))/, "$2");
353
element.setAttribute("oncommand", "enigChangeMailLayout"+arg);
358
var toggleMsgPaneElementIds = ["cmd_toggleMessagePane"];
359
for (var i = 0; i < toggleMsgPaneElementIds.length; i++) {
360
var elementId = toggleMsgPaneElementIds[i];
361
var element = document.getElementById(elementId);
364
element.setAttribute("oncommand", "enigToggleMessagePane()");
371
function enigChangeMailLayout(viewType) {
372
ChangeMailLayout(viewType);
374
// This event requires that we re-subscribe to these events!
375
gEnigMessagePane.addEventListener("unload", enigMessageFrameUnload, true);
376
gEnigMessagePane.addEventListener("load", enigMessageFrameLoad, true);
377
enigMessageReload(false);
380
function enigToggleMessagePane() {
382
MsgToggleMessagePane(true);
384
var button=document.getElementById("button_enigmail_decrypt")
385
if (gFolderDisplay.messageDisplay.visible) {
386
button.removeAttribute("disabled");
389
button.setAttribute("disabled", "true");
393
function enigGetCurrentMsgUriSpec() {
395
if (gFolderDisplay.selectedMessages.length != 1)
398
var uriSpec = gFolderDisplay.selectedMessageUris[0];
399
//DEBUG_LOG("enigmailMessengerOverlay.js: enigGetCurrentMsgUrl: uriSpec="+uriSpec+"\n");
408
function enigGetCurrentMsgUrl() {
410
var uriSpec = enigGetCurrentMsgUriSpec();
415
var msgService = messenger.messageServiceFromURI(uriSpec);
417
var urlObj = new Object();
418
msgService.GetUrlForUri(uriSpec, urlObj, msgWindow);
420
var url = urlObj.value;
422
if (url.scheme=="file") {
426
return url.QueryInterface(Components.interfaces.nsIMsgMailNewsUrl);
435
function enigUpdateOptionsDisplay() {
436
DEBUG_LOG("enigmailMessengerOverlay.js: enigUpdateOptionsDisplay: \n");
437
var optList = ["autoDecrypt"];
439
for (var j=0; j<optList.length; j++) {
440
var menuElement = document.getElementById("enigmail_"+optList[j]);
441
menuElement.setAttribute("checked", EnigGetPref(optList[j]) ? "true" : "false");
444
optList = ["decryptverify", "importpublickey", "savedecrypted"];
445
for (j=0; j<optList.length; j++) {
446
menuElement = document.getElementById("enigmail_"+optList[j]);
447
if (gEnigDecryptButton && gEnigDecryptButton.disabled) {
448
menuElement.setAttribute("disabled", "true");
451
menuElement.removeAttribute("disabled");
457
function enigToggleAttribute(attrName)
459
DEBUG_LOG("enigmailMsgessengerOverlay.js: enigToggleAttribute('"+attrName+"')\n");
461
var menuElement = document.getElementById("enigmail_"+attrName);
463
var oldValue = EnigGetPref(attrName);
464
EnigSetPref(attrName, !oldValue);
466
enigUpdateOptionsDisplay();
468
if (attrName == "autoDecrypt")
469
enigMessageReload(false);
472
function enigMessageImport(event) {
473
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageImport: "+event+"\n");
475
return enigMessageParse(!event, true, "");
478
// callback function for automatic decryption
479
function enigMessageAutoDecrypt(event) {
480
enigMessageDecrypt(event, true);
483
// analyse message header and decrypt/verify message
484
function enigMessageDecrypt(event, isAuto) {
485
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageDecrypt: "+event+"\n");
493
MsgHdrToMimeMessage(gFolderDisplay.selectedMessage , cbObj, enigMsgDecryptMimeCb, true);
496
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageDecrypt: cannot use MsgHdrToMimeMessage\n");
497
enigMessageDecryptCb(event, isAuto, null);
502
function enigMsgDecryptMimeCb(msg, mimeMsg) {
503
var enigmailSvc=GetEnigmailSvc();
504
if (!enigmailSvc) return;
506
enigMessageDecryptCb(this.event, this.isAuto, mimeMsg);
509
function enigMessageDecryptCb(event, isAuto, mimeMsg){
510
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageDecryptCb:\n");
513
var contentType = "";
515
if (mimeMsg == null) {
516
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageDecryptCb: mimeMsg is null\n");
517
contentType=currentHeaderData['content-type'].headerValue;
519
headers: {'content-type': contentType },
520
contentType: contentType,
525
// Copy selected headers
526
gEnigSavedHeaders = {};
528
for (var index=0; index < gEnigHeadersList.length; index++) {
529
var headerName = gEnigHeadersList[index];
530
var headerValue = "";
532
if (mimeMsg.headers[headerName] != undefined) {
533
headerValue = mimeMsg.headers[headerName].toString();
536
gEnigSavedHeaders[headerName] = headerValue;
537
DEBUG_LOG("enigmailMessengerOverlay.js: "+headerName+": "+headerValue+"\n");
540
var embeddedSigned = null;
541
var embeddedEncrypted = null;
542
if (gEnigSavedHeaders["content-type"] &&
543
((gEnigSavedHeaders["content-type"].search(/^multipart\/mixed/i) == 0) ||
544
(gEnigSavedHeaders["content-type"].search(/^multipart\/encrypted/i) == 0))) {
545
for (var indexb in currentAttachments) {
546
var attachment = currentAttachments[indexb];
548
if (attachment.contentType.search(/^application\/pgp-signature/i) == 0) {
549
embeddedSigned = attachment.url.replace(/\&filename=.*$/,"").replace(/\.\d+\.\d+$/, "");
551
if (attachment.contentType.search(/^application\/pgp-encrypted/i) == 0) {
552
embeddedEncrypted = attachment.url.replace(/\&filename=.*$/,"").replace(/\.\d+\.\d+$/, "");
554
DEBUG_LOG("enigmailMessengerOverlay.js: "+indexb+": "+attachment.contentType+"\n");
559
var contentEncoding = "";
560
var xEnigmailVersion = "";
562
if (gEnigSavedHeaders) {
563
contentType = gEnigSavedHeaders["content-type"];
564
contentEncoding = gEnigSavedHeaders["content-transfer-encoding"];
565
xEnigmailVersion = gEnigSavedHeaders["x-enigmail-version"];
568
if (isAuto && (! EnigGetPref("autoDecrypt"))) {
569
var signedMsg = ((contentType.search(/^multipart\/signed(;|$)/i) == 0) && (contentType.search(/application\/pgp-signature/i)>0));
570
var encrypedMsg = ((contentType.search(/^multipart\/encrypted(;|$)/i) == 0) && (contentType.search(/application\/pgp-encrypted/i)>0));
571
if (embeddedSigned || embeddedEncrypted ||
572
encrypedMsg || signedMsg) {
573
enigmailSvc = GetEnigmailSvc();
577
if ((!enigmailSvc.mimeInitialized() && encrypedMsg) || signedMsg ||
578
((!encrypedMsg) && (embeddedSigned || embeddedEncrypted))) {
579
enigUpdateHdrIcons(ENIG_POSSIBLE_PGPMIME, 0, "", "", "", EnigGetString("possiblyPgpMime"));
585
if (((contentType.search(/^multipart\/encrypted(;|$)/i) == 0) ||
586
(embeddedEncrypted && contentType.search(/^multipart\/mixed(;|$)/i) == 0))
587
&& (!embeddedSigned)) {
588
// multipart/encrypted
589
DEBUG_LOG("enigmailMessengerOverlay.js: multipart/encrypted\n");
590
enigmailSvc = GetEnigmailSvc();
594
if (!enigmailSvc.mimeInitialized()) {
595
// Display enigmail:dummy URL in message pane to initialize
597
// Need to add event listener to gEnigMessagePane to make it work
598
// Adding to msgFrame doesn't seem to work
599
gEnigMessagePane.addEventListener("load", enigMimeInit, true);
600
gEnigRemoveListener = true;
602
DEBUG_LOG("enigmailMessengerOverlay.js: loading enigmail:dummy ...\n");
603
gEnigNoShowReload = true;
605
var msgFrame = EnigGetFrame(window, "messagepane");
606
messenger.loadURL(msgFrame, "enigmail:dummy");
610
enigMessageReload(false);
612
else if (embeddedEncrypted && (! encrypedMsg)) {
613
var mailNewsUrl = enigGetCurrentMsgUrl();
615
mailNewsUrl.spec = embeddedEncrypted;
616
enigVerifyEmbeddedMsg(window, mailNewsUrl, msgWindow, msgUriSpec, contentEncoding, event);
623
var tryVerify = false;
624
var msgUriSpec = enigGetCurrentMsgUriSpec();
625
var enableSubpartTreatment = false;
626
// special treatment for embedded signed messages
627
if (embeddedSigned) {
628
if (contentType.search(/^multipart\/encrypted(;|$)/i) == 0) {
631
if (contentType.search(/^multipart\/mixed(;|$)/i) == 0) {
633
enableSubpartTreatment = true;
637
if ((contentType.search(/^multipart\/signed(;|$)/i) == 0) &&
638
(contentType.search(/application\/pgp-signature/i) >= 0)) {
643
DEBUG_LOG("enigmailMessengerOverlay.js: multipart/signed\n");
645
enigmailSvc = GetEnigmailSvc();
649
var mailNewsUrl = enigGetCurrentMsgUrl();
651
if (embeddedSigned) {
652
mailNewsUrl.spec = embeddedSigned;
653
enigVerifyEmbeddedMsg(window, mailNewsUrl, msgWindow, msgUriSpec, contentEncoding, event);
656
var verifier = Components.classes[ENIG_ENIGMIMEVERIFY_CONTRACTID].createInstance(Components.interfaces.nsIEnigMimeVerify);
658
verifier.init(window, mailNewsUrl, msgWindow, msgUriSpec,
659
true, enableSubpartTreatment);
665
enigMessageParse(!event, false, contentEncoding);
669
function enigMessageParse(interactive, importOnly, contentEncoding) {
670
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageParse: "+interactive+"\n");
671
var msgFrame = EnigGetFrame(window, "messagepane");
672
DEBUG_LOG("enigmailMessengerOverlay.js: msgFrame="+msgFrame+"\n");
675
///EnigDumpHTML(msgFrame.document.documentElement);
677
var bodyElement = msgFrame.document.getElementsByTagName("body")[0];
678
DEBUG_LOG("enigmailMessengerOverlay.js: bodyElement="+bodyElement+"\n");
680
var findStr = /* interactive ? null : */ "-----BEGIN PGP";
685
foundIndex = bodyElement.textContent.indexOf(findStr);
686
if (foundIndex >= 0) {
687
if (bodyElement.textContent.indexOf(findStr+" LICENSE AUTHORIZATION") == foundIndex)
691
if (foundIndex >= 0) {
692
msgText = bodyElement.textContent;
700
var charset = msgWindow ? msgWindow.mailCharacterSet : "";
702
// Encode ciphertext to charset from unicode
703
msgText = EnigConvertFromUnicode(msgText, charset);
705
var mozPlainText = bodyElement.innerHTML.search(/class=\"moz-text-plain\"/);
707
if ((mozPlainText >= 0) && (mozPlainText < 40)) {
708
// workaround for too much expanded emoticons in plaintext msg
709
var r = new RegExp(/( )(;-\)|:-\)|;\)|:\)|:-\(|:\(|:-\\|:-P|:-D|:-\[|:-\*|\>:o|8-\)|:-\$|:-X|\=-O|:-\!|O:-\)|:\'\()( )/g);
710
if (msgText.search(r) >= 0) {
711
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageParse: performing emoticons fixing\n");
712
msgText = msgText.replace(r, "$2");
716
// extract text preceeding and/or following armored block
720
head=msgText.substring(0,msgText.indexOf(findStr)).replace(/^[\n\r\s]*/,"");
721
head=head.replace(/[\n\r\s]*$/,"");
722
var endStart=msgText.indexOf("-----END PGP");
723
var nextLine=msgText.substring(endStart).search(/[\n\r]/);
725
tail=msgText.substring(endStart+nextLine).replace(/^[\n\r\s]*/,"");
729
//DEBUG_LOG("enigmailMessengerOverlay.js: msgText='"+msgText+"'\n");
731
var mailNewsUrl = enigGetCurrentMsgUrl();
733
var urlSpec = mailNewsUrl ? mailNewsUrl.spec : "";
735
retry = (charset != "UTF-8" ? 1 : 2);
737
enigMessageParseCallback(msgText, contentEncoding, charset, interactive,
738
importOnly, urlSpec, "", retry, head, tail);
742
function enigMessageParseCallback(msgText, contentEncoding, charset, interactive,
743
importOnly, messageUrl, signature, retry,
745
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageParseCallback: "+interactive+", "+interactive+", importOnly="+importOnly+", charset="+charset+", msgUrl="+messageUrl+", retry="+retry+", signature='"+signature+"'\n");
750
var enigmailSvc = GetEnigmailSvc();
756
var newSignature = "";
759
var errorMsgObj = new Object();
760
var keyIdObj = new Object();
764
var importFlags = nsIEnigmail.UI_INTERACTIVE;
765
exitCode = enigmailSvc.importKey(window, importFlags, msgText, "",
770
if (msgText.indexOf("\nCharset:") > 0) {
771
// Check if character set needs to be overridden
772
var startOffset = msgText.indexOf("-----BEGIN PGP ");
774
if (startOffset >= 0) {
775
var subText = msgText.substr(startOffset);
777
subText = subText.replace(/\r\n/g, "\n");
778
subText = subText.replace(/\r/g, "\n");
780
var endOffset = subText.search(/\n\n/);
782
subText = subText.substr(0,endOffset) + "\n";
784
var matches = subText.match(/\nCharset: *(.*) *\n/i)
785
if (matches && (matches.length > 1)) {
786
// Override character set
787
charset = matches[1];
788
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageParseCallback: OVERRIDING charset="+charset+"\n");
794
var exitCodeObj = new Object();
795
var statusFlagsObj = new Object();
796
var userIdObj = new Object();
797
var sigDetailsObj = new Object();
798
var blockSeparationObj = new Object();
800
var signatureObj = new Object();
801
signatureObj.value = signature;
803
var uiFlags = interactive ? (nsIEnigmail.UI_INTERACTIVE |
804
nsIEnigmail.UI_ALLOW_KEY_IMPORT |
805
nsIEnigmail.UI_UNVERIFIED_ENC_OK) : 0;
808
plainText = enigmailSvc.decryptMessage(window, uiFlags, msgText,
809
signatureObj, exitCodeObj, statusFlagsObj,
810
keyIdObj, userIdObj, sigDetailsObj, errorMsgObj, blockSeparationObj);
812
//DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageParseCallback: plainText='"+plainText+"'\n");
814
exitCode = exitCodeObj.value;
815
newSignature = signatureObj.value;
817
if (plainText == "" && exitCode == 0) {
821
statusFlags = statusFlagsObj.value;
823
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageParseCallback: newSignature='"+newSignature+"'\n");
826
var errorMsg = errorMsgObj.value;
829
if (interactive && errorMsg)
830
EnigLongAlert(errorMsg);
834
enigUpdateHdrIcons(exitCode, statusFlags, keyIdObj.value, userIdObj.value, sigDetailsObj.value, errorMsg, null);
836
var noSecondTry = nsIEnigmail.GOOD_SIGNATURE |
837
nsIEnigmail.EXPIRED_SIGNATURE |
838
nsIEnigmail.EXPIRED_KEY_SIGNATURE |
839
nsIEnigmail.EXPIRED_KEY |
840
nsIEnigmail.REVOKED_KEY |
841
nsIEnigmail.NO_PUBKEY |
842
nsIEnigmail.NO_SECKEY |
843
nsIEnigmail.IMPORTED_KEY |
844
nsIEnigmail.MISSING_PASSPHRASE |
845
nsIEnigmail.BAD_PASSPHRASE |
846
nsIEnigmail.UNKNOWN_ALGO |
847
nsIEnigmail.DECRYPTION_OKAY |
848
nsIEnigmail.OVERFLOWED;
850
if ((exitCode !=0) && (! (statusFlags & noSecondTry))) {
851
// Bad signature/armor
853
msgText = EnigConvertFromUnicode(msgText, "UTF-8");
854
enigMessageParseCallback(msgText, contentEncoding, charset, interactive,
855
importOnly, messageUrl, signature, retry + 1,
859
else if (retry == 2) {
860
// Try to verify signature by accessing raw message text directly
861
// (avoid recursion by setting retry parameter to false on callback)
863
enigMsgDirect(interactive, importOnly, contentEncoding, charset, newSignature, 0, head, tail, enigMessageParseCallback);
866
else if (retry == 3) {
867
msgText = EnigConvertToUnicode(msgText, "UTF-8");
868
enigMessageParseCallback(msgText, contentEncoding, charset, interactive,
869
importOnly, messageUrl, null, retry + 1,
876
if (interactive && gEnigSecurityInfo && gEnigSecurityInfo.statusInfo)
877
EnigLongAlert(gEnigSecurityInfo.statusInfo);
882
plainText = EnigConvertFromUnicode(EnigConvertToUnicode(plainText, "UTF-8"), charset);
885
if (blockSeparationObj.value.indexOf(" ")>=0) {
886
var blocks = blockSeparationObj.value.split(/ /);
887
var blockInfo = blocks[0].split(/:/);
888
plainText = EnigGetString("notePartEncrypted") + "\n\n" + plainText.substr(0, blockInfo[1]) + "\n\n" + EnigGetString("noteCutMessage");
891
// Save decrypted message status, headers, and content
892
var headerList = {"subject":"", "from":"", "date":"", "to":"", "cc":""};
894
var index, headerName;
896
if (!gViewAllHeaders) {
897
for (index = 0; index < headerList.length; index++) {
898
headerList[index] = "";
902
for (index = 0; index < gExpandedHeaderList.length; index++) {
903
headerList[gExpandedHeaderList[index].name] = "";
906
for (headerName in currentHeaderData) {
907
headerList[headerName] = "";
911
for (headerName in headerList) {
912
if (currentHeaderData[headerName])
913
headerList[headerName] = currentHeaderData[headerName].headerValue;
917
if (headerList["cc"] == headerList["to"])
918
headerList["cc"] = "";
920
var hasAttachments = currentAttachments && currentAttachments.length;
921
var attachmentsEncrypted=true;
923
for (index in currentAttachments) {
924
if (! enigCheckEncryptedAttach(currentAttachments[index])) {
925
if (!enigCheckSignedAttachment(currentAttachments, index)) attachmentsEncrypted=false;
929
var msgRfc822Text = "";
932
// print a warning if the signed or encrypted part doesn't start
933
// quite early in the message
934
matches=head.match(/(\n)/g);
935
if (matches && matches.length >10) {
936
msgRfc822Text=EnigGetString("notePartEncrypted")+"\n\n";
938
msgRfc822Text+=head+"\n\n";
940
msgRfc822Text += EnigGetString("beginPgpPart")+"\n\n";
942
msgRfc822Text+=plainText;
944
msgRfc822Text+="\n\n"+EnigGetString("endPgpPart")+"\n\n"+tail;
947
gEnigDecryptedMessage = {url:messageUrl,
948
headerList:headerList,
949
hasAttachments:hasAttachments,
950
attachmentsEncrypted:attachmentsEncrypted,
952
plainText:msgRfc822Text};
954
var msgFrame = EnigGetFrame(window, "messagepane");
955
var bodyElement = msgFrame.document.getElementsByTagName("body")[0];
958
// Create and load one-time message URI
959
var messageContent = enigGetDecryptedMessage("message/rfc822", false);
961
gEnigNoShowReload = true;
963
var uri = enigmailSvc.createMessageURI(messageUrl,
968
gEnigCreatedURIs.push(uri);
970
//msgFrame.location=uri;
971
messenger.loadURL(msgFrame, uri);
974
// Display plain text with hyperlinks
976
// Get selection range for inserting HTML
977
var domSelection = msgFrame._content.getSelection();
979
var privateSelection = domSelection.QueryInterface(Components.interfaces.nsISelectionPrivate);
980
var selection = privateSelection.QueryInterface(Components.interfaces.nsISelection);
982
selection.collapse(bodyElement, 0);
983
var selRange = selection.getRangeAt(0);
985
// Decode plaintext to unicode
986
tail = EnigConvertToUnicode(tail, charset);
987
var uniText = EnigConvertToUnicode(plainText, charset);
991
htmlText += "<pre>"+enigEscapeTextForHTML(EnigConvertToUnicode(head, charset),true)+"</pre><p/>\n";
993
htmlText += '<table border="0" cellspacing="0" width="100%"><tbody><tr><td bgcolor="#9490FF" width="10"></td>' +
994
'<td bgcolor="#9490FF" width="10"><pre>Begin Signed or Encrypted Text</pre></td></tr>\n'+
995
'<tr><td bgcolor="#9490FF"></td>'+
997
enigEscapeTextForHTML(uniText, true) +
998
'</pre></td></tr>\n' +
999
'<tr><td bgcolor="#9490FF" width="10"></td>' +
1000
'<td bgcolor="#9490FF" width="10"><pre>End Signed or Encrypted Text</pre></td></tr>' +
1001
'</tbody></table>\n'
1004
htmlText += "<p/><pre>"+enigEscapeTextForHTML(EnigConvertToUnicode(tail, charset),true)+"</pre>";
1007
var docFrag = selRange.createContextualFragment(htmlText);
1010
while (bodyElement.hasChildNodes())
1011
bodyElement.removeChild(bodyElement.childNodes[0]);
1013
if (hasAttachments && (! attachmentsEncrypted)) {
1014
var newTextNode = msgFrame.document.createTextNode(EnigGetString("enigNote"));
1016
var newEmElement = msgFrame.document.createElement("em");
1017
newEmElement.appendChild(newTextNode);
1019
bodyElement.appendChild(newEmElement);
1020
bodyElement.appendChild(msgFrame.document.createElement("p"));
1023
bodyElement.appendChild(docFrag.firstChild);
1030
// check if an attachment could be signed
1031
function enigCheckSignedAttachment(currentAttachments, index) {
1033
// check if filename ends with .sig
1034
if (currentAttachments[index].displayName.search(/\.sig$/i) > 0) return true;
1037
var findFile = currentAttachments[index].displayName.toLowerCase()+".sig";
1039
for (i in currentAttachments) {
1040
if (currentAttachments[i].displayName.toLowerCase() == findFile) signed=true;
1045
// check if the attachment could be encrypted
1046
function enigCheckEncryptedAttach(attachment) {
1047
return (attachment.displayName.match(/\.(gpg|pgp|asc)$/i) ||
1048
attachment.contentType.match(/^application\/pgp(\-.*)?$/i));
1051
function enigEscapeTextForHTML(text, hyperlink) {
1052
// Escape special characters
1053
if (text.indexOf("&") > -1)
1054
text = text.replace(/&/g, "&")
1056
if (text.indexOf("<") > -1)
1057
text = text.replace(/</g, "<")
1059
if (text.indexOf(">") > -1)
1060
text = text.replace(/>/g, ">")
1062
if (text.indexOf("\"") > -1)
1063
text = text.replace(/"/g, """)
1068
// Hyperlink email addresses
1069
var addrs = text.match(/\b[A-Za-z0-9_+\-\.]+@[A-Za-z0-9\-\.]+\b/g);
1071
var newText, offset, loc;
1072
if (addrs && addrs.length) {
1076
for (var j=0; j < addrs.length; j++) {
1077
var addr = addrs[j];
1079
loc = text.indexOf(addr, offset);
1084
newText += text.substr(offset, loc-offset);
1086
// Strip any period off the end of address
1087
addr = addr.replace(/[\.]$/, "");
1092
newText += "<a href=\"mailto:"+addr+"\">" + addr + "</a>";
1094
offset = loc + addr.length;
1097
newText += text.substr(offset, text.length-offset);
1103
var urls = text.match(/\b(http|https|ftp):\S+\s/g);
1105
if (urls && urls.length) {
1109
for (var k=0; k < urls.length; k++) {
1112
loc = text.indexOf(url, offset);
1117
newText += text.substr(offset, loc-offset);
1119
// Strip delimiters off the end of URL
1120
url = url.replace(/\s$/, "");
1121
url = url.replace(/([\),\.']|>|")$/, "");
1126
newText += "<a href=\""+url+"\">" + url + "</a>";
1128
offset = loc + url.length;
1131
newText += text.substr(offset, text.length-offset);
1139
function enigGetDecryptedMessage(contentType, includeHeaders) {
1140
DEBUG_LOG("enigmailMessengerOverlay.js: enigGetDecryptedMessage: "+contentType+", "+includeHeaders+"\n");
1142
if (!gEnigDecryptedMessage)
1143
return "No decrypted message found!\n";
1145
var enigmailSvc = GetEnigmailSvc();
1149
var headerList = gEnigDecryptedMessage.headerList;
1151
var statusLine = gEnigSecurityInfo ? gEnigSecurityInfo.statusLine : "";
1153
var contentData = "";
1157
if (contentType == "message/rfc822") {
1160
if (includeHeaders) {
1163
var msg = gFolderDisplay.selectedMessage;
1165
msgHdr = { "From": msg.author,
1166
"Subject": msg.subject,
1167
"To": msg.recipients,
1169
"Date": EnigGetDateTime(msg.dateInSeconds, true, true) };
1172
if(gFolderDisplay.selectedMessageIsNews) {
1173
if (typeof (currentHeaderData.newsgroups)) {
1174
msgHdr.Newsgroups = currentHeaderData.newsgroups.headerValue;
1178
for (headerName in msgHdr) {
1179
if (msgHdr[headerName] && msgHdr[headerName].length>0)
1180
contentData += headerName + ": " + msgHdr[headerName] + "\r\n";
1185
// the above seems to fail every now and then
1186
// so, here is the fallback
1187
for (headerName in headerList) {
1188
headerValue = headerList[headerName];
1189
contentData += headerName + ": " + headerValue + "\r\n";
1194
contentData += "Content-Type: text/plain";
1196
if (gEnigDecryptedMessage.charset) {
1197
contentData += "; charset="+gEnigDecryptedMessage.charset;
1200
contentData += "\r\n\r\n";
1202
if (gEnigDecryptedMessage.hasAttachments && (! gEnigDecryptedMessage.attachmentsEncrypted)) {
1203
contentData += EnigGetString("enigContentNote");
1206
contentData += gEnigDecryptedMessage.plainText;
1209
// text/html or text/plain
1211
if (contentType == "text/html") {
1212
contentData += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset="+gEnigDecryptedMessage.charset+"\">\r\n";
1214
contentData += "<html><head></head><body>\r\n";
1218
if (contentType == "text/html") {
1219
contentData += "<b>"+EnigGetString("enigHeader")+"</b> " +
1220
enigEscapeTextForHTML(statusLine, false) + "<br>\r\n<hr>\r\n";
1222
contentData += EnigGetString("enigHeader")+" " + statusLine + "\r\n\r\n";
1226
if (includeHeaders) {
1227
for (headerName in headerList) {
1228
headerValue = headerList[headerName];
1231
if (contentType == "text/html") {
1232
contentData += "<b>"+enigEscapeTextForHTML(headerName, false)+":</b> "+
1233
enigEscapeTextForHTML(headerValue, false)+"<br>\r\n";
1235
contentData += headerName + ": " + headerValue + "\r\n";
1241
if (contentType == "text/html") {
1242
contentData += "<pre>"+enigEscapeTextForHTML(gEnigDecryptedMessage.plainText, false)+"</pre>\r\n";
1244
contentData += "</body></html>\r\n";
1248
contentData += "\r\n"+gEnigDecryptedMessage.plainText;
1251
if (!(enigmailSvc.isDosLike)) {
1252
contentData = contentData.replace(/\r\n/g, "\n");
1260
function enigMsgDefaultPrint(elementId) {
1261
DEBUG_LOG("enigmailMessengerOverlay.js: enigMsgDefaultPrint: "+elementId+"\n");
1263
goDoCommand(elementId.indexOf("printpreview")>=0 ? "cmd_printpreview" : "cmd_print");
1266
function enigMsgPrint(elementId) {
1267
DEBUG_LOG("enigmailMessengerOverlay.js: enigMsgPrint: "+elementId+"\n");
1269
var contextMenu = (elementId.search("Context") > -1);
1271
if (!gEnigDecryptedMessage || typeof(gEnigDecryptedMessage) == "undefined") {
1272
enigMsgDefaultPrint(elementId);
1276
var mailNewsUrl = enigGetCurrentMsgUrl();
1279
enigMsgDefaultPrint(elementId);
1283
if (gEnigDecryptedMessage.url != mailNewsUrl.spec) {
1284
gEnigDecryptedMessage = null;
1285
enigMsgDefaultPrint(elementId);
1289
var enigmailSvc = GetEnigmailSvc();
1291
enigMsgDefaultPrint(elementId);
1295
// Note: Trying to print text/html content does not seem to work with
1297
var msgContent = enigGetDecryptedMessage("message/rfc822", true);
1299
var uri = enigmailSvc.createMessageURI(gEnigDecryptedMessage.url,
1305
gEnigCreatedURIs.push(uri);
1307
DEBUG_LOG("enigmailMessengerOverlay.js: enigMsgPrint: uri="+uri+"\n");
1309
var messageList = [uri];
1311
var printPreview = (elementId.indexOf("printpreview")>=0);
1313
window.openDialog("chrome://messenger/content/msgPrintEngine.xul",
1315
"chrome,dialog=no,all,centerscreen",
1316
1, messageList, statusFeedback,
1317
printPreview, Components.interfaces.nsIMsgPrintEngine.MNAB_PRINTPREVIEW_MSG,
1324
function enigMessageSave() {
1325
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageSave: \n");
1327
if (!gEnigDecryptedMessage) {
1328
EnigAlert(EnigGetString("noDecrypted"));
1332
var mailNewsUrl = enigGetCurrentMsgUrl();
1335
EnigAlert(EnigGetString("noMessage"));
1339
if (gEnigDecryptedMessage.url != mailNewsUrl.spec) {
1340
gEnigDecryptedMessage = null;
1341
EnigAlert(EnigGetString("useButton"));
1345
var saveFile = EnigFilePicker(EnigGetString("saveHeader"),
1346
gEnigLastSaveDir, true, "txt",
1347
null, ["Text files", "*.txt"]);
1348
if (!saveFile) return;
1350
DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageSave: path="+saveFile.path+"\n");
1352
if (saveFile.parent)
1353
gEnigLastSaveDir = EnigGetFilePath(saveFile.parent);
1355
var textContent = enigGetDecryptedMessage("text/plain", true);
1357
// EnigAlert(textContent);
1359
if (!EnigWriteFileContents(saveFile.path, textContent, null)) {
1360
EnigAlert("Error in saving to file "+saveFile.path);
1367
function enigMsgDirect(interactive, importOnly, contentEncoding, charset, signature, bufferSize, head, tail, callbackFunction) {
1368
WRITE_LOG("enigmailMessengerOverlay.js: enigMsgDirect: contentEncoding="+contentEncoding+", signature="+signature+"\n");
1369
var mailNewsUrl = enigGetCurrentMsgUrl();
1373
var ipcBuffer = Components.classes[ENIG_IPCBUFFER_CONTRACTID].createInstance(Components.interfaces.nsIIPCBuffer);
1374
var mimeListener = Components.classes[ENIG_ENIGMIMELISTENER_CONTRACTID].createInstance(Components.interfaces.nsIEnigMimeListener);
1376
if (bufferSize > 0) {
1377
ipcBuffer.open(bufferSize, false);
1380
ipcBuffer.open(ENIG_MSG_BUFFER_SIZE, false);
1383
var callbackArg = { interactive:interactive,
1384
importOnly:importOnly,
1385
contentEncoding:contentEncoding,
1387
messageUrl:mailNewsUrl.spec,
1388
signature:signature,
1389
ipcBuffer:ipcBuffer,
1390
expectedBufferSize: bufferSize,
1393
mimeListener: mimeListener,
1394
callbackFunction: callbackFunction };
1396
var requestObserver = new EnigRequestObserver(enigMsgDirectCallback,
1399
ipcBuffer.observe(requestObserver, mailNewsUrl);
1401
var ioServ = Components.classes[ENIG_IOSERVICE_CONTRACTID].getService(Components.interfaces.nsIIOService);
1403
var channel = ioServ.newChannelFromURI(mailNewsUrl);
1405
var pipeFilter = Components.classes[ENIG_PIPEFILTERLISTENER_CONTRACTID].createInstance(Components.interfaces.nsIPipeFilterListener);
1406
pipeFilter.init(ipcBuffer, null,
1409
0, true, false, null);
1415
mimeListener.init(pipeFilter, null, ENIG_MSG_HEADER_SIZE, true, false, true);
1417
listener = mimeListener;
1420
listener = pipeFilter;
1423
channel.asyncOpen(pipeFilter, mailNewsUrl);
1427
function enigMsgDirectCallback(callbackArg, ctxt) {
1428
DEBUG_LOG("enigmailMessengerOverlay.js: enigMsgDirectCallback: "+ctxt+"\n");
1430
var mailNewsUrl = enigGetCurrentMsgUrl();
1431
var urlSpec = mailNewsUrl ? mailNewsUrl.spec : "";
1432
var newBufferSize = 0;
1434
var l= urlSpec.length;
1436
if (urlSpec.substr(0, l) != callbackArg.messageUrl.substr(0, l)) {
1437
ERROR_LOG("enigmailMessengerOverlay.js: enigMsgDirectCallback: Message URL mismatch "+mailNewsUrl.spec+" vs. "+callbackArg.messageUrl+"\n");
1441
if (callbackArg.ipcBuffer.overflowed) {
1442
WARNING_LOG("enigmailMessengerOverlay.js: enigMsgDirectCallback: MESSAGE BUFFER OVERFLOW\n");
1443
if (! callbackArg.expectedBufferSize) {
1444
// set correct buffer size
1445
newBufferSize=((callbackArg.ipcBuffer.totalBytes+1500)/1024).toFixed(0)*1024;
1449
var msgText = callbackArg.ipcBuffer.getData();
1450
msgText = EnigConvertFromUnicode(msgText, "UTF-8");
1452
callbackArg.ipcBuffer.shutdown();
1454
if (newBufferSize > 0) {
1455
// retry with correct buffer size
1456
enigMsgDirect(callbackArg.interactive,
1457
callbackArg.importOnly,
1458
callbackArg.contentEncoding,
1459
callbackArg.charset,
1460
callbackArg.signature,
1464
callbackArg.callbackFunction);
1467
DEBUG_LOG("enigmailMessengerOverlay.js: enigMsgDirectCallback: msgText='"+msgText+"'\n");
1469
callbackArg.callbackFunction(msgText, callbackArg.contentEncoding,
1470
callbackArg.charset,
1471
callbackArg.interactive,
1472
callbackArg.importOnly,
1473
callbackArg.messageUrl,
1474
callbackArg.signature,
1481
function enigVerifyEmbeddedMsg(window, msgUrl, msgWindow, msgUriSpec, contentEncoding, event) {
1482
DEBUG_LOG("enigmailMessengerOverlay.js: enigVerifyEmbedded: msgUrl"+msgUrl+"\n");
1484
var ipcBuffer = Components.classes[ENIG_IPCBUFFER_CONTRACTID].createInstance(Components.interfaces.nsIIPCBuffer);
1485
ipcBuffer.open(ENIG_UNLIMITED_BUFFER_SIZE, false);
1487
var callbackArg = { ipcBuffer: ipcBuffer,
1490
msgWindow: msgWindow,
1491
msgUriSpec: msgUriSpec,
1492
contentEncoding: contentEncoding,
1495
var requestObserver = new EnigRequestObserver(enigVerifyEmbeddedCallback,
1498
ipcBuffer.observe(requestObserver, msgUrl);
1500
var ioServ = Components.classes[ENIG_IOSERVICE_CONTRACTID].getService(Components.interfaces.nsIIOService);
1502
var channel = ioServ.newChannelFromURI(msgUrl);
1504
var pipeFilter = Components.classes[ENIG_PIPEFILTERLISTENER_CONTRACTID].createInstance(Components.interfaces.nsIPipeFilterListener);
1506
pipeFilter.init(ipcBuffer, null,
1509
0, false, false, null);
1511
channel.asyncOpen(pipeFilter, msgUrl);
1514
function enigVerifyEmbeddedCallback(callbackArg, ctxt) {
1515
DEBUG_LOG("enigmailMessengerOverlay.js: enigVerifyEmbeddedCallback: "+ctxt+"\n");
1517
var txt = callbackArg.ipcBuffer.getData();
1518
callbackArg.ipcBuffer.shutdown();
1520
if (txt.length > 0) {
1521
msigned=txt.search(/content\-type:[ \t]*multipart\/signed/i);
1523
// Real multipart/signed message; let's try to verify it
1524
DEBUG_LOG("enigmailMessengerOverlay.js: enigVerifyEmbeddedCallback: detected multipart/signed\n");
1526
callbackArg.enableSubpartTreatment=(msigned > 0);
1528
var uri = Components.classes[ENIG_SIMPLEURI_CONTRACTID].createInstance(Components.interfaces.nsIURI);
1529
uri.spec = "enigmail:dummy";
1531
var ipcService = Components.classes[ENIG_IPCSERVICE_CONTRACTID].getService(Components.interfaces.nsIIPCService);
1532
var channel = ipcService.newStringChannel(uri, "", "", txt);
1533
var verifier = Components.classes[ENIG_ENIGMIMEVERIFY_CONTRACTID].createInstance(Components.interfaces.nsIEnigMimeVerify);
1535
verifier.initWithChannel(callbackArg.window, channel, callbackArg.msgWindow, callbackArg.msgUriSpec,
1536
true, callbackArg.enableSubpartTreatment);
1542
DEBUG_LOG("enigmailMessengerOverlay.js: enigVerifyEmbeddedCallback: try inline PGP\n");
1544
enigMessageParse(!callbackArg.event, false, callbackArg.contentEncoding);
1548
function enigKeyRequest(interactive, keyId, urlSpec) {
1549
DEBUG_LOG("enigmailMessengerOverlay.js: enigKeyRequest: keyId="+keyId+", urlSpec="+urlSpec+"\n");
1551
var ipcBuffer = Components.classes[ENIG_IPCBUFFER_CONTRACTID].createInstance(Components.interfaces.nsIIPCBuffer);
1553
ipcBuffer.open(ENIG_KEY_BUFFER_SIZE, false);
1555
var ioServ = Components.classes[ENIG_IOSERVICE_CONTRACTID].getService(Components.interfaces.nsIIOService);
1558
var uri = ioServ.newURI(urlSpec, "", null);
1560
var channel = ioServ.newChannelFromURI(uri);
1562
var httpChannel = channel.QueryInterface(Components.interfaces.nsIHttpChannel);
1564
// Disable HTTP redirection
1565
httpChannel.redirectionLimit = 0;
1567
var callbackArg = { interactive:interactive,
1570
httpChannel:httpChannel,
1571
ipcBuffer:ipcBuffer };
1573
var requestObserver = new EnigRequestObserver(enigKeyRequestCallback,
1576
ipcBuffer.observe(requestObserver, null);
1578
DEBUG_LOG("enigmailMessengerOverlay.js: enigKeyRequest: httpChannel="+httpChannel+", asyncOpen ...\n");
1580
httpChannel.asyncOpen(ipcBuffer, null);
1583
ERROR_LOG("enigmailMessengerOverlay.js: enigKeyRequest: Error - failed to create channel\n");
1589
function enigKeyRequestCallback(callbackArg, ctxt) {
1590
var urlSpec = callbackArg.urlSpec;
1591
var httpChannel = callbackArg.httpChannel;
1593
DEBUG_LOG("enigmailMessengerOverlay.js: enigKeyRequestCallback: urlSpec="+urlSpec+"\n");
1595
if (callbackArg.ipcBuffer.overflowed) {
1596
WARNING_LOG("enigmailMessengerOverlay.js: enigKeyRequestCallback: KEY BUFFER OVERFLOW\n");
1599
var eTag = httpChannel.getResponseHeader("ETag");
1601
var keyText = callbackArg.ipcBuffer.getData();
1603
callbackArg.ipcBuffer.shutdown();
1605
DEBUG_LOG("enigmailMessengerOverlay.js: enigKeyRequestCallback: keyText='"+keyText+"'\n");
1607
DEBUG_LOG("enigmailMessengerOverlay.js: enigKeyRequestCallback: NoCache='"+httpChannel.isNoCacheResponse()+"'\n");
1609
DEBUG_LOG("enigmailMessengerOverlay.js: enigKeyRequestCallback: ETag: "+eTag+"\n");
1611
// NEED TO EXTRACT KEY ETC.
1615
// handle a selected attachment (decrypt & open or save)
1616
function enigHandleAttachmentSel(actionType) {
1617
DEBUG_LOG("enigmailMessengerOverlay.js: enigHandleAttachmentSel: actionType="+actionType+"\n");
1619
var attachmentList = document.getElementById('attachmentList');
1620
var selectedAttachments = attachmentList.selectedItems;
1621
var anAttachment = selectedAttachments[0].attachment;
1623
switch (actionType) {
1624
case "saveAttachment":
1625
case "openAttachment":
1627
enigHandleAttachment(actionType, anAttachment);
1632
function enigHandleAttachment(actionType, anAttachment) {
1633
DEBUG_LOG("enigmailMessengerOverlay.js: enigHandleAttachment: actionType="+actionType+", anAttachment(url)="+anAttachment.url+"\n");
1635
var ipcBuffer = Components.classes[ENIG_IPCBUFFER_CONTRACTID].createInstance(Components.interfaces.nsIIPCBuffer);
1637
var argumentsObj = { actionType: actionType,
1638
attachment: anAttachment,
1639
forceBrowser: false,
1640
ipcBuffer: ipcBuffer
1643
var requestObserver = new EnigRequestObserver(enigDecryptAttachmentCallback,
1646
var ioServ = Components.classes[ENIG_IOSERVICE_CONTRACTID].getService(Components.interfaces.nsIIOService);
1648
ipcBuffer.open(ENIG_UNLIMITED_BUFFER_SIZE, false);
1649
var msgUri = ioServ.newURI(argumentsObj.attachment.url, null, null);
1651
ipcBuffer.observe(requestObserver, msgUri);
1653
var channel = ioServ.newChannelFromURI(msgUri);
1655
var pipeFilter = Components.classes[ENIG_PIPEFILTERLISTENER_CONTRACTID].createInstance(Components.interfaces.nsIPipeFilterListener);
1657
pipeFilter.init(ipcBuffer, null,
1660
0, false, false, null);
1663
listener = pipeFilter;
1665
channel.asyncOpen(listener, msgUri);
1669
function enigDecryptAttachmentCallback(callbackArg, ctxt) {
1670
DEBUG_LOG("enigmailMessengerOverlay.js: enigDecryptAttachmentCallback: "+ctxt+"\n");
1672
if (callbackArg.ipcBuffer.overflowed) {
1673
WARNING_LOG("enigmailMessengerOverlay.js: enigDecryptAttachmentCallback: MESSAGE BUFFER OVERFLOW\n");
1676
var exitCodeObj = new Object();
1677
var statusFlagsObj = new Object();
1678
var errorMsgObj= new Object();
1679
var exitStatus = -1;
1681
var enigmailSvc = GetEnigmailSvc();
1683
var rawFileName=callbackArg.attachment.displayName.replace(/\.(asc|pgp|gpg)$/i,"");
1685
if (callbackArg.actionType == "saveAttachment") {
1686
outFile = EnigFilePicker(EnigGetString("saveAttachmentHeader"),
1687
gEnigLastSaveDir, true, "",
1689
if (! outFile) return;
1693
var tmpDir = EnigGetTempDir();
1695
outFile = Components.classes[ENIG_LOCAL_FILE_CONTRACTID].createInstance(Components.interfaces.nsILocalFile);
1696
outFile.initWithPath(tmpDir);
1697
if (!(outFile.isDirectory() && outFile.isWritable())) {
1698
errorMsgObj.value=EnigGetString("noTempDir");
1701
outFile.append(rawFileName);
1702
outFile.createUnique(Components.interfaces.NORMAL_FILE_TYPE, 0600);
1705
errorMsgObj.value=EnigGetString("noTempDir");
1710
if (callbackArg.actionType == "importKey") {
1712
var dataLength = new Object();
1713
var byteData = callbackArg.ipcBuffer.getByteData(dataLength);
1714
exitStatus = enigmailSvc.importKey(parent, 0, byteData, "", errorMsgObj);
1717
if (exitStatus == 0) {
1718
EnigLongAlert(EnigGetString("successKeyImport")+"\n\n"+errorMsgObj.value);
1721
EnigAlert(EnigGetString("failKeyImport")+"\n"+errorMsgObj.value);
1727
exitStatus=enigmailSvc.decryptAttachment(window, outFile,
1728
callbackArg.attachment.displayName,
1729
callbackArg.ipcBuffer,
1730
exitCodeObj, statusFlagsObj,
1733
callbackArg.ipcBuffer.shutdown();
1734
if ((! exitStatus) || exitCodeObj.value != 0) {
1736
if (statusFlagsObj.value &
1737
(nsIEnigmail.DECRYPTION_OKAY | nsIEnigmail.UNVERIFIED_SIGNATURE)) {
1738
if (callbackArg.actionType == "openAttachment") {
1739
exitStatus = EnigConfirm(EnigGetString("decryptOkNoSig"), EnigGetString("msgOvl.button.contAnyway"));
1742
EnigAlert(EnigGetString("decryptOkNoSig"));
1746
EnigAlert(EnigGetString("failedDecrypt")+"\n\n"+errorMsgObj.value);
1751
if (statusFlagsObj.value & nsIEnigmail.IMPORTED_KEY) {
1752
EnigLongAlert(EnigGetString("successKeyImport")+"\n\n"+errorMsgObj.value);
1754
else if (statusFlagsObj.value & nsIEnigmail.DISPLAY_MESSAGE) {
1755
HandleSelectedAttachments('open');
1757
else if ((statusFlagsObj.value & nsIEnigmail.DISPLAY_MESSAGE) ||
1758
(callbackArg.actionType == "openAttachment")) {
1759
var ioServ = Components.classes[ENIG_IOSERVICE_CONTRACTID].getService(Components.interfaces.nsIIOService);
1760
var outFileUri = ioServ.newFileURI(outFile);
1761
var fileExt = outFile.leafName.replace(/(.*\.)(\w+)$/, "$2")
1762
if (fileExt && ! callbackArg.forceBrowser) {
1763
var extAppLauncher = Components.classes[ENIG_MIME_CONTRACTID].getService(Components.interfaces.nsPIExternalAppLauncher);
1764
extAppLauncher.deleteTemporaryFileOnExit(outFile);
1767
var mimeService = Components.classes[ENIG_MIME_CONTRACTID].getService(Components.interfaces.nsIMIMEService);
1768
var fileMimeType = mimeService.getTypeFromFile(outFile);
1769
var fileMimeInfo = mimeService.getFromTypeAndExtension(fileMimeType, fileExt);
1771
fileMimeInfo.launchWithFile(outFile);
1774
// if the attachment file type is unknown, an exception is thrown,
1775
// so let it be handled by a browser window
1776
enigLoadExternalURL(outFileUri.asciiSpec);
1780
// open the attachment using an external application
1781
enigLoadExternalURL(outFileUri.asciiSpec);
1786
function enigLoadExternalURL(url) {
1787
if (gEnigDecryptButton && gEnigDecryptButton.getAttribute("buttontype")=="seamonkey") {
1788
EnigLoadURLInNavigatorWindow(url, true);
1791
messenger.launchExternalURL(url);
1796
// handle double click events on Attachments
1797
function enigAttachmentListClick (elementId, event) {
1798
DEBUG_LOG("enigmailMessengerOverlay.js: enigAttachmentListClick: event="+event+"\n");
1800
var attachment=event.target.attachment;
1801
if (enigCheckEncryptedAttach(attachment)) {
1802
if (event.button != 0) return;
1804
if (event.detail == 2) // double click
1805
enigHandleAttachment("openAttachment", attachment);
1808
attachmentListClick(event);
1813
function enigHandleUnknownKey() {
1814
var pubKeyId = "0x" + gEnigSecurityInfo.keyId.substr(8, 8);
1816
var mesg = EnigGetString("pubKeyNeeded") + EnigGetString("keyImport",pubKeyId);
1818
if (EnigConfirm(mesg, EnigGetString("keyMan.button.import"))) {
1820
searchList : [ pubKeyId ]
1822
var resultObj = new Object();
1824
EnigDownloadKeys(inputObj, resultObj);
1826
if (resultObj.importedKeys > 0) {
1827
enigMessageReload(false);
1832
function enigReceiveKeyCancel(progressBar) {
1833
DEBUG_LOG("enigmailMessengerOverlay.js: enigReceiveKeyCancel\n");
1835
var keyRetrProcess = gEnigIpcRequest.pipeTransport;
1837
if (keyRetrProcess && !keyRetrProcess.isAttached()) {
1838
keyRetrProcess.terminate();
1840
gEnigIpcRequest.close(true);
1842
EnigAlert(EnigGetString("keyImportError")+ EnigGetString("failCancel"));