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

« back to all changes in this revision

Viewing changes to extensions/enigmail/package/enigmail.js

  • Committer: Package Import Robot
  • Author(s): Chris Coulson
  • Date: 2012-04-30 01:08:44 UTC
  • mfrom: (0.12.10)
  • Revision ID: package-import@ubuntu.com-20120430010844-i4a0z0d73kgrah49
Tags: 2:1.4.1-0ubuntu0.11.10.2
* New upstream release v1.4.1
  - LP: #987305
  - Fix LP: #968122 - localization messed up

Show diffs side-by-side

added added

removed removed

Lines of Context:
37
37
Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");
38
38
Components.utils.import("resource://gre/modules/AddonManager.jsm");
39
39
Components.utils.import("resource://enigmail/subprocess.jsm");
 
40
Components.utils.import("resource://enigmail/pipeConsole.jsm");
 
41
Components.utils.import("resource://gre/modules/ctypes.jsm");
40
42
 
41
43
// Maximum size of message directly processed by Enigmail
42
44
const MSG_BUFFER_SIZE = 98304;   // 96 kB
74
76
const ENIGMAIL_EXTENSION_ID = "{847b3a00-7ab1-11d4-8f02-006008948af5}";
75
77
 
76
78
// Contract IDs and CIDs used by this module
77
 
const NS_IPCSERVICE_CONTRACTID  = "@mozilla.org/process/ipc-service;1";
78
79
const NS_IPCBUFFER_CONTRACTID   = "@mozilla.org/ipc/ipc-buffer;1";
79
 
const NS_PIPECONSOLE_CONTRACTID = "@mozilla.org/process/pipe-console;1";
80
80
const NS_PIPETRANSPORT_CONTRACTID="@mozilla.org/ipc/pipe-transport;1";
81
81
const NS_PROCESS_UTIL_CONTRACTID = "@mozilla.org/process/util;1"
82
82
const NS_MSGCOMPOSESECURE_CONTRACTID = "@mozilla.org/messengercompose/composesecure;1";
112
112
const nsILocalFile           = Ci.nsILocalFile;
113
113
const nsILocalFileWin        = Ci.nsILocalFileWin;
114
114
const nsIProtocolHandler     = Ci.nsIProtocolHandler;
115
 
const nsIIPCService          = Ci.nsIIPCService;
116
 
const nsIPipeConsole         = Ci.nsIPipeConsole;
117
115
const nsIEnvironment         = Ci.nsIEnvironment;
118
116
const nsIEnigmail            = Ci.nsIEnigmail;
119
117
const nsIEnigStrBundle       = Ci.nsIStringBundleService;
170
168
                    INV_SGNR:                            0x100000000
171
169
};
172
170
 
173
 
var gCachedPassphrase = null;
174
 
var gCacheTimer = null;
175
 
 
176
171
///////////////////////////////////////////////////////////////////////////////
177
172
// File read/write operations
178
173
 
484
479
        contentData = "Enigmail error: invalid URI "+aURI.spec;
485
480
      }
486
481
 
487
 
      var channel = gEnigmailSvc.ipcService.newStringChannel(aURI,
488
 
                                                      contentType,
489
 
                                                      "UTF-8",
490
 
                                                      contentData);
 
482
      var channel =Ec.newStringChannel(aURI, contentType, "UTF-8", contentData);
491
483
 
492
484
      return channel;
493
485
    }
494
486
 
495
487
    if (aURI.spec == aURI.scheme+":dummy") {
496
488
      // Dummy PKCS7 content (to access mimeEncryptedClass)
497
 
      channel = gEnigmailSvc.ipcService.newStringChannel(aURI,
498
 
                                                         "message/rfc822",
499
 
                                                          "",
500
 
                                                          gDummyPKCS7);
 
489
      channel = Ec.newStringChannel(aURI, "message/rfc822", "", gDummyPKCS7);
501
490
      return channel;
502
491
    }
503
492
 
557
546
// Enigmail encryption/decryption service
558
547
///////////////////////////////////////////////////////////////////////////////
559
548
 
560
 
function GetPassphrase(domWindow, passwdObj, useAgentObj, rememberXTimes) {
561
 
  Ec.DEBUG_LOG("enigmail.js: GetPassphrase:\n");
562
 
 
563
 
  useAgentObj.value = false;
564
 
  try {
565
 
    var noPassphrase = gEnigmailSvc.prefBranch.getBoolPref("noPassphrase");
566
 
    useAgentObj.value = gEnigmailSvc.useGpgAgent();
567
 
 
568
 
    if (noPassphrase || useAgentObj.value) {
569
 
      passwdObj.value = "";
570
 
      return true;
571
 
    }
572
 
 
573
 
  }
574
 
  catch(ex) {}
575
 
 
576
 
  var maxIdleMinutes = gEnigmailSvc.getMaxIdleMinutes();
577
 
 
578
 
  if (gEnigmailSvc.haveCachedPassphrase()) {
579
 
    passwdObj.value = gCachedPassphrase;
580
 
 
581
 
    if (gEnigmailSvc._passwdAccessTimes > 0) {
582
 
      --gEnigmailSvc._passwdAccessTimes;
583
 
 
584
 
      if (gEnigmailSvc._passwdAccessTimes <= 0 && maxIdleMinutes <= 0) {
585
 
        gEnigmailSvc.clearCachedPassphrase();
586
 
      }
587
 
    }
588
 
    return true;
589
 
  }
590
 
 
591
 
  // Obtain password interactively
592
 
  var checkObj = new Object();
593
 
 
594
 
  var promptMsg = Ec.getString("enterPassOrPin");
595
 
  passwdObj.value = "";
596
 
  checkObj.value = true;
597
 
 
598
 
  var checkMsg = (maxIdleMinutes>0) ? Ec.getString("rememberPass", [ maxIdleMinutes ]) : "";
599
 
 
600
 
  var success;
601
 
 
602
 
  var promptService = Cc[NS_PROMPTSERVICE_CONTRACTID].getService(Ci.nsIPromptService);
603
 
  success = promptService.promptPassword(domWindow,
604
 
                                         Ec.getString("enigPrompt"),
605
 
                                         promptMsg,
606
 
                                         passwdObj,
607
 
                                         checkMsg,
608
 
                                         checkObj);
609
 
 
610
 
  if (!success)
611
 
    return false;
612
 
 
613
 
  Ec.DEBUG_LOG("enigmail.js: GetPassphrase: got passphrase\n");
614
 
 
615
 
  // remember the passphrase for accessing serveral times in a sequence
616
 
 
617
 
  if (rememberXTimes) gEnigmailSvc._passwdAccessTimes = rememberXTimes;
618
 
 
619
 
  // Remember passphrase only if necessary
620
 
  if ((checkObj.value && (maxIdleMinutes > 0)) || rememberXTimes)
621
 
    gEnigmailSvc.setCachedPassphrase(passwdObj.value, rememberXTimes);
622
 
 
623
 
  return true;
624
 
}
625
 
 
626
549
// Remove all quoted strings (and angle brackets) from a list of email
627
550
// addresses, returning a list of pure email address
628
551
function EnigStripEmail(mailAddrs) {
690
613
  isOs2    : false,
691
614
  isDosLike: false,
692
615
 
693
 
  ipcService: null,
694
616
  prefBranch: null,
695
 
  console:    null,
696
617
  keygenProcess: null,  // TODO: remove me
697
618
  keygenConsole: null,
698
619
 
704
625
  rulesList: null,
705
626
  gpgAgentInfo: {preStarted: false, envStr: ""},
706
627
 
707
 
  _lastActiveTime: 0,
708
 
  _passwdAccessTimes: 0,
709
628
  _messageIdList: {},
710
629
  _xpcom_factory: {
711
630
    createInstance: function (aOuter, iid) {
723
642
  observe: function (aSubject, aTopic, aData) {
724
643
    Ec.DEBUG_LOG("enigmail.js: Enigmail.observe: topic='"+aTopic+"' \n");
725
644
 
726
 
    if (aTopic == "timer-callback") {
727
 
      // Cause cached password to expire, if need be
728
 
      if (!this.haveCachedPassphrase()) {
729
 
        // No cached password; cancel repeating timer
730
 
        if (gCacheTimer)
731
 
          gCacheTimer.cancel();
732
 
      }
733
 
 
734
 
    } else if (aTopic == NS_XPCOM_SHUTDOWN_OBSERVER_ID) {
 
645
    if (aTopic == NS_XPCOM_SHUTDOWN_OBSERVER_ID) {
735
646
      // XPCOM shutdown
736
647
      this.finalize();
737
648
 
792
703
    return promptService.alert(domWindow, Ec.getString("enigError"), mesg);
793
704
  },
794
705
 
795
 
  getMaxIdleMinutes: function () {
796
 
    var maxIdleMinutes = 5;
797
 
    try {
798
 
      maxIdleMinutes = this.prefBranch.getIntPref("maxIdleMinutes");
799
 
    } catch (ex) {
800
 
    }
801
 
 
802
 
    return maxIdleMinutes;
803
 
  },
804
 
 
805
706
  getLogDirectoryPrefix: function () {
806
707
    var logDirectory = "";
807
708
    try {
817
718
    return dirPrefix;
818
719
  },
819
720
 
820
 
  getExtensionBaseDir: function () {
821
 
    var file = null;
822
 
    var isComplete = false;
823
 
    AddonManager.getAddonByID(ENIGMAIL_EXTENSION_ID, function (addon) {
824
 
      try {
825
 
        file = addon.getResourceURI(".").QueryInterface(Ci.nsIFileURL).file;
826
 
      }
827
 
      catch (ex) {
828
 
        Ec.ERROR_LOG("enigmail.js: getExtensionBaseDir: "+ex+"\n");
829
 
      }
830
 
      isComplete = true;
831
 
    });
832
 
    var thread = Cc["@mozilla.org/thread-manager;1"]
833
 
                 .getService(Ci.nsIThreadManager)
834
 
                 .currentThread;
835
 
    while (!isComplete)
836
 
      thread.processNextEvent(true);
837
 
 
838
 
    return file;
839
 
  },
840
 
 
841
 
  stillActive: function () {
842
 
    Ec.DEBUG_LOG("enigmail.js: Enigmail.stillActive: \n");
843
 
 
844
 
    // Update last active time
845
 
    var curDate = new Date();
846
 
    this._lastActiveTime = curDate.getTime();
847
 
  //  Ec.DEBUG_LOG("enigmail.js: Enigmail.stillActive: _lastActiveTime="+this._lastActiveTime+"\n");
848
 
  },
849
 
 
850
 
 
851
 
  clearCachedPassphrase: function () {
852
 
    Ec.DEBUG_LOG("enigmail.js: Enigmail.clearCachedPassphrase: \n");
853
 
 
854
 
    gCachedPassphrase = null;
855
 
  },
856
 
 
857
 
  setCachedPassphrase: function (passphrase) {
858
 
    Ec.DEBUG_LOG("enigmail.js: Enigmail.setCachedPassphrase: \n");
859
 
 
860
 
    gCachedPassphrase = passphrase;
861
 
    this.stillActive();
862
 
 
863
 
    var maxIdleMinutes = this.getMaxIdleMinutes();
864
 
 
865
 
    var createTimerType = null;
866
 
    const nsITimer = Ci.nsITimer;
867
 
 
868
 
    if (this.haveCachedPassphrase() && (this._passwdAccessTimes > 0) && (maxIdleMinutes <= 0)) {
869
 
      // we remember the passphrase for at most 1 minute
870
 
      createTimerType = nsITimer.TYPE_ONE_SHOT;
871
 
      maxIdleMinutes = 1;
872
 
    }
873
 
    else if (this.haveCachedPassphrase() && (maxIdleMinutes > 0)) {
874
 
      createTimerType = nsITimer.TYPE_REPEATING_SLACK;
875
 
    }
876
 
 
877
 
    if (createTimerType != null) {
878
 
      // Start timer
879
 
      if (gCacheTimer)
880
 
        gCacheTimer.cancel();
881
 
 
882
 
      var delayMillisec = maxIdleMinutes*60*1000;
883
 
 
884
 
      gCacheTimer = Cc[NS_TIMER_CONTRACTID].createInstance(nsITimer);
885
 
 
886
 
      if (!gCacheTimer) {
887
 
        Ec.ERROR_LOG("enigmail.js: Enigmail.setCachedPassphrase: Error - failed to create timer\n");
888
 
        throw Components.results.NS_ERROR_FAILURE;
889
 
      }
890
 
 
891
 
      gCacheTimer.init(this, delayMillisec,
892
 
                        createTimerType);
893
 
 
894
 
      Ec.DEBUG_LOG("enigmail.js: Enigmail.setCachedPassphrase: gCacheTimer="+gCacheTimer+"\n");
895
 
    }
896
 
  },
897
 
 
898
 
  haveCachedPassphrase: function () {
899
 
    Ec.DEBUG_LOG("enigmail.js: Enigmail.haveCachedPassphrase: \n");
900
 
 
901
 
    var havePassphrase = ((typeof gCachedPassphrase) == "string");
902
 
 
903
 
    if (!havePassphrase)
904
 
      return false;
905
 
 
906
 
    var curDate = new Date();
907
 
    var currentTime = curDate.getTime();
908
 
 
909
 
    var maxIdleMinutes = this.getMaxIdleMinutes();
910
 
    var delayMillisec = maxIdleMinutes*60*1000;
911
 
 
912
 
    var expired = ((currentTime - this._lastActiveTime) >= delayMillisec);
913
 
 
914
 
  //  Ec.DEBUG_LOG("enigmail.js: Enigmail.haveCachedPassphrase: ")
915
 
  //  Ec.DEBUG_LOG("currentTime="+currentTime+", _lastActiveTime="+this._lastActiveTime+", expired="+expired+"\n");
916
 
 
917
 
    if (expired && (this._passwdAccessTimes <= 0)) {
918
 
      // Too much idle time; forget cached password
919
 
      gCachedPassphrase = null;
920
 
      havePassphrase = false;
921
 
 
922
 
      Ec.WRITE_LOG("enigmail.js: Enigmail.haveCachedPassphrase: CACHE IDLED OUT\n");
923
 
    }
924
 
 
925
 
    return havePassphrase;
926
 
  },
927
 
 
928
721
 
929
722
  finalize: function () {
930
723
    Ec.DEBUG_LOG("enigmail.js: Enigmail.finalize:\n");
933
726
    if (this.gpgAgentProcess != null) {
934
727
      Ec.DEBUG_LOG("enigmail.js: Enigmail.finalize: stopping gpg-agent PID="+this.gpgAgentProcess+"\n");
935
728
      try {
936
 
        var extensionLoc = this.getExtensionBaseDir();
937
 
        extensionLoc.append("wrappers");
938
 
        extensionLoc.append("gpg-agent-wrapper.sh");
939
 
        try {
940
 
          extensionLoc.permissions=0755;
941
 
        }
942
 
        catch(ex) {}
943
 
 
944
 
        agentProcess = Cc[NS_PROCESS_UTIL_CONTRACTID].createInstance(Ci.nsIProcess);
945
 
        agentProcess.init(extensionLoc);
946
 
        agentProcess.run(true, [ "stop", this.gpgAgentProcess ], 2);
 
729
        var libName=subprocess.getPlatformValue(0);
 
730
        var libc = ctypes.open(libName);
 
731
 
 
732
        //int kill(pid_t pid, int sig);
 
733
        var kill = libc.declare("kill",
 
734
                              ctypes.default_abi,
 
735
                              ctypes.int,
 
736
                              ctypes.int32_t,
 
737
                              ctypes.int);
 
738
 
 
739
        kill(parseInt(this.gpgAgentProcess), 15);
947
740
      }
948
741
      catch (ex) {
 
742
        Ec.ERROR_LOG("enigmail.js: Enigmail.finalize ERROR: "+ex+"\n");
949
743
      }
950
744
    }
951
745
 
954
748
      this.logFileStream = null;
955
749
    }
956
750
 
957
 
    if (this.console) {
958
 
      this.console.shutdown();
959
 
      this.console = null;
960
 
    }
961
 
 
962
751
    gLogLevel = 3;
963
752
    this.initializationError = "";
964
753
    this.initializationAttempted = false;
1020
809
    Ec.initialize(this, gLogLevel);
1021
810
    this.version = version;
1022
811
 
1023
 
    subprocess.registerLogHandler(function(txt) { Ec.ERROR_LOG("subprocess.jsm: "+txt) });
1024
 
    if (gLogLevel > 4) {
1025
 
      subprocess.registerDebugHandler(function(txt) { Ec.DEBUG_LOG("subprocess.jsm: "+txt) });
1026
 
    }
1027
 
 
1028
812
    Ec.DEBUG_LOG("enigmail.js: Enigmail version "+this.version+"\n");
1029
813
    Ec.DEBUG_LOG("enigmail.js: OS/CPU="+this.oscpu+"\n");
1030
814
    Ec.DEBUG_LOG("enigmail.js: Platform="+this.platform+"\n");
1051
835
      Ec.WARNING_LOG("enigmail.js: Enigmail: gLogLevel="+gLogLevel+"\n");
1052
836
    }
1053
837
 
 
838
    subprocess.registerLogHandler(function(txt) { Ec.ERROR_LOG("subprocess.jsm: "+txt) });
 
839
 
 
840
    matches = nspr_log_modules.match(/subprocess:(\d+)/);
 
841
    if (matches && (matches.length > 1)) {
 
842
      if (matches[1] > 2) subprocess.registerDebugHandler(function(txt) { Ec.DEBUG_LOG("subprocess.jsm: "+txt) });
 
843
    }
 
844
 
 
845
 
1054
846
    // Initialize global environment variables list
1055
847
    var passEnv = [ "GNUPGHOME", "GPGDIR", "ETC",
1056
848
                    "ALLUSERSPROFILE", "APPDATA", "BEGINLIBPATH",
1083
875
    Ec.DEBUG_LOG("enigmail.js: Enigmail.initialize: Ec.envList = "+Ec.envList+"\n");
1084
876
 
1085
877
    try {
1086
 
      // Access IPC Service
1087
 
 
1088
 
      var ipcService = Cc[NS_IPCSERVICE_CONTRACTID].getService();
1089
 
      ipcService = ipcService.QueryInterface(nsIIPCService);
1090
 
 
1091
 
      this.ipcService = ipcService;
1092
 
 
1093
 
      // Create a non-joinable console
1094
 
      var pipeConsole = Cc[NS_PIPECONSOLE_CONTRACTID].createInstance(nsIPipeConsole);
1095
 
 
1096
 
      pipeConsole.open(499, 0, false);
1097
 
 
1098
 
      this.console = pipeConsole;
1099
 
 
1100
 
      pipeConsole.write("Initializing Enigmail service ...\n");
 
878
      EnigmailConsole.write("Initializing Enigmail service ...\n");
1101
879
 
1102
880
    } catch (ex) {
1103
881
      this.initializationError = Ec.getString("enigmimeNotAvail");
1124
902
 
1125
903
    obsServ.addObserver(this, NS_XPCOM_SHUTDOWN_OBSERVER_ID, false);
1126
904
 
1127
 
    this.stillActive();
 
905
    Ec.stillActive();
1128
906
    this.initialized = true;
1129
907
 
1130
908
    Ec.DEBUG_LOG("enigmail.js: Enigmail.initialize: END\n");
1150
928
    this.initialized = false;
1151
929
    this.initializationAttempted = true;
1152
930
 
1153
 
    this.console.write("Reinitializing Enigmail service ...\n");
 
931
    EnigmailConsole.write("Reinitializing Enigmail service ...\n");
1154
932
    this.setAgentPath();
1155
933
    this.initialized = true;
1156
934
  },
1454
1232
        if ((! this.isDosLike) && (this.agentVersion < "2.1" )) {
1455
1233
          args = [ "--sh", "--no-use-standard-socket",
1456
1234
                  "--daemon",
1457
 
                  "--default-cache-ttl", (this.getMaxIdleMinutes()*60).toString(),
 
1235
                  "--default-cache-ttl", (Ec.getMaxIdleMinutes()*60).toString(),
1458
1236
                  "--max-cache-ttl", "999999" ];  // ca. 11 days
1459
1237
 
1460
1238
          try {
1494
1272
          initPath(envFile, this.determineGpgHomeDir());
1495
1273
          envFile.append("gpg-agent.conf");
1496
1274
 
1497
 
          var data="default-cache-ttl " + (this.getMaxIdleMinutes()*60)+"\n";
 
1275
          var data="default-cache-ttl " + (Ec.getMaxIdleMinutes()*60)+"\n";
1498
1276
          data += "max-cache-ttl 999999";
1499
1277
          if (! envFile.exists()) {
1500
1278
            try {
1517
1295
  },
1518
1296
 
1519
1297
 
1520
 
  passwdCommand: function () {
1521
 
 
1522
 
    var commandArgs = [];
1523
 
 
1524
 
    try {
1525
 
      var  gpgVersion = this.agentVersion.match(/^\d+\.\d+/);
1526
 
      if (this.useGpgAgent()) {
1527
 
         commandArgs.push("--use-agent");
1528
 
      }
1529
 
      else {
1530
 
        if (! gEnigmailSvc.prefBranch.getBoolPref("noPassphrase")) {
1531
 
          commandArgs.push("--passphrase-fd");
1532
 
          commandArgs.push("0");
1533
 
          if (gpgVersion && gpgVersion[0] >= "1.1") {
1534
 
            commandArgs.push("--no-use-agent");
1535
 
          }
1536
 
        }
1537
 
      }
1538
 
    } catch (ex) {}
1539
 
 
1540
 
    return commandArgs;
1541
 
  },
1542
 
 
1543
 
  /***
1544
 
   * determine if a password is required to be sent to GnuPG
1545
 
   */
1546
 
  requirePassword: function () {
1547
 
    if (this.useGpgAgent()) {
1548
 
      return false;
1549
 
    }
1550
 
 
1551
 
    return (! gEnigmailSvc.prefBranch.getBoolPref("noPassphrase"));
1552
 
  },
1553
 
 
1554
1298
  simpleExecCmd: function (command, args, exitCodeObj, errorMsgObj) {
1555
1299
    Ec.WRITE_LOG("enigmail.js: Enigmail.simpleExecCmd: command = "+command+" "+args.join(" ")+"\n");
1556
1300
 
1569
1313
    var outputData = "";
1570
1314
    var errOutput  = "";
1571
1315
 
1572
 
    Ec.CONSOLE_LOG("\nenigmail> "+Ec.printCmdLine(command, args)+"\n");
 
1316
    Ec.CONSOLE_LOG("enigmail> "+Ec.printCmdLine(command, args)+"\n");
1573
1317
 
1574
1318
    try {
1575
1319
      subprocess.call({
1601
1345
    Ec.DEBUG_LOG("enigmail.js: Enigmail.simpleExecCmd: exitCode = "+exitCodeObj.value+"\n");
1602
1346
    Ec.DEBUG_LOG("enigmail.js: Enigmail.simpleExecCmd: errOutput = "+errOutput+"\n");
1603
1347
 
1604
 
    this.stillActive();
 
1348
    Ec.stillActive();
1605
1349
 
1606
1350
    return outputData;
1607
1351
  },
1644
1388
 
1645
1389
    var blockSeparationObj = new Object();
1646
1390
 
1647
 
    Ec.CONSOLE_LOG("\nenigmail> "+Ec.printCmdLine(command, args)+"\n");
 
1391
    Ec.CONSOLE_LOG("enigmail> "+Ec.printCmdLine(command, args)+"\n");
1648
1392
 
1649
1393
    var proc = {
1650
1394
      command:     command,
1697
1441
 
1698
1442
    Ec.CONSOLE_LOG(errorMsgObj.value+"\n");
1699
1443
 
1700
 
    this.stillActive();
 
1444
    Ec.stillActive();
1701
1445
 
1702
1446
    return outputData;
1703
1447
  },
1715
1459
    var useAgentObj = {value: false};
1716
1460
 
1717
1461
    if (needPassphrase) {
1718
 
      args = args.concat(this.passwdCommand());
 
1462
      args = args.concat(Ec.passwdCommand());
1719
1463
 
1720
1464
      var passwdObj = new Object();
1721
1465
 
1722
 
      if (!GetPassphrase(domWindow, passwdObj, useAgentObj, 0)) {
 
1466
      if (!Ec.getPassphrase(domWindow, passwdObj, useAgentObj, 0)) {
1723
1467
         Ec.ERROR_LOG("enigmail.js: Enigmail.execStart: Error - no passphrase supplied\n");
1724
1468
 
1725
1469
         statusFlagsObj.value |= nsIEnigmail.MISSING_PASSPHRASE;
1738
1482
      Ec.DEBUG_LOG("enigmail.js: Enigmail.execStart: copied command line/env to files "+prefix+"enigcmd.txt/enigenv.txt\n");
1739
1483
    }
1740
1484
 
1741
 
    Ec.CONSOLE_LOG("\nenigmail> "+Ec.printCmdLine(command, args)+"\n");
 
1485
    Ec.CONSOLE_LOG("enigmail> "+Ec.printCmdLine(command, args)+"\n");
1742
1486
 
1743
1487
    var pipetrans = Cc[NS_PIPETRANSPORT_CONTRACTID].createInstance();
1744
1488
 
1763
1507
        // Write to child STDIN
1764
1508
        // (ignore errors, because child may have exited already, closing STDIN)
1765
1509
        try {
1766
 
          if (this.requirePassword()) {
 
1510
          if (Ec.requirePassword()) {
1767
1511
             pipetrans.writeSync(passphrase, passphrase.length);
1768
1512
             pipetrans.writeSync("\n", 1);
1769
1513
          }
1826
1570
 
1827
1571
    Ec.CONSOLE_LOG(Ec.convertFromUnicode(errorMsgObj.value)+"\n");
1828
1572
 
1829
 
    this.stillActive();
 
1573
    Ec.stillActive();
1830
1574
 
1831
1575
    return exitCode;
1832
1576
  },
1993
1737
 
1994
1738
    if (statusFlagsObj.value & nsIEnigmail.BAD_PASSPHRASE) {
1995
1739
      // "Unremember" passphrase on error return
1996
 
      this.clearCachedPassphrase();
 
1740
      Ec.clearCachedPassphrase();
1997
1741
    }
1998
1742
 
1999
1743
    if (statusFlagsObj.value & nsIEnigmail.BAD_PASSPHRASE) {
2168
1912
      var passwdObj   = new Object();
2169
1913
      var useAgentObj = new Object();
2170
1914
      // Get the passphrase and remember it for the next 2 subsequent calls to gpg
2171
 
      if (!GetPassphrase(null, passwdObj, useAgentObj, 2)) {
 
1915
      if (!Ec.getPassphrase(null, passwdObj, useAgentObj, 2)) {
2172
1916
        Ec.ERROR_LOG("enigmail.js: Enigmail.determineHashAlgorithm: Error - no passphrase supplied\n");
2173
1917
 
2174
1918
        return 3;
2214
1958
        // Abormal return
2215
1959
        if (statusFlagsObj.value & nsIEnigmail.BAD_PASSPHRASE) {
2216
1960
          // "Unremember" passphrase on error return
2217
 
          this.clearCachedPassphrase();
 
1961
          Ec.clearCachedPassphrase();
2218
1962
          errorMsgObj.value = Ec.getString("badPhrase");
2219
1963
        }
2220
1964
        this.alertMsg(null, errorMsgObj.value);
2491
2235
      RegExp.multiline = false;
2492
2236
    }
2493
2237
 
 
2238
    // HACK to better support messages from Outlook: if there are empty lines, drop them
 
2239
    if (pgpBlock.search(/MESSAGE-----\r?\n\r?\nVersion/) >=0) {
 
2240
      Ec.DEBUG_LOG("enigmail.js: Enigmail.decryptMessage: apply Outlook empty line workaround\n");
 
2241
      pgpBlock = pgpBlock.replace( /\r?\n\r?\n/g, "\n" );
 
2242
    }
 
2243
 
2494
2244
    var head = cipherText.substr(0, beginIndexObj.value);
2495
2245
    var tail = cipherText.substr(endIndexObj.value+1,
2496
2246
                                 cipherText.length - endIndexObj.value - 1);
2932
2682
 
2933
2683
    if (statusFlagsObj.value & nsIEnigmail.BAD_PASSPHRASE) {
2934
2684
      // "Unremember" passphrase on decryption failure
2935
 
      this.clearCachedPassphrase();
 
2685
      Ec.clearCachedPassphrase();
2936
2686
    }
2937
2687
 
2938
2688
    var pubKeyId;
3420
3170
    var signMessage = (sendFlags & nsIEnigmail.SEND_SIGNED);
3421
3171
 
3422
3172
    if (signMessage ) {
3423
 
      args = args.concat(this.passwdCommand());
 
3173
      args = args.concat(Ec.passwdCommand());
3424
3174
 
3425
3175
      var passwdObj = new Object();
3426
3176
      var useAgentObj = new Object();
3427
3177
 
3428
 
      if (!GetPassphrase(parent, passwdObj, useAgentObj, 0)) {
 
3178
      if (!Ec.getPassphrase(parent, passwdObj, useAgentObj, 0)) {
3429
3179
         Ec.ERROR_LOG("enigmail.js: Enigmail.encryptAttachment: Error - no passphrase supplied\n");
3430
3180
 
3431
3181
         statusFlagsObj.value |= nsIEnigmail.MISSING_PASSPHRASE;
3467
3217
    Ec.DEBUG_LOG("enigmail.js: Enigmail.getAttachmentFileName\n");
3468
3218
 
3469
3219
    var args = Ec.getAgentArgs(true);
3470
 
    args = args.concat(this.passwdCommand());
 
3220
    args = args.concat(Ec.passwdCommand());
3471
3221
    args.push("--list-packets");
3472
3222
 
3473
3223
    var passphrase = null;
3474
3224
    var passwdObj = new Object();
3475
3225
    var useAgentObj = new Object();
3476
3226
 
3477
 
    if (!GetPassphrase(parent, passwdObj, useAgentObj, 0)) {
 
3227
    if (!Ec.getPassphrase(parent, passwdObj, useAgentObj, 0)) {
3478
3228
      Ec.ERROR_LOG("enigmail.js: Enigmail.getAttachmentFileName: Error - no passphrase supplied\n");
3479
3229
      return null;
3480
3230
    }
3501
3251
    }
3502
3252
 
3503
3253
    try {
3504
 
      if (this.requirePassword()) {
 
3254
      if (Ec.requirePassword()) {
3505
3255
        pipeTrans.writeSync(passphrase, passphrase.length);
3506
3256
        pipeTrans.writeSync("\n", 1);
3507
3257
      }
3605
3355
 
3606
3356
    var args = Ec.getAgentArgs(true);
3607
3357
    args = args.concat(["-o", outFileName, "--yes"]);
3608
 
    args = args.concat(this.passwdCommand());
 
3358
    args = args.concat(Ec.passwdCommand());
3609
3359
    args.push("-d");
3610
3360
 
3611
3361
 
3615
3365
    var passwdObj = new Object();
3616
3366
    var useAgentObj = new Object();
3617
3367
 
3618
 
    if (!GetPassphrase(parent, passwdObj, useAgentObj, 0)) {
 
3368
    if (!Ec.getPassphrase(parent, passwdObj, useAgentObj, 0)) {
3619
3369
      Ec.ERROR_LOG("enigmail.js: Enigmail.decryptAttachment: Error - no passphrase supplied\n");
3620
3370
 
3621
3371
      statusFlagsObj.value |= nsIEnigmail.MISSING_PASSPHRASE;
3636
3386
    }
3637
3387
 
3638
3388
    try {
3639
 
      if (this.requirePassword()) {
 
3389
      if (Ec.requirePassword()) {
3640
3390
        pipeTrans.writeSync(passphrase, passphrase.length);
3641
3391
        pipeTrans.writeSync("\n", 1);
3642
3392
      }
3858
3608
    this.rulesList = null;
3859
3609
  },
3860
3610
 
3861
 
  signKey: function (parent, userId, keyId, signLocally, trustLevel, errorMsgObj) {
3862
 
    Ec.DEBUG_LOG("enigmail.js: Enigmail.signKey: trustLevel="+trustLevel+", userId="+userId+", keyId="+keyId+"\n");
3863
 
    var r = this.editKey(parent, true, userId, keyId,
3864
 
                        (signLocally ? "lsign" : "sign"),
3865
 
                        { trustLevel: trustLevel},
3866
 
                        signKeyCallback,
3867
 
                        null,
3868
 
                        errorMsgObj);
3869
 
    this.stillActive();
3870
 
 
3871
 
    return r;
3872
 
  },
3873
 
 
3874
 
  setKeyTrust: function (parent, keyId, trustLevel, errorMsgObj) {
3875
 
    Ec.DEBUG_LOG("enigmail.js: Enigmail.setKeyTrust: trustLevel="+trustLevel+", keyId="+keyId+"\n");
3876
 
 
3877
 
    return this.editKey(parent, false, null, keyId, "trust",
3878
 
                        { trustLevel: trustLevel},
3879
 
                        keyTrustCallback,
3880
 
                        null,
3881
 
                        errorMsgObj);
3882
 
  },
3883
 
 
3884
3611
  genRevokeCert: function (parent, keyId, outFile, reasonCode, reasonText, errorMsgObj) {
3885
3612
    Ec.DEBUG_LOG("enigmail.js: Enigmail.genRevokeCert: keyId="+keyId+"\n");
3886
3613
 
3891
3618
                        revokeCertCallback,
3892
3619
                        null,
3893
3620
                        errorMsgObj);
3894
 
    this.stillActive();
 
3621
    Ec.stillActive();
3895
3622
 
3896
3623
    return r;
3897
3624
  },
3907
3634
                        addUidCallback,
3908
3635
                        null,
3909
3636
                        errorMsgObj);
3910
 
    this.stillActive();
 
3637
    Ec.stillActive();
3911
3638
 
3912
3639
    return r;
3913
3640
  },
3921
3648
                        deleteKeyCallback,
3922
3649
                        null,
3923
3650
                        errorMsgObj);
3924
 
    this.stillActive();
 
3651
    Ec.stillActive();
3925
3652
 
3926
3653
    return r;
3927
3654
  },
3939
3666
                        changePassphraseCallback,
3940
3667
                        pwdObserver,
3941
3668
                        errorMsgObj);
3942
 
    this.stillActive();
 
3669
    Ec.stillActive();
3943
3670
 
3944
3671
    return r;
3945
3672
  },
3956
3683
                        revokeSubkeyCallback,
3957
3684
                        null,
3958
3685
                        errorMsgObj);
3959
 
    this.stillActive();
 
3686
    Ec.stillActive();
3960
3687
 
3961
3688
    return r;
3962
3689
  },
3970
3697
                        null,
3971
3698
                        null,
3972
3699
                        errorMsgObj);
3973
 
    this.stillActive();
 
3700
    Ec.stillActive();
3974
3701
 
3975
3702
    return r;
3976
3703
  },
3983
3710
                        setPrimaryUidCallback,
3984
3711
                        null,
3985
3712
                        errorMsgObj);
3986
 
    this.stillActive();
 
3713
    Ec.stillActive();
3987
3714
 
3988
3715
    return r;
3989
3716
  },
3997
3724
                        deleteUidCallback,
3998
3725
                        null,
3999
3726
                        errorMsgObj);
4000
 
    this.stillActive();
 
3727
    Ec.stillActive();
4001
3728
 
4002
3729
    return r;
4003
3730
  },
4011
3738
                        revokeUidCallback,
4012
3739
                        null,
4013
3740
                        errorMsgObj);
4014
 
    this.stillActive();
 
3741
    Ec.stillActive();
4015
3742
 
4016
3743
    return r;
4017
3744
  },
4026
3753
                        addPhotoCallback,
4027
3754
                        null,
4028
3755
                        errorMsgObj);
4029
 
    this.stillActive();
 
3756
    Ec.stillActive();
4030
3757
 
4031
3758
    return r;
4032
3759
  },
4104
3831
    var useAgentObj = new Object();
4105
3832
 
4106
3833
    if (needPassphrase) {
4107
 
      args=args.concat(this.passwdCommand());
 
3834
      args=args.concat(Ec.passwdCommand());
4108
3835
 
4109
3836
      var passwdObj = new Object();
4110
3837
 
4111
 
      if (!GetPassphrase(parent, passwdObj, useAgentObj, 0)) {
 
3838
      if (!Ec.getPassphrase(parent, passwdObj, useAgentObj, 0)) {
4112
3839
         Ec.ERROR_LOG("enigmail.js: Enigmail.editKey: Error - no passphrase supplied\n");
4113
3840
 
4114
3841
         errorMsgObj.value = Ec.getString("noPassphrase");
4149
3876
    }
4150
3877
 
4151
3878
    var pipeTrans = this.execStart(this.agentPath, args, false, parent, null, null,
4152
 
                                   true, statusFlags);
 
3879
                                   statusFlags);
4153
3880
    if (! pipeTrans) return -1;
4154
3881
 
4155
 
    if (needPassphrase && this.requirePassword()) {
 
3882
    if (needPassphrase && Ec.requirePassword()) {
4156
3883
      try {
4157
3884
        pipeTrans.writeSync(passphrase, passphrase.length);
4158
3885
        pipeTrans.writeSync("\n", 1);
4192
3919
      break;
4193
3920
    case -2:
4194
3921
      errorMsgObj.value=Ec.getString("badPhrase");
4195
 
      this.clearCachedPassphrase();
 
3922
      Ec.clearCachedPassphrase();
4196
3923
    default:
4197
3924
      exitCode = returnCode;
4198
3925
    }
4326
4053
  }
4327
4054
};
4328
4055
 
4329
 
function signKeyCallback(inputData, keyEdit, ret) {
4330
 
 
4331
 
  ret.writeTxt = "";
4332
 
  ret.errorMsg = "";
4333
 
 
4334
 
  if (keyEdit.doCheck(GET_BOOL, "sign_uid.okay" )) {
4335
 
    ret.exitCode = 0;
4336
 
    ret.writeTxt = "Y";
4337
 
  }
4338
 
  else if (keyEdit.doCheck(GET_BOOL, "keyedit.sign_all.okay" )) {
4339
 
    ret.exitCode = 0;
4340
 
    ret.writeTxt = "Y";
4341
 
  }
4342
 
  else if (keyEdit.doCheck(GET_LINE, "sign_uid.expire" )) {
4343
 
    ret.exitCode = 0;
4344
 
    ret.writeTxt = "0";
4345
 
  }
4346
 
  else if (keyEdit.doCheck(GET_LINE, "trustsig_prompt.trust_value" )) {
4347
 
    ret.exitCode = 0;
4348
 
    ret.writeTxt = "0";
4349
 
  }
4350
 
  else if (keyEdit.doCheck(GET_LINE, "trustsig_prompt.trust_depth" )) {
4351
 
    ret.exitCode = 0;
4352
 
    ret.writeTxt = "";}
4353
 
  else if (keyEdit.doCheck(GET_LINE, "trustsig_prompt.trust_regexp" )) {
4354
 
    ret.exitCode = 0;
4355
 
    ret.writeTxt = "0";}
4356
 
  else if (keyEdit.doCheck(GET_LINE, "siggen.valid" )) {
4357
 
    ret.exitCode = 0;
4358
 
    ret.writeTxt = "0";
4359
 
  }
4360
 
  else if (keyEdit.doCheck(GET_BOOL, "sign_uid.local_promote_okay" )) {
4361
 
    ret.exitCode = 0;
4362
 
    ret.writeTxt = "Y";
4363
 
  }
4364
 
  else if (keyEdit.doCheck(GET_LINE, "sign_uid.class" )) {
4365
 
    ret.exitCode = 0;
4366
 
    ret.writeTxt = new String(inputData.trustLevel);
4367
 
  }
4368
 
  else if (keyEdit.doCheck(GET_HIDDEN, "passphrase.adminpin.ask")) {
4369
 
    GetPin(inputData.parent, Ec.getString("enterAdminPin"), ret);
4370
 
  }
4371
 
  else if (keyEdit.doCheck(GET_HIDDEN, "passphrase.pin.ask")) {
4372
 
    GetPin(inputData.parent, Ec.getString("enterCardPin"), ret);
4373
 
  }
4374
 
  else if (keyEdit.doCheck(GET_LINE, "keyedit.prompt")) {
4375
 
    ret.exitCode = 0;
4376
 
    ret.quitNow = true;
4377
 
  }
4378
 
  else {
4379
 
    ret.quitNow=true;
4380
 
    Ec.ERROR_LOG("Unknown command prompt: "+keyEdit.getText()+"\n");
4381
 
    ret.exitCode=-1;
4382
 
  }
4383
 
}
4384
 
 
4385
 
function keyTrustCallback(inputData, keyEdit, ret) {
4386
 
  ret.writeTxt = "";
4387
 
  ret.errorMsg = "";
4388
 
 
4389
 
  if (keyEdit.doCheck(GET_LINE, "edit_ownertrust.value" )) {
4390
 
    ret.exitCode = 0;
4391
 
    ret.writeTxt = new String(inputData.trustLevel);
4392
 
  }
4393
 
  else if (keyEdit.doCheck(GET_BOOL, "edit_ownertrust.set_ultimate.okay")) {
4394
 
    ret.exitCode = 0;
4395
 
    ret.writeTxt = "Y";
4396
 
  }
4397
 
  else if (keyEdit.doCheck(GET_LINE, "keyedit.prompt")) {
4398
 
    ret.exitCode = 0;
4399
 
    ret.quitNow = true;
4400
 
  }
4401
 
  else if (keyEdit.doCheck(GET_HIDDEN, "passphrase.adminpin.ask")) {
4402
 
    GetPin(inputData.parent, Ec.getString("enterAdminPin"), ret);
4403
 
  }
4404
 
  else if (keyEdit.doCheck(GET_HIDDEN, "passphrase.pin.ask")) {
4405
 
    GetPin(inputData.parent, Ec.getString("enterCardPin"), ret);
4406
 
  }
4407
 
  else {
4408
 
    ret.quitNow=true;
4409
 
    Ec.ERROR_LOG("Unknown command prompt: "+keyEdit.getText()+"\n");
4410
 
    ret.exitCode=-1;
4411
 
  }
4412
 
}
4413
 
 
4414
4056
 
4415
4057
function addUidCallback(inputData, keyEdit, ret) {
4416
4058
  ret.writeTxt = "";