~ubuntu-branches/ubuntu/oneiric/enigmail/oneiric-updates

« back to all changes in this revision

Viewing changes to extensions/enigmail/ui/content/enigmailMessengerOverlay.js

  • Committer: Bazaar Package Importer
  • Author(s): Alexander Sack
  • Date: 2010-04-10 01:42:24 UTC
  • Revision ID: james.westby@ubuntu.com-20100410014224-fbq9ui5x3b0h2t36
Tags: 2:1.0.1-0ubuntu1
* First releaase of enigmail 1.0.1 for tbird/icedove 3
  (LP: #527138)
* redo packaging from scratch 
  + add debian/make-orig target that uses xulrunner provided
    buildsystem + enigmail tarball to produce a proper orig.tar.gz
  + use debhelper 7 with mozilla-devscripts
  + use debian source format 3.0 (quilt)
  + patch enigmail to use frozen API only
    - add debian/patches/frozen_api.diff
  + patch build system to not link against -lxul - which isnt
    available for sdks produced by all-static apps like tbird
    - add debian/patches/build_system_dont_link_libxul.diff
  + add minimal build-depends to control

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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/
 
6
 
 
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.
 
11
 
 
12
The Original Code is Enigmail.
 
13
 
 
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.
 
17
 
 
18
Contributor(s):
 
19
Patrick Brunschwig <patrick.brunschwig@gmx.net>
 
20
 
 
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
 
31
GPL.
 
32
*/
 
33
 
 
34
// Uses: chrome://enigmail/content/enigmailCommon.js
 
35
 
 
36
// Initialize enigmailCommon
 
37
 
 
38
EnigInitCommon("enigmailMessengerOverlay");
 
39
Components.utils.import("resource://app/modules/gloda/mimemsg.js");
 
40
 
 
41
var gEnigCreatedURIs = [];
 
42
 
 
43
var gEnigDecryptedMessage;
 
44
var gEnigSecurityInfo = null;
 
45
var gEnigLastSaveDir = "";
 
46
 
 
47
var gEnigMessagePane = null;
 
48
var gEnigNoShowReload = false;
 
49
var gEnigLastEncryptedMsgKey = null;
 
50
var gEnigDecryptButton = null;
 
51
var gEnigIpcRequest = null;
 
52
 
 
53
var gEnigRemoveListener = false;
 
54
 
 
55
var gEnigHeadersList = ["content-type", "content-transfer-encoding",
 
56
                        "x-enigmail-version"];
 
57
var gEnigSavedHeaders = null;
 
58
 
 
59
var gShowHeadersObj = {"viewallheaders":2,
 
60
                       "viewnormalheaders":1,
 
61
                       "viewbriefheaders":0};
 
62
 
 
63
window.addEventListener("load",   enigMessengerStartup, false);
 
64
window.addEventListener("unload", enigMessengerFinish,  false);
 
65
 
 
66
var gEnigTreeController = {
 
67
  supportsCommand: function(command) {
 
68
    // DEBUG_LOG("enigmailMessengerOverlay.js: treeCtrl: supportsCommand: "+command+"\n");
 
69
    switch(command) {
 
70
    case "button_enigmail_decrypt":
 
71
      return true;
 
72
    }
 
73
    return false;
 
74
  },
 
75
  isCommandEnabled: function(command) {
 
76
    // DEBUG_LOG("enigmailMessengerOverlay.js: treeCtrl: isCommandEnabled: "+command+"\n");
 
77
    try {
 
78
      if (gFolderDisplay.messageDisplay.visible) {
 
79
        if (gFolderDisplay.selectedCount != 1) enigStatusBarHide();
 
80
        return (gFolderDisplay.selectedCount == 1);
 
81
      }
 
82
      enigStatusBarHide();
 
83
    }
 
84
    catch (ex) {}
 
85
    return  false;
 
86
  },
 
87
  doCommand: function(command) {
 
88
    //DEBUG_LOG("enigmailMessengerOverlay.js: treeCtrl: doCommand: "+command+"\n");
 
89
    // nothing
 
90
  },
 
91
  onEvent: function(event) {
 
92
    // DEBUG_LOG("enigmailMessengerOverlay.js: treeCtrl: onEvent: "+command+"\n");
 
93
    // nothing
 
94
  }
 
95
}
 
96
 
 
97
function enigMessengerStartup() {
 
98
  DEBUG_LOG("enigmailMessengerOverlay.js: Startup\n");
 
99
 
 
100
  gEnigMessagePane = document.getElementById("messagepane");
 
101
 
 
102
  if (gEnigMessagePane == null) return; // TB 2.0 on Mac OS X calls this twice -- once far too early
 
103
 
 
104
  // enigUpdateOptionsDisplay();
 
105
 
 
106
  // Override SMIME ui
 
107
  var viewSecurityCmd = document.getElementById("cmd_viewSecurityStatus");
 
108
  if (viewSecurityCmd) {
 
109
    viewSecurityCmd.setAttribute("oncommand", "enigViewSecurityInfo(null, true);");
 
110
  }
 
111
 
 
112
  // Override print command
 
113
  var printElementIds = ["cmd_print", "cmd_printpreview", "key_print", "button-print",
 
114
                         "mailContext-print", "mailContext-printpreview"];
 
115
 
 
116
  EnigOverrideAttribute( printElementIds, "oncommand",
 
117
                         "enigMsgPrint('", "');");
 
118
 
 
119
  enigOverrideLayoutChange();
 
120
 
 
121
  gEnigSavedHeaders = null;
 
122
 
 
123
  gEnigDecryptButton = document.getElementById("button-enigmail-decrypt");
 
124
 
 
125
  var toolbarElem = document.getElementById("mail-bar2");
 
126
  if (toolbarElem && EnigGetOS() == "Darwin") {
 
127
    toolbarElem.setAttribute("platform", "macos");
 
128
  }
 
129
 
 
130
  enigMessageFrameLoad();
 
131
 
 
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);
 
136
 
 
137
  if (EnigGetPref("handleDoubleClick")) {
 
138
    // ovveride function for double clicking an attachment
 
139
    EnigOverrideAttribute(["attachmentList"], "onclick",
 
140
                        "enigAttachmentListClick('", "', event);");
 
141
  }
 
142
 
 
143
  top.controllers.appendController(gEnigTreeController);
 
144
}
 
145
 
 
146
function enigMessengerFinish() {
 
147
  DEBUG_LOG("enigmailMessengerOverlay.js: Finish\n");
 
148
}
 
149
 
 
150
 
 
151
function enigViewSecurityInfo(event, displaySmimeMsg) {
 
152
  DEBUG_LOG("enigmailMessengerOverlay.js: enigViewSecurityInfo\n");
 
153
 
 
154
  if (event && event.button != 0)
 
155
    return;
 
156
    
 
157
  if (gSignatureStatus >= 0 || gEncryptionStatus >= 0) {
 
158
    showMessageReadSecurityInfo()
 
159
  }
 
160
  else {
 
161
    if (gEnigSecurityInfo) 
 
162
      enigViewOpenpgpInfo()
 
163
    else 
 
164
      showMessageReadSecurityInfo();
 
165
  }
 
166
}
 
167
 
 
168
function enigViewOpenpgpInfo() {
 
169
  if (gEnigSecurityInfo) {
 
170
    EnigLongAlert(EnigGetString("securityInfo")+gEnigSecurityInfo.statusInfo);
 
171
  }
 
172
}
 
173
 
 
174
 
 
175
function enigDisplayMimeMessage() {
 
176
  DEBUG_LOG("enigmailMessengerOverlay.js: enigDisplayMimeMessage\n");
 
177
 
 
178
  var charset = msgWindow ? msgWindow.mailCharacterSet : "";
 
179
  var contentEncoding = "";
 
180
 
 
181
  if ("content-transfer-encoding" in gEnigSavedHeaders) {
 
182
    contentEncoding = gEnigSavedHeaders["content-transfer-encoding"];
 
183
  }
 
184
 
 
185
  enigMsgDirect(true, false, contentEncoding, charset, "", 0, "", "", enigDisplayMimeCallback)
 
186
}
 
187
 
 
188
function enigDisplayMimeCallback(msgText) {
 
189
  DEBUG_LOG("enigmailMessengerOverlay.js: enigDisplayMimeCallback\n");
 
190
 
 
191
  if (!msgText)
 
192
    return;
 
193
 
 
194
  var enigmailSvc = GetEnigmailSvc();
 
195
  if (!enigmailSvc)
 
196
    return;
 
197
 
 
198
  var plainText;
 
199
  var exitCode;
 
200
  var statusFlags = 0;
 
201
 
 
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;
 
211
 
 
212
  plainText = enigmailSvc.decryptMessage(window, uiFlags, msgText,
 
213
                                signatureObj, exitCodeObj, statusFlagsObj,
 
214
                                keyIdObj, userIdObj, sigDetailsObj, errorMsgObj, blockSeparationObj);
 
215
 
 
216
  if (!plainText) {
 
217
     if (interactive && gEnigSecurityInfo && gEnigSecurityInfo.statusInfo)
 
218
       EnigLongAlert(gEnigSecurityInfo.statusInfo);
 
219
     return;
 
220
  }
 
221
 
 
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");
 
226
  }
 
227
  EnigLongAlert(EnigGetString("securityInfo")+gEnigSecurityInfo.statusInfo+"\n---------------------------------\n"+plainText);
 
228
}
 
229
 
 
230
function enigMessageReload(noShowReload) {
 
231
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageReload: "+noShowReload+"\n");
 
232
 
 
233
  gEnigNoShowReload = noShowReload;
 
234
 
 
235
  ReloadMessage();
 
236
}
 
237
 
 
238
function enigmailReloadCompleteMsg() {
 
239
  gDBView.reloadMessageWithAllParts();
 
240
}
 
241
 
 
242
 
 
243
function enigMessageCleanup() {
 
244
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageCleanup\n");
 
245
 
 
246
  var enigmailBox = document.getElementById("enigmailBox");
 
247
 
 
248
  if (enigmailBox && !enigmailBox.collapsed) {
 
249
    enigmailBox.setAttribute("collapsed", "true");
 
250
 
 
251
    var statusText = document.getElementById("expandedEnigmailStatusText");
 
252
 
 
253
    if (statusText)
 
254
      statusText.value="";
 
255
  }
 
256
 
 
257
  if (gEnigCreatedURIs.length) {
 
258
    // Cleanup messages belonging to this window (just in case)
 
259
    var enigmailSvc = GetEnigmailSvc();
 
260
    if (enigmailSvc) {
 
261
      DEBUG_LOG("enigmailMessengerOverlay.js: Cleanup: Deleting messages\n");
 
262
      for (var index=0; index < gEnigCreatedURIs.length; index++) {
 
263
        enigmailSvc.deleteMessageURI(gEnigCreatedURIs[index]);
 
264
      }
 
265
      gEnigCreatedURIs = [];
 
266
    }
 
267
  }
 
268
 
 
269
  gEnigDecryptedMessage = null;
 
270
  gEnigSecurityInfo = null;
 
271
}
 
272
 
 
273
function enigMimeInit() {
 
274
  DEBUG_LOG("enigmailMessengerOverlay.js: *****enigMimeInit\n");
 
275
 
 
276
  try {
 
277
    const ENIG_ENIGCONTENTHANDLER_CID =
 
278
      Components.ID("{847b3a51-7ab1-11d4-8f02-006008948af5}");
 
279
 
 
280
    const ENIG_ENIGENCRYPTEDHANDLER_CONTRACTID = "@mozilla.org/mimecth;1?type=multipart/encrypted";
 
281
 
 
282
    var compMgr = Components.manager.QueryInterface(Components.interfaces.nsIComponentRegistrar);
 
283
 
 
284
    var enigContentHandlerCID = compMgr.contractIDToCID(ENIG_ENIGENCRYPTEDHANDLER_CONTRACTID);
 
285
 
 
286
    var handlePGPMime = (enigContentHandlerCID.toString() ==
 
287
                     ENIG_ENIGCONTENTHANDLER_CID);
 
288
 
 
289
    DEBUG_LOG("enigmailMessengerOverlay.js: *****enigMimeInit: handlePGPMime="+handlePGPMime+"\n");
 
290
 
 
291
  } catch (ex) {}
 
292
 
 
293
  if (gEnigRemoveListener) {
 
294
    gEnigMessagePane.removeEventListener("load", enigMimeInit, true);
 
295
    gEnigRemoveListener = false;
 
296
  }
 
297
 
 
298
  var enigmailSvc = GetEnigmailSvc();
 
299
  if (!enigmailSvc)
 
300
     return;
 
301
 
 
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");
 
307
 
 
308
    enigMessageReload(false);
 
309
 
 
310
  } else {
 
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");
 
314
  }
 
315
}
 
316
 
 
317
function enigMessageFrameLoad() {
 
318
  // called before a message is displayed
 
319
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageFrameLoad\n");
 
320
  // not used anymore (-> gEnigTreeController)
 
321
}
 
322
 
 
323
 
 
324
function enigMessageFrameUnload() {
 
325
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageFrameUnload\n");
 
326
 
 
327
  if (gEnigNoShowReload) {
 
328
    gEnigNoShowReload = false;
 
329
 
 
330
  } else {
 
331
    gEnigSavedHeaders = null;
 
332
 
 
333
    enigMessageCleanup();
 
334
  }
 
335
}
 
336
 
 
337
function enigThreadPaneOnClick() {
 
338
  DEBUG_LOG("enigmailMessengerOverlay.js: enigThreadPaneOnClick\n");
 
339
}
 
340
 
 
341
function enigOverrideLayoutChange() {
 
342
  DEBUG_LOG("enigmailMessengerOverlay.js: enigOverrideLayoutChange\n");
 
343
  var viewTypeElementIds = ["messagePaneVertical",
 
344
                            "messagePaneClassic",
 
345
                            "messagePaneWide"];
 
346
  for (var i = 0; i < viewTypeElementIds.length; i++) {
 
347
    var elementId = viewTypeElementIds[i];
 
348
    var element = document.getElementById(elementId);
 
349
    if (element) {
 
350
      try {
 
351
        var oldValue = element.getAttribute("oncommand").replace(/;/g, "");
 
352
        var arg=oldValue.replace(/^(.*)(\(.*\))/, "$2");
 
353
        element.setAttribute("oncommand", "enigChangeMailLayout"+arg);
 
354
      } catch (ex) {}
 
355
    }
 
356
  }
 
357
  
 
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);
 
362
    if (element) {
 
363
      try {
 
364
        element.setAttribute("oncommand", "enigToggleMessagePane()");
 
365
      } catch (ex) {}
 
366
    }
 
367
  }
 
368
  
 
369
}
 
370
 
 
371
function enigChangeMailLayout(viewType) {
 
372
  ChangeMailLayout(viewType);
 
373
 
 
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);  
 
378
}
 
379
 
 
380
function enigToggleMessagePane() {
 
381
  enigStatusBarHide();
 
382
  MsgToggleMessagePane(true);
 
383
  
 
384
  var button=document.getElementById("button_enigmail_decrypt")
 
385
  if (gFolderDisplay.messageDisplay.visible) {
 
386
    button.removeAttribute("disabled");
 
387
  }
 
388
  else {
 
389
    button.setAttribute("disabled", "true");
 
390
  }
 
391
}
 
392
 
 
393
function enigGetCurrentMsgUriSpec() {
 
394
  try {
 
395
    if (gFolderDisplay.selectedMessages.length != 1)
 
396
      return "";
 
397
 
 
398
    var uriSpec = gFolderDisplay.selectedMessageUris[0];
 
399
    //DEBUG_LOG("enigmailMessengerOverlay.js: enigGetCurrentMsgUrl: uriSpec="+uriSpec+"\n");
 
400
 
 
401
    return uriSpec;
 
402
 
 
403
  } catch (ex) {
 
404
    return "";
 
405
  }
 
406
}
 
407
 
 
408
function enigGetCurrentMsgUrl() {
 
409
  try {
 
410
    var uriSpec = enigGetCurrentMsgUriSpec();
 
411
 
 
412
    if (!uriSpec)
 
413
      return null;
 
414
 
 
415
    var msgService = messenger.messageServiceFromURI(uriSpec);
 
416
 
 
417
    var urlObj = new Object();
 
418
    msgService.GetUrlForUri(uriSpec, urlObj, msgWindow);
 
419
 
 
420
    var url = urlObj.value;
 
421
 
 
422
    if (url.scheme=="file") {
 
423
      return url;
 
424
    }
 
425
    else {
 
426
      return url.QueryInterface(Components.interfaces.nsIMsgMailNewsUrl);
 
427
    }
 
428
    
 
429
  } catch (ex) {
 
430
    return null;
 
431
  }
 
432
 
 
433
}
 
434
 
 
435
function enigUpdateOptionsDisplay() {
 
436
  DEBUG_LOG("enigmailMessengerOverlay.js: enigUpdateOptionsDisplay: \n");
 
437
  var optList = ["autoDecrypt"];
 
438
 
 
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");
 
442
  }
 
443
 
 
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");
 
449
    }
 
450
    else {
 
451
       menuElement.removeAttribute("disabled");
 
452
    }
 
453
  }
 
454
}
 
455
 
 
456
 
 
457
function enigToggleAttribute(attrName)
 
458
{
 
459
  DEBUG_LOG("enigmailMsgessengerOverlay.js: enigToggleAttribute('"+attrName+"')\n");
 
460
 
 
461
  var menuElement = document.getElementById("enigmail_"+attrName);
 
462
 
 
463
  var oldValue = EnigGetPref(attrName);
 
464
  EnigSetPref(attrName, !oldValue);
 
465
 
 
466
  enigUpdateOptionsDisplay();
 
467
 
 
468
  if (attrName == "autoDecrypt")
 
469
    enigMessageReload(false);
 
470
}
 
471
 
 
472
function enigMessageImport(event) {
 
473
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageImport: "+event+"\n");
 
474
 
 
475
  return enigMessageParse(!event, true, "");
 
476
}
 
477
 
 
478
// callback function for automatic decryption
 
479
function enigMessageAutoDecrypt(event) {
 
480
  enigMessageDecrypt(event, true);
 
481
}
 
482
 
 
483
// analyse message header and decrypt/verify message
 
484
function enigMessageDecrypt(event, isAuto) {
 
485
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageDecrypt: "+event+"\n");
 
486
  
 
487
  var cbObj = {
 
488
    event: event,
 
489
    isAuto: isAuto
 
490
  };
 
491
 
 
492
  try {  
 
493
    MsgHdrToMimeMessage(gFolderDisplay.selectedMessage , cbObj, enigMsgDecryptMimeCb, true);
 
494
  }
 
495
  catch (ex) {
 
496
    DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageDecrypt: cannot use MsgHdrToMimeMessage\n");
 
497
    enigMessageDecryptCb(event, isAuto, null);
 
498
  }
 
499
}
 
500
 
 
501
 
 
502
function enigMsgDecryptMimeCb(msg, mimeMsg) {
 
503
  var enigmailSvc=GetEnigmailSvc();
 
504
  if (!enigmailSvc) return;
 
505
  
 
506
  enigMessageDecryptCb(this.event, this.isAuto, mimeMsg);
 
507
}  
 
508
 
 
509
function enigMessageDecryptCb(event, isAuto, mimeMsg){
 
510
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageDecryptCb:\n");
 
511
 
 
512
  var showHeaders = 0;
 
513
  var contentType = "";
 
514
 
 
515
  if (mimeMsg == null) {
 
516
    DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageDecryptCb: mimeMsg is null\n");
 
517
    contentType=currentHeaderData['content-type'].headerValue;
 
518
    mimeMsg = {
 
519
      headers: {'content-type': contentType },
 
520
      contentType: contentType,
 
521
      parts: {}
 
522
    }
 
523
  }
 
524
  
 
525
  // Copy selected headers
 
526
  gEnigSavedHeaders = {};
 
527
 
 
528
  for (var index=0; index < gEnigHeadersList.length; index++) {
 
529
    var headerName = gEnigHeadersList[index];
 
530
    var headerValue = "";
 
531
 
 
532
    if (mimeMsg.headers[headerName] != undefined) {
 
533
      headerValue = mimeMsg.headers[headerName].toString();
 
534
    }
 
535
 
 
536
    gEnigSavedHeaders[headerName] = headerValue;
 
537
    DEBUG_LOG("enigmailMessengerOverlay.js: "+headerName+": "+headerValue+"\n");
 
538
  }
 
539
 
 
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];
 
547
 
 
548
      if (attachment.contentType.search(/^application\/pgp-signature/i) == 0) {
 
549
        embeddedSigned = attachment.url.replace(/\&filename=.*$/,"").replace(/\.\d+\.\d+$/, "");
 
550
      }
 
551
      if (attachment.contentType.search(/^application\/pgp-encrypted/i) == 0) {
 
552
        embeddedEncrypted = attachment.url.replace(/\&filename=.*$/,"").replace(/\.\d+\.\d+$/, "");
 
553
      }
 
554
      DEBUG_LOG("enigmailMessengerOverlay.js: "+indexb+": "+attachment.contentType+"\n");
 
555
    }
 
556
  }
 
557
  
 
558
 
 
559
  var contentEncoding = "";
 
560
  var xEnigmailVersion = "";
 
561
 
 
562
  if (gEnigSavedHeaders) {
 
563
    contentType      = gEnigSavedHeaders["content-type"];
 
564
    contentEncoding  = gEnigSavedHeaders["content-transfer-encoding"];
 
565
    xEnigmailVersion = gEnigSavedHeaders["x-enigmail-version"];
 
566
  }
 
567
 
 
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();
 
574
      if (!enigmailSvc)
 
575
        return;
 
576
 
 
577
      if ((!enigmailSvc.mimeInitialized() && encrypedMsg) || signedMsg ||
 
578
          ((!encrypedMsg) && (embeddedSigned || embeddedEncrypted))) {
 
579
        enigUpdateHdrIcons(ENIG_POSSIBLE_PGPMIME, 0, "", "", "", EnigGetString("possiblyPgpMime"));
 
580
      }
 
581
    }
 
582
    return;
 
583
  }
 
584
 
 
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();
 
591
    if (!enigmailSvc)
 
592
      return;
 
593
 
 
594
    if (!enigmailSvc.mimeInitialized()) {
 
595
      // Display enigmail:dummy URL in message pane to initialize
 
596
 
 
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;
 
601
 
 
602
      DEBUG_LOG("enigmailMessengerOverlay.js: loading enigmail:dummy ...\n");
 
603
      gEnigNoShowReload = true;
 
604
 
 
605
      var msgFrame = EnigGetFrame(window, "messagepane");
 
606
      messenger.loadURL(msgFrame, "enigmail:dummy");
 
607
 
 
608
    }
 
609
    else if (! isAuto) {
 
610
      enigMessageReload(false);
 
611
    }
 
612
    else if (embeddedEncrypted && (! encrypedMsg)) {
 
613
      var mailNewsUrl = enigGetCurrentMsgUrl();
 
614
      if (mailNewsUrl) {
 
615
        mailNewsUrl.spec = embeddedEncrypted;
 
616
        enigVerifyEmbeddedMsg(window, mailNewsUrl, msgWindow, msgUriSpec, contentEncoding, event);
 
617
      }
 
618
    }
 
619
 
 
620
    return;
 
621
  }
 
622
 
 
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) {
 
629
      tryVerify = true;
 
630
    }
 
631
    if (contentType.search(/^multipart\/mixed(;|$)/i) == 0) {
 
632
      tryVerify = true;
 
633
      enableSubpartTreatment = true;
 
634
    }
 
635
  }
 
636
 
 
637
  if ((contentType.search(/^multipart\/signed(;|$)/i) == 0) &&
 
638
       (contentType.search(/application\/pgp-signature/i) >= 0)) {
 
639
    tryVerify=true;
 
640
  }
 
641
  if (tryVerify) {
 
642
    // multipart/signed
 
643
    DEBUG_LOG("enigmailMessengerOverlay.js: multipart/signed\n");
 
644
 
 
645
    enigmailSvc = GetEnigmailSvc();
 
646
    if (!enigmailSvc)
 
647
      return;
 
648
 
 
649
    var mailNewsUrl = enigGetCurrentMsgUrl();
 
650
    if (mailNewsUrl) {
 
651
      if (embeddedSigned) {
 
652
        mailNewsUrl.spec = embeddedSigned;
 
653
        enigVerifyEmbeddedMsg(window, mailNewsUrl, msgWindow, msgUriSpec, contentEncoding, event);
 
654
      }
 
655
      else {
 
656
        var verifier = Components.classes[ENIG_ENIGMIMEVERIFY_CONTRACTID].createInstance(Components.interfaces.nsIEnigMimeVerify);
 
657
 
 
658
        verifier.init(window, mailNewsUrl, msgWindow, msgUriSpec,
 
659
                      true, enableSubpartTreatment);
 
660
      }
 
661
      return;
 
662
    }
 
663
  }
 
664
 
 
665
  enigMessageParse(!event, false, contentEncoding);
 
666
}
 
667
 
 
668
 
 
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");
 
673
 
 
674
 
 
675
  ///EnigDumpHTML(msgFrame.document.documentElement);
 
676
 
 
677
  var bodyElement = msgFrame.document.getElementsByTagName("body")[0];
 
678
  DEBUG_LOG("enigmailMessengerOverlay.js: bodyElement="+bodyElement+"\n");
 
679
 
 
680
  var findStr = /* interactive ? null : */ "-----BEGIN PGP";
 
681
  var msgText = null;
 
682
  var foundIndex = -1;
 
683
  
 
684
  if (findStr) {
 
685
    foundIndex = bodyElement.textContent.indexOf(findStr);
 
686
    if (foundIndex >= 0) {
 
687
      if (bodyElement.textContent.indexOf(findStr+" LICENSE AUTHORIZATION") == foundIndex) 
 
688
        foundIndex = -1;
 
689
    }
 
690
  }
 
691
  if (foundIndex >= 0) {
 
692
    msgText = bodyElement.textContent;
 
693
  }
 
694
  
 
695
  if (!msgText) {
 
696
    // No PGP content
 
697
    return;
 
698
  }
 
699
 
 
700
  var charset = msgWindow ? msgWindow.mailCharacterSet : "";
 
701
 
 
702
  // Encode ciphertext to charset from unicode
 
703
  msgText = EnigConvertFromUnicode(msgText, charset);
 
704
 
 
705
  var mozPlainText = bodyElement.innerHTML.search(/class=\"moz-text-plain\"/);
 
706
 
 
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");
 
713
    }
 
714
  }
 
715
 
 
716
  // extract text preceeding and/or following armored block
 
717
  var head="";
 
718
  var tail="";
 
719
  if (findStr) {
 
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]/);
 
724
    if (nextLine>0) {
 
725
      tail=msgText.substring(endStart+nextLine).replace(/^[\n\r\s]*/,"");
 
726
    }
 
727
  }
 
728
 
 
729
  //DEBUG_LOG("enigmailMessengerOverlay.js: msgText='"+msgText+"'\n");
 
730
 
 
731
  var mailNewsUrl = enigGetCurrentMsgUrl();
 
732
 
 
733
  var urlSpec = mailNewsUrl ? mailNewsUrl.spec : "";
 
734
 
 
735
  retry = (charset != "UTF-8" ? 1 : 2);
 
736
 
 
737
  enigMessageParseCallback(msgText, contentEncoding, charset, interactive,
 
738
                           importOnly, urlSpec, "", retry, head, tail);
 
739
}
 
740
 
 
741
 
 
742
function enigMessageParseCallback(msgText, contentEncoding, charset, interactive,
 
743
                                  importOnly, messageUrl, signature, retry,
 
744
                                  head, tail) {
 
745
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageParseCallback: "+interactive+", "+interactive+", importOnly="+importOnly+", charset="+charset+", msgUrl="+messageUrl+", retry="+retry+", signature='"+signature+"'\n");
 
746
 
 
747
  if (!msgText)
 
748
    return;
 
749
 
 
750
  var enigmailSvc = GetEnigmailSvc();
 
751
  if (!enigmailSvc)
 
752
    return;
 
753
 
 
754
  var plainText;
 
755
  var exitCode;
 
756
  var newSignature = "";
 
757
  var statusFlags = 0;
 
758
 
 
759
  var errorMsgObj = new Object();
 
760
  var keyIdObj    = new Object();
 
761
 
 
762
  if (importOnly) {
 
763
    // Import public key
 
764
    var importFlags = nsIEnigmail.UI_INTERACTIVE;
 
765
    exitCode = enigmailSvc.importKey(window, importFlags, msgText, "",
 
766
                                     errorMsgObj);
 
767
 
 
768
  } else {
 
769
 
 
770
    if (msgText.indexOf("\nCharset:") > 0) {
 
771
      // Check if character set needs to be overridden
 
772
      var startOffset = msgText.indexOf("-----BEGIN PGP ");
 
773
 
 
774
      if (startOffset >= 0) {
 
775
        var subText = msgText.substr(startOffset);
 
776
 
 
777
        subText = subText.replace(/\r\n/g, "\n");
 
778
        subText = subText.replace(/\r/g,   "\n");
 
779
 
 
780
        var endOffset = subText.search(/\n\n/);
 
781
        if (endOffset > 0) {
 
782
          subText = subText.substr(0,endOffset) + "\n";
 
783
 
 
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");
 
789
          }
 
790
        }
 
791
      }
 
792
    }
 
793
 
 
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();
 
799
 
 
800
    var signatureObj = new Object();
 
801
    signatureObj.value = signature;
 
802
 
 
803
    var uiFlags = interactive ? (nsIEnigmail.UI_INTERACTIVE |
 
804
                                 nsIEnigmail.UI_ALLOW_KEY_IMPORT |
 
805
                                 nsIEnigmail.UI_UNVERIFIED_ENC_OK) : 0;
 
806
 
 
807
 
 
808
    plainText = enigmailSvc.decryptMessage(window, uiFlags, msgText,
 
809
                                 signatureObj, exitCodeObj, statusFlagsObj,
 
810
                                 keyIdObj, userIdObj, sigDetailsObj, errorMsgObj, blockSeparationObj);
 
811
 
 
812
    //DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageParseCallback: plainText='"+plainText+"'\n");
 
813
 
 
814
    exitCode = exitCodeObj.value;
 
815
    newSignature = signatureObj.value;
 
816
    
 
817
    if (plainText == "" && exitCode == 0) {
 
818
      plainText = " ";
 
819
    }
 
820
 
 
821
    statusFlags = statusFlagsObj.value;
 
822
    
 
823
    DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageParseCallback: newSignature='"+newSignature+"'\n");
 
824
  }
 
825
 
 
826
  var errorMsg = errorMsgObj.value;
 
827
 
 
828
  if (importOnly) {
 
829
     if (interactive && errorMsg)
 
830
       EnigLongAlert(errorMsg);
 
831
     return;
 
832
  }
 
833
 
 
834
  enigUpdateHdrIcons(exitCode, statusFlags, keyIdObj.value, userIdObj.value, sigDetailsObj.value, errorMsg, null);
 
835
 
 
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;
 
849
 
 
850
  if ((exitCode !=0) && (! (statusFlags & noSecondTry))) {
 
851
    // Bad signature/armor
 
852
    if (retry == 1) {
 
853
      msgText = EnigConvertFromUnicode(msgText, "UTF-8");
 
854
      enigMessageParseCallback(msgText, contentEncoding, charset, interactive,
 
855
                               importOnly, messageUrl, signature, retry + 1,
 
856
                               head, tail);
 
857
      return;
 
858
    }
 
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)
 
862
      newSignature = "";
 
863
      enigMsgDirect(interactive, importOnly, contentEncoding, charset, newSignature, 0, head, tail, enigMessageParseCallback);
 
864
      return;
 
865
    }
 
866
    else if (retry == 3) {
 
867
      msgText = EnigConvertToUnicode(msgText, "UTF-8");
 
868
      enigMessageParseCallback(msgText, contentEncoding, charset, interactive,
 
869
                               importOnly, messageUrl, null, retry + 1,
 
870
                               head, tail)
 
871
      return;
 
872
    }
 
873
  }
 
874
 
 
875
  if (!plainText) {
 
876
     if (interactive && gEnigSecurityInfo && gEnigSecurityInfo.statusInfo)
 
877
       EnigLongAlert(gEnigSecurityInfo.statusInfo);
 
878
     return;
 
879
  }
 
880
  
 
881
  if (retry >= 2) {
 
882
    plainText = EnigConvertFromUnicode(EnigConvertToUnicode(plainText, "UTF-8"), charset);
 
883
  }
 
884
 
 
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");
 
889
  }
 
890
 
 
891
  // Save decrypted message status, headers, and content
 
892
  var headerList = {"subject":"", "from":"", "date":"", "to":"", "cc":""};
 
893
 
 
894
  var index, headerName;
 
895
 
 
896
  if (!gViewAllHeaders) {
 
897
    for (index = 0; index < headerList.length; index++) {
 
898
      headerList[index] = "";
 
899
    }
 
900
 
 
901
  } else {
 
902
    for (index = 0; index < gExpandedHeaderList.length; index++) {
 
903
      headerList[gExpandedHeaderList[index].name] = "";
 
904
    }
 
905
 
 
906
    for (headerName in currentHeaderData) {
 
907
      headerList[headerName] = "";
 
908
    }
 
909
  }
 
910
 
 
911
  for (headerName in headerList) {
 
912
    if (currentHeaderData[headerName])
 
913
      headerList[headerName] = currentHeaderData[headerName].headerValue;
 
914
  }
 
915
 
 
916
  // WORKAROUND
 
917
  if (headerList["cc"] == headerList["to"])
 
918
    headerList["cc"] = "";
 
919
 
 
920
  var hasAttachments = currentAttachments && currentAttachments.length;
 
921
  var attachmentsEncrypted=true;
 
922
 
 
923
  for (index in currentAttachments) {
 
924
    if (! enigCheckEncryptedAttach(currentAttachments[index])) {
 
925
      if (!enigCheckSignedAttachment(currentAttachments, index)) attachmentsEncrypted=false;
 
926
    }
 
927
  }
 
928
 
 
929
  var msgRfc822Text = "";
 
930
  if (head || tail) {
 
931
    if (head) {
 
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";
 
937
      }
 
938
      msgRfc822Text+=head+"\n\n";
 
939
    }
 
940
    msgRfc822Text += EnigGetString("beginPgpPart")+"\n\n";
 
941
  }
 
942
  msgRfc822Text+=plainText;
 
943
  if (head || tail) {
 
944
    msgRfc822Text+="\n\n"+EnigGetString("endPgpPart")+"\n\n"+tail;
 
945
  }
 
946
 
 
947
  gEnigDecryptedMessage = {url:messageUrl,
 
948
                           headerList:headerList,
 
949
                           hasAttachments:hasAttachments,
 
950
                           attachmentsEncrypted:attachmentsEncrypted,
 
951
                           charset:charset,
 
952
                           plainText:msgRfc822Text};
 
953
 
 
954
  var msgFrame = EnigGetFrame(window, "messagepane");
 
955
  var bodyElement = msgFrame.document.getElementsByTagName("body")[0];
 
956
 
 
957
  try {
 
958
    // Create and load one-time message URI
 
959
    var messageContent = enigGetDecryptedMessage("message/rfc822", false);
 
960
 
 
961
    gEnigNoShowReload = true;
 
962
 
 
963
    var uri = enigmailSvc.createMessageURI(messageUrl,
 
964
                                           "message/rfc822",
 
965
                                           "",
 
966
                                           messageContent,
 
967
                                           false);
 
968
    gEnigCreatedURIs.push(uri);
 
969
 
 
970
    //msgFrame.location=uri;
 
971
    messenger.loadURL(msgFrame, uri);
 
972
 
 
973
  } catch (ex) {
 
974
    // Display plain text with hyperlinks
 
975
 
 
976
    // Get selection range for inserting HTML
 
977
    var domSelection = msgFrame._content.getSelection();
 
978
 
 
979
    var privateSelection = domSelection.QueryInterface(Components.interfaces.nsISelectionPrivate);
 
980
    var selection = privateSelection.QueryInterface(Components.interfaces.nsISelection);
 
981
 
 
982
    selection.collapse(bodyElement, 0);
 
983
    var selRange = selection.getRangeAt(0);
 
984
 
 
985
    // Decode plaintext to unicode
 
986
    tail = EnigConvertToUnicode(tail, charset);
 
987
    var uniText = EnigConvertToUnicode(plainText, charset);
 
988
 
 
989
    var htmlText="";
 
990
    if (head) {
 
991
       htmlText += "<pre>"+enigEscapeTextForHTML(EnigConvertToUnicode(head, charset),true)+"</pre><p/>\n";
 
992
    }
 
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>'+
 
996
      '<td><pre>' +
 
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'
 
1002
 
 
1003
    if (tail) {
 
1004
       htmlText += "<p/><pre>"+enigEscapeTextForHTML(EnigConvertToUnicode(tail, charset),true)+"</pre>";
 
1005
    }
 
1006
 
 
1007
    var docFrag = selRange.createContextualFragment(htmlText);
 
1008
 
 
1009
    // Clear HTML body
 
1010
    while (bodyElement.hasChildNodes())
 
1011
        bodyElement.removeChild(bodyElement.childNodes[0]);
 
1012
 
 
1013
    if (hasAttachments && (! attachmentsEncrypted)) {
 
1014
      var newTextNode = msgFrame.document.createTextNode(EnigGetString("enigNote"));
 
1015
 
 
1016
      var newEmElement = msgFrame.document.createElement("em");
 
1017
      newEmElement.appendChild(newTextNode);
 
1018
 
 
1019
      bodyElement.appendChild(newEmElement);
 
1020
      bodyElement.appendChild(msgFrame.document.createElement("p"));
 
1021
    }
 
1022
 
 
1023
    bodyElement.appendChild(docFrag.firstChild);
 
1024
 
 
1025
  }
 
1026
 
 
1027
  return;
 
1028
}
 
1029
 
 
1030
// check if an attachment could be signed
 
1031
function enigCheckSignedAttachment(currentAttachments, index) {
 
1032
 
 
1033
  // check if filename ends with .sig
 
1034
  if (currentAttachments[index].displayName.search(/\.sig$/i) > 0) return true;
 
1035
  
 
1036
  var signed = false;
 
1037
  var findFile = currentAttachments[index].displayName.toLowerCase()+".sig";
 
1038
  var i;
 
1039
  for (i in currentAttachments) {
 
1040
    if (currentAttachments[i].displayName.toLowerCase() == findFile) signed=true;
 
1041
  }
 
1042
  return signed;
 
1043
}
 
1044
 
 
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));
 
1049
}
 
1050
 
 
1051
function enigEscapeTextForHTML(text, hyperlink) {
 
1052
  // Escape special characters
 
1053
  if (text.indexOf("&") > -1)
 
1054
    text = text.replace(/&/g, "&amp;")
 
1055
 
 
1056
  if (text.indexOf("<") > -1)
 
1057
    text = text.replace(/</g, "&lt;")
 
1058
 
 
1059
  if (text.indexOf(">") > -1)
 
1060
    text = text.replace(/>/g, "&gt;")
 
1061
 
 
1062
  if (text.indexOf("\"") > -1)
 
1063
    text = text.replace(/"/g, "&quot;")
 
1064
 
 
1065
  if (!hyperlink)
 
1066
    return text;
 
1067
 
 
1068
  // Hyperlink email addresses
 
1069
  var addrs = text.match(/\b[A-Za-z0-9_+\-\.]+@[A-Za-z0-9\-\.]+\b/g);
 
1070
 
 
1071
  var newText, offset, loc;
 
1072
  if (addrs && addrs.length) {
 
1073
    newText = "";
 
1074
    offset = 0;
 
1075
 
 
1076
    for (var j=0; j < addrs.length; j++) {
 
1077
      var addr = addrs[j];
 
1078
 
 
1079
      loc = text.indexOf(addr, offset);
 
1080
      if (loc < offset)
 
1081
        break;
 
1082
 
 
1083
      if (loc > offset)
 
1084
        newText += text.substr(offset, loc-offset);
 
1085
 
 
1086
      // Strip any period off the end of address
 
1087
      addr = addr.replace(/[\.]$/, "");
 
1088
 
 
1089
      if (!addr.length)
 
1090
        continue;
 
1091
 
 
1092
      newText += "<a href=\"mailto:"+addr+"\">" + addr + "</a>";
 
1093
 
 
1094
      offset = loc + addr.length;
 
1095
    }
 
1096
 
 
1097
    newText += text.substr(offset, text.length-offset);
 
1098
 
 
1099
    text = newText;
 
1100
  }
 
1101
 
 
1102
  // Hyperlink URLs
 
1103
  var urls = text.match(/\b(http|https|ftp):\S+\s/g);
 
1104
 
 
1105
  if (urls && urls.length) {
 
1106
    newText = "";
 
1107
    offset = 0;
 
1108
 
 
1109
    for (var k=0; k < urls.length; k++) {
 
1110
      var url = urls[k];
 
1111
 
 
1112
      loc = text.indexOf(url, offset);
 
1113
      if (loc < offset)
 
1114
        break;
 
1115
 
 
1116
      if (loc > offset)
 
1117
        newText += text.substr(offset, loc-offset);
 
1118
 
 
1119
      // Strip delimiters off the end of URL
 
1120
      url = url.replace(/\s$/, "");
 
1121
      url = url.replace(/([\),\.']|&gt;|&quot;)$/, "");
 
1122
 
 
1123
      if (!url.length)
 
1124
        continue;
 
1125
 
 
1126
      newText += "<a href=\""+url+"\">" + url + "</a>";
 
1127
 
 
1128
      offset = loc + url.length;
 
1129
    }
 
1130
 
 
1131
    newText += text.substr(offset, text.length-offset);
 
1132
 
 
1133
    text = newText;
 
1134
  }
 
1135
 
 
1136
  return text;
 
1137
}
 
1138
 
 
1139
function enigGetDecryptedMessage(contentType, includeHeaders) {
 
1140
  DEBUG_LOG("enigmailMessengerOverlay.js: enigGetDecryptedMessage: "+contentType+", "+includeHeaders+"\n");
 
1141
 
 
1142
  if (!gEnigDecryptedMessage)
 
1143
    return "No decrypted message found!\n";
 
1144
 
 
1145
  var enigmailSvc = GetEnigmailSvc();
 
1146
  if (!enigmailSvc)
 
1147
    return "";
 
1148
 
 
1149
  var headerList = gEnigDecryptedMessage.headerList;
 
1150
 
 
1151
  var statusLine = gEnigSecurityInfo ? gEnigSecurityInfo.statusLine : "";
 
1152
 
 
1153
  var contentData = "";
 
1154
 
 
1155
  var headerName;
 
1156
 
 
1157
  if (contentType == "message/rfc822") {
 
1158
    // message/rfc822
 
1159
 
 
1160
    if (includeHeaders) {
 
1161
      try {
 
1162
 
 
1163
        var msg = gFolderDisplay.selectedMessage;
 
1164
        if (msg) {
 
1165
          msgHdr = { "From": msg.author,
 
1166
                     "Subject": msg.subject,
 
1167
                     "To": msg.recipients,
 
1168
                     "Cc": msg.ccList,
 
1169
                     "Date": EnigGetDateTime(msg.dateInSeconds, true, true) };
 
1170
 
 
1171
 
 
1172
          if(gFolderDisplay.selectedMessageIsNews) {
 
1173
            if (typeof (currentHeaderData.newsgroups)) {
 
1174
              msgHdr.Newsgroups = currentHeaderData.newsgroups.headerValue;
 
1175
            }
 
1176
          }
 
1177
 
 
1178
          for (headerName in msgHdr) {
 
1179
            if (msgHdr[headerName] && msgHdr[headerName].length>0)
 
1180
              contentData += headerName + ": " + msgHdr[headerName] + "\r\n";
 
1181
          }
 
1182
 
 
1183
        }
 
1184
      } catch (ex) {
 
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";
 
1190
        }
 
1191
      }
 
1192
    }
 
1193
 
 
1194
    contentData += "Content-Type: text/plain";
 
1195
 
 
1196
    if (gEnigDecryptedMessage.charset) {
 
1197
      contentData += "; charset="+gEnigDecryptedMessage.charset;
 
1198
    }
 
1199
 
 
1200
    contentData += "\r\n\r\n";
 
1201
 
 
1202
    if (gEnigDecryptedMessage.hasAttachments && (! gEnigDecryptedMessage.attachmentsEncrypted)) {
 
1203
      contentData += EnigGetString("enigContentNote");
 
1204
    }
 
1205
 
 
1206
    contentData += gEnigDecryptedMessage.plainText;
 
1207
 
 
1208
  } else {
 
1209
    // text/html or text/plain
 
1210
 
 
1211
    if (contentType == "text/html") {
 
1212
      contentData += "<meta http-equiv=\"Content-Type\" content=\"text/html; charset="+gEnigDecryptedMessage.charset+"\">\r\n";
 
1213
 
 
1214
      contentData += "<html><head></head><body>\r\n";
 
1215
    }
 
1216
 
 
1217
    if (statusLine) {
 
1218
      if (contentType == "text/html") {
 
1219
        contentData += "<b>"+EnigGetString("enigHeader")+"</b> " +
 
1220
                       enigEscapeTextForHTML(statusLine, false) + "<br>\r\n<hr>\r\n";
 
1221
      } else{
 
1222
        contentData += EnigGetString("enigHeader")+" " + statusLine + "\r\n\r\n";
 
1223
      }
 
1224
    }
 
1225
 
 
1226
    if (includeHeaders) {
 
1227
      for (headerName in headerList) {
 
1228
        headerValue = headerList[headerName];
 
1229
 
 
1230
        if (headerValue) {
 
1231
          if (contentType == "text/html") {
 
1232
            contentData += "<b>"+enigEscapeTextForHTML(headerName, false)+":</b> "+
 
1233
                                 enigEscapeTextForHTML(headerValue, false)+"<br>\r\n";
 
1234
          } else {
 
1235
            contentData += headerName + ": " + headerValue + "\r\n";
 
1236
          }
 
1237
        }
 
1238
      }
 
1239
    }
 
1240
 
 
1241
    if (contentType == "text/html") {
 
1242
      contentData += "<pre>"+enigEscapeTextForHTML(gEnigDecryptedMessage.plainText, false)+"</pre>\r\n";
 
1243
 
 
1244
      contentData += "</body></html>\r\n";
 
1245
 
 
1246
    } else {
 
1247
 
 
1248
      contentData += "\r\n"+gEnigDecryptedMessage.plainText;
 
1249
    }
 
1250
 
 
1251
    if (!(enigmailSvc.isDosLike)) {
 
1252
      contentData = contentData.replace(/\r\n/g, "\n");
 
1253
    }
 
1254
  }
 
1255
 
 
1256
  return contentData;
 
1257
}
 
1258
 
 
1259
 
 
1260
function enigMsgDefaultPrint(elementId) {
 
1261
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMsgDefaultPrint: "+elementId+"\n");
 
1262
 
 
1263
  goDoCommand(elementId.indexOf("printpreview")>=0 ? "cmd_printpreview" : "cmd_print");
 
1264
}
 
1265
 
 
1266
function enigMsgPrint(elementId) {
 
1267
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMsgPrint: "+elementId+"\n");
 
1268
 
 
1269
  var contextMenu = (elementId.search("Context") > -1);
 
1270
 
 
1271
  if (!gEnigDecryptedMessage || typeof(gEnigDecryptedMessage) == "undefined") {
 
1272
    enigMsgDefaultPrint(elementId);
 
1273
    return;
 
1274
  }
 
1275
 
 
1276
  var mailNewsUrl = enigGetCurrentMsgUrl();
 
1277
 
 
1278
  if (!mailNewsUrl) {
 
1279
    enigMsgDefaultPrint(elementId);
 
1280
    return
 
1281
  }
 
1282
 
 
1283
  if (gEnigDecryptedMessage.url != mailNewsUrl.spec) {
 
1284
    gEnigDecryptedMessage = null;
 
1285
    enigMsgDefaultPrint(elementId);
 
1286
    return;
 
1287
  }
 
1288
 
 
1289
  var enigmailSvc = GetEnigmailSvc();
 
1290
  if (!enigmailSvc) {
 
1291
    enigMsgDefaultPrint(elementId);
 
1292
    return;
 
1293
  }
 
1294
 
 
1295
  // Note: Trying to print text/html content does not seem to work with
 
1296
  //       non-ASCII chars
 
1297
  var msgContent = enigGetDecryptedMessage("message/rfc822", true);
 
1298
 
 
1299
  var uri = enigmailSvc.createMessageURI(gEnigDecryptedMessage.url,
 
1300
                                         "message/rfc822",
 
1301
                                         "",
 
1302
                                         msgContent,
 
1303
                                         false);
 
1304
 
 
1305
  gEnigCreatedURIs.push(uri);
 
1306
 
 
1307
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMsgPrint: uri="+uri+"\n");
 
1308
 
 
1309
  var messageList = [uri];
 
1310
 
 
1311
  var printPreview = (elementId.indexOf("printpreview")>=0);
 
1312
 
 
1313
  window.openDialog("chrome://messenger/content/msgPrintEngine.xul",
 
1314
                    "",
 
1315
                    "chrome,dialog=no,all,centerscreen",
 
1316
                    1, messageList, statusFeedback,
 
1317
                    printPreview, Components.interfaces.nsIMsgPrintEngine.MNAB_PRINTPREVIEW_MSG,
 
1318
                    window);
 
1319
  
 
1320
  return true;
 
1321
 
 
1322
}
 
1323
 
 
1324
function enigMessageSave() {
 
1325
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageSave: \n");
 
1326
 
 
1327
  if (!gEnigDecryptedMessage) {
 
1328
    EnigAlert(EnigGetString("noDecrypted"));
 
1329
    return;
 
1330
  }
 
1331
 
 
1332
  var mailNewsUrl = enigGetCurrentMsgUrl();
 
1333
 
 
1334
  if (!mailNewsUrl) {
 
1335
    EnigAlert(EnigGetString("noMessage"));
 
1336
    return;
 
1337
  }
 
1338
 
 
1339
  if (gEnigDecryptedMessage.url != mailNewsUrl.spec) {
 
1340
    gEnigDecryptedMessage = null;
 
1341
    EnigAlert(EnigGetString("useButton"));
 
1342
    return;
 
1343
  }
 
1344
 
 
1345
  var saveFile = EnigFilePicker(EnigGetString("saveHeader"),
 
1346
                                gEnigLastSaveDir, true, "txt",
 
1347
                                null, ["Text files", "*.txt"]);
 
1348
  if (!saveFile) return;
 
1349
 
 
1350
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMessageSave: path="+saveFile.path+"\n");
 
1351
 
 
1352
  if (saveFile.parent)
 
1353
    gEnigLastSaveDir = EnigGetFilePath(saveFile.parent);
 
1354
 
 
1355
  var textContent = enigGetDecryptedMessage("text/plain", true);
 
1356
 
 
1357
//  EnigAlert(textContent);
 
1358
 
 
1359
  if (!EnigWriteFileContents(saveFile.path, textContent, null)) {
 
1360
    EnigAlert("Error in saving to file "+saveFile.path);
 
1361
    return;
 
1362
  }
 
1363
 
 
1364
  return;
 
1365
}
 
1366
 
 
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();
 
1370
  if (!mailNewsUrl)
 
1371
    return;
 
1372
 
 
1373
  var ipcBuffer = Components.classes[ENIG_IPCBUFFER_CONTRACTID].createInstance(Components.interfaces.nsIIPCBuffer);
 
1374
  var mimeListener = Components.classes[ENIG_ENIGMIMELISTENER_CONTRACTID].createInstance(Components.interfaces.nsIEnigMimeListener);
 
1375
 
 
1376
  if (bufferSize > 0) {
 
1377
    ipcBuffer.open(bufferSize, false);
 
1378
  }
 
1379
  else {
 
1380
    ipcBuffer.open(ENIG_MSG_BUFFER_SIZE, false);
 
1381
  }
 
1382
 
 
1383
  var callbackArg = { interactive:interactive,
 
1384
                      importOnly:importOnly,
 
1385
                      contentEncoding:contentEncoding,
 
1386
                      charset:charset,
 
1387
                      messageUrl:mailNewsUrl.spec,
 
1388
                      signature:signature,
 
1389
                      ipcBuffer:ipcBuffer,
 
1390
                      expectedBufferSize: bufferSize,
 
1391
                      head:head,
 
1392
                      tail:tail,
 
1393
                      mimeListener: mimeListener,
 
1394
                      callbackFunction: callbackFunction };
 
1395
 
 
1396
  var requestObserver = new EnigRequestObserver(enigMsgDirectCallback,
 
1397
                                                callbackArg);
 
1398
 
 
1399
  ipcBuffer.observe(requestObserver, mailNewsUrl);
 
1400
 
 
1401
  var ioServ = Components.classes[ENIG_IOSERVICE_CONTRACTID].getService(Components.interfaces.nsIIOService);
 
1402
 
 
1403
  var channel = ioServ.newChannelFromURI(mailNewsUrl);
 
1404
 
 
1405
  var pipeFilter = Components.classes[ENIG_PIPEFILTERLISTENER_CONTRACTID].createInstance(Components.interfaces.nsIPipeFilterListener);
 
1406
  pipeFilter.init(ipcBuffer, null,
 
1407
                "-----BEGIN PGP",
 
1408
                "-----END PGP",
 
1409
                0, true, false, null);
 
1410
 
 
1411
  var listener;
 
1412
 
 
1413
  try {
 
1414
 
 
1415
    mimeListener.init(pipeFilter, null, ENIG_MSG_HEADER_SIZE, true, false, true);
 
1416
 
 
1417
    listener = mimeListener;
 
1418
 
 
1419
  } catch (ex) {
 
1420
    listener = pipeFilter;
 
1421
  }
 
1422
 
 
1423
  channel.asyncOpen(pipeFilter, mailNewsUrl);
 
1424
}
 
1425
 
 
1426
 
 
1427
function enigMsgDirectCallback(callbackArg, ctxt) {
 
1428
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMsgDirectCallback: "+ctxt+"\n");
 
1429
 
 
1430
  var mailNewsUrl = enigGetCurrentMsgUrl();
 
1431
  var urlSpec = mailNewsUrl ? mailNewsUrl.spec : "";
 
1432
  var newBufferSize = 0;
 
1433
 
 
1434
  var l= urlSpec.length;
 
1435
 
 
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");
 
1438
    return;
 
1439
  }
 
1440
 
 
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;
 
1446
    }
 
1447
  }
 
1448
 
 
1449
  var msgText = callbackArg.ipcBuffer.getData();
 
1450
  msgText = EnigConvertFromUnicode(msgText, "UTF-8");
 
1451
 
 
1452
  callbackArg.ipcBuffer.shutdown();
 
1453
 
 
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,
 
1461
                  newBufferSize,
 
1462
                  callbackArg.head,
 
1463
                  callbackArg.tail,
 
1464
                  callbackArg.callbackFunction);
 
1465
 
 
1466
  }
 
1467
  DEBUG_LOG("enigmailMessengerOverlay.js: enigMsgDirectCallback: msgText='"+msgText+"'\n");
 
1468
 
 
1469
  callbackArg.callbackFunction(msgText, callbackArg.contentEncoding,
 
1470
                           callbackArg.charset,
 
1471
                           callbackArg.interactive,
 
1472
                           callbackArg.importOnly,
 
1473
                           callbackArg.messageUrl,
 
1474
                           callbackArg.signature,
 
1475
                           3,
 
1476
                           callbackArg.head,
 
1477
                           callbackArg.tail);
 
1478
}
 
1479
 
 
1480
 
 
1481
function enigVerifyEmbeddedMsg(window, msgUrl, msgWindow, msgUriSpec, contentEncoding, event) {
 
1482
  DEBUG_LOG("enigmailMessengerOverlay.js: enigVerifyEmbedded: msgUrl"+msgUrl+"\n");
 
1483
 
 
1484
  var ipcBuffer = Components.classes[ENIG_IPCBUFFER_CONTRACTID].createInstance(Components.interfaces.nsIIPCBuffer);
 
1485
  ipcBuffer.open(ENIG_UNLIMITED_BUFFER_SIZE, false);
 
1486
 
 
1487
  var callbackArg = { ipcBuffer: ipcBuffer,
 
1488
                      window: window,
 
1489
                      msgUrl: msgUrl,
 
1490
                      msgWindow: msgWindow,
 
1491
                      msgUriSpec: msgUriSpec,
 
1492
                      contentEncoding: contentEncoding,
 
1493
                      event: event };
 
1494
 
 
1495
  var requestObserver = new EnigRequestObserver(enigVerifyEmbeddedCallback,
 
1496
                                                callbackArg);
 
1497
 
 
1498
  ipcBuffer.observe(requestObserver, msgUrl);
 
1499
 
 
1500
  var ioServ = Components.classes[ENIG_IOSERVICE_CONTRACTID].getService(Components.interfaces.nsIIOService);
 
1501
 
 
1502
  var channel = ioServ.newChannelFromURI(msgUrl);
 
1503
 
 
1504
  var pipeFilter = Components.classes[ENIG_PIPEFILTERLISTENER_CONTRACTID].createInstance(Components.interfaces.nsIPipeFilterListener);
 
1505
 
 
1506
  pipeFilter.init(ipcBuffer, null,
 
1507
                "",
 
1508
                "",
 
1509
                0, false, false, null);
 
1510
 
 
1511
  channel.asyncOpen(pipeFilter, msgUrl);
 
1512
}
 
1513
 
 
1514
function enigVerifyEmbeddedCallback(callbackArg, ctxt) {
 
1515
  DEBUG_LOG("enigmailMessengerOverlay.js: enigVerifyEmbeddedCallback: "+ctxt+"\n");
 
1516
 
 
1517
  var txt = callbackArg.ipcBuffer.getData();
 
1518
  callbackArg.ipcBuffer.shutdown();
 
1519
 
 
1520
  if (txt.length > 0) {
 
1521
    msigned=txt.search(/content\-type:[ \t]*multipart\/signed/i);
 
1522
    if(msigned >= 0) {
 
1523
      // Real multipart/signed message; let's try to verify it
 
1524
      DEBUG_LOG("enigmailMessengerOverlay.js: enigVerifyEmbeddedCallback: detected multipart/signed\n");
 
1525
 
 
1526
      callbackArg.enableSubpartTreatment=(msigned > 0);
 
1527
 
 
1528
      var uri = Components.classes[ENIG_SIMPLEURI_CONTRACTID].createInstance(Components.interfaces.nsIURI);
 
1529
      uri.spec = "enigmail:dummy";
 
1530
 
 
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);
 
1534
      
 
1535
      verifier.initWithChannel(callbackArg.window, channel, callbackArg.msgWindow, callbackArg.msgUriSpec,
 
1536
                      true, callbackArg.enableSubpartTreatment);
 
1537
      return;
 
1538
    }
 
1539
  }
 
1540
  
 
1541
  // try inline PGP
 
1542
  DEBUG_LOG("enigmailMessengerOverlay.js: enigVerifyEmbeddedCallback: try inline PGP\n");
 
1543
 
 
1544
  enigMessageParse(!callbackArg.event, false, callbackArg.contentEncoding);
 
1545
}
 
1546
 
 
1547
 
 
1548
function enigKeyRequest(interactive, keyId, urlSpec) {
 
1549
  DEBUG_LOG("enigmailMessengerOverlay.js: enigKeyRequest: keyId="+keyId+", urlSpec="+urlSpec+"\n");
 
1550
 
 
1551
  var ipcBuffer = Components.classes[ENIG_IPCBUFFER_CONTRACTID].createInstance(Components.interfaces.nsIIPCBuffer);
 
1552
 
 
1553
  ipcBuffer.open(ENIG_KEY_BUFFER_SIZE, false);
 
1554
 
 
1555
  var ioServ = Components.classes[ENIG_IOSERVICE_CONTRACTID].getService(Components.interfaces.nsIIOService);
 
1556
 
 
1557
  try {
 
1558
    var uri = ioServ.newURI(urlSpec, "", null);
 
1559
 
 
1560
    var channel = ioServ.newChannelFromURI(uri);
 
1561
 
 
1562
    var httpChannel = channel.QueryInterface(Components.interfaces.nsIHttpChannel);
 
1563
 
 
1564
    // Disable HTTP redirection
 
1565
    httpChannel.redirectionLimit = 0;
 
1566
 
 
1567
    var callbackArg = { interactive:interactive,
 
1568
                        keyId:keyId,
 
1569
                        urlSpec:urlSpec,
 
1570
                        httpChannel:httpChannel,
 
1571
                        ipcBuffer:ipcBuffer };
 
1572
 
 
1573
    var requestObserver = new EnigRequestObserver(enigKeyRequestCallback,
 
1574
                                                  callbackArg);
 
1575
 
 
1576
    ipcBuffer.observe(requestObserver, null);
 
1577
 
 
1578
    DEBUG_LOG("enigmailMessengerOverlay.js: enigKeyRequest: httpChannel="+httpChannel+", asyncOpen ...\n");
 
1579
 
 
1580
    httpChannel.asyncOpen(ipcBuffer, null);
 
1581
 
 
1582
  } catch (ex) {
 
1583
    ERROR_LOG("enigmailMessengerOverlay.js: enigKeyRequest: Error - failed to create channel\n");
 
1584
  }
 
1585
 
 
1586
}
 
1587
 
 
1588
 
 
1589
function enigKeyRequestCallback(callbackArg, ctxt) {
 
1590
  var urlSpec = callbackArg.urlSpec;
 
1591
  var httpChannel = callbackArg.httpChannel;
 
1592
 
 
1593
  DEBUG_LOG("enigmailMessengerOverlay.js: enigKeyRequestCallback: urlSpec="+urlSpec+"\n");
 
1594
 
 
1595
  if (callbackArg.ipcBuffer.overflowed) {
 
1596
    WARNING_LOG("enigmailMessengerOverlay.js: enigKeyRequestCallback: KEY BUFFER OVERFLOW\n");
 
1597
  }
 
1598
 
 
1599
  var eTag = httpChannel.getResponseHeader("ETag");
 
1600
 
 
1601
  var keyText = callbackArg.ipcBuffer.getData();
 
1602
 
 
1603
  callbackArg.ipcBuffer.shutdown();
 
1604
 
 
1605
  DEBUG_LOG("enigmailMessengerOverlay.js: enigKeyRequestCallback: keyText='"+keyText+"'\n");
 
1606
 
 
1607
  DEBUG_LOG("enigmailMessengerOverlay.js: enigKeyRequestCallback: NoCache='"+httpChannel.isNoCacheResponse()+"'\n");
 
1608
 
 
1609
  DEBUG_LOG("enigmailMessengerOverlay.js: enigKeyRequestCallback: ETag: "+eTag+"\n");
 
1610
 
 
1611
  // NEED TO EXTRACT KEY ETC.
 
1612
}
 
1613
 
 
1614
 
 
1615
// handle a selected attachment (decrypt & open or save)
 
1616
function enigHandleAttachmentSel(actionType) {
 
1617
  DEBUG_LOG("enigmailMessengerOverlay.js: enigHandleAttachmentSel: actionType="+actionType+"\n");
 
1618
 
 
1619
  var attachmentList = document.getElementById('attachmentList');
 
1620
  var selectedAttachments = attachmentList.selectedItems;
 
1621
  var anAttachment = selectedAttachments[0].attachment;
 
1622
 
 
1623
  switch (actionType) {
 
1624
  case "saveAttachment":
 
1625
  case "openAttachment":
 
1626
  case "importKey":
 
1627
    enigHandleAttachment(actionType, anAttachment);
 
1628
  }
 
1629
}
 
1630
 
 
1631
 
 
1632
function enigHandleAttachment(actionType, anAttachment) {
 
1633
  DEBUG_LOG("enigmailMessengerOverlay.js: enigHandleAttachment: actionType="+actionType+", anAttachment(url)="+anAttachment.url+"\n");
 
1634
 
 
1635
  var ipcBuffer = Components.classes[ENIG_IPCBUFFER_CONTRACTID].createInstance(Components.interfaces.nsIIPCBuffer);
 
1636
 
 
1637
  var argumentsObj = { actionType: actionType,
 
1638
                       attachment: anAttachment,
 
1639
                       forceBrowser: false,
 
1640
                       ipcBuffer: ipcBuffer
 
1641
                     };
 
1642
 
 
1643
  var requestObserver = new EnigRequestObserver(enigDecryptAttachmentCallback,
 
1644
                                                argumentsObj);
 
1645
 
 
1646
  var ioServ = Components.classes[ENIG_IOSERVICE_CONTRACTID].getService(Components.interfaces.nsIIOService);
 
1647
 
 
1648
  ipcBuffer.open(ENIG_UNLIMITED_BUFFER_SIZE, false);
 
1649
  var msgUri = ioServ.newURI(argumentsObj.attachment.url, null, null);
 
1650
 
 
1651
  ipcBuffer.observe(requestObserver, msgUri);
 
1652
 
 
1653
  var channel = ioServ.newChannelFromURI(msgUri);
 
1654
 
 
1655
  var pipeFilter = Components.classes[ENIG_PIPEFILTERLISTENER_CONTRACTID].createInstance(Components.interfaces.nsIPipeFilterListener);
 
1656
 
 
1657
  pipeFilter.init(ipcBuffer, null,
 
1658
                "",
 
1659
                "",
 
1660
                0, false, false, null);
 
1661
 
 
1662
  var listener;
 
1663
  listener = pipeFilter;
 
1664
 
 
1665
  channel.asyncOpen(listener, msgUri);
 
1666
}
 
1667
 
 
1668
 
 
1669
function enigDecryptAttachmentCallback(callbackArg, ctxt) {
 
1670
  DEBUG_LOG("enigmailMessengerOverlay.js: enigDecryptAttachmentCallback: "+ctxt+"\n");
 
1671
 
 
1672
  if (callbackArg.ipcBuffer.overflowed) {
 
1673
    WARNING_LOG("enigmailMessengerOverlay.js: enigDecryptAttachmentCallback: MESSAGE BUFFER OVERFLOW\n");
 
1674
  }
 
1675
 
 
1676
  var exitCodeObj = new Object();
 
1677
  var statusFlagsObj = new Object();
 
1678
  var errorMsgObj= new Object();
 
1679
  var exitStatus = -1;
 
1680
 
 
1681
  var enigmailSvc =  GetEnigmailSvc();
 
1682
  var outFile;
 
1683
  var rawFileName=callbackArg.attachment.displayName.replace(/\.(asc|pgp|gpg)$/i,"");
 
1684
 
 
1685
  if (callbackArg.actionType == "saveAttachment") {
 
1686
    outFile = EnigFilePicker(EnigGetString("saveAttachmentHeader"),
 
1687
                                gEnigLastSaveDir, true, "",
 
1688
                                rawFileName, null);
 
1689
    if (! outFile) return;
 
1690
  }
 
1691
  else {
 
1692
    // open
 
1693
    var tmpDir = EnigGetTempDir();
 
1694
    try {
 
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");
 
1699
        return;
 
1700
      }
 
1701
      outFile.append(rawFileName);
 
1702
      outFile.createUnique(Components.interfaces.NORMAL_FILE_TYPE, 0600);
 
1703
    }
 
1704
    catch (ex) {
 
1705
      errorMsgObj.value=EnigGetString("noTempDir");
 
1706
      return;
 
1707
    }
 
1708
  }
 
1709
 
 
1710
  if (callbackArg.actionType == "importKey") {
 
1711
    try {
 
1712
      var dataLength = new Object();
 
1713
      var byteData = callbackArg.ipcBuffer.getByteData(dataLength);
 
1714
      exitStatus = enigmailSvc.importKey(parent, 0, byteData, "", errorMsgObj);
 
1715
    }
 
1716
    catch (ex) {}
 
1717
    if (exitStatus == 0) {
 
1718
      EnigLongAlert(EnigGetString("successKeyImport")+"\n\n"+errorMsgObj.value);
 
1719
    }
 
1720
    else {
 
1721
      EnigAlert(EnigGetString("failKeyImport")+"\n"+errorMsgObj.value);
 
1722
    }
 
1723
 
 
1724
    return;
 
1725
  }
 
1726
 
 
1727
  exitStatus=enigmailSvc.decryptAttachment(window, outFile,
 
1728
                                callbackArg.attachment.displayName,
 
1729
                                callbackArg.ipcBuffer,
 
1730
                                exitCodeObj, statusFlagsObj,
 
1731
                                errorMsgObj);
 
1732
 
 
1733
  callbackArg.ipcBuffer.shutdown();
 
1734
  if ((! exitStatus) || exitCodeObj.value != 0) {
 
1735
    exitStatus=false;
 
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"));
 
1740
      }
 
1741
      else {
 
1742
        EnigAlert(EnigGetString("decryptOkNoSig"));
 
1743
      }
 
1744
    }
 
1745
    else {
 
1746
      EnigAlert(EnigGetString("failedDecrypt")+"\n\n"+errorMsgObj.value);
 
1747
      exitStatus=false;
 
1748
    }
 
1749
  }
 
1750
  if (exitStatus) {
 
1751
    if (statusFlagsObj.value & nsIEnigmail.IMPORTED_KEY) {
 
1752
      EnigLongAlert(EnigGetString("successKeyImport")+"\n\n"+errorMsgObj.value);
 
1753
    }
 
1754
    else if (statusFlagsObj.value & nsIEnigmail.DISPLAY_MESSAGE) {
 
1755
      HandleSelectedAttachments('open');
 
1756
    }
 
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);
 
1765
        
 
1766
        try {
 
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);
 
1770
 
 
1771
          fileMimeInfo.launchWithFile(outFile);
 
1772
        }
 
1773
        catch (ex) {
 
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);
 
1777
        }
 
1778
      }
 
1779
 
 
1780
      // open the attachment using an external application
 
1781
      enigLoadExternalURL(outFileUri.asciiSpec);
 
1782
    }
 
1783
  }
 
1784
}
 
1785
 
 
1786
function enigLoadExternalURL(url) {
 
1787
  if (gEnigDecryptButton && gEnigDecryptButton.getAttribute("buttontype")=="seamonkey") {
 
1788
    EnigLoadURLInNavigatorWindow(url, true);
 
1789
  }
 
1790
  else {
 
1791
    messenger.launchExternalURL(url);
 
1792
  }
 
1793
}
 
1794
 
 
1795
 
 
1796
// handle double click events on Attachments
 
1797
function enigAttachmentListClick (elementId, event) {
 
1798
  DEBUG_LOG("enigmailMessengerOverlay.js: enigAttachmentListClick: event="+event+"\n");
 
1799
 
 
1800
  var attachment=event.target.attachment;
 
1801
  if (enigCheckEncryptedAttach(attachment)) {
 
1802
    if (event.button != 0) return;
 
1803
 
 
1804
    if (event.detail == 2) // double click
 
1805
      enigHandleAttachment("openAttachment", attachment);
 
1806
  }
 
1807
  else {
 
1808
    attachmentListClick(event);
 
1809
  }
 
1810
}
 
1811
 
 
1812
// download keys
 
1813
function enigHandleUnknownKey() {
 
1814
  var pubKeyId = "0x" + gEnigSecurityInfo.keyId.substr(8, 8);
 
1815
 
 
1816
  var mesg =  EnigGetString("pubKeyNeeded") + EnigGetString("keyImport",pubKeyId);
 
1817
 
 
1818
  if (EnigConfirm(mesg, EnigGetString("keyMan.button.import"))) {
 
1819
    var inputObj = {
 
1820
      searchList : [ pubKeyId ]
 
1821
    };
 
1822
    var resultObj = new Object();
 
1823
 
 
1824
    EnigDownloadKeys(inputObj, resultObj);
 
1825
 
 
1826
    if (resultObj.importedKeys > 0) {
 
1827
      enigMessageReload(false);
 
1828
    }
 
1829
  }
 
1830
}
 
1831
 
 
1832
function enigReceiveKeyCancel(progressBar) {
 
1833
  DEBUG_LOG("enigmailMessengerOverlay.js: enigReceiveKeyCancel\n");
 
1834
 
 
1835
  var keyRetrProcess = gEnigIpcRequest.pipeTransport;
 
1836
 
 
1837
  if (keyRetrProcess && !keyRetrProcess.isAttached()) {
 
1838
    keyRetrProcess.terminate();
 
1839
  }
 
1840
  gEnigIpcRequest.close(true);
 
1841
 
 
1842
  EnigAlert(EnigGetString("keyImportError")+ EnigGetString("failCancel"));
 
1843
 
 
1844
}
 
1845
 
 
1846