Page Menu
Home
GnuPG
Search
Configure Global Search
Log In
Files
F36624269
enigmailMsgComposeOverlay.js
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Size
93 KB
Subscribers
None
enigmailMsgComposeOverlay.js
View Options
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public
* License Version 1.1 (the "MPL"); you may not use this file
* except in compliance with the MPL. You may obtain a copy of
* the MPL at http://www.mozilla.org/MPL/
*
* Software distributed under the MPL is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the MPL for the specific language governing
* rights and limitations under the MPL.
*
* The Original Code is Enigmail.
*
* The Initial Developer of the Original Code is Ramalingam Saravanan.
* Portions created by Ramalingam Saravanan <svn@xmlterm.org> are
* Copyright (C) 2001 Ramalingam Saravanan. All Rights Reserved.
*
* Contributor(s):
* Patrick Brunschwig <patrick@mozilla-enigmail.org>
* Ludwig Hügelschäfer <ludwig@hammernoch.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
* ***** END LICENSE BLOCK ***** */
try
{
// TB with omnijar
Components
.
utils
.
import
(
"resource:///modules/gloda/mimemsg.js"
);
}
catch
(
ex
)
{
// TB without omnijar
Components
.
utils
.
import
(
"resource://app/modules/gloda/mimemsg.js"
);
}
Components
.
utils
.
import
(
"resource://enigmail/enigmailCommon.jsm"
);
Components
.
utils
.
import
(
"resource://enigmail/commonFuncs.jsm"
);
if
(
!
Enigmail
)
var
Enigmail
=
{};
Enigmail
.
msg
=
{
// List of hash algorithms for PGP/MIME signatures
mimeHashAlgo
:
[
null
,
"sha1"
,
"ripemd160"
,
"sha256"
,
"sha384"
,
"sha512"
,
"sha224"
],
editor
:
null
,
dirty
:
null
,
processed
:
null
,
timeoutId
:
null
,
sendPgpMime
:
false
,
sendMode
:
null
,
sendModeDirty
:
0
,
nextCommandId
:
null
,
docaStateListener
:
null
,
identity
:
null
,
enableRules
:
null
,
modifiedAttach
:
null
,
lastFocusedWindow
:
null
,
determineSendFlagId
:
null
,
signRules
:
1
,
encryptRules
:
1
,
attachOwnKeyObj
:
{
appendAttachment
:
false
,
attachedObj
:
null
,
attachedKey
:
null
},
compFieldsEnig_CID
:
"@mozdev.org/enigmail/composefields;1"
,
composeStartup
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.composeStartup\n"
);
// Relabel/hide SMIME button and menu item
var
smimeButton
=
document
.
getElementById
(
"button-security"
);
if
(
smimeButton
)
{
smimeButton
.
setAttribute
(
"label"
,
"S/MIME"
);
}
var
enigButton
=
document
.
getElementById
(
"button-enigmail-send"
);
var
msgId
=
document
.
getElementById
(
"msgIdentityPopup"
);
if
(
msgId
)
msgId
.
setAttribute
(
"oncommand"
,
"Enigmail.msg.setIdentityCallback();"
);
var
subj
=
document
.
getElementById
(
"msgSubject"
);
subj
.
setAttribute
(
'onfocus'
,
"Enigmail.msg.fireSendFlags()"
);
this
.
setIdentityDefaults
();
this
.
msgComposeReset
(
false
);
this
.
composeOpen
();
},
composeUnload
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.composeUnload\n"
);
//if (gMsgCompose)
// gMsgCompose.UnregisterStateListener(Enigmail.composeStateListener);
},
handleClick
:
function
(
event
,
modifyType
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.handleClick\n"
);
switch
(
event
.
button
)
{
case
2
:
// do not process the event any futher
// needed on Windows to prevent displaying the context menu
event
.
preventDefault
();
this
.
doPgpButton
();
break
;
case
0
:
this
.
doPgpButton
(
modifyType
);
break
;
}
},
setIdentityCallback
:
function
(
elementId
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.setIdentityCallback: elementId="
+
elementId
+
"\n"
);
this
.
setIdentityDefaults
();
},
getAccDefault
:
function
(
value
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.getAccDefault: identity="
+
this
.
identity
.
key
+
" value="
+
value
+
"\n"
);
var
enabled
=
this
.
identity
.
getBoolAttribute
(
"enablePgp"
);
if
(
value
==
"enabled"
)
return
enabled
;
if
(
enabled
)
{
var
r
=
null
;
switch
(
value
)
{
case
'encrypt'
:
r
=
this
.
identity
.
getIntAttribute
(
"defaultEncryptionPolicy"
);
break
;
case
'signPlain'
:
r
=
this
.
identity
.
getBoolAttribute
(
"pgpSignPlain"
);
break
;
case
'signEnc'
:
r
=
this
.
identity
.
getBoolAttribute
(
"pgpSignEncrypted"
);
break
;
case
'pgpMimeMode'
:
case
'attachPgpKey'
:
r
=
this
.
identity
.
getBoolAttribute
(
value
);
break
;
}
EnigmailCommon
.
DEBUG_LOG
(
" "
+
value
+
"="
+
r
+
"\n"
);
return
r
;
}
else
{
switch
(
value
)
{
case
'encrypt'
:
return
0
;
case
'signPlain'
:
case
'signEnc'
:
case
'pgpMimeMode'
:
case
'attachPgpKey'
:
return
false
;
}
}
return
null
;
},
setIdentityDefaults
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.setIdentityDefaults\n"
);
this
.
identity
=
getCurrentIdentity
();
if
(
this
.
getAccDefault
(
"enabled"
))
{
EnigmailFuncs
.
getSignMsg
(
this
.
identity
);
}
if
(
!
this
.
sendModeDirty
)
{
this
.
setSendDefaultOptions
();
this
.
updateStatusBar
();
}
},
// set the current default for sending a message
// depending on the identity
setSendDefaultOptions
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.setSendDefaultOptions\n"
);
const
nsIEnigmail
=
Components
.
interfaces
.
nsIEnigmail
;
const
SIGN
=
nsIEnigmail
.
SEND_SIGNED
;
const
ENCRYPT
=
nsIEnigmail
.
SEND_ENCRYPTED
;
this
.
sendMode
=
0
;
if
(
!
this
.
getAccDefault
(
"enabled"
))
{
return
;
}
if
(
this
.
getAccDefault
(
"encrypt"
)
>
0
)
{
this
.
sendMode
|=
ENCRYPT
;
if
(
this
.
getAccDefault
(
"signEnc"
))
this
.
sendMode
|=
SIGN
;
}
else
{
if
(
this
.
getAccDefault
(
"signPlain"
))
this
.
sendMode
|=
SIGN
;
}
this
.
sendPgpMime
=
this
.
getAccDefault
(
"pgpMimeMode"
);
this
.
attachOwnKeyObj
.
appendAttachment
=
this
.
getAccDefault
(
"attachPgpKey"
);
this
.
attachOwnKeyObj
.
attachedObj
=
null
;
this
.
attachOwnKeyObj
.
attachedKey
=
null
;
},
getMsgProperties
:
function
(
msgUri
,
draft
)
{
const
nsIEnigmail
=
Components
.
interfaces
.
nsIEnigmail
;
var
properties
=
0
;
try
{
var
messenger
=
Components
.
classes
[
"@mozilla.org/messenger;1"
].
getService
(
Components
.
interfaces
.
nsIMessenger
);
var
msgHdr
=
messenger
.
messageServiceFromURI
(
msgUri
).
messageURIToMsgHdr
(
msgUri
);
if
(
msgHdr
)
{
properties
=
msgHdr
.
getUint32Property
(
"enigmail"
);
if
(
draft
)
{
try
{
MsgHdrToMimeMessage
(
msgHdr
,
null
,
this
.
getMsgPropertiesCb
,
true
,
{
examineEncryptedParts
:
true
});
}
catch
(
ex
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMessengerOverlay.js: Enigmail.msg.getMsgProperties: cannot use MsgHdrToMimeMessage\n"
);
}
}
}
}
catch
(
ex
)
{
}
if
(
EnigmailCommon
.
isEncryptedUri
(
msgUri
))
{
properties
|=
nsIEnigmail
.
DECRYPTION_OKAY
;
}
return
properties
;
},
getMsgPropertiesCb
:
function
(
msg
,
mimeMsg
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.getMsgPropertiesCb\n"
);
const
nsIEnigmail
=
Components
.
interfaces
.
nsIEnigmail
;
const
SIGN
=
nsIEnigmail
.
SEND_SIGNED
;
var
flags
=
0
;
if
(
mimeMsg
&&
mimeMsg
.
headers
[
"x-enigmail-draft-status"
])
flags
=
Number
(
mimeMsg
.
headers
[
"x-enigmail-draft-status"
]);
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.getMsgPropertiesCb: draftStatus: "
+
flags
+
"\n"
);
if
(
flags
&
SIGN
)
Enigmail
.
msg
.
setSendMode
(
'sign'
);
},
composeOpen
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.composeOpen\n"
);
const
nsIEnigmail
=
Components
.
interfaces
.
nsIEnigmail
;
const
SIGN
=
nsIEnigmail
.
SEND_SIGNED
;
const
ENCRYPT
=
nsIEnigmail
.
SEND_ENCRYPTED
;
var
msgFlags
;
var
msgUri
=
null
;
var
msgIsDraft
=
false
;
this
.
determineSendFlagId
=
null
;
var
toobarElem
=
document
.
getElementById
(
"composeToolbar2"
);
if
(
toobarElem
&&
(
EnigmailCommon
.
getOS
()
==
"Darwin"
))
{
toobarElem
.
setAttribute
(
"platform"
,
"macos"
);
}
if
(
EnigmailCommon
.
getPref
(
"keepSettingsForReply"
)
&&
(
!
(
this
.
sendMode
&
ENCRYPT
)))
{
// var enigMimeService = Components.classes[EnigmailCommon.ENIGMIMESERVICE_CONTRACTID].getService(Components.interfaces.nsIEnigMimeService);
// if (enigMimeService)
// {
var
draftId
=
gMsgCompose
.
compFields
.
draftId
;
if
(
typeof
(
draftId
)
==
"string"
&&
draftId
.
length
>
0
)
{
msgUri
=
draftId
.
replace
(
/\?.*$/
,
""
);
msgIsDraft
=
true
;
}
else
if
(
typeof
(
gMsgCompose
.
originalMsgURI
)
==
"string"
&&
gMsgCompose
.
originalMsgURI
.
length
>
0
)
{
msgUri
=
gMsgCompose
.
originalMsgURI
;
}
if
(
msgUri
!=
null
)
{
msgFlags
=
this
.
getMsgProperties
(
msgUri
,
msgIsDraft
);
if
(
msgFlags
&
nsIEnigmail
.
DECRYPTION_OKAY
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.composeOpen: has encrypted originalMsgUri\n"
);
EnigmailCommon
.
DEBUG_LOG
(
"originalMsgURI="
+
gMsgCompose
.
originalMsgURI
+
"\n"
);
this
.
setSendMode
(
'encrypt'
);
this
.
removeAttachedKey
();
}
else
if
(
msgFlags
&
(
nsIEnigmail
.
GOOD_SIGNATURE
|
nsIEnigmail
.
BAD_SIGNATURE
|
nsIEnigmail
.
UNVERIFIED_SIGNATURE
))
{
this
.
setSendMode
(
'sign'
);
this
.
removeAttachedKey
();
}
}
// }
}
// check for attached signature files and remove them
var
bucketList
=
document
.
getElementById
(
"attachmentBucket"
);
if
(
bucketList
.
hasChildNodes
())
{
var
node
=
bucketList
.
firstChild
;
nodeNumber
=
0
;
while
(
node
)
{
if
(
node
.
attachment
.
contentType
==
"application/pgp-signature"
)
{
if
(
!
this
.
findRelatedAttachment
(
bucketList
,
node
))
{
node
=
bucketList
.
removeItemAt
(
nodeNumber
);
// Let's release the attachment object held by the node else it won't go away until the window is destroyed
node
.
attachment
=
null
;
}
}
else
{
++
nodeNumber
;
}
node
=
node
.
nextSibling
;
}
if
(
!
bucketList
.
hasChildNodes
())
{
try
{
// TB only
UpdateAttachmentBucket
(
false
);
}
catch
(
ex
)
{}
}
}
try
{
// TB only
UpdateAttachmentBucket
(
bucketList
.
hasChildNodes
());
}
catch
(
ex
)
{}
this
.
updateStatusBar
();
},
// check if an signature is related to another attachment
findRelatedAttachment
:
function
(
bucketList
,
node
)
{
// check if filename ends with .sig
if
(
node
.
attachment
.
name
.
search
(
/\.sig$/i
)
<
0
)
return
null
;
var
relatedNode
=
bucketList
.
firstChild
;
var
findFile
=
node
.
attachment
.
name
.
toLowerCase
();
var
baseAttachment
=
null
;
while
(
relatedNode
)
{
if
(
relatedNode
.
attachment
.
name
.
toLowerCase
()
+
".sig"
==
findFile
)
baseAttachment
=
relatedNode
.
attachment
;
relatedNode
=
relatedNode
.
nextSibling
;
}
return
baseAttachment
;
},
msgComposeReopen
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.msgComposeReopen\n"
);
this
.
msgComposeReset
(
false
);
this
.
composeOpen
();
},
msgComposeClose
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.msgComposeClose\n"
);
var
ioServ
;
try
{
// we should delete the original temporary files of the encrypted or signed
// inline PGP attachments (the rest is done automatically)
if
(
this
.
modifiedAttach
)
{
ioServ
=
Components
.
classes
[
EnigmailCommon
.
IOSERVICE_CONTRACTID
].
getService
(
Components
.
interfaces
.
nsIIOService
);
if
(
!
ioServ
)
return
;
for
(
var
i
in
this
.
modifiedAttach
)
{
if
(
this
.
modifiedAttach
[
i
].
origTemp
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.msgComposeClose: deleting "
+
this
.
modifiedAttach
[
i
].
origUrl
+
"\n"
);
var
fileUri
=
ioServ
.
newURI
(
this
.
modifiedAttach
[
i
].
origUrl
,
null
,
null
);
var
fileHandle
=
Components
.
classes
[
EnigmailCommon
.
LOCAL_FILE_CONTRACTID
].
createInstance
(
EnigmailCommon
.
getLocalFileApi
());
fileHandle
.
initWithPath
(
fileUri
.
path
);
if
(
fileHandle
.
exists
())
fileHandle
.
remove
(
false
);
}
}
this
.
modifiedAttach
=
null
;
}
}
catch
(
ex
)
{
EnigmailCommon
.
ERROR_LOG
(
"enigmailMsgComposeOverlay.js: ECSL.ComposeProcessDone: could not delete all files:\n"
+
ex
.
toString
()
+
"\n"
);
}
this
.
msgComposeReset
(
true
);
},
msgComposeReset
:
function
(
closing
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.msgComposeReset\n"
);
this
.
dirty
=
0
;
this
.
processed
=
null
;
this
.
timeoutId
=
null
;
this
.
modifiedAttach
=
null
;
this
.
sendModeDirty
=
0
;
this
.
sendMode
=
0
;
this
.
enableRules
=
true
;
this
.
identity
=
null
;
if
(
!
closing
)
{
this
.
setIdentityDefaults
();
}
},
initRadioMenu
:
function
(
prefName
,
optionIds
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMessengerOverlay.js: Enigmail.msg.initRadioMenu: "
+
prefName
+
"\n"
);
var
encryptId
;
var
prefValue
=
EnigmailCommon
.
getPref
(
prefName
);
if
(
prefValue
>=
optionIds
.
length
)
return
;
var
menuItem
=
document
.
getElementById
(
"enigmail_"
+
optionIds
[
prefValue
]);
if
(
menuItem
)
menuItem
.
setAttribute
(
"checked"
,
"true"
);
},
usePpgMimeOption
:
function
(
value
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMessengerOverlay.js: Enigmail.msg.usePpgMimeOption: "
+
value
+
"\n"
);
EnigmailCommon
.
setPref
(
"usePGPMimeOption"
,
value
);
return
true
;
},
togglePgpMime
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.togglePgpMime\n"
);
this
.
sendPgpMime
=
!
this
.
sendPgpMime
;
},
toggleAttachOwnKey
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.toggleAttachOwnKey\n"
);
EnigmailCommon
.
getService
(
window
);
// make sure Enigmail is loaded and working
this
.
attachOwnKeyObj
.
appendAttachment
=
!
this
.
attachOwnKeyObj
.
appendAttachment
;
},
attachOwnKey
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.attachOwnKey:\n"
);
var
userIdValue
;
if
(
this
.
identity
.
getIntAttribute
(
"pgpKeyMode"
)
>
0
)
{
userIdValue
=
this
.
identity
.
getCharAttribute
(
"pgpkeyId"
);
if
(
this
.
attachOwnKeyObj
.
attachedKey
&&
(
this
.
attachOwnKeyObj
.
attachedKey
!=
userIdValue
))
{
// remove attached key if user ID changed
this
.
removeAttachedKey
();
}
if
(
!
this
.
attachOwnKeyObj
.
attachedKey
)
{
var
attachedObj
=
this
.
extractAndAttachKey
(
[
userIdValue
]
);
if
(
attachedObj
)
{
this
.
attachOwnKeyObj
.
attachedObj
=
attachedObj
;
this
.
attachOwnKeyObj
.
attachedKey
=
userIdValue
;
}
}
}
else
{
EnigmailCommon
.
ERROR_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.attachOwnKey: trying to attach unknown own key!\n"
);
}
},
attachKey
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.attachKey: \n"
);
var
resultObj
=
new
Object
();
var
inputObj
=
new
Object
();
inputObj
.
dialogHeader
=
EnigmailCommon
.
getString
(
"keysToExport"
);
inputObj
.
options
=
"multisel,allowexpired,nosending"
;
var
userIdValue
=
""
;
window
.
openDialog
(
"chrome://enigmail/content/enigmailUserSelection.xul"
,
""
,
"dialog,modal,centerscreen"
,
inputObj
,
resultObj
);
try
{
if
(
resultObj
.
cancelled
)
return
;
this
.
extractAndAttachKey
(
resultObj
.
userList
);
}
catch
(
ex
)
{
// cancel pressed -> do nothing
return
;
}
},
extractAndAttachKey
:
function
(
uid
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.attachKey: \n"
);
var
enigmailSvc
=
EnigmailCommon
.
getService
(
window
);
if
(
!
enigmailSvc
)
return
null
;
var
tmpDir
=
EnigmailCommon
.
getTempDir
();
try
{
var
tmpFile
=
Components
.
classes
[
EnigmailCommon
.
LOCAL_FILE_CONTRACTID
].
createInstance
(
EnigmailCommon
.
getLocalFileApi
());
tmpFile
.
initWithPath
(
tmpDir
);
if
(
!
(
tmpFile
.
isDirectory
()
&&
tmpFile
.
isWritable
()))
{
EnigmailCommon
.
alert
(
window
,
EnigmailCommon
.
getString
(
"noTempDir"
));
return
null
;
}
}
catch
(
ex
)
{
EnigmailCommon
.
writeException
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.extractAndAttachKey"
,
ex
);
}
tmpFile
.
append
(
"key.asc"
);
tmpFile
.
createUnique
(
Components
.
interfaces
.
nsIFile
.
NORMAL_FILE_TYPE
,
0600
);
// save file
var
exitCodeObj
=
{};
var
errorMsgObj
=
{};
enigmailSvc
.
extractKey
(
window
,
0
,
uid
.
join
(
" "
),
tmpFile
/*.path */
,
exitCodeObj
,
errorMsgObj
);
if
(
exitCodeObj
.
value
!=
0
)
{
EnigmailCommon
.
alert
(
window
,
errorMsgObj
.
value
);
return
null
;
}
// create attachment
var
ioServ
=
Components
.
classes
[
EnigmailCommon
.
IOSERVICE_CONTRACTID
].
getService
(
Components
.
interfaces
.
nsIIOService
);
var
tmpFileURI
=
ioServ
.
newFileURI
(
tmpFile
);
var
keyAttachment
=
Components
.
classes
[
"@mozilla.org/messengercompose/attachment;1"
].
createInstance
(
Components
.
interfaces
.
nsIMsgAttachment
);
keyAttachment
.
url
=
tmpFileURI
.
spec
;
if
((
uid
.
length
==
1
)
&&
(
uid
[
0
].
search
(
/^(0x)?[a-fA-F0-9]+$/
)
==
0
))
{
keyAttachment
.
name
=
"0x"
+
uid
[
0
].
substr
(
-
8
,
8
)
+
".asc"
;
}
else
{
keyAttachment
.
name
=
"pgpkeys.asc"
;
}
keyAttachment
.
temporary
=
true
;
keyAttachment
.
contentType
=
"application/pgp-keys"
;
// add attachment to msg
this
.
addAttachment
(
keyAttachment
);
try
{
// TB only
ChangeAttachmentBucketVisibility
(
false
);
}
catch
(
ex
)
{}
gContentChanged
=
true
;
return
keyAttachment
;
},
addAttachment
:
function
(
attachment
)
{
if
(
typeof
(
AddAttachment
)
==
"undefined"
)
{
// TB >= 3.0
AddUrlAttachment
(
attachment
);
}
else
{
// SeaMonkey and TB <= 3.0
AddAttachment
(
attachment
);
}
},
undoEncryption
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.undoEncryption:\n"
);
if
(
this
.
processed
)
{
this
.
replaceEditorText
(
this
.
processed
.
origText
);
this
.
processed
=
null
;
}
else
{
this
.
decryptQuote
(
true
);
}
var
node
;
var
nodeNumber
;
var
bucketList
=
document
.
getElementById
(
"attachmentBucket"
);
if
(
this
.
modifiedAttach
&&
bucketList
&&
bucketList
.
hasChildNodes
()
)
{
// undo inline encryption of attachments
for
(
var
i
=
0
;
i
<
this
.
modifiedAttach
.
length
;
i
++
)
{
node
=
bucketList
.
firstChild
;
nodeNumber
=-
1
;
while
(
node
)
{
++
nodeNumber
;
if
(
node
.
attachment
.
url
==
this
.
modifiedAttach
[
i
].
newUrl
)
{
if
(
this
.
modifiedAttach
[
i
].
encrypted
)
{
node
.
attachment
.
url
=
this
.
modifiedAttach
[
i
].
origUrl
;
node
.
attachment
.
name
=
this
.
modifiedAttach
[
i
].
origName
;
node
.
attachment
.
temporary
=
this
.
modifiedAttach
[
i
].
origTemp
;
node
.
attachment
.
contentType
=
this
.
modifiedAttach
[
i
].
origCType
;
}
else
{
node
=
bucketList
.
removeItemAt
(
nodeNumber
);
// Let's release the attachment object held by the node else it won't go away until the window is destroyed
node
.
attachment
=
null
;
}
// delete encrypted file
try
{
this
.
modifiedAttach
[
i
].
newFile
.
remove
(
false
);
}
catch
(
ex
)
{}
node
=
null
;
// next attachment please
}
else
{
node
=
node
.
nextSibling
;
}
}
}
}
this
.
removeAttachedKey
();
},
removeAttachedKey
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.removeAttachedKey: \n"
);
var
bucketList
=
document
.
getElementById
(
"attachmentBucket"
);
var
node
=
bucketList
.
firstChild
;
if
(
bucketList
&&
bucketList
.
hasChildNodes
()
&&
this
.
attachOwnKeyObj
.
attachedObj
)
{
// undo attaching own key
var
nodeNumber
=-
1
;
while
(
node
)
{
++
nodeNumber
;
if
(
node
.
attachment
.
url
==
this
.
attachOwnKeyObj
.
attachedObj
.
url
)
{
node
=
bucketList
.
removeItemAt
(
nodeNumber
);
// Let's release the attachment object held by the node else it won't go away until the window is destroyed
node
.
attachment
=
null
;
this
.
attachOwnKeyObj
.
attachedObj
=
null
;
this
.
attachOwnKeyObj
.
attachedKey
=
null
;
node
=
null
;
// exit loop
}
else
{
node
=
node
.
nextSibling
;
}
}
if
(
!
bucketList
.
hasChildNodes
())
{
try
{
// TB only
ChangeAttachmentBucketVisibility
(
true
);
}
catch
(
ex
)
{}
}
}
},
replaceEditorText
:
function
(
text
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.replaceEditorText:\n"
);
this
.
editorSelectAll
();
// Overwrite text in clipboard for security
// (Otherwise plaintext will be available in the clipbaord)
this
.
editorInsertText
(
"Enigmail"
);
this
.
editorSelectAll
();
this
.
editorInsertText
(
text
);
},
goAccountManager
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.goAccountManager:\n"
);
EnigmailCommon
.
getService
(
window
);
var
server
=
null
;
try
{
var
currentId
=
getCurrentIdentity
();
var
amService
=
Components
.
classes
[
"@mozilla.org/messenger/account-manager;1"
].
getService
();
var
servers
=
amService
.
GetServersForIdentity
(
currentId
);
var
folderURI
=
servers
.
GetElementAt
(
0
).
QueryInterface
(
Components
.
interfaces
.
nsIMsgIncomingServer
).
serverURI
;
server
=
GetMsgFolderFromUri
(
folderURI
,
true
).
server
}
catch
(
ex
)
{}
window
.
openDialog
(
"chrome://enigmail/content/am-enigprefs-edit.xul"
,
""
,
"dialog,modal,centerscreen"
,
{
identity
:
currentId
,
account
:
server
});
this
.
setIdentityDefaults
();
},
doPgpButton
:
function
(
what
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.doPgpButton: what="
+
what
+
"\n"
);
if
(
!
what
)
what
=
this
.
nextCommandId
;
this
.
nextCommandId
=
""
;
EnigmailCommon
.
getService
(
window
);
// try to access Enigmail to launch the wizard if needed
try
{
if
(
!
this
.
getAccDefault
(
"enabled"
))
{
if
(
EnigmailCommon
.
confirmDlg
(
window
,
EnigmailCommon
.
getString
(
"configureNow"
),
EnigmailCommon
.
getString
(
"msgCompose.button.configure"
)))
{
this
.
goAccountManager
();
if
(
!
this
.
identity
.
getBoolAttribute
(
"enablePgp"
))
return
;
}
else
{
return
;
}
}
}
catch
(
ex
)
{}
switch
(
what
)
{
case
'plain'
:
case
'sign'
:
case
'dont-sign'
:
case
'sign-if-enc'
:
case
'encrypt'
:
case
'enc-ifpossible'
:
case
'toggle-sign'
:
case
'toggle-encrypt'
:
this
.
setSendMode
(
what
);
break
;
case
'togglePGPMime'
:
this
.
togglePgpMime
();
break
;
case
'toggleRules'
:
this
.
toggleRules
();
break
;
default
:
this
.
displaySecuritySettings
();
}
return
;
},
nextCommand
:
function
(
what
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.nextCommand: what="
+
what
+
"\n"
);
this
.
nextCommandId
=
what
;
},
setSendMode
:
function
(
sendMode
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.setSendMode: sendMode="
+
sendMode
+
"\n"
);
const
nsIEnigmail
=
Components
.
interfaces
.
nsIEnigmail
;
const
SIGN
=
nsIEnigmail
.
SEND_SIGNED
;
const
ENCRYPT
=
nsIEnigmail
.
SEND_ENCRYPTED
;
var
origSendMode
=
this
.
sendMode
;
switch
(
sendMode
)
{
case
'toggle-sign'
:
this
.
displaySignClickWarn
();
this
.
sendModeDirty
=
2
;
if
(
this
.
sendMode
&
SIGN
)
{
this
.
sendMode
&=
~
SIGN
;
}
else
{
this
.
sendMode
|=
SIGN
;
}
break
;
case
'toggle-encrypt'
:
if
(
this
.
sendMode
&
ENCRYPT
)
{
this
.
setSendMode
(
'plain'
);
}
else
{
this
.
setSendMode
(
'encrypt'
);
}
break
;
case
'encrypt'
:
this
.
sendMode
|=
ENCRYPT
;
if
(
this
.
sendModeDirty
<
2
)
{
if
(
this
.
getAccDefault
(
"signEnc"
))
{
this
.
sendMode
|=
SIGN
;
}
else
{
this
.
sendMode
&=
~
SIGN
;
}
}
break
;
case
'sign'
:
this
.
sendMode
|=
SIGN
;
break
;
case
'plain'
:
this
.
sendMode
&=
~
ENCRYPT
;
if
(
this
.
sendModeDirty
<
2
)
{
if
(
this
.
getAccDefault
(
"signPlain"
))
{
this
.
sendMode
|=
SIGN
;
}
else
{
this
.
sendMode
&=
~
SIGN
;
}
}
break
;
default
:
EnigmailCommon
.
alert
(
window
,
"Enigmail.msg.setSendMode - Strange value: "
+
sendMode
);
break
;
}
if
(
this
.
sendMode
!=
origSendMode
&&
this
.
sendModeDirty
<
2
)
this
.
sendModeDirty
=
1
;
this
.
updateStatusBar
();
},
updateStatusBar
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.updateStatusBar:\n"
);
const
nsIEnigmail
=
Components
.
interfaces
.
nsIEnigmail
;
const
SIGN
=
nsIEnigmail
.
SEND_SIGNED
;
const
ENCRYPT
=
nsIEnigmail
.
SEND_ENCRYPTED
;
var
statusBar
=
document
.
getElementById
(
"enigmail-status-bar"
);
if
(
!
this
.
getAccDefault
(
"enabled"
))
{
// hide icons if enigmail not enabled
statusBar
.
removeAttribute
(
"signed"
);
statusBar
.
removeAttribute
(
"encrypted"
);
return
;
}
var
signedIcon
=
document
.
getElementById
(
"enigmail-signed-status"
);
var
encryptedIcon
=
document
.
getElementById
(
"enigmail-encrypted-status"
);
if
(
this
.
sendMode
&
SIGN
)
{
switch
(
this
.
signRules
)
{
case
0
:
statusBar
.
setAttribute
(
"signed"
,
"activeMinus"
);
break
;
case
1
:
statusBar
.
setAttribute
(
"signed"
,
"activeNull"
);
break
;
case
2
:
statusBar
.
setAttribute
(
"signed"
,
"activePlus"
);
break
;
}
signedIcon
.
setAttribute
(
"tooltiptext"
,
EnigmailCommon
.
getString
(
"signYes"
));
}
else
{
switch
(
this
.
signRules
)
{
case
0
:
statusBar
.
setAttribute
(
"signed"
,
"inactiveMinus"
);
break
;
case
1
:
statusBar
.
setAttribute
(
"signed"
,
"inactiveNull"
);
break
;
case
2
:
statusBar
.
setAttribute
(
"signed"
,
"inactivePlus"
);
break
;
}
signedIcon
.
setAttribute
(
"tooltiptext"
,
EnigmailCommon
.
getString
(
"signNo"
));
}
if
(
this
.
sendMode
&
ENCRYPT
)
{
switch
(
this
.
encryptRules
)
{
case
0
:
statusBar
.
setAttribute
(
"encrypted"
,
"activeMinus"
);
break
;
case
1
:
statusBar
.
setAttribute
(
"encrypted"
,
"activeNull"
);
break
;
case
2
:
statusBar
.
setAttribute
(
"encrypted"
,
"activePlus"
);
break
;
}
encryptedIcon
.
setAttribute
(
"tooltiptext"
,
EnigmailCommon
.
getString
(
"encryptYes"
));
}
else
{
switch
(
this
.
encryptRules
)
{
case
0
:
statusBar
.
setAttribute
(
"encrypted"
,
"inactiveMinus"
);
break
;
case
1
:
statusBar
.
setAttribute
(
"encrypted"
,
"inactiveNull"
);
break
;
case
2
:
statusBar
.
setAttribute
(
"encrypted"
,
"inactivePlus"
);
break
;
}
encryptedIcon
.
setAttribute
(
"tooltiptext"
,
EnigmailCommon
.
getString
(
"encryptNo"
));
}
},
determineSendFlags
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.focusChange: Enigmail.msg.determineSendFlags\n"
);
if
(
this
.
getAccDefault
(
"enabled"
))
{
var
compFields
=
Components
.
classes
[
"@mozilla.org/messengercompose/composefields;1"
].
createInstance
(
Components
.
interfaces
.
nsIMsgCompFields
);
Recipients2CompFields
(
compFields
);
var
arrLen
=
new
Object
();
var
matchedKeysObj
=
new
Object
();
var
flagsObj
=
new
Object
();
var
toAddrList
=
new
Array
();
var
recList
;
if
(
compFields
.
to
.
length
>
0
)
{
recList
=
compFields
.
splitRecipients
(
compFields
.
to
,
true
,
arrLen
)
this
.
addRecipients
(
toAddrList
,
recList
);
}
if
(
compFields
.
cc
.
length
>
0
)
{
recList
=
compFields
.
splitRecipients
(
compFields
.
cc
,
true
,
arrLen
)
this
.
addRecipients
(
toAddrList
,
recList
);
}
if
(
compFields
.
bcc
.
length
>
0
)
{
recList
=
compFields
.
splitRecipients
(
compFields
.
bcc
,
true
,
arrLen
)
this
.
addRecipients
(
toAddrList
,
recList
);
}
this
.
signRules
=
1
;
this
.
encryptRules
=
1
;
if
(
toAddrList
.
length
>
0
)
{
if
(
Enigmail
.
hlp
.
getRecipientsKeys
(
toAddrList
.
join
(
", "
),
false
,
false
,
matchedKeysObj
,
flagsObj
))
{
this
.
signRules
=
flagsObj
.
sign
;
this
.
encryptRules
=
flagsObj
.
encrypt
;
}
}
this
.
updateStatusBar
();
}
this
.
determineSendFlagId
=
null
;
},
setMenuSettings
:
function
(
postfix
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.setMenuSettings: postfix="
+
postfix
+
"\n"
);
const
nsIEnigmail
=
Components
.
interfaces
.
nsIEnigmail
;
const
SIGN
=
nsIEnigmail
.
SEND_SIGNED
;
const
ENCRYPT
=
nsIEnigmail
.
SEND_ENCRYPTED
;
document
.
getElementById
(
"enigmail_encrypted_send"
+
postfix
).
setAttribute
(
"checked"
,
this
.
sendMode
&
ENCRYPT
?
"true"
:
"false"
);
document
.
getElementById
(
"enigmail_signed_send"
+
postfix
).
setAttribute
(
"checked"
,
this
.
sendMode
&
SIGN
?
"true"
:
"false"
);
var
menuElement
=
document
.
getElementById
(
"enigmail_sendPGPMime"
+
postfix
);
if
(
menuElement
)
menuElement
.
setAttribute
(
"checked"
,
this
.
sendPgpMime
.
toString
());
menuElement
=
document
.
getElementById
(
"enigmail_disable_rules"
+
postfix
);
if
(
menuElement
)
menuElement
.
setAttribute
(
"checked"
,
(
!
this
.
enableRules
).
toString
());
menuElement
=
document
.
getElementById
(
"enigmail_insert_own_key"
);
if
(
menuElement
)
{
if
(
this
.
identity
.
getIntAttribute
(
"pgpKeyMode"
)
>
0
)
{
menuElement
.
setAttribute
(
"checked"
,
this
.
attachOwnKeyObj
.
appendAttachment
.
toString
());
menuElement
.
removeAttribute
(
"disabled"
);
}
else
{
menuElement
.
setAttribute
(
"disabled"
,
"true"
);
}
}
},
displaySecuritySettings
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.displaySecuritySettings\n"
);
var
inputObj
=
{
sendFlags
:
this
.
sendMode
,
usePgpMime
:
this
.
sendPgpMime
,
disableRules
:
!
this
.
enableRules
};
window
.
openDialog
(
"chrome://enigmail/content/enigmailEncryptionDlg.xul"
,
""
,
"dialog,modal,centerscreen"
,
inputObj
);
if
(
this
.
sendMode
!=
inputObj
.
sendFlags
)
{
this
.
dirty
=
2
;
}
this
.
sendMode
=
inputObj
.
sendFlags
;
this
.
sendPgpMime
=
inputObj
.
usePgpMime
;
this
.
enableRules
=
!
inputObj
.
disableRules
;
this
.
updateStatusBar
();
},
displaySignClickWarn
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.displaySignClickWarn\n"
);
if
((
this
.
sendModeDirty
<
2
)
&&
(
this
.
getAccDefault
(
"signPlain"
)
||
this
.
getAccDefault
(
"signEnc"
)))
{
EnigmailCommon
.
alertPref
(
window
,
EnigmailCommon
.
getString
(
"signIconClicked"
),
"displaySignWarn"
);
}
},
confirmBeforeSend
:
function
(
toAddr
,
gpgKeys
,
sendFlags
,
isOffline
,
msgSendType
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.confirmBeforeSend: sendFlags="
+
sendFlags
+
"\n"
);
// get confirmation before sending message
var
msgStatus
=
""
;
const
nsIEnigmail
=
Components
.
interfaces
.
nsIEnigmail
;
const
SIGN
=
nsIEnigmail
.
SEND_SIGNED
;
const
ENCRYPT
=
nsIEnigmail
.
SEND_ENCRYPTED
;
if
(
sendFlags
&
(
ENCRYPT
|
SIGN
))
{
if
(
sendFlags
&
nsIEnigmail
.
SEND_PGP_MIME
)
msgStatus
+=
EnigmailCommon
.
getString
(
"statPGPMIME"
)
+
" "
;
if
(
sendFlags
&
SIGN
)
msgStatus
+=
EnigmailCommon
.
getString
(
"statSigned"
)
+
" "
;
if
(
sendFlags
&
ENCRYPT
)
msgStatus
+=
EnigmailCommon
.
getString
(
"statEncrypted"
)
+
" "
;
}
else
{
msgStatus
+=
EnigmailCommon
.
getString
(
"statPlain"
)
+
" "
;
}
gpgKeys
=
gpgKeys
.
replace
(
/^, /
,
""
).
replace
(
/, $/
,
""
);
var
msgConfirm
=
(
isOffline
||
sendFlags
&
nsIEnigmail
.
SEND_LATER
)
?
EnigmailCommon
.
getString
(
"offlineSave"
,
[
msgStatus
,
EnigmailFuncs
.
stripEmail
(
toAddr
).
replace
(
/,/g
,
", "
)
])
:
EnigmailCommon
.
getString
(
"onlineSend"
,
[
msgStatus
,
EnigmailFuncs
.
stripEmail
(
toAddr
).
replace
(
/,/g
,
", "
)
]);
if
(
sendFlags
&
ENCRYPT
)
msgConfirm
+=
"\n\n"
+
EnigmailCommon
.
getString
(
"encryptKeysNote"
,
[
gpgKeys
]);
return
EnigmailCommon
.
confirmDlg
(
window
,
msgConfirm
,
EnigmailCommon
.
getString
((
isOffline
||
sendFlags
&
nsIEnigmail
.
SEND_LATER
)
?
"msgCompose.button.save"
:
"msgCompose.button.send"
));
},
addRecipients
:
function
(
toAddrList
,
recList
)
{
for
(
var
i
=
0
;
i
<
recList
.
length
;
i
++
)
{
toAddrList
.
push
(
EnigmailFuncs
.
stripEmail
(
recList
[
i
].
replace
(
/[\",]/g
,
""
)));
}
},
setDraftStatus
:
function
(
sendFlags
)
{
gMsgCompose
.
compFields
.
otherRandomHeaders
+=
"X-Enigmail-Draft-Status: "
+
sendFlags
+
"\r\n"
;
},
getSenderUserId
:
function
()
{
var
userIdValue
=
null
;
if
(
this
.
identity
.
getIntAttribute
(
"pgpKeyMode"
)
>
0
)
{
userIdValue
=
this
.
identity
.
getCharAttribute
(
"pgpkeyId"
);
if
(
!
userIdValue
)
{
var
mesg
=
EnigmailCommon
.
getString
(
"composeSpecifyEmail"
);
var
valueObj
=
new
Object
();
valueObj
.
value
=
userIdValue
;
if
(
EnigmailCommon
.
promptValue
(
window
,
mesg
,
valueObj
))
{
userIdValue
=
valueObj
.
value
;
}
}
if
(
userIdValue
)
{
this
.
identity
.
setCharAttribute
(
"pgpkeyId"
,
userIdValue
);
}
else
{
this
.
identity
.
setIntAttribute
(
"pgpKeyMode"
,
0
);
}
}
if
(
typeof
(
userIdValue
)
!=
"string"
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.getSenderUserId: type of userIdValue="
+
typeof
(
userIdValue
)
+
"\n"
);
userIdValue
=
this
.
identity
.
email
;
}
return
userIdValue
;
},
keySelection
:
function
(
enigmailSvc
,
sendFlags
,
optSendFlags
,
gotSendFlags
,
fromAddr
,
toAddrList
,
bccAddrList
)
{
const
nsIEnigmail
=
Components
.
interfaces
.
nsIEnigmail
;
const
SIGN
=
nsIEnigmail
.
SEND_SIGNED
;
const
ENCRYPT
=
nsIEnigmail
.
SEND_ENCRYPTED
;
var
recipientsSelection
=
EnigmailCommon
.
getPref
(
"recipientsSelection"
);
var
toAddr
=
toAddrList
.
join
(
", "
);
var
bccAddr
=
bccAddrList
.
join
(
", "
);
var
testCipher
=
null
;
var
notSignedIfNotEnc
=
(
this
.
sendModeDirty
<
2
&&
(
!
this
.
getAccDefault
(
"signPlain"
)));
if
(
toAddr
.
length
>=
1
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg: toAddr="
+
toAddr
+
"\n"
);
var
repeatSelection
=
0
;
while
(
repeatSelection
<
2
)
{
if
(
recipientsSelection
!=
3
&&
recipientsSelection
!=
4
&&
this
.
enableRules
)
{
var
matchedKeysObj
=
new
Object
;
var
flagsObj
=
new
Object
;
if
(
!
Enigmail
.
hlp
.
getRecipientsKeys
(
toAddr
,
(
repeatSelection
==
1
),
true
,
matchedKeysObj
,
flagsObj
))
{
return
null
;
}
if
(
matchedKeysObj
.
value
)
toAddr
=
matchedKeysObj
.
value
;
if
(
flagsObj
.
value
)
{
switch
(
flagsObj
.
sign
)
{
case
0
:
sendFlags
&=
~
SIGN
;
break
;
case
2
:
sendFlags
|=
SIGN
;
break
;
}
switch
(
flagsObj
.
encrypt
)
{
case
0
:
sendFlags
&=
~
ENCRYPT
;
break
;
case
2
:
sendFlags
|=
ENCRYPT
;
break
;
}
switch
(
flagsObj
.
pgpMime
)
{
case
0
:
sendFlags
&=
~
nsIEnigmail
.
SEND_PGP_MIME
;
break
;
case
2
:
sendFlags
|=
nsIEnigmail
.
SEND_PGP_MIME
;
break
;
}
}
if
(
!
Enigmail
.
hlp
.
getRecipientsKeys
(
bccAddr
,
(
repeatSelection
==
1
),
true
,
matchedKeysObj
,
flagsObj
))
{
return
null
;
}
if
(
matchedKeysObj
.
value
)
bccAddr
=
matchedKeysObj
.
value
;
// bcc recipients are part of "normal" recipients as well; no need to do furter processing of flags etc.
}
repeatSelection
++
;
if
(
sendFlags
&
ENCRYPT
)
{
// Encrypt or sign test message for default encryption
var
testExitCodeObj
=
new
Object
();
var
testStatusFlagsObj
=
new
Object
();
var
testErrorMsgObj
=
new
Object
();
var
testPlain
=
"Test Message"
;
var
testUiFlags
=
nsIEnigmail
.
UI_TEST
;
var
testSendFlags
=
nsIEnigmail
.
SEND_TEST
|
ENCRYPT
|
optSendFlags
;
// test recipients
testCipher
=
enigmailSvc
.
encryptMessage
(
window
,
testUiFlags
,
null
,
testPlain
,
fromAddr
,
toAddr
,
bccAddr
,
testSendFlags
,
testExitCodeObj
,
testStatusFlagsObj
,
testErrorMsgObj
);
if
(
testStatusFlagsObj
.
value
)
{
// check if own key is invalid
let
errLines
=
testErrorMsgObj
.
value
.
split
(
/\r?\n/
);
let
s
=
new
RegExp
(
"INV_(RECP|SGNR) [0-9]+ \<?"
+
fromAddr
+
"\>?"
);
for
(
let
l
=
0
;
l
<
errLines
.
length
;
l
++
)
{
if
(
errLines
[
l
].
search
(
s
)
==
0
)
{
EnigmailCommon
.
alert
(
window
,
EnigmailCommon
.
getString
(
"errorKeyUnusable"
,
[
fromAddr
]));
return
null
;
}
}
}
if
((
recipientsSelection
==
4
)
||
((
testStatusFlagsObj
.
value
&
nsIEnigmail
.
INVALID_RECIPIENT
)
&&
(
recipientsSelection
==
2
||
recipientsSelection
==
3
)))
{
// check for invalid recipient keys
var
resultObj
=
new
Object
();
var
inputObj
=
new
Object
();
inputObj
.
toAddr
=
toAddr
;
inputObj
.
invalidAddr
=
Enigmail
.
hlp
.
getInvalidAddress
(
testErrorMsgObj
.
value
);
inputObj
.
options
=
"multisel"
;
if
(
recipientsSelection
==
2
)
inputObj
.
options
+=
",rulesOption"
if
(
notSignedIfNotEnc
)
inputObj
.
options
+=
",notsigned"
;
if
(
recipientsSelection
==
4
)
inputObj
.
options
+=
",noforcedisp"
;
inputObj
.
dialogHeader
=
EnigmailCommon
.
getString
(
"recipientsSelectionHdr"
);
window
.
openDialog
(
"chrome://enigmail/content/enigmailUserSelection.xul"
,
""
,
"dialog,modal,centerscreen"
,
inputObj
,
resultObj
);
try
{
if
(
resultObj
.
cancelled
)
{
return
null
;
}
if
(
resultObj
.
perRecipientRules
&&
this
.
enableRules
)
{
// do an extra round because the user want to set a PGP rule
continue
;
}
if
(
!
resultObj
.
encrypt
)
{
// encryption explicitely turned off
sendFlags
&=
~
ENCRYPT
;
if
(
notSignedIfNotEnc
)
sendFlags
&=
~
SIGN
;
}
else
{
if
(
bccAddrList
.
length
>
0
)
{
bccAddr
=
resultObj
.
userList
.
join
(
", "
);
toAddr
=
""
;
}
else
{
toAddr
=
resultObj
.
userList
.
join
(
", "
);
bccAddr
=
""
;
}
}
testCipher
=
"ok"
;
testExitCodeObj
.
value
=
0
;
}
catch
(
ex
)
{
// cancel pressed -> don't send mail
return
null
;
}
}
if
((
!
testCipher
||
(
testExitCodeObj
.
value
!=
0
))
&&
recipientsSelection
==
5
)
{
// Test encryption failed; turn off default encryption
sendFlags
&=
~
ENCRYPT
;
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg: No default encryption because test failed\n"
);
}
}
repeatSelection
=
2
;
}
if
((
gotSendFlags
&
ENCRYPT
)
&&
!
(
sendFlags
&
ENCRYPT
))
{
// Default encryption turned off; turn off signing as well
if
(
this
.
sendModeDirty
<
2
&&
(
!
this
.
getAccDefault
(
"signPlain"
)))
{
sendFlags
&=
~
SIGN
;
}
}
}
return
{
sendFlags
:
sendFlags
,
toAddr
:
toAddr
,
bccAddr
:
bccAddr
};
},
encryptMsg
:
function
(
msgSendType
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg: msgType="
+
msgSendType
+
", Enigmail.msg.sendMode="
+
this
.
sendMode
+
"\n"
);
const
nsIEnigmail
=
Components
.
interfaces
.
nsIEnigmail
;
const
SIGN
=
nsIEnigmail
.
SEND_SIGNED
;
const
ENCRYPT
=
nsIEnigmail
.
SEND_ENCRYPTED
;
var
promptSvc
=
EnigmailCommon
.
getPromptSvc
();
var
gotSendFlags
=
this
.
sendMode
;
var
sendFlags
=
0
;
window
.
enigmailSendFlags
=
0
;
switch
(
msgSendType
)
{
case
nsIMsgCompDeliverMode
.
Later
:
sendFlags
|=
nsIEnigmail
.
SEND_LATER
;
break
;
case
nsIMsgCompDeliverMode
.
SaveAsDraft
:
case
nsIMsgCompDeliverMode
.
SaveAsTemplate
:
case
nsIMsgCompDeliverMode
.
AutoSaveAsDraft
:
sendFlags
|=
nsIEnigmail
.
SAVE_MESSAGE
;
break
;
}
var
msgCompFields
=
gMsgCompose
.
compFields
;
var
newsgroups
=
msgCompFields
.
newsgroups
;
// Check if sending to any newsgroups
if
((
!
(
sendFlags
&
nsIEnigmail
.
SAVE_MESSAGE
))
&&
msgCompFields
.
to
==
""
&&
msgCompFields
.
cc
==
""
&&
msgCompFields
.
bcc
==
""
&&
newsgroups
==
""
)
{
// don't attempt to send message if no recipient specified
var
bundle
=
document
.
getElementById
(
"bundle_composeMsgs"
);
EnigmailCommon
.
alert
(
window
,
bundle
.
getString
(
"12511"
));
return
false
;
}
if
(
gotSendFlags
&
SIGN
)
sendFlags
|=
SIGN
;
if
(
gotSendFlags
&
ENCRYPT
)
{
sendFlags
|=
ENCRYPT
;
}
var
encryptIfPossible
=
false
;
if
(
sendFlags
&
nsIEnigmail
.
SAVE_MESSAGE
)
{
if
(
!
((
sendFlags
&
ENCRYPT
)
&&
EnigmailCommon
.
confirmPref
(
window
,
EnigmailCommon
.
getString
(
"savingMessage"
),
"saveEncrypted"
,
EnigmailCommon
.
getString
(
"msgCompose.button.encrypt"
),
EnigmailCommon
.
getString
(
"msgCompose.button.dontEncrypt"
))))
{
sendFlags
&=
~
ENCRYPT
;
if
(
this
.
attachOwnKeyObj
.
appendAttachment
)
this
.
attachOwnKey
();
if
(
sendFlags
&
SIGN
)
this
.
setDraftStatus
(
sendFlags
);
return
true
;
}
}
if
(
gWindowLocked
)
{
EnigmailCommon
.
alert
(
window
,
EnigmailCommon
.
getString
(
"windowLocked"
));
return
false
;
}
if
(
this
.
dirty
)
{
// make sure the sendFlags are reset before the message is processed
// (it may have been set by a previously cancelled send operation!)
try
{
if
(
gMsgCompose
.
compFields
.
securityInfo
instanceof
Components
.
interfaces
.
nsIEnigMsgCompFields
)
{
gMsgCompose
.
compFields
.
securityInfo
.
sendFlags
=
0
;
}
else
if
(
gMsgCompose
.
compFields
.
securityInfo
==
null
)
{
throw
"dummy"
;
}
}
catch
(
ex
){
try
{
var
newSecurityInfo
=
Components
.
classes
[
this
.
compFieldsEnig_CID
].
createInstance
(
Components
.
interfaces
.
nsIEnigMsgCompFields
);
if
(
newSecurityInfo
)
{
newSecurityInfo
.
sendFlags
=
0
;
gMsgCompose
.
compFields
.
securityInfo
=
newSecurityInfo
;
}
}
catch
(
ex
)
{
EnigmailCommon
.
writeException
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.attachKey"
,
ex
);
}
}
}
this
.
dirty
=
true
;
var
enigmailSvc
=
EnigmailCommon
.
getService
(
window
);
if
(
!
enigmailSvc
)
{
var
msg
=
EnigmailCommon
.
getString
(
"sendUnencrypted"
);
if
(
EnigmailCommon
.
enigmailSvc
&&
EnigmailCommon
.
enigmailSvc
.
initializationError
)
{
msg
=
EnigmailCommon
.
enigmailSvc
.
initializationError
+
"\n\n"
+
msg
;
}
return
EnigmailCommon
.
confirmDlg
(
window
,
msg
,
EnigmailCommon
.
getString
(
"msgCompose.button.send"
));
}
try
{
var
exitCodeObj
=
new
Object
();
var
statusFlagsObj
=
new
Object
();
var
errorMsgObj
=
new
Object
();
this
.
modifiedAttach
=
null
;
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg: currentId="
+
this
.
identity
+
", "
+
this
.
identity
.
email
+
"\n"
);
var
fromAddr
=
this
.
identity
.
email
;
var
pgpEnabled
=
this
.
getAccDefault
(
"enabled"
);
if
(
!
pgpEnabled
)
{
if
((
sendFlags
&
(
ENCRYPT
|
SIGN
))
||
this
.
attachOwnKeyObj
.
appendAttachment
)
{
if
(
!
EnigmailCommon
.
confirmDlg
(
window
,
EnigmailCommon
.
getString
(
"acctNotConfigured"
),
EnigmailCommon
.
getString
(
"msgCompose.button.send"
)))
return
false
;
}
return
true
;
}
var
optSendFlags
=
0
;
var
inlineEncAttach
=
false
;
if
(
EnigmailCommon
.
getPref
(
"alwaysTrustSend"
))
{
optSendFlags
|=
nsIEnigmail
.
SEND_ALWAYS_TRUST
;
}
if
(
EnigmailCommon
.
getPref
(
"encryptToSelf"
)
||
(
sendFlags
&
nsIEnigmail
.
SAVE_MESSAGE
))
{
optSendFlags
|=
nsIEnigmail
.
SEND_ENCRYPT_TO_SELF
;
}
sendFlags
|=
optSendFlags
;
var
userIdValue
=
this
.
getSenderUserId
();
if
(
userIdValue
)
{
fromAddr
=
userIdValue
;
}
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg:gMsgCompose="
+
gMsgCompose
+
"\n"
);
var
toAddrList
=
[];
var
bccAddrList
=
[];
if
(
sendFlags
&
nsIEnigmail
.
SAVE_MESSAGE
)
{
if
(
userIdValue
.
search
(
/@/
)
==
-
1
)
{
toAddrList
.
push
(
userIdValue
);
}
else
{
toAddrList
.
push
(
EnigmailFuncs
.
stripEmail
(
userIdValue
.
replace
(
/[\",]/g
,
""
)));
}
}
else
{
var
splitRecipients
;
var
arrLen
=
new
Object
();
splitRecipients
=
msgCompFields
.
splitRecipients
;
//EnigmailCommon.alert(window, typeof(msgCompFields.cc));
if
(
msgCompFields
.
to
.
length
>
0
)
{
var
recList
=
splitRecipients
(
msgCompFields
.
to
,
true
,
arrLen
)
this
.
addRecipients
(
toAddrList
,
recList
);
}
if
(
msgCompFields
.
cc
.
length
>
0
)
{
recList
=
splitRecipients
(
msgCompFields
.
cc
,
true
,
arrLen
)
this
.
addRecipients
(
toAddrList
,
recList
);
}
if
(
msgCompFields
.
bcc
.
length
>
0
)
{
recList
=
splitRecipients
(
msgCompFields
.
bcc
,
true
,
arrLen
)
var
bccLC
=
EnigmailFuncs
.
stripEmail
(
msgCompFields
.
bcc
).
toLowerCase
()
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg: BCC: "
+
bccLC
+
"\n"
);
var
selfBCC
=
this
.
identity
.
email
&&
(
this
.
identity
.
email
.
toLowerCase
()
==
bccLC
);
if
(
selfBCC
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg: Self BCC\n"
);
this
.
addRecipients
(
toAddrList
,
recList
);
}
else
if
(
sendFlags
&
ENCRYPT
)
{
// BCC and encryption
if
(
encryptIfPossible
)
{
sendFlags
&=
~
ENCRYPT
;
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg: No default encryption because of BCC\n"
);
}
else
{
var
dummy
=
{
value
:
null
};
var
hideBccUsers
=
promptSvc
.
confirmEx
(
window
,
EnigmailCommon
.
getString
(
"enigConfirm"
),
EnigmailCommon
.
getString
(
"sendingHiddenRcpt"
),
(
promptSvc
.
BUTTON_TITLE_IS_STRING
*
promptSvc
.
BUTTON_POS_0
)
+
(
promptSvc
.
BUTTON_TITLE_CANCEL
*
promptSvc
.
BUTTON_POS_1
)
+
(
promptSvc
.
BUTTON_TITLE_IS_STRING
*
promptSvc
.
BUTTON_POS_2
),
EnigmailCommon
.
getString
(
"sendWithShownBcc"
),
null
,
EnigmailCommon
.
getString
(
"sendWithHiddenBcc"
),
null
,
dummy
);
switch
(
hideBccUsers
)
{
case
2
:
this
.
addRecipients
(
bccAddrList
,
recList
);
// no break here on purpose!
case
0
:
this
.
addRecipients
(
toAddrList
,
recList
);
break
;
case
1
:
return
false
;
}
}
}
}
if
(
newsgroups
)
{
toAddrList
.
push
(
newsgroups
);
if
(
sendFlags
&
ENCRYPT
)
{
if
(
!
encryptIfPossible
)
{
if
(
!
EnigmailCommon
.
getPref
(
"encryptToNews"
))
{
EnigmailCommon
.
alert
(
window
,
EnigmailCommon
.
getString
(
"sendingNews"
));
return
false
;
}
else
if
(
!
EnigmailCommon
.
confirmPref
(
window
,
EnigmailCommon
.
getString
(
"sendToNewsWarning"
),
"warnOnSendingNewsgroups"
,
EnigmailCommon
.
getString
(
"msgCompose.button.send"
)))
{
return
false
;
}
}
else
{
sendFlags
&=
~
ENCRYPT
;
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg: No default encryption because of newsgroups\n"
);
}
}
}
}
var
usePGPMimeOption
=
EnigmailCommon
.
getPref
(
"usePGPMimeOption"
);
if
(
this
.
sendPgpMime
)
{
// Use PGP/MIME
sendFlags
|=
nsIEnigmail
.
SEND_PGP_MIME
;
}
var
result
=
this
.
keySelection
(
enigmailSvc
,
sendFlags
,
optSendFlags
,
gotSendFlags
,
fromAddr
,
toAddrList
,
bccAddrList
);
var
toAddr
;
var
bccAddr
;
if
(
!
result
)
{
return
false
;
}
else
{
sendFlags
=
result
.
sendFlags
;
toAddr
=
result
.
toAddr
;
bccAddr
=
result
.
bccAddr
;
}
if
(
sendFlags
&
nsIEnigmail
.
SAVE_MESSAGE
)
{
// always enable PGP/MIME if message is saved
sendFlags
|=
nsIEnigmail
.
SEND_PGP_MIME
;
}
if
(
this
.
attachOwnKeyObj
.
appendAttachment
)
this
.
attachOwnKey
();
var
bucketList
=
document
.
getElementById
(
"attachmentBucket"
);
var
hasAttachments
=
((
bucketList
&&
bucketList
.
hasChildNodes
())
||
gMsgCompose
.
compFields
.
attachVCard
);
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: hasAttachments = "
+
hasAttachments
+
"\n"
);
if
(
hasAttachments
&&
(
sendFlags
&
(
ENCRYPT
|
SIGN
))
&&
!
(
sendFlags
&
nsIEnigmail
.
SEND_PGP_MIME
)
&&
enigmailSvc
.
composeSecure
)
{
inputObj
=
new
Object
();
inputObj
.
pgpMimePossible
=
true
;
inputObj
.
inlinePossible
=
true
;
inputObj
.
restrictedScenario
=
false
;
// determine if attachments are all local files (currently the only
// supported kind of attachments)
var
node
=
bucketList
.
firstChild
;
while
(
node
)
{
if
(
node
.
attachment
.
url
.
substring
(
0
,
7
)
!=
"file://"
)
{
inputObj
.
inlinePossible
=
false
;
}
node
=
node
.
nextSibling
;
}
if
(
inputObj
.
pgpMimePossible
||
inputObj
.
inlinePossible
)
{
resultObj
=
new
Object
();
resultObj
.
selected
=
EnigmailCommon
.
getPref
(
"encryptAttachments"
);
//skip or not
var
skipCheck
=
EnigmailCommon
.
getPref
(
"encryptAttachmentsSkipDlg"
);
if
(
skipCheck
==
1
)
{
if
((
resultObj
.
selected
==
2
&&
inputObj
.
pgpMimePossible
==
false
)
||
(
resultObj
.
selected
==
1
&&
inputObj
.
inlinePossible
==
false
))
{
//add var to disable remember box since we're dealing with restricted scenarios...
inputObj
.
restrictedScenario
=
true
;
resultObj
.
selected
=
-
1
;
window
.
openDialog
(
"chrome://enigmail/content/enigmailAttachmentsDialog.xul"
,
""
,
"dialog,modal,centerscreen"
,
inputObj
,
resultObj
);
}
}
else
{
resultObj
.
selected
=
-
1
;
window
.
openDialog
(
"chrome://enigmail/content/enigmailAttachmentsDialog.xul"
,
""
,
"dialog,modal,centerscreen"
,
inputObj
,
resultObj
);
}
if
(
resultObj
.
selected
<
0
)
{
// dialog cancelled
return
false
;
}
else
if
(
resultObj
.
selected
==
1
)
{
// encrypt attachments
inlineEncAttach
=
true
;
}
else
if
(
resultObj
.
selected
==
2
)
{
// send as PGP/MIME
sendFlags
|=
nsIEnigmail
.
SEND_PGP_MIME
;
}
}
else
{
if
(
sendFlags
&
ENCRYPT
)
{
if
(
!
EnigmailCommon
.
confirmDlg
(
window
,
EnigmailCommon
.
getString
(
"attachWarning"
),
EnigmailCommon
.
getString
(
"msgCompose.button.send"
)))
return
false
;
}
}
}
var
usingPGPMime
=
(
sendFlags
&
nsIEnigmail
.
SEND_PGP_MIME
)
&&
(
sendFlags
&
(
ENCRYPT
|
SIGN
));
if
(
usingPGPMime
&&
!
enigmailSvc
.
composeSecure
)
{
if
(
!
EnigmailCommon
.
confirmDlg
(
window
,
EnigmailCommon
.
getString
(
"noPGPMIME"
),
EnigmailCommon
.
getString
(
"msgCompose.button.useInlinePGP"
)))
{
throw
Components
.
results
.
NS_ERROR_FAILURE
;
}
usingPGPMime
=
false
;
}
// Detect PGP/MIME and S/MIME
if
(
usingPGPMime
)
{
if
(
gMsgCompose
.
compFields
.
securityInfo
instanceof
Components
.
interfaces
.
nsIMsgSMIMECompFields
)
{
if
(
gMsgCompose
.
compFields
.
securityInfo
.
requireEncryptMessage
||
gMsgCompose
.
compFields
.
securityInfo
.
signMessage
)
{
var
prefAlgo
=
EnigmailCommon
.
getPref
(
"mimePreferPgp"
);
if
(
prefAlgo
==
1
)
{
var
checkedObj
=
{
value
:
null
};
var
prefAlgo
=
promptSvc
.
confirmEx
(
window
,
EnigmailCommon
.
getString
(
"enigConfirm"
),
EnigmailCommon
.
getString
(
"pgpMime_sMime.dlg.text"
),
(
promptSvc
.
BUTTON_TITLE_IS_STRING
*
promptSvc
.
BUTTON_POS_0
)
+
(
promptSvc
.
BUTTON_TITLE_CANCEL
*
promptSvc
.
BUTTON_POS_1
)
+
(
promptSvc
.
BUTTON_TITLE_IS_STRING
*
promptSvc
.
BUTTON_POS_2
),
EnigmailCommon
.
getString
(
"pgpMime_sMime.dlg.pgpMime.button"
),
null
,
EnigmailCommon
.
getString
(
"pgpMime_sMime.dlg.sMime.button"
),
EnigmailCommon
.
getString
(
"dlgKeepSetting"
),
checkedObj
);
if
(
checkedObj
.
value
&&
(
prefAlgo
==
0
||
prefAlgo
==
2
))
EnigmailCommon
.
setPref
(
"mimePreferPgp"
,
prefAlgo
);
}
switch
(
prefAlgo
)
{
case
0
:
gMsgCompose
.
compFields
.
securityInfo
.
requireEncryptMessage
=
false
;
gMsgCompose
.
compFields
.
securityInfo
.
signMessage
=
false
;
break
;
case
1
:
return
false
;
case
2
:
return
true
;
break
;
default
:
return
false
;
}
}
}
}
var
uiFlags
=
nsIEnigmail
.
UI_INTERACTIVE
;
if
(
usingPGPMime
)
uiFlags
|=
nsIEnigmail
.
UI_PGP_MIME
;
if
((
sendFlags
&
(
ENCRYPT
|
SIGN
))
&&
usingPGPMime
)
{
// Use EnigMime
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg: Using EnigMime, flags="
+
sendFlags
+
"\n"
);
var
oldSecurityInfo
=
gMsgCompose
.
compFields
.
securityInfo
;
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg: oldSecurityInfo = "
+
oldSecurityInfo
+
"\n"
);
if
(
!
oldSecurityInfo
)
{
try
{
newSecurityInfo
=
oldSecurityInfo
.
QueryInterface
(
Components
.
interfaces
.
nsIEnigMsgCompFields
);
}
catch
(
ex
)
{}
}
if
(
!
newSecurityInfo
)
{
newSecurityInfo
=
Components
.
classes
[
this
.
compFieldsEnig_CID
].
createInstance
(
Components
.
interfaces
.
nsIEnigMsgCompFields
);
if
(
!
newSecurityInfo
)
throw
Components
.
results
.
NS_ERROR_FAILURE
;
newSecurityInfo
.
init
(
oldSecurityInfo
);
gMsgCompose
.
compFields
.
securityInfo
=
newSecurityInfo
;
}
if
((
sendFlags
&
nsIEnigmail
.
SAVE_MESSAGE
)
&&
(
sendFlags
&
SIGN
))
{
this
.
setDraftStatus
(
sendFlags
);
sendFlags
&=
~
SIGN
;
}
newSecurityInfo
.
sendFlags
=
sendFlags
;
newSecurityInfo
.
UIFlags
=
uiFlags
;
newSecurityInfo
.
senderEmailAddr
=
fromAddr
;
newSecurityInfo
.
recipients
=
toAddr
;
newSecurityInfo
.
bccRecipients
=
bccAddr
;
newSecurityInfo
.
hashAlgorithm
=
this
.
mimeHashAlgo
[
EnigmailCommon
.
getPref
(
"mimeHashAlgorithm"
)];
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg: securityInfo = "
+
newSecurityInfo
+
"\n"
);
}
else
if
(
!
this
.
processed
&&
(
sendFlags
&
(
ENCRYPT
|
SIGN
)))
{
// use inline PGP
var
sendInfo
=
{
sendFlags
:
sendFlags
,
inlineEncAttach
:
inlineEncAttach
,
fromAddr
:
fromAddr
,
toAddr
:
toAddr
,
bccAddr
:
bccAddr
,
uiFlags
:
uiFlags
,
bucketList
:
bucketList
};
if
(
!
this
.
encryptInline
(
sendInfo
))
{
return
false
;
}
}
// EnigSend: Handle both plain and encrypted messages below
var
isOffline
=
(
gIOService
&&
gIOService
.
offline
);
window
.
enigmailSendFlags
=
sendFlags
;
// update the list of attachments
Attachments2CompFields
(
msgCompFields
);
if
((
!
(
sendFlags
&
nsIEnigmail
.
SAVE_MESSAGE
))
&&
EnigmailCommon
.
getPref
(
"confirmBeforeSend"
))
{
if
(
!
this
.
confirmBeforeSend
(
toAddrList
.
join
(
", "
),
toAddr
+
", "
+
bccAddr
,
sendFlags
,
isOffline
))
{
if
(
this
.
processed
)
{
this
.
undoEncryption
();
}
else
{
this
.
removeAttachedKey
();
}
return
false
;
}
}
else
if
(
(
sendFlags
&
nsIEnigmail
.
SEND_WITH_CHECK
)
&&
!
this
.
messageSendCheck
()
)
{
// Abort send
if
(
this
.
processed
)
{
this
.
undoEncryption
();
}
else
{
this
.
removeAttachedKey
();
}
return
false
;
}
if
(
msgCompFields
.
characterSet
!=
"ISO-2022-JP"
)
{
if
((
usingPGPMime
&&
((
sendFlags
&
(
ENCRYPT
|
SIGN
))))
||
((
!
usingPGPMime
)
&&
(
sendFlags
&
ENCRYPT
)))
{
try
{
// make sure plaintext is not changed to 7bit
if
(
typeof
(
msgCompFields
.
forceMsgEncoding
)
==
"boolean"
)
{
msgCompFields
.
forceMsgEncoding
=
true
;
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg: enabled forceMsgEncoding\n"
);
}
}
catch
(
ex
)
{}
}
}
}
catch
(
ex
)
{
EnigmailCommon
.
writeException
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg"
,
ex
);
msg
=
EnigmailCommon
.
getString
(
"signFailed"
);
if
(
EnigmailCommon
.
enigmailSvc
&&
EnigmailCommon
.
enigmailSvc
.
initializationError
)
{
msg
+=
"\n"
+
EnigmailCommon
.
enigmailSvc
.
initializationError
;
}
return
EnigmailCommon
.
confirmDlg
(
window
,
msg
,
EnigmailCommon
.
getString
(
"msgCompose.button.sendUnencrypted"
));
}
return
true
;
},
encryptInline
:
function
(
sendInfo
)
{
// sign/encrpyt message using inline-PGP
const
dce
=
Components
.
interfaces
.
nsIDocumentEncoder
const
nsIEnigmail
=
Components
.
interfaces
.
nsIEnigmail
;
const
SIGN
=
nsIEnigmail
.
SEND_SIGNED
;
const
ENCRYPT
=
nsIEnigmail
.
SEND_ENCRYPTED
;
var
enigmailSvc
=
EnigmailCommon
.
getService
(
window
);
if
(
!
enigmailSvc
)
return
false
;
if
(
gMsgCompose
.
composeHTML
)
{
var
errMsg
=
EnigmailCommon
.
getString
(
"hasHTML"
);
EnigmailCommon
.
alertCount
(
window
,
"composeHtmlAlertCount"
,
errMsg
);
}
try
{
var
convert
=
DetermineConvertibility
();
if
(
convert
==
nsIMsgCompConvertible
.
No
)
{
if
(
!
EnigmailCommon
.
confirmDlg
(
window
,
EnigmailCommon
.
getString
(
"strippingHTML"
),
EnigmailCommon
.
getString
(
"msgCompose.button.sendAnyway"
)))
{
return
false
;
}
}
}
catch
(
ex
)
{
EnigmailCommon
.
writeException
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptInline"
,
ex
);
}
try
{
if
(
this
.
getMailPref
(
"mail.strictly_mime"
))
{
if
(
EnigmailCommon
.
confirmPref
(
window
,
EnigmailCommon
.
getString
(
"quotedPrintableWarn"
),
"quotedPrintableWarn"
))
{
EnigmailCommon
.
prefRoot
.
setBoolPref
(
"mail.strictly_mime"
,
false
);
}
}
}
catch
(
ex
)
{}
var
sendFlowed
;
try
{
sendFlowed
=
this
.
getMailPref
(
"mailnews.send_plaintext_flowed"
);
}
catch
(
ex
)
{
sendFlowed
=
true
;
}
var
encoderFlags
=
dce
.
OutputFormatted
|
dce
.
OutputLFLineBreak
;
var
wrapper
=
gMsgCompose
.
editor
.
QueryInterface
(
Components
.
interfaces
.
nsIEditorMailSupport
);
var
editor
=
gMsgCompose
.
editor
.
QueryInterface
(
Components
.
interfaces
.
nsIPlaintextEditor
);
var
wrapWidth
=
72
;
if
(
!
(
sendInfo
.
sendFlags
&
ENCRYPT
))
{
// signed messages only
if
(
gMsgCompose
.
composeHTML
)
{
// enforce line wrapping here
// otherwise the message isn't signed correctly
try
{
wrapWidth
=
this
.
getMailPref
(
"editor.htmlWrapColumn"
);
if
(
wrapWidth
>
0
&&
wrapWidth
<
68
&&
gMsgCompose
.
wrapLength
>
0
)
{
if
(
EnigmailCommon
.
confirmDlg
(
window
,
EnigmailCommon
.
getString
(
"minimalLineWrapping"
,
[
wrapWidth
]
)))
{
EnigmailCommon
.
prefRoot
.
setIntPref
(
"editor.htmlWrapColumn"
,
68
)
}
}
if
(
EnigmailCommon
.
getPref
(
"wrapHtmlBeforeSend"
))
{
if
(
wrapWidth
)
{
editor
.
wrapWidth
=
wrapWidth
-
2
;
// prepare for the worst case: a 72 char's long line starting with '-'
wrapper
.
rewrap
(
false
);
}
}
}
catch
(
ex
)
{}
}
else
{
try
{
wrapWidth
=
this
.
getMailPref
(
"mailnews.wraplength"
);
if
(
wrapWidth
>
0
&&
wrapWidth
<
68
&&
editor
.
wrapWidth
>
0
)
{
if
(
EnigmailCommon
.
confirmDlg
(
window
,
EnigmailCommon
.
getString
(
"minimalLineWrapping"
,
[
wrapWidth
]
)))
{
wrapWidth
=
68
;
EnigmailCommon
.
prefRoot
.
setIntPref
(
"mailnews.wraplength"
,
wrapWidth
)
}
}
if
(
wrapWidth
&&
editor
.
wrapWidth
>
0
)
{
editor
.
wrapWidth
=
wrapWidth
-
2
;
wrapper
.
rewrap
(
true
);
editor
.
wrapWidth
=
wrapWidth
;
}
}
catch
(
ex
)
{}
}
}
https
:
//addons.mozilla.org/en-US/developers/addon/enigmail/versions/1394284
var
exitCodeObj
=
new
Object
();
var
statusFlagsObj
=
new
Object
();
var
errorMsgObj
=
new
Object
();
// Get plain text
// (Do we need to set the nsIDocumentEncoder.* flags?)
var
origText
=
this
.
editorGetContentAs
(
"text/plain"
,
encoderFlags
);
if
(
!
origText
)
origText
=
""
;
if
(
origText
.
length
>
0
)
{
// Sign/encrypt body text
var
escText
=
origText
;
// Copy plain text for possible escaping
if
(
sendFlowed
&&
!
(
sendInfo
.
sendFlags
&
ENCRYPT
))
{
// Prevent space stuffing a la RFC 2646 (format=flowed).
//EnigmailCommon.DEBUG_LOG("enigmailMsgComposeOverlay.js: escText["+encoderFlags+"] = '"+escText+"'\n");
// MULTILINE MATCHING ON
RegExp
.
multiline
=
true
;
escText
=
escText
.
replace
(
/^From /g
,
"~From "
);
escText
=
escText
.
replace
(
/^>/g
,
"|"
);
escText
=
escText
.
replace
(
/^[ \t]+$/g
,
""
);
escText
=
escText
.
replace
(
/^ /g
,
"~ "
);
// MULTILINE MATCHING OFF
RegExp
.
multiline
=
false
;
//EnigmailCommon.DEBUG_LOG("enigmailMsgComposeOverlay.js: escText = '"+escText+"'\n");
// Replace plain text and get it again
this
.
replaceEditorText
(
escText
);
escText
=
this
.
editorGetContentAs
(
"text/plain"
,
encoderFlags
);
}
// Replace plain text and get it again (to avoid linewrapping problems)
this
.
replaceEditorText
(
escText
);
escText
=
this
.
editorGetContentAs
(
"text/plain"
,
encoderFlags
);
//EnigmailCommon.DEBUG_LOG("enigmailMsgComposeOverlay.js: escText["+encoderFlags+"] = '"+escText+"'\n");
// Encrypt plaintext
var
charset
=
this
.
editorGetCharset
();
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptMsg: charset="
+
charset
+
"\n"
);
// Encode plaintext to charset from unicode
var
plainText
=
(
sendInfo
.
sendFlags
&
ENCRYPT
)
?
EnigmailCommon
.
convertFromUnicode
(
origText
,
charset
)
:
EnigmailCommon
.
convertFromUnicode
(
escText
,
charset
);
var
cipherText
=
enigmailSvc
.
encryptMessage
(
window
,
sendInfo
.
uiFlags
,
null
,
plainText
,
sendInfo
.
fromAddr
,
sendInfo
.
toAddr
,
sendInfo
.
bccAddr
,
sendInfo
.
sendFlags
,
exitCodeObj
,
statusFlagsObj
,
errorMsgObj
);
var
exitCode
=
exitCodeObj
.
value
;
//EnigmailCommon.DEBUG_LOG("enigmailMsgComposeOverlay.js: cipherText = '"+cipherText+"'\n");
if
(
cipherText
&&
(
exitCode
==
0
))
{
// Encryption/signing succeeded; overwrite plaintext
if
(
gMsgCompose
.
composeHTML
)
{
// workaround for Thunderbird bug (TB adds an extra space in front of the text)
cipherText
=
"\n"
+
cipherText
;
}
else
cipherText
=
cipherText
.
replace
(
/\r\n/g
,
"\n"
);
if
(
(
sendInfo
.
sendFlags
&
ENCRYPT
)
&&
charset
&&
(
charset
.
search
(
/^us-ascii$/i
)
!=
0
)
)
{
// Add Charset armor header for encrypted blocks
cipherText
=
cipherText
.
replace
(
/(-----BEGIN PGP MESSAGE----- *)(\r?\n)/
,
"$1$2Charset: "
+
charset
+
"$2"
);
}
// Decode ciphertext from charset to unicode and overwrite
this
.
replaceEditorText
(
EnigmailCommon
.
convertToUnicode
(
cipherText
,
charset
)
);
// Save original text (for undo)
this
.
processed
=
{
"origText"
:
origText
,
"charset"
:
charset
};
}
else
{
// Restore original text
this
.
replaceEditorText
(
origText
);
if
(
sendInfo
.
sendFlags
&
(
ENCRYPT
|
SIGN
))
{
// Encryption/signing failed
EnigmailCommon
.
alert
(
window
,
EnigmailCommon
.
getString
(
"sendAborted"
)
+
errorMsgObj
.
value
);
return
false
;
}
}
}
if
(
sendInfo
.
inlineEncAttach
)
{
// encrypt attachments
this
.
modifiedAttach
=
new
Array
();
exitCode
=
this
.
encryptAttachments
(
sendInfo
.
bucketList
,
this
.
modifiedAttach
,
window
,
sendInfo
.
uiFlags
,
sendInfo
.
fromAddr
,
sendInfo
.
toAddr
,
sendInfo
.
bccAddr
,
sendInfo
.
sendFlags
,
errorMsgObj
);
if
(
exitCode
!=
0
)
{
this
.
modifiedAttach
=
null
;
if
(
errorMsgObj
.
value
)
{
EnigmailCommon
.
alert
(
window
,
EnigmailCommon
.
getString
(
"sendAborted"
)
+
errorMsgObj
.
value
);
}
else
{
EnigmailCommon
.
alert
(
window
,
EnigmailCommon
.
getString
(
"sendAborted"
)
+
"an internal error has occurred"
);
}
if
(
this
.
processed
)
{
this
.
undoEncryption
();
}
else
{
this
.
removeAttachedKey
();
}
return
false
;
}
}
return
true
;
},
getMailPref
:
function
(
prefName
)
{
var
prefValue
=
null
;
try
{
var
prefType
=
EnigmailCommon
.
prefRoot
.
getPrefType
(
prefName
);
// Get pref value
switch
(
prefType
)
{
case
EnigmailCommon
.
prefBranch
.
PREF_BOOL
:
prefValue
=
EnigmailCommon
.
prefRoot
.
getBoolPref
(
prefName
);
break
;
case
EnigmailCommon
.
prefBranch
.
PREF_INT
:
prefValue
=
EnigmailCommon
.
prefRoot
.
getIntPref
(
prefName
);
break
;
case
EnigmailCommon
.
prefBranch
.
PREF_STRING
:
prefValue
=
EnigmailCommon
.
prefRoot
.
getCharPref
(
prefName
);
break
;
default
:
prefValue
=
undefined
;
break
;
}
}
catch
(
ex
)
{
// Failed to get pref value
EnigmailCommon
.
ERROR_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.getMailPref: unknown prefName:"
+
prefName
+
" \n"
);
}
return
prefValue
;
},
messageSendCheck
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.messageSendCheck\n"
);
try
{
var
warn
=
this
.
getMailPref
(
"mail.warn_on_send_accel_key"
);
if
(
warn
)
{
var
checkValue
=
{
value
:
false
};
var
bundle
=
document
.
getElementById
(
"bundle_composeMsgs"
);
var
buttonPressed
=
EnigmailCommon
.
getPromptSvc
().
confirmEx
(
window
,
bundle
.
getString
(
'sendMessageCheckWindowTitle'
),
bundle
.
getString
(
'sendMessageCheckLabel'
),
(
EnigmailCommon
.
getPromptSvc
().
BUTTON_TITLE_IS_STRING
*
EnigmailCommon
.
getPromptSvc
().
BUTTON_POS_0
)
+
(
EnigmailCommon
.
getPromptSvc
().
BUTTON_TITLE_CANCEL
*
EnigmailCommon
.
getPromptSvc
().
BUTTON_POS_1
),
bundle
.
getString
(
'sendMessageCheckSendButtonLabel'
),
null
,
null
,
bundle
.
getString
(
'CheckMsg'
),
checkValue
);
if
(
buttonPressed
!=
0
)
{
return
false
;
}
if
(
checkValue
.
value
)
{
EnigmailCommon
.
prefRoot
.
setBoolPref
(
"mail.warn_on_send_accel_key"
,
false
);
}
}
}
catch
(
ex
)
{}
return
true
;
},
modifyCompFields
:
function
(
msgCompFields
)
{
const
HEADERMODE_KEYID
=
0x01
;
const
HEADERMODE_URL
=
0x10
;
try
{
if
(
this
.
identity
.
getBoolAttribute
(
"enablePgp"
))
{
var
enigmailHeaders
=
""
;
if
(
EnigmailCommon
.
getPref
(
"addHeaders"
))
{
enigmailHeaders
+=
"X-Enigmail-Version: "
+
EnigmailCommon
.
getVersion
()
+
"\r\n"
;
}
var
pgpHeader
=
""
;
var
openPgpHeaderMode
=
this
.
identity
.
getIntAttribute
(
"openPgpHeaderMode"
);
if
(
openPgpHeaderMode
>
0
)
pgpHeader
=
"OpenPGP: "
;
if
(
openPgpHeaderMode
&
HEADERMODE_KEYID
)
{
var
keyId
=
this
.
identity
.
getCharAttribute
(
"pgpkeyId"
);
if
(
keyId
.
substr
(
0
,
2
).
toLowerCase
()
==
"0x"
)
{
pgpHeader
+=
"id="
+
keyId
.
substr
(
2
);
}
}
if
(
openPgpHeaderMode
&
HEADERMODE_URL
)
{
if
(
pgpHeader
.
indexOf
(
"="
)
>
0
)
pgpHeader
+=
";\r\n\t"
;
pgpHeader
+=
"url="
+
this
.
identity
.
getCharAttribute
(
"openPgpUrlName"
);
}
if
(
pgpHeader
.
length
>
0
)
{
enigmailHeaders
+=
pgpHeader
+
"\r\n"
;
}
msgCompFields
.
otherRandomHeaders
+=
enigmailHeaders
;
}
}
catch
(
ex
)
{
EnigmailCommon
.
writeException
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.modifyCompFields"
,
ex
);
}
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.modifyCompFields: otherRandomHeaders = "
+
msgCompFields
.
otherRandomHeaders
+
"\n"
);
},
sendMessageListener
:
function
(
event
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.sendMessageListener\n"
);
try
{
var
msgcomposeWindow
=
document
.
getElementById
(
"msgcomposeWindow"
);
this
.
modifyCompFields
(
gMsgCompose
.
compFields
);
if
(
!
this
.
encryptMsg
(
Number
(
msgcomposeWindow
.
getAttribute
(
"msgtype"
))))
{
this
.
removeAttachedKey
();
event
.
preventDefault
();
event
.
stopPropagation
();
}
}
catch
(
ex
)
{}
},
// Replacement for wrong charset conversion detection of Thunderbird
checkCharsetConversion
:
function
(
msgCompFields
)
{
const
dce
=
Components
.
interfaces
.
nsIDocumentEncoder
;
try
{
var
encoderFlags
=
dce
.
OutputFormatted
|
dce
.
OutputLFLineBreak
;
var
docText
=
this
.
editorGetContentAs
(
"text/plain"
,
encoderFlags
);
if
(
docText
.
length
>
0
)
{
var
converter
=
Components
.
classes
[
"@mozilla.org/intl/saveascharset;1"
].
createInstance
(
Components
.
interfaces
.
nsISaveAsCharset
);
converter
.
Init
(
msgCompFields
.
characterSet
,
0
,
1
);
return
(
converter
.
Convert
(
docText
).
length
>=
docText
.
length
);
}
}
catch
(
ex
)
{}
return
true
;
},
// encrypt attachments when sending inline PGP mails
// It's quite a hack: the attachments are stored locally
// and the attachments list is modified to pick up the
// encrypted file(s) instead of the original ones.
encryptAttachments
:
function
(
bucketList
,
newAttachments
,
window
,
uiFlags
,
fromAddr
,
toAddr
,
bccAddr
,
sendFlags
,
errorMsgObj
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptAttachments\n"
);
const
nsIEnigmail
=
Components
.
interfaces
.
nsIEnigmail
;
const
SIGN
=
nsIEnigmail
.
SEND_SIGNED
;
const
ENCRYPT
=
nsIEnigmail
.
SEND_ENCRYPTED
;
var
ioServ
;
var
fileTemplate
;
errorMsgObj
.
value
=
""
;
try
{
ioServ
=
Components
.
classes
[
EnigmailCommon
.
IOSERVICE_CONTRACTID
].
getService
(
Components
.
interfaces
.
nsIIOService
);
if
(
!
ioServ
)
return
-
1
;
}
catch
(
ex
)
{
return
-
1
;
}
var
tmpDir
=
EnigmailCommon
.
getTempDir
();
var
extAppLauncher
=
Components
.
classes
[
"@mozilla.org/mime;1"
].
getService
(
Components
.
interfaces
.
nsPIExternalAppLauncher
);
try
{
fileTemplate
=
Components
.
classes
[
EnigmailCommon
.
LOCAL_FILE_CONTRACTID
].
createInstance
(
EnigmailCommon
.
getLocalFileApi
());
fileTemplate
.
initWithPath
(
tmpDir
);
if
(
!
(
fileTemplate
.
isDirectory
()
&&
fileTemplate
.
isWritable
()))
{
errorMsgObj
.
value
=
EnigmailCommon
.
getString
(
"noTempDir"
);
return
-
1
;
}
fileTemplate
.
append
(
"encfile"
);
}
catch
(
ex
)
{
errorMsgObj
.
value
=
EnigmailCommon
.
getString
(
"noTempDir"
);
return
-
1
;
}
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.encryptAttachments tmpDir="
+
tmpDir
+
"\n"
);
var
enigmailSvc
=
EnigmailCommon
.
getService
(
window
);
if
(
!
enigmailSvc
)
return
null
;
var
exitCodeObj
=
new
Object
();
var
statusFlagsObj
=
new
Object
();
var
node
=
bucketList
.
firstChild
;
while
(
node
)
{
var
origUrl
=
node
.
attachment
.
url
;
if
(
origUrl
.
substring
(
0
,
7
)
!=
"file://"
)
{
// this should actually never happen since it is pre-checked!
errorMsgObj
.
value
=
"The attachment '"
+
node
.
attachment
.
name
+
"' is not a local file"
;
return
-
1
;
}
// transform attachment URL to platform-specific file name
var
origUri
=
ioServ
.
newURI
(
origUrl
,
null
,
null
);
var
origFile
=
origUri
.
QueryInterface
(
Components
.
interfaces
.
nsIFileURL
);
if
(
node
.
attachment
.
temporary
)
{
try
{
var
origLocalFile
=
Components
.
classes
[
EnigmailCommon
.
LOCAL_FILE_CONTRACTID
].
createInstance
(
EnigmailCommon
.
getLocalFileApi
());
origLocalFile
.
initWithPath
(
origFile
.
file
.
path
);
extAppLauncher
.
deleteTemporaryFileOnExit
(
origLocalFile
);
}
catch
(
ex
)
{}
}
var
newFile
=
fileTemplate
.
clone
();
var
txtMessage
;
try
{
newFile
.
createUnique
(
Components
.
interfaces
.
nsIFile
.
NORMAL_FILE_TYPE
,
0600
);
txtMessage
=
enigmailSvc
.
encryptAttachment
(
window
,
fromAddr
,
toAddr
,
bccAddr
,
sendFlags
,
origFile
.
file
,
newFile
,
exitCodeObj
,
statusFlagsObj
,
errorMsgObj
);
}
catch
(
ex
)
{}
if
(
exitCodeObj
.
value
!=
0
)
{
return
exitCodeObj
.
value
;
}
var
fileInfo
=
new
Object
();
fileInfo
.
origFile
=
origFile
;
fileInfo
.
origUrl
=
node
.
attachment
.
url
;
fileInfo
.
origName
=
node
.
attachment
.
name
;
fileInfo
.
origTemp
=
node
.
attachment
.
temporary
;
fileInfo
.
origCType
=
node
.
attachment
.
contentType
;
// transform platform specific new file name to file:// URL
var
newUri
=
ioServ
.
newFileURI
(
newFile
);
fileInfo
.
newUrl
=
newUri
.
asciiSpec
;
fileInfo
.
newFile
=
newFile
;
fileInfo
.
encrypted
=
(
sendFlags
&
ENCRYPT
);
newAttachments
.
push
(
fileInfo
);
node
=
node
.
nextSibling
;
}
var
i
=
0
;
if
(
sendFlags
&
ENCRYPT
)
{
// if we got here, all attachments were encrpted successfully,
// so we replace their names & urls
node
=
bucketList
.
firstChild
;
while
(
node
)
{
node
.
attachment
.
url
=
newAttachments
[
i
].
newUrl
;
node
.
attachment
.
name
+=
EnigmailCommon
.
getPref
(
"inlineAttachExt"
);
node
.
attachment
.
contentType
=
"application/octet-stream"
;
node
.
attachment
.
temporary
=
true
;
++
i
;
node
=
node
.
nextSibling
;
}
}
else
{
// for inline signing we need to add new attachments for every
// signed file
for
(
i
=
0
;
i
<
newAttachments
.
length
;
i
++
)
{
// create new attachment
var
fileAttachment
=
Components
.
classes
[
"@mozilla.org/messengercompose/attachment;1"
].
createInstance
(
Components
.
interfaces
.
nsIMsgAttachment
);
fileAttachment
.
temporary
=
true
;
fileAttachment
.
url
=
newAttachments
[
i
].
newUrl
;
fileAttachment
.
name
=
newAttachments
[
i
].
origName
+
EnigmailCommon
.
getPref
(
"inlineSigAttachExt"
);
// add attachment to msg
this
.
addAttachment
(
fileAttachment
);
}
}
return
0
;
},
toggleAttribute
:
function
(
attrName
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.toggleAttribute('"
+
attrName
+
"')\n"
);
var
menuElement
=
document
.
getElementById
(
"enigmail_"
+
attrName
);
var
oldValue
=
EnigmailCommon
.
getPref
(
attrName
);
EnigmailCommon
.
setPref
(
attrName
,
!
oldValue
);
},
toggleAccountAttr
:
function
(
attrName
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.toggleAccountAttr('"
+
attrName
+
"')\n"
);
var
oldValue
=
this
.
identity
.
getBoolAttribute
(
attrName
);
this
.
identity
.
setBoolAttribute
(
attrName
,
!
oldValue
)
},
toggleRules
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.toggleRules: Enigmail.msg.enableRules="
+
Enigmail
.
msg
.
enableRules
+
"\n"
);
this
.
enableRules
=
!
this
.
enableRules
;
},
decryptQuote
:
function
(
interactive
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.decryptQuote: "
+
interactive
+
"\n"
);
const
nsIEnigmail
=
Components
.
interfaces
.
nsIEnigmail
;
if
(
gWindowLocked
||
this
.
processed
)
return
;
var
enigmailSvc
=
EnigmailCommon
.
getService
(
window
);
if
(
!
enigmailSvc
)
return
;
const
dce
=
Components
.
interfaces
.
nsIDocumentEncoder
;
var
encoderFlags
=
dce
.
OutputFormatted
|
dce
.
OutputLFLineBreak
;
var
docText
=
this
.
editorGetContentAs
(
"text/plain"
,
encoderFlags
);
var
blockBegin
=
docText
.
indexOf
(
"-----BEGIN PGP "
);
if
(
blockBegin
<
0
)
return
;
// Determine indentation string
var
indentBegin
=
docText
.
substr
(
0
,
blockBegin
).
lastIndexOf
(
"\n"
);
var
indentStr
=
docText
.
substring
(
indentBegin
+
1
,
blockBegin
);
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.decryptQuote: indentStr='"
+
indentStr
+
"'\n"
);
var
beginIndexObj
=
new
Object
();
var
endIndexObj
=
new
Object
();
var
indentStrObj
=
new
Object
();
var
blockType
=
enigmailSvc
.
locateArmoredBlock
(
docText
,
0
,
indentStr
,
beginIndexObj
,
endIndexObj
,
indentStrObj
);
if
((
blockType
!=
"MESSAGE"
)
&&
(
blockType
!=
"SIGNED MESSAGE"
))
return
;
var
beginIndex
=
beginIndexObj
.
value
;
var
endIndex
=
endIndexObj
.
value
;
var
head
=
docText
.
substr
(
0
,
beginIndex
);
var
tail
=
docText
.
substr
(
endIndex
+
1
);
var
pgpBlock
=
docText
.
substr
(
beginIndex
,
endIndex
-
beginIndex
+
1
);
var
indentRegexp
;
if
(
indentStr
)
{
// MULTILINE MATCHING ON
RegExp
.
multiline
=
true
;
if
(
indentStr
==
"> "
)
{
// replace ">> " with "> > " to allow correct quoting
pgpBlock
=
pgpBlock
.
replace
(
/^>>/g
,
"> >"
);
}
// Delete indentation
indentRegexp
=
new
RegExp
(
"^"
+
indentStr
,
"g"
);
pgpBlock
=
pgpBlock
.
replace
(
indentRegexp
,
""
);
//tail = tail.replace(indentRegexp, "");
if
(
indentStr
.
match
(
/[ \t]*$/
))
{
indentStr
=
indentStr
.
replace
(
/[ \t]*$/g
,
""
);
indentRegexp
=
new
RegExp
(
"^"
+
indentStr
+
"$"
,
"g"
);
pgpBlock
=
pgpBlock
.
replace
(
indentRegexp
,
""
);
}
// Handle blank indented lines
pgpBlock
=
pgpBlock
.
replace
(
/^[ \t]*>[ \t]*$/g
,
""
);
//tail = tail.replace(/^[ \t]*>[ \t]*$/g, "");
// Trim leading space in tail
tail
=
tail
.
replace
(
/^\s*\n/
,
"\n"
);
// MULTILINE MATCHING OFF
RegExp
.
multiline
=
false
;
}
if
(
tail
.
search
(
/\S/
)
<
0
)
{
// No non-space characters in tail; delete it
tail
=
""
;
}
//EnigmailCommon.DEBUG_LOG("enigmailMsgComposeOverlay.js: Enigmail.msg.decryptQuote: pgpBlock='"+pgpBlock+"'\n");
var
charset
=
this
.
editorGetCharset
();
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.decryptQuote: charset="
+
charset
+
"\n"
);
// Encode ciphertext from unicode to charset
var
cipherText
=
EnigmailCommon
.
convertFromUnicode
(
pgpBlock
,
charset
);
if
((
!
this
.
getMailPref
(
"mailnews.reply_in_default_charset"
))
&&
(
blockType
==
"MESSAGE"
))
{
// set charset according to PGP block, if available (encrypted messages only)
cipherText
=
cipherText
.
replace
(
/\r\n/g
,
"\n"
);
cipherText
=
cipherText
.
replace
(
/\r/g
,
"\n"
);
var
cPos
=
cipherText
.
search
(
/\nCharset: .+\n/i
);
if
(
cPos
<
cipherText
.
search
(
/\n\n/
))
{
var
charMatch
=
cipherText
.
match
(
/\n(Charset: )(.+)\n/i
);
if
(
charMatch
&&
charMatch
.
length
>
2
)
{
charset
=
charMatch
[
2
];
gMsgCompose
.
SetDocumentCharset
(
charset
);
}
}
}
// Decrypt message
var
signatureObj
=
new
Object
();
signatureObj
.
value
=
""
;
var
exitCodeObj
=
new
Object
();
var
statusFlagsObj
=
new
Object
();
var
userIdObj
=
new
Object
();
var
keyIdObj
=
new
Object
();
var
sigDateObj
=
new
Object
();
var
errorMsgObj
=
new
Object
();
var
blockSeparationObj
=
new
Object
();
var
uiFlags
=
nsIEnigmail
.
UI_UNVERIFIED_ENC_OK
;
var
plainText
=
enigmailSvc
.
decryptMessage
(
window
,
uiFlags
,
cipherText
,
signatureObj
,
exitCodeObj
,
statusFlagsObj
,
keyIdObj
,
userIdObj
,
sigDateObj
,
errorMsgObj
,
blockSeparationObj
);
// Decode plaintext from charset to unicode
plainText
=
EnigmailCommon
.
convertToUnicode
(
plainText
,
charset
);
if
(
EnigmailCommon
.
getPref
(
"keepSettingsForReply"
))
{
if
(
statusFlagsObj
.
value
&
nsIEnigmail
.
DECRYPTION_OKAY
)
this
.
setSendMode
(
'encrypt'
);
}
var
exitCode
=
exitCodeObj
.
value
;
if
(
exitCode
!=
0
)
{
// Error processing
var
errorMsg
=
errorMsgObj
.
value
;
var
statusLines
=
errorMsg
.
split
(
/\r?\n/
);
var
displayMsg
;
if
(
statusLines
&&
statusLines
.
length
)
{
// Display only first ten lines of error message
while
(
statusLines
.
length
>
10
)
statusLines
.
pop
();
displayMsg
=
statusLines
.
join
(
"\n"
);
if
(
interactive
)
EnigmailCommon
.
alert
(
window
,
displayMsg
);
}
}
if
(
blockType
==
"MESSAGE"
&&
exitCode
==
0
&&
plainText
.
length
==
0
)
{
plainText
=
" "
;
}
if
(
!
plainText
)
{
if
(
blockType
!=
"SIGNED MESSAGE"
)
return
;
// Extract text portion of clearsign block
plainText
=
enigmailSvc
.
extractSignaturePart
(
pgpBlock
,
nsIEnigmail
.
SIGNATURE_TEXT
);
}
var
doubleDashSeparator
=
EnigmailCommon
.
getPref
(
"doubleDashSeparator"
)
if
(
gMsgCompose
.
type
!=
nsIMsgCompType
.
Template
&&
gMsgCompose
.
type
!=
nsIMsgCompType
.
Draft
&&
doubleDashSeparator
)
{
var
signOffset
=
plainText
.
search
(
/[\r\n]-- +[\r\n]/
);
if
(
signOffset
<
0
&&
blockType
==
"SIGNED MESSAGE"
)
{
signOffset
=
plainText
.
search
(
/[\r\n]--[\r\n]/
);
}
if
(
signOffset
>
0
)
{
// Strip signature portion of quoted message
plainText
=
plainText
.
substr
(
0
,
signOffset
+
1
);
}
}
var
clipBoard
=
Components
.
classes
[
"@mozilla.org/widget/clipboard;1"
].
getService
(
Components
.
interfaces
.
nsIClipboard
);
if
(
clipBoard
.
supportsSelectionClipboard
())
{
// get the clipboard contents for selected text (X11)
try
{
var
transferable
=
Components
.
classes
[
"@mozilla.org/widget/transferable;1"
].
createInstance
(
Components
.
interfaces
.
nsITransferable
);
transferable
.
addDataFlavor
(
"text/unicode"
);
clipBoard
.
getData
(
transferable
,
clipBoard
.
kSelectionClipboard
);
var
flavour
=
{};
var
data
=
{};
var
length
=
{};
transferable
.
getAnyTransferData
(
flavour
,
data
,
length
);
}
catch
(
ex
)
{}
}
// Replace encrypted quote with decrypted quote (destroys selection clipboard on X11)
this
.
editorSelectAll
();
//EnigmailCommon.DEBUG_LOG("enigmailMsgComposeOverlay.js: Enigmail.msg.decryptQuote: plainText='"+plainText+"'\n");
if
(
head
)
this
.
editorInsertText
(
head
);
var
quoteElement
;
if
(
indentStr
)
{
quoteElement
=
this
.
editorInsertAsQuotation
(
plainText
);
}
else
{
this
.
editorInsertText
(
plainText
);
}
if
(
tail
)
this
.
editorInsertText
(
tail
);
if
(
clipBoard
.
supportsSelectionClipboard
())
{
try
{
// restore the clipboard contents for selected text (X11)
var
pasteClipboard
=
Components
.
classes
[
"@mozilla.org/widget/clipboardhelper;1"
].
getService
(
Components
.
interfaces
.
nsIClipboardHelper
);
data
=
data
.
value
.
QueryInterface
(
Components
.
interfaces
.
nsISupportsString
).
data
;
pasteClipboard
.
copyStringToClipboard
(
data
,
clipBoard
.
kSelectionClipboard
);
}
catch
(
ex
)
{}
}
if
(
interactive
)
return
;
// Position cursor
var
replyOnTop
=
1
;
try
{
replyOnTop
=
this
.
identity
.
replyOnTop
;
}
catch
(
ex
)
{}
if
(
!
indentStr
||
!
quoteElement
)
replyOnTop
=
1
;
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.decryptQuote: replyOnTop="
+
replyOnTop
+
", quoteElement="
+
quoteElement
+
"\n"
);
var
nsISelectionController
=
Components
.
interfaces
.
nsISelectionController
;
if
(
this
.
editor
.
selectionController
)
{
var
selection
=
this
.
editor
.
selectionController
;
selection
.
completeMove
(
false
,
false
);
// go to start;
switch
(
replyOnTop
)
{
case
0
:
// Position after quote
this
.
editor
.
endOfDocument
();
if
(
tail
)
{
for
(
cPos
=
0
;
cPos
<
tail
.
length
;
cPos
++
)
{
selection
.
characterMove
(
false
,
false
);
// move backwards
}
}
break
;
case
2
:
// Select quote
if
(
head
)
{
for
(
cPos
=
0
;
cPos
<
head
.
length
;
cPos
++
)
{
selection
.
characterMove
(
true
,
false
);
}
}
selection
.
completeMove
(
true
,
true
);
if
(
tail
)
{
for
(
cPos
=
0
;
cPos
<
tail
.
length
;
cPos
++
)
{
selection
.
characterMove
(
false
,
true
);
// move backwards
}
}
break
;
default
:
// Position at beginning of document
if
(
this
.
editor
)
{
this
.
editor
.
beginningOfDocument
();
}
}
this
.
editor
.
selectionController
.
scrollSelectionIntoView
(
nsISelectionController
.
SELECTION_NORMAL
,
nsISelectionController
.
SELECTION_ANCHOR_REGION
,
true
);
}
},
editorInsertText
:
function
(
plainText
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.editorInsertText\n"
);
if
(
this
.
editor
)
{
var
mailEditor
;
try
{
mailEditor
=
this
.
editor
.
QueryInterface
(
Components
.
interfaces
.
nsIEditorMailSupport
);
mailEditor
.
insertTextWithQuotations
(
plainText
);
}
catch
(
ex
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.editorInsertText: no mail editor\n"
);
this
.
editor
.
insertText
(
plainText
);
}
}
},
editorInsertAsQuotation
:
function
(
plainText
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.editorInsertAsQuotation\n"
);
if
(
this
.
editor
)
{
var
mailEditor
;
try
{
mailEditor
=
this
.
editor
.
QueryInterface
(
Components
.
interfaces
.
nsIEditorMailSupport
);
}
catch
(
ex
)
{}
if
(
!
mailEditor
)
return
0
;
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.editorInsertAsQuotation: mailEditor="
+
mailEditor
+
"\n"
);
mailEditor
.
insertAsQuotation
(
plainText
);
return
1
;
}
return
0
;
},
editorSelectAll
:
function
()
{
if
(
this
.
editor
)
{
this
.
editor
.
selectAll
();
}
},
editorGetCharset
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.editorGetCharset\n"
);
return
this
.
editor
.
documentCharacterSet
;
},
editorGetContentAs
:
function
(
mimeType
,
flags
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.editorGetContentAs\n"
);
if
(
this
.
editor
)
{
return
this
.
editor
.
outputToString
(
mimeType
,
flags
);
}
},
focusChange
:
function
()
{
// call original TB function
CommandUpdate_MsgCompose
();
var
focusedWindow
=
top
.
document
.
commandDispatcher
.
focusedWindow
;
// we're just setting focus to where it was before
if
(
focusedWindow
==
Enigmail
.
msg
.
lastFocusedWindow
)
{
// skip
return
;
}
Enigmail
.
msg
.
lastFocusedWindow
=
focusedWindow
;
Enigmail
.
msg
.
fireSendFlags
()
},
fireSendFlags
:
function
()
{
try
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: Enigmail.msg.fireSendFlags\n"
);
if
(
!
this
.
determineSendFlagId
)
{
this
.
determineSendFlagId
=
EnigmailCommon
.
dispatchEvent
(
function
_sendFlagWrapper
()
{
Enigmail
.
msg
.
determineSendFlags
()
},
0
);
}
}
catch
(
ex
)
{}
}
};
Enigmail
.
composeStateListener
=
{
NotifyComposeFieldsReady
:
function
()
{
// Note: NotifyComposeFieldsReady is only called when a new window is created (i.e. not in case a window object is reused).
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: ECSL.NotifyComposeFieldsReady\n"
);
try
{
Enigmail
.
msg
.
editor
=
gMsgCompose
.
editor
.
QueryInterface
(
Components
.
interfaces
.
nsIEditor
);
}
catch
(
ex
)
{}
if
(
!
Enigmail
.
msg
.
editor
)
return
;
function
enigDocStateListener
()
{}
enigDocStateListener
.
prototype
=
{
QueryInterface
:
function
(
iid
)
{
if
(
!
iid
.
equals
(
Components
.
interfaces
.
nsIDocumentStateListener
)
&&
!
iid
.
equals
(
Components
.
interfaces
.
nsISupports
))
throw
Components
.
results
.
NS_ERROR_NO_INTERFACE
;
return
this
;
},
NotifyDocumentCreated
:
function
()
{
// EnigmailCommon.DEBUG_LOG("enigmailMsgComposeOverlay.js: EDSL.NotifyDocumentCreated\n");
},
NotifyDocumentWillBeDestroyed
:
function
()
{
// EnigmailCommon.DEBUG_LOG("enigmailMsgComposeOverlay.js: EDSL.enigDocStateListener.NotifyDocumentWillBeDestroyed\n");
},
NotifyDocumentStateChanged
:
function
(
nowDirty
)
{
}
}
var
docStateListener
=
new
enigDocStateListener
();
Enigmail
.
msg
.
editor
.
addDocumentStateListener
(
docStateListener
);
},
ComposeProcessDone
:
function
(
aResult
)
{
// Note: called after a mail was sent (or saved)
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: ECSL.ComposeProcessDone: "
+
aResult
+
"\n"
);
if
(
aResult
!=
Components
.
results
.
NS_OK
)
{
if
(
Enigmail
.
msg
.
processed
)
Enigmail
.
msg
.
undoEncryption
();
Enigmail
.
msg
.
removeAttachedKey
();
}
},
NotifyComposeBodyReady
:
function
()
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: ECSL.ComposeBodyReady\n"
);
var
isEmpty
,
isEditable
;
isEmpty
=
Enigmail
.
msg
.
editor
.
documentIsEmpty
;
isEditable
=
Enigmail
.
msg
.
editor
.
isDocumentEditable
;
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: EDSL.NotifyDocumentStateChanged: isEmpty="
+
isEmpty
+
", isEditable="
+
isEditable
+
"\n"
);
if
(
!
isEditable
||
isEmpty
)
return
;
if
(
!
Enigmail
.
msg
.
timeoutId
&&
!
Enigmail
.
msg
.
dirty
)
{
Enigmail
.
msg
.
timeoutId
=
EnigmailCommon
.
setTimeout
(
function
()
{
Enigmail
.
msg
.
decryptQuote
(
false
)
},
0
);
}
},
SaveInFolderDone
:
function
(
folderURI
)
{
//EnigmailCommon.DEBUG_LOG("enigmailMsgComposeOverlay.js: ECSL.SaveInFolderDone\n");
}
};
window
.
addEventListener
(
"load"
,
function
_enigmail_composeStartup
(
event
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: got load event\n"
);
Enigmail
.
msg
.
composeStartup
(
event
);
},
false
);
window
.
addEventListener
(
"unload"
,
function
_enigmail_composeUnload
(
event
)
{
Enigmail
.
msg
.
composeUnload
(
event
);
},
false
);
// Handle recycled windows
window
.
addEventListener
(
'compose-window-close'
,
function
_enigmail_msgComposeClose
(
event
)
{
Enigmail
.
msg
.
msgComposeClose
(
event
);
},
true
);
window
.
addEventListener
(
'compose-window-reopen'
,
function
_enigmail_msgComposeReopen
(
event
)
{
Enigmail
.
msg
.
msgComposeReopen
(
event
);
},
true
);
// Listen to message sending event
window
.
addEventListener
(
'compose-send-message'
,
function
_enigmail_sendMessageListener
(
event
)
{
Enigmail
.
msg
.
sendMessageListener
(
event
);
},
true
);
window
.
addEventListener
(
'compose-window-init'
,
function
_enigmail_composeWindowInit
(
event
)
{
EnigmailCommon
.
DEBUG_LOG
(
"enigmailMsgComposeOverlay.js: _enigmail_composeWindowInit\n"
);
gMsgCompose
.
RegisterStateListener
(
Enigmail
.
composeStateListener
);
},
true
);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Thu, Feb 26, 7:17 PM (15 h, 29 m)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
4e/a7/32fc0fad93d7789cd0ed84c393bd
Attached To
rENIG Enigmail
Event Timeline
Log In to Comment