зеркало из https://github.com/mozilla/pjs.git
NOT PART OF THE BUILD
Adding new smime extension files. NOT PART OF THE BUILD
This commit is contained in:
Родитель
6f3ef7d321
Коммит
d08deab452
|
@ -0,0 +1,133 @@
|
|||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998-2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributors:
|
||||
* ddrinan@netscape.com
|
||||
* Scott MacGregor <mscott@netscape.com>
|
||||
*/
|
||||
|
||||
var gIdentity;
|
||||
var gPref = null;
|
||||
var gEncryptionCertName = null;
|
||||
var gEncryptIfPossible = null;
|
||||
var gEncryptAlways = null;
|
||||
var gSignCertName = null;
|
||||
var gSignMessages = null;
|
||||
|
||||
function onInit()
|
||||
{
|
||||
// initialize all of our elements based on the current identity values....
|
||||
gEncryptionCertName = document.getElementById("identity.encryption_cert_name");
|
||||
gEncryptIfPossible = document.getElementById("identity.encrypt_mail_if_possible");
|
||||
gEncryptAlways = document.getElementById("identity.encrypt_mail_always");
|
||||
gSignCertName = document.getElementById("identity.signing_cert_name");
|
||||
gSignMessages = document.getElementById("identity.sign_mail");
|
||||
|
||||
gEncryptionCertName.value = gIdentity.getUnicharAttribute("encryption_cert_name");
|
||||
gEncryptIfPossible.checked = gIdentity.getBoolAttribute("encrypt_mail_if_possible");
|
||||
gEncryptAlways.checked = gIdentity.getBoolAttribute("encrypt_mail_always");
|
||||
if (!gEncryptionCertName.value)
|
||||
{
|
||||
gEncryptAlways.setAttribute("disabled", true);
|
||||
}
|
||||
|
||||
// we currently don't support encrypt if possible so keep it disabled for now...
|
||||
gEncryptIfPossible.setAttribute("disabled", true);
|
||||
|
||||
gSignCertName.value = gIdentity.getUnicharAttribute("signing_cert_name");
|
||||
gSignMessages.checked = gIdentity.getBoolAttribute("sign_mail");
|
||||
if (!gSignCertName.value)
|
||||
{
|
||||
gSignMessages.setAttribute("disabled", true);
|
||||
}
|
||||
}
|
||||
|
||||
function onPreInit(account, accountValues)
|
||||
{
|
||||
gIdentity = account.defaultIdentity;
|
||||
}
|
||||
|
||||
function onSave()
|
||||
{
|
||||
}
|
||||
|
||||
function onLockPreference()
|
||||
{
|
||||
dump("XXX on lock\n");
|
||||
}
|
||||
|
||||
|
||||
// Does the work of disabling an element given the array which contains xul id/prefstring pairs.
|
||||
// Also saves the id/locked state in an array so that other areas of the code can avoid
|
||||
// stomping on the disabled state indiscriminately.
|
||||
function disableIfLocked( prefstrArray )
|
||||
{
|
||||
if (!gLockedPref)
|
||||
gLockedPref = new Array;
|
||||
|
||||
for (i=0; i<prefstrArray.length; i++) {
|
||||
var id = prefstrArray[i].id;
|
||||
var element = document.getElementById(id);
|
||||
if (gPref.prefIsLocked(prefstrArray[i].prefstring)) {
|
||||
element.disabled = true;
|
||||
gLockedPref[id] = true;
|
||||
} else {
|
||||
element.removeAttribute("disabled");
|
||||
gLockedPref[id] = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function smimeSelectCert(smime_cert)
|
||||
{
|
||||
var picker = Components.classes["@mozilla.org/user_cert_picker;1"]
|
||||
.getService(Components.interfaces.nsIUserCertPicker);
|
||||
var canceled = new Object;
|
||||
var x509cert = 0;
|
||||
var certUsage;
|
||||
|
||||
if (smime_cert == "identity.encryption_cert_name") {
|
||||
certUsage = 5;
|
||||
} else if (smime_cert == "identity.signing_cert_name") {
|
||||
certUsage = 4;
|
||||
}
|
||||
|
||||
try {
|
||||
var smimeBundle = document.getElementById("bundle_smime");
|
||||
x509cert = picker.pickByUsage(window,
|
||||
smimeBundle.getString("prefPanel-smime"),
|
||||
smimeBundle.getString("smimeCertPrompt"),
|
||||
certUsage, // this is from enum SECCertUsage
|
||||
false, false, canceled);
|
||||
} catch(e) {
|
||||
// XXX display error message in the future
|
||||
}
|
||||
|
||||
if (!canceled.value && x509cert) {
|
||||
var certInfo = document.getElementById(smime_cert);
|
||||
if (certInfo) {
|
||||
certInfo.setAttribute("disabled", "false");
|
||||
certInfo.value = x509cert.nickname;
|
||||
|
||||
if (smime_cert == "identity.encryption_cert_name") {
|
||||
gEncryptAlways.removeAttribute("disabled");
|
||||
} else {
|
||||
gSignMessages.removeAttribute("disabled");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<!--
|
||||
|
||||
The contents of this file are subject to the Netscape Public
|
||||
License Version 1.1 (the "License"); you may not use this file
|
||||
except in compliance with the License. You may obtain a copy of
|
||||
the License at http://www.mozilla.org/NPL/
|
||||
|
||||
Software distributed under the License is distributed on an "AS
|
||||
IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
implied. See the License for the specific language governing
|
||||
rights and limitations under the License.
|
||||
|
||||
The Initial Developer of the Original Code is Netscape
|
||||
Communications Corporation. Portions created by Netscape are
|
||||
Copyright (C) 1998-2001 Netscape Communications Corporation. All
|
||||
Rights Reserved.
|
||||
|
||||
Contributors:
|
||||
ddrinan@netscape.com
|
||||
Scott MacGregor <mscott@netscape.com>
|
||||
|
||||
-->
|
||||
|
||||
<?xml-stylesheet href="chrome://messenger/skin/accountManage.css" type="text/css"?>
|
||||
<?xul-overlay href="chrome://global/content/dialogOverlay.xul"?>
|
||||
|
||||
<!DOCTYPE window SYSTEM "chrome://messenger/locale/am-smime.dtd">
|
||||
|
||||
<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
|
||||
xmlns:html="http://www.w3.org/1999/xhtml"
|
||||
class="color-dialog"
|
||||
onload="parent.onPanelLoaded('am-smime.xul');"
|
||||
orient="vertical">
|
||||
|
||||
<stringbundle id="bundle_smime" src="chrome://messenger/locale/am-smime.properties"/>
|
||||
<script type="application/x-javascript" src="chrome://messenger/content/AccountManager.js"/>
|
||||
<script type="application/x-javascript" src="chrome://messenger/content/am-smime.js"/>
|
||||
|
||||
<hbox class="box-smallheader" title="&securityTitle.label;" />
|
||||
|
||||
<groupbox orient="vertical" id="encryption.titlebox">
|
||||
<caption label="&encryptionGroupTitle.label;"/>
|
||||
|
||||
<label value="&encryptionCert.message;"/>
|
||||
<separator class="thin"/>
|
||||
|
||||
<textbox id="identity.encryption_cert_name" iscontrolcontainer="true" wsm_persist="true" genericattr="true" flex="1"
|
||||
pref="true" preftype="wstring" prefattribute="value"
|
||||
prefstring="mail.identity.%identitykey%.encryption_cert_name" readonly="true" disabled="true"/>
|
||||
|
||||
<separator class="thin"/>
|
||||
<hbox>
|
||||
<spacer flex="1"/>
|
||||
<button id="encryptionCertSelectButton"
|
||||
label="&certificate.button;"
|
||||
oncommand="smimeSelectCert('identity.encryption_cert_name')"/>
|
||||
</hbox>
|
||||
|
||||
<checkbox id="identity.encrypt_mail_if_possible" iscontrolcontainer="true" wsm_persist="true" genericattr="true" pref="true"
|
||||
preftype="bool" prefattribute="value"
|
||||
prefstring="mail.identity.%identitykey%.encrypt_mail_if_possible"
|
||||
label="&ifPossibleEncryptMessage.label;" />
|
||||
|
||||
<checkbox id="identity.encrypt_mail_always" iscontrolcontainer="true" wsm_persist="true" genericattr="true" pref="true"
|
||||
preftype="bool" prefattribute="value"
|
||||
prefstring="mail.identity.%identitykey%.encrypt_mail_always"
|
||||
label="&alwaysEncryptMessage.label;" />
|
||||
</groupbox>
|
||||
|
||||
<separator class="thin"/>
|
||||
<groupbox orient="vertical" id="signing.titlebox">
|
||||
<caption label="&signingGroupTitle.label;"/>
|
||||
|
||||
<label value="&signingCert.message;"/>
|
||||
<separator class="thin"/>
|
||||
|
||||
<textbox id="identity.signing_cert_name" iscontrolcontainer="true" wsm_persist="true" genericattr="true" flex="1"
|
||||
pref="true" preftype="wstring" prefattribute="value"
|
||||
prefstring="mail.identity.%identitykey%.signing_cert_name" readonly="true" disabled="true"/>
|
||||
|
||||
<separator class="thin"/>
|
||||
|
||||
<hbox>
|
||||
<spacer flex="1"/>
|
||||
<button id="signingCertSelectButton"
|
||||
label="&certificate.button;"
|
||||
oncommand="smimeSelectCert('identity.signing_cert_name')"/>
|
||||
</hbox>
|
||||
|
||||
<checkbox id="identity.sign_mail" iscontrolcontainer="true" wsm_persist="true" genericattr="true" pref="true"
|
||||
preftype="bool" prefattribute="value"
|
||||
prefstring="mail.identity.%identitykey%.sign_mail"
|
||||
label="&signMessage.label;"/>
|
||||
</groupbox>
|
||||
</page>
|
|
@ -0,0 +1,29 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:chrome="http://chrome.mozilla.org/rdf#">
|
||||
|
||||
<!-- list all the packages being supplied by this jar -->
|
||||
<RDF:Seq about="urn:mozilla:package:root">
|
||||
<RDF:li resource="urn:mozilla:package:messenger-smime"/>
|
||||
</RDF:Seq>
|
||||
|
||||
<!-- package information -->
|
||||
<RDF:Description about="urn:mozilla:package:messenger-smime"
|
||||
chrome:displayName="Messenger"
|
||||
chrome:author="mozilla.org"
|
||||
chrome:name="messenger-smime"
|
||||
chrome:localeVersion="0.9.4"
|
||||
chrome:skinVersion="0.9.4">
|
||||
</RDF:Description>
|
||||
|
||||
<!-- overlay information -->
|
||||
<RDF:Seq about="urn:mozilla:overlays">
|
||||
<RDF:li resource="chrome://messenger/content/messengercompose/messengercompose.xul"/>
|
||||
</RDF:Seq>
|
||||
|
||||
<RDF:Seq about="chrome://messenger/content/messengercompose/messengercompose.xul">
|
||||
<RDF:li>chrome://messenger-smime/content/msgCompSMIMEOverlay.xul</RDF:li>
|
||||
</RDF:Seq>
|
||||
|
||||
</RDF:RDF>
|
|
@ -0,0 +1,45 @@
|
|||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..\..\..
|
||||
|
||||
CHROME_DIR=packages\messenger
|
||||
CHROME_CONTENT_DIR=messenger\content
|
||||
CHROME_MISC_DIR=.
|
||||
CHROME_TYPE=content
|
||||
|
||||
CHROME_CONTENT = \
|
||||
.\am-smime.xul \
|
||||
.\am-smime.js \
|
||||
.\msgCompSMIMEOverlay.js \
|
||||
.\msgCompSMIMEOverlay.xul \
|
||||
.\contents.rdf \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install::
|
||||
$(MAKE_INSTALL) .\smime.js $(DIST)\bin\defaults\pref
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
chrome::
|
||||
$(REGCHROME) content messenger-smime messenger.jar
|
|
@ -0,0 +1,115 @@
|
|||
/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998-2001 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributors:
|
||||
* ddrinan@netscape.com
|
||||
* Scott MacGreogr <mscott@netscape.com>
|
||||
*/
|
||||
|
||||
var ismimeCompFields = Components.interfaces.nsIMsgSMIMECompFields;
|
||||
var smimeCompFieldsContractID = "@mozilla.org/messenger-smime/composefields;1";
|
||||
|
||||
// InitializeSecurityInfo --> when we want to override the default smime behavior for the current message,
|
||||
// we need to make sure we have a security info object on the msg compose fields....
|
||||
function GetSecurityInfo()
|
||||
{
|
||||
var smimeComposefields;
|
||||
var msgCompFields = msgCompose.compFields;
|
||||
if (msgCompFields)
|
||||
{
|
||||
if (!msgCompFields.securityInfo)
|
||||
{
|
||||
smimeComposefields = Components.classes[smimeCompFieldsContractID].createInstance(ismimeCompFields);
|
||||
if (smimeComposefields)
|
||||
{
|
||||
msgCompFields.securityInfo = smimeComposefields;
|
||||
// set up the intial security state....
|
||||
smimeComposefields.alwaysEncryptMessage = gCurrentIdentity.getBoolAttribute("encrypt_mail_always");
|
||||
smimeComposefields.signMessage = gCurrentIdentity.getBoolAttribute("sign_mail");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
smimeComposefields = msgCompFields.securityInfo;
|
||||
}
|
||||
} // if we have message compose fields...
|
||||
|
||||
return smimeComposefields
|
||||
}
|
||||
|
||||
function encryptMessage()
|
||||
{
|
||||
var checkedNode = document.getElementById("menu_securityEncryptAlways");
|
||||
var checked = checkedNode.getAttribute("checked");
|
||||
|
||||
var smimeCompFields = GetSecurityInfo();
|
||||
|
||||
if (checked)
|
||||
{
|
||||
var encryptionCertName = gCurrentIdentity.getUnicharAttribute("encryption_cert_name");
|
||||
if (!encryptionCertName)
|
||||
{
|
||||
alert(gComposeMsgsBundle.getString("chooseEncryptionCertMsg"));
|
||||
checkedNode.removeAttribute("checked");
|
||||
smimeCompFields.signMessage = false;
|
||||
return;
|
||||
}
|
||||
|
||||
smimeCompFields.alwaysEncryptMessage = true;
|
||||
checkedNode.setAttribute("checked", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
smimeCompFields.alwaysEncryptMessage = false;
|
||||
checkedNode.removeAttribute("checked");
|
||||
}
|
||||
}
|
||||
|
||||
function signMessage()
|
||||
{
|
||||
var checkedNode = document.getElementById("menu_securitySign");
|
||||
var checked = checkedNode.getAttribute("checked");
|
||||
|
||||
var smimeCompFields = GetSecurityInfo();
|
||||
|
||||
if (checked) // if checked, make sure we have a cert name...
|
||||
{
|
||||
var signingCertName = gCurrentIdentity.getUnicharAttribute("signing_cert_name");
|
||||
if (!signingCertName)
|
||||
{
|
||||
alert(gComposeMsgsBundle.getString("chooseSigningCertMsg"));
|
||||
checkedNode.removeAttribute("checked");
|
||||
smimeCompFields.signMessage = false;
|
||||
return;
|
||||
}
|
||||
|
||||
smimeCompFields.signMessage = true;
|
||||
checkedNode.setAttribute("checked", true);
|
||||
}
|
||||
else
|
||||
{
|
||||
smimeCompFields.signMessage = false;
|
||||
checkedNode.removeAttribute("checked");
|
||||
}
|
||||
}
|
||||
|
||||
function setSecuritySettings()
|
||||
{
|
||||
var smimeCompFields = GetSecurityInfo();
|
||||
document.getElementById("menu_securityEncryptAlways").setAttribute("checked", smimeCompFields.alwaysEncryptMessage);
|
||||
document.getElementById("menu_securitySign").setAttribute("checked", smimeCompFields.signMessage);
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<?xml version="1.0"?>
|
||||
<!--
|
||||
- The contents of this file are subject to the Netscape Public
|
||||
- License Version 1.1 (the "License"); you may not use this file
|
||||
- except in compliance with the License. You may obtain a copy of
|
||||
- the License at http://www.mozilla.org/NPL/
|
||||
-
|
||||
- Software distributed under the License is distributed on an "AS
|
||||
- IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
- implied. See the License for the specific language governing
|
||||
- rights and limitations under the License.
|
||||
-
|
||||
- The Original Code is Mozilla Communicator client code, released
|
||||
- March 31, 1998.
|
||||
-
|
||||
- The Initial Developer of the Original Code is Netscape
|
||||
- Communications Corporation. Portions created by Netscape are
|
||||
- Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
- Rights Reserved.
|
||||
-
|
||||
- Contributor(s):
|
||||
- David Drinan <ddrinan@netscape.com>
|
||||
- Scott MacGregor <mscott@netscape.com
|
||||
-->
|
||||
|
||||
|
||||
<!DOCTYPE overlay SYSTEM "chrome://messenger-smime/locale/msgCompSMIMEOverlay.dtd">
|
||||
|
||||
<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
|
||||
<script language="JavaScript" src="chrome://messenger-smime/content/msgCompSMIMEOverlay.js"/>
|
||||
|
||||
<menupopup id="optionsMenuPopup">
|
||||
<menuseparator insertafter="fccMenu"/>
|
||||
<menu label="&securityMenu.label;">
|
||||
<menupopup onpopupshowing="setSecuritySettings()">
|
||||
<menuitem id="menu_securityEncryptIfPossible" type="checkbox" label="&menu_securityEncryptIfPossible.label;" disabled="true"/>
|
||||
<menuitem id="menu_securityEncryptAlways" type="checkbox" label="&menu_securityEncryptAlways.label;" oncommand="encryptMessage()"/>
|
||||
<menuitem id="menu_securitySign" type="checkbox" label="&menu_securitySign.label;" oncommand="signMessage()"/>
|
||||
</menupopup>
|
||||
</menu>
|
||||
</menupopup>
|
||||
|
||||
</overlay>
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
/*
|
||||
Add any default pref values we want for smime
|
||||
*/
|
||||
|
||||
pref("mail.identity.default.encryption_cert_name","");
|
||||
pref("mail.identity.default.encrypt_mail_if_possible", false);
|
||||
pref("mail.identity.default.encrypt_mail_always", false);
|
||||
pref("mail.identity.default.signing_cert_name", "");
|
||||
pref("mail.identity.default.sign_mail", false);
|
||||
|
||||
|
|
@ -0,0 +1,11 @@
|
|||
<!ENTITY securityTitle.label "Security">
|
||||
<!ENTITY encryptionGroupTitle.label "Encryption">
|
||||
<!ENTITY ifPossibleEncryptMessage.label "Encrypt messages if possible">
|
||||
<!ENTITY alwaysEncryptMessage.label "Always encrypt messages">
|
||||
<!ENTITY encryptionCert.message "Personal certificate used for encryption:">
|
||||
<!ENTITY encryptionCert.notselected "No certificate set">
|
||||
<!ENTITY certificate.button "Select Certificate">
|
||||
<!ENTITY signingGroupTitle.label "Signing">
|
||||
<!ENTITY signMessage.label "Digitally sign messages">
|
||||
<!ENTITY signingCert.message "Personal certificate used for signing:">
|
||||
<!ENTITY signingCert.notselected "No certificate set">
|
|
@ -0,0 +1,3 @@
|
|||
prefPanel-smime=Secure Mail
|
||||
smimeCertPrompt=Select the certificate that you want to use:
|
||||
|
|
@ -0,0 +1,23 @@
|
|||
<?xml version="1.0"?>
|
||||
<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:chrome="http://www.mozilla.org/rdf/chrome#">
|
||||
|
||||
<!-- list all the skins being supplied by this package -->
|
||||
<RDF:Seq about="urn:mozilla:locale:root">
|
||||
<RDF:li resource="urn:mozilla:locale:en-US"/>
|
||||
</RDF:Seq>
|
||||
|
||||
<!-- locale information -->
|
||||
<RDF:Description about="urn:mozilla:locale:en-US">
|
||||
<chrome:packages>
|
||||
<RDF:Seq about="urn:mozilla:locale:en-US:packages">
|
||||
<RDF:li resource="urn:mozilla:locale:en-US:messenger-smime"/>
|
||||
</RDF:Seq>
|
||||
</chrome:packages>
|
||||
</RDF:Description>
|
||||
|
||||
<!-- Version Information. State that we work only with major version of this
|
||||
package. -->
|
||||
<RDF:Description about="urn:mozilla:locale:en-US:messenger-smime"
|
||||
chrome:localeVersion="0.9.4"/>
|
||||
</RDF:RDF>
|
|
@ -0,0 +1,38 @@
|
|||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..\..\..\..
|
||||
|
||||
CHROME_DIR=locales\en-US
|
||||
CHROME_L10N_DIR=messenger\locale
|
||||
|
||||
CHROME_L10N = \
|
||||
.\am-smime.dtd \
|
||||
.\am-smime.properties \
|
||||
.\msgCompSMIMEOverlay.dtd \
|
||||
.\contents.rdf \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
chrome::
|
||||
$(REGCHROME) locale en-US/messenger-smime en-US.jar
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
<!--LOCALIZATION NOTE msgCompSMIMEOverlay.dtd UI for s/mime hooks in message composition -->
|
||||
|
||||
<!ENTITY securityMenu.label "Security">
|
||||
<!ENTITY menu_securityEncryptIfPossible.label "Encrypt if Possible">
|
||||
<!ENTITY menu_securityEncryptAlways.label "Always Encrypt">
|
||||
<!ENTITY menu_securitySign.label "Sign">
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
#
|
||||
|
||||
DEPTH = ../../../..
|
||||
topsrcdir = @top_srcdir@
|
||||
srcdir = @srcdir@
|
||||
VPATH = @srcdir@
|
||||
|
||||
include $(DEPTH)/config/autoconf.mk
|
||||
|
||||
MODULE = msgsmime
|
||||
LIBRARY_NAME = msgsmime_s
|
||||
META_COMPONENT = mail
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
dom \
|
||||
editor \
|
||||
uriloader \
|
||||
msgbase \
|
||||
mailnews \
|
||||
necko \
|
||||
mime \
|
||||
pref \
|
||||
intl \
|
||||
locale \
|
||||
unicharutil \
|
||||
layout \
|
||||
content \
|
||||
msgbaseutil \
|
||||
msgdb \
|
||||
rdf \
|
||||
appshell \
|
||||
msgimap \
|
||||
msgnews \
|
||||
uconv \
|
||||
docshell \
|
||||
webshell \
|
||||
addrbook \
|
||||
widget \
|
||||
htmlparser \
|
||||
txmgr \
|
||||
exthandler \
|
||||
mork \
|
||||
wallet \
|
||||
nkcache \
|
||||
mimetype \
|
||||
windowwatcher \
|
||||
pipnss \
|
||||
msgcompose \
|
||||
$(NULL)
|
||||
|
||||
CPPSRCS = \
|
||||
nsMsgComposeSecure.cpp \
|
||||
$(NULL)
|
||||
|
||||
EXPORTS = \
|
||||
nsMsgComposeSecure.h \
|
||||
$(NULL)
|
||||
|
||||
# we don't want the shared lib, but we want to force the creation of a static lib.
|
||||
FORCE_STATIC_LIB = 1
|
||||
|
||||
include $(topsrcdir)/config/rules.mk
|
||||
|
||||
ifeq ($(OS_ARCH), Linux)
|
||||
DEFINES += -D_BSD_SOURCE
|
||||
endif
|
||||
|
||||
install:: ./smime-service.js
|
||||
$(INSTALL) $< $(DIST)/bin/components
|
|
@ -0,0 +1,87 @@
|
|||
#!nmake
|
||||
#
|
||||
# The contents of this file are subject to the Netscape Public
|
||||
# License Version 1.1 (the "License"); you may not use this file
|
||||
# except in compliance with the License. You may obtain a copy of
|
||||
# the License at http://www.mozilla.org/NPL/
|
||||
#
|
||||
# Software distributed under the License is distributed on an "AS
|
||||
# IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
# implied. See the License for the specific language governing
|
||||
# rights and limitations under the License.
|
||||
#
|
||||
# The Original Code is mozilla.org code.
|
||||
#
|
||||
# The Initial Developer of the Original Code is Netscape
|
||||
# Communications Corporation. Portions created by Netscape are
|
||||
# Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
# Rights Reserved.
|
||||
#
|
||||
# Contributor(s):
|
||||
|
||||
DEPTH=..\..\..\..
|
||||
MODULE= msgsmime
|
||||
REQUIRES = xpcom \
|
||||
string \
|
||||
dom \
|
||||
editor \
|
||||
uriloader \
|
||||
msgbase \
|
||||
msgsearch \
|
||||
mailnews \
|
||||
necko \
|
||||
mime \
|
||||
pref \
|
||||
intl \
|
||||
locale \
|
||||
uconv \
|
||||
unicharutil \
|
||||
layout \
|
||||
msgbaseutil \
|
||||
msgdb \
|
||||
rdf \
|
||||
appshell \
|
||||
msgimap \
|
||||
msgnews \
|
||||
docshell \
|
||||
webshell \
|
||||
addrbook \
|
||||
widget \
|
||||
htmlparser \
|
||||
txmgr \
|
||||
exthandler \
|
||||
mork \
|
||||
wallet \
|
||||
nkcache \
|
||||
mimetype \
|
||||
windowwatcher \
|
||||
content \
|
||||
msgcompo \
|
||||
pipnss \
|
||||
$(NULL)
|
||||
|
||||
include <$(DEPTH)\config\config.mak>
|
||||
|
||||
################################################################################
|
||||
## exports
|
||||
|
||||
EXPORTS= nsMsgComposeSecure.h \
|
||||
$(NULL)
|
||||
|
||||
################################################################################
|
||||
## library
|
||||
|
||||
LIBRARY_NAME=msgsmime_s
|
||||
|
||||
CPP_OBJS= .\$(OBJDIR)\nsMsgComposeSecure.obj \
|
||||
$(NULL)
|
||||
|
||||
|
||||
include <$(DEPTH)\config\rules.mak>
|
||||
|
||||
install:: $(LIBRARY)
|
||||
$(MAKE_INSTALL) $(LIBRARY) $(DIST)\lib
|
||||
$(MAKE_INSTALL) .\smime-service.js $(DIST)\bin\components
|
||||
|
||||
clobber::
|
||||
rm -f $(DIST)\lib\$(LIBRARY_NAME).lib
|
|
@ -0,0 +1,921 @@
|
|||
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* David Drinan <ddrinan@netscape.com>
|
||||
*/
|
||||
|
||||
#include "nsMsgComposeSecure.h"
|
||||
#include "nspr.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsICMS.h"
|
||||
#include "nsIX509Cert.h"
|
||||
#include "nsIMimeConverter.h"
|
||||
#include "nsMimeStringResources.h"
|
||||
#include "nsMimeTypes.h"
|
||||
#include "nsIX509Cert.h"
|
||||
#include "nsIX509CertDB.h"
|
||||
#include "nsMsgBaseCID.h"
|
||||
#include "nsIMsgHeaderParser.h"
|
||||
#include "nsFileStream.h"
|
||||
#include "nsIServiceManager.h"
|
||||
#include "nsIMsgIdentity.h"
|
||||
#include "nsIMsgCompFields.h"
|
||||
|
||||
static NS_DEFINE_CID(kMsgHeaderParserCID, NS_MSGHEADERPARSER_CID);
|
||||
|
||||
// XXX These strings should go in properties file XXX //
|
||||
#define MIME_MULTIPART_SIGNED_BLURB "This is a cryptographically signed message in MIME format."
|
||||
#define MIME_SMIME_ENCRYPTED_CONTENT_DESCRIPTION "S/MIME Encrypted Message"
|
||||
#define MIME_SMIME_SIGNATURE_CONTENT_DESCRIPTION "S/MIME Cryptographic Signature"
|
||||
|
||||
#define MK_MIME_ERROR_WRITING_FILE -1
|
||||
|
||||
#define SEC_ERROR_NO_EMAIL_CERT -100
|
||||
|
||||
static void mime_crypto_write_base64 (void *closure, const char *buf,
|
||||
unsigned long size);
|
||||
static nsresult mime_encoder_output_fn(const char *buf, PRInt32 size, void *closure);
|
||||
static nsresult mime_nested_encoder_output_fn (const char *buf, PRInt32 size, void *closure);
|
||||
static int make_multipart_signed_header_string(PRBool outer_p,
|
||||
char **header_return,
|
||||
char **boundary_return);
|
||||
extern "C" char *mime_make_separator(const char *prefix);
|
||||
|
||||
// mscott --> FIX ME...for now cloning code from compose\nsMsgEncode.h/.cpp
|
||||
|
||||
#include "prprf.h"
|
||||
#include "prmem.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsMsgMimeCID.h"
|
||||
#include "nsIMimeConverter.h"
|
||||
|
||||
/* This is the next generation string retrieval call */
|
||||
static NS_DEFINE_CID(kCMimeConverterCID, NS_MIME_CONVERTER_CID);
|
||||
|
||||
MimeEncoderData *
|
||||
MIME_B64EncoderInit(nsresult (*output_fn) (const char *buf, PRInt32 size, void *closure), void *closure)
|
||||
{
|
||||
MimeEncoderData *returnEncoderData = nsnull;
|
||||
nsIMimeConverter *converter;
|
||||
nsresult res = nsComponentManager::CreateInstance(kCMimeConverterCID, nsnull,
|
||||
NS_GET_IID(nsIMimeConverter), (void **)&converter);
|
||||
if (NS_SUCCEEDED(res) && nsnull != converter)
|
||||
{
|
||||
res = converter->B64EncoderInit(output_fn, closure, &returnEncoderData);
|
||||
NS_RELEASE(converter);
|
||||
}
|
||||
return NS_SUCCEEDED(res) ? returnEncoderData : nsnull;
|
||||
}
|
||||
|
||||
MimeEncoderData *
|
||||
MIME_QPEncoderInit(nsresult (*output_fn) (const char *buf, PRInt32 size, void *closure), void *closure)
|
||||
{
|
||||
MimeEncoderData *returnEncoderData = nsnull;
|
||||
nsIMimeConverter *converter;
|
||||
nsresult res = nsComponentManager::CreateInstance(kCMimeConverterCID, nsnull,
|
||||
NS_GET_IID(nsIMimeConverter), (void **)&converter);
|
||||
if (NS_SUCCEEDED(res) && nsnull != converter)
|
||||
{
|
||||
res = converter->QPEncoderInit(output_fn, closure, &returnEncoderData);
|
||||
NS_RELEASE(converter);
|
||||
}
|
||||
return NS_SUCCEEDED(res) ? returnEncoderData : nsnull;
|
||||
}
|
||||
|
||||
MimeEncoderData *
|
||||
MIME_UUEncoderInit(char *filename, nsresult (*output_fn) (const char *buf, PRInt32 size, void *closure), void *closure)
|
||||
{
|
||||
MimeEncoderData *returnEncoderData = nsnull;
|
||||
nsIMimeConverter *converter;
|
||||
nsresult res = nsComponentManager::CreateInstance(kCMimeConverterCID, nsnull,
|
||||
NS_GET_IID(nsIMimeConverter), (void **)&converter);
|
||||
if (NS_SUCCEEDED(res) && nsnull != converter)
|
||||
{
|
||||
res = converter->UUEncoderInit(filename, output_fn, closure, &returnEncoderData);
|
||||
NS_RELEASE(converter);
|
||||
}
|
||||
return NS_SUCCEEDED(res) ? returnEncoderData : nsnull;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MIME_EncoderDestroy(MimeEncoderData *data, PRBool abort_p)
|
||||
{
|
||||
//MimeEncoderData *returnEncoderData = nsnull;
|
||||
nsIMimeConverter *converter;
|
||||
nsresult res = nsComponentManager::CreateInstance(kCMimeConverterCID, nsnull,
|
||||
NS_GET_IID(nsIMimeConverter), (void **)&converter);
|
||||
if (NS_SUCCEEDED(res) && nsnull != converter)
|
||||
{
|
||||
res = converter->EncoderDestroy(data, abort_p);
|
||||
NS_RELEASE(converter);
|
||||
}
|
||||
|
||||
return NS_SUCCEEDED(res) ? 0 : -1;
|
||||
}
|
||||
|
||||
nsresult
|
||||
MIME_EncoderWrite(MimeEncoderData *data, const char *buffer, PRInt32 size)
|
||||
{
|
||||
// MimeEncoderData *returnEncoderData = nsnull;
|
||||
nsIMimeConverter *converter;
|
||||
PRInt32 written = 0;
|
||||
nsresult res = nsComponentManager::CreateInstance(kCMimeConverterCID, nsnull,
|
||||
NS_GET_IID(nsIMimeConverter), (void **)&converter);
|
||||
if (NS_SUCCEEDED(res) && nsnull != converter) {
|
||||
res = converter->EncoderWrite(data, buffer, size, &written);
|
||||
NS_RELEASE(converter);
|
||||
}
|
||||
return NS_SUCCEEDED(res) ? 0 : -1;
|
||||
}
|
||||
|
||||
static void
|
||||
GenerateGlobalRandomBytes(unsigned char *buf, PRInt32 len)
|
||||
{
|
||||
static PRBool firstTime = PR_TRUE;
|
||||
|
||||
if (firstTime)
|
||||
{
|
||||
// Seed the random-number generator with current time so that
|
||||
// the numbers will be different every time we run.
|
||||
PRInt32 aTime;
|
||||
LL_L2I(aTime, PR_Now());
|
||||
srand( (unsigned)aTime );
|
||||
firstTime = PR_FALSE;
|
||||
}
|
||||
|
||||
for( PRInt32 i = 0; i < len; i++ )
|
||||
buf[i] = rand() % 10;
|
||||
}
|
||||
|
||||
char
|
||||
*mime_make_separator(const char *prefix)
|
||||
{
|
||||
unsigned char rand_buf[13];
|
||||
GenerateGlobalRandomBytes(rand_buf, 12);
|
||||
|
||||
return PR_smprintf("------------%s"
|
||||
"%02X%02X%02X%02X"
|
||||
"%02X%02X%02X%02X"
|
||||
"%02X%02X%02X%02X",
|
||||
prefix,
|
||||
rand_buf[0], rand_buf[1], rand_buf[2], rand_buf[3],
|
||||
rand_buf[4], rand_buf[5], rand_buf[6], rand_buf[7],
|
||||
rand_buf[8], rand_buf[9], rand_buf[10], rand_buf[11]);
|
||||
}
|
||||
|
||||
// end of copied code which needs fixed....
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of nsMsgSMIMEComposeFields
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsMsgSMIMEComposeFields, nsIMsgSMIMECompFields)
|
||||
|
||||
nsMsgSMIMEComposeFields::nsMsgSMIMEComposeFields()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
}
|
||||
|
||||
nsMsgSMIMEComposeFields::~nsMsgSMIMEComposeFields()
|
||||
{
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSignMessage(PRBool value)
|
||||
{
|
||||
mSignMessage = value;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSignMessage(PRBool *_retval)
|
||||
{
|
||||
*_retval = mSignMessage;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgSMIMEComposeFields::SetAlwaysEncryptMessage(PRBool value)
|
||||
{
|
||||
mAlwaysEncryptMessage = value;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgSMIMEComposeFields::GetAlwaysEncryptMessage(PRBool *_retval)
|
||||
{
|
||||
*_retval = mAlwaysEncryptMessage;
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
// Implementation of nsMsgComposeSecure
|
||||
/////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
NS_IMPL_ISUPPORTS1(nsMsgComposeSecure, nsIMsgComposeSecure)
|
||||
|
||||
nsMsgComposeSecure::nsMsgComposeSecure()
|
||||
{
|
||||
NS_INIT_ISUPPORTS();
|
||||
/* member initializers and constructor code */
|
||||
mStream = 0;
|
||||
mDataHash = 0;
|
||||
mSigEncoderData = 0;
|
||||
mMultipartSignedBoundary = 0;
|
||||
mSelfSigningCert = 0;
|
||||
mSelfEncryptionCert = 0;
|
||||
mCerts = 0;
|
||||
mEncryptionCinfo = 0;
|
||||
mEncryptionContext = 0;
|
||||
mCryptoEncoderData = 0;
|
||||
}
|
||||
|
||||
nsMsgComposeSecure::~nsMsgComposeSecure()
|
||||
{
|
||||
/* destructor code */
|
||||
if (mEncryptionContext) {
|
||||
mEncryptionContext->Finish();
|
||||
}
|
||||
|
||||
if (mSigEncoderData) {
|
||||
MIME_EncoderDestroy (mSigEncoderData, PR_TRUE);
|
||||
}
|
||||
if (mCryptoEncoderData) {
|
||||
MIME_EncoderDestroy (mCryptoEncoderData, PR_TRUE);
|
||||
}
|
||||
|
||||
PR_FREEIF(mMultipartSignedBoundary);
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgComposeSecure::RequiresCryptoEncapsulation(nsIMsgIdentity * aIdentity, nsIMsgCompFields * aCompFields, PRBool * aRequiresEncryptionWork)
|
||||
{
|
||||
NS_ENSURE_ARG_POINTER(aRequiresEncryptionWork);
|
||||
|
||||
nsresult rv = NS_OK;
|
||||
*aRequiresEncryptionWork = PR_FALSE;
|
||||
|
||||
PRBool alwaysEncryptMessages = PR_FALSE;
|
||||
PRBool signMessage = PR_FALSE;
|
||||
rv = ExtractEncryptionState(aIdentity, aCompFields, &signMessage, &alwaysEncryptMessages);
|
||||
|
||||
if (alwaysEncryptMessages || signMessage)
|
||||
*aRequiresEncryptionWork = PR_TRUE;
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
nsresult nsMsgComposeSecure::ExtractEncryptionState(nsIMsgIdentity * aIdentity, nsIMsgCompFields * aComposeFields, PRBool * aSignMessage, PRBool * aEncrypt)
|
||||
{
|
||||
if (!aComposeFields && !aIdentity)
|
||||
return NS_OK; // kick out...invalid args....
|
||||
|
||||
nsCOMPtr<nsISupports> securityInfo;
|
||||
if (aComposeFields)
|
||||
aComposeFields->GetSecurityInfo(getter_AddRefs(securityInfo));
|
||||
|
||||
if (securityInfo) // if we were given security comp fields, use them.....
|
||||
{
|
||||
nsCOMPtr<nsIMsgSMIMECompFields> smimeCompFields = do_QueryInterface(securityInfo);
|
||||
if (smimeCompFields)
|
||||
{
|
||||
smimeCompFields->GetSignMessage(aSignMessage);
|
||||
smimeCompFields->GetAlwaysEncryptMessage(aEncrypt);
|
||||
}
|
||||
}
|
||||
else if (aIdentity) // get the default info from the identity....
|
||||
{
|
||||
aIdentity->GetBoolAttribute("encrypt_mail_always", aEncrypt);
|
||||
aIdentity->GetBoolAttribute("sign_mail", aSignMessage);
|
||||
}
|
||||
|
||||
return NS_OK;
|
||||
}
|
||||
|
||||
/* void beginCryptoEncapsulation (in nsOutputFileStream aStream, in boolean aEncrypt, in boolean aSign, in string aRecipeints, in boolean aIsDraft); */
|
||||
NS_IMETHODIMP nsMsgComposeSecure::BeginCryptoEncapsulation(nsOutputFileStream * aStream, const char * aRecipients, nsIMsgCompFields * aCompFields, nsIMsgIdentity * aIdentity, PRBool aIsDraft)
|
||||
{
|
||||
nsresult rv = NS_OK;
|
||||
|
||||
PRBool encryptMessages = PR_FALSE;
|
||||
PRBool signMessage = PR_FALSE;
|
||||
ExtractEncryptionState(aIdentity, aCompFields, &signMessage, &encryptMessages);
|
||||
|
||||
if (!signMessage && !encryptMessages) return NS_ERROR_FAILURE;
|
||||
|
||||
mStream = aStream;
|
||||
mIsDraft = aIsDraft;
|
||||
|
||||
if (encryptMessages && signMessage)
|
||||
mCryptoState = mime_crypto_signed_encrypted;
|
||||
else if (encryptMessages)
|
||||
mCryptoState = mime_crypto_encrypted;
|
||||
else if (signMessage)
|
||||
mCryptoState = mime_crypto_clear_signed;
|
||||
else
|
||||
PR_ASSERT(0);
|
||||
|
||||
aIdentity->GetUnicharAttribute("signing_cert_name", getter_Copies(mSigningCertName));
|
||||
aIdentity->GetUnicharAttribute("encryption_cert_name", getter_Copies(mEncryptionCertName));
|
||||
|
||||
rv = MimeCryptoHackCerts(aRecipients, encryptMessages, signMessage);
|
||||
if (NS_FAILED(rv)) {
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
switch (mCryptoState)
|
||||
{
|
||||
case mime_crypto_clear_signed:
|
||||
rv = MimeInitMultipartSigned(PR_TRUE);
|
||||
break;
|
||||
case mime_crypto_opaque_signed:
|
||||
PR_ASSERT(0); /* #### no api for this yet */
|
||||
rv = -1;
|
||||
break;
|
||||
case mime_crypto_signed_encrypted:
|
||||
rv = MimeInitEncryption(PR_TRUE);
|
||||
break;
|
||||
case mime_crypto_encrypted:
|
||||
rv = MimeInitEncryption(PR_FALSE);
|
||||
break;
|
||||
case mime_crypto_none:
|
||||
/* This can happen if mime_crypto_hack_certs() decided to turn off
|
||||
encryption (by asking the user.) */
|
||||
rv = 1;
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
break;
|
||||
}
|
||||
|
||||
FAIL:
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* void finishCryptoEncapsulation (in boolean aAbort); */
|
||||
NS_IMETHODIMP nsMsgComposeSecure::FinishCryptoEncapsulation(PRBool aAbort)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
if (!aAbort) {
|
||||
switch (mCryptoState) {
|
||||
case mime_crypto_clear_signed:
|
||||
rv = MimeFinishMultipartSigned (PR_TRUE);
|
||||
break;
|
||||
case mime_crypto_opaque_signed:
|
||||
PR_ASSERT(0); /* #### no api for this yet */
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
case mime_crypto_signed_encrypted:
|
||||
rv = MimeFinishEncryption (PR_TRUE);
|
||||
break;
|
||||
case mime_crypto_encrypted:
|
||||
rv = MimeFinishEncryption (PR_FALSE);
|
||||
break;
|
||||
default:
|
||||
PR_ASSERT(0);
|
||||
rv = NS_ERROR_FAILURE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgComposeSecure::MimeInitMultipartSigned(PRBool aOuter)
|
||||
{
|
||||
/* First, construct and write out the multipart/signed MIME header data.
|
||||
*/
|
||||
nsresult rv = NS_OK;
|
||||
char *header = 0;
|
||||
PRInt32 L;
|
||||
|
||||
rv = make_multipart_signed_header_string(aOuter, &header,
|
||||
&mMultipartSignedBoundary);
|
||||
if (NS_FAILED(rv)) goto FAIL;
|
||||
|
||||
L = nsCRT::strlen(header);
|
||||
|
||||
if (aOuter){
|
||||
/* If this is the outer block, write it to the file. */
|
||||
if (PRInt32(mStream->write(header, L)) < L) {
|
||||
rv = MK_MIME_ERROR_WRITING_FILE;
|
||||
}
|
||||
} else {
|
||||
/* If this is an inner block, feed it through the crypto stream. */
|
||||
rv = MimeCryptoWriteBlock (header, L);
|
||||
}
|
||||
|
||||
PR_Free(header);
|
||||
if (NS_FAILED(rv)) goto FAIL;
|
||||
|
||||
/* Now initialize the crypto library, so that we can compute a hash
|
||||
on the object which we are signing.
|
||||
*/
|
||||
|
||||
mHashType = nsIHash::HASH_AlgSHA1;
|
||||
|
||||
PR_SetError(0,0);
|
||||
mDataHash = do_CreateInstance(NS_HASH_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return 0;
|
||||
|
||||
rv = mDataHash->Create(mHashType);
|
||||
if (NS_FAILED(rv)) {
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
PR_SetError(0,0);
|
||||
rv = mDataHash->Begin();
|
||||
FAIL:
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgComposeSecure::MimeInitEncryption(PRBool aSign)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
/* First, construct and write out the opaque-crypto-blob MIME header data.
|
||||
*/
|
||||
|
||||
char *s =
|
||||
PR_smprintf("Content-Type: " APPLICATION_XPKCS7_MIME
|
||||
"; name=\"smime.p7m\"" CRLF
|
||||
"Content-Transfer-Encoding: " ENCODING_BASE64 CRLF
|
||||
"Content-Disposition: attachment"
|
||||
"; filename=\"smime.p7m\"" CRLF
|
||||
"Content-Description: %s" CRLF
|
||||
CRLF,
|
||||
MIME_SMIME_ENCRYPTED_CONTENT_DESCRIPTION);
|
||||
PRInt32 L;
|
||||
if (!s) return NS_ERROR_OUT_OF_MEMORY;
|
||||
L = nsCRT::strlen(s);
|
||||
if (PRInt32(mStream->write(s, L)) < L) {
|
||||
return NS_ERROR_FAILURE;
|
||||
}
|
||||
PR_Free(s);
|
||||
s = 0;
|
||||
|
||||
/* Now initialize the crypto library, so that we can filter the object
|
||||
to be encrypted through it.
|
||||
*/
|
||||
|
||||
if (!mIsDraft) {
|
||||
PRUint32 numCerts;
|
||||
mCerts->Count(&numCerts);
|
||||
PR_ASSERT(numCerts > 0);
|
||||
if (numCerts == 0) return NS_ERROR_FAILURE;
|
||||
}
|
||||
|
||||
/* Initialize the base64 encoder. */
|
||||
PR_ASSERT(!mCryptoEncoderData);
|
||||
mCryptoEncoderData = MIME_B64EncoderInit(mime_encoder_output_fn,
|
||||
this);
|
||||
if (!mCryptoEncoderData) {
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
/* Initialize the encrypter (and add the sender's cert.) */
|
||||
PR_ASSERT(mSelfEncryptionCert);
|
||||
PR_SetError(0,0);
|
||||
mEncryptionCinfo = do_CreateInstance(NS_CMSMESSAGE_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return 0;
|
||||
rv = mEncryptionCinfo->CreateEncrypted(mCerts); // XXX Fix this later XXX //
|
||||
if (NS_FAILED(rv)) {
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
mEncryptionContext = do_CreateInstance(NS_CMSENCODER_CONTRACTID, &rv);
|
||||
if (NS_FAILED(rv)) return 0;
|
||||
|
||||
rv = mEncryptionContext->Start(mEncryptionCinfo, mime_crypto_write_base64, mCryptoEncoderData); // XXX Fix this later XXX //
|
||||
if (NS_FAILED(rv)) {
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
/* If we're signing, tack a multipart/signed header onto the front of
|
||||
the data to be encrypted, and initialize the sign-hashing code too.
|
||||
*/
|
||||
if (aSign) {
|
||||
rv = MimeInitMultipartSigned(PR_FALSE);
|
||||
if (NS_FAILED(rv)) goto FAIL;
|
||||
}
|
||||
|
||||
FAIL:
|
||||
return rv;
|
||||
}
|
||||
|
||||
nsresult nsMsgComposeSecure::MimeFinishMultipartSigned (PRBool aOuter)
|
||||
{
|
||||
int status;
|
||||
nsresult rv;
|
||||
PRUint32 sec_item_len;
|
||||
unsigned char * sec_item_data;
|
||||
nsCOMPtr<nsICMSMessage> cinfo = do_CreateInstance(NS_CMSMESSAGE_CONTRACTID, &rv);
|
||||
nsCOMPtr<nsICMSEncoder> encoder = do_CreateInstance(NS_CMSENCODER_CONTRACTID, &rv);
|
||||
PRStatus ds_status = PR_FAILURE;
|
||||
char * header = nsnull;
|
||||
|
||||
/* Compute the hash...
|
||||
*/
|
||||
mDataHash->ResultLen(mHashType, &sec_item_len);
|
||||
sec_item_data = (unsigned char *) PR_MALLOC(sec_item_len);
|
||||
if (!sec_item_data) {
|
||||
status = NS_ERROR_OUT_OF_MEMORY;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
PR_SetError(0,0);
|
||||
mDataHash->End(sec_item_data, &sec_item_len, sec_item_len);
|
||||
status = PR_GetError();
|
||||
if (status < 0) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
PR_SetError(0,0);
|
||||
mDataHash = 0;
|
||||
|
||||
status = PR_GetError();
|
||||
if (status < 0) goto FAIL;
|
||||
|
||||
/* Write out the headers for the signature.
|
||||
*/
|
||||
PRInt32 L;
|
||||
header =
|
||||
PR_smprintf(CRLF
|
||||
"--%s" CRLF
|
||||
"Content-Type: " APPLICATION_XPKCS7_SIGNATURE
|
||||
"; name=\"smime.p7s\"" CRLF
|
||||
"Content-Transfer-Encoding: " ENCODING_BASE64 CRLF
|
||||
"Content-Disposition: attachment; "
|
||||
"filename=\"smime.p7s\"" CRLF
|
||||
"Content-Description: %s" CRLF
|
||||
CRLF,
|
||||
mMultipartSignedBoundary,
|
||||
MIME_SMIME_SIGNATURE_CONTENT_DESCRIPTION);
|
||||
if (!header) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
L = nsCRT::strlen(header);
|
||||
if (aOuter) {
|
||||
/* If this is the outer block, write it to the file. */
|
||||
if (PRInt32(mStream->write(header, L)) < L) {
|
||||
rv = MK_MIME_ERROR_WRITING_FILE;
|
||||
}
|
||||
} else {
|
||||
/* If this is an inner block, feed it through the crypto stream. */
|
||||
rv = MimeCryptoWriteBlock (header, L);
|
||||
}
|
||||
|
||||
PR_Free(header);
|
||||
if (status < 0) goto FAIL;
|
||||
|
||||
/* Create the signature...
|
||||
*/
|
||||
|
||||
PR_ASSERT(mHashType == nsIHash::HASH_AlgSHA1);
|
||||
|
||||
PR_ASSERT (mSelfSigningCert);
|
||||
PR_SetError(0,0);
|
||||
rv = cinfo->CreateSigned(mSelfSigningCert, mSelfEncryptionCert, sec_item_data, sec_item_len);
|
||||
if (NS_FAILED(rv)) {
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
/* Initialize the base64 encoder for the signature data.
|
||||
*/
|
||||
PR_ASSERT(!mSigEncoderData);
|
||||
mSigEncoderData =
|
||||
MIME_B64EncoderInit((aOuter
|
||||
? mime_encoder_output_fn
|
||||
: mime_nested_encoder_output_fn),
|
||||
this);
|
||||
if (!mSigEncoderData) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
/* Write out the signature.
|
||||
*/
|
||||
PR_SetError(0,0);
|
||||
rv = encoder->Start(cinfo, mime_crypto_write_base64, mSigEncoderData);
|
||||
if (NS_FAILED(rv)) {
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
// We're not passing in any data, so no update needed.
|
||||
rv = encoder->Finish();
|
||||
if (NS_FAILED(rv)) {
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
/* Shut down the sig's base64 encoder.
|
||||
*/
|
||||
rv = MIME_EncoderDestroy(mSigEncoderData, PR_FALSE);
|
||||
mSigEncoderData = 0;
|
||||
if (NS_FAILED(rv)) {
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
/* Now write out the terminating boundary.
|
||||
*/
|
||||
{
|
||||
PRInt32 L;
|
||||
char *header = PR_smprintf(CRLF "--%s--" CRLF,
|
||||
mMultipartSignedBoundary);
|
||||
PR_Free(mMultipartSignedBoundary);
|
||||
mMultipartSignedBoundary = 0;
|
||||
|
||||
if (!header) {
|
||||
rv = NS_ERROR_OUT_OF_MEMORY;
|
||||
goto FAIL;
|
||||
}
|
||||
L = nsCRT::strlen(header);
|
||||
if (aOuter) {
|
||||
/* If this is the outer block, write it to the file. */
|
||||
if (PRInt32(mStream->write(header, L)) < L)
|
||||
rv = MK_MIME_ERROR_WRITING_FILE;
|
||||
} else {
|
||||
/* If this is an inner block, feed it through the crypto stream. */
|
||||
rv = MimeCryptoWriteBlock (header, L);
|
||||
}
|
||||
}
|
||||
|
||||
FAIL:
|
||||
PR_FREEIF(sec_item_data);
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
||||
/* Helper function for mime_finish_crypto_encapsulation() to close off
|
||||
an opaque crypto object (for encrypted or signed-and-encrypted messages.)
|
||||
*/
|
||||
nsresult nsMsgComposeSecure::MimeFinishEncryption (PRBool aSign)
|
||||
{
|
||||
nsresult rv;
|
||||
|
||||
/* If this object is both encrypted and signed, close off the
|
||||
signature first (since it's inside.) */
|
||||
if (aSign) {
|
||||
rv = MimeFinishMultipartSigned (PR_FALSE);
|
||||
if (NS_FAILED(rv)) {
|
||||
goto FAIL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Close off the opaque encrypted blob.
|
||||
*/
|
||||
PR_ASSERT(mEncryptionContext);
|
||||
|
||||
rv = mEncryptionContext->Finish();
|
||||
if (NS_FAILED(rv)) {
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
mEncryptionContext = 0;
|
||||
|
||||
PR_ASSERT(mEncryptionCinfo);
|
||||
if (!mEncryptionCinfo) {
|
||||
rv = NS_ERROR_FAILURE;
|
||||
}
|
||||
if (mEncryptionCinfo) {
|
||||
mEncryptionCinfo = 0;
|
||||
}
|
||||
|
||||
/* Shut down the base64 encoder. */
|
||||
rv = MIME_EncoderDestroy(mCryptoEncoderData, PR_FALSE);
|
||||
mCryptoEncoderData = 0;
|
||||
|
||||
FAIL:
|
||||
return rv;
|
||||
}
|
||||
|
||||
/* Used to figure out what certs should be used when encrypting this message.
|
||||
*/
|
||||
nsresult nsMsgComposeSecure::MimeCryptoHackCerts(const char *aRecipients, PRBool aEncrypt, PRBool aSign)
|
||||
{
|
||||
int status = 0;
|
||||
char *all_mailboxes = 0, *mailboxes = 0, *mailbox_list = 0;
|
||||
const char *mailbox = 0;
|
||||
PRUint32 count = 0;
|
||||
PRUint32 numCerts;
|
||||
nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
|
||||
nsCOMPtr<nsIMsgHeaderParser> pHeader;
|
||||
nsresult res = nsComponentManager::CreateInstance(kMsgHeaderParserCID,
|
||||
NULL, NS_GET_IID(nsIMsgHeaderParser),
|
||||
(void **) getter_AddRefs(pHeader));
|
||||
res = NS_NewISupportsArray(getter_AddRefs(mCerts));
|
||||
if (NS_FAILED(res)) {
|
||||
return res;
|
||||
}
|
||||
|
||||
PRBool no_clearsigning_p = PR_FALSE;
|
||||
|
||||
PR_ASSERT(aEncrypt || aSign);
|
||||
certdb->GetEmailEncryptionCert(mEncryptionCertName, getter_AddRefs(mSelfEncryptionCert));
|
||||
certdb->GetEmailSigningCert(mSigningCertName, getter_AddRefs(mSelfSigningCert));
|
||||
if ((mSelfSigningCert == nsnull) && aSign) {
|
||||
status = SEC_ERROR_NO_EMAIL_CERT;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
if ((mSelfEncryptionCert == nsnull) && aEncrypt) {
|
||||
status = SEC_ERROR_NO_EMAIL_CERT;
|
||||
goto FAIL;
|
||||
}
|
||||
|
||||
pHeader->ExtractHeaderAddressMailboxes(nsnull,aRecipients, &all_mailboxes);
|
||||
pHeader->RemoveDuplicateAddresses(nsnull, all_mailboxes, 0, PR_FALSE /*removeAliasesToMe*/, &mailboxes);
|
||||
PR_FREEIF(all_mailboxes);
|
||||
|
||||
if (mailboxes) {
|
||||
pHeader->ParseHeaderAddresses (nsnull, mailboxes, 0, &mailbox_list, &count);
|
||||
}
|
||||
PR_FREEIF(mailboxes);
|
||||
if (count < 0) return count;
|
||||
|
||||
/* If the message is to be encrypted, then get the recipient certs */
|
||||
if (aEncrypt) {
|
||||
mailbox = mailbox_list;
|
||||
for (; count > 0; count--) {
|
||||
nsCOMPtr<nsIX509Cert> cert;
|
||||
certdb->GetCertByEmailAddress(nsnull, mailbox, getter_AddRefs(cert));
|
||||
if (!cert) {
|
||||
mailbox += nsCRT::strlen(mailbox) + 1;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* #### see if recipient requests `signedData'.
|
||||
if (...) no_clearsigning_p = PR_TRUE;
|
||||
(This is the only reason we even bother looking up the certs
|
||||
of the recipients if we're sending a signed-but-not-encrypted
|
||||
message.)
|
||||
*/
|
||||
mCerts->AppendElement(cert);
|
||||
mailbox += nsCRT::strlen(mailbox) + 1;
|
||||
}
|
||||
mCerts->Count(&numCerts);
|
||||
if (numCerts == 0) {
|
||||
res = NS_ERROR_FAILURE; // XXX We should set a specific error in this case XXX //
|
||||
goto FAIL;
|
||||
}
|
||||
}
|
||||
FAIL:
|
||||
PR_FREEIF(mailbox_list);
|
||||
return res;
|
||||
}
|
||||
|
||||
NS_IMETHODIMP nsMsgComposeSecure::MimeCryptoWriteBlock (const char *buf, PRInt32 size)
|
||||
{
|
||||
int status = 0;
|
||||
nsresult rv;
|
||||
|
||||
/* If this is a From line, mangle it before signing it. You just know
|
||||
that something somewhere is going to mangle it later, and that's
|
||||
going to cause the signature check to fail.
|
||||
|
||||
(This assumes that, in the cases where From-mangling must happen,
|
||||
this function is called a line at a time. That happens to be the
|
||||
case.)
|
||||
*/
|
||||
if (size >= 5 && buf[0] == 'F' && !nsCRT::strncmp(buf, "From ", 5)) {
|
||||
char mangle[] = ">";
|
||||
status = MimeCryptoWriteBlock (mangle, 1);
|
||||
if (status < 0)
|
||||
return status;
|
||||
}
|
||||
|
||||
/* If we're signing, or signing-and-encrypting, feed this data into
|
||||
the computation of the hash. */
|
||||
if (mDataHash) {
|
||||
PR_SetError(0,0);
|
||||
mDataHash->Update((unsigned char *) buf, size);
|
||||
status = PR_GetError();
|
||||
if (status < 0) goto FAIL;
|
||||
}
|
||||
|
||||
PR_SetError(0,0);
|
||||
if (mEncryptionContext) {
|
||||
/* If we're encrypting, or signing-and-encrypting, write this data
|
||||
by filtering it through the crypto library. */
|
||||
|
||||
rv = mEncryptionContext->Update(buf, size);
|
||||
if (NS_FAILED(rv)) {
|
||||
status = PR_GetError();
|
||||
PR_ASSERT(status < 0);
|
||||
if (status >= 0) status = -1;
|
||||
goto FAIL;
|
||||
}
|
||||
} else {
|
||||
/* If we're not encrypting (presumably just signing) then write this
|
||||
data directly to the file. */
|
||||
|
||||
if (PRInt32(mStream->write (buf, size)) < size) {
|
||||
return MK_MIME_ERROR_WRITING_FILE;
|
||||
}
|
||||
}
|
||||
FAIL:
|
||||
return status;
|
||||
}
|
||||
|
||||
/* Returns a string consisting of a Content-Type header, and a boundary
|
||||
string, suitable for moving from the header block, down into the body
|
||||
of a multipart object. The boundary itself is also returned (so that
|
||||
the caller knows what to write to close it off.)
|
||||
*/
|
||||
static int
|
||||
make_multipart_signed_header_string(PRBool outer_p,
|
||||
char **header_return,
|
||||
char **boundary_return)
|
||||
{
|
||||
*header_return = 0;
|
||||
*boundary_return = mime_make_separator("ms");
|
||||
const char * crypto_multipart_blurb = nsnull;
|
||||
|
||||
if (!*boundary_return)
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
|
||||
if (outer_p) {
|
||||
crypto_multipart_blurb = MIME_MULTIPART_SIGNED_BLURB;
|
||||
}
|
||||
|
||||
*header_return =
|
||||
PR_smprintf("Content-Type: " MULTIPART_SIGNED "; "
|
||||
"protocol=\"" APPLICATION_XPKCS7_SIGNATURE "\"; "
|
||||
"micalg=" PARAM_MICALG_SHA1 "; "
|
||||
"boundary=\"%s\"" CRLF
|
||||
CRLF
|
||||
"%s%s"
|
||||
"--%s" CRLF,
|
||||
|
||||
*boundary_return,
|
||||
(crypto_multipart_blurb ? crypto_multipart_blurb : ""),
|
||||
(crypto_multipart_blurb ? CRLF CRLF : ""),
|
||||
*boundary_return);
|
||||
|
||||
if (!*header_return) {
|
||||
PR_Free(*boundary_return);
|
||||
*boundary_return = 0;
|
||||
return NS_ERROR_OUT_OF_MEMORY;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Used as the output function of a SEC_PKCS7EncoderContext -- we feed
|
||||
plaintext into the crypto engine, and it calls this function with encrypted
|
||||
data; then this function writes a base64-encoded representation of that
|
||||
data to the file (by filtering it through the given MimeEncoderData object.)
|
||||
|
||||
Also used as the output function of SEC_PKCS7Encode() -- but in that case,
|
||||
it's used to write the encoded representation of the signature. The only
|
||||
difference is which MimeEncoderData object is used.
|
||||
*/
|
||||
static void
|
||||
mime_crypto_write_base64 (void *closure, const char *buf,
|
||||
unsigned long size)
|
||||
{
|
||||
MimeEncoderData *data = (MimeEncoderData *) closure;
|
||||
int status = MIME_EncoderWrite (data, buf, size);
|
||||
PR_SetError(status < 0 ? status : 0, 0);
|
||||
}
|
||||
|
||||
|
||||
/* Used as the output function of MimeEncoderData -- when we have generated
|
||||
the signature for a multipart/signed object, this is used to write the
|
||||
base64-encoded representation of the signature to the file.
|
||||
*/
|
||||
nsresult mime_encoder_output_fn(const char *buf, PRInt32 size, void *closure)
|
||||
{
|
||||
nsMsgComposeSecure *state = (nsMsgComposeSecure *) closure;
|
||||
nsOutputFileStream *stream = state->GetOutputStream();
|
||||
if (PRInt32(stream->write((char *) buf, size)) < size)
|
||||
return MK_MIME_ERROR_WRITING_FILE;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Like mime_encoder_output_fn, except this is used for the case where we
|
||||
are both signing and encrypting -- the base64-encoded output of the
|
||||
signature should be fed into the crypto engine, rather than being written
|
||||
directly to the file.
|
||||
*/
|
||||
static nsresult
|
||||
mime_nested_encoder_output_fn (const char *buf, PRInt32 size, void *closure)
|
||||
{
|
||||
nsMsgComposeSecure *state = (nsMsgComposeSecure *) closure;
|
||||
return state->MimeCryptoWriteBlock ((char *) buf, size);
|
||||
}
|
|
@ -0,0 +1,92 @@
|
|||
/* -*- Mode: idl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
*
|
||||
* The contents of this file are subject to the Netscape Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/NPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1998 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
*/
|
||||
#ifndef _nsMsgComposeSecure_H_
|
||||
#define _nsMsgComposeSecure_H_
|
||||
|
||||
#include "nsIMsgComposeSecure.h"
|
||||
#include "nsIMsgSMIMECompFields.h"
|
||||
#include "nsCOMPtr.h"
|
||||
#include "nsICMS.h"
|
||||
#include "nsIX509Cert.h"
|
||||
#include "nsIMimeConverter.h"
|
||||
|
||||
class nsIMsgCompFields;
|
||||
|
||||
class nsMsgSMIMEComposeFields : public nsIMsgSMIMECompFields
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMSGSMIMECOMPFIELDS
|
||||
|
||||
nsMsgSMIMEComposeFields();
|
||||
virtual ~nsMsgSMIMEComposeFields();
|
||||
|
||||
private:
|
||||
PRBool mSignMessage;
|
||||
PRBool mAlwaysEncryptMessage;
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
mime_crypto_none, /* normal unencapsulated MIME message */
|
||||
mime_crypto_clear_signed, /* multipart/signed encapsulation */
|
||||
mime_crypto_opaque_signed, /* application/x-pkcs7-mime (signedData) */
|
||||
mime_crypto_encrypted, /* application/x-pkcs7-mime */
|
||||
mime_crypto_signed_encrypted /* application/x-pkcs7-mime */
|
||||
} mimeDeliveryCryptoState;
|
||||
|
||||
class nsMsgComposeSecure : public nsIMsgComposeSecure
|
||||
{
|
||||
public:
|
||||
NS_DECL_ISUPPORTS
|
||||
NS_DECL_NSIMSGCOMPOSESECURE
|
||||
|
||||
nsMsgComposeSecure();
|
||||
virtual ~nsMsgComposeSecure();
|
||||
/* additional members */
|
||||
nsOutputFileStream *GetOutputStream() { return mStream;}
|
||||
private:
|
||||
nsresult MimeInitMultipartSigned(PRBool aOuter);
|
||||
nsresult MimeInitEncryption(PRBool aSign);
|
||||
nsresult MimeFinishMultipartSigned (PRBool aOuter);
|
||||
nsresult MimeFinishEncryption (PRBool aSign);
|
||||
nsresult MimeCryptoHackCerts(const char *aRecipients, PRBool aEncrypt, PRBool aSign);
|
||||
|
||||
nsresult ExtractEncryptionState(nsIMsgIdentity * aIdentity, nsIMsgCompFields * aComposeFields, PRBool * aSignMessage, PRBool * aEncrypt);
|
||||
|
||||
mimeDeliveryCryptoState mCryptoState;
|
||||
nsOutputFileStream *mStream;
|
||||
PRInt16 mHashType;
|
||||
nsCOMPtr<nsIHash> mDataHash;
|
||||
MimeEncoderData *mSigEncoderData;
|
||||
char *mMultipartSignedBoundary;
|
||||
nsXPIDLString mSigningCertName;
|
||||
nsCOMPtr<nsIX509Cert> mSelfSigningCert;
|
||||
nsXPIDLString mEncryptionCertName;
|
||||
nsCOMPtr<nsIX509Cert> mSelfEncryptionCert;
|
||||
nsCOMPtr<nsISupportsArray> mCerts;
|
||||
nsCOMPtr<nsICMSMessage> mEncryptionCinfo;
|
||||
nsCOMPtr<nsICMSEncoder> mEncryptionContext;
|
||||
MimeEncoderData *mCryptoEncoderData;
|
||||
PRBool mIsDraft;
|
||||
};
|
||||
|
||||
#endif
|
|
@ -0,0 +1,111 @@
|
|||
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
|
||||
* The contents of this file are subject to the Mozilla Public
|
||||
* License Version 1.1 (the "License"); you may not use this file
|
||||
* except in compliance with the License. You may obtain a copy of
|
||||
* the License at http://www.mozilla.org/MPL/
|
||||
*
|
||||
* Software distributed under the License is distributed on an "AS
|
||||
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
|
||||
* implied. See the License for the specific language governing
|
||||
* rights and limitations under the License.
|
||||
*
|
||||
* The Original Code is mozilla.org code.
|
||||
*
|
||||
* The Initial Developer of the Original Code is Netscape
|
||||
* Communications Corporation. Portions created by Netscape are
|
||||
* Copyright (C) 1999 Netscape Communications Corporation. All
|
||||
* Rights Reserved.
|
||||
*
|
||||
* Contributor(s):
|
||||
* Seth Spitzer <sspitzer@netscape.com>
|
||||
*/
|
||||
|
||||
|
||||
/* components defined in this file */
|
||||
const SMIME_EXTENSION_SERVICE_CONTRACTID =
|
||||
"@mozilla.org/accounmanager/extension;1?name=smime";
|
||||
const SMIME_EXTENSION_SERVICE_CID =
|
||||
Components.ID("{f2809796-1dd1-11b2-8c1b-8f15f007c699}");
|
||||
|
||||
/* interafces used in this file */
|
||||
const nsIMsgAccountManagerExtension = Components.interfaces.nsIMsgAccountManagerExtension;
|
||||
const nsICategoryManager = Components.interfaces.nsICategoryManager;
|
||||
const nsISupports = Components.interfaces.nsISupports;
|
||||
|
||||
function SMIMEService()
|
||||
{}
|
||||
|
||||
SMIMEService.prototype.name = "smime";
|
||||
SMIMEService.prototype.showPanel =
|
||||
|
||||
function (server)
|
||||
|
||||
{
|
||||
// don't show the S/MIME panel for news accounts
|
||||
return (server.type != "nntp");
|
||||
}
|
||||
|
||||
/* factory for command line handler service (SMIMEService) */
|
||||
var SMIMEFactory = new Object();
|
||||
|
||||
SMIMEFactory.createInstance =
|
||||
function (outer, iid) {
|
||||
if (outer != null)
|
||||
throw Components.results.NS_ERROR_NO_AGGREGATION;
|
||||
|
||||
if (!iid.equals(nsIMsgAccountManagerExtension) && !iid.equals(nsISupports))
|
||||
throw Components.results.NS_ERROR_INVALID_ARG;
|
||||
|
||||
return new SMIMEService();
|
||||
}
|
||||
|
||||
|
||||
var SMIMEModule = new Object();
|
||||
|
||||
SMIMEModule.registerSelf =
|
||||
function (compMgr, fileSpec, location, type)
|
||||
{
|
||||
dump("*** Registering smime account manager extension.\n");
|
||||
compMgr.registerComponentWithType(SMIME_EXTENSION_SERVICE_CID,
|
||||
"SMIME Account Manager Extension Service",
|
||||
SMIME_EXTENSION_SERVICE_CONTRACTID, fileSpec,
|
||||
location, true, true, type);
|
||||
catman = Components.classes["@mozilla.org/categorymanager;1"].getService(nsICategoryManager);
|
||||
catman.addCategoryEntry("mailnews-accountmanager-extensions",
|
||||
"smime account manager extension",
|
||||
SMIME_EXTENSION_SERVICE_CONTRACTID, true, true);
|
||||
}
|
||||
|
||||
SMIMEModule.unregisterSelf =
|
||||
function(compMgr, fileSpec, location)
|
||||
{
|
||||
compMgr.unregisterComponentSpec(SMIME_EXTENSION_SERVICE_CID, fileSpec);
|
||||
catman = Components.classes["@mozilla.org/categorymanager;1"].getService(nsICategoryManager);
|
||||
catman.deleteCategoryEntry("mailnews-accountmanager-extensions",
|
||||
SMIME_EXTENSION_SERVICE_CONTRACTID, true);
|
||||
}
|
||||
|
||||
SMIMEModule.getClassObject =
|
||||
function (compMgr, cid, iid) {
|
||||
if (cid.equals(SMIME_EXTENSION_SERVICE_CID))
|
||||
return SMIMEFactory;
|
||||
|
||||
|
||||
if (!iid.equals(Components.interfaces.nsIFactory))
|
||||
throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
|
||||
|
||||
throw Components.results.NS_ERROR_NO_INTERFACE;
|
||||
}
|
||||
|
||||
SMIMEModule.canUnload =
|
||||
function(compMgr)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/* entrypoint */
|
||||
function NSGetModule(compMgr, fileSpec) {
|
||||
return SMIMEModule;
|
||||
}
|
||||
|
||||
|
Загрузка…
Ссылка в новой задаче