1974
1970
getLocalFileApi: function () {
1975
if ("nsILocalFile" in Ci) {
1976
return Ci.nsILocalFile;
1975
// Extract public key from Status Message
1976
extractPubkey: function (statusMsg) {
1978
var matchb = statusMsg.match(/(^|\n)NO_PUBKEY (\w{8})(\w{8})/);
1980
if (matchb && (matchb.length > 3)) {
1981
this.DEBUG_LOG("enigmail.js: Enigmail.extractPubkey: NO_PUBKEY 0x"+matchb[3]+"\n");
1982
keyId = matchb[2]+matchb[3];
1995
execStart: function (command, args, needPassphrase, domWindow, listener, statusFlagsObj) {
1996
this.WRITE_LOG("enigmailCommon.jsm: execStart: command = "+this.printCmdLine(command, args)+", needPassphrase="+needPassphrase+", domWindow="+domWindow+", listener="+listener+"\n");
1998
if (! listener) listener = {};
2000
statusFlagsObj.value = 0;
2002
var passphrase = null;
2003
var useAgentObj = {value: false};
2005
if (needPassphrase) {
2006
args = args.concat(this.passwdCommand());
2008
var passwdObj = new Object();
2010
if (!this.getPassphrase(domWindow, passwdObj, useAgentObj, 0)) {
2011
this.ERROR_LOG("enigmailCommon.jsm: execStart: Error - no passphrase supplied\n");
2013
statusFlagsObj.value |= nsIEnigmail.MISSING_PASSPHRASE;
2017
passphrase = passwdObj.value;
2020
this.CONSOLE_LOG("enigmail> "+this.printCmdLine(command, args)+"\n");
2023
proc = subprocess.call({
2026
environment: this.getEnvList(),
2028
stdin: function (pipe) {
2029
if (needPassphrase) {
2030
// Write to child STDIN
2031
// (ignore errors, because child may have exited already, closing STDIN)
2033
if (EnigmailCommon.requirePassword()) {
2034
pipe.write(passphrase+"\n");
2039
if (listener.stdin) listener.stdin(pipe);
2041
stdout: function(data) { listener.stdout(data) },
2042
stderr: function(data) { listener.stderr(data) },
2043
done: function(result) {
2045
listener.done(result.exitCode);
2048
EnigmailCommon.writeException("enigmailCommon.jsm", ex);
2054
this.CONSOLE_LOG("enigmail.jsm: execStart: Error - Failed to start PipeTransport\n");
2055
this.ERROR_LOG("enigmailCommon.jsm: execStart: subprocess.call failed with '"+ex.toString()+"'\n");
2062
decryptMessageStart: function (win, verifyOnly, listener,
2063
statusFlagsObj, errorMsgObj) {
2064
this.DEBUG_LOG("enigmailCommon.jsm: decryptMessageStart: verifyOnly="+verifyOnly+"\n");
2066
this.getService(win);
2067
if (! (this.enigmailSvc)) {
2068
this.ERROR_LOG("enigmail.jsm: decryptMessageStart: not yet initialized\n");
2069
errorMsgObj.value = this.getString("notInit");
2073
if (gKeygenProcess) {
2074
errorMsgObj.value = this.getString("notComplete");
2078
var args = this.getAgentArgs(true);
2080
var keyserver = this.getPref("autoKeyRetrieve");
2081
if (keyserver && keyserver != "") {
2082
args.push("--keyserver-options");
2083
var keySrvArgs="auto-key-retrieve";
2084
var srvProxy = this.getHttpProxy(keyserver);
2086
keySrvArgs += ",http-proxy="+srvProxy;
2088
args.push(keySrvArgs);
2089
args.push("--keyserver");
2090
args.push(keyserver);
2094
args.push("--verify");
2097
args.push("--decrypt");
2100
var proc = this.execStart(this.enigmailSvc.agentPath, args, !verifyOnly, win,
2101
listener, statusFlagsObj);
2103
if (statusFlagsObj.value & nsIEnigmail.MISSING_PASSPHRASE) {
2104
this.ERROR_LOG("enigmailCommon.jsm: decryptMessageStart: Error - no passphrase supplied\n");
2106
errorMsgObj.value = this.getString("noPassphrase");
2113
decryptMessageEnd: function (stderrStr, exitCode, outputLen, verifyOnly, noOutput, uiFlags, retStatusObj) {
2114
this.DEBUG_LOG("enigmail.jsm: decryptMessageEnd: uiFlags="+uiFlags+", verifyOnly="+verifyOnly+", noOutput="+noOutput+"\n");
2116
this.DEBUG_LOG("enigmail.jsm: decryptMessageEnd: stderrStr="+stderrStr+"\n");
2117
var interactive = uiFlags & nsIEnigmail.UI_INTERACTIVE;
2118
var pgpMime = uiFlags & nsIEnigmail.UI_PGP_MIME;
2119
var allowImport = uiFlags & nsIEnigmail.UI_ALLOW_KEY_IMPORT;
2120
var unverifiedEncryptedOK = uiFlags & nsIEnigmail.UI_UNVERIFIED_ENC_OK;
2123
retStatusObj.statusFlags = 0;
2124
retStatusObj.errorMsg = "";
2125
retStatusObj.blockSeparation = "";
2127
var errorMsg = this.parseErrorOutput(stderrStr, retStatusObj);
2130
retStatusObj.statusFlags |= verifyOnly ? nsIEnigmail.PGP_MIME_SIGNED
2131
: nsIEnigmail.PGP_MIME_ENCRYPTED;
2134
var statusMsg = retStatusObj.statusMsg;
2135
exitCode = this.fixExitCode(exitCode, retStatusObj.statusFlags);
2136
if ((exitCode == 0) && !noOutput && !outputLen &&
2137
((retStatusObj.statusFlags & (gStatusFlags.DECRYPTION_OKAY | gStatusFlags.GOODSIG)) == 0)) {
2141
if (exitCode == 0) {
2143
var errLines, goodSignPat, badSignPat, keyExpPat, revKeyPat, validSigPat;
2146
errLines = statusMsg.split(/\r?\n/);
2148
goodSignPat = /GOODSIG (\w{16}) (.*)$/i;
2149
badSignPat = /BADSIG (\w{16}) (.*)$/i;
2150
keyExpPat = /EXPKEYSIG (\w{16}) (.*)$/i
2151
revKeyPat = /REVKEYSIG (\w{16}) (.*)$/i;
2152
validSigPat = /VALIDSIG (\w+) (.*) (\d+) (.*)/i;
2155
errLines = stderrStr.value.split(/\r?\n/);
2157
goodSignPat = /Good signature from (user )?"(.*)"\.?/i;
2158
badSignPat = /BAD signature from (user )?"(.*)"\.?/i;
2159
keyExpPat = /This key has expired/i;
2160
revKeyPat = /This key has been revoked/i;
2161
validSigPat = /dummy-not-used/i;
2164
retStatusObj.errorMsg = "";
2173
var sigDetails = "";
2175
for (j=0; j<errLines.length; j++) {
2176
matches = errLines[j].match(badSignPat);
2178
if (matches && (matches.length > 2)) {
2180
goodSignature = false;
2181
userId = matches[2];
2186
matches = errLines[j].match(revKeyPat);
2188
if (matches && (matches.length > 2)) {
2190
goodSignature = true;
2191
userId = matches[2];
2196
matches = errLines[j].match(goodSignPat);
2198
if (matches && (matches.length > 2)) {
2200
goodSignature = true;
2201
userId = matches[2];
2206
matches = errLines[j].match(keyExpPat);
2208
if (matches && (matches.length > 2)) {
2210
goodSignature = true;
2211
userId = matches[2];
2218
if (goodSignature) {
2219
for (var j=0; j<errLines.length; j++) {
2220
matches = errLines[j].match(validSigPat);
2222
if (matches && (matches.length > 4))
2223
keyId = matches[4].substr(-16); // in case of several subkeys refer to the main key ID
2225
if (matches && (matches.length > 2)) {
2226
sigDetails = errLines[j].substr(9);
2233
if (userId && keyId && this.prefBranch.getBoolPref("displaySecondaryUid")) {
2234
let uids = this.enigmailSvc.getKeyDetails(keyId, true);
2243
userId = this.convertToUnicode(userId, "UTF-8");
2246
retStatusObj.userId = userId;
2247
retStatusObj.keyId = keyId;
2248
retStatusObj.sigDetails = sigDetails;
2251
var trustPrefix = "";
2253
if (retStatusObj.statusFlags & nsIEnigmail.UNTRUSTED_IDENTITY) {
2254
trustPrefix += this.getString("prefUntrusted")+" ";
2257
if (retStatusObj.statusFlags & nsIEnigmail.REVOKED_KEY) {
2258
trustPrefix += this.getString("prefRevoked")+" ";
2261
if (retStatusObj.statusFlags & nsIEnigmail.EXPIRED_KEY_SIGNATURE) {
2262
trustPrefix += this.getString("prefExpiredKey")+" ";
2264
} else if (retStatusObj.statusFlags & nsIEnigmail.EXPIRED_SIGNATURE) {
2265
trustPrefix += this.getString("prefExpired")+" ";
2268
if (goodSignature) {
2269
retStatusObj.errorMsg = trustPrefix + this.getString("prefGood", [userId]) /* + ", " +
2270
this.getString("keyId") + " 0x" + keyId.substring(8,16); */
2272
retStatusObj.errorMsg = trustPrefix + this.getString("prefBad", [userId]) /*+ ", " +
2273
this.getString("keyId") + " 0x" + keyId.substring(8,16); */
2279
if (retStatusObj.statusFlags & nsIEnigmail.UNVERIFIED_SIGNATURE) {
2280
retStatusObj.keyId = this.extractPubkey(statusMsg)
2287
if (retStatusObj.statusFlags & nsIEnigmail.BAD_PASSPHRASE) {
2288
// "Unremember" passphrase on decryption failure
2289
this.clearCachedPassphrase();
2294
if (retStatusObj.statusFlags & nsIEnigmail.UNVERIFIED_SIGNATURE) {
2295
// Unverified signature
2296
retStatusObj.keyId = this.extractPubkey(statusMsg);
2298
if (retStatusObj.statusFlags & nsIEnigmail.DECRYPTION_OKAY) {
2304
if (exitCode != 0) {
2306
this.DEBUG_LOG("enigmail.jsm: decryptMessageEnd: command execution exit code: "+exitCode+"\n");
2310
if (cmdErrorMsgObj.value) {
2311
errorMsgObj.value = this.agentType + " " + this.getString("cmdLine");
2312
errorMsgObj.value += "\n" + cmdLineObj.value;
2313
errorMsgObj.value += "\n" + cmdErrorMsgObj.value;