/.project
/.settings
/packager/build/
+/packager/build-mach/
/packager/dist/
/packager/updateKey
/packager/*.bz2
--- /dev/null
+#
+# ***** 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 "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 the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of 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 *****
+
+DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = ximf-company-def
+DIRS =
+
+XPI_NAME = ximf_company_def
+INSTALL_EXTENSION_ID = {E255643F-7DCA-4cd8-B0C2-61EAADE39FCE}
+XPI_PKGNAME = ximf_company_def
+
+DIST_FILES = install.rdf
+
+USE_EXTENSION_MANIFEST = 1
+
+libs::
+ $(INSTALL) $(srcdir)/chrome/content/*.xml $(FINAL_TARGET)/chrome/content
+ $(INSTALL) $(srcdir)/chrome/content/AmocoCorporation/*.xml $(FINAL_TARGET)/chrome/content/AmocoCorporation
+ $(INSTALL) $(srcdir)/chrome/content/CaterpillarInc/*.xml $(FINAL_TARGET)/chrome/content/CaterpillarInc
+ $(INSTALL) $(srcdir)/chrome/content/WhirlpoolCorporation/*.xml $(FINAL_TARGET)/chrome/content/WhirlpoolCorporation
+
+include $(topsrcdir)/config/rules.mk
--- /dev/null
+content ximf-conpany-def chrome/content/
\ No newline at end of file
-<?xml version="1.0" encoding="UTF-8"?>
-
-<ximf:instance name="Amoco" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">
- <ximf:dictionary id="OneDico">
- <ximf:locale lang="fr">
- <ximf:ilk entity="ilk-info-box">Information</ximf:ilk>
- <ximf:ilk entity="ilk-security-panel">Securité</ximf:ilk>
- <ximf:ilk entity="ilk-originator-reference">Réferences d'origine</ximf:ilk>
- <ximf:ilk entity="ilk-reply-before">Répondre avant</ximf:ilk>
- <ximf:ilk entity="ilk-classification-panel">Classification</ximf:ilk>
- <ximf:ilk entity="ilk-classification">Classification de sécurité</ximf:ilk>
- <ximf:ilk entity="ilk-privacy-mark">Marque privée</ximf:ilk>
- <ximf:ilk entity="ilk-general">Général</ximf:ilk>
- <ximf:ilk entity="ilk-confidential">Confidentiel</ximf:ilk>
- <ximf:ilk entity="ilk-highly-confidential">Très confidentiel</ximf:ilk>
- <ximf:ilk entity="ilk-minimum">Minimum</ximf:ilk>
- <ximf:ilk entity="ilk-medium">Moyen</ximf:ilk>
- <ximf:ilk entity="ilk-maximum">Maximum</ximf:ilk>
- <ximf:ilk entity="ilk-critical">Critique</ximf:ilk>
- </ximf:locale>
- <ximf:locale lang="en-US">
- <ximf:ilk entity="ilk-info-box">Information</ximf:ilk>
- <ximf:ilk entity="ilk-security-panel">Security</ximf:ilk>
- <ximf:ilk entity="ilk-reply-before">Reply before</ximf:ilk>
- <ximf:ilk entity="ilk-originator-reference">Origin references</ximf:ilk>
- <ximf:ilk entity="ilk-classification-panel">Classification</ximf:ilk>
- <ximf:ilk entity="ilk-classification">Security classification</ximf:ilk>
- <ximf:ilk entity="ilk-privacy-mark">Privacy mark</ximf:ilk>
- <ximf:ilk entity="ilk-general">General</ximf:ilk>
- <ximf:ilk entity="ilk-confidential">Confidential</ximf:ilk>
- <ximf:ilk entity="ilk-highly-confidential">Highly Confidential</ximf:ilk>
- <ximf:ilk entity="ilk-minimum">Minimum</ximf:ilk>
- <ximf:ilk entity="ilk-medium">Medium</ximf:ilk>
- <ximf:ilk entity="ilk-maximum">Maximum</ximf:ilk>
- <ximf:ilk entity="ilk-critical">Critical</ximf:ilk>
- </ximf:locale>
- </ximf:dictionary>
-</ximf:instance>
+<?xml version="1.0" encoding="UTF-8"?>\r
+\r
+<ximf:instance name="Amoco" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">\r
+ <ximf:dictionary id="OneDico">\r
+ <ximf:locale lang="fr">\r
+ <ximf:ilk entity="ilk-info-box">Information</ximf:ilk>\r
+ <ximf:ilk entity="ilk-security-panel">Securité</ximf:ilk>\r
+ <ximf:ilk entity="ilk-originator-reference">Réferences d'origine</ximf:ilk> \r
+ <ximf:ilk entity="ilk-reply-before">Répondre avant</ximf:ilk>\r
+ <ximf:ilk entity="ilk-classification-panel">Classification</ximf:ilk>\r
+ <ximf:ilk entity="ilk-classification">Classification de sécurité</ximf:ilk>\r
+ <ximf:ilk entity="ilk-privacy-mark">Marque privée</ximf:ilk> \r
+ <ximf:ilk entity="ilk-general">Général</ximf:ilk>\r
+ <ximf:ilk entity="ilk-confidential">Confidentiel</ximf:ilk> \r
+ <ximf:ilk entity="ilk-highly-confidential">Très confidentiel</ximf:ilk>\r
+ <ximf:ilk entity="ilk-minimum">Minimum</ximf:ilk>\r
+ <ximf:ilk entity="ilk-medium">Moyen</ximf:ilk>\r
+ <ximf:ilk entity="ilk-maximum">Maximum</ximf:ilk>\r
+ <ximf:ilk entity="ilk-critical">Critique</ximf:ilk> \r
+ </ximf:locale>\r
+ <ximf:locale lang="en-US">\r
+ <ximf:ilk entity="ilk-info-box">Information</ximf:ilk>\r
+ <ximf:ilk entity="ilk-security-panel">Security</ximf:ilk>\r
+ <ximf:ilk entity="ilk-reply-before">Reply before</ximf:ilk>\r
+ <ximf:ilk entity="ilk-originator-reference">Origin references</ximf:ilk>\r
+ <ximf:ilk entity="ilk-classification-panel">Classification</ximf:ilk>\r
+ <ximf:ilk entity="ilk-classification">Security classification</ximf:ilk>\r
+ <ximf:ilk entity="ilk-privacy-mark">Privacy mark</ximf:ilk>\r
+ <ximf:ilk entity="ilk-general">General</ximf:ilk>\r
+ <ximf:ilk entity="ilk-confidential">Confidential</ximf:ilk> \r
+ <ximf:ilk entity="ilk-highly-confidential">Highly Confidential</ximf:ilk>\r
+ <ximf:ilk entity="ilk-minimum">Minimum</ximf:ilk>\r
+ <ximf:ilk entity="ilk-medium">Medium</ximf:ilk>\r
+ <ximf:ilk entity="ilk-maximum">Maximum</ximf:ilk>\r
+ <ximf:ilk entity="ilk-critical">Critical</ximf:ilk> \r
+ </ximf:locale>\r
+ </ximf:dictionary>\r
+</ximf:instance>\r
-<?xml version="1.0" encoding="UTF-8"?>
-<?xml-stylesheet type="text/xsl" href="ximftoxul.xsl"?>
-<ximf:instance name="Amoco" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">
-
- <!-- OID AMOCO -->
- <ximf:header id="header-policy-identifier" headerName="X-XIMF-Security-Policy-Identifier" >
- <ximf:string content="1.2.840.113549.1.9.16.7.1"/>
- </ximf:header>
-
- <!-- Security Classification-->
- <ximf:header id="header-classification"
- headerName="X-XIMF-Security-Classification"
- technicalHeaderName="X-XIMF-Security-Classification-Identifier"
- type="string"
- technicalType="oid"
- ilk="ilk-classification"
- isMandatory="true">
- <ximf:set id="value-amoco-classification">
- <ximf:string ilk="ilk-general" content="amoco-general" technicalContent="6" />
- <ximf:string ilk="ilk-confidential" content="amoco-confidential" technicalContent="7" />
- <ximf:string ilk="ilk-highly-confidential" content="amoco-highly-confidential" technicalContent="8" />
- </ximf:set>
- </ximf:header>
-
- <ximf:header id="header-privacy-mark" headerName="X-XIMF-Privacy-Mark" ilk="ilk-privacy-mark" isMandatory="true">
- <ximf:set id="value-privacy-mark">
- <ximf:string ilk="ilk-minimum" content="amoco-minimum" />
- <ximf:string ilk="ilk-medium" content="amoco-medium" />
- <ximf:string ilk="ilk-maximum" content="amoco-maximum" />
- <ximf:string ilk="ilk-critical" content="amoco-critical" />
- </ximf:set>
- </ximf:header>
-
- <!-- headers advanced -->
- <!-- headers advanced -->
- <ximf:header id="header-primary-precedence" headerName="X-XIMF-Primary-Precedence" ilk="ilk-primary-precedence" isMandatory="true">
- <ximf:set id="value-precedence">
- <ximf:string id="data-routine-precedence" ilk="ilk-routine" content="routine" index="0" aclLevel="30"/>
- <ximf:string id="data-urgent-precedence" ilk="ilk-urgent" content="priority" index="1" aclLevel="40"/>
- <ximf:string id="data-immediat-precedence" ilk="ilk-immediat" content="immediate" index="2" aclLevel="50"/>
- <ximf:string id="data-flash-precedence" ilk="ilk-flash" content="flash" index="3" aclLevel="100"/>
- </ximf:set>
- </ximf:header>
-
- <ximf:header id="header-copy-precedence" headerName="X-XIMF-Copy-Precedence" ilk="ilk-copy-precedence" isMandatory="false">
- <ximf:set ref="value-precedence"/>
- </ximf:header>
-
- <ximf:header id="header-reply-before" headerName="X-XIMF-Reply-Before" ilk="ilk-reply-before" isMandatory="false" type="date">
- <ximf:string id="value-reply-before" editable="true" />
- </ximf:header>
-
- <ximf:header id="header-originator-reference" headerName="X-XIMF-Originator-Reference" ilk="ilk-originator-reference" isMandatory="false" type="string">
- <ximf:string id="value-originator-reference" maxItem="5" editable="true" separator=";"/>
- </ximf:header>
-
-
-
-</ximf:instance>
+<?xml version="1.0" encoding="UTF-8"?>\r
+<?xml-stylesheet type="text/xsl" href="ximftoxul.xsl"?>\r
+<ximf:instance name="Amoco" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">\r
+\r
+ <!-- OID AMOCO -->\r
+ <ximf:header id="header-policy-identifier" headerName="X-XIMF-Security-Policy-Identifier" > \r
+ <ximf:string content="1.2.840.113549.1.9.16.7.1"/>\r
+ </ximf:header>\r
+ \r
+ <!-- Security Classification-->\r
+ <ximf:header id="header-classification" \r
+ headerName="X-XIMF-Security-Classification"\r
+ technicalHeaderName="X-XIMF-Security-Classification-Identifier"\r
+ type="string"\r
+ technicalType="oid"\r
+ ilk="ilk-classification"\r
+ isMandatory="true">\r
+ <ximf:set id="value-amoco-classification">\r
+ <ximf:string ilk="ilk-general" content="amoco-general" technicalContent="6" /> \r
+ <ximf:string ilk="ilk-confidential" content="amoco-confidential" technicalContent="7" />\r
+ <ximf:string ilk="ilk-highly-confidential" content="amoco-highly-confidential" technicalContent="8" /> \r
+ </ximf:set>\r
+ </ximf:header>\r
+ \r
+ <ximf:header id="header-privacy-mark" headerName="X-XIMF-Privacy-Mark" ilk="ilk-privacy-mark" isMandatory="true">\r
+ <ximf:set id="value-privacy-mark">\r
+ <ximf:string ilk="ilk-minimum" content="amoco-minimum" />\r
+ <ximf:string ilk="ilk-medium" content="amoco-medium" />\r
+ <ximf:string ilk="ilk-maximum" content="amoco-maximum" />\r
+ <ximf:string ilk="ilk-critical" content="amoco-critical" />\r
+ </ximf:set>\r
+ </ximf:header>\r
+ \r
+ <!-- headers advanced -->\r
+ <!-- headers advanced -->\r
+ <ximf:header id="header-primary-precedence" headerName="X-XIMF-Primary-Precedence" ilk="ilk-primary-precedence" isMandatory="true">\r
+ <ximf:set id="value-precedence">\r
+ <ximf:string id="data-routine-precedence" ilk="ilk-routine" content="routine" index="0" aclLevel="30"/>\r
+ <ximf:string id="data-urgent-precedence" ilk="ilk-urgent" content="priority" index="1" aclLevel="40"/>\r
+ <ximf:string id="data-immediat-precedence" ilk="ilk-immediat" content="immediate" index="2" aclLevel="50"/>\r
+ <ximf:string id="data-flash-precedence" ilk="ilk-flash" content="flash" index="3" aclLevel="100"/>\r
+ </ximf:set>\r
+ </ximf:header>\r
+ \r
+ <ximf:header id="header-copy-precedence" headerName="X-XIMF-Copy-Precedence" ilk="ilk-copy-precedence" isMandatory="false">\r
+ <ximf:set ref="value-precedence"/>\r
+ </ximf:header>\r
+ \r
+ <ximf:header id="header-reply-before" headerName="X-XIMF-Reply-Before" ilk="ilk-reply-before" isMandatory="false" type="date">\r
+ <ximf:string id="value-reply-before" editable="true" />\r
+ </ximf:header> \r
+ \r
+ <ximf:header id="header-originator-reference" headerName="X-XIMF-Originator-Reference" ilk="ilk-originator-reference" isMandatory="false" type="string">\r
+ <ximf:string id="value-originator-reference" maxItem="5" editable="true" separator=";"/>\r
+ </ximf:header>\r
+ \r
+</ximf:instance>\r
-<?xml version="1.0" encoding="UTF-8"?>
-<ximf:instance name="Amoco" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">
-<ximf:ihm xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <ximf:panel id="pane_security" ilk="ilk-classification-panel">
- <ximf:groupbox id="group-classification" ilk="ilk-security-panel">
- <ximf:headerRef>header-classification</ximf:headerRef>
- <ximf:headerRef>header-privacy-mark</ximf:headerRef>
- </ximf:groupbox>
- <ximf:groupbox id="group-info" ilk="ilk-info-box">
- <ximf:headerRef>header-originator-reference</ximf:headerRef>
- <ximf:headerRef>header-reply-before</ximf:headerRef>
- </ximf:groupbox>
- </ximf:panel>
- <ximf:treeRcv>
- <ximf:headerRef>header-classification</ximf:headerRef>
- <ximf:headerRef>header-privacy-mark</ximf:headerRef>
- </ximf:treeRcv>
-</ximf:ihm>
-</ximf:instance>
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ximf:instance name="Amoco" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">\r
+<ximf:ihm xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+ <ximf:panel id="pane_security" ilk="ilk-classification-panel">\r
+ <ximf:groupbox id="group-classification" ilk="ilk-security-panel">\r
+ <ximf:headerRef>header-classification</ximf:headerRef> \r
+ <ximf:headerRef>header-privacy-mark</ximf:headerRef>\r
+ </ximf:groupbox> \r
+ <ximf:groupbox id="group-info" ilk="ilk-info-box"> \r
+ <ximf:headerRef>header-originator-reference</ximf:headerRef> \r
+ <ximf:headerRef>header-reply-before</ximf:headerRef> \r
+ </ximf:groupbox> \r
+ </ximf:panel> \r
+ <ximf:treeRcv>\r
+ <ximf:headerRef>header-classification</ximf:headerRef> \r
+ <ximf:headerRef>header-privacy-mark</ximf:headerRef>\r
+ </ximf:treeRcv>\r
+</ximf:ihm>\r
+</ximf:instance>\r
-<?xml version="1.0" encoding="UTF-8"?>
-
-<ximf:instance name="Amoco" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">
- <ximf:rule id="compatibility-rule" description="Règle sur la compatibilités X-SMTP / XIMF" >
- <ximf:compatibility targetName="X-SMTP" targetVersion="1.1">
- <ximf:aliasHeader headerName="X-P772-Version">
- <ximf:aliasValue valueName="1.1"/>
- </ximf:aliasHeader>
- <ximf:aliasHeader headerName="X-P772-Originator-Reference" headerRef="X-XIMF-Originator-Reference"/>
- <ximf:aliasHeader headerName="X-P772-Security-Classification" headerRef="X-XIMF-Security-Classification"/>
- </ximf:compatibility>
- </ximf:rule>
- <ximf:rule id="association-rule" description="Règle d'associations de valeurs" >
- <ximf:association>
- <ximf:aliasHeader headerName="X-XIMF-Privacy-Mark" headerRef="X-XIMF-Security-Classification">
- <ximf:aliasValue valueName="amoco-minimum,amoco-medium" valueRef="amoco-general" />
- <ximf:aliasValue valueName="amoco-minimum,amoco-medium,amoco-maximum" valueRef="amoco-confidential" />
- <ximf:aliasValue valueName="amoco-minimum,amoco-medium,amoco-maximum,amoco-critical" valueRef="amoco-highly-confidential" />
- </ximf:aliasHeader>
- </ximf:association>
- </ximf:rule>
-</ximf:instance>
+<?xml version="1.0" encoding="UTF-8"?>\r
+\r
+<ximf:instance name="Amoco" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">\r
+ <ximf:rule id="compatibility-rule" description="Règle sur la compatibilités X-SMTP / XIMF" >\r
+ <ximf:compatibility targetName="X-SMTP" targetVersion="1.1">\r
+ <ximf:aliasHeader headerName="X-P772-Version">\r
+ <ximf:aliasValue valueName="1.1"/> \r
+ </ximf:aliasHeader> \r
+ <ximf:aliasHeader headerName="X-P772-Originator-Reference" headerRef="X-XIMF-Originator-Reference"/>\r
+ <ximf:aliasHeader headerName="X-P772-Security-Classification" headerRef="X-XIMF-Security-Classification"/>\r
+ </ximf:compatibility> \r
+ </ximf:rule>\r
+ <ximf:rule id="association-rule" description="Règle d'associations de valeurs" >\r
+ <ximf:association>\r
+ <ximf:aliasHeader headerName="X-XIMF-Privacy-Mark" headerRef="X-XIMF-Security-Classification">\r
+ <ximf:aliasValue valueName="amoco-minimum,amoco-medium" valueRef="amoco-general" />\r
+ <ximf:aliasValue valueName="amoco-minimum,amoco-medium,amoco-maximum" valueRef="amoco-confidential" />\r
+ <ximf:aliasValue valueName="amoco-minimum,amoco-medium,amoco-maximum,amoco-critical" valueRef="amoco-highly-confidential" />\r
+ </ximf:aliasHeader> \r
+ </ximf:association>\r
+ </ximf:rule> \r
+</ximf:instance>\r
-<?xml version="1.0" encoding="utf-8"?>
-<ximf xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <ximf:base name="Attribution_List">
- <ximf:header>
- <ximf:title>Attribution</ximf:title>
- <ximf:description>Attribution keys</ximf:description>
- <ximf:column>key</ximf:column>
- <ximf:column>description</ximf:column>
- </ximf:header>
- <ximf:tree>
- <ximf:description>
- <ximf:data>HUMAN RESOURCE</ximf:data>
- <ximf:data>Message for human resource only</ximf:data>
- </ximf:description>
- <ximf:description>
- <ximf:data>SOFTWARE RESOURCE</ximf:data>
- <ximf:data>Message for software resource only</ximf:data>
- </ximf:description>
- <ximf:description>
- <ximf:data>BUSINESS RESOURCE</ximf:data>
- <ximf:data>Message for businnes resource only</ximf:data>
- </ximf:description>
- <ximf:description>
- <ximf:data>MARKET RESOURCE</ximf:data>
- <ximf:data>Message for market resource only</ximf:data>
- </ximf:description>
- <ximf:description>
- <ximf:data>ALL PUBLIC</ximf:data>
- <ximf:data>Message for public</ximf:data>
- </ximf:description>
- <ximf:description>
- <ximf:data>CONTRIBUTORS ONLY</ximf:data>
- <ximf:data>Message for contributors only</ximf:data>
- </ximf:description>
- </ximf:tree>
- </ximf:base>
+<?xml version="1.0" encoding="utf-8"?>\r
+<ximf xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+ <ximf:base name="Attribution_List">\r
+ <ximf:header>\r
+ <ximf:title>Attribution</ximf:title>\r
+ <ximf:description>Attribution keys</ximf:description>\r
+ <ximf:column>key</ximf:column>\r
+ <ximf:column>description</ximf:column>\r
+ </ximf:header>\r
+ <ximf:tree>\r
+ <ximf:description>\r
+ <ximf:data>HUMAN RESOURCE</ximf:data>\r
+ <ximf:data>Message for human resource only</ximf:data>\r
+ </ximf:description>\r
+ <ximf:description>\r
+ <ximf:data>SOFTWARE RESOURCE</ximf:data>\r
+ <ximf:data>Message for software resource only</ximf:data>\r
+ </ximf:description> \r
+ <ximf:description>\r
+ <ximf:data>BUSINESS RESOURCE</ximf:data>\r
+ <ximf:data>Message for businnes resource only</ximf:data>\r
+ </ximf:description> \r
+ <ximf:description>\r
+ <ximf:data>MARKET RESOURCE</ximf:data>\r
+ <ximf:data>Message for market resource only</ximf:data>\r
+ </ximf:description>\r
+ <ximf:description>\r
+ <ximf:data>ALL PUBLIC</ximf:data>\r
+ <ximf:data>Message for public</ximf:data>\r
+ </ximf:description>\r
+ <ximf:description>\r
+ <ximf:data>CONTRIBUTORS ONLY</ximf:data>\r
+ <ximf:data>Message for contributors only</ximf:data>\r
+ </ximf:description> \r
+ </ximf:tree>\r
+ </ximf:base>\r
</ximf>
\ No newline at end of file
-<?xml version="1.0" encoding="UTF-8"?>
-
-<ximf:instance name="caterpillar" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">
- <ximf:dictionary id="OneDico">
- <ximf:locale lang="fr">
- <ximf:ilk entity="ilk-akw">Attribution</ximf:ilk>
- <ximf:ilk entity="ilk-security-box">Sécurité</ximf:ilk>
- <ximf:ilk entity="ilk-precedence-panel">Urgence</ximf:ilk>
- <ximf:ilk entity="ilk-public">PUBLIC</ximf:ilk>
- <ximf:ilk entity="ilk-confidential-green">CONFIDENTIEL VERT</ximf:ilk>
- <ximf:ilk entity="ilk-confidential-yellow">CONFIDENTIEL JAUNE</ximf:ilk>
- <ximf:ilk entity="ilk-confidential-red">CONFIDENTIEL ROUGE</ximf:ilk>
- <ximf:ilk entity="ilk-routine">Routine</ximf:ilk>
- <ximf:ilk entity="ilk-urgent">Urgent</ximf:ilk>
- <ximf:ilk entity="ilk-immediat">Immédiat</ximf:ilk>
- <ximf:ilk entity="ilk-flash">Flash</ximf:ilk>
- <ximf:ilk entity="header-akw">Attribution</ximf:ilk>
- <ximf:ilk entity="ilk-primary-precedence">Urgence pour action</ximf:ilk>
- <ximf:ilk entity="ilk-copy-precedence">Urgence pour information</ximf:ilk>
- <ximf:ilk entity="ilk-advanced-panel">Avancé</ximf:ilk>
- <ximf:ilk entity="ilk-originator-reference">Réferences d'origine</ximf:ilk>
- <ximf:ilk entity="ilk-reply-before">Répondre avant</ximf:ilk>
- <ximf:ilk entity="ilk-classification-panel">Classification</ximf:ilk>
- <ximf:ilk entity="ilk-classification">Classification de sécurité</ximf:ilk>
- <ximf:ilk entity="ilk-privacy-mark">Marque privée</ximf:ilk>
- <ximf:ilk entity="ilk-general">Général</ximf:ilk>
- <ximf:ilk entity="ilk-confidential">Confidentiel</ximf:ilk>
- <ximf:ilk entity="ilk-highly-confidential">Très confidentiel</ximf:ilk>
- <ximf:ilk entity="ilk-minimum">Minimum</ximf:ilk>
- <ximf:ilk entity="ilk-medium">Moyen</ximf:ilk>
- <ximf:ilk entity="ilk-maximum">Maximum</ximf:ilk>
- <ximf:ilk entity="ilk-critical">Critique</ximf:ilk>
- </ximf:locale>
- <ximf:locale lang="en-US">
- <ximf:ilk entity="ilk-akw">Attribution</ximf:ilk>
- <ximf:ilk entity="ilk-security-box">Security</ximf:ilk>
- <ximf:ilk entity="ilk-precedence-panel">Precedence</ximf:ilk>
- <ximf:ilk entity="ilk-public">PUBLIC</ximf:ilk>
- <ximf:ilk entity="ilk-confidential-green">CONFIDENTIAL GREEN</ximf:ilk>
- <ximf:ilk entity="ilk-confidential-yellow">CONFIDENTIAL YELLOW</ximf:ilk>
- <ximf:ilk entity="ilk-confidential-red">CONFIDENTIAL RED</ximf:ilk>
- <ximf:ilk entity="ilk-routine">Routine</ximf:ilk>
- <ximf:ilk entity="ilk-urgent">Urgent</ximf:ilk>
- <ximf:ilk entity="ilk-immediat">Immediate</ximf:ilk>
- <ximf:ilk entity="ilk-flash">Flash</ximf:ilk>
- <ximf:ilk entity="header-akw">Attribution</ximf:ilk>
- <ximf:ilk entity="ilk-primary-precedence">Primary precedence</ximf:ilk>
- <ximf:ilk entity="ilk-copy-precedence">Copy precedence</ximf:ilk>
- <ximf:ilk entity="ilk-advanced-panel">Advanced</ximf:ilk>
- <ximf:ilk entity="ilk-reply-before">Reply before</ximf:ilk>
- <ximf:ilk entity="ilk-originator-reference">Origin references</ximf:ilk>
- <ximf:ilk entity="ilk-classification-panel">Classification</ximf:ilk>
- <ximf:ilk entity="ilk-classification">Security classification</ximf:ilk>
- <ximf:ilk entity="ilk-privacy-mark">Privacy mark</ximf:ilk>
- <ximf:ilk entity="ilk-general">General</ximf:ilk>
- <ximf:ilk entity="ilk-confidential">Confidential</ximf:ilk>
- <ximf:ilk entity="ilk-highly-confidential">Highly Confidential</ximf:ilk>
- <ximf:ilk entity="ilk-minimum">Minimum</ximf:ilk>
- <ximf:ilk entity="ilk-medium">Medium</ximf:ilk>
- <ximf:ilk entity="ilk-maximum">Maximum</ximf:ilk>
- <ximf:ilk entity="ilk-critical">Critical</ximf:ilk>
- </ximf:locale>
- </ximf:dictionary>
-</ximf:instance>
+<?xml version="1.0" encoding="UTF-8"?>\r
+\r
+<ximf:instance name="caterpillar" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">\r
+ <ximf:dictionary id="OneDico">\r
+ <ximf:locale lang="fr">\r
+ <ximf:ilk entity="ilk-akw">Attribution</ximf:ilk>\r
+ <ximf:ilk entity="ilk-security-box">Sécurité</ximf:ilk>\r
+ <ximf:ilk entity="ilk-precedence-panel">Urgence</ximf:ilk>\r
+ <ximf:ilk entity="ilk-public">PUBLIC</ximf:ilk>\r
+ <ximf:ilk entity="ilk-confidential-green">CONFIDENTIEL VERT</ximf:ilk>\r
+ <ximf:ilk entity="ilk-confidential-yellow">CONFIDENTIEL JAUNE</ximf:ilk>\r
+ <ximf:ilk entity="ilk-confidential-red">CONFIDENTIEL ROUGE</ximf:ilk>\r
+ <ximf:ilk entity="ilk-routine">Routine</ximf:ilk>\r
+ <ximf:ilk entity="ilk-urgent">Urgent</ximf:ilk>\r
+ <ximf:ilk entity="ilk-immediat">Immédiat</ximf:ilk>\r
+ <ximf:ilk entity="ilk-flash">Flash</ximf:ilk> \r
+ <ximf:ilk entity="header-akw">Attribution</ximf:ilk>\r
+ <ximf:ilk entity="ilk-primary-precedence">Urgence pour action</ximf:ilk>\r
+ <ximf:ilk entity="ilk-copy-precedence">Urgence pour information</ximf:ilk>\r
+ <ximf:ilk entity="ilk-advanced-panel">Avancé</ximf:ilk>\r
+ <ximf:ilk entity="ilk-originator-reference">Réferences d'origine</ximf:ilk> \r
+ <ximf:ilk entity="ilk-reply-before">Répondre avant</ximf:ilk>\r
+ <ximf:ilk entity="ilk-classification-panel">Classification</ximf:ilk>\r
+ <ximf:ilk entity="ilk-classification">Classification de sécurité</ximf:ilk>\r
+ <ximf:ilk entity="ilk-privacy-mark">Marque privée</ximf:ilk> \r
+ <ximf:ilk entity="ilk-general">Général</ximf:ilk>\r
+ <ximf:ilk entity="ilk-confidential">Confidentiel</ximf:ilk> \r
+ <ximf:ilk entity="ilk-highly-confidential">Très confidentiel</ximf:ilk>\r
+ <ximf:ilk entity="ilk-minimum">Minimum</ximf:ilk>\r
+ <ximf:ilk entity="ilk-medium">Moyen</ximf:ilk>\r
+ <ximf:ilk entity="ilk-maximum">Maximum</ximf:ilk>\r
+ <ximf:ilk entity="ilk-critical">Critique</ximf:ilk> \r
+ </ximf:locale>\r
+ <ximf:locale lang="en-US">\r
+ <ximf:ilk entity="ilk-akw">Attribution</ximf:ilk>\r
+ <ximf:ilk entity="ilk-security-box">Security</ximf:ilk>\r
+ <ximf:ilk entity="ilk-precedence-panel">Precedence</ximf:ilk>\r
+ <ximf:ilk entity="ilk-public">PUBLIC</ximf:ilk>\r
+ <ximf:ilk entity="ilk-confidential-green">CONFIDENTIAL GREEN</ximf:ilk>\r
+ <ximf:ilk entity="ilk-confidential-yellow">CONFIDENTIAL YELLOW</ximf:ilk>\r
+ <ximf:ilk entity="ilk-confidential-red">CONFIDENTIAL RED</ximf:ilk>\r
+ <ximf:ilk entity="ilk-routine">Routine</ximf:ilk>\r
+ <ximf:ilk entity="ilk-urgent">Urgent</ximf:ilk>\r
+ <ximf:ilk entity="ilk-immediat">Immediate</ximf:ilk>\r
+ <ximf:ilk entity="ilk-flash">Flash</ximf:ilk>\r
+ <ximf:ilk entity="header-akw">Attribution</ximf:ilk>\r
+ <ximf:ilk entity="ilk-primary-precedence">Primary precedence</ximf:ilk>\r
+ <ximf:ilk entity="ilk-copy-precedence">Copy precedence</ximf:ilk>\r
+ <ximf:ilk entity="ilk-advanced-panel">Advanced</ximf:ilk>\r
+ <ximf:ilk entity="ilk-reply-before">Reply before</ximf:ilk>\r
+ <ximf:ilk entity="ilk-originator-reference">Origin references</ximf:ilk>\r
+ <ximf:ilk entity="ilk-classification-panel">Classification</ximf:ilk>\r
+ <ximf:ilk entity="ilk-classification">Security classification</ximf:ilk>\r
+ <ximf:ilk entity="ilk-privacy-mark">Privacy mark</ximf:ilk>\r
+ <ximf:ilk entity="ilk-general">General</ximf:ilk>\r
+ <ximf:ilk entity="ilk-confidential">Confidential</ximf:ilk> \r
+ <ximf:ilk entity="ilk-highly-confidential">Highly Confidential</ximf:ilk>\r
+ <ximf:ilk entity="ilk-minimum">Minimum</ximf:ilk>\r
+ <ximf:ilk entity="ilk-medium">Medium</ximf:ilk>\r
+ <ximf:ilk entity="ilk-maximum">Maximum</ximf:ilk>\r
+ <ximf:ilk entity="ilk-critical">Critical</ximf:ilk> \r
+ </ximf:locale>\r
+ </ximf:dictionary>\r
+</ximf:instance>\r
-<?xml version="1.0" encoding="UTF-8"?>
-<?xml-stylesheet type="text/xsl" href="ximftoxul.xsl"?>
-<ximf:instance name="Caterpillar" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">
-
- <!-- OID CATERPILLAR -->
- <ximf:header id="header-policy-identifier" headerName="X-XIMF-Security-Policy-Identifier" >
- <ximf:string content="1.2.840.113549.1.9.16.7.2"/>
- </ximf:header>
-
- <!-- Security Classification-->
- <ximf:header id="header-classification"
- headerName="X-XIMF-Security-Classification"
- technicalHeaderName="X-XIMF-Security-Classification-Identifier"
- type="string"
- technicalType="oid"
- ilk="ilk-classification"
- isMandatory="true">
- <ximf:set id="value-caterpillar-classification">
- <ximf:string ilk="ilk-public" content="caterpillar-public" technicalContent="6" />
- <ximf:string ilk="ilk-confidential-green" content="caterpillar-green" technicalContent="7" />
- <ximf:string ilk="ilk-confidential-yellow" content="caterpillar-yellow" technicalContent="8" />
- <ximf:string ilk="ilk-confidential-red" content="caterpillar-red" technicalContent="9" />
- </ximf:set>
- </ximf:header>
-
- <!-- headers advanced -->
- <ximf:header id="header-primary-precedence" headerName="X-XIMF-Primary-Precedence" ilk="ilk-primary-precedence" isMandatory="true">
- <ximf:set id="value-precedence">
- <ximf:string id="data-routine-precedence" ilk="ilk-routine" content="routine" index="0" aclLevel="30"/>
- <ximf:string id="data-urgent-precedence" ilk="ilk-urgent" content="priority" index="1" aclLevel="40"/>
- <ximf:string id="data-immediat-precedence" ilk="ilk-immediat" content="immediate" index="2" aclLevel="50"/>
- <ximf:string id="data-flash-precedence" ilk="ilk-flash" content="flash" index="3" aclLevel="100"/>
- </ximf:set>
- </ximf:header>
-
- <ximf:header id="header-copy-precedence" headerName="X-XIMF-Copy-Precedence" ilk="ilk-copy-precedence" isMandatory="false">
- <ximf:set ref="value-precedence"/>
- </ximf:header>
-
- <!-- attribution -->
- <ximf:header id="header-akw" headerName="X-XIMF-Attribution-Key-Word" ilk="ilk-akw" type="string">
- <ximf:set ref="attribution-list.xml" separator=";" maxItem="2"/>
- </ximf:header>
-
-</ximf:instance>
+<?xml version="1.0" encoding="UTF-8"?>\r
+<?xml-stylesheet type="text/xsl" href="ximftoxul.xsl"?>\r
+<ximf:instance name="Caterpillar" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">\r
+\r
+ <!-- OID CATERPILLAR -->\r
+ <ximf:header id="header-policy-identifier" headerName="X-XIMF-Security-Policy-Identifier" > \r
+ <ximf:string content="1.2.840.113549.1.9.16.7.2"/>\r
+ </ximf:header>\r
+ \r
+ <!-- Security Classification-->\r
+ <ximf:header id="header-classification" \r
+ headerName="X-XIMF-Security-Classification"\r
+ technicalHeaderName="X-XIMF-Security-Classification-Identifier"\r
+ type="string"\r
+ technicalType="oid"\r
+ ilk="ilk-classification"\r
+ isMandatory="true">\r
+ <ximf:set id="value-caterpillar-classification">\r
+ <ximf:string ilk="ilk-public" content="caterpillar-public" technicalContent="6" /> \r
+ <ximf:string ilk="ilk-confidential-green" content="caterpillar-green" technicalContent="7" />\r
+ <ximf:string ilk="ilk-confidential-yellow" content="caterpillar-yellow" technicalContent="8" />\r
+ <ximf:string ilk="ilk-confidential-red" content="caterpillar-red" technicalContent="9" /> \r
+ </ximf:set>\r
+ </ximf:header>\r
+ \r
+ <!-- headers advanced -->\r
+ <ximf:header id="header-primary-precedence" headerName="X-XIMF-Primary-Precedence" ilk="ilk-primary-precedence" isMandatory="true">\r
+ <ximf:set id="value-precedence">\r
+ <ximf:string id="data-routine-precedence" ilk="ilk-routine" content="routine" index="0" aclLevel="30"/>\r
+ <ximf:string id="data-urgent-precedence" ilk="ilk-urgent" content="priority" index="1" aclLevel="40"/>\r
+ <ximf:string id="data-immediat-precedence" ilk="ilk-immediat" content="immediate" index="2" aclLevel="50"/>\r
+ <ximf:string id="data-flash-precedence" ilk="ilk-flash" content="flash" index="3" aclLevel="100"/>\r
+ </ximf:set>\r
+ </ximf:header>\r
+ \r
+ <ximf:header id="header-copy-precedence" headerName="X-XIMF-Copy-Precedence" ilk="ilk-copy-precedence" isMandatory="false">\r
+ <ximf:set ref="value-precedence"/>\r
+ </ximf:header>\r
+ \r
+ <!-- attribution --> \r
+ <ximf:header id="header-akw" headerName="X-XIMF-Attribution-Key-Word" ilk="ilk-akw" type="string">\r
+ <ximf:set ref="attribution-list.xml" separator=";" maxItem="2"/>\r
+ </ximf:header> \r
+ \r
+</ximf:instance>\r
-<?xml version="1.0" encoding="UTF-8"?>
-<ximf:instance name="Caterpillar" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">
-<ximf:ihm xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <ximf:panel id="pane_security" ilk="ilk-classification-panel">
- <ximf:groupbox ilk="ilk-security-box">
- <ximf:headerRef>header-classification</ximf:headerRef>
- </ximf:groupbox>
- </ximf:panel>
- <ximf:panel id="pane_adanced" ilk="ilk-advanced-panel">
- <ximf:groupbox ilk="ilk-precedence-panel">
- <ximf:headerRef>header-primary-precedence</ximf:headerRef>
- <ximf:headerRef>header-copy-precedence</ximf:headerRef>
- <ximf:headerRef>header-akw</ximf:headerRef>
- </ximf:groupbox>
- </ximf:panel>
- <ximf:treeRcv>
- <ximf:headerRef>header-classification</ximf:headerRef>
- </ximf:treeRcv>
-</ximf:ihm>
-</ximf:instance>
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ximf:instance name="Caterpillar" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">\r
+<ximf:ihm xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+ <ximf:panel id="pane_security" ilk="ilk-classification-panel">\r
+ <ximf:groupbox ilk="ilk-security-box">\r
+ <ximf:headerRef>header-classification</ximf:headerRef>\r
+ </ximf:groupbox>\r
+ </ximf:panel> \r
+ <ximf:panel id="pane_adanced" ilk="ilk-advanced-panel">\r
+ <ximf:groupbox ilk="ilk-precedence-panel">\r
+ <ximf:headerRef>header-primary-precedence</ximf:headerRef>\r
+ <ximf:headerRef>header-copy-precedence</ximf:headerRef>\r
+ <ximf:headerRef>header-akw</ximf:headerRef>\r
+ </ximf:groupbox> \r
+ </ximf:panel>\r
+ <ximf:treeRcv>\r
+ <ximf:headerRef>header-classification</ximf:headerRef>\r
+ </ximf:treeRcv>\r
+</ximf:ihm>\r
+</ximf:instance>\r
-<?xml version="1.0" encoding="UTF-8"?>
-
-<ximf:instance name="caterpillar" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">
- <ximf:rule id="compatibility-rule" description="Règle sur la compatibilités X-SMTP / XIMF" >
- <ximf:association>
- <ximf:aliasHeader headerName="X-XIMF-Copy-Precedence" headerRef="X-XIMF-Primary-Precedence">
- <ximf:aliasValue valueName="routine" valueRef="routine" />
- <ximf:aliasValue valueName="routine" valueRef="priority" />
- <ximf:aliasValue valueName="routine,priority" valueRef="immediate" />
- <ximf:aliasValue valueName="routine,priority,immediate" valueRef="flash" />
- </ximf:aliasHeader>
- </ximf:association>
- </ximf:rule>
-
- <ximf:rule id="label-pictures-rule" description="rule to display pictures on received mails" >
- <ximf:classificationPictures targetName="ClassificationPictures">
- <ximf:aliasHeader headerName="url" headerRef="X-XIMF-Security-Classification-Identifier" >
- <ximf:aliasValue valueRef="7" valueName="chrome://ximfmail-company/content/CaterpillarInc/resource/caterpillar-green.png" />
- <ximf:aliasValue valueRef="8" valueName="chrome://ximfmail-company/content/CaterpillarInc/resource/caterpillar-yellow.png" />
- <ximf:aliasValue valueRef="9" valueName="chrome://ximfmail-company/content/CaterpillarInc/resource/caterpillar-red.png" />
- </ximf:aliasHeader>
- </ximf:classificationPictures>
- </ximf:rule>
-</ximf:instance>
+<?xml version="1.0" encoding="UTF-8"?>\r
+\r
+<ximf:instance name="caterpillar" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">\r
+ <ximf:rule id="compatibility-rule" description="Règle sur la compatibilités X-SMTP / XIMF" >\r
+ <ximf:association>\r
+ <ximf:aliasHeader headerName="X-XIMF-Copy-Precedence" headerRef="X-XIMF-Primary-Precedence"> \r
+ <ximf:aliasValue valueName="routine" valueRef="routine" />\r
+ <ximf:aliasValue valueName="routine" valueRef="priority" />\r
+ <ximf:aliasValue valueName="routine,priority" valueRef="immediate" />\r
+ <ximf:aliasValue valueName="routine,priority,immediate" valueRef="flash" />\r
+ </ximf:aliasHeader>\r
+ </ximf:association>\r
+ </ximf:rule>\r
+ <ximf:rule id="label-pictures-rule" description="rule to display pictures on received mails" > \r
+ <ximf:classificationPictures targetName="ClassificationPictures">\r
+ <ximf:aliasHeader headerName="url" headerRef="X-XIMF-Security-Classification-Identifier" > \r
+ <ximf:aliasValue valueRef="7" valueName="chrome://ximf-conpany-def/content/CaterpillarInc/resource/caterpillar-green.png" />\r
+ <ximf:aliasValue valueRef="8" valueName="chrome://ximf-conpany-def/content/CaterpillarInc/resource/caterpillar-yellow.png" />\r
+ <ximf:aliasValue valueRef="9" valueName="chrome://ximf-conpany-def/content/CaterpillarInc/resource/caterpillar-red.png" /> \r
+ </ximf:aliasHeader>\r
+ </ximf:classificationPictures> \r
+ </ximf:rule>\r
+</ximf:instance>\r
-<?xml version="1.0" encoding="UTF-8"?>
-
-<ximf:instance name="Whirlpool" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">
- <ximf:dictionary id="OneDico">
- <ximf:locale lang="fr">
- <ximf:ilk entity="ilk-exempted-address">Adresses exemptées</ximf:ilk>
- <ximf:ilk entity="ilk-address">Addresses</ximf:ilk>
- <ximf:ilk entity="ilk-urgence-box">Information</ximf:ilk>
- <ximf:ilk entity="ilk-general-panel">Général</ximf:ilk>
- <ximf:ilk entity="ilk-internal">INTERNE</ximf:ilk>
- <ximf:ilk entity="ilk-public">PUBLIC</ximf:ilk>
- <ximf:ilk entity="ilk-security-panel">Securité</ximf:ilk>
- <ximf:ilk entity="ilk-originator-reference">Réferences d'origine</ximf:ilk>
- <ximf:ilk entity="ilk-reply-before">Répondre avant</ximf:ilk>
- <ximf:ilk entity="ilk-classification-panel">Classification</ximf:ilk>
- <ximf:ilk entity="ilk-classification">Classification de sécurité</ximf:ilk>
- <ximf:ilk entity="ilk-privacy-mark">Marque privée</ximf:ilk>
- <ximf:ilk entity="ilk-general">Général</ximf:ilk>
- <ximf:ilk entity="ilk-confidential">CONFIDENTIEL</ximf:ilk>
- <ximf:ilk entity="ilk-highly-confidential">Très confidentiel</ximf:ilk>
- <ximf:ilk entity="ilk-minimum">Minimum</ximf:ilk>
- <ximf:ilk entity="ilk-medium">Moyen</ximf:ilk>
- <ximf:ilk entity="ilk-maximum">Maximum</ximf:ilk>
- <ximf:ilk entity="ilk-critical">Critique</ximf:ilk>
- </ximf:locale>
- <ximf:locale lang="en-US">
- <ximf:ilk entity="ilk-exempted-address">Exempted adresses</ximf:ilk>
- <ximf:ilk entity="ilk-address">Address</ximf:ilk>
- <ximf:ilk entity="ilk-urgence-box">Information</ximf:ilk>
- <ximf:ilk entity="ilk-general-panel">General</ximf:ilk>
- <ximf:ilk entity="ilk-internal">INTERAL</ximf:ilk>
- <ximf:ilk entity="ilk-public">PUBLIC</ximf:ilk>
- <ximf:ilk entity="ilk-security-panel">Security</ximf:ilk>
- <ximf:ilk entity="ilk-reply-before">Reply before</ximf:ilk>
- <ximf:ilk entity="ilk-originator-reference">Origin references</ximf:ilk>
- <ximf:ilk entity="ilk-classification-panel">Classification</ximf:ilk>
- <ximf:ilk entity="ilk-classification">Security classification</ximf:ilk>
- <ximf:ilk entity="ilk-privacy-mark">Privacy mark</ximf:ilk>
- <ximf:ilk entity="ilk-general">General</ximf:ilk>
- <ximf:ilk entity="ilk-confidential">CONFIDENTIAL</ximf:ilk>
- <ximf:ilk entity="ilk-highly-confidential">Highly Confidential</ximf:ilk>
- <ximf:ilk entity="ilk-minimum">Minimum</ximf:ilk>
- <ximf:ilk entity="ilk-medium">Medium</ximf:ilk>
- <ximf:ilk entity="ilk-maximum">Maximum</ximf:ilk>
- <ximf:ilk entity="ilk-critical">Critical</ximf:ilk>
- </ximf:locale>
- </ximf:dictionary>
-</ximf:instance>
+<?xml version="1.0" encoding="UTF-8"?>\r
+\r
+<ximf:instance name="Whirlpool" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">\r
+ <ximf:dictionary id="OneDico">\r
+ <ximf:locale lang="fr">\r
+ <ximf:ilk entity="ilk-exempted-address">Adresses exemptées</ximf:ilk>\r
+ <ximf:ilk entity="ilk-address">Addresses</ximf:ilk>\r
+ <ximf:ilk entity="ilk-urgence-box">Information</ximf:ilk>\r
+ <ximf:ilk entity="ilk-general-panel">Général</ximf:ilk>\r
+ <ximf:ilk entity="ilk-internal">INTERNE</ximf:ilk>\r
+ <ximf:ilk entity="ilk-public">PUBLIC</ximf:ilk>\r
+ <ximf:ilk entity="ilk-security-panel">Securité</ximf:ilk>\r
+ <ximf:ilk entity="ilk-originator-reference">Réferences d'origine</ximf:ilk> \r
+ <ximf:ilk entity="ilk-reply-before">Répondre avant</ximf:ilk>\r
+ <ximf:ilk entity="ilk-classification-panel">Classification</ximf:ilk>\r
+ <ximf:ilk entity="ilk-classification">Classification de sécurité</ximf:ilk>\r
+ <ximf:ilk entity="ilk-privacy-mark">Marque privée</ximf:ilk> \r
+ <ximf:ilk entity="ilk-general">Général</ximf:ilk>\r
+ <ximf:ilk entity="ilk-confidential">CONFIDENTIEL</ximf:ilk> \r
+ <ximf:ilk entity="ilk-highly-confidential">Très confidentiel</ximf:ilk>\r
+ <ximf:ilk entity="ilk-minimum">Minimum</ximf:ilk>\r
+ <ximf:ilk entity="ilk-medium">Moyen</ximf:ilk>\r
+ <ximf:ilk entity="ilk-maximum">Maximum</ximf:ilk>\r
+ <ximf:ilk entity="ilk-critical">Critique</ximf:ilk> \r
+ </ximf:locale>\r
+ <ximf:locale lang="en-US">\r
+ <ximf:ilk entity="ilk-exempted-address">Exempted adresses</ximf:ilk>\r
+ <ximf:ilk entity="ilk-address">Address</ximf:ilk>\r
+ <ximf:ilk entity="ilk-urgence-box">Information</ximf:ilk>\r
+ <ximf:ilk entity="ilk-general-panel">General</ximf:ilk>\r
+ <ximf:ilk entity="ilk-internal">INTERAL</ximf:ilk>\r
+ <ximf:ilk entity="ilk-public">PUBLIC</ximf:ilk>\r
+ <ximf:ilk entity="ilk-security-panel">Security</ximf:ilk>\r
+ <ximf:ilk entity="ilk-reply-before">Reply before</ximf:ilk>\r
+ <ximf:ilk entity="ilk-originator-reference">Origin references</ximf:ilk>\r
+ <ximf:ilk entity="ilk-classification-panel">Classification</ximf:ilk>\r
+ <ximf:ilk entity="ilk-classification">Security classification</ximf:ilk>\r
+ <ximf:ilk entity="ilk-privacy-mark">Privacy mark</ximf:ilk>\r
+ <ximf:ilk entity="ilk-general">General</ximf:ilk>\r
+ <ximf:ilk entity="ilk-confidential">CONFIDENTIAL</ximf:ilk> \r
+ <ximf:ilk entity="ilk-highly-confidential">Highly Confidential</ximf:ilk>\r
+ <ximf:ilk entity="ilk-minimum">Minimum</ximf:ilk>\r
+ <ximf:ilk entity="ilk-medium">Medium</ximf:ilk>\r
+ <ximf:ilk entity="ilk-maximum">Maximum</ximf:ilk>\r
+ <ximf:ilk entity="ilk-critical">Critical</ximf:ilk> \r
+ </ximf:locale>\r
+ </ximf:dictionary>\r
+</ximf:instance>\r
-<?xml version="1.0" encoding="UTF-8"?>
-<?xml-stylesheet type="text/xsl" href="ximftoxul.xsl"?>
-<ximf:instance name="Whirlpool" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">
-
- <!-- OID WHIRLPOOL -->
- <ximf:header id="header-policy-identifier" headerName="X-XIMF-Security-Policy-Identifier" >
- <ximf:string content="1.2.840.113549.1.9.16.7.3"/>
- </ximf:header>
-
- <!-- Security Classification-->
- <ximf:header id="header-classification"
- headerName="X-XIMF-Security-Classification"
- technicalHeaderName="X-XIMF-Security-Classification-Identifier"
- type="string"
- technicalType="oid"
- ilk="ilk-classification"
- isMandatory="true">
- <ximf:set id="value-whirlpool-classification">
- <ximf:string ilk="ilk-public" content="whirlpool-public" technicalContent="6" >
- <ximf:linkedValue ref="value-privacy-mark-other" />
- </ximf:string>
- <ximf:string ilk="ilk-internal" content="whirlpool-internal" technicalContent="7" >
- <ximf:linkedValue ref="value-privacy-mark-confidential" />
- </ximf:string>
- <ximf:string ilk="ilk-confidential" content="whirlpool-confidential" technicalContent="8" >
- <ximf:linkedValue ref="value-privacy-mark-confidential" />
- </ximf:string>
- </ximf:set>
- </ximf:header>
- <ximf:header id="header-privacy-mark" headerName="X-XIMF-Privacy-Mark" ilk="ilk-privacy-mark" isMandatory="false">
- <ximf:set id="value-privacy-mark-confidential">
- <ximf:string ilk="MAKE NO COPY" content="MAKE NO COPY" />
- <ximf:string ilk="ATTORNEY-CLIENT PRIVILEGED DOCUMENT" content="ATTORNEY-CLIENT PRIVILEGED DOCUMENT" />
- <ximf:string ilk="THIRD PARTY CONFIDENTIAL" content="THIRD PARTY CONFIDENTIAL" />
- <ximf:compstring ilk="LIMITED TO" content="LIMITED TO" separator=" : ">
- <ximf:string editable="true" />
- </ximf:compstring>
- <ximf:string ilk="COVERED BY A NON-ANALYSIS AGREEMENT" content="COVERED BY A NON-ANALYSIS AGREEMENT" />
- </ximf:set>
- <ximf:set id="value-privacy-mark-other">
- <ximf:string ilk="SEND BY INTERNET" content="SEND BY INTERNET" />
- <ximf:string ilk="PRIVATE" content="PRIVATE" />
- </ximf:set>
- </ximf:header>
-
- <!-- headers unmandatories -->
- <ximf:header id="header-reply-before" headerName="X-XIMF-Reply-Before" ilk="ilk-reply-before" isMandatory="false" type="date">
- <ximf:string id="value-reply-before" editable="true" />
- </ximf:header>
-
- <ximf:header id="header-originator-reference" headerName="X-XIMF-Originator-Reference" ilk="ilk-originator-reference" isMandatory="false" type="string">
- <ximf:string id="value-originator-reference" maxItem="10" editable="true" separator=" - "/>
- </ximf:header>
-
- <!-- Adresses exemptées -->
- <ximf:header id="header-exempted-address" headerName="X-XIMF-Exempted-Address" ilk="ilk-exempted-address" isMandatory="false" type="address">
- <ximf:string id="value-exempted-address" editable="true" />
- </ximf:header>
-
-</ximf:instance>
+<?xml version="1.0" encoding="UTF-8"?>\r
+<?xml-stylesheet type="text/xsl" href="ximftoxul.xsl"?>\r
+<ximf:instance name="Whirlpool" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">\r
+\r
+ <!-- OID WHIRLPOOL -->\r
+ <ximf:header id="header-policy-identifier" headerName="X-XIMF-Security-Policy-Identifier" > \r
+ <ximf:string content="1.2.840.113549.1.9.16.7.3"/>\r
+ </ximf:header>\r
+ \r
+ <!-- Security Classification-->\r
+ <ximf:header id="header-classification" \r
+ headerName="X-XIMF-Security-Classification"\r
+ technicalHeaderName="X-XIMF-Security-Classification-Identifier"\r
+ type="string"\r
+ technicalType="oid"\r
+ ilk="ilk-classification"\r
+ isMandatory="true">\r
+ <ximf:set id="value-whirlpool-classification">\r
+ <ximf:string ilk="ilk-public" content="whirlpool-public" technicalContent="6" > \r
+ <ximf:linkedValue ref="value-privacy-mark-other" />\r
+ </ximf:string> \r
+ <ximf:string ilk="ilk-internal" content="whirlpool-internal" technicalContent="7" >\r
+ <ximf:linkedValue ref="value-privacy-mark-confidential" />\r
+ </ximf:string> \r
+ <ximf:string ilk="ilk-confidential" content="whirlpool-confidential" technicalContent="8" >\r
+ <ximf:linkedValue ref="value-privacy-mark-confidential" />\r
+ </ximf:string> \r
+ </ximf:set>\r
+ </ximf:header> \r
+ <ximf:header id="header-privacy-mark" headerName="X-XIMF-Privacy-Mark" ilk="ilk-privacy-mark" isMandatory="false">\r
+ <ximf:set id="value-privacy-mark-confidential">\r
+ <ximf:compstring ilk="LIMITED TO" content="LIMITED TO" separator=" : ">\r
+ <ximf:string editable="true" />\r
+ </ximf:compstring>\r
+ <ximf:string ilk="MAKE NO COPY" content="MAKE NO COPY" />\r
+ <ximf:string ilk="ATTORNEY-CLIENT PRIVILEGED DOCUMENT" content="ATTORNEY-CLIENT PRIVILEGED DOCUMENT" />\r
+ <ximf:string ilk="THIRD PARTY CONFIDENTIAL" content="THIRD PARTY CONFIDENTIAL" />\r
+ <ximf:string ilk="COVERED BY A NON-ANALYSIS AGREEMENT" content="COVERED BY A NON-ANALYSIS AGREEMENT" />\r
+ </ximf:set>\r
+ <ximf:set id="value-privacy-mark-other">\r
+ <ximf:string ilk="SEND BY INTERNET" content="SEND BY INTERNET" />\r
+ <ximf:string ilk="PRIVATE" content="PRIVATE" />\r
+ </ximf:set>\r
+ </ximf:header>\r
+ \r
+ <!-- headers unmandatories -->\r
+ <ximf:header id="header-reply-before" headerName="X-XIMF-Reply-Before" ilk="ilk-reply-before" isMandatory="false" type="date">\r
+ <ximf:string id="value-reply-before" editable="true" />\r
+ </ximf:header> \r
+ \r
+ <ximf:header id="header-originator-reference" headerName="X-XIMF-Originator-Reference" ilk="ilk-originator-reference" isMandatory="false" type="string">\r
+ <ximf:string id="value-originator-reference" maxItem="10" editable="true" separator=" - "/>\r
+ </ximf:header>\r
+ \r
+ <!-- Adresses exemptées -->\r
+ <ximf:header id="header-exempted-address" headerName="X-XIMF-Exempted-Address" ilk="ilk-exempted-address" isMandatory="false" type="address">\r
+ <ximf:string id="value-exempted-address" editable="true" />\r
+ </ximf:header>\r
+\r
+</ximf:instance>\r
-<?xml version="1.0" encoding="UTF-8"?>
-<ximf:instance name="Whirlpool" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">
- <ximf:ihm xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
- <ximf:panel id="pane_security" ilk="ilk-security-panel">
- <ximf:groupbox id="group-classification" ilk="ilk-classification-panel">
- <ximf:headerRef>header-classification</ximf:headerRef>
- <ximf:headerRef>header-privacy-mark</ximf:headerRef>
- </ximf:groupbox>
- </ximf:panel>
- <ximf:panel id="pane_general" ilk="ilk-general-panel">
- <ximf:groupbox id="group-ref" ilk="ilk-urgence-box">
- <ximf:headerRef>header-originator-reference</ximf:headerRef>
- <ximf:headerRef>header-reply-before</ximf:headerRef>
- </ximf:groupbox>
- </ximf:panel>
- <ximf:panel id="pane_address" ilk="ilk-address">
- <ximf:headerRef>header-exempted-address</ximf:headerRef>
- </ximf:panel>
- <ximf:treeRcv>
- <ximf:headerRef>header-classification</ximf:headerRef>
- <ximf:headerRef>header-privacy-mark</ximf:headerRef>
- </ximf:treeRcv>
- </ximf:ihm>
-</ximf:instance>
+<?xml version="1.0" encoding="UTF-8"?>\r
+<ximf:instance name="Whirlpool" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">\r
+ <ximf:ihm xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">\r
+ <ximf:panel id="pane_security" ilk="ilk-security-panel">\r
+ <ximf:groupbox id="group-classification" ilk="ilk-classification-panel">\r
+ <ximf:headerRef>header-classification</ximf:headerRef> \r
+ <ximf:headerRef>header-privacy-mark</ximf:headerRef>\r
+ </ximf:groupbox> \r
+ </ximf:panel> \r
+ <ximf:panel id="pane_general" ilk="ilk-general-panel"> \r
+ <ximf:groupbox id="group-ref" ilk="ilk-urgence-box"> \r
+ <ximf:headerRef>header-originator-reference</ximf:headerRef> \r
+ <ximf:headerRef>header-reply-before</ximf:headerRef> \r
+ </ximf:groupbox> \r
+ </ximf:panel>\r
+ <ximf:panel id="pane_address" ilk="ilk-address"> \r
+ <ximf:headerRef>header-exempted-address</ximf:headerRef> \r
+ </ximf:panel>\r
+ <ximf:treeRcv>\r
+ <ximf:headerRef>header-classification</ximf:headerRef> \r
+ <ximf:headerRef>header-privacy-mark</ximf:headerRef>\r
+ </ximf:treeRcv>\r
+ </ximf:ihm>\r
+</ximf:instance>\r
-<?xml version="1.0" encoding="UTF-8"?>
-
-<ximf:instance name="Whirlpool" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">
- <!--
- -->
-</ximf:instance>
+<?xml version="1.0" encoding="UTF-8"?>\r
+\r
+<ximf:instance name="Whirlpool" version="1.0" ximfVersion="2.0" xmlns:ximf="http://eads.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">\r
+</ximf:instance>\r
--- /dev/null
+<?xml version="1.0" encoding="utf-8"?>\r
+<profile>\r
+ <theme name="Company Def"\r
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"\r
+ xsi:noNamespaceSchemaLocation="D:\DOC\ximf_profile.xsd">\r
+ <instance id="smtp" ximfVersion="2.0" version="1.0" label="Message standard" name="smtp" directory="" author="string"/>\r
+ <instance id="idAmocoDefinition" ximfVersion="2.0" version="1.0"\r
+ name="Amoco"\r
+ directory="{E255643F-7DCA-4cd8-B0C2-61EAADE39FCE}/chrome/content/AmocoCorporation/"\r
+ author="Ximfmail">\r
+ <schema id="AAAAB" name="Amoco">headers-amoco.xml</schema>\r
+ <dictionary author="EADS DS">dictionary-amoco.xml</dictionary>\r
+ <ihm id="AAAAC" name="string">ihm-amoco.xml</ihm>\r
+ <rule id="AAAAD" author="string">rules-amoco.xml</rule>\r
+ </instance>\r
+ <instance id="idCaterpillarDefinition" ximfVersion="2.0"\r
+ version="1.0" name="Caterpillar"\r
+ directory="{E255643F-7DCA-4cd8-B0C2-61EAADE39FCE}/chrome/content/CaterpillarInc/"\r
+ author="Ximfmail">\r
+ <schema name="Caterpillar">headers-caterpillar.xml</schema>\r
+ <dictionary>dictionary-caterpillar.xml</dictionary>\r
+ <ihm>ihm-caterpillar.xml</ihm>\r
+ <rule author="string">rules-caterpillar.xml</rule>\r
+ </instance>\r
+ <instance id="idWhirlpoolDefinition" ximfVersion="2.0"\r
+ version="1.0" name="Whirlpool"\r
+ directory="{E255643F-7DCA-4cd8-B0C2-61EAADE39FCE}/chrome/content/WhirlpoolCorporation/"\r
+ author="Ximfmail">\r
+ <schema name="Whirlpool">headers-whirlpool.xml</schema>\r
+ <dictionary>dictionary-whirlpool.xml</dictionary>\r
+ <ihm>ihm-whirlpool.xml</ihm>\r
+ <rule>rules-whirlpool.xml</rule>\r
+ </instance>\r
+ </theme>\r
+</profile>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="no"?><RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">\r
+ <Description about="urn:mozilla:install-manifest">\r
+ <em:name>Definition Company Sample</em:name>\r
+ <em:version>24.3.0.1.0</em:version>\r
+ <em:id>{E255643F-7DCA-4cd8-B0C2-61EAADE39FCE}</em:id>\r
+ <em:description>Sample Definition Instances for Ximfmail</em:description>\r
+ <em:unpack>true</em:unpack>\r
+ <em:targetApplication>\r
+ <!-- Thunderbird -->\r
+ <Description>\r
+ <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>\r
+ <em:minVersion>24.3.0</em:minVersion>\r
+ <em:maxVersion>24.3.*</em:maxVersion>\r
+ </Description>\r
+ </em:targetApplication>\r
+ <!-- Development team -->\r
+ <em:creator>Airbus Defence and Space</em:creator>\r
+ <!-- Informations -->\r
+ <em:homepageURL>http://www.airbusdefenceandspace.com</em:homepageURL>\r
+ <em:optionsURL/><em:aboutURL/><em:iconURL/><em:updateURL/>\r
+ </Description>\r
+</RDF>
\ No newline at end of file
--- /dev/null
+ximf-company-def.jar:
+% content ximf-company-def %content/
+% locale ximf-company-def fr %locale/fr-FR/
+% locale ximf-company-def us %locale/en-US/
+% skin ximf-incompany-def %classic/1.0 skin/classic/
+ content/CaterpillarInc/resource/caterpillar-green.png (chrome/content/CaterpillarInc/resource/caterpillar-green.png)
+ content/CaterpillarInc/resource/caterpillar-yellow.png (chrome/content/CaterpillarInc/resource/caterpillar-yellow.png)
+ content/CaterpillarInc/resource/caterpillar-red.png (chrome/content/CaterpillarInc/resource/caterpillar-red.png)
+
+
--- /dev/null
+#
+# ***** 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 "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 the Initial Developer are Copyright (C) 1998
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+#
+# Alternatively, the contents of this file may be used under the terms of
+# either of 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 *****
+
+DEPTH = ../../..
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+MODULE = ximf_mdn
+DIRS =
+
+XPI_NAME = Ximf_mdn
+INSTALL_EXTENSION_ID = {A9FAF6FB-7786-4a66-AE31-9D4E5A22E445}
+XPI_PKGNAME = ximf_mdn
+
+DIST_FILES = install.rdf update.rdf
+
+USE_EXTENSION_MANIFEST = 1
+
+include $(topsrcdir)/config/rules.mk
--- /dev/null
+content ximf_mdn chrome/content/
+overlay chrome://messenger/content/messenger.xul chrome://ximf_mdn/content/messenger_ov_ximfmdn.xul
+overlay chrome://messenger/content/messageWindow.xul chrome://ximf_mdn/content/messageWindow_ov_ximfmdn.xul
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!-- ***** BEGIN LICENSE BLOCK *****\r
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1\r
+ -\r
+ - The contents of this file are subject to the Mozilla Public License Version\r
+ - 1.1 (the "License"); you may not use this file except in compliance with\r
+ - the License. You may obtain a copy of the License at\r
+ - http://www.mozilla.org/MPL/\r
+ -\r
+ - Software distributed under the License is distributed on an "AS IS" basis,\r
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\r
+ - for the specific language governing rights and limitations under the\r
+ - License.\r
+ -\r
+ - The Original Code is Mozilla Communicator\r
+ -\r
+ - The Initial Developer of the Original Code is\r
+ - BT Global Services / Etat francais Ministere de la Defense\r
+ - Portions created by the Initial Developer are Copyright (C) 2002\r
+ - the Initial Developer. All Rights Reserved.\r
+ -\r
+ - Contributor(s):\r
+ - Eric Ballet Baz BT Global Services / Etat francais Ministere de la Defense\r
+ -\r
+ - Alternatively, the contents of this file may be used under the terms of\r
+ - either the GNU General Public License Version 2 or later (the "GPL"), or\r
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
+ - in which case the provisions of the GPL or the LGPL are applicable instead\r
+ - of those above. If you wish to allow use of your version of this file only\r
+ - under the terms of either the GPL or the LGPL, and not to allow others to\r
+ - use your version of this file under the terms of the MPL, indicate your\r
+ - decision by deleting the provisions above and replace them with the notice\r
+ - and other provisions required by the LGPL or the GPL. If you do not delete\r
+ - the provisions above, a recipient may use your version of this file under\r
+ - the terms of any one of the MPL, the GPL or the LGPL.\r
+ -\r
+ - ***** END LICENSE BLOCK ***** -->\r
+ \r
+<overlay id="mdn_extended_messengeWindow_overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">\r
+ <script type="application/javascript" src="chrome://ximf_mdn/content/ximfmdn_extended.js"/> \r
+</overlay>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!-- ***** BEGIN LICENSE BLOCK *****\r
+ - Version: MPL 1.1/GPL 2.0/LGPL 2.1\r
+ -\r
+ - The contents of this file are subject to the Mozilla Public License Version\r
+ - 1.1 (the "License"); you may not use this file except in compliance with\r
+ - the License. You may obtain a copy of the License at\r
+ - http://www.mozilla.org/MPL/\r
+ -\r
+ - Software distributed under the License is distributed on an "AS IS" basis,\r
+ - WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\r
+ - for the specific language governing rights and limitations under the\r
+ - License.\r
+ -\r
+ - The Original Code is Mozilla Communicator\r
+ -\r
+ - The Initial Developer of the Original Code is\r
+ - BT Global Services / Etat francais Ministere de la Defense\r
+ - Portions created by the Initial Developer are Copyright (C) 2002\r
+ - the Initial Developer. All Rights Reserved.\r
+ -\r
+ - Contributor(s):\r
+ - Eric Ballet Baz BT Global Services / Etat francais Ministere de la Defense\r
+ -\r
+ - Alternatively, the contents of this file may be used under the terms of\r
+ - either the GNU General Public License Version 2 or later (the "GPL"), or\r
+ - the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
+ - in which case the provisions of the GPL or the LGPL are applicable instead\r
+ - of those above. If you wish to allow use of your version of this file only\r
+ - under the terms of either the GPL or the LGPL, and not to allow others to\r
+ - use your version of this file under the terms of the MPL, indicate your\r
+ - decision by deleting the provisions above and replace them with the notice\r
+ - and other provisions required by the LGPL or the GPL. If you do not delete\r
+ - the provisions above, a recipient may use your version of this file under\r
+ - the terms of any one of the MPL, the GPL or the LGPL.\r
+ -\r
+ - ***** END LICENSE BLOCK ***** -->\r
+<overlay id="mdn_extended_messenger_overlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">\r
+ <script type="application/javascript" src="chrome://ximf_mdn/content/ximfmdn_extended.js"/>\r
+</overlay>
\ No newline at end of file
--- /dev/null
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-\r
+ * ***** BEGIN LICENSE BLOCK *****\r
+ * Version: MPL 1.1/GPL 2.0/LGPL 2.1\r
+ *\r
+ * The contents of this file are subject to the Mozilla Public License Version\r
+ * 1.1 (the "License"); you may not use this file except in compliance with\r
+ * the License. You may obtain a copy of the License at\r
+ * http://www.mozilla.org/MPL/\r
+ *\r
+ * Software distributed under the License is distributed on an "AS IS" basis,\r
+ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License\r
+ * for the specific language governing rights and limitations under the\r
+ * License.\r
+ *\r
+ * The Original Code is mozilla.org Code.\r
+ *\r
+ * The Initial Developer of the Original Code is\r
+ * BT Global Services / Etat francais Ministere de la Defense\r
+ * Portions created by the Initial Developer are Copyright (C) 1998-2001\r
+ * the Initial Developer. All Rights Reserved.\r
+ *\r
+ * Contributor(s):\r
+ * Eric Ballet Baz BT Global Services / Etat francais Ministere de la Defense\r
+ * Copyright (c) 2014 CASSIDIAN - All rights reserved\r
+ *\r
+ * Alternatively, the contents of this file may be used under the terms of\r
+ * either of the GNU General Public License Version 2 or later (the "GPL"),\r
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
+ * in which case the provisions of the GPL or the LGPL are applicable instead\r
+ * of those above. If you wish to allow use of your version of this file only\r
+ * under the terms of either the GPL or the LGPL, and not to allow others to\r
+ * use your version of this file under the terms of the MPL, indicate your\r
+ * decision by deleting the provisions above and replace them with the notice\r
+ * and other provisions required by the GPL or the LGPL. If you do not delete\r
+ * the provisions above, a recipient may use your version of this file under\r
+ * the terms of any one of the MPL, the GPL or the LGPL.\r
+ *\r
+ * ***** END LICENSE BLOCK ***** */\r
+\r
+// MDN Disposition Type for Deletion\r
+var MDN_DISPOSE_TYPE_DELETED = 3;\r
+var MDN_Registered=false;\r
+//Save the original built SetupCommandUpdateHandlers functions\r
+var mdn_extended_OriginalSetupCommandUpdateHandlers;\r
+if(!mdn_extended_OriginalSetupCommandUpdateHandlers)\r
+{\r
+ mdn_extended_OriginalSetupCommandUpdateHandlers=SetupCommandUpdateHandlers;\r
+}\r
+\r
+// Controller object that will handle deletion commands : used to override default controller\r
+var mdn_extended_MDN_DeleteController = {\r
+ supportsCommand: function(command) {\r
+ switch (command) {\r
+ case "cmd_delete":\r
+ case "button_delete":\r
+ case "cmd_shiftDelete":\r
+ return true;\r
+ default:\r
+ return false;\r
+ }\r
+ },\r
+ isCommandEnabled: function(command) {\r
+ // Delegate this call to the default controller\r
+ return DefaultController.isCommandEnabled(command);\r
+ },\r
+ doCommand: function(command) {\r
+ // if the user invoked a key short cut then it is possible that we got here for a command which is really disabled. kick out if the command should be disabled.\r
+ if (!this.isCommandEnabled(command)) {\r
+ return;\r
+ }\r
+ // HandleMDNDeleteResponse for each message to delete\r
+ var selectedMessages = gFolderDisplay.selectedMessageUris;\r
+ if (selectedMessages) {\r
+ var nbSelectedMessages = selectedMessages.length;\r
+ for (var i = 0; i < nbSelectedMessages; i++) {\r
+ var URL = mdn_extended_createURLFromURI(selectedMessages[i]);\r
+ var headers = mdn_extended_createHeadersFromURI(selectedMessages[i]);\r
+ mdn_extended_HandleMDNDeleteResponse(URL, headers);\r
+ }\r
+ }\r
+ // Delegate deletion to the default controller\r
+ DefaultController.doCommand(command);\r
+ },\r
+ onEvent: function(event) {\r
+ }\r
+};\r
+\r
+function mdn_extended_createHeadersFromURI(messageURI) {\r
+ var messageService = messenger.messageServiceFromURI(messageURI);\r
+ var messageStream = Components.classes["@mozilla.org/network/sync-stream-listener;1"].createInstance().QueryInterface(Components.interfaces.nsIInputStream);\r
+ var inputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance().QueryInterface(Components.interfaces.nsIScriptableInputStream);\r
+ inputStream.init(messageStream);\r
+ var newuri = messageService.streamMessage(messageURI,messageStream, msgWindow, null, false, null);\r
+\r
+ var content = "";\r
+ inputStream.available();\r
+ while (inputStream.available()) {\r
+ content = content + inputStream.read(512);\r
+ var p = content.indexOf("\r\n\r\n");\r
+ var p1 = content.indexOf("\r\r");\r
+ var p2 = content.indexOf("\n\n");\r
+ if (p > 0) {\r
+ content = content.substring(0, p);\r
+ break;\r
+ }\r
+ if (p1 > 0) {\r
+ content = content.substring(0, p1);\r
+ break;\r
+ }\r
+ if (p2 > 0) {\r
+ content = content.substring(0, p2);\r
+ break;\r
+ }\r
+ if (content.length > 512 * 8)\r
+ {\r
+ throw "Could not find end-of-headers line.";\r
+ return null;\r
+ }\r
+ }\r
+ content = content + "\r\n";\r
+\r
+ var headers = Components.classes["@mozilla.org/messenger/mimeheaders;1"].createInstance().QueryInterface(Components.interfaces.nsIMimeHeaders);\r
+ headers.initialize(content, content.length);\r
+ return headers;\r
+}\r
+\r
+function mdn_extended_createURLFromURI(messageURI) {\r
+ var messageService = messenger.messageServiceFromURI(messageURI);\r
+ var holder = new Object();\r
+ messageService.GetUrlForUri(messageURI, holder, null);\r
+ holder.value.QueryInterface(Components.interfaces.nsIMsgMailNewsUrl);\r
+ return holder.value;\r
+}\r
+\r
+\r
+// This function handles all mdn delete response generation\r
+function mdn_extended_HandleMDNDeleteResponse(aUrl, headers) {\r
+ if (!aUrl) {\r
+ return;\r
+ }\r
+ var msgFolder = aUrl.folder;\r
+ var msgURI = gFolderDisplay.selectedMessageUris[0]; //GetLoadedMessage();\r
+ if (!msgFolder || !msgURI || gFolderDisplay.selectedMessageIsNews) {\r
+ return;\r
+ }\r
+ // If the message is already in the Trash don't send a MDN delete report\r
+ if (msgFolder.isSpecialFolder( Components.interfaces.nsMsgFolderFlags.Trash, true)) {\r
+ return;\r
+ }\r
+ // if the message is marked as junk, do NOT attempt to process a return receipt in order to better protect the user\r
+ var msgHdr = gFolderDisplay.selectedMessage;\r
+ var junkScore = msgHdr.getStringProperty("junkscore");\r
+ if(junkScore !== "0") {\r
+ return;\r
+ }\r
+ var msgHdr = messenger.msgHdrFromURI(msgURI);\r
+ var mimeHdr = headers;\r
+ // If we didn't get the message id when we downloaded the message header,\r
+ // we cons up an md5: message id. If we've done that, we'll try to extract\r
+ // the message id out of the mime headers for the whole message.\r
+ var msgId = msgHdr.messageId;\r
+ if (msgId.split(":")[0] == "md5") {\r
+ var mimeMsgId = mimeHdr.extractHeader("Message-Id", false);\r
+ if (mimeMsgId) {\r
+ msgHdr.messageId = mimeMsgId;\r
+ }\r
+ }\r
+ // Check if the message has already been delete (IMAP)\r
+ var msgFlags = msgHdr.flags;\r
+ if ((msgFlags & Components.interfaces.nsMsgMessageFlags.IMAPDeleted)) {\r
+ return;\r
+ }\r
+ // Check if the positive MDN message has been sent\r
+ if ((msgFlags & Components.interfaces.nsMsgMessageFlags.MDNReportSent)) {\r
+ return;\r
+ }\r
+ // Check if the msg has a "Disposition-Notification-To" header.\r
+ var DNTHeader = mimeHdr.extractHeader("Disposition-Notification-To", false);\r
+ var oldDNTHeader = mimeHdr.extractHeader("Return-Receipt-To", false);\r
+ if (!DNTHeader && !oldDNTHeader) {\r
+ return;\r
+ }\r
+ // Everything looks good so far, let's generate the MDN delete response.\r
+ var mdnGenerator = Components.classes["@mozilla.org/messenger-mdn/generator;1"].createInstance(Components.interfaces.nsIMsgMdnGenerator);\r
+ if (mdnGenerator.process(MDN_DISPOSE_TYPE_DELETED, msgWindow, msgFolder, msgHdr.messageKey, mimeHdr, true)) {\r
+ mdnGenerator.userAgreed();\r
+ }\r
+}\r
+\r
+\r
+// Extension Hook : replace the built in SetupCommandUpdateHandlers functions defined in mail3PaneWindowCommands.js and in messageWindow.js with our own..\r
+SetupCommandUpdateHandlers = function mdn_extended_SetupCommandUpdateHandlers() {\r
+ //Test if the MDN controller is registered\r
+ // to have not some calls in loop\r
+ if(!MDN_Registered)\r
+ {\r
+ // Call built in SetupCommandUpdateHandlers function\r
+ mdn_extended_OriginalSetupCommandUpdateHandlers();\r
+\r
+ // Register our MDN_DeleteController as the first controller in the list\r
+ top.controllers.insertControllerAt(0, mdn_extended_MDN_DeleteController);\r
+ MDN_Registered=true;\r
+ dump("MDN_DeleteController Registered\n");\r
+ }\r
+}\r
+\r
+\r
+\r
--- /dev/null
+<?xml version="1.0"?>\r
+<RDF:RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#"\r
+ xmlns:NC="http://home.netscape.com/NC-rdf#"\r
+ xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">\r
+ <RDF:Description RDF:about="urn:mozilla:install-manifest"\r
+ em:id="{A9FAF6FB-7786-4a66-AE31-9D4E5A22E445}"\r
+ em:name="XIMF MDN extented"\r
+ em:version="24.3.0.1.0"\r
+ em:description="Message Disposition Notification extended"\r
+ em:creator="Airbus Defence and Space"\r
+ em:homepageURL="http://www.airbusdefenceandspace.com">\r
+ <em:targetApplication>\r
+ <!-- Thunderbird -->\r
+ <Description>\r
+ <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>\r
+ <em:minVersion>24.3.0</em:minVersion>\r
+ <em:maxVersion>24.3.*</em:maxVersion>\r
+ </Description>\r
+ </em:targetApplication>\r
+ </RDF:Description> \r
+</RDF:RDF>
\ No newline at end of file
--- /dev/null
+ximf_mdn.jar:
+% content ximf_mdn %content/
+% locale ximf_mdn fr %locale/fr_FR/
+% locale ximf_mdn us %locale/en_US/
+% skin ximf_mdn %classic/1.0 skin/
+% overlay chrome://messenger/content/messenger.xul chrome://ximf_mdn/content/messenger_ov_ximfmdn.xul
+% overlay chrome://messenger/content/messageWindow.xul chrome://ximf_mdn/content/messageWindow_ov_ximfmdn.xul
+ content/ximfmdn_extended.js (chrome/content/ximfmdn_extended.js)
+ content/messenger_ov_ximfmdn.xul (chrome/content/messenger_ov_ximfmdn.xul)
+ content/messageWindow_ov_ximfmdn.xul (chrome/content/messageWindow_ov_ximfmdn.xul)
+
--- /dev/null
+<?xml version="1.0"?>\r
+\r
+<RDF:RDF xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\r
+xmlns:em="http://www.mozilla.org/2004/em-rdf#">\r
+\r
+<RDF:Description about="urn:mozilla:extension:${thunext.name}">\r
+ <em:updates>\r
+ <RDF:Seq>\r
+ <RDF:li resource="urn:mozilla:extension:${thunext.name}:1.0.1.1265161759"/>\r
+ </RDF:Seq>\r
+ </em:updates>\r
+ <em:version>1.0.1.1265161759</em:version>\r
+ <em:updateLink>http://smdev085/update/fr/ximf_mdn/@ARCHIVE_NAME@</em:updateLink>\r
+</RDF:Description>\r
+\r
+<RDF:Description about="urn:mozilla:extension:${thunext.name}:1.0.1.1265161759">\r
+<em:version>1.0.1.1265161759</em:version>\r
+<em:targetApplication>\r
+ <!-- Thunderbird -->\r
+ <Description>\r
+ <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>\r
+ <em:minVersion>1.5</em:minVersion>\r
+ <em:maxVersion>2.0.*</em:maxVersion>\r
+ <em:updateLink>http://smdev085/update/fr/ximf_mdn/@ARCHIVE_NAME@</em:updateLink>\r
+ </Description>\r
+</em:targetApplication>\r
+</RDF:Description>\r
+\r
+</RDF:RDF>\r
+++ /dev/null
-content ximfmail-company chrome/content/ xpcnativewrappers=yes
+++ /dev/null
-<?xml version="1.0" encoding="utf-8"?>
-<profile>
- <theme name="Company Def" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="D:\DOC\DOC_THUN_INTRACED\ximf_profile.xsd">
- <instance id="smtp" ximfVersion="2.0" version="1.0" name="standard" />
- <instance id="idAmocoDefinition" ximfVersion="2.0" version="1.0" name="Amoco" directory="{E255643F-7DCA-4cd8-B0C2-61EAADE39FCE}/chrome/content/AmocoCorporation/" author="Ximfmail">
- <schema id="AAAAB" name="Amoco">headers-amoco.xml</schema>
- <dictionary author="EADS DS">dictionary-amoco.xml</dictionary>
- <ihm id="AAAAC" name="string">ihm-amoco.xml</ihm>
- <rule id="AAAAD" author="string">rules-amoco.xml</rule>
- </instance>
- <instance id="idCaterpillarDefinition" ximfVersion="2.0" version="1.0" name="Caterpillar" directory="{E255643F-7DCA-4cd8-B0C2-61EAADE39FCE}/chrome/content/CaterpillarInc/" author="Ximfmail">
- <schema name="Caterpillar">headers-caterpillar.xml</schema>
- <dictionary>dictionary-caterpillar.xml</dictionary>
- <ihm >ihm-caterpillar.xml</ihm>
- <rule author="string">rules-caterpillar.xml</rule>
- </instance>
- <instance id="idWhirlpoolDefinition" ximfVersion="2.0" version="1.0" name="Whirlpool" directory="{E255643F-7DCA-4cd8-B0C2-61EAADE39FCE}/chrome/content/WhirlpoolCorporation/" author="Ximfmail">
- <schema name="Whirlpool">headers-whirlpool.xml</schema>
- <dictionary>dictionary-whirlpool.xml</dictionary>
- <ihm>ihm-whirlpool.xml</ihm>
- <rule>rules-whirlpool.xml</rule>
- </instance>
- </theme>
-</profile>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
- <Description about="urn:mozilla:install-manifest">
- <em:name>Definition Company Sample</em:name>
- <em:version>__VERSION__</em:version>
- <em:id>{E255643F-7DCA-4cd8-B0C2-61EAADE39FCE}</em:id>
- <em:description>Sample Definition Instances for Ximfmail</em:description>
-
- <em:targetApplication>
- <!-- Thunderbird -->
- <Description>
- <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
- <em:minVersion>1.5</em:minVersion>
- <em:maxVersion>3.1.*</em:maxVersion>
- </Description>
- </em:targetApplication>
-
- <!-- Equipe de developpement, contributeurs et traducteurs -->
- <em:creator>EADS Defence and Security Systems SA</em:creator>
-
- <!-- Informations diverses -->
- <em:homepageURL>http://www.trustedbird.org/</em:homepageURL>
- <em:updateURL>__UPDATE_RDF_URL__</em:updateURL>
- <em:updateKey>__UPDATE_KEY__</em:updateKey>
-
- <em:hidden/>
- </Description>
-</RDF>
+++ /dev/null
-<?xml version="1.0" encoding="UTF-8"?>
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">
- <em:creator>EADS Defence and Security Systems SA</em:creator>
- <rdf:Description rdf:about="urn:mozilla:extension:{E255643F-7DCA-4cd8-B0C2-61EAADE39FCE}">
- <em:updates>
- <rdf:Seq>
- <rdf:li>
- <rdf:Description>
- <em:version>__VERSION__</em:version>
- <em:targetApplication>
- <rdf:Description>
- <!-- Thunderbird -->
- <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>
- <em:minVersion>1.5</em:minVersion>
- <em:maxVersion>3.1.*</em:maxVersion>
- <em:updateLink>__XPI_URL__</em:updateLink>
- <em:updateHash>__UPDATE_HASH__</em:updateHash>
- </rdf:Description>
- </em:targetApplication>
- </rdf:Description>
- </rdf:li>
- </rdf:Seq>
- </em:updates>
- </rdf:Description>
-</rdf:RDF>
-Ximfmail (3.1.20+1.8.2)
-* Corrective on diplaying classification stamps
-* Corrective on displaying XIMF headers panel
-* Corrective on managing XIMF instances
-* Corrective on custom columns
-* Corrective on empty Ximf header value to hide
-* Corrective on using settings to sign messages (user can send unsigned message)
--- Sep 07 2012
-
Ximfmail (3.1.11+0.6.4)
-* Corrective on blocking TrustedBird on downloading messages with big attachments
-* Corrective on using settings to sign messages
+ * Corrective on blocking TrustedBird on downloading messages with big attachments
+ * Corrective on using settings to sign messages
-- Sep 09 2011
+Ximfmail (24.3.0.0.1.0)
+ * Upgrade to be used with Trustedbird 24.3.0
+-- 06 Mai 2014
\ No newline at end of file
#
# ***** END LICENSE BLOCK *****
+
+
+
DEPTH = ../../..
topsrcdir = @top_srcdir@
srcdir = @srcdir@
-content ximfmail chrome/content/kernel/ xpcnativewrappers=yes
-content theme_ximfmail chrome/content/theme/ xpcnativewrappers=yes
+content ximfmail chrome/content/kernel/
+content theme_ximfmail chrome/content/theme/
locale ximfmail fr chrome/locale/fr-FR/
locale ximfmail us chrome/locale/en-US/
skin ximfmail classic/1.0 chrome/skin/
overlay chrome://messenger/content/messengercompose/messengercompose.xul chrome://ximfmail/content/messengerCompose-ov-ximfmail.xul
overlay chrome://messenger/content/messageWindow.xul chrome://ximfmail/content/messageWindow-ov-ximfmail.xul
overlay chrome://messenger-smime/content/msgReadSecurityInfo.xul chrome://ximfmail/content/msgReadSecurityInfo-ov-ximfmail.xul
+
+# Preference Service
+component {4B539696-E605-4663-B9E9-CB6D44B6FFEB} components/ximfmail-service.js
+contract @mozilla.org/accountmanager/extension;1?name=ximfmail-account {4B539696-E605-4663-B9E9-CB6D44B6FFEB}
+category mailnews-accountmanager-extensions ximfmail-account-manager-extension @mozilla.org/accountmanager/extension;1?name=ximfmail-account
/* ***** BEGIN LICENSE BLOCK *****\r
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
*\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
* are permitted provided that the following conditons are met :\r
*\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
* in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
* prior written permission from EADS Defence and Security.\r
- * \r
+ *\r
* Alternatively, the contents of this file may be used under the terms of\r
* either of the GNU General Public License Version 2 or later (the "GPL"),\r
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
* and other provisions required by the GPL or the LGPL. If you do not delete\r
* the provisions above, a recipient may use your version of this file under\r
* the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
+ *\r
* REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ *\r
+ * Contributor(s):\r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
* ***** END LICENSE BLOCK ***** */\r
- \r
-/* \r
- * global variables\r
- */\r
-var gXimfmailIdentity=null;\r
-\r
-/* \r
- * new theme selection : load instances of theme\r
- */\r
-function onCommandTheme(){ \r
- var themeRef = $("#listTheme").attr("value"); \r
- ChangeRefAttrRdfElement("instanceCompose", themeRef);\r
- InitRDFMenuList("instanceComposeList"); \r
- ChangeRefAttrRdfElement("instanceTreeThread", themeRef);\r
- InitRDFMenuList("instanceTreeThreadList");\r
- ChangeRefAttrRdfElement("instanceMailPanel", themeRef);\r
- InitRDFMenuList("instanceMailPanelList");\r
-};\r
-\r
-\r
-/*\r
- * load pref ximfmail settings\r
- */ \r
-function onInit(aPageId, aServerId){\r
- \r
- if(gXimfmailIdentity == null){\r
- // no account id (local folder)\r
- $("#checkListTheme").attr("checked", "false");\r
- UseXimfmail();\r
- $("#checkListTheme").attr("disabled", "true"); \r
- return; \r
- }\r
- $("#checkListTheme").removeAttr("disabled");\r
- \r
- //get XIMF instances of profile for account\r
- if(!gXimfCatalog) CreateXimfmailCatalog();\r
- var listInstances = document.getElementById("listThemPopup"); \r
- listInstances.database.AddDataSource(gXimfCatalog.getDSCatalog()); \r
- listInstances.builder.rebuild();\r
- \r
- //alert("Informations compte : \r\n\n" + aPageId + "\r\n"+ aServerId + "\r\n" + gXimfIdentity + "\r\n" + gXimfAccount.incomingServer.key);\r
- UpdateRDFListWithPref(gXimfmailIdentity.key,"ximfmail_theme_ref","listTheme");\r
- onCommandTheme();\r
- UpdateRDFListWithPref(gXimfmailIdentity.key,"ximfmail_instance_compose_ref","instanceComposeList");\r
- UpdateRDFListWithPref(gXimfmailIdentity.key,XIMF_PREF_IDENTITY_TREETHREAD_REF,"instanceTreeThreadList");\r
- UpdateRDFListWithPref(gXimfmailIdentity.key,XIMF_PREF_IDENTITY_MAIL_PANEL_REF,"instanceMailPanelList");\r
- \r
- // determine if user uses ximfmail \r
- if(gXimfmailIdentity.getBoolAttribute(XIMF_PREF_IDENTITY_USE_XIMFMAIL)){\r
- $("#checkListTheme").attr("checked", "true");\r
- }else{\r
- $("#checkListTheme").attr("checked", "false");\r
- }\r
- \r
- $("#listTheme").bind('command', onCommandTheme);\r
- $("#checkListTheme").click(UseXimfmail);\r
- UseXimfmail();\r
- \r
- // determine if user wants XSMTP compatibility\r
- $("#xsmtpComptibilityBox").attr("checked", gXimfmailIdentity.getBoolAttribute("ximfmail_xsmtp_compatibility_on"));\r
- //$("#secureHeadersRuleBox").attr("checked", gXimfmailIdentity.getBoolAttribute("ximfmail_secure_header_on"));\r
- //$("#signMsgAlwaysRuleBox").attr("checked", gXimfmailIdentity.getBoolAttribute("ximfmail_sign_message_always_on"));\r
-\r
+// get pref settings\r
+function onPreInit(account, accountValues) {\r
+ XimfmailAccountPage.getInstance().setIdentity(account.defaultIdentity);\r
}\r
-\r
-/*\r
- * \r
- */ \r
-function UseXimfmail(){\r
- //IsDisableXimfmailManager("checkListTheme","isUsingXimfail");\r
- //alert("UseXimfmail " +idCheckElement+" "+idBroadcaster );\r
- if($("#checkListTheme").attr("checked") == "true"){\r
- $("#isUsingXimfail").attr("disabled","false"); \r
- return false; \r
- }else{\r
- $("#isUsingXimfail").attr("disabled","true");\r
- return true;\r
- }\r
+function onInit(aPageId, aServerId) {\r
+ XimfmailAccountPage.getInstance().init();\r
}\r
- \r
-/*\r
- * get pref settings\r
- */\r
-function onPreInit(account, accountValues){\r
- gXimfmailIdentity = account.defaultIdentity;\r
+// save all changes on this page\r
+function onSave() {\r
+ XimfmailAccountPage.getInstance().save();\r
}\r
-\r
-/*\r
- * save all changes on this page\r
+/**\r
+ * Ximfmail settings account page\r
*/\r
-function onSave(){\r
- if(gXimfmailIdentity == null)return;\r
- // save ximfmail selection to preferences\r
- SetXimfmailPref(gXimfmailIdentity.key, "ximfmail_theme_ref", $("#listTheme").attr("value"));\r
- SetXimfmailPref(gXimfmailIdentity.key, "ximfmail_theme_name", $("#listTheme").attr("label"));\r
- SetXimfmailPref(gXimfmailIdentity.key, "ximfmail_instance_compose_ref", $("#instanceComposeList").attr("value")); \r
- gXimfmailIdentity.setCharAttribute(XIMF_PREF_IDENTITY_TREETHREAD_REF,$("#instanceTreeThreadList").attr("value"));\r
- gXimfmailIdentity.setCharAttribute(XIMF_PREF_IDENTITY_MAIL_PANEL_REF,$("#instanceMailPanelList").attr("value"));\r
- \r
- if($("#checkListTheme").attr("checked") == "true"){ \r
- gXimfmailIdentity.setBoolAttribute(XIMF_PREF_IDENTITY_USE_XIMFMAIL,true);\r
- try{CreateSecurityLabelXml()}catch(e){}\r
- }else{ \r
- gXimfmailIdentity.setBoolAttribute(XIMF_PREF_IDENTITY_USE_XIMFMAIL,false);\r
+var XimfmailAccountPage = ( function () {\r
+ var instantiated = null;\r
+ var accountIdentity = null;\r
+ var log = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);\r
+ // enable/disable ximfmail settings\r
+ function toogle(){\r
+ if ($("#checkListTheme").attr("checked") === "true") {\r
+ $("#isUsingXimfail").attr("disabled", "false");\r
+ } else {\r
+ $("#isUsingXimfail").attr("disabled", "true");\r
+ }\r
+ }\r
+ /*\r
+ * init default menulist xul element with first menuitem\r
+ * idMenuList : id of menulist xul element\r
+ */\r
+ function initEntryMenu(idMenuList){\r
+ var itemlist = $("#"+ idMenuList +" > menupopup > menuitem");\r
+ $("#"+idMenuList).attr("value",$(itemlist[0]).attr("value"));\r
+ $("#"+idMenuList).attr("label",$(itemlist[0]).attr("label"));\r
+ }\r
+ /*\r
+ * display user pref value in menulist if exists\r
+ * manage RDF Catalog list in accountWizard, accountManager\r
+ * identity : user identity key\r
+ * idPref : user preference key\r
+ * idList : id of menulist xul element\r
+ */\r
+ function initEntryMenuWithPref(idPref,idList){\r
+ var pref = ximfPref.get(accountIdentity.key,idPref);\r
+ log.logStringMessage("[am-ximfmail - initEntryMenuWithPref] pref : " + pref);\r
+ if (pref) {\r
+ var entry = document.getElementById(idList);\r
+ if(!entry){\r
+ log.logStringMessage("[am-ximfmail - initEntryMenuWithPref] unloaded entry : " + entry);\r
+ return;\r
+ }\r
+ var themeList = entry.menupopup.childNodes;\r
+ for (var i=0; i<themeList.length; ++i) {\r
+ if(themeList[i].localName === "menuitem") {\r
+ var themeListval = themeList[i].value;\r
+ if( pref === themeListval){\r
+ entry.value = themeListval;\r
+ entry.label = themeList[i].label;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ }\r
}\r
- \r
- if($("#xsmtpComptibilityBox").attr("checked") == "true"){\r
- gXimfmailIdentity.setBoolAttribute("ximfmail_xsmtp_compatibility_on",true); \r
- }else{\r
- gXimfmailIdentity.setBoolAttribute("ximfmail_xsmtp_compatibility_on",false);\r
- } \r
-}
\ No newline at end of file
+ // load instances of selected theme\r
+ function loadTheme() {\r
+ var themeRef = $("#listTheme").attr("value");\r
+ AddRdfDataSce2domList("instanceCompose", themeRef);\r
+ initEntryMenu("instanceComposeList");\r
+ AddRdfDataSce2domList("instanceTreeThread", themeRef);\r
+ initEntryMenu("instanceTreeThreadList");\r
+ };\r
+ /**\r
+ * Listener on datasources of istance definitions menu\r
+ */\r
+ var treebuilderListener = {\r
+ item: null,\r
+ willRebuild : function(builder) {\r
+ },\r
+ didRebuild : function(builder) {\r
+ // determine if user uses ximfmail\r
+ $("#checkListTheme").attr("checked", "false");\r
+ if (ximfPref.getBool(accountIdentity.key, ximfConst.XIMF_PREF_IDENTITY_USE_XIMFMAIL)) {\r
+ $("#checkListTheme").attr("checked", "true");\r
+ }\r
+ initEntryMenuWithPref("ximfmail_theme_ref","listTheme");\r
+ loadTheme();\r
+ initEntryMenuWithPref("ximfmail_instance_compose_ref","instanceComposeList");\r
+ initEntryMenuWithPref(ximfConst.XIMF_PREF_IDENTITY_TREETHREAD_REF,"instanceTreeThreadList");\r
+ $("#listTheme").bind('command', loadTheme);\r
+ $("#checkListTheme").click(toogle);\r
+ toogle();\r
+ // determine if user wants XSMTP compatibility\r
+ $("#xsmtpComptibilityBox").attr("checked", ximfPref.getBool(accountIdentity.key, "ximfmail_xsmtp_compatibility_on").toString());\r
+ }\r
+ };\r
+ //\r
+ function instantiate() {\r
+ return {\r
+ setIdentity : function (aIdentity) {\r
+ accountIdentity = aIdentity;\r
+ },\r
+ init : function () {\r
+ try {\r
+ if (!accountIdentity) {\r
+ // no account id (local folder)\r
+ $("#checkListTheme").attr("checked", "false");\r
+ toogle();\r
+ $("#checkListTheme").attr("disabled", "true");\r
+ return;\r
+ }\r
+ $("#checkListTheme").removeAttr("disabled");\r
+ //load XIMF instances of profile for account\r
+ XimfCatalogFactory.getIntance(function(instance){\r
+ var listInstances = document.getElementById("listThemPopup");\r
+ listInstances.database.AddDataSource(instance.getDSCatalog());\r
+ listInstances.builder.addListener(treebuilderListener);\r
+ listInstances.builder.rebuild();\r
+ });\r
+ } catch (ex) {\r
+ log.logStringMessage("[am-ximfmail] Error on init settings for account " + accountIdentity.key + " : " + ex);\r
+ }\r
+ },\r
+ save : function () {\r
+ try {\r
+ if (!accountIdentity) {\r
+ return;\r
+ }\r
+ // save ximfmail selection to preferences\r
+ ximfPref.set(accountIdentity.key, "ximfmail_theme_ref", $("#listTheme").attr("value"));\r
+ ximfPref.set(accountIdentity.key, "ximfmail_theme_name", $("#listTheme").attr("label"));\r
+ ximfPref.set(accountIdentity.key, "ximfmail_instance_compose_ref", $("#instanceComposeList").attr("value"));\r
+ ximfPref.set(accountIdentity.key, ximfConst.XIMF_PREF_IDENTITY_TREETHREAD_REF,$("#instanceTreeThreadList").attr("value"));\r
+ if($("#checkListTheme").attr("checked") === "true"){\r
+ ximfPref.setBool(accountIdentity.key, ximfConst.XIMF_PREF_IDENTITY_USE_XIMFMAIL,true);\r
+ try{\r
+ CreateSecurityLabelXml();\r
+ }catch(e){}\r
+ }else{\r
+ ximfPref.setBool(accountIdentity.key, ximfConst.XIMF_PREF_IDENTITY_USE_XIMFMAIL,false);\r
+ }\r
+ if($("#xsmtpComptibilityBox").attr("checked") === "true"){\r
+ ximfPref.setBool(accountIdentity.key, "ximfmail_xsmtp_compatibility_on",true);\r
+ }else{\r
+ ximfPref.setBool(accountIdentity.key, "ximfmail_xsmtp_compatibility_on",false);\r
+ }\r
+ log.logStringMessage("[am-ximfmail] Save settings for account " + accountIdentity.key);\r
+ } catch (ex) {\r
+ log.logStringMessage("[am-ximfmail] Error on saving settings for account " + accountIdentity.key + " : " + ex);\r
+ }\r
+ }\r
+ };\r
+ };\r
+ //\r
+ return {\r
+ getInstance : function(){\r
+ if(!instantiated){\r
+ instantiated = instantiate();\r
+ }\r
+ return instantiated;\r
+ }\r
+ };\r
+})();
\ No newline at end of file
<!-- ***** BEGIN LICENSE BLOCK *****\r
- Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
- ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- - \r
-\r
- - Redistribution and use, in source and binary forms, with or without modification, \r
+ -\r
+ - Redistribution and use, in source and binary forms, with or without modification,\r
- are permitted provided that the following conditons are met :\r
-\r
- - 1. Redistributions of source code must retain the above copyright notice, \r
- - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ - 1. Redistributions of source code must retain the above copyright notice,\r
+ - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
- in the redistribution of the source code.\r
- - 3. Neither the names of the copyright holders nor the names of any contributors \r
- - may be used to endorse or promote products derived from this software without specific \r
+ - 3. Neither the names of the copyright holders nor the names of any contributors\r
+ - may be used to endorse or promote products derived from this software without specific\r
- prior written permission from EADS Defence and Security.\r
- - \r
+ -\r
- Alternatively, the contents of this file may be used under the terms of\r
- either of the GNU General Public License Version 2 or later (the "GPL"),\r
- or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
- and other provisions required by the GPL or the LGPL. If you do not delete\r
- the provisions above, a recipient may use your version of this file under\r
- the terms of any one of the MPL, the GPL or the LGPL.\r
- - \r
+ -\r
- REMINDER :\r
- - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
- IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- - \r
- - EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ -\r
+ - EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ - \r
+ - Contributor(s):\r
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved \r
- ***** END LICENSE BLOCK ***** -->\r
\r
<?xml-stylesheet href="chrome://messenger/skin/accountManage.css" type="text/css"?>\r
class="color-dialog" onload="parent.onPanelLoaded('am-ximfmail.xul');"\r
orient="vertical">\r
\r
+ <script type="application/javascript" src="chrome://messenger/content/AccountManager.js"/>\r
<script type="application/javascript" src="chrome://ximfmail/content/jquery.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/constant-ximfmail.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/ximfCatalog.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/controler-ximfmail.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/ximfmail.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/am-ximfmail.js" />\r
- \r
+\r
<broadcasterset>\r
<broadcaster id="isUsingXimfail" disabled="true"/>\r
</broadcasterset>\r
<checkbox id="checkListTheme" label="&ximfmail.am.themeChoice;" />\r
<menulist id="listTheme" observes="isUsingXimfail" flex="1">\r
<menupopup\r
- datasources="rdf:null" \r
+ datasources="rdf:null"\r
ref="http://www.ximfmail.com/catalog"\r
id="listThemPopup">\r
<template>\r
</rule>\r
</template>\r
</menupopup>\r
- </menulist> \r
+ </menulist>\r
</hbox>\r
<groupbox flex="1">\r
<caption>\r
object="?ximfVersion" />\r
<triple subject="?elt"\r
predicate="http://www.ximfmail.com/RDF#instance"\r
- object="?name" /> \r
+ object="?name" />\r
<triple subject="?elt"\r
predicate="http://www.ximfmail.com/RDF#instanceLabel"\r
- object="?label" /> \r
+ object="?label" />\r
<triple subject="?elt"\r
predicate="http://www.ximfmail.com/RDF#active"\r
- object="true" /> \r
+ object="true" />\r
</conditions>\r
<action>\r
- <menuitem uri="?elt" value="?elt" label="?label"/> \r
+ <menuitem uri="?elt" value="?elt" label="?label"/>\r
</action>\r
</rule>\r
</template>\r
</menupopup>\r
</menulist>\r
- </row> \r
+ </row>\r
<row>\r
<label value="&ximfmail.am.instanceTreeThreadChoice;" />\r
<menulist id="instanceTreeThreadList" observes="isUsingXimfail" flex="1">\r
- <menupopup \r
+ <menupopup\r
id="instanceTreeThread"\r
datasources="rdf:null"\r
ref=""\r
template="tplInstanceMenu" />\r
</menulist>\r
</row>\r
- <row>\r
- <label value="&ximfmail.am.instanceMailPanelChoice;" />\r
- <menulist id="instanceMailPanelList" observes="isUsingXimfail" flex="1">\r
- <menupopup \r
- id="instanceMailPanel"\r
- datasources="rdf:null"\r
- ref=""\r
- template="tplInstanceMenu" />\r
- </menulist>\r
- </row>\r
</rows>\r
</grid>\r
- <!-- \r
+ <!--\r
<checkbox id="ximfAdvancedReceivedMsg" label="afficher les entetes" observes="isUsingXimfail" />\r
-->\r
<checkbox id="xsmtpComptibilityBox" label="&ximfmail.am.xsmtpCompatibilityCheck;" observes="isUsingXimfail" />\r
- <!-- \r
+ <!--\r
<checkbox id="secureHeadersRuleBox" label="&ximfmail.am.secureHeadersRuleCheck;" observes="isUsingXimfail" />\r
<checkbox id="signMsgAlwaysRuleBox" label="&ximfmail.am.signMsgAlwaysRuleCheck;" observes="isUsingXimfail" />\r
- --> \r
+ -->\r
</groupbox>\r
- \r
+\r
</vbox>\r
</page>
\ No newline at end of file
/* ***** BEGIN LICENSE BLOCK *****\r
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
*\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
* are permitted provided that the following conditons are met :\r
*\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
* in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
* prior written permission from EADS Defence and Security.\r
- * \r
+ *\r
* Alternatively, the contents of this file may be used under the terms of\r
* either of the GNU General Public License Version 2 or later (the "GPL"),\r
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
* and other provisions required by the GPL or the LGPL. If you do not delete\r
* the provisions above, a recipient may use your version of this file under\r
* the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
+ *\r
* REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
* ***** END LICENSE BLOCK ***** */\r
var gJSLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].createInstance(Components.interfaces.mozIJSSubScriptLoader);\r
var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);\r
gJSLoader.loadSubScript("chrome://ximfmail/content/jquery.js");\r
gJSLoader.loadSubScript("chrome://ximfmail/content/ximfmail.js");\r
\r
-var _XIMF_ATT_XVALUE = "ximfvalue";\r
- \r
var gDlgTreeXimf_maxItem = null;\r
var gDlgTreeXimf_current_selection = null;\r
var gDlgTreeXimf_current_separator = null;\r
var gXmlDatasFilePath = null;\r
var gRdfTempo = null;\r
-\r
-\r
var gSelectedDate = null;\r
var gSelectedDayItem = null;\r
-var gSelectedMonthItem = null; // dom month\r
+var gSelectedMonthItem = null;\r
var gSelectedHourItem = null;\r
var gSelectedMinItem = null;\r
var gTitleDlg = null;\r
/*\r
window.arguments = [];\r
args[0] id de la textbox à enrichir\r
- args[1] date courant affichee \r
+ args[1] date courant affichee\r
*/\r
-var gBoxOpener = null; // display date\r
+// gBoxOpener : display date\r
+var gBoxOpener = null;\r
$(document).ready(function(){\r
- \r
var gArgs = window.arguments;\r
- if(gArgs[0].length <= 0) return;\r
+ if (gArgs[0].length <= 0) {\r
+ return;\r
+ }\r
// load background datas\r
gBoxOpener = gArgs[0][0];\r
gTitleDlg = gArgs[0][2];\r
- \r
if(gBoxOpener){\r
gSelectedDate = parseDate(gArgs[0][1]);\r
}else{\r
- adjustCurrentDate(); \r
- } \r
- \r
+ adjustCurrentDate();\r
+ }\r
UpdateCalendar();\r
- \r
-}); \r
-\r
+});\r
/*\r
- * \r
+ *\r
*/\r
-function clickOk(){ \r
- \r
- var date = ConvertDateForDisplay(); \r
- window.opener.document.getElementById(gBoxOpener).value = date; \r
- window.opener.document.getElementById(gBoxOpener).setAttribute(_XIMF_ATT_XVALUE, gSelectedDate.toGMTString()); \r
+function clickOk(){\r
+ var date = ConvertDateForDisplay();\r
+ window.opener.document.getElementById(gBoxOpener).value = date;\r
+ window.opener.document.getElementById(gBoxOpener).setAttribute("ximfvalue", gSelectedDate.toGMTString());\r
window.close();\r
return true;\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
function clickCancel(){\r
window.close();\r
- return false; \r
+ return false;\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
function adjustCurrentDate(){\r
gSelectedDate = new Date();\r
- \r
- // minutes %5 \r
- gSelectedDate.setMinutes(parseInt(Math.round(gSelectedDate.getMinutes()/5)*5, 10)); \r
- UpdateCalendar(); \r
+ // minutes %5\r
+ gSelectedDate.setMinutes(parseInt(Math.round(gSelectedDate.getMinutes()/5)*5, 10));\r
+ UpdateCalendar();\r
}\r
-\r
function ConvertDateForDisplay(){\r
var displayDate = null;\r
var date = new Date();\r
- if( gSelectedDate ){ date = gSelectedDate;}\r
- try{ \r
- //displayDate = date.getDate() + "/" + (date.getMonth()+1) + "/" + date.getFullYear() + " " + date.getHours() + ":" + date.getMinutes();\r
+ if ( gSelectedDate ) {\r
+ date = gSelectedDate;\r
+ }\r
+ try{\r
// day\r
if(date.getDate()>=10){\r
displayDate = date.getDate();\r
}else{\r
displayDate = "0"+date.getDate();\r
}\r
- \r
//month\r
if((date.getMonth()+1)>=10){\r
displayDate += "/" + (date.getMonth()+1);\r
}else{\r
displayDate += "/0" + (date.getMonth()+1);\r
}\r
- \r
//year\r
displayDate += "/" + date.getFullYear() + " ";\r
- \r
// hour\r
if(date.getHours()>=10){\r
displayDate += "" + date.getHours();\r
}else{\r
displayDate += "0" + date.getHours();\r
}\r
- \r
//minutes\r
displayDate += ":";\r
if(date.getMinutes()>=10){\r
displayDate += date.getMinutes();\r
}else{\r
displayDate += "0" + date.getMinutes();\r
- } \r
+ }\r
}catch( e ){\r
- \r
}\r
return displayDate;\r
}\r
- \r
-\r
function UpdateCalendar(){\r
- try{ \r
+ try{\r
// Set up the picker, called when the popup pops\r
- // get the start date from the popup value attribute and select it \r
- var startDate = gSelectedDate; \r
- \r
- if(startDate){ \r
+ // get the start date from the popup value attribute and select it\r
+ var startDate = gSelectedDate;\r
+ if(startDate){\r
gOriginalDate = new Date( startDate );\r
gSelectedDate = new Date( startDate );\r
}else{\r
gOriginalDate = new Date();\r
gSelectedDate = new Date();\r
- gSelectedDate.setMinutes(Math.round((gSelectedDate.getMinutes()/5))*5); \r
- gOriginalDate.setMinutes(Math.round((gOriginalDate.getMinutes()/5))*5); \r
+ gSelectedDate.setMinutes(Math.round((gSelectedDate.getMinutes()/5))*5);\r
+ gOriginalDate.setMinutes(Math.round((gOriginalDate.getMinutes()/5))*5);\r
}\r
- \r
// draw the year based on the selected date\r
redrawYear();\r
- \r
// draw the month based on the selected date\r
var month = gSelectedDate.getMonth() + 1;\r
var selectedMonthBoxItem = document.getElementById("oe-date-picker-year-month-" + month + "-box" );\r
selectMonthItem( selectedMonthBoxItem );\r
- \r
// draw in the days for the selected date\r
redrawDays();\r
- \r
//EADS - draw in hours and minutes for selected date\r
var hour = gSelectedDate.getHours();\r
var selectedHoursBoxItem = document.getElementById("ximfmail-date-picker-hour-box-" + hour );\r
selectHoursItem(selectedHoursBoxItem);\r
- \r
var min = gSelectedDate.getMinutes();\r
var selectedMinutesBoxItem = null;\r
- if(min%5 != 0)\r
+ if(min%5 !== 0){\r
selectedMinutesBoxItem = document.getElementById("ximfmail-date-picker-min-box-" + (Math.round(min/5)*5) );\r
- else\r
+ }else{\r
selectedMinutesBoxItem = document.getElementById("ximfmail-date-picker-min-box-" + min );\r
- selectMinutesItem(selectedMinutesBoxItem); \r
- \r
- //title calendar\r
+ }\r
+ selectMinutesItem(selectedMinutesBoxItem);\r
+ // title calendar\r
$("#ximf-date-picker-title").attr("value", gTitleDlg.substring(0,gTitleDlg.lastIndexOf(":")));\r
}catch(e){}\r
}\r
-\r
function clickDay(newDayItem, newDayItemNumber){\r
// Called when a day is clicked, close the picker and call the client's oncommand\r
// get the clicked day\r
- if( gSelectedDayItem == newDayItem )\r
+ if( gSelectedDayItem === newDayItem ) {\r
return;\r
- \r
+ }\r
// update new selection\r
newDayItem.setAttribute("selected",true);\r
if(gSelectedDayItem){\r
gSelectedDayItem.removeAttribute("selected");\r
}\r
gSelectedDayItem = newDayItem;\r
- \r
var dayNumberItem = document.getElementById("oe-date-picker-month-day-text-" + newDayItemNumber );\r
var dayNumber = dayNumberItem.getAttribute( "value" );\r
// they may have clicked an unfilled day, if so ignore it and leave the picker up\r
- if( dayNumber != "" ){ \r
+ if( dayNumber !== "" ){\r
selectDayItem(newDayItem);\r
// set the selected date to what they cliked on\r
gSelectedDate.setDate( dayNumber );\r
}\r
}\r
-\r
-\r
/*\r
- * \r
+ *\r
*/\r
function clickMonth(newMonthItem, newMonthNumber){\r
- // Called when a month box is clicked \r
- // already selected, return \r
- if( gSelectedMonthItem == newMonthItem )\r
+ // Called when a month box is clicked\r
+ // already selected, return\r
+ if( gSelectedMonthItem === newMonthItem ) {\r
return;\r
- \r
+ }\r
// update new selection\r
newMonthItem.setAttribute("selected",true);\r
if(gSelectedMonthItem){\r
gSelectedMonthItem.removeAttribute("selected");\r
}\r
gSelectedMonthItem = newMonthItem;\r
- \r
- \r
// Avoid problems when changing months if the date is at the end of the month\r
// i.e. if date is 31 march and you do a setmonth to april, the month would\r
// actually be set to may, beacause april only has 30 days.\r
// This is why we keep the original date around.\r
var oldDate = gSelectedDate.getDate();\r
var yearNumber = gSelectedDate.getFullYear();\r
-\r
var pastLastDate = new Date( yearNumber, newMonthNumber-1, 32 );\r
- var lastDayOfMonth = 32 - pastLastDate.getDate(); \r
-\r
+ var lastDayOfMonth = 32 - pastLastDate.getDate();\r
if( oldDate > lastDayOfMonth ){\r
gSelectedDate.setDate(lastDayOfMonth);\r
}\r
-\r
// update the selected date\r
gSelectedDate.setMonth( newMonthNumber - 1 );\r
-\r
// select Month\r
selectMonthItem( newMonthItem );\r
-\r
// redraw days\r
redrawDays();\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
function previousYearCommand(increment){\r
- // Called when previous Year button is clicked \r
- // update the selected date\r
-\r
- var oldYear = gSelectedDate.getFullYear(); \r
- gSelectedDate.setFullYear( oldYear - increment ); \r
-\r
- // redraw the year and the days\r
- redrawYear();\r
- redrawDays();\r
+ // Called when previous Year button is clicked\r
+ // update the selected date\r
+ var oldYear = gSelectedDate.getFullYear();\r
+ gSelectedDate.setFullYear( oldYear - increment );\r
+ // redraw the year and the days\r
+ redrawYear();\r
+ redrawDays();\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
function nextYearCommand(increment){\r
- // Called when next Year button is clicked \r
- // update the selected date\r
-\r
- var oldYear = gSelectedDate.getFullYear(); \r
- gSelectedDate.setFullYear( oldYear + increment ); \r
-\r
- // redraw the year and the days\r
- redrawYear();\r
- redrawDays();\r
+ // Called when next Year button is clicked\r
+ // update the selected date\r
+ var oldYear = gSelectedDate.getFullYear();\r
+ gSelectedDate.setFullYear( oldYear + increment );\r
+ // redraw the year and the days\r
+ redrawYear();\r
+ redrawDays();\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
function redrawYear(){\r
var yearTitleItem = document.getElementById("oe-date-picker-year-title-text");\r
yearTitleItem.setAttribute( "value", gSelectedDate.getFullYear() );\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
function selectMonthItem(newMonthItem){\r
- // Select a month box \r
+ // Select a month box\r
// clear old selection, if there is one\r
- if( gSelectedMonthItem != null ){\r
+ if( gSelectedMonthItem !== null ){\r
gSelectedMonthItem.removeAttribute("selected");\r
}\r
-\r
// Set the selected attribute, used to give it a different style\r
newMonthItem.setAttribute( "selected" , true );\r
-\r
// Remember new selection\r
gSelectedMonthItem = newMonthItem;\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
function selectDayItem(newDayItem){\r
- // Select a day box \r
+ // Select a day box\r
// clear old selection, if there is one\r
-\r
- if( gSelectedDayItem != null ){\r
+ if( gSelectedDayItem !== null ){\r
gSelectedDayItem.removeAttribute("selected");\r
}\r
-\r
- if( newDayItem != null ){\r
+ if( newDayItem !== null ){\r
// Set the selected attribute, used to give it a different style\r
newDayItem.setAttribute( "selected" , true );\r
}\r
- \r
// Remember new selection\r
gSelectedDayItem = newDayItem;\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
function redrawDays(){\r
// Redraw day numbers based on the selected date\r
- // Write in all the day numbers \r
+ // Write in all the day numbers\r
var firstDate = new Date( gSelectedDate.getFullYear(), gSelectedDate.getMonth(), 1 );\r
var firstDayOfWeek = firstDate.getDay();\r
- \r
- //get last Day Of Month \r
+ //get last Day Of Month\r
var pastLastDate = new Date( gSelectedDate.getFullYear(), gSelectedDate.getMonth(), 32 );\r
- var lastDayOfMonth = 32 - pastLastDate.getDate(); \r
- \r
- // clear the selected day item \r
+ var lastDayOfMonth = 32 - pastLastDate.getDate();\r
+ // clear the selected day item\r
selectDayItem( null );\r
- \r
// redraw each day bax in the 7 x 6 grid\r
var dayNumber = 1;\r
for( var dayIndex = 0; dayIndex < 42; ++dayIndex ){\r
// get the day text box\r
var dayNumberItem = document.getElementById("oe-date-picker-month-day-text-" + (dayIndex + 1) );\r
- \r
// if it is an unfilled day ( before first or after last ), just set its value to "",\r
// and don't increment the day number.\r
if( dayIndex < firstDayOfWeek || dayNumber > lastDayOfMonth )\r
{\r
- dayNumberItem.setAttribute( "value" , "" ); \r
+ dayNumberItem.setAttribute( "value" , "" );\r
}else{\r
// set the value to the day number\r
dayNumberItem.setAttribute( "value" , dayNumber );\r
- \r
// draw the day as selected\r
- if( dayNumber == gSelectedDate.getDate() ){\r
+ if( dayNumber === gSelectedDate.getDate() ){\r
var dayNumberBoxItem = document.getElementById( "oe-date-picker-month-day-" + (dayIndex + 1) + "-box" );\r
selectDayItem( dayNumberBoxItem );\r
}\r
- \r
// advance the day number\r
- ++dayNumber; \r
+ ++dayNumber;\r
}\r
}\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
function parseDate(datestr){\r
- //var datestr = _input.value; \r
try{\r
- if( datestr != "" ){\r
+ if( datestr !== "" ){\r
var reg=new RegExp("[ / :]+", "g"); //eads\r
- var parts = datestr.split(reg); \r
- if( parts.length >= 5 ){ \r
- //var d = new Date(month, day, year, hour, minutes, seconds);\r
- //return new Date(parseInt(parts[1]-1),parseInt(parts[0]),parseInt(parts[2]),parseInt(parts[3]),parseInt(parts[4]),0);\r
- //alert("SPLIT DATE\nmonth : "+parts[1] + "\n day : " + parts[0] +"\n year : "+ parts[2] +"\n hour : "+ parts[3] +"\n min : "+ parts[4]);\r
+ var parts = datestr.split(reg);\r
+ if( parts.length >= 5 ){\r
var new_date = new Date();\r
new_date.setDate(parseInt(parts[0], 10));\r
new_date.setMonth(parseInt(parts[1]-1, 10));\r
new_date.setHours(parseInt(parts[3], 10));\r
new_date.setMinutes(parseInt(parts[4], 10));\r
new_date.setSeconds(0);\r
- return new_date; \r
+ return new_date;\r
}\r
}\r
}catch(e){}\r
return null;\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
function clickHour(newHoursItem,newHourItemNumber){\r
- if( gSelectedHourItem == newHoursItem ) return;\r
- selectHoursItem(newHoursItem);\r
- /*\r
- // update new selection\r
- newHoursItem.setAttribute("selected",true);\r
- if(gSelectedHourItem){\r
- gSelectedHourItem.removeAttribute("selected");\r
+ if( gSelectedHourItem === newHoursItem ) {\r
+ return;\r
}\r
- gSelectedHourItem = newHoursItem;\r
- */\r
- \r
- gSelectedDate.setHours(parseInt(newHourItemNumber, 10)); \r
+ selectHoursItem(newHoursItem);\r
+ gSelectedDate.setHours(parseInt(newHourItemNumber, 10));\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
function selectHoursItem(newHoursItem){\r
- // Select a month box \r
+ // Select a month box\r
// clear old selection, if there is one\r
- if( gSelectedHourItem != null ){\r
+ if( gSelectedHourItem !== null ){\r
gSelectedHourItem.removeAttribute( "selected" );\r
}\r
-\r
// Set the selected attribute, used to give it a different style\r
newHoursItem.setAttribute( "selected" , true );\r
-\r
// Remember new selection\r
gSelectedHourItem = newHoursItem;\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
-function clickMin(newMinItem,newMinItemNumber){ \r
- if( gSelectedMinItem == newMinItem ) return;\r
+function clickMin(newMinItem,newMinItemNumber){\r
+ if ( gSelectedMinItem === newMinItem ) {\r
+ return;\r
+ }\r
// update new selection\r
selectMinutesItem(newMinItem);\r
- /*newMinItem.setAttribute("selected",true);\r
- \r
- if(gSelectedMinItem){\r
- gSelectedMinItem.removeAttribute("selected");\r
- }\r
- gSelectedMinItem = newMinItem;\r
- */\r
gSelectedDate.setMinutes(parseInt(newMinItemNumber, 10));\r
- \r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
function selectMinutesItem(newMinutesItem){\r
- // Select a month box \r
+ // Select a month box\r
// clear old selection, if there is one\r
- if( gSelectedMinItem != null ){\r
+ if( gSelectedMinItem !== null ){\r
gSelectedMinItem.removeAttribute( "selected" );\r
}\r
-\r
// Set the selected attribute, used to give it a different style\r
newMinutesItem.setAttribute( "selected" , true );\r
-\r
// Remember new selection\r
gSelectedMinItem = newMinutesItem;\r
-}
\ No newline at end of file
+}
\ No newline at end of file
<!-- ***** BEGIN LICENSE BLOCK *****\r
- Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
- ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- - \r
-\r
- - Redistribution and use, in source and binary forms, with or without modification, \r
+ -\r
+ - Redistribution and use, in source and binary forms, with or without modification,\r
- are permitted provided that the following conditons are met :\r
-\r
- - 1. Redistributions of source code must retain the above copyright notice, \r
- - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ - 1. Redistributions of source code must retain the above copyright notice,\r
+ - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
- in the redistribution of the source code.\r
- - 3. Neither the names of the copyright holders nor the names of any contributors \r
- - may be used to endorse or promote products derived from this software without specific \r
+ - 3. Neither the names of the copyright holders nor the names of any contributors\r
+ - may be used to endorse or promote products derived from this software without specific\r
- prior written permission from EADS Defence and Security.\r
- - \r
+ -\r
- Alternatively, the contents of this file may be used under the terms of\r
- either of the GNU General Public License Version 2 or later (the "GPL"),\r
- or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
- and other provisions required by the GPL or the LGPL. If you do not delete\r
- the provisions above, a recipient may use your version of this file under\r
- the terms of any one of the MPL, the GPL or the LGPL.\r
- - \r
+ -\r
- REMINDER :\r
- - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
- IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- - \r
- - EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ -\r
+ - EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ - \r
+ - Contributor(s):\r
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
- ***** END LICENSE BLOCK ***** -->\r
\r
<?xml-stylesheet href="chrome://ximfmail/content/calendar/calendar.css" type="text/css"?>\r
<!DOCTYPE overlay SYSTEM "chrome://ximfmail/locale/datepicker.dtd">\r
\r
-<window id="datetimepicker_dialog" \r
+<window id="datetimepicker_dialog"\r
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" >\r
- \r
+\r
<script type="application/javascript" src="chrome://ximfmail/content/calendar/dialogCalendar-ximfmail.js" />\r
- \r
- \r
- <vbox id="oe-date-picker-overlay-box" > \r
+\r
+\r
+ <vbox id="oe-date-picker-overlay-box" >\r
<hbox id="ximf-date-picker-head-controls-box">\r
- <box> \r
+ <box>\r
<label id="ximf-date-picker-title" />\r
- </box> \r
+ </box>\r
<box flex="1"/>\r
- <box> \r
+ <box>\r
<image id="ximf-date-picker-cancel-control-box" onclick="clickCancel()"/>\r
</box>\r
</hbox>\r
<hbox id="oe-date-picker-year-controls-box" >\r
<box flex="1">\r
- <image id="oe-date-picker-year-previous-jump-button" onclick="previousYearCommand(10)"/> \r
- <image id="oe-date-picker-year-previous-button" onclick="previousYearCommand(1)"/> \r
+ <image id="oe-date-picker-year-previous-jump-button" onclick="previousYearCommand(10)"/>\r
+ <image id="oe-date-picker-year-previous-button" onclick="previousYearCommand(1)"/>\r
</box>\r
- <label id="oe-date-picker-year-title-text" value="" /> \r
+ <label id="oe-date-picker-year-title-text" value="" />\r
<box flex="1" id="oe-date-picker-year-next-button-box" >\r
<image id="oe-date-picker-year-next-button" onclick="nextYearCommand(1)"/>\r
<image id="oe-date-picker-year-next-jump-button" onclick="nextYearCommand(10)"/>\r
- </box> \r
- </hbox> \r
+ </box>\r
+ </hbox>\r
<grid id="oe-date-picker-year-grid" flex="1">\r
<columns>\r
<column class="oe-date-picker-year-column-class" flex="1"/>\r
<row flex="1">\r
<vbox class="oe-date-picker-year-month-box-class" id="oe-date-picker-year-month-1-box" onclick="clickMonth(this, 1)" >\r
<spacer flex="1" />\r
- <box ><label class="oe-date-picker-year-month-name-class" value="&month.1.MMM;" /></box> \r
+ <box ><label class="oe-date-picker-year-month-name-class" value="&month.1.MMM;" /></box>\r
<spacer flex="1" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-year-month-box-class" id="oe-date-picker-year-month-2-box" onclick="clickMonth(this, 2)" >\r
<spacer flex="1" />\r
- <box><label class="oe-date-picker-year-month-name-class" value="&month.2.MMM;" /></box> \r
+ <box><label class="oe-date-picker-year-month-name-class" value="&month.2.MMM;" /></box>\r
<spacer flex="1" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-year-month-box-class" id="oe-date-picker-year-month-3-box" onclick="clickMonth(this, 3)" >\r
<spacer flex="1" />\r
- <box><label class="oe-date-picker-year-month-name-class" value="&month.3.MMM;" /></box> \r
+ <box><label class="oe-date-picker-year-month-name-class" value="&month.3.MMM;" /></box>\r
<spacer flex="1" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-year-month-box-class" id="oe-date-picker-year-month-4-box" onclick="clickMonth(this, 4)" >\r
<spacer flex="1" />\r
- <box><label class="oe-date-picker-year-month-name-class" value="&month.4.MMM;" /></box> \r
+ <box><label class="oe-date-picker-year-month-name-class" value="&month.4.MMM;" /></box>\r
<spacer flex="1" />\r
- </vbox> \r
- </row> \r
+ </vbox>\r
+ </row>\r
<row flex="1">\r
<vbox class="oe-date-picker-year-month-box-class" id="oe-date-picker-year-month-5-box" onclick="clickMonth(this, 5)" >\r
<spacer flex="1" />\r
- <box><label class="oe-date-picker-year-month-name-class" value="&month.5.MMM;" /></box> \r
+ <box><label class="oe-date-picker-year-month-name-class" value="&month.5.MMM;" /></box>\r
<spacer flex="1" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-year-month-box-class" id="oe-date-picker-year-month-6-box" onclick="clickMonth(this, 6)" >\r
<spacer flex="1" />\r
- <box><label class="oe-date-picker-year-month-name-class" value="&month.6.MMM;" /></box> \r
+ <box><label class="oe-date-picker-year-month-name-class" value="&month.6.MMM;" /></box>\r
<spacer flex="1" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-year-month-box-class" id="oe-date-picker-year-month-7-box" onclick="clickMonth(this, 7)" >\r
<spacer flex="1" />\r
- <box><label class="oe-date-picker-year-month-name-class" value="&month.7.MMM;" /></box> \r
+ <box><label class="oe-date-picker-year-month-name-class" value="&month.7.MMM;" /></box>\r
<spacer flex="1" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-year-month-box-class" id="oe-date-picker-year-month-8-box" onclick="clickMonth(this, 8)" >\r
<spacer flex="1" />\r
- <box><label class="oe-date-picker-year-month-name-class" value="&month.8.MMM;" /></box> \r
+ <box><label class="oe-date-picker-year-month-name-class" value="&month.8.MMM;" /></box>\r
<spacer flex="1" />\r
- </vbox> \r
- </row> \r
+ </vbox>\r
+ </row>\r
<row flex="1" >\r
<vbox class="oe-date-picker-year-month-box-class" id="oe-date-picker-year-month-9-box" onclick="clickMonth(this, 9)" >\r
<spacer flex="1" />\r
- <box><label class="oe-date-picker-year-month-name-class" value="&month.9.MMM;" /></box> \r
+ <box><label class="oe-date-picker-year-month-name-class" value="&month.9.MMM;" /></box>\r
<spacer flex="1" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-year-month-box-class" id="oe-date-picker-year-month-10-box" onclick="clickMonth(this, 10)" >\r
<spacer flex="1" />\r
- <box><label class="oe-date-picker-year-month-name-class" value="&month.10.MMM;" /></box> \r
+ <box><label class="oe-date-picker-year-month-name-class" value="&month.10.MMM;" /></box>\r
<spacer flex="1" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-year-month-box-class" id="oe-date-picker-year-month-11-box" onclick="clickMonth(this, 11)" >\r
<spacer flex="1" />\r
- <box><label class="oe-date-picker-year-month-name-class" value="&month.11.MMM;" /></box> \r
+ <box><label class="oe-date-picker-year-month-name-class" value="&month.11.MMM;" /></box>\r
<spacer flex="1" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-year-month-box-class" id="oe-date-picker-year-month-12-box" onclick="clickMonth(this, 12)" >\r
<spacer flex="1" />\r
- <box><label class="oe-date-picker-year-month-name-class" value="&month.12.MMM;" /></box> \r
+ <box><label class="oe-date-picker-year-month-name-class" value="&month.12.MMM;" /></box>\r
<spacer flex="1" />\r
- </vbox> \r
- </row> \r
+ </vbox>\r
+ </row>\r
</rows>\r
</grid>\r
<box id="oe-date-picker-month-grid-box" flex="1">\r
<row id="oe-date-picker-month-days-header-box">\r
<vbox class="oe-date-picker-month-days-header-class-red" id="oe-date-picker-month-day-1-header-box">\r
<label class="oe-date-picker-month-days-header-class" value="&day.1.DDD;" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-days-box-header-class" id="oe-date-picker-month-day-2-header-box">\r
<label class="oe-date-picker-month-days-header-class" value="&day.2.DDD;" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-days-box-header-class" id="oe-date-picker-month-day-3-header-box">\r
<label class="oe-date-picker-month-days-header-class" value="&day.3.DDD;" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-days-box-header-class" id="oe-date-picker-month-day-4-header-box">\r
<label class="oe-date-picker-month-days-header-class" value="&day.4.DDD;" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-days-box-header-class" id="oe-date-picker-month-day-5-header-box">\r
<label class="oe-date-picker-month-days-header-class" value="&day.5.DDD;" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-days-box-header-class" id="oe-date-picker-month-day-6-header-box">\r
<label class="oe-date-picker-month-days-header-class" value="&day.6.DDD;" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-days-box-header-class" id="oe-date-picker-month-day-7-header-box">\r
<label class="oe-date-picker-month-days-header-class" value="&day.7.DDD;" />\r
- </vbox> \r
+ </vbox>\r
</row>\r
<row>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-1-box" onclick="clickDay(this,1)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-1" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-2-box" onclick="clickDay(this,2)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-2" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-3-box" onclick="clickDay(this,3)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-3" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-4-box" onclick="clickDay(this,4)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-4" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-5-box" onclick="clickDay(this,5)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-5" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-6-box" onclick="clickDay(this,6)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-6" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-7-box" onclick="clickDay(this,7)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-7" value="" />\r
- </vbox> \r
+ </vbox>\r
</row>\r
<row>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-8-box" onclick="clickDay(this,8)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-8" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-9-box" onclick="clickDay(this,9)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-9" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-10-box" onclick="clickDay(this,10)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-10" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-11-box" onclick="clickDay(this,11)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-11" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-12-box" onclick="clickDay(this,12)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-12" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-13-box" onclick="clickDay(this,13)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-13" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-14-box" onclick="clickDay(this,14)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-14" value="" />\r
- </vbox> \r
+ </vbox>\r
</row>\r
<row>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-15-box" onclick="clickDay(this,15)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-15" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-16-box" onclick="clickDay(this,16)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-16" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-17-box" onclick="clickDay(this,17)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-17" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-18-box" onclick="clickDay(this,18)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-18" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-19-box" onclick="clickDay(this,19)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-19" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-20-box" onclick="clickDay(this,20)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-20" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-21-box" onclick="clickDay(this,21)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-21" value="" />\r
- </vbox> \r
- </row> \r
+ </vbox>\r
+ </row>\r
<row>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-22-box" onclick="clickDay(this,22)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-22" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-23-box" onclick="clickDay(this,23)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-23" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-24-box" onclick="clickDay(this,24)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-24" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-25-box" onclick="clickDay(this,25)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-25" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-26-box" onclick="clickDay(this,26)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-26" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-27-box" onclick="clickDay(this,27)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-27" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-28-box" onclick="clickDay(this,28)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-28" value="" />\r
- </vbox> \r
- </row> \r
+ </vbox>\r
+ </row>\r
<row>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-29-box" onclick="clickDay(this,29)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-29" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-30-box" onclick="clickDay(this,30)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-30" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-31-box" onclick="clickDay(this,31)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-31" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-32-box" onclick="clickDay(this,32)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-32" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-33-box" onclick="clickDay(this,33)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-33" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-34-box" onclick="clickDay(this,34)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-34" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-35-box" onclick="clickDay(this,35)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-35" value="" />\r
- </vbox> \r
- </row> \r
+ </vbox>\r
+ </row>\r
<row>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-36-box" onclick="clickDay(this,36)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-36" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-37-box" onclick="clickDay(this,37)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-37" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-38-box" onclick="clickDay(this,38)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-38" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-39-box" onclick="clickDay(this,39)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-39" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-40-box" onclick="clickDay(this,40)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-40" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-41-box" onclick="clickDay(this,41)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-41" value="" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="oe-date-picker-month-day-42-box" onclick="clickDay(this,42)">\r
<label class="oe-date-picker-month-day-number-class" id="oe-date-picker-month-day-text-42" value="" />\r
- </vbox> \r
- </row> \r
+ </vbox>\r
+ </row>\r
</rows>\r
</grid>\r
</box>\r
<row flex="1" id="ximfmail-date-picker-hour-12-header-box">\r
<vbox class="oe-date-picker-year-month-box-class" id="ximfmail-date-picker-hour-box-0" onclick="clickHour(this,0)">\r
<label class="oe-date-picker-month-day-number-class" id="ximfmail-date-picker-hour-text-0" value=" 00 " />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-year-month-box-class" id="ximfmail-date-picker-hour-box-1" onclick="clickHour(this,1)">\r
<label class="oe-date-picker-month-day-number-class" id="ximfmail-date-picker-hour-text-1" value=" 01 " />\r
</vbox>\r
</vbox>\r
<vbox class="oe-date-picker-year-month-box-class" id="ximfmail-date-picker-hour-box-11" onclick="clickHour(this,11)">\r
<label class="oe-date-picker-month-day-number-class" id="ximfmail-date-picker-hour-text-11" value=" 11 " />\r
- </vbox> \r
+ </vbox>\r
</row>\r
- <row flex="1" id="ximfmail-date-picker-hour-24-header-box"> \r
+ <row flex="1" id="ximfmail-date-picker-hour-24-header-box">\r
<vbox class="oe-date-picker-year-month-box-class" id="ximfmail-date-picker-hour-box-12" onclick="clickHour(this,12)">\r
<label class="oe-date-picker-month-day-number-class" id="ximfmail-date-picker-hour-text-12" value=" 12 " />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-year-month-box-class" id="ximfmail-date-picker-hour-box-13" onclick="clickHour(this,13)">\r
<label class="oe-date-picker-month-day-number-class" id="ximfmail-date-picker-hour-text-13" value=" 13 " />\r
</vbox>\r
</vbox>\r
<vbox class="oe-date-picker-year-month-box-class" id="ximfmail-date-picker-hour-box-23" onclick="clickHour(this,23)">\r
<label class="oe-date-picker-month-day-number-class" id="ximfmail-date-picker-hour-text-23" value=" 23 " />\r
- </vbox> \r
+ </vbox>\r
</row>\r
</rows>\r
- </grid> \r
+ </grid>\r
<hbox><label value="&min.label;"/></hbox>\r
<grid flex="1" id="ximfmail-date-picker-min-grid">\r
<columns>\r
<column flex="1"/>\r
<column flex="1"/>\r
<column flex="1"/>\r
- <column flex="1"/> \r
+ <column flex="1"/>\r
</columns>\r
<rows>\r
<row id="ximfmail-date-picker-min-line1-header-box">\r
<vbox class="oe-date-picker-month-day-box-class" id="ximfmail-date-picker-min-box-0" onclick="clickMin(this,0)">\r
<label class="oe-date-picker-month-day-number-class" id="ximfmail-date-picker-min-text-0" value=":00" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="ximfmail-date-picker-min-box-5" onclick="clickMin(this,5)">\r
<label class="oe-date-picker-month-day-number-class" id="ximfmail-date-picker-min-text-5" value=":05" />\r
</vbox>\r
</vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="ximfmail-date-picker-min-box-25" onclick="clickMin(this,25)">\r
<label class="oe-date-picker-month-day-number-class" id="ximfmail-date-picker-min-text-25" value=":25" />\r
- </vbox> \r
+ </vbox>\r
</row>\r
<row id="ximfmail-date-picker-min-line2-header-box">\r
<vbox class="oe-date-picker-month-day-box-class" id="ximfmail-date-picker-min-box-30" onclick="clickMin(this,30)">\r
</vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="ximfmail-date-picker-min-box-35" onclick="clickMin(this,35)">\r
<label class="oe-date-picker-month-day-number-class" id="ximfmail-date-picker-min-text-35" value=":35" />\r
- </vbox> \r
+ </vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="ximfmail-date-picker-min-box-40" onclick="clickMin(this,40)">\r
<label class="oe-date-picker-month-day-number-class" id="ximfmail-date-picker-min-text-40" value=":40" />\r
</vbox>\r
</vbox>\r
<vbox class="oe-date-picker-month-day-box-class" id="ximfmail-date-picker-min-box-55" onclick="clickMin(this,55)">\r
<label class="oe-date-picker-month-day-number-class" id="ximfmail-date-picker-min-text-55" value=":55" />\r
- </vbox> \r
+ </vbox>\r
</row>\r
</rows>\r
- </grid> \r
+ </grid>\r
<hbox id="ximf-date-picker-end-controls-box">\r
- <box> \r
+ <box>\r
<image id="oe-date-picker-currenttime-text" onclick="adjustCurrentDate()" />\r
- </box> \r
+ </box>\r
<box flex="1" />\r
- <box> \r
+ <box>\r
<image id="ximf-date-picker-ok-control-box" onclick="clickOk()"/>\r
</box>\r
</hbox>\r
- </vbox> \r
+ </vbox>\r
</window>
\ No newline at end of file
/* ***** BEGIN LICENSE BLOCK *****\r
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
*\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
* are permitted provided that the following conditons are met :\r
*\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
* in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
* prior written permission from EADS Defence and Security.\r
- * \r
+ *\r
* Alternatively, the contents of this file may be used under the terms of\r
* either of the GNU General Public License Version 2 or later (the "GPL"),\r
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
* and other provisions required by the GPL or the LGPL. If you do not delete\r
* the provisions above, a recipient may use your version of this file under\r
* the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
+ *\r
* REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ *\r
+ * Contributor(s):\r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
* ***** END LICENSE BLOCK ***** */\r
\r
-\r
-var SMTP_VERSION="0.0";\r
-var SMTP_INSTANCE="smtp";\r
-var LATIN_CHARSET = "ISO-8859-1";\r
-\r
-var XIMF_PREF_IDENTITY_USE_XIMFMAIL = "ximfmail_on";\r
-var XIMF_PREF_IDENTITY_TREETHREAD_REF = "ximfmail_instance_treethread_ref";\r
-var XIMF_PREF_IDENTITY_MAIL_PANEL_REF = "ximfmail_instance_mail_panel_ref";\r
-var PREF_DEFAULT_CHARSET = "mailnews.view_default_charset";\r
-var PREF_MAILNEWS_DEFAULT_CHARSET = "view_default_charset";\r
-var PREF_MAILNEWS = "mailnews";\r
-var PREF_MSGWINDOW_REFRESH = "ximfmail.msgwindow.hdr";\r
-\r
-/*\r
- * Schema xml elements, attributes...\r
- */\r
-var XIMF_VERSION_HEADER = "X-XIMF-Version";\r
-var _XIMF_ATT_XVALUE = "ximfvalue";\r
-var _XIMF_ATT_TEC_VALUE = "ximftecvalue";\r
-var _XIMF_ATT_MAX_ITEMS = "ximfmaxitems";\r
-var _XIMF_ATT_IS_MULTISET = "ismultiset";\r
-var _XIMF_ATT_REF_BOX = "ximfreftextbox";\r
-var _XIMF_ATT_REF_HEADER = "refheader";\r
-var _XIMF_ATT_LINK_POPUP_BOX = "linkpopupbox";\r
-var _XIMF_ATT_CONCAT_ID = "ximfconcatid";\r
-var _XIMF_ATT_SEPARATOR = "ximfseparator";\r
-var _XIMF_ATT_TEC_SEPARATOR = "ximftecseparator";\r
-var _XIMF_DEFAULT_SEPARATOR = ";";\r
-var _XIMF_ELT_DATEPICKER = "datepicker";\r
-\r
-var XIMF_HEADER_RFC_VERSION = "x-ximf-version";\r
-var XIMF_HEADER_INSTANCE_VERSION = "x-instance-version";\r
-var XIMF_HEADER_INSTANCE_NAME = "x-instance-name";\r
-\r
-\r
-//\r
-var DEFAULT_XIMF_VERSION = "1.0";\r
-var DEFAULT_XIMF_NAME = "XIMF_BASIC";\r
-var XIMF_VERSION_HEADER = "X-XIMF-Version";\r
-var XIMF_NAME_HEADER = "X-XIMF-NAME";\r
-var XIMF_ENDLINE = "\r\n"; // Windows CRLF\r
-var XIMF_SEPARATOR_HEADER = ": ";\r
-\r
-var XIMFMAIL_SECURE_HEADERS_XML_FILE = "secureHeadersMail.xml";\r
-var XIMFMAIL_SECURITY_LABEL_XML_DIR = "securityLabel";\r
-var XIMFMAIL_SECURITY_LABEL_XML_FILE = "ximfmailSecurityLabels.xml";\r
-\r
+var ximfConst = ximfConst || {};\r
+ximfConst = {\r
+ SMTP_VERSION : "0.0",\r
+ SMTP_INSTANCE_KEY : "smtp",\r
+ LATIN_CHARSET : "ISO-8859-1",\r
+ XIMF_PREF_IDENTITY_USE_XIMFMAIL : "ximfmail_on",\r
+ XIMF_PREF_IDENTITY_TREETHREAD_REF : "ximfmail_instance_treethread_ref",\r
+ // XIMF_PREF_IDENTITY_MAIL_PANEL_REF : "ximfmail_instance_mail_panel_ref",\r
+ PREF_DEFAULT_CHARSET : "mailnews.view_default_charset",\r
+ PREF_MAILNEWS_DEFAULT_CHARSET : "view_default_charset",\r
+ PREF_MAILNEWS : "mailnews",\r
+ PREF_MSGWINDOW_REFRESH : "ximfmail.msgwindow.hdr",\r
+ XIMFMAIL_SECURE_HEADERS_XML_FILE : "secureHeadersMail.xml",\r
+ XIMF_VERSION_HEADER : "X-XIMF-Version",\r
+ _XIMF_ATT_XVALUE : "ximfvalue",\r
+ _XIMF_ATT_TEC_VALUE : "ximftecvalue",\r
+ _XIMF_ATT_MAX_ITEMS : "ximfmaxitems",\r
+ _XIMF_ATT_IS_MULTISET : "ismultiset",\r
+ _XIMF_ATT_REF_BOX : "ximfreftextbox",\r
+ _XIMF_ATT_REF_HEADER : "refheader",\r
+ _XIMF_ATT_LINK_POPUP_BOX : "linkpopupbox",\r
+ _XIMF_ATT_CONCAT_ID : "ximfconcatid",\r
+ _XIMF_ATT_SEPARATOR : "ximfseparator",\r
+ _XIMF_ATT_TEC_SEPARATOR : "ximftecseparator",\r
+ _XIMF_DEFAULT_SEPARATOR : ",",\r
+ DEFAULT_XIMF_VERSION : "1.0",\r
+ DEFAULT_XIMF_NAME : "XIMF_BASIC",\r
+ XIMF_NAME_HEADER : "X-XIMF-NAME",\r
+ XIMF_ENDLINE : "\r\n",\r
+ XIMF_SEPARATOR_HEADER : ": ",\r
+ CHROME_XSL_SECURE_HEADERS: "chrome://theme_ximfmail/content/secureHeaders-ximfmail.xsl",\r
+ CHROME_XSL_MSG_COMPOSE : "chrome://theme_ximfmail/content/messengerCompose-ximfmail.xsl",\r
+ CHROME_XSL_TREE_RCV : "chrome://theme_ximfmail/content/threadTree-ximfmail.xsl", //gChromeXslTreeRcv\r
+ CHROME_XSL_SECURITY_LABEL : "chrome://theme_ximfmail/content/securityLabel-ximfmail.xsl",\r
+ CHROME_XSL_TREE_DIALOG : "chrome://ximfmail/content/dialogTree-ximfmail.xul",\r
+ CHROME_XSL_DLG_CALENDAR : "chrome://ximfmail/content/calendar/dialogCalendar-ximfmail.xul",\r
+ CHROME_XSL_DLG_EDITOR : "chrome://ximfmail/content/editor/dialogEditor-ximfmail.xul"\r
+};
\ No newline at end of file
/* ***** BEGIN LICENSE BLOCK *****\r
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
*\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
* are permitted provided that the following conditons are met :\r
*\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
* in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
* prior written permission from EADS Defence and Security.\r
- * \r
+ *\r
* Alternatively, the contents of this file may be used under the terms of\r
* either of the GNU General Public License Version 2 or later (the "GPL"),\r
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
* and other provisions required by the GPL or the LGPL. If you do not delete\r
* the provisions above, a recipient may use your version of this file under\r
* the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
+ *\r
* REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ *\r
+ * Contributor(s):\r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
* ***** END LICENSE BLOCK ***** */\r
- \r
-/* \r
- * global variables\r
+/**\r
+ * Object to manage user preference for Ximfmail\r
*/\r
-var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);\r
-\r
-/*\r
- * \r
- */ \r
- function IsXimfailActivated(identity){\r
- //alert(identity + "(ximfmail_on) = " + GetXimfmailPref(identity,"ximfmail_on"));\r
- //if(GetXimfmailPref(identity,"ximfmail_on") == "true")\r
- if(identity.getBoolAttribute("ximfmail_on"))\r
- return true;\r
- else\r
- return false;\r
- }\r
- \r
-/*\r
- * get value of ximfmail user preference \r
- */\r
-function GetXimfmailPref(idIdentity,key){\r
- var prefValue = ""; \r
- var ximfmailPrefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("mail.identity." + idIdentity + ".");\r
- if(ximfmailPrefBranch.prefHasUserValue(key)) \r
- prefValue = ximfmailPrefBranch.getCharPref(key); \r
- return prefValue;\r
-}\r
-\r
-/*\r
- * set value of ximfmail user preference\r
- */\r
-function SetXimfmailPref(idIdentity,key,value){ \r
- try{\r
- gConsole.logStringMessage("[ximfmail - SetXimfmailPref] key "+key+" : "+value);\r
- \r
- var prefSvc = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);\r
- var ximfmailPrefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("mail.identity." + idIdentity + ".");\r
- ximfmailPrefBranch.setCharPref(key,value);\r
- prefSvc.savePrefFile(null);\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - SetXimfmailPref] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
- }\r
-}\r
-\r
-function ResetXimfmailPref(idIdentity,key){ \r
- var prefSvc = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);\r
- var ximfmailPrefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("mail.identity." + idIdentity + ".");\r
- ximfmailPrefBranch.ClearUserPref(key);\r
- prefSvc.savePrefFile(null);\r
-}\r
-\r
-\r
-/*\r
+var ximfPref = ximfPref || {};\r
+ximfPref = {\r
+ log : function (sMessage, sFileName, iLineNumber) {\r
+ var trace = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);\r
+ if (sFileName) {\r
+ trace.logStringMessage("[controler-ximfmail] " + sMessage + "\nfile : " + sFileName + "\nline : " + sFileName);\r
+ } else {\r
+ trace.logStringMessage("[controler-ximfmail] " + sMessage);\r
+ }\r
+ },\r
+ get : function (idIdentity, key) {\r
+ var prefValue = undefined;\r
+ try {\r
+ var ximfmailPrefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("mail.identity." + idIdentity + ".");\r
+ if(ximfmailPrefBranch.prefHasUserValue(key)) {\r
+ prefValue = ximfmailPrefBranch.getCharPref(key);\r
+ }\r
+ } catch (ex) {\r
+ this.log(ex, Error().fileName, ex.lineNumber);\r
+ }\r
+ return prefValue;\r
+ },\r
+ set : function (idIdentity, key, value) {\r
+ try{\r
+ var prefSvc = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);\r
+ var ximfmailPrefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("mail.identity." + idIdentity + ".");\r
+ ximfmailPrefBranch.setCharPref(key,value);\r
+ prefSvc.savePrefFile(null);\r
+ this.log("set pref " + key + " of " + idIdentity + " to " + value);\r
+ }catch(ex){\r
+ this.log(ex, Error().fileName, ex.lineNumber);\r
+ }\r
+ },\r
+ getBool : function (idIdentity, key) {\r
+ var prefValue = undefined;\r
+ try {\r
+ var ximfmailPrefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("mail.identity." + idIdentity + ".");\r
+ if(ximfmailPrefBranch.prefHasUserValue(key)) {\r
+ prefValue = ximfmailPrefBranch.getBoolPref(key);\r
+ }\r
+ } catch (ex) {\r
+ this.log(ex, Error().fileName, ex.lineNumber);\r
+ }\r
+ return prefValue;\r
+ },\r
+ setBool: function (idIdentity, key, value) {\r
+ try{\r
+ var prefSvc = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);\r
+ var ximfmailPrefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("mail.identity." + idIdentity + ".");\r
+ ximfmailPrefBranch.setBoolPref(key, value);\r
+ prefSvc.savePrefFile(null);\r
+ this.log("set pref " + key + " of " + idIdentity + " to " + value);\r
+ }catch(ex){\r
+ this.log(ex, Error().fileName, ex.lineNumber);\r
+ }\r
+ },\r
+ isXimfAccountOn : function (identity) {\r
+ if (identity.getBoolAttribute("ximfmail_on")) {\r
+ return true;\r
+ } else {\r
+ return false;\r
+ }\r
+ },\r
+ reset : function (idIdentity,key) {\r
+ try{\r
+ var prefSvc = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService);\r
+ var ximfmailPrefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch("mail.identity." + idIdentity + ".");\r
+ ximfmailPrefBranch.ClearUserPref(key);\r
+ prefSvc.savePrefFile(null);\r
+ }catch(ex){\r
+ this.log(ex, Error().fileName, ex.lineNumber);\r
+ }\r
+ }\r
+};\r
+/**\r
* set value to reference attribute of xul element\r
* used for RDF resource\r
* idElement : id of xul element\r
* refValue : value of ref attribute\r
*/\r
-function ChangeRefAttrRdfElement(idElement,refValue){\r
- //$("#"+idElement).attr("ref",refValue);\r
- \r
- var list = document.getElementById(idElement); \r
- list.database.AddDataSource(XimfCatalog.getInstance().getDSCatalog()); \r
+function AddRdfDataSce2domList(idElement,refValue) {\r
+ var list = document.getElementById(idElement);\r
+ list.database.AddDataSource(XimfCatalog.getInstance().getDSCatalog());\r
list.setAttribute("ref",refValue);\r
list.builder.rebuild();\r
- \r
-}\r
-\r
-/*\r
- * init default menulist xul element with first menuitem \r
- * idMenuList : id of menulist xul element\r
- */\r
-function InitRDFMenuList(idMenuList){\r
- var itemlist = $("#"+ idMenuList +" > menupopup > menuitem"); \r
- $("#"+idMenuList).attr("value",$(itemlist[0]).attr("value"));\r
- $("#"+idMenuList).attr("label",$(itemlist[0]).attr("label"));\r
-}\r
-\r
-/*\r
- * display user pref value in menulist if exists\r
- * manage RDF Catalog list in accountWizard, accountManager\r
- * identity : user identity key\r
- * idPref : user preference key\r
- * idList : id of menulist xul element\r
- */\r
-function UpdateRDFListWithPref(identity, idPref,idList){\r
- var pref = GetXimfmailPref(identity,idPref);\r
- if(pref){\r
- var themeList = $("#"+idList+" > menupopup > menuitem");\r
- for(var i=0; i<themeList.length; i++){ \r
- if( pref == $(themeList[i]).attr("value")){\r
- $("#"+idList).attr("value",$(themeList[i]).attr("value"));\r
- $("#"+idList).attr("label",$(themeList[i]).attr("label")); \r
- }\r
- }\r
- }\r
}
\ No newline at end of file
/* ***** BEGIN LICENSE BLOCK *****\r
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
*\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
* are permitted provided that the following conditons are met :\r
*\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
* in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
* prior written permission from EADS Defence and Security.\r
- * \r
+ *\r
* Alternatively, the contents of this file may be used under the terms of\r
* either of the GNU General Public License Version 2 or later (the "GPL"),\r
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
* and other provisions required by the GPL or the LGPL. If you do not delete\r
* the provisions above, a recipient may use your version of this file under\r
* the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
+ *\r
* REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ *\r
+ * Contributor(s):\r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
* ***** END LICENSE BLOCK ***** */\r
-\r
- \r
/*\r
window.arguments = [];\r
args[0] header label\r
args[1] header XIMF\r
args[2] list of label values\r
- args[3] list of XIMF values \r
+ args[3] list of XIMF values\r
args[4] label separator\r
args[5] XIMF separator\r
*/\r
function OnDisplayInformations(){\r
var gArgs = window.arguments;\r
var xSeparator = null;\r
- var NB_CHARACTERS = 45; \r
- \r
+ var NB_CHARACTERS = 45;\r
if(gArgs[0].length > 0){\r
- var title = gArgs[0][0]; \r
+ var title = gArgs[0][0];\r
var xHdr = gArgs[0][1];\r
var val = gArgs[0][2];\r
- var xval = gArgs[0][3]; \r
+ var xval = gArgs[0][3];\r
}\r
- \r
- if(gArgs[0].length == 5){\r
+ if(gArgs[0].length === 5){\r
var xSeparator = gArgs[0][4];\r
}\r
- \r
//add complete header to description\r
- //document.getElementById("ximfheaderName").value = title.substring(0,title.lastIndexOf(":"));\r
document.title = title.substring(0,title.lastIndexOf(":"));\r
if(!xSeparator){\r
document.getElementById("ximfheaderValue").value = val;\r
- }else{ \r
+ }else{\r
var reg=new RegExp("["+xSeparator+"]+", "g");\r
document.getElementById("ximfheaderValue").value = val.replace(reg,"\n");\r
}\r
}\r
-\r
function doOK()\r
-{ \r
+{\r
return true;\r
}\r
-\r
function doCancel()\r
{\r
return true;\r
<!-- ***** BEGIN LICENSE BLOCK *****\r
- Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
- ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- - \r
-\r
- - Redistribution and use, in source and binary forms, with or without modification, \r
+ -\r
+ - Redistribution and use, in source and binary forms, with or without modification,\r
- are permitted provided that the following conditons are met :\r
-\r
- - 1. Redistributions of source code must retain the above copyright notice, \r
- - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ - 1. Redistributions of source code must retain the above copyright notice,\r
+ - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
- in the redistribution of the source code.\r
- - 3. Neither the names of the copyright holders nor the names of any contributors \r
- - may be used to endorse or promote products derived from this software without specific \r
+ - 3. Neither the names of the copyright holders nor the names of any contributors\r
+ - may be used to endorse or promote products derived from this software without specific\r
- prior written permission from EADS Defence and Security.\r
- - \r
+ -\r
- Alternatively, the contents of this file may be used under the terms of\r
- either of the GNU General Public License Version 2 or later (the "GPL"),\r
- or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
- and other provisions required by the GPL or the LGPL. If you do not delete\r
- the provisions above, a recipient may use your version of this file under\r
- the terms of any one of the MPL, the GPL or the LGPL.\r
- - \r
+ -\r
- REMINDER :\r
- - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
- IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- - \r
- - EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ -\r
+ - EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ - \r
+ - Contributor(s):\r
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved \r
- ***** END LICENSE BLOCK ***** -->\r
\r
<!DOCTYPE overlay SYSTEM "chrome://ximfmail/locale/ximfmail.dtd">\r
<?xml-stylesheet href="chrome://ximfmail/skin" type="text/css"?>\r
<!-- title="&dlgheader.hdrInfo.descr;" -->\r
-<dialog id="ximfmail-dialog-hdrInfo" \r
- \r
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" \r
- buttons="accept" \r
+<dialog id="ximfmail-dialog-hdrInfo"\r
+\r
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"\r
+ buttons="accept"\r
buttonlabelaccept="OK"\r
ondialogaccept="return doOK();"\r
- onload="OnDisplayInformations();"> \r
- <script type="application/javascript" src="chrome://ximfmail/content/dialogHdrInfo-ximfmail.js" /> \r
- <vbox flex="1"> \r
- <label id="ximfheaderName"/> \r
- <vbox id="box-ilkheaderValue" flex="1"> \r
- <spacer flex="1"/> \r
- <textbox id="ximfheaderValue" rows="5" readonly="true" multiline="true" flex="1"/> \r
- </vbox> \r
+ onload="OnDisplayInformations();">\r
+ <script type="application/javascript" src="chrome://ximfmail/content/dialogHdrInfo-ximfmail.js" />\r
+ <vbox flex="1">\r
+ <label id="ximfheaderName"/>\r
+ <vbox id="box-ilkheaderValue" flex="1">\r
+ <spacer flex="1"/>\r
+ <textbox id="ximfheaderValue" rows="5" readonly="true" multiline="true" flex="1"/>\r
+ </vbox>\r
</vbox>\r
-</dialog>
\ No newline at end of file
+</dialog>
\ No newline at end of file
-var XIMF_DIALOG_TREE_RDF_ROOT_URI = "http://www.ximfmail.com/dialogtree/datas";
-var XIMF_DIALOG_TREE_PREDICATE_COLUMN_0 = "http://www.ximfmail.com/RDF#column0";
-var XIMF_DIALOG_TREE_PREDICATE_COLUMN_1 = "http://www.ximfmail.com/RDF#column1";
-
-function Indexage(){
- this.A = -1;
- this.B = -1;
- this.C = -1;
- this.D = -1;
- this.E = -1;
- this.F = -1;
- this.G = -1;
- this.H = -1;
- this.I = -1;
- this.J = -1;
- this.K = -1;
- this.L = -1;
- this.M = -1;
- this.N = -1;
- this.O = -1;
- this.P = -1;
- this.Q = -1;
- this.R = -1;
- this.S = -1;
- this.T = -1;
- this.U = -1;
- this.V = -1;
- this.W = -1;
- this.X = -1;
- this.Y = -1;
- this.Z = -1;
-};
-/*
- *
- */
-function DialogTreeRDFSourceClass()
-{
- // private:
- var _rdfService = null;
- var _rdfCUtils = null;
- var _treeProjectsDatasource = null;
- var _treeProjectsRefURI = null;
- var _SeqRDFC_data = null;
-
- // public:
- if(typeof DialogTreeRDFSourceClass.initialized == "undefined")
- {
- //init
- DialogTreeRDFSourceClass.prototype.initialize = function(dataSource, strURI)
- {
- try{
- gConsole.logStringMessage("[ximfmail - DialogTreeRDFClass ] \n ");
- // ref : attribut of tree. use to save all data in the same dataSource
- _treeProjectsRefURI = strURI;
-
- // init RDF service
- _rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
-
- // init data source
- if(null == _treeProjectsDatasource)
- {
- _treeProjectsDatasource = dataSource;
- }
-
- // init RDF Container Utils
- _rdfCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].createInstance(Components.interfaces.nsIRDFContainerUtils);
-
- // Init seq Container data source
- var seqNode = _rdfService.GetResource(_treeProjectsRefURI);
- _SeqRDFC_data = _rdfCUtils.MakeSeq(_treeProjectsDatasource, seqNode);
- }catch(e){
- gConsole.logStringMessage("[ximfmail - DialogTreeRDFClass ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
- }
- }
-
- //
- DialogTreeRDFSourceClass.prototype.getEntriesCount = function()
- {
- if(_SeqRDFC_data){
- return _SeqRDFC_data.GetCount();
- }else{
- return 0;
- }
- }
- //
- DialogTreeRDFSourceClass.prototype.getDataSource=function()
- {
- return _treeProjectsDatasource;
- };
-
- DialogTreeRDFSourceClass.prototype.getDataEntry = function(uri,predicate){
- try
- {
- var data = "";
- var resource = _rdfService.GetResource(uri);
- var targets = _treeProjectsDatasource.ArcLabelsOut(resource);
- while (targets.hasMoreElements())
- {
- var newpredicate = targets.getNext();
- if (newpredicate instanceof Components.interfaces.nsIRDFResource)
- {
- var target = _treeProjectsDatasource.GetTarget(resource, newpredicate, true);
- if (target instanceof Components.interfaces.nsIRDFLiteral)
- {
- if(newpredicate.Value == predicate)
- data = target.Value;
- }
- }
- }
- }catch(e){
- gConsole.logStringMessage("[ximfmail - DialogTreeRDFSourceClass ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
- }
- return data;
- };
-
-
- DialogTreeRDFSourceClass.prototype.getEntryByPos = function(beggin, nbr)
- {
- var arrayResult = [];
- try
- {
- var seq = _SeqRDFC_data.GetElements();
- var currentData = 0;
- while (seq.hasMoreElements())
- {
- var element = seq.getNext();
- if (element instanceof Components.interfaces.nsIRDFResource)
- {
- if(currentData >= beggin && currentData <= beggin+nbr)
- {
- var col0 = this.getDataEntry(element.ValueUTF8,XIMF_DIALOG_TREE_PREDICATE_COLUMN_0);
- var col1 = this.getDataEntry(element.ValueUTF8,XIMF_DIALOG_TREE_PREDICATE_COLUMN_1);
-
- arrayResult.push([col0,col1]);
- }
- }
- currentData++;
- }
- }catch(e){
- gConsole.logStringMessage("[ximfmail - getSeachText ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
- }
- return arrayResult;
-
- };
-
- //
- DialogTreeRDFSourceClass.prototype.getEntryByText = function(textToFind, nbr, curpos)
- {
- var arrayResult = [];
- var beggin = _SeqRDFC_data.GetCount();
- try
- {
- var seq = _SeqRDFC_data.GetElements();
- var currentData = 0;
- while (seq.hasMoreElements())
- {
- var element = seq.getNext();
- if (element instanceof Components.interfaces.nsIRDFResource)
- {
- if(curpos <= currentData)
- {
- var col0 = this.getDataEntry(element.ValueUTF8,XIMF_DIALOG_TREE_PREDICATE_COLUMN_0);
- if(beggin == _SeqRDFC_data.GetCount())
- if(col0.toUpperCase().indexOf(textToFind.toUpperCase()) != -1)
- beggin = currentData;
-
- if(currentData >= beggin && currentData <= beggin+nbr)
- {
- var col1 = this.getDataEntry(element.ValueUTF8,XIMF_DIALOG_TREE_PREDICATE_COLUMN_1);
- arrayResult.push([col0,col1]);
- }
- }
- }
- currentData++;
- }
- }catch(e){
- gConsole.logStringMessage("[ximfmail - getSeachText ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
- }
- return [arrayResult,beggin];
- };
-
- DialogTreeRDFSourceClass.prototype.getIndex = function()
- {
- var arrayResult = [];
- var beggin = -1;
- var indexAZ = new Indexage();
- try
- {
- var seq = _SeqRDFC_data.GetElements();
- var currentData = 0;
- while (seq.hasMoreElements())
- {
- var element = seq.getNext();
- if (element instanceof Components.interfaces.nsIRDFResource)
- {
- var col0 = this.getDataEntry(element.ValueUTF8,XIMF_DIALOG_TREE_PREDICATE_COLUMN_0);
- if(indexAZ[col0[0].toUpperCase()] == -1)
- {
- indexAZ[col0[0].toUpperCase()] = currentData;
- }
- }
- currentData++;
- }
- }catch(e){
- gConsole.logStringMessage("[ximfmail - getIndex ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
- }
- return indexAZ;
- };
- // object initialisation
- DialogTreeRDFSourceClass.initialized = true;
- }
-}
-
-/*
- *
- */
-function DialogTreeRDFClass()
-{
- // private:
- var _rdfService = null;
- var _rdfCUtils = null;
- var _treeProjectsDatasource = null;
- var _treeProjectsRefURI = null;
- var _SeqRDFC_data = null;
- var _RdfDataSourceOrigin = null;
- var _indexAZ = null;
-
- // public:
- if(typeof DialogTreeRDFClass.initialized == "undefined")
- {
- //init
- DialogTreeRDFClass.prototype.initialize = function(dataSource, strURI)
- {
- try{
- // ref : attribut of tree. use to save all data in the same dataSource
- _treeProjectsRefURI = XIMF_DIALOG_TREE_RDF_ROOT_URI;
-
- // init RDF service
- _rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
-
- // init data source
- if(null == _treeProjectsDatasource)
- {
- _treeProjectsDatasource = _rdfService.GetDataSource("rdf:in-memory-datasource");
- _treeProjectsDatasource.QueryInterface(Components.interfaces.nsIRDFInMemoryDataSource);
- }
-
- // init RDF Container Utils
- _rdfCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].createInstance(Components.interfaces.nsIRDFContainerUtils);
-
- // Init seq Container data source
- var seqNode = _rdfService.GetResource(_treeProjectsRefURI);
- _SeqRDFC_data = _rdfCUtils.MakeSeq(_treeProjectsDatasource, seqNode);
-
- _RdfDataSourceOrigin = new DialogTreeRDFSourceClass();
- _RdfDataSourceOrigin.initialize(dataSource, strURI);
-
- _indexAZ = _RdfDataSourceOrigin.getIndex();
-
- }catch(e){
- gConsole.logStringMessage("[ximfmail - DialogTreeRDFClass ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
- }
- }
-
- //
- DialogTreeRDFClass.prototype.getEntriesCount = function()
- {
- if(_SeqRDFC_data){
- return _SeqRDFC_data.GetCount();
- }else{
- return 0;
- }
- }
- //
- DialogTreeRDFClass.prototype.getDataSource=function()
- {
- return _treeProjectsDatasource;
- };
-
- DialogTreeRDFClass.prototype.addEntryDisplay = function(entry, index)
- {
- // append resource element to sequence
- //[DN,name,type]
- var col0 = entry[0];
- var col1 = entry[1];
-
- var newURI = _treeProjectsRefURI + "/data" + index ;
- var newResource = _rdfService.GetResource(newURI);
- _SeqRDFC_data.AppendElement(newResource);
-
- // save user informations
- if(col0)
- {
- _treeProjectsDatasource.Assert(newResource,
- _rdfService.GetResource(XIMF_DIALOG_TREE_PREDICATE_COLUMN_0),
- _rdfService.GetLiteral(col0),
- true);
- }
-
- if(col1)
- {
- _treeProjectsDatasource.Assert(newResource,
- _rdfService.GetResource(XIMF_DIALOG_TREE_PREDICATE_COLUMN_1),
- _rdfService.GetLiteral(col1),
- true);
- }
- };
-
-
- DialogTreeRDFClass.prototype.getDataEntry = function(uri,predicate)
- {
- try{
- _RdfDataSourceOrigin.getDataEntry(uri,predicate);
- }catch(e){
- gConsole.logStringMessage("[ximfmail - DialogTreeRDFClass ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
- }
- return data;
- };
-
- DialogTreeRDFClass.prototype.removeAllDisplay = function()
- {
- try
- {
- if(_SeqRDFC_data)
- {
- var numEntri = _SeqRDFC_data.GetCount();
- for (var indexCur = numEntri; indexCur >0; indexCur--)
- {
- _SeqRDFC_data.RemoveElementAt(indexCur,true);
- }
- }
- }catch(e){
- gConsole.logStringMessage("[ximfmail - DialogTreeRDFClass ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
- }
- };
-
- //
- DialogTreeRDFClass.prototype.updateDisplay = function(curpos,maxPos)
- {
- //
- var colFoundArray = [];
- var maxEntry = _RdfDataSourceOrigin.getEntriesCount();
-
- if(curpos+maxPos > maxEntry)
- curpos = maxEntry-maxPos;
-
- colFoundArray = _RdfDataSourceOrigin.getEntryByPos(curpos, maxPos);
-
- this.removeAllDisplay();
-
- for(var currItem=0;currItem<colFoundArray.length;currItem++)
- {
- this.addEntryDisplay(colFoundArray[currItem], currItem);
- }
- $("#ximfmail.treedialog").attr("hidevscroll","true");
- };
-
- //
- DialogTreeRDFClass.prototype.updateDisplayByText = function(textToFind,maxPos,curpos)
- {
- //
- var colFoundArray = [];
- var index = _indexAZ[textToFind[0].toUpperCase()];
-
- if(index == -1)
- return -1;
-
- if(textToFind.length == 1)
- {
- if(index==curpos)
- return -1;
-
- this.updateDisplay(index,maxPos);
- return index;
- }
-
- var maxEntry = _RdfDataSourceOrigin.getEntriesCount();
- if(index+maxPos > maxEntry)
- index = maxEntry-maxPos-1;
-
- var result = _RdfDataSourceOrigin.getEntryByText(textToFind, maxPos, index);
- colFoundArray = result[0];
-
- if(colFoundArray.length == 0)
- return -1;
-
- this.removeAllDisplay();
-
- for(var currItem=0;currItem<colFoundArray.length;currItem++)
- {
- this.addEntryDisplay(colFoundArray[currItem], currItem);
- }
- $("#ximfmail.treedialog").attr("hidevscroll","true");
-
- return result[1];
- };
-
- //
- DialogTreeRDFClass.prototype.getMaxEntry = function()
- {
- //
- var remoteCount = 0;
-
- remoteCount = _RdfDataSourceOrigin.getEntriesCount();
-
- return remoteCount;
- };
-
- // object initialisation
- DialogTreeRDFClass.initialized = true;
- }
+/* ***** BEGIN LICENSE BLOCK *****\r
+ * Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
+ * ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
+ *\r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditons are met :\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
+ * in the redistribution of the source code.\r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
+ * prior written permission from EADS Defence and Security.\r
+ *\r
+ * Alternatively, the contents of this file may be used under the terms of\r
+ * either of the GNU General Public License Version 2 or later (the "GPL"),\r
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
+ * in which case the provisions of the GPL or the LGPL are applicable instead\r
+ * of those above. If you wish to allow use of your version of this file only\r
+ * under the terms of either the GPL or the LGPL, and not to allow others to\r
+ * use your version of this file under the terms of the MPL, indicate your\r
+ * decision by deleting the provisions above and replace them with the notice\r
+ * and other provisions required by the GPL or the LGPL. If you do not delete\r
+ * the provisions above, a recipient may use your version of this file under\r
+ * the terms of any one of the MPL, the GPL or the LGPL.\r
+ *\r
+ * REMINDER :\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ *\r
+ * Contributor(s):\r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
+ * ***** END LICENSE BLOCK ***** */\r
+var XIMF_DIALOG_TREE_RDF_ROOT_URI = "http://www.ximfmail.com/dialogtree/datas";\r
+var XIMF_DIALOG_TREE_PREDICATE_COLUMN_0 = "http://www.ximfmail.com/RDF#column0";\r
+var XIMF_DIALOG_TREE_PREDICATE_COLUMN_1 = "http://www.ximfmail.com/RDF#column1";\r
+\r
+function Indexage(){\r
+ this.A = -1;\r
+ this.B = -1;\r
+ this.C = -1;\r
+ this.D = -1;\r
+ this.E = -1;\r
+ this.F = -1;\r
+ this.G = -1;\r
+ this.H = -1;\r
+ this.I = -1;\r
+ this.J = -1;\r
+ this.K = -1;\r
+ this.L = -1;\r
+ this.M = -1;\r
+ this.N = -1;\r
+ this.O = -1;\r
+ this.P = -1;\r
+ this.Q = -1;\r
+ this.R = -1;\r
+ this.S = -1;\r
+ this.T = -1;\r
+ this.U = -1;\r
+ this.V = -1;\r
+ this.W = -1;\r
+ this.X = -1;\r
+ this.Y = -1;\r
+ this.Z = -1;\r
+};\r
+/*\r
+ *\r
+ */\r
+function DialogTreeRDFSourceClass() {\r
+ // private:\r
+ var _rdfService = null;\r
+ var _rdfCUtils = null;\r
+ var _treeProjectsDatasource = null;\r
+ var _treeProjectsRefURI = null;\r
+ var _SeqRDFC_data = null;\r
+ // public:\r
+ if (typeof DialogTreeRDFSourceClass.initialized === "undefined") {\r
+ //init\r
+ DialogTreeRDFSourceClass.prototype.initialize = function(dataSource, strURI) {\r
+ try {\r
+ gConsole.logStringMessage("[ximfmail - DialogTreeRDFClass ] \n ");\r
+ // ref : attribut of tree. use to save all data in the same dataSource\r
+ _treeProjectsRefURI = strURI;\r
+ // init RDF service\r
+ _rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);\r
+ // init data source\r
+ if (null === _treeProjectsDatasource) {\r
+ _treeProjectsDatasource = dataSource;\r
+ }\r
+ // init RDF Container Utils\r
+ _rdfCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].createInstance(Components.interfaces.nsIRDFContainerUtils);\r
+ // Init seq Container data source\r
+ var seqNode = _rdfService.GetResource(_treeProjectsRefURI);\r
+ _SeqRDFC_data = _rdfCUtils.MakeSeq(_treeProjectsDatasource, seqNode);\r
+ } catch(e){\r
+ gConsole.logStringMessage("[ximfmail - DialogTreeRDFClass ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
+ }\r
+ //\r
+ DialogTreeRDFSourceClass.prototype.getEntriesCount = function() {\r
+ if (_SeqRDFC_data) {\r
+ return _SeqRDFC_data.GetCount();\r
+ } else {\r
+ return 0;\r
+ }\r
+ }\r
+ //\r
+ DialogTreeRDFSourceClass.prototype.getDataSource=function() {\r
+ return _treeProjectsDatasource;\r
+ };\r
+\r
+ DialogTreeRDFSourceClass.prototype.getDataEntry = function(uri,predicate) {\r
+ try {\r
+ var data = "";\r
+ var resource = _rdfService.GetResource(uri);\r
+ var targets = _treeProjectsDatasource.ArcLabelsOut(resource);\r
+ while (targets.hasMoreElements()) {\r
+ var newpredicate = targets.getNext();\r
+ if (newpredicate instanceof Components.interfaces.nsIRDFResource) {\r
+ var target = _treeProjectsDatasource.GetTarget(resource, newpredicate, true);\r
+ if (target instanceof Components.interfaces.nsIRDFLiteral && newpredicate.Value === predicate) {\r
+ data = target.Value;\r
+ }\r
+ }\r
+ }\r
+ }catch(e){\r
+ gConsole.logStringMessage("[ximfmail - DialogTreeRDFSourceClass ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
+ return data;\r
+ };\r
+ DialogTreeRDFSourceClass.prototype.getEntryByPos = function(beggin, nbr) {\r
+ var arrayResult = [];\r
+ try {\r
+ var seq = _SeqRDFC_data.GetElements();\r
+ var currentData = 0;\r
+ while (seq.hasMoreElements()) {\r
+ var element = seq.getNext();\r
+ if (element instanceof Components.interfaces.nsIRDFResource && currentData >= beggin && currentData <= beggin+nbr) {\r
+ var col0 = this.getDataEntry(element.ValueUTF8,XIMF_DIALOG_TREE_PREDICATE_COLUMN_0);\r
+ var col1 = this.getDataEntry(element.ValueUTF8,XIMF_DIALOG_TREE_PREDICATE_COLUMN_1);\r
+ arrayResult.push([col0,col1]);\r
+ }\r
+ currentData++;\r
+ }\r
+ }catch(e){\r
+ gConsole.logStringMessage("[ximfmail - getSeachText ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
+ return arrayResult;\r
+ };\r
+\r
+ //\r
+ DialogTreeRDFSourceClass.prototype.getEntryByText = function(textToFind, nbr, curpos) {\r
+ var arrayResult = [];\r
+ var beggin = _SeqRDFC_data.GetCount();\r
+ try {\r
+ var seq = _SeqRDFC_data.GetElements();\r
+ var currentData = 0;\r
+ while (seq.hasMoreElements()) {\r
+ var element = seq.getNext();\r
+ if (element instanceof Components.interfaces.nsIRDFResource && curpos <= currentData) {\r
+ var col0 = this.getDataEntry(element.ValueUTF8,XIMF_DIALOG_TREE_PREDICATE_COLUMN_0);\r
+ if (beggin === _SeqRDFC_data.GetCount() && col0.toUpperCase().indexOf(textToFind.toUpperCase()) !== -1) {\r
+ beggin = currentData;\r
+ }\r
+ if (currentData >= beggin && currentData <= beggin+nbr) {\r
+ var col1 = this.getDataEntry(element.ValueUTF8,XIMF_DIALOG_TREE_PREDICATE_COLUMN_1);\r
+ arrayResult.push([col0,col1]);\r
+ }\r
+ }\r
+ currentData++;\r
+ }\r
+ }catch(e){\r
+ gConsole.logStringMessage("[ximfmail - getSeachText ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
+ return [arrayResult,beggin];\r
+ };\r
+ DialogTreeRDFSourceClass.prototype.getIndex = function() {\r
+ var arrayResult = [];\r
+ var beggin = -1;\r
+ var indexAZ = new Indexage();\r
+ try {\r
+ var seq = _SeqRDFC_data.GetElements();\r
+ var currentData = 0;\r
+ while (seq.hasMoreElements()) {\r
+ var element = seq.getNext();\r
+ if (element instanceof Components.interfaces.nsIRDFResource) {\r
+ var col0 = this.getDataEntry(element.ValueUTF8,XIMF_DIALOG_TREE_PREDICATE_COLUMN_0);\r
+ if(indexAZ[col0[0].toUpperCase()] === -1) {\r
+ indexAZ[col0[0].toUpperCase()] = currentData;\r
+ }\r
+ }\r
+ currentData++;\r
+ }\r
+ }catch(e){\r
+ gConsole.logStringMessage("[ximfmail - getIndex ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
+ return indexAZ;\r
+ };\r
+ // object initialisation\r
+ DialogTreeRDFSourceClass.initialized = true;\r
+ }\r
+}\r
+\r
+/*\r
+ *\r
+ */\r
+function DialogTreeRDFClass() {\r
+ // private:\r
+ var _rdfService = null;\r
+ var _rdfCUtils = null;\r
+ var _treeProjectsDatasource = null;\r
+ var _treeProjectsRefURI = null;\r
+ var _SeqRDFC_data = null;\r
+ var _RdfDataSourceOrigin = null;\r
+ var _indexAZ = null;\r
+ // public:\r
+ if(typeof DialogTreeRDFClass.initialized === "undefined") {\r
+ //init\r
+ DialogTreeRDFClass.prototype.initialize = function(dataSource, strURI) {\r
+ try {\r
+ // ref : attribut of tree. use to save all data in the same dataSource\r
+ _treeProjectsRefURI = XIMF_DIALOG_TREE_RDF_ROOT_URI;\r
+ // init RDF service\r
+ _rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);\r
+ // init data source\r
+ if (null === _treeProjectsDatasource) {\r
+ _treeProjectsDatasource = _rdfService.GetDataSource("rdf:in-memory-datasource");\r
+ _treeProjectsDatasource.QueryInterface(Components.interfaces.nsIRDFInMemoryDataSource);\r
+ }\r
+ // init RDF Container Utils\r
+ _rdfCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].createInstance(Components.interfaces.nsIRDFContainerUtils);\r
+ // Init seq Container data source\r
+ var seqNode = _rdfService.GetResource(_treeProjectsRefURI);\r
+ _SeqRDFC_data = _rdfCUtils.MakeSeq(_treeProjectsDatasource, seqNode);\r
+ _RdfDataSourceOrigin = new DialogTreeRDFSourceClass();\r
+ _RdfDataSourceOrigin.initialize(dataSource, strURI);\r
+ _indexAZ = _RdfDataSourceOrigin.getIndex();\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - DialogTreeRDFClass ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
+ }\r
+ //\r
+ DialogTreeRDFClass.prototype.getEntriesCount = function() {\r
+ if (_SeqRDFC_data) {\r
+ return _SeqRDFC_data.GetCount();\r
+ }else{\r
+ return 0;\r
+ }\r
+ }\r
+ //\r
+ DialogTreeRDFClass.prototype.getDataSource=function() {\r
+ return _treeProjectsDatasource;\r
+ };\r
+ DialogTreeRDFClass.prototype.addEntryDisplay = function(entry, index) {\r
+ // append resource element to sequence\r
+ //[DN,name,type]\r
+ var col0 = entry[0];\r
+ var col1 = entry[1];\r
+ var newURI = _treeProjectsRefURI + "/data" + index ;\r
+ var newResource = _rdfService.GetResource(newURI);\r
+ _SeqRDFC_data.AppendElement(newResource);\r
+ // save user informations\r
+ if(col0) {\r
+ _treeProjectsDatasource.Assert(newResource,\r
+ _rdfService.GetResource(XIMF_DIALOG_TREE_PREDICATE_COLUMN_0),\r
+ _rdfService.GetLiteral(col0),\r
+ true);\r
+ }\r
+ if(col1) {\r
+ _treeProjectsDatasource.Assert(newResource,\r
+ _rdfService.GetResource(XIMF_DIALOG_TREE_PREDICATE_COLUMN_1),\r
+ _rdfService.GetLiteral(col1),\r
+ true);\r
+ }\r
+ };\r
+ DialogTreeRDFClass.prototype.getDataEntry = function(uri,predicate) {\r
+ try{\r
+ _RdfDataSourceOrigin.getDataEntry(uri,predicate);\r
+ }catch(e){\r
+ gConsole.logStringMessage("[ximfmail - DialogTreeRDFClass ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
+ return data;\r
+ };\r
+ DialogTreeRDFClass.prototype.removeAllDisplay = function() {\r
+ try {\r
+ if(_SeqRDFC_data) {\r
+ var numEntri = _SeqRDFC_data.GetCount();\r
+ for (var indexCur = numEntri; indexCur >0; indexCur--) {\r
+ _SeqRDFC_data.RemoveElementAt(indexCur,true);\r
+ }\r
+ }\r
+ }catch(e){\r
+ gConsole.logStringMessage("[ximfmail - DialogTreeRDFClass ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
+ };\r
+ //\r
+ DialogTreeRDFClass.prototype.updateDisplay = function(curpos,maxPos) {\r
+ var colFoundArray = [];\r
+ var maxEntry = _RdfDataSourceOrigin.getEntriesCount();\r
+ if(curpos+maxPos > maxEntry) {\r
+ curpos = maxEntry-maxPos;\r
+ }\r
+ colFoundArray = _RdfDataSourceOrigin.getEntryByPos(curpos, maxPos);\r
+ this.removeAllDisplay();\r
+ for(var currItem=0;currItem<colFoundArray.length;currItem++) {\r
+ this.addEntryDisplay(colFoundArray[currItem], currItem);\r
+ }\r
+ $("#ximfmail.treedialog").attr("hidevscroll","true");\r
+ };\r
+ DialogTreeRDFClass.prototype.updateDisplayByText = function(textToFind,maxPos,curpos) {\r
+ var colFoundArray = [];\r
+ var index = _indexAZ[textToFind[0].toUpperCase()];\r
+ if(index === -1) {\r
+ return -1;\r
+ }\r
+ if(textToFind.length === 1) {\r
+ if(index===curpos){\r
+ return -1;\r
+ }\r
+ this.updateDisplay(index,maxPos);\r
+ return index;\r
+ }\r
+ var maxEntry = _RdfDataSourceOrigin.getEntriesCount();\r
+ if(index+maxPos > maxEntry){\r
+ index = maxEntry-maxPos-1;\r
+ }\r
+ var result = _RdfDataSourceOrigin.getEntryByText(textToFind, maxPos, index);\r
+ colFoundArray = result[0];\r
+ if(colFoundArray.length === 0){\r
+ return -1;\r
+ }\r
+ this.removeAllDisplay();\r
+ for(var currItem=0;currItem<colFoundArray.length;currItem++) {\r
+ this.addEntryDisplay(colFoundArray[currItem], currItem);\r
+ }\r
+ $("#ximfmail.treedialog").attr("hidevscroll","true");\r
+ return result[1];\r
+ };\r
+ //\r
+ DialogTreeRDFClass.prototype.getMaxEntry = function() {\r
+ var remoteCount = 0;\r
+ remoteCount = _RdfDataSourceOrigin.getEntriesCount();\r
+ return remoteCount;\r
+ };\r
+ // object initialisation\r
+ DialogTreeRDFClass.initialized = true;\r
+ }\r
}
\ No newline at end of file
/* ***** BEGIN LICENSE BLOCK *****\r
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
*\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
* are permitted provided that the following conditons are met :\r
*\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
* in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
* prior written permission from EADS Defence and Security.\r
- * \r
+ *\r
* Alternatively, the contents of this file may be used under the terms of\r
* either of the GNU General Public License Version 2 or later (the "GPL"),\r
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
* and other provisions required by the GPL or the LGPL. If you do not delete\r
* the provisions above, a recipient may use your version of this file under\r
* the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
+ *\r
* REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ *\r
+ * Contributor(s):\r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
* ***** END LICENSE BLOCK ***** */\r
-\r
var gJSLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].createInstance(Components.interfaces.mozIJSSubScriptLoader);\r
var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);\r
- \r
-\r
var gDlgTreeXimf_maxItem_alert = "";\r
var gDlgTreeXimf_current_selection = null;\r
var gDlgTreeXimf_current_separator = null;\r
var gTitleDlg = "";\r
-\r
-function XimfDataSource(){\r
- this._id; // xml file name path\r
- this._dataSource;\r
- this._refDataSource; \r
-}\r
-\r
// RDF list\r
var gMaxDataList = 15;\r
var gCurposList = -1;\r
var gIDTimeoutListSearch = null;\r
var gSearchText = "";\r
var gRDFList = null;\r
-\r
-\r
var gArgsOpener = null;\r
-\r
$(document).ready(function(){\r
var gArgs = window.arguments;\r
- if(gArgs[0].length <= 0) return;\r
-\r
+ if(gArgs[0].length <= 0) {\r
+ return;\r
+ }\r
// load event manager\r
$("#ximfmail_dTreeAdd").bind("command",OnPushAddSelection);\r
$("#iTreechildDialog").dblclick(OnPushAddSelection);\r
$("#ximfmail_dTreeDel").bind("command",OnPushDelSelection);\r
$("#ximfmail_dTreeRaz").bind("command",OnPushRazSelection);\r
- \r
- // event for scroll \r
+ // event for scroll\r
$("#ximfmailTreeDialogScroll").mousemove(OnClickScrollTreeList);\r
$("#ximfmailTreeDialogScroll").click(OnClickScrollTreeList);\r
$("#iTreechildDialog").mousemove(OnClickScrollTreeList);\r
$(window).resize(OnClickScrollTreeList);\r
- \r
document.getElementById("iTreechildDialog").addEventListener('DOMMouseScroll', OnScrollTreeList, false);\r
$("#ximfmail.treedialog").keypress(OnKeyPressScrollTreeList);\r
$("#ximfmailTreeDialogDisplaybox").keypress(OnKeyPressScrollTreeList);\r
- \r
// load background datas\r
try{\r
- gArgsOpener = gArgs[0]; // gArgs[0] is an XimfmailTreedialogArgs object - XimfmailTreedialogArgs class description at ximfmail.js file\r
+ // gArgs[0] is an XimfmailTreedialogArgs object - XimfmailTreedialogArgs class description at ximfmail.js file\r
+ gArgsOpener = gArgs[0];\r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - ready ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
return;\r
}\r
- \r
- // create alert message \r
+ // create alert message\r
if(parseInt(gArgsOpener.maxItemsSelected, 10) > 1){\r
gDlgTreeXimf_maxItem_alert = gArgsOpener.maxItemsSelected + " "+ getIlkProperties("ximfmail.dialog.editor.warning.nbrows");\r
}else{\r
- if(parseInt(gArgsOpener.maxItemsSelected, 10) == 1){\r
+ if(parseInt(gArgsOpener.maxItemsSelected, 10) === 1){\r
gDlgTreeXimf_maxItem_alert = gArgsOpener.maxItemsSelected + " "+ getIlkProperties("ximfmail.dialog.editor.warning.nbrows.one");\r
}\r
}\r
- \r
try{\r
- //set main title \r
- var sTitle = gArgsOpener.title; \r
- if(sTitle.indexOf(":") != -1){\r
+ //set main title\r
+ var sTitle = gArgsOpener.title;\r
+ if(sTitle.indexOf(":") !== -1){\r
sTitle = sTitle.substring(0,sTitle.lastIndexOf(":"));\r
- } \r
+ }\r
$("#treeDialogHeader").attr("title",sTitle);\r
$("#treeDialogHeader").attr("description",gDlgTreeXimf_maxItem_alert);\r
- \r
//set title columns\r
$("#iCol0").attr("label",gArgsOpener.titleColKey);\r
$("#iCol1").attr("label",gArgsOpener.titleColLabel);\r
- \r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - AddCurrentSelection ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);\r
}\r
- \r
- LoadXmlDatas(); \r
+ LoadXmlDatas();\r
});\r
-\r
/*\r
* attach RDF Source to local tree\r
*/\r
function LoadXmlDatas(){\r
- try{ \r
+ try{\r
//\r
- var tree = document.getElementById("iTreechildDialog"); \r
- \r
+ var tree = document.getElementById("iTreechildDialog");\r
gRDFList = new DialogTreeRDFClass();\r
- gRDFList.initialize(gArgsOpener.dataSource, gArgsOpener.refdataSource);\r
- \r
- tree.database.AddDataSource(gRDFList.getDataSource()); \r
- //tree.setAttribute("ref",gArgsOpener.refdataSource); \r
+ gRDFList.initialize(gArgsOpener.dataSource, gArgsOpener.refdataSource);\r
+ tree.database.AddDataSource(gRDFList.getDataSource());\r
tree.builder.rebuild();\r
- \r
OnClickScrollTreeList(0);\r
- \r
- //\r
AddCurrentSelection();\r
- }catch(e){ \r
+ }catch(e){\r
gConsole.logStringMessage("[ximfmail - LoadXmlDatas ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
- } \r
+ }\r
}\r
-\r
function AddCurrentSelection(){\r
// load current selected values\r
if(gArgsOpener.currentKeys.length > 0){\r
- /*var reg = null; \r
- if(gDlgTreeXimf_current_separator){\r
- reg=new RegExp("["+gDlgTreeXimf_current_separator+"]+", "g"); \r
- }else{\r
- reg=new RegExp("[;,]+", "g");\r
- }\r
- var arrayItems = gDlgTreeXimf_current_selection.split(reg); \r
- */\r
var list = document.getElementById("ximfmail_selection");\r
for (var i=0; i<gArgsOpener.currentKeys.length; i++) {\r
- if(gArgsOpener.currentLabels[i]!=""){\r
+ if(gArgsOpener.currentLabels[i]!==""){\r
var item = list.appendItem(gArgsOpener.currentKeys[i]);\r
- if(gArgsOpener.currentKeys[i]!=""){\r
+ if(gArgsOpener.currentKeys[i]!==""){\r
item.setAttribute("tooltiptext",gArgsOpener.currentLabels[i]);\r
}\r
- } \r
+ }\r
}\r
- } \r
+ }\r
}\r
-\r
function OnPushAddSelection(){\r
- try{ \r
+ try{\r
var tree = document.getElementById("ximfmail.treedialog");\r
var list = document.getElementById("ximfmail_selection");\r
var start = new Object();\r
var end = new Object();\r
var numRanges = tree.view.selection.getRangeCount();\r
- \r
- \r
for (var t=0; t<numRanges; t++){\r
tree.view.selection.getRangeAt(t,start,end);\r
- for (var v=start.value; v<=end.value; v++){ \r
- if(gArgsOpener.maxItemsSelected){ \r
- var nbItems = $("#ximfmail_selection listitem"); \r
- if(nbItems.length >= gArgsOpener.maxItemsSelected){\r
- ximfAlert(gDlgTreeXimf_maxItem_alert); \r
- return;\r
- }\r
- } \r
- var item = list.appendItem(tree.view.getCellText(v, tree.columns.getColumnAt(0))); //list.appendItem(label,value)\r
- item.tooltipText=tree.view.getCellText(v, tree.columns.getColumnAt(1));\r
+ for (var v=start.value; v<=end.value; v++){\r
+ if(gArgsOpener.maxItemsSelected){\r
+ var nbItems = $("#ximfmail_selection listitem");\r
+ if(nbItems.length >= gArgsOpener.maxItemsSelected){\r
+ ximfAlert(gDlgTreeXimf_maxItem_alert);\r
+ return;\r
+ }\r
+ }\r
+ var item = list.appendItem(tree.view.getCellText(v, tree.columns.getColumnAt(0))); //list.appendItem(label,value)\r
+ item.tooltipText=tree.view.getCellText(v, tree.columns.getColumnAt(1));\r
}\r
}\r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - OnPushAddSelection ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
}\r
}\r
-\r
function OnPushDelSelection(){\r
var list = document.getElementById("ximfmail_selection");\r
list.removeItemAt( list.selectedIndex );\r
}\r
-\r
function OnPushRazSelection(){\r
var list = document.getElementById("ximfmail_selection");\r
- var count = $("#ximfmail_selection listitem"); \r
+ var count = $("#ximfmail_selection listitem");\r
for(var i=count.length; i>0; --i){\r
list.removeItemAt(i-1);\r
}\r
}\r
-\r
-\r
-\r
function doOK(){\r
- // get current selection \r
- var list = $("#ximfmail_selection listitem"); \r
+ // get current selection\r
+ var list = $("#ximfmail_selection listitem");\r
for(var idx_list = 0; idx_list < list.length;++idx_list){\r
var currentItem = list[idx_list].getAttribute("label");\r
var currentTooltip = list[idx_list].getAttribute("tooltiptext");\r
- if(currentItem != ""){\r
- gArgsOpener.retKeys.push(currentItem); \r
+ if(currentItem !== ""){\r
+ gArgsOpener.retKeys.push(currentItem);\r
gArgsOpener.retLabels.push(currentTooltip);\r
}\r
- } \r
+ }\r
return true;\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
function doCancel()\r
{\r
- gArgsOpener.retIsCancel=true; \r
+ gArgsOpener.retIsCancel=true;\r
}\r
-\r
function getTreeSelection(){\r
var list="";\r
var tree = document.getElementById("ximfmail.treedialog");\r
var start = new Object();\r
var end = new Object();\r
var numRanges = tree.view.selection.getRangeCount();\r
-\r
for (var t=0; t<numRanges; t++){\r
tree.view.selection.getRangeAt(t,start,end);\r
for (var v=start.value; v<=end.value; v++){\r
- if(list!="")\r
+ if (list!=="") {\r
list+=",";\r
+ }\r
list += tree.view.getCellText(v, tree.columns.getColumnAt(0));\r
}\r
}\r
return list;\r
}\r
-\r
-\r
-\r
-\r
-///BEGIN TEST\r
function OnSelectTreeData(evt){\r
- //alert("OnSelectTreeData");\r
var elt = evt.currentTarget;\r
- //var tree = document.getElementById("ximfmail.tree");\r
if(elt.view){\r
- //alert("index = " + elt.view.selection.currentIndex);\r
- \r
// on select\r
var cellIndex = 0;\r
var cellText = elt.view.getCellText(elt.currentIndex, elt.columns.getColumnAt(cellIndex));\r
- //alert("cellText: "+cellText);\r
- } \r
- \r
+ }\r
var row = new Object();\r
var col = new Object();\r
var child = new Object();\r
- \r
- //elt.firstChild.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, child);\r
- elt.treeBoxObject.getCellAt(evt.clientX, evt.clientY, row, col, child);\r
+ elt.treeBoxObject.getCellAt(evt.clientX, evt.clientY, row, col, child);\r
var idMatch;\r
try {\r
idMatch = col.value.element.getAttribute('id');\r
} catch (error) {\r
idMatch = col.value;\r
}\r
- //alert(row.value + " : " + idMatch);\r
- //return {row: row.value, col: idMatch}; \r
}\r
-\r
function OnClickTreeData(evt){\r
- //alert("OnSelectTreeData");\r
- var elt = evt.currentTarget; \r
+ var elt = evt.currentTarget;\r
var row = new Object();\r
var col = new Object();\r
var child = new Object();\r
- //elt.firstChild.treeBoxObject.getCellAt(event.clientX, event.clientY, row, col, child);\r
elt.treeBoxObject.getCellAt(evt.clientX, evt.clientY, row, col, child);\r
var idMatch;\r
try {\r
} catch (error) {\r
idMatch = col.value;\r
}\r
- //alert(row.value + " : " + idMatch);\r
- //return {row: row.value, col: idMatch}; \r
}\r
-\r
-\r
/* for to scroll */\r
function OnClickScrollTreeList(evt)\r
{\r
- try\r
- {\r
- if(parseInt($("#ximfmailTreeDialogScroll").attr("maxpos"), 10) <=0)\r
- return;\r
+ try {\r
+ if (parseInt($("#ximfmailTreeDialogScroll").attr("maxpos"), 10) <=0) {\r
+ return;\r
+ }\r
var treeResult = document.getElementById("ximfmail.treedialog");\r
$("#iTreechildDialog").attr("hidevscroll","true");\r
var curpos = 0;\r
- \r
curpos = parseInt($("#ximfmailTreeDialogScroll").attr("curpos"), 10);\r
var pageLength = gMaxDataList;\r
try{\r
- pageLength = treeResult.boxObject.getPageLength();\r
- if(0 == pageLength)\r
- pageLength = gMaxDataList;\r
- }catch(e){pageLength = gMaxDataList;}\r
- \r
- /*gConsole.logStringMessage("gCurposList=" + gCurposList + " curpos=" + curpos+ " gMaxDataList=" + gMaxDataList\r
- + " pageLength=" + pageLength+ " gRDFList.getEntriesCount()=" + gRDFList.getEntriesCount());*/\r
- \r
- if(gCurposList != curpos || gMaxDataList != pageLength \r
- || gMaxDataList != gRDFList.getEntriesCount()\r
- || evt == 0)\r
- {\r
+ pageLength = treeResult.boxObject.getPageLength();\r
+ if (0 === pageLength) {\r
+ pageLength = gMaxDataList;\r
+ }\r
+ }catch(e){\r
+ pageLength = gMaxDataList;\r
+ }\r
+ if(gCurposList !== curpos || gMaxDataList !== pageLength || gMaxDataList !== gRDFList.getEntriesCount() || evt === 0) {\r
window.setCursor("wait");\r
gMaxDataList = pageLength;\r
var maxEntry = parseInt(gRDFList.getMaxEntry(), 10);\r
- \r
gRDFList.updateDisplay(curpos,gMaxDataList-1);\r
var maxpos = gMaxDataList;\r
- \r
- if(maxEntry - gMaxDataList >= 0)\r
+ if(maxEntry - gMaxDataList >= 0) {\r
maxpos = maxEntry - gMaxDataList;\r
- else\r
+ } else {\r
maxpos = -1;\r
- \r
- if(maxEntry < gMaxDataList)\r
- gMaxDataList = maxEntry;\r
+ }\r
+ if (maxEntry < gMaxDataList) {\r
+ gMaxDataList = maxEntry;\r
+ }\r
$("#ximfmailTreeDialogScroll").attr("maxpos",maxpos);\r
- \r
gCurposList = curpos;\r
- \r
- if(maxEntry == 0 || maxpos <= 0) \r
- {\r
+ if(maxEntry === 0 || maxpos <= 0) {\r
$("#ximfmailTreeDialogScroll").attr("hidden","true");\r
gMaxDataList = maxEntry;\r
- }\r
- else\r
+ } else {\r
$("#ximfmailTreeDialogScroll").removeAttr("hidden");\r
- \r
- if(treeResult.database != null)\r
- {\r
+ }\r
+ if(treeResult.database !== null) {\r
treeResult.database.AddDataSource(gRDFList.getDataSource());\r
treeResult.builder.rebuild();\r
clearTimeout(gIDTimeoutList);\r
}\r
window.setCursor("auto");\r
}\r
-\r
function OnScrollTreeList(event)\r
{\r
window.setCursor("wait");\r
- try\r
- {\r
+ try {\r
var curpos = parseInt($("#ximfmailTreeDialogScroll").attr("curpos"), 10);\r
var addPos = 0;\r
- if(event.detail == -3)\r
+ if(event.detail === -3) {\r
addPos = -3;\r
- else if(event.detail == 3)\r
+ } else if (event.detail === 3) {\r
addPos = 3;\r
+ }\r
curpos += addPos;\r
var maxpos = parseInt(gRDFList.getMaxEntry(), 10) - gMaxDataList;\r
- \r
- if(curpos<0)\r
+ if (curpos<0) {\r
curpos = 0;\r
- if(curpos>maxpos)\r
+ }\r
+ if (curpos>maxpos) {\r
curpos = maxpos;\r
- \r
+ }\r
$("#ximfmailTreeDialogScroll").attr("curpos", curpos);\r
OnClickScrollTreeList(0);\r
}\r
}\r
window.setCursor("auto");\r
}\r
-\r
function OnKeyPressScrollTreeList(event)\r
{\r
window.setCursor("wait");\r
var maxEntry = parseInt(gRDFList.getMaxEntry(), 10);\r
var maxpos = maxEntry - gMaxDataList;\r
var textToFind = "";\r
- \r
switch(event.keyCode)\r
{\r
case 33:\r
// page up\r
addPos = 1-gMaxDataList;\r
break;\r
- \r
case 34:\r
// page down\r
addPos = gMaxDataList-1;\r
break;\r
- \r
case 35:\r
// end\r
addPos = 0;\r
curpos = maxpos;\r
break;\r
- \r
case 36:\r
// beggin\r
addPos = 0;\r
curpos = 0;\r
- break; \r
- \r
+ break;\r
case 38:\r
// up\r
addPos = -1;\r
break;\r
- \r
case 40:\r
// down\r
addPos = 1;\r
break;\r
- \r
default:\r
- if(event.charCode ==0)\r
+ if(event.charCode === 0)\r
{\r
window.setCursor("auto");\r
return;\r
}\r
- else\r
+ else {\r
textToFind = String.fromCharCode(event.charCode);\r
+ }\r
}\r
- \r
- if("" == textToFind)\r
+ if("" === textToFind)\r
{\r
curpos += addPos;\r
- \r
- if(curpos<0)\r
+ if(curpos<0) {\r
curpos = 0;\r
- if(curpos>maxpos)\r
+ }\r
+ if(curpos>maxpos) {\r
curpos = maxpos;\r
- \r
+ }\r
$("#ximfmailTreeDialogScroll").attr("curpos", curpos);\r
OnClickScrollTreeList(0);\r
}\r
clearTimeout(gIDTimeoutListSearch);\r
gSearchText += textToFind;\r
var curposAfter = gRDFList.updateDisplayByText(gSearchText,gMaxDataList,curpos);\r
- if(curposAfter == -1)\r
+ if(curposAfter === -1)\r
{\r
gSearchText = "";\r
window.setCursor("auto");\r
else\r
{\r
var maxpos = gMaxDataList;\r
- if(maxEntry - gMaxDataList >= 0)\r
+ if(maxEntry - gMaxDataList >= 0){\r
maxpos = maxEntry - gMaxDataList;\r
- else\r
+ } else {\r
maxpos = -1;\r
- \r
- if(maxEntry < gMaxDataList)\r
+ }\r
+\r
+ if(maxEntry < gMaxDataList) {\r
gMaxDataList = maxEntry;\r
- \r
+ }\r
$("#ximfmailTreeDialogScroll").attr("maxpos",maxpos);\r
$("#ximfmailTreeDialogScroll").attr("curpos", curposAfter);\r
OnClickScrollTreeList(0);\r
- \r
+\r
gIDTimeoutListSearch = setTimeout(resetSearchText,2000);\r
}\r
}\r
- \r
}\r
catch(e)\r
{\r
}\r
window.setCursor("auto");\r
}\r
-\r
function resetSearchText()\r
{\r
gSearchText = "";\r
<!-- ***** BEGIN LICENSE BLOCK *****\r
- Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
- ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- - \r
-\r
- - Redistribution and use, in source and binary forms, with or without modification, \r
+ -\r
+ - Redistribution and use, in source and binary forms, with or without modification,\r
- are permitted provided that the following conditons are met :\r
-\r
- - 1. Redistributions of source code must retain the above copyright notice, \r
- - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ - 1. Redistributions of source code must retain the above copyright notice,\r
+ - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
- in the redistribution of the source code.\r
- - 3. Neither the names of the copyright holders nor the names of any contributors \r
- - may be used to endorse or promote products derived from this software without specific \r
+ - 3. Neither the names of the copyright holders nor the names of any contributors\r
+ - may be used to endorse or promote products derived from this software without specific\r
- prior written permission from EADS Defence and Security.\r
- - \r
+ -\r
- Alternatively, the contents of this file may be used under the terms of\r
- either of the GNU General Public License Version 2 or later (the "GPL"),\r
- or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
- and other provisions required by the GPL or the LGPL. If you do not delete\r
- the provisions above, a recipient may use your version of this file under\r
- the terms of any one of the MPL, the GPL or the LGPL.\r
- - \r
+ -\r
- REMINDER :\r
- - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
- IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- - \r
- - EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ -\r
+ - EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ - \r
+ - Contributor(s):\r
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved \r
- ***** END LICENSE BLOCK ***** -->\r
\r
<!DOCTYPE overlay SYSTEM "chrome://ximfmail/locale/ximfmail.dtd">\r
<?xml-stylesheet href="chrome://global/skin/global.css" type="text/css"?>\r
\r
<!-- onload="window.sizeToContent();" -->\r
-<dialog id="treedialog" title="" \r
- xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" \r
- buttons="accept,cancel" \r
+<dialog id="treedialog" title=""\r
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"\r
+ buttons="accept,cancel"\r
buttonlabelcancel="&treedialog.buttonlabelcancel;"\r
buttonlabelaccept="&treedialog.buttonlabelaccept;"\r
ondialogaccept="return doOK();"\r
ondialogcancel="return doCancel();">\r
- <script type="application/javascript" src="chrome://ximfmail/content/jquery.js" /> \r
- <script type="application/javascript" src="chrome://ximfmail/content/ximfmail.js" /> \r
- <script type="application/javascript" src="chrome://ximfmail/content/constant-ximfmail.js" /> \r
- <script type="application/javascript" src="chrome://ximfmail/content/dialogTree-ximfmail.js" /> \r
+ <script type="application/javascript" src="chrome://ximfmail/content/jquery.js" />\r
+ <script type="application/javascript" src="chrome://ximfmail/content/ximfmail.js" />\r
+ <script type="application/javascript" src="chrome://ximfmail/content/constant-ximfmail.js" />\r
+ <script type="application/javascript" src="chrome://ximfmail/content/dialogTree-ximfmail.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/dialogTree-rdf-ximfmail.js" />\r
- \r
- <hbox id="ximfmailTreeDialogBox" flex="1" style="height:400px; width:800px;"> \r
- <hbox id="ximfmailTreeDialogDisplaybox" flex="1"> \r
- <tree id="ximfmail.treedialog" flex="1" enableColumnDrag="true" \r
+\r
+ <hbox id="ximfmailTreeDialogBox" flex="1" style="height:400px; width:800px;">\r
+ <hbox id="ximfmailTreeDialogDisplaybox" flex="1">\r
+ <tree id="ximfmail.treedialog" flex="1" enableColumnDrag="true"\r
flags="dont-build-content">\r
- <treecols> \r
+ <treecols>\r
<treecol id="iCol0" label="&ximfmail.dialogtree.title.col0;" primary="true" persist="hidden ordinal width sortDirection" flex="1"/>\r
<splitter class="tree-splitter"/>\r
<treecol id="iCol1" label="&ximfmail.dialogtree.title.col1;" persist="hidden ordinal width sortDirection" flex="2" />\r
- <splitter class="tree-splitter"/> \r
- </treecols> \r
+ <splitter class="tree-splitter"/>\r
+ </treecols>\r
<treechildren flex="1"\r
id="iTreechildDialog"\r
datasources="rdf:null"\r
</template>\r
</treechildren>\r
</tree>\r
- <scrollbar id="ximfmailTreeDialogScroll" curpos="0" maxpos="50" orient="vertical" /> \r
+ <scrollbar id="ximfmailTreeDialogScroll" curpos="0" maxpos="50" orient="vertical" />\r
</hbox>\r
<vbox id="ximfmailTreeDialogButtonbox">\r
<spacer flex="1"/>\r
<button id="ximfmail_dTreeAdd" image="chrome://ximfmail/content/resource/arrow_right.png" tooltiptext="add selection"/>\r
<button id="ximfmail_dTreeDel" image="chrome://ximfmail/content/resource/arrow_left.png" tooltiptext="delete item" />\r
- <button id="ximfmail_dTreeRaz" image="chrome://ximfmail/content/resource/clear_right_list.png" tooltiptext="delete complete selection"/> \r
+ <button id="ximfmail_dTreeRaz" image="chrome://ximfmail/content/resource/clear_right_list.png" tooltiptext="delete complete selection"/>\r
<spacer flex="1"/>\r
</vbox>\r
- <listbox id="ximfmail_selection" style="width:200px;"> \r
- </listbox> \r
+ <listbox id="ximfmail_selection" style="width:200px;">\r
+ </listbox>\r
</hbox>\r
-</dialog>
\ No newline at end of file
+</dialog>
\ No newline at end of file
-\r
/* ***** BEGIN LICENSE BLOCK *****\r
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
*\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
* are permitted provided that the following conditons are met :\r
*\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
* in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
* prior written permission from EADS Defence and Security.\r
- * \r
+ *\r
* Alternatively, the contents of this file may be used under the terms of\r
* either of the GNU General Public License Version 2 or later (the "GPL"),\r
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
* and other provisions required by the GPL or the LGPL. If you do not delete\r
* the provisions above, a recipient may use your version of this file under\r
* the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
+ *\r
* REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
* ***** END LICENSE BLOCK ***** */\r
var gJSLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].createInstance(Components.interfaces.mozIJSSubScriptLoader);\r
var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);\r
gJSLoader.loadSubScript("chrome://ximfmail/content/jquery.js");\r
gJSLoader.loadSubScript("chrome://ximfmail/content/ximfmail.js");\r
-\r
var gBoxOpener = null;\r
var gXimfMaxItems = null;\r
var gXimfMinItems = null;\r
var gXimfSeparator = null;\r
var gCurrentText = null;\r
-var gEditorElt = null; //textbox elment\r
+var gEditorElt = null;\r
var gTitleDlg = null;\r
var gDlgEditorXimf_maxItem_alert = "";\r
-\r
/*\r
window.arguments = [];\r
- args[0] id of textbox \r
+ args[0] id of textbox\r
args[1] text\r
- args[2] separator value \r
+ args[2] separator value\r
args[3] max items to write\r
args[4] min items to write\r
*/\r
-$(document).ready(function(){ \r
+$(document).ready(function(){\r
var gArgs = window.arguments;\r
- if(gArgs[0].length < 5){ \r
- ximfAlert("error nbargs = "+gArgs[0].length)\r
- return;} \r
- \r
+ if(gArgs[0].length < 5){\r
+ ximfAlert("error nbargs = "+gArgs[0].length);\r
+ return;\r
+ }\r
// load background datas\r
gBoxOpener = gArgs[0][0];\r
gCurrentText = gArgs[0][1];\r
gXimfSeparator = gArgs[0][2];\r
gXimfMaxItems = gArgs[0][3];\r
- gXimfMinItems = gArgs[0][4]; \r
+ gXimfMinItems = gArgs[0][4];\r
gTitleDlg = gArgs[0][5];\r
- //\r
- gEditorElt = document.getElementById("textbox-editor"); \r
- gConsole.logStringMessage("[ximfmail - dialogEditor ] \n id of textbox :" + gArgs[0][0] + "\n separator value: " + gArgs[0][2] + "\n max items to write: "+ gArgs[0][3] + "\n min items to write: " +gArgs[0][4]); \r
- \r
+ gEditorElt = document.getElementById("textbox-editor");\r
+ gConsole.logStringMessage("[ximfmail - dialogEditor ] \n id of textbox :" + gArgs[0][0] + "\n separator value: " + gArgs[0][2] + "\n max items to write: "+ gArgs[0][3] + "\n min items to write: " +gArgs[0][4]);\r
if(parseInt(gXimfMaxItems, 10) > 1){\r
- gDlgEditorXimf_maxItem_alert = gXimfMaxItems + " "+ getIlkProperties("ximfmail.dialog.editor.warning.nbrows"); \r
+ gDlgEditorXimf_maxItem_alert = gXimfMaxItems + " "+ getIlkProperties("ximfmail.dialog.editor.warning.nbrows");\r
$("#textbox-editor").attr("style","width:400px;height:100px");\r
- }else{ \r
+ }else{\r
gDlgEditorXimf_maxItem_alert = gXimfMaxItems + "1 "+ getIlkProperties("ximfmail.dialog.editor.warning.nbrows.one");\r
$("#textbox-editor").attr("maxrows","1");\r
}\r
RefreshEditor();\r
- \r
// event observer\r
- $("#textbox-editor").keypress(onCheck); \r
-}); \r
-\r
+ $("#textbox-editor").keypress(onCheck);\r
+});\r
/*\r
- * \r
+ *\r
*/\r
function doOK()\r
{\r
- if(!gEditorElt) return false;\r
- if(gXimfMinItems){\r
+ if (!gEditorElt) {\r
+ return false;\r
+ }\r
+ if(gXimfMinItems){\r
if( getWritedRowsCount() < parseInt(gXimfMinItems, 10)){\r
ximfAlert("not enough item");\r
}\r
}\r
- \r
var newvalue = "";\r
- if(!gXimfSeparator){ \r
- newvalue = gEditorElt.value; \r
- }else{ \r
+ if(!gXimfSeparator){\r
+ newvalue = gEditorElt.value;\r
+ }else{\r
var reg=new RegExp("\n", "g");\r
- //newvalue = gEditorElt.value.replace(reg , gXimfSeparator);\r
- var arrayValue = gEditorElt.value.split(reg); \r
+ var arrayValue = gEditorElt.value.split(reg);\r
var nbElements = arrayValue.length;\r
if(parseInt(gXimfMaxItems, 10)<arrayValue.length){\r
nbElements = parseInt(gXimfMaxItems, 10);\r
ximfAlert(gDlgEditorXimf_maxItem_alert);\r
- } \r
+ }\r
for(var i=0 ; i<nbElements ; ++i){\r
- if(arrayValue[i]!=""){\r
- if(i==0)\r
+ if(arrayValue[i] !== ""){\r
+ if (i === 0) {\r
newvalue = arrayValue[i];\r
- else\r
- newvalue += gXimfSeparator + arrayValue[i]; \r
- } \r
+ } else {\r
+ newvalue += gXimfSeparator + arrayValue[i];\r
+ }\r
+ }\r
}\r
}\r
- \r
- \r
- //remove last separator \r
- if(newvalue.lastIndexOf(gXimfSeparator)+1 == newvalue.length){\r
+ //remove last separator\r
+ if(newvalue.lastIndexOf(gXimfSeparator)+1 === newvalue.length){\r
newvalue = newvalue.substring(0,newvalue.lastIndexOf(gXimfSeparator));\r
- } \r
- \r
+ }\r
window.opener.document.getElementById(gBoxOpener).value = newvalue;\r
- window.opener.document.getElementById(gBoxOpener).setAttribute("ximfvalue", newvalue); \r
+ window.opener.document.getElementById(gBoxOpener).setAttribute("ximfvalue", newvalue);\r
window.opener.document.getElementById(gBoxOpener).setAttribute("tooltiptext", newvalue);\r
return true;\r
}\r
-\r
-\r
function doCancel()\r
{\r
return true;\r
}\r
-\r
-\r
/*\r
- * \r
+ *\r
*/\r
function onCheck(aEvent){\r
- if(!gEditorElt) return false;\r
- var key = aEvent.which; \r
+ if (!gEditorElt) {\r
+ return false;\r
+ }\r
+ var key = aEvent.which;\r
switch(key){\r
- case 13: // key=="\n" \r
- if( getWritedRowsCount() >= parseInt(gXimfMaxItems, 10)){\r
- ximfAlert(gDlgEditorXimf_maxItem_alert); \r
+ case 13: // key==="\n"\r
+ if ( getWritedRowsCount() >= parseInt(gXimfMaxItems, 10)) {\r
+ ximfAlert(gDlgEditorXimf_maxItem_alert);\r
var reg = new RegExp("\n", "g");\r
var artxt = gEditorElt.value.split(reg);\r
var newText = "";\r
for(var i=0 ; i < gXimfMaxItems; ++i){\r
if(i < artxt.length){\r
- if(gXimfMaxItems-1 == i){\r
+ if(gXimfMaxItems-1 === i){\r
newText += artxt[i];\r
}else{\r
newText += artxt[i] + "\n";\r
}\r
}\r
}\r
- gEditorElt.value = newText; \r
+ gEditorElt.value = newText;\r
}\r
case 8: // backspace\r
case 0: // delete\r
break;\r
default:\r
if( getWritedRowsCount() > parseInt(gXimfMaxItems, 10)){\r
- ximfAlert(gDlgEditorXimf_maxItem_alert); \r
+ ximfAlert(gDlgEditorXimf_maxItem_alert);\r
return false;\r
}\r
}\r
- /*\r
- // check for entries items\r
- if(key == 13){ // key=="\n" \r
- if( getWritedRowsCount() >= parseInt(gXimfMaxItems, 10)){\r
- alert(gDlgEditorXimf_maxItem_alert); \r
- var reg = new RegExp("\n", "g");\r
- var artxt = gEditorElt.value.split(reg);\r
- var newText = "";\r
- for(var i=0 ; i < gXimfMaxItems; ++i){\r
- if(i < artxt.length){\r
- if(gXimfMaxItems-1 == i){\r
- newText += artxt[i];\r
- }else{\r
- newText += artxt[i] + "\n";\r
- }\r
- }\r
- }\r
- gEditorElt.value = newText; \r
- }\r
- }\r
- else{\r
- if( getWritedRowsCount() > parseInt(gXimfMaxItems, 10)){\r
- alert(gDlgEditorXimf_maxItem_alert); \r
- return false;\r
- }\r
- }*/\r
return true;\r
}\r
-\r
function getWritedRowsCount(){\r
var nblines = 0;\r
var reg=new RegExp("\n", "g");\r
var nbvalue = gEditorElt.value.split(reg);\r
return nbvalue.length;\r
}\r
-/*\r
- * \r
- */\r
function RefreshEditor(){\r
- if(!gEditorElt) return;\r
-\r
+ if(!gEditorElt) {\r
+ return;\r
+ }\r
// title box\r
- $("#editorDialogHeader").attr("title",gTitleDlg); \r
+ $("#editorDialogHeader").attr("title",gTitleDlg);\r
$("#editorDialogHeader").attr("description",gDlgEditorXimf_maxItem_alert);\r
- \r
// text value\r
if(!gXimfSeparator){\r
gEditorElt.setAttribute("multiline","false");\r
- gEditorElt.value = gCurrentText; \r
+ gEditorElt.value = gCurrentText;\r
}else{\r
- try{ \r
+ try{\r
gEditorElt.setAttribute("multiline","true");\r
- if(gCurrentText){ \r
- var reg=new RegExp(gXimfSeparator, "g"); \r
- var multitxt = gCurrentText.replace(reg , "\n"); \r
- //gEditorElt.setAttribute("value",multitxt+"\n");\r
+ if(gCurrentText){\r
+ var reg=new RegExp(gXimfSeparator, "g");\r
+ var multitxt = gCurrentText.replace(reg , "\n");\r
gEditorElt.setAttribute("value",multitxt);\r
- } \r
+ }\r
}catch(e){\r
- gConsole.logStringMessage("[ximfmail - RefreshEditor ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber); \r
- } \r
+ gConsole.logStringMessage("[ximfmail - RefreshEditor ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);\r
+ }\r
}\r
}
\ No newline at end of file
- Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
- ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- \r
- -\r
- Redistribution and use, in source and binary forms, with or without modification, \r
- are permitted provided that the following conditons are met :\r
-\r
- IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- \r
- EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ - \r
+ - Contributor(s):\r
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
- ***** END LICENSE BLOCK ***** -->\r
\r
<!DOCTYPE overlay SYSTEM "chrome://ximfmail/locale/ximfmail.dtd">\r
/* ***** BEGIN LICENSE BLOCK *****
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.
- *
*
- * Redistribution and use, in source and binary forms, with or without modification,
+ *
+ * Redistribution and use, in source and binary forms, with or without modification,
* are permitted provided that the following conditons are met :
*
- * 1. Redistributions of source code must retain the above copyright notice,
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached
* in the redistribution of the source code.
- * 3. Neither the names of the copyright holders nor the names of any contributors
- * may be used to endorse or promote products derived from this software without specific
+ * 3. Neither the names of the copyright holders nor the names of any contributors
+ * may be used to endorse or promote products derived from this software without specific
* prior written permission from EADS Defence and Security.
- *
+ *
* Alternatively, the contents of this file may be used under the terms of
* either of 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"),
* 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.
- *
+ *
* REMINDER :
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * EADS Defence and Security - 1 Boulevard Jean Moulin -
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)
+ *
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)
* ***** END LICENSE BLOCK ***** */
var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
-
-
/**
Get message source
@param {nsIMsgDBHdr} header
@return {string} Message source or <b>false</b> if an error occurs
*/
function XimfmailGetMessage(mailUri, callbackFunction, callbackParam){
- if (!mailUri) return;
+ if (!mailUri) {
+ return;
+ }
var streamListener = {
QueryInterface: function(aIID) {
- if (aIID.equals(Components.interfaces.nsISupports)
- || aIID.equals(Components.interfaces.nsIStreamListener))
+ if (aIID.equals(Components.interfaces.nsISupports) || aIID.equals(Components.interfaces.nsIStreamListener)) {
return this;
+ }
},
data: "",
isDataComplete: false,
this.data += stream.read(available);
stream.close();
stream = null;
-
// parse headers only
- var idxEnd = this.data.indexOf("\r\n\r\n",0); // * CRLF DOS : "\r\n"
- if(idxEnd == -1) idxEnd = this.data.indexOf("\n\n",0); // * CRLF UNIX : "\n"
- if(idxEnd == -1) idxEnd = this.data.indexOf("\r\r",0); //CRLF OS : "\r"
- if(idxEnd != -1) this.isDataComplete = true;
+ // * CRLF DOS : "\r\n"
+ var idxEnd = this.data.indexOf("\r\n\r\n",0);
+ if (idxEnd === -1) {
+ // * CRLF UNIX : "\n"
+ idxEnd = this.data.indexOf("\n\n",0);
+ }
+ if (idxEnd === -1) {
+ //CRLF OS : "\r"
+ idxEnd = this.data.indexOf("\r\r",0);
+ }
+ if (idxEnd !== -1) {
+ this.isDataComplete = true;
+ }
gConsole.logStringMessage("[XimfmailGetMessage - streamListener.onDataAvailable ]isDataComplete=true ");
}
gConsole.logStringMessage("[XimfmailGetMessage - streamListener.onDataAvailable ]");
},
onStopRequest: function(request, context, status) {
- if (Components.isSuccessCode(status)) {
- gConsole.logStringMessage("[XimfmailGetMessage - streamListener.isDataComplete ] all mime headers have been parsed - status = " + status );
+ if (Components.isSuccessCode(status)) {
+ gConsole.logStringMessage("[XimfmailGetMessage - streamListener.isDataComplete ] all mime headers have been parsed - status = " + status );
callbackFunction( this.data, mailUri, callbackParam);
- } else {
- if(this.isDataComplete == true){
- // all mime headers have been parsed
- gConsole.logStringMessage("[XimfmailGetMessage - streamListener.isDataComplete ] all mime headers have been parsed !");
+ } else {
+ if(this.isDataComplete === true){
+ // all mime headers have been parsed
+ gConsole.logStringMessage("[XimfmailGetMessage - streamListener.isDataComplete ] all mime headers have been parsed !");
callbackFunction( this.data, mailUri, callbackParam);
}else{
gConsole.logStringMessage("[XimfmailGetMessage - streamListener.onStopRequest ] Error: "+status);
}
}
}
- }
-
+ };
gConsole.logStringMessage("[ximfmail - XimfmailGetMessage ]");
- //$("#ximfmailMailPanel").attr("collapsed","true"); // XIMF headers ihm
- //$("#ximfmail-custom-panel").attr("collapsed","true"); //XIMF account profile type ihm
- var pref = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch(null);
- pref = pref.QueryInterface(Components.interfaces.nsIPrefBranch2);
- if(pref.getBoolPref("mailnews.headers.showXimfmail")){
+ if(Services.prefs.getBoolPref("mailnews.headers.showXimfmail")){
// parse message to get XIMF headers
var cmessenger = Components.classes["@mozilla.org/messenger;1"].createInstance(Components.interfaces.nsIMessenger);
var msgSvc = cmessenger.messageServiceFromURI(mailUri);
- try { msgSvc.streamMessage(mailUri, streamListener, null, null, false, null); } catch (ex) { return false; }
+ try {
+ msgSvc.streamMessage(mailUri, streamListener, null, null, false, null);
+ } catch (ex) {
+ return false;
+ }
}else{
DeleteXimfHeaders();
gUriMsgLoading.remove(mailUri);
- }
+ }
}
-
/*
* Set Ximf headers of message to array : {[headerName][headerValue],[headerName][headerValue],...}
* headerName will be low-case formated
* use "for (headerName in gSecureHeadersArray) {}" to parse array
- */
+ */
function XimfmailParseMessage(msgSrc){
- var separator = new RegExp("\\r\\n|\\r|\\n", "i");// end line
+ // separator : split end lines
+ var separator = new RegExp("\\r\\n|\\r|\\n", "i");
var tab = msgSrc.split(separator);
var currentXimfHdrArray = {};
-
- // filter on IMF headers - append data to array
+ // filter on IMF headers - append data to array
var reg_folding = new RegExp("( )","g");
- var reg_folding2 = new RegExp("(\t)","g");
+ var reg_folding2 = new RegExp("(\t)","g");
for(var idxTab=0; idxTab<tab.length; ++idxTab){
try{
- var header_line = tab[idxTab];
+ var header_line = tab[idxTab];
// search for long header fields (folding) - RFC 2822
- if(header_line[0]!= " "){
+ if(header_line[0] !== " "){
while( idxTab < tab.length ){
try{
var next_line = tab[idxTab+1];
if(next_line){
- if(next_line[0] == " " || next_line[0] == "\t"){
- header_line += next_line; //next_line.toLowerCase();
+ if(next_line[0] === " " || next_line[0] === "\t"){
+ header_line += next_line;
header_line = header_line.replace(reg_folding," ");
header_line = header_line.replace(reg_folding2,"");
++idxTab;
}else{ break; }
}else{ break; }
}catch(e){}
- }
- }
+ }
+ }
// decode MIME Header and add header to arrray
- if(header_line.indexOf(":")!=-1){
- let hdrName = header_line.substring(0,header_line.indexOf(": ",0));
- let hdrValue = header_line.substring(header_line.indexOf(": ",header_line)+2);
- if(hdrName != "") currentXimfHdrArray[hdrName/*.toLowerCase()*/]= DecodeMimeXimfheader(hdrValue);
+ if(header_line.indexOf(":") !== -1){
+ var hdrName = header_line.substring(0,header_line.indexOf(": ",0));
+ var hdrValue = header_line.substring(header_line.indexOf(": ",header_line)+2);
+ if (hdrName !== "") {
+ currentXimfHdrArray[hdrName/*.toLowerCase()*/]= DecodeMimeXimfheader(hdrValue);
+ }
}
}catch(e){}
- }
+ }
return currentXimfHdrArray;
}
-
-
+/*
+ * Convert mime header value to string value
+ */
+function DecodeMimeXimfheader(sHeaderValue){
+ var newHdrValue = null;
+ var charsetDefault = "LATIN_CHARSET";
+ try{
+ // convert MIME format (encoded-word ASCII) to String
+ if (gLastMailCharset) {
+ charsetDefault = gLastMailCharset;
+ }
+ var mimeXimfConverter = Components.classes["@mozilla.org/messenger/mimeconverter;1"].getService(Components.interfaces.nsIMimeConverter);
+ newHdrValue = mimeXimfConverter.decodeMimeHeader(sHeaderValue,charsetDefault,false,true);
+ }catch(ex){
+ newHdrValue = sHeaderValue;
+ }
+ return newHdrValue;
+}
/*
* Ximf headers of current message
*/
-function XimfmailMesssage(){
- this._mailUri = null;
+function XimfmailMesssage(){
+ this._mailUri = null;
this._instanceMsgXimf = null;
- this._current_definition = null;
this._currentXimfHdrArray = {};
- if(typeof XimfmailMesssage.initialized == "undefined"){
+ if(typeof XimfmailMesssage.initialized === "undefined"){
// set uri of message
XimfmailMesssage.prototype.set = function(uri){
try{
- if(!uri) return;
- if(this._mailUri == uri) return;
- this._mailUri = uri;
+ if (!uri) {
+ return;
+ }
+ if (this._mailUri === uri) {
+ return;
+ }
+ this._mailUri = uri;
}catch(e){
gConsole.logStringMessage("[ximfmail - XimfmailMesssage.set ] " + e +"\nline : " + e.lineNumber + " : "+ e + "\nfile : "+ Error().fileName);
}
return false;
};
- //
- XimfmailMesssage.prototype.init = function(uri,headerArray){
+ XimfmailMesssage.prototype.init = function(uri,headerArray) {
try{
- if(!uri) return;
- if(this._mailUri == uri) return;
+ if (!uri) {
+ return;
+ }
+ if (this._mailUri === uri) {
+ return;
+ }
this._mailUri = uri;
this._instanceMsgXimf = null;
-
- // this._currentXimfHdrArray=headerArray;
// be sure to have lower case header name
- for(hdr in headerArray){
- //this._currentXimfHdrArray[hdr.toLowerCase()] = headerArray[hdr];
+ for (hdr in headerArray) {
this._currentXimfHdrArray[hdr] = headerArray[hdr];
}
-
- // get account XIMF definition
- var prefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch(null);
- this._current_definition = "";
- if(prefBranch.prefHasUserValue("mailnews.instance.mailpanel")){
- if(prefBranch.prefHasUserValue("mailnews.theme.mailpanel"))
- this._current_definition = prefBranch.getCharPref("mailnews.theme.mailpanel");
- }else{
- gConsole.logStringMessage("DBG [ximfmail - XimfmailMesssage.init ] no ximf preferences ");
- return false;
- }
-
- var uriXimfInstance = this.hasXimfHeaders(this._current_definition);
- if(uriXimfInstance){
- gConsole.logStringMessage("DBG [ximfmail - XimfmailMesssage.init ] mail instance : " + uriXimfInstance);
+ var uriXimfInstance = this.getXimfmailInstanceURI();
+ if(uriXimfInstance !== undefined){
+ gConsole.logStringMessage("DBG [ximfmail - XimfmailMesssage.init ] mail instance : " + uriXimfInstance);
this._instanceMsgXimf = uriXimfInstance;
return true;
}else{
return false;
}
-
-
}catch(e){
gConsole.logStringMessage("[ximfmail - XimfmailMesssage.init ] " + e +"\nline : " + e.lineNumber + " : "+ e + "\nfile : "+ Error().fileName);
}
return false;
- };
-
-
+ };
// check message with XimfmailCatalog
- XimfmailMesssage.prototype.hasXimfHeaders = function(currentDefinition){
- try{
- var sversion = null;
- var sname = null;
-
- sversion = this.getHeaderValue(XIMF_VERSION_HEADER);
- sname = this.getHeaderValue(XIMF_NAME_HEADER);
- gConsole.logStringMessage("DBG [ximfmail - MessageAnalyser - hasXimfHeaders ] \ndefinition uri = "+ currentDefinition +"\nXIMF version = "+ sversion+"\nXIMF name = "+sname );
-
- //if(gXimfCatalog && sname && sversion)
- if(!sname) return null;
-
- // check currentDefinition in XimfmailCatalog
- if(!gXimfCatalog){CreateXimfmailCatalog();}
- var uriInstanceXimf = gXimfCatalog.getInstanceUri(currentDefinition,sname,sversion);
-
+ XimfmailMesssage.prototype.getXimfmailInstanceURI = function(){
+ var uriInstanceXimf = undefined;
+ try{
+ var sversion = this.getHeaderValue(ximfConst.XIMF_VERSION_HEADER);
+ var sname = this.getHeaderValue(ximfConst.XIMF_NAME_HEADER);
+ if(sname){
+ var arrayInstances = XimfCatalog.getInstance().getInstanceList();
+ for(idx in arrayInstances){
+ var instance = arrayInstances[idx];
+ if (instance.substring(instance.lastIndexOf("/")+1).toLowerCase() === sname.toLowerCase()) {
+ uriInstanceXimf = instance;
+ break;
+ }
+ }
+ }
}catch(e){
gConsole.logStringMessage("[ximfmail - XimfmailMesssage.hasXimfHeaders ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
}
-
+
return uriInstanceXimf;
};
-
// get XIMF value from message
XimfmailMesssage.prototype.getHeaderValue = function(headerName){
var value = null;
- try{
- //value = this._currentXimfHdrArray[headerName.toLowerCase()];
- value = this._currentXimfHdrArray[headerName];
- if(value == null){
+ try{
+ value = this._currentXimfHdrArray[headerName];
+ if(value === null){
// try to get header insensitive case
for(hdr in this._currentXimfHdrArray){
- if(headerName.toLowerCase() == hdr.toLowerCase()){
+ if(headerName.toLowerCase() === hdr.toLowerCase()){
value = this._currentXimfHdrArray[hdr];
break;
- //alert("value as insensitive case founded : " +hdr+" : "+ value)
}
- }
+ }
}
-
}catch(e){
- gConsole.logStringMessage("[ximfmail - XimfmailMesssage.getValue ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
+ gConsole.logStringMessage("[ximfmail - XimfmailMesssage.getValue ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
value=null;
}
return value;
};
-
// get XIMF value from message
XimfmailMesssage.prototype.getCompleteXimfArray = function(){
return this._currentXimfHdrArray;
};
// set XIMF value to message
- XimfmailMesssage.prototype.setXimfHeader = function(headerName,headerValue){
+ XimfmailMesssage.prototype.setXimfHeader = function(headerName,headerValue){
try{
- //this._currentXimfHdrArray[headerName.toLowerCase()] = headerValue;
this._currentXimfHdrArray[headerName] = headerValue;
}catch(e){
- gConsole.logStringMessage("[ximfmail - XimfmailMesssage.setXimfHeader ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
- }
+ gConsole.logStringMessage("[ximfmail - XimfmailMesssage.setXimfHeader ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
+ }
};
XimfmailMesssage.initialized = true;
}
/* ***** BEGIN LICENSE BLOCK *****
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.
- *
*
- * Redistribution and use, in source and binary forms, with or without modification,
+ *
+ * Redistribution and use, in source and binary forms, with or without modification,
* are permitted provided that the following conditons are met :
*
- * 1. Redistributions of source code must retain the above copyright notice,
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached
* in the redistribution of the source code.
- * 3. Neither the names of the copyright holders nor the names of any contributors
- * may be used to endorse or promote products derived from this software without specific
+ * 3. Neither the names of the copyright holders nor the names of any contributors
+ * may be used to endorse or promote products derived from this software without specific
* prior written permission from EADS Defence and Security.
- *
+ *
* Alternatively, the contents of this file may be used under the terms of
* either of 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"),
* 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.
- *
+ *
* REMINDER :
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * EADS Defence and Security - 1 Boulevard Jean Moulin -
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)
+ *
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)
* ***** END LICENSE BLOCK ***** */
-
var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
-
-//
+gConsole.logStringMessage("messageWindow-ov-ximfmail.js file loaded");
window.addEventListener('messagepane-loaded', InitXimfailMsgWindow, true);
-
/*
- * gUriMsgLoading check for messages which are currently loading *
+ * gUriMsgLoading check for messages which are currently loading *
*/
var gUriMsgLoading = {
- uriList : [], // array of uri loading
+ // array of uri loading
+ uriList : [],
add : function(uri){
- if(uri) this.uriList.push(uri)
+ if (uri) {
+ this.uriList.push(uri);
+ }
gConsole.logStringMessage("[ximfmail - gUriMsgLoading.add ] uri : " + uri);
},
remove : function(uri){
- if(!uri) return;
+ if (!uri) {
+ return;
+ }
var idx = 0;
try{
for(idx ; idx<this.uriList.length ; ++idx){
if(this.uriList[idx] === uri){
this.uriList.splice(idx,1);
- gConsole.logStringMessage("[ximfmail - gUriMsgLoading.remove ] uri : " + uri);
+ gConsole.logStringMessage("[ximfmail - gUriMsgLoading.remove ] uri : " + uri);
return;
}
}
}catch(e){
- gConsole.logStringMessage("[ximfmail - gUriMsgLoading.remove ] error for uri " + uri +"\n error: "+ e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ gConsole.logStringMessage("[ximfmail - gUriMsgLoading.remove ] error for uri " + uri +"\n error: "+ e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
}
},
isLoading : function(uri){
- if(!uri) return;
+ if (!uri) {
+ return;
+ }
try{
for(var idx=0 ; idx<this.uriList.length ; ++idx){
if(this.uriList[idx] === uri){
- gConsole.logStringMessage("[ximfmail - gUriMsgLoading.isloading : true ] uri : " + uri);
+ gConsole.logStringMessage("[ximfmail - gUriMsgLoading.isloading : true ] uri : " + uri);
return true;
}
}
}
gConsole.logStringMessage("[ximfmail - gUriMsgLoading.isloading : false ] uri : " + uri);
return false;
- }
+ }
};
-
/*
- * Create a message listener
+ * Create a message listener
*/
function InitXimfailMsgWindow(){
- //
+ //
gMessageListeners.push({
onStartHeaders: function (){
- $("#ximfmailMailPanel").attr("collapsed","true"); // box for ximf headers
- $("#ximfHeadBox").attr("collapsed","true"); // box for ximf pictures
+ // box for ximf headers
+ $("#ximfmailMailPanel").attr("collapsed","true");
+ // box for ximf pictures
+ $("#ximfHeadBox").attr("collapsed","true");
},
- onEndHeaders: function(){
+ onEndHeaders: function(){
var uriMsg = null;
if (gMessageDisplay.isDummy){
// displayed message from disk
- uriMsg = gMessageDisplay.displayedUri;
+ uriMsg = gMessageDisplay.displayedUri;
gConsole.logStringMessage("[ximfmail - InitXimfailMsgWindow.onEndHeaders ]\ndisplayed message from disk - url = "+uriMsg);
- }else{
+ } else {
// get uri of selected message
var msgDBHdr = gFolderDisplay.selectedMessage;
- if(msgDBHdr) uriMsg = msgDBHdr.folder.getUriForMsg(msgDBHdr);
+ if (msgDBHdr) {
+ uriMsg = msgDBHdr.folder.getUriForMsg(msgDBHdr);
+ }
}
if(!gUriMsgLoading.isLoading(uriMsg)){
gUriMsgLoading.add(uriMsg);
- XimfmailGetMessage(uriMsg,XimfmailParseAndOpenMesssage);
+ XimfmailGetMessage(uriMsg, function(msgSrc, uriSrc) {
+ // Parse Ximf headers in message and display them if necessary
+ var currentXimfHdrArray = XimfmailParseMessage(msgSrc);
+ var folderPaneElt = document.getElementById('folderPaneBox');
+ if (folderPaneElt) {
+ var ximfMsg = new XimfmailMesssage();
+ if (ximfMsg.init(uriSrc, currentXimfHdrArray)) {
+ if (folderPaneElt.hasAttribute("collapsed")) {
+ // message opened in new tab
+ $("#ximfmail-custom-panel").attr("collapsed","true");
+ ShowXimfmailPanel(ximfMsg);
+ ShowExpandedHeaders(ximfMsg);
+ $("#ximfmailMailPanel").removeAttr("collapsed");
+ } else {
+ // preview pane, no headers to display
+ ShowExpandedHeaders(ximfMsg);
+ $("#ximfmail-custom-panel").removeAttr("collapsed");
+ }
+ gUriMsgLoading.remove(uriSrc);
+ }
+ } else {
+ // message opened in new window
+ OpenWindowXimfMesssage(uriSrc, currentXimfHdrArray);
+ }
+ });
}
},
onEndAttachments: function (){
}
});
}
-
-/*
- * Get Extended headers of messages and display known instances
+/**
+ * Add Ximf headers to new window message
+ * @param uriSrc
+ * @param ximfHdrArray
*/
-function XimfmailParseAndOpenMesssage(msgSrc,uriSrc){
- var currentXimfHdrArray = XimfmailParseMessage(msgSrc);
- try{
-
- var ximfMsg = new XimfmailMesssage();
- if(ximfMsg.init(uriSrc,currentXimfHdrArray)){
- //alert("XimfmailParseMesssage uriSrc = " + uriSrc +" \n valid ximfmail message")
- var folderPaneElt = document.getElementById('folderPaneBox');
- if(folderPaneElt){
- // is read message opened in new tab
- if(folderPaneElt.hasAttribute("collapsed")){
- $("#ximfmail-custom-panel").attr("collapsed","true");
- if(ShowXimfmailPanel(ximfMsg)){
- $("#ximfmailMailPanel").removeAttr("collapsed");
- }
- }else{
- $("#ximfmail-custom-panel").removeAttr("collapsed");
- }
- }else{
- // message is displayed in new window
- if(ShowXimfmailPanel(ximfMsg)) $("#ximfmailMailPanel").removeAttr("collapsed");
- }
- // common elements to display
- ShowExpandedHeaders(ximfMsg);
- }
-
+function OpenWindowXimfMesssage(uriSrc, ximfHdrArray) {
+ try {
+ // ximfCatalog must be loaded (new window here...)
+ var ximfMsg = new XimfmailMesssage();
+ if(ximfMsg.init(uriSrc, ximfHdrArray)){
+ ShowXimfmailPanel(ximfMsg);
+ ShowExpandedHeaders(ximfMsg);
+ gUriMsgLoading.remove(uriSrc);
+ $("#ximfmailMailPanel").removeAttr("collapsed");
+ }
}catch(e){
- gConsole.logStringMessage("XimfmailParseAndOpenMesssage error:"+e);
+ gConsole.logStringMessage("[OpenWindowXimfMesssage] Error: " + e);
}
- gUriMsgLoading.remove(uriSrc);
-};
-
-
+}
/*
* Remove all XIMF functions if selected account is not XIMFMAIL tagged
*/
// hide ximf expanded headers
$("#ximfCategoryClassificationLabelImg").removeAttr("src");
$("#ximfSecurityClassificationLabelImg").removeAttr("src");
- if($("#signedHdrIcon").attr("signed") == "ximfalert"){
+ if($("#signedHdrIcon").attr("signed") === "ximfalert"){
$("#signedHdrIcon").attr("signed","");
}
- try{$(".ximfImgCategory").remove()}catch(e){}
+ try{
+ $(".ximfImgCategory").remove();
+ }catch(e){}
}catch(e){}
-}
-
-
-/*
+}
+/*
* Dom document manipulations
- */
-function ToogleHiddenPanel(){
- if($("#ximfMailTable").attr("hidden") == "true"){
- $("#ximfMailTable").attr("hidden","false");
+ */
+function ToogleHiddenPanel(){
+ if($("#ximfMailTable").attr("hidden") === "true"){
+ $("#ximfMailTable").attr("hidden","false");
$("#ximfmailComposeMessageMaximize").attr("hidden","true");
- $("#ximfmailComposeMessageMinimize").attr("hidden","false");
+ $("#ximfmailComposeMessageMinimize").attr("hidden","false");
}else{
- $("#ximfMailTable").attr("hidden","true");
+ $("#ximfMailTable").attr("hidden","true");
$("#ximfmailComposeMessageMaximize").attr("hidden","false");
- $("#ximfmailComposeMessageMinimize").attr("hidden","true");
+ $("#ximfmailComposeMessageMinimize").attr("hidden","true");
}
-}
-
-//
-function ConvertMimeDatasToLabelValues(){
- try{
- var txtBoxList = $("textbox[class='XimfTextboxDisplay']");
- for(var x = 0; x<txtBoxList.length; ++x){
- var valueBox = txtBoxList[x].getAttribute("value");
- if( valueBox != ""){
- // menuitem case
- var items = $("panel[id='"+ txtBoxList[x].getAttribute("refpanel") +"'] menuitem");
- if(items.length > 0){
- for(var y = 0; y < items.length; ++y){
- var valueItem = items[y].getAttribute("ximfvalue");
- if(valueBox.toLowerCase() == valueItem.toLowerCase()){
- txtBoxList[x].setAttribute("value", items[y].getAttribute("label"));
- }
+}
+//
+function ConvertMimeDatasToLabelValues() {
+ try {
+ var valueItem = "";
+ var valueBox = "";
+ var txtBoxList = $("textbox[class='XimfTextboxDisplay']");
+ for (var x = 0; x<txtBoxList.length; ++x) {
+ valueBox = txtBoxList[x].getAttribute("value");
+ if ( valueBox !== "") {
+ // menuitem case
+ var items = $("panel[id='"+ txtBoxList[x].getAttribute("refpanel") +"'] menuitem");
+ if (items.length > 0) {
+ for (var idxItm = 0; idxItm < items.length; ++idxItm) {
+ valueItem = items[idxItm].getAttribute("ximfvalue");
+ if (valueBox.toLowerCase() === valueItem.toLowerCase()) {
+ txtBoxList[x].setAttribute("value", items[idxItm].getAttribute("label"));
}
}
- // button case
- var buttons = $("panel[id='"+ txtBoxList[x].getAttribute("refpanel") +"'] button");
- if(buttons.length > 0){
- for(var y = 0; y < buttons.length; ++y){
- var valueItem = buttons[y].getAttribute("ximfvalue");
- //alert("valuebox="+valueBox+"\nvalueItem="+valueItem)
- if(valueBox.toLowerCase() == valueItem.toLowerCase()){
- txtBoxList[x].setAttribute("value", buttons[y].getAttribute("label"));
- }
+ }
+ // button case
+ var buttons = $("panel[id='"+ txtBoxList[x].getAttribute("refpanel") +"'] button");
+ if (buttons.length > 0) {
+ for (var idxBtn = 0; idxBtn < buttons.length; ++idxBtn) {
+ valueItem = buttons[idxBtn].getAttribute("ximfvalue");
+ if (valueBox.toLowerCase() === valueItem.toLowerCase()) {
+ txtBoxList[x].setAttribute("value", buttons[idxBtn].getAttribute("label"));
}
}
- // chekbox case
- var checkboxes = $("panel[id='"+ txtBoxList[x].getAttribute("refpanel") +"'] checkbox");
- if(checkboxes.length > 0){
- for(var y = 0; y < checkboxes.length; ++y){
- var valueItem = checkboxes[y].getAttribute("ximfvalue");
- //alert("valuebox="+valueBox+"\nvalueItem="+valueItem)
- if(valueBox.toLowerCase() == valueItem.toLowerCase()){
- txtBoxList[x].setAttribute("value", checkboxes[y].getAttribute("label"));
- }
+ }
+ // chekbox case
+ var checkboxes = $("panel[id='"+ txtBoxList[x].getAttribute("refpanel") +"'] checkbox");
+ if (checkboxes.length > 0 ){
+ for (var idxChk = 0; idxChk < checkboxes.length; ++idxChk) {
+ valueItem = checkboxes[idxChk].getAttribute("ximfvalue");
+ if (valueBox.toLowerCase() === valueItem.toLowerCase()) {
+ txtBoxList[x].setAttribute("value", checkboxes[idxChk].getAttribute("label"));
}
}
}
}
- }catch(e){}
- };
-
+ }
+ } catch(e) {}
+};
/*
- * Set label and ximfvalue of ximf linked element
- *
+ * Set label and ximfvalue of ximf linked element
+ *
* @ximfMesssage : ximfmailMesssage object
*/
function ComputeXimfElementLinked(ximfelement,idPanel,ximfMessage){
var ximfValue = ximfMessage.getHeaderValue(xHeader);
if(ximfValue){
// search for value and comlete display box
- $(ximfelement).attr("refpanel",idPanel);
+ $(ximfelement).attr("refpanel",idPanel);
var display_box = $("textbox[refheader='" + xHeader + "']");
-
// default values
$(ximfelement).attr("value",ximfValue);
$(ximfelement).attr("ximfvalue",ximfValue);
$(ximfelement).attr("tooltiptext",ximfValue);
-
// menuitem value (ilk, linkpopup...)
- var menu_item = $("panel[id='"+$(ximfelement).attr("refpanel")+"'] menuitem");
+ var menu_item = $("panel[id='"+$(ximfelement).attr("refpanel")+"'] menuitem");
for(var idx_menu_item = 0 ; idx_menu_item < menu_item.length ; ++idx_menu_item){
- var current_ximfvalue = menu_item[idx_menu_item].getAttribute("ximfvalue");
- if(current_ximfvalue.toLowerCase() == ximfValue.toLowerCase()){
+ var current_ximfvalue = menu_item[idx_menu_item].getAttribute("ximfvalue");
+ if(current_ximfvalue.toLowerCase() === ximfValue.toLowerCase()){
ximfelement.setAttribute("value",menu_item[idx_menu_item].getAttribute("label"));
$(ximfelement).attr("ximfvalue",ximfValue);
$(ximfelement).attr("tooltiptext",menu_item[idx_menu_item].getAttribute("label"));
-
- //linkpopup manager
+ //linkpopup manager
var linkpopup = menu_item[idx_menu_item].getAttribute("linkpopupbox");
- if(linkpopup){
+ if(linkpopup){
var targetpopup = $("panel[id='"+linkpopup+"']");
- $("textbox[id='" + targetpopup[0].getAttribute("ximfreftextbox")+"']").attr("refpanel",linkpopup);
- ComputeXimfElementLinked($("textbox[id='" + targetpopup[0].getAttribute("ximfreftextbox")+"']"),targetpopup[0].id,ximfMessage);
- }
+ $("textbox[id='" + targetpopup[0].getAttribute("ximfreftextbox")+"']").attr("refpanel",linkpopup);
+ ComputeXimfElementLinked($("textbox[id='" + targetpopup[0].getAttribute("ximfreftextbox")+"']"),targetpopup[0].id,ximfMessage);
+ }
}
}
}
}catch(e){
- gConsole.logStringMessage("[ximfmail - ComputeXimfElementLinked ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
- }
+ gConsole.logStringMessage("[ximfmail - ComputeXimfElementLinked ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ }
}
-
-// load ximf headers in DOM documents
-function ShowXimfmailPanel(ximfmailMesssage){
- try{
- // create DOM panel using compose message template xslt
- if(gXimfCatalog){
- $("#ximfmailMailPanelTitle").attr("value",gXimfCatalog.getNameInstance(ximfmailMesssage._instanceMsgXimf));
- }else{
- $("#ximfmailMailPanelTitle").attr("value","XIMFMAIL");
- }
+// load ximf headers in DOM documents
+function ShowXimfmailPanel(ximfmailMesssage) {
+ try {
+ var defaultXimfName = ximfConst.DEFAULT_XIMF_NAME;
+ var ximfName = XimfCatalog.getInstance().getNameInstance(ximfmailMesssage._instanceMsgXimf);
+ if (!ximfName) {
+ ximfName = defaultXimfName;
+ }
+ var arrList = XimfCatalog.getInstance().getInstanceList;
+ // create DOM panel using compose message template xslt
+ $("#ximfmailMailPanelTitle").attr("value",ximfName);
$("#ximfmailMailHeadersTablist").empty();
var composeDom = CreateDOMWithXimfInstance(ximfmailMesssage._instanceMsgXimf,"chrome://theme_ximfmail/content/messengerCompose-ximfmail.xsl");
$("#ximfmailMailHeadersTablist").append(composeDom);
$("#ximfmailMailPanel").attr("hidden","true");
- $("#ximfmail-custom-panel").attr("collapsed",true); // Dom element of preview panel
+ // Dom element of preview panel
+ $("#ximfmail-custom-panel").attr("collapsed",true);
// compute datas to message
- try{
- var xheader_dom = $("label[ximfheader]");
- for(var idx_xheader_dom=0; idx_xheader_dom<xheader_dom.length; ++idx_xheader_dom){
- try{
- //gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - search value for textbox : " + xheader_dom[idx_xheader_dom].getAttribute("ximfheader"));
- var ximfValue = ximfmailMesssage.getHeaderValue(xheader_dom[idx_xheader_dom].getAttribute("ximfheader"));
- if(ximfValue){
+ try {
+ var xheader_dom = $("label[ximfheader]");
+ var ximfValue = "";
+ var display_box = "";
+ for (var idxXmfHdr=0; idxXmfHdr < xheader_dom.length; ++idxXmfHdr) {
+ try {
+ ximfValue = ximfmailMesssage.getHeaderValue(xheader_dom[idxXmfHdr].getAttribute("ximfheader"));
+ if (ximfValue) {
// search for value and comlete display box
- var display_box = $("textbox[refheader='" + xheader_dom[idx_xheader_dom].getAttribute("id") + "']");
- if(display_box.length > 0){
- try{
+ display_box = $("textbox[refheader='" + xheader_dom[idxXmfHdr].getAttribute("id") + "']");
+ if (display_box.length > 0) {
+ try {
// ximfValue is in Array
- if(ximfValue.constructor == Array){
+ if (ximfValue.constructor === Array) {
var sSeparator = display_box[0].getAttribute("ximfseparator");
ximfValue = ximfValue.join(sSeparator);
- }
- }catch(e){}
-
+ }
+ } catch(e) {}
// default values
display_box[0].setAttribute("value",ximfValue);
display_box[0].setAttribute("ximfvalue",ximfValue);
display_box[0].setAttribute("tooltiptext",ximfValue);
-
// menuitem value (ilk, linkpopup...)
var menu_item = $("panel[id='"+display_box[0].getAttribute("refpanel")+"'] menuitem");
-
- for(var idx_menu_item = 0 ; idx_menu_item < menu_item.length ; ++idx_menu_item){
- var current_ximfvalue = menu_item[idx_menu_item].getAttribute("ximfvalue");
- if(current_ximfvalue.toLowerCase() == ximfValue.toLowerCase()){
+ for (var idx_menu_item = 0 ; idx_menu_item < menu_item.length ; ++idx_menu_item) {
+ var current_ximfvalue = menu_item[idx_menu_item].getAttribute("ximfvalue");
+ if (current_ximfvalue.toLowerCase() === ximfValue.toLowerCase()) {
display_box[0].setAttribute("value",menu_item[idx_menu_item].getAttribute("label"));
display_box[0].setAttribute("ximfvalue",current_ximfvalue);
display_box[0].setAttribute("tooltiptext",menu_item[idx_menu_item].getAttribute("label"));
-
- //linkpopup manager
+ //linkpopup manager
var linkpopup = menu_item[idx_menu_item].getAttribute("linkpopupbox");
- if(linkpopup){
+ if (linkpopup) {
var targetpopup = $("panel[id='"+linkpopup+"']");
-
- ComputeXimfElementLinked($("textbox[id='" + targetpopup[0].getAttribute("ximfreftextbox")+"']"),targetpopup[0].id,ximfmailMesssage);
- }
+
+ ComputeXimfElementLinked($("textbox[id='" + targetpopup[0].getAttribute("ximfreftextbox")+"']"),targetpopup[0].id,ximfmailMesssage);
+ }
}
}
}
}
- }catch(e){
- gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ } catch(e) {
+ gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
}
}
-
// load free text values
- xheader_dom = $("textbox[class='ximfEditor']");
- for(var idx_xheader_dom=0; idx_xheader_dom<xheader_dom.length; ++idx_xheader_dom){
- try{
- var oriTxtboxId = xheader_dom[idx_xheader_dom].getAttribute("ximfreftextbox");
+ xheader_dom = $("textbox[class='ximfEditor']");
+ for (var idxXmfEdtr=0; idxXmfEdtr<xheader_dom.length; ++idxXmfEdtr) {
+ try {
+ var oriTxtboxId = xheader_dom[idxXmfEdtr].getAttribute("ximfreftextbox");
var ximfLabelId = $("textbox[id='"+oriTxtboxId+"']").attr("refheader");
- if(ximfLabelId){
- //gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - search value for freetext :" + $("label[id='"+ximfLabelId+"']").attr("ximfheader")+"\nid ="+ximfLabelId);
- var ximfValue = ximfmailMesssage.getHeaderValue($("label[id='"+ximfLabelId+"']").attr("ximfheader"));
- if(ximfValue){
+ if (ximfLabelId) {
+ ximfValue = ximfmailMesssage.getHeaderValue($("label[id='"+ximfLabelId+"']").attr("ximfheader"));
+ if (ximfValue) {
try{
- // ximfValue is in Array
- if(ximfValue.constructor == Array){
- var display_box = $("textbox[refheader='" + xheader_dom[idx_xheader_dom].getAttribute("id") + "']");
- if(display_box.length > 0){
+ // ximfValue is in Array
+ if(ximfValue.constructor === Array){
+ display_box = $("textbox[refheader='" + xheader_dom[idxXmfEdtr].getAttribute("id") + "']");
+ if(display_box.length > 0){
var sSeparator = display_box[0].getAttribute("ximfseparator");
ximfValue = ximfValue.join(sSeparator);
}
- }
- }catch(e){}
- xheader_dom[idx_xheader_dom].setAttribute("value",ximfValue);
- }
- }
- }catch(e){
- gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
- }
+ }
+ }catch(e){}
+ xheader_dom[idxXmfEdtr].setAttribute("value",ximfValue);
+ }
+ }
+ } catch(e) {
+ gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ }
}
-
// load address values
- xheader_dom = $("ximfaddress");
- for(var idx_xheader_dom=0; idx_xheader_dom<xheader_dom.length; ++idx_xheader_dom){
+ xheader_dom = $("ximfaddress");
+ for(var idxXmfAddr=0; idxXmfAddr<xheader_dom.length; ++idxXmfAddr){
try{
- //var oriTxtbox = $("textbox[id='"+xheader_dom[idx_xheader_dom].getAttribute("ximfreftextbox")+"']").attr("refheader");
- var refHeader = xheader_dom[idx_xheader_dom].getAttribute("refheader");
+ var refHeader = xheader_dom[idxXmfAddr].getAttribute("refheader");
if(refHeader){
- //gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - search value for freetext :" + $("label[id='"+ximfLabelId+"']").attr("ximfheader")+"\nid ="+ximfLabelId);
- var ximfValue = ximfmailMesssage.getHeaderValue($("label[id='"+refHeader+"']").attr("ximfheader"));
+ ximfValue = ximfmailMesssage.getHeaderValue($("label[id='"+refHeader+"']").attr("ximfheader"));
if(ximfValue){
try{
- // ximfValue is in Array
- if(ximfValue.constructor == Array){
- var display_box = $("textbox[refheader='" + xheader_dom[idx_xheader_dom].getAttribute("id") + "']");
- if(display_box.length > 0){
+ // ximfValue is in Array
+ if(ximfValue.constructor === Array){
+ display_box = $("textbox[refheader='" + xheader_dom[idxXmfAddr].getAttribute("id") + "']");
+ if(display_box.length > 0){
var sSeparator = display_box[0].getAttribute("ximfseparator");
ximfValue = ximfValue.join(sSeparator);
}
- }
- }catch(e){}
- xheader_dom[idx_xheader_dom].listaddress = ximfValue;
- //alert("load address values \n"+ximfValue+"\n"+xheader_dom[idx_xheader_dom].listaddress);
- }
- }
+ }
+ }catch(e){}
+ xheader_dom[idxXmfAddr].listaddress = ximfValue;
+ }
+ }
}catch(e){
- gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
- }
+ gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ }
}
-
- // load datetime values
- xheader_dom = $("textbox[class='ximfDatetime']");
- for(var idx_xheader_dom=0; idx_xheader_dom<xheader_dom.length; ++idx_xheader_dom){
- try{
- var refHeader = xheader_dom[idx_xheader_dom].getAttribute("refheader");
- if(refHeader){
- //gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - search value for freetext :" + $("label[id='"+ximfLabelId+"']").attr("ximfheader")+"\nid ="+ximfLabelId);
- var ximfValue = ximfmailMesssage.getHeaderValue($("label[id='"+refHeader+"']").attr("ximfheader"));
- if(ximfValue){
- //alert($("label[id='"+refHeader+"']").attr("ximfheader")+" :: "+ximfValue)
- xheader_dom[idx_xheader_dom].setAttribute("ximfvalue", ximfValue);
- var thisDate = ConvertZTimeToLocal(ximfValue);
- if(!thisDate) thisDate = ximfValue;
- xheader_dom[idx_xheader_dom].setAttribute("value",thisDate );
- xheader_dom[idx_xheader_dom].setAttribute("ximftype","date");
- }
- }
- }catch(e){
- gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
- }
- }
- }catch(e){
- gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
- }
-
+ // load datetime values
+ xheader_dom = $("textbox[class='ximfDatetime']");
+ for (var idxDttm=0; idxDttm<xheader_dom.length; ++idxDttm) {
+ try {
+ var refHeader = xheader_dom[idxDttm].getAttribute("refheader");
+ if (refHeader) {
+ ximfValue = ximfmailMesssage.getHeaderValue($("label[id='"+refHeader+"']").attr("ximfheader"));
+ if (ximfValue) {
+ xheader_dom[idxDttm].setAttribute("ximfvalue", ximfValue);
+ var thisDate = ConvertZTimeToLocal(ximfValue);
+ if (!thisDate) {
+ thisDate = ximfValue;
+ }
+ xheader_dom[idxDttm].setAttribute("value",thisDate );
+ xheader_dom[idxDttm].setAttribute("ximftype","date");
+ }
+ }
+ } catch(e) {
+ gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ }
+ }
+ } catch(e) {
+ gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ }
// replace values with international labels
- ConvertMimeDatasToLabelValues();
-
+ ConvertMimeDatasToLabelValues();
// modify DOM to create readable ihm
- //replace textbox elements with labels elements
- xheader_dom = $("textbox[class='XimfTextboxDisplay']");
- for(var idx_xheader_dom=0; idx_xheader_dom<xheader_dom.length; ++idx_xheader_dom){
- try{
- ReplaceTxtboxWithLabel(xheader_dom[idx_xheader_dom]);
- }catch(e){
- gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
- }
- }
- xheader_dom = $("textbox[class='ximfDatetime']");
- for(var idx_xheader_dom=0; idx_xheader_dom<xheader_dom.length; ++idx_xheader_dom){
- try{
- ReplaceTxtboxWithLabel(xheader_dom[idx_xheader_dom]);
- }catch(e){
- gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
- }
- }
-
- // remove template datas
- $("button[class*='ximfEraser']").remove(); // delete erase button
- $("#ximfmailMailHeadersTablist panel").remove(); // delete popup
- $("label[class='ximfHeaderLabel']").attr("style","color:inherit;"); // no mandatory labels
-
+ //replace textbox elements with labels elements
+ xheader_dom = $("textbox[class='XimfTextboxDisplay']");
+ for (var idxTxtDsp=0; idxTxtDsp<xheader_dom.length; ++idxTxtDsp) {
+ try {
+ ReplaceTxtboxWithLabel(xheader_dom[idxTxtDsp]);
+ } catch(e) {
+ gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ }
+ }
+ xheader_dom = $("textbox[class='ximfDatetime']");
+ for (var idx_xheader_dom=0; idx_xheader_dom<xheader_dom.length; ++idx_xheader_dom) {
+ try {
+ ReplaceTxtboxWithLabel(xheader_dom[idx_xheader_dom]);
+ } catch(e) {
+ gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ }
+ }
+ // remove template datas
+ // delete erase button
+ $("button[class*='ximfEraser']").remove();
+ // delete popup
+ $("#ximfmailMailHeadersTablist panel").remove();
+ // no mandatory labels
+ $("label[class='ximfHeaderLabel']").attr("style","color:inherit;");
// event manager panel
$("#ximfmailComposeMessageMaximize").click(ToogleHiddenPanel);
- $("#ximfmailComposeMessageMinimize").click(ToogleHiddenPanel);
- $("#ximfmailMailPanelFocusBar").dblclick(ToogleHiddenPanel);
- $("#ximfmailMailPanel").attr("hidden","false"); // display new panel
- $("button[class*='ximfDetail']").bind("command",OnSelectDetail); //
- }catch(e){
+ $("#ximfmailComposeMessageMinimize").click(ToogleHiddenPanel);
+ $("#ximfmailMailPanelFocusBar").dblclick(ToogleHiddenPanel);
+ // display new panel
+ $("#ximfmailMailPanel").attr("hidden","false");
+ $("button[class*='ximfDetail']").bind("command",OnSelectDetail);
+ } catch(e) {
gConsole.logStringMessage("[ximfmail - ShowXimfmailPanel ] " + e +"\nline : " + e.lineNumber + " : "+ e + "\nfile : "+ Error().fileName);
- }
-
- return true;
+ }
+ return true;
};
-
// remove compose template textbox and add dispayed label
function ReplaceTxtboxWithLabel(element){
try{
- //label
+ //label
var ximflabel = document.createElement("label");
$(ximflabel).attr("id",element.getAttribute("id"));
$(ximflabel).attr("value",element.getAttribute("value"));
$(ximflabel).attr("ximfvalue",element.getAttribute("ximfvalue"));
-
- $(ximflabel).attr("refheader",element.getAttribute("refheader"));
+
+ $(ximflabel).attr("refheader",element.getAttribute("refheader"));
$(ximflabel).attr("class","ximfDisplay");
$(ximflabel).attr("crop","end");
if(element.hasAttribute("ximfseparator")){
}
if(element.hasAttribute("ximftype")){
$(ximflabel).attr("ximftype",element.getAttribute("ximftype"));
- }
-
- // detail image
- /*
- var ximfDetailImage = document.createElement("button");
- $(ximfDetailImage).attr("class","ximfmailButton ximfDetail");
- $(ximfDetailImage).attr("refLabel",element.id);
- $(ximflabel.parentNode).append(ximfDetailImage);*/
-
+ }
// replace DOM
$(element).replaceWith(ximflabel);
-
}catch(e){
- gConsole.logStringMessage("[ximfmail - ReplaceTxtboxWithLabel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ gConsole.logStringMessage("[ximfmail - ReplaceTxtboxWithLabel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
}
-}
-
+}
// insert security pictures...
function ShowExpandedHeaders(ximfmailMesssage){
- try{
+ try {
+ gConsole.logStringMessage("[ximfmail - showExpandedHeaders ] get gor pictures rules... ");
// raz ximf pictures elements
- try{
+ try {
$(".ximfImgCategory").remove();
$("#ximfSecurityClassificationLabelImg").attr("src","");
$("#ximfCategoryClassificationLabelImg").attr("src","");
- }catch(e){}
-
- // selected message has no XIMF headers
- if(!ximfmailMesssage._instanceMsgXimf){
- return false;
+ } catch(e) {}
+ // selected message has no XIMF headers
+ if (!ximfmailMesssage._instanceMsgXimf) {
+ return false;
}
-
// ximfmail elements to display pictures
+ var headerRef = "";
+ var valueRef = "";
+ var tabPictureValueRef = undefined;
+ var tabPictureValueName = undefined;
var imgClassification = document.getElementById("ximfSecurityClassificationLabelImg");
var imgCategory = document.getElementById("ximfCategoryClassificationLabelImg");
-
//display security labels pictures
- //gConsole.logStringMessage("[ximfmail - showExpandedHeaders ] \n search for labels to display... ");
- if(imgClassification){
- imgClassification.setAttribute("src","");
- var reg=new RegExp("[&]+", "g");
- var picturesClassifArray = CreateRulesArray(ximfmailMesssage._instanceMsgXimf,"ximf:classificationPictures");
- for(var iHdr=0; iHdr<picturesClassifArray.length ; ++iHdr){
- var headerRef = picturesClassifArray[iHdr]._headerRef;
- var valueRef = ximfmailMesssage.getHeaderValue(headerRef);
- if(valueRef){
- for(var idxPix = 0 ; idxPix < picturesClassifArray.length ; ++idxPix){
- var tabPictureValueRef =picturesClassifArray[idxPix]._valueRef.split(reg);
- var tabPictureValueName =picturesClassifArray[idxPix]._valueName.split(reg);
- for(var iPict = 0 ; iPict<tabPictureValueRef.length ; ++iPict ){
- //alert("picturesClassifArray[idxPix]._valueRef : "+picturesClassifArray[idxPix]._valueRef);
- var valuemsg = valueRef.toLowerCase();
- var valueref = tabPictureValueRef[iPict].toLowerCase();
- if( valuemsg.indexOf(valueref, 0) != -1 ){
- imgClassification.setAttribute("src",tabPictureValueName[iPict]);
- }
- }
- }
+ gConsole.logStringMessage("[ximfmail - showExpandedHeaders ] \n search for labels to display... ");
+ if (imgClassification) {
+ imgClassification.setAttribute("src","");
+ var reg=new RegExp("[&]+", "g");
+ var picturesClassifArray = CreateRulesArray(ximfmailMesssage._instanceMsgXimf,"ximf:classificationPictures");
+ for (var idxClssfPct=0; idxClssfPct<picturesClassifArray.length ; ++idxClssfPct) {
+ headerRef = picturesClassifArray[idxClssfPct]._headerRef;
+ valueRef = ximfmailMesssage.getHeaderValue(headerRef);
+ if (valueRef) {
+ for (var idxClssPix = 0 ; idxClssPix < picturesClassifArray.length ; ++idxClssPix) {
+ tabPictureValueRef =picturesClassifArray[idxClssPix]._valueRef.split(reg);
+ tabPictureValueName =picturesClassifArray[idxClssPix]._valueName.split(reg);
+ for (var idxClssfPict = 0 ; idxClssfPict<tabPictureValueRef.length ; ++idxClssfPict ) {
+ var regClassImg = new RegExp(tabPictureValueRef[idxClssfPict] + "[\\W]","gi");
+ // valueRef : SECTION SIGN caracter as last item checked with regex
+ valueRef += "\u00A7";
+ if (valueRef.match(regClassImg)) {
+ imgClassification.setAttribute("src",tabPictureValueName[idxClssfPict]);
+ }
+ }
+ }
}
- }
- }
-
- if(imgCategory){
- imgCategory.setAttribute("src","");
+ }
+ }
+ // check categories logos
+ if (imgCategory) {
+ imgCategory.setAttribute("src","");
$(".ximfImgCategory").remove();
- var reg=new RegExp("[&]+", "g");
+ var regImgCtg=new RegExp("[&]+", "g");
var picturesCategorArray = CreateRulesArray(ximfmailMesssage._instanceMsgXimf,"ximf:categoryPictures");
- for(var iHdr=0; iHdr<picturesCategorArray.length ; ++iHdr){
- var headerRef = picturesCategorArray[iHdr]._headerRef;
- var valueRef = ximfmailMesssage.getHeaderValue(headerRef);
- if(valueRef){
- for(var idxPix = 0 ; idxPix < picturesCategorArray.length ; ++idxPix){
- var tabPictureValueRef = picturesCategorArray[idxPix]._valueRef.split(reg);
- var tabPictureValueName = picturesCategorArray[idxPix]._valueName.split(reg);
- for(var iPict = 0 ; iPict<tabPictureValueRef.length ; ++iPict ){
- //alert("picturesClassifArray[idxPix]._valueRef : "+picturesClassifArray[idxPix]._valueRef + " & " + valueRef );
- var valuemsg = valueRef.toLowerCase();
- var valueref = tabPictureValueRef[iPict].toLowerCase();
- var container = document.getElementById("ximfHeadBox");
- if( valuemsg.indexOf(valueref, 0) != -1 ){
- //imgCategory.setAttribute("src",tabPictureValueName[iPict]);
- try{
+ var container = document.getElementById("ximfHeadBox");
+ for (var iHdr=0; iHdr<picturesCategorArray.length ; ++iHdr) {
+ headerRef = picturesCategorArray[iHdr]._headerRef;
+ valueRef = ximfmailMesssage.getHeaderValue(headerRef);
+ if (valueRef) {
+ for (var idxPix = 0 ; idxPix < picturesCategorArray.length ; ++idxPix) {
+ tabPictureValueRef = picturesCategorArray[idxPix]._valueRef.split(regImgCtg);
+ tabPictureValueName = picturesCategorArray[idxPix]._valueName.split(regImgCtg);
+ for (var iPict = 0 ; iPict<tabPictureValueRef.length ; ++iPict ) {
+ var regCatImg = new RegExp(tabPictureValueRef[iPict] + "[\\W]","gi");
+ // SECTION SIGN caracter as last item checked with regex
+ valueRef += "\u00A7";
+ if (valueRef.match(regCatImg)) {
+ try {
var img = document.createElement("image");
img.setAttribute("class","ximfImgCategory");
img.setAttribute("src",tabPictureValueName[iPict]);
- container.appendChild(img);
- }catch(e){
- gConsole.logStringMessage("[ximfmail - showExpandedHeaders ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ container.appendChild(img);
+ } catch(e) {
+ gConsole.logStringMessage("[ximfmail - showExpandedHeaders ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
}
- }
- }
- }
- }
- }
- }
- }catch(e){
- gConsole.logStringMessage("[ximfmail - showExpandedHeaders ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ }
+ }
+ }
+ }
+ }
+ }
+ } catch(e) {
+ gConsole.logStringMessage("[ximfmail - showExpandedHeaders ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
}
-
// secure headers signature are present in message, isn't it?
// this rule is applied only on ximf messages with same instance of current account
- try{
- secureHdrsArray = CreateRulesArray(ximfmailMesssage._instanceMsgXimf,"ximfsecureHeaders");
- if(secureHdrsArray.length > 0){
- var smimeBox = document.getElementById("smimeBox")
- if(smimeBox.hasAttribute("collapsed")){
+ try {
+ secureHdrsArray = CreateRulesArray(ximfmailMesssage._instanceMsgXimf,"ximfsecureHeaders");
+ if (secureHdrsArray.length > 0) {
+ var smimeBox = document.getElementById("smimeBox");
+ if (smimeBox.hasAttribute("collapsed")) {
// Trustedbird hasn't detected signature
// set ximfmail information to user
smimeBox.removeAttribute("collapsed");
- $("#signedHdrIcon").attr("signed","ximfalert");
+ $("#signedHdrIcon").attr("signed","ximfalert");
}
}
- }catch(e){
+ } catch(e) {
gConsole.logStringMessage("[ximfmail - showExpandedHeaders ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
}
-
$("#ximfHeadBox").removeAttr("collapsed");
return true;
}
-
// show values ximf
function OnSelectDetail(evt){
- try{
- idBox = evt.currentTarget.getAttribute("refLabel");
+ try{
+ idBox = evt.currentTarget.getAttribute("refLabel");
var eltTextbox = document.getElementById(idBox);
-
- // display datas of current XIMF header
- if(eltTextbox.value != ""){
- // get informations of datas to load
- var args = [];
+ // display datas of current XIMF header
+ if(eltTextbox.value !== ""){
+ // get informations of datas to load
+ var args = [];
var hLabel = document.getElementById(eltTextbox.getAttribute("refheader"));
- args.push(hLabel.getAttribute("value")); // args[0] : textbox id
- args.push(hLabel.getAttribute("ximfheader")); // args[1] : catalog ref
- args.push(eltTextbox.value); // args[2] : title dialogbox
- args.push(eltTextbox.getAttribute("ximfvalue")); // args[3] : description dialogbox
+ // args[0] : textbox id
+ args.push(hLabel.getAttribute("value"));
+ // args[1] : catalog ref
+ args.push(hLabel.getAttribute("ximfheader"));
+ // args[2] : title dialogbox
+ args.push(eltTextbox.value);
+ // args[3] : description dialogbox
+ args.push(eltTextbox.getAttribute("ximfvalue"));
if(eltTextbox.hasAttribute("ximfseparator")){
args.push(eltTextbox.getAttribute("ximfseparator"));
}
- // open dialog
+ // open dialog
window.openDialog("chrome://ximfmail/content/dialogHdrInfo-ximfmail.xul","showmore", "chrome,resizable,centerscreen,modal",args);
- }
+ }
}catch(e){
- gConsole.logStringMessage("[ximfmail - OnSelectXimfmailContextBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ gConsole.logStringMessage("[ximfmail - OnSelectXimfmailContextBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
}
}
\ No newline at end of file
<!-- ***** BEGIN LICENSE BLOCK *****
- Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.
- ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.
- -
-
- - Redistribution and use, in source and binary forms, with or without modification,
+ -
+ - Redistribution and use, in source and binary forms, with or without modification,
- are permitted provided that the following conditons are met :
-
- - 1. Redistributions of source code must retain the above copyright notice,
- - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached
+ - 1. Redistributions of source code must retain the above copyright notice,
+ - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached
- in the redistribution of the source code.
- - 3. Neither the names of the copyright holders nor the names of any contributors
- - may be used to endorse or promote products derived from this software without specific
+ - 3. Neither the names of the copyright holders nor the names of any contributors
+ - may be used to endorse or promote products derived from this software without specific
- prior written permission from EADS Defence and Security.
- -
+ -
- Alternatively, the contents of this file may be used under the terms of
- either of 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"),
- 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.
- -
+ -
- REMINDER :
- - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
- IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- -
- - EADS Defence and Security - 1 Boulevard Jean Moulin -
- - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)
+ -
+ - EADS Defence and Security - 1 Boulevard Jean Moulin -
+ - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)
+ -
+ - Contributor(s):
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved
- ***** END LICENSE BLOCK ***** -->
<?xml-stylesheet href="chrome://ximfmail/skin" type="text/css"?>
<!DOCTYPE overlay SYSTEM "chrome://ximfmail/locale/ximfmail.dtd">
<overlay id="ximfMessengerOverlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
- xmlns:html="http://www.w3.org/1999/xhtml">
-
- <script type="application/javascript" src="chrome://ximfmail/content/jquery.js" />
- <script type="application/javascript" src="chrome://ximfmail/content/controler-ximfmail.js" />
+ xmlns:html="http://www.w3.org/1999/xhtml">\r
+\r
+ <script type="application/javascript" src="chrome://ximfmail/content/jquery.js" />\r
+ <script type="application/javascript" src="chrome://ximfmail/content/controler-ximfmail.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/constant-ximfmail.js" />
- <script type="application/javascript" src="chrome://ximfmail/content/ximfCatalog.js" />
- <script type="application/javascript" src="chrome://ximfmail/content/ximfmail.js" />
- <script type="application/javascript" src="chrome://ximfmail/content/messageAnalyser-ximfmail.js" />
- <script type="application/javascript" src="chrome://ximfmail/content/messageWindow-ov-ximfmail.js" />
-
+ <script type="application/javascript" src="chrome://ximfmail/content/ximfCatalog.js" />\r
+ <script type="application/javascript" src="chrome://ximfmail/content/ximfmail.js" />\r
+ <script type="application/javascript" src="chrome://ximfmail/content/messageAnalyser-ximfmail.js" />\r
+ <script type="application/javascript" src="chrome://ximfmail/content/messageWindow-ov-ximfmail.js" />\r
+\r
<!-- Display Ximf pictures in message -->
<html:div id="expandedHeadersTopBox">
<hbox id="ximfHeadBox" insertafter="header-view-toolbox">
- <image id="ximfSecurityClassificationLabelImg"/>
- <image id="ximfCategoryClassificationLabelImg"/>
+ <image id="ximfSecurityClassificationLabelImg"/>
+ <image id="ximfCategoryClassificationLabelImg"/>
</hbox>
- </html:div>
-
- <vbox id="messagepanebox">
+ </html:div>\r
+\r
+ <vbox id="messagepanebox">\r
<!-- Display Ximf headers in message of new window -->
<vbox id="ximfmailMailPanel" insertafter="msgHeaderView" collapsed="true">
- <hbox id="ximfmailMailPanelFocusBar" class="ximfmailFocusBar" flex="1" align="center">
+ <hbox id="ximfmailMailPanelFocusBar" class="ximfmailFocusBar" flex="1" align="center">
<button class="ximfmailButton" id="ximfmailComposeMessageMaximize" tooltiptext="&ximfmail.compose.focus;" accesskey="+" hidden="true" />
<button class="ximfmailButton" id="ximfmailComposeMessageMinimize" tooltiptext="&ximfmail.compose.unfocus;" accesskey="-" />
<label id="ximfmailMailPanelTitle" value="&ximfmail.compose.headerTab;"/>
<image id="ximfmailComposeMessageLogo"/>
<spacer flex="1" />
- </hbox>
- <hbox id="ximfMailTable" >
+ </hbox>
+ <hbox id="ximfMailTable" >
<tabbox id="ximfmailMailHeadersTablist" flex="1"/>
- </hbox>
+ </hbox>
</vbox>
</vbox>
</overlay>
\ No newline at end of file
/* ***** BEGIN LICENSE BLOCK *****\r
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
*\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
* are permitted provided that the following conditons are met :\r
*\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
* in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
* prior written permission from EADS Defence and Security.\r
- * \r
+ *\r
* Alternatively, the contents of this file may be used under the terms of\r
* either of the GNU General Public License Version 2 or later (the "GPL"),\r
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
* and other provisions required by the GPL or the LGPL. If you do not delete\r
* the provisions above, a recipient may use your version of this file under\r
* the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
+ *\r
* REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
* ***** END LICENSE BLOCK ***** */\r
+/**\r
+ * messenger-ov-ximfmail.js\r
+ *\r
+ */\r
// global variables\r
var gCurrentIdentity = null;\r
var gPreviousIdentity = null;\r
var gComposeMsgByMenuitem = false;\r
-\r
var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);\r
-var gXBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch(null);\r
-\r
-var gChromeXslMsgCompose = "chrome://theme_ximfmail/content/messengerCompose-ximfmail.xsl";\r
-var gChromeXslTreeRcv = "chrome://theme_ximfmail/content/threadTree-ximfmail.xsl";\r
-\r
-\r
+gConsole.logStringMessage("[messenger-ov-ximfmail] file loaded");\r
/*\r
- * init ximfmail on main panel\r
+ * Get account user settings\r
*/\r
-$(document).ready(function(){\r
- // init ximfmail operations\r
- CreateXimfmailCatalog(); \r
- OnSelectfolderPane(); \r
- \r
- // Creating Ximf Custom Columns\r
- var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);\r
- observerService.addObserver(XimfThreadTreeDBViewObserver, "MsgCreateDBView", false); \r
- \r
- // event manager\r
- $("#folderTree").select(OnSelectfolderPane);\r
- //optional-for technical informations $("#threadTree").select(OnSelectMsg);\r
- //opening message event\r
- $("#threadTree").dblclick(OnOpenMsg); \r
- $("#cmd_openMessage").bind("command",OnOpenMsg);\r
- $("#key_openMessage").bind("command",OnOpenMsg);\r
- $("#threadTree").keypress(OnOpenMsgWithKey); \r
- //\r
- $("#button-newmsg").mousedown(OnSelectfolderPane); // load instances \r
- $("#button-newmsg").bind('command', OnComposeDefaultMsg); // use default instance \r
- $("#button-reply").mousedown(OnSelectfolderPane);\r
- $("#button-reply").bind('command', OnComposeDefaultMsg);\r
- $("#button-replyall").mousedown(OnSelectfolderPane);\r
- $("#button-replyall").bind('command', OnComposeDefaultMsg);\r
- $("#button-forward").mousedown(OnSelectfolderPane);\r
- $("#button-forward").bind('command', OnComposeDefaultMsg); \r
- $("#threadTree").bind('select', OnSelectMsg);\r
- \r
- // Security Labels compatibility (RFC2634)\r
- try{CreateSecurityLabelXml();}catch(e){}\r
- \r
-});\r
-\r
-/*\r
- * \r
+function GetCurrentXimfUser() {\r
+ try {\r
+ var folders = GetSelectedMsgFolders();\r
+ var identity = null;\r
+ var server = null;\r
+ var ximfUser = "";\r
+ if (folders.length > 0){\r
+ // Get the incoming server associated with this uri.\r
+ identity = getIdentityForServer(folders[0].server);\r
+ }\r
+ if (!identity) {\r
+ identity = MailServices.accounts.defaultAccount.defaultIdentity;\r
+ }\r
+ if (identity) {\r
+ gCurrentIdentity = identity;\r
+ var prefName="mail.identity."+identity.key+".useremail";\r
+ if (Services.prefs.prefHasUserValue( prefName )) {\r
+ ximfUser = Services.prefs.getCharPref(prefName);\r
+ }\r
+ }\r
+ }catch (ex){\r
+ gConsole.logStringMessage("[messenger-ov-ximfmail - GetCurrentXimfUser] failed to get an identity to pre-select: " + ex);\r
+ }\r
+ return ximfUser;\r
+};\r
+/**\r
+ * Compute DOM user folder with XIMF account user informations\r
+ */\r
+function OnSelectfolderPane() {\r
+ try{\r
+ // get current identity\r
+ GetCurrentXimfUser();\r
+ if (!gCurrentIdentity) {\r
+ gConsole.logStringMessage("[messenger-ov-ximfmail - OnSelectfolderPane ] gCurrentIdentity invalid");\r
+ return;\r
+ }\r
+ // custom-panel update\r
+ var title = ximfPref.get(gCurrentIdentity.key, "ximfmail_theme_name");\r
+ $("#title-custom").attr("value",title);\r
+ // load context of currentUser\r
+ var refRdf = ximfPref.get(gCurrentIdentity.key,"ximfmail_theme_ref");\r
+ AddRdfDataSce2domList("menupopup-newmsg", refRdf);\r
+ // mailpanel instance : to display compose messages\r
+ var mailTheme = ximfPref.get(gCurrentIdentity.key, "ximfmail_theme_ref");\r
+ Services.prefs.setCharPref("mailnews.theme.mailpanel",mailTheme);\r
+ // is ximfail context used\r
+ if (ximfPref.isXimfAccountOn(gCurrentIdentity)) {\r
+ Services.prefs.setBoolPref("mailnews.headers.showXimfmail",true);\r
+ $("#menupopup-newmsg").attr("datasources","chrome://theme_ximfmail/content/ximfCatalog.rdf");\r
+ $("#menupopup-newmsg menuitem").attr("hidden","false");\r
+ $("#ximfmail-custom-panel").removeAttr("collapsed");\r
+ $("#button-newmsg").attr("type","menu-button");\r
+ try {\r
+ // update secure headers settings file with ximf instance\r
+ var currentInstance = ximfPref.get(gCurrentIdentity.key, "ximfmail_instance_compose_ref");\r
+ gConsole.logStringMessage("[messenger-ov-ximfmail - OnSelectfolderPane - UpdateSecureHeadersFileSettings]currentInstance = " + currentInstance );\r
+ UpdateSecureHeadersFileSettings (currentInstance, gCurrentIdentity);\r
+ gConsole.logStringMessage("[messenger-ov-ximfmail - OnSelectfolderPane - UpdateSecureHeadersFileSettings] Succes updating secure headers file settings");\r
+ } catch (e) {\r
+ gConsole.logStringMessage("[messenger-ov-ximfmail - OnSelectfolderPane - UpdateSecureHeadersFileSettings] Problem updating secure headers file settings : " + e);\r
+ }\r
+ } else {\r
+ Services.prefs.setBoolPref("mailnews.headers.showXimfmail",false);\r
+ $("#menupopup-newmsg").attr("datasources","");\r
+ $("#menupopup-newmsg menuitem").attr("hidden","true");\r
+ $("#ximfmail-custom-panel").attr("collapsed","true");\r
+ $("#button-newmsg").attr("type","");\r
+ }\r
+ }catch(e){\r
+ gConsole.logStringMessage("[messenger-ov-ximfmail - OnSelectfolderPane ] " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
+}\r
+/**\r
+ * Set/Unset XIMFMAIL flag on opening message\r
+ * @returns {Boolean}\r
*/\r
-function OnOpenMsgWithKey(evt){ if(evt.keyCode == 13){OnOpenMsg();}}\r
function OnOpenMsg(){\r
- if(!gCurrentIdentity) return false; \r
- if (IsXimfailActivated(gCurrentIdentity)){ \r
- pref.setBoolPref("mailnews.headers.showXimfmail",true); \r
+ if (!gCurrentIdentity) {\r
+ return false;\r
+ }\r
+ if (ximfPref.isXimfAccountOn(gCurrentIdentity)){\r
+ Services.prefs.setBoolPref("mailnews.headers.showXimfmail",true);\r
// flag on new open message requested\r
- try{ \r
- if(!pref.getBoolPref(PREF_MSGWINDOW_REFRESH)){\r
- pref.setBoolPref(PREF_MSGWINDOW_REFRESH,true); \r
+ try{\r
+ if(!Services.prefs.getBoolPref(ximfConst.PREF_MSGWINDOW_REFRESH)){\r
+ Services.prefs.setBoolPref(ximfConst.PREF_MSGWINDOW_REFRESH,true);\r
}else{\r
- pref.setBoolPref(PREF_MSGWINDOW_REFRESH,false); \r
+ Services.prefs.setBoolPref(ximfConst.PREF_MSGWINDOW_REFRESH,false);\r
}\r
- }catch(e){pref.setBoolPref(PREF_MSGWINDOW_REFRESH,true);}\r
+ }catch(e){Services.prefs.setBoolPref(ximfConst.PREF_MSGWINDOW_REFRESH,true);}\r
}else{\r
- pref.setBoolPref("mailnews.headers.showXimfmail",false); \r
+ Services.prefs.setBoolPref("mailnews.headers.showXimfmail",false);\r
}\r
- return true; \r
+ return true;\r
}\r
-\r
-/*\r
- * \r
+/**\r
+ * Set/Unset XIMFMAIL flag on selected message\r
+ * @returns {Boolean}\r
*/\r
function OnSelectMsg(){\r
try{\r
- if(!gCurrentIdentity) return false; \r
- if (IsXimfailActivated(gCurrentIdentity)){ \r
- pref.setBoolPref("mailnews.headers.showXimfmail",true);\r
- }else{\r
- pref.setBoolPref("mailnews.headers.showXimfmail",false); \r
+ if (!gCurrentIdentity) {\r
+ return false;\r
}\r
- }catch(error){\r
- gConsole.logStringMessage("ximfmail error - on select message : " + error);\r
- }\r
-}\r
-\r
-/*\r
- * define instance ximf to use\r
- */ \r
-function OnCommandComposeMsgXimfmail(event){\r
- gComposeMsgByMenuitem=true; \r
- var pathXmlXimf = event.currentTarget.getAttribute("value"); \r
- gXBranch.setCharPref("ximfmail.composeMsg.instance",pathXmlXimf); \r
- var prefXsmtpCompatibility = GetXimfmailPref(gCurrentIdentity.key, "ximfmail_xsmtp_compatibility");\r
- if(prefXsmtpCompatibility == "true"){ \r
- gXBranch.setCharPref("ximfmail.composeMsg.xsmtp_on","true");\r
- } \r
-}\r
-\r
-/*\r
- * Inspect account user\r
- */ \r
-function OnSelectfolderPane(){\r
- try{\r
- GetCurrentUser();\r
- \r
- if(!gCurrentIdentity){\r
- gConsole.logStringMessage("[ximfmail - OnSelectfolderPane ] gCurrentIdentity invalid");\r
- return;\r
- } \r
- \r
- // custom-panel update\r
- var title = GetXimfmailPref(gCurrentIdentity.key, "ximfmail_theme_name"); \r
- $("#title-custom").attr("value",title); \r
- \r
- // load context of currentUser \r
- var refRdf = GetXimfmailPref(gCurrentIdentity.key,"ximfmail_theme_ref"); \r
- \r
- ChangeRefAttrRdfElement("menupopup-newmsg", refRdf);\r
- \r
- // mailpanel instance : to display received/send messages\r
- var mailInstance = GetXimfmailPref(gCurrentIdentity.key, "ximfmail_instance_mail_panel_ref");\r
- gXBranch.setCharPref("mailnews.instance.mailpanel",mailInstance);\r
- var mailTheme = GetXimfmailPref(gCurrentIdentity.key, "ximfmail_theme_ref");\r
- gXBranch.setCharPref("mailnews.theme.mailpanel",mailTheme);\r
-\r
- // is ximfail context used \r
- if (IsXimfailActivated(gCurrentIdentity)){ \r
- pref.setBoolPref("mailnews.headers.showXimfmail",true);\r
- $("#menupopup-newmsg").attr("datasources","chrome://theme_ximfmail/content/ximfCatalog.rdf");\r
- $("#menupopup-newmsg menuitem").attr("hidden","false");\r
- $("#ximfmail-custom-panel").removeAttr("collapsed"); \r
- $("#button-newmsg").attr("type","menu-button");\r
+ if (ximfPref.isXimfAccountOn(gCurrentIdentity)){\r
+ Services.prefs.setBoolPref("mailnews.headers.showXimfmail",true);\r
}else{\r
- pref.setBoolPref("mailnews.headers.showXimfmail",false);\r
- $("#menupopup-newmsg").attr("datasources","");\r
- $("#menupopup-newmsg menuitem").attr("hidden","true");\r
- $("#ximfmail-custom-panel").attr("collapsed","true"); \r
- $("#button-newmsg").attr("type","");\r
+ Services.prefs.setBoolPref("mailnews.headers.showXimfmail",false);\r
}\r
}catch(e){\r
- gConsole.logStringMessage("[ximfmail - OnSelectfolderPane ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber); \r
+ gConsole.logStringMessage("[messenger-ov-ximfmail - OnSelectMsg ] " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
}\r
}\r
-\r
-/*\r
- * \r
- */ \r
+/**\r
+ * Set instance ximf to use on composing message.\r
+ * Called on press new message button.\r
+ */\r
+function OnCommandComposeMsgXimfmail(event){\r
+ gComposeMsgByMenuitem=true;\r
+ var pathXmlXimf = event.currentTarget.getAttribute("value");\r
+ Services.prefs.setCharPref("ximfmail.composeMsg.instance",pathXmlXimf);\r
+ var prefXsmtpCompatibility = ximfPref.get(gCurrentIdentity.key, "ximfmail_xsmtp_compatibility");\r
+ if (prefXsmtpCompatibility === "true") {\r
+ Services.prefs.setCharPref("ximfmail.composeMsg.xsmtp_on", "true");\r
+ }\r
+}\r
+/**\r
+ * Set XIMF instance to use on composing message.\r
+ * @param evt\r
+ */\r
function OnComposeDefaultMsg(evt){\r
- //alert("OnComposeDefaultMsg")\r
if(!gComposeMsgByMenuitem){\r
- //alert("OnComposeInstanceMsg : " + $("#menupopup-newmsg").attr("ref"));\r
- //var prefCompose = GetXimfmailPref(gCurrentIdentity.key, "ximfmail_instance_compose_ref");\r
- \r
var idButton = evt.currentTarget.id;\r
- var prefKey = ""; \r
- if(idButton == "button-newmsg") prefKey = "ximfmail_instance_compose_ref";\r
- if(idButton == "button-reply") prefKey = "ximfmail_instance_answer_ref";\r
- if(idButton == "button-replyall") prefKey = "ximfmail_instance_answer_ref";\r
- if(idButton == "button-forward") prefKey = "ximfmail_instance_forward_ref";\r
- \r
- if (IsXimfailActivated(gCurrentIdentity)){ \r
- gXBranch.setCharPref("ximfmail.composeMsg.instance",GetXimfmailPref(gCurrentIdentity.key, prefKey));\r
- }else{\r
- gXBranch.setCharPref("ximfmail.composeMsg.instance",""); \r
- } \r
+ var prefKey = "";\r
+ if (idButton === "button-newmsg") {\r
+ prefKey = "ximfmail_instance_compose_ref";}\r
+ if (idButton === "button-reply") {\r
+ prefKey = "ximfmail_instance_answer_ref";\r
+ }\r
+ if (idButton === "button-replyall") {\r
+ prefKey = "ximfmail_instance_answer_ref";\r
+ }\r
+ if (idButton === "button-forward") {\r
+ prefKey = "ximfmail_instance_forward_ref";\r
+ }\r
+ if (ximfPref.isXimfAccountOn(gCurrentIdentity)) {\r
+ Services.prefs.setCharPref("ximfmail.composeMsg.instance", ximfPref.get(gCurrentIdentity.key, prefKey));\r
+ } else {\r
+ Services.prefs.setCharPref("ximfmail.composeMsg.instance","");\r
+ }\r
}\r
- gComposeMsgByMenuitem=false; \r
+ gComposeMsgByMenuitem=false;\r
}\r
-\r
-/*\r
- * Get account user settings\r
+/**\r
+ * Update main panel with XIMF environment\r
*/\r
- function GetCurrentUser() {\r
- \r
- var folder=GetFirstSelectedMsgFolder();\r
- var identity = null; \r
- var server;\r
- \r
- try {\r
- if (folder){\r
- // Get the incoming server associated with this uri.\r
- server = folder.server; \r
- identity = getIdentityForServer(server);\r
- } \r
- }catch (ex){\r
- gConsole.logStringMessage("ximfmail error - failed to get an identity to pre-select: " + error);\r
- return "";\r
+$(document).ready(function(){\r
+ // event manager\r
+ $("#folderTree").select(OnSelectfolderPane);\r
+ $("#threadTree").dblclick(OnOpenMsg);\r
+ $("#cmd_openMessage").bind("command",OnOpenMsg);\r
+ $("#key_openMessage").bind("command",OnOpenMsg);\r
+ $("#threadTree").keypress(function(evt){\r
+ if(evt.keyCode === 13){\r
+ OnOpenMsg();\r
+ }\r
+ });\r
+ // load instances\r
+ $("#button-newmsg").mousedown(OnSelectfolderPane);\r
+ // use default instance\r
+ $("#button-newmsg").bind('command', OnComposeDefaultMsg);\r
+ $("#button-reply").mousedown(OnSelectfolderPane);\r
+ $("#button-reply").bind('command', OnComposeDefaultMsg);\r
+ $("#button-replyall").mousedown(OnSelectfolderPane);\r
+ $("#button-replyall").bind('command', OnComposeDefaultMsg);\r
+ $("#button-forward").mousedown(OnSelectfolderPane);\r
+ $("#button-forward").bind('command', OnComposeDefaultMsg);\r
+ $("#threadTree").bind('select', OnSelectMsg);\r
+ // Creating Ximf Custom Columns\r
+ var observerService = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);\r
+ observerService.addObserver(XimfThreadTreeDBViewObserver, "MsgCreateDBView", false);\r
+ // switch to current folder\r
+ OnSelectfolderPane();\r
+ try{\r
+ // Security Labels compatibility (RFC2634)\r
+ CreateSecurityLabelXml();\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[messenger-ov-ximfmail] Warning - Security Label compatibility : " + e);\r
}\r
- if(identity){\r
- gCurrentIdentity=identity;\r
- var prefName="mail.identity."+identity.key+".useremail"; \r
- try{\r
- if(gXBranch.prefHasUserValue( prefName ))\r
- return gXBranch.getCharPref(prefName); \r
- }catch(exp){ \r
- gConsole.logStringMessage("ximfmail error - failed to get the prefence account type : " + error);\r
- }\r
- } \r
-}\r
+});
\ No newline at end of file
<!-- ***** BEGIN LICENSE BLOCK *****\r
- Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
- ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- - \r
-\r
- - Redistribution and use, in source and binary forms, with or without modification, \r
+ -\r
+ - Redistribution and use, in source and binary forms, with or without modification,\r
- are permitted provided that the following conditons are met :\r
-\r
- - 1. Redistributions of source code must retain the above copyright notice, \r
- - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ - 1. Redistributions of source code must retain the above copyright notice,\r
+ - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
- in the redistribution of the source code.\r
- - 3. Neither the names of the copyright holders nor the names of any contributors \r
- - may be used to endorse or promote products derived from this software without specific \r
+ - 3. Neither the names of the copyright holders nor the names of any contributors\r
+ - may be used to endorse or promote products derived from this software without specific\r
- prior written permission from EADS Defence and Security.\r
- - \r
+ -\r
- Alternatively, the contents of this file may be used under the terms of\r
- either of the GNU General Public License Version 2 or later (the "GPL"),\r
- or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
- and other provisions required by the GPL or the LGPL. If you do not delete\r
- the provisions above, a recipient may use your version of this file under\r
- the terms of any one of the MPL, the GPL or the LGPL.\r
- - \r
+ -\r
- REMINDER :\r
- - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
- IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- - \r
- - EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ -\r
+ - EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ - \r
+ - Contributor(s):\r
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
- ***** END LICENSE BLOCK ***** -->\r
\r
<?xml-stylesheet href="chrome://ximfmail/skin" type="text/css"?>\r
<!DOCTYPE overlay SYSTEM "chrome://ximfmail/locale/ximfmail.dtd">\r
<overlay id="ximfMessengerOverlay" xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"\r
xmlns:html="http://www.w3.org/1999/xhtml">\r
- \r
- <script type="application/javascript" src="chrome://ximfmail/content/jquery.js" /> \r
+ <script type="application/javascript" src="chrome://ximfmail/content/jquery.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/constant-ximfmail.js" />\r
- <script type="application/javascript" src="chrome://ximfmail/content/ximfCatalog.js" />\r
- <script type="application/javascript" src="chrome://ximfmail/content/controler-ximfmail.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/ximfmail.js" />\r
+ <script type="application/javascript" src="chrome://ximfmail/content/ximfCatalog.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/messageAnalyser-ximfmail.js" />\r
- <script type="application/javascript" src="chrome://ximfmail/content/messageWindow-ov-ximfmail.js" />\r
+ <script type="application/javascript" src="chrome://ximfmail/content/controler-ximfmail.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/threadTree-ximfmail.js" />\r
+ <script type="application/javascript" src="chrome://ximfmail/content/messageWindow-ov-ximfmail.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/messenger-ov-ximfmail.js" />\r
\r
<!-- pane of messages received -->\r
<tree id="threadTree">\r
- <treecols id="threadCols"> \r
- </treecols>\r
+ <treecols id="threadCols">\r
+ </treecols>\r
</tree>\r
- \r
+\r
<!-- messages box -->\r
<box id="messagesBox" >\r
<hbox id="ximfmail-custom-panel" class="ximfmailFocusBar" insertafter="threadpane-splitter" collapsed="true">\r
<separator flex="1"/>\r
</hbox>\r
</box>\r
- \r
+\r
<!-- toolbar button Compose New Message -->\r
<toolbarbutton id="button-newmsg" type="menu-button" >\r
<menupopup id="menupopup-newmsg"\r
<rule>\r
<conditions>\r
<content uri="?list" />\r
- <member container="?list" child="?elt" /> \r
+ <member container="?list" child="?elt" />\r
<triple subject="?elt"\r
predicate="http://www.ximfmail.com/RDF#instance" object="?name" />\r
<triple subject="?elt"\r
- predicate="http://www.ximfmail.com/RDF#pathSchema" \r
+ predicate="http://www.ximfmail.com/RDF#pathSchema"\r
object="?pathSchema" />\r
<triple subject="?elt"\r
- predicate="http://www.ximfmail.com/RDF#pathIhm" \r
+ predicate="http://www.ximfmail.com/RDF#pathIhm"\r
object="?pathIhm" />\r
<triple subject="?elt"\r
- predicate="http://www.ximfmail.com/RDF#pathDictionary" \r
+ predicate="http://www.ximfmail.com/RDF#pathDictionary"\r
object="?pathDictionary" />\r
<triple subject="?elt"\r
predicate="http://www.ximfmail.com/RDF#instanceLabel"\r
- object="?label" /> \r
+ object="?label" />\r
<triple subject="?elt"\r
predicate="http://www.ximfmail.com/RDF#active"\r
object="true" />\r
</conditions>\r
- <action> \r
- <menuitem uri="?elt" \r
+ <action>\r
+ <menuitem uri="?elt"\r
value="?elt"\r
- label="?label" \r
+ label="?label"\r
pathSchema="?pathSchema"\r
pathDictionary="?pathDictionary"\r
- pathIhm="?pathIhm" \r
- observes="isXimfailActivated" \r
+ pathIhm="?pathIhm"\r
+ observes="isXimfailActivated"\r
oncommand="OnCommandComposeMsgXimfmail(event);"/>\r
</action>\r
</rule>\r
</template>\r
</menupopup>\r
- </toolbarbutton> \r
- \r
+ </toolbarbutton>\r
+\r
<!-- Display Ximf headers in single message -->\r
<vbox id="singlemessage">\r
- <vbox id="ximfmailMailPanel" insertafter="msgHeaderView" collapsed="true"> \r
+ <vbox id="ximfmailMailPanel" insertafter="msgHeaderView" collapsed="true">\r
<hbox id="ximfmailMailPanelFocusBar" class="ximfmailFocusBar" flex="1" align="center">\r
<button class="ximfmailButton" id="ximfmailComposeMessageMaximize" tooltiptext="&ximfmail.compose.focus;" accesskey="+" hidden="true" />\r
<button class="ximfmailButton" id="ximfmailComposeMessageMinimize" tooltiptext="&ximfmail.compose.unfocus;" accesskey="-" />\r
<label id="ximfmailMailPanelTitle" value="&ximfmail.compose.headerTab;"/>\r
- <image id="ximfmailComposeMessageLogo"/> \r
+ <image id="ximfmailComposeMessageLogo"/>\r
<spacer flex="1" />\r
- </hbox> \r
- <hbox id="ximfMailTable" > \r
+ </hbox>\r
+ <hbox id="ximfMailTable" >\r
<tabbox id="ximfmailMailHeadersTablist" flex="1"/>\r
- </hbox> \r
+ </hbox>\r
</vbox>\r
</vbox>\r
- \r
- <!-- Display Ximf pictures in message expandedHeadersBottomBox --> \r
+\r
+ <!-- Display Ximf pictures in message expandedHeadersBottomBox -->\r
<html:div id="expandedHeadersTopBox">\r
<hbox id="ximfHeadBox" insertafter="header-view-toolbox">\r
- <image id="ximfSecurityClassificationLabelImg"/> \r
- <image id="ximfCategoryClassificationLabelImg"/> \r
+ <image id="ximfSecurityClassificationLabelImg"/>\r
+ <image id="ximfCategoryClassificationLabelImg"/>\r
</hbox>\r
</html:div>\r
- \r
+\r
</overlay>
\ No newline at end of file
/* ***** BEGIN LICENSE BLOCK *****\r
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
*\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
* are permitted provided that the following conditons are met :\r
*\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
* in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
* prior written permission from EADS Defence and Security.\r
- * \r
+ *\r
* Alternatively, the contents of this file may be used under the terms of\r
* either of the GNU General Public License Version 2 or later (the "GPL"),\r
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
* and other provisions required by the GPL or the LGPL. If you do not delete\r
* the provisions above, a recipient may use your version of this file under\r
* the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
+ *\r
* REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
* ***** END LICENSE BLOCK ***** */\r
-\r
-var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);\r
-var gPrefBranch = null;\r
+gConsole.logStringMessage("[ximfmail] messengerCompose-ov-ximfmail.js file loaded ");\r
var gCurrentInstance = "";\r
-\r
-\r
-/* Init ximfmail document */ \r
-window.addEventListener("compose-window-init", XimfmailComposeInit, true);\r
-\r
-/*\r
- * (Re)open message composer with XIMF instance\r
- */\r
-function XimfmailComposeInit(){\r
- // ximfmail not requested\r
- ResetXimfhdrsDom();\r
- if(!gPrefBranch) gPrefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch(null);\r
- if(!gPrefBranch.getBoolPref("mailnews.headers.showXimfmail")){ \r
- $("#isUsingXimfail").attr("hidden","true"); \r
- try{\r
- //remove ximf events ...\r
- HideSendMessageElements(true);\r
- $("#addressingWidget").unbind("command",SpecialXimfRule_CheckAddress); \r
- ReloadSecurityAccess();\r
- }catch(e){}\r
- }else{\r
- if(!gXimfCatalog) CreateXimfmailCatalog();\r
- $("#isUsingXimfail").attr("hidden","false");\r
- \r
- // observer on sending message\r
- var ximfmailObserverSvc = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);\r
- ximfmailObserverSvc.addObserver(ximfmailOnSend, "mail:composeOnSend", false); \r
- \r
- XimfmailStartup();\r
- } \r
-}\r
-\r
-\r
-var gMaxTimeoutXimfmail=0;\r
-function XimfmailStartup(){\r
- if(!gCurrentIdentity){ \r
- // I can't catch event on completely initialized compose message, so loop on gCurrentIdentity loaded\r
- if(gMaxTimeoutXimfmail<20){\r
- setTimeout("XimfmailStartup()", 100);\r
- ++gMaxTimeoutXimfmail;\r
- }\r
- return;\r
- }\r
- \r
- var currentInstance = null;\r
- var current_definition = null;\r
- // is Template or Draft message\r
- var typeMsg = -1;\r
- try{\r
- // get current definition and default instance of account loaded \r
- currentInstance = gPrefBranch.getCharPref("ximfmail.composeMsg.instance");\r
- current_definition = gPrefBranch.getCharPref("mailnews.theme.mailpanel");\r
- var args = window.arguments[0];\r
- if(args){\r
- typeMsg = args.type;\r
- }else{ \r
- if(gMsgCompose) typeMsg = gMsgCompose.type; \r
- }\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - XimfmailStartup ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber); \r
- }\r
- \r
- try{ \r
- switch(typeMsg){ \r
- case nsIMsgCompType.Draft:\r
- case nsIMsgCompType.Template:\r
- case nsIMsgCompType.Reply:\r
- case nsIMsgCompType.ReplyAll:\r
- case nsIMsgCompType.ReplyToSender: \r
- case nsIMsgCompType.ForwardInline: \r
- case nsIMsgCompType.ForwardAsAttachment: \r
- var uriMsg = null;\r
- if( args){\r
- uriMsg = args.originalMsgURI; \r
- }else{\r
- if(gMsgCompose) uriMsg = gMsgCompose.originalMsgURI; \r
- }\r
- XimfmailGetMessage(uriMsg,XimfmailParseAndUpdateComposeMesssage); \r
- break;\r
- default : \r
- LoadXimfmailPanel(currentInstance);\r
- break;\r
- }\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - XimfmailStartup ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
- } \r
- //gConsole.logStringMessage("DBG [ximfmail - messengerCompose - XimfmailStartup ] \n XIMF instance : "+ currentInstance + "\n XIMF definition : " + current_definition);\r
-}\r
-\r
-/*\r
- * Get Extended headers of messages and display known instances\r
- */\r
-function XimfmailParseAndUpdateComposeMesssage(msgSrc,uriSrc){\r
- \r
- var currentXimfHdrArray = XimfmailParseMessage(msgSrc);\r
- var ximfMsg = new XimfmailMesssage();\r
- if(ximfMsg.init(uriSrc,currentXimfHdrArray)){\r
- LoadXimfmailPanel(ximfMsg._instanceMsgXimf);\r
- ComputeWithForm(ximfMsg);\r
- }else{ \r
- $("#ximfmailComposeMessageTitle").attr("value","");\r
- $("#isUsingXimfail").attr("hidden","false");\r
- //remove ximf events ...\r
- HideSendMessageElements(true);\r
- $("#addressingWidget").unbind("command",SpecialXimfRule_CheckAddress);\r
- ReloadSecurityAccess();\r
- }\r
-}\r
-\r
-/*\r
- * \r
+var gcounterStarter = 1;\r
+/**\r
+ * mail:composeOnSend observer\r
+ * Add XIMF Headers to MIME message\r
*/\r
-function LoadXimfmailPanel(currentInstance){\r
- try{\r
- ReloadSecurityAccess(); // reload security user functions\r
- }catch(e){}\r
- gConsole.logStringMessage("DBG [ximfmail - messengerCompose - LoadXimfmailPanel ] \n XIMF instance : "+ currentInstance);\r
- if(currentInstance){\r
- InsertXimfmailComposer(currentInstance);\r
- gCurrentInstance = currentInstance;\r
- // ximfmail composer is initialized, event-it \r
- var event = document.createEvent('Events');\r
- event.initEvent('compose-ximfmail-init', false, true);\r
- document.getElementById("msgcomposeWindow").dispatchEvent(event);\r
- } \r
-}\r
-\r
-// overload Trustedbird function : add verifications on security message\r
-SendMessage = function(){\r
- if(CheckIfMustBSigned()){ return false;}\r
- dump("SendMessage from XUL\n");\r
- GenericSendMessage(nsIMsgCompDeliverMode.Now);\r
-};\r
-\r
-// overload Trustedbird function : add verifications on security message\r
-SendMessageLater = function(){\r
- if(CheckIfMustBSigned()){ return false;}\r
- dump("SendMessageLater from XUL\n");\r
- GenericSendMessage(nsIMsgCompDeliverMode.Later);\r
-};\r
-\r
-/*\r
- * is XIMFMAIL message ?\r
- * yes : check if message must be signed\r
- * no : continue\r
- */\r
-function CheckIfMustBSigned(){ \r
- try{\r
-\r
- var arrSecureHdrs = CreateRulesArray(gCurrentInstance,"ximf:secureHeaders"); \r
- var arrSecurityLabelHdrs = CreateRulesArray(gCurrentInstance,"ximf:securityLabel");\r
- if(arrSecureHdrs.length > 0 || arrSecurityLabelHdrs.length > 0){ \r
- if(!gSMFields.signMessage){ \r
- // current message must be secured\r
- toggleSignMessage(); \r
- if (!gCurrentIdentity.getUnicharAttribute("signing_cert_name")){ \r
- return true;\r
- }else{ \r
- if(!gSMFields.signMessage){\r
- // certificate is set by user\r
- toggleSignMessage();\r
- }\r
- }\r
- }\r
- }\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - SendMessage_Ximf ] not a ximf message... \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
- }\r
- return false;\r
-}\r
-\r
-/*\r
- * \r
- */\r
-var ximfmailOnSend = {\r
+var XimfMsgSend = XimfMsgSend || {};\r
+XimfMsgSend = {\r
observe: function(subject, topic, data) {\r
- if(!gCurrentIdentity) return; \r
- try{\r
- var msgCompFields = gMsgCompose.compFields; \r
+ if (!gCurrentIdentity) {\r
+ return;\r
+ }\r
+ try {\r
+ var msgCompFields = gMsgCompose.compFields;\r
var charSet = null;\r
charSet = msgCompFields.characterSet;\r
if(!charSet){\r
- charSet == msgCompFields.defaultCharacterSet;\r
+ charSet === msgCompFields.defaultCharacterSet;\r
}\r
- \r
var currCompfieldsotherHeaders = msgCompFields.otherRandomHeaders;\r
- var addCompfieldsotherHeaders = "";\r
- //alert("currCompfieldsotherHeaders = " + currCompfieldsotherHeaders)\r
- // insert extended headers in sending message\r
- var headersToSend = ReadMimeHeadersSelection( XIMF_ENDLINE, charSet);\r
- if(msgCompFields && headersToSend){ \r
- //msgCompFields.otherRandomHeaders += headersToSend; \r
- addCompfieldsotherHeaders += headersToSend;\r
+ // add headers of ximf instance\r
+ var addCompfieldsotherHeaders = "";\r
+ var ximfCatalog = XimfCatalog.getInstance();\r
+ if (ximfCatalog) {\r
+ var ximfName = ximfConst.DEFAULT_XIMF_NAME;\r
+ ximfName = ximfCatalog.getNameInstance(gXimfHdrs.getXimfInstanceResource());\r
+ try {\r
+ if (ximfName.toLowerCase() === ximfConst.SMTP_INSTANCE_KEY) {\r
+ // FT INT_FT3970\r
+ gConsole.logStringMessage("[ximfmail - ximfmailOnSend ] Send non XIMF message - instance " + ximfName);\r
+ } else {\r
+ addCompfieldsotherHeaders += EncodeMimeXimfheader(ximfConst.XIMF_NAME_HEADER, ximfName, charSet) + ximfConst.XIMF_ENDLINE;\r
+ // insert XIMF-Version - B4521\r
+ var ximfVersion = ximfConst.DEFAULT_XIMF_VERSION;\r
+ ximfVersion = ximfCatalog.getVersionInstance(gXimfHdrs.getXimfInstanceResource());\r
+ addCompfieldsotherHeaders += EncodeMimeXimfheader(ximfConst.XIMF_VERSION_HEADER, ximfVersion, charSet) + ximfConst.XIMF_ENDLINE;\r
+ // insert extended headers in sending message\r
+ var headersToSend = ReadMimeHeadersSelection(ximfConst.XIMF_ENDLINE, charSet);\r
+ if (headersToSend) {\r
+ addCompfieldsotherHeaders += headersToSend;\r
+ gConsole.logStringMessage("[XimfMsgSend] Ximf header added to send message!");\r
+ }\r
+ }\r
+ } catch(ex) {\r
+ gConsole.logStringMessage("[XimfMsgSend]Exception : " + ex + "\nfile : " + Error().fileName + "\nline : " + Error().lineNumber);\r
+ }\r
}\r
- \r
// apply xsmtp rules instances\r
- if(gCurrentIdentity.getBoolAttribute("ximfmail_xsmtp_compatibility_on")){ \r
- var xsmtpHeadersToSend = ReadXsmptHeadersTranslation(XIMF_SEPARATOR_HEADER, XIMF_ENDLINE,charSet);\r
- if(msgCompFields && xsmtpHeadersToSend){\r
- //msgCompFields.otherRandomHeaders += xsmtpHeadersToSend;\r
+ if (gCurrentIdentity.getBoolAttribute("ximfmail_xsmtp_compatibility_on")) {\r
+ var xsmtpHeadersToSend = ReadXsmptHeadersTranslation(ximfConst.XIMF_SEPARATOR_HEADER, ximfConst.XIMF_ENDLINE,charSet);\r
+ if (xsmtpHeadersToSend) {\r
addCompfieldsotherHeaders += xsmtpHeadersToSend;\r
- gConsole.logStringMessage("[ximfmail - ximfmailOnSend ] \n compatibility xsmtp process");\r
+ gConsole.logStringMessage("[XimfMsgSend]XSMTP compatibility process");\r
}\r
}\r
- \r
// add ximf headers 1 time - copy last XIMF entries\r
- if(currCompfieldsotherHeaders.length <= 0 ){\r
+ if (currCompfieldsotherHeaders.length <= 0 ) {\r
msgCompFields.otherRandomHeaders = addCompfieldsotherHeaders;\r
- }else{\r
- var regCRLF = new RegExp(XIMF_ENDLINE, "g"); \r
+ } else {\r
+ var regCRLF = new RegExp(ximfConst.XIMF_ENDLINE, "g");\r
var arrayAddCompfieldsotherHeaders = addCompfieldsotherHeaders.split(regCRLF);\r
var arrayCurrCompfieldsotherHeaders = currCompfieldsotherHeaders.split(regCRLF);\r
- for(i=0 ; i<arrayAddCompfieldsotherHeaders.length ; ++i){\r
+ for (var i=0; i < arrayAddCompfieldsotherHeaders.length; ++i) {\r
var tmpAdd = arrayAddCompfieldsotherHeaders[i].slice(0,arrayAddCompfieldsotherHeaders[i].indexOf(":",0));\r
- if(tmpAdd !=""){\r
- for(j=0 ; j<arrayCurrCompfieldsotherHeaders.length ; ++j){\r
+ if (tmpAdd !=="") {\r
+ for (j=0 ; j<arrayCurrCompfieldsotherHeaders.length ; ++j) {\r
var tmpCurr = arrayCurrCompfieldsotherHeaders[j].slice(0,arrayCurrCompfieldsotherHeaders[j].indexOf(":",0));\r
- if(tmpCurr != ""){\r
- if(tmpCurr == tmpAdd){ \r
- arrayCurrCompfieldsotherHeaders[j] = arrayAddCompfieldsotherHeaders[i];\r
- arrayAddCompfieldsotherHeaders[i] = "";\r
- break;\r
- }\r
+ if (tmpCurr !== "" && tmpCurr === tmpAdd) {\r
+ arrayCurrCompfieldsotherHeaders[j] = arrayAddCompfieldsotherHeaders[i];\r
+ arrayAddCompfieldsotherHeaders[i] = "";\r
+ break;\r
}\r
}\r
}\r
}\r
- \r
//update new selection\r
var arrayAddCompfieldsotherHeaders2 = new Array();\r
- for(i=0 ; i<arrayAddCompfieldsotherHeaders.length ; ++i){;\r
- if(arrayAddCompfieldsotherHeaders[i]!= ""){\r
+ for (var i=0 ; i<arrayAddCompfieldsotherHeaders.length ; ++i) {;\r
+ if (arrayAddCompfieldsotherHeaders[i]!== "") {\r
arrayAddCompfieldsotherHeaders2.push(arrayAddCompfieldsotherHeaders[i]);\r
}\r
- } \r
- // insert header \r
- msgCompFields.otherRandomHeaders = arrayCurrCompfieldsotherHeaders.join(XIMF_ENDLINE);\r
- if(arrayAddCompfieldsotherHeaders2.length>0){\r
- msgCompFields.otherRandomHeaders += arrayAddCompfieldsotherHeaders2.join(XIMF_ENDLINE);\r
+ }\r
+ // insert header\r
+ msgCompFields.otherRandomHeaders = arrayCurrCompfieldsotherHeaders.join(ximfConst.XIMF_ENDLINE);\r
+ if (arrayAddCompfieldsotherHeaders2.length>0) {\r
+ msgCompFields.otherRandomHeaders += arrayAddCompfieldsotherHeaders2.join(ximfConst.XIMF_ENDLINE);\r
}\r
}\r
- \r
// append Security labels\r
AppendESSSecuityLabel();\r
}catch(e){\r
- gConsole.logStringMessage("[ximfmail - ximfmailOnSend ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber); \r
- } \r
+ gConsole.logStringMessage("[XimfMsgSend] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
}\r
-};
\ No newline at end of file
+};\r
+/**\r
+ * (Re)open message composer with XIMF instance\r
+ */\r
+var XimfMsgCompose = XimfMsgCompose || {};\r
+XimfMsgCompose = { \r
+ maxNbStarter : 20,\r
+ counterStarter : 0,\r
+ catalog: null,\r
+ currentInstance : undefined,\r
+ preinit: function(){\r
+ var objMsgCompose = this;\r
+ XimfCatalogFactory.getIntance(function (instance) {\r
+ gConsole.logStringMessage("[ximfmail - XimfMsgCompose ] instance of catalog ready to use, init composer...");\r
+ objMsgCompose.catalog = instance;\r
+ objMsgCompose.init();\r
+ });\r
+ },\r
+ init: function () {\r
+ // ximfmail not requested\r
+ gConsole.logStringMessage("[ximfmail - XimfMsgCompose ] init begin...");\r
+ var prefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch(null);\r
+ var showXimfmail = prefBranch.getBoolPref("mailnews.headers.showXimfmail");\r
+ //ResetXimfhdrsDom();\r
+ if (showXimfmail === false) {\r
+ gConsole.logStringMessage("[ximfmail - XimfMsgCompose ] no ximfmail composerfor this message");\r
+ $("#isUsingXimfail").attr("hidden","true");\r
+ try{\r
+ //remove ximf events ...\r
+ HideSendMessageElements(true);\r
+ $("#addressingWidget").unbind("command",SpecialXimfRule_CheckAddress);\r
+ ReloadSecurityAccess();\r
+ }catch(e){\r
+ }\r
+ return;\r
+ }\r
+ // let's compose ximf message\r
+ gConsole.logStringMessage("[ximfmail - XimfMsgCompose ] instance of ximfmail has to be loaded");\r
+ var o = this;\r
+ $("#isUsingXimfail").attr("hidden","false");\r
+ // observer on sending message\r
+ var ximfmailObserverSvc = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);\r
+ ximfmailObserverSvc.addObserver(XimfMsgSend, "mail:composeOnSend", false);\r
+ // add catalog\r
+ XimfMsgSend.ximfCatalog = o.catalog;\r
+ // check message type\r
+ try {\r
+ // is Template or Draft message\r
+ var typeMsg = -1;\r
+ var args = window.arguments[0];\r
+ if (args) {\r
+ typeMsg = args.type;\r
+ } else {\r
+ if (gMsgCompose) {\r
+ typeMsg = gMsgCompose.type;\r
+ }\r
+ }\r
+ switch (typeMsg) {\r
+ case nsIMsgCompType.Draft:\r
+ case nsIMsgCompType.Template:\r
+ case nsIMsgCompType.Reply:\r
+ case nsIMsgCompType.ReplyAll:\r
+ case nsIMsgCompType.ReplyToSender:\r
+ case nsIMsgCompType.ForwardInline:\r
+ case nsIMsgCompType.ForwardAsAttachment:\r
+ var uriMsg = null;\r
+ if (args) {\r
+ uriMsg = args.originalMsgURI;\r
+ } else {\r
+ if (gMsgCompose) {\r
+ uriMsg = gMsgCompose.originalMsgURI;\r
+ }\r
+ } \r
+ ResetXimfhdrsDom();\r
+ XimfmailGetMessage(uriMsg, function (msgSrc,uriSrc) {\r
+ // Get Extended headers of messages and display known instances\r
+ var currentXimfHdrArray = XimfmailParseMessage(msgSrc);\r
+ var ximfMsg = new XimfmailMesssage();\r
+ if (ximfMsg.init(uriSrc,currentXimfHdrArray)) {\r
+ gConsole.logStringMessage("[ximfmail - XimfMsgCompose ] parse original message and load Ximf instance " + ximfMsg._instanceMsgXimf);\r
+ o.currentInstance = ximfMsg._instanceMsgXimf;\r
+ o.loadPanel();\r
+ ComputeWithForm(ximfMsg);\r
+ } else {\r
+ $("#ximfmailComposeMessageTitle").attr("value","");\r
+ $("#isUsingXimfail").attr("hidden","false");\r
+ HideSendMessageElements(true);\r
+ $("#addressingWidget").unbind("command",SpecialXimfRule_CheckAddress);\r
+ ReloadSecurityAccess();\r
+ }\r
+ });\r
+ break;\r
+ default :\r
+ // default instance of account loaded\r
+ o.currentInstance = prefBranch.getCharPref("ximfmail.composeMsg.instance");\r
+ gConsole.logStringMessage("[ximfmail - XimfMsgCompose ] load Ximf instance " + o.currentInstance);\r
+ o.loadPanel();\r
+ break;\r
+ }\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - XimfMsgCompose ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
+ } \r
+ },\r
+ loadPanel : function () {\r
+ gConsole.logStringMessage("[XimfMsgCompose:loadPanel ] XIMF instance : " + this.currentInstance);\r
+ try{\r
+ // reload security user functions\r
+ ReloadSecurityAccess();\r
+ }catch(e){}\r
+ \r
+ if (this.currentInstance) {\r
+ try {\r
+ gCurrentInstance = this.currentInstance;\r
+ if (null !== gXimfHdrs) {\r
+ gXimfHdrs = null;\r
+ }\r
+ gXimfHdrs = new XimfmailInstanceHeaders();\r
+ gXimfHdrs.init(gCurrentInstance);\r
+ gXimfHdrs.loadXimfSecurityRules(gCurrentIdentity);\r
+ InsertXimfhdrsDom(gXimfHdrs.getXimfInstanceResource(), ximfConst.CHROME_XSL_MSG_COMPOSE, this.catalog);\r
+ // controler init\r
+ LoadXimfhdrsEventObserver();\r
+ ExecuteXimfHdrsDefaultValuesRule();\r
+ InitSpecialXimfRules();\r
+ CheckXimfhdrsSelection();\r
+ }catch(e){\r
+ gConsole.logStringMessage("[ximfmail - InsertXimfmailComposer ] " + e +"\nline : " + e.lineNumber + " : "+ e + "\nfile : "+ Error().fileName);\r
+ }\r
+ }\r
+ // ximfmail composer is initialized, event-it\r
+ var event = document.createEvent('Events');\r
+ event.initEvent('compose-ximfmail-init', false, true);\r
+ document.getElementById("msgcomposeWindow").dispatchEvent(event);\r
+ }\r
+};\r
+/**\r
+ * wait for thunderbird context before initializing ximfmail composer\r
+ * @returns\r
+ */\r
+function ximfMsgComposeStarter() {\r
+ var maxNbStarter = 20;\r
+ gConsole.logStringMessage("[ximfmail - ximfMsgComposeStarter ]start try " + gcounterStarter + "/" + maxNbStarter + " - gCurrentIdentity = " + gCurrentIdentity.key);\r
+ if (!gCurrentIdentity) {\r
+ try{\r
+ // try to get identity\r
+ // copy code from LoadIdentity(startup) function of MsgComposeCommand.js file\r
+ var identityElement = document.getElementById("msgIdentity");\r
+ if (identityElement) {\r
+ gCurrentIdentity = MailServices.accounts.getIdentity(identityElement.value);\r
+ }\r
+ }catch(e){\r
+ gConsole.logStringMessage("[ximfmail - ximfMsgComposeStarter ] error : " + e);\r
+ }\r
+ gConsole.logStringMessage("[ximfmail - ximfMsgComposeStarter ] get gCurrentIdentity = " + gCurrentIdentity.key);\r
+ // I can't catch event on completely initialized compose message, so loop on gCurrentIdentity loaded\r
+ if (gcounterStarter < maxNbStarter) {\r
+ gcounterStarter++;\r
+ setTimeout(function() {\r
+ ximfMsgComposeStarter();\r
+ }, 50);\r
+ return;\r
+ }\r
+ }\r
+ // init XimfMsgCompose\r
+ gConsole.logStringMessage("[ximfmail - ximfMsgComposeStarter ] Init XimfMsgCompose with identity " + gCurrentIdentity.key);\r
+ XimfMsgCompose.preinit();\r
+}\r
+//init ximfmail document\r
+window.addEventListener("compose-window-reopen", function() {\r
+ XimfMsgCompose.init(); \r
+ }, true);\r
+window.addEventListener("compose-window-init", function() {\r
+ gConsole.logStringMessage("[ximfmail - ximfMsgComposeStarter ] compose-window-init event catched! ");\r
+ gcounterStarter = 1;\r
+ ximfMsgComposeStarter(); \r
+ }, true);\r
+// overload Trustedbird function : add verifications on security message\r
+SendMessage = function(){\r
+ if (CheckIfMustBSigned()) {\r
+ return false;\r
+ }\r
+ GenericSendMessage(nsIMsgCompDeliverMode.Now);\r
+};\r
+// overload Trustedbird function : add verifications on security message\r
+SendMessageLater = function() {\r
+ if(CheckIfMustBSigned()){\r
+ return false;\r
+ }\r
+ GenericSendMessage(nsIMsgCompDeliverMode.Later);\r
+};\r
+/*\r
+ * is XIMFMAIL message ?\r
+ * yes : check if message must be signed\r
+ * no : continue\r
+ */\r
+function CheckIfMustBSigned() {\r
+ try {\r
+ var arrSecureHdrs = CreateRulesArray(gCurrentInstance,"ximf:secureHeaders");\r
+ var arrSecurityLabelHdrs = CreateRulesArray(gCurrentInstance,"ximf:securityLabel");\r
+ if ((arrSecureHdrs.length > 0 || arrSecurityLabelHdrs.length > 0) && !gSMFields.signMessage) {\r
+ // current message must be secured\r
+ toggleSignMessage();\r
+ if (!gCurrentIdentity.getUnicharAttribute("signing_cert_name")) {\r
+ return true;\r
+ } else {\r
+ if (!gSMFields.signMessage) {\r
+ // certificate is set by user\r
+ toggleSignMessage();\r
+ }\r
+ }\r
+ }\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - SendMessage_Ximf ] not a ximf message... \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
+ }\r
+ return false;\r
+}
\ No newline at end of file
<!-- ***** BEGIN LICENSE BLOCK *****\r
- Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
- ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- - \r
-\r
- - Redistribution and use, in source and binary forms, with or without modification, \r
+ -\r
+ - Redistribution and use, in source and binary forms, with or without modification,\r
- are permitted provided that the following conditons are met :\r
-\r
- - 1. Redistributions of source code must retain the above copyright notice, \r
- - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ - 1. Redistributions of source code must retain the above copyright notice,\r
+ - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
- in the redistribution of the source code.\r
- - 3. Neither the names of the copyright holders nor the names of any contributors \r
- - may be used to endorse or promote products derived from this software without specific \r
+ - 3. Neither the names of the copyright holders nor the names of any contributors\r
+ - may be used to endorse or promote products derived from this software without specific\r
- prior written permission from EADS Defence and Security.\r
- - \r
+ -\r
- Alternatively, the contents of this file may be used under the terms of\r
- either of the GNU General Public License Version 2 or later (the "GPL"),\r
- or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
- and other provisions required by the GPL or the LGPL. If you do not delete\r
- the provisions above, a recipient may use your version of this file under\r
- the terms of any one of the MPL, the GPL or the LGPL.\r
- - \r
+ -\r
- REMINDER :\r
- - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
- IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- - \r
- - EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ -\r
+ - EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ - \r
+ - Contributor(s):\r
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
- ***** END LICENSE BLOCK ***** -->\r
\r
<!-- Feuilles de style -->\r
\r
<overlay id="ov-composeMsg"\r
xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"\r
- xmlns:html="http://www.w3.org/1999/xhtml"> \r
- \r
+ xmlns:html="http://www.w3.org/1999/xhtml">\r
<script type="application/javascript" src="chrome://ximfmail/content/jquery.js" />\r
- <script type="application/javascript" src="chrome://ximfmail/content/messengerCompose-ov-ximfmail.js" /> \r
<script type="application/javascript" src="chrome://ximfmail/content/constant-ximfmail.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/ximfCatalog.js" />\r
- <script type="application/javascript" src="chrome://ximfmail/content/ximfmail.js" /> \r
+ <script type="application/javascript" src="chrome://ximfmail/content/ximfmail.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/ximfDataSource.js" />\r
<script type="application/javascript" src="chrome://ximfmail/content/messageAnalyser-ximfmail.js" />\r
- <script type="application/javascript" src="chrome://ximfmail/content/messengerComposeHeaders-ximfmail.js" /> \r
- <script type="application/javascript" src="chrome://ximfmail/content/ximfSpecial.js" /> \r
- <script type="application/javascript" src="chrome://messenger/content/messengercompose/addressingWidgetOverlay.js"/>\r
- \r
- <broadcasterset>\r
+ <script type="application/javascript" src="chrome://ximfmail/content/messengerComposeHeaders-ximfmail.js" />\r
+ <script type="application/javascript" src="chrome://ximfmail/content/ximfSpecial.js" />\r
+ <script type="application/javascript" src="chrome://messenger/content/messengercompose/addressingWidgetOverlay.js"/>\r
+ <script type="application/javascript" src="chrome://ximfmail/content/messengerCompose-ov-ximfmail.js" /> \r
+ <broadcasterset id="composeBroadcasters">\r
<broadcaster id="isShowingXimfail" hidden="false"/>\r
<broadcaster id="isUsingXimfail" hidden="false"/>\r
</broadcasterset>\r
<button class="ximfmailButton" id="ximfmailComposeMessageMaximize" tooltiptext="&ximfmail.compose.focus;" accesskey="+" hidden="true" />\r
<button class="ximfmailButton" id="ximfmailComposeMessageMinimize" tooltiptext="&ximfmail.compose.unfocus;" accesskey="-" />\r
<image id="ximfmailComposeMessageLogo"/>\r
- <label id="ximfmailComposeMessageTitle" value="&ximfmail.compose.headerTab;" /> \r
+ <label id="ximfmailComposeMessageTitle" value="&ximfmail.compose.headerTab;" />\r
<spacer flex="1" />\r
- </hbox> \r
- <tabbox id="ximfmailComposeMessageHeadersTablist" observes="isShowingXimfail" handleCtrlTab="true" eventnode="parent"/> \r
+ </hbox>\r
+ <tabbox id="ximfmailComposeMessageHeadersTablist" observes="isShowingXimfail" handleCtrlTab="true" eventnode="parent"/>\r
</vbox>\r
- </toolbar> \r
+ </toolbar>\r
</toolbox>\r
</overlay>
\ No newline at end of file
/* ***** BEGIN LICENSE BLOCK *****\r
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
*\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
* are permitted provided that the following conditons are met :\r
*\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
* in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
* prior written permission from EADS Defence and Security.\r
- * \r
+ *\r
* Alternatively, the contents of this file may be used under the terms of\r
* either of the GNU General Public License Version 2 or later (the "GPL"),\r
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
* and other provisions required by the GPL or the LGPL. If you do not delete\r
* the provisions above, a recipient may use your version of this file under\r
* the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
+ *\r
* REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
* ***** END LICENSE BLOCK ***** */\r
-\r
-var gChromeXslMsgCompose = "chrome://theme_ximfmail/content/messengerCompose-ximfmail.xsl";\r
-var gChromeXslSecureHeaders = "chrome://theme_ximfmail/content/secureHeaders-ximfmail.xsl";\r
-var gChromeXslSecurityLabel = "chrome://theme_ximfmail/content/securityLabel-ximfmail.xsl";\r
-var gChomeXulXimfTreeDialog = "chrome://ximfmail/content/dialogTree-ximfmail.xul"; \r
-var gChomeXulXimfCalendarDialog = "chrome://ximfmail/content/calendar/dialogCalendar-ximfmail.xul";\r
-var gChomeXulXimfEditorDialog = "chrome://ximfmail/content/editor/dialogEditor-ximfmail.xul";\r
-\r
-//\r
-function onclosepanel(){\r
- try{\r
- //alert('onclosepanel ' + evt.currentTarget.id)\r
- //var a = document.getElementById("search");\r
+gConsole.logStringMessage("[ximfmail] messengerComposeHeaders-ximfmail.js file loaded ");\r
+var gXimfHdrs = null;\r
+function onclosepanel() {\r
var lisitem = $("#search-panel checkbox");\r
- var resString = ""; \r
- for(var i=0;i<lisitem.length;++i){\r
- if(lisitem[i].hasAttribute("checked"))\r
- resString += $(lisitem[i]).attr("label")+ " | ";\r
+ var resString = "";\r
+ for (i=0;i<lisitem.length;++i) {\r
+ if (lisitem[i].hasAttribute("checked")) {\r
+ resString += $(lisitem[i]).attr("label")+ " | ";\r
+ }\r
}\r
var b = document.getElementById("txtpanel");\r
b.value = resString;\r
- }catch(e){\r
- alert("e = " + e)\r
- } \r
}\r
-\r
-var gXimfHdrs = null; \r
-// \r
-function XimfmailInstanceHeaders(){\r
+function XimfmailInstanceHeaders() {\r
//private:\r
- var _instance = null; \r
+ var _instance = null;\r
var _ximfHdrArray = [];\r
- var _xsmtpHdrArray = []; \r
+ var _xsmtpHdrArray = [];\r
var _eSSSecurityLabelHdrArray = [];\r
var _ximfAssociatedHdrArray = [];\r
var _ximfSpecialRulesArray = []; //FT 3504\r
- \r
//public:\r
- if(typeof XimfmailInstanceHeaders.initialized == "undefined"){ \r
- //\r
+ if (typeof XimfmailInstanceHeaders.initialized === "undefined") {\r
XimfmailInstanceHeaders.prototype.init = function(ximfInstanceResource){\r
- _instance = ximfInstanceResource; \r
+ _instance = ximfInstanceResource;\r
_xsmtpHdrArray = CreateRulesArray(_instance,"ximf:compatibility");\r
- _ximfAssociatedHdrArray = CreateRulesArray(_instance, "ximf:association"); \r
- _ximfSpecialRulesArray = CreateRulesArray(_instance, "ximf:special"); //FT 3504 \r
- }; \r
- // \r
- XimfmailInstanceHeaders.prototype.getXimfInstanceResource = function(){ \r
- return _instance; \r
+ _ximfAssociatedHdrArray = CreateRulesArray(_instance, "ximf:association");\r
+ _ximfSpecialRulesArray = CreateRulesArray(_instance, "ximf:special"); //FT 3504\r
};\r
- //\r
- XimfmailInstanceHeaders.prototype.getXimfHdrArray = function(){ \r
+ XimfmailInstanceHeaders.prototype.getXimfInstanceResource = function(){\r
+ return _instance;\r
+ };\r
+ XimfmailInstanceHeaders.prototype.getXimfHdrArray = function(){\r
return _ximfHdrArray;\r
};\r
- //\r
- XimfmailInstanceHeaders.prototype.getXsmtpHdrArray = function(){ \r
- return _xsmtpHdrArray; \r
+ XimfmailInstanceHeaders.prototype.getXsmtpHdrArray = function(){\r
+ return _xsmtpHdrArray;\r
};\r
- //\r
- XimfmailInstanceHeaders.prototype.getXimfAssociatedHdrArray = function(){ \r
- return _ximfAssociatedHdrArray; \r
+ XimfmailInstanceHeaders.prototype.getXimfAssociatedHdrArray = function(){\r
+ return _ximfAssociatedHdrArray;\r
};\r
- //\r
- XimfmailInstanceHeaders.prototype.getESSSecurityLabelHdrArray = function(){ \r
- return _eSSSecurityLabelHdrArray; \r
+ XimfmailInstanceHeaders.prototype.getESSSecurityLabelHdrArray = function(){\r
+ return _eSSSecurityLabelHdrArray;\r
};\r
//FT 3504\r
- XimfmailInstanceHeaders.prototype.getSpecialRulesArray = function(){ \r
- return _ximfSpecialRulesArray; \r
+ XimfmailInstanceHeaders.prototype.getSpecialRulesArray = function(){\r
+ return _ximfSpecialRulesArray;\r
};\r
- // \r
- XimfmailInstanceHeaders.prototype.loadXimfSecurityRules = function(){\r
- var isToogleSigned = false;\r
+ XimfmailInstanceHeaders.prototype.loadXimfSecurityRules = function(identity){\r
+ var isForceSign = false;\r
// get secure state from prefs\r
- if(!gSMFields){\r
+ if (!gSMFields) {\r
// use Trustedbird function to initialize gSMFields\r
- onComposerReOpen(); \r
+ onComposerReOpen();\r
}\r
-\r
- // secure headers \r
- try{\r
+ // secure headers\r
+ try {\r
// create XMLFile at temp directory with rules datas\r
- var secureHdrArray = [];\r
- secureHdrArray = CreateRulesArray(_instance,"ximf:secureHeaders"); \r
- if(secureHdrArray.length > 0){\r
- var signHeaders = CreateDOMWithXimfInstance(_instance,gChromeXslSecureHeaders); \r
- if(signHeaders){\r
- var file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile); // get profile folder\r
- var serializer = new XMLSerializer();\r
- var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);\r
- \r
- file.append(XIMFMAIL_SECURE_HEADERS_XML_FILE);\r
- foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate\r
- serializer.serializeToStream(signHeaders, foStream, ""); // rememeber, doc is the DOM tree\r
- foStream.close();\r
- \r
- // set folder datas\r
- gCurrentIdentity.setCharAttribute("secureheaders.folderdata",file.path);\r
- \r
- // message with secure headers : force sign message\r
- gCurrentIdentity.setBoolAttribute("secureheaders.checked",true);\r
- $("#idItemSecureHeaders_1").attr("checked","true"); \r
- $("#idItemSecureHeaders_2").attr("checked","true"); \r
- $("#idItemSecureHeaders_1").attr("disabled","true");\r
- $("#idItemSecureHeaders_2").attr("disabled","true"); \r
- \r
- $("#menu_securitySign1").attr("checked","true");\r
- $("#menu_securitySign2").attr("checked","true");\r
- $("#menu_securitySign1").attr("disabled","true");\r
- $("#menu_securitySign2").attr("disabled","true");\r
- \r
- if(!gSMFields.signMessage){\r
- toggleSignMessage();\r
- isToogleSigned = true;\r
- // if certificate problem resolved, try to load ui signature\r
- if (gCurrentIdentity.getUnicharAttribute("signing_cert_name")&&!gSMFields.signMessage){\r
- toggleSignMessage();// certificate is set by user\r
- }\r
- \r
- }\r
- gConsole.logStringMessage("ximfmail - loadSecurityRules - secureHeaders on "); \r
- }\r
- }else{\r
+ if (UpdateSecureHeadersFileSettings (_instance, identity)) {\r
+ // message with secure headers : force sign message\r
+ identity.setBoolAttribute("secureheaders.checked",true);\r
+ setSecureHeaderUI();\r
+ $("#secureHeaderStatus").attr("disabled","true");\r
+ $("#menu_securitySign1").attr("disabled","true");\r
+ $("#menu_securitySign2").attr("disabled","true");\r
+ isForceSign = true;\r
+ gConsole.logStringMessage("ximfmail - loadSecurityRules - secureHeaders on ");\r
+ } else {\r
gConsole.logStringMessage("ximfmail - loadSecurityRules - secureHeaders off ");\r
}\r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - loadSecurityRules - secureHeaders] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
}\r
- // Security Labels \r
+ // Security Labels\r
try{\r
// create XMLFile at temp directory with rules datas\r
_eSSSecurityLabelHdrArray = CreateRulesArray(_instance,"ximf:securityLabel");\r
- if(_eSSSecurityLabelHdrArray.length > 0){ \r
- $("#menu_securityLabelDialog1").attr("checked","true"); \r
+ if (_eSSSecurityLabelHdrArray.length > 0) {\r
+ $("#menu_securityLabelDialog1").attr("checked","true");\r
$("#menu_securityLabelDialog1").attr("disabled","true");\r
- $("#menu_securityLabelDialog2").attr("checked","true"); \r
+ $("#menu_securityLabelDialog2").attr("checked","true");\r
$("#menu_securityLabelDialog2").attr("disabled","true");\r
- \r
- $("#menu_securitySign1").attr("checked","true"); \r
+\r
+ $("#menu_securitySign1").attr("checked","true");\r
$("#menu_securitySign1").attr("disabled","true");\r
$("#menu_securitySign2").attr("checked","true");\r
$("#menu_securitySign2").attr("disabled","true");\r
- \r
- if(!gSMFields.signMessage){\r
- if(!isToogleSigned){\r
- toggleSignMessage();\r
- // if certificate problem resolved, try to load ui signature\r
- if (gCurrentIdentity.getUnicharAttribute("signing_cert_name")&&!gSMFields.signMessage){\r
- toggleSignMessage();// certificate is set by user\r
- }\r
+ if (!gSMFields.signMessage && !isForceSign) {\r
+ toggleSignMessage();\r
+ // if certificate problem resolved, try to load ui signature\r
+ if (identity.getUnicharAttribute("signing_cert_name")&&!gSMFields.signMessage) {\r
+ toggleSignMessage();// certificate is set by user\r
}\r
- } \r
- \r
- // \r
+ }\r
gSMFields.securityClassification = -1;\r
gSMFields.privacyMark = "";\r
- gSMFields.securityCategories = ""; \r
- gConsole.logStringMessage("ximfmail - loadSecurityRules - securityLabels on "); \r
- }else{\r
- gConsole.logStringMessage("ximfmail - loadSecurityRules - securityLabels off "); \r
- } \r
- }catch(e){\r
+ gSMFields.securityCategories = "";\r
+ gConsole.logStringMessage("ximfmail - loadSecurityRules - securityLabels on ");\r
+ } else {\r
+ gConsole.logStringMessage("ximfmail - loadSecurityRules - securityLabels off ");\r
+ }\r
+ } catch(e) {\r
gConsole.logStringMessage("[ximfmail - loadSecurityRules - securityLabel] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
- } \r
+ }\r
};\r
// init object\r
XimfmailInstanceHeaders.initialized = true;\r
}\r
}\r
-\r
-//\r
-function XimfDataSource(){\r
+function XimfDataSource() {\r
this._id; // xml file name path\r
this._dataSource;\r
- this._refDataSource; \r
-}\r
-\r
-//\r
-function InsertXimfmailComposer(currentInstance){\r
- try{\r
- if(gXimfHdrs){gXimfHdrs = null;}\r
- gXimfHdrs = new XimfmailInstanceHeaders();\r
- gXimfHdrs.init(currentInstance);\r
- gXimfHdrs.loadXimfSecurityRules();\r
- \r
- // ihm init \r
- InsertXimfhdrsDom(gXimfHdrs.getXimfInstanceResource(), gChromeXslMsgCompose);\r
- \r
- // controler init \r
- LoadXimfhdrsEventObserver(); \r
- ExecuteXimfHdrsDefaultValuesRule(); \r
- InitSpecialXimfRules();\r
- CheckXimfhdrsSelection();\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - InsertXimfmailComposer ] " + e +"\nline : " + e.lineNumber + " : "+ e + "\nfile : "+ Error().fileName);\r
- }\r
+ this._refDataSource;\r
}\r
-\r
/*\r
* DOM MANIPULATIONS OF XIMFMAIL ELEMENTS\r
*/\r
gConsole.logStringMessage("[ximfmail - ResetXimfhdrsDom ] " + e +"\nline : " + e.lineNumber + " : "+ e + "\nfile : "+ Error().fileName);\r
}\r
}\r
- \r
-function InsertXimfhdrsDom(ximfInstanceResource, urlXslTemplate){\r
- // append to document ximfmail panel ihm \r
- if(!ximfInstanceResource){\r
- $("#isUsingXimfail").attr("hidden","true");\r
- return;\r
- }\r
-\r
- if(gXimfCatalog){\r
- $("#ximfmailComposeMessageTitle").attr("value",gXimfCatalog.getLabelInstance(ximfInstanceResource));\r
- }else{\r
- $("#ximfmailComposeMessageTitle").attr("value","XIMFMAIL");\r
- $("#ximfmailComposeMessageTitle").attr("tooltiptext",ximfInstanceResource);\r
- } \r
- \r
- try{\r
- // Add XSLT result in MessengerCompose window \r
- $("#ximfmailComposeMessageHeadersTablist").append(CreateDOMWithXimfInstance(ximfInstanceResource, urlXslTemplate));\r
- }catch(e){\r
- // TODO : alert user of xslt problem\r
- ("#isUsingXimfail").attr("hidden","true");\r
- } \r
- \r
- // custom panels where maxitem=1 and contains composed elements\r
- var arrPanel = $("panel[ximfmaxitem='1']");\r
- for(var i=0;i<arrPanel.length;++i){ \r
- // checkboxes are used\r
- var chkboxes = $("panel[id='"+arrPanel[i].id+"'] checkbox"); \r
- if(chkboxes.length>=1){ \r
- var mnuitems = $("panel[id='"+arrPanel[i].id+"'] menuitem");\r
- for(j=0;j<mnuitems.length;++j){\r
- var chkbx = document.createElement("checkbox");\r
- $(chkbx).attr("id",$(mnuitems[j]).attr("id"));\r
- $(chkbx).attr("class","ximfCheckbox");\r
- $(chkbx).attr("label",$(mnuitems[j]).attr("label"));\r
- $(chkbx).attr("ximfvalue",$(mnuitems[j]).attr("ximfvalue"));\r
- $(chkbx).attr("ximftextbox",$(mnuitems[j]).attr("ximftextbox"));\r
- if(mnuitems[j].hasAttribute("ximftecvalue"))$(chkbx).attr("ximftecvalue",$(mnuitems[j]).attr("ximftecvalue"));\r
- $(mnuitems[j].parentNode).append(chkbx);\r
- $(mnuitems[j]).remove(); \r
- }\r
+function InsertXimfhdrsDom(ximfInstanceResource, urlXslTemplate, ximfCatalog) {\r
+ // append to document ximfmail panel ihm\r
+ if(!ximfInstanceResource){\r
+ $("#isUsingXimfail").attr("hidden","true");\r
+ return;\r
+ }\r
+ if (ximfCatalog) {\r
+ $("#ximfmailComposeMessageTitle").attr("value",ximfCatalog.getLabelInstance(ximfInstanceResource));\r
+ } else {\r
+ $("#ximfmailComposeMessageTitle").attr("value","XIMFMAIL");\r
+ $("#ximfmailComposeMessageTitle").attr("tooltiptext",ximfInstanceResource);\r
+ }\r
+ try{\r
+ // Add XSLT result in MessengerCompose window\r
+ $("#ximfmailComposeMessageHeadersTablist").append(CreateDOMWithXimfInstance(ximfInstanceResource, urlXslTemplate));\r
+ }catch(e){\r
+ // TODO : alert user of xslt problem\r
+ gConsole.logStringMessage("[ximfmail - ResetXimfhdrsDom ] Error creating ximfmail panel :" + e +"\nline : " + e.lineNumber + " : "+ e + "\nfile : "+ Error().fileName);\r
+ ("#isUsingXimfail").attr("hidden","true");\r
+ }\r
+ // custom panels where maxitem=1 and contains composed elements\r
+ var arrPanel = $("panel[ximfmaxitem='1']");\r
+ for (var idxPnl=0; idxPnl < arrPanel.length; ++idxPnl) {\r
+ // checkboxes are used\r
+ var chkboxes = $("panel[id='"+arrPanel[idxPnl].id+"'] checkbox");\r
+ if (chkboxes.length >= 1) {\r
+ var mnuitems = $("panel[id='"+arrPanel[idxPnl].id+"'] menuitem");\r
+ for (var idxMnuItm=0; idxMnuItm < mnuitems.length; ++idxMnuItm) {\r
+ var chkbx = document.createElement("checkbox");\r
+ $(chkbx).attr("id",$(mnuitems[idxMnuItm]).attr("id"));\r
+ $(chkbx).attr("class","ximfCheckbox");\r
+ $(chkbx).attr("label",$(mnuitems[idxMnuItm]).attr("label"));\r
+ $(chkbx).attr("ximfvalue",$(mnuitems[idxMnuItm]).attr("ximfvalue"));\r
+ $(chkbx).attr("ximftextbox",$(mnuitems[idxMnuItm]).attr("ximftextbox"));\r
+ if (mnuitems[idxMnuItm].hasAttribute("ximftecvalue")) {\r
+ $(chkbx).attr("ximftecvalue",$(mnuitems[idxMnuItm]).attr("ximftecvalue"));\r
}\r
- \r
+ $(mnuitems[idxMnuItm].parentNode).append(chkbx);\r
+ $(mnuitems[idxMnuItm]).remove();\r
}\r
- \r
- // custom input boxes\r
- try{ \r
- var inputPopupList = $("textbox[class='ximfInputbox']");\r
- for(var i = 0; i < inputPopupList.length; ++i){ \r
- var padre = inputPopupList[i].parentNode;\r
- if(padre.nodeName=="popup"){\r
- padre.setAttribute("position", "overlap");\r
- //padre.setAttribute("style", "min-width : 250px; background-color:#5cacea; "); //#48a2e7;\r
- } \r
- } \r
- }catch(err){}\r
- \r
- // internationalisation of ximfmail context popup\r
- try{ \r
- var gBundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);\r
- var stringBundle = gBundle.createBundle("chrome://ximfmail/locale/ximfmail.properties"); \r
- var contextMenuList = $("menuitem[class='ximfContext']");\r
- for(var i=0; i<contextMenuList.length; ++i){\r
- var ilabel = contextMenuList[i].getAttribute("label");\r
- var sLabel = stringBundle.GetStringFromName(ilabel);\r
- if(sLabel!=""){\r
- contextMenuList[i].setAttribute("label",sLabel);\r
- }\r
- }\r
- }catch(err){}\r
- \r
- // Custom Ximf Headers Dom\r
- CustomXimfhdrsInputBox(); \r
- CustomXimfhdrsButton(); \r
- CustomXimfhdrsTreeDialog(); // append DOM elements to access external datas\r
- \r
- // display Ximf elements\r
- $("#isUsingXimfail").attr("hidden","false");\r
-} \r
-\r
+ }\r
+ }\r
+ // custom input boxes\r
+ try {\r
+ var inputPopupList = $("textbox[class='ximfInputbox']");\r
+ for (var idxPpLst = 0; idxPpLst < inputPopupList.length; ++idxPpLst) {\r
+ var padre = inputPopupList[idxPpLst].parentNode;\r
+ if (padre.nodeName === "popup") {\r
+ padre.setAttribute("position", "overlap");\r
+ }\r
+ }\r
+ } catch(err) {}\r
+ // internationalisation of ximfmail context popup\r
+ try {\r
+ var gBundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);\r
+ var stringBundle = gBundle.createBundle("chrome://ximfmail/locale/ximfmail.properties");\r
+ var contextMenuList = $("menuitem[class='ximfContext']");\r
+ for (var idxCtxtMnu=0; idxCtxtMnu<contextMenuList.length; ++idxCtxtMnu) {\r
+ var ilabel = contextMenuList[idxCtxtMnu].getAttribute("label");\r
+ var sLabel = stringBundle.GetStringFromName(ilabel);\r
+ if (sLabel !== "") {\r
+ contextMenuList[idxCtxtMnu].setAttribute("label",sLabel);\r
+ }\r
+ }\r
+ } catch(err) {}\r
+ // Custom Ximf Headers Dom\r
+ CustomXimfhdrsInputBox();\r
+ CustomXimfhdrsButton();\r
+ // append DOM elements to access external datas\r
+ CustomXimfhdrsTreeDialog();\r
+ // display Ximf elements\r
+ $("#isUsingXimfail").attr("hidden","false");\r
+}\r
/*\r
* change ximtextbox elements to edit box\r
*/\r
-function CustomXimfhdrsInputBox(){ \r
+function CustomXimfhdrsInputBox() {\r
var listEditorClass = $("popup > textbox[class='ximfInputbox']");\r
- for(var i = 0 ; i<listEditorClass.length ; ++i){ \r
- try{\r
+ for (var i = 0 ; i<listEditorClass.length ; ++i) {\r
+ try {\r
var idTxtBox = $(listEditorClass[i]).attr("ximfreftextbox");\r
var inputbox = $("textbox[id='"+idTxtBox+"']");\r
- if($(inputbox).attr("class") != "ximfDatetime"){ \r
- var editor_button = $("textbox[id='"+idTxtBox+"']>button"); \r
- $(editor_button).attr("class","ximfmailButtonTxt ximfEditor"); \r
+ if ($(inputbox).attr("class") !== "ximfDatetime") {\r
+ var editor_button = $("textbox[id='"+idTxtBox+"']>button");\r
+ $(editor_button).attr("class","ximfmailButtonTxt ximfEditor");\r
$(editor_button).attr("tooltiptext",getIlkProperties("ximfmail.composer.editor.image"));\r
$(editor_button).attr("refbox",$(inputbox).attr("id"));\r
- \r
$(inputbox).attr("ximfmaxitems", $(listEditorClass[i]).attr("ximfmaxitems"));\r
$(inputbox).attr("ximfminitems", $(listEditorClass[i]).attr("ximfminitems"));\r
$(inputbox).attr("ximseparator", $(listEditorClass[i]).attr("ximseparator"));\r
$(inputbox).removeAttr("popup");\r
$(inputbox).removeAttr("readonly");\r
}\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - CustomXimfhdrsInputBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
- } \r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - CustomXimfhdrsInputBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
+ }\r
}\r
- \r
- try{\r
+ try {\r
// remove popup of free text\r
$("textbox[class='ximfEditor'] ~ popup").remove();\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - CustomXimfhdrsInputBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber); \r
- } \r
-} \r
- \r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - CustomXimfhdrsInputBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);\r
+ }\r
+}\r
/*\r
- * Add international tooltiptext to button \r
- */ \r
-function CustomXimfhdrsButton(){ \r
+ * Add international tooltiptext to button\r
+ */\r
+function CustomXimfhdrsButton() {\r
var listCalendarClass = $("button[class*='ximfDatepicker']");\r
- for(var i = 0 ; i<listCalendarClass.length ; ++i){\r
- try{ \r
- listCalendarClass[i].setAttribute("tooltiptext",getIlkProperties("ximfmail.composer.calendar.image"));\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - customizeCalendarBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : " + e.lineNumber); \r
- } \r
- } \r
+ for (var idxClndr = 0; idxClndr < listCalendarClass.length; ++idxClndr) {\r
+ try {\r
+ listCalendarClass[idxClndr].setAttribute("tooltiptext",getIlkProperties("ximfmail.composer.calendar.image"));\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - customizeCalendarBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : " + e.lineNumber);\r
+ }\r
+ }\r
var listPopupClass = $("button[class*='ximfPopup']");\r
- for(var i = 0 ; i<listPopupClass.length ; ++i){\r
- try{ \r
- listPopupClass[i].setAttribute("tooltiptext",getIlkProperties("ximfmail.composer.popup.image"));\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - customizeCalendarBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : " + e.lineNumber); \r
- } \r
+ for (var idxPp = 0 ; idxPp < listPopupClass.length ; ++idxPp){\r
+ try{\r
+ listPopupClass[idxPp].setAttribute("tooltiptext",getIlkProperties("ximfmail.composer.popup.image"));\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - customizeCalendarBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : " + e.lineNumber);\r
+ }\r
}\r
}\r
-\r
/*\r
* Add informations to load ximfTreeDialog\r
- */ \r
-function CustomXimfhdrsTreeDialog(){ \r
- var listTreeClass = $("box[class='ximfTreeDialog']"); \r
+ */\r
+function CustomXimfhdrsTreeDialog() {\r
+ var listTreeClass = $("box[class='ximfTreeDialog']");\r
for(var i = 0; i<listTreeClass.length;++i){\r
- try{\r
- var idTxtBox = listTreeClass[i].getAttribute("refBox"); \r
- \r
- // create DOM element to acces External Tree Dialog \r
+ try {\r
+ var idTxtBox = listTreeClass[i].getAttribute("refBox");\r
+ // create DOM element to acces External Tree Dialog\r
var data_button = $("textbox[id='"+idTxtBox+"']>button");\r
data_button[0].setAttribute("class", "ximfmailButtonTxt ximfTreeDialog");// insert image in DOM\r
- data_button[0].setAttribute("id","image-"+idTxtBox); \r
+ data_button[0].setAttribute("id","image-"+idTxtBox);\r
data_button[0].setAttribute("refBox",idTxtBox);\r
data_button[0].setAttribute("refExternal",listTreeClass[i].getAttribute("refExternal"));\r
data_button[0].setAttribute("tooltiptext",getIlkProperties("ximfmail.composer.treedlg.image"));\r
- \r
$("textbox[id='"+idTxtBox+"']").attr("refExternal",listTreeClass[i].getAttribute("refExternal"));\r
$("textbox[id='"+idTxtBox+"']").attr("refBox",idTxtBox);\r
$("textbox[id='"+idTxtBox+"']").removeAttr("popup");\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - createButtonsOfExternDatas ] \n " + e + "\nfile : " + Error().fileName+"\nline : " + e.lineNumber); \r
- } \r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - createButtonsOfExternDatas ] \n " + e + "\nfile : " + Error().fileName+"\nline : " + e.lineNumber);\r
+ }\r
}\r
-} \r
- \r
- \r
+}\r
/*\r
* Switch On / Off Ximf DOM\r
*/\r
-function ToogleXimfhdrsPanel(){ \r
- if($("#isShowingXimfail").attr("hidden") == "true"){\r
+function ToogleXimfhdrsPanel(){\r
+ if ($("#isShowingXimfail").attr("hidden") === "true") {\r
$("#isShowingXimfail").attr("hidden","false");\r
- $("#ximfmailComposeMessageMaximize").attr("hidden","true"); \r
- $("#ximfmailComposeMessageMinimize").attr("hidden","false"); \r
- \r
+ $("#ximfmailComposeMessageMaximize").attr("hidden","true");\r
+ $("#ximfmailComposeMessageMinimize").attr("hidden","false");\r
// set focus on first tab\r
try{\r
- var tbox = $("#ximfmailComposeMessageHeadersTablist textbox[class='ximfEditor']"); \r
+ var tbox = $("#ximfmailComposeMessageHeadersTablist textbox[class='ximfEditor']");\r
if(tbox){\r
$(tbox[0]).click();\r
}\r
- }catch(e){} \r
- try{ \r
+ } catch(e) {}\r
+ try {\r
var tab = $("#ximfmailComposeMessageHeadersTablist tab");\r
if(tab){\r
- $(tab[0]).click(); \r
+ $(tab[0]).click();\r
}\r
- }catch(e){} \r
- }else{\r
+ } catch(e) {}\r
+ } else {\r
$("#isShowingXimfail").attr("hidden","true");\r
- $("#ximfmailComposeMessageMaximize").attr("hidden","false"); \r
- $("#ximfmailComposeMessageMinimize").attr("hidden","true"); \r
+ $("#ximfmailComposeMessageMaximize").attr("hidden","false");\r
+ $("#ximfmailComposeMessageMinimize").attr("hidden","true");\r
}\r
-}; \r
-\r
+};\r
/*\r
* manage DOM elements to send message\r
*/\r
-function HideSendMessageElements(isToSend){\r
- if(!isToSend){\r
+function HideSendMessageElements(isToSend) {\r
+ if (!isToSend) {\r
// ihm to unactive sending message\r
- //$("#ximfmailComposeMessageState").attr("class","ximfmailUnacceptState");\r
- $("#button-send").attr("disabled", "true"); \r
- // $("menuitem[key='key_send']").attr("disabled", "true");\r
+ $("#button-send").attr("disabled", "true");\r
$("#menu_File menuitem[command='cmd_sendNow']").attr("hidden", "true");\r
- $("#menu_File menuitem[key='key_sendLater']").attr("hidden", "true"); \r
- }else{\r
+ $("#menu_File menuitem[key='key_sendLater']").attr("hidden", "true");\r
+ } else {\r
// ihm to active sending message\r
- //$("#ximfmailComposeMessageState").attr("class","ximfmailAcceptState");\r
$("#button-send").removeAttr("disabled");\r
- // $("menuitem[key='key_send']").removeAttr("disabled");\r
$("#menu_File menuitem[command='cmd_sendNow']").removeAttr("hidden");\r
- $("#menu_File menuitem[key='key_sendLater']").removeAttr("hidden"); \r
+ $("#menu_File menuitem[key='key_sendLater']").removeAttr("hidden");\r
}\r
-};\r
-\r
+}\r
/*\r
* Open Window to select external datas\r
*/\r
var _dataSourceArray = []; // array of ximfHdr : _ximfHdrArray[ximfHdr]\r
- function OpenTreeDialog(element){\r
- var keyCat = element.getAttribute("refExternal"); \r
+ function OpenTreeDialog(element) {\r
+ var keyCat = element.getAttribute("refExternal");\r
var refBox = element.getAttribute("refBox");\r
var idxDatasSource = -1;\r
var rdfdataSource = null;\r
- var refRdfdataSource = null; \r
- \r
+ var refRdfdataSource = null;\r
// get/create RDF sources\r
- try{ \r
- for(var idx_dataSourceArray = 0; idx_dataSourceArray < _dataSourceArray.length ; ++idx_dataSourceArray){\r
- if(keyCat == _dataSourceArray[idx_dataSourceArray]._id){\r
+ try {\r
+ for (var idx_dataSourceArray = 0; idx_dataSourceArray < _dataSourceArray.length ; ++idx_dataSourceArray) {\r
+ if (keyCat === _dataSourceArray[idx_dataSourceArray]._id) {\r
idxDatasSource = idx_dataSourceArray;\r
- //alert("datasource exist : "+_dataSourceArray[idxDatasSource]._id + "idxDatasSource = " + idxDatasSource);\r
}\r
}\r
- if(idxDatasSource >= 0){\r
- //alert("attach datasource "+_dataSourceArray[idxDatasSource]._refDataSource); \r
+ if (idxDatasSource >= 0) {\r
rdfdataSource = _dataSourceArray[idxDatasSource]._dataSource;\r
refRdfdataSource = _dataSourceArray[idxDatasSource]._refDataSource;\r
- }else{ \r
+ } else {\r
// get xml schema from profile instance directory\r
- var sCompletePath = getFilePathInProfile("extensions/"+gXimfCatalog.getSchemaInstance(gXimfHdrs.getXimfInstanceResource()));\r
- sCompletePath = sCompletePath.substring(0, sCompletePath.lastIndexOf("\\")+1) + keyCat; \r
+ var sCompletePath = getFilePathInProfile("extensions/"+ XimfCatalog.getInstance().getSchemaInstance(gXimfHdrs.getXimfInstanceResource()));\r
+ sCompletePath = sCompletePath.substring(0, sCompletePath.lastIndexOf("\\")+1) + keyCat;\r
var dir = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);\r
- dir.initWithPath( sCompletePath ); \r
- if(!dir.exists()){return;}\r
- \r
+ dir.initWithPath( sCompletePath );\r
+ if (!dir.exists()) {\r
+ return;\r
+ }\r
// create and save datasource\r
xDataSource = new XimfDataSource();\r
- xDataSource._id = keyCat; \r
+ xDataSource._id = keyCat;\r
var res = CreateRdfDatasSource(sCompletePath);\r
rdfdataSource = res._dataSource;\r
- xDataSource._dataSource = rdfdataSource; \r
+ xDataSource._dataSource = rdfdataSource;\r
refRdfdataSource = res._refDataSource;\r
xDataSource._refDataSource = refRdfdataSource;\r
- \r
- //alert("new datasource "+refRdfdataSource); \r
_dataSourceArray.push(xDataSource);\r
- } \r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - addExternDatas ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber); \r
+ }\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - addExternDatas ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);\r
}\r
- \r
- // push datas to new dialog window \r
- try{ \r
- // get informations of datas to load \r
+ // push datas to new dialog window\r
+ try {\r
+ // get informations of datas to load\r
var eltTxtBox = document.getElementById(refBox);\r
- var separator = eltTxtBox.getAttribute(_XIMF_ATT_SEPARATOR) \r
- //args.push(eltTxtBox.getAttribute(_XIMF_ATT_XVALUE)); \r
+ var separator = eltTxtBox.getAttribute(ximfConst._XIMF_ATT_SEPARATOR);\r
var header = document.getElementById(eltTxtBox.getAttribute("refheader"));\r
- \r
// set informations of datas to load\r
- var args = new XimfmailTreedialogArgs(); \r
+ var args = new XimfmailTreedialogArgs();\r
args.dataSource = rdfdataSource;\r
args.refdataSource = refRdfdataSource;\r
args.title = header.getAttribute("value");\r
- args.maxItemsSelected = eltTxtBox.getAttribute(_XIMF_ATT_MAX_ITEMS);\r
- \r
- // push current selection \r
- if(eltTxtBox.value){\r
- try{\r
+ args.maxItemsSelected = eltTxtBox.getAttribute(ximfConst._XIMF_ATT_MAX_ITEMS);\r
+ // push current selection\r
+ if (eltTxtBox.value) {\r
+ try {\r
var currentValue = eltTxtBox.value;\r
- if(args.maxItemsSelected > 1 && separator !="" ){\r
- var reg = new RegExp("["+separator+"]+", "g"); \r
+ if (args.maxItemsSelected > 1 && separator !== "" ) {\r
+ var reg = new RegExp("["+separator+"]+", "g");\r
var arrayItems = currentValue.split(reg);\r
- for(var i=0 ; i<arrayItems.length;++i){\r
- if(arrayItems[i] != "") args.currentKeys.push(arrayItems[i]); \r
+ for(var idxItm=0 ; idxItm < arrayItems.length; ++idxItm){\r
+ if (arrayItems[idxItm] !== "") {\r
+ args.currentKeys.push(arrayItems[idxItm]);\r
+ }\r
}\r
- }else{\r
- // \r
+ } else {\r
args.currentKeys.push(currentValue);\r
- if($(eltTxtBox).attr("tooltiptext")){\r
+ if ($(eltTxtBox).attr("tooltiptext")) {\r
args.currentLabels.push($(eltTxtBox).attr("tooltiptext"));\r
}\r
}\r
}catch(ex){\r
- gConsole.logStringMessage("[ximfmail - OpenTreeDialogBox_Svc ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
+ gConsole.logStringMessage("[ximfmail - OpenTreeDialogBox_Svc ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
}\r
- } \r
- \r
- // open dialog \r
- window.openDialog(gChomeXulXimfTreeDialog,"showmore", "chrome,resizable,centerscreen,modal",args);\r
- \r
- if(args.retIsCancel){\r
- gConsole.logStringMessage("[ximfmail - OpenTreeDialogBox_Svc ] selection has been canceled !"); \r
- return; \r
- }\r
- \r
+ }\r
+ // open dialog\r
+ window.openDialog(ximfConst.CHROME_XSL_TREE_DIALOG,"showmore", "chrome,resizable,centerscreen,modal",args);\r
+ if (args.retIsCancel) {\r
+ gConsole.logStringMessage("[ximfmail - OpenTreeDialogBox_Svc ] selection has been canceled !");\r
+ return;\r
+ }\r
// get for user selection\r
- if(args.retKeys.length > 1){ \r
+ if (args.retKeys.length > 1) {\r
var value = "";\r
- for(var i=0 ; i < args.retKeys.length ; ++i){\r
- if(value == ""){\r
- value = args.retKeys[i];\r
- }else{\r
- value = value + separator + args.retKeys[i];\r
+ for (var idxKey=0 ; idxKey < args.retKeys.length ; ++idxKey) {\r
+ if (value === "") {\r
+ value = args.retKeys[idxKey];\r
+ } else {\r
+ value = value + separator + args.retKeys[idxKey];\r
}\r
}\r
// set new list values\r
eltTxtBox.value = value;\r
- $(eltTxtBox).attr("ximfvalue",value); \r
- $(eltTxtBox).attr("tooltiptext",""); \r
- }else{\r
- if(args.retKeys[0]){\r
+ $(eltTxtBox).attr("ximfvalue",value);\r
+ $(eltTxtBox).attr("tooltiptext","");\r
+ } else {\r
+ if (args.retKeys[0]) {\r
eltTxtBox.value = args.retKeys[0];\r
$(eltTxtBox).attr("ximfvalue",args.retKeys[0]); // used for mandatories headers control rules\r
- $(eltTxtBox).attr("tooltiptext",args.retLabels[0]); \r
- }else{\r
+ $(eltTxtBox).attr("tooltiptext",args.retLabels[0]);\r
+ } else {\r
eltTxtBox.value = "";\r
- $(eltTxtBox).attr("ximfvalue",""); \r
- $(eltTxtBox).attr("tooltiptext",""); \r
+ $(eltTxtBox).attr("ximfvalue","");\r
+ $(eltTxtBox).attr("tooltiptext","");\r
}\r
}\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - addExternDatas ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber); \r
- } \r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - addExternDatas ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);\r
+ }\r
}\r
-\r
/*\r
* Open window to select datetime\r
*/\r
-function OpenCalendarDialog(button){\r
- try{\r
- // get informations of datas to load \r
- var args = []; \r
+function OpenCalendarDialog(button) {\r
+ try {\r
+ // get informations of datas to load\r
+ var args = [];\r
var idBox = button.getAttribute("refBox");\r
var ebox = document.getElementById(idBox);\r
- args.push(idBox); // args[0] : id de la textbox a enrichir\r
- args.push(ebox.value); // displayed date\r
+ // args[0] : id de la textbox a enrichir\r
+ args.push(idBox);\r
+ // displayed date\r
+ args.push(ebox.value);\r
args.push($("label[id='"+ebox.getAttribute("refheader")+"']").attr("value"));\r
-\r
- // open dialog \r
- window.openDialog(gChomeXulXimfCalendarDialog,"showmore", "chrome,resizable,centerscreen,modal",args);\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - openCalendarDialogBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber); \r
- } \r
+ // open dialog\r
+ window.openDialog(ximfConst.CHROME_XSL_DLG_CALENDAR,"showmore", "chrome,resizable,centerscreen,modal",args);\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - openCalendarDialogBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);\r
+ }\r
}\r
-\r
-\r
/*\r
* Open window text editor\r
*/\r
-function OpenEditorDialog(button){\r
- try{\r
+function OpenEditorDialog(button) {\r
+ try {\r
var args=[];\r
var idBox = button.getAttribute("refbox");\r
args.push(idBox);\r
- \r
var ebox = document.getElementById(idBox);\r
- if(ebox){\r
- args.push(ebox.value); \r
- args.push(ebox.getAttribute("ximfseparator")); \r
+ if (ebox) {\r
+ args.push(ebox.value);\r
+ args.push(ebox.getAttribute("ximfseparator"));\r
args.push(ebox.getAttribute("ximfmaxitems"));\r
- args.push(ebox.getAttribute("ximfminitems")); \r
+ args.push(ebox.getAttribute("ximfminitems"));\r
args.push($("label[id='"+ebox.getAttribute("refheader")+"']").attr("value"));\r
- window.openDialog(gChomeXulXimfEditorDialog,"showmore", "chrome,resizable,centerscreen,modal",args);\r
+ window.openDialog(ximfConst.CHROME_XSL_DLG_EDITOR,"showmore", "chrome,resizable,centerscreen,modal",args);\r
}\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - openEditorDialogBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber); \r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - openEditorDialogBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);\r
}\r
}\r
-\r
/*\r
* Open window with complete informations of ximf header\r
*/\r
-function OpenInfoDialog(idBox){ \r
- // get informations of datas to load \r
+function OpenInfoDialog(idBox) {\r
+ // get informations of datas to load\r
var args = [];\r
var txtBox = document.getElementById(idBox);\r
var hLabel = document.getElementById(txtBox.getAttribute("refheader"));\r
args.push(hLabel.getAttribute("value")); // args[0] : id de la textbox a enrichir\r
args.push(hLabel.getAttribute("ximfheader")); // args[1] : ref du catalogue a charger\r
args.push(txtBox.value); // args[2] : titre de la dialogbox\r
- args.push(txtBox.getAttribute("ximfvalue")); // args[3] : description de la dialogbox \r
- if(txtBox.hasAttribute("ximfseparator")){\r
+ args.push(txtBox.getAttribute("ximfvalue")); // args[3] : description de la dialogbox\r
+ if (txtBox.hasAttribute("ximfseparator")) {\r
args.push(txtBox.getAttribute("ximfseparator"));\r
}\r
- // open dialog \r
+ // open dialog\r
window.openDialog("chrome://ximfmail/content/dialogHdrInfo-ximfmail.xul","showmore", "chrome,resizable,centerscreen,modal",args);\r
}\r
-// END DOM FUNCTIONS\r
-\r
/*\r
* EVENT MANAGER OF XIMFMAIL ELEMENTS\r
- */ \r
-function LoadXimfhdrsEventObserver(){ \r
+ */\r
+function LoadXimfhdrsEventObserver () { \r
// animation on ximfmail panel\r
$("#ximfmailComposeMessageMaximize").bind("command",OnClickXimfhdrsBar);\r
$("#ximfmailComposeMessageMinimize").bind("command",OnClickXimfhdrsBar);\r
$("#ximfmailComposeMessageFocusBar").dblclick(OnClickXimfhdrsBar);\r
- \r
- // command events on ximfmail elements \r
- $("button[class='ximfButton']").bind("command",OnSelectButtonPopup); \r
- $("menuitem[class='ximfOkSet']").bind("command",OnSelectCheckPopup); \r
+ // command events on ximfmail elements\r
+ $("button[class='ximfButton']").bind("command",OnSelectButtonPopup);\r
+ $("menuitem[class='ximfOkSet']").bind("command",OnSelectCheckPopup);\r
$("textbox[class='XimfTextboxDisplay']").mouseover(OnHoverTextbox);\r
- $("menuitem[class='ximfContext']").bind("command",OnSelectContextBox); \r
- $("button[class*='ximfEraser']").bind("command",OnClickEraser); \r
+ $("menuitem[class='ximfContext']").bind("command",OnSelectContextBox);\r
+ $("button[class*='ximfEraser']").bind("command",OnClickEraser);\r
$("button[class*='ximfTreeDialog']").bind("command",OnClickTreeDialogButton);\r
- $("button[class*='ximfDatepicker']").bind("command",OnClickDatepicker); \r
+ $("button[class*='ximfDatepicker']").bind("command",OnClickDatepicker);\r
$("textbox[class='ximfEditor']").click(OnXimfhdrsEditor);\r
- $("textbox[class='ximfEditor']").bind("change",OnCheckXimfhdrsEditor); \r
+ $("textbox[class='ximfEditor']").bind("change",OnCheckXimfhdrsEditor);\r
$("button[class*='ximfEditor']").bind("command",OnClickEditorButton);\r
- \r
// check for mandatory ximf headers when editor texbox has changed\r
- $("#ximfmailComposeMessageHeadersTablist textbox").bind("change",function(e){\r
- e.currentTarget.setAttribute("ximfvalue",e.currentTarget.value);\r
- CheckXimfhdrsSelection();});\r
- \r
+ $("#ximfmailComposeMessageHeadersTablist textbox").bind("change", function() {\r
+ $(this).setAttribute("ximfvalue", $(this).value);\r
+ CheckXimfhdrsSelection();\r
+ });\r
// get complete information of ximf hdr\r
- $("button[class*='ximfDetail']").bind("command",function(evt){\r
- OpenInfoDialog($(evt.currentTarget).attr("refLabel")); \r
+ $("button[class*='ximfDetail']").bind("command", function() {\r
+ OpenInfoDialog($(this).attr("refLabel"));\r
});\r
- \r
- // open panel under ximfmail textbox \r
- $("button[class*='ximfPopup']").bind("command",function(evt){\r
- var panel = document.getElementById($(evt.currentTarget).attr("refpanel")); \r
- $("#"+panel.id+" richlistitem").removeAttr("selected"); \r
+ // open panel under ximfmail textbox\r
+ $("button[class*='ximfPopup']").bind("command", function(evt) {\r
+ var panel = document.getElementById($(evt.currentTarget).attr("refpanel"));\r
+ $("#"+panel.id+" richlistitem").removeAttr("selected");\r
$("#"+panel.id+" richlistitem").removeAttr("current");\r
panel.openPopup(evt.currentTarget.parentNode, "after_start", 0, 0, false, false);\r
});\r
- \r
- // menuitem selected for 1 entry header \r
- $("menuitem[class*='ximfItem']").bind("command",function(evt){ \r
- ComputeXimfhdrsMenuItem(evt.currentTarget); \r
- var box = document.getElementById($(evt.currentTarget).attr("ximftextbox")); \r
+ // menuitem selected for 1 entry header\r
+ $("menuitem[class*='ximfItem']").bind("command", function(evt) {\r
+ ComputeXimfhdrsMenuItem(evt.currentTarget);\r
+ var box = document.getElementById($(evt.currentTarget).attr("ximftextbox"));\r
document.getElementById($(box).attr("refpanel")).hidePopup();\r
- }); \r
- \r
- // keyboard event on panel \r
- $("panel").bind("keyup",function(evt){ \r
- if(evt.keyCode == 13){ \r
- var panel = evt.currentTarget; \r
+ });\r
+ // keyboard event on panel\r
+ $("panel").bind("keyup", function(evt) {\r
+ if (evt.keyCode === 13) {\r
+ var panel = evt.currentTarget;\r
var richlistitem = $("#" + evt.currentTarget.id + " richlistitem");\r
- for(var i=0;i<richlistitem.length;++i){\r
- if(richlistitem[i].selected){\r
+ for (i=0;i<richlistitem.length;++i) {\r
+ if (richlistitem[i].selected) {\r
var nodes = richlistitem[i].childNodes;\r
- for(j=0;j<nodes.length;++j){\r
- if(nodes[j].localName=="menuitem"){\r
+ for (j=0;j<nodes.length;++j) {\r
+ if(nodes[j].localName === "menuitem") {\r
ComputeXimfhdrsMenuItem(nodes[j]);\r
var box = document.getElementById($(nodes[j]).attr("ximftextbox"));\r
XimfailComposeCanClose();\r
document.getElementById($(box).attr("refpanel")).hidePopup();\r
return;\r
}\r
- } \r
+ }\r
}\r
}\r
document.getElementById(evt.currentTarget.id).hidePopup();\r
- } \r
+ }\r
});\r
- \r
// checkbox panel is selected\r
- $("panel checkbox").bind("command",function(evt){\r
- ComputePanelOfCheckboxSelection(evt.currentTarget.id)});\r
-\r
+ $("panel checkbox").bind("command",function(evt) {\r
+ ComputePanelOfCheckboxSelection(evt.currentTarget.id);\r
+ });\r
// check richlistitem where ximfchild=true (ximf computestring)\r
- $("panel").bind("popuphiding",function(evt){\r
+ $("panel").bind("popuphiding",function(evt) {\r
var CompstringItem = $("#" + evt.currentTarget.id + " richlistitem[ximfchild='true']");\r
- for(var i=0; i<CompstringItem.length; i++){\r
+ for (i=0; i<CompstringItem.length; ++i) {\r
var chk1 = CompstringItem[i].firstElementChild;\r
- if(chk1.localName == "checkbox"){\r
- if(chk1.checked){ \r
- if(!IsAcceptableXimfCompstring(chk1.id)){\r
- chk1.checked = false;\r
- chk1.removeAttribute("ximfchild");\r
- ComputePanelOfCheckboxSelection(chk1.id);\r
- } \r
- }\r
+ if (chk1.localName === "checkbox" && chk1.checked && !IsAcceptableXimfCompstring(chk1.id)) {\r
+ chk1.checked = false;\r
+ chk1.removeAttribute("ximfchild");\r
+ ComputePanelOfCheckboxSelection(chk1.id);\r
}\r
}\r
- \r
});\r
- \r
// panel can accept more than 1 entry for header\r
- $("panel").bind("popuphidden",function(evt){\r
- if(parseInt($(evt.currentTarget).attr("ximfmaxitem"), 10) > 1 ){\r
+ $("panel").bind("popuphidden", function(evt) {\r
+ if (parseInt($(evt.currentTarget).attr("ximfmaxitem"), 10) > 1 ) {\r
// if panel has XIMF multiset implementation, don't compute it\r
var multisetPanel = $("#" + evt.currentTarget.id + " button[class='ximfButton']");\r
- if(multisetPanel.length <=0){\r
+ if (multisetPanel.length <=0) {\r
ComputeXimfhdrsMultivaluePanel(evt.currentTarget.id);\r
}\r
- }else{\r
+ } else {\r
var nbChk = $("#" + evt.currentTarget.id + " checkbox");\r
- if(nbChk.length > 0 )ComputeXimfhdrsMultivaluePanel(evt.currentTarget.id); \r
+ if (nbChk.length > 0 ) {\r
+ ComputeXimfhdrsMultivaluePanel(evt.currentTarget.id);\r
+ }\r
}\r
XimfailComposeCanClose();\r
- }); \r
- \r
+ });\r
// panel - first entry must be selected before selecting composed item\r
- $("panel").bind("popupshown",function(evt){\r
- if(parseInt($(evt.currentTarget).attr("ximfmaxitem"), 10) <= 1 ) return;\r
- var richitems = $("#" + evt.currentTarget.id + " richlistbox" ).children("richlistitem"); \r
- for(var i=0 ; i<richitems.length; ++i){\r
+ $("panel").bind("popupshown",function(evt) {\r
+ if (parseInt($(evt.currentTarget).attr("ximfmaxitem"), 10) <= 1 ) {\r
+ return;\r
+ }\r
+ var richitems = $("#" + evt.currentTarget.id + " richlistbox" ).children("richlistitem");\r
+ for (var i=0 ; i<richitems.length; ++i) {\r
var chk1 = richitems[i].firstElementChild;\r
- if(chk1.localName == "checkbox"){\r
- if(!chk1.checked){\r
- var eltsChild = richitems[i].getElementsByTagName("checkbox"); \r
- for(j=0 ; j < eltsChild.length; ++j){\r
- $(eltsChild[j]).attr("disabled","true");\r
- }\r
- $(chk1).attr("disabled","false");//.removeAttr("disabled"); \r
+ if (chk1.localName === "checkbox" && !chk1.checked){\r
+ var eltsChild = richitems[i].getElementsByTagName("checkbox");\r
+ for (j=0 ; j < eltsChild.length; ++j) {\r
+ $(eltsChild[j]).attr("disabled","true");\r
}\r
+ $(chk1).attr("disabled","false");\r
}\r
}\r
- }); \r
- \r
+ });\r
// remove css style from mouse item selections\r
- $("#ximfmailComposeMessageHeadersTablist richlistitem").mouseout(function(evt){\r
- if(evt.currentTarget.hasAttribute("selected"))\r
+ $("#ximfmailComposeMessageHeadersTablist richlistitem").mouseout(function(evt) {\r
+ if (evt.currentTarget.hasAttribute("selected")) {\r
$(evt.currentTarget).removeAttr("selected");\r
+ }\r
});\r
-\r
// get document tab control, set focus to ximfmail tabbox\r
- $(document).bind("keypress",function(evt){\r
- if(evt.keyCode == 9 && evt.target.id=="msgSubject"){ // 9: tabuklation keycode\r
- if(document.getElementById("ximfmailComposeMessageMinimize").hasAttribute("hidden")){\r
+ $(document).bind("keypress", function(evt) {\r
+ if (evt.keyCode === 9 && evt.target.id === "msgSubject") { // 9: tabuklation keycode\r
+ if (document.getElementById("ximfmailComposeMessageMinimize").hasAttribute("hidden")) {\r
$("#ximfmailComposeMessageMaximize").focus();\r
- }else{\r
+ } else {\r
$("#ximfmailComposeMessageMinimize").focus();\r
}\r
}\r
- }); \r
-}; \r
-\r
-function OnClickXimfhdrsBar(evt){\r
- ToogleXimfhdrsPanel(); \r
-};\r
-\r
-\r
-function OnSelectButtonPopup(evt){\r
- ComputeXimfhdrsButtonPopup(evt.currentTarget); \r
-};\r
-\r
-function OnSelectCheckPopup(evt){ \r
- ComputeXimfhdrsCheckPopup(evt.currentTarget); \r
-};\r
-\r
-\r
-function OnClickEraser(evt){ \r
+ }); \r
+}\r
+function OnClickXimfhdrsBar(evt) {\r
+ ToogleXimfhdrsPanel();\r
+}\r
+function OnSelectButtonPopup(evt) {\r
+ ComputeXimfhdrsButtonPopup(evt.currentTarget);\r
+}\r
+function OnSelectCheckPopup(evt) {\r
+ ComputeXimfhdrsCheckPopup(evt.currentTarget);\r
+}\r
+function OnClickEraser(evt) {\r
EraseAndComputeXimfhdrsTextbox(document.getElementById(evt.currentTarget.id).getAttribute("refValue"), false);\r
- CheckXimfhdrsSelection();// valid document state\r
-};\r
- \r
-function OnClickTreeDialogButton(evt){ \r
+ // valid document state\r
+ CheckXimfhdrsSelection();\r
+}\r
+function OnClickTreeDialogButton(evt) {\r
OpenTreeDialog(evt.currentTarget);\r
XimfailComposeCanClose();\r
-}; \r
-\r
-function OnClickDatepicker(evt){ \r
+}\r
+function OnClickDatepicker(evt) {\r
OpenCalendarDialog(evt.currentTarget);\r
XimfailComposeCanClose();\r
-}; \r
-\r
-function OnClickEditorButton(evt){\r
+}\r
+function OnClickEditorButton(evt) {\r
OpenEditorDialog(evt.currentTarget);\r
CheckXimfhdrsSelection();\r
XimfailComposeCanClose();\r
-}; \r
-\r
-\r
-function OnXimfhdrsEditor(evt){ \r
- var id = evt.currentTarget.id; \r
+}\r
+function OnXimfhdrsEditor(evt) {\r
+ var id = evt.currentTarget.id;\r
var bx = document.getElementById(id);\r
- bx.focus(); \r
-};\r
-\r
-\r
-function OnHoverTextbox(evt){\r
- try{\r
+ bx.focus();\r
+}\r
+function OnHoverTextbox(evt) {\r
+ try {\r
elt = evt.currentTarget;\r
- tooltext = elt.value; \r
- if(tooltext != ""){ \r
+ tooltext = elt.value;\r
+ if(tooltext !== ""){\r
elt.setAttribute("tooltiptext",tooltext);\r
}else{\r
elt.removeAttribute("tooltiptext");\r
}\r
}catch(e){\r
- gConsole.logStringMessage("[ximfmail - OnHoverXimfTextbox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber); \r
+ gConsole.logStringMessage("[ximfmail - OnHoverXimfTextbox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
}\r
}\r
-\r
/*\r
* Display context menu Ximfmail\r
*/\r
-function OnSelectContextBox(evt){\r
- try{ \r
- idBox = evt.currentTarget.getAttribute("idbox"); \r
+function OnSelectContextBox(evt) {\r
+ try{\r
+ idBox = evt.currentTarget.getAttribute("idbox");\r
var eltTextbox = document.getElementById(idBox);\r
- switch(parseInt(evt.currentTarget.getAttribute("idx"), 10)){ \r
+ switch (parseInt(evt.currentTarget.getAttribute("idx"), 10)) {\r
case 1:\r
// erase all selected values\r
EraseAndComputeXimfhdrsTextbox(eltTextbox.id, true);\r
break;\r
case 2:\r
- // display datas of current XIMF header \r
- if(eltTextbox.value != ""){\r
+ // display datas of current XIMF header\r
+ if(eltTextbox.value !== ""){\r
OpenInfoDialog(idBox);\r
}\r
- break; \r
+ break;\r
default:\r
gConsole.logStringMessage("[ximfmail warning OnSelectXimfmailContextBox] \n unknown choice : "+eltTextbox.getAttribute("idx"));\r
break;\r
}\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - OnSelectXimfmailContextBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - OnSelectXimfmailContextBox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
}\r
}\r
- \r
-function OnCheckXimfhdrsEditor(evt){\r
- try{\r
- //alert(evt.currentTarget.id)\r
+function OnCheckXimfhdrsEditor(evt) {\r
+ try {\r
var domElt = evt.currentTarget;\r
- var maxItems = domElt.getAttribute("ximfmaxitems"); \r
- var separatorItem = domElt.getAttribute("ximfseparator"); \r
- var labelHeader = document.getElementById(domElt.getAttribute("refheader")).getAttribute("value"); \r
- if(maxItems==""){return;} \r
- var dlgEditorXimf_maxItem_alert = maxItems + " "+ getIlkProperties("ximfmail.dialog.editor.warning.nbrows"); \r
- var arrayItem = domElt.value.split(separatorItem); \r
+ var maxItems = domElt.getAttribute("ximfmaxitems");\r
+ var separatorItem = domElt.getAttribute("ximfseparator");\r
+ var labelHeader = document.getElementById(domElt.getAttribute("refheader")).getAttribute("value");\r
+ if(maxItems === "") {\r
+ return;\r
+ }\r
+ var dlgEditorXimf_maxItem_alert = maxItems + " "+ getIlkProperties("ximfmail.dialog.editor.warning.nbrows");\r
+ var arrayItem = domElt.value.split(separatorItem);\r
var nbItems = arrayItem.length;\r
- if(parseInt(maxItems, 10)<arrayItem.length){\r
+ if (parseInt(maxItems, 10)<arrayItem.length) {\r
nbItems = parseInt(maxItems, 10);\r
- ximfAlert(labelHeader,dlgEditorXimf_maxItem_alert); \r
- var newvalue = ""; \r
- for(var i=0 ; i<nbItems ; ++i){\r
- if(arrayItem[i]!=""){\r
- if(i==0)\r
+ ximfAlert(labelHeader,dlgEditorXimf_maxItem_alert);\r
+ var newvalue = "";\r
+ for (var i=0 ; i<nbItems ; ++i) {\r
+ if (arrayItem[i] !== "") {\r
+ if (i===0) {\r
newvalue = arrayItem[i];\r
- else\r
- newvalue += separatorItem + arrayItem[i]; \r
- } \r
+ } else {\r
+ newvalue += separatorItem + arrayItem[i];\r
+ }\r
+ }\r
}\r
domElt.value = newvalue;\r
domElt.inputField = newvalue;\r
- } \r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - OnCheckXimfhdrsEditor ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
+ }\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - OnCheckXimfhdrsEditor ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
}\r
}\r
-\r
-// END EVENT FUNCTIONS\r
-\r
-\r
/*\r
* COMPUTE XIMFMAIL ELEMENTS AND UPDATE DOM\r
*/\r
-function CheckXimfhdrsSelection(){ \r
- try{ \r
+function CheckXimfhdrsSelection() {\r
+ try {\r
var isRuleOk=true;\r
- // apply generic rules \r
- if(!ExecuteXimfHdrsAssociationRule()){isRuleOk=false; } \r
- if(!ExecuteXimfHdrsMandatoryRule()){isRuleOk=false; } \r
- AppendESSSecuityLabel(); \r
- HideSendMessageElements(isRuleOk); \r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - IsReadyToSend ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber); \r
+ // apply generic rules\r
+ if (!ExecuteXimfHdrsAssociationRule()) {\r
+ isRuleOk=false;\r
+ }\r
+ if (!ExecuteXimfHdrsMandatoryRule()) {\r
+ isRuleOk=false;\r
+ }\r
+ AppendESSSecuityLabel();\r
+ HideSendMessageElements(isRuleOk);\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - IsReadyToSend ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
}\r
}\r
-\r
/*\r
* Update Ximf header selected from multi choice panel\r
*/\r
-function ComputeXimfhdrsMultivaluePanel(idPanel){\r
- try{\r
+function ComputeXimfhdrsMultivaluePanel(idPanel) {\r
+ try {\r
var panel = document.getElementById(idPanel);\r
var ximfSeparator = $(panel).attr("ximfseparator");\r
var ximfTecSeparator = $(panel).attr("ximftecseparator");\r
var selectionObject = new Object;\r
selectionObject.value = "";\r
selectionObject.ximfvalue = "";\r
- selectionObject.ximftecvalue = ""; \r
+ selectionObject.ximftecvalue = "";\r
var listRichBox = panel.getElementsByTagName("richlistbox");\r
var childnodes = listRichBox[0].childNodes;\r
- \r
- //\r
- for(var i = 0 ; i < childnodes.length ; i++){ \r
- if(childnodes[i].localName == "richlistitem"){\r
+ for (var i = 0 ; i < childnodes.length ; i++) {\r
+ if (childnodes[i].localName === "richlistitem") {\r
var selectionItem = GetXimfSelectionOfRichlistitem(childnodes[i],ximfSeparator,ximfTecSeparator);\r
- if(selectionItem){ \r
- if(selectionItem.value != ""){\r
- if(selectionObject.value == ""){\r
+ if (selectionItem) {\r
+ if (selectionItem.value !== "") {\r
+ if (selectionObject.value === "") {\r
selectionObject.value = selectionItem.value;\r
selectionObject.ximfvalue = selectionItem.ximfvalue;\r
- if(selectionItem.ximftecvalue != "") selectionObject.ximftecvalue = selectionItem.ximftecvalue;\r
- }else{\r
+ if (selectionItem.ximftecvalue !== "") {\r
+ selectionObject.ximftecvalue = selectionItem.ximftecvalue;\r
+ }\r
+ } else {\r
selectionObject.value += ximfSeparator + selectionItem.value;\r
selectionObject.ximfvalue += ximfSeparator + selectionItem.ximfvalue;\r
- if(selectionItem.ximftecvalue != "") selectionObject.ximftecvalue += ximfTecSeparator + selectionItem.ximftecvalue;\r
+ if (selectionItem.ximftecvalue !== "") {\r
+ selectionObject.ximftecvalue += ximfTecSeparator + selectionItem.ximftecvalue;\r
+ }\r
}\r
- \r
}\r
}\r
}\r
}\r
- \r
// save selection to ximfhdr textbox\r
var hdrTextbox = document.getElementById($(panel).attr("ximfreftextbox"));\r
hdrTextbox.value = selectionObject.value;\r
- $(hdrTextbox).attr("ximfvalue",selectionObject.ximfvalue); \r
+ $(hdrTextbox).attr("ximfvalue",selectionObject.ximfvalue);\r
$(hdrTextbox).attr("ximfseparator",ximfSeparator);\r
- if(selectionObject.ximftecvalue != ""){\r
+ if (selectionObject.ximftecvalue !== "") {\r
$(hdrTextbox).attr("ximftecvalue",selectionObject.ximftecvalue);\r
$(hdrTextbox).attr("ximftecseparator",ximfTecSeparator);\r
- } \r
- \r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - ComputeXimfhdrsMultivaluePanel ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber); \r
- } \r
+ }\r
+ } catch (e) {\r
+ gConsole.logStringMessage("[ximfmail - ComputeXimfhdrsMultivaluePanel ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);\r
+ }\r
}\r
-\r
-\r
/*\r
* Get XIMF informations of composed element\r
*/\r
-function GetXimfSelectionOfRichlistitem(richItem,cSeparator,cTecSeparator){\r
+function GetXimfSelectionOfRichlistitem(richItem,cSeparator,cTecSeparator) {\r
var selectionObject = new Object;\r
selectionObject.value = "";\r
selectionObject.ximfvalue = "";\r
selectionObject.ximftecvalue = "";\r
selectionObject.separator = "";\r
selectionObject.tecseparator = "";\r
- try{\r
+ try {\r
var childnodes = richItem.childNodes;\r
- \r
// single element to decode\r
- if(childnodes.length == 1){\r
+ if (childnodes.length === 1) {\r
return GetXimfValuesOfRichlistItem(childnodes[0]);\r
- } \r
- \r
+ }\r
// multi element to decode\r
- if(!GetXimfValuesOfRichlistItem(childnodes[0])) return selectionObject;\r
+ if (!GetXimfValuesOfRichlistItem(childnodes[0])) {\r
+ return selectionObject;\r
+ }\r
// create array of user informations\r
- var arrItems = new Array(); \r
- for(var i=0 ; i < childnodes.length ; i++){\r
- if(childnodes[i].localName == "vbox"){\r
- var childnodes2 = childnodes[i].childNodes; \r
- for(var j=0 ; j < childnodes2.length ; j++){\r
- var item = GetXimfValuesOfRichlistItem(childnodes2[j].firstChild);\r
- if(item){\r
- arrItems.push(item);\r
- } \r
+ var arrSlaveItems = new Array();\r
+ var masterItem = null;\r
+ for (var idxChilNd=0 ; idxChilNd < childnodes.length ; idxChilNd++) {\r
+ switch (childnodes[idxChilNd].localName) {\r
+ case "checkbox" :\r
+ var item = GetXimfValuesOfRichlistItem(childnodes[idxChilNd]);\r
+ if (item) {\r
+ masterItem = item;\r
+ }\r
+ break;\r
+ case "vbox":\r
+ var childnodes2 = childnodes[idxChilNd].childNodes;\r
+ for (var idxChilNd2 = 0 ; idxChilNd2 < childnodes2.length ; idxChilNd2++) {\r
+ var item = GetXimfValuesOfRichlistItem(childnodes2[idxChilNd2].firstChild);\r
+ if (item) {\r
+ arrSlaveItems.push(item);\r
+ }\r
+ }\r
+ break;\r
+ default:\r
+ var item = GetXimfValuesOfRichlistItem(childnodes[idxChilNd]);\r
+ if (item) {\r
+ arrSlaveItems.push(item);\r
}\r
}\r
- var item = GetXimfValuesOfRichlistItem(childnodes[i]);\r
- if(item){\r
- arrItems.push(item);\r
- } \r
- }\r
- \r
- // format Ximf informations \r
- if(arrItems.length > 1){\r
- for(var i = arrItems.length-1 ; i >= 0 ; --i){\r
- var cConcatId = arrItems[i].concatid;\r
- // get element with id cConcatId\r
- // concat linked values and create formated information\r
- if(arrItems[i].concatid != arrItems[i].id){\r
- for(var j = 0 ; j < arrItems.length ; ++j){\r
- if(arrItems[j].id == cConcatId){\r
- if(selectionObject.value == ""){ \r
- selectionObject.value = arrItems[j].value + arrItems[j].separator + arrItems[i].value;\r
- selectionObject.ximfvalue = arrItems[j].ximfvalue + arrItems[j].separator + arrItems[i].ximfvalue; \r
- if(arrItems[j].ximftecvalue != "")\r
- selectionObject.ximftecvalue = arrItems[j].ximftecvalue + arrItems[j].tecseparator + arrItems[i].ximftecvalue;\r
- }else{\r
- selectionObject.value += cSeparator + arrItems[j].value + arrItems[j].separator + arrItems[i].value;\r
- selectionObject.ximfvalue += cSeparator + arrItems[j].ximfvalue + arrItems[j].separator + arrItems[i].ximfvalue; \r
- if(arrItems[j].ximftecvalue != "")\r
- selectionObject.ximftecvalue += cTecSeparator + arrItems[j].ximftecvalue + arrItems[j].tecseparator + arrItems[i].ximftecvalue;\r
+ }\r
+ // format Ximf informations\r
+ if (arrSlaveItems.length > 0 && masterItem !== null) {\r
+ var newvalue = undefined;\r
+ var newximfvalue = undefined;\r
+ var newximftecvalue = undefined;\r
+ if (masterItem.bfactorise) {\r
+ for (var idxSlvItm = 0 ; idxSlvItm < arrSlaveItems.length ; ++idxSlvItm) {\r
+ // concat linked values\r
+ if (masterItem.id === arrSlaveItems[idxSlvItm].concatid) {\r
+ if ( newvalue === undefined) {\r
+ newvalue = arrSlaveItems[idxSlvItm].value;\r
+ newximfvalue = arrSlaveItems[idxSlvItm].ximfvalue;\r
+\r
+ } else {\r
+ newvalue += masterItem.separator + arrSlaveItems[idxSlvItm].value;\r
+ newximfvalue += masterItem.separator + arrSlaveItems[idxSlvItm].ximfvalue;\r
+ }\r
+ }\r
+ // technical value formating\r
+ if (masterItem.ximftecvalue !== "" || arrSlaveItems[idxSlvItm].ximftecvalue !== "") {\r
+ newximftecvalue = masterItem.ximftecvalue + masterItem.tecseparator + arrSlaveItems[idxSlvItm].ximftecvalue;\r
+ if (newximftecvalue !== undefined) {\r
+ if (selectionObject.ximftecvalue === "" ) {\r
+ selectionObject.ximftecvalue = newximftecvalue;\r
+ } else {\r
+ selectionObject.ximftecvalue += cTecSeparator + newximftecvalue;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ // factorize master item with slaves\r
+ if (!masterItem.bpositionend) {\r
+ newvalue = masterItem.value + " " + newvalue;\r
+ newximfvalue = masterItem.ximfvalue + " " + newximfvalue;\r
+ } else {\r
+ newvalue = newvalue + " " + masterItem.value;\r
+ newximfvalue = newximfvalue + " " + masterItem.ximfvalue;\r
+ }\r
+ // set compstring items\r
+ if (selectionObject.value === "") {\r
+ selectionObject.value = newvalue;\r
+ selectionObject.ximfvalue = newximfvalue;\r
+ } else {\r
+ selectionObject.value += cSeparator + newvalue;\r
+ selectionObject.ximfvalue += cSeparator + newximfvalue;\r
+ }\r
+ } else {\r
+ for (var i = 0 ; i < arrSlaveItems.length ; ++i) {\r
+ // concat linked values and create formated information\r
+ if (masterItem.id === arrSlaveItems[i].concatid) {\r
+ if (!masterItem.bpositionend) {\r
+ newvalue = masterItem.value + masterItem.separator + arrSlaveItems[i].value;\r
+ newximfvalue = masterItem.ximfvalue + masterItem.separator + arrSlaveItems[i].ximfvalue;\r
+ } else {\r
+ newvalue = arrSlaveItems[i].value + masterItem.separator + masterItem.value;\r
+ newximfvalue = arrSlaveItems[i].ximfvalue + masterItem.separator + masterItem.ximfvalue;\r
+ }\r
+ // technical value formating\r
+ if (masterItem.ximftecvalue !== "" || arrSlaveItems[i].ximftecvalue !== "") {\r
+ newximftecvalue = masterItem.ximftecvalue + masterItem.tecseparator + arrSlaveItems[i].ximftecvalue;\r
+ }\r
+ // set compstring items\r
+ if (selectionObject.value === "") {\r
+ selectionObject.value = newvalue;\r
+ selectionObject.ximfvalue = newximfvalue;\r
+ if (newximftecvalue !== undefined) {\r
+ selectionObject.ximftecvalue = newximftecvalue;\r
+ }\r
+ } else {\r
+ selectionObject.value += cSeparator + newvalue;\r
+ selectionObject.ximfvalue += cSeparator + newximfvalue;\r
+ if (newximftecvalue !== undefined) {\r
+ selectionObject.ximftecvalue += cTecSeparator + newximftecvalue;\r
}\r
- arrItems.splice(i,1); // erase array element\r
- break; \r
}\r
}\r
}\r
}\r
- }else{\r
+ } else {\r
// case 1 item is used in item selection\r
- if(arrItems[0].value != ""){\r
- selectionObject.value += arrItems[0].value;\r
- selectionObject.ximfvalue += arrItems[0].ximfvalue; \r
- if(arrItems[0].ximftecvalue != "")\r
- selectionObject.ximftecvalue += arrItems[0].ximftecvalue;\r
- } \r
- } \r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - GetXimfSelectionOfRichlistitem ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
+ if (masterItem.value !== "") {\r
+ selectionObject.value += masterItem.value;\r
+ selectionObject.ximfvalue += masterItem.ximfvalue;\r
+ if (masterItem.ximftecvalue !== "") {\r
+ selectionObject.ximftecvalue += masterItem.ximftecvalue;\r
+ }\r
+ }\r
+ }\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - GetXimfSelectionOfRichlistitem ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
}\r
- return selectionObject; \r
+ return selectionObject;\r
}\r
-\r
/*\r
- * get iformations of element selected by user \r
+ * get iformations of element selected by user\r
*/\r
function GetXimfValuesOfRichlistItem(richItem){\r
var oItem = new Object;\r
oItem.ximftecvalue = "";\r
oItem.separator = "";\r
oItem.tecseparator = "";\r
- \r
- try{ \r
- switch(richItem.localName){\r
+ oItem.bfactorise = false;\r
+ oItem.bpositionend = false;\r
+ try{\r
+ switch (richItem.localName) {\r
case "checkbox" :\r
- if(richItem.hasAttribute("checked")){ \r
+ if (richItem.hasAttribute("checked")) {\r
oItem.value = richItem.getAttribute("label");\r
oItem.ximfvalue = richItem.getAttribute("ximfvalue");\r
- if(richItem.hasAttribute("ximftecvalue")) oItem.ximftecvalue = richItem.getAttribute("ximftecvalue");\r
- if(richItem.hasAttribute("ximfseparator")) oItem.separator = richItem.getAttribute("ximfseparator");\r
- if(richItem.hasAttribute("ximftecseparator")) oItem.tecseparator = richItem.getAttribute("ximftecseparator");\r
- if(richItem.hasAttribute("id")) oItem.id = richItem.getAttribute("id");\r
- if(richItem.hasAttribute("ximfconcatid")) oItem.concatid = richItem.getAttribute("ximfconcatid"); \r
- } \r
+ if (richItem.hasAttribute("ximftecvalue")) {\r
+ oItem.ximftecvalue = richItem.getAttribute("ximftecvalue");\r
+ }\r
+ if (richItem.hasAttribute("ximfseparator")) {\r
+ oItem.separator = richItem.getAttribute("ximfseparator");\r
+ }\r
+ if (richItem.hasAttribute("ximftecseparator")) {\r
+ oItem.tecseparator = richItem.getAttribute("ximftecseparator");}\r
+ if (richItem.hasAttribute("id")) {\r
+ oItem.id = richItem.getAttribute("id");\r
+ }\r
+ if (richItem.hasAttribute("ximfconcatid")) {\r
+ oItem.concatid = richItem.getAttribute("ximfconcatid");\r
+ }\r
+ if (richItem.hasAttribute("ximfcompositionend")) {\r
+ oItem.bpositionend = richItem.getAttribute("ximfcompositionend") === "true" ? true : false;\r
+ }\r
+ if (richItem.hasAttribute("ximffactorise")) {\r
+ oItem.bfactorise = richItem.getAttribute("ximffactorise") === "true" ? true : false;\r
+ }\r
+ }\r
break;\r
case "textbox" :\r
- if(richItem.value != ""){ \r
+ if (richItem.value !== "") {\r
oItem.value = richItem.value;\r
- oItem.ximfvalue = richItem.value; \r
- if(richItem.hasAttribute("ximfseparator")) oItem.separator = richItem.getAttribute("ximfseparator"); \r
- if(richItem.hasAttribute("id")) oItem.id = richItem.getAttribute("id");\r
- if(richItem.hasAttribute("ximfconcatid")) oItem.concatid = richItem.getAttribute("ximfconcatid");\r
- } \r
+ oItem.ximfvalue = richItem.value;\r
+ if (richItem.hasAttribute("ximfseparator")) {\r
+ oItem.separator = richItem.getAttribute("ximfseparator");\r
+ }\r
+ if (richItem.hasAttribute("id")) {\r
+ oItem.id = richItem.getAttribute("id");\r
+ }\r
+ if (richItem.hasAttribute("ximfconcatid")) {\r
+ oItem.concatid = richItem.getAttribute("ximfconcatid");\r
+ }\r
+ }\r
break;\r
}\r
- \r
- if(oItem.value == "") oItem = null;\r
- \r
+ if (oItem.value === "") {\r
+ oItem = null;\r
+ }\r
}catch(e){\r
- gConsole.logStringMessage("[ximfmail - GetXimfSelectionOfRichlistitem ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber); \r
+ gConsole.logStringMessage("[ximfmail - GetXimfSelectionOfRichlistitem ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
}\r
- return oItem; \r
+ return oItem;\r
}\r
-\r
/*\r
* Update Ximf header selected from single choice panel\r
*/\r
-function ComputeXimfhdrsMenuItem(menuitem){\r
+function ComputeXimfhdrsMenuItem(menuitem) {\r
try{\r
var iMaxItems = 0;\r
- var sXimfseparator = _XIMF_DEFAULT_SEPARATOR;\r
- var eltTextbox = document.getElementById(menuitem.getAttribute("ximftextbox")); \r
- \r
+ var sXimfseparator = ximfConst._XIMF_DEFAULT_SEPARATOR;\r
+ var eltTextbox = document.getElementById(menuitem.getAttribute("ximftextbox"));\r
// CheckXimfhdrsSelection for list with finished elements number\r
- if(eltTextbox.hasAttribute(_XIMF_ATT_MAX_ITEMS) ){\r
- iMaxItems = parseInt(eltTextbox.getAttribute(_XIMF_ATT_MAX_ITEMS),10);\r
+ if (eltTextbox.hasAttribute(ximfConst._XIMF_ATT_MAX_ITEMS)) {\r
+ iMaxItems = parseInt(eltTextbox.getAttribute(ximfConst._XIMF_ATT_MAX_ITEMS),10);\r
}\r
- \r
- // CheckXimfhdrsSelection for separator value \r
- if(eltTextbox.hasAttribute(_XIMF_ATT_SEPARATOR) ){\r
- sXimfseparator = eltTextbox.getAttribute(_XIMF_ATT_SEPARATOR);\r
+ // CheckXimfhdrsSelection for separator value\r
+ if (eltTextbox.hasAttribute(ximfConst._XIMF_ATT_SEPARATOR)) {\r
+ sXimfseparator = eltTextbox.getAttribute(ximfConst._XIMF_ATT_SEPARATOR);\r
}\r
- \r
// CheckXimfhdrsSelection for concated values\r
var sConcatVal="";\r
var sConcatXimfVal="";\r
var sConcatTecVal="";\r
- var sContentSeparator = _XIMF_DEFAULT_SEPARATOR; \r
- var sContenTecSeparator = _XIMF_DEFAULT_SEPARATOR;\r
- if(menuitem.hasAttribute(_XIMF_ATT_CONCAT_ID)){ \r
- //\r
- if(menuitem.hasAttribute(_XIMF_ATT_SEPARATOR)){\r
- sContentSeparator = menuitem.getAttribute(_XIMF_ATT_SEPARATOR);\r
- }else{\r
- if(menuitem.parentNode.hasAttribute(_XIMF_ATT_SEPARATOR)){\r
- sContentSeparator = menuitem.parentNode.getAttribute(_XIMF_ATT_SEPARATOR); \r
+ var sContentSeparator = ximfConst._XIMF_DEFAULT_SEPARATOR;\r
+ var sContenTecSeparator = ximfConst._XIMF_DEFAULT_SEPARATOR;\r
+ if (menuitem.hasAttribute(ximfConst._XIMF_ATT_CONCAT_ID)) {\r
+ if (menuitem.hasAttribute(ximfConst._XIMF_ATT_SEPARATOR)) {\r
+ sContentSeparator = menuitem.getAttribute(ximfConst._XIMF_ATT_SEPARATOR);\r
+ } else {\r
+ if (menuitem.parentNode.hasAttribute(ximfConst._XIMF_ATT_SEPARATOR)) {\r
+ sContentSeparator = menuitem.parentNode.getAttribute(ximfConst._XIMF_ATT_SEPARATOR);\r
}\r
- } \r
- //\r
- if(menuitem.hasAttribute(_XIMF_ATT_TEC_SEPARATOR)){\r
- sContenTecSeparator = menuitem.getAttribute(_XIMF_ATT_TEC_SEPARATOR);\r
- }else{\r
- if(menuitem.parentNode.hasAttribute(_XIMF_ATT_TEC_SEPARATOR)){\r
- sContenTecSeparator = menuitem.parentNode.getAttribute(_XIMF_ATT_TEC_SEPARATOR); \r
+ }\r
+ if (menuitem.hasAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR)) {\r
+ sContenTecSeparator = menuitem.getAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR);\r
+ } else {\r
+ if (menuitem.parentNode.hasAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR)) {\r
+ sContenTecSeparator = menuitem.parentNode.getAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR);\r
}\r
}\r
- \r
- var sIds = menuitem.getAttribute(_XIMF_ATT_CONCAT_ID);\r
+ var sIds = menuitem.getAttribute(ximfConst._XIMF_ATT_CONCAT_ID);\r
var reg=new RegExp("[+]+", "g");\r
var arrayIds = sIds.split(reg);\r
for (var i=0; i<arrayIds.length; i++) {\r
- try{ \r
+ try{\r
var cElt = document.getElementById(arrayIds[i]);\r
- if(cElt){\r
- if(sConcatVal == ""){ \r
+ if (cElt) {\r
+ if (sConcatVal === "") {\r
sConcatVal = cElt.getAttribute("label");\r
- sConcatXimfVal = cElt.getAttribute(_XIMF_ATT_XVALUE);\r
- sConcatTecVal = cElt.getAttribute(_XIMF_ATT_TEC_VALUE);\r
- }else{\r
+ sConcatXimfVal = cElt.getAttribute(ximfConst._XIMF_ATT_XVALUE);\r
+ sConcatTecVal = cElt.getAttribute(ximfConst._XIMF_ATT_TEC_VALUE);\r
+ } else {\r
sConcatVal = sConcatVal + sContentSeparator + cElt.getAttribute("label");\r
- sConcatXimfVal = sConcatXimfVal + sContentSeparator + cElt.getAttribute(_XIMF_ATT_XVALUE);\r
- sConcatTecVal = sConcatTecVal + sContenTecSeparator + cElt.getAttribute(_XIMF_ATT_TEC_VALUE);\r
+ sConcatXimfVal = sConcatXimfVal + sContentSeparator + cElt.getAttribute(ximfConst._XIMF_ATT_XVALUE);\r
+ sConcatTecVal = sConcatTecVal + sContenTecSeparator + cElt.getAttribute(ximfConst._XIMF_ATT_TEC_VALUE);\r
}\r
}\r
}catch(e){}\r
}\r
}\r
- \r
- // replace existing value if exits \r
- var sOldximfvalue = eltTextbox.getAttribute(_XIMF_ATT_XVALUE);\r
- eltTextbox.value = sConcatVal + menuitem.getAttribute("label"); \r
- eltTextbox.setAttribute(_XIMF_ATT_XVALUE, sConcatXimfVal + menuitem.getAttribute(_XIMF_ATT_XVALUE));\r
- \r
+ // replace existing value if exits\r
+ var sOldximfvalue = eltTextbox.getAttribute(ximfConst._XIMF_ATT_XVALUE);\r
+ eltTextbox.value = sConcatVal + menuitem.getAttribute("label");\r
+ eltTextbox.setAttribute(ximfConst._XIMF_ATT_XVALUE, sConcatXimfVal + menuitem.getAttribute(ximfConst._XIMF_ATT_XVALUE));\r
// watch for technical value\r
- if(menuitem.hasAttribute(_XIMF_ATT_TEC_VALUE)){ \r
- eltTextbox.setAttribute(_XIMF_ATT_TEC_VALUE, sConcatTecVal + menuitem.getAttribute(_XIMF_ATT_TEC_VALUE));\r
+ if (menuitem.hasAttribute(ximfConst._XIMF_ATT_TEC_VALUE)) {\r
+ eltTextbox.setAttribute(ximfConst._XIMF_ATT_TEC_VALUE, sConcatTecVal + menuitem.getAttribute(ximfConst._XIMF_ATT_TEC_VALUE));\r
}\r
- \r
//erase old linkPopup case and new selection\r
- if(sOldximfvalue!=""){\r
- if(sOldximfvalue != menuitem.getAttribute(_XIMF_ATT_XVALUE)){ \r
- var sOldlinkpopup = $("panel[id='"+ eltTextbox.getAttribute("refpanel")+"'] menuitem[ximfvalue='"+sOldximfvalue+"']").attr(_XIMF_ATT_LINK_POPUP_BOX);\r
- EraseAndComputeXimfhdrsTextbox($("panel[id='"+ sOldlinkpopup +"']").attr(_XIMF_ATT_REF_BOX));\r
- // delete popup link in textbox\r
- $("textbox[id='" + $("panel[id='"+ sOldlinkpopup +"']").attr(_XIMF_ATT_REF_BOX) + "']").removeAttr("refpanel");\r
- $("textbox[id='" + $("panel[id='"+ sOldlinkpopup +"']")+ " button").removeAttr("refpanel");\r
- } \r
- } \r
- \r
+ if (sOldximfvalue !== "" && sOldximfvalue !== menuitem.getAttribute(ximfConst._XIMF_ATT_XVALUE)) {\r
+ var sOldlinkpopup = $("panel[id='"+ eltTextbox.getAttribute("refpanel")+"'] menuitem[ximfvalue='"+sOldximfvalue+"']").attr(ximfConst._XIMF_ATT_LINK_POPUP_BOX);\r
+ EraseAndComputeXimfhdrsTextbox($("panel[id='"+ sOldlinkpopup +"']").attr(ximfConst._XIMF_ATT_REF_BOX));\r
+ // delete popup link in textbox\r
+ $("textbox[id='" + $("panel[id='"+ sOldlinkpopup +"']").attr(ximfConst._XIMF_ATT_REF_BOX) + "']").removeAttr("refpanel");\r
+ $("textbox[id='" + $("panel[id='"+ sOldlinkpopup +"']")+ " button").removeAttr("refpanel");\r
+ }\r
// manage popup of link header\r
- if(menuitem.hasAttribute(_XIMF_ATT_LINK_POPUP_BOX)){ \r
- var popupset = document.getElementById(menuitem.getAttribute(_XIMF_ATT_LINK_POPUP_BOX));\r
- var txtbox = document.getElementById(popupset.getAttribute(_XIMF_ATT_REF_BOX));\r
- txtbox.setAttribute("refpanel",menuitem.getAttribute(_XIMF_ATT_LINK_POPUP_BOX));\r
- $("textbox[id='" + txtbox.getAttribute("id") + "'] button").attr("refpanel",menuitem.getAttribute(_XIMF_ATT_LINK_POPUP_BOX)); \r
- } \r
- \r
+ if (menuitem.hasAttribute(ximfConst._XIMF_ATT_LINK_POPUP_BOX)) {\r
+ var popupset = document.getElementById(menuitem.getAttribute(ximfConst._XIMF_ATT_LINK_POPUP_BOX));\r
+ var txtbox = document.getElementById(popupset.getAttribute(ximfConst._XIMF_ATT_REF_BOX));\r
+ txtbox.setAttribute("refpanel",menuitem.getAttribute(ximfConst._XIMF_ATT_LINK_POPUP_BOX));\r
+ $("textbox[id='" + txtbox.getAttribute("id") + "'] button").attr("refpanel",menuitem.getAttribute(ximfConst._XIMF_ATT_LINK_POPUP_BOX));\r
+ }\r
// valid document state\r
- CheckXimfhdrsSelection(); \r
+ CheckXimfhdrsSelection();\r
}catch(e){\r
- gConsole.logStringMessage("[ximfmail - OnSelectXimfItem ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber); \r
- } \r
+ gConsole.logStringMessage("[ximfmail - OnSelectXimfItem ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
}\r
-\r
/*\r
* Update Ximf header selected in menu popup with button\r
*/\r
function ComputeXimfhdrsButtonPopup(button){\r
- // Add selection and associated values for header from button popup \r
+ // Add selection and associated values for header from button popup\r
try{\r
var sXimfValues="";\r
- var sValues=""; \r
+ var sValues="";\r
var sXimfTechnicalValues="";\r
var ximfvalue = "";\r
var value = "";\r
var ximftechnicalvalue="";\r
- var sContentSeparator = _XIMF_DEFAULT_SEPARATOR; \r
- var sContenTecSeparator = _XIMF_DEFAULT_SEPARATOR; \r
+ var sContentSeparator = ximfConst._XIMF_DEFAULT_SEPARATOR;\r
+ var sContenTecSeparator = ximfConst._XIMF_DEFAULT_SEPARATOR;\r
var eltTextbox = document.getElementById(button.getAttribute("ximfreftextbox"));\r
- \r
- sXimfValues = eltTextbox.getAttribute(_XIMF_ATT_XVALUE);\r
+ sXimfValues = eltTextbox.getAttribute(ximfConst._XIMF_ATT_XVALUE);\r
sValues = eltTextbox.value;\r
- sXimfTechnicalValues = eltTextbox.getAttribute(_XIMF_ATT_TEC_VALUE);\r
- \r
- // CheckXimfhdrsSelection for concated values \r
- if(button.hasAttribute(_XIMF_ATT_CONCAT_ID)){ \r
- var sIds = button.getAttribute(_XIMF_ATT_CONCAT_ID);\r
+ sXimfTechnicalValues = eltTextbox.getAttribute(ximfConst._XIMF_ATT_TEC_VALUE);\r
+ // CheckXimfhdrsSelection for concated values\r
+ if (button.hasAttribute(ximfConst._XIMF_ATT_CONCAT_ID)) {\r
+ var sIds = button.getAttribute(ximfConst._XIMF_ATT_CONCAT_ID);\r
var reg=new RegExp("[+]+", "g");\r
var arrayIds = sIds.split(reg);\r
- for (var i=0; i<arrayIds.length; i++){ \r
- var cElt = document.getElementById(arrayIds[i]); \r
- if(cElt){\r
- //\r
- if(cElt.hasAttribute(_XIMF_ATT_SEPARATOR))\r
- sContentSeparator = cElt.getAttribute(_XIMF_ATT_SEPARATOR);\r
- if(cElt.hasAttribute(_XIMF_ATT_TEC_SEPARATOR))\r
- sContenTecSeparator = cElt.getAttribute(_XIMF_ATT_TEC_SEPARATOR);\r
-\r
- //\r
- if(value == ""){ \r
+ for (var i=0; i<arrayIds.length; i++){\r
+ var cElt = document.getElementById(arrayIds[i]);\r
+ if (cElt) {\r
+ if (cElt.hasAttribute(ximfConst._XIMF_ATT_SEPARATOR)) {\r
+ sContentSeparator = cElt.getAttribute(ximfConst._XIMF_ATT_SEPARATOR);\r
+ }\r
+ if (cElt.hasAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR)) {\r
+ sContenTecSeparator = cElt.getAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR);\r
+ }\r
+ if (value === "") {\r
value = cElt.getAttribute("label") + sContentSeparator;\r
- ximfvalue = cElt.getAttribute(_XIMF_ATT_XVALUE) + sContentSeparator;\r
- ximftechnicalvalue = cElt.getAttribute(_XIMF_ATT_TEC_VALUE) + sContenTecSeparator;\r
- }else{\r
+ ximfvalue = cElt.getAttribute(ximfConst._XIMF_ATT_XVALUE) + sContentSeparator;\r
+ ximftechnicalvalue = cElt.getAttribute(ximfConst._XIMF_ATT_TEC_VALUE) + sContenTecSeparator;\r
+ } else {\r
value = value + cElt.getAttribute("label") + sContentSeparator ;\r
- ximfvalue = ximfvalue + cElt.getAttribute(_XIMF_ATT_XVALUE) + sContentSeparator ;\r
- ximftechnicalvalue = ximftechnicalvalue + cElt.getAttribute(_XIMF_ATT_TEC_VALUE) + sContenTecSeparator ;\r
+ ximfvalue = ximfvalue + cElt.getAttribute(ximfConst._XIMF_ATT_XVALUE) + sContentSeparator ;\r
+ ximftechnicalvalue = ximftechnicalvalue + cElt.getAttribute(ximfConst._XIMF_ATT_TEC_VALUE) + sContenTecSeparator ;\r
}\r
}\r
}\r
}\r
- \r
// get default parameters\r
- if(button.hasAttribute(_XIMF_ATT_SEPARATOR))\r
- sContentSeparator = button.getAttribute(_XIMF_ATT_SEPARATOR);\r
- \r
- if(button.hasAttribute(_XIMF_ATT_TEC_SEPARATOR))\r
- sContenTecSeparator = button.getAttribute(_XIMF_ATT_TEC_SEPARATOR); \r
- \r
- if(sValues != ""){\r
- sValues = sValues + sContentSeparator + value + button.getAttribute("label"); \r
- sXimfValues = sXimfValues + sContentSeparator + ximfvalue + button.getAttribute(_XIMF_ATT_XVALUE);\r
- sXimfTechnicalValues = sXimfTechnicalValues + sContenTecSeparator + ximftechnicalvalue + button.getAttribute(_XIMF_ATT_TEC_VALUE);\r
- }else{\r
+ if (button.hasAttribute(ximfConst._XIMF_ATT_SEPARATOR)) {\r
+ sContentSeparator = button.getAttribute(ximfConst._XIMF_ATT_SEPARATOR);\r
+ }\r
+ if (button.hasAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR)) {\r
+ sContenTecSeparator = button.getAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR);\r
+ }\r
+ if (sValues !== "") {\r
+ sValues = sValues + sContentSeparator + value + button.getAttribute("label");\r
+ sXimfValues = sXimfValues + sContentSeparator + ximfvalue + button.getAttribute(ximfConst._XIMF_ATT_XVALUE);\r
+ sXimfTechnicalValues = sXimfTechnicalValues + sContenTecSeparator + ximftechnicalvalue + button.getAttribute(ximfConst._XIMF_ATT_TEC_VALUE);\r
+ } else {\r
sValues = value + button.getAttribute("label");\r
- sXimfValues = ximfvalue + button.getAttribute(_XIMF_ATT_XVALUE);\r
- sXimfTechnicalValues = ximftechnicalvalue + button.getAttribute(_XIMF_ATT_TEC_VALUE);\r
- } \r
- \r
+ sXimfValues = ximfvalue + button.getAttribute(ximfConst._XIMF_ATT_XVALUE);\r
+ sXimfTechnicalValues = ximftechnicalvalue + button.getAttribute(ximfConst._XIMF_ATT_TEC_VALUE);\r
+ }\r
// load new values\r
- eltTextbox.setAttribute(_XIMF_ATT_XVALUE,sXimfValues);\r
+ eltTextbox.setAttribute(ximfConst._XIMF_ATT_XVALUE,sXimfValues);\r
eltTextbox.value=sValues;\r
- \r
CheckXimfhdrsSelection();\r
}catch(e){\r
- gConsole.logStringMessage("[ximfmail - OnSelectXimfButton ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber); \r
+ gConsole.logStringMessage("[ximfmail - OnSelectXimfButton ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
}\r
}\r
-\r
/*\r
* Update Ximf header selected in menu popup with CheckXimfhdrsSelection\r
*/\r
-function ComputeXimfhdrsCheckPopup(xulElement){\r
+function ComputeXimfhdrsCheckPopup(xulElement) {\r
//CheckXimfhdrsSelection all selected values and add to ximf box\r
- try{\r
+ try {\r
var sXimfValues="";\r
var sValues="";\r
var sXimfTechnicalValues="";\r
- var sContentSeparator = _XIMF_DEFAULT_SEPARATOR; \r
- var sContenTecSeparator = _XIMF_DEFAULT_SEPARATOR;\r
+ var sContentSeparator = ximfConst._XIMF_DEFAULT_SEPARATOR;\r
+ var sContenTecSeparator = ximfConst._XIMF_DEFAULT_SEPARATOR;\r
+ var sConcatSeparator = ximfConst._XIMF_DEFAULT_SEPARATOR;\r
+ var sConcatTecSeparator = ximfConst._XIMF_DEFAULT_SEPARATOR;\r
var nextElt = null;\r
var idTextBox = "";\r
var parentElt = null;\r
- //\r
- nextElt = xulElement.parentNode; \r
+ nextElt = xulElement.parentNode;\r
var arrayCheckedbox = null;\r
- while(nextElt){\r
- if(nextElt.localName == "popup"){ \r
- arrayCheckedbox = $("popup[id='"+nextElt.id+"'] checkbox[class='ximfCheckbox'][checked]" ); \r
- //alert("checklist OK !!" + nextElt.id + arrayCheckbox.length);\r
+ while (nextElt) {\r
+ if (nextElt.localName === "popup") {\r
+ arrayCheckedbox = $("popup[id='"+nextElt.id+"'] checkbox[class='ximfCheckbox'][checked]" );\r
// id of parent node\r
- idTextBox = nextElt.getAttribute('ximfreftextbox'); \r
+ idTextBox = nextElt.getAttribute('ximfreftextbox');\r
parentElt = nextElt;\r
// get default parameters\r
- if(parentElt.hasAttribute(_XIMF_ATT_SEPARATOR))\r
- sContentSeparator = parentElt.getAttribute(_XIMF_ATT_SEPARATOR);\r
- if(parentElt.hasAttribute(_XIMF_ATT_TEC_SEPARATOR))\r
- sContenTecSeparator = parentElt.getAttribute(_XIMF_ATT_TEC_SEPARATOR); \r
+ if (parentElt.hasAttribute(ximfConst._XIMF_ATT_SEPARATOR)) {\r
+ sContentSeparator = parentElt.getAttribute(ximfConst._XIMF_ATT_SEPARATOR);\r
+ }\r
+ if (parentElt.hasAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR)) {\r
+ sContenTecSeparator = parentElt.getAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR);\r
+ }\r
break;\r
}\r
- nextElt = nextElt.parentNode;\r
+ nextElt = nextElt.parentNode;\r
}\r
- //alert("arrayCheckedbox.length = " + arrayCheckedbox.length);\r
// get value of each checkbox selected\r
- for( var idx=0 ; idx < arrayCheckedbox.length; ++idx){\r
- var ximfvalue = "";\r
- var value = "";\r
- var ximftechnicalvalue=""; \r
- \r
- var concatvalue = "";\r
- var ximfconcatvalue = "";\r
- var ximfconcattechnicalvalue = "";\r
- \r
- \r
- if(arrayCheckedbox[idx].hasAttribute("label")){\r
- value = arrayCheckedbox[idx].getAttribute("label");\r
+ var ximfvalue = "";\r
+ var value = "";\r
+ var ximftechnicalvalue="";\r
+ var concatvalue = "";\r
+ var ximfconcatvalue = "";\r
+ var ximfconcattechnicalvalue = "";\r
+ var sIds = "";\r
+ var arrayIds = undefined;\r
+ var cElt = undefined;\r
+ for ( var idxChkBx=0 ; idxChkBx < arrayCheckedbox.length; ++idxChkBx) {\r
+ ximfvalue = "";\r
+ value = "";\r
+ ximftechnicalvalue="";\r
+ concatvalue = "";\r
+ ximfconcatvalue = "";\r
+ ximfconcattechnicalvalue = "";\r
+ if (arrayCheckedbox[idxChkBx].hasAttribute("label")) {\r
+ value = arrayCheckedbox[idxChkBx].getAttribute("label");\r
+ }\r
+ if (arrayCheckedbox[idxChkBx].hasAttribute(ximfConst._XIMF_ATT_XVALUE)) {\r
+ ximfvalue = arrayCheckedbox[idxChkBx].getAttribute(ximfConst._XIMF_ATT_XVALUE);\r
}\r
- if(arrayCheckedbox[idx].hasAttribute(_XIMF_ATT_XVALUE)){\r
- ximfvalue = arrayCheckedbox[idx].getAttribute(_XIMF_ATT_XVALUE);\r
- } \r
- if(arrayCheckedbox[idx].hasAttribute(_XIMF_ATT_TEC_VALUE)){\r
- ximftechnicalvalue = arrayCheckedbox[idx].getAttribute(_XIMF_ATT_TEC_VALUE);\r
- } \r
- \r
- // search for XIMF ComplexString \r
- if(arrayCheckedbox[idx].hasAttribute(_XIMF_ATT_CONCAT_ID)){\r
- var sIds = arrayCheckedbox[idx].getAttribute(_XIMF_ATT_CONCAT_ID);\r
+ if (arrayCheckedbox[idxChkBx].hasAttribute(ximfConst._XIMF_ATT_TEC_VALUE)) {\r
+ ximftechnicalvalue = arrayCheckedbox[idxChkBx].getAttribute(ximfConst._XIMF_ATT_TEC_VALUE);\r
+ }\r
+ // search for XIMF ComplexString\r
+ if (arrayCheckedbox[idxChkBx].hasAttribute(ximfConst._XIMF_ATT_CONCAT_ID)) {\r
+ sIds = arrayCheckedbox[idxChkBx].getAttribute(ximfConst._XIMF_ATT_CONCAT_ID);\r
var reg=new RegExp("[+]+", "g");\r
- var arrayIds = sIds.split(reg);\r
- \r
- for (var k=0; k<arrayIds.length; ++k) { \r
- var cElt = document.getElementById(arrayIds[k]);\r
- if(cElt){\r
- var sConcatSeparator = _XIMF_DEFAULT_SEPARATOR;\r
- var sConcatTecSeparator = _XIMF_DEFAULT_SEPARATOR;\r
- if(cElt.hasAttribute(_XIMF_ATT_SEPARATOR))\r
- sConcatSeparator = cElt.getAttribute(_XIMF_ATT_SEPARATOR);\r
- if(cElt.hasAttribute(_XIMF_ATT_TEC_SEPARATOR))\r
- sConcatTecSeparator = cElt.getAttribute(_XIMF_ATT_TEC_SEPARATOR);\r
- if(cElt.getAttribute(_XIMF_ATT_XVALUE)){ \r
- if(concatvalue == ""){ \r
+ arrayIds = sIds.split(reg);\r
+ for (var idxIds=0; idxIds < arrayIds.length; ++idxIds) {\r
+ cElt = document.getElementById(arrayIds[idxIds]);\r
+ if (cElt) {\r
+ if (cElt.hasAttribute(ximfConst._XIMF_ATT_SEPARATOR)) {\r
+ sConcatSeparator = cElt.getAttribute(ximfConst._XIMF_ATT_SEPARATOR);\r
+ }\r
+ if (cElt.hasAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR)) {\r
+ sConcatTecSeparator = cElt.getAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR);\r
+ }\r
+ if (cElt.getAttribute(ximfConst._XIMF_ATT_XVALUE)) {\r
+ if (concatvalue === "") {\r
concatvalue = cElt.getAttribute("label") + sConcatSeparator;\r
- ximfconcatvalue = cElt.getAttribute(_XIMF_ATT_XVALUE) + sConcatSeparator ;\r
- if(cElt.hasAttribute(_XIMF_ATT_TEC_VALUE)){\r
- ximfconcattechnicalvalue = cElt.getAttribute(_XIMF_ATT_TEC_VALUE) + sConcatTecSeparator;\r
+ ximfconcatvalue = cElt.getAttribute(ximfConst._XIMF_ATT_XVALUE) + sConcatSeparator ;\r
+ if (cElt.hasAttribute(ximfConst._XIMF_ATT_TEC_VALUE)) {\r
+ ximfconcattechnicalvalue = cElt.getAttribute(ximfConst._XIMF_ATT_TEC_VALUE) + sConcatTecSeparator;\r
}\r
- }else{\r
+ } else {\r
concatvalue = concatvalue + cElt.getAttribute("label") + sConcatSeparator;\r
- ximfconcatvalue = ximfconcatvalue + cElt.getAttribute(_XIMF_ATT_XVALUE) + sConcatSeparator;\r
- if(cElt.hasAttribute(_XIMF_ATT_TEC_VALUE)){\r
- ximfconcattechnicalvalue = ximfconcattechnicalvalue + cElt.getAttribute(_XIMF_ATT_TEC_VALUE) + sConcatTecSeparator;\r
+ ximfconcatvalue = ximfconcatvalue + cElt.getAttribute(ximfConst._XIMF_ATT_XVALUE) + sConcatSeparator;\r
+ if (cElt.hasAttribute(ximfConst._XIMF_ATT_TEC_VALUE)) {\r
+ ximfconcattechnicalvalue = ximfconcattechnicalvalue + cElt.getAttribute(ximfConst._XIMF_ATT_TEC_VALUE) + sConcatTecSeparator;\r
}\r
}\r
}\r
}\r
}\r
}\r
- \r
- // \r
- if(sValues != ""){\r
- sValues = sValues + sContentSeparator + concatvalue + value; \r
+ if (sValues !== "") {\r
+ sValues = sValues + sContentSeparator + concatvalue + value;\r
sXimfValues = sXimfValues + sContentSeparator + ximfconcatvalue + ximfvalue ;\r
- if(ximfconcattechnicalvalue != "" || ximftechnicalvalue != ""){\r
+ if (ximfconcattechnicalvalue !== "" || ximftechnicalvalue !== "") {\r
sXimfTechnicalValues = sXimfTechnicalValues + sContenTecSeparator + ximfconcattechnicalvalue + ximftechnicalvalue ;\r
}\r
- }else{\r
- sValues = concatvalue + value; \r
+ } else {\r
+ sValues = concatvalue + value;\r
sXimfValues = ximfconcatvalue + ximfvalue;\r
- if(ximfconcattechnicalvalue != "" || ximftechnicalvalue != ""){ \r
+ if(ximfconcattechnicalvalue !== "" || ximftechnicalvalue !== ""){\r
sXimfTechnicalValues = ximfconcattechnicalvalue + ximftechnicalvalue;\r
}\r
}\r
}\r
- \r
//CheckXimfhdrsSelection for input values\r
- var arrayTextbox = $("popup[id='"+parentElt.id+"'] textbox[class='ximfInputbox']" ); \r
- //alert("arrayTextbox.length = " + arrayTextbox.length);\r
- for( var idx=0 ; idx < arrayTextbox.length; ++idx){\r
- var ximfvalue = "";\r
- var value = ""; \r
- var concatvalue = "";\r
- var ximfconcatvalue = ""; \r
- \r
- // search for XIMF ComplexString \r
- if(arrayTextbox[idx].hasAttribute(_XIMF_ATT_CONCAT_ID)){\r
- var sIds = arrayTextbox[idx].getAttribute(_XIMF_ATT_CONCAT_ID);\r
- var reg=new RegExp("[+]+", "g");\r
- var arrayIds = sIds.split(reg);\r
- \r
- for (var k=0; k<arrayIds.length; ++k) { \r
- var cElt = document.getElementById(arrayIds[k]);\r
- if(cElt){\r
- var sConcatSeparator = _XIMF_DEFAULT_SEPARATOR;\r
- var sConcatTecSeparator = _XIMF_DEFAULT_SEPARATOR;\r
- if(cElt.hasAttribute(_XIMF_ATT_SEPARATOR))\r
- sConcatSeparator = cElt.getAttribute(_XIMF_ATT_SEPARATOR);\r
- if(cElt.hasAttribute(_XIMF_ATT_TEC_SEPARATOR))\r
- sConcatTecSeparator = cElt.getAttribute(_XIMF_ATT_TEC_SEPARATOR);\r
- \r
- if(cElt.getAttribute("label")){ \r
- if(concatvalue == ""){ \r
+ arrayTextbox = $("popup[id='"+parentElt.id+"'] textbox[class='ximfInputbox']" );\r
+ for ( var idxTxtBx=0 ; idxTxtBx < arrayTextbox.length; ++idxTxtBx) {\r
+ concatvalue = "";\r
+ ximfconcatvalue = "";\r
+ // search for XIMF ComplexString\r
+ if (arrayTextbox[idxTxtBx].hasAttribute(ximfConst._XIMF_ATT_CONCAT_ID)) {\r
+ sIds = arrayTextbox[idxTxtBx].getAttribute(ximfConst._XIMF_ATT_CONCAT_ID);\r
+ var regId=new RegExp("[+]+", "g");\r
+ arrayIds = sIds.split(regId);\r
+ for (var k=0; k<arrayIds.length; ++k) {\r
+ cElt = document.getElementById(arrayIds[k]);\r
+ if (cElt) {\r
+ if (cElt.hasAttribute(ximfConst._XIMF_ATT_SEPARATOR)) {\r
+ sConcatSeparator = cElt.getAttribute(ximfConst._XIMF_ATT_SEPARATOR);\r
+ }\r
+ if (cElt.hasAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR)) {\r
+ sConcatTecSeparator = cElt.getAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR);\r
+ }\r
+ if (cElt.getAttribute("label")) {\r
+ if (concatvalue === "") {\r
concatvalue = cElt.getAttribute("label") + sConcatSeparator;\r
- ximfconcatvalue = cElt.getAttribute(_XIMF_ATT_XVALUE) + sConcatSeparator ;\r
- ximfconcattechnicalvalue = cElt.getAttribute(_XIMF_ATT_TEC_VALUE);\r
- }else{\r
+ ximfconcatvalue = cElt.getAttribute(ximfConst._XIMF_ATT_XVALUE) + sConcatSeparator ;\r
+ ximfconcattechnicalvalue = cElt.getAttribute(ximfConst._XIMF_ATT_TEC_VALUE);\r
+ } else {\r
concatvalue = concatvalue + cElt.getAttribute("label") + sConcatSeparator;\r
- ximfconcatvalue = ximfconcatvalue + cElt.getAttribute(_XIMF_ATT_XVALUE) + sConcatSeparator;\r
- ximfconcattechnicalvalue = ximfconcattechnicalvalue + sConcatTecSeparator + cElt.getAttribute(_XIMF_ATT_TEC_VALUE) ;\r
+ ximfconcatvalue = ximfconcatvalue + cElt.getAttribute(ximfConst._XIMF_ATT_XVALUE) + sConcatSeparator;\r
+ ximfconcattechnicalvalue = ximfconcattechnicalvalue + sConcatTecSeparator + cElt.getAttribute(ximfConst._XIMF_ATT_TEC_VALUE) ;\r
}\r
}\r
}\r
}\r
}\r
- \r
- // save edit entry \r
- var sInValues = arrayTextbox[idx].value;\r
+ // save edit entry\r
+ var sInValues = arrayTextbox[idxTxtBx].value;\r
var reg=new RegExp("[\n]+", "g");\r
var arrayValues = sInValues.split(reg);\r
- var valuelist = ""; \r
+ var valuelist = "";\r
var valueXimflist = "";\r
- for (var i=0; i<arrayValues.length; ++i) { \r
- if(arrayValues[i] != ""){\r
- if(valuelist == ""){ \r
+ for (var i=0; i<arrayValues.length; ++i) {\r
+ if (arrayValues[i] !== "") {\r
+ if (valuelist === "") {\r
valuelist = concatvalue + arrayValues[i];\r
- valueXimflist = ximfconcatvalue + arrayValues[i]; \r
- }else{\r
+ valueXimflist = ximfconcatvalue + arrayValues[i];\r
+ } else {\r
valuelist = valuelist + sContentSeparator + concatvalue + arrayValues[i];\r
valueXimflist = valueXimflist + sContentSeparator + ximfconcatvalue + arrayValues[i];\r
}\r
- } \r
- } \r
- \r
- // add new edit entry \r
- if(valuelist!=""){\r
- if(sValues != ""){\r
- sValues = sValues + sContentSeparator + valuelist; \r
- sXimfValues = sXimfValues + sContentSeparator + valueXimflist ; \r
- }else{\r
- sValues = valuelist; \r
+ }\r
+ }\r
+ // add new edit entry\r
+ if (valuelist !== "") {\r
+ if (sValues !== "") {\r
+ sValues = sValues + sContentSeparator + valuelist;\r
+ sXimfValues = sXimfValues + sContentSeparator + valueXimflist ;\r
+ } else {\r
+ sValues = valuelist;\r
sXimfValues = valueXimflist;\r
}\r
// technical values\r
- if(ximfconcattechnicalvalue!=""){\r
- if(sXimfTechnicalValues!=""){\r
+ if (ximfconcattechnicalvalue !== "") {\r
+ if (sXimfTechnicalValues !== "") {\r
sXimfTechnicalValues = sXimfTechnicalValues + sContenTecSeparator + ximfconcattechnicalvalue ;\r
- }else{\r
+ } else {\r
sXimfTechnicalValues = ximfconcattechnicalvalue;\r
}\r
}\r
}\r
- } \r
- \r
+ }\r
// set values to textbox\r
var txt = document.getElementById(idTextBox);\r
txt.value = sValues;\r
txt.setAttribute("ximfvalue",sXimfValues);\r
- txt.setAttribute(_XIMF_ATT_TEC_VALUE,sXimfTechnicalValues); \r
- txt.setAttribute(_XIMF_ATT_SEPARATOR,sContentSeparator);\r
- txt.setAttribute(_XIMF_ATT_TEC_SEPARATOR,sContenTecSeparator);\r
+ txt.setAttribute(ximfConst._XIMF_ATT_TEC_VALUE,sXimfTechnicalValues);\r
+ txt.setAttribute(ximfConst._XIMF_ATT_SEPARATOR,sContentSeparator);\r
+ txt.setAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR,sContenTecSeparator);\r
CheckXimfhdrsSelection();\r
- }catch(e){\r
- }\r
-};\r
-\r
-\r
+ } catch (e) {\r
+ }\r
+}\r
/*\r
* Check elements of panel and update accessibility of elements\r
*/\r
function ComputePanelOfCheckboxSelection(idCheckbox){\r
- try{\r
- // get informations of panel \r
+ try {\r
+ // get informations of panel\r
var pnl = document.getElementById(idCheckbox);\r
- while(pnl.localName != "panel"){\r
+ while (pnl.localName !== "panel") {\r
pnl = pnl.parentNode;\r
- } \r
- \r
+ }\r
// check for selected item number\r
- var nbItems = $(pnl).attr("ximfmaxitem"); \r
- var richitems = $("#" + pnl.id + " richlistbox" ).children("richlistitem"); \r
- var nbchkedboxes = 0; \r
- for(var i=0 ; i<richitems.length; ++i){\r
- var chk1 = richitems[i].firstElementChild; \r
- if(chk1.localName == "checkbox"){ \r
+ var nbItems = $(pnl).attr("ximfmaxitem");\r
+ var richitems = $("#" + pnl.id + " richlistbox" ).children("richlistitem");\r
+ var nbchkedboxes = 0;\r
+ var chk1 = undefined;\r
+ var eltsChild = undefined;\r
+ for (idxRchItm=0; idxRchItm<richitems.length; ++idxRchItm) {\r
+ chk1 = richitems[idxRchItm].firstElementChild;\r
+ if (chk1.localName === "checkbox") {\r
if(chk1.checked){\r
- var eltsChild = richitems[i].getElementsByTagName("checkbox");\r
+ eltsChild = richitems[idxRchItm].getElementsByTagName("checkbox");\r
var cptChk = 0;\r
- for(j=0 ; j < eltsChild.length; ++j){\r
- if(eltsChild[j].hasAttribute("checked")) cptChk++;\r
+ for (var idxEltChild=0 ; idxEltChild < eltsChild.length; ++idxEltChild) {\r
+ if (eltsChild[idxEltChild].hasAttribute("checked")) {\r
+ cptChk++;\r
+ }\r
}\r
nbchkedboxes = nbchkedboxes + cptChk;\r
- if(cptChk > 1) nbchkedboxes = nbchkedboxes - 1;\r
- \r
+ if (cptChk > 1) {\r
+ nbchkedboxes = nbchkedboxes - 1;\r
+ }\r
// Compstring flag, if true, child value must be filled\r
- var ximfChild = false; \r
- if(richitems[i].hasAttribute("ximfchild"))\r
- if(richitems[i].getAttribute("ximfchild")=="true") \r
- $(chk1).attr("ximfchild","true"); \r
+ var ximfChild = false;\r
+ if (richitems[idxRchItm].hasAttribute("ximfchild")) {\r
+ if (richitems[idxRchItm].getAttribute("ximfchild") === "true") {\r
+ $(chk1).attr("ximfchild","true");\r
+ }\r
+ }\r
}else{\r
$(chk1).removeAttr("ximfchild");\r
}\r
}\r
}\r
- \r
var chkboxes = $("#" + pnl.id + " checkbox" );\r
// enable/disable items that can be selected\r
- if(nbchkedboxes < nbItems){\r
- // other items can be selected \r
- $(chkboxes).attr("disabled","false");//.removeAttr("disabled"); \r
- for(var i=0 ; i<richitems.length; ++i){\r
- var chk1 = richitems[i].firstElementChild;\r
- if(chk1.localName == "checkbox"){\r
- if(!chk1.checked){\r
- \r
- var eltsChild = richitems[i].getElementsByTagName("checkbox"); \r
- for(j=0 ; j < eltsChild.length; ++j){\r
- $(eltsChild[j]).removeAttr("checked");\r
- $(eltsChild[j]).attr("disabled","true"); \r
- }\r
- $(chk1).attr("disabled","false");//.removeAttr("disabled"); \r
+ if (nbchkedboxes < nbItems) {\r
+ // other items can be selected\r
+ $(chkboxes).attr("disabled","false");\r
+ for (i=0 ; i<richitems.length; ++i) {\r
+ chk1 = richitems[i].firstElementChild;\r
+ if (chk1.localName === "checkbox" && !chk1.checked) {\r
+ eltsChild = richitems[i].getElementsByTagName("checkbox");\r
+ for (j = 0 ; j < eltsChild.length; ++j) {\r
+ $(eltsChild[j]).removeAttr("checked");\r
+ $(eltsChild[j]).attr("disabled","true");\r
}\r
+ $(chk1).attr("disabled","false");\r
}\r
}\r
- }else{\r
- // max selection is selected, disable others items \r
- for(var i=0 ; i<richitems.length; ++i){\r
- var chk1 = richitems[i].firstElementChild;\r
- if(chk1.localName == "checkbox"){\r
- var eltsChild = richitems[i].getElementsByTagName("checkbox"); \r
- if(!chk1.checked){ \r
- $(chk1).removeAttr("ximfchild"); \r
- for(j=0 ; j < eltsChild.length; ++j){ \r
- $(eltsChild[j]).removeAttr("checked"); \r
- $(eltsChild[j]).attr("disabled","true"); \r
+ } else {\r
+ // max selection is selected, disable others items\r
+ for (i=0 ; i<richitems.length; ++i) {\r
+ chk1 = richitems[i].firstElementChild;\r
+ if (chk1.localName === "checkbox") {\r
+ eltsChild = richitems[i].getElementsByTagName("checkbox");\r
+ if (!chk1.checked) {\r
+ $(chk1).removeAttr("ximfchild");\r
+ for (j=0 ; j < eltsChild.length; ++j) {\r
+ $(eltsChild[j]).removeAttr("checked");\r
+ $(eltsChild[j]).attr("disabled","true");\r
}\r
- }else{\r
+ } else {\r
// disable composed items\r
- if(eltsChild.length > 1){\r
- var intCpt = 0; \r
- for(j=0 ; j < eltsChild.length; ++j){ \r
- if(eltsChild[j].hasAttribute("checked")) intCpt++;\r
+ if (eltsChild.length > 1) {\r
+ var intCpt = 0;\r
+ for (j=0; j < eltsChild.length; ++j) {\r
+ if (eltsChild[j].hasAttribute("checked")) {\r
+ intCpt++;\r
+ }\r
}\r
- switch(intCpt){\r
+ switch (intCpt) {\r
case 1:\r
- for(j=0 ; j < eltsChild.length; ++j){\r
- $(eltsChild[j]).attr("disabled","false");//.removeAttr("disabled");\r
+ for (j=0 ; j < eltsChild.length; ++j) {\r
+ $(eltsChild[j]).attr("disabled","false");\r
}\r
chk1.checked = true;\r
break;\r
case 2:\r
- for(j=0 ; j < eltsChild.length; ++j){\r
- if(!eltsChild[j].hasAttribute("checked")) \r
+ for (j=0 ; j < eltsChild.length; ++j) {\r
+ if(!eltsChild[j].hasAttribute("checked")) {\r
$(eltsChild[j]).attr("disabled","true");\r
+ }\r
}\r
break;\r
- } \r
+ default:\r
+ break;\r
+ }\r
}\r
}\r
- } \r
- } \r
+ }\r
+ }\r
}\r
- XimfailComposeCanClose(); \r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - ComputePanelOfCheckboxSelection ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
- } \r
+ XimfailComposeCanClose();\r
+ } catch (e) {\r
+ gConsole.logStringMessage("[ximfmail - ComputePanelOfCheckboxSelection ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
+ }\r
}\r
-\r
-\r
/*\r
* Check item group - more than 1 element must be selected\r
*/\r
-function IsAcceptableXimfCompstring(idCompstring){\r
- try{ \r
+function IsAcceptableXimfCompstring(idCompstring) {\r
+ try {\r
var isAcceptableCompstring = false;\r
- // \r
+ //\r
var siblingElement = document.getElementById(idCompstring).nextElementSibling;\r
- if(siblingElement){\r
- if(siblingElement.localName == "textbox"){ \r
- if(siblingElement.value !="") isAcceptableCompstring = true; \r
- }else{\r
+ if (siblingElement) {\r
+ if (siblingElement.localName === "textbox") {\r
+ if (siblingElement.value !== "") {\r
+ isAcceptableCompstring = true;\r
+ }\r
+ } else {\r
// search for textboxes\r
var childTxtboxList = siblingElement.getElementsByTagName("textbox");\r
- for(var i=0 ; i<childTxtboxList.length ; ++i){\r
- if(childTxtboxList[i].value !=""){\r
+ for (i=0 ; i<childTxtboxList.length ; ++i) {\r
+ if (childTxtboxList[i].value !== "") {\r
isAcceptableCompstring = true;\r
break;\r
}\r
}\r
- \r
- if(!isAcceptableCompstring){\r
+ if (!isAcceptableCompstring) {\r
// search for checkboxes\r
var childCheckBoxList = siblingElement.getElementsByTagName("checkbox");\r
- for(var i=0 ; i<childCheckBoxList.length ; ++i){\r
- if(childCheckBoxList[i].checked){\r
+ for (i=0 ; i<childCheckBoxList.length ; ++i) {\r
+ if(childCheckBoxList[i].checked) {\r
isAcceptableCompstring = true;\r
break;\r
}\r
}\r
}\r
}\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - IsAcceptableXimfCompstring ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
- } \r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - IsAcceptableXimfCompstring ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
+ }\r
return isAcceptableCompstring;\r
}\r
-\r
/*\r
* Delete all values of ximfmail element\r
*/\r
- function EraseAndComputeXimfhdrsTextbox(idTextBox){ \r
- try{\r
+ function EraseAndComputeXimfhdrsTextbox (idTextBox) {\r
+ try {\r
var eltTextbox = document.getElementById(idTextBox);\r
- \r
// datepicker case\r
- if(eltTextbox.localName == _XIMF_ELT_DATEPICKER){\r
+ if (eltTextbox.localName === "datepicker") {\r
eltTextbox._input.value = "";\r
eltTextbox.gPopup.value = null;\r
return;\r
}\r
- \r
eltTextbox.value = "";\r
- eltTextbox.setAttribute(_XIMF_ATT_XVALUE,""); \r
- if(eltTextbox.hasAttribute(_XIMF_ATT_TEC_VALUE)){\r
- eltTextbox.setAttribute(_XIMF_ATT_TEC_VALUE,"");\r
+ eltTextbox.setAttribute(ximfConst._XIMF_ATT_XVALUE,"");\r
+ if (eltTextbox.hasAttribute(ximfConst._XIMF_ATT_TEC_VALUE)) {\r
+ eltTextbox.setAttribute(ximfConst._XIMF_ATT_TEC_VALUE,"");\r
}\r
- \r
// raz panel selections\r
$("panel[id='"+ eltTextbox.getAttribute("refpanel")+"'] checkbox").removeAttr("checked");\r
$("panel[id='"+ eltTextbox.getAttribute("refpanel")+"'] checkbox").removeAttr("disabled");\r
var listTxtbox = $("panel[id='"+ eltTextbox.getAttribute("refpanel")+"'] textbox");\r
- for(var i=0;i<listTxtbox.length;++i)listTxtbox[i].value="";\r
- \r
- // delete repanel of linked values \r
+ for (i=0;i<listTxtbox.length;++i) {\r
+ listTxtbox[i].value="";\r
+ }\r
+ // delete repanel of linked values\r
menu_link = $("panel[id='"+ eltTextbox.getAttribute("refpanel")+"'] menuitem[linkpopupbox]");\r
- if(menu_link.length > 0){\r
- for(var i=0 ; i<menu_link.length ; ++i) { \r
- try{\r
+ if (menu_link.length > 0) {\r
+ for (i=0 ; i<menu_link.length ; ++i) {\r
+ try {\r
var popupset = document.getElementById($(menu_link[i]).attr("linkpopupbox"));\r
- var txtbox = document.getElementById(popupset.getAttribute(_XIMF_ATT_REF_BOX));\r
- EraseAndComputeXimfhdrsTextbox(popupset.getAttribute(_XIMF_ATT_REF_BOX));\r
+ var txtbox = document.getElementById(popupset.getAttribute(ximfConst._XIMF_ATT_REF_BOX));\r
+ EraseAndComputeXimfhdrsTextbox(popupset.getAttribute(ximfConst._XIMF_ATT_REF_BOX));\r
txtbox.setAttribute("refpanel","");\r
- $("textbox[id='"+popupset.getAttribute(_XIMF_ATT_REF_BOX)+"'] button").attr("refpanel","");\r
- }catch(e){}\r
+ $("textbox[id='"+popupset.getAttribute(ximfConst._XIMF_ATT_REF_BOX)+"'] button").attr("refpanel","");\r
+ } catch(e) {}\r
}\r
- } \r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - eraseXimfmailTextbox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
+ }\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - eraseXimfmailTextbox ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
}\r
}\r
-\r
/*\r
* Compute DOM with datas (used to load draft or template message)\r
*/\r
-function ComputeWithForm(ximfMessage){ \r
- if (!ximfMessage instanceof XimfmailMesssage){\r
+function ComputeWithForm(ximfMessage) {\r
+ if (!ximfMessage instanceof XimfmailMesssage) {\r
gConsole.logStringMessage("[ximfmail - ComputeWithForm ] \n parameter of refreshDatas must be a ximfMessage object");\r
- return false; \r
+ return false;\r
}\r
- \r
// compute free text type\r
// compute time type\r
- // compute menus type \r
- try{\r
- var xheader_dom = $("label[ximfheader]"); \r
- \r
- for(var idx_xheader_dom=0; idx_xheader_dom<xheader_dom.length; ++idx_xheader_dom){\r
+ // compute menus type\r
+ try {\r
+ var current_ximfvalue = "";\r
+ var valuemsg = "";\r
+ var valueref = "";\r
+ var xheader_dom = $("label[ximfheader]");\r
+ for (var idx_xheader_dom=0; idx_xheader_dom<xheader_dom.length; ++idx_xheader_dom) {\r
var display_box = null;\r
- try{\r
- //gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - search value for textbox : " + xheader_dom[idx_xheader_dom].getAttribute("ximfheader")); \r
+ try {\r
var ximfValue = ximfMessage.getHeaderValue(xheader_dom[idx_xheader_dom].getAttribute("ximfheader"));\r
- if(ximfValue){ \r
+ if (ximfValue) {\r
// search for value and complete display box\r
var display_box_list = $("textbox[refheader='" + xheader_dom[idx_xheader_dom].getAttribute("id") + "']");\r
- \r
- if(!display_box_list) continue;\r
+ if (!display_box_list) {\r
+ continue;\r
+ }\r
for(var i = 0 ; i < display_box_list.length ; ++i){\r
- if(display_box_list[i].nodeName == "textbox"){\r
+ if(display_box_list[i].nodeName === "textbox"){\r
display_box = display_box_list[i];\r
}\r
}\r
- if(!display_box) continue;\r
- \r
- // default values \r
+ if (!display_box) {\r
+ continue;\r
+ }\r
+ // default values\r
$(display_box).attr("value",ximfValue);\r
$(display_box).attr("ximfvalue",ximfValue);\r
$(display_box).attr("tooltiptext",ximfValue);\r
-\r
// menuitem value (ilk, linkpopup...)\r
var menu_item = $("panel[id='"+$(display_box).attr("refpanel")+"'] menuitem");\r
- if(menu_item.length > 0){ \r
+ if (menu_item.length > 0) {\r
for(var idx_menu_item = 0 ; idx_menu_item < menu_item.length ; ++idx_menu_item){\r
try{\r
- var current_ximfvalue = menu_item[idx_menu_item].getAttribute("ximfvalue"); \r
- var valuemsg = String_trim(ximfValue.toLowerCase());\r
- var valueref = String_trim(current_ximfvalue.toLowerCase()); \r
- if( valuemsg.indexOf(valueref, 0) != -1 ){\r
- \r
- //linkpopup manager \r
+ current_ximfvalue = menu_item[idx_menu_item].getAttribute("ximfvalue");\r
+ valuemsg = String_trim(ximfValue.toLowerCase());\r
+ valueref = String_trim(current_ximfvalue.toLowerCase());\r
+ if( valuemsg.indexOf(valueref, 0) !== -1 ){\r
+ //linkpopup manager\r
var linkpopup = menu_item[idx_menu_item].getAttribute("linkpopupbox");\r
- if(linkpopup){ \r
- var targetpopup = $("panel[id='"+linkpopup+"']");\r
- $("textbox[id='" + targetpopup[0].getAttribute("ximfreftextbox")+"']").attr("refpanel",linkpopup);\r
- $("textbox[id='" + targetpopup[0].getAttribute("ximfreftextbox")+"'] button[class*='ximfPopup']").attr("refpanel",linkpopup);\r
+ if(linkpopup){\r
+ var targetlnkpopup = $("panel[id='"+linkpopup+"']");\r
+ $("textbox[id='" + targetlnkpopup[0].getAttribute("ximfreftextbox")+"']").attr("refpanel",linkpopup);\r
+ $("textbox[id='" + targetlnkpopup[0].getAttribute("ximfreftextbox")+"'] button[class*='ximfPopup']").attr("refpanel",linkpopup);\r
}\r
- \r
- //insert values in textbox \r
+ //insert values in textbox\r
$(display_box).attr("ximfvalue",current_ximfvalue);\r
$(display_box).attr("tooltiptext",menu_item[idx_menu_item].getAttribute("label"));\r
display_box.inputField.value = menu_item[idx_menu_item].getAttribute("label");\r
//technical value is associated\r
- try{ \r
+ try{\r
var xtcval = menu_item[idx_menu_item].getAttribute("ximftecvalue");\r
- if(xtcval){ \r
+ if(xtcval){\r
display_box.setAttribute("ximftecvalue",xtcval);\r
}\r
}catch(err){}\r
}\r
}catch(err){\r
- gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas ] \n " + err + "\nfile : " + Error().fileName+"\nline : "+err.lineNumber); \r
+ gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas ] \n " + err + "\nfile : " + Error().fileName+"\nline : "+err.lineNumber);\r
}\r
}\r
}\r
- \r
- \r
- // checkbox value (ilk, linkpopup...) \r
+ // checkbox value (ilk, linkpopup...)\r
var check_item = $("panel[id='"+$(display_box).attr("refpanel")+"'] checkbox");\r
- if(check_item.length > 0){ \r
+ if(check_item.length > 0){\r
var newximfvalue = "";\r
var newtooltiptex = "";\r
var newlabel = "";\r
var newximftecvalue = "";\r
var xSeparator = $("panel[id='"+$(display_box).attr("refpanel")+"']").attr("ximfseparator");\r
- var xTecSeparator = $("panel[id='"+$(display_box).attr("refpanel")+"']").attr("ximftecseparator"); \r
- var arrayValue = []\r
- \r
- if(xSeparator){ \r
- var reg=new RegExp("["+xSeparator+"]+", "g"); \r
+ var xTecSeparator = $("panel[id='"+$(display_box).attr("refpanel")+"']").attr("ximftecseparator");\r
+ var arrayValue = [];\r
+ if(xSeparator){\r
+ var reg=new RegExp("["+xSeparator+"]+", "g");\r
arrayValue = ximfValue.split(reg);\r
}else{\r
arrayValue.push(ximfValue);\r
- } \r
- for(var idx_arrayValue=0 ; idx_arrayValue<arrayValue.length ; ++idx_arrayValue){ \r
+ }\r
+ for(var idx_arrayValue=0 ; idx_arrayValue<arrayValue.length ; ++idx_arrayValue){\r
var isarrayValueAppend = false;\r
- for(var idx_check_item = 0 ; idx_check_item < check_item.length ; ++idx_check_item){ \r
+ for(var idx_check_item = 0 ; idx_check_item < check_item.length ; ++idx_check_item){\r
try{\r
- var current_ximfvalue = check_item[idx_check_item].getAttribute("ximfvalue"); \r
- var valuemsg = arrayValue[idx_arrayValue].toLowerCase();\r
- var valueref = current_ximfvalue.toLowerCase(); \r
- if( valuemsg == valueref){\r
- isarrayValueAppend = true; \r
- // \r
- check_item[idx_check_item].setAttribute("checked",true); \r
- //linkpopup manager \r
+ current_ximfvalue = check_item[idx_check_item].getAttribute("ximfvalue");\r
+ valuemsg = arrayValue[idx_arrayValue].toLowerCase();\r
+ valueref = current_ximfvalue.toLowerCase();\r
+ if( valuemsg === valueref){\r
+ isarrayValueAppend = true;\r
+ check_item[idx_check_item].setAttribute("checked",true);\r
+ //linkpopup manager\r
var linkpopup = check_item[idx_check_item].getAttribute("linkpopupbox");\r
- if(linkpopup){ \r
+ if(linkpopup){\r
var targetpopup = $("panel[id='"+linkpopup+"']");\r
$("textbox[id='" + targetpopup[0].getAttribute("ximfreftextbox")+"']").attr("refpanel",linkpopup);\r
}\r
- \r
// save values\r
- if(xSeparator && newlabel!=""){\r
+ if(xSeparator && newlabel !== ""){\r
newlabel += xSeparator + check_item[idx_check_item].getAttribute("label");\r
}else{\r
newlabel = check_item[idx_check_item].getAttribute("label");\r
}\r
- if(xSeparator && newximfvalue!=""){\r
- newximfvalue += xSeparator + current_ximfvalue; \r
+ if(xSeparator && newximfvalue !== ""){\r
+ newximfvalue += xSeparator + current_ximfvalue;\r
}else{\r
newximfvalue = current_ximfvalue;\r
}\r
- if(xSeparator && newtooltiptex!=""){\r
- newtooltiptex += xSeparator + check_item[idx_check_item].getAttribute("label"); \r
+ if(xSeparator && newtooltiptex !== ""){\r
+ newtooltiptex += xSeparator + check_item[idx_check_item].getAttribute("label");\r
}else{\r
newtooltiptex = check_item[idx_check_item].getAttribute("label");\r
}\r
- \r
//technical value is associated\r
var xtcval = check_item[idx_check_item].getAttribute("ximftecvalue");\r
- if(xtcval){ \r
- if(xTecSeparator && newximftecvalue!=""){\r
- newximftecvalue += xTecSeparator + xtcval; \r
+ if(xtcval){\r
+ if(xTecSeparator && newximftecvalue !== ""){\r
+ newximftecvalue += xTecSeparator + xtcval;\r
}else{\r
newximftecvalue = xtcval;\r
- } \r
- } \r
+ }\r
+ }\r
}\r
}catch(err){\r
- gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas ] \n " + err + "\nfile : " + Error().fileName+"\nline : "+err.lineNumber); \r
+ gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas ] \n " + err + "\nfile : " + Error().fileName+"\nline : "+err.lineNumber);\r
}\r
}\r
- if(!isarrayValueAppend && arrayValue[idx_arrayValue]!=""){ \r
- if(xSeparator && newlabel!=""){\r
+ if (!isarrayValueAppend && arrayValue[idx_arrayValue] !== "") {\r
+ if (xSeparator && newlabel !== "") {\r
newlabel += xSeparator + arrayValue[idx_arrayValue];\r
- }else{\r
+ } else {\r
newlabel = arrayValue[idx_arrayValue];\r
}\r
- if(xSeparator && newximfvalue!=""){\r
- newximfvalue += xSeparator + arrayValue[idx_arrayValue]; \r
- }else{\r
+ if (xSeparator && newximfvalue !== "") {\r
+ newximfvalue += xSeparator + arrayValue[idx_arrayValue];\r
+ } else {\r
newximfvalue = arrayValue[idx_arrayValue];\r
}\r
- if(xSeparator && newtooltiptex!=""){\r
- newtooltiptex += xSeparator + arrayValue[idx_arrayValue]; \r
- }else{\r
+ if (xSeparator && newtooltiptex !== "") {\r
+ newtooltiptex += xSeparator + arrayValue[idx_arrayValue];\r
+ } else {\r
newtooltiptex = arrayValue[idx_arrayValue];\r
}\r
}\r
}\r
- \r
//insert values in textbox\r
- if(newximfvalue!="") $(display_box).attr("ximfvalue",newximfvalue);\r
- if(newtooltiptex!="") $(display_box).attr("tooltiptext",newtooltiptex);\r
- if(newlabel!="") display_box.inputField.value = newlabel; \r
- if(newximftecvalue!="") $(display_box).attr("ximftecvalue",newximftecvalue);\r
- if(xTecSeparator!="") $(display_box).attr("ximftecseparator",xTecSeparator);\r
- if(xSeparator!="") $(display_box).attr("ximfseparator",xSeparator);\r
- }\r
- \r
- // button value (ilk, linkpopup...) \r
- var button_item = $("panel[id='"+$(display_box).attr("refpanel")+"'] button"); \r
- if(button_item.length > 0){ \r
- for(var idx_button_item = 0 ; idx_button_item < button_item.length ; ++idx_button_item){\r
- try{\r
- var current_ximfvalue = button_item[idx_button_item].getAttribute("ximfvalue"); \r
- if(current_ximfvalue != ""){ \r
- var valuemsg = String_trim(ximfValue.toLowerCase());\r
- var valueref = String_trim(current_ximfvalue.toLowerCase()); \r
- if( valuemsg.indexOf(valueref, 0) != -1 ){\r
- \r
- //linkpopup manager \r
+ if (newximfvalue !== "") {\r
+ $(display_box).attr("ximfvalue",newximfvalue);\r
+ }\r
+ if (newtooltiptex !== "") {\r
+ $(display_box).attr("tooltiptext",newtooltiptex);\r
+ }\r
+ if (newlabel !== "") {\r
+ display_box.inputField.value = newlabel;\r
+ }\r
+ if (newximftecvalue !== "") {\r
+ $(display_box).attr("ximftecvalue",newximftecvalue);\r
+ }\r
+ if (xTecSeparator !== "") {\r
+ $(display_box).attr("ximftecseparator",xTecSeparator);\r
+ }\r
+ if (xSeparator !== "") {\r
+ $(display_box).attr("ximfseparator",xSeparator);\r
+ }\r
+ }\r
+ // button value (ilk, linkpopup...)\r
+ var button_item = $("panel[id='"+$(display_box).attr("refpanel")+"'] button");\r
+ if (button_item.length > 0) {\r
+ for (var idx_button_item = 0 ; idx_button_item < button_item.length ; ++idx_button_item) {\r
+ try {\r
+ current_ximfvalue = button_item[idx_button_item].getAttribute("ximfvalue");\r
+ if (current_ximfvalue !== "") {\r
+ valuemsg = String_trim(ximfValue.toLowerCase());\r
+ valueref = String_trim(current_ximfvalue.toLowerCase());\r
+ if ( valuemsg.indexOf(valueref, 0) !== -1 ) {\r
+ //linkpopup manager\r
var linkpopup = button_item[idx_button_item].getAttribute("linkpopupbox");\r
- if(linkpopup){ \r
+ if (linkpopup) {\r
var targetpopup = $("panel[id='"+linkpopup+"']");\r
$("textbox[id='" + targetpopup[0].getAttribute("ximfreftextbox")+"']").attr("refpanel",linkpopup);\r
}\r
- \r
- //insert values in textbox \r
+ //insert values in textbox\r
$(display_box).attr("ximfvalue",current_ximfvalue);\r
$(display_box).attr("tooltiptext",button_item[idx_button_item].getAttribute("label"));\r
display_box.inputField.value = button_item[idx_button_item].getAttribute("label");\r
- \r
//technical value is associated\r
- try{ \r
+ try {\r
var xtcval = button_item[idx_button_item].getAttribute("ximftecvalue");\r
- if(xtcval){ \r
+ if (xtcval) {\r
$(display_box).attr("ximftecvalue",xtcval);\r
}\r
- }catch(err){}\r
+ } catch (err) {}\r
}\r
}\r
- }catch(err){\r
- gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas ] \n " + err + "\nfile : " + Error().fileName+"\nline : "+err.lineNumber); \r
+ } catch (err) {\r
+ gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas ] \n " + err + "\nfile : " + Error().fileName+"\nline : "+err.lineNumber);\r
}\r
}\r
- } \r
+ }\r
}\r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
}\r
}\r
- \r
- // load free text values\r
- xheader_dom = $("textbox[class='ximfEditor']"); \r
- for(var idx_xheader_dom=0; idx_xheader_dom<xheader_dom.length; ++idx_xheader_dom){\r
- try{\r
- var oriTxtboxId = xheader_dom[idx_xheader_dom].getAttribute("ximfreftextbox"); \r
- var ximfLabelId = $("textbox[id='"+oriTxtboxId+"']").attr("refheader");\r
- if(ximfLabelId){\r
- //gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - search value for freetext :" + $("label[id='"+ximfLabelId+"']").attr("ximfheader")+"\nid ="+ximfLabelId); \r
- var ximfValue = ximfMessage.getHeaderValue($("label[id='"+ximfLabelId+"']").attr("ximfheader")); \r
- if(ximfValue){ \r
- xheader_dom[idx_xheader_dom].setAttribute("value",ximfValue);\r
- } \r
- } \r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
- } \r
+ // load free text values\r
+ xheader_dom = $("textbox[class='ximfEditor']");\r
+ var ximfValue = "";\r
+ for (var idxXmfEdtr=0; idxXmfEdtr<xheader_dom.length; ++idxXmfEdtr) {\r
+ try {\r
+ var oriTxtboxId = xheader_dom[idxXmfEdtr].getAttribute("ximfreftextbox");\r
+ var ximfLabelId = $("textbox[id='"+oriTxtboxId+"']").attr("refheader");\r
+ if (ximfLabelId) {\r
+ ximfValue = ximfMessage.getHeaderValue($("label[id='"+ximfLabelId+"']").attr("ximfheader"));\r
+ if (ximfValue) {\r
+ xheader_dom[idxXmfEdtr].setAttribute("value",ximfValue);\r
+ }\r
+ }\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
}\r
- \r
- // load address values\r
- xheader_dom = $("ximfaddress"); \r
- for(var idx_xheader_dom=0; idx_xheader_dom<xheader_dom.length; ++idx_xheader_dom){\r
- try{\r
- var refHeader = xheader_dom[idx_xheader_dom].getAttribute(_XIMF_ATT_REF_HEADER); \r
- if(refHeader){\r
- //gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - search value for freetext :" + $("label[id='"+ximfLabelId+"']").attr("ximfheader")+"\nid ="+ximfLabelId); \r
- var ximfValue = ximfMessage.getHeaderValue($("label[id='"+refHeader+"']").attr("ximfheader")); \r
- if(ximfValue){ \r
- xheader_dom[idx_xheader_dom].listaddress = ximfValue;\r
- //alert("load address values \n"+ximfValue+"\n"+xheader_dom[idx_xheader_dom].listaddress); \r
- } \r
- } \r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
- } \r
+ }\r
+ // load address values\r
+ xheader_dom = $("ximfaddress");\r
+ var refHeader = "";\r
+ for(var idxXmfAddr=0; idxXmfAddr<xheader_dom.length; ++idxXmfAddr){\r
+ try {\r
+ refHeader = xheader_dom[idxXmfAddr].getAttribute(ximfConst._XIMF_ATT_REF_HEADER);\r
+ if (refHeader) {\r
+ ximfValue = ximfMessage.getHeaderValue($("label[id='" + refHeader + "']").attr("ximfheader"));\r
+ if (ximfValue) {\r
+ xheader_dom[idxXmfAddr].listaddress = ximfValue;\r
+ }\r
+ }\r
+ } catch (e) {\r
+ gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
}\r
- \r
- // load datetime values \r
- xheader_dom = $("textbox[class='ximfDatetime']"); \r
- for(var idx_xheader_dom=0; idx_xheader_dom<xheader_dom.length; ++idx_xheader_dom){\r
- try{\r
- var refHeader = xheader_dom[idx_xheader_dom].getAttribute(_XIMF_ATT_REF_HEADER); \r
- if(refHeader){\r
- //gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - search value for freetext :" + $("label[id='"+ximfLabelId+"']").attr("ximfheader")+"\nid ="+ximfLabelId); \r
- var ximfValue = ximfMessage.getHeaderValue($("label[id='"+refHeader+"']").attr("ximfheader")); \r
- if(ximfValue){\r
- //alert($("label[id='"+refHeader+"']").attr("ximfheader")+" :: "+ximfValue)\r
- var thisDate = ConvertZTimeToLocal(ximfValue); \r
- if(!thisDate) thisDate = ximfValue; \r
- // load date\r
- xheader_dom[idx_xheader_dom].setAttribute("value",thisDate );\r
- xheader_dom[idx_xheader_dom].setAttribute("ximfvalue", ximfValue); \r
- } \r
- } \r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
- } \r
+ }\r
+ // load datetime values\r
+ xheader_dom = $("textbox[class='ximfDatetime']");\r
+ for (var idxXmfDtm=0; idxXmfDtm<xheader_dom.length; ++idxXmfDtm) {\r
+ try {\r
+ refHeader = xheader_dom[idxXmfDtm].getAttribute(ximfConst._XIMF_ATT_REF_HEADER);\r
+ if (refHeader) {\r
+ ximfValue = ximfMessage.getHeaderValue($("label[id='" + refHeader + "']").attr("ximfheader"));\r
+ if (ximfValue) {\r
+ var thisDate = ConvertZTimeToLocal(ximfValue);\r
+ if (!thisDate) {\r
+ thisDate = ximfValue;\r
+ }\r
+ // load date\r
+ xheader_dom[idxXmfDtm].setAttribute("value",thisDate );\r
+ xheader_dom[idxXmfDtm].setAttribute("ximfvalue", ximfValue);\r
+ }\r
+ }\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
}\r
- CheckXimfhdrsSelection(); \r
- }catch(e){\r
- gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber); \r
+ }\r
+ CheckXimfhdrsSelection();\r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - XimfMsgComposeView - refreshDatas] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
}\r
}\r
-\r
-// END COMPUTE FUNCTIONS\r
-\r
-\r
/*\r
* XIMF RULES AND DOM\r
*/\r
-function ExecuteXimfHdrsMandatoryRule(){\r
+function ExecuteXimfHdrsMandatoryRule() {\r
var isRuleOk=true;\r
- /*\r
- var mandatoriesHdrs = $("label[ximfmandatory='true']");\r
- for(var i=0; i<mandatoriesHdrs.length; ++i){\r
- if($("textbox[refheader='"+mandatoriesHdrs[i].getAttribute("id")+"']").attr("ximfvalue") == ""){\r
- mandatoriesHdrs[i].setAttribute("style","color:red;"); \r
- isRuleOk = false;\r
- }else{\r
- mandatoriesHdrs[i].setAttribute("style","color:black;"); \r
- }\r
- }*/\r
- \r
//color tab container\r
var panelHdrs = $("tabpanel[class='ximfpane']");\r
for(var idx_panelHdrs = 0 ; idx_panelHdrs < panelHdrs.length ; ++idx_panelHdrs){\r
// CheckXimfhdrsSelection for mandatory elements\r
var mandatoriesHdrs = $("tabpanel[id='"+ idXimfPanel + "'] label[ximfmandatory='true']");\r
for(var i=0; i<mandatoriesHdrs.length; ++i){\r
- if($("textbox[refheader='"+mandatoriesHdrs[i].getAttribute("id")+"']").attr("ximfvalue") == ""){\r
- mandatoriesHdrs[i].setAttribute("style","color:#b20000;"); \r
- cTab[0].setAttribute("ismandatory","true"); \r
- isRuleOk = false; \r
+ if($("textbox[refheader='"+mandatoriesHdrs[i].getAttribute("id")+"']").attr("ximfvalue") === ""){\r
+ mandatoriesHdrs[i].setAttribute("style","color:#b20000;");\r
+ cTab[0].setAttribute("ismandatory","true");\r
+ isRuleOk = false;\r
}else{\r
- mandatoriesHdrs[i].setAttribute("style","color:inherit;"); \r
+ mandatoriesHdrs[i].setAttribute("style","color:inherit;");\r
}\r
}\r
}\r
return isRuleOk;\r
}\r
- \r
/*\r
* XIMF RULES AND DOM\r
*/\r
-function ExecuteXimfHdrsAssociationRule(){\r
+function ExecuteXimfHdrsAssociationRule() {\r
var isRuleOk=true;\r
var isAlertDisplayed=false;\r
var associateArray = gXimfHdrs.getXimfAssociatedHdrArray();\r
- if(!associateArray) return isRuleOk;\r
- \r
+ if (!associateArray) {\r
+ return isRuleOk;\r
+ }\r
// label to prompt\r
// internationalisation\r
var sAlertLabel = "";\r
- try{ \r
+ try{\r
var gBundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);\r
- var stringBundle = gBundle.createBundle("chrome://ximfmail/locale/ximfmail.properties"); \r
+ var stringBundle = gBundle.createBundle("chrome://ximfmail/locale/ximfmail.properties");\r
sAlertLabel = stringBundle.GetStringFromName("ximf-association-alert-label");\r
- }catch(err){sAlertLabel = "Datas will be deleted!"} \r
- \r
+ }catch(err){\r
+ sAlertLabel = "Datas will be deleted!";\r
+ }\r
var reg=new RegExp("[&]+", "g");\r
- for(var i=0; i<associateArray.length; ++i){ \r
+ for(var i=0; i<associateArray.length; ++i){\r
var headerRef = $("label[ximfheader='"+associateArray[i]._headerRef+"']").attr("id");\r
var valueRef = $("textbox[refheader='"+headerRef+"']").attr("ximfvalue");\r
- \r
var headerName = $("label[ximfheader='"+associateArray[i]._headerName+"']").attr("id");\r
var valueName = $("textbox[refheader='"+headerName+"']").attr("ximfvalue");\r
- \r
var tabAssociateValueRef =associateArray[i]._valueRef.split(reg);\r
var tabAssociateValueName =associateArray[i]._valueName.split(reg);\r
- \r
var idTextbox = $("textbox[refheader='"+headerName+"']").attr("id");\r
- var tabItems = $("panel[ximfreftextbox='"+idTextbox+"'] menuitem");// list of menuitems\r
- \r
- if(valueRef !=""){ \r
- for(var j=0; j<tabAssociateValueRef.length; ++j){ \r
- if(valueRef == tabAssociateValueRef[j]){ \r
- if(tabAssociateValueName[j].lastIndexOf(valueName) == -1 ){\r
- \r
- if(valueName != "" && !isAlertDisplayed){\r
+ // list of menuitems\r
+ var tabItems = $("panel[ximfreftextbox='"+idTextbox+"'] menuitem");\r
+ if(valueRef !== ""){\r
+ for(var j=0; j<tabAssociateValueRef.length; ++j){\r
+ if(valueRef === tabAssociateValueRef[j]){\r
+ if(tabAssociateValueName[j].lastIndexOf(valueName) === -1 ){\r
+ if(valueName !== "" && !isAlertDisplayed){\r
// ask for delete datas\r
ximfAlert(sAlertLabel);\r
- isAlertDisplayed = true; \r
- } \r
- \r
- EraseAndComputeXimfhdrsTextbox($("textbox[refheader='"+headerName+"']").attr("id")); \r
+ isAlertDisplayed = true;\r
+ }\r
+ EraseAndComputeXimfhdrsTextbox($("textbox[refheader='"+headerName+"']").attr("id"));\r
}\r
for(var idx_tabItems=0; idx_tabItems<tabItems.length; ++idx_tabItems){\r
- if(tabAssociateValueName[j].lastIndexOf(tabItems[idx_tabItems].getAttribute("ximfvalue")) == -1){\r
+ if(tabAssociateValueName[j].lastIndexOf(tabItems[idx_tabItems].getAttribute("ximfvalue")) === -1){\r
tabItems[idx_tabItems].setAttribute("disabled","true");\r
tabItems[idx_tabItems].parentNode.setAttribute("ximfenable","false"); // css style\r
}else{\r
- tabItems[idx_tabItems].removeAttribute("disabled"); \r
+ tabItems[idx_tabItems].removeAttribute("disabled");\r
tabItems[idx_tabItems].parentNode.setAttribute("ximfenable","true"); // css style\r
- } \r
+ }\r
}\r
}\r
}\r
for(var idx_tabItems=0; idx_tabItems<tabItems.length; ++idx_tabItems){\r
tabItems[idx_tabItems].setAttribute("disabled","true");\r
tabItems[idx_tabItems].parentNode.setAttribute("ximfenable","false"); // css style\r
- \r
- if(valueName != "" && !isAlertDisplayed){\r
+\r
+ if(valueName !== "" && !isAlertDisplayed){\r
// ask for delete datas\r
- ximfAlert(sAlertLabel); \r
+ ximfAlert(sAlertLabel);\r
isAlertDisplayed = true;\r
}\r
EraseAndComputeXimfhdrsTextbox($("textbox[refheader='"+headerName+"']").attr("id"));\r
- \r
- } \r
+ }\r
}\r
}\r
- return isRuleOk; \r
+ return isRuleOk;\r
}\r
-\r
/*\r
* XIMF RULES AND DOM : manage default values\r
*/\r
-function ExecuteXimfHdrsDefaultValuesRule(){\r
- \r
- try{ \r
+function ExecuteXimfHdrsDefaultValuesRule() {\r
+ try{\r
// get default value in ximfHdr\r
- var textboxXimfHdrs = $("textbox[class='XimfTextboxDisplay']"); \r
- for(var i=0; i<textboxXimfHdrs.length; ++i){\r
+ var textboxXimfHdrs = $("textbox[class='XimfTextboxDisplay']");\r
+ for (var i=0; i<textboxXimfHdrs.length; ++i) {\r
try{\r
- var refDefaultItemXimfHdr = $("panel[id='" + $(textboxXimfHdrs[i]).attr("refpanel") + "']").attr("ximfdefault"); \r
- if(refDefaultItemXimfHdr && $(textboxXimfHdrs[i]).attr("ximfvalue") == "" ){\r
+ var refDefaultItemXimfHdr = $("panel[id='" + $(textboxXimfHdrs[i]).attr("refpanel") + "']").attr("ximfdefault");\r
+ if(refDefaultItemXimfHdr && $(textboxXimfHdrs[i]).attr("ximfvalue") === "" ){\r
var item = $("#"+refDefaultItemXimfHdr);\r
if(item.length > 0){\r
$(textboxXimfHdrs[i]).attr("ximfvalue",$(item[0]).attr("ximfvalue"));\r
- textboxXimfHdrs[i].value = $(item[0]).attr("label"); \r
+ textboxXimfHdrs[i].value = $(item[0]).attr("label");\r
var techvalue=$(item[0]).attr("ximftecvalue");\r
- if(techvalue){ \r
+ if(techvalue){\r
$(textboxXimfHdrs[i]).attr("ximftecvalue",techvalue);\r
}\r
}else{\r
}\r
}\r
}catch(err){}\r
- } \r
+ }\r
}catch(err){\r
gConsole.logStringMessage("[ximfmail - ExecuteXimfHdrsDefaultValuesRule ] \n " + err + "\nfile : " + Error().fileName+"\nline : "+err.lineNumber);\r
- } \r
- \r
- \r
+ }\r
}\r
-\r
/*\r
* Init non generic rules\r
* FT 3504\r
*/\r
-function InitSpecialXimfRules(){ \r
+function InitSpecialXimfRules() {\r
try{\r
// load special rules\r
var specialRulesArray = gXimfHdrs.getSpecialRulesArray();\r
for(var i=0 ; i < specialRulesArray.length ; ++i){\r
- // search for ximf value \r
- var nameHeader = specialRulesArray[i]._headerName; \r
+ // search for ximf value\r
+ var nameHeader = specialRulesArray[i]._headerName;\r
var refHeader = specialRulesArray[i]._headerRef;\r
var targetName = specialRulesArray[i]._targetName;\r
- \r
switch(targetName){\r
case XIMF_RULE_TARGET_NAME_MANDATORY_HEADERS:\r
gConsole.logStringMessage("[ximfmail - InitSpecialXimfRules ] load special rule " + targetName);\r
SpecialMandatoryHeaders(nameHeader,refHeader);\r
break;\r
- default: break;\r
+ default:\r
+ break;\r
}\r
- //alert("refHeader = " + refHeader + "\nnameHeader = " + nameHeader+"\ntargetName = " + targetName);\r
- } \r
+ }\r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - InitSpecialXimfRules ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
}\r
}\r
-\r
/*\r
- * \r
+ *\r
*/\r
-function AppendESSSecuityLabel (){\r
+function AppendESSSecuityLabel () {\r
var essArray = gXimfHdrs.getESSSecurityLabelHdrArray();\r
- if(!essArray) return;\r
- if(essArray.length <= 0) return;\r
- \r
- if(!gSMFields) return;\r
+ if (!essArray) {\r
+ return;\r
+ }\r
+ if (essArray.length <= 0) {\r
+ return;\r
+ }\r
+ if (!gSMFields) {\r
+ return;\r
+ }\r
try{\r
- var essLabels = CreateDOMWithXimfInstance(gXimfHdrs.getXimfInstanceResource(),gChromeXslSecurityLabel); \r
- }catch(e){ \r
+ var essLabels = CreateDOMWithXimfInstance(gXimfHdrs.getXimfInstanceResource(),ximfConst.CHROME_XSL_SECURITY_LABEL);\r
+ }catch(e){\r
gConsole.logStringMessage("[ximfmail - AppendESSSecuityLabel ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
return false;\r
- } \r
- try{ \r
+ }\r
+ try{\r
var ximftexboxArray = $("#ximfmailComposeMessageHeadersTablist textbox");\r
var ximfhiddenlabelArray = $("#ximfmailComposeMessageHeadersTablist label[class='ximfHiddenHeader']");\r
- var elt = null; \r
+ var elt = null;\r
+ var sXimfValue = null;\r
+ var sXimfLabel = null;\r
+ var sXimfSeparator = null;\r
+ var sXimfTecSeparator = null;\r
+ var refHeader = null;\r
+ var refValue =null;\r
+ var nameValue = null;\r
+ var sXimfHeader = null;\r
+ var item = undefined;\r
for(var i=0 ; i < essArray.length ; ++i){\r
- // search for ximf value \r
- var sXimfValue = null;\r
- var sXimfLabel = null;\r
- var sXimfSeparator = null;\r
- var sXimfTecSeparator = null;\r
- var refHeader = essArray[i]._headerRef; \r
- var refValue = essArray[i]._valueRef;\r
- var nameValue = essArray[i]._valueName; \r
- \r
+ // search for ximf value\r
+ sXimfValue = null;\r
+ sXimfLabel = null;\r
+ sXimfSeparator = null;\r
+ sXimfTecSeparator = null;\r
+ refHeader = essArray[i]._headerRef;\r
+ refValue = essArray[i]._valueRef;\r
+ nameValue = essArray[i]._valueName;\r
for(var j=0 ; j < ximftexboxArray.length; ++j ){\r
- var sXimfHeader = $("label[id='" + ximftexboxArray[j].getAttribute(_XIMF_ATT_REF_HEADER) + "']").attr("ximfheader");\r
- \r
- if(refHeader == sXimfHeader){\r
- sXimfValue = ximftexboxArray[j].getAttribute(_XIMF_ATT_XVALUE);\r
- sXimfSeparator = ximftexboxArray[j].getAttribute(_XIMF_ATT_SEPARATOR); \r
+ sXimfHeader = $("label[id='" + ximftexboxArray[j].getAttribute(ximfConst._XIMF_ATT_REF_HEADER) + "']").attr("ximfheader");\r
+ if(refHeader === sXimfHeader){\r
+ sXimfValue = ximftexboxArray[j].getAttribute(ximfConst._XIMF_ATT_XVALUE);\r
+ sXimfSeparator = ximftexboxArray[j].getAttribute(ximfConst._XIMF_ATT_SEPARATOR);\r
break;\r
}\r
- \r
//technical header case\r
- sXimfHeader = $("label[id='" + ximftexboxArray[j].getAttribute(_XIMF_ATT_REF_HEADER) + "']").attr("ximftecheader");\r
- if(refHeader == sXimfHeader){\r
- sXimfValue = ximftexboxArray[j].getAttribute(_XIMF_ATT_TEC_VALUE);\r
- sXimfSeparator = ximftexboxArray[j].getAttribute(_XIMF_ATT_SEPARATOR);\r
- sXimfLabel = ximftexboxArray[j].getAttribute(_XIMF_ATT_XVALUE);\r
- sXimfTecSeparator = ximftexboxArray[j].getAttribute(_XIMF_ATT_TEC_SEPARATOR); \r
+ sXimfHeader = $("label[id='" + ximftexboxArray[j].getAttribute(ximfConst._XIMF_ATT_REF_HEADER) + "']").attr("ximftecheader");\r
+ if(refHeader === sXimfHeader){\r
+ sXimfValue = ximftexboxArray[j].getAttribute(ximfConst._XIMF_ATT_TEC_VALUE);\r
+ sXimfSeparator = ximftexboxArray[j].getAttribute(ximfConst._XIMF_ATT_SEPARATOR);\r
+ sXimfLabel = ximftexboxArray[j].getAttribute(ximfConst._XIMF_ATT_XVALUE);\r
+ sXimfTecSeparator = ximftexboxArray[j].getAttribute(ximfConst._XIMF_ATT_TEC_SEPARATOR);\r
break;\r
}\r
}\r
if(!sXimfValue){\r
for(var idx_ximfhiddenlabelArray=0 ; idx_ximfhiddenlabelArray < ximfhiddenlabelArray.length; ++idx_ximfhiddenlabelArray ){\r
- var sXimfHeader = ximfhiddenlabelArray[idx_ximfhiddenlabelArray].getAttribute("ximfheader");\r
- if(refHeader == sXimfHeader){\r
- sXimfValue = ximfhiddenlabelArray[idx_ximfhiddenlabelArray].getAttribute(_XIMF_ATT_XVALUE);\r
- sXimfSeparator = ximfhiddenlabelArray[idx_ximfhiddenlabelArray].getAttribute(_XIMF_ATT_SEPARATOR); \r
+ sXimfHeader = ximfhiddenlabelArray[idx_ximfhiddenlabelArray].getAttribute("ximfheader");\r
+ if(refHeader === sXimfHeader){\r
+ sXimfValue = ximfhiddenlabelArray[idx_ximfhiddenlabelArray].getAttribute(ximfConst._XIMF_ATT_XVALUE);\r
+ sXimfSeparator = ximfhiddenlabelArray[idx_ximfhiddenlabelArray].getAttribute(ximfConst._XIMF_ATT_SEPARATOR);\r
break;\r
- } \r
+ }\r
}\r
- } \r
- \r
+ }\r
//search valueName if refValue defined\r
- if(refValue){\r
- var reg=new RegExp("[&]+", "g");\r
- var arrayRefValue = refValue.split(reg);\r
- var arrayNameValue = nameValue.split(reg); \r
- for (var idxArrayRefValue=0; idxArrayRefValue<arrayRefValue.length; ++idxArrayRefValue){ \r
- if(arrayRefValue[idxArrayRefValue] == sXimfValue){\r
- if (arrayNameValue[idxArrayRefValue]){ \r
- sXimfValue = arrayNameValue[idxArrayRefValue]; \r
- break;\r
- }\r
- } \r
+ if (refValue) {\r
+ var regrfVal=new RegExp("[&]+", "g");\r
+ var arrayRefValue = refValue.split(regrfVal);\r
+ var arrayNameValue = nameValue.split(regrfVal);\r
+ for (var idxArrayRefValue=0; idxArrayRefValue<arrayRefValue.length; ++idxArrayRefValue) {\r
+ if (arrayRefValue[idxArrayRefValue] === sXimfValue && arrayNameValue[idxArrayRefValue]) {\r
+ sXimfValue = arrayNameValue[idxArrayRefValue];\r
+ break;\r
+ }\r
}\r
}\r
- \r
// add label to sign it\r
- switch(essArray[i]._headerName){\r
- case "SecurityPolicyIdentifier": //Security Policy Identifier\r
- //gConsole.logStringMessage("SecurityPolicyIdentifier = "+sXimfValue); \r
- if(sXimfValue == ""){ \r
+ switch(essArray[i]._headerName) {\r
+ case "SecurityPolicyIdentifier":\r
+ //Security Policy Identifier\r
+ if (sXimfValue === "") {\r
gSMFields.securityClassification = -1;\r
gSMFields.privacyMark = "";\r
gSMFields.securityCategories = "";\r
- }else{\r
+ } else {\r
gSMFields.securityPolicyIdentifier = sXimfValue;\r
- if(essLabels){\r
+ if (essLabels) {\r
elt = essLabels.childNodes[0].getElementsByTagName("securityPolicyIdentifier");\r
elt[0].setAttribute("value",sXimfValue);\r
if(sXimfLabel){\r
}else{\r
elt[0].setAttribute("label",sXimfValue);\r
}\r
- } \r
+ }\r
}\r
break;\r
- case "SecurityClassification": \r
+ case "SecurityClassification":\r
// Security Classification\r
- // gConsole.logStringMessage("SecurityClassification = "+sXimfValue);\r
// values must be 0,1,2,3,4 or 5 (RFC 2634)\r
- // gConsole.logStringMessage("SecurityCategory = "+sXimfValue); \r
- if(sXimfValue == ""){ break; }\r
- if(sXimfValue >= 0 && sXimfValue <= 5){\r
+ if (sXimfValue === "") {\r
+ break;\r
+ }\r
+ if (sXimfValue >= 0 && sXimfValue <= 5) {\r
gSMFields.securityClassification = sXimfValue;\r
- if(essLabels){\r
+ if (essLabels) {\r
elt = essLabels.childNodes[0].getElementsByTagName("securityClassification");\r
- var item = elt[0].getElementsByTagName("item");\r
- for(var k=0; k<item.length; ++k){\r
- if(item[k].getAttribute("value") == sXimfValue){ \r
+ item = elt[0].getElementsByTagName("item");\r
+ for (var k=0; k<item.length; ++k) {\r
+ if (item[k].getAttribute("value") === sXimfValue){\r
item[k].setAttribute("ximf",sXimfLabel);\r
}\r
}\r
- } \r
+ }\r
}else{\r
gSMFields.securityClassification = -1;\r
- } \r
+ }\r
break;\r
- case "ESSPrivacyMark": // Privacy Mark \r
- //gConsole.logStringMessage("ESSPrivacyMark = "+sXimfValue);\r
+ case "ESSPrivacyMark": // Privacy Mark\r
gSMFields.privacyMark = sXimfValue;\r
- if(essLabels){\r
+ if (essLabels) {\r
elt = essLabels.childNodes[0].getElementsByTagName("privacyMark");\r
- var item = elt[0].getElementsByTagName("item");\r
- item[0].setAttribute("value",sXimfValue); \r
+ item = elt[0].getElementsByTagName("item");\r
+ item[0].setAttribute("value",sXimfValue);\r
}\r
break;\r
- case "SecurityCategory": \r
- // Security Categories \r
- // format to load : oid|type|value name e.g. 0.0.0|1|value|0.0.0.1|2|value \r
+ case "SecurityCategory":\r
+ // Security Categories\r
+ // format to load : oid|type|value name e.g. 0.0.0|1|value|0.0.0.1|2|value\r
var categories = "";\r
var regtec = new RegExp("["+sXimfTecSeparator+"]+", "g");\r
var reg = new RegExp("["+sXimfSeparator+"]+", "g");\r
- //var regtec = new RegExp("[;,]+", "g");\r
- \r
- if(sXimfValue!=""){\r
- var tab_XimfValue = sXimfValue.split(regtec); \r
- if(sXimfLabel){ \r
- var tab_XimfLabel = sXimfLabel.split(reg); \r
- for(var idx_tab_XimfValue=0; idx_tab_XimfValue<tab_XimfValue.length; ++idx_tab_XimfValue){\r
- try{\r
- if(tab_XimfValue[idx_tab_XimfValue]!="" && tab_XimfLabel[idx_tab_XimfValue]!=""){\r
- if(categories != ""){\r
+ if (sXimfValue !== "") {\r
+ var tab_XimfValue = sXimfValue.split(regtec);\r
+ if (sXimfLabel) {\r
+ var tab_XimfLabel = sXimfLabel.split(reg);\r
+ for (var idx_tab_XimfValue=0; idx_tab_XimfValue<tab_XimfValue.length; ++idx_tab_XimfValue) {\r
+ try {\r
+ if (tab_XimfValue[idx_tab_XimfValue] !== "" && tab_XimfLabel[idx_tab_XimfValue] !== "") {\r
+ if (categories !== "") {\r
categories += "|";\r
}\r
//ximftecvalue = "oid,value"\r
- var regOidValueSep = ","; // FT INT_FT4041 - var regOidValueSep = new RegExp("(,)","g");\r
+ var regOidValueSep = ","; // FT INT_FT4041\r
var tmp = tab_XimfValue[idx_tab_XimfValue];\r
var oid = tmp.slice(0,tmp.indexOf(regOidValueSep,0));\r
var value = tmp.slice(tmp.indexOf(regOidValueSep,0)+1,tmp.length);\r
- //alert("tmp=" + tmp + "\ntmp.indexOf(regOidValueSep) = " + tmp.indexOf(regOidValueSep)+"\n>>oid = "+oid+"\nvalue = " + value)\r
- \r
- if(value){ \r
- var type = null; \r
- \r
- if(essLabels){\r
+ if (value) {\r
+ var type = null;\r
+ if (essLabels) {\r
var elt = essLabels.childNodes[0].getElementsByTagName("securityCategories");\r
- //var item = elt[0].getElementsByTagName("item"); // create item...\r
// get type form rules definition\r
type = $(elt).attr("type");\r
- if(!type) type = "2"; // fefault value as integer\r
- \r
+ if (!type) {\r
+ // default value as integer\r
+ type = "2";\r
+ }\r
// add values to xml file\r
// <item oid="" type="" value="" label=""/>\r
- var item = document.createElement("item");\r
+ item = document.createElement("item");\r
item.setAttribute("oid",oid);\r
item.setAttribute("type",type);\r
item.setAttribute("value",value);\r
- item.setAttribute("label",tab_XimfLabel[idx_tab_XimfValue]); \r
- $(elt).append(item); \r
- } \r
- categories += oid + "|" + type + "|" + value; \r
+ item.setAttribute("label",tab_XimfLabel[idx_tab_XimfValue]);\r
+ $(elt).append(item);\r
+ }\r
+ categories += oid + "|" + type + "|" + value;\r
}\r
}\r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - AppendESSSecuityLabel - SecurityCategory] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
- } \r
+ }\r
}\r
}\r
- } \r
- if(categories != "")\r
+ }\r
+ if (categories !== "") {\r
gConsole.logStringMessage("SecurityCategories = " + categories);\r
- gSMFields.securityCategories = categories; \r
+ gSMFields.securityCategories = categories;\r
+ }\r
break;\r
default:\r
- break; \r
- } \r
+ break;\r
+ }\r
}\r
} catch (e) {\r
gConsole.logStringMessage("[ximfmail - AppendESSSecuityLabel ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);\r
}\r
- \r
try{\r
- /*\r
- // create file es XIMFMAIL_SECURITY_LABEL_XML_FILE \r
- if(essLabels){ \r
- // create securityLabel directory\r
- var essfile = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile); // get profile folder\r
- var serializer = new XMLSerializer();\r
- var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);\r
- \r
- essfile.append(XIMFMAIL_SECURITY_LABEL_XML_DIR);\r
- try{essfile.create(essfile.DIRECTORY_TYPE,0);}catch(err){} \r
- essfile.append(XIMFMAIL_SECURITY_LABEL_XML_FILE);\r
- \r
- foStream.init(essfile, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate\r
- serializer.serializeToStream(essLabels, foStream, ""); // rememeber, doc is the DOM tree\r
- foStream.close();\r
+ // call external trustedBird functions\r
+ securityLabelSetUIStatusBar(gSMFields.securityPolicyIdentifier, gSMFields.securityClassification);\r
+ if (!gSMFields.signMessage) {\r
+ signMessage();\r
}\r
- * */\r
}catch(e){}\r
- \r
- \r
- try{\r
- // call external trustedBird functions\r
- securityLabelSetUIStatusBar(gSMFields.securityPolicyIdentifier, gSMFields.securityClassification); \r
- if (!gSMFields.signMessage) signMessage();\r
- }catch(e){} \r
}\r
-\r
/*\r
- * Check for changes to document and allow saving before closing \r
- */ \r
-function XimfailComposeCanClose(){\r
+ * Check for changes to document and allow saving before closing\r
+ */\r
+function XimfailComposeCanClose() {\r
try{\r
- if(gContentChanged == true) return;\r
+ if (gContentChanged === true) {\r
+ return;\r
+ }\r
var charSet = null;\r
if(gMsgCompose){\r
charSet = gMsgCompose.compFields.characterSet;\r
- if(!charSet) charSet == msgCompFields.defaultCharacterSet;\r
+ if (!charSet) {\r
+ charSet === msgCompFields.defaultCharacterSet;\r
+ }\r
+ }\r
+ var ximfmailMimeSelection = ReadMimeHeadersSelection( ximfConst.XIMF_ENDLINE, charSet);\r
+ if (ximfmailMimeSelection.length > 0) {\r
+ // used xith ComposeCanClose()\r
+ gContentChanged = true;\r
}\r
- var ximfmailMimeSelection = ReadMimeHeadersSelection( XIMF_ENDLINE, charSet);\r
- if(ximfmailMimeSelection.length > 0) gContentChanged = true; // used xith ComposeCanClose() \r
} catch (e) {\r
gConsole.logStringMessage("[ximfmail - XimfailComposeCanClose ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);\r
}\r
-} \r
- \r
-/*\r
- * READ XIMFMAIL DOM SELECTION \r
- */ \r
-function ReadMimeHeadersSelection( headersSeparator, charSet){\r
+}\r
+/**\r
+ * Extract Ximf headers from DOM composer and format them to MIME headers\r
+ */\r
+function ReadMimeHeadersSelection(headersSeparator, charSet) {\r
var sCompleteList="";\r
- \r
- // insert XIMF-NAME - name of instance\r
- var ximfName = DEFAULT_XIMF_NAME;\r
- if(gXimfCatalog){\r
- ximfName = gXimfCatalog.getNameInstance(gXimfHdrs.getXimfInstanceResource());\r
- } \r
- try{\r
- // FT INT_FT3970\r
- if(ximfName.toLowerCase() == SMTP_INSTANCE){ \r
- gConsole.logStringMessage("[ximfmail - ximfmailOnSend ] Send non XIMF message - instance " + ximfName);\r
- return sCompleteList;\r
- }\r
- }catch(e){} \r
- sCompleteList += EncodeMimeXimfheader(XIMF_NAME_HEADER, ximfName, charSet) + headersSeparator;\r
-\r
- // insert XIMF-Version - B4521\r
- var ximfVersion = DEFAULT_XIMF_VERSION;\r
- if(gXimfCatalog){\r
- ximfVersion = gXimfCatalog.getVersionInstance(gXimfHdrs.getXimfInstanceResource());\r
- }\r
- sCompleteList += EncodeMimeXimfheader(XIMF_VERSION_HEADER, ximfVersion, charSet) + headersSeparator;\r
- \r
- \r
// send hidden headers elements\r
var arrayValues = $("label[class='ximfHiddenHeader']");\r
- if(arrayValues){ \r
- for(var idx=0; idx<arrayValues.length; idx++){\r
- try { \r
- if(arrayValues[idx].getAttribute(_XIMF_ATT_XVALUE)){ \r
- sCompleteList += EncodeMimeXimfheader($(arrayValues[idx]).attr("ximfheader"), $(arrayValues[idx]).attr(_XIMF_ATT_XVALUE), charSet) + headersSeparator; \r
+ if (arrayValues) {\r
+ for (var idxHdnHdr=0; idxHdnHdr<arrayValues.length; idxHdnHdr++) {\r
+ try {\r
+ if (arrayValues[idxHdnHdr].getAttribute(ximfConst._XIMF_ATT_XVALUE)) {\r
+ sCompleteList += EncodeMimeXimfheader($(arrayValues[idxHdnHdr]).attr("ximfheader"), $(arrayValues[idxHdnHdr]).attr(ximfConst._XIMF_ATT_XVALUE), charSet) + headersSeparator;\r
}\r
} catch (e) {\r
- gConsole.logStringMessage("[ximfmail - ximfmailOnSend ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber); \r
- } \r
+ gConsole.logStringMessage("[ximfmail - ximfmailOnSend ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
}\r
}\r
- \r
// send textbox elements\r
arrayValues = $("textbox[class='XimfTextboxDisplay']");\r
- if(arrayValues){ \r
- for(var idx=0; idx<arrayValues.length; idx++){\r
- try { \r
- if($(arrayValues[idx]).attr(_XIMF_ATT_XVALUE)){\r
- sCompleteList += EncodeMimeXimfheader($("#"+$(arrayValues[idx]).attr(_XIMF_ATT_REF_HEADER)).attr("ximfheader"), $(arrayValues[idx]).attr(_XIMF_ATT_XVALUE), charSet) + headersSeparator;\r
- if($(arrayValues[idx]).attr(_XIMF_ATT_TEC_VALUE)){ \r
- sCompleteList += EncodeMimeXimfheader($("#"+$(arrayValues[idx]).attr(_XIMF_ATT_REF_HEADER)).attr("ximftecheader"), $(arrayValues[idx]).attr(_XIMF_ATT_TEC_VALUE), charSet) + headersSeparator;\r
- } \r
+ if(arrayValues) {\r
+ for(var idxTxtbxDspl=0; idxTxtbxDspl<arrayValues.length; idxTxtbxDspl++) {\r
+ try {\r
+ if ($(arrayValues[idxTxtbxDspl]).attr(ximfConst._XIMF_ATT_XVALUE)) {\r
+ sCompleteList += EncodeMimeXimfheader($("#"+$(arrayValues[idxTxtbxDspl]).attr(ximfConst._XIMF_ATT_REF_HEADER)).attr("ximfheader"), $(arrayValues[idxTxtbxDspl]).attr(ximfConst._XIMF_ATT_XVALUE), charSet) + headersSeparator;\r
+ if ($(arrayValues[idxTxtbxDspl]).attr(ximfConst._XIMF_ATT_TEC_VALUE)) {\r
+ sCompleteList += EncodeMimeXimfheader($("#"+$(arrayValues[idxTxtbxDspl]).attr(ximfConst._XIMF_ATT_REF_HEADER)).attr("ximftecheader"), $(arrayValues[idxTxtbxDspl]).attr(ximfConst._XIMF_ATT_TEC_VALUE), charSet) + headersSeparator;\r
+ }\r
}\r
} catch (e) {\r
- gConsole.logStringMessage("[ximfmail - ximfmailOnSend ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber); \r
- } \r
+ gConsole.logStringMessage("[ximfmail - ximfmailOnSend ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
}\r
}\r
-\r
- // send editor elements \r
- try{ \r
+ // send editor elements\r
+ try{\r
arrayValues = $("textbox[class='ximfEditor']");\r
- if(arrayValues){\r
- for( idx=0; idx<arrayValues.length; idx++){ \r
- if(arrayValues[idx].value){\r
- try{\r
- sCompleteList += EncodeMimeXimfheader($("#"+$(arrayValues[idx]).attr(_XIMF_ATT_REF_HEADER)).attr("ximfheader"), arrayValues[idx].value, charSet) + headersSeparator; \r
+ if(arrayValues) {\r
+ for (var idxEdtr=0; idxEdtr<arrayValues.length; idxEdtr++) {\r
+ if (arrayValues[idxEdtr].value) {\r
+ try {\r
+ sCompleteList += EncodeMimeXimfheader($("#"+$(arrayValues[idxEdtr]).attr(ximfConst._XIMF_ATT_REF_HEADER)).attr("ximfheader"), arrayValues[idxEdtr].value, charSet) + headersSeparator;\r
} catch (e) {\r
gConsole.logStringMessage("[ximfmail - ximfmailOnSend ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
- } \r
+ }\r
}\r
}\r
}\r
- }catch(e){\r
- \r
- } \r
-\r
+ } catch(e) {\r
+ }\r
// send datetime elements\r
- try{\r
- //arrayValues = $("#ximfmailComposeMessagePanel " + _XIMF_ELT_DATEPICKER); \r
- arrayValues = $("textbox[class='ximfDatetime']"); \r
- if(arrayValues){ \r
- for( idx=0; idx<arrayValues.length; idx++){ \r
- if(arrayValues[idx].value){ \r
- try{\r
- sCompleteList += EncodeMimeXimfheader($("#"+$(arrayValues[idx]).attr(_XIMF_ATT_REF_HEADER)).attr("ximfheader"), arrayValues[idx].getAttribute(_XIMF_ATT_XVALUE), charSet) + headersSeparator; \r
+ try {\r
+ arrayValues = $("textbox[class='ximfDatetime']");\r
+ if (arrayValues) {\r
+ for (var idxDttm=0; idxDttm < arrayValues.length; idxDttm++) {\r
+ if (arrayValues[idxDttm].value) {\r
+ try {\r
+ sCompleteList += EncodeMimeXimfheader($("#"+$(arrayValues[idxDttm]).attr(ximfConst._XIMF_ATT_REF_HEADER)).attr("ximfheader"), arrayValues[idxDttm].getAttribute(ximfConst._XIMF_ATT_XVALUE), charSet) + headersSeparator;\r
} catch (e) {\r
- //alert(e)\r
gConsole.logStringMessage("[ximfmail - ximfmailOnSend ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
- } \r
+ }\r
}\r
}\r
}\r
- }catch(e){}\r
- \r
+ } catch(e) {}\r
// send ximfaddress elements\r
- try{\r
+ try {\r
arrayValues = $("#ximfmailComposeMessagePanel ximfaddress");\r
- if(arrayValues){ \r
- for( idx=0; idx<arrayValues.length; idx++){ \r
- if(arrayValues[idx].listaddress != ""){\r
- try{\r
- sCompleteList += EncodeMimeXimfheader($("#"+$(arrayValues[idx]).attr(_XIMF_ATT_REF_HEADER)).attr("ximfheader"), arrayValues[idx].listaddress, charSet) + headersSeparator;\r
- \r
+ if (arrayValues) {\r
+ for (var idxAddr=0; idxAddr<arrayValues.length; idxAddr++) {\r
+ if (arrayValues[idxAddr].listaddress !== "") {\r
+ try {\r
+ sCompleteList += EncodeMimeXimfheader($("#"+$(arrayValues[idxAddr]).attr(ximfConst._XIMF_ATT_REF_HEADER)).attr("ximfheader"), arrayValues[idxAddr].listaddress, charSet) + headersSeparator;\r
} catch (e) {\r
gConsole.logStringMessage("[ximfmail - ximfmailOnSend ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
- } \r
+ }\r
}\r
}\r
}\r
- }catch(e){}\r
- //alert ("getHeadersSelection \n" + sCompleteList);\r
+ } catch(e) {}\r
return sCompleteList;\r
}\r
-\r
- \r
-function ReadXsmptHeadersTranslation(headerValueSeparator, headersSeparator,charSet){\r
+function ReadXsmptHeadersTranslation(headerValueSeparator, headersSeparator,charSet) {\r
var sCompleteList = "";\r
var xsmtpArray = gXimfHdrs.getXsmtpHdrArray();\r
- if(!xsmtpArray) return;\r
+ if (!xsmtpArray) {\r
+ return;\r
+ }\r
// create mandatory xsmpt headers\r
- //this.AddMandatoryXsmtpHeader();\r
- try{ \r
- for(var i=0 ; i < xsmtpArray.length ; ++i){\r
- if(!xsmtpArray[i]._headerRef){\r
+ try {\r
+ for (var i=0 ; i < xsmtpArray.length ; ++i) {\r
+ if (!xsmtpArray[i]._headerRef) {\r
sCompleteList += EncodeMimeXimfheader(xsmtpArray[i]._headerName, xsmtpArray[i]._valueName, charSet) + headersSeparator;\r
}\r
- } \r
+ }\r
} catch (e) {\r
gConsole.logStringMessage("[ximfmail - AddMandatoryXsmtpHeader ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
}\r
- \r
// Copy and convert XIMF headers to XSMTP headers\r
- var ximftexboxArray = $("textbox[class='XimfTextboxDisplay']["+_XIMF_ATT_XVALUE+"]");\r
- for(var i = 0 ; i < ximftexboxArray.length; ++i ){\r
- var sXimfHeader = $("label[class='ximfHeaderLabel'][id='" + ximftexboxArray[i].getAttribute(_XIMF_ATT_REF_HEADER) + "']").attr("ximfheader");\r
- var sXimfValue = ximftexboxArray[i].getAttribute(_XIMF_ATT_XVALUE);\r
- \r
- if(sXimfValue != ""){\r
- //this.AddXsmtpHeader(sXimfHeader,sXimfValue);\r
- try{ \r
- for(var j=0 ; j < xsmtpArray.length ; ++j){\r
- //alert(this._ArrayheadersCompatibility[i]._headerRef +" -- "+ ximfHeader);\r
- \r
- if(xsmtpArray[j]._headerRef == sXimfHeader){\r
- //alert(this._ArrayheadersCompatibility[i]._headerRef +" -- "+ ximfHeader);\r
- var xvalue = sXimfValue; // default, copy of XIMF value \r
+ var ximftexboxArray = $("textbox[class='XimfTextboxDisplay']["+ximfConst._XIMF_ATT_XVALUE+"]");\r
+ var xvalue = "";\r
+ for (var i = 0 ; i < ximftexboxArray.length; ++i ) {\r
+ var sXimfHeader = $("label[class='ximfHeaderLabel'][id='" + ximftexboxArray[i].getAttribute(ximfConst._XIMF_ATT_REF_HEADER) + "']").attr("ximfheader");\r
+ var sXimfValue = ximftexboxArray[i].getAttribute(ximfConst._XIMF_ATT_XVALUE);\r
+ if (sXimfValue !== "") {\r
+ try {\r
+ for (var j=0 ; j < xsmtpArray.length ; ++j) {\r
+ if (xsmtpArray[j]._headerRef === sXimfHeader) {\r
+ xvalue = sXimfValue; // default, copy of XIMF value\r
// get for values references\r
var reg=new RegExp("[&]+", "g");\r
- if(xsmtpArray[j]._valueRef){\r
+ if (xsmtpArray[j]._valueRef) {\r
var arrayValRefs = xsmtpArray[j]._valueRef.split(reg);\r
var arrayVals = xsmtpArray[j]._valueName.split(reg);\r
- for (var k=0; k<arrayValRefs.length; ++k){ \r
- if(arrayValRefs[k] == sXimfValue){\r
- if (arrayVals[k]){ \r
+ for (var k=0; k<arrayValRefs.length; ++k) {\r
+ if (arrayValRefs[k] === sXimfValue && arrayVals[k]) {\r
xvalue = arrayVals[k];\r
break;\r
- }\r
- } \r
+ }\r
+ }\r
+ } else {\r
+ if (xsmtpArray[j]._valueName) {\r
+ // default, copy of XIMF value\r
+ xvalue = xsmtpArray[j]._valueName;\r
}\r
- }else{\r
- if(xsmtpArray[j]._valueName)\r
- var xvalue = xsmtpArray[j]._valueName; // default, copy of XIMF value \r
}\r
- \r
// append line to headers\r
- sCompleteList += EncodeMimeXimfheader(xsmtpArray[j]._headerName, xvalue, charSet) + headersSeparator; \r
+ sCompleteList += EncodeMimeXimfheader(xsmtpArray[j]._headerName, xvalue, charSet) + headersSeparator;\r
}\r
- } \r
+ }\r
} catch (e) {\r
gConsole.logStringMessage("[ximfmail - AddXsmtpHeader ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);\r
}\r
- } //if \r
+ }\r
}\r
return sCompleteList;\r
}\r
-\r
/*\r
* Security rules are only valid for XIMFMAIL Instances\r
*/\r
-function ReloadSecurityAccess(){\r
+function ReloadSecurityAccess() {\r
// access secure headers\r
gCurrentIdentity.setBoolAttribute("secureheaders.checked",false);\r
- $("#idItemSecureHeaders_1").removeAttr("checked"); \r
- $("#idItemSecureHeaders_2").removeAttr("checked"); \r
- $("#idItemSecureHeaders_1").removeAttr("disabled");\r
- $("#idItemSecureHeaders_2").removeAttr("disabled"); \r
+ setNoSecureHeaderUI();\r
+ $("#secureHeaderStatus").removeAttr("disabled");\r
$("#menu_securitySign1").removeAttr("disabled");\r
$("#menu_securitySign2").removeAttr("disabled");\r
- \r
// access security label\r
- $("#menu_securityLabelDialog1").removeAttr("checked"); \r
- $("#menu_securityLabelDialog2").removeAttr("checked"); \r
+ $("#menu_securityLabelDialog1").removeAttr("checked");\r
+ $("#menu_securityLabelDialog2").removeAttr("checked");\r
$("#menu_securityLabelDialog1").removeAttr("disabled");\r
- $("#menu_securityLabelDialog2").removeAttr("disabled"); \r
+ $("#menu_securityLabelDialog2").removeAttr("disabled");\r
}
\ No newline at end of file
var pkiParams = window.arguments[0].QueryInterface(Components.interfaces.nsIPKIParamBlock);\r
params = pkiParams.QueryInterface(Components.interfaces.nsIDialogParamBlock);\r
gSignatureStatus = params.GetInt(1);\r
- if(gSignatureStatus == -1){\r
+ if(gSignatureStatus === -1){\r
var gBundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);\r
- var stringBundle = gBundle.createBundle("chrome://ximfmail/locale/ximfmail.properties"); \r
- var sLabel = stringBundle.GetStringFromName("ximfmail.securityinfo.warning"); \r
+ var stringBundle = gBundle.createBundle("chrome://ximfmail/locale/ximfmail.properties");\r
+ var sLabel = stringBundle.GetStringFromName("ximfmail.securityinfo.warning");\r
var labelItem = document.getElementById("signatureLabel");\r
labelItem.value = sLabel;\r
labelItem.setAttribute("style","color:#b20000");\r
<!-- ***** BEGIN LICENSE BLOCK *****\r
- Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
- ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- - \r
-\r
- - Redistribution and use, in source and binary forms, with or without modification, \r
+ -\r
+ - Redistribution and use, in source and binary forms, with or without modification,\r
- are permitted provided that the following conditons are met :\r
-\r
- - 1. Redistributions of source code must retain the above copyright notice, \r
- - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ - 1. Redistributions of source code must retain the above copyright notice,\r
+ - 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
- in the redistribution of the source code.\r
- - 3. Neither the names of the copyright holders nor the names of any contributors \r
- - may be used to endorse or promote products derived from this software without specific \r
+ - 3. Neither the names of the copyright holders nor the names of any contributors\r
+ - may be used to endorse or promote products derived from this software without specific\r
- prior written permission from EADS Defence and Security.\r
- - \r
+ -\r
- Alternatively, the contents of this file may be used under the terms of\r
- either of the GNU General Public License Version 2 or later (the "GPL"),\r
- or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
- and other provisions required by the GPL or the LGPL. If you do not delete\r
- the provisions above, a recipient may use your version of this file under\r
- the terms of any one of the MPL, the GPL or the LGPL.\r
- - \r
+ -\r
- REMINDER :\r
- - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ - ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ - WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ - IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ - INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ - (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ - LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ - WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
- IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- - \r
- - EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ -\r
+ - EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ - \r
+ - Contributor(s):\r
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved \r
- ***** END LICENSE BLOCK ***** -->\r
\r
<?xml-stylesheet href="chrome://ximfmail/skin" type="text/css"?>\r
-\r
/* ***** BEGIN LICENSE BLOCK *****\r
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
*\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
* are permitted provided that the following conditons are met :\r
*\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
* in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
* prior written permission from EADS Defence and Security.\r
- * \r
+ *\r
* Alternatively, the contents of this file may be used under the terms of\r
* either of the GNU General Public License Version 2 or later (the "GPL"),\r
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
* and other provisions required by the GPL or the LGPL. If you do not delete\r
* the provisions above, a recipient may use your version of this file under\r
* the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
+ *\r
* REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ *\r
+ * Contributor(s):\r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
* ***** END LICENSE BLOCK ***** */\r
- \r
-/*\r
- * XimfThreadTreeDBViewObserver\r
- * 'MsgCreateDBView' : Special event that gets fired whenever a view is created. \r
- * When that event fires, set up the custom column handler on the new view.\r
+/**\r
+ * threaTree-ximfmail.js\r
+ * Add custom columns into message view folder with XIMF headers defined in rules of XIMF instance activated in user profile.\r
*/\r
+var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);\r
var XimfThreadTreeDBViewObserver = {\r
// Components.interfaces.nsIObserver\r
- observe: function(aMsgFolder, aTopic, aData){ \r
+ observe: function(aMsgFolder, aTopic, aData){\r
gConsole.logStringMessage("ximfmail - XimfThreadTreeDBViewObserver:observe");\r
XimfThreadTree.getInstance().create();\r
}\r
-}\r
-\r
+};\r
/*\r
- * Column handler template definition \r
+ * Column handler template definition\r
*/\r
function XimfCustomColumnHandler(property){\r
// Properties\r
this.property = property;\r
- this.isString = true; \r
- \r
+ this.isString = true;\r
// Functions\r
- this.getSortStringForRow = function (hdr){ return (this.isString) ? hdr.getStringProperty(this.property) : ""; };\r
- this.isString = function (){ return this.isString; };\r
- this.getCellProperties = function (row, col, props) {};\r
- this.getRowProperties = function(row, props){};\r
- this.getImageSrc = function (row, col){return null; };\r
- this.getSortLongForRow = function(hdr){ return (this.isString) ? 0 : new Number(hdr.getStringProperty(this.property)).value; };\r
+ this.getSortStringForRow = function (hdr){\r
+ return (this.isString) ? hdr.getStringProperty(this.property) : "";\r
+ };\r
+ this.isString = function (){\r
+ return this.isString;\r
+ };\r
+ this.getCellProperties = function (row, col, props) {};\r
+ this.getRowProperties = function(row, props){};\r
+ this.getImageSrc = function (row, col){\r
+ return null;\r
+ };\r
+ this.getSortLongForRow = function(hdr) {\r
+ return (this.isString) ? 0 : new Number(hdr.getStringProperty(this.property)).value;\r
+ };\r
this.getCellText = function (row, col){\r
// get cell informations\r
var key = gDBView.getKeyAt(row);\r
var hdr = gDBView.db.GetMsgHdrForKey(key);\r
- var value = hdr.getStringProperty(this.property); \r
- // get ilk value if exists \r
- var ilklabel = XimfThreadTree.getInstance().getIlkColumnArray()[this.property.toLowerCase()][value.toLowerCase()];\r
- if(ilklabel == undefined) ilklabel = value;\r
- //gConsole.logStringMessage("[ximfmail - XimfCustomColumnHandler ] getCellText "+this.property+" = " + ilklabel ); \r
- return ilklabel; \r
+ var value = hdr.getStringProperty(this.property);\r
+ // get ilk value if exists\r
+ var ilklabel = "";\r
+ if (value) {\r
+ try {\r
+ ilklabel = XimfThreadTree.getInstance().getIlkColumnArray()[this.property.toLowerCase()][value.toLowerCase()];\r
+ } catch(e) {\r
+ ilklabel = value;\r
+ }\r
+ if (ilklabel === undefined) {\r
+ ilklabel = value;\r
+ }\r
+ }\r
+ return ilklabel;\r
};\r
};\r
-\r
/*\r
- * XimfThreadTree \r
+ * XimfThreadTree\r
* Custom Columns with XIMF headers\r
- * Get XIMF headers in xml containers <ihm> of Ximfmail instances : \r
+ * Get XIMF headers in xml containers <ihm> of Ximfmail instances :\r
* <ximf:treeRcv>\r
- * <ximf:headerRef>header-reference</ximf:headerRef> \r
+ * <ximf:headerRef>header-reference</ximf:headerRef>\r
* <ximf:headerRef>header-reference-other</ximf:headerRef>\r
* </ximf:treeRcv>\r
*/\r
var XimfThreadTree = (function(){\r
// private:\r
- var instantiated; \r
+ var instantiated;\r
var _chromeXslTreeRcv = "chrome://theme_ximfmail/content/threadTree-ximfmail.xsl";\r
var _ximfHdrArrayByID = [];\r
- var _refAccountArray = []; \r
+ var _refAccountArray = [];\r
var _ximfIlilkCustomColumnArray = [];\r
- \r
// add DOM element to tree\r
function addColumn(domTreecol,idTreecol){\r
- $("#threadCols").append(domTreecol); // istancedom_treecol is mofified by append jquery function is called\r
+ // istancedom_treecol is mofified by append jquery function is called\r
+ $("#threadCols").append(domTreecol);\r
var splitter_dom = document.createElement("splitter");\r
$(splitter_dom).attr("reftreecol",idTreecol);\r
$(splitter_dom).attr("class","tree-splitter");\r
- $(splitter_dom).attr("ximfheadtree","1"); \r
+ $(splitter_dom).attr("ximfheadtree","1");\r
$("#threadCols").append(splitter_dom);\r
gConsole.logStringMessage("[ximfmail - XimfThreadTree:addColumn] add new ximf column to Dom - id = " + idTreecol);\r
};\r
// attach handler object to custom column. addColumnHandler that takes a column ID\r
function addColumnHandler(idTreecol){\r
- if (gDBView){ \r
- gDBView.addColumnHandler(idTreecol, new XimfCustomColumnHandler(idTreecol.toLowerCase())); \r
+ if (gDBView){\r
+ gDBView.addColumnHandler(idTreecol, new XimfCustomColumnHandler(idTreecol.toLowerCase()));\r
gConsole.logStringMessage("[ximfmail - XimfThreadTree:addColumnHandler] load new XimfCustomColumnHandler for column " + idTreecol);\r
}\r
};\r
// remove DOM element from tree\r
- function deleteColummn(idTreeCol){ \r
+ function deleteColummn(idTreeCol){\r
for(var i = 0 ; i < _ximfHdrArrayByID.length ; ++i){\r
if(_ximfHdrArrayByID[i] === idTreeCol){\r
_ximfHdrArrayByID.splice(i,1);\r
$("#"+idTreeCol).remove();\r
$("splitter[reftreecol='"+idTreeCol+"']").remove();\r
- gConsole.logStringMessage("[ximfmail - XimfThreadTree:deleteColummn] remove ximf column from Dom - id = " + idTreeCol); \r
+ gConsole.logStringMessage("[ximfmail - XimfThreadTree:deleteColummn] remove ximf column from Dom - id = " + idTreeCol);\r
}\r
- } \r
+ }\r
};\r
// update Ximfmail column\r
function updateXimfHdrArrayByID(idToUpdate){\r
- gConsole.logStringMessage("[ximfmail - XimfThreadTree:updateXimfHdrArrayByID] update Ximfmail column " + idToUpdate); \r
+ gConsole.logStringMessage("[ximfmail - XimfThreadTree:updateXimfHdrArrayByID] update Ximfmail column " + idToUpdate);\r
var isIdExist = false;\r
for(var i = 0 ; i < _ximfHdrArrayByID.length ; ++i){\r
- if(_ximfHdrArrayByID[i] === idToUpdate){ \r
+ if(_ximfHdrArrayByID[i] === idToUpdate){\r
isIdExist = true;\r
break;\r
}\r
var xListHdr = "";\r
var prefList = [];\r
var prefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch(null);\r
- \r
try {\r
xListHdr = prefBranch.getCharPref(preference);\r
- if((xListHdr) != ""){\r
+ if((xListHdr) !== ""){\r
var reg=new RegExp("[ ]+", "g");\r
- prefList=xListHdr.split(reg); \r
+ prefList=xListHdr.split(reg);\r
}\r
} catch(ex) {}\r
- \r
- function isDataInArray(data,array){ \r
+ function isDataInArray(data,array){\r
for(var i=0; i<array.length; ++i){\r
- if(data == array[i]){\r
+ if(data === array[i]){\r
return true;\r
}\r
}\r
return false;\r
- }; \r
- \r
+ };\r
// add only new headers\r
- for (var i = 0; i < _ximfHdrArrayByID.length; i++) { \r
+ for (var i = 0; i < _ximfHdrArrayByID.length; i++) {\r
if (!isDataInArray(_ximfHdrArrayByID[i].toLowerCase(),prefList)){\r
- if (xListHdr != "") {\r
+ if (xListHdr !== "") {\r
xListHdr += " ";\r
- } \r
+ }\r
xListHdr += _ximfHdrArrayByID[i].toLowerCase();\r
}\r
}\r
prefBranch.setCharPref(preference, xListHdr);\r
};\r
// obsolete?\r
- function updateColumnToHide(){ \r
+ function updateColumnToHide(){\r
try{\r
- if(_ximfHdrArrayByID.length <= 0 ) return;\r
- if(gCurrentIdentity){ \r
+ if(_ximfHdrArrayByID.length <= 0 ) {\r
+ return;\r
+ }\r
+ if(gCurrentIdentity){\r
var prefList = gCurrentIdentity.getCharAttribute("ximfmail_context_DBHeaders");\r
- if(prefList == undefined) return;\r
+ if (prefList === undefined) {\r
+ return;\r
+ }\r
for(var i=0; i<_ximfHdrArrayByID.length; ++i){\r
- if(prefList.lastIndexOf(_ximfHdrArrayByID[i]) != -1){\r
+ if(prefList.lastIndexOf(_ximfHdrArrayByID[i]) !== -1){\r
$("treecol[id='"+_ximfHdrArrayByID[i]+"']").attr("hidden","true");\r
}\r
}\r
}\r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - XimfThreadTree:updateColumnToHide ] " + e +"\nline : " + Error().lineNumber + " : "+ e + "\nfile : "+ Error().fileName);\r
- } \r
- }; \r
+ }\r
+ };\r
// get ilk values from instance\r
- function updateXimfIlkCustomColumnArray(currentInstance){\r
+ function updateXimfIlkCustomColumnArray(currentInstance) {\r
try{\r
gConsole.logStringMessage("[ximfmail - XimfThreadTree:updateXimfIlkCustomColumnArray ] create ilk array for Ximf values of instance : "+currentInstance);\r
- \r
// get xml schema for instance\r
- gXimfCatalog = XimfCatalog.getInstance();\r
- \r
+ XimfCatalogFactory.getIntance(function(instance){\r
+ var dir = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);\r
+ var completePath = getFilePathInProfile("extensions/"+instance.getSchemaInstance(currentInstance));\r
+ dir.initWithPath( completePath );\r
+ if(!dir.exists()){\r
+ gConsole.logStringMessage("[ximfmail - XimfThreadTree:updateXimfIlkCustomColumnArray] Error on loading schema file : " + completePath);\r
+ return;\r
+ }\r
+ var objXML = GetXmlDocument(completePath);\r
+ var headers = objXML.getElementsByTagName("ximf:header");\r
+ // get xml dictionary parser\r
+ var urlDictionary = getFilePathInProfile("extensions/"+instance.getDictionaryInstance(currentInstance));\r
+ dir.initWithPath( urlDictionary );\r
+ if(!dir.exists()){\r
+ gConsole.logStringMessage("[ximfmail - XimfThreadTree:updateXimfIlkCustomColumnArray] Error on loading dictionary file : " + completePath);\r
+ return;\r
+ }\r
+ var dicoXML = GetXmlDocument(urlDictionary);\r
+ var dicoElements = dicoXML.getElementsByTagName("ximf:locale");\r
+ // get local lang\r
+ var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);\r
+ var refLang = prefs.getCharPref("general.useragent.locale");\r
+ if (!refLang) {\r
+ refLang = "fr";\r
+ }\r
+ var ilkEntities = null;\r
+ for(var idxLang=0 ; idxLang < dicoElements.length ; ++idxLang){\r
+ if(dicoElements[idxLang].getAttribute("lang") === refLang){\r
+ ilkEntities = dicoElements[idxLang].getElementsByTagName("ximf:ilk");\r
+ break;\r
+ }\r
+ }\r
+ // parse XML and get ilk values\r
+ for(var i=0 ; i < _ximfHdrArrayByID.length ; ++i){\r
+ var currentTreeColId = _ximfHdrArrayByID[i];\r
+ for(var idxH = 0 ; idxH < headers.length; ++idxH){\r
+ var attrHeaderList = headers[idxH].attributes;\r
+ var headerName = headers[idxH].getAttribute("headerName");\r
+ if(headerName.toLowerCase() === currentTreeColId.toLowerCase()){\r
+ var stringListElt = headers[idxH].getElementsByTagName("ximf:string");\r
+ var tmparray = new Array();\r
+ for(var j=0 ; j< stringListElt.length ; j++){\r
+ try{\r
+ // get values from instance headers\r
+ var sContent = stringListElt[j].getAttribute("content");\r
+ var sIlk = stringListElt[j].getAttribute("ilk");\r
+ // get ilk entity from instance dictionay\r
+ if(ilkEntities){\r
+ for(var idxIlk = 0 ; idxIlk < ilkEntities.length ; ++idxIlk){\r
+ if(ilkEntities[idxIlk].getAttribute("entity") === sIlk){\r
+ sIlk = ilkEntities[idxIlk].textContent;\r
+ break;\r
+ }\r
+ }\r
+ }\r
+ // push array\r
+ tmparray[sContent.toLowerCase()]=sIlk;\r
+ } catch(e){\r
+ gConsole.logStringMessage("[ximfmail - XimfThreadTree:updateXimfIlkCustomColumnArray ] " + e +"\nline : " + e.lineNumber + " : "+ e + "\nfile : "+ Error().fileName);\r
+ }\r
+ }\r
+ // save ilk values for an ximf header\r
+ if (tmparray) {\r
+ _ximfIlilkCustomColumnArray[headerName.toLowerCase()] = tmparray;\r
+ }\r
+ }\r
+ }\r
+ }\r
+ });\r
+ return;\r
var dir = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);\r
var completePath = getFilePathInProfile("extensions/"+gXimfCatalog.getSchemaInstance(currentInstance));\r
- dir.initWithPath( completePath ); \r
- if(!dir.exists()){ \r
+ dir.initWithPath( completePath );\r
+ if (!dir.exists()) {\r
gConsole.logStringMessage("[ximfmail - XimfThreadTree:updateXimfIlkCustomColumnArray] Error on loading schema file : " + completePath);\r
return;\r
- } \r
+ }\r
var objXML = GetXmlDocument(completePath);\r
var headers = objXML.getElementsByTagName("ximf:header");\r
- \r
// get xml dictionary parser\r
var urlDictionary = getFilePathInProfile("extensions/"+gXimfCatalog.getDictionaryInstance(currentInstance));\r
- dir.initWithPath( urlDictionary ); \r
- if(!dir.exists()){ \r
+ dir.initWithPath( urlDictionary );\r
+ if(!dir.exists()){\r
gConsole.logStringMessage("[ximfmail - XimfThreadTree:updateXimfIlkCustomColumnArray] Error on loading dictionary file : " + completePath);\r
return;\r
- } \r
+ }\r
var dicoXML = GetXmlDocument(urlDictionary);\r
var dicoElements = dicoXML.getElementsByTagName("ximf:locale");\r
- \r
- // get local lang \r
+ // get local lang\r
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);\r
var refLang = prefs.getCharPref("general.useragent.locale");\r
- if(!refLang) refLang = "fr"; \r
+ if (!refLang) {\r
+ refLang = "fr";\r
+ }\r
var ilkEntities = null;\r
- for(var idxLang=0 ; idxLang < dicoElements.length ; ++idxLang){ \r
- if(dicoElements[idxLang].getAttribute("lang") == refLang){\r
+ for(var idxLang=0 ; idxLang < dicoElements.length ; ++idxLang){\r
+ if(dicoElements[idxLang].getAttribute("lang") === refLang){\r
ilkEntities = dicoElements[idxLang].getElementsByTagName("ximf:ilk");\r
break;\r
}\r
}\r
- \r
// parse XML and get ilk values\r
for(var i=0 ; i < _ximfHdrArrayByID.length ; ++i){\r
var currentTreeColId = _ximfHdrArrayByID[i];\r
- for(var idxH = 0 ; idxH < headers.length; ++idxH){ \r
- var attrHeaderList = headers[idxH].attributes; \r
- var headerName = headers[idxH].getAttribute("headerName"); \r
- if(headerName.toLowerCase() == currentTreeColId.toLowerCase()){\r
- var stringListElt = headers[idxH].getElementsByTagName("ximf:string"); \r
- var tmparray = new Array(); \r
+ for(var idxH = 0 ; idxH < headers.length; ++idxH){\r
+ var attrHeaderList = headers[idxH].attributes;\r
+ var headerName = headers[idxH].getAttribute("headerName");\r
+ if(headerName.toLowerCase() === currentTreeColId.toLowerCase()){\r
+ var stringListElt = headers[idxH].getElementsByTagName("ximf:string");\r
+ var tmparray = new Array();\r
for(var j=0 ; j< stringListElt.length ; j++){\r
- try{ \r
+ try{\r
// get values from instance headers\r
- var sContent = stringListElt[j].getAttribute("content"); \r
- var sIlk = stringListElt[j].getAttribute("ilk") \r
+ var sContent = stringListElt[j].getAttribute("content");\r
+ var sIlk = stringListElt[j].getAttribute("ilk");\r
// get ilk entity from instance dictionay\r
if(ilkEntities){\r
for(var idxIlk = 0 ; idxIlk < ilkEntities.length ; ++idxIlk){\r
- if(ilkEntities[idxIlk].getAttribute("entity") == sIlk){\r
+ if(ilkEntities[idxIlk].getAttribute("entity") === sIlk){\r
sIlk = ilkEntities[idxIlk].textContent;\r
break;\r
}\r
}\r
}\r
- \r
// push array\r
tmparray[sContent.toLowerCase()]=sIlk;\r
- \r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - XimfThreadTree:updateXimfIlkCustomColumnArray ] " + e +"\nline : " + e.lineNumber + " : "+ e + "\nfile : "+ Error().fileName);\r
- } \r
+ }\r
+ }\r
+ // save ilk values for an ximf header\r
+ if (tmparray) {\r
+ _ximfIlilkCustomColumnArray[headerName.toLowerCase()] = tmparray;\r
}\r
- // save ilk values for an ximf header \r
- if(tmparray) _ximfIlilkCustomColumnArray[headerName.toLowerCase()] = tmparray;\r
}\r
}\r
}\r
- }catch(e){ \r
+ }catch(e){\r
gConsole.logStringMessage("[ximfmail - XimfThreadTree:updateXimfIlkCustomColumnArray] " + e +"\nline : " + e.lineNumber + " : "+ e + "\nfile : "+ Error().fileName);\r
- } \r
+ }\r
};\r
- function init(){ \r
+ function init(){\r
// singleton here\r
return{\r
// create : create Ximf columns if don't exist and/or add handler on Ximf columns\r
create : function(){\r
try{\r
gConsole.logStringMessage("[ximfmail - XimfThreadTree:create ] create begin - _ximfHdrArrayByID len : "+_ximfHdrArrayByID.length);\r
- GetCurrentUser();\r
- if(!gCurrentIdentity) return false;\r
+ GetCurrentXimfUser();\r
+ if (!gCurrentIdentity){\r
+ return false;\r
+ }\r
var refIdentityKey = gCurrentIdentity.key;\r
- var currentlistID = $("#threadCols treecol[ximfheadtree='1']"); // get existing Ximf columns \r
- \r
- // check if Ximf columns of account already created \r
+ // get existing Ximf columns\r
+ var currentlistID = $("#threadCols treecol[ximfheadtree='1']");\r
+ // check if Ximf columns of account already created\r
for(var i = 0 ; i < _refAccountArray.length ; ++i){\r
if(_refAccountArray[i] === refIdentityKey){\r
// account already updated for this session, don't do it again,\r
- // handler Ximfmail columns headers must be fired \r
+ // handler Ximfmail columns headers must be fired\r
for(var idx =0 ; idx < currentlistID.length ; ++idx){\r
- addColumnHandler(currentlistID[idx].id); \r
- } \r
+ addColumnHandler(currentlistID[idx].id);\r
+ }\r
gConsole.logStringMessage("[ximfmail - XimfThreadTree:create ] account already updated for this session - handler Ximfmail columns");\r
- return true; \r
- } \r
+ return true;\r
+ }\r
}\r
_refAccountArray.push(refIdentityKey);\r
- \r
- // get Ximfmail instance with headers to custom \r
- var currentInstance = gCurrentIdentity.getCharAttribute("ximfmail_instance_treethread_ref"); \r
+ // get Ximfmail instance with headers to custom\r
+ var currentInstance = gCurrentIdentity.getCharAttribute("ximfmail_instance_treethread_ref");\r
var instancedom = CreateDOMWithXimfInstance(currentInstance,_chromeXslTreeRcv);\r
var istancedom_treecol = instancedom.childNodes;\r
- \r
// add new headers to tree\r
gConsole.logStringMessage("[ximfmail - XimfThreadTree:create ] " + istancedom_treecol.length + " elements in Ximfmail instance to custom");\r
for(var k = istancedom_treecol.length - 1 ; k >= 0 ; --k){\r
try{\r
- var instanceId = $(istancedom_treecol[k]).attr("id"); \r
+ var instanceId = $(istancedom_treecol[k]).attr("id");\r
var isCurrentIdInInstance = false;\r
for(var l = 0 ; l < currentlistID.length ; ++l){\r
if( instanceId === $(currentlistID[l]).attr("id")){\r
- isCurrentIdInInstance = true; \r
- gConsole.logStringMessage("[ximfmail - XimfThreadTree:create ] instance " + instanceId + " exists"); \r
+ isCurrentIdInInstance = true;\r
+ gConsole.logStringMessage("[ximfmail - XimfThreadTree:create ] instance " + instanceId + " exists");\r
break;\r
}\r
}\r
if(!isCurrentIdInInstance){\r
updateXimfHdrArrayByID(instanceId);\r
- addColumn(istancedom_treecol[k],instanceId); // add DOM element to tree\r
- addColumnHandler(instanceId); // load handler\r
- gConsole.logStringMessage("[ximfmail - XimfThreadTree:create ] instance " + instanceId + " created"); \r
+ // add DOM element to tree\r
+ addColumn(istancedom_treecol[k],instanceId);\r
+ // load handler\r
+ addColumnHandler(instanceId);\r
+ gConsole.logStringMessage("[ximfmail - XimfThreadTree:create ] instance " + instanceId + " created");\r
//updateColumnToHide(); ???\r
}\r
}catch(e){\r
- gConsole.logStringMessage("[ximfmail - XimfThreadTree:create ] compute error - id = " + k + " : " + e); \r
+ gConsole.logStringMessage("[ximfmail - XimfThreadTree:create ] compute error - id = " + k + " : " + e);\r
}\r
}\r
- \r
// used by Thunderbird to check for x-headers\r
- addCustomPreferences('mailnews.customDBHeaders'); \r
- \r
+ addCustomPreferences('mailnews.customDBHeaders');\r
// load ilk array for Ximf values of tree cells\r
updateXimfIlkCustomColumnArray(currentInstance);\r
- \r
- // trace ilk array \r
+ // trace ilk array\r
var string = "";\r
for(xh in _ximfIlilkCustomColumnArray){\r
for(ilk in _ximfIlilkCustomColumnArray[xh]){\r
string += "["+ xh +"]["+ ilk +"]["+ _ximfIlilkCustomColumnArray[xh][ilk] + "]\n";\r
}\r
}\r
- gConsole.logStringMessage("[ximfmail - XimfThreadTree:create ] array of ilk of ximf value" + string); \r
- return true; \r
- }catch(e){ \r
+ gConsole.logStringMessage("[ximfmail - XimfThreadTree:create ] array of ilk of ximf value" + string);\r
+ return true;\r
+ }catch(e){\r
gConsole.logStringMessage("[ximfmail - XimfThreadTree:create] " + e +"\nline : " + e.lineNumber + " : "+ e + "\nfile : "+ Error().fileName);\r
return false;\r
- } \r
+ }\r
},\r
// delete all custom columns of XIMF headers\r
- deleteXimfColummns : function(){ \r
+ deleteXimfColummns : function(){\r
$("treecol[ximfheadtree='1']").remove();\r
- $("splitter[ximfheadtree='1']").remove(); \r
- gConsole.logStringMessage("[ximfmail - XimfThreadTree:deleteXimfColummns ] delete all custom columns of XIMF headers"); \r
+ $("splitter[ximfheadtree='1']").remove();\r
+ gConsole.logStringMessage("[ximfmail - XimfThreadTree:deleteXimfColummns ] delete all custom columns of XIMF headers");\r
},\r
// attach customColumnHandler for all columns of XIMF headers\r
addCustomColumnHandler : function(){\r
var currentlistID = $("#threadCols treecol[ximfheadtree='1']");\r
- for(var i =0 ; i < currentlistID.length ; ++i){ \r
- addColumnHandler(); \r
+ for(var i =0 ; i < currentlistID.length ; ++i){\r
+ addColumnHandler();\r
}\r
- gConsole.logStringMessage("[ximfmail - XimfThreadTree:addCustomColumnHandler ] attach customColumnHandler for all columns of XIMF headers"); \r
+ gConsole.logStringMessage("[ximfmail - XimfThreadTree:addCustomColumnHandler ] attach customColumnHandler for all columns of XIMF headers");\r
},\r
// get ilk array for Ximf values of tree cells\r
- getIlkColumnArray : function(){ \r
+ getIlkColumnArray : function(){\r
return _ximfIlilkCustomColumnArray;\r
},\r
//obsolete?\r
saveColumnToHide : function(){\r
- var listID = $("#threadCols treecol[ximfheadtree='1']");//\r
+ var listID = $("#threadCols treecol[ximfheadtree='1']");\r
try{\r
- if(gCurrentIdentity){ \r
- prefList = ""\r
+ if(gCurrentIdentity){\r
+ prefList = "";\r
for(var i=0; i<listID.length; ++i){\r
- if(listID[i].getAttribute("hidden") == "true"){\r
- if(prefList != "") prefList +=",";\r
+ if(listID[i].getAttribute("hidden") === "true"){\r
+ if(prefList !== "") {\r
+ prefList +=",";\r
+ }\r
prefList += listID[i].id;\r
}\r
- } \r
+ }\r
gCurrentIdentity.setCharAttribute("ximfmail_context_DBHeaders",prefList);\r
}\r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - saveColumnToHide ] " + e +"\nline : " + Error().lineNumber + " : "+ e + "\nfile : "+ Error().fileName);\r
}\r
}\r
- } \r
+ };\r
}\r
return{\r
getInstance : function(){\r
}\r
return instantiated;\r
}\r
- }; \r
-})(); // one shot on XimfThreadTree
\ No newline at end of file
+ };\r
+})();
\ No newline at end of file
/* ***** BEGIN LICENSE BLOCK *****
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.
- *
*
- * Redistribution and use, in source and binary forms, with or without modification,
+ *
+ * Redistribution and use, in source and binary forms, with or without modification,
* are permitted provided that the following conditons are met :
*
- * 1. Redistributions of source code must retain the above copyright notice,
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached
* in the redistribution of the source code.
- * 3. Neither the names of the copyright holders nor the names of any contributors
- * may be used to endorse or promote products derived from this software without specific
+ * 3. Neither the names of the copyright holders nor the names of any contributors
+ * may be used to endorse or promote products derived from this software without specific
* prior written permission from EADS Defence and Security.
- *
+ *
* Alternatively, the contents of this file may be used under the terms of
* either of 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"),
* 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.
- *
+ *
* REMINDER :
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * EADS Defence and Security - 1 Boulevard Jean Moulin -
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)
+ *
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)
+ *
+ * Contributor(s):
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved
* ***** END LICENSE BLOCK ***** */
+/**
+ * ximfCatalog.js
+ * Check XIMF instances of Trustedbird profile and save informations of ximfmail-profile.xml files into RDF datasource memory.
+ * RDF datas can be read with XimfCatalog class.
+ */
var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
-
-/*
+/**
* XimfCatalog : instance to get RDF list of Ximfmail instances
* call example : var ximfCatalog = XimfCatalog().getIntance().publicmethod();
*/
var XimfCatalog = (function(){
var instantiated;
- var _rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
+ var _rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
var _dsCatalog = Components.classes["@mozilla.org/rdf/datasource;1?name=in-memory-datasource"].createInstance(Components.interfaces.nsIRDFDataSource);
var _rdfCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].getService(Components.interfaces.nsIRDFContainerUtils);
-
- /*
- *
+ /**
+ * Check and save for ximfmail instances definitions in Profile
*/
- function Create(force,aclLevel){
- try{
- if(force !== true){
- if(instantiated){
- gConsole.logStringMessage("[ximfmail - XimfCatalog:Create ] Catalog has already been instantiated");
- return;
- }
+ function Create(force, acl){
+ if (force !== true && instantiated) {
+ return;
+ }
+ // Report saved resources
+ if (_dsCatalog) {
+ var counter=0;
+ var it = _dsCatalog.GetAllResources();
+ while(it.hasMoreElements()){
+ counter++;
+ it.getNext();
}
-
- var extensionPath = getFilePathInProfile("extensions/");
- var extensionList = getExtensionsList();
- var sCompletePath;
- var dir = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
-
- // search for themes extensions
- for(i = 0; i<extensionList.length; i++){
+ gConsole.logStringMessage("[ximfmail - XimfCatalog:Create] " + counter + " existing resources in XimfmailCatalog" );
+ }
+ var localXimfProfileFile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ Components.utils.import("resource://gre/modules/AddonManager.jsm");
+ AddonManager.getAllAddons(function(aAddons) {
+ var nbAddons = aAddons.length;
+ gConsole.logStringMessage("[XimfCatalog:Create] Analyse all addons...");
+ for(var idx = 0 ; idx < nbAddons ; ++idx){
try{
- sCompletePath = getFilePathInProfile("extensions/" + extensionList[i].id + "/chrome/content/ximfmail-profile.xml");
- dir.initWithPath( sCompletePath );
- if(dir.exists()){
- // get xml profile
- var xmlDoc = GetXmlDocument(sCompletePath);
- //gXimfCatalog.registerXimfmailProfileNode(xmlDoc.documentElement,aclLevel);
- AppendInstance(xmlDoc.documentElement,aclLevel);
+ // check for ximfmail instance
+ localXimfProfileFile.initWithFile(getFileFromProfile("extensions/" + aAddons[idx].id + "/chrome/content/ximfmail-profile.xml"));
+ if (localXimfProfileFile.exists()) {
+ var xmlDoc = GetXmlDocument(localXimfProfileFile.path);
+ AppendInstance(xmlDoc.documentElement,acl);
}
- }catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog:Create ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ } catch(e) {
+ gConsole.logStringMessage("[XimfCatalog:Create] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
}
}
-
// Report saved resources
if(_dsCatalog){
var counter=0;
counter++;
it.getNext();
}
- gConsole.logStringMessage("[ximfmail - XimfCatalog:Create ] "+counter+" resources added to XimfmailCatalog" );
- }
- }catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog:Create ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
- }
+ gConsole.logStringMessage("[ximfmail - XimfCatalog:Create] "+counter+" resources added to XimfmailCatalog" );
+ }
+ });
}
- /*
- *
- */
function AppendInstance(domProfile,aclLevel){
- gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance ] Append to catalog instance (Level " + aclLevel + ")" + TRACE_DATE() );
- try{
+ gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance ] Append to catalog instance (Level " + aclLevel + ")" + TRACE_DATE() );
+ try{
// default title of smtp message
- var smtpXimfVersion = DEFAULT_XIMF_VERSION;
+ var smtpXimfVersion = ximfConst.DEFAULT_XIMF_VERSION;
var smtpVersion = "1.0";
var smtpInstance = "smtp";
var smtpInstanceLabel = "";
try{
- if(gPrefBranch){
+ if(gPrefBranch){
var val = gPrefBranch.getCharPref("ximfmail.smtp_msg.name");
- if(val){ smtpInstance = val; }
+ if (val) {
+ smtpInstance = val;
+ }
}
}catch(e){}
-
- // create Seq container
+ // create Seq container
var RDFCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].createInstance(Components.interfaces.nsIRDFContainerUtils);
-
// create RDF resources
- var seqNode = _rdfService.GetResource("http://www.ximfmail.com/catalog");
- var RDFC = null;
- try{
- RDFC = _rdfCUtils.MakeSeq(_dsCatalog, seqNode);
+ var seqNode = _rdfService.GetResource("http://www.ximfmail.com/catalog");
+ var RDFC = null;
+ try{
+ RDFC = _rdfCUtils.MakeSeq(_dsCatalog, seqNode);
}catch(e){
gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
}
-
- // add datas from xml profile to RDF file
+ // add datas from xml profile to RDF file
// Create theme List
- var themeTag = domProfile.getElementsByTagName("theme");
- var theme = "";
+ var themeTag = domProfile.getElementsByTagName("theme");
+ var theme = "";
var uriThemeDefinition = "http://www.ximfmail.com/catalog/" + themeTag[0].getAttribute("name");
if(themeTag.length > 0){
- //var adate = new Date();
- //theme = themeTag[0].getAttribute("name")+"-" + parseInt(adate.getTime())+ parseInt(Math.round(Math.random()*1000));
- theme = themeTag[0].getAttribute("name");
- var newURI = "http://www.ximfmail.com/catalog/" + theme;
-
- // get acl default level
- var defaultacl=-1;
+ theme = themeTag[0].getAttribute("name");
+ var newURI = "http://www.ximfmail.com/catalog/" + theme;
+ // get acl default level
+ var defaultacl=-1;
if(themeTag[0].hasAttribute("defaultacl")){
defaultacl = themeTag[0].getAttribute("defaultacl");
- gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance ] Default ACL level of profile " + newURI + " : " + defaultacl);
+ gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance ] Default ACL level of profile " + newURI + " : " + defaultacl);
}
-
- if( RDFC.IndexOf(_rdfService.GetResource(newURI)) == -1){
- gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] RDFC - AppendElement " + newURI);
+ if( RDFC.IndexOf(_rdfService.GetResource(newURI)) === -1){
+ gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] RDFC - AppendElement " + newURI);
RDFC.AppendElement(_rdfService.GetResource(newURI));
-
_dsCatalog.Assert(_rdfService.GetResource(newURI),
_rdfService.GetResource("http://www.ximfmail.com/RDF#name"),
- _rdfService.GetLiteral(theme), true);
-
+ _rdfService.GetLiteral(theme), true);
_dsCatalog.Assert(_rdfService.GetResource(newURI),
_rdfService.GetResource("http://www.ximfmail.com/RDF#refSeq"),
_rdfService.GetLiteral("http://www.ximfmail.com/catalog/instance_"+theme), true);
-
_dsCatalog.Assert(_rdfService.GetResource(newURI),
_rdfService.GetResource("http://www.ximfmail.com/RDF#defaultacl"),
- _rdfService.GetLiteral(defaultacl), true);
-
+ _rdfService.GetLiteral(defaultacl), true);
}else{
- gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] RDFC - ReplacedElement " + newURI);
-
+ gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] RDFC - ReplacedElement " + newURI);
_dsCatalog.Unassert(_rdfService.GetResource(newURI),
_rdfService.GetResource("http://www.ximfmail.com/RDF#name"),
_rdfService.GetLiteral( getTarget(newURI,"http://www.ximfmail.com/RDF#name")));
-
_dsCatalog.Assert(_rdfService.GetResource(newURI),
_rdfService.GetResource("http://www.ximfmail.com/RDF#name"),
_rdfService.GetLiteral(theme), true);
-
_dsCatalog.Unassert(_rdfService.GetResource(newURI),
_rdfService.GetResource("http://www.ximfmail.com/RDF#refSeq"),
_rdfService.GetLiteral( getTarget(newURI,"http://www.ximfmail.com/RDF#refSeq")));
-
_dsCatalog.Assert(_rdfService.GetResource(newURI),
_rdfService.GetResource("http://www.ximfmail.com/RDF#refSeq"),
_rdfService.GetLiteral("http://www.ximfmail.com/catalog/instance_"+theme), true);
-
_dsCatalog.Unassert(_rdfService.GetResource(newURI),
_rdfService.GetResource("http://www.ximfmail.com/RDF#defaultacl"),
_rdfService.GetLiteral( getTarget(newURI,"http://www.ximfmail.com/RDF#defaultacl")));
-
_dsCatalog.Assert(_rdfService.GetResource(newURI),
_rdfService.GetResource("http://www.ximfmail.com/RDF#defaultacl"),
_rdfService.GetLiteral(defaultacl), true);
}
-
-
- }
-
- // Create instance List
+ }
+ // Create instance List
var RDFCI = RDFCUtils.MakeSeq(_dsCatalog, _rdfService.GetResource("http://www.ximfmail.com/catalog/instance_"+theme));
-
- // create definitions entries
+ // create definitions entries
var instanceTag = themeTag[0].getElementsByTagName("instance");
- //alert(instanceTag.length + " instances in profile xml " + theme)
-
- var sValue="";
- var bHasSmtpInstance=false;
+ var sValue="";
+ var bHasSmtpInstance=false;
for(var i = 0; i < instanceTag.length; i++){
try{
// default instance message, continue
- if(instanceTag[i].getAttribute("id") == "smtp"){
- bHasSmtpInstance = true;
+ if(instanceTag[i].getAttribute("id") === "smtp"){
+ bHasSmtpInstance = true;
smtpInstance = instanceTag[i].getAttribute("name");
- smtpVersion = instanceTag[i].getAttribute("version");
- smtpXimfVersion = instanceTag[i].getAttribute("ximfVersion");
+ smtpVersion = instanceTag[i].getAttribute("version");
+ smtpXimfVersion = instanceTag[i].getAttribute("ximfVersion");
try{
smtpInstanceLabel = instanceTag[i].getAttribute("label");
}catch(ex){}
- if(!smtpInstanceLabel) smtpInstanceLabel = smtpInstance;
- continue;
+ if (!smtpInstanceLabel) {
+ smtpInstanceLabel = smtpInstance;
+ }
+ continue;
}
}catch(e){}
// append resource element to sequence
var newURI = "http://www.ximfmail.com/catalog/instance_"+theme +"/"+instanceTag[i].getAttribute("name");
var newResource = _rdfService.GetResource(newURI);
- var isNewItem = false;
- if( RDFCI.IndexOf(newResource) == -1){
- RDFCI.AppendElement(newResource);
+ var isNewItem = false;
+ if( RDFCI.IndexOf(newResource) === -1){
+ RDFCI.AppendElement(newResource);
isNewItem = true;
}
-
-
// append ximfVersion of instance
if(isNewItem){
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#ximfVersion"),
_rdfService.GetLiteral(instanceTag[i].getAttribute("ximfVersion")), true);
- }else{
- _dsCatalog.Unassert(newResource,
+ }else{
+ _dsCatalog.Unassert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#ximfVersion"),
_rdfService.GetLiteral(getTarget(newURI,"http://www.ximfmail.com/RDF#ximfVersion")));
-
+
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#ximfVersion"),
_rdfService.GetLiteral(instanceTag[i].getAttribute("ximfVersion")), true);
-
+
}
-
// append name of instance
if(isNewItem){
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#instance"),
- _rdfService.GetLiteral(instanceTag[i].getAttribute("name")), true);
- }else{
- /*
- _dsCatalog.Change(newResource,
- _rdfService.GetResource("http://www.ximfmail.com/RDF#instance"),
- _rdfService.GetLiteral(getTarget(newURI,"http://www.ximfmail.com/RDF#instance")),
- _rdfService.GetLiteral(instanceTag[i].getAttribute("name")));
- */
-
- _dsCatalog.Unassert(newResource,
+ _rdfService.GetLiteral(instanceTag[i].getAttribute("name")), true);
+ }else{
+ _dsCatalog.Unassert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#instance"),
_rdfService.GetLiteral(getTarget(newURI,"http://www.ximfmail.com/RDF#instance")));
-
+
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#instance"),
- _rdfService.GetLiteral(instanceTag[i].getAttribute("name")), true);
+ _rdfService.GetLiteral(instanceTag[i].getAttribute("name")), true);
}
-
// append label of instance
try{
var instLabel = instanceTag[i].getAttribute("label");
- if(!instLabel) instLabel = instanceTag[i].getAttribute("name");
- //gConsole.logStringMessage("instLabel" + instLabel);
+ if (!instLabel) {
+ instLabel = instanceTag[i].getAttribute("name");
+ }
if(isNewItem){
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#instanceLabel"),
_rdfService.GetLiteral(instLabel), true);
- }else{
- _dsCatalog.Unassert(newResource,
+ }else{
+ _dsCatalog.Unassert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#instanceLabel"),
_rdfService.GetLiteral(getTarget(newURI,"http://www.ximfmail.com/RDF#instanceLabel")));
-
+
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#instanceLabel"),
_rdfService.GetLiteral(instLabel), true);
}
}catch(ex){}
-
// append version of instance
if(isNewItem){
_dsCatalog.Assert(newResource,
_dsCatalog.Unassert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#version"),
_rdfService.GetLiteral(getTarget(newURI,"http://www.ximfmail.com/RDF#version")));
-
+
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#version"),
_rdfService.GetLiteral(instanceTag[i].getAttribute("version")), true);
-
+
}
// append id of instance
- try{
- if(isNewItem){
+ try{
+ if(isNewItem){
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#id"),
_rdfService.GetLiteral(instanceTag[i].getAttribute("id")), true);
}else{
- _dsCatalog.Unassert(newResource,
+ _dsCatalog.Unassert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#id"),
_rdfService.GetLiteral(getTarget(newURI,"http://www.ximfmail.com/RDF#id")));
_dsCatalog.Assert(newResource,
_rdfService.GetLiteral(instanceTag[i].getAttribute("id")), true);
}
}catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
}
-
// schema path value
- try{
+ try{
var schemaElt = instanceTag[i].getElementsByTagName("schema");
sValue="";
if(schemaElt){
- sValue = schemaElt[0].textContent;
+ sValue = schemaElt[0].textContent;
}
if(isNewItem){
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#pathSchema"),
_rdfService.GetLiteral(instanceTag[i].getAttribute("directory")+sValue), true);
- }else{
+ }else{
_dsCatalog.Unassert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#pathSchema"),
- _rdfService.GetLiteral(getTarget(newURI,"http://www.ximfmail.com/RDF#pathSchema")));
+ _rdfService.GetLiteral(getTarget(newURI,"http://www.ximfmail.com/RDF#pathSchema")));
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#pathSchema"),
_rdfService.GetLiteral(instanceTag[i].getAttribute("directory")+sValue), true);
}
}catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber);
- }
-
+ gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber);
+ }
try{
// ihm path value
var ihmElt = instanceTag[i].getElementsByTagName("ihm");
sValue="";
if(ihmElt){
- sValue = ihmElt[0].textContent;
+ sValue = ihmElt[0].textContent;
}
if(isNewItem){
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#pathIhm"),
_rdfService.GetLiteral(instanceTag[i].getAttribute("directory")+sValue), true);
}
-
- }catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber);
+ }catch(e){
+ gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber);
}
-
try{
// rules path value
var rulesDico = instanceTag[i].getElementsByTagName("rule");
sValue="";
if(rulesDico){
- sValue = rulesDico[0].textContent;
- }
+ sValue = rulesDico[0].textContent;
+ }
if(isNewItem){
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#pathRules"),
_rdfService.GetLiteral(instanceTag[i].getAttribute("directory")+sValue), true);
}
}catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber);
- }
-
+ gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber);
+ }
try{
// dictionary path value
var ihmDico = instanceTag[i].getElementsByTagName("dictionary");
sValue="";
if(ihmDico){
- sValue = ihmDico[0].textContent;
- }
+ sValue = ihmDico[0].textContent;
+ }
if(isNewItem){
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#pathDictionary"),
_rdfService.GetLiteral(instanceTag[i].getAttribute("directory")+sValue), true);
}
}catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber);
+ gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber);
}
-
if(isNewItem){
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#theme"),
_rdfService.GetLiteral(theme), true);
- }else{
+ }else{
_dsCatalog.Unassert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#theme"),
_rdfService.GetLiteral(getTarget(newURI,"http://www.ximfmail.com/RDF#theme")));
_rdfService.GetResource("http://www.ximfmail.com/RDF#theme"),
_rdfService.GetLiteral(theme), true);
}
-
try{
// aclLevel of instance to hide/unhide it on account
- sValue="true";
+ sValue="true";
var iAclLevel = -1;
var acltag = instanceTag[i].getElementsByTagName("acl");
- if(acltag.length>0)iAclLevel = acltag[0].textContent;
- if(aclLevel){
- if(parseInt(iAclLevel, 10) > parseInt(aclLevel, 10)) sValue = "false";
+ if (acltag.length>0) {
+ iAclLevel = acltag[0].textContent;
+ }
+ if(aclLevel){
+ if (parseInt(iAclLevel, 10) > parseInt(aclLevel, 10)) {
+ sValue = "false";
+ }
}else{
- if(parseInt(iAclLevel, 10) > parseInt(getTarget(uriThemeDefinition,"http://www.ximfmail.com/RDF#defaultacl"), 10))sValue = "false";
+ if (parseInt(iAclLevel, 10) > parseInt(getTarget(uriThemeDefinition,"http://www.ximfmail.com/RDF#defaultacl"), 10)) {
+ sValue = "false";
+ }
}
-
if(isNewItem){
_dsCatalog.Assert(newResource,
_rdfService.GetResource("http://www.ximfmail.com/RDF#active"),
_rdfService.GetResource("http://www.ximfmail.com/RDF#active"),
_rdfService.GetLiteral(sValue), true);
}
- }catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber);
- }
+ }catch(e){
+ gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber);
+ }
}
// insert smtp entry
- if(bHasSmtpInstance){
+ if(bHasSmtpInstance){
var smtpURI = "http://www.ximfmail.com/catalog/instance_"+theme +"/smtp";
- var smtpResource = _rdfService.GetResource(smtpURI);
- if( RDFCI.IndexOf(smtpResource) == -1){
+ var smtpResource = _rdfService.GetResource(smtpURI);
+ if( RDFCI.IndexOf(smtpResource) === -1){
RDFCI.AppendElement(smtpResource);
_dsCatalog.Assert(smtpResource,_rdfService.GetResource("http://www.ximfmail.com/RDF#ximfVersion"), _rdfService.GetLiteral(smtpXimfVersion), true);
_dsCatalog.Assert(smtpResource,_rdfService.GetResource("http://www.ximfmail.com/RDF#instance"),_rdfService.GetLiteral(smtpInstance), true);
_dsCatalog.Assert(smtpResource,_rdfService.GetResource("http://www.ximfmail.com/RDF#pathIhm"),_rdfService.GetLiteral(smtpInstance), true);
_dsCatalog.Assert(smtpResource,_rdfService.GetResource("http://www.ximfmail.com/RDF#pathRules"),_rdfService.GetLiteral(smtpInstance), true);
_dsCatalog.Assert(smtpResource,_rdfService.GetResource("http://www.ximfmail.com/RDF#pathDictionary"),_rdfService.GetLiteral(smtpInstance), true);
- _dsCatalog.Assert(smtpResource,_rdfService.GetResource("http://www.ximfmail.com/RDF#theme"),_rdfService.GetLiteral(smtpInstance), true);
+ _dsCatalog.Assert(smtpResource,_rdfService.GetResource("http://www.ximfmail.com/RDF#theme"),_rdfService.GetLiteral(smtpInstance), true);
_dsCatalog.Assert(smtpResource, _rdfService.GetResource("http://www.ximfmail.com/RDF#active"), _rdfService.GetLiteral("true"), true);
// append label of instance
try{
}catch(ex){}
}
}
- // save datas to file DBG
- //_dsCatalog.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);
- //var rdfXimfCatalogPath = getFilePathInProfile("extensions/{A627B834-BD9F-4b3f-9AF5-347B5A570402}/chrome/content/theme/ximfCatalogBck.rdf");
- //_dsCatalog.FlushTo("file:///" + rdfXimfCatalogPath);
gConsole.logStringMessage("[ximfmail - XimfCatalog:AppendInstance] executed "+TRACE_DATE());
- }catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog.registerXimfmailProfileNode ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ }catch(e){
+ gConsole.logStringMessage("[ximfmail - XimfCatalog.registerXimfmailProfileNode ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
}
- }
-
+ };
/*
* read informations from catalog
*/
try{
var resource = _rdfService.GetResource(instance);
var targets = _dsCatalog.ArcLabelsOut(resource);
- while (targets.hasMoreElements()){
+ while (targets.hasMoreElements()){
var newpredicate = targets.getNext();
if (newpredicate instanceof Components.interfaces.nsIRDFResource){
- var target = _dsCatalog.GetTarget(resource, newpredicate, true);
- if (target instanceof Components.interfaces.nsIRDFLiteral){
- //alert("getTarget\n"+newpredicate.Value + " : \n\r" + target.Value);
- if(newpredicate.Value == predicate)
- return target.Value;
- }
+ var target = _dsCatalog.GetTarget(resource, newpredicate, true);
+ if (target instanceof Components.interfaces.nsIRDFLiteral && newpredicate.Value === predicate) {
+ return target.Value;
}
+ }
}
- }catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);
+ }catch(e){
+ gConsole.logStringMessage("[ximfmail - XimfCatalog ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);
}
return null;
- }
-
+ };
function init(){
- //
- Create();
-
// singleton pattern here
return{
+ addProfile : function (xmlProfile){
+ AppendInstance(xmlProfile,null);
+ },
publicProperty : "test",
- /*
- * get datasource object
- */
+ //get datasource object
getDSCatalog : function(){
return _dsCatalog;
},
- /*
- *
- */
rebuild : function(aclLevel){
Create(true,aclLevel);
- gConsole.logStringMessage("[ximfmail - XimfCatalog.rebuild ] rebuild operation executed");
- },
- /*
- * create catalog with profile xml informations
- */
+ gConsole.logStringMessage("[ximfmail - XimfCatalog.rebuild ] rebuild operation executed");
+ },
+ //create catalog with profile xml informations
registerXimfmailProfileNode : function(domProfile,aclLevel){
- AppendInstance(domProfile,aclLevel);
- gConsole.logStringMessage("[ximfmail - XimfCatalog.registerXimfmailProfileNode ] registerXimfmailProfileNode operation executed");
+ AppendInstance(domProfile,aclLevel);
+ gConsole.logStringMessage("[ximfmail - XimfCatalog.registerXimfmailProfileNode ] registerXimfmailProfileNode operation executed");
},
RemoveSeqCatalog : function(seqNode){
try{
// create RDF resources
-
- //var seqNode = _rdfService.GetResource("http://www.ximfmail.com/catalog");
- var rSeqCatalog = null;
- try{
- rSeqCatalog = _rdfCUtils.MakeSeq(_dsCatalog, seqNode);
+ var rSeqCatalog = null;
+ try{
+ rSeqCatalog = _rdfCUtils.MakeSeq(_dsCatalog, seqNode);
}catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog.registerXimfmailProfileNode ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
- }
+ gConsole.logStringMessage("[ximfmail - XimfCatalog.registerXimfmailProfileNode ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
+ }
if(rSeqCatalog){
- /*
- var numEntri = rSeqCatalog.GetCount();
- for (var indexCur = numEntri; indexCur >0; indexCur--){
- rSeqCatalog.RemoveElementAt(indexCur,true);
- alert("remove " + rSeqCatalog)
- }
- */
-
- var tseq = rSeqCatalog.GetElements();
- alert(seqNode.ValueUTF8+"\nnb elements to remove = " + rSeqCatalog.GetCount())
+ var tseq = rSeqCatalog.GetElements();
var uriResource = "";
while (tseq.hasMoreElements()){
var element = tseq.getNext();
if (element instanceof Components.interfaces.nsIRDFResource){
uriResource = element.ValueUTF8;
- alert("remove " + uriResource)
var resource = _rdfService.GetResource(uriResource);
rSeqCatalog.RemoveElementAt(rSeqCatalog.IndexOf(resource),true);
- }else{
- alert("remove " + uriResource)
- }
+ }
}
- alert("nb elements = " + rSeqCatalog.GetCount())
- }
- }catch(e){
- alert(e)
- gConsole.logStringMessage("[ximfmail - XimfCatalog - RemoveSeqCatalog ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
+ }
+ }catch(e){
+ gConsole.logStringMessage("[ximfmail - XimfCatalog - RemoveSeqCatalog ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
}
},
getNameInstance : function(instance){
},
getInstanceUri : function(ximfDefUri,ximfName,ximfVersion){
try{
- gConsole.logStringMessage("[ximfmail - XimfCatalog:getInstanceUri ] ximfDefUri = "+ximfDefUri+" - ximfName = "+ximfName+" - ximfVersion = " + ximfVersion );
- /// get container of instance resources of current definition
+ gConsole.logStringMessage("[ximfmail - XimfCatalog:getInstanceUri ] ximfDefUri = "+ximfDefUri+" - ximfName = "+ximfName+" - ximfVersion = " + ximfVersion );
+ // get container of instance resources of current definition
var RDFCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].createInstance(Components.interfaces.nsIRDFContainerUtils);
- //alert("getInstanceUri - ximfDefUri = " + ximfDefUri)
- var rs_seqInstance = _rdfService.GetResource(ximfDefUri);
+ var rs_seqInstance = _rdfService.GetResource(ximfDefUri);
var containerInstances = RDFCUtils.MakeSeq(_dsCatalog, rs_seqInstance);
- var children = containerInstances.GetElements();
+ var children = containerInstances.GetElements();
while (children.hasMoreElements()){
- // search uri instance with ximfVersion and ximfName
+ // search uri instance with ximfVersion and ximfName
var child = children.getNext();
- if (child instanceof Components.interfaces.nsIRDFResource){
+ if (child instanceof Components.interfaces.nsIRDFResource){
var instance_resource = child.Value;
- //alert("instance_resource = "+instance_resource);
- //var thisName = this.getNameInstance(instance_resource);
- var thisName = getTarget(instance_resource,"http://www.ximfmail.com/RDF#instance")
- //var thisVersion = this.getVersionInstance(instance_resource);
+ var thisName = getTarget(instance_resource,"http://www.ximfmail.com/RDF#instance");
var thisVersion = getTarget(instance_resource,"http://www.ximfmail.com/RDF#ximfVersion");
- //alert("<"+thisName+"><"+thisVersion+">\n<"+ximfName+"><"+ximfVersion+">")
if(thisName && thisVersion){
thisName = String_trim(thisName).toLowerCase();
- if(thisName == String_trim(ximfName).toLowerCase()){
- /*
- if(thisVersion == ximfVersion){
- //alert("instance path found >>"+instance_resource);
- return instance_resource;
- }*/
+ if(thisName === String_trim(ximfName).toLowerCase()){
return instance_resource;
- }
+ }
}
- }
+ }
/*
DEBUG loop : list of predicats
var resource = _rdfService.GetResource(instance_resource);
var targets = _dsCatalog.ArcLabelsOut(resource);
- while (targets.hasMoreElements()){
+ while (targets.hasMoreElements()){
var newpredicate = targets.getNext();
if (newpredicate instanceof Components.interfaces.nsIRDFResource){
alert("Resource is: " + newpredicate.Value);
}
}*/
}
-
- // search for instance in others definitions of catalog
+
+ // search for instance in others definitions of catalog
var completeCatalog = _rdfService.GetResource("http://www.ximfmail.com/catalog");
var containerDefinitions = RDFCUtils.MakeSeq(_dsCatalog, completeCatalog);
- var children = containerDefinitions.GetElements();
+ var children = containerDefinitions.GetElements();
while (children.hasMoreElements()){
try{
- // search uri instance with ximfVersion and ximfName
+ // search uri instance with ximfVersion and ximfName
var child = children.getNext();
- if (child instanceof Components.interfaces.nsIRDFResource){
+ if (child instanceof Components.interfaces.nsIRDFResource){
var def_resource = child.ValueUTF8;
- // get uri of definition container
- var seqUriInstance = getTarget(def_resource,"http://www.ximfmail.com/RDF#refSeq");
- if(seqUriInstance != ximfDefUri){
- var rs_seqInstance2 = _rdfService.GetResource(seqUriInstance);
+ // get uri of definition container
+ var seqUriInstance = getTarget(def_resource,"http://www.ximfmail.com/RDF#refSeq");
+ if(seqUriInstance !== ximfDefUri){
+ var rs_seqInstance2 = _rdfService.GetResource(seqUriInstance);
var containerInstances2 = RDFCUtils.MakeSeq(_dsCatalog, rs_seqInstance2);
- var children2 = containerInstances2.GetElements();
- //alert("inspect uri in :\n" + def_resource+"\nref:\n"+ximfDefUri+"\n elments count = " + containerInstances2.GetCount())
+ var children2 = containerInstances2.GetElements();
while (children2.hasMoreElements()){
- // search uri instance with ximfVersion and ximfName
+ // search uri instance with ximfVersion and ximfName
var child2 = children2.getNext();
- if (child2 instanceof Components.interfaces.nsIRDFResource){
- var instance_resource2 = child2.ValueUTF8;
- //var thisName2 = this.getNameInstance(instance_resource2);
- var thisName2 = getTarget(instance_resource2,"http://www.ximfmail.com/RDF#instance")
-
+ if (child2 instanceof Components.interfaces.nsIRDFResource){
+ var instance_resource2 = child2.ValueUTF8;
+ var thisName2 = getTarget(instance_resource2,"http://www.ximfmail.com/RDF#instance");
if(thisName2){
thisName2 = String_trim(thisName2).toLowerCase();
- if(thisName2 == String_trim(ximfName).toLowerCase()){
- //alert("instance_resource matched = "+instance_resource2);
+ if(thisName2 === String_trim(ximfName).toLowerCase()){
return instance_resource2;
- }
+ }
}
}
- }
+ }
}
- }
+ }
}catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog - getInstanceUri] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
- }
- }
+ gConsole.logStringMessage("[ximfmail - XimfCatalog - getInstanceUri] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
+ }
+ }
}catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog - getInstanceUri] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
+ gConsole.logStringMessage("[ximfmail - XimfCatalog - getInstanceUri] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
}
return null;
},
// array of instances of one definition
getInstanceList : function(){
var arrayInstancesUri = [];
- try{
+ try{
// search for instance in others definitions of catalog
var RDFCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].createInstance(Components.interfaces.nsIRDFContainerUtils);
var completeCatalog = _rdfService.GetResource("http://www.ximfmail.com/catalog");
var containerDefinitions = RDFCUtils.MakeSeq(_dsCatalog, completeCatalog);
- var children = containerDefinitions.GetElements();
+ var children = containerDefinitions.GetElements();
while (children.hasMoreElements()){
try{
- // search uri instance with ximfVersion and ximfName
+ // search uri instance with ximfVersion and ximfName
var child = children.getNext();
- if (child instanceof Components.interfaces.nsIRDFResource){
+ if (child instanceof Components.interfaces.nsIRDFResource){
var def_resource = child.ValueUTF8;
- // get uri of definition container
- var seqUriInstance = getTarget(def_resource,"http://www.ximfmail.com/RDF#refSeq");
- //arrayInstancesUri.push(seqUriInstance);
-
- var rs_seqInstance2 = _rdfService.GetResource(seqUriInstance);
+ // get uri of definition container
+ var seqUriInstance = getTarget(def_resource,"http://www.ximfmail.com/RDF#refSeq");
+ var rs_seqInstance2 = _rdfService.GetResource(seqUriInstance);
var containerInstances2 = RDFCUtils.MakeSeq(_dsCatalog, rs_seqInstance2);
- var children2 = containerInstances2.GetElements();
- //alert("inspect uri in :\n" + def_resource+"\nref:\n"+ximfDefUri+"\n elments count = " + containerInstances2.GetCount())
+ var children2 = containerInstances2.GetElements();
while (children2.hasMoreElements()){
- // search uri instance with ximfVersion and ximfName
+ // search uri instance with ximfVersion and ximfName
var child2 = children2.getNext();
if (child2 instanceof Components.interfaces.nsIRDFResource){
- var instance_resource2 = child2.ValueUTF8;
- arrayInstancesUri.push(instance_resource2);
- }
+ var instance_resource2 = child2.ValueUTF8;
+ arrayInstancesUri.push(instance_resource2);
+ }
}
-
- }
+
+ }
}catch(e){
- gConsole.logStringMessage("[ximfmail - XimfCatalog - getInstanceUri] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
- }
+ gConsole.logStringMessage("[ximfmail - XimfCatalog - getInstanceUri] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ }
}
}catch(e){
- // alert("[XimfCatalog]error instance loading...." + e);
- gConsole.logStringMessage("[ximfmail - XimfCatalog ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ gConsole.logStringMessage("[ximfmail - XimfCatalog ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
}
-
return arrayInstancesUri;
- }
- }; // end init() singleton
- }
- return{
- getInstance : function(){
- if(!instantiated){
+ }
+ // end init() singleton
+ };
+ };
+ return { getInstance : function() {
+ if (!instantiated) {
+ gConsole.logStringMessage("[ximfmail - XimfCatalog ] init catalog...");
instantiated = init();
}
return instantiated;
}
+ };
+})();
+/**
+ * Inspect local ximf instances extensions and create new catalog
+ */
+var XimfCatalogFactory = (function() {
+ function createCatalog(callback) {
+ var localXimfProfileFile = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ Components.utils.import("resource://gre/modules/AddonManager.jsm");
+ var ximfcatalog = XimfCatalog.getInstance();
+ AddonManager.getAllAddons( function(aAddons) {
+ var nbAddons = aAddons.length;
+ gConsole.logStringMessage("[XimfCatalog:Create] Analyse all addons...");
+ for(var idx = 0 ; idx < nbAddons ; ++idx){
+ try{
+ // check for ximfmail instance
+ localXimfProfileFile.initWithFile(getFileFromProfile("extensions/" + aAddons[idx].id + "/chrome/content/ximfmail-profile.xml"));
+ if (localXimfProfileFile.exists()) {
+ var xmlDoc = GetXmlDocument(localXimfProfileFile.path);
+ ximfcatalog.addProfile(xmlDoc.documentElement);
+ }
+ } catch(e) {
+ gConsole.logStringMessage("[XimfCatalog:Create] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ }
+ }
+ if (callback) {
+ callback(ximfcatalog);
+ }
+ });
}
-
-})();
\ No newline at end of file
+ return {
+ getIntance : function(callback) {
+ createCatalog(callback);
+ }
+ };
+})();
+// load catalog by calling fatory
+XimfCatalogFactory.getIntance();
\ No newline at end of file
/* ***** BEGIN LICENSE BLOCK *****\r
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
*\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
* are permitted provided that the following conditons are met :\r
*\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
* in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
* prior written permission from EADS Defence and Security.\r
- * \r
+ *\r
* Alternatively, the contents of this file may be used under the terms of\r
* either of the GNU General Public License Version 2 or later (the "GPL"),\r
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
* and other provisions required by the GPL or the LGPL. If you do not delete\r
* the provisions above, a recipient may use your version of this file under\r
* the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
+ *\r
* REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ *\r
+ * Contributor(s):\r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
* ***** END LICENSE BLOCK ***** */\r
- \r
+\r
/*\r
- * \r
+ *\r
*/\r
-function XRDFDataSource(){ \r
+function XRDFDataSource(){\r
this._dataSource;\r
- this._refDataSource; \r
+ this._refDataSource;\r
}\r
-\r
-\r
/*\r
* create DataSource RDF with xml file of values\r
- * xmlDataPath of xml format recognized : \r
+ * xmlDataPath of xml format recognized :\r
<ximf:base name="MCA_List">\r
<ximf:header>\r
<ximf:title>Saaa</ximf:title>\r
</ximf:base>\r
*/\r
function CreateRdfDatasSource(xmlDataPath){\r
- try{ \r
- \r
- if(!xmlDataPath) return;\r
- \r
+ try{\r
+ if (!xmlDataPath) {\r
+ return;\r
+ }\r
var domProfile = null;\r
- \r
var xDataSource = new XRDFDataSource();\r
var xmlDoc = GetXmlDocument(xmlDataPath);\r
- if(xmlDoc){ \r
- domProfile = xmlDoc.documentElement; \r
+ if(xmlDoc){\r
+ domProfile = xmlDoc.documentElement;\r
}else{\r
gConsole.logStringMessage("[ximfmail - ximfTreeDialog ] \n " + Error.description + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
return;\r
}\r
- \r
// is valid xml document?\r
- var baseTag = domProfile.getElementsByTagName("ximf:base"); \r
- if(baseTag.length <= 0) return; \r
- \r
- // init RDF XPCOM Services \r
- var _rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService); \r
+ var baseTag = domProfile.getElementsByTagName("ximf:base");\r
+ if (baseTag.length <= 0) {\r
+ return;\r
+ }\r
+ // init RDF XPCOM Services\r
+ var _rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);\r
var _dsCatalog = Components.classes["@mozilla.org/rdf/datasource;1?name=in-memory-datasource"].createInstance(Components.interfaces.nsIRDFDataSource);\r
var _rdfCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].getService(Components.interfaces.nsIRDFContainerUtils);\r
- \r
- // parse XML file and create RDF resources \r
- var tname = baseTag[0].getAttribute("name"); \r
- var baseURI = "http://www.ximfmail.com/catalog/" + tname; \r
- var datasUri = baseURI + "/datas"; \r
- \r
+ // parse XML file and create RDF resources\r
+ var tname = baseTag[0].getAttribute("name");\r
+ var baseURI = "http://www.ximfmail.com/catalog/" + tname;\r
+ var datasUri = baseURI + "/datas";\r
var seqNode = _rdfService.GetResource(datasUri);\r
- var RDFC_data = null; \r
- try{ \r
+ var RDFC_data = null;\r
+ try {\r
RDFC_data = _rdfCUtils.MakeSeq(_dsCatalog, seqNode);\r
- \r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - CreateRdfDatasSource ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
- } \r
- \r
- var treeTag = baseTag[0].getElementsByTagName("ximf:tree"); \r
+ }\r
+ var treeTag = baseTag[0].getElementsByTagName("ximf:tree");\r
var instanceTag = treeTag[0].getElementsByTagName("ximf:description");\r
for(var i = 0; i < instanceTag.length; ++i){\r
// append resource element to sequence\r
- var newURI = datasUri + "/data" + i; \r
- //_rdfContainer.AppendElement(_rdfService.GetResource(newURI));\r
+ var newURI = datasUri + "/data" + i;\r
RDFC_data.AppendElement(_rdfService.GetResource(newURI));\r
- \r
var instanceTagData = instanceTag[i].getElementsByTagName("ximf:data");\r
for(var j = 0; j < instanceTagData.length; ++j){\r
// append description element\r
_dsCatalog.Assert(_rdfService.GetResource(newURI),\r
_rdfService.GetResource("http://www.ximfmail.com/RDF#column"+j),\r
- _rdfService.GetLiteral(instanceTagData[j].textContent), true); \r
+ _rdfService.GetLiteral(instanceTagData[j].textContent), true);\r
}\r
}\r
//create objet result\r
- //alert("CreateRdfDatasSource new ref : "+datasUri);\r
xDataSource._dataSource = _dsCatalog;\r
xDataSource._refDataSource = datasUri;\r
- return xDataSource; \r
- }catch(e){ \r
+ return xDataSource;\r
+ }catch(e){\r
gConsole.logStringMessage("[ximfmail - CreateRdfDatasSource ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
- } \r
+ }\r
}\r
-\r
/*\r
* create DataSource RDF with array of values\r
* arrayDatas = [[col0][col1][coln], [col0][col1][coln], [col0][col1][coln], ...]\r
* nameSvc = title of box selection\r
*/\r
function CreateRdfDatasSource_array(arrayDatas, strTitle){\r
- try{ \r
- // is valid array document? \r
- if(arrayDatas.length <= 0){ \r
+ try{\r
+ // is valid array document?\r
+ if(arrayDatas.length <= 0){\r
return;\r
- } \r
- \r
- // init RDF XPCOM Services \r
+ }\r
+ // init RDF XPCOM Services\r
var xDataSource = new XRDFDataSource();\r
- var _rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService); \r
+ var _rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);\r
var _dsCatalog = Components.classes["@mozilla.org/rdf/datasource;1?name=in-memory-datasource"].createInstance(Components.interfaces.nsIRDFDataSource);\r
var _rdfCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].getService(Components.interfaces.nsIRDFContainerUtils);\r
- \r
- // parse XML file and create RDF resources \r
- var baseURI = "http://www.ximfmail.com/catalog/" + strTitle; \r
- var datasUri = baseURI + "/datas"; \r
- \r
+ // parse XML file and create RDF resources\r
+ var baseURI = "http://www.ximfmail.com/catalog/" + strTitle;\r
+ var datasUri = baseURI + "/datas";\r
var seqNode = _rdfService.GetResource(datasUri);\r
- var RDFC_data = null; \r
- try{ \r
+ var RDFC_data = null;\r
+ try{\r
RDFC_data = _rdfCUtils.MakeSeq(_dsCatalog, seqNode);\r
- \r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - XimfTreeData.registerXimfmailProfileNode ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
- } \r
- \r
+ }\r
for(var i = 0; i < arrayDatas.length; ++i){\r
// append resource element to sequence\r
- var newURI = datasUri + "/data" + i; \r
+ var newURI = datasUri + "/data" + i;\r
RDFC_data.AppendElement(_rdfService.GetResource(newURI));\r
- \r
+\r
var arrayCols = arrayDatas[i];\r
for(var j = 0; j < arrayCols.length; ++j){\r
var valData = arrayCols[j];\r
- if (valData == "")\r
+ if (valData === "") {\r
valData = " ";\r
+ }\r
// append description element\r
- _dsCatalog.Assert(_rdfService.GetResource(newURI), \r
- _rdfService.GetResource("http://www.ximfmail.com/RDF#column"+j), \r
- _rdfService.GetLiteral(valData), \r
+ _dsCatalog.Assert(_rdfService.GetResource(newURI),\r
+ _rdfService.GetResource("http://www.ximfmail.com/RDF#column"+j),\r
+ _rdfService.GetLiteral(valData),\r
true\r
- ); \r
+ );\r
}\r
}\r
- \r
//create objet result\r
- //alert("CreateRdfDatasSource new ref : "+datasUri);\r
xDataSource._dataSource = _dsCatalog;\r
xDataSource._refDataSource = datasUri;\r
- return xDataSource; \r
- }catch(e){ \r
+ return xDataSource;\r
+ }catch(e){\r
gConsole.logStringMessage("[ximfmail - XimfTreeData.CreateRdfDatasSource ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
- } \r
-}\r
+ }\r
+}
\ No newline at end of file
-var XIMF_RULE_TARGET_NAME_MANDATORY_HEADERS = "MandatoryHeaders"\r
+/* ***** BEGIN LICENSE BLOCK *****\r
+ * Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
+ * ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
+ *\r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditons are met :\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
+ * in the redistribution of the source code.\r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
+ * prior written permission from EADS Defence and Security.\r
+ *\r
+ * Alternatively, the contents of this file may be used under the terms of\r
+ * either of the GNU General Public License Version 2 or later (the "GPL"),\r
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
+ * in which case the provisions of the GPL or the LGPL are applicable instead\r
+ * of those above. If you wish to allow use of your version of this file only\r
+ * under the terms of either the GPL or the LGPL, and not to allow others to\r
+ * use your version of this file under the terms of the MPL, indicate your\r
+ * decision by deleting the provisions above and replace them with the notice\r
+ * and other provisions required by the GPL or the LGPL. If you do not delete\r
+ * the provisions above, a recipient may use your version of this file under\r
+ * the terms of any one of the MPL, the GPL or the LGPL.\r
+ *\r
+ * REMINDER :\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ *\r
+ * Contributor(s):\r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
+ * ***** END LICENSE BLOCK ***** */\r
+var XIMF_RULE_TARGET_NAME_MANDATORY_HEADERS = "MandatoryHeaders";\r
var gSpecialMandatoryHeaders = [];\r
-\r
//\r
function SpecialMandatoryHeaders(nameHeader,refHeader){\r
- //alert("SpecialMandatoryHeaders refHeader = " + refHeader + "\nnameHeader = " + nameHeader);\r
if(nameHeader && refHeader){\r
var o = new Object();\r
o.nameHeader = nameHeader;\r
$("#addressingWidget").bind("command",SpecialXimfRule_CheckAddress);\r
AddEventSpecialMandatoryHeaders();\r
}\r
-\r
//\r
function AddEventSpecialMandatoryHeaders(){\r
- $("#addressingWidget textbox").bind("input",function(evt){if(evt.currentTarget.value.length <= 1) SpecialXimfRule_CheckAddress();});\r
+ $("#addressingWidget textbox").bind("input",function(evt){\r
+ if(evt.currentTarget.value.length <= 1) {\r
+ SpecialXimfRule_CheckAddress();\r
+ }\r
+ });\r
}\r
-\r
//\r
-function SpecialXimfRule_CheckAddress(){ \r
+function SpecialXimfRule_CheckAddress(){\r
try{\r
- var menulist = $("#addressingWidget menulist"); \r
+ var menulist = $("#addressingWidget menulist");\r
for(var idxSMH = 0 ; idxSMH < gSpecialMandatoryHeaders.length ; ++idxSMH){\r
- var valueRef = "addr_" + gSpecialMandatoryHeaders[idxSMH].refHeader; //\r
+ var valueRef = "addr_" + gSpecialMandatoryHeaders[idxSMH].refHeader;\r
var nameHeader = gSpecialMandatoryHeaders[idxSMH].nameHeader;\r
var valueRefSelected = false;\r
- \r
for(var i=0;i<menulist.length;++i){\r
var valueMenuList = $(menulist[i]).attr("value");\r
- \r
- if( valueMenuList == valueRef){//"addr_cc"\r
- try{ \r
+ if( valueMenuList === valueRef){\r
+ // "addr_cc"\r
+ try{\r
var id = $(menulist[i]).attr("id");\r
- var idBox = "addressCol2#" + id.slice(id.indexOf("#")+1,id.length); \r
+ var idBox = "addressCol2#" + id.slice(id.indexOf("#")+1,id.length);\r
elt = document.getElementById(idBox);\r
- if(elt.value != ""){\r
+ if(elt.value !== ""){\r
// Apply specific rule SpecialXimfRule_MandatoryHeadersCC\r
- //alert("id = " + idBox + "\nvalue = " + elt.value); \r
SpecialXimfRule_MandatoryHeaders(nameHeader);\r
- valueRefSelected = true; \r
+ valueRefSelected = true;\r
}\r
- }catch(ex){} \r
+ }catch(ex){}\r
break;\r
}\r
- } \r
- \r
+ }\r
// no rules to apply : unregister it\r
if(!valueRefSelected){\r
- //gConsole.logStringMessage("SpecialXimfRule_No_MandatoryHeaders ");\r
SpecialXimfRule_No_MandatoryHeaders(nameHeader);\r
}\r
}\r
- \r
- // register new textboxes events \r
+ // register new textboxes events\r
setTimeout("AddEventSpecialMandatoryHeaders()", 50);\r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - SpecialXimfRule_CheckAddress ] \n " + err + "\nfile : " + Error().fileName+"\nline : "+err.lineNumber);\r
- } \r
+ }\r
}\r
-\r
//\r
function SpecialXimfRule_MandatoryHeaders(nameHeader){\r
try{\r
- //gConsole.logStringMessage("SpecialXimfRule_MandatoryHeaders on " + nameHeader); \r
- // get headers to mandatory \r
+ // get headers to mandatory\r
var hdrLabel = $("label[ximfheader='"+nameHeader+"']");\r
if(hdrLabel){\r
hdrLabel[0].setAttribute("ximfmandatory","true");\r
CheckXimfhdrsSelection();\r
- } \r
+ }\r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - SpecialXimfRule_MandatoryHeaders ] \n " + err + "\nfile : " + Error().fileName+"\nline : "+err.lineNumber);\r
- } \r
+ }\r
}\r
-\r
//\r
function SpecialXimfRule_No_MandatoryHeaders(nameHeader){\r
try{\r
- //gConsole.logStringMessage("SpecialXimfRule_No_MandatoryHeaders on " + nameHeader)\r
//get headers to unmandatory\r
var hdrLabel = $("label[ximfheader='"+nameHeader+"']");\r
if(hdrLabel){\r
hdrLabel[0].setAttribute("ximfmandatory","false");\r
- hdrLabel[0].setAttribute("style","color:inherit;"); \r
+ hdrLabel[0].setAttribute("style","color:inherit;");\r
CheckXimfhdrsSelection();\r
}\r
}catch(e){\r
/* ***** BEGIN LICENSE BLOCK *****\r
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
*\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
* are permitted provided that the following conditons are met :\r
*\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
* in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
* prior written permission from EADS Defence and Security.\r
- * \r
+ *\r
* Alternatively, the contents of this file may be used under the terms of\r
* either of the GNU General Public License Version 2 or later (the "GPL"),\r
* or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
* and other provisions required by the GPL or the LGPL. If you do not delete\r
* the provisions above, a recipient may use your version of this file under\r
* the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
+ *\r
* REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ *\r
+ * Contributor(s):\r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
* ***** END LICENSE BLOCK ***** */\r
var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);\r
-\r
var CHROME_XIMFMAIL_TREEDATA = "chrome://theme_ximfmail/content/ximfTreeData.rdf";\r
var gRelativeXimfTreePath = "extensions/{A627B834-BD9F-4b3f-9AF5-347B5A570402}/chrome/content/theme/ximfTreeDataBck.rdf";\r
-\r
/*\r
- * \r
+ *\r
*/\r
function XimfTreeData(){\r
// private:\r
var _rdfService = null;\r
var _rdfCUtils = null;\r
- \r
var _dsCatalog = null;\r
var _rootNode = null;\r
var _urlCatalog = CHROME_XIMFMAIL_TREEDATA;\r
- var _instanceCounter = 0; // instance counter for index RDF file\r
- \r
+ // instance counter for index RDF file\r
+ var _instanceCounter = 0;\r
function init(){\r
try{\r
- if(!_rdfService)\r
+ if (!_rdfService) {\r
_rdfService = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);\r
- \r
+ }\r
if(!_dsCatalog){\r
- //_dsCatalog = _rdfService.GetDataSource(CHROME_XIMFMAIL_TREEDATA);\r
- //_dsCatalog.RegisterDataSource(); \r
_dsCatalog = Components.classes["@mozilla.org/rdf/datasource;1?name=in-memory-datasource"].createInstance(Components.interfaces.nsIRDFDataSource);\r
- //_dsCatalog = _rdfService.GetDataSource("rdf:ximfTree"); \r
+\r
}\r
- //_dsCatalog = Components.classes["@mozilla.org/rdf/datasource;1?name=in-memory-datasource"].createInstance(Components.interfaces.nsIRDFDataSource);\r
- \r
- if(!_rdfCUtils)\r
+ if (!_rdfCUtils) {\r
_rdfCUtils = Components.classes["@mozilla.org/rdf/container-utils;1"].getService(Components.interfaces.nsIRDFContainerUtils);\r
+ }\r
}catch(e){\r
- gConsole.logStringMessage("[ximfmail - XimfTreeData.init ] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber); \r
+ gConsole.logStringMessage("[ximfmail - XimfTreeData.init ] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber);\r
return false;\r
- } \r
+ }\r
return true;\r
}\r
- \r
// public:\r
- if(typeof XimfTreeData.initialized == "undefined"){\r
+ if (typeof XimfTreeData.initialized === "undefined") {\r
/*\r
* read infomations from catalog\r
*/\r
XimfTreeData.prototype.getTarget = function(instance,predicate){\r
- try{\r
+ try {\r
init();\r
var resource = _rdfService.GetResource(instance);\r
var targets = _dsCatalog.ArcLabelsOut(resource);\r
- while (targets.hasMoreElements()){ \r
+ while (targets.hasMoreElements()) {\r
var newpredicate = targets.getNext();\r
- if (newpredicate instanceof Components.interfaces.nsIRDFResource){\r
+ if (newpredicate instanceof Components.interfaces.nsIRDFResource) {\r
var target = _dsCatalog.GetTarget(resource, newpredicate, true);\r
- /*if (target instanceof Components.interfaces.nsIRDFResource){\r
- alert("Resource is: " + target.Value);\r
- }else*/\r
- if (target instanceof Components.interfaces.nsIRDFLiteral){\r
- //alert(newpredicate.Value + " : \n\r" + target.Value);\r
- if(newpredicate.Value == predicate)\r
+ if (target instanceof Components.interfaces.nsIRDFLiteral && newpredicate.Value === predicate) {\r
return target.Value;\r
- }\r
+ }\r
}\r
}\r
- }catch(e){\r
- //alert("[XimfTreeData]error instance loading...." + e);\r
- gConsole.logStringMessage("[ximfmail - XimfTreeData.getTarget ] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber); \r
+ } catch(e) {\r
+ gConsole.logStringMessage("[ximfmail - XimfTreeData.getTarget ] \n " + e + "\nfile : " + e.fileName+"\nline : "+e.lineNumber);\r
}\r
};\r
/*\r
try{\r
// create Seq container\r
init();\r
- \r
// create our root nodes\r
- //_rootNode = RDF.GetResource("urn:root"); \r
- //var seqNode = RDF.GetResource("urn:root:seq"); \r
- \r
var seqCatalog = _rdfService.GetResource("http://www.ximfmail.com/catalog");\r
var RDFC_Cat = null;\r
try{\r
- RDFC_Cat = _rdfCUtils.MakeSeq(_dsCatalog, seqCatalog); \r
+ RDFC_Cat = _rdfCUtils.MakeSeq(_dsCatalog, seqCatalog);\r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - XimfTreeData.registerXimfmailProfileNode ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
- } \r
- \r
- //alert("RDFC_Cat count= "+RDFC_Cat.GetCount());\r
- \r
- /* */\r
- var baseTag = domProfile.getElementsByTagName("base"); \r
- if(baseTag.length <= 0) return; \r
- //alert(baseTag[0].getAttribute("name"))\r
- var tname = baseTag[0].getAttribute("name"); \r
+ }\r
+ var baseTag = domProfile.getElementsByTagName("base");\r
+ if (baseTag.length <= 0) {\r
+ return;\r
+ }\r
+ var tname = baseTag[0].getAttribute("name");\r
var baseURI = "http://www.ximfmail.com/catalog/" + tname;\r
- //alert("baseURI = " + baseURI); \r
- //_rdfContainer.AppendElement(_rdfService.GetResource(baseURI));\r
try{\r
- //var RDFC_Cat = Components.classes["@mozilla.org/rdf/container;1"].createInstance(Components.interfaces.nsIRDFContainer);\r
- //RDFC_Cat.Init(_dsCatalog, seqCatalog);\r
RDFC_Cat.AppendElement(_rdfService.GetResource(baseURI));\r
}catch(e){\r
gConsole.logStringMessage("[ximfmail - XimfTreeData.registerXimfmailProfileNode ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
}\r
- \r
_dsCatalog.Assert(_rdfService.GetResource(baseURI),\r
_rdfService.GetResource("http://www.ximfmail.com/RDF#name"),\r
- _rdfService.GetLiteral(tname), true); \r
- \r
- \r
+ _rdfService.GetLiteral(tname), true);\r
_dsCatalog.Assert(_rdfService.GetResource(baseURI),\r
_rdfService.GetResource("http://www.ximfmail.com/RDF#dialogheader"),\r
- _rdfService.GetLiteral(baseURI+"/dialogheader"), true); \r
- \r
+ _rdfService.GetLiteral(baseURI+"/dialogheader"), true);\r
_dsCatalog.Assert(_rdfService.GetResource(baseURI),\r
_rdfService.GetResource("http://www.ximfmail.com/RDF#datas"),\r
_rdfService.GetLiteral(baseURI+"/datas"), true);\r
- \r
// Create dialogheader description\r
- var dlgUri = baseURI + "/dialogheader"; \r
- var seqNode = _rdfService.GetResource(dlgUri); \r
- var RDFC_Dgh = null; \r
+ var dlgUri = baseURI + "/dialogheader";\r
+ var seqNode = _rdfService.GetResource(dlgUri);\r
+ var RDFC_Dgh = null;\r
RDFC_Dgh = _rdfCUtils.MakeSeq(_dsCatalog, seqNode);\r
- //RDFC.Init(_dsCatalog, seqNode);\r
RDFC_Dgh.AppendElement(_rdfService.GetResource(dlgUri));\r
- \r
- var headerTag = baseTag[0].getElementsByTagName("header"); \r
+ var headerTag = baseTag[0].getElementsByTagName("header");\r
// append tiltle element <ximf:title>MCA</ximf:title>\r
- var title = headerTag[0].getElementsByTagName("title"); \r
+ var title = headerTag[0].getElementsByTagName("title");\r
_dsCatalog.Assert(_rdfService.GetResource(dlgUri),\r
_rdfService.GetResource("http://www.ximfmail.com/RDF#title"),\r
_rdfService.GetLiteral(title[0].textContent), true);\r
- \r
// append description element <ximf:descritpion>Mentions et clés d'attribution</ximf:descritpion>\r
var descritpion = headerTag[0].getElementsByTagName("description");\r
_dsCatalog.Assert(_rdfService.GetResource(dlgUri),\r
_rdfService.GetResource("http://www.ximfmail.com/RDF#description"),\r
_rdfService.GetLiteral(descritpion[0].textContent), true);\r
- \r
// append title colonne <ximf:column>clé</ximf:column>\r
var columnTag = headerTag[0].getElementsByTagName("column");\r
for(var x = 0; x < columnTag.length; ++x){\r
// append description element\r
_dsCatalog.Assert(_rdfService.GetResource(dlgUri),\r
_rdfService.GetResource("http://www.ximfmail.com/RDF#column"+x),\r
- _rdfService.GetLiteral(columnTag[x].textContent), true); \r
+ _rdfService.GetLiteral(columnTag[x].textContent), true);\r
}\r
- \r
- \r
- /* */\r
// Create datas descritpion\r
var datasUri = baseURI + "/datas";\r
var seqNode = _rdfService.GetResource(datasUri);\r
- var RDFC_data = null; \r
- try{ \r
+ var RDFC_data = null;\r
+ try{\r
RDFC_data = _rdfCUtils.MakeSeq(_dsCatalog, seqNode);\r
}catch(e){\r
- gConsole.logStringMessage("[ximfmail - XimfTreeData.registerXimfmailProfileNode ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
- } \r
- //_rdfContainer.Init(_dsCatalog, seqNode);\r
- //var RDFC_Dat = Components.classes["@mozilla.org/rdf/container;1"].createInstance(Components.interfaces.nsIRDFContainer);\r
- //try{\r
- // RDFC_Dat.Init(_dsCatalog, seqNode); \r
- //}catch(e){\r
- // gConsole.logStringMessage("[ximfmail - XimfTreeData.registerXimfmailProfileNode ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
- //}\r
- // add datas from xml profile to RDF file \r
- var treeTag = baseTag[0].getElementsByTagName("tree"); \r
+ gConsole.logStringMessage("[ximfmail - XimfTreeData.registerXimfmailProfileNode ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
+ // add datas from xml profile to RDF file\r
+ var treeTag = baseTag[0].getElementsByTagName("tree");\r
var instanceTag = treeTag[0].getElementsByTagName("description");\r
for(var i = 0; i < instanceTag.length; ++i){\r
// append resource element to sequence\r
- var newURI = datasUri + "/data" + i; \r
- //_rdfContainer.AppendElement(_rdfService.GetResource(newURI));\r
+ var newURI = datasUri + "/data" + i;\r
RDFC_data.AppendElement(_rdfService.GetResource(newURI));\r
- \r
var instanceTagData = instanceTag[i].getElementsByTagName("data");\r
for(var j = 0; j < instanceTagData.length; ++j){\r
// append description element\r
_dsCatalog.Assert(_rdfService.GetResource(newURI),\r
_rdfService.GetResource("http://www.ximfmail.com/RDF#column"+j),\r
- _rdfService.GetLiteral(instanceTagData[j].textContent), true); \r
+ _rdfService.GetLiteral(instanceTagData[j].textContent), true);\r
}\r
}\r
- \r
- //_dsCatalog.RegisterDataSource(); \r
- }catch(e){ \r
+ }catch(e){\r
gConsole.logStringMessage("[ximfmail - XimfTreeData.registerXimfmailProfileNode ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
- } \r
- \r
- // save datas to file \r
- /*\r
- _dsCatalog.QueryInterface(Components.interfaces.nsIRDFRemoteDataSource);\r
- var rdfXimfTreeDataPath = getFilePathInProfile(gRelativeXimfTreePath); \r
- _dsCatalog.FlushTo("file:///" + rdfXimfTreeDataPath); */ \r
+ }\r
};\r
- \r
XimfTreeData.prototype.getTitleHeader = function(key){\r
var uri = "http://www.ximfmail.com/catalog/"+ key + "/dialogheader";\r
return this.getTarget(uri,"http://www.ximfmail.com/RDF#title");\r
};\r
- \r
XimfTreeData.prototype.getDescriptionHeader = function(key){\r
var uri = "http://www.ximfmail.com/catalog/"+ key + "/dialogheader";\r
return this.getTarget(uri,"http://www.ximfmail.com/RDF#description");\r
};\r
- \r
XimfTreeData.prototype.getTitleColumn = function(key,idx){\r
var uri = "http://www.ximfmail.com/catalog/"+ key + "/dialogheader";\r
return this.getTarget(uri,"http://www.ximfmail.com/RDF#column"+idx);\r
};\r
- \r
XimfTreeData.initialized = true;\r
}\r
}
\ No newline at end of file
/* ***** BEGIN LICENSE BLOCK *****
* Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.
* ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.
- *
*
- * Redistribution and use, in source and binary forms, with or without modification,
+ *
+ * Redistribution and use, in source and binary forms, with or without modification,
* are permitted provided that the following conditons are met :
*
- * 1. Redistributions of source code must retain the above copyright notice,
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached
+ * 1. Redistributions of source code must retain the above copyright notice,
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached
* in the redistribution of the source code.
- * 3. Neither the names of the copyright holders nor the names of any contributors
- * may be used to endorse or promote products derived from this software without specific
+ * 3. Neither the names of the copyright holders nor the names of any contributors
+ * may be used to endorse or promote products derived from this software without specific
* prior written permission from EADS Defence and Security.
- *
+ *
* Alternatively, the contents of this file may be used under the terms of
* either of 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"),
* 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.
- *
+ *
* REMINDER :
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
* IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- *
- * EADS Defence and Security - 1 Boulevard Jean Moulin -
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)
+ *
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)
+ *
+ * Contributor(s):
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved
* ***** END LICENSE BLOCK ***** */
-
-// GLOBALS
-//var relativeXimfCatalogPath = "ximf/ximfmail/chrome/content/theme/ximfCatalog.rdf";
var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
-
+/*
+ * Load informations of ximf extensions in RDF memory
+ */
+var gXimfCatalog = null;
+/**
+ *
+ * @returns {String}
+ */
function TRACE_DATE(){
- var ladate=new Date();
+ var ladate=new Date();
var h=ladate.getHours();
- if (h<10) {h = "0" + h}
+ if (h<10) {
+ h = "0" + h;
+ }
var m=ladate.getMinutes();
- if (m<10) {m = "0" + m}
+ if (m<10) {
+ m = "0" + m;
+ }
var s=ladate.getSeconds();
- if (s<10) {s = "0" + s};
- return "\nDATE > "+ladate.getDate()+"/"+(ladate.getMonth()+1)+"/"+ladate.getFullYear()+" "+h+":"+m+":"+s+":"+ladate.getMilliseconds();
+ if (s<10) {
+ s = "0" + s;
+ }
+ return "\nDATE > "+ladate.getDate()+"/"+(ladate.getMonth()+1)+"/"+ladate.getFullYear()+" "+h+":"+m+":"+s+":"+ladate.getMilliseconds();
}
-
-
/*
- * Load informations of ximf extensions in RDF memory
+ * get file / path of user profile
*/
-var gXimfCatalog = null;
-function CreateXimfmailCatalog(aclLevel){
- try{
- if(!gXimfCatalog) gXimfCatalog = XimfCatalog.getInstance();
- }catch(e){
- gConsole.logStringMessage("[ximfmail - Create XimfCatalog ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
+ function getFileFromProfile(aRelativePath) {
+ var file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
+ // Add relative data file
+ var path = aRelativePath.split("/");
+ for (var i = 0, sz = path.length; i < sz; i++) {
+ if (path[i] !== "") {
+ file.append(path[i]);
+ }
}
+ return file;
}
-
-/*
- * get path of user profile
- */
- function getFilePathInProfile(aRelativePath) {
- var file = Components.classes["@mozilla.org/file/directory_service;1"]
- .getService(Components.interfaces.nsIProperties)
- .get("ProfD", Components.interfaces.nsIFile);
-
- // Add relative data file
- var path = aRelativePath.split("/");
- for (var i = 0, sz = path.length; i < sz; i++) {
- if (path[i] != "")
- file.append(path[i]);
- }
+function getFilePathInProfile(aRelativePath) {
+ var file = getFileFromProfile(aRelativePath);
return file.path;
}
-
/*
* List files of 'dir' directory
*/
var dir = Components.classes["@mozilla.org/file/local;1"].
createInstance(Components.interfaces.nsILocalFile);
dir.initWithPath( bn );
-
// read files of working directory
var dlst = dir.directoryEntries;
while(dlst.hasMoreElements()) {
var file = dlst.getNext().QueryInterface(Components.interfaces.nsIFile);
- if (file.isFile() && file.leafName.substring(file.leafName.lastIndexOf('.'))=='.xul') {
+ if (file.isFile() && file.leafName.substring(file.leafName.lastIndexOf('.')) === '.xul') {
/* Create html list */
var html_li = document.createElementNS(HTML_NS, 'li');
var html_a = document.createElementNS(HTML_NS, 'a');
html_li.appendChild(html_a);
html_lst.appendChild(html_li);
}
- }
+ }
}
-
/*
- * List extensions of profile
+ * List extensions of profile
*/
function getExtensionsList(){
- try{
+ try{
var em = Components.classes["@mozilla.org/extensions/manager;1"].getService(Components.interfaces.nsIExtensionManager);
var rfdSvc = Components.classes["@mozilla.org/rdf/rdf-service;1"].getService(Components.interfaces.nsIRDFService);
var url = em.datasource.URI;
- return em.getItemList(Components.interfaces.nsIUpdateItem.TYPE_ADDON, { });
-
+ return em.getItemList(Components.interfaces.nsIUpdateItem.TYPE_ADDON, { });
+
}catch(e){
gConsole.logStringMessage("[ximfmail - getExtensionsList ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
- }
+ }
}
-
-
-/*
+/*
* get XML parser from file
* sPath : complete path File locate on Disk
*/
var stream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
stream.init(file, -1, -1, Components.interfaces.nsIFileInputStream.CLOSE_ON_EOF);
var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser);
-
return parser.parseFromStream(stream, null, file.fileSize, "text/xml");
}
-
-
/*
- *
+ *
*/
function xHeader(headerRef,headerName,valueRef,valueName,targetName){
- if(headerRef)
+ if (headerRef) {
this._headerRef=headerRef;
- if(headerName)
+ }
+ if (headerName) {
this._headerName = headerName;
- if(valueRef)
+ }
+ if (valueRef) {
this._valueRef = valueRef;
- if(valueName)
+ }
+ if (valueName) {
this._valueName = valueName;
+ }
//FT3504
- if(targetName)
+ if (targetName) {
this._targetName = targetName;
-
+ }
}
-
/*
* Create an array of XIMF headers and XIMF values to use for specific check rules
* Function returns an array of xHeader objects
* XIMF values are store in string and separated with '&' character
*/
-function CreateRulesArray(instancePath,ruleType){
-
-
- var tabHeaders = new Array; // tabHeaders[headerRef][headerName][valueRef][valueName] : headers X to add with values X
- // tabHeaders['0'][headerName]['0'][valueName] : headers to add necessarily
- // tabHeaders[headerRef][headerName][valueRef]['0'] : headersto add with XIMF values
+function CreateRulesArray(instancePath, ruleType){
+ // tabHeaders[headerRef][headerName][valueRef][valueName] : headers X to add with values X
+ // tabHeaders['0'][headerName]['0'][valueName] : headers to add necessarily
+ // tabHeaders[headerRef][headerName][valueRef]['0'] : headersto add with XIMF values
+ var tabHeaders = new Array;
try{
// get xml rules
var dir = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
-
- var urlRules = getFilePathInProfile("extensions/"+gXimfCatalog.getRulesInstance(instancePath));
- dir.initWithPath( urlRules );
- if(!dir.exists()){
+ var urlRules = getFilePathInProfile("extensions/"+ XimfCatalog.getInstance().getRulesInstance(instancePath));
+ dir.initWithPath( urlRules );
+ if(!dir.exists()){
gConsole.logStringMessage("[Ximfmail - CreateRulesArray] Error loading dictionary file : " + urlRules);
return;
- }
- var xmlDoc = GetXmlDocument(urlRules);
- //oki var instanceTag = xmlDoc.getElementsByTagName("rules");
+ }
+ var xmlDoc = GetXmlDocument(urlRules);
var compatibleTag = xmlDoc.getElementsByTagName(ruleType);
var sValue="";
//FT3504
var childNodes = compatibleTag[idx].childNodes;
var targetName = compatibleTag[idx].getAttribute("targetName");
for(var j=0; j <childNodes.length; ++j ){
- var hname = "";
- var href = "";
+ var hname = "";
+ var href = "";
var vname = "";
- var vref = "";
- if(childNodes[j].localName == "aliasHeader"){
+ var vref = "";
+ if(childNodes[j].localName === "aliasHeader"){
hname = childNodes[j].getAttribute("headerName");
href = childNodes[j].getAttribute("headerRef");
var childHeader = childNodes[j].childNodes;
for(var k=0; k <childHeader.length; ++k ){
//get attributes
- if(childHeader[k].localName == "aliasValue"){
- if (vname == ""){
+ if(childHeader[k].localName === "aliasValue"){
+ if (vname === ""){
vname = childHeader[k].getAttribute("valueName");
- vref = childHeader[k].getAttribute("valueRef");
+ vref = childHeader[k].getAttribute("valueRef");
}else{
vname = vname + "&" + childHeader[k].getAttribute("valueName");
- vref = vref + "&" + childHeader[k].getAttribute("valueRef");
+ vref = vref + "&" + childHeader[k].getAttribute("valueRef");
}
}
- }
-
- // load values to array
- tabHeaders.push(new xHeader(href, hname, vref, vname,targetName));
-
- }
+ }
+ // load values to array
+ tabHeaders.push(new xHeader(href, hname, vref, vname,targetName));
+ }
}
- }
-
- //log array values
+ }
}catch(e){
- gConsole.logStringMessage("[ximfmail - CreateRulesArray ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
- }
-
- return tabHeaders;
-}
-
-
-/*
- * Create Dom Node with xml instance schemas
- * Create DOM with XSL transformation
-*/
-function CreateDOMWithXimfInstanceRef(instancePath, xslUrl){
- try{
- // create XSLT Processor
- var xslProcessor = new XSLTProcessor();
-
- // import XSLT File
- var myXMLHTTPRequest = new XMLHttpRequest();
- myXMLHTTPRequest.open("GET", xslUrl, false);
- myXMLHTTPRequest.send(null);
- var objXSL = myXMLHTTPRequest.responseXML;
- xslProcessor.importStylesheet(objXSL);
-
- // get local lang for ilk management
- var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
- var paramLang = prefs.getCharPref("general.useragent.locale");
- if(paramLang)
- xslProcessor.setParameter("","gLang", paramLang);
-
- // get xml schema
- //var gXimfCatalog = new XimfCatalog();
- var dir = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
- var completePath = getFilePathInProfile("extensions/"+gXimfCatalog.getSchemaInstance(instancePath));
-
- dir.initWithPath( completePath );
- if(!dir.exists()){
- gConsole.logStringMessage("[Ximfmail - CreateDOMWithXimfInstanceRef] Error loading schema file : " + completePath);
- return;
- }else{
- //gConsole.logStringMessage("[Ximfmail - CreateDOMWithXimfInstanceRef] loading schema file : " + completePath);
- }
- var objXML = GetXmlDocument(completePath);
-
- // get xml dictionary
- var urlDictionary = getFilePathInProfile("extensions/"+gXimfCatalog.getDictionaryInstance(instancePath));
-
- dir.initWithPath( urlDictionary );
- if(!dir.exists()){
- gConsole.logStringMessage("[Ximfmail - CreateDOMWithXimfInstanceRef] Error loading dictionary file : " + completePath);
- return;
- }
-
- // get xml ihm
- var urlIhm = getFilePathInProfile("extensions/"+gXimfCatalog.getIhmInstance(instancePath));
-
- dir.initWithPath( urlIhm );
- if(!dir.exists()){
- gConsole.logStringMessage("[Ximfmail - CreateDOMWithXimfInstanceRef] Error loading ihm file : " + completePath);
- return;
- }
-
- // insert dictionary node, ihm node to instance node of xml schema
- var objDicoXML = GetXmlDocument(urlDictionary);
- var oDicoNode = objDicoXML.getElementsByTagName("ximf:dictionary");
- var objIhmXML = GetXmlDocument(urlIhm);
- var oIhmNode = objIhmXML.getElementsByTagName("ximf:ihm");
- var oSchemaNode = objXML.getElementsByTagName("ximf:instance");
- oSchemaNode[0].appendChild( oDicoNode[0] );
- oSchemaNode[0].appendChild( oIhmNode[0] );
-
- // transform document
- var docResult = xslProcessor.transformToFragment(objXML, document);
- return docResult;
- }catch(e){
- gConsole.logStringMessage("[Ximfmail - CreateDOMWithXimfInstance] Error on creating instance...\n" + e + " [ " + Error().fileName + Error().lineNumber +"]");
- alert("[Ximfmail] Error on creating instance...\n" + e+ " [ " + Error().fileName + Error().lineNumber +"]");
+ gConsole.logStringMessage("[ximfmail - CreateRulesArray ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+e.lineNumber);
}
+ return tabHeaders;
}
-
+/**
+ *
+ * @param instancePath
+ * @param xslUrl
+ * @returns
+ */
function CreateDOMWithXimfInstance(instancePath, xslUrl){
- try{
- //gConsole.logStringMessage("[Ximfmail - CreateDOMWithXimfInstance] instancepath = " + instancePath +"\n xslurl = " + xslUrl );
- var xml = CreateXMLObjectWithXimfmailInstance(instancePath);
+ try{
+ var xml = CreateXMLObjectWithXimfmailInstance(instancePath);
return ApplyXimfmailXslt(xslUrl,xml);
}catch(e){
gConsole.logStringMessage("[Ximfmail - CreateDOMWithXimfInstance] Error on creating instance...\n" + e + " [ " + Error().fileName + Error().lineNumber +"]");
- alert("[Ximfmail] Error on creating instance...\n" + e+ " [ " + Error().fileName + Error().lineNumber +"]");
}
return null;
}
-
function CreateXMLObjectWithXimfmailInstance(instancePath){
try{
// get xml schema
var dir = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
- var completePath = getFilePathInProfile("extensions/"+gXimfCatalog.getSchemaInstance(instancePath));
-
- dir.initWithPath( completePath );
- if(!dir.exists()){
+ var completePath = getFilePathInProfile("extensions/"+XimfCatalog.getInstance().getSchemaInstance(instancePath));
+ dir.initWithPath( completePath );
+ if(!dir.exists()){
gConsole.logStringMessage("[Ximfmail - CreateXMLObjectWithXimfmailInstance] Error loading schema file : " + completePath);
return null;
}
-
var objXML = GetXmlDocument(completePath);
-
// get xml dictionary
- var urlDictionary = getFilePathInProfile("extensions/"+gXimfCatalog.getDictionaryInstance(instancePath));
- dir.initWithPath( urlDictionary );
- if(dir.exists()){
+ var urlDictionary = getFilePathInProfile("extensions/"+XimfCatalog.getInstance().getDictionaryInstance(instancePath));
+ dir.initWithPath( urlDictionary );
+ if(dir.exists()){
var objDicoXML = GetXmlDocument(urlDictionary);
var oDicoNode = objDicoXML.getElementsByTagName("ximf:dictionary");
}
-
// get xml ihm
- var urlIhm = getFilePathInProfile("extensions/"+gXimfCatalog.getIhmInstance(instancePath));
-
- dir.initWithPath( urlIhm );
- if(dir.exists()){
- var objIhmXML = GetXmlDocument(urlIhm);
+ var urlIhm = getFilePathInProfile("extensions/"+XimfCatalog.getInstance().getIhmInstance(instancePath));
+ dir.initWithPath( urlIhm );
+ if(dir.exists()){
+ var objIhmXML = GetXmlDocument(urlIhm);
var oIhmNode = objIhmXML.getElementsByTagName("ximf:ihm");
}
-
// get xml rules
- var urlRules = getFilePathInProfile("extensions/"+gXimfCatalog.getRulesInstance(instancePath));
-
- dir.initWithPath( urlRules );
- if(dir.exists()){
+ var urlRules = getFilePathInProfile("extensions/"+XimfCatalog.getInstance().getRulesInstance(instancePath));
+ dir.initWithPath( urlRules );
+ if(dir.exists()){
var objRulesXML = GetXmlDocument(urlRules);
var oRulesNode = objRulesXML.getElementsByTagName("ximf:rule");
}
-
- // insert dictionary node, ihm node to instance node of xml schema
+ // insert dictionary node, ihm node to instance node of xml schema
var oSchemaNode = objXML.getElementsByTagName("ximf:instance");
if(oDicoNode.length > 0){
oSchemaNode[0].appendChild( oDicoNode[0] );
}
-
if(oIhmNode.length > 0){
oSchemaNode[0].appendChild( oIhmNode[0] );
- }
-
+ }
for(var i=0; i < oRulesNode.length; ++i){
oSchemaNode[0].appendChild( oRulesNode[i] );
}
gConsole.logStringMessage("[Ximfmail - CreateXMLObjectWithXimfmailInstance] \nError : " + e + " \n [ " + Error().fileName + Error().lineNumber +"]");
}
return null;
-
}
-
/*
* Create DOM node with xslt transformation on xml object
*/
function ApplyXimfmailXslt(xsltUrl,xmlObject){
-
- if(!xmlObject) return null;
- try{
- // import XSLT File
+ if(!xmlObject) {
+ return null;
+ }
+ try{
+ // import XSLT File
var myXMLHTTPRequest = new XMLHttpRequest();
myXMLHTTPRequest.open("GET", xsltUrl, false);
myXMLHTTPRequest.send(null);
- var objXSL = myXMLHTTPRequest.responseXML;
- var xslProcessor = new XSLTProcessor();
+ var objXSL = myXMLHTTPRequest.responseXML;
+ var xslProcessor = new XSLTProcessor();
xslProcessor.importStylesheet(objXSL);
-
// get local lang
var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
var paramLang = prefs.getCharPref("general.useragent.locale");
- if(paramLang){
+ if(paramLang){
xslProcessor.setParameter("","gLang", paramLang);
}
-
// transform document
- var docResult = xslProcessor.transformToFragment(xmlObject, document);
- return docResult;
+ var docResult = xslProcessor.transformToFragment(xmlObject, document);
+ return docResult;
}catch(e){
gConsole.logStringMessage("[Ximfmail - CreateXMLObjectWithXimfmailInstance] \nError : " + e + " \n [ " + Error().fileName + Error().lineNumber +"]");
}
- return null;
-}
-
-
+ return null;
+}
/*
* Sat, 06 Jun 2009 16:10:00 GMT >> 09/06/2009 14:10:55
*/
function ConvertZTimeToLocal(thisdate){
var new_date = null;
- var reg=new RegExp("[ / :]+", "g"); //eads
- var parts = thisdate.split(reg); // parts[day][date][month][year][hour][minute][sec][gmt+0]
- if(parts.length < 8) return;
-
+ var reg=new RegExp("[ / :]+", "g");
+ // parts[day][date][month][year][hour][minute][sec][gmt+0]
+ var parts = thisdate.split(reg);
+ if (parts.length < 8) {
+ return;
+ }
// get date
- new_date = parts[1];
+ new_date = parts[1];
// get month
var month = "";
switch(parts[2].toLowerCase()){
case "jan":
- new_date += "/01/";
+ new_date += "/01/";
month = "0";
break;
case "feb":
- new_date += "/02/";
+ new_date += "/02/";
month = "1";
break;
case "mar":
- new_date += "/03/";
+ new_date += "/03/";
month = "2";
break;
case "apr":
- new_date += "/04/";
+ new_date += "/04/";
month = "3";
break;
case "may":
- new_date += "/05/";
+ new_date += "/05/";
month = "4";
break;
case "jun":
- new_date += "/06/";
+ new_date += "/06/";
month = "5";
break;
case "jul":
- new_date += "/07/";
+ new_date += "/07/";
month = "6";
break;
case "aug":
- new_date += "/08/";
+ new_date += "/08/";
month = "7";
break;
case "sep":
- new_date += "/09/";
+ new_date += "/09/";
month = "8";
break;
case "oct":
- new_date += "/10/";
+ new_date += "/10/";
month = "9";
break;
case "nov":
- new_date += "/11/";
+ new_date += "/11/";
month = "10";
break;
case "dec":
- new_date += "/12/";
+ new_date += "/12/";
month = "11";
break;
- default : new_date += "/??/";
- }
+ default : new_date += "/??/";
+ }
//get year
new_date += parts[3];
//get time, adjust time GMT and LocaleTime
cdat.setUTCFullYear(parseInt("20"+parts[3], 10));
cdat.setUTCMonth(parseInt(month, 10));
cdat.setUTCDate(parseInt(parts[1], 10));
-
var hour = parts[4];
var min = parts[5];
- try{
- if(parts[4][0]=="0")
+ try {
+ if (parts[4][0] === "0") {
hour=parts[4][1];
- }catch(e){}
+ }
+ } catch(e) {}
try{
- if(parts[5][0]=="0")
+ if(parts[5][0] === "0") {
min=parts[5][1];
+ }
}catch(e){}
-
// get local time
var time = (parseInt(hour, 10)*60) + parseInt(min, 10) + (cdat.getTimezoneOffset()*-1);
- //gConsole.logStringMessage("DBG [Ximfmail - ConvertZTimeToLocal] Formule \n"+(parseInt(hour, 10)*60)+"+"+parseInt(min, 10)+"+" +cdat.getTimezoneOffset()+"="+time);
-
- var hour = parseInt(parseInt(time, 10)/60, 10);
- if(parseInt(hour, 10)<=9) hour = "0" + hour;
- if(parseInt(min, 10) < 0){
-
+ hour = parseInt(parseInt(time, 10)/60, 10);
+ if (parseInt(hour, 10)<=9) {
+ hour = "0" + hour;
}
- if(parseInt(min, 10) < 24){
-
+ min = parseInt(parseInt(time, 10)%60, 10);
+ if (parseInt(min, 10)<=9) {
+ min = "0" + min;
}
- var min = parseInt(parseInt(time, 10)%60, 10);
- if(parseInt(min, 10)<=9) min = "0" + min;
-
new_date += " "+ hour +":"+min;
-
- //gConsole.logStringMessage("DBG [Ximfmail - ConvertZTimeToLocal] \n"+hour+":"+min+" >> " +time+"\n"+time+"/60 = "+ parseInt(time, 10)/60 + "\n" + time + "%60 = " + parseInt(time, 10)%60);
-
return new_date;
-}
-
+}
/*
* get international value from ximfmail propertie file
*/
function getIlkProperties(key){
var sLabel = "";
// internationalisation of ximfmail context popup
- try{
+ try{
var gBundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
- var stringBundle = gBundle.createBundle("chrome://ximfmail/locale/ximfmail.properties");
- sLabel = stringBundle.GetStringFromName(key);
- }catch(err){}
- return sLabel;
-}
-
+ var stringBundle = gBundle.createBundle("chrome://ximfmail/locale/ximfmail.properties");
+ sLabel = stringBundle.GetStringFromName(key);
+ }catch(err){}
+ return sLabel;
+}
function String_trim(s) {
var c ="";
var tmp="";
- for (var i = 0; i < s.length; i++) {
- if(s[i] != " " &&
- s[i] != "\t"){
+ for (var i = 0; i < s.length; i++) {
+ if(s[i] !== " " && s[i] !== "\t") {
c += s[i];
}
}
return c;
}
-
/*
- * BUG 4689 - using folding with header
+ * BUG 4689 - using folding with header
* realize mime format convert special character to encoded-word ASCII format (RFC 2047)
* rule based on RFC222 : Internet Message Format
*/
function EncodeMimeXimfheader(sHeader, sValue, charSet){
try{
var tmpValue = "";
- var sValueFolding = "";
- //IMF_HEADER_LINE_MAX_LENGTH=Components.interfaces.nsIMimeConverter.MIME_ENCODED_WORD_SIZE;
-
- try{
+ var sValueFolding = "";
+ try{
// realize mime format convert special character to encoded-word ASCII format (RFC 2047)
- var mimeEncoder = Components.classes["@mozilla.org/messenger/mimeconverter;1"].getService(Components.interfaces.nsIMimeConverter);
+ var mimeEncoder = Components.classes["@mozilla.org/messenger/mimeconverter;1"].getService(Components.interfaces.nsIMimeConverter);
sValueFolding = mimeEncoder.encodeMimePartIIStr_UTF8(sValue, false, charSet , sHeader.length + 2, Components.interfaces.nsIMimeConverter.MIME_ENCODED_WORD_SIZE);
}catch (ex){
sValueFolding = sValue;
- }
+ }
}catch(e){
sValueFolding = sValue;
- }
- return sHeader + ": " + sValueFolding;
-}
-
-/*
- * Convert mime header value to string value
- */
-function DecodeMimeXimfheader(sHeaderValue){
- var newHdrValue = null;
- var charsetDefault = "LATIN_CHARSET";
- try{
- // convert MIME format (encoded-word ASCII) to String
- if(gLastMailCharset) charsetDefault = gLastMailCharset;
- var mimeXimfConverter = Components.classes["@mozilla.org/messenger/mimeconverter;1"].getService(Components.interfaces.nsIMimeConverter);
- newHdrValue = mimeXimfConverter.decodeMimeHeader(sHeaderValue,charsetDefault,false,true);
- }catch(ex){
- newHdrValue = sHeaderValue;
}
- return newHdrValue;
+ return sHeader + ": " + sValueFolding;
}
-
/*
* Datas class of dialogTree window
window.arguments = [];
args[0] id textbox to update
args[1] reference of catalogue to load
args[2] title of dialogbox
- args[3] description of dialogbox
+ args[3] description of dialogbox
args[4] title of column 0 of dialogbox
args[5] title of column 1 of dialogbox
*/
function XimfmailTreedialogArgs(){
- this.idTargetTextbox = ""; // id textbox to update
- this.title = ""; // ttitle of dialogbox
- this.description = ""; // description of dialogbox
- this.dataSource = ""; // datasource
+ // id textbox to update
+ this.idTargetTextbox = "";
+ // ttitle of dialogbox
+ this.title = "";
+ // description of dialogbox
+ this.description = "";
+ // datasource
+ this.dataSource = "";
this.titleColKey = "";
this.titleColLabel = "";
- this.refdataSource = ""; // reference of catalogue to load
- this.currentKeys = []; //
- this.currentLabels = []; //
- this.maxItemsSelected = 1;
+ // reference of catalogue to load
+ this.refdataSource = "";
+ this.currentKeys = [];
+ this.currentLabels = [];
+ this.maxItemsSelected = 1;
this.retKeys=[];
this.retLabels=[];
this.retIsCancel=false;
}
-
-
+/**
+ * update Secure Headers file definition with current user Ximf instance
+ *
+ */
+function UpdateSecureHeadersFileSettings (instancePath, identity) {
+ // create XMLFile at temp directory with rules datas
+ var secureHdrArray = [];
+ var res = false;
+ try {
+ secureHdrArray = CreateRulesArray(instancePath,"ximf:secureHeaders");
+ if (secureHdrArray.length > 0) {
+ var signHeaders = CreateDOMWithXimfInstance(instancePath, ximfConst.CHROME_XSL_SECURE_HEADERS);
+ if (signHeaders) {
+ // get profile folder
+ var file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
+ var serializer = new XMLSerializer();
+ var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
+ file.append(ximfConst.XIMFMAIL_SECURE_HEADERS_XML_FILE);
+ // write, create, truncate
+ foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0);
+ // rememeber, doc is the DOM tree
+ serializer.serializeToStream(signHeaders, foStream, "");
+ foStream.close();
+ // set folder datas
+ identity.setCharAttribute("secureheaders.folderdata",file.path);
+ gConsole.logStringMessage("ximfmail - UpdateSecureHeadersFileSettings] succes updating file " + file.path );
+ res = true;
+ }
+ } else {
+ gConsole.logStringMessage("[ximfmail - UpdateSecureHeadersFileSettings] no rules defined for instance " + instancePath);
+ }
+ } catch (e) {
+ gConsole.logStringMessage("[ximfmail - UpdateSecureHeadersFileSettings] Error : " + e);
+ }
+ return res;
+}
/**
* Transform all instances of Ximfmail catalog in xml files
* Thoses files will be used to display Security Labels (RFC 2634)
*/
-function CreateSecurityLabelXml(){
- try{
- if(!gXimfCatalog){return;}
-
+function CreateSecurityLabelXml(){
+ try{
var listRef = "";
- var arrayIstances = gXimfCatalog.getInstanceList();
- var xsltUrl = "chrome://theme_ximfmail/content/instance2SecurityLabel-ximfmail.xsl";
+ var arrayIstances = XimfCatalog.getInstance().getInstanceList();
+ var xsltUrl = "chrome://theme_ximfmail/content/instance2SecurityLabel-ximfmail.xsl";
for(i=0 ; i< arrayIstances.length ; ++i){
try{
var cInstance = arrayIstances[i];
- listRef += cInstance + " \n";
+ listRef += cInstance + " \n";
var resXsl = CreateDOMWithXimfInstance(arrayIstances[i] , xsltUrl);
if(resXsl){
- var newFileName = gXimfCatalog.getNameInstance(arrayIstances[i])+".xml";
- var file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile); // get profile folder
+ var newFileName = XimfCatalog.getInstance().getNameInstance(arrayIstances[i])+".xml";
+ // get profile folder
+ var file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
var serializer = new XMLSerializer();
var foStream = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
file.append("securityLabel");
- try{file.create(file.DIRECTORY_TYPE,0);}catch(err){}
+ try {
+ file.create(file.DIRECTORY_TYPE,0);
+ } catch(err) {}
file.append(newFileName);
- foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0); // write, create, truncate
- serializer.serializeToStream(resXsl, foStream, ""); // rememeber, doc is the DOM tree
+ // write, create, truncate
+ foStream.init(file, 0x02 | 0x08 | 0x20, 0664, 0);
+ // rememeber, doc is the DOM tree
+ serializer.serializeToStream(resXsl, foStream, "");
foStream.close();
}
}catch(e){
gConsole.logStringMessage("[ximfmail - CreateSecurityLabelXml ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);
- }
- }
+ }
+ }
}catch(e){
gConsole.logStringMessage("[ximfmail - CreateSecurityLabelXml ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+ e.lineNumber);
- }
+ }
}
-
-function ximfAlert(title,message){
+function ximfAlert(title,message){
if(!message){
message = title;
title = "";
}
var prompts = Components.classes["@mozilla.org/embedcomp/prompt-service;1"].getService(Components.interfaces.nsIPromptService);
- prompts.alert(window,title, message);
+ prompts.alert(window,title, message);
}
-
/*
* return value of array {[key][value],[key][value],...}
- * @param key :
- * @param array :
+ * @param key :
+ * @param array :
*/
function GetValueFromArrayWithInsensitiveKey(key, array){
var value = null;
- try{
- value = array[key];
- if(value == null){
+ try{
+ value = array[key];
+ if(value === null){
// try to get value of array with insensitive case key
for(akey in array){
- if(akey.toLowerCase() == key.toLowerCase()){
- value = array[akey];
- //alert("GetValueFromArrayWithInsensitiveKey - value as insensitive case founded : " +akey+" : "+ value)
+ if(akey.toLowerCase() === key.toLowerCase()){
+ value = array[akey];
break;
}
- }
- }
+ }
+ }
}catch(e){
- gConsole.logStringMessage("[ximfmail - GetValueFromArrayWithInsensitiveKey ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
+ gConsole.logStringMessage("[ximfmail - GetValueFromArrayWithInsensitiveKey ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
value=null;
}
return value;
<xsl:if test="@contentPositionEnd">\r
<xsl:attribute name="ximfcompositionend"><xsl:value-of select="@contentPositionEnd" /></xsl:attribute>\r
</xsl:if>\r
+ <xsl:if test="@contentFactorise">\r
+ <xsl:attribute name="ximffactorise"><xsl:value-of select="@contentFactorise" /></xsl:attribute>\r
+ </xsl:if>\r
</xsl:element> \r
<xsl:for-each select="*">\r
<xsl:choose>\r
-# ***** BEGIN LICENSE BLOCK *****
-# Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.
-# ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.
-#
-#
-# Redistribution and use, in source and binary forms, with or without modification,
-# are permitted provided that the following conditons are met :
-#
-# 1. Redistributions of source code must retain the above copyright notice,
-# 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached
-# in the redistribution of the source code.
-# 3. Neither the names of the copyright holders nor the names of any contributors
-# may be used to endorse or promote products derived from this software without specific
-# prior written permission from EADS Defence and Security.
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either of 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.
-#
-# REMINDER :
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# EADS Defence and Security - 1 Boulevard Jean Moulin -
-# ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)
-# ***** END LICENSE BLOCK *****
-# Strings used in the Mozill AccountManager
-prefPanel-ximfmail=XIMF
+# ***** BEGIN LICENSE BLOCK *****\r
+# Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
+# ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
+# \r
+#\r
+# Redistribution and use, in source and binary forms, with or without modification, \r
+# are permitted provided that the following conditons are met :\r
+#\r
+# 1. Redistributions of source code must retain the above copyright notice, \r
+# 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+# in the redistribution of the source code.\r
+# 3. Neither the names of the copyright holders nor the names of any contributors \r
+# may be used to endorse or promote products derived from this software without specific \r
+# prior written permission from EADS Defence and Security.\r
+# \r
+# Alternatively, the contents of this file may be used under the terms of\r
+# either of the GNU General Public License Version 2 or later (the "GPL"),\r
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
+# in which case the provisions of the GPL or the LGPL are applicable instead\r
+# of those above. If you wish to allow use of your version of this file only\r
+# under the terms of either the GPL or the LGPL, and not to allow others to\r
+# use your version of this file under the terms of the MPL, indicate your\r
+# decision by deleting the provisions above and replace them with the notice\r
+# and other provisions required by the GPL or the LGPL. If you do not delete\r
+# the provisions above, a recipient may use your version of this file under\r
+# the terms of any one of the MPL, the GPL or the LGPL.\r
+# \r
+# REMINDER :\r
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+# IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+# \r
+# EADS Defence and Security - 1 Boulevard Jean Moulin - \r
+# ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+# ***** END LICENSE BLOCK *****\r
+# Strings used in the Mozill AccountManager\r
+prefPanel-ximfmail=XIMF\r
-
-
-<!ENTITY time.midnight "Midnight" >
-<!ENTITY time.1 "1:00 AM" >
-<!ENTITY time.2 "2:00 AM" >
-<!ENTITY time.3 "3:00 AM" >
-<!ENTITY time.4 "4:00 AM" >
-<!ENTITY time.5 "5:00 AM" >
-<!ENTITY time.6 "6:00 AM" >
-<!ENTITY time.7 "7:00 AM" >
-<!ENTITY time.8 "8:00 AM" >
-<!ENTITY time.9 "9:00 AM" >
-<!ENTITY time.10 "10:00 AM" >
-<!ENTITY time.11 "11:00 AM" >
-<!ENTITY time.noon "Noon" >
-<!ENTITY time.13 "1:00 PM" >
-<!ENTITY time.14 "2:00 PM" >
-<!ENTITY time.15 "3:00 PM" >
-<!ENTITY time.16 "4:00 PM" >
-<!ENTITY time.17 "5:00 PM" >
-<!ENTITY time.18 "6:00 PM" >
-<!ENTITY time.19 "7:00 PM" >
-<!ENTITY time.20 "8:00 PM" >
-<!ENTITY time.21 "9:00 PM" >
-<!ENTITY time.22 "10:00 PM" >
-<!ENTITY time.23 "11:00 PM" >
-
-<!ENTITY allDayEvents.label "All Day Events">
-
-<!-- Month Names -->
-<!ENTITY day.1.Ddd "Dim" >
-<!ENTITY day.2.Ddd "Lun" >
-<!ENTITY day.3.Ddd "Mar" >
-<!ENTITY day.4.Ddd "Mer" >
-<!ENTITY day.5.Ddd "Jeu" >
-<!ENTITY day.6.Ddd "Ven" >
-<!ENTITY day.7.Ddd "Sam" >
-
-<!ENTITY day.1.DDD "DIM" >
-<!ENTITY day.2.DDD "LUN" >
-<!ENTITY day.3.DDD "MAR" >
-<!ENTITY day.4.DDD "MAR" >
-<!ENTITY day.5.DDD "JEU" >
-<!ENTITY day.6.DDD "VEN" >
-<!ENTITY day.7.DDD "SAM" >
-
-<!ENTITY day.1.name "Sunday" >
-<!ENTITY day.2.name "Monday" >
-<!ENTITY day.3.name "Tuesday" >
-<!ENTITY day.4.name "Wednesday" >
-<!ENTITY day.5.name "Thursday" >
-<!ENTITY day.6.name "Friday" >
-<!ENTITY day.7.name "Saturday" >
-
-<!ENTITY time.am "AM" >
-<!ENTITY time.pm "PM" >
-<!ENTITY time.midnight "Midnight" >
-<!ENTITY time.noon "Noon" >
-
-
-<!ENTITY month.1.MMM "JAN" >
-<!ENTITY month.2.MMM "FEV" >
-<!ENTITY month.3.MMM "MAR" >
-<!ENTITY month.4.MMM "AVR" >
-<!ENTITY month.5.MMM "MAI" >
-<!ENTITY month.6.MMM "JUN" >
-<!ENTITY month.7.MMM "JUL" >
-<!ENTITY month.8.MMM "AUT" >
-<!ENTITY month.9.MMM "SEP" >
-<!ENTITY month.10.MMM "OCT" >
-<!ENTITY month.11.MMM "NOV" >
-<!ENTITY month.12.MMM "DEC" >
-
-<!ENTITY time.AM "AM" >
-<!ENTITY time.PM "PM" >
-
-<!ENTITY more.label "MORE" >
-<!ENTITY less.label "LESS" >
-<!ENTITY calendar "calendrier">
-
-<!ENTITY hour.label "Heure">
+\r
+\r
+<!ENTITY time.midnight "Midnight" >\r
+<!ENTITY time.1 "1:00 AM" >\r
+<!ENTITY time.2 "2:00 AM" >\r
+<!ENTITY time.3 "3:00 AM" >\r
+<!ENTITY time.4 "4:00 AM" >\r
+<!ENTITY time.5 "5:00 AM" >\r
+<!ENTITY time.6 "6:00 AM" >\r
+<!ENTITY time.7 "7:00 AM" >\r
+<!ENTITY time.8 "8:00 AM" >\r
+<!ENTITY time.9 "9:00 AM" >\r
+<!ENTITY time.10 "10:00 AM" >\r
+<!ENTITY time.11 "11:00 AM" >\r
+<!ENTITY time.noon "Noon" >\r
+<!ENTITY time.13 "1:00 PM" >\r
+<!ENTITY time.14 "2:00 PM" >\r
+<!ENTITY time.15 "3:00 PM" >\r
+<!ENTITY time.16 "4:00 PM" >\r
+<!ENTITY time.17 "5:00 PM" >\r
+<!ENTITY time.18 "6:00 PM" >\r
+<!ENTITY time.19 "7:00 PM" >\r
+<!ENTITY time.20 "8:00 PM" >\r
+<!ENTITY time.21 "9:00 PM" >\r
+<!ENTITY time.22 "10:00 PM" >\r
+<!ENTITY time.23 "11:00 PM" >\r
+\r
+<!ENTITY allDayEvents.label "All Day Events">\r
+\r
+<!-- Month Names -->\r
+<!ENTITY day.1.Ddd "Dim" >\r
+<!ENTITY day.2.Ddd "Lun" >\r
+<!ENTITY day.3.Ddd "Mar" >\r
+<!ENTITY day.4.Ddd "Mer" >\r
+<!ENTITY day.5.Ddd "Jeu" >\r
+<!ENTITY day.6.Ddd "Ven" >\r
+<!ENTITY day.7.Ddd "Sam" >\r
+\r
+<!ENTITY day.1.DDD "DIM" >\r
+<!ENTITY day.2.DDD "LUN" >\r
+<!ENTITY day.3.DDD "MAR" >\r
+<!ENTITY day.4.DDD "MAR" >\r
+<!ENTITY day.5.DDD "JEU" >\r
+<!ENTITY day.6.DDD "VEN" >\r
+<!ENTITY day.7.DDD "SAM" >\r
+\r
+<!ENTITY day.1.name "Sunday" >\r
+<!ENTITY day.2.name "Monday" >\r
+<!ENTITY day.3.name "Tuesday" >\r
+<!ENTITY day.4.name "Wednesday" >\r
+<!ENTITY day.5.name "Thursday" >\r
+<!ENTITY day.6.name "Friday" >\r
+<!ENTITY day.7.name "Saturday" >\r
+\r
+<!ENTITY time.am "AM" >\r
+<!ENTITY time.pm "PM" >\r
+<!ENTITY time.midnight "Midnight" >\r
+<!ENTITY time.noon "Noon" >\r
+\r
+\r
+<!ENTITY month.1.MMM "JAN" >\r
+<!ENTITY month.2.MMM "FEV" >\r
+<!ENTITY month.3.MMM "MAR" >\r
+<!ENTITY month.4.MMM "AVR" >\r
+<!ENTITY month.5.MMM "MAI" >\r
+<!ENTITY month.6.MMM "JUN" >\r
+<!ENTITY month.7.MMM "JUL" >\r
+<!ENTITY month.8.MMM "AUT" >\r
+<!ENTITY month.9.MMM "SEP" >\r
+<!ENTITY month.10.MMM "OCT" >\r
+<!ENTITY month.11.MMM "NOV" >\r
+<!ENTITY month.12.MMM "DEC" >\r
+\r
+<!ENTITY time.AM "AM" >\r
+<!ENTITY time.PM "PM" >\r
+\r
+<!ENTITY more.label "MORE" >\r
+<!ENTITY less.label "LESS" >\r
+<!ENTITY calendar "calendrier">\r
+\r
+<!ENTITY hour.label "Heure">\r
<!ENTITY min.label "Minutes">
\ No newline at end of file
-<!ENTITY ximfmail.accountWizard.pageTitle "Voulez-vous utiliser des en-têtes XIMF?">
-<!ENTITY ximfmail.am.themeChoice "Utiliser une définition d'instances XIMF pour ce compte : ">
-<!ENTITY ximfmail.am.instanceGroup "Instances XIMF">
-<!ENTITY ximfmail.am.instanceGroup.composition "Rédaction">
-<!ENTITY ximfmail.am.instanceGroup.message "Messages">
-<!ENTITY ximfmail.am.instanceComposeChoice "Créer un message avec l'instance : ">
-<!ENTITY ximfmail.am.instanceAnswerChoice "Répondre à un message avec l'instance : ">
-<!ENTITY ximfmail.am.instanceTransferChoice "Transférer un message avec l'instance : ">
-<!ENTITY ximfmail.am.xsmtpCompatibilityCheck "Assurer la compatibilité XSMTP des entêtes XIMF">
-<!ENTITY ximfmail.am.dialogTitle "XIMFMAIL : entêtes de messages">
-<!ENTITY ximfmail.am.description "Utilisation et gestion d'entêtes XIMF">
-<!ENTITY ximfmail.compose.headerTab " ">
-<!ENTITY ximfmail.compose.advancedTab "Avancé">
-<!ENTITY ximfmail.am.instanceGroup.reception "Réception">
-<!ENTITY ximfmail.am.instanceTreeThreadChoice "Trier les entêtes de messages avec l'instance : ">
-<!ENTITY ximfmail.am.instanceMailPanelChoice "Afficher les messages stockés avec l'instance : ">
-<!ENTITY dlgheader.hdrInfo.descr "Sélection courante d'entête XIMF">
-<!ENTITY ximfmail.composer.context.erase "Effacer la derniere valeur">
-<!ENTITY ximfmail.composer.context.eraseall "Effacer toutes les valeurs">
-<!ENTITY ximfmail.composer.context.details "Détailler les valeurs">
-<!ENTITY ximfmail.composer.context.info "Information">
-<!ENTITY ximfmail.compose.focus "Agrandir Alt +">
-<!ENTITY ximfmail.compose.unfocus "Réduire Alt -">
-<!ENTITY treedialog.buttonlabelcancel "Annuler">
-<!ENTITY treedialog.buttonlabelaccept "Sélectionner">
-<!ENTITY ximfmail.am.secureHeadersRuleCheck "Signer les entêtes du message">
-<!ENTITY ximfmail.am.signMsgAlwaysRuleCheck "Signer systématiquement le message">
-<!ENTITY ximfmail.dialogtree.title.col0 "Mot clé">
+<!ENTITY ximfmail.accountWizard.pageTitle "Voulez-vous utiliser des en-têtes XIMF?">\r
+<!ENTITY ximfmail.am.themeChoice "Utiliser une définition d'instances XIMF pour ce compte : ">\r
+<!ENTITY ximfmail.am.instanceGroup "Instances XIMF">\r
+<!ENTITY ximfmail.am.instanceGroup.composition "Rédaction">\r
+<!ENTITY ximfmail.am.instanceGroup.message "Messages">\r
+<!ENTITY ximfmail.am.instanceComposeChoice "Créer un message avec l'instance : ">\r
+<!ENTITY ximfmail.am.instanceAnswerChoice "Répondre à un message avec l'instance : ">\r
+<!ENTITY ximfmail.am.instanceTransferChoice "Transférer un message avec l'instance : ">\r
+<!ENTITY ximfmail.am.xsmtpCompatibilityCheck "Assurer la compatibilité XSMTP des entêtes XIMF">\r
+<!ENTITY ximfmail.am.dialogTitle "XIMFMAIL : entêtes de messages">\r
+<!ENTITY ximfmail.am.description "Utilisation et gestion d'entêtes XIMF">\r
+<!ENTITY ximfmail.compose.headerTab " ">\r
+<!ENTITY ximfmail.compose.advancedTab "Avancé">\r
+<!ENTITY ximfmail.am.instanceGroup.reception "Réception">\r
+<!ENTITY ximfmail.am.instanceTreeThreadChoice "Trier les entêtes de messages avec l'instance : ">\r
+<!ENTITY ximfmail.am.instanceMailPanelChoice "Afficher les messages stockés avec l'instance : ">\r
+<!ENTITY dlgheader.hdrInfo.descr "Sélection courante d'entête XIMF">\r
+<!ENTITY ximfmail.composer.context.erase "Effacer la derniere valeur">\r
+<!ENTITY ximfmail.composer.context.eraseall "Effacer toutes les valeurs">\r
+<!ENTITY ximfmail.composer.context.details "Détailler les valeurs">\r
+<!ENTITY ximfmail.composer.context.info "Information">\r
+<!ENTITY ximfmail.compose.focus "Agrandir Alt +">\r
+<!ENTITY ximfmail.compose.unfocus "Réduire Alt -">\r
+<!ENTITY treedialog.buttonlabelcancel "Annuler"> \r
+<!ENTITY treedialog.buttonlabelaccept "Sélectionner">\r
+<!ENTITY ximfmail.am.secureHeadersRuleCheck "Signer les entêtes du message">\r
+<!ENTITY ximfmail.am.signMsgAlwaysRuleCheck "Signer systématiquement le message">\r
+<!ENTITY ximfmail.dialogtree.title.col0 "Mot clé">\r
<!ENTITY ximfmail.dialogtree.title.col1 "Libellé">
\ No newline at end of file
-# ***** BEGIN LICENSE BLOCK *****
-# Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.
-# ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.
-#
-#
-# Redistribution and use, in source and binary forms, with or without modification,
-# are permitted provided that the following conditons are met :
-#
-# 1. Redistributions of source code must retain the above copyright notice,
-# 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached
-# in the redistribution of the source code.
-# 3. Neither the names of the copyright holders nor the names of any contributors
-# may be used to endorse or promote products derived from this software without specific
-# prior written permission from EADS Defence and Security.
-#
-# Alternatively, the contents of this file may be used under the terms of
-# either of 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.
-#
-# REMINDER :
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
-# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
-# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-# IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
-# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
-# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
-# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
-# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
-# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-#
-# EADS Defence and Security - 1 Boulevard Jean Moulin -
-# ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)
-# ***** END LICENSE BLOCK *****
-label=valeur
-ximfmailAccountWizardDoneInstance=d\u00E9finition XIMF :
-ximfmail.composer.context.erase=Effacer la derni\u00E8re valeur
-ximfmail.composer.context.eraseall=Effacer toutes les valeurs
-ximfmail.composer.context.details=D\u00E9tailler les valeurs
-ximfmail.composer.context.info=Information
-ximfmail.composer.editor.image=Ouvrir l\u0027\u00E9diteur
-ximfmail.composer.treedlg.image=Ouvrir l\u0027outil de donn\u00E9es externes
-ximfmail.composer.calendar.image=Ouvrir le calendrier
-ximfmail.composer.popup.image=Ouvrir le menu
-ximfmail.dialog.editor.warning.nbrows=\u00E9l\u00E9ments au plus seront enregistr\u00E9s
-ximfmail.dialog.editor.warning.nbrows.one=\u00E9l\u00E9ment au plus sera enregistr\u00E9
-ximf-association-alert-label=Des donn\u00e9es saisies vont \u00eatre effac\u00e9es!
-ximfmail.securityinfo.warning=[ximfmail information] le message devrait \u00eatre sign\u00e9 :
-
-
-
+# ***** BEGIN LICENSE BLOCK *****\r
+# Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
+# ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
+# \r
+#\r
+# Redistribution and use, in source and binary forms, with or without modification, \r
+# are permitted provided that the following conditons are met :\r
+#\r
+# 1. Redistributions of source code must retain the above copyright notice, \r
+# 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+# in the redistribution of the source code.\r
+# 3. Neither the names of the copyright holders nor the names of any contributors \r
+# may be used to endorse or promote products derived from this software without specific \r
+# prior written permission from EADS Defence and Security.\r
+# \r
+# Alternatively, the contents of this file may be used under the terms of\r
+# either of the GNU General Public License Version 2 or later (the "GPL"),\r
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
+# in which case the provisions of the GPL or the LGPL are applicable instead\r
+# of those above. If you wish to allow use of your version of this file only\r
+# under the terms of either the GPL or the LGPL, and not to allow others to\r
+# use your version of this file under the terms of the MPL, indicate your\r
+# decision by deleting the provisions above and replace them with the notice\r
+# and other provisions required by the GPL or the LGPL. If you do not delete\r
+# the provisions above, a recipient may use your version of this file under\r
+# the terms of any one of the MPL, the GPL or the LGPL.\r
+# \r
+# REMINDER :\r
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+# IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+# \r
+# EADS Defence and Security - 1 Boulevard Jean Moulin - \r
+# ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+# ***** END LICENSE BLOCK *****\r
+label=valeur\r
+ximfmailAccountWizardDoneInstance=d\u00E9finition XIMF : \r
+ximfmail.composer.context.erase=Effacer la derni\u00E8re valeur\r
+ximfmail.composer.context.eraseall=Effacer toutes les valeurs\r
+ximfmail.composer.context.details=D\u00E9tailler les valeurs\r
+ximfmail.composer.context.info=Information\r
+ximfmail.composer.editor.image=Ouvrir l\u0027\u00E9diteur\r
+ximfmail.composer.treedlg.image=Ouvrir l\u0027outil de donn\u00E9es externes\r
+ximfmail.composer.calendar.image=Ouvrir le calendrier\r
+ximfmail.composer.popup.image=Ouvrir le menu\r
+ximfmail.dialog.editor.warning.nbrows=\u00E9l\u00E9ments au plus seront enregistr\u00E9s\r
+ximfmail.dialog.editor.warning.nbrows.one=\u00E9l\u00E9ment au plus sera enregistr\u00E9\r
+ximf-association-alert-label=Des donn\u00e9es saisies vont \u00eatre effac\u00e9es!\r
+ximfmail.securityinfo.warning=[ximfmail information] le message devrait \u00eatre sign\u00e9 :\r
+\r
+\r
+\r
-
@import url("chrome://global/skin");
datepicker{
padding:5px !important;
background-image : url("chrome://ximfmail/content/resource/bottom_bg.jpg");
}
+#ximfmailMailPanel tabpanels{
+ background-color : -moz-dialog;
+}
.ximfmailFocusBar{
min-height:20px;
+++ /dev/null
-/* ***** BEGIN LICENSE BLOCK *****\r
- * Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
- * ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
- * \r
- *\r
- * Redistribution and use, in source and binary forms, with or without modification, \r
- * are permitted provided that the following conditons are met :\r
- *\r
- * 1. Redistributions of source code must retain the above copyright notice, \r
- * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
- * in the redistribution of the source code.\r
- * 3. Neither the names of the copyright holders nor the names of any contributors \r
- * may be used to endorse or promote products derived from this software without specific \r
- * prior written permission from EADS Defence and Security.\r
- * \r
- * Alternatively, the contents of this file may be used under the terms of\r
- * either of the GNU General Public License Version 2 or later (the "GPL"),\r
- * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
- * in which case the provisions of the GPL or the LGPL are applicable instead\r
- * of those above. If you wish to allow use of your version of this file only\r
- * under the terms of either the GPL or the LGPL, and not to allow others to\r
- * use your version of this file under the terms of the MPL, indicate your\r
- * decision by deleting the provisions above and replace them with the notice\r
- * and other provisions required by the GPL or the LGPL. If you do not delete\r
- * the provisions above, a recipient may use your version of this file under\r
- * the terms of any one of the MPL, the GPL or the LGPL.\r
- * \r
- * REMINDER :\r
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
- * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
- * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
- * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
- * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
- * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
- * \r
- * EADS Defence and Security - 1 Boulevard Jean Moulin - \r
- * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
- * ***** END LICENSE BLOCK ***** */\r
-// components defined in this file\r
-const AM_XIMF_MAIL_EXTENSION_SERVICE_CONTRACTID =\r
- "@mozilla.org/accountmanager/extension;1?name=am-service-ximfmail";\r
-const AM_XIMF_MAIL_EXTENSION_SERVICE_CID =\r
- Components.ID("{E1934208-A30D-4950-8DCE-DCDAB01BDC65}");\r
- \r
- \r
-// interfaces used in this file\r
-const nsIMsgAccountManagerExtension = Components.interfaces.nsIMsgAccountManagerExtension;\r
-const nsICategoryManager = Components.interfaces.nsICategoryManager;\r
-const nsISupports = Components.interfaces.nsISupports;\r
-\r
-function XimfmailPrefService(){}\r
-\r
-XimfmailPrefService.prototype.name = "ximfmail";\r
-XimfmailPrefService.prototype.chromePackageName = "ximfmail"\r
-XimfmailPrefService.prototype.showPanel =\r
-function (server){\r
- // show Ximfmail panel for all account types \r
- return true;\r
-}\r
-\r
-// factory for command line handler service (XimfMailService)\r
-var XimfmailPrefFactory = new Object();\r
-\r
-XimfmailPrefFactory.createInstance =\r
-function (outer, iid) {\r
- if (outer != null)\r
- throw Components.results.NS_ERROR_NO_AGGREGATION;\r
-\r
- if (!iid.equals(nsIMsgAccountManagerExtension) && !iid.equals(nsISupports))\r
- throw Components.results.NS_ERROR_INVALID_ARG;\r
-\r
- return new XimfmailPrefService();\r
-}\r
-\r
-var XimfmailPrefsModule = new Object();\r
-\r
-XimfmailPrefsModule.registerSelf =\r
-function (compMgr, fileSpec, location, type)\r
-{\r
- dump("Registering Ximfmail account manager extension.\n");\r
-\r
- compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);\r
- compMgr.registerFactoryLocation(AM_XIMF_MAIL_EXTENSION_SERVICE_CID,\r
- "Ximfmail Account Manager Extension Service",\r
- AM_XIMF_MAIL_EXTENSION_SERVICE_CONTRACTID,\r
- fileSpec,\r
- location,\r
- type);\r
- catman = Components.classes["@mozilla.org/categorymanager;1"].getService(nsICategoryManager);\r
- catman.addCategoryEntry("mailnews-accountmanager-extensions",\r
- "ximfmail-accountmanager-extension",\r
- AM_XIMF_MAIL_EXTENSION_SERVICE_CONTRACTID, true, true);\r
- dump("Ximfmail account manager extension registered.\n");\r
-}\r
-\r
-XimfmailPrefsModule.unregisterSelf =\r
-function(compMgr, fileSpec, location)\r
-{\r
- compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);\r
- compMgr.unregisterFactoryLocation(AM_XIMF_MAIL_EXTENSION_SERVICE_CID, fileSpec);\r
- catman = Components.classes["@mozilla.org/categorymanager;1"].getService(nsICategoryManager);\r
- catman.deleteCategoryEntry("mailnews-accountmanager-extensions",\r
- AM_XIMF_MAIL_EXTENSION_SERVICE_CONTRACTID, true);\r
-}\r
-\r
-XimfmailPrefsModule.getClassObject =\r
-function (compMgr, cid, iid) {\r
- if (cid.equals(AM_XIMF_MAIL_EXTENSION_SERVICE_CID))\r
- return XimfmailPrefFactory;\r
-\r
-\r
- if (!iid.equals(Components.interfaces.nsIFactory))\r
- throw Components.results.NS_ERROR_NOT_IMPLEMENTED;\r
-\r
- throw Components.results.NS_ERROR_NO_INTERFACE; \r
-}\r
-\r
-XimfmailPrefsModule.canUnload =\r
-function(compMgr)\r
-{\r
- return true;\r
-}\r
-\r
-// entrypoint\r
-function NSGetModule(compMgr, fileSpec) {\r
- return XimfmailPrefsModule;\r
-}
\ No newline at end of file
--- /dev/null
+/* ***** BEGIN LICENSE BLOCK *****\r
+ * Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
+ * ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
+ *\r
+ *\r
+ * Redistribution and use, in source and binary forms, with or without modification,\r
+ * are permitted provided that the following conditons are met :\r
+ *\r
+ * 1. Redistributions of source code must retain the above copyright notice,\r
+ * 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached\r
+ * in the redistribution of the source code.\r
+ * 3. Neither the names of the copyright holders nor the names of any contributors\r
+ * may be used to endorse or promote products derived from this software without specific\r
+ * prior written permission from EADS Defence and Security.\r
+ *\r
+ * Alternatively, the contents of this file may be used under the terms of\r
+ * either of the GNU General Public License Version 2 or later (the "GPL"),\r
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
+ * in which case the provisions of the GPL or the LGPL are applicable instead\r
+ * of those above. If you wish to allow use of your version of this file only\r
+ * under the terms of either the GPL or the LGPL, and not to allow others to\r
+ * use your version of this file under the terms of the MPL, indicate your\r
+ * decision by deleting the provisions above and replace them with the notice\r
+ * and other provisions required by the GPL or the LGPL. If you do not delete\r
+ * the provisions above, a recipient may use your version of this file under\r
+ * the terms of any one of the MPL, the GPL or the LGPL.\r
+ *\r
+ * REMINDER :\r
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND\r
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED\r
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.\r
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,\r
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES\r
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;\r
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,\r
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING\r
+ * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ *\r
+ * EADS Defence and Security - 1 Boulevard Jean Moulin -\r
+ * ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ *\r
+ * Contributor(s):\r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved\r
+ * ***** END LICENSE BLOCK ***** */\r
+// components defined in this file\r
+\r
+Components.utils.import("resource://gre/modules/XPCOMUtils.jsm");\r
+function XimfmailAccountManagerExtension() {}\r
+\r
+XimfmailAccountManagerExtension.prototype = {\r
+ name: "ximfmail",\r
+ chromePackageName: "ximfmail",\r
+ classID: Components.ID("{4B539696-E605-4663-B9E9-CB6D44B6FFEB}"),\r
+ classDescription: "Ximfmail Account Manager Extension Service",\r
+ contractID: "@mozilla.org/accountmanager/extension;1?name=ximfmail",\r
+ _xpcom_categories: [{\r
+ category: "mailnews-accountmanager-extensions"\r
+ // entry: "Enigmail account manager extension",\r
+ // service: false\r
+ }],\r
+ QueryInterface: XPCOMUtils.generateQI([Components.interfaces.nsIMsgAccountManagerExtension]),\r
+ showPanel: function (server)\r
+ {\r
+ // don't show the panel for news, rss, or local accounts\r
+ return (server.type !== "nntp" && server.type !== "rss" &&\r
+ server.type !== "im" && server.type !== "none");\r
+ }\r
+};\r
+\r
+//Create entry point for the module\r
+if (XPCOMUtils.generateNSGetFactory) {\r
+ var NSGetFactory = XPCOMUtils.generateNSGetFactory([XimfmailAccountManagerExtension]);\r
+} else {\r
+ var NSGetModule = XPCOMUtils.generateNSGetModule([XimfmailAccountManagerExtension]);\r
+}\r
+function postModuleRegisterCallback (compMgr, fileSpec, componentsArray) {\r
+ dump("Ximfmail account manager extension registered\n");\r
+}\r
-<?xml version="1.0" encoding="UTF-8" standalone="no"?><RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">\r
- <Description about="urn:mozilla:install-manifest">\r
- <em:name>XIMFMail</em:name>\r
- <em:version>1.8.2</em:version>\r
- <em:id>{A627B834-BD9F-4b3f-9AF5-347B5A570402}</em:id>\r
- <em:description>Xtend Internet Message Format engine</em:description>\r
-\r
- <em:targetApplication>\r
- <!-- Thunderbird -->\r
- <Description>\r
- <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>\r
- <em:minVersion>3.1</em:minVersion>\r
- <em:maxVersion>3.1.*</em:maxVersion>\r
- </Description>\r
- </em:targetApplication>\r
-\r
- <!-- Development team -->\r
- <em:creator>CASSIDIAN - an EADS Company</em:creator>\r
-\r
- <!-- Informations -->\r
- <em:homepageURL>http://www.cassidian.com/cassidian/int/en.html</em:homepageURL>\r
- <em:iconURL>chrome://ximfmail/content/resource/icon-ximfmail.png</em:iconURL>\r
- <em:optionsURL/><em:aboutURL/></Description>\r
-</RDF>
\ No newline at end of file
+<?xml version="1.0"?>\r
+<RDF:RDF xmlns:em="http://www.mozilla.org/2004/em-rdf#"\r
+ xmlns:NC="http://home.netscape.com/NC-rdf#"\r
+ xmlns:RDF="http://www.w3.org/1999/02/22-rdf-syntax-ns#">\r
+ <RDF:Description RDF:about="urn:mozilla:install-manifest"\r
+ em:id="{A627B834-BD9F-4b3f-9AF5-347B5A570402}"\r
+ em:name="XIMFMail"\r
+ em:version="24.3.0.0.1.0"\r
+ em:description="Xtend Internet Message Format engine"\r
+ em:creator="Airbus Defence and Space"\r
+ em:homepageURL="http://www.airbusdefenceandspace.com"\r
+ em:iconURL="chrome://ximfmail/content/resource/icon-ximfmail.png">\r
+ <em:targetApplication>\r
+ <!-- Thunderbird -->\r
+ <Description>\r
+ <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>\r
+ <em:minVersion>24.3.0</em:minVersion>\r
+ <em:maxVersion>24.3.*</em:maxVersion>\r
+ </Description>\r
+ </em:targetApplication>\r
+ </RDF:Description> \r
+</RDF:RDF>
\ No newline at end of file
--- /dev/null
+locale mozapps fr chrome/locale/fr/mozapps/\r
+override chrome://mozapps/locale/downloads/settingsChange.dtd chrome://messenger/locale/downloads/settingsChange.dtd\r
+locale global-region fr chrome/locale/fr/global-region/\r
+locale messenger-mapi fr chrome/locale/fr/messenger-mapi/\r
+locale messenger-smime fr chrome/locale/fr/messenger-smime/\r
+locale necko fr chrome/locale/fr/necko/\r
+locale branding fr chrome/locale/fr/branding/\r
+locale editor fr chrome/locale/fr/editor/\r
+locale global-platform fr chrome/locale/fr/global-platform/\r
+locale messenger-region fr chrome/locale/fr/messenger-region/\r
+locale alerts fr chrome/locale/fr/alerts/\r
+locale global fr chrome/locale/fr/global/\r
+locale messenger fr chrome/locale/fr/messenger/\r
+locale pippki fr chrome/locale/fr/pippki/\r
+locale passwordmgr fr chrome/locale/fr/passwordmgr/\r
+override chrome://global/locale/netError.dtd chrome://messenger/locale/netError.dtd\r
+locale communicator fr chrome/locale/fr/communicator/\r
+locale pipnss fr chrome/locale/fr/pipnss/\r
+locale cookie fr chrome/locale/fr/cookie/\r
+locale places fr chrome/locale/fr/places/\r
+locale autoconfig fr chrome/locale/fr/autoconfig/\r
+locale mozldap fr chrome/locale/fr/mozldap/\r
+locale messenger-newsblog fr chrome/locale/fr/messenger-newsblog/\r
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!ENTITY brandShortName "Trustedbird">
+<!ENTITY brandFullName "Trustedbird">
+<!ENTITY vendorShortName "trustedbird.org">
+<!ENTITY trademarkInfo.part1 "Mozilla Thunderbird et les logos Thunderbird
+ sont des marques déposées de la Mozilla Foundation.">
--- /dev/null
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+brandShortName=Trustedbird
+brandFullName=Trustedbird
+vendorShortName=trustedbird.org
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public\r
+ - License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->\r
+\r
+<!ENTITY props.name.label "Nom :">\r
+<!ENTITY props.value.label "Contenu :">\r
+<!ENTITY props.domain.label "Hôte :">\r
+<!ENTITY props.path.label "Chemin :">\r
+<!ENTITY props.secure.label "Envoi pour :">\r
+<!ENTITY props.expires.label "Expire :">\r
+<!ENTITY props.policy.label "Politique du site :">\r
+\r
+<!ENTITY button.allow.label "Autoriser">\r
+<!ENTITY button.allow.accesskey "A">\r
+<!ENTITY button.session.label "Autoriser durant la session">\r
+<!ENTITY button.session.accesskey "s">\r
+<!ENTITY button.deny.label "Interdire">\r
+<!ENTITY button.deny.accesskey "I">\r
+\r
+<!ENTITY dialog.title "Confirmer les paramètres de cookie">\r
+<!ENTITY dialog.remember.label "Appliquer ce choix pour tous les cookies de ce site">\r
+<!ENTITY dialog.remember.accesskey "A">\r
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!--LOCALIZATION NOTE msgCompSMIMEOverlay.dtd UI for s/mime hooks in message composition -->
+<!ENTITY menu_securityEncryptRequire.label "Chiffrer ce message">
+<!ENTITY menu_securityEncryptRequire.accesskey "r">
+
+<!ENTITY menu_securitySign.label "Signer numériquement ce message">
+<!ENTITY menu_securitySign.accesskey "S">
+
+<!ENTITY menu_securityStatus.label "Voir les informations de sécurité">
+<!ENTITY menu_securityStatus.accesskey "i">
+
+<!ENTITY securityButton.label "Sécurité">
+<!ENTITY securityButton.tooltip "Voir ou modifier les paramètres de sécurité">
+
+<!ENTITY menu_viewSecurityStatus.label "Infos de sécurité du message">
+<!ENTITY menu_viewSecurityStatus.accesskey "I">
+
+<!ENTITY menu_securitySMIMEReceiptRequest.label "Demander un accusé de réception signé">
+<!ENTITY menu_securitySMIMEReceiptRequest.accesskey "D">
+
+<!ENTITY menu_securityLabel.label "Libellé de sécurité...">
+<!ENTITY menu_securityLabel.accesskey "L">
+
+<!ENTITY menu.secureheaders.label "Sécuriser les entêtes">
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!--LOCALIZATION NOTE msgCompSecurityInfo.dtd UI for viewing security status when composing a message -->
+
+<!ENTITY title.label "Sécurité des messages">
+<!ENTITY subject.plaintextWarning "Note : Le champ « Sujet » d'un message n'est jamais chiffré.">
+<!ENTITY status.heading "Le contenu du message sera envoyé de la façon suivante :">
+<!ENTITY status.signed "Signé numériquement :">
+<!ENTITY status.securityLabel "Libellé de sécurité :">
+<!ENTITY status.encrypted "Chiffré :">
+<!ENTITY status.certificates "Certificats :">
+<!ENTITY view.label "Voir">
+<!ENTITY view.accesskey "V">
+<!ENTITY tree.recipient "Destinataire :">
+<!ENTITY tree.status "Statut :">
+<!ENTITY tree.issuedDate "Émis le :">
+<!ENTITY tree.expiresDate "Expire le :">
+<!ENTITY status.signedReceiptRequest "Demande d'accusé signé:">
\ No newline at end of file
--- /dev/null
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+StatusNotFound=Non trouvé
+StatusValid=Valide
+StatusExpired=Expiré
+StatusUntrusted=Non vérifié
+StatusRevoked=Révoqué
+StatusInvalid=Invalide
+StatusYes=Oui
+StatusNo=Non
+StatusNotPossible=Impossible
--- /dev/null
+<!--LOCALIZATION NOTE msgCompSecurityLabelDialog.dtd UI for selecting security label properties when composing a message -->
+
+<!ENTITY securityLabelDialog.name "Libellé de sécurité">
+<!ENTITY securityLabelDialog.securityPolicyIdentifier.name "Politique de sécurité :">
+<!ENTITY securityLabelDialog.securityClassification.name "Classification de sécurité :">
+<!ENTITY securityLabelDialog.privacyMark.name "Marque de confidentialité :">
+<!ENTITY securityLabelDialog.securityCategories.name "Catégories de sécurité :">
+<!ENTITY securityLabelDialog.securityCategories.button.add.name "Ajouter">
+<!ENTITY securityLabelDialog.securityCategories.button.remove.name "Supprimer">
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!--LOCALIZATION NOTE msgReadSMIMEOverlay.dtd UI for s/mime hooks in message reading -->
+
+<!ENTITY menu_securityStatus.label "Infos de sécurité des messages">
+<!ENTITY menu_securityStatus.accesskey "I">
+<!ENTITY securityLabelSecurityClassificationColumn.label "Classification de sécurité">
+<!ENTITY securityLabelSecurityClassificationColumn.tooltip "Cliquez pour trier par classification de sécurité">
--- /dev/null
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ImapOnDemand=Le message actuellement affiché a été signé numériquement, mais toutes ses pièces jointes n'ont pas encore été téléchargées. Ce faisant, la signature ne peut pas être validée. Cliquez sur OK pour télécharger le message complet et valider la signature.
+#
+#NOTE To translater, anything between %..% and <..> should not be translated.
+# the former will be replaced by java script, and the latter is HTML formatting.
+#
+CantDecryptTitle=%brand% ne peut pas déchiffrer ce message
+CantDecryptBody=L'expéditeur a chiffré ce message à votre intention en utilisant un de vos certificats numériques. Cependant, %brand% n'a pas trouvé ce certificat ni la clef privée associée. <br> Les solutions possibles : <br><ul><li>si vous possédez une carte à puce, veuillez l'insérer ;</li><li>si vous avez changé d'ordinateur ou si vous utilisez un nouveau profil pour %brand%, il vous faut restaurer votre certificat et la clef privée depuis une sauvegarde. Les copies de sauvegarde de certificat sont des fichiers dont l'extension est « .p12 ».</li></ul>
+secureinfomsg_default=L\u0027int\u00E9grit\u00E9 du message est corrompue
+secureinfomsgmore_default=Assurez vous que le message provient d\u0027un \u00E9metteur de confiance
+secureinfomsg_ok=L\u0027int\u00E9grit\u00E9 du message est assur\u00E9e
+secureinfomsgmore_ok=
+secureinfomsg_notok=La signature de ce message n\u0027est pas valide
+secureinfomsgmore_notok=plusieurs causes possibles : le contenu du message a \u00E9t\u00E9 modifi\u00E9, la signature a \u00E9t\u00E9 modifi\u00E9e, l\u0027\u00E9metteur du message a pu \u00eatre modifi\u00E9
+secureinfomsg_hdrnok=Un des champs d\u0027ent\u00eate a \u00E9t\u00E9 modifi\u00E9
+secureinfomsg_unsecured=Ce message n\u0027est pas s\u00E9curis\u00E9
+secureinfomsg_hdrwarning=La signature de ce message est valide mais son int\u00E9grit\u00E9 n\u0027est pas compl\u00E8tement assur\u00E9e
+secureinfomsgmore_warning=Selon la configuration des ent\u00eates s\u00E9curis\u00E9s du compte local, certains ent\u00eates devraient \u00eatre sign\u00E9s
+securevalue_warning=Cet ent\u00eate devrait \u00eatre sign\u00E9
\ No newline at end of file
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!--LOCALIZATION NOTE msgReadSecurityInfo.dtd UI for viewing security status when reading a received message -->
+
+<!ENTITY status.label "Sécurité des messages">
+<!ENTITY signatureCert.label "Voir la signature du certificat">
+<!ENTITY encryptionCert.label "Voir le certificat de chiffrement">
+
+<!ENTITY signer.name "Signé par :">
+<!ENTITY recipient.name "Chiffré pour :">
+<!ENTITY email.address "Adresse électronique :">
+<!ENTITY issuer.name "Certificat fourni par :">
+
+<!ENTITY securityLabel.name "Libellé de sécurité">
+<!ENTITY securityLabel.securityPolicyIdentifier.name "Politique de sécurité :">
+<!ENTITY securityLabel.securityClassification.name "Classification de sécurité :">
+<!ENTITY securityLabel.privacyMark.name "Marque de confidentialité :">
+<!ENTITY securityLabel.securityCategories.name "Catégories de sécurité :">
--- /dev/null
+noSigningCertTitle=Impossible d'envoyer un accusé de réception signé
+noSigningCert=Il est nécessaire de paramétrer un ou plusieurs certificats personnels avant d'utiliser cette fonction de sécurité.
\ No newline at end of file
--- /dev/null
+# msgSecurityLabel.js
+unknownSecurityPolicyIdentifier=inconnue
+unknownSecurityClassification=inconnue
+unknownSecurityCategory=inconnue
+# msgCompSecurityLabelDialog.js
+noSecurityPolicyIdentifier=aucune
+noSecurityClassification=aucune
--- /dev/null
+# securityLabel.js\r
+unknownSecurityPolicyIdentifier=unknown\r
+unknownSecurityClassification=unknown\r
+unknownSecurityCategory=unknown\r
+# securityLabelDialog.js\r
+noSecurityPolicyIdentifier=none\r
+noSecurityClassification=none\r
--- /dev/null
+<!--LOCALIZATION NOTE securityLabelTreeColOverlay.dtd UI -->\r
+<!ENTITY securityLabelSecurityClassificationColumn.label "Classification de sécurité">\r
+<!ENTITY securityLabelSecurityClassificationColumn.tooltip "trier par étiquettes de sécurité">\r
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!ENTITY newDirectoryTitle.label "Propriétés du serveur d'annuaire">
+<!ENTITY directoryName.label "Nom :">
+<!ENTITY directoryName.accesskey "n">
+<!ENTITY directoryHostname.label "Nom d'hôte :">
+<!ENTITY directoryHostname.accesskey "o">
+<!ENTITY directoryBaseDN.label "Nom distinct de base :">
+<!ENTITY directoryBaseDN.accesskey "b">
+<!ENTITY findButton.label "Rechercher">
+<!ENTITY findButton.accesskey "h">
+<!ENTITY directorySecure.label "Utiliser une connexion chiffrée (SSL)">
+<!ENTITY directorySecure.accesskey "U">
+<!ENTITY directoryLogin.label "Connecter avec l'utilisateur :">
+<!ENTITY directoryLogin.accesskey "C">
+<!ENTITY General.tab "Général">
+<!ENTITY Offline.tab "Hors connexion">
+<!ENTITY Advanced.tab "Avancé">
+<!ENTITY portNumber.label "Numéro de port :">
+<!ENTITY portNumber.accesskey "p">
+<!ENTITY searchFilter.label "Filtre de recherche :">
+<!ENTITY searchFilter.accesskey "f">
+<!ENTITY scope.label "Étendue :">
+<!ENTITY scope.accesskey "e">
+<!ENTITY scopeOneLevel.label "Un niveau">
+<!ENTITY scopeOneLevel.accesskey "i">
+<!ENTITY scopeSubtree.label "Sous-arbre">
+<!ENTITY scopeSubtree.accesskey "S">
+<!ENTITY return.label "Ne pas retourner plus de">
+<!ENTITY return.accesskey "r">
+<!ENTITY results.label "résultats">
+<!ENTITY offlineText.label "Vous pouvez créer une copie locale de cet annuaire pour pouvoir l'utiliser une fois hors connexion.">
+<!ENTITY saslMechanism.label "Méthode d'identification : ">
+<!ENTITY saslMechanism.accesskey "M">
+<!ENTITY saslOff.label "Simple">
+<!ENTITY saslOff.accesskey "l">
+<!ENTITY saslGSSAPI.label "Kerberos (GSSAPI)">
+<!ENTITY saslGSSAPI.accesskey "K">
+<!ENTITY saslEXTERNAL.label "EXTERNAL">
+<!ENTITY saslEXTERNAL.accesskey "E">
+
+<!-- Localization note: this is here because the width of the dialog
+ is determined by the width of the base DN box; and that is likely
+ to vary somewhat with the language.
+-->
+<!ENTITY newDirectoryWidth "42em">
--- /dev/null
+<!ENTITY pane.title "Eiquettes de sécurité">\r
+<!ENTITY securityLabel.location "Emplacement des labeles dans l'enveloppe tripme">\r
+<!ENTITY securityLabel.bothSignatures "Signature interne et externe">\r
+<!ENTITY securityLabel.innerSignatureOnly "Signature interne uniquement">\r
+<!ENTITY securityLabel.outerSignatureOnly "Signature externe uniquement"
\ No newline at end of file
--- /dev/null
+prefPanel-securitylabel=Etiquettes s\u00E9curit\u00E9\r
+\r
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!-- extracted from am-server-top.xul -->
+
+<!ENTITY messageStorage.label "Stockage des messages">
+<!ENTITY securitySettings.label "Paramètres de sécurité">
+<!ENTITY serverSettings.label "Paramètres du serveur">
+<!ENTITY serverType.label "Type de serveur :">
+<!ENTITY serverName.label "Nom du serveur :">
+<!ENTITY serverName.accesskey "N">
+<!ENTITY userName.label "Nom d'utilisateur :">
+<!ENTITY userName.accesskey "m">
+<!ENTITY port.label "Port :">
+<!ENTITY port.accesskey "P">
+<!ENTITY serverPortDefault.label "Défaut :">
+<!-- LOCALIZATION NOTE (biffStart.label) : translate below 2 line with grammer dependency
+ For example, in Japanese cases:
+ biffStart.label "every"
+ biffEnd.label "minutes for new messages Check"
+-->
+<!ENTITY biffStart.label "Vérifier les nouveaux messages toutes les ">
+<!ENTITY biffStart.accesskey "V">
+<!ENTITY biffEnd.label "minutes">
+<!ENTITY connectionSecurity.label "Sécurité de la connexion :">
+<!ENTITY connectionSecurity.accesskey "S">
+<!ENTITY connectionSecurityType-0.label "Aucune">
+<!ENTITY connectionSecurityType-1.label "STARTTLS, si disponible">
+<!ENTITY connectionSecurityType-2.label "STARTTLS">
+<!ENTITY connectionSecurityType-3.label "SSL/TLS">
+<!ENTITY authMethod.label "Méthode d'authentification :">
+<!ENTITY authMethod.accesskey "i">
+<!ENTITY leaveOnServer.label "Laisser les messages sur le serveur">
+<!ENTITY leaveOnServer.accesskey "g">
+<!ENTITY headersOnly.label "Télécharger uniquement les en-têtes">
+<!ENTITY headersOnly.accesskey "e">
+<!ENTITY deleteByAgeFromServer.label "Pendant au maximum">
+<!ENTITY deleteByAgeFromServer.accesskey "x">
+<!ENTITY daysEnd.label "jours">
+<!ENTITY deleteOnServer2.label "Jusqu'à ce que je les supprime ">
+<!ENTITY deleteOnServer2.accesskey "u">
+<!ENTITY downloadOnBiff.label "Télécharger automatiquement les nouveaux messages">
+<!ENTITY downloadOnBiff.accesskey "m">
+<!ENTITY username.label "Votre nom de connexion">
+<!ENTITY deleteMessagePrefix.label "Lorsque je supprime un message :">
+<!ENTITY modelMoveToTrash.label "le mettre dans ce dossier :">
+<!ENTITY modelMoveToTrash.accesskey "o">
+<!ENTITY modelMarkDeleted.label "le marquer comme supprimé">
+<!ENTITY modelMarkDeleted.accesskey "q">
+<!ENTITY modelDeleteImmediately.label "le supprimer immédiatement">
+<!ENTITY modelDeleteImmediately.accesskey "d">
+<!-- LOCALIZATION NOTE (expungeOnExit.label) : do not translate two of """ in below line -->
+<!ENTITY expungeOnExit.label "Nettoyer le dossier « Courrier entrant » en quittant.">
+<!ENTITY expungeOnExit.accesskey "y">
+<!ENTITY emptyTrashOnExit.label "Vider la corbeille en quittant">
+<!ENTITY emptyTrashOnExit.accesskey "b">
+<!ENTITY loginAtStartup.label "Vérifier le courrier au lancement">
+<!ENTITY loginAtStartup.accesskey "r">
+<!-- LOCALIZATION NOTE (maxMessagesStart.label) : translate below 2 lines with grammar dependency
+ maxMessengerStart.label will be followed by maxMessagesEnd.label with the number
+ of messages between them
+-->
+<!ENTITY maxMessagesStart.label "Me demander avant de télécharger plus de ">
+<!ENTITY maxMessagesStart.accesskey "t">
+<!-- LOCALIZATION NOTE (maxMessagesEnd.label) : see note for maxMessagesStart.label -->
+<!ENTITY maxMessagesEnd.label "messages.">
+<!ENTITY alwaysAuthenticate.label "Toujours demander une authentification lors de la connexion à ce serveur">
+<!ENTITY alwaysAuthenticate.accesskey "j">
+<!ENTITY newsrcFilePath.label "Fichier newsrc :">
+<!ENTITY newsrcPicker.label "Sélectionner un fichier newsrc">
+<!ENTITY abbreviate.label "Afficher les noms des groupes de discussion dans le panneau des dossiers de courrier comme :">
+<!ENTITY abbreviateOn.label "des noms complets (par exemple « mozilla.dev.apps.thunderbird »)">
+<!ENTITY abbreviateOff.label "des noms abrégés (par exemple « m.d.a.thunderbird »)">
+<!ENTITY advancedButton.label "Avancés…">
+<!ENTITY advancedButton.accesskey "s">
+<!ENTITY serverDefaultCharset.label "Encodage de caractères par défaut :">
+<!ENTITY localPath.label "Répertoire local :">
+<!ENTITY localFolderPicker.label "Sélection du répertoire local">
+<!ENTITY browseFolder.label "Parcourir…">
+<!ENTITY browseFolder.accesskey "P">
+<!ENTITY browseNewsrc.label "Parcourir…">
+<!ENTITY browseNewsrc.accesskey "a">
+
+<!ENTITY accountTitle.label "Paramètres du compte">
+<!ENTITY accountSettingsDesc.label "Ce compte est spécial, aucune identité ne lui est associée.">
+
+<!ENTITY externalLogin.label "avec un contrôle d'identité">
+<!ENTITY externalLogin.accesskey "c">
+<!ENTITY authByCert.label "Authentification par certificat, si disponible">
+<!ENTITY authByCert.accesskey "h">
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!ENTITY securityTitle.label "Sécurité">
+<!ENTITY securityTab.label "Sécurité">
+<!ENTITY securityHeading.label "Pour envoyer et recevoir des messages signés ou chiffrés, il est nécessaire de spécifier à la fois un certificat de signature numérique et un certificat de chiffrement.">
+<!ENTITY encryptionGroupTitle.label "Chiffrement">
+<!ENTITY encryptionChoiceLabel.label "Utiliser le chiffrement pour l'envoi des messages :">
+<!ENTITY neverEncrypt.label "Jamais">
+<!ENTITY neverEncrypt.accesskey "J">
+<!ENTITY alwaysEncryptMessage.label "Toujours chiffrer les messages">
+<!ENTITY alwaysEncryptMessage.accesskey "T">
+<!ENTITY encryptionCert.message "Certificat personnel pour chiffrer et déchiffrer les messages envoyés :">
+<!ENTITY digitalSign.certificate.button "Sélectionner un certificat…">
+<!ENTITY digitalSign.certificate.accesskey "S">
+<!ENTITY digitalSign.certificate_clear.button "Effacer">
+<!ENTITY digitalSign.certificate_clear.accesskey "E">
+<!ENTITY encryption.certificate.button "Sélectionner…">
+<!ENTITY encryption.certificate.accesskey "c">
+<!ENTITY encryption.certificate_clear.button "Effacer">
+<!ENTITY encryption.certificate_clear.accesskey "r">
+<!ENTITY signingGroupTitle.label "Signature">
+<!ENTITY signMessage.label "Signer les messages numériquement">
+<!ENTITY signMessage.accesskey "n">
+<!ENTITY signingCert.message "Certificat personnel pour signer numériquement les messages envoyés :">
+<!ENTITY SMIMEReceiptRequest.label "Lors de l'envoi d'un message signé, toujours demander un accusé de réception signé">
+<!ENTITY SMIMEReceiptRequest.accesskey "L">
+<!ENTITY SMIMEReceiptSendPolicy.label "Lors de la réception d'une demande d'accusé de réception signé :">
+<!ENTITY SMIMEReceiptSendPolicy.accesskey "d">
+<!ENTITY SMIMEReceiptSendPolicy.askMe.label "Me demander">
+<!ENTITY SMIMEReceiptSendPolicy.neverSend.label "Ne jamais envoyer">
+<!ENTITY SMIMEReceiptSendPolicy.alwaysSend.label "Toujours envoyer">
+
+<!ENTITY certificates.label "Certificats">
+<!ENTITY manageCerts.label "Afficher les certificats">
+<!ENTITY manageCerts.accesskey "A">
+<!ENTITY manageDevices.label "Périphériques de sécurité">
+<!ENTITY manageDevices.accesskey "P">
+
+<!ENTITY secureHeaderFolderPicker.label "Utiliser ce fichier pour signernumériquement les entêtes des messages envoyés">
+<!ENTITY secureHeaderPath.label "Fichiers des entêtes à sécuriser">
+<!ENTITY browseFolder.label "Parcourir...">
+<!ENTITY browseFolder.accesskey "a">
+<!ENTITY smime.am.infomsg.label "Afficher l'état de sécurité des messages reçus">
\ No newline at end of file
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!ENTITY titledefault.label "&brandFullName;">
+<!ENTITY titleSeparator.label " - ">
+
+<!-- File Menu -->
+<!ENTITY newFolderCmd.label "Dossier…">
+<!ENTITY newFolderCmd.accesskey "D">
+<!ENTITY closeTabCmd2.label "Fermer l'onglet">
+<!ENTITY closeTabCmd2.accesskey "m">
+<!ENTITY closeOtherTabsCmd2.label "Fermer les autres onglets">
+<!ENTITY closeOtherTabsCmd2.accesskey "F">
+<!ENTITY recentlyClosedTabsCmd.label "Onglets récemment fermés">
+<!ENTITY recentlyClosedTabsCmd.accesskey "r">
+
+<!ENTITY undoCloseTabCmd.commandkey "T">
+<!-- LOCALIZATION NOTE (moveToNewWindow.label):
+ Menu option to cause the current tab to be migrated to a new Thunderbird
+ window.
+ -->
+<!ENTITY moveToNewWindow.label "Basculer dans une nouvelle fenêtre">
+<!ENTITY moveToNewWindow.accesskey "B">
+<!ENTITY newVirtualFolderCmd.label "Dossier virtuel…">
+<!ENTITY newVirtualFolderCmd.accesskey "v">
+<!ENTITY newOtherAccountsCmd.label "Autres comptes…">
+<!ENTITY newOtherAccountsCmd.accesskey "m">
+<!ENTITY newCreateEmailAccountCmd.label "Obtenir un nouveau compte courrier…">
+<!ENTITY newCreateEmailAccountCmd.accesskey "b">
+<!ENTITY newExistingEmailAccountCmd.label "Compte courrier existant…">
+<!ENTITY newExistingEmailAccountCmd.accesskey "e">
+<!ENTITY newIMAccountCmd.label "Compte de messagerie instantanée…">
+<!ENTITY newIMAccountCmd.accesskey "C">
+<!ENTITY newFeedAccountCmd.label "Compte de flux…">
+<!ENTITY newFeedAccountCmd.accesskey "d">
+<!ENTITY newIMContactCmd.label "Contact de messagerie instantanée…">
+<!ENTITY newIMContactCmd.accesskey "n">
+<!ENTITY openMessageFileCmd.label "Ouvrir un fichier…">
+<!ENTITY openMessageFileCmd.accesskey "O">
+<!ENTITY saveAsMenu.label "Enregistrer comme">
+<!ENTITY saveAsMenu.accesskey "S">
+<!ENTITY saveAsFileCmd.label "Fichier">
+<!ENTITY saveAsFileCmd.accesskey "F">
+<!ENTITY saveAsFileCmd.key "s">
+<!ENTITY saveAsTemplateCmd.label "Modèle">
+<!ENTITY saveAsTemplateCmd.accesskey "M">
+<!ENTITY getNewMsgForCmd.label "Relever les nouveaux messages pour">
+<!ENTITY getNewMsgForCmd.accesskey "l">
+<!ENTITY getAllNewMsgCmdPopupMenu.label "Tous les comptes">
+<!ENTITY getAllNewMsgCmdPopupMenu.accesskey "T">
+<!ENTITY getNewMsgCurrentAccountCmdPopupMenu.label "Le compte en cours d'utilisation">
+<!ENTITY getNewMsgCurrentAccountCmdPopupMenu.accesskey "L">
+<!ENTITY getNextNMsgCmd.label "Relever les 500 prochains messages">
+<!ENTITY getNextNMsgCmd.accesskey "p">
+<!ENTITY sendUnsentCmd.label "Envoyer les messages en attente">
+<!ENTITY sendUnsentCmd.accesskey "a">
+<!ENTITY subscribeCmd.label "S'abonner…">
+<!ENTITY subscribeCmd.accesskey "b">
+<!ENTITY deleteFolder.label "Supprimer le dossier">
+<!ENTITY deleteFolder.accesskey "d">
+<!ENTITY renameFolder.label "Renommer le dossier…">
+<!ENTITY renameFolder.accesskey "R">
+<!ENTITY renameFolder.key "VK_F2">
+<!ENTITY compactFolders.label "Compacter les dossiers">
+<!ENTITY compactFolders.accesskey "C">
+<!ENTITY emptyTrashCmd.label "Vider la corbeille">
+<!ENTITY emptyTrashCmd.accesskey "V">
+<!ENTITY offlineMenu.label "Hors connexion">
+<!ENTITY offlineMenu.accesskey "H">
+<!ENTITY offlineGoOfflineCmd.label "Travailler hors connexion">
+<!ENTITY offlineGoOfflineCmd.accesskey "h">
+<!ENTITY synchronizeOfflineCmd.label "Synchroniser…">
+<!ENTITY synchronizeOfflineCmd.accesskey "S">
+<!ENTITY settingsOfflineCmd.label "Paramètres hors connexion…">
+<!ENTITY settingsOfflineCmd.accesskey "P">
+<!ENTITY downloadSelectedCmd.label "Relever les messages sélectionnés">
+<!ENTITY downloadSelectedCmd.accesskey "R">
+<!ENTITY downloadStarredCmd.label "Relever les messages suivis">
+<!ENTITY downloadStarredCmd.accesskey "v">
+<!ENTITY printCmd.label "Imprimer…">
+<!ENTITY printCmd.accesskey "p">
+<!ENTITY printCmd.key "p">
+<!ENTITY printPreviewCmd.label "Aperçu avant impression">
+<!ENTITY printPreviewCmd.accesskey "u">
+<!ENTITY printSetupCmd.label "Mise en page…">
+<!ENTITY printSetupCmd.accesskey "g">
+
+<!-- Edit Menu -->
+<!ENTITY deleteMsgCmd.label "Supprimer le message">
+<!ENTITY deleteMsgCmd.accesskey "S">
+<!ENTITY undeleteMsgCmd.label "Restaurer le message">
+<!ENTITY undeleteMsgCmd.accesskey "R">
+<!ENTITY deleteMsgsCmd.label "Supprimer les messages sélectionnés">
+<!ENTITY deleteMsgsCmd.accesskey "S">
+<!ENTITY undeleteMsgsCmd.label "Restaurer les messages sélectionnés">
+<!ENTITY undeleteMsgsCmd.accesskey "R">
+<!ENTITY deleteFolderCmd.label "Supprimer le dossier">
+<!ENTITY deleteFolderCmd.accesskey "d">
+<!ENTITY unsubscribeNewsgroupCmd.label "Se désabonner">
+<!ENTITY unsubscribeNewsgroupCmd.accesskey "n">
+<!ENTITY selectMenu.label "Sélectionner">
+<!ENTITY selectMenu.accesskey "t">
+<!ENTITY all.label "Tout">
+<!ENTITY all.accesskey "T">
+<!ENTITY selectThreadCmd.label "Discussion">
+<!ENTITY selectThreadCmd.accesskey "D">
+<!ENTITY selectThreadCmd.key "a">
+<!ENTITY selectFlaggedCmd.label "Messages suivis">
+<!ENTITY selectFlaggedCmd.accesskey "u">
+<!ENTITY menuFavoriteFolder.label "Dossier préféré">
+<!ENTITY menuFavoriteFolder.accesskey "D">
+<!ENTITY folderPropsCmd.label "Propriétés du dossier">
+<!ENTITY folderPropsFolderCmd.label "Propriétés du dossier…">
+<!ENTITY folderPropsNewsgroupCmd.label "Propriétés du groupe…">
+<!ENTITY folderPropsCmd.accesskey "o">
+<!ENTITY undoDeleteMsgCmd.label "Annuler l'effacement">
+<!ENTITY redoDeleteMsgCmd.label "Restaurer le message effacé">
+<!ENTITY undoMoveMsgCmd.label "Annuler le déplacement de message">
+<!ENTITY redoMoveMsgCmd.label "Rétablir le déplacement de message">
+<!ENTITY undoCopyMsgCmd.label "Annuler la copie de message">
+<!ENTITY redoCopyMsgCmd.label "Rétablir la copie de message">
+<!ENTITY undoMarkAllCmd.label "Annuler le marquage de tous les messages comme lus">
+<!ENTITY redoMarkAllCmd.label "Rétablir le marquage de tous les messages comme lus">
+<!ENTITY undoDefaultCmd.label "Annuler">
+<!ENTITY undoDefaultCmd.accesskey "A">
+<!ENTITY redoDefaultCmd.label "Rétablir">
+<!ENTITY redoDefaultCmd.accesskey "R">
+
+<!-- View Menu -->
+<!ENTITY menubarCmd.label "Barre de menus">
+<!ENTITY menubarCmd.accesskey "m">
+<!ENTITY showMessengerToolbarCmd.label "Barre d'outils courrier">
+<!ENTITY showMessengerToolbarCmd.accesskey "t">
+<!ENTITY customizeToolbar.label "Personnaliser…">
+<!ENTITY customizeToolbar.accesskey "P">
+
+<!ENTITY messagePaneLayoutStyle.label "Disposition">
+<!ENTITY messagePaneLayoutStyle.accesskey "p">
+<!ENTITY messagePaneClassic.label "Classique">
+<!ENTITY messagePaneClassic.accesskey "C">
+<!ENTITY messagePaneWide.label "Large">
+<!ENTITY messagePaneWide.accesskey "L">
+<!ENTITY messagePaneVertical.label "Verticale">
+<!ENTITY messagePaneVertical.accesskey "V">
+<!ENTITY showFolderPaneCmd.label "Panneau des dossiers">
+<!ENTITY showFolderPaneCmd.accesskey "o">
+<!ENTITY showMessageCmd.label "Panneau d'affichage des messages">
+<!ENTITY showMessageCmd.accesskey "n">
+
+<!ENTITY folderView.label "Dossiers">
+<!ENTITY folderView.accesskey "r">
+<!ENTITY unifiedFolders.label "Unifiés">
+<!ENTITY unifiedFolders.accesskey "U">
+<!ENTITY allFolders.label "Tous">
+<!ENTITY allFolders.accesskey "T">
+<!ENTITY unreadFolders.label "Avec des messages non lus">
+<!ENTITY unreadFolders.accesskey "A">
+<!ENTITY favoriteFolders.label "Préférés">
+<!ENTITY favoriteFolders.accesskey "P">
+<!ENTITY recentFolders.label "Récents">
+<!ENTITY recentFolders.accesskey "R">
+
+<!-- Sort Menu -->
+<!ENTITY sortMenu.label "Trier par">
+<!ENTITY sortMenu.accesskey "e">
+<!ENTITY sortByDateCmd.label "Date">
+<!ENTITY sortByDateCmd.accesskey "t">
+<!ENTITY sortByReceivedCmd.label "Reçu">
+<!ENTITY sortByReceivedCmd.accesskey "R">
+<!ENTITY sortByStarCmd.label "Suivi">
+<!ENTITY sortByStarCmd.accesskey "v">
+<!ENTITY sortByAttachmentsCmd.label "Pièces jointes">
+<!ENTITY sortByAttachmentsCmd.accesskey "j">
+<!ENTITY sortByPriorityCmd.label "Priorité">
+<!ENTITY sortByPriorityCmd.accesskey "P">
+<!ENTITY sortBySizeCmd.label "Taille">
+<!ENTITY sortBySizeCmd.accesskey "i">
+<!ENTITY sortByStatusCmd.label "Statut">
+<!ENTITY sortByStatusCmd.accesskey "u">
+<!ENTITY sortByTagsCmd.label "Étiquettes">
+<!ENTITY sortByTagsCmd.accesskey "q">
+<!ENTITY sortByJunkStatusCmd.label "Statut indésirable">
+<!ENTITY sortByJunkStatusCmd.accesskey "b">
+<!ENTITY sortBySubjectCmd.label "Sujet">
+<!ENTITY sortBySubjectCmd.accesskey "S">
+<!ENTITY sortByFromCmd.label "Expéditeur">
+<!ENTITY sortByFromCmd.accesskey "x">
+<!ENTITY sortByRecipientCmd.label "Destinataire">
+<!ENTITY sortByRecipientCmd.accesskey "D">
+<!ENTITY sortByUnreadCmd.label "Lu">
+<!ENTITY sortByUnreadCmd.accesskey "L">
+<!ENTITY sortByOrderReceivedCmd.label "Ordre de réception">
+<!ENTITY sortByOrderReceivedCmd.accesskey "O">
+<!ENTITY sortAscending.label "Ordre croissant">
+<!ENTITY sortAscending.accesskey "a">
+<!ENTITY sortDescending.label "Ordre décroissant">
+<!ENTITY sortDescending.accesskey "n">
+<!ENTITY sortThreaded.label "Discussions groupées">
+<!ENTITY sortThreaded.accesskey "c">
+<!ENTITY sortUnthreaded.label "Discussions non groupées">
+<!ENTITY sortUnthreaded.accesskey "g">
+<!ENTITY groupBySort.label "Groupées par critère de tri">
+<!ENTITY groupBySort.accesskey "e">
+<!ENTITY msgsMenu.label "Message">
+<!ENTITY msgsMenu.accesskey "M">
+<!ENTITY threads.label "Discussions">
+<!ENTITY threads.accesskey "D">
+<!ENTITY allMsgsCmd.label "Toutes">
+<!ENTITY allMsgsCmd.accesskey "T">
+<!ENTITY expandAllThreadsCmd.label "Développer toutes les discussions">
+<!ENTITY expandAllThreadsCmd.accesskey "D">
+<!ENTITY expandAllThreadsCmd.key "*">
+<!ENTITY collapseAllThreadsCmd.label "Réduire toutes les discussions">
+<!ENTITY collapseAllThreadsCmd.accesskey "R">
+<!ENTITY collapseAllThreadsCmd.key "\">
+<!ENTITY unreadMsgsCmd.label "Non lues">
+<!ENTITY unreadMsgsCmd.accesskey "N">
+<!ENTITY threadsWithUnreadCmd.label "Avec des messages non lus">
+<!ENTITY threadsWithUnreadCmd.accesskey "A">
+<!ENTITY watchedThreadsWithUnreadCmd.label "Surveillées avec des messages non lus">
+<!ENTITY watchedThreadsWithUnreadCmd.accesskey "S">
+<!ENTITY ignoredThreadsCmd.label "Ignorées">
+<!ENTITY ignoredThreadsCmd.accesskey "I">
+
+<!ENTITY headersMenu.label "En-têtes">
+<!ENTITY headersMenu.accesskey "t">
+<!ENTITY headersAllCmd.label "Complets">
+<!ENTITY headersAllCmd.accesskey "C">
+<!ENTITY headersNormalCmd.label "Normaux">
+<!ENTITY headersNormalCmd.accesskey "N">
+<!ENTITY bodyMenu.label "Corps du message en">
+<!ENTITY bodyMenu.accesskey "o">
+<!ENTITY bodyAllowHTML.label "HTML original">
+<!ENTITY bodyAllowHTML.accesskey "H">
+<!ENTITY bodySanitized.label "HTML simple">
+<!ENTITY bodySanitized.accesskey "s">
+<!ENTITY bodyAsPlaintext.label "Texte seul">
+<!ENTITY bodyAsPlaintext.accesskey "x">
+<!ENTITY bodyAllParts.label "Tous les éléments">
+<!ENTITY bodyAllParts.accesskey "T">
+
+<!ENTITY bodyMenuFeed.label "Corps de message du flux">
+<!ENTITY bodyMenuFeed.accesskey "C">
+<!ENTITY viewFeedWebPage.label "Page web">
+<!ENTITY viewFeedWebPage.accesskey "W">
+<!ENTITY viewFeedSummary.label "Résumé">
+<!ENTITY viewFeedSummary.accesskey "R">
+<!ENTITY viewFeedSummaryFeedPropsPref.label "Format par défaut">
+<!ENTITY viewFeedSummaryFeedPropsPref.accesskey "F">
+
+<!ENTITY viewAttachmentsInlineCmd.label "Afficher les pièces jointes dans les messages">
+<!ENTITY viewAttachmentsInlineCmd.accesskey "A">
+
+<!ENTITY pageSourceCmd.label "Code source du message">
+<!ENTITY pageSourceCmd.accesskey "s">
+<!ENTITY pageSourceCmd.key "u">
+<!ENTITY getNewMessagesCmd.key "y">
+<!ENTITY getAllNewMessagesCmd.key "Y">
+
+<!-- Search Menu -->
+<!ENTITY findMenu.label "Rechercher">
+<!ENTITY findMenu.accesskey "h">
+<!ENTITY findCmd.label "Rechercher…">
+<!ENTITY findCmd.accesskey "R">
+<!ENTITY findCmd.key "f">
+<!ENTITY findAgainCmd.label "Rechercher le suivant">
+<!ENTITY findAgainCmd.accesskey "v">
+<!ENTITY findAgainCmd.key "g">
+<!ENTITY findAgainCmd.key2 "VK_F3">
+<!ENTITY findPrevCmd.key "g">
+<!ENTITY findPrevCmd.key2 "VK_F3">
+<!ENTITY searchMailCmd.label "Rechercher dans le courrier">
+<!ENTITY searchMailCmd.accesskey "c">
+<!ENTITY searchMailCmd.key "f">
+<!ENTITY searchAddressesCmd.label "Rechercher dans les adresses…">
+<!ENTITY searchAddressesCmd.accesskey "a">
+
+<!-- Go Menu -->
+<!ENTITY goMenu.label "Aller à">
+<!ENTITY goMenu.accesskey "l">
+<!ENTITY nextMenu.label "Prochain">
+<!ENTITY nextMenu.accesskey "P">
+<!ENTITY nextMsgCmd.label "Message">
+<!ENTITY nextMsgCmd.accesskey "m">
+<!ENTITY nextMsgCmd.key "f">
+<!ENTITY nextUnreadMsgCmd.label "Message non lu">
+<!ENTITY nextUnreadMsgCmd.accesskey "n">
+<!ENTITY nextUnreadMsgCmd.key "n">
+<!ENTITY nextStarredMsgCmd.label "Message suivi">
+<!ENTITY nextStarredMsgCmd.accesskey "v">
+<!ENTITY nextUnreadThread.label "Discussion non lue">
+<!ENTITY nextUnreadThread.accesskey "s">
+<!ENTITY nextUnreadThread.key "t">
+<!ENTITY prevMenu.label "Précédent">
+<!ENTITY prevMenu.accesskey "r">
+<!ENTITY prevMsgCmd.label "Message">
+<!ENTITY prevMsgCmd.accesskey "M">
+<!ENTITY prevMsgCmd.key "b">
+<!ENTITY prevUnreadMsgCmd.label "Message non lu">
+<!ENTITY prevUnreadMsgCmd.accesskey "n">
+<!ENTITY prevUnreadMsgCmd.key "p">
+<!ENTITY goForwardCmd.label "Suivant">
+<!ENTITY goForwardCmd.accesskey "S">
+<!ENTITY goForwardCmd.commandKey "]">
+<!ENTITY goBackCmd.label "Précédent">
+<!ENTITY goBackCmd.accesskey "c">
+<!ENTITY goBackCmd.commandKey "[">
+<!ENTITY goChatCmd.label "Chat">
+<!ENTITY goChatCmd.accesskey "h">
+<!ENTITY goChatCmd.key "I">
+<!ENTITY prevStarredMsgCmd.label "Message suivi">
+<!ENTITY prevStarredMsgCmd.accesskey "v">
+<!ENTITY folderMenu.label "Dossier">
+<!ENTITY folderMenu.accesskey "o">
+<!ENTITY thisFolder.label "Ce dossier">
+<!ENTITY thisFolder.accesskey "C">
+<!ENTITY goRecentlyClosedTabs.label "Onglets récemment fermés">
+<!ENTITY goRecentlyClosedTabs.accesskey "r">
+<!ENTITY startPageCmd.label "Page de démarrage">
+<!ENTITY startPageCmd.accesskey "g">
+
+<!-- Message Menu -->
+<!ENTITY msgMenu.label "Messages">
+<!ENTITY msgMenu.accesskey "M">
+<!ENTITY newMsgCmd.label "Nouveau message">
+<!ENTITY newMsgCmd.accesskey "N">
+<!ENTITY newNewMsgCmd.label "Message">
+<!ENTITY newNewMsgCmd.accesskey "M">
+<!ENTITY archiveMsgCmd.label "Archiver">
+<!ENTITY archiveMsgCmd.accesskey "A">
+<!ENTITY archiveMsgCmd.key "a">
+<!ENTITY cancelNewsMsgCmd.label "Annuler le message">
+<!ENTITY cancelNewsMsgCmd.accesskey "A">
+<!ENTITY replyMsgCmd.label "Répondre">
+<!ENTITY replyMsgCmd.accesskey "R">
+<!ENTITY replyMsgCmd.key "r">
+<!ENTITY replySenderCmd.label "Répondre à l'exp. seulement">
+<!ENTITY replySenderCmd.accesskey "R">
+<!ENTITY replyNewsgroupCmd2.label "Faire suivre au groupe">
+<!ENTITY replyNewsgroupCmd2.accesskey "g">
+<!ENTITY replyToAllMsgCmd.label "Répondre à tous">
+<!ENTITY replyToAllMsgCmd.accesskey "t">
+<!ENTITY replyToAllMsgCmd.key "r">
+<!ENTITY replyToListMsgCmd.label "Répondre à la liste">
+<!ENTITY replyToListMsgCmd.accesskey "o">
+<!ENTITY replyToListMsgCmd.key "l">
+<!ENTITY forwardMsgCmd.label "Transférer">
+<!ENTITY forwardMsgCmd.accesskey "f">
+<!ENTITY forwardMsgCmd.key "l">
+<!ENTITY forwardAsMenu.label "Transférer au format">
+<!ENTITY forwardAsMenu.accesskey "s">
+<!ENTITY forwardAsInline.label "Intégré">
+<!ENTITY forwardAsInline.accesskey "I">
+<!ENTITY forwardAsAttachmentCmd.label "Pièce jointe">
+<!ENTITY forwardAsAttachmentCmd.accesskey "P">
+<!ENTITY editMsgAsNewCmd.label "Modifier comme un nouveau message">
+<!ENTITY editMsgAsNewCmd.accesskey "e">
+<!ENTITY editMsgAsNewCmd.key "e">
+<!ENTITY createFilter.label "Créer un filtre à partir du message…">
+<!ENTITY createFilter.accesskey "i">
+<!ENTITY moveMsgToMenu.label "Déplacer le message vers">
+<!ENTITY moveMsgToMenu.accesskey "D">
+<!ENTITY moveCopyMsgRecentMenu.label "Récent">
+<!ENTITY moveCopyMsgRecentMenu.accesskey "R">
+<!ENTITY copyMessageLocation.label "Copier l'adresse du message">
+<!ENTITY copyMessageLocation.accesskey "m">
+<!ENTITY copyMsgToMenu.label "Copier le message vers">
+<!ENTITY copyMsgToMenu.accesskey "C">
+<!ENTITY moveToFolderAgain.label "Déplacer à nouveau">
+<!ENTITY moveToFolderAgain.accesskey "v">
+<!ENTITY moveToFolderAgainCmd.key "m">
+<!ENTITY killThreadMenu.label "Ignorer la discussion">
+<!ENTITY killThreadMenu.accesskey "I">
+<!ENTITY killThreadMenu.key "k">
+<!ENTITY killSubthreadMenu.label "Ignorer les sous-fils de discussion">
+<!ENTITY killSubthreadMenu.accesskey "n">
+<!ENTITY killSubthreadMenu.key "k">
+<!ENTITY watchThreadMenu.label "Surveiller la discussion">
+<!ENTITY watchThreadMenu.accesskey "S">
+<!ENTITY watchThreadMenu.key "w">
+<!ENTITY fileHereMenu.label "Classer ici">
+<!ENTITY fileHereMenu.accesskey "a">
+<!ENTITY copyHereMenu.label "Copier ici">
+<!ENTITY copyHereMenu.accesskey "C">
+<!ENTITY tagMenu.label "Étiquette">
+<!ENTITY tagMenu.accesskey "q">
+<!ENTITY tagCmd0.key "0">
+<!ENTITY tagCmd1.key "1">
+<!ENTITY tagCmd2.key "2">
+<!ENTITY tagCmd3.key "3">
+<!ENTITY tagCmd4.key "4">
+<!ENTITY tagCmd5.key "5">
+<!ENTITY tagCmd6.key "6">
+<!ENTITY tagCmd7.key "7">
+<!ENTITY tagCmd8.key "8">
+<!ENTITY tagCmd9.key "9">
+<!ENTITY markMenu.label "Marquer">
+<!ENTITY markMenu.accesskey "a">
+<!ENTITY toggleReadCmd.key "m">
+<!ENTITY markAsReadCmd.label "Comme lu">
+<!ENTITY markAsReadCmd.accesskey "l">
+<!ENTITY markAsUnreadCmd.label "Comme non lu">
+<!ENTITY markAsUnreadCmd.accesskey "m">
+<!ENTITY markThreadAsReadCmd.label "La discussion comme lue">
+<!ENTITY markThreadAsReadCmd.accesskey "d">
+<!ENTITY markThreadAsReadCmd.key "r">
+<!ENTITY markReadByDateCmd.label "Comme lus par date…">
+<!ENTITY markReadByDateCmd.accesskey "t">
+<!ENTITY markReadByDateCmd.key "c">
+<!ENTITY markAllReadCmd.label "Tous les messages comme lus">
+<!ENTITY markAllReadCmd.accesskey "g">
+<!ENTITY markAllReadCmd.key "c">
+<!ENTITY markStarredCmd.label "Ajouter un suivi">
+<!ENTITY markStarredCmd.accesskey "v">
+<!ENTITY markStarredCmd.key "S">
+<!ENTITY markAsJunkCmd.label "Comme indésirable">
+<!ENTITY markAsJunkCmd.accesskey "i">
+<!ENTITY markAsJunkCmd.key "j">
+<!ENTITY markAsNotJunkCmd.label "Comme acceptable">
+<!ENTITY markAsNotJunkCmd.accesskey "a">
+<!ENTITY markAsNotJunkCmd.key "j">
+<!ENTITY recalculateJunkScoreCmd.label "Lancer le contrôle des indésirables">
+<!ENTITY recalculateJunkScoreCmd.accesskey "s">
+<!ENTITY openMessageWindowCmd.label "Ouvrir le message">
+<!ENTITY openMessageWindowCmd.accesskey "O">
+<!ENTITY openMessageWindowCmd.key "o">
+<!ENTITY openConversationCmd.label "Ouvrir dans la discussion">
+<!ENTITY openConversationCmd.accesskey "u">
+<!ENTITY openConversationCmd.key "o">
+<!ENTITY openAttachmentListCmd.label "Pièces jointes">
+<!ENTITY openAttachmentListCmd.accesskey "j">
+<!ENTITY openFeedMessage1.label "À l'ouverture des messages de flux">
+<!ENTITY openFeedMessage1.accesskey "x">
+<!ENTITY openFeedWebPage.label "Ouvrir en tant que page web">
+<!ENTITY openFeedWebPage.accesskey "w">
+<!ENTITY openFeedSummary.label "Ouvrir en tant que résumé">
+<!ENTITY openFeedSummary.accesskey "t">
+<!ENTITY openFeedWebPageInMP.label "Basculer entre page web et résumé dans le panneau de message">
+<!ENTITY openFeedWebPageInMP.accesskey "B">
+
+<!-- Windows Menu -->
+<!ENTITY windowMenu.label "Fenêtre">
+
+<!-- Tools Menu -->
+<!ENTITY tasksMenu.label "Outils">
+<!ENTITY tasksMenu.accesskey "O">
+<!ENTITY messengerCmd.label "Courrier et groupes">
+<!ENTITY messengerCmd.accesskey "g">
+<!ENTITY addressBookCmd.label "Carnet d'adresses">
+<!ENTITY addressBookCmd.accesskey "a">
+<!ENTITY addressBookCmd.key "B">
+<!ENTITY addons.label "Modules complémentaires">
+<!ENTITY addons.accesskey "c">
+<!ENTITY activitymanager.label "Activités">
+<!ENTITY activitymanager.accesskey "v">
+<!ENTITY imAccountsStatus.label "État de messagerie instantanée">
+<!ENTITY imAccountsStatus.accesskey "d">
+<!ENTITY imStatus.available "Disponible">
+<!ENTITY imStatus.unavailable "Occupé">
+<!ENTITY imStatus.offline "Déconnecté">
+<!ENTITY imStatus.showAccounts "Afficher les comptes…">
+<!ENTITY joinChatCmd.label "Rejoindre la discussion…">
+<!ENTITY joinChatCmd.accesskey "o">
+<!ENTITY savedFiles.label "Fichiers enregistrés">
+<!ENTITY savedFiles.accesskey "F">
+<!ENTITY savedFiles.key "j">
+<!ENTITY filtersCmd.label "Filtres de messages…">
+<!ENTITY filtersCmd.accesskey "t">
+<!ENTITY filtersApply.label "Appliquer les filtres sur le dossier">
+<!ENTITY filtersApply.accesskey "l">
+<!ENTITY filtersApplyToSelection.label "Appliquer les filtres sur les messages sélectionnés">
+<!ENTITY filtersApplyToSelection.accesskey "A">
+<!ENTITY filtersApplyToMessage.label "Appliquer les filtres sur le message">
+<!ENTITY filtersApplyToMessage.accesskey "m">
+<!ENTITY runJunkControls.label "Traquer les indésirables dans le dossier">
+<!ENTITY runJunkControls.accesskey "q">
+<!ENTITY deleteJunk.label "Supprimer les indésirables de ce dossier">
+<!ENTITY deleteJunk.accesskey "e">
+<!ENTITY importCmd.label "Importer…">
+<!ENTITY importCmd.accesskey "I">
+<!ENTITY errorConsoleCmd.label "Console d'erreurs">
+<!ENTITY errorConsoleCmd.accesskey "s">
+<!ENTITY errorConsoleCmd.commandkey "j">
+<!ENTITY clearRecentHistory.label "Supprimer l'historique récent…">
+<!ENTITY clearRecentHistory.accesskey "h">
+<!ENTITY accountManagerCmd.label "Paramètres des comptes…">
+<!ENTITY accountManagerCmd.accesskey "m">
+<!-- LOCALIZATION NOTE (accountManagerCmdUnix.accesskey): belongs to accountManagerCmd.label,
+ which is placed under the Edit menu on Unix systems -->
+<!ENTITY accountManagerCmdUnix.accesskey "a">
+<!ENTITY allowRemoteDebugging.label "Autoriser le débogage distant">
+<!ENTITY allowRemoteDebugging.accesskey "g">
+
+<!-- Mail Toolbar -->
+<!ENTITY getMsgButton.label "Relever">
+<!ENTITY newMsgButton.label "Écrire">
+<!ENTITY replyButton.label "Répondre">
+<!ENTITY replyAllButton.label "Rép. à tous">
+<!ENTITY replyListButton.label "Rép. à la liste">
+<!ENTITY forwardButton.label "Transférer">
+<!ENTITY fileButton.label "Classer">
+<!ENTITY archiveButton.label "Archiver">
+<!ENTITY nextButton.label "Suivant">
+<!ENTITY nextButtonToolbarItem.label "Non lu suivant">
+<!ENTITY nextMsgButton.label "Suivant">
+<!ENTITY previousButton.label "Précédent">
+<!ENTITY previousButtonToolbarItem.label "Non lu précédent">
+<!ENTITY previousMsgButton.label "Précédent">
+<!ENTITY backButton1.label "Reculer">
+<!ENTITY goForwardButton1.label "Avancer">
+<!ENTITY deleteItem.title "Supprimer">
+<!ENTITY deleteButton.label "Supprimer">
+<!ENTITY undeleteButton.label "Restaurer">
+<!ENTITY markButton.label "Marquer">
+<!ENTITY printButton.label "Imprimer">
+<!ENTITY stopButton.label "Arrêter">
+<!ENTITY throbberItem.title "Indicateur d'activité">
+<!ENTITY junkItem.title "Indésirable">
+<!ENTITY junkButton.label "Indésirable">
+<!ENTITY notJunkButton.label "Acceptable">
+<!ENTITY addressBookButton.label "Adresses">
+<!ENTITY chatButton.label "Chat">
+<!ENTITY glodaSearch.title "Recherche globale">
+<!ENTITY searchItem.title "Recherche rapide">
+<!ENTITY mailViewsToolbarItem.title "Vues de courrier">
+<!ENTITY folderLocationToolbarItem.title "Emplacement du dossier">
+<!ENTITY tagButton.label "Étiquette">
+<!ENTITY compactButton.label "Compacter">
+<!ENTITY appmenuButton.label "Menu de l'application">
+
+<!-- Mail Toolbar Tooltips-->
+<!ENTITY advancedButton.tooltip "Rechercher dans les messages…">
+<!ENTITY getMsgButton.tooltip "Relever les nouveaux messages">
+<!ENTITY getAllNewMsgCmd.label "Relever tous les nouveaux messages">
+<!ENTITY getAllNewMsgCmd.accesskey "l">
+<!ENTITY newMsgButton.tooltip "Créer un nouveau message">
+<!ENTITY replyButton.tooltip "Répondre au message">
+<!ENTITY replyAllButton.tooltip "Répondre à l'expéditeur et à tous les destinataires">
+<!ENTITY replyListButton.tooltip "Répondre à la liste de diffusion">
+<!ENTITY forwardButton.tooltip "Transférer le message sélectionné">
+<!ENTITY forwardAsInline.tooltip "Transférer le message sélectionné au format intégré">
+<!ENTITY forwardAsAttachment.tooltip "Transférer le message sélectionné au format pièce jointe">
+<!ENTITY fileButton.tooltip "Classer les messages sélectionnés">
+<!ENTITY archiveButton.tooltip "Archiver les messages sélectionnés">
+<!ENTITY nextButton.tooltip "Aller au prochain message non lu">
+<!ENTITY nextMsgButton.tooltip "Aller au prochain message">
+<!ENTITY goForwardButton.tooltip "Avancer d'un message">
+<!ENTITY goBackButton.tooltip "Reculer d'un message">
+<!ENTITY previousButton.tooltip "Aller au précédent message non lu">
+<!ENTITY previousMsgButton.tooltip "Aller au précédent message">
+<!ENTITY deleteButton.tooltip "Supprimer le message ou le dossier sélectionné">
+<!ENTITY undeleteButton.tooltip "Restaurer le message sélectionné">
+<!ENTITY markButton.tooltip "Marquer les messages">
+<!ENTITY printButton.tooltip "Imprimer ce message">
+<!ENTITY stopButton.tooltip "Arrêter le transfert courant">
+<!ENTITY junkButton.tooltip "Marquer les messages sélectionnés comme indésirables">
+<!ENTITY notJunkButton.tooltip "Marquer les messages sélectionnés comme acceptables">
+<!ENTITY addressBookButton.tooltip "Ouvrir le carnet d'adresses">
+<!ENTITY chatButton.tooltip "Afficher l'onglet de messagerie instantanée">
+<!ENTITY tagButton.tooltip "Étiqueter les messages">
+<!ENTITY compactButton.tooltip "Retirer les messages supprimés du dossier sélectionné">
+<!ENTITY appmenuButton1.tooltip "Afficher le menu de &brandShortName;">
+
+<!-- Toolbar Button Popup -->
+<!ENTITY buttonMenuForwardAsInline.label "Transférer au format intégré">
+<!ENTITY buttonMenuForwardAsAttachment.label "Transférer au format pièce jointe">
+
+<!-- AppMenu Popup -->
+<!ENTITY appmenuNewMsgCmd.label "Nouveau message">
+<!ENTITY appmenuNewContactCmd.label "Contact du carnet d'adresses…">
+<!ENTITY appmenuEditMenu.label "Éditer">
+<!ENTITY appmenuQFBMenu.label "Barre de filtre rapide">
+<!ENTITY appmenuToolbarLayout.label "Personnaliser les barres d'outils…">
+<!ENTITY appmenuSelectThread.label "Sélectionner la discussion">
+<!ENTITY appmenuSelectFlagged.label "Sélectionner les messages suivis">
+
+<!-- Tags Menu Popup -->
+<!ENTITY addNewTag.label "Nouvelle étiquette…">
+<!ENTITY addNewTag.accesskey "N">
+<!ENTITY manageTags.label "Gérer les étiquettes…">
+<!ENTITY manageTags.accesskey "G">
+
+<!-- Folder Pane -->
+<!ENTITY folderColumn.label "Nom">
+<!ENTITY folderSizeColumn.label "Taille">
+
+<!-- Folder Pane Context Menu -->
+<!ENTITY folderContextGetMessages.label "Relever les nouveaux messages">
+<!ENTITY folderContextGetMessages.accesskey "R">
+<!ENTITY folderContextOpenInNewWindow.label "Ouvrir dans une nouvelle fenêtre">
+<!ENTITY folderContextOpenInNewWindow.accesskey "O">
+<!ENTITY folderContextOpenNewTab.label "Ouvrir dans un nouvel onglet">
+<!ENTITY folderContextOpenNewTab.accesskey "u">
+<!ENTITY folderContextNew.label "Nouveau sous-dossier…">
+<!ENTITY folderContextNew.accesskey "v">
+<!ENTITY folderContextRename.label "Renommer">
+<!ENTITY folderContextRename.accesskey "R">
+<!ENTITY folderContextRemove.label "Supprimer">
+<!ENTITY folderContextRemove.accesskey "e">
+<!ENTITY folderContextCompact.label "Compacter">
+<!ENTITY folderContextCompact.accesskey "p">
+<!ENTITY folderContextEmptyTrash.label "Vider cette corbeille maintenant">
+<!ENTITY folderContextEmptyTrash.accesskey "V">
+<!ENTITY folderContextEmptyJunk.label "Vider le dossier des indésirables">
+<!ENTITY folderContextEmptyJunk.accesskey "s">
+<!ENTITY folderContextSendUnsentMessages.label "Envoyer les messages non envoyés">
+<!ENTITY folderContextSendUnsentMessages.accesskey "n">
+<!ENTITY folderContextUnsubscribe.label "Se désabonner du groupe…">
+<!ENTITY folderContextUnsubscribe.accesskey "u">
+<!ENTITY folderContextMarkNewsgroupRead.label "Marquer le groupe comme lu">
+<!ENTITY folderContextMarkNewsgroupRead.accesskey "q">
+<!ENTITY folderContextMarkMailFolderRead.label "Marquer le dossier comme lu">
+<!ENTITY folderContextMarkMailFolderRead.accesskey "d">
+<!ENTITY folderContextSubscribe.label "S'abonner…">
+<!ENTITY folderContextSubscribe.accesskey "b">
+<!ENTITY folderContextSearchForMessages.label "Rechercher dans les messages…">
+<!ENTITY folderContextSearchForMessages.accesskey "c">
+<!ENTITY folderContextProperties.label "Propriétés…">
+<!ENTITY folderContextProperties.accesskey "t">
+<!ENTITY folderContextFavoriteFolder.label "Dossier préféré">
+<!ENTITY folderContextFavoriteFolder.accesskey "f">
+<!ENTITY folderContextSettings.label "Paramètres…">
+<!ENTITY folderContextSettings.accesskey "a">
+
+<!-- Search Bar -->
+<!ENTITY SearchNameOrEmail.label "Le nom ou le message contient :">
+<!ENTITY SearchNameOrEmail.accesskey "n">
+
+<!-- Gloda Search Bar -->
+<!ENTITY glodaSearchBar.placeholder "Recherche dans les messages…">
+
+<!-- Quick Search Menu Bar -->
+<!ENTITY searchSubjectMenu.label "Sujet">
+<!ENTITY searchFromMenu.label "Expéditeur">
+<!ENTITY searchSubjectOrFromMenu.label "Sujet ou Expéditeur">
+<!ENTITY searchRecipient.label "Pour ou Copie à">
+<!ENTITY searchSubjectOrRecipientMenu.label "Sujet, Pour ou Copie à">
+<!ENTITY searchMessageBody.label "Message complet">
+<!ENTITY saveAsVirtualFolderMenu.label "Enregistrer la recherche comme dossier…">
+
+<!-- Thread Pane -->
+<!ENTITY threadColumn.label "Discussion">
+<!ENTITY fromColumn.label "Expéditeur">
+<!ENTITY recipientColumn.label "Destinataire">
+<!ENTITY subjectColumn.label "Sujet">
+<!ENTITY dateColumn.label "Date">
+<!ENTITY priorityColumn.label "Priorité">
+<!ENTITY tagsColumn.label "Étiquettes">
+<!ENTITY accountColumn.label "Compte">
+<!ENTITY statusColumn.label "Statut">
+<!ENTITY sizeColumn.label "Taille">
+<!ENTITY junkStatusColumn.label "Statut indésirable">
+<!ENTITY unreadColumn.label "Non lu">
+<!ENTITY totalColumn.label "Total">
+<!ENTITY readColumn.label "Lu">
+<!ENTITY receivedColumn.label "Reçu">
+<!ENTITY starredColumn.label "Suivi">
+<!ENTITY locationColumn.label "Emplacement">
+<!ENTITY idColumn.label "Ordre de réception">
+<!ENTITY attachmentColumn.label "Pièces jointes">
+
+<!-- Thread Pane Tooltips -->
+<!ENTITY columnChooser.tooltip "Choisir les colonnes à afficher">
+<!ENTITY threadColumn.tooltip "Afficher les fils de discussion">
+<!ENTITY fromColumn.tooltip "Trier par expéditeur">
+<!ENTITY recipientColumn.tooltip "Trier par destinataire">
+<!ENTITY subjectColumn.tooltip "Trier par sujet">
+<!ENTITY dateColumn.tooltip "Trier par date">
+<!ENTITY priorityColumn.tooltip "Trier par priorité">
+<!ENTITY tagsColumn.tooltip "Trier par étiquettes">
+<!ENTITY accountColumn.tooltip "Trier par compte">
+<!ENTITY statusColumn.tooltip "Trier par statut">
+<!ENTITY sizeColumn.tooltip "Trier par taille">
+<!ENTITY junkStatusColumn.tooltip "Trier par statut indésirable">
+<!ENTITY unreadColumn.tooltip "Nombre de messages non lus dans le fil">
+<!ENTITY totalColumn.tooltip "Nombre total de messages dans le fil">
+<!ENTITY readColumn.tooltip "Trier par statut de lecture">
+<!ENTITY receivedColumn.tooltip "Trier par date de réception">
+<!ENTITY starredColumn.tooltip "Trier par suivi">
+<!ENTITY locationColumn.tooltip "Trier par adresse">
+<!ENTITY idColumn.tooltip "Trier par ordre de réception">
+<!ENTITY attachmentColumn.tooltip "Trier par pièces jointes">
+
+<!-- Thread Pane Context Menu -->
+<!ENTITY contextOpenNewWindow.label "Ouvrir dans une nouvelle fenêtre">
+<!ENTITY contextOpenNewWindow.accesskey "n">
+<!-- The key potentially conflicts with cutCmd.accessKey which is defined in
+ textcontext.dtd from toolkit. Right now, both menu items can't be visible
+ at the same time, but should someone enable copy/paste of message, this key
+ would probably need to be changed. -->
+<!ENTITY contextOpenNewTab.label "Ouvrir dans un nouvel onglet">
+<!ENTITY contextOpenNewTab.accesskey "u">
+<!ENTITY contextOpenConversation.label "Ouvrir le message dans la discussion">
+<!ENTITY contextOpenConversation.accesskey "v">
+<!ENTITY contextEditAsNew.label "Modifier comme un nouveau message…">
+<!ENTITY contextEditAsNew.accesskey "e">
+<!ENTITY contextArchive.label "Archiver">
+<!ENTITY contextArchive.accesskey "h">
+<!ENTITY contextReplySender.label "Répondre à l'expéditeur">
+<!ENTITY contextReplySender.accesskey "R">
+<!ENTITY contextReplyNewsgroup2.label "Faire suivre au groupe">
+<!ENTITY contextReplyNewsgroup2.accesskey "g">
+<!ENTITY contextReplyAll.label "Répondre à tout le monde">
+<!ENTITY contextReplyAll.accesskey "t">
+<!ENTITY contextReplyList.label "Répondre à la liste">
+<!ENTITY contextReplyList.accesskey "l">
+<!ENTITY contextForward.label "Transférer">
+<!ENTITY contextForward.accesskey "f">
+<!ENTITY contextForwardAsMenu.label "Transférer au format">
+<!ENTITY contextForwardAsMenu.accesskey "n">
+<!ENTITY contextForwardAsInline.label "Intégré">
+<!ENTITY contextForwardAsInline.accesskey "I">
+<!ENTITY contextForwardAsAttachmentItem.label "Pièce jointe">
+<!ENTITY contextForwardAsAttachmentItem.accesskey "P">
+<!ENTITY contextMultiForwardAsAttachment.label "Transférer au format pièce jointe">
+<!ENTITY contextMultiForwardAsAttachment.accesskey "p">
+<!ENTITY contextMoveMsgMenu.label "Déplacer vers">
+<!ENTITY contextMoveMsgMenu.accesskey "D">
+<!ENTITY contextMoveCopyMsgRecentMenu.label "Récent">
+<!ENTITY contextMoveCopyMsgRecentMenu.accesskey "R">
+<!ENTITY contextCopyMsgMenu.label "Copier vers">
+<!ENTITY contextCopyMsgMenu.accesskey "c">
+<!ENTITY contextKillThreadMenu.label "Ignorer le sujet">
+<!ENTITY contextKillThreadMenu.accesskey "I">
+<!ENTITY contextKillSubthreadMenu.label "Ignorer le sous-sujet">
+<!ENTITY contextWatchThreadMenu.label "Surveiller le sujet">
+<!ENTITY contextSaveAs.label "Enregistrer comme…">
+<!ENTITY contextSaveAs.accesskey "s">
+<!ENTITY contextPrint.label "Imprimer…">
+<!ENTITY contextPrint.accesskey "p">
+<!ENTITY contextPrintPreview.label "Aperçu avant impression">
+<!ENTITY contextPrintPreview.accesskey "o">
+
+<!-- Thread Pane Column Picker -->
+<!-- LOCALIZATION NOTE (columnPicker.resetToInbox.label):
+ This option in the thread pane column picker causes us to reset the
+ customizations for the thread pane columns in this folder to their default.
+ -->
+<!ENTITY columnPicker.resetToInbox.label "Réinitialiser">
+<!-- LOCALIZATION NOTE (columnPicker.applyTo.label):
+ This option in the thread pane column picker pops up a sub-menu containing
+ the "columnPicker.applyToFolder.label" and
+ "columnPicker.applyToFolderAndChildren.label" options. This item indicates
+ a desire to apply the currently displayed set of columns to some other
+ folder(s). The sub-menu items indicate whether we want to apply it to just
+ a folder or also its children.
+ -->
+<!ENTITY columnPicker.applyTo.label "Appliquer ces paramètres à…">
+<!-- LOCALIZATION NOTE (columnPicker.applyToFolder.label):
+ This option in the thread pane column picker is found on a sub-menu beneath
+ the "columnPicker.applyTo.label" alongside
+ "columnPicker.applyToFolderAndChildren.label". It indicates a desire to
+ apply the currently display thread pane column settings to a single folder
+ that the user selects using the same widget as the move to/copy to
+ mechanism (via a series of popups).
+ -->
+<!ENTITY columnPicker.applyToFolder.label "Dossier…">
+<!-- LOCALIZATION NOTE (columnPicker.applyToFolderAndChildren.label):
+ This option in the thread pane column picker is found on a sub-menu beneath
+ the "columnPicker.applyTo.label" alongside
+ "columnPicker.applyToFolder.label". It indicates a desire to
+ apply the currently display thread pane column settings to a folder and all
+ of its descendents. The user selects the folder using the same widget as the
+ move to/copy to mechanism (via a series of popups).
+ -->
+<!ENTITY columnPicker.applyToFolderAndChildren.label "Dossier et sous-dossiers…">
+<!-- LOCALIZATION NOTE (columnPicker.thisFolder.label):
+ This is used in the folder selection widget for the
+ "columnPicker.applyToFolder.label" and
+ "columnPicker.applyToFolderAndChildren.label" menu options. Whenever
+ a folder has children, it results in a menu popup; the first menu item
+ in that popup is given this label to indicate that that folder should be
+ selected. For example, if folder "A" has two children, "B" and "C", then
+ when the user hovers over "A", a new popup menu will be displayed whose
+ items are "This folder", "B", and "C". This is the equivalent of the
+ "File here" option for the move to/copy to widge.t
+ -->
+<!ENTITY columnPicker.thisFolder.label "Ce dossier">
+
+<!-- Media (video/audio) controls -->
+<!ENTITY contextPlay.label "Lire">
+<!ENTITY contextPlay.accesskey "L">
+<!ENTITY contextPause.label "Pause">
+<!ENTITY contextPause.accesskey "P">
+<!ENTITY contextMute.label "Muet">
+<!ENTITY contextMute.accesskey "u">
+<!ENTITY contextUnmute.label "Audible">
+<!ENTITY contextUnmute.accesskey "A">
+
+<!-- junk bar -->
+<!ENTITY junkBarMessage2.label "&brandShortName; pense que ce message est indésirable.">
+<!ENTITY junkBarButton1.label "Acceptable">
+<!ENTITY junkInfoButton.label "?">
+
+<!-- Remote Content Bar -->
+<!ENTITY remoteContentMessage2.label "Afin de protéger votre vie privée, les contenus distants ont été bloqués.">
+<!ENTITY loadRemoteContentButton3.label "Afficher les contenus maintenant">
+
+<!-- Phishing bar Bar -->
+<!ENTITY phishingBarMessage2.label "Ce message est peut-être frauduleux.">
+<!ENTITY removePhishingBarButton1.label "Ignorer l'avertissement">
+<!ENTITY disablePhishingWarning1.label "Désactiver la détection de courrier frauduleux pour tous les messages">
+<!ENTITY reportPhishingError1.label "Ce message ne semble pas être frauduleux">
+
+<!-- MDN Bar -->
+<!ENTITY mdnBarMessage.label "L'auteur de ce message a souhaité être prévenu lorsque vous lirez ce message. Souhaitez-vous avertir l'expéditeur ?">
+<!ENTITY mdnBarIgnoreButton.label "Ignorer">
+<!ENTITY mdnBarSendButton.label "Envoyer l'accusé de réception">
+<!ENTITY mdnBarIgnoreButton2.label "Ignorer">
+<!ENTITY mdnBarIgnoreButton2.accesskey "I">
+<!ENTITY mdnBarSendButton2.label "Envoyer l'accusé de réception">
+<!ENTITY mdnBarSendButton2.accesskey "E">
+
+<!-- S/MIME Receipt Request Bar -->
+<!ENTITY SMIMEReceiptRequestBarMessage.label "L'auteur de ce message a souhaité être prévenu avec un accusé de réception signé lorsque vous lirez ce message. Souhaitez-vous avertir l'expéditeur ?">
+<!ENTITY SMIMEReceiptRequestBarIgnoreButton.label "Ignorer">
+<!ENTITY SMIMEReceiptRequestBarSendButton.label "Envoyer l'accusé de réception signé">
+
+<!-- S/MIME Receipt Bar -->
+<!ENTITY SMIMEReceiptVerifiedBarMessage.label "Ce message est un accusé de réception signé valide qui a été vérifié avec le message que vous avez envoyé.">
+<!ENTITY SMIMEReceiptBarOpenMessageButton.label "Afficher le message envoyé">
+<!ENTITY SMIMEReceiptNotVerifiedBarMessage.label "Ce message est un accusé de réception signé valide mais il n'a PAS été vérifié avec le message que vous avez envoyé car celui-ci n'a pas été trouvé ou n'a pas été lu.">
+
+<!-- Quick Search Bar -->
+<!-- LOCALIZATION NOTE (quickSearchCmd.key):
+ This is actually the key used for the global message search box; we have
+ not changed
+ -->
+<!ENTITY quickSearchCmd.key "k">
+<!-- LOCALIZATION NOTE (search.label.base):
+ This is the base of the empty text for the global search box. We replace
+ #1 with the contents of the appropriate search.keyLabel.* value for the
+ platform.
+ The goal is to convey to the user that typing in the box will allow them
+ to search for messages globally and that there is a hotkey they can press
+ to get to the box faster. If the global indexer is disabled, the search
+ box will be collapsed and the user will never see this message.
+ -->
+<!ENTITY search.label.base "Rechercher… #1">
+<!-- LOCALIZATION NOTE (search.keyLabel.nonmac):
+ The description of the key-binding to get into the global search box on
+ windows and linux (which use the control key). We use the key defined in
+ the quickSearchCmd.key entity defined above, the letter should match it.
+ -->
+<!ENTITY search.keyLabel.nonmac "<Ctrl+K>">
+<!-- LOCALIZATION NOTE (search.keyLabel.mac):
+ The description of the key-binding to get into the global search box on mac
+ systems. We use the key defined in the quickSearchCmd.key entity defined
+ above, the letter should match it.
+ -->
+<!ENTITY search.keyLabel.mac "<⌘K>">
+
+<!-- Message Header Context Menu -->
+<!ENTITY AddToAddressBook.label "Ajouter l'adresse au carnet d'adresses">
+<!ENTITY AddToAddressBook.accesskey "j">
+<!ENTITY AddDirectlyToAddressBook.label "Ajouter au carnet d'adresses">
+<!ENTITY AddDirectlyToAddressBook.accesskey "o">
+<!ENTITY EditContact.label "Modifier le contact…">
+<!ENTITY EditContact.accesskey "M">
+<!ENTITY ViewContact.label "Afficher le contact">
+<!ENTITY ViewContact.accesskey "A">
+<!ENTITY SubscribeToNewsgroup.label "S'abonner à un groupe de discussion">
+<!ENTITY SubscribeToNewsgroup.accesskey "N">
+<!ENTITY SendMessageTo.label "Envoyer un message à">
+<!ENTITY SendMessageTo.accesskey "y">
+<!ENTITY CopyEmailAddress.label "Copier l'adresse électronique">
+<!ENTITY CopyEmailAddress.accesskey "C">
+<!ENTITY CopyNewsgroupName.label "Copier le nom du groupe de discussion">
+<!ENTITY CopyNewsgroupName.accesskey "g">
+<!ENTITY CopyNewsgroupURL.label "Copier l'adresse du groupe de discussion">
+<!ENTITY CopyNewsgroupURL.accesskey "d">
+<!ENTITY CreateFilterFrom.label "Créer un filtre…">
+<!ENTITY CreateFilterFrom.accesskey "f">
+<!ENTITY reportPhishingURL.label "Signaler un courrier frauduleux">
+<!ENTITY reportPhishingURL.accesskey "S">
+
+<!-- Spell checker context menu items -->
+<!ENTITY spellAddDictionaries.label "Add Dictionaries…">
+<!ENTITY spellAddDictionaries.accesskey "A">
+
+<!-- Content Pane Context Menu -->
+<!ENTITY saveLinkAsCmd.label "Enregistrer le lien sous…">
+<!ENTITY saveLinkAsCmd.accesskey "e">
+<!ENTITY saveImageAsCmd.label "Enregistrer l'image sous…">
+<!ENTITY saveImageAsCmd.accesskey "a">
+<!ENTITY copyLinkCmd.label "Copier l'adresse du lien">
+<!ENTITY copyLinkCmd.accesskey "n">
+<!ENTITY copyImageAllCmd.label "Copier l'image">
+<!ENTITY copyImageAllCmd.accesskey "m">
+<!ENTITY copyEmailCmd.label "Copier l'adresse électronique">
+<!ENTITY copyEmailCmd.accesskey "e">
+<!ENTITY stopCmd.label "Arrêter">
+<!ENTITY stopCmd.accesskey "r">
+<!ENTITY reloadCmd.label "Actualiser">
+<!ENTITY reloadCmd.accesskey "c">
+<!ENTITY openInBrowser.label "Ouvrir dans le navigateur">
+<!ENTITY openInBrowser.accesskey "n">
+<!ENTITY openLinkInBrowser.label "Ouvrir le lien dans le navigateur">
+<!ENTITY openLinkInBrowser.accesskey "a">
+
+<!-- Statusbar -->
+<!ENTITY statusText.label "Chargé">
+
+<!-- Mac OS X Window Menu -->
+<!ENTITY minimizeWindow.label "Réduire">
+<!ENTITY minimizeWindow.key "m">
+<!ENTITY bringAllToFront.label "Tout amener à l'avant-plan">
+<!ENTITY zoomWindow.label "Zoom">
+
+<!-- Mac OS X Application Menu (Cocoa widgets) -->
+<!ENTITY preferencesCmdMac.label "Préférences…">
+<!ENTITY preferencesCmdMac.commandkey ",">
+<!ENTITY preferencesCmdMac.modifiers "accel">
+<!ENTITY servicesMenuMac.label "Services">
+<!ENTITY hideThisAppCmdMac.label "Masquer &brandShortName;">
+<!ENTITY hideThisAppCmdMac.commandkey "H">
+<!ENTITY hideThisAppCmdMac.modifiers "accel">
+<!ENTITY hideOtherAppsCmdMac.label "Masquer les autres">
+<!ENTITY hideOtherAppsCmdMac.commandkey "H">
+<!ENTITY hideOtherAppsCmdMac.modifiers "accel,alt">
+<!ENTITY showAllAppsCmdMac.label "Tout afficher">
--- /dev/null
+<!ENTITY secureHeaders.name "Entêtes Sécurisés">\r
+<!ENTITY secureHeaders.field "Entêtes Sécurisés :">\r
+<!ENTITY secureHeadersView.label "Voir Les Entêtes Sécurisés">\r
+<!ENTITY secureHeadersList.label "Listes Des Entêtes Sécurisés">\r
+<!ENTITY headername.label "Entête">\r
+<!ENTITY headervalue.label "Valeur signée">\r
+<!ENTITY headerstatus.label "Statut">\r
+<!ENTITY headerencrypted.label "Chiffré">\r
+<!ENTITY headermimevalue.label "Valeur affichée">\r
+<!ENTITY headercanonisation.label "Canonicalisation">\r
--- /dev/null
+menu.secureheaders.label=S\u00E9curiser les ent\u00EAtes\r
+secureInfo.secureheaders.label=Ent\u00EAtes S\u00E9curis\u00E9s\r
+secureheaders.label=Ent\u00EAtes S\u00E9curis\u00E9s :\r
+yes.label=Oui\r
+no.label=Non\r
+notdefine.label=Non defini\r
+headerstatus.deleted.label=Supprim\u00E9\r
+headerstatus.duplicated.label=Dupliqu\u00E9\r
+headerstatus.modified.label=Modifi\u00E9\r
+headersecure.valid.label=Ent\u00EAtes valide\r
+headersecure.invalid.label=Ent\u00EAtes modifi\u00E9\r
+allsecureheaders.valid.label=L\u0027 int\u00E9grit\u00E9 des ent\u00EAtes est v\u00E9rifi\u00E9e\r
+allsecureheaders.invalid.label=Les ent\u00EAtes ont \u00E9t\u00E9 modifi\u00E9s\r
+headercanoniz.simple.label=Simple\r
+headercanoniz.relaxed.label=Relach\u00E9
\ No newline at end of file
--- /dev/null
+pref("general.useragent.locale", "fr");\r
--- /dev/null
+<?xml version="1.0"?>\r
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:em="http://www.mozilla.org/2004/em-rdf#">\r
+ <rdf:Description about="urn:mozilla:install-manifest">\r
+\r
+ <em:id>trustedbird24.3.0_l10n_fr@trustedbird.org</em:id>\r
+ <em:name>Trustedbird 24.3.0 French Language Pack</em:name>\r
+ <em:version>24.3.0</em:version>\r
+ <em:creator>L'équipe FrenchMozilla</em:creator>\r
+\r
+ <em:type>2</em:type>\r
+ <em:homepageURL>http://www.trustedbird.org/</em:homepageURL>\r
+ <em:contributor>Frédéric Chateaux</em:contributor><em:contributor>Cédric Corazza</em:contributor><em:contributor>Philippe Dessante</em:contributor><em:contributor>Benoît Leseul</em:contributor>\r
+ <em:contributor>Trustedbird/Milimail project</em:contributor>\r
+\r
+ <em:homepageURL>http://www.trustedbird.org/</em:homepageURL>\r
+\r
+ <em:updateURL>http://packages.trustedbird.org/updates/trustedbird17ESR-l10n-fr/update.rdf</em:updateURL>\r
+ <em:updateKey>updates disabled</em:updateKey>\r
+\r
+ <em:targetApplication>\r
+ <rdf:Description>\r
+ <!-- Thunderbird (only with Trustedbird) -->\r
+ <em:id>{3550f703-e582-4d05-9a08-453d09bdfdc6}</em:id>\r
+ <em:minVersion>24.3.0</em:minVersion>\r
+ <em:maxVersion>24.3.*</em:maxVersion>\r
+ </rdf:Description>\r
+ </em:targetApplication>\r
+\r
+ <em:description>French Language Pack for Trustedbird.</em:description>\r
+ </rdf:Description>\r
+</rdf:RDF>\r
thunderbird3.1.source.version.file.name = version-192.txt
thunderbird3.1.source.patch.path = trustedbird-patch-source-3.1
+thunderbird24.source.file.name = thunderbird-24.3.0.source.tar.bz2
+thunderbird24.source.file.sha1sum = 9660b6b4870ca2ff6e2543a50d9bec02b569b1df
+thunderbird24.source.directory = comm-esr24
+thunderbird24.source.dist.directory = mozilla/dist
+thunderbird24.source.version.file.name = version.txt
+thunderbird24.source.patch.path = trustedbird-patch-source-24
# List of add-ons to build with the 'package-addons' target (add the special packages "all-addons-tb2" and "all-addons-tb30" at the end in order to build the meta-packages)
addon.list = card-viewer-extended,check-recipients,crl-over-ldap,directoryContactTabsEngine,directoryContactTabsData-template,directoryContactTabsData-sample,dsn-settings,mailXFormsEngine,mailXFormsData-template,mailXFormsData-sample,mdn-extended,multi-ldap,notification-viewer,out-of-office,send-format-ldap,trustedbird2-l10n-fr,trustedbird3.1-l10n-fr,ximfmail,ximfmail-company,xsmtp,all-addons-tb2,all-addons-tb30
--- /dev/null
+# Trustedbird Configuration File
+mk_add_options MOZ_OBJDIR=@TOPSRCDIR@/obj-trustedbird
+ac_add_options --enable-application=mail
+ac_add_options --enable-optimize
+ac_add_options --disable-debug
+ac_add_options --disable-tests
--- /dev/null
+trustedbird (24.3.0.0.1.0)
+ * Upgrade to Thunderbird 24.3.0
+--06 Mai 2014
+
+trustedbird (3.1.15+0.5.3)
+ * Upgrade to Thunderbird 3.1.15
+
+trustedbird (3.1.14+0.5.3)
+ * Corrective on blocking TrustedBird on downloading messages with big attachments
+ * Correctives on security informations of signed messages function
+
+trustedbird (3.1.14+0.5.1)
+ * Upgrade to Thunderbird 3.1.14
+ * Changes on SecureHeader policy
+-- Sep 12 2011
+
+trustedbird (3.1.10+0.5.1)
+ * Upgrade to Thunderbird 3.1.10
+ *
+-- Mar 08 2011
+
+trustedbird (3.1.9+0.4.3)
+ * Upgrade to Thunderbird 3.1.9
+-- Mar 08 2011
+
+trustedbird (3.1.8+0.4.3)
+ * Upgrade to Thunderbird 3.1.8
+-- Mar 03 2011
+
+trustedbird (3.1.7+0.4.3)
+ * Upgrade to Thunderbird 3.1.7
+ * Add SASL external (IMAPS - LDAPS)
+ * Add Secured Headers (based on RFC 5652)
+-- Feb 23 2011
+
+trustedbird (3.1.7+0.2.0)
+ * Upgrade to Thunderbird 3.1.7
+-- Dec 13 2010
+
+trustedbird (3.1.6+0.4.0)
+ * Upgrade to Thunderbird 3.1.6
+ * Add LDAPS
+-- Nov 24 2010
+
+trustedbird (3.1.6+0.2.0)
+ * Upgrade to Thunderbird 3.1.6
+-- Nov 4 2010
+
+trustedbird (3.1.5+0.3.0)
+ * Add SASL external
+ * Add Secured Headers (based on RFC 5652)
+ * Add XIMFMAIL
+-- 28 Oct 2010
+
+trustedbird (3.1.5+0.2.0)
+ * Upgrade to Thunderbird 3.1.5
+-- Oct 20 2010
+
+trustedbird (3.1.4+0.2.0)
+ * Add S/MIME security labels (RFC 2634)
+-- Sep 20 2010
+
+trustedbird (3.1.4+0.1.0)
+ * Upgrade to Thunderbird 3.1.4
+-- Sep 17 2010
+
+trustedbird (3.1.3+0.1.0)
+ * Upgrade to Thunderbird 3.1.3
+-- Sep 10 2010
+
+trustedbird (3.1.2+0.1.0)
+ * Add S/MIME signed receipts (RFC 2634)
+-- Aug 30 2010
+
+trustedbird (3.1.2+0.0.1)
+ * Upgrade to Thunderbird 3.1.2
+-- Aug 17 2010
+
+trustedbird (3.1.1+0.0.1)
+ * Upgrade to Thunderbird 3.1.1
+-- Jul 29 2010
+
+trustedbird (3.1.0+0.0.1)
+ * Thunderbird 3.1 rebranding
+-- Jul 12 2010
--- /dev/null
+/* ***** 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 "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 Communicator client code, released
+ * March 31, 1998.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 1998-1999
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Copyright (c) 2010 CASSIDIAN - All rights reserved
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+#include "ldap-int.h"
+
+#ifdef LDAP_SASLIO_HOOKS
+/*
+ * Global SASL Init data
+ */
+
+static int
+nsldapi_sasl_fail()
+{
+ return( SASL_FAIL );
+}
+
+sasl_callback_t client_callbacks[] = {
+ { SASL_CB_GETOPT, nsldapi_sasl_fail, NULL },
+ { SASL_CB_GETREALM, NULL, NULL },
+ { SASL_CB_USER, NULL, NULL },
+ { SASL_CB_CANON_USER, NULL, NULL },
+ { SASL_CB_AUTHNAME, NULL, NULL },
+ { SASL_CB_PASS, NULL, NULL },
+ { SASL_CB_ECHOPROMPT, NULL, NULL },
+ { SASL_CB_NOECHOPROMPT, NULL, NULL },
+ { SASL_CB_LIST_END, NULL, NULL }
+};
+
+int
+nsldapi_sasl_cvterrno( LDAP *ld, int err, char *msg )
+{
+ int rc = LDAP_LOCAL_ERROR;
+
+ switch (err) {
+ case SASL_OK:
+ rc = LDAP_SUCCESS;
+ break;
+ case SASL_NOMECH:
+ rc = LDAP_AUTH_UNKNOWN;
+ break;
+ case SASL_BADSERV:
+ rc = LDAP_CONNECT_ERROR;
+ break;
+ case SASL_DISABLED:
+ case SASL_ENCRYPT:
+ case SASL_EXPIRED:
+ case SASL_NOUSERPASS:
+ case SASL_NOVERIFY:
+ case SASL_PWLOCK:
+ case SASL_TOOWEAK:
+ case SASL_UNAVAIL:
+ case SASL_WEAKPASS:
+ rc = LDAP_INAPPROPRIATE_AUTH;
+ break;
+ case SASL_BADAUTH:
+ case SASL_NOAUTHZ:
+ rc = LDAP_INVALID_CREDENTIALS;
+ break;
+ case SASL_NOMEM:
+ rc = LDAP_NO_MEMORY;
+ break;
+ case SASL_NOUSER:
+ rc = LDAP_NO_SUCH_OBJECT;
+ break;
+ case SASL_CONTINUE:
+ case SASL_FAIL:
+ case SASL_INTERACT:
+ default:
+ rc = LDAP_LOCAL_ERROR;
+ break;
+ }
+
+ LDAP_SET_LDERRNO( ld, rc, NULL, msg );
+ return( rc );
+}
+
+#ifdef LDAP_SASLIO_GET_MECHS_FROM_SERVER
+/*
+ * Get available SASL Mechanisms supported by the server
+ */
+
+static int
+nsldapi_get_sasl_mechs ( LDAP *ld, char **pmech )
+{
+ char *attr[] = { "supportedSASLMechanisms", NULL };
+ char **values, **v, *mech, *m;
+ LDAPMessage *res, *e;
+ struct timeval timeout;
+ int slen, rc;
+
+ if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
+ return( LDAP_PARAM_ERROR );
+ }
+
+ timeout.tv_sec = SEARCH_TIMEOUT_SECS;
+ timeout.tv_usec = 0;
+
+ rc = ldap_search_st( ld, "", LDAP_SCOPE_BASE,
+ "objectclass=*", attr, 0, &timeout, &res );
+
+ if ( rc != LDAP_SUCCESS ) {
+ return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
+ }
+
+ e = ldap_first_entry( ld, res );
+ if ( e == NULL ) {
+ ldap_msgfree( res );
+ if ( ld->ld_errno == LDAP_SUCCESS ) {
+ LDAP_SET_LDERRNO( ld, LDAP_NO_SUCH_OBJECT, NULL, NULL );
+ }
+ return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
+ }
+
+ values = ldap_get_values( ld, e, "supportedSASLMechanisms" );
+ if ( values == NULL ) {
+ ldap_msgfree( res );
+ LDAP_SET_LDERRNO( ld, LDAP_NO_SUCH_ATTRIBUTE, NULL, NULL );
+ return( LDAP_NO_SUCH_ATTRIBUTE );
+ }
+
+ slen = 0;
+ for(v = values; *v != NULL; v++ ) {
+ slen += strlen(*v) + 1;
+ }
+ if ( (mech = NSLDAPI_CALLOC(1, slen)) == NULL) {
+ ldap_value_free( values );
+ ldap_msgfree( res );
+ LDAP_SET_LDERRNO( ld, LDAP_NO_MEMORY, NULL, NULL );
+ return( LDAP_NO_MEMORY );
+ }
+ m = mech;
+ for(v = values; *v; v++) {
+ if (v != values) {
+ *m++ = ' ';
+ }
+ slen = strlen(*v);
+ strncpy(m, *v, slen);
+ m += slen;
+ }
+ *m = '\0';
+
+ ldap_value_free( values );
+ ldap_msgfree( res );
+
+ *pmech = mech;
+
+ return( LDAP_SUCCESS );
+}
+#endif /* LDAP_SASLIO_GET_MECHS_FROM_SERVER */
+
+int
+nsldapi_sasl_secprops(
+ const char *in,
+ sasl_security_properties_t *secprops )
+{
+ int i;
+ char **props = NULL;
+ char *inp;
+ unsigned sflags = 0;
+ sasl_ssf_t max_ssf = 0;
+ sasl_ssf_t min_ssf = 0;
+ unsigned maxbufsize = 0;
+ int got_sflags = 0;
+ int got_max_ssf = 0;
+ int got_min_ssf = 0;
+ int got_maxbufsize = 0;
+
+ if (in == NULL) {
+ return LDAP_PARAM_ERROR;
+ }
+ inp = nsldapi_strdup(in);
+ if (inp == NULL) {
+ return LDAP_PARAM_ERROR;
+ }
+ props = ldap_str2charray( inp, "," );
+ NSLDAPI_FREE( inp );
+
+ if( props == NULL || secprops == NULL ) {
+ return LDAP_PARAM_ERROR;
+ }
+
+ for( i=0; props[i]; i++ ) {
+ if( strcasecmp(props[i], "none") == 0 ) {
+ got_sflags++;
+
+ } else if( strcasecmp(props[i], "noactive") == 0 ) {
+ got_sflags++;
+ sflags |= SASL_SEC_NOACTIVE;
+
+ } else if( strcasecmp(props[i], "noanonymous") == 0 ) {
+ got_sflags++;
+ sflags |= SASL_SEC_NOANONYMOUS;
+
+ } else if( strcasecmp(props[i], "nodict") == 0 ) {
+ got_sflags++;
+ sflags |= SASL_SEC_NODICTIONARY;
+
+ } else if( strcasecmp(props[i], "noplain") == 0 ) {
+ got_sflags++;
+ sflags |= SASL_SEC_NOPLAINTEXT;
+
+ } else if( strcasecmp(props[i], "forwardsec") == 0 ) {
+ got_sflags++;
+ sflags |= SASL_SEC_FORWARD_SECRECY;
+
+ } else if( strcasecmp(props[i], "passcred") == 0 ) {
+ got_sflags++;
+ sflags |= SASL_SEC_PASS_CREDENTIALS;
+
+ } else if( strncasecmp(props[i],
+ "minssf=", sizeof("minssf")) == 0 ) {
+ if( isdigit( props[i][sizeof("minssf")] ) ) {
+ got_min_ssf++;
+ min_ssf = atoi( &props[i][sizeof("minssf")] );
+ } else {
+ return LDAP_NOT_SUPPORTED;
+ }
+
+ } else if( strncasecmp(props[i],
+ "maxssf=", sizeof("maxssf")) == 0 ) {
+ if( isdigit( props[i][sizeof("maxssf")] ) ) {
+ got_max_ssf++;
+ max_ssf = atoi( &props[i][sizeof("maxssf")] );
+ } else {
+ return LDAP_NOT_SUPPORTED;
+ }
+
+ } else if( strncasecmp(props[i],
+ "maxbufsize=", sizeof("maxbufsize")) == 0 ) {
+ if( isdigit( props[i][sizeof("maxbufsize")] ) ) {
+ got_maxbufsize++;
+ maxbufsize = atoi( &props[i][sizeof("maxbufsize")] );
+ if( maxbufsize &&
+ (( maxbufsize < SASL_MIN_BUFF_SIZE )
+ || (maxbufsize > SASL_MAX_BUFF_SIZE ))) {
+ return( LDAP_PARAM_ERROR );
+ }
+ } else {
+ return( LDAP_NOT_SUPPORTED );
+ }
+ } else {
+ return( LDAP_NOT_SUPPORTED );
+ }
+ }
+
+ if(got_sflags) {
+ secprops->security_flags = sflags;
+ }
+ if(got_min_ssf) {
+ secprops->min_ssf = min_ssf;
+ }
+ if(got_max_ssf) {
+ secprops->max_ssf = max_ssf;
+ }
+ if(got_maxbufsize) {
+ secprops->maxbufsize = maxbufsize;
+ }
+
+ ldap_charray_free( props );
+ return( LDAP_SUCCESS );
+}
+#endif /* LDAP_SASLIO_HOOKS */
+
+static int
+nsldapi_sasl_bind_s(
+ LDAP *ld,
+ const char *dn,
+ const char *mechanism,
+ const struct berval *cred,
+ LDAPControl **serverctrls,
+ LDAPControl **clientctrls,
+ struct berval **servercredp,
+ LDAPControl ***responsectrls
+)
+{
+ int err, msgid;
+ LDAPMessage *result;
+
+ LDAPDebug( LDAP_DEBUG_TRACE, "nsldapi_sasl_bind_s\n", 0, 0, 0 );
+
+ if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
+ return( LDAP_PARAM_ERROR );
+ }
+
+ if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
+ LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
+ return( LDAP_NOT_SUPPORTED );
+ }
+
+ if ( ( err = ldap_sasl_bind( ld, dn, mechanism, cred, serverctrls,
+ clientctrls, &msgid )) != LDAP_SUCCESS )
+ return( err );
+
+ if ( ldap_result( ld, msgid, 1, (struct timeval *) 0, &result ) == -1 )
+ return( LDAP_GET_LDERRNO( ld, NULL, NULL ) );
+
+ /* Get the controls sent by the server if requested */
+ if ( responsectrls ) {
+ if ( ( err = ldap_parse_result( ld, result, &err, NULL, NULL,
+ NULL, responsectrls, 0 )) != LDAP_SUCCESS )
+ return( err );
+ }
+
+ err = ldap_parse_sasl_bind_result( ld, result, servercredp, 0 );
+ if (err != LDAP_SUCCESS && err != LDAP_SASL_BIND_IN_PROGRESS) {
+ ldap_msgfree( result );
+ return( err );
+ }
+
+ return( ldap_result2error( ld, result, 1 ) );
+}
+
+#ifdef LDAP_SASLIO_HOOKS
+static int
+nsldapi_sasl_do_bind( LDAP *ld, const char *dn,
+ const char *mechs, unsigned flags,
+ LDAP_SASL_INTERACT_PROC *callback, void *defaults,
+ LDAPControl **sctrl, LDAPControl **cctrl, LDAPControl ***rctrl )
+{
+ sasl_interact_t *prompts = NULL;
+ sasl_conn_t *ctx = NULL;
+ sasl_ssf_t *ssf = NULL;
+ const char *mech = NULL;
+ int saslrc, rc;
+ struct berval ccred;
+ unsigned credlen;
+ int stepnum = 1;
+ char *sasl_username = NULL;
+
+ if (rctrl) {
+ /* init to NULL so we can call ldap_controls_free below */
+ *rctrl = NULL;
+ }
+
+ if (NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3) {
+ LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
+ return( LDAP_NOT_SUPPORTED );
+ }
+
+ /* shouldn't happen */
+ if (callback == NULL) {
+ return( LDAP_LOCAL_ERROR );
+ }
+
+ if ( (rc = nsldapi_sasl_open(ld, NULL, &ctx, 0)) != LDAP_SUCCESS ) {
+ return( rc );
+ }
+
+ ccred.bv_val = NULL;
+ ccred.bv_len = 0;
+
+ LDAPDebug(LDAP_DEBUG_TRACE, "Starting SASL/%s authentication\n",
+ (mechs ? mechs : ""), 0, 0 );
+
+ do {
+ saslrc = sasl_client_start( ctx,
+ mechs,
+ &prompts,
+ (const char **)&ccred.bv_val,
+ &credlen,
+ &mech );
+
+ LDAPDebug(LDAP_DEBUG_TRACE, "Doing step %d of client start for SASL/%s authentication\n",
+ stepnum, (mech ? mech : ""), 0 );
+ stepnum++;
+
+ if( saslrc == SASL_INTERACT &&
+ (callback)(ld, flags, defaults, prompts) != LDAP_SUCCESS ) {
+ break;
+ }
+ } while ( saslrc == SASL_INTERACT );
+
+ ccred.bv_len = credlen;
+
+ if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
+ return( nsldapi_sasl_cvterrno( ld, saslrc, nsldapi_strdup( sasl_errdetail( ctx ) ) ) );
+ }
+
+ stepnum = 1;
+
+ do {
+ struct berval *scred;
+ int clientstepnum = 1;
+
+ scred = NULL;
+
+ if (rctrl) {
+ /* if we're looping again, we need to free any controls set
+ during the previous loop */
+ /* NOTE that this assumes we only care about the controls
+ returned by the last call to nsldapi_sasl_bind_s - if
+ we care about _all_ controls, we will have to figure out
+ some way to append them each loop go round */
+ ldap_controls_free(*rctrl);
+ *rctrl = NULL;
+ }
+
+ LDAPDebug(LDAP_DEBUG_TRACE, "Doing step %d of bind for SASL/%s authentication\n",
+ stepnum, (mech ? mech : ""), 0 );
+ stepnum++;
+
+ /* notify server of a sasl bind step */
+ rc = nsldapi_sasl_bind_s(ld, dn, mech, &ccred,
+ sctrl, cctrl, &scred, rctrl);
+
+ if ( ccred.bv_val != NULL ) {
+ ccred.bv_val = NULL;
+ }
+
+ if ( rc != LDAP_SUCCESS && rc != LDAP_SASL_BIND_IN_PROGRESS ) {
+ ber_bvfree( scred );
+ return( rc );
+ }
+
+ if( rc == LDAP_SUCCESS && saslrc == SASL_OK ) {
+ /* we're done, no need to step */
+ if( scred ) {
+ if ( scred->bv_len == 0 ) { /* MS AD sends back empty screds */
+ LDAPDebug(LDAP_DEBUG_ANY,
+ "SASL BIND complete - ignoring empty credential response\n",
+ 0, 0, 0);
+ ber_bvfree( scred );
+ } else {
+ /* but server provided us with data! */
+ LDAPDebug(LDAP_DEBUG_TRACE,
+ "SASL BIND complete but invalid because server responded with credentials - length [%u]\n",
+ scred->bv_len, 0, 0);
+ ber_bvfree( scred );
+ LDAP_SET_LDERRNO( ld, LDAP_LOCAL_ERROR,
+ NULL, "Error during SASL handshake - invalid server credential response" );
+ return( LDAP_LOCAL_ERROR );
+ }
+ }
+ break;
+ }
+
+ /* perform the next step of the sasl bind */
+ do {
+ LDAPDebug(LDAP_DEBUG_TRACE, "Doing client step %d of bind step %d for SASL/%s authentication\n",
+ clientstepnum, stepnum, (mech ? mech : "") );
+ clientstepnum++;
+ saslrc = sasl_client_step( ctx,
+ (scred == NULL) ? NULL : scred->bv_val,
+ (scred == NULL) ? 0 : scred->bv_len,
+ &prompts,
+ (const char **)&ccred.bv_val,
+ &credlen );
+
+ if( saslrc == SASL_INTERACT &&
+ (callback)(ld, flags, defaults, prompts)
+ != LDAP_SUCCESS ) {
+ break;
+ }
+ } while ( saslrc == SASL_INTERACT );
+
+ ccred.bv_len = credlen;
+ ber_bvfree( scred );
+
+ if ( (saslrc != SASL_OK) && (saslrc != SASL_CONTINUE) ) {
+ return( nsldapi_sasl_cvterrno( ld, saslrc, nsldapi_strdup( sasl_errdetail( ctx ) ) ) );
+ }
+ } while ( rc == LDAP_SASL_BIND_IN_PROGRESS );
+
+ if ( rc != LDAP_SUCCESS ) {
+ return( rc );
+ }
+
+ if ( saslrc != SASL_OK ) {
+ return( nsldapi_sasl_cvterrno( ld, saslrc, nsldapi_strdup( sasl_errdetail( ctx ) ) ) );
+ }
+
+ saslrc = sasl_getprop( ctx, SASL_USERNAME, (const void **) &sasl_username );
+ if ( (saslrc == SASL_OK) && sasl_username ) {
+ LDAPDebug(LDAP_DEBUG_TRACE, "SASL identity: %s\n", sasl_username, 0, 0);
+ }
+
+ saslrc = sasl_getprop( ctx, SASL_SSF, (const void **) &ssf );
+ if( saslrc == SASL_OK ) {
+ if( ssf && *ssf ) {
+ LDAPDebug(LDAP_DEBUG_TRACE,
+ "SASL install encryption, for SSF: %lu\n",
+ (unsigned long) *ssf, 0, 0 );
+ nsldapi_sasl_install( ld, NULL );
+ }
+ }
+
+ return( rc );
+}
+#endif /* LDAP_SASLIO_HOOKS */
+
+
+/*
+ * ldap_sasl_bind - authenticate to the ldap server. The dn, mechanism,
+ * and credentials of the entry to which to bind are supplied. An LDAP
+ * error code is returned and if LDAP_SUCCESS is returned *msgidp is set
+ * to the id of the request initiated.
+ *
+ * Example:
+ * struct berval creds;
+ * LDAPControl **ctrls;
+ * int err, msgid;
+ * ... fill in creds with credentials ...
+ * ... fill in ctrls with server controls ...
+ * err = ldap_sasl_bind( ld, "cn=manager, o=university of michigan, c=us",
+ * "mechanismname", &creds, ctrls, NULL, &msgid );
+ */
+int
+LDAP_CALL
+ldap_sasl_bind(
+ LDAP *ld,
+ const char *dn,
+ const char *mechanism,
+ const struct berval *cred,
+ LDAPControl **serverctrls,
+ LDAPControl **clientctrls,
+ int *msgidp
+)
+{
+ BerElement *ber;
+ int rc, simple, msgid, ldapversion;
+
+ /*
+ * The ldapv3 bind request looks like this:
+ * BindRequest ::= SEQUENCE {
+ * version INTEGER,
+ * name DistinguishedName, -- who
+ * authentication CHOICE {
+ * simple [0] OCTET STRING, -- passwd
+ * sasl [3] SaslCredentials -- v3 only
+ * }
+ * }
+ * SaslCredentials ::= SEQUENCE {
+ * mechanism LDAPString,
+ * credentials OCTET STRING
+ * }
+ * all wrapped up in an LDAPMessage sequence.
+ */
+
+ LDAPDebug( LDAP_DEBUG_TRACE, "ldap_sasl_bind\n", 0, 0, 0 );
+
+ if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
+ return( LDAP_PARAM_ERROR );
+ }
+
+ if ( msgidp == NULL ) {
+ LDAP_SET_LDERRNO( ld, LDAP_PARAM_ERROR, NULL, NULL );
+ return( LDAP_PARAM_ERROR );
+ }
+
+ if ( ( ld->ld_options & LDAP_BITOPT_RECONNECT ) != 0 ) {
+ nsldapi_handle_reconnect( ld );
+ }
+
+ simple = ( mechanism == LDAP_SASL_SIMPLE );
+ ldapversion = NSLDAPI_LDAP_VERSION( ld );
+
+ /* only ldapv3 or higher can do sasl binds */
+ if ( !simple && ldapversion < LDAP_VERSION3 ) {
+ LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
+ return( LDAP_NOT_SUPPORTED );
+ }
+
+ LDAP_MUTEX_LOCK( ld, LDAP_MSGID_LOCK );
+ msgid = ++ld->ld_msgid;
+ LDAP_MUTEX_UNLOCK( ld, LDAP_MSGID_LOCK );
+
+ if ( dn == NULL )
+ dn = "";
+
+ if ( ld->ld_cache_on && ld->ld_cache_bind != NULL ) {
+ LDAP_MUTEX_LOCK( ld, LDAP_CACHE_LOCK );
+ if ( (rc = (ld->ld_cache_bind)( ld, msgid, LDAP_REQ_BIND, dn,
+ cred, LDAP_AUTH_SASL )) != 0 ) {
+ *msgidp = rc;
+ LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
+ return( LDAP_SUCCESS );
+ }
+ LDAP_MUTEX_UNLOCK( ld, LDAP_CACHE_LOCK );
+ }
+
+ /* create a message to send */
+ if (( rc = nsldapi_alloc_ber_with_options( ld, &ber ))
+ != LDAP_SUCCESS ) {
+ return( rc );
+ }
+
+ /* fill it in */
+ if ( simple ) { /* simple bind; works in LDAPv2 or v3 */
+ struct berval tmpcred;
+
+ if ( cred == NULL ) {
+ tmpcred.bv_val = "";
+ tmpcred.bv_len = 0;
+ cred = &tmpcred;
+ }
+ rc = ber_printf( ber, "{it{isto}", msgid, LDAP_REQ_BIND,
+ ldapversion, dn, LDAP_AUTH_SIMPLE, cred->bv_val,
+ cred->bv_len );
+
+ } else { /* SASL bind; requires LDAPv3 or better */
+ if (strcmp(mechanism, LDAP_SASL_EXTERNAL) == 0)
+ {
+ rc = ber_printf( ber, "{it{ist{so}}", msgid,
+ LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SASL,
+ mechanism, cred->bv_val,
+ cred->bv_len );
+ }
+ else if ( cred == NULL || cred->bv_val == NULL || cred->bv_len == 0) {
+ rc = ber_printf( ber, "{it{ist{s}}", msgid,
+ LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SASL,
+ mechanism );
+ } else {
+ rc = ber_printf( ber, "{it{ist{so}}", msgid,
+ LDAP_REQ_BIND, ldapversion, dn, LDAP_AUTH_SASL,
+ mechanism, cred->bv_val,
+ cred->bv_len );
+ }
+ }
+
+ if ( rc == -1 ) {
+ LDAP_SET_LDERRNO( ld, LDAP_ENCODING_ERROR, NULL, NULL );
+ ber_free( ber, 1 );
+ return( LDAP_ENCODING_ERROR );
+ }
+
+ if ( (rc = nsldapi_put_controls( ld, serverctrls, 1, ber ))
+ != LDAP_SUCCESS ) {
+ ber_free( ber, 1 );
+ return( rc );
+ }
+
+ /* send the message */
+ rc = nsldapi_send_initial_request( ld, msgid, LDAP_REQ_BIND,
+ (char *)dn, ber );
+ *msgidp = rc;
+ return( rc < 0 ? LDAP_GET_LDERRNO( ld, NULL, NULL ) : LDAP_SUCCESS );
+}
+
+/*
+ * ldap_sasl_bind_s - bind to the ldap server using sasl authentication
+ * The dn, mechanism, and credentials of the entry to which to bind are
+ * supplied. LDAP_SUCCESS is returned upon success, the ldap error code
+ * otherwise.
+ *
+ * Example:
+ * struct berval creds;
+ * ... fill in creds with credentials ...
+ * ldap_sasl_bind_s( ld, "cn=manager, o=university of michigan, c=us",
+ * "mechanismname", &creds )
+ */
+int
+LDAP_CALL
+ldap_sasl_bind_s(
+ LDAP *ld,
+ const char *dn,
+ const char *mechanism,
+ const struct berval *cred,
+ LDAPControl **serverctrls,
+ LDAPControl **clientctrls,
+ struct berval **servercredp
+)
+{
+ return ( nsldapi_sasl_bind_s( ld, dn, mechanism, cred,
+ serverctrls, clientctrls, servercredp, NULL ) );
+}
+
+#ifdef LDAP_SASLIO_HOOKS
+/*
+ * SASL Authentication Interface: ldap_sasl_interactive_bind_s
+ *
+ * This routine takes a DN, SASL mech list, and a SASL callback
+ * and performs the necessary sequencing to complete a SASL bind
+ * to the LDAP connection ld. The user provided callback can
+ * use an optionally provided set of default values to complete
+ * any necessary interactions.
+ *
+ * Currently imposes the following restrictions:
+ * A mech list must be provided
+ * LDAP_SASL_INTERACTIVE mode requires a callback
+ */
+int
+LDAP_CALL
+ldap_sasl_interactive_bind_s( LDAP *ld, const char *dn,
+ const char *saslMechanism,
+ LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags,
+ LDAP_SASL_INTERACT_PROC *callback, void *defaults )
+{
+ return ldap_sasl_interactive_bind_ext_s( ld, dn,
+ saslMechanism, sctrl, cctrl, flags, callback,
+ defaults, NULL );
+}
+
+/*
+ * ldap_sasl_interactive_bind_ext_s
+ *
+ * This function extends ldap_sasl_interactive_bind_s by allowing
+ * controls received from the server to be returned as rctrl. The
+ * caller must pass in a valid LDAPControl** pointer and free the
+ * array of controls when finished with them e.g.
+ * LDAPControl **retctrls = NULL;
+ * ...
+ * ldap_sasl_interactive_bind_ext_s(ld, ...., &retctrls);
+ * ...
+ * ldap_controls_free(retctrls);
+ * Only the controls from the server during the last bind step are returned -
+ * intermediate controls (if any, usually not) are discarded.
+ */
+int
+LDAP_CALL
+ldap_sasl_interactive_bind_ext_s( LDAP *ld, const char *dn,
+ const char *saslMechanism,
+ LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags,
+ LDAP_SASL_INTERACT_PROC *callback, void *defaults, LDAPControl ***rctrl )
+{
+#ifdef LDAP_SASLIO_GET_MECHS_FROM_SERVER
+ char *smechs;
+#endif
+ int rc;
+
+ LDAPDebug( LDAP_DEBUG_TRACE, "ldap_sasl_interactive_bind_s\n", 0, 0, 0 );
+
+ if ( !NSLDAPI_VALID_LDAP_POINTER( ld )) {
+ return( LDAP_PARAM_ERROR );
+ }
+
+ if ((flags == LDAP_SASL_INTERACTIVE) && (callback == NULL)) {
+ return( LDAP_PARAM_ERROR );
+ }
+
+ LDAP_MUTEX_LOCK(ld, LDAP_SASL_LOCK );
+
+ if( saslMechanism == NULL || *saslMechanism == '\0' ) {
+#ifdef LDAP_SASLIO_GET_MECHS_FROM_SERVER
+ rc = nsldapi_get_sasl_mechs( ld, &smechs );
+ if( rc != LDAP_SUCCESS ) {
+ LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK );
+ return( rc );
+ }
+ saslMechanism = smechs;
+#else
+ LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK );
+ return( LDAP_PARAM_ERROR );
+#endif /* LDAP_SASLIO_GET_MECHS_FROM_SERVER */
+ }
+
+ rc = nsldapi_sasl_do_bind( ld, dn, saslMechanism,
+ flags, callback, defaults, sctrl, cctrl, rctrl);
+
+ LDAP_MUTEX_UNLOCK(ld, LDAP_SASL_LOCK );
+ return( rc );
+}
+#else /* LDAP_SASLIO_HOOKS */
+/* stubs for platforms that do not support SASL */
+int
+LDAP_CALL
+ldap_sasl_interactive_bind_s( LDAP *ld, const char *dn,
+ const char *saslMechanism,
+ LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags,
+ LDAP_SASL_INTERACT_PROC *callback, void *defaults )
+{
+ return LDAP_SUCCESS;
+}
+
+int
+LDAP_CALL
+ldap_sasl_interactive_bind_ext_s( LDAP *ld, const char *dn,
+ const char *saslMechanism,
+ LDAPControl **sctrl, LDAPControl **cctrl, unsigned flags,
+ LDAP_SASL_INTERACT_PROC *callback, void *defaults, LDAPControl ***rctrl )
+{
+ return LDAP_SUCCESS;
+}
+#endif /* LDAP_SASLIO_HOOKS */
+
+
+/* returns an LDAP error code that indicates if parse succeeded or not */
+int
+LDAP_CALL
+ldap_parse_sasl_bind_result(
+ LDAP *ld,
+ LDAPMessage *res,
+ struct berval **servercredp,
+ int freeit
+)
+{
+ BerElement ber;
+ int rc, err;
+ ber_int_t along;
+ ber_len_t len;
+ char *m, *e;
+
+ LDAPDebug( LDAP_DEBUG_TRACE, "ldap_parse_sasl_bind_result\n", 0, 0, 0 );
+
+ /*
+ * the ldapv3 SASL bind response looks like this:
+ *
+ * BindResponse ::= [APPLICATION 1] SEQUENCE {
+ * COMPONENTS OF LDAPResult,
+ * serverSaslCreds [7] OCTET STRING OPTIONAL
+ * }
+ *
+ * all wrapped up in an LDAPMessage sequence.
+ */
+
+ if ( !NSLDAPI_VALID_LDAP_POINTER( ld ) ||
+ !NSLDAPI_VALID_LDAPMESSAGE_BINDRESULT_POINTER( res )) {
+ return( LDAP_PARAM_ERROR );
+ }
+
+ /* only ldapv3 or higher can do sasl binds */
+ if ( NSLDAPI_LDAP_VERSION( ld ) < LDAP_VERSION3 ) {
+ LDAP_SET_LDERRNO( ld, LDAP_NOT_SUPPORTED, NULL, NULL );
+ return( LDAP_NOT_SUPPORTED );
+ }
+
+ if ( servercredp != NULL ) {
+ *servercredp = NULL;
+ }
+
+ ber = *(res->lm_ber); /* struct copy */
+
+ /* skip past message id, matched dn, error message ... */
+ rc = ber_scanf( &ber, "{iaa}", &along, &m, &e );
+
+ if ( rc != LBER_ERROR &&
+ ber_peek_tag( &ber, &len ) == LDAP_TAG_SASL_RES_CREDS ) {
+ rc = ber_get_stringal( &ber, servercredp );
+ }
+
+ if ( freeit ) {
+ ldap_msgfree( res );
+ }
+
+ if ( rc == LBER_ERROR ) {
+ err = LDAP_DECODING_ERROR;
+ } else {
+ err = (int) along;
+ }
+
+ LDAP_SET_LDERRNO( ld, err, m, e );
+ /* this is a little kludge for the 3.0 Barracuda/hammerhead relese */
+ /* the docs state that the return is either LDAP_DECODING_ERROR */
+ /* or LDAP_SUCCESS. Here we match the docs... it's cleaner in 3.1 */
+
+ if ( LDAP_DECODING_ERROR == err ) {
+ return (LDAP_DECODING_ERROR);
+ } else {
+ return( LDAP_SUCCESS );
+ }
+}
+
--- /dev/null
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * ***** 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 "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 the mozilla.org LDAP XPCOM SDK.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Dan Mosedale <dmose@mozilla.org>
+ * Simon Wilkinson <simon@sxw.org.uk>
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved
+ *
+ * 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 ***** */
+
+#include "nsISupports.idl"
+#include "nsILDAPConnection.idl"
+#include "nsIAuthModule.idl"
+
+interface nsILDAPMessage;
+interface nsILDAPMessageListener;
+interface nsILDAPModification;
+interface nsIMutableArray;
+interface nsIArray;
+
+%{C++
+#define NS_LDAPOPERATION_CONTRACTID "@mozilla.org/network/ldap-operation;1"
+%}
+
+// XXXdmose check to make sure ctl-related err codes documented
+
+typedef uint32_t PRIntervalTime;
+
+[scriptable, uuid(4dfb1b19-fc8f-4525-92e7-f97b78a9747a)]
+interface nsILDAPOperation : nsISupports
+{
+ /**
+ * The connection this operation is on.
+ *
+ * @exception NS_ERROR_ILLEGAL_VALUE a NULL pointer was passed in
+ */
+ readonly attribute nsILDAPConnection connection;
+
+ /**
+ * Callback for individual result messages related to this operation (set
+ * by the init() method). This is actually an nsISupports proxy object,
+ * as the callback will happen from another thread.
+ *
+ * @exception NS_ERROR_ILLEGAL_VALUE a NULL pointer was passed in
+ */
+ readonly attribute nsILDAPMessageListener messageListener;
+
+ /**
+ * The message-id associated with this operation.
+ *
+ * @exception NS_ERROR_ILLEGAL_VALUE a NULL pointer was passed in
+ */
+ readonly attribute long messageID;
+
+ /**
+ * private parameter (anything caller desires)
+ */
+ attribute nsISupports closure;
+
+ /**
+ * No time and/or size limit specified
+ */
+ const long NO_LIMIT = 0;
+
+ /**
+ * If specified, these arrays of nsILDAPControls are passed into the LDAP
+ * C SDK for any extended operations (ie method calls on this interface
+ * ending in "Ext").
+ */
+ attribute nsIMutableArray serverControls;
+ attribute nsIMutableArray clientControls;
+
+ /**
+ * Initializes this operation. Must be called prior to initiating
+ * any actual operations. Note that by default, the aMessageListener
+ * callbacks happen on the LDAP connection thread. If you need them
+ * to happen on the main thread (or any other thread), then you should
+ * created an nsISupports proxy object and pass that in.
+ *
+ * @param aConnection connection this operation should use
+ * @param aMessageListener interface used to call back the results.
+ * @param aClosure private parameter (anything caller desires)
+ *
+ * @exception NS_ERROR_ILLEGAL_VALUE a NULL pointer was passed in
+ * @exception NS_ERROR_UNEXPECTED failed to get connection handle
+ */
+ void init(in nsILDAPConnection aConnection,
+ in nsILDAPMessageListener aMessageListener,
+ in nsISupports aClosure);
+
+ /**
+ * Asynchronously authenticate to the LDAP server.
+ *
+ * @param passwd the password used for binding; NULL for anon-binds
+ *
+ * @exception NS_ERROR_LDAP_ENCODING_ERROR problem encoding bind request
+ * @exception NS_ERROR_LDAP_SERVER_DOWN server down (XXX rebinds?)
+ * @exception NS_ERROR_LDAP_CONNECT_ERROR connection failed or lost
+ * @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
+ * @exception NS_ERROR_UNEXPECTED internal error
+ */
+ void simpleBind(in AUTF8String passwd);
+
+ /**
+ * Asynchronously perform a SASL bind against the LDAP server
+ *
+ * @param service the host name of the service being connected to
+ * @param mechanism the name of the SASL mechanism in use
+ * @param authModule the nsIAuthModule to be used to perform the operation
+ *
+ */
+ void saslBind(in ACString service, in ACString mechanism,
+ in nsIAuthModule authModule);
+
+ /**
+ * Continue a SASL bind operation
+ *
+ * @param token the next SASL token to send to the server
+ * @param tokenLen the length of the token to send
+ *
+ */
+ void saslStep(in string token, in unsigned long tokenLen);
+
+ /**
+ * Kicks off an asynchronous add request. The "ext" stands for
+ * "extensions", and is intended to convey that this method will
+ * eventually support the extensions described in the
+ * draft-ietf-ldapext-ldap-c-api-04.txt Internet Draft.
+ *
+ * @param aBaseDn Base DN to add
+ * @param aModCount Number of modifications
+ * @param aMods Array of modifications
+ *
+ * @exception NS_ERROR_NOT_INITIALIZED operation not initialized
+ * @exception NS_ERROR_INVALID_ARG invalid argument
+ * @exception NS_ERROR_LDAP_ENCODING_ERROR error during BER-encoding
+ * @exception NS_ERROR_LDAP_SERVER_DOWN the LDAP server did not
+ * receive the request or the
+ * connection was lost
+ * @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
+ * @exception NS_ERROR_LDAP_NOT_SUPPORTED not supported in the version
+ * of the LDAP protocol that the
+ * client is using
+ * @exception NS_ERROR_UNEXPECTED an unexpected error has
+ * occurred
+ *
+ * XXX doesn't currently handle LDAPControl params
+ */
+ void addExt(in AUTF8String aBaseDn, in nsIArray aMods);
+
+ /**
+ * Kicks off an asynchronous delete request. The "ext" stands for
+ * "extensions", and is intended to convey that this method will
+ * eventually support the extensions described in the
+ * draft-ietf-ldapext-ldap-c-api-04.txt Internet Draft.
+ *
+ * @param aBaseDn Base DN to delete
+ *
+ * @exception NS_ERROR_NOT_INITIALIZED operation not initialized
+ * @exception NS_ERROR_INVALID_ARG invalid argument
+ * @exception NS_ERROR_LDAP_ENCODING_ERROR error during BER-encoding
+ * @exception NS_ERROR_LDAP_SERVER_DOWN the LDAP server did not
+ * receive the request or the
+ * connection was lost
+ * @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
+ * @exception NS_ERROR_LDAP_NOT_SUPPORTED not supported in the version
+ * of the LDAP protocol that the
+ * client is using
+ * @exception NS_ERROR_UNEXPECTED an unexpected error has
+ * occurred
+ *
+ * XXX doesn't currently handle LDAPControl params
+ */
+ void deleteExt(in AUTF8String aBaseDn);
+
+ /**
+ * Kicks off an asynchronous modify request. The "ext" stands for
+ * "extensions", and is intended to convey that this method will
+ * eventually support the extensions described in the
+ * draft-ietf-ldapext-ldap-c-api-04.txt Internet Draft.
+ *
+ * @param aBaseDn Base DN to modify
+ * @param aModCount Number of modifications
+ * @param aMods Array of modifications
+ *
+ * @exception NS_ERROR_NOT_INITIALIZED operation not initialized
+ * @exception NS_ERROR_INVALID_ARG invalid argument
+ * @exception NS_ERROR_LDAP_ENCODING_ERROR error during BER-encoding
+ * @exception NS_ERROR_LDAP_SERVER_DOWN the LDAP server did not
+ * receive the request or the
+ * connection was lost
+ * @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
+ * @exception NS_ERROR_LDAP_NOT_SUPPORTED not supported in the version
+ * of the LDAP protocol that the
+ * client is using
+ * @exception NS_ERROR_UNEXPECTED an unexpected error has
+ * occurred
+ *
+ * XXX doesn't currently handle LDAPControl params
+ */
+ void modifyExt(in AUTF8String aBaseDn, in nsIArray aMods);
+
+ /**
+ * Kicks off an asynchronous rename request.
+ *
+ * @param aBaseDn Base DN to rename
+ * @param aNewRDn New relative DN
+ * @param aNewParent DN of the new parent under which to move the
+ * entry
+ * @param aDeleteOldRDn Indicates whether to remove the old relative
+ * DN as a value in the entry or not
+ *
+ * @exception NS_ERROR_NOT_INITIALIZED operation not initialized
+ * @exception NS_ERROR_INVALID_ARG invalid argument
+ * @exception NS_ERROR_LDAP_ENCODING_ERROR error during BER-encoding
+ * @exception NS_ERROR_LDAP_SERVER_DOWN the LDAP server did not
+ * receive the request or the
+ * connection was lost
+ * @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
+ * @exception NS_ERROR_LDAP_NOT_SUPPORTED not supported in the version
+ * of the LDAP protocol that the
+ * client is using
+ * @exception NS_ERROR_UNEXPECTED an unexpected error has
+ * occurred
+ *
+ * XXX doesn't currently handle LDAPControl params
+ */
+ void rename(in AUTF8String aBaseDn, in AUTF8String aNewRDn,
+ in AUTF8String aNewParent, in boolean aDeleteOldRDn);
+
+ /**
+ * Kicks off an asynchronous search request. The "ext" stands for
+ * "extensions", and is intended to convey that this method will
+ * eventually support the extensions described in the
+ * draft-ietf-ldapext-ldap-c-api-04.txt Internet Draft.
+ *
+ * @param aBaseDn Base DN to search
+ * @param aScope One of SCOPE_{BASE,ONELEVEL,SUBTREE}
+ * @param aFilter Search filter
+ * @param aAttributes Comma separated list of values, holding the
+ * attributes we need
+ * @param aTimeOut How long to wait
+ * @param aSizeLimit Maximum number of entries to return.
+ *
+ * @exception NS_ERROR_NOT_INITIALIZED operation not initialized
+ * @exception NS_ERROR_LDAP_ENCODING_ERROR error during BER-encoding
+ * @exception NS_ERROR_LDAP_SERVER_DOWN the LDAP server did not
+ * receive the request or the
+ * connection was lost
+ * @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
+ * @exception NS_ERROR_INVALID_ARG invalid argument
+ * @exception NS_ERROR_LDAP_NOT_SUPPORTED not supported in the version
+ * of the LDAP protocol that the
+ * client is using
+ * @exception NS_ERROR_LDAP_FILTER_ERROR
+ * @exception NS_ERROR_UNEXPECTED
+ */
+ void searchExt(in AUTF8String aBaseDn, in int32_t aScope,
+ in AUTF8String aFilter, in ACString aAttributes,
+ in PRIntervalTime aTimeOut, in int32_t aSizeLimit);
+
+ /**
+ * Cancels an async operation that is in progress.
+ *
+ * XXX controls not supported yet
+ *
+ * @exception NS_ERROR_NOT_IMPLEMENTED server or client controls
+ * were set on this object
+ * @exception NS_ERROR_NOT_INITIALIZED operation not initialized
+ * @exception NS_ERROR_LDAP_ENCODING_ERROR error during BER-encoding
+ * @exception NS_ERROR_LDAP_SERVER_DOWN the LDAP server did not
+ * receive the request or the
+ * connection was lost
+ * @exception NS_ERROR_OUT_OF_MEMORY out of memory
+ * @exception NS_ERROR_INVALID_ARG invalid argument
+ * @exception NS_ERROR_UNEXPECTED internal error
+ */
+ void abandonExt();
+
+
+ /**
+ * Asynchronously authenticate to the LDAP server.
+ *
+ * @param passwd the password used for binding; NULL for anon-binds
+ *
+ * @exception NS_ERROR_LDAP_ENCODING_ERROR problem encoding bind request
+ * @exception NS_ERROR_LDAP_SERVER_DOWN server down (XXX rebinds?)
+ * @exception NS_ERROR_LDAP_CONNECT_ERROR connection failed or lost
+ * @exception NS_ERROR_OUT_OF_MEMORY ran out of memory
+ * @exception NS_ERROR_UNEXPECTED internal error
+ */
+ void saslBind2();
+};
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * ***** 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 "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 the mozilla.org LDAP XPCOM SDK.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2000
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Dan Mosedale <dmose@mozilla.org>
+ * Simon Wilkinson <simon@sxw.org.uk>
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved
+ *
+ * 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 ***** */
+
+#include "nsLDAPInternal.h"
+#include "nsLDAPOperation.h"
+#include "nsLDAPBERValue.h"
+#include "nsILDAPMessage.h"
+#include "nsILDAPModification.h"
+#include "nsIComponentManager.h"
+#include "nspr.h"
+#include "nsISimpleEnumerator.h"
+#include "nsLDAPControl.h"
+#include "nsILDAPErrors.h"
+#include "nsIClassInfoImpl.h"
+#include "nsIAuthModule.h"
+#include "nsArrayUtils.h"
+#include "nsMemory.h"
+
+// Helper function
+static nsresult TranslateLDAPErrorToNSError(const int ldapError)
+{
+ switch (ldapError) {
+ case LDAP_SUCCESS:
+ return NS_OK;
+
+ case LDAP_ENCODING_ERROR:
+ return NS_ERROR_LDAP_ENCODING_ERROR;
+
+ case LDAP_CONNECT_ERROR:
+ return NS_ERROR_LDAP_CONNECT_ERROR;
+
+ case LDAP_SERVER_DOWN:
+ return NS_ERROR_LDAP_SERVER_DOWN;
+
+ case LDAP_NO_MEMORY:
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ case LDAP_NOT_SUPPORTED:
+ return NS_ERROR_LDAP_NOT_SUPPORTED;
+
+ case LDAP_PARAM_ERROR:
+ return NS_ERROR_INVALID_ARG;
+
+ case LDAP_FILTER_ERROR:
+ return NS_ERROR_LDAP_FILTER_ERROR;
+
+ default:
+ PR_LOG(gLDAPLogModule, PR_LOG_ERROR,
+ ("TranslateLDAPErrorToNSError: "
+ "Do not know how to translate LDAP error: 0x%x", ldapError));
+ return NS_ERROR_UNEXPECTED;
+ }
+}
+
+
+// constructor
+nsLDAPOperation::nsLDAPOperation()
+{
+}
+
+// destructor
+nsLDAPOperation::~nsLDAPOperation()
+{
+}
+
+NS_IMPL_CLASSINFO(nsLDAPOperation, NULL, nsIClassInfo::THREADSAFE,
+ NS_LDAPOPERATION_CID)
+
+NS_IMPL_THREADSAFE_ADDREF(nsLDAPOperation)
+NS_IMPL_THREADSAFE_RELEASE(nsLDAPOperation)
+NS_INTERFACE_MAP_BEGIN(nsLDAPOperation)
+ NS_INTERFACE_MAP_ENTRY(nsILDAPOperation)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsILDAPOperation)
+ NS_IMPL_QUERY_CLASSINFO(nsLDAPOperation)
+NS_INTERFACE_MAP_END_THREADSAFE
+NS_IMPL_CI_INTERFACE_GETTER1(nsLDAPOperation, nsILDAPOperation)
+
+/**
+ * Initializes this operation. Must be called prior to use.
+ *
+ * @param aConnection connection this operation should use
+ * @param aMessageListener where are the results are called back to.
+ */
+NS_IMETHODIMP
+nsLDAPOperation::Init(nsILDAPConnection *aConnection,
+ nsILDAPMessageListener *aMessageListener,
+ nsISupports *aClosure)
+{
+ if (!aConnection) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ // so we know that the operation is not yet running (and therefore don't
+ // try and call ldap_abandon_ext() on it) or remove it from the queue.
+ //
+ mMsgID = 0;
+
+ // set the member vars
+ //
+ mConnection = static_cast<nsLDAPConnection*>(aConnection);
+ mMessageListener = aMessageListener;
+ mClosure = aClosure;
+
+ // cache the connection handle
+ //
+ mConnectionHandle =
+ mConnection->mConnectionHandle;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLDAPOperation::GetClosure(nsISupports **_retval)
+{
+ if (!_retval) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+ NS_IF_ADDREF(*_retval = mClosure);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLDAPOperation::SetClosure(nsISupports *aClosure)
+{
+ mClosure = aClosure;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLDAPOperation::GetConnection(nsILDAPConnection* *aConnection)
+{
+ if (!aConnection) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ *aConnection = mConnection;
+ NS_IF_ADDREF(*aConnection);
+
+ return NS_OK;
+}
+
+void
+nsLDAPOperation::Clear()
+{
+ mMessageListener = nullptr;
+ mClosure = nullptr;
+ mConnection = nullptr;
+}
+
+NS_IMETHODIMP
+nsLDAPOperation::GetMessageListener(nsILDAPMessageListener **aMessageListener)
+{
+ if (!aMessageListener) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ *aMessageListener = mMessageListener;
+ NS_IF_ADDREF(*aMessageListener);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLDAPOperation::SaslBind(const nsACString &service,
+ const nsACString &mechanism,
+ nsIAuthModule *authModule)
+{
+ nsresult rv;
+ nsAutoCString bindName;
+ struct berval creds;
+ unsigned int credlen;
+
+ mAuthModule = authModule;
+ mMechanism.Assign(mechanism);
+
+ rv = mConnection->GetBindName(bindName);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ creds.bv_val = NULL;
+ mAuthModule->Init(PromiseFlatCString(service).get(),
+ nsIAuthModule::REQ_DEFAULT, nullptr,
+ NS_ConvertUTF8toUTF16(bindName).get(), nullptr);
+
+ rv = mAuthModule->GetNextToken(nullptr, 0, (void **)&creds.bv_val,
+ &credlen);
+ if (NS_FAILED(rv) || !creds.bv_val)
+ return rv;
+
+ creds.bv_len = credlen;
+ const int lderrno = ldap_sasl_bind(mConnectionHandle, bindName.get(),
+ mMechanism.get(), &creds, NULL, NULL,
+ &mMsgID);
+ nsMemory::Free(creds.bv_val);
+
+ if (lderrno != LDAP_SUCCESS)
+ return TranslateLDAPErrorToNSError(lderrno);
+
+ // make sure the connection knows where to call back once the messages
+ // for this operation start coming in
+ rv = mConnection->AddPendingOperation(mMsgID, this);
+
+ if (NS_FAILED(rv))
+ (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsLDAPOperation::SaslStep(const char *token, uint32_t tokenLen)
+{
+ nsresult rv;
+ nsAutoCString bindName;
+ struct berval clientCreds;
+ struct berval serverCreds;
+ unsigned int credlen;
+
+ rv = mConnection->RemovePendingOperation(mMsgID);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ serverCreds.bv_val = (char *) token;
+ serverCreds.bv_len = tokenLen;
+
+ rv = mConnection->GetBindName(bindName);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = mAuthModule->GetNextToken(serverCreds.bv_val, serverCreds.bv_len,
+ (void **) &clientCreds.bv_val, &credlen);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ clientCreds.bv_len = credlen;
+
+ const int lderrno = ldap_sasl_bind(mConnectionHandle, bindName.get(),
+ mMechanism.get(), &clientCreds, NULL,
+ NULL, &mMsgID);
+
+ nsMemory::Free(clientCreds.bv_val);
+
+ if (lderrno != LDAP_SUCCESS)
+ return TranslateLDAPErrorToNSError(lderrno);
+
+ // make sure the connection knows where to call back once the messages
+ // for this operation start coming in
+ rv = mConnection->AddPendingOperation(mMsgID, this);
+ if (NS_FAILED(rv))
+ (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
+
+ return rv;
+}
+
+
+// wrapper for ldap_simple_bind()
+//
+NS_IMETHODIMP
+nsLDAPOperation::SimpleBind(const nsACString& passwd)
+{
+ nsRefPtr<nsLDAPConnection> connection = mConnection;
+ // There is a possibilty that mConnection can be cleared by another
+ // thread. Grabbing a local reference to mConnection may avoid this.
+ // See https://bugzilla.mozilla.org/show_bug.cgi?id=557928#c1
+ nsresult rv;
+ nsAutoCString bindName;
+ int32_t originalMsgID = mMsgID;
+ // Ugly hack alert:
+ // the first time we get called with a passwd, remember it.
+ // Then, if we get called again w/o a password, use the
+ // saved one. Getting called again means we're trying to
+ // fall back to VERSION2.
+ // Since LDAP operations are thrown away when done, it won't stay
+ // around in memory.
+ if (!passwd.IsEmpty())
+ mSavePassword = passwd;
+
+ NS_PRECONDITION(mMessageListener != 0, "MessageListener not set");
+
+ rv = connection->GetBindName(bindName);
+ if (NS_FAILED(rv))
+ return rv;
+
+ PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
+ ("nsLDAPOperation::SimpleBind(): called; bindName = '%s'; ",
+ bindName.get()));
+
+ // If this is a second try at binding, remove the operation from pending ops
+ // because msg id has changed...
+ if (originalMsgID)
+ connection->RemovePendingOperation(originalMsgID);
+
+ mMsgID = ldap_simple_bind(mConnectionHandle, bindName.get(),
+ mSavePassword.get());
+
+ if (mMsgID == -1) {
+ // XXX Should NS_ERROR_LDAP_SERVER_DOWN cause a rebind here?
+ return TranslateLDAPErrorToNSError(ldap_get_lderrno(mConnectionHandle,
+ 0, 0));
+ }
+
+ // make sure the connection knows where to call back once the messages
+ // for this operation start coming in
+ rv = connection->AddPendingOperation(mMsgID, this);
+ switch (rv) {
+ case NS_OK:
+ break;
+
+ // note that the return value of ldap_abandon_ext() is ignored, as
+ // there's nothing useful to do with it
+
+ case NS_ERROR_OUT_OF_MEMORY:
+ (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
+ return NS_ERROR_OUT_OF_MEMORY;
+ break;
+
+ case NS_ERROR_UNEXPECTED:
+ case NS_ERROR_ILLEGAL_VALUE:
+ default:
+ (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return NS_OK;
+}
+
+// wrapper for ldap_sasl_bind()
+//
+NS_IMETHODIMP
+nsLDAPOperation::SaslBind2()
+{
+ nsresult rv;
+ struct berval cred;
+ int32_t originalMsgID = mMsgID;
+
+ NS_PRECONDITION(mMessageListener != 0, "MessageListener not set");
+
+ // If this is a second try at binding, remove the operation from pending ops
+ // because msg id has changed...
+ if (originalMsgID)
+ mConnection->RemovePendingOperation(originalMsgID);
+
+ cred.bv_val = "";
+ cred.bv_len = strlen(cred.bv_val)*sizeof(char);
+
+ const int lderrno = ldap_sasl_bind( mConnectionHandle, "", LDAP_SASL_EXTERNAL, &cred, NULL, NULL,&mMsgID );
+ if (lderrno != LDAP_SUCCESS)
+ return TranslateLDAPErrorToNSError(lderrno);
+
+ // make sure the connection knows where to call back once the messages
+ // for this operation start coming in
+ rv = mConnection->AddPendingOperation(mMsgID, this);
+ switch (rv) {
+ case NS_OK:
+ break;
+
+ // note that the return value of ldap_abandon_ext() is ignored, as
+ // there's nothing useful to do with it
+
+ case NS_ERROR_OUT_OF_MEMORY:
+ (void *)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
+ return NS_ERROR_OUT_OF_MEMORY;
+ break;
+
+ case NS_ERROR_UNEXPECTED:
+ case NS_ERROR_ILLEGAL_VALUE:
+ default:
+ (void *)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ return NS_OK;
+}
+
+/**
+ * Given an nsIArray of nsILDAPControls, return the appropriate
+ * zero-terminated array of LDAPControls ready to pass in to the C SDK.
+ */
+static nsresult
+convertControlArray(nsIArray *aXpcomArray, LDAPControl ***aArray)
+{
+ // get the size of the original array
+ uint32_t length;
+ nsresult rv = aXpcomArray->GetLength(&length);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // don't allocate an array if someone passed us in an empty one
+ if (!length) {
+ *aArray = 0;
+ return NS_OK;
+ }
+
+ // allocate a local array of the form understood by the C-SDK;
+ // +1 is to account for the final null terminator. PR_Calloc is
+ // is used so that ldap_controls_free will work anywhere during the
+ // iteration
+ LDAPControl **controls =
+ static_cast<LDAPControl **>
+ (PR_Calloc(length+1, sizeof(LDAPControl)));
+
+ // prepare to enumerate the array
+ nsCOMPtr<nsISimpleEnumerator> enumerator;
+ rv = aXpcomArray->Enumerate(getter_AddRefs(enumerator));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool moreElements;
+ rv = enumerator->HasMoreElements(&moreElements);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ uint32_t i = 0;
+ while (moreElements) {
+
+ // get the next array element
+ nsCOMPtr<nsISupports> isupports;
+ rv = enumerator->GetNext(getter_AddRefs(isupports));
+ if (NS_FAILED(rv)) {
+ ldap_controls_free(controls);
+ return rv;
+ }
+ nsCOMPtr<nsILDAPControl> control = do_QueryInterface(isupports, &rv);
+ if (NS_FAILED(rv)) {
+ ldap_controls_free(controls);
+ return NS_ERROR_INVALID_ARG; // bogus element in the array
+ }
+ nsLDAPControl *ctl = static_cast<nsLDAPControl *>
+ (static_cast<nsILDAPControl *>
+ (control.get()));
+
+ // convert it to an LDAPControl structure placed in the new array
+ rv = ctl->ToLDAPControl(&controls[i]);
+ if (NS_FAILED(rv)) {
+ ldap_controls_free(controls);
+ return rv;
+ }
+
+ // on to the next element
+ rv = enumerator->HasMoreElements(&moreElements);
+ if (NS_FAILED(rv)) {
+ ldap_controls_free(controls);
+ return NS_ERROR_UNEXPECTED;
+ }
+ ++i;
+ }
+
+ *aArray = controls;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLDAPOperation::SearchExt(const nsACString& aBaseDn, int32_t aScope,
+ const nsACString& aFilter,
+ const nsACString &aAttributes,
+ PRIntervalTime aTimeOut, int32_t aSizeLimit)
+{
+ if (!mMessageListener) {
+ NS_ERROR("nsLDAPOperation::SearchExt(): mMessageListener not set");
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ // XXX add control logging
+ PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
+ ("nsLDAPOperation::SearchExt(): called with aBaseDn = '%s'; "
+ "aFilter = '%s'; aAttributes = %s; aSizeLimit = %d",
+ PromiseFlatCString(aBaseDn).get(),
+ PromiseFlatCString(aFilter).get(),
+ PromiseFlatCString(aAttributes).get(), aSizeLimit));
+
+ LDAPControl **serverctls = 0;
+ nsresult rv;
+ if (mServerControls) {
+ rv = convertControlArray(mServerControls, &serverctls);
+ if (NS_FAILED(rv)) {
+ PR_LOG(gLDAPLogModule, PR_LOG_ERROR,
+ ("nsLDAPOperation::SearchExt(): error converting server "
+ "control array: %x", rv));
+ return rv;
+ }
+ }
+
+ LDAPControl **clientctls = 0;
+ if (mClientControls) {
+ rv = convertControlArray(mClientControls, &clientctls);
+ if (NS_FAILED(rv)) {
+ PR_LOG(gLDAPLogModule, PR_LOG_ERROR,
+ ("nsLDAPOperation::SearchExt(): error converting client "
+ "control array: %x", rv));
+ ldap_controls_free(serverctls);
+ return rv;
+ }
+ }
+
+ // Convert our comma separated string to one that the C-SDK will like, i.e.
+ // convert to a char array and add a last NULL element.
+ nsTArray<nsCString> attrArray;
+ ParseString(aAttributes, ',', attrArray);
+ char **attrs = nullptr;
+ uint32_t origLength = attrArray.Length();
+ if (origLength)
+ {
+ attrs = static_cast<char **> (NS_Alloc((origLength + 1) * sizeof(char *)));
+ if (!attrs)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ for (uint32_t i = 0; i < origLength; ++i)
+ attrs[i] = ToNewCString(attrArray[i]);
+
+ attrs[origLength] = 0;
+ }
+
+ // XXX deal with timeout here
+ int retVal = ldap_search_ext(mConnectionHandle,
+ PromiseFlatCString(aBaseDn).get(),
+ aScope, PromiseFlatCString(aFilter).get(),
+ attrs, 0, serverctls, clientctls, 0,
+ aSizeLimit, &mMsgID);
+
+ // clean up
+ ldap_controls_free(serverctls);
+ ldap_controls_free(clientctls);
+ // The last entry is null, so no need to free that.
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(origLength, attrs);
+
+ rv = TranslateLDAPErrorToNSError(retVal);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // make sure the connection knows where to call back once the messages
+ // for this operation start coming in
+ //
+ rv = mConnection->AddPendingOperation(mMsgID, this);
+ if (NS_FAILED(rv)) {
+ switch (rv) {
+ case NS_ERROR_OUT_OF_MEMORY:
+ (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ default:
+ (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
+ NS_ERROR("nsLDAPOperation::SearchExt(): unexpected error in "
+ "mConnection->AddPendingOperation");
+ return NS_ERROR_UNEXPECTED;
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLDAPOperation::GetMessageID(int32_t *aMsgID)
+{
+ if (!aMsgID) {
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ *aMsgID = mMsgID;
+
+ return NS_OK;
+}
+
+// as far as I can tell from reading the LDAP C SDK code, abandoning something
+// that has already been abandoned does not return an error
+//
+NS_IMETHODIMP
+nsLDAPOperation::AbandonExt()
+{
+ nsresult rv;
+ nsresult retStatus = NS_OK;
+
+ if ( mMessageListener == 0 || mMsgID == 0 ) {
+ NS_ERROR("nsLDAPOperation::AbandonExt(): mMessageListener or "
+ "mMsgId not initialized");
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ // XXX handle controls here
+ if (mServerControls || mClientControls) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+
+ rv = TranslateLDAPErrorToNSError(ldap_abandon_ext(mConnectionHandle,
+ mMsgID, 0, 0));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // try to remove it from the pendingOperations queue, if it's there.
+ // even if something goes wrong here, the abandon() has already succeeded
+ // succeeded (and there's nothing else the caller can reasonably do),
+ // so we only pay attention to this in debug builds.
+ //
+ // check mConnection in case we're getting bit by
+ // http://bugzilla.mozilla.org/show_bug.cgi?id=239729, wherein we
+ // theorize that ::Clearing the operation is nulling out the mConnection
+ // from another thread.
+ if (mConnection)
+ {
+ rv = mConnection->RemovePendingOperation(mMsgID);
+
+ if (NS_FAILED(rv)) {
+ // XXXdmose should we keep AbandonExt from happening on multiple
+ // threads at the same time? that's when this condition is most
+ // likely to occur. i _think_ the LDAP C SDK is ok with this; need
+ // to verify.
+ //
+ NS_WARNING("nsLDAPOperation::AbandonExt: "
+ "mConnection->RemovePendingOperation(this) failed.");
+ }
+ }
+
+ return retStatus;
+}
+
+NS_IMETHODIMP
+nsLDAPOperation::GetClientControls(nsIMutableArray **aControls)
+{
+ NS_IF_ADDREF(*aControls = mClientControls);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsLDAPOperation::SetClientControls(nsIMutableArray *aControls)
+{
+ mClientControls = aControls;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsLDAPOperation::GetServerControls(nsIMutableArray **aControls)
+{
+ NS_IF_ADDREF(*aControls = mServerControls);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsLDAPOperation::SetServerControls(nsIMutableArray *aControls)
+{
+ mServerControls = aControls;
+ return NS_OK;
+}
+
+// wrappers for ldap_add_ext
+//
+nsresult
+nsLDAPOperation::AddExt(const char *base,
+ nsIArray *mods,
+ LDAPControl **serverctrls,
+ LDAPControl **clientctrls)
+{
+ if (mMessageListener == 0) {
+ NS_ERROR("nsLDAPOperation::AddExt(): mMessageListener not set");
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ LDAPMod **attrs = 0;
+ int retVal = LDAP_SUCCESS;
+ uint32_t modCount = 0;
+ nsresult rv = mods->GetLength(&modCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (mods && modCount) {
+ attrs = static_cast<LDAPMod **>(nsMemory::Alloc((modCount + 1) *
+ sizeof(LDAPMod *)));
+ if (!attrs) {
+ NS_ERROR("nsLDAPOperation::AddExt: out of memory ");
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ nsAutoCString type;
+ uint32_t index;
+ for (index = 0; index < modCount && NS_SUCCEEDED(rv); ++index) {
+ attrs[index] = new LDAPMod();
+
+ if (!attrs[index])
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ nsCOMPtr<nsILDAPModification> modif(do_QueryElementAt(mods, index, &rv));
+ if (NS_FAILED(rv))
+ break;
+
+#ifdef NS_DEBUG
+ int32_t operation;
+ NS_ASSERTION(NS_SUCCEEDED(modif->GetOperation(&operation)) &&
+ ((operation & ~LDAP_MOD_BVALUES) == LDAP_MOD_ADD),
+ "AddExt can only add.");
+#endif
+
+ attrs[index]->mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES;
+
+ nsresult rv = modif->GetType(type);
+ if (NS_FAILED(rv))
+ break;
+
+ attrs[index]->mod_type = ToNewCString(type);
+
+ rv = CopyValues(modif, &attrs[index]->mod_bvalues);
+ if (NS_FAILED(rv))
+ break;
+ }
+
+ if (NS_SUCCEEDED(rv)) {
+ attrs[modCount] = 0;
+
+ retVal = ldap_add_ext(mConnectionHandle, base, attrs,
+ serverctrls, clientctrls, &mMsgID);
+ }
+ else
+ // reset the modCount so we correctly free the array.
+ modCount = index;
+ }
+
+ for (uint32_t counter = 0; counter < modCount; ++counter)
+ delete attrs[counter];
+
+ nsMemory::Free(attrs);
+
+ return NS_FAILED(rv) ? rv : TranslateLDAPErrorToNSError(retVal);
+}
+
+/**
+ * wrapper for ldap_add_ext(): kicks off an async add request.
+ *
+ * @param aBaseDn Base DN to search
+ * @param aModCount Number of modifications
+ * @param aMods Array of modifications
+ *
+ * XXX doesn't currently handle LDAPControl params
+ *
+ * void addExt (in AUTF8String aBaseDn, in unsigned long aModCount,
+ * [array, size_is (aModCount)] in nsILDAPModification aMods);
+ */
+NS_IMETHODIMP
+nsLDAPOperation::AddExt(const nsACString& aBaseDn,
+ nsIArray *aMods)
+{
+ PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
+ ("nsLDAPOperation::AddExt(): called with aBaseDn = '%s'",
+ PromiseFlatCString(aBaseDn).get()));
+
+ nsresult rv = AddExt(PromiseFlatCString(aBaseDn).get(), aMods, 0, 0);
+ if (NS_FAILED(rv))
+ return rv;
+
+ // make sure the connection knows where to call back once the messages
+ // for this operation start coming in
+ rv = mConnection->AddPendingOperation(mMsgID, this);
+
+ if (NS_FAILED(rv)) {
+ (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
+ PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
+ ("nsLDAPOperation::AddExt(): abandoned due to rv %x",
+ rv));
+ }
+ return rv;
+}
+
+// wrappers for ldap_delete_ext
+//
+nsresult
+nsLDAPOperation::DeleteExt(const char *base,
+ LDAPControl **serverctrls,
+ LDAPControl **clientctrls)
+{
+ if (mMessageListener == 0) {
+ NS_ERROR("nsLDAPOperation::DeleteExt(): mMessageListener not set");
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ return TranslateLDAPErrorToNSError(ldap_delete_ext(mConnectionHandle, base,
+ serverctrls, clientctrls,
+ &mMsgID));
+}
+
+/**
+ * wrapper for ldap_delete_ext(): kicks off an async delete request.
+ *
+ * @param aBaseDn Base DN to delete
+ *
+ * XXX doesn't currently handle LDAPControl params
+ *
+ * void deleteExt(in AUTF8String aBaseDn);
+ */
+NS_IMETHODIMP
+nsLDAPOperation::DeleteExt(const nsACString& aBaseDn)
+{
+ PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
+ ("nsLDAPOperation::DeleteExt(): called with aBaseDn = '%s'",
+ PromiseFlatCString(aBaseDn).get()));
+
+ nsresult rv = DeleteExt(PromiseFlatCString(aBaseDn).get(), 0, 0);
+ if (NS_FAILED(rv))
+ return rv;
+
+ // make sure the connection knows where to call back once the messages
+ // for this operation start coming in
+ rv = mConnection->AddPendingOperation(mMsgID, this);
+
+ if (NS_FAILED(rv)) {
+ (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
+ PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
+ ("nsLDAPOperation::AddExt(): abandoned due to rv %x",
+ rv));
+ }
+ return rv;
+}
+
+// wrappers for ldap_modify_ext
+//
+nsresult
+nsLDAPOperation::ModifyExt(const char *base,
+ nsIArray *mods,
+ LDAPControl **serverctrls,
+ LDAPControl **clientctrls)
+{
+ if (mMessageListener == 0) {
+ NS_ERROR("nsLDAPOperation::ModifyExt(): mMessageListener not set");
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ LDAPMod **attrs = 0;
+ int retVal = 0;
+ uint32_t modCount = 0;
+ nsresult rv = mods->GetLength(&modCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (modCount && mods) {
+ attrs = static_cast<LDAPMod **>(nsMemory::Alloc((modCount + 1) *
+ sizeof(LDAPMod *)));
+ if (!attrs) {
+ NS_ERROR("nsLDAPOperation::ModifyExt: out of memory ");
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ nsAutoCString type;
+ uint32_t index;
+ for (index = 0; index < modCount && NS_SUCCEEDED(rv); ++index) {
+ attrs[index] = new LDAPMod();
+ if (!attrs[index])
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ nsCOMPtr<nsILDAPModification> modif(do_QueryElementAt(mods, index, &rv));
+ if (NS_FAILED(rv))
+ break;
+
+ int32_t operation;
+ nsresult rv = modif->GetOperation(&operation);
+ if (NS_FAILED(rv))
+ break;
+
+ attrs[index]->mod_op = operation | LDAP_MOD_BVALUES;
+
+ rv = modif->GetType(type);
+ if (NS_FAILED(rv))
+ break;
+
+ attrs[index]->mod_type = ToNewCString(type);
+
+ rv = CopyValues(modif, &attrs[index]->mod_bvalues);
+ if (NS_FAILED(rv))
+ break;
+ }
+
+ if (NS_SUCCEEDED(rv)) {
+ attrs[modCount] = 0;
+
+ retVal = ldap_modify_ext(mConnectionHandle, base, attrs,
+ serverctrls, clientctrls, &mMsgID);
+ }
+ else
+ // reset the modCount so we correctly free the array.
+ modCount = index;
+
+ }
+
+ for (uint32_t counter = 0; counter < modCount; ++counter)
+ delete attrs[counter];
+
+ nsMemory::Free(attrs);
+
+ return NS_FAILED(rv) ? rv : TranslateLDAPErrorToNSError(retVal);
+}
+
+/**
+ * wrapper for ldap_modify_ext(): kicks off an async modify request.
+ *
+ * @param aBaseDn Base DN to modify
+ * @param aModCount Number of modifications
+ * @param aMods Array of modifications
+ *
+ * XXX doesn't currently handle LDAPControl params
+ *
+ * void modifyExt (in AUTF8String aBaseDn, in unsigned long aModCount,
+ * [array, size_is (aModCount)] in nsILDAPModification aMods);
+ */
+NS_IMETHODIMP
+nsLDAPOperation::ModifyExt(const nsACString& aBaseDn,
+ nsIArray *aMods)
+{
+ PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
+ ("nsLDAPOperation::ModifyExt(): called with aBaseDn = '%s'",
+ PromiseFlatCString(aBaseDn).get()));
+
+ nsresult rv = ModifyExt(PromiseFlatCString(aBaseDn).get(),
+ aMods, 0, 0);
+ if (NS_FAILED(rv))
+ return rv;
+
+ // make sure the connection knows where to call back once the messages
+ // for this operation start coming in
+ rv = mConnection->AddPendingOperation(mMsgID, this);
+
+ if (NS_FAILED(rv)) {
+ (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
+ PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
+ ("nsLDAPOperation::AddExt(): abandoned due to rv %x",
+ rv));
+ }
+ return rv;
+}
+
+// wrappers for ldap_rename
+//
+nsresult
+nsLDAPOperation::Rename(const char *base,
+ const char *newRDn,
+ const char *newParent,
+ bool deleteOldRDn,
+ LDAPControl **serverctrls,
+ LDAPControl **clientctrls)
+{
+ if (mMessageListener == 0) {
+ NS_ERROR("nsLDAPOperation::Rename(): mMessageListener not set");
+ return NS_ERROR_NOT_INITIALIZED;
+ }
+
+ return TranslateLDAPErrorToNSError(ldap_rename(mConnectionHandle, base,
+ newRDn, newParent,
+ deleteOldRDn, serverctrls,
+ clientctrls, &mMsgID));
+}
+
+/**
+ * wrapper for ldap_rename(): kicks off an async rename request.
+ *
+ * @param aBaseDn Base DN to rename
+ * @param aNewRDn New relative DN
+ * @param aNewParent DN of the new parent under which to move the
+ *
+ * XXX doesn't currently handle LDAPControl params
+ *
+ * void rename(in AUTF8String aBaseDn, in AUTF8String aNewRDn,
+ * in AUTF8String aNewParent, in boolean aDeleteOldRDn);
+ */
+NS_IMETHODIMP
+nsLDAPOperation::Rename(const nsACString& aBaseDn,
+ const nsACString& aNewRDn,
+ const nsACString& aNewParent,
+ bool aDeleteOldRDn)
+{
+ PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
+ ("nsLDAPOperation::Rename(): called with aBaseDn = '%s'",
+ PromiseFlatCString(aBaseDn).get()));
+
+ nsresult rv = Rename(PromiseFlatCString(aBaseDn).get(),
+ PromiseFlatCString(aNewRDn).get(),
+ PromiseFlatCString(aNewParent).get(),
+ aDeleteOldRDn, 0, 0);
+ if (NS_FAILED(rv))
+ return rv;
+
+ // make sure the connection knows where to call back once the messages
+ // for this operation start coming in
+ rv = mConnection->AddPendingOperation(mMsgID, this);
+
+ if (NS_FAILED(rv)) {
+ (void)ldap_abandon_ext(mConnectionHandle, mMsgID, 0, 0);
+ PR_LOG(gLDAPLogModule, PR_LOG_DEBUG,
+ ("nsLDAPOperation::AddExt(): abandoned due to rv %x",
+ rv));
+ }
+ return rv;
+}
+
+// wrappers for ldap_search_ext
+//
+
+/* static */
+nsresult
+nsLDAPOperation::CopyValues(nsILDAPModification* aMod, berval*** aBValues)
+{
+ nsCOMPtr<nsIArray> values;
+ nsresult rv = aMod->GetValues(getter_AddRefs(values));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ uint32_t valuesCount;
+ rv = values->GetLength(&valuesCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ *aBValues = static_cast<berval **>
+ (nsMemory::Alloc((valuesCount + 1) *
+ sizeof(berval *)));
+ if (!*aBValues)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ uint32_t valueIndex;
+ for (valueIndex = 0; valueIndex < valuesCount; ++valueIndex) {
+ nsCOMPtr<nsILDAPBERValue> value(do_QueryElementAt(values, valueIndex, &rv));
+
+ berval* bval = new berval;
+ if (NS_FAILED(rv) || !bval) {
+ for (uint32_t counter = 0;
+ counter < valueIndex && counter < valuesCount;
+ ++counter)
+ delete (*aBValues)[valueIndex];
+
+ nsMemory::Free(*aBValues);
+ delete bval;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+ value->Get((uint32_t*)&bval->bv_len,
+ (uint8_t**)&bval->bv_val);
+ (*aBValues)[valueIndex] = bval;
+ }
+
+ (*aBValues)[valuesCount] = 0;
+ return NS_OK;
+}
--- /dev/null
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#filter substitution
+[App]
+Name=Trustedbird
+Version=@APP_VERSION@
+BuildID=@GRE_BUILDID@
+#ifdef MOZ_SOURCE_REPO
+SourceRepository=@MOZ_SOURCE_REPO@
+#endif
+#ifdef MOZ_SOURCE_STAMP
+SourceStamp=@MOZ_SOURCE_STAMP@
+#endif
+ID={3550f703-e582-4d05-9a08-453d09bdfdc6}
+
+[Gecko]
+MinVersion=@GRE_MILESTONE@
+MaxVersion=@GRE_MILESTONE@
+
+[XRE]
+EnableProfileMigrator=1
+EnableExtensionManager=1
+
+[Crash Reporter]
+#if MOZILLA_OFFICIAL
+Enabled=1
+#endif
+ServerURL=https://crash-reports.mozilla.com/submit
--- /dev/null
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH = @DEPTH@
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+include $(topsrcdir)/config/rules.mk
+
+FILES := \
+ mimeTypes.rdf \
+ localstore.rdf \
+ securityLabelPolicy-sample.xml \
+ secureHeadersDefault.xml \
+ $(NULL)
+
+libs:: $(FILES)
+ $(SYSINSTALL) $(IFLAGS1) $^ $(DIST)/bin/defaults/profile
+
+install:: $(FILES)
+ $(SYSINSTALL) $(IFLAGS1) $^ $(DESTDIR)$(mozappdir)/defaults/profile
--- /dev/null
+/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#filter substitution
+
+#ifdef XP_UNIX
+#ifndef XP_MACOSX
+#define UNIX_BUT_NOT_MAC
+#endif
+#endif
+
+pref("general.useragent.locale", "@AB_CD@");
+pref("general.skins.selectedSkin", "classic/1.0");
+
+#ifdef XP_MACOSX
+pref("browser.chromeURL", "chrome://messenger/content/messengercompose/messengercompose.xul");
+pref("mail.biff.animate_dock_icon", false);
+#endif
+
+pref("mail.rights.version", 0);
+
+// Don't show the about:rights notification in debug or non-official builds.
+#ifdef DEBUG
+pref("mail.rights.override", true);
+#endif
+#ifndef MOZILLA_OFFICIAL
+pref("mail.rights.override", true);
+#endif
+
+// gtk2 (*nix) lacks transparent/translucent drag support (bug 376238), so we
+// want to disable it so people can see where they are dragging things.
+// (Stock gtk drag icons will be used instead.)
+#ifdef MOZ_WIDGET_GTK2
+pref("nglayout.enable_drag_images", false);
+#endif
+
+// The minimum delay in seconds for the timer to fire.
+// default=2 minutes
+pref("app.update.timerMinimumDelay", 120);
+
+// App-specific update preferences
+
+// The interval to check for updates (app.update.interval) is defined in
+// the branding files.
+
+// Enables some extra Application Update Logging (can reduce performance)
+pref("app.update.log", false);
+
+// When |app.update.cert.requireBuiltIn| is true or not specified the
+// final certificate and all certificates the connection is redirected to before
+// the final certificate for the url specified in the |app.update.url|
+// preference must be built-in.
+pref("app.update.cert.requireBuiltIn", true);
+
+// When |app.update.cert.checkAttributes| is true or not specified the
+// certificate attributes specified in the |app.update.certs.| preference branch
+// are checked against the certificate for the url specified by the
+// |app.update.url| preference.
+pref("app.update.cert.checkAttributes", true);
+
+// The number of certificate attribute check failures to allow for background
+// update checks before notifying the user of the failure. User initiated update
+// checks always notify the user of the certificate attribute check failure.
+pref("app.update.cert.maxErrors", 5);
+
+// The |app.update.certs.| preference branch contains branches that are
+// sequentially numbered starting at 1 that contain attribute name / value
+// pairs for the certificate used by the server that hosts the update xml file
+// as specified in the |app.update.url| preference. When these preferences are
+// present the following conditions apply for a successful update check:
+// 1. the uri scheme must be https
+// 2. the preference name must exist as an attribute name on the certificate and
+// the value for the name must be the same as the value for the attribute name
+// on the certificate.
+// If these conditions aren't met it will be treated the same as when there is
+// no update available. This validation will not be performed when using the
+// |app.update.url.override| preference for update checking.
+pref("app.update.certs.1.issuerName", "CN=Thawte SSL CA,O=\"Thawte, Inc.\",C=US");
+pref("app.update.certs.1.commonName", "aus3.mozilla.org");
+
+pref("app.update.certs.2.issuerName", "CN=DigiCert Secure Server CA,O=DigiCert Inc,C=US");
+pref("app.update.certs.2.commonName", "aus3.mozilla.org");
+
+// Whether or not app updates are enabled
+pref("app.update.enabled", false);
+
+// This preference turns on app.update.mode and allows automatic download and
+// install to take place. We use a separate boolean toggle for this to make
+// the UI easier to construct.
+pref("app.update.auto", false);
+
+// Defines how the Application Update Service notifies the user about updates:
+//
+// AUM Set to: Minor Releases: Major Releases:
+// 0 download no prompt download no prompt
+// 1 download no prompt download no prompt if no incompatibilities
+// 2 download no prompt prompt
+//
+// See chart in nsUpdateService.js.in for more details
+//
+pref("app.update.mode", 1);
+
+// If set to true, the Update Service will present no UI for any event.
+pref("app.update.silent", false);
+
+// If set to true, the Update Service will apply updates in the background
+// when it finishes downloading them.
+pref("app.update.staging.enabled", true);
+
+// Update service URL:
+pref("app.update.url", "");
+
+// URL user can browse to manually if for some reason all update installation
+// attempts fail.
+pref("app.update.url.manual", "https://adullact.net/plugins/mediawiki/wiki/milimail/index.php/Trustedbird_Project");
+// A default value for the "More information about this update" link
+// supplied in the "An update is available" page of the update wizard.
+pref("app.update.url.details", "https://adullact.net/plugins/mediawiki/wiki/milimail/index.php/Trustedbird_Project");
+// User-settable override to app.update.url for testing purposes.
+//pref("app.update.url.override", "");
+
+// app.update.promptWaitTime is in branding section
+
+// Show the Update Checking/Ready UI when the user was idle for x seconds
+pref("app.update.idletime", 60);
+
+// Whether or not we show a dialog box informing the user that the update was
+// successfully applied. This is off in Firefox by default since we show a
+// upgrade start page instead! Other apps may wish to show this UI, and supply
+// a whatsNewURL field in their brand.properties that contains a link to a page
+// which tells users what's new in this new update.
+pref("app.update.showInstalledUI", false);
+
+// Whether or not to attempt using the service for updates.
+#ifdef MOZ_MAINTENANCE_SERVICE
+pref("app.update.service.enabled", true);
+#endif
+
+// Release notes URL
+pref("app.releaseNotesURL", "https://adullact.net/plugins/mediawiki/wiki/milimail/index.php/Trustedbird_Project");
+// Base URL for web-based support pages.
+pref("app.support.baseURL", "http://support.live.mozillamessaging.com/%LOCALE%/%APP%/%APPBUILDID%/");
+
+// Controls enabling of the extension system logging (can reduce performance)
+pref("extensions.logging.enabled", false);
+
+// Disables strict compatibility, making addons compatible-by-default.
+pref("extensions.strictCompatibility", false);
+
+// Specifies a minimum maxVersion an addon needs to say it's compatible with
+// for it to be compatible by default.
+pref("extensions.minCompatibleAppVersion", "5.0");
+
+pref("extensions.update.autoUpdateDefault", true);
+
+// Disable add-ons installed into the shared user and shared system areas by
+// default. This does not include the application directory. See the SCOPE
+// constants in AddonManager.jsm for values to use here
+pref("extensions.autoDisableScopes", 15);
+
+// Preferences for AMO integration
+pref("extensions.getAddons.cache.enabled", true);
+pref("extensions.getAddons.maxResults", 15);
+pref("extensions.getAddons.get.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/guid:%IDS%?src=thunderbird&appOS=%OS%&appVersion=%VERSION%");
+pref("extensions.getAddons.getWithPerformance.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/guid:%IDS%?src=thunderbird&appOS=%OS%&appVersion=%VERSION%&tMain=%TIME_MAIN%&tFirstPaint=%TIME_FIRST_PAINT%&tSessionRestored=%TIME_SESSION_RESTORED%");
+pref("extensions.getAddons.search.browseURL", "https://addons.mozilla.org/%LOCALE%/%APP%/search?q=%TERMS%");
+pref("extensions.getAddons.search.url", "https://services.addons.mozilla.org/%LOCALE%/%APP%/api/%API_VERSION%/search/%TERMS%/all/%MAX_RESULTS%/%OS%/%VERSION%/%COMPATIBILITY_MODE%?src=thunderbird");
+pref("extensions.webservice.discoverURL", "https://services.addons.mozilla.org/%LOCALE%/%APP%/discovery/pane/%VERSION%/%OS%");
+
+// Blocklist preferences
+pref("extensions.blocklist.enabled", true);
+pref("extensions.blocklist.interval", 86400);
+pref("extensions.blocklist.url", "https://addons.mozilla.org/blocklist/3/%APP_ID%/%APP_VERSION%/%PRODUCT%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/%OS_VERSION%/%DISTRIBUTION%/%DISTRIBUTION_VERSION%/%PING_COUNT%/%TOTAL_PING_COUNT%/%DAYS_SINCE_LAST_PING%/");
+pref("extensions.blocklist.detailsURL", "https://addons.mozilla.org/%LOCALE%/%APP%/blocked/");
+pref("extensions.blocklist.itemURL", "https://addons.mozilla.org/%LOCALE%/%APP%/blocked/%blockID%");
+
+// Enables some extra Extension System Logging (can reduce performance)
+pref("extensions.logging.enabled", false);
+
+// Symmetric (can be overridden by individual extensions) update preferences.
+// e.g.
+// extensions.{GUID}.update.enabled
+// extensions.{GUID}.update.url
+// extensions.{GUID}.update.interval
+// .. etc ..
+//
+pref("extensions.update.enabled", true);
+pref("extensions.update.url", "https://versioncheck.addons.mozilla.org/update/VersionCheck.php?reqVersion=%REQ_VERSION%&id=%ITEM_ID%&version=%ITEM_VERSION%&maxAppVersion=%ITEM_MAXAPPVERSION%&status=%ITEM_STATUS%&appID=%APP_ID%&appVersion=%APP_VERSION%&appOS=%APP_OS%&appABI=%APP_ABI%&locale=%APP_LOCALE%¤tAppVersion=%CURRENT_APP_VERSION%&updateType=%UPDATE_TYPE%&compatMode=%COMPATIBILITY_MODE%");
+
+pref("extensions.update.interval", 86400); // Check for updates to Extensions and
+ // Themes every day
+
+pref("extensions.dss.enabled", false); // Dynamic Skin Switching
+pref("extensions.dss.switchPending", false); // Non-dynamic switch pending after next
+
+pref("extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.name", "chrome://messenger/locale/messenger.properties");
+pref("extensions.{972ce4c6-7e08-4474-a285-3208198ce6fd}.description", "chrome://messenger/locale/messenger.properties");
+
+pref("lightweightThemes.update.enabled", true);
+
+pref("xpinstall.whitelist.add", "addons.mozilla.org");
+pref("xpinstall.whitelist.add.36", "getpersonas.com");
+
+pref("general.smoothScroll", true);
+#ifdef UNIX_BUT_NOT_MAC
+pref("general.autoScroll", false);
+#else
+pref("general.autoScroll", true);
+#endif
+
+pref("mail.shell.checkDefaultClient", true);
+pref("mail.spellcheck.inline", true);
+
+pref("mail.folder.views.version", 0);
+
+// target folder URI used for the last move or copy
+pref("mail.last_msg_movecopy_target_uri", "");
+// last move or copy operation was a move
+pref("mail.last_msg_movecopy_was_move", true);
+
+//Set the font color for links to something lighter
+pref("browser.anchor_color", "#0B6CDA");
+
+#ifdef XP_WIN
+pref("browser.preferences.instantApply", false);
+#else
+pref("browser.preferences.instantApply", true);
+#endif
+#ifdef XP_MACOSX
+pref("browser.preferences.animateFadeIn", true);
+#else
+pref("browser.preferences.animateFadeIn", false);
+#endif
+
+pref("browser.download.show_plugins_in_list", false);
+pref("browser.download.hide_plugins_without_extensions", true);
+
+pref("accessibility.typeaheadfind", false);
+pref("accessibility.typeaheadfind.timeout", 5000);
+pref("accessibility.typeaheadfind.linksonly", false);
+pref("accessibility.typeaheadfind.flashBar", 1);
+
+pref("mail.close_message_window.on_delete", false);
+
+// Number of lines of To/CC/BCC address headers to show before "more"
+// truncates the list.
+pref("mailnews.headers.show_n_lines_before_more", 1);
+
+// We want to keep track of what items are appropriate in
+// localstore.rdf. We use versioning to scrub out the things
+// that have become obsolete.
+pref("mail.ui-rdf.version", 0);
+
+/////////////////////////////////////////////////////////////////
+// Overrides of the core mailnews.js prefs
+/////////////////////////////////////////////////////////////////
+pref("mail.showCondensedAddresses", true); // show the friendly display name for people I know
+
+pref("mailnews.attachments.display.start_expanded", false);
+// hidden pref for changing how we present attachments in the message pane
+pref("mailnews.attachments.display.view", 0);
+pref("mail.pane_config.dynamic", 0);
+pref("mailnews.reuse_thread_window2", true);
+pref("editor.singleLine.pasteNewlines", 4); // substitute commas for new lines in single line text boxes
+
+// hidden pref to ensure a certain number of headers in the message pane
+// to avoid the height of the header area from changing when headers are present / not present
+pref("mailnews.headers.minNumHeaders", 0); // 0 means we ignore this pref
+
+// 0=no header, 1="<author> wrote:", 2="On <date> <author> wrote:"
+// 3="<author> wrote On <date>:", 4=user specified
+pref("mailnews.reply_header_type", 2);
+
+pref("mail.operate_on_msgs_in_collapsed_threads", true);
+pref("mail.warn_on_collapsed_thread_operation", true);
+pref("mail.warn_on_shift_delete", true);
+
+// only affects cookies from RSS articles
+// 0-Accept, 1-dontAcceptForeign, 2-dontUse
+pref("network.cookie.cookieBehavior", 0);
+
+// clear the SeaMonkey pref, so we don't hear about how we don't have a chrome
+// package registered for editor-region while opening about:config
+pref("editor.throbber.url", "");
+
+// 0=as attachment 2=default forward as inline with attachments
+pref("mail.forward_message_mode", 2);
+
+// 0=ask, 1=plain, 2=html, 3=both
+pref("mail.default_html_action", 3);
+
+/////////////////////////////////////////////////////////////////
+// End core mailnews.js pref overrides
+/////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////
+// Overrides for generic app behavior from the core all.js
+/////////////////////////////////////////////////////////////////
+
+pref("browser.hiddenWindowChromeURL", "chrome://messenger/content/hiddenWindow.xul");
+
+pref("offline.startup_state", 2);
+// 0 Ask before sending unsent messages when going online
+// 1 Always send unsent messages when going online
+// 2 Never send unsent messages when going online
+pref("offline.send.unsent_messages", 0);
+
+// 0 Ask before synchronizing the offline mail store when going offline
+// 1 Always synchronize the offline store when going offline
+// 2 Never synchronize the offline store when going offline
+pref("offline.download.download_messages", 0);
+
+#ifdef UNIX_BUT_NOT_MAC
+pref("offline.autoDetect", false);
+#else
+// Windows and Mac can automatically move the user offline or online based on
+// the network connection.
+pref("offline.autoDetect", true);
+#endif
+
+// Expose only select protocol handlers. All others should go
+// through the external protocol handler route.
+// If you are changing this list, you may need to also consider changing the
+// list in nsMsgContentPolicy::IsExposedProtocol.
+pref("network.protocol-handler.expose-all", false);
+pref("network.protocol-handler.expose.mailto", true);
+pref("network.protocol-handler.expose.news", true);
+pref("network.protocol-handler.expose.snews", true);
+pref("network.protocol-handler.expose.nntp", true);
+pref("network.protocol-handler.expose.imap", true);
+pref("network.protocol-handler.expose.addbook", true);
+pref("network.protocol-handler.expose.pop", true);
+pref("network.protocol-handler.expose.mailbox", true);
+// Although we allow these to be exposed internally, there are various places
+// (e.g. message pane) where we may divert them out to external applications.
+pref("network.protocol-handler.expose.about", true);
+pref("network.protocol-handler.expose.http", true);
+pref("network.protocol-handler.expose.https", true);
+
+// suppress external-load warning for standard browser schemes
+pref("network.protocol-handler.warn-external.http", false);
+pref("network.protocol-handler.warn-external.https", false);
+pref("network.protocol-handler.warn-external.ftp", false);
+
+pref("network.hosts.smtp_server", "mail");
+pref("network.hosts.pop_server", "mail");
+
+pref("security.warn_entering_secure", false);
+pref("security.warn_entering_weak", false);
+pref("security.warn_leaving_secure", false);
+pref("security.warn_viewing_mixed", false);
+
+pref("general.config.obscure_value", 0); // for MCD .cfg files
+
+pref("browser.display.auto_quality_min_font_size", 0);
+
+pref("view_source.syntax_highlight", false);
+
+pref("toolkit.telemetry.infoURL", "http://www.mozilla.org/thunderbird/legal/privacy/#telemetry");
+
+pref("mousewheel.withcontrolkey.action", 3);
+/////////////////////////////////////////////////////////////////
+// End core all.js pref overrides
+/////////////////////////////////////////////////////////////////
+
+/////////////////////////////////////////////////////////////////
+// Generic browser related prefs.
+/////////////////////////////////////////////////////////////////
+pref("browser.send_pings", false);
+pref("browser.chrome.toolbar_tips", true);
+pref("browser.xul.error_pages.enabled", true);
+pref("browser.xul.error_pages.expert_bad_cert", false);
+
+// Attachment download manager settings
+pref("mail.attachment.store.version", 0);
+pref("browser.download.useDownloadDir", false);
+pref("browser.download.folderList", 0);
+pref("browser.download.manager.showAlertOnComplete", false);
+pref("browser.download.manager.showAlertInterval", 2000);
+pref("browser.download.manager.retention", 1);
+pref("browser.download.manager.showWhenStarting", true);
+pref("browser.download.manager.closeWhenDone", true);
+pref("browser.download.manager.openDelay", 100);
+pref("browser.download.manager.focusWhenStarting", false);
+pref("browser.download.manager.flashCount", 0);
+pref("browser.download.manager.addToRecentDocs", true);
+
+pref("spellchecker.dictionary", "");
+// Dictionary download preference
+pref("spellchecker.dictionaries.download.url", "https://addons.mozilla.org/%LOCALE%/%APP%/dictionaries/");
+
+// profile.force.migration can be used to bypass the migration wizard, forcing migration from a particular
+// mail application without any user intervention. Possible values are:
+// seamonkey (mozilla suite), eudora, oexpress, outlook.
+pref("profile.force.migration", "");
+
+// prefs to control the mail alert notification
+pref("alerts.slideIncrementTime", 50);
+pref("alerts.totalOpenTime", 10000);
+
+// analyze urls in mail messages for scams
+pref("mail.phishing.detection.enabled", true);
+// If phishing detection is enabled, allow fine grained control
+// of the local, static tests
+pref("mail.phishing.detection.ipaddresses", true);
+pref("mail.phishing.detection.mismatched_hosts", true);
+
+pref("browser.safebrowsing.enabled", false);
+
+// Non-enhanced mode (local url lists) URL list to check for updates
+pref("browser.safebrowsing.provider.0.updateURL", "");
+pref("browser.safebrowsing.dataProvider", 0);
+
+// Does the provider name need to be localizable?
+pref("browser.safebrowsing.provider.0.name", "");
+pref("browser.safebrowsing.provider.0.lookupURL", "");
+pref("browser.safebrowsing.provider.0.keyURL", "");
+pref("browser.safebrowsing.provider.0.reportURL", "");
+
+// HTML report pages
+pref("browser.safebrowsing.provider.0.reportGenericURL", "http://{moz:locale}.phish-generic.mozilla.com/?hl={moz:locale}");
+pref("browser.safebrowsing.provider.0.reportErrorURL", "http://{moz:locale}.phish-error.mozilla.com/?hl={moz:locale}");
+pref("browser.safebrowsing.provider.0.reportPhishURL", "http://{moz:locale}.phish-report.mozilla.com/?hl={moz:locale}");
+
+// FAQ URL
+// XXX Firefox is hard-coded because we haven't got our own version yet.
+pref("browser.safebrowsing.warning.infoURL", "https://www.mozilla.org/%LOCALE%/firefox/phishing-protection/");
+
+// prevent status-bar spoofing even if people are foolish enough to turn on JS
+pref("dom.disable_window_status_change", true);
+
+// If a message is opened using Enter or a double click, what should we do?
+// 0 - open it in a new window
+// 1 - open it in an existing window
+// 2 - open it in a new tab
+pref("mail.openMessageBehavior", 2);
+pref("mail.openMessageBehavior.version", 0);
+// If messages or folders are opened using the context menu or a middle click,
+// should we open them in the foreground or in the background?
+pref("mail.tabs.loadInBackground", true);
+
+// Tabs
+pref("mail.tabs.tabMinWidth", 100);
+pref("mail.tabs.tabMaxWidth", 210);
+pref("mail.tabs.tabClipWidth", 140);
+pref("mail.tabs.autoHide", false);
+pref("mail.tabs.closeWindowWithLastTab", true);
+
+// Where to show tab close buttons:
+// 0 - active tab only
+// 1 - all tabs until tabClipWidth is reached, then active tab only
+// 2 - no close buttons
+// 3 - at the end of the tabstrip
+pref("mail.tabs.closeButtons", 1);
+
+// Allow the tabs to be in the titlebar on supported systems
+pref("mail.tabs.drawInTitlebar", true);
+
+// The breakpad report server to link to in about:crashes
+pref("breakpad.reportURL", "http://crash-stats.mozilla.com/report/index/");
+
+// OS Integrated Search and Indexing
+#ifdef XP_WIN
+pref("mail.winsearch.enable", false);
+pref("mail.winsearch.firstRunDone", false);
+#else
+#ifdef XP_MACOSX
+pref("mail.spotlight.enable", false);
+pref("mail.spotlight.firstRunDone", false);
+#endif
+#endif
+
+// -- Windows Search/Spotlight logging options
+#ifdef XP_WIN
+// Should we output warnings and errors to the "error console"?
+pref("mail.winsearch.logging.console", false);
+// Should we output all output levels to stdout via dump?
+pref("mail.winsearch.logging.dump", false);
+#else
+#ifdef XP_MACOSX
+// Should we output warnings and errors to the "error console"?
+pref("mail.spotlight.logging.console", false);
+// Should we output all output levels to stdout via dump?
+pref("mail.spotlight.logging.dump", false);
+#endif
+#endif
+
+// Whether to use a panel that looks like an OS X sheet for customization
+#ifdef XP_MACOSX
+pref("toolbar.customization.usesheet", true);
+#else
+pref("toolbar.customization.usesheet", false);
+#endif
+
+// Number of recipient rows shown by default
+pref("mail.compose.addresswidget.numRowsShownDefault", 3);
+
+// Check for missing attachments?
+pref("mail.compose.attachment_reminder", true);
+// Words that should trigger a missing attachments warning.
+pref("mail.compose.attachment_reminder_keywords", "chrome://messenger/locale/messengercompose/composeMsgs.properties");
+// When no action is taken on the inline missing attachement notification,
+// show an alert on send?
+pref("mail.compose.attachment_reminder_aggressive", true);
+
+// True if the user should be notified when attaching big files
+pref("mail.compose.big_attachments.notify", true);
+// Size (in kB) to automatically prompt for conversion of attachments to
+// cloud links
+pref("mail.compose.big_attachments.threshold_kb", 5120);
+// True if the user should be notified that links will be inserted into
+// their message when the upload is completed
+pref("mail.compose.big_attachments.insert_notification", true);
+
+// Set this to false to prevent instrumentation from happening, e.g., user
+// has opted out, or an enterprise wants to disable it from the git go.
+pref("mail.instrumentation.askUser", true);
+pref("mail.instrumentation.userOptedIn", false);
+pref("mail.instrumentation.postUrl", "https://www.mozilla.org/instrumentation");
+// not sure how this will be formatted - would be nice to make it extensible.
+pref("mail.instrumentation.lastNotificationSent", "");
+
+pref("browser.formfill.enable", true);
+
+// Disable autoplay as we don't handle audio elements in emails very well.
+// See bug 515082.
+pref("media.autoplay.enabled", false);
+
+// whether to hide the timeline view by default in the faceted search display
+pref("gloda.facetview.hidetimeline", true);
+
+// Enable gloda by default!
+pref("mailnews.database.global.indexer.enabled", true);
+// Show gloda errors in the error console
+pref("mailnews.database.global.logging.console", true);
+
+// page to load to find good header add-ons
+pref("mailnews.migration.header_addons_url","http://live.mozillamessaging.com/%APP%/addons/search?q=header&locale=%LOCALE%&lver=%VERSION%&hver=%VERSION%&os=%OS%");
+
+// Serif fonts look dated. Switching those language families to sans-serif
+// where we think it makes sense. Worth investigating for other font families
+// as well, viz bug 520824. See all.js for the rest of the font families
+// preferences.
+pref("font.default", "sans-serif");
+pref("font.default.x-unicode", "sans-serif");
+pref("font.default.x-western", "sans-serif");
+pref("font.default.x-central-euro", "sans-serif");
+pref("font.default.x-cyrillic", "sans-serif");
+pref("font.default.x-baltic", "sans-serif");
+pref("font.default.el", "sans-serif");
+pref("font.default.tr", "sans-serif");
+
+#ifdef XP_MACOSX
+pref("font.name.sans-serif.x-unicode", "Lucida Grande");
+pref("font.name.monospace.x-unicode", "Menlo");
+pref("font.name-list.sans-serif.x-unicode", "Lucida Grande");
+pref("font.name-list.monospace.x-unicode", "Menlo, Monaco");
+pref("font.size.variable.x-unicode", 15);
+pref("font.size.fixed.x-unicode", 12);
+
+pref("font.name.sans-serif.x-western", "Lucida Grande");
+pref("font.name.monospace.x-western", "Menlo");
+pref("font.name-list.sans-serif.x-western", "Lucida Grande");
+pref("font.name-list.monospace.x-western", "Menlo, Monaco");
+pref("font.size.variable.x-western", 15);
+pref("font.size.fixed.x-western", 12);
+
+pref("font.name.sans-serif.x-central-euro", "Lucida Grande");
+pref("font.name.monospace.x-central-euro", "Menlo");
+pref("font.name-list.sans-serif.x-central-euro", "Lucida Grande");
+pref("font.name-list.monospace.x-central-euro", "Menlo, Monaco");
+pref("font.size.variable.x-central-euro", 15);
+pref("font.size.fixed.x-central-euro", 12);
+
+pref("font.name.sans-serif.x-cyrillic", "Lucida Grande");
+pref("font.name.monospace.x-cyrillic", "Menlo");
+pref("font.name-list.sans-serif.x-cyrillic", "Lucida Grande");
+pref("font.name-list.monospace.x-cyrillic", "Menlo, Monaco");
+pref("font.size.variable.x-cyrillic", 15);
+pref("font.size.fixed.x-cyrillic", 12);
+
+pref("font.name.sans-serif.x-baltic", "Lucida Grande");
+pref("font.name.monospace.x-baltic", "Menlo");
+pref("font.name-list.sans-serif.x-baltic", "Lucida Grande");
+pref("font.name-list.monospace.x-baltic", "Menlo, Monaco");
+pref("font.size.variable.x-baltic", 15);
+pref("font.size.fixed.x-baltic", 12);
+
+pref("font.name.sans-serif.el", "Lucida Grande");
+pref("font.name.monospace.el", "Menlo");
+pref("font.name-list.sans-serif.el", "Lucida Grande");
+pref("font.name-list.monospace.el", "Menlo, Monaco");
+pref("font.size.variable.el", 15);
+pref("font.size.fixed.el", 12);
+
+pref("font.name.sans-serif.tr", "Lucida Grande");
+pref("font.name.monospace.tr", "Menlo");
+pref("font.name-list.sans-serif.tr", "Lucida Grande");
+pref("font.name-list.monospace.tr", "Menlo, Monaco");
+pref("font.size.variable.tr", 15);
+pref("font.size.fixed.tr", 12);
+#endif
+
+// Since different versions of Windows need different settings, we'll handle
+// this in mailMigrator.js.
+
+// Linux, in other words. Other OSes may wish to override.
+#ifdef UNIX_BUT_NOT_MAC
+// The font.name-list fallback is defined in case font.name isn't
+// present -- e.g. in case a profile that's been used on Windows Vista or above
+// is used on Linux.
+pref("font.name-list.serif.x-unicode", "serif");
+pref("font.name-list.sans-serif.x-unicode", "sans-serif");
+pref("font.name-list.monospace.x-unicode", "monospace");
+
+pref("font.name-list.serif.x-western", "serif");
+pref("font.name-list.sans-serif.x-western", "sans-serif");
+pref("font.name-list.monospace.x-western", "monospace");
+
+pref("font.name-list.serif.x-central-euro", "serif");
+pref("font.name-list.sans-serif.x-central-euro", "sans-serif");
+pref("font.name-list.monospace.x-central-euro", "monospace");
+
+pref("font.name-list.serif.x-cyrillic", "serif");
+pref("font.name-list.sans-serif.x-cyrillic", "sans-serif");
+pref("font.name-list.monospace.x-cyrillic", "monospace");
+
+pref("font.name-list.serif.x-baltic", "serif");
+pref("font.name-list.sans-serif.x-baltic", "sans-serif");
+pref("font.name-list.monospace.x-baltic", "monospace");
+
+pref("font.name-list.serif.el", "serif");
+pref("font.name-list.sans-serif.el", "sans-serif");
+pref("font.name-list.monospace.el", "monospace");
+
+pref("font.name-list.serif.tr", "serif");
+pref("font.name-list.sans-serif.tr", "sans-serif");
+pref("font.name-list.monospace.tr", "monospace");
+#endif
+
+pref("mail.font.windows.version", 0);
+
+// What level of warning should we send to the error console?
+pref("mail.wizard.logging.console", "None");
+// What level of warning should we send to stdout via dump?
+pref("mail.wizard.logging.dump", "None");
+
+// Handle links targeting new windows (from within content tabs)
+// These are the values that Firefox can be set to:
+// 0=default window, 1=current window/tab, 2=new window,
+// 3=new tab in most recent window
+//
+// Thunderbird only supports a value of 3. Other values can be set, but are
+// not implemented or supported.
+pref("browser.link.open_newwindow", 3);
+
+// These are the values that Firefox can be set to:
+// 0: no restrictions - divert everything
+// 1: don't divert window.open at all
+// 2: don't divert window.open with features
+//
+// Thunderbird only supports a value of 0. Other values can be set, but are
+// not implemented or supported.
+pref("browser.link.open_newwindow.restriction", 0);
+
+pref("browser.tabs.loadDivertedInBackground", false);
+
+// Browser icon prefs
+pref("browser.chrome.site_icons", true);
+pref("browser.chrome.favicons", true);
+
+// Disable places by default as we don't want to store global history
+// Below we define reasonable defaults as copied from Firefox so that we have
+// something sensible should an extension wish to enable this.
+pref("places.history.enabled", false);
+
+// The percentage of system memory that the Places database can use. Out of the
+// allowed cache size it will at most use the size of the database file.
+// Changes to this value are effective after an application restart.
+// Acceptable values are between 0 and 50.
+// In Thunderbird, we're not exercising places much, so it makes sense to make
+// it use a lower percentage of the cache. Plus, we have another more important
+// sqlite database (gloda) that deserves to use cache.
+pref("places.database.cache_to_memory_percentage", 1);
+
+// the (maximum) number of the recent visits to sample
+// when calculating frecency
+pref("places.frecency.numVisits", 10);
+
+// buckets (in days) for frecency calculation
+pref("places.frecency.firstBucketCutoff", 4);
+pref("places.frecency.secondBucketCutoff", 14);
+pref("places.frecency.thirdBucketCutoff", 31);
+pref("places.frecency.fourthBucketCutoff", 90);
+
+// weights for buckets for frecency calculations
+pref("places.frecency.firstBucketWeight", 100);
+pref("places.frecency.secondBucketWeight", 70);
+pref("places.frecency.thirdBucketWeight", 50);
+pref("places.frecency.fourthBucketWeight", 30);
+pref("places.frecency.defaultBucketWeight", 10);
+
+// bonus (in percent) for visit transition types for frecency calculations
+pref("places.frecency.embedVisitBonus", 0);
+pref("places.frecency.framedLinkVisitBonus", 0);
+pref("places.frecency.linkVisitBonus", 100);
+pref("places.frecency.typedVisitBonus", 2000);
+pref("places.frecency.bookmarkVisitBonus", 75);
+pref("places.frecency.downloadVisitBonus", 0);
+pref("places.frecency.permRedirectVisitBonus", 0);
+pref("places.frecency.tempRedirectVisitBonus", 0);
+pref("places.frecency.defaultVisitBonus", 0);
+
+// bonus (in percent) for place types for frecency calculations
+pref("places.frecency.unvisitedBookmarkBonus", 140);
+pref("places.frecency.unvisitedTypedBonus", 200);
+
+pref("browser.urlbar.restrict.openpage", "%");
+
+// The default for this pref reflects whether the build is capable of IPC.
+// (Turning it on in a no-IPC build will have no effect.)
+#ifdef XP_MACOSX
+// i386 ipc preferences
+pref("dom.ipc.plugins.enabled.i386", false);
+pref("dom.ipc.plugins.enabled.i386.flash player.plugin", true);
+pref("dom.ipc.plugins.enabled.i386.javaplugin2_npapi.plugin", true);
+pref("dom.ipc.plugins.enabled.i386.javaappletplugin.plugin", true);
+// x86_64 ipc preferences
+pref("dom.ipc.plugins.enabled.x86_64", true);
+#else
+pref("dom.ipc.plugins.enabled", true);
+#endif
+
+// This pref governs whether we attempt to work around problems caused by
+// plugins using OS calls to manipulate the cursor while running out-of-
+// process. These workarounds all involve intercepting (hooking) certain
+// OS calls in the plugin process, then arranging to make certain OS calls
+// in the browser process. Eventually plugins will be required to use the
+// NPAPI to manipulate the cursor, and these workarounds will be removed.
+// See bug 621117.
+#ifdef XP_MACOSX
+pref("dom.ipc.plugins.nativeCursorSupport", true);
+#endif
+
+// plugin finder service url
+pref("pfs.datasource.url", "https://pfs.mozilla.org/plugins/PluginFinderService.
+php?mimetype=%PLUGIN_MIMETYPE%&appID=%APP_ID%&appVersion=%APP_VERSION%&clientOS=
+%CLIENT_OS%&chromeLocale=%CHROME_LOCALE%&appRelease=%APP_RELEASE%");
+
+// By default we show an infobar message when pages require plugins the user has
+// not installed, or are outdated.
+pref("plugins.hide_infobar_for_missing_plugin", false);
+pref("plugins.hide_infobar_for_outdated_plugin", false);
+
+#ifdef XP_MACOSX
+pref("plugins.use_layers", false);
+pref("plugins.hide_infobar_for_carbon_failure_plugin", false);
+#endif
+
+pref("plugins.update.url", "https://www.mozilla.org/%LOCALE%/plugincheck/");
+pref("plugins.update.notifyUser", false);
+pref("plugins.crash.supportUrl", "https://live.mozillamessaging.com/%APP%/plugin-crashed?locale=%LOCALE%&version=%VERSION%&os=%OS%&buildid=%APPBUILDID%");
+
+// Windows taskbar support
+#ifdef XP_WIN
+pref("mail.taskbar.lists.enabled", true);
+pref("mail.taskbar.lists.tasks.enabled", true);
+#endif
+
+// Disable hardware accelerated layers
+pref("layers.acceleration.disabled", true);
+#ifdef XP_WIN
+// and direct2d support on Windows
+pref("gfx.direct2d.disabled", true);
+#endif
+
+// Account provisioner.
+pref("mail.provider.providerList", "https://broker-live.mozillamessaging.com/provider/list");
+pref("mail.provider.suggestFromName", "https://broker-live.mozillamessaging.com/provider/suggest");
+pref("mail.provider.enabled", true);
+
+pref("mail.websearch.open_externally", false);
+
+// Pointer to the default engine name.
+pref("browser.search.defaultenginename", "chrome://messenger-region/locale/region.properties");
+
+// Ordering of search engines in the engine list.
+pref("browser.search.order.1", "chrome://messenger-region/locale/region.properties");
+pref("browser.search.order.2", "chrome://messenger-region/locale/region.properties");
+pref("browser.search.order.3", "chrome://messenger-region/locale/region.properties");
+
+// XXX Don't update yet, until we've verified how that affects us.
+pref("browser.search.update", false);
+
+// Check whether we need to perform engine updates every 6 hours
+pref("browser.search.update.interval", 21600);
+
+// Disable remote debugging protocol logging
+pref("devtools.debugger.log", false);
+
+pref("mail.chat.enabled", true);
+pref("mail.chat.play_notification_sound", true);
+// Send typing notification in private conversations
+pref("purple.conversations.im.send_typing", true);
+
+// BigFiles
+pref("mail.cloud_files.enabled", true);
+pref("mail.cloud_files.inserted_urls.footer.link", "http://www.getthunderbird.com");
+pref("mail.cloud_files.learn_more_url", "https://support.mozillamessaging.com/kb/filelink-large-attachments");
+
+// Ignore threads
+pref("mail.ignore_thread.learn_more_url", "https://support.mozillamessaging.com/kb/ignore-threads");
+
+// Sanitize dialog window
+pref("privacy.cpd.cookies", true);
+pref("privacy.cpd.cache", true);
+
+// What default should we use for the time span in the sanitizer:
+// 0 - Clear everything
+// 1 - Last Hour
+// 2 - Last 2 Hours
+// 3 - Last 4 Hours
+// 4 - Today
+pref("privacy.sanitize.timeSpan", 1);
+
+// PgpMime Proxy
+pref("mail.pgpmime.addon_url", "https://addons.mozilla.org/thunderbird/addon/enigmail/");
+
+// If set to true, Thunderbird will collapse the main menu for new profiles
+// (or, more precisely, profiles that start with no accounts created).
+pref("mail.main_menu.collapse_by_default", true);
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>\r
+<!--\r
+ * ***** BEGIN LICENSE BLOCK *****\r
+Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
+secure header is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
+\r
+\r
+Redistribution and use, in source and binary forms, with or without modification, are permitted provided that the following conditons are met :\r
+\r
+1. Redistributions of source code must retain the above copyright notice,\r
+2.MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached in the redistribution of the source code.\r
+3. Neither the names of the copyright holders nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission from EADS Defence and Security.\r
+\r
+Alternatively, the contents of this file may be used under the terms of\r
+ * either of the GNU General Public License Version 2 or later (the "GPL"),\r
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
+ * in which case the provisions of the GPL or the LGPL are applicable instead\r
+ * of those above. If you wish to allow use of your version of this file only\r
+ * under the terms of either the GPL or the LGPL, and not to allow others to\r
+ * use your version of this file under the terms of the MPL, indicate your\r
+ * decision by deleting the provisions above and replace them with the notice\r
+ * and other provisions required by the GPL or the LGPL. If you do not delete\r
+ * the provisions above, a recipient may use your version of this file under\r
+ * the terms of any one of the MPL, the GPL or the LGPL.\r
+\r
+REMINDER :\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ \r
+EADS Defence and Security - 1 Boulevard Jean Moulin - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ * ***** END LICENSE BLOCK ***** */\r
+-->\r
+\r
+<!-- ximfsecureheaders definition example -->\r
+<ximf:secure_headers id="001" version="1.0" ximfVersion="2.0" xmlns:ximf="http://ximf.org/ximf/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://eads.org/ximf/ ximf.xsd">\r
+ <ximf:headers identity="XIMF_BASIC">\r
+ <ximf:header name="X-XIMF-Primary-Precedence" status="0" />\r
+ <ximf:header name="X-XIMF-Copy-Precedence" status="0" />\r
+ <ximf:header name="X-XIMF-Correspondance-Type" />\r
+ <ximf:header name="X-XIMF-Exchange-Type" />\r
+ <ximf:header name="X-XIMF-Security-Policy-Identifier" /> \r
+ <ximf:header name="X-XIMF-Security-Classification-Identifier" />\r
+ <ximf:header name="X-XIMF-Attribution-Keyword" /> \r
+ <ximf:header name="X-XIMF-Security-Categories" />\r
+ <ximf:header name="X-XIMF-Security-Categories-Identifier" /> \r
+ <ximf:header name="Reply-To" />\r
+ <ximf:header name="Sender" />\r
+ <ximf:header name="To" />\r
+ <ximf:header name="Cc" />\r
+ <ximf:header name="From" />\r
+ <ximf:header name="Subject" /> \r
+ </ximf:headers>\r
+</ximf:secure_headers>
\ No newline at end of file
--- /dev/null
+<?xml version="1.0" encoding="UTF-8"?>
+<!-- ESS Security Label policy definition example -->
+<securityLabel>
+
+ <!--
+ Security Policy Identifier
+ value (attribute) [OID]
+ label (attribute) [string]: displayed name of the policy
+ -->
+ <securityPolicyIdentifier value="1.2.840.113549.1.9.16.7.1" label="default" />
+
+
+ <!--
+ Security Classification
+ valueDisplayed (attribute) [boolean]: decide if value is displayed or only label
+ item (element):
+ value (attribute) [integer]: must be in 0 - 256 range
+ label (attribute) [string]: displayed name
+ -->
+ <securityClassification valueDisplayed="true">
+ <item value="0" label="unmarked" />
+ <item value="1" label="unclassified" />
+ <item value="2" label="restricted" />
+ <item value="3" label="confidential" />
+ <item value="4" label="secret" />
+ <item value="5" label="top-secret" />
+ </securityClassification>
+
+
+ <!--
+ Privacy Mark
+ freeText (attribute) [boolean]: define if free text if allowed
+ item (element): add a predefined privacy mark
+ value (attribute) [string]: displayed text and value of the privacy mark
+ -->
+ <privacyMark freeText="true">
+ <item value="NOCONTRACTOR" />
+ <item value="NOFORN" />
+ <item value="保密" />
+ <item value="प्रतिबंधित/सीमित" />
+ </privacyMark>
+
+
+ <!--
+ Security Categories
+ securityClassificationValue (attribute) [integer]: specify that these categories apply only to this classification
+ item (element): category
+ oid (attribute) [OID]: type of the category
+ type (attribute) [integer]: data type of value attribute (1 for UTF-8 string, 2 for integer)
+ value (attribute) [string]: text of the category
+ label (attribute) [string]: displayed name of the category
+ -->
+
+ <!-- For all Security Classification -->
+ <securityCategories>
+ <item oid="1.2.66.1.5" type="1" value="private" label="Private" />
+ <item oid="1.2.66.1.89.4" type="1" value="EU Protected Information" label="Protected Information" />
+ </securityCategories>
+
+ <!-- Only for Security Classification 4 -->
+ <securityCategories securityClassificationValue="4">
+ <item oid="1.2.3.8" type="1" value="EYES ONLY" label="EYES ONLY" />
+ <item oid="1.2.398.5" type="1" value="EU do not print" label="DO NOT PRINT" />
+ <item oid="1.2.398.5" type="1" value="FR do not print" label="Ne pas imprimer" />
+ </securityCategories>
+
+ <!-- Only for Security Classification 5 -->
+ <securityCategories securityClassificationValue="5">
+ <item oid="1.2.324.74" type="1" value="NATO CONFIDENTIAL" label="NATO CONFIDENTIAL" />
+ <item oid="1.2.324.75" type="1" value="NATO RESTRICTED" label="NATO RESTRICTED" />
+ <item oid="1.2.99.2" type="1" value="高度機密" label="top-secret" />
+ <item oid="1.2.99.3" type="2" value="57" label="a" />
+ <item oid="1.2.99.4" type="2" value="6000" label="b" />
+ <item oid="1.2.99.5" type="1" value="6000" label="c" />
+ </securityCategories>
+
+</securityLabel>
--- /dev/null
+<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
+<assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
+<assemblyIdentity
+ version="1.0.0.0"
+ processorArchitecture="*"
+ name="Trustedbird"
+ type="win32"
+/>
+<description>Trustedbird</description>
+<dependency>
+ <dependentAssembly>
+ <assemblyIdentity
+ type="win32"
+ name="Microsoft.Windows.Common-Controls"
+ version="6.0.0.0"
+ processorArchitecture="*"
+ publicKeyToken="6595b64144ccf1df"
+ language="*"
+ />
+ </dependentAssembly>
+</dependency>
+<ms_asmv3:trustInfo xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
+ <ms_asmv3:security>
+ <ms_asmv3:requestedPrivileges>
+ <ms_asmv3:requestedExecutionLevel level="asInvoker" uiAccess="false" />
+ </ms_asmv3:requestedPrivileges>
+ </ms_asmv3:security>
+</ms_asmv3:trustInfo>
+ <ms_asmv3:application xmlns:ms_asmv3="urn:schemas-microsoft-com:asm.v3">
+ <ms_asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
+ <dpiAware>true</dpiAware>
+ </ms_asmv3:windowsSettings>
+ </ms_asmv3:application>
+ <compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
+ <application>
+ <supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}"/>
+ <supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}"/>
+ <supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}"/>
+ <supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}"/>
+ </application>
+ </compatibility>
+</assembly>
--- /dev/null
+<?xml version="1.0"?> <!-- -*- Mode: HTML -*- -->
+
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://messenger/content/aboutDialog.css" type="text/css"?>
+<?xml-stylesheet href="chrome://branding/content/aboutDialog.css" type="text/css"?>
+
+<!DOCTYPE window [
+<!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd" >
+%brandDTD;
+<!ENTITY % aboutDialogDTD SYSTEM "chrome://messenger/locale/aboutDialog.dtd" >
+%aboutDialogDTD;
+]>
+
+<window xmlns:html="http://www.w3.org/1999/xhtml"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ id="aboutDialog"
+ windowtype="Mail:About"
+ onload="init(event);"
+#ifdef MOZ_UPDATER
+ onunload="onUnload(event);"
+#endif
+#ifdef XP_MACOSX
+ inwindowmenu="false"
+#else
+ title="&aboutDialog.title;"
+#endif
+ role="dialog"
+ aria-describedby="version distribution distributionId currentChannelText communityDesc contributeDesc trademark"
+ >
+
+ <script type="application/javascript" src="chrome://messenger/content/aboutDialog.js"/>
+ <script type="application/javascript" src="chrome://messenger/content/specialTabs.js"/>
+ <!-- This one is for openURL -->
+ <script type="application/javascript" src="chrome://global/content/contentAreaUtils.js"/>
+
+ <vbox id="aboutDialogContainer">
+ <hbox id="clientBox">
+ <vbox id="leftBox" flex="1"/>
+ <vbox id="rightBox" flex="1">
+#expand <label id="version">__MOZ_APP_VERSION__</label>
+ <label id="distribution" class="text-blurb"/>
+ <label id="distributionId" class="text-blurb"/>
+
+ <vbox id="detailsBox">
+ <vbox id="updateBox">
+#ifdef MOZ_UPDATER
+ <deck id="updateDeck" orient="vertical">
+ <hbox id="updateButtonBox" align="center">
+ <button id="updateButton" align="start"
+ oncommand="gAppUpdater.buttonOnCommand();"/>
+ <spacer flex="1"/>
+ </hbox>
+ <hbox id="checkingForUpdates" align="center">
+ <image class="update-throbber"/><label>&update.checkingForUpdates;</label>
+ </hbox>
+ <hbox id="checkingAddonCompat" align="center">
+ <image class="update-throbber"/><label>&update.checkingAddonCompat;</label>
+ </hbox>
+ <hbox id="downloading" align="center">
+ <image class="update-throbber"/><label>&update.downloading.start;</label><label id="downloadStatus"/><label>&update.downloading.end;</label>
+ </hbox>
+ <hbox id="applying" align="center">
+ <image class="update-throbber"/><label>&update.applying;</label>
+ </hbox>
+ <hbox id="downloadFailed" align="center">
+ <label>&update.failed.start;</label><label id="failedLink" class="text-link">&update.failed.linkText;</label><label>&update.failed.end;</label>
+ </hbox>
+ <hbox id="adminDisabled" align="center">
+ <label>&update.adminDisabled;</label>
+ </hbox>
+ <hbox id="noUpdatesFound" align="center">
+ <label>&update.noUpdatesFound;</label>
+ </hbox>
+ <hbox id="manualUpdate" align="center">
+ <label>&update.manual.start;</label><label id="manualLink" class="text-link">&update.manual.linkText;</label><label>&update.manual.end;</label>
+ </hbox>
+ <hbox id="unsupportedSystem" align="center">
+ <label>&update.unsupported.start;</label><label id="unsupportedLink" class="text-link">&update.unsupported.linkText;</label><label>&update.unsupported.end;</label>
+ </hbox>
+ </deck>
+#endif
+ </vbox>
+#ifdef MOZ_UPDATER
+ <description class="text-blurb" id="currentChannelText">
+ &channel.description.start;<label id="currentChannel"/>&channel.description.end;
+ </description>
+#endif
+ <description class="text-blurb" id="communityDesc">
+ &community.start2;<label class="text-link" onclick="openURL('http://adullact.net/projects/milimail/');" oncommand="openUILink(this.getAttribute('href'), event);">&community.mozillaLink;</label>&community.middle2;<label class="text-link" onclick="openAboutTab('about:credits');">&community.creditsLink;</label>&community.end2;
+ </description>
+ <description class="text-blurb" id="contributeDesc">
+ &contribute.start;<label class="text-link" onclick="openURL('http://www.mozilla.org/contribute/');">&contribute.getInvolvedLink;</label>&contribute.end;
+ </description>
+ </vbox>
+ </vbox>
+ </hbox>
+ <vbox id="bottomBox">
+ <hbox pack="center">
+ <label class="text-link bottom-link" onclick="openAboutTab('about:license');">&bottomLinks.license;</label>
+ <label class="text-link bottom-link" onclick="openAboutTab('about:rights');">&bottomLinks.rights;</label>
+ <label class="text-link bottom-link" onclick="openURL('https://www.mozilla.org/en-US/thunderbird/legal/privacy/');">&bottomLinks.privacy;</label>
+ </hbox>
+ <description id="trademark">
+ <label class="trademark-label">&trademarkInfo.part1;</label>
+ </description>
+ </vbox>
+ </vbox>
+
+ <keyset id="mainKeyset">
+ <key keycode="VK_ESCAPE" oncommand="window.close();"/>
+#ifdef XP_MACOSX
+ <key id="key_close" modifiers="accel" key="&cmdCloseMac.commandKey;"
+ oncommand="window.close();"/>
+#endif
+ </keyset>
+</window>
--- /dev/null
+/* -*- indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+Components.utils.import("resource:///modules/gloda/dbview.js");
+Components.utils.import("resource:///modules/mailServices.js");
+Components.utils.import("resource://gre/modules/Services.jsm");
+Components.utils.import("resource://gre/modules/PluralForm.jsm");
+
+const ADDR_DB_LARGE_COMMIT = 1;
+
+const kClassicMailLayout = 0;
+const kWideMailLayout = 1;
+const kVerticalMailLayout = 2;
+const kMailLayoutCommandMap =
+{
+ "cmd_viewClassicMailLayout": kClassicMailLayout,
+ "cmd_viewWideMailLayout": kWideMailLayout,
+ "cmd_viewVerticalMailLayout": kVerticalMailLayout
+};
+
+// Per message header flags to keep track of whether the user is allowing remote
+// content for a particular message.
+// if you change or add more values to these constants, be sure to modify
+// the corresponding definitions in nsMsgContentPolicy.cpp
+const kNoRemoteContentPolicy = 0;
+const kBlockRemoteContent = 1;
+const kAllowRemoteContent = 2;
+
+const kMsgNotificationPhishingBar = 1;
+const kMsgNotificationJunkBar = 2;
+const kMsgNotificationRemoteImages = 3;
+const kMsgNotificationMDN = 4;
+const kMsgNotificationSMIMEReceiptRequest = 5;
+const kMsgNotificationSMIMEReceiptVerified = 6;
+const kMsgNotificationSMIMEReceiptNotVerified = 7;
+
+Components.utils.import("resource:///modules/MailUtils.js");
+Components.utils.import("resource:///modules/MailConsts.js");
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+// Timer to mark read, if the user has configured the app to mark a message as
+// read if it is viewed for more than n seconds.
+var gMarkViewedMessageAsReadTimer = null;
+
+// the user preference,
+// if HTML is not allowed. I assume, that the user could have set this to a
+// value > 1 in his prefs.js or user.js, but that the value will not
+// change during runtime other than through the MsgBody*() functions below.
+var gDisallow_classes_no_html = 1;
+
+// Disable the new account menu item if the account preference is locked.
+// The other affected areas are the account central, the account manager
+// dialog, and the account provisioner window.
+function menu_new_init()
+{
+ // If the account provisioner is pref'd off, we shouldn't display the menu
+ // item.
+ ShowMenuItem("newCreateEmailAccountMenuItem",
+ Services.prefs.getBoolPref("mail.provider.enabled"));
+
+ // If we don't have a gFolderDisplay, just get out of here and leave the menu
+ // as it is.
+ if (!gFolderDisplay)
+ return;
+
+ let folder = gFolderDisplay.displayedFolder;
+ if (!folder)
+ return;
+
+ if (Services.prefs.prefIsLocked("mail.disable_new_account_addition"))
+ document.getElementById("newAccountMenuItem").setAttribute("disabled", "true");
+
+ const nsMsgFolderFlags = Components.interfaces.nsMsgFolderFlags;
+ var isInbox = folder.isSpecialFolder(nsMsgFolderFlags.Inbox);
+ var showNew = folder.canCreateSubfolders ||
+ (isInbox && !(folder.flags & nsMsgFolderFlags.Virtual));
+ ShowMenuItem("menu_newFolder", showNew);
+ ShowMenuItem("menu_newVirtualFolder", showNew);
+
+ EnableMenuItem("menu_newFolder", folder.server.type != "imap" || MailOfflineMgr.isOnline());
+ if (showNew)
+ {
+ var bundle = document.getElementById("bundle_messenger");
+ // Change "New Folder..." menu according to the context.
+ SetMenuItemLabel("menu_newFolder", bundle.getString(
+ (folder.isServer || isInbox) ? "newFolderMenuItem" : "newSubfolderMenuItem"));
+ }
+}
+
+function goUpdateMailMenuItems(commandset)
+{
+ for (var i = 0; i < commandset.childNodes.length; i++)
+ {
+ var commandID = commandset.childNodes[i].getAttribute("id");
+ if (commandID)
+ goUpdateCommand(commandID);
+ }
+
+ updateCheckedStateForIgnoreAndWatchThreadCmds();
+}
+
+/**
+ * Update the ignore (sub)thread, and watch thread commands so the menus
+ * using them get the checked state set up properly.
+ */
+function updateCheckedStateForIgnoreAndWatchThreadCmds() {
+ document.getElementById("cmd_killThread")
+ .setAttribute("checked", gFolderDisplay.selectedMessageThreadIgnored);
+ document.getElementById("cmd_killSubthread")
+ .setAttribute("checked", gFolderDisplay.selectedMessageSubthreadIgnored);
+ document.getElementById("cmd_watchThread")
+ .setAttribute("checked", gFolderDisplay.selectedMessageThreadWatched);
+}
+
+function file_init()
+{
+ document.commandDispatcher.updateCommands('create-menu-file');
+}
+
+function InitEditMessagesMenu()
+{
+ goSetMenuValue('cmd_delete', 'valueDefault');
+ goSetAccessKey('cmd_delete', 'valueDefaultAccessKey');
+ document.commandDispatcher.updateCommands('create-menu-edit');
+
+ // initialize the favorite Folder checkbox in the edit menu
+ let favoriteFolderMenu = document.getElementById('menu_favoriteFolder');
+ if (!favoriteFolderMenu.hasAttribute("disabled")) {
+ let folders = gFolderTreeView.getSelectedFolders();
+ if (folders.length == 1 && !folders[0].isServer) {
+ const kFavoriteFlag = Components.interfaces.nsMsgFolderFlags.Favorite;
+ // Adjust the checked state on the menu item.
+ favoriteFolderMenu.setAttribute("checked", folders[0].getFlag(kFavoriteFlag));
+ favoriteFolderMenu.hidden = false;
+ } else {
+ favoriteFolderMenu.hidden = true;
+ }
+ }
+}
+
+function InitAppFolderViewsMenu()
+{
+ goSetMenuValue('cmd_delete', 'valueDefault');
+ goSetAccessKey('cmd_delete', 'valueDefaultAccessKey');
+ document.commandDispatcher.updateCommands('create-menu-edit');
+
+ // initialize the favorite Folder checkbox in the appmenu menu
+ let favoriteAppFolderMenu = document.getElementById('appmenu_favoriteFolder');
+ if (!favoriteAppFolderMenu.hasAttribute("disabled")) {
+ let folders = gFolderTreeView.getSelectedFolders();
+ if (folders.length == 1 && !folders[0].isServer) {
+ const kFavoriteFlag = Components.interfaces.nsMsgFolderFlags.Favorite;
+ // Adjust the checked state on the menu item.
+ favoriteAppFolderMenu.setAttribute("checked", folders[0].getFlag(kFavoriteFlag));
+ favoriteAppFolderMenu.hidden = false;
+ } else {
+ favoriteAppFolderMenu.hidden = true;
+ }
+ }
+}
+
+function InitGoMessagesMenu()
+{
+ document.commandDispatcher.updateCommands('create-menu-go');
+}
+
+/**
+ * This is called every time the view menu popup is displayed. It is
+ * responsible for updating the menu items' state to reflect reality.
+ */
+function view_init()
+{
+ let isFeed = gFolderDisplay &&
+ ((gFolderDisplay.displayedFolder &&
+ gFolderDisplay.displayedFolder.server.type == "rss") ||
+ gFolderDisplay.selectedMessageIsFeed);
+
+ let accountCentralDisplayed = gFolderDisplay.isAccountCentralDisplayed;
+ let messagePaneMenuItem = document.getElementById("menu_showMessage");
+ if (!messagePaneMenuItem.hidden) { // Hidden in the standalone msg window.
+ messagePaneMenuItem.setAttribute("checked",
+ accountCentralDisplayed ? false : gMessageDisplay.visible);
+ messagePaneMenuItem.disabled = accountCentralDisplayed;
+ }
+
+ let messagePaneAppMenuItem = document.getElementById("appmenu_showMessage");
+ if (!messagePaneAppMenuItem.hidden) { // Hidden in the standalone msg window.
+ messagePaneAppMenuItem.setAttribute("checked",
+ accountCentralDisplayed ? false : gMessageDisplay.visible);
+ messagePaneAppMenuItem.disabled = accountCentralDisplayed;
+ }
+
+ let folderPaneMenuItem = document.getElementById("menu_showFolderPane");
+ if (!folderPaneMenuItem.hidden) { // Hidden in the standalone msg window.
+ folderPaneMenuItem.setAttribute("checked", gFolderDisplay.folderPaneVisible);
+ }
+
+ let folderPaneAppMenuItem = document.getElementById("appmenu_showFolderPane");
+ if (!folderPaneAppMenuItem.hidden) { // Hidden in the standalone msg window.
+ folderPaneAppMenuItem.setAttribute("checked", gFolderDisplay.folderPaneVisible);
+ }
+
+ // Disable some menus if account manager is showing
+ document.getElementById("viewSortMenu").disabled = accountCentralDisplayed;
+
+ let appmenuViewSort = document.getElementById("appmenu_viewSortMenu");
+ if (appmenuViewSort)
+ appmenuViewSort.disabled = accountCentralDisplayed;
+
+ document.getElementById("viewMessageViewMenu").disabled = accountCentralDisplayed;
+
+ let appmenuViewMessageView = document.getElementById("appmenu_viewMessageViewMenu");
+ if (appmenuViewMessageView)
+ appmenuViewMessageView.disabled = accountCentralDisplayed;
+
+ document.getElementById("viewMessagesMenu").disabled = accountCentralDisplayed;
+
+ let appmenuViewMessagesMenu = document.getElementById("appmenu_viewMessagesMenu");
+ if (appmenuViewMessagesMenu)
+ appmenuViewMessagesMenu.disabled = accountCentralDisplayed;
+
+ // Hide the views menu item if the user doesn't have the views toolbar button
+ // visible.
+ var viewsToolbarButton = document.getElementById("mailviews-container");
+ document.getElementById('viewMessageViewMenu').hidden = !viewsToolbarButton;
+
+ // Initialize the Message Body menuitem
+ document.getElementById('viewBodyMenu').hidden = isFeed;
+
+ let appmenuViewBodyMenu = document.getElementById('appmenu_viewBodyMenu');
+ if (appmenuViewBodyMenu)
+ appmenuViewBodyMenu.hidden = isFeed;
+
+ // Initialize the Show Feed Summary menu
+ let viewFeedSummary = document.getElementById('viewFeedSummary');
+ viewFeedSummary.hidden = !isFeed;
+ let appmenuViewFeedSummary = document.getElementById('appmenu_viewFeedSummary');
+ if (appmenuViewFeedSummary)
+ appmenuViewFeedSummary.hidden = !isFeed;
+
+ let viewRssMenuItemIds = ["bodyFeedGlobalWebPage",
+ "bodyFeedGlobalSummary",
+ "bodyFeedPerFolderPref"];
+ let checked = FeedMessageHandler.onSelectPref;
+ for each (let [index, id] in Iterator(viewRssMenuItemIds)) {
+ document.getElementById(id)
+ .setAttribute("checked", index == checked);
+ }
+
+ // Initialize the View Attachment Inline menu
+ var viewAttachmentInline = Services.prefs.getBoolPref("mail.inline_attachments");
+ document.getElementById("viewAttachmentsInlineMenuitem")
+ .setAttribute("checked", viewAttachmentInline);
+
+ document.commandDispatcher.updateCommands('create-menu-view');
+}
+
+function InitViewLayoutStyleMenu(event)
+{
+ var paneConfig = Services.prefs.getIntPref("mail.pane_config.dynamic");
+ var layoutStyleMenuitem = event.target.childNodes[paneConfig];
+ if (layoutStyleMenuitem)
+ layoutStyleMenuitem.setAttribute("checked", "true");
+}
+
+/**
+ * Initialize (check) appropriate folder mode under the View | Folder menu.
+ */
+function InitViewFolderViewsMenu(event)
+{
+ let selected = event.target.querySelector("[value=" + gFolderTreeView.mode + "]");
+ if (selected) {
+ selected.setAttribute("checked", "true");
+ }
+}
+
+function setSortByMenuItemCheckState(id, value)
+{
+ var menuitem = document.getElementById(id);
+ if (menuitem)
+ menuitem.setAttribute("checked", value);
+}
+
+/**
+ * Called when showing the menu_viewSortPopup menupopup, so it should always
+ * be up-to-date.
+ */
+function InitViewSortByMenu()
+{
+ var sortType = gFolderDisplay.view.primarySortType;
+
+ setSortByMenuItemCheckState("sortByDateMenuitem", (sortType == nsMsgViewSortType.byDate));
+ setSortByMenuItemCheckState("sortByReceivedMenuitem", (sortType == nsMsgViewSortType.byReceived));
+ setSortByMenuItemCheckState("sortByFlagMenuitem", (sortType == nsMsgViewSortType.byFlagged));
+ setSortByMenuItemCheckState("sortByOrderReceivedMenuitem", (sortType == nsMsgViewSortType.byId));
+ setSortByMenuItemCheckState("sortByPriorityMenuitem", (sortType == nsMsgViewSortType.byPriority));
+ setSortByMenuItemCheckState("sortBySizeMenuitem", (sortType == nsMsgViewSortType.bySize));
+ setSortByMenuItemCheckState("sortByStatusMenuitem", (sortType == nsMsgViewSortType.byStatus));
+ setSortByMenuItemCheckState("sortBySubjectMenuitem", (sortType == nsMsgViewSortType.bySubject));
+ setSortByMenuItemCheckState("sortByUnreadMenuitem", (sortType == nsMsgViewSortType.byUnread));
+ setSortByMenuItemCheckState("sortByTagsMenuitem", (sortType == nsMsgViewSortType.byTags));
+ setSortByMenuItemCheckState("sortByJunkStatusMenuitem", (sortType == nsMsgViewSortType.byJunkStatus));
+ setSortByMenuItemCheckState("sortByFromMenuitem", (sortType == nsMsgViewSortType.byAuthor));
+ setSortByMenuItemCheckState("sortByRecipientMenuitem", (sortType == nsMsgViewSortType.byRecipient));
+ setSortByMenuItemCheckState("sortByAttachmentsMenuitem", (sortType == nsMsgViewSortType.byAttachments));
+
+ var sortOrder = gFolderDisplay.view.primarySortOrder;
+ var sortTypeSupportsGrouping = (sortType == nsMsgViewSortType.byAuthor ||
+ sortType == nsMsgViewSortType.byDate || sortType == nsMsgViewSortType.byReceived ||
+ sortType == nsMsgViewSortType.byPriority ||
+ sortType == nsMsgViewSortType.bySubject || sortType == nsMsgViewSortType.byTags ||
+ sortType == nsMsgViewSortType.byRecipient || sortType == nsMsgViewSortType.byAccount ||
+ sortType == nsMsgViewSortType.byStatus || sortType == nsMsgViewSortType.byFlagged ||
+ sortType == nsMsgViewSortType.byAttachments);
+
+ setSortByMenuItemCheckState("sortAscending", (sortOrder == nsMsgViewSortOrder.ascending));
+ setSortByMenuItemCheckState("sortDescending", (sortOrder == nsMsgViewSortOrder.descending));
+
+ var grouped = gFolderDisplay.view.showGroupedBySort;
+ var threaded = gFolderDisplay.view.showThreaded;
+ var sortThreadedMenuItem = document.getElementById("sortThreaded");
+ var sortUnthreadedMenuItem = document.getElementById("sortUnthreaded");
+
+ sortThreadedMenuItem.setAttribute("checked", threaded);
+ sortUnthreadedMenuItem.setAttribute("checked", !threaded && !grouped);
+
+ var groupBySortOrderMenuItem = document.getElementById("groupBySort");
+
+ groupBySortOrderMenuItem.setAttribute("disabled", !sortTypeSupportsGrouping);
+ groupBySortOrderMenuItem.setAttribute("checked", grouped);
+}
+
+function InitAppViewSortByMenu()
+{
+ let sortType = gFolderDisplay.view.primarySortType;
+
+ setSortByMenuItemCheckState("appmenu_sortByDateMenuitem", (sortType == nsMsgViewSortType.byDate));
+ setSortByMenuItemCheckState("appmenu_sortByReceivedMenuitem", (sortType == nsMsgViewSortType.byReceived));
+ setSortByMenuItemCheckState("appmenu_sortByFlagMenuitem", (sortType == nsMsgViewSortType.byFlagged));
+ setSortByMenuItemCheckState("appmenu_sortByOrderReceivedMenuitem", (sortType == nsMsgViewSortType.byId));
+ setSortByMenuItemCheckState("appmenu_sortByPriorityMenuitem", (sortType == nsMsgViewSortType.byPriority));
+ setSortByMenuItemCheckState("appmenu_sortBySizeMenuitem", (sortType == nsMsgViewSortType.bySize));
+ setSortByMenuItemCheckState("appmenu_sortByStatusMenuitem", (sortType == nsMsgViewSortType.byStatus));
+ setSortByMenuItemCheckState("appmenu_sortBySubjectMenuitem", (sortType == nsMsgViewSortType.bySubject));
+ setSortByMenuItemCheckState("appmenu_sortByUnreadMenuitem", (sortType == nsMsgViewSortType.byUnread));
+ setSortByMenuItemCheckState("appmenu_sortByTagsMenuitem", (sortType == nsMsgViewSortType.byTags));
+ setSortByMenuItemCheckState("appmenu_sortByJunkStatusMenuitem", (sortType == nsMsgViewSortType.byJunkStatus));
+ setSortByMenuItemCheckState("appmenu_sortByFromMenuitem", (sortType == nsMsgViewSortType.byAuthor));
+ setSortByMenuItemCheckState("appmenu_sortByRecipientMenuitem", (sortType == nsMsgViewSortType.byRecipient));
+ setSortByMenuItemCheckState("appmenu_sortByAttachmentsMenuitem", (sortType == nsMsgViewSortType.byAttachments));
+
+ let sortOrder = gFolderDisplay.view.primarySortOrder;
+ let sortTypeSupportsGrouping = (sortType == nsMsgViewSortType.byAuthor ||
+ sortType == nsMsgViewSortType.byDate ||
+ sortType == nsMsgViewSortType.byReceived ||
+ sortType == nsMsgViewSortType.byPriority ||
+ sortType == nsMsgViewSortType.bySubject ||
+ sortType == nsMsgViewSortType.byTags ||
+ sortType == nsMsgViewSortType.byRecipient ||
+ sortType == nsMsgViewSortType.byAccount ||
+ sortType == nsMsgViewSortType.byStatus ||
+ sortType == nsMsgViewSortType.byFlagged ||
+ sortType == nsMsgViewSortType.byAttachments);
+
+ setSortByMenuItemCheckState("appmenu_sortAscending", (sortOrder == nsMsgViewSortOrder.ascending));
+ setSortByMenuItemCheckState("appmenu_sortDescending", (sortOrder == nsMsgViewSortOrder.descending));
+
+ let grouped = gFolderDisplay.view.showGroupedBySort;
+ let threaded = gFolderDisplay.view.showThreaded;
+ let sortThreadedMenuItem = document.getElementById("appmenu_sortThreaded");
+ let sortUnthreadedMenuItem = document.getElementById("appmenu_sortUnthreaded");
+
+ sortThreadedMenuItem.setAttribute("checked", threaded);
+ sortUnthreadedMenuItem.setAttribute("checked", !threaded && !grouped);
+
+ let groupBySortOrderMenuItem = document.getElementById("appmenu_groupBySort");
+
+ groupBySortOrderMenuItem.setAttribute("disabled", !sortTypeSupportsGrouping);
+ groupBySortOrderMenuItem.setAttribute("checked", grouped);
+}
+
+function InitViewMessagesMenu()
+{
+ document.getElementById("viewAllMessagesMenuItem").setAttribute("checked",
+ !gFolderDisplay.view.showUnreadOnly &&
+ !gFolderDisplay.view.specialView);
+
+ document.getElementById("viewUnreadMessagesMenuItem").setAttribute("checked",
+ gFolderDisplay.view.showUnreadOnly);
+
+ document.getElementById("viewThreadsWithUnreadMenuItem").setAttribute("checked",
+ gFolderDisplay.view.specialViewThreadsWithUnread);
+
+ document.getElementById("viewWatchedThreadsWithUnreadMenuItem").setAttribute("checked",
+ gFolderDisplay.view.specialViewWatchedThreadsWithUnread);
+
+ document.getElementById("viewIgnoredThreadsMenuItem").setAttribute("checked",
+ gFolderDisplay.view.showIgnored);
+}
+
+function InitAppmenuViewMessagesMenu()
+{
+ document.getElementById("appmenu_viewAllMessagesMenuItem").setAttribute("checked",
+ !gFolderDisplay.view.showUnreadOnly &&
+ !gFolderDisplay.view.specialView);
+
+ document.getElementById("appmenu_viewUnreadMessagesMenuItem").setAttribute("checked",
+ gFolderDisplay.view.showUnreadOnly);
+
+ document.getElementById("appmenu_viewThreadsWithUnreadMenuItem").setAttribute("checked",
+ gFolderDisplay.view.specialViewThreadsWithUnread);
+
+ document.getElementById("appmenu_viewWatchedThreadsWithUnreadMenuItem").setAttribute("checked",
+ gFolderDisplay.view.specialViewWatchedThreadsWithUnread);
+
+ document.getElementById("appmenu_viewIgnoredThreadsMenuItem").setAttribute("checked",
+ gFolderDisplay.view.showIgnored);
+}
+
+function InitMessageMenu()
+{
+ var selectedMsg = gFolderDisplay.selectedMessage;
+ var isNews = gFolderDisplay.selectedMessageIsNews;
+ var isFeed = gFolderDisplay.selectedMessageIsFeed;
+
+ // We show reply to Newsgroups only for news messages.
+ document.getElementById("replyNewsgroupMainMenu").hidden = !isNews;
+
+ // For mail messages we say reply. For news we say ReplyToSender.
+ document.getElementById("replyMainMenu").hidden = isNews;
+ document.getElementById("replySenderMainMenu").hidden = !isNews;
+
+ document.getElementById("menu_cancel").hidden = !isNews;
+
+ // Disable the move and copy menus if there are no messages selected or if
+ // the message is a dummy - e.g. opening a message in the standalone window.
+ let messageStoredInternally = selectedMsg && !gMessageDisplay.isDummy;
+ // Disable the move menu if we can't delete msgs from the folder.
+ let canMove = messageStoredInternally &&
+ gFolderDisplay.canDeleteSelectedMessages;
+ document.getElementById("moveMenu").disabled = !canMove;
+
+ // Also disable copy when no folder is loaded (like for .eml files).
+ let canCopy = selectedMsg && (!gMessageDisplay.isDummy ||
+ window.arguments[0].scheme == "file");
+ document.getElementById("copyMenu").disabled = !canCopy;
+
+ initMoveToFolderAgainMenu(document.getElementById("moveToFolderAgain"));
+
+ // Disable the Forward As menu item if no message is selected.
+ document.getElementById("forwardAsMenu").disabled = !selectedMsg;
+
+ // Disable the Tag menu item if no message is selected or when we're
+ // not in a folder.
+ document.getElementById("tagMenu").disabled = !messageStoredInternally;
+
+ // Initialize the Open Message menuitem
+ var winType = document.documentElement.getAttribute('windowtype');
+ if (winType == "mail:3pane")
+ document.getElementById('openMessageWindowMenuitem').hidden = isFeed;
+
+ // Initialize the Open Feed Message handler menu
+ let index = FeedMessageHandler.onOpenPref;
+ document.getElementById("menu_openFeedMessage")
+ .childNodes[index].setAttribute("checked", true);
+
+ let openRssMenu = document.getElementById("openFeedMessage");
+ openRssMenu.hidden = !isFeed;
+ if (winType != "mail:3pane")
+ openRssMenu.hidden = true;
+
+ // Disable mark menu when we're not in a folder.
+ document.getElementById("markMenu").disabled = gMessageDisplay.isDummy;
+
+ document.commandDispatcher.updateCommands('create-menu-message');
+}
+
+function InitAppMessageMenu()
+{
+ let selectedMsg = gFolderDisplay.selectedMessage;
+ let isNews = gFolderDisplay.selectedMessageIsNews;
+ let isFeed = gFolderDisplay.selectedMessageIsFeed;
+
+ // We show reply to Newsgroups only for news messages.
+ document.getElementById("appmenu_replyNewsgroupMainMenu").hidden = !isNews;
+
+ // For mail messages we say reply. For news we say ReplyToSender.
+ document.getElementById("appmenu_replyMainMenu").hidden = isNews;
+ document.getElementById("appmenu_replySenderMainMenu").hidden = !isNews;
+
+ document.getElementById("appmenu_cancel").hidden = !isNews;
+
+ // Disable the move and copy menus if there are no messages selected or if
+ // the message is a dummy - e.g. opening a message in the standalone window.
+ let messageStoredInternally = selectedMsg && !gMessageDisplay.isDummy;
+ // Disable the move menu if we can't delete msgs from the folder.
+ let canMove = messageStoredInternally &&
+ gFolderDisplay.canDeleteSelectedMessages;
+ document.getElementById("appmenu_moveMenu").disabled = !canMove;
+
+ // Also disable copy when no folder is loaded (like for .eml files).
+ let canCopy = selectedMsg && (!gMessageDisplay.isDummy ||
+ window.arguments[0].scheme == "file");
+ document.getElementById("appmenu_copyMenu").disabled = !canCopy;
+
+ initMoveToFolderAgainMenu(document.getElementById("appmenu_moveToFolderAgain"));
+
+ // Disable the Forward As menu item if no message is selected.
+ document.getElementById("appmenu_forwardAsMenu").disabled = !selectedMsg;
+
+ // Disable the Tag menu item if no message is selected or when we're
+ // not in a folder.
+ document.getElementById("appmenu_tagMenu").disabled = !messageStoredInternally;
+
+ // Initialize the Open Message menuitem
+ let winType = document.documentElement.getAttribute('windowtype');
+ if (winType == "mail:3pane")
+ document.getElementById('appmenu_openMessageWindowMenuitem').hidden = isFeed;
+
+ // Initialize the Open Feed Message handler menu
+ let index = FeedMessageHandler.onOpenPref;
+ document.getElementById("appmenu_openFeedMessagePopup")
+ .childNodes[index]
+ .setAttribute("checked", true);
+
+ let openRssMenu = document.getElementById("appmenu_openFeedMessage");
+ openRssMenu.hidden = !isFeed;
+ if (winType != "mail:3pane")
+ openRssMenu.hidden = true;
+
+ // Disable mark menu when we're not in a folder.
+ document.getElementById("appmenu_markMenu").disabled = gMessageDisplay.isDummy;
+ document.commandDispatcher.updateCommands('create-menu-message');
+}
+
+/**
+ * Initializes the menu item aMenuItem to show either "Move" or "Copy" to
+ * folder again, based on the value of mail.last_msg_movecopy_target_uri.
+ * The menu item label and accesskey are adjusted to include the folder name.
+ *
+ * @param aMenuItem the menu item to adjust
+ */
+function initMoveToFolderAgainMenu(aMenuItem)
+{
+ var lastFolderURI = Services.prefs.getCharPref("mail.last_msg_movecopy_target_uri");
+ var isMove = Services.prefs.getBoolPref("mail.last_msg_movecopy_was_move");
+ if (lastFolderURI)
+ {
+ var destMsgFolder = GetMsgFolderFromUri(lastFolderURI);
+ var bundle = document.getElementById("bundle_messenger");
+ var stringName = isMove ? "moveToFolderAgain" : "copyToFolderAgain";
+ aMenuItem.label = bundle.getFormattedString(stringName,
+ [destMsgFolder.prettyName], 1);
+ // This gives us moveToFolderAgainAccessKey and copyToFolderAgainAccessKey.
+ aMenuItem.accesskey = bundle.getString(stringName + "AccessKey");
+ }
+}
+
+function InitViewHeadersMenu()
+{
+ const dt = Components.interfaces.nsMimeHeaderDisplayTypes;
+ var headerchoice = Services.prefs.getIntPref("mail.show_headers");
+ document.getElementById("cmd_viewAllHeader")
+ .setAttribute("checked", headerchoice == dt.AllHeaders);
+ document.getElementById("cmd_viewNormalHeader")
+ .setAttribute("checked", headerchoice == dt.NormalHeaders);
+ document.commandDispatcher.updateCommands("create-menu-mark");
+}
+
+/**
+ * @param headermode {Ci.nsMimeHeaderDisplayTypes}
+ */
+function AdjustHeaderView(headermode)
+{
+ const all = Components.interfaces.nsMimeHeaderDisplayTypes.AllHeaders;
+ document.getElementById("expandedHeaderView")
+ .setAttribute("show_header_mode", headermode == all ? "all" : "normal");
+}
+
+
+function InitViewBodyMenu()
+{
+ // Separate render prefs not implemented for feeds, bug 458606. Show the
+ // checked item for feeds as for the regular pref.
+ // let html_as = Services.prefs.getIntPref("rss.display.html_as");
+ // let prefer_plaintext = Services.prefs.getBoolPref("rss.display.prefer_plaintext");
+ // let disallow_classes = Services.prefs.getIntPref("rss.display.disallow_mime_handlers");
+
+ let html_as = Services.prefs.getIntPref("mailnews.display.html_as");
+ let prefer_plaintext = Services.prefs.getBoolPref("mailnews.display.prefer_plaintext");
+ let disallow_classes = Services.prefs.getIntPref("mailnews.display.disallow_mime_handlers");
+ let isFeed = gFolderDisplay.selectedMessageIsFeed;
+ const defaultIDs = ["bodyAllowHTML",
+ "bodySanitized",
+ "bodyAsPlaintext",
+ "bodyAllParts"];
+ const rssIDs = ["bodyFeedSummaryAllowHTML",
+ "bodyFeedSummarySanitized",
+ "bodyFeedSummaryAsPlaintext"];
+ let menuIDs = isFeed ? rssIDs : defaultIDs;
+
+ if (disallow_classes > 0)
+ gDisallow_classes_no_html = disallow_classes;
+ // else gDisallow_classes_no_html keeps its inital value (see top)
+
+ let AllowHTML_menuitem = document.getElementById(menuIDs[0]);
+ let Sanitized_menuitem = document.getElementById(menuIDs[1]);
+ let AsPlaintext_menuitem = document.getElementById(menuIDs[2]);
+ let AllBodyParts_menuitem = menuIDs[3] ? document.getElementById(menuIDs[3])
+ : null;
+
+ document.getElementById("bodyAllParts").hidden =
+ ! Services.prefs.getBoolPref("mailnews.display.show_all_body_parts_menu");
+
+ if (!prefer_plaintext && !html_as && !disallow_classes &&
+ AllowHTML_menuitem)
+ AllowHTML_menuitem.setAttribute("checked", true);
+ else if (!prefer_plaintext && html_as == 3 && disallow_classes > 0 &&
+ Sanitized_menuitem)
+ Sanitized_menuitem.setAttribute("checked", true);
+ else if (prefer_plaintext && html_as == 1 && disallow_classes > 0 &&
+ AsPlaintext_menuitem)
+ AsPlaintext_menuitem.setAttribute("checked", true);
+ else if (!prefer_plaintext && html_as == 4 && !disallow_classes &&
+ AllBodyParts_menuitem)
+ AllBodyParts_menuitem.setAttribute("checked", true);
+ // else (the user edited prefs/user.js) check none of the radio menu items
+
+ if (isFeed) {
+ AllowHTML_menuitem.hidden = !FeedMessageHandler.gShowSummary;
+ Sanitized_menuitem.hidden = !FeedMessageHandler.gShowSummary;
+ AsPlaintext_menuitem.hidden = !FeedMessageHandler.gShowSummary;
+ document.getElementById("viewFeedSummarySeparator").hidden = !FeedMessageHandler.gShowSummary;
+ }
+}
+
+function InitAppmenuViewBodyMenu()
+{
+ let html_as = Services.prefs.getIntPref("mailnews.display.html_as");
+ let prefer_plaintext = Services.prefs.getBoolPref("mailnews.display.prefer_plaintext");
+ let disallow_classes = Services.prefs.getIntPref("mailnews.display.disallow_mime_handlers");
+ let isFeed = gFolderDisplay.selectedMessageIsFeed;
+ const kDefaultIDs = ["appmenu_bodyAllowHTML",
+ "appmenu_bodySanitized",
+ "appmenu_bodyAsPlaintext",
+ "appmenu_bodyAllParts"];
+ const kRssIDs = ["appmenu_bodyFeedSummaryAllowHTML",
+ "appmenu_bodyFeedSummarySanitized",
+ "appmenu_bodyFeedSummaryAsPlaintext"];
+ let menuIDs = isFeed ? kRssIDs : kDefaultIDs;
+
+ if (disallow_classes > 0)
+ gDisallow_classes_no_html = disallow_classes;
+ // else gDisallow_classes_no_html keeps its inital value (see top)
+
+ let AllowHTML_menuitem = document.getElementById(menuIDs[0]);
+ let Sanitized_menuitem = document.getElementById(menuIDs[1]);
+ let AsPlaintext_menuitem = document.getElementById(menuIDs[2]);
+ let AllBodyParts_menuitem = menuIDs[3] ? document.getElementById(menuIDs[3])
+ : null;
+
+ document.getElementById("appmenu_bodyAllParts").hidden =
+ !Services.prefs.getBoolPref("mailnews.display.show_all_body_parts_menu");
+
+ if (!prefer_plaintext && !html_as && !disallow_classes &&
+ AllowHTML_menuitem)
+ AllowHTML_menuitem.setAttribute("checked", true);
+ else if (!prefer_plaintext && html_as == 3 && disallow_classes > 0 &&
+ Sanitized_menuitem)
+ Sanitized_menuitem.setAttribute("checked", true);
+ else if (prefer_plaintext && html_as == 1 && disallow_classes > 0 &&
+ AsPlaintext_menuitem)
+ AsPlaintext_menuitem.setAttribute("checked", true);
+ else if (!prefer_plaintext && html_as == 4 && !disallow_classes &&
+ AllBodyParts_menuitem)
+ AllBodyParts_menuitem.setAttribute("checked", true);
+ // else (the user edited prefs/user.js) check none of the radio menu items
+
+ if (isFeed) {
+ AllowHTML_menuitem.hidden = !gShowFeedSummary;
+ Sanitized_menuitem.hidden = !gShowFeedSummary;
+ AsPlaintext_menuitem.hidden = !gShowFeedSummary;
+ document.getElementById("appmenu_viewFeedSummarySeparator").hidden = !gShowFeedSummary;
+ }
+}
+
+/**
+ * Expand or collapse the folder pane.
+ */
+function MsgToggleFolderPane()
+{
+ // Bail without doing anything if we are not a folder tab.
+ let currentTabInfo = document.getElementById("tabmail").currentTabInfo;
+ if (currentTabInfo.mode.name != "folder")
+ return;
+
+ togglePaneSplitter("folderpane_splitter");
+}
+
+/**
+ * Expand or collapse the message preview pane.
+ */
+function MsgToggleMessagePane()
+{
+ // Bail without doing anything if we are not a folder tab.
+ let currentTabInfo = document.getElementById("tabmail").currentTabInfo;
+ if (currentTabInfo.mode.name != "folder")
+ return;
+
+ togglePaneSplitter("threadpane-splitter");
+ ChangeMessagePaneVisibility(IsMessagePaneCollapsed());
+ SetFocusThreadPaneIfNotOnMessagePane();
+}
+
+function SetMenuItemLabel(menuItemId, customLabel)
+{
+ var menuItem = document.getElementById(menuItemId);
+ if (menuItem)
+ menuItem.setAttribute('label', customLabel);
+}
+
+function RemoveAllMessageTags()
+{
+ var selectedMessages = gFolderDisplay.selectedMessages;
+ if (!selectedMessages.length)
+ return;
+
+ var messages = Components.classes["@mozilla.org/array;1"]
+ .createInstance(Components.interfaces.nsIMutableArray);
+ let tagArray = MailServices.tags.getAllTags({});
+
+ var allKeys = "";
+ for (var j = 0; j < tagArray.length; ++j)
+ {
+ if (j)
+ allKeys += " ";
+ allKeys += tagArray[j].key;
+ }
+
+ var prevHdrFolder = null;
+ // this crudely handles cross-folder virtual folders with selected messages
+ // that spans folders, by coalescing consecutive messages in the selection
+ // that happen to be in the same folder. nsMsgSearchDBView does this better,
+ // but nsIMsgDBView doesn't handle commands with arguments, and untag takes a
+ // key argument. Furthermore, we only delete legacy labels and known tags,
+ // keeping other keywords like (non)junk intact.
+
+ for (var i = 0; i < selectedMessages.length; ++i)
+ {
+ var msgHdr = selectedMessages[i];
+ msgHdr.label = 0; // remove legacy label
+ if (prevHdrFolder != msgHdr.folder)
+ {
+ if (prevHdrFolder)
+ prevHdrFolder.removeKeywordsFromMessages(messages, allKeys);
+ messages.clear();
+ prevHdrFolder = msgHdr.folder;
+ }
+ messages.appendElement(msgHdr, false);
+ }
+ if (prevHdrFolder)
+ prevHdrFolder.removeKeywordsFromMessages(messages, allKeys);
+ OnTagsChange();
+}
+
+/**
+ * Toggle the state of a message tag on the selected messages (based on the
+ * state of the first selected message, like for starring).
+ *
+ * @param keyNumber the number (1 through 9) associated with the tag
+ */
+function ToggleMessageTagKey(keyNumber)
+{
+ let msgHdr = gFolderDisplay.selectedMessage;
+ if (!msgHdr)
+ return;
+
+ let tagArray = MailServices.tags.getAllTags({});
+ if (keyNumber > tagArray.length)
+ return;
+
+ let key = tagArray[keyNumber - 1].key;
+ let curKeys = msgHdr.getStringProperty("keywords").split(" ");
+ if (msgHdr.label)
+ curKeys.push("$label" + msgHdr.label);
+ let addKey = curKeys.indexOf(key) < 0;
+
+ ToggleMessageTag(key, addKey);
+}
+
+function ToggleMessageTagMenu(target)
+{
+ var key = target.getAttribute("value");
+ var addKey = target.getAttribute("checked") == "true";
+ ToggleMessageTag(key, addKey);
+}
+
+function ToggleMessageTag(key, addKey)
+{
+ var messages = Components.classes["@mozilla.org/array;1"]
+ .createInstance(Components.interfaces.nsIMutableArray);
+ var msg = Components.classes["@mozilla.org/array;1"]
+ .createInstance(Components.interfaces.nsIMutableArray);
+ var selectedMessages = gFolderDisplay.selectedMessages;
+ var toggler = addKey ? "addKeywordsToMessages" : "removeKeywordsFromMessages";
+ var prevHdrFolder = null;
+ // this crudely handles cross-folder virtual folders with selected messages
+ // that spans folders, by coalescing consecutive msgs in the selection
+ // that happen to be in the same folder. nsMsgSearchDBView does this
+ // better, but nsIMsgDBView doesn't handle commands with arguments,
+ // and (un)tag takes a key argument.
+ for (var i = 0; i < selectedMessages.length; ++i)
+ {
+ var msgHdr = selectedMessages[i];
+ if (msgHdr.label)
+ {
+ // Since we touch all these messages anyway, migrate the label now.
+ // If we don't, the thread tree won't always show the correct tag state,
+ // because resetting a label doesn't update the tree anymore...
+ msg.clear();
+ msg.appendElement(msgHdr, false);
+ msgHdr.folder.addKeywordsToMessages(msg, "$label" + msgHdr.label);
+ msgHdr.label = 0; // remove legacy label
+ }
+ if (prevHdrFolder != msgHdr.folder)
+ {
+ if (prevHdrFolder)
+ prevHdrFolder[toggler](messages, key);
+ messages.clear();
+ prevHdrFolder = msgHdr.folder;
+ }
+ messages.appendElement(msgHdr, false);
+ }
+ if (prevHdrFolder)
+ prevHdrFolder[toggler](messages, key);
+ OnTagsChange();
+}
+
+function AddTag()
+{
+ var args = {result: "", okCallback: AddTagCallback};
+ var dialog = window.openDialog("chrome://messenger/content/newTagDialog.xul",
+ "",
+ "chrome,titlebar,modal",
+ args);
+}
+
+function ManageTags()
+{
+ openOptionsDialog("paneDisplay", "tagTab");
+}
+
+function AddTagCallback(name, color)
+{
+ MailServices.tags.addTag(name, color, '');
+ try
+ {
+ ToggleMessageTag(MailServices.tags.getKeyForTag(name), true);
+ }
+ catch(ex)
+ {
+ return false;
+ }
+ return true;
+}
+
+function SetMessageTagLabel(menuitem, index, name)
+{
+ // if a <key> is defined for this tag, use its key as the accesskey
+ // (the key for the tag at index n needs to have the id key_tag<n>)
+ let shortcutkey = document.getElementById("key_tag" + index);
+ let accesskey = shortcutkey ? shortcutkey.getAttribute("key") : " ";
+ if (accesskey != " ") {
+ menuitem.setAttribute("accesskey", accesskey);
+ menuitem.setAttribute("acceltext", accesskey);
+ }
+ let label = document.getElementById("bundle_messenger")
+ .getFormattedString("mailnews.tags.format",
+ [accesskey, name]);
+ menuitem.setAttribute("label", label);
+}
+
+function InitMessageTags(menuPopup)
+{
+ let tagArray = MailServices.tags.getAllTags({});
+ var tagCount = tagArray.length;
+
+ // Remove any existing non-static entries... (clear tags list before rebuilding it)
+ // "5" is the number of menu items (including separators) on the top of the menu
+ // that should not be cleared.
+ for (let i = menuPopup.childNodes.length; i > 5; --i)
+ menuPopup.removeChild(menuPopup.lastChild);
+
+ // create label and accesskey for the static remove item
+ var tagRemoveLabel = document.getElementById("bundle_messenger")
+ .getString("mailnews.tags.remove");
+ SetMessageTagLabel(menuPopup.lastChild.previousSibling, 0, tagRemoveLabel);
+
+ // now rebuild the list
+ var msgHdr = gFolderDisplay.selectedMessage;
+ var curKeys = msgHdr.getStringProperty("keywords");
+ if (msgHdr.label)
+ curKeys += " $label" + msgHdr.label;
+
+ for (var i = 0; i < tagCount; ++i)
+ {
+ var taginfo = tagArray[i];
+ // TODO we want to either remove or "check" the tags that already exist
+ var newMenuItem = document.createElement("menuitem");
+ SetMessageTagLabel(newMenuItem, i + 1, taginfo.tag);
+ newMenuItem.setAttribute("value", taginfo.key);
+ newMenuItem.setAttribute("type", "checkbox");
+ let removeKey = (" " + curKeys + " ").contains(" " + taginfo.key + " ");
+ newMenuItem.setAttribute('checked', removeKey);
+ newMenuItem.setAttribute('oncommand', 'ToggleMessageTagMenu(event.target);');
+ var color = taginfo.color;
+ if (color)
+ newMenuItem.setAttribute("class", "lc-" + color.substr(1));
+ menuPopup.appendChild(newMenuItem);
+ }
+}
+
+function InitRecentlyClosedTabsPopup(menuPopup)
+{
+ let tabs = document.getElementById("tabmail").recentlyClosedTabs;
+
+ // show Popup only when there are restorable tabs.
+ if( !tabs.length )
+ return false;
+
+ // Clear the list before rebulding it.
+ while (menuPopup.childNodes.length > 0)
+ menuPopup.removeChild(menuPopup.firstChild);
+
+ // Rebuild the recently closed tab list
+ for (let i = 0; i < tabs.length; i++ ) {
+
+ let menuItem = document.createElement("menuitem");
+ menuItem.setAttribute("label",tabs[i].title);
+ menuItem.setAttribute('oncommand',
+ 'document.getElementById("tabmail").undoCloseTab('+i+');');
+
+ if (i==0)
+ menuItem.setAttribute('key',"key_undoCloseTab");
+
+ menuPopup.appendChild(menuItem);
+ }
+
+ // "Restore All Tabs" with only one entry does not make sense
+ if (tabs.length > 1) {
+ menuPopup.appendChild(document.createElement("menuseparator"));
+
+ let menuItem = document.createElement("menuitem");
+ menuItem.setAttribute("label", document.getElementById("bundle_messenger")
+ .getString("restoreAllTabs"));
+ menuItem.setAttribute("oncommand","goRestoreAllTabs();");
+ menuPopup.appendChild(menuItem);
+ }
+
+ return true;
+}
+
+function goRestoreAllTabs()
+{
+ let tabmail = document.getElementById("tabmail");
+
+ let len = tabmail.recentlyClosedTabs.length;
+
+ while(len--)
+ document.getElementById("tabmail").undoCloseTab();
+}
+
+function backToolbarMenu_init(menuPopup)
+{
+ populateHistoryMenu(menuPopup, true);
+}
+
+function getMsgToolbarMenu_init()
+{
+ document.commandDispatcher.updateCommands('create-menu-getMsgToolbar');
+}
+
+var gNavDebug = false;
+function navDebug(str)
+{
+ if (gNavDebug)
+ dump(str);
+}
+
+function populateHistoryMenu(menuPopup, isBackMenu)
+{
+ // remove existing entries
+ while (menuPopup.firstChild)
+ menuPopup.removeChild(menuPopup.firstChild);
+ var curPos = new Object;
+ var numEntries = new Object;
+ var historyEntries = new Object;
+ messenger.getNavigateHistory(curPos, numEntries, historyEntries);
+ curPos.value = curPos.value * 2;
+ navDebug("curPos = " + curPos.value + " numEntries = " + numEntries.value + "\n");
+ var historyArray = historyEntries.value;
+ var folder;
+ var newMenuItem;
+ if (gFolderDisplay.selectedMessage)
+ {
+ if (!isBackMenu)
+ curPos.value += 2;
+ else
+ curPos.value -= 2;
+ }
+ // For populating the back menu, we want the most recently visited
+ // messages first in the menu. So we go backward from curPos to 0.
+ // For the forward menu, we want to go forward from curPos to the end.
+ var relPos = 0;
+ for (var i = curPos.value; (isBackMenu) ? i >= 0 : i < historyArray.length; i += ((isBackMenu) ? -2 : 2))
+ {
+ navDebug("history[" + i + "] = " + historyArray[i] + "\n");
+ navDebug("history[" + i + "] = " + historyArray[i + 1] + "\n");
+ folder = GetMsgFolderFromUri(historyArray[i + 1]);
+ navDebug("folder URI = " + folder.URI + "pretty name " + folder.prettyName + "\n");
+ var menuText = "";
+
+ // If the message was not being displayed via the current folder, prepend
+ // the folder name. We do not need to check underlying folders for
+ // virtual folders because 'folder' is the display folder, not the
+ // underlying one.
+ if (folder != gFolderDisplay.displayedFolder)
+ menuText = folder.prettyName + " - ";
+
+ var msgHdr = messenger.msgHdrFromURI(historyArray[i]);
+
+ var subject = "";
+ if (msgHdr.flags & Components.interfaces.nsMsgMessageFlags.HasRe)
+ subject = "Re: ";
+ if (msgHdr.mime2DecodedSubject)
+ subject += msgHdr.mime2DecodedSubject;
+ if (subject)
+ menuText += subject + " - ";
+
+ menuText += msgHdr.mime2DecodedAuthor;
+ newMenuItem = document.createElement('menuitem');
+ newMenuItem.setAttribute('label', menuText);
+ relPos += isBackMenu ? -1 : 1;
+ newMenuItem.setAttribute('value', relPos);
+ newMenuItem.folder = folder;
+ newMenuItem.setAttribute('oncommand', 'NavigateToUri(event.target); event.stopPropagation();');
+ menuPopup.appendChild(newMenuItem);
+ if (! (relPos % 20))
+ break;
+ }
+}
+
+/**
+ * This is triggered by the history navigation menu options, as created by
+ * populateHistoryMenu above.
+ */
+function NavigateToUri(target)
+{
+ var historyIndex = target.getAttribute('value');
+ var msgUri = messenger.getMsgUriAtNavigatePos(historyIndex);
+ var folder = target.folder;
+ var msgHdr = messenger.msgHdrFromURI(msgUri);
+ navDebug("navigating from " + messenger.navigatePos + " by " + historyIndex + " to " + msgUri + "\n");
+
+ // this "- 0" seems to ensure that historyIndex is treated as an int, not a string.
+ messenger.navigatePos += (historyIndex - 0);
+
+ if (gFolderDisplay.displayedFolder != folder) {
+ if (gFolderTreeView)
+ gFolderTreeView.selectFolder(folder);
+ else
+ gFolderDisplay.show(folder);
+ }
+ gFolderDisplay.selectMessage(msgHdr);
+}
+
+function forwardToolbarMenu_init(menuPopup)
+{
+ populateHistoryMenu(menuPopup, false);
+}
+
+function InitMessageMark()
+{
+ document.getElementById("cmd_markAsFlagged")
+ .setAttribute("checked", SelectedMessagesAreFlagged());
+
+ document.commandDispatcher.updateCommands('create-menu-mark');
+}
+
+function UpdateJunkToolbarButton()
+{
+ var junkButtonDeck = document.getElementById("junk-deck");
+ if (junkButtonDeck)
+ junkButtonDeck.selectedIndex = SelectedMessagesAreJunk() ? 1 : 0;
+}
+
+/**
+ * Should the reply command/button be enabled?
+ *
+ * @return whether the reply command/button should be enabled.
+ */
+function IsReplyEnabled()
+{
+ // If we're in an rss item, we never want to Reply, because there's
+ // usually no-one useful to reply to.
+ return !gFolderDisplay.selectedMessageIsFeed;
+}
+
+/**
+ * Should the reply-all command/button be enabled?
+ *
+ * @return whether the reply-all command/button should be enabled.
+ */
+function IsReplyAllEnabled()
+{
+ if (gFolderDisplay.selectedMessageIsNews)
+ // If we're in a news item, we always want ReplyAll, because we can
+ // reply to the sender and the newsgroup.
+ return true;
+ if (gFolderDisplay.selectedMessageIsFeed)
+ // If we're in an rss item, we never want to ReplyAll, because there's
+ // usually no-one useful to reply to.
+ return false;
+
+ let msgHdr = gFolderDisplay.selectedMessage;
+
+ let addresses = msgHdr.author + "," + msgHdr.recipients + "," + msgHdr.ccList;
+
+ // If we've got any BCCed addresses (because we sent the message), add
+ // them as well.
+ if ("bcc" in currentHeaderData)
+ addresses += currentHeaderData.bcc.headerValue;
+
+ // Check to see if my email address is in the list of addresses.
+ let myEmail = getIdentityForHeader(msgHdr).email;
+ // We aren't guaranteed to have an email address, so guard against that.
+ let imInAddresses = myEmail && (addresses.toLowerCase().contains(
+ myEmail.toLowerCase()));
+
+ // Now, let's get the number of unique addresses.
+ let uniqueAddresses = MailServices.headerParser.removeDuplicateAddresses(addresses, "");
+ let emailAddresses = {};
+ let numAddresses = MailServices.headerParser.parseHeadersWithArray(uniqueAddresses,
+ emailAddresses, {}, {});
+
+ // XXX: This should be handled by the nsIMsgHeaderParser. See Bug 498480.
+ // Remove addresses that look like email groups, because we don't support
+ // those yet. (Any address with a : in it will be an empty email group,
+ // or the colon and the groupname would be set as the first name, and not
+ // show up in the address at all.)
+ for (var i in emailAddresses.value)
+ {
+ if (emailAddresses.value[i].contains(":"))
+ numAddresses--;
+ }
+
+ // I don't want to count my address in the number of addresses to reply
+ // to, since I won't be emailing myself.
+ if (imInAddresses)
+ numAddresses--;
+
+ // ReplyAll is enabled if there is more than 1 person to reply to.
+ return numAddresses > 1;
+}
+
+/**
+ * Should the reply-list command/button be enabled?
+ *
+ * @return whether the reply-list command/button should be enabled.
+ */
+function IsReplyListEnabled()
+{
+ // ReplyToList is enabled if there is a List-Post header
+ // with the correct format.
+ let listPost = currentHeaderData["list-post"];
+ if (!listPost)
+ return false;
+
+ // XXX: Once Bug 496914 provides a parser, we should use that instead.
+ // Until then, we need to keep the following regex in sync with the
+ // listPost parsing in nsMsgCompose.cpp's
+ // QuotingOutputStreamListener::OnStopRequest.
+ return /<mailto:.+>/.test(listPost["headerValue"]);
+}
+
+/**
+ * Update the enabled/disabled states of the Reply, Reply-All, and
+ * Reply-List buttons. (After this function runs, one of the buttons
+ * should be shown, and the others should be hidden.)
+ */
+function UpdateReplyButtons()
+{
+ // If we have no message, because we're being called from
+ // MailToolboxCustomizeDone before someone selected a message, then just
+ // return.
+ if (!gFolderDisplay.selectedMessage)
+ return;
+
+ let buttonToShow;
+ if (gFolderDisplay.selectedMessageIsNews)
+ {
+ // News messages always default to the "followup" dual-button.
+ buttonToShow = "followup";
+ }
+ else if (gFolderDisplay.selectedMessageIsFeed)
+ {
+ // RSS items hide all the reply buttons.
+ buttonToShow = null;
+ }
+ else
+ {
+ // Mail messages show the "reply" button (not the dual-button) and
+ // possibly the "reply all" and "reply list" buttons.
+ if (IsReplyListEnabled())
+ buttonToShow = "replyList";
+ else if (IsReplyAllEnabled())
+ buttonToShow = "replyAll";
+ else
+ buttonToShow = "reply";
+ }
+
+ let smartReplyButton = document.getElementById("hdrSmartReplyButton");
+ if (smartReplyButton)
+ {
+ let replyButton = document.getElementById("hdrReplyButton");
+ let replyAllButton = document.getElementById("hdrReplyAllButton");
+ let replyListButton = document.getElementById("hdrReplyListButton");
+ let followupButton = document.getElementById("hdrFollowupButton");
+
+ replyButton.hidden = (buttonToShow != "reply");
+ replyAllButton.hidden = (buttonToShow != "replyAll");
+ replyListButton.hidden = (buttonToShow != "replyList");
+ followupButton.hidden = (buttonToShow != "followup");
+ }
+
+ let replyToSenderButton = document.getElementById("hdrReplyToSenderButton");
+ if (replyToSenderButton)
+ {
+ if (gFolderDisplay.selectedMessageIsFeed)
+ replyToSenderButton.hidden = true;
+ else if (smartReplyButton)
+ replyToSenderButton.hidden = (buttonToShow == "reply");
+ else
+ replyToSenderButton.hidden = false;
+ }
+
+ goUpdateCommand("button_reply");
+ goUpdateCommand("button_replyall");
+ goUpdateCommand("button_replylist");
+ goUpdateCommand("button_followup");
+}
+
+function UpdateDeleteToolbarButton()
+{
+ var deleteButtonDeck = document.getElementById("delete-deck");
+ if (!deleteButtonDeck)
+ return;
+
+ // Never show "Undelete" in the 3-pane for folders, when delete would
+ // apply to the selected folder.
+ if (gFolderDisplay.focusedPane == document.getElementById("folderTree") &&
+ GetNumSelectedMessages() == 0)
+ deleteButtonDeck.selectedIndex = 0;
+ else
+ deleteButtonDeck.selectedIndex = SelectedMessagesAreDeleted() ? 1 : 0;
+}
+function UpdateDeleteCommand()
+{
+ var value = "value";
+ if (SelectedMessagesAreDeleted())
+ value += "IMAPDeleted";
+ if (GetNumSelectedMessages() < 2)
+ value += "Message";
+ else
+ value += "Messages";
+ goSetMenuValue("cmd_delete", value);
+ goSetAccessKey("cmd_delete", value + "AccessKey");
+}
+
+function SelectedMessagesAreDeleted()
+{
+ let firstSelectedMessage = gFolderDisplay.selectedMessage;
+ return firstSelectedMessage &&
+ (firstSelectedMessage.flags &
+ Components.interfaces.nsMsgMessageFlags.IMAPDeleted);
+}
+
+function SelectedMessagesAreJunk()
+{
+ try {
+ var junkScore = gFolderDisplay.selectedMessage.getStringProperty("junkscore");
+ return (junkScore != "") && (junkScore != "0");
+ }
+ catch (ex) {
+ return false;
+ }
+}
+
+function SelectedMessagesAreRead()
+{
+ let messages = gFolderDisplay.selectedMessages;
+ if (messages.length == 0)
+ return undefined;
+ if (messages.every(function(msg) { return msg.isRead; }))
+ return true;
+ if (messages.every(function(msg) { return !msg.isRead; }))
+ return false;
+ return undefined;
+}
+
+function SelectedMessagesAreFlagged()
+{
+ let firstSelectedMessage = gFolderDisplay.selectedMessage;
+ return firstSelectedMessage && firstSelectedMessage.isFlagged;
+}
+
+function GetFirstSelectedMsgFolder()
+{
+ try {
+ var selectedFolders = GetSelectedMsgFolders();
+ } catch (e) {
+ logException(e);
+ }
+ return (selectedFolders.length > 0) ? selectedFolders[0] : null;
+}
+
+function GetInboxFolder(server)
+{
+ try {
+ var rootMsgFolder = server.rootMsgFolder;
+
+ // Now find the Inbox.
+ const nsMsgFolderFlags = Components.interfaces.nsMsgFolderFlags;
+ return rootMsgFolder.getFolderWithFlags(nsMsgFolderFlags.Inbox);
+ }
+ catch (ex) {
+ dump(ex + "\n");
+ }
+ return null;
+}
+
+function GetMessagesForInboxOnServer(server)
+{
+ var inboxFolder = GetInboxFolder(server);
+
+ // If the server doesn't support an inbox it could be an RSS server or some
+ // other server type. Just use the root folder and the server implementation
+ // can figure out what to do.
+ if (!inboxFolder)
+ inboxFolder = server.rootFolder;
+
+ GetNewMsgs(server, inboxFolder);
+}
+
+function MsgGetMessage()
+{
+ // if offline, prompt for getting messages
+ if (MailOfflineMgr.isOnline() || MailOfflineMgr.getNewMail())
+ GetFolderMessages();
+}
+
+function MsgGetMessagesForAllServers(defaultServer)
+{
+ // now log into any server
+ try
+ {
+ var allServers = accountManager.allServers;
+ // Array of arrays of servers for a particular folder.
+ var pop3DownloadServersArray = [];
+ // Parallel array of folders to download to...
+ var localFoldersToDownloadTo = [];
+ var pop3Server;
+ for (var i = 0; i < allServers.length; ++i)
+ {
+ var currentServer = allServers.queryElementAt(i, Components.interfaces.nsIMsgIncomingServer);
+ if (currentServer.protocolInfo.canLoginAtStartUp &&
+ currentServer.loginAtStartUp)
+ {
+ if (defaultServer && defaultServer.equals(currentServer) &&
+ !defaultServer.isDeferredTo &&
+ defaultServer.rootFolder == defaultServer.rootMsgFolder)
+ {
+ // skip, already opened
+ }
+ else if (currentServer.type == "pop3" && currentServer.downloadOnBiff)
+ {
+ CoalesceGetMsgsForPop3ServersByDestFolder(currentServer,
+ pop3DownloadServersArray, localFoldersToDownloadTo);
+ pop3Server = currentServer.QueryInterface(Components.interfaces.nsIPop3IncomingServer);
+ }
+ else
+ {
+ // Check to see if there are new messages on the server
+ currentServer.performBiff(msgWindow);
+ }
+ }
+ }
+ for (var i = 0; i < pop3DownloadServersArray.length; ++i)
+ {
+ // Any ol' pop3Server will do - the serversArray specifies which servers
+ // to download from.
+ pop3Server.downloadMailFromServers(pop3DownloadServersArray[i],
+ pop3DownloadServersArray[i].length,
+ msgWindow,
+ localFoldersToDownloadTo[i],
+ null);
+ }
+ }
+ catch(ex)
+ {
+ dump(ex + "\n");
+ }
+}
+
+/**
+ * Get messages for all those accounts which have the capability
+ * of getting messages and have session password available i.e.,
+ * curretnly logged in accounts.
+ * if offline, prompt for getting messages.
+ */
+function MsgGetMessagesForAllAuthenticatedAccounts()
+{
+ if (MailOfflineMgr.isOnline() || MailOfflineMgr.getNewMail())
+ GetMessagesForAllAuthenticatedAccounts();
+}
+
+/**
+ * Get messages for the account selected from Menu dropdowns.
+ * if offline, prompt for getting messages.
+ *
+ * @param aFolder (optional) a folder in the account for which messages should
+ * be retrieved. If null, all accounts will be used.
+ */
+function MsgGetMessagesForAccount(aFolder)
+{
+ if (!aFolder) {
+ goDoCommand('cmd_getNewMessages');
+ return;
+ }
+
+ if (MailOfflineMgr.isOnline() || MailOfflineMgr.getNewMail()) {
+ var server = aFolder.server;
+ GetMessagesForInboxOnServer(server);
+ }
+}
+
+// if offline, prompt for getNextNMessages
+function MsgGetNextNMessages()
+{
+ if (MailOfflineMgr.isOnline() || MailOfflineMgr.getNewMail())
+ GetNextNMessages(GetFirstSelectedMsgFolder());
+}
+
+function MsgDeleteMessage(reallyDelete, fromToolbar)
+{
+ // If from the toolbar, return right away if this is a news message
+ // only allow cancel from the menu: "Edit | Cancel / Delete Message".
+ if (fromToolbar && gFolderDisplay.view.isNewsFolder)
+ return;
+
+ gFolderDisplay.hintAboutToDeleteMessages();
+ if (reallyDelete)
+ gDBView.doCommand(nsMsgViewCommandType.deleteNoTrash);
+ else
+ gDBView.doCommand(nsMsgViewCommandType.deleteMsg);
+}
+
+/**
+ * Copies the selected messages to the destination folder
+ * @param aDestFolder the destination folder
+ */
+function MsgCopyMessage(aDestFolder)
+{
+ if (gMessageDisplay.isDummy) {
+ let file = window.arguments[0].QueryInterface(Components.interfaces
+ .nsIFileURL).file;
+ MailServices.copy.CopyFileMessage(file, aDestFolder, null, false,
+ Components.interfaces.nsMsgMessageFlags.Read,
+ "", null, msgWindow);
+ }
+ else
+ gDBView.doCommandWithFolder(nsMsgViewCommandType.copyMessages, aDestFolder);
+
+ Services.prefs.setCharPref("mail.last_msg_movecopy_target_uri", aDestFolder.URI);
+ Services.prefs.setBoolPref("mail.last_msg_movecopy_was_move", false);
+}
+
+/**
+ * Moves the selected messages to the destination folder
+ * @param aDestFolder the destination folder
+ */
+function MsgMoveMessage(aDestFolder)
+{
+ gFolderDisplay.hintAboutToDeleteMessages();
+ gDBView.doCommandWithFolder(nsMsgViewCommandType.moveMessages, aDestFolder);
+ Services.prefs.setCharPref("mail.last_msg_movecopy_target_uri", aDestFolder.URI);
+ Services.prefs.setBoolPref("mail.last_msg_movecopy_was_move", true);
+}
+
+/**
+ * Calls the ComposeMessage function with the desired type, and proper default
+ * based on the event that fired it.
+ *
+ * @param aCompType the nsIMsgCompType to pass to the function
+ * @param aEvent (optional) the event that triggered the call
+ */
+function composeMsgByType(aCompType, aEvent) {
+ // If we're the hidden window, then we're not going to have a gFolderDisplay
+ // to work out existing folders, so just use null.
+ let msgFolder = gFolderDisplay ? GetFirstSelectedMsgFolder() : null;
+ let msgUris = gFolderDisplay ? gFolderDisplay.selectedMessageUris : null;
+
+ if (aEvent && aEvent.shiftKey) {
+ ComposeMessage(aCompType,
+ Components.interfaces.nsIMsgCompFormat.OppositeOfDefault,
+ msgFolder, msgUris);
+ }
+ else {
+ ComposeMessage(aCompType, Components.interfaces.nsIMsgCompFormat.Default,
+ msgFolder, msgUris);
+ }
+}
+
+function MsgNewMessage(event)
+{
+ composeMsgByType(Components.interfaces.nsIMsgCompType.New, event);
+}
+
+function MsgReplyMessage(event)
+{
+ if (gFolderDisplay.selectedMessageIsNews)
+ MsgReplyGroup(event);
+ else
+ MsgReplySender(event);
+}
+
+function MsgReplySender(event)
+{
+ composeMsgByType(Components.interfaces.nsIMsgCompType.ReplyToSender, event);
+}
+
+function MsgReplyGroup(event)
+{
+ composeMsgByType(Components.interfaces.nsIMsgCompType.ReplyToGroup, event);
+}
+
+function MsgReplyToAllMessage(event)
+{
+ composeMsgByType(Components.interfaces.nsIMsgCompType.ReplyAll, event);
+}
+
+function MsgReplyToListMessage(event)
+{
+ composeMsgByType(Components.interfaces.nsIMsgCompType.ReplyToList, event);
+}
+
+// Message Archive function
+
+function BatchMessageMover()
+{
+ this._batches = {};
+ this._currentKey = null;
+}
+
+BatchMessageMover.prototype = {
+
+ archiveMessages: function BatchMessageMover_archiveMessages (aMsgHdrs)
+ {
+ gFolderDisplay.hintMassMoveStarting();
+
+ if (!aMsgHdrs.length)
+ return;
+
+ for (let i = 0; i < aMsgHdrs.length; ++i)
+ {
+ let msgHdr = aMsgHdrs[i];
+
+ let server = msgHdr.folder.server;
+ let rootFolder = server.rootFolder;
+
+ let msgDate = new Date(msgHdr.date / 1000); // convert date to JS date object
+ let msgYear = msgDate.getFullYear().toString();
+ let monthFolderName = msgDate.toLocaleFormat("%Y-%m");
+ let archiveFolderUri;
+
+ let archiveGranularity;
+ let archiveKeepFolderStructure;
+ if (server.type == "rss") {
+ // RSS servers don't have an identity so we special case the archives URI.
+ archiveFolderUri = server.serverURI + "/Archives";
+ archiveGranularity = Application.prefs.getValue("mail.identity.default.archive_granularity", 0);
+ archiveKeepFolderStructure =
+ Application.prefs.getValue("mail.identity.default.archive_keep_folder_structure", false);
+ }
+ else {
+ let identity = getIdentityForHeader(msgHdr);
+ archiveFolderUri = identity.archiveFolder;
+ archiveGranularity = identity.archiveGranularity;
+ archiveKeepFolderStructure = identity.archiveKeepFolderStructure;
+ }
+ let archiveFolder = GetMsgFolderFromUri(archiveFolderUri, false);
+
+ let copyBatchKey = msgHdr.folder.URI + '\0' + monthFolderName;
+ if (archiveGranularity >= Components.interfaces.nsIMsgIdentity
+ .perMonthArchiveFolders)
+ copyBatchKey += msgYear;
+
+ if (archiveGranularity >= Components.interfaces.nsIMsgIdentity
+ .perMonthArchiveFolders)
+ copyBatchKey += monthFolderName;
+
+ if (archiveKeepFolderStructure)
+ copyBatchKey += msgHdr.folder.URI;
+
+ // Add a key to copyBatchKey
+ if (! (copyBatchKey in this._batches)) {
+ this._batches[copyBatchKey] = [msgHdr.folder, archiveFolderUri,
+ archiveGranularity,
+ archiveKeepFolderStructure,
+ msgYear, monthFolderName];
+ }
+ this._batches[copyBatchKey].push(msgHdr);
+ }
+ MailServices.mfn.addListener(this, MailServices.mfn.folderAdded);
+
+ // Now we launch the code iterating over all message copies, one in turn.
+ this.processNextBatch();
+ },
+
+ processNextBatch: function BatchMessageMover_processNextBatch ()
+ {
+ for (let key in this._batches)
+ {
+ this._currentKey = key;
+ let batch = this._batches[key];
+ let [srcFolder, archiveFolderUri, granularity, keepFolderStructure, msgYear, msgMonth] = batch;
+ let msgs = batch.slice(6);
+
+ let archiveFolder = GetMsgFolderFromUri(archiveFolderUri, false);
+ let dstFolder = archiveFolder;
+ // For folders on some servers (e.g. IMAP), we need to create the
+ // sub-folders asynchronously, so we chain the urls using the listener
+ // called back from createStorageIfMissing. For local,
+ // createStorageIfMissing is synchronous.
+ let isAsync = archiveFolder.server.protocolInfo.foldersCreatedAsync;
+ if (!archiveFolder.parent)
+ {
+ archiveFolder.setFlag(Components.interfaces.nsMsgFolderFlags.Archive);
+ archiveFolder.createStorageIfMissing(this);
+ if (isAsync)
+ return;
+ }
+
+ let forceSingle = !archiveFolder.canCreateSubfolders;
+ if (!forceSingle && (archiveFolder.server instanceof
+ Components.interfaces.nsIImapIncomingServer))
+ forceSingle = archiveFolder.server.isGMailServer;
+ if (forceSingle)
+ granularity = Components.interfaces.nsIMsgIncomingServer
+ .singleArchiveFolder;
+
+ if (granularity >= Components.interfaces.nsIMsgIdentity.perYearArchiveFolders)
+ {
+ archiveFolderUri += "/" + msgYear;
+ dstFolder = GetMsgFolderFromUri(archiveFolderUri, false);
+ if (!dstFolder.parent)
+ {
+ dstFolder.createStorageIfMissing(this);
+ if (isAsync)
+ return;
+ }
+ }
+ if (granularity >= Components.interfaces.nsIMsgIdentity.perMonthArchiveFolders)
+ {
+ archiveFolderUri += "/" + msgMonth;
+ dstFolder = GetMsgFolderFromUri(archiveFolderUri, false);
+ if (!dstFolder.parent)
+ {
+ dstFolder.createStorageIfMissing(this);
+ if (isAsync)
+ return;
+ }
+ }
+
+ // Create the folder structure in Archives
+ // For imap folders, we need to create the sub-folders asynchronously,
+ // so we chain the actions using the listener called back from
+ // createSubfolder. For local, createSubfolder is synchronous.
+ if (archiveFolder.canCreateSubfolders && keepFolderStructure)
+ {
+ // Collect in-order list of folders of source folder structure,
+ // excluding top-level INBOX folder
+ let folderNames = [];
+ let rootFolder = srcFolder.server.rootFolder;
+ let inboxFolder = GetInboxFolder(srcFolder.server);
+ let folder = srcFolder;
+ while (folder != rootFolder && folder != inboxFolder)
+ {
+ folderNames.unshift(folder.name);
+ folder = folder.parent;
+ }
+ // Determine Archive folder structure
+ for (let i = 0; i < folderNames.length; ++i)
+ {
+ let folderName = folderNames[i];
+ if (!dstFolder.containsChildNamed(folderName))
+ {
+ // Create Archive sub-folder (IMAP: async)
+ if (isAsync)
+ {
+ this._dstFolderParent = dstFolder;
+ this._dstFolderName = folderName;
+ }
+ dstFolder.createSubfolder(folderName, msgWindow);
+ if (isAsync)
+ return;
+ }
+ dstFolder = dstFolder.getChildNamed(folderName);
+ }
+ }
+
+ if (dstFolder != srcFolder)
+ {
+ let array = Components.classes["@mozilla.org/array;1"]
+ .createInstance(Components.interfaces.nsIMutableArray);
+ msgs.forEach(function(item){array.appendElement(item, false);});
+ // If the source folder doesn't support deleting messages, we
+ // make archive a copy, not a move.
+ MailServices.copy.CopyMessages(srcFolder, array, dstFolder,
+ srcFolder.canDeleteMessages, this, msgWindow, true);
+ return; // only do one.
+ }
+ delete this._batches[key];
+ }
+ gFolderDisplay.hintMassMoveCompleted();
+
+ MailServices.mfn.removeListener(this);
+
+ },
+ OnStartRunningUrl: function(url) {
+ },
+
+ OnStopRunningUrl: function(url, exitCode)
+ {
+ // this will always be a create folder url, afaik.
+ if (Components.isSuccessCode(exitCode))
+ this.processNextBatch();
+ else
+ this._batches = null;
+ },
+
+ // also implements nsIMsgCopyServiceListener, but we only care
+ // about the OnStopCopy
+ OnStartCopy: function() {
+ },
+ OnProgress: function(aProgress, aProgressMax) {
+ },
+ SetMessageKey: function(aKey) {
+ },
+ GetMessageId: function() {
+ },
+ OnStopCopy: function(aStatus)
+ {
+ if (Components.isSuccessCode(aStatus))
+ {
+ // remove batch we just finished and continue
+ delete this._batches[this._currentKey];
+ this._currentKey = null;
+ this.processNextBatch();
+ }
+ else
+ {
+ this._batches = null;
+ }
+ },
+ // This also implements nsIMsgFolderListener, but we only care about the
+ // folderAdded (createSubfolder callback).
+ folderAdded: function(aFolder)
+ {
+ // Check that this is the folder we're interested in.
+ if (aFolder.parent == this._dstFolderParent &&
+ aFolder.name == this._dstFolderName)
+ {
+ this._dstFolderParent = null;
+ this._dstFolderName = null;
+ this.processNextBatch();
+ }
+ },
+
+ QueryInterface: function(iid) {
+ if (!iid.equals(Components.interfaces.nsIUrlListener) &&
+ !iid.equals(Components.interfaces.nsIMsgCopyServiceListener) &&
+ !iid.equals(Components.interfaces.nsISupports))
+ throw Components.results.NS_ERROR_NO_INTERFACE;
+ return this;
+ }
+}
+
+/**
+ * Archives the selected messages
+ *
+ * @param event the event that caused us to call this function
+ */
+function MsgArchiveSelectedMessages(event)
+{
+ let batchMover = new BatchMessageMover();
+ batchMover.archiveMessages(gFolderDisplay.selectedMessages);
+}
+
+function MsgForwardMessage(event)
+{
+ var forwardType = 0;
+ try {
+ forwardType = Services.prefs.getIntPref("mail.forward_message_mode");
+ }
+ catch (ex) {
+ dump("failed to retrieve pref mail.forward_message_mode");
+ }
+
+ // mail.forward_message_mode could be 1, if the user migrated from 4.x
+ // 1 (forward as quoted) is obsolete, so we treat is as forward inline
+ // since that is more like forward as quoted then forward as attachment
+ if (forwardType == 0)
+ MsgForwardAsAttachment(event);
+ else
+ MsgForwardAsInline(event);
+}
+
+function MsgForwardAsAttachment(event)
+{
+ composeMsgByType(Components.interfaces.nsIMsgCompType.ForwardAsAttachment, event);
+}
+
+function MsgForwardAsInline(event)
+{
+ composeMsgByType(Components.interfaces.nsIMsgCompType.ForwardInline, event);
+}
+
+function MsgEditMessageAsNew()
+{
+ composeMsgByType(Components.interfaces.nsIMsgCompType.Template);
+}
+
+function MsgComposeDraftMessage()
+{
+ ComposeMessage(Components.interfaces.nsIMsgCompType.Draft,
+ Components.interfaces.nsIMsgCompFormat.Default,
+ gFolderDisplay.displayedFolder,
+ gFolderDisplay.selectedMessageUris);
+}
+
+function MsgCreateFilter()
+{
+ // retrieve Sender direct from selected message's headers
+ var msgHdr = gFolderDisplay.selectedMessage;
+ let emailAddress = MailServices.headerParser.extractHeaderAddressMailboxes(msgHdr.author);
+ if (emailAddress)
+ top.MsgFilters(emailAddress, null);
+}
+
+function MsgNewFolder(callBackFunctionName)
+{
+ var preselectedFolder = GetFirstSelectedMsgFolder();
+ var dualUseFolders = true;
+ var server = null;
+ var destinationFolder = null;
+
+ if (preselectedFolder)
+ {
+ try {
+ server = preselectedFolder.server;
+ if (server)
+ {
+ destinationFolder = getDestinationFolder(preselectedFolder, server);
+
+ var imapServer =
+ server.QueryInterface(Components.interfaces.nsIImapIncomingServer);
+ if (imapServer)
+ dualUseFolders = imapServer.dualUseFolders;
+ }
+ } catch (e) {
+ dump ("Exception: dualUseFolders = true\n");
+ }
+ }
+ window.openDialog("chrome://messenger/content/newFolderDialog.xul", "",
+ "chrome,titlebar,modal",
+ {folder: destinationFolder, dualUseFolders: dualUseFolders,
+ okCallback:callBackFunctionName});
+}
+
+function getDestinationFolder(preselectedFolder, server)
+{
+ var destinationFolder = null;
+
+ if (!preselectedFolder.canCreateSubfolders)
+ {
+ destinationFolder = server.rootMsgFolder;
+
+ var verifyCreateSubfolders = null;
+ if (destinationFolder)
+ verifyCreateSubfolders = destinationFolder.canCreateSubfolders;
+
+ // In case the server cannot have subfolders, get default account and set
+ // its incoming server as parent folder.
+ if (!verifyCreateSubfolders)
+ {
+ try {
+ var defaultFolder = GetDefaultAccountRootFolder();
+ var checkCreateSubfolders = null;
+ if (defaultFolder)
+ checkCreateSubfolders = defaultFolder.canCreateSubfolders;
+
+ if (checkCreateSubfolders)
+ destinationFolder = defaultFolder;
+
+ } catch (e) {
+ dump ("Exception: defaultAccount Not Available\n");
+ }
+ }
+ }
+ else
+ destinationFolder = preselectedFolder;
+
+ return destinationFolder;
+}
+
+/** Open subscribe window. */
+function MsgSubscribe()
+{
+ var preselectedFolder = GetFirstSelectedMsgFolder();
+
+ if (preselectedFolder && preselectedFolder.server.type == "rss")
+ openSubscriptionsDialog(preselectedFolder); // open feed subscription dialog
+ else
+ Subscribe(preselectedFolder); // open imap/nntp subscription dialog
+}
+
+/**
+ * Show a confirmation dialog - check if the user really want to unsubscribe
+ * from the given newsgroup/s.
+ * @folders an array of newsgroup folders to unsubscribe from
+ * @return true if the user said it's ok to unsubscribe
+ */
+function ConfirmUnsubscribe(folders)
+{
+ var bundle = document.getElementById("bundle_messenger");
+ var titleMsg = bundle.getString("confirmUnsubscribeTitle");
+ var dialogMsg = (folders.length == 1) ?
+ bundle.getFormattedString("confirmUnsubscribeText", [folders[0].name], 1) :
+ bundle.getString("confirmUnsubscribeManyText");
+
+ return Services.prompt.confirm(window, titleMsg, dialogMsg);
+}
+
+/**
+ * Unsubscribe from selected or passed in newsgroup/s.
+ * @param newsgroups (optional param) the newsgroup folders to unsubscribe from
+ */
+function MsgUnsubscribe(newsgroups)
+{
+ var folders = newsgroups || gFolderTreeView.getSelectedFolders();
+ if (!ConfirmUnsubscribe(folders))
+ return;
+
+ for (let i = 0; i < folders.length; i++) {
+ let subscribableServer = folders[i].server.QueryInterface(
+ Components.interfaces.nsISubscribableServer);
+ subscribableServer.unsubscribe(folders[i].name);
+ subscribableServer.commitSubscribeChanges();
+ }
+}
+
+function ToggleFavoriteFolderFlag()
+{
+ var folder = GetFirstSelectedMsgFolder();
+ folder.toggleFlag(Components.interfaces.nsMsgFolderFlags.Favorite);
+}
+
+function MsgSaveAsFile()
+{
+ SaveAsFile(gFolderDisplay.selectedMessageUris);
+}
+
+function MsgSaveAsTemplate()
+{
+ if (GetNumSelectedMessages() == 1)
+ SaveAsTemplate(gFolderDisplay.selectedMessageUris[0]);
+}
+
+function CreateToolbarTooltip(document, event)
+{
+ event.stopPropagation();
+ var tn = document.tooltipNode;
+ if (tn.localName != "tab")
+ return false; // Not a tab, so cancel the tooltip.
+ if ("mOverCloseButton" in tn && tn.mOverCloseButton) {
+ event.target.setAttribute("label", tn.getAttribute("closetabtext"));
+ return true;
+ }
+ if (tn.hasAttribute("label")) {
+ event.target.setAttribute("label", tn.getAttribute("label"));
+ return true;
+ }
+ return false;
+}
+
+function MsgOpenNewWindowForFolder(folderURI, msgKeyToSelect)
+{
+ if (folderURI) {
+ window.openDialog("chrome://messenger/content/", "_blank",
+ "chrome,all,dialog=no", folderURI, msgKeyToSelect);
+ return;
+ }
+
+ // If there is a right-click happening, gFolderTreeView.getSelectedFolders()
+ // will tell us about it (while the selection's currentIndex would reflect
+ // the node that was selected/displayed before the right-click.)
+ let selectedFolders = gFolderTreeView.getSelectedFolders();
+ for (let i = 0; i < selectedFolders.length; i++) {
+ window.openDialog("chrome://messenger/content/", "_blank",
+ "chrome,all,dialog=no",
+ selectedFolders[i].URI, msgKeyToSelect);
+ }
+}
+
+/**
+ * UI-triggered command to open the currently selected folder(s) in new tabs.
+ * @param aBackground [optional] if true, then the folder tab is opened in the
+ * background. If false or not given, then the folder tab is
+ * opened in the foreground.
+ */
+function MsgOpenNewTabForFolder(aBackground)
+{
+ // If there is a right-click happening, gFolderTreeView.getSelectedFolders()
+ // will tell us about it (while the selection's currentIndex would reflect
+ // the node that was selected/displayed before the right-click.)
+ let selectedFolders = gFolderTreeView.getSelectedFolders();
+ for (let i = 0; i < selectedFolders.length; i++) {
+ document.getElementById("tabmail").openTab("folder",
+ {folder: selectedFolders[i], background: aBackground});
+ }
+}
+
+function MsgOpenSelectedMessages()
+{
+ // Toggle message body (feed summary) and content-base url in message pane or
+ // load in browser, per pref, otherwise open summary or web page in new window
+ // or tab, per that pref.
+ if (gFolderDisplay.selectedMessageIsFeed) {
+ let msgHdr = gFolderDisplay.selectedMessage;
+ if (FeedMessageHandler.onOpenPref == FeedMessageHandler.kOpenToggleInMessagePane) {
+ let showSummary = FeedMessageHandler.shouldShowSummary(msgHdr, true);
+ FeedMessageHandler.setContent(msgHdr, showSummary);
+ return;
+ }
+ if (FeedMessageHandler.onOpenPref == FeedMessageHandler.kOpenLoadInBrowser) {
+ setTimeout(FeedMessageHandler.loadWebPage, 20, msgHdr, {browser:true});
+ return;
+ }
+ }
+
+ // This is somewhat evil. If we're in a 3pane window, we'd have a tabmail
+ // element and would pass it in here, ensuring that if we open tabs, we use
+ // this tabmail to open them. If we aren't, then we wouldn't, so
+ // displayMessages would look for a 3pane window and open tabs there.
+ MailUtils.displayMessages(gFolderDisplay.selectedMessages,
+ gFolderDisplay.view,
+ document.getElementById("tabmail"));
+}
+
+function MsgOpenFromFile()
+{
+ const nsIFilePicker = Components.interfaces.nsIFilePicker;
+ var fp = Components.classes["@mozilla.org/filepicker;1"]
+ .createInstance(nsIFilePicker);
+
+ var bundle = document.getElementById("bundle_messenger");
+ var filterLabel = bundle.getString("EMLFiles");
+ var windowTitle = bundle.getString("OpenEMLFiles");
+
+ fp.init(window, windowTitle, nsIFilePicker.modeOpen);
+ fp.appendFilter(filterLabel, "*.eml");
+
+ // Default or last filter is "All Files".
+ fp.appendFilters(nsIFilePicker.filterAll);
+
+ try {
+ var ret = fp.show();
+ if (ret == nsIFilePicker.returnCancel)
+ return;
+ }
+ catch (ex) {
+ dump("filePicker.chooseInputFile threw an exception\n");
+ return;
+ }
+
+ var uri = fp.fileURL.QueryInterface(Components.interfaces.nsIURL);
+ uri.query = "type=application/x-message-display";
+
+ window.openDialog("chrome://messenger/content/messageWindow.xul", "_blank",
+ "all,chrome,dialog=no,status,toolbar", uri);
+}
+
+function MsgOpenNewWindowForMessage(aMsgHdr)
+{
+ // no message header provided? get the selected message (this will give us
+ // the right-click selected message if that's what is going down.)
+ if (!aMsgHdr)
+ aMsgHdr = gFolderDisplay.selectedMessage;
+
+ // (there might not have been a selected message, so check...)
+ if (aMsgHdr)
+ // we also need to tell the window about our current view so that it can
+ // clone it. This enables advancing through the messages, etc.
+ window.openDialog("chrome://messenger/content/messageWindow.xul", "_blank",
+ "all,chrome,dialog=no,status,toolbar",
+ aMsgHdr, gFolderDisplay.view);
+}
+
+/**
+ * Display the given message in an existing folder tab.
+ *
+ * @param aMsgHdr The message header to display.
+ */
+function MsgDisplayMessageInFolderTab(aMsgHdr)
+{
+ // Look for a folder tab
+ let tabmail = document.getElementById("tabmail");
+ let folderTab = tabmail.getTabInfoForCurrentOrFirstModeInstance(
+ tabmail.tabModes["folder"]);
+ let folderDisplay = folderTab.folderDisplay;
+ let folder = gFolderTreeView.getFolderForMsgHdr(aMsgHdr);
+
+ // XXX Yuck. We really need to have the tabmail be able to handle an extra
+ // param with data to send to showTab, and to have the folder display have
+ // a |selectFolderAndMessage| method that handles most of the messiness.
+ folderDisplay.selectMessageComingUp();
+
+ // Switch to the tab
+ tabmail.switchToTab(folderTab);
+
+ // We don't want to drop view filters at first
+ if (folderDisplay.view.getViewIndexForMsgHdr(aMsgHdr, false) !=
+ nsMsgViewIndex_None) {
+ folderDisplay.selectMessage(aMsgHdr);
+ }
+ else {
+ if (folderDisplay.displayedFolder != folder ||
+ folderDisplay.view.isVirtual) {
+ // Force select the folder
+ folderDisplay.show(folder);
+ gFolderTreeView.selectFolder(folder, true);
+ }
+
+ // Force select the message
+ folderDisplay.selectMessage(aMsgHdr, true);
+ }
+}
+
+function MsgJunk()
+{
+ MsgJunkMailInfo(true);
+ JunkSelectedMessages(!SelectedMessagesAreJunk());
+}
+
+/**
+ * Update the "mark as junk" button in the message header area.
+ */
+function UpdateJunkButton()
+{
+ // The junk message should slave off the selected message, as the preview pane
+ // may not be visible
+ let hdr = gFolderDisplay.selectedMessage;
+ // But only the message display knows if we are dealing with a dummy.
+ if (!hdr || gMessageDisplay.isDummy) // .eml file
+ return;
+ let junkScore = hdr.getStringProperty("junkscore");
+ let hideJunk = (junkScore == Components.interfaces.nsIJunkMailPlugin.IS_SPAM_SCORE);
+ if (!gFolderDisplay.getCommandStatus(nsMsgViewCommandType.junk))
+ hideJunk = true;
+ if (document.getElementById('hdrJunkButton')) {
+ document.getElementById('hdrJunkButton').disabled = hideJunk;
+ }
+}
+
+/**
+ * Checks if the selected messages can be marked as read or unread
+ *
+ * @param markingRead true if trying to mark messages as read, false otherwise
+ * @return true if the chosen operation can be performed
+ */
+function CanMarkMsgAsRead(markingRead)
+{
+ return gFolderDisplay.selectedMessages.length > 0 &&
+ SelectedMessagesAreRead() != markingRead;
+}
+
+/**
+ * Marks the selected messages as read or unread
+ *
+ * @param read true if trying to mark messages as read, false if marking unread,
+ * undefined if toggling the read status
+ */
+function MsgMarkMsgAsRead(read)
+{
+ if (read == undefined)
+ read = !gFolderDisplay.selectedMessage.isRead;
+ MarkSelectedMessagesRead(read);
+}
+
+function MsgMarkAsFlagged()
+{
+ MarkSelectedMessagesFlagged(!SelectedMessagesAreFlagged());
+}
+
+function MsgMarkReadByDate()
+{
+ window.openDialog("chrome://messenger/content/markByDate.xul","",
+ "chrome,modal,titlebar,centerscreen",
+ gFolderDisplay.displayedFolder);
+}
+
+function MsgMarkAllRead()
+{
+ let folders = gFolderTreeView.getSelectedFolders();
+ for (let i = 0; i < folders.length; i++)
+ folders[i].markAllMessagesRead(msgWindow);
+}
+
+function MsgFilters(emailAddress, folder)
+{
+ if (!folder)
+ {
+ // Try to determine the folder from the selected message.
+ if (gDBView)
+ {
+ /*
+ * Here we face a decision. If the message has been moved to a
+ * different account, then a single filter cannot work for both
+ * manual and incoming scope. So we will create the filter based
+ * on its existing location, which will make it work properly in
+ * manual scope. This is the best solution for POP3 with global
+ * inbox (as then both manual and incoming filters work correctly),
+ * but may not be what IMAP users who filter to a local folder
+ * really want.
+ */
+ try
+ {
+ folder = gFolderDisplay.selectedMessage.folder;
+ // except for news, we define the filter on the account's root
+ if (!gFolderDisplay.selectedMessageIsNews)
+ folder = folder.rootFolder;
+ }
+ catch (ex) {}
+ }
+ if (!folder)
+ folder = GetFirstSelectedMsgFolder();
+ }
+ var args;
+ if (emailAddress)
+ {
+ // We have to do prefill filter so we are going to launch the
+ // filterEditor dialog and prefill that with the emailAddress.
+ args = { filterList: folder.getEditableFilterList(msgWindow) };
+ args.filterName = emailAddress;
+ window.openDialog("chrome://messenger/content/FilterEditor.xul", "",
+ "chrome, modal, resizable,centerscreen,dialog=yes", args);
+
+ // If the user hits ok in the filterEditor dialog we set args.refresh=true
+ // there we check this here in args to show filterList dialog.
+ if ("refresh" in args && args.refresh)
+ {
+ args = { refresh: true, folder: folder };
+ MsgFilterList(args);
+ }
+ }
+ else // just launch filterList dialog
+ {
+ args = { refresh: false, folder: folder };
+ MsgFilterList(args);
+ }
+}
+
+function MsgApplyFilters()
+{
+ let preselectedFolder = GetFirstSelectedMsgFolder();
+ let selectedFolders = Components.classes["@mozilla.org/array;1"]
+ .createInstance(Components.interfaces.nsIMutableArray);
+ selectedFolders.appendElement(preselectedFolder, false);
+
+ let curFilterList = preselectedFolder.getFilterList(msgWindow);
+ // create a new filter list and copy over the enabled filters to it.
+ // We do this instead of having the filter after the fact code ignore
+ // disabled filters because the Filter Dialog filter after the fact
+ // code would have to clone filters to allow disabled filters to run,
+ // and we don't support cloning filters currently.
+ let tempFilterList = MailServices.filters.getTempFilterList(preselectedFolder);
+ let numFilters = curFilterList.filterCount;
+ // make sure the temp filter list uses the same log stream
+ tempFilterList.logStream = curFilterList.logStream;
+ tempFilterList.loggingEnabled = curFilterList.loggingEnabled;
+ let newFilterIndex = 0;
+ for (let i = 0; i < numFilters; i++)
+ {
+ let curFilter = curFilterList.getFilterAt(i);
+ // only add enabled, UI visibile filters that are in the manual context
+ if (curFilter.enabled && !curFilter.temporary &&
+ (curFilter.filterType & Components.interfaces.nsMsgFilterType.Manual))
+ {
+ tempFilterList.insertFilterAt(newFilterIndex, curFilter);
+ newFilterIndex++;
+ }
+ }
+ MailServices.filters.applyFiltersToFolders(tempFilterList, selectedFolders, msgWindow);
+}
+
+function MsgApplyFiltersToSelection()
+{
+ // bail if we're dealing with a dummy header
+ if (gMessageDisplay.isDummy)
+ return;
+
+ var selectedMessages = gFolderDisplay.selectedMessages;
+ if (selectedMessages.length) {
+ MailServices.filters.applyFilters(Components.interfaces.nsMsgFilterType.Manual,
+ toXPCOMArray(selectedMessages,
+ Components.interfaces.nsIMutableArray),
+ gFolderDisplay.displayedFolder,
+ msgWindow);
+ }
+}
+
+function ChangeMailLayout(newLayout)
+{
+ Services.prefs.setIntPref("mail.pane_config.dynamic", newLayout);
+}
+
+function ChangeMailLayoutForCommand(aCommand)
+{
+ ChangeMailLayout(kMailLayoutCommandMap[aCommand]);
+}
+
+function MsgViewAllHeaders()
+{
+ const mode = Components.interfaces.nsMimeHeaderDisplayTypes.AllHeaders;
+ Services.prefs.setIntPref("mail.show_headers", mode); // 2
+ AdjustHeaderView(mode);
+ ReloadMessage();
+}
+
+function MsgViewNormalHeaders()
+{
+ const mode = Components.interfaces.nsMimeHeaderDisplayTypes.NormalHeaders;
+ Services.prefs.setIntPref("mail.show_headers", mode); // 1
+ AdjustHeaderView(mode);
+ ReloadMessage();
+}
+
+function MsgBodyAllowHTML()
+{
+ Services.prefs.setBoolPref("mailnews.display.prefer_plaintext", false);
+ Services.prefs.setIntPref("mailnews.display.html_as", 0);
+ Services.prefs.setIntPref("mailnews.display.disallow_mime_handlers", 0);
+ ReloadMessage();
+}
+
+function MsgBodySanitized()
+{
+ Services.prefs.setBoolPref("mailnews.display.prefer_plaintext", false);
+ Services.prefs.setIntPref("mailnews.display.html_as", 3);
+ Services.prefs.setIntPref("mailnews.display.disallow_mime_handlers",
+ gDisallow_classes_no_html);
+ ReloadMessage();
+}
+
+function MsgBodyAsPlaintext()
+{
+ Services.prefs.setBoolPref("mailnews.display.prefer_plaintext", true);
+ Services.prefs.setIntPref("mailnews.display.html_as", 1);
+ Services.prefs.setIntPref("mailnews.display.disallow_mime_handlers",
+ gDisallow_classes_no_html);
+ ReloadMessage();
+}
+
+function MsgBodyAllParts()
+{
+ Services.prefs.setBoolPref("mailnews.display.prefer_plaintext", false);
+ Services.prefs.setIntPref("mailnews.display.html_as", 4);
+ Services.prefs.setIntPref("mailnews.display.disallow_mime_handlers", 0);
+ ReloadMessage();
+}
+
+function MsgFeedBodyRenderPrefs(plaintext, html, mime)
+{
+ // Separate render prefs not implemented for feeds, bug 458606.
+ // Services.prefs.setBoolPref("rss.display.prefer_plaintext", plaintext);
+ // Services.prefs.setIntPref("rss.display.html_as", html);
+ // Services.prefs.setIntPref("rss.display.disallow_mime_handlers", mime);
+
+ Services.prefs.setBoolPref("mailnews.display.prefer_plaintext", plaintext);
+ Services.prefs.setIntPref("mailnews.display.html_as", html);
+ Services.prefs.setIntPref("mailnews.display.disallow_mime_handlers", mime);
+ // Reload only if showing rss summary; menuitem hidden if web page..
+ ReloadMessage();
+}
+
+function ToggleInlineAttachment(target)
+{
+ var viewAttachmentInline = !Services.prefs.getBoolPref("mail.inline_attachments");
+ Services.prefs.setBoolPref("mail.inline_attachments", viewAttachmentInline)
+ target.setAttribute("checked", viewAttachmentInline ? "true" : "false");
+ ReloadMessage();
+}
+
+function PrintEnginePrintInternal(doPrintPreview, msgType)
+{
+ var messageList = gFolderDisplay.selectedMessageUris;
+ if (!messageList) {
+ dump("PrintEnginePrintInternal(): No messages selected.\n");
+ return;
+ }
+
+ window.openDialog("chrome://messenger/content/msgPrintEngine.xul", "",
+ "chrome,dialog=no,all,centerscreen",
+ messageList.length, messageList, statusFeedback,
+ doPrintPreview, msgType);
+}
+
+function PrintEnginePrint()
+{
+ return PrintEnginePrintInternal(false,
+ Components.interfaces.nsIMsgPrintEngine.MNAB_PRINT_MSG);
+}
+
+function PrintEnginePrintPreview()
+{
+ return PrintEnginePrintInternal(true,
+ Components.interfaces.nsIMsgPrintEngine.MNAB_PRINTPREVIEW_MSG);
+}
+
+function IsMailFolderSelected()
+{
+ var selectedFolders = GetSelectedMsgFolders();
+ var folder = selectedFolders.length ? selectedFolders[0] : null;
+ return folder && folder.server.type != "nntp";
+}
+
+function IsGetNewMessagesEnabled()
+{
+ let allServers = accountManager.allServers;
+ for (let i = 0; i < allServers.length; ++i) {
+ let server = allServers.queryElementAt(i, Components.interfaces.nsIMsgIncomingServer);
+ if (server.type == "none")
+ continue;
+ return true;
+ }
+ return false;
+}
+
+function IsGetNextNMessagesEnabled()
+{
+ var selectedFolders = GetSelectedMsgFolders();
+ var folder = selectedFolders.length ? selectedFolders[0] : null;
+
+ var menuItem = document.getElementById("menu_getnextnmsg");
+ if (folder && !folder.isServer &&
+ folder.server instanceof Components.interfaces.nsINntpIncomingServer) {
+ menuItem.label = PluralForm.get(folder.server.maxArticles,
+ document.getElementById("bundle_messenger")
+ .getString("getNextNewsMessages"))
+ .replace("#1", folder.server.maxArticles);
+ menuItem.removeAttribute("hidden");
+ return true;
+ }
+
+ menuItem.setAttribute("hidden","true");
+ return false;
+}
+
+function MsgSynchronizeOffline()
+{
+ window.openDialog("chrome://messenger/content/msgSynchronize.xul", "",
+ "centerscreen,chrome,modal,titlebar,resizable=yes",
+ {msgWindow:msgWindow});
+}
+
+function SpaceHit(event)
+{
+ // If focus is in chrome, we want to scroll the content window, unless
+ // the focus is on an important chrome button like the otherActionsButton
+ // popup; if focus is on a non-link content element like a button, bail so we
+ // don't scroll when the element is going to do something else.
+
+ var contentWindow = document.commandDispatcher.focusedWindow;
+ let focusedElement = document.commandDispatcher.focusedElement;
+
+ if (!gMessageDisplay.singleMessageDisplay) {
+ contentWindow = document.getElementById("multimessage").contentWindow;
+ } else if (contentWindow.top == window) {
+ // These elements should always take priority over scrolling.
+ const importantElements = ["otherActionsButton", "attachmentToggle"];
+ contentWindow = window.content;
+ if (focusedElement && importantElements.indexOf(focusedElement.id) != -1)
+ return;
+ }
+ else if (focusedElement && !hRefForClickEvent(event))
+ return;
+
+ if (!contentWindow)
+ return;
+
+ var rssiframe = contentWindow.document.getElementById('_mailrssiframe');
+ // If we are displaying an RSS article, we really want to scroll
+ // the nested iframe.
+ if (contentWindow == window.content && rssiframe)
+ contentWindow = rssiframe.contentWindow;
+
+ if (event && event.shiftKey) {
+ // if at the start of the message, go to the previous one
+ if (contentWindow.scrollY > 0)
+ contentWindow.scrollByPages(-1);
+ else if (Services.prefs.getBoolPref("mail.advance_on_spacebar"))
+ goDoCommand("cmd_previousUnreadMsg");
+ }
+ else {
+ // if at the end of the message, go to the next one
+ if (contentWindow.scrollY < contentWindow.scrollMaxY)
+ contentWindow.scrollByPages(1);
+ else if (Services.prefs.getBoolPref("mail.advance_on_spacebar"))
+ goDoCommand("cmd_nextUnreadMsg");
+ }
+}
+
+function IsAccountOfflineEnabled()
+{
+ var selectedFolders = GetSelectedMsgFolders();
+
+ if (selectedFolders && (selectedFolders.length == 1))
+ return selectedFolders[0].supportsOffline;
+ return false;
+}
+
+function GetDefaultAccountRootFolder()
+{
+ try {
+ var account = accountManager.defaultAccount;
+ var defaultServer = account.incomingServer;
+ var defaultFolder = defaultServer.rootMsgFolder;
+ return defaultFolder;
+ }
+ catch (ex) {
+ }
+ return null;
+}
+
+/**
+ * Check for new messages for all selected folders, or for the default account
+ * in case no folders are selected.
+ */
+function GetFolderMessages()
+{
+ var selectedFolders = GetSelectedMsgFolders();
+ var defaultAccountRootFolder = GetDefaultAccountRootFolder();
+
+ // if no default account, get msg isn't going do anything anyways
+ // so bail out
+ if (!defaultAccountRootFolder)
+ return;
+
+ // if nothing selected, use the default
+ var folders = (selectedFolders.length) ? selectedFolders : [defaultAccountRootFolder];
+ for (var i = 0; i < folders.length; i++) {
+ var serverType = folders[i].server.type;
+ if (folders[i].isServer && (serverType == "nntp")) {
+ // If we're doing "get msgs" on a news server,
+ // update unread counts on this server.
+ folders[i].server.performExpand(msgWindow);
+ }
+ else if (serverType == "none") {
+ // If "Local Folders" is selected and the user does "Get Msgs" and
+ // LocalFolders is not deferred to, get new mail for the default account
+ //
+ // XXX TODO
+ // Should shift click get mail for all (authenticated) accounts?
+ // see bug #125885.
+ if (!folders[i].server.isDeferredTo)
+ GetNewMsgs(defaultAccountRootFolder.server, defaultAccountRootFolder);
+ else
+ GetNewMsgs(folders[i].server, folders[i]);
+ }
+ else {
+ GetNewMsgs(folders[i].server, folders[i]);
+ }
+ }
+}
+
+/**
+ * Gets new messages for the given server, for the given folder.
+ * @param server which nsIMsgIncomingServer to check for new messages
+ * @param folder which nsIMsgFolder folder to check for new messages
+ */
+function GetNewMsgs(server, folder)
+{
+ // Note that for Global Inbox folder.server != server when we want to get
+ // messages for a specific account.
+
+ const nsIMsgFolder = Components.interfaces.nsIMsgFolder;
+ // Whenever we do get new messages, clear the old new messages.
+ folder.biffState = nsIMsgFolder.nsMsgBiffState_NoMail;
+ folder.clearNewMessages();
+ server.getNewMessages(folder, msgWindow, null);
+}
+
+function SendUnsentMessages()
+{
+ let msgSendlater = Components.classes["@mozilla.org/messengercompose/sendlater;1"]
+ .getService(Components.interfaces.nsIMsgSendLater);
+
+ let allIdentities = MailServices.accounts.allIdentities;
+ let identitiesCount = allIdentities.length;
+ for (let i = 0; i < identitiesCount; i++) {
+ let currentIdentity = allIdentities.queryElementAt(i, Components.interfaces.nsIMsgIdentity);
+ let msgFolder = msgSendlater.getUnsentMessagesFolder(currentIdentity);
+ if (msgFolder) {
+ let numMessages = msgFolder.getTotalMessages(false /* include subfolders */);
+ if (numMessages > 0) {
+ msgSendlater.sendUnsentMessages(currentIdentity);
+ // Right now, all identities point to the same unsent messages
+ // folder, so to avoid sending multiple copies of the
+ // unsent messages, we only call messenger.SendUnsentMessages() once.
+ // See bug #89150 for details.
+ break;
+ }
+ }
+ }
+}
+
+function CoalesceGetMsgsForPop3ServersByDestFolder(currentServer,
+ pop3DownloadServersArray,
+ localFoldersToDownloadTo)
+{
+ var outNumFolders = new Object();
+ const kInboxFlag = Components.interfaces.nsMsgFolderFlags.Inbox;
+ var inboxFolder = currentServer.rootMsgFolder.getFolderWithFlags(kInboxFlag);
+ // coalesce the servers that download into the same folder...
+ var index = localFoldersToDownloadTo.indexOf(inboxFolder);
+ if (index == -1)
+ {
+ if (inboxFolder)
+ {
+ inboxFolder.biffState = Components.interfaces.nsIMsgFolder.nsMsgBiffState_NoMail;
+ inboxFolder.clearNewMessages();
+ }
+ localFoldersToDownloadTo.push(inboxFolder);
+ index = pop3DownloadServersArray.length;
+ pop3DownloadServersArray.push([]);
+ }
+ pop3DownloadServersArray[index].push(currentServer);
+}
+
+function GetMessagesForAllAuthenticatedAccounts()
+{
+ // now log into any server
+ try
+ {
+ var allServers = accountManager.allServers;
+ // array of isupportsarrays of servers for a particular folder
+ var pop3DownloadServersArray = [];
+ // parallel array of folders to download to...
+ var localFoldersToDownloadTo = [];
+ var pop3Server;
+
+ for (var i = 0; i < allServers.length; ++i)
+ {
+ var currentServer = allServers.queryElementAt(i, Components.interfaces.nsIMsgIncomingServer);
+ if (currentServer.protocolInfo.canGetMessages &&
+ !currentServer.passwordPromptRequired)
+ {
+ if (currentServer.type == "pop3")
+ {
+ CoalesceGetMsgsForPop3ServersByDestFolder(currentServer,
+ pop3DownloadServersArray, localFoldersToDownloadTo);
+ pop3Server = currentServer.QueryInterface(Components.interfaces.nsIPop3IncomingServer);
+ }
+ else
+ // get new messages on the server for imap or rss
+ GetMessagesForInboxOnServer(currentServer);
+ }
+ }
+ for (var i = 0; i < pop3DownloadServersArray.length; ++i)
+ {
+ // any ol' pop3Server will do - the serversArray specifies which servers to download from
+ pop3Server.downloadMailFromServers(pop3DownloadServersArray[i],
+ pop3DownloadServersArray[i].length,
+ msgWindow,
+ localFoldersToDownloadTo[i],
+ null);
+ }
+ }
+ catch(ex)
+ {
+ dump(ex + "\n");
+ }
+}
+
+function CommandUpdate_UndoRedo()
+{
+ EnableMenuItem("menu_undo", SetupUndoRedoCommand("cmd_undo"));
+ EnableMenuItem("menu_redo", SetupUndoRedoCommand("cmd_redo"));
+}
+
+function SetupUndoRedoCommand(command)
+{
+ // If we have selected a server, and are viewing account central
+ // there is no loaded folder.
+ var loadedFolder = gFolderDisplay.displayedFolder;
+ if (!loadedFolder || !loadedFolder.server.canUndoDeleteOnServer)
+ return false;
+
+ var canUndoOrRedo;
+ var txnType;
+ if (command == "cmd_undo")
+ {
+ canUndoOrRedo = messenger.canUndo();
+ txnType = messenger.getUndoTransactionType();
+ }
+ else
+ {
+ canUndoOrRedo = messenger.canRedo();
+ txnType = messenger.getRedoTransactionType();
+ }
+
+ if (canUndoOrRedo)
+ {
+ var commands =
+ ['valueDefault', 'valueDeleteMsg', 'valueMoveMsg', 'valueCopyMsg', 'valueUnmarkAllMsgs'];
+ goSetMenuValue(command, commands[txnType]);
+ }
+ else
+ {
+ goSetMenuValue(command, 'valueDefault');
+ }
+ return canUndoOrRedo;
+}
+
+/**
+ * Triggered by the global JunkStatusChanged notification, we handle updating
+ * the message display if our displayed message might have had its junk status
+ * change. This primarily entails updating the notification bar (that thing
+ * that appears above the message and says "this message might be junk") and
+ * (potentially) reloading the message because junk status affects the form of
+ * HTML display used (sanitized vs not).
+ * When our tab implementation is no longer multiplexed (reusing the same
+ * display widget), this must be moved into the MessageDisplayWidget or
+ * otherwise be scoped to the tab.
+ */
+function HandleJunkStatusChanged(folder)
+{
+ // We have nothing to do (and should bail) if:
+ // - There is no currently displayed message.
+ // - The displayed message is an .eml file from disk or an attachment.
+ // - The folder that has had a junk change is not backing the display folder.
+
+ // This might be the stand alone window, open to a message that was
+ // and attachment (or on disk), in which case, we want to ignore it.
+ if (!gMessageDisplay.displayedMessage ||
+ gMessageDisplay.isDummy ||
+ gFolderDisplay.displayedFolder != folder)
+ return;
+
+ // If multiple message are selected and we change the junk status
+ // we don't want to show the junk bar (since the message pane is blank).
+ var msgHdr = null;
+ if (GetNumSelectedMessages() == 1)
+ msgHdr = gMessageDisplay.displayedMessage;
+ var junkBarWasDisplayed = gMessageNotificationBar.isFlagSet(kMsgNotificationJunkBar);
+ gMessageNotificationBar.setJunkMsg(msgHdr);
+
+ // Only reload message if junk bar display state has changed.
+ if (msgHdr && junkBarWasDisplayed != gMessageNotificationBar.isFlagSet(kMsgNotificationJunkBar))
+ {
+ // We may be forcing junk mail to be rendered with sanitized html.
+ // In that scenario, we want to reload the message if the status has just
+ // changed to not junk.
+ var sanitizeJunkMail = Services.prefs.getBoolPref("mail.spam.display.sanitize");
+
+ // Only bother doing this if we are modifying the html for junk mail....
+ if (sanitizeJunkMail)
+ {
+ let junkScore = msgHdr.getStringProperty("junkscore");
+ let isJunk = (junkScore == Components.interfaces.nsIJunkMailPlugin.IS_SPAM_SCORE);
+
+ // If the current row isn't going to change, reload to show sanitized or
+ // unsanitized. Otherwise we wouldn't see the reloaded version anyway.
+
+ // 1) When marking as non-junk, the msg would move back to the inbox.
+ // 2) When marking as junk, the msg will move or delete, if manualMark is set.
+ // 3) Marking as junk in the junk folder just changes the junk status.
+ if ((!isJunk && folder.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Inbox)) ||
+ (isJunk && !folder.server.spamSettings.manualMark) ||
+ (isJunk && folder.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Junk)))
+ ReloadMessage();
+ }
+ }
+}
+
+var gMessageNotificationBar =
+{
+ mBarStatus: 0,
+ // flag bit values for mBarStatus, indexed by kMsgNotificationXXX
+ mBarFlagValues: [
+ 0, // for no msgNotificationBar
+ 1, // 1 << (kMsgNotificationPhishingBar - 1)
+ 2, // 1 << (kMsgNotificationJunkBar - 1)
+ 4, // 1 << (kMsgNotificationRemoteImages - 1)
+ 8, // 1 << (kMsgNotificationMDN - 1)
+ 16, // 1 << (kMsgNotificationSMIMEReceiptRequest - 1)
+ 32, // 1 << (kMsgNotificationSMIMEReceiptVerified - 1)
+ 64 // 1 << (kMsgNotificationSMIMEReceiptNotVerified - 1)
+ ],
+
+ get mMsgNotificationBar() {
+ delete this.mMsgNotificationBar;
+ return this.mMsgNotificationBar = document.getElementById('msgNotificationBar');
+ },
+
+ setJunkMsg: function(aMsgHdr)
+ {
+ var isJunk = false;
+
+ if (aMsgHdr)
+ {
+ var junkScore = aMsgHdr.getStringProperty("junkscore");
+ isJunk = ((junkScore != "") && (junkScore != "0"));
+ }
+
+ this.updateMsgNotificationBar(kMsgNotificationJunkBar, isJunk);
+
+ goUpdateCommand('button_junk');
+ },
+
+ setRemoteContentMsg: function(aMsgHdr)
+ {
+ // update the allow remote content for sender string
+ let emailAddress = MailServices.headerParser.extractHeaderAddressMailboxes(aMsgHdr.author);
+ var desc = document.getElementById("bundle_messenger")
+ .getFormattedString("alwaysLoadRemoteContentForSender2",
+ [emailAddress ? emailAddress : aMsgHdr.author]);
+ var authorDesc = document.getElementById("allowRemoteContentForAuthorDesc");
+ authorDesc.value = desc;
+ authorDesc.setAttribute("tooltiptext", desc);
+ this.updateMsgNotificationBar(kMsgNotificationRemoteImages, true);
+ },
+
+ setPhishingMsg: function()
+ {
+ this.updateMsgNotificationBar(kMsgNotificationPhishingBar, true);
+ },
+
+ setMDNMsg: function(aMdnGenerator, aMsgHeader, aMimeHdr)
+ {
+ this.mdnGenerator = aMdnGenerator;
+ // Return receipts can be RFC 3798 or not.
+ let mdnHdr = aMimeHdr.extractHeader("Disposition-Notification-To", false) ||
+ aMimeHdr.extractHeader("Return-Receipt-To", false); // not
+ let fromHdr = aMimeHdr.extractHeader("From", false);
+
+ let mdnAddr = MailServices.headerParser.extractHeaderAddressMailboxes(mdnHdr);
+ let fromAddr = MailServices.headerParser.extractHeaderAddressMailboxes(fromHdr);
+
+ let authorName = MailServices.headerParser.extractHeaderAddressName(
+ aMsgHeader.mime2DecodedAuthor) || aMsgHeader.author;
+
+ let mdnBarMsg = document.getElementById("mdnBarMessage");
+ if (mdnBarMsg.firstChild) // might have to remove old text first
+ mdnBarMsg.removeChild(mdnBarMsg.firstChild);
+
+ var bundle = document.getElementById("bundle_messenger");
+ var barMsg;
+ // If the return receipt doesn't go to the sender address, note that in the
+ // notification.
+ if (mdnAddr != fromAddr)
+ barMsg = bundle.getFormattedString("mdnBarMessageAddressDiffers",
+ [authorName, mdnAddr]);
+ else
+ barMsg = bundle.getFormattedString("mdnBarMessageNormal", [authorName]);
+ mdnBarMsg.appendChild(document.createTextNode(barMsg));
+ this.updateMsgNotificationBar(kMsgNotificationMDN, true);
+ },
+
+ setSMIMEReceiptRequestMsg: function(aSMIMEReceiptGenerator, recipient)
+ {
+ document.getElementById('SMIMEReceiptRequestBarRecipient').value = "(" + recipient + ")";
+ this.SMIMEReceiptGenerator = aSMIMEReceiptGenerator;
+ this.updateMsgNotificationBar(kMsgNotificationSMIMEReceiptRequest, true);
+ },
+
+ setSMIMEReceiptMsg: function(aRequestMsgHdr)
+ {
+ this.SMIMEReceiptRequestMsgHdr = aRequestMsgHdr;
+ if (aRequestMsgHdr)
+ this.updateMsgNotificationBar(kMsgNotificationSMIMEReceiptVerified, true);
+ else
+ this.updateMsgNotificationBar(kMsgNotificationSMIMEReceiptNotVerified, true);
+ },
+ clearMsgNotifications: function()
+ {
+ this.mBarStatus = 0;
+ this.mMsgNotificationBar.selectedIndex = 0;
+ this.mMsgNotificationBar.collapsed = true;
+ },
+
+ updateMsgNotificationBar: function(aIndex, aSet)
+ {
+ var chunk = this.mBarFlagValues[aIndex];
+ var status = aSet ? this.mBarStatus | chunk : this.mBarStatus & ~chunk;
+ this.mBarStatus = status;
+
+ // the phishing message takes precedence over the junk message
+ // which takes precedence over the remote content message
+ this.mMsgNotificationBar.selectedIndex = this.mBarFlagValues.indexOf(status & -status);
+ this.mMsgNotificationBar.collapsed = !status;
+ },
+
+ /**
+ * @param aFlag one of the |mBarFlagValues| values
+ * @return true if aFlag is currently set for the loaded message
+ */
+ isFlagSet: function(aFlag)
+ {
+ var chunk = this.mBarFlagValues[aFlag];
+ return this.mBarStatus & chunk;
+ }
+};
+
+/**
+ * LoadMsgWithRemoteContent
+ * Reload the current message, allowing remote content
+ */
+function LoadMsgWithRemoteContent()
+{
+ // we want to get the msg hdr for the currently selected message
+ // change the "remoteContentBar" property on it
+ // then reload the message
+
+ setMsgHdrPropertyAndReload("remoteContentPolicy", kAllowRemoteContent);
+ window.content.focus();
+}
+
+/**
+ * Reloads the message after adjusting the remote content policy for the sender.
+ * Iterate through the local address books looking for a card with the same e-mail address as the
+ * sender of the current loaded message. If we find a card, update the allow remote content field.
+ * If we can't find a card, prompt the user with a new AB card dialog, pre-selecting the remote content field.
+ */
+function allowRemoteContentForSender()
+{
+ // get the sender of the msg hdr
+ var msgHdr = gMessageDisplay.displayedMessage;
+ if (!msgHdr)
+ return;
+
+ var names = {};
+ var addresses = {};
+ var fullNames = {};
+ var numAddresses;
+
+ numAddresses = MailServices.headerParser.parseHeadersWithArray(msgHdr.author, addresses, names, fullNames);
+ var authorEmailAddress = addresses.value[0];
+ if (!authorEmailAddress)
+ return;
+
+ // search through all of our local address books looking for a match.
+ let enumerator = MailServices.ab.directories;
+ var cardForEmailAddress;
+ var addrbook;
+ while (!cardForEmailAddress && enumerator.hasMoreElements())
+ {
+ addrbook = enumerator.getNext()
+ .QueryInterface(Components.interfaces.nsIAbDirectory);
+ // Try/catch because some cardForEmailAddress functions may not be
+ // implemented.
+ try {
+ // If its a read-only book, don't find a card as we won't be able
+ // to modify the card.
+ if (!addrbook.readOnly)
+ cardForEmailAddress = addrbook.cardForEmailAddress(authorEmailAddress);
+ } catch (e) {}
+ }
+
+ var allowRemoteContent = false;
+ if (cardForEmailAddress)
+ {
+ // set the property for remote content
+ cardForEmailAddress.setProperty("AllowRemoteContent", true);
+ addrbook.modifyCard(cardForEmailAddress);
+ allowRemoteContent = true;
+ }
+ else
+ {
+ var args = {primaryEmail:authorEmailAddress, displayName:names.value[0],
+ allowRemoteContent:true};
+ // create a new card and set the property
+ window.openDialog("chrome://messenger/content/addressbook/abNewCardDialog.xul",
+ "", "chrome,resizable=no,titlebar,modal,centerscreen", args);
+ allowRemoteContent = args.allowRemoteContent;
+ }
+
+ // Reload the message if we've updated the remote content policy for the sender.
+ if (allowRemoteContent)
+ ReloadMessage();
+}
+
+/**
+ * Set the msg hdr flag to ignore the phishing warning and reload the message.
+ */
+function IgnorePhishingWarning()
+{
+ // This property should really be called skipPhishingWarning or something
+ // like that, but it's too late to change that now.
+ // This property is used to supress the phishing bar for the message.
+ setMsgHdrPropertyAndReload("notAPhishMessage", 1);
+}
+
+/**
+ * Allow disabling the scam feature for all messages until lists are in place.
+ */
+function DisablePhishingWarning()
+{
+ Application.prefs.setValue("mail.phishing.detection.enabled", false);
+ ReloadMessage();
+}
+
+function setMsgHdrPropertyAndReload(aProperty, aValue)
+{
+ // we want to get the msg hdr for the currently selected message
+ // change the appropiate property on it then reload the message
+ var msgHdr = gMessageDisplay.displayedMessage;
+ if (msgHdr)
+ {
+ msgHdr.setUint32Property(aProperty, aValue);
+ ReloadMessage();
+ }
+}
+
+/**
+ * Mark a specified message as read.
+ * @param msgHdr header (nsIMsgDBHdr) of the message to mark as read
+ */
+function MarkMessageAsRead(msgHdr)
+{
+ ClearPendingReadTimer();
+ var headers = Components.classes["@mozilla.org/array;1"]
+ .createInstance(Components.interfaces.nsIMutableArray);
+ headers.appendElement(msgHdr, false);
+ msgHdr.folder.markMessagesRead(headers, true);
+}
+
+function ClearPendingReadTimer()
+{
+ if (gMarkViewedMessageAsReadTimer)
+ {
+ clearTimeout(gMarkViewedMessageAsReadTimer);
+ gMarkViewedMessageAsReadTimer = null;
+ }
+}
+
+// this is called when layout is actually finished rendering a
+// mail message. OnMsgLoaded is called when libmime is done parsing the message
+function OnMsgParsed(aUrl)
+{
+ // browser doesn't do this, but I thought it could be a useful thing to test out...
+ // If the find bar is visible and we just loaded a new message, re-run
+ // the find command. This means the new message will get highlighted and
+ // we'll scroll to the first word in the message that matches the find text.
+ var findBar = document.getElementById("FindToolbar");
+ if (!findBar.hidden)
+ findBar.onFindAgainCommand(false);
+
+ // Run the phishing detector on the message if it hasn't been marked as not
+ // a scam already.
+ var msgHdr = gMessageDisplay.displayedMessage;
+ if (msgHdr && !msgHdr.getUint32Property("notAPhishMessage"))
+ gPhishingDetector.analyzeMsgForPhishingURLs(aUrl);
+
+ // notify anyone (e.g., extensions) who's interested in when a message is loaded.
+ let selectedMessageUris = gFolderDisplay.selectedMessageUris;
+ let msgURI = selectedMessageUris ? selectedMessageUris[0] : null;
+ Services.obs.notifyObservers(msgWindow.msgHeaderSink, "MsgMsgDisplayed", msgURI);
+
+ // scale any overflowing images
+ let doc = document.getElementById("messagepane").contentDocument;
+ let imgs = doc.images;
+ for (let i = 0; i < imgs.length; i++)
+ {
+ let img = imgs[i];
+ if (img.className == "moz-attached-image" && img.naturalWidth > doc.body.clientWidth)
+ {
+ if (img.hasAttribute("shrinktofit"))
+ img.setAttribute("isshrunk", "true");
+ else
+ img.setAttribute("overflowing", "true");
+ }
+ }
+}
+
+function OnMsgLoaded(aUrl)
+{
+ if (!aUrl || gMessageDisplay.isDummy)
+ return;
+
+ var msgHdr = gMessageDisplay.displayedMessage;
+
+ var wintype = document.documentElement.getAttribute('windowtype');
+
+ gMessageNotificationBar.setJunkMsg(msgHdr);
+
+ goUpdateCommand('button_delete');
+
+ var markReadAutoMode = Services.prefs.getBoolPref("mailnews.mark_message_read.auto");
+
+ // We just finished loading a message. If messages are to be marked as read
+ // automatically, set a timer to mark the message is read after n seconds
+ // where n can be configured by the user.
+ if (msgHdr && !msgHdr.isRead && markReadAutoMode)
+ {
+ let markReadOnADelay = Services.prefs.getBoolPref("mailnews.mark_message_read.delay");
+
+ // Only use the timer if viewing using the 3-pane preview pane and the
+ // user has set the pref.
+ if (markReadOnADelay && wintype == "mail:3pane") // 3-pane window
+ {
+ ClearPendingReadTimer();
+ let markReadDelayTime = Services.prefs.getIntPref("mailnews.mark_message_read.delay.interval");
+ if (markReadDelayTime == 0)
+ MarkMessageAsRead(msgHdr);
+ else
+ gMarkViewedMessageAsReadTimer = setTimeout(MarkMessageAsRead,
+ markReadDelayTime * 1000,
+ msgHdr);
+ }
+ else // standalone msg window
+ {
+ MarkMessageAsRead(msgHdr);
+ }
+ }
+
+ // See if MDN was requested but has not been sent.
+ HandleMDNResponse(aUrl);
+}
+
+/**
+ * This function handles all mdn response generation (ie, imap and pop).
+ * For pop the msg uid can be 0 (ie, 1st msg in a local folder) so no
+ * need to check uid here. No one seems to set mimeHeaders to null so
+ * no need to check it either.
+ */
+function HandleMDNResponse(aUrl)
+{
+ if (!aUrl)
+ return;
+
+ var msgFolder = aUrl.folder;
+ var msgHdr = gFolderDisplay.selectedMessage;
+ if (!msgFolder || !msgHdr || gFolderDisplay.selectedMessageIsNews)
+ return;
+
+ // if the message is marked as junk, do NOT attempt to process a return receipt
+ // in order to better protect the user
+ if (SelectedMessagesAreJunk())
+ return;
+
+ var mimeHdr;
+
+ try {
+ mimeHdr = aUrl.mimeHeaders;
+ } catch (ex) {
+ return;
+ }
+
+ // If we didn't get the message id when we downloaded the message header,
+ // we cons up an md5: message id. If we've done that, we'll try to extract
+ // the message id out of the mime headers for the whole message.
+ var msgId = msgHdr.messageId;
+ if (msgId.startsWith("md5:"))
+ {
+ var mimeMsgId = mimeHdr.extractHeader("Message-Id", false);
+ if (mimeMsgId)
+ msgHdr.messageId = mimeMsgId;
+ }
+
+ // After a msg is downloaded it's already marked READ at this point so we must check if
+ // the msg has a "Disposition-Notification-To" header and no MDN report has been sent yet.
+ if (msgHdr.flags & Components.interfaces.nsMsgMessageFlags.MDNReportSent)
+ return;
+
+ var DNTHeader = mimeHdr.extractHeader("Disposition-Notification-To", false);
+ var oldDNTHeader = mimeHdr.extractHeader("Return-Receipt-To", false);
+ if (!DNTHeader && !oldDNTHeader)
+ return;
+
+ // Everything looks good so far, let's generate the MDN response.
+ var mdnGenerator = Components.classes["@mozilla.org/messenger-mdn/generator;1"]
+ .createInstance(Components.interfaces.nsIMsgMdnGenerator);
+ const MDN_DISPOSE_TYPE_DISPLAYED = 0;
+ let askUser = mdnGenerator.process(MDN_DISPOSE_TYPE_DISPLAYED, msgWindow, msgFolder,
+ msgHdr.messageKey, mimeHdr, false);
+ if (askUser)
+ gMessageNotificationBar.setMDNMsg(mdnGenerator, msgHdr, mimeHdr);
+}
+
+function SendMDNResponse()
+{
+ gMessageNotificationBar.mdnGenerator.userAgreed();
+ gMessageNotificationBar.updateMsgNotificationBar(kMsgNotificationMDN, false);
+}
+
+function IgnoreMDNResponse()
+{
+ gMessageNotificationBar.mdnGenerator.userDeclined();
+ gMessageNotificationBar.updateMsgNotificationBar(kMsgNotificationMDN, false);
+}
+
+function SendSMIMEReceipt()
+{
+ gMessageNotificationBar.SMIMEReceiptGenerator.userAgreed();
+ gMessageNotificationBar.updateMsgNotificationBar(kMsgNotificationSMIMEReceiptRequest, false);
+}
+
+function IgnoreSMIMEReceipt()
+{
+ gMessageNotificationBar.SMIMEReceiptGenerator.userDeclined();
+ gMessageNotificationBar.updateMsgNotificationBar(kMsgNotificationSMIMEReceiptRequest, false);
+}
+
+function OpenSMIMEReceiptRequestMessage()
+{
+ MailUtils.displayMessage(gMessageNotificationBar.SMIMEReceiptRequestMsgHdr, null, document.getElementById("tabmail"));
+}
+
+function QuickSearchFocus()
+{
+ let tabmail = document.getElementById('tabmail');
+
+ // If we're currently viewing a Gloda tab, drill down to find the
+ // built-in search input, and select that.
+ if (tabmail
+ && tabmail.currentTabInfo.mode.name == "glodaFacet") {
+ let searchInput = tabmail.currentTabInfo
+ .panel
+ .querySelector(".remote-gloda-search");
+ if (searchInput)
+ searchInput.select();
+
+ return;
+ }
+
+ if (tabmail && tabmail.currentTabInfo.mode.name == "chat") {
+ let searchInput = document.getElementById("IMSearchInput");
+ if (searchInput)
+ searchInput.select();
+ return;
+ }
+
+ var quickSearchTextBox = document.getElementById('searchInput');
+ if (quickSearchTextBox)
+ quickSearchTextBox.select();
+}
+
+/**
+ * Opens a search window with the given folder, or the displayed one if none is
+ * chosen.
+ *
+ * @param [aFolder] the folder to open the search window for, if different from
+ * the displayed one
+ */
+function MsgSearchMessages(aFolder)
+{
+ // We always open a new search dialog for each search command
+ window.openDialog("chrome://messenger/content/SearchDialog.xul", "_blank",
+ "chrome,resizable,status,centerscreen,dialog=no",
+ { folder: aFolder || gFolderDisplay.displayedFolder });
+}
+
+function MsgJunkMailInfo(aCheckFirstUse)
+{
+ if (aCheckFirstUse) {
+ if (!Services.prefs.getBoolPref("mailnews.ui.junk.firstuse"))
+ return;
+ Services.prefs.setBoolPref("mailnews.ui.junk.firstuse", false);
+
+ // check to see if this is an existing profile where the user has started using
+ // the junk mail feature already
+ if (MailServices.junk.userHasClassified)
+ return;
+ }
+
+ var desiredWindow = Services.wm.getMostRecentWindow("mailnews:junkmailinfo");
+
+ if (desiredWindow)
+ desiredWindow.focus();
+ else
+ window.openDialog("chrome://messenger/content/junkMailInfo.xul",
+ "mailnews:junkmailinfo",
+ "centerscreen,resizeable=no,titlebar,chrome,modal", null);
+}
+
+function MsgSearchAddresses()
+{
+ var args = { directory: null };
+ OpenOrFocusWindow(args, "mailnews:absearch", "chrome://messenger/content/ABSearchDialog.xul");
+}
+
+function MsgFilterList(args)
+{
+ OpenOrFocusWindow(args, "mailnews:filterlist", "chrome://messenger/content/FilterListDialog.xul");
+}
+
+function OpenOrFocusWindow(args, windowType, chromeURL)
+{
+ var desiredWindow = Services.wm.getMostRecentWindow(windowType);
+
+ if (desiredWindow) {
+ desiredWindow.focus();
+ if ("refresh" in args && args.refresh)
+ desiredWindow.refresh();
+ }
+ else
+ window.openDialog(chromeURL, "", "chrome,resizable,status,centerscreen,dialog=no", args);
+}
+
+// This global is for SeaMonkey compatibility in newsblogOverlay.js.
+let gShowFeedSummary = true;
+
+let FeedMessageHandler = {
+ gShowSummary: true,
+ gToggle: false,
+ kSelectOverrideWebPage: 0,
+ kSelectOverrideSummary: 1,
+ kSelectFeedDefault: 2,
+ kOpenWebPage: 0,
+ kOpenSummary: 1,
+ kOpenToggleInMessagePane: 2,
+ kOpenLoadInBrowser: 3,
+
+ /**
+ * How to load message on threadpane select.
+ */
+ get onSelectPref() {
+ return Services.prefs.getIntPref("rss.show.summary");
+ },
+
+ set onSelectPref(val) {
+ Services.prefs.setIntPref("rss.show.summary", val);
+ ReloadMessage();
+ },
+
+ /**
+ * Load web page on threadpane select.
+ */
+ get loadWebPageOnSelectPref() {
+ return Services.prefs.getIntPref("rss.message.loadWebPageOnSelect") ? true : false;
+ },
+
+ /**
+ * How to load message on open (enter/dbl click in threadpane, contextmenu).
+ */
+ get onOpenPref() {
+ return Services.prefs.getIntPref("rss.show.content-base");
+ },
+
+ set onOpenPref(val) {
+ Services.prefs.setIntPref("rss.show.content-base", val);
+ },
+
+ /**
+ * Determine if a message is a feed message. Prior to Tb15, a message had to
+ * be in an rss acount type folder. In Tb15 and later, a flag is set on the
+ * message itself upon initial store; the message can be moved to any folder.
+ *
+ * @param nsIMsgDBHdr aMsgHdr - the message.
+ *
+ * @return true if message is a feed, false if not.
+ */
+ isFeedMessage: function (aMsgHdr) {
+ return (aMsgHdr instanceof Components.interfaces.nsIMsgDBHdr) &&
+ ((aMsgHdr.flags & Components.interfaces.nsMsgMessageFlags.FeedMsg) ||
+ (aMsgHdr.folder && aMsgHdr.folder.server.type == "rss"));
+ },
+
+ /**
+ * Determine whether to show a feed message summary or load a web page in the
+ * message pane.
+ *
+ * @param nsIMsgDBHdr aMsgHdr - the message.
+ * @param bool aToggle - true if in toggle mode, false otherwise.
+ *
+ * @return true if summary is to be displayed, false if web page.
+ */
+ shouldShowSummary: function (aMsgHdr, aToggle) {
+ // Not a feed message, always show summary (the message).
+ if (!this.isFeedMessage(aMsgHdr))
+ return true;
+
+ // Notified of a summary reload when toggling, reset toggle and return.
+ if (!aToggle && this.gToggle)
+ return !(this.gToggle = false);
+
+ let showSummary = true;
+ this.gToggle = aToggle;
+
+ // Thunderbird 2 rss messages with 'Show article summary' not selected,
+ // ie message body constructed to show web page in an iframe, can't show
+ // a summary - notify user.
+ let contentDoc = getBrowser().contentDocument;
+ let rssIframe = contentDoc.getElementById("_mailrssiframe");
+ if (rssIframe) {
+ if (this.gToggle || this.onSelectPref == this.kSelectOverrideSummary)
+ this.gToggle = false;
+ return false;
+ }
+
+ if (aToggle)
+ // Toggle mode, flip value.
+ return gShowFeedSummary = this.gShowSummary = !this.gShowSummary;
+
+ let wintype = document.documentElement.getAttribute("windowtype");
+ let tabMail = document.getElementById("tabmail");
+ let messageTab = tabMail && tabMail.currentTabInfo.mode.type == "message";
+ let messageWindow = wintype == "mail:messageWindow";
+
+ switch (this.onSelectPref) {
+ case this.kSelectOverrideWebPage:
+ showSummary = false;
+ break;
+ case this.kSelectOverrideSummary:
+ showSummary = true
+ break;
+ case this.kSelectFeedDefault:
+ // Get quickmode per feed folder pref from feeds.rdf. If the feed
+ // message is not in a feed account folder (hence the folder is not in
+ // the feeds database), or FZ_QUICKMODE property is not found (possible
+ // in pre renovation urls), err on the side of showing the summary.
+ // For the former, toggle or global override is necessary; for the
+ // latter, a show summary checkbox toggle in Subscribe dialog will set
+ // one on the path to bliss.
+ let folder = aMsgHdr.folder, targetRes;
+ try {
+ targetRes = FeedUtils.getParentTargetForChildResource(
+ folder.URI, FeedUtils.FZ_QUICKMODE, folder.server);
+ }
+ catch (ex) {
+ // Not in a feed account folder or other error.
+ FeedUtils.log.info("FeedMessageHandler.shouldShowSummary: could not " +
+ "get summary pref for this folder");
+ }
+
+ showSummary = targetRes && targetRes.QueryInterface(Ci.nsIRDFLiteral).
+ Value == "false" ? false : true;
+ break;
+ }
+
+ gShowFeedSummary = this.gShowSummary = showSummary;
+
+ if (messageWindow || messageTab) {
+ // Message opened in either standalone window or tab, due to either
+ // message open pref (we are here only if the pref is 0 or 1) or
+ // contextmenu open.
+ switch (this.onOpenPref) {
+ case this.kOpenToggleInMessagePane:
+ // Opened by contextmenu, use the value derived above.
+ // XXX: allow a toggle via crtl?
+ break;
+ case this.kOpenWebPage:
+ showSummary = false;
+ break;
+ case this.kOpenSummary:
+ showSummary = true;
+ break;
+ }
+ }
+
+ // Auto load web page in browser on select, per pref; shouldShowSummary() is
+ // always called first to 1)test if feed, 2)get summary pref, so do it here.
+ if (this.loadWebPageOnSelectPref)
+ setTimeout(FeedMessageHandler.loadWebPage, 20, aMsgHdr, {browser:true});
+
+ return showSummary;
+ },
+
+ /**
+ * Load a web page for feed messages. Use MsgHdrToMimeMessage() to get
+ * the content-base url from the message headers. We cannot rely on
+ * currentHeaderData; it has not yet been streamed at our entry point in
+ * displayMessageChanged(), and in the case of a collapsed message pane it
+ * is not streamed.
+ *
+ * @param nsIMsgDBHdr aMessageHdr - the message.
+ * @param {obj} aWhere - name value=true pair, where name is in:
+ * 'messagepane', 'browser', 'tab', 'window'.
+ */
+ loadWebPage: function (aMessageHdr, aWhere) {
+ MsgHdrToMimeMessage(aMessageHdr, null, function(aMsgHdr, aMimeMsg) {
+ if (aMimeMsg && aMimeMsg.headers["content-base"] &&
+ aMimeMsg.headers["content-base"][0]) {
+ let url = aMimeMsg.headers["content-base"], uri;
+ try {
+ uri = Services.io.newURI(url, null, null);
+ url = uri.spec;
+ }
+ catch (ex) {
+ FeedUtils.log.info("FeedMessageHandler.loadWebPage: " +
+ "invalid Content-Base header url - " + url);
+ return;
+ }
+ if (aWhere.browser)
+ Components.classes["@mozilla.org/uriloader/external-protocol-service;1"]
+ .getService(Components.interfaces.nsIExternalProtocolService)
+ .loadURI(uri);
+ else if (aWhere.messagepane) {
+ let loadFlag = getBrowser().webNavigation.LOAD_FLAGS_NONE;
+ getBrowser().webNavigation.loadURI(url, loadFlag, null, null, null);
+ }
+ else if (aWhere.tab)
+ openContentTab(url, "tab", "^");
+ else if (aWhere.window)
+ openContentTab(url, "window", "^");
+ }
+ else
+ FeedUtils.log.info("FeedMessageHandler.loadWebPage: could not get " +
+ "Content-Base header url for this message");
+ });
+ },
+
+ /**
+ * Display summary or load web page for feed messages. Caller should already
+ * know if the message is a feed message.
+ *
+ * @param nsIMsgDBHdr aMsgHdr - the message.
+ * @param bool aShowSummary - true if summary is to be displayed, false if
+ * web page.
+ */
+ setContent: function (aMsgHdr, aShowSummary) {
+ if (aShowSummary) {
+ // Only here if toggling to summary in 3pane.
+ if (this.gToggle && gDBView && GetNumSelectedMessages() == 1)
+ ReloadMessage();
+ }
+ else {
+ let browser = getBrowser();
+ if (browser && browser.contentDocument && browser.contentDocument.body)
+ browser.contentDocument.body.hidden = true;
+ // If in a non rss folder, hide possible remote content bar on a web
+ // page load, as it doesn't apply.
+ gMessageNotificationBar.clearMsgNotifications();
+
+ this.loadWebPage(aMsgHdr, {messagepane:true});
+ this.gToggle = false;
+ }
+ }
+}
+
+function initAppMenuPopup(aMenuPopup, aEvent)
+{
+ file_init();
+ view_init();
+ InitGoMessagesMenu();
+ menu_new_init();
+ CommandUpdate_UndoRedo();
+ InitAppFolderViewsMenu();
+ document.commandDispatcher.updateCommands('create-menu-tasks');
+
+ // If the onpopupshowing event's target is on one of the splitmenu
+ // menuitem popups, stash that popup in aMenuPopup (the menupopup one
+ // level up) so that splitmenu knows which popup to close when it opens
+ // up it's popupmenu.
+ if (aEvent.target.parentNode.parentNode.parentNode.parentNode == aMenuPopup)
+ aMenuPopup._currentPopup = aEvent.target;
+}
--- /dev/null
+<?xml version="1.0"?>
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifdef XP_UNIX
+#ifndef XP_MACOSX
+#define XP_GNOME 1
+#endif
+#endif
+
+<?xml-stylesheet href="chrome://messenger/skin/folderMenus.css" type="text/css"?>
+
+<!-- Overlaying utilityOverlay.xul here is a temporary band-aid for a
+ hard-to-reproduce problem where File, Edit, and View menus disappear on
+ Mac when certain add-ons are installed (bug 398702). Work to find a
+ better fix is ongoing. Ultimately, utilityOverlay.xul wants to
+ disappear from Thunderbird entirely (bug 359748). -->
+<?xul-overlay href="chrome://communicator/content/utilityOverlay.xul"?>
+
+<?xul-overlay href="chrome://global/content/charsetOverlay.xul"?>
+#ifdef XP_MACOSX
+<?xul-overlay href="chrome://messenger/content/macMenuOverlay.xul"?>
+#endif
+<?xul-overlay href="chrome://messenger/content/baseMenuOverlay.xul"?>
+
+<!DOCTYPE overlay [
+ <!ENTITY % messengerDTD SYSTEM "chrome://messenger/locale/messenger.dtd">
+ %messengerDTD;
+ <!ENTITY % msgViewPickerDTD SYSTEM "chrome://messenger/locale/msgViewPickerOverlay.dtd" >
+ %msgViewPickerDTD;
+ <!ENTITY % brandDTD SYSTEM "chrome://branding/locale/brand.dtd">
+ %brandDTD;
+ <!ENTITY % textcontextDTD SYSTEM "chrome://global/locale/textcontext.dtd">
+ %textcontextDTD;
+ <!ENTITY % baseMenuOverlayDTD SYSTEM "chrome://messenger/locale/baseMenuOverlay.dtd">
+ %baseMenuOverlayDTD;
+ <!ENTITY % utilityDTD SYSTEM "chrome://communicator/locale/utilityOverlay.dtd">
+ %utilityDTD;
+ <!ENTITY % charsetDTD SYSTEM "chrome://global/locale/charsetOverlay.dtd">
+ %charsetDTD;
+ <!ENTITY % viewZoomOverlayDTD SYSTEM "chrome://messenger/locale/viewZoomOverlay.dtd">
+ %viewZoomOverlayDTD;
+]>
+
+<overlay xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+<script type="application/javascript" src="chrome://messenger/content/mailCommands.js"/>
+<script type="application/javascript" src="chrome://messenger/content/junkCommands.js"/>
+<script type="application/javascript" src="chrome://messenger/content/mailWindowOverlay.js"/>
+<script type="application/javascript" src="chrome://messenger/content/mailTabs.js"/>
+<script type="application/javascript" src="chrome://messenger/content/messageDisplay.js"/>
+<script type="application/javascript" src="chrome://messenger/content/folderDisplay.js"/>
+<script type="application/javascript" src="chrome://messenger-newsblog/content/newsblogOverlay.js"/>
+<script type="application/javascript" src="chrome://messenger/content/mail-offline.js"/>
+<script type="application/javascript" src="chrome://global/content/printUtils.js"/>
+<script type="application/javascript" src="chrome://messenger/content/msgViewPickerOverlay.js"/>
+<script type="application/javascript" src="chrome://messenger/content/plugins.js"/>
+<script type="application/javascript" src="chrome://global/content/viewZoomOverlay.js"/>
+<script type="application/javascript" src="chrome://messenger/content/newmailaccount/uriListener.js"/>
+<script type="application/javascript" src="chrome://messenger-newsblog/content/utils.js"/>
+
+<stringbundleset id="stringbundleset">
+ <stringbundle id="bundle_messenger" src="chrome://messenger/locale/messenger.properties"/>
+ <stringbundle id="bundle_offlinePrompts" src="chrome://messenger/locale/offline.properties"/>
+</stringbundleset>
+
+<!-- Performance optimization...we include utilityOverlay.xul which defines some command sets
+ which are updated based on events like focus and select. We have our own custom events
+ which we use to optmize when we do command updating. To avoid unnecessary command updating,
+ we are going to override the events the global edit menu items and select edit menu items
+ are updated on with events of our own controlling.
+ -->
+
+<commandset id="globalEditMenuItems"
+ commandupdater="true"
+ events="create-menu-edit"
+ oncommandupdate="goUpdateGlobalEditMenuItems()"/>
+<commandset id="selectEditMenuItems"
+ commandupdater="true"
+ events="create-menu-edit"
+ oncommandupdate="goUpdateSelectEditMenuItems()"/>
+
+<!-- End command set merging -->
+
+<commandset id="mailFileMenuItems"
+ commandupdater="true"
+ events="create-menu-file"
+ oncommandupdate="goUpdateMailMenuItems(this)">
+
+ <command id="cmd_getNewMessages" oncommand="goDoCommand('cmd_getNewMessages')" disabled="true"/>
+ <command id="cmd_open" oncommand="goDoCommand('cmd_open')"/>
+
+ <command id="cmd_emptyTrash" oncommand="goDoCommand('cmd_emptyTrash')" disabled="true"/>
+ <command id="cmd_compactFolder" oncommand="goDoCommand('cmd_compactFolder')" disabled="true"/>
+ <command id="cmd_printSetup" oncommand="goDoCommand('cmd_printSetup')" disabled="true"/>
+ <command id="cmd_print" oncommand="goDoCommand('cmd_print')" disabled="true"/>
+ <command id="cmd_printpreview" oncommand="goDoCommand('cmd_printpreview')" disabled="true"/>
+ <command id="cmd_saveAsFile" oncommand="goDoCommand('cmd_saveAsFile')" disabled="true"/>
+ <command id="cmd_saveAsTemplate" oncommand="goDoCommand('cmd_saveAsTemplate')" disabled="true"/>
+ <command id="cmd_getNextNMessages" oncommand="goDoCommand('cmd_getNextNMessages')" disabled="true"/>
+ <command id="cmd_deleteFolder" oncommand="goDoCommand('cmd_deleteFolder')"/>
+ <command id="cmd_renameFolder" oncommand="goDoCommand('cmd_renameFolder')" />
+ <command id="cmd_sendUnsentMsgs" oncommand="goDoCommand('cmd_sendUnsentMsgs')" />
+ <command id="cmd_synchronizeOffline" oncommand="goDoCommand('cmd_synchronizeOffline')" disabled="true"/>
+ <command id="cmd_downloadFlagged" oncommand="goDoCommand('cmd_downloadFlagged')" disabled="true"/>
+ <command id="cmd_downloadSelected" oncommand="goDoCommand('cmd_downloadSelected')" disabled="true"/>
+ <command id="cmd_settingsOffline" oncommand="goDoCommand('cmd_settingsOffline')" disabled="true"/>
+</commandset>
+
+<commandset id="mailCommands">
+ <command id="cmd_quit"/>
+ <!--The cmd_createFilterFromPopup is used to notify the email context popup -->
+ <command id="cmd_createFilterFromPopup"/>
+ <command id="cmd_pageSetup"/>
+ <command id="cmd_CustomizeMailToolbar"
+ oncommand="CustomizeMailToolbar('mail-toolbox', 'CustomizeMailToolbar')"/>
+</commandset>
+
+<commandset id="mailViewMenuItems"
+ commandupdater="true"
+ events="create-menu-view"
+ oncommandupdate="goUpdateMailMenuItems(this)">
+
+ <command id="cmd_viewPageSource" oncommand="goDoCommand('cmd_viewPageSource')" disabled="true"/>
+ <command id="cmd_setFolderCharset" oncommand="goDoCommand('cmd_setFolderCharset')" />
+
+ <command id="cmd_expandAllThreads" oncommand="goDoCommand('cmd_expandAllThreads')" disabled="true"/>
+ <command id="cmd_collapseAllThreads" oncommand="goDoCommand('cmd_collapseAllThreads')" disabled="true"/>
+ <command id="cmd_viewClassicMailLayout" oncommand="goDoCommand('cmd_viewClassicMailLayout')" disabled="true"/>
+ <command id="cmd_viewWideMailLayout" oncommand="goDoCommand('cmd_viewWideMailLayout')" disabled="true"/>
+ <command id="cmd_viewVerticalMailLayout" oncommand="goDoCommand('cmd_viewVerticalMailLayout')" disabled="true"/>
+ <command id="cmd_toggleFolderPane" oncommand="goDoCommand('cmd_toggleFolderPane')" disabled="true"/>
+ <command id="cmd_toggleMessagePane" oncommand="goDoCommand('cmd_toggleMessagePane')" disabled="true"/>
+ <command id="cmd_viewAllMsgs" oncommand="goDoCommand('cmd_viewAllMsgs')" disabled="true"/>
+ <command id="cmd_viewUnreadMsgs" oncommand="goDoCommand('cmd_viewUnreadMsgs')" disabled="true"/>
+ <command id="cmd_viewThreadsWithUnread" oncommand="goDoCommand('cmd_viewThreadsWithUnread')" disabled="true"/>
+ <command id="cmd_viewWatchedThreadsWithUnread" oncommand="goDoCommand('cmd_viewWatchedThreadsWithUnread')" disabled="true"/>
+ <command id="cmd_viewIgnoredThreads" oncommand="goDoCommand('cmd_viewIgnoredThreads')" disabled="true"/>
+ <commandset id="viewZoomCommands"
+ commandupdater="true"
+ events="create-menu-view"
+ oncommandupdate="goUpdateMailMenuItems(this);">
+ <command id="cmd_fullZoomReduce"
+ oncommand="goDoCommand('cmd_fullZoomReduce');"/>
+ <command id="cmd_fullZoomEnlarge"
+ oncommand="goDoCommand('cmd_fullZoomEnlarge');"/>
+ <command id="cmd_fullZoomReset"
+ oncommand="goDoCommand('cmd_fullZoomReset');"/>
+ <command id="cmd_fullZoomToggle"
+ oncommand="goDoCommand('cmd_fullZoomToggle');"/>
+ </commandset>
+</commandset>
+
+<commandset id="mailEditMenuItems"
+ commandupdater="true"
+ events="create-menu-edit"
+ oncommandupdate="goUpdateMailMenuItems(this)">
+
+ <command id="cmd_undo"
+ valueDeleteMsg="&undoDeleteMsgCmd.label;"
+ valueMoveMsg="&undoMoveMsgCmd.label;"
+ valueCopyMsg="&undoCopyMsgCmd.label;"
+ valueUnmarkAllMsgs="&undoMarkAllCmd.label;"
+ valueDefault="&undoDefaultCmd.label;"/>
+ <command id="cmd_redo"
+ valueDeleteMsg="&redoDeleteMsgCmd.label;"
+ valueMoveMsg="&redoMoveMsgCmd.label;"
+ valueCopyMsg="&redoCopyMsgCmd.label;"
+ valueUnmarkAllMsgs="&redoMarkAllCmd.label;"
+ valueDefault="&redoDefaultCmd.label;"/>
+ <command id="cmd_cut"/>
+ <command id="cmd_copy"/>
+ <command id="cmd_paste"/>
+ <command id="cmd_delete"
+ valueFolder="&deleteFolderCmd.label;"
+ valueFolderAccessKey="&deleteFolderCmd.accesskey;"
+ valueNewsgroup="&unsubscribeNewsgroupCmd.label;"
+ valueNewsgroupAccessKey="&unsubscribeNewsgroupCmd.accesskey;"
+ valueMessage="&deleteMsgCmd.label;"
+ valueMessageAccessKey="&deleteMsgCmd.accesskey;"
+ valueIMAPDeletedMessage="&undeleteMsgCmd.label;"
+ valueIMAPDeletedMessageAccessKey="&undeleteMsgCmd.accesskey;"
+ valueMessages="&deleteMsgsCmd.label;"
+ valueMessagesAccessKey="&deleteMsgsCmd.accesskey;"
+ valueIMAPDeletedMessages="&undeleteMsgsCmd.label;"
+ valueIMAPDeletedMessagesAccessKey="&undeleteMsgsCmd.accesskey;"/>
+ <command id="cmd_cancel" oncommand="goDoCommand('cmd_cancel')"/>
+ <command id="cmd_selectAll"/>
+ <command id="cmd_selectThread" oncommand="goDoCommand('cmd_selectThread')"/>
+ <command id="cmd_selectFlagged" oncommand="goDoCommand('cmd_selectFlagged')"/>
+ <command id="cmd_properties" oncommand="goDoCommand('cmd_properties')"
+ valueNewsgroup="&folderPropsNewsgroupCmd.label;"
+ valueFolder="&folderPropsFolderCmd.label;"
+ valueGeneric="&folderPropsCmd.label;"/>
+ <command id="cmd_find" oncommand="goDoCommand('cmd_find')" disabled="true"/>
+ <command id="cmd_findAgain" oncommand="goDoCommand('cmd_findAgain')" disabled="true"/>
+ <command id="cmd_findPrevious" oncommand="goDoCommand('cmd_findPrevious')"
+ disabled="true"/>
+ <command id="cmd_search" oncommand="goDoCommand('cmd_search')"/>
+ <!-- Stop/abort current network activities. -->
+ <command id="cmd_stop" oncommand="goDoCommand('cmd_stop')"/>
+ <command id="cmd_reload" oncommand="goDoCommand('cmd_reload')"/>
+</commandset>
+
+<commandset id="mailEditContextMenuItems">
+ <command id="cmd_copyLink"/>
+ <command id="cmd_copyImage"/>
+</commandset>
+
+<commandset id="mailGoMenuItems"
+ commandupdater="true"
+ events="create-menu-go"
+ oncommandupdate="goUpdateMailMenuItems(this)">
+
+ <command id="cmd_nextMsg" oncommand="goDoCommand('cmd_nextMsg')" disabled="true"/>
+ <command id="cmd_nextUnreadMsg" oncommand="goDoCommand('cmd_nextUnreadMsg')" disabled="true"/>
+ <command id="cmd_nextFlaggedMsg" oncommand="goDoCommand('cmd_nextFlaggedMsg')" disabled="true"/>
+ <command id="cmd_nextUnreadThread" oncommand="goDoCommand('cmd_nextUnreadThread')" disabled="true"/>
+ <command id="cmd_previousMsg" oncommand="goDoCommand('cmd_previousMsg')" disabled="true"/>
+ <command id="cmd_previousUnreadMsg" oncommand="goDoCommand('cmd_previousUnreadMsg')" disabled="true"/>
+ <command id="cmd_previousFlaggedMsg" oncommand="goDoCommand('cmd_previousFlaggedMsg')" disabled="true"/>
+ <command id="cmd_goStartPage" oncommand="goDoCommand('cmd_goStartPage');"/>
+ <command id="cmd_undoCloseTab" oncommand="goDoCommand('cmd_undoCloseTab');"/>
+ <command id="cmd_goForward" oncommand="goDoCommand('cmd_goForward')" disabled="true"/>
+ <command id="cmd_goBack" oncommand="goDoCommand('cmd_goBack')" disabled="true"/>
+ <command id="cmd_chat" oncommand="goDoCommand('cmd_chat')" disabled="true"/>
+</commandset>
+
+<commandset id="mailMessageMenuItems"
+ commandupdater="true"
+ events="create-menu-message"
+ oncommandupdate="goUpdateMailMenuItems(this)">
+ <command id="cmd_archive" oncommand="goDoCommand('cmd_archive')"/>
+ <command id="cmd_reply" oncommand="MsgReplyMessage(event)"/>
+ <command id="cmd_replySender" oncommand="MsgReplySender(event);"/>
+ <command id="cmd_replyGroup" oncommand="MsgReplyGroup(event);"/>
+ <command id="cmd_replyall" oncommand="MsgReplyToAllMessage(event);"/>
+ <command id="cmd_replylist" oncommand="MsgReplyToListMessage(event);"/>
+ <command id="cmd_forward" oncommand="MsgForwardMessage(event);"/>
+ <command id="cmd_forwardInline" oncommand="MsgForwardAsInline(event)"/>
+ <command id="cmd_forwardAttachment" oncommand="MsgForwardAsAttachment(event);"/>
+ <command id="cmd_editAsNew" oncommand="goDoCommand('cmd_editAsNew')"/>
+ <command id="cmd_openMessage" oncommand="goDoCommand('cmd_openMessage')"/>
+ <command id="cmd_openConversation" oncommand="goDoCommand('cmd_openConversation')"/>
+ <command id="cmd_moveToFolderAgain" oncommand="goDoCommand('cmd_moveToFolderAgain')"/>
+ <command id="cmd_createFilterFromMenu" oncommand="goDoCommand('cmd_createFilterFromMenu')"/>
+ <command id="cmd_killThread" oncommand="goDoCommand('cmd_killThread')"/>
+ <command id="cmd_killSubthread" oncommand="goDoCommand('cmd_killSubthread')"/>
+ <command id="cmd_watchThread" oncommand="goDoCommand('cmd_watchThread')"/>
+</commandset>
+
+<commandset id="mailToolbarItems"
+ commandupdater="true"
+ events="mail-toolbar"
+ oncommandupdate="goUpdateMailMenuItems(this)">
+ <command id="button_reply"/>
+ <command id="button_replyall"/>
+ <command id="button_replylist"/>
+ <command id="button_followup"/>
+ <command id="button_archive"/>
+ <command id="button_forward"/>
+ <command id="button_delete"/>
+ <command id="button_mark"/>
+ <command id="cmd_tag"/>
+ <command id="button_getNewMessages"/>
+ <command id="button_print"/>
+ <command id="button_previous"/>
+ <command id="button_previousMsg"/>
+ <command id="button_next"/>
+ <command id="button_nextMsg"/>
+ <command id="button_goBack"/>
+ <command id="button_goForward"/>
+ <command id="button_file"/>
+ <command id="cmd_delete"/>
+ <command id="button_junk"/>
+ <command id="button_compact"/>
+ <command id="cmd_chat"/>
+</commandset>
+
+<commandset id="mailGetMsgMenuItems"
+ commandupdater="true"
+ events="create-menu-getMsgToolbar,create-menu-file"
+ oncommandupdate="goUpdateMailMenuItems(this)">
+
+ <command id="cmd_getMsgsForAuthAccounts"
+ oncommand="goDoCommand('cmd_getMsgsForAuthAccounts'); event.stopPropagation()"
+ disabled="true"/>
+</commandset>
+
+<commandset id="mailMarkMenuItems"
+ commandupdater="true"
+ events="create-menu-mark"
+ oncommandupdate="goUpdateMailMenuItems(this)">
+
+ <command id="cmd_toggleRead" oncommand="goDoCommand('cmd_toggleRead'); event.stopPropagation()" disabled="true"/>
+ <command id="cmd_markAsRead" oncommand="goDoCommand('cmd_markAsRead'); event.stopPropagation()" disabled="true"/>
+ <command id="cmd_markAsUnread" oncommand="goDoCommand('cmd_markAsUnread'); event.stopPropagation()" disabled="true"/>
+ <command id="cmd_markAllRead" oncommand="goDoCommand('cmd_markAllRead'); event.stopPropagation()" disabled="true"/>
+ <command id="cmd_markThreadAsRead" oncommand="goDoCommand('cmd_markThreadAsRead'); event.stopPropagation()" disabled="true"/>
+ <command id="cmd_markReadByDate" oncommand="goDoCommand('cmd_markReadByDate');" disabled="true"/>
+ <command id="cmd_markAsFlagged" oncommand="goDoCommand('cmd_markAsFlagged'); event.stopPropagation()" disabled="true"/>
+ <command id="cmd_markAsJunk" oncommand="goDoCommand('cmd_markAsJunk'); event.stopPropagation()" disabled="true"/>
+ <command id="cmd_markAsNotJunk" oncommand="goDoCommand('cmd_markAsNotJunk'); event.stopPropagation()" disabled="true"/>
+ <command id="cmd_recalculateJunkScore" oncommand="goDoCommand('cmd_recalculateJunkScore');" disabled="true"/>
+ <command id="cmd_viewAllHeader" oncommand="goDoCommand('cmd_viewAllHeader');" disabled="true"/>
+ <command id="cmd_viewNormalHeader" oncommand="goDoCommand('cmd_viewNormalHeader');" disabled="true"/>
+</commandset>
+
+<commandset id="mailTagMenuItems"
+ commandupdater="true"
+ events="create-menu-tag"
+ oncommandupdate="goUpdateMailMenuItems(this);">
+
+ <command id="cmd_addTag" oncommand="goDoCommand('cmd_addTag'); event.stopPropagation();"/>
+ <command id="cmd_manageTags" oncommand="goDoCommand('cmd_manageTags'); event.stopPropagation();"/>
+ <command id="cmd_removeTags" oncommand="goDoCommand('cmd_removeTags'); event.stopPropagation();"/>
+</commandset>
+
+<commandset id="mailToolsMenuItems"
+ commandupdater="true"
+ events="create-menu-tasks"
+ oncommandupdate="goUpdateMailMenuItems(this)">
+ <command id="cmd_displayMsgFilters"
+ oncommand="goDoCommand('cmd_displayMsgFilters');" disabled="true"/>
+ <command id="cmd_applyFilters" oncommand="goDoCommand('cmd_applyFilters');" disabled="true"/>
+ <command id="cmd_applyFiltersToSelection"
+ oncommand="goDoCommand('cmd_applyFiltersToSelection');"
+ disabled="true"
+ valueSelection="&filtersApplyToSelection.label;"
+ valueSelectionAccessKey="&filtersApplyToSelection.accesskey;"
+ valueMessage="&filtersApplyToMessage.label;"
+ valueMessageAccessKey="&filtersApplyToMessage.accesskey;"/>
+ <command id="cmd_runJunkControls" oncommand="goDoCommand('cmd_runJunkControls');" disabled="true"/>
+ <command id="cmd_deleteJunk" oncommand="goDoCommand('cmd_deleteJunk');" disabled="true"/>
+</commandset>
+
+#ifdef XP_MACOSX
+<commandset id="macWindowMenuItems">
+ <!-- Mac Window menu -->
+ <command id="minimizeWindow" label="&minimizeWindow.label;" oncommand="window.minimize();"/>
+ <command id="zoomWindow" label="&zoomWindow.label;" oncommand="zoomWindow();"/>
+ <command id="Tasks:Mail" oncommand="focusOnMail(1);"/>
+ <command id="Tasks:AddressBook" oncommand="toAddressBook();"/>
+</commandset>
+#endif
+
+<keyset id="mailKeys">
+ <key id="space" key=" " modifiers="shift any" oncommand="SpaceHit(event);"/>
+
+ <!-- File Menu -->
+ <key id="key_close"/>
+#ifndef XP_MACOSX
+ <key id="key_close2" keycode="VK_F4" modifiers="accel" command="cmd_close"/>
+ <key id="key_renameFolder" keycode="&renameFolder.key;" oncommand="goDoCommand('cmd_renameFolder')"/>
+#endif
+#ifdef XP_UNIX
+ <key id="key_quit"/>
+#endif
+ <!-- Edit Menu -->
+ <key id="key_undo"/>
+ <key id="key_redo"/>
+ <key id="key_cut"/>
+ <key id="key_copy"/>
+ <key id="key_paste"/>
+#ifdef XP_MACOSX
+ <key id="key_delete" keycode="VK_BACK"
+ oncommand="goDoCommand('cmd_delete');"/>
+ <key id="key_delete2" keycode="VK_DELETE"
+ oncommand="goDoCommand('cmd_delete');"/>
+ <key id="cmd_shiftDelete" keycode="VK_BACK"
+ oncommand="goDoCommand('cmd_shiftDelete');" modifiers="shift"/>
+ <key id="cmd_shiftDelete2" keycode="VK_DELETE"
+ oncommand="goDoCommand('cmd_shiftDelete');" modifiers="shift"/>
+#else
+ <key id="key_delete" keycode="VK_DELETE"
+ oncommand="goDoCommand('cmd_delete');"/>
+ <key id="cmd_shiftDelete" keycode="VK_DELETE"
+ oncommand="goDoCommand('cmd_shiftDelete');" modifiers="shift"/>
+#endif
+ <key id="key_selectAll"/>
+ <key id="key_selectThread" key="&selectThreadCmd.key;" oncommand="goDoCommand('cmd_selectThread');" modifiers="accel, shift"/>
+
+ <key id="key_toggleRead" key="&toggleReadCmd.key;" oncommand="goDoCommand('cmd_toggleRead');"/>
+ <key id="key_toggleFlagged" key="&markStarredCmd.key;" oncommand="goDoCommand('cmd_markAsFlagged');"/>
+ <key id="key_markJunk" key="&markAsJunkCmd.key;" oncommand="goDoCommand('cmd_markAsJunk');"/>
+ <key id="key_markNotJunk" key="&markAsNotJunkCmd.key;" oncommand="goDoCommand('cmd_markAsNotJunk');"
+ modifiers="shift"/>
+
+ <key id="key_markAllRead" key="&markAllReadCmd.key;"
+ oncommand="goDoCommand('cmd_markAllRead');" modifiers="shift"/>
+
+ <key id="key_markThreadAsRead" key="&markThreadAsReadCmd.key;" oncommand="goDoCommand('cmd_markThreadAsRead')"/>
+ <key id="key_markReadByDate" key="&markReadByDateCmd.key;" oncommand="goDoCommand('cmd_markReadByDate')"/>
+ <key id="key_nextMsg" key="&nextMsgCmd.key;" oncommand="goDoCommand('cmd_nextMsg')"/>
+ <key id="key_nextUnreadMsg" key="&nextUnreadMsgCmd.key;" oncommand="goDoCommand('cmd_nextUnreadMsg')"/>
+ <key id="key_expandAllThreads" key="&expandAllThreadsCmd.key;" oncommand="goDoCommand('cmd_expandAllThreads')"/>
+ <key key="&expandAllThreadsCmd.key;" modifiers="shift" oncommand="goDoCommand('cmd_expandAllThreads')"/>
+ <key id="key_collapseAllThreads" key="&collapseAllThreadsCmd.key;" oncommand="goDoCommand('cmd_collapseAllThreads')"/>
+ <key key="&collapseAllThreadsCmd.key;" modifiers="shift" oncommand="goDoCommand('cmd_collapseAllThreads')"/>
+ <key id="key_nextUnreadThread" key="&nextUnreadThread.key;" oncommand="goDoCommand('cmd_nextUnreadThread')"/>
+ <key id="key_previousMsg" key="&prevMsgCmd.key;" oncommand="goDoCommand('cmd_previousMsg')"/>
+ <key id="key_previousUnreadMsg" key="&prevUnreadMsgCmd.key;" oncommand="goDoCommand('cmd_previousUnreadMsg')"/>
+ <key id="key_archive" key="&archiveMsgCmd.key;" oncommand="goDoCommand('cmd_archive')"/>
+ <key id="key_goForward" key="&goForwardCmd.commandKey;" oncommand="goDoCommand('cmd_goForward')"/>
+ <key id="key_goBack" key="&goBackCmd.commandKey;" oncommand="goDoCommand('cmd_goBack')"/>
+ <key id="key_goChat" key="&goChatCmd.key;" oncommand="goDoCommand('cmd_chat')" modifiers="accel,shift"/>
+ <key id="key_goStartPage" keycode="VK_HOME" oncommand="goDoCommand('cmd_goStartPage')" modifiers="alt"/>
+ <key id="key_undoCloseTab" key="&undoCloseTabCmd.commandkey;" oncommand="goDoCommand('cmd_undoCloseTab')" modifiers="accel, shift"/>
+ <key id="key_reply" key="&replyMsgCmd.key;" oncommand="goDoCommand('cmd_reply')" modifiers="accel"/>
+ <key id="key_replyall" key="&replyToAllMsgCmd.key;" oncommand="goDoCommand('cmd_replyall')" modifiers="accel, shift"/>
+ <key id="key_replylist" key="&replyToListMsgCmd.key;" oncommand="goDoCommand('cmd_replylist')" modifiers="accel, shift"/>
+ <key id="key_forward" key="&forwardMsgCmd.key;" oncommand="goDoCommand('cmd_forward')" modifiers="accel"/>
+ <key id="key_editAsNew" key="&editMsgAsNewCmd.key;" oncommand="goDoCommand('cmd_editAsNew')" modifiers="accel"/>
+ <key id="key_watchThread" key="&watchThreadMenu.key;" oncommand="goDoCommand('cmd_watchThread')" />
+ <key id="key_killThread" key="&killThreadMenu.key;" oncommand="goDoCommand('cmd_killThread')" />
+ <key id="key_killSubthread" key="&killSubthreadMenu.key;" oncommand="goDoCommand('cmd_killSubthread')" modifiers="shift" />
+ <key id="key_openMessage" key="&openMessageWindowCmd.key;" oncommand="goDoCommand('cmd_openMessage')" modifiers="accel"/>
+ <key id="key_openConversation" key="&openConversationCmd.key;" oncommand="goDoCommand('cmd_openConversation')" modifiers="accel, shift"/>
+#ifdef XP_MACOSX
+ <key id="key_moveToFolderAgain" key="&moveToFolderAgainCmd.key;" oncommand="goDoCommand('cmd_moveToFolderAgain')" modifiers="alt, accel"/>
+#else
+ <key id="key_moveToFolderAgain" key="&moveToFolderAgainCmd.key;" oncommand="goDoCommand('cmd_moveToFolderAgain')" modifiers="accel, shift"/>
+#endif
+ <key id="key_print" key="&printCmd.key;" oncommand="goDoCommand('cmd_print')" modifiers="accel"/>
+ <key id="key_saveAsFile" key="&saveAsFileCmd.key;" oncommand="goDoCommand('cmd_saveAsFile')" modifiers="accel"/>
+ <key id="key_viewPageSource" key="&pageSourceCmd.key;" oncommand="goDoCommand('cmd_viewPageSource')" modifiers="accel"/>
+#ifdef XP_MACOSX
+ <key id="key_getNewMessagesAlt" keycode="VK_F5"
+ oncommand="goDoCommand('cmd_getNewMessages');"/>
+ <key id="key_getAllNewMessagesAlt" keycode="VK_F5" modifiers="shift"
+ oncommand="goDoCommand('cmd_getMsgsForAuthAccounts');"/>
+ <key id="key_getNewMessages" key="&getNewMessagesCmd.key;" modifiers="accel"
+ oncommand="goDoCommand('cmd_getNewMessages');"/>
+ <key id="key_getAllNewMessages" key="&getAllNewMessagesCmd.key;" modifiers="accel, shift"
+ oncommand="goDoCommand('cmd_getMsgsForAuthAccounts');"/>
+#else
+ <key id="key_getNewMessages" keycode="VK_F5"
+ oncommand="goDoCommand('cmd_getNewMessages');"/>
+ <key id="key_getAllNewMessages" keycode="VK_F5" modifiers="shift"
+ oncommand="goDoCommand('cmd_getMsgsForAuthAccounts');"/>
+#endif
+#ifdef XP_GNOME
+ <key id="key_getNewMessages2" keycode="VK_F9"
+ oncommand="goDoCommand('cmd_getNewMessages');"/>
+ <key id="key_getAllNewMessages2" keycode="VK_F9" modifiers="shift"
+ oncommand="goDoCommand('cmd_getMsgsForAuthAccounts');"/>
+#endif
+ <key id="key_find" key="&findCmd.key;" oncommand="goDoCommand('cmd_find')" modifiers="accel"/>
+ <key id="key_findAgain" key="&findAgainCmd.key;" oncommand="goDoCommand('cmd_findAgain')" modifiers="accel"/>
+ <key id="key_findPrev" key="&findPrevCmd.key;" oncommand="goDoCommand('cmd_findPrevious')" modifiers="accel, shift"/>
+ <key keycode="&findAgainCmd.key2;" oncommand="goDoCommand('cmd_findAgain')"/>
+ <key keycode="&findPrevCmd.key2;" oncommand="goDoCommand('cmd_findPrevious')" modifiers="shift"/>
+ <key id="key_quickSearchFocus" key="&quickSearchCmd.key;" oncommand="QuickSearchFocus()" modifiers="accel"/>
+
+ <keyset id="viewZoomKeys">
+ <key id="key_fullZoomReduce" key="&fullZoomReduceCmd.commandkey;"
+ command="cmd_fullZoomReduce" modifiers="accel"/>
+ <key key="&fullZoomReduceCmd.commandkey2;"
+ command="cmd_fullZoomReduce" modifiers="accel"/>
+ <key id="key_fullZoomEnlarge" key="&fullZoomEnlargeCmd.commandkey;"
+ command="cmd_fullZoomEnlarge" modifiers="accel"/>
+ <key key="&fullZoomEnlargeCmd.commandkey2;"
+ command="cmd_fullZoomEnlarge" modifiers="accel"/>
+ <key key="&fullZoomEnlargeCmd.commandkey3;"
+ command="cmd_fullZoomEnlarge" modifiers="accel"/>
+ <key id="key_fullZoomReset" key="&fullZoomResetCmd.commandkey;"
+ command="cmd_fullZoomReset" modifiers="accel"/>
+ <key key="&fullZoomResetCmd.commandkey2;"
+ command="cmd_fullZoomReset" modifiers="accel"/>
+ </keyset>
+
+ <!-- Tab/F6 Keys -->
+ <key keycode="VK_TAB" oncommand="SwitchPaneFocus(event);" modifiers="control,shift"/>
+ <key keycode="VK_TAB" oncommand="SwitchPaneFocus(event);" modifiers="control"/>
+ <key keycode="VK_F6" oncommand="SwitchPaneFocus(event);" modifiers="control,shift"/>
+ <key keycode="VK_F6" oncommand="SwitchPaneFocus(event);" modifiers="control"/>
+ <key keycode="VK_F6" oncommand="SwitchPaneFocus(event);" modifiers="shift"/>
+ <key keycode="VK_F6" oncommand="SwitchPaneFocus(event);"/>
+
+ <!-- View Toggle Keys (F8) -->
+ <key id="key_toggleMessagePane" keycode="VK_F8" oncommand="goDoCommand('cmd_toggleMessagePane');"/>
+
+ <!-- Tag Keys -->
+ <!-- Includes both shifted and not, for Azerty and other layouts where the
+ numeric keys are shifted. -->
+ <key id="key_tag0" key="&tagCmd0.key;" modifiers="shift any"
+ oncommand="goDoCommand('cmd_removeTags');"/>
+ <key id="key_tag1" key="&tagCmd1.key;" modifiers="shift any"
+ oncommand="goDoCommand('cmd_tag1');"/>
+ <key id="key_tag2" key="&tagCmd2.key;" modifiers="shift any"
+ oncommand="goDoCommand('cmd_tag2');"/>
+ <key id="key_tag3" key="&tagCmd3.key;" modifiers="shift any"
+ oncommand="goDoCommand('cmd_tag3');"/>
+ <key id="key_tag4" key="&tagCmd4.key;" modifiers="shift any"
+ oncommand="goDoCommand('cmd_tag4');"/>
+ <key id="key_tag5" key="&tagCmd5.key;" modifiers="shift any"
+ oncommand="goDoCommand('cmd_tag5');"/>
+ <key id="key_tag6" key="&tagCmd6.key;" modifiers="shift any"
+ oncommand="goDoCommand('cmd_tag6');"/>
+ <key id="key_tag7" key="&tagCmd7.key;" modifiers="shift any"
+ oncommand="goDoCommand('cmd_tag7');"/>
+ <key id="key_tag8" key="&tagCmd8.key;" modifiers="shift any"
+ oncommand="goDoCommand('cmd_tag8');"/>
+ <key id="key_tag9" key="&tagCmd9.key;" modifiers="shift any"
+ oncommand="goDoCommand('cmd_tag9');"/>
+
+ <!-- Tools Keys -->
+ <key id="key_searchMail" key="&searchMailCmd.key;" oncommand="goDoCommand('cmd_search')" modifiers="accel, shift"/>
+ <key id="key_errorConsole" key="&errorConsoleCmd.commandkey;" oncommand="toJavaScriptConsole();" modifiers="accel,shift"/>
+ <key id="key_addressbook"
+ key="&addressBookCmd.key;"
+ modifiers="accel, shift"
+ oncommand="toAddressBook();"/>
+ <key id="key_savedFiles"
+ key="&savedFiles.key;"
+ modifiers="accel"
+ oncommand="openSavedFilesWnd();"/>
+
+#ifdef XP_GNOME
+#define NUM_SELECT_TAB_MODIFIER alt
+#else
+#define NUM_SELECT_TAB_MODIFIER accel
+#endif
+
+#expand <key id="key_mail" oncommand="focusOnMail(0, event);" key="1" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
+#expand <key id="key_selectTab2" oncommand="focusOnMail(1, event);" key="2" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
+#expand <key id="key_selectTab3" oncommand="focusOnMail(2, event);" key="3" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
+#expand <key id="key_selectTab4" oncommand="focusOnMail(3, event);" key="4" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
+#expand <key id="key_selectTab5" oncommand="focusOnMail(4, event);" key="5" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
+#expand <key id="key_selectTab6" oncommand="focusOnMail(5, event);" key="6" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
+#expand <key id="key_selectTab7" oncommand="focusOnMail(6, event);" key="7" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
+#expand <key id="key_selectTab8" oncommand="focusOnMail(7, event);" key="8" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
+#expand <key id="key_selectLastTab" oncommand="focusOnMail(-1, event);" key="9" modifiers="__NUM_SELECT_TAB_MODIFIER__"/>
+
+#ifdef XP_MACOSX
+ <!-- Mac Window menu keys -->
+ <key id="key_minimizeWindow" command="minimizeWindow" key="&minimizeWindow.key;" modifiers="accel"/>
+ <!-- the following 3 keys are used in the application menu on Mac OS X Cocoa widgets -->
+ <key id="key_preferencesCmdMac" key="&preferencesCmdMac.commandkey;" modifiers="&preferencesCmdMac.modifiers;"/>
+ <key id="key_hideThisAppCmdMac" key="&hideThisAppCmdMac.commandkey;" modifiers="&hideThisAppCmdMac.modifiers;"/>
+ <key id="key_hideOtherAppsCmdMac" key="&hideOtherAppsCmdMac.commandkey;" modifiers="&hideOtherAppsCmdMac.modifiers;"/>
+#endif
+
+ <!-- Common keys for the base menu overlay -->
+ <keyset id="baseMenuKeyset"/>
+</keyset>
+
+ <!-- "Please keep all items and separators up to date in nsContextMenu.js when making changes here" -->
+ <menupopup id="mailContext"
+ pagemenu="start"
+ onpopupshowing="return fillMailContextMenu(event);"
+ onpopuphiding="mailContextOnPopupHiding(event);">
+
+ <menuseparator id="page-menu-separator"/>
+
+ <!-- Spellchecking suggestions -->
+ <menuitem id="mailContext-spell-no-suggestions"
+ disabled="true"
+ label="&spellNoSuggestions.label;"/>
+ <menuitem id="mailContext-spell-add-to-dictionary"
+ label="&spellAddToDictionary.label;"
+ accesskey="&spellAddToDictionary.accesskey;"
+ oncommand="gSpellChecker.addToDictionary();"/>
+ <menuseparator id="mailContext-spell-suggestions-separator"/>
+
+ <menuitem id="mailContext-openInBrowser"
+ label="&openInBrowser.label;"
+ accesskey="&openInBrowser.accesskey;"
+ oncommand="gContextMenu.openInBrowser();"/>
+ <menuitem id="mailContext-openLinkInBrowser"
+ label="&openLinkInBrowser.label;"
+ accesskey="&openLinkInBrowser.accesskey;"
+ oncommand="gContextMenu.openLinkInBrowser();"/>
+ <menuseparator id="mailContext-sep-open-browser"/>
+ <menuitem id="mailContext-reload"
+ label="&reloadCmd.label;"
+ accesskey="&reloadCmd.accesskey;"
+ command="cmd_reload"/>
+ <menuitem id="mailContext-stop"
+ label="&stopCmd.label;"
+ accesskey="&stopCmd.accesskey;"
+ command="cmd_stop"/>
+ <menuseparator id="mailContext-sep-link"/>
+ <menuitem id="mailContext-undo"
+ label="&undoDefaultCmd.label;"
+ accesskey="&undoDefaultCmd.accesskey;"
+ command="cmd_undo"/>
+ <menuseparator id="mailContext-sep-undo"/>
+ <menuitem id="mailContext-cut"
+ label="&cutCmd.label;"
+ accesskey="&cutCmd.accesskey;"
+ command="cmd_copy"/>
+ <menuitem id="mailContext-copy"
+ label="©Cmd.label;"
+ accesskey="©Cmd.accesskey;"
+ command="cmd_copy"/>
+ <menuitem id="mailContext-paste"
+ label="&pasteCmd.label;"
+ accesskey="&pasteCmd.accesskey;"
+ command="cmd_paste"/>
+ <menuitem id="mailContext-selectall"
+ label="&selectAllCmd.label;"
+ accesskey="&selectAllCmd.accesskey;"
+ command="cmd_selectAll"/>
+ <menuseparator id="mailContext-sep-clipboard"/>
+
+ <menuitem id="mailContext-searchTheWeb"
+ label="[glodaComplete.webSearch1.label]"
+ oncommand="openSearchTab(event.target.value)"/>
+
+ <!-- Spellchecking general menu items (enable, add dictionaries...) -->
+ <menuseparator id="mailContext-spell-separator"/>
+ <menuitem id="mailContext-spell-check-enabled"
+ label="&spellCheckToggle.label;"
+ type="checkbox"
+ accesskey="&spellCheckToggle.accesskey;"
+ oncommand="gSpellChecker.toggleEnabled();"/>
+ <menuitem id="mailContext-spell-add-dictionaries-main"
+ label="&spellAddDictionaries.label;"
+ accesskey="&spellAddDictionaries.accesskey;"
+ oncommand="gContextMenu.addDictionaries();"/>
+ <menu id="mailContext-spell-dictionaries"
+ label="&spellDictionaries.label;"
+ accesskey="&spellDictionaries.accesskey;">
+ <menupopup id="mailContext-spell-dictionaries-menu">
+ <menuseparator id="mailContext-spell-language-separator"/>
+ <menuitem id="mailContext-spell-add-dictionaries"
+ label="&spellAddDictionaries.label;"
+ accesskey="&spellAddDictionaries.accesskey;"
+ oncommand="gContextMenu.addDictionaries();"/>
+ </menupopup>
+ </menu>
+
+ <menuseparator id="mailContext-sep-open"/>
+ <menuitem id="mailContext-media-play"
+ label="&contextPlay.label;"
+ accesskey="&contextPlay.accesskey;"
+ oncommand="gContextMenu.mediaCommand('play');"/>
+ <menuitem id="mailContext-media-pause"
+ label="&contextPause.label;"
+ accesskey="&contextPause.accesskey;"
+ oncommand="gContextMenu.mediaCommand('pause');"/>
+ <menuitem id="mailContext-media-mute"
+ label="&contextMute.label;"
+ accesskey="&contextMute.accesskey;"
+ oncommand="gContextMenu.mediaCommand('mute');"/>
+ <menuitem id="mailContext-media-unmute"
+ label="&contextUnmute.label;"
+ accesskey="&contextUnmute.accesskey;"
+ oncommand="gContextMenu.mediaCommand('unmute');"/>
+ <menuitem id="threadPaneContext-openNewTab"
+ label="&contextOpenNewTab.label;"
+ accesskey="&contextOpenNewTab.accesskey;"
+ oncommand="OpenMessageInNewTab(event);"/>
+ <menuitem id="mailContext-openNewWindow"
+ label="&contextOpenNewWindow.label;"
+ accesskey="&contextOpenNewWindow.accesskey;"
+ oncommand="MsgOpenNewWindowForMessage();"/>
+ <menuitem id="mailContext-openConversation"
+ label="&contextOpenConversation.label;"
+ accesskey="&contextOpenConversation.accesskey;"
+ oncommand="gConversationOpener.openConversationForMessages(gFolderDisplay.selectedMessages);"/>
+ <menuseparator id="mailContext-sep-open2"/>
+ <menuitem id="mailContext-replyNewsgroup"
+ label="&contextReplyNewsgroup2.label;"
+ accesskey="&contextReplyNewsgroup2.accesskey;"
+ oncommand="MsgReplyGroup(event);"/>
+ <menuitem id="mailContext-replySender"
+ label="&contextReplySender.label;"
+ accesskey="&contextReplySender.accesskey;"
+ oncommand="MsgReplySender(event);"/>
+ <menuitem id="mailContext-replyAll"
+ label="&contextReplyAll.label;"
+ accesskey="&contextReplyAll.accesskey;"
+ oncommand="MsgReplyToAllMessage(event);"/>
+ <menuitem id="mailContext-replyList"
+ label="&contextReplyList.label;"
+ accesskey="&contextReplyList.accesskey;"
+ oncommand="MsgReplyToListMessage(event);"/>
+ <menuitem id="mailContext-forward"
+ label="&contextForward.label;"
+ accesskey="&contextForward.accesskey;"
+ oncommand="MsgForwardMessage(event);"/>
+ <menu id="mailContext-forwardAsMenu"
+ label="&contextForwardAsMenu.label;"
+ accesskey="&contextForwardAsMenu.accesskey;">
+ <menupopup id="mailContext-forwardAsPopup">
+ <menuitem id="mailContext-forwardAsInline"
+ label="&contextForwardAsInline.label;"
+ accesskey="&contextForwardAsInline.accesskey;"
+ command="cmd_forwardInline"/>
+ <menuitem id="mailContext-forwardAsAttachment"
+ label="&contextForwardAsAttachmentItem.label;"
+ accesskey="&contextForwardAsAttachmentItem.accesskey;"
+ command="cmd_forwardAttachment"/>
+ </menupopup>
+ </menu>
+ <menuitem id="mailContext-multiForwardAsAttachment"
+ label="&contextMultiForwardAsAttachment.label;"
+ accesskey="&contextMultiForwardAsAttachment.accesskey;"
+ oncommand="MsgForwardAsAttachment(event);"/>
+ <menuitem id="mailContext-editAsNew"
+ label="&contextEditAsNew.label;"
+ accesskey="&contextEditAsNew.accesskey;"
+ oncommand="MsgEditMessageAsNew();"/>
+ <menuseparator id="mailContext-sep-reply"/>
+ <menu id="mailContext-tags" label="&tagMenu.label;" accesskey="&tagMenu.accesskey;">
+ <menupopup id="mailContext-tagpopup"
+ onpopupshowing="InitMessageTags(this);">
+ <menuitem id="addNewTag"
+ label="&addNewTag.label;"
+ accesskey="&addNewTag.accesskey;"
+ command="cmd_addTag"/>
+ <menuitem id="manageTags"
+ label="&manageTags.label;"
+ accesskey="&manageTags.accesskey;"
+ command="cmd_manageTags"/>
+ <menuseparator id="mailContext-sep-afterTagAddNew"/>
+ <menuitem id="mailContext-tagRemoveAll"
+ command="cmd_removeTags"/>
+ <menuseparator id="mailContext-sep-afterTagRemoveAll"/>
+ </menupopup>
+ </menu>
+ <menu id="mailContext-mark"
+ label="&markMenu.label;"
+ accesskey="&markMenu.accesskey;">
+ <menupopup id="mailContext-markPopup"
+ onpopupshowing="InitMessageMark()">
+ <menuitem id="mailContext-markRead"
+ label="&markAsReadCmd.label;"
+ accesskey="&markAsReadCmd.accesskey;"
+ command="cmd_markAsRead"/>
+ <menuitem id="mailContext-markUnread"
+ label="&markAsUnreadCmd.label;"
+ accesskey="&markAsUnreadCmd.accesskey;"
+ command="cmd_markAsUnread"/>
+ <menuitem id="mailContext-markThreadAsRead"
+ label="&markThreadAsReadCmd.label;"
+ accesskey="&markThreadAsReadCmd.accesskey;"
+ command="cmd_markThreadAsRead"/>
+ <menuitem id="mailContext-markReadByDate"
+ label="&markReadByDateCmd.label;"
+ accesskey="&markReadByDateCmd.accesskey;"
+ command="cmd_markReadByDate"/>
+ <menuitem id="mailContext-markAllRead"
+ label="&markAllReadCmd.label;"
+ accesskey="&markAllReadCmd.accesskey;"
+ command="cmd_markAllRead"/>
+ <menuseparator id="mailContext-sep-afterMarkAllRead"/>
+ <menuitem id="mailContext-markFlagged"
+ type="checkbox"
+ label="&markStarredCmd.label;"
+ accesskey="&markStarredCmd.accesskey;"
+ command="cmd_markAsFlagged"/>
+ <menuseparator id="mailContext-sep-afterMarkFlagged"/>
+ <menuitem id="mailContext-markAsJunk"
+ label="&markAsJunkCmd.label;"
+ accesskey="&markAsJunkCmd.accesskey;"
+ command="cmd_markAsJunk"/>
+ <menuitem id="mailContext-markAsNotJunk"
+ label="&markAsNotJunkCmd.label;"
+ accesskey="&markAsNotJunkCmd.accesskey;"
+ command="cmd_markAsNotJunk"/>
+ <menuitem id="mailContext-recalculateJunkScore"
+ label="&recalculateJunkScoreCmd.label;"
+ accesskey="&recalculateJunkScoreCmd.accesskey;"
+ command="cmd_recalculateJunkScore"/>
+ </menupopup>
+ </menu>
+ <menuseparator id="mailContext-sep-afterMarkMenu"/>
+ <menuitem id="mailContext-copyMessageUrl"
+ label="©MessageLocation.label;"
+ accesskey="©MessageLocation.accesskey;"
+ oncommand="CopyMessageUrl()"/>
+ <menuitem id="mailContext-archive"
+ label="&contextArchive.label;"
+ accesskey="&contextArchive.accesskey;"
+ oncommand="MsgArchiveSelectedMessages(event);"/>
+ <menu id="mailContext-moveMenu"
+ label="&contextMoveMsgMenu.label;"
+ accesskey="&contextMoveMsgMenu.accesskey;"
+ oncommand="MsgMoveMessage(event.target._folder)">
+ <menupopup id="mailContext-fileHereMenu"
+ type="folder"
+ mode="filing"
+ showFileHereLabel="true"
+ showRecent="true"
+ fileHereLabel="&fileHereMenu.label;"
+ fileHereAccessKey="&fileHereMenu.accesskey;"
+ recentLabel="&contextMoveCopyMsgRecentMenu.label;"
+ recentAccessKey="&contextMoveCopyMsgRecentMenu.accesskey;"/>
+ </menu>
+ <menu id="mailContext-copyMenu"
+ label="&contextCopyMsgMenu.label;"
+ accesskey="&contextCopyMsgMenu.accesskey;"
+ oncommand="MsgCopyMessage(event.target._folder)">
+ <menupopup id="mailContext-copyHereMenu"
+ type="folder"
+ mode="filing"
+ showFileHereLabel="true"
+ showRecent="true"
+ fileHereLabel="©HereMenu.label;"
+ fileHereAccessKey="©HereMenu.accesskey;"
+ recentLabel="&contextMoveCopyMsgRecentMenu.label;"
+ recentAccessKey="&contextMoveCopyMsgRecentMenu.accesskey;"/>
+ </menu>
+ <menuitem id="mailContext-moveToFolderAgain"
+ command="cmd_moveToFolderAgain"
+ label="&moveToFolderAgain.label;"
+ accesskey="&moveToFolderAgain.accesskey;"/>
+ <menuseparator id="paneContext-afterMove"/>
+ <menuitem id="mailContext-ignoreThread"
+ label="&contextKillThreadMenu.label;"
+ accesskey="&contextKillThreadMenu.accesskey;"
+ command="cmd_killThread"/>
+ <menuitem id="mailContext-ignoreSubthread"
+ label="&contextKillSubthreadMenu.label;"
+ command="cmd_killSubthread"/>
+ <menuitem id="mailContext-watchThread"
+ label="&contextWatchThreadMenu.label;"
+ command="cmd_watchThread"/>
+ <menuseparator id="mailContext-afterWatchThread"/>
+ <menuitem id="mailContext-saveAs"
+ label="&contextSaveAs.label;"
+ accesskey="&contextSaveAs.accesskey;"
+ oncommand="MsgSaveAsFile();"/>
+ <menuitem id="mailContext-printpreview"
+ label="&contextPrintPreview.label;"
+ accesskey="&contextPrintPreview.accesskey;"
+ observes="cmd_printpreview"
+ command="cmd_printpreview"/>
+ <menuitem id="mailContext-print"
+ label="&contextPrint.label;"
+ accesskey="&contextPrint.accesskey;"
+ observes="cmd_print"
+ command="cmd_print"/>
+ <menuitem id="mailContext-delete"
+ command="cmd_delete"/>
+ <menuitem id="downloadSelected"
+ label="&downloadSelectedCmd.label;"
+ accesskey="&downloadSelectedCmd.accesskey;"
+ command="cmd_downloadSelected"/>
+ <menuseparator id="mailContext-sep-edit"/>
+ <menuitem id="mailContext-copylink"
+ label="©LinkCmd.label;"
+ accesskey="©LinkCmd.accesskey;"
+ command="cmd_copyLink"/>
+ <menuitem id="mailContext-copyimage"
+ label="©ImageAllCmd.label;"
+ accesskey="©ImageAllCmd.accesskey;"
+ command="cmd_copyImage"/>
+ <menuitem id="mailContext-addemail"
+ label="&AddToAddressBook.label;"
+ accesskey="&AddToAddressBook.accesskey;"
+ oncommand="addEmail();"/>
+ <menuitem id="mailContext-composeemailto"
+ label="&SendMessageTo.label;"
+ accesskey="&SendMessageTo.accesskey;"
+ oncommand="composeEmailTo();"/>
+ <menuitem id="mailContext-copyemail"
+ label="©EmailCmd.label;"
+ accesskey="©EmailCmd.accesskey;"
+ oncommand="gContextMenu.copyEmail();"/>
+ <menuseparator id="mailContext-sep-copy"/>
+ <menuitem id="mailContext-savelink"
+ label="&saveLinkAsCmd.label;"
+ accesskey="&saveLinkAsCmd.accesskey;"
+ oncommand="gContextMenu.saveLink();"/>
+ <menuitem id="mailContext-saveimage"
+ label="&saveImageAsCmd.label;"
+ accesskey="&saveImageAsCmd.accesskey;"
+ oncommand="gContextMenu.saveImage();"/>
+ <menuseparator id="mailContext-sep-reportPhishing"/>
+ <menuitem id="mailContext-reportPhishingURL"
+ label="&reportPhishingURL.label;"
+ accesskey="&reportPhishingURL.accesskey;"
+ oncommand="gPhishingDetector.reportPhishingURL(gContextMenu.linkURL);"/>
+
+ </menupopup>
+
+ <menupopup id="folderPaneContext"
+ onpopupshowing="return fillFolderPaneContextMenu();"
+ onpopuphiding="if (event.target == this) folderPaneOnPopupHiding();">
+ <menuitem id="folderPaneContext-getMessages"
+ label="&folderContextGetMessages.label;"
+ accesskey="&folderContextGetMessages.accesskey;"
+ oncommand="MsgGetMessage();"/>
+ <menuitem id="folderPaneContext-openNewTab"
+ label="&folderContextOpenNewTab.label;"
+ accesskey="&folderContextOpenNewTab.accesskey;"
+ oncommand="FolderPaneContextMenuNewTab(event);"/>
+ <menuitem id="folderPaneContext-openNewWindow"
+ label="&folderContextOpenInNewWindow.label;"
+ accesskey="&folderContextOpenInNewWindow.accesskey;"
+ oncommand="MsgOpenNewWindowForFolder(null,-1);"/>
+ <menuitem id="folderPaneContext-searchMessages"
+ label="&folderContextSearchForMessages.label;"
+ accesskey="&folderContextSearchForMessages.accesskey;"
+ oncommand="gFolderTreeController.searchMessages();"/>
+ <menuitem id="folderPaneContext-subscribe"
+ label="&folderContextSubscribe.label;"
+ accesskey="&folderContextSubscribe.accesskey;"
+ oncommand="MsgSubscribe();"/>
+ <menuitem id="folderPaneContext-newsUnsubscribe"
+ label="&folderContextUnsubscribe.label;"
+ accesskey="&folderContextUnsubscribe.accesskey;"
+ oncommand="MsgUnsubscribe();"/>
+ <menuseparator id="folderPaneContext-sep1"/>
+ <menuitem id="folderPaneContext-new"
+ label="&folderContextNew.label;"
+ accesskey="&folderContextNew.accesskey;"
+ oncommand="gFolderTreeController.newFolder();"/>
+ <menuitem id="folderPaneContext-remove"
+ label="&folderContextRemove.label;"
+ accesskey="&folderContextRemove.accesskey;"
+ oncommand="gFolderTreeController.deleteFolder();"/>
+ <menuitem id="folderPaneContext-rename"
+ label="&folderContextRename.label;"
+ accesskey="&folderContextRename.accesskey;"
+ oncommand="gFolderTreeController.renameFolder();"/>
+ <menuseparator id="folderPaneContext-sep2"/>
+ <menuitem id="folderPaneContext-compact"
+ label="&folderContextCompact.label;"
+ accesskey="&folderContextCompact.accesskey;"
+ oncommand="gFolderTreeController.compactFolders();"/>
+ <menuitem id="folderPaneContext-markMailFolderAllRead"
+ label="&folderContextMarkMailFolderRead.label;"
+ accesskey="&folderContextMarkMailFolderRead.accesskey;"
+ oncommand="MsgMarkAllRead();"/>
+ <menuitem id="folderPaneContext-markNewsgroupAllRead"
+ label="&folderContextMarkNewsgroupRead.label;"
+ accesskey="&folderContextMarkNewsgroupRead.accesskey;"
+ oncommand="MsgMarkAllRead();"/>
+ <menuitem id="folderPaneContext-emptyTrash"
+ label="&folderContextEmptyTrash.label;"
+ accesskey="&folderContextEmptyTrash.accesskey;"
+ oncommand="gFolderTreeController.emptyTrash();"/>
+ <menuitem id="folderPaneContext-emptyJunk"
+ label="&folderContextEmptyJunk.label;"
+ accesskey="&folderContextEmptyJunk.accesskey;"
+ oncommand="gFolderTreeController.emptyJunk();"/>
+ <menuitem id="folderPaneContext-sendUnsentMessages"
+ label="&folderContextSendUnsentMessages.label;"
+ accesskey="&folderContextSendUnsentMessages.accesskey;"
+ oncommand="goDoCommand('cmd_sendUnsentMsgs')"/>
+ <menuseparator id="folderPaneContext-sep3"/>
+ <menuitem id="folderPaneContext-favoriteFolder"
+ type="checkbox"
+ label="&folderContextFavoriteFolder.label;"
+ accesskey="&folderContextFavoriteFolder.accesskey;"
+ check="false"
+ oncommand="ToggleFavoriteFolderFlag();"/>
+ <menuitem id="folderPaneContext-properties"
+ label="&folderContextProperties.label;"
+ accesskey="&folderContextProperties.accesskey;"
+ oncommand="gFolderTreeController.editFolder();"/>
+ <menuitem id="folderPaneContext-settings"
+ label="&folderContextSettings.label;"
+ accesskey="&folderContextSettings.accesskey;"
+ oncommand="gFolderTreeController.editFolder();"/>
+ </menupopup>
+
+ <menupopup id="toolbar-context-menu"
+ onpopupshowing="onViewToolbarsPopupShowing(event, 'mail-toolbox');">
+ <menuseparator id="customizeMailToolbarMenuSeparator"/>
+ <menuitem id="CustomizeMailToolbar"
+ command="cmd_CustomizeMailToolbar"
+ label="&customizeToolbar.label;"
+ accesskey="&customizeToolbar.accesskey;"/>
+ </menupopup>
+
+<popupset id="mainPopupSet">
+ <menupopup id="appmenu-popup"
+ onpopupshowing="initAppMenuPopup(this, event);">
+ <hbox>
+ <vbox id="appmenuPrimaryPane">
+ <splitmenu id="appmenu_newMessage"
+ label="&appmenuNewMsgCmd.label;"
+ oncommand="MsgNewMessage(null);">
+ <menupopup id="appmenu_newMenupopup">
+ <menuitem id="newNewMsgCmd"
+ label="&newNewMsgCmd.label;"
+ key="key_newMessage2"
+ oncommand="MsgNewMessage(null);"/>
+ <menuitem id="appmenu_newFolder"
+ label="&newFolderCmd.label;"
+ oncommand="gFolderTreeController.newFolder();"/>
+ <menuitem id="appmenu_newVirtualFolder"
+ label="&newVirtualFolderCmd.label;"
+ oncommand="gFolderTreeController.newVirtualFolder();"/>
+ <menuseparator id="appmenu_newAccountPopupMenuSeparator"/>
+ <menuitem id="appmenu_newCreateEmailAccountMenuItem"
+ label="&newCreateEmailAccountCmd.label;"
+ oncommand="NewMailAccountProvisioner(msgWindow);"/>
+ <menuitem id="appmenu_newMailAccountMenuItem"
+ label="&newExistingEmailAccountCmd.label;"
+ oncommand="NewMailAccount(msgWindow);"/>
+ <menuitem id="appmenu_newIMAccountMenuItem"
+ label="&newIMAccountCmd.label;"
+ oncommand="openIMAccountWizard();"/>
+ <menuitem id="appmenu_newFeedAccountMenuItem"
+ label="&newFeedAccountCmd.label;"
+ accesskey="&newFeedAccountCmd.accesskey;"
+ oncommand="AddFeedAccount();"/>
+ <menuitem id="appmenu_newAccountMenuItem"
+ label="&newOtherAccountsCmd.label;"
+ oncommand="MsgAccountWizard();"/>
+ <menuseparator id="appmenu_newPopupMenuSeparator"/>
+ <menuitem id="appmenu_newCard"
+ label="&appmenuNewContactCmd.label;"
+ command="cmd_newCard"/>
+ <menuitem id="appmenu_newIMContactMenuItem"
+ label="&newIMContactCmd.label;"
+ oncommand="chatHandler.addBuddy();"/>
+ </menupopup>
+ </splitmenu>
+ <menu id="appmenu_msgAttachmentMenu"
+ label="&openAttachmentListCmd.label;"
+ disabled="true">
+ <menupopup id="appmenu_attachmentMenuList"
+ onpopupshowing="FillAttachmentListPopup(this);"/>
+ </menu>
+ <menuseparator class="appmenu-menuseparator"/>
+ <hbox>
+ <menuitem id="appmenu-edit-label"
+ label="&appmenuEditMenu.label;"
+ disabled="true"/>
+ <toolbarbutton id="appmenu-cut"
+ class="appmenu-edit-button"
+ command="cmd_cut"
+ onclick="if (!this.disabled) hidePopup();"
+ tooltiptext="&cutCmd.label;"/>
+ <toolbarbutton id="appmenu-copy"
+ class="appmenu-edit-button"
+ command="cmd_copy"
+ onclick="if (!this.disabled) hidePopup();"
+ tooltiptext="©Cmd.label;"/>
+ <toolbarbutton id="appmenu-paste"
+ class="appmenu-edit-button"
+ command="cmd_paste"
+ onclick="if (!this.disabled) hidePopup();"
+ tooltiptext="&pasteCmd.label;"/>
+ <spacer flex="1"/>
+ <menu id="appmenu-editmenu">
+ <menupopup id="appmenu-editmenu-menupopup">
+ <menuitem id="appmenu-editmenu-cut"
+ class="menuitem-iconic"
+ label="&cutCmd.label;"
+ key="key_cut"
+ command="cmd_cut"/>
+ <menuitem id="appmenu-editmenu-copy"
+ class="menuitem-iconic"
+ label="©Cmd.label;"
+ key="key_copy"
+ command="cmd_copy"/>
+ <menuitem id="appmenu-editmenu-paste"
+ class="menuitem-iconic"
+ label="&pasteCmd.label;"
+ key="key_paste"
+ command="cmd_paste"/>
+ <menuseparator/>
+ <menuitem id="appmenu-editmenu-undo"
+ label="&undoCmd.label;"
+ key="key_undo"
+ command="cmd_undo"/>
+ <menuitem id="appmenu-editmenu-redo"
+ label="&redoCmd.label;"
+ key="key_redo"
+ command="cmd_redo"/>
+ <menuseparator id="appmenu_messageAfterRedoEditSeparator"/>
+ <menuitem id="appmenu_delete"
+ label="&deleteCmd.label;"
+#ifdef XP_MACOSX
+ acceltext="⌫"
+#else
+ key="key_delete"
+#endif
+ command="cmd_delete"/>
+ <menuseparator id="appmenu_messageAfterDeleteEditSeparator"/>
+ <menuitem id="appmenu-editmenu-selectAll"
+ label="&selectAllCmd.label;"
+ key="key_selectAll"
+ command="cmd_selectAll"/>
+ <menuitem id="appmenu_selectThread"
+ label="&appmenuSelectThread.label;"
+ key="key_selectThread"
+ command="cmd_selectThread"/>
+ <menuitem id="appmenu_selectFlagged"
+ label="&appmenuSelectFlagged.label;"
+ command="cmd_selectFlagged"/>
+ </menupopup>
+ </menu>
+ </hbox>
+ <splitmenu id="appmenu_find"
+ label="&findMenu.label;"
+ command="cmd_find">
+ <menupopup id="appmenu_FindPopup">
+ <menuitem id="appmenu_findCmd"
+ label="&findCmd.label;"
+ key="key_find"
+ command="cmd_find"/>
+ <menuitem id="appmenu_findAgainCmd"
+ label="&findAgainCmd.label;"
+ key="key_findAgain"
+ command="cmd_findAgain"/>
+ <menuseparator id="appMenuAfterFindSeparator"/>
+ <menuitem id="appmenu_searchMailCmd"
+ label="&searchMailCmd.label;"
+ key="key_searchMail"
+ command="cmd_search"/>
+ <menuitem id="appmenu_searchAddressesCmd"
+ label="&searchAddressesCmd.label;"
+ oncommand="MsgSearchAddresses()"/>
+ </menupopup>
+ </splitmenu>
+ <splitmenu id="appmenu_print"
+ iconic="true"
+ label="&printCmd.label;"
+ key="printKb"
+ command="cmd_print">
+ <menupopup>
+ <menuitem id="appmenu_print_popup"
+ class="menuitem-iconic"
+ label="&printCmd.label;"
+ key="key_print"
+ command="cmd_print"/>
+#ifndef XP_MACOSX
+ <menuitem id="appmenu_printPreview"
+ label="&printPreviewCmd.label;"
+ command="cmd_printpreview"/>
+#endif
+ <menuitem id="appmenu_printSetup"
+ label="&printSetupCmd.label;"
+ command="cmd_printSetup"/>
+ </menupopup>
+ </splitmenu>
+ <menuseparator class="appmenu-menuseparator"/>
+ <menu id="appmenu_saveAs"
+ label="&saveAsMenu.label;">
+ <menupopup id="menu_SavePopup">
+ <menuitem id="appmenu_saveAsFile"
+ label="&saveAsFileCmd.label;"
+ key="key_saveAsFile"
+ command="cmd_saveAsFile"/>
+ <menuitem id="appmenu_saveAsTemplate"
+ label="&saveAsTemplateCmd.label;"
+ command="cmd_saveAsTemplate"/>
+ </menupopup>
+ </menu>
+ <menu id="appmenu_FolderViews"
+ label="&folderView.label;">
+ <menupopup id="appmenu_FolderViewsPopup"
+ onpopupshowing="InitAppFolderViewsMenu();
+ InitViewFolderViewsMenu(event);">
+ <menuitem id="appmenu_allFolders"
+ value="all"
+ label="&allFolders.label;"
+ type="radio"
+ name="viewmessages"
+ oncommand="gFolderTreeView.mode = this.value;"/>
+ <menuitem id="appmenu_smartFolders"
+ value="smart"
+ label="&unifiedFolders.label;"
+ type="radio"
+ name="viewmessages"
+ oncommand="gFolderTreeView.mode = this.value;"/>
+ <menuitem id="appmenu_unreadFolders"
+ label="&unreadFolders.label;"
+ value="unread"
+ type="radio"
+ name="viewmessages"
+ oncommand="gFolderTreeView.mode = this.value;"/>
+ <menuitem id="appmenu_favoriteFolders"
+ value="favorite"
+ label="&favoriteFolders.label;"
+ type="radio"
+ name="viewmessages"
+ oncommand="gFolderTreeView.mode = this.value;"/>
+ <menuitem id="appmenu_recentFolders"
+ value="recent"
+ label="&recentFolders.label;"
+ type="radio"
+ name="viewmessages"
+ oncommand="gFolderTreeView.mode = this.value;"/>
+ <menuseparator id="appmenu_favoritePropertiesSeparator"/>
+ <menuitem id="appmenu_favoriteFolder"
+ type="checkbox"
+ label="&menuFavoriteFolder.label;"
+ check="false"
+ oncommand="ToggleFavoriteFolderFlag();"/>
+ <menuitem id="appmenu_properties"
+ label="&folderPropsCmd.label;"
+ command="cmd_properties"/>
+ </menupopup>
+ </menu>
+ <menuitem id="appmenu_emptyTrash"
+ label="&emptyTrashCmd.label;"
+ command="cmd_emptyTrash"/>
+ <spacer flex="1"/>
+ <menuitem id="appmenu-quit"
+ class="menuitem-iconic"
+#ifdef XP_WIN
+ label="&quitApplicationCmd.label;"
+#else
+ label="&quitApplicationCmdUnix.label;"
+#endif
+ command="cmd_quit"/>
+ </vbox>
+ <vbox id="appmenuSecondaryPane">
+ <menuitem id="appmenu_activityManager"
+ label="&activitymanager.label;"
+ oncommand="openActivityMgr();"/>
+ <splitmenu id="appmenu_filters"
+ label="&filtersCmd.label;"
+ command="cmd_displayMsgFilters">
+ <menupopup id="appmenu_FilterMenu">
+ <menuitem id="appmenu_filtersCmd"
+ label="&filtersCmd.label;"
+ command="cmd_displayMsgFilters"/>
+ <menuitem id="applyFilters"
+ label="&filtersApply.label;"
+ command="cmd_applyFilters"/>
+ <menuitem id="applyFiltersToSelection"
+ label="&filtersApplyToMessage.label;"
+ command="cmd_applyFiltersToSelection"/>
+ </menupopup>
+ </splitmenu>
+ <spacer class="appmenuPane-spacer"/>
+ <menuitem id="appmenu_addons"
+ class="menuitem-iconic"
+ label="&addons.label;"
+ oncommand="openAddonsMgr();"/>
+ <splitmenu id="appmenu_customize"
+#ifdef XP_WIN
+ label="&preferencesCmd.label;"
+#else
+ label="&preferencesCmdUnix.label;"
+#endif
+ oncommand="openOptionsDialog();">
+ <menupopup id="appmenu_customizeMenu"
+ onpopupshowing="onViewToolbarsPopupShowing(event, 'mail-toolbox', document.getElementById('appmenu_quickFilterBar'));">
+ <menuitem id="appmenu_preferences"
+#ifdef XP_WIN
+ label="&preferencesCmd.label;"
+#else
+ label="&preferencesCmdUnix.label;"
+#endif
+ oncommand="openOptionsDialog();"/>
+ <menuitem id="appmenu_accountmgr"
+ label="&accountManagerCmd.label;"
+ oncommand="MsgAccountManager(null);"/>
+ <menuseparator/>
+ <menuitem id="appmenu_quickFilterBar"
+ type="checkbox"
+ label="&appmenuQFBMenu.label;"
+ command="cmd_toggleQuickFilterBar">
+ <observes element="qfb-show-filter-bar" attribute="checked"/>
+ </menuitem>
+ <menuitem id="appmenu_showStatusbar"
+ type="checkbox"
+ label="&showTaskbarCmd.label;"
+ oncommand="goToggleToolbar('status-bar', 'menu_showTaskbar')"
+ checked="true"/>
+ <menuseparator id="appmenu_toggleToolbarsSeparator"/>
+ <menuitem id="appmenu_toolbarLayout"
+ label="&appmenuToolbarLayout.label;"
+ command="cmd_CustomizeMailToolbar"/>
+ <menuseparator id="appmenu_paneViewSeparator"/>
+ <menu id="appmenu_MessagePaneLayout"
+ label="&messagePaneLayoutStyle.label;">
+ <menupopup id="appmenu_view_layout_popup"
+ onpopupshowing="InitViewLayoutStyleMenu(event)">
+ <menuitem id="appmenu_messagePaneClassic"
+ type="radio"
+ label="&messagePaneClassic.label;"
+ name="viewlayoutgroup"
+ command="cmd_viewClassicMailLayout"/>
+ <menuitem id="appmenu_messagePaneWide"
+ type="radio"
+ label="&messagePaneWide.label;"
+ name="viewlayoutgroup"
+ command="cmd_viewWideMailLayout"/>
+ <menuitem id="appmenu_messagePaneVertical"
+ type="radio"
+ label="&messagePaneVertical.label;"
+ name="viewlayoutgroup"
+ command="cmd_viewVerticalMailLayout"/>
+ <menuseparator id="appmenu_viewMenuAfterPaneVerticalSeparator"/>
+ <menuitem id="appmenu_showFolderPane"
+ type="checkbox"
+ label="&showFolderPaneCmd.label;"
+ command="cmd_toggleFolderPane"/>
+ <menuitem id="appmenu_showMessage"
+ type="checkbox"
+ label="&showMessageCmd.label;"
+ key="key_toggleMessagePane"
+ command="cmd_toggleMessagePane"/>
+ </menupopup>
+ </menu>
+ </menupopup>
+ </splitmenu>
+ <spacer class="appmenuPane-spacer"/>
+ <!-- File menu -->
+ <menu id="appmenu_File"
+ label="&fileMenu.label;">
+ <menupopup id="appmenu_FilePopup">
+ <menuitem id="appmenu_openMessageFileMenuitem"
+ label="&openMessageFileCmd.label;"
+ oncommand="MsgOpenFromFile();"/>
+ <menuitem id="appmenu_close"
+ label="&closeCmd.label;"
+ key="key_close"
+ command="cmd_close"/>
+ <menuseparator id="appmenu_fileMenuAfterCloseSeparator"/>
+ <menu id="appmenu_getNewMsgFor"
+ label="&getNewMsgForCmd.label;"
+ oncommand="MsgGetMessagesForAccount(event.target._folder)">
+ <menupopup type="folder"
+ mode="getMail"
+ id="appmenu_getAllNewMsgPopup"
+ expandFolders="false">
+ <menuitem id="appmenu_getnewmsgs_all_accounts"
+ label="&getAllNewMsgCmdPopupMenu.label;"
+ key="key_getAllNewMessages"
+ command="cmd_getMsgsForAuthAccounts"/>
+ <menuitem id="appmenu_getnewmsgs_current_account"
+ label="&getNewMsgCurrentAccountCmdPopupMenu.label;"
+ key="key_getNewMessages"
+ command="cmd_getNewMessages"/>
+ <menuseparator/>
+ </menupopup>
+ </menu>
+ <menuitem id="appmenu_getNextNMsgs"
+ label="&getNextNMsgCmd.label;"
+ command="cmd_getNextNMessages"/>
+ <menuitem id="appmenu_sendUnsentMsgs"
+ label="&sendUnsentCmd.label;"
+ command="cmd_sendUnsentMsgs"/>
+ <menuitem id="appmenu_subscribe"
+ label="&subscribeCmd.label;"
+ oncommand="MsgSubscribe();"/>
+ <menuseparator id="appmenu_fileMenuAfterSubscribeSeparator"/>
+ <menuitem id="appmenu_deleteFolder"
+ label="&deleteFolder.label;"
+ command="cmd_deleteFolder"/>
+ <menuitem id="appmenu_renameFolder"
+ label="&renameFolder.label;"
+ key="key_renameFolder"
+ command="cmd_renameFolder"/>
+ <menuseparator id="appmenu_fileMenuAfterRenameSeparator"/>
+ <menuitem id="appmenu_compactFolder"
+ label="&compactFolders.label;"
+ command="cmd_compactFolder"/>
+ <menuseparator id="appmenu_fileMenuAfterCompactSeparator"/>
+ <menu id="appmenu_offline"
+ label="&offlineMenu.label;">
+ <menupopup id="appmenu_OfflinePopup">
+ <menuitem id="appmenu_goOffline"
+ type="checkbox"
+ label="&offlineGoOfflineCmd.label;"
+ oncommand="MailOfflineMgr.toggleOfflineStatus();"/>
+ <menuseparator id="appmenu_offlineMenuAfterGoSeparator"/>
+ <menuitem id="appmenu_synchronizeOffline"
+ label="&synchronizeOfflineCmd.label;"
+ command="cmd_synchronizeOffline"/>
+ <menuitem id="appmenu_settingsOffline"
+ label="&settingsOfflineCmd.label;"
+ command="cmd_settingsOffline"/>
+ <menuseparator id="app_offlineMenuAfterSettingsSeparator"/>
+ <menuitem id="appmenu_downloadFlagged"
+ label="&downloadStarredCmd.label;"
+ command="cmd_downloadFlagged"/>
+ <menuitem id="appmenu_downloadSelected"
+ label="&downloadSelectedCmd.label;"
+ command="cmd_downloadSelected"/>
+ </menupopup>
+ </menu>
+ </menupopup>
+ </menu>
+ <!-- View menu -->
+ <menu id="appmenu_View"
+ label="&viewMenu.label;">
+ <menupopup id="appmenu_View_Popup">
+ <menu id="appmenu_viewSortMenu"
+ label="&sortMenu.label;">
+ <menupopup id="appmenu_viewSortPopup" onpopupshowing="InitAppViewSortByMenu()">
+ <menuitem id="appmenu_sortByDateMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortByDateCmd.label;"
+ oncommand="MsgSortThreadPane('byDate')"/>
+ <menuitem id="appmenu_sortByReceivedMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortByReceivedCmd.label;"
+ oncommand="MsgSortThreadPane('byReceived')"/>
+ <menuitem id="appmenu_sortByFlagMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortByStarCmd.label;"
+ oncommand="MsgSortThreadPane('byFlagged')"/>
+ <menuitem id="appmenu_sortByOrderReceivedMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortByOrderReceivedCmd.label;"
+ oncommand="MsgSortThreadPane('byId')"/>
+ <menuitem id="appmenu_sortByPriorityMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortByPriorityCmd.label;"
+ oncommand="MsgSortThreadPane('byPriority')"/>
+ <menuitem id="appmenu_sortByFromMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortByFromCmd.label;"
+ oncommand="MsgSortThreadPane('byAuthor')"/>
+ <menuitem id="appmenu_sortByRecipientMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortByRecipientCmd.label;"
+ oncommand="MsgSortThreadPane('byRecipient')"/>
+ <menuitem id="appmenu_sortBySizeMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortBySizeCmd.label;"
+ oncommand="MsgSortThreadPane('bySize')"/>
+ <menuitem id="appmenu_sortByStatusMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortByStatusCmd.label;"
+ oncommand="MsgSortThreadPane('byStatus')"/>
+ <menuitem id="appmenu_sortBySubjectMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortBySubjectCmd.label;"
+ oncommand="MsgSortThreadPane('bySubject')"/>
+ <menuitem id="appmenu_sortByUnreadMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortByUnreadCmd.label;"
+ oncommand="MsgSortThreadPane('byUnread')"/>
+ <menuitem id="appmenu_sortByTagsMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortByTagsCmd.label;"
+ oncommand="MsgSortThreadPane('byTags')"/>
+ <menuitem id="appmenu_sortByJunkStatusMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortByJunkStatusCmd.label;"
+ oncommand="MsgSortThreadPane('byJunkStatus')"/>
+ <menuitem id="appmenu_sortByAttachmentsMenuitem"
+ type="radio"
+ name="sortby"
+ label="&sortByAttachmentsCmd.label;"
+ oncommand="MsgSortThreadPane('byAttachments')"/>
+ <menuseparator id="appmenu_sortAfterAttachmentSeparator"/>
+ <menuitem id="appmenu_sortAscending"
+ type="radio"
+ name="sortdirection"
+ label="&sortAscending.label;"
+ oncommand="MsgSortAscending()"/>
+ <menuitem id="appmenu_sortDescending"
+ type="radio"
+ name="sortdirection"
+ label="&sortDescending.label;"
+ oncommand="MsgSortDescending()"/>
+ <menuseparator id="appmenu_sortAfterDescendingSeparator"/>
+ <menuitem id="appmenu_sortThreaded"
+ type="radio"
+ name="threaded"
+ label="&sortThreaded.label;"
+ oncommand="MsgSortThreaded();"/>
+ <menuitem id="appmenu_sortUnthreaded"
+ type="radio"
+ name="threaded"
+ label="&sortUnthreaded.label;"
+ oncommand="MsgSortUnthreaded();"/>
+ <menuitem id="appmenu_groupBySort"
+ type="radio"
+ name="group"
+ label="&groupBySort.label;"
+ oncommand="MsgGroupBySort();"/>
+ </menupopup>
+ </menu>
+ <menu id="appmenu_viewMessageViewMenu"
+ label="&msgsMenu.label;"
+ command="mailHideMenus"
+ oncommand="ViewChangeByMenuitem(event.target);">
+ <menupopup id="appmenu_viewMessagePopup"
+ onpopupshowing="RefreshViewPopup(this, false);">
+ <menuitem id="appmenu_viewMessageAll"
+ value="0"
+ type="radio"
+ label="&viewAll.label;"/>
+ <menuitem id="appmenu_viewMessageUnread"
+ value="1"
+ type="radio"
+ label="&viewUnread.label;"/>
+ <menuitem id="appmenu_viewMessageNotDeleted"
+ value="3"
+ type="radio"
+ label="&viewNotDeleted.label;"/>
+ <menuseparator id="appmenu_messageViewAfterUnreadSeparator"/>
+ <menu id="viewMessageTags"
+ label="&viewTags.label;">
+ <menupopup id="appmenu_viewMessageTagsPopup"
+ onpopupshowing="RefreshTagsPopup(this, false);"/>
+ </menu>
+ <menu id="appmenu_viewMessageCustomViews"
+ label="&viewCustomViews.label;">
+ <menupopup id="appmenu_viewMessageCustomViewsPopup"
+ onpopupshowing="RefreshCustomViewsPopup(this, false);"/>
+ </menu>
+ <menuseparator id="appmenu_messageViewAfterCustomSeparator"/>
+ <menuitem id="appmenu_viewMessageVirtualFolder"
+ value="7"
+ label="&viewVirtualFolder.label;"/>
+ <menuitem id="appmenu_viewMessageCustomize"
+ value="8"
+ label="&viewCustomizeView.label;"/>
+ </menupopup>
+ </menu>
+ <menu label="&threads.label;"
+ id="appmenu_viewMessagesMenu">
+ <menupopup id="appmenu_ThreadsPopup"
+ onpopupshowing="InitAppmenuViewMessagesMenu()">
+ <menuitem id="appmenu_viewAllMessagesMenuItem"
+ type="radio"
+ name="viewmessages"
+ label="&allMsgsCmd.label;"
+ disabled="true"
+ command="cmd_viewAllMsgs"/>
+ <menuitem id="appmenu_viewUnreadMessagesMenuItem"
+ type="radio"
+ name="viewmessages"
+ label="&unreadMsgsCmd.label;"
+ disabled="true"
+ command="cmd_viewUnreadMsgs"/>
+ <menuitem id="appmenu_viewThreadsWithUnreadMenuItem"
+ type="radio"
+ name="viewmessages"
+ label="&threadsWithUnreadCmd.label;"
+ disabled="true"
+ command="cmd_viewThreadsWithUnread"/>
+ <menuitem id="appmenu_viewWatchedThreadsWithUnreadMenuItem"
+ type="radio"
+ name="viewmessages"
+ label="&watchedThreadsWithUnreadCmd.label;"
+ disabled="true"
+ command="cmd_viewWatchedThreadsWithUnread"/>
+ <menuseparator id="appmenu_threadsAfterWatchedSeparator"/>
+ <menuitem id="appmenu_viewIgnoredThreadsMenuItem"
+ type="checkbox"
+ label="&ignoredThreadsCmd.label;"
+ disabled="true"
+ command="cmd_viewIgnoredThreads"/>
+ <menuseparator id="appmenu_threadsAfterIgnoredSeparator"/>
+ <menuitem id="appmenu_expandAllThreads"
+ label="&expandAllThreadsCmd.label;"
+ key="key_expandAllThreads"
+ disabled="true"
+ command="cmd_expandAllThreads"/>
+ <menuitem id="appmenu_collapseAllThreads"
+ label="&collapseAllThreadsCmd.label;"
+ key="key_collapseAllThreads"
+ disabled="true"
+ command="cmd_collapseAllThreads"/>
+ </menupopup>
+ </menu>
+ <menuseparator id="appmenu_viewAfterThreadsSeparator"/>
+ <menu id="appmenu_viewHeadersMenu"
+ label="&headersMenu.label;">
+ <menupopup id="appmenu_HeadersPopup" onpopupshowing="InitViewHeadersMenu();">
+ <menuitem id="appmenu_viewallheaders"
+ type="radio"
+ name="viewheadergroup"
+ label="&headersAllCmd.label;"
+ command="cmd_viewAllHeader"/>
+ <menuitem id="appmenu_viewnormalheaders"
+ type="radio"
+ name="viewheadergroup"
+ label="&headersNormalCmd.label;"
+ command="cmd_viewNormalHeader"/>
+ </menupopup>
+ </menu>
+ <menu id="appmenu_viewBodyMenu"
+ label="&bodyMenu.label;">
+ <menupopup id="appmenu_viewBodyPopMenu"
+ onpopupshowing="InitAppmenuViewBodyMenu()">
+ <menuitem id="appmenu_bodyAllowHTML"
+ type="radio"
+ name="bodyPlaintextVsHTMLPref"
+ label="&bodyAllowHTML.label;"
+ oncommand="MsgBodyAllowHTML()"/>
+ <menuitem id="appmenu_bodySanitized"
+ type="radio"
+ name="bodyPlaintextVsHTMLPref"
+ label="&bodySanitized.label;"
+ oncommand="MsgBodySanitized()"/>
+ <menuitem id="appmenu_bodyAsPlaintext"
+ type="radio"
+ name="bodyPlaintextVsHTMLPref"
+ label="&bodyAsPlaintext.label;"
+ oncommand="MsgBodyAsPlaintext()"/>
+ <menuitem id="appmenu_bodyAllParts"
+ type="radio"
+ name="bodyPlaintextVsHTMLPref"
+ label="&bodyAllParts.label;"
+ oncommand="MsgBodyAllParts()"/>
+ </menupopup>
+ </menu>
+ <menu id="appmenu_viewFeedSummary"
+ label="&bodyMenuFeed.label;">
+ <menupopup id="appmenu_viewFeedSummaryPopupMenu"
+ onpopupshowing="InitAppmenuViewBodyMenu()">
+ <menuitem id="appmenu_bodyFeedGlobalWebPage"
+ type="radio"
+ name="viewFeedSummaryGroup"
+ label="&viewFeedWebPage.label;"
+ observes="bodyFeedGlobalWebPage"
+ oncommand="FeedMessageHandler.onSelectPref = 0"/>
+ <menuitem id="appmenu_bodyFeedGlobalSummary"
+ type="radio"
+ name="viewFeedSummaryGroup"
+ label="&viewFeedSummary.label;"
+ observes="bodyFeedGlobalSummary"
+ oncommand="FeedMessageHandler.onSelectPref = 1"/>
+ <menuitem id="appmenu_bodyFeedPerFolderPref"
+ type="radio"
+ name="viewFeedSummaryGroup"
+ label="&viewFeedSummaryFeedPropsPref.label;"
+ observes="bodyFeedPerFolderPref"
+ oncommand="FeedMessageHandler.onSelectPref = 2"/>
+ <menuseparator id="appmenu_viewFeedSummarySeparator"/>
+ <menuitem id="appmenu_bodyFeedSummaryAllowHTML"
+ type="radio"
+ name="viewFeedBodyHTMLGroup"
+ label="&bodyAllowHTML.label;"
+ oncommand="MsgFeedBodyRenderPrefs(false, 0, 0)"/>
+ <menuitem id="appmenu_bodyFeedSummarySanitized"
+ type="radio"
+ name="viewFeedBodyHTMLGroup"
+ label="&bodySanitized.label;"
+ oncommand="MsgFeedBodyRenderPrefs(false, 3, gDisallow_classes_no_html)"/>
+ <menuitem id="appmenu_bodyFeedSummaryAsPlaintext"
+ type="radio"
+ name="viewFeedBodyHTMLGroup"
+ label="&bodyAsPlaintext.label;"
+ oncommand="MsgFeedBodyRenderPrefs(true, 1, gDisallow_classes_no_html)"/>
+ </menupopup>
+ </menu>
+ <menuitem id="appmenu_viewAttachmentsInlineMenuitem"
+ label="&viewAttachmentsInlineCmd.label;"
+ oncommand="ToggleInlineAttachment(event.target)"
+ type="checkbox"
+ checked="true"/>
+ <menuseparator id="appmenu_viewAfterAttachmentsSeparator"/>
+ <menu id="appmenu_viewFullZoomMenu"
+ label="&fullZoom.label;"
+ onpopupshowing="UpdateFullZoomMenu()">
+ <menupopup id="appmenu_viewFullZoomPopupMenu">
+ <menuitem id="appmenu_fullZoomEnlarge"
+ label="&fullZoomEnlargeCmd.label;"
+ key="key_fullZoomEnlarge"
+ command="cmd_fullZoomEnlarge"/>
+ <menuitem id="appmenu_fullZoomReduce"
+ label="&fullZoomReduceCmd.label;"
+ key="key_fullZoomReduce"
+ command="cmd_fullZoomReduce"/>
+ <menuseparator id="appmenu_fullZoomAfterReduceSeparator"/>
+ <menuitem id="appmenu_fullZoomReset"
+ label="&fullZoomResetCmd.label;"
+ key="key_fullZoomReset"
+ command="cmd_fullZoomReset"/>
+ <menuseparator id="appmenu_fullZoomAfterResetSeparator"/>
+ <menuitem id="appmenu_fullZoomToggle"
+ label="&fullZoomToggleCmd.label;"
+ type="checkbox"
+ command="cmd_fullZoomToggle"
+ checked="false"/>
+ </menupopup>
+ </menu>
+ <menu id="appmenu_charsetMenu"
+ label="&charsetMenu.label;"
+ datasources="rdf:charset-menu"
+ ref="NC:MailviewCharsetMenuRoot"
+ oncommand="MailMultiplexHandler(event)"
+ onpopupshowing="CreateMenu('mailview');UpdateMailMenus()"
+ onpopupshown="CreateMenu('more-menu');"
+ observes="isImage">
+ <template>
+ <rule rdf:type="http://home.netscape.com/NC-rdf#BookmarkSeparator">
+ <menupopup>
+ <menuseparator uri="..." />
+ </menupopup>
+ </rule>
+ <rule>
+ <menupopup>
+ <menuitem type="radio" name="charsetGroup" checked="rdf:http://home.netscape.com/NC-rdf#Checked" uri="..." label="rdf:http://home.netscape.com/NC-rdf#Name"/>
+ </menupopup>
+ </rule>
+ </template>
+ <menupopup>
+ <menu label="&charsetMenuAutodet.label;"
+ datasources="rdf:charset-menu" ref="NC:BrowserAutodetMenuRoot">
+ <template>
+ <rule rdf:type="http://home.netscape.com/NC-rdf#CharsetDetector">
+ <menupopup>
+ <menuitem type="radio" name="detectorGroup" checked="rdf:http://home.netscape.com/NC-rdf#Checked" uri="..." label="rdf:http://home.netscape.com/NC-rdf#Name"/>
+ </menupopup>
+ </rule>
+ </template>
+ <menupopup>
+ </menupopup>
+ </menu>
+ <menu label="&charsetMenuMore.label;"
+ datasources="rdf:charset-menu" ref="NC:BrowserMoreCharsetMenuRoot">
+ <template>
+ <rule>
+ <menupopup>
+ <menuitem uri="..." label="rdf:http://home.netscape.com/NC-rdf#Name"/>
+ </menupopup>
+ </rule>
+ </template>
+ <menupopup>
+ <menu label="&charsetMenuMore1.label;"
+ datasources="rdf:charset-menu" ref="NC:BrowserMore1CharsetMenuRoot">
+ <template>
+ <rule>
+ <menupopup>
+ <menuitem uri="..." label="rdf:http://home.netscape.com/NC-rdf#Name"/>
+ </menupopup>
+ </rule>
+ </template>
+ <menupopup>
+ </menupopup>
+ </menu>
+ <menu label="&charsetMenuMore2.label;"
+ datasources="rdf:charset-menu" ref="NC:BrowserMore2CharsetMenuRoot">
+ <template>
+ <rule>
+ <menupopup>
+ <menuitem uri="..." label="rdf:http://home.netscape.com/NC-rdf#Name"/>
+ </menupopup>
+ </rule>
+ </template>
+ <menupopup>
+ </menupopup>
+ </menu>
+ <menu label="&charsetMenuMore3.label;"
+ datasources="rdf:charset-menu" ref="NC:BrowserMore3CharsetMenuRoot">
+ <template>
+ <rule>
+ <menupopup>
+ <menuitem uri="..." label="rdf:http://home.netscape.com/NC-rdf#Name"/>
+ </menupopup>
+ </rule>
+ </template>
+ <menupopup>
+ </menupopup>
+ </menu>
+ <menu label="&charsetMenuMore4.label;"
+ datasources="rdf:charset-menu" ref="NC:BrowserMore4CharsetMenuRoot">
+ <template>
+ <rule>
+ <menupopup>
+ <menuitem uri="..." label="rdf:http://home.netscape.com/NC-rdf#Name"/>
+ </menupopup>
+ </rule>
+ </template>
+ <menupopup>
+ </menupopup>
+ </menu>
+ <menu label="&charsetMenuMore5.label;"
+ datasources="rdf:charset-menu" ref="NC:BrowserMore5CharsetMenuRoot">
+ <template>
+ <rule>
+ <menupopup>
+ <menuitem uri="..." label="rdf:http://home.netscape.com/NC-rdf#Name"/>
+ </menupopup>
+ </rule>
+ </template>
+ <menupopup>
+ </menupopup>
+ </menu>
+ <menuseparator />
+ </menupopup>
+ </menu>
+ <menuitem name="charsetCustomize"
+ label="&charsetCustomize.label;"
+ oncommand="window.openDialog('chrome://global/content/customizeCharset.xul', 'PrefWindow', 'chrome,modal=yes,resizable=yes', 'browser');"/>
+ </menupopup>
+ </menu>
+ <menuseparator id="appmenu_viewAfterCharsetSeparator"/>
+ <menuitem id="appmenu_pageSourceMenuItem"
+ label="&pageSourceCmd.label;"
+ key="key_viewPageSource"
+ command="cmd_viewPageSource"/>
+ </menupopup>
+ </menu>
+ <!-- Go menu -->
+ <menu id="appmenu_Go"
+ label="&goMenu.label;">
+ <menupopup id="appmenu_GoPopup">
+ <menu id="appmenu_goNextMenu"
+ label="&nextMenu.label;">
+ <menupopup id="appmenu_GoNextPopup">
+ <menuitem id="appmenu_nextMsg"
+ label="&nextMsgCmd.label;"
+ key="key_nextMsg"
+ command="cmd_nextMsg"/>
+ <menuitem id="appmenu_nextUnreadMsg"
+ label="&nextUnreadMsgCmd.label;"
+ key="key_nextUnreadMsg"
+ command="cmd_nextUnreadMsg"/>
+ <menuitem id="appmenu_nextFlaggedMsg"
+ label="&nextStarredMsgCmd.label;"
+ command="cmd_nextFlaggedMsg"/>
+ <menuseparator id="appmenu_goNextAfterFlaggedSeparator"/>
+ <menuitem id="appmenu_nextUnreadThread"
+ label="&nextUnreadThread.label;"
+ key="key_nextUnreadThread"
+ command="cmd_nextUnreadThread"/>
+ </menupopup>
+ </menu>
+ <menu id="appmenu_goPreviousMenu"
+ label="&prevMenu.label;">
+ <menupopup id="appmenu_GoPreviousPopup">
+ <menuitem id="appmenu_prevMsg"
+ label="&prevMsgCmd.label;"
+ key="key_previousMsg"
+ command="cmd_previousMsg"/>
+ <menuitem id="appmenu_prevUnreadMsg"
+ label="&prevUnreadMsgCmd.label;"
+ key="key_previousUnreadMsg"
+ command="cmd_previousUnreadMsg"/>
+ <menuitem id="appmenu_prevFlaggedMsg"
+ label="&prevStarredMsgCmd.label;"
+ command="cmd_previousFlaggedMsg"/>
+ </menupopup>
+ </menu>
+ <menuitem id="appmenu_goForward"
+ label="&goForwardCmd.label;"
+ key="key_goForward"
+ command="cmd_goForward"/>
+ <menuitem id="appmenu_goBack"
+ label="&goBackCmd.label;"
+ key="key_goBack"
+ command="cmd_goBack"/>
+ <menuseparator id="appmenu_goNextSeparator"/>
+ <menuitem id="appmenu_goChat"
+ label="&goChatCmd.label;"
+ key="key_goChat"
+ command="cmd_chat"/>
+ <menuseparator id="appmenu_goChatSeparator"/>
+ <menu id="appmenu_goFolderMenu"
+ label="&folderMenu.label;"
+ oncommand="gFolderTreeView.selectFolder(event.target._folder, true)">
+ <menupopup id="appmenu_GoFolderPopup"
+ type="folder"
+ showFileHereLabel="true"
+ fileHereLabel="&thisFolder.label;"
+ showRecent="true"
+ recentLabel="&contextMoveCopyMsgRecentMenu.label;"/>
+ </menu>
+ <menuseparator id="appmenu_goFolderSeparator"/>
+ <menu id="appmenu_goRecentlyClosedTabs"
+ label="&goRecentlyClosedTabs.label;"
+ observes="cmd_undoCloseTab">
+ <menupopup id="appmenu_GoRecentlyClosedTabsPopup"
+ onpopupshowing="return InitRecentlyClosedTabsPopup(this)" />
+ </menu>
+ <menuseparator id="appmenu_goRecentlyClosedTabsSeparator"/>
+ <menuitem id="appmenu_goStartPage"
+ label="&startPageCmd.label;"
+ key="key_goStartPage"
+ command="cmd_goStartPage"/>
+ </menupopup>
+ </menu>
+ <!-- Message menu -->
+ <menu id="appmenu_messageMenu"
+ label="&msgMenu.label;">
+ <menupopup id="appmenu_messageMenuPopup"
+ onpopupshowing="InitAppMessageMenu();">
+ <menuitem id="appmenu_newMsgCmd"
+ label="&newMsgCmd.label;"
+ key="key_newMessage2"
+ oncommand="MsgNewMessage(null);"/>
+ <menuitem id="appmenu_replyMainMenu"
+ label="&replyMsgCmd.label;"
+ key="key_reply"
+ command="cmd_reply"/>
+ <menuitem id="appmenu_replyNewsgroupMainMenu"
+ label="&replyNewsgroupCmd2.label;"
+ key="key_reply"
+ command="cmd_replyGroup"/>
+ <menuitem id="appmenu_replySenderMainMenu"
+ label="&replySenderCmd.label;"
+ command="cmd_replySender"/>
+ <menuitem id="appmenu_replyToAll"
+ label="&replyToAllMsgCmd.label;"
+ key="key_replyall"
+ command="cmd_replyall"/>
+ <menuitem id="appmenu_replyToList"
+ label="&replyToListMsgCmd.label;"
+ key="key_replylist"
+ command="cmd_replylist"/>
+ <menuitem id="appmenu_forwardMsg"
+ label="&forwardMsgCmd.label;"
+ key="key_forward"
+ command="cmd_forward"/>
+ <menu id="appmenu_forwardAsMenu"
+ label="&forwardAsMenu.label;">
+ <menupopup id="appmenu_forwardAsPopup">
+ <menuitem id="appmenu_forwardAsInline"
+ label="&forwardAsInline.label;"
+ command="cmd_forwardInline"/>
+ <menuitem id="appmenu_forwardAsAttachment"
+ label="&forwardAsAttachmentCmd.label;"
+ command="cmd_forwardAttachment"/>
+ </menupopup>
+ </menu>
+ <menuitem id="appmenu_editMsgAsNew"
+ label="&editMsgAsNewCmd.label;"
+ key="key_editAsNew"
+ command="cmd_editAsNew"/>
+ <menuseparator id="appmenu_messageMenuAfterCompositionCommandsSeparator"/>
+ <menuitem id="appmenu_openMessageWindowMenuitem"
+ label="&openMessageWindowCmd.label;"
+ key="key_openMessage"
+ command="cmd_openMessage"/>
+ <menuitem id="appmenu_openConversationMenuitem"
+ label="&openConversationCmd.label;"
+ key="key_openConversation"
+ command="cmd_openConversation"/>
+ <menu id="appmenu_openFeedMessage"
+ label="&openFeedMessage1.label;">
+ <menupopup id="appmenu_openFeedMessagePopup">
+ <menuitem id="appmenu_openFeedWebPage"
+ type="radio"
+ name="openFeedGroup"
+ label="&openFeedWebPage.label;"
+ oncommand="FeedMessageHandler.onOpenPref = 0"/>
+ <menuitem id="appmenu_openFeedSummary"
+ type="radio"
+ name="openFeedGroup"
+ label="&openFeedSummary.label;"
+ oncommand="FeedMessageHandler.onOpenPref = 1"/>
+ <menuitem id="appmenu_openFeedWebPageInMessagePane"
+ type="radio"
+ name="openFeedGroup"
+ label="&openFeedWebPageInMP.label;"
+ oncommand="FeedMessageHandler.onOpenPref = 2"/>
+ </menupopup>
+ </menu>
+ <menuseparator id="appmenu_messageAfterOpenMsgSeparator"/>
+ <menu id="appmenu_tagMenu"
+ label="&tagMenu.label;"
+ command="cmd_tag">
+ <menupopup id="appmenu_tagMenu-tagpopup"
+ onpopupshowing="InitMessageTags(this);">
+ <menuitem id="appmenu_addNewTag"
+ label="&addNewTag.label;"
+ command="cmd_addTag"/>
+ <menuitem id="appmenu_manageTags"
+ label="&manageTags.label;"
+ command="cmd_manageTags"/>
+ <menuseparator id="appmenu_tagMenu-sep-afterTagAddNew"/>
+ <menuitem id="appmenu_tagMenu-tagRemoveAll"
+ command="cmd_removeTags"/>
+ <menuseparator id="appmenu_tagMenuAfterRemoveSeparator"/>
+ </menupopup>
+ </menu>
+ <menu id="appmenu_markMenu"
+ label="&markMenu.label;">
+ <menupopup id="appmenu_MarkPopup"
+ onpopupshowing="InitMessageMark()">
+ <menuitem id="appmenu_markReadMenuItem"
+ label="&markAsReadCmd.label;"
+ command="cmd_markAsRead"/>
+ <menuitem id="appmenu_markUnreadMenuItem"
+ label="&markAsUnreadCmd.label;"
+ command="cmd_markAsUnread"/>
+ <menuitem id="appmenu_markThreadAsRead"
+ label="&markThreadAsReadCmd.label;"
+ key="key_markThreadAsRead"
+ command="cmd_markThreadAsRead"/>
+ <menuitem id="appmenu_markReadByDate"
+ label="&markReadByDateCmd.label;"
+ key="key_markReadByDate"
+ command="cmd_markReadByDate"/>
+ <menuitem id="appmenu_markAllRead"
+ label="&markAllReadCmd.label;"
+ key="key_markAllRead"
+ command="cmd_markAllRead"/>
+ <menuseparator id="markMenuAfterAllReadSeparator"/>
+ <menuitem id="appmenu_markFlaggedMenuItem"
+ type="checkbox"
+ label="&markStarredCmd.label;"
+ key="key_toggleFlagged"
+ command="cmd_markAsFlagged"/>
+ <menuseparator id="markMenuAfterFlaggedSeparator"/>
+ <menuitem id="appmenu_markAsJunk"
+ label="&markAsJunkCmd.label;"
+ key="key_markJunk"
+ command="cmd_markAsJunk"/>
+ <menuitem id="appmenu_markAsNotJunk"
+ label="&markAsNotJunkCmd.label;"
+ key="key_markNotJunk"
+ command="cmd_markAsNotJunk"/>
+ <menuitem id="appmenu_recalculateJunkScore"
+ label="&recalculateJunkScoreCmd.label;"
+ command="cmd_recalculateJunkScore"/>
+ </menupopup>
+ </menu>
+ <menuseparator id="appmenu_messageMenuAfterMarkSeparator"/>
+ <menuitem id="appmenu_archiveMainMenu"
+ label="&archiveMsgCmd.label;"
+ key="key_archive"
+ command="cmd_archive"/>
+ <menuitem id="appmenu_cancel"
+ command="cmd_cancel"
+ label="&cancelNewsMsgCmd.label;"/>
+ <menu id="appmenu_moveMenu"
+ label="&moveMsgToMenu.label;"
+ oncommand="MsgMoveMessage(event.target._folder)">
+ <menupopup type="folder"
+ mode="filing"
+ showFileHereLabel="true"
+ showRecent="true"
+ fileHereLabel="&fileHereMenu.label;"
+ recentLabel="&moveCopyMsgRecentMenu.label;"/>
+ </menu>
+ <menu id="appmenu_copyMenu"
+ label="©MsgToMenu.label;"
+ oncommand="MsgCopyMessage(event.target._folder)">
+ <menupopup type="folder"
+ mode="filing"
+ showFileHereLabel="true"
+ showRecent="true"
+ fileHereLabel="©HereMenu.label;"
+ recentLabel="&moveCopyMsgRecentMenu.label;"/>
+ </menu>
+ <menuitem id="appmenu_moveToFolderAgain"
+ command="cmd_moveToFolderAgain"
+ key="key_moveToFolderAgain"
+ label="&moveToFolderAgain.label;"/>
+ <menuseparator id="appmenu_messageMenuAfterMoveCommandsSeparator"/>
+ <menuitem id="appmenu_createFilter"
+ label="&createFilter.label;"
+ command="cmd_createFilterFromMenu"/>
+ <menuseparator id="appmenu_threadItemsSeparator"/>
+ <menuitem label="&killThreadMenu.label;"
+ id="appmenu_killThread"
+ key="key_killThread"
+ type="checkbox"
+ command="cmd_killThread"/>
+ <menuitem label="&killSubthreadMenu.label;"
+ id="appmenu_killSubthread"
+ key="key_killSubthread"
+ type="checkbox"
+ command="cmd_killSubthread"/>
+ <menuitem label="&watchThreadMenu.label;"
+ id="appmenu_watchThread"
+ key="key_watchThread"
+ type="checkbox"
+ command="cmd_watchThread"/>
+ </menupopup>
+ </menu>
+ <!-- Tools menu -->
+ <menu id="appmenu_tasksMenu"
+ label="&tasksMenu.label;">
+ <menupopup id="appmenu_taskPopup">
+ <menuitem hidden="true"
+ id="appmenu_tasksMenuMail"
+ class="menuitem-iconic menu-iconic"
+ label="&messengerCmd.label;"
+ key="key_mail"
+ oncommand="toMessengerWindow();"/>
+ <menuitem id="appmenu_addressBook"
+ label="&addressBookCmd.label;"
+ key="key_addressbook"
+ oncommand="toOpenWindowByType('mail:addressbook', 'chrome://messenger/content/addressbook/addressbook.xul');"/>
+ <menuseparator id="devToolsSeparator"/>
+ <menuitem id="appmenu_openSavedFilesWnd"
+ label="&savedFiles.label;"
+ key="key_savedFiles"
+ oncommand="openSavedFilesWnd();"/>
+ <menu id="appmenu_imAccountsStatus"
+ label="&imAccountsStatus.label;"
+ oncommand="chatHandler.setStatusMenupopupCommand(event);">
+ <menupopup id="appmenu_imStatusMenupopup">
+ <menuitem id="appmenu_imStatusAvailable"
+ status="available"
+ label="&imStatus.available;"
+ class="menuitem-iconic"/>
+ <menuitem id="appmenu_imStatusUnavailable"
+ status="unavailable"
+ label="&imStatus.unavailable;"
+ class="menuitem-iconic"/>
+ <menuseparator id="appmenu_imStatusOfflineSeparator"/>
+ <menuitem id="appmenu_imStatusOffline"
+ status="offline"
+ label="&imStatus.offline;"
+ class="menuitem-iconic"/>
+ <menuseparator id="appmenu_imStatusShowAccountsSeparator"/>
+ <menuitem id="appmenu_imStatusShowAccounts"
+ label="&imStatus.showAccounts;"/>
+ </menupopup>
+ </menu>
+ <menuitem id="appmenu_joinChatMenuItem"
+ label="&joinChatCmd.label;"
+ oncommand="chatHandler.joinChat();"/>
+ <menuseparator id="appmenu_afterChatSeparator"/>
+ <menuitem id="appmenu_runJunkControls"
+ label="&runJunkControls.label;"
+ command="cmd_runJunkControls"/>
+ <menuitem id="appmenu_deleteJunk"
+ label="&deleteJunk.label;"
+ command="cmd_deleteJunk"/>
+ <menuseparator id="tasksMenuAfterDeleteSeparator"/>
+ <menuitem id="appmenu_import"
+ label="&importCmd.label;"
+ oncommand="toImport();"/>
+ <menuitem id="appmenu_javascriptConsole"
+ label="&errorConsoleCmd.label;"
+ key="key_errorConsole"
+ oncommand="toJavaScriptConsole();"/>
+ <menuitem id="appmenu_sanitizeHistory"
+ label="&clearRecentHistory.label;"
+ oncommand="toSanitize();"/>
+ </menupopup>
+ </menu>
+ <!-- Help menu -->
+ <splitmenu id="appmenu_help"
+ label="&helpMenuWin.label;"
+ oncommand="openSupportURL();">
+ <menupopup id="appmenu_helpMenupopup">
+ <menuitem id="appmenu_openHelp"
+ label="&openHelp.label;"
+ key="key_openHelp"
+ oncommand="openSupportURL();"/>
+ <menuitem id="appmenu_whatsNew"
+ label="&whatsNewCmd.label;"
+ oncommand="openWhatsNew();"/>
+ <menuitem id="appmenu_releaseNotes"
+ label="&releaseCmd2.label;"
+ oncommand="openFormattedURL('app.releaseNotesURL');"/>
+ <menuseparator/>
+ <menuitem id="appmenu_troubleshootingInfo"
+ label="&helpTroubleshootingInfo.label;"
+ oncommand="AboutSupportOverlay.openInNewTab();"/>
+ <menuseparator/>
+ <menuitem id="appmenu_safeMode"
+ label="&helpSafeMode.label;"
+ oncommand="safeModeRestart();"/>
+ <menuseparator/>
+ <menuitem id="appmenu_about"
+ label="&aboutMenuCmd.label;"
+ oncommand="openAboutDialog();"/>
+ </menupopup>
+ </splitmenu>
+ </vbox>
+ </hbox>
+ </menupopup>
+</popupset>
+
+<!-- The reason we put the menubar inside a toolbox is due to the labelalign and
+ defaultlabelalign attributes that the toolbars might expect from their
+ parent toolboxes. This lets us control how toolbar buttons appear in the
+ toolbars by default.
+
+ We also put the toolbars inside a toolbox named "navigation-toolbox" to
+ leverage overlays, since we currently have several windows (3pane,
+ message reader, compose, address book) that take advantage of these
+ toolbars.
+-->
+<toolbox id="navigation-toolbox" class="toolbox-top" labelalign="end" defaultlabelalign="end">
+ <!-- Menu -->
+ <toolbar type="menubar" id="mail-toolbar-menubar2" class="chromeclass-menubar" customizable="true"
+ toolboxid="mail-toolbox"
+#ifdef XP_MACOSX
+ defaultset="menubar-items"
+#else
+ defaultset="menubar-items,spring"
+#endif
+#ifndef XP_MACOSX
+ toolbarname="&menubarCmd.label;"
+ accesskey="&menubarCmd.accesskey;"
+#endif
+ context="toolbar-context-menu" mode="icons"
+ insertbefore="tabs-toolbar">
+ <toolbaritem id="menubar-items" align="center">
+ <menubar id="mail-menubar" style="border:0px;padding:0px;margin:0px;-moz-appearance:none">
+ <!-- File -->
+ <menu id="menu_File">
+ <menupopup id="menu_FilePopup" onpopupshowing="file_init();">
+ <menu id="menu_New">
+ <menupopup id="menu_NewPopup" onpopupshowing="menu_new_init();">
+ <menuitem id="newNewMsgCmd" label="&newNewMsgCmd.label;"
+ accesskey="&newNewMsgCmd.accesskey;"
+ key="key_newMessage2"
+ oncommand="MsgNewMessage(null);"/>
+ <menuitem id="menu_newFolder" label="&newFolderCmd.label;"
+ oncommand="gFolderTreeController.newFolder();"
+ accesskey="&newFolderCmd.accesskey;"/>
+ <menuitem id="menu_newVirtualFolder" label="&newVirtualFolderCmd.label;"
+ oncommand="gFolderTreeController.newVirtualFolder();"
+ accesskey="&newVirtualFolderCmd.accesskey;"/>
+ <menuseparator id="newAccountPopupMenuSeparator"/>
+ <menuitem id="newCreateEmailAccountMenuItem"
+ label="&newCreateEmailAccountCmd.label;"
+ accesskey="&newCreateEmailAccountCmd.accesskey;"
+ oncommand="NewMailAccountProvisioner(msgWindow);"/>
+ <menuitem id="newMailAccountMenuItem"
+ label="&newExistingEmailAccountCmd.label;"
+ accesskey="&newExistingEmailAccountCmd.accesskey;"
+ oncommand="NewMailAccount(msgWindow);"/>
+ <menuitem id="newIMAccountMenuItem"
+ label="&newIMAccountCmd.label;"
+ accesskey="&newIMAccountCmd.accesskey;"
+ oncommand="openIMAccountWizard();"/>
+ <menuitem id="newFeedAccountMenuItem"
+ label="&newFeedAccountCmd.label;"
+ accesskey="&newFeedAccountCmd.accesskey;"
+ oncommand="AddFeedAccount();"/>
+ <menuitem id="newAccountMenuItem"
+ label="&newOtherAccountsCmd.label;"
+ accesskey="&newOtherAccountsCmd.accesskey;"
+ oncommand="MsgAccountWizard();"/>
+ <menuseparator id="newPopupMenuSeparator"/>
+ <menuitem id="menu_newCard"/>
+ <menuitem id="newIMContactMenuItem"
+ label="&newIMContactCmd.label;"
+ accesskey="&newIMContactCmd.accesskey;"
+ oncommand="chatHandler.addBuddy();"/>
+ </menupopup>
+ </menu>
+ <menuitem id="openMessageFileMenuitem" label="&openMessageFileCmd.label;"
+ accesskey="&openMessageFileCmd.accesskey;"
+ oncommand="MsgOpenFromFile();"/>
+ <menuitem id="menu_close"/>
+ <menuseparator id="fileMenuAfterCloseSeparator"/>
+ <menu id="menu_saveAs" label="&saveAsMenu.label;" accesskey="&saveAsMenu.accesskey;">
+ <menupopup id="menu_SavePopup">
+ <menuitem id="menu_saveAsFile" label="&saveAsFileCmd.label;"
+ accesskey="&saveAsFileCmd.accesskey;"
+ key="key_saveAsFile"
+ command="cmd_saveAsFile"/>
+ <menuitem id="menu_saveAsTemplate" label="&saveAsTemplateCmd.label;"
+ accesskey="&saveAsTemplateCmd.accesskey;"
+ command="cmd_saveAsTemplate"/>
+ </menupopup>
+ </menu>
+ <menuseparator id="fileMenuAfterSaveSeparator"/>
+ <menu label="&getNewMsgForCmd.label;" accesskey="&getNewMsgForCmd.accesskey;"
+ id="menu_getAllNewMsg"
+ oncommand="MsgGetMessagesForAccount(event.target._folder)">
+ <menupopup type="folder" mode="getMail" id="menu_getAllNewMsgPopup"
+ expandFolders="false">
+ <menuitem id="menu_getnewmsgs_all_accounts"
+ label="&getAllNewMsgCmdPopupMenu.label;"
+ accesskey="&getAllNewMsgCmdPopupMenu.accesskey;"
+ key="key_getAllNewMessages"
+ command="cmd_getMsgsForAuthAccounts"/>
+ <menuitem id="menu_getnewmsgs_current_account"
+ label="&getNewMsgCurrentAccountCmdPopupMenu.label;"
+ accesskey="&getNewMsgCurrentAccountCmdPopupMenu.accesskey;"
+ key="key_getNewMessages"
+ command="cmd_getNewMessages"/>
+ <menuseparator/>
+ </menupopup>
+ </menu>
+ <menuitem id="menu_getnextnmsg" label="&getNextNMsgCmd.label;" accesskey="&getNextNMsgCmd.accesskey;"
+ command="cmd_getNextNMessages"/>
+ <menuitem id="menu_sendunsentmsgs" label="&sendUnsentCmd.label;"
+ accesskey="&sendUnsentCmd.accesskey;" command="cmd_sendUnsentMsgs"/>
+ <menuitem id="menu_subscribe" label="&subscribeCmd.label;"
+ accesskey="&subscribeCmd.accesskey;" oncommand="MsgSubscribe();"/>
+ <menuseparator id="fileMenuAfterSubscribeSeparator"/>
+ <menuitem id="menu_deleteFolder" label="&deleteFolder.label;"
+ accesskey="&deleteFolder.accesskey;"
+ command="cmd_deleteFolder"/>
+ <menuitem id="menu_renameFolder" label="&renameFolder.label;"
+ accesskey="&renameFolder.accesskey;"
+ key="key_renameFolder"
+ command="cmd_renameFolder"/>
+ <menuitem id="menu_compactFolder"
+ label="&compactFolders.label;"
+ accesskey="&compactFolders.accesskey;"
+ command="cmd_compactFolder"/>
+ <menuitem id="menu_emptyTrash" label="&emptyTrashCmd.label;"
+ accesskey="&emptyTrashCmd.accesskey;"
+ command="cmd_emptyTrash"/>
+ <menuseparator id="trashMenuSeparator"/>
+ <menu id="offlineMenuItem" label="&offlineMenu.label;" accesskey="&offlineMenu.accesskey;">
+ <menupopup id="menu_OfflinePopup">
+ <menuitem id="goOfflineMenuItem" type="checkbox" label="&offlineGoOfflineCmd.label;"
+ accesskey="&offlineGoOfflineCmd.accesskey;" oncommand="MailOfflineMgr.toggleOfflineStatus();"/>
+ <menuseparator id="offlineMenuAfterGoSeparator"/>
+ <menuitem id="menu_synchronizeOffline"
+ label="&synchronizeOfflineCmd.label;"
+ accesskey="&synchronizeOfflineCmd.accesskey;"
+ command="cmd_synchronizeOffline"/>
+ <menuitem id="menu_settingsOffline"
+ label="&settingsOfflineCmd.label;"
+ accesskey="&settingsOfflineCmd.accesskey;"
+ command="cmd_settingsOffline"/>
+ <menuseparator id="offlineMenuAfterSettingsSeparator"/>
+ <menuitem id="menu_downloadFlagged"
+ label="&downloadStarredCmd.label;"
+ accesskey="&downloadStarredCmd.accesskey;"
+ command="cmd_downloadFlagged"/>
+ <menuitem id="menu_downloadSelected"
+ label="&downloadSelectedCmd.label;"
+ accesskey="&downloadSelectedCmd.accesskey;"
+ command="cmd_downloadSelected"/>
+ </menupopup>
+ </menu>
+ <menuseparator id="fileMenuAfterOfflineSeparator"/>
+ <menuitem id="printSetupMenuItem" label="&printSetupCmd.label;" accesskey="&printSetupCmd.accesskey;" command="cmd_printSetup"/>
+#ifndef XP_MACOSX
+ <menuitem id="printPreviewMenuItem" label="&printPreviewCmd.label;" accesskey="&printPreviewCmd.accesskey;" command="cmd_printpreview"/>
+#endif
+ <menuitem id="printMenuItem" key="key_print" label="&printCmd.label;" accesskey="&printCmd.accesskey;" command="cmd_print"/>
+ </menupopup>
+ </menu>
+
+ <!-- Edit -->
+ <menu id="menu_Edit" oncommand="CommandUpdate_UndoRedo();">
+ <menupopup id="menu_EditPopup" onpopupshowing="InitEditMessagesMenu()">
+ <menuitem id="menu_undo" label="&undoDefaultCmd.label;" accesskey="&undoDefaultCmd.accesskey;" key="key_undo" command="cmd_undo"/>
+ <menuitem id="menu_redo" label="&redoDefaultCmd.label;" accesskey="&redoDefaultCmd.accesskey;" key="key_redo" command="cmd_redo"/>
+ <menuseparator id="editMenuAfterRedoSeparator"/>
+ <menuitem id="menu_cut"/>
+ <menuitem id="menu_copy"/>
+ <menuitem id="menu_paste"/>
+ <menuitem id="menu_delete" command="cmd_delete"/>
+ <menuseparator id="editMenuAfterDeleteSeparator"/>
+ <menu id="menu_select" label="&selectMenu.label;" accesskey="&selectMenu.accesskey;">
+ <menupopup id="menu_SelectPopup">
+ <menuitem id="menu_SelectAll" label="&all.label;"
+ accesskey="&all.accesskey;" key="key_selectAll"
+ command="cmd_selectAll"/>
+ <menuseparator id="selectMenuSeparator"/>
+ <menuitem id="menu_selectThread" label="&selectThreadCmd.label;"
+ accesskey="&selectThreadCmd.accesskey;"
+ key="key_selectThread"
+ command="cmd_selectThread"/>
+ <menuitem id="menu_selectFlagged"
+ label="&selectFlaggedCmd.label;"
+ accesskey="&selectFlaggedCmd.accesskey;"
+ command="cmd_selectFlagged"/>
+ </menupopup>
+ </menu>
+ <menuseparator id="editMenuAfterSelectSeparator"/>
+ <menu id="menu_find" label="&findMenu.label;" accesskey="&findMenu.accesskey;">
+ <menupopup id="menu_FindPopup">
+ <menuitem id="menu_findCmd" label="&findCmd.label;" key="key_find" accesskey="&findCmd.accesskey;" command="cmd_find"/>
+ <menuitem id="menu_findAgainCmd" label="&findAgainCmd.label;" key="key_findAgain" accesskey="&findAgainCmd.accesskey;" command="cmd_findAgain"/>
+ <menuseparator id="editMenuAfterFindSeparator"/>
+ <menuitem id="searchMailCmd" label="&searchMailCmd.label;"
+ key="key_searchMail"
+ accesskey="&searchMailCmd.accesskey;"
+ command="cmd_search"/>
+ <menuitem id="searchAddressesCmd" label="&searchAddressesCmd.label;"
+ accesskey="&searchAddressesCmd.accesskey;"
+ oncommand="MsgSearchAddresses()"/>
+ </menupopup>
+ </menu>
+ <menuseparator id="editPropertiesSeparator"/>
+ <menuitem id="menu_favoriteFolder"
+ type="checkbox"
+ label="&menuFavoriteFolder.label;"
+ accesskey="&menuFavoriteFolder.accesskey;"
+ check="false"
+ oncommand="ToggleFavoriteFolderFlag();"/>
+ <menuitem id="menu_properties" label="&folderPropsCmd.label;"
+ accesskey="&folderPropsCmd.accesskey;"
+ command="cmd_properties"/>
+#ifdef XP_UNIX
+#ifndef XP_MACOSX
+ <menuitem id="menu_accountmgr" label="&accountManagerCmd.label;" accesskey="&accountManagerCmdUnix.accesskey;" oncommand="MsgAccountManager(null);"/>
+ <menuitem id="menu_preferences" oncommand="openOptionsDialog()"/>
+#endif
+#endif
+ </menupopup>
+ </menu>
+
+ <!-- View -->
+ <menu id="menu_View">
+ <menupopup id="menu_View_Popup" onpopupshowing="view_init();">
+ <menu id="menu_Toolbars" onpopupshowing="onViewToolbarsPopupShowing(event, 'mail-toolbox');">
+ <menupopup id="view_toolbars_popup">
+ <menuitem id="menu_showTaskbar" type="checkbox"/>
+ <menuseparator id="viewMenuBeforeCustomizeMailToolbarsSeparator"/>
+ <menuitem id="customizeMailToolbars"
+ command="cmd_CustomizeMailToolbar"
+ label="&customizeToolbar.label;"
+ accesskey="&customizeToolbar.accesskey;"/>
+ </menupopup>
+ </menu>
+ <menu id="menu_MessagePaneLayout" label="&messagePaneLayoutStyle.label;" accesskey="&messagePaneLayoutStyle.accesskey;">
+ <menupopup id="view_layout_popup" onpopupshowing="InitViewLayoutStyleMenu(event)">
+ <menuitem id="messagePaneClassic" type="radio" label="&messagePaneClassic.label;" name="viewlayoutgroup"
+ accesskey="&messagePaneClassic.accesskey;" command="cmd_viewClassicMailLayout"/>
+ <menuitem id="messagePaneWide" type="radio" label="&messagePaneWide.label;" name="viewlayoutgroup"
+ accesskey="&messagePaneWide.accesskey;" command="cmd_viewWideMailLayout"/>
+ <menuitem id="messagePaneVertical" type="radio" label="&messagePaneVertical.label;" name="viewlayoutgroup"
+ accesskey="&messagePaneVertical.accesskey;" command="cmd_viewVerticalMailLayout"/>
+ <menuseparator id="viewMenuAfterPaneVerticalSeparator"/>
+ <menuitem id="menu_showFolderPane" type="checkbox" label="&showFolderPaneCmd.label;"
+ accesskey="&showFolderPaneCmd.accesskey;" command="cmd_toggleFolderPane"/>
+ <menuitem id="menu_showMessage" type="checkbox" label="&showMessageCmd.label;" key="key_toggleMessagePane"
+ accesskey="&showMessageCmd.accesskey;" command="cmd_toggleMessagePane"/>
+ </menupopup>
+ </menu>
+ <menu id="menu_FolderViews" label="&folderView.label;" accesskey="&folderView.accesskey;">
+ <menupopup id="menu_FolderViewsPopup"
+ onpopupshowing="InitViewFolderViewsMenu(event)">
+ <menuitem id="menu_allFolders" value="all"
+ label="&allFolders.label;"
+ accesskey="&allFolders.accesskey;"
+ type="radio" name="viewmessages"
+ oncommand="gFolderTreeView.mode = this.value;"/>
+ <menuitem id="menu_smartFolders" value="smart"
+ label="&unifiedFolders.label;"
+ accesskey="&unifiedFolders.accesskey;"
+ type="radio" name="viewmessages"
+ oncommand="gFolderTreeView.mode = this.value;"/>
+ <menuitem id="menu_unreadFolders"
+ label="&unreadFolders.label;" value="unread"
+ accesskey="&unreadFolders.accesskey;"
+ type="radio" name="viewmessages"
+ oncommand="gFolderTreeView.mode = this.value;"/>
+ <menuitem id="menu_favoriteFolders" value="favorite"
+ label="&favoriteFolders.label;"
+ accesskey="&favoriteFolders.accesskey;"
+ type="radio" name="viewmessages"
+ oncommand="gFolderTreeView.mode = this.value;"/>
+ <menuitem id="menu_recentFolders" value="recent"
+ label="&recentFolders.label;"
+ accesskey="&recentFolders.accesskey;"
+ type="radio" name="viewmessages"
+ oncommand="gFolderTreeView.mode = this.value;"/>
+ </menupopup>
+ </menu>
+ <menuseparator id="viewSortMenuSeparator"/>
+ <menu id="viewSortMenu" accesskey="&sortMenu.accesskey;" label="&sortMenu.label;">
+ <menupopup id="menu_viewSortPopup" onpopupshowing="InitViewSortByMenu()">
+ <menuitem id="sortByDateMenuitem" type="radio" name="sortby" label="&sortByDateCmd.label;" accesskey="&sortByDateCmd.accesskey;" oncommand="MsgSortThreadPane('byDate')"/>
+ <menuitem id="sortByReceivedMenuitem" type="radio" name="sortby" label="&sortByReceivedCmd.label;" accesskey="&sortByReceivedCmd.accesskey;" oncommand="MsgSortThreadPane('byReceived')"/>
+ <menuitem id="sortByFlagMenuitem" type="radio" name="sortby" label="&sortByStarCmd.label;" accesskey="&sortByStarCmd.accesskey;" oncommand="MsgSortThreadPane('byFlagged')"/>
+ <menuitem id="sortByOrderReceivedMenuitem" type="radio" name="sortby" label="&sortByOrderReceivedCmd.label;" accesskey="&sortByOrderReceivedCmd.accesskey;" oncommand="MsgSortThreadPane('byId')"/>
+ <menuitem id="sortByPriorityMenuitem" type="radio" name="sortby" label="&sortByPriorityCmd.label;" accesskey="&sortByPriorityCmd.accesskey;" oncommand="MsgSortThreadPane('byPriority')"/>
+ <menuitem id="sortByFromMenuitem" type="radio" name="sortby" label="&sortByFromCmd.label;" accesskey="&sortByFromCmd.accesskey;" oncommand="MsgSortThreadPane('byAuthor')"/>
+ <menuitem id="sortByRecipientMenuitem" type="radio" name="sortby" label="&sortByRecipientCmd.label;" accesskey="&sortByRecipientCmd.accesskey;" oncommand="MsgSortThreadPane('byRecipient')"/>
+ <menuitem id="sortBySizeMenuitem" type="radio" name="sortby" label="&sortBySizeCmd.label;" accesskey="&sortBySizeCmd.accesskey;" oncommand="MsgSortThreadPane('bySize')"/>
+ <menuitem id="sortByStatusMenuitem" type="radio" name="sortby" label="&sortByStatusCmd.label;" accesskey="&sortByStatusCmd.accesskey;" oncommand="MsgSortThreadPane('byStatus')"/>
+ <menuitem id="sortBySubjectMenuitem" type="radio" name="sortby" label="&sortBySubjectCmd.label;" accesskey="&sortBySubjectCmd.accesskey;" oncommand="MsgSortThreadPane('bySubject')"/>
+ <menuitem id="sortByUnreadMenuitem" type="radio" name="sortby" label="&sortByUnreadCmd.label;" accesskey="&sortByUnreadCmd.accesskey;" oncommand="MsgSortThreadPane('byUnread')"/>
+ <menuitem id="sortByTagsMenuitem" type="radio" name="sortby" label="&sortByTagsCmd.label;" accesskey="&sortByTagsCmd.accesskey;" oncommand="MsgSortThreadPane('byTags')"/>
+ <menuitem id="sortByJunkStatusMenuitem" type="radio" name="sortby" label="&sortByJunkStatusCmd.label;" accesskey="&sortByJunkStatusCmd.accesskey;" oncommand="MsgSortThreadPane('byJunkStatus')"/>
+ <menuitem id="sortByAttachmentsMenuitem" type="radio" name="sortby" label="&sortByAttachmentsCmd.label;" accesskey="&sortByAttachmentsCmd.accesskey;" oncommand="MsgSortThreadPane('byAttachments')"/>
+ <menuseparator id="sortAfterAttachmentSeparator"/>
+ <menuitem id="sortAscending" type="radio" name="sortdirection" label="&sortAscending.label;" accesskey="&sortAscending.accesskey;" oncommand="MsgSortAscending()"/>
+ <menuitem id="sortDescending" type="radio" name="sortdirection" label="&sortDescending.label;" accesskey="&sortDescending.accesskey;" oncommand="MsgSortDescending()"/>
+ <menuseparator id="sortAfterDescendingSeparator"/>
+ <menuitem id="sortThreaded" type="radio" name="threaded" label="&sortThreaded.label;" accesskey="&sortThreaded.accesskey;" oncommand="MsgSortThreaded();"/>
+ <menuitem id="sortUnthreaded" type="radio" name="threaded" label="&sortUnthreaded.label;" accesskey="&sortUnthreaded.accesskey;" oncommand="MsgSortUnthreaded();"/>
+ <menuitem id="groupBySort" type="radio" name="group" label="&groupBySort.label;" accesskey="&groupBySort.accesskey;" oncommand="MsgGroupBySort();"/>
+ </menupopup>
+ </menu>
+ <menu id="viewMessageViewMenu" label="&msgsMenu.label;" accesskey="&msgsMenu.accesskey;"
+ command="mailHideMenus" oncommand="ViewChangeByMenuitem(event.target);">
+ <menupopup id="viewMessagePopup" onpopupshowing="RefreshViewPopup(this, false);">
+ <menuitem id="viewMessageAll" value="0" type="radio" label="&viewAll.label;" accesskey="&viewAll.accesskey;"/>
+ <menuitem id="viewMessageUnread" value="1" type="radio" label="&viewUnread.label;" accesskey="&viewUnread.accesskey;"/>
+ <menuitem id="viewMessageNotDeleted" value="3" type="radio" label="&viewNotDeleted.label;" accesskey="&viewNotDeleted.accesskey;"/>
+ <menuseparator id="messageViewAfterUnreadSeparator"/>
+ <menu id="viewMessageTags" label="&viewTags.label;" accesskey="&viewTags.accesskey;">
+ <menupopup id="viewMessageTagsPopup" onpopupshowing="RefreshTagsPopup(this, false);"/>
+ </menu>
+ <menu id="viewMessageCustomViews" label="&viewCustomViews.label;" accesskey="&viewCustomViews.accesskey;">
+ <menupopup id="viewMessageCustomViewsPopup" onpopupshowing="RefreshCustomViewsPopup(this, false);"/>
+ </menu>
+ <menuseparator id="messageViewAfterCustomSeparator"/>
+ <menuitem id="viewMessageVirtualFolder" value="7" label="&viewVirtualFolder.label;" accesskey="&viewVirtualFolder.accesskey;"/>
+ <menuitem id="viewMessageCustomize" value="8" label="&viewCustomizeView.label;" accesskey="&viewCustomizeView.accesskey;"/>
+ </menupopup>
+ </menu>
+
+ <menu label="&threads.label;" id="viewMessagesMenu" accesskey="&threads.accesskey;">
+ <menupopup id="menu_ThreadsPopup" onpopupshowing="InitViewMessagesMenu()">
+ <menuitem id="viewAllMessagesMenuItem" type="radio" name="viewmessages" label="&allMsgsCmd.label;" accesskey="&allMsgsCmd.accesskey;" disabled="true" command="cmd_viewAllMsgs"/>
+ <menuitem id="viewUnreadMessagesMenuItem" type="radio" name="viewmessages" label="&unreadMsgsCmd.label;" accesskey="&unreadMsgsCmd.accesskey;" disabled="true" command="cmd_viewUnreadMsgs"/>
+ <menuitem id="viewThreadsWithUnreadMenuItem" type="radio" name="viewmessages" label="&threadsWithUnreadCmd.label;" accesskey="&threadsWithUnreadCmd.accesskey;" disabled="true" command="cmd_viewThreadsWithUnread"/>
+ <menuitem id="viewWatchedThreadsWithUnreadMenuItem" type="radio" name="viewmessages" label="&watchedThreadsWithUnreadCmd.label;" accesskey="&watchedThreadsWithUnreadCmd.accesskey;" disabled="true" command="cmd_viewWatchedThreadsWithUnread"/>
+ <menuseparator id="threadsAfterWatchedSeparator"/>
+ <menuitem id="viewIgnoredThreadsMenuItem" type="checkbox" label="&ignoredThreadsCmd.label;" disabled="true" command="cmd_viewIgnoredThreads" accesskey="&ignoredThreadsCmd.accesskey;"/>
+ <menuseparator id="threadsAfterIgnoredSeparator"/>
+ <menuitem id="menu_expandAllThreads" label="&expandAllThreadsCmd.label;" accesskey="&expandAllThreadsCmd.accesskey;" key="key_expandAllThreads" disabled="true" command="cmd_expandAllThreads"/>
+ <menuitem id="collapseAllThreads" label="&collapseAllThreadsCmd.label;" accesskey="&collapseAllThreadsCmd.accesskey;" key="key_collapseAllThreads" disabled="true" command="cmd_collapseAllThreads"/>
+ </menupopup>
+ </menu>
+ <menuseparator id="viewAfterThreadsSeparator"/>
+ <menu id="viewheadersmenu" label="&headersMenu.label;" accesskey="&headersMenu.accesskey;">
+ <menupopup id="menu_HeadersPopup" onpopupshowing="InitViewHeadersMenu();">
+ <menuitem id="viewallheaders"
+ type="radio"
+ name="viewheadergroup"
+ label="&headersAllCmd.label;"
+ accesskey="&headersAllCmd.accesskey;"
+ command="cmd_viewAllHeader"/>
+ <menuitem id="viewnormalheaders"
+ type="radio"
+ name="viewheadergroup"
+ label="&headersNormalCmd.label;"
+ accesskey="&headersNormalCmd.accesskey;"
+ command="cmd_viewNormalHeader"/>
+ </menupopup>
+ </menu>
+ <menu id="viewBodyMenu" accesskey="&bodyMenu.accesskey;" label="&bodyMenu.label;">
+ <menupopup id="viewBodyPopMenu" onpopupshowing="InitViewBodyMenu()">
+ <menuitem id="bodyAllowHTML" type="radio" name="bodyPlaintextVsHTMLPref" label="&bodyAllowHTML.label;"
+ accesskey="&bodyAllowHTML.accesskey;" oncommand="MsgBodyAllowHTML()"/>
+ <menuitem id="bodySanitized" type="radio" name="bodyPlaintextVsHTMLPref" label="&bodySanitized.label;"
+ accesskey="&bodySanitized.accesskey;"
+ oncommand="MsgBodySanitized()"/>
+ <menuitem id="bodyAsPlaintext" type="radio" name="bodyPlaintextVsHTMLPref" label="&bodyAsPlaintext.label;"
+ accesskey="&bodyAsPlaintext.accesskey;" oncommand="MsgBodyAsPlaintext()"/>
+ <menuitem id="bodyAllParts" type="radio" name="bodyPlaintextVsHTMLPref" label="&bodyAllParts.label;"
+ accesskey="&bodyAllParts.accesskey;" oncommand="MsgBodyAllParts()"/>
+ </menupopup>
+ </menu>
+ <menu id="viewFeedSummary"
+ label="&bodyMenuFeed.label;"
+ accesskey="&bodyMenuFeed.accesskey;">
+ <menupopup id="viewFeedSummaryPopupMenu"
+ onpopupshowing="InitViewBodyMenu()">
+ <menuitem id="bodyFeedGlobalWebPage"
+ type="radio"
+ name="viewFeedSummaryGroup"
+ label="&viewFeedWebPage.label;"
+ accesskey="&viewFeedWebPage.accesskey;"
+ oncommand="FeedMessageHandler.onSelectPref = 0"/>
+ <menuitem id="bodyFeedGlobalSummary"
+ type="radio"
+ name="viewFeedSummaryGroup"
+ label="&viewFeedSummary.label;"
+ accesskey="&viewFeedSummary.accesskey;"
+ oncommand="FeedMessageHandler.onSelectPref = 1"/>
+ <menuitem id="bodyFeedPerFolderPref"
+ type="radio"
+ name="viewFeedSummaryGroup"
+ label="&viewFeedSummaryFeedPropsPref.label;"
+ accesskey="&viewFeedSummaryFeedPropsPref.accesskey;"
+ oncommand="FeedMessageHandler.onSelectPref = 2"/>
+ <menuseparator id="viewFeedSummarySeparator"/>
+ <menuitem id="bodyFeedSummaryAllowHTML"
+ type="radio"
+ name="viewFeedBodyHTMLGroup"
+ label="&bodyAllowHTML.label;"
+ accesskey="&bodyAllowHTML.accesskey;"
+ oncommand="MsgFeedBodyRenderPrefs(false, 0, 0)"/>
+ <menuitem id="bodyFeedSummarySanitized"
+ type="radio"
+ name="viewFeedBodyHTMLGroup"
+ label="&bodySanitized.label;"
+ accesskey="&bodySanitized.accesskey;"
+ oncommand="MsgFeedBodyRenderPrefs(false, 3, gDisallow_classes_no_html)"/>
+ <menuitem id="bodyFeedSummaryAsPlaintext"
+ type="radio"
+ name="viewFeedBodyHTMLGroup"
+ label="&bodyAsPlaintext.label;"
+ accesskey="&bodyAsPlaintext.accesskey;"
+ oncommand="MsgFeedBodyRenderPrefs(true, 1, gDisallow_classes_no_html)"/>
+ </menupopup>
+ </menu>
+ <menuitem id="viewAttachmentsInlineMenuitem" label="&viewAttachmentsInlineCmd.label;" accesskey="&viewAttachmentsInlineCmd.accesskey;"
+ oncommand="ToggleInlineAttachment(event.target)" type="checkbox" checked="true"/>
+ <menuseparator id="viewAfterAttachmentsSeparator"/>
+ <menu id="viewFullZoomMenu" label="&fullZoom.label;" accesskey="&fullZoom.accesskey;"
+ onpopupshowing="UpdateFullZoomMenu()">
+ <menupopup id="viewFullZoomPopupMenu">
+ <menuitem id="menu_fullZoomEnlarge" key="key_fullZoomEnlarge"
+ label="&fullZoomEnlargeCmd.label;"
+ accesskey="&fullZoomEnlargeCmd.accesskey;"
+ command="cmd_fullZoomEnlarge"/>
+ <menuitem id="menu_fullZoomReduce" key="key_fullZoomReduce"
+ label="&fullZoomReduceCmd.label;"
+ accesskey="&fullZoomReduceCmd.accesskey;"
+ command="cmd_fullZoomReduce"/>
+ <menuseparator id="fullZoomAfterReduceSeparator"/>
+ <menuitem id="menu_fullZoomReset" key="key_fullZoomReset"
+ label="&fullZoomResetCmd.label;"
+ accesskey="&fullZoomResetCmd.accesskey;"
+ command="cmd_fullZoomReset"/>
+ <menuseparator id="fullZoomAfterResetSeparator"/>
+ <menuitem id="menu_fullZoomToggle" label="&fullZoomToggleCmd.label;"
+ accesskey="&fullZoomToggleCmd.accesskey;"
+ type="checkbox" command="cmd_fullZoomToggle" checked="false"/>
+ </menupopup>
+ </menu>
+ <menu id="mailviewCharsetMenu" />
+ <menuseparator id="viewAfterCharsetSeparator"/>
+ <menuitem id="pageSourceMenuItem" label="&pageSourceCmd.label;" key="key_viewPageSource" accesskey="&pageSourceCmd.accesskey;" command="cmd_viewPageSource"/>
+ </menupopup>
+ </menu>
+
+ <!-- Go -->
+ <menu id="menu_Go" label="&goMenu.label;" accesskey="&goMenu.accesskey;">
+ <menupopup id="menu_GoPopup" onpopupshowing="InitGoMessagesMenu();">
+ <menu id="goNextMenu" label="&nextMenu.label;" accesskey="&nextMenu.accesskey;">
+ <menupopup id="menu_GoNextPopup">
+ <menuitem id="menu_nextMsg" label="&nextMsgCmd.label;" accesskey="&nextMsgCmd.accesskey;" command="cmd_nextMsg"
+ key="key_nextMsg"/>
+ <menuitem id="menu_nextUnreadMsg" label="&nextUnreadMsgCmd.label;" accesskey="&nextUnreadMsgCmd.accesskey;" command="cmd_nextUnreadMsg"
+ key="key_nextUnreadMsg"/>
+ <menuitem id="menu_nextFlaggedMsg" label="&nextStarredMsgCmd.label;" accesskey="&nextStarredMsgCmd.accesskey;" command="cmd_nextFlaggedMsg"/>
+ <menuseparator id="goNextAfterFlaggedSeparator"/>
+ <menuitem id="menu_nextUnreadThread"
+ label="&nextUnreadThread.label;"
+ accesskey="&nextUnreadThread.accesskey;"
+ command="cmd_nextUnreadThread"
+ key="key_nextUnreadThread"/>
+ </menupopup>
+ </menu>
+ <menu id="goPreviousMenu" label="&prevMenu.label;" accesskey="&prevMenu.accesskey;">
+ <menupopup id="menu_GoPreviousPopup">
+ <menuitem id="menu_prevMsg" label="&prevMsgCmd.label;" accesskey="&prevMsgCmd.accesskey;" command="cmd_previousMsg"
+ key="key_previousMsg"/>
+ <menuitem id="menu_prevUnreadMsg" label="&prevUnreadMsgCmd.label;" accesskey="&prevUnreadMsgCmd.accesskey;" command="cmd_previousUnreadMsg"
+ key="key_previousUnreadMsg"/>
+ <menuitem id="menu_prevFlaggedMsg" label="&prevStarredMsgCmd.label;" accesskey="&prevStarredMsgCmd.accesskey;" command="cmd_previousFlaggedMsg"/>
+ </menupopup>
+ </menu>
+ <menuitem id="menu_goForward" label="&goForwardCmd.label;"
+ accesskey="&goForwardCmd.accesskey;" command="cmd_goForward"
+ key="key_goForward"/>
+ <menuitem id="menu_goBack" label="&goBackCmd.label;"
+ accesskey="&goBackCmd.accesskey;" command="cmd_goBack"
+ key="key_goBack"/>
+ <menuseparator id="goNextSeparator"/>
+ <menuitem id="menu_goChat" label="&goChatCmd.label;"
+ accesskey="&goChatCmd.accesskey;"
+ command="cmd_chat"
+ key="key_goChat"/>
+ <menuseparator id="goChatSeparator"/>
+ <menu id="goFolderMenu"
+ label="&folderMenu.label;"
+ accesskey="&folderMenu.accesskey;"
+ oncommand="gFolderTreeView.selectFolder(event.target._folder, true)">
+ <menupopup id="menu_GoFolderPopup"
+ type="folder"
+ showFileHereLabel="true"
+ fileHereLabel="&thisFolder.label;"
+ fileHereAccessKey="&thisFolder.accesskey;"
+ showRecent="true"
+ recentLabel="&contextMoveCopyMsgRecentMenu.label;"
+ recentAccessKey="&contextMoveCopyMsgRecentMenu.accesskey;"/>
+ </menu>
+ <menuseparator id="goFolderSeparator"/>
+
+ <menu id="goRecentlyClosedTabs"
+ label="&goRecentlyClosedTabs.label;"
+ accesskey="&goRecentlyClosedTabs.accesskey;"
+ observes="cmd_undoCloseTab">
+ <menupopup id="menu_GoRecentlyClosedTabsPopup"
+ onpopupshowing="return InitRecentlyClosedTabsPopup(this)" />
+ </menu>
+ <menuseparator id="goRecentlyClosedTabsSeparator"/>
+
+ <menuitem id="goStartPage"
+ label="&startPageCmd.label;"
+ accesskey="&startPageCmd.accesskey;"
+ command="cmd_goStartPage"
+ key="key_goStartPage"/>
+ </menupopup>
+ </menu>
+
+ <!-- Message -->
+ <menu id="messageMenu" label="&msgMenu.label;" accesskey="&msgMenu.accesskey;">
+ <menupopup id="messageMenuPopup" onpopupshowing="InitMessageMenu();">
+ <menuitem id="newMsgCmd" label="&newMsgCmd.label;"
+ accesskey="&newMsgCmd.accesskey;"
+ key="key_newMessage2"
+ oncommand="MsgNewMessage(null);"/>
+ <menuitem id="replyMainMenu" label="&replyMsgCmd.label;"
+ accesskey="&replyMsgCmd.accesskey;"
+ key="key_reply"
+ command="cmd_reply"/>
+ <menuitem id="replyNewsgroupMainMenu" label="&replyNewsgroupCmd2.label;"
+ accesskey="&replyNewsgroupCmd2.accesskey;"
+ key="key_reply"
+ command="cmd_replyGroup"/>
+ <menuitem id="replySenderMainMenu" label="&replySenderCmd.label;"
+ accesskey="&replySenderCmd.accesskey;"
+ command="cmd_replySender"/>
+ <menuitem id="menu_replyToAll" label="&replyToAllMsgCmd.label;"
+ accesskey="&replyToAllMsgCmd.accesskey;"
+ key="key_replyall"
+ command="cmd_replyall"/>
+ <menuitem id="menu_replyToList" label="&replyToListMsgCmd.label;"
+ accesskey="&replyToListMsgCmd.accesskey;"
+ key="key_replylist"
+ command="cmd_replylist"/>
+ <menuitem id="menu_forwardMsg" label="&forwardMsgCmd.label;"
+ accesskey="&forwardMsgCmd.accesskey;"
+ key="key_forward"
+ command="cmd_forward"/>
+ <menu id="forwardAsMenu" label="&forwardAsMenu.label;" accesskey="&forwardAsMenu.accesskey;">
+ <menupopup id="menu_forwardAsPopup">
+ <menuitem id="menu_forwardAsInline"
+ label="&forwardAsInline.label;"
+ accesskey="&forwardAsInline.accesskey;"
+ command="cmd_forwardInline"/>
+ <menuitem id="menu_forwardAsAttachment"
+ label="&forwardAsAttachmentCmd.label;"
+ accesskey="&forwardAsAttachmentCmd.accesskey;"
+ command="cmd_forwardAttachment"/>
+ </menupopup>
+ </menu>
+ <menuitem id="menu_editMsgAsNew" label="&editMsgAsNewCmd.label;"
+ accesskey="&editMsgAsNewCmd.accesskey;"
+ key="key_editAsNew"
+ command="cmd_editAsNew"/>
+ <menuseparator id="messageMenuAfterCompositionCommandsSeparator"/>
+ <menuitem id="openMessageWindowMenuitem" label="&openMessageWindowCmd.label;"
+ command="cmd_openMessage"
+ accesskey="&openMessageWindowCmd.accesskey;"
+ key="key_openMessage"/>
+ <menuitem id="openConversationMenuitem" label="&openConversationCmd.label;"
+ command="cmd_openConversation"
+ accesskey="&openConversationCmd.accesskey;"
+ key="key_openConversation"/>
+ <menu id="openFeedMessage"
+ label="&openFeedMessage1.label;"
+ accesskey="&openFeedMessage1.accesskey;">
+ <menupopup id="menu_openFeedMessage">
+ <menuitem id="menu_openFeedWebPage"
+ type="radio"
+ name="openFeedGroup"
+ label="&openFeedWebPage.label;"
+ accesskey="&openFeedWebPage.accesskey;"
+ oncommand="FeedMessageHandler.onOpenPref = 0"/>
+ <menuitem id="menu_openFeedSummary"
+ type="radio"
+ name="openFeedGroup"
+ label="&openFeedSummary.label;"
+ accesskey="&openFeedSummary.accesskey;"
+ oncommand="FeedMessageHandler.onOpenPref = 1"/>
+ <menuitem id="menu_openFeedWebPageInMessagePane"
+ type="radio"
+ name="openFeedGroup"
+ label="&openFeedWebPageInMP.label;"
+ accesskey="&openFeedWebPageInMP.accesskey;"
+ oncommand="FeedMessageHandler.onOpenPref = 2"/>
+ </menupopup>
+ </menu>
+ <menuseparator id="messageAfterOpenMsgSeparator"/>
+ <menu id="msgAttachmentMenu"
+ label="&openAttachmentListCmd.label;"
+ accesskey="&openAttachmentListCmd.accesskey;"
+ disabled="true">
+ <menupopup id="attachmentMenuList" onpopupshowing="FillAttachmentListPopup(this);"/>
+ </menu>
+ <menuseparator id="messageAfterAttachmentMenuSeparator"/>
+ <menu id="tagMenu" label="&tagMenu.label;" accesskey="&tagMenu.accesskey;" command="cmd_tag">
+ <menupopup id="tagMenu-tagpopup"
+ onpopupshowing="InitMessageTags(this);">
+ <menuitem id="addNewTag"
+ label="&addNewTag.label;"
+ accesskey="&addNewTag.accesskey;"
+ command="cmd_addTag"/>
+ <menuitem id="manageTags"
+ label="&manageTags.label;"
+ accesskey="&manageTags.accesskey;"
+ command="cmd_manageTags"/>
+ <menuseparator id="tagMenu-sep-afterTagAddNew"/>
+ <menuitem id="tagMenu-tagRemoveAll"
+ command="cmd_removeTags"/>
+ <menuseparator id="tagMenuAfterRemoveSeparator"/>
+ </menupopup>
+ </menu>
+ <menu id="markMenu" label="&markMenu.label;" accesskey="&markMenu.accesskey;">
+ <menupopup id="menu_MarkPopup" onpopupshowing="InitMessageMark()">
+ <menuitem id="markReadMenuItem" label="&markAsReadCmd.label;"
+ accesskey="&markAsReadCmd.accesskey;"
+ command="cmd_markAsRead"/>
+ <menuitem id="markUnreadMenuItem" label="&markAsUnreadCmd.label;"
+ accesskey="&markAsUnreadCmd.accesskey;"
+ command="cmd_markAsUnread"/>
+ <menuitem id="menu_markThreadAsRead" label="&markThreadAsReadCmd.label;" accesskey="&markThreadAsReadCmd.accesskey;" command="cmd_markThreadAsRead"
+ key="key_markThreadAsRead"/>
+ <menuitem id="menu_markReadByDate" label="&markReadByDateCmd.label;" accesskey="&markReadByDateCmd.accesskey;" command="cmd_markReadByDate"
+ key="key_markReadByDate"/>
+ <menuitem id="menu_markAllRead" label="&markAllReadCmd.label;" key="key_markAllRead" accesskey="&markAllReadCmd.accesskey;" command="cmd_markAllRead"/>
+ <menuseparator id="markMenuAfterAllReadSeparator"/>
+ <menuitem id="markFlaggedMenuItem"
+ type="checkbox"
+ label="&markStarredCmd.label;"
+ accesskey="&markStarredCmd.accesskey;"
+ command="cmd_markAsFlagged"
+ key="key_toggleFlagged"/>
+ <menuseparator id="markMenuAfterFlaggedSeparator"/>
+ <menuitem id="menu_markAsJunk" label="&markAsJunkCmd.label;"
+ accesskey="&markAsJunkCmd.accesskey;"
+ command="cmd_markAsJunk"
+ key="key_markJunk"/>
+ <menuitem id="menu_markAsNotJunk" label="&markAsNotJunkCmd.label;"
+ key="key_markNotJunk"
+ accesskey="&markAsNotJunkCmd.accesskey;"
+ command="cmd_markAsNotJunk"/>
+ <menuitem id="menu_recalculateJunkScore"
+ label="&recalculateJunkScoreCmd.label;"
+ accesskey="&recalculateJunkScoreCmd.accesskey;"
+ command="cmd_recalculateJunkScore"/>
+ </menupopup>
+ </menu>
+ <menuseparator id="messageMenuAfterMarkSeparator"/>
+ <menuitem id="archiveMainMenu" label="&archiveMsgCmd.label;"
+ accesskey="&archiveMsgCmd.accesskey;"
+ key="key_archive"
+ command="cmd_archive"/>
+ <menuitem id="menu_cancel" command="cmd_cancel"
+ label="&cancelNewsMsgCmd.label;"
+ accesskey="&cancelNewsMsgCmd.accesskey;"/>
+ <menu id="moveMenu"
+ label="&moveMsgToMenu.label;"
+ accesskey="&moveMsgToMenu.accesskey;"
+ oncommand="MsgMoveMessage(event.target._folder)">
+ <menupopup type="folder" mode="filing" showFileHereLabel="true"
+ showRecent="true" fileHereLabel="&fileHereMenu.label;"
+ fileHereAccessKey="&fileHereMenu.accesskey;"
+ recentLabel="&moveCopyMsgRecentMenu.label;"
+ recentAccessKey="&moveCopyMsgRecentMenu.accesskey;"/>
+ </menu>
+ <menu id="copyMenu"
+ label="©MsgToMenu.label;"
+ accesskey="©MsgToMenu.accesskey;"
+ oncommand="MsgCopyMessage(event.target._folder)">
+ <menupopup type="folder" mode="filing" showFileHereLabel="true"
+ showRecent="true" fileHereLabel="©HereMenu.label;"
+ fileHereAccessKey="©HereMenu.accesskey;"
+ recentLabel="&moveCopyMsgRecentMenu.label;"
+ recentAccessKey="&moveCopyMsgRecentMenu.accesskey;"/>
+ </menu>
+ <menuitem id="moveToFolderAgain" key="key_moveToFolderAgain" command="cmd_moveToFolderAgain"
+ label="&moveToFolderAgain.label;" accesskey="&moveToFolderAgain.accesskey;"/>
+ <menuseparator id="messageMenuAfterMoveCommandsSeparator"/>
+ <menuitem id="createFilter" label="&createFilter.label;"
+ accesskey="&createFilter.accesskey;"
+ command="cmd_createFilterFromMenu"/>
+ <menuseparator id="threadItemsSeparator"/>
+ <menuitem id="killThread"
+ label="&killThreadMenu.label;"
+ accesskey="&killThreadMenu.accesskey;"
+ command="cmd_killThread"
+ type="checkbox"
+ key="key_killThread"/>
+ <menuitem id="killSubthread"
+ label="&killSubthreadMenu.label;"
+ accesskey="&killSubthreadMenu.accesskey;"
+ type="checkbox"
+ command="cmd_killSubthread"
+ key="key_killSubthread"/>
+ <menuitem id="watchThread"
+ label="&watchThreadMenu.label;"
+ accesskey="&watchThreadMenu.accesskey;"
+ type="checkbox"
+ command="cmd_watchThread"
+ key="key_watchThread"/>
+ </menupopup>
+ </menu>
+
+ <!-- Tools -->
+ <menu id="tasksMenu" label="&tasksMenu.label;" accesskey="&tasksMenu.accesskey;">
+ <menupopup id="taskPopup" onpopupshowing="document.commandDispatcher.updateCommands('create-menu-tasks')">
+#ifndef XP_MACOSX
+ <menuitem hidden="true" accesskey="&messengerCmd.accesskey;" label="&messengerCmd.label;"
+ key="key_mail" oncommand="toMessengerWindow();" id="tasksMenuMail" class="menuitem-iconic menu-iconic"/>
+ <menuitem id="addressBook"
+ label="&addressBookCmd.label;"
+ accesskey="&addressBookCmd.accesskey;"
+ key="key_addressbook"
+ oncommand="toOpenWindowByType('mail:addressbook', 'chrome://messenger/content/addressbook/addressbook.xul');"/>
+ <menuseparator id="devToolsSeparator"/>
+#endif
+ <menuitem id="menu_openSavedFilesWnd" label="&savedFiles.label;"
+ accesskey="&savedFiles.accesskey;"
+ key="key_savedFiles"
+ oncommand="openSavedFilesWnd();"/>
+ <menuitem id="addonsManager" label="&addons.label;" accesskey="&addons.accesskey;"
+ oncommand="openAddonsMgr();"/>
+ <menuitem id="activityManager" label="&activitymanager.label;"
+ accesskey="&activitymanager.accesskey;"
+ oncommand="openActivityMgr();"/>
+ <menu id="imAccountsStatus" label="&imAccountsStatus.label;"
+ accesskey="&imAccountsStatus.accesskey;"
+ oncommand="chatHandler.setStatusMenupopupCommand(event);">
+ <menupopup id="imStatusMenupopup">
+ <menuitem id="imStatusAvailable" status="available" label="&imStatus.available;" class="menuitem-iconic"/>
+ <menuitem id="imStatusUnavailable" status="unavailable" label="&imStatus.unavailable;" class="menuitem-iconic"/>
+ <menuseparator id="imStatusOfflineSeparator"/>
+ <menuitem id="imStatusOffline" status="offline" label="&imStatus.offline;" class="menuitem-iconic"/>
+ <menuseparator id="imStatusShowAccountsSeparator"/>
+ <menuitem id="imStatusShowAccounts" label="&imStatus.showAccounts;"/>
+ </menupopup>
+ </menu>
+ <menuitem id="joinChatMenuItem"
+ label="&joinChatCmd.label;"
+ accesskey="&joinChatCmd.accesskey;"
+ oncommand="chatHandler.joinChat();"/>
+
+ <menuseparator id="devToolsSeparator"/>
+ <menuitem id="filtersCmd" label="&filtersCmd.label;"
+ accesskey="&filtersCmd.accesskey;"
+ command="cmd_displayMsgFilters"/>
+ <menuitem id="applyFilters"
+ label="&filtersApply.label;"
+ accesskey="&filtersApply.accesskey;"
+ command="cmd_applyFilters"/>
+ <menuitem id="applyFiltersToSelection"
+ label="&filtersApplyToMessage.label;"
+ accesskey="&filtersApplyToMessage.accesskey;"
+ command="cmd_applyFiltersToSelection"/>
+ <menuseparator id="tasksMenuAfterApplySeparator"/>
+ <menuitem id="runJunkControls"
+ label="&runJunkControls.label;"
+ accesskey="&runJunkControls.accesskey;"
+ command="cmd_runJunkControls"/>
+ <menuitem id="deleteJunk"
+ label="&deleteJunk.label;"
+ accesskey="&deleteJunk.accesskey;"
+ command="cmd_deleteJunk"/>
+ <menuseparator id="tasksMenuAfterDeleteSeparator"/>
+ <menuitem id="menu_import" label="&importCmd.label;"
+ accesskey="&importCmd.accesskey;"
+ oncommand="toImport();"/>
+ <menuitem id="javascriptConsole" label="&errorConsoleCmd.label;" accesskey="&errorConsoleCmd.accesskey;" key="key_errorConsole" oncommand="toJavaScriptConsole();"/>
+ <menuitem id="sanitizeHistory"
+ label="&clearRecentHistory.label;"
+ accesskey="&clearRecentHistory.accesskey;"
+ oncommand="toSanitize();"/>
+#ifndef XP_UNIX
+ <menuseparator id="prefSep"/>
+ <menuitem id="menu_accountmgr" label="&accountManagerCmd.label;" accesskey="&accountManagerCmd.accesskey;" oncommand="MsgAccountManager(null);"/>
+ <menuitem id="menu_preferences" oncommand="openOptionsDialog()"/>
+#else
+#ifdef XP_MACOSX
+ <menuseparator id="prefSep"/>
+ <menuitem id="menu_accountmgr" label="&accountManagerCmd.label;" accesskey="&accountManagerCmd.accesskey;" oncommand="MsgAccountManager(null);"/>
+ <menuitem id="menu_preferences" label="&preferencesCmdMac.label;" key="key_preferencesCmdMac" oncommand="openOptionsDialog()"/>
+ <menuitem id="menu_mac_services" label="&servicesMenuMac.label;"/>
+ <menuitem id="menu_mac_hide_app" label="&hideThisAppCmdMac.label;" key="key_hideThisAppCmdMac"/>
+ <menuitem id="menu_mac_hide_others" label="&hideOtherAppsCmdMac.label;" key="key_hideOtherAppsCmdMac"/>
+ <menuitem id="menu_mac_show_all" label="&showAllAppsCmdMac.label;"/>
+#endif
+#endif
+ </menupopup>
+ </menu>
+
+#ifdef XP_MACOSX
+<!-- Mac window menu -->
+#include ../../../mozilla/toolkit/content/macWindowMenu.inc
+#endif
+
+ <!-- Help -->
+ <menu id="helpMenu"/>
+
+ <spacer id="menubar_spacer" flex="100%"/>
+ </menubar>
+ </toolbaritem>
+#ifdef CAN_DRAW_IN_TITLEBAR
+ <hbox class="titlebar-placeholder" type="caption-buttons" ordinal="1000"/>
+#endif
+ </toolbar>
+</toolbox>
+
+<toolbox id="mail-toolbox"
+ class="mail-toolbox"
+ mode="full"
+ defaultmode="full"
+#ifdef XP_MACOSX
+ iconsize="small"
+ defaulticonsize="small"
+#endif
+ labelalign="end"
+ defaultlabelalign="end">
+
+ <toolbarpalette id="MailToolbarPalette">
+ <toolbarbutton id="button-getmsg"
+ type="menu-button"
+ class="toolbarbutton-1"
+ label="&getMsgButton.label;"
+ tooltiptext="&getMsgButton.tooltip;"
+ oncommand="MsgGetMessagesForAccount(event.target._folder)"
+ observes="button_getNewMessages">
+ <menupopup id="button-getMsgPopup"
+ onpopupshowing="getMsgToolbarMenu_init();"
+ type="folder"
+ expandFolders="false"
+ mode="getMail">
+ <menuitem id="button-getAllNewMsg"
+ label="&getAllNewMsgCmd.label;"
+ accesskey="&getAllNewMsgCmd.accesskey;"
+ command="cmd_getMsgsForAuthAccounts"/>
+ <menuseparator id="button-getAllNewMsgSeparator"/>
+ </menupopup>
+ </toolbarbutton>
+ <toolbarbutton id="button-newmsg"
+ class="toolbarbutton-1"
+ label="&newMsgButton.label;"
+ tooltiptext="&newMsgButton.tooltip;"
+ oncommand="MsgNewMessage(event)"/>
+ <toolbarbutton id="button-reply"
+ class="toolbarbutton-1"
+ label="&replyButton.label;"
+ tooltiptext="&replyButton.tooltip;"
+ observes="button_reply"
+ command="cmd_reply"/>
+ <toolbarbutton id="button-replyall"
+ class="toolbarbutton-1"
+ label="&replyAllButton.label;"
+ tooltiptext="&replyAllButton.tooltip;"
+ observes="button_replyall"
+ command="cmd_replyall"/>
+ <toolbarbutton id="button-replylist"
+ class="toolbarbutton-1"
+ label="&replyListButton.label;"
+ tooltiptext="&replyListButton.tooltip;"
+ observes="button_replylist"
+ command="cmd_replylist"/>
+ <toolbarbutton id="button-forward"
+ type="menu-button"
+ class="toolbarbutton-1"
+ label="&forwardButton.label;"
+ tooltiptext="&forwardButton.tooltip;"
+ observes="button_forward"
+ command="cmd_forward">
+ <menupopup id="button-ForwardPopup">
+ <menuitem id="button-ForwardAsInlineMenu"
+ label="&buttonMenuForwardAsInline.label;"
+ tooltiptext="&forwardAsInline.tooltip;"
+ command="cmd_forwardInline"/>
+ <menuitem id="button-ForwardAsAttachmentMenu"
+ label="&buttonMenuForwardAsAttachment.label;"
+ tooltiptext="&forwardAsAttachment.tooltip;"
+ command="cmd_forwardAttachment"/>
+ </menupopup>
+ </toolbarbutton>
+ <toolbarbutton id="button-file"
+ type="menu"
+ class="toolbarbutton-1"
+ label="&fileButton.label;"
+ observes="button_file"
+ oncommand="MsgMoveMessage(event.target._folder)">
+ <menupopup id="button-filePopup"
+ type="folder"
+ mode="filing"
+ showRecent="true"
+ showFileHereLabel="true"
+ fileHereLabel="&fileHereMenu.label;"
+ fileHereAccessKey="&fileHereMenu.accesskey;"
+ recentLabel="&moveCopyMsgRecentMenu.label;"
+ recentAccessKey="&moveCopyMsgRecentMenu.accesskey;"/>
+ </toolbarbutton>
+ <toolbarbutton id="button-archive"
+ class="toolbarbutton-1"
+ label="&archiveButton.label;"
+ tooltiptext="&archiveButton.tooltip;"
+ observes="button_archive"
+ oncommand="MsgArchiveSelectedMessages(event)"/>
+ <toolbarbutton id="button-goback"
+ class="toolbarbutton-1"
+ type="menu-button"
+ label="&backButton1.label;"
+ oncommand="goDoCommand('cmd_goBack')"
+ tooltiptext="&goBackButton.tooltip;"
+ observes="button_goBack">
+ <menupopup id="button-goBackPopup" onpopupshowing="backToolbarMenu_init(this)">
+ <menuitem id="button-goBack" label="&goBackCmd.label;" command="cmd_goBack"/>
+ <menuseparator id="button-goBackSeparator"/>
+ </menupopup>
+ </toolbarbutton>
+ <toolbarbutton id="button-goforward"
+ class="toolbarbutton-1"
+ type="menu-button"
+ label="&goForwardButton1.label;"
+ oncommand="goDoCommand('cmd_goForward')"
+ tooltiptext="&goForwardButton.tooltip;"
+ observes="button_goForward">
+ <menupopup id="button-goForwardPopup" onpopupshowing="forwardToolbarMenu_init(this)">
+ <menuitem id="button-goForward"
+ label="&goForwardCmd.label;"
+ command="cmd_goForward"/>
+ <menuseparator id="button-goForwardSeparator"/>
+ </menupopup>
+ </toolbarbutton>
+ <toolbaritem id="button-previous"
+ title="&previousButtonToolbarItem.label;"
+ align="center"
+ class="chromeclass-toolbar-additional">
+ <toolbarbutton id="button-previousUnread"
+ class="toolbarbutton-1"
+ label="&previousButton.label;"
+ oncommand="goDoCommand('button_previous')"
+ tooltiptext="&previousButton.tooltip;"
+ observes="button_previous"/>
+ </toolbaritem>
+ <toolbarbutton id="button-previousMsg"
+ class="toolbarbutton-1"
+ label="&previousMsgButton.label;"
+ oncommand="goDoCommand('button_previousMsg')"
+ tooltiptext="&previousMsgButton.tooltip;"
+ observes="button_previousMsg"/>
+ <toolbaritem id="button-next"
+ title="&nextButtonToolbarItem.label;"
+ align="center"
+ class="chromeclass-toolbar-additional">
+ <toolbarbutton id="button-nextUnread"
+ class="toolbarbutton-1"
+ label="&nextButton.label;"
+ oncommand="goDoCommand('button_next')"
+ tooltiptext="&nextButton.tooltip;"
+ observes="button_next"/>
+ </toolbaritem>
+ <toolbarbutton id="button-nextMsg"
+ class="toolbarbutton-1"
+ label="&nextMsgButton.label;"
+ oncommand="goDoCommand('button_nextMsg');"
+ tooltiptext="&nextMsgButton.tooltip;"
+ observes="button_nextMsg"/>
+ <toolbaritem id="button-junk" title="&junkItem.title;">
+ <deck id="junk-deck" observes="button_junk">
+ <toolbarbutton id="button-isJunk"
+ class="toolbarbutton-1 junk-button"
+ label="&junkButton.label;"
+ tooltiptext="&junkButton.tooltip;"
+ observes="button_junk"
+ oncommand="goDoCommand('button_junk')"/>
+ <toolbarbutton id="button-notJunk"
+ class="toolbarbutton-1 junk-button"
+ label="¬JunkButton.label;"
+ tooltiptext="¬JunkButton.tooltip;"
+ observes="button_junk"
+ oncommand="goDoCommand('button_junk')"/>
+ </deck>
+ </toolbaritem>
+ <toolbaritem id="button-delete" title="&deleteItem.title;">
+ <deck id="delete-deck" observes="button_delete">
+ <toolbarbutton id="button-mark-deleted"
+ class="toolbarbutton-1 delete-button"
+ label="&deleteButton.label;"
+ tooltiptext="&deleteButton.tooltip;"
+ observes="button_delete"
+ oncommand="goDoCommand(event.shiftKey ? 'button_shiftDelete' : 'button_delete')"/>
+ <toolbarbutton id="button-mark-undelete"
+ class="toolbarbutton-1 delete-button"
+ label="&undeleteButton.label;"
+ tooltiptext="&undeleteButton.tooltip;"
+ observes="button_delete"
+ oncommand="goDoCommand('button_delete')"/>
+ </deck>
+ </toolbaritem>
+#ifdef XP_MACOSX
+ <toolbarbutton id="button-print"
+ class="toolbarbutton-1"
+ label="&printButton.label;"
+ observes="button_print"
+ oncommand="goDoCommand('cmd_print')"
+ tooltiptext="&printButton.tooltip;"/>
+#else
+ <toolbarbutton id="button-print"
+ class="toolbarbutton-1"
+ label="&printButton.label;"
+ observes="button_print"
+ oncommand="goDoCommand('cmd_print')"
+ tooltiptext="&printButton.tooltip;"
+ type="menu-button">
+ <menupopup id="printMenu" onpopupshowing="goUpdateCommand('cmd_printpreview');">
+ <menuitem id="button-printMenu"
+ label="&printCmd.label;"
+ accesskey="&printCmd.accesskey;"
+ default="true"/>
+ <menuitem id="button-printPreviewMenu"
+ label="&printPreviewCmd.label;"
+ accesskey="&printPreviewCmd.accesskey;"
+ observes="cmd_printpreview"
+ command="cmd_printpreview"/>
+ </menupopup>
+ </toolbarbutton>
+#endif
+ <toolbarbutton id="button-mark"
+ type="menu-button"
+ class="toolbarbutton-1"
+ label="&markButton.label;"
+ oncommand="goDoCommand('button_mark')"
+ observes="button_mark"
+ tooltiptext="&markButton.tooltip;">
+ <menupopup id="button-markPopup" onpopupshowing="InitMessageMark()">
+ <menuitem id="markReadToolbarItem"
+ label="&markAsReadCmd.label;"
+ accesskey="&markAsReadCmd.accesskey;"
+ command="cmd_markAsRead" />
+ <menuitem id="markUnreadToolbarItem"
+ label="&markAsUnreadCmd.label;"
+ accesskey="&markAsUnreadCmd.accesskey;"
+ command="cmd_markAsUnread" />
+ <menuitem id="button-markThreadAsRead"
+ label="&markThreadAsReadCmd.label;"
+ key="key_markThreadAsRead"
+ accesskey="&markThreadAsReadCmd.accesskey;"
+ command="cmd_markThreadAsRead"/>
+ <menuitem id="button-markReadByDate"
+ label="&markReadByDateCmd.label;"
+ key="key_markReadByDate"
+ accesskey="&markReadByDateCmd.accesskey;"
+ command="cmd_markReadByDate"/>
+ <menuitem id="button-markAllRead"
+ label="&markAllReadCmd.label;"
+ key="key_markAllRead"
+ accesskey="&markAllReadCmd.accesskey;"
+ command="cmd_markAllRead"/>
+ <menuseparator id="button-markAllReadSeparator"/>
+ <menuitem id="markFlaggedToolbarItem"
+ type="checkbox"
+ label="&markStarredCmd.label;"
+ accesskey="&markStarredCmd.accesskey;"
+ key="key_toggleFlagged"
+ command="cmd_markAsFlagged"/>
+ </menupopup>
+ </toolbarbutton>
+ <toolbarbutton id="button-tag"
+ type="menu"
+ class="toolbarbutton-1"
+ label="&tagButton.label;"
+ tooltiptext="&tagButton.tooltip;"
+ command="cmd_tag">
+ <menupopup id="button-tagpopup"
+ onpopupshowing="InitMessageTags(this);">
+ <menuitem id="addNewTag"
+ label="&addNewTag.label;"
+ accesskey="&addNewTag.accesskey;"
+ command="cmd_addTag"/>
+ <menuitem id="manageTags"
+ label="&manageTags.label;"
+ accesskey="&manageTags.accesskey;"
+ command="cmd_manageTags"/>
+ <menuseparator id="button-tagpopup-sep-afterTagAddNew"/>
+ <menuitem id="button-tagRemoveAll"
+ command="cmd_removeTags"/>
+ <menuseparator id="button-afterTagRemoveAllSeparator"/>
+ </menupopup>
+ </toolbarbutton>
+ <toolbarbutton id="button-address"
+ class="toolbarbutton-1"
+ label="&addressBookButton.label;"
+ oncommand="toAddressBook();"
+ tooltiptext="&addressBookButton.tooltip;"/>
+ <toolbarbutton id="button-chat"
+ class="toolbarbutton-1"
+ label="&chatButton.label;"
+ command="cmd_chat"
+ observes="cmd_chat"
+ tooltiptext="&chatButton.tooltip;"/>
+ <toolbaritem id="throbber-box" title="&throbberItem.title;" align="center" pack="center"
+ mousethrough="always">
+ <image/>
+ </toolbaritem>
+ <toolbarbutton id="button-stop"
+ class="toolbarbutton-1"
+ label="&stopButton.label;"
+ tooltiptext="&stopButton.tooltip;"
+ command="cmd_stop"/>
+ <toolbarbutton id="button-appmenu"
+ class="toolbarbutton-1 button-appmenu"
+ label="&appmenuButton.label;"
+ tooltiptext="&appmenuButton1.tooltip;"/>
+ </toolbarpalette>
+
+ <!-- If changes are made to the default set of toolbar buttons, you may need to rev the id
+ of mail-bar in order to force the new default items to show up for users who customized their toolbar
+ in earlier versions. Bumping the id means users will have to re-customize their toolbar!
+ -->
+
+ <toolbar id="mail-bar3"
+ class="inline-toolbar chromeclass-toolbar"
+ toolbarname="&showMessengerToolbarCmd.label;"
+ accesskey="&showMessengerToolbarCmd.accesskey;"
+ fullscreentoolbar="true" mode="full"
+ customizable="true"
+ context="toolbar-context-menu"
+#ifdef XP_MACOSX
+ iconsize="small"
+ defaultset="button-getmsg,button-newmsg,button-chat,button-address,spacer,button-tag,qfb-show-filter-bar,spring,gloda-search,button-appmenu">
+#else
+ defaultset="button-getmsg,button-newmsg,button-chat,button-address,separator,button-tag,qfb-show-filter-bar,spring,gloda-search,button-appmenu">
+#endif
+ </toolbar>
+
+ <toolbarset id="customToolbars" context="toolbar-context-menu"/>
+</toolbox>
+
+<!-- The msgNotificationBar appears on top of the message and displays
+ information like: junk, contains remote images, or is a suspected phishing
+ URL.
+-->
+<deck id="msgNotificationBar" selectedIndex="0" collapsed="true">
+ <hbox id="msgNotificationNoStatus"/>
+
+ <hbox id="phishingBar" class="msgNotificationBar" align="center">
+ <image id="phishingBarImage"/>
+ <vbox flex="1">
+ <description flex="1" class="msgNotificationBarText">&phishingBarMessage2.label;</description>
+ <label id="disablePhishingWarning" class="msgNotificaton-smallText text-link"
+ value="&disablePhishingWarning1.label;" onclick="DisablePhishingWarning();"/>
+ <label id="reportPhishingError" value="&reportPhishingError1.label;" class="msgNotificaton-smallText text-link" collapsed="true"/>
+ </vbox>
+ <button label="&removePhishingBarButton1.label;" oncommand="IgnorePhishingWarning();"/>
+ </hbox>
+
+ <hbox id="junkBar" class="msgNotificationBar" align="center">
+ <image id="junkBarImage"/>
+ <description flex="1" class="msgNotificationBarText">&junkBarMessage2.label;</description>
+ <button label="&junkBarButton1.label;" oncommand="JunkSelectedMessages(false);"/>
+ </hbox>
+
+ <hbox id="remoteContentBar" class="msgNotificationBar" align="center">
+ <image id="remoteContentImage"/>
+ <vbox flex="1">
+ <description class="msgNotificationBarText">&remoteContentMessage2.label;</description>
+ <label id="allowRemoteContentForAuthorDesc" class="msgNotificaton-smallText text-link"
+ crop="end"
+ onclick="allowRemoteContentForSender();"/>
+ </vbox>
+ <button id="remoteContentBarButton" label="&loadRemoteContentButton3.label;"
+ oncommand="LoadMsgWithRemoteContent();"/>
+ </hbox>
+
+ <hbox id="mdnBar" class="msgNotificationBar" align="center">
+ <image id="mdnBarImage"/>
+ <description id="mdnBarMessage" class="msgNotificationBarText" flex="1"/>
+ <button label="&mdnBarIgnoreButton2.label;"
+ accesskey="&mdnBarIgnoreButton2.accesskey;"
+ oncommand="IgnoreMDNResponse();"/>
+ <button label="&mdnBarSendButton2.label;"
+ accesskey="&mdnBarSendButton2.accesskey;"
+ oncommand="SendMDNResponse();"/>
+ </hbox>
+ <hbox id="SMIMEReceiptRequestBar" class="msgNotificationBar" align="center">
+ <image id="SMIMEReceiptRequestBarImage"/>
+ <vbox flex="1">
+ <description flex="1" class="msgNotificationBarText">
+ &SMIMEReceiptRequestBarMessage.label;
+ <label id="SMIMEReceiptRequestBarRecipient" class="msgNotificaton-smallText"/>
+ </description>
+ </vbox>
+ <button label="&SMIMEReceiptRequestBarIgnoreButton.label;" oncommand="IgnoreSMIMEReceipt();"/>
+ <button label="&SMIMEReceiptRequestBarSendButton.label;" oncommand="SendSMIMEReceipt();"/>
+ </hbox>
+
+ <hbox id="SMIMEReceiptVerifiedBar" class="msgNotificationBar" align="center">
+ <image id="SMIMEReceiptBarImage"/>
+ <description flex="1" class="msgNotificationBarText">&SMIMEReceiptVerifiedBarMessage.label;</description>
+ <button id="SMIMEReceiptBarOpenMessageButton" label="&SMIMEReceiptBarOpenMessageButton.label;" oncommand="OpenSMIMEReceiptRequestMessage();"/>
+ </hbox>
+
+ <hbox id="SMIMEReceiptNotVerifiedBar" class="msgNotificationBar" align="center">
+ <image id="SMIMEReceiptBarImage"/>
+ <description flex="1" class="msgNotificationBarText">&SMIMEReceiptNotVerifiedBarMessage.label;</description>
+ </hbox>
+
+</deck>
+
+<statusbar class="chromeclass-status" id="status-bar">
+ <hbox insertbefore="unreadMessageCount" id="statusTextBox" flex="1">
+ <statusbarpanel id="offline-status" class="statusbarpanel-iconic" oncommand="MailOfflineMgr.toggleOfflineStatus();"/>
+ <statusbarpanel id="statusText" label="&statusText.label;" flex="1"/>
+ <statusbarpanel class="statusbarpanel-progress" collapsed="true" id="statusbar-progresspanel">
+ <progressmeter class="progressmeter-statusbar" id="statusbar-icon" mode="normal" value="0"/>
+ </statusbarpanel>
+ <statusbarpanel class="statusbarpanel-progress"
+ id="quotaPanel" hidden="true">
+ <stack>
+ <progressmeter class="progressmeter-statusbar"
+ id="quotaMeter"
+ mode="normal"
+ value="0" />
+ <label id="quotaLabel"
+ onclick="gFolderTreeController.editFolder('QuotaTab');" />
+ </stack>
+ </statusbarpanel>
+ </hbox>
+</statusbar>
+
+</overlay>
--- /dev/null
+# ***** 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 "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 Thunderbird unofficial branding.
+#
+# The Initial Developer of the Original Code is
+# Mozilla Messaging
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Banner <bugzilla@standard8.plus.com>
+#
+# 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 *****
+
+# Branding Makefile for nightlies/unofficial branding
+
+DEPTH = @DEPTH@
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+PREF_JS_EXPORTS += $(srcdir)/thunderbird-branding.js
+
+include $(topsrcdir)/config/rules.mk
+
+export::
+ $(NSINSTALL) -D $(DIST)/branding
+ifeq ($(OS_ARCH),WINNT)
+ cp $(srcdir)/thunderbird.ico $(DIST)/branding/thunderbird.ico
+ cp $(srcdir)/branding.nsi $(DIST)/branding/branding.nsi
+ cp $(srcdir)/wizHeader.bmp $(DIST)/branding/wizHeader.bmp
+ cp $(srcdir)/wizHeaderRTL.bmp $(DIST)/branding/wizHeaderRTL.bmp
+ cp $(srcdir)/wizWatermark.bmp $(DIST)/branding/wizWatermark.bmp
+endif
+ifeq (cocoa,$(MOZ_WIDGET_TOOLKIT))
+ cp $(srcdir)/background.png $(DIST)/branding/background.png
+ cp $(srcdir)/dsstore $(DIST)/branding/dsstore
+ cp $(srcdir)/disk.icns $(DIST)/branding/disk.icns
+ cp $(srcdir)/thunderbird.icns $(DIST)/branding/thunderbird.icns
+endif
+ifeq ($(MOZ_WIDGET_TOOLKIT),gtk2)
+ cp $(srcdir)/mailicon16.png $(DIST)/branding/default16.png
+ cp $(srcdir)/mailicon22.png $(DIST)/branding/default22.png
+ cp $(srcdir)/mailicon24.png $(DIST)/branding/default24.png
+ cp $(srcdir)/mailicon32.png $(DIST)/branding/default32.png
+ cp $(srcdir)/mailicon48.png $(DIST)/branding/default48.png
+ cp $(srcdir)/mailicon256.png $(DIST)/branding/default256.png
+endif
+ifeq ($(OS_ARCH),OS2)
+ cp $(srcdir)/thunderbird-os2.ico $(DIST)/branding/thunderbird.ico
+endif
+
+# Now sort out the branding specific icons
+ifeq ($(OS_ARCH),WINNT)
+ cp $(srcdir)/windows/messengerWindow.ico $(DIST)/branding/messengerWindow.ico
+endif
+ifeq ($(OS_ARCH),OS2)
+ cp $(srcdir)/os2/messengerWindow.ico $(DIST)/branding/messengerWindow.ico
+endif
--- /dev/null
+# ***** 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 "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 the Mozilla Installer code.
+#
+# The Initial Developer of the Original Code is Mozilla Foundation
+# Portions created by the Initial Developer are Copyright (C) 2006
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Robert Strong <robert.bugzilla@gmail.com>
+#
+# 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 *****
+
+# NSIS defines for nightly builds.
+# The release build branding.nsi is located in other-license/branding/thunderbird/
+
+# BrandFullNameInternal is used for some registry and file system values
+# instead of BrandFullName and typically should not be modified.
+!define BrandFullNameInternal "Trustedbird"
+!define CompanyName "trustedbird.org"
+!define URLInfoAbout "http://www.trustedbird.org/"
+!define URLUpdateInfo "http://www.trustedbird.org/"
+!define SurveyURL ""
--- /dev/null
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+MOZ_APP_DISPLAYNAME=Trustedbird
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */\r
+\r
+\r
+#aboutDialogContainer {\r
+ /*background-image: url("chrome://branding/content/about-background.png");\r
+ background-repeat: no-repeat;*/\r
+ background-color: #ce5c00;\r
+ color: #fff;\r
+}\r
+\r
+.text-link {\r
+ color: #33f !important;\r
+}\r
+\r
+.bottom-link {\r
+ color: #fff !important;\r
+}\r
+\r
+#rightBox {\r
+ background-image: url("chrome://branding/content/about-wordmark.png");\r
+ background-repeat: no-repeat;\r
+ /* padding-top creates room for the wordmark */\r
+ padding-top: 38px;\r
+ margin-top:20px;\r
+ margin-left: 30px;\r
+ margin-right: 30px;\r
+}\r
+\r
+#bottomBox {\r
+ background-color: rgba(0,0,0,.7);\r
+}\r
+\r
+#clientBox {\r
+ background-color: #F7F7F7;\r
+ color: #222222;\r
+}\r
+\r
+#leftBox {\r
+ background-image: url("chrome://branding/content/about-logo.png");\r
+ background-repeat: no-repeat;\r
+ /* min-width and min-height create room for the logo */\r
+ min-width: 310px;\r
+ min-height: 210px;\r
+ margin-top:20px;\r
+ -moz-margin-start: 30px;\r
+}\r
+\r
+\r
+\r
+#updateDeck > hbox > label:not([class="text-link"]) {\r
+ color: #909090;\r
+}\r
+\r
+#trademark {\r
+ font-size: xx-small;\r
+ text-align: center;\r
+ color: #999999;\r
+ margin-top: 10px;\r
+ margin-bottom: 10px;\r
+}\r
--- /dev/null
+#filter substitution
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+messenger.jar:
+% content branding %content/branding/
+ content/branding/about-background.png (content/about-background.png)
+ content/branding/about-logo.png (content/about-logo.png)
+ content/branding/about-wordmark.png (content/about-wordmark.png)
+ content/branding/about.png (content/about.png)
+ content/branding/icon48.png (content/icon48.png)
+ content/branding/icon64.png (content/icon64.png)
+ content/branding/aboutDialog.css (content/aboutDialog.css)
+ ../classic/skin/classic/messenger/icons/new-mail-alert.png (content/icon48.png)
+#ifdef XP_WIN
+ ../classic/skin/classic/aero/messenger/icons/new-mail-alert.png (content/icon48.png)
+#endif
--- /dev/null
+# ***** 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 "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 Thunderbird unofficial branding.
+#
+# The Initial Developer of the Original Code is
+# Mozilla Messaging
+# Portions created by the Initial Developer are Copyright (C) 2008
+# the Initial Developer. All Rights Reserved.
+#
+# Contributor(s):
+# Mark Banner <bugzilla@standard8.plus.com>
+#
+# 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 *****
+
+DEPTH = @DEPTH@
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+relativesrcdir = @relativesrcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+DEFINES += -DAB_CD=$(AB_CD) -DMOZ_DISTRIBUTION_ID_UNQUOTED=$(MOZ_DISTRIBUTION_ID)
+
+include $(topsrcdir)/config/rules.mk
--- /dev/null
+<!ENTITY brandShortName "Trustedbird">
+<!ENTITY brandFullName "Trustedbird">
+<!ENTITY vendorShortName "trustedbird.org">
+<!ENTITY logoTrademark " ">
+<!ENTITY trademarkInfo.part1 " ">
--- /dev/null
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+brandShortName=Trustedbird
+brandFullName=Trustedbird
+vendorShortName=trustedbird.org
--- /dev/null
+#filter substitution
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+@AB_CD@.jar:
+% locale branding @AB_CD@ %locale/branding/
+# Shredder branding only exists in en-US
+ locale/branding/brand.dtd (en-US/brand.dtd)
+ locale/branding/brand.properties (en-US/brand.properties)
--- /dev/null
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
--- /dev/null
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DIRS += ['locales']
+
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// Default start page
+pref("mailnews.start_page.url","");
+
+// first launch welcome page
+pref("mailnews.start_page.welcome_url","");
+
+// start page override to load after an update
+pref("mailnews.start_page.override_url","");
+
+// Interval: Time between checks for a new version (in seconds)
+// nightly=8 hours, official=24 hours
+pref("app.update.interval", 28800);
+
+// The time interval between the downloading of mar file chunks in the
+// background (in seconds)
+pref("app.update.download.backgroundInterval", 60);
+
+// Give the user x seconds to react before showing the big UI. nightly=1 hour
+pref("app.update.promptWaitTime", 3600);
+
+pref("app.vendorURL", "");
--- /dev/null
+#! /bin/sh
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+MOZ_APP_BASENAME=Thunderbird
+MOZ_APP_NAME=trustedbird
+MOZ_UPDATER=1
+MOZ_THUNDERBIRD=1
+MOZ_CHROME_FILE_FORMAT=omni
+MOZ_NO_ACTIVEX_SUPPORT=1
+MOZ_ACTIVEX_SCRIPTING_SUPPORT=
+MOZ_LDAP_XPCOM=1
+MOZ_COMPOSER=1
+if test "$OS_ARCH" = "WINNT"; then
+ if ! test "$HAVE_64BIT_OS"; then
+ MOZ_VERIFY_MAR_SIGNATURE=1
+ MOZ_MAINTENANCE_SERVICE=1
+ fi
+fi
+
+# Disable Accessibility on Mac for now as unit tests fail (bug 862238).
+if test "$OS_ARCH" = "Darwin"; then
+ ACCESSIBILITY=
+fi
+
+MOZ_SAFE_BROWSING=1
+MOZ_MEDIA_NAVIGATOR=1
+MOZ_MORK=1
+MAIL_COMPONENT="mail msgsmime import"
+MAIL_MODULE="MODULE(nsMailModule) MODULE(nsMsgSMIMEModule) MODULE(nsImportServiceModule)"
+if test -n "$_WIN32_MSVC"; then
+ MAIL_COMPONENT="$MAIL_COMPONENT msgMapi"
+ MAIL_MODULE="$MAIL_MODULE MODULE(msgMapiModule)"
+fi
+
+MOZ_APP_VERSION_TXT=${_topsrcdir}/$MOZ_BUILD_APP/config/version.txt
+MOZ_APP_VERSION=`cat $MOZ_APP_VERSION_TXT`
+THUNDERBIRD_VERSION=$MOZ_APP_VERSION
+
+MOZ_UA_BUILDID=20100101
+
+MOZ_BRANDING_DIRECTORY=mail/branding/trustedbird
+MOZ_OFFICIAL_BRANDING_DIRECTORY=other-licenses/branding/thunderbird
+MOZ_APP_ID={3550f703-e582-4d05-9a08-453d09bdfdc6}
+# This should usually be the same as the value MAR_CHANNEL_ID.
+# If more than one ID is needed, then you should use a comma separated list
+# of values.
+ACCEPTED_MAR_CHANNEL_IDS=thunderbird-comm-release
+# The MAR_CHANNEL_ID must not contain the following 3 characters: ",\t "
+MAR_CHANNEL_ID=thunderbird-comm-release
--- /dev/null
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Copyright(c) Airbus Defence ans Space - all rights reserved */
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+// Account encryption policy values:
+// const kEncryptionPolicy_Never = 0;
+// 'IfPossible' was used by ns4.
+// const kEncryptionPolicy_IfPossible = 1;
+const kEncryptionPolicy_Always = 2;
+
+var gEncryptedURIService =
+ Components.classes["@mozilla.org/messenger-smime/smime-encrypted-uris-service;1"]
+ .getService(Components.interfaces.nsIEncryptedSMIMEURIsService);
+
+var gNextSecurityButtonCommand = "";
+var gSMFields = null;
+
+var gEncryptOptionChanged;
+var gSignOptionChanged;
+
+var gSecurityLabelConf = null;
+
+function onComposerClose()
+{
+ gSMFields = null;
+ setNoEncryptionUI();
+ setNoSignatureUI();
+ setSecurityLabelStatusBarUI();
+ setNoSecureHeaderUI();
+
+ if (!gMsgCompose || !gMsgCompose.compFields)
+ return;
+
+ gMsgCompose.compFields.securityInfo = null;
+}
+
+function onComposerReOpen()
+{
+ // Are we already set up ? Or are the required fields missing ?
+ if (gSMFields || !gMsgCompose || !gMsgCompose.compFields)
+ return;
+
+ gMsgCompose.compFields.securityInfo = null;
+
+ gSMFields = Components.classes["@mozilla.org/messenger-smime/composefields;1"]
+ .createInstance(Components.interfaces.nsIMsgSMIMECompFields);
+ if (!gSMFields)
+ return;
+
+ gMsgCompose.compFields.securityInfo = gSMFields;
+
+ // Set up the intial security state.
+ gSMFields.requireEncryptMessage =
+ gCurrentIdentity.getIntAttribute("encryptionpolicy") == kEncryptionPolicy_Always;
+ if (!gSMFields.requireEncryptMessage &&
+ gEncryptedURIService &&
+ gEncryptedURIService.isEncrypted(gMsgCompose.originalMsgURI))
+ {
+ // Override encryption setting if original is known as encrypted.
+ gSMFields.requireEncryptMessage = true;
+ }
+ if (gSMFields.requireEncryptMessage)
+ setEncryptionUI();
+ else
+ setNoEncryptionUI();
+
+ gSMFields.signMessage = gCurrentIdentity.getBoolAttribute("sign_mail");
+ if (gSMFields.signMessage)
+ setSignatureUI();
+ else
+ setNoSignatureUI();
+
+ if (gSMFields.signMessage)
+ gSMFields.SMIMEReceiptRequest = gCurrentIdentity.getBoolAttribute("smime_receipt_request");
+
+ setSecurityLabelStatusBarUI();
+ setNoSecureHeaderUI();
+}
+
+addEventListener("load", smimeComposeOnLoad, false);
+
+// this function gets called multiple times,
+// but only on first open, not on composer recycling
+function smimeComposeOnLoad()
+{
+ removeEventListener("load", smimeComposeOnLoad, false);
+
+ onComposerReOpen();
+
+ top.controllers.appendController(SecurityController);
+
+ addEventListener("compose-from-changed", onComposerFromChanged, true);
+ addEventListener("compose-send-message", onComposerSendMessage, true);
+ addEventListener("compose-window-close", onComposerClose, true);
+ addEventListener("compose-window-reopen", onComposerReOpen, true);
+
+ addEventListener("unload", smimeComposeOnUnload, false);
+}
+
+function smimeComposeOnUnload()
+{
+ removeEventListener("unload", smimeComposeOnUnload, false);
+
+ removeEventListener("compose-from-changed", onComposerFromChanged, true);
+ removeEventListener("compose-send-message", onComposerSendMessage, true);
+ removeEventListener("compose-window-close", onComposerClose, true);
+ removeEventListener("compose-window-reopen", onComposerReOpen, true);
+
+ top.controllers.removeController(SecurityController);
+}
+
+// stub routine to make our call to MsgAccountManager work correctly
+function GetSelectedFolderURI()
+{
+ return;
+}
+
+function GetServer(uri)
+{
+ let servers = gAccountManager.getServersForIdentity(gCurrentIdentity);
+ return servers.queryElementAt(0, Components.interfaces.nsIMsgIncomingServer);
+}
+
+function showNeedSetupInfo()
+{
+ let compSmimeBundle = document.getElementById("bundle_comp_smime");
+ let brandBundle = document.getElementById("bundle_brand");
+ if (!compSmimeBundle || !brandBundle)
+ return;
+
+ let buttonPressed =
+ Services.prompt.confirmEx(window,
+ brandBundle.getString("brandShortName"),
+ compSmimeBundle.getString("NeedSetup"),
+ Services.prompt.STD_YES_NO_BUTTONS, 0, 0, 0, null, {});
+ if (buttonPressed == 0)
+ MsgAccountManager("am-smime.xul");
+}
+
+function toggleEncryptMessage()
+{
+ if (!gSMFields)
+ return;
+
+ gSMFields.requireEncryptMessage = !gSMFields.requireEncryptMessage;
+
+ if (gSMFields.requireEncryptMessage)
+ {
+ // Make sure we have a cert.
+ if (!gCurrentIdentity.getUnicharAttribute("encryption_cert_name"))
+ {
+ gSMFields.requireEncryptMessage = false;
+ showNeedSetupInfo();
+ return;
+ }
+
+ setEncryptionUI();
+ }
+ else
+ {
+ setNoEncryptionUI();
+ }
+
+ gEncryptOptionChanged = true;
+}
+
+function toggleSignMessage()
+{
+ if (!gSMFields)
+ return;
+
+ gSMFields.signMessage = !gSMFields.signMessage;
+
+ if (gSMFields.signMessage) // make sure we have a cert name...
+ {
+ if (!gCurrentIdentity.getUnicharAttribute("signing_cert_name"))
+ {
+ gSMFields.signMessage = false;
+ showNeedSetupInfo();
+ return;
+ }
+
+ gSMFields.SMIMEReceiptRequest = gCurrentIdentity.getBoolAttribute("smime_receipt_request");
+
+ setSignatureUI();
+ }
+ else
+ {
+ gSMFields.SMIMEReceiptRequest = false;
+
+ gSMFields.securityPolicyIdentifier = "";
+ setSecurityLabelStatusBarUI();
+ setNoSignatureUI();
+ }
+
+ gSignOptionChanged = true;
+}
+
+function toggleSMIMEReceiptRequest()
+{
+ if (!gSMFields)
+ return;
+
+ gSMFields.SMIMEReceiptRequest = !gSMFields.SMIMEReceiptRequest;
+
+ if (gSMFields.SMIMEReceiptRequest)
+ {
+ var signingCertName = gCurrentIdentity.getUnicharAttribute("signing_cert_name");
+
+ if (!signingCertName)
+ {
+ gSMFields.SMIMEReceiptRequest = false;
+ showNeedSetupInfo();
+ return;
+ }
+
+ // Force signing
+ gSMFields.signMessage = true;
+
+ setSignatureUI();
+ }
+}
+
+function setSecuritySettings(menu_id)
+{
+ if (!gSMFields)
+ return;
+
+ document.getElementById("menu_securityEncryptRequire" + menu_id)
+ .setAttribute("checked", gSMFields.requireEncryptMessage);
+ document.getElementById("menu_securitySign" + menu_id)
+ .setAttribute("checked", gSMFields.signMessage);
+ document.getElementById("menu_securitySMIMEReceiptRequest" + menu_id)
+ .setAttribute("checked", gSMFields.SMIMEReceiptRequest);
+}
+
+function setNextCommand(what)
+{
+ gNextSecurityButtonCommand = what;
+}
+
+function doSecurityButton()
+{
+ var what = gNextSecurityButtonCommand;
+ gNextSecurityButtonCommand = "";
+
+ switch (what)
+ {
+ case "encryptMessage":
+ toggleEncryptMessage();
+ break;
+
+ case "signMessage":
+ toggleSignMessage();
+ break;
+
+ case "SMIMEReceiptRequest":
+ toggleSMIMEReceiptRequest();
+ break;
+
+ case "securityLabelDialog":
+ showSecurityLabelDialog();
+ break;
+ case "secureHeaders":
+ toogleSecureHeaders();
+ break;
+ case "show":
+ default:
+ showMessageComposeSecurityStatus();
+ }
+}
+
+function setNoSignatureUI()
+{
+ top.document.getElementById("securityStatus").removeAttribute("signing");
+ top.document.getElementById("signing-status").collapsed = true;
+ setNoSecureHeaderUI();
+}
+
+function setSignatureUI()
+{
+ top.document.getElementById("securityStatus").setAttribute("signing", "ok");
+ top.document.getElementById("signing-status").collapsed = false;
+}
+
+function setNoEncryptionUI()
+{
+ top.document.getElementById("securityStatus").removeAttribute("crypto");
+ top.document.getElementById("encryption-status").collapsed = true;
+}
+
+function setEncryptionUI()
+{
+ top.document.getElementById("securityStatus").setAttribute("crypto", "ok");
+ top.document.getElementById("encryption-status").collapsed = false;
+}
+
+function showMessageComposeSecurityStatus()
+{
+ Recipients2CompFields(gMsgCompose.compFields);
+
+ var secureHeaderCheck = "false";
+ if ( top.document.getElementById("secureHeaderStatus").hasAttribute("checked")) {
+ secureHeaderCheck = top.document.getElementById("secureHeaderStatus").getAttribute("checked");
+ }
+
+ window.openDialog(
+ "chrome://messenger-smime/content/msgCompSecurityInfo.xul",
+ "",
+ "chrome,modal,resizable,centerscreen",
+ {
+ compFields : gMsgCompose.compFields,
+ subject : GetMsgSubjectElement().value,
+ smFields : gSMFields,
+ isSigningCertAvailable :
+ gCurrentIdentity.getUnicharAttribute("signing_cert_name") != "",
+ isEncryptionCertAvailable :
+ gCurrentIdentity.getUnicharAttribute("encryption_cert_name") != "",
+ isSecureHeaderAvailable : secureHeaderCheck,
+ currentIdentity : gCurrentIdentity
+ }
+ );
+}
+
+var SecurityController =
+{
+ supportsCommand: function(command)
+ {
+ switch (command)
+ {
+ case "cmd_viewSecurityStatus":
+ return true;
+
+ default:
+ return false;
+ }
+ },
+
+ isCommandEnabled: function(command)
+ {
+ switch (command)
+ {
+ case "cmd_viewSecurityStatus":
+ return true;
+
+ default:
+ return false;
+ }
+ }
+};
+
+function onComposerSendMessage()
+{
+ let missingCount = new Object();
+ let emailAddresses = new Object();
+
+ try
+ {
+ if (!gMsgCompose.compFields.securityInfo.requireEncryptMessage)
+ return;
+
+ Components.classes["@mozilla.org/messenger-smime/smimejshelper;1"]
+ .createInstance(Components.interfaces.nsISMimeJSHelper)
+ .getNoCertAddresses(gMsgCompose.compFields,
+ missingCount,
+ emailAddresses);
+ }
+ catch (e)
+ {
+ return;
+ }
+
+ if (missingCount.value > 0)
+ {
+ // The rules here: If the current identity has a directoryServer set, then
+ // use that, otherwise, try the global preference instead.
+
+ let autocompleteDirectory;
+
+ // Does the current identity override the global preference?
+ if (gCurrentIdentity.overrideGlobalPref)
+ {
+ autocompleteDirectory = gCurrentIdentity.directoryServer;
+ }
+ else
+ {
+ // Try the global one
+ if (Services.prefs.getBoolPref("ldap_2.autoComplete.useDirectory"))
+ autocompleteDirectory =
+ Services.prefs.getCharPref("ldap_2.autoComplete.directoryServer");
+ }
+
+ if (autocompleteDirectory)
+ window.openDialog("chrome://messenger-smime/content/certFetchingStatus.xul",
+ "",
+ "chrome,modal,resizable,centerscreen",
+ autocompleteDirectory,
+ emailAddresses.value);
+ }
+}
+
+function onComposerFromChanged()
+{
+ if (!gSMFields)
+ return;
+
+ var encryptionPolicy = gCurrentIdentity.getIntAttribute("encryptionpolicy");
+ var useEncryption = false;
+ if (!gEncryptOptionChanged)
+ {
+ // Encryption wasn't manually checked.
+ // Set up the encryption policy from the setting of the new identity.
+
+ useEncryption = (encryptionPolicy == kEncryptionPolicy_Always);
+ }
+ else
+ {
+ // The encryption policy was manually checked. That means we can get into
+ // the situation that the new identity doesn't have a cert to encrypt with.
+ // If it doesn't, don't encrypt.
+
+ if (encryptionPolicy != kEncryptionPolicy_Always) // Encrypted (policy unencrypted, manually changed).
+ {
+ // Make sure we have a cert for encryption.
+ useEncryption = !!gCurrentIdentity.getUnicharAttribute("encryption_cert_name");
+ }
+ }
+ gSMFields.requireEncryptMessage = useEncryption;
+ if (useEncryption)
+ setEncryptionUI();
+ else
+ setNoEncryptionUI();
+
+ var signMessage = gCurrentIdentity.getBoolAttribute("sign_mail");
+ var useSigning = false;
+ if (!gSignOptionChanged)
+ {
+ // Signing wasn't manually checked.
+ // Set up the signing policy from the setting of the new identity.
+
+ useSigning = signMessage;
+ }
+ else
+ {
+ // The signing policy was manually checked. That means we can get into
+ // the situation that the new identity doesn't have a cert to sign with.
+ // If it doesn't, don't sign.
+
+ if (!signMessage) // Signed (policy unsigned, manually changed).
+ {
+ // Make sure we have a cert for signing.
+ useSigning = !!gCurrentIdentity.getUnicharAttribute("signing_cert_name");
+ }
+ }
+ gSMFields.signMessage = useSigning;
+ if (useSigning)
+ {
+ gSMFields.SMIMEReceiptRequest = gCurrentIdentity.getBoolAttribute("smime_receipt_request");
+ setSignatureUI();
+ }
+ else
+ {
+ gSMFields.SMIMEReceiptRequest = false;
+ setNoSignatureUI();
+ }
+
+ gSMFields.securityPolicyIdentifier = "";
+ setSecurityLabelStatusBarUI();
+}
+
+/**
+ * Show a dialog to define Security Label settings
+ */
+function showSecurityLabelDialog() {
+ window.openDialog('chrome://messenger-smime/content/msgCompSecurityLabelDialog.xul', '', 'chrome,resizable=yes,titlebar,modal,width=500,height=450');
+
+ /* make sure we have a cert name for signing */
+ if (gSMFields.securityPolicyIdentifier != "")
+ {
+ var signingCertName = gCurrentIdentity.getUnicharAttribute("signing_cert_name");
+ if (!signingCertName)
+ {
+ gSMFields.securityPolicyIdentifier = "";
+ setSecurityLabelStatusBarUI();
+ showNeedSetupInfo();
+ return;
+ }
+
+ // Enable signing if disabled
+ if (!gSMFields.signMessage)
+ toggleSignMessage();
+ }
+
+ setSecurityLabelStatusBarUI();
+}
+
+/**
+ * Display Security Label info in status bar of compose window
+ */
+function setSecurityLabelStatusBarUI() {
+ if (!gSMFields || gSMFields.securityPolicyIdentifier == "") {
+ top.document.getElementById("securityLabel-status").label = "";
+ top.document.getElementById("securityLabel-status").collapsed = true;
+ return;
+ }
+
+ if (!gSecurityLabelConf)
+ gSecurityLabelConf = new securityLabelConf();
+
+ var securityLabelValue = "";
+
+ if (gSMFields.securityClassification != -1)
+ securityLabelValue = gSecurityLabelConf.getSecurityClassificationName(gSMFields.securityPolicyIdentifier, gSMFields.securityClassification) + " ";
+
+ securityLabelValue += "[" + gSecurityLabelConf.getSecurityPolicyIdentifierName(gSMFields.securityPolicyIdentifier) + "]";
+ top.document.getElementById("securityLabel-status").label = securityLabelValue;
+ top.document.getElementById("securityLabel-status").collapsed = false;
+}
+
+/**
+*
+*/
+function toogleSecureHeaders () {
+ if (!gSMFields) {
+ return;
+ }
+ if (document.getElementById("secureHeaderStatus").hasAttribute("checked")) {
+ setNoSecureHeaderUI();
+ } else {
+ setSecureHeaderUI()
+ }
+
+}
+function setNoSecureHeaderUI() {
+ top.document.getElementById("secureHeaderStatus").removeAttribute("checked");
+}
+
+function setSecureHeaderUI() {
+ top.document.getElementById("secureHeaderStatus").setAttribute("checked", "true");
+ if (!gSMFields.signMessage) {
+ toggleSignMessage();
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ - Contributor(s):
+ - David Drinan <ddrinan@netscape.com>
+ - Scott MacGregor <mscott@netscape.com
+ - EADS Defence and Security Systems Copyright 2008 (c) All Rights Reserved
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved -->
+
+<?xml-stylesheet href="chrome://messenger/skin/smime/msgCompSMIMEOverlay.css" type="text/css"?>
+
+<!DOCTYPE overlay SYSTEM "chrome://messenger-smime/locale/msgCompSMIMEOverlay.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgCompSMIMEOverlay.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgSecurityLabel.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgCompSMIMESecureHeaders.js"/>
+
+ <window id="msgcomposeWindow">
+ <broadcasterset id="composeBroadcasters">
+ <broadcaster id="securityStatus" crypto="" signing=""/>
+ <broadcaster id="secureHeaderStatus" />
+ </broadcasterset>
+ <observes element="securityStatus" attribute="crypto" />
+ <observes element="securityStatus" attribute="signing" />
+ <stringbundle id="bundle_comp_smime" src="chrome://messenger-smime/locale/msgCompSMIMEOverlay.properties"/>
+ <stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
+ </window>
+
+ <menupopup id="optionsMenuPopup"
+ onpopupshowing="setSecuritySettings(1);">
+ <menuseparator id="smimeOptionsSeparator"/>
+
+ <menuitem id="menu_securityEncryptRequire1"
+ type="checkbox"
+ label="&menu_securityEncryptRequire.label;"
+ accesskey="&menu_securityEncryptRequire.accesskey;"
+ oncommand="toggleEncryptMessage();"/>
+ <menuitem id="menu_securitySign1"
+ type="checkbox"
+ label="&menu_securitySign.label;"
+ accesskey="&menu_securitySign.accesskey;"
+ oncommand="toggleSignMessage();"/>
+
+ <menuitem id="menu_securitySMIMEReceiptRequest1"
+ type="checkbox"
+ label="&menu_securitySMIMEReceiptRequest.label;"
+ accesskey="&menu_securitySMIMEReceiptRequest.accesskey;"
+ oncommand="toggleSMIMEReceiptRequest()"/>
+
+ <menuseparator id="menu_securityLabelDialogSeparator1"/>
+ <menuitem id="menu_securityLabelDialog1"
+ label="&menu_securityLabel.label;"
+ accesskey="&menu_securityLabel.accesskey;"
+ oncommand="showSecurityLabelDialog();"/>
+ <menuitem id="menu_securitySecureHeader1"
+ type="checkbox"
+ label="&menu.secureheaders.label;"
+ observes="secureHeaderStatus"
+ oncommand="toogleSecureHeaders();"/>
+</menupopup>
+
+ <toolbarpalette id="MsgComposeToolbarPalette">
+ <toolbarbutton id="button-security"
+ type="menu-button"
+ class="toolbarbutton-1"
+ label="&securityButton.label;"
+ tooltiptext="&securityButton.tooltip;"
+ oncommand="doSecurityButton();">
+ <menupopup onpopupshowing="setSecuritySettings(2);">
+ <menuitem id="menu_securityEncryptRequire2"
+ type="checkbox"
+ label="&menu_securityEncryptRequire.label;"
+ accesskey="&menu_securityEncryptRequire.accesskey;"
+ oncommand="setNextCommand('encryptMessage');"/>
+ <menuitem id="menu_securitySign2"
+ type="checkbox"
+ label="&menu_securitySign.label;"
+ accesskey="&menu_securitySign.accesskey;"
+ oncommand="setNextCommand('signMessage');"/>
+ <menuitem id="menu_securitySMIMEReceiptRequest2"
+ type="checkbox"
+ label="&menu_securitySMIMEReceiptRequest.label;"
+ accesskey="&menu_securitySMIMEReceiptRequest.accesskey;"
+ oncommand="setNextCommand('SMIMEReceiptRequest');"/>
+ <menuseparator id="menu_securityLabelDialogSeparator2"/>
+ <menuitem id="menu_securityLabelDialog2"
+ label="&menu_securityLabel.label;"
+ accesskey="&menu_securityLabel.accesskey;"
+ oncommand="setNextCommand('securityLabelDialog');"/>
+ <menuitem id="menu_securitySecureHeader2"
+ type="checkbox"
+ label="&menu.secureheaders.label;"
+ observes="secureHeaderStatus"
+ oncommand="setNextCommand('secureHeaders');"/>
+ <menuseparator id="smimeToolbarButtonSeparator"/>
+ <menuitem id="menu_securityStatus2"
+ label="&menu_securityStatus.label;"
+ accesskey="&menu_securityStatus.accesskey;"
+ oncommand="setNextCommand('show');"/>
+ </menupopup>
+ </toolbarbutton>
+ </toolbarpalette>
+
+ <statusbar id="status-bar">
+ <statusbarpanel insertbefore="offline-status" class="statusbarpanel-iconic" collapsed="true"
+ id="signing-status" oncommand="showMessageComposeSecurityStatus();"/>
+ <statusbarpanel insertbefore="offline-status" class="statusbarpanel-text" collapsed="true"
+ id="securityLabel-status" onclick="showSecurityLabelDialog();"/>
+ <statusbarpanel insertbefore="offline-status" class="statusbarpanel-iconic" collapsed="true"
+ id="encryption-status" oncommand="showMessageComposeSecurityStatus();"/>
+ </statusbar>
+
+ <commandset id="composeCommands">
+ <command id="cmd_viewSecurityStatus" oncommand="showMessageComposeSecurityStatus();"/>
+ </commandset>
+
+ <menupopup id="menu_View_Popup">
+ <menuseparator id="viewMenuBeforeSecurityStatusSeparator"/>
+ <menuitem id="menu_viewSecurityStatus"
+ label="&menu_viewSecurityStatus.label;"
+ accesskey="&menu_viewSecurityStatus.accesskey;"
+ command="cmd_viewSecurityStatus"/>
+ </menupopup>
+
+</overlay>
--- /dev/null
+/* -*- Mode: JavaScript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Scott MacGregor <mscott@netscape.com>
+ * ESS Signed Receipts: Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ * Secure headers : Copyright (c) 2011 CASSIDIAN - All rights reserved
+ * Secure headers : Copyright(c) Airbus Defence and Space 2014 - All rights reserved
+ */
+
+const MSG_FLAG_SIGNED_RECEIPT_SENT = 0x2000000;
+const nsIMsgSMIMESecureHeader = Components.interfaces.nsIMsgSMIMESecureHeader;
+const nsIMimeConverter = Components.interfaces.nsIMimeConverter;
+const nsIMIMEHeaderParam = Components.interfaces.nsIMIMEHeaderParam;
+const nsIArray = Components.interfaces.nsIArray;
+
+var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
+var gSignedUINode = null;
+var gEncryptedUINode = null;
+var gSMIMEContainer = null;
+var gStatusBar = null;
+var gSMIMEInfoMsg = null;
+var gSMIMEInfoMsgMore = null;
+
+var gEncryptedURIService = null;
+var gMyLastEncryptedURI = null;
+
+var gSMIMEBundle = null;
+
+// manipulates some globals from msgReadSMIMEOverlay.js
+const nsICMSMessageErrors = Components.interfaces.nsICMSMessageErrors;
+
+var smimeHeaderSink =
+{
+ maxWantedNesting: function()
+ {
+ return 1;
+ },
+
+ signedStatus: function(aNestingLevel, aSignatureStatus, aSignerCert)
+ {
+ if (aNestingLevel > 1) {
+ // we are not interested
+ return;
+ }
+
+ gSignatureStatus = aSignatureStatus;
+ gSignerCert = aSignerCert;
+
+ gSMIMEContainer.collapsed = false;
+ gSignedUINode.collapsed = false;
+ //gConsole.logStringMessage("[smimeHeaderSink:smimeHeaderSink] nsICMSMessageErrors : " + aSignatureStatus);
+ switch (aSignatureStatus) {
+ case nsICMSMessageErrors.SUCCESS:
+ gSignedUINode.setAttribute("signed", "ok");
+ gStatusBar.setAttribute("signed", "ok");
+ gSMIMEInfoMsg.setAttribute("value", gSMIMEBundle.getString("secureinfomsg_ok"));
+ gSMIMEInfoMsgMore.value=gSMIMEBundle.getString("secureinfomsgmore_ok").replace(/<BR>/g,"\n");
+ setSMIMEInfoMsg("ok");
+ break;
+
+ case nsICMSMessageErrors.VERIFY_NOT_YET_ATTEMPTED:
+ gSignedUINode.setAttribute("signed", "unknown");
+ gStatusBar.setAttribute("signed", "unknown");
+ break;
+
+ case nsICMSMessageErrors.VERIFY_CERT_WITHOUT_ADDRESS:
+ case nsICMSMessageErrors.VERIFY_HEADER_MISMATCH:
+ gSignedUINode.setAttribute("signed", "mismatch");
+ gStatusBar.setAttribute("signed", "mismatch");
+ break;
+
+ default:
+ gSignedUINode.setAttribute("signed", "notok");
+ gStatusBar.setAttribute("signed", "notok");
+ gSMIMEInfoMsg.setAttribute("value", gSMIMEBundle.getString("secureinfomsg_notok"));
+ gSMIMEInfoMsgMore.value=gSMIMEBundle.getString("secureinfomsgmore_notok").replace(/<BR>/g,"\n");
+ setSMIMEInfoMsg("notok");
+ break;
+ }
+
+ // If certificate is not null, display subject name
+ if(gSignerCert != null) {
+ var signerValueField = document.getElementById("expandedsignerBox");
+ if(signerValueField != null) {
+ //gConsole.logStringMessage("Set subject name: " + gSignerCert.subjectName);
+ signerValueField.headerValue = gSignerCert.subjectName;
+ }
+ else {
+ gConsole.logStringMessage("Cannot find UI signer box");
+ }
+ }
+ else {
+ gConsole.logStringMessage("No certificate");
+ signerValueField.headerValue = "";
+ }
+ },
+
+ encryptionStatus: function(aNestingLevel, aEncryptionStatus, aRecipientCert)
+ {
+ if (aNestingLevel > 1) {
+ // we are not interested
+ return;
+ }
+
+ gEncryptionStatus = aEncryptionStatus;
+ gEncryptionCert = aRecipientCert;
+
+ gSMIMEContainer.collapsed = false;
+ gEncryptedUINode.collapsed = false;
+
+ if (nsICMSMessageErrors.SUCCESS == aEncryptionStatus)
+ {
+ gEncryptedUINode.setAttribute("encrypted", "ok");
+ gStatusBar.setAttribute("encrypted", "ok");
+ }
+ else
+ {
+ gEncryptedUINode.setAttribute("encrypted", "notok");
+ gStatusBar.setAttribute("encrypted", "notok");
+ }
+
+ if (gEncryptedURIService)
+ {
+ gMyLastEncryptedURI = gFolderDisplay.selectedMessageUris[0];
+ gEncryptedURIService.rememberEncrypted(gMyLastEncryptedURI);
+ }
+
+ switch (aEncryptionStatus)
+ {
+ case nsICMSMessageErrors.SUCCESS:
+ case nsICMSMessageErrors.ENCRYPT_INCOMPLETE:
+ break;
+ default:
+ var brand = document.getElementById("bundle_brand")
+ .getString("brandShortName");
+ var title = gSMIMEBundle.getString("CantDecryptTitle").replace(/%brand%/g,brand);
+ var body = gSMIMEBundle.getString("CantDecryptBody").replace(/%brand%/g,brand);
+
+ // insert our message
+ msgWindow.displayHTMLInMessagePane(title,
+ "<html>\n"+
+ "<body bgcolor=\"#fafaee\">\n"+
+ "<center><br><br><br>\n"+
+ "<table>\n"+
+ "<tr><td>\n"+
+ "<center><strong><font size=\"+3\">\n"+
+ title+"</font></center><br>\n"+
+ body+"\n"+
+ "</td></tr></table></center></body></html>", false);
+ break;
+ }
+ },
+
+ // Check the SMIME receipt request and send a receipt
+ SMIMEReceiptRequestStatus: function(aSignedContentIdentifier,
+ aSignedContentIdentifierLen,
+ aReceiptsFrom,
+ aReceiptsTo,
+ aOriginatorSignatureValue,
+ aOriginatorSignatureValueLen,
+ aOriginatorContentType,
+ aOriginatorContentTypeLen,
+ aMsgSigDigest,
+ aMsgSigDigestLen)
+ {
+ var msgHdr = gMessageDisplay.displayedMessage;
+ var msgFolder = gFolderDisplay.displayedFolder;
+
+ if (!msgFolder || !(msgFolder.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Mail, true)))
+ return;
+
+ if (msgFolder.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Trash, true) ||
+ msgFolder.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Queue, true) ||
+ msgFolder.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Junk, true) ||
+ msgFolder.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Templates, true) ||
+ msgFolder.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Drafts, true))
+ return;
+
+ // Check if message has been deleted
+ if (msgHdr.flags & Components.interfaces.nsMsgMessageFlags.IMAPDeleted)
+ return;
+
+ // Check if message is marked as junk
+ var junkScore = msgHdr.getStringProperty("junkscore");
+ if (junkScore != "" && junkScore != "0")
+ return;
+
+ // Write S/MIME receipt request properties in message db
+ if (msgHdr.getStringProperty("SMIMEReceiptType") == "") {
+ msgHdr.setStringProperty("SMIMEReceiptType", "request");
+ msgHdr.setStringProperty("SMIMEReceiptSignedContentIdentifier", aSignedContentIdentifier);
+ msgHdr.setStringProperty("SMIMEReceiptOriginatorSignatureValue", aOriginatorSignatureValue);
+ msgHdr.setStringProperty("SMIMEReceiptOriginatorContentType", aOriginatorContentType);
+ msgHdr.setStringProperty("SMIMEReceiptMsgSigDigest", aMsgSigDigest);
+ }
+
+ // Check in local message database if this request has already been processed
+ if (msgHdr.getStringProperty("SMIMEReceiptRequestProcessed") != "")
+ return;
+
+ // Check in IMAP if this request has already been processed
+ var keywords = msgHdr.getStringProperty("keywords");
+ if (keywords != "" && keywords.indexOf("smimereceiptrequestprocessed") != -1)
+ {
+ // If IMAP flag is set, write it in local message db
+ msgHdr.setStringProperty("SMIMEReceiptRequestProcessed", "true");
+ return;
+ }
+
+ mimeHeaders = getMessageHeaders(msgHdr);
+ if (!mimeHeaders)
+ return;
+
+ // Create and send a receipt
+ var SMIMEReceiptGenerator = Components.classes["@mozilla.org/messenger-smime/smimereceiptgenerator;1"]
+ .createInstance(Components.interfaces.nsIMsgSMIMEReceiptGenerator);
+ var askUser = SMIMEReceiptGenerator.process(msgWindow,
+ msgFolder,
+ msgHdr.messageKey,
+ mimeHeaders,
+ aSignedContentIdentifier,
+ aSignedContentIdentifierLen,
+ aReceiptsFrom,
+ aReceiptsTo,
+ aOriginatorSignatureValue,
+ aOriginatorSignatureValueLen,
+ aOriginatorContentType,
+ aOriginatorContentTypeLen,
+ aMsgSigDigest,
+ aMsgSigDigestLen);
+
+ if (askUser)
+ gMessageNotificationBar.setSMIMEReceiptRequestMsg(SMIMEReceiptGenerator, aReceiptsTo);
+ },
+ updateSecureHeadersState: function(msgSrc) {
+ var mimeEncoder = Components.classes["@mozilla.org/messenger/mimeconverter;1"].getService(Components.interfaces.nsIMimeConverter);
+ // parse mime msg : extract headers
+ //get MIME headers only
+ var currentMimeHeaderDataArray = {};
+ var idxEnd = msgSrc.indexOf("\r\n\r\n",0); // * CRLF DOS : "\r\n"
+ if(idxEnd == -1) idxEnd = msgSrc.indexOf("\n\n",0); // * CRLF UNIX : "\n"
+ if(idxEnd == -1) idxEnd = msgSrc.indexOf("\r\r",0); //CRLF OS : "\r"
+ if(idxEnd != -1) msgSrc = msgSrc.substr(0,idxEnd); //dbg gConsole.logStringMessage("[smime - MessageAnalyser - succes getting mime headers : ] \n" + msgSrc);
+
+ // extract IMF headers - append data to array
+ var isnewLine = false;
+ var header_line = "";
+ var strTraceline="";
+ for(var i=0 ; i<msgSrc.length ; ++i){
+ header_line += msgSrc[i];
+ // is CRLF separator
+ if(msgSrc[i] === '\r' || msgSrc[i] === '\n'){
+ if(i+1 < msgSrc.length){
+ if(msgSrc[i+1] !== '\r' && msgSrc[i+1] !== '\n'){
+ isnewLine = true;
+ }
+ // is folding CRLF
+ if(msgSrc[i+1] === '\t' || msgSrc[i+1] === ' '){
+ isnewLine = false;
+ }
+ }
+ }
+
+ // last line
+ if( i === (msgSrc.length-1) ){
+ isnewLine = true;
+ }
+
+ // save new line if IMF header
+ if(isnewLine){
+ //gConsole.logStringMessage("[ximfmail - createXimfHdrArray - decode header line : ] \n" + header_line);
+ if(header_line.indexOf(":")!=-1){
+ let oEntry = new Object;
+ oEntry.headerName = header_line.substring(0,header_line.indexOf(": ",0));
+ oEntry.headerValue = header_line.substring(header_line.indexOf(": ",header_line)+2);
+ if(oEntry.headerName !== ""){
+ currentMimeHeaderDataArray[oEntry.headerName] = oEntry;
+ //gConsole.logStringMessage("[smime - MessageAnalyser - push : ] \n[" + oEntry.headerName + "]["+ oEntry.headerValue+"]");
+ strTraceline += "[" + oEntry.headerName + " : " + oEntry.headerValue + "]";
+ }
+ }
+ header_line = "";
+ isnewLine = false;
+ }
+ }
+
+ gConsole.logStringMessage("[smime - updateSecureHeadersState - MIME HEADERS : \n" + strTraceline);
+
+
+ // Compute secure headers and mime headers
+ //gConsole.logStringMessage("[smime - updatesecureheaders ] *** secureHeaders analysis begin *** " );
+ var secStatus = true; //flag for the global secure headers status, set at true as default means all secure headers were not modified
+ gSecureHeadersState=1;
+ for (headerName in gSecureHeadersArray) {
+ //Verify the value validity only in the case where header status is duplicated
+ var headerMimeExists = false;
+ var tmp_hdrName = gSecureHeadersArray[headerName].hdrName;
+ var canonalgo = gSecureHeadersArray[headerName].hdrCanonAlgo;
+ if(canonalgo){
+ // RFC 4871 - relaxed header canonicalization algorithm - convert header field names to lowercase
+ tmp_hdrName = tmp_hdrName.toLowerCase();
+ }
+ gConsole.logStringMessage("secureHeadersStatus - \n check for signed header "+tmp_hdrName);
+ for(headerMimeName in currentMimeHeaderDataArray){
+ var tmp_hdrMimeName = currentMimeHeaderDataArray[headerMimeName].headerName;
+ if(canonalgo){
+ // RFC 4871 - relaxed header canonicalization algorithm - convert header field names to lowercase
+ tmp_hdrMimeName = tmp_hdrMimeName.toLowerCase();
+ }
+
+ //gConsole.logStringMessage("secureHeadersStatus - canonalgo : "+ canonalgo +" \nsigned header : "+tmp_hdrName+"\nmime header : "+tmp_hdrMimeName);
+ if(tmp_hdrName == tmp_hdrMimeName){
+ // compare secured value ans MIME value of header
+ headerMimeExists = true; // header is in mime
+ var hdrValue = gSecureHeadersArray[headerName].hdrSecureValue;
+ var hdrMimeValue = currentMimeHeaderDataArray[headerMimeName].headerValue;
+ var charset = getMimeValueCharset(hdrMimeValue);
+
+ // body - delete SP/WPS characters before and after body
+ hdrMimeValue = deleteFirstAndLastWhiteSpace(hdrMimeValue);
+ hdrValue = deleteFirstAndLastWhiteSpace(hdrValue);
+
+ if(canonalgo){
+ // relaxed canonicalization algorithm
+ hdrMimeValue = canonilizeHeaderValue(hdrMimeValue);
+ hdrValue = canonilizeHeaderValue(hdrValue);
+ gConsole.logStringMessage("secureHeadersStatus - relaxed canonicalization \n mime value:\n>" +hdrMimeValue+ "<\nsecured value:\n>"+hdrValue+"<");
+ }else{
+ // simple canonicalization algorithm
+ //hdrMimeValue = UnfoldingMimeValue(hdrMimeValue);
+ hdrMimeValue = deleteLastCRLF(hdrMimeValue);
+ //hdrValue = UnfoldingMimeValue(hdrValue);
+ hdrValue = deleteLastCRLF(hdrValue);
+ gConsole.logStringMessage("secureHeadersStatus - simple canonicalization \n mime value:\n>" +hdrMimeValue+ "<\nsecured value:\n>"+hdrValue+"<");
+ }
+
+ if(hdrValue!==hdrMimeValue) //test if the header value in the signature and that one in the mime message is the same
+ {
+ gSecureHeadersArray[headerName].hdrSignedRes = "invalid"; //hdrValidity="invalid"; //header was modified
+ secStatus=false;
+ //dbg gConsole.logStringMessage("Warning - failed on verifing secured header "+tmp_hdrName+" :\n mime value:\n>" +hdrMimeValue+ "<\nsecured value:\n>"+hdrValue+"<");
+ gConsole.logStringMessage("[smimeHeaderSink:updateSecureHeadersState]Warning - failed on verifing secured header ");
+ }
+
+ // decode values from MIME format
+ var tmpDecdodedValue=null;
+ var mimeEncoder = Components.classes["@mozilla.org/messenger/mimeconverter;1"].getService(Components.interfaces.nsIMimeConverter);
+ tmpDecdodedValue = mimeEncoder.decodeMimeHeader(hdrMimeValue, charset, false, true);//encodeMimePartIIStr(hdrValue, false, "ISO-8859-1" , 0, 72);
+ if(tmpDecdodedValue){
+ gSecureHeadersArray[headerName].hdrMimeValue = tmpDecdodedValue;
+ }else{
+ gSecureHeadersArray[headerName].hdrMimeValue = hdrMimeValue;
+ }
+ tmpDecdodedValue = null;
+ tmpDecdodedValue = mimeEncoder.decodeMimeHeader(hdrValue,charset,false,true);
+ if(tmpDecdodedValue){
+ gSecureHeadersArray[headerName].hdrSecureValue = tmpDecdodedValue;
+ }else{
+ gSecureHeadersArray[headerName].hdrSecureValue = hdrValue;
+ }
+ gSecureHeaders = "signedData in";
+ //dbg gConsole.logStringMessage("secureHeadersStatus - header "+headerName+" \nmime value: >" +gSecureHeadersArray[headerName].hdrMimeValue+ "<\nsigned value:>"+gSecureHeadersArray[headerName].hdrSecureValue+"<");
+ break; // header is correctly checked
+ }
+ }
+
+ // mime header has been lost, deleted...
+ if(!headerMimeExists){
+ gSecureHeadersArray[headerName].hdrSignedRes = "invalid"; //header was modified
+ secStatus=false;
+ }
+
+ }
+
+ // display result to user
+ if((!secStatus) && (gSignatureStatus == nsICMSMessageErrors.SUCCESS))
+ {
+ //At least one secure header was modified, set the signed status to mismastch
+ gConsole.logStringMessage("[smimeHeaderSink:updateSecureHeadersState] At least one secure header was modified ");
+ gSignedUINode.setAttribute("signed", "mismatch");
+ gStatusBar.setAttribute("signed", "mismatch");
+ gSecureHeadersState=0;
+ gSMIMEInfoMsg.setAttribute("value", gSMIMEBundle.getString("secureinfomsg_hdrnok"));
+ gSMIMEInfoMsgMore.value=gSMIMEBundle.getString("secureinfomsgmore_default").replace(/<BR>/g,"\n");
+ setSMIMEInfoMsg("notok");
+ }
+
+ // check signed headers with local rules of secure headers
+ // Calls ReadXmlHeadersToSign (see msgCompSMIMESecureHeaders.js) to load the secureHeaders.xml configuration file
+ // For each header in the message:
+ // 1. check if the header is in the configuration file
+ // 2. In this case, check that it was secured in signature
+ // 3. If the header was not secured, raise a warning (status change ?)
+ try{
+ UpdateLocalSecureHeaderList();
+ for(localheader in gLocalSecureHeaderList){
+ try{
+ var oHeader = gSecureHeadersArray[localheader];
+ if(!oHeader){
+ // try with relaxed canon algo
+ oHeader = gSecureHeadersArray[localheader.toLowerCase()];
+ }
+ if(!oHeader){
+ // check if message contains this header
+ var oMimeHeader = currentMimeHeaderDataArray[localheader];
+ if(oMimeHeader){
+ gConsole.logStringMessage(" missing signed header compared to local rules security : " + gLocalSecureHeaderList[localheader].hdrName + " ("+localheader+")");
+
+ // decode value from MIME format
+ let tmpDecdodedValue="";
+ let tmphdrValue=currentMimeHeaderDataArray[localheader].headerValue;
+ let charset = getMimeValueCharset(tmphdrValue);
+ tmpDecdodedValue = mimeEncoder.decodeMimeHeader(tmphdrValue, charset, false, true);//encodeMimePartIIStr(hdrValue, false, "ISO-8859-1" , 0, 72);
+
+ var oEntry = new Object;
+ oEntry.hdrName = localheader.toLowerCase(); // signed header
+ oEntry.hdrSecureValue = gSMIMEBundle.getString("securevalue_warning");
+ oEntry.hdrMimeValue = tmpDecdodedValue; // value in the MIME message
+ oEntry.hdrSignedStatus = "";
+ oEntry.hdrCanonAlgo = "";
+ oEntry.hdrEncryptStatus = "";
+ oEntry.hdrSignedRes = "unsigned";
+ gSecureHeadersArray[oEntry.hdrName] = oEntry;
+
+ // set to user warning informations
+ if((secStatus) && (gSignatureStatus == nsICMSMessageErrors.SUCCESS)){
+ gSignedUINode.setAttribute("signed", "mismatch");
+ gStatusBar.setAttribute("signed", "mismatch");
+ gSMIMEInfoMsg.setAttribute("value", gSMIMEBundle.getString("secureinfomsg_hdrwarning"));
+ gSMIMEInfoMsgMore.value=gSMIMEBundle.getString("secureinfomsgmore_warning").replace(/<BR>/g,"\n");
+ setSMIMEInfoMsg("warning");
+ }
+ }
+ }
+ }catch(e){
+ gConsole.logStringMessage(" CLR_575 HEADER ERROR : " + e + "\n " + e.fileName + "\nline : " + e.lineNumber);
+ }
+ }
+ }catch(e){
+ gConsole.logStringMessage(" CLR_575 ERROR : " + e + "\n "+ e.fileName + "\nline : " + e.lineNumber);
+ }
+
+
+ },//end updateSecureHeadersState
+ secureHeadersStatus: function(aSecureHeaders, aCanonAlgo){
+ gSecureHeaders = "";
+ gSecureHeadersArray = {}; // clear array
+ if(aSecureHeaders) {
+ var secureHeadersArray = aSecureHeaders.QueryInterface(nsIArray);
+ if (secureHeadersArray.length <= 0 ) {
+ gConsole.logStringMessage("[smimeHeaderSink:secureHeadersStatus] *** no secure headers in smime signeddata ");
+ } else {
+ for(var i=0;i<secureHeadersArray.length;++i) {
+ var sHeader = secureHeadersArray.queryElementAt(i,nsIMsgSMIMESecureHeader);
+ if (sHeader) {
+ var oEntry = new Object;
+ oEntry.hdrName = sHeader.headerName; // signed header
+ oEntry.hdrSecureValue = sHeader.headerValue; // Value in the signature
+ oEntry.hdrMimeValue = ""; // value in the MIME message
+ oEntry.hdrSignedStatus = sHeader.headerStatus;
+ oEntry.hdrCanonAlgo = aCanonAlgo;
+ oEntry.hdrEncryptStatus = "";
+ oEntry.hdrSignedRes = "valid";
+ gSecureHeadersArray[oEntry.hdrName] = oEntry;
+ }
+ }
+ }
+ getMessageSource(gFolderDisplay.selectedMessageUris[0], this.updateSecureHeadersState);
+ }
+ },
+ // Check the SMIME receipt with the request
+ SMIMEReceiptStatus: function(aSignedContentIdentifier,
+ aSignedContentIdentifierLen,
+ aOriginatorSignatureValue,
+ aOriginatorSignatureValueLen,
+ aOriginatorContentType,
+ aOriginatorContentTypeLen,
+ aMsgSigDigest,
+ aMsgSigDigestLen)
+ {
+ var msgHdr = gMessageDisplay.displayedMessage;
+
+ // Write S/MIME receipt properties in message db
+ if (msgHdr.getStringProperty("SMIMEReceiptType") == "") {
+ msgHdr.setStringProperty("SMIMEReceiptType", "receipt");
+ msgHdr.setStringProperty("SMIMEReceiptSignedContentIdentifier", aSignedContentIdentifier);
+ msgHdr.setStringProperty("SMIMEReceiptOriginatorSignatureValue", aOriginatorSignatureValue);
+ msgHdr.setStringProperty("SMIMEReceiptOriginatorContentType", aOriginatorContentType);
+ msgHdr.setStringProperty("SMIMEReceiptMsgSigDigest", aMsgSigDigest);
+ }
+
+ var requestMsgHdr = null;
+
+ // Find and compare the request properties with this receipt
+ try {
+ let allFolders = Components.classes["@mozilla.org/supports-array;1"]
+ .createInstance(Components.interfaces.nsISupportsArray);
+ msgHdr.folder.rootFolder.ListDescendents(allFolders);
+
+ // Search the request in all folders
+ for each (let folder in fixIterator(allFolders, Components.interfaces.nsIMsgFolder)) {
+
+ if (folder.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Trash, true) ||
+ folder.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Queue, true) ||
+ folder.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Junk, true) ||
+ folder.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Templates, true) ||
+ folder.isSpecialFolder(Components.interfaces.nsMsgFolderFlags.Drafts, true))
+ continue;
+
+ var enumerator = folder.getDBFolderInfoAndDB({}).EnumerateMessages();
+ while (enumerator.hasMoreElements()) {
+ let itemMsgHdr = enumerator.getNext().QueryInterface(Components.interfaces.nsIMsgDBHdr);
+
+ if (itemMsgHdr.getStringProperty("SMIMEReceiptType") == "request") {
+ if (itemMsgHdr.getStringProperty("SMIMEReceiptSignedContentIdentifier") == aSignedContentIdentifier &&
+ itemMsgHdr.getStringProperty("SMIMEReceiptOriginatorSignatureValue") == aOriginatorSignatureValue &&
+ itemMsgHdr.getStringProperty("SMIMEReceiptOriginatorContentType") == aOriginatorContentType &&
+ itemMsgHdr.getStringProperty("SMIMEReceiptMsgSigDigest") == aMsgSigDigest) {
+ requestMsgHdr = itemMsgHdr;
+ break;
+ }
+ }
+ }
+
+ if (requestMsgHdr)
+ break;
+
+ }
+ } catch (e) {}
+
+ gMessageNotificationBar.setSMIMEReceiptMsg(requestMsgHdr);
+ },
+ securityLabelStatus: function(aSecurityPolicyIdentifier, aSecurityClassification, aPrivacyMark, aSecurityCategories)
+ {
+ gSecurityPolicyIdentifier = aSecurityPolicyIdentifier;
+ gSecurityClassification = aSecurityClassification;
+ gPrivacyMark = aPrivacyMark;
+ gSecurityCategories = aSecurityCategories;
+
+ /* Add Security Label info in message database so as to be displayed in a column */
+ var msgHdr = gMessageDisplay.displayedMessage;
+ if (msgHdr && gSecurityPolicyIdentifier != "") {
+ /* Write Security Label in message database */
+ msgHdr.setStringProperty("securityLabelSecurityPolicyIdentifier", gSecurityPolicyIdentifier);
+ msgHdr.setStringProperty("securityLabelSecurityClassification", gSecurityClassification);
+ msgHdr.setStringProperty("securityLabelPrivacyMark", gPrivacyMark);
+ msgHdr.setStringProperty("securityLabelSecurityCategories", gSecurityCategories);
+ }
+ },
+
+ QueryInterface : function(iid)
+ {
+ if (iid.equals(Components.interfaces.nsIMsgSMIMEHeaderSink) || iid.equals(Components.interfaces.nsISupports))
+ return this;
+ throw Components.results.NS_NOINTERFACE;
+ }
+};
+
+function getMessageHeaders(aMsgDBHdr) {
+ if (!aMsgDBHdr) return null;
+
+ try {
+
+ var streamListener = Components.classes["@mozilla.org/network/sync-stream-listener;1"].createInstance(Components.interfaces.nsISyncStreamListener);
+ var msgURI = aMsgDBHdr.folder.getUriForMsg(aMsgDBHdr);
+ var inputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance().QueryInterface(Components.interfaces.nsIScriptableInputStream);
+ inputStream.init(streamListener);
+ messenger.messageServiceFromURI(msgURI).streamMessage(msgURI, streamListener, null, null, false, null);
+
+ var content = "";
+
+ while (inputStream.available()) {
+ content += inputStream.read(512);
+ var p = content.indexOf("\r\n\r\n");
+ var p1 = content.indexOf("\r\r");
+ var p2 = content.indexOf("\n\n");
+ if (p > 0) {
+ content = content.substring(0, p);
+ break;
+ }
+ if (p1 > 0) {
+ content = content.substring(0, p1);
+ break;
+ }
+ if (p2 > 0) {
+ content = content.substring(0, p2);
+ break;
+ }
+ }
+ content += "\r\n";
+
+ var headers = content.split(/\r\n\r\n|\r\r|\n\n/, 1)[0];
+ var mimeHeaders = Components.classes["@mozilla.org/messenger/mimeheaders;1"]
+ .createInstance(Components.interfaces.nsIMimeHeaders);
+ mimeHeaders.initialize(headers, headers.length);
+
+ return mimeHeaders;
+
+ } catch (e) {
+ dump("getMessageHeaders exception: " + e + "\n");
+ }
+
+ return null;
+}
+
+function forgetEncryptedURI()
+{
+ if (gMyLastEncryptedURI && gEncryptedURIService)
+ {
+ gEncryptedURIService.forgetEncrypted(gMyLastEncryptedURI);
+ gMyLastEncryptedURI = null;
+ }
+}
+
+function onSMIMEStartHeaders()
+{
+ gEncryptionStatus = -1;
+ gSignatureStatus = -1;
+
+ gSecurityPolicyIdentifier = null;
+ gSecurityClassification = -1;
+ gPrivacyMark = null;
+ gSecurityCategories = null;
+
+ gSignerCert = null;
+ gEncryptionCert = null;
+
+ gSMIMEContainer.collapsed = true;
+
+ gSignedUINode.collapsed = true;
+ gSignedUINode.removeAttribute("signed");
+ gStatusBar.removeAttribute("signed");
+
+ gEncryptedUINode.collapsed = true;
+ gEncryptedUINode.removeAttribute("encrypted");
+ gStatusBar.removeAttribute("encrypted");
+
+ forgetEncryptedURI();
+}
+
+function onSMIMEEndHeaders()
+{
+ // display secure info message panel
+ var setSmimeInfoMsg = true;
+ var prefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch(null);
+ try{
+ if(gCurrentIdentity){
+ setSmimeInfoMsg = gCurrentIdentity.getBoolAttribute("secureheaders.smimeinfomsg");
+ //gConsole.logStringMessage("[msgHdrViewSMIMEOnLoad] secureheaders.smimeinfomsg pref = "+setSmimeInfoMsg);
+ prefBranch.setBoolPref("smimeinfomsg_on", setSmimeInfoMsg);
+ }
+ }catch(e){
+ //gConsole.logStringMessage("[msgHdrViewSMIMEOnLoad] smimeinfomsg error : " + e);
+ var prefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch(null);
+ if(prefBranch.prefHasUserValue("smimeinfomsg_on")){
+ setSmimeInfoMsg = prefBranch.getBoolPref("smimeinfomsg_on");
+ //gConsole.logStringMessage("[msgHdrViewSMIMEOnLoad] smimeinfomsg used : " + setSmimeInfoMsg);
+ }
+ }
+ if(document.getElementById("singlemessage")== undefined){
+ if(setSmimeInfoMsg){
+ document.getElementById("secureinfomsg2").setAttribute("collapsed","false");
+ }else{
+ document.getElementById("secureinfomsg2").setAttribute("collapsed","true");
+ }
+ }else{
+ if(setSmimeInfoMsg){
+ document.getElementById("secureinfomsg").setAttribute("collapsed","false");
+ }else{
+ document.getElementById("secureinfomsg").setAttribute("collapsed","true");
+ }
+ }
+
+ // check if message is signed
+ if(checkSignedDataMsg()){
+ //gSMIMEInfoMsg.setAttribute("value", gSMIMEBundle.getString(""));
+ //gSMIMEInfoMsgMore.value=gSMIMEBundle.getString("secureinfomsgmore_nok").replace(/<BR>/g,"\n");
+ gSMIMEInfoMsg.setAttribute("value", gSMIMEBundle.getString("secureinfomsg_default"));
+ gSMIMEInfoMsgMore.value=gSMIMEBundle.getString("secureinfomsgmore_default").replace(/<BR>/g,"\n");
+ setSMIMEInfoMsg("notok");
+ }else{
+ gSMIMEInfoMsg.setAttribute("value", gSMIMEBundle.getString("secureinfomsg_unsecured"));
+ gSMIMEInfoMsgMore.value=gSMIMEBundle.getString("secureinfomsgmore_default").replace(/<BR>/g,"\n");
+ setSMIMEInfoMsg("");
+ }
+}
+
+//
+function onSmartCardChange()
+{
+ // only reload encrypted windows
+ if (gMyLastEncryptedURI && gEncryptionStatus != -1) {
+ ReloadMessage();
+ }
+}
+
+//
+function msgHdrViewSMIMEOnLoad(event)
+{
+ window.crypto.enableSmartCardEvents = true;
+ document.addEventListener("smartcard-insert", onSmartCardChange, false);
+ document.addEventListener("smartcard-remove", onSmartCardChange, false);
+ if (!gSMIMEBundle)
+ gSMIMEBundle = document.getElementById("bundle_read_smime");
+
+ // we want to register our security header sink as an opaque nsISupports
+ // on the msgHdrSink used by mail.....
+ msgWindow.msgHeaderSink.securityInfo = smimeHeaderSink;
+
+ gSignedUINode = document.getElementById('signedHdrIcon');
+ gEncryptedUINode = document.getElementById('encryptedHdrIcon');
+ gSMIMEContainer = document.getElementById('smimeBox');
+ gStatusBar = document.getElementById('status-bar');
+
+ // add ourself to the list of message display listeners so we get notified when we are about to display a
+ // message.
+ var listener = {};
+ listener.onStartHeaders = onSMIMEStartHeaders;
+ listener.onEndHeaders = onSMIMEEndHeaders;
+ gMessageListeners.push(listener);
+
+ gEncryptedURIService =
+ Components.classes["@mozilla.org/messenger-smime/smime-encrypted-uris-service;1"]
+ .getService(Components.interfaces.nsIEncryptedSMIMEURIsService);
+
+ // display security information message
+ gSMIMEInfoMsg = document.getElementById("secureinfomsgl");
+ gSMIMEInfoMsgMore = document.getElementById("secureinfomsgd");
+ if(gSMIMEInfoMsg == undefined){
+ gSMIMEInfoMsg = document.getElementById("secureinfomsgl2");
+ gSMIMEInfoMsgMore = document.getElementById("secureinfomsgd2");
+ }
+
+ try{
+ if(gCurrentIdentity){
+ //gConsole.logStringMessage("[msgHdrViewSMIMEOnLoad] secureheaders.smimeinfomsg pref = "+setSmimeInfoMsg);
+ // save datas of current account for extern windows
+ var prefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch(null);
+ prefBranch.setBoolPref("smimeinfomsg_on", gCurrentIdentity.getBoolAttribute("secureheaders.smimeinfomsg"));
+ prefBranch.setCharPref("smimeinfomsg_localsecurehdrpath", gCurrentIdentity.getCharAttribute(PREF_SECURE_HEADERS_FOLDER_DATAS));
+ }
+ }catch(e){gConsole.logStringMessage("[msgHdrViewSMIMEOnLoad] smimeinfomsg error : " + e);}
+
+ // new folder selected : collapse gSMIMEInfoMsg container
+ try{
+ var el = document.getElementById("folderTree");
+ el.addEventListener("select", function(){
+ if(document.getElementById("singlemessage") != undefined)
+ document.getElementById("secureinfomsg").setAttribute("collapsed","true");},
+ false);
+ }catch(e){}
+
+}
+
+function msgHdrViewSMIMEOnUnload(event)
+{
+ window.crypto.enableSmartCardEvents = false;
+ document.removeEventListener("smartcard-insert", onSmartCardChange, false);
+ document.removeEventListener("smartcard-remove", onSmartCardChange, false);
+ forgetEncryptedURI();
+ removeEventListener('messagepane-loaded', msgHdrViewSMIMEOnLoad, true);
+ removeEventListener('messagepane-unloaded', msgHdrViewSMIMEOnUnload, true);
+ removeEventListener('messagepane-hide', msgHdrViewSMIMEOnMessagePaneHide, true);
+ removeEventListener('messagepane-unhide', msgHdrViewSMIMEOnMessagePaneUnhide, true);
+}
+
+function msgHdrViewSMIMEOnMessagePaneHide()
+{
+ gSMIMEContainer.collapsed = true;
+ gSignedUINode.collapsed = true;
+ gEncryptedUINode.collapsed = true;
+}
+
+function msgHdrViewSMIMEOnMessagePaneUnhide()
+{
+ if (gEncryptionStatus != -1 || gSignatureStatus != -1)
+ {
+ gSMIMEContainer.collapsed = false;
+
+ if (gSignatureStatus != -1)
+ {
+ gSignedUINode.collapsed = false;
+ }
+
+ if (gEncryptionStatus != -1)
+ {
+ gEncryptedUINode.collapsed = false;
+ }
+ }
+}
+
+function getMimeValueCharset(val)
+{
+ var res="";
+ if(val.indexOf("=?")!=-1)
+ {
+ val=val.substring(val.indexOf("=?")+2);
+ if(val.indexOf("?")!=-1)
+ {
+ res=val.substring(0,val.indexOf("?"));
+ }
+ }
+ return res;
+}
+
+
+/*
+ *
+ */
+function ReplaceStr(expr,a,b){
+ var i=0
+ while (i!=-1) {
+ i=expr.indexOf(a,0);
+ if (i>=0) {
+ expr=expr.substring(0,i)+b+expr.substring(i+a.length);
+ i+=b.length;
+ }
+ }
+ return expr;
+}
+
+/*
+ * Unfolding string from mime value
+ * RFC 822 : unfolding is accomplished by removing any CRLF that is immediately followed by WSP
+ */
+function UnfoldingMimeValue(str){
+ // CRLF DOS : "\r\n"
+ // CRLF UNIX : "\n"
+ var rv = ReplaceStr(str,"\r\n\t","\t");
+ rv = ReplaceStr(rv,"\n\t","\t");
+ rv = ReplaceStr(rv,"\r\n "," ");
+ return ReplaceStr(rv,"\n "," ");
+}
+
+
+/*
+ * RFC 4871 - relaxed header canonicalization algorithm
+ * Delete WSP at the begining and and of field
+ */
+function deleteFirstAndLastWhiteSpace(str){
+ var rv=str;
+ var imax=rv.length;
+ for(var i=0; i<imax; ++i){
+ var nochange1=true;
+ var nochange2=true;
+
+ //delete all WSP at the end of each unfolded header field value
+ if(rv[rv.length-1]==' ' || rv[rv.length-1]=='\t'){
+ rv = rv.slice(0,rv.length-1);
+ nochange1=false;
+ }
+
+ //delete any WSP remaining before and after the colon separating field name form value
+ if(rv[0]==' ' || rv[0]=='\t'){
+ rv = rv.slice(1,rv.length);
+ nochange2=false;
+ }
+
+ if(nochange1==true && nochange2==true) break;
+ }
+ return rv;
+}
+
+/*
+ * Delete CRLF at end of sequence str
+ * CRLF DOS : "\r\n"
+ * CRLF UNIX : "\n"
+ * CRLF OS : "\r"
+ */
+function deleteLastCRLF(str){
+ var rv=str;
+ var imax=rv.length;
+ if(rv[imax-1] == "\n")
+ rv = rv.slice(0,imax-1);
+ imax=rv.length;
+ if(rv[imax-1] == "\r")
+ rv = rv.slice(0,imax-1);
+ return rv;
+}
+
+/*
+ * RFC 4871 - relaxed header canonicalization algorithm
+ */
+function canonilizeHeaderValue(hdrval){
+ // Unfold all header field continuation lines as described in [RFC2822]
+ var val = UnfoldingMimeValue(hdrval);
+
+ // Convert all sequences of one or more WSP characters to a single SP character
+ val = ReplaceStr(val,"\t"," ");
+ val = ReplaceStr(val," "," ");
+
+ // Delete all WSP characters at the end of each unfolded value
+ // Delete any WSP characters remaining before and after the colon separating header field
+ val=deleteFirstAndLastWhiteSpace(val);
+ val = deleteLastCRLF(val);
+ return val;
+}
+
+/*
+ *
+ */
+function checkSignedDataMsg(){
+ //
+ var list="";
+ var headerName;
+ var regHdrName_contentype = new RegExp("content-type", "ig");
+ var regHdrValue_signed = new RegExp("multipart/signed", "ig");
+ for (headerName in currentHeaderData) {
+ //list += currentHeaderData[headerName].headerName +":"+currentHeaderData[headerName].headerValue + " $$ ";
+ if(regHdrName_contentype.test(currentHeaderData[headerName].headerName)){
+ if(regHdrValue_signed.test(currentHeaderData[headerName].headerValue)){
+ gConsole.logStringMessage("[checkSignedDataSmimeSelectedMsg] Msg Is Signed");
+ return true;
+ }
+ }
+ }
+ gConsole.logStringMessage("[checkSignedDataSmimeSelectedMsg] Msg Is Unsigned");
+ //dbg gConsole.logStringMessage("[checkSignedDataSmimeSelectedMsg] list : " + list);
+ return false;
+}
+
+ /**
+Get message source
+@param {nsIMsgDBHdr} header
+@param {function} callbackFunction Function to call when data are received: callbackFunction(header, receivedData, callbackParam)
+@param callbackParam Parameter of callbackFunction
+@return {string} Message source or <b>false</b> if an error occurs
+*/
+function getMessageSource(mailUri, callbackFunction, callbackParam){
+ if (!mailUri) return;
+ var streamListener = {
+ QueryInterface: function(aIID) {
+ if (aIID.equals(Components.interfaces.nsISupports)
+ || aIID.equals(Components.interfaces.nsIStreamListener))
+ return this;
+ throw Components.results.NS_NOINTERFACE;
+ },
+ data: "",
+ isDataComplete: false,
+ onStartRequest: function(request, context) {},
+ onDataAvailable: function(request, context, inputStream, offset, available) {
+ if(!this.isDataComplete ){
+ var stream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
+ stream.init(inputStream);
+ this.data += stream.read(available);
+ stream.close();
+ stream = null;
+
+ // parse headers only
+ var idxEnd = this.data.indexOf("\r\n\r\n",0); // * CRLF DOS : "\r\n"
+ if(idxEnd == -1) idxEnd = this.data.indexOf("\n\n",0); // * CRLF UNIX : "\n"
+ if(idxEnd == -1) idxEnd = this.data.indexOf("\r\r",0); //CRLF OS : "\r"
+ if(idxEnd != -1) this.isDataComplete = true; // msgSrc = msgSrc.substr(0,idxEnd); //dbg gConsole.logStringMessage("[smime - MessageAnalyser - succes getting mime headers : ] \n" + msgSrc);
+ }
+ },
+ onStopRequest: function(request, context, status) {
+ if (Components.isSuccessCode(status)) {
+ callbackFunction(this.data, callbackParam);
+ } else {
+ gConsole.logStringMessage("[getMessageSource - streamListener.onStopRequest ] - Error: "+ status);
+ if(this.isDataComplete == true){
+ // all mime headers have been parsed
+ gConsole.logStringMessage("[getMessageSource - streamListener.isDataComplete ] all mime headers have been parsed !");
+ callbackFunction( this.data, callbackParam);
+ }
+ }
+ }
+ }
+
+ var cmessenger = Components.classes["@mozilla.org/messenger;1"].createInstance(Components.interfaces.nsIMessenger);
+ var msgSvc = cmessenger.messageServiceFromURI(mailUri);
+ try { msgSvc.streamMessage(mailUri, streamListener, null, null, false, null); } catch (ex) { return false; }
+}
+
+/*
+ * set status signature for displaying panel
+ */
+function setSMIMEInfoMsg(status){
+ //#secureinfomsgh[signed="ok"],
+ //#secureinfomsgh2[signed="ok"]
+ try{document.getElementById("secureinfomsgh").setAttribute("signed",status)}catch(e){}
+ try{document.getElementById("secureinfomsgh2").setAttribute("signed",status)}catch(e){}
+}
+
+/*
+ * UpdateLocalSecureHeaderList
+ * Read the XML secure headers configuration file
+ * Add headers to sign with local rules in gLocalSecureHeaderList array {[headername][objectEntry],[headername][objectEntry],...}
+*/
+var PREF_SECURE_HEADERS_FOLDER_DATAS="secureheaders.folderdata";
+var DEFAULT_SECUREHEADERS_XML_DIR = "secureHeaders"
+var DEFAULT_SECUREHEADERS_XML_FILE = "secureHeadersDefault.xml"
+var gLocalSecureHeaderList = []; // {headerName,headerName,...}
+var gPrefLocalSecureheaderXmlPath = "";
+var gPrefLocalSecureheaderXmlDate = ""
+function UpdateLocalSecureHeaderList(){
+ try{
+ var strLocalList = ""; // trace list
+
+ // get xml file path
+ var file = null;
+ //var pref_data = gCurrentIdentity.getCharAttribute(PREF_SECURE_HEADERS_FOLDER_DATAS);
+ var pref_data = "";
+ try{
+ if(gCurrentIdentity){
+ //gConsole.logStringMessage("[msgHdrViewSMIMEOnLoad] secureheaders.smimeinfomsg pref = "+setSmimeInfoMsg);
+ // save datas of current account for extern windows
+ var prefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch(null);
+ pref_data = gCurrentIdentity.getCharAttribute(PREF_SECURE_HEADERS_FOLDER_DATAS);
+ prefBranch.setCharPref("smimeinfomsg_localsecurehdrpath", pref_data);
+ gConsole.logStringMessage("[_secure_headers - UpdateLocalSecureHeaderList] smimeinfomsg_localsecurehdrpath pref = " + pref_data);
+ }
+ }catch(e){
+ // try to get path from current prefs
+ var prefBranch = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefService).getBranch(null);
+ pref_data = prefBranch.getCharPref("smimeinfomsg_localsecurehdrpath");
+ gConsole.logStringMessage("[_secure_headers - UpdateLocalSecureHeaderList] e : "+ e + " line " + e.lineNumber + " \n smimeinfomsg_localsecurehdrpath pref = " + pref_data);
+ }
+
+ if(!pref_data){
+ file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile); // get profile folder
+ file.append(DEFAULT_SECUREHEADERS_XML_DIR);
+ file.append(DEFAULT_SECUREHEADERS_XML_FILE);
+ pref_data = file.path;
+ }else{
+ file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ file.initWithPath( pref_data );
+ }
+ if(!file.exists()){
+ gConsole.logStringMessage("[_secure_headers - UpdateLocalSecureHeaderList] Error loading schema file : " + completePath);
+ return;
+ }
+
+ // is list modified
+ if(gPrefLocalSecureheaderXmlPath === pref_data)
+ if(file.lastModifiedTime === gPrefLocalSecureheaderXmlDate)
+ return;
+ gPrefLocalSecureheaderXmlPath = pref_data;
+ gPrefLocalSecureheaderXmlDate = file.lastModifiedTime;
+ gLocalSecureHeaderList = [];
+ gConsole.logStringMessage("[_secure_headers - UpdateLocalSecureHeaderList] last modified time file : " + gPrefLocalSecureheaderXmlDate + "\npath :" + gPrefLocalSecureheaderXmlPath);
+
+ // Get Xml Document parser
+ var stream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
+ stream.init(file, -1, -1, Components.interfaces.nsIFileInputStream.CLOSE_ON_EOF);
+ var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser);
+ var xmlDoc = parser.parseFromStream(stream, null, file.fileSize, "text/xml");
+
+ // get datas from file
+ var compatibleTag = xmlDoc.getElementsByTagName("ximf:headers");
+ var sValue="";
+ if(compatibleTag.length>0){
+ // get headers to sign
+ var childNodes = compatibleTag[0].childNodes;
+ for(var j=0; j <childNodes.length; ++j ){
+ var header_name = "";
+ var header_status = 0;
+ //var header_encrypted = -1;
+ if(childNodes[j].localName == "header"){
+ header_name = childNodes[j].getAttribute("name");
+ if(childNodes[j].hasAttribute("status")) header_status = parseInt(childNodes[j].getAttribute("status"));
+ /*if(childNodes[j].hasAttribute("encrypted")) header_encrypted = parseInt(childNodes[j].getAttribute("encrypted"));*/
+
+ var oEntry = new Object;
+ oEntry.hdrName = header_name;
+ oEntry.hdrSecureValue = "";
+ oEntry.hdrMimeValue = "";
+ oEntry.hdrSignedStatus = header_status;
+ oEntry.hdrCanonAlgo = ""; //TODO
+ oEntry.hdrEncryptStatus = "";
+ oEntry.hdrSignedRes = "";
+ gLocalSecureHeaderList[oEntry.hdrName] = oEntry;
+ //gConsole.logStringMessage("[CLR_575] local rule header " + header_name);
+ strLocalList += header_name + "\n";
+ }
+ }
+ }else{
+ gConsole.logStringMessage("[_secure_headers - UpdateLocalSecureHeaderList] no headers tag in file " + completePath);
+ }
+ } catch (e) {
+ gConsole.logStringMessage("[_secure_headers - UpdateLocalSecureHeaderList ] \n " + e + "\nfile : " + e.fileName+"\nline : "+ e.lineNumber);
+ }
+ gConsole.logStringMessage("[_secure_headers - UpdateLocalSecureHeaderList ] new local list of secure headers : \n " + strLocalList);
+ return gLocalSecureHeaderList;
+}
+
+addEventListener('messagepane-loaded', msgHdrViewSMIMEOnLoad, true);
+addEventListener('messagepane-unloaded', msgHdrViewSMIMEOnUnload, true);
+addEventListener('messagepane-hide', msgHdrViewSMIMEOnMessagePaneHide, true);
+addEventListener('messagepane-unhide', msgHdrViewSMIMEOnMessagePaneUnhide, true);
--- /dev/null
+<?xml version="1.0"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ - Contributor(s):
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved -->
+
+<?xml-stylesheet href="chrome://messenger/skin/smime/msgHdrViewSMIMEOverlay.css" type="text/css"?>
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgHdrViewSMIMEOverlay.js"/>
+<!-- These stringbundles are already defined in msgReadSMIMEOverlay.xul!
+ <stringbundleset id="stringbundleset">
+ <stringbundle id="bundle_read_smime" src="chrome://messenger-smime/locale/msgReadSMIMEOverlay.properties"/>
+ <stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
+ </stringbundleset>
+-->
+
+ <hbox id="dateValueBox">
+ <hbox id="smimeBox" insertbefore="dateLabel" collapsed="true">
+ <image id="signedHdrIcon"
+ onclick="showMessageReadSecurityInfo();" collapsed="true"/>
+ <image id="encryptedHdrIcon"
+ onclick="showMessageReadSecurityInfo();" collapsed="true"/>
+ </hbox>
+ </hbox>
+
+ <vbox id="singlemessage">
+ <vbox id="secureinfomsg" insertafter="msgNotificationBar" collapsed="true">
+ <hbox id="secureinfomsgh">
+ <vbox>
+ <label id="secureinfomsgl" onclick="showMessageReadSecurityInfo();"/>
+ <description id="secureinfomsgd" />
+ </vbox>
+ </hbox>
+ </vbox>
+ </vbox>
+ <vbox id="messagepanebox">
+ <vbox id="secureinfomsg2" insertafter="msgNotificationBar" collapsed="true">
+ <hbox id="secureinfomsgh2">
+ <vbox>
+ <label id="secureinfomsgl2" onclick="showMessageReadSecurityInfo();"/>
+ <!-- <html:div id="secureinfomsgd2" /> -->
+ <description id="secureinfomsgd2" />
+ </vbox>
+ </hbox>
+ </vbox>
+ </vbox>
+</overlay>
+
--- /dev/null
+<?xml version="1.0"?>
+
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<?xml-stylesheet href="chrome://messenger/skin/smime/msgReadSMIMEOverlay.css" type="text/css"?>
+
+<!DOCTYPE overlay SYSTEM "chrome://messenger-smime/locale/msgReadSMIMEOverlay.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgReadSMIMEOverlay.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgSecurityLabel.js"/>
+
+ <stringbundleset id="stringbundleset">
+ <stringbundle id="bundle_read_smime" src="chrome://messenger-smime/locale/msgReadSMIMEOverlay.properties"/>
+ <stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
+ </stringbundleset>
+
+ <commandset id="mailViewMenuItems">
+ <command id="cmd_viewSecurityStatus" oncommand="showMessageReadSecurityInfo();" disabled="true"/>
+ </commandset>
+
+ <menupopup id="menu_View_Popup">
+ <menuitem id="menu_securityStatus" insertafter="pageSourceMenuItem"
+ label="&menu_securityStatus.label;" accesskey="&menu_securityStatus.accesskey;"
+ command="cmd_viewSecurityStatus"/>
+ </menupopup>
+
+ <tree id="threadTree">
+ <treecols id="threadCols">
+ <splitter class="tree-splitter"/>
+ <treecol id="securityLabelSecurityClassificationColumn" persist="hidden ordinal width" hidden="true"
+ currentView="unthreaded" label="&securityLabelSecurityClassificationColumn.label;"
+ tooltiptext="&securityLabelSecurityClassificationColumn.tooltip;"/>
+ </treecols>
+ </tree>
+
+</overlay>
--- /dev/null
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+messenger.jar:
+% content messenger-smime %content/messenger-smime/
+% overlay chrome://messenger/content/messengercompose/messengercompose.xul chrome://messenger-smime/content/msgCompSMIMEOverlay.xul
+% overlay chrome://messenger/content/msgHdrViewOverlay.xul chrome://messenger-smime/content/msgHdrViewSMIMEOverlay.xul
+% overlay chrome://messenger/content/messenger.xul chrome://messenger-smime/content/msgReadSMIMEOverlay.xul
+% overlay chrome://messenger/content/messageWindow.xul chrome://messenger-smime/content/msgReadSMIMEOverlay.xul
+% overlay chrome://messenger/content/am-identity-edit.xul chrome://messenger/content/am-smimeIdentityEditOverlay.xul
+ content/messenger-smime/msgReadSMIMEOverlay.xul (content/msgReadSMIMEOverlay.xul)
+ content/messenger-smime/msgCompSMIMEOverlay.xul (content/msgCompSMIMEOverlay.xul)
+ content/messenger-smime/msgCompSMIMEOverlay.js (content/msgCompSMIMEOverlay.js)
+ content/messenger-smime/msgHdrViewSMIMEOverlay.js (content/msgHdrViewSMIMEOverlay.js)
+ content/messenger-smime/msgHdrViewSMIMEOverlay.xul (content/msgHdrViewSMIMEOverlay.xul)
+ content/messenger/am-smime.xul (/mailnews/extensions/smime/content/am-smime.xul)
+ content/messenger/am-smime.js (/mailnews/extensions/smime/content/am-smime.js)
+ content/messenger/am-smimeIdentityEditOverlay.xul (/mailnews/extensions/smime/content/am-smimeIdentityEditOverlay.xul)
+ content/messenger/am-smimeOverlay.xul (/mailnews/extensions/smime/content/am-smimeOverlay.xul)
+ content/messenger-smime/msgReadSMIMEOverlay.js (/mailnews/extensions/smime/content/msgReadSMIMEOverlay.js)
+ content/messenger-smime/msgCompSecurityInfo.js (/mailnews/extensions/smime/content/msgCompSecurityInfo.js)
+ content/messenger-smime/msgCompSecurityInfo.xul (/mailnews/extensions/smime/content/msgCompSecurityInfo.xul)
+ content/messenger-smime/msgReadSecurityInfo.xul (/mailnews/extensions/smime/content/msgReadSecurityInfo.xul)
+ content/messenger-smime/msgReadSecurityInfo.js (/mailnews/extensions/smime/content/msgReadSecurityInfo.js)
+ content/messenger-smime/certFetchingStatus.xul (/mailnews/extensions/smime/content/certFetchingStatus.xul)
+ content/messenger-smime/certFetchingStatus.js (/mailnews/extensions/smime/content/certFetchingStatus.js)
+ content/messenger-smime/msgSecurityLabel.js (/mailnews/extensions/smime/content/msgSecurityLabel.js)
+ content/messenger-smime/msgCompSecurityLabelDialog.xul (/mailnews/extensions/smime/content/msgCompSecurityLabelDialog.xul)
+ content/messenger-smime/msgCompSecurityLabelDialog.js (/mailnews/extensions/smime/content/msgCompSecurityLabelDialog.js)
+ content/messenger-smime/msgCompSMIMESecureHeaders.js (/mailnews/extensions/smime/content/msgCompSMIMESecureHeaders.js)
+ content/messenger-smime/msgReadSecureHeadersView.xul (/mailnews/extensions/smime/content/msgReadSecureHeadersView.xul)
+ content/messenger-smime/msgReadSecureHeadersView.js (/mailnews/extensions/smime/content/msgReadSecureHeadersView.js)
--- /dev/null
+; This Source Code Form is subject to the terms of the Mozilla Public
+; License, v. 2.0. If a copy of the MPL was not distributed with this
+; file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+; Package file for the Thunderbird build.
+;
+; Packaging manifest is used to copy files from dist/bin
+; to the staging directory.
+; Some other files are built in the staging directory directly,
+; so they will be implicitly packaged too.
+;
+; File format:
+;
+; [] designates a toplevel component. Example: [xpcom]
+; * wildcard
+; ; file comment
+;
+
+#filter substitution
+
+#ifdef XP_UNIX
+#ifndef XP_MACOSX
+#define UNIX_BUT_NOT_MAC
+#endif
+#endif
+
+#ifdef XP_MACOSX
+; Mac bundle stuff
+@APPNAME@/Contents/Info.plist
+@APPNAME@/Contents/PkgInfo
+@APPNAME@/Contents/Resources/
+@APPNAME@/Contents/_CodeSignature/CodeResources
+@APPNAME@/Contents/Library/
+#endif
+
+[@AB_CD@]
+@BINPATH@/chrome/@AB_CD@@JAREXT@
+@BINPATH@/chrome/@AB_CD@.manifest
+@BINPATH@/@PREF_DIR@/all-l10n.js
+@BINPATH@/searchplugins/*
+@BINPATH@/dictionaries/*
+@BINPATH@/hyphenation/*
+#ifdef XP_WIN32
+@BINPATH@/uninstall/helper.exe
+#endif
+#ifdef MOZ_UPDATER
+@BINPATH@/update.locale
+@BINPATH@/updater.ini
+#endif
+
+[xpcom]
+@BINPATH@/dependentlibs.list
+#ifndef MOZ_NATIVE_NSPR
+@BINPATH@/@DLL_PREFIX@nspr4@DLL_SUFFIX@
+@BINPATH@/@DLL_PREFIX@plc4@DLL_SUFFIX@
+@BINPATH@/@DLL_PREFIX@plds4@DLL_SUFFIX@
+#endif
+#ifndef MOZ_STATIC_JS
+@BINPATH@/@DLL_PREFIX@mozjs@DLL_SUFFIX@
+#endif
+#ifdef XP_WIN32
+@BINPATH@/@DLL_PREFIX@gkmedias@DLL_SUFFIX@
+#ifndef MOZ_DEBUG
+#if MOZ_MSVC_REDIST == 1400
+@BINPATH@/Microsoft.VC80.CRT.manifest
+@BINPATH@/msvcm80.dll
+@BINPATH@/msvcp80.dll
+@BINPATH@/msvcr80.dll
+#elif MOZ_MSVC_REDIST == 1500
+@BINPATH@/Microsoft.VC90.CRT.manifest
+@BINPATH@/msvcm90.dll
+@BINPATH@/msvcp90.dll
+@BINPATH@/msvcr90.dll
+#elif MOZ_MSVC_REDIST == 1600
+@BINPATH@/msvcp100.dll
+@BINPATH@/msvcr100.dll
+#elif MOZ_MSVC_REDIST == 1700
+@BINPATH@/msvcp110.dll
+@BINPATH@/msvcr110.dll
+#endif
+#endif
+#endif
+@BINPATH@/@DLL_PREFIX@mozalloc@DLL_SUFFIX@
+#ifdef MOZ_SHARED_MOZGLUE
+@BINPATH@/@DLL_PREFIX@mozglue@DLL_SUFFIX@
+#endif
+#ifdef XP_MACOSX
+@BINPATH@/XUL
+#else
+@BINPATH@/@DLL_PREFIX@xul@DLL_SUFFIX@
+#endif
+#ifdef XP_MACOSX
+@BINPATH@/@MOZ_CHILD_PROCESS_NAME@.app/
+@BINPATH@/@DLL_PREFIX@plugin_child_interpose@DLL_SUFFIX@
+#else
+@BINPATH@/@MOZ_CHILD_PROCESS_NAME@
+#endif
+; ANGLE GLES-on-D3D rendering library
+#ifdef MOZ_ANGLE_RENDERER
+@BINPATH@/libEGL.dll
+@BINPATH@/libGLESv2.dll
+@BINPATH@/@MOZ_D3DCOMPILER_DLL@
+#endif
+
+; Modules
+@BINPATH@/modules/*
+
+; Optional RSS extension
+[newsblog]
+@BINPATH@/chrome/newsblog@JAREXT@
+@BINPATH@/chrome/newsblog.manifest
+@BINPATH@/components/newsblog.js
+@BINPATH@/components/newsblog.manifest
+
+[mail]
+#ifndef XP_UNIX
+@BINPATH@/@MOZ_APP_NAME@.exe
+#else
+@BINPATH@/@MOZ_APP_NAME@-bin
+@BINPATH@/@MOZ_APP_NAME@
+#endif
+@BINPATH@/application.ini
+#ifdef MOZ_UPDATER
+@BINPATH@/update-settings.ini
+#endif
+@BINPATH@/blocklist.xml
+@BINPATH@/platform.ini
+#ifdef XP_OS2
+@BINPATH@/@DLL_PREFIX@mozsqlt3@DLL_SUFFIX@
+#else
+#ifndef MOZ_NATIVE_SQLITE
+@BINPATH@/@DLL_PREFIX@mozsqlite3@DLL_SUFFIX@
+#endif
+#endif
+#ifdef UNIX_BUT_NOT_MAC
+@BINPATH@/run-mozilla.sh
+#ifdef MOZ_UPDATER
+@BINPATH@/icons/*.png
+#endif
+#endif
+
+; [OS/2]
+#ifdef XP_OS2
+@BINPATH@/MozSounds.cmd
+@BINPATH@/*.xqs
+@BINPATH@/components/*.xqs
+#endif
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Mail Specific Files
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+@BINPATH@/defaults/messenger/mailViews.dat
+@BINPATH@/defaults/profile/localstore.rdf
+@BINPATH@/defaults/profile/prefs.js
+@BINPATH@/defaults/profile/mimeTypes.rdf
+@BINPATH@/defaults/profile/securityLabelPolicy-sample.xml
+@BINPATH@/defaults/profile/secureHeadersDefault.xml
+
+@BINPATH@/isp/*
+
+#if defined(MOZ_ENABLE_DBUS) || defined(MOZ_ENABLE_GNOME_COMPONENT) || defined(MOZ_ENABLE_GNOMEVFS)
+@BINPATH@/components/components.manifest
+#endif
+@BINPATH@/components/aboutRedirector.js
+@BINPATH@/components/activity.xpt
+@BINPATH@/components/activityComponents.manifest
+@BINPATH@/components/cloudFileComponents.manifest
+@BINPATH@/components/cloudfile.xpt
+@BINPATH@/components/addrbook.xpt
+@BINPATH@/components/fts3tok.xpt
+; interfaces.manifest doesn't get packaged because it is dynamically
+; re-created at packaging time when linking the xpts that will actually
+; go into the package, so the test related interfaces aren't included.
+@BINPATH@/components/mime.xpt
+@BINPATH@/components/mimeJSComponents.js
+@BINPATH@/components/msgMime.manifest
+@BINPATH@/components/steel.xpt
+@BINPATH@/components/msgAsyncPrompter.js
+@BINPATH@/components/msgbase.xpt
+@BINPATH@/components/msgBase.manifest
+@BINPATH@/components/msgcompose.xpt
+@BINPATH@/components/msgdb.xpt
+@BINPATH@/components/msgimap.xpt
+@BINPATH@/components/msglocal.xpt
+@BINPATH@/components/msgnews.xpt
+@BINPATH@/components/msgsearch.xpt
+@BINPATH@/components/import.xpt
+@BINPATH@/components/mailcompsbase.xpt
+@BINPATH@/components/mailview.xpt
+@BINPATH@/components/mailprofilemigration.xpt
+@BINPATH@/components/messageWakeupService.js
+@BINPATH@/components/messageWakeupService.manifest
+@BINPATH@/components/nsActivity.js
+@BINPATH@/components/nsActivityManager.js
+@BINPATH@/components/nsActivityManagerUI.js
+@BINPATH@/components/nsYouSendIt.js
+@BINPATH@/components/nsUbuntuOne.js
+@BINPATH@/components/nsBox.js
+@BINPATH@/components/nsAddrbook.manifest
+@BINPATH@/components/nsMailNewsCommandLineHandler.js
+@BINPATH@/components/services-crypto-component.xpt
+#ifndef XP_OS2
+@BINPATH@/components/shellservice.xpt
+#endif
+@BINPATH@/components/xpcom_base.xpt
+@BINPATH@/components/xpcom_system.xpt
+@BINPATH@/components/xpcom_components.xpt
+@BINPATH@/components/xpcom_ds.xpt
+@BINPATH@/components/xpcom_io.xpt
+@BINPATH@/components/xpcom_threads.xpt
+@BINPATH@/components/xpcom_xpti.xpt
+@BINPATH@/chrome/toolkit@JAREXT@
+@BINPATH@/chrome/toolkit.manifest
+@BINPATH@/chrome/comm@JAREXT@
+@BINPATH@/chrome/comm.manifest
+@BINPATH@/chrome/messenger@JAREXT@
+@BINPATH@/chrome/messenger.manifest
+#ifndef XP_UNIX
+@BINPATH@/chrome/icons/default/abcardWindow.ico
+@BINPATH@/chrome/icons/default/addressbookWindow.ico
+@BINPATH@/chrome/icons/default/messengerWindow.ico
+@BINPATH@/chrome/icons/default/msgcomposeWindow.ico
+#elifdef UNIX_BUT_NOT_MAC
+@BINPATH@/chrome/icons/default/*.png
+#endif
+@BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/install.rdf
+@BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/icon.png
+@BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/preview.png
+@BINPATH@/extensions/{972ce4c6-7e08-4474-a285-3208198ce6fd}/chrome.manifest
+
+; Gloda
+@BINPATH@/chrome/gloda@JAREXT@
+@BINPATH@/chrome/gloda.manifest
+@BINPATH@/components/glautocomp.js
+@BINPATH@/components/gloda.manifest
+@BINPATH@/components/jsmimeemitter.js
+
+; New message notification
+@BINPATH@/components/newMailNotificationService.js
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Mail Extensions (smime, etc.)
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+#ifdef XP_WIN32
+@BINPATH@/MapiProxy.dll
+@BINPATH@/mozMapi32.dll
+@BINPATH@/components/mapihook.xpt
+#endif
+@BINPATH@/components/mailComponents.manifest
+@BINPATH@/components/mailContentHandler.js
+@BINPATH@/components/mailGlue.js
+@BINPATH@/components/nsMailDefaultHandler.js
+#ifndef XP_OS2
+@BINPATH@/components/nsSetDefaultMail.js
+@BINPATH@/components/shell.manifest
+#endif
+@BINPATH@/components/offlineStartup.js
+@BINPATH@/components/offlineStartup.manifest
+@BINPATH@/components/steelApplication.js
+@BINPATH@/components/steelApplication.manifest
+
+
+@BINPATH@/components/mdn-service.js
+@BINPATH@/components/mdn-service.manifest
+@BINPATH@/components/smime-service.js
+@BINPATH@/components/smime-service.manifest
+@BINPATH@/components/msgsmime.xpt
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; instant messaging
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; shared with Instantbird
+@BINPATH@/@PREF_DIR@/chat-prefs.js
+@BINPATH@/chrome/chat@JAREXT@
+@BINPATH@/chrome/chat.manifest
+@BINPATH@/components/chat.xpt
+@BINPATH@/components/imAccounts.js
+@BINPATH@/components/imAccounts.manifest
+@BINPATH@/components/imCommands.js
+@BINPATH@/components/imCommands.manifest
+@BINPATH@/components/imContacts.js
+@BINPATH@/components/imContacts.manifest
+@BINPATH@/components/imConversations.js
+@BINPATH@/components/imConversations.manifest
+@BINPATH@/components/imCore.js
+@BINPATH@/components/imCore.manifest
+@BINPATH@/components/facebook.js
+@BINPATH@/components/facebook.manifest
+@BINPATH@/components/gtalk.js
+@BINPATH@/components/gtalk.manifest
+@BINPATH@/components/twitter.js
+@BINPATH@/components/twitter.manifest
+@BINPATH@/components/irc.js
+@BINPATH@/components/irc.manifest
+@BINPATH@/components/xmpp.js
+@BINPATH@/components/xmpp.manifest
+@BINPATH@/components/smileProtocolHandler.js
+@BINPATH@/components/smileProtocolHandler.manifest
+@BINPATH@/components/logger.js
+@BINPATH@/components/logger.manifest
+
+; Thunderbird specific
+@BINPATH@/@PREF_DIR@/all-im.js
+@BINPATH@/components/im.manifest
+@BINPATH@/components/imIncomingServer.js
+@BINPATH@/components/imProtocolInfo.js
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Chrome Files
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+@BINPATH@/chrome/classic@JAREXT@
+@BINPATH@/chrome/classic.manifest
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Default Profile Settings
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; default pref files
+@BINPATH@/defaults/pref/all-thunderbird.js
+@BINPATH@/defaults/pref/channel-prefs.js
+@BINPATH@/defaults/pref/composer.js
+@BINPATH@/defaults/pref/mailnews.js
+@BINPATH@/defaults/pref/mdn.js
+@BINPATH@/defaults/pref/smime.js
+@BINPATH@/defaults/pref/thunderbird-branding.js
+@BINPATH@/greprefs.js
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; App extensions to Mail
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; LDAP components
+@BINPATH@/components/mozldap.xpt
+@BINPATH@/components/nsAbLDAPAttributeMap.js
+@BINPATH@/components/nsLDAPProtocolHandler.js
+@BINPATH@/components/ldapComponents.manifest
+#ifdef XP_WIN32
+@BINPATH@/nsldap32v60@DLL_SUFFIX@
+@BINPATH@/nsldappr32v60@DLL_SUFFIX@
+@BINPATH@/nsldif32v60@DLL_SUFFIX@
+#else
+@BINPATH@/@DLL_PREFIX@ldap60@DLL_SUFFIX@
+@BINPATH@/@DLL_PREFIX@ldif60@DLL_SUFFIX@
+@BINPATH@/@DLL_PREFIX@prldap60@DLL_SUFFIX@
+#endif
+
+; login manager
+@BINPATH@/components/loginmgr.xpt
+@BINPATH@/components/nsLoginInfo.js
+@BINPATH@/components/nsLoginManager.js
+@BINPATH@/components/nsLoginManagerPrompter.js
+@BINPATH@/components/passwordmgr.manifest
+@BINPATH@/components/storage-Legacy.js
+@BINPATH@/components/storage-mozStorage.js
+@BINPATH@/components/crypto-SDR.js
+
+; download progress
+@BINPATH@/components/nsHelperAppDlg.js
+@BINPATH@/components/nsHelperAppDlg.manifest
+@BINPATH@/components/nsDownloadManagerUI.js
+@BINPATH@/components/nsDownloadManagerUI.manifest
+@BINPATH@/components/downloads.xpt
+
+; Protocol/Content handling
+@BINPATH@/components/nsContentDispatchChooser.js
+@BINPATH@/components/nsContentDispatchChooser.manifest
+@BINPATH@/components/nsHandlerService.js
+@BINPATH@/components/nsHandlerService.manifest
+@BINPATH@/components/nsWebHandlerApp.js
+@BINPATH@/components/nsWebHandlerApp.manifest
+@BINPATH@/components/nsSMTPProtocolHandler.js
+@BINPATH@/components/nsSMTPProtocolHandler.manifest
+
+; spellchecker (may not be present)
+@BINPATH@/components/spellchecker.xpt
+
+; misson control, autoconfig
+@BINPATH@/defaults/autoconfig/platform.js
+@BINPATH@/defaults/autoconfig/prefcalls.js
+@BINPATH@/components/autoconfig.xpt
+
+; Phishing Protection
+@BINPATH@/components/phishing.manifest
+@BINPATH@/components/nsPhishingProtectionApplication.js
+@BINPATH@/components/nsUrlClassifierListManager.js
+@BINPATH@/components/nsUrlClassifierHashCompleter.js
+@BINPATH@/components/nsUrlClassifierLib.js
+@BINPATH@/components/nsURLClassifier.manifest
+@BINPATH@/components/url-classifier.xpt
+
+; Address Book autocomplete
+@BINPATH@/components/nsAbAutoCompleteMyDomain.js
+@BINPATH@/components/nsAbAutoCompleteSearch.js
+
+; Windows Search integration
+; the module is included as part of the "Modules" rule
+#ifdef XP_WIN32
+@BINPATH@/components/mailwinsearch.xpt
+@BINPATH@/WSEnable.exe
+#endif
+
+; Bayesian trait analysis
+@BINPATH@/components/nsMsgTraitService.js
+@BINPATH@/components/nsMsgTraitService.manifest
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+; Base Package Files
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+; xpconnect
+@BINPATH@/components/xpconnect.xpt
+
+; XP widgets/graphics
+@BINPATH@/components/widget.xpt
+#ifdef XP_MACOSX
+@BINPATH@/components/widget_cocoa.xpt
+#endif
+@BINPATH@/components/gfx.xpt
+
+; layout
+@BINPATH@/components/content_base.xpt
+@BINPATH@/components/content_canvas.xpt
+@BINPATH@/components/content_events.xpt
+@BINPATH@/components/content_html.xpt
+@BINPATH@/components/content_htmldoc.xpt
+@BINPATH@/components/content_xslt.xpt
+@BINPATH@/components/html5.xpt
+@BINPATH@/components/htmlparser.xpt
+@BINPATH@/components/identity.xpt
+@BINPATH@/components/layout_base.xpt
+#ifdef NS_PRINTING
+@BINPATH@/components/layout_printing.xpt
+#endif
+@BINPATH@/components/layout_xul.xpt
+@BINPATH@/components/xulapp.xpt
+@BINPATH@/components/xul.xpt
+@BINPATH@/components/xuldoc.xpt
+@BINPATH@/components/xultmpl.xpt
+
+@BINPATH@/components/inspector.xpt
+
+; Imaging:
+@BINPATH@/components/imgicon.xpt
+@BINPATH@/components/imglib2.xpt
+
+; accessibility (out of process API support)
+#ifdef ACCESSIBILITY
+@BINPATH@/components/accessibility.xpt
+#ifdef XP_WIN32
+@BINPATH@/AccessibleMarshal.dll
+#endif
+#endif
+
+; caps (JavaScript security)
+@BINPATH@/components/caps.xpt
+
+; glue: appshell, docshell, uriloader, chrome, components
+@BINPATH@/components/appshell.xpt
+@BINPATH@/components/appstartup.xpt
+@BINPATH@/components/docshell.xpt
+@BINPATH@/components/uriloader.xpt
+@BINPATH@/components/webBrowser_core.xpt
+@BINPATH@/components/windowwatcher.xpt
+@BINPATH@/components/webbrowserpersist.xpt
+@BINPATH@/components/commandhandler.xpt
+
+; jar
+@BINPATH@/components/jar.xpt
+
+; prefs
+@BINPATH@/components/pref.xpt
+
+; profile
+@BINPATH@/components/profile.xpt
+@BINPATH@/components/toolkitprofile.xpt
+
+; toolkit
+@BINPATH@/components/AppProtocolHandler.js
+@BINPATH@/components/AppProtocolHandler.manifest
+@BINPATH@/components/AppsService.js
+@BINPATH@/components/AppsService.manifest
+@BINPATH@/components/BrowserElementParent.js
+@BINPATH@/components/BrowserElementParent.manifest
+@BINPATH@/components/ColorAnalyzer.js
+@BINPATH@/components/Identity.manifest
+@BINPATH@/components/PageThumbsProtocol.js
+@BINPATH@/components/PermissionSettings.js
+@BINPATH@/components/SettingsManager.js
+@BINPATH@/components/SettingsManager.manifest
+@BINPATH@/components/SiteSpecificUserAgent.js
+@BINPATH@/components/SiteSpecificUserAgent.manifest
+@BINPATH@/components/Webapps.js
+@BINPATH@/components/Webapps.manifest
+@BINPATH@/components/commandlines.xpt
+@BINPATH@/components/chrome.xpt
+@BINPATH@/components/cryptoComponents.manifest
+@BINPATH@/components/Downloads.manifest
+@BINPATH@/components/DownloadLegacy.js
+@BINPATH@/components/nsDefaultCLH.js
+@BINPATH@/components/nsDefaultCLH.manifest
+@BINPATH@/components/nsDOMIdentity.js
+@BINPATH@/components/nsFormAutoComplete.js
+@BINPATH@/components/nsFormHistory.js
+@BINPATH@/components/FormHistoryStartup.js
+@BINPATH@/components/nsIDService.js
+@BINPATH@/components/nsInputListAutoComplete.js
+@BINPATH@/components/nsLivemarkService.js
+@BINPATH@/components/nsPlacesAutoComplete.js
+@BINPATH@/components/nsPlacesAutoComplete.manifest
+@BINPATH@/components/nsPlacesExpiration.js
+@BINPATH@/components/nsPrompter.js
+@BINPATH@/components/nsPrompter.manifest
+@BINPATH@/components/nsSearchService.js
+@BINPATH@/components/nsSearchSuggestions.js
+@BINPATH@/components/nsTaggingService.js
+@BINPATH@/components/PlacesCategoriesStarter.js
+@BINPATH@/components/servicesComponents.manifest
+@BINPATH@/components/TCPSocket.js
+@BINPATH@/components/TCPSocketParentIntermediary.js
+@BINPATH@/components/TCPSocket.manifest
+#ifdef MOZ_WEBRTC
+@BINPATH@/components/PeerConnection.js
+@BINPATH@/components/PeerConnection.manifest
+#endif
+@BINPATH@/components/TelemetryPing.js
+@BINPATH@/components/TelemetryPing.manifest
+@BINPATH@/components/toolkitplaces.manifest
+@BINPATH@/components/toolkitsearch.manifest
+#ifdef UNIX_BUT_NOT_MAC
+@BINPATH@/components/toolkitremote.xpt
+@BINPATH@/mozilla-xremote-client
+#endif
+#ifdef MOZ_GTK2
+@BINPATH@/components/filepicker.xpt
+@BINPATH@/components/nsFilePicker.js
+@BINPATH@/components/nsFilePicker.manifest
+#endif
+#ifdef MOZ_ENABLE_DBUS
+@BINPATH@/components/@DLL_PREFIX@dbusservice@DLL_SUFFIX@
+#endif
+#ifdef MOZ_ENABLE_PROFILER_SPS
+@BINPATH@/components/profiler.xpt
+#endif
+
+; rdf
+@BINPATH@/components/rdf.xpt
+
+; required i18n libraries
+@BINPATH@/components/intl.xpt
+@BINPATH@/components/locale.xpt
+@BINPATH@/components/uconv.xpt
+@BINPATH@/components/unicharutil.xpt
+
+; dom
+@BINPATH@/components/dom.xpt
+@BINPATH@/components/dom_alarm.xpt
+@BINPATH@/components/dom_apps.xpt
+@BINPATH@/components/dom_base.xpt
+@BINPATH@/components/dom_battery.xpt
+@BINPATH@/components/dom_browserelement.xpt
+@BINPATH@/components/dom_camera.xpt
+@BINPATH@/components/dom_canvas.xpt
+@BINPATH@/components/dom_contacts.xpt
+@BINPATH@/components/dom_core.xpt
+@BINPATH@/components/dom_css.xpt
+@BINPATH@/components/dom_devicestorage.xpt
+@BINPATH@/components/dom_events.xpt
+@BINPATH@/components/dom_file.xpt
+@BINPATH@/components/dom_gamepad.xpt
+@BINPATH@/components/dom_geolocation.xpt
+@BINPATH@/components/dom_html.xpt
+@BINPATH@/components/dom_indexeddb.xpt
+@BINPATH@/components/dom_json.xpt
+@BINPATH@/components/dom_media.xpt
+@BINPATH@/components/dom_mobilemessage.xpt
+@BINPATH@/components/dom_network.xpt
+@BINPATH@/components/dom_notification.xpt
+@BINPATH@/components/dom_offline.xpt
+@BINPATH@/components/dom_permissionsettings.xpt
+@BINPATH@/components/dom_power.xpt
+@BINPATH@/components/dom_push.xpt
+@BINPATH@/components/dom_quota.xpt
+@BINPATH@/components/dom_range.xpt
+@BINPATH@/components/dom_settings.xpt
+@BINPATH@/components/dom_sidebar.xpt
+@BINPATH@/components/dom_smil.xpt
+@BINPATH@/components/dom_storage.xpt
+@BINPATH@/components/dom_stylesheets.xpt
+@BINPATH@/components/dom_system.xpt
+@BINPATH@/components/dom_traversal.xpt
+@BINPATH@/components/dom_webspeechrecognition.xpt
+@BINPATH@/components/dom_webspeechsynth.xpt
+@BINPATH@/components/dom_xbl.xpt
+@BINPATH@/components/dom_xul.xpt
+@BINPATH@/components/NetworkGeolocationProvider.js
+@BINPATH@/components/NetworkGeolocationProvider.manifest
+
+; editor / composer for HTML compose
+@BINPATH@/components/editor.xpt
+@BINPATH@/components/composer.xpt
+@BINPATH@/components/txmgr.xpt
+
+; find functionality
+@BINPATH@/components/txtsvc.xpt
+
+; moz storage
+@BINPATH@/components/storage.xpt
+
+; netwerk
+@BINPATH@/components/necko.xpt
+@BINPATH@/components/necko_about.xpt
+@BINPATH@/components/necko_dns.xpt
+@BINPATH@/components/necko_http.xpt
+@BINPATH@/components/necko_ipc.xpt
+@BINPATH@/components/necko_res.xpt
+@BINPATH@/components/necko_strconv.xpt
+@BINPATH@/components/necko_file.xpt
+@BINPATH@/components/necko_ftp.xpt
+@BINPATH@/components/necko_cache.xpt
+@BINPATH@/components/necko_cookie.xpt
+@BINPATH@/components/necko_socket.xpt
+@BINPATH@/components/necko_viewsource.xpt
+@BINPATH@/components/necko_websocket.xpt
+#ifdef NECKO_WIFI
+@BINPATH@/components/necko_wifi.xpt
+#endif
+@BINPATH@/components/necko_wyciwyg.xpt
+
+; extensions
+@BINPATH@/components/addonManager.js
+@BINPATH@/components/amContentHandler.js
+@BINPATH@/components/amWebInstallListener.js
+@BINPATH@/components/nsBlocklistService.js
+#ifdef MOZ_UPDATER
+@BINPATH@/components/nsUpdateService.js
+@BINPATH@/components/nsUpdateService.manifest
+@BINPATH@/components/nsUpdateServiceStub.js
+#endif
+@BINPATH@/components/nsUpdateTimerManager.js
+@BINPATH@/components/nsUpdateTimerManager.manifest
+@BINPATH@/components/extensions.xpt
+@BINPATH@/components/extensions.manifest
+@BINPATH@/components/update.xpt
+#ifdef MOZ_WEBSERVICES
+@BINPATH@/components/websrvcs.xpt
+#endif
+@BINPATH@/components/nsURLFormatter.js
+@BINPATH@/components/nsURLFormatter.manifest
+@BINPATH@/components/urlformatter.xpt
+@BINPATH@/components/nsContentPrefService.js
+@BINPATH@/components/nsContentPrefService.manifest
+
+; [Personal Security Manager]
+;
+; NSS libraries are signed in the staging directory,
+; meaning their .chk files are created there directly.
+;
+#ifndef MOZ_NATIVE_NSS
+@BINPATH@/@DLL_PREFIX@freebl3@DLL_SUFFIX@
+@BINPATH@/@DLL_PREFIX@nss3@DLL_SUFFIX@
+@BINPATH@/@DLL_PREFIX@nssckbi@DLL_SUFFIX@
+#ifndef NSS_DISABLE_DBM
+@BINPATH@/@DLL_PREFIX@nssdbm3@DLL_SUFFIX@
+#endif
+@BINPATH@/@DLL_PREFIX@nssutil3@DLL_SUFFIX@
+@BINPATH@/@DLL_PREFIX@smime3@DLL_SUFFIX@
+@BINPATH@/@DLL_PREFIX@softokn3@DLL_SUFFIX@
+@BINPATH@/@DLL_PREFIX@ssl3@DLL_SUFFIX@
+#endif
+@BINPATH@/chrome/pippki@JAREXT@
+@BINPATH@/chrome/pippki.manifest
+@BINPATH@/components/pipboot.xpt
+@BINPATH@/components/pipnss.xpt
+@BINPATH@/components/pippki.xpt
+
+; for Solaris SPARC
+#ifdef SOLARIS
+@BINPATH@/@DLL_PREFIX@freebl_32fpu_3@DLL_SUFFIX@
+@BINPATH@/@DLL_PREFIX@freebl_32int_3@DLL_SUFFIX@
+@BINPATH@/@DLL_PREFIX@freebl_32int64_3@DLL_SUFFIX@
+#endif
+
+; core platform files
+@BINPATH@/components/FeedProcessor.js
+@BINPATH@/components/FeedProcessor.manifest
+@BINPATH@/components/xpautocomplete.xpt
+@BINPATH@/components/autocomplete.xpt
+@BINPATH@/components/alerts.xpt
+@BINPATH@/components/jsdebugger.xpt
+@BINPATH@/components/jsdservice.xpt
+@BINPATH@/components/jsinspector.xpt
+@BINPATH@/components/fastfind.xpt
+@BINPATH@/components/find.xpt
+@BINPATH@/components/ConsoleAPI.js
+@BINPATH@/components/ConsoleAPI.manifest
+@BINPATH@/components/ContactManager.js
+@BINPATH@/components/ContactManager.manifest
+@BINPATH@/components/contentAreaDropListener.js
+@BINPATH@/components/contentAreaDropListener.manifest
+@BINPATH@/components/contentSecurityPolicy.js
+@BINPATH@/components/contentSecurityPolicy.manifest
+@BINPATH@/components/directory.xpt
+@BINPATH@/components/jsconsole-clhandler.js
+@BINPATH@/components/jsconsole-clhandler.manifest
+@BINPATH@/components/layout_xul_tree.xpt
+@BINPATH@/components/mozfind.xpt
+@BINPATH@/components/mimetype.xpt
+@BINPATH@/components/parentalcontrols.xpt
+#ifdef MOZ_WEBRTC
+@BINPATH@/components/peerconnection.xpt
+#endif
+@BINPATH@/components/exthandler.xpt
+@BINPATH@/components/exthelper.xpt
+@BINPATH@/components/embed_base.xpt
+@BINPATH@/components/windowds.xpt
+@BINPATH@/components/dom_xpath.xpt
+@BINPATH@/components/lwbrk.xpt
+@BINPATH@/components/nsINIProcessor.js
+@BINPATH@/components/nsINIProcessor.manifest
+@BINPATH@/components/pluginGlue.manifest
+@BINPATH@/components/txEXSLTRegExFunctions.js
+@BINPATH@/components/txEXSLTRegExFunctions.manifest
+@BINPATH@/components/feeds.xpt
+@BINPATH@/components/saxparser.xpt
+@BINPATH@/components/satchel.manifest
+@BINPATH@/components/satchel.xpt
+@BINPATH@/components/shistory.xpt
+@BINPATH@/components/telemetry.xpt
+@BINPATH@/components/zipwriter.xpt
+@BINPATH@/components/cookie.xpt
+@BINPATH@/components/places.xpt
+@BINPATH@/components/plugin.xpt
+@BINPATH@/components/prefetch.xpt
+@BINPATH@/res/langGroups.properties
+@BINPATH@/res/language.properties
+@BINPATH@/res/entityTables/*
+@BINPATH@/res/dtd/*
+@BINPATH@/res/fonts/*
+@BINPATH@/res/contenteditable.css
+@BINPATH@/res/designmode.css
+@BINPATH@/res/html/folder.png
+#ifdef XP_MACOSX
+@BINPATH@/res/cursors/
+@BINPATH@/res/MainMenu.nib/
+#endif
+
+; editor resource files
+@BINPATH@/res/EditorOverride.css
+@BINPATH@/res/grabber.gif
+@BINPATH@/res/table-add-column-after-active.gif
+@BINPATH@/res/table-add-column-after-hover.gif
+@BINPATH@/res/table-add-column-after.gif
+@BINPATH@/res/table-add-column-before-active.gif
+@BINPATH@/res/table-add-column-before-hover.gif
+@BINPATH@/res/table-add-column-before.gif
+@BINPATH@/res/table-add-row-after-active.gif
+@BINPATH@/res/table-add-row-after-hover.gif
+@BINPATH@/res/table-add-row-after.gif
+@BINPATH@/res/table-add-row-before-active.gif
+@BINPATH@/res/table-add-row-before-hover.gif
+@BINPATH@/res/table-add-row-before.gif
+@BINPATH@/res/table-remove-column-active.gif
+@BINPATH@/res/table-remove-column-hover.gif
+@BINPATH@/res/table-remove-column.gif
+@BINPATH@/res/table-remove-row-active.gif
+@BINPATH@/res/table-remove-row-hover.gif
+@BINPATH@/res/table-remove-row.gif
+
+; svg
+@BINPATH@/res/svg.css
+@BINPATH@/components/dom_svg.xpt
+
+; [Updater]
+#ifdef MOZ_UPDATER
+#ifdef XP_MACOSX
+@BINPATH@/updater.app/
+#else
+@BINPATH@/updater@BIN_SUFFIX@
+#endif
+#endif
+
+; [MaintenanceService]
+;
+#ifdef MOZ_MAINTENANCE_SERVICE
+@BINPATH@/maintenanceservice.exe
+@BINPATH@/maintenanceservice_installer.exe
+#endif
+
+; [Crash Reporter]
+;
+#ifdef MOZ_CRASHREPORTER
+#ifdef XP_MACOSX
+@BINPATH@/crashreporter.app/
+#else
+#ifndef XP_OS2
+@BINPATH@/crashreporter@BIN_SUFFIX@
+@BINPATH@/crashreporter.ini
+#ifdef XP_UNIX
+@BINPATH@/Throbber-small.gif
+#endif
+#endif
+#endif
+#ifdef MOZ_CRASHREPORTER_INJECTOR
+@BINPATH@/breakpadinjector.dll
+#endif
+#endif
+
+; GNOME hooks
+#ifdef MOZ_ENABLE_GNOME_COMPONENT
+@BINPATH@/components/@DLL_PREFIX@mozgnome@DLL_SUFFIX@
+#endif
--- /dev/null
+<!--LOCALIZATION NOTE msgCompSMIMEOverlay.dtd UI for s/mime hooks in message composition -->
+<!ENTITY menu_securityEncryptRequire.label "Encrypt This Message">
+<!ENTITY menu_securityEncryptRequire.accesskey "E">
+
+<!ENTITY menu_securitySign.label "Digitally Sign This Message">
+<!ENTITY menu_securitySign.accesskey "M">
+
+<!ENTITY menu_securityStatus.label "View Security Info">
+<!ENTITY menu_securityStatus.accesskey "I">
+
+<!ENTITY securityButton.label "Security">
+<!ENTITY securityButton.tooltip "View or change security settings">
+
+<!ENTITY menu_viewSecurityStatus.label "Message Security Info">
+<!ENTITY menu_viewSecurityStatus.accesskey "I">
+
+<!ENTITY menu_securitySMIMEReceiptRequest.label "Request a Signed Receipt">
+<!ENTITY menu_securitySMIMEReceiptRequest.accesskey "R">
+
+<!ENTITY menu_securityLabel.label "Security Label...">
+<!ENTITY menu_securityLabel.accesskey "L">
+
+<!ENTITY menu.secureheaders.label "Secure headers">
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<!--LOCALIZATION NOTE msgCompSecurityInfo.dtd UI for viewing security status when composing a message -->
+
+<!ENTITY title.label "Message Security">
+<!ENTITY subject.plaintextWarning "Please note: Subject lines of email messages are never encrypted.">
+<!ENTITY status.heading "The contents of your message will be sent as follows:">
+<!ENTITY status.signed "Digitally signed:">
+<!ENTITY status.securityLabel "Security Label:">
+<!ENTITY status.encrypted "Encrypted:">
+<!ENTITY status.certificates "Certificates:">
+<!ENTITY status.signedReceiptRequest "Signed Receipt Request:">
+<!ENTITY status.securityLabel "Security Label:">
+<!ENTITY status.tripleWrapped "Triple Wrapped:">
+<!ENTITY view.label "View">
+<!ENTITY view.accesskey "V">
+<!ENTITY tree.recipient "Recipient">
+<!ENTITY tree.status "Status">
+<!ENTITY tree.issuedDate "Issued">
+<!ENTITY tree.expiresDate "Expires">
--- /dev/null
+<!--LOCALIZATION NOTE msgCompSecurityLabelDialog.dtd UI for selecting security label properties when composing a message -->
+<!ENTITY securityLabelDialog.name "Security Label">
+<!ENTITY securityLabelDialog.securityPolicyIdentifier.name "Security Policy:">
+<!ENTITY securityLabelDialog.securityClassification.name "Security Classification:">
+<!ENTITY securityLabelDialog.privacyMark.name "Privacy Mark:">
+<!ENTITY securityLabelDialog.securityCategories.name "Security Categories:">
+<!ENTITY securityLabelDialog.securityCategories.button.add.name "Add">
+<!ENTITY securityLabelDialog.securityCategories.button.remove.name "Remove selected">
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<!--LOCALIZATION NOTE msgReadSMIMEOverlay.dtd UI for s/mime hooks in message reading -->
+
+<!ENTITY menu_securityStatus.label "Message Security Info">
+<!ENTITY menu_securityStatus.accesskey "I">
+<!ENTITY securityLabelSecurityClassificationColumn.label "Security Classification">
+<!ENTITY securityLabelSecurityClassificationColumn.tooltip "Click to sort by Security Classification">
--- /dev/null
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ImapOnDemand=The displayed message has been digitally signed, but not all its attachments have been downloaded yet. Therefore, the signature cannot be validated. Click OK to download the complete message and validate the signature.
+#
+#NOTE To translater, anything between %..% and <..> should not be translated.
+# the former will be replaced by java script, and the latter is HTML formatting.
+#
+CantDecryptTitle=%brand% cannot decrypt this message
+CantDecryptBody=The sender encrypted this message to you using one of your digital certificates, however %brand% was not able to find this certificate and corresponding private key. <br> Possible solutions: <br><ul><li>If you have a smartcard, please insert it now. <li>If you are using a new machine, or if you are using a new %brand% profile, you will need to restore your certificate and private key from a backup. Certificate backups usually end in ".p12".</ul>
+secureinfomsg_default=Integrity of this message is corrupted
+secureinfomsgmore_default=Make sure the message comes from a trusted sender
+secureinfomsg_ok=Integrity of this message is guaranteed
+secureinfomsgmore_ok=
+secureinfomsg_notok=The message signature is corrupted
+secureinfomsgmore_notok=several reasons: body message has been changed or signature has been changed or sender message has been changed
+secureinfomsg_hdrnok=A header has been changed
+secureinfomsg_unsecured=this message is unsecured
+secureinfomsg_hdrwarning=Signature of this message is valid but its integrity is unguaranteed
+secureinfomsgmore_warning=According to Secured Headers settings of local account, headers should be secured
+securevalue_warning=This header should be secured
\ No newline at end of file
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<!--LOCALIZATION NOTE msgReadSecurityInfo.dtd UI for viewing security status when reading a received message -->
+
+<!ENTITY status.label "Message Security">
+<!ENTITY signatureCert.label "View Signature Certificate">
+<!ENTITY encryptionCert.label "View Encryption Certificate">
+
+<!ENTITY signer.name "Signed by:">
+<!ENTITY recipient.name "Encrypted for:">
+<!ENTITY email.address "Email address:">
+<!ENTITY issuer.name "Certificate issued by:">
+
+<!ENTITY securityLabel.name "Security Label">
+<!ENTITY securityLabel.securityPolicyIdentifier.name "Security Policy:">
+<!ENTITY securityLabel.securityClassification.name "Security Classification:">
+<!ENTITY securityLabel.privacyMark.name "Privacy Mark:">
+<!ENTITY securityLabel.securityCategories.name "Security Categories:">
--- /dev/null
+noSigningCertTitle=Unable to send a signed receipt
+noSigningCert=No signing certificate available!
\ No newline at end of file
--- /dev/null
+# msgSecurityLabel.js
+unknownSecurityPolicyIdentifier=unknown
+unknownSecurityClassification=unknown
+unknownSecurityCategory=unknown
+# msgCompSecurityLabelDialog.js
+noSecurityPolicyIdentifier=none
+noSecurityClassification=none
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<!ENTITY newDirectoryTitle.label "Directory Server Properties">
+<!ENTITY directoryName.label "Name: ">
+<!ENTITY directoryName.accesskey "n">
+<!ENTITY directoryHostname.label "Hostname: ">
+<!ENTITY directoryHostname.accesskey "o">
+<!ENTITY directoryBaseDN.label "Base DN: ">
+<!ENTITY directoryBaseDN.accesskey "b">
+<!ENTITY findButton.label "Find">
+<!ENTITY findButton.accesskey "f">
+<!ENTITY directorySecure.label "Use secure connection (SSL)">
+<!ENTITY directorySecure.accesskey "U">
+<!ENTITY directoryLogin.label "Bind DN: ">
+<!ENTITY directoryLogin.accesskey "i">
+<!ENTITY General.tab "General">
+<!ENTITY Offline.tab "Offline">
+<!ENTITY Advanced.tab "Advanced">
+<!ENTITY portNumber.label "Port number: ">
+<!ENTITY portNumber.accesskey "p">
+<!ENTITY searchFilter.label "Search filter: ">
+<!ENTITY searchFilter.accesskey "f">
+<!ENTITY scope.label "Scope: ">
+<!ENTITY scope.accesskey "c">
+<!ENTITY scopeOneLevel.label "One Level">
+<!ENTITY scopeOneLevel.accesskey "L">
+<!ENTITY scopeSubtree.label "Subtree">
+<!ENTITY scopeSubtree.accesskey "S">
+<!ENTITY return.label "Don't return more than">
+<!ENTITY return.accesskey "r">
+<!ENTITY results.label "results">
+<!ENTITY offlineText.label "You can download a local copy of this directory so that it is available for use when you are working offline.">
+<!ENTITY saslMechanism.label "Login method: ">
+<!ENTITY saslMechanism.accesskey "m">
+<!ENTITY saslOff.label "Simple">
+<!ENTITY saslOff.accesskey "l">
+<!ENTITY saslGSSAPI.label "Kerberos (GSSAPI)">
+<!ENTITY saslGSSAPI.accesskey "K">
+<!ENTITY saslEXTERNAL.label "EXTERNAL">
+<!ENTITY saslEXTERNAL.accesskey "E">
+
+
+<!-- Localization note: this is here because the width of the dialog
+ is determined by the width of the base DN box; and that is likely
+ to vary somewhat with the language.
+-->
+<!ENTITY newDirectoryWidth "36em">
--- /dev/null
+<!--LOCALIZATION NOTE am-secureheaders.dtd UI for secure headers preferences -->\r
+<!ENTITY pane.title "Secure Headers">\r
+<!ENTITY secureHeaderFolderPicker.label "Secure headers file">\r
+<!ENTITY secureHeaderPath.label "Secure header file">\r
+<!ENTITY browseFolder.label "Browse...">\r
+<!ENTITY browseFolder.accesskey "B">\r
+<!ENTITY useSecureHeaders.label "Use secure headers">\r
+<!ENTITY secureHeadersDescription.label "Secure headers definition" >\r
+<!ENTITY secureHeadersDatas.label "Secure headers" >\r
+<!ENTITY smime.am.infomsg.label "Set security state of each message">\r
+\r
+\r
+\r
+\r
+\r
--- /dev/null
+# ***** BEGIN LICENSE BLOCK *****\r
+# Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
+# ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
+# \r
+#\r
+# Redistribution and use, in source and binary forms, with or without modification, \r
+# are permitted provided that the following conditons are met :\r
+#\r
+# 1. Redistributions of source code must retain the above copyright notice, \r
+# 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+# in the redistribution of the source code.\r
+# 3. Neither the names of the copyright holders nor the names of any contributors \r
+# may be used to endorse or promote products derived from this software without specific \r
+# prior written permission from EADS Defence and Security.\r
+# \r
+# Alternatively, the contents of this file may be used under the terms of\r
+# either of the GNU General Public License Version 2 or later (the "GPL"),\r
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
+# in which case the provisions of the GPL or the LGPL are applicable instead\r
+# of those above. If you wish to allow use of your version of this file only\r
+# under the terms of either the GPL or the LGPL, and not to allow others to\r
+# use your version of this file under the terms of the MPL, indicate your\r
+# decision by deleting the provisions above and replace them with the notice\r
+# and other provisions required by the GPL or the LGPL. If you do not delete\r
+# the provisions above, a recipient may use your version of this file under\r
+# the terms of any one of the MPL, the GPL or the LGPL.\r
+# \r
+# REMINDER :\r
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+# IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+# \r
+# EADS Defence and Security - 1 Boulevard Jean Moulin - \r
+# ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+# ***** END LICENSE BLOCK *****\r
+# Strings used in the Mozill AccountManager\r
+prefPanel-secureheaders=Secure Headers\r
+\r
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<!-- extracted from am-server-top.xul -->
+
+<!ENTITY messageStorage.label "Message Storage">
+<!ENTITY securitySettings.label "Security Settings">
+<!ENTITY serverSettings.label "Server Settings">
+<!ENTITY serverType.label "Server Type:">
+<!ENTITY serverName.label "Server Name:">
+<!ENTITY serverName.accesskey "S">
+<!ENTITY userName.label "User Name:">
+<!ENTITY userName.accesskey "N">
+<!ENTITY port.label "Port:">
+<!ENTITY port.accesskey "P">
+<!ENTITY serverPortDefault.label "Default:">
+<!-- LOCALIZATION NOTE (biffStart.label) : translate below 2 line with grammer dependency
+ For example, in Japanese cases:
+ biffStart.label "every"
+ biffEnd.label "minutes for new messages Check"
+-->
+<!ENTITY biffStart.label "Check for new messages every ">
+<!ENTITY biffStart.accesskey "y">
+<!ENTITY biffEnd.label "minutes">
+<!ENTITY connectionSecurity.label "Connection security:">
+<!ENTITY connectionSecurity.accesskey "u">
+<!ENTITY connectionSecurityType-0.label "None">
+<!ENTITY connectionSecurityType-1.label "STARTTLS, if available">
+<!ENTITY connectionSecurityType-2.label "STARTTLS">
+<!ENTITY connectionSecurityType-3.label "SSL/TLS">
+<!ENTITY authMethod.label "Authentication method:">
+<!ENTITY authMethod.accesskey "i">
+<!ENTITY leaveOnServer.label "Leave messages on server">
+<!ENTITY leaveOnServer.accesskey "g">
+<!ENTITY headersOnly.label "Fetch headers only">
+<!ENTITY headersOnly.accesskey "e">
+<!ENTITY deleteByAgeFromServer.label "For at most">
+<!ENTITY deleteByAgeFromServer.accesskey "o">
+<!ENTITY daysEnd.label "days">
+<!ENTITY deleteOnServer2.label "Until I delete them">
+<!ENTITY deleteOnServer2.accesskey "d">
+<!ENTITY downloadOnBiff.label "Automatically download new messages">
+<!ENTITY downloadOnBiff.accesskey "m">
+<!ENTITY username.label "Your Login Name">
+<!ENTITY deleteMessagePrefix.label "When I delete a message:">
+<!ENTITY modelMoveToTrash.label "Move it to this folder:">
+<!ENTITY modelMoveToTrash.accesskey "o">
+<!ENTITY modelMarkDeleted.label "Just mark it as deleted">
+<!ENTITY modelMarkDeleted.accesskey "k">
+<!ENTITY modelDeleteImmediately.label "Remove it immediately">
+<!ENTITY modelDeleteImmediately.accesskey "d">
+<!-- LOCALIZATION NOTE (expungeOnExit.label) : do not translate two of """ in below line -->
+<!ENTITY expungeOnExit.label "Clean up ("Expunge") Inbox on Exit">
+<!ENTITY expungeOnExit.accesskey "E">
+<!ENTITY emptyTrashOnExit.label "Empty Trash on Exit">
+<!ENTITY emptyTrashOnExit.accesskey "x">
+<!ENTITY loginAtStartup.label "Check for new messages at startup">
+<!ENTITY loginAtStartup.accesskey "C">
+<!-- LOCALIZATION NOTE (maxMessagesStart.label) : translate below 2 lines with grammar dependency
+ maxMessengerStart.label will be followed by maxMessagesEnd.label with the number
+ of messages between them
+-->
+<!ENTITY maxMessagesStart.label "Ask me before downloading more than">
+<!ENTITY maxMessagesStart.accesskey "m">
+<!-- LOCALIZATION NOTE (maxMessagesEnd.label) : see note for maxMessagesStart.label -->
+<!ENTITY maxMessagesEnd.label "messages">
+<!ENTITY alwaysAuthenticate.label "Always request authentication when connecting to this server">
+<!ENTITY alwaysAuthenticate.accesskey "w">
+<!ENTITY newsrcFilePath.label "newsrc file:">
+<!ENTITY newsrcPicker.label "Select newsrc File">
+<!ENTITY abbreviate.label "Show newsgroup names in the Mail Folder pane as:">
+<!ENTITY abbreviateOn.label "Full names (For example, 'netscape.public.mozilla.mail-news')">
+<!ENTITY abbreviateOff.label "Abbreviate names (For example, 'n.p.m.mail-news')">
+<!ENTITY advancedButton.label "Advanced…">
+<!ENTITY advancedButton.accesskey "v">
+<!ENTITY serverDefaultCharset.label "Default Character Encoding:">
+<!ENTITY localPath.label "Local directory:">
+<!ENTITY localFolderPicker.label "Select Local Directory">
+<!ENTITY browseFolder.label "Browse…">
+<!ENTITY browseFolder.accesskey "B">
+<!ENTITY browseNewsrc.label "Browse…">
+<!ENTITY browseNewsrc.accesskey "e">
+
+<!ENTITY accountTitle.label "Account Settings">
+<!ENTITY accountSettingsDesc.label "The following is a special account. There are no identities associated with it.">
+<!ENTITY authByCert.label "Authentification by certificate, if available">
+<!ENTITY authByCert.accesskey "c">
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<!ENTITY securityTitle.label "Security">
+<!ENTITY securityTab.label "Security">
+<!ENTITY securityHeading.label "To send and receive signed or encrypted messages, you should specify both a digital signing certificate and an encryption certificate.">
+<!ENTITY encryptionGroupTitle.label "Encryption">
+<!ENTITY encryptionChoiceLabel.label "Default encryption setting when sending messages:">
+<!ENTITY neverEncrypt.label "Never (do not use encryption)">
+<!ENTITY neverEncrypt.accesskey "N">
+<!ENTITY alwaysEncryptMessage.label "Required (can't send message unless all recipients have certificates)">
+<!ENTITY alwaysEncryptMessage.accesskey "u">
+<!ENTITY encryptionCert.message "Use this certificate to encrypt & decrypt messages sent to you:">
+<!ENTITY digitalSign.certificate.button "Select…">
+<!ENTITY digitalSign.certificate.accesskey "S">
+<!ENTITY digitalSign.certificate_clear.button "Clear">
+<!ENTITY digitalSign.certificate_clear.accesskey "C">
+<!ENTITY encryption.certificate.button "Select…">
+<!ENTITY encryption.certificate.accesskey "t">
+<!ENTITY encryption.certificate_clear.button "Clear">
+<!ENTITY encryption.certificate_clear.accesskey "e">
+<!ENTITY signingGroupTitle.label "Digital Signing">
+<!ENTITY signMessage.label "Digitally sign messages (by default)">
+<!ENTITY signMessage.accesskey "D">
+<!ENTITY signingCert.message "Use this certificate to digitally sign messages you send:">
+<!ENTITY SMIMEReceiptRequest.label "When sending signed messages, always request a signed receipt">
+<!ENTITY SMIMEReceiptRequest.accesskey "W">
+<!ENTITY SMIMEReceiptSendPolicy.label "When I receive a request for a signed receipt:">
+<!ENTITY SMIMEReceiptSendPolicy.accesskey "R">
+<!ENTITY SMIMEReceiptSendPolicy.askMe.label "Ask me">
+<!ENTITY SMIMEReceiptSendPolicy.neverSend.label "Never send">
+<!ENTITY SMIMEReceiptSendPolicy.alwaysSend.label "Always send">
+
+<!ENTITY certificates.label "Certificates">
+<!ENTITY manageCerts.label "View Certificates">
+<!ENTITY manageCerts.accesskey "V">
+<!ENTITY manageDevices.label "Security Devices">
+<!ENTITY manageDevices.accesskey "y">
+
+<!ENTITY secureHeaderFolderPicker.label "Use this file to digitally sign headers of messages you send">
+<!ENTITY secureHeaderPath.label "Secure header file">
+<!ENTITY browseFolder.label "Browse...">
+<!ENTITY browseFolder.accesskey "B">
+<!ENTITY smime.am.infomsg.label "Display security state of received messages">
\ No newline at end of file
--- /dev/null
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+<!ENTITY titledefault.label "&brandFullName;">
+<!ENTITY titleSeparator.label " - ">
+
+<!-- File Menu -->
+<!ENTITY newFolderCmd.label "Folder…">
+<!ENTITY newFolderCmd.accesskey "F">
+<!ENTITY closeTabCmd2.label "Close Tab">
+<!ENTITY closeTabCmd2.accesskey "C">
+<!ENTITY closeOtherTabsCmd2.label "Close Other Tabs">
+<!ENTITY closeOtherTabsCmd2.accesskey "o">
+<!ENTITY recentlyClosedTabsCmd.label "Recently Closed Tabs">
+<!ENTITY recentlyClosedTabsCmd.accesskey "R">
+
+<!ENTITY undoCloseTabCmd.commandkey "T">
+<!-- LOCALIZATION NOTE (moveToNewWindow.label):
+ Menu option to cause the current tab to be migrated to a new Thunderbird
+ window.
+ -->
+<!ENTITY moveToNewWindow.label "Move to New Window">
+<!ENTITY moveToNewWindow.accesskey "W">
+<!ENTITY newVirtualFolderCmd.label "Saved Search…">
+<!ENTITY newVirtualFolderCmd.accesskey "S">
+<!ENTITY newOtherAccountsCmd.label "Other Accounts…">
+<!ENTITY newOtherAccountsCmd.accesskey "O">
+<!ENTITY newCreateEmailAccountCmd.label "Get a New Mail Account…">
+<!ENTITY newCreateEmailAccountCmd.accesskey "G">
+<!ENTITY newExistingEmailAccountCmd.label "Existing Mail Account…">
+<!ENTITY newExistingEmailAccountCmd.accesskey "E">
+<!ENTITY newIMAccountCmd.label "Chat Account…">
+<!ENTITY newIMAccountCmd.accesskey "C">
+<!ENTITY newFeedAccountCmd.label "Feed Account…">
+<!ENTITY newFeedAccountCmd.accesskey "d">
+<!ENTITY newIMContactCmd.label "Chat Contact…">
+<!ENTITY newIMContactCmd.accesskey "h">
+<!ENTITY openMessageFileCmd.label "Open Saved Message…">
+<!ENTITY openMessageFileCmd.accesskey "O">
+<!ENTITY openAttachmentCmd.label "Attachments">
+<!ENTITY openAttachmentCmd.accesskey "A">
+<!ENTITY saveAsMenu.label "Save As">
+<!ENTITY saveAsMenu.accesskey "S">
+<!ENTITY saveAsFileCmd.label "File">
+<!ENTITY saveAsFileCmd.accesskey "F">
+<!ENTITY saveAsFileCmd.key "s">
+<!ENTITY saveAsTemplateCmd.label "Template">
+<!ENTITY saveAsTemplateCmd.accesskey "T">
+<!ENTITY getNewMsgForCmd.label "Get New Messages for">
+<!ENTITY getNewMsgForCmd.accesskey "w">
+<!ENTITY getAllNewMsgCmdPopupMenu.label "All Accounts">
+<!ENTITY getAllNewMsgCmdPopupMenu.accesskey "A">
+<!ENTITY getNewMsgCurrentAccountCmdPopupMenu.label "Current Account">
+<!ENTITY getNewMsgCurrentAccountCmdPopupMenu.accesskey "C">
+<!ENTITY getNextNMsgCmd.label "Get Next 500 News Messages">
+<!ENTITY getNextNMsgCmd.accesskey "t">
+<!ENTITY sendUnsentCmd.label "Send Unsent Messages">
+<!ENTITY sendUnsentCmd.accesskey "d">
+<!ENTITY subscribeCmd.label "Subscribe…">
+<!ENTITY subscribeCmd.accesskey "b">
+<!ENTITY deleteFolder.label "Delete Folder">
+<!ENTITY deleteFolder.accesskey "e">
+<!ENTITY renameFolder.label "Rename Folder…">
+<!ENTITY renameFolder.accesskey "R">
+<!ENTITY renameFolder.key "VK_F2">
+<!ENTITY compactFolders.label "Compact Folders">
+<!ENTITY compactFolders.accesskey "F">
+<!ENTITY emptyTrashCmd.label "Empty Trash">
+<!ENTITY emptyTrashCmd.accesskey "y">
+<!ENTITY offlineMenu.label "Offline">
+<!ENTITY offlineMenu.accesskey "l">
+<!ENTITY offlineGoOfflineCmd.label "Work Offline">
+<!ENTITY offlineGoOfflineCmd.accesskey "w">
+<!ENTITY synchronizeOfflineCmd.label "Download/Sync Now…">
+<!ENTITY synchronizeOfflineCmd.accesskey "S">
+<!ENTITY settingsOfflineCmd.label "Offline Settings…">
+<!ENTITY settingsOfflineCmd.accesskey "e">
+<!ENTITY downloadSelectedCmd.label "Get Selected Messages">
+<!ENTITY downloadSelectedCmd.accesskey "l">
+<!ENTITY downloadStarredCmd.label "Get Starred Messages">
+<!ENTITY downloadStarredCmd.accesskey "a">
+<!ENTITY printCmd.label "Print…">
+<!ENTITY printCmd.accesskey "P">
+<!ENTITY printCmd.key "p">
+<!ENTITY printPreviewCmd.label "Print Preview">
+<!ENTITY printPreviewCmd.accesskey "v">
+<!ENTITY printSetupCmd.label "Page Setup…">
+<!ENTITY printSetupCmd.accesskey "u">
+
+<!-- Edit Menu -->
+<!ENTITY deleteMsgCmd.label "Delete Message">
+<!ENTITY deleteMsgCmd.accesskey "D">
+<!ENTITY undeleteMsgCmd.label "Undelete Message">
+<!ENTITY undeleteMsgCmd.accesskey "d">
+<!ENTITY deleteMsgsCmd.label "Delete Selected Messages">
+<!ENTITY deleteMsgsCmd.accesskey "D">
+<!ENTITY undeleteMsgsCmd.label "Undelete Selected Messages">
+<!ENTITY undeleteMsgsCmd.accesskey "d">
+<!ENTITY deleteFolderCmd.label "Delete Folder">
+<!ENTITY deleteFolderCmd.accesskey "D">
+<!ENTITY unsubscribeNewsgroupCmd.label "Unsubscribe">
+<!ENTITY unsubscribeNewsgroupCmd.accesskey "b">
+<!ENTITY selectMenu.label "Select">
+<!ENTITY selectMenu.accesskey "S">
+<!ENTITY all.label "All">
+<!ENTITY all.accesskey "A">
+<!ENTITY selectThreadCmd.label "Thread">
+<!ENTITY selectThreadCmd.accesskey "T">
+<!ENTITY selectThreadCmd.key "a">
+<!ENTITY selectFlaggedCmd.label "Starred Messages">
+<!ENTITY selectFlaggedCmd.accesskey "S">
+<!ENTITY menuFavoriteFolder.label "Favorite Folder">
+<!ENTITY menuFavoriteFolder.accesskey "v">
+<!ENTITY folderPropsCmd.label "Properties…">
+<!ENTITY folderPropsFolderCmd.label "Folder Properties…">
+<!ENTITY folderPropsNewsgroupCmd.label "Newsgroup Properties…">
+<!ENTITY folderPropsCmd.accesskey "o">
+<!ENTITY undoDeleteMsgCmd.label "Undo Delete Message">
+<!ENTITY redoDeleteMsgCmd.label "Redo Delete Message">
+<!ENTITY undoMoveMsgCmd.label "Undo Move Message">
+<!ENTITY redoMoveMsgCmd.label "Redo Move Message">
+<!ENTITY undoCopyMsgCmd.label "Undo Copy Message">
+<!ENTITY redoCopyMsgCmd.label "Redo Copy Message">
+<!ENTITY undoMarkAllCmd.label "Undo Mark All Read">
+<!ENTITY redoMarkAllCmd.label "Redo Mark All Read">
+<!ENTITY undoDefaultCmd.label "Undo">
+<!ENTITY undoDefaultCmd.accesskey "U">
+<!ENTITY redoDefaultCmd.label "Redo">
+<!ENTITY redoDefaultCmd.accesskey "R">
+
+<!-- View Menu -->
+<!ENTITY menubarCmd.label "Menu Bar">
+<!ENTITY menubarCmd.accesskey "M">
+<!ENTITY showMessengerToolbarCmd.label "Mail Toolbar">
+<!ENTITY showMessengerToolbarCmd.accesskey "o">
+<!ENTITY customizeToolbar.label "Customize…">
+<!ENTITY customizeToolbar.accesskey "C">
+
+<!ENTITY messagePaneLayoutStyle.label "Layout">
+<!ENTITY messagePaneLayoutStyle.accesskey "L">
+<!ENTITY messagePaneClassic.label "Classic View">
+<!ENTITY messagePaneClassic.accesskey "C">
+<!ENTITY messagePaneWide.label "Wide View">
+<!ENTITY messagePaneWide.accesskey "W">
+<!ENTITY messagePaneVertical.label "Vertical View">
+<!ENTITY messagePaneVertical.accesskey "V">
+<!ENTITY showFolderPaneCmd.label "Folder Pane">
+<!ENTITY showFolderPaneCmd.accesskey "F">
+<!ENTITY showMessageCmd.label "Message Pane">
+<!ENTITY showMessageCmd.accesskey "M">
+
+<!ENTITY folderView.label "Folders">
+<!ENTITY folderView.accesskey "F">
+<!ENTITY unifiedFolders.label "Unified">
+<!ENTITY unifiedFolders.accesskey "n">
+<!ENTITY allFolders.label "All">
+<!ENTITY allFolders.accesskey "A">
+<!ENTITY unreadFolders.label "Unread">
+<!ENTITY unreadFolders.accesskey "U">
+<!ENTITY favoriteFolders.label "Favorite">
+<!ENTITY favoriteFolders.accesskey "F">
+<!ENTITY recentFolders.label "Recent">
+<!ENTITY recentFolders.accesskey "R">
+
+<!-- Sort Menu -->
+<!ENTITY sortMenu.label "Sort by">
+<!ENTITY sortMenu.accesskey "S">
+<!ENTITY sortByDateCmd.label "Date">
+<!ENTITY sortByDateCmd.accesskey "e">
+<!ENTITY sortByReceivedCmd.label "Received">
+<!ENTITY sortByReceivedCmd.accesskey "v">
+<!ENTITY sortByStarCmd.label "Star">
+<!ENTITY sortByStarCmd.accesskey "S">
+<!ENTITY sortByAttachmentsCmd.label "Attachments">
+<!ENTITY sortByAttachmentsCmd.accesskey "A">
+<!ENTITY sortByPriorityCmd.label "Priority">
+<!ENTITY sortByPriorityCmd.accesskey "P">
+<!ENTITY sortBySizeCmd.label "Size">
+<!ENTITY sortBySizeCmd.accesskey "z">
+<!ENTITY sortByStatusCmd.label "Status">
+<!ENTITY sortByStatusCmd.accesskey "u">
+<!ENTITY sortByTagsCmd.label "Tags">
+<!ENTITY sortByTagsCmd.accesskey "g">
+<!ENTITY sortByJunkStatusCmd.label "Junk Status">
+<!ENTITY sortByJunkStatusCmd.accesskey "J">
+<!ENTITY sortBySubjectCmd.label "Subject">
+<!ENTITY sortBySubjectCmd.accesskey "b">
+<!ENTITY sortByFromCmd.label "From">
+<!ENTITY sortByFromCmd.accesskey "F">
+<!ENTITY sortByRecipientCmd.label "Recipient">
+<!ENTITY sortByRecipientCmd.accesskey "c">
+<!ENTITY sortByUnreadCmd.label "Read">
+<!ENTITY sortByUnreadCmd.accesskey "R">
+<!ENTITY sortByOrderReceivedCmd.label "Order Received">
+<!ENTITY sortByOrderReceivedCmd.accesskey "O">
+<!ENTITY sortAscending.label "Ascending">
+<!ENTITY sortAscending.accesskey "A">
+<!ENTITY sortDescending.label "Descending">
+<!ENTITY sortDescending.accesskey "D">
+<!ENTITY sortThreaded.label "Threaded">
+<!ENTITY sortThreaded.accesskey "T">
+<!ENTITY sortUnthreaded.label "Unthreaded">
+<!ENTITY sortUnthreaded.accesskey "h">
+<!ENTITY groupBySort.label "Grouped By Sort">
+<!ENTITY groupBySort.accesskey "G">
+<!ENTITY msgsMenu.label "Messages">
+<!ENTITY msgsMenu.accesskey "M">
+<!ENTITY threads.label "Threads">
+<!ENTITY threads.accesskey "e">
+<!ENTITY allMsgsCmd.label "All">
+<!ENTITY allMsgsCmd.accesskey "A">
+<!ENTITY expandAllThreadsCmd.label "Expand All Threads">
+<!ENTITY expandAllThreadsCmd.accesskey "E">
+<!ENTITY expandAllThreadsCmd.key "*">
+<!ENTITY collapseAllThreadsCmd.label "Collapse All Threads">
+<!ENTITY collapseAllThreadsCmd.accesskey "C">
+<!ENTITY collapseAllThreadsCmd.key "\">
+<!ENTITY unreadMsgsCmd.label "Unread">
+<!ENTITY unreadMsgsCmd.accesskey "U">
+<!ENTITY threadsWithUnreadCmd.label "Threads with Unread">
+<!ENTITY threadsWithUnreadCmd.accesskey "T">
+<!ENTITY watchedThreadsWithUnreadCmd.label "Watched Threads with Unread">
+<!ENTITY watchedThreadsWithUnreadCmd.accesskey "W">
+<!ENTITY ignoredThreadsCmd.label "Ignored Threads">
+<!ENTITY ignoredThreadsCmd.accesskey "i">
+
+<!ENTITY headersMenu.label "Headers">
+<!ENTITY headersMenu.accesskey "H">
+<!ENTITY headersAllCmd.label "All">
+<!ENTITY headersAllCmd.accesskey "A">
+<!ENTITY headersNormalCmd.label "Normal">
+<!ENTITY headersNormalCmd.accesskey "N">
+<!ENTITY bodyMenu.label "Message Body As">
+<!ENTITY bodyMenu.accesskey "B">
+<!ENTITY bodyAllowHTML.label "Original HTML">
+<!ENTITY bodyAllowHTML.accesskey "H">
+<!ENTITY bodySanitized.label "Simple HTML">
+<!ENTITY bodySanitized.accesskey "S">
+<!ENTITY bodyAsPlaintext.label "Plain Text">
+<!ENTITY bodyAsPlaintext.accesskey "P">
+<!ENTITY bodyAllParts.label "All Body Parts">
+<!ENTITY bodyAllParts.accesskey "A">
+
+<!ENTITY bodyMenuFeed.label "Feed Message Body As">
+<!ENTITY bodyMenuFeed.accesskey "B">
+<!ENTITY viewFeedWebPage.label "Web Page">
+<!ENTITY viewFeedWebPage.accesskey "W">
+<!ENTITY viewFeedSummary.label "Summary">
+<!ENTITY viewFeedSummary.accesskey "m">
+<!ENTITY viewFeedSummaryFeedPropsPref.label "Default Format">
+<!ENTITY viewFeedSummaryFeedPropsPref.accesskey "D">
+
+<!ENTITY viewAttachmentsInlineCmd.label "Display Attachments Inline">
+<!ENTITY viewAttachmentsInlineCmd.accesskey "A">
+
+<!ENTITY pageSourceCmd.label "Message Source">
+<!ENTITY pageSourceCmd.accesskey "o">
+<!ENTITY pageSourceCmd.key "u">
+<!ENTITY getNewMessagesCmd.key "y">
+<!ENTITY getAllNewMessagesCmd.key "Y">
+
+<!-- Search Menu -->
+<!ENTITY findMenu.label "Find">
+<!ENTITY findMenu.accesskey "F">
+<!ENTITY findCmd.label "Find in This Message…">
+<!ENTITY findCmd.accesskey "F">
+<!ENTITY findCmd.key "f">
+<!ENTITY findAgainCmd.label "Find Again">
+<!ENTITY findAgainCmd.accesskey "g">
+<!ENTITY findAgainCmd.key "g">
+<!ENTITY findAgainCmd.key2 "VK_F3">
+<!ENTITY findPrevCmd.key "g">
+<!ENTITY findPrevCmd.key2 "VK_F3">
+<!ENTITY searchMailCmd.label "Search Messages…">
+<!ENTITY searchMailCmd.accesskey "M">
+<!ENTITY searchMailCmd.key "f">
+<!ENTITY searchAddressesCmd.label "Search Addresses…">
+<!ENTITY searchAddressesCmd.accesskey "S">
+
+<!-- Go Menu -->
+<!ENTITY goMenu.label "Go">
+<!ENTITY goMenu.accesskey "G">
+<!ENTITY nextMenu.label "Next">
+<!ENTITY nextMenu.accesskey "N">
+<!ENTITY nextMsgCmd.label "Message">
+<!ENTITY nextMsgCmd.accesskey "M">
+<!ENTITY nextMsgCmd.key "f">
+<!ENTITY nextUnreadMsgCmd.label "Unread Message">
+<!ENTITY nextUnreadMsgCmd.accesskey "U">
+<!ENTITY nextUnreadMsgCmd.key "n">
+<!ENTITY nextStarredMsgCmd.label "Starred Message">
+<!ENTITY nextStarredMsgCmd.accesskey "S">
+<!ENTITY nextUnreadThread.label "Unread Thread">
+<!ENTITY nextUnreadThread.accesskey "T">
+<!ENTITY nextUnreadThread.key "t">
+<!ENTITY prevMenu.label "Previous">
+<!ENTITY prevMenu.accesskey "P">
+<!ENTITY prevMsgCmd.label "Message">
+<!ENTITY prevMsgCmd.accesskey "M">
+<!ENTITY prevMsgCmd.key "b">
+<!ENTITY prevUnreadMsgCmd.label "Unread Message">
+<!ENTITY prevUnreadMsgCmd.accesskey "U">
+<!ENTITY prevUnreadMsgCmd.key "p">
+<!ENTITY goForwardCmd.label "Forward">
+<!ENTITY goForwardCmd.accesskey "F">
+<!ENTITY goForwardCmd.commandKey "]">
+<!ENTITY goBackCmd.label "Back">
+<!ENTITY goBackCmd.accesskey "B">
+<!ENTITY goBackCmd.commandKey "[">
+<!ENTITY goChatCmd.label "Chat">
+<!ENTITY goChatCmd.accesskey "c">
+<!ENTITY goChatCmd.key "I">
+<!ENTITY prevStarredMsgCmd.label "Starred Message">
+<!ENTITY prevStarredMsgCmd.accesskey "S">
+<!ENTITY folderMenu.label "Folder">
+<!ENTITY folderMenu.accesskey "O">
+<!ENTITY thisFolder.label "This Folder">
+<!ENTITY thisFolder.accesskey "F">
+<!ENTITY goRecentlyClosedTabs.label "Recently Closed Tabs">
+<!ENTITY goRecentlyClosedTabs.accesskey "R">
+<!ENTITY startPageCmd.label "Mail Start Page">
+<!ENTITY startPageCmd.accesskey "S">
+
+<!-- Message Menu -->
+<!ENTITY msgMenu.label "Message">
+<!ENTITY msgMenu.accesskey "M">
+<!ENTITY newMsgCmd.label "New Message">
+<!ENTITY newMsgCmd.accesskey "N">
+<!ENTITY newNewMsgCmd.label "Message">
+<!ENTITY newNewMsgCmd.accesskey "M">
+<!ENTITY archiveMsgCmd.label "Archive">
+<!ENTITY archiveMsgCmd.accesskey "A">
+<!ENTITY archiveMsgCmd.key "a">
+<!ENTITY cancelNewsMsgCmd.label "Cancel Message">
+<!ENTITY cancelNewsMsgCmd.accesskey "C">
+<!ENTITY replyMsgCmd.label "Reply">
+<!ENTITY replyMsgCmd.accesskey "R">
+<!ENTITY replyMsgCmd.key "r">
+<!ENTITY replySenderCmd.label "Reply to Sender Only">
+<!ENTITY replySenderCmd.accesskey "R">
+<!ENTITY replyNewsgroupCmd2.label "Followup to Newsgroup">
+<!ENTITY replyNewsgroupCmd2.accesskey "u">
+<!ENTITY replyToAllMsgCmd.label "Reply to All">
+<!ENTITY replyToAllMsgCmd.accesskey "p">
+<!ENTITY replyToAllMsgCmd.key "r">
+<!ENTITY replyToListMsgCmd.label "Reply to List">
+<!ENTITY replyToListMsgCmd.accesskey "L">
+<!ENTITY replyToListMsgCmd.key "l">
+<!ENTITY forwardMsgCmd.label "Forward">
+<!ENTITY forwardMsgCmd.accesskey "F">
+<!ENTITY forwardMsgCmd.key "l">
+<!ENTITY forwardAsMenu.label "Forward As">
+<!ENTITY forwardAsMenu.accesskey "w">
+<!ENTITY forwardAsInline.label "Inline">
+<!ENTITY forwardAsInline.accesskey "I">
+<!ENTITY forwardAsAttachmentCmd.label "Attachment">
+<!ENTITY forwardAsAttachmentCmd.accesskey "A">
+<!ENTITY editMsgAsNewCmd.label "Edit Message As New">
+<!ENTITY editMsgAsNewCmd.accesskey "E">
+<!ENTITY editMsgAsNewCmd.key "e">
+<!ENTITY createFilter.label "Create Filter From Message…">
+<!ENTITY createFilter.accesskey "a">
+<!ENTITY moveMsgToMenu.label "Move To">
+<!ENTITY moveMsgToMenu.accesskey "M">
+<!ENTITY moveCopyMsgRecentMenu.label "Recent">
+<!ENTITY moveCopyMsgRecentMenu.accesskey "R">
+<!ENTITY copyMessageLocation.label "Copy Message Location">
+<!ENTITY copyMessageLocation.accesskey "M">
+<!ENTITY copyMsgToMenu.label "Copy To">
+<!ENTITY copyMsgToMenu.accesskey "C">
+<!ENTITY moveToFolderAgain.label "Move Again">
+<!ENTITY moveToFolderAgain.accesskey "i">
+<!ENTITY moveToFolderAgainCmd.key "m">
+<!ENTITY killThreadMenu.label "Ignore Thread">
+<!ENTITY killThreadMenu.accesskey "I">
+<!ENTITY killThreadMenu.key "k">
+<!ENTITY killSubthreadMenu.label "Ignore Subthread">
+<!ENTITY killSubthreadMenu.accesskey "S">
+<!ENTITY killSubthreadMenu.key "k">
+<!ENTITY watchThreadMenu.label "Watch Thread">
+<!ENTITY watchThreadMenu.accesskey "W">
+<!ENTITY watchThreadMenu.key "w">
+<!ENTITY fileHereMenu.label "File Here">
+<!ENTITY fileHereMenu.accesskey "F">
+<!ENTITY copyHereMenu.label "Copy Here">
+<!ENTITY copyHereMenu.accesskey "C">
+<!ENTITY tagMenu.label "Tag">
+<!ENTITY tagMenu.accesskey "g">
+<!ENTITY tagCmd0.key "0">
+<!ENTITY tagCmd1.key "1">
+<!ENTITY tagCmd2.key "2">
+<!ENTITY tagCmd3.key "3">
+<!ENTITY tagCmd4.key "4">
+<!ENTITY tagCmd5.key "5">
+<!ENTITY tagCmd6.key "6">
+<!ENTITY tagCmd7.key "7">
+<!ENTITY tagCmd8.key "8">
+<!ENTITY tagCmd9.key "9">
+<!ENTITY markMenu.label "Mark">
+<!ENTITY markMenu.accesskey "k">
+<!ENTITY toggleReadCmd.key "m">
+<!ENTITY markAsReadCmd.label "As Read">
+<!ENTITY markAsReadCmd.accesskey "R">
+<!ENTITY markAsUnreadCmd.label "As Unread">
+<!ENTITY markAsUnreadCmd.accesskey "U">
+<!ENTITY markThreadAsReadCmd.label "Thread As Read">
+<!ENTITY markThreadAsReadCmd.accesskey "T">
+<!ENTITY markThreadAsReadCmd.key "r">
+<!ENTITY markReadByDateCmd.label "As Read by Date…">
+<!ENTITY markReadByDateCmd.accesskey "D">
+<!ENTITY markReadByDateCmd.key "c">
+<!ENTITY markAllReadCmd.label "All Read">
+<!ENTITY markAllReadCmd.accesskey "A">
+<!ENTITY markAllReadCmd.key "c">
+<!ENTITY markStarredCmd.label "Add Star">
+<!ENTITY markStarredCmd.accesskey "S">
+<!ENTITY markStarredCmd.key "S">
+<!ENTITY markAsJunkCmd.label "As Junk">
+<!ENTITY markAsJunkCmd.accesskey "J">
+<!ENTITY markAsJunkCmd.key "j">
+<!ENTITY markAsNotJunkCmd.label "As Not Junk">
+<!ENTITY markAsNotJunkCmd.accesskey "N">
+<!ENTITY markAsNotJunkCmd.key "j">
+<!ENTITY recalculateJunkScoreCmd.label "Run Junk Mail Controls">
+<!ENTITY recalculateJunkScoreCmd.accesskey "C">
+<!ENTITY openMessageWindowCmd.label "Open Message">
+<!ENTITY openMessageWindowCmd.accesskey "O">
+<!ENTITY openMessageWindowCmd.key "o">
+<!ENTITY openConversationCmd.label "Open in Conversation">
+<!ENTITY openConversationCmd.accesskey "s">
+<!ENTITY openConversationCmd.key "o">
+<!ENTITY openAttachmentListCmd.label "Attachments">
+<!ENTITY openAttachmentListCmd.accesskey "h">
+<!ENTITY openFeedMessage1.label "When Opening Feed Messages">
+<!ENTITY openFeedMessage1.accesskey "O">
+<!ENTITY openFeedWebPage.label "Open as Web Page">
+<!ENTITY openFeedWebPage.accesskey "W">
+<!ENTITY openFeedSummary.label "Open as Summary">
+<!ENTITY openFeedSummary.accesskey "S">
+<!ENTITY openFeedWebPageInMP.label "Toggle Web Page and Summary in Message Pane">
+<!ENTITY openFeedWebPageInMP.accesskey "T">
+
+<!-- Windows Menu -->
+<!ENTITY windowMenu.label "Window">
+
+<!-- Tools Menu -->
+<!ENTITY tasksMenu.label "Tools">
+<!ENTITY tasksMenu.accesskey "T">
+<!ENTITY messengerCmd.label "Mail & Newsgroups">
+<!ENTITY messengerCmd.accesskey "N">
+<!ENTITY addressBookCmd.label "Address Book">
+<!ENTITY addressBookCmd.accesskey "B">
+<!ENTITY addressBookCmd.key "B">
+<!ENTITY addons.label "Add-ons">
+<!ENTITY addons.accesskey "A">
+<!ENTITY activitymanager.label "Activity Manager">
+<!ENTITY activitymanager.accesskey "v">
+<!ENTITY imAccountsStatus.label "Chat status">
+<!ENTITY imAccountsStatus.accesskey "C">
+<!ENTITY imStatus.available "Available">
+<!ENTITY imStatus.unavailable "Unavailable">
+<!ENTITY imStatus.offline "Offline">
+<!ENTITY imStatus.showAccounts "Show Accounts…">
+<!ENTITY joinChatCmd.label "Join Chat…">
+<!ENTITY joinChatCmd.accesskey "t">
+<!ENTITY savedFiles.label "Saved Files">
+<!ENTITY savedFiles.accesskey "l">
+<!ENTITY savedFiles.key "j">
+<!ENTITY filtersCmd.label "Message Filters…">
+<!ENTITY filtersCmd.accesskey "F">
+<!ENTITY filtersApply.label "Run Filters on Folder">
+<!ENTITY filtersApply.accesskey "R">
+<!ENTITY filtersApplyToSelection.label "Run Filters on Selected Messages">
+<!ENTITY filtersApplyToSelection.accesskey "u">
+<!ENTITY filtersApplyToMessage.label "Run Filters on Message">
+<!ENTITY filtersApplyToMessage.accesskey "u">
+<!ENTITY runJunkControls.label "Run Junk Mail Controls on Folder">
+<!ENTITY runJunkControls.accesskey "C">
+<!ENTITY deleteJunk.label "Delete Mail Marked as Junk in Folder">
+<!ENTITY deleteJunk.accesskey "D">
+<!ENTITY importCmd.label "Import…">
+<!ENTITY importCmd.accesskey "m">
+<!ENTITY errorConsoleCmd.label "Error Console">
+<!ENTITY errorConsoleCmd.accesskey "E">
+<!ENTITY errorConsoleCmd.commandkey "j">
+<!ENTITY clearRecentHistory.label "Clear Recent History…">
+<!ENTITY clearRecentHistory.accesskey "H">
+<!ENTITY accountManagerCmd.label "Account Settings…">
+<!ENTITY accountManagerCmd.accesskey "S">
+<!-- LOCALIZATION NOTE (accountManagerCmdUnix.accesskey): belongs to accountManagerCmd.label,
+ which is placed under the Edit menu on Unix systems -->
+<!ENTITY accountManagerCmdUnix.accesskey "A">
+<!ENTITY allowRemoteDebugging.label "Allow Remote Debugging">
+<!ENTITY allowRemoteDebugging.accesskey "g">
+
+<!-- Mail Toolbar -->
+<!ENTITY getMsgButton.label "Get Mail">
+<!ENTITY newMsgButton.label "Write">
+<!ENTITY replyButton.label "Reply">
+<!ENTITY replyAllButton.label "Reply All">
+<!ENTITY replyListButton.label "Reply to List">
+<!ENTITY forwardButton.label "Forward">
+<!ENTITY fileButton.label "File">
+<!ENTITY archiveButton.label "Archive">
+<!ENTITY nextButton.label "Next">
+<!ENTITY nextButtonToolbarItem.label "Next Unread">
+<!ENTITY nextMsgButton.label "Next">
+<!ENTITY previousButton.label "Previous">
+<!ENTITY previousButtonToolbarItem.label "Previous Unread">
+<!ENTITY previousMsgButton.label "Previous">
+<!ENTITY backButton1.label "Back">
+<!ENTITY goForwardButton1.label "Forward">
+<!ENTITY deleteItem.title "Delete">
+<!ENTITY deleteButton.label "Delete">
+<!ENTITY undeleteButton.label "Undelete">
+<!ENTITY markButton.label "Mark">
+<!ENTITY printButton.label "Print">
+<!ENTITY stopButton.label "Stop">
+<!ENTITY throbberItem.title "Activity Indicator">
+<!ENTITY junkItem.title "Junk">
+<!ENTITY junkButton.label "Junk">
+<!ENTITY notJunkButton.label "Not Junk">
+<!ENTITY addressBookButton.label "Address Book">
+<!ENTITY chatButton.label "Chat">
+<!ENTITY glodaSearch.title "Global Search">
+<!ENTITY searchItem.title "Quick Search">
+<!ENTITY mailViewsToolbarItem.title "Mail Views">
+<!ENTITY folderLocationToolbarItem.title "Folder Location">
+<!ENTITY tagButton.label "Tag">
+<!ENTITY compactButton.label "Compact">
+<!ENTITY appmenuButton.label "AppMenu">
+
+<!-- Mail Toolbar Tooltips-->
+<!ENTITY advancedButton.tooltip "Advanced message search">
+<!ENTITY getMsgButton.tooltip "Get new messages">
+<!ENTITY getAllNewMsgCmd.label "Get All New Messages">
+<!ENTITY getAllNewMsgCmd.accesskey "G">
+<!ENTITY newMsgButton.tooltip "Create a new message">
+<!ENTITY replyButton.tooltip "Reply to the message">
+<!ENTITY replyAllButton.tooltip "Reply to sender and all recipients">
+<!ENTITY replyListButton.tooltip "Reply to mailing list">
+<!ENTITY forwardButton.tooltip "Forward selected message">
+<!ENTITY forwardAsInline.tooltip "Forward selected message as inline text">
+<!ENTITY forwardAsAttachment.tooltip "Forward selected message as an attachment">
+<!ENTITY fileButton.tooltip "File selected message">
+<!ENTITY archiveButton.tooltip "Archive selected messages">
+<!ENTITY nextButton.tooltip "Move to the next unread message">
+<!ENTITY nextMsgButton.tooltip "Move to the next message">
+<!ENTITY previousButton.tooltip "Move to the previous unread message">
+<!ENTITY previousMsgButton.tooltip "Move to the previous message">
+<!ENTITY goForwardButton.tooltip "Go forward one message">
+<!ENTITY goBackButton.tooltip "Go back one message">
+<!ENTITY deleteButton.tooltip "Delete selected message or folder">
+<!ENTITY undeleteButton.tooltip "Undelete selected message">
+<!ENTITY markButton.tooltip "Mark messages">
+<!ENTITY printButton.tooltip "Print this message">
+<!ENTITY stopButton.tooltip "Stop the current transfer">
+<!ENTITY junkButton.tooltip "Mark the selected messages as junk">
+<!ENTITY notJunkButton.tooltip "Mark the selected messages as not junk">
+<!ENTITY addressBookButton.tooltip "Go to the address book">
+<!ENTITY chatButton.tooltip "Show the Chat tab">
+<!ENTITY tagButton.tooltip "Tag messages">
+<!ENTITY compactButton.tooltip "Remove deleted messages from selected folder">
+<!ENTITY appmenuButton1.tooltip "Display the &brandShortName; Menu">
+
+<!-- Toolbar Button Popup -->
+<!ENTITY buttonMenuForwardAsInline.label "Forward Inline">
+<!ENTITY buttonMenuForwardAsAttachment.label "Forward As Attachment">
+
+<!-- AppMenu Popup -->
+<!ENTITY appmenuNewMsgCmd.label "New Message">
+<!ENTITY appmenuNewContactCmd.label "Address Book Contact…">
+<!ENTITY appmenuEditMenu.label "Edit">
+<!ENTITY appmenuQFBMenu.label "Quick Filter Bar">
+<!ENTITY appmenuToolbarLayout.label "Toolbar Layout…">
+<!ENTITY appmenuSelectThread.label "Select Thread">
+<!ENTITY appmenuSelectFlagged.label "Select Starred Messages">
+
+<!-- Tags Menu Popup -->
+<!ENTITY addNewTag.label "New Tag…">
+<!ENTITY addNewTag.accesskey "N">
+<!ENTITY manageTags.label "Manage Tags…">
+<!ENTITY manageTags.accesskey "M">
+
+<!-- Folder Pane -->
+<!ENTITY folderColumn.label "Name">
+<!ENTITY folderSizeColumn.label "Size">
+
+<!-- Folder Pane Context Menu -->
+<!ENTITY folderContextGetMessages.label "Get Messages">
+<!ENTITY folderContextGetMessages.accesskey "G">
+<!ENTITY folderContextOpenInNewWindow.label "Open in New Window">
+<!ENTITY folderContextOpenInNewWindow.accesskey "O">
+<!ENTITY folderContextOpenNewTab.label "Open in New Tab">
+<!ENTITY folderContextOpenNewTab.accesskey "T">
+<!ENTITY folderContextNew.label "New Subfolder…">
+<!ENTITY folderContextNew.accesskey "N">
+<!ENTITY folderContextRename.label "Rename">
+<!ENTITY folderContextRename.accesskey "R">
+<!ENTITY folderContextRemove.label "Delete">
+<!ENTITY folderContextRemove.accesskey "D">
+<!ENTITY folderContextCompact.label "Compact">
+<!ENTITY folderContextCompact.accesskey "C">
+<!ENTITY folderContextEmptyTrash.label "Empty Trash">
+<!ENTITY folderContextEmptyTrash.accesskey "y">
+<!ENTITY folderContextEmptyJunk.label "Empty Junk">
+<!ENTITY folderContextEmptyJunk.accesskey "J">
+<!ENTITY folderContextSendUnsentMessages.label "Send Unsent Messages">
+<!ENTITY folderContextSendUnsentMessages.accesskey "d">
+<!ENTITY folderContextUnsubscribe.label "Unsubscribe">
+<!ENTITY folderContextUnsubscribe.accesskey "U">
+<!ENTITY folderContextMarkNewsgroupRead.label "Mark Newsgroup Read">
+<!ENTITY folderContextMarkNewsgroupRead.accesskey "k">
+<!ENTITY folderContextMarkMailFolderRead.label "Mark Folder Read">
+<!ENTITY folderContextMarkMailFolderRead.accesskey "k">
+<!ENTITY folderContextSubscribe.label "Subscribe…">
+<!ENTITY folderContextSubscribe.accesskey "b">
+<!ENTITY folderContextSearchForMessages.label "Search Messages…">
+<!ENTITY folderContextSearchForMessages.accesskey "S">
+<!ENTITY folderContextProperties.label "Properties…">
+<!ENTITY folderContextProperties.accesskey "P">
+<!ENTITY folderContextFavoriteFolder.label "Favorite Folder">
+<!ENTITY folderContextFavoriteFolder.accesskey "a">
+<!ENTITY folderContextSettings.label "Settings…">
+<!ENTITY folderContextSettings.accesskey "e">
+
+<!-- Search Bar -->
+<!ENTITY SearchNameOrEmail.label "Name or Email contains:">
+<!ENTITY SearchNameOrEmail.accesskey "N">
+
+<!-- Gloda Search Bar -->
+<!ENTITY glodaSearchBar.placeholder "Search messages…">
+
+<!-- Quick Search Menu Bar -->
+<!ENTITY searchSubjectMenu.label "Subject">
+<!ENTITY searchFromMenu.label "From">
+<!ENTITY searchSubjectOrFromMenu.label "Subject or From">
+<!ENTITY searchRecipient.label "To or Cc">
+<!ENTITY searchSubjectOrRecipientMenu.label "Subject, To or Cc">
+<!ENTITY searchMessageBody.label "Entire Message">
+<!ENTITY saveAsVirtualFolderMenu.label "Save Search as a Folder…">
+
+<!-- Thread Pane -->
+<!ENTITY threadColumn.label "Thread">
+<!ENTITY fromColumn.label "From">
+<!ENTITY recipientColumn.label "Recipient">
+<!ENTITY subjectColumn.label "Subject">
+<!ENTITY dateColumn.label "Date">
+<!ENTITY priorityColumn.label "Priority">
+<!ENTITY tagsColumn.label "Tag">
+<!ENTITY accountColumn.label "Account">
+<!ENTITY statusColumn.label "Status">
+<!ENTITY sizeColumn.label "Size">
+<!ENTITY junkStatusColumn.label "Junk Status">
+<!ENTITY unreadColumn.label "Unread">
+<!ENTITY totalColumn.label "Total">
+<!ENTITY readColumn.label "Read">
+<!ENTITY receivedColumn.label "Received">
+<!ENTITY starredColumn.label "Starred">
+<!ENTITY locationColumn.label "Location">
+<!ENTITY idColumn.label "Order Received">
+<!ENTITY attachmentColumn.label "Attachments">
+
+<!-- Thread Pane Tooltips -->
+<!ENTITY columnChooser.tooltip "Click to select columns to display">
+<!ENTITY threadColumn.tooltip "Click to display message threads">
+<!ENTITY fromColumn.tooltip "Click to sort by from">
+<!ENTITY recipientColumn.tooltip "Click to sort by recipient">
+<!ENTITY subjectColumn.tooltip "Click to sort by subject">
+<!ENTITY dateColumn.tooltip "Click to sort by date">
+<!ENTITY priorityColumn.tooltip "Click to sort by priority">
+<!ENTITY tagsColumn.tooltip "Click to sort by tags">
+<!ENTITY accountColumn.tooltip "Click to sort by account">
+<!ENTITY statusColumn.tooltip "Click to sort by status">
+<!ENTITY sizeColumn.tooltip "Click to sort by size">
+<!ENTITY junkStatusColumn.tooltip "Click to sort by junk status">
+<!ENTITY unreadColumn.tooltip "Number of unread messages in thread">
+<!ENTITY totalColumn.tooltip "Total number of messages in thread">
+<!ENTITY readColumn.tooltip "Click to sort by read">
+<!ENTITY receivedColumn.tooltip "Click to sort by date received">
+<!ENTITY starredColumn.tooltip "Click to sort by star">
+<!ENTITY locationColumn.tooltip "Click to sort by location">
+<!ENTITY idColumn.tooltip "Click to sort by order received">
+<!ENTITY attachmentColumn.tooltip "Click to sort by attachments">
+
+<!-- Thread Pane Context Menu -->
+<!ENTITY contextOpenNewWindow.label "Open Message in New Window">
+<!ENTITY contextOpenNewWindow.accesskey "W">
+<!-- The key potentially conflicts with cutCmd.accessKey which is defined in
+ textcontext.dtd from toolkit. Right now, both menu items can't be visible
+ at the same time, but should someone enable copy/paste of message, this key
+ would probably need to be changed. -->
+<!ENTITY contextOpenNewTab.label "Open Message in New Tab">
+<!ENTITY contextOpenNewTab.accesskey "T">
+<!ENTITY contextOpenConversation.label "Open Message in Conversation">
+<!ENTITY contextOpenConversation.accesskey "n">
+<!ENTITY contextEditAsNew.label "Edit As New…">
+<!ENTITY contextEditAsNew.accesskey "E">
+<!ENTITY contextArchive.label "Archive">
+<!ENTITY contextArchive.accesskey "h">
+<!ENTITY contextReplySender.label "Reply to Sender Only">
+<!ENTITY contextReplySender.accesskey "R">
+<!ENTITY contextReplyNewsgroup2.label "Followup to Newsgroup">
+<!ENTITY contextReplyNewsgroup2.accesskey "u">
+<!ENTITY contextReplyAll.label "Reply to All">
+<!ENTITY contextReplyAll.accesskey "A">
+<!ENTITY contextReplyList.label "Reply to List">
+<!ENTITY contextReplyList.accesskey "L">
+<!ENTITY contextForward.label "Forward">
+<!ENTITY contextForward.accesskey "F">
+<!ENTITY contextForwardAsMenu.label "Forward As">
+<!ENTITY contextForwardAsMenu.accesskey "o">
+<!ENTITY contextForwardAsInline.label "Inline">
+<!ENTITY contextForwardAsInline.accesskey "I">
+<!ENTITY contextForwardAsAttachmentItem.label "Attachment">
+<!ENTITY contextForwardAsAttachmentItem.accesskey "A">
+<!ENTITY contextMultiForwardAsAttachment.label "Forward as Attachments">
+<!ENTITY contextMultiForwardAsAttachment.accesskey "o">
+<!ENTITY contextMoveMsgMenu.label "Move To">
+<!ENTITY contextMoveMsgMenu.accesskey "M">
+<!ENTITY contextMoveCopyMsgRecentMenu.label "Recent">
+<!ENTITY contextMoveCopyMsgRecentMenu.accesskey "R">
+<!ENTITY contextCopyMsgMenu.label "Copy To">
+<!ENTITY contextCopyMsgMenu.accesskey "C">
+<!ENTITY contextKillThreadMenu.label "Ignore Thread">
+<!ENTITY contextKillThreadMenu.accesskey "I">
+<!ENTITY contextKillSubthreadMenu.label "Ignore Subthread">
+<!ENTITY contextWatchThreadMenu.label "Watch Thread">
+<!ENTITY contextSaveAs.label "Save As…">
+<!ENTITY contextSaveAs.accesskey "S">
+<!ENTITY contextPrint.label "Print…">
+<!ENTITY contextPrint.accesskey "P">
+<!ENTITY contextPrintPreview.label "Print Preview">
+<!ENTITY contextPrintPreview.accesskey "v">
+
+<!-- Thread Pane Column Picker -->
+<!-- LOCALIZATION NOTE (columnPicker.resetToInbox.label):
+ This option in the thread pane column picker causes us to reset the
+ customizations for the thread pane columns in this folder to their default.
+ -->
+<!ENTITY columnPicker.resetToInbox.label "Reset columns to default">
+<!-- LOCALIZATION NOTE (columnPicker.applyTo.label):
+ This option in the thread pane column picker pops up a sub-menu containing
+ the "columnPicker.applyToFolder.label" and
+ "columnPicker.applyToFolderAndChildren.label" options. This item indicates
+ a desire to apply the currently displayed set of columns to some other
+ folder(s). The sub-menu items indicate whether we want to apply it to just
+ a folder or also its children.
+ -->
+<!ENTITY columnPicker.applyTo.label "Apply columns to…">
+<!-- LOCALIZATION NOTE (columnPicker.applyToFolder.label):
+ This option in the thread pane column picker is found on a sub-menu beneath
+ the "columnPicker.applyTo.label" alongside
+ "columnPicker.applyToFolderAndChildren.label". It indicates a desire to
+ apply the currently display thread pane column settings to a single folder
+ that the user selects using the same widget as the move to/copy to
+ mechanism (via a series of popups).
+ -->
+<!ENTITY columnPicker.applyToFolder.label "Folder…">
+<!-- LOCALIZATION NOTE (columnPicker.applyToFolderAndChildren.label):
+ This option in the thread pane column picker is found on a sub-menu beneath
+ the "columnPicker.applyTo.label" alongside
+ "columnPicker.applyToFolder.label". It indicates a desire to
+ apply the currently display thread pane column settings to a folder and all
+ of its descendents. The user selects the folder using the same widget as the
+ move to/copy to mechanism (via a series of popups).
+ -->
+<!ENTITY columnPicker.applyToFolderAndChildren.label "Folder and its children…">
+<!-- LOCALIZATION NOTE (columnPicker.thisFolder.label):
+ This is used in the folder selection widget for the
+ "columnPicker.applyToFolder.label" and
+ "columnPicker.applyToFolderAndChildren.label" menu options. Whenever
+ a folder has children, it results in a menu popup; the first menu item
+ in that popup is given this label to indicate that that folder should be
+ selected. For example, if folder "A" has two children, "B" and "C", then
+ when the user hovers over "A", a new popup menu will be displayed whose
+ items are "This folder", "B", and "C". This is the equivalent of the
+ "File here" option for the move to/copy to widge.t
+ -->
+<!ENTITY columnPicker.thisFolder.label "This folder">
+
+
+<!-- Media (video/audio) controls -->
+<!ENTITY contextPlay.label "Play">
+<!ENTITY contextPlay.accesskey "P">
+<!ENTITY contextPause.label "Pause">
+<!ENTITY contextPause.accesskey "P">
+<!ENTITY contextMute.label "Mute">
+<!ENTITY contextMute.accesskey "M">
+<!ENTITY contextUnmute.label "Unmute">
+<!ENTITY contextUnmute.accesskey "m">
+
+<!-- Junk Bar -->
+<!ENTITY junkBarMessage2.label "&brandShortName; thinks this message is junk mail.">
+<!ENTITY junkBarButton1.label "Not Junk">
+<!ENTITY junkInfoButton.label "?">
+
+<!-- Remote Content Bar -->
+<!ENTITY remoteContentMessage2.label "To protect your privacy, &brandShortName; has blocked remote content in this message.">
+<!ENTITY loadRemoteContentButton3.label "Show Remote Content">
+
+<!-- Phishing Bar -->
+<!ENTITY phishingBarMessage2.label "This message may be a scam.">
+<!ENTITY removePhishingBarButton1.label "Ignore Warning">
+<!ENTITY disablePhishingWarning1.label "Disable scam detection for all messages">
+<!ENTITY reportPhishingError1.label "This message doesn't appear to be a scam.">
+
+<!-- MDN Bar -->
+<!ENTITY mdnBarIgnoreButton2.label "Ignore">
+<!ENTITY mdnBarIgnoreButton2.accesskey "I">
+<!ENTITY mdnBarSendButton2.label "Send Return Receipt">
+<!ENTITY mdnBarSendButton2.accesskey "S">
+
+<!-- S/MIME Receipt Request Bar -->
+<!ENTITY SMIMEReceiptRequestBarMessage.label "The sender of this message has asked to be notified by a signed receipt when you read this message. Do you wish to notify the sender?">
+<!ENTITY SMIMEReceiptRequestBarIgnoreButton.label "Ignore Request">
+<!ENTITY SMIMEReceiptRequestBarSendButton.label "Send Receipt">
+
+<!-- S/MIME Receipt Bar -->
+<!ENTITY SMIMEReceiptVerifiedBarMessage.label "This message is a valid signed receipt verified with the message you sent.">
+<!ENTITY SMIMEReceiptBarOpenMessageButton.label "View sent message">
+<!ENTITY SMIMEReceiptNotVerifiedBarMessage.label "This message is a valid signed receipt but it has NOT been verified with the message you sent because it can't be located or has not been read.">
+
+<!-- Quick Search Bar -->
+<!-- LOCALIZATION NOTE (quickSearchCmd.key):
+ This is actually the key used for the global message search box; we have
+ not changed
+ -->
+<!ENTITY quickSearchCmd.key "k">
+<!-- LOCALIZATION NOTE (search.label.base):
+ This is the base of the empty text for the global search box. We replace
+ #1 with the contents of the appropriate search.keyLabel.* value for the
+ platform.
+ The goal is to convey to the user that typing in the box will allow them
+ to search for messages globally and that there is a hotkey they can press
+ to get to the box faster. If the global indexer is disabled, the search
+ box will be collapsed and the user will never see this message.
+ -->
+<!ENTITY search.label.base "Search… #1">
+<!-- LOCALIZATION NOTE (search.keyLabel.nonmac):
+ The description of the key-binding to get into the global search box on
+ windows and linux (which use the control key). We use the key defined in
+ the quickSearchCmd.key entity defined above, the letter should match it.
+ -->
+<!ENTITY search.keyLabel.nonmac "<Ctrl+K>">
+<!-- LOCALIZATION NOTE (search.keyLabel.mac):
+ The description of the key-binding to get into the global search box on mac
+ systems. We use the key defined in the quickSearchCmd.key entity defined
+ above, the letter should match it.
+ -->
+<!ENTITY search.keyLabel.mac "<⌘K>">
+
+<!-- Message Header Context Menu -->
+<!ENTITY AddToAddressBook.label "Add to Address Book…">
+<!ENTITY AddToAddressBook.accesskey "B">
+<!ENTITY AddDirectlyToAddressBook.label "Add to Address Book">
+<!ENTITY AddDirectlyToAddressBook.accesskey "B">
+<!ENTITY EditContact.label "Edit Contact…">
+<!ENTITY EditContact.accesskey "E">
+<!ENTITY ViewContact.label "View Contact">
+<!ENTITY ViewContact.accesskey "V">
+<!ENTITY SubscribeToNewsgroup.label "Subscribe to Newsgroup">
+<!ENTITY SubscribeToNewsgroup.accesskey "N">
+<!ENTITY SendMessageTo.label "Compose Message To">
+<!ENTITY SendMessageTo.accesskey "s">
+<!ENTITY CopyEmailAddress.label "Copy Email Address">
+<!ENTITY CopyEmailAddress.accesskey "C">
+<!ENTITY CopyNewsgroupName.label "Copy Newsgroup Name">
+<!ENTITY CopyNewsgroupName.accesskey "C">
+<!ENTITY CopyNewsgroupURL.label "Copy Newsgroup URL">
+<!ENTITY CopyNewsgroupURL.accesskey "U">
+<!ENTITY CreateFilterFrom.label "Create Filter From…">
+<!ENTITY CreateFilterFrom.accesskey "F">
+<!ENTITY reportPhishingURL.label "Report Email Scam">
+<!ENTITY reportPhishingURL.accesskey "o">
+
+<!-- Spell checker context menu items -->
+<!ENTITY spellAddDictionaries.label "Add Dictionaries…">
+<!ENTITY spellAddDictionaries.accesskey "A">
+
+<!-- Content Pane Context Menu -->
+<!ENTITY saveLinkAsCmd.label "Save Link As…">
+<!ENTITY saveLinkAsCmd.accesskey "k">
+<!ENTITY saveImageAsCmd.label "Save Image As…">
+<!ENTITY saveImageAsCmd.accesskey "v">
+<!ENTITY copyLinkCmd.label "Copy Link Location">
+<!ENTITY copyLinkCmd.accesskey "L">
+<!ENTITY copyImageAllCmd.label "Copy Image">
+<!ENTITY copyImageAllCmd.accesskey "I">
+<!ENTITY copyEmailCmd.label "Copy Email Address">
+<!ENTITY copyEmailCmd.accesskey "E">
+<!ENTITY stopCmd.label "Stop">
+<!ENTITY stopCmd.accesskey "S">
+<!ENTITY reloadCmd.label "Reload">
+<!ENTITY reloadCmd.accesskey "R">
+<!ENTITY openInBrowser.label "Open In Browser">
+<!ENTITY openInBrowser.accesskey "O">
+<!ENTITY openLinkInBrowser.label "Open Link In Browser">
+<!ENTITY openLinkInBrowser.accesskey "O">
+
+<!-- Statusbar -->
+<!ENTITY statusText.label "Done">
+
+<!-- Mac OS X Window Menu -->
+<!ENTITY minimizeWindow.label "Minimize">
+<!ENTITY minimizeWindow.key "m">
+<!ENTITY bringAllToFront.label "Bring All to Front">
+<!ENTITY zoomWindow.label "Zoom">
+
+<!-- Mac OS X Application Menu (Cocoa widgets) -->
+<!ENTITY preferencesCmdMac.label "Preferences…">
+<!ENTITY preferencesCmdMac.commandkey ",">
+<!ENTITY preferencesCmdMac.modifiers "accel">
+<!ENTITY servicesMenuMac.label "Services">
+<!ENTITY hideThisAppCmdMac.label "Hide &brandShortName;">
+<!ENTITY hideThisAppCmdMac.commandkey "H">
+<!ENTITY hideThisAppCmdMac.modifiers "accel">
+<!ENTITY hideOtherAppsCmdMac.label "Hide Others">
+<!ENTITY hideOtherAppsCmdMac.commandkey "H">
+<!ENTITY hideOtherAppsCmdMac.modifiers "accel,alt">
+<!ENTITY showAllAppsCmdMac.label "Show All">
--- /dev/null
+<!--LOCALIZATION NOTE msgReadSecurityInfo.dtd UI for viewing security status when reading a received message -->\r
+<!ENTITY secureHeaders.name "Secure Headers">\r
+<!ENTITY secureHeaders.field "Secure Headers :">\r
+<!ENTITY secureHeadersView.label "View Secure Headers">\r
+<!ENTITY secureHeadersList.label "Secure Headers List">\r
+<!ENTITY headername.label "Header">\r
+<!ENTITY headervalue.label "Signed value">\r
+<!ENTITY headerstatus.label "Status">\r
+<!ENTITY headerencrypted.label "Encrypted">\r
+<!ENTITY headermimevalue.label "Displayed value">\r
+<!ENTITY headercanonisation.label "Canonicalization">
\ No newline at end of file
--- /dev/null
+menu.secureheaders.label=Secure headers\r
+secureInfo.secureheaders.label=Secure Headers\r
+secureheaders.label=Secure Headers :\r
+yes.label=Yes\r
+no.label=No\r
+notdefine.label=Not Defined\r
+headerstatus.deleted.label=Deleted\r
+headerstatus.duplicated.label=Duplicated\r
+headerstatus.modified.label=Modified\r
+headersecure.valid.label=Valid header\r
+headersecure.invalid.label=Modified header\r
+allsecureheaders.valid.label= All secure headers are valid\r
+allsecureheaders.invalid.label=Secures headers were modified\r
+headercanoniz.simple.label=Simple\r
+headercanoniz.relaxed.label=Relaxed
\ No newline at end of file
--- /dev/null
+# securityLabel.js\r
+unknownSecurityPolicyIdentifier=unknown\r
+unknownSecurityClassification=unknown\r
+unknownSecurityCategory=unknown\r
+\r
+# securityLabelDialog.js\r
+noSecurityPolicyIdentifier=none\r
+noSecurityClassification=none\r
--- /dev/null
+<!--LOCALIZATION NOTE securityLabelTreeColOverlay.dtd UI -->\r
+<!ENTITY securityLabelSecurityClassificationColumn.label "Classification de sécurité">\r
+<!ENTITY securityLabelSecurityClassificationColumn.tooltip "trier par étiquettes de sécurité">\r
--- /dev/null
+<!ENTITY pane.title "Entêtes Sécurisés">\r
+<!ENTITY secureHeaderFolderPicker.label "Fichier des entêtes sécurisés">\r
+<!ENTITY secureHeaderPath.label "Fichier des entêtes sécurisés">\r
+<!ENTITY browseFolder.label "Parcourir...">\r
+<!ENTITY browseFolder.accesskey "P">\r
+<!ENTITY useSecureHeaders.label "Activer les entêtes sécurises pour ce compte">\r
+<!ENTITY secureHeadersDescription.label "Définition des entêtes sécurisés">\r
+<!ENTITY secureHeadersDatas.label "Entêtes sécurisés">\r
--- /dev/null
+# ***** BEGIN LICENSE BLOCK *****\r
+# Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
+# ximfmail is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
+# \r
+#\r
+# Redistribution and use, in source and binary forms, with or without modification, \r
+# are permitted provided that the following conditons are met :\r
+#\r
+# 1. Redistributions of source code must retain the above copyright notice, \r
+# 2. MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached \r
+# in the redistribution of the source code.\r
+# 3. Neither the names of the copyright holders nor the names of any contributors \r
+# may be used to endorse or promote products derived from this software without specific \r
+# prior written permission from EADS Defence and Security.\r
+# \r
+# Alternatively, the contents of this file may be used under the terms of\r
+# either of the GNU General Public License Version 2 or later (the "GPL"),\r
+# or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
+# in which case the provisions of the GPL or the LGPL are applicable instead\r
+# of those above. If you wish to allow use of your version of this file only\r
+# under the terms of either the GPL or the LGPL, and not to allow others to\r
+# use your version of this file under the terms of the MPL, indicate your\r
+# decision by deleting the provisions above and replace them with the notice\r
+# and other provisions required by the GPL or the LGPL. If you do not delete\r
+# the provisions above, a recipient may use your version of this file under\r
+# the terms of any one of the MPL, the GPL or the LGPL.\r
+# \r
+# REMINDER :\r
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND \r
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED \r
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. \r
+# IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, \r
+# INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES \r
+# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; \r
+# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, \r
+# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING \r
+# IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+# \r
+# EADS Defence and Security - 1 Boulevard Jean Moulin - \r
+# ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000) \r
+# ***** END LICENSE BLOCK *****\r
+# Strings used in the Mozill AccountManager\r
+prefPanel-secureheaders=Ent\u00EAtes S\u00E9curis\u00E9s\r
+\r
--- /dev/null
+<!ENTITY pane.title "Eiquettes de sécurité">\r
+<!ENTITY securityLabel.location "Emplacement des labeles dans l'enveloppe tripme">\r
+<!ENTITY securityLabel.bothSignatures "Signature interne et externe">\r
+<!ENTITY securityLabel.innerSignatureOnly "Signature interne uniquement">\r
+<!ENTITY securityLabel.outerSignatureOnly "Signature externe uniquement"
\ No newline at end of file
--- /dev/null
+prefPanel-securitylabel=Etiquettes s\u00E9curit\u00E9\r
+\r
--- /dev/null
+<!ENTITY secureHeaders.name "Entêtes Sécurisés">\r
+<!ENTITY secureHeaders.field "Entêtes Sécurisés :">\r
+<!ENTITY secureHeadersView.label "Voir Les Entêtes Sécurisés">\r
+<!ENTITY secureHeadersList.label "Listes Des Entêtes Sécurisés">\r
+<!ENTITY headername.label "Entête">\r
+<!ENTITY headervalue.label "Valeur signée">\r
+<!ENTITY headerstatus.label "Statut">\r
+<!ENTITY headerencrypted.label "Chiffré">\r
+<!ENTITY headermimevalue.label "Valeur affichée">\r
+<!ENTITY headercanonisation.label "Canonicalisation">\r
--- /dev/null
+menu.secureheaders.label=S\u00E9curiser les ent\u00EAtes\r
+secureInfo.secureheaders.label=Ent\u00EAtes S\u00E9curis\u00E9s\r
+secureheaders.label=Ent\u00EAtes S\u00E9curis\u00E9s :\r
+yes.label=Oui\r
+no.label=Non\r
+notdefine.label=Non defini\r
+headerstatus.deleted.label=Supprim\u00E9\r
+headerstatus.duplicated.label=Dupliqu\u00E9\r
+headerstatus.modified.label=Modifi\u00E9\r
+headersecure.valid.label=Ent\u00EAtes valide\r
+headersecure.invalid.label=Ent\u00EAtes modifi\u00E9\r
+allsecureheaders.valid.label=L\u0027 int\u00E9grit\u00E9 des ent\u00EAtes est v\u00E9rifi\u00E9e\r
+allsecureheaders.invalid.label=Les ent\u00EAtes ont \u00E9t\u00E9 modifi\u00E9s\r
+headercanoniz.simple.label=Simple\r
+headercanoniz.relaxed.label=Relach\u00E9
\ No newline at end of file
--- /dev/null
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+
+#filter substitution
+
+@AB_CD@.jar:
+% locale messenger @AB_CD@ %locale/@AB_CD@/messenger/
+% override chrome://mozapps/locale/downloads/settingsChange.dtd chrome://messenger/locale/downloads/settingsChange.dtd
+% override chrome://global/locale/netError.dtd chrome://messenger/locale/netError.dtd
+ locale/@AB_CD@/messenger/aboutDialog.dtd (%chrome/messenger/aboutDialog.dtd)
+ locale/@AB_CD@/messenger/aboutRights.dtd (%chrome/messenger/aboutRights.dtd)
+ locale/@AB_CD@/messenger/aboutRights.properties (%chrome/messenger/aboutRights.properties)
+ locale/@AB_CD@/messenger/aboutSupportMail.dtd (%chrome/messenger/aboutSupportMail.dtd)
+ locale/@AB_CD@/messenger/aboutSupportMail.properties (%chrome/messenger/aboutSupportMail.properties)
+ locale/@AB_CD@/messenger/telemetry.properties (%chrome/messenger/telemetry.properties)
+ locale/@AB_CD@/messenger/accountCreation.dtd (%chrome/messenger/accountCreation.dtd)
+ locale/@AB_CD@/messenger/accountCreation.properties (%chrome/messenger/accountCreation.properties)
+ locale/@AB_CD@/messenger/accountCreationModel.properties (%chrome/messenger/accountCreationModel.properties)
+ locale/@AB_CD@/messenger/accountCreationUtil.properties (%chrome/messenger/accountCreationUtil.properties)
+ locale/@AB_CD@/messenger/systemIntegrationDialog.dtd (%chrome/messenger/systemIntegrationDialog.dtd)
+ locale/@AB_CD@/messenger/virtualFolderProperties.dtd (%chrome/messenger/virtualFolderProperties.dtd)
+ locale/@AB_CD@/messenger/virtualFolderListDialog.dtd (%chrome/messenger/virtualFolderListDialog.dtd)
+ locale/@AB_CD@/messenger/multimessageview.properties (%chrome/messenger/multimessageview.properties)
+ locale/@AB_CD@/messenger/multimessageview.dtd (%chrome/messenger/multimessageview.dtd)
+ locale/@AB_CD@/messenger/mailOverlay.dtd (%chrome/messenger/mailOverlay.dtd)
+ locale/@AB_CD@/messenger/messenger.dtd (%chrome/messenger/messenger.dtd)
+ locale/@AB_CD@/messenger/viewZoomOverlay.dtd (%chrome/messenger/viewZoomOverlay.dtd)
+ locale/@AB_CD@/messenger/customizeToolbarOverlay.dtd (%chrome/messenger/customizeToolbarOverlay.dtd)
+ locale/@AB_CD@/messenger/baseMenuOverlay.dtd (%chrome/messenger/baseMenuOverlay.dtd)
+ locale/@AB_CD@/messenger/tabmail.dtd (%chrome/messenger/tabmail.dtd)
+ locale/@AB_CD@/messenger/msgAccountCentral.dtd (%chrome/messenger/msgAccountCentral.dtd)
+ locale/@AB_CD@/messenger/SearchDialog.dtd (%chrome/messenger/SearchDialog.dtd)
+ locale/@AB_CD@/messenger/AccountManager.dtd (%chrome/messenger/AccountManager.dtd)
+ locale/@AB_CD@/messenger/AccountWizard.dtd (%chrome/messenger/AccountWizard.dtd)
+ locale/@AB_CD@/messenger/am-advanced.dtd (%chrome/messenger/am-advanced.dtd)
+ locale/@AB_CD@/messenger/am-server-advanced.dtd (%chrome/messenger/am-server-advanced.dtd)
+ locale/@AB_CD@/messenger/am-copies.dtd (%chrome/messenger/am-copies.dtd)
+ locale/@AB_CD@/messenger/am-offline.dtd (%chrome/messenger/am-offline.dtd)
+ locale/@AB_CD@/messenger/am-addressing.dtd (%chrome/messenger/am-addressing.dtd)
+ locale/@AB_CD@/messenger/am-main.dtd (%chrome/messenger/am-main.dtd)
+ locale/@AB_CD@/messenger/am-server-top.dtd (%chrome/messenger/am-server-top.dtd)
+ locale/@AB_CD@/messenger/am-identities-list.dtd (%chrome/messenger/am-identities-list.dtd)
+ locale/@AB_CD@/messenger/am-identity-edit.dtd (%chrome/messenger/am-identity-edit.dtd)
+ locale/@AB_CD@/messenger/am-im.dtd (%chrome/messenger/am-im.dtd)
+ locale/@AB_CD@/messenger/am-serverwithnoidentities.dtd (%chrome/messenger/am-serverwithnoidentities.dtd)
+ locale/@AB_CD@/messenger/am-junk.dtd (%chrome/messenger/am-junk.dtd)
+ locale/@AB_CD@/messenger/prefs.properties (%chrome/messenger/prefs.properties)
+ locale/@AB_CD@/messenger/smtpEditOverlay.dtd (%chrome/messenger/smtpEditOverlay.dtd)
+ locale/@AB_CD@/messenger/am-smime.dtd (%chrome/messenger/am-smime.dtd)
+ locale/@AB_CD@/messenger/am-smime.properties (%chrome/messenger/am-smime.properties)
+ locale/@AB_CD@/messenger/messenger.properties (%chrome/messenger/messenger.properties)
+ locale/@AB_CD@/messenger/newFolderDialog.dtd (%chrome/messenger/newFolderDialog.dtd)
+ locale/@AB_CD@/messenger/newTagDialog.dtd (%chrome/messenger/newTagDialog.dtd)
+ locale/@AB_CD@/messenger/renameFolderDialog.dtd (%chrome/messenger/renameFolderDialog.dtd)
+ locale/@AB_CD@/messenger/folderpane.dtd (%chrome/messenger/folderpane.dtd)
+ locale/@AB_CD@/messenger/folderProps.dtd (%chrome/messenger/folderProps.dtd)
+ locale/@AB_CD@/messenger/folderWidgets.properties (%chrome/messenger/folderWidgets.properties)
+ locale/@AB_CD@/messenger/subscribe.dtd (%chrome/messenger/subscribe.dtd)
+ locale/@AB_CD@/messenger/subscribe.properties (%chrome/messenger/subscribe.properties)
+ locale/@AB_CD@/messenger/msgFolderPickerOverlay.dtd (%chrome/messenger/msgFolderPickerOverlay.dtd)
+ locale/@AB_CD@/messenger/msgHdrViewOverlay.dtd (%chrome/messenger/msgHdrViewOverlay.dtd)
+ locale/@AB_CD@/messenger/editContactOverlay.dtd (%chrome/messenger/editContactOverlay.dtd)
+ locale/@AB_CD@/messenger/editContactOverlay.properties (%chrome/messenger/editContactOverlay.properties)
+ locale/@AB_CD@/messenger/mailEditorOverlay.dtd (%chrome/messenger/mailEditorOverlay.dtd)
+ locale/@AB_CD@/messenger/msgSynchronize.dtd (%chrome/messenger/msgSynchronize.dtd)
+ locale/@AB_CD@/messenger/offline.properties (%chrome/messenger/offline.properties)
+ locale/@AB_CD@/messenger/junkMailInfo.dtd (%chrome/messenger/junkMailInfo.dtd)
+ locale/@AB_CD@/messenger/viewLog.dtd (%chrome/messenger/viewLog.dtd)
+ locale/@AB_CD@/messenger/FilterListDialog.dtd (%chrome/messenger/FilterListDialog.dtd)
+ locale/@AB_CD@/messenger/CustomHeaders.dtd (%chrome/messenger/CustomHeaders.dtd)
+ locale/@AB_CD@/messenger/FilterEditor.dtd (%chrome/messenger/FilterEditor.dtd)
+ locale/@AB_CD@/messenger/search-attributes.properties (%chrome/messenger/search-attributes.properties)
+ locale/@AB_CD@/messenger/search-operators.properties (%chrome/messenger/search-operators.properties)
+ locale/@AB_CD@/messenger/search.properties (%chrome/messenger/search.properties)
+ locale/@AB_CD@/messenger/filter.properties (%chrome/messenger/filter.properties)
+ locale/@AB_CD@/messenger/custom.properties (%chrome/messenger/custom.properties)
+ locale/@AB_CD@/messenger/searchTermOverlay.dtd (%chrome/messenger/searchTermOverlay.dtd)
+ locale/@AB_CD@/messenger/imapMsgs.properties (%chrome/messenger/imapMsgs.properties)
+ locale/@AB_CD@/messenger/localMsgs.properties (%chrome/messenger/localMsgs.properties)
+ locale/@AB_CD@/messenger/downloadheaders.dtd (%chrome/messenger/downloadheaders.dtd)
+ locale/@AB_CD@/messenger/news.properties (%chrome/messenger/news.properties)
+ locale/@AB_CD@/messenger/mime.properties (%chrome/messenger/mime.properties)
+ locale/@AB_CD@/messenger/mimeheader.properties (%chrome/messenger/mimeheader.properties)
+ locale/@AB_CD@/messenger/smime.properties (%chrome/messenger/smime.properties)
+ locale/@AB_CD@/messenger/pgpmime.properties (%chrome/messenger/pgpmime.properties)
+ locale/@AB_CD@/messenger/markByDate.dtd (%chrome/messenger/markByDate.dtd)
+ locale/@AB_CD@/messenger/am-mdn.dtd (%chrome/messenger/am-mdn.dtd)
+ locale/@AB_CD@/messenger/am-mdn.properties (%chrome/messenger/am-mdn.properties)
+ locale/@AB_CD@/messenger/am-archiveoptions.dtd (%chrome/messenger/am-archiveoptions.dtd)
+ locale/@AB_CD@/messenger/msgmdn.properties (%chrome/messenger/msgmdn.properties)
+ locale/@AB_CD@/messenger/mailviews.properties (%chrome/messenger/mailviews.properties)
+ locale/@AB_CD@/messenger/msgViewPickerOverlay.dtd (%chrome/messenger/msgViewPickerOverlay.dtd)
+ locale/@AB_CD@/messenger/mailViewSetup.dtd (%chrome/messenger/mailViewSetup.dtd)
+ locale/@AB_CD@/messenger/mailViewList.dtd (%chrome/messenger/mailViewList.dtd)
+ locale/@AB_CD@/messenger/offlineStartup.properties (%chrome/messenger/offlineStartup.properties)
+ locale/@AB_CD@/messenger/importMsgs.properties (%chrome/messenger/importMsgs.properties)
+ locale/@AB_CD@/messenger/importDialog.dtd (%chrome/messenger/importDialog.dtd)
+ locale/@AB_CD@/messenger/fieldMapImport.dtd (%chrome/messenger/fieldMapImport.dtd)
+ locale/@AB_CD@/messenger/textImportMsgs.properties (%chrome/messenger/textImportMsgs.properties)
+ locale/@AB_CD@/messenger/vCardImportMsgs.properties (%chrome/messenger/vCardImportMsgs.properties)
+ locale/@AB_CD@/messenger/appleMailImportMsgs.properties (%chrome/messenger/appleMailImportMsgs.properties)
+ locale/@AB_CD@/messenger/eudoraImportMsgs.properties (%chrome/messenger/eudoraImportMsgs.properties)
+ locale/@AB_CD@/messenger/oeImportMsgs.properties (%chrome/messenger/oeImportMsgs.properties)
+ locale/@AB_CD@/messenger/wmImportMsgs.properties (%chrome/messenger/wmImportMsgs.properties)
+ locale/@AB_CD@/messenger/outlookImportMsgs.properties (%chrome/messenger/outlookImportMsgs.properties)
+ locale/@AB_CD@/messenger/shutdownWindow.properties (%chrome/messenger/shutdownWindow.properties)
+ locale/@AB_CD@/messenger/configEditorOverlay.dtd (%chrome/messenger/configEditorOverlay.dtd)
+ locale/@AB_CD@/messenger/gloda.properties (%chrome/messenger/gloda.properties)
+ locale/@AB_CD@/messenger/glodaComplete.properties (%chrome/messenger/glodaComplete.properties)
+ locale/@AB_CD@/messenger/templateUtils.properties (%chrome/messenger/templateUtils.properties)
+ locale/@AB_CD@/messenger/glodaFacetView.properties (%chrome/messenger/glodaFacetView.properties)
+ locale/@AB_CD@/messenger/glodaFacetView.dtd (%chrome/messenger/glodaFacetView.dtd)
+ locale/@AB_CD@/messenger/quickFilterBar.dtd (%chrome/messenger/quickFilterBar.dtd)
+ locale/@AB_CD@/messenger/safeMode.dtd (%chrome/messenger/safeMode.dtd)
+ locale/@AB_CD@/messenger/taskbar.properties (%chrome/messenger/taskbar.properties)
+ locale/@AB_CD@/messenger/junkLog.dtd (%chrome/messenger/junkLog.dtd)
+ locale/@AB_CD@/messenger/msgPrintEngine.dtd (%chrome/messenger/msgPrintEngine.dtd)
+ locale/@AB_CD@/messenger/addressbook/abMainWindow.dtd (%chrome/messenger/addressbook/abMainWindow.dtd)
+ locale/@AB_CD@/messenger/addressbook/abNewCardDialog.dtd (%chrome/messenger/addressbook/abNewCardDialog.dtd)
+ locale/@AB_CD@/messenger/addressbook/abContactsPanel.dtd (%chrome/messenger/addressbook/abContactsPanel.dtd)
+ locale/@AB_CD@/messenger/addressbook/abAddressBookNameDialog.dtd (%chrome/messenger/addressbook/abAddressBookNameDialog.dtd)
+ locale/@AB_CD@/messenger/addressbook/abCardOverlay.dtd (%chrome/messenger/addressbook/abCardOverlay.dtd)
+ locale/@AB_CD@/messenger/addressbook/abResultsPaneOverlay.dtd (%chrome/messenger/addressbook/abResultsPaneOverlay.dtd)
+ locale/@AB_CD@/messenger/addressbook/abMailListDialog.dtd (%chrome/messenger/addressbook/abMailListDialog.dtd)
+ locale/@AB_CD@/messenger/addressbook/addressBook.properties (%chrome/messenger/addressbook/addressBook.properties)
+ locale/@AB_CD@/messenger/addressbook/ldapAutoCompErrs.properties (%chrome/messenger/addressbook/ldapAutoCompErrs.properties)
+ locale/@AB_CD@/messenger/addressbook/pref-directory.dtd (%chrome/messenger/addressbook/pref-directory.dtd)
+ locale/@AB_CD@/messenger/addressbook/pref-directory-add.dtd (%chrome/messenger/addressbook/pref-directory-add.dtd)
+ locale/@AB_CD@/messenger/addressbook/replicationProgress.properties (%chrome/messenger/addressbook/replicationProgress.properties)
+ locale/@AB_CD@/messenger/cloudfile/addAccountDialog.dtd (%chrome/messenger/cloudfile/addAccountDialog.dtd)
+ locale/@AB_CD@/messenger/cloudfile/management.dtd (%chrome/messenger/cloudfile/management.dtd)
+ locale/@AB_CD@/messenger/cloudfile/UbuntuOne/management.dtd (%chrome/messenger/cloudfile/UbuntuOne/management.dtd)
+ locale/@AB_CD@/messenger/cloudfile/UbuntuOne/settings.dtd (%chrome/messenger/cloudfile/UbuntuOne/settings.dtd)
+ locale/@AB_CD@/messenger/cloudfile/YouSendIt/management.dtd (%chrome/messenger/cloudfile/YouSendIt/management.dtd)
+ locale/@AB_CD@/messenger/cloudfile/YouSendIt/settings.dtd (%chrome/messenger/cloudfile/YouSendIt/settings.dtd)
+ locale/@AB_CD@/messenger/cloudfile/YouSendIt/fileExceedsLimit.dtd (%chrome/messenger/cloudfile/YouSendIt/fileExceedsLimit.dtd)
+ locale/@AB_CD@/messenger/cloudfile/YouSendIt/fileExceedsQuota.dtd (%chrome/messenger/cloudfile/YouSendIt/fileExceedsQuota.dtd)
+ locale/@AB_CD@/messenger/cloudfile/YouSendIt/fileExceeds2GB.dtd (%chrome/messenger/cloudfile/YouSendIt/fileExceeds2GB.dtd)
+ locale/@AB_CD@/messenger/cloudfile/Box/settings.dtd (%chrome/messenger/cloudfile/Box/settings.dtd)
+ locale/@AB_CD@/messenger/cloudfile/Box/management.dtd (%chrome/messenger/cloudfile/Box/management.dtd)
+ locale/@AB_CD@/messenger/cloudfile/Box/auth.dtd (%chrome/messenger/cloudfile/Box/auth.dtd)
+ locale/@AB_CD@/messenger/messengercompose/messengercompose.dtd (%chrome/messenger/messengercompose/messengercompose.dtd)
+ locale/@AB_CD@/messenger/messengercompose/addressingWidgetOverlay.dtd (%chrome/messenger/messengercompose/addressingWidgetOverlay.dtd)
+ locale/@AB_CD@/messenger/messengercompose/askSendFormat.dtd (%chrome/messenger/messengercompose/askSendFormat.dtd)
+ locale/@AB_CD@/messenger/messengercompose/askSendFormat.properties (%chrome/messenger/messengercompose/askSendFormat.properties)
+ locale/@AB_CD@/messenger/messengercompose/sendProgress.dtd (%chrome/messenger/messengercompose/sendProgress.dtd)
+ locale/@AB_CD@/messenger/messengercompose/sendProgress.properties (%chrome/messenger/messengercompose/sendProgress.properties)
+ locale/@AB_CD@/messenger/messengercompose/composeMsgs.properties (%chrome/messenger/messengercompose/composeMsgs.properties)
+ locale/@AB_CD@/messenger/messengercompose/mailComposeEditorOverlay.dtd (%chrome/messenger/messengercompose/mailComposeEditorOverlay.dtd)
+ locale/@AB_CD@/messenger/preferences/preferences.dtd (%chrome/messenger/preferences/preferences.dtd)
+ locale/@AB_CD@/messenger/preferences/general.dtd (%chrome/messenger/preferences/general.dtd)
+ locale/@AB_CD@/messenger/preferences/display.dtd (%chrome/messenger/preferences/display.dtd)
+ locale/@AB_CD@/messenger/preferences/colors.dtd (%chrome/messenger/preferences/colors.dtd)
+ locale/@AB_CD@/messenger/preferences/chat.dtd (%chrome/messenger/preferences/chat.dtd)
+ locale/@AB_CD@/messenger/preferences/compose.dtd (%chrome/messenger/preferences/compose.dtd)
+ locale/@AB_CD@/messenger/preferences/sendoptions.dtd (%chrome/messenger/preferences/sendoptions.dtd)
+ locale/@AB_CD@/messenger/preferences/security.dtd (%chrome/messenger/preferences/security.dtd)
+ locale/@AB_CD@/messenger/preferences/advanced.dtd (%chrome/messenger/preferences/advanced.dtd)
+ locale/@AB_CD@/messenger/preferences/attachmentReminder.dtd (%chrome/messenger/preferences/attachmentReminder.dtd)
+ locale/@AB_CD@/messenger/preferences/receipts.dtd (%chrome/messenger/preferences/receipts.dtd)
+ locale/@AB_CD@/messenger/preferences/connection.dtd (%chrome/messenger/preferences/connection.dtd)
+ locale/@AB_CD@/messenger/preferences/applications.dtd (%chrome/messenger/preferences/applications.dtd)
+ locale/@AB_CD@/messenger/preferences/applications.properties (%chrome/messenger/preferences/applications.properties)
+ locale/@AB_CD@/messenger/preferences/applicationManager.dtd (%chrome/messenger/preferences/applicationManager.dtd)
+ locale/@AB_CD@/messenger/preferences/applicationManager.properties (%chrome/messenger/preferences/applicationManager.properties)
+ locale/@AB_CD@/messenger/preferences/fonts.dtd (%chrome/messenger/preferences/fonts.dtd)
+ locale/@AB_CD@/messenger/preferences/offline.dtd (%chrome/messenger/preferences/offline.dtd)
+ locale/@AB_CD@/messenger/preferences/notifications.dtd (%chrome/messenger/preferences/notifications.dtd)
+ locale/@AB_CD@/messenger/preferences/preferences.properties (%chrome/messenger/preferences/preferences.properties)
+ locale/@AB_CD@/messenger/preferences/cookies.dtd (%chrome/messenger/preferences/cookies.dtd)
+ locale/@AB_CD@/messenger/preferences/permissions.dtd (%chrome/messenger/preferences/permissions.dtd)
+ locale/@AB_CD@/messenger/migration/migration.dtd (%chrome/messenger/migration/migration.dtd)
+ locale/@AB_CD@/messenger/migration/migration.properties (%chrome/messenger/migration/migration.properties)
+ locale/@AB_CD@/messenger/newmailaccount/accountProvisioner.properties (%chrome/messenger/newmailaccount/accountProvisioner.properties)
+ locale/@AB_CD@/messenger/newmailaccount/accountProvisioner.dtd (%chrome/messenger/newmailaccount/accountProvisioner.dtd)
+ locale/@AB_CD@/messenger/searchIntegrationWin.dtd (%chrome/messenger/searchIntegrationWin.dtd)
+ locale/@AB_CD@/messenger/searchIntegrationMac.dtd (%chrome/messenger/searchIntegrationMac.dtd)
+ locale/@AB_CD@/messenger/searchIntegrationDefault.dtd (%chrome/messenger/searchIntegrationDefault.dtd)
+ locale/@AB_CD@/messenger/activity.dtd (%chrome/messenger/activity.dtd)
+ locale/@AB_CD@/messenger/activity.properties (%chrome/messenger/activity.properties)
+ locale/@AB_CD@/messenger/downloads/settingsChange.dtd (%chrome/overrides/settingsChange.dtd)
+ locale/@AB_CD@/messenger/netError.dtd (%chrome/overrides/netError.dtd)
+ locale/@AB_CD@/messenger/downloadsOverlay.dtd (%chrome/messenger/downloadsOverlay.dtd)
+ locale/@AB_CD@/messenger/chat.dtd (%chrome/messenger/chat.dtd)
+ locale/@AB_CD@/messenger/chat.properties (%chrome/messenger/chat.properties)
+ locale/@AB_CD@/messenger/addbuddy.dtd (%chrome/messenger/addbuddy.dtd)
+ locale/@AB_CD@/messenger/joinChat.dtd (%chrome/messenger/joinChat.dtd)
+ locale/@AB_CD@/messenger/imAccounts.dtd (%chrome/messenger/imAccounts.dtd)
+ locale/@AB_CD@/messenger/imAccounts.properties (%chrome/messenger/imAccounts.properties)
+ locale/@AB_CD@/messenger/imAccountWizard.dtd (%chrome/messenger/imAccountWizard.dtd)
+ locale/@AB_CD@/messenger/sanitize.dtd (%chrome/messenger/sanitize.dtd)
+% locale messenger-mapi @AB_CD@ %locale/@AB_CD@/messenger-mapi/
+ locale/@AB_CD@/messenger-mapi/mapi.properties (%chrome/messenger-mapi/mapi.properties)
+% locale messenger-newsblog @AB_CD@ %locale/@AB_CD@/messenger-newsblog/
+ locale/@AB_CD@/messenger-newsblog/newsblog.properties (%chrome/messenger-newsblog/newsblog.properties)
+ locale/@AB_CD@/messenger-newsblog/feed-subscriptions.dtd (%chrome/messenger-newsblog/feed-subscriptions.dtd)
+ locale/@AB_CD@/messenger-newsblog/am-newsblog.dtd (%chrome/messenger-newsblog/am-newsblog.dtd)
+% locale messenger-smime @AB_CD@ %locale/@AB_CD@/messenger-smime/
+ locale/@AB_CD@/messenger-smime/msgCompSMIMEOverlay.dtd (%chrome/messenger-smime/msgCompSMIMEOverlay.dtd)
+ locale/@AB_CD@/messenger-smime/msgCompSMIMEOverlay.properties (%chrome/messenger-smime/msgCompSMIMEOverlay.properties)
+ locale/@AB_CD@/messenger-smime/msgReadSMIMEOverlay.dtd (%chrome/messenger-smime/msgReadSMIMEOverlay.dtd)
+ locale/@AB_CD@/messenger-smime/msgReadSMIMEOverlay.properties (%chrome/messenger-smime/msgReadSMIMEOverlay.properties)
+ locale/@AB_CD@/messenger-smime/msgCompSecurityInfo.dtd (%chrome/messenger-smime/msgCompSecurityInfo.dtd)
+ locale/@AB_CD@/messenger-smime/msgCompSecurityInfo.properties (%chrome/messenger-smime/msgCompSecurityInfo.properties)
+ locale/@AB_CD@/messenger-smime/msgReadSecurityInfo.dtd (%chrome/messenger-smime/msgReadSecurityInfo.dtd)
+ locale/@AB_CD@/messenger-smime/certFetchingStatus.dtd (%chrome/messenger-smime/certFetchingStatus.dtd)
+ locale/@AB_CD@/messenger-smime/msgSecurityInfo.properties (%chrome/messenger-smime/msgSecurityInfo.properties)
+ locale/@AB_CD@/messenger-smime/msgSMIMEReceiptGenerator.properties (%chrome/messenger-smime/msgSMIMEReceiptGenerator.properties)
+ locale/@AB_CD@/messenger-smime/msgSecurityLabel.properties (%chrome/messenger-smime/msgSecurityLabel.properties)
+ locale/@AB_CD@/messenger-smime/msgCompSecurityLabelDialog.dtd (%chrome/messenger-smime/msgCompSecurityLabelDialog.dtd)
+% locale messenger-region @AB_CD@ %locale/@AB_CD@/messenger-region/
+ locale/@AB_CD@/messenger-region/region.properties (%chrome/messenger-region/region.properties)
+% locale mozldap @AB_CD@ %locale/@AB_CD@/mozldap/
+ locale/@AB_CD@/mozldap/ldap.properties (%chrome/mozldap/ldap.properties)
+% locale communicator @AB_CD@ %locale/@AB_CD@/communicator/
+ locale/@AB_CD@/communicator/utilityOverlay.dtd (%chrome/communicator/utilityOverlay.dtd)
+ locale/@AB_CD@/messenger/am-secureheaders.properties (%chrome/messenger/am-secureheaders.properties)
+ locale/@AB_CD@/messenger/am-secureheaders.dtd (%chrome/messenger/am-secureheaders.dtd)
+ locale/@AB_CD@/messenger/secureheaders.dtd (%chrome/messenger/secureheaders.dtd)
+ locale/@AB_CD@/messenger/secureheaders.properties (%chrome/messenger/secureheaders.properties)
--- /dev/null
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+classic.jar:
+ skin/classic/communicator/smileys.css (mail/smileys.css)
+% skin messenger classic/1.0 %skin/classic/messenger/
+ skin/classic/messenger/primaryToolbar.css (mail/primaryToolbar.css)
+ skin/classic/messenger/aboutSupport.css (../windows/mail/aboutSupport.css)
+ skin/classic/messenger/accountCentral.css (mail/accountCentral.css)
+ skin/classic/messenger/accountCreation.css (mail/accountCreation.css)
+ skin/classic/messenger/accountManage.css (mail/accountManage.css)
+ skin/classic/messenger/accountWizard.css (mail/accountWizard.css)
+* skin/classic/messenger/chat.css (mail/chat.css)
+ skin/classic/messenger/userIcon.png (mail/userIcon.png)
+ skin/classic/messenger/grain.png (mail/grain.png)
+* skin/classic/messenger/imAccounts.css (../../components/im/themes/imAccounts.css)
+* skin/classic/messenger/imAccountWizard.css (../../components/im/themes/imAccountWizard.css)
+ skin/classic/messenger/imBuddytooltip.css (../../components/im/themes/imBuddytooltip.css)
+ skin/classic/messenger/imMenulist.css (../../components/im/themes/imMenulist.css)
+* skin/classic/messenger/imRichlistbox.css (../../components/im/themes/imRichlistbox.css)
+ skin/classic/messenger/imStatus.css (../../components/im/themes/imStatus.css)
+ skin/classic/messenger/founder.png (../../components/im/themes/founder.png)
+ skin/classic/messenger/operator.png (../../components/im/themes/operator.png)
+ skin/classic/messenger/half-operator.png (../../components/im/themes/half-operator.png)
+ skin/classic/messenger/voice.png (../../components/im/themes/voice.png)
+ skin/classic/messenger/browserRequest.css (mail/browserRequest.css)
+ skin/classic/messenger/section_collapsed.png (mail/section_collapsed.png)
+ skin/classic/messenger/section_expanded.png (mail/section_expanded.png)
+ skin/classic/messenger/messageHeader.css (mail/messageHeader.css)
+ skin/classic/messenger/messageBody.css (mail/messageBody.css)
+ skin/classic/messenger/webSearch.css (mail/webSearch.css)
+ skin/classic/messenger/messageQuotes.css (mail/messageQuotes.css)
+ skin/classic/messenger/messenger.css (mail/messenger.css)
+ skin/classic/messenger/attachmentList.css (mail/attachmentList.css)
+ skin/classic/messenger/imageFilters.svg (mail/imageFilters.svg)
+ skin/classic/messenger/mailWindow1.css (mail/mailWindow1.css)
+ skin/classic/messenger/tagColors.css (mail/tagColors.css)
+ skin/classic/messenger/messageWindow.css (mail/messageWindow.css)
+ skin/classic/messenger/searchBox.css (mail/searchBox.css)
+ skin/classic/messenger/junkMail.css (mail/junkMail.css)
+ skin/classic/messenger/folderMenus.css (mail/folderMenus.css)
+ skin/classic/messenger/folderPane.css (mail/folderPane.css)
+ skin/classic/messenger/subscribe.css (mail/subscribe.css)
+ skin/classic/messenger/virtualFolderListDialog.css (mail/virtualFolderListDialog.css)
+ skin/classic/messenger/searchDialog.css (mail/searchDialog.css)
+ skin/classic/messenger/msgSelectOffline.css (mail/msgSelectOffline.css)
+ skin/classic/messenger/filterDialog.css (mail/filterDialog.css)
+ skin/classic/messenger/multimessageview.css (mail/multimessageview.css)
+ skin/classic/messenger/glodaFacetView.css (mail/glodaFacetView.css)
+ skin/classic/messenger/icons/exclude.png (mail/icons/exclude.png)
+ skin/classic/messenger/icons/exclude-selected.png (mail/icons/exclude-selected.png)
+ skin/classic/messenger/icons/zoomout.png (mail/icons/zoomout.png)
+ skin/classic/messenger/icons/zoomout-hover.png (mail/icons/zoomout-hover.png)
+ skin/classic/messenger/dialogs.css (mail/dialogs.css)
+ skin/classic/messenger/newmailalert.css (mail/newmailalert.css)
+ skin/classic/messenger/tabmail.css (mail/tabmail.css)
+ skin/classic/messenger/editContactOverlay.css (mail/editContactOverlay.css)
+ skin/classic/messenger/quickFilterBar.css (mail/quickFilterBar.css)
+ skin/classic/messenger/starred48.png (mail/starred48.png)
+ skin/classic/messenger/contactStarred.png (mail/contactStarred.png)
+ skin/classic/messenger/starContact.png (mail/starContact.png)
+ skin/classic/messenger/activity/activity.css (mail/activity/activity.css)
+ skin/classic/messenger/activity/buttons.png (mail/activity/buttons.png)
+ skin/classic/messenger/activity/defaultProcessIcon.png (mail/activity/defaultProcessIcon.png)
+ skin/classic/messenger/activity/defaultEventIcon.png (mail/activity/defaultEventIcon.png)
+ skin/classic/messenger/activity/defaultWarningIcon.png (mail/activity/defaultWarningIcon.png)
+ skin/classic/messenger/activity/undoIcon.png (mail/activity/undoIcon.png)
+ skin/classic/messenger/activity/syncMailIcon.png (mail/activity/syncMailIcon.png)
+ skin/classic/messenger/activity/sendMailIcon.png (mail/activity/sendMailIcon.png)
+ skin/classic/messenger/activity/removeItemIcon.png (mail/activity/removeItemIcon.png)
+ skin/classic/messenger/activity/addItemIcon.png (mail/activity/addItemIcon.png)
+ skin/classic/messenger/activity/moveMailIcon.png (mail/activity/moveMailIcon.png)
+ skin/classic/messenger/activity/copyMailIcon.png (mail/activity/copyMailIcon.png)
+ skin/classic/messenger/activity/deleteMailIcon.png (mail/activity/deleteMailIcon.png)
+ skin/classic/messenger/activity/compactMailIcon.png (mail/activity/compactMailIcon.png)
+ skin/classic/messenger/activity/indexMailIcon.png (mail/activity/indexMailIcon.png)
+ skin/classic/messenger/addressbook/addressbook.css (mail/addrbook/addressbook.css)
+ skin/classic/messenger/addressbook/abContactsPanel.css (mail/addrbook/abContactsPanel.css)
+ skin/classic/messenger/addressbook/cardDialog.css (mail/addrbook/cardDialog.css)
+ skin/classic/messenger/addressbook/abResultsPane.css (mail/addrbook/abResultsPane.css)
+ skin/classic/messenger/addressbook/icons/abcard.png (mail/addrbook/abcard.png)
+ skin/classic/messenger/addressbook/icons/addrbook.png (mail/addrbook/addrbook.png)
+ skin/classic/messenger/addressbook/icons/ablist.png (mail/addrbook/ablist.png)
+ skin/classic/messenger/addressbook/icons/contact-generic.png (mail/addrbook/contact-generic.png)
+ skin/classic/messenger/addressbook/icons/contact-generic-tiny.png (mail/addrbook/contact-generic-tiny.png)
+ skin/classic/messenger/addressbook/icons/addressbook-toolbar.png (mail/addrbook/addressbook-toolbar.png)
+ skin/classic/messenger/addressbook/icons/addressbook-toolbar-small.png (mail/addrbook/addressbook-toolbar-small.png)
+ skin/classic/messenger/addressbook/icons/abcard-large.png (mail/addrbook/abcard-large.png)
+ skin/classic/messenger/addressbook/icons/remote-addrbook.png (mail/addrbook/remote-addrbook.png)
+ skin/classic/messenger/addressbook/icons/remote-addrbook-error.png (mail/addrbook/remote-addrbook-error.png)
+ skin/classic/messenger/addressbook/icons/secure-remote-addrbook.png (mail/addrbook/secure-remote-addrbook.png)
+ skin/classic/messenger/cloudfile/addAccountDialog.css (mail/cloudfile/addAccountDialog.css)
+ skin/classic/messenger/cloudfile/YouSendIt/settings.css (mail/cloudfile/YouSendIt/settings.css)
+ skin/classic/messenger/cloudfile/YouSendIt/fileExceedsLimit.css (mail/cloudfile/YouSendIt/fileExceedsLimit.css)
+ skin/classic/messenger/cloudfile/YouSendIt/check.png (mail/cloudfile/YouSendIt/check.png)
+ skin/classic/messenger/messengercompose/messengercompose.css (mail/compose/messengercompose.css)
+ skin/classic/messenger/messengercompose/editorOverlay.css (mail/compose/editorOverlay.css)
+ skin/classic/messenger/messengercompose/compose-toolbar.png (mail/compose/compose-toolbar.png)
+ skin/classic/messenger/messengercompose/compose-toolbar-small.png (mail/compose/compose-toolbar-small.png)
+ skin/classic/messenger/messengercompose/format-buttons.png (mail/compose/format-buttons.png)
+% skin messenger-newsblog classic/1.0 %skin/classic/messenger-newsblog/
+ skin/classic/messenger-newsblog/feed-subscriptions.css (mail/newsblog/feed-subscriptions.css)
+ skin/classic/messenger-newsblog/icons/rss-feed.png (mail/newsblog/rss-feed.png)
+ skin/classic/messenger-newsblog/icons/server-rss.png (mail/newsblog/server-rss.png)
+ skin/classic/messenger/preferences/alwaysAsk.png (mail/preferences/alwaysAsk.png)
+ skin/classic/messenger/preferences/preferences.css (mail/preferences/preferences.css)
+ skin/classic/messenger/preferences/general.png (mail/preferences/general.png)
+ skin/classic/messenger/preferences/display.png (mail/preferences/display.png)
+ skin/classic/messenger/preferences/composition.png (mail/preferences/composition.png)
+ skin/classic/messenger/preferences/security.png (mail/preferences/security.png)
+ skin/classic/messenger/preferences/attachments.png (mail/preferences/attachments.png)
+ skin/classic/messenger/preferences/applications.css (mail/preferences/applications.css)
+ skin/classic/messenger/preferences/advanced.png (mail/preferences/advanced.png)
+ skin/classic/messenger/preferences/chat.png (mail/preferences/chat.png)
+ skin/classic/messenger/preferences/background.png (mail/preferences/background.png)
+ skin/classic/messenger/preferences/hover.png (mail/preferences/hover.png)
+ skin/classic/messenger/preferences/selected.png (mail/preferences/selected.png)
+ skin/classic/messenger/preferences/auth-error.png (mail/preferences/auth-error.png)
+ skin/classic/messenger/smime/msgCompSMIMEOverlay.css (mail/smime/msgCompSMIMEOverlay.css)
+ skin/classic/messenger/smime/msgHdrViewSMIMEOverlay.css (mail/smime/msgHdrViewSMIMEOverlay.css)
+ skin/classic/messenger/smime/msgReadSMIMEOverlay.css (mail/smime/msgReadSMIMEOverlay.css)
+ skin/classic/messenger/smime/msgReadSecurityInfo.css (mail/smime/msgReadSecurityInfo.css)
+ skin/classic/messenger/smime/msgCompSecurityInfo.css (mail/smime/msgCompSecurityInfo.css)
+ skin/classic/messenger/smime/certFetchingStatus.css (mail/smime/certFetchingStatus.css)
+ skin/classic/messenger/smime/msgReadSecureHeaders.css (mail/smime/msgReadSecureHeaders.css)
+ skin/classic/messenger/smime/icons/hdrCryptoNotOk.png (mail/smime/hdrCryptoNotOk.png)
+ skin/classic/messenger/smime/icons/hdrCryptoOk.png (mail/smime/hdrCryptoOk.png)
+ skin/classic/messenger/smime/icons/hdrSignNotOk.png (mail/smime/hdrSignNotOk.png)
+ skin/classic/messenger/smime/icons/hdrSignOk.png (mail/smime/hdrSignOk.png)
+ skin/classic/messenger/smime/icons/hdrSignUnknown.png (mail/smime/hdrSignUnknown.png)
+ skin/classic/messenger/smime/icons/sbCryptoNotOk.png (mail/smime/sbCryptoNotOk.png)
+ skin/classic/messenger/smime/icons/sbCryptoOk.png (mail/smime/sbCryptoOk.png)
+ skin/classic/messenger/smime/icons/sbSignNotOk.png (mail/smime/sbSignNotOk.png)
+ skin/classic/messenger/smime/icons/sbSignOk.png (mail/smime/sbSignOk.png)
+ skin/classic/messenger/smime/icons/sbSignUnknown.png (mail/smime/sbSignUnknown.png)
+ skin/classic/messenger/smime/icons/check_sign.png (mail/smime/check_sign.png)
+ skin/classic/messenger/smime/icons/cross_sign.png (mail/smime/cross_sign.png)
+ skin/classic/messenger/smime/icons/unsign.png (mail/smime/unsign.png)
+ skin/classic/messenger/icons/timeline.png (mail/icons/timeline.png)
+ skin/classic/messenger/icons/timeline-inverted.png (mail/icons/timeline-inverted.png)
+ skin/classic/messenger/icons/empty-search-results.png (mail/icons/empty-search-results.png)
+ skin/classic/messenger/icons/secure.png (mail/icons/secure.png)
+ skin/classic/messenger/icons/update.png (mail/icons/update.png)
+ skin/classic/messenger/icons/insecure.png (mail/icons/insecure.png)
+ skin/classic/messenger/icons/identity.png (mail/icons/identity.png)
+ skin/classic/messenger/icons/tick.png (mail/icons/tick.png)
+ skin/classic/messenger/icons/error.png (mail/icons/error.png)
+ skin/classic/messenger/icons/cancel.png (mail/icons/cancel.png)
+ skin/classic/messenger/icons/mail-toolbar.png (mail/icons/mail-toolbar.png)
+ skin/classic/messenger/icons/mail-toolbar-small.png (mail/icons/mail-toolbar-small.png)
+ skin/classic/messenger/icons/folder-pane.png (mail/icons/folder-pane.png)
+ skin/classic/messenger/icons/folder-blank.png (mail/icons/folder-blank.png)
+ skin/classic/messenger/icons/folder-new-star.png (mail/icons/folder-new-star.png)
+ skin/classic/messenger/icons/message-list.png (mail/icons/message-list.png)
+ skin/classic/messenger/icons/message.png (mail/icons/message.png)
+ skin/classic/messenger/icons/attachment-deleted.png (mail/icons/attachment-deleted.png)
+ skin/classic/messenger/icons/attachment-deleted-large.png (mail/icons/attachment-deleted-large.png)
+ skin/classic/messenger/icons/attachment-col.svg (mail/icons/attachment-col.svg)
+ skin/classic/messenger/icons/columnpicker.svg (mail/icons/columnpicker.svg)
+ skin/classic/messenger/icons/junk-col.svg (mail/icons/junk-col.svg)
+ skin/classic/messenger/icons/thread-col.svg (mail/icons/thread-col.svg)
+ skin/classic/messenger/icons/thread.png (mail/icons/thread.png)
+ skin/classic/messenger/icons/thread-ignored.png (mail/icons/thread-ignored.png)
+ skin/classic/messenger/icons/message-ignored.png (mail/icons/message-ignored.png)
+ skin/classic/messenger/icons/thread-watched.png (mail/icons/thread-watched.png)
+ skin/classic/messenger/icons/flag-col.svg (mail/icons/flag-col.svg)
+ skin/classic/messenger/icons/server.png (mail/icons/server.png)
+ skin/classic/messenger/icons/readcol.svg (mail/icons/readcol.svg)
+ skin/classic/messenger/icons/search-arrow.png (mail/icons/search-arrow.png)
+ skin/classic/messenger/icons/close-button.png (mail/icons/close-button.png)
+ skin/classic/messenger/icons/close-inverted.png (mail/icons/close-inverted.png)
+ skin/classic/messenger/icons/closeTab.svg (mail/icons/closeTab.svg)
+ skin/classic/messenger/icons/closeTab-active.svg (mail/icons/closeTab-active.svg)
+ skin/classic/messenger/icons/remote-blocked.png (mail/icons/remote-blocked.png)
+ skin/classic/messenger/icons/phishing.png (mail/icons/phishing.png)
+ skin/classic/messenger/icons/junk.png (mail/icons/junk.png)
+ skin/classic/messenger/icons/check.gif (mail/icons/check.gif)
+ skin/classic/messenger/icons/notchecked.gif (mail/icons/notchecked.gif)
+ skin/classic/messenger/icons/online.png (mail/icons/online.png)
+ skin/classic/messenger/icons/offline.png (mail/icons/offline.png)
+ skin/classic/messenger/icons/row.png (mail/icons/row.png)
+ skin/classic/messenger/icons/black_pin.png (mail/icons/black_pin.png)
+ skin/classic/messenger/icons/dropmarker.svg (mail/icons/dropmarker.svg)
+ skin/classic/messenger/icons/dropmarker-hover.svg (mail/icons/dropmarker-hover.svg)
+ skin/classic/messenger/icons/filterbar.png (mail/icons/filterbar.png)
+ skin/classic/messenger/icons/red_pin.png (mail/icons/red_pin.png)
+ skin/classic/messenger/icons/tabActiveEnd.svg (mail/icons/tabActiveEnd.svg)
+ skin/classic/messenger/icons/tabActiveMiddle.svg (mail/icons/tabActiveMiddle.svg)
+ skin/classic/messenger/icons/tabActiveStart.svg (mail/icons/tabActiveStart.svg)
+ skin/classic/messenger/icons/tabBackgroundEnd.png (mail/icons/tabBackgroundEnd.png)
+ skin/classic/messenger/icons/tabBackgroundMiddle.png (mail/icons/tabBackgroundMiddle.png)
+ skin/classic/messenger/icons/tabBackgroundStart.png (mail/icons/tabBackgroundStart.png)
+ skin/classic/messenger/icons/tabDragIndicator.png (mail/icons/tabDragIndicator.png)
+ skin/classic/messenger/icons/button-archive.svg (mail/icons/button-archive.svg)
+ skin/classic/messenger/icons/button-delete.svg (mail/icons/button-delete.svg)
+ skin/classic/messenger/icons/button-forward.svg (mail/icons/button-forward.svg)
+ skin/classic/messenger/icons/button-junk.svg (mail/icons/button-junk.svg)
+ skin/classic/messenger/icons/button-reply.svg (mail/icons/button-reply.svg)
+ skin/classic/messenger/icons/button-reply-all.svg (mail/icons/button-reply-all.svg)
+ skin/classic/messenger/icons/button-reply-list.svg (mail/icons/button-reply-list.svg)
+ skin/classic/messenger/icons/button-tag.svg (mail/icons/button-tag.svg)
+ skin/classic/messenger/icons/chat-toolbar.png (mail/icons/chat-toolbar.png)
+ skin/classic/messenger/icons/chat-toolbar-small.png (mail/icons/chat-toolbar-small.png)
+ skin/classic/messenger/icons/status.png (mail/icons/status.png)
+ skin/classic/messenger/icons/status-small.png (mail/icons/status-small.png)
+% skin communicator classic/1.0 %skin/classic/communicator/
+ skin/classic/communicator/communicator.css (mail/communicator.css)
+ skin/classic/communicator/icons/smileys/smiley-smile.png (mail/icons/smiley-smile.png)
+ skin/classic/communicator/icons/smileys/smiley-frown.png (mail/icons/smiley-frown.png)
+ skin/classic/communicator/icons/smileys/smiley-wink.png (mail/icons/smiley-wink.png)
+ skin/classic/communicator/icons/smileys/smiley-tongue-out.png (mail/icons/smiley-tongue-out.png)
+ skin/classic/communicator/icons/smileys/smiley-laughing.png (mail/icons/smiley-laughing.png)
+ skin/classic/communicator/icons/smileys/smiley-embarassed.png (mail/icons/smiley-embarassed.png)
+ skin/classic/communicator/icons/smileys/smiley-undecided.png (mail/icons/smiley-undecided.png)
+ skin/classic/communicator/icons/smileys/smiley-surprised.png (mail/icons/smiley-surprised.png)
+ skin/classic/communicator/icons/smileys/smiley-kiss.png (mail/icons/smiley-kiss.png)
+ skin/classic/communicator/icons/smileys/smiley-yell.png (mail/icons/smiley-yell.png)
+ skin/classic/communicator/icons/smileys/smiley-cool.png (mail/icons/smiley-cool.png)
+ skin/classic/communicator/icons/smileys/smiley-money-mouth.png (mail/icons/smiley-money-mouth.png)
+ skin/classic/communicator/icons/smileys/smiley-foot-in-mouth.png (mail/icons/smiley-foot-in-mouth.png)
+ skin/classic/communicator/icons/smileys/smiley-innocent.png (mail/icons/smiley-innocent.png)
+ skin/classic/communicator/icons/smileys/smiley-cry.png (mail/icons/smiley-cry.png)
+ skin/classic/communicator/icons/smileys/smiley-sealed.png (mail/icons/smiley-sealed.png)
+ skin/classic/messenger/accountcentral/read-messages.png (mail/accountcentral/read-messages.png)
+ skin/classic/messenger/accountcentral/write-message.png (mail/accountcentral/write-message.png)
+ skin/classic/messenger/accountcentral/create-account.png (mail/accountcentral/create-account.png)
+ skin/classic/messenger/accountcentral/account-settings.png (mail/accountcentral/account-settings.png)
+ skin/classic/messenger/accountcentral/search-messages.png (mail/accountcentral/search-messages.png)
+ skin/classic/messenger/accountcentral/manage-filters.png (mail/accountcentral/manage-filters.png)
+ skin/classic/messenger/accountcentral/offline-settings.png (mail/accountcentral/offline-settings.png)
+ skin/classic/messenger/accountcentral/manage-imap.png (mail/accountcentral/manage-imap.png)
+ skin/classic/messenger/accountcentral/manage-newsgroups.png (mail/accountcentral/manage-newsgroups.png)
+ skin/classic/messenger/accountcentral/manage-rss.png (mail/accountcentral/manage-rss.png)
+ skin/classic/messenger/icons/arrow-dn-grey.png (mail/icons/arrow-dn-grey.png)
+ skin/classic/messenger/icons/arrow-dn-blue.png (mail/icons/arrow-dn-blue.png)
+ skin/classic/messenger/icons/arrow/arrow-left.png (mail/icons/arrow/arrow-left.png)
+ skin/classic/messenger/icons/arrow/arrow-right.png (mail/icons/arrow/arrow-right.png)
+ skin/classic/messenger/icons/arrow/arrow-up.png (mail/icons/arrow/arrow-up.png)
+ skin/classic/messenger/icons/arrow/arrow-down.png (mail/icons/arrow/arrow-down.png)
+ skin/classic/messenger/icons/arrow/arrow-left-dim.png (mail/icons/arrow/arrow-left-dim.png)
+ skin/classic/messenger/icons/arrow/arrow-right-dim.png (mail/icons/arrow/arrow-right-dim.png)
+ skin/classic/messenger/icons/arrow/arrow-up-dim.png (mail/icons/arrow/arrow-up-dim.png)
+ skin/classic/messenger/icons/arrow/arrow-down-dim.png (mail/icons/arrow/arrow-down-dim.png)
+ skin/classic/messenger/icons/arrow/foldercycler-arrow-left.png (mail/icons/arrow/foldercycler-arrow-left.png)
+ skin/classic/messenger/icons/arrow/foldercycler-arrow-right.png (mail/icons/arrow/foldercycler-arrow-right.png)
+ skin/classic/messenger/icons/search-favorite.png (mail/icons/search-favorite.png)
+ skin/classic/messenger/icons/connecting.png (mail/icons/connecting.png)
+ skin/classic/messenger/icons/loading.png (mail/icons/loading.png)
+ skin/classic/messenger/tagbg.png (mail/tagbg.png)
+% skin editor classic/1.0 %skin/classic/editor/
+ skin/classic/editor/editor.css (editor/editor.css)
+ skin/classic/editor/EditorDialog.css (editor/EditorDialog.css)
+ skin/classic/editor/icons/img-align-bottom.gif (editor/img-align-bottom.gif)
+ skin/classic/editor/icons/img-align-left.gif (editor/img-align-left.gif)
+ skin/classic/editor/icons/img-align-middle.gif (editor/img-align-middle.gif)
+ skin/classic/editor/icons/img-align-right.gif (editor/img-align-right.gif)
+ skin/classic/editor/icons/img-align-top.gif (editor/img-align-top.gif)
+ skin/classic/messenger/newmailaccount/accountProvisioner.css (mail/newmailaccount/accountProvisioner.css)
+ skin/classic/messenger/newmailaccount/search.gif (mail/newmailaccount/search.gif)
+ skin/classic/messenger/newmailaccount/spinner.gif (mail/newmailaccount/spinner.gif)
+ skin/classic/messenger/newmailaccount/success-addons.png (mail/newmailaccount/success-addons.png)
+ skin/classic/messenger/newmailaccount/success-border.png (mail/newmailaccount/success-border.png)
+ skin/classic/messenger/newmailaccount/success-compose.png (mail/newmailaccount/success-compose.png)
+ skin/classic/messenger/newmailaccount/success-signature.png (mail/newmailaccount/success-signature.png)
+ skin/classic/messenger/newmailaccount/search.png (mail/newmailaccount/search.png)
+ skin/classic/messenger/icons/ubuntuone.png (mail/icons/ubuntuone.png)
+ skin/classic/messenger/icons/yousendit.png (mail/icons/yousendit.png)
+ skin/classic/messenger/sanitizeDialog.css (mail/sanitizeDialog.css)
+ skin/classic/messenger/icons/box-logo.png (mail/icons/box-logo.png)
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved
+ */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+#signedHdrIcon {
+ list-style-image: none;
+ visibility: visible;
+ -moz-margin-end: 10px;
+}
+
+#signedHdrIcon[signed="ok"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrSignOk.png");
+ visibility: visible;
+}
+
+#signedHdrIcon[signed="unknown"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrSignUnknown.png");
+ visibility: visible;
+}
+
+#signedHdrIcon[signed="mismatch"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrSignUnknown.png");
+ visibility: visible;
+}
+
+#signedHdrIcon[signed="notok"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrSignNotOk.png");
+ visibility: visible;
+}
+
+#encryptedHdrIcon {
+ list-style-image: none;
+ visibility: visible;
+}
+
+#encryptedHdrIcon[encrypted="ok"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrCryptoOk.png");
+ visibility: visible;
+}
+
+#encryptedHdrIcon[encrypted="notok"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrCryptoNotOk.png");
+ visibility: visible;
+}
+
+#secureinfomsgh,
+#secureinfomsgh2{
+ margin-top:2px;
+ margin-bottom:2px;
+ padding-left:5px;
+ background-color:#ffffcc;
+}
+
+#secureinfomsgh[signed="notok"],#secureinfomsgh2[signed="notok"]{background-color:#ff5959;}
+#secureinfomsgh[signed="ok"],#secureinfomsgh2[signed="ok"]{background-color:#CAFF70;}
+#secureinfomsgh[signed="warning"],#secureinfomsgh2[signed="warning"]{background-color:#E76914;}
+
+#secureinfomsg label,
+#secureinfomsg2 label{
+ font-weight: bold;
+ cursor: pointer;
+}
+#secureinfomsg label:hover,
+#secureinfomsg2 label:hover{
+ color: #00007f;
+}
\ No newline at end of file
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. \r
+ * Contributor(s): \r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */\r
+\r
+/* ===== msgReadSecureHeaders.css ========================================\r
+ == Styles for the secure headers info window when displaying received mail.\r
+ ======================================================================= */\r
+\r
+@import url("chrome://messenger/skin/");\r
+\r
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");\r
+\r
+#secHeader_treechild_id::-moz-tree-row(selected){ \r
+ background-color: DarkGray;\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-row(odd){ \r
+ background-color: #EEEEEE;\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-row(odd, selected){ \r
+ background-color: DarkGray;\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-cell-text(valid){ \r
+ color: green;\r
+}\r
+#secHeader_treechild_id::-moz-tree-cell-text(invalid){ \r
+ color: #b10000;\r
+ font-weight: bold;\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-cell-text(unsigned){ \r
+ color: #E76914; \r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-image(valid){\r
+ list-style-image: url("chrome://messenger/skin/smime/icons/check_sign.png");\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-image(invalid){\r
+ list-style-image: url("chrome://messenger/skin/smime/icons/cross_sign.png");\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-image(unsigned){\r
+ list-style-image: url("chrome://messenger/skin/smime/icons/unsign.png");\r
+}
\ No newline at end of file
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* ===== msgReadSecurityInfo.css ========================================
+ == Styles for the security info window when displaying received mail.
+ ======================================================================= */
+
+@import url("chrome://messenger/skin/");
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+#signatureLabel {
+ font-weight: bold;
+}
+
+#signatureCert {
+ margin: 5px;
+}
+
+#encryptionLabel {
+ font-weight: bold;
+}
+
+#encryptionCert {
+ margin: 5px;
+}
+
+#securityLabel {
+ font-weight: bold;
+}
+
+#securityLabelContent {
+ margin: 5px;
+}
\ No newline at end of file
--- /dev/null
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+classic.jar:
+% skin messenger classic/1.0 %skin/classic/messenger/
+ skin/classic/messenger/glodaFacetView.css (mail/glodaFacetView.css)
+ skin/classic/messenger/multimessageview.css (mail/multimessageview.css)
+ skin/classic/messenger/dialogs.css (mail/dialogs.css)
+ skin/classic/messenger/messenger.css (mail/messenger.css)
+ skin/classic/messenger/primaryToolbar.css (mail/primaryToolbar.css)
+ skin/classic/messenger/aboutSupport.css (../windows/mail/aboutSupport.css)
+ skin/classic/messenger/accountCentral.css (mail/accountCentral.css)
+ skin/classic/messenger/accountCreation.css (mail/accountCreation.css)
+ skin/classic/messenger/accountManage.css (mail/accountManage.css)
+ skin/classic/messenger/accountWizard.css (mail/accountWizard.css)
+* skin/classic/messenger/chat.css (mail/chat.css)
+ skin/classic/messenger/userIcon.png (mail/userIcon.png)
+ skin/classic/messenger/grain.png (mail/grain.png)
+* skin/classic/messenger/imAccounts.css (../../components/im/themes/imAccounts.css)
+* skin/classic/messenger/imAccountWizard.css (../../components/im/themes/imAccountWizard.css)
+ skin/classic/messenger/imBuddytooltip.css (../../components/im/themes/imBuddytooltip.css)
+ skin/classic/messenger/imMenulist.css (../../components/im/themes/imMenulist.css)
+* skin/classic/messenger/imRichlistbox.css (../../components/im/themes/imRichlistbox.css)
+ skin/classic/messenger/imStatus.css (../../components/im/themes/imStatus.css)
+ skin/classic/messenger/founder.png (../../components/im/themes/founder.png)
+ skin/classic/messenger/operator.png (../../components/im/themes/operator.png)
+ skin/classic/messenger/half-operator.png (../../components/im/themes/half-operator.png)
+ skin/classic/messenger/voice.png (../../components/im/themes/voice.png)
+ skin/classic/messenger/browserRequest.css (mail/browserRequest.css)
+ skin/classic/messenger/section_collapsed.png (mail/section_collapsed.png)
+ skin/classic/messenger/section_expanded.png (mail/section_expanded.png)
+ skin/classic/messenger/messageHeader.css (mail/messageHeader.css)
+ skin/classic/messenger/messageWindow.css (mail/messageWindow.css)
+ skin/classic/messenger/messageBody.css (mail/messageBody.css)
+ skin/classic/messenger/webSearch.css (mail/webSearch.css)
+ skin/classic/messenger/attachmentList.css (mail/attachmentList.css)
+ skin/classic/messenger/msgSelectOffline.css (mail/msgSelectOffline.css)
+ skin/classic/messenger/mailWindow1.css (mail/mailWindow1.css)
+ skin/classic/messenger/searchBox.css (mail/searchBox.css)
+ skin/classic/messenger/tagColors.css (mail/tagColors.css)
+ skin/classic/messenger/junkMail.css (mail/junkMail.css)
+ skin/classic/messenger/folderMenus.css (mail/folderMenus.css)
+ skin/classic/messenger/folderPane.css (mail/folderPane.css)
+ skin/classic/messenger/subscribe.css (mail/subscribe.css)
+ skin/classic/messenger/virtualFolderListDialog.css (mail/virtualFolderListDialog.css)
+ skin/classic/messenger/searchDialog.css (mail/searchDialog.css)
+ skin/classic/messenger/filterDialog.css (mail/filterDialog.css)
+ skin/classic/messenger/tabmail.css (mail/tabmail.css)
+ skin/classic/messenger/editContactOverlay.css (mail/editContactOverlay.css)
+ skin/classic/messenger/quickFilterBar.css (mail/quickFilterBar.css)
+ skin/classic/messenger/starred48.png (mail/starred48.png)
+ skin/classic/messenger/starIcons.png (mail/starIcons.png)
+ skin/classic/messenger/starIcons@2x.png (mail/starIcons@2x.png)
+ skin/classic/messenger/activity/activity.css (mail/activity/activity.css)
+ skin/classic/messenger/activity/buttons.png (mail/activity/buttons.png)
+ skin/classic/messenger/activity/defaultProcessIcon.png (mail/activity/defaultProcessIcon.png)
+ skin/classic/messenger/activity/defaultEventIcon.png (mail/activity/defaultEventIcon.png)
+ skin/classic/messenger/activity/defaultWarningIcon.png (mail/activity/defaultWarningIcon.png)
+ skin/classic/messenger/activity/undoIcon.png (mail/activity/undoIcon.png)
+ skin/classic/messenger/activity/syncMailIcon.png (mail/activity/syncMailIcon.png)
+ skin/classic/messenger/activity/sendMailIcon.png (mail/activity/sendMailIcon.png)
+ skin/classic/messenger/activity/removeItemIcon.png (mail/activity/removeItemIcon.png)
+ skin/classic/messenger/activity/addItemIcon.png (mail/activity/addItemIcon.png)
+ skin/classic/messenger/activity/moveMailIcon.png (mail/activity/moveMailIcon.png)
+ skin/classic/messenger/activity/copyMailIcon.png (mail/activity/copyMailIcon.png)
+ skin/classic/messenger/activity/deleteMailIcon.png (mail/activity/deleteMailIcon.png)
+ skin/classic/messenger/activity/compactMailIcon.png (mail/activity/compactMailIcon.png)
+ skin/classic/messenger/activity/indexMailIcon.png (mail/activity/indexMailIcon.png)
+ skin/classic/messenger/addressbook/addressbook.css (mail/addrbook/addressbook.css)
+ skin/classic/messenger/addressbook/abContactsPanel.css (mail/addrbook/abContactsPanel.css)
+ skin/classic/messenger/addressbook/cardDialog.css (mail/addrbook/cardDialog.css)
+ skin/classic/messenger/addressbook/abResultsPane.css (mail/addrbook/abResultsPane.css)
+ skin/classic/messenger/addressbook/icons/abcard.png (mail/addrbook/abcard.png)
+ skin/classic/messenger/addressbook/icons/ablist.png (mail/addrbook/ablist.png)
+ skin/classic/messenger/addressbook/icons/contact-generic.png (mail/addrbook/contact-generic.png)
+ skin/classic/messenger/addressbook/icons/contact-generic@2x.png (mail/addrbook/contact-generic@2x.png)
+ skin/classic/messenger/addressbook/icons/contact-generic-tiny.png (mail/addrbook/contact-generic-tiny.png)
+ skin/classic/messenger/addressbook/icons/contact-generic-tiny@2x.png (mail/addrbook/contact-generic-tiny@2x.png)
+ skin/classic/messenger/addressbook/icons/addressbook-toolbar.png (mail/addrbook/addressbook-toolbar.png)
+ skin/classic/messenger/addressbook/icons/addressbook-toolbar@2x.png (mail/addrbook/addressbook-toolbar@2x.png)
+ skin/classic/messenger/addressbook/icons/addressbook@2x.png (mail/addrbook/addressbook@2x.png)
+ skin/classic/messenger/addressbook/icons/abcard.png (mail/addrbook/abcard.png)
+ skin/classic/messenger/addressbook/icons/ablist.png (mail/addrbook/ablist.png)
+ skin/classic/messenger/addressbook/icons/addrbook.png (mail/addrbook/addrbook.png)
+ skin/classic/messenger/addressbook/icons/remote-addrbook-error.png (mail/addrbook/remote-addrbook-error.png)
+ skin/classic/messenger/addressbook/icons/remote-addrbook.png (mail/addrbook/remote-addrbook.png)
+ skin/classic/messenger/addressbook/icons/secure-remote-addrbook.png (mail/addrbook/secure-remote-addrbook.png)
+ skin/classic/messenger/cloudfile/addAccountDialog.css (mail/cloudfile/addAccountDialog.css)
+ skin/classic/messenger/cloudfile/YouSendIt/settings.css (mail/cloudfile/YouSendIt/settings.css)
+ skin/classic/messenger/cloudfile/YouSendIt/fileExceedsLimit.css (mail/cloudfile/YouSendIt/fileExceedsLimit.css)
+ skin/classic/messenger/cloudfile/YouSendIt/check.png (mail/cloudfile/YouSendIt/check.png)
+ skin/classic/messenger/messengercompose/messengercompose.css (mail/compose/messengercompose.css)
+ skin/classic/messenger/messengercompose/attachmentnotification.png (mail/compose/attachmentnotification.png)
+ skin/classic/messenger/messengercompose/compose-toolbar.png (mail/compose/compose-toolbar.png)
+ skin/classic/messenger/messengercompose/compose-toolbar@2x.png (mail/compose/compose-toolbar@2x.png)
+ skin/classic/messenger/messengercompose/emoticon_cool.png (mail/compose/emoticon_cool.png)
+ skin/classic/messenger/messengercompose/emoticon_cry.png (mail/compose/emoticon_cry.png)
+ skin/classic/messenger/messengercompose/emoticon_embarrassed.png (mail/compose/emoticon_embarrassed.png)
+ skin/classic/messenger/messengercompose/emoticon_foot_in_mouth.png (mail/compose/emoticon_foot_in_mouth.png)
+ skin/classic/messenger/messengercompose/emoticon_frown.png (mail/compose/emoticon_frown.png)
+ skin/classic/messenger/messengercompose/emoticon_innocent.png (mail/compose/emoticon_innocent.png)
+ skin/classic/messenger/messengercompose/emoticon_kiss.png (mail/compose/emoticon_kiss.png)
+ skin/classic/messenger/messengercompose/emoticon_laughing.png (mail/compose/emoticon_laughing.png)
+ skin/classic/messenger/messengercompose/emoticon_money_mouth.png (mail/compose/emoticon_money_mouth.png)
+ skin/classic/messenger/messengercompose/emoticon_sealed.png (mail/compose/emoticon_sealed.png)
+ skin/classic/messenger/messengercompose/emoticon_smile.png (mail/compose/emoticon_smile.png)
+ skin/classic/messenger/messengercompose/emoticon_surprised.png (mail/compose/emoticon_surprised.png)
+ skin/classic/messenger/messengercompose/emoticon_tongue_out.png (mail/compose/emoticon_tongue_out.png)
+ skin/classic/messenger/messengercompose/emoticon_undecided.png (mail/compose/emoticon_undecided.png)
+ skin/classic/messenger/messengercompose/emoticon_wink.png (mail/compose/emoticon_wink.png)
+ skin/classic/messenger/messengercompose/emoticon_yell.png (mail/compose/emoticon_yell.png)
+ skin/classic/messenger/messengercompose/emotes@2x.png (mail/compose/emotes@2x.png)
+ skin/classic/messenger/messengercompose/format-buttons.png (mail/compose/format-buttons.png)
+ skin/classic/messenger/messengercompose/format-buttons@2x.png (mail/compose/format-buttons@2x.png)
+ skin/classic/messenger/messengercompose/insert-menu.png (mail/compose/insert-menu.png)
+ skin/classic/messenger/messengercompose/insert-menu@2x.png (mail/compose/insert-menu@2x.png)
+% skin messenger-newsblog classic/1.0 %skin/classic/messenger-newsblog/
+ skin/classic/messenger-newsblog/feed-subscriptions.css (mail/newsblog/feed-subscriptions.css)
+ skin/classic/messenger-newsblog/rss-feed.png (mail/newsblog/rss-feed.png)
+ skin/classic/messenger-newsblog/rss-feed@2x.png (mail/newsblog/rss-feed@2x.png)
+ skin/classic/messenger/preferences/alwaysAsk.png (mail/preferences/alwaysAsk.png)
+ skin/classic/messenger/preferences/application.png (mail/preferences/application.png)
+ skin/classic/messenger/preferences/saveFile.png (mail/preferences/saveFile.png)
+ skin/classic/messenger/preferences/preferences.css (mail/preferences/preferences.css)
+ skin/classic/messenger/preferences/applications.css (mail/preferences/applications.css)
+ skin/classic/messenger/preferences/mail-options.png (mail/preferences/mail-options.png)
+ skin/classic/messenger/preferences/mail-options@2x.png (mail/preferences/mail-options@2x.png)
+ skin/classic/messenger/preferences/auth-error.png (mail/preferences/auth-error.png)
+ skin/classic/messenger/smime/msgCompSMIMEOverlay.css (mail/smime/msgCompSMIMEOverlay.css)
+ skin/classic/messenger/smime/msgHdrViewSMIMEOverlay.css (mail/smime/msgHdrViewSMIMEOverlay.css)
+ skin/classic/messenger/smime/msgReadSMIMEOverlay.css (mail/smime/msgReadSMIMEOverlay.css)
+ skin/classic/messenger/smime/msgReadSecurityInfo.css (mail/smime/msgReadSecurityInfo.css)
+ skin/classic/messenger/smime/msgCompSecurityInfo.css (mail/smime/msgCompSecurityInfo.css)
+ skin/classic/messenger/smime/certFetchingStatus.css (mail/smime/certFetchingStatus.css)
+ skin/classic/messenger/smime/msgReadSecureHeaders.css (mail/smime/msgReadSecureHeaders.css)
+ skin/classic/messenger/smime/icons/sbSignOk.png (mail/smime/sbSignOk.png)
+ skin/classic/messenger/smime/icons/sbSignUnknown.png (mail/smime/sbSignUnknown.png)
+ skin/classic/messenger/smime/icons/sbSignNotOk.png (mail/smime/sbSignNotOk.png)
+ skin/classic/messenger/smime/icons/sbCryptoOk.png (mail/smime/sbCryptoOk.png)
+ skin/classic/messenger/smime/icons/sbCryptoNotOk.png (mail/smime/sbCryptoNotOk.png)
+ skin/classic/messenger/smime/icons/hdrSignOk.png (mail/smime/hdrSignOk.png)
+ skin/classic/messenger/smime/icons/hdrSignUnknown.png (mail/smime/hdrSignUnknown.png)
+ skin/classic/messenger/smime/icons/hdrSignNotOk.png (mail/smime/hdrSignNotOk.png)
+ skin/classic/messenger/smime/icons/hdrCryptoOk.png (mail/smime/hdrCryptoOk.png)
+ skin/classic/messenger/smime/icons/hdrCryptoNotOk.png (mail/smime/hdrCryptoNotOk.png)
+ skin/classic/messenger/smime/icons/check_sign.png (mail/smime/check_sign.png)
+ skin/classic/messenger/smime/icons/cross_sign.png (mail/smime/cross_sign.png)
+ skin/classic/messenger/smime/icons/unsign.png (mail/smime/unsign.png)
+ skin/classic/messenger/icons/twisty-open.gif (mail/icons/twisty-open.gif)
+ skin/classic/messenger/icons/spin-buttons-active.png (mail/icons/spin-buttons-active.png)
+ skin/classic/messenger/icons/spin-buttons.png (mail/icons/spin-buttons.png)
+ skin/classic/messenger/icons/sidebar-item.png (mail/icons/sidebar-item.png)
+ skin/classic/messenger/icons/appmenu-icons.png (mail/icons/appmenu-icons.png)
+ skin/classic/messenger/icons/appmenu-icons-active.png (mail/icons/appmenu-icons-active.png)
+ skin/classic/messenger/icons/appmenu-icons@2x.png (mail/icons/appmenu-icons@2x.png)
+ skin/classic/messenger/icons/appmenu-icons-active@2x.png (mail/icons/appmenu-icons-active@2x.png)
+ skin/classic/messenger/icons/attachment-deleted.png (mail/icons/attachment-deleted.png)
+ skin/classic/messenger/icons/attachment-deleted-large.png (mail/icons/attachment-deleted-large.png)
+ skin/classic/messenger/icons/attachment-col.png (mail/icons/attachment-col.png)
+ skin/classic/messenger/icons/attachment-selected.png (mail/icons/attachment-selected.png)
+ skin/classic/messenger/icons/attachment.png (mail/icons/attachment.png)
+ skin/classic/messenger/icons/check.png (mail/icons/check.png)
+ skin/classic/messenger/icons/close-inverted.png (mail/icons/close-inverted.png)
+ skin/classic/messenger/icons/close-inverted@2x.png (mail/icons/close-inverted@2x.png)
+ skin/classic/messenger/icons/dot.png (mail/icons/dot.png)
+ skin/classic/messenger/icons/column-headers.png (mail/icons/column-headers.png)
+ skin/classic/messenger/icons/column-headers@2x.png (mail/icons/column-headers@2x.png)
+ skin/classic/messenger/icons/flagcol.png (mail/icons/flagcol.png)
+ skin/classic/messenger/icons/flag-col.png (mail/icons/flag-col.png)
+ skin/classic/messenger/icons/flaggedmail.png (mail/icons/flaggedmail.png)
+ skin/classic/messenger/icons/folder-pane.png (mail/icons/folder-pane.png)
+ skin/classic/messenger/icons/folder-pane@2x.png (mail/icons/folder-pane@2x.png)
+ skin/classic/messenger/icons/exclude.png (mail/icons/exclude.png)
+ skin/classic/messenger/icons/exclude-selected.png (mail/icons/exclude-selected.png)
+ skin/classic/messenger/icons/group-background.gif (mail/icons/group-background.gif)
+ skin/classic/messenger/icons/junk-column-header.png (mail/icons/junk-column-header.png)
+ skin/classic/messenger/icons/mail-toolbar.png (mail/icons/mail-toolbar.png)
+ skin/classic/messenger/icons/mail-toolbar@2x.png (mail/icons/mail-toolbar@2x.png)
+ skin/classic/messenger/icons/message-mail-attach.png (mail/icons/message-mail-attach.png)
+ skin/classic/messenger/icons/message-mail-imapdelete.png (mail/icons/message-mail-imapdelete.png)
+ skin/classic/messenger/icons/message-mail-new.png (mail/icons/message-mail-new.png)
+ skin/classic/messenger/icons/message-mail.png (mail/icons/message-mail.png)
+ skin/classic/messenger/icons/message-news-attach-offl.png (mail/icons/message-news-attach-offl.png)
+ skin/classic/messenger/icons/message-news-attach.png (mail/icons/message-news-attach.png)
+ skin/classic/messenger/icons/message-news-new-attach.png (mail/icons/message-news-new-attach.png)
+ skin/classic/messenger/icons/message-news-new.png (mail/icons/message-news-new.png)
+ skin/classic/messenger/icons/toolbarbutton-dropmarker.png (mail/icons/toolbarbutton-dropmarker.png)
+ skin/classic/messenger/icons/toolbarbutton-dropmarker-lion.png (mail/icons/toolbarbutton-dropmarker-lion.png)
+ skin/classic/messenger/icons/toolbarbutton-dropmarker-lion@2x.png (mail/icons/toolbarbutton-dropmarker-lion@2x.png)
+ skin/classic/messenger/icons/readcol.png (mail/icons/readcol.png)
+ skin/classic/messenger/icons/readmail.png (mail/icons/readmail.png)
+ skin/classic/messenger/icons/secure.png (mail/icons/secure.png)
+ skin/classic/messenger/icons/server.png (mail/icons/server.png)
+ skin/classic/messenger/icons/server@2x.png (mail/icons/server@2x.png)
+ skin/classic/messenger/icons/update.png (mail/icons/update.png)
+ skin/classic/messenger/icons/insecure.png (mail/icons/insecure.png)
+ skin/classic/messenger/icons/identity.png (mail/icons/identity.png)
+ skin/classic/messenger/icons/identity@2x.png (mail/icons/identity@2x.png)
+ skin/classic/messenger/icons/item.png (mail/icons/item.png)
+ skin/classic/messenger/icons/error.png (mail/icons/error.png)
+ skin/classic/messenger/icons/symbol-forwarded.png (mail/icons/symbol-forwarded.png)
+ skin/classic/messenger/icons/symbol-forwarded-selected.png (mail/icons/symbol-forwarded-selected.png)
+ skin/classic/messenger/icons/symbol-replied.png (mail/icons/symbol-replied.png)
+ skin/classic/messenger/icons/symbol-replied-selected.png (mail/icons/symbol-replied-selected.png)
+ skin/classic/messenger/icons/symbol-replied-forwarded.png (mail/icons/symbol-replied-forwarded.png)
+ skin/classic/messenger/icons/symbol-replied-forwarded-selected.png (mail/icons/symbol-replied-forwarded-selected.png)
+ skin/classic/messenger/icons/symbol-imapdeleted.png (mail/icons/symbol-imapdeleted.png)
+ skin/classic/messenger/icons/symbol-imapdeleted-selected.png (mail/icons/symbol-imapdeleted-selected.png)
+ skin/classic/messenger/icons/symbol-null.png (mail/icons/symbol-null.png)
+ skin/classic/messenger/icons/thread-closed-eye.png (mail/icons/thread-closed-eye.png)
+ skin/classic/messenger/icons/thread-closed-kill.png (mail/icons/thread-closed-kill.png)
+ skin/classic/messenger/icons/message-closed-kill.png (mail/icons/message-closed-kill.png)
+ skin/classic/messenger/icons/thread-closed-selected.png (mail/icons/thread-closed-selected.png)
+ skin/classic/messenger/icons/thread-closed.png (mail/icons/thread-closed.png)
+ skin/classic/messenger/icons/thread-new-closed.png (mail/icons/thread-new-closed.png)
+ skin/classic/messenger/icons/threadcol.png (mail/icons/threadcol.png)
+ skin/classic/messenger/icons/threadpane-col.png (mail/icons/threadpane-col.png)
+ skin/classic/messenger/icons/threadpane-col@2x.png (mail/icons/threadpane-col@2x.png)
+ skin/classic/messenger/icons/threadpane-splitter-bg.gif (mail/icons/threadpane-splitter-bg.gif)
+ skin/classic/messenger/icons/vertical-threadpane-splitter-bg.gif (mail/icons/vertical-threadpane-splitter-bg.gif)
+ skin/classic/messenger/icons/vertical-threadpane-splitter-bg-rtl.gif (mail/icons/vertical-threadpane-splitter-bg-rtl.gif)
+ skin/classic/messenger/icons/unreadmail-selected.png (mail/icons/unreadmail-selected.png)
+ skin/classic/messenger/icons/unreadmail.png (mail/icons/unreadmail.png)
+ skin/classic/messenger/icons/unthreadcol.png (mail/icons/unthreadcol.png)
+ skin/classic/messenger/icons/online.png (mail/icons/online.png)
+ skin/classic/messenger/icons/online@2x.png (mail/icons/online@2x.png)
+ skin/classic/messenger/icons/offline.png (mail/icons/offline.png)
+ skin/classic/messenger/icons/offline@2x.png (mail/icons/offline@2x.png)
+ skin/classic/messenger/icons/warning.png (mail/icons/warning.png)
+ skin/classic/messenger/icons/arrow-dn-7.png (mail/icons/arrow-dn-7.png)
+ skin/classic/messenger/icons/zoomout.png (mail/icons/zoomout.png)
+ skin/classic/messenger/icons/zoomout-hover.png (mail/icons/zoomout-hover.png)
+ skin/classic/messenger/icons/timeline.png (mail/icons/timeline.png)
+ skin/classic/messenger/icons/timeline-inverted.png (mail/icons/timeline-inverted.png)
+ skin/classic/messenger/icons/empty-search-results.png (mail/icons/empty-search-results.png)
+ skin/classic/messenger/icons/QFB-toolbar.png (mail/icons/QFB-toolbar.png)
+ skin/classic/messenger/icons/QFB-toolbar@2x.png (mail/icons/QFB-toolbar@2x.png)
+ skin/classic/messenger/icons/search-tab.png (mail/icons/search-tab.png)
+ skin/classic/messenger/icons/search-tab@2x.png (mail/icons/search-tab@2x.png)
+ skin/classic/messenger/icons/chat-toolbar.png (mail/icons/chat-toolbar.png)
+ skin/classic/messenger/icons/chat-toolbar@2x.png (mail/icons/chat-toolbar@2x.png)
+ skin/classic/messenger/icons/status.png (mail/icons/status.png)
+ skin/classic/messenger/icons/status@2x.png (mail/icons/status@2x.png)
+ skin/classic/messenger/icons/status-small.png (mail/icons/status-small.png)
+ skin/classic/messenger/icons/status-small@2x.png (mail/icons/status-small@2x.png)
+ skin/classic/messenger/icons/connecting.png (mail/icons/connecting.png)
+ skin/classic/messenger/icons/loading.png (mail/icons/loading.png)
+ skin/classic/messenger/icons/loading@2x.png (mail/icons/loading@2x.png)
+ skin/classic/messenger/tabs/alltabs-box-bkgnd-icon.png (mail/tabs/alltabs-box-bkgnd-icon.png)
+ skin/classic/messenger/tabs/alltabs-box-bkgnd-icon@2x.png (mail/tabs/alltabs-box-bkgnd-icon@2x.png)
+ skin/classic/messenger/tabs/alltabs-box-overflow-bkgnd-animate.png (mail/tabs/alltabs-box-overflow-bkgnd-animate.png)
+ skin/classic/messenger/tabs/newtab.png (mail/tabs/newtab.png)
+ skin/classic/messenger/tabs/tabDragIndicator.png (mail/tabs/tabDragIndicator.png)
+ skin/classic/messenger/tabs/tab-arrow.png (mail/tabs/tab-arrow.png)
+ skin/classic/messenger/tabs/tab-arrow@2x.png (mail/tabs/tab-arrow@2x.png)
+ skin/classic/messenger/tabs/tabActiveEnd.png (mail/tabs/tabActiveEnd.png)
+ skin/classic/messenger/tabs/tabActiveEnd@2x.png (mail/tabs/tabActiveEnd@2x.png)
+ skin/classic/messenger/tabs/tabActiveMiddle.png (mail/tabs/tabActiveMiddle.png)
+ skin/classic/messenger/tabs/tabActiveMiddle@2x.png (mail/tabs/tabActiveMiddle@2x.png)
+ skin/classic/messenger/tabs/tabActiveStart.png (mail/tabs/tabActiveStart.png)
+ skin/classic/messenger/tabs/tabActiveStart@2x.png (mail/tabs/tabActiveStart@2x.png)
+ skin/classic/messenger/tabs/tabHoverEnd.png (mail/tabs/tabHoverEnd.png)
+ skin/classic/messenger/tabs/tabHoverEnd@2x.png (mail/tabs/tabHoverEnd@2x.png)
+ skin/classic/messenger/tabs/tabHoverMiddle.png (mail/tabs/tabHoverMiddle.png)
+ skin/classic/messenger/tabs/tabHoverMiddle@2x.png (mail/tabs/tabHoverMiddle@2x.png)
+ skin/classic/messenger/tabs/tabHoverStart.png (mail/tabs/tabHoverStart.png)
+ skin/classic/messenger/tabs/tabHoverStart@2x.png (mail/tabs/tabHoverStart@2x.png)
+ skin/classic/messenger/tabs/tabInactiveEnd.png (mail/tabs/tabInactiveEnd.png)
+ skin/classic/messenger/tabs/tabInactiveEnd@2x.png (mail/tabs/tabInactiveEnd@2x.png)
+ skin/classic/messenger/tabs/tabInactiveMiddle.png (mail/tabs/tabInactiveMiddle.png)
+ skin/classic/messenger/tabs/tabInactiveMiddle@2x.png (mail/tabs/tabInactiveMiddle@2x.png)
+ skin/classic/messenger/tabs/tabInactiveStart.png (mail/tabs/tabInactiveStart.png)
+ skin/classic/messenger/tabs/tabInactiveStart@2x.png (mail/tabs/tabInactiveStart@2x.png)
+ skin/classic/messenger/accountcentral/accountsettings.png (mail/accountcentral/accountsettings.png)
+ skin/classic/messenger/accountcentral/accountsettings@2x.png (mail/accountcentral/accountsettings@2x.png)
+ skin/classic/messenger/accountcentral/folder.png (mail/accountcentral/folder.png)
+ skin/classic/messenger/accountcentral/folder@2x.png (mail/accountcentral/folder@2x.png)
+ skin/classic/messenger/accountcentral/junk.png (mail/accountcentral/junk.png)
+ skin/classic/messenger/accountcentral/junk@2x.png (mail/accountcentral/junk@2x.png)
+ skin/classic/messenger/accountcentral/mailbox.png (mail/accountcentral/mailbox.png)
+ skin/classic/messenger/accountcentral/mailbox@2x.png (mail/accountcentral/mailbox@2x.png)
+ skin/classic/messenger/accountcentral/newaccount.png (mail/accountcentral/newaccount.png)
+ skin/classic/messenger/accountcentral/newaccount@2x.png (mail/accountcentral/newaccount@2x.png)
+ skin/classic/messenger/accountcentral/offline.png (mail/accountcentral/offline.png)
+ skin/classic/messenger/accountcentral/offline@2x.png (mail/accountcentral/offline@2x.png)
+ skin/classic/messenger/accountcentral/search-messages.png (mail/accountcentral/search-messages.png)
+ skin/classic/messenger/accountcentral/search-messages@2x.png (mail/accountcentral/search-messages@2x.png)
+ skin/classic/messenger/accountcentral/manage-subscriptions.png (mail/accountcentral/manage-subscriptions.png)
+ skin/classic/messenger/accountcentral/manage-rss.png (mail/accountcentral/manage-rss.png)
+ skin/classic/messenger/accountcentral/manage-rss@2x.png (mail/accountcentral/manage-rss@2x.png)
+ skin/classic/messenger/accountcentral/writemail.png (mail/accountcentral/writemail.png)
+ skin/classic/messenger/accountcentral/writemail@2x.png (mail/accountcentral/writemail@2x.png)
+% skin communicator classic/1.0 %skin/classic/communicator/
+ skin/classic/communicator/communicator.css (mail/communicator.css)
+ skin/classic/communicator/smileys.css (mail/smileys.css)
+ skin/classic/communicator/icons/smileys/smiley-smile.png (mail/icons/smiley-smile.png)
+ skin/classic/communicator/icons/smileys/smiley-frown.png (mail/icons/smiley-frown.png)
+ skin/classic/communicator/icons/smileys/smiley-wink.png (mail/icons/smiley-wink.png)
+ skin/classic/communicator/icons/smileys/smiley-tongue-out.png (mail/icons/smiley-tongue-out.png)
+ skin/classic/communicator/icons/smileys/smiley-laughing.png (mail/icons/smiley-laughing.png)
+ skin/classic/communicator/icons/smileys/smiley-embarassed.png (mail/icons/smiley-embarassed.png)
+ skin/classic/communicator/icons/smileys/smiley-undecided.png (mail/icons/smiley-undecided.png)
+ skin/classic/communicator/icons/smileys/smiley-surprised.png (mail/icons/smiley-surprised.png)
+ skin/classic/communicator/icons/smileys/smiley-kiss.png (mail/icons/smiley-kiss.png)
+ skin/classic/communicator/icons/smileys/smiley-yell.png (mail/icons/smiley-yell.png)
+ skin/classic/communicator/icons/smileys/smiley-cool.png (mail/icons/smiley-cool.png)
+ skin/classic/communicator/icons/smileys/smiley-money-mouth.png (mail/icons/smiley-money-mouth.png)
+ skin/classic/communicator/icons/smileys/smiley-foot-in-mouth.png (mail/icons/smiley-foot-in-mouth.png)
+ skin/classic/communicator/icons/smileys/smiley-innocent.png (mail/icons/smiley-innocent.png)
+ skin/classic/communicator/icons/smileys/smiley-cry.png (mail/icons/smiley-cry.png)
+ skin/classic/communicator/icons/smileys/smiley-sealed.png (mail/icons/smiley-sealed.png)
+ skin/classic/messenger/icons/arrow-dn-grey.png (mail/icons/arrow-dn-grey.png)
+ skin/classic/messenger/icons/arrow-dn-black.png (mail/icons/arrow-dn-black.png)
+ skin/classic/messenger/icons/arrow-dn-blue.png (mail/icons/arrow-dn-blue.png)
+ skin/classic/messenger/icons/arrow/arrow-left.png (mail/icons/arrow/arrow-left.png)
+ skin/classic/messenger/icons/arrow/arrow-right.png (mail/icons/arrow/arrow-right.png)
+ skin/classic/messenger/icons/arrow/arrow-up.png (mail/icons/arrow/arrow-up.png)
+ skin/classic/messenger/icons/arrow/arrow-down.png (mail/icons/arrow/arrow-down.png)
+ skin/classic/messenger/icons/arrow/arrow-left-dim.png (mail/icons/arrow/arrow-left-dim.png)
+ skin/classic/messenger/icons/arrow/arrow-right-dim.png (mail/icons/arrow/arrow-right-dim.png)
+ skin/classic/messenger/icons/arrow/arrow-up-dim.png (mail/icons/arrow/arrow-up-dim.png)
+ skin/classic/messenger/icons/arrow/arrow-down-dim.png (mail/icons/arrow/arrow-down-dim.png)
+ skin/classic/messenger/icons/search-favorite.png (mail/icons/search-favorite.png)
+ skin/classic/messenger/tagbg.png (mail/tagbg.png)
+ skin/classic/messenger/icons/download.png (mail/icons/download.png)
+% skin editor classic/1.0 %skin/classic/editor/
+ skin/classic/editor/editor.css (editor/editor.css)
+ skin/classic/editor/EditorDialog.css (editor/EditorDialog.css)
+ skin/classic/editor/icons/img-align-bottom.gif (editor/img-align-bottom.gif)
+ skin/classic/editor/icons/img-align-left.gif (editor/img-align-left.gif)
+ skin/classic/editor/icons/img-align-middle.gif (editor/img-align-middle.gif)
+ skin/classic/editor/icons/img-align-right.gif (editor/img-align-right.gif)
+ skin/classic/editor/icons/img-align-top.gif (editor/img-align-top.gif)
+ skin/classic/messenger/newmailaccount/accountProvisioner.css (mail/newmailaccount/accountProvisioner.css)
+ skin/classic/messenger/newmailaccount/search.gif (mail/newmailaccount/search.gif)
+ skin/classic/messenger/newmailaccount/spinner.gif (mail/newmailaccount/spinner.gif)
+ skin/classic/messenger/newmailaccount/success-addons.png (mail/newmailaccount/success-addons.png)
+ skin/classic/messenger/newmailaccount/success-border.png (mail/newmailaccount/success-border.png)
+ skin/classic/messenger/newmailaccount/success-compose.png (mail/newmailaccount/success-compose.png)
+ skin/classic/messenger/newmailaccount/success-signature.png (mail/newmailaccount/success-signature.png)
+ skin/classic/messenger/newmailaccount/search.png (mail/newmailaccount/search.png)
+ skin/classic/messenger/icons/ubuntuone.png (mail/icons/ubuntuone.png)
+ skin/classic/messenger/icons/yousendit.png (mail/icons/yousendit.png)
+ skin/classic/messenger/places/expander-closed.png (places/expander-closed.png)
+ skin/classic/messenger/places/expander-closed-active.png (places/expander-closed-active.png)
+ skin/classic/messenger/places/expander-open.png (places/expander-open.png)
+ skin/classic/messenger/places/expander-open-active.png (places/expander-open-active.png)
+ skin/classic/messenger/sanitizeDialog.css (mail/sanitizeDialog.css)
+ skin/classic/messenger/icons/box-logo.png (mail/icons/box-logo.png)
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+#signedHdrIcon {
+ list-style-image: none;
+ visibility: visible;
+}
+
+#signedHdrIcon[signed="ok"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrSignOk.png");
+ visibility: visible;
+}
+
+#signedHdrIcon[signed="unknown"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrSignUnknown.png");
+ visibility: visible;
+}
+
+#signedHdrIcon[signed="mismatch"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrSignUnknown.png");
+ visibility: visible;
+}
+
+#signedHdrIcon[signed="notok"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrSignNotOk.png");
+ visibility: visible;
+}
+
+#encryptedHdrIcon {
+ list-style-image: none;
+ visibility: visible;
+}
+
+#encryptedHdrIcon[encrypted="ok"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrCryptoOk.png");
+ visibility: visible;
+}
+
+#encryptedHdrIcon[encrypted="notok"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrCryptoNotOk.png");
+ visibility: visible;
+}
+
+#secureinfomsgh,
+#secureinfomsgh2{
+ margin-top:2px;
+ margin-bottom:2px;
+ padding-left:5px;
+ background-color:#ffffcc;
+}
+
+#secureinfomsgh[signed="notok"],#secureinfomsgh2[signed="notok"]{background-color:#ff5959;}
+#secureinfomsgh[signed="ok"],#secureinfomsgh2[signed="ok"]{background-color:#CAFF70;}
+#secureinfomsgh[signed="warning"],#secureinfomsgh2[signed="warning"]{background-color:#E76914;}
+
+#secureinfomsg label,
+#secureinfomsg2 label{
+ font-weight: bold;
+ cursor: pointer;
+}
+#secureinfomsg label:hover,
+#secureinfomsg2 label:hover{
+ color: #00007f;
+}
\ No newline at end of file
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. \r
+ * Contributor(s): \r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */\r
+\r
+/* ===== msgReadSecureHeaders.css ========================================\r
+ == Styles for the secure headers info window when displaying received mail.\r
+ ======================================================================= */\r
+\r
+@import url("chrome://messenger/skin/");\r
+\r
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");\r
+\r
+#secHeader_treechild_id::-moz-tree-row(selected){ \r
+ background-color: DarkGray;\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-row(odd){ \r
+ background-color: #EEEEEE;\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-row(odd, selected){ \r
+ background-color: DarkGray;\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-cell-text(valid){ \r
+ color: green;\r
+}\r
+#secHeader_treechild_id::-moz-tree-cell-text(invalid){ \r
+ color: #b10000;\r
+ font-weight: bold;\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-cell-text(unsigned){ \r
+ color: #E76914; \r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-image(valid){\r
+ list-style-image: url("chrome://messenger/skin/smime/icons/check_sign.png");\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-image(invalid){\r
+ list-style-image: url("chrome://messenger/skin/smime/icons/cross_sign.png");\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-image(unsigned){\r
+ list-style-image: url("chrome://messenger/skin/smime/icons/unsign.png");\r
+}
\ No newline at end of file
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* ===== msgReadSecurityInfo.css ========================================
+ == Styles for the security info window when displaying received mail.
+ ======================================================================= */
+
+@import url("chrome://messenger/skin/");
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+#signatureLabel {
+ font-weight: bold;
+}
+
+#signatureCert {
+ margin: 5px;
+}
+
+#encryptionLabel {
+ font-weight: bold;
+}
+
+#encryptionCert {
+ margin: 5px;
+}
+
+#securityLabel {
+ font-weight: bold;
+}
+
+#securityLabelContent {
+ margin: 5px;
+}
\ No newline at end of file
--- /dev/null
+classic.jar:
+% skin editor classic/1.0 %skin/classic/editor/
+ skin/classic/editor/editor.css (editor/editor.css)
+ skin/classic/editor/EditorDialog.css (editor/EditorDialog.css)
+ skin/classic/editor/icons/img-align-bottom.gif (editor/img-align-bottom.gif)
+ skin/classic/editor/icons/img-align-left.gif (editor/img-align-left.gif)
+ skin/classic/editor/icons/img-align-middle.gif (editor/img-align-middle.gif)
+ skin/classic/editor/icons/img-align-right.gif (editor/img-align-right.gif)
+ skin/classic/editor/icons/img-align-top.gif (editor/img-align-top.gif)
+
+# ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
+# ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
+#
+# If you add a new file here, you'll need to add it to the aero section at the
+# bottom of this file, too. If you do not, people using Windows prior to Vista
+# will be able to enjoy your additions, but people using Vista and above will
+# not.
+#
+# ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
+# ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION! ATTENTION!
+
+% skin communicator classic/1.0 %skin/classic/communicator/ os=WINNT osversion<6
+% skin communicator classic/1.0 %skin/classic/communicator/ os!=WINNT
+ skin/classic/communicator/communicator.css (mail/communicator.css)
+ skin/classic/communicator/smileys.css (mail/smileys.css)
+ skin/classic/communicator/icons/smileys/smiley-smile.png (mail/icons/smiley-smile.png)
+ skin/classic/communicator/icons/smileys/smiley-frown.png (mail/icons/smiley-frown.png)
+ skin/classic/communicator/icons/smileys/smiley-wink.png (mail/icons/smiley-wink.png)
+ skin/classic/communicator/icons/smileys/smiley-tongue-out.png (mail/icons/smiley-tongue-out.png)
+ skin/classic/communicator/icons/smileys/smiley-laughing.png (mail/icons/smiley-laughing.png)
+ skin/classic/communicator/icons/smileys/smiley-embarassed.png (mail/icons/smiley-embarassed.png)
+ skin/classic/communicator/icons/smileys/smiley-undecided.png (mail/icons/smiley-undecided.png)
+ skin/classic/communicator/icons/smileys/smiley-surprised.png (mail/icons/smiley-surprised.png)
+ skin/classic/communicator/icons/smileys/smiley-kiss.png (mail/icons/smiley-kiss.png)
+ skin/classic/communicator/icons/smileys/smiley-yell.png (mail/icons/smiley-yell.png)
+ skin/classic/communicator/icons/smileys/smiley-cool.png (mail/icons/smiley-cool.png)
+ skin/classic/communicator/icons/smileys/smiley-money-mouth.png (mail/icons/smiley-money-mouth.png)
+ skin/classic/communicator/icons/smileys/smiley-foot-in-mouth.png (mail/icons/smiley-foot-in-mouth.png)
+ skin/classic/communicator/icons/smileys/smiley-innocent.png (mail/icons/smiley-innocent.png)
+ skin/classic/communicator/icons/smileys/smiley-cry.png (mail/icons/smiley-cry.png)
+ skin/classic/communicator/icons/smileys/smiley-sealed.png (mail/icons/smiley-sealed.png)
+% skin messenger classic/1.0 %skin/classic/messenger/ os=WINNT osversion<6
+% skin messenger classic/1.0 %skin/classic/messenger/ os!=WINNT
+ skin/classic/messenger/primaryToolbar.css (mail/primaryToolbar.css)
+ skin/classic/messenger/aboutSupport.css (mail/aboutSupport.css)
+ skin/classic/messenger/accountCentral.css (mail/accountCentral.css)
+ skin/classic/messenger/accountCreation.css (mail/accountCreation.css)
+ skin/classic/messenger/accountManage.css (mail/accountManage.css)
+ skin/classic/messenger/accountWizard.css (mail/accountWizard.css)
+* skin/classic/messenger/chat.css (mail/chat.css)
+ skin/classic/messenger/userIcon.png (mail/userIcon.png)
+ skin/classic/messenger/grain.png (mail/grain.png)
+* skin/classic/messenger/imAccounts.css (../../components/im/themes/imAccounts.css)
+* skin/classic/messenger/imAccountWizard.css (../../components/im/themes/imAccountWizard.css)
+ skin/classic/messenger/imBuddytooltip.css (../../components/im/themes/imBuddytooltip.css)
+ skin/classic/messenger/imMenulist.css (../../components/im/themes/imMenulist.css)
+* skin/classic/messenger/imRichlistbox.css (../../components/im/themes/imRichlistbox.css)
+ skin/classic/messenger/imStatus.css (../../components/im/themes/imStatus.css)
+ skin/classic/messenger/founder.png (../../components/im/themes/founder.png)
+ skin/classic/messenger/operator.png (../../components/im/themes/operator.png)
+ skin/classic/messenger/half-operator.png (../../components/im/themes/half-operator.png)
+ skin/classic/messenger/voice.png (../../components/im/themes/voice.png)
+ skin/classic/messenger/browserRequest.css (mail/browserRequest.css)
+ skin/classic/messenger/section_collapsed.png (mail/section_collapsed.png)
+ skin/classic/messenger/section_expanded.png (mail/section_expanded.png)
+ skin/classic/messenger/messageHeader.css (mail/messageHeader.css)
+ skin/classic/messenger/messageBody.css (mail/messageBody.css)
+ skin/classic/messenger/webSearch.css (mail/webSearch.css)
+ skin/classic/messenger/messageQuotes.css (mail/messageQuotes.css)
+ skin/classic/messenger/messenger.css (mail/messenger.css)
+ skin/classic/messenger/attachmentList.css (mail/attachmentList.css)
+ skin/classic/messenger/imageFilters.svg (mail/imageFilters.svg)
+ skin/classic/messenger/mailWindow1.css (mail/mailWindow1.css)
+ skin/classic/messenger/tagColors.css (mail/tagColors.css)
+ skin/classic/messenger/messageWindow.css (mail/messageWindow.css)
+ skin/classic/messenger/searchBox.css (mail/searchBox.css)
+ skin/classic/messenger/junkMail.css (mail/junkMail.css)
+ skin/classic/messenger/folderMenus.css (mail/folderMenus.css)
+ skin/classic/messenger/folderPane.css (mail/folderPane.css)
+ skin/classic/messenger/subscribe.css (mail/subscribe.css)
+ skin/classic/messenger/virtualFolderListDialog.css (mail/virtualFolderListDialog.css)
+ skin/classic/messenger/searchDialog.css (mail/searchDialog.css)
+ skin/classic/messenger/msgSelectOffline.css (mail/msgSelectOffline.css)
+ skin/classic/messenger/filterDialog.css (mail/filterDialog.css)
+ skin/classic/messenger/dialogs.css (mail/dialogs.css)
+ skin/classic/messenger/multimessageview.css (mail/multimessageview.css)
+ skin/classic/messenger/glodaFacetView.css (mail/glodaFacetView.css)
+ skin/classic/messenger/icons/exclude.png (mail/icons/exclude.png)
+ skin/classic/messenger/icons/exclude-selected.png (mail/icons/exclude-selected.png)
+ skin/classic/messenger/newmailalert.css (mail/newmailalert.css)
+ skin/classic/messenger/tabmail.css (mail/tabmail.css)
+ skin/classic/messenger/editContactOverlay.css (mail/editContactOverlay.css)
+ skin/classic/messenger/quickFilterBar.css (mail/quickFilterBar.css)
+ skin/classic/messenger/starred48.png (mail/starred48.png)
+ skin/classic/messenger/contactStarred.png (mail/contactStarred.png)
+ skin/classic/messenger/starContact.png (mail/starContact.png)
+ skin/classic/messenger/activity/activity.css (mail/activity/activity.css)
+ skin/classic/messenger/activity/buttons.png (mail/activity/buttons.png)
+ skin/classic/messenger/activity/defaultProcessIcon.png (mail/activity/defaultProcessIcon.png)
+ skin/classic/messenger/activity/defaultEventIcon.png (mail/activity/defaultEventIcon.png)
+ skin/classic/messenger/activity/defaultWarningIcon.png (mail/activity/defaultWarningIcon.png)
+ skin/classic/messenger/activity/undoIcon.png (mail/activity/undoIcon.png)
+ skin/classic/messenger/activity/syncMailIcon.png (mail/activity/syncMailIcon.png)
+ skin/classic/messenger/activity/sendMailIcon.png (mail/activity/sendMailIcon.png)
+ skin/classic/messenger/activity/removeItemIcon.png (mail/activity/removeItemIcon.png)
+ skin/classic/messenger/activity/addItemIcon.png (mail/activity/addItemIcon.png)
+ skin/classic/messenger/activity/moveMailIcon.png (mail/activity/moveMailIcon.png)
+ skin/classic/messenger/activity/copyMailIcon.png (mail/activity/copyMailIcon.png)
+ skin/classic/messenger/activity/deleteMailIcon.png (mail/activity/deleteMailIcon.png)
+ skin/classic/messenger/activity/compactMailIcon.png (mail/activity/compactMailIcon.png)
+ skin/classic/messenger/activity/indexMailIcon.png (mail/activity/indexMailIcon.png)
+ skin/classic/messenger/addressbook/addressbook.css (mail/addrbook/addressbook.css)
+ skin/classic/messenger/addressbook/abContactsPanel.css (mail/addrbook/abContactsPanel.css)
+ skin/classic/messenger/addressbook/cardDialog.css (mail/addrbook/cardDialog.css)
+ skin/classic/messenger/addressbook/abResultsPane.css (mail/addrbook/abResultsPane.css)
+ skin/classic/messenger/addressbook/icons/abcard.png (mail/addrbook/abcard.png)
+ skin/classic/messenger/addressbook/icons/addrbook.png (mail/addrbook/addrbook.png)
+ skin/classic/messenger/addressbook/icons/ablist.png (mail/addrbook/ablist.png)
+ skin/classic/messenger/addressbook/icons/contact-generic.png (mail/addrbook/contact-generic.png)
+ skin/classic/messenger/addressbook/icons/contact-generic-tiny.png (mail/addrbook/contact-generic-tiny.png)
+ skin/classic/messenger/addressbook/icons/addressbook-toolbar.png (mail/addrbook/addressbook-toolbar.png)
+ skin/classic/messenger/addressbook/icons/addressbook-toolbar-small.png (mail/addrbook/addressbook-toolbar-small.png)
+ skin/classic/messenger/addressbook/icons/abcard-large.png (mail/addrbook/abcard-large.png)
+ skin/classic/messenger/addressbook/icons/remote-addrbook.png (mail/addrbook/remote-addrbook.png)
+ skin/classic/messenger/addressbook/icons/remote-addrbook-error.png (mail/addrbook/remote-addrbook-error.png)
+ skin/classic/messenger/addressbook/icons/secure-remote-addrbook.png (mail/addrbook/secure-remote-addrbook.png)
+ skin/classic/messenger/cloudfile/addAccountDialog.css (mail/cloudfile/addAccountDialog.css)
+ skin/classic/messenger/cloudfile/YouSendIt/settings.css (mail/cloudfile/YouSendIt/settings.css)
+ skin/classic/messenger/cloudfile/YouSendIt/fileExceedsLimit.css (mail/cloudfile/YouSendIt/fileExceedsLimit.css)
+ skin/classic/messenger/cloudfile/YouSendIt/check.png (mail/cloudfile/YouSendIt/check.png)
+ skin/classic/messenger/messengercompose/messengercompose.css (mail/compose/messengercompose.css)
+ skin/classic/messenger/messengercompose/compose-toolbar.png (mail/compose/compose-toolbar.png)
+ skin/classic/messenger/messengercompose/compose-toolbar-small.png (mail/compose/compose-toolbar-small.png)
+ skin/classic/messenger/messengercompose/format-buttons.png (mail/compose/format-buttons.png)
+ skin/classic/messenger/preferences/alwaysAsk.png (mail/preferences/alwaysAsk.png)
+ skin/classic/messenger/preferences/application.png (mail/preferences/application.png)
+ skin/classic/messenger/preferences/preferences.css (mail/preferences/preferences.css)
+ skin/classic/messenger/preferences/general.png (mail/preferences/general.png)
+ skin/classic/messenger/preferences/display.png (mail/preferences/display.png)
+ skin/classic/messenger/preferences/composition.png (mail/preferences/composition.png)
+ skin/classic/messenger/preferences/security.png (mail/preferences/security.png)
+ skin/classic/messenger/preferences/attachments.png (mail/preferences/attachments.png)
+ skin/classic/messenger/preferences/applications.css (mail/preferences/applications.css)
+ skin/classic/messenger/preferences/saveFile.png (mail/preferences/saveFile.png)
+ skin/classic/messenger/preferences/advanced.png (mail/preferences/advanced.png)
+ skin/classic/messenger/preferences/chat.png (mail/preferences/chat.png)
+ skin/classic/messenger/preferences/background.png (mail/preferences/background.png)
+ skin/classic/messenger/preferences/hover.png (mail/preferences/hover.png)
+ skin/classic/messenger/preferences/selected.png (mail/preferences/selected.png)
+ skin/classic/messenger/preferences/auth-error.png (mail/preferences/auth-error.png)
+ skin/classic/messenger/smime/msgCompSMIMEOverlay.css (mail/smime/msgCompSMIMEOverlay.css)
+ skin/classic/messenger/smime/msgHdrViewSMIMEOverlay.css (mail/smime/msgHdrViewSMIMEOverlay.css)
+ skin/classic/messenger/smime/msgReadSMIMEOverlay.css (mail/smime/msgReadSMIMEOverlay.css)
+ skin/classic/messenger/smime/msgReadSecurityInfo.css (mail/smime/msgReadSecurityInfo.css)
+ skin/classic/messenger/smime/msgCompSecurityInfo.css (mail/smime/msgCompSecurityInfo.css)
+ skin/classic/messenger/smime/certFetchingStatus.css (mail/smime/certFetchingStatus.css)
+ skin/classic/messenger/smime/msgReadSecureHeaders.css (mail/smime/msgReadSecureHeaders.css)
+ skin/classic/messenger/smime/icons/hdrCryptoNotOk.png (mail/smime/hdrCryptoNotOk.png)
+ skin/classic/messenger/smime/icons/hdrCryptoOk.png (mail/smime/hdrCryptoOk.png)
+ skin/classic/messenger/smime/icons/hdrSignNotOk.png (mail/smime/hdrSignNotOk.png)
+ skin/classic/messenger/smime/icons/hdrSignOk.png (mail/smime/hdrSignOk.png)
+ skin/classic/messenger/smime/icons/hdrSignUnknown.png (mail/smime/hdrSignUnknown.png)
+ skin/classic/messenger/smime/icons/sbCryptoNotOk.png (mail/smime/sbCryptoNotOk.png)
+ skin/classic/messenger/smime/icons/sbCryptoOk.png (mail/smime/sbCryptoOk.png)
+ skin/classic/messenger/smime/icons/sbSignNotOk.png (mail/smime/sbSignNotOk.png)
+ skin/classic/messenger/smime/icons/sbSignOk.png (mail/smime/sbSignOk.png)
+ skin/classic/messenger/smime/icons/sbSignUnknown.png (mail/smime/sbSignUnknown.png)
+ skin/classic/messenger/smime/icons/check_sign.png (mail/smime/check_sign.png)
+ skin/classic/messenger/smime/icons/cross_sign.png (mail/smime/cross_sign.png)
+ skin/classic/messenger/smime/icons/unsign.png (mail/smime/unsign.png)
+ skin/classic/messenger/icons/zoomout.png (mail/icons/zoomout.png)
+ skin/classic/messenger/icons/zoomout-hover.png (mail/icons/zoomout-hover.png)
+ skin/classic/messenger/icons/readmail.png (mail/icons/readmail.png)
+ skin/classic/messenger/icons/mail-toolbar.png (mail/icons/mail-toolbar.png)
+ skin/classic/messenger/icons/mail-toolbar-small.png (mail/icons/mail-toolbar-small.png)
+ skin/classic/messenger/icons/folder.png (mail/icons/folder.png)
+ skin/classic/messenger/icons/message.png (mail/icons/message.png)
+ skin/classic/messenger/icons/license.txt (mail/icons/license.txt)
+ skin/classic/messenger/icons/appmenu-icons.png (mail/icons/appmenu-icons.png)
+ skin/classic/messenger/icons/attachment-deleted.png (mail/icons/attachment-deleted.png)
+ skin/classic/messenger/icons/attachment-deleted-large.png (mail/icons/attachment-deleted-large.png)
+ skin/classic/messenger/icons/attachment-col.png (mail/icons/attachment-col.png)
+ skin/classic/messenger/icons/attachment-col.svg (mail/icons/attachment-col.svg)
+ skin/classic/messenger/icons/columnpicker.svg (mail/icons/columnpicker.svg)
+ skin/classic/messenger/icons/junk-col.svg (mail/icons/junk-col.svg)
+ skin/classic/messenger/icons/thread-col.svg (mail/icons/thread-col.svg)
+ skin/classic/messenger/icons/thread-col-sorta.png (mail/icons/thread-col-sorta.png)
+ skin/classic/messenger/icons/thread-col-sortd.png (mail/icons/thread-col-sortd.png)
+ skin/classic/messenger/icons/thread.png (mail/icons/thread.png)
+ skin/classic/messenger/icons/thread-ignored.png (mail/icons/thread-ignored.png)
+ skin/classic/messenger/icons/message-ignored.png (mail/icons/message-ignored.png)
+ skin/classic/messenger/icons/thread-watched.png (mail/icons/thread-watched.png)
+ skin/classic/messenger/icons/flag-col.png (mail/icons/flag-col.png)
+ skin/classic/messenger/icons/flag-col.svg (mail/icons/flag-col.svg)
+ skin/classic/messenger/icons/flag.png (mail/icons/flag.png)
+ skin/classic/messenger/icons/flag-empty.png (mail/icons/flag-empty.png)
+ skin/classic/messenger/icons/server.png (mail/icons/server.png)
+ skin/classic/messenger/icons/read.png (mail/icons/read.png)
+ skin/classic/messenger/icons/readcol.svg (mail/icons/readcol.svg)
+ skin/classic/messenger/icons/unreadmail.png (mail/icons/unreadmail.png)
+ skin/classic/messenger/icons/search-arrow.gif (mail/icons/search-arrow.gif)
+ skin/classic/messenger/icons/quick-search-clear.png (mail/icons/quick-search-clear.png)
+ skin/classic/messenger/icons/close-button.png (mail/icons/close-button.png)
+ skin/classic/messenger/icons/closeTab.png (mail/icons/closeTab.png)
+ skin/classic/messenger/icons/remote-blocked.png (mail/icons/remote-blocked.png)
+ skin/classic/messenger/icons/phishing.png (mail/icons/phishing.png)
+ skin/classic/messenger/icons/junk.png (mail/icons/junk.png)
+ skin/classic/messenger/icons/check.gif (mail/icons/check.gif)
+ skin/classic/messenger/icons/notchecked.gif (mail/icons/notchecked.gif)
+ skin/classic/messenger/icons/online.png (mail/icons/online.png)
+ skin/classic/messenger/icons/offline.png (mail/icons/offline.png)
+ skin/classic/messenger/icons/row.png (mail/icons/row.png)
+ skin/classic/messenger/icons/secure.png (mail/icons/secure.png)
+ skin/classic/messenger/icons/update.png (mail/icons/update.png)
+ skin/classic/messenger/icons/insecure.png (mail/icons/insecure.png)
+ skin/classic/messenger/icons/identity.png (mail/icons/identity.png)
+ skin/classic/messenger/icons/tick.png (mail/icons/tick.png)
+ skin/classic/messenger/icons/error.png (mail/icons/error.png)
+ skin/classic/messenger/icons/cancel.png (mail/icons/cancel.png)
+ skin/classic/messenger/icons/tab-arrow-left.png (mail/icons/tab-arrow-left.png)
+ skin/classic/messenger/icons/tab-arrow-left-inverted.png (mail/icons/tab-arrow-left-inverted.png)
+ skin/classic/messenger/icons/mainwindow-dropdown-arrow.png (mail/icons/mainwindow-dropdown-arrow.png)
+ skin/classic/messenger/icons/mainwindow-dropdown-arrow-inverted.png (mail/icons/mainwindow-dropdown-arrow-inverted.png)
+ skin/classic/messenger/icons/tabDragIndicator.png (mail/icons/tabDragIndicator.png)
+ skin/classic/messenger/icons/tabActiveEnd.svg (mail/icons/tabActiveEnd.svg)
+ skin/classic/messenger/icons/tabActiveMiddle.svg (mail/icons/tabActiveMiddle.svg)
+ skin/classic/messenger/icons/tabActiveStart.svg (mail/icons/tabActiveStart.svg)
+ skin/classic/messenger/icons/tabBackgroundEnd.png (mail/icons/tabBackgroundEnd.png)
+ skin/classic/messenger/icons/tabBackgroundMiddle.png (mail/icons/tabBackgroundMiddle.png)
+ skin/classic/messenger/icons/tabBackgroundStart.png (mail/icons/tabBackgroundStart.png)
+ skin/classic/messenger/icons/connecting.png (mail/icons/connecting.png)
+ skin/classic/messenger/icons/loading.png (mail/icons/loading.png)
+ skin/classic/messenger/icons/chat-toolbar.png (mail/icons/chat-toolbar.png)
+ skin/classic/messenger/icons/chat-toolbar-small.png (mail/icons/chat-toolbar-small.png)
+ skin/classic/messenger/icons/status.png (mail/icons/status.png)
+ skin/classic/messenger/icons/status-small.png (mail/icons/status-small.png)
+ skin/classic/messenger/accountcentral/read-messages.png (mail/accountcentral/read-messages.png)
+ skin/classic/messenger/accountcentral/write-message.png (mail/accountcentral/write-message.png)
+ skin/classic/messenger/accountcentral/create-account.png (mail/accountcentral/create-account.png)
+ skin/classic/messenger/accountcentral/account-settings.png (mail/accountcentral/account-settings.png)
+ skin/classic/messenger/accountcentral/search-messages.png (mail/accountcentral/search-messages.png)
+ skin/classic/messenger/accountcentral/manage-filters.png (mail/accountcentral/manage-filters.png)
+ skin/classic/messenger/accountcentral/offline-settings.png (mail/accountcentral/offline-settings.png)
+ skin/classic/messenger/accountcentral/manage-imap.png (mail/accountcentral/manage-imap.png)
+ skin/classic/messenger/accountcentral/manage-newsgroups.png (mail/accountcentral/manage-newsgroups.png)
+ skin/classic/messenger/accountcentral/manage-rss.png (mail/accountcentral/manage-rss.png)
+ skin/classic/messenger/icons/arrow-dn-grey.png (mail/icons/arrow-dn-grey.png)
+ skin/classic/messenger/icons/arrow-dn-black.png (mail/icons/arrow-dn-black.png)
+ skin/classic/messenger/icons/arrow-dn-blue.png (mail/icons/arrow-dn-blue.png)
+ skin/classic/messenger/icons/arrow/arrow-left.png (mail/icons/arrow/arrow-left.png)
+ skin/classic/messenger/icons/arrow/arrow-right.png (mail/icons/arrow/arrow-right.png)
+ skin/classic/messenger/icons/arrow/arrow-up.png (mail/icons/arrow/arrow-up.png)
+ skin/classic/messenger/icons/arrow/arrow-down.png (mail/icons/arrow/arrow-down.png)
+ skin/classic/messenger/icons/arrow/arrow-left-dim.png (mail/icons/arrow/arrow-left-dim.png)
+ skin/classic/messenger/icons/arrow/arrow-right-dim.png (mail/icons/arrow/arrow-right-dim.png)
+ skin/classic/messenger/icons/arrow/arrow-up-dim.png (mail/icons/arrow/arrow-up-dim.png)
+ skin/classic/messenger/icons/arrow/arrow-down-dim.png (mail/icons/arrow/arrow-down-dim.png)
+ skin/classic/messenger/icons/timeline.png (mail/icons/timeline.png)
+ skin/classic/messenger/icons/timeline-inverted.png (mail/icons/timeline-inverted.png)
+ skin/classic/messenger/icons/empty-search-results.png (mail/icons/empty-search-results.png)
+ skin/classic/messenger/icons/arrow/foldercycler-arrow-left.png (mail/icons/arrow/foldercycler-arrow-left.png)
+ skin/classic/messenger/icons/arrow/foldercycler-arrow-right.png (mail/icons/arrow/foldercycler-arrow-right.png)
+ skin/classic/messenger/icons/search-favorite.png (mail/icons/search-favorite.png)
+ skin/classic/messenger/icons/xp-pin-grey.png (mail/icons/xp-pin-grey.png)
+ skin/classic/messenger/icons/xp-pin-red.png (mail/icons/xp-pin-red.png)
+ skin/classic/messenger/tagbg.png (mail/tagbg.png)
+% skin messenger-newsblog classic/1.0 %skin/classic/messenger-newsblog/ os=WINNT osversion<6
+% skin messenger-newsblog classic/1.0 %skin/classic/messenger-newsblog/ os!=WINNT
+ skin/classic/messenger-newsblog/feed-subscriptions.css (mail/newsblog/feed-subscriptions.css)
+ skin/classic/messenger-newsblog/icons/rss-feed.png (mail/newsblog/rss-feed.png)
+ skin/classic/messenger-newsblog/icons/server-rss.png (mail/newsblog/server-rss.png)
+ skin/classic/messenger/newmailaccount/accountProvisioner.css (mail/newmailaccount/accountProvisioner.css)
+ skin/classic/messenger/newmailaccount/search.gif (mail/newmailaccount/search.gif)
+ skin/classic/messenger/newmailaccount/spinner.gif (mail/newmailaccount/spinner.gif)
+ skin/classic/messenger/newmailaccount/success-addons.png (mail/newmailaccount/success-addons.png)
+ skin/classic/messenger/newmailaccount/success-border.png (mail/newmailaccount/success-border.png)
+ skin/classic/messenger/newmailaccount/success-compose.png (mail/newmailaccount/success-compose.png)
+ skin/classic/messenger/newmailaccount/success-signature.png (mail/newmailaccount/success-signature.png)
+ skin/classic/messenger/newmailaccount/search.png (mail/newmailaccount/search.png)
+ skin/classic/messenger/sanitizeDialog.css (mail/sanitizeDialog.css)
+ skin/classic/messenger/icons/ubuntuone.png (mail/icons/ubuntuone.png)
+ skin/classic/messenger/icons/yousendit.png (mail/icons/yousendit.png)
+ skin/classic/messenger/icons/box-logo.png (mail/icons/box-logo.png)
+#ifdef XP_WIN
+% skin communicator classic/1.0 %skin/classic/aero/communicator/ os=WINNT osversion>=6
+ skin/classic/aero/communicator/communicator.css (mail/communicator.css)
+ skin/classic/aero/communicator/smileys.css (mail/smileys.css)
+ skin/classic/aero/communicator/icons/smileys/smiley-smile.png (mail/icons/smiley-smile-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-frown.png (mail/icons/smiley-frown-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-wink.png (mail/icons/smiley-wink-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-tongue-out.png (mail/icons/smiley-tongue-out-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-laughing.png (mail/icons/smiley-laughing-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-embarassed.png (mail/icons/smiley-embarassed-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-undecided.png (mail/icons/smiley-undecided-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-surprised.png (mail/icons/smiley-surprised-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-kiss.png (mail/icons/smiley-kiss-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-yell.png (mail/icons/smiley-yell-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-cool.png (mail/icons/smiley-cool-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-money-mouth.png (mail/icons/smiley-money-mouth-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-foot-in-mouth.png (mail/icons/smiley-foot-in-mouth-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-innocent.png (mail/icons/smiley-innocent-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-cry.png (mail/icons/smiley-cry-aero.png)
+ skin/classic/aero/communicator/icons/smileys/smiley-sealed.png (mail/icons/smiley-sealed-aero.png)
+% skin messenger classic/1.0 %skin/classic/aero/messenger/ os=WINNT osversion>=6
+ skin/classic/aero/messenger/primaryToolbar.css (mail/primaryToolbar-aero.css)
+ skin/classic/aero/messenger/aboutSupport.css (mail/aboutSupport.css)
+ skin/classic/aero/messenger/accountCentral.css (mail/accountCentral.css)
+ skin/classic/aero/messenger/accountCreation.css (mail/accountCreation.css)
+ skin/classic/aero/messenger/accountManage.css (mail/accountManage.css)
+ skin/classic/aero/messenger/accountWizard.css (mail/accountWizard.css)
+* skin/classic/aero/messenger/chat.css (mail/chat-aero.css)
+ skin/classic/aero/messenger/userIcon.png (mail/userIcon.png)
+ skin/classic/aero/messenger/grain.png (mail/grain.png)
+* skin/classic/aero/messenger/imAccounts.css (../../components/im/themes/imAccounts.css)
+* skin/classic/aero/messenger/imAccountWizard.css (../../components/im/themes/imAccountWizard.css)
+ skin/classic/aero/messenger/imBuddytooltip.css (../../components/im/themes/imBuddytooltip.css)
+ skin/classic/aero/messenger/imMenulist.css (../../components/im/themes/imMenulist.css)
+* skin/classic/aero/messenger/imRichlistbox.css (../../components/im/themes/imRichlistbox.css)
+ skin/classic/aero/messenger/imStatus.css (../../components/im/themes/imStatus.css)
+ skin/classic/aero/messenger/founder.png (../../components/im/themes/founder.png)
+ skin/classic/aero/messenger/operator.png (../../components/im/themes/operator.png)
+ skin/classic/aero/messenger/half-operator.png (../../components/im/themes/half-operator.png)
+ skin/classic/aero/messenger/voice.png (../../components/im/themes/voice.png)
+* skin/classic/aero/messenger/browserRequest.css (mail/browserRequest-aero.css)
+ skin/classic/aero/messenger/section_collapsed.png (mail/section_collapsed.png)
+ skin/classic/aero/messenger/section_expanded.png (mail/section_expanded.png)
+ skin/classic/aero/messenger/messageHeader.css (mail/messageHeader-aero.css)
+ skin/classic/aero/messenger/messageBody.css (mail/messageBody.css)
+ skin/classic/aero/messenger/webSearch.css (mail/webSearch-aero.css)
+ skin/classic/aero/messenger/messageQuotes.css (mail/messageQuotes.css)
+* skin/classic/aero/messenger/messenger.css (mail/messenger-aero.css)
+* skin/classic/aero/messenger/attachmentList.css (mail/attachmentList-aero.css)
+ skin/classic/aero/messenger/imageFilters.svg (mail/imageFilters.svg)
+* skin/classic/aero/messenger/mailWindow1.css (mail/mailWindow1-aero.css)
+* skin/classic/aero/messenger/tagColors.css (mail/tagColors-aero.css)
+ skin/classic/aero/messenger/messageWindow.css (mail/messageWindow-aero.css)
+ skin/classic/aero/messenger/searchBox.css (mail/searchBox.css)
+ skin/classic/aero/messenger/junkMail.css (mail/junkMail.css)
+ skin/classic/aero/messenger/folderMenus.css (mail/folderMenus.css)
+* skin/classic/aero/messenger/folderPane.css (mail/folderPane-aero.css)
+ skin/classic/aero/messenger/subscribe.css (mail/subscribe.css)
+ skin/classic/aero/messenger/virtualFolderListDialog.css (mail/virtualFolderListDialog.css)
+* skin/classic/aero/messenger/searchDialog.css (mail/searchDialog-aero.css)
+ skin/classic/aero/messenger/msgSelectOffline.css (mail/msgSelectOffline.css)
+ skin/classic/aero/messenger/filterDialog.css (mail/filterDialog.css)
+ skin/classic/aero/messenger/dialogs.css (mail/dialogs.css)
+ skin/classic/aero/messenger/multimessageview.css (mail/multimessageview.css)
+ skin/classic/aero/messenger/glodaFacetView.css (mail/glodaFacetView.css)
+ skin/classic/aero/messenger/icons/exclude.png (mail/icons/exclude.png)
+ skin/classic/aero/messenger/icons/exclude-selected.png (mail/icons/exclude-selected.png)
+ skin/classic/aero/messenger/icons/zoomout.png (mail/icons/zoomout.png)
+ skin/classic/aero/messenger/icons/zoomout-hover.png (mail/icons/zoomout-hover.png)
+ skin/classic/aero/messenger/newmailalert.css (mail/newmailalert.css)
+ skin/classic/aero/messenger/tabmail.css (mail/tabmail-aero.css)
+ skin/classic/aero/messenger/editContactOverlay.css (mail/editContactOverlay.css)
+ skin/classic/aero/messenger/quickFilterBar.css (mail/quickFilterBar-aero.css)
+ skin/classic/aero/messenger/starred48.png (mail/starred48.png)
+ skin/classic/aero/messenger/contactStarred.png (mail/contactStarred.png)
+ skin/classic/aero/messenger/starContact.png (mail/starContact.png)
+* skin/classic/aero/messenger/activity/activity.css (mail/activity/activity-aero.css)
+ skin/classic/aero/messenger/activity/buttons.png (mail/activity/buttons.png)
+ skin/classic/aero/messenger/activity/defaultProcessIcon.png (mail/activity/defaultProcessIcon-aero.png)
+ skin/classic/aero/messenger/activity/defaultEventIcon.png (mail/activity/defaultEventIcon.png)
+ skin/classic/aero/messenger/activity/defaultWarningIcon.png (mail/activity/defaultWarningIcon-aero.png)
+ skin/classic/aero/messenger/activity/undoIcon.png (mail/activity/undoIcon-aero.png)
+ skin/classic/aero/messenger/activity/syncMailIcon.png (mail/activity/syncMailIcon-aero.png)
+ skin/classic/aero/messenger/activity/sendMailIcon.png (mail/activity/sendMailIcon-aero.png)
+ skin/classic/aero/messenger/activity/removeItemIcon.png (mail/activity/removeItemIcon-aero.png)
+ skin/classic/aero/messenger/activity/addItemIcon.png (mail/activity/addItemIcon-aero.png)
+ skin/classic/aero/messenger/activity/moveMailIcon.png (mail/activity/moveMailIcon-aero.png)
+ skin/classic/aero/messenger/activity/copyMailIcon.png (mail/activity/copyMailIcon-aero.png)
+ skin/classic/aero/messenger/activity/deleteMailIcon.png (mail/activity/deleteMailIcon-aero.png)
+ skin/classic/aero/messenger/activity/compactMailIcon.png (mail/activity/compactMailIcon-aero.png)
+ skin/classic/aero/messenger/activity/indexMailIcon.png (mail/activity/indexMailIcon-aero.png)
+ skin/classic/aero/messenger/addressbook/addressbook.css (mail/addrbook/addressbook-aero.css)
+* skin/classic/aero/messenger/addressbook/abContactsPanel.css (mail/addrbook/abContactsPanel-aero.css)
+ skin/classic/aero/messenger/addressbook/cardDialog.css (mail/addrbook/cardDialog.css)
+ skin/classic/aero/messenger/addressbook/abResultsPane.css (mail/addrbook/abResultsPane.css)
+ skin/classic/aero/messenger/addressbook/icons/abcard.png (mail/addrbook/abcard.png)
+ skin/classic/aero/messenger/addressbook/icons/addrbook.png (mail/addrbook/addrbook-aero.png)
+ skin/classic/aero/messenger/addressbook/icons/ablist.png (mail/addrbook/ablist.png)
+ skin/classic/aero/messenger/addressbook/icons/contact-generic.png (mail/addrbook/contact-generic.png)
+ skin/classic/aero/messenger/addressbook/icons/contact-generic-tiny.png (mail/addrbook/contact-generic-tiny.png)
+ skin/classic/aero/messenger/addressbook/icons/addressbook-toolbar.png (mail/addrbook/addressbook-toolbar-aero.png)
+ skin/classic/aero/messenger/addressbook/icons/addressbook-toolbar-inverted.png (mail/addrbook/addressbook-toolbar-aero-inverted.png)
+ skin/classic/aero/messenger/addressbook/icons/abcard-large.png (mail/addrbook/abcard-large.png)
+ skin/classic/aero/messenger/addressbook/icons/remote-addrbook.png (mail/addrbook/remote-addrbook-aero.png)
+ skin/classic/aero/messenger/addressbook/icons/remote-addrbook-error.png (mail/addrbook/remote-addrbook-error.png)
+ skin/classic/aero/messenger/addressbook/icons/secure-remote-addrbook.png (mail/addrbook/secure-remote-addrbook-aero.png)
+* skin/classic/aero/messenger/cloudfile/addAccountDialog.css (mail/cloudfile/addAccountDialog-aero.css)
+ skin/classic/aero/messenger/cloudfile/YouSendIt/settings.css (mail/cloudfile/YouSendIt/settings.css)
+ skin/classic/aero/messenger/cloudfile/YouSendIt/fileExceedsLimit.css (mail/cloudfile/YouSendIt/fileExceedsLimit.css)
+ skin/classic/aero/messenger/cloudfile/YouSendIt/check.png (mail/cloudfile/YouSendIt/check.png)
+ skin/classic/aero/messenger/messengercompose/messengercompose.css (mail/compose/messengercompose-aero.css)
+ skin/classic/aero/messenger/messengercompose/compose-toolbar.png (mail/compose/compose-toolbar-aero.png)
+ skin/classic/aero/messenger/messengercompose/compose-toolbar-inverted.png (mail/compose/compose-toolbar-aero-inverted.png)
+ skin/classic/aero/messenger/messengercompose/format-buttons.png (mail/compose/format-buttons-aero.png)
+ skin/classic/aero/messenger/preferences/alwaysAsk.png (mail/preferences/alwaysAsk.png)
+ skin/classic/aero/messenger/preferences/application.png (mail/preferences/application.png)
+* skin/classic/aero/messenger/preferences/preferences.css (mail/preferences/preferences-aero.css)
+ skin/classic/aero/messenger/preferences/general.png (mail/preferences/general-aero.png)
+ skin/classic/aero/messenger/preferences/display.png (mail/preferences/display-aero.png)
+ skin/classic/aero/messenger/preferences/composition.png (mail/preferences/composition-aero.png)
+ skin/classic/aero/messenger/preferences/junk.png (mail/preferences/junk-aero.png)
+ skin/classic/aero/messenger/preferences/security.png (mail/preferences/security-aero.png)
+ skin/classic/aero/messenger/preferences/attachments.png (mail/preferences/attachments-aero.png)
+ skin/classic/aero/messenger/preferences/applications.css (mail/preferences/applications.css)
+ skin/classic/aero/messenger/preferences/saveFile.png (mail/preferences/saveFile.png)
+ skin/classic/aero/messenger/preferences/advanced.png (mail/preferences/advanced-aero.png)
+ skin/classic/aero/messenger/preferences/chat.png (mail/preferences/chat-aero.png)
+ skin/classic/aero/messenger/preferences/background.png (mail/preferences/background.png)
+ skin/classic/aero/messenger/preferences/hover.png (mail/preferences/hover.png)
+ skin/classic/aero/messenger/preferences/selected.png (mail/preferences/selected.png)
+ skin/classic/aero/messenger/preferences/auth-error.png (mail/preferences/auth-error.png)
+ skin/classic/aero/messenger/smime/msgCompSMIMEOverlay.css (mail/smime/msgCompSMIMEOverlay.css)
+ skin/classic/aero/messenger/smime/msgHdrViewSMIMEOverlay.css (mail/smime/msgHdrViewSMIMEOverlay.css)
+ skin/classic/aero/messenger/smime/msgReadSMIMEOverlay.css (mail/smime/msgReadSMIMEOverlay.css)
+ skin/classic/aero/messenger/smime/msgReadSecurityInfo.css (mail/smime/msgReadSecurityInfo.css)
+ skin/classic/aero/messenger/smime/msgCompSecurityInfo.css (mail/smime/msgCompSecurityInfo.css)
+ skin/classic/aero/messenger/smime/certFetchingStatus.css (mail/smime/certFetchingStatus.css)
+ skin/classic/aero/messenger/smime/msgReadSecureHeaders.css (mail/smime/msgReadSecureHeaders.css)
+ skin/classic/aero/messenger/smime/icons/hdrCryptoNotOk.png (mail/smime/hdrCryptoNotOk-aero.png)
+ skin/classic/aero/messenger/smime/icons/hdrCryptoOk.png (mail/smime/hdrCryptoOk-aero.png)
+ skin/classic/aero/messenger/smime/icons/hdrSignNotOk.png (mail/smime/hdrSignNotOk-aero.png)
+ skin/classic/aero/messenger/smime/icons/hdrSignOk.png (mail/smime/hdrSignOk-aero.png)
+ skin/classic/aero/messenger/smime/icons/hdrSignUnknown.png (mail/smime/hdrSignUnknown-aero.png)
+ skin/classic/aero/messenger/smime/icons/sbCryptoNotOk.png (mail/smime/sbCryptoNotOk-aero.png)
+ skin/classic/aero/messenger/smime/icons/sbCryptoOk.png (mail/smime/sbCryptoOk-aero.png)
+ skin/classic/aero/messenger/smime/icons/sbSignNotOk.png (mail/smime/sbSignNotOk-aero.png)
+ skin/classic/aero/messenger/smime/icons/sbSignOk.png (mail/smime/sbSignOk-aero.png)
+ skin/classic/aero/messenger/smime/icons/sbSignUnknown.png (mail/smime/sbSignUnknown-aero.png)
+ skin/classic/aero/messenger/smime/icons/check_sign.png (mail/smime/check_sign.png)
+ skin/classic/aero/messenger/smime/icons/cross_sign.png (mail/smime/cross_sign.png)
+ skin/classic/aero/messenger/smime/icons/unsign.png (mail/smime/unsign.png)
+ skin/classic/aero/messenger/icons/timeline.png (mail/icons/timeline.png)
+ skin/classic/aero/messenger/icons/timeline-inverted.png (mail/icons/timeline-inverted.png)
+ skin/classic/aero/messenger/icons/empty-search-results.png (mail/icons/empty-search-results.png)
+ skin/classic/aero/messenger/icons/readmail.png (mail/icons/readmail.png)
+ skin/classic/aero/messenger/icons/mail-toolbar.png (mail/icons/mail-toolbar-aero.png)
+ skin/classic/aero/messenger/icons/mail-toolbar-inverted.png (mail/icons/mail-toolbar-aero-inverted.png)
+ skin/classic/aero/messenger/icons/arrow-dn-inverted.png (mail/icons/arrow-dn-inverted.png)
+ skin/classic/aero/messenger/icons/folder.png (mail/icons/folder-aero.png)
+ skin/classic/aero/messenger/icons/message.png (mail/icons/message-aero.png)
+ skin/classic/aero/messenger/icons/license.txt (mail/icons/license.txt)
+ skin/classic/aero/messenger/icons/appmenu-icons.png (mail/icons/appmenu-icons.png)
+ skin/classic/aero/messenger/icons/attachment-deleted.png (mail/icons/attachment-deleted.png)
+ skin/classic/aero/messenger/icons/attachment-deleted-large.png (mail/icons/attachment-deleted-large.png)
+ skin/classic/aero/messenger/icons/attachment-col.png (mail/icons/attachment-col-aero.png)
+ skin/classic/aero/messenger/icons/attachment-col.svg (mail/icons/attachment-col.svg)
+ skin/classic/aero/messenger/icons/columnpicker.svg (mail/icons/columnpicker.svg)
+ skin/classic/aero/messenger/icons/junk-col.svg (mail/icons/junk-col.svg)
+ skin/classic/aero/messenger/icons/thread-col.svg (mail/icons/thread-col.svg)
+ skin/classic/aero/messenger/icons/thread-col-sorta.png (mail/icons/thread-col-sorta.png)
+ skin/classic/aero/messenger/icons/thread-col-sortd.png (mail/icons/thread-col-sortd.png)
+ skin/classic/aero/messenger/icons/thread.png (mail/icons/thread.png)
+ skin/classic/aero/messenger/icons/thread-ignored.png (mail/icons/thread-ignored.png)
+ skin/classic/aero/messenger/icons/message-ignored.png (mail/icons/message-ignored.png)
+ skin/classic/aero/messenger/icons/thread-watched.png (mail/icons/thread-watched.png)
+ skin/classic/aero/messenger/icons/flag-col.png (mail/icons/flag-col-aero.png)
+ skin/classic/aero/messenger/icons/flag-col.svg (mail/icons/flag-col.svg)
+ skin/classic/aero/messenger/icons/flag.png (mail/icons/flag-aero.png)
+ skin/classic/aero/messenger/icons/flag-empty.png (mail/icons/flag-empty-aero.png)
+ skin/classic/aero/messenger/icons/server.png (mail/icons/server-aero.png)
+ skin/classic/aero/messenger/icons/readcol.svg (mail/icons/readcol.svg)
+ skin/classic/aero/messenger/icons/unreadmail.png (mail/icons/unreadmail.png)
+ skin/classic/aero/messenger/icons/search-arrow.gif (mail/icons/search-arrow.gif)
+ skin/classic/aero/messenger/icons/quick-search-icons.png (mail/icons/quick-search-icons-aero.png)
+ skin/classic/aero/messenger/icons/quick-search-clear.png (mail/icons/quick-search-clear.png)
+ skin/classic/aero/messenger/icons/close-button.png (mail/icons/close-button.png)
+ skin/classic/aero/messenger/icons/closeTab.png (mail/icons/closeTab.png)
+ skin/classic/aero/messenger/icons/remote-blocked.png (mail/icons/remote-blocked.png)
+ skin/classic/aero/messenger/icons/phishing.png (mail/icons/phishing.png)
+ skin/classic/aero/messenger/icons/junk.png (mail/icons/junk-aero.png)
+ skin/classic/aero/messenger/icons/check.gif (mail/icons/check.gif)
+ skin/classic/aero/messenger/icons/notchecked.gif (mail/icons/notchecked.gif)
+ skin/classic/aero/messenger/icons/online.png (mail/icons/online-aero.png)
+ skin/classic/aero/messenger/icons/offline.png (mail/icons/offline-aero.png)
+ skin/classic/aero/messenger/icons/row.png (mail/icons/row.png)
+ skin/classic/aero/messenger/icons/update.png (mail/icons/update.png)
+ skin/classic/aero/messenger/icons/secure.png (mail/icons/secure.png)
+ skin/classic/aero/messenger/icons/insecure.png (mail/icons/insecure.png)
+ skin/classic/aero/messenger/icons/identity.png (mail/icons/identity.png)
+ skin/classic/aero/messenger/icons/tick.png (mail/icons/tick.png)
+ skin/classic/aero/messenger/icons/error.png (mail/icons/error.png)
+ skin/classic/aero/messenger/icons/cancel.png (mail/icons/cancel.png)
+ skin/classic/aero/messenger/icons/tabActiveEnd.png (mail/icons/tabActiveEnd.png)
+ skin/classic/aero/messenger/icons/tabActiveEnd.svg (mail/icons/tabActiveEnd.svg)
+ skin/classic/aero/messenger/icons/tabActiveMiddle.png (mail/icons/tabActiveMiddle.png)
+ skin/classic/aero/messenger/icons/tabActiveMiddle.svg (mail/icons/tabActiveMiddle.svg)
+ skin/classic/aero/messenger/icons/tabActiveStart.png (mail/icons/tabActiveStart.png)
+ skin/classic/aero/messenger/icons/tabActiveStart.svg (mail/icons/tabActiveStart.svg)
+ skin/classic/aero/messenger/icons/tabBackgroundEnd.png (mail/icons/tabBackgroundEnd.png)
+ skin/classic/aero/messenger/icons/tabBackgroundMiddle.png (mail/icons/tabBackgroundMiddle.png)
+ skin/classic/aero/messenger/icons/tabBackgroundStart.png (mail/icons/tabBackgroundStart.png)
+ skin/classic/aero/messenger/icons/tabbar-background.png (mail/icons/tabbar-background.png)
+ skin/classic/aero/messenger/icons/tab-arrow-left.png (mail/icons/tab-arrow-left.png)
+ skin/classic/aero/messenger/icons/tab-arrow-left-inverted.png (mail/icons/tab-arrow-left-inverted.png)
+ skin/classic/aero/messenger/icons/mainwindow-dropdown-arrow.png (mail/icons/mainwindow-dropdown-arrow.png)
+ skin/classic/aero/messenger/icons/mainwindow-dropdown-arrow-inverted.png (mail/icons/mainwindow-dropdown-arrow-inverted.png)
+ skin/classic/aero/messenger/icons/toolbarbutton-arrow-inverted.png (mail/icons/toolbarbutton-arrow-inverted.png)
+ skin/classic/aero/messenger/icons/toolbarbutton-arrow.png (mail/icons/toolbarbutton-arrow.png)
+ skin/classic/aero/messenger/icons/tabDragIndicator.png (mail/icons/tabDragIndicator.png)
+ skin/classic/aero/messenger/accountcentral/read-messages.png (mail/accountcentral/read-messages.png)
+ skin/classic/aero/messenger/accountcentral/write-message.png (mail/accountcentral/write-message.png)
+ skin/classic/aero/messenger/accountcentral/create-account.png (mail/accountcentral/create-account.png)
+ skin/classic/aero/messenger/accountcentral/account-settings.png (mail/accountcentral/account-settings.png)
+ skin/classic/aero/messenger/accountcentral/search-messages.png (mail/accountcentral/search-messages.png)
+ skin/classic/aero/messenger/accountcentral/manage-filters.png (mail/accountcentral/manage-filters.png)
+ skin/classic/aero/messenger/accountcentral/offline-settings.png (mail/accountcentral/offline-settings.png)
+ skin/classic/aero/messenger/accountcentral/manage-imap.png (mail/accountcentral/manage-imap.png)
+ skin/classic/aero/messenger/accountcentral/manage-newsgroups.png (mail/accountcentral/manage-newsgroups.png)
+ skin/classic/aero/messenger/accountcentral/manage-rss.png (mail/accountcentral/manage-rss.png)
+ skin/classic/aero/messenger/icons/arrow-dn-grey.png (mail/icons/arrow-dn-grey.png)
+ skin/classic/aero/messenger/icons/arrow-dn-black.png (mail/icons/arrow-dn-black.png)
+ skin/classic/aero/messenger/icons/arrow-dn-blue.png (mail/icons/arrow-dn-blue.png)
+ skin/classic/aero/messenger/icons/arrow/arrow-left.png (mail/icons/arrow/arrow-left.png)
+ skin/classic/aero/messenger/icons/arrow/arrow-right.png (mail/icons/arrow/arrow-right.png)
+ skin/classic/aero/messenger/icons/arrow/arrow-up.png (mail/icons/arrow/arrow-up.png)
+ skin/classic/aero/messenger/icons/arrow/arrow-down.png (mail/icons/arrow/arrow-down.png)
+ skin/classic/aero/messenger/icons/arrow/arrow-left-dim.png (mail/icons/arrow/arrow-left-dim.png)
+ skin/classic/aero/messenger/icons/arrow/arrow-right-dim.png (mail/icons/arrow/arrow-right-dim.png)
+ skin/classic/aero/messenger/icons/arrow/arrow-up-dim.png (mail/icons/arrow/arrow-up-dim.png)
+ skin/classic/aero/messenger/icons/arrow/arrow-down-dim.png (mail/icons/arrow/arrow-down-dim.png)
+ skin/classic/aero/messenger/icons/arrow/foldercycler-arrow-left.png (mail/icons/arrow/foldercycler-arrow-left.png)
+ skin/classic/aero/messenger/icons/arrow/foldercycler-arrow-right.png (mail/icons/arrow/foldercycler-arrow-right.png)
+ skin/classic/aero/messenger/icons/search-favorite.png (mail/icons/search-favorite.png)
+ skin/classic/aero/messenger/icons/xp-pin-grey.png (mail/icons/xp-pin-grey.png)
+ skin/classic/aero/messenger/icons/xp-pin-red.png (mail/icons/xp-pin-red.png)
+ skin/classic/aero/messenger/icons/connecting.png (mail/icons/connecting.png)
+ skin/classic/aero/messenger/icons/loading.png (mail/icons/loading.png)
+ skin/classic/aero/messenger/tagbg.png (mail/tagbg.png)
+ skin/classic/aero/messenger/icons/download.png (mail/icons/download.png)
+ skin/classic/aero/messenger/icons/chat-toolbar.png (mail/icons/chat-toolbar-aero.png)
+ skin/classic/aero/messenger/icons/status.png (mail/icons/status-aero.png)
+ skin/classic/aero/messenger/icons/status-small.png (mail/icons/status-small-aero.png)
+% skin messenger-newsblog classic/1.0 %skin/classic/aero/messenger-newsblog/ os=WINNT osversion>=6
+ skin/classic/aero/messenger-newsblog/feed-subscriptions.css (mail/newsblog/feed-subscriptions.css)
+ skin/classic/aero/messenger-newsblog/icons/rss-feed.png (mail/newsblog/rss-feed.png)
+ skin/classic/aero/messenger-newsblog/icons/server-rss.png (mail/newsblog/server-rss-aero.png)
+ skin/classic/aero/messenger/newmailaccount/accountProvisioner.css (mail/newmailaccount/accountProvisioner-aero.css)
+ skin/classic/aero/messenger/newmailaccount/search.gif (mail/newmailaccount/search.gif)
+ skin/classic/aero/messenger/newmailaccount/spinner.gif (mail/newmailaccount/spinner.gif)
+ skin/classic/aero/messenger/newmailaccount/success-addons.png (mail/newmailaccount/success-addons.png)
+ skin/classic/aero/messenger/newmailaccount/success-border.png (mail/newmailaccount/success-border.png)
+ skin/classic/aero/messenger/newmailaccount/success-compose.png (mail/newmailaccount/success-compose.png)
+ skin/classic/aero/messenger/newmailaccount/success-signature.png (mail/newmailaccount/success-signature.png)
+ skin/classic/aero/messenger/newmailaccount/search.png (mail/newmailaccount/search.png)
+ skin/classic/aero/messenger/icons/ubuntuone.png (mail/icons/ubuntuone.png)
+ skin/classic/aero/messenger/icons/yousendit.png (mail/icons/yousendit.png)
+ skin/classic/aero/messenger/sanitizeDialog.css (mail/sanitizeDialog.css)
+ skin/classic/aero/messenger/icons/box-logo.png (mail/icons/box-logo.png)
+#endif
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+#signedHdrIcon {
+ list-style-image: none;
+ visibility: visible;
+ -moz-margin-end: 10px;
+}
+
+#signedHdrIcon[signed="ok"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrSignOk.png");
+ visibility: visible;
+}
+
+#signedHdrIcon[signed="unknown"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrSignUnknown.png");
+ visibility: visible;
+}
+
+#signedHdrIcon[signed="mismatch"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrSignUnknown.png");
+ visibility: visible;
+}
+
+#signedHdrIcon[signed="notok"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrSignNotOk.png");
+ visibility: visible;
+}
+
+#encryptedHdrIcon {
+ list-style-image: none;
+ visibility: visible;
+}
+
+#encryptedHdrIcon[encrypted="ok"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrCryptoOk.png");
+ visibility: visible;
+}
+
+#encryptedHdrIcon[encrypted="notok"] {
+ list-style-image: url("chrome://messenger/skin/smime/icons/hdrCryptoNotOk.png");
+ visibility: visible;
+}
+
+#secureinfomsgh,
+#secureinfomsgh2{
+ margin-top:2px;
+ margin-bottom:2px;
+ padding-left:5px;
+ background-color:#ffffcc;
+}
+
+#secureinfomsgh[signed="notok"],#secureinfomsgh2[signed="notok"]{background-color:#ff5959;}
+#secureinfomsgh[signed="ok"],#secureinfomsgh2[signed="ok"]{background-color:#CAFF70;}
+#secureinfomsgh[signed="warning"],#secureinfomsgh2[signed="warning"]{background-color:#E76914;}
+
+#secureinfomsg label,
+#secureinfomsg2 label{
+ font-weight: bold;
+ cursor: pointer;
+}
+#secureinfomsg label:hover,
+#secureinfomsg2 label:hover{
+ color: #00007f;
+}
\ No newline at end of file
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. \r
+ * Contributor(s): \r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */\r
+\r
+/* ===== msgReadSecureHeaders.css ========================================\r
+ == Styles for the secure headers info window when displaying received mail.\r
+ ======================================================================= */\r
+\r
+@import url("chrome://messenger/skin/");\r
+\r
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");\r
+\r
+#secHeader_treechild_id::-moz-tree-row(selected){ \r
+ background-color: DarkGray;\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-row(odd){ \r
+ background-color: #EEEEEE;\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-row(odd, selected){ \r
+ background-color: DarkGray;\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-cell-text(valid){ \r
+ color: green;\r
+}\r
+#secHeader_treechild_id::-moz-tree-cell-text(invalid){ \r
+ color: #b10000;\r
+ font-weight: bold;\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-cell-text(unsigned){ \r
+ color: #E76914; \r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-image(valid){\r
+ list-style-image: url("chrome://messenger/skin/smime/icons/check_sign.png");\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-image(invalid){\r
+ list-style-image: url("chrome://messenger/skin/smime/icons/cross_sign.png");\r
+}\r
+\r
+#secHeader_treechild_id::-moz-tree-image(unsigned){\r
+ list-style-image: url("chrome://messenger/skin/smime/icons/unsign.png");\r
+}
\ No newline at end of file
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/* ===== msgReadSecurityInfo.css ========================================
+ == Styles for the security info window when displaying received mail.
+ ======================================================================= */
+
+@import url("chrome://messenger/skin/");
+
+@namespace url("http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul");
+
+#signatureLabel {
+ font-weight: bold;
+}
+
+#signatureCert {
+ margin: 5px;
+}
+
+#encryptionLabel {
+ font-weight: bold;
+}
+
+#encryptionCert {
+ margin: 5px;
+}
+
+#securityLabel {
+ font-weight: bold;
+}
+
+#securityLabelContent {
+ margin: 5px;
+}
\ No newline at end of file
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/**
+ * Use of items in this file require:
+ *
+ * GetSelectedDirectory()
+ * returns the URI of the selected directory
+ * AbResultsPaneDoubleClick(card)
+ * Is called when the results pane is double-clicked, with the clicked card.
+ * AbEditCard(card)
+ * Is called when a card is to be edited, with the card as the parameter.
+ *
+ * The following function is only required if ResultsPaneController is used:
+ *
+ * goSetMenuValue()
+ * Core function in globalOverlay.js
+ */
+
+// List/card selections in the results pane.
+const kNothingSelected = 0;
+const kListsAndCards = 1;
+const kMultipleListsOnly = 2;
+const kSingleListOnly = 3;
+const kCardsOnly = 4;
+
+// Global Variables
+
+// gAbView holds an object with an nsIAbView interface
+var gAbView = null;
+// Holds a reference to the "abResultsTree" document element. Initially
+// set up by SetAbView.
+var gAbResultsTree = null;
+
+function SetAbView(aURI)
+{
+ // If we don't have a URI, just clear the view and leave everything else
+ // alone.
+ if (!aURI) {
+ gAbView.clearView();
+ return;
+ }
+
+ // If we do have a URI, we want to allow updating the review even if the
+ // URI is the same, as the search results may be different.
+
+ var sortColumn = kDefaultSortColumn;
+ var sortDirection = kDefaultAscending;
+
+ if (!gAbResultsTree) {
+ gAbResultsTree = document.getElementById("abResultsTree");
+ gAbResultsTree.controllers.appendController(ResultsPaneController);
+ }
+
+ if (gAbView) {
+ sortColumn = gAbView.sortColumn;
+ sortDirection = gAbView.sortDirection;
+ }
+ else {
+ if (gAbResultsTree.hasAttribute("sortCol"))
+ sortColumn = gAbResultsTree.getAttribute("sortCol");
+ var sortColumnNode = document.getElementById(sortColumn);
+ if (sortColumnNode && sortColumnNode.hasAttribute("sortDirection"))
+ sortDirection = sortColumnNode.getAttribute("sortDirection");
+ }
+
+ var directory = GetDirectoryFromURI(aURI);
+
+ if (!gAbView)
+ gAbView = Components.classes["@mozilla.org/addressbook/abview;1"]
+ .createInstance(Components.interfaces.nsIAbView);
+
+ var actualSortColumn = gAbView.setView(directory, GetAbViewListener(),
+ sortColumn, sortDirection);
+
+ gAbResultsTree.treeBoxObject.view =
+ gAbView.QueryInterface(Components.interfaces.nsITreeView);
+
+ UpdateSortIndicators(actualSortColumn, sortDirection);
+}
+
+function CloseAbView()
+{
+ if (gAbView)
+ gAbView.clearView();
+}
+
+function GetOneOrMoreCardsSelected()
+{
+ return (gAbView && (gAbView.selection.getRangeCount() > 0));
+}
+
+function GetSelectedAddresses()
+{
+ return GetAddressesForCards(GetSelectedAbCards());
+}
+
+function GetNumSelectedCards()
+{
+ try {
+ return gAbView.selection.count;
+ }
+ catch (ex) {
+ }
+
+ // if something went wrong, return 0 for the count.
+ return 0;
+}
+
+function GetSelectedCardTypes()
+{
+ var cards = GetSelectedAbCards();
+ if (!cards)
+ return kNothingSelected; // no view
+
+ var count = cards.length;
+ if (count == 0)
+ return kNothingSelected; // nothing selected
+
+ var mailingListCnt = 0;
+ var cardCnt = 0;
+ for (var i = 0; i < count; i++) {
+ if (cards[i].isMailList)
+ mailingListCnt++;
+ else
+ cardCnt++;
+ }
+ return (mailingListCnt == 0) ? kCardsOnly :
+ (cardCnt > 0) ? kListsAndCards :
+ (mailingListCnt == 1) ? kSingleListOnly :
+ kMultipleListsOnly;
+}
+
+// NOTE, will return -1 if more than one card selected, or no cards selected.
+function GetSelectedCardIndex()
+{
+ if (!gAbView)
+ return -1;
+
+ var treeSelection = gAbView.selection;
+ if (treeSelection.getRangeCount() == 1) {
+ var start = new Object;
+ var end = new Object;
+ treeSelection.getRangeAt(0, start, end);
+ if (start.value == end.value)
+ return start.value;
+ }
+
+ return -1;
+}
+
+// NOTE, returns the card if exactly one card is selected, null otherwise
+function GetSelectedCard()
+{
+ var index = GetSelectedCardIndex();
+ return (index == -1) ? null : gAbView.getCardFromRow(index);
+}
+
+function GetSelectedAbCards()
+{
+ var abView = gAbView;
+
+ // if sidebar is open, and addressbook panel is open and focused,
+ // then use the ab view from sidebar (gCurFrame is from sidebarOverlay.js)
+ if (document.getElementById("sidebar-box")) {
+ const abPanelUrl =
+ "chrome://messenger/content/addressbook/addressbook-panel.xul";
+ if (gCurFrame &&
+ gCurFrame.getAttribute("src") == abPanelUrl &&
+ document.commandDispatcher.focusedWindow == gCurFrame.contentDocument.defaultView)
+ abView = gCurFrame.contentDocument.defaultView.gAbView;
+ }
+
+ if (!abView)
+ return null;
+
+ var cards = new Array(abView.selection.count);
+ var i, j;
+ var count = abView.selection.getRangeCount();
+ var current = 0;
+ for (i = 0; i < count; ++i) {
+ var start = new Object;
+ var end = new Object;
+ abView.selection.getRangeAt(i,start,end);
+ for (j = start.value; j <= end.value; ++j)
+ cards[current++] = abView.getCardFromRow(j);
+ }
+ return cards;
+}
+
+// XXX todo
+// an optimization might be to make this return
+// the selected ranges, which would be faster
+// when the user does large selections, but for now, let's keep it simple.
+function GetSelectedRows()
+{
+ var selectedRows = "";
+
+ if (!gAbView)
+ return selectedRows;
+
+ var i, j;
+ var rangeCount = gAbView.selection.getRangeCount();
+ for (i = 0; i < rangeCount; ++i) {
+ var start = new Object;
+ var end = new Object;
+ gAbView.selection.getRangeAt(i, start, end);
+ for (j = start.value;j <= end.value; ++j) {
+ if (selectedRows)
+ selectedRows += ",";
+ selectedRows += j;
+ }
+ }
+
+ return selectedRows;
+}
+
+function AbSwapFirstNameLastName()
+{
+ if (gAbView)
+ gAbView.swapFirstNameLastName();
+}
+
+function AbEditSelectedCard()
+{
+ AbEditCard(GetSelectedCard());
+}
+
+function AbResultsPaneOnClick(event)
+{
+ // we only care about button 0 (left click) events
+ if (event.button != 0) return;
+
+ // all we need to worry about here is double clicks
+ // and column header clicks.
+ //
+ // we get in here for clicks on the "treecol" (headers)
+ // and the "scrollbarbutton" (scrollbar buttons)
+ // we don't want those events to cause a "double click"
+
+ var t = event.originalTarget;
+
+ if (t.localName == "treecol") {
+ var sortDirection;
+ var currentDirection = t.getAttribute("sortDirection");
+
+ // Revert the sort order. If none is set, use Ascending.
+ sortDirection = currentDirection == kDefaultAscending ?
+ kDefaultDescending : kDefaultAscending;
+
+ SortAndUpdateIndicators(t.id, sortDirection);
+ }
+ else if (t.localName == "treechildren") {
+ // figure out what row the click was in
+ var row = gAbResultsTree.treeBoxObject.getRowAt(event.clientX,
+ event.clientY);
+ if (row == -1)
+ return;
+
+ if (event.detail == 2)
+ AbResultsPaneDoubleClick(gAbView.getCardFromRow(row));
+ }
+}
+
+function AbSortAscending()
+{
+ var sortColumn = gAbResultsTree.getAttribute("sortCol");
+ SortAndUpdateIndicators(sortColumn, kDefaultAscending);
+}
+
+function AbSortDescending()
+{
+ var sortColumn = gAbResultsTree.getAttribute("sortCol");
+ SortAndUpdateIndicators(sortColumn, kDefaultDescending);
+}
+
+function SortResultPane(sortColumn)
+{
+ var sortDirection = kDefaultAscending;
+ if (gAbView)
+ sortDirection = gAbView.sortDirection;
+
+ SortAndUpdateIndicators(sortColumn, sortDirection);
+}
+
+function SortAndUpdateIndicators(sortColumn, sortDirection)
+{
+ UpdateSortIndicators(sortColumn, sortDirection);
+
+ if (gAbView)
+ gAbView.sortBy(sortColumn, sortDirection);
+}
+
+function UpdateSortIndicators(colID, sortDirection)
+{
+ var sortedColumn = null;
+
+ // set the sort indicator on the column we are sorted by
+ if (colID) {
+ sortedColumn = document.getElementById(colID);
+ if (sortedColumn) {
+ sortedColumn.setAttribute("sortDirection",sortDirection);
+ gAbResultsTree.setAttribute("sortCol", colID);
+ }
+ }
+
+ // remove the sort indicator from all the columns
+ // except the one we are sorted by
+ var currCol = gAbResultsTree.firstChild.firstChild;
+ while (currCol) {
+ if (currCol != sortedColumn && currCol.localName == "treecol")
+ currCol.removeAttribute("sortDirection");
+ currCol = currCol.nextSibling;
+ }
+}
+
+function InvalidateResultsPane()
+{
+ if (gAbResultsTree)
+ gAbResultsTree.treeBoxObject.invalidate();
+}
+
+// Controller object for Results Pane
+var ResultsPaneController =
+{
+ supportsCommand: function(command)
+ {
+ switch (command) {
+ case "cmd_selectAll":
+ case "cmd_delete":
+ case "button_delete":
+ case "button_edit":
+ case "cmd_newlist":
+ return true;
+ default:
+ return false;
+ }
+ },
+
+ isCommandEnabled: function(command)
+ {
+ switch (command) {
+ case "cmd_selectAll":
+ return true;
+ case "cmd_delete":
+ case "button_delete":
+ var numSelected;
+ var enabled = false;
+ if (gAbView && gAbView.selection) {
+ if (gAbView.directory)
+ enabled = !gAbView.directory.readOnly;
+ numSelected = gAbView.selection.count;
+ }
+ else
+ numSelected = 0;
+
+ // fix me, don't update on isCommandEnabled
+ if (command == "cmd_delete") {
+ switch (GetSelectedCardTypes()) {
+ case kSingleListOnly:
+ goSetMenuValue(command, "valueList");
+ break;
+ case kMultipleListsOnly:
+ goSetMenuValue(command, "valueLists");
+ break;
+ case kListsAndCards:
+ goSetMenuValue(command, "valueItems");
+ break;
+ case kCardsOnly:
+ default:
+ if (numSelected < 2)
+ goSetMenuValue(command, "valueCard");
+ else
+ goSetMenuValue(command, "valueCards");
+ break;
+ }
+ }
+ return (enabled && (numSelected > 0));
+ case "button_edit":
+ return (GetSelectedCardIndex() != -1);
+ case "cmd_newlist":
+ var selectedDir = GetSelectedDirectory();
+ if (selectedDir) {
+ var abDir = GetDirectoryFromURI(selectedDir);
+ if (abDir) {
+ return abDir.supportsMailingLists;
+ }
+ }
+ return false;
+ default:
+ return false;
+ }
+ },
+
+ doCommand: function(command)
+ {
+ switch (command) {
+ case "cmd_selectAll":
+ if (gAbView)
+ gAbView.selectAll();
+ break;
+ case "cmd_delete":
+ case "button_delete":
+ AbDelete();
+ break;
+ case "button_edit":
+ AbEditSelectedCard();
+ break;
+ case "cmd_newlist":
+ AbNewList();
+ break;
+ }
+ },
+
+ onEvent: function(event)
+ {
+ // on blur events set the menu item texts back to the normal values
+ if (event == "blur")
+ goSetMenuValue("cmd_delete", "valueDefault");
+ }
+};
+
+function SelectFirstCard()
+{
+ if (gAbView && gAbView.selection)
+ gAbView.selection.select(0);
+}
--- /dev/null
+/* -*- Mode: Java; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */
+
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+Components.utils.import("resource:///modules/mailServices.js");
+Components.utils.import("resource:///modules/hostnameUtils.jsm");
+
+var gCurrentDirectory = null;
+var gReplicationBundle = null;
+var gReplicationService =
+ Components.classes["@mozilla.org/addressbook/ldap-replication-service;1"].
+ getService(Components.interfaces.nsIAbLDAPReplicationService);
+var gReplicationCancelled = false;
+var gProgressText;
+var gProgressMeter;
+var gDownloadInProgress = false;
+
+const kDefaultMaxHits = 100;
+const kDefaultLDAPPort = 389;
+const kDefaultSecureLDAPPort = 636;
+const kLDAPDirectory = 0; // defined in nsDirPrefs.h
+
+var ldapOfflineObserver = {
+ observe: function(subject, topic, state)
+ {
+ // sanity checks
+ if (topic != "network:offline-status-changed") return;
+ setDownloadOfflineOnlineState(state == "offline");
+ }
+}
+
+function Startup()
+{
+ gReplicationBundle = document.getElementById("bundle_replication");
+
+ document.getElementById("download").label =
+ gReplicationBundle.getString("downloadButton");
+ document.getElementById("download").accessKey =
+ gReplicationBundle.getString("downloadButton.accesskey");
+
+ if ("arguments" in window && window.arguments[0]) {
+ gCurrentDirectory = window.arguments[0].selectedDirectory;
+ try {
+ fillSettings();
+ } catch (ex) {
+ dump("pref-directory-add.js:Startup(): fillSettings() exception: "
+ + ex + "\n");
+ }
+
+ // Only set up the download button for online/offline status toggling
+ // if the pref isn't locked to disable the button.
+ if (!Services.prefs.prefIsLocked(gCurrentDirectory.dirPrefId +
+ ".disable_button_download")) {
+ // Now connect to the offline/online observer
+ Services.obs.addObserver(ldapOfflineObserver,
+ "network:offline-status-changed", false);
+
+ // Now set the initial offline/online state and update the state
+ setDownloadOfflineOnlineState(Services.io.offline);
+ }
+ } else {
+ fillDefaultSettings();
+ // Don't add observer here as it doesn't make any sense.
+ }
+}
+
+function onUnload()
+{
+ if ("arguments" in window &&
+ window.arguments[0] &&
+ !Services.prefs.prefIsLocked(gCurrentDirectory.dirPrefId +
+ ".disable_button_download")) {
+ // Remove the observer that we put in on dialog startup
+ Services.obs.removeObserver(ldapOfflineObserver,
+ "network:offline-status-changed");
+ }
+}
+
+var progressListener = {
+ onStateChange: function(aWebProgress, aRequest, aStateFlags, aStatus)
+ {
+ if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_START) {
+ // start the spinning
+ gProgressMeter.setAttribute("mode", "undetermined");
+ gProgressText.value = gReplicationBundle.getString(aStatus ?
+ "replicationStarted" :
+ "changesStarted");
+ gDownloadInProgress = true;
+ document.getElementById("download").label =
+ gReplicationBundle.getString("cancelDownloadButton");
+ document.getElementById("download").accessKey =
+ gReplicationBundle.getString("cancelDownloadButton.accesskey");
+ }
+
+ if (aStateFlags & Components.interfaces.nsIWebProgressListener.STATE_STOP) {
+ EndDownload(aStatus);
+ }
+ },
+ onProgressChange: function(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress)
+ {
+ gProgressText.value = gReplicationBundle.getFormattedString("currentCount",
+ [aCurSelfProgress]);
+ },
+ onLocationChange: function(aWebProgress, aRequest, aLocation, aFlags)
+ {
+ },
+ onStatusChange: function(aWebProgress, aRequest, aStatus, aMessage)
+ {
+ },
+ onSecurityChange: function(aWebProgress, aRequest, state)
+ {
+ },
+ QueryInterface : function(iid)
+ {
+ if (iid.equals(Components.interfaces.nsIWebProgressListener) ||
+ iid.equals(Components.interfaces.nsISupportsWeakReference) ||
+ iid.equals(Components.interfaces.nsISupports))
+ return this;
+ throw Components.results.NS_NOINTERFACE;
+ }
+};
+
+function DownloadNow()
+{
+ if (!gDownloadInProgress) {
+ gProgressText = document.getElementById("replicationProgressText");
+ gProgressMeter = document.getElementById("replicationProgressMeter");
+
+ gProgressText.hidden = false;
+ gProgressMeter.hidden = false;
+ gReplicationCancelled = false;
+
+ try {
+ if (gCurrentDirectory instanceof Components.interfaces.nsIAbLDAPDirectory)
+ gReplicationService.startReplication(gCurrentDirectory,
+ progressListener);
+ else
+ EndDownload(false);
+ }
+ catch (ex) {
+ EndDownload(false);
+ }
+ } else {
+ gReplicationCancelled = true;
+ try {
+ gReplicationService.cancelReplication(gCurrentDirectory.dirPrefId);
+ }
+ catch (ex) {
+ // XXX todo
+ // perhaps replication hasn't started yet? This can happen if you hit cancel after attempting to replication when offline
+ dump("unexpected failure while cancelling. ex=" + ex + "\n");
+ }
+ }
+}
+
+function EndDownload(aStatus)
+{
+ document.getElementById("download").label =
+ gReplicationBundle.getString("downloadButton");
+ document.getElementById("download").accessKey =
+ gReplicationBundle.getString("downloadButton.accesskey");
+
+ // stop the spinning
+ gProgressMeter.setAttribute("mode", "normal");
+ gProgressMeter.setAttribute("value", "100");
+ gProgressMeter.hidden = true;
+
+ gDownloadInProgress = false;
+ gProgressText.value =
+ gReplicationBundle.getString(aStatus ? "replicationSucceeded" :
+ gReplicationCancelled ? "replicationCancelled" :
+ "replicationFailed");
+}
+
+// fill the settings panel with the data from the preferences.
+//
+function fillSettings()
+{
+ document.getElementById("description").value = gCurrentDirectory.dirName;
+
+ if (gCurrentDirectory instanceof Components.interfaces.nsIAbLDAPDirectory) {
+ var ldapUrl = gCurrentDirectory.lDAPURL;
+
+ document.getElementById("results").value = gCurrentDirectory.maxHits;
+ document.getElementById("login").value = gCurrentDirectory.authDn;
+ document.getElementById("hostname").value = ldapUrl.host;
+ document.getElementById("basedn").value = ldapUrl.dn;
+ document.getElementById("search").value = ldapUrl.filter;
+
+ var sub = document.getElementById("sub");
+ switch(ldapUrl.scope) {
+ case Components.interfaces.nsILDAPURL.SCOPE_ONELEVEL:
+ sub.radioGroup.selectedItem = document.getElementById("one");
+ break;
+ default:
+ sub.radioGroup.selectedItem = sub;
+ break;
+ }
+
+ var sasl = document.getElementById("saslMechanism");
+ switch (gCurrentDirectory.saslMechanism) {
+ case "GSSAPI":
+ sasl.selectedItem = document.getElementById("GSSAPI");
+ break;
+ case "EXTERNAL":
+ sasl.selectedItem = document.getElementById("EXTERNAL");
+ break;
+ default:
+ sasl.selectedItem = document.getElementById("Simple");
+ break;
+ }
+
+ var secure = ldapUrl.options & ldapUrl.OPT_SECURE
+ if (secure)
+ document.getElementById("secure").setAttribute("checked", "true");
+
+ if (ldapUrl.port == -1)
+ document.getElementById("port").value =
+ (secure ? kDefaultSecureLDAPPort : kDefaultLDAPPort);
+ else
+ document.getElementById("port").value = ldapUrl.port;
+ }
+
+ // check if any of the preferences for this server are locked.
+ //If they are locked disable them
+ DisableUriFields(gCurrentDirectory.dirPrefId + ".uri");
+ DisableElementIfPrefIsLocked(gCurrentDirectory.dirPrefId + ".description", "description");
+ DisableElementIfPrefIsLocked(gCurrentDirectory.dirPrefId + ".disable_button_download", "download");
+ DisableElementIfPrefIsLocked(gCurrentDirectory.dirPrefId + ".maxHits", "results");
+ DisableElementIfPrefIsLocked(gCurrentDirectory.dirPrefId + ".auth.dn", "login");
+}
+
+function DisableElementIfPrefIsLocked(aPrefName, aElementId)
+{
+ if (Services.prefs.prefIsLocked(aPrefName))
+ document.getElementById(aElementId).setAttribute('disabled', true);
+}
+
+// disables all the text fields corresponding to the .uri pref.
+function DisableUriFields(aPrefName)
+{
+ if (Services.prefs.prefIsLocked(aPrefName)) {
+ let lockedElements = document.querySelectorAll('[disableiflocked="true"]');
+ for (let i = 0; i < lockedElements.length; i++)
+ lockedElements[i].setAttribute('disabled', 'true');
+ }
+}
+
+function onSecure()
+{
+ document.getElementById("port").value =
+ document.getElementById("secure").checked ? kDefaultSecureLDAPPort :
+ kDefaultLDAPPort;
+}
+
+function fillDefaultSettings()
+{
+ document.getElementById("port").value = kDefaultLDAPPort;
+ document.getElementById("results").value = kDefaultMaxHits;
+ var sub = document.getElementById("sub");
+ sub.radioGroup.selectedItem = sub;
+
+ // Disable the download button and add some text indicating why.
+ document.getElementById("download").disabled = true;
+ document.getElementById("downloadWarningMsg").hidden = false;
+ document.getElementById("downloadWarningMsg").textContent = document.
+ getElementById("bundle_addressBook").
+ getString("abReplicationSaveSettings");
+}
+
+function hasOnlyWhitespaces(string)
+{
+ // get all the whitespace characters of string and assign them to str.
+ // string is not modified in this function
+ // returns true if string contains only whitespaces and/or tabs
+ var re = /[ \s]/g;
+ var str = string.match(re);
+ if (str && (str.length == string.length))
+ return true;
+ else
+ return false;
+}
+
+function hasCharacters(number)
+{
+ var re = /[0-9]/g;
+ var num = number.match(re);
+ if(num && (num.length == number.length))
+ return false;
+ else
+ return true;
+}
+
+function onAccept()
+{
+ try {
+ var pref_string_content = "";
+ var pref_string_title = "";
+
+ var description = document.getElementById("description").value;
+ var hostname = cleanUpHostName(document.getElementById("hostname").value);
+ var port = document.getElementById("port").value;
+ var secure = document.getElementById("secure");
+ var results = document.getElementById("results").value;
+ var errorValue = null;
+ var saslMechanism = "";
+ if ((!description) || (description.trim() == ""))
+ errorValue = "invalidName";
+ else if (!isLegalHostNameOrIP(hostname))
+ errorValue = "invalidHostname";
+ // XXX write isValidDn and call it on the dn string here?
+ else if (port && hasCharacters(port))
+ errorValue = "invalidPortNumber";
+ else if (results && hasCharacters(results))
+ errorValue = "invalidResults";
+ if (!errorValue) {
+ // XXX Due to the LDAP c-sdk pass a dummy url to the IO service, then
+ // update the parts (bug 473351).
+ let ldapUrl = Services.io.newURI(
+ (secure.checked ? "ldaps://" : "ldap://") + "localhost/dc=???", null, null)
+ .QueryInterface(Components.interfaces.nsILDAPURL);
+
+ ldapUrl.host = hostname;
+ ldapUrl.port = port ? port :
+ (secure.checked ? kDefaultSecureLDAPPort :
+ kDefaultLDAPPort);
+ ldapUrl.dn = document.getElementById("basedn").value;
+ ldapUrl.scope = document.getElementById("one").selected ?
+ Components.interfaces.nsILDAPURL.SCOPE_ONELEVEL :
+ Components.interfaces.nsILDAPURL.SCOPE_SUBTREE;
+
+ ldapUrl.filter = document.getElementById("search").value;
+ if (document.getElementById("GSSAPI").selected) {
+ saslMechanism = "GSSAPI";
+ }
+ if (document.getElementById("EXTERNAL").selected) {
+ saslMechanism = "EXTERNAL";
+ }
+
+ // check if we are modifying an existing directory or adding a new directory
+ if (gCurrentDirectory) {
+ gCurrentDirectory.dirName = description;
+ gCurrentDirectory.lDAPURL = ldapUrl.QueryInterface(Components.interfaces.nsILDAPURL);
+ window.opener.gNewServerString = gCurrentDirectory.dirPrefId;
+ }
+ else { // adding a new directory
+ window.opener.gNewServerString =
+ MailServices.ab.newAddressBook(description, ldapUrl.spec, kLDAPDirectory);
+ }
+
+ // XXX This is really annoying - both new/modify Address Book don't
+ // give us back the new directory we just created - so go find it from
+ // rdf so we can set a few final things up on it.
+ var targetURI = "moz-abldapdirectory://" + window.opener.gNewServerString;
+ var theDirectory =
+ MailServices.ab.getDirectory(targetURI)
+ .QueryInterface(Components.interfaces.nsIAbLDAPDirectory);
+
+ theDirectory.maxHits = results;
+ theDirectory.authDn = document.getElementById("login").value;
+ theDirectory.saslMechanism = saslMechanism;
+
+ window.opener.gNewServer = description;
+ // set window.opener.gUpdate to true so that LDAP Directory Servers
+ // dialog gets updated
+ window.opener.gUpdate = true;
+ } else {
+ var addressBookBundle = document.getElementById("bundle_addressBook");
+
+ Services.prompt.alert(window,
+ document.title,
+ addressBookBundle.getString(errorValue));
+ return false;
+ }
+ } catch (outer) {
+ dump("Internal error in pref-directory-add.js:onAccept() " + outer + "\n");
+ }
+ return true;
+}
+
+function onCancel()
+{
+ window.opener.gUpdate = false;
+}
+
+
+// called by Help button in platform overlay
+function doHelpButton()
+{
+ openHelp("mail-ldap-properties");
+}
+
+// Sets the download button state for offline or online.
+// This function should only be called for ldap edit dialogs.
+function setDownloadOfflineOnlineState(isOffline)
+{
+ if (isOffline)
+ {
+ // Disable the download button and add some text indicating why.
+ document.getElementById("downloadWarningMsg").textContent = document.
+ getElementById("bundle_addressBook").
+ getString("abReplicationOfflineWarning");
+ }
+ document.getElementById("downloadWarningMsg").hidden = !isOffline;
+ document.getElementById("download").disabled = isOffline;
+}
--- /dev/null
+<?xml version="1.0"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ - Contributor(s):
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved -->
+
+<?xml-stylesheet href="chrome://messenger/skin/" type="text/css"?>
+
+<!DOCTYPE dialog SYSTEM "chrome://messenger/locale/addressbook/pref-directory-add.dtd">
+
+<dialog id="addDirectory"
+ style="width: &newDirectoryWidth;"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="&newDirectoryTitle.label;"
+ onload="Startup();"
+ onunload="onUnload();"
+ buttons="accept,cancel"
+ ondialogaccept="return onAccept();"
+ ondialogcancel="return onCancel();">
+
+ <script type="application/javascript" src="chrome://messenger/content/addressbook/pref-directory-add.js"/>
+ <stringbundle id="bundle_addressBook" src="chrome://messenger/locale/addressbook/addressBook.properties"/>
+ <stringbundle id="bundle_replication" src="chrome://messenger/locale/addressbook/replicationProgress.properties"/>
+
+ <keyset id="keyset"/>
+ <vbox id="editDirectory">
+
+ <tabbox style="margin:5px">
+ <tabs id="directoryTabBox">
+ <tab label="&General.tab;"/>
+ <tab label="&Offline.tab;"/>
+ <tab label="&Advanced.tab;"/>
+ </tabs>
+
+ <tabpanels id="directoryTabPanels" flex="1">
+ <vbox>
+ <grid flex="1">
+ <columns>
+ <column/>
+ <column flex="1"/>
+ <column/>
+ </columns>
+
+ <rows>
+ <row align="center">
+ <label value="&directoryName.label;" accesskey="&directoryName.accesskey;"
+ control="description"/>
+ <textbox id="description" flex="1"/>
+ <spacer flex="1"/>
+ </row>
+ <row align="center">
+ <label value="&directoryHostname.label;" accesskey="&directoryHostname.accesskey;"
+ control="hostname"/>
+ <textbox id="hostname" flex="1" disableiflocked="true" class="uri-element"/>
+ <spacer flex="1"/>
+ </row>
+ <row align="center">
+ <label value="&directoryBaseDN.label;"
+ accesskey="&directoryBaseDN.accesskey;"
+ control="basedn"/>
+ <vbox>
+ <textbox id="basedn" disableiflocked="true" class="uri-element"/>
+ </vbox>
+ <button label="&findButton.label;"
+ accesskey="&findButton.accesskey;" disabled="true"/>
+ </row>
+ <row align="center">
+ <label value="&portNumber.label;"
+ accesskey="&portNumber.accesskey;"
+ control="port"/>
+ <hbox>
+ <textbox id="port" type="number" size="5" min="1"
+ max="65535" hidespinbuttons="true"
+ disableiflocked="true"/>
+ </hbox>
+ </row>
+ <row align="center">
+ <label value="&directoryLogin.label;"
+ accesskey="&directoryLogin.accesskey;"
+ control="login"/>
+ <textbox id="login" flex="1" class="uri-element"/>
+ </row>
+ </rows>
+ </grid>
+ <separator/>
+ <checkbox id="secure" label="&directorySecure.label;"
+ accesskey="&directorySecure.accesskey;"
+ oncommand="onSecure();" disableiflocked="true"/>
+ </vbox>
+ <vbox>
+ <description>&offlineText.label;</description>
+ <separator/>
+ <hbox>
+ <button id="download" oncommand="DownloadNow();"/>
+ <spacer flex="1"/>
+ </hbox>
+ <description id="downloadWarningMsg" hidden="true" class="error"/>
+ <description id="replicationProgressText" hidden="true"/>
+
+ <progressmeter id="replicationProgressMeter" mode="normal" value="0" hidden="true"/>
+ </vbox>
+ <grid>
+ <columns>
+ <column/>
+ <column flex="1"/>
+ </columns>
+
+ <rows>
+ <row align="center">
+ <label value="&return.label;"
+ accesskey="&return.accesskey;"
+ control="results"/>
+ <hbox align="center">
+ <textbox id="results" type="number" size="10" min="1"
+ max="2147483647" hidespinbuttons="true"/>
+ <label value="&results.label;"/>
+ </hbox>
+ </row>
+ <row align="center">
+ <label value="&scope.label;" control="scope" accesskey="&scope.accesskey;"/>
+ <radiogroup id="scope" orient="horizontal">
+ <radio id="one" value="1" label="&scopeOneLevel.label;"
+ disableiflocked="true" accesskey="&scopeOneLevel.accesskey;"/>
+ <radio id="sub" value="2" label="&scopeSubtree.label;"
+ disableiflocked="true" accesskey="&scopeSubtree.accesskey;"/>
+ </radiogroup>
+ </row>
+ <row>
+ <label value="&searchFilter.label;"
+ accesskey="&searchFilter.accesskey;"
+ control="search"/>
+ <textbox id="search" multiline="true" flex="1" disableiflocked="true"/>
+ </row>
+ <row>
+ <label value="&saslMechanism.label;" control="saslMechanism" accesskey="&saslMechanism.accesskey;"/>
+ <menulist id="saslMechanism">
+ <menupopup>
+ <menuitem id="Simple" value=""
+ label="&saslOff.label;"
+ accesskey="&saslOff.accesskey;"/>
+ <menuitem id="GSSAPI" value="GSSAPI"
+ label="&saslGSSAPI.label;"
+ accesskey="&saslGSSAPI.accesskey;"/>
+ <menuitem id="EXTERNAL" value="EXTERNAL"
+ label="&saslEXTERNAL.label;"
+ accesskey="&saslEXTERNAL.accesskey;"/>
+ </menupopup>
+ </menulist>
+ </row>
+ </rows>
+ </grid>
+ </tabpanels>
+ </tabbox>
+ </vbox>
+
+</dialog>
+
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */
+
+#include "nsAbLDAPListenerBase.h"
+#include "nsIWindowWatcher.h"
+#include "nsIWindowMediator.h"
+#include "nsIDOMWindow.h"
+#include "nsIAuthPrompt.h"
+#include "nsIStringBundle.h"
+#include "nsILDAPMessage.h"
+#include "nsILDAPErrors.h"
+#include "nsILoginManager.h"
+#include "nsILoginInfo.h"
+#include "nsServiceManagerUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "nsMemory.h"
+#include "mozilla/Services.h"
+#include "nspr.h"
+
+using namespace mozilla;
+
+
+#ifdef PR_LOGGING
+static PRLogModuleInfo* gLDAPLog
+ = PR_NewLogModule("LDAPLog");
+#endif
+
+#define PRINTF(args) PR_LOG(gLDAPLog, PR_LOG_DEBUG, args)
+
+nsAbLDAPListenerBase::nsAbLDAPListenerBase(nsILDAPURL* url,
+ nsILDAPConnection* connection,
+ const nsACString &login,
+ const int32_t timeOut) :
+ mDirectoryUrl(url), mConnection(connection), mLogin(login),
+ mTimeOut(timeOut), mBound(false), mInitialized(false),
+ mLock("nsAbLDAPListenerBase.mLock")
+{
+}
+
+nsAbLDAPListenerBase::~nsAbLDAPListenerBase()
+{
+}
+
+nsresult nsAbLDAPListenerBase::Initiate()
+{
+ if (!mConnection || !mDirectoryUrl)
+ return NS_ERROR_NULL_POINTER;
+
+ if (mInitialized)
+ return NS_OK;
+
+ mInitialized = true;
+
+ return NS_OK;
+}
+
+// If something fails in this function, we must call InitFailed() so that the
+// derived class (and listener) knows to cancel what its doing as there is
+// a problem.
+NS_IMETHODIMP nsAbLDAPListenerBase::OnLDAPInit(nsILDAPConnection *aConn, nsresult aStatus)
+{
+ if (!mConnection || !mDirectoryUrl)
+ {
+ InitFailed();
+ return NS_ERROR_NULL_POINTER;
+ }
+
+ nsresult rv;
+ nsString passwd;
+
+ // Make sure that the Init() worked properly
+ if (NS_FAILED(aStatus))
+ {
+ InitFailed();
+ return NS_OK;
+ }
+
+ // If mLogin is set, we're expected to use it to get a password.
+ //
+ if (!mLogin.IsEmpty() && (!mSaslMechanism.EqualsLiteral("GSSAPI")
+ || !mSaslMechanism.EqualsLiteral("EXTERNAL")) )
+ {
+ // get the string bundle service
+ //
+ nsCOMPtr<nsIStringBundleService> stringBundleSvc =
+ mozilla::services::GetStringBundleService();
+ if (!stringBundleSvc)
+ {
+ NS_ERROR("nsAbLDAPListenerBase::OnLDAPInit():"
+ " error getting string bundle service");
+ InitFailed();
+ return NS_ERROR_UNEXPECTED;
+ }
+
+ // get the LDAP string bundle
+ //
+ nsCOMPtr<nsIStringBundle> ldapBundle;
+ rv = stringBundleSvc->CreateBundle("chrome://mozldap/locale/ldap.properties",
+ getter_AddRefs(ldapBundle));
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPListenerBase::OnLDAPInit(): error creating string"
+ "bundle chrome://mozldap/locale/ldap.properties");
+ InitFailed();
+ return rv;
+ }
+
+ // get the title for the authentication prompt
+ //
+ nsString authPromptTitle;
+ rv = ldapBundle->GetStringFromName(NS_LITERAL_STRING("authPromptTitle").get(),
+ getter_Copies(authPromptTitle));
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPListenerBase::OnLDAPInit(): error getting"
+ "'authPromptTitle' string from bundle "
+ "chrome://mozldap/locale/ldap.properties");
+ InitFailed();
+ return rv;
+ }
+
+ // get the host name for the auth prompt
+ //
+ nsAutoCString host;
+ rv = mDirectoryUrl->GetAsciiHost(host);
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPListenerBase::OnLDAPInit(): error getting ascii host"
+ "name from directory url");
+ InitFailed();
+ return rv;
+ }
+
+ // hostTemp is only necessary to work around a code-generation
+ // bug in egcs 1.1.2 (the version of gcc that comes with Red Hat 6.2),
+ // which is the default compiler for Mozilla on linux at the moment.
+ //
+ NS_ConvertASCIItoUTF16 hostTemp(host);
+ const PRUnichar *hostArray[1] = { hostTemp.get() };
+
+ // format the hostname into the authprompt text string
+ //
+ nsString authPromptText;
+ rv = ldapBundle->FormatStringFromName(NS_LITERAL_STRING("authPromptText").get(),
+ hostArray,
+ sizeof(hostArray) / sizeof(const PRUnichar *),
+ getter_Copies(authPromptText));
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPListenerBase::OnLDAPInit():"
+ "error getting 'authPromptText' string from bundle "
+ "chrome://mozldap/locale/ldap.properties");
+ InitFailed();
+ return rv;
+ }
+
+ // get the window mediator service, so we can get an auth prompter
+ //
+ nsCOMPtr<nsIWindowMediator> windowMediator =
+ do_GetService(NS_WINDOWMEDIATOR_CONTRACTID, &rv);
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPListenerBase::OnLDAPInit():"
+ " couldn't get window mediator service.");
+ InitFailed();
+ return rv;
+ }
+
+ // get the addressbook window, as it will be used to parent the auth
+ // prompter dialog
+ //
+ nsCOMPtr<nsIDOMWindow> window;
+ rv = windowMediator->GetMostRecentWindow(nullptr,
+ getter_AddRefs(window));
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPListenerBase::OnLDAPInit():"
+ " error getting most recent window");
+ InitFailed();
+ return rv;
+ }
+
+ // get the window watcher service, so we can get an auth prompter
+ //
+ nsCOMPtr<nsIWindowWatcher> windowWatcherSvc =
+ do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPListenerBase::OnLDAPInit():"
+ " couldn't get window watcher service.");
+ InitFailed();
+ return rv;
+ }
+
+ // get the auth prompter itself
+ //
+ nsCOMPtr<nsIAuthPrompt> authPrompter;
+ rv = windowWatcherSvc->GetNewAuthPrompter(window,
+ getter_AddRefs(authPrompter));
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPMessageBase::OnLDAPInit():"
+ " error getting auth prompter");
+ InitFailed();
+ return rv;
+ }
+
+ // get authentication password, prompting the user if necessary
+ //
+ // we're going to use the URL spec of the server as the "realm" for
+ // wallet to remember the password by / for.
+
+ // Get the specification
+ nsCString spec;
+ rv = mDirectoryUrl->GetSpec(spec);
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPMessageBase::OnLDAPInit():"
+ " error getting directory url spec");
+ InitFailed();
+ return rv;
+ }
+
+ bool status;
+ rv = authPrompter->PromptPassword(authPromptTitle.get(),
+ authPromptText.get(),
+ NS_ConvertUTF8toUTF16(spec).get(),
+ nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
+ getter_Copies(passwd),
+ &status);
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPMessageBase::OnLDAPInit(): failed to prompt for"
+ " password");
+ InitFailed();
+ return rv;
+ }
+ else if (!status)
+ {
+ InitFailed(true);
+ return NS_OK;
+ }
+ }
+
+ // Initiate the LDAP operation
+ mOperation = do_CreateInstance(NS_LDAPOPERATION_CONTRACTID, &rv);
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPMessageBase::OnLDAPInit(): failed to create ldap operation");
+ InitFailed();
+ return rv;
+ }
+
+ rv = mOperation->Init(mConnection, this, nullptr);
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPMessageBase::OnLDAPInit(): failed to Initialise operation");
+ InitFailed();
+ return rv;
+ }
+
+ // non-password mechanisms EXTERNAL
+ if (mSaslMechanism.EqualsLiteral("EXTERNAL"))
+ {
+ PRINTF(("mOperation->SaslBind2();\n"));
+ rv = mOperation->SaslBind2();
+
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPMessageBase::OnLDAPInit(): "
+ "failed to perform EXTERNAL bind");
+ mOperation = 0; // Break Listener -> Operation -> Listener ref cycle
+ InitFailed();
+ PRINTF(("mOperation->SaslBind2() Failed;\n"));
+ }
+ else
+ PRINTF(("mOperation->SaslBind2() OK;\n"));
+ return rv;
+ }
+
+ // Try non-password mechanisms first
+ if (mSaslMechanism.EqualsLiteral("GSSAPI"))
+ {
+ PRINTF(("mOperation->SaslBind() GSSAPI;\n"));
+
+ nsAutoCString service;
+ rv = mDirectoryUrl->GetAsciiHost(service);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ service.Insert(NS_LITERAL_CSTRING("ldap@"), 0);
+
+ nsCOMPtr<nsIAuthModule> authModule =
+ do_CreateInstance(NS_AUTH_MODULE_CONTRACTID_PREFIX "sasl-gssapi", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = mOperation->SaslBind(service, mSaslMechanism, authModule);
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPMessageBase::OnLDAPInit(): "
+ "failed to perform GSSAPI bind");
+ mOperation = 0; // Break Listener -> Operation -> Listener ref cycle
+ InitFailed();
+ }
+ return rv;
+ }
+
+ // Bind
+ PRINTF(("mOperation->SimpleBind() \n"));
+ rv = mOperation->SimpleBind(NS_ConvertUTF16toUTF8(passwd));
+ if (NS_FAILED(rv))
+ {
+ NS_ERROR("nsAbLDAPMessageBase::OnLDAPInit(): failed to perform bind operation");
+ mOperation = 0; // Break Listener->Operation->Listener reference cycle
+ InitFailed();
+ }
+ return rv;
+}
+
+nsresult nsAbLDAPListenerBase::OnLDAPMessageBind(nsILDAPMessage *aMessage)
+{
+ if (mBound)
+ return NS_OK;
+
+ // see whether the bind actually succeeded
+ //
+ int32_t errCode;
+ nsresult rv = aMessage->GetErrorCode(&errCode);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (errCode != nsILDAPErrors::SUCCESS)
+ {
+ // if the login failed, tell the wallet to forget this password
+ //
+ if (errCode == nsILDAPErrors::INAPPROPRIATE_AUTH ||
+ errCode == nsILDAPErrors::INVALID_CREDENTIALS)
+ {
+ // Login failed, so try again - but first remove the existing login(s)
+ // so that the user gets prompted. This may not be the best way of doing
+ // things, we need to review that later.
+
+ nsCOMPtr<nsILoginManager> loginMgr =
+ do_GetService(NS_LOGINMANAGER_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCString spec;
+ rv = mDirectoryUrl->GetSpec(spec);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCString prePath;
+ rv = mDirectoryUrl->GetPrePath(prePath);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ uint32_t count;
+ nsILoginInfo** logins;
+
+ rv = loginMgr->FindLogins(&count, NS_ConvertUTF8toUTF16(prePath),
+ EmptyString(),
+ NS_ConvertUTF8toUTF16(spec), &logins);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Typically there should only be one-login stored for this url, however,
+ // just in case there isn't.
+ for (uint32_t i = 0; i < count; ++i)
+ {
+ rv = loginMgr->RemoveLogin(logins[i]);
+ if (NS_FAILED(rv))
+ {
+ NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, logins);
+ return rv;
+ }
+ }
+ NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, logins);
+
+ // XXX We should probably pop up an error dialog telling
+ // the user that the login failed here, rather than just bringing
+ // up the password dialog again, which is what calling OnLDAPInit()
+ // does.
+ return OnLDAPInit(nullptr, NS_OK);
+ }
+
+ // Don't know how to handle this, so use the message error code in
+ // the failure return value so we hopefully get it back to the UI.
+ return NS_ERROR_GENERATE_FAILURE(NS_ERROR_MODULE_LDAP, errCode);
+ }
+
+ mBound = true;
+ return DoTask();
+}
--- /dev/null
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */
+
+Components.utils.import("resource:///modules/iteratorUtils.jsm");
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+var gServer;
+var gObserver;
+const Ci = Components.interfaces;
+
+function onInit(aPageId, aServerId)
+{
+ initServerType();
+
+ onCheckItem("server.biffMinutes", ["server.doBiff"]);
+ onCheckItem("nntp.maxArticles", ["nntp.notifyOn"]);
+ setupMailOnServerUI();
+ setupFixedUI();
+ if (document.getElementById("server.type").getAttribute("value") == "imap")
+ setupImapDeleteUI(aServerId);
+
+ // "STARTTLS, if available" is vulnerable to MITM attacks so we shouldn't
+ // allow users to choose it anymore. Hide the option unless the user already
+ // has it set.
+ hideUnlessSelected(document.getElementById("connectionSecurityType-1"));
+
+ //SASL EXTERNAL
+ try {
+ //set mail.server.%serverkey%.authByCert for sasl external
+ if(gServer){
+ var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
+ var prefAuthByCert = "mail.server." + gServer.key + ".authByCert";
+ if(prefs.prefHasUserValue(prefAuthByCert)){
+ var bAuthByCert = prefs.getBoolPref(prefAuthByCert);
+ if(bAuthByCert)
+ document.getElementById("server.authByCert").setAttribute("checked", "true");
+ else
+ document.getElementById("server.authByCert").setAttribute("checked", "false");
+ }else
+ prefs.setBoolPref(prefAuthByCert,false);
+ }
+ }catch (ex) { }
+}
+
+//SASL EXTERNAL
+// save mail.server.%serverkey%.authByCert for sasl external
+function onSave(){
+ try{
+ if(gServer){
+ var prefs = Components.classes["@mozilla.org/preferences-service;1"].getService(Components.interfaces.nsIPrefBranch);
+ var prefAuthByCert = "mail.server." + gServer.key + ".authByCert";
+ var isAuthByCert = document.getElementById("server.authByCert").getAttribute("checked");
+ if(isAuthByCert == "true"){
+ prefs.setBoolPref(prefAuthByCert,true);
+ }else{
+ prefs.setBoolPref(prefAuthByCert,false);
+ }
+ }
+ }catch (ex) { }
+}
+
+function onPreInit(account, accountValues)
+{
+ var type = parent.getAccountValue(account, accountValues, "server", "type", null, false);
+ hideShowControls(type);
+
+ Services.obs.notifyObservers(null, "charsetmenu-selected", "other");
+
+ gServer = account.incomingServer;
+
+ if(!account.incomingServer.canEmptyTrashOnExit)
+ {
+ document.getElementById("server.emptyTrashOnExit").setAttribute("hidden", "true");
+ document.getElementById("imap.deleteModel.box").setAttribute("hidden", "true");
+ }
+}
+
+function initServerType()
+{
+ var serverType = document.getElementById("server.type").getAttribute("value");
+ var propertyName = "serverType-" + serverType;
+
+ var messengerBundle = document.getElementById("bundle_messenger");
+ var verboseName = messengerBundle.getString(propertyName);
+ setDivText("servertype.verbose", verboseName);
+
+ secureSelect(true);
+
+ setLabelFromStringBundle("authMethod-no", "authNo");
+ setLabelFromStringBundle("authMethod-old", "authOld");
+ setLabelFromStringBundle("authMethod-kerberos", "authKerberos");
+ setLabelFromStringBundle("authMethod-external", "authExternal");
+ setLabelFromStringBundle("authMethod-ntlm", "authNTLM");
+ setLabelFromStringBundle("authMethod-anysecure", "authAnySecure");
+ setLabelFromStringBundle("authMethod-any", "authAny");
+ setLabelFromStringBundle("authMethod-password-encrypted",
+ "authPasswordEncrypted");
+ //authMethod-password-cleartext already set in selectSelect()
+
+ // Hide deprecated/hidden auth options, unless selected
+ hideUnlessSelected(document.getElementById("authMethod-no"));
+ hideUnlessSelected(document.getElementById("authMethod-old"));
+ hideUnlessSelected(document.getElementById("authMethod-anysecure"));
+ hideUnlessSelected(document.getElementById("authMethod-any"));
+
+ if(document.getElementById("server.socketType").value == 0){
+ document.getElementById("server.authByCert").setAttribute("disabled", "true");
+ document.getElementById("server.authByCert").setAttribute("checked","false");
+ }else{
+ document.getElementById("server.authByCert").removeAttribute("disabled");
+ }
+}
+
+function hideUnlessSelected(element)
+{
+ element.hidden = !element.selected;
+}
+
+function setLabelFromStringBundle(elementID, stringName)
+{
+ document.getElementById(elementID).label =
+ document.getElementById("bundle_messenger").getString(stringName);
+}
+
+function setDivText(divname, value)
+{
+ var div = document.getElementById(divname);
+ if (!div)
+ return;
+ div.setAttribute("value", value);
+}
+
+
+function onAdvanced()
+{
+ // Store the server type and, if an IMAP or POP3 server,
+ // the settings needed for the IMAP/POP3 tab into the array
+ var serverSettings = {};
+ var serverType = document.getElementById("server.type").getAttribute("value");
+ serverSettings.serverType = serverType;
+
+ serverSettings.serverPrettyName = gServer.prettyName;
+ serverSettings.account = top.getCurrentAccount();
+
+ if (serverType == "imap")
+ {
+ serverSettings.dualUseFolders = document.getElementById("imap.dualUseFolders").checked;
+ serverSettings.usingSubscription = document.getElementById("imap.usingSubscription").checked;
+ serverSettings.useIdle = document.getElementById("imap.useIdle").checked;
+ serverSettings.maximumConnectionsNumber = document.getElementById("imap.maximumConnectionsNumber").getAttribute("value");
+ // string prefs
+ serverSettings.personalNamespace = document.getElementById("imap.personalNamespace").getAttribute("value");
+ serverSettings.publicNamespace = document.getElementById("imap.publicNamespace").getAttribute("value");
+ serverSettings.serverDirectory = document.getElementById("imap.serverDirectory").getAttribute("value");
+ serverSettings.otherUsersNamespace = document.getElementById("imap.otherUsersNamespace").getAttribute("value");
+ serverSettings.overrideNamespaces = document.getElementById("imap.overrideNamespaces").checked;
+ }
+ else if (serverType == "pop3")
+ {
+ serverSettings.deferGetNewMail = document.getElementById("pop3.deferGetNewMail").checked;
+ serverSettings.deferredToAccount = document.getElementById("pop3.deferredToAccount").getAttribute("value");
+ }
+
+ window.openDialog("chrome://messenger/content/am-server-advanced.xul",
+ "_blank", "chrome,modal,titlebar", serverSettings);
+
+ if (serverType == "imap")
+ {
+ document.getElementById("imap.dualUseFolders").checked = serverSettings.dualUseFolders;
+ document.getElementById("imap.usingSubscription").checked = serverSettings.usingSubscription;
+ document.getElementById("imap.useIdle").checked = serverSettings.useIdle;
+ document.getElementById("imap.maximumConnectionsNumber").setAttribute("value", serverSettings.maximumConnectionsNumber);
+ // string prefs
+ document.getElementById("imap.personalNamespace").setAttribute("value", serverSettings.personalNamespace);
+ document.getElementById("imap.publicNamespace").setAttribute("value", serverSettings.publicNamespace);
+ document.getElementById("imap.serverDirectory").setAttribute("value", serverSettings.serverDirectory);
+ document.getElementById("imap.otherUsersNamespace").setAttribute("value", serverSettings.otherUsersNamespace);
+ document.getElementById("imap.overrideNamespaces").checked = serverSettings.overrideNamespaces;
+ }
+ else if (serverType == "pop3")
+ {
+ document.getElementById("pop3.deferGetNewMail").checked = serverSettings.deferGetNewMail;
+ document.getElementById("pop3.deferredToAccount").setAttribute("value", serverSettings.deferredToAccount);
+ let pop3Server = gServer.QueryInterface(Components.interfaces.nsIPop3IncomingServer);
+ // we're explicitly setting this so we'll go through the SetDeferredToAccount method
+ pop3Server.deferredToAccount = serverSettings.deferredToAccount;
+ // Setting the server to be deferred causes a rebuild of the account tree,
+ // losing the current selection. Reselect the current server again as it
+ // didn't really disappear.
+ parent.selectServer(parent.getCurrentAccount().incomingServer, parent.currentPageId);
+
+ // Iterate over all accounts to see if any of their junk targets are now
+ // invalid (pointed to the account that is now deferred).
+ // If any such target is found it is reset to a new safe folder
+ // (the deferred to account or Local Folders). If junk was really moved
+ // to that folder (moveOnSpam = true) then moving junk is disabled
+ // (so that the user notices it and checks the settings).
+ // This is the same sanitization as in am-junk.js, just applied to all POP accounts.
+ let deferredURI = serverSettings.deferredToAccount &&
+ MailServices.accounts.getAccount(serverSettings.deferredToAccount)
+ .incomingServer.serverURI;
+
+ for each (let account in fixIterator(MailServices.accounts.accounts,
+ Components.interfaces.nsIMsgAccount)) {
+ let accountValues = parent.getValueArrayFor(account);
+ let type = parent.getAccountValue(account, accountValues, "server", "type",
+ null, false);
+ // Try to keep this list of account types not having Junk settings
+ // synchronized with the list in AccountManager.js.
+ if (type != "nntp" && type != "rss" && type != "im") {
+ let spamActionTargetAccount = parent.getAccountValue(account, accountValues,
+ "server", "spamActionTargetAccount", "string", true);
+ let spamActionTargetFolder = parent.getAccountValue(account, accountValues,
+ "server", "spamActionTargetFolder", "string", true);
+ let moveOnSpam = parent.getAccountValue(account, accountValues,
+ "server", "moveOnSpam", "bool", true);
+
+ // Check if there are any invalid junk targets and fix them.
+ [ spamActionTargetAccount, spamActionTargetFolder, moveOnSpam ] =
+ sanitizeJunkTargets(spamActionTargetAccount,
+ spamActionTargetFolder,
+ deferredURI || account.incomingServer.serverURI,
+ parent.getAccountValue(account, accountValues, "server", "moveTargetMode", "int", true),
+ account.incomingServer.spamSettings,
+ moveOnSpam);
+
+ parent.setAccountValue(accountValues, "server", "moveOnSpam", moveOnSpam);
+ parent.setAccountValue(accountValues, "server", "spamActionTargetAccount",
+ spamActionTargetAccount);
+ parent.setAccountValue(accountValues, "server", "spamActionTargetFolder",
+ spamActionTargetFolder);
+ }
+ }
+ }
+}
+
+function secureSelect(aLoading)
+{
+ var socketType = document.getElementById("server.socketType").value;
+ var serverType = document.getElementById("server.type").value;
+ var defaultPort = gServer.protocolInfo.getDefaultServerPort(false);
+ var defaultPortSecure = gServer.protocolInfo.getDefaultServerPort(true);
+ var port = document.getElementById("server.port");
+ var portDefault = document.getElementById("defaultPort");
+ var prevDefaultPort = portDefault.value;
+
+ const Ci = Components.interfaces;
+ if (socketType == Ci.nsMsgSocketType.SSL) {
+ portDefault.value = defaultPortSecure;
+ if (port.value == "" || (!aLoading && port.value == defaultPort && prevDefaultPort != portDefault.value))
+ port.value = defaultPortSecure;
+ } else {
+ portDefault.value = defaultPort;
+ if (port.value == "" || (!aLoading && port.value == defaultPortSecure && prevDefaultPort != portDefault.value))
+ port.value = defaultPort;
+ }
+
+ // switch "insecure password" label
+ setLabelFromStringBundle("authMethod-password-cleartext",
+ socketType == Ci.nsMsgSocketType.SSL ||
+ socketType == Ci.nsMsgSocketType.alwaysSTARTTLS ?
+ "authPasswordCleartextViaSSL" : "authPasswordCleartextInsecurely");
+
+ if(document.getElementById("server.socketType").value == 0){
+ document.getElementById("server.authByCert").setAttribute("disabled", "true");
+ document.getElementById("server.authByCert").setAttribute("checked","false");
+ }else{
+ document.getElementById("server.authByCert").removeAttribute("disabled");
+ }
+}
+
+function setupMailOnServerUI()
+{
+ onCheckItem("pop3.deleteMailLeftOnServer", ["pop3.leaveMessagesOnServer"]);
+ setupAgeMsgOnServerUI();
+}
+
+function setupAgeMsgOnServerUI()
+{
+ const kLeaveMsgsId = "pop3.leaveMessagesOnServer";
+ const kDeleteByAgeId = "pop3.deleteByAgeFromServer";
+ onCheckItem(kDeleteByAgeId, [kLeaveMsgsId]);
+ onCheckItem("daysEnd", [kLeaveMsgsId]);
+ onCheckItem("pop3.numDaysToLeaveOnServer", [kLeaveMsgsId, kDeleteByAgeId]);
+}
+
+function setupFixedUI()
+{
+ var controls = [document.getElementById("fixedServerName"),
+ document.getElementById("fixedUserName"),
+ document.getElementById("fixedServerPort")];
+
+ var len = controls.length;
+ for (var i=0; i<len; i++) {
+ var fixedElement = controls[i];
+ var otherElement = document.getElementById(fixedElement.getAttribute("use"));
+
+ fixedElement.setAttribute("collapsed", "true");
+ otherElement.removeAttribute("collapsed");
+ }
+}
+
+function BrowseForNewsrc()
+{
+ const nsIFilePicker = Components.interfaces.nsIFilePicker;
+ const nsILocalFile = Components.interfaces.nsILocalFile;
+
+ var newsrcTextBox = document.getElementById("nntp.newsrcFilePath");
+ var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
+ fp.init(window,
+ document.getElementById("browseForNewsrc").getAttribute("filepickertitle"),
+ nsIFilePicker.modeSave);
+
+ var currentNewsrcFile;
+ try {
+ currentNewsrcFile = Components.classes["@mozilla.org/file/local;1"]
+ .createInstance(nsILocalFile);
+ currentNewsrcFile.initWithPath(newsrcTextBox.value);
+ } catch (e) {
+ dump("Failed to create nsILocalFile instance for the current newsrc file.\n");
+ }
+
+ if (currentNewsrcFile) {
+ fp.displayDirectory = currentNewsrcFile.parent;
+ fp.defaultString = currentNewsrcFile.leafName;
+ }
+
+ fp.appendFilters(nsIFilePicker.filterAll);
+
+ if (fp.show() != nsIFilePicker.returnCancel)
+ newsrcTextBox.value = fp.file.path;
+}
+
+function setupImapDeleteUI(aServerId)
+{
+ // read delete_model preference
+ var deleteModel = document.getElementById("imap.deleteModel").getAttribute("value");
+ selectImapDeleteModel(deleteModel);
+
+ // read trash_folder_name preference
+ var trashFolderName = getTrashFolderName();
+
+ // set folderPicker menulist
+ var trashPopup = document.getElementById("msgTrashFolderPopup");
+ trashPopup._teardown();
+ trashPopup._parentFolder = GetMsgFolderFromUri(aServerId);
+ trashPopup._ensureInitialized();
+
+ // TODO: There is something wrong here, selectFolder() fails even if the
+ // folder does exist. Try to fix in bug 802609.
+ let trashFolder = GetMsgFolderFromUri(aServerId + "/" + trashFolderName, false);
+ try {
+ trashPopup.selectFolder(trashFolder);
+ } catch(ex) {
+ trashPopup.parentNode.setAttribute("label", trashFolder.prettyName);
+ }
+ trashPopup.parentNode.folder = trashFolder;
+}
+
+function selectImapDeleteModel(choice)
+{
+ // set deleteModel to selected mode
+ document.getElementById("imap.deleteModel").setAttribute("value", choice);
+
+ switch (choice)
+ {
+ case "0" : // markDeleted
+ // disable folderPicker
+ document.getElementById("msgTrashFolderPicker").setAttribute("disabled", "true");
+ break;
+ case "1" : // moveToTrashFolder
+ // enable folderPicker
+ document.getElementById("msgTrashFolderPicker").removeAttribute("disabled");
+ break;
+ case "2" : // deleteImmediately
+ // disable folderPicker
+ document.getElementById("msgTrashFolderPicker").setAttribute("disabled", "true");
+ break;
+ default :
+ dump("Error in enabling/disabling server.TrashFolderPicker\n");
+ break;
+ }
+}
+
+// Capture any menulist changes from folderPicker
+function folderPickerChange(aEvent)
+{
+ var folder = aEvent.target._folder;
+ var folderPath = getFolderPathFromRoot(folder);
+
+ // Set the value to be persisted.
+ document.getElementById("imap.trashFolderName")
+ .setAttribute("value", folderPath);
+
+ // Update the widget to show/do correct things even for subfolders.
+ var trashFolderPicker = document.getElementById("msgTrashFolderPicker");
+ trashFolderPicker.setAttribute("label", folder.prettyName);
+}
+
+/** Generate the relative folder path from the root. */
+function getFolderPathFromRoot(folder)
+{
+ var path = folder.name;
+ var parentFolder = folder.parent;
+ while (parentFolder && parentFolder != folder.rootFolder) {
+ path = parentFolder.name + "/" + path;
+ parentFolder = parentFolder.parent;
+ }
+ // IMAP Inbox URI's start with INBOX, not Inbox.
+ return path.replace(/^Inbox/, "INBOX");
+}
+
+// Get trash_folder_name from prefs
+function getTrashFolderName()
+{
+ var trashFolderName = document.getElementById("imap.trashFolderName").getAttribute("value");
+ // if the preference hasn't been set, set it to a sane default
+ if (!trashFolderName) {
+ trashFolderName = "Trash";
+ document.getElementById("imap.trashFolderName").setAttribute("value",trashFolderName);
+ }
+ return trashFolderName;
+}
--- /dev/null
+<?xml version="1.0"?>
+
+<!--
+
+ This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<?xml-stylesheet href="chrome://messenger/skin/accountManage.css" type="text/css"?>
+<?xml-stylesheet href="chrome://messenger/skin/messenger.css" type="text/css"?>
+<?xml-stylesheet href="chrome://messenger/skin/folderMenus.css" type="text/css"?>
+
+<!DOCTYPE page [
+<!ENTITY % trashDTD SYSTEM "chrome://messenger/locale/am-server-top.dtd">%trashDTD;
+<!ENTITY % pickerDTD SYSTEM "chrome://messenger/locale/msgFolderPickerOverlay.dtd"> %pickerDTD;
+]>
+
+<page xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ title="&serverSettings.label;"
+ onload="parent.onPanelLoaded('am-server.xul');">
+
+ <vbox flex="1" style="overflow: auto;">
+ <script type="application/javascript" src="chrome://messenger/content/AccountManager.js"/>
+ <script type="application/javascript" src="chrome://messenger/content/am-server.js"/>
+ <script type="application/javascript" src="chrome://messenger/content/am-prefs.js"/>
+ <script type="application/javascript" src="chrome://messenger/content/amUtils.js"/>
+ <script type="application/javascript" src="chrome://messenger/content/widgetglue.js"/>
+ <stringbundle id="bundle_messenger" src="chrome://messenger/locale/messenger.properties"/>
+
+ <label hidden="true" wsm_persist="true" id="server.type"/>
+
+ <dialogheader title="&serverSettings.label;"/>
+
+ <grid>
+ <columns>
+ <column/>
+ <column flex="1"/>
+ <column/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label value="&serverType.label;"/>
+ <label id="servertype.verbose"/>
+ </row>
+ <row align="center">
+ <hbox>
+ <label value="&serverName.label;" accesskey="&serverName.accesskey;"
+ control="server.realHostName"/>
+ </hbox>
+ <hbox align="center">
+ <label id="fixedServerName" collapsed="true" use="server.realHostName"/>
+ <textbox wsm_persist="true"
+ size="20"
+ flex="1"
+ id="server.realHostName"
+ prefstring="mail.server.%serverkey%.realhostname"
+ class="uri-element"/>
+ </hbox>
+ <hbox align="center">
+ <label hidefor="movemail" value="&port.label;"
+ accesskey="&port.accesskey;" control="server.port"/>
+ <label id="fixedServerPort" hidefor="movemail"
+ collapsed="true" use="server.port"/>
+ <textbox wsm_persist="true" size="3" id="server.port"
+ preftype="int" hidefor="movemail"
+ prefstring="mail.server.%serverkey%.port"
+ type="number" min="1" max="65535" increment="1"/>
+ <label value="&serverPortDefault.label;" hidefor="movemail"/>
+ <label id="defaultPort" hidefor="movemail"/>
+ </hbox>
+ </row>
+ <row align="center">
+ <hbox align="center" hidefor="nntp">
+ <label value="&userName.label;"
+ accesskey="&userName.accesskey;"
+ control="server.realUsername"/>
+ </hbox>
+ <hbox align="center" hidefor="nntp">
+ <label id="fixedUserName" collapsed="true" use="server.realUsername"/>
+ <textbox wsm_persist="true"
+ size="20"
+ flex="1"
+ id="server.realUsername"
+ prefstring="mail.server.%serverkey%.realusername"/>
+ </hbox>
+ </row>
+ </rows>
+ </grid>
+
+ <separator class="thin"/>
+
+ <groupbox hidefor="movemail">
+ <caption label="&securitySettings.label;"/>
+
+ <grid flex="1">
+ <columns>
+ <column/>
+ <column/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label value="&connectionSecurity.label;"
+ accesskey="&connectionSecurity.accesskey;"
+ control="server.socketType"/>
+ <menulist wsm_persist="true" id="server.socketType"
+ oncommand="secureSelect();">
+ <menupopup id="server.socketTypePopup">
+ <menuitem value="0" label="&connectionSecurityType-0.label;"/>
+ <menuitem id="connectionSecurityType-1"
+ value="1" label="&connectionSecurityType-1.label;"
+ disabled="true"/>
+ <menuitem value="2" label="&connectionSecurityType-2.label;"
+ hidefor="nntp"/>
+ <menuitem value="3" label="&connectionSecurityType-3.label;"/>
+ </menupopup>
+ </menulist>
+ </row>
+ <row align="center" hidefor="nntp,movemail">
+ <label value="&authMethod.label;"
+ accesskey="&authMethod.accesskey;"
+ control="server.authMethod"/>
+ <!-- same in smtpEditOverlay.xul/js -->
+ <menulist id="server.authMethod"
+ wsm_persist="true"
+ preftype="int" type="number"
+ prefstring="mail.server.%serverkey%.authMethod">
+ <menupopup id="server.authMethodPopup">
+ <menuitem id="authMethod-no" value="1"/>
+ <menuitem id="authMethod-old" value="2"/>
+ <menuitem id="authMethod-password-cleartext" value="3"/>
+ <menuitem id="authMethod-password-encrypted" value="4"/>
+ <menuitem id="authMethod-kerberos" value="5"/>
+ <menuitem id="authMethod-ntlm" value="6"/>
+ <menuitem id="authMethod-external" value="7"/>
+ <menuitem id="authMethod-anysecure" value="8"/>
+ <menuitem id="authMethod-any" value="9"/>
+ </menupopup>
+ </menulist>
+ </row>
+ <row>
+ <checkbox id="server.authByCert"
+ label="&authByCert.label;"
+ accesskey="&authByCert.accesskey;" />
+ </row>
+ </rows>
+ </grid>
+ </groupbox>
+
+ <groupbox>
+ <caption label="&serverSettings.label;"/>
+ <vbox align="start">
+ <checkbox wsm_persist="true"
+ id="server.loginAtStartUp"
+ label="&loginAtStartup.label;"
+ accesskey="&loginAtStartup.accesskey;"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.login_at_startup"/>
+ </vbox>
+ <hbox align="center">
+ <checkbox wsm_persist="true" id="server.doBiff" label="&biffStart.label;"
+ accesskey="&biffStart.accesskey;"
+ oncommand="onCheckItem('server.biffMinutes', [this.id]);"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.check_new_mail"/>
+ <textbox wsm_persist="true" id="server.biffMinutes"
+ type="number" size="3" min="1" increment="1"
+ aria-labelledby="server.doBiff server.biffMinutes biffEnd"
+ preftype="int"
+ prefstring="mail.server.%serverkey%.check_time"/>
+ <label id="biffEnd" control="server.biffMinutes" value="&biffEnd.label;"/>
+ </hbox>
+ <!-- Necessary for POP3 and Movemail (Bug 480945) -->
+ <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=480945 -->
+ <vbox align="start" hidefor="imap,nntp">
+ <checkbox wsm_persist="true" id="server.downloadOnBiff"
+ label="&downloadOnBiff.label;" prefattribute="value"
+ accesskey="&downloadOnBiff.accesskey;"
+ prefstring="mail.server.%serverkey%.download_on_biff"/>
+ </vbox>
+ <!-- POP3 -->
+ <vbox align="start" hidefor="imap,nntp,movemail">
+ <checkbox wsm_persist="true" id="pop3.headersOnly"
+ label="&headersOnly.label;"
+ accesskey="&headersOnly.accesskey;"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.headers_only"/>
+
+ <checkbox wsm_persist="true" id="pop3.leaveMessagesOnServer"
+ label="&leaveOnServer.label;" oncommand="setupMailOnServerUI();"
+ accesskey="&leaveOnServer.accesskey;"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.leave_on_server"/>
+
+ <hbox align="center">
+ <checkbox wsm_persist="true" id="pop3.deleteByAgeFromServer" class="indent"
+ label="&deleteByAgeFromServer.label;" oncommand="setupAgeMsgOnServerUI();"
+ accesskey="&deleteByAgeFromServer.accesskey;"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.delete_by_age_from_server"/>
+ <textbox wsm_persist="true" id="pop3.numDaysToLeaveOnServer" size="3"
+ aria-labelledby="pop3.deleteByAgeFromServer pop3.numDaysToLeaveOnServer daysEnd"
+ preftype="int" type="number" min="1" increment="1"
+ prefstring="mail.server.%serverkey%.num_days_to_leave_on_server"/>
+ <label id="daysEnd" control="pop3.numDaysToLeaveOnServer" value="&daysEnd.label;"/>
+ </hbox>
+
+ <checkbox wsm_persist="true" id="pop3.deleteMailLeftOnServer" class="indent"
+ label="&deleteOnServer2.label;"
+ accesskey="&deleteOnServer2.accesskey;"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.delete_mail_left_on_server"/>
+
+ <!-- hidden elements for data transfer to and from advanced... dialog -->
+ <hbox flex="1" hidefor="imap,nntp,movemail" hidden="true">
+ <checkbox hidden="true" wsm_persist="true" id="pop3.deferGetNewMail"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.deferGetNewMail"/>
+ <label hidden="true" wsm_persist="true" id="pop3.deferredToAccount"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.deferredToAccount"/>
+
+ </hbox>
+ </vbox>
+ <!-- IMAP -->
+ <label hidden="true" wsm_persist="true" id="imap.trashFolderName"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.trash_folder_name"/>
+
+ <hbox align="center" hidefor="pop3,nntp,movemail">
+ <label value="&deleteMessagePrefix.label;" align="left"
+ control="imap.deleteModel"/>
+ </hbox>
+ <hbox align="end">
+ <hbox align="center"
+ id="imap.deleteModel.box"
+ hidefor="pop3,nntp,movemail"
+ flex="1">
+ <radiogroup id="imap.deleteModel"
+ wsm_persist="true"
+ oncommand="selectImapDeleteModel(this.value);"
+ prefstring="mail.server.%serverkey%.delete_model">
+ <grid class="specialFolderPickerGrid">
+ <columns>
+ <column/>
+ <column flex="1"/>
+ </columns>
+ <rows>
+ <row align="center">
+ <radio id="modelMoveToTrash"
+ value="1"
+ label="&modelMoveToTrash.label;"
+ accesskey="&modelMoveToTrash.accesskey;"/>
+ <menulist id="msgTrashFolderPicker"
+ aria-labelledby="modelMoveToTrash"
+ oncommand="folderPickerChange(event);">
+ <menupopup id="msgTrashFolderPopup"
+ type="folder"
+ mode="filing"
+ showFileHereLabel="true"
+ fileHereLabel="&filemessageschoosethis.label;"/>
+ </menulist>
+ </row>
+ <row align="center">
+ <radio id="modelMarkDeleted"
+ value="0"
+ label="&modelMarkDeleted.label;"
+ accesskey="&modelMarkDeleted.accesskey;"/>
+ </row>
+ <row align="center">
+ <radio id="modelDeleteImmediately"
+ value="2"
+ label="&modelDeleteImmediately.label;"
+ accesskey="&modelDeleteImmediately.accesskey;"/>
+ </row>
+ </rows>
+ </grid>
+ </radiogroup>
+ </hbox>
+ <!-- This button should have identical attributes to the
+ server.popAdvancedButton except the hidefor attribute. -->
+ <button label="&advancedButton.label;"
+ accesskey="&advancedButton.accesskey;"
+ oncommand="onAdvanced();"
+ wsm_persist="true"
+ id="server.imapAdvancedButton"
+ prefstring="mail.server.%serverkey%.advanced.disable"
+ hidefor="pop3,nntp,movemail"/>
+ </hbox>
+
+ <!-- Advanced IMAP settings -->
+ <hbox flex="1" hidefor="pop3,nntp,movemail" hidden="true">
+ <checkbox hidden="true" wsm_persist="true" id="imap.dualUseFolders"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.dual_use_folders"/>
+ <checkbox hidden="true" wsm_persist="true" id="imap.usingSubscription"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.using_subscription"/>
+ <checkbox hidden="true" wsm_persist="true" id="imap.useIdle"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.use_idle"/>
+ <label hidden="true" wsm_persist="true" id="imap.maximumConnectionsNumber"/>
+ <label hidden="true" wsm_persist="true" id="imap.personalNamespace"/>
+ <label hidden="true" wsm_persist="true" id="imap.publicNamespace"/>
+ <label hidden="true" wsm_persist="true" id="imap.otherUsersNamespace"/>
+ <label hidden="true" wsm_persist="true" id="imap.serverDirectory"/>
+ <checkbox hidden="true" wsm_persist="true" id="imap.overrideNamespaces"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.override_namespaces"/>
+ </hbox>
+
+ <!-- NNTP -->
+ <hbox hidefor="pop3,imap,movemail" align="center">
+ <checkbox wsm_persist="true" id="nntp.notifyOn"
+ label="&maxMessagesStart.label;"
+ accesskey="&maxMessagesStart.accesskey;"
+ oncommand="onCheckItem('nntp.maxArticles', [this.id]);"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.notify.on"/>
+ <textbox wsm_persist="true" id="nntp.maxArticles"
+ type="number" size="4" min="1" increment="10"
+ aria-labelledby="nntp.notifyOn nntp.maxArticles maxMessagesEnd"
+ preftype="int"
+ prefstring="mail.server.%serverkey%.max_articles"/>
+ <label control="nntp.maxArticles" value="&maxMessagesEnd.label;" id="maxMessagesEnd"/>
+ </hbox>
+ <checkbox hidefor="pop3,imap,movemail" wsm_persist="true" id="nntp.pushAuth"
+ label="&alwaysAuthenticate.label;"
+ accesskey="&alwaysAuthenticate.accesskey;"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.always_authenticate"/>
+
+ <!-- take out for now - bug 45079
+ <hbox flex="1" hidefor="pop3,imap,movemail">
+ <groupbox>
+ <caption class="header" label="&abbreviate.label;"/>
+
+ <radiogroup wsm_persist="true" id="nntp.abbreviate">
+ <radio wsm_persist="true" value="true"
+ label="&abbreviateOn.label;"/>
+ <radio wsm_persist="true" value="false"
+ label="&abbreviateOff.label;"/>
+ </radiogroup>
+ </groupbox>
+ </hbox>
+ -->
+
+ </groupbox>
+
+ <groupbox>
+ <caption label="&messageStorage.label;"/>
+
+ <hbox align="end">
+ <vbox align="start" flex="1" id="exitHandlingBox=">
+ <checkbox hidefor="pop3,nntp,movemail"
+ wsm_persist="true"
+ id="imap.cleanupInboxOnExit"
+ label="&expungeOnExit.label;"
+ accesskey="&expungeOnExit.accesskey;"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.cleanup_inbox_on_exit"/>
+ <checkbox hidefor="nntp"
+ wsm_persist="true"
+ id="server.emptyTrashOnExit"
+ label="&emptyTrashOnExit.label;"
+ accesskey="&emptyTrashOnExit.accesskey;"
+ prefattribute="value"
+ prefstring="mail.server.%serverkey%.empty_trash_on_exit"/>
+ </vbox>
+ <button label="&advancedButton.label;"
+ accesskey="&advancedButton.accesskey;"
+ oncommand="onAdvanced();"
+ wsm_persist="true"
+ id="server.popAdvancedButton"
+ prefstring="mail.server.%serverkey%.advanced.disable"
+ hidefor="imap,nntp,movemail"/>
+ </hbox>
+
+ <vbox hidefor="imap,pop3,movemail">
+ <label value="&newsrcFilePath.label;" control="nntp.newsrcFilePath"/>
+ <hbox align="center">
+ <textbox readonly="true"
+ wsm_persist="true"
+ flex="1"
+ id="nntp.newsrcFilePath"
+ datatype="nsILocalFile"
+ prefstring="mail.server.%serverkey%.newsrc.file"
+ class="uri-element"/>
+ <button id="browseForNewsrc"
+ label="&browseNewsrc.label;"
+ filepickertitle="&newsrcPicker.label;"
+ accesskey="&browseNewsrc.accesskey;"
+ oncommand="BrowseForNewsrc();"/>
+ </hbox>
+ </vbox>
+
+ <separator class="thin"/>
+
+ <vbox>
+ <label value="&localPath.label;" control="server.localPath"/>
+ <hbox align="center">
+ <textbox readonly="true"
+ wsm_persist="true"
+ flex="1"
+ id="server.localPath"
+ datatype="nsILocalFile"
+ prefstring="mail.server.%serverkey%.directory"
+ class="uri-element"/>
+ <button id="browseForLocalFolder"
+ label="&browseFolder.label;"
+ filepickertitle="&localFolderPicker.label;"
+ accesskey="&browseFolder.accesskey;"
+ oncommand="BrowseForLocalFolders();"/>
+ </hbox>
+ </vbox>
+
+ </groupbox>
+
+ <separator class="thin"/>
+
+ <hbox hidefor="imap,pop3,movemail" align="center" valign="middle" iscontrolcontainer="true">
+ <label value="&serverDefaultCharset.label;" control="nntp.charset"/>
+ <menulist hidable="true"
+ hidefor="imap,pop3,movemail"
+ wsm_persist="true"
+ id="nntp.charset"
+ ref="NC:DecodersRoot"
+ datasources="rdf:charset-menu"
+ preftype="string"
+ prefstring="mail.server.%serverkey%.charset">
+ <template>
+ <menupopup>
+ <menuitem label="rdf:http://home.netscape.com/NC-rdf#Name" value="..." uri="..."/>
+ </menupopup>
+ </template>
+ </menulist>
+ </hbox>
+ </vbox>
+</page>
--- /dev/null
+/* -*- Mode: IDL; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+#include "MailNewsTypes2.idl"
+
+interface nsIMsgFolder;
+interface nsIMsgFolderCache;
+interface nsIMsgWindow;
+interface nsIMsgProtocolInfo;
+interface nsIMsgFilterList;
+interface nsIMsgRetentionSettings;
+interface nsIMsgDownloadSettings;
+interface nsISpamSettings;
+interface nsIMsgFilterPlugin;
+interface nsIUrlListener;
+interface nsIMsgDBHdr;
+interface nsIFile;
+interface nsIURI;
+interface nsIMsgPluggableStore;
+
+/*
+ * Interface for incoming mail/news host
+ * this is the base interface for all mail server types (imap, pop, nntp, etc)
+ * often you will want to add extra interfaces that give you server-specific
+ * attributes and methods.
+ */
+[scriptable, uuid(92f4ee31-a14d-48dc-8676-22417caefa84)]
+interface nsIMsgIncomingServer : nsISupports {
+
+ /**
+ * internal pref key - guaranteed to be unique across all servers
+ */
+ attribute ACString key;
+
+ /**
+ * pretty name - should be "userid on hostname"
+ * if the pref is not set
+ */
+ attribute AString prettyName;
+
+ /**
+ * helper function to construct the pretty name in a server type
+ * specific way - e.g., mail for foo@test.com, news on news.mozilla.org
+ */
+ readonly attribute AString constructedPrettyName;
+
+ /**
+ * hostname of the server
+ */
+ attribute ACString hostName;
+
+ /**
+ * real hostname of the server (if server name is changed it's stored here)
+ */
+ attribute ACString realHostName;
+
+ /* port of the server */
+ attribute long port;
+
+ /**
+ * userid to log into the server
+ */
+ attribute ACString username;
+
+ /**
+ * real username of the server (if username is changed it's stored here)
+ */
+ attribute ACString realUsername;
+
+ /**
+ * protocol type, i.e. "pop3", "imap", "nntp", "none", etc
+ * used to construct URLs
+ */
+ attribute ACString type;
+
+ /**
+ * The proper instance of nsIMsgProtocolInfo corresponding to this server type.
+ */
+ readonly attribute nsIMsgProtocolInfo protocolInfo;
+
+ readonly attribute AString accountManagerChrome;
+
+ /**
+ * the schema for the local mail store, such
+ * as "mailbox", "imap", or "news"
+ * used to construct URIs
+ */
+ readonly attribute ACString localStoreType;
+
+ // Perform specific tasks (reset flags, remove files, etc) for account user/server name changes.
+ void onUserOrHostNameChanged(in ACString oldName, in ACString newName,
+ in bool hostnameChanged);
+
+ /* cleartext version of the password */
+ attribute ACString password;
+
+ /**
+ * Attempts to get the password first from the password manager, if that
+ * fails it will attempt to get it from the user if aMsgWindow is supplied.
+ *
+ * @param aPromptString The text of the prompt if the user is prompted for
+ * password.
+ * @param aPromptTitle The title of the prompt if the user is prompted.
+ * @param aMsgWindow A message window to associate the prompt with.
+ * @return The obtained password. Could be an empty password.
+ *
+ * @exception NS_ERROR_FAILURE The password could not be obtained.
+ *
+ * @note NS_MSG_PASSWORD_PROMPT_CANCELLED is a success code that is returned
+ * if the prompt was presented to the user but the user cancelled the
+ * prompt.
+ */
+ ACString getPasswordWithUI(in AString aPromptString, in AString aPromptTitle,
+ in nsIMsgWindow aMsgWindow);
+
+ /* forget the password in memory and in single signon database */
+ void forgetPassword();
+
+ /* forget the password in memory which is cached for the session */
+ void forgetSessionPassword();
+
+ /* should we download whole messages when biff goes off? */
+ attribute boolean downloadOnBiff;
+
+ /* should we biff the server? */
+ attribute boolean doBiff;
+
+ /* how often to biff */
+ attribute long biffMinutes;
+
+ /* current biff state */
+ attribute unsigned long biffState;
+
+ /* are we running a url as a result of biff going off? (different from user clicking get msg) */
+ attribute boolean performingBiff;
+
+ /* the on-disk path to message storage for this server */
+ attribute nsIFile localPath;
+
+ /// message store to use for the folders under this server.
+ readonly attribute nsIMsgPluggableStore msgStore;
+
+ /* the RDF URI for the root mail folder */
+ readonly attribute ACString serverURI;
+
+ /* the root folder for this server, even if server is deferred */
+ attribute nsIMsgFolder rootFolder;
+
+ /* root folder for this account
+ - if account is deferred, root folder of deferred-to account */
+ readonly attribute nsIMsgFolder rootMsgFolder;
+
+ /* are we already getting new Messages on the current server..
+ This is used to help us prevent multiple get new msg commands from
+ going off at the same time. */
+ attribute boolean serverBusy;
+
+ /**
+ * Is the server using a secure channel (SSL or STARTTLS).
+ */
+ readonly attribute boolean isSecure;
+
+ /**
+ * Authentication mechanism.
+ *
+ * @see nsMsgAuthMethod (in MailNewsTypes2.idl)
+ * Same as "mail.server...authMethod" pref
+ */
+ attribute nsMsgAuthMethodValue authMethod;
+
+ /**
+ * Whether to SSL or STARTTLS or not
+ *
+ * @see nsMsgSocketType (in MailNewsTypes2.idl)
+ * Same as "mail.server...socketType" pref
+ */
+ attribute nsMsgSocketTypeValue socketType;
+
+ /* empty trash on exit */
+ attribute boolean emptyTrashOnExit;
+
+ /**
+ * Get the server's list of filters.
+ *
+ * This SHOULD be the same filter list as the root folder's, if the server
+ * supports per-folder filters. Furthermore, this list SHOULD be used for all
+ * incoming messages.
+ *
+ * Since the returned nsIMsgFilterList is mutable, it is not necessary to call
+ * setFilterList after the filters have been changed.
+ *
+ * @param aMsgWindow @ref msgwindow "The standard message window"
+ * @return The list of filters.
+ */
+ nsIMsgFilterList getFilterList(in nsIMsgWindow aMsgWindow);
+
+ /**
+ * Set the server's list of filters.
+ *
+ * Note that this does not persist the filter list. To change the contents
+ * of the existing filters, use getFilterList and mutate the values as
+ * appopriate.
+ *
+ * @param aFilterList The new list of filters.
+ */
+ void setFilterList(in nsIMsgFilterList aFilterList);
+
+ /**
+ * Get user editable filter list. This does not have to be the same as
+ * the filterlist above, typically depending on the users preferences.
+ * The filters in this list are not processed, but only to be edited by
+ * the user.
+ * @see getFilterList
+ *
+ * @param aMsgWindow @ref msgwindow "The standard message window"
+ * @return The list of filters.
+ */
+ nsIMsgFilterList getEditableFilterList(in nsIMsgWindow aMsgWindow);
+
+ /**
+ * Set user editable filter list.
+ * This does not persist the filterlist, @see setFilterList
+ * @see getEditableFilterList
+ * @see setFilterList
+ *
+ * @param aFilterList The new list of filters.
+ */
+ void setEditableFilterList(in nsIMsgFilterList aFilterList);
+
+ /* we use this to set the default local path. we use this when migrating prefs */
+ void setDefaultLocalPath(in nsIFile aDefaultLocalPath);
+
+ /**
+ * Verify that we can logon
+ *
+ * @param aUrlListener - gets called back with success or failure.
+ * @param aMsgWindow nsIMsgWindow to use for notification callbacks.
+ * @return - the url that we run.
+ */
+ nsIURI verifyLogon(in nsIUrlListener aUrlListener, in nsIMsgWindow aMsgWindow);
+
+ /* do a biff */
+ void performBiff(in nsIMsgWindow aMsgWindow);
+
+ /* get new messages */
+ void getNewMessages(in nsIMsgFolder aFolder, in nsIMsgWindow aMsgWindow,
+ in nsIUrlListener aUrlListener);
+ /* this checks if a server needs a password to do biff */
+ readonly attribute boolean serverRequiresPasswordForBiff;
+
+ /* this gets called when the server is expanded in the folder pane */
+ void performExpand(in nsIMsgWindow aMsgWindow);
+
+ /* Write out all known folder data to panacea.dat */
+ void writeToFolderCache(in nsIMsgFolderCache folderCache);
+
+ /* close any server connections */
+ void closeCachedConnections();
+
+ /* ... */
+ void shutdown();
+
+ /**
+ * Get or set the value as determined by the preference tree.
+ *
+ * These methods MUST NOT fail if the preference is not set, and therefore
+ * they MUST have a default value. This default value is provided in practice
+ * by use of a default preference tree. The standard format for the pref
+ * branches are <tt>mail.server.<i>key</i>.</tt> for per-server preferences,
+ * such that the preference is <tt>mail.server.<i>key</i>.<i>attr</i></tt>.
+ *
+ * The attributes are passed in as strings for ease of access by the C++
+ * consumers of this method.
+ *
+ * @param attr The value for which the preference should be accessed.
+ * @param value The value of the preference to set.
+ * @return The value of the preference.
+ * @{
+ */
+ boolean getBoolValue(in string attr);
+ void setBoolValue(in string attr, in boolean value);
+
+ ACString getCharValue(in string attr);
+ void setCharValue(in string attr, in ACString value);
+
+ AString getUnicharValue(in string attr);
+ void setUnicharValue(in string attr, in AString value);
+
+ long getIntValue(in string attr);
+ void setIntValue(in string attr, in long value);
+ /** @} */
+
+ /**
+ * Get or set the value as determined by the preference tree.
+ *
+ * These methods MUST NOT fail if the preference is not set, and therefore
+ * they MUST have a default value. This default value is provided in practice
+ * by use of a default preference tree. The standard format for the pref
+ * branches are <tt>mail.server.<i>key</i>.</tt> for per-server preferences,
+ * such that the preference is <tt>mail.server.<i>key</i>.<i>attr</i></tt>.
+ *
+ * The attributes are passed in as strings for ease of access by the C++
+ * consumers of this method.
+ *
+ * There are two preference names on here for legacy reasons, where the first
+ * is the name which will be using a (preferred) relative preference and the
+ * second a deprecated absolute preference. Implementations that do not have
+ * to worry about supporting legacy preferences can safely ignore this second
+ * parameter. Callers must still provide a valid value, though.
+ *
+ * @param relpref The name of the relative file preference.
+ * @param absref The name of the absolute file preference.
+ * @param aValue The value of the preference to set.
+ * @return The value of the preference.
+ * @{
+ */
+ nsIFile getFileValue(in string relpref, in string abspref);
+ void setFileValue(in string relpref, in string abspref, in nsIFile aValue);
+ /** @} */
+
+ /**
+ * this is really dangerous. this destroys all pref values
+ * do not call this unless you know what you're doing!
+ */
+ void clearAllValues();
+
+ /**
+ * this is also very dangerous. this will remove the files
+ * associated with this server on disk.
+ */
+ void removeFiles();
+
+ attribute boolean valid;
+
+ AString toString();
+
+ void displayOfflineMsg(in nsIMsgWindow aWindow);
+
+ /* used for comparing nsIMsgIncomingServers */
+ boolean equals(in nsIMsgIncomingServer server);
+
+ /* Get Messages at startup */
+ readonly attribute boolean downloadMessagesAtStartup;
+
+ /* check to this if the server supports filters */
+ attribute boolean canHaveFilters;
+
+ /**
+ * can this server be removed from the account manager? for
+ * instance, local mail is not removable, but an imported folder is
+ */
+ attribute boolean canDelete;
+
+ attribute boolean loginAtStartUp;
+
+ attribute boolean limitOfflineMessageSize;
+ attribute long maxMessageSize;
+
+ attribute nsIMsgRetentionSettings retentionSettings;
+
+ /* check if this server can be a default server */
+ readonly attribute boolean canBeDefaultServer;
+
+ /* check if this server allows search operations */
+ readonly attribute boolean canSearchMessages;
+
+ /* check if this server allows canEmptyTrashOnExit operations */
+ readonly attribute boolean canEmptyTrashOnExit;
+
+ /* display startup page once per account per session */
+ attribute boolean displayStartupPage;
+ attribute nsIMsgDownloadSettings downloadSettings;
+
+ /*
+ * Offline support level. Support level can vary based on abilities
+ * and features each server can offer wrt to offline service.
+ * Here is the legend to determine the each support level details
+ *
+ * supportLevel == 0 --> no offline support (default)
+ * supportLevel == 10 --> regular offline feature support
+ * supportLevel == 20 --> extended offline feature support
+ *
+ * Each server can initialize itself to the support level if needed
+ * to override the default choice i.e., no offline support.
+ *
+ * POP3, None and Movemail will default to 0.
+ * IMAP level 10 and NEWS with level 20.
+ *
+ */
+ attribute long offlineSupportLevel;
+
+ /* create pretty name for migrated accounts */
+ AString generatePrettyNameForMigration();
+
+ /* does this server have disk space settings? */
+ readonly attribute boolean supportsDiskSpace;
+
+ /**
+ * Hide this server/account from the UI - used for smart mailboxes.
+ * The server can be retrieved from the account manager by name using the
+ * various Find methods, but nsIMsgAccountManager's GetAccounts and
+ * GetAllServers methods won't return the server/account.
+ */
+ attribute boolean hidden;
+
+ /**
+ * If the server supports Fcc/Sent/etc, default prefs can point to
+ * the server. Otherwise, copies and folders prefs should point to
+ * Local Folders.
+ *
+ * By default this value is set to true via global pref 'allows_specialfolders_usage'
+ * (mailnews.js). For Nntp, the value is overridden to be false.
+ * If ISPs want to modify this value, they should do that in their rdf file
+ * by using this attribute. Please look at mozilla/mailnews/base/ispdata/aol.rdf for
+ * usage example.
+ */
+ attribute boolean defaultCopiesAndFoldersPrefsToServer;
+
+ /* can this server allows sub folder creation */
+ attribute boolean canCreateFoldersOnServer;
+
+ /* can this server allows message filing ? */
+ attribute boolean canFileMessagesOnServer;
+
+ /* can this server allow compacting folders ? */
+ readonly attribute boolean canCompactFoldersOnServer;
+
+ /* can this server allow undo delete ? */
+ readonly attribute boolean canUndoDeleteOnServer;
+
+ /* used for setting up the filter UI */
+ readonly attribute nsMsgSearchScopeValue filterScope;
+
+ /* used for setting up the search UI */
+ readonly attribute nsMsgSearchScopeValue searchScope;
+
+ /**
+ * If the password for the server is available either via authentication
+ * in the current session or from password manager stored entries, return
+ * false. Otherwise, return true. If password is obtained from password
+ * manager, set the password member variable.
+ */
+ readonly attribute boolean passwordPromptRequired;
+
+ /**
+ * for mail, this configures both the MDN filter, and the server-side
+ * spam filter filters, if needed.
+ *
+ * If we have set up to filter return receipts into
+ * our Sent folder, this utility method creates
+ * a filter to do that, and adds it to our filterList
+ * if it doesn't exist. If it does, it will enable it.
+ *
+ * this is not used by news filters (yet).
+ */
+ void configureTemporaryFilters(in nsIMsgFilterList filterList);
+
+ /**
+ * If Sent folder pref is changed we need to clear the temporary
+ * return receipt filter so that the new return receipt filter can
+ * be recreated (by ConfigureTemporaryReturnReceiptsFilter()).
+ */
+ void clearTemporaryReturnReceiptsFilter();
+
+ /**
+ * spam settings
+ */
+ readonly attribute nsISpamSettings spamSettings;
+ readonly attribute nsIMsgFilterPlugin spamFilterPlugin;
+
+ nsIMsgFolder getMsgFolderFromURI(in nsIMsgFolder aFolderResource, in ACString aURI);
+
+ /// Indicates if any other server has deferred storage to this account.
+ readonly attribute boolean isDeferredTo;
+
+ const long keepDups = 0;
+ const long deleteDups = 1;
+ const long moveDupsToTrash = 2;
+ const long markDupsRead = 3;
+
+ attribute long incomingDuplicateAction;
+
+ // check if new hdr is a duplicate of a recently arrived header
+ boolean isNewHdrDuplicate(in nsIMsgDBHdr aNewHdr);
+
+ /**
+ * Set a boolean to force an inherited propertyName to return empty instead
+ * of inheriting from a parent folder, server, or the global
+ *
+ * @param propertyName The name of the property
+ * @param aForcePropertyEmpty true if an empty inherited property should be returned
+ */
+ void setForcePropertyEmpty(in string propertyName, in boolean aForcePropertyEmpty);
+
+ /**
+ * Get a boolean to force an inherited propertyName to return empty instead
+ * of inheriting from a parent folder, server, or the global
+ *
+ * @param propertyName The name of the property
+ *
+ * @return true if an empty inherited property should be returned
+ */
+ boolean getForcePropertyEmpty(in string propertyName);
+
+ /**
+ * Return the order in which this server type should appear in the folder pane.
+ * This sort order is a number between 100000000 and 900000000 so that RDF can
+ * use it as a string.
+ * The current return values are these:
+ * 0 = default account, 100000000 = mail accounts (POP3/IMAP4),
+ * 200000000 = Local Folders, 300000000 = IM accounts,
+ * 400000000 = RSS, 500000000 = News
+ * If a new server type is created a TB UI reviewer must decide its sort order.
+ */
+ readonly attribute long sortOrder;
+
+ //check if the authentification by certificate is activated
+ boolean isAuthentificationByCertificate();
+
+};
+
+%{C++
+/*
+ * Following values for offline support have been used by
+ * various files. If you are modifying any of the values
+ * below, please do take care of the following files.
+ * - mozilla/mailnews/base/src/nsMsgAccountManagerDS.cpp
+ * - mozilla/mailnews/base/util/nsMsgIncomingServer.cpp
+ * - mozilla/mailnews/imap/src/nsImapIncomingServer.cpp
+ * - mozilla/mailnews/local/src/nsPop3IncomingServer.cpp
+ * - mozilla/mailnews/news/src/nsNntpIncomingServer.cpp
+ * - mozilla/mailnews/base/content/msgAccountCentral.js
+ * - mozilla/modules/libpref/src/init/mailnews.js
+ * - ns/modules/libpref/src/init/mailnews-ns.js
+ * - ns/mailnews/base/ispdata/aol.rdf
+ * - ns/mailnews/base/ispdata/nswebmail.rdf
+ */
+#define OFFLINE_SUPPORT_LEVEL_NONE 0
+#define OFFLINE_SUPPORT_LEVEL_REGULAR 10
+#define OFFLINE_SUPPORT_LEVEL_EXTENDED 20
+#define OFFLINE_SUPPORT_LEVEL_UNDEFINED -1
+
+// Value when no port setting is found
+#define PORT_NOT_SET -1
+
+/* some useful macros to implement nsIMsgIncomingServer accessors */
+#define NS_IMPL_SERVERPREF_STR(_class, _postfix, _prefname) \
+NS_IMETHODIMP \
+_class::Get##_postfix(nsACString& retval) \
+{ \
+ return GetCharValue(_prefname, retval); \
+} \
+NS_IMETHODIMP \
+_class::Set##_postfix(const nsACString& chvalue) \
+{ \
+ return SetCharValue(_prefname, chvalue); \
+}
+
+#define NS_IMPL_SERVERPREF_BOOL(_class, _postfix, _prefname)\
+NS_IMETHODIMP \
+_class::Get##_postfix(bool *retval) \
+{ \
+ return GetBoolValue(_prefname, retval); \
+} \
+NS_IMETHODIMP \
+_class::Set##_postfix(bool bvalue) \
+{ \
+ return SetBoolValue(_prefname, bvalue); \
+}
+
+#define NS_IMPL_SERVERPREF_INT(_class, _postfix, _prefname)\
+NS_IMETHODIMP \
+_class::Get##_postfix(int32_t *retval) \
+{ \
+ return GetIntValue(_prefname, retval); \
+} \
+NS_IMETHODIMP \
+_class::Set##_postfix(int32_t ivalue) \
+{ \
+ return SetIntValue(_prefname, ivalue); \
+}
+
+%}
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsMsgIncomingServer.h"
+#include "nscore.h"
+#include "plstr.h"
+#include "prmem.h"
+#include "prprf.h"
+
+#include "nsIServiceManager.h"
+#include "nsCOMPtr.h"
+#include "nsStringGlue.h"
+#include "nsISupportsObsolete.h"
+#include "nsISupportsPrimitives.h"
+
+#include "nsMsgBaseCID.h"
+#include "nsMsgDBCID.h"
+#include "nsIMsgFolder.h"
+#include "nsIMsgFolderCache.h"
+#include "nsIMsgPluggableStore.h"
+#include "nsIMsgFolderCacheElement.h"
+#include "nsIMsgWindow.h"
+#include "nsIMsgFilterService.h"
+#include "nsIMsgProtocolInfo.h"
+#include "nsIPrefService.h"
+#include "nsIRelativeFilePref.h"
+#include "nsIDocShell.h"
+#include "nsIAuthPrompt.h"
+#include "nsNetUtil.h"
+#include "nsIWindowWatcher.h"
+#include "nsIStringBundle.h"
+#include "nsIMsgHdr.h"
+#include "nsIRDFService.h"
+#include "nsRDFCID.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsILoginInfo.h"
+#include "nsILoginManager.h"
+#include "nsIMsgAccountManager.h"
+#include "nsIMsgMdnGenerator.h"
+#include "nsMsgFolderFlags.h"
+#include "nsMsgUtils.h"
+#include "nsMsgMessageFlags.h"
+#include "nsIMsgSearchTerm.h"
+#include "nsAppDirectoryServiceDefs.h"
+#include "mozilla/Services.h"
+#include "nsIMsgFilter.h"
+#include "nsIArray.h"
+#include "nsArrayUtils.h"
+
+#define PORT_NOT_SET -1
+
+nsMsgIncomingServer::nsMsgIncomingServer():
+ m_rootFolder(0),
+ m_numMsgsDownloaded(0),
+ m_biffState(nsIMsgFolder::nsMsgBiffState_Unknown),
+ m_serverBusy(false),
+ m_canHaveFilters(true),
+ m_displayStartupPage(true),
+ mPerformingBiff(false)
+{
+ m_downloadedHdrs.Init(50);
+}
+
+nsMsgIncomingServer::~nsMsgIncomingServer()
+{
+}
+
+NS_IMPL_THREADSAFE_ADDREF(nsMsgIncomingServer)
+NS_IMPL_THREADSAFE_RELEASE(nsMsgIncomingServer)
+NS_INTERFACE_MAP_BEGIN(nsMsgIncomingServer)
+ NS_INTERFACE_MAP_ENTRY(nsIMsgIncomingServer)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIMsgIncomingServer)
+NS_INTERFACE_MAP_END_THREADSAFE
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetServerBusy(bool aServerBusy)
+{
+ m_serverBusy = aServerBusy;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetServerBusy(bool * aServerBusy)
+{
+ NS_ENSURE_ARG_POINTER(aServerBusy);
+ *aServerBusy = m_serverBusy;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetKey(nsACString& serverKey)
+{
+ serverKey = m_serverKey;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetKey(const nsACString& serverKey)
+{
+ m_serverKey.Assign(serverKey);
+
+ // in order to actually make use of the key, we need the prefs
+ nsresult rv;
+ nsCOMPtr<nsIPrefService> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsAutoCString branchName;
+ branchName.AssignLiteral("mail.server.");
+ branchName.Append(m_serverKey);
+ branchName.Append('.');
+ rv = prefs->GetBranch(branchName.get(), getter_AddRefs(mPrefBranch));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return prefs->GetBranch("mail.server.default.", getter_AddRefs(mDefPrefBranch));
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetRootFolder(nsIMsgFolder * aRootFolder)
+{
+ m_rootFolder = aRootFolder;
+ return NS_OK;
+}
+
+// this will return the root folder of this account,
+// even if this server is deferred.
+NS_IMETHODIMP
+nsMsgIncomingServer::GetRootFolder(nsIMsgFolder * *aRootFolder)
+{
+ NS_ENSURE_ARG_POINTER(aRootFolder);
+ if (!m_rootFolder)
+ {
+ nsresult rv = CreateRootFolder();
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ NS_IF_ADDREF(*aRootFolder = m_rootFolder);
+ return NS_OK;
+}
+
+// this will return the root folder of the deferred to account,
+// if this server is deferred.
+NS_IMETHODIMP
+nsMsgIncomingServer::GetRootMsgFolder(nsIMsgFolder **aRootMsgFolder)
+{
+ return GetRootFolder(aRootMsgFolder);
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::PerformExpand(nsIMsgWindow *aMsgWindow)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::VerifyLogon(nsIUrlListener *aUrlListener, nsIMsgWindow *aMsgWindow,
+ nsIURI **aURL)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::PerformBiff(nsIMsgWindow* aMsgWindow)
+{
+ //This has to be implemented in the derived class, but in case someone doesn't implement it
+ //just return not implemented.
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetNewMessages(nsIMsgFolder *aFolder, nsIMsgWindow *aMsgWindow,
+ nsIUrlListener *aUrlListener)
+{
+ NS_ENSURE_ARG_POINTER(aFolder);
+ return aFolder->GetNewMessages(aMsgWindow, aUrlListener);
+}
+
+NS_IMETHODIMP nsMsgIncomingServer::GetPerformingBiff(bool *aPerformingBiff)
+{
+ NS_ENSURE_ARG_POINTER(aPerformingBiff);
+ *aPerformingBiff = mPerformingBiff;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgIncomingServer::SetPerformingBiff(bool aPerformingBiff)
+{
+ mPerformingBiff = aPerformingBiff;
+ return NS_OK;
+}
+
+NS_IMPL_GETSET(nsMsgIncomingServer, BiffState, uint32_t, m_biffState)
+
+NS_IMETHODIMP nsMsgIncomingServer::WriteToFolderCache(nsIMsgFolderCache *folderCache)
+{
+ nsresult rv = NS_OK;
+ if (m_rootFolder)
+ {
+ nsCOMPtr <nsIMsgFolder> msgFolder = do_QueryInterface(m_rootFolder, &rv);
+ if (NS_SUCCEEDED(rv) && msgFolder)
+ rv = msgFolder->WriteToFolderCache(folderCache, true /* deep */);
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::Shutdown()
+{
+ nsresult rv = CloseCachedConnections();
+ mFilterPlugin = nullptr;
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ if (mFilterList)
+ {
+ // close the filter log stream
+ rv = mFilterList->SetLogStream(nullptr);
+ NS_ENSURE_SUCCESS(rv,rv);
+ mFilterList = nullptr;
+ }
+
+ if (mSpamSettings)
+ {
+ // close the spam log stream
+ rv = mSpamSettings->SetLogStream(nullptr);
+ NS_ENSURE_SUCCESS(rv,rv);
+ mSpamSettings = nullptr;
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::CloseCachedConnections()
+{
+ // derived class should override if they cache connections.
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetDownloadMessagesAtStartup(bool *getMessagesAtStartup)
+{
+ // derived class should override if they need to do this.
+ *getMessagesAtStartup = false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetCanHaveFilters(bool *canHaveFilters)
+{
+ NS_ENSURE_ARG_POINTER(canHaveFilters);
+ *canHaveFilters = m_canHaveFilters;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetCanHaveFilters(bool aCanHaveFilters)
+{
+ m_canHaveFilters = aCanHaveFilters;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetCanBeDefaultServer(bool *canBeDefaultServer)
+{
+ // derived class should override if they need to do this.
+ *canBeDefaultServer = false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetCanSearchMessages(bool *canSearchMessages)
+{
+ // derived class should override if they need to do this.
+ NS_ENSURE_ARG_POINTER(canSearchMessages);
+ *canSearchMessages = false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetCanCompactFoldersOnServer(bool *canCompactFoldersOnServer)
+{
+ // derived class should override if they need to do this.
+ NS_ENSURE_ARG_POINTER(canCompactFoldersOnServer);
+ *canCompactFoldersOnServer = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetCanUndoDeleteOnServer(bool *canUndoDeleteOnServer)
+{
+ // derived class should override if they need to do this.
+ NS_ENSURE_ARG_POINTER(canUndoDeleteOnServer);
+ *canUndoDeleteOnServer = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetCanEmptyTrashOnExit(bool *canEmptyTrashOnExit)
+{
+ // derived class should override if they need to do this.
+ NS_ENSURE_ARG_POINTER(canEmptyTrashOnExit);
+ *canEmptyTrashOnExit = true;
+ return NS_OK;
+}
+
+// construct <localStoreType>://[<username>@]<hostname
+NS_IMETHODIMP
+nsMsgIncomingServer::GetServerURI(nsACString& aResult)
+{
+ nsresult rv;
+ rv = GetLocalStoreType(aResult);
+ NS_ENSURE_SUCCESS(rv, rv);
+ aResult.AppendLiteral("://");
+
+ nsCString username;
+ rv = GetUsername(username);
+ if (NS_SUCCEEDED(rv) && !username.IsEmpty()) {
+ nsCString escapedUsername;
+ MsgEscapeString(username, nsINetUtil::ESCAPE_XALPHAS, escapedUsername);
+ // not all servers have a username
+ aResult.Append(escapedUsername);
+ aResult.Append('@');
+ }
+
+ nsCString hostname;
+ rv = GetHostName(hostname);
+ if (NS_SUCCEEDED(rv) && !hostname.IsEmpty()) {
+ nsCString escapedHostname;
+ MsgEscapeString(hostname, nsINetUtil::ESCAPE_URL_PATH, escapedHostname);
+ // not all servers have a hostname
+ aResult.Append(escapedHostname);
+ }
+ return NS_OK;
+}
+
+// helper routine to create local folder on disk, if it doesn't exist.
+nsresult
+nsMsgIncomingServer::CreateLocalFolder(const nsAString& folderName)
+{
+ nsCOMPtr<nsIMsgFolder> rootFolder;
+ nsresult rv = GetRootFolder(getter_AddRefs(rootFolder));
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsIMsgFolder> child;
+ rv = rootFolder->GetChildNamed(folderName, getter_AddRefs(child));
+ if (child)
+ return NS_OK;
+ nsCOMPtr<nsIMsgPluggableStore> msgStore;
+ rv = GetMsgStore(getter_AddRefs(msgStore));
+ NS_ENSURE_SUCCESS(rv, rv);
+ return msgStore->CreateFolder(rootFolder, folderName, getter_AddRefs(child));
+}
+
+nsresult
+nsMsgIncomingServer::CreateRootFolder()
+{
+ nsresult rv;
+ // get the URI from the incoming server
+ nsCString serverUri;
+ rv = GetServerURI(serverUri);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIRDFService> rdf = do_GetService("@mozilla.org/rdf/rdf-service;1", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // get the corresponding RDF resource
+ // RDF will create the server resource if it doesn't already exist
+ nsCOMPtr<nsIRDFResource> serverResource;
+ rv = rdf->GetResource(serverUri, getter_AddRefs(serverResource));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // make incoming server know about its root server folder so we
+ // can find sub-folders given an incoming server.
+ m_rootFolder = do_QueryInterface(serverResource, &rv);
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetBoolValue(const char *prefname,
+ bool *val)
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ NS_ENSURE_ARG_POINTER(val);
+ *val = false;
+
+ if (NS_FAILED(mPrefBranch->GetBoolPref(prefname, val)))
+ mDefPrefBranch->GetBoolPref(prefname, val);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetBoolValue(const char *prefname,
+ bool val)
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ bool defaultValue;
+ nsresult rv = mDefPrefBranch->GetBoolPref(prefname, &defaultValue);
+
+ if (NS_SUCCEEDED(rv) && val == defaultValue)
+ mPrefBranch->ClearUserPref(prefname);
+ else
+ rv = mPrefBranch->SetBoolPref(prefname, val);
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetIntValue(const char *prefname,
+ int32_t *val)
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ NS_ENSURE_ARG_POINTER(val);
+ *val = 0;
+
+ if (NS_FAILED(mPrefBranch->GetIntPref(prefname, val)))
+ mDefPrefBranch->GetIntPref(prefname, val);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetFileValue(const char* aRelPrefName,
+ const char* aAbsPrefName,
+ nsIFile** aLocalFile)
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ // Get the relative first
+ nsCOMPtr<nsIRelativeFilePref> relFilePref;
+ nsresult rv = mPrefBranch->GetComplexValue(aRelPrefName,
+ NS_GET_IID(nsIRelativeFilePref),
+ getter_AddRefs(relFilePref));
+ if (relFilePref) {
+ rv = relFilePref->GetFile(aLocalFile);
+ NS_ASSERTION(*aLocalFile, "An nsIRelativeFilePref has no file.");
+ if (NS_SUCCEEDED(rv))
+ (*aLocalFile)->Normalize();
+ } else {
+ rv = mPrefBranch->GetComplexValue(aAbsPrefName,
+ NS_GET_IID(nsIFile),
+ reinterpret_cast<void**>(aLocalFile));
+ if (NS_FAILED(rv))
+ return rv;
+
+ rv = NS_NewRelativeFilePref(*aLocalFile,
+ NS_LITERAL_CSTRING(NS_APP_USER_PROFILE_50_DIR),
+ getter_AddRefs(relFilePref));
+ if (relFilePref)
+ rv = mPrefBranch->SetComplexValue(aRelPrefName,
+ NS_GET_IID(nsIRelativeFilePref),
+ relFilePref);
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetFileValue(const char* aRelPrefName,
+ const char* aAbsPrefName,
+ nsIFile* aLocalFile)
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ // Write the relative path.
+ nsCOMPtr<nsIRelativeFilePref> relFilePref;
+ NS_NewRelativeFilePref(aLocalFile,
+ NS_LITERAL_CSTRING(NS_APP_USER_PROFILE_50_DIR),
+ getter_AddRefs(relFilePref));
+ if (relFilePref) {
+ nsresult rv = mPrefBranch->SetComplexValue(aRelPrefName,
+ NS_GET_IID(nsIRelativeFilePref),
+ relFilePref);
+ if (NS_FAILED(rv))
+ return rv;
+ }
+ return mPrefBranch->SetComplexValue(aAbsPrefName, NS_GET_IID(nsIFile), aLocalFile);
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetIntValue(const char *prefname,
+ int32_t val)
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ int32_t defaultVal;
+ nsresult rv = mDefPrefBranch->GetIntPref(prefname, &defaultVal);
+
+ if (NS_SUCCEEDED(rv) && defaultVal == val)
+ mPrefBranch->ClearUserPref(prefname);
+ else
+ rv = mPrefBranch->SetIntPref(prefname, val);
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetCharValue(const char *prefname,
+ nsACString& val)
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ nsCString tmpVal;
+ if (NS_FAILED(mPrefBranch->GetCharPref(prefname, getter_Copies(tmpVal))))
+ mDefPrefBranch->GetCharPref(prefname, getter_Copies(tmpVal));
+ val = tmpVal;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetUnicharValue(const char *prefname,
+ nsAString& val)
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ nsCOMPtr<nsISupportsString> supportsString;
+ if (NS_FAILED(mPrefBranch->GetComplexValue(prefname,
+ NS_GET_IID(nsISupportsString),
+ getter_AddRefs(supportsString))))
+ mDefPrefBranch->GetComplexValue(prefname,
+ NS_GET_IID(nsISupportsString),
+ getter_AddRefs(supportsString));
+
+ if (supportsString)
+ return supportsString->GetData(val);
+ val.Truncate();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetCharValue(const char *prefname,
+ const nsACString& val)
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ if (val.IsEmpty()) {
+ mPrefBranch->ClearUserPref(prefname);
+ return NS_OK;
+ }
+
+ nsCString defaultVal;
+ nsresult rv = mDefPrefBranch->GetCharPref(prefname, getter_Copies(defaultVal));
+
+ if (NS_SUCCEEDED(rv) && defaultVal.Equals(val))
+ mPrefBranch->ClearUserPref(prefname);
+ else
+ rv = mPrefBranch->SetCharPref(prefname, nsCString(val).get());
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetUnicharValue(const char *prefname,
+ const nsAString& val)
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ if (val.IsEmpty()) {
+ mPrefBranch->ClearUserPref(prefname);
+ return NS_OK;
+ }
+
+ nsCOMPtr<nsISupportsString> supportsString;
+ nsresult rv = mDefPrefBranch->GetComplexValue(prefname,
+ NS_GET_IID(nsISupportsString),
+ getter_AddRefs(supportsString));
+ nsString defaultVal;
+ if (NS_SUCCEEDED(rv) &&
+ NS_SUCCEEDED(supportsString->GetData(defaultVal)) &&
+ defaultVal.Equals(val))
+ mPrefBranch->ClearUserPref(prefname);
+ else {
+ supportsString = do_CreateInstance(NS_SUPPORTS_STRING_CONTRACTID, &rv);
+ if (supportsString) {
+ supportsString->SetData(val);
+ rv = mPrefBranch->SetComplexValue(prefname,
+ NS_GET_IID(nsISupportsString),
+ supportsString);
+ }
+ }
+
+ return rv;
+}
+
+// pretty name is the display name to show to the user
+NS_IMETHODIMP
+nsMsgIncomingServer::GetPrettyName(nsAString& retval)
+{
+ nsresult rv = GetUnicharValue("name", retval);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // if there's no name, then just return the hostname
+ return retval.IsEmpty() ? GetConstructedPrettyName(retval) : rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetPrettyName(const nsAString& value)
+{
+ SetUnicharValue("name", value);
+ nsCOMPtr<nsIMsgFolder> rootFolder;
+ GetRootFolder(getter_AddRefs(rootFolder));
+ if (rootFolder)
+ rootFolder->SetPrettyName(value);
+ return NS_OK;
+}
+
+
+// construct the pretty name to show to the user if they haven't
+// specified one. This should be overridden for news and mail.
+NS_IMETHODIMP
+nsMsgIncomingServer::GetConstructedPrettyName(nsAString& retval)
+{
+ nsCString username;
+ nsresult rv = GetUsername(username);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!username.IsEmpty()) {
+ CopyASCIItoUTF16(username, retval);
+ retval.AppendLiteral(" on ");
+ }
+
+ nsCString hostname;
+ rv = GetHostName(hostname);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ retval.Append(NS_ConvertASCIItoUTF16(hostname));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::ToString(nsAString& aResult)
+{
+ aResult.AssignLiteral("[nsIMsgIncomingServer: ");
+ aResult.Append(NS_ConvertASCIItoUTF16(m_serverKey));
+ aResult.AppendLiteral("]");
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgIncomingServer::SetPassword(const nsACString& aPassword)
+{
+ m_password = aPassword;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgIncomingServer::GetPassword(nsACString& aPassword)
+{
+ aPassword = m_password;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgIncomingServer::GetServerRequiresPasswordForBiff(bool *aServerRequiresPasswordForBiff)
+{
+ NS_ENSURE_ARG_POINTER(aServerRequiresPasswordForBiff);
+ *aServerRequiresPasswordForBiff = true;
+ return NS_OK;
+}
+
+// This sets m_password if we find a password in the pw mgr.
+nsresult nsMsgIncomingServer::GetPasswordWithoutUI()
+{
+ nsresult rv;
+ nsCOMPtr<nsILoginManager> loginMgr(do_GetService(NS_LOGINMANAGER_CONTRACTID,
+ &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Get the current server URI
+ nsCString currServerUri;
+ rv = GetLocalStoreType(currServerUri);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ currServerUri.AppendLiteral("://");
+
+ nsCString temp;
+ rv = GetHostName(temp);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ currServerUri.Append(temp);
+
+ NS_ConvertUTF8toUTF16 currServer(currServerUri);
+
+ uint32_t numLogins = 0;
+ nsILoginInfo** logins = nullptr;
+ rv = loginMgr->FindLogins(&numLogins, currServer, EmptyString(),
+ currServer, &logins);
+
+ // Login manager can produce valid fails, e.g. NS_ERROR_ABORT when a user
+ // cancels the master password dialog. Therefore handle that here, but don't
+ // warn about it.
+ if (NS_FAILED(rv))
+ return rv;
+
+ // Don't abort here, if we didn't find any or failed, then we'll just have
+ // to prompt.
+ if (numLogins > 0)
+ {
+ nsCString serverCUsername;
+ rv = GetUsername(serverCUsername);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ NS_ConvertUTF8toUTF16 serverUsername(serverCUsername);
+
+ nsString username;
+ for (uint32_t i = 0; i < numLogins; ++i)
+ {
+ rv = logins[i]->GetUsername(username);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (username.Equals(serverUsername))
+ {
+ nsString password;
+ rv = logins[i]->GetPassword(password);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ m_password = NS_LossyConvertUTF16toASCII(password);
+ break;
+ }
+ }
+ NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(numLogins, logins);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetPasswordWithUI(const nsAString& aPromptMessage, const
+ nsAString& aPromptTitle,
+ nsIMsgWindow* aMsgWindow,
+ nsACString& aPassword)
+{
+ nsresult rv = NS_OK;
+
+ if (m_password.IsEmpty())
+ {
+ // let's see if we have the password in the password manager and
+ // can avoid this prompting thing. This makes it easier to get embedders
+ // to get up and running w/o a password prompting UI.
+ rv = GetPasswordWithoutUI();
+ // If GetPasswordWithoutUI returns NS_ERROR_ABORT, the most likely case
+ // is the user canceled getting the master password, so just return
+ // straight away, as they won't want to get prompted again.
+ if (rv == NS_ERROR_ABORT)
+ return NS_MSG_PASSWORD_PROMPT_CANCELLED;
+ }
+ if (m_password.IsEmpty())
+ {
+ nsCOMPtr<nsIAuthPrompt> dialog;
+ // aMsgWindow is required if we need to prompt
+ if (aMsgWindow)
+ {
+ rv = aMsgWindow->GetAuthPrompt(getter_AddRefs(dialog));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ if (dialog)
+ {
+ // prompt the user for the password
+ nsCString serverUri;
+ rv = GetLocalStoreType(serverUri);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ serverUri.AppendLiteral("://");
+ nsCString temp;
+ rv = GetUsername(temp);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (!temp.IsEmpty())
+ {
+ nsCString escapedUsername;
+ MsgEscapeString(temp, nsINetUtil::ESCAPE_XALPHAS, escapedUsername);
+ serverUri.Append(escapedUsername);
+ serverUri.Append('@');
+ }
+
+ rv = GetHostName(temp);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ serverUri.Append(temp);
+
+ // we pass in the previously used password, if any, into PromptPassword
+ // so that it will appear as ******. This means we can't use an nsString
+ // and getter_Copies.
+ PRUnichar *uniPassword = nullptr;
+ if (!aPassword.IsEmpty())
+ uniPassword = ToNewUnicode(NS_ConvertASCIItoUTF16(aPassword));
+
+ bool okayValue = true;
+ rv = dialog->PromptPassword(PromiseFlatString(aPromptTitle).get(),
+ PromiseFlatString(aPromptMessage).get(),
+ NS_ConvertASCIItoUTF16(serverUri).get(),
+ nsIAuthPrompt::SAVE_PASSWORD_PERMANENTLY,
+ &uniPassword, &okayValue);
+ nsAutoString uniPasswordAdopted;
+ uniPasswordAdopted.Adopt(uniPassword);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (!okayValue) // if the user pressed cancel, just return an empty string;
+ {
+ aPassword.Truncate();
+ return NS_MSG_PASSWORD_PROMPT_CANCELLED;
+ }
+
+ // we got a password back...so remember it
+ rv = SetPassword(NS_LossyConvertUTF16toASCII(uniPasswordAdopted));
+ NS_ENSURE_SUCCESS(rv, rv);
+ } // if we got a prompt dialog
+ else
+ return NS_ERROR_FAILURE;
+ } // if the password is empty
+ return GetPassword(aPassword);
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::ForgetPassword()
+{
+ nsresult rv;
+ nsCOMPtr<nsILoginManager> loginMgr =
+ do_GetService(NS_LOGINMANAGER_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Get the current server URI
+ nsCString currServerUri;
+ rv = GetLocalStoreType(currServerUri);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ currServerUri.AppendLiteral("://");
+
+ nsCString temp;
+ rv = GetHostName(temp);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ currServerUri.Append(temp);
+
+ uint32_t count;
+ nsILoginInfo** logins;
+
+ NS_ConvertUTF8toUTF16 currServer(currServerUri);
+
+ nsCString serverCUsername;
+ rv = GetUsername(serverCUsername);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ NS_ConvertUTF8toUTF16 serverUsername(serverCUsername);
+
+ rv = loginMgr->FindLogins(&count, currServer, EmptyString(),
+ currServer, &logins);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // There should only be one-login stored for this url, however just in case
+ // there isn't.
+ nsString username;
+ for (uint32_t i = 0; i < count; ++i)
+ {
+ if (NS_SUCCEEDED(logins[i]->GetUsername(username)) &&
+ username.Equals(serverUsername))
+ {
+ // If this fails, just continue, we'll still want to remove the password
+ // from our local cache.
+ loginMgr->RemoveLogin(logins[i]);
+ }
+ }
+ NS_FREE_XPCOM_ISUPPORTS_POINTER_ARRAY(count, logins);
+
+ return SetPassword(EmptyCString());
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::ForgetSessionPassword()
+{
+ m_password.Truncate();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetDefaultLocalPath(nsIFile *aDefaultLocalPath)
+{
+ nsresult rv;
+ nsCOMPtr<nsIMsgProtocolInfo> protocolInfo;
+ rv = GetProtocolInfo(getter_AddRefs(protocolInfo));
+ NS_ENSURE_SUCCESS(rv, rv);
+ return protocolInfo->SetDefaultLocalPath(aDefaultLocalPath);
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetLocalPath(nsIFile **aLocalPath)
+{
+ nsresult rv;
+
+ // if the local path has already been set, use it
+ rv = GetFileValue("directory-rel", "directory", aLocalPath);
+ if (NS_SUCCEEDED(rv) && *aLocalPath)
+ return rv;
+
+ // otherwise, create the path using the protocol info.
+ // note we are using the
+ // hostname, unless that directory exists.
+// this should prevent all collisions.
+ nsCOMPtr<nsIMsgProtocolInfo> protocolInfo;
+ rv = GetProtocolInfo(getter_AddRefs(protocolInfo));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIFile> localPath;
+ rv = protocolInfo->GetDefaultLocalPath(getter_AddRefs(localPath));
+ NS_ENSURE_SUCCESS(rv, rv);
+ localPath->Create(nsIFile::DIRECTORY_TYPE, 0755);
+
+ nsCString hostname;
+ rv = GetHostName(hostname);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // set the leaf name to "dummy", and then call MakeUnique with a suggested leaf name
+ rv = localPath->AppendNative(hostname);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = localPath->CreateUnique(nsIFile::DIRECTORY_TYPE, 0755);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = SetLocalPath(localPath);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ localPath.swap(*aLocalPath);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetMsgStore(nsIMsgPluggableStore **aMsgStore)
+{
+ NS_ENSURE_ARG_POINTER(aMsgStore);
+ if (!m_msgStore)
+ {
+ nsCString storeContractID;
+ nsresult rv;
+ // We don't want there to be a default pref, I think, since
+ // we can't change the default. We may want no pref to mean
+ // berkeley store, and then set the store pref off of some sort
+ // of default when creating a server. But we need to make sure
+ // that we do always write a store pref.
+ GetCharValue("storeContractID", storeContractID);
+ if (storeContractID.IsEmpty())
+ {
+ storeContractID.Assign("@mozilla.org/msgstore/berkeleystore;1");
+ SetCharValue("storeContractID", storeContractID);
+ }
+ // Right now, we just have one pluggable store per server. If we want
+ // to support multiple, this pref could be a list of pluggable store
+ // contract id's.
+ m_msgStore = do_CreateInstance(storeContractID.get(), &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ NS_IF_ADDREF(*aMsgStore = m_msgStore);
+ return NS_OK;
+}
+
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetLocalPath(nsIFile *aLocalPath)
+{
+ NS_ENSURE_ARG_POINTER(aLocalPath);
+ aLocalPath->Create(nsIFile::DIRECTORY_TYPE, 0755);
+ return SetFileValue("directory-rel", "directory", aLocalPath);
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetLocalStoreType(nsACString& aResult)
+{
+ NS_NOTYETIMPLEMENTED("nsMsgIncomingServer superclass not implementing GetLocalStoreType!");
+ return NS_ERROR_UNEXPECTED;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetAccountManagerChrome(nsAString& aResult)
+{
+ aResult.AssignLiteral("am-main.xul");
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::Equals(nsIMsgIncomingServer *server, bool *_retval)
+{
+ nsresult rv;
+
+ NS_ENSURE_ARG_POINTER(server);
+ NS_ENSURE_ARG_POINTER(_retval);
+
+ nsCString key1;
+ nsCString key2;
+
+ rv = GetKey(key1);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = server->GetKey(key2);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // compare the server keys
+ *_retval = key1.Equals(key2, nsCaseInsensitiveCStringComparator());
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::ClearAllValues()
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ return mPrefBranch->DeleteBranch("");
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::RemoveFiles()
+{
+ // IMPORTANT, see bug #77652
+ // don't turn this code on yet. we don't inform the user that
+ // we are going to be deleting the directory, and they might have
+ // tweaked their localPath pref for this server to point to
+ // somewhere they didn't want deleted.
+ // until we tell them, we shouldn't do the delete.
+ nsCString deferredToAccount;
+ GetCharValue("deferred_to_account", deferredToAccount);
+ bool isDeferredTo = true;
+ GetIsDeferredTo(&isDeferredTo);
+ if (!deferredToAccount.IsEmpty() || isDeferredTo)
+ {
+ NS_ASSERTION(false, "shouldn't remove files for a deferred account");
+ return NS_ERROR_FAILURE;
+ }
+ nsCOMPtr <nsIFile> localPath;
+ nsresult rv = GetLocalPath(getter_AddRefs(localPath));
+ NS_ENSURE_SUCCESS(rv, rv);
+ return localPath->Remove(true);
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetFilterList(nsIMsgFilterList *aFilterList)
+{
+ mFilterList = aFilterList;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetFilterList(nsIMsgWindow *aMsgWindow, nsIMsgFilterList **aResult)
+{
+ NS_ENSURE_ARG_POINTER(aResult);
+ if (!mFilterList)
+ {
+ nsCOMPtr<nsIMsgFolder> msgFolder;
+ // use GetRootFolder so for deferred pop3 accounts, we'll get the filters
+ // file from the deferred account, not the deferred to account,
+ // so that filters will still be per-server.
+ nsresult rv = GetRootFolder(getter_AddRefs(msgFolder));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCString filterType;
+ rv = GetCharValue("filter.type", filterType);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (!filterType.IsEmpty() && !filterType.EqualsLiteral("default"))
+ {
+ nsAutoCString contractID("@mozilla.org/filterlist;1?type=");
+ contractID += filterType;
+ ToLowerCase(contractID);
+ mFilterList = do_CreateInstance(contractID.get(), &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = mFilterList->SetFolder(msgFolder);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ NS_ADDREF(*aResult = mFilterList);
+ return NS_OK;
+ }
+
+ // The default case, a local folder, is a bit special. It requires
+ // more initialization.
+
+ nsCOMPtr<nsIFile> thisFolder;
+ rv = msgFolder->GetFilePath(getter_AddRefs(thisFolder));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mFilterFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = mFilterFile->InitWithFile(thisFolder);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ mFilterFile->AppendNative(NS_LITERAL_CSTRING("msgFilterRules.dat"));
+
+ bool fileExists;
+ mFilterFile->Exists(&fileExists);
+ if (!fileExists)
+ {
+ nsCOMPtr<nsIFile> oldFilterFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = oldFilterFile->InitWithFile(thisFolder);
+ NS_ENSURE_SUCCESS(rv, rv);
+ oldFilterFile->AppendNative(NS_LITERAL_CSTRING("rules.dat"));
+
+ oldFilterFile->Exists(&fileExists);
+ if (fileExists) //copy rules.dat --> msgFilterRules.dat
+ {
+ rv = oldFilterFile->CopyToNative(thisFolder, NS_LITERAL_CSTRING("msgFilterRules.dat"));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+ }
+ nsCOMPtr<nsIMsgFilterService> filterService =
+ do_GetService(NS_MSGFILTERSERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = filterService->OpenFilterList(mFilterFile, msgFolder, aMsgWindow, getter_AddRefs(mFilterList));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ NS_IF_ADDREF(*aResult = mFilterList);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetEditableFilterList(nsIMsgFilterList *aEditableFilterList)
+{
+ mEditableFilterList = aEditableFilterList;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetEditableFilterList(nsIMsgWindow *aMsgWindow, nsIMsgFilterList **aResult)
+{
+ NS_ENSURE_ARG_POINTER(aResult);
+ if (!mEditableFilterList)
+ {
+ bool editSeparate;
+ nsresult rv = GetBoolValue("filter.editable.separate", &editSeparate);
+ if (NS_FAILED(rv) || !editSeparate)
+ return GetFilterList(aMsgWindow, aResult);
+
+ nsCString filterType;
+ rv = GetCharValue("filter.editable.type", filterType);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsAutoCString contractID("@mozilla.org/filterlist;1?type=");
+ contractID += filterType;
+ ToLowerCase(contractID);
+ mEditableFilterList = do_CreateInstance(contractID.get(), &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIMsgFolder> msgFolder;
+ // use GetRootFolder so for deferred pop3 accounts, we'll get the filters
+ // file from the deferred account, not the deferred to account,
+ // so that filters will still be per-server.
+ rv = GetRootFolder(getter_AddRefs(msgFolder));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = mEditableFilterList->SetFolder(msgFolder);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ NS_ADDREF(*aResult = mEditableFilterList);
+ return NS_OK;
+ }
+
+ NS_IF_ADDREF(*aResult = mEditableFilterList);
+ return NS_OK;
+}
+
+// If the hostname contains ':' (like hostname:1431)
+// then parse and set the port number.
+nsresult
+nsMsgIncomingServer::InternalSetHostName(const nsACString& aHostname, const char * prefName)
+{
+ nsCString hostname;
+ hostname = aHostname;
+ if (MsgCountChar(hostname, ':') == 1)
+ {
+ int32_t colonPos = hostname.FindChar(':');
+ nsAutoCString portString(Substring(hostname, colonPos));
+ hostname.SetLength(colonPos);
+ nsresult err;
+ int32_t port = portString.ToInteger(&err);
+ if (NS_SUCCEEDED(err))
+ SetPort(port);
+ }
+ return SetCharValue(prefName, hostname);
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::OnUserOrHostNameChanged(const nsACString& oldName,
+ const nsACString& newName,
+ bool hostnameChanged)
+{
+ nsresult rv;
+
+ // 1. Reset password so that users are prompted for new password for the new user/host.
+ ForgetPassword();
+
+ // 2. Let the derived class close all cached connection to the old host.
+ CloseCachedConnections();
+
+ // 3. Notify any listeners for account server changes.
+ nsCOMPtr<nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = accountManager->NotifyServerChanged(this);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // 4. Lastly, replace all occurrences of old name in the acct name with the new one.
+ nsString acctName;
+ rv = GetPrettyName(acctName);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ NS_ENSURE_FALSE(acctName.IsEmpty(), NS_OK);
+
+ // exit if new name contains @ then better do not update the account name
+ if (!hostnameChanged && (newName.FindChar('@') != kNotFound))
+ return NS_OK;
+
+ int32_t atPos = acctName.FindChar('@');
+
+ // get previous username and hostname
+ nsCString userName, hostName;
+ if (hostnameChanged)
+ {
+ rv = GetRealUsername(userName);
+ NS_ENSURE_SUCCESS(rv, rv);
+ hostName.Assign(oldName);
+ }
+ else
+ {
+ userName.Assign(oldName);
+ rv = GetRealHostName(hostName);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // switch corresponding part of the account name to the new name...
+ if (!hostnameChanged && (atPos != kNotFound))
+ {
+ // ...if username changed and the previous username was equal to the part
+ // of the account name before @
+ if (StringHead(acctName, atPos).Equals(NS_ConvertASCIItoUTF16(userName)))
+ acctName.Replace(0, userName.Length(), NS_ConvertASCIItoUTF16(newName));
+ }
+ if (hostnameChanged)
+ {
+ // ...if hostname changed and the previous hostname was equal to the part
+ // of the account name after @, or to the whole account name
+ if (atPos == kNotFound)
+ atPos = 0;
+ else
+ atPos += 1;
+ if (Substring(acctName, atPos).Equals(NS_ConvertASCIItoUTF16(hostName))) {
+ acctName.Replace(atPos, acctName.Length() - atPos,
+ NS_ConvertASCIItoUTF16(newName));
+ }
+ }
+
+ return SetPrettyName(acctName);
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetHostName(const nsACString& aHostname)
+{
+ return (InternalSetHostName(aHostname, "hostname"));
+}
+
+// SetRealHostName() is called only when the server name is changed from the
+// UI (Account Settings page). No one should call it in any circumstances.
+NS_IMETHODIMP
+nsMsgIncomingServer::SetRealHostName(const nsACString& aHostname)
+{
+ nsCString oldName;
+ nsresult rv = GetRealHostName(oldName);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = InternalSetHostName(aHostname, "realhostname");
+
+ // A few things to take care of if we're changing the hostname.
+ if (!aHostname.Equals(oldName, nsCaseInsensitiveCStringComparator()))
+ rv = OnUserOrHostNameChanged(oldName, aHostname, true);
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetHostName(nsACString& aResult)
+{
+ nsresult rv;
+ rv = GetCharValue("hostname", aResult);
+ if (MsgCountChar(aResult, ':') == 1)
+ {
+ // gack, we need to reformat the hostname - SetHostName will do that
+ SetHostName(aResult);
+ rv = GetCharValue("hostname", aResult);
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetRealHostName(nsACString& aResult)
+{
+ // If 'realhostname' is set (was changed) then use it, otherwise use 'hostname'
+ nsresult rv;
+ rv = GetCharValue("realhostname", aResult);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (aResult.IsEmpty())
+ return GetHostName(aResult);
+
+ if (MsgCountChar(aResult, ':') == 1)
+ {
+ SetRealHostName(aResult);
+ rv = GetCharValue("realhostname", aResult);
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetRealUsername(nsACString& aResult)
+{
+ // If 'realuserName' is set (was changed) then use it, otherwise use 'userName'
+ nsresult rv;
+ rv = GetCharValue("realuserName", aResult);
+ NS_ENSURE_SUCCESS(rv, rv);
+ return aResult.IsEmpty() ? GetUsername(aResult) : rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetRealUsername(const nsACString& aUsername)
+{
+ // Need to take care of few things if we're changing the username.
+ nsCString oldName;
+ nsresult rv = GetRealUsername(oldName);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = SetCharValue("realuserName", aUsername);
+ if (!oldName.Equals(aUsername))
+ rv = OnUserOrHostNameChanged(oldName, aUsername, false);
+ return rv;
+}
+
+#define BIFF_PREF_NAME "check_new_mail"
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetDoBiff(bool *aDoBiff)
+{
+ NS_ENSURE_ARG_POINTER(aDoBiff);
+
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ nsresult rv;
+
+ rv = mPrefBranch->GetBoolPref(BIFF_PREF_NAME, aDoBiff);
+ if (NS_SUCCEEDED(rv))
+ return rv;
+
+ // if the pref isn't set, use the default
+ // value based on the protocol
+ nsCOMPtr<nsIMsgProtocolInfo> protocolInfo;
+ rv = GetProtocolInfo(getter_AddRefs(protocolInfo));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = protocolInfo->GetDefaultDoBiff(aDoBiff);
+ // note, don't call SetDoBiff()
+ // since we keep changing our minds on
+ // if biff should be on or off, let's keep the ability
+ // to change the default in future builds.
+ // if we call SetDoBiff() here, it will be in the users prefs.
+ // and we can't do anything after that.
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetDoBiff(bool aDoBiff)
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ return mPrefBranch->SetBoolPref(BIFF_PREF_NAME, aDoBiff);
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetPort(int32_t *aPort)
+{
+ NS_ENSURE_ARG_POINTER(aPort);
+
+ nsresult rv;
+ rv = GetIntValue("port", aPort);
+ // We can't use a port of 0, because the URI parsing code fails.
+ if (*aPort != PORT_NOT_SET && *aPort)
+ return rv;
+
+ // if the port isn't set, use the default
+ // port based on the protocol
+ nsCOMPtr<nsIMsgProtocolInfo> protocolInfo;
+ rv = GetProtocolInfo(getter_AddRefs(protocolInfo));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ int32_t socketType;
+ rv = GetSocketType(&socketType);
+ NS_ENSURE_SUCCESS(rv, rv);
+ bool useSSLPort = (socketType == nsMsgSocketType::SSL);
+ return protocolInfo->GetDefaultServerPort(useSSLPort, aPort);
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetPort(int32_t aPort)
+{
+ nsresult rv;
+
+ nsCOMPtr<nsIMsgProtocolInfo> protocolInfo;
+ rv = GetProtocolInfo(getter_AddRefs(protocolInfo));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ int32_t socketType;
+ rv = GetSocketType(&socketType);
+ NS_ENSURE_SUCCESS(rv, rv);
+ bool useSSLPort = (socketType == nsMsgSocketType::SSL);
+
+ int32_t defaultPort;
+ protocolInfo->GetDefaultServerPort(useSSLPort, &defaultPort);
+ return SetIntValue("port", aPort == defaultPort ? PORT_NOT_SET : aPort);
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetProtocolInfo(nsIMsgProtocolInfo **aResult)
+{
+ NS_ENSURE_ARG_POINTER(aResult);
+
+ nsCString type;
+ nsresult rv = GetType(type);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsAutoCString contractid(NS_MSGPROTOCOLINFO_CONTRACTID_PREFIX);
+ contractid.Append(type);
+
+ nsCOMPtr<nsIMsgProtocolInfo> protocolInfo = do_GetService(contractid.get(), &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ protocolInfo.forget(aResult);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgIncomingServer::GetRetentionSettings(nsIMsgRetentionSettings **settings)
+{
+ NS_ENSURE_ARG_POINTER(settings);
+ nsMsgRetainByPreference retainByPreference;
+ int32_t daysToKeepHdrs = 0;
+ int32_t numHeadersToKeep = 0;
+ bool keepUnreadMessagesOnly = false;
+ int32_t daysToKeepBodies = 0;
+ bool cleanupBodiesByDays = false;
+ bool applyToFlaggedMessages = false;
+ nsresult rv = NS_OK;
+ // Create an empty retention settings object,
+ // get the settings from the server prefs, and init the object from the prefs.
+ nsCOMPtr <nsIMsgRetentionSettings> retentionSettings =
+ do_CreateInstance(NS_MSG_RETENTIONSETTINGS_CONTRACTID);
+ if (retentionSettings)
+ {
+ rv = GetBoolValue("keepUnreadOnly", &keepUnreadMessagesOnly);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = GetIntValue("retainBy", (int32_t*) &retainByPreference);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = GetIntValue("numHdrsToKeep", &numHeadersToKeep);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = GetIntValue("daysToKeepHdrs", &daysToKeepHdrs);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = GetIntValue("daysToKeepBodies", &daysToKeepBodies);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = GetBoolValue("cleanupBodies", &cleanupBodiesByDays);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = GetBoolValue("applyToFlaggedMessages", &applyToFlaggedMessages);
+ NS_ENSURE_SUCCESS(rv, rv);
+ retentionSettings->SetRetainByPreference(retainByPreference);
+ retentionSettings->SetNumHeadersToKeep((uint32_t) numHeadersToKeep);
+ retentionSettings->SetKeepUnreadMessagesOnly(keepUnreadMessagesOnly);
+ retentionSettings->SetDaysToKeepBodies(daysToKeepBodies);
+ retentionSettings->SetDaysToKeepHdrs(daysToKeepHdrs);
+ retentionSettings->SetCleanupBodiesByDays(cleanupBodiesByDays);
+ retentionSettings->SetApplyToFlaggedMessages(applyToFlaggedMessages);
+ }
+ else
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ NS_IF_ADDREF(*settings = retentionSettings);
+ return rv;
+}
+
+NS_IMETHODIMP nsMsgIncomingServer::SetRetentionSettings(nsIMsgRetentionSettings *settings)
+{
+ nsMsgRetainByPreference retainByPreference;
+ uint32_t daysToKeepHdrs = 0;
+ uint32_t numHeadersToKeep = 0;
+ bool keepUnreadMessagesOnly = false;
+ uint32_t daysToKeepBodies = 0;
+ bool cleanupBodiesByDays = false;
+ bool applyToFlaggedMessages = false;
+ settings->GetRetainByPreference(&retainByPreference);
+ settings->GetNumHeadersToKeep(&numHeadersToKeep);
+ settings->GetKeepUnreadMessagesOnly(&keepUnreadMessagesOnly);
+ settings->GetDaysToKeepBodies(&daysToKeepBodies);
+ settings->GetDaysToKeepHdrs(&daysToKeepHdrs);
+ settings->GetCleanupBodiesByDays(&cleanupBodiesByDays);
+ settings->GetApplyToFlaggedMessages(&applyToFlaggedMessages);
+ nsresult rv = SetBoolValue("keepUnreadOnly", keepUnreadMessagesOnly);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = SetIntValue("retainBy", retainByPreference);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = SetIntValue("numHdrsToKeep", numHeadersToKeep);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = SetIntValue("daysToKeepHdrs", daysToKeepHdrs);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = SetIntValue("daysToKeepBodies", daysToKeepBodies);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = SetBoolValue("cleanupBodies", cleanupBodiesByDays);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = SetBoolValue("applyToFlaggedMessages", applyToFlaggedMessages);
+ NS_ENSURE_SUCCESS(rv, rv);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetDisplayStartupPage(bool *displayStartupPage)
+{
+ NS_ENSURE_ARG_POINTER(displayStartupPage);
+ *displayStartupPage = m_displayStartupPage;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetDisplayStartupPage(bool displayStartupPage)
+{
+ m_displayStartupPage = displayStartupPage;
+ return NS_OK;
+}
+
+
+NS_IMETHODIMP nsMsgIncomingServer::GetDownloadSettings(nsIMsgDownloadSettings **settings)
+{
+ NS_ENSURE_ARG_POINTER(settings);
+ bool downloadUnreadOnly = false;
+ bool downloadByDate = false;
+ uint32_t ageLimitOfMsgsToDownload = 0;
+ nsresult rv = NS_OK;
+ if (!m_downloadSettings)
+ {
+ m_downloadSettings = do_CreateInstance(NS_MSG_DOWNLOADSETTINGS_CONTRACTID);
+ if (m_downloadSettings)
+ {
+ rv = GetBoolValue("downloadUnreadOnly", &downloadUnreadOnly);
+ rv = GetBoolValue("downloadByDate", &downloadByDate);
+ rv = GetIntValue("ageLimit", (int32_t *) &ageLimitOfMsgsToDownload);
+ m_downloadSettings->SetDownloadUnreadOnly(downloadUnreadOnly);
+ m_downloadSettings->SetDownloadByDate(downloadByDate);
+ m_downloadSettings->SetAgeLimitOfMsgsToDownload(ageLimitOfMsgsToDownload);
+ }
+ else
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ // Create an empty download settings object,
+ // get the settings from the server prefs, and init the object from the prefs.
+ }
+ NS_IF_ADDREF(*settings = m_downloadSettings);
+ return rv;
+}
+
+NS_IMETHODIMP nsMsgIncomingServer::SetDownloadSettings(nsIMsgDownloadSettings *settings)
+{
+ m_downloadSettings = settings;
+ bool downloadUnreadOnly = false;
+ bool downloadByDate = false;
+ uint32_t ageLimitOfMsgsToDownload = 0;
+ m_downloadSettings->GetDownloadUnreadOnly(&downloadUnreadOnly);
+ m_downloadSettings->GetDownloadByDate(&downloadByDate);
+ m_downloadSettings->GetAgeLimitOfMsgsToDownload(&ageLimitOfMsgsToDownload);
+ nsresult rv = SetBoolValue("downloadUnreadOnly", downloadUnreadOnly);
+ NS_ENSURE_SUCCESS(rv, rv);
+ SetBoolValue("downloadByDate", downloadByDate);
+ return SetIntValue("ageLimit", ageLimitOfMsgsToDownload);
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetSupportsDiskSpace(bool *aSupportsDiskSpace)
+{
+ NS_ENSURE_ARG_POINTER(aSupportsDiskSpace);
+ *aSupportsDiskSpace = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetOfflineSupportLevel(int32_t *aSupportLevel)
+{
+ NS_ENSURE_ARG_POINTER(aSupportLevel);
+
+ nsresult rv = GetIntValue("offline_support_level", aSupportLevel);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (*aSupportLevel == OFFLINE_SUPPORT_LEVEL_UNDEFINED)
+ *aSupportLevel = OFFLINE_SUPPORT_LEVEL_NONE;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetOfflineSupportLevel(int32_t aSupportLevel)
+{
+ SetIntValue("offline_support_level", aSupportLevel);
+ return NS_OK;
+}
+#define BASE_MSGS_URL "chrome://messenger/locale/messenger.properties"
+
+NS_IMETHODIMP nsMsgIncomingServer::DisplayOfflineMsg(nsIMsgWindow *aMsgWindow)
+{
+ NS_ENSURE_ARG_POINTER(aMsgWindow);
+
+ nsCOMPtr<nsIStringBundleService> bundleService =
+ mozilla::services::GetStringBundleService();
+ NS_ENSURE_TRUE(bundleService, NS_ERROR_UNEXPECTED);
+
+ nsCOMPtr<nsIStringBundle> bundle;
+ nsresult rv = bundleService->CreateBundle(BASE_MSGS_URL, getter_AddRefs(bundle));
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (bundle)
+ {
+ nsString errorMsgTitle;
+ nsString errorMsgBody;
+ bundle->GetStringFromName(NS_LITERAL_STRING("nocachedbodybody").get(), getter_Copies(errorMsgBody));
+ bundle->GetStringFromName(NS_LITERAL_STRING("nocachedbodytitle").get(), getter_Copies(errorMsgTitle));
+ aMsgWindow->DisplayHTMLInMessagePane(errorMsgTitle, errorMsgBody, true);
+ }
+
+ return NS_OK;
+}
+
+// Called only during the migration process. A unique name is generated for the
+// migrated account.
+NS_IMETHODIMP
+nsMsgIncomingServer::GeneratePrettyNameForMigration(nsAString& aPrettyName)
+{
+/**
+ * 4.x had provisions for multiple imap servers to be maintained under
+ * single identity. So, when migrated each of those server accounts need
+ * to be represented by unique account name. nsImapIncomingServer will
+ * override the implementation for this to do the right thing.
+*/
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetFilterScope(nsMsgSearchScopeValue *filterScope)
+{
+ NS_ENSURE_ARG_POINTER(filterScope);
+ *filterScope = nsMsgSearchScope::offlineMailFilter;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetSearchScope(nsMsgSearchScopeValue *searchScope)
+{
+ NS_ENSURE_ARG_POINTER(searchScope);
+ *searchScope = nsMsgSearchScope::offlineMail;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetIsSecure(bool *aIsSecure)
+{
+ NS_ENSURE_ARG_POINTER(aIsSecure);
+ int32_t socketType;
+ nsresult rv = GetSocketType(&socketType);
+ NS_ENSURE_SUCCESS(rv,rv);
+ *aIsSecure = (socketType == nsMsgSocketType::alwaysSTARTTLS ||
+ socketType == nsMsgSocketType::SSL);
+ return NS_OK;
+}
+
+// use the convenience macros to implement the accessors
+NS_IMPL_SERVERPREF_STR(nsMsgIncomingServer, Username, "userName")
+NS_IMPL_SERVERPREF_INT(nsMsgIncomingServer, AuthMethod, "authMethod")
+NS_IMPL_SERVERPREF_INT(nsMsgIncomingServer, BiffMinutes, "check_time")
+NS_IMPL_SERVERPREF_STR(nsMsgIncomingServer, Type, "type")
+NS_IMPL_SERVERPREF_BOOL(nsMsgIncomingServer, DownloadOnBiff, "download_on_biff")
+NS_IMPL_SERVERPREF_BOOL(nsMsgIncomingServer, Valid, "valid")
+NS_IMPL_SERVERPREF_BOOL(nsMsgIncomingServer, EmptyTrashOnExit,
+ "empty_trash_on_exit")
+NS_IMPL_SERVERPREF_BOOL(nsMsgIncomingServer, CanDelete, "canDelete")
+NS_IMPL_SERVERPREF_BOOL(nsMsgIncomingServer, LoginAtStartUp, "login_at_startup")
+NS_IMPL_SERVERPREF_BOOL(nsMsgIncomingServer,
+ DefaultCopiesAndFoldersPrefsToServer,
+ "allows_specialfolders_usage")
+
+NS_IMPL_SERVERPREF_BOOL(nsMsgIncomingServer,
+ CanCreateFoldersOnServer,
+ "canCreateFolders")
+
+NS_IMPL_SERVERPREF_BOOL(nsMsgIncomingServer,
+ CanFileMessagesOnServer,
+ "canFileMessages")
+
+NS_IMPL_SERVERPREF_BOOL(nsMsgIncomingServer,
+ LimitOfflineMessageSize,
+ "limit_offline_message_size")
+
+NS_IMPL_SERVERPREF_INT(nsMsgIncomingServer, MaxMessageSize, "max_size")
+
+NS_IMPL_SERVERPREF_INT(nsMsgIncomingServer, IncomingDuplicateAction, "dup_action")
+
+NS_IMPL_SERVERPREF_BOOL(nsMsgIncomingServer, Hidden, "hidden")
+
+NS_IMETHODIMP nsMsgIncomingServer::GetSocketType(int32_t *aSocketType)
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ nsresult rv = mPrefBranch->GetIntPref("socketType", aSocketType);
+
+ // socketType is set to default value. Look at isSecure setting
+ if (NS_FAILED(rv))
+ {
+ bool isSecure;
+ rv = mPrefBranch->GetBoolPref("isSecure", &isSecure);
+ if (NS_SUCCEEDED(rv) && isSecure)
+ {
+ *aSocketType = nsMsgSocketType::SSL;
+ // don't call virtual method in case overrides call GetSocketType
+ nsMsgIncomingServer::SetSocketType(*aSocketType);
+ }
+ else
+ {
+ if (!mDefPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+ rv = mDefPrefBranch->GetIntPref("socketType", aSocketType);
+ if (NS_FAILED(rv))
+ *aSocketType = nsMsgSocketType::plain;
+ }
+ }
+ return rv;
+}
+
+NS_IMETHODIMP nsMsgIncomingServer::SetSocketType(int32_t aSocketType)
+{
+ if (!mPrefBranch)
+ return NS_ERROR_NOT_INITIALIZED;
+
+ int32_t socketType = nsMsgSocketType::plain;
+ mPrefBranch->GetIntPref("socketType", &socketType);
+
+ nsresult rv = mPrefBranch->SetIntPref("socketType", aSocketType);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool isSecureOld = (socketType == nsMsgSocketType::alwaysSTARTTLS ||
+ socketType == nsMsgSocketType::SSL);
+ bool isSecureNew = (aSocketType == nsMsgSocketType::alwaysSTARTTLS ||
+ aSocketType == nsMsgSocketType::SSL);
+ if ((isSecureOld != isSecureNew) && m_rootFolder) {
+ nsCOMPtr <nsIAtom> isSecureAtom = MsgGetAtom("isSecure");
+ m_rootFolder->NotifyBoolPropertyChanged(isSecureAtom,
+ isSecureOld, isSecureNew);
+ }
+ return NS_OK;
+}
+
+// Check if the password is available and return a boolean indicating whether
+// it is being authenticated or not.
+NS_IMETHODIMP
+nsMsgIncomingServer::GetPasswordPromptRequired(bool *aPasswordIsRequired)
+{
+ NS_ENSURE_ARG_POINTER(aPasswordIsRequired);
+ *aPasswordIsRequired = true;
+
+ // If the password is not even required for biff we don't need to check any further
+ nsresult rv = GetServerRequiresPasswordForBiff(aPasswordIsRequired);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!*aPasswordIsRequired)
+ return NS_OK;
+
+ // If the password is empty, check to see if it is stored and to be retrieved
+ if (m_password.IsEmpty())
+ (void)GetPasswordWithoutUI();
+
+ *aPasswordIsRequired = m_password.IsEmpty();
+ return rv;
+}
+
+NS_IMETHODIMP nsMsgIncomingServer::ConfigureTemporaryFilters(nsIMsgFilterList *aFilterList)
+{
+ nsresult rv = ConfigureTemporaryReturnReceiptsFilter(aFilterList);
+ if (NS_FAILED(rv)) // shut up warnings...
+ return rv;
+ return ConfigureTemporaryServerSpamFilters(aFilterList);
+}
+
+nsresult
+nsMsgIncomingServer::ConfigureTemporaryServerSpamFilters(nsIMsgFilterList *filterList)
+{
+ nsCOMPtr<nsISpamSettings> spamSettings;
+ nsresult rv = GetSpamSettings(getter_AddRefs(spamSettings));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool useServerFilter;
+ rv = spamSettings->GetUseServerFilter(&useServerFilter);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // if we aren't configured to use server filters, then return early.
+ if (!useServerFilter)
+ return NS_OK;
+
+ // For performance reasons, we'll handle clearing of filters if the user turns
+ // off the server-side filters from the junk mail controls, in the junk mail controls.
+ nsAutoCString serverFilterName;
+ spamSettings->GetServerFilterName(serverFilterName);
+ if (serverFilterName.IsEmpty())
+ return NS_OK;
+ int32_t serverFilterTrustFlags = 0;
+ (void) spamSettings->GetServerFilterTrustFlags(&serverFilterTrustFlags);
+ if (!serverFilterTrustFlags)
+ return NS_OK;
+ // check if filters have been setup already.
+ nsAutoString yesFilterName, noFilterName;
+ CopyASCIItoUTF16(serverFilterName, yesFilterName);
+ yesFilterName.AppendLiteral("Yes");
+
+ CopyASCIItoUTF16(serverFilterName, noFilterName);
+ noFilterName.AppendLiteral("No");
+
+ nsCOMPtr<nsIMsgFilter> newFilter;
+ (void) filterList->GetFilterNamed(yesFilterName,
+ getter_AddRefs(newFilter));
+
+ if (!newFilter)
+ (void) filterList->GetFilterNamed(noFilterName,
+ getter_AddRefs(newFilter));
+ if (newFilter)
+ return NS_OK;
+
+ nsCOMPtr<nsIFile> file;
+ spamSettings->GetServerFilterFile(getter_AddRefs(file));
+
+ // it's possible that we can no longer find the sfd file (i.e. the user disabled an extnsion that
+ // was supplying the .sfd file.
+ if (!file)
+ return NS_OK;
+
+ nsCOMPtr<nsIMsgFilterService> filterService = do_GetService(NS_MSGFILTERSERVICE_CONTRACTID, &rv);
+ nsCOMPtr<nsIMsgFilterList> serverFilterList;
+
+ rv = filterService->OpenFilterList(file, NULL, NULL, getter_AddRefs(serverFilterList));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = serverFilterList->GetFilterNamed(yesFilterName,
+ getter_AddRefs(newFilter));
+ if (newFilter && serverFilterTrustFlags & nsISpamSettings::TRUST_POSITIVES)
+ {
+ newFilter->SetTemporary(true);
+ // check if we're supposed to move junk mail to junk folder; if so,
+ // add filter action to do so.
+
+ /*
+ * We don't want this filter to activate on messages that have
+ * been marked by the user as not spam. This occurs when messages that
+ * were marked as good are moved back into the inbox. But to
+ * do this with a filter, we have to add a boolean term. That requires
+ * that we rewrite the existing filter search terms to group them.
+ */
+
+ // get the list of search terms from the filter
+ nsCOMPtr<nsISupportsArray> searchTerms;
+ rv = newFilter->GetSearchTerms(getter_AddRefs(searchTerms));
+ NS_ENSURE_SUCCESS(rv, rv);
+ uint32_t count = 0;
+ searchTerms->Count(&count);
+ if (count > 1) // don't need to group a single term
+ {
+ // beginGrouping the first term, and endGrouping the last term
+ nsCOMPtr<nsIMsgSearchTerm> firstTerm(do_QueryElementAt(searchTerms,
+ 0, &rv));
+ NS_ENSURE_SUCCESS(rv,rv);
+ firstTerm->SetBeginsGrouping(true);
+
+ nsCOMPtr<nsIMsgSearchTerm> lastTerm(do_QueryElementAt(searchTerms,
+ count - 1, &rv));
+ NS_ENSURE_SUCCESS(rv,rv);
+ lastTerm->SetEndsGrouping(true);
+ }
+
+ // Create a new term, checking if the user set junk status. The term will
+ // search for junkscoreorigin != "user"
+ nsCOMPtr<nsIMsgSearchTerm> searchTerm;
+ rv = newFilter->CreateTerm(getter_AddRefs(searchTerm));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ searchTerm->SetAttrib(nsMsgSearchAttrib::JunkScoreOrigin);
+ searchTerm->SetOp(nsMsgSearchOp::Isnt);
+ searchTerm->SetBooleanAnd(true);
+
+ nsCOMPtr<nsIMsgSearchValue> searchValue;
+ searchTerm->GetValue(getter_AddRefs(searchValue));
+ NS_ENSURE_SUCCESS(rv, rv);
+ searchValue->SetAttrib(nsMsgSearchAttrib::JunkScoreOrigin);
+ searchValue->SetStr(NS_LITERAL_STRING("user"));
+ searchTerm->SetValue(searchValue);
+
+ searchTerms->InsertElementAt(searchTerm, count);
+
+ bool moveOnSpam, markAsReadOnSpam;
+ spamSettings->GetMoveOnSpam(&moveOnSpam);
+ if (moveOnSpam)
+ {
+ nsCString spamFolderURI;
+ rv = spamSettings->GetSpamFolderURI(getter_Copies(spamFolderURI));
+ if (NS_SUCCEEDED(rv) && (!spamFolderURI.IsEmpty()))
+ {
+ nsCOMPtr <nsIMsgRuleAction> moveAction;
+ rv = newFilter->CreateAction(getter_AddRefs(moveAction));
+ if (NS_SUCCEEDED(rv))
+ {
+ moveAction->SetType(nsMsgFilterAction::MoveToFolder);
+ moveAction->SetTargetFolderUri(spamFolderURI);
+ newFilter->AppendAction(moveAction);
+ }
+ }
+ }
+ spamSettings->GetMarkAsReadOnSpam(&markAsReadOnSpam);
+ if (markAsReadOnSpam)
+ {
+ nsCOMPtr <nsIMsgRuleAction> markAsReadAction;
+ rv = newFilter->CreateAction(getter_AddRefs(markAsReadAction));
+ if (NS_SUCCEEDED(rv))
+ {
+ markAsReadAction->SetType(nsMsgFilterAction::MarkRead);
+ newFilter->AppendAction(markAsReadAction);
+ }
+ }
+ filterList->InsertFilterAt(0, newFilter);
+ }
+
+ rv = serverFilterList->GetFilterNamed(noFilterName,
+ getter_AddRefs(newFilter));
+ if (newFilter && serverFilterTrustFlags & nsISpamSettings::TRUST_NEGATIVES)
+ {
+ newFilter->SetTemporary(true);
+ filterList->InsertFilterAt(0, newFilter);
+ }
+
+ return rv;
+}
+
+nsresult
+nsMsgIncomingServer::ConfigureTemporaryReturnReceiptsFilter(nsIMsgFilterList *filterList)
+{
+ nsresult rv;
+
+ nsCOMPtr<nsIMsgAccountManager> accountMgr = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIMsgIdentity> identity;
+ rv = accountMgr->GetFirstIdentityForServer(this, getter_AddRefs(identity));
+ NS_ENSURE_SUCCESS(rv, rv);
+ // this can return success and a null identity...
+
+ bool useCustomPrefs = false;
+ int32_t incorp = nsIMsgMdnGenerator::eIncorporateInbox;
+ NS_ENSURE_TRUE(identity, NS_ERROR_NULL_POINTER);
+
+ identity->GetBoolAttribute("use_custom_prefs", &useCustomPrefs);
+ if (useCustomPrefs)
+ rv = GetIntValue("incorporate_return_receipt", &incorp);
+ else
+ {
+ nsCOMPtr<nsIPrefBranch> prefs(do_GetService(NS_PREFSERVICE_CONTRACTID));
+ if (prefs)
+ prefs->GetIntPref("mail.incorporate.return_receipt", &incorp);
+ }
+
+ bool enable = (incorp == nsIMsgMdnGenerator::eIncorporateSent);
+
+ // this is a temporary, internal mozilla filter
+ // it will not show up in the UI, it will not be written to disk
+ NS_NAMED_LITERAL_STRING(internalReturnReceiptFilterName, "mozilla-temporary-internal-MDN-receipt-filter");
+
+ nsCOMPtr<nsIMsgFilter> newFilter;
+ rv = filterList->GetFilterNamed(internalReturnReceiptFilterName,
+ getter_AddRefs(newFilter));
+ if (newFilter)
+ newFilter->SetEnabled(enable);
+ else if (enable)
+ {
+ nsCString actionTargetFolderUri;
+ rv = identity->GetFccFolder(actionTargetFolderUri);
+ if (!actionTargetFolderUri.IsEmpty())
+ {
+ filterList->CreateFilter(internalReturnReceiptFilterName,
+ getter_AddRefs(newFilter));
+ if (newFilter)
+ {
+ newFilter->SetEnabled(true);
+ // this internal filter is temporary
+ // and should not show up in the UI or be written to disk
+ newFilter->SetTemporary(true);
+
+ nsCOMPtr<nsIMsgSearchTerm> term;
+ nsCOMPtr<nsIMsgSearchValue> value;
+
+ rv = newFilter->CreateTerm(getter_AddRefs(term));
+ if (NS_SUCCEEDED(rv))
+ {
+ rv = term->GetValue(getter_AddRefs(value));
+ if (NS_SUCCEEDED(rv))
+ {
+ // we need to use OtherHeader + 1 so nsMsgFilter::GetTerm will
+ // return our custom header.
+ value->SetAttrib(nsMsgSearchAttrib::OtherHeader + 1);
+ value->SetStr(NS_LITERAL_STRING("multipart/report"));
+ term->SetAttrib(nsMsgSearchAttrib::OtherHeader + 1);
+ term->SetOp(nsMsgSearchOp::Contains);
+ term->SetBooleanAnd(true);
+ term->SetArbitraryHeader(NS_LITERAL_CSTRING("Content-Type"));
+ term->SetValue(value);
+ newFilter->AppendTerm(term);
+ }
+ }
+ rv = newFilter->CreateTerm(getter_AddRefs(term));
+ if (NS_SUCCEEDED(rv))
+ {
+ rv = term->GetValue(getter_AddRefs(value));
+ if (NS_SUCCEEDED(rv))
+ {
+ // XXX todo
+ // determine if ::OtherHeader is the best way to do this.
+ // see nsMsgSearchOfflineMail::MatchTerms()
+ value->SetAttrib(nsMsgSearchAttrib::OtherHeader + 1);
+ value->SetStr(NS_LITERAL_STRING("disposition-notification"));
+ term->SetAttrib(nsMsgSearchAttrib::OtherHeader + 1);
+ term->SetOp(nsMsgSearchOp::Contains);
+ term->SetBooleanAnd(true);
+ term->SetArbitraryHeader(NS_LITERAL_CSTRING("Content-Type"));
+ term->SetValue(value);
+ newFilter->AppendTerm(term);
+ }
+ }
+ nsCOMPtr<nsIMsgRuleAction> filterAction;
+ rv = newFilter->CreateAction(getter_AddRefs(filterAction));
+ if (NS_SUCCEEDED(rv))
+ {
+ filterAction->SetType(nsMsgFilterAction::MoveToFolder);
+ filterAction->SetTargetFolderUri(actionTargetFolderUri);
+ newFilter->AppendAction(filterAction);
+ filterList->InsertFilterAt(0, newFilter);
+ }
+ }
+ }
+ }
+ return rv;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::ClearTemporaryReturnReceiptsFilter()
+{
+ if (mFilterList)
+ {
+ nsCOMPtr<nsIMsgFilter> mdnFilter;
+ nsresult rv = mFilterList->GetFilterNamed(NS_LITERAL_STRING("mozilla-temporary-internal-MDN-receipt-filter"),
+ getter_AddRefs(mdnFilter));
+ if (NS_SUCCEEDED(rv) && mdnFilter)
+ return mFilterList->RemoveFilter(mdnFilter);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetMsgFolderFromURI(nsIMsgFolder *aFolderResource, const nsACString& aURI, nsIMsgFolder **aFolder)
+{
+ nsCOMPtr<nsIMsgFolder> rootMsgFolder;
+ nsresult rv = GetRootMsgFolder(getter_AddRefs(rootMsgFolder));
+ NS_ENSURE_TRUE(rootMsgFolder, NS_ERROR_UNEXPECTED);
+
+ nsCOMPtr <nsIMsgFolder> msgFolder;
+ rv = rootMsgFolder->GetChildWithURI(aURI, true, true /*caseInsensitive*/, getter_AddRefs(msgFolder));
+ if (NS_FAILED(rv) || !msgFolder)
+ msgFolder = aFolderResource;
+ NS_IF_ADDREF(*aFolder = msgFolder);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetSpamSettings(nsISpamSettings **aSpamSettings)
+{
+ NS_ENSURE_ARG_POINTER(aSpamSettings);
+
+ nsAutoCString spamActionTargetAccount;
+ GetCharValue("spamActionTargetAccount", spamActionTargetAccount);
+ if (spamActionTargetAccount.IsEmpty())
+ {
+ GetServerURI(spamActionTargetAccount);
+ SetCharValue("spamActionTargetAccount", spamActionTargetAccount);
+ }
+
+ if (!mSpamSettings) {
+ nsresult rv;
+ mSpamSettings = do_CreateInstance(NS_SPAMSETTINGS_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv,rv);
+ mSpamSettings->Initialize(this);
+ NS_ENSURE_SUCCESS(rv,rv);
+ }
+
+ NS_ADDREF(*aSpamSettings = mSpamSettings);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetSpamFilterPlugin(nsIMsgFilterPlugin **aFilterPlugin)
+{
+ NS_ENSURE_ARG_POINTER(aFilterPlugin);
+ if (!mFilterPlugin)
+ {
+ nsresult rv;
+ mFilterPlugin = do_GetService("@mozilla.org/messenger/filter-plugin;1?name=bayesianfilter", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ NS_IF_ADDREF(*aFilterPlugin = mFilterPlugin);
+ return NS_OK;
+}
+
+// get all the servers that defer to the account for the passed in server. Note that
+// destServer may not be "this"
+nsresult nsMsgIncomingServer::GetDeferredServers(nsIMsgIncomingServer *destServer, nsCOMArray<nsIPop3IncomingServer>& aServers)
+{
+ nsresult rv;
+ nsCOMPtr<nsIMsgAccountManager> accountManager
+ = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr <nsIMsgAccount> thisAccount;
+ accountManager->FindAccountForServer(destServer, getter_AddRefs(thisAccount));
+ if (thisAccount)
+ {
+ nsCOMPtr<nsIArray> allServers;
+ nsCString accountKey;
+ thisAccount->GetKey(accountKey);
+ accountManager->GetAllServers(getter_AddRefs(allServers));
+ if (allServers)
+ {
+ uint32_t serverCount;
+ allServers->GetLength(&serverCount);
+ for (uint32_t i = 0; i < serverCount; i++)
+ {
+ nsCOMPtr<nsIPop3IncomingServer> server(do_QueryElementAt(allServers, i));
+ if (server)
+ {
+ nsCString deferredToAccount;
+ server->GetDeferredToAccount(deferredToAccount);
+ if (deferredToAccount.Equals(accountKey))
+ aServers.AppendElement(server);
+ }
+ }
+ }
+ }
+ return rv;
+}
+
+NS_IMETHODIMP nsMsgIncomingServer::GetIsDeferredTo(bool *aIsDeferredTo)
+{
+ NS_ENSURE_ARG_POINTER(aIsDeferredTo);
+ nsCOMPtr<nsIMsgAccountManager> accountManager
+ = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID);
+ if (accountManager)
+ {
+ nsCOMPtr <nsIMsgAccount> thisAccount;
+ accountManager->FindAccountForServer(this, getter_AddRefs(thisAccount));
+ if (thisAccount)
+ {
+ nsCOMPtr<nsIArray> allServers;
+ nsCString accountKey;
+ thisAccount->GetKey(accountKey);
+ accountManager->GetAllServers(getter_AddRefs(allServers));
+ if (allServers)
+ {
+ uint32_t serverCount;
+ allServers->GetLength(&serverCount);
+ for (uint32_t i = 0; i < serverCount; i++)
+ {
+ nsCOMPtr <nsIMsgIncomingServer> server (do_QueryElementAt(allServers, i));
+ if (server)
+ {
+ nsCString deferredToAccount;
+ server->GetCharValue("deferred_to_account", deferredToAccount);
+ if (deferredToAccount.Equals(accountKey))
+ {
+ *aIsDeferredTo = true;
+ return NS_OK;
+ }
+ }
+ }
+ }
+ }
+ }
+ *aIsDeferredTo = false;
+ return NS_OK;
+}
+
+const long kMaxDownloadTableSize = 500;
+
+// aClosure is the server, from that we get the cutoff point, below which we evict
+// aData is the arrival index of the msg.
+/* static */PLDHashOperator nsMsgIncomingServer::evictOldEntries(nsCStringHashKey::KeyType aKey, int32_t &aData, void *aClosure)
+{
+ nsMsgIncomingServer *server = (nsMsgIncomingServer *) aClosure;
+ if (aData < server->m_numMsgsDownloaded - kMaxDownloadTableSize/2)
+ return PL_DHASH_REMOVE;
+ return server->m_downloadedHdrs.Count() > kMaxDownloadTableSize/2 ? PL_DHASH_NEXT : PL_DHASH_STOP;
+}
+
+// hash the concatenation of the message-id and subject as the hash table key,
+// and store the arrival index as the value. To limit the size of the hash table,
+// we just throw out ones with a lower ordinal value than the cut-off point.
+NS_IMETHODIMP nsMsgIncomingServer::IsNewHdrDuplicate(nsIMsgDBHdr *aNewHdr, bool *aResult)
+{
+ NS_ENSURE_ARG_POINTER(aResult);
+ NS_ENSURE_ARG_POINTER(aNewHdr);
+ *aResult = false;
+
+ // If the message has been partially downloaded, the message should not
+ // be considered a duplicated message. See bug 714090.
+ uint32_t flags;
+ aNewHdr->GetFlags(&flags);
+ if (flags & nsMsgMessageFlags::Partial)
+ return NS_OK;
+
+ nsAutoCString strHashKey;
+ nsCString messageId, subject;
+ aNewHdr->GetMessageId(getter_Copies(messageId));
+ strHashKey.Append(messageId);
+ aNewHdr->GetSubject(getter_Copies(subject));
+ // err on the side of caution and ignore messages w/o subject or messageid.
+ if (subject.IsEmpty() || messageId.IsEmpty())
+ return NS_OK;
+ strHashKey.Append(subject);
+ int32_t hashValue = 0;
+ m_downloadedHdrs.Get(strHashKey, &hashValue);
+ if (hashValue)
+ *aResult = true;
+ else
+ {
+ // we store the current size of the hash table as the hash
+ // value - this allows us to delete older entries.
+ m_downloadedHdrs.Put(strHashKey, ++m_numMsgsDownloaded);
+ // Check if hash table is larger than some reasonable size
+ // and if is it, iterate over hash table deleting messages
+ // with an arrival index < number of msgs downloaded - half the reasonable size.
+ if (m_downloadedHdrs.Count() >= kMaxDownloadTableSize)
+ m_downloadedHdrs.Enumerate(evictOldEntries, this);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetForcePropertyEmpty(const char *aPropertyName, bool *_retval)
+{
+ NS_ENSURE_ARG_POINTER(_retval);
+ nsAutoCString nameEmpty(aPropertyName);
+ nameEmpty.Append(NS_LITERAL_CSTRING(".empty"));
+ nsCString value;
+ GetCharValue(nameEmpty.get(), value);
+ *_retval = value.EqualsLiteral("true");
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::SetForcePropertyEmpty(const char *aPropertyName, bool aValue)
+{
+ nsAutoCString nameEmpty(aPropertyName);
+ nameEmpty.Append(NS_LITERAL_CSTRING(".empty"));
+ return SetCharValue(nameEmpty.get(),
+ aValue ? NS_LITERAL_CSTRING("true") : NS_LITERAL_CSTRING(""));
+}
+
+NS_IMETHODIMP
+nsMsgIncomingServer::GetSortOrder(int32_t* aSortOrder)
+{
+ NS_ENSURE_ARG_POINTER(aSortOrder);
+ *aSortOrder = 100000000;
+return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgIncomingServer::IsAuthentificationByCertificate( bool *_retval)
+{
+ *_retval = false;
+ nsresult rv;
+ nsAutoCString prefAuthCert;
+ nsCOMPtr<nsIMsgAccountManager> accountManager =
+ do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+
+ nsCOMPtr<nsIPrefBranch> prefBranch = do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ nsCOMPtr<nsIMsgIdentity> identity;
+ rv = accountManager->GetFirstIdentityForServer(this, getter_AddRefs(identity));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ nsCString idKey;
+
+ if (NS_SUCCEEDED(rv) && identity)
+ {
+ rv = GetKey(idKey);
+ }
+
+ if(NS_SUCCEEDED(rv))
+ {
+ prefAuthCert.Append("mail.server.");
+ prefAuthCert.Append(idKey);
+ prefAuthCert.Append(".authByCert");
+ rv = prefBranch->GetBoolPref(prefAuthCert.get(),_retval);
+ if(NS_FAILED(rv))
+ {
+ *_retval=false;
+ prefBranch->SetBoolPref(prefAuthCert.get(),false);
+ }
+ }
+
+ return NS_OK;
+}
+
--- /dev/null
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+# These extensions are not optional.
+PARALLEL_DIRS += [
+ 'dsn',
+ 'mdn',
+ 'mailviews/public',
+ 'mailviews/src',
+ 'mailviews/content',
+ 'bayesian-spam-filter',
+ 'offline-startup',
+ 'newsblog',
+ 'fts3/public',
+ 'fts3/src',
+]
+
+if CONFIG['MOZ_PSM']:
+ PARALLEL_DIRS += ['smime']
+
--- /dev/null
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH = @DEPTH@
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+LIBRARY_NAME = msgsmime
+EXPORT_LIBRARY = 1
+IS_COMPONENT = 1
+MODULE_NAME = nsMsgSMIMEModule
+ifndef MOZ_INCOMPLETE_EXTERNAL_LINKAGE
+MOZILLA_INTERNAL_API = 1
+LIBXUL_LIBRARY = 1
+endif
+
+
+LOCAL_INCLUDES += -I$(srcdir)/../src
+
+SHARED_LIBRARY_LIBS = \
+ ../src/$(LIB_PREFIX)msgsmime_s.$(LIB_SUFFIX) \
+ $(NULL)
+
+ifdef MOZILLA_INTERNAL_API
+EXTRA_DSO_LDOPTS = \
+ $(LIBS_DIR) \
+ $(EXTRA_DSO_LIBS) \
+ $(MOZ_COMPONENT_LIBS) \
+ $(NULL)
+else
+EXTRA_DSO_LDOPTS = \
+ $(LIBS_DIR) \
+ $(EXTRA_DSO_LIBS) \
+ $(XPCOM_GLUE_LDOPTS) \
+ $(NSPR_LIBS) \
+ $(NULL)
+endif
+
+include $(topsrcdir)/config/rules.mk
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Contributor(s):
+ * Scott MacGregor <mscott@netscape.com>
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */
+
+#include "mozilla/ModuleUtils.h"
+#include "nsISupports.h"
+#include "nsCOMPtr.h"
+
+#include "nsIFactory.h"
+#include "nsIServiceManager.h"
+#include "nsIModule.h"
+
+#include "pratom.h"
+#include "nsMsgSMIMECID.h"
+#include "nsMsgCompCID.h"
+
+/* Include all of the interfaces our factory can generate components for */
+#include "nsMsgComposeSecure.h"
+#include "nsSMimeJSHelper.h"
+#include "nsEncryptedSMIMEURIsService.h"
+#include "nsMsgSMIMEReceiptGenerator.h"
+
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgComposeSecure)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgSMIMEComposeFields)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsSMimeJSHelper)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsEncryptedSMIMEURIsService)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgSMIMEReceiptGenerator)
+NS_GENERIC_FACTORY_CONSTRUCTOR(nsMsgSMIMESecureHeader)
+
+NS_DEFINE_NAMED_CID(NS_MSGCOMPOSESECURE_CID);
+NS_DEFINE_NAMED_CID(NS_MSGSMIMECOMPFIELDS_CID);
+NS_DEFINE_NAMED_CID(NS_SMIMEJSJELPER_CID);
+NS_DEFINE_NAMED_CID(NS_SMIMEENCRYPTURISERVICE_CID);
+NS_DEFINE_NAMED_CID(NS_SMIMERECEIPT_GENERATOR_CID);
+NS_DEFINE_NAMED_CID(NS_SMIMESECUREHEADER_CID);
+
+const mozilla::Module::CIDEntry kMsgSMIMECIDs[] = {
+ { &kNS_MSGCOMPOSESECURE_CID, false, NULL, nsMsgComposeSecureConstructor },
+ { &kNS_MSGSMIMECOMPFIELDS_CID, false, NULL, nsMsgSMIMEComposeFieldsConstructor },
+ { &kNS_SMIMEJSJELPER_CID, false, NULL, nsSMimeJSHelperConstructor },
+ { &kNS_SMIMEENCRYPTURISERVICE_CID, false, NULL, nsEncryptedSMIMEURIsServiceConstructor },
+ { &kNS_SMIMERECEIPT_GENERATOR_CID, false, NULL, nsMsgSMIMEReceiptGeneratorConstructor },
+ { &kNS_SMIMESECUREHEADER_CID, false, NULL, nsMsgSMIMESecureHeaderConstructor },
+ { NULL }
+};
+
+const mozilla::Module::ContractIDEntry kMsgSMIMEContracts[] = {
+ { NS_MSGCOMPOSESECURE_CONTRACTID, &kNS_MSGCOMPOSESECURE_CID },
+ { NS_MSGSMIMECOMPFIELDS_CONTRACTID, &kNS_MSGSMIMECOMPFIELDS_CID },
+ { NS_SMIMEJSHELPER_CONTRACTID, &kNS_SMIMEJSJELPER_CID },
+ { NS_SMIMEENCRYPTURISERVICE_CONTRACTID, &kNS_SMIMEENCRYPTURISERVICE_CID },
+ { NS_SMIMESECUREHEADER_CONTRACTID, &kNS_SMIMESECUREHEADER_CID },
+ { NS_SMIMERECEIPT_GENERATOR_CONTRACTID, &kNS_SMIMERECEIPT_GENERATOR_CID},
+ { NULL }
+};
+
+/////////////////////////////////////////////////////////////////////////////
+//
+/////////////////////////////////////////////////////////////////////////////
+
+static const mozilla::Module kMsgSMIMEModule = {
+ mozilla::Module::kVersion,
+ kMsgSMIMECIDs,
+ kMsgSMIMEContracts
+};
+
+NSMODULE_DEFN(nsMsgSMIMEModule) = &kMsgSMIMEModule;
--- /dev/null
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+const nsIX509CertDB = Components.interfaces.nsIX509CertDB;
+const nsX509CertDBContractID = "@mozilla.org/security/x509certdb;1";
+const nsIX509Cert = Components.interfaces.nsIX509Cert;
+
+const email_recipient_cert_usage = 5;
+const email_signing_cert_usage = 4;
+
+var gIdentity;
+var gPref = null;
+var gEncryptionCertName = null;
+var gHiddenEncryptionPolicy = null;
+var gEncryptionChoices = null;
+var gSignCertName = null;
+var gSignMessages = null;
+var gEncryptAlways = null;
+var gNeverEncrypt = null;
+var gSMIMEReceiptRequest = null;
+var gSMIMEReceiptSendPolicy = null;
+var gBundle = null;
+var gBrandBundle;
+var gSmimePrefbranch;
+var gEncryptionChoicesLocked;
+var gSigningChoicesLocked;
+const kEncryptionCertPref = "identity.encryption_cert_name";
+const kSigningCertPref = "identity.signing_cert_name";
+
+function onInit()
+{
+ smimeInitializeFields();
+ secureHeadersInitialize();
+}
+
+function smimeInitializeFields()
+{
+ // initialize all of our elements based on the current identity values....
+ gEncryptionCertName = document.getElementById(kEncryptionCertPref);
+ gHiddenEncryptionPolicy = document.getElementById("identity.encryptionpolicy");
+ gEncryptionChoices = document.getElementById("encryptionChoices");
+ gSignCertName = document.getElementById(kSigningCertPref);
+ gSignMessages = document.getElementById("identity.sign_mail");
+ gEncryptAlways = document.getElementById("encrypt_mail_always");
+ gNeverEncrypt = document.getElementById("encrypt_mail_never");
+ gSMIMEReceiptRequest = document.getElementById("identity.smime_receipt_request");
+ gSMIMEReceiptSendPolicy = document.getElementById("identity.smime_receipt_send_policy");
+ gBundle = document.getElementById("bundle_smime");
+ gBrandBundle = document.getElementById("bundle_brand");
+
+ gEncryptionChoicesLocked = false;
+ gSigningChoicesLocked = false;
+
+ if (!gIdentity) {
+ // The user is going to create a new identity.
+ // Set everything to default values.
+ // Do not take over the values from gAccount.defaultIdentity
+ // as the new identity is going to have a different mail address.
+
+ gEncryptionCertName.value = "";
+ gSignCertName.value = "";
+
+ gEncryptAlways.setAttribute("disabled", true);
+ gNeverEncrypt.setAttribute("disabled", true);
+ gSignMessages.setAttribute("disabled", true);
+ gSMIMEReceiptRequest.setAttribute("disabled", true);
+ gSMIMEReceiptSendPolicy.setAttribute("disabled", true);
+
+ gSignMessages.checked = false;
+ gEncryptionChoices.value = 0;
+
+ gSMIMEReceiptRequest.checked = false;
+ gSMIMEReceiptSendPolicy.value = 0;
+ }
+ else {
+ gEncryptionCertName.value = gIdentity.getUnicharAttribute("encryption_cert_name");
+
+ gEncryptionChoices.value = gIdentity.getIntAttribute("encryptionpolicy");
+
+ if (!gEncryptionCertName.value) {
+ gEncryptAlways.setAttribute("disabled", true);
+ gNeverEncrypt.setAttribute("disabled", true);
+ }
+ else {
+ enableEncryptionControls(true);
+ }
+
+ gSignCertName.value = gIdentity.getUnicharAttribute("signing_cert_name");
+ gSignMessages.checked = gIdentity.getBoolAttribute("sign_mail");
+ gSMIMEReceiptRequest.checked = gIdentity.getBoolAttribute("smime_receipt_request");
+ gSMIMEReceiptSendPolicy.value = gIdentity.getIntAttribute("smime_receipt_send_policy");
+ if (!gSignCertName.value)
+ {
+ gSignMessages.setAttribute("disabled", true);
+ gSMIMEReceiptRequest.setAttribute("disabled", true);
+ gSMIMEReceiptSendPolicy.setAttribute("disabled", true);
+ }
+ else {
+ enableSigningControls(true);
+ }
+ }
+
+ // Always start with enabling signing and encryption cert select buttons.
+ // This will keep the visibility of buttons in a sane state as user
+ // jumps from security panel of one account to another.
+ enableCertSelectButtons();
+
+ // Disable all locked elements on the panel
+ if (gIdentity)
+ onLockPreference();
+}
+
+function onPreInit(account, accountValues)
+{
+ gIdentity = account.defaultIdentity;
+}
+
+function onSave()
+{
+ smimeSave();
+ secureHeadersSave();
+}
+
+function smimeSave()
+{
+ // find out which radio for the encryption radio group is selected and set that on our hidden encryptionChoice pref....
+ var newValue = gEncryptionChoices.value;
+ gHiddenEncryptionPolicy.setAttribute('value', newValue);
+ gIdentity.setIntAttribute("encryptionpolicy", newValue);
+ gIdentity.setUnicharAttribute("encryption_cert_name", gEncryptionCertName.value);
+
+ gIdentity.setBoolAttribute("sign_mail", gSignMessages.checked);
+ gIdentity.setUnicharAttribute("signing_cert_name", gSignCertName.value);
+
+ gIdentity.setBoolAttribute("smime_receipt_request", gSMIMEReceiptRequest.checked);
+ gIdentity.setIntAttribute("smime_receipt_send_policy", gSMIMEReceiptSendPolicy.value);
+}
+
+function smimeOnAcceptEditor()
+{
+ try {
+ if (!onOk())
+ return false;
+ }
+ catch (ex) {}
+
+ smimeSave();
+
+ return true;
+}
+
+function onLockPreference()
+{
+ var initPrefString = "mail.identity";
+ var finalPrefString;
+
+ var allPrefElements = [
+ { prefstring:"signingCertSelectButton", id:"signingCertSelectButton"},
+ { prefstring:"encryptionCertSelectButton", id:"encryptionCertSelectButton"},
+ { prefstring:"sign_mail", id:"identity.sign_mail"},
+ { prefstring:"encryptionpolicy", id:"encryptionChoices"}
+ ];
+
+ finalPrefString = initPrefString + "." + gIdentity.key + ".";
+ gSmimePrefbranch = Services.prefs.getBranch(finalPrefString);
+
+ disableIfLocked( allPrefElements );
+}
+
+
+// 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 )
+{
+ var i;
+ for (i=0; i<prefstrArray.length; i++) {
+ var id = prefstrArray[i].id;
+ var element = document.getElementById(id);
+ if (gSmimePrefbranch.prefIsLocked(prefstrArray[i].prefstring)) {
+ // If encryption choices radio group is locked, make sure the individual
+ // choices in the group are locked. Set a global (gEncryptionChoicesLocked)
+ // indicating the status so that locking can be maintained further.
+ if (id == "encryptionChoices") {
+ document.getElementById("encrypt_mail_never").setAttribute("disabled", "true");
+ document.getElementById("encrypt_mail_always").setAttribute("disabled", "true");
+ gEncryptionChoicesLocked = true;
+ }
+ // If option to sign mail is locked (with true/false set in config file), disable
+ // the corresponding checkbox and set a global (gSigningChoicesLocked) in order to
+ // honor the locking as user changes other elements on the panel.
+ if (id == "identity.sign_mail") {
+ document.getElementById("identity.sign_mail").setAttribute("disabled", "true");
+ gSigningChoicesLocked = true;
+ }
+ else {
+ element.setAttribute("disabled", "true");
+ if (id == "signingCertSelectButton") {
+ document.getElementById("signingCertClearButton").setAttribute("disabled", "true");
+ }
+ else if (id == "encryptionCertSelectButton") {
+ document.getElementById("encryptionCertClearButton").setAttribute("disabled", "true");
+ }
+ }
+ }
+ }
+}
+
+function alertUser(message)
+{
+ Services.prompt.alert(window,
+ gBrandBundle.getString("brandShortName"),
+ message);
+}
+
+function askUser(message)
+{
+ let button = Services.prompt.confirmEx(
+ window,
+ gBrandBundle.getString("brandShortName"),
+ message,
+ Services.prompt.STD_YES_NO_BUTTONS,
+ null,
+ null,
+ null,
+ null,
+ {});
+ // confirmEx returns button index:
+ return (button == 0);
+}
+
+function checkOtherCert(nickname, pref, usage, msgNeedCertWantSame, msgWantSame, msgNeedCertWantToSelect, enabler)
+{
+ var otherCertInfo = document.getElementById(pref);
+ if (!otherCertInfo)
+ return;
+
+ if (otherCertInfo.value == nickname)
+ // all is fine, same cert is now selected for both purposes
+ return;
+
+ var certdb = Components.classes[nsX509CertDBContractID].getService(nsIX509CertDB);
+ if (!certdb)
+ return;
+
+ if (email_recipient_cert_usage == usage) {
+ matchingOtherCert = certdb.findEmailEncryptionCert(nickname);
+ }
+ else if (email_signing_cert_usage == usage) {
+ matchingOtherCert = certdb.findEmailSigningCert(nickname);
+ }
+ else
+ return;
+
+ var userWantsSameCert = false;
+
+ if (!otherCertInfo.value.length) {
+ if (matchingOtherCert) {
+ userWantsSameCert = askUser(gBundle.getString(msgNeedCertWantSame));
+ }
+ else {
+ if (askUser(gBundle.getString(msgNeedCertWantToSelect))) {
+ smimeSelectCert(pref);
+ }
+ }
+ }
+ else {
+ if (matchingOtherCert) {
+ userWantsSameCert = askUser(gBundle.getString(msgWantSame));
+ }
+ }
+
+ if (userWantsSameCert) {
+ otherCertInfo.value = nickname;
+ enabler(true);
+ }
+}
+
+function smimeSelectCert(smime_cert)
+{
+ var certInfo = document.getElementById(smime_cert);
+ if (!certInfo)
+ return;
+
+ var picker = Components.classes["@mozilla.org/user_cert_picker;1"]
+ .createInstance(Components.interfaces.nsIUserCertPicker);
+ var canceled = new Object;
+ var x509cert = 0;
+ var certUsage;
+ var selectEncryptionCert;
+
+ if (smime_cert == kEncryptionCertPref) {
+ selectEncryptionCert = true;
+ certUsage = email_recipient_cert_usage;
+ } else if (smime_cert == kSigningCertPref) {
+ selectEncryptionCert = false;
+ certUsage = email_signing_cert_usage;
+ }
+
+ try {
+ x509cert = picker.pickByUsage(window,
+ certInfo.value,
+ certUsage, // this is from enum SECCertUsage
+ false, false, canceled);
+ } catch(e) {
+ canceled.value = false;
+ x509cert = null;
+ }
+
+ if (!canceled.value) {
+ if (!x509cert) {
+ var errorString;
+ if (selectEncryptionCert) {
+ errorString = "NoEncryptionCert";
+ }
+ else {
+ errorString = "NoSigningCert";
+ }
+ alertUser(gBundle.getString(errorString));
+ }
+ else {
+ certInfo.removeAttribute("disabled");
+ certInfo.value = x509cert.nickname;
+
+ if (selectEncryptionCert) {
+ enableEncryptionControls(true);
+
+ checkOtherCert(certInfo.value,
+ kSigningCertPref, email_signing_cert_usage,
+ "signing_needCertWantSame",
+ "signing_wantSame",
+ "signing_needCertWantToSelect",
+ enableSigningControls);
+ } else {
+ enableSigningControls(true);
+
+ checkOtherCert(certInfo.value,
+ kEncryptionCertPref, email_recipient_cert_usage,
+ "encryption_needCertWantSame",
+ "encryption_wantSame",
+ "encryption_needCertWantToSelect",
+ enableEncryptionControls);
+ }
+ }
+ }
+
+ enableCertSelectButtons();
+}
+
+function enableEncryptionControls(do_enable)
+{
+ if (gEncryptionChoicesLocked)
+ return;
+
+ if (do_enable) {
+ gEncryptAlways.removeAttribute("disabled");
+ gNeverEncrypt.removeAttribute("disabled");
+ }
+ else {
+ gEncryptAlways.setAttribute("disabled", "true");
+ gNeverEncrypt.setAttribute("disabled", "true");
+ gEncryptionChoices.value = 0;
+ }
+}
+
+function enableSigningControls(do_enable)
+{
+ if (gSigningChoicesLocked)
+ return;
+
+ if (do_enable) {
+ gSignMessages.removeAttribute("disabled");
+
+ gSMIMEReceiptRequest.removeAttribute("disabled");
+ gSMIMEReceiptSendPolicy.removeAttribute("disabled");
+ }
+ else {
+ gSignMessages.setAttribute("disabled", "true");
+ gSignMessages.checked = false;
+
+ gSMIMEReceiptRequest.setAttribute("disabled", "true");
+ gSMIMEReceiptRequest.checked = false;
+ gSMIMEReceiptSendPolicy.setAttribute("disabled", "true");
+ gSMIMEReceiptSendPolicy.value = 0;
+ }
+}
+
+function enableCertSelectButtons()
+{
+ document.getElementById("signingCertSelectButton").removeAttribute("disabled");
+
+ if (document.getElementById('identity.signing_cert_name').value.length)
+ document.getElementById("signingCertClearButton").removeAttribute("disabled");
+ else
+ document.getElementById("signingCertClearButton").setAttribute("disabled", "true");
+
+ document.getElementById("encryptionCertSelectButton").removeAttribute("disabled");
+
+ if (document.getElementById('identity.encryption_cert_name').value.length)
+ document.getElementById("encryptionCertClearButton").removeAttribute("disabled");
+ else
+ document.getElementById("encryptionCertClearButton").setAttribute("disabled", "true");
+}
+
+function smimeClearCert(smime_cert)
+{
+ var certInfo = document.getElementById(smime_cert);
+ if (!certInfo)
+ return;
+
+ certInfo.setAttribute("disabled", "true");
+ certInfo.value = "";
+
+ if (smime_cert == kEncryptionCertPref) {
+ enableEncryptionControls(false);
+ } else if (smime_cert == kSigningCertPref) {
+ enableSigningControls(false);
+ }
+
+ enableCertSelectButtons();
+}
+
+function openCertManager()
+{
+ // Check for an existing certManager window and focus it; it's not
+ // application modal.
+ let lastCertManager = Services.wm.getMostRecentWindow("mozilla:certmanager");
+ if (lastCertManager)
+ lastCertManager.focus();
+ else
+ window.openDialog("chrome://pippki/content/certManager.xul", "",
+ "centerscreen,resizable=yes,dialog=no");
+}
+
+function openDeviceManager()
+{
+ // Check for an existing deviceManager window and focus it; it's not
+ // application modal.
+ let lastCertManager = Services.wm.getMostRecentWindow("mozilla:devicemanager");
+ if (lastCertManager)
+ lastCertManager.focus();
+ else
+ window.openDialog("chrome://pippki/content/device_manager.xul", "",
+ "centerscreen,resizable=yes,dialog=no");
+}
+
+function smimeOnLoadEditor()
+{
+ smimeInitializeFields();
+
+ document.documentElement.setAttribute("ondialogaccept",
+ "return smimeOnAcceptEditor();");
+}
+/**
+ * OnInit() : Secureheaders process
+ */
+const PREF_SECUREHEADERS_FOLDER_DATAS = "secureheaders.folderdata";
+const DEFAULT_SECUREHEADERS_XML_DIR = "secureHeaders"
+const PREF_SECUREHEADERS_SMIMEINFO = "secureheaders.smimeinfomsg";
+const DEFAULT_SECUREHEADERS_XML_FILE = "secureHeadersDefault.xml";
+function secureHeadersInitialize() {
+ /* Get profile directory */
+ var dirSecureHeader = Components.classes["@mozilla.org/file/directory_service;1"].createInstance(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
+ dirSecureHeader.append("secureHeaders");
+
+ /* Copy a default profile if needed */
+ if (!dirSecureHeader.exists()) {
+ dirSecureHeader.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+ var defaultFile = Components.classes["@mozilla.org/file/directory_service;1"].createInstance(Components.interfaces.nsIProperties).get("ProfDefNoLoc", Components.interfaces.nsIFile);
+ defaultFile.append("secureHeadersDefault.xml");
+ if (defaultFile.exists())
+ defaultFile.copyTo(dirSecureHeader, "secureHeadersDefault.xml");
+ }
+
+ var currentFolderTextBox = document.getElementById("secureheaders.xmlPath");
+ if(currentFolderTextBox.value==""){
+ var pref_data = gIdentity.getCharAttribute(PREF_SECUREHEADERS_FOLDER_DATAS) ;
+ if(pref_data){
+ currentFolderTextBox.value = pref_data;
+ }else{
+ //
+ var file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
+ file.append(DEFAULT_SECUREHEADERS_XML_DIR);
+ file.append(DEFAULT_SECUREHEADERS_XML_FILE);
+ //
+ var currentFolderTextBox = document.getElementById("secureheaders.xmlPath");
+ currentFolderTextBox.value = file.path;
+ //currentFolderTextBox.value = file.path + DEFAULT_SECUREHEADERS_XML_DIR+DEFAULT_SECUREHEADERS_XML_FILE;
+ gIdentity.setCharAttribute(PREF_SECUREHEADERS_FOLDER_DATAS,currentFolderTextBox.value);
+ }
+ }
+
+ if(gIdentity.getBoolAttribute(PREF_SECUREHEADERS_SMIMEINFO)){
+ document.getElementById("smimeinfomsgcheck").setAttribute("checked", "true");
+ }else{
+ document.getElementById("smimeinfomsgcheck").setAttribute("checked", "false");
+ }
+}
+function secureHeadersSave() {
+ // save secure headers selection to preferences
+ var currentFolderTextBox = document.getElementById("secureheaders.xmlPath");
+ gIdentity.setCharAttribute(PREF_SECUREHEADERS_FOLDER_DATAS,currentFolderTextBox.value);
+ if(document.getElementById("smimeinfomsgcheck").getAttribute("checked") == "true"){
+ gIdentity.setBoolAttribute(PREF_SECUREHEADERS_SMIMEINFO,true);
+ }else{
+ gIdentity.setBoolAttribute(PREF_SECUREHEADERS_SMIMEINFO,false);
+ }
+}
+/**
+ * Secure-headers : browser to select file
+ */
+function BrowseForXmlFile() {
+ var nsIFilePicker = Components.interfaces.nsIFilePicker;
+ var fp = Components.classes["@mozilla.org/filepicker;1"].createInstance(nsIFilePicker);
+ var currentFolder = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ var currentFolderTextBox = document.getElementById("secureheaders.xmlPath");
+
+ if(currentFolderTextBox.value!=""){
+ currentFolder.initWithPath(currentFolderTextBox.value);
+ }else{
+ // var extensionPath = getFilePathInProfile(DEFAULT_SECUREHEADERS_XML_RELATIVE_DIR);
+ var dirProfile = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);
+ dirProfile.append(DEFAULT_SECUREHEADERS_XML_DIR);
+ currentFolder.initWithPath(dirProfile.path);
+ }
+ //fp.init(window, document.getElementById("browseForXmlFolder").getAttribute("filepickertitle"), nsIFilePicker.modeOpen);
+ //fp.appendFilters(nsIFilePicker.filterXML);
+ fp.init(window, document.getElementById("browseForXmlFolder").getAttribute("filepickertitle"), nsIFilePicker.modeOpen);
+ fp.displayDirectory = currentFolder;
+
+ var ret = fp.show();
+ if (ret == nsIFilePicker.returnOK)
+ {
+ // convert the nsILocalFile into a nsIFileSpec
+ currentFolderTextBox.value = fp.file.path;
+ }
+ }
--- /dev/null
+<?xml version="1.0"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<?xml-stylesheet href="chrome://messenger/skin/accountManage.css"
+ type="text/css"?>
+
+<!DOCTYPE overlay SYSTEM "chrome://messenger/locale/am-smime.dtd">
+
+<overlay xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <vbox id="smimeEditing">
+
+ <stringbundleset>
+ <stringbundle id="bundle_smime" src="chrome://messenger/locale/am-smime.properties"/>
+ <stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
+ </stringbundleset>
+
+ <label hidden="true" wsm_persist="true" id="identity.encryptionpolicy"/>
+
+ <description>&securityHeading.label;</description>
+
+ <groupbox id="signing.titlebox">
+ <caption label="&signingGroupTitle.label;"/>
+
+ <label value="&signingCert.message;" control="identity.signing_cert_name"
+ prefstring="mail.identity.%identitykey%.encryptionpolicy"/>
+
+ <hbox align="center">
+ <textbox id="identity.signing_cert_name" wsm_persist="true" flex="1"
+ prefstring="mail.identity.%identitykey%.signing_cert_name"
+ readonly="true" disabled="true"/>
+
+ <button id="signingCertSelectButton"
+ label="&digitalSign.certificate.button;"
+ accesskey="&digitalSign.certificate.accesskey;"
+ oncommand="smimeSelectCert('identity.signing_cert_name')"/>
+
+ <button id="signingCertClearButton"
+ label="&digitalSign.certificate_clear.button;"
+ accesskey="&digitalSign.certificate_clear.accesskey;"
+ oncommand="smimeClearCert('identity.signing_cert_name')"/>
+ </hbox>
+
+ <separator class="thin"/>
+
+ <checkbox id="identity.sign_mail" wsm_persist="true"
+ prefstring="mail.identity.%identitykey%.sign_mail"
+ label="&signMessage.label;" accesskey="&signMessage.accesskey;"/>
+
+ <checkbox id="identity.smime_receipt_request" wsm_persist="true"
+ prefstring="mail.identity.%identitykey%.smime_receipt_request"
+ label="&SMIMEReceiptRequest.label;" accesskey="&SMIMEReceiptRequest.accesskey;"/>
+
+ <hbox align="center">
+ <label id="SMIMEReceiptSendPolicyLabel" value="&SMIMEReceiptSendPolicy.label;"
+ control="identity.smime_receipt_send_policy" accesskey="&SMIMEReceiptSendPolicy.accesskey;"/>
+
+ <menulist id="identity.smime_receipt_send_policy" wsm_persist="true">
+ <menupopup>
+ <menuitem value="1" label="&SMIMEReceiptSendPolicy.neverSend.label;"/>
+ <menuitem value="2" label="&SMIMEReceiptSendPolicy.alwaysSend.label;"/>
+ <menuitem value="0" label="&SMIMEReceiptSendPolicy.askMe.label;"/>
+ </menupopup>
+ </menulist>
+ </hbox>
+ <!-- Secure Headers -->
+ <label value="&secureHeaderPath.label;"/>
+ <hbox align="center">
+ <textbox readonly="true" wsm_persist="true" flex="1" id="secureheaders.xmlPath" datatype="nsIFileSpec"
+ prefstring="mail.server.%serverkey%.secureheaders.directory" value=""/>
+ <button id="browseForXmlFolder" label="&browseFolder.label;" filepickertitle="&secureHeaderFolderPicker.label;"
+ accesskey="&browseFolder.accesskey;" oncommand="BrowseForXmlFile()"/>
+ </hbox>
+ <checkbox id="smimeinfomsgcheck" label="&smime.am.infomsg.label;" checked="true"/>
+ </groupbox>
+
+ <groupbox id="encryption.titlebox">
+ <caption label="&encryptionGroupTitle.label;"/>
+
+ <label value="&encryptionCert.message;"
+ control="identity.encryption_cert_name"/>
+
+ <hbox align="center">
+ <textbox id="identity.encryption_cert_name" wsm_persist="true" flex="1"
+ prefstring="mail.identity.%identitykey%.encryption_cert_name"
+ readonly="true" disabled="true"/>
+
+ <button id="encryptionCertSelectButton"
+ label="&encryption.certificate.button;"
+ accesskey="&encryption.certificate.accesskey;"
+ oncommand="smimeSelectCert('identity.encryption_cert_name')"/>
+
+ <button id="encryptionCertClearButton"
+ label="&encryption.certificate_clear.button;"
+ accesskey="&encryption.certificate_clear.accesskey;"
+ oncommand="smimeClearCert('identity.encryption_cert_name')"/>
+ </hbox>
+
+ <separator class="thin"/>
+
+ <label value="&encryptionChoiceLabel.label;" control="encryptionChoices"/>
+
+ <radiogroup id="encryptionChoices">
+ <radio id="encrypt_mail_never" wsm_persist="true" value="0"
+ label="&neverEncrypt.label;"
+ accesskey="&neverEncrypt.accesskey;"/>
+
+ <radio id="encrypt_mail_always" wsm_persist="true" value="2"
+ label="&alwaysEncryptMessage.label;"
+ accesskey="&alwaysEncryptMessage.accesskey;"/>
+ </radiogroup>
+ </groupbox>
+
+ <!-- Certificate manager -->
+ <groupbox id="smimeCertificateManager" orient="horizontal">
+ <caption label="&certificates.label;"/>
+ <button id="openCertManagerButton" oncommand="openCertManager();"
+ label="&manageCerts.label;" accesskey="&manageCerts.accesskey;"
+ prefstring="security.disable_button.openCertManager"/>
+ <button id="openDeviceManagerButton" oncommand="openDeviceManager();"
+ label="&manageDevices.label;" accesskey="&manageDevices.accesskey;"
+ prefstring="security.disable_button.openDeviceManager"/>
+ </groupbox>
+ </vbox>
+</overlay>
--- /dev/null
+/* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * ddrinan@netscape.com
+ * Scott MacGregor <mscott@netscape.com>
+ * Copyright(c) 2011 CASSIDIAN - All rights reserved
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+// Account encryption policy values:
+// const kEncryptionPolicy_Never = 0;
+// 'IfPossible' was used by ns4.
+// const kEncryptionPolicy_IfPossible = 1;
+const kEncryptionPolicy_Always = 2;
+
+var gEncryptedURIService =
+ Components.classes["@mozilla.org/messenger-smime/smime-encrypted-uris-service;1"]
+ .getService(Components.interfaces.nsIEncryptedSMIMEURIsService);
+
+var gNextSecurityButtonCommand = "";
+var gSMFields = null;
+
+var gEncryptOptionChanged;
+var gSignOptionChanged;
+
+var gSecurityLabelConf = null;
+
+function onComposerClose()
+{
+ gSMFields = null;
+ setNoEncryptionUI();
+ setNoSignatureUI();
+ setSecurityLabelStatusBarUI();
+ setNoSecureHeaderUI();
+
+ if (!gMsgCompose || !gMsgCompose.compFields)
+ return;
+
+ gMsgCompose.compFields.securityInfo = null;
+}
+
+function onComposerReOpen()
+{
+ // Are we already set up ? Or are the required fields missing ?
+ if (gSMFields || !gMsgCompose || !gMsgCompose.compFields)
+ return;
+
+ gMsgCompose.compFields.securityInfo = null;
+
+ gSMFields = Components.classes["@mozilla.org/messenger-smime/composefields;1"]
+ .createInstance(Components.interfaces.nsIMsgSMIMECompFields);
+ if (!gSMFields)
+ return;
+
+ gMsgCompose.compFields.securityInfo = gSMFields;
+
+ // Set up the intial security state.
+ gSMFields.requireEncryptMessage =
+ gCurrentIdentity.getIntAttribute("encryptionpolicy") == kEncryptionPolicy_Always;
+ if (!gSMFields.requireEncryptMessage &&
+ gEncryptedURIService &&
+ gEncryptedURIService.isEncrypted(gMsgCompose.originalMsgURI))
+ {
+ // Override encryption setting if original is known as encrypted.
+ gSMFields.requireEncryptMessage = true;
+ }
+ if (gSMFields.requireEncryptMessage)
+ setEncryptionUI();
+ else
+ setNoEncryptionUI();
+
+ gSMFields.signMessage = gCurrentIdentity.getBoolAttribute("sign_mail");
+ if (gSMFields.signMessage)
+ setSignatureUI();
+ else
+ setNoSignatureUI();
+
+ if (gSMFields.signMessage)
+ gSMFields.SMIMEReceiptRequest = gCurrentIdentity.getBoolAttribute("smime_receipt_request");
+
+ setSecurityLabelStatusBarUI();
+ setNoSecureHeaderUI();
+}
+
+addEventListener("load", smimeComposeOnLoad, false);
+
+// this function gets called multiple times,
+// but only on first open, not on composer recycling
+function smimeComposeOnLoad()
+{
+ removeEventListener("load", smimeComposeOnLoad, false);
+
+ onComposerReOpen();
+
+ top.controllers.appendController(SecurityController);
+
+ addEventListener("compose-from-changed", onComposerFromChanged, true);
+ addEventListener("compose-send-message", onComposerSendMessage, true);
+ addEventListener("compose-window-close", onComposerClose, true);
+ addEventListener("compose-window-reopen", onComposerReOpen, true);
+
+ addEventListener("unload", smimeComposeOnUnload, false);
+}
+
+function smimeComposeOnUnload()
+{
+ removeEventListener("unload", smimeComposeOnUnload, false);
+
+ removeEventListener("compose-from-changed", onComposerFromChanged, true);
+ removeEventListener("compose-send-message", onComposerSendMessage, true);
+ removeEventListener("compose-window-close", onComposerClose, true);
+ removeEventListener("compose-window-reopen", onComposerReOpen, true);
+
+ top.controllers.removeController(SecurityController);
+}
+
+// stub routine to make our call to MsgAccountManager work correctly
+function GetSelectedFolderURI()
+{
+ return;
+}
+
+function GetServer(uri)
+{
+ var servers = gAccountManager.GetServersForIdentity(gCurrentIdentity);
+ return servers.QueryElementAt(0, Components.interfaces.nsIMsgIncomingServer);
+}
+
+function showNeedSetupInfo()
+{
+ let compSmimeBundle = document.getElementById("bundle_comp_smime");
+ let brandBundle = document.getElementById("bundle_brand");
+ if (!compSmimeBundle || !brandBundle)
+ return;
+
+ let buttonPressed = Services.prompt.confirmEx(window,
+ brandBundle.getString("brandShortName"),
+ compSmimeBundle.getString("NeedSetup"),
+ Services.prompt.STD_YES_NO_BUTTONS, 0, 0, 0, null, {});
+ if (buttonPressed == 0)
+ openHelp("sign-encrypt", "chrome://communicator/locale/help/suitehelp.rdf");
+}
+
+function toggleEncryptMessage()
+{
+ if (!gSMFields)
+ return;
+
+ gSMFields.requireEncryptMessage = !gSMFields.requireEncryptMessage;
+
+ if (gSMFields.requireEncryptMessage)
+ {
+ // Make sure we have a cert.
+ if (!gCurrentIdentity.getUnicharAttribute("encryption_cert_name"))
+ {
+ gSMFields.requireEncryptMessage = false;
+ showNeedSetupInfo();
+ return;
+ }
+
+ setEncryptionUI();
+ }
+ else
+ {
+ setNoEncryptionUI();
+ }
+
+ gEncryptOptionChanged = true;
+}
+
+function toggleSignMessage()
+{
+ if (!gSMFields)
+ return;
+
+ gSMFields.signMessage = !gSMFields.signMessage;
+
+ if (gSMFields.signMessage) // make sure we have a cert name...
+ {
+ if (!gCurrentIdentity.getUnicharAttribute("signing_cert_name"))
+ {
+ gSMFields.signMessage = false;
+ showNeedSetupInfo();
+ return;
+ }
+
+ gSMFields.SMIMEReceiptRequest = gCurrentIdentity.getBoolAttribute("smime_receipt_request");
+
+ setSignatureUI();
+ }
+ else
+ {
+ gSMFields.SMIMEReceiptRequest = false;
+
+ gSMFields.securityPolicyIdentifier = "";
+ setSecurityLabelStatusBarUI();
+ setNoSignatureUI();
+ }
+
+ gSignOptionChanged = true;
+}
+
+function toggleSMIMEReceiptRequest()
+{
+ if (!gSMFields)
+ return;
+
+ gSMFields.SMIMEReceiptRequest = !gSMFields.SMIMEReceiptRequest;
+
+ if (gSMFields.SMIMEReceiptRequest)
+ {
+ var signingCertName = gCurrentIdentity.getUnicharAttribute("signing_cert_name");
+
+ if (!signingCertName)
+ {
+ gSMFields.SMIMEReceiptRequest = false;
+ showNeedSetupInfo();
+ return;
+ }
+
+ // Force signing
+ gSMFields.signMessage = true;
+
+ setSignatureUI();
+ }
+}
+
+function setSecuritySettings(menu_id)
+{
+ if (!gSMFields)
+ return;
+
+ document.getElementById("menu_securityEncryptRequire" + menu_id)
+ .setAttribute("checked", gSMFields.requireEncryptMessage);
+ document.getElementById("menu_securitySign" + menu_id)
+ .setAttribute("checked", gSMFields.signMessage);
+ document.getElementById("menu_securitySMIMEReceiptRequest" + menu_id)
+ .setAttribute("checked", gSMFields.SMIMEReceiptRequest);
+}
+
+function setNextCommand(what)
+{
+ gNextSecurityButtonCommand = what;
+}
+
+function doSecurityButton()
+{
+ var what = gNextSecurityButtonCommand;
+ gNextSecurityButtonCommand = "";
+
+ switch (what)
+ {
+ case "encryptMessage":
+ toggleEncryptMessage();
+ break;
+
+ case "signMessage":
+ toggleSignMessage();
+ break;
+
+ case "SMIMEReceiptRequest":
+ toggleSMIMEReceiptRequest();
+ break;
+
+ case "securityLabelDialog":
+ showSecurityLabelDialog();
+ break;
+ case "secureHeaders":
+ toogleSecureHeaders();
+ break;
+ case "show":
+ default:
+ showMessageComposeSecurityStatus();
+ }
+}
+
+function setNoSignatureUI()
+{
+ top.document.getElementById("securityStatus").removeAttribute("signing");
+ top.document.getElementById("signing-status").collapsed = true;
+ setNoSecureHeaderUI();
+}
+
+function setSignatureUI()
+{
+ top.document.getElementById("securityStatus").setAttribute("signing", "ok");
+ top.document.getElementById("signing-status").collapsed = false;
+}
+
+function setNoEncryptionUI()
+{
+ top.document.getElementById("securityStatus").removeAttribute("crypto");
+ top.document.getElementById("encryption-status").collapsed = true;
+}
+
+function setEncryptionUI()
+{
+ top.document.getElementById("securityStatus").setAttribute("crypto", "ok");
+ top.document.getElementById("encryption-status").collapsed = false;
+}
+
+function showMessageComposeSecurityStatus()
+{
+ Recipients2CompFields(gMsgCompose.compFields);
+
+ var secureHeaderCheck = "false";
+ if ( top.document.getElementById("secureHeaderStatus").hasAttribute("checked")) {
+ secureHeaderCheck = top.document.getElementById("secureHeaderStatus").getAttribute("checked");
+ }
+
+ window.openDialog(
+ "chrome://messenger-smime/content/msgCompSecurityInfo.xul",
+ "",
+ "chrome,modal,resizable,centerscreen",
+ {
+ compFields : gMsgCompose.compFields,
+ subject : GetMsgSubjectElement().value,
+ smFields : gSMFields,
+ isSigningCertAvailable :
+ gCurrentIdentity.getUnicharAttribute("signing_cert_name") != "",
+ isEncryptionCertAvailable :
+ gCurrentIdentity.getUnicharAttribute("encryption_cert_name") != "",
+ isSecureHeaderAvailable : secureHeaderCheck,
+ currentIdentity : gCurrentIdentity
+ }
+ );
+}
+
+var SecurityController =
+{
+ supportsCommand: function(command)
+ {
+ switch (command)
+ {
+ case "cmd_viewSecurityStatus":
+ return true;
+
+ default:
+ return false;
+ }
+ },
+
+ isCommandEnabled: function(command)
+ {
+ switch (command)
+ {
+ case "cmd_viewSecurityStatus":
+ return true;
+
+ default:
+ return false;
+ }
+ }
+};
+
+function onComposerSendMessage()
+{
+ let missingCount = new Object();
+ let emailAddresses = new Object();
+
+ try
+ {
+ if (!gMsgCompose.compFields.securityInfo.requireEncryptMessage)
+ return;
+
+ Components.classes["@mozilla.org/messenger-smime/smimejshelper;1"]
+ .createInstance(Components.interfaces.nsISMimeJSHelper)
+ .getNoCertAddresses(gMsgCompose.compFields,
+ missingCount,
+ emailAddresses);
+ }
+ catch (e)
+ {
+ return;
+ }
+
+ if (missingCount.value > 0)
+ {
+ // The rules here: If the current identity has a directoryServer set, then
+ // use that, otherwise, try the global preference instead.
+
+ let autocompleteDirectory;
+
+ // Does the current identity override the global preference?
+ if (gCurrentIdentity.overrideGlobalPref)
+ {
+ autocompleteDirectory = gCurrentIdentity.directoryServer;
+ }
+ else
+ {
+ // Try the global one
+ if (Services.prefs.getBoolPref("ldap_2.autoComplete.useDirectory"))
+ autocompleteDirectory =
+ Services.prefs.getCharPref("ldap_2.autoComplete.directoryServer");
+ }
+
+ if (autocompleteDirectory)
+ window.openDialog("chrome://messenger-smime/content/certFetchingStatus.xul",
+ "",
+ "chrome,modal,resizable,centerscreen",
+ autocompleteDirectory,
+ emailAddresses.value);
+ }
+}
+
+function onComposerFromChanged()
+{
+ if (!gSMFields)
+ return;
+
+ var encryptionPolicy = gCurrentIdentity.getIntAttribute("encryptionpolicy");
+ var useEncryption = false;
+
+ if (!gEncryptOptionChanged)
+ {
+ // Encryption wasn't manually checked.
+ // Set up the encryption policy from the setting of the new identity.
+
+ // 0 == never, 1 == if possible (ns4), 2 == always encrypt.
+ useEncryption = (encryptionPolicy == kEncryptionPolicy_Always);
+ }
+ else
+ {
+ // The encryption policy was manually checked. That means we can get into
+ // the situation that the new identity doesn't have a cert to encrypt with.
+ // If it doesn't, don't encrypt.
+
+ if (encryptionPolicy != kEncryptionPolicy_Always) // Encrypted (policy unencrypted, manually changed).
+ {
+ // Make sure we have a cert for encryption.
+ useEncryption = !!gCurrentIdentity.getUnicharAttribute("encryption_cert_name");
+ }
+ }
+ gSMFields.requireEncryptMessage = useEncryption;
+ if (useEncryption)
+ setEncryptionUI();
+ else
+ setNoEncryptionUI();
+
+ var signMessage = gCurrentIdentity.getBoolAttribute("sign_mail");
+ var useSigning = false;
+
+ if (!gSignOptionChanged)
+ {
+ // Signing wasn't manually checked.
+ // Set up the signing policy from the setting of the new identity.
+ useSigning = signMessage;
+ }
+ else
+ {
+ useSigning = !!gCurrentIdentity.getUnicharAttribute("signing_cert_name");
+ }
+ gSMFields.signMessage = useSigning;
+ if (useSigning)
+ {
+ gSMFields.SMIMEReceiptRequest = gCurrentIdentity.getBoolAttribute("smime_receipt_request");
+ setSignatureUI();
+ }
+ else
+ {
+ gSMFields.SMIMEReceiptRequest = false;
+ setNoSignatureUI();
+ }
+
+ gSMFields.securityPolicyIdentifier = "";
+ setSecurityLabelStatusBarUI();
+}
+
+/**
+ * Show a dialog to define Security Label settings
+ */
+function showSecurityLabelDialog() {
+ window.openDialog('chrome://messenger-smime/content/msgCompSecurityLabelDialog.xul', '', 'chrome,resizable=yes,titlebar,modal,width=500,height=450');
+
+ /* make sure we have a cert name for signing */
+ if (gSMFields.securityPolicyIdentifier != "")
+ {
+ var signingCertName = gCurrentIdentity.getUnicharAttribute("signing_cert_name");
+ if (!signingCertName)
+ {
+ gSMFields.securityPolicyIdentifier = "";
+ setSecurityLabelStatusBarUI();
+ showNeedSetupInfo();
+ return;
+ }
+
+ // Enable signing if disabled
+ if (!gSMFields.signMessage)
+ toggleSignMessage();
+ }
+
+ setSecurityLabelStatusBarUI();
+}
+
+/**
+ * Display Security Label info in status bar of compose window
+ */
+function setSecurityLabelStatusBarUI() {
+ if (!gSMFields || gSMFields.securityPolicyIdentifier == "") {
+ top.document.getElementById("securityLabel-status").label = "";
+ top.document.getElementById("securityLabel-status").collapsed = true;
+ return;
+ }
+
+ if (!gSecurityLabelConf)
+ gSecurityLabelConf = new securityLabelConf();
+
+ var securityLabelValue = "";
+
+ if (gSMFields.securityClassification != -1)
+ securityLabelValue = gSecurityLabelConf.getSecurityClassificationName(gSMFields.securityPolicyIdentifier, gSMFields.securityClassification) + " ";
+
+ securityLabelValue += "[" + gSecurityLabelConf.getSecurityPolicyIdentifierName(gSMFields.securityPolicyIdentifier) + "]";
+ top.document.getElementById("securityLabel-status").label = securityLabelValue;
+ top.document.getElementById("securityLabel-status").collapsed = false;
+}
+
+/**
+*
+*/
+function toogleSecureHeaders () {
+ if (!gSMFields) {
+ return;
+ }
+ if (document.getElementById("secureHeaderStatus").hasAttribute("checked")) {
+ setNoSecureHeaderUI();
+ } else {
+ setSecureHeaderUI()
+ }
+
+}
+function setNoSecureHeaderUI() {
+ top.document.getElementById("secureHeaderStatus").removeAttribute("checked");
+}
+
+function setSecureHeaderUI() {
+ top.document.getElementById("secureHeaderStatus").setAttribute("checked", "true");
+ if (!gSMFields.signMessage) {
+ toggleSignMessage();
+ }
+}
\ No newline at end of file
--- /dev/null
+<?xml version="1.0"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ - Contributor(s):
+ - David Drinan <ddrinan@netscape.com>
+ - Scott MacGregor <mscott@netscape.com
+ - EADS Defence and Security Systems Copyright 2008 (c) All Rights Reserved
+ - CASSIDIAN 2014 (c) All Rights Reserved
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved -->
+
+<?xml-stylesheet href="chrome://messenger/skin/smime/msgCompSMIMEOverlay.css" type="text/css"?>
+
+<!DOCTYPE overlay SYSTEM "chrome://messenger-smime/locale/msgCompSMIMEOverlay.dtd">
+
+<overlay xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
+
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgCompSMIMEOverlay.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgSecurityLabel.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgCompSMIMESecureHeaders.js"/>
+
+ <window id="msgcomposeWindow">
+ <broadcasterset id="composeBroadcasters">
+ <broadcaster id="securityStatus" crypto="" signing=""/>
+ <broadcaster id="secureHeaderStatus" />
+ </broadcasterset>
+ <observes element="securityStatus" attribute="crypto" />
+ <observes element="securityStatus" attribute="signing" />
+ <stringbundle id="bundle_comp_smime" src="chrome://messenger-smime/locale/msgCompSMIMEOverlay.properties"/>
+ <stringbundle id="bundle_brand" src="chrome://branding/locale/brand.properties"/>
+ </window>
+
+ <menupopup id="optionsMenuPopup"
+ onpopupshowing="setSecuritySettings(1);">
+ <menuseparator id="smimeOptionsSeparator"/>
+
+ <menuitem id="menu_securityEncryptRequire1"
+ type="checkbox"
+ label="&menu_securityEncryptRequire.label;"
+ accesskey="&menu_securityEncryptRequire.accesskey;"
+ oncommand="toggleEncryptMessage();"/>
+ <menuitem id="menu_securitySign1"
+ type="checkbox"
+ label="&menu_securitySign.label;"
+ accesskey="&menu_securitySign.accesskey;"
+ oncommand="toggleSignMessage();"/>
+
+ <menuitem id="menu_securitySMIMEReceiptRequest1"
+ type="checkbox"
+ label="&menu_securitySMIMEReceiptRequest.label;"
+ accesskey="&menu_securitySMIMEReceiptRequest.accesskey;"
+ oncommand="toggleSMIMEReceiptRequest()"/>
+
+ <menuseparator id="menu_securityLabelDialogSeparator1"/>
+ <menuitem id="menu_securityLabelDialog1"
+ label="&menu_securityLabel.label;"
+ accesskey="&menu_securityLabel.accesskey;"
+ oncommand="showSecurityLabelDialog();"/>
+ <menuitem id="menu_securitySecureHeader1"
+ type="checkbox"
+ label="&menu.secureheaders.label;"
+ observes="secureHeaderStatus"
+ oncommand="toogleSecureHeaders();"/>
+</menupopup>
+
+ <toolbarpalette id="MsgComposeToolbarPalette">
+ <toolbarbutton id="button-security"
+ type="menu-button"
+ class="toolbarbutton-1"
+ label="&securityButton.label;"
+ tooltiptext="&securityButton.tooltip;"
+ oncommand="doSecurityButton();">
+ <menupopup onpopupshowing="setSecuritySettings(2);">
+ <menuitem id="menu_securityEncryptRequire2"
+ type="checkbox"
+ label="&menu_securityEncryptRequire.label;"
+ accesskey="&menu_securityEncryptRequire.accesskey;"
+ oncommand="setNextCommand('encryptMessage');"/>
+ <menuitem id="menu_securitySign2"
+ type="checkbox"
+ label="&menu_securitySign.label;"
+ accesskey="&menu_securitySign.accesskey;"
+ oncommand="setNextCommand('signMessage');"/>
+ <menuitem id="menu_securitySMIMEReceiptRequest2"
+ type="checkbox"
+ label="&menu_securitySMIMEReceiptRequest.label;"
+ accesskey="&menu_securitySMIMEReceiptRequest.accesskey;"
+ oncommand="setNextCommand('SMIMEReceiptRequest');"/>
+ <menuseparator id="menu_securityLabelDialogSeparator2"/>
+ <menuitem id="menu_securityLabelDialog2"
+ label="&menu_securityLabel.label;"
+ accesskey="&menu_securityLabel.accesskey;"
+ oncommand="setNextCommand('securityLabelDialog');"/>
+ <menuitem id="menu_securitySecureHeader2"
+ type="checkbox"
+ label="&menu.secureheaders.label;"
+ observes="secureHeaderStatus"
+ oncommand="setNextCommand('secureHeaders');"/>
+ <menuseparator id="smimeToolbarButtonSeparator"/>
+ <menuitem id="menu_securityStatus2"
+ label="&menu_securityStatus.label;"
+ accesskey="&menu_securityStatus.accesskey;"
+ oncommand="setNextCommand('show');"/>
+ </menupopup>
+ </toolbarbutton>
+ </toolbarpalette>
+
+ <statusbar id="status-bar">
+ <statusbarpanel insertbefore="offline-status" class="statusbarpanel-iconic" collapsed="true"
+ id="signing-status" oncommand="showMessageComposeSecurityStatus();"/>
+ <statusbarpanel insertbefore="offline-status" class="statusbarpanel-text" collapsed="true"
+ id="securityLabel-status" onclick="showSecurityLabelDialog();"/>
+ <statusbarpanel insertbefore="offline-status" class="statusbarpanel-iconic" collapsed="true"
+ id="encryption-status" oncommand="showMessageComposeSecurityStatus();"/>
+ </statusbar>
+
+ <commandset id="composeCommands">
+ <command id="cmd_viewSecurityStatus" oncommand="showMessageComposeSecurityStatus();"/>
+ </commandset>
+
+ <menupopup id="menu_View_Popup">
+ <menuseparator id="viewMenuBeforeSecurityStatusSeparator"/>
+ <menuitem id="menu_viewSecurityStatus"
+ label="&menu_viewSecurityStatus.label;"
+ accesskey="&menu_viewSecurityStatus.accesskey;"
+ command="cmd_viewSecurityStatus"/>
+ </menupopup>
+
+</overlay>
--- /dev/null
+ /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-\r
+ * This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.\r
+ * Contributor(s):\r
+ * Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved\r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */\r
+\r
+var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);\r
+\r
+const PREF_SECURE_HEADERS_FOLDER_DATAS="secureheaders.folderdata";\r
+const PREF_DEFAULT_SECUREHEADERS = "secureheaders.bydefault";\r
+const PROPERTIES_URL = "chrome://messenger/locale/secureheaders.properties";\r
+const SECURE_HEADERS_ATTRIBUTE_CHECK="secureheaders.checked";\r
+const HEADER_SEPARATOR=",";\r
+\r
+/*\r
+ * \r
+ */\r
+//document.addEventListener('load', msgCompSMIMEOnLoad, true);\r
+window.addEventListener("compose-window-init", msgCompSMIMEOnLoad, true);\r
+window.addEventListener("compose-window-reopen", msgCompSMIMEOnLoad, true);\r
+function msgCompSMIMEOnLoad() {\r
+ gConsole.logStringMessage("[msgCompSMIMESecureHeaders : msgCompSMIMEOnLoad]");\r
+ \r
+ /* Get profile directory */\r
+ var dirSecureHeader = Components.classes["@mozilla.org/file/directory_service;1"].createInstance(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile);\r
+ dirSecureHeader.append("secureHeaders");\r
+ \r
+ /* Copy a default profile if needed */\r
+ if (!dirSecureHeader.exists()) {\r
+ dirSecureHeader.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);\r
+ var defaultFile = Components.classes["@mozilla.org/file/directory_service;1"].createInstance(Components.interfaces.nsIProperties).get("ProfDefNoLoc", Components.interfaces.nsIFile);\r
+ defaultFile.append("secureHeadersDefault.xml");\r
+ if (defaultFile.exists())\r
+ defaultFile.copyTo(dirSecureHeader, "secureHeadersDefault.xml");\r
+ }\r
+ \r
+ // observer on sending message\r
+ var secureheaders_ObserverSvc = Components.classes["@mozilla.org/observer-service;1"].getService(Components.interfaces.nsIObserverService);\r
+ secureheaders_ObserverSvc.addObserver(secureheaders_OnSend, "mail:composeOnSend", false); \r
+}\r
+\r
+\r
+/*\r
+ * \r
+ */\r
+var secureheaders_OnSend = {\r
+ _ArrayheadersToSign : null,\r
+ observe: function(subject, topic, data) {\r
+ //is HeaderSecure requested\r
+ gConsole.logStringMessage("[msgCompSMIMESecureHeaders : Observe]");\r
+ var elt = document.getElementById("menu_securitySecureHeader1");\r
+ if(elt.hasAttribute("checked")){\r
+ this.AddSecureHeadersArray();\r
+ }\r
+ },\r
+ AddSecureHeadersArray: function(){\r
+ try {\r
+ if (!gMsgCompose.compFields) return;\r
+ if (!gMsgCompose.compFields.securityInfo) return;\r
+ \r
+ var msgSMimeCompFields = gMsgCompose.compFields.securityInfo;\r
+ if(!msgSMimeCompFields){\r
+ gConsole.logStringMessage("[msgCompSMIMESecureHeaders : AddSecureHeadersArray] gMsgCompose.compFields.securityInfo not found");\r
+ return;\r
+ }\r
+ gConsole.logStringMessage("[msgCompSMIMESecureHeaders : AddSecureHeadersArray]");\r
+ \r
+ //clear secure headers\r
+ msgSMimeCompFields.clearSecureHeaders();\r
+\r
+ // get preferences informations to sign\r
+ var arrayHeaderToSign = ReadXmlHeadersToSign();\r
+ \r
+ // relaxed canon algorithm as default value \r
+ msgSMimeCompFields.canonAlgorithme = 1;\r
+ \r
+ if(arrayHeaderToSign){\r
+ var secHeader = null;\r
+ \r
+ for(i=0;i<arrayHeaderToSign.length;++i){ \r
+ if(arrayHeaderToSign[i]._name == "canonalgo"){\r
+ // is canonalgo value\r
+ msgSMimeCompFields.canonAlgorithme = parseInt(arrayHeaderToSign[i]._status,10);\r
+ //gConsole.logStringMessage("[ _secure_headers - AddSecureHeadersArray] canonAlgorithme = " + msgSMimeCompFields.canonAlgorithme);\r
+ }else{ \r
+ // create Header object\r
+ secHeader = Components.classes["@mozilla.org/messenger-smime/smime-secure-header;1"].createInstance(Components.interfaces.nsIMsgSMIMESecureHeader);\r
+ secHeader.headerName=arrayHeaderToSign[i]._name;\r
+ if(arrayHeaderToSign[i]._status!="")\r
+ secHeader.headerStatus=arrayHeaderToSign[i]._status;\r
+ /*if(arrayHeaderToSign[i]._encrypted!="")\r
+ secHeader.headerEncrypted=arrayHeaderToSign[i]._encrypted;*/\r
+ \r
+ // push Header object to array of msgCompFields object\r
+ msgSMimeCompFields.addSecureHeader(secHeader);\r
+ }\r
+ }\r
+ }\r
+ }catch(e){\r
+ gConsole.logStringMessage("[msgCompSMIMESecureHeaders : AddSecureHeadersArray] Error: " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
+ } \r
+};\r
+\r
+/*\r
+ *\r
+ */\r
+var DEFAULT_SECUREHEADERS_XML_DIR = "secureHeaders"\r
+var DEFAULT_SECUREHEADERS_XML_FILE = "secureHeadersDefault.xml"\r
+function ReadXmlHeadersToSign(){\r
+ try{\r
+ //var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);\r
+ \r
+ // get xml file path\r
+ if(!gCurrentIdentity){ \r
+ gConsole.logStringMessage("[msgCompSMIMESecureHeaders : ReadXmlHeadersToSign] no xml files define \n ");\r
+ return;\r
+ }\r
+ var pref_data = gCurrentIdentity.getCharAttribute(PREF_SECURE_HEADERS_FOLDER_DATAS);\r
+ var file = null;\r
+ if(!pref_data){ \r
+ file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile); // get profile folder\r
+ file.append(DEFAULT_SECUREHEADERS_XML_DIR);\r
+ file.append(DEFAULT_SECUREHEADERS_XML_FILE);\r
+ pref_data = file.path;\r
+ }else{\r
+ file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);\r
+ file.initWithPath( pref_data );\r
+ }\r
+ \r
+ if(!file.exists()){\r
+ gConsole.logStringMessage("[msgCompSMIMESecureHeaders : ReadXmlHeadersToSign] Error loading schema file : " + completePath);\r
+ return;\r
+ }\r
+ \r
+ // Get Xml Document parser\r
+ var stream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);\r
+ stream.init(file, -1, -1, Components.interfaces.nsIFileInputStream.CLOSE_ON_EOF);\r
+ var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser);\r
+ var xmlDoc = parser.parseFromStream(stream, null, file.fileSize, "text/xml");\r
+ \r
+ // get datas from file\r
+ var tabSecureHeaders = new Array; // tabHeaders[headerName][status][encrypted]\r
+ var compatibleTag = xmlDoc.getElementsByTagName("ximf:headers");\r
+ var sValue="";\r
+ \r
+ if(compatibleTag.length>0){\r
+ // get canonical algorithm\r
+ if(compatibleTag[0].hasAttribute("canonalgo")){\r
+ var canonalgo = compatibleTag[0].getAttribute("canonalgo"); \r
+ tabSecureHeaders.push(new xSecureHeader("canonalgo", canonalgo));\r
+ //gConsole.logStringMessage("[msgCompSMIMESecureHeaders : ReadXmlHeadersToSign] get canonical algorithm : " + canonalgo);\r
+ }\r
+ \r
+ // get headers to sign\r
+ var childNodes = compatibleTag[0].childNodes;\r
+ for(var j=0; j <childNodes.length; ++j ){\r
+ var header_name = ""; \r
+ var header_status = 0; \r
+ \r
+ //var header_encrypted = -1;\r
+ if(childNodes[j].localName == "header"){\r
+ header_name = childNodes[j].getAttribute("name");\r
+ if(childNodes[j].hasAttribute("status"))\r
+ header_status = parseInt(childNodes[j].getAttribute("status"),10);\r
+ \r
+ /*if(childNodes[j].hasAttribute("encrypted"))\r
+ header_encrypted = parseInt(childNodes[j].getAttribute("encrypted"),10);*/\r
+ \r
+ // load values to array\r
+ tabSecureHeaders.push(new xSecureHeader(header_name, header_status));\r
+ }\r
+ }\r
+ return tabSecureHeaders;\r
+ }else{\r
+ gConsole.logStringMessage("[msgCompSMIMESecureHeaders : ReadXmlHeadersToSign] no headers tag in file " + completePath);\r
+ }\r
+ } catch (e) {\r
+ gConsole.logStringMessage("[msgCompSMIMESecureHeaders : ReadXmlHeadersToSign] Error: " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);\r
+ }\r
+}\r
+\r
+/*\r
+ * \r
+ */\r
+function xSecureHeader(name,status){\r
+ if(name)\r
+ this._name = name;\r
+ if(status)\r
+ this._status = status;\r
+ /*if(encrypted)\r
+ this._encrypted = encrypted;*/\r
+}
\ No newline at end of file
--- /dev/null
+/* ***** 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 "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 Communicator.
+ *
+ * The Initial Developer of the Original Code is
+ * Netscape Communications Corporation.
+ * Portions created by the Initial Developer are Copyright (C) 2002
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Eric Ballet Baz / BT Global Services / Etat francais - Ministere de la Defense
+ * Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved
+ *
+ * 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 ***** */
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+var gListBox;
+var gViewButton;
+var gBundle;
+
+var gEmailAddresses;
+var gCertStatusSummaries;
+var gCertIssuedInfos;
+var gCertExpiresInfos;
+var gCerts;
+var gCount;
+
+var gSMimeContractID = "@mozilla.org/messenger-smime/smimejshelper;1";
+var gISMimeJSHelper = Components.interfaces.nsISMimeJSHelper;
+var gIX509Cert = Components.interfaces.nsIX509Cert;
+const nsICertificateDialogs = Components.interfaces.nsICertificateDialogs;
+const nsCertificateDialogs = "@mozilla.org/nsCertificateDialogs;1"
+
+const PREF_SECURE_HEADERS_FOLDER_DATAS="secureheaders.folderdata";
+const SECURE_HEADER_PROPERTIES_URL = "chrome://messenger/locale/secureheaders.properties";
+var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);
+
+function getStatusExplanation(value)
+{
+ switch (value)
+ {
+ case gIX509Cert.VERIFIED_OK:
+ return gBundle.getString("StatusValid");
+
+ case gIX509Cert.NOT_VERIFIED_UNKNOWN:
+ case gIX509Cert.INVALID_CA:
+ case gIX509Cert.USAGE_NOT_ALLOWED:
+ return gBundle.getString("StatusInvalid");
+
+ case gIX509Cert.CERT_REVOKED:
+ return gBundle.getString("StatusRevoked");
+
+ case gIX509Cert.CERT_EXPIRED:
+ return gBundle.getString("StatusExpired");
+
+ case gIX509Cert.CERT_NOT_TRUSTED:
+ case gIX509Cert.ISSUER_NOT_TRUSTED:
+ case gIX509Cert.ISSUER_UNKNOWN:
+ return gBundle.getString("StatusUntrusted");
+ }
+
+ return "";
+}
+
+function onLoad()
+{
+ var params = window.arguments[0];
+ if (!params)
+ return;
+
+ var helper = Components.classes[gSMimeContractID].createInstance(gISMimeJSHelper);
+
+ if (!helper)
+ return;
+
+ gListBox = document.getElementById("infolist");
+ gViewButton = document.getElementById("viewCertButton");
+ gBundle = document.getElementById("bundle_smime_comp_info");
+
+ gEmailAddresses = new Object();
+ gCertStatusSummaries = new Object();
+ gCertIssuedInfos = new Object();
+ gCertExpiresInfos = new Object();
+ gCerts = new Object();
+ gCount = new Object();
+ var canEncrypt = new Object();
+
+ var allow_ldap_cert_fetching = false;
+
+ try {
+ if (params.compFields.securityInfo.requireEncryptMessage) {
+ allow_ldap_cert_fetching = true;
+ }
+ }
+ catch (e)
+ {
+ }
+
+ while (true)
+ {
+ try
+ {
+ helper.getRecipientCertsInfo(
+ params.compFields,
+ gCount,
+ gEmailAddresses,
+ gCertStatusSummaries,
+ gCertIssuedInfos,
+ gCertExpiresInfos,
+ gCerts,
+ canEncrypt);
+ }
+ catch (e)
+ {
+ dump(e);
+ return;
+ }
+
+ if (!allow_ldap_cert_fetching)
+ break;
+
+ allow_ldap_cert_fetching = false;
+
+ var missing = new Array();
+
+ for (var j = gCount.value - 1; j >= 0; --j)
+ {
+ if (!gCerts.value[j])
+ {
+ missing[missing.length] = gEmailAddresses.value[j];
+ }
+ }
+
+ if (missing.length > 0)
+ {
+ var autocompleteLdap = Services.prefs
+ .getBoolPref("ldap_2.autoComplete.useDirectory");
+
+ if (autocompleteLdap)
+ {
+ var autocompleteDirectory = null;
+ if (params.currentIdentity.overrideGlobalPref) {
+ autocompleteDirectory = params.currentIdentity.directoryServer;
+ } else {
+ autocompleteDirectory = Services.prefs
+ .getCharPref("ldap_2.autoComplete.directoryServer");
+ }
+
+ if (autocompleteDirectory)
+ {
+ window.openDialog('chrome://messenger-smime/content/certFetchingStatus.xul',
+ '',
+ 'chrome,resizable=1,modal=1,dialog=1',
+ autocompleteDirectory,
+ missing
+ );
+ }
+ }
+ }
+ }
+
+ if (gBundle)
+ {
+ var yes_string = gBundle.getString("StatusYes");
+ var no_string = gBundle.getString("StatusNo");
+ var not_possible_string = gBundle.getString("StatusNotPossible");
+
+ var signed_element = document.getElementById("signed");
+ var encrypted_element = document.getElementById("encrypted");
+ var signedReceiptRequest_element = document.getElementById("signedReceiptRequest");
+ //var tripleWrapped_element = document.getElementById("tripleWrapped");
+ var securityLabel_element = document.getElementById("securityLabel");
+
+ if (params.smFields.requireEncryptMessage)
+ {
+ if (params.isEncryptionCertAvailable && canEncrypt.value)
+ {
+ encrypted_element.value = yes_string;
+ }
+ else
+ {
+ encrypted_element.value = not_possible_string;
+ }
+ }
+ else
+ {
+ encrypted_element.value = no_string;
+ }
+
+ if (params.smFields.signMessage)
+ {
+ if (params.isSigningCertAvailable)
+ {
+ signed_element.value = yes_string;
+ }
+ else
+ {
+ signed_element.value = not_possible_string;
+ }
+ }
+ else
+ {
+ signed_element.value = no_string;
+ }
+
+ if (params.smFields.SMIMEReceiptRequest)
+ {
+ if (params.isSigningCertAvailable)
+ signedReceiptRequest_element.value = yes_string;
+ else
+ signedReceiptRequest_element.value = not_possible_string;
+ }
+ else
+ signedReceiptRequest_element.value = no_string;
+ /*
+ if (params.smFields.tripleWrapMessage)
+ {
+ if (params.isEncryptionCertAvailable && canEncrypt.value && params.isSigningCertAvailable)
+ {
+ tripleWrapped_element.value = yes_string;
+ }
+ else
+ {
+ tripleWrapped_element.value = not_possible_string;
+ }
+ }
+ else
+ {
+ tripleWrapped_element.value = no_string;
+ }
+*/
+ /* Security Label */
+ if (params.smFields.securityPolicyIdentifier != "")
+ {
+ var tSecurityLabelConf = new securityLabelConf();;
+ var securityLabelValue = "";
+ if (params.smFields.securityClassification != -1)
+ securityLabelValue = tSecurityLabelConf.getSecurityClassificationName(params.smFields.securityPolicyIdentifier, params.smFields.securityClassification) + " ";
+
+ securityLabelValue += "[" + tSecurityLabelConf.getSecurityPolicyIdentifierName(params.smFields.securityPolicyIdentifier) + "]";
+ securityLabel_element.value = securityLabelValue;
+ }
+ else
+ securityLabel_element.value = no_string;
+
+ }
+
+ var imax = gCount.value;
+
+ for (var i = 0; i < imax; ++i)
+ {
+ var listitem = document.createElement("listitem");
+
+ listitem.appendChild(createCell(gEmailAddresses.value[i]));
+
+ if (!gCerts.value[i])
+ {
+ listitem.appendChild(createCell(gBundle.getString("StatusNotFound")));
+ }
+ else
+ {
+ listitem.appendChild(createCell(getStatusExplanation(gCertStatusSummaries.value[i])));
+ listitem.appendChild(createCell(gCertIssuedInfos.value[i]));
+ listitem.appendChild(createCell(gCertExpiresInfos.value[i]));
+ }
+
+ gListBox.appendChild(listitem);
+ }
+
+ //Secure Headers
+ var gSecureBundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
+ var secureBundle = gSecureBundle.createBundle(SECURE_HEADER_PROPERTIES_URL);
+ var sLabel;
+ if(params.isSecureHeaderAvailable == "true"){
+ // get international label for new line
+ sLabel = secureBundle.GetStringFromName("yes.label");
+ document.getElementById("headerSecured").setAttribute("value",sLabel);
+ ReadSecureHeaders(params);
+ }
+ else{
+ sLabel = secureBundle.GetStringFromName("no.label");
+ document.getElementById("headerSecured").setAttribute("value",sLabel);
+ }
+}
+
+function onSelectionChange(event)
+{
+ gViewButton.disabled = !(gListBox.selectedItems.length == 1 &&
+ certForRow(gListBox.selectedIndex));
+}
+
+function viewCertHelper(parent, cert) {
+ var cd = Components.classes[nsCertificateDialogs].getService(nsICertificateDialogs);
+ cd.viewCert(parent, cert);
+}
+
+function certForRow(aRowIndex) {
+ return gCerts.value[aRowIndex];
+}
+
+function viewSelectedCert()
+{
+ if (!gViewButton.disabled)
+ viewCertHelper(window, certForRow(gListBox.selectedIndex));
+}
+
+function doHelpButton()
+{
+ openHelp('compose_security', 'chrome://communicator/locale/help/suitehelp.rdf');
+}
+
+function createCell(label)
+{
+ var cell = document.createElement("listcell");
+ cell.setAttribute("label", label)
+ return cell;
+}
+
+function ReadSecureHeaders(params){
+ // get international label for new line
+ var gSecureBundle = Components.classes["@mozilla.org/intl/stringbundle;1"].getService(Components.interfaces.nsIStringBundleService);
+ var secureBundle = gSecureBundle.createBundle(SECURE_HEADER_PROPERTIES_URL);
+
+ var arrayHeaderSecure=ReadXmlHeadersToSecure(params);
+ if(arrayHeaderSecure && params.isSecureHeaderAvailable)
+ {
+ document.getElementById("secureheaderbox").collapsed = false;
+ var treechild = document.getElementById("secHeader_treechild_id");
+ for(var i=0;i<arrayHeaderSecure.length;++i)
+ {
+ var label;
+ //read the current header property
+ var headerName = arrayHeaderSecure[i]._name;
+ var headerStatus = arrayHeaderSecure[i]._status;
+ var headerEncrypted = arrayHeaderSecure[i]._encrypted;
+
+ //create each element for the tree
+ var treeitem=document.createElement("treeitem");
+ var treerow=document.createElement("treerow");
+ var namecell=document.createElement("treecell");
+ var statuscell=document.createElement("treecell");
+ var encryptedcell=document.createElement("treecell");
+
+ //set the header name
+ namecell.setAttribute("label",headerName);
+
+ //set the header status
+ switch(headerStatus)
+ {
+ case "-1":
+ label=secureBundle.GetStringFromName("notdefine.label");
+ break;
+ case "0" :
+ label=secureBundle.GetStringFromName("headerstatus.duplicated.label");
+ break;
+ case "1" :
+ label=secureBundle.GetStringFromName("headerstatus.deleted.label");
+ break;
+ case "2":
+ label=secureBundle.GetStringFromName("headerstatus.modified.label");
+ break;
+ default:
+ label="ERROR";
+ break;
+ }
+ statuscell.setAttribute("label",label);
+
+ //set the header encrypted
+ switch(headerEncrypted)
+ {
+ case "-1":
+ label=secureBundle.GetStringFromName("notdefine.label");
+ break;
+ case "0" :
+ label=secureBundle.GetStringFromName("no.label");
+ break;
+ case "1" :
+ label=secureBundle.GetStringFromName("yes.label");
+ break;
+ default:
+ label="ERROR";
+ break;
+ }
+ encryptedcell.setAttribute("label",label);
+
+ //append all element in the tree
+ treerow.appendChild(namecell);
+ treerow.appendChild(statuscell);
+ treerow.appendChild(encryptedcell);
+ treeitem.appendChild(treerow);
+ treechild.appendChild(treeitem);
+ }
+ }
+
+}
+
+/*
+ *
+ */
+var DEFAULT_SECUREHEADERS_XML_DIR = "secureHeaders"
+var DEFAULT_SECUREHEADERS_XML_FILE = "secureHeadersDefault.xml"
+function ReadXmlHeadersToSecure(params){
+ try{
+ // get xml file path
+ if(!params.currentIdentity){
+ gConsole.logStringMessage("[msgCompSecurityInfo.js - ReadXmlHeadersToSecure ] no xml files define \n ");
+ return;
+ }
+
+ var pref_data = params.currentIdentity.getCharAttribute(PREF_SECURE_HEADERS_FOLDER_DATAS);
+ var file = null;
+
+ if(!pref_data){
+ file = Components.classes["@mozilla.org/file/directory_service;1"].getService(Components.interfaces.nsIProperties).get("ProfD", Components.interfaces.nsIFile); // get profile folder
+ file.append(DEFAULT_SECUREHEADERS_XML_DIR);
+ file.append(DEFAULT_SECUREHEADERS_XML_FILE);
+ }else{
+ file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
+ file.initWithPath( pref_data );
+ }
+
+ if(!file.exists()){
+ gConsole.logStringMessage("[msgCompSecurityInfo.js - ReadXmlHeadersToSecure] Error loading schema file : " + pref_data);
+ return;
+ }
+
+ // Get Xml Document parser
+ var stream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
+ stream.init(file, -1, -1, Components.interfaces.nsIFileInputStream.CLOSE_ON_EOF);
+ var parser = Components.classes["@mozilla.org/xmlextras/domparser;1"].createInstance(Components.interfaces.nsIDOMParser);
+ var xmlDoc = parser.parseFromStream(stream, null, file.fileSize, "text/xml");
+
+ // get datas from file
+ var tabSecureHeaders = new Array; // tabHeaders[headerName][status][encrypted]
+ var compatibleTag = xmlDoc.getElementsByTagName("ximf:headers");
+ var sValue="";
+ if(compatibleTag.length>0){
+ var childNodes = compatibleTag[0].childNodes;
+ for(var j=0; j <childNodes.length; ++j ){
+ var header_name = "";
+ var header_status = "-1";
+ var header_encrypted = "-1";
+ if(childNodes[j].localName == "header"){
+ header_name = childNodes[j].getAttribute("name");
+ if(childNodes[j].hasAttribute("status"))
+ {
+ header_status = childNodes[j].getAttribute("status");
+ }
+ if(childNodes[j].hasAttribute("encrypted"))
+ header_encrypted = parseInt(childNodes[j].getAttribute("encrypted"),10);
+ // load values to array
+ tabSecureHeaders.push(new xSecureHeader(header_name, header_status,header_encrypted));
+ }
+ }
+ return tabSecureHeaders;
+ }else{
+ gConsole.logStringMessage("[msgCompSecurityInfo.js - ReadXmlHeadersToSecure] no headers tag in file " + pref_data);
+ }
+ } catch (e) {
+ gConsole.logStringMessage("[msgCompSecurityInfo.js - ReadXmlHeadersToSecure ] \n " + e + "\nfile : " + Error().fileName+"\nline : "+Error().lineNumber);
+ }
+}
+
+/*
+*
+*/
+function xSecureHeader(name,status,encrypted){
+ if(name)
+ this._name = name;
+ if(status)
+ this._status = status;
+ if(encrypted)
+ this._encrypted = encrypted;
+}
--- /dev/null
+<?xml version="1.0"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ - Contributor(s):
+ - Eric Ballet Baz BT Global Services / Etat francais Ministere de la Defense
+ - Copyright(c) 2011 CASSIDIAN - All rights reserved
+ - Copyright(c) Airbus Defence and Space 2014 - All rights reserved -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://messenger/skin/smime/msgCompSecurityInfo.css" type="text/css"?>
+
+<!DOCTYPE dialog [
+<!ENTITY % msgCompSecurityInfoDTD SYSTEM "chrome://messenger-smime/locale/msgCompSecurityInfo.dtd">
+<!ENTITY % secureheadersDTD SYSTEM "chrome://messenger/locale/secureheaders.dtd">
+%msgCompSecurityInfoDTD;
+%secureheadersDTD;
+]>
+
+<dialog id="msgCompSecurityInfo" title="&title.label;"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ style="width: 50em;"
+ persist="width height"
+ buttons="accept"
+ onload="onLoad();">
+
+ <script type="application/javascript" src="chrome://help/content/contextHelp.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgCompSecurityInfo.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgSecurityLabel.js"/>
+
+ <stringbundle id="bundle_smime_comp_info" src="chrome://messenger-smime/locale/msgCompSecurityInfo.properties"/>
+
+ <description>&subject.plaintextWarning;</description>
+ <separator class="thin"/>
+ <description>&status.heading;</description>
+ <grid>
+ <columns>
+ <column/>
+ <column/>
+ <column/>
+ </columns>
+ <rows>
+ <row>
+ <label value="&status.signed;"/>
+ <label id="signed"/>
+ </row>
+ <row>
+ <label value="&status.securityLabel;"/>
+ <label id="securityLabel"/>
+ </row>
+ <row>
+ <label value="&status.encrypted;"/>
+ <label id="encrypted"/>
+ </row>
+ <row>
+ <label value="&secureHeaders.field;"/>
+ <label id="headerSecured"/>
+ </row>
+ <row>
+ <label value="&status.signedReceiptRequest;"/>
+ <label id="signedReceiptRequest"/>
+ </row>
+ </rows>
+ </grid>
+
+ <vbox id="secureheaderbox" flex="1" style="width:40px; height:100px;" collapsed="true">
+ <tree flex="1">
+ <treecols>
+ <treecol id="headerName" label="&headername.label;" flex="1" persist="width ordinal hidden" />
+ <splitter class="tree-splitter"/>
+ <treecol id="headerStatus" label="&headerstatus.label;" flex="1" persist="width ordinal hidden" />
+ </treecols>
+ <treechildren id="secHeader_treechild_id">
+ </treechildren>
+ </tree>
+ </vbox>
+
+ <separator class="thin"/>
+ <label value="&status.certificates;" control="infolist"/>
+
+ <listbox id="infolist" flex="1"
+ onselect="onSelectionChange(event);">
+ <listcols>
+ <listcol flex="3" width="0"/>
+ <splitter class="tree-splitter"/>
+ <listcol flex="1" width="0"/>
+ <splitter class="tree-splitter"/>
+ <listcol flex="2" width="0"/>
+ <splitter class="tree-splitter"/>
+ <listcol flex="2" width="0"/>
+ </listcols>
+ <listhead>
+ <listheader label="&tree.recipient;"/>
+ <listheader label="&tree.status;"/>
+ <listheader label="&tree.issuedDate;"/>
+ <listheader label="&tree.expiresDate;"/>
+ </listhead>
+ </listbox>
+ <hbox pack="start">
+ <button id="viewCertButton" disabled="true"
+ label="&view.label;" accesskey="&view.accesskey;"
+ oncommand="viewSelectedCert();"/>
+ </hbox>
+</dialog>
\ No newline at end of file
--- /dev/null
+/* ***** 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 "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
+ * BT Global Services / Etat francais - Ministere de la Defense.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ *
+ * 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 ***** */
+
+var gSMFields;
+var gSecurityLabelDialogStringBundle;
+var currentSecurityPolicyIdentifier;
+var currentSecurityClassification;
+var currentPrivacyMark;
+var currentSecurityCategories;
+
+var gSecurityLabelConf;
+
+function securityLabelDialogOnLoad() {
+ gSMFields = window.opener.gSMFields; //window.opener.gMsgCompose.compFields.securityInfo;
+ if (gSMFields == null)
+ return;
+
+ gSecurityLabelDialogStringBundle = Components.classes["@mozilla.org/intl/stringbundle;1"]
+ .getService(Components.interfaces.nsIStringBundleService)
+ .createBundle("chrome://messenger-smime/locale/msgSecurityLabel.properties");
+
+ /* Read Security Label profiles */
+ gSecurityLabelConf = new securityLabelConf();
+
+ /* Get current values */
+ currentSecurityPolicyIdentifier = gSMFields.securityPolicyIdentifier;
+ currentSecurityClassification = gSMFields.securityClassification;
+ currentPrivacyMark = gSMFields.privacyMark;
+ currentSecurityCategories = gSMFields.securityCategories;
+
+ /* Build Security Policy menulist */
+ var securityPolicyIdentifierMenuList = document.getElementById("securityLabelSecurityPolicyIdentifierMenuList");
+
+ /* Clear list */
+ while (securityPolicyIdentifierMenuList.menupopup.firstChild)
+ securityPolicyIdentifierMenuList.menupopup.removeChild(securityPolicyIdentifierMenuList.menupopup.firstChild);
+
+ /* Construct list */
+ securityLabelDialogCreateMenuItem(securityPolicyIdentifierMenuList, gSecurityLabelDialogStringBundle.GetStringFromName("noSecurityPolicyIdentifier"), "", "");
+ for (policyName in gSecurityLabelConf.mSecurityPolicyList)
+ securityLabelDialogCreateMenuItem(securityPolicyIdentifierMenuList, policyName, gSecurityLabelConf.mSecurityPolicyList[policyName], currentSecurityPolicyIdentifier);
+
+ /* Init UI */
+ securityLabelDialogInitUI();
+}
+
+function securityLabelDialogOnSecurityPolicyIdentifier() {
+ currentSecurityClassification = -1;
+ currentPrivacyMark = "";
+ currentSecurityCategories = "";
+
+ securityLabelDialogInitUI();
+}
+
+function securityLabelDialogInitUI() {
+ var selectedPolicyIdentifier = document.getElementById("securityLabelSecurityPolicyIdentifierMenuList").label;
+
+ /* Build Security Classification menulist */
+ var securityClassificationMenuList = document.getElementById("securityLabelSecurityClassificationMenuList");
+
+ /* Clear list */
+ while (securityClassificationMenuList.menupopup.firstChild)
+ securityClassificationMenuList.menupopup.removeChild(securityClassificationMenuList.menupopup.firstChild);
+
+ /* Construct list */
+ securityLabelDialogCreateMenuItem(securityClassificationMenuList, gSecurityLabelDialogStringBundle.GetStringFromName("noSecurityClassification"), "-1", "-1");
+ for (classificationName in gSecurityLabelConf.mSecurityClassificationList[selectedPolicyIdentifier])
+ securityLabelDialogCreateMenuItem(securityClassificationMenuList, classificationName, gSecurityLabelConf.mSecurityClassificationList[selectedPolicyIdentifier][classificationName], currentSecurityClassification);
+
+ /* Build Privacy Mark menulist */
+ var privacyMarkMenuList = document.getElementById("securityLabelPrivacyMarkMenuList");
+
+ /* Clear list */
+ while (privacyMarkMenuList.menupopup.firstChild)
+ privacyMarkMenuList.menupopup.removeChild(privacyMarkMenuList.menupopup.firstChild);
+ privacyMarkMenuList.removeAttribute("editable");
+
+ /* Construct list */
+ securityLabelDialogCreateMenuItem(privacyMarkMenuList, "", "", "");
+ for (privacyMarkName in gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier])
+ if (privacyMarkName != "freeText")
+ securityLabelDialogCreateMenuItem(privacyMarkMenuList, gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier][privacyMarkName], gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier][privacyMarkName], currentPrivacyMark);
+
+ if (gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier] && gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier]["freeText"])
+ privacyMarkMenuList.setAttribute("editable", true);
+
+ document.getElementById("securityLabelPrivacyMarkTextBox").value = currentPrivacyMark;
+ document.getElementById("securityLabelPrivacyMarkMenuList").value = currentPrivacyMark;
+
+ /* Security Categories */
+ securityLabelDialogSecurityCategoriesClearList();
+ if (currentSecurityCategories !== "" && currentSecurityCategories !== undefined) {
+ var s = currentSecurityCategories.split("|");
+ if (s.length % 3 == 0) {
+ for (var i = 0; i < s.length; i += 3)
+ securityLabelDialogSecurityCategoriesAddItem(s[i] + "|" + s[i + 1] + "|" + s[i + 2]);
+
+ var securityLabelSecurityCategoriesListBox = document.getElementById("securityLabelSecurityCategoriesListBox");
+ securityLabelSecurityCategoriesListBox.selectedItem = securityLabelSecurityCategoriesListBox.firstChild;
+ }
+ }
+
+ /* Enable/disable widgets */
+ securityLabelDialogSetControls();
+}
+
+function securityLabelDialogOnSecurityClassification() {
+ securityLabelDialogSecurityCategoriesClearList();
+}
+
+function securityLabelDialogCreateMenuItem(menulist, label, value, selectedValue) {
+ var menuitem = menulist.appendItem(label, value);
+ if (value == selectedValue)
+ menulist.selectedItem = menuitem;
+}
+
+function securityLabelDialogSecurityCategoriesOnButtonAdd() {
+ securityLabelDialogSecurityCategoriesAddItem("");
+}
+
+function securityLabelDialogSecurityCategoriesAddItem(selectedValue) {
+ var securityLabelSecurityCategoriesListBox = document.getElementById("securityLabelSecurityCategoriesListBox");
+ var n = 0;
+ while (document.getElementById("securityLabelSecurityCategoriesMenuList" + n) != null)
+ n++;
+
+ var menulist = document.createElement("menulist");
+ menulist.setAttribute("id", "securityLabelSecurityCategoriesMenuList" + n);
+ menulist.setAttribute("flex", "1");
+
+ var listitem = document.createElement("listitem");
+ listitem.setAttribute("id", "securityLabelSecurityCategoriesListitem" + n);
+ listitem.setAttribute("allowevents", true);
+ listitem.appendChild(menulist);
+ securityLabelSecurityCategoriesListBox.appendChild(listitem);
+ securityLabelSecurityCategoriesListBox.ensureIndexIsVisible(securityLabelSecurityCategoriesListBox.getRowCount() - 1);
+ securityLabelSecurityCategoriesListBox.selectedItem = listitem;
+
+ /* Construct menulist */
+ securityLabelDialogCreateMenuItem(menulist, "", "", selectedValue);
+ var selectedPolicyIdentifier = document.getElementById("securityLabelSecurityPolicyIdentifierMenuList").label;
+ for (var i = 0; i < 2; i++) {
+ if (gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier]) {
+ var list;
+ /* Security Categories for all classifications */
+ if (i == 0)
+ list = gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier]["all"];
+ /* Security Categories for selected classification */
+ if (i == 1)
+ list = gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier][document.getElementById("securityLabelSecurityClassificationMenuList").value];
+
+ for (securityCategoryName in list)
+ securityLabelDialogCreateMenuItem(menulist, securityCategoryName, list[securityCategoryName][0] + "|" + list[securityCategoryName][1] + "|" + list[securityCategoryName][2], selectedValue);
+ }
+ }
+
+ /* Enable/disable widgets */
+ securityLabelDialogSetControls();
+}
+
+function securityLabelDialogSecurityCategoriesOnButtonRemove() {
+ var securityLabelSecurityCategoriesListBox = document.getElementById("securityLabelSecurityCategoriesListBox");
+
+ if (securityLabelSecurityCategoriesListBox.selectedItem != null) {
+ var nextNode = securityLabelSecurityCategoriesListBox.selectedItem.nextSibling;
+ if (nextNode == null)
+ nextNode = securityLabelSecurityCategoriesListBox.selectedItem.previousSibling;
+ securityLabelSecurityCategoriesListBox.removeChild(securityLabelSecurityCategoriesListBox.selectedItem);
+ securityLabelSecurityCategoriesListBox.selectedItem = nextNode;
+ }
+
+ /* Enable/disable widgets */
+ securityLabelDialogSetControls();
+}
+
+function securityLabelDialogSecurityCategoriesClearList() {
+ var securityLabelSecurityCategoriesListBox = document.getElementById("securityLabelSecurityCategoriesListBox");
+
+ while (securityLabelSecurityCategoriesListBox.hasChildNodes())
+ securityLabelSecurityCategoriesListBox.removeChild(securityLabelSecurityCategoriesListBox.firstChild);
+
+ /* Enable/disable widgets */
+ securityLabelDialogSetControls();
+}
+
+function securityLabelDialogOnAccept() {
+ /* Security Policy Identifier */
+ gSMFields.securityPolicyIdentifier = document.getElementById("securityLabelSecurityPolicyIdentifierMenuList").value;
+ if (gSMFields.securityPolicyIdentifier != "") {
+
+ /* Security Classification */
+ gSMFields.securityClassification = document.getElementById("securityLabelSecurityClassificationMenuList").value;
+
+ /* Privacy Mark */
+ var selectedPolicyIdentifier = document.getElementById("securityLabelSecurityPolicyIdentifierMenuList").label;
+ if (gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier] && gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier].length > 0)
+ gSMFields.privacyMark = document.getElementById("securityLabelPrivacyMarkMenuList").value;
+ else
+ gSMFields.privacyMark = document.getElementById("securityLabelPrivacyMarkTextBox").value;
+
+ /* Security Categories */
+ var securityLabelSecurityCategoriesListBox = document.getElementById("securityLabelSecurityCategoriesListBox");
+ var securityCategories = "";
+ if (securityLabelSecurityCategoriesListBox.hasChildNodes()) {
+ for (var i = 0; i < securityLabelSecurityCategoriesListBox.childNodes.length; i++) {
+ var value = securityLabelSecurityCategoriesListBox.childNodes[i].firstChild.value;
+
+ if (value != undefined && value != "") {
+ if (securityCategories != "")
+ securityCategories += "|";
+ securityCategories += value;
+ }
+ }
+ }
+ gSMFields.securityCategories = securityCategories;
+
+ } else {
+ gSMFields.securityClassification = -1;
+ gSMFields.privacyMark = "";
+ gSMFields.securityCategories = "";
+ }
+}
+
+function securityLabelDialogSetControls() {
+ var selectedPolicyIdentifier = document.getElementById("securityLabelSecurityPolicyIdentifierMenuList").label;
+ if (gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier] && gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier].length > 0) {
+ document.getElementById("securityLabelPrivacyMarkTextBox").hidden = true;
+ document.getElementById("securityLabelPrivacyMarkMenuList").hidden = false;
+ } else {
+ document.getElementById("securityLabelPrivacyMarkTextBox").hidden = false;
+ document.getElementById("securityLabelPrivacyMarkMenuList").hidden = true;
+ }
+
+ if (document.getElementById("securityLabelSecurityPolicyIdentifierMenuList").value != "") {
+ document.getElementById("securityLabelSecurityClassificationMenuList").disabled = false;
+
+ if (gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier] && gSecurityLabelConf.mPrivacyMarkList[selectedPolicyIdentifier]["freeText"])
+ document.getElementById("securityLabelPrivacyMarkTextBox").disabled = false;
+ else
+ document.getElementById("securityLabelPrivacyMarkTextBox").disabled = true;
+
+ document.getElementById("securityLabelPrivacyMarkMenuList").disabled = false;
+ document.getElementById("securityLabelSecurityCategoriesListBox").disabled = false;
+
+ /* Security Categories for all classifications */
+ var list1;
+ if (gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier])
+ list1 = gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier]["all"];
+
+ /* Security Categories for selected classification */
+ var list2;
+ if (gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier])
+ list2 = gSecurityLabelConf.mSecurityCategoriesList[selectedPolicyIdentifier][document.getElementById("securityLabelSecurityClassificationMenuList").value];
+
+ if (list1 != undefined || list2 != undefined)
+ document.getElementById("securityLabelSecurityCategoriesButtonAdd").disabled = false;
+ else
+ document.getElementById("securityLabelSecurityCategoriesButtonAdd").disabled = true;
+
+ if (document.getElementById("securityLabelSecurityCategoriesListBox").getRowCount() > 0 && document.getElementById("securityLabelSecurityCategoriesListBox").getRowCount() < 64)
+ document.getElementById("securityLabelSecurityCategoriesButtonRemove").disabled = false;
+ else
+ document.getElementById("securityLabelSecurityCategoriesButtonRemove").disabled = true;
+
+ } else {
+ document.getElementById("securityLabelSecurityClassificationMenuList").disabled = true;
+ document.getElementById("securityLabelPrivacyMarkTextBox").disabled = true;
+ document.getElementById("securityLabelPrivacyMarkMenuList").disabled = true;
+ document.getElementById("securityLabelSecurityCategoriesListBox").disabled = true;
+ document.getElementById("securityLabelSecurityCategoriesButtonAdd").disabled = true;
+ document.getElementById("securityLabelSecurityCategoriesButtonRemove").disabled = true;
+ }
+}
--- /dev/null
+<?xml version="1.0"?>
+<!-- ***** 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 "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
+ * BT Global Services / Etat francais - Ministere de la Defense.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ *
+ * 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 ***** -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<!DOCTYPE dialog SYSTEM "chrome://messenger-smime/locale/msgCompSecurityLabelDialog.dtd">
+
+<dialog xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ xmlns:html="http://www.w3.org/1999/xhtml"
+ id="securityLabelDialog"
+ buttons="accept,cancel"
+ defaultButton="accept"
+ title="&securityLabelDialog.name;"
+ onload="securityLabelDialogOnLoad();"
+ ondialogaccept="securityLabelDialogOnAccept();">
+
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgSecurityLabel.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgCompSecurityLabelDialog.js"/>
+
+ <dialogheader title="&securityLabelDialog.name;" />
+
+ <grid flex="1">
+
+ <columns>
+ <column />
+ <column flex="1"/>
+ </columns>
+
+ <rows>
+ <row align="center">
+ <label control="securityLabelSecurityPolicyIdentifierTextBox" value="&securityLabelDialog.securityPolicyIdentifier.name;" />
+ <menulist id="securityLabelSecurityPolicyIdentifierMenuList" oncommand="securityLabelDialogOnSecurityPolicyIdentifier();">
+ <menupopup />
+ </menulist>
+ </row>
+ <row align="center">
+ <label control="securityLabelPrivacyMarkTextBox" value="&securityLabelDialog.privacyMark.name;" />
+ <vbox>
+ <textbox id="securityLabelPrivacyMarkTextBox" />
+ <menulist id="securityLabelPrivacyMarkMenuList">
+ <menupopup />
+ </menulist>
+ </vbox>
+ </row>
+ <row align="center">
+ <label value="&securityLabelDialog.securityClassification.name;" />
+ <menulist id="securityLabelSecurityClassificationMenuList" oncommand="securityLabelDialogOnSecurityClassification();">
+ <menupopup />
+ </menulist>
+ </row>
+ <row flex="1">
+ <label value="&securityLabelDialog.securityCategories.name;" />
+ <vbox flex="1">
+ <listbox id="securityLabelSecurityCategoriesListBox" flex="1" />
+ <hbox>
+ <button id="securityLabelSecurityCategoriesButtonAdd" label="&securityLabelDialog.securityCategories.button.add.name;" oncommand="securityLabelDialogSecurityCategoriesOnButtonAdd();" />
+ <button id="securityLabelSecurityCategoriesButtonRemove" label="&securityLabelDialog.securityCategories.button.remove.name;" oncommand="securityLabelDialogSecurityCategoriesOnButtonRemove();" />
+ </hbox>
+ <separator />
+ </vbox>
+ </row>
+ </rows>
+
+ </grid>
+
+</dialog>
--- /dev/null
+/* -*- Mode: Java; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Eric Ballet Baz / BT Global Services / Etat francais - Ministere de la Defense
+ * Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ * Copyright(c) 2011 CASSIDIAN - All rights reserved
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */
+
+Components.utils.import("resource://gre/modules/Services.jsm");
+
+var gEncryptionStatus = -1;
+var gSignatureStatus = -1;
+var gSignerCert = null;
+var gEncryptionCert = null;
+var gSecurityPolicyIdentifier = null;
+var gSecurityClassification = -1;
+var gPrivacyMark = null;
+var gSecurityCategories = null;
+var gSecurityLabelConf = null;
+var gSecureHeaders = "";
+var gSecureHeadersState=-1;
+/*
+gSecureHeadersArray[o.hdrName]={
+ o.hdrName = sHeader.headerName; // signed header
+ o.hdrSecureValue = sHeader.headerValue; // value in the signature
+ o.hdrMimeValue = ""; // value in the MIME message
+ o.hdrSignedStatus = sHeader.headerStatus;
+ o.hdrCanonAlgo = aCanonAlgo;
+ o.hdrEncryptStatus = "";
+ o.hdrSignedRes = "valid";}
+*/
+const SECURE_HEADER_SEPARATOR = "###HEADER_SEPARATOR###";
+const HEADER_VAL_SEPARATOR = "###HEADER_VAL###";
+var gSecureHeadersArray={};
+addEventListener("load", smimeReadOnLoad, false);
+
+function smimeReadOnLoad()
+{
+ removeEventListener("load", smimeReadOnLoad, false);
+
+ top.controllers.appendController(SecurityController);
+
+ addEventListener("unload", smimeReadOnUnload, false);
+
+ Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService)
+ .addObserver(securityLabelCreateDbObserver, "MsgCreateDBView", false);
+
+ if (!gSecurityLabelConf)
+ gSecurityLabelConf = new securityLabelConf();
+}
+
+function smimeReadOnUnload()
+{
+ removeEventListener("unload", smimeReadOnUnload, false);
+
+ top.controllers.removeController(SecurityController);
+
+ Components.classes["@mozilla.org/observer-service;1"]
+ .getService(Components.interfaces.nsIObserverService)
+ .removeObserver(securityLabelCreateDbObserver, "MsgCreateDBView");
+}
+
+function showImapSignatureUnknown()
+{
+ let readSmimeBundle = document.getElementById("bundle_read_smime");
+ let brandBundle = document.getElementById("bundle_brand");
+ if (!readSmimeBundle || !brandBundle)
+ return;
+
+ if (Services.prompt.confirm(window, brandBundle.getString("brandShortName"),
+ readSmimeBundle.getString("ImapOnDemand")))
+ {
+ gDBView.reloadMessageWithAllParts();
+ }
+}
+
+function showMessageReadSecurityInfo()
+{
+ let gSignedUINode = document.getElementById("signedHdrIcon");
+ if (gSignedUINode && gSignedUINode.getAttribute("signed") == "unknown")
+ {
+ showImapSignatureUnknown();
+ return;
+ }
+
+ let pkiParams = Components.classes["@mozilla.org/security/pkiparamblock;1"]
+ .createInstance(Components.interfaces.nsIPKIParamBlock);
+
+ // isupport array starts with index 1
+ pkiParams.setISupportAtIndex(1, gSignerCert);
+ pkiParams.setISupportAtIndex(2, gEncryptionCert);
+
+ var params = pkiParams.QueryInterface(Components.interfaces.nsIDialogParamBlock);
+ // int array starts with index 0, but that is used for window exit status
+ params.SetInt(1, gSignatureStatus);
+ params.SetInt(2, gEncryptionStatus);
+ params.SetInt(3, gSecurityClassification);
+ params.SetInt(4,gSecureHeadersState);
+
+ params.SetString(0, gSecurityPolicyIdentifier);
+ params.SetString(1, gPrivacyMark);
+ params.SetString(2, gSecurityCategories);
+ params.SetString(12,gSecureHeaders);
+
+ gConsole.logStringMessage("[showMessageReadSecurityInfo] Signature status: " + gSignatureStatus);
+ gConsole.logStringMessage("[showMessageReadSecurityInfo] gSecurityPolicyIdentifier: " + gSecurityPolicyIdentifier);
+ gConsole.logStringMessage("[showMessageReadSecurityInfo] gPrivacyMark: " + gPrivacyMark);
+ gConsole.logStringMessage("[showMessageReadSecurityInfo] gSecurityCategories: " + gSecurityCategories);
+ gConsole.logStringMessage("[showMessageReadSecurityInfo] gSecureHeaders: " + gSecureHeaders);
+
+ //create string with gSecureHeadersArray
+ var arraySecureHeadersString = "";
+ for (headerName in gSecureHeadersArray) {
+ arraySecureHeadersString+=gSecureHeadersArray[headerName].hdrName+HEADER_VAL_SEPARATOR;
+ arraySecureHeadersString+=gSecureHeadersArray[headerName].hdrSecureValue+HEADER_VAL_SEPARATOR; //put the value decoded instead of the value in the signature (encoded RFC2047) for the diplay
+ arraySecureHeadersString+=gSecureHeadersArray[headerName].hdrMimeValue+HEADER_VAL_SEPARATOR;
+ arraySecureHeadersString+=""+gSecureHeadersArray[headerName].hdrSignedStatus+HEADER_VAL_SEPARATOR;
+ arraySecureHeadersString+=gSecureHeadersArray[headerName].hdrCanonAlgo+HEADER_VAL_SEPARATOR;
+ //arraySecureHeadersString+=""+gSecureHeadersArray[headerName].hdrEncryptStatus+HEADER_VAL_SEPARATOR;
+ arraySecureHeadersString+=""+gSecureHeadersArray[headerName].hdrSignedRes+HEADER_VAL_SEPARATOR;
+ arraySecureHeadersString+=SECURE_HEADER_SEPARATOR;
+ }
+ params.SetString(13,arraySecureHeadersString);
+ window.openDialog("chrome://messenger-smime/content/msgReadSecurityInfo.xul",
+ "", "chrome,resizable=1,modal=1,dialog=1", pkiParams);
+}
+
+var SecurityController =
+{
+ supportsCommand: function(command)
+ {
+ switch (command)
+ {
+ case "cmd_viewSecurityStatus":
+ return true;
+
+ default:
+ return false;
+ }
+ },
+
+ isCommandEnabled: function(command)
+ {
+ switch (command)
+ {
+ case "cmd_viewSecurityStatus":
+ if (document.documentElement.getAttribute('windowtype') == "mail:messageWindow")
+ return GetNumSelectedMessages() > 0;
+
+ if (GetNumSelectedMessages() > 0 && gDBView)
+ {
+ let enabled = {value: false};
+ let checkStatus = {};
+ gDBView.getCommandStatus(nsMsgViewCommandType.cmdRequiringMsgBody,
+ enabled, checkStatus);
+ return enabled.value;
+ }
+ // else: fall through.
+
+ default:
+ return false;
+ }
+ }
+};
+
+/* Add Security Label column */
+var securityLabelCreateDbObserver = {
+ observe: function(aMsgFolder, aTopic, aData) {
+ try {
+ if (gDBView != undefined && gDBView.addColumnHandler)
+ gDBView.addColumnHandler("securityLabelSecurityClassificationColumn", securityLabelSecurityClassificationColumnHandler);
+ } catch(e) {}
+ }
+}
+
+var securityLabelSecurityClassificationColumnHandler = {
+ getCellText: function(row, column) {
+ var key = gDBView.getKeyAt(row);
+ var hdr = gDBView.db.GetMsgHdrForKey(key);
+ var securityLabelSecurityPolicyIdentifier = hdr.getStringProperty("securityLabelSecurityPolicyIdentifier");
+ var securityLabelSecurityClassification = hdr.getStringProperty("securityLabelSecurityClassification");
+
+ if (securityLabelSecurityPolicyIdentifier != "" && securityLabelSecurityClassification != "" && securityLabelSecurityClassification != "-1")
+ return gSecurityLabelConf.getSecurityClassificationName(securityLabelSecurityPolicyIdentifier, securityLabelSecurityClassification);
+
+ return "";
+ },
+ getSortStringForRow: function(hdr) {
+ var securityLabelSecurityPolicyIdentifier = hdr.getStringProperty("securityLabelSecurityPolicyIdentifier");
+ var securityLabelSecurityClassification = hdr.getStringProperty("securityLabelSecurityClassification");
+
+ if (securityLabelSecurityPolicyIdentifier != "") {
+ if (securityLabelSecurityClassification != "" && securityLabelSecurityClassification != "-1") {
+ if (securityLabelSecurityClassification < 10)
+ return "00" + securityLabelSecurityClassification;
+ else if (securityLabelSecurityClassification < 100)
+ return "0" + securityLabelSecurityClassification;
+ else
+ return securityLabelSecurityClassification;
+ }
+ }
+ return "";
+ },
+ isString: function() {return true;},
+ getCellProperties: function(row, col, props){ },
+ getRowProperties: function(row, props){ },
+ getImageSrc: function(row, col) {return null;},
+ getSortLongForRow: function(hdr) {return 0;}
+}
--- /dev/null
+ /* -*- Mode: Java; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-\r
+ * This Source Code Form is subject to the terms of the Mozilla Public\r
+ * License, v. 2.0. If a copy of the MPL was not distributed with this\r
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.\r
+ * Contributor(s):\r
+ * Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved\r
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */\r
+\r
+const SECURE_HEADER_SEPARATOR = "###HEADER_SEPARATOR###";\r
+const HEADER_VAL_SEPARATOR = "###HEADER_VAL###";\r
+\r
+/*\r
+gSecureHeadersArray[o.hdrName]={\r
+ o.hdrName = sHeader.headerName; // signed header\r
+ o.hdrSecureValue = sHeader.headerValue; // Value in the signature\r
+ o.hdrMimeValue = ""; // value in the MIME message\r
+ o.hdrSignedStatus = sHeader.headerStatus;\r
+ o.hdrCanonAlgo = aCanonAlgo;\r
+ o.hdrEncryptStatus = "";\r
+ o.hdrSignedRes = "valid";}\r
+*/\r
+function onLoad()\r
+{\r
+ var gSecureHeadersBundle = document.getElementById("bundle_secure_headers_view");\r
+\r
+ var secureHeadersString = window.arguments[0]; \r
+ \r
+ if(secureHeadersString=="")return;\r
+ // split secureHeadersString to cSecureHeadersArray\r
+ var cSecureHeadersArray = {}; \r
+ var each_header_tab=secureHeadersString.split(SECURE_HEADER_SEPARATOR);\r
+ for(var i=0;i<each_header_tab.length;++i){\r
+ var each_value_header_tab=each_header_tab[i].split(HEADER_VAL_SEPARATOR);\r
+ var oEntry = new Object;\r
+ var headerNameEntry = ""; \r
+ for(var idxElt=0;idxElt<each_value_header_tab.length;++idxElt){ \r
+ switch(idxElt){\r
+ case 0:\r
+ headerNameEntry = each_value_header_tab[idxElt];\r
+ oEntry.hdrName = each_value_header_tab[idxElt];\r
+ break;\r
+ case 1:\r
+ oEntry.hdrSecureValue = each_value_header_tab[idxElt];\r
+ break;\r
+ case 2:\r
+ oEntry.hdrMimeValue = each_value_header_tab[idxElt];\r
+ break;\r
+ case 3:\r
+ oEntry.hdrSignedStatus = each_value_header_tab[idxElt];\r
+ break;\r
+ case 4:\r
+ oEntry.hdrCanonAlgo = each_value_header_tab[idxElt];\r
+ break;\r
+ case 5:\r
+ oEntry.hdrSignedRes = each_value_header_tab[idxElt];\r
+ break; \r
+ }\r
+ }\r
+ oEntry.hdrEncryptStatus = "";\r
+ if(headerNameEntry!="") cSecureHeadersArray[headerNameEntry] = oEntry;\r
+ }\r
+ \r
+ // create tree viewer\r
+ var treechild = document.getElementById("secHeader_treechild_id"); \r
+ for (headerName in cSecureHeadersArray) {\r
+ var label=""; \r
+ //create each element for the tree\r
+ var treeitem=document.createElement("treeitem");\r
+ var treerow=document.createElement("treerow");\r
+ var namecell=document.createElement("treecell");\r
+ var valuecell=document.createElement("treecell");\r
+ var statuscell=document.createElement("treecell"); \r
+ var canonizcell=document.createElement("treecell"); \r
+ var valueMimecell=document.createElement("treecell");\r
+ //var encryptedcell=document.createElement("treecell");\r
+ \r
+ //set the header name, value and status\r
+ namecell.setAttribute("label",cSecureHeadersArray[headerName].hdrName);\r
+ valuecell.setAttribute("label",cSecureHeadersArray[headerName].hdrSecureValue); // signed value\r
+ namecell.setAttribute("properties",cSecureHeadersArray[headerName].hdrSignedRes); \r
+ valueMimecell.setAttribute("label",cSecureHeadersArray[headerName].hdrMimeValue); // displayed value in message\r
+ \r
+ //set the header status\r
+ switch(cSecureHeadersArray[headerName].hdrSignedStatus){\r
+ case "-1":\r
+ label=gSecureHeadersBundle.getString("notdefine.label");\r
+ break;\r
+ case "0" :\r
+ label=gSecureHeadersBundle.getString("headerstatus.duplicated.label");\r
+ break;\r
+ case "1" :\r
+ label=gSecureHeadersBundle.getString("headerstatus.deleted.label");\r
+ break;\r
+ case "2":\r
+ label=gSecureHeadersBundle.getString("headerstatus.modified.label");\r
+ break;\r
+ default:\r
+ label="ERROR";\r
+ break;\r
+ }\r
+ statuscell.setAttribute("label",label);\r
+ \r
+ //set the canonization algo used\r
+ var sAlgo = "";\r
+ switch(parseInt(cSecureHeadersArray[headerName].hdrCanonAlgo,10)){\r
+ case 0:\r
+ sAlgo = gSecureHeadersBundle.getString("headercanoniz.simple.label");\r
+ break;\r
+ case 1:\r
+ sAlgo = gSecureHeadersBundle.getString("headercanoniz.relaxed.label");\r
+ break; \r
+ }\r
+ canonizcell.setAttribute("label",sAlgo);\r
+ \r
+ //set the header encrypted\r
+ /*switch(gSecureHeadersArray[headerName].hdrEncryptStatus){\r
+ case -1:\r
+ label=gSecureHeadersBundle.getString("notdefine.label");\r
+ break;\r
+ case 0 :\r
+ label=gSecureHeadersBundle.getString("no.label");\r
+ break;\r
+ case 1 :\r
+ label=gSecureHeadersBundle.getString("yes.label");\r
+ break;\r
+ default:\r
+ label="ERROR";\r
+ break;\r
+ }\r
+ encryptedcell.setAttribute("label",label);*/\r
+\r
+ //append all elements in the tree\r
+ treerow.appendChild(namecell);\r
+ treerow.appendChild(valuecell);\r
+ treerow.appendChild(statuscell); \r
+ treerow.appendChild(canonizcell); \r
+ treerow.appendChild(valueMimecell); \r
+ //treerow.appendChild(encryptedcell);\r
+ treeitem.appendChild(treerow);\r
+ treechild.appendChild(treeitem);\r
+ }\r
+}\r
+\r
+/*\r
+ * Load complete informations of selected header in texteboxes box\r
+ */\r
+function DisplayDetailHeader(){\r
+ var gConsole = Components.classes["@mozilla.org/consoleservice;1"].getService(Components.interfaces.nsIConsoleService);\r
+ try{\r
+ var tree = document.getElementById("secureheaderstree.id"); \r
+ var v = tree.currentIndex;\r
+ document.getElementById("headerName_val").value = tree.view.getCellText(v, tree.columns.getColumnAt(0)); \r
+ document.getElementById("headerValue_val").value = tree.view.getCellText(v, tree.columns.getColumnAt(1));\r
+ document.getElementById("headerStatus_val").value = tree.view.getCellText(v, tree.columns.getColumnAt(2));\r
+ document.getElementById("headerCanonization_val").value = tree.view.getCellText(v, tree.columns.getColumnAt(3));\r
+ document.getElementById("headerMimeValue_val").value = tree.view.getCellText(v, tree.columns.getColumnAt(4));\r
+ }catch(e){\r
+ gConsole.logStringMessage("DisplayDetailHeader -error : " + e + " - line " + e.lineNumber);\r
+ }\r
+}\r
--- /dev/null
+<!--\r
+/* ***** BEGIN LICENSE BLOCK *****\r
+Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved.\r
+secure header is under the triple license MPL 1.1/GPL 2.0/LGPL 2.1.\r
+\r
+\r
+Redistribution and use, in source and binary forms, with or without modification, are permitted provided that the following conditons are met :\r
+\r
+1. Redistributions of source code must retain the above copyright notice,\r
+2.MPL 1.1/GPL 2.0/LGPL 2.1. license agreements must be attached in the redistribution of the source code.\r
+3. Neither the names of the copyright holders nor the names of any contributors may be used to endorse or promote products derived from this software without specific prior written permission from EADS Defence and Security.\r
+\r
+Alternatively, the contents of this file may be used under the terms of\r
+ * either of the GNU General Public License Version 2 or later (the "GPL"),\r
+ * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),\r
+ * in which case the provisions of the GPL or the LGPL are applicable instead\r
+ * of those above. If you wish to allow use of your version of this file only\r
+ * under the terms of either the GPL or the LGPL, and not to allow others to\r
+ * use your version of this file under the terms of the MPL, indicate your\r
+ * decision by deleting the provisions above and replace them with the notice\r
+ * and other provisions required by the GPL or the LGPL. If you do not delete\r
+ * the provisions above, a recipient may use your version of this file under\r
+ * the terms of any one of the MPL, the GPL or the LGPL.\r
+\r
+REMINDER :\r
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.\r
+ \r
+EADS Defence and Security - 1 Boulevard Jean Moulin - ZAC de la Clef Saint Pierre - 78990 Elancourt - FRANCE (IDDN.FR.001.480012.002.S.P.2008.000.10000)\r
+ * ***** END LICENSE BLOCK ***** */\r
+-->\r
+\r
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>\r
+<?xml-stylesheet href="chrome://messenger/skin/smime/msgReadSecureHeaders.css" type="text/css"?>\r
+\r
+<!DOCTYPE dialog SYSTEM "chrome://messenger/locale/secureheaders.dtd">\r
+\r
+<dialog id="msgReadSecureHeadersViewId" title="&secureHeadersList.label;"\r
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul" \r
+ style="width:50em;"\r
+ buttons="accept"\r
+ persist="width height"\r
+ onload="onLoad();">\r
+\r
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgReadSecureHeadersView.js"/>\r
+\r
+ <stringbundle id="bundle_secure_headers_view" src="chrome://messenger/locale/secureheaders.properties"/> \r
+ <vbox flex="1"> \r
+ <hbox flex="1" style="width:30px; height:250px;">\r
+ <tree id="secureheaderstree.id" flex="1" seltype="single" onselect="DisplayDetailHeader();" >\r
+ <treecols>\r
+ <treecol id="headerName" label="&headername.label;" flex="1" persist="width ordinal hidden" ordinal="1"/>\r
+ <splitter class="tree-splitter"/>\r
+ <treecol id="headerValue" label="&headervalue.label;" flex="2" persist="width ordinal hidden" ordinal="2"/>\r
+ <treecol id="headerStatus" label="&headerstatus.label;" ordinal="3" hidden="true" ignoreincolumnpicker="true"/>\r
+ <treecol id="headerCanonization" label="&headercanonisation.label;" ordinal="4" hidden="true" ignoreincolumnpicker="true"/>\r
+ <treecol id="headerMimeValue" label="&headermimevalue.label;" ordinal="5" hidden="true" ignoreincolumnpicker="true"/>\r
+ </treecols> \r
+ <treechildren id="secHeader_treechild_id"> \r
+ </treechildren>\r
+ </tree>\r
+ </hbox>\r
+ <spacer flex="1"/>\r
+ <hbox flex="1" style="border:thin groove inherit;">\r
+ <grid flex="1">\r
+ <columns >\r
+ <column align="center"/> \r
+ <column flex="1" align="center"/>\r
+ </columns>\r
+ <rows>\r
+ <row>\r
+ <label id="headerName_desc" value="&headername.label;"/> \r
+ <textbox id="headerName_val" readonly="true" flex="1"/>\r
+ </row>\r
+ <row>\r
+ <label id="headerValue_desc" value="&headervalue.label;"/>\r
+ <textbox id="headerValue_val" readonly="true" flex="1"/>\r
+ </row>\r
+ <row>\r
+ <label id="headerMimeValue_desc" value="&headermimevalue.label;"/>\r
+ <textbox id="headerMimeValue_val" readonly="true" flex="1"/>\r
+ </row> \r
+ <row>\r
+ <label id="headerStatus_desc" value="&headerstatus.label;"/>\r
+ <textbox id="headerStatus_val" readonly="true" flex="1"/>\r
+ </row>\r
+ <row>\r
+ <label id="headerCanonization_desc" value="&headercanonisation.label;"/>\r
+ <textbox id="headerCanonization_val" readonly="true" flex="1"/>\r
+ </row>\r
+ </rows>\r
+ </grid>\r
+ </hbox>\r
+ </vbox>\r
+</dialog>
\ No newline at end of file
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Kai Engert <kaie@netscape.com>
+ * Copyright(c) 2011 CASSIDIAN - All rights reserved
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */
+
+const nsIPKIParamBlock = Components.interfaces.nsIPKIParamBlock;
+const nsIDialogParamBlock = Components.interfaces.nsIDialogParamBlock;
+const nsIX509Cert = Components.interfaces.nsIX509Cert;
+const nsICMSMessageErrors = Components.interfaces.nsICMSMessageErrors;
+const nsICertificateDialogs = Components.interfaces.nsICertificateDialogs;
+const nsCertificateDialogs = "@mozilla.org/nsCertificateDialogs;1"
+
+var gSignerCert = null;
+var gEncryptionCert = null;
+
+var gSignatureStatus = -1;
+var gEncryptionStatus = -1;
+
+var gSecurityPolicyIdentifier = null;
+var gSecurityClassification = -1;
+var gPrivacyMark = null;
+var gSecurityCategories = null;
+
+var gSecurityLabelConf = null;
+
+var gSecureHeaders = "";
+var gSecureHeadersState = -1;
+var params = null;
+
+function setText(id, value) {
+ var element = document.getElementById(id);
+ if (!element)
+ return;
+ if (element.hasChildNodes())
+ element.removeChild(element.firstChild);
+ var textNode = document.createTextNode(value);
+ element.appendChild(textNode);
+}
+
+function onLoad()
+{
+ var pkiParams = window.arguments[0].QueryInterface(nsIPKIParamBlock);
+ var isupport = pkiParams.getISupportAtIndex(1);
+ if (isupport) {
+ gSignerCert = isupport.QueryInterface(nsIX509Cert);
+ }
+ isupport = pkiParams.getISupportAtIndex(2);
+ if (isupport) {
+ gEncryptionCert = isupport.QueryInterface(nsIX509Cert);
+ }
+
+ params = pkiParams.QueryInterface(nsIDialogParamBlock);
+
+ gSignatureStatus = params.GetInt(1);
+ gEncryptionStatus = params.GetInt(2);
+ gSecurityClassification = params.GetInt(3);
+ gSecureHeadersState = params.GetInt(4);
+
+ gSecurityPolicyIdentifier = params.GetString(0);
+ gPrivacyMark = params.GetString(1);
+ gSecurityCategories = params.GetString(2);
+ gSecureHeaders = params.GetString(12);
+
+ if (!gSecurityLabelConf)
+ gSecurityLabelConf = new securityLabelConf();
+
+ var bundle = document.getElementById("bundle_smime_read_info");
+ var bundle_secure_headers = document.getElementById("bundle_smime_secure_headers");
+
+ if (bundle) {
+ var sigInfoLabel = null;
+ var sigInfoHeader = null;
+ var sigInfo = null;
+ var sigInfo_clueless = false;
+
+ switch (gSignatureStatus) {
+ case -1:
+ case nsICMSMessageErrors.VERIFY_NOT_SIGNED:
+ sigInfoLabel = "SINoneLabel";
+ sigInfo = "SINone";
+ break;
+
+ case nsICMSMessageErrors.SUCCESS:
+ sigInfoLabel = "SIValidLabel";
+ sigInfo = "SIValid";
+ break;
+
+
+ case nsICMSMessageErrors.VERIFY_BAD_SIGNATURE:
+ case nsICMSMessageErrors.VERIFY_DIGEST_MISMATCH:
+ sigInfoLabel = "SIInvalidLabel";
+ sigInfoHeader = "SIInvalidHeader";
+ sigInfo = "SIContentAltered";
+ break;
+
+ case nsICMSMessageErrors.VERIFY_UNKNOWN_ALGO:
+ case nsICMSMessageErrors.VERIFY_UNSUPPORTED_ALGO:
+ sigInfoLabel = "SIInvalidLabel";
+ sigInfoHeader = "SIInvalidHeader";
+ sigInfo = "SIInvalidCipher";
+ break;
+
+ case nsICMSMessageErrors.VERIFY_HEADER_MISMATCH:
+ sigInfoLabel = "SIPartiallyValidLabel";
+ sigInfoHeader = "SIPartiallyValidHeader";
+ sigInfo = "SIHeaderMismatch";
+ break;
+
+ case nsICMSMessageErrors.VERIFY_CERT_WITHOUT_ADDRESS:
+ sigInfoLabel = "SIPartiallyValidLabel";
+ sigInfoHeader = "SIPartiallyValidHeader";
+ sigInfo = "SICertWithoutAddress";
+ break;
+
+ case nsICMSMessageErrors.VERIFY_UNTRUSTED:
+ sigInfoLabel = "SIInvalidLabel";
+ sigInfoHeader = "SIInvalidHeader";
+ sigInfo = "SIUntrustedCA";
+ // XXX Need to extend to communicate better errors
+ // might also be:
+ // SIExpired SIRevoked SINotYetValid SIUnknownCA SIExpiredCA SIRevokedCA SINotYetValidCA
+ break;
+
+ case nsICMSMessageErrors.VERIFY_NOT_YET_ATTEMPTED:
+ case nsICMSMessageErrors.GENERAL_ERROR:
+ case nsICMSMessageErrors.VERIFY_NO_CONTENT_INFO:
+ case nsICMSMessageErrors.VERIFY_BAD_DIGEST:
+ case nsICMSMessageErrors.VERIFY_NOCERT:
+ case nsICMSMessageErrors.VERIFY_ERROR_UNVERIFIED:
+ case nsICMSMessageErrors.VERIFY_ERROR_PROCESSING:
+ case nsICMSMessageErrors.VERIFY_MALFORMED_SIGNATURE:
+ sigInfoLabel = "SIInvalidLabel";
+ sigInfoHeader = "SIInvalidHeader";
+ sigInfo_clueless = true;
+ break;
+ }
+
+
+ document.getElementById("signatureLabel").value =
+ bundle.getString(sigInfoLabel);
+
+ var label;
+ if (sigInfoHeader) {
+ label = document.getElementById("signatureHeader");
+ label.collapsed = false;
+ label.value = bundle.getString(sigInfoHeader);
+ }
+
+ var str;
+ if (sigInfo) {
+ str = bundle.getString(sigInfo);
+ }
+ else if (sigInfo_clueless) {
+ str = bundle.getString("SIClueless") + " (" + gSignatureStatus + ")";
+ }
+ setText("signatureExplanation", str);
+
+
+ var encInfoLabel = null;
+ var encInfoHeader = null;
+ var encInfo = null;
+ var encInfo_clueless = false;
+
+ switch (gEncryptionStatus) {
+ case -1:
+ encInfoLabel = "EINoneLabel";
+ encInfo = "EINone";
+ break;
+
+ case nsICMSMessageErrors.SUCCESS:
+ encInfoLabel = "EIValidLabel";
+ encInfo = "EIValid";
+ break;
+
+ case nsICMSMessageErrors.ENCRYPT_INCOMPLETE:
+ encInfoLabel = "EIInvalidLabel";
+ encInfo = "EIContentAltered";
+ break;
+
+ case nsICMSMessageErrors.GENERAL_ERROR:
+ encInfoLabel = "EIInvalidLabel";
+ encInfoHeader = "EIInvalidHeader";
+ encInfo_clueless = 1;
+ break;
+ }
+
+
+ document.getElementById("encryptionLabel").value =
+ bundle.getString(encInfoLabel);
+
+ if (encInfoHeader) {
+ label = document.getElementById("encryptionHeader");
+ label.collapsed = false;
+ label.value = bundle.getString(encInfoHeader);
+ }
+
+ if (encInfo) {
+ str = bundle.getString(encInfo);
+ }
+ else if (encInfo_clueless) {
+ str = bundle.getString("EIClueless");
+ }
+ setText("encryptionExplanation", str);
+ }
+
+ if (gSignerCert) {
+ document.getElementById("signatureCert").collapsed = false;
+ if (gSignerCert.subjectName) {
+ document.getElementById("signedBy").value = gSignerCert.commonName;
+ }
+ if (gSignerCert.emailAddress) {
+ document.getElementById("signerEmail").value = gSignerCert.emailAddress;
+ }
+ if (gSignerCert.issuerName) {
+ document.getElementById("sigCertIssuedBy").value = gSignerCert.issuerCommonName;
+ }
+ }
+
+ if (gEncryptionCert) {
+ document.getElementById("encryptionCert").collapsed = false;
+ if (gEncryptionCert.subjectName) {
+ document.getElementById("encryptedFor").value = gEncryptionCert.commonName;
+ }
+ if (gEncryptionCert.emailAddress) {
+ document.getElementById("recipientEmail").value = gEncryptionCert.emailAddress;
+ }
+ if (gEncryptionCert.issuerName) {
+ document.getElementById("encCertIssuedBy").value = gEncryptionCert.issuerCommonName;
+ }
+ }
+
+ if(gSecureHeaders !="" &&
+ gSignatureStatus != -1 &&
+ gSignatureStatus === nsICMSMessageErrors.SUCCESS){ //gSignatureStatus != nsICMSMessageErrors.VERIFY_NOT_SIGNED){
+ document.getElementById("secureHeaderBox").collapsed = false;
+ label = document.getElementById("secureHeadersLabel");
+ label.collapsed = false;
+ label.value = bundle_secure_headers.getString("secureInfo.secureheaders.label");
+
+ var secureStatelabel = document.getElementById("secureHeadersStateLabel");
+ secureStatelabel.hidden = false;
+ switch (gSecureHeadersState) {
+ case 1:
+ secureStatelabel.value = bundle_secure_headers.getString("allsecureheaders.valid.label");
+ break;
+ case 2:
+ secureStatelabel.value = bundle_secure_headers.getString("allsecureheaders.missing.label");
+ break;
+ case 3:
+ secureStatelabel.value = bundle_secure_headers.getString("allsecureheaders.none.label");
+ break;
+ default:
+ secureStatelabel.value = bundle_secure_headers.getString("allsecureheaders.invalid.label");
+ break;
+ }
+ } else {
+ gConsole.logStringMessage("[msgReadSecurityInfo:load] no secure headers : gSecureHeaders = " + gSecureHeaders + " - gSignatureStatus = " + gSignatureStatus);
+ document.getElementById("secureHeaderBox").collapsed = true;
+ }
+
+ if (gSecurityPolicyIdentifier != "") {
+ document.getElementById("securityLabelBox").collapsed = false;
+ document.getElementById("securityLabelSecurityPolicyIdentifierValue").value = gSecurityLabelConf.getSecurityPolicyIdentifierName(gSecurityPolicyIdentifier);
+ if (gSecurityClassification != -1) {
+ document.getElementById("securityLabelSecurityClassificationValue").value = gSecurityLabelConf.getSecurityClassificationName(gSecurityPolicyIdentifier, gSecurityClassification);
+ document.getElementById("securityLabelSecurityClassificationRow").collapsed = false;
+ }
+ if (gPrivacyMark != "") {
+ document.getElementById("securityLabelPrivacyMarkValue").value = gPrivacyMark;
+ document.getElementById("securityLabelPrivacyMarkRow").collapsed = false;
+ }
+ if (gSecurityCategories != "") {
+ var securityLabelSecurityCategoriesListBox = document.getElementById("securityLabelSecurityCategoriesListBox");
+
+ securityCategoriesArray = gSecurityCategories.split("|");
+ var listboxSize = securityCategoriesArray.length / 3;
+ if (listboxSize > 5) listboxSize = 5;
+ securityLabelSecurityCategoriesListBox.setAttribute("rows", listboxSize);
+
+ for (var i = 0; i < securityCategoriesArray.length; i += 3) {
+ var listitem = document.createElement("listitem");
+ listitem.setAttribute("label", gSecurityLabelConf.getSecurityCategoryName(gSecurityPolicyIdentifier, gSecurityClassification, securityCategoriesArray[i], securityCategoriesArray[i + 1], securityCategoriesArray[i + 2]));
+ securityLabelSecurityCategoriesListBox.appendChild(listitem);
+ }
+ document.getElementById("securityLabelSecurityCategoriesRow").collapsed = false;
+ }
+ }
+}
+
+function viewCertHelper(parent, cert) {
+ var cd = Components.classes[nsCertificateDialogs].getService(nsICertificateDialogs);
+ cd.viewCert(parent, cert);
+}
+
+function viewSignatureCert()
+{
+ if (gSignerCert) {
+ viewCertHelper(window, gSignerCert);
+ }
+}
+
+function viewEncryptionCert()
+{
+ if (gEncryptionCert) {
+ viewCertHelper(window, gEncryptionCert);
+ }
+}
+
+function doHelpButton()
+{
+ openHelp('received_security');
+}
+
+function viewSecureHeaders(){
+ if(gSecureHeaders!="")
+ {
+ window.openDialog('chrome://messenger-smime/content/msgReadSecureHeadersView.xul',
+ '', 'chrome,resizable=1,modal=1,dialog=1', params.GetString(13) );
+ }
+}
--- /dev/null
+<?xml version="1.0"?>
+<!-- This Source Code Form is subject to the terms of the Mozilla Public
+ - License, v. 2.0. If a copy of the MPL was not distributed with this
+ - file, You can obtain one at http://mozilla.org/MPL/2.0/. -->
+
+<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
+<?xml-stylesheet href="chrome://messenger/skin/smime/msgReadSecurityInfo.css" type="text/css"?>
+
+<!DOCTYPE dialog [
+ <!ENTITY % msgReadSecurityInfoDTD SYSTEM "chrome://messenger-smime/locale/msgReadSecurityInfo.dtd">
+ %msgReadSecurityInfoDTD;
+ <!ENTITY % secureheadersDTD SYSTEM "chrome://messenger/locale/secureheaders.dtd">
+ %secureheadersDTD;
+]>
+
+<dialog id="msgReadSecurityInfo" title="&status.label;"
+ xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul"
+ style="width: 40em;"
+ buttons="accept"
+ onload="onLoad();">
+
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgReadSecurityInfo.js"/>
+ <script type="application/javascript" src="chrome://messenger-smime/content/msgSecurityLabel.js"/>
+
+ <stringbundle id="bundle_smime_read_info" src="chrome://messenger-smime/locale/msgSecurityInfo.properties"/>
+ <stringbundle id="bundle_smime_secure_headers" src="chrome://messenger/locale/secureheaders.properties"/>
+
+ <vbox flex="1">
+ <label id="signatureLabel"/>
+ <label id="signatureHeader" collapsed="true"/>
+ <description id="signatureExplanation"/>
+ <vbox id="signatureCert" collapsed="true">
+ <hbox>
+ <label id="signedByLabel">&signer.name;</label>
+ <description id="signedBy"/>
+ </hbox>
+ <hbox>
+ <label id="signerEmailLabel">&email.address;</label>
+ <description id="signerEmail"/>
+ </hbox>
+ <hbox>
+ <label id="sigCertIssuedByLabel">&issuer.name;</label>
+ <description id="sigCertIssuedBy"/>
+ </hbox>
+ <hbox>
+ <button id="signatureCertView" label="&signatureCert.label;"
+ oncommand="viewSignatureCert()"/>
+ </hbox>
+ </vbox>
+
+ <separator/>
+
+ <label id="encryptionLabel"/>
+ <label id="encryptionHeader" collapsed="true"/>
+ <description id="encryptionExplanation"/>
+ <vbox id="encryptionCert" collapsed="true">
+ <hbox>
+ <label id="encryptedForLabel">&recipient.name;</label>
+ <description id="encryptedFor"/>
+ </hbox>
+ <hbox>
+ <label id="recipientEmailLabel">&email.address;</label>
+ <description id="recipientEmail"/>
+ </hbox>
+ <hbox>
+ <label id="encCertIssuedByLabel">&issuer.name;</label>
+ <description id="encCertIssuedBy"/>
+ </hbox>
+ <hbox>
+ <button id="encryptionCertView" label="&encryptionCert.label;"
+ oncommand="viewEncryptionCert()"/>
+ </hbox>
+ </vbox>
+
+ <vbox id="securityLabelBox" collapsed="true">
+ <separator/>
+ <label id="securityLabel">&securityLabel.name;</label>
+ <grid id="securityLabelContent" flex="1">
+ <columns>
+ <column />
+ <column flex="1"/>
+ </columns>
+ <rows>
+ <row align="center">
+ <label id="securityLabelSecurityPolicyIdentifierLabel" value="&securityLabel.securityPolicyIdentifier.name;"/>
+ <description id="securityLabelSecurityPolicyIdentifierValue"/>
+ </row>
+ <row align="center" id="securityLabelPrivacyMarkRow" collapsed="true">
+ <label id="securityLabelPrivacyMarkLabel" value="&securityLabel.privacyMark.name;"/>
+ <description id="securityLabelPrivacyMarkValue"/>
+ </row>
+ <row align="center" id="securityLabelSecurityClassificationRow" collapsed="true">
+ <label id="securityLabelSecurityClassificationLabel" value="&securityLabel.securityClassification.name;"/>
+ <description id="securityLabelSecurityClassificationValue"/>
+ </row>
+ <row align="center" id="securityLabelSecurityCategoriesRow" collapsed="true">
+ <label id="securityLabelSecurityCategoriesLabel" value="&securityLabel.securityCategories.name;"/>
+ <listbox id="securityLabelSecurityCategoriesListBox" flex="1"/>
+ </row>
+ </rows>
+ </grid>
+ </vbox>
+
+ <vbox id="secureHeaderBox" collapsed="true">
+ <separator/>
+ <label id="secureHeadersLabel" style="font-weight: bold;"/>
+ <hbox>
+ <button id="secureHeadersView" label="&secureHeadersView.label;"
+ oncommand="viewSecureHeaders()"/>
+ <label id="secureHeadersStateLabel" hidden="true"/>
+ </hbox>
+ </vbox>
+ </vbox>
+</dialog>
--- /dev/null
+/* ***** 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 "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
+ * BT Global Services / Etat francais - Ministere de la Defense.
+ * Portions created by the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ *
+ * 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 ***** */
+
+
+function securityLabelConf() {
+ this.readProfiles();
+}
+
+securityLabelConf.prototype = {
+
+ mSecurityPolicyList: [],
+ mSecurityClassificationList: [],
+ mPrivacyMarkList: [],
+ mSecurityCategoriesList: [],
+
+ stringBundle: Components.classes["@mozilla.org/intl/stringbundle;1"]
+ .getService(Components.interfaces.nsIStringBundleService)
+ .createBundle("chrome://messenger-smime/locale/msgSecurityLabel.properties"),
+
+ /**
+ * Read Security Label profiles in %profile%/securityLabel/ directory
+ */
+ readProfiles: function() {
+
+ /* Reset lists */
+ this.mSecurityPolicyList = [];
+ this.mSecurityClassificationList = [];
+ this.mPrivacyMarkList = [];
+ this.mSecurityCategoriesList = [];
+
+ /* Get profile directory */
+ var dir = Components.classes["@mozilla.org/file/directory_service;1"]
+ .createInstance(Components.interfaces.nsIProperties)
+ .get("ProfD", Components.interfaces.nsIFile);
+ dir.append("securityLabel");
+
+ /* Copy a default profile if needed */
+ if (!dir.exists()) {
+ dir.create(Components.interfaces.nsIFile.DIRECTORY_TYPE, 0755);
+ var defaultFile = Components.classes["@mozilla.org/file/directory_service;1"]
+ .createInstance(Components.interfaces.nsIProperties)
+ .get("ProfDefNoLoc", Components.interfaces.nsIFile);
+ defaultFile.append("securityLabelPolicy-sample.xml");
+ if (defaultFile.exists())
+ defaultFile.copyTo(dir, "default.xml");
+ }
+
+ if (dir.isDirectory()) {
+ /* Read directory contents */
+ var entries = dir.directoryEntries;
+ var dirList = [];
+ while (entries.hasMoreElements()) {
+ var entry = entries.getNext();
+ entry.QueryInterface(Components.interfaces.nsIFile);
+ dirList.push(entry);
+ }
+
+ for (var i in dirList) {
+ try {
+ if (dirList[i].isFile() && dirList[i].leafName.match(/\.xml$/) != null) {
+
+ /* Read file */
+ var fiStream = Components.classes["@mozilla.org/network/file-input-stream;1"]
+ .createInstance(Components.interfaces.nsIFileInputStream);
+ var siStream = Components.classes["@mozilla.org/scriptableinputstream;1"]
+ .createInstance(Components.interfaces.nsIScriptableInputStream);
+ fiStream.init(dirList[i], 1, 0, false);
+ siStream.init(fiStream);
+ var data = new String();
+ data += siStream.read(-1);
+ siStream.close();
+ fiStream.close();
+ var uniConv = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"]
+ .createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
+ uniConv.charset = "UTF-8";
+ var fileContents = uniConv.ConvertToUnicode(data);
+
+ if (fileContents != false) {
+ /* Parse file contents */
+ var domParser = new DOMParser();
+ var dom = domParser.parseFromString(fileContents, "text/xml");
+ if (dom.documentElement.nodeName == "securityLabel") {
+ var policy = this.parseSecurityPolicyIdentifier(dom);
+ if (policy) {
+ this.mSecurityPolicyList[policy[0]] = policy[1];
+ this.mSecurityClassificationList[policy[0]] = this.parseSecurityClassification(dom);
+ this.mPrivacyMarkList[policy[0]] = this.parsePrivacyMark(dom);
+ this.mSecurityCategoriesList[policy[0]] = this.parseSecurityCategories(dom);
+ }
+ }
+ }
+ }
+ } catch (e) {
+ dump("S/MIME Security Label: error while reading " + dirList[i].leafName + "\n");
+ }
+ }
+ }
+ },
+
+ parseSecurityPolicyIdentifier: function(aDom) {
+ var nodeList = aDom.getElementsByTagName("securityPolicyIdentifier");
+ if (nodeList.length == 1) {
+ var node = nodeList.item(0);
+ var label = node.getAttribute("label").trim();
+ var value = node.getAttribute("value").trim();
+ if (label != "" && value != "")
+ return [label, value];
+ }
+
+ return false;
+ },
+
+ parseSecurityClassification: function(aDom) {
+ var list = [];
+
+ var nodeList1 = aDom.getElementsByTagName("securityClassification");
+ if (nodeList1.length == 1) {
+ var node = nodeList1.item(0);
+ var displayValue = node.getAttribute("valueDisplayed");
+ if (node.hasChildNodes()) {
+ var nodeList2 = node.childNodes;
+ for (var i = 0; i < nodeList2.length; i++) {
+ var itemNode = nodeList2.item(i);
+ if (itemNode.nodeName == "item") {
+ var label = itemNode.getAttribute("label").trim();
+ var value = itemNode.getAttribute("value").trim();
+ value = parseInt(value,10);
+ if (label != "" && value >= 0 && value <= 256) {
+ if (displayValue != "false" && displayValue != "0")
+ label += " (" + value + ")";
+ list[label] = value;
+ }
+ }
+ }
+ }
+ }
+
+ return list;
+ },
+
+ parsePrivacyMark: function(aDom) {
+ var list = [];
+
+ var nodeList1 = aDom.getElementsByTagName("privacyMark");
+ if (nodeList1.length == 1) {
+ var node = nodeList1.item(0);
+ var freeText = node.getAttribute("freeText");
+ if (freeText != "false" && freeText != "0")
+ list["freeText"] = true;
+ else
+ list["freeText"] = false;
+ if (node.hasChildNodes()) {
+ var nodeList2 = node.childNodes;
+ for (var i = 0; i < nodeList2.length; i++) {
+ var itemNode = nodeList2.item(i);
+ if (itemNode.nodeName == "item") {
+ var value = itemNode.getAttribute("value").trim();
+ list.push(value);
+ }
+ }
+ }
+ }
+
+ return list;
+ },
+
+ parseSecurityCategories: function(aDom) {
+ var list = [];
+
+ var nodeList1 = aDom.getElementsByTagName("securityCategories");
+ for (var k = 0; k < nodeList1.length; k++) {
+ var node = nodeList1.item(k);
+ var securityClassificationValue = "all";
+ if (node.hasAttribute("securityClassificationValue"))
+ securityClassificationValue = node.getAttribute("securityClassificationValue").trim();
+
+ if (node.hasChildNodes()) {
+ var nodeList2 = node.childNodes;
+ for (var i = 0; i < nodeList2.length; i++) {
+ var itemNode = nodeList2.item(i);
+ if (itemNode.nodeName == "item") {
+ var label = itemNode.getAttribute("label").trim();
+ var oid = itemNode.getAttribute("oid").replace(/\|/g, "").trim();
+ var type = itemNode.getAttribute("type").replace(/\|/g, "").trim();
+ var value = itemNode.getAttribute("value").replace(/\|/g, "").trim();
+ if (label != "" && oid != "" && type != "" && value != "") {
+ if (list[securityClassificationValue] == undefined)
+ list[securityClassificationValue] = new Array();
+ list[securityClassificationValue][label] = [oid, type, value];
+ }
+ }
+ }
+ }
+ }
+
+ return list;
+ },
+
+ /**
+ * Get Human-readable Security Policy Identifier
+ * @param aSecurityPolicyIdentifier String with Policy Identifier OID
+ * @return String with the name of the Policy Identifier
+ */
+ getSecurityPolicyIdentifierName: function(aSecurityPolicyIdentifier) {
+ if (aSecurityPolicyIdentifier == undefined || aSecurityPolicyIdentifier == "")
+ return "";
+
+ for (policyName in this.mSecurityPolicyList)
+ if (this.mSecurityPolicyList[policyName] == aSecurityPolicyIdentifier)
+ return policyName;
+
+ return this.stringBundle.GetStringFromName("unknownSecurityPolicyIdentifier") +" (" + aSecurityPolicyIdentifier + ")";
+ },
+
+ /**
+ * Get Human-readable Security Classification value
+ * @param aSecurityPolicyIdentifier String with Policy Identifier OID
+ * @param aSecurityClassification Classification value
+ * @return String with the name and value of the Security Classification
+ */
+ getSecurityClassificationName: function(aSecurityPolicyIdentifier, aSecurityClassification) {
+ if (aSecurityPolicyIdentifier == undefined || aSecurityClassification == undefined)
+ return "";
+
+ var securityPolicyIdentifierName = this.getSecurityPolicyIdentifierName(aSecurityPolicyIdentifier);
+
+ if (this.mSecurityClassificationList[securityPolicyIdentifierName] != undefined)
+ for (classificationName in this.mSecurityClassificationList[securityPolicyIdentifierName])
+ if (this.mSecurityClassificationList[securityPolicyIdentifierName][classificationName] == aSecurityClassification)
+ return classificationName;
+
+ return this.stringBundle.GetStringFromName("unknownSecurityClassification") + " (" + aSecurityClassification + ")";
+ },
+
+ /**
+ * Get Human-readable Security Category value
+ * @param aSecurityPolicyIdentifier String with Policy Identifier OID
+ * @param aSecurityClassification Classification value
+ * @param aSecurityCategoryOid Category OID
+ * @param aSecurityCategoryType Category type
+ * @param aSecurityCategoryValue Category value
+ * @return String with the name of the Security Category
+ */
+ getSecurityCategoryName: function(aSecurityPolicyIdentifier, aSecurityClassification, aSecurityCategoryOid, aSecurityCategoryType, aSecurityCategoryValue) {
+ if (aSecurityPolicyIdentifier == undefined || aSecurityClassification == undefined || aSecurityCategoryOid == undefined || aSecurityCategoryType == undefined || aSecurityCategoryValue == undefined)
+ return "";
+
+ var securityPolicyIdentifierName = this.getSecurityPolicyIdentifierName(aSecurityPolicyIdentifier);
+
+ if (this.mSecurityCategoriesList[securityPolicyIdentifierName] != undefined) {
+ for (var i = 0; i < 2; i++) {
+ var list;
+ /* Security Categories for all classifications */
+ if (i == 0)
+ list = this.mSecurityCategoriesList[securityPolicyIdentifierName]["all"];
+ /* Security Categories for selected classification */
+ if (i == 1)
+ list = this.mSecurityCategoriesList[securityPolicyIdentifierName][aSecurityClassification.toString()];
+
+ for (securityCategoryName in list)
+ if (list[securityCategoryName][0] == aSecurityCategoryOid && list[securityCategoryName][1] == aSecurityCategoryType && list[securityCategoryName][2] == aSecurityCategoryValue)
+ return securityCategoryName;
+ }
+ }
+
+ return this.stringBundle.GetStringFromName("unknownSecurityCategory") + " (" + aSecurityCategoryOid + " | " + aSecurityCategoryValue + ")";
+ }
+}
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ Add any default pref values we want for smime
+*/
+
+pref("mail.identity.default.encryption_cert_name","");
+pref("mail.identity.default.encryptionpolicy", 0);
+pref("mail.identity.default.signing_cert_name", "");
+pref("mail.identity.default.sign_mail", false);
+pref("mail.identity.default.smime_receipt_request", false);
+pref("mail.identity.default.smime_receipt_send_policy", 0); /* 0: ask 1: never 2: always */
+
+
--- /dev/null
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+#ifdef MOZ_SUITE
+messenger.jar:
+% content messenger-smime %content/messenger-smime/
+% overlay chrome://messenger/content/messengercompose/messengercompose.xul chrome://messenger-smime/content/msgCompSMIMEOverlay.xul
+% overlay chrome://messenger/content/msgHdrViewOverlay.xul chrome://messenger-smime/content/msgHdrViewSMIMEOverlay.xul
+% overlay chrome://messenger/content/mailWindowOverlay.xul chrome://messenger-smime/content/msgReadSMIMEOverlay.xul
+% overlay chrome://messenger/content/am-identity-edit.xul chrome://messenger/content/am-smimeIdentityEditOverlay.xul
+ content/messenger/am-smime.xul (content/am-smime.xul)
+ content/messenger/am-smime.js (content/am-smime.js)
+ content/messenger/am-smimeIdentityEditOverlay.xul (content/am-smimeIdentityEditOverlay.xul)
+ content/messenger/am-smimeOverlay.xul (content/am-smimeOverlay.xul)
+ content/messenger-smime/msgCompSMIMEOverlay.js (content/msgCompSMIMEOverlay.js)
+ content/messenger-smime/msgCompSMIMEOverlay.xul (content/msgCompSMIMEOverlay.xul)
+ content/messenger-smime/msgReadSMIMEOverlay.js (content/msgReadSMIMEOverlay.js)
+ content/messenger-smime/msgReadSMIMEOverlay.xul (content/msgReadSMIMEOverlay.xul)
+ content/messenger-smime/msgHdrViewSMIMEOverlay.xul (content/msgHdrViewSMIMEOverlay.xul)
+ content/messenger-smime/msgHdrViewSMIMEOverlay.js (content/msgHdrViewSMIMEOverlay.js)
+ content/messenger-smime/msgCompSecurityInfo.xul (content/msgCompSecurityInfo.xul)
+ content/messenger-smime/msgCompSecurityInfo.js (content/msgCompSecurityInfo.js)
+ content/messenger-smime/msgReadSecurityInfo.xul (content/msgReadSecurityInfo.xul)
+ content/messenger-smime/msgReadSecurityInfo.js (content/msgReadSecurityInfo.js)
+ content/messenger-smime/certFetchingStatus.xul (content/certFetchingStatus.xul)
+ content/messenger-smime/certFetchingStatus.js (content/certFetchingStatus.js)
+ content/messenger-smime/msgSecurityLabel.js (content/msgSecurityLabel.js)
+ content/messenger-smime/msgCompSecurityLabelDialog.xul (content/msgCompSecurityLabelDialog.xul)
+ content/messenger-smime/msgCompSecurityLabelDialog.js (content/msgCompSecurityLabelDialog.js)
+ content/messenger-smime/msgCompSMIMESecureHeaders.js (content/msgCompSMIMESecureHeaders.js)
+ content/messenger-smime/msgReadSecureHeadersView.xul (content/msgReadSecureHeadersView.xul)
+ content/messenger-smime/msgReadSecureHeadersView.js (content/msgReadSecureHeadersView.js)
+#endif
\ No newline at end of file
--- /dev/null
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+XPIDL_SOURCES += [
+ 'nsIEncryptedSMIMEURIsSrvc.idl',
+ 'nsIMsgSMIMECompFields.idl',
+ 'nsIMsgSMIMEHeaderSink.idl',
+ 'nsIMsgSMIMEReceiptGenerator.idl',
+ 'nsIMsgSMIMESecureHeader.idl',
+ 'nsISMimeJSHelper.idl',
+]
+
+MODULE = 'msgsmime'
+
--- /dev/null
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Scott MacGregor <mscott@netscape.com>
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved */
+
+
+/* This is a private interface used exclusively by SMIME. NO ONE outside of extensions/smime
+ should have any knowledge nor should be referring to this interface.
+*/
+
+#include "nsISupports.idl"
+
+[ptr] native UnsignedCharPtr(unsigned char);
+
+interface nsIMsgSMIMESecureHeader;
+interface nsIMutableArray;
+
+[scriptable, uuid(338E91F9-5970-4f81-B771-0822A32B1161)]
+interface nsIMsgSMIMECompFields : nsISupports
+{
+ attribute boolean signMessage;
+ attribute boolean requireEncryptMessage;
+ attribute boolean SMIMEReceiptRequest;
+ attribute boolean SMIMEReceipt;
+ [noscript] attribute UnsignedCharPtr SMIMEReceiptSignedContentIdentifier;
+ attribute unsigned long SMIMEReceiptSignedContentIdentifierLen;
+ [noscript] attribute UnsignedCharPtr SMIMEReceiptOriginatorSignatureValue;
+ attribute unsigned long SMIMEReceiptOriginatorSignatureValueLen;
+ [noscript] attribute UnsignedCharPtr SMIMEReceiptOriginatorContentType;
+ attribute unsigned long SMIMEReceiptOriginatorContentTypeLen;
+ [noscript] attribute UnsignedCharPtr SMIMEReceiptMsgSigDigest;
+ attribute unsigned long SMIMEReceiptMsgSigDigestLen;
+
+ attribute AString securityPolicyIdentifier;
+ attribute long securityClassification;
+ attribute AString privacyMark;
+ attribute AString securityCategories;
+
+ attribute long canonAlgorithme;
+ void addSecureHeader(in nsIMsgSMIMESecureHeader secureHeader);
+ void clearSecureHeaders();
+ void getSecureHeadersList(out nsIMutableArray secureHeadersList);
+
+};
--- /dev/null
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Scott MacGregor <mscott@netscape.com>
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved */
+
+
+/* This is a private interface used exclusively by SMIME. NO ONE outside of extensions/smime
+ or the hard coded smime decryption files in mime/src should have any knowledge nor should
+ be referring to this interface.
+*/
+
+#include "nsISupports.idl"
+
+interface nsIX509Cert;
+interface nsIMutableArray;
+
+[scriptable, uuid(25380FA1-E70C-4e82-B0BC-F31C2F41C470)]
+interface nsIMsgSMIMEHeaderSink : nsISupports
+{
+ void signedStatus(in long aNestingLevel, in long aSignatureStatus, in nsIX509Cert aSignerCert);
+ void encryptionStatus(in long aNestingLevel, in long aEncryptionStatus, in nsIX509Cert aReceipientCert);
+ void SMIMEReceiptRequestStatus([const,array,size_is(aSignedContentIdentifierLen)] in octet aSignedContentIdentifier,
+ in unsigned long aSignedContentIdentifierLen,
+ in unsigned long aReceiptsFrom,
+ in AString aReceiptsTo,
+ [const,array,size_is(aOriginatorSignatureValueLen)] in octet aOriginatorSignatureValue,
+ in unsigned long aOriginatorSignatureValueLen,
+ [const,array,size_is(aOriginatorContentTypeLen)] in octet aOriginatorContentType,
+ in unsigned long aOriginatorContentTypeLen,
+ [const,array,size_is(aMsgSigDigestLen)] in octet aMsgSigDigest,
+ in unsigned long aMsgSigDigestLen);
+ void SMIMEReceiptStatus([const,array,size_is(aSignedContentIdentifierLen)] in octet aSignedContentIdentifier,
+ in unsigned long aSignedContentIdentifierLen,
+ [const,array,size_is(aOriginatorSignatureValueLen)] in octet aOriginatorSignatureValue,
+ in unsigned long aOriginatorSignatureValueLen,
+ [const,array,size_is(aOriginatorContentTypeLen)] in octet aOriginatorContentType,
+ in unsigned long aOriginatorContentTypeLen,
+ [const,array,size_is(aMsgSigDigestLen)] in octet aMsgSigDigest,
+ in unsigned long aMsgSigDigestLen);
+
+ void secureHeadersStatus(in nsIMutableArray aSecureHeaders, in long canonAlgo);
+
+ void securityLabelStatus(in AString aSecurityPolicyIdentifier,
+ in long aSecurityClassification,
+ in AString aPrivacyMark,
+ in AString aSecurityCategories);
+
+ long maxWantedNesting(); // 1 == only info on outermost nesting level wanted
+};
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 "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 the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+#include "nsISupports.idl"
+#include "MailNewsTypes2.idl"
+
+interface nsIMsgWindow;
+interface nsIMsgFolder;
+interface nsIMimeHeaders;
+
+[scriptable, uuid(5547f653-6adc-4a01-8467-036fce6fc83b)]
+interface nsIMsgSMIMEReceiptGenerator : nsISupports
+{
+ boolean process(in nsIMsgWindow aWindow,
+ in nsIMsgFolder aFolder,
+ in nsMsgKey aKey,
+ in nsIMimeHeaders aHeaders,
+ [array,size_is(aSignedContentIdentifierLen)] in octet aSignedContentIdentifier,
+ in unsigned long aSignedContentIdentifierLen,
+ in unsigned long aReceiptsFrom,
+ in AString aReceiptsTo,
+ [array,size_is(aOriginatorSignatureValueLen)] in octet aOriginatorSignatureValue,
+ in unsigned long aOriginatorSignatureValueLen,
+ [array,size_is(aOriginatorContentTypeLen)] in octet aOriginatorContentType,
+ in unsigned long aOriginatorContentTypeLen,
+ [array,size_is(aMsgSigDigestLen)] in octet aMsgSigDigest,
+ in unsigned long aMsgSigDigestLen);
+
+ void userAgreed();
+ void userDeclined();
+};
--- /dev/null
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved. */
+
+#include "nsISupports.idl"
+
+// {A1BBE613-DA57-4766-84F0-343DAAFF6EB2}
+//static const GUID <<name>> =
+//{ 0xa1bbe613, 0xda57, 0x4766, { 0x84, 0xf0, 0x34, 0x3d, 0xaa, 0xff, 0x6e, 0xb2 } };
+
+[scriptable, uuid(A1BBE613-DA57-4766-84F0-343DAAFF6EB2)]
+interface nsIMsgSMIMESecureHeader : nsISupports
+{
+ attribute AString headerName;
+ attribute AString headerValue;
+ attribute long headerStatus;
+ attribute long headerEncrypted;
+};
\ No newline at end of file
--- /dev/null
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+DEPTH = @DEPTH@
+topsrcdir = @top_srcdir@
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+include $(DEPTH)/config/autoconf.mk
+
+LIBRARY_NAME = msgsmime_s
+ifndef MOZ_INCOMPLETE_EXTERNAL_LINKAGE
+MOZILLA_INTERNAL_API = 1
+LIBXUL_LIBRARY = 1
+endif
+
+
+FORCE_STATIC_LIB = 1
+
+include $(topsrcdir)/config/rules.mk
+
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * David Drinan <ddrinan@netscape.com>
+ * Stephane Saux <ssaux@netscape.com>
+ * ESS Signed Receipts: Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ * Secure headers : Copyright (c) 2011 CASSIDIAN - All rights reserved
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */
+
+#include "nsMsgComposeSecure.h"
+
+#include "msgCore.h"
+#include "nsIMsgCompFields.h"
+#include "nsIMsgHeaderParser.h"
+#include "nsIMsgIdentity.h"
+#include "nsISMimeCert.h"
+#include "nsIX509CertDB.h"
+#include "nsMimeTypes.h"
+#include "nsMsgMimeCID.h"
+#include "nsMsgCompCID.h"
+#include "nspr.h"
+#include "nsComponentManagerUtils.h"
+#include "nsServiceManagerUtils.h"
+#include "nsMemory.h"
+#include "nsAlgorithm.h"
+#include "nsIMsgCompUtils.h"
+#include "mozilla/Services.h"
+#include "mozilla/mailnews/MimeEncoder.h"
+#include <algorithm>
+#include "nsVoidArray.h"
+#include "nsArrayUtils.h"
+
+using mozilla::mailnews::MimeEncoder;
+
+// 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 MIME_SMIME_RECEIPT_CONTENT_DESCRIPTION "S/MIME Receipt"
+
+#define MK_MIME_ERROR_WRITING_FILE -1
+
+#define SMIME_STRBUNDLE_URL "chrome://messenger/locale/am-smime.properties"
+
+// It doesn't make sense to encode the message because the message will be
+// displayed only if the MUA doesn't support MIME.
+// We need to consider what to do in case the server doesn't support 8BITMIME.
+// In short, we can't use non-ASCII characters here.
+static const char crypto_multipart_blurb[] = "This is a cryptographically signed message in MIME format.";
+
+static void mime_crypto_write_base64 (void *closure, const char *buf,
+ unsigned long size);
+static nsresult mime_encoder_output_fn(const char *buf, int32_t size,
+ void *closure);
+static nsresult mime_nested_encoder_output_fn(const char *buf, int32_t size,
+ void *closure);
+static nsresult make_multipart_signed_header_string(bool outer_p,
+ char **header_return,
+ char **boundary_return);
+static char *mime_make_separator(const char *prefix);
+
+
+static void
+GenerateGlobalRandomBytes(unsigned char *buf, int32_t len)
+{
+ static bool firstTime = true;
+
+ if (firstTime)
+ {
+ // Seed the random-number generator with current time so that
+ // the numbers will be different every time we run.
+ srand( (unsigned)PR_Now() );
+ firstTime = false;
+ }
+
+ for( int32_t 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 nsMsgSMIMESecureHeader
+/////////////////////////////////////////////////////////////////////////////////////////
+NS_IMPL_ISUPPORTS1(nsMsgSMIMESecureHeader, nsIMsgSMIMESecureHeader)
+
+nsMsgSMIMESecureHeader::nsMsgSMIMESecureHeader():mHeaderStatus(-1),mHeaderEncrypted(-1)
+{
+
+}
+
+nsMsgSMIMESecureHeader::~nsMsgSMIMESecureHeader()
+{
+}
+
+NS_IMETHODIMP nsMsgSMIMESecureHeader::SetHeaderName( const nsAString & value)
+{
+ mHeaderName = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMESecureHeader::GetHeaderName( nsAString & _retval)
+{
+ _retval=mHeaderName;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMESecureHeader::SetHeaderValue( const nsAString & value)
+{
+ mHeaderValue = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMESecureHeader::GetHeaderValue( nsAString & _retval)
+{
+ _retval=mHeaderValue;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMESecureHeader::SetHeaderStatus( int value )
+{
+ mHeaderStatus=value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMESecureHeader::GetHeaderStatus(int * _retval)
+{
+ *_retval=mHeaderStatus;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMESecureHeader::SetHeaderEncrypted( int value )
+{
+ mHeaderEncrypted=value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMESecureHeader::GetHeaderEncrypted(int * _retval)
+{
+ *_retval = mHeaderEncrypted;
+ return NS_OK;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Implementation of nsMsgSMIMEComposeFields
+/////////////////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_ISUPPORTS1(nsMsgSMIMEComposeFields, nsIMsgSMIMECompFields)
+
+nsMsgSMIMEComposeFields::nsMsgSMIMEComposeFields()
+:mSignMessage(false), mAlwaysEncryptMessage(false),
+mSMIMEReceiptRequest(PR_FALSE),
+mSMIMEReceipt(PR_FALSE),
+mSMIMEReceiptSignedContentIdentifierLen(0),
+mSMIMEReceiptOriginatorSignatureValueLen(0),
+mSMIMEReceiptOriginatorContentTypeLen(0),
+mSMIMEReceiptMsgSigDigestLen(0),
+mCanonAlgorithme(0),
+mSecurityClassification(-1)
+{
+ nsresult rv;
+ m_secureHeaders = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+}
+
+nsMsgSMIMEComposeFields::~nsMsgSMIMEComposeFields()
+{
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSignMessage(bool value)
+{
+ mSignMessage = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSignMessage(bool *_retval)
+{
+ *_retval = mSignMessage;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetRequireEncryptMessage(bool value)
+{
+ mAlwaysEncryptMessage = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetRequireEncryptMessage(bool *_retval)
+{
+ *_retval = mAlwaysEncryptMessage;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSMIMEReceiptRequest(bool value)
+{
+ mSMIMEReceiptRequest = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSMIMEReceiptRequest(bool *_retval)
+{
+ *_retval = mSMIMEReceiptRequest;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSMIMEReceipt(bool value)
+{
+ mSMIMEReceipt = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSMIMEReceipt(bool *_retval)
+{
+ *_retval = mSMIMEReceipt;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSMIMEReceiptSignedContentIdentifier(unsigned char *value)
+{
+ mSMIMEReceiptSignedContentIdentifier = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSMIMEReceiptSignedContentIdentifier(unsigned char **_retval)
+{
+ *_retval = mSMIMEReceiptSignedContentIdentifier;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSMIMEReceiptSignedContentIdentifierLen(uint32_t value)
+{
+ mSMIMEReceiptSignedContentIdentifierLen = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSMIMEReceiptSignedContentIdentifierLen(uint32_t *_retval)
+{
+ *_retval = mSMIMEReceiptSignedContentIdentifierLen;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSMIMEReceiptOriginatorSignatureValue(unsigned char *value)
+{
+ mSMIMEReceiptOriginatorSignatureValue = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSMIMEReceiptOriginatorSignatureValue(unsigned char **_retval)
+{
+ *_retval = mSMIMEReceiptOriginatorSignatureValue;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSMIMEReceiptOriginatorSignatureValueLen(uint32_t value)
+{
+ mSMIMEReceiptOriginatorSignatureValueLen = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSMIMEReceiptOriginatorSignatureValueLen(uint32_t *_retval)
+{
+ *_retval = mSMIMEReceiptOriginatorSignatureValueLen;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSMIMEReceiptOriginatorContentType(unsigned char *value)
+{
+ mSMIMEReceiptOriginatorContentType = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSMIMEReceiptOriginatorContentType(unsigned char **_retval)
+{
+ *_retval = mSMIMEReceiptOriginatorContentType;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSMIMEReceiptOriginatorContentTypeLen(uint32_t value)
+{
+ mSMIMEReceiptOriginatorContentTypeLen = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSMIMEReceiptOriginatorContentTypeLen(uint32_t *_retval)
+{
+ *_retval = mSMIMEReceiptOriginatorContentTypeLen;
+ return NS_OK;
+}
+
+//Secure Headers
+NS_IMETHODIMP nsMsgSMIMEComposeFields::AddSecureHeader(nsIMsgSMIMESecureHeader * secureHeader)
+{
+ nsresult rv = NS_OK;
+
+ if (!secureHeader)
+ return NS_ERROR_FAILURE;
+ rv=m_secureHeaders->AppendElement(secureHeader,PR_FALSE);
+ return rv;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSecureHeadersList(nsIMutableArray ** _SecureHeaders)
+{
+ *_SecureHeaders=m_secureHeaders;
+ NS_ADDREF(*_SecureHeaders);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::ClearSecureHeaders()
+{
+ if(m_secureHeaders)
+ {
+ m_secureHeaders->Clear();
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetCanonAlgorithme(int32_t value)
+{
+ mCanonAlgorithme=value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetCanonAlgorithme(int32_t * retval)
+{
+ *retval = mCanonAlgorithme;
+ return NS_OK;
+}
+//
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSMIMEReceiptMsgSigDigest(unsigned char *value)
+{
+ mSMIMEReceiptMsgSigDigest = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSMIMEReceiptMsgSigDigest(unsigned char **_retval)
+{
+ *_retval = mSMIMEReceiptMsgSigDigest;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSMIMEReceiptMsgSigDigestLen(uint32_t value)
+{
+ mSMIMEReceiptMsgSigDigestLen = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSMIMEReceiptMsgSigDigestLen(uint32_t *_retval)
+{
+ *_retval = mSMIMEReceiptMsgSigDigestLen;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSecurityPolicyIdentifier(const nsAString &value)
+{
+ mSecurityPolicyIdentifier = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSecurityPolicyIdentifier(nsAString &_retval)
+{
+ _retval = mSecurityPolicyIdentifier;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSecurityClassification(int32_t value)
+{
+ mSecurityClassification = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSecurityClassification(int32_t *_retval)
+{
+ *_retval = mSecurityClassification;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetPrivacyMark(const nsAString &value)
+{
+ mPrivacyMark = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetPrivacyMark(nsAString &_retval)
+{
+ _retval = mPrivacyMark;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::SetSecurityCategories(const nsAString &value)
+{
+ mSecurityCategories = value;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEComposeFields::GetSecurityCategories(nsAString &_retval)
+{
+ _retval = mSecurityCategories;
+ return NS_OK;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////
+// Implementation of nsMsgComposeSecure
+/////////////////////////////////////////////////////////////////////////////////////////
+
+NS_IMPL_ISUPPORTS1(nsMsgComposeSecure, nsIMsgComposeSecure)
+
+nsMsgComposeSecure::nsMsgComposeSecure()
+{
+ /* member initializers and constructor code */
+ mMultipartSignedBoundary = 0;
+ mBuffer = 0;
+ mBufferedBytes = 0;
+ mCanonAlgorithme=0;
+ mHasSecuritylabel = PR_FALSE;
+ mSecurityClassification = -1;
+}
+
+nsMsgComposeSecure::~nsMsgComposeSecure()
+{
+ /* destructor code */
+ if (mEncryptionContext) {
+ if (mBufferedBytes) {
+ mEncryptionContext->Update(mBuffer, mBufferedBytes);
+ mBufferedBytes = 0;
+ }
+ mEncryptionContext->Finish();
+ }
+
+ delete [] mBuffer;
+
+ PR_FREEIF(mMultipartSignedBoundary);
+}
+
+NS_IMETHODIMP nsMsgComposeSecure::RequiresCryptoEncapsulation(nsIMsgIdentity * aIdentity, nsIMsgCompFields * aCompFields, bool * aRequiresEncryptionWork)
+{
+ NS_ENSURE_ARG_POINTER(aRequiresEncryptionWork);
+
+ *aRequiresEncryptionWork = false;
+
+ bool alwaysEncryptMessages = false;
+ bool signMessage = false;
+ nsresult rv = ExtractEncryptionState(aIdentity, aCompFields, &signMessage, &alwaysEncryptMessages);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (alwaysEncryptMessages || signMessage)
+ *aRequiresEncryptionWork = true;
+
+ return NS_OK;
+}
+
+
+nsresult nsMsgComposeSecure::GetSMIMEBundleString(const PRUnichar *name,
+ PRUnichar **outString)
+{
+ *outString = nullptr;
+
+ NS_ENSURE_ARG_POINTER(name);
+
+ NS_ENSURE_TRUE(InitializeSMIMEBundle(), NS_ERROR_FAILURE);
+
+ return mSMIMEBundle->GetStringFromName(name, outString);
+}
+
+nsresult
+nsMsgComposeSecure::
+SMIMEBundleFormatStringFromName(const PRUnichar *name,
+ const PRUnichar **params,
+ uint32_t numParams,
+ PRUnichar **outString)
+{
+ NS_ENSURE_ARG_POINTER(name);
+
+ if (!InitializeSMIMEBundle())
+ return NS_ERROR_FAILURE;
+
+ return mSMIMEBundle->FormatStringFromName(name, params,
+ numParams, outString);
+}
+
+bool nsMsgComposeSecure::InitializeSMIMEBundle()
+{
+ if (mSMIMEBundle)
+ return true;
+
+ nsCOMPtr<nsIStringBundleService> bundleService =
+ mozilla::services::GetStringBundleService();
+ nsresult rv = bundleService->CreateBundle(SMIME_STRBUNDLE_URL,
+ getter_AddRefs(mSMIMEBundle));
+ NS_ENSURE_SUCCESS(rv, false);
+
+ return true;
+}
+
+void nsMsgComposeSecure::SetError(nsIMsgSendReport *sendReport, const PRUnichar *bundle_string)
+{
+ if (!sendReport || !bundle_string)
+ return;
+
+ if (mErrorAlreadyReported)
+ return;
+
+ mErrorAlreadyReported = true;
+
+ nsString errorString;
+ nsresult res;
+
+ res = GetSMIMEBundleString(bundle_string,
+ getter_Copies(errorString));
+
+ if (NS_SUCCEEDED(res) && !errorString.IsEmpty())
+ {
+ sendReport->SetMessage(nsIMsgSendReport::process_Current,
+ errorString.get(),
+ true);
+ }
+}
+
+void nsMsgComposeSecure::SetErrorWithParam(nsIMsgSendReport *sendReport, const PRUnichar *bundle_string, const char *param)
+{
+ if (!sendReport || !bundle_string || !param)
+ return;
+
+ if (mErrorAlreadyReported)
+ return;
+
+ mErrorAlreadyReported = true;
+
+ nsString errorString;
+ nsresult res;
+ const PRUnichar *params[1];
+
+ NS_ConvertASCIItoUTF16 ucs2(param);
+ params[0]= ucs2.get();
+
+ res = SMIMEBundleFormatStringFromName(bundle_string,
+ params,
+ 1,
+ getter_Copies(errorString));
+
+ if (NS_SUCCEEDED(res) && !errorString.IsEmpty())
+ {
+ sendReport->SetMessage(nsIMsgSendReport::process_Current,
+ errorString.get(),
+ true);
+ }
+}
+
+nsresult nsMsgComposeSecure::ExtractEncryptionState(nsIMsgIdentity * aIdentity, nsIMsgCompFields * aComposeFields, bool * aSignMessage, bool * aEncrypt)
+{
+ if (!aComposeFields && !aIdentity)
+ return NS_ERROR_FAILURE; // kick out...invalid args....
+
+ NS_ENSURE_ARG_POINTER(aSignMessage);
+ NS_ENSURE_ARG_POINTER(aEncrypt);
+
+ 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->GetRequireEncryptMessage(aEncrypt);
+ return NS_OK;
+ }
+ }
+
+ // get the default info from the identity....
+ int32_t ep = 0;
+ nsresult testrv = aIdentity->GetIntAttribute("encryptionpolicy", &ep);
+ if (NS_FAILED(testrv)) {
+ *aEncrypt = false;
+ }
+ else {
+ *aEncrypt = (ep > 0);
+ }
+
+ testrv = aIdentity->GetBoolAttribute("sign_mail", aSignMessage);
+ if (NS_FAILED(testrv))
+ {
+ *aSignMessage = false;
+ }
+ return NS_OK;
+}
+
+nsresult nsMsgComposeSecure::ExtractSMIMEReceiptState(nsIMsgIdentity *aIdentity,
+ nsIMsgCompFields *aComposeFields,
+ bool *aSMIMEReceiptRequest,
+ bool *aSMIMEReceipt,
+ unsigned char **aSMIMEReceiptSignedContentIdentifier,
+ uint32_t *aSMIMEReceiptSignedContentIdentifierLen,
+ unsigned char **aSMIMEReceiptOriginatorSignatureValue,
+ uint32_t *aSMIMEReceiptOriginatorSignatureValueLen,
+ unsigned char **aSMIMEReceiptOriginatorContentType,
+ uint32_t *aSMIMEReceiptOriginatorContentTypeLen,
+ unsigned char **aSMIMEReceiptMsgSigDigest,
+ uint32_t *aSMIMEReceiptMsgSigDigestLen)
+{
+ if (!aComposeFields && !aIdentity)
+ return NS_ERROR_FAILURE; // kick out...invalid args....
+
+ NS_ENSURE_ARG(aSMIMEReceiptRequest);
+ NS_ENSURE_ARG(aSMIMEReceipt);
+ NS_ENSURE_ARG(aSMIMEReceiptSignedContentIdentifier);
+ NS_ENSURE_ARG(aSMIMEReceiptSignedContentIdentifierLen);
+ NS_ENSURE_ARG(aSMIMEReceiptOriginatorSignatureValue);
+ NS_ENSURE_ARG(aSMIMEReceiptOriginatorSignatureValueLen);
+ NS_ENSURE_ARG(aSMIMEReceiptOriginatorContentType);
+ NS_ENSURE_ARG(aSMIMEReceiptOriginatorContentTypeLen);
+ NS_ENSURE_ARG(aSMIMEReceiptMsgSigDigest);
+ NS_ENSURE_ARG(aSMIMEReceiptMsgSigDigestLen);
+
+ *aSMIMEReceiptRequest = PR_FALSE;
+ *aSMIMEReceipt = PR_FALSE;
+
+ 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)
+ {
+ /* Get SMIME receipt request */
+ smimeCompFields->GetSMIMEReceiptRequest(aSMIMEReceiptRequest);
+
+ if (*aSMIMEReceiptRequest)
+ return NS_OK;
+
+ /* Get SMIME receipt */
+ smimeCompFields->GetSMIMEReceipt(aSMIMEReceipt);
+ if (*aSMIMEReceipt)
+ {
+ smimeCompFields->GetSMIMEReceiptSignedContentIdentifier(aSMIMEReceiptSignedContentIdentifier);
+ smimeCompFields->GetSMIMEReceiptSignedContentIdentifierLen(aSMIMEReceiptSignedContentIdentifierLen);
+ smimeCompFields->GetSMIMEReceiptOriginatorSignatureValue(aSMIMEReceiptOriginatorSignatureValue);
+ smimeCompFields->GetSMIMEReceiptOriginatorSignatureValueLen(aSMIMEReceiptOriginatorSignatureValueLen);
+ smimeCompFields->GetSMIMEReceiptOriginatorContentType(aSMIMEReceiptOriginatorContentType);
+ smimeCompFields->GetSMIMEReceiptOriginatorContentTypeLen(aSMIMEReceiptOriginatorContentTypeLen);
+ smimeCompFields->GetSMIMEReceiptMsgSigDigest(aSMIMEReceiptMsgSigDigest);
+ smimeCompFields->GetSMIMEReceiptMsgSigDigestLen(aSMIMEReceiptMsgSigDigestLen);
+ return NS_OK;
+ }
+
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
+nsresult nsMsgComposeSecure::ExtractSecurityLabelState(nsIMsgCompFields * aComposeFields, bool * aHasSecuritylabel, nsAString& aSecurityPolicyIdentifier, int32_t * aSecurityClassification, nsAString& aPrivacyMark, nsAString& aSecurityCategories)
+{
+ if (!aComposeFields)
+ return NS_ERROR_FAILURE; // kick out...invalid args....
+
+ NS_ENSURE_ARG_POINTER(aHasSecuritylabel);
+ NS_ENSURE_ARG_POINTER(aSecurityClassification);
+
+ 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->GetSecurityPolicyIdentifier(aSecurityPolicyIdentifier);
+ smimeCompFields->GetSecurityClassification(aSecurityClassification);
+ smimeCompFields->GetPrivacyMark(aPrivacyMark);
+ smimeCompFields->GetSecurityCategories(aSecurityCategories);
+ if (!aSecurityPolicyIdentifier.IsEmpty())
+ *aHasSecuritylabel = PR_TRUE;
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
+/* void beginCryptoEncapsulation (in nsOutputFileStream aStream, in boolean aEncrypt, in boolean aSign, in string aRecipeints, in boolean aIsDraft); */
+NS_IMETHODIMP nsMsgComposeSecure::BeginCryptoEncapsulation(nsIOutputStream * aStream,
+ const char * aRecipients,
+ nsIMsgCompFields * aCompFields,
+ nsIMsgIdentity * aIdentity,
+ nsIMsgSendReport *sendReport,
+ bool aIsDraft)
+{
+ mErrorAlreadyReported = false;
+ nsresult rv = NS_OK;
+
+ bool encryptMessages = false;
+ bool signMessage = false;
+ ExtractEncryptionState(aIdentity, aCompFields, &signMessage, &encryptMessages);
+
+ if (!signMessage && !encryptMessages) return NS_ERROR_FAILURE;
+
+ // Extract SMIME receipt request and receipt state
+ mSMIMEReceiptRequest = PR_FALSE;
+ ExtractSMIMEReceiptState(aIdentity,
+ aCompFields,
+ &mSMIMEReceiptRequest,
+ &mSMIMEReceipt,
+ &mSMIMEReceiptSignedContentIdentifier,
+ &mSMIMEReceiptSignedContentIdentifierLen,
+ &mSMIMEReceiptOriginatorSignatureValue,
+ &mSMIMEReceiptOriginatorSignatureValueLen,
+ &mSMIMEReceiptOriginatorContentType,
+ &mSMIMEReceiptOriginatorContentTypeLen,
+ &mSMIMEReceiptMsgSigDigest,
+ &mSMIMEReceiptMsgSigDigestLen);
+
+ //Extract Headers to secure
+ ReadHeadersToSecure(aIdentity,aCompFields);
+
+ if (mSMIMEReceiptRequest) {
+ signMessage = PR_TRUE;
+
+ /* Generate a random signed content identifier for the receipt request */
+ nsCOMPtr<nsIMsgCompUtils> compUtils;
+ compUtils = do_GetService(NS_MSGCOMPUTILS_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = compUtils->MsgGenerateMessageId(aIdentity, getter_Copies(mSMIMEReceiptRequestSignedContentIdentifier));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ /* Get sender address for the recipient field of the receipt request */
+ aIdentity->GetEmail(mSMIMEReceiptRequestReceiptsTo);
+ } else if (mSMIMEReceipt) {
+ signMessage = PR_TRUE;
+ }
+
+ ExtractSecurityLabelState(aCompFields, &mHasSecuritylabel, mSecurityPolicyIdentifier, &mSecurityClassification, mPrivacyMark, mSecurityCategories);
+
+ mStream = aStream;
+ mIsDraft = aIsDraft;
+
+ if (mSMIMEReceipt)
+ mCryptoState = mime_crypto_signed_receipt;
+ else 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", mSigningCertName);
+ aIdentity->GetUnicharAttribute("encryption_cert_name", mEncryptionCertName);
+
+ rv = MimeCryptoHackCerts(aRecipients, sendReport, encryptMessages, signMessage);
+ if (NS_FAILED(rv)) {
+ goto FAIL;
+ }
+
+ switch (mCryptoState)
+ {
+ case mime_crypto_clear_signed:
+ rv = MimeInitMultipartSigned(true, sendReport);
+ break;
+ case mime_crypto_opaque_signed:
+ PR_ASSERT(0); /* #### no api for this yet */
+ rv = NS_ERROR_NOT_IMPLEMENTED;
+ break;
+ case mime_crypto_signed_encrypted:
+ rv = MimeInitEncryption(true, sendReport);
+ break;
+ case mime_crypto_encrypted:
+ rv = MimeInitEncryption(false, sendReport);
+ break;
+ case mime_crypto_signed_receipt:
+ /* Nothing to be done here */
+ break;
+ case mime_crypto_none:
+ /* This can happen if mime_crypto_hack_certs() decided to turn off
+ encryption (by asking the user.) */
+ // XXX 1 is not a valid nsresult
+ rv = static_cast<nsresult>(1);
+ break;
+ default:
+ PR_ASSERT(0);
+ break;
+ }
+
+FAIL:
+ return rv;
+}
+
+/* void finishCryptoEncapsulation (in boolean aAbort); */
+NS_IMETHODIMP nsMsgComposeSecure::FinishCryptoEncapsulation(bool aAbort, nsIMsgSendReport *sendReport)
+{
+ nsresult rv = NS_OK;
+
+ if (!aAbort) {
+ switch (mCryptoState) {
+ case mime_crypto_clear_signed:
+ rv = MimeFinishMultipartSigned (true, sendReport);
+ 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 (true, sendReport);
+ break;
+ case mime_crypto_encrypted:
+ rv = MimeFinishEncryption (false, sendReport);
+ break;
+ case mime_crypto_signed_receipt:
+ rv = MimeFinishSignedReceipt(sendReport);
+ break;
+ default:
+ PR_ASSERT(0);
+ rv = NS_ERROR_FAILURE;
+ break;
+ }
+ }
+ return rv;
+}
+
+nsresult nsMsgComposeSecure::MimeInitMultipartSigned(bool aOuter, nsIMsgSendReport *sendReport)
+{
+ /* First, construct and write out the multipart/signed MIME header data.
+ */
+ nsresult rv = NS_OK;
+ char *header = 0;
+ uint32_t L;
+
+ rv = make_multipart_signed_header_string(aOuter, &header,
+ &mMultipartSignedBoundary);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ L = strlen(header);
+
+ if (aOuter){
+ /* If this is the outer block, write it to the file. */
+ uint32_t n;
+ rv = mStream->Write(header, L, &n);
+ if (NS_FAILED(rv) || n < L) {
+ // XXX This is -1, not an nsresult
+ rv = static_cast<nsresult>(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);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ /* Now initialize the crypto library, so that we can compute a hash
+ on the object which we are signing.
+ */
+
+ mHashType = nsICryptoHash::SHA1;
+
+ PR_SetError(0,0);
+ mDataHash = do_CreateInstance("@mozilla.org/security/hash;1", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = mDataHash->Init(mHashType);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PR_SetError(0,0);
+ return rv;
+}
+
+nsresult nsMsgComposeSecure::MimeInitEncryption(bool aSign, nsIMsgSendReport *sendReport)
+{
+ nsresult rv;
+ nsCOMPtr<nsIStringBundleService> bundleSvc =
+ mozilla::services::GetStringBundleService();
+ NS_ENSURE_TRUE(bundleSvc, NS_ERROR_UNEXPECTED);
+
+ nsCOMPtr<nsIStringBundle> sMIMEBundle;
+ nsString mime_smime_enc_content_desc;
+
+ bundleSvc->CreateBundle(SMIME_STRBUNDLE_URL, getter_AddRefs(sMIMEBundle));
+
+ if (!sMIMEBundle)
+ return NS_ERROR_FAILURE;
+
+ sMIMEBundle->GetStringFromName(NS_LITERAL_STRING("mime_smimeEncryptedContentDesc").get(),
+ getter_Copies(mime_smime_enc_content_desc));
+ NS_ConvertUTF16toUTF8 enc_content_desc_utf8(mime_smime_enc_content_desc);
+
+ /* First, construct and write out the opaque-crypto-blob MIME header data.
+ */
+
+ char *s =
+ PR_smprintf("Content-Type: " APPLICATION_PKCS7_MIME
+ "; name=\"smime.p7m\"; smime-type=enveloped-data" CRLF
+ "Content-Transfer-Encoding: " ENCODING_BASE64 CRLF
+ "Content-Disposition: attachment"
+ "; filename=\"smime.p7m\"" CRLF
+ "Content-Description: %s" CRLF
+ CRLF,
+ enc_content_desc_utf8.get());
+
+ uint32_t L;
+ if (!s) return NS_ERROR_OUT_OF_MEMORY;
+ L = strlen(s);
+ uint32_t n;
+ rv = mStream->Write(s, L, &n);
+ if (NS_FAILED(rv) || n < 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) {
+ uint32_t numCerts;
+ mCerts->GetLength(&numCerts);
+ PR_ASSERT(numCerts > 0);
+ if (numCerts == 0) return NS_ERROR_FAILURE;
+ }
+
+ // Initialize the base64 encoder
+ MOZ_ASSERT(!mCryptoEncoder, "Shouldn't have an encoder already");
+ mCryptoEncoder = MimeEncoder::GetBase64Encoder(mime_encoder_output_fn,
+ this);
+
+ /* 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 rv;
+ rv = mEncryptionCinfo->CreateEncrypted(mCerts);
+ if (NS_FAILED(rv)) {
+ SetError(sendReport, NS_LITERAL_STRING("ErrorEncryptMail").get());
+ goto FAIL;
+ }
+
+ mEncryptionContext = do_CreateInstance(NS_CMSENCODER_CONTRACTID, &rv);
+ if (NS_FAILED(rv)) return rv;
+
+ if (!mBuffer) {
+ mBuffer = new char[eBufferSize];
+ if (!mBuffer)
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ mBufferedBytes = 0;
+
+ rv = mEncryptionContext->Start(mEncryptionCinfo, mime_crypto_write_base64, mCryptoEncoder);
+ if (NS_FAILED(rv)) {
+ SetError(sendReport, NS_LITERAL_STRING("ErrorEncryptMail").get());
+ 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(false, sendReport);
+ if (NS_FAILED(rv)) goto FAIL;
+ }
+
+ FAIL:
+ return rv;
+}
+
+nsresult nsMsgComposeSecure::MimeFinishMultipartSigned (bool aOuter, nsIMsgSendReport *sendReport)
+{
+ int status;
+ nsresult rv;
+ nsCOMPtr<nsICMSMessage> cinfo = do_CreateInstance(NS_CMSMESSAGE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsICMSEncoder> encoder = do_CreateInstance(NS_CMSENCODER_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ char * header = nullptr;
+ nsCOMPtr<nsIStringBundleService> bundleSvc =
+ mozilla::services::GetStringBundleService();
+ NS_ENSURE_TRUE(bundleSvc, NS_ERROR_UNEXPECTED);
+
+ nsCOMPtr<nsIStringBundle> sMIMEBundle;
+ nsString mime_smime_sig_content_desc;
+
+ bundleSvc->CreateBundle(SMIME_STRBUNDLE_URL, getter_AddRefs(sMIMEBundle));
+
+ if (!sMIMEBundle)
+ return NS_ERROR_FAILURE;
+
+ sMIMEBundle->GetStringFromName(NS_LITERAL_STRING("mime_smimeSignatureContentDesc").get(),
+ getter_Copies(mime_smime_sig_content_desc));
+
+ NS_ConvertUTF16toUTF8 sig_content_desc_utf8(mime_smime_sig_content_desc);
+
+ /* Compute the hash...
+ */
+
+ nsAutoCString hashString;
+ mDataHash->Finish(false, hashString);
+
+ mDataHash = 0;
+
+ status = PR_GetError();
+ if (status < 0) goto FAIL;
+
+ /* Write out the headers for the signature.
+ */
+ uint32_t L;
+ header =
+ PR_smprintf(CRLF
+ "--%s" CRLF
+ "Content-Type: " APPLICATION_PKCS7_SIGNATURE
+ "; name=\"smime.p7s\"" CRLF
+ "Content-Transfer-Encoding: " ENCODING_BASE64 CRLF
+ "Content-Disposition: attachment; "
+ "filename=\"smime.p7s\"" CRLF
+ "Content-Description: %s" CRLF
+ CRLF,
+ mMultipartSignedBoundary,
+ sig_content_desc_utf8.get());
+
+ if (!header) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ goto FAIL;
+ }
+
+ L = strlen(header);
+ if (aOuter) {
+ /* If this is the outer block, write it to the file. */
+ uint32_t n;
+ rv = mStream->Write(header, L, &n);
+ if (NS_FAILED(rv) || n < L) {
+ // XXX This is -1, not an nsresult
+ rv = static_cast<nsresult>(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);
+
+ /* Store the SMIME receipt request
+ */
+ if (mSMIMEReceiptRequest && !mSMIMEReceiptRequestReceiptsTo.IsEmpty())
+ cinfo->SetReceiptRequest(mSMIMEReceiptRequestSignedContentIdentifier, mSMIMEReceiptRequestReceiptsTo);
+
+ /* Store Security Label
+ */
+ if (mHasSecuritylabel)
+ rv = cinfo->SetSecurityLabel(NS_ConvertUTF16toUTF8(mSecurityPolicyIdentifier), mSecurityClassification, NS_ConvertUTF16toUTF8(mPrivacyMark), NS_ConvertUTF16toUTF8(mSecurityCategories));
+
+ /* Create the signature...
+ */
+
+ PR_ASSERT(mHashType == nsICryptoHash::SHA1);
+
+ PR_ASSERT (mSelfSigningCert);
+ PR_SetError(0,0);
+
+ rv = cinfo->CreateSigned(mSelfSigningCert,
+ mSelfEncryptionCert,
+ (unsigned char*)hashString.get(),
+ hashString.Length(),
+ mSecureHeaders,
+ mCanonAlgorithme);
+
+ if (NS_FAILED(rv)) {
+ SetError(sendReport, NS_LITERAL_STRING("ErrorCanNotSign").get());
+ goto FAIL;
+ }
+
+ // Initialize the base64 encoder for the signature data.
+ MOZ_ASSERT(!mSigEncoder, "Shouldn't already have a mSigEncoder");
+ mSigEncoder = MimeEncoder::GetBase64Encoder(
+ (aOuter ? mime_encoder_output_fn : mime_nested_encoder_output_fn), this);
+
+ /* Write out the signature.
+ */
+ PR_SetError(0,0);
+ rv = encoder->Start(cinfo, mime_crypto_write_base64, mSigEncoder);
+ if (NS_FAILED(rv)) {
+ SetError(sendReport, NS_LITERAL_STRING("ErrorCanNotSignMail").get());
+ goto FAIL;
+ }
+
+ // We're not passing in any data, so no update needed.
+ rv = encoder->Finish();
+ if (NS_FAILED(rv)) {
+ SetError(sendReport, NS_LITERAL_STRING("ErrorCanNotSignMail").get());
+ goto FAIL;
+ }
+
+ // Shut down the sig's base64 encoder.
+ rv = mSigEncoder->Flush();
+ mSigEncoder = nullptr;
+ if (NS_FAILED(rv)) {
+ goto FAIL;
+ }
+
+ /* Now write out the terminating boundary.
+ */
+ {
+ uint32_t 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 = strlen(header);
+ if (aOuter) {
+ /* If this is the outer block, write it to the file. */
+ uint32_t n;
+ rv = mStream->Write(header, L, &n);
+ if (NS_FAILED(rv) || n < L)
+ // XXX This is -1, not an nsresult
+ rv = static_cast<nsresult>(MK_MIME_ERROR_WRITING_FILE);
+ } else {
+ /* If this is an inner block, feed it through the crypto stream. */
+ rv = MimeCryptoWriteBlock (header, L);
+ }
+ }
+
+FAIL:
+ return rv;
+}
+
+nsresult nsMsgComposeSecure::MimeFinishSignedReceipt(nsIMsgSendReport *sendReport)
+{
+ nsresult rv;
+ unsigned long L;
+ uint32_t n;
+ unsigned char *encodedReceiptObject = NULL;
+ uint32_t encodedReceiptObjectLen = 0;
+
+ nsCOMPtr<nsICMSMessage> cinfo = do_CreateInstance(NS_CMSMESSAGE_CONTRACTID, &rv);
+ nsCOMPtr<nsICMSEncoder> encoder = do_CreateInstance(NS_CMSENCODER_CONTRACTID, &rv);
+ char * header = nullptr;
+
+ /* Write out the headers for the signature.
+ */
+ header = PR_smprintf("Content-Type: " APPLICATION_PKCS7_MIME "; smime-type=signed-receipt; name=\"smime.p7m\"" CRLF
+ "Content-Transfer-Encoding: " ENCODING_BASE64 CRLF
+ "Content-Disposition: attachment; filename=\"smime.p7m\"" CRLF
+ "Content-Description: %s" CRLF CRLF,
+ MIME_SMIME_RECEIPT_CONTENT_DESCRIPTION);
+
+ if (!header) {
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ goto FAIL;
+ }
+
+ L = strlen(header);
+ rv = mStream->Write(header, L, &n);
+ if (NS_FAILED(rv) || n < L)
+ rv = static_cast<nsresult>(MK_MIME_ERROR_WRITING_FILE);
+ PR_smprintf_free(header);
+
+ /* Store the SMIME receipt values
+ */
+ cinfo->SetReceipt(mSMIMEReceiptSignedContentIdentifier,
+ mSMIMEReceiptSignedContentIdentifierLen,
+ mSMIMEReceiptOriginatorSignatureValue,
+ mSMIMEReceiptOriginatorSignatureValueLen,
+ mSMIMEReceiptOriginatorContentType,
+ mSMIMEReceiptOriginatorContentTypeLen,
+ mSMIMEReceiptMsgSigDigest,
+ mSMIMEReceiptMsgSigDigestLen);
+
+ /* Create the signature...
+ */
+
+ PR_ASSERT (mSelfSigningCert);
+ PR_SetError(0, 0);
+
+ rv = cinfo->CreateSigned(mSelfSigningCert, mSelfEncryptionCert, NULL, 0,NULL,0);
+ if (NS_FAILED(rv)) {
+ SetError(sendReport, NS_LITERAL_STRING("ErrorCanNotSign").get());
+ goto FAIL;
+ }
+
+ /* Create receipt object and set message digest */
+ rv = cinfo->CreateReceipt((const uint8_t**)&encodedReceiptObject, &encodedReceiptObjectLen);
+ if (NS_FAILED(rv)) {
+ SetError(sendReport, NS_LITERAL_STRING("ErrorCanNotSign").get());
+ goto FAIL;
+ }
+
+ /* Initialize the base64 encoder for the signature data.
+ */
+ MOZ_ASSERT(!mSigEncoder, "Shouldn't already have a mSigEncoder");
+ mSigEncoder = MimeEncoder::GetBase64Encoder(mime_encoder_output_fn , this);
+
+ /* Write out the signature.
+ */
+ PR_SetError(0, 0);
+ rv = encoder->Start(cinfo, mime_crypto_write_base64, mSigEncoder);
+ if (NS_FAILED(rv)) {
+ SetError(sendReport, NS_LITERAL_STRING("ErrorCanNotSign").get());
+ goto FAIL;
+ }
+
+ /* Attach receipt object to the signature */
+ rv = encoder->Update((char*)encodedReceiptObject, (long)encodedReceiptObjectLen);
+ if (NS_FAILED(rv)) {
+ SetError(sendReport, NS_LITERAL_STRING("ErrorCanNotSign").get());
+ goto FAIL;
+ }
+
+ rv = encoder->Finish();
+ if (NS_FAILED(rv)) {
+ SetError(sendReport, NS_LITERAL_STRING("ErrorCanNotSign").get());
+ goto FAIL;
+ }
+
+ /* Shut down the sig's base64 encoder.
+ */
+ rv = mSigEncoder->Flush();
+ mSigEncoder = nullptr;
+ if (NS_FAILED(rv))
+ goto FAIL;
+
+ rv = mStream->Write(CRLF, 2, &n);
+ if (NS_FAILED(rv) || n < 2)
+ rv = NS_ERROR_FAILURE;
+
+FAIL:
+ 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 (bool aSign, nsIMsgSendReport *sendReport)
+{
+ nsresult rv;
+
+ /* If this object is both encrypted and signed, close off the
+ signature first (since it's inside.) */
+ if (aSign) {
+ rv = MimeFinishMultipartSigned (false, sendReport);
+ if (NS_FAILED(rv)) {
+ goto FAIL;
+ }
+ }
+
+ /* Close off the opaque encrypted blob.
+ */
+ PR_ASSERT(mEncryptionContext);
+
+ if (mBufferedBytes) {
+ rv = mEncryptionContext->Update(mBuffer, mBufferedBytes);
+ mBufferedBytes = 0;
+ if (NS_FAILED(rv)) {
+ PR_ASSERT(PR_GetError() < 0);
+ goto FAIL;
+ }
+ }
+
+ rv = mEncryptionContext->Finish();
+ if (NS_FAILED(rv)) {
+ SetError(sendReport, NS_LITERAL_STRING("ErrorEncryptMail").get());
+ goto FAIL;
+ }
+
+ mEncryptionContext = 0;
+
+ PR_ASSERT(mEncryptionCinfo);
+ if (!mEncryptionCinfo) {
+ rv = NS_ERROR_FAILURE;
+ }
+ if (mEncryptionCinfo) {
+ mEncryptionCinfo = 0;
+ }
+
+ // Shut down the base64 encoder.
+ mCryptoEncoder->Flush();
+ mCryptoEncoder = nullptr;
+
+ uint32_t n;
+ rv = mStream->Write(CRLF, 2, &n);
+ if (NS_FAILED(rv) || n < 2)
+ rv = NS_ERROR_FAILURE;
+
+ FAIL:
+ return rv;
+}
+
+/* Used to figure out what certs should be used when encrypting this message.
+ */
+nsresult nsMsgComposeSecure::MimeCryptoHackCerts(const char *aRecipients,
+ nsIMsgSendReport *sendReport,
+ bool aEncrypt,
+ bool aSign)
+{
+ char *mailbox_list = 0;
+ nsCString all_mailboxes, mailboxes;
+ const char *mailbox = 0;
+ uint32_t count = 0;
+ nsCOMPtr<nsIX509CertDB> certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
+ nsresult res;
+ nsCOMPtr<nsIMsgHeaderParser> pHeader = do_GetService(NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID, &res);
+ NS_ENSURE_SUCCESS(res,res);
+
+ mCerts = do_CreateInstance(NS_ARRAY_CONTRACTID, &res);
+ if (NS_FAILED(res)) {
+ return res;
+ }
+
+ PR_ASSERT(aEncrypt || aSign);
+ certdb->FindEmailEncryptionCert(mEncryptionCertName, getter_AddRefs(mSelfEncryptionCert));
+ certdb->FindEmailSigningCert(mSigningCertName, getter_AddRefs(mSelfSigningCert));
+
+ // must have both the signing and encryption certs to sign
+ if ((mSelfSigningCert == nullptr) && aSign) {
+ SetError(sendReport, NS_LITERAL_STRING("NoSenderSigningCert").get());
+ res = NS_ERROR_FAILURE;
+ goto FAIL;
+ }
+
+ if ((mSelfEncryptionCert == nullptr) && aEncrypt) {
+ SetError(sendReport, NS_LITERAL_STRING("NoSenderEncryptionCert").get());
+ res = NS_ERROR_FAILURE;
+ goto FAIL;
+ }
+
+ pHeader->ExtractHeaderAddressMailboxes(nsDependentCString(aRecipients),
+ all_mailboxes);
+ pHeader->RemoveDuplicateAddresses(all_mailboxes, EmptyCString(), mailboxes);
+
+ pHeader->ParseHeaderAddresses(mailboxes.get(), 0, &mailbox_list, &count);
+
+ // XXX This is not a valid use of nsresult
+ if (count < 0) return static_cast<nsresult>(count);
+
+ if (aEncrypt && mSelfEncryptionCert) {
+ // Make sure self's configured cert is prepared for being used
+ // as an email recipient cert.
+
+ nsCOMPtr<nsISMimeCert> sc = do_QueryInterface(mSelfEncryptionCert);
+ if (sc) {
+ sc->SaveSMimeProfile();
+ }
+ }
+
+ /* If the message is to be encrypted, then get the recipient certs */
+ if (aEncrypt) {
+ mailbox = mailbox_list;
+
+ bool already_added_self_cert = false;
+
+ for (; count > 0; count--) {
+ nsCString mailbox_lowercase;
+ ToLowerCase(nsDependentCString(mailbox), mailbox_lowercase);
+ nsCOMPtr<nsIX509Cert> cert;
+ res = certdb->FindCertByEmailAddress(nullptr, mailbox_lowercase.get(),
+ getter_AddRefs(cert));
+ if (NS_FAILED(res)) {
+ // Failure to find a valid encryption cert is fatal.
+ // Here I assume that mailbox is ascii rather than utf8.
+ SetErrorWithParam(sendReport,
+ NS_LITERAL_STRING("MissingRecipientEncryptionCert").get(),
+ mailbox);
+
+ goto FAIL;
+ }
+
+ /* #### see if recipient requests `signedData'.
+ if (...) no_clearsigning_p = 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.)
+ */
+
+ bool isSame;
+ if (NS_SUCCEEDED(cert->Equals(mSelfEncryptionCert, &isSame))
+ && isSame) {
+ already_added_self_cert = true;
+ }
+
+ mCerts->AppendElement(cert, false);
+ // To understand this loop, especially the "+= strlen +1", look at the documentation
+ // of ParseHeaderAddresses. Basically, it returns a list of zero terminated strings.
+ mailbox += strlen(mailbox) + 1;
+ }
+
+ if (!already_added_self_cert) {
+ mCerts->AppendElement(mSelfEncryptionCert, false);
+ }
+ }
+FAIL:
+ if (mailbox_list) {
+ nsMemory::Free(mailbox_list);
+ }
+ return res;
+}
+
+NS_IMETHODIMP nsMsgComposeSecure::MimeCryptoWriteBlock (const char *buf, int32_t 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' && !strncmp(buf, "From ", 5)) {
+ char mangle[] = ">";
+ nsresult res = MimeCryptoWriteBlock (mangle, 1);
+ if (NS_FAILED(res))
+ return res;
+ // This value will actually be cast back to an nsresult before use, so this
+ // cast is reasonable under the circumstances.
+ status = static_cast<int>(res);
+ }
+
+ /* 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((const uint8_t*) 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. */
+
+ /* We want to create equally sized encryption strings */
+ const char *inputBytesIterator = buf;
+ uint32_t inputBytesLeft = size;
+
+ while (inputBytesLeft) {
+ const uint32_t spaceLeftInBuffer = eBufferSize - mBufferedBytes;
+ const uint32_t bytesToAppend = std::min(inputBytesLeft, spaceLeftInBuffer);
+
+ memcpy(mBuffer+mBufferedBytes, inputBytesIterator, bytesToAppend);
+ mBufferedBytes += bytesToAppend;
+
+ inputBytesIterator += bytesToAppend;
+ inputBytesLeft -= bytesToAppend;
+
+ if (eBufferSize == mBufferedBytes) {
+ rv = mEncryptionContext->Update(mBuffer, mBufferedBytes);
+ mBufferedBytes = 0;
+ 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. */
+
+ uint32_t n;
+ rv = mStream->Write(buf, size, &n);
+ if (NS_FAILED(rv) || n < size) {
+ // XXX MK_MIME_ERROR_WRITING_FILE is -1, which is not a valid nsresult
+ return static_cast<nsresult>(MK_MIME_ERROR_WRITING_FILE);
+ }
+ }
+ FAIL:
+ // XXX status sometimes has invalid nsresults like -1 or PR_GetError()
+ // assigned to it
+ return static_cast<nsresult>(status);
+}
+
+
+/*
+ * unfold string sequence : CRLF sequences followed by WSP will be interpreted without the CRLF
+ */
+nsAutoString& removeJumpSymb(nsAutoString& s)
+{
+ s.ReplaceSubstring(NS_LITERAL_STRING("\n\r "), NS_LITERAL_STRING(" "));
+ s.ReplaceSubstring(NS_LITERAL_STRING("\r\n "), NS_LITERAL_STRING(" "));
+ s.ReplaceSubstring(NS_LITERAL_STRING("\r "), NS_LITERAL_STRING(" "));
+ s.ReplaceSubstring(NS_LITERAL_STRING("\n "), NS_LITERAL_STRING(" "));
+ s.ReplaceSubstring(NS_LITERAL_STRING("\n\r\t"), NS_LITERAL_STRING(" "));
+ s.ReplaceSubstring(NS_LITERAL_STRING("\r\n\t"), NS_LITERAL_STRING(" "));
+ s.ReplaceSubstring(NS_LITERAL_STRING("\r\t"), NS_LITERAL_STRING(" "));
+ s.ReplaceSubstring(NS_LITERAL_STRING("\n\t"), NS_LITERAL_STRING(" "));
+
+ return s;
+}
+
+/*
+ * Convert all sequences of one ore more WSP characters to a single SP character
+ */
+nsAutoString& onlyOneWhiteSpace(nsAutoString& s){
+ s.ReplaceSubstring(NS_LITERAL_STRING("\t"), NS_LITERAL_STRING(" "));
+ s.ReplaceSubstring(NS_LITERAL_STRING(" "), NS_LITERAL_STRING(" "));
+
+ return s;
+}
+
+
+nsAutoString& canonilizeHeaderValue(nsAutoString &hdrval)
+{
+ removeJumpSymb(hdrval);
+ onlyOneWhiteSpace(hdrval);
+ hdrval.CompressWhitespace(PR_TRUE,PR_TRUE);
+ return hdrval;
+}
+
+nsAutoString& canonilizeHeaderName(nsAutoString &hdrname)
+{
+ nsAutoCString utf8str = NS_ConvertUTF16toUTF8(hdrname);
+ ToLowerCase(utf8str);
+ hdrname = NS_ConvertUTF8toUTF16(utf8str);
+ onlyOneWhiteSpace(hdrname);
+ hdrname.CompressWhitespace(PR_TRUE,PR_TRUE);
+ return hdrname;
+}
+
+/*
+ Parse extended headers
+ */
+void parseHeaderValue(const nsAString & str, const nsAString& headerName, nsAString & headerVal)
+{
+ nsVoidArray tab_header;
+ nsAutoString ligne_header;
+ nsAutoString tmpstr(str);
+ nsAString::const_iterator cur_pos_str,cur_pos_CRLF,start,end;
+
+ tmpstr.BeginReading(start);
+ tmpstr.EndReading(end);
+
+ cur_pos_str=start;
+ cur_pos_CRLF=end;
+ NS_NAMED_LITERAL_STRING(valuePrefix, "\r\n");
+
+ while(FindInReadable(valuePrefix, start, end))
+ {
+ cur_pos_CRLF = end;
+ if(*cur_pos_CRLF == PRUnichar(' '))
+ {
+ ligne_header.Append(Substring(cur_pos_CRLF.start(),cur_pos_CRLF.get()));
+ tmpstr.Replace(0,end.get()-end.start(),NS_LITERAL_STRING(""));
+ }
+ else
+ {
+ ligne_header.Append(Substring(cur_pos_CRLF.start(),cur_pos_CRLF.get()));
+ nsAutoString _hdrName;
+ nsAutoString _hdrValue;
+
+ _hdrName.Assign(Substring(ligne_header,0,ligne_header.FindChar(':',0)));
+ _hdrValue.Assign(Substring(ligne_header,ligne_header.FindChar(':',0)+2,ligne_header.Length()-ligne_header.FindChar(':',0)+1));
+ if(_hdrName.Equals(headerName)){
+ headerVal.Assign(_hdrValue);
+ break;
+ }
+ ligne_header.Assign(NS_LITERAL_STRING(""));
+ tmpstr.Replace(0,end.get()-end.start(),NS_LITERAL_STRING(""));
+ }
+
+ tmpstr.BeginReading(start);
+ tmpstr.EndReading(end);
+ }
+}
+
+/*
+ Returns mime encoded value
+ */
+void GetMimeEncodedValue(nsAString& headerName, nsAString& charset, PRBool bstructured, nsAString & value, nsAString & result){
+ nsresult rv;
+ char * tmp;
+ tmp=NULL;
+ nsCOMPtr<nsIMimeConverter> mimeconverter = do_GetService(NS_MIME_CONVERTER_CONTRACTID, &rv);
+
+ mimeconverter->EncodeMimePartIIStr_UTF8(NS_ConvertUTF16toUTF8(value),
+ bstructured,
+ NS_ConvertUTF16toUTF8(charset).get(),
+ (PRInt32)headerName.Length()+2, // header len + 2 characters semi-colon and space ": "
+ nsIMimeConverter::MIME_ENCODED_WORD_SIZE,
+ &tmp);
+ if(tmp!=NULL)
+ {
+ result.Assign(NS_ConvertUTF8toUTF16(tmp));
+ }
+ else{
+ result.Assign(value);
+ }
+}
+
+/*
+ Returns value of header as mime encoded format
+ */
+void GetValueHeader(nsAString& headerName,nsIMsgCompFields * aComposeFields, nsAString & result)
+{
+ nsresult rv;
+ nsAutoString otherHeaders;
+ nsAutoString to;
+ nsAutoString from;
+ nsAutoString subject;
+ nsAutoString cc;
+ nsAutoString bcc;
+ nsAutoString body;
+ nsAutoString messageId;
+ nsAutoString priority;
+ nsAutoString replyTo;
+ nsAutoString charset;
+
+ aComposeFields->GetTo(to);
+ aComposeFields->GetFrom(from);
+ aComposeFields->GetSubject(subject);
+ aComposeFields->GetCc(cc);
+ aComposeFields->GetBcc(bcc);
+ aComposeFields->GetBody(body);
+ aComposeFields->GetOtherRandomHeaders(otherHeaders);
+ aComposeFields->GetReplyTo(replyTo);
+ char * tmp;
+ aComposeFields->GetMessageId(&tmp);
+ messageId=NS_ConvertASCIItoUTF16(tmp);
+ aComposeFields->GetPriority(&tmp);
+ priority=NS_ConvertASCIItoUTF16(tmp);
+ aComposeFields->GetCharacterSet(&tmp);
+ charset=NS_ConvertASCIItoUTF16(tmp);
+ if(charset.IsEmpty()){
+ aComposeFields->GetDefaultCharacterSet(&tmp);
+ charset=NS_ConvertASCIItoUTF16(tmp);
+ }
+
+ //replace the tabulation by a space for each header
+ //which can be multiline to simplify the treatment
+ to.ReplaceSubstring(NS_LITERAL_STRING("\t"), NS_LITERAL_STRING(" "));
+ cc.ReplaceSubstring(NS_LITERAL_STRING("\t"), NS_LITERAL_STRING(" "));
+ bcc.ReplaceSubstring(NS_LITERAL_STRING("\t"), NS_LITERAL_STRING(" "));
+
+ if(headerName.LowerCaseEqualsLiteral("from")){
+ if(!from.IsEmpty()){
+ GetMimeEncodedValue(headerName, charset, PR_TRUE, from, result);
+ return;
+ }
+ }
+ else if(headerName.LowerCaseEqualsLiteral("to")){
+ if(!to.IsEmpty()){
+ GetMimeEncodedValue(headerName, charset, PR_TRUE, to, result);
+ return;
+ }
+ }
+ else if(headerName.LowerCaseEqualsLiteral("body")){
+ if(!body.IsEmpty()){
+ GetMimeEncodedValue(headerName, charset, PR_FALSE, body, result);
+ return;
+ }
+ }
+ else if(headerName.LowerCaseEqualsLiteral("subject")){
+ if(!subject.IsEmpty()){
+ GetMimeEncodedValue(headerName, charset, PR_FALSE, subject, result);
+ return;
+ }
+ }
+ else if(headerName.LowerCaseEqualsLiteral("cc")){
+ if(!cc.IsEmpty()){
+ GetMimeEncodedValue(headerName, charset, PR_TRUE, cc, result);
+ return;
+ }
+ }
+ else if(headerName.LowerCaseEqualsLiteral("bcc")){
+ if(!bcc.IsEmpty()){
+ GetMimeEncodedValue(headerName, charset, PR_TRUE, bcc, result);
+ return;
+ }
+ }
+ else if(headerName.LowerCaseEqualsLiteral("message-id")){
+ if(!messageId.IsEmpty())
+ result.Assign(messageId);
+ }
+ else if(headerName.LowerCaseEqualsLiteral("priority")){
+ if(!priority.IsEmpty())
+ result.Assign(priority);
+ }
+ else if(headerName.LowerCaseEqualsLiteral("reply-to")){
+ if(!replyTo.IsEmpty()){
+ GetMimeEncodedValue(headerName, charset, PR_TRUE, replyTo, result);
+ return;
+ }
+ }
+ else{
+ parseHeaderValue(otherHeaders,headerName,result);
+ }
+
+}
+
+/*
+ Returns array of secure headers
+ */
+nsresult nsMsgComposeSecure::ReadHeadersToSecure(nsIMsgIdentity * aIdentity,nsIMsgCompFields * aComposeFields){
+
+ //Extract Signed Headers list
+ 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)
+ {
+ nsCOMPtr<nsIMutableArray> tmpHeaders;
+ smimeCompFields->GetSecureHeadersList(getter_AddRefs(tmpHeaders));
+ smimeCompFields->GetCanonAlgorithme(&mCanonAlgorithme);
+ if(tmpHeaders)
+ {
+ nsresult rv;
+ mSecureHeaders = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+ PRUint32 nbHeaders;
+ tmpHeaders->GetLength(&nbHeaders);
+
+ for(int i=0;i<nbHeaders;++i)
+ {
+ nsCOMPtr<nsIMsgSMIMESecureHeader> _secureHeader= do_QueryElementAt(tmpHeaders,i);
+ if(_secureHeader)
+ {
+ nsAutoString _headerName;
+ nsAutoString _headerValue;
+ PRInt32 _headerStatus;
+ _secureHeader->GetHeaderName(_headerName);
+ GetValueHeader(_headerName,aComposeFields,_headerValue);
+ if(!_headerValue.IsEmpty()){
+
+ if(mCanonAlgorithme){
+ canonilizeHeaderName(_headerName);
+ canonilizeHeaderValue(_headerValue);
+ }
+ _secureHeader->SetHeaderName(_headerName);
+ _secureHeader->SetHeaderValue(_headerValue);
+ mSecureHeaders->AppendElement(_secureHeader,PR_FALSE);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+
+ return NS_OK;
+}
+
+
+/* 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 nsresult
+make_multipart_signed_header_string(bool outer_p,
+ char **header_return,
+ char **boundary_return)
+{
+ *header_return = 0;
+ *boundary_return = mime_make_separator("ms");
+
+ if (!*boundary_return)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ *header_return = PR_smprintf(
+ "Content-Type: " MULTIPART_SIGNED "; "
+ "protocol=\"" APPLICATION_PKCS7_SIGNATURE "\"; "
+ "micalg=" PARAM_MICALG_SHA1 "; "
+ "boundary=\"%s\"" CRLF
+ CRLF
+ "%s%s"
+ "--%s" CRLF,
+
+ *boundary_return,
+ (outer_p ? crypto_multipart_blurb : ""),
+ (outer_p ? CRLF CRLF : ""),
+ *boundary_return);
+
+ if (!*header_return) {
+ PR_Free(*boundary_return);
+ *boundary_return = 0;
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ return NS_OK;
+}
+
+/* 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 MimeEncoder 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 MimeEncoder object is used.
+ */
+static void
+mime_crypto_write_base64 (void *closure, const char *buf, unsigned long size)
+{
+ MimeEncoder *encoder = (MimeEncoder *) closure;
+ nsresult rv = encoder->Write(buf, size);
+ PR_SetError(NS_FAILED(rv) ? static_cast<uint32_t>(rv) : 0, 0);
+}
+
+
+/* Used as the output function of MimeEncoder -- 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, int32_t size, void *closure)
+{
+ nsMsgComposeSecure *state = (nsMsgComposeSecure *) closure;
+ nsCOMPtr<nsIOutputStream> stream;
+ state->GetOutputStream(getter_AddRefs(stream));
+ uint32_t n;
+ nsresult rv = stream->Write((char *) buf, size, &n);
+ if (NS_FAILED(rv) || n < size)
+ return NS_ERROR_FAILURE;
+ else
+ return NS_OK;
+}
+
+/* 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, int32_t size, void *closure)
+{
+ nsMsgComposeSecure *state = (nsMsgComposeSecure *) closure;
+ return state->MimeCryptoWriteBlock((char *) buf, size);
+}
--- /dev/null
+/* -*- Mode: idl; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved */
+#ifndef _nsMsgComposeSecure_H_
+#define _nsMsgComposeSecure_H_
+
+#include "nsIMsgComposeSecure.h"
+#include "nsIMsgSMIMECompFields.h"
+#include "nsCOMPtr.h"
+#include "nsICMSEncoder.h"
+#include "nsIX509Cert.h"
+#include "nsIMimeConverter.h"
+#include "nsIStringBundle.h"
+#include "nsICryptoHash.h"
+#include "nsICMSMessage.h"
+#include "nsIMutableArray.h"
+#include "nsStringGlue.h"
+#include "nsIOutputStream.h"
+#include "nsAutoPtr.h"
+#include "nsIMsgSMIMESecureHeader.h"
+
+class nsIMsgCompFields;
+namespace mozilla {
+namespace mailnews {
+class MimeEncoder;
+}
+}
+
+class nsMsgSMIMEComposeFields : public nsIMsgSMIMECompFields
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIMSGSMIMECOMPFIELDS
+
+ nsMsgSMIMEComposeFields();
+ virtual ~nsMsgSMIMEComposeFields();
+
+private:
+ bool mSignMessage;
+ bool mAlwaysEncryptMessage;
+ bool mSMIMEReceiptRequest;
+ bool mSMIMEReceipt;
+ unsigned char *mSMIMEReceiptSignedContentIdentifier;
+ unsigned long mSMIMEReceiptSignedContentIdentifierLen;
+ unsigned char *mSMIMEReceiptOriginatorSignatureValue;
+ unsigned long mSMIMEReceiptOriginatorSignatureValueLen;
+ unsigned char *mSMIMEReceiptOriginatorContentType;
+ unsigned long mSMIMEReceiptOriginatorContentTypeLen;
+ unsigned char *mSMIMEReceiptMsgSigDigest;
+ unsigned long mSMIMEReceiptMsgSigDigestLen;
+ nsCOMPtr<nsIMutableArray> m_secureHeaders;
+ long mCanonAlgorithme;
+ nsString mSecurityPolicyIdentifier;
+ long mSecurityClassification;
+ nsString mPrivacyMark;
+ nsString mSecurityCategories;
+};
+
+class nsMsgSMIMESecureHeader : public nsIMsgSMIMESecureHeader
+{
+
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIMSGSMIMESECUREHEADER
+
+ nsMsgSMIMESecureHeader();
+ virtual ~nsMsgSMIMESecureHeader();
+
+private:
+ nsString mHeaderName;
+ nsString mHeaderValue;
+ int mHeaderStatus;
+ int mHeaderEncrypted;
+
+};
+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 */
+ mime_crypto_signed_receipt /* application/x-pkcs7-mime with smime-type=signed-receipt */
+} mimeDeliveryCryptoState;
+
+class nsMsgComposeSecure : public nsIMsgComposeSecure
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIMSGCOMPOSESECURE
+
+ nsMsgComposeSecure();
+ virtual ~nsMsgComposeSecure();
+ /* additional members */
+ void GetOutputStream(nsIOutputStream **stream) { NS_IF_ADDREF(*stream = mStream);}
+private:
+ typedef mozilla::mailnews::MimeEncoder MimeEncoder;
+ nsresult MimeInitMultipartSigned(bool aOuter, nsIMsgSendReport *sendReport);
+ nsresult MimeInitEncryption(bool aSign, nsIMsgSendReport *sendReport);
+ nsresult MimeFinishMultipartSigned (bool aOuter, nsIMsgSendReport *sendReport);
+ nsresult MimeFinishSignedReceipt(nsIMsgSendReport *sendReport);
+ nsresult MimeFinishEncryption (bool aSign, nsIMsgSendReport *sendReport);
+ nsresult MimeCryptoHackCerts(const char *aRecipients, nsIMsgSendReport *sendReport, bool aEncrypt, bool aSign);
+ bool InitializeSMIMEBundle();
+ nsresult GetSMIMEBundleString(const PRUnichar *name,
+ PRUnichar **outString);
+ nsresult SMIMEBundleFormatStringFromName(const PRUnichar *name,
+ const PRUnichar **params,
+ uint32_t numParams,
+ PRUnichar **outString);
+ nsresult ExtractEncryptionState(nsIMsgIdentity * aIdentity, nsIMsgCompFields * aComposeFields, bool * aSignMessage, bool * aEncrypt);
+ nsresult ExtractSMIMEReceiptState(nsIMsgIdentity *aIdentity,
+ nsIMsgCompFields *aComposeFields,
+ bool *aSMIMEReceiptRequest,
+ bool *aSMIMEReceipt,
+ unsigned char **aSMIMEReceiptSignedContentIdentifier,
+ uint32_t *aSMIMEReceiptSignedContentIdentifierLen,
+ unsigned char **aSMIMEReceiptOriginatorSignatureValue,
+ uint32_t *aSMIMEReceiptOriginatorSignatureValueLen,
+ unsigned char **aSMIMEReceiptOriginatorContentType,
+ uint32_t *aSMIMEReceiptOriginatorContentTypeLen,
+ unsigned char **aSMIMEReceiptMsgSigDigest,
+ uint32_t *aSMIMEReceiptMsgSigDigestLen);
+
+ nsresult ExtractSecurityLabelState(nsIMsgCompFields *aComposeFields, bool *aHasSecuritylabel, nsAString& aSecurityPolicyIdentifier, int32_t *aSecurityClassification, nsAString& aPrivacyMark, nsAString& aSecurityCategories);
+
+ nsresult ReadHeadersToSecure(nsIMsgIdentity * aIdentity,nsIMsgCompFields * aComposeFields);
+
+ mimeDeliveryCryptoState mCryptoState;
+ nsCOMPtr<nsIOutputStream> mStream;
+ int16_t mHashType;
+ nsCOMPtr<nsICryptoHash> mDataHash;
+ nsAutoPtr<MimeEncoder> mSigEncoder;
+ char *mMultipartSignedBoundary;
+ nsString mSigningCertName;
+ nsCOMPtr<nsIX509Cert> mSelfSigningCert;
+ nsString mEncryptionCertName;
+ nsCOMPtr<nsIX509Cert> mSelfEncryptionCert;
+ nsCOMPtr<nsIMutableArray> mCerts;
+ nsCOMPtr<nsICMSMessage> mEncryptionCinfo;
+ nsCOMPtr<nsICMSEncoder> mEncryptionContext;
+ nsCOMPtr<nsIStringBundle> mSMIMEBundle;
+
+ nsAutoPtr<MimeEncoder> mCryptoEncoder;
+ bool mIsDraft;
+
+ enum {eBufferSize = 8192};
+ char *mBuffer;
+ uint32_t mBufferedBytes;
+
+ bool mErrorAlreadyReported;
+ void SetError(nsIMsgSendReport *sendReport, const PRUnichar *bundle_string);
+ void SetErrorWithParam(nsIMsgSendReport *sendReport, const PRUnichar *bundle_string, const char *param);
+
+ bool mSMIMEReceiptRequest;
+ nsCString mSMIMEReceiptRequestSignedContentIdentifier;
+ nsCString mSMIMEReceiptRequestReceiptsTo;
+
+ bool mSMIMEReceipt;
+ unsigned char *mSMIMEReceiptSignedContentIdentifier;
+ uint32_t mSMIMEReceiptSignedContentIdentifierLen;
+ unsigned char *mSMIMEReceiptOriginatorSignatureValue;
+ uint32_t mSMIMEReceiptOriginatorSignatureValueLen;
+ unsigned char *mSMIMEReceiptOriginatorContentType;
+ uint32_t mSMIMEReceiptOriginatorContentTypeLen;
+ unsigned char *mSMIMEReceiptMsgSigDigest;
+ uint32_t mSMIMEReceiptMsgSigDigestLen;
+ nsCOMPtr<nsIMutableArray> mSecureHeaders;
+ int32_t mCanonAlgorithme;
+
+ bool mHasSecuritylabel;
+ nsString mSecurityPolicyIdentifier;
+ int32_t mSecurityClassification;
+ nsString mPrivacyMark;
+ nsString mSecurityCategories;
+};
+
+#endif
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef nsMsgSMIMECID_h__
+#define nsMsgSMIMECID_h__
+
+#include "nsISupports.h"
+#include "nsIFactory.h"
+#include "nsIComponentManager.h"
+
+#define NS_MSGSMIMECOMPFIELDS_CONTRACTID \
+ "@mozilla.org/messenger-smime/composefields;1"
+
+#define NS_MSGSMIMECOMPFIELDS_CID \
+{ /* 122C919C-96B7-49a0-BBC8-0ABC67EEFFE0 */ \
+ 0x122c919c, 0x96b7, 0x49a0, \
+ { 0xbb, 0xc8, 0xa, 0xbc, 0x67, 0xee, 0xff, 0xe0 }}
+
+#define NS_MSGCOMPOSESECURE_CID \
+{ /* dd753201-9a23-4e08-957f-b3616bf7e012 */ \
+ 0xdd753201, 0x9a23, 0x4e08, \
+ {0x95, 0x7f, 0xb3, 0x61, 0x6b, 0xf7, 0xe0, 0x12 }}
+
+#define NS_SMIMEJSHELPER_CONTRACTID \
+ "@mozilla.org/messenger-smime/smimejshelper;1"
+
+#define NS_SMIMEJSJELPER_CID \
+{ /* d57d928c-60e4-4f81-999d-5c762e611205 */ \
+ 0xd57d928c, 0x60e4, 0x4f81, \
+ {0x99, 0x9d, 0x5c, 0x76, 0x2e, 0x61, 0x12, 0x05 }}
+
+#define NS_SMIMEENCRYPTURISERVICE_CONTRACTID \
+ "@mozilla.org/messenger-smime/smime-encrypted-uris-service;1"
+
+#define NS_SMIMEENCRYPTURISERVICE_CID \
+{ /* a0134d58-018f-4d40-a099-fa079e5024a6 */ \
+ 0xa0134d58, 0x018f, 0x4d40, \
+ {0xa0, 0x99, 0xfa, 0x07, 0x9e, 0x50, 0x24, 0xa6 }}
+
+#define NS_SMIMERECEIPT_GENERATOR_CONTRACTID \
+ "@mozilla.org/messenger-smime/smimereceiptgenerator;1"
+
+#define NS_SMIMERECEIPT_GENERATOR_CID \
+{ /* f988ef90-28ec-4f4b-aa2e-a49d067556f1 */ \
+ 0xf988ef90, 0x28ec, 0x4f4b, \
+ {0xaa, 0x2e, 0xa4, 0x9d, 0x06, 0x75, 0x56, 0xf1 }}
+
+#define NS_SMIMESECUREHEADER_CONTRACTID \
+ "@mozilla.org/messenger-smime/smime-secure-header;1"
+
+#define NS_SMIMESECUREHEADER_CID \
+{ /* A1BBE613-DA57-4766-84F0-343DAAFF6EB2 */ \
+ 0xa1bbe613, 0xda57, 0x4766, \
+ { 0x84, 0xf0, 0x34, 0x3d, 0xaa, 0xff, 0x6e, 0xb2 }}
+
+#endif // nsMsgSMIMECID_h__
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 "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 the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+#include "nsMsgSMIMEReceiptGenerator.h"
+#include "nsIMsgAccountManager.h"
+#include "nsMsgBaseCID.h"
+#include "nsMailHeaders.h"
+#include "nsISmtpService.h"
+#include "nsMsgCompCID.h"
+#include "nsDirectoryServiceDefs.h"
+#include "nsMsgUtils.h"
+#include "nsISmtpServer.h"
+#include "nsIPrompt.h"
+#include "nsIStringBundle.h"
+#include "nsNetUtil.h"
+#include "nsComposeStrings.h"
+#include "nsMsgI18N.h"
+#include "nsIMsgCompUtils.h"
+#include "nsIMsgHeaderParser.h"
+#include "nsMsgSMIMECID.h"
+#include "nsIMsgCompFields.h"
+#include "nsIHttpProtocolHandler.h"
+#include "nsImapCore.h"
+#include "nsIMsgImapMailFolder.h"
+#include "prprf.h"
+#include "prmem.h"
+
+
+#define SMIME_RECEIPT_REQUEST_PROCESSED "SMIMEReceiptRequestProcessed"
+
+#define PUSH_N_FREE_STRING(p) \
+ do { if (p) { rv = WriteString(p); PR_smprintf_free(p); p = 0; if (NS_FAILED(rv)) return rv; } \
+ else { return NS_ERROR_OUT_OF_MEMORY; } \
+ } while (0)
+
+
+NS_IMPL_ISUPPORTS2(nsMsgSMIMEReceiptGenerator, nsIMsgSMIMEReceiptGenerator, nsIUrlListener)
+
+nsMsgSMIMEReceiptGenerator::nsMsgSMIMEReceiptGenerator()
+{
+ m_signedContentIdentifier = NULL;
+ m_originatorSignatureValue = NULL;
+ m_originatorContentType = NULL;
+ m_msgSigDigest = NULL;
+}
+
+nsMsgSMIMEReceiptGenerator::~nsMsgSMIMEReceiptGenerator()
+{
+ PR_FREEIF(m_signedContentIdentifier);
+ PR_FREEIF(m_originatorSignatureValue);
+ PR_FREEIF(m_originatorContentType);
+ PR_FREEIF(m_msgSigDigest);
+}
+
+NS_IMETHODIMP nsMsgSMIMEReceiptGenerator::Process(nsIMsgWindow *aWindow,
+ nsIMsgFolder *aFolder,
+ nsMsgKey aKey,
+ nsIMimeHeaders *aHeaders,
+ uint8_t *aSignedContentIdentifier,
+ uint32_t aSignedContentIdentifierLen,
+ uint32_t aReceiptsFrom,
+ const nsAString& aReceiptsTo,
+ uint8_t *aOriginatorSignatureValue,
+ uint32_t aOriginatorSignatureValueLen,
+ uint8_t *aOriginatorContentType,
+ uint32_t aOriginatorContentTypeLen,
+ uint8_t *aMsgSigDigest,
+ uint32_t aMsgSigDigestLen,
+ bool *_retval)
+{
+ nsresult rv;
+ m_window = aWindow;
+ m_folder = aFolder;
+ m_key = aKey;
+ m_headers = aHeaders;
+ CopyUTF16toUTF8(aReceiptsTo, m_recipient);
+
+ m_signedContentIdentifier = (unsigned char*)PR_MALLOC(aSignedContentIdentifierLen);
+ memcpy(m_signedContentIdentifier, aSignedContentIdentifier, aSignedContentIdentifierLen);
+ m_signedContentIdentifierLen = aSignedContentIdentifierLen;
+
+ m_originatorSignatureValue = (unsigned char*)PR_MALLOC(aOriginatorSignatureValueLen);
+ memcpy(m_originatorSignatureValue, aOriginatorSignatureValue, aOriginatorSignatureValueLen);
+ m_originatorSignatureValueLen = aOriginatorSignatureValueLen;
+
+ m_originatorContentType = (unsigned char*)PR_MALLOC(aOriginatorContentTypeLen);
+ memcpy(m_originatorContentType, aOriginatorContentType, aOriginatorContentTypeLen);
+ m_originatorContentTypeLen = aOriginatorContentTypeLen;
+
+ m_msgSigDigest = (unsigned char*)PR_MALLOC(aMsgSigDigestLen);
+ memcpy(m_msgSigDigest, aMsgSigDigest, aMsgSigDigestLen);
+ m_msgSigDigestLen = aMsgSigDigestLen;
+
+ *_retval = PR_FALSE;
+
+ rv = m_folder->GetMessageHeader(m_key, getter_AddRefs(m_msghdr));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = GetIdentity();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (m_identity)
+ {
+ nsCString identEmail;
+ m_identity->GetEmail(identEmail);
+ if (identEmail.Equals(m_recipient))
+ {
+ // If receipt recipient is myself, don't send anything
+ UserDeclined();
+ return NS_OK;
+ }
+
+ /* Get send policy */
+ int32_t sendPolicy; /* 0: ask 1: never 2: always */
+ m_identity->GetIntAttribute("smime_receipt_send_policy", &sendPolicy);
+
+ switch (sendPolicy)
+ {
+ case 0:
+ *_retval = PR_TRUE;
+ break;
+ case 1:
+ UserDeclined();
+ break;
+ case 2:
+ UserAgreed();
+ break;
+ default:
+ UserDeclined();
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEReceiptGenerator::UserAgreed()
+{
+ nsresult rv;
+
+ nsString signingCertName;
+ m_identity->GetUnicharAttribute("signing_cert_name", signingCertName);
+ if (signingCertName.IsEmpty())
+ {
+ // No signing cert available
+ nsCOMPtr<nsIPrompt> dialog;
+ rv = m_window->GetPromptDialog(getter_AddRefs(dialog));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIStringBundle> bundle;
+ nsCOMPtr<nsIStringBundleService> bundleService(do_GetService("@mozilla.org/intl/stringbundle;1", &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = bundleService->CreateBundle("chrome://messenger-smime/locale/msgSMIMEReceiptGenerator.properties", getter_AddRefs(bundle));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsString errorTitle;
+ nsString errorMsg;
+ rv = bundle->GetStringFromName(NS_LITERAL_STRING("noSigningCertTitle").get(), getter_Copies(errorTitle));
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = bundle->GetStringFromName(NS_LITERAL_STRING("noSigningCert").get(), getter_Copies(errorMsg));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = dialog->Alert(errorTitle.get(), errorMsg.get());
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ rv = CreateMessage();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = SendMessage();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return rv;
+}
+
+NS_IMETHODIMP nsMsgSMIMEReceiptGenerator::UserDeclined()
+{
+ nsresult rv;
+
+ rv = StoreSMIMEReceiptSentFlag();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_OK;
+}
+
+nsresult nsMsgSMIMEReceiptGenerator::CreateMessage()
+{
+ nsresult rv;
+
+ rv = GetSpecialDirectoryWithFileName(NS_OS_TEMP_DIR, "smimeReceiptMsg", getter_AddRefs(m_file));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = m_file->CreateUnique(nsIFile::NORMAL_FILE_TYPE, 00600);
+ //nsCOMPtr <nsIFile> localFile = do_QueryInterface(m_file);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = NS_NewLocalFileOutputStream(getter_AddRefs(m_outputStream),
+ m_file,
+ PR_CREATE_FILE | PR_WRONLY | PR_TRUNCATE,
+ 0664);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "creating smime receipt message: failed to output stream");
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Create message headers
+ rv = CreateMessageHeaders();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ m_composeSecure = do_CreateInstance(NS_MSGCOMPOSESECURE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Create compose fields
+ nsCOMPtr<nsIMsgCompFields> compFields = do_CreateInstance(NS_MSGCOMPFIELDS_CONTRACTID, &rv);
+ if (!compFields)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ nsCOMPtr<nsIMsgSMIMECompFields> SMIMECompFields = do_CreateInstance(NS_MSGSMIMECOMPFIELDS_CONTRACTID, &rv);
+ if (!SMIMECompFields)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ SMIMECompFields->SetSignMessage(PR_TRUE);
+ SMIMECompFields->SetSMIMEReceipt(PR_TRUE);
+ SMIMECompFields->SetSMIMEReceiptSignedContentIdentifier(m_signedContentIdentifier);
+ SMIMECompFields->SetSMIMEReceiptSignedContentIdentifierLen(m_signedContentIdentifierLen);
+ SMIMECompFields->SetSMIMEReceiptOriginatorSignatureValue(m_originatorSignatureValue);
+ SMIMECompFields->SetSMIMEReceiptOriginatorSignatureValueLen(m_originatorSignatureValueLen);
+ SMIMECompFields->SetSMIMEReceiptOriginatorContentType(m_originatorContentType);
+ SMIMECompFields->SetSMIMEReceiptOriginatorContentTypeLen(m_originatorContentTypeLen);
+ SMIMECompFields->SetSMIMEReceiptMsgSigDigest(m_msgSigDigest);
+ SMIMECompFields->SetSMIMEReceiptMsgSigDigestLen(m_msgSigDigestLen);
+
+ compFields->SetSecurityInfo(SMIMECompFields);
+
+ // Create S/MIME signature
+ rv = m_composeSecure->BeginCryptoEncapsulation(m_outputStream, m_recipient.get(), compFields, m_identity, NULL, PR_FALSE);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = m_composeSecure->FinishCryptoEncapsulation(PR_FALSE, NULL);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if (m_outputStream)
+ {
+ m_outputStream->Flush();
+ m_outputStream->Close();
+ }
+
+ if (NS_FAILED(rv))
+ m_file->Remove(PR_FALSE);
+
+ return rv;
+}
+
+nsresult nsMsgSMIMEReceiptGenerator::CreateMessageHeaders()
+{
+ char* convbuf = nullptr;
+ char* tmpBuffer = nullptr;
+ char* parm = nullptr;
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIMsgCompUtils> compUtils;
+
+ compUtils = do_GetService(NS_MSGCOMPUTILS_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ tmpBuffer = (char*)PR_CALLOC(256);
+
+ if (!tmpBuffer)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ PRExplodedTime now;
+ PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &now);
+
+ int gmtoffset = (now.tm_params.tp_gmt_offset + now.tm_params.tp_dst_offset) / 60;
+ /* Use PR_FormatTimeUSEnglish() to format the date in US English format,
+ then figure out what our local GMT offset is, and append it (since
+ PR_FormatTimeUSEnglish() can't do that.) Generate four digit years as
+ per RFC 1123 (superceding RFC 822.)
+ */
+ PR_FormatTimeUSEnglish(tmpBuffer, 100,
+ "Date: %a, %d %b %Y %H:%M:%S ",
+ &now);
+
+ PR_snprintf(tmpBuffer + strlen(tmpBuffer), 100,
+ "%c%02d%02d" CRLF,
+ (gmtoffset >= 0 ? '+' : '-'),
+ ((gmtoffset >= 0 ? gmtoffset : -gmtoffset) / 60),
+ ((gmtoffset >= 0 ? gmtoffset : -gmtoffset) % 60));
+
+ rv = WriteString(tmpBuffer);
+ PR_Free(tmpBuffer);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCString charset;
+ rv = m_folder->GetCharset(charset);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool conformToStandard = PR_FALSE;
+ if (compUtils)
+ compUtils->GetMsgMimeConformToStandard(&conformToStandard);
+
+ nsCString email;
+ nsString fullName;
+ m_identity->GetFullName(fullName);
+ m_identity->GetEmail(email);
+
+ nsCString fullAddress;
+ nsCOMPtr<nsIMsgHeaderParser> parser(do_GetService(NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID));
+ if (parser)
+ parser->MakeFullAddressString(NS_ConvertUTF16toUTF8(fullName).get(), email.get(), getter_Copies(fullAddress));
+
+ convbuf = nsMsgI18NEncodeMimePartIIStr((!fullAddress.IsEmpty()) ? fullAddress.get(): email.get(), PR_TRUE, charset.get(), 0, conformToStandard);
+
+ parm = PR_smprintf("From: %s" CRLF, convbuf ? convbuf : email.get());
+ PUSH_N_FREE_STRING(parm);
+
+ PR_Free(convbuf);
+
+ if (compUtils)
+ {
+ nsCString msgId;
+ rv = compUtils->MsgGenerateMessageId(m_identity, getter_Copies(msgId));
+ tmpBuffer = PR_smprintf("Message-ID: %s" CRLF, msgId.get());
+ PUSH_N_FREE_STRING(tmpBuffer);
+ }
+
+ nsCString subject;
+ m_headers->ExtractHeader(HEADER_SUBJECT, false, subject);
+ convbuf = nsMsgI18NEncodeMimePartIIStr(subject.Length() ? subject.get() : "[no subject]", PR_FALSE, charset.get(), 0, conformToStandard);
+ tmpBuffer = PR_smprintf("Subject: S/MIME Receipt: %s" CRLF, (convbuf ? convbuf : (subject.Length() ? subject.get() : "[no subject]")));
+ PUSH_N_FREE_STRING(tmpBuffer);
+ PR_Free(convbuf);
+
+ convbuf = nsMsgI18NEncodeMimePartIIStr(m_recipient.get(), PR_TRUE, charset.get(), 0, conformToStandard);
+ tmpBuffer = PR_smprintf("To: %s" CRLF, convbuf ? convbuf : m_recipient.get());
+ PUSH_N_FREE_STRING(tmpBuffer);
+ PR_Free(convbuf);
+
+ nsCString messageId;
+ m_headers->ExtractHeader(HEADER_MESSAGE_ID, false, messageId);
+ if (!messageId.IsEmpty())
+ {
+ if (*messageId.get() == '<')
+ tmpBuffer = PR_smprintf("References: %s" CRLF, messageId.get());
+ else
+ tmpBuffer = PR_smprintf("References: <%s>" CRLF, messageId.get());
+ PUSH_N_FREE_STRING(tmpBuffer);
+ }
+
+ tmpBuffer = PR_smprintf("%s" CRLF, "MIME-Version: 1.0");
+ PUSH_N_FREE_STRING(tmpBuffer);
+
+ nsCOMPtr<nsIHttpProtocolHandler> pHTTPHandler = do_GetService(NS_NETWORK_PROTOCOL_CONTRACTID_PREFIX "http", &rv);
+ if (NS_SUCCEEDED(rv) && pHTTPHandler)
+ {
+ nsAutoCString userAgentString;
+ pHTTPHandler->GetUserAgent(userAgentString);
+
+ if (!userAgentString.IsEmpty())
+ {
+ tmpBuffer = PR_smprintf("User-Agent: %s" CRLF, userAgentString.get());
+ PUSH_N_FREE_STRING(tmpBuffer);
+ }
+ }
+
+ return rv;
+}
+
+nsresult nsMsgSMIMEReceiptGenerator::WriteString(const char *aStr)
+{
+ NS_ENSURE_ARG(aStr);
+ unsigned long len = strlen(aStr);
+ uint32_t wLen = 0;
+
+ return m_outputStream->Write(aStr, len, &wLen);
+}
+
+nsresult nsMsgSMIMEReceiptGenerator::SendMessage()
+{
+ nsresult rv;
+ nsCOMPtr<nsISmtpService> smtpService = do_GetService(NS_SMTPSERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ nsCOMPtr<nsIRequest> aRequest;
+ smtpService->SendMailMessage(m_file, m_recipient.get(), m_identity,
+ nullptr, this, nullptr, nullptr, PR_FALSE, nullptr,
+ getter_AddRefs(aRequest));
+
+ return NS_OK;
+}
+
+nsresult nsMsgSMIMEReceiptGenerator::GetIdentity()
+{
+ nsresult rv = m_folder->GetServer(getter_AddRefs(m_server));
+ nsCOMPtr<nsIMsgAccountManager> accountManager = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
+ if (accountManager && m_server)
+ {
+ if (!m_identity)
+ {
+ // check if this is a message delivered to the global inbox,
+ // in which case we find the originating account's identity.
+ nsCString accountKey;
+ m_headers->ExtractHeader(HEADER_X_MOZILLA_ACCOUNT_KEY, false, accountKey);
+ nsCOMPtr <nsIMsgAccount> account;
+ if (!accountKey.IsEmpty())
+ accountManager->GetAccount(accountKey, getter_AddRefs(account));
+ if (account)
+ account->GetIncomingServer(getter_AddRefs(m_server));
+
+ if (m_server)
+ {
+ // Find the correct identity based on the "To:" and "Cc:" header
+ nsCString mailTo;
+ nsCString mailCC;
+ m_headers->ExtractHeader(HEADER_TO, true, mailTo);
+ m_headers->ExtractHeader(HEADER_CC, true, mailCC);
+ nsCOMPtr<nsIArray> servIdentities;
+ accountManager->GetIdentitiesForServer(m_server, getter_AddRefs(servIdentities));
+ if (servIdentities)
+ {
+ nsCOMPtr<nsIMsgIdentity> ident;
+ nsCString identEmail;
+ uint32_t count = 0;
+ servIdentities->GetLength(&count);
+ // First check in the "To:" header
+ for (unsigned long i = 0; i < count; i++)
+ {
+ rv = servIdentities->QueryElementAt(i, NS_GET_IID(nsIMsgIdentity),getter_AddRefs(ident));
+ if (NS_FAILED(rv))
+ continue;
+ ident->GetEmail(identEmail);
+ if (!mailTo.IsEmpty() && !identEmail.IsEmpty() && mailTo.Find(identEmail, PR_TRUE) != -1)
+ {
+ m_identity = ident;
+ break;
+ }
+ }
+ // If no match, check the "Cc:" header
+ if (!m_identity)
+ {
+ for (unsigned long i = 0; i < count; i++)
+ {
+ rv = servIdentities->QueryElementAt(i, NS_GET_IID(nsIMsgIdentity),getter_AddRefs(ident));
+ if (NS_FAILED(rv))
+ continue;
+ ident->GetEmail(identEmail);
+ if (!mailCC.IsEmpty() && !identEmail.IsEmpty() && mailCC.Find(identEmail, PR_TRUE) != -1)
+ {
+ m_identity = ident;
+ break;
+ }
+ }
+ }
+ }
+
+ // If no match again, use the first identity
+ if (!m_identity)
+ rv = accountManager->GetFirstIdentityForServer(m_server, getter_AddRefs(m_identity));
+ }
+ }
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ return NS_OK;
+}
+
+nsresult nsMsgSMIMEReceiptGenerator::StoreSMIMEReceiptSentFlag()
+{
+ nsresult rv;
+
+ // Set a flag in local message database
+ rv = m_msghdr->SetStringProperty(SMIME_RECEIPT_REQUEST_PROCESSED, "true");
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIMsgImapMailFolder> imapFolder = do_QueryInterface(m_folder);
+ if (!imapFolder)
+ return NS_OK;
+
+ // Set an IMAP flag if possible
+ rv = imapFolder->StoreCustomKeywords(m_window, NS_LITERAL_CSTRING(SMIME_RECEIPT_REQUEST_PROCESSED), EmptyCString(), &m_key, 1, nullptr);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEReceiptGenerator::OnStartRunningUrl(nsIURI *aUrl)
+{
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgSMIMEReceiptGenerator::OnStopRunningUrl(nsIURI *aUrl, nsresult aExitCode)
+{
+ nsresult rv;
+
+ if (m_file)
+ m_file->Remove(PR_FALSE);
+
+ if (NS_SUCCEEDED(aExitCode))
+ {
+ rv = StoreSMIMEReceiptSentFlag();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ return NS_OK;
+ }
+
+ switch (aExitCode)
+ {
+ case NS_ERROR_UNKNOWN_HOST:
+ case NS_ERROR_UNKNOWN_PROXY_HOST:
+ aExitCode = NS_ERROR_SMTP_SEND_FAILED_UNKNOWN_SERVER;
+ break;
+ case NS_ERROR_CONNECTION_REFUSED:
+ case NS_ERROR_PROXY_CONNECTION_REFUSED:
+ aExitCode = NS_ERROR_SMTP_SEND_FAILED_REFUSED;
+ break;
+ case NS_ERROR_NET_INTERRUPT:
+ aExitCode = NS_ERROR_SMTP_SEND_FAILED_INTERRUPTED;
+ break;
+ case NS_ERROR_NET_TIMEOUT:
+ case NS_ERROR_NET_RESET:
+ aExitCode = NS_ERROR_SMTP_SEND_FAILED_TIMEOUT;
+ break;
+ case NS_ERROR_SMTP_PASSWORD_UNDEFINED:
+ // nothing to do, just keep the code
+ break;
+ default:
+ if (aExitCode != NS_ERROR_ABORT && !NS_IS_MSG_ERROR(aExitCode))
+ aExitCode = NS_ERROR_SMTP_SEND_FAILED_UNKNOWN_REASON;
+ break;
+ }
+
+ nsCOMPtr<nsISmtpService> smtpService(do_GetService(NS_SMTPSERVICE_CONTRACTID, &rv));
+ NS_ENSURE_SUCCESS(rv,rv);
+
+ // Get the smtp hostname and format the string.
+ nsCString smtpHostName;
+ nsCOMPtr<nsISmtpServer> smtpServer;
+ rv = smtpService->GetServerByIdentity(m_identity, getter_AddRefs(smtpServer));
+ if (NS_SUCCEEDED(rv))
+ smtpServer->GetHostname(smtpHostName);
+
+ nsAutoString hostStr;
+ CopyASCIItoUTF16(smtpHostName, hostStr);
+ const PRUnichar *params[] = { hostStr.get() };
+
+ nsCOMPtr<nsIStringBundle> bundle;
+ nsCOMPtr<nsIStringBundleService> bundleService(do_GetService("@mozilla.org/intl/stringbundle;1", &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = bundleService->CreateBundle("chrome://messenger/locale/messengercompose/composeMsgs.properties", getter_AddRefs(bundle));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsString failed_msg, dialogTitle;
+
+ bundle->FormatStringFromID(NS_ERROR_GET_CODE(aExitCode), params, 1, getter_Copies(failed_msg));
+ bundle->GetStringFromID(NS_MSG_SEND_ERROR_TITLE, getter_Copies(dialogTitle));
+
+ nsCOMPtr<nsIPrompt> dialog;
+ rv = m_window->GetPromptDialog(getter_AddRefs(dialog));
+ if (NS_SUCCEEDED(rv))
+ dialog->Alert(dialogTitle.get(),failed_msg.get());
+
+ return NS_OK;
+}
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* ***** 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 "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 the Initial Developer are Copyright (C) 2010
+ * the Initial Developer. All Rights Reserved.
+ *
+ * Contributor(s):
+ * Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ *
+ * Alternatively, the contents of this file may be used under the terms of
+ * either of 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 ***** */
+
+#ifndef _nsMsgSMIMEReceiptGenerator_H_
+#define _nsMsgSMIMEReceiptGenerator_H_
+
+#include "nsIMsgSMIMEReceiptGenerator.h"
+#include "nsCOMPtr.h"
+#include "nsIUrlListener.h"
+#include "nsIMsgHdr.h"
+#include "nsIMsgIncomingServer.h"
+#include "nsIOutputStream.h"
+#include "nsIFile.h"
+#include "nsIMsgIdentity.h"
+#include "nsIMsgWindow.h"
+#include "nsIMimeHeaders.h"
+#include "nsString.h"
+#include "nsMsgComposeSecure.h"
+
+class nsMsgSMIMEReceiptGenerator : public nsIMsgSMIMEReceiptGenerator, public nsIUrlListener
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIMSGSMIMERECEIPTGENERATOR
+ NS_DECL_NSIURLLISTENER
+
+ nsMsgSMIMEReceiptGenerator();
+ virtual ~nsMsgSMIMEReceiptGenerator();
+
+private:
+ nsresult CreateMessage();
+ nsresult CreateMessageHeaders();
+ nsresult WriteString(const char *aStr);
+ nsresult SendMessage();
+ nsresult GetIdentity();
+ nsresult StoreSMIMEReceiptSentFlag();
+
+private:
+ nsCOMPtr<nsIMsgWindow> m_window;
+ nsCOMPtr<nsIOutputStream> m_outputStream;
+ nsCOMPtr<nsIFile> m_file;
+ nsCOMPtr<nsIMsgIdentity> m_identity;
+ nsCString m_recipient;
+ nsCOMPtr<nsIMsgFolder> m_folder;
+ nsMsgKey m_key;
+ nsCOMPtr<nsIMsgDBHdr> m_msghdr;
+ nsCOMPtr<nsIMsgIncomingServer> m_server;
+ nsCOMPtr<nsIMimeHeaders> m_headers;
+ nsCOMPtr<nsIMsgComposeSecure> m_composeSecure;
+ nsCOMPtr<nsIMsgSMIMECompFields> m_SMIMECompFields;
+ PRUint8 *m_signedContentIdentifier;
+ PRUint32 m_signedContentIdentifierLen;
+ PRUint8 *m_originatorSignatureValue;
+ PRUint32 m_originatorSignatureValueLen;
+ PRUint8 *m_originatorContentType;
+ PRUint32 m_originatorContentTypeLen;
+ PRUint8 *m_msgSigDigest;
+ PRUint32 m_msgSigDigestLen;
+};
+
+#endif // _nsMsgSMIMEReceiptGenerator_H_
--- /dev/null
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */
+
+#ifdef MOZ_LOGGING
+// sorry, this has to be before the pre-compiled header
+#define FORCE_PR_LOG /* Allow logging in the release build */
+#endif
+
+// as does this
+#include "msgCore.h" // for pre-compiled headers
+#include "nsMsgUtils.h"
+
+#include "nsIServiceManager.h"
+#include "nsICharsetConverterManager.h"
+#include "nsIStringBundle.h"
+#include "nsVersionComparator.h"
+
+#include "nsMsgImapCID.h"
+#include "nsThreadUtils.h"
+#include "nsISupportsObsolete.h"
+#include "nsIMsgStatusFeedback.h"
+#include "nsImapCore.h"
+#include "nsImapProtocol.h"
+#include "nsIMsgMailNewsUrl.h"
+#include "nsIMAPHostSessionList.h"
+#include "nsIMAPBodyShell.h"
+#include "nsImapMailFolder.h"
+#include "nsIMsgAccountManager.h"
+#include "nsImapServerResponseParser.h"
+#include "nspr.h"
+#include "plbase64.h"
+#include "nsIImapService.h"
+#include "nsISocketTransportService.h"
+#include "nsIStreamListenerTee.h"
+#include "nsNetUtil.h"
+#include "nsIDBFolderInfo.h"
+#include "nsIPipe.h"
+#include "nsIMsgFolder.h"
+#include "nsMsgMessageFlags.h"
+#include "nsImapStringBundle.h"
+#include "nsICopyMsgStreamListener.h"
+#include "nsTextFormatter.h"
+#include "nsIMsgHdr.h"
+#include "nsMsgI18N.h"
+#include <algorithm>
+// for the memory cache...
+#include "nsICacheEntryDescriptor.h"
+#include "nsICacheSession.h"
+#include "nsIPrompt.h"
+#include "nsIDocShell.h"
+#include "nsIDocShellLoadInfo.h"
+#include "nsIMessengerWindowService.h"
+#include "nsIWindowMediator.h"
+#include "nsIWindowWatcher.h"
+#include "nsCOMPtr.h"
+#include "nsMimeTypes.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsXPCOMCIDInternal.h"
+#include "nsIXULAppInfo.h"
+#include "nsSyncRunnableHelpers.h"
+
+PRLogModuleInfo *IMAP;
+
+// netlib required files
+#include "nsIStreamListener.h"
+#include "nsIMsgIncomingServer.h"
+#include "nsIImapIncomingServer.h"
+#include "nsIPrefBranch.h"
+#include "nsIPrefService.h"
+#include "nsIPrefLocalizedString.h"
+#include "nsImapUtils.h"
+#include "nsIStreamConverterService.h"
+#include "nsIProxyInfo.h"
+#include "nsISSLSocketControl.h"
+#include "nsProxyRelease.h"
+#include "nsDebug.h"
+#include "nsMsgCompressIStream.h"
+#include "nsMsgCompressOStream.h"
+#include "nsAlgorithm.h"
+using namespace mozilla;
+
+#define ONE_SECOND ((uint32_t)1000) // one second
+
+#define OUTPUT_BUFFER_SIZE (4096*2) // mscott - i should be able to remove this if I can use nsMsgLineBuffer???
+
+#define IMAP_ENV_HEADERS "From To Cc Bcc Subject Date Message-ID "
+#define IMAP_DB_HEADERS "Priority X-Priority References Newsgroups In-Reply-To Content-Type Reply-To"
+#define IMAP_ENV_AND_DB_HEADERS IMAP_ENV_HEADERS IMAP_DB_HEADERS
+static const PRIntervalTime kImapSleepTime = PR_MillisecondsToInterval(60000);
+static int32_t gPromoteNoopToCheckCount = 0;
+static const uint32_t kFlagChangesBeforeCheck = 10;
+static const int32_t kMaxSecondsBeforeCheck = 600;
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsMsgImapHdrXferInfo, nsIImapHeaderXferInfo)
+
+nsMsgImapHdrXferInfo::nsMsgImapHdrXferInfo()
+ : m_hdrInfos(kNumHdrsToXfer)
+{
+ m_nextFreeHdrInfo = 0;
+}
+
+nsMsgImapHdrXferInfo::~nsMsgImapHdrXferInfo()
+{
+}
+
+NS_IMETHODIMP nsMsgImapHdrXferInfo::GetNumHeaders(int32_t *aNumHeaders)
+{
+ *aNumHeaders = m_nextFreeHdrInfo;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgImapHdrXferInfo::GetHeader(int32_t hdrIndex, nsIImapHeaderInfo **aResult)
+{
+ // If the header index is more than (or equal to) our next free pointer, then
+ // its a header we haven't really got and the caller has done something
+ // wrong.
+ NS_ENSURE_TRUE(hdrIndex < m_nextFreeHdrInfo, NS_ERROR_NULL_POINTER);
+
+ *aResult = m_hdrInfos.SafeObjectAt(hdrIndex);
+ if (!*aResult)
+ return NS_ERROR_NULL_POINTER;
+
+ NS_ADDREF(*aResult);
+ return NS_OK;
+}
+
+static const int32_t kInitLineHdrCacheSize = 512; // should be about right
+
+nsIImapHeaderInfo* nsMsgImapHdrXferInfo::StartNewHdr()
+{
+ if (m_nextFreeHdrInfo >= kNumHdrsToXfer)
+ return nullptr;
+
+ nsIImapHeaderInfo *result = m_hdrInfos.SafeObjectAt(m_nextFreeHdrInfo++);
+ if (result)
+ return result;
+
+ nsMsgImapLineDownloadCache *lineCache = new nsMsgImapLineDownloadCache();
+ if (!lineCache)
+ return nullptr;
+
+ lineCache->GrowBuffer(kInitLineHdrCacheSize);
+
+ m_hdrInfos.AppendObject(lineCache);
+
+ return lineCache;
+}
+
+// maybe not needed...
+void nsMsgImapHdrXferInfo::FinishCurrentHdr()
+{
+ // nothing to do?
+}
+
+void nsMsgImapHdrXferInfo::ResetAll()
+{
+ int32_t count = m_hdrInfos.Count();
+ for (int32_t i = 0; i < count; i++)
+ {
+ nsIImapHeaderInfo *hdrInfo = m_hdrInfos[i];
+ if (hdrInfo)
+ hdrInfo->ResetCache();
+ }
+ m_nextFreeHdrInfo = 0;
+}
+
+void nsMsgImapHdrXferInfo::ReleaseAll()
+{
+ m_hdrInfos.Clear();
+ m_nextFreeHdrInfo = 0;
+}
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsMsgImapLineDownloadCache, nsIImapHeaderInfo)
+
+// **** helper class for downloading line ****
+nsMsgImapLineDownloadCache::nsMsgImapLineDownloadCache()
+{
+ fLineInfo = (msg_line_info *) PR_CALLOC(sizeof( msg_line_info));
+ fLineInfo->uidOfMessage = nsMsgKey_None;
+ m_msgSize = 0;
+}
+
+nsMsgImapLineDownloadCache::~nsMsgImapLineDownloadCache()
+{
+ PR_Free( fLineInfo);
+}
+
+uint32_t nsMsgImapLineDownloadCache::CurrentUID()
+{
+ return fLineInfo->uidOfMessage;
+}
+
+uint32_t nsMsgImapLineDownloadCache::SpaceAvailable()
+{
+ return kDownLoadCacheSize - m_bufferPos;
+}
+
+msg_line_info *nsMsgImapLineDownloadCache::GetCurrentLineInfo()
+{
+ AppendBuffer("", 1); // null terminate the buffer
+ fLineInfo->adoptedMessageLine = GetBuffer();
+ return fLineInfo;
+}
+
+NS_IMETHODIMP nsMsgImapLineDownloadCache::ResetCache()
+{
+ ResetWritePos();
+ return NS_OK;
+}
+
+bool nsMsgImapLineDownloadCache::CacheEmpty()
+{
+ return m_bufferPos == 0;
+}
+
+NS_IMETHODIMP nsMsgImapLineDownloadCache::CacheLine(const char *line, uint32_t uid)
+{
+ NS_ASSERTION((PL_strlen(line) + 1) <= SpaceAvailable(),
+ "Oops... line length greater than space available");
+
+ fLineInfo->uidOfMessage = uid;
+
+ AppendString(line);
+ return NS_OK;
+}
+
+/* attribute nsMsgKey msgUid; */
+NS_IMETHODIMP nsMsgImapLineDownloadCache::GetMsgUid(nsMsgKey *aMsgUid)
+{
+ *aMsgUid = fLineInfo->uidOfMessage;
+ return NS_OK;
+}
+NS_IMETHODIMP nsMsgImapLineDownloadCache::SetMsgUid(nsMsgKey aMsgUid)
+{
+ fLineInfo->uidOfMessage = aMsgUid;
+ return NS_OK;
+}
+
+/* attribute long msgSize; */
+NS_IMETHODIMP nsMsgImapLineDownloadCache::GetMsgSize(int32_t *aMsgSize)
+{
+ *aMsgSize = m_msgSize;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsMsgImapLineDownloadCache::SetMsgSize(int32_t aMsgSize)
+{
+ m_msgSize = aMsgSize;
+ return NS_OK;
+}
+
+/* attribute string msgHdrs; */
+NS_IMETHODIMP nsMsgImapLineDownloadCache::GetMsgHdrs(const char **aMsgHdrs)
+{
+ // this doesn't copy the string
+ AppendBuffer("", 1); // null terminate the buffer
+ *aMsgHdrs = GetBuffer();
+ return NS_OK;
+}
+
+/* the following macros actually implement addref, release and query interface for our component. */
+
+NS_IMPL_ADDREF_INHERITED(nsImapProtocol, nsMsgProtocol)
+NS_IMPL_RELEASE_INHERITED(nsImapProtocol, nsMsgProtocol )
+
+NS_INTERFACE_MAP_BEGIN(nsImapProtocol)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIImapProtocol)
+ NS_INTERFACE_MAP_ENTRY(nsIRunnable)
+ NS_INTERFACE_MAP_ENTRY(nsIImapProtocol)
+ NS_INTERFACE_MAP_ENTRY(nsIInputStreamCallback)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+ NS_INTERFACE_MAP_ENTRY(nsIImapProtocolSink)
+ NS_INTERFACE_MAP_ENTRY(nsIMsgAsyncPromptListener)
+NS_INTERFACE_MAP_END_THREADSAFE
+
+static int32_t gTooFastTime = 2;
+static int32_t gIdealTime = 4;
+static int32_t gChunkAddSize = 16384;
+static int32_t gChunkSize = 250000;
+static int32_t gChunkThreshold = gChunkSize + gChunkSize/2;
+static bool gChunkSizeDirty = false;
+static bool gFetchByChunks = true;
+static bool gInitialized = false;
+static bool gHideUnusedNamespaces = true;
+static bool gHideOtherUsersFromList = false;
+static bool gUseEnvelopeCmd = false;
+static bool gUseLiteralPlus = true;
+static bool gExpungeAfterDelete = false;
+static bool gCheckDeletedBeforeExpunge = false; //bug 235004
+static int32_t gResponseTimeout = 60;
+
+// let delete model control expunging, i.e., don't ever expunge when the
+// user chooses the imap delete model, otherwise, expunge when over the
+// threshhold. This is the normal TB behavior.
+static const int32_t kAutoExpungeDeleteModel = 0;
+// Expunge whenever the folder is opened
+static const int32_t kAutoExpungeAlways = 1;
+// Expunge when over the threshhold, independent of the delete model.
+static const int32_t kAutoExpungeOnThreshold = 2;
+static int32_t gExpungeOption = kAutoExpungeDeleteModel;
+static int32_t gExpungeThreshold = 20;
+
+const int32_t kAppBufSize = 100;
+// can't use static nsCString because it shows up as a leak.
+static char gAppName[kAppBufSize];
+static char gAppVersion[kAppBufSize];
+
+nsresult nsImapProtocol::GlobalInitialization(nsIPrefBranch *aPrefBranch)
+{
+ gInitialized = true;
+
+ aPrefBranch->GetIntPref("mail.imap.chunk_fast", &gTooFastTime); // secs we read too little too fast
+ aPrefBranch->GetIntPref("mail.imap.chunk_ideal", &gIdealTime); // secs we read enough in good time
+ aPrefBranch->GetIntPref("mail.imap.chunk_add", &gChunkAddSize); // buffer size to add when wasting time
+ aPrefBranch->GetIntPref("mail.imap.chunk_size", &gChunkSize);
+ aPrefBranch->GetIntPref("mail.imap.min_chunk_size_threshold",
+ &gChunkThreshold);
+ aPrefBranch->GetBoolPref("mail.imap.hide_other_users",
+ &gHideOtherUsersFromList);
+ aPrefBranch->GetBoolPref("mail.imap.hide_unused_namespaces",
+ &gHideUnusedNamespaces);
+ aPrefBranch->GetIntPref("mail.imap.noop_check_count",
+ &gPromoteNoopToCheckCount);
+ aPrefBranch->GetBoolPref("mail.imap.use_envelope_cmd",
+ &gUseEnvelopeCmd);
+ aPrefBranch->GetBoolPref("mail.imap.use_literal_plus", &gUseLiteralPlus);
+ aPrefBranch->GetBoolPref("mail.imap.expunge_after_delete",
+ &gExpungeAfterDelete);
+ aPrefBranch->GetBoolPref("mail.imap.check_deleted_before_expunge",
+ &gCheckDeletedBeforeExpunge);
+ aPrefBranch->GetIntPref("mail.imap.expunge_option", &gExpungeOption);
+ aPrefBranch->GetIntPref("mail.imap.expunge_threshold_number",
+ &gExpungeThreshold);
+ aPrefBranch->GetIntPref("mailnews.tcptimeout", &gResponseTimeout);
+ nsCOMPtr<nsIXULAppInfo> appInfo(do_GetService(XULAPPINFO_SERVICE_CONTRACTID));
+
+ if (appInfo)
+ {
+ nsCString appName, appVersion;
+ appInfo->GetName(appName);
+ appInfo->GetVersion(appVersion);
+ PL_strncpyz(gAppName, appName.get(), kAppBufSize);
+ PL_strncpyz(gAppVersion, appVersion.get(), kAppBufSize);
+ }
+ return NS_OK;
+}
+
+nsImapProtocol::nsImapProtocol() : nsMsgProtocol(nullptr),
+ m_dataAvailableMonitor("imapDataAvailable"),
+ m_urlReadyToRunMonitor("imapUrlReadyToRun"),
+ m_pseudoInterruptMonitor("imapPseudoInterrupt"),
+ m_dataMemberMonitor("imapDataMember"),
+ m_threadDeathMonitor("imapThreadDeath"),
+ m_waitForBodyIdsMonitor("imapWaitForBodyIds"),
+ m_fetchBodyListMonitor("imapFetchBodyList"),
+ m_passwordReadyMonitor("imapPasswordReady"),
+ mLock("nsImapProtocol.mLock"),
+ m_parser(*this)
+{
+ m_urlInProgress = false;
+ m_idle = false;
+ m_retryUrlOnError = false;
+ m_useIdle = true; // by default, use it
+ m_useCondStore = true;
+ m_useCompressDeflate = true;
+ m_ignoreExpunges = false;
+ m_prefAuthMethods = kCapabilityUndefined;
+ m_failedAuthMethods = 0;
+ m_currentAuthMethod = kCapabilityUndefined;
+ m_socketType = nsMsgSocketType::trySTARTTLS;
+ m_connectionStatus = NS_OK;
+ m_safeToCloseConnection = false;
+ m_hostSessionList = nullptr;
+ m_flagState = nullptr;
+ m_fetchBodyIdList = nullptr;
+ m_isGmailServer = false;
+ m_fetchingWholeMessage = false;
+
+ nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
+ NS_ASSERTION(prefBranch, "FAILED to create the preference service");
+
+ // read in the accept languages preference
+ if (prefBranch)
+ {
+ if (!gInitialized)
+ GlobalInitialization(prefBranch);
+
+ nsCOMPtr<nsIPrefLocalizedString> prefString;
+ prefBranch->GetComplexValue("intl.accept_languages",
+ NS_GET_IID(nsIPrefLocalizedString),
+ getter_AddRefs(prefString));
+ if (prefString)
+ prefString->ToString(getter_Copies(mAcceptLanguages));
+
+ nsCString customDBHeaders;
+ prefBranch->GetCharPref("mailnews.customDBHeaders",
+ getter_Copies(customDBHeaders));
+
+ ParseString(customDBHeaders, ' ', mCustomDBHeaders);
+ prefBranch->GetBoolPref("mailnews.display.prefer_plaintext", &m_preferPlainText);
+
+ nsAutoCString customHeaders;;
+ prefBranch->GetCharPref("mailnews.customHeaders",
+ getter_Copies(customHeaders));
+ customHeaders.StripWhitespace();
+ ParseString(customHeaders, ':', mCustomHeaders);
+ }
+
+ // ***** Thread support *****
+ m_thread = nullptr;
+ m_imapThreadIsRunning = false;
+ m_currentServerCommandTagNumber = 0;
+ m_active = false;
+ m_folderNeedsSubscribing = false;
+ m_folderNeedsACLRefreshed = false;
+ m_threadShouldDie = false;
+ m_inThreadShouldDie = false;
+ m_pseudoInterrupted = false;
+ m_nextUrlReadyToRun = false;
+ m_trackingTime = false;
+ m_curFetchSize = 0;
+ m_startTime = 0;
+ m_endTime = 0;
+ m_lastActiveTime = 0;
+ m_lastProgressTime = 0;
+ ResetProgressInfo();
+
+ m_tooFastTime = 0;
+ m_idealTime = 0;
+ m_chunkAddSize = 0;
+ m_chunkStartSize = 0;
+ m_fetchByChunks = true;
+ m_sendID = true;
+ m_chunkSize = 0;
+ m_chunkThreshold = 0;
+ m_fromHeaderSeen = false;
+ m_closeNeededBeforeSelect = false;
+ m_needNoop = false;
+ m_noopCount = 0;
+ m_fetchBodyListIsNew = false;
+ m_flagChangeCount = 0;
+ m_lastCheckTime = PR_Now();
+
+ m_checkForNewMailDownloadsHeaders = true; // this should be on by default
+ m_hierarchyNameState = kNoOperationInProgress;
+ m_discoveryStatus = eContinue;
+
+ m_overRideUrlConnectionInfo = false;
+ // m_dataOutputBuf is used by Send Data
+ m_dataOutputBuf = (char *) PR_CALLOC(sizeof(char) * OUTPUT_BUFFER_SIZE);
+ m_allocatedSize = OUTPUT_BUFFER_SIZE;
+
+ // used to buffer incoming data by ReadNextLine
+ m_inputStreamBuffer = new nsMsgLineStreamBuffer(OUTPUT_BUFFER_SIZE, true /* allocate new lines */, false /* leave CRLFs on the returned string */);
+ m_currentBiffState = nsIMsgFolder::nsMsgBiffState_Unknown;
+ m_progressStringId = 0;
+
+ // since these are embedded in the nsImapProtocol object, but passed
+ // through proxied xpcom methods, just AddRef them here.
+ m_hdrDownloadCache = new nsMsgImapHdrXferInfo();
+ m_downloadLineCache = new nsMsgImapLineDownloadCache();
+ m_specialXListMailboxes.Init(0);
+
+ // subscription
+ m_autoSubscribe = true;
+ m_autoUnsubscribe = true;
+ m_autoSubscribeOnOpen = true;
+ m_deletableChildren = nullptr;
+
+ mFolderLastModSeq = 0;
+
+ Configure(gTooFastTime, gIdealTime, gChunkAddSize, gChunkSize,
+ gChunkThreshold, gFetchByChunks);
+
+ // where should we do this? Perhaps in the factory object?
+ if (!IMAP)
+ IMAP = PR_NewLogModule("IMAP");
+}
+
+nsresult nsImapProtocol::Configure(int32_t TooFastTime, int32_t IdealTime,
+ int32_t ChunkAddSize, int32_t ChunkSize, int32_t ChunkThreshold,
+ bool FetchByChunks)
+{
+ m_tooFastTime = TooFastTime; // secs we read too little too fast
+ m_idealTime = IdealTime; // secs we read enough in good time
+ m_chunkAddSize = ChunkAddSize; // buffer size to add when wasting time
+ m_chunkStartSize = m_chunkSize = ChunkSize;
+ m_chunkThreshold = ChunkThreshold;
+ m_fetchByChunks = FetchByChunks;
+
+ return NS_OK;
+}
+
+
+NS_IMETHODIMP
+nsImapProtocol::Initialize(nsIImapHostSessionList * aHostSessionList,
+ nsIImapIncomingServer *aServer)
+{
+ NS_PRECONDITION(aHostSessionList && aServer,
+ "oops...trying to initialize with a null host session list or server!");
+ if (!aHostSessionList || !aServer)
+ return NS_ERROR_NULL_POINTER;
+
+ nsresult rv = m_downloadLineCache->GrowBuffer(kDownLoadCacheSize);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ m_flagState = new nsImapFlagAndUidState(kImapFlagAndUidStateSize);
+ if (!m_flagState)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ aServer->GetUseIdle(&m_useIdle);
+ aServer->GetUseCondStore(&m_useCondStore);
+ aServer->GetUseCompressDeflate(&m_useCompressDeflate);
+ NS_ADDREF(m_flagState);
+
+ m_hostSessionList = aHostSessionList; // no ref count...host session list has life time > connection
+ m_parser.SetHostSessionList(aHostSessionList);
+ m_parser.SetFlagState(m_flagState);
+
+ // one of the initializations that should be done in UI thread
+ nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID, &rv));
+
+ // Now initialize the thread for the connection
+ if (m_thread == nullptr)
+ {
+ nsresult rv = NS_NewThread(getter_AddRefs(m_iThread), this);
+ if (NS_FAILED(rv))
+ {
+ NS_ASSERTION(m_iThread, "Unable to create imap thread.\n");
+ return rv;
+ }
+ m_iThread->GetPRThread(&m_thread);
+
+ }
+ return NS_OK;
+}
+
+nsImapProtocol::~nsImapProtocol()
+{
+ PR_Free(m_fetchBodyIdList);
+
+ NS_IF_RELEASE(m_flagState);
+
+ PR_Free(m_dataOutputBuf);
+ delete m_inputStreamBuffer;
+
+ // **** We must be out of the thread main loop function
+ NS_ASSERTION(!m_imapThreadIsRunning, "Oops, thread is still running.\n");
+}
+
+const nsCString&
+nsImapProtocol::GetImapHostName()
+{
+ if (m_runningUrl && m_hostName.IsEmpty())
+ {
+ nsCOMPtr<nsIURI> url = do_QueryInterface(m_runningUrl);
+ url->GetAsciiHost(m_hostName);
+ }
+
+ return m_hostName;
+}
+
+const nsCString&
+nsImapProtocol::GetImapUserName()
+{
+ nsCOMPtr<nsIMsgIncomingServer> server = do_QueryReferent(m_server);
+ if (m_userName.IsEmpty() && server)
+ server->GetUsername(m_userName);
+ return m_userName;
+}
+
+const char*
+nsImapProtocol::GetImapServerKey()
+{
+ nsCOMPtr<nsIMsgIncomingServer> server = do_QueryReferent(m_server);
+ if (m_serverKey.IsEmpty() && server)
+ server->GetKey(m_serverKey);
+ return m_serverKey.get();
+}
+
+void
+nsImapProtocol::SetupSinkProxy()
+{
+ nsresult res;
+ if (m_runningUrl)
+ {
+ if (!m_imapMailFolderSink)
+ {
+ nsCOMPtr<nsIImapMailFolderSink> aImapMailFolderSink;
+ (void) m_runningUrl->GetImapMailFolderSink(getter_AddRefs(aImapMailFolderSink));
+ if (aImapMailFolderSink)
+ {
+ m_imapMailFolderSink = new ImapMailFolderSinkProxy(aImapMailFolderSink);
+ }
+ }
+
+ if (!m_imapMessageSink)
+ {
+ nsCOMPtr<nsIImapMessageSink> aImapMessageSink;
+ (void) m_runningUrl->GetImapMessageSink(getter_AddRefs(aImapMessageSink));
+ m_imapMessageSink = new ImapMessageSinkProxy(aImapMessageSink);
+ }
+ if (!m_imapServerSink)
+ {
+ nsCOMPtr<nsIImapServerSink> aImapServerSink;
+ res = m_runningUrl->GetImapServerSink(getter_AddRefs(aImapServerSink));
+ m_imapServerSink = new ImapServerSinkProxy(aImapServerSink);
+ }
+ if (!m_imapProtocolSink)
+ {
+ nsCOMPtr<nsIImapProtocolSink> anImapProxyHelper(do_QueryInterface(NS_ISUPPORTS_CAST(nsIImapProtocolSink*, this), &res));
+ m_imapProtocolSink = new ImapProtocolSinkProxy(anImapProxyHelper);
+ }
+ }
+}
+
+static void SetSecurityCallbacksFromChannel(nsISocketTransport* aTrans, nsIChannel* aChannel)
+{
+ nsCOMPtr<nsIInterfaceRequestor> callbacks;
+ aChannel->GetNotificationCallbacks(getter_AddRefs(callbacks));
+
+ nsCOMPtr<nsILoadGroup> loadGroup;
+ aChannel->GetLoadGroup(getter_AddRefs(loadGroup));
+
+ nsCOMPtr<nsIInterfaceRequestor> securityCallbacks;
+ MsgNewNotificationCallbacksAggregation(callbacks, loadGroup,
+ getter_AddRefs(securityCallbacks));
+ if (securityCallbacks)
+ aTrans->SetSecurityCallbacks(securityCallbacks);
+}
+
+// Setup With Url is intended to set up data which is held on a PER URL basis and not
+// a per connection basis. If you have data which is independent of the url we are currently
+// running, then you should put it in Initialize().
+// This is only ever called from the UI thread. It is called from LoadUrl, right
+// before the url gets run - i.e., the url is next in line to run.
+nsresult nsImapProtocol::SetupWithUrl(nsIURI * aURL, nsISupports* aConsumer)
+{
+ nsresult rv = NS_ERROR_FAILURE;
+ NS_PRECONDITION(aURL, "null URL passed into Imap Protocol");
+ if (aURL)
+ {
+ m_runningUrl = do_QueryInterface(aURL, &rv);
+ if (NS_FAILED(rv)) return rv;
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningUrl);
+ nsCOMPtr<nsIMsgIncomingServer> server = do_QueryReferent(m_server);
+ if (!server)
+ {
+ rv = mailnewsUrl->GetServer(getter_AddRefs(server));
+ NS_ENSURE_SUCCESS(rv, rv);
+ m_server = do_GetWeakReference(server);
+ }
+ nsCOMPtr <nsIMsgFolder> folder;
+ mailnewsUrl->GetFolder(getter_AddRefs(folder));
+ mFolderLastModSeq = 0;
+ mFolderTotalMsgCount = 0;
+ mFolderHighestUID = 0;
+ m_uidValidity = kUidUnknown;
+ if (folder)
+ {
+ nsCOMPtr<nsIMsgDatabase> folderDB;
+ nsCOMPtr<nsIDBFolderInfo> folderInfo;
+ folder->GetDBFolderInfoAndDB(getter_AddRefs(folderInfo), getter_AddRefs(folderDB));
+ if (folderInfo)
+ {
+ nsCString modSeqStr;
+ folderInfo->GetCharProperty(kModSeqPropertyName, modSeqStr);
+ mFolderLastModSeq = ParseUint64Str(modSeqStr.get());
+ folderInfo->GetNumMessages(&mFolderTotalMsgCount);
+ folderInfo->GetUint32Property(kHighestRecordedUIDPropertyName, 0, &mFolderHighestUID);
+ folderInfo->GetImapUidValidity(&m_uidValidity);
+ }
+ }
+ nsCOMPtr<nsIImapIncomingServer> imapServer = do_QueryInterface(server);
+ nsCOMPtr<nsIStreamListener> aRealStreamListener = do_QueryInterface(aConsumer);
+ m_runningUrl->GetMockChannel(getter_AddRefs(m_mockChannel));
+ imapServer->GetIsGMailServer(&m_isGmailServer);
+ if (!m_mockChannel)
+ {
+ // there are several imap operations that aren't initiated via a nsIChannel::AsyncOpen call on the mock channel.
+ // such as selecting a folder. nsImapProtocol now insists on a mock channel when processing a url.
+ nsCOMPtr<nsIChannel> channel;
+ rv = NS_NewChannel(getter_AddRefs(channel), aURL, nullptr, nullptr, nullptr, 0);
+ m_mockChannel = do_QueryInterface(channel);
+
+ // Certain imap operations (not initiated by the IO Service via AsyncOpen) can be interrupted by the stop button on the toolbar.
+ // We do this by using the loadgroup of the docshell for the message pane. We really shouldn't be doing this..
+ // See the comment in nsMsgMailNewsUrl::GetLoadGroup.
+ nsCOMPtr<nsILoadGroup> loadGroup;
+ mailnewsUrl->GetLoadGroup(getter_AddRefs(loadGroup)); // get the message pane load group
+ nsCOMPtr<nsIRequest> ourRequest = do_QueryInterface(m_mockChannel);
+ if (loadGroup)
+ loadGroup->AddRequest(ourRequest, nullptr /* context isupports */);
+ }
+
+ if (m_mockChannel)
+ {
+ m_mockChannel->SetImapProtocol(this);
+ // if we have a listener from a mock channel, over-ride the consumer that was passed in
+ nsCOMPtr<nsIStreamListener> channelListener;
+ m_mockChannel->GetChannelListener(getter_AddRefs(channelListener));
+ if (channelListener) // only over-ride if we have a non null channel listener
+ aRealStreamListener = channelListener;
+ m_mockChannel->GetChannelContext(getter_AddRefs(m_channelContext));
+ nsCOMPtr<nsIMsgWindow> msgWindow;
+ GetMsgWindow(getter_AddRefs(msgWindow));
+ if (!msgWindow)
+ GetTopmostMsgWindow(getter_AddRefs(msgWindow));
+ if (msgWindow)
+ {
+ nsCOMPtr<nsIDocShell> docShell;
+ msgWindow->GetMessageWindowDocShell(getter_AddRefs(docShell));
+ nsCOMPtr<nsIInterfaceRequestor> ir(do_QueryInterface(docShell));
+ nsCOMPtr<nsIInterfaceRequestor> interfaceRequestor;
+ msgWindow->GetNotificationCallbacks(getter_AddRefs(interfaceRequestor));
+ nsCOMPtr<nsIInterfaceRequestor> aggregateIR;
+ MsgNewInterfaceRequestorAggregation(interfaceRequestor, ir, getter_AddRefs(aggregateIR));
+ m_mockChannel->SetNotificationCallbacks(aggregateIR);
+ }
+ }
+
+ // since we'll be making calls directly from the imap thread to the channel listener,
+ // we need to turn it into a proxy object....we'll assume that the listener is on the same thread
+ // as the event sink queue
+ if (aRealStreamListener)
+ {
+ NS_ASSERTION(!m_channelListener, "shouldn't already have a channel listener");
+ m_channelListener = new StreamListenerProxy(aRealStreamListener);
+ }
+
+ server->GetRealHostName(m_realHostName);
+ int32_t authMethod;
+ (void) server->GetAuthMethod(&authMethod);
+ InitPrefAuthMethods(authMethod);
+ (void) server->GetSocketType(&m_socketType);
+ bool shuttingDown;
+ (void) imapServer->GetShuttingDown(&shuttingDown);
+ if (!shuttingDown)
+ (void) imapServer->GetUseIdle(&m_useIdle);
+ else
+ m_useIdle = false;
+ imapServer->GetFetchByChunks(&m_fetchByChunks);
+ imapServer->GetSendID(&m_sendID);
+
+ nsAutoString trashFolderName;
+ if (NS_SUCCEEDED(imapServer->GetTrashFolderName(trashFolderName)))
+ CopyUTF16toMUTF7(trashFolderName, m_trashFolderName);
+
+ nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
+ if (prefBranch)
+ {
+ bool preferPlainText;
+ prefBranch->GetBoolPref("mailnews.display.prefer_plaintext", &preferPlainText);
+ // If the pref has changed since the last time we ran a url,
+ // clear the shell cache for this host.
+ if (preferPlainText != m_preferPlainText)
+ {
+ m_hostSessionList->ClearShellCacheForHost(GetImapServerKey());
+ m_preferPlainText = preferPlainText;
+ }
+ }
+
+ if ( m_runningUrl && !m_transport /* and we don't have a transport yet */)
+ {
+ // extract the file name and create a file transport...
+ int32_t port=-1;
+ server->GetPort(&port);
+
+ if (port <= 0)
+ {
+ int32_t socketType;
+ // Be a bit smarter about setting the default port
+ port = (NS_SUCCEEDED(server->GetSocketType(&socketType)) &&
+ socketType == nsMsgSocketType::SSL) ?
+ nsIImapUrl::DEFAULT_IMAPS_PORT : nsIImapUrl::DEFAULT_IMAP_PORT;
+ }
+ nsCOMPtr<nsISocketTransportService> socketService =
+ do_GetService(NS_SOCKETTRANSPORTSERVICE_CONTRACTID, &rv);
+ if (NS_SUCCEEDED(rv) && aURL)
+ {
+ aURL->GetPort(&port);
+
+ Log("SetupWithUrl", nullptr, "clearing IMAP_CONNECTION_IS_OPEN");
+ ClearFlag(IMAP_CONNECTION_IS_OPEN);
+ const char *connectionType = nullptr;
+
+ if (m_socketType == nsMsgSocketType::SSL)
+ connectionType = "ssl";
+ else if (m_socketType == nsMsgSocketType::alwaysSTARTTLS)
+ connectionType = "starttls";
+ // This can go away once we think everyone is migrated
+ // away from the trySTARTTLS socket type.
+ else if (m_socketType == nsMsgSocketType::trySTARTTLS)
+ connectionType = "starttls";
+
+ nsCOMPtr<nsIProxyInfo> proxyInfo;
+ rv = MsgExamineForProxy("imap", m_realHostName.get(), port, getter_AddRefs(proxyInfo));
+ if (NS_FAILED(rv))
+ proxyInfo = nullptr;
+
+ const nsACString *socketHost;
+ uint16_t socketPort;
+
+ if (m_overRideUrlConnectionInfo)
+ {
+ socketHost = &m_logonHost;
+ socketPort = m_logonPort;
+ }
+ else
+ {
+ socketHost = &m_realHostName;
+ socketPort = port;
+ }
+ rv = socketService->CreateTransport(&connectionType, connectionType != nullptr,
+ *socketHost, socketPort, proxyInfo,
+ getter_AddRefs(m_transport));
+ if (NS_FAILED(rv) && m_socketType == nsMsgSocketType::trySTARTTLS)
+ {
+ connectionType = nullptr;
+ m_socketType = nsMsgSocketType::plain;
+ rv = socketService->CreateTransport(&connectionType, connectionType != nullptr,
+ *socketHost, socketPort, proxyInfo,
+ getter_AddRefs(m_transport));
+ }
+ // remember so we can know whether we can issue a start tls or not...
+ m_connectionType = connectionType;
+ if (m_transport && m_mockChannel)
+ {
+ uint8_t qos;
+ rv = GetQoSBits(&qos);
+ if (NS_SUCCEEDED(rv))
+ m_transport->SetQoSBits(qos);
+
+ // Ensure that the socket can get the notification callbacks
+ SetSecurityCallbacksFromChannel(m_transport, m_mockChannel);
+
+ // open buffered, blocking input stream
+ rv = m_transport->OpenInputStream(nsITransport::OPEN_BLOCKING, 0, 0, getter_AddRefs(m_inputStream));
+ if (NS_FAILED(rv)) return rv;
+
+ // open buffered, blocking output stream
+ rv = m_transport->OpenOutputStream(nsITransport::OPEN_BLOCKING, 0, 0, getter_AddRefs(m_outputStream));
+ if (NS_FAILED(rv)) return rv;
+ SetFlag(IMAP_CONNECTION_IS_OPEN);
+ }
+ }
+ } // if m_runningUrl
+
+ if (m_transport && m_mockChannel)
+ {
+ m_transport->SetTimeout(nsISocketTransport::TIMEOUT_CONNECT, gResponseTimeout + 60);
+ int32_t readWriteTimeout = gResponseTimeout;
+ if (m_runningUrl)
+ {
+ m_runningUrl->GetImapAction(&m_imapAction);
+ // this is a silly hack, but the default of 100 seconds is way too long
+ // for things like APPEND, which should come back immediately.
+ if (m_imapAction == nsIImapUrl::nsImapAppendMsgFromFile ||
+ m_imapAction == nsIImapUrl::nsImapAppendDraftFromFile)
+ {
+ readWriteTimeout = 20;
+ }
+ else if (m_imapAction == nsIImapUrl::nsImapOnlineMove ||
+ m_imapAction == nsIImapUrl::nsImapOnlineCopy)
+ {
+ nsCString messageIdString;
+ m_runningUrl->GetListOfMessageIds(messageIdString);
+ uint32_t copyCount = CountMessagesInIdString(messageIdString.get());
+ // If we're move/copying a large number of messages,
+ // which should be rare, increase the timeout based on number
+ // of messages. 40 messages per second should be sufficiently slow.
+ if (copyCount > 2400) // 40 * 60, 60 is default read write timeout
+ readWriteTimeout = std::max(readWriteTimeout, (int32_t)copyCount/40);
+ }
+ }
+ m_transport->SetTimeout(nsISocketTransport::TIMEOUT_READ_WRITE, readWriteTimeout);
+ // set the security info for the mock channel to be the security status for our underlying transport.
+ nsCOMPtr<nsISupports> securityInfo;
+ m_transport->GetSecurityInfo(getter_AddRefs(securityInfo));
+ m_mockChannel->SetSecurityInfo(securityInfo);
+
+ SetSecurityCallbacksFromChannel(m_transport, m_mockChannel);
+
+ nsCOMPtr<nsITransportEventSink> sink = do_QueryInterface(m_mockChannel);
+ if (sink) {
+ nsCOMPtr<nsIThread> thread = do_GetMainThread();
+ m_transport->SetEventSink(sink, thread);
+ }
+
+ // and if we have a cache entry that we are saving the message to, set the security info on it too.
+ // since imap only uses the memory cache, passing this on is the right thing to do.
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningUrl);
+ if (mailnewsUrl)
+ {
+ nsCOMPtr<nsICacheEntryDescriptor> cacheEntry;
+ mailnewsUrl->GetMemCacheEntry(getter_AddRefs(cacheEntry));
+ if (cacheEntry)
+ cacheEntry->SetSecurityInfo(securityInfo);
+ }
+ }
+ } // if aUR
+
+ return rv;
+}
+
+
+// when the connection is done processing the current state, free any per url state data...
+void nsImapProtocol::ReleaseUrlState(bool rerunning)
+{
+ // clear out the socket's reference to the notification callbacks for this transaction
+ {
+ MutexAutoLock mon(mLock);
+ if (m_transport)
+ {
+ m_transport->SetSecurityCallbacks(nullptr);
+ m_transport->SetEventSink(nullptr, nullptr);
+ }
+ }
+
+ if (m_mockChannel && !rerunning)
+ {
+ // Proxy the close of the channel to the ui thread.
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->CloseMockChannel(m_mockChannel);
+ else
+ m_mockChannel->Close();
+
+ {
+ // grab a lock so m_mockChannel doesn't get cleared out
+ // from under us.
+ MutexAutoLock mon(mLock);
+ if (m_mockChannel)
+ {
+ // Proxy the release of the channel to the main thread. This is something
+ // that the xpcom proxy system should do for us!
+ nsCOMPtr<nsIThread> thread = do_GetMainThread();
+ nsIImapMockChannel *doomed = nullptr;
+ m_mockChannel.swap(doomed);
+ NS_ProxyRelease(thread, doomed);
+ }
+ }
+ }
+
+ m_channelContext = nullptr; // this might be the url - null it out before the final release of the url
+ m_imapMessageSink = nullptr;
+
+ // Proxy the release of the listener to the main thread. This is something
+ // that the xpcom proxy system should do for us!
+ {
+ // grab a lock so the m_channelListener doesn't get cleared.
+ MutexAutoLock mon(mLock);
+ if (m_channelListener)
+ {
+ nsCOMPtr<nsIThread> thread = do_GetMainThread();
+ nsIStreamListener *doomed = nullptr;
+ m_channelListener.swap(doomed);
+ NS_ProxyRelease(thread, doomed);
+ }
+ }
+ m_channelInputStream = nullptr;
+ m_channelOutputStream = nullptr;
+
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsurl;
+ nsCOMPtr<nsIImapMailFolderSink> saveFolderSink;
+
+ {
+ MutexAutoLock mon(mLock);
+ if (m_runningUrl)
+ {
+ mailnewsurl = do_QueryInterface(m_runningUrl);
+ saveFolderSink = m_imapMailFolderSink;
+
+ m_runningUrl = nullptr; // force us to release our last reference on the url
+ m_urlInProgress = false;
+ }
+ }
+ // Need to null this out whether we have an m_runningUrl or not
+ m_imapMailFolderSink = nullptr;
+
+ // we want to make sure the imap protocol's last reference to the url gets released
+ // back on the UI thread. This ensures that the objects the imap url hangs on to
+ // properly get released back on the UI thread.
+ if (saveFolderSink)
+ {
+ nsCOMPtr<nsIThread> thread = do_GetMainThread();
+ nsIMsgMailNewsUrl *doomed = nullptr;
+ mailnewsurl.swap(doomed);
+ NS_ProxyRelease(thread, doomed);
+ saveFolderSink = nullptr;
+ }
+}
+
+
+class nsImapThreadShutdownEvent : public nsRunnable {
+public:
+ nsImapThreadShutdownEvent(nsIThread *thread) : mThread(thread) {
+ }
+ NS_IMETHOD Run() {
+ mThread->Shutdown();
+ return NS_OK;
+ }
+private:
+ nsCOMPtr<nsIThread> mThread;
+};
+
+
+NS_IMETHODIMP nsImapProtocol::Run()
+{
+ PR_CEnterMonitor(this);
+ NS_ASSERTION(!m_imapThreadIsRunning,
+ "Oh. oh. thread is already running. What's wrong here?");
+ if (m_imapThreadIsRunning)
+ {
+ PR_CExitMonitor(this);
+ return NS_OK;
+ }
+
+ m_imapThreadIsRunning = true;
+ PR_CExitMonitor(this);
+
+ // call the platform specific main loop ....
+ ImapThreadMainLoop();
+
+ if (m_runningUrl)
+ {
+ nsCOMPtr<nsIThread> thread = do_GetMainThread();
+ nsIImapUrl *doomed = nullptr;
+ m_runningUrl.swap(doomed);
+ NS_ProxyRelease(thread, doomed);
+ }
+
+ // close streams via UI thread if it's not already done
+ if (m_imapProtocolSink)
+ m_imapProtocolSink->CloseStreams();
+
+ m_imapMailFolderSink = nullptr;
+ m_imapMessageSink = nullptr;
+
+ // shutdown this thread, but do it from the main thread
+ nsCOMPtr<nsIRunnable> ev = new nsImapThreadShutdownEvent(m_iThread);
+ if (NS_FAILED(NS_DispatchToMainThread(ev)))
+ NS_WARNING("Failed to dispatch nsImapThreadShutdownEvent");
+ m_iThread = nullptr;
+ return NS_OK;
+}
+
+//
+// Must be called from UI thread only
+//
+NS_IMETHODIMP nsImapProtocol::CloseStreams()
+{
+ // make sure that it is called by the UI thread
+ NS_ABORT_IF_FALSE(NS_IsMainThread(), "CloseStreams() should not be called from an off UI thread");
+
+ {
+ MutexAutoLock mon(mLock);
+ if (m_transport)
+ {
+ // make sure the transport closes (even if someone is still indirectly
+ // referencing it).
+ m_transport->Close(NS_ERROR_ABORT);
+ m_transport = nullptr;
+ }
+ m_inputStream = nullptr;
+ m_outputStream = nullptr;
+ m_channelListener = nullptr;
+ m_channelContext = nullptr;
+ if (m_mockChannel)
+ {
+ m_mockChannel->Close();
+ m_mockChannel = nullptr;
+ }
+ m_channelInputStream = nullptr;
+ m_channelOutputStream = nullptr;
+
+ // Close scope because we must let go of the monitor before calling
+ // RemoveConnection to unblock anyone who tries to get a monitor to the
+ // protocol object while holding onto a monitor to the server.
+ }
+ nsCOMPtr<nsIMsgIncomingServer> me_server = do_QueryReferent(m_server);
+ if (me_server)
+ {
+ nsresult result;
+ nsCOMPtr<nsIImapIncomingServer>
+ aImapServer(do_QueryInterface(me_server, &result));
+ if (NS_SUCCEEDED(result))
+ aImapServer->RemoveConnection(this);
+ me_server = nullptr;
+ }
+ m_server = nullptr;
+ // take this opportunity of being on the UI thread to
+ // persist chunk prefs if they've changed
+ if (gChunkSizeDirty)
+ {
+ nsCOMPtr<nsIPrefBranch> prefBranch(do_GetService(NS_PREFSERVICE_CONTRACTID));
+ if (prefBranch)
+ {
+ prefBranch->SetIntPref("mail.imap.chunk_size", gChunkSize);
+ prefBranch->SetIntPref("mail.imap.min_chunk_size_threshold", gChunkThreshold);
+ gChunkSizeDirty = false;
+ }
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapProtocol::GetUrlWindow(nsIMsgMailNewsUrl *aUrl,
+ nsIMsgWindow **aMsgWindow)
+{
+ NS_ENSURE_ARG_POINTER(aUrl);
+ NS_ENSURE_ARG_POINTER(aMsgWindow);
+ return aUrl->GetMsgWindow(aMsgWindow);
+}
+
+NS_IMETHODIMP nsImapProtocol::OnInputStreamReady(nsIAsyncInputStream *inStr)
+{
+ // should we check if it's a close vs. data available?
+ if (m_idle)
+ {
+ uint64_t bytesAvailable = 0;
+ (void) inStr->Available(&bytesAvailable);
+ // check if data available - might be a close
+ if (bytesAvailable != 0)
+ {
+ ReentrantMonitorAutoEnter mon(m_urlReadyToRunMonitor);
+ m_lastActiveTime = PR_Now();
+ m_nextUrlReadyToRun = true;
+ mon.Notify();
+ }
+ }
+ return NS_OK;
+}
+
+// this is to be called from the UI thread. It sets m_threadShouldDie,
+// and then signals the imap thread, which, when it wakes up, should exit.
+// The imap thread cleanup code will check m_safeToCloseConnection.
+NS_IMETHODIMP
+nsImapProtocol::TellThreadToDie(bool aIsSafeToClose)
+{
+ NS_WARN_IF_FALSE(NS_IsMainThread(),
+ "TellThreadToDie(aIsSafeToClose) should only be called from UI thread");
+ MutexAutoLock mon(mLock);
+
+ nsCOMPtr<nsIMsgIncomingServer> me_server = do_QueryReferent(m_server);
+ if (me_server)
+ {
+ nsresult rv;
+ nsCOMPtr<nsIImapIncomingServer>
+ aImapServer(do_QueryInterface(me_server, &rv));
+ if (NS_SUCCEEDED(rv))
+ aImapServer->RemoveConnection(this);
+ m_server = nullptr;
+ me_server = nullptr;
+ }
+ {
+ ReentrantMonitorAutoEnter deathMon(m_threadDeathMonitor);
+ m_safeToCloseConnection = aIsSafeToClose;
+ m_threadShouldDie = true;
+ }
+ ReentrantMonitorAutoEnter readyMon(m_urlReadyToRunMonitor);
+ m_nextUrlReadyToRun = true;
+ readyMon.Notify();
+ return NS_OK;
+}
+
+void
+nsImapProtocol::TellThreadToDie()
+{
+ nsresult rv = NS_OK;
+ NS_WARN_IF_FALSE(!NS_IsMainThread(),
+ "TellThreadToDie() should not be called from UI thread");
+
+ // prevent re-entering this method because it may lock the UI.
+ if (m_inThreadShouldDie)
+ return;
+ m_inThreadShouldDie = true;
+
+ // This routine is called only from the imap protocol thread.
+ // The UI thread causes this to be called by calling TellThreadToDie.
+ // In that case, m_safeToCloseConnection will be FALSE if it's dropping a
+ // timed out connection, true when closing a cached connection.
+ // We're using PR_CEnter/ExitMonitor because Monitors don't like having
+ // us to hold one monitor and call code that gets a different monitor. And
+ // some of the methods we call here use Monitors.
+ PR_CEnterMonitor(this);
+
+ m_urlInProgress = true; // let's say it's busy so no one tries to use
+ // this about to die connection.
+ bool urlWritingData = false;
+ bool connectionIdle = !m_runningUrl;
+
+ if (!connectionIdle)
+ urlWritingData = m_imapAction == nsIImapUrl::nsImapAppendMsgFromFile
+ || m_imapAction == nsIImapUrl::nsImapAppendDraftFromFile;
+
+ bool closeNeeded = GetServerStateParser().GetIMAPstate() ==
+ nsImapServerResponseParser::kFolderSelected && m_safeToCloseConnection;
+ nsCString command;
+ // if a url is writing data, we can't even logout, so we're just
+ // going to close the connection as if the user pressed stop.
+ if (m_currentServerCommandTagNumber > 0 && !urlWritingData)
+ {
+ bool isAlive = false;
+ if (m_transport)
+ rv = m_transport->IsAlive(&isAlive);
+
+ if (TestFlag(IMAP_CONNECTION_IS_OPEN) && m_idle && isAlive)
+ EndIdle(false);
+
+ if (NS_SUCCEEDED(rv) && isAlive && closeNeeded && GetDeleteIsMoveToTrash() &&
+ TestFlag(IMAP_CONNECTION_IS_OPEN) && m_outputStream)
+ Close(true, connectionIdle);
+
+ if (NS_SUCCEEDED(rv) && isAlive && TestFlag(IMAP_CONNECTION_IS_OPEN) &&
+ NS_SUCCEEDED(GetConnectionStatus()) && m_outputStream)
+ Logout(true, connectionIdle);
+ }
+ PR_CExitMonitor(this);
+ // close streams via UI thread
+ if (m_imapProtocolSink)
+ {
+ m_imapProtocolSink->CloseStreams();
+ m_imapProtocolSink = nullptr;
+ }
+ Log("TellThreadToDie", nullptr, "close socket connection");
+
+ {
+ ReentrantMonitorAutoEnter mon(m_threadDeathMonitor);
+ m_threadShouldDie = true;
+ }
+ {
+ ReentrantMonitorAutoEnter dataMon(m_dataAvailableMonitor);
+ dataMon.Notify();
+ }
+ ReentrantMonitorAutoEnter urlReadyMon(m_urlReadyToRunMonitor);
+ urlReadyMon.NotifyAll();
+}
+
+NS_IMETHODIMP
+nsImapProtocol::GetLastActiveTimeStamp(PRTime* aTimeStamp)
+{
+ if (aTimeStamp)
+ *aTimeStamp = m_lastActiveTime;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsImapProtocol::PseudoInterruptMsgLoad(nsIMsgFolder *aImapFolder, nsIMsgWindow *aMsgWindow, bool *interrupted)
+{
+ NS_ENSURE_ARG (interrupted);
+
+ *interrupted = false;
+
+ PR_CEnterMonitor(this);
+
+ if (m_runningUrl && !TestFlag(IMAP_CLEAN_UP_URL_STATE))
+ {
+ nsImapAction imapAction;
+ m_runningUrl->GetImapAction(&imapAction);
+
+ if (imapAction == nsIImapUrl::nsImapMsgFetch)
+ {
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIImapUrl> runningImapURL;
+
+ rv = GetRunningImapURL(getter_AddRefs(runningImapURL));
+ if (NS_SUCCEEDED(rv) && runningImapURL)
+ {
+ nsCOMPtr <nsIMsgFolder> runningImapFolder;
+ nsCOMPtr <nsIMsgWindow> msgWindow;
+ nsCOMPtr <nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(runningImapURL);
+ mailnewsUrl->GetMsgWindow(getter_AddRefs(msgWindow));
+ mailnewsUrl->GetFolder(getter_AddRefs(runningImapFolder));
+ if (aImapFolder == runningImapFolder && msgWindow == aMsgWindow)
+ {
+ PseudoInterrupt(true);
+ *interrupted = true;
+ }
+ }
+ }
+ }
+ PR_CExitMonitor(this);
+#ifdef DEBUG_bienvenu
+ printf("interrupt msg load : %s\n", (*interrupted) ? "TRUE" : "FALSE");
+#endif
+ return NS_OK;
+}
+
+void
+nsImapProtocol::ImapThreadMainLoop()
+{
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("ImapThreadMainLoop entering [this=%x]\n", this));
+
+ PRIntervalTime sleepTime = kImapSleepTime;
+ while (!DeathSignalReceived())
+ {
+ nsresult rv = NS_OK;
+ bool readyToRun;
+
+ // wait for an URL to process...
+ {
+ ReentrantMonitorAutoEnter mon(m_urlReadyToRunMonitor);
+
+ while (NS_SUCCEEDED(rv) && !DeathSignalReceived() &&
+ !m_nextUrlReadyToRun && !m_threadShouldDie)
+ rv = mon.Wait(sleepTime);
+
+ readyToRun = m_nextUrlReadyToRun;
+ m_nextUrlReadyToRun = false;
+ }
+ // This will happen if the UI thread signals us to die
+ if (m_threadShouldDie)
+ {
+ TellThreadToDie();
+ break;
+ }
+
+ if (NS_FAILED(rv) && PR_PENDING_INTERRUPT_ERROR == PR_GetError())
+ {
+ printf("error waiting for monitor\n");
+ break;
+ }
+
+ if (readyToRun && m_runningUrl)
+ {
+ if (m_currentServerCommandTagNumber && m_transport)
+ {
+ bool isAlive;
+ rv = m_transport->IsAlive(&isAlive);
+ // if the transport is not alive, and we've ever sent a command with this connection, kill it.
+ // otherwise, we've probably just not finished setting it so don't kill it!
+ if (NS_FAILED(rv) || !isAlive)
+ {
+ // This says we never started running the url, which is the case.
+ m_runningUrl->SetRerunningUrl(false);
+ RetryUrl();
+ return;
+ }
+ }
+ //
+ // NOTE: Though we cleared m_nextUrlReadyToRun above, it may have been
+ // set by LoadImapUrl, which runs on the main thread. Because of this,
+ // we must not try to clear m_nextUrlReadyToRun here.
+ //
+ if (ProcessCurrentURL())
+ {
+ m_nextUrlReadyToRun = true;
+ m_imapMailFolderSink = nullptr;
+ }
+ else
+ {
+ // see if we want to go into idle mode. Might want to check a pref here too.
+ if (m_useIdle && !m_urlInProgress && GetServerStateParser().GetCapabilityFlag() & kHasIdleCapability
+ && GetServerStateParser().GetIMAPstate()
+ == nsImapServerResponseParser::kFolderSelected)
+ {
+ Idle(); // for now, lets just do it. We'll probably want to use a timer
+ }
+ else // if not idle, don't need to remember folder sink
+ m_imapMailFolderSink = nullptr;
+ }
+ }
+ else if (m_idle && !m_threadShouldDie)
+ {
+ HandleIdleResponses();
+ }
+ if (!GetServerStateParser().Connected())
+ break;
+#ifdef DEBUG_bienvenu
+ else
+ printf("ready to run but no url and not idle\n");
+#endif
+ // This can happen if the UI thread closes cached connections in the
+ // OnStopRunningUrl notification.
+ if (m_threadShouldDie)
+ TellThreadToDie();
+ }
+ m_imapThreadIsRunning = false;
+
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("ImapThreadMainLoop leaving [this=%x]\n", this));
+}
+
+void nsImapProtocol::HandleIdleResponses()
+{
+ // int32_t oldRecent = GetServerStateParser().NumberOfRecentMessages();
+ nsAutoCString commandBuffer(GetServerCommandTag());
+ commandBuffer.Append(" IDLE" CRLF);
+
+ do
+ {
+ ParseIMAPandCheckForNewMail(commandBuffer.get());
+ }
+ while (m_inputStreamBuffer->NextLineAvailable() && GetServerStateParser().Connected());
+
+ // if (oldRecent != GetServerStateParser().NumberOfRecentMessages())
+ // We might check that something actually changed, but for now we can
+ // just assume it. OnNewIdleMessages must run a url, so that
+ // we'll go back into asyncwait mode.
+ if (GetServerStateParser().Connected() && m_imapMailFolderSink)
+ m_imapMailFolderSink->OnNewIdleMessages();
+}
+
+void nsImapProtocol::EstablishServerConnection()
+{
+#define ESC_LENGTH(x) (sizeof(x) - 1)
+#define ESC_OK "* OK"
+#define ESC_OK_LEN ESC_LENGTH(ESC_OK)
+#define ESC_PREAUTH "* PREAUTH"
+#define ESC_PREAUTH_LEN ESC_LENGTH(ESC_PREAUTH)
+#define ESC_CAPABILITY_STAR "* "
+#define ESC_CAPABILITY_STAR_LEN ESC_LENGTH(ESC_CAPABILITY_STAR)
+#define ESC_CAPABILITY_OK "* OK ["
+#define ESC_CAPABILITY_OK_LEN ESC_LENGTH(ESC_CAPABILITY_OK)
+#define ESC_CAPABILITY_GREETING (ESC_CAPABILITY_OK "CAPABILITY")
+#define ESC_CAPABILITY_GREETING_LEN ESC_LENGTH(ESC_CAPABILITY_GREETING)
+
+ char * serverResponse = CreateNewLineFromSocket(); // read in the greeting
+
+ // record the fact that we've received a greeting for this connection so we don't ever
+ // try to do it again..
+ if (serverResponse)
+ SetFlag(IMAP_RECEIVED_GREETING);
+
+ if (!PL_strncasecmp(serverResponse, ESC_OK, ESC_OK_LEN))
+ {
+ SetConnectionStatus(NS_OK);
+
+ if (!PL_strncasecmp(serverResponse, ESC_CAPABILITY_GREETING, ESC_CAPABILITY_GREETING_LEN))
+ {
+ nsAutoCString tmpstr(serverResponse);
+ int32_t endIndex = tmpstr.FindChar(']', ESC_CAPABILITY_GREETING_LEN);
+ if (endIndex >= 0)
+ {
+ // Allocate the new buffer here. This buffer will be passed to
+ // ParseIMAPServerResponse() where it will be used to fill the
+ // fCurrentLine field and will be freed by the next call to
+ // ResetLexAnalyzer().
+ char *fakeServerResponse = (char*)PR_Malloc(PL_strlen(serverResponse));
+ // Munge the greeting into something that would pass for an IMAP
+ // server's response to a "CAPABILITY" command.
+ strcpy(fakeServerResponse, ESC_CAPABILITY_STAR);
+ strcat(fakeServerResponse, serverResponse + ESC_CAPABILITY_OK_LEN);
+ fakeServerResponse[endIndex - ESC_CAPABILITY_OK_LEN + ESC_CAPABILITY_STAR_LEN] = '\0';
+ // Tell the response parser that we just issued a "CAPABILITY" and
+ // got the following back.
+ GetServerStateParser().ParseIMAPServerResponse("1 CAPABILITY", true, fakeServerResponse);
+ }
+ }
+ }
+ else if (!PL_strncasecmp(serverResponse, ESC_PREAUTH, ESC_PREAUTH_LEN))
+ {
+ // we've been pre-authenticated.
+ // we can skip the whole password step, right into the
+ // kAuthenticated state
+ GetServerStateParser().PreauthSetAuthenticatedState();
+
+ if (GetServerStateParser().GetCapabilityFlag() == kCapabilityUndefined)
+ Capability();
+
+ if ( !(GetServerStateParser().GetCapabilityFlag() &
+ (kIMAP4Capability | kIMAP4rev1Capability | kIMAP4other) ) )
+ {
+ // AlertUserEvent_UsingId(MK_MSG_IMAP_SERVER_NOT_IMAP4);
+ SetConnectionStatus(NS_ERROR_FAILURE); // stop netlib
+ }
+ else
+ {
+ // let's record the user as authenticated.
+ m_imapServerSink->SetUserAuthenticated(true);
+
+ ProcessAfterAuthenticated();
+ // the connection was a success
+ SetConnectionStatus(NS_OK);
+ }
+ }
+
+ PR_Free(serverResponse); // we don't care about the greeting yet...
+
+#undef ESC_LENGTH
+#undef ESC_OK
+#undef ESC_OK_LEN
+#undef ESC_PREAUTH
+#undef ESC_PREAUTH_LEN
+#undef ESC_CAPABILITY_STAR
+#undef ESC_CAPABILITY_STAR_LEN
+#undef ESC_CAPABILITY_OK
+#undef ESC_CAPABILITY_OK_LEN
+#undef ESC_CAPABILITY_GREETING
+#undef ESC_CAPABILITY_GREETING_LEN
+}
+
+// This can get called from the UI thread or an imap thread.
+// It makes sure we don't get left with partial messages in
+// the memory cache.
+static void DoomCacheEntry(nsIMsgMailNewsUrl *url)
+{
+ bool readingFromMemCache = false;
+ nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(url);
+ imapUrl->GetMsgLoadingFromCache(&readingFromMemCache);
+ if (!readingFromMemCache)
+ {
+ nsCOMPtr<nsICacheEntryDescriptor> cacheEntry;
+ url->GetMemCacheEntry(getter_AddRefs(cacheEntry));
+ if (cacheEntry)
+ cacheEntry->Doom();
+ }
+}
+
+// returns true if another url was run, false otherwise.
+bool nsImapProtocol::ProcessCurrentURL()
+{
+ nsresult rv = NS_OK;
+ if (m_idle)
+ EndIdle();
+
+ if (m_retryUrlOnError)
+ {
+ // we clear this flag if we're re-running immediately, because that
+ // means we never sent a start running url notification, and later we
+ // don't send start running notification if we think we're rerunning
+ // the url (see first call to SetUrlState below). This means we won't
+ // send a start running notification, which means our stop running
+ // notification will be ignored because we don't think we were running.
+ m_runningUrl->SetRerunningUrl(false);
+ return RetryUrl();
+ }
+ Log("ProcessCurrentURL", nullptr, "entering");
+ (void) GetImapHostName(); // force m_hostName to get set.
+
+
+ bool logonFailed = false;
+ bool anotherUrlRun = false;
+ bool rerunningUrl = false;
+ bool isExternalUrl;
+ bool validUrl = true;
+
+ PseudoInterrupt(false); // clear this if left over from previous url.
+
+ m_runningUrl->GetRerunningUrl(&rerunningUrl);
+ m_runningUrl->GetExternalLinkUrl(&isExternalUrl);
+ m_runningUrl->GetValidUrl(&validUrl);
+ m_runningUrl->GetImapAction(&m_imapAction);
+
+ if (isExternalUrl)
+ {
+ if (m_imapAction == nsIImapUrl::nsImapSelectFolder)
+ {
+ // we need to send a start request so that the doc loader
+ // will call HandleContent on the imap service so we
+ // can abort this url, and run a new url in a new msg window
+ // to run the folder load url and get off this crazy merry-go-round.
+ if (m_channelListener)
+ {
+ nsCOMPtr<nsIRequest> request = do_QueryInterface(m_mockChannel);
+ m_channelListener->OnStartRequest(request, m_channelContext);
+ }
+ return false;
+ }
+ }
+
+ if (!m_imapMailFolderSink)
+ SetupSinkProxy(); // try this again. Evil, but I'm desperate.
+
+ // Reinitialize the parser
+ GetServerStateParser().InitializeState();
+ GetServerStateParser().SetConnected(true);
+
+ // acknowledge that we are running the url now..
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsurl = do_QueryInterface(m_runningUrl, &rv);
+ nsAutoCString urlSpec;
+ mailnewsurl->GetSpec(urlSpec);
+ Log("ProcessCurrentURL", urlSpec.get(), (validUrl) ? " = currentUrl\n" : " is not valid\n");
+ if (!validUrl)
+ return false;
+
+ if (NS_SUCCEEDED(rv) && mailnewsurl && m_imapMailFolderSink && !rerunningUrl)
+ m_imapMailFolderSink->SetUrlState(this, mailnewsurl, true, false,
+ NS_OK);
+
+ // if we are set up as a channel, we should notify our channel listener that we are starting...
+ // so pass in ourself as the channel and not the underlying socket or file channel the protocol
+ // happens to be using
+ if (m_channelListener) // ### not sure we want to do this if rerunning url...
+ {
+ nsCOMPtr<nsIRequest> request = do_QueryInterface(m_mockChannel);
+ m_channelListener->OnStartRequest(request, m_channelContext);
+ }
+ // If we haven't received the greeting yet, we need to make sure we strip
+ // it out of the input before we start to do useful things...
+ if (!TestFlag(IMAP_RECEIVED_GREETING))
+ EstablishServerConnection();
+
+ // Step 1: If we have not moved into the authenticated state yet then do so
+ // by attempting to logon.
+ if (!DeathSignalReceived() && NS_SUCCEEDED(GetConnectionStatus()) &&
+ (GetServerStateParser().GetIMAPstate() ==
+ nsImapServerResponseParser::kNonAuthenticated))
+ {
+ /* if we got here, the server's greeting should not have been PREAUTH */
+ if (GetServerStateParser().GetCapabilityFlag() == kCapabilityUndefined)
+ Capability();
+
+ if ( !(GetServerStateParser().GetCapabilityFlag() & (kIMAP4Capability | kIMAP4rev1Capability |
+ kIMAP4other) ) )
+ {
+ if (!DeathSignalReceived() && NS_SUCCEEDED(GetConnectionStatus()))
+ AlertUserEventUsingId(IMAP_SERVER_NOT_IMAP4);
+
+ SetConnectionStatus(NS_ERROR_FAILURE); // stop netlib
+ }
+ else
+ {
+ if ((m_connectionType.Equals("starttls")
+ && (m_socketType == nsMsgSocketType::trySTARTTLS
+ && (GetServerStateParser().GetCapabilityFlag() & kHasStartTLSCapability)))
+ || m_socketType == nsMsgSocketType::alwaysSTARTTLS)
+ {
+ StartTLS();
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ nsCOMPtr<nsISupports> secInfo;
+ nsCOMPtr<nsISocketTransport> strans = do_QueryInterface(m_transport, &rv);
+ if (NS_FAILED(rv))
+ return false;
+
+ rv = strans->GetSecurityInfo(getter_AddRefs(secInfo));
+
+ if (NS_SUCCEEDED(rv) && secInfo)
+ {
+ nsCOMPtr<nsISSLSocketControl> sslControl = do_QueryInterface(secInfo, &rv);
+
+ if (NS_SUCCEEDED(rv) && sslControl)
+ {
+ rv = sslControl->StartTLS();
+ if (NS_SUCCEEDED(rv))
+ {
+ if (m_socketType == nsMsgSocketType::trySTARTTLS)
+ m_imapServerSink->UpdateTrySTARTTLSPref(true);
+ // force re-issue of "capability", because servers may
+ // enable other auth features (e.g. remove LOGINDISABLED
+ // and add AUTH=PLAIN) after we upgraded to SSL.
+ Capability();
+ eIMAPCapabilityFlags capabilityFlag = GetServerStateParser().GetCapabilityFlag();
+ // Courier imap doesn't return STARTTLS capability if we've done
+ // a STARTTLS! But we need to remember this capability so we'll
+ // try to use STARTTLS next time.
+ if (!(capabilityFlag & kHasStartTLSCapability))
+ {
+ capabilityFlag |= kHasStartTLSCapability;
+ GetServerStateParser().SetCapabilityFlag(capabilityFlag);
+ CommitCapability();
+ }
+ }
+ }
+ }
+ if (NS_FAILED(rv))
+ {
+ nsAutoCString logLine("STARTTLS negotiation failed. Error 0x");
+ logLine.AppendInt(static_cast<uint32_t>(rv), 16);
+ Log("ProcessCurrentURL", nullptr, logLine.get());
+ if (m_socketType == nsMsgSocketType::alwaysSTARTTLS)
+ {
+ SetConnectionStatus(rv); // stop netlib
+ m_transport->Close(rv);
+ }
+ else if (m_socketType == nsMsgSocketType::trySTARTTLS)
+ m_imapServerSink->UpdateTrySTARTTLSPref(false);
+ }
+ }
+ else if (m_socketType == nsMsgSocketType::alwaysSTARTTLS)
+ {
+ SetConnectionStatus(NS_ERROR_FAILURE); // stop netlib
+ if (m_transport)
+ m_transport->Close(rv);
+ }
+ else if (m_socketType == nsMsgSocketType::trySTARTTLS)
+ {
+ // STARTTLS failed, so downgrade socket type
+ m_imapServerSink->UpdateTrySTARTTLSPref(false);
+ }
+ }
+ else if (m_socketType == nsMsgSocketType::trySTARTTLS)
+ {
+ // we didn't know the server supported TLS when we created
+ // the socket, so we're going to retry with a STARTTLS socket
+ if (GetServerStateParser().GetCapabilityFlag() & kHasStartTLSCapability)
+ {
+ ClearFlag(IMAP_CONNECTION_IS_OPEN);
+ TellThreadToDie();
+ SetConnectionStatus(NS_ERROR_FAILURE);
+ return RetryUrl();
+ }
+ else
+ {
+ // trySTARTTLS set, but server doesn't have TLS capability,
+ // so downgrade socket type
+ m_imapServerSink->UpdateTrySTARTTLSPref(false);
+ m_socketType = nsMsgSocketType::plain;
+ }
+ }
+ logonFailed = !TryToLogon();
+ if (m_retryUrlOnError)
+ return RetryUrl();
+ }
+ } // if death signal not received
+
+ if (!DeathSignalReceived() && (NS_SUCCEEDED(GetConnectionStatus())))
+ {
+ // if the server supports a language extension then we should
+ // attempt to issue the language extension.
+ if ( GetServerStateParser().GetCapabilityFlag() & kHasLanguageCapability)
+ Language();
+
+ if (m_runningUrl)
+ FindMailboxesIfNecessary();
+
+ nsImapState imapState;
+ if (m_runningUrl)
+ m_runningUrl->GetRequiredImapState(&imapState);
+
+ if (imapState == nsIImapUrl::nsImapAuthenticatedState)
+ ProcessAuthenticatedStateURL();
+ else // must be a url that requires us to be in the selected state
+ ProcessSelectedStateURL();
+
+ if (m_retryUrlOnError)
+ return RetryUrl();
+
+ // The URL has now been processed
+ if ((!logonFailed && NS_FAILED(GetConnectionStatus())) ||
+ DeathSignalReceived())
+ HandleCurrentUrlError();
+
+ }
+ else if (!logonFailed)
+ HandleCurrentUrlError();
+
+// if we are set up as a channel, we should notify our channel listener that we are stopping...
+// so pass in ourself as the channel and not the underlying socket or file channel the protocol
+// happens to be using
+ if (m_channelListener)
+ {
+ nsCOMPtr<nsIRequest> request = do_QueryInterface(m_mockChannel);
+ NS_ASSERTION(request, "no request");
+ if (request) {
+ nsresult status;
+ request->GetStatus(&status);
+ if (!GetServerStateParser().LastCommandSuccessful() && NS_SUCCEEDED(status))
+ status = NS_MSG_ERROR_IMAP_COMMAND_FAILED;
+ rv = m_channelListener->OnStopRequest(request, m_channelContext, status);
+ }
+ }
+ bool suspendUrl = false;
+ m_runningUrl->GetMoreHeadersToDownload(&suspendUrl);
+ if (mailnewsurl && m_imapMailFolderSink)
+ {
+ if (logonFailed)
+ rv = NS_ERROR_FAILURE;
+ else if (GetServerStateParser().CommandFailed())
+ rv = NS_MSG_ERROR_IMAP_COMMAND_FAILED;
+ else
+ rv = GetConnectionStatus();
+ // we are done with this url.
+ m_imapMailFolderSink->SetUrlState(this, mailnewsurl, false, suspendUrl,
+ rv);
+ // doom the cache entry
+ if (NS_FAILED(rv) && DeathSignalReceived() && m_mockChannel)
+ DoomCacheEntry(mailnewsurl);
+ }
+ else
+ NS_ERROR("missing url or sink");
+
+ // disable timeouts before caching connection.
+ if (m_transport)
+ m_transport->SetTimeout(nsISocketTransport::TIMEOUT_READ_WRITE, PR_UINT32_MAX);
+
+ SetFlag(IMAP_CLEAN_UP_URL_STATE);
+
+ nsCOMPtr <nsISupports> copyState;
+ if (m_runningUrl)
+ m_runningUrl->GetCopyState(getter_AddRefs(copyState));
+ // this is so hokey...we MUST clear any local references to the url
+ // BEFORE calling ReleaseUrlState
+ mailnewsurl = nullptr;
+
+ if (suspendUrl)
+ m_imapServerSink->SuspendUrl(m_runningUrl);
+ // save the imap folder sink since we need it to do the CopyNextStreamMessage
+ nsRefPtr<ImapMailFolderSinkProxy> imapMailFolderSink = m_imapMailFolderSink;
+ // release the url as we are done with it...
+ ReleaseUrlState(false);
+ ResetProgressInfo();
+
+ ClearFlag(IMAP_CLEAN_UP_URL_STATE);
+
+ if (imapMailFolderSink)
+ {
+ if (copyState)
+ {
+ rv = imapMailFolderSink->CopyNextStreamMessage(GetServerStateParser().LastCommandSuccessful() &&
+ NS_SUCCEEDED(GetConnectionStatus()),
+ copyState);
+ if (NS_FAILED(rv))
+ PR_LOG(IMAP, PR_LOG_ALWAYS, ("CopyNextStreamMessage failed:%lx\n", rv));
+
+ nsCOMPtr<nsIThread> thread = do_GetMainThread();
+ nsISupports *doomed = nullptr;
+ copyState.swap(doomed);
+ NS_ProxyRelease(thread, doomed);
+ }
+ // we might need this to stick around for IDLE support
+ m_imapMailFolderSink = imapMailFolderSink;
+ imapMailFolderSink = nullptr;
+ }
+ else
+ PR_LOG(IMAP, PR_LOG_ALWAYS, ("null imapMailFolderSink\n"));
+
+ // now try queued urls, now that we've released this connection.
+ if (m_imapServerSink)
+ {
+ if (NS_SUCCEEDED(GetConnectionStatus()))
+ rv = m_imapServerSink->LoadNextQueuedUrl(this, &anotherUrlRun);
+ else // if we don't do this, they'll just sit and spin until
+ // we run some other url on this server.
+ {
+ Log("ProcessCurrentURL", nullptr, "aborting queued urls");
+ rv = m_imapServerSink->AbortQueuedUrls();
+ }
+ }
+
+ // if we didn't run another url, release the server sink to
+ // cut circular refs.
+ if (!anotherUrlRun)
+ m_imapServerSink = nullptr;
+
+ nsCOMPtr<nsIImapIncomingServer> imapServer = do_QueryReferent(m_server, &rv);
+ if (NS_FAILED(GetConnectionStatus()) || !GetServerStateParser().Connected()
+ || GetServerStateParser().SyntaxError())
+ {
+ if (imapServer)
+ imapServer->RemoveConnection(this);
+
+ if (!DeathSignalReceived())
+ {
+ TellThreadToDie();
+ }
+ }
+ else
+ {
+ if (imapServer)
+ {
+ bool shuttingDown;
+ imapServer->GetShuttingDown(&shuttingDown);
+ if (shuttingDown)
+ m_useIdle = false;
+ }
+ }
+ return anotherUrlRun;
+}
+
+bool nsImapProtocol::RetryUrl()
+{
+ nsCOMPtr <nsIImapUrl> kungFuGripImapUrl = m_runningUrl;
+ nsCOMPtr <nsIImapMockChannel> saveMockChannel;
+
+ // the mock channel might be null - that's OK.
+ if (m_imapServerSink)
+ (void) m_imapServerSink->PrepareToRetryUrl(kungFuGripImapUrl, getter_AddRefs(saveMockChannel));
+
+ ReleaseUrlState(true);
+ nsresult rv;
+ nsCOMPtr<nsIImapIncomingServer> imapServer = do_QueryReferent(m_server, &rv);
+ if (NS_SUCCEEDED(rv))
+ imapServer->RemoveConnection(this);
+ if (m_imapServerSink)
+ m_imapServerSink->RetryUrl(kungFuGripImapUrl, saveMockChannel);
+ return (m_imapServerSink != nullptr); // we're running a url (the same url)
+}
+
+// ignoreBadAndNOResponses --> don't throw a error dialog if this command results in a NO or Bad response
+// from the server..in other words the command is "exploratory" and we don't really care if it succeeds or fails.
+void nsImapProtocol::ParseIMAPandCheckForNewMail(const char* commandString, bool aIgnoreBadAndNOResponses)
+{
+ if (commandString)
+ GetServerStateParser().ParseIMAPServerResponse(commandString, aIgnoreBadAndNOResponses);
+ else
+ GetServerStateParser().ParseIMAPServerResponse(m_currentCommand.get(), aIgnoreBadAndNOResponses);
+ // **** fix me for new mail biff state *****
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// End of nsIStreamListenerSupport
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+NS_IMETHODIMP
+nsImapProtocol::GetRunningUrl(nsIURI **result)
+{
+ if (result && m_runningUrl)
+ return m_runningUrl->QueryInterface(NS_GET_IID(nsIURI), (void**)
+ result);
+ else
+ return NS_ERROR_NULL_POINTER;
+}
+
+
+NS_IMETHODIMP nsImapProtocol::GetRunningImapURL(nsIImapUrl **aImapUrl)
+{
+ if (aImapUrl && m_runningUrl)
+ return m_runningUrl->QueryInterface(NS_GET_IID(nsIImapUrl), (void**) aImapUrl);
+ else
+ return NS_ERROR_NULL_POINTER;
+
+}
+
+/*
+ * Writes the data contained in dataBuffer into the current output stream. It also informs
+ * the transport layer that this data is now available for transmission.
+ * Returns a positive number for success, 0 for failure (not all the bytes were written to the
+ * stream, etc). We need to make another pass through this file to install an error system (mscott)
+ */
+
+nsresult nsImapProtocol::SendData(const char * dataBuffer, bool aSuppressLogging)
+{
+ nsresult rv = NS_ERROR_NULL_POINTER;
+
+ if (!m_transport)
+ {
+ Log("SendData", nullptr, "clearing IMAP_CONNECTION_IS_OPEN");
+ // the connection died unexpectedly! so clear the open connection flag
+ ClearFlag(IMAP_CONNECTION_IS_OPEN);
+ TellThreadToDie();
+ SetConnectionStatus(NS_ERROR_FAILURE);
+ return NS_ERROR_FAILURE;
+ }
+
+ if (dataBuffer && m_outputStream)
+ {
+ m_currentCommand = dataBuffer;
+ if (!aSuppressLogging)
+ Log("SendData", nullptr, dataBuffer);
+ else
+ Log("SendData", nullptr, "Logging suppressed for this command (it probably contained authentication information)");
+
+ {
+ // don't allow someone to close the stream/transport out from under us
+ // this can happen when the ui thread calls TellThreadToDie.
+ PR_CEnterMonitor(this);
+ uint32_t n;
+ if (m_outputStream)
+ rv = m_outputStream->Write(dataBuffer, PL_strlen(dataBuffer), &n);
+ PR_CExitMonitor(this);
+ }
+ if (NS_FAILED(rv))
+ {
+ Log("SendData", nullptr, "clearing IMAP_CONNECTION_IS_OPEN");
+ // the connection died unexpectedly! so clear the open connection flag
+ ClearFlag(IMAP_CONNECTION_IS_OPEN);
+ TellThreadToDie();
+ SetConnectionStatus(rv);
+ if (m_runningUrl && !m_retryUrlOnError)
+ {
+ bool alreadyRerunningUrl;
+ m_runningUrl->GetRerunningUrl(&alreadyRerunningUrl);
+ if (!alreadyRerunningUrl)
+ {
+ m_runningUrl->SetRerunningUrl(true);
+ m_retryUrlOnError = true;
+ }
+ }
+ }
+ }
+
+ return rv;
+}
+
+/////////////////////////////////////////////////////////////////////////////////////////////
+// Begin protocol state machine functions...
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+ // ProcessProtocolState - we override this only so we'll link - it should never get called.
+
+nsresult nsImapProtocol::ProcessProtocolState(nsIURI * url, nsIInputStream * inputStream,
+ uint64_t sourceOffset, uint32_t length)
+{
+ return NS_OK;
+}
+
+class UrlListenerNotifierEvent : public nsRunnable
+{
+public:
+ UrlListenerNotifierEvent(nsIMsgMailNewsUrl *aUrl, nsIImapProtocol *aProtocol)
+ : mUrl(aUrl), mProtocol(aProtocol)
+ {}
+
+ NS_IMETHOD Run()
+ {
+ if (mUrl)
+ {
+ nsCOMPtr<nsIMsgFolder> folder;
+ mUrl->GetFolder(getter_AddRefs(folder));
+ NS_ENSURE_TRUE(folder, NS_OK);
+ nsCOMPtr<nsIImapMailFolderSink> folderSink(do_QueryInterface(folder));
+ // This causes the url listener to get OnStart and Stop notifications.
+ folderSink->SetUrlState(mProtocol, mUrl, true, false, NS_OK);
+ folderSink->SetUrlState(mProtocol, mUrl, false, false, NS_OK);
+ }
+ return NS_OK;
+ }
+
+private:
+ nsCOMPtr<nsIMsgMailNewsUrl> mUrl;
+ nsCOMPtr<nsIImapProtocol> mProtocol;
+};
+
+
+bool nsImapProtocol::TryToRunUrlLocally(nsIURI *aURL, nsISupports *aConsumer)
+{
+ nsresult rv;
+ nsCOMPtr<nsIImapUrl> imapUrl(do_QueryInterface(aURL, &rv));
+ NS_ENSURE_SUCCESS(rv, false);
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(aURL);
+ nsCString messageIdString;
+ imapUrl->GetListOfMessageIds(messageIdString);
+ bool useLocalCache = false;
+ if (!messageIdString.IsEmpty() && !HandlingMultipleMessages(messageIdString))
+ {
+ nsImapAction action;
+ imapUrl->GetImapAction(&action);
+ nsCOMPtr <nsIMsgFolder> folder;
+ mailnewsUrl->GetFolder(getter_AddRefs(folder));
+ NS_ENSURE_TRUE(folder, false);
+
+ folder->HasMsgOffline(atoi(messageIdString.get()), &useLocalCache);
+ mailnewsUrl->SetMsgIsInLocalCache(useLocalCache);
+ // We're downloading a single message for offline use, and it's
+ // already offline. So we shouldn't do anything, but we do
+ // need to notify the url listener.
+ if (useLocalCache && action == nsIImapUrl::nsImapMsgDownloadForOffline)
+ {
+ nsCOMPtr<nsIRunnable> event = new UrlListenerNotifierEvent(mailnewsUrl,
+ this);
+ // Post this as an event because it can lead to re-entrant calls to
+ // LoadNextQueuedUrl if the listener runs a new url.
+ if (event)
+ NS_DispatchToCurrentThread(event);
+ return true;
+ }
+ }
+ if (!useLocalCache)
+ return false;
+
+ nsCOMPtr<nsIImapMockChannel> mockChannel;
+ imapUrl->GetMockChannel(getter_AddRefs(mockChannel));
+ if (!mockChannel)
+ return false;
+
+ nsImapMockChannel *imapChannel = static_cast<nsImapMockChannel *>(mockChannel.get());
+ if (!imapChannel)
+ return false;
+
+ nsCOMPtr <nsILoadGroup> loadGroup;
+ imapChannel->GetLoadGroup(getter_AddRefs(loadGroup));
+ if (!loadGroup) // if we don't have one, the url will snag one from the msg window...
+ mailnewsUrl->GetLoadGroup(getter_AddRefs(loadGroup));
+
+ if (loadGroup)
+ loadGroup->RemoveRequest((nsIRequest *) mockChannel, nullptr /* context isupports */, NS_OK);
+
+ if (imapChannel->ReadFromLocalCache())
+ {
+ (void) imapChannel->NotifyStartEndReadFromCache(true);
+ return true;
+ }
+ return false;
+}
+
+
+// LoadImapUrl takes a url, initializes all of our url specific data by calling SetupUrl.
+// If we don't have a connection yet, we open the connection. Finally, we signal the
+// url to run monitor to let the imap main thread loop process the current url (it is waiting
+// on this monitor). There is a contract that the imap thread has already been started b4 we
+// attempt to load a url....
+NS_IMETHODIMP nsImapProtocol::LoadImapUrl(nsIURI * aURL, nsISupports * aConsumer)
+{
+ nsresult rv;
+ if (aURL)
+ {
+#ifdef DEBUG_bienvenu
+ nsAutoCString urlSpec;
+ aURL->GetSpec(urlSpec);
+ printf("loading url %s\n", urlSpec.get());
+#endif
+ if (TryToRunUrlLocally(aURL, aConsumer))
+ return NS_OK;
+ m_urlInProgress = true;
+ m_imapMailFolderSink = nullptr;
+ rv = SetupWithUrl(aURL, aConsumer);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "error setting up imap url");
+ if (NS_FAILED(rv))
+ return rv;
+
+ SetupSinkProxy(); // generate proxies for all of the event sinks in the url
+ m_lastActiveTime = PR_Now();
+ if (m_transport && m_runningUrl)
+ {
+ nsImapAction imapAction;
+ m_runningUrl->GetImapAction(&imapAction);
+ // if we're shutting down, and not running the kinds of urls we run at
+ // shutdown, then this should fail because running urls during
+ // shutdown will very likely fail and potentially hang.
+ nsCOMPtr<nsIMsgAccountManager> accountMgr = do_GetService(NS_MSGACCOUNTMANAGER_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ bool shuttingDown = false;
+ (void) accountMgr->GetShutdownInProgress(&shuttingDown);
+ if (shuttingDown && imapAction != nsIImapUrl::nsImapExpungeFolder &&
+ imapAction != nsIImapUrl::nsImapDeleteAllMsgs &&
+ imapAction != nsIImapUrl::nsImapDeleteFolder)
+ return NS_ERROR_FAILURE;
+
+ // if we're running a select or delete all, do a noop first.
+ // this should really be in the connection cache code when we know
+ // we're pulling out a selected state connection, but maybe we
+ // can get away with this.
+ m_needNoop = (imapAction == nsIImapUrl::nsImapSelectFolder || imapAction == nsIImapUrl::nsImapDeleteAllMsgs);
+
+ // We now have a url to run so signal the monitor for url ready to be processed...
+ ReentrantMonitorAutoEnter urlReadyMon(m_urlReadyToRunMonitor);
+ m_nextUrlReadyToRun = true;
+ urlReadyMon.Notify();
+
+ } // if we have an imap url and a transport
+ else
+ NS_ASSERTION(false, "missing channel or running url");
+
+ } // if we received a url!
+
+ return rv;
+}
+
+NS_IMETHODIMP nsImapProtocol::IsBusy(bool *aIsConnectionBusy,
+ bool *isInboxConnection)
+{
+ if (!aIsConnectionBusy || !isInboxConnection)
+ return NS_ERROR_NULL_POINTER;
+ nsresult rv = NS_OK;
+ *aIsConnectionBusy = false;
+ *isInboxConnection = false;
+ if (!m_transport)
+ {
+ // this connection might not be fully set up yet.
+ rv = NS_ERROR_FAILURE;
+ }
+ else
+ {
+ if (m_urlInProgress) // do we have a url? That means we're working on it...
+ *aIsConnectionBusy = true;
+
+ if (GetServerStateParser().GetIMAPstate() ==
+ nsImapServerResponseParser::kFolderSelected && GetServerStateParser().GetSelectedMailboxName() &&
+ PL_strcasecmp(GetServerStateParser().GetSelectedMailboxName(),
+ "Inbox") == 0)
+ *isInboxConnection = true;
+
+ }
+ return rv;
+}
+
+#define IS_SUBSCRIPTION_RELATED_ACTION(action) (action == nsIImapUrl::nsImapSubscribe\
+|| action == nsIImapUrl::nsImapUnsubscribe || action == nsIImapUrl::nsImapDiscoverAllBoxesUrl || action == nsIImapUrl::nsImapListFolder)
+
+
+// canRunUrl means the connection is not busy, and is in the selected state
+// for the desired folder (or authenticated).
+// has to wait means it's in the right selected state, but busy.
+NS_IMETHODIMP nsImapProtocol::CanHandleUrl(nsIImapUrl * aImapUrl,
+ bool * aCanRunUrl,
+ bool * hasToWait)
+{
+ if (!aCanRunUrl || !hasToWait || !aImapUrl)
+ return NS_ERROR_NULL_POINTER;
+ nsresult rv = NS_OK;
+ MutexAutoLock mon(mLock);
+
+ *aCanRunUrl = false; // assume guilty until proven otherwise...
+ *hasToWait = false;
+
+ if (DeathSignalReceived())
+ return NS_ERROR_FAILURE;
+
+ bool isBusy = false;
+ bool isInboxConnection = false;
+
+ if (!m_transport)
+ {
+ // this connection might not be fully set up yet.
+ return NS_ERROR_FAILURE;
+ }
+ IsBusy(&isBusy, &isInboxConnection);
+ bool inSelectedState = GetServerStateParser().GetIMAPstate() ==
+ nsImapServerResponseParser::kFolderSelected;
+
+ nsAutoCString curSelectedUrlFolderName;
+ nsAutoCString pendingUrlFolderName;
+ if (inSelectedState)
+ curSelectedUrlFolderName = GetServerStateParser().GetSelectedMailboxName();
+
+ if (isBusy)
+ {
+ nsImapState curUrlImapState;
+ NS_ASSERTION(m_runningUrl,"isBusy, but no running url.");
+ if (m_runningUrl)
+ {
+ m_runningUrl->GetRequiredImapState(&curUrlImapState);
+ if (curUrlImapState == nsIImapUrl::nsImapSelectedState)
+ {
+ char *folderName = GetFolderPathString();
+ if (!curSelectedUrlFolderName.Equals(folderName))
+ pendingUrlFolderName.Assign(folderName);
+ inSelectedState = true;
+ PR_Free(folderName);
+ }
+ }
+ }
+
+ nsImapState imapState;
+ nsImapAction actionForProposedUrl;
+ aImapUrl->GetImapAction(&actionForProposedUrl);
+ aImapUrl->GetRequiredImapState(&imapState);
+
+ // OK, this is a bit of a hack - we're going to pretend that
+ // these types of urls requires a selected state connection on
+ // the folder in question. This isn't technically true,
+ // but we would much rather use that connection for several reasons,
+ // one is that some UW servers require us to use that connection
+ // the other is that we don't want to leave a connection dangling in
+ // the selected state for the deleted folder.
+ // If we don't find a connection in that selected state,
+ // we'll fall back to the first free connection.
+ bool isSelectedStateUrl = imapState == nsIImapUrl::nsImapSelectedState
+ || actionForProposedUrl == nsIImapUrl::nsImapDeleteFolder || actionForProposedUrl == nsIImapUrl::nsImapRenameFolder
+ || actionForProposedUrl == nsIImapUrl::nsImapMoveFolderHierarchy
+ || actionForProposedUrl == nsIImapUrl::nsImapAppendDraftFromFile
+ || actionForProposedUrl == nsIImapUrl::nsImapAppendMsgFromFile
+ || actionForProposedUrl == nsIImapUrl::nsImapFolderStatus;
+
+ nsCOMPtr<nsIMsgMailNewsUrl> msgUrl = do_QueryInterface(aImapUrl);
+ nsCOMPtr<nsIMsgIncomingServer> server;
+ rv = msgUrl->GetServer(getter_AddRefs(server));
+ if (NS_SUCCEEDED(rv))
+ {
+ // compare host/user between url and connection.
+ nsCString urlHostName;
+ nsCString urlUserName;
+ rv = server->GetHostName(urlHostName);
+ NS_ENSURE_SUCCESS(rv, rv);
+ rv = server->GetUsername(urlUserName);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ if ((GetImapHostName().IsEmpty() ||
+ urlHostName.Equals(GetImapHostName(), nsCaseInsensitiveCStringComparator())) &&
+ (GetImapUserName().IsEmpty() ||
+ urlUserName.Equals(GetImapUserName(), nsCaseInsensitiveCStringComparator())))
+ {
+ if (isSelectedStateUrl)
+ {
+ if (inSelectedState)
+ {
+ // *** jt - in selected state can only run url with
+ // matching foldername
+ char *folderNameForProposedUrl = nullptr;
+ rv = aImapUrl->CreateServerSourceFolderPathString(
+ &folderNameForProposedUrl);
+ if (NS_SUCCEEDED(rv) && folderNameForProposedUrl)
+ {
+ bool isInbox =
+ PL_strcasecmp("Inbox", folderNameForProposedUrl) == 0;
+ if (!curSelectedUrlFolderName.IsEmpty() || !pendingUrlFolderName.IsEmpty())
+ {
+ bool matched = isInbox ?
+ PL_strcasecmp(curSelectedUrlFolderName.get(),
+ folderNameForProposedUrl) == 0 :
+ PL_strcmp(curSelectedUrlFolderName.get(),
+ folderNameForProposedUrl) == 0;
+ if (!matched && !pendingUrlFolderName.IsEmpty())
+ {
+ matched = isInbox ?
+ PL_strcasecmp(pendingUrlFolderName.get(),
+ folderNameForProposedUrl) == 0 :
+ PL_strcmp(pendingUrlFolderName.get(),
+ folderNameForProposedUrl) == 0;
+ }
+ if (matched)
+ {
+ if (isBusy)
+ *hasToWait = true;
+ else
+ *aCanRunUrl = true;
+ }
+ }
+ }
+ PR_LOG(IMAP, PR_LOG_DEBUG,
+ ("proposed url = %s folder for connection %s has To Wait = %s can run = %s",
+ folderNameForProposedUrl, curSelectedUrlFolderName.get(),
+ (*hasToWait) ? "TRUE" : "FALSE", (*aCanRunUrl) ? "TRUE" : "FALSE"));
+ PR_FREEIF(folderNameForProposedUrl);
+ }
+ }
+ else // *** jt - an authenticated state url can be run in either
+ // authenticated or selected state
+ {
+ nsImapAction actionForRunningUrl;
+
+ // If proposed url is subscription related, and we are currently running
+ // a subscription url, then we want to queue the proposed url after the current url.
+ // Otherwise, we can run this url if we're not busy.
+ // If we never find a running subscription-related url, the caller will
+ // just use whatever free connection it can find, which is what we want.
+ if (IS_SUBSCRIPTION_RELATED_ACTION(actionForProposedUrl))
+ {
+ if (isBusy && m_runningUrl)
+ {
+ m_runningUrl->GetImapAction(&actionForRunningUrl);
+ if (IS_SUBSCRIPTION_RELATED_ACTION(actionForRunningUrl))
+ {
+ *aCanRunUrl = false;
+ *hasToWait = true;
+ }
+ }
+ }
+ else
+ {
+ if (!isBusy)
+ *aCanRunUrl = true;
+ }
+ }
+ }
+ }
+ return rv;
+}
+
+
+// Command tag handling stuff
+void nsImapProtocol::IncrementCommandTagNumber()
+{
+ sprintf(m_currentServerCommandTag, "%u", ++m_currentServerCommandTagNumber);
+}
+
+const char *nsImapProtocol::GetServerCommandTag()
+{
+ return m_currentServerCommandTag;
+}
+
+void nsImapProtocol::ProcessSelectedStateURL()
+{
+ nsCString mailboxName;
+ bool bMessageIdsAreUids = true;
+ bool moreHeadersToDownload;
+ imapMessageFlagsType msgFlags = 0;
+ nsCString urlHost;
+
+ // this can't fail, can it?
+ nsresult res;
+ res = m_runningUrl->GetImapAction(&m_imapAction);
+ m_runningUrl->MessageIdsAreUids(&bMessageIdsAreUids);
+ m_runningUrl->GetMsgFlags(&msgFlags);
+ m_runningUrl->GetMoreHeadersToDownload(&moreHeadersToDownload);
+
+ res = CreateServerSourceFolderPathString(getter_Copies(mailboxName));
+ if (NS_FAILED(res))
+ Log("ProcessSelectedStateURL", nullptr, "error getting source folder path string");
+
+ if (NS_SUCCEEDED(res) && !DeathSignalReceived())
+ {
+ bool selectIssued = false;
+ if (GetServerStateParser().GetIMAPstate() == nsImapServerResponseParser::kFolderSelected)
+ {
+ if (GetServerStateParser().GetSelectedMailboxName() &&
+ PL_strcmp(GetServerStateParser().GetSelectedMailboxName(),
+ mailboxName.get()))
+ { // we are selected in another folder
+ if (m_closeNeededBeforeSelect)
+ Close();
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ selectIssued = true;
+ SelectMailbox(mailboxName.get());
+ }
+ }
+ else if (!GetServerStateParser().GetSelectedMailboxName())
+ { // why are we in the selected state with no box name?
+ SelectMailbox(mailboxName.get());
+ selectIssued = true;
+ }
+ else if (moreHeadersToDownload && m_imapMailFolderSink) // we need to fetch older headers
+ {
+ nsMsgKey *msgIdList = nullptr;
+ uint32_t msgCount = 0;
+ bool more;
+ m_imapMailFolderSink->GetMsgHdrsToDownload(&more, &m_progressCount,
+ &msgCount, &msgIdList);
+ if (msgIdList)
+ {
+ FolderHeaderDump(msgIdList, msgCount);
+ NS_Free(msgIdList);
+ m_runningUrl->SetMoreHeadersToDownload(more);
+ // We're going to be re-running this url.
+ if (more)
+ m_runningUrl->SetRerunningUrl(true);
+ }
+ HeaderFetchCompleted();
+ }
+ else
+ {
+ // get new message counts, if any, from server
+ if (m_needNoop)
+ {
+ m_noopCount++;
+ if ((gPromoteNoopToCheckCount > 0 && (m_noopCount % gPromoteNoopToCheckCount) == 0) ||
+ CheckNeeded())
+ Check();
+ else
+ Noop(); // I think this is needed when we're using a cached connection
+ m_needNoop = false;
+ }
+ }
+ }
+ else
+ {
+ // go to selected state
+ SelectMailbox(mailboxName.get());
+ selectIssued = GetServerStateParser().LastCommandSuccessful();
+ }
+
+ if (selectIssued)
+ RefreshACLForFolderIfNecessary(mailboxName.get());
+
+ bool uidValidityOk = true;
+ if (GetServerStateParser().LastCommandSuccessful() && selectIssued &&
+ (m_imapAction != nsIImapUrl::nsImapSelectFolder) && (m_imapAction != nsIImapUrl::nsImapLiteSelectFolder))
+ {
+
+ // error on the side of caution, if the fe event fails to set uidStruct->returnValidity, then assume that UIDVALIDITY
+ // did not roll. This is a common case event for attachments that are fetched within a browser context.
+ if (!DeathSignalReceived())
+ uidValidityOk = m_uidValidity == kUidUnknown ||
+ m_uidValidity == GetServerStateParser().FolderUID();
+ }
+
+ if (!uidValidityOk)
+ Log("ProcessSelectedStateURL", nullptr, "uid validity not ok");
+ if (GetServerStateParser().LastCommandSuccessful() && !DeathSignalReceived() && (uidValidityOk || m_imapAction == nsIImapUrl::nsImapDeleteAllMsgs))
+ {
+ if (GetServerStateParser().CurrentFolderReadOnly())
+ {
+ Log("ProcessSelectedStateURL", nullptr, "current folder read only");
+ if (m_imapAction == nsIImapUrl::nsImapAddMsgFlags ||
+ m_imapAction == nsIImapUrl::nsImapSubtractMsgFlags)
+ {
+ bool canChangeFlag = false;
+ if (GetServerStateParser().ServerHasACLCapability() && m_imapMailFolderSink)
+ {
+ uint32_t aclFlags = 0;
+
+ if (NS_SUCCEEDED(m_imapMailFolderSink->GetAclFlags(&aclFlags))
+ && aclFlags != 0) // make sure we have some acl flags
+ canChangeFlag = ((msgFlags & kImapMsgSeenFlag) && (aclFlags & IMAP_ACL_STORE_SEEN_FLAG));
+ }
+ else
+ canChangeFlag = (GetServerStateParser().SettablePermanentFlags() & msgFlags) == msgFlags;
+ if (!canChangeFlag)
+ return;
+ }
+ if (m_imapAction == nsIImapUrl::nsImapExpungeFolder || m_imapAction == nsIImapUrl::nsImapDeleteMsg ||
+ m_imapAction == nsIImapUrl::nsImapDeleteAllMsgs)
+ return;
+ }
+ switch (m_imapAction)
+ {
+ case nsIImapUrl::nsImapLiteSelectFolder:
+ if (GetServerStateParser().LastCommandSuccessful() &&
+ m_imapMailFolderSink && !moreHeadersToDownload)
+ {
+ m_imapMailFolderSink->SetUidValidity(GetServerStateParser().FolderUID());
+ ProcessMailboxUpdate(false); // handle uidvalidity change
+ }
+ break;
+ case nsIImapUrl::nsImapSaveMessageToDisk:
+ case nsIImapUrl::nsImapMsgFetch:
+ case nsIImapUrl::nsImapMsgFetchPeek:
+ case nsIImapUrl::nsImapMsgDownloadForOffline:
+ case nsIImapUrl::nsImapMsgPreview:
+ {
+ nsCString messageIdString;
+ m_runningUrl->GetListOfMessageIds(messageIdString);
+ // we don't want to send the flags back in a group
+ if (HandlingMultipleMessages(messageIdString) || m_imapAction == nsIImapUrl::nsImapMsgDownloadForOffline
+ || m_imapAction == nsIImapUrl::nsImapMsgPreview)
+ {
+ // multiple messages, fetch them all
+ SetProgressString(IMAP_FOLDER_RECEIVING_MESSAGE_OF);
+
+ m_progressIndex = 0;
+ m_progressCount = CountMessagesInIdString(messageIdString.get());
+
+ // we need to set this so we'll get the msg from the memory cache.
+ if (m_imapAction == nsIImapUrl::nsImapMsgFetchPeek)
+ SetContentModified(IMAP_CONTENT_NOT_MODIFIED);
+
+ FetchMessage(messageIdString,
+ (m_imapAction == nsIImapUrl::nsImapMsgPreview)
+ ? kBodyStart : kEveryThingRFC822Peek);
+ if (m_imapAction == nsIImapUrl::nsImapMsgPreview)
+ HeaderFetchCompleted();
+ SetProgressString(0);
+ }
+ else
+ {
+ // A single message ID
+ nsIMAPeFetchFields whatToFetch = kEveryThingRFC822;
+ if(m_imapAction == nsIImapUrl::nsImapMsgFetchPeek)
+ whatToFetch = kEveryThingRFC822Peek;
+
+ // First, let's see if we're requesting a specific MIME part
+ char *imappart = nullptr;
+ m_runningUrl->GetImapPartToFetch(&imappart);
+ if (imappart)
+ {
+ if (bMessageIdsAreUids)
+ {
+ // We actually want a specific MIME part of the message.
+ // The Body Shell will generate it, even though we haven't downloaded it yet.
+
+ IMAP_ContentModifiedType modType = GetShowAttachmentsInline() ?
+ IMAP_CONTENT_MODIFIED_VIEW_INLINE :
+ IMAP_CONTENT_MODIFIED_VIEW_AS_LINKS ;
+
+ nsRefPtr<nsIMAPBodyShell> foundShell;
+ res = m_hostSessionList->FindShellInCacheForHost(GetImapServerKey(),
+ GetServerStateParser().GetSelectedMailboxName(),
+ messageIdString.get(), modType, getter_AddRefs(foundShell));
+ if (!foundShell)
+ {
+ // The shell wasn't in the cache. Deal with this case later.
+ Log("SHELL",NULL,"Loading part, shell not found in cache!");
+ //PR_LOG(IMAP, out, ("BODYSHELL: Loading part, shell not found in cache!"));
+ // The parser will extract the part number from the current URL.
+ SetContentModified(modType);
+ Bodystructure(messageIdString, bMessageIdsAreUids);
+ }
+ else
+ {
+ Log("SHELL", NULL, "Loading Part, using cached shell.");
+ //PR_LOG(IMAP, out, ("BODYSHELL: Loading part, using cached shell."));
+ SetContentModified(modType);
+ foundShell->SetConnection(this);
+ GetServerStateParser().UseCachedShell(foundShell);
+ //Set the current uid in server state parser (in case it was used for new mail msgs earlier).
+ GetServerStateParser().SetCurrentResponseUID((uint32_t)atoi(messageIdString.get()));
+ foundShell->Generate(imappart);
+ GetServerStateParser().UseCachedShell(NULL);
+ }
+ }
+ else
+ {
+ // Message IDs are not UIDs.
+ NS_ASSERTION(false, "message ids aren't uids");
+ }
+ PR_Free(imappart);
+ }
+ else
+ {
+ // downloading a single message: try to do it by bodystructure, and/or do it by chunks
+ uint32_t messageSize = GetMessageSize(messageIdString.get(), bMessageIdsAreUids);
+ // We need to check the format_out bits to see if we are allowed to leave out parts,
+ // or if we are required to get the whole thing. Some instances where we are allowed
+ // to do it by parts: when viewing a message, replying to a message, or viewing its source
+ // Some times when we're NOT allowed: when forwarding a message, saving it, moving it, etc.
+ // need to set a flag in the url, I guess, equiv to allow_content_changed.
+ bool allowedToBreakApart = true; // (ce && !DeathSignalReceived()) ? ce->URL_s->allow_content_change : false;
+ bool mimePartSelectorDetected;
+ bool urlOKToFetchByParts = false;
+ m_runningUrl->GetMimePartSelectorDetected(&mimePartSelectorDetected);
+ m_runningUrl->GetFetchPartsOnDemand(&urlOKToFetchByParts);
+
+#ifdef PR_LOGGING
+ {
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsurl = do_QueryInterface(m_runningUrl);
+ nsAutoCString urlSpec;
+ if (mailnewsurl)
+ mailnewsurl->GetSpec(urlSpec);
+ PR_LOG(IMAP, PR_LOG_DEBUG,
+ ("SHELL: URL %s, OKToFetchByParts %d, allowedToBreakApart %d, ShouldFetchAllParts %d",
+ urlSpec.get(), urlOKToFetchByParts, allowedToBreakApart,
+ GetShouldFetchAllParts()));
+ }
+#endif
+
+ if (urlOKToFetchByParts &&
+ allowedToBreakApart &&
+ !GetShouldFetchAllParts() &&
+ GetServerStateParser().ServerHasIMAP4Rev1Capability() /* &&
+ !mimePartSelectorDetected */) // if a ?part=, don't do BS.
+ {
+ // OK, we're doing bodystructure
+
+ // Before fetching the bodystructure, let's check our body shell cache to see if
+ // we already have it around.
+ nsRefPtr<nsIMAPBodyShell> foundShell;
+ IMAP_ContentModifiedType modType = GetShowAttachmentsInline() ?
+ IMAP_CONTENT_MODIFIED_VIEW_INLINE :
+ IMAP_CONTENT_MODIFIED_VIEW_AS_LINKS ;
+
+ bool wasStoringMsgOffline;
+ m_runningUrl->GetStoreResultsOffline(&wasStoringMsgOffline);
+ m_runningUrl->SetStoreOfflineOnFallback(wasStoringMsgOffline);
+ m_runningUrl->SetStoreResultsOffline(false);
+ nsCOMPtr<nsIMsgMailNewsUrl> mailurl = do_QueryInterface(m_runningUrl);
+ if (mailurl)
+ {
+ mailurl->SetAddToMemoryCache(false);
+ // need to proxy this over to the ui thread
+ if (m_imapMessageSink)
+ m_imapMessageSink->SetImageCacheSessionForUrl(mailurl);
+
+ }
+ SetContentModified(modType); // This will be looked at by the cache
+ if (bMessageIdsAreUids)
+ {
+ res = m_hostSessionList->FindShellInCacheForHost(GetImapServerKey(),
+ GetServerStateParser().GetSelectedMailboxName(),
+ messageIdString.get(), modType, getter_AddRefs(foundShell));
+ if (foundShell)
+ {
+ Log("SHELL",NULL,"Loading message, using cached shell.");
+ //PR_LOG(IMAP, out, ("BODYSHELL: Loading message, using cached shell."));
+ foundShell->SetConnection(this);
+ GetServerStateParser().UseCachedShell(foundShell);
+ //Set the current uid in server state parser (in case it was used for new mail msgs earlier).
+ GetServerStateParser().SetCurrentResponseUID((uint32_t)atoi(messageIdString.get()));
+ foundShell->Generate(NULL);
+ GetServerStateParser().UseCachedShell(NULL);
+ }
+ }
+
+ if (!foundShell)
+ Bodystructure(messageIdString, bMessageIdsAreUids);
+ }
+ else
+ {
+ // Not doing bodystructure. Fetch the whole thing, and try to do
+ // it in chunks.
+ SetContentModified(IMAP_CONTENT_NOT_MODIFIED);
+ FetchTryChunking(messageIdString, whatToFetch,
+ bMessageIdsAreUids, NULL, messageSize, true);
+ }
+ }
+ if (GetServerStateParser().LastCommandSuccessful()
+ && m_imapAction != nsIImapUrl::nsImapMsgPreview
+ && m_imapAction != nsIImapUrl::nsImapMsgFetchPeek)
+ {
+ uint32_t uid = atoi(messageIdString.get());
+ int32_t index;
+ bool foundIt;
+ imapMessageFlagsType flags = m_flagState->GetMessageFlagsFromUID(uid, &foundIt, &index);
+ if (foundIt)
+ {
+ flags |= kImapMsgSeenFlag;
+ m_flagState->SetMessageFlags(index, flags);
+ }
+ }
+ }
+ }
+ break;
+ case nsIImapUrl::nsImapExpungeFolder:
+ Expunge();
+ // note fall through to next cases.
+ case nsIImapUrl::nsImapSelectFolder:
+ case nsIImapUrl::nsImapSelectNoopFolder:
+ if (!moreHeadersToDownload)
+ ProcessMailboxUpdate(true);
+ break;
+ case nsIImapUrl::nsImapMsgHeader:
+ {
+ nsCString messageIds;
+ m_runningUrl->GetListOfMessageIds(messageIds);
+
+ FetchMessage(messageIds,
+ kHeadersRFC822andUid);
+ // if we explicitly ask for headers, as opposed to getting them as a result
+ // of selecting the folder, or biff, send the headerFetchCompleted notification
+ // to flush out the header cache.
+ HeaderFetchCompleted();
+ }
+ break;
+ case nsIImapUrl::nsImapSearch:
+ {
+ nsAutoCString searchCriteriaString;
+ m_runningUrl->CreateSearchCriteriaString(getter_Copies(searchCriteriaString));
+ Search(searchCriteriaString.get(), bMessageIdsAreUids);
+ // drop the results on the floor for now
+ }
+ break;
+ case nsIImapUrl::nsImapUserDefinedMsgCommand:
+ {
+ nsCString messageIdString;
+ nsCString command;
+
+ m_runningUrl->GetCommand(command);
+ m_runningUrl->GetListOfMessageIds(messageIdString);
+ IssueUserDefinedMsgCommand(command.get(), messageIdString.get());
+ }
+ break;
+ case nsIImapUrl::nsImapUserDefinedFetchAttribute:
+ {
+ nsCString messageIdString;
+ nsCString attribute;
+
+ m_runningUrl->GetCustomAttributeToFetch(attribute);
+ m_runningUrl->GetListOfMessageIds(messageIdString);
+ FetchMsgAttribute(messageIdString, attribute);
+ }
+ break;
+ case nsIImapUrl::nsImapMsgStoreCustomKeywords:
+ {
+ // if the server doesn't support user defined flags, don't try to set them.
+ uint16_t userFlags;
+ GetSupportedUserFlags(&userFlags);
+ if (! (userFlags & kImapMsgSupportUserFlag))
+ break;
+ nsCString messageIdString;
+ nsCString addFlags;
+ nsCString subtractFlags;
+
+ m_runningUrl->GetListOfMessageIds(messageIdString);
+ m_runningUrl->GetCustomAddFlags(addFlags);
+ m_runningUrl->GetCustomSubtractFlags(subtractFlags);
+ if (!addFlags.IsEmpty())
+ {
+ nsAutoCString storeString("+FLAGS (");
+ storeString.Append(addFlags);
+ storeString.Append(")");
+ Store(messageIdString, storeString.get(), true);
+ }
+ if (!subtractFlags.IsEmpty())
+ {
+ nsAutoCString storeString("-FLAGS (");
+ storeString.Append(subtractFlags);
+ storeString.Append(")");
+ Store(messageIdString, storeString.get(), true);
+ }
+ }
+ break;
+ case nsIImapUrl::nsImapDeleteMsg:
+ {
+ nsCString messageIdString;
+ m_runningUrl->GetListOfMessageIds(messageIdString);
+
+ ProgressEventFunctionUsingId (HandlingMultipleMessages(messageIdString) ?
+ IMAP_DELETING_MESSAGES :IMAP_DELETING_MESSAGE);
+
+ Store(messageIdString, "+FLAGS (\\Deleted)", bMessageIdsAreUids);
+
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ //delete_message_struct *deleteMsg = (delete_message_struct *) PR_Malloc (sizeof(delete_message_struct));
+ // convert name back from utf7
+ nsCString canonicalName;
+ const char *selectedMailboxName = GetServerStateParser().GetSelectedMailboxName();
+ if (selectedMailboxName)
+ {
+ m_runningUrl->AllocateCanonicalPath(selectedMailboxName,
+ kOnlineHierarchySeparatorUnknown, getter_Copies(canonicalName));
+ }
+
+ if (m_imapMessageSink)
+ m_imapMessageSink->NotifyMessageDeleted(canonicalName.get(), false, messageIdString.get());
+ // notice we don't wait for this to finish...
+ }
+ else
+ HandleMemoryFailure();
+ }
+ break;
+ case nsIImapUrl::nsImapDeleteFolderAndMsgs:
+ DeleteFolderAndMsgs(mailboxName.get());
+ break;
+ case nsIImapUrl::nsImapDeleteAllMsgs:
+ {
+ uint32_t numberOfMessages = GetServerStateParser().NumberOfMessages();
+ if (numberOfMessages)
+ {
+ Store(NS_LITERAL_CSTRING("1:*"), "+FLAGS.SILENT (\\Deleted)",
+ false); // use sequence #'s
+
+ if (GetServerStateParser().LastCommandSuccessful())
+ Expunge(); // expunge messages with deleted flag
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ // convert name back from utf7
+ nsCString canonicalName;
+ const char *selectedMailboxName = GetServerStateParser().GetSelectedMailboxName();
+ if (selectedMailboxName )
+ {
+ m_runningUrl->AllocateCanonicalPath(selectedMailboxName,
+ kOnlineHierarchySeparatorUnknown, getter_Copies(canonicalName));
+ }
+
+ if (m_imapMessageSink)
+ m_imapMessageSink->NotifyMessageDeleted(canonicalName.get(), true, nullptr);
+ }
+
+ }
+ bool deleteSelf = false;
+ DeleteSubFolders(mailboxName.get(), deleteSelf); // don't delete self
+ }
+ break;
+ case nsIImapUrl::nsImapAppendDraftFromFile:
+ {
+ OnAppendMsgFromFile();
+ }
+ break;
+ case nsIImapUrl::nsImapAddMsgFlags:
+ {
+ nsCString messageIdString;
+ m_runningUrl->GetListOfMessageIds(messageIdString);
+
+ ProcessStoreFlags(messageIdString, bMessageIdsAreUids,
+ msgFlags, true);
+ }
+ break;
+ case nsIImapUrl::nsImapSubtractMsgFlags:
+ {
+ nsCString messageIdString;
+ m_runningUrl->GetListOfMessageIds(messageIdString);
+
+ ProcessStoreFlags(messageIdString, bMessageIdsAreUids,
+ msgFlags, false);
+ }
+ break;
+ case nsIImapUrl::nsImapSetMsgFlags:
+ {
+ nsCString messageIdString;
+ m_runningUrl->GetListOfMessageIds(messageIdString);
+
+ ProcessStoreFlags(messageIdString, bMessageIdsAreUids,
+ msgFlags, true);
+ ProcessStoreFlags(messageIdString, bMessageIdsAreUids,
+ ~msgFlags, false);
+ }
+ break;
+ case nsIImapUrl::nsImapBiff:
+ PeriodicBiff();
+ break;
+ case nsIImapUrl::nsImapOnlineCopy:
+ case nsIImapUrl::nsImapOnlineMove:
+ {
+ nsCString messageIdString;
+ m_runningUrl->GetListOfMessageIds(messageIdString);
+ char *destinationMailbox = OnCreateServerDestinationFolderPathString();
+
+ if (destinationMailbox)
+ {
+ if (m_imapAction == nsIImapUrl::nsImapOnlineMove)
+ {
+ if (HandlingMultipleMessages(messageIdString))
+ ProgressEventFunctionUsingIdWithString (IMAP_MOVING_MESSAGES_TO, destinationMailbox);
+ else
+ ProgressEventFunctionUsingIdWithString (IMAP_MOVING_MESSAGE_TO, destinationMailbox);
+ }
+ else {
+ if (HandlingMultipleMessages(messageIdString))
+ ProgressEventFunctionUsingIdWithString (IMAP_COPYING_MESSAGES_TO, destinationMailbox);
+ else
+ ProgressEventFunctionUsingIdWithString (IMAP_COPYING_MESSAGE_TO, destinationMailbox);
+ }
+ Copy(messageIdString.get(), destinationMailbox, bMessageIdsAreUids);
+ PR_FREEIF( destinationMailbox);
+ ImapOnlineCopyState copyState;
+ if (DeathSignalReceived())
+ copyState = ImapOnlineCopyStateType::kInterruptedState;
+ else
+ copyState = GetServerStateParser().LastCommandSuccessful() ?
+ (ImapOnlineCopyState) ImapOnlineCopyStateType::kSuccessfulCopy :
+ (ImapOnlineCopyState) ImapOnlineCopyStateType::kFailedCopy;
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->OnlineCopyCompleted(this, copyState);
+
+ // Don't mark msg 'Deleted' for aol servers since we already issued 'xaol-move' cmd.
+ if (GetServerStateParser().LastCommandSuccessful() &&
+ (m_imapAction == nsIImapUrl::nsImapOnlineMove) &&
+ !(GetServerStateParser().ServerIsAOLServer() ||
+ GetServerStateParser().GetCapabilityFlag() & kHasMoveCapability))
+ {
+ Store(messageIdString, "+FLAGS (\\Deleted \\Seen)",
+ bMessageIdsAreUids);
+ bool storeSuccessful = GetServerStateParser().LastCommandSuccessful();
+
+ if (gExpungeAfterDelete && storeSuccessful)
+ Expunge();
+
+ if (m_imapMailFolderSink)
+ {
+ copyState = storeSuccessful ? (ImapOnlineCopyState) ImapOnlineCopyStateType::kSuccessfulDelete
+ : (ImapOnlineCopyState) ImapOnlineCopyStateType::kFailedDelete;
+ m_imapMailFolderSink->OnlineCopyCompleted(this, copyState);
+ }
+ }
+ }
+ else
+ HandleMemoryFailure();
+ }
+ break;
+ case nsIImapUrl::nsImapOnlineToOfflineCopy:
+ case nsIImapUrl::nsImapOnlineToOfflineMove:
+ {
+ nsCString messageIdString;
+ nsresult rv = m_runningUrl->GetListOfMessageIds(messageIdString);
+ if (NS_SUCCEEDED(rv))
+ {
+ SetProgressString(IMAP_FOLDER_RECEIVING_MESSAGE_OF);
+ m_progressIndex = 0;
+ m_progressCount = CountMessagesInIdString(messageIdString.get());
+
+ FetchMessage(messageIdString, kEveryThingRFC822Peek);
+
+ SetProgressString(0);
+ if (m_imapMailFolderSink)
+ {
+ ImapOnlineCopyState copyStatus;
+ copyStatus = GetServerStateParser().LastCommandSuccessful() ?
+ ImapOnlineCopyStateType::kSuccessfulCopy : ImapOnlineCopyStateType::kFailedCopy;
+
+ m_imapMailFolderSink->OnlineCopyCompleted(this, copyStatus);
+ if (GetServerStateParser().LastCommandSuccessful() &&
+ (m_imapAction == nsIImapUrl::nsImapOnlineToOfflineMove))
+ {
+ Store(messageIdString, "+FLAGS (\\Deleted \\Seen)",bMessageIdsAreUids);
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ copyStatus = ImapOnlineCopyStateType::kSuccessfulDelete;
+ if (gExpungeAfterDelete)
+ Expunge();
+ }
+ else
+ copyStatus = ImapOnlineCopyStateType::kFailedDelete;
+
+ m_imapMailFolderSink->OnlineCopyCompleted(this, copyStatus);
+ }
+ }
+ }
+ else
+ HandleMemoryFailure();
+ }
+ break;
+ default:
+ if (GetServerStateParser().LastCommandSuccessful() && !uidValidityOk)
+ ProcessMailboxUpdate(false); // handle uidvalidity change
+ break;
+ }
+ }
+ }
+ else if (!DeathSignalReceived())
+ HandleMemoryFailure();
+}
+
+nsresult nsImapProtocol::BeginMessageDownLoad(
+ uint32_t total_message_size, // for user, headers and body
+ const char *content_type)
+{
+ nsresult rv = NS_OK;
+ char *sizeString = PR_smprintf("OPEN Size: %ld", total_message_size);
+ Log("STREAM",sizeString,"Begin Message Download Stream");
+ PR_Free(sizeString);
+ // start counting how many bytes we see in this message after all transformations
+ m_bytesToChannel = 0;
+
+ if (content_type)
+ {
+ m_fromHeaderSeen = false;
+ if (GetServerStateParser().GetDownloadingHeaders())
+ {
+ // if we get multiple calls to BeginMessageDownload w/o intervening
+ // calls to NormalEndMessageDownload or Abort, then we're just
+ // going to fake a NormalMessageEndDownload. This will most likely
+ // cause an empty header to get written to the db, and the user
+ // will have to delete the empty header themselves, which
+ // should remove the message from the server as well.
+ if (m_curHdrInfo)
+ NormalMessageEndDownload();
+ if (!m_curHdrInfo)
+ m_curHdrInfo = m_hdrDownloadCache->StartNewHdr();
+ if (m_curHdrInfo)
+ m_curHdrInfo->SetMsgSize(total_message_size);
+ return NS_OK;
+ }
+ // if we have a mock channel, that means we have a channel listener who wants the
+ // message. So set up a pipe. We'll write the messsage into one end of the pipe
+ // and they will read it out of the other end.
+ else if (m_channelListener)
+ {
+ // create a pipe to pump the message into...the output will go to whoever
+ // is consuming the message display
+ // we create an "infinite" pipe in case we get extremely long lines from the imap server,
+ // and the consumer is waiting for a whole line
+ nsCOMPtr<nsIPipe> pipe = do_CreateInstance("@mozilla.org/pipe;1");
+ rv = pipe->Init(false, false, 4096, PR_UINT32_MAX, nullptr);
+ NS_ASSERTION(NS_SUCCEEDED(rv), "nsIPipe->Init failed!");
+
+ pipe->GetInputStream(getter_AddRefs(m_channelInputStream));
+ pipe->GetOutputStream(getter_AddRefs(m_channelOutputStream));
+ }
+ // else, if we are saving the message to disk!
+ else if (m_imapMessageSink /* && m_imapAction == nsIImapUrl::nsImapSaveMessageToDisk */)
+ {
+ // we get here when download the inbox for offline use
+ nsCOMPtr<nsIFile> file;
+ bool addDummyEnvelope = true;
+ nsCOMPtr<nsIMsgMessageUrl> msgurl = do_QueryInterface(m_runningUrl);
+ msgurl->GetMessageFile(getter_AddRefs(file));
+ msgurl->GetAddDummyEnvelope(&addDummyEnvelope);
+ if (file)
+ rv = m_imapMessageSink->SetupMsgWriteStream(file, addDummyEnvelope);
+ }
+ if (m_imapMailFolderSink && m_runningUrl)
+ {
+ nsCOMPtr <nsISupports> copyState;
+ if (m_runningUrl)
+ {
+ m_runningUrl->GetCopyState(getter_AddRefs(copyState));
+ if (copyState) // only need this notification during copy
+ {
+ nsCOMPtr<nsIMsgMailNewsUrl> mailurl = do_QueryInterface(m_runningUrl);
+ m_imapMailFolderSink->StartMessage(mailurl);
+ }
+ }
+ }
+
+ }
+ else
+ HandleMemoryFailure();
+ return rv;
+}
+
+void
+nsImapProtocol::GetShouldDownloadAllHeaders(bool *aResult)
+{
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->GetShouldDownloadAllHeaders(aResult);
+}
+
+void
+nsImapProtocol::GetArbitraryHeadersToDownload(nsCString &aResult)
+{
+ if (m_imapServerSink)
+ m_imapServerSink->GetArbitraryHeaders(aResult);
+}
+
+void
+nsImapProtocol::AdjustChunkSize()
+{
+ int32_t deltaInSeconds;
+ PRTime2Seconds(m_endTime - m_startTime, &deltaInSeconds);
+ m_trackingTime = false;
+ if (deltaInSeconds < 0)
+ return; // bogus for some reason
+
+ if (deltaInSeconds <= m_tooFastTime && m_curFetchSize >= m_chunkSize)
+ {
+ m_chunkSize += m_chunkAddSize;
+ m_chunkThreshold = m_chunkSize + (m_chunkSize / 2);
+ // we used to have a max for the chunk size - I don't think that's needed.
+ }
+ else if (deltaInSeconds <= m_idealTime)
+ return;
+ else
+ {
+ if (m_chunkSize > m_chunkStartSize)
+ m_chunkSize = m_chunkStartSize;
+ else if (m_chunkSize > (m_chunkAddSize * 2))
+ m_chunkSize -= m_chunkAddSize;
+ m_chunkThreshold = m_chunkSize + (m_chunkSize / 2);
+ }
+ // remember these new values globally so new connections
+ // can take advantage of them.
+ if (gChunkSize != m_chunkSize)
+ {
+ // will cause chunk size pref to be written in CloseStream.
+ gChunkSizeDirty = true;
+ gChunkSize = m_chunkSize;
+ gChunkThreshold = m_chunkThreshold;
+ }
+}
+
+// authenticated state commands
+
+// escape any backslashes or quotes. Backslashes are used a lot with our NT server
+void nsImapProtocol::CreateEscapedMailboxName(const char *rawName, nsCString &escapedName)
+{
+ escapedName.Assign(rawName);
+
+ for (int32_t strIndex = 0; *rawName; strIndex++)
+ {
+ char currentChar = *rawName++;
+ if ((currentChar == '\\') || (currentChar == '\"'))
+ escapedName.Insert('\\', strIndex++);
+ }
+}
+void nsImapProtocol::SelectMailbox(const char *mailboxName)
+{
+ ProgressEventFunctionUsingIdWithString (IMAP_STATUS_SELECTING_MAILBOX, mailboxName);
+ IncrementCommandTagNumber();
+
+ m_closeNeededBeforeSelect = false; // initial value
+ GetServerStateParser().ResetFlagInfo();
+ nsCString escapedName;
+ CreateEscapedMailboxName(mailboxName, escapedName);
+ nsCString commandBuffer(GetServerCommandTag());
+ commandBuffer.Append(" select \"");
+ commandBuffer.Append(escapedName.get());
+ commandBuffer.Append("\"");
+ if (UseCondStore())
+ commandBuffer.Append(" (CONDSTORE)");
+ commandBuffer.Append(CRLF);
+
+ nsresult res;
+ res = SendData(commandBuffer.get());
+ if (NS_FAILED(res)) return;
+ ParseIMAPandCheckForNewMail();
+
+ int32_t numOfMessagesInFlagState = 0;
+ nsImapAction imapAction;
+ m_flagState->GetNumberOfMessages(&numOfMessagesInFlagState);
+ res = m_runningUrl->GetImapAction(&imapAction);
+ // if we've selected a mailbox, and we're not going to do an update because of the
+ // url type, but don't have the flags, go get them!
+ if (GetServerStateParser().LastCommandSuccessful() && NS_SUCCEEDED(res) &&
+ imapAction != nsIImapUrl::nsImapSelectFolder && imapAction != nsIImapUrl::nsImapExpungeFolder
+ && imapAction != nsIImapUrl::nsImapLiteSelectFolder &&
+ imapAction != nsIImapUrl::nsImapDeleteAllMsgs &&
+ ((GetServerStateParser().NumberOfMessages() != numOfMessagesInFlagState) && (numOfMessagesInFlagState == 0)))
+ {
+ ProcessMailboxUpdate(false);
+ }
+}
+
+// Please call only with a single message ID
+void nsImapProtocol::Bodystructure(const nsCString &messageId, bool idIsUid)
+{
+ IncrementCommandTagNumber();
+
+ nsCString commandString(GetServerCommandTag());
+ if (idIsUid)
+ commandString.Append(" UID");
+ commandString.Append(" fetch ");
+
+ commandString.Append(messageId);
+ commandString.Append(" (BODYSTRUCTURE)" CRLF);
+
+ nsresult rv = SendData(commandString.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail(commandString.get());
+}
+
+void nsImapProtocol::PipelinedFetchMessageParts(const char *uid, nsIMAPMessagePartIDArray *parts)
+{
+ // assumes no chunking
+
+ // build up a string to fetch
+ nsCString stringToFetch, what;
+ int32_t currentPartNum = 0;
+ while ((parts->GetNumParts() > currentPartNum) && !DeathSignalReceived())
+ {
+ nsIMAPMessagePartID *currentPart = parts->GetPart(currentPartNum);
+ if (currentPart)
+ {
+ // Do things here depending on the type of message part
+ // Append it to the fetch string
+ if (currentPartNum > 0)
+ stringToFetch.Append(" ");
+
+ switch (currentPart->GetFields())
+ {
+ case kMIMEHeader:
+ what = "BODY.PEEK[";
+ what.Append(currentPart->GetPartNumberString());
+ what.Append(".MIME]");
+ stringToFetch.Append(what);
+ break;
+ case kRFC822HeadersOnly:
+ if (currentPart->GetPartNumberString())
+ {
+ what = "BODY.PEEK[";
+ what.Append(currentPart->GetPartNumberString());
+ what.Append(".HEADER]");
+ stringToFetch.Append(what);
+ }
+ else
+ {
+ // headers for the top-level message
+ stringToFetch.Append("BODY.PEEK[HEADER]");
+ }
+ break;
+ default:
+ NS_ASSERTION(false, "we should only be pipelining MIME headers and Message headers");
+ break;
+ }
+
+ }
+ currentPartNum++;
+ }
+
+ // Run the single, pipelined fetch command
+ if ((parts->GetNumParts() > 0) && !DeathSignalReceived() && !GetPseudoInterrupted() && stringToFetch.get())
+ {
+ IncrementCommandTagNumber();
+
+ nsCString commandString(GetServerCommandTag());
+ commandString.Append(" UID fetch ");
+ commandString.Append(uid, 10);
+ commandString.Append(" (");
+ commandString.Append(stringToFetch);
+ commandString.Append(")" CRLF);
+ nsresult rv = SendData(commandString.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail(commandString.get());
+ }
+}
+
+
+void nsImapProtocol::FetchMsgAttribute(const nsCString &messageIds, const nsCString &attribute)
+{
+ IncrementCommandTagNumber();
+
+ nsAutoCString commandString (GetServerCommandTag());
+ commandString.Append(" UID fetch ");
+ commandString.Append(messageIds);
+ commandString.Append(" (");
+ commandString.Append(attribute);
+ commandString.Append(")" CRLF);
+ nsresult rv = SendData(commandString.get());
+
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail(commandString.get());
+ GetServerStateParser().SetFetchingFlags(false);
+ // Always clear this flag after every fetch.
+ m_fetchingWholeMessage = false;
+}
+
+// this routine is used to fetch a message or messages, or headers for a
+// message...
+
+void nsImapProtocol::FallbackToFetchWholeMsg(const nsCString &messageId, uint32_t messageSize)
+{
+ if (m_imapMessageSink && m_runningUrl)
+ {
+ bool shouldStoreMsgOffline;
+ m_runningUrl->GetStoreOfflineOnFallback(&shouldStoreMsgOffline);
+ m_runningUrl->SetStoreResultsOffline(shouldStoreMsgOffline);
+ }
+ FetchTryChunking(messageId,
+ m_imapAction == nsIImapUrl::nsImapMsgFetchPeek ?
+ kEveryThingRFC822Peek : kEveryThingRFC822,
+ true, nullptr, messageSize, true);
+}
+
+void
+nsImapProtocol::FetchMessage(const nsCString &messageIds,
+ nsIMAPeFetchFields whatToFetch,
+ const char *fetchModifier,
+ uint32_t startByte, uint32_t numBytes,
+ char *part)
+{
+ IncrementCommandTagNumber();
+
+ nsCString commandString;
+ commandString = "%s UID fetch";
+
+ switch (whatToFetch) {
+ case kEveryThingRFC822:
+ m_flagChangeCount++;
+ m_fetchingWholeMessage = true;
+ if (m_trackingTime)
+ AdjustChunkSize(); // we started another segment
+ m_startTime = PR_Now(); // save start of download time
+ m_trackingTime = true;
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("FetchMessage everything: curFetchSize %u numBytes %u",
+ m_curFetchSize, numBytes));
+ if (numBytes > 0)
+ m_curFetchSize = numBytes;
+
+ if (GetServerStateParser().ServerHasIMAP4Rev1Capability())
+ {
+ if (GetServerStateParser().GetCapabilityFlag() & kHasXSenderCapability)
+ commandString.Append(" %s (XSENDER UID RFC822.SIZE BODY[]");
+ else
+ commandString.Append(" %s (UID RFC822.SIZE BODY[]");
+ }
+ else
+ {
+ if (GetServerStateParser().GetCapabilityFlag() & kHasXSenderCapability)
+ commandString.Append(" %s (XSENDER UID RFC822.SIZE RFC822");
+ else
+ commandString.Append(" %s (UID RFC822.SIZE RFC822");
+ }
+ if (numBytes > 0)
+ {
+ // if we are retrieving chunks
+ char *byterangeString = PR_smprintf("<%ld.%ld>",startByte, numBytes);
+ if (byterangeString)
+ {
+ commandString.Append(byterangeString);
+ PR_Free(byterangeString);
+ }
+ }
+ commandString.Append(")");
+
+ break;
+
+ case kEveryThingRFC822Peek:
+ {
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("FetchMessage peek: curFetchSize %u numBytes %u",
+ m_curFetchSize, numBytes));
+ if (numBytes > 0)
+ m_curFetchSize = numBytes;
+ const char *formatString = "";
+ eIMAPCapabilityFlags server_capabilityFlags = GetServerStateParser().GetCapabilityFlag();
+
+ m_fetchingWholeMessage = true;
+ if (server_capabilityFlags & kIMAP4rev1Capability)
+ {
+ // use body[].peek since rfc822.peek is not in IMAP4rev1
+ if (server_capabilityFlags & kHasXSenderCapability)
+ formatString = " %s (XSENDER UID RFC822.SIZE BODY.PEEK[]";
+ else
+ formatString = " %s (UID RFC822.SIZE BODY.PEEK[]";
+ }
+ else
+ {
+ if (server_capabilityFlags & kHasXSenderCapability)
+ formatString = " %s (XSENDER UID RFC822.SIZE RFC822.peek";
+ else
+ formatString = " %s (UID RFC822.SIZE RFC822.peek";
+ }
+
+ commandString.Append(formatString);
+ if (numBytes > 0)
+ {
+ // if we are retrieving chunks
+ char *byterangeString = PR_smprintf("<%ld.%ld>",startByte, numBytes);
+ if (byterangeString)
+ {
+ commandString.Append(byterangeString);
+ PR_Free(byterangeString);
+ }
+ }
+ commandString.Append(")");
+ }
+ break;
+ case kHeadersRFC822andUid:
+ if (GetServerStateParser().ServerHasIMAP4Rev1Capability())
+ {
+ eIMAPCapabilityFlags server_capabilityFlags = GetServerStateParser().GetCapabilityFlag();
+ bool aolImapServer = ((server_capabilityFlags & kAOLImapCapability) != 0);
+ bool downloadAllHeaders = false;
+ // checks if we're filtering on "any header" or running a spam filter requiring all headers
+ GetShouldDownloadAllHeaders(&downloadAllHeaders);
+
+ if (!downloadAllHeaders) // if it's ok -- no filters on any header, etc.
+ {
+ char *headersToDL = nullptr;
+ char *what = nullptr;
+ const char *dbHeaders = (gUseEnvelopeCmd) ? IMAP_DB_HEADERS : IMAP_ENV_AND_DB_HEADERS;
+ nsCString arbitraryHeaders;
+ GetArbitraryHeadersToDownload(arbitraryHeaders);
+ for (uint32_t i = 0; i < mCustomDBHeaders.Length(); i++)
+ {
+ if (arbitraryHeaders.Find(mCustomDBHeaders[i], CaseInsensitiveCompare) == kNotFound)
+ {
+ if (!arbitraryHeaders.IsEmpty())
+ arbitraryHeaders.Append(' ');
+ arbitraryHeaders.Append(mCustomDBHeaders[i]);
+ }
+ }
+ for (uint32_t i = 0; i < mCustomHeaders.Length(); i++)
+ {
+ if (arbitraryHeaders.Find(mCustomHeaders[i], CaseInsensitiveCompare) == kNotFound)
+ {
+ if (!arbitraryHeaders.IsEmpty())
+ arbitraryHeaders.Append(' ');
+ arbitraryHeaders.Append(mCustomHeaders[i]);
+ }
+ }
+ if (arbitraryHeaders.IsEmpty())
+ headersToDL = strdup(dbHeaders);
+ else
+ headersToDL = PR_smprintf("%s %s",dbHeaders, arbitraryHeaders.get());
+
+ if (gUseEnvelopeCmd)
+ what = PR_smprintf(" ENVELOPE BODY.PEEK[HEADER.FIELDS (%s)])", headersToDL);
+ else
+ what = PR_smprintf(" BODY.PEEK[HEADER.FIELDS (%s)])",headersToDL);
+ NS_Free(headersToDL);
+ if (what)
+ {
+ commandString.Append(" %s (UID ");
+ if (m_isGmailServer)
+ commandString.Append("X-GM-MSGID X-GM-THRID X-GM-LABELS ");
+ if (aolImapServer)
+ commandString.Append(" XAOL.SIZE") ;
+ else
+ commandString.Append("RFC822.SIZE");
+ commandString.Append(" FLAGS");
+ commandString.Append(what);
+ PR_Free(what);
+ }
+ else
+ {
+ commandString.Append(" %s (UID RFC822.SIZE BODY.PEEK[HEADER] FLAGS)");
+ }
+ }
+ else
+ commandString.Append(" %s (UID RFC822.SIZE BODY.PEEK[HEADER] FLAGS)");
+ }
+ else
+ commandString.Append(" %s (UID RFC822.SIZE RFC822.HEADER FLAGS)");
+ break;
+ case kUid:
+ commandString.Append(" %s (UID)");
+ break;
+ case kFlags:
+ GetServerStateParser().SetFetchingFlags(true);
+ commandString.Append(" %s (FLAGS)");
+ break;
+ case kRFC822Size:
+ commandString.Append(" %s (RFC822.SIZE)");
+ break;
+ case kBodyStart:
+ {
+ int32_t numBytesToFetch;
+ m_runningUrl->GetNumBytesToFetch(&numBytesToFetch);
+
+ commandString.Append(" %s (UID BODY.PEEK[HEADER.FIELDS (Content-Type Content-Transfer-Encoding)] BODY.PEEK[TEXT]<0.");
+ commandString.AppendInt(numBytesToFetch);
+ commandString.Append(">)");
+ }
+ break;
+ case kRFC822HeadersOnly:
+ if (GetServerStateParser().ServerHasIMAP4Rev1Capability())
+ {
+ if (part)
+ {
+ commandString.Append(" %s (BODY[");
+ char *what = PR_smprintf("%s.HEADER])", part);
+ if (what)
+ {
+ commandString.Append(what);
+ PR_Free(what);
+ }
+ else
+ HandleMemoryFailure();
+ }
+ else
+ {
+ // headers for the top-level message
+ commandString.Append(" %s (BODY[HEADER])");
+ }
+ }
+ else
+ commandString.Append(" %s (RFC822.HEADER)");
+ break;
+ case kMIMEPart:
+ commandString.Append(" %s (BODY.PEEK[%s]");
+ if (numBytes > 0)
+ {
+ // if we are retrieving chunks
+ char *byterangeString = PR_smprintf("<%ld.%ld>",startByte, numBytes);
+ if (byterangeString)
+ {
+ commandString.Append(byterangeString);
+ PR_Free(byterangeString);
+ }
+ }
+ commandString.Append(")");
+ break;
+ case kMIMEHeader:
+ commandString.Append(" %s (BODY[%s.MIME])");
+ break;
+ };
+
+ if (fetchModifier)
+ commandString.Append(fetchModifier);
+
+ commandString.Append(CRLF);
+
+ // since messageIds can be infinitely long, use a dynamic buffer rather than the fixed one
+ const char *commandTag = GetServerCommandTag();
+ int protocolStringSize = commandString.Length() + messageIds.Length() + PL_strlen(commandTag) + 1 +
+ (part ? PL_strlen(part) : 0);
+ char *protocolString = (char *) PR_CALLOC( protocolStringSize );
+
+ if (protocolString)
+ {
+ char *cCommandStr = ToNewCString(commandString);
+ if ((whatToFetch == kMIMEPart) ||
+ (whatToFetch == kMIMEHeader))
+ {
+ PR_snprintf(protocolString, // string to create
+ protocolStringSize, // max size
+ cCommandStr, // format string
+ commandTag, // command tag
+ messageIds.get(),
+ part);
+ }
+ else
+ {
+ PR_snprintf(protocolString, // string to create
+ protocolStringSize, // max size
+ cCommandStr, // format string
+ commandTag, // command tag
+ messageIds.get());
+ }
+
+ nsresult rv = SendData(protocolString);
+
+ nsMemory::Free(cCommandStr);
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail(protocolString);
+ PR_Free(protocolString);
+ GetServerStateParser().SetFetchingFlags(false);
+ // Always clear this flag after every fetch.
+ m_fetchingWholeMessage = false;
+ if (GetServerStateParser().LastCommandSuccessful() && CheckNeeded())
+ Check();
+ }
+ else
+ HandleMemoryFailure();
+}
+
+void nsImapProtocol::FetchTryChunking(const nsCString &messageIds,
+ nsIMAPeFetchFields whatToFetch,
+ bool idIsUid,
+ char *part,
+ uint32_t downloadSize,
+ bool tryChunking)
+{
+ GetServerStateParser().SetTotalDownloadSize(downloadSize);
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("FetchTryChunking: curFetchSize %u", downloadSize));
+ m_curFetchSize = downloadSize; // we'll change this if chunking.
+ if (m_fetchByChunks && tryChunking &&
+ GetServerStateParser().ServerHasIMAP4Rev1Capability() &&
+ (downloadSize > (uint32_t) m_chunkThreshold))
+ {
+ uint32_t startByte = 0;
+ GetServerStateParser().ClearLastFetchChunkReceived();
+ while (!DeathSignalReceived() && !GetPseudoInterrupted() &&
+ !GetServerStateParser().GetLastFetchChunkReceived() &&
+ GetServerStateParser().ContinueParse())
+ {
+ FetchMessage(messageIds,
+ whatToFetch,
+ nullptr,
+ startByte, m_chunkSize,
+ part);
+ startByte += m_chunkSize;
+ }
+
+ // Only abort the stream if this is a normal message download
+ // Otherwise, let the body shell abort the stream.
+ if ((whatToFetch == kEveryThingRFC822)
+ &&
+ ((startByte > 0 && (startByte < downloadSize) &&
+ (DeathSignalReceived() || GetPseudoInterrupted())) ||
+ !GetServerStateParser().ContinueParse()))
+ {
+ AbortMessageDownLoad();
+ PseudoInterrupt(false);
+ }
+ }
+ else
+ {
+ // small message, or (we're not chunking and not doing bodystructure),
+ // or the server is not rev1.
+ // Just fetch the whole thing.
+ FetchMessage(messageIds, whatToFetch, nullptr, 0, 0, part);
+ }
+}
+
+
+void nsImapProtocol::PipelinedFetchMessageParts(nsCString &uid, nsIMAPMessagePartIDArray *parts)
+{
+ // assumes no chunking
+
+ // build up a string to fetch
+ nsCString stringToFetch;
+ nsCString what;
+
+ int32_t currentPartNum = 0;
+ while ((parts->GetNumParts() > currentPartNum) && !DeathSignalReceived())
+ {
+ nsIMAPMessagePartID *currentPart = parts->GetPart(currentPartNum);
+ if (currentPart)
+ {
+ // Do things here depending on the type of message part
+ // Append it to the fetch string
+ if (currentPartNum > 0)
+ stringToFetch += " ";
+
+ switch (currentPart->GetFields())
+ {
+ case kMIMEHeader:
+ what = "BODY.PEEK[";
+ what += currentPart->GetPartNumberString();
+ what += ".MIME]";
+ stringToFetch += what;
+ break;
+ case kRFC822HeadersOnly:
+ if (currentPart->GetPartNumberString())
+ {
+ what = "BODY.PEEK[";
+ what += currentPart->GetPartNumberString();
+ what += ".HEADER]";
+ stringToFetch += what;
+ }
+ else
+ {
+ // headers for the top-level message
+ stringToFetch += "BODY.PEEK[HEADER]";
+ }
+ break;
+ default:
+ NS_ASSERTION(false, "we should only be pipelining MIME headers and Message headers");
+ break;
+ }
+
+ }
+ currentPartNum++;
+ }
+
+ // Run the single, pipelined fetch command
+ if ((parts->GetNumParts() > 0) && !DeathSignalReceived() && !GetPseudoInterrupted() && stringToFetch.get())
+ {
+ IncrementCommandTagNumber();
+
+ char *commandString = PR_smprintf("%s UID fetch %s (%s)%s",
+ GetServerCommandTag(), uid.get(),
+ stringToFetch.get(), CRLF);
+
+ if (commandString)
+ {
+ nsresult rv = SendData(commandString);
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail(commandString);
+ PR_Free(commandString);
+ }
+ else
+ HandleMemoryFailure();
+ }
+}
+
+
+void
+nsImapProtocol::PostLineDownLoadEvent(const char *line, uint32_t uidOfMessage)
+{
+ if (!GetServerStateParser().GetDownloadingHeaders())
+ {
+ uint32_t byteCount = PL_strlen(line);
+ bool echoLineToMessageSink = false;
+ // if we have a channel listener, then just spool the message
+ // directly to the listener
+ if (m_channelListener)
+ {
+ uint32_t count = 0;
+ if (m_channelOutputStream)
+ {
+ nsresult rv = m_channelOutputStream->Write(line, byteCount, &count);
+ NS_ASSERTION(count == byteCount, "IMAP channel pipe couldn't buffer entire write");
+ if (NS_SUCCEEDED(rv))
+ {
+ nsCOMPtr<nsIRequest> request = do_QueryInterface(m_mockChannel);
+ m_channelListener->OnDataAvailable(request, m_channelContext, m_channelInputStream, 0, count);
+ }
+ // else some sort of explosion?
+ }
+ }
+ if (m_runningUrl)
+ m_runningUrl->GetStoreResultsOffline(&echoLineToMessageSink);
+
+ m_bytesToChannel += byteCount;
+ if (m_imapMessageSink && line && echoLineToMessageSink && !GetPseudoInterrupted())
+ m_imapMessageSink->ParseAdoptedMsgLine(line, uidOfMessage, m_runningUrl);
+ }
+ // ***** We need to handle the pseudo interrupt here *****
+}
+
+// Handle a line seen by the parser.
+// * The argument |lineCopy| must be nullptr or should contain the same string as
+// |line|. |lineCopy| will be modified.
+// * A line may be passed by parts, e.g., "part1 part2\r\n" may be passed as
+// HandleMessageDownLoadLine("part 1 ", 1);
+// HandleMessageDownLoadLine("part 2\r\n", 0);
+// However, it is assumed that a CRLF or a CRCRLF is never split (i.e., this is
+// ensured *before* invoking this method).
+void nsImapProtocol::HandleMessageDownLoadLine(const char *line, bool isPartialLine,
+ char *lineCopy)
+{
+ NS_PRECONDITION(lineCopy == nullptr || !PL_strcmp(line, lineCopy),
+ "line and lineCopy must contain the same string");
+ const char *messageLine = line;
+ uint32_t lineLength = strlen(messageLine);
+ const char *cEndOfLine = messageLine + lineLength;
+ char *localMessageLine = nullptr;
+
+ // If we obtain a partial line (due to fetching by chunks), we do not
+ // add/modify the end-of-line terminator.
+ if (!isPartialLine)
+ {
+ // Change this line to native line termination, duplicate if necessary.
+ // Do not assume that the line really ends in CRLF
+ // to start with, even though it is supposed to be RFC822
+
+ // normalize line endings to CRLF unless we are saving the message to disk
+ bool canonicalLineEnding = true;
+ nsCOMPtr<nsIMsgMessageUrl> msgUrl = do_QueryInterface(m_runningUrl);
+
+ if (m_imapAction == nsIImapUrl::nsImapSaveMessageToDisk && msgUrl)
+ msgUrl->GetCanonicalLineEnding(&canonicalLineEnding);
+
+ NS_PRECONDITION(MSG_LINEBREAK_LEN == 1 ||
+ (MSG_LINEBREAK_LEN == 2 && !PL_strcmp(CRLF, MSG_LINEBREAK)),
+ "violated assumptions on MSG_LINEBREAK");
+ if (MSG_LINEBREAK_LEN == 1 && !canonicalLineEnding)
+ {
+ bool lineEndsWithCRorLF = lineLength >= 1 &&
+ (cEndOfLine[-1] == '\r' || cEndOfLine[-1] == '\n');
+ char *endOfLine;
+ if (lineCopy && lineEndsWithCRorLF) // true for most lines
+ {
+ endOfLine = lineCopy + lineLength;
+ messageLine = lineCopy;
+ }
+ else
+ {
+ // leave enough room for one more char, MSG_LINEBREAK[0]
+ localMessageLine = (char *) PR_MALLOC(lineLength + 2);
+ if (!localMessageLine) // memory failure
+ return;
+ PL_strcpy(localMessageLine, line);
+ endOfLine = localMessageLine + lineLength;
+ messageLine = localMessageLine;
+ }
+
+ if (lineLength >= 2 &&
+ endOfLine[-2] == '\r' &&
+ endOfLine[-1] == '\n')
+ {
+ if(lineLength>=3 && endOfLine[-3] == '\r') // CRCRLF
+ {
+ endOfLine--;
+ lineLength--;
+ }
+ /* CRLF -> CR or LF */
+ endOfLine[-2] = MSG_LINEBREAK[0];
+ endOfLine[-1] = '\0';
+ lineLength--;
+ }
+ else if (lineLength >= 1 &&
+ ((endOfLine[-1] == '\r') || (endOfLine[-1] == '\n')))
+ {
+ /* CR -> LF or LF -> CR */
+ endOfLine[-1] = MSG_LINEBREAK[0];
+ }
+ else // no eol characters at all
+ {
+ endOfLine[0] = MSG_LINEBREAK[0]; // CR or LF
+ endOfLine[1] = '\0';
+ lineLength++;
+ }
+ }
+ else // enforce canonical CRLF linebreaks
+ {
+ if (lineLength==0 || (lineLength == 1 && cEndOfLine[-1] == '\n'))
+ {
+ messageLine = CRLF;
+ lineLength = 2;
+ }
+ else if (cEndOfLine[-1] != '\n' || cEndOfLine[-2] != '\r' ||
+ (lineLength >=3 && cEndOfLine[-3] == '\r'))
+ {
+ // The line does not end in CRLF (or it ends in CRCRLF).
+ // Copy line and leave enough room for two more chars (CR and LF).
+ localMessageLine = (char *) PR_MALLOC(lineLength + 3);
+ if (!localMessageLine) // memory failure
+ return;
+ PL_strcpy(localMessageLine, line);
+ char *endOfLine = localMessageLine + lineLength;
+ messageLine = localMessageLine;
+
+ if (lineLength>=3 && endOfLine[-1] == '\n' &&
+ endOfLine[-2] == '\r')
+ {
+ // CRCRLF -> CRLF
+ endOfLine[-2] = '\n';
+ endOfLine[-1] = '\0';
+ lineLength--;
+ }
+ else if ((endOfLine[-1] == '\r') || (endOfLine[-1] == '\n'))
+ {
+ // LF -> CRLF or CR -> CRLF
+ endOfLine[-1] = '\r';
+ endOfLine[0] = '\n';
+ endOfLine[1] = '\0';
+ lineLength++;
+ }
+ else // no eol characters at all
+ {
+ endOfLine[0] = '\r';
+ endOfLine[1] = '\n';
+ endOfLine[2] = '\0';
+ lineLength += 2;
+ }
+ }
+ }
+ }
+ NS_ASSERTION(lineLength == PL_strlen(messageLine), "lineLength not accurate");
+
+ // check if sender obtained via XSENDER server extension matches "From:" field
+ const char *xSenderInfo = GetServerStateParser().GetXSenderInfo();
+ if (xSenderInfo && *xSenderInfo && !m_fromHeaderSeen)
+ {
+ if (!PL_strncmp("From: ", messageLine, 6))
+ {
+ m_fromHeaderSeen = true;
+ if (PL_strstr(messageLine, xSenderInfo) != NULL)
+ // Adding a X-Mozilla-Status line here is not very elegant but it
+ // works. Another X-Mozilla-Status line is added to the message when
+ // downloading to a local folder; this new line will also contain the
+ // 'authed' flag we are adding here. (If the message is again
+ // uploaded to the server, this flag is lost.)
+ // 0x0200 == nsMsgMessageFlags::SenderAuthed
+ HandleMessageDownLoadLine("X-Mozilla-Status: 0200\r\n", false);
+ GetServerStateParser().FreeXSenderInfo();
+ }
+ }
+
+ if (GetServerStateParser().GetDownloadingHeaders())
+ {
+ if (!m_curHdrInfo)
+ BeginMessageDownLoad(GetServerStateParser().SizeOfMostRecentMessage(), MESSAGE_RFC822);
+ if (m_curHdrInfo)
+ m_curHdrInfo->CacheLine(messageLine, GetServerStateParser().CurrentResponseUID());
+ PR_Free(localMessageLine);
+ return;
+ }
+ // if this line is for a different message, or the incoming line is too big
+ if (((m_downloadLineCache->CurrentUID() != GetServerStateParser().CurrentResponseUID()) && !m_downloadLineCache->CacheEmpty()) ||
+ (m_downloadLineCache->SpaceAvailable() < lineLength + 1) )
+ FlushDownloadCache();
+
+ // so now the cache is flushed, but this string might still be to big
+ if (m_downloadLineCache->SpaceAvailable() < lineLength + 1)
+ PostLineDownLoadEvent(messageLine, GetServerStateParser().CurrentResponseUID());
+ else
+ m_downloadLineCache->CacheLine(messageLine, GetServerStateParser().CurrentResponseUID());
+
+ PR_Free(localMessageLine);
+}
+
+void nsImapProtocol::FlushDownloadCache()
+{
+ if (!m_downloadLineCache->CacheEmpty())
+ {
+ msg_line_info *downloadLine = m_downloadLineCache->GetCurrentLineInfo();
+ PostLineDownLoadEvent(downloadLine->adoptedMessageLine,
+ downloadLine->uidOfMessage);
+ m_downloadLineCache->ResetCache();
+ }
+}
+
+void nsImapProtocol::NormalMessageEndDownload()
+{
+ Log("STREAM", "CLOSE", "Normal Message End Download Stream");
+
+ if (m_trackingTime)
+ AdjustChunkSize();
+ if (m_imapMailFolderSink && m_curHdrInfo && GetServerStateParser().GetDownloadingHeaders())
+ {
+ m_curHdrInfo->SetMsgSize(GetServerStateParser().SizeOfMostRecentMessage());
+ m_curHdrInfo->SetMsgUid(GetServerStateParser().CurrentResponseUID());
+ m_hdrDownloadCache->FinishCurrentHdr();
+ int32_t numHdrsCached;
+ m_hdrDownloadCache->GetNumHeaders(&numHdrsCached);
+ if (numHdrsCached == kNumHdrsToXfer)
+ {
+ m_imapMailFolderSink->ParseMsgHdrs(this, m_hdrDownloadCache);
+ m_hdrDownloadCache->ResetAll();
+ }
+ }
+ FlushDownloadCache();
+
+ if (!GetServerStateParser().GetDownloadingHeaders())
+ {
+ int32_t updatedMessageSize = -1;
+ if (m_fetchingWholeMessage)
+ {
+ updatedMessageSize = m_bytesToChannel;
+#ifdef PR_LOGGING
+ if (m_bytesToChannel != GetServerStateParser().SizeOfMostRecentMessage()) {
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("STREAM:CLOSE Server's RFC822.SIZE %u, actual size %u",
+ GetServerStateParser().SizeOfMostRecentMessage(),
+ m_bytesToChannel));
+ }
+#endif
+ }
+ // need to know if we're downloading for display or not. We'll use action == nsImapMsgFetch for now
+ nsImapAction imapAction = nsIImapUrl::nsImapSelectFolder; // just set it to some legal value
+ if (m_runningUrl)
+ m_runningUrl->GetImapAction(&imapAction);
+
+ if (m_imapMessageSink)
+ m_imapMessageSink->NormalEndMsgWriteStream(m_downloadLineCache->CurrentUID(), imapAction == nsIImapUrl::nsImapMsgFetch, m_runningUrl, updatedMessageSize);
+
+ if (m_runningUrl && m_imapMailFolderSink)
+ {
+ nsCOMPtr <nsISupports> copyState;
+ m_runningUrl->GetCopyState(getter_AddRefs(copyState));
+ if (copyState) // only need this notification during copy
+ {
+ nsCOMPtr<nsIMsgMailNewsUrl> mailUrl (do_QueryInterface(m_runningUrl));
+ m_imapMailFolderSink->EndMessage(mailUrl, m_downloadLineCache->CurrentUID());
+ }
+ }
+ }
+ m_curHdrInfo = nullptr;
+}
+
+void nsImapProtocol::AbortMessageDownLoad()
+{
+ Log("STREAM", "CLOSE", "Abort Message Download Stream");
+
+ if (m_trackingTime)
+ AdjustChunkSize();
+ FlushDownloadCache();
+ if (GetServerStateParser().GetDownloadingHeaders())
+ {
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->AbortHeaderParseStream(this);
+ }
+ else if (m_imapMessageSink)
+ m_imapMessageSink->AbortMsgWriteStream();
+
+ m_curHdrInfo = nullptr;
+}
+
+
+void nsImapProtocol::ProcessMailboxUpdate(bool handlePossibleUndo)
+{
+ if (DeathSignalReceived())
+ return;
+
+ // Update quota information
+ char *boxName;
+ GetSelectedMailboxName(&boxName);
+ GetQuotaDataIfSupported(boxName);
+ PR_Free(boxName);
+
+ // fetch the flags and uids of all existing messages or new ones
+ if (!DeathSignalReceived() && GetServerStateParser().NumberOfMessages())
+ {
+ if (handlePossibleUndo)
+ {
+ // undo any delete flags we may have asked to
+ nsCString undoIdsStr;
+ nsAutoCString undoIds;
+
+ GetCurrentUrl()->GetListOfMessageIds(undoIdsStr);
+ undoIds.Assign(undoIdsStr);
+ if (!undoIds.IsEmpty())
+ {
+ char firstChar = (char) undoIds.CharAt(0);
+ undoIds.Cut(0, 1); // remove first character
+ // if this string started with a '-', then this is an undo of a delete
+ // if its a '+' its a redo
+ if (firstChar == '-')
+ Store(undoIds, "-FLAGS (\\Deleted)", true); // most servers will fail silently on a failure, deal with it?
+ else if (firstChar == '+')
+ Store(undoIds, "+FLAGS (\\Deleted)", true); // most servers will fail silently on a failure, deal with it?
+ else
+ NS_ASSERTION(false, "bogus undo Id's");
+ }
+ }
+
+ // make the parser record these flags
+ nsCString fetchStr;
+ int32_t added = 0, deleted = 0;
+
+ m_flagState->GetNumberOfMessages(&added);
+ deleted = m_flagState->NumberOfDeletedMessages();
+ bool flagStateEmpty = !added;
+ // Figure out if we need to do any kind of sync.
+ bool needFolderSync = (flagStateEmpty || added == deleted) && (!UseCondStore() ||
+ (GetServerStateParser().fHighestModSeq != mFolderLastModSeq) ||
+ (GetShowDeletedMessages() &&
+ GetServerStateParser().NumberOfMessages() != mFolderTotalMsgCount));
+
+ // Figure out if we need to do a full sync (UID Fetch Flags 1:*),
+ // a partial sync using CHANGEDSINCE, or a sync from the previous
+ // highwater mark.
+
+ // if the folder doesn't know about the highest uid, or the flag state
+ // is empty, and we're not using CondStore, we need a full sync.
+ bool needFullFolderSync = !mFolderHighestUID || (flagStateEmpty && !UseCondStore());
+
+ if (needFullFolderSync || needFolderSync)
+ {
+ nsCString idsToFetch("1:*");
+ char fetchModifier[40] = "";
+ if (!needFullFolderSync && !GetShowDeletedMessages() && UseCondStore())
+ PR_snprintf(fetchModifier, sizeof(fetchModifier), " (CHANGEDSINCE %llu)",
+ mFolderLastModSeq);
+ else
+ m_flagState->SetPartialUIDFetch(false);
+
+ FetchMessage(idsToFetch, kFlags, fetchModifier);
+ // lets see if we should expunge during a full sync of flags.
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ // if we did a CHANGEDSINCE fetch, do a sanity check on the msg counts
+ // to see if some other client may have done an expunge.
+ if (m_flagState->GetPartialUIDFetch())
+ {
+ if (m_flagState->NumberOfDeletedMessages() +
+ mFolderTotalMsgCount != GetServerStateParser().NumberOfMessages())
+ {
+ // sanity check failed - fall back to full flag sync
+ m_flagState->Reset();
+ m_flagState->SetPartialUIDFetch(false);
+ FetchMessage(NS_LITERAL_CSTRING("1:*"), kFlags);
+ }
+ }
+ int32_t numDeleted = m_flagState->NumberOfDeletedMessages();
+ // Don't do expunge when we are lite selecting folder because we
+ // could be doing undo.
+ // Expunge if we're always expunging, or the number of deleted messages
+ // is over the threshhold, and we're either always respecting the
+ // threshhold, or we're expunging based on the delete model, and
+ // the delete model is not the imap delete model.
+ if (m_imapAction != nsIImapUrl::nsImapLiteSelectFolder &&
+ (gExpungeOption == kAutoExpungeAlways ||
+ (numDeleted >= gExpungeThreshold &&
+ (gExpungeOption == kAutoExpungeOnThreshold ||
+ (gExpungeOption == kAutoExpungeDeleteModel && !GetShowDeletedMessages())))))
+ Expunge();
+ }
+ }
+ else
+ {
+ uint32_t highestRecordedUID = GetServerStateParser().HighestRecordedUID();
+ // if we're using CONDSTORE, and the parser hasn't seen any UIDs, use
+ // the highest UID we've seen from the folder.
+ if (UseCondStore() && !highestRecordedUID)
+ highestRecordedUID = mFolderHighestUID;
+
+ AppendUid(fetchStr, highestRecordedUID + 1);
+ fetchStr.Append(":*");
+ FetchMessage(fetchStr, kFlags); // only new messages please
+ }
+ }
+ else if (GetServerStateParser().LastCommandSuccessful())
+ {
+ GetServerStateParser().ResetFlagInfo();
+ // the flag state is empty, but not partial.
+ m_flagState->SetPartialUIDFetch(false);
+ }
+
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ nsImapAction imapAction;
+ nsresult res = m_runningUrl->GetImapAction(&imapAction);
+ if (NS_SUCCEEDED(res) && imapAction == nsIImapUrl::nsImapLiteSelectFolder)
+ return;
+ }
+
+ bool entered_waitForBodyIdsMonitor = false;
+
+ uint32_t *msgIdList = nullptr;
+ uint32_t msgCount = 0;
+
+ nsImapMailboxSpec *new_spec = GetServerStateParser().CreateCurrentMailboxSpec();
+ if (new_spec && GetServerStateParser().LastCommandSuccessful())
+ {
+ nsImapAction imapAction;
+ nsresult res = m_runningUrl->GetImapAction(&imapAction);
+ if (NS_SUCCEEDED(res) && imapAction == nsIImapUrl::nsImapExpungeFolder)
+ new_spec->mBoxFlags |= kJustExpunged;
+ m_waitForBodyIdsMonitor.Enter();
+ entered_waitForBodyIdsMonitor = true;
+
+ if (m_imapMailFolderSink)
+ {
+ bool more;
+ m_imapMailFolderSink->UpdateImapMailboxInfo(this, new_spec);
+ m_imapMailFolderSink->GetMsgHdrsToDownload(&more, &m_progressCount,
+ &msgCount, &msgIdList);
+ m_progressIndex = 0;
+ m_runningUrl->SetMoreHeadersToDownload(more);
+ // We're going to be re-running this url if there are more headers.
+ if (more)
+ m_runningUrl->SetRerunningUrl(true);
+ }
+ }
+ else if (!new_spec)
+ HandleMemoryFailure();
+
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ if (entered_waitForBodyIdsMonitor)
+ m_waitForBodyIdsMonitor.Exit();
+
+ if (msgIdList && !DeathSignalReceived() && GetServerStateParser().LastCommandSuccessful())
+ {
+ FolderHeaderDump(msgIdList, msgCount);
+ NS_Free( msgIdList);
+ }
+ HeaderFetchCompleted();
+ // this might be bogus, how are we going to do pane notification and stuff when we fetch bodies without
+ // headers!
+ }
+ else if (entered_waitForBodyIdsMonitor) // need to exit this monitor if death signal received
+ m_waitForBodyIdsMonitor.Exit();
+
+ // wait for a list of bodies to fetch.
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ WaitForPotentialListOfBodysToFetch(&msgIdList, msgCount);
+ if ( msgCount && GetServerStateParser().LastCommandSuccessful())
+ {
+ // Tell the url that it should store the msg fetch results offline,
+ // while we're dumping the messages, and then restore the setting.
+ bool wasStoringOffline;
+ m_runningUrl->GetStoreResultsOffline(&wasStoringOffline);
+ m_runningUrl->SetStoreResultsOffline(true);
+ m_progressIndex = 0;
+ m_progressCount = msgCount;
+ FolderMsgDump(msgIdList, msgCount, kEveryThingRFC822Peek);
+ m_runningUrl->SetStoreResultsOffline(wasStoringOffline);
+ }
+ }
+ if (!GetServerStateParser().LastCommandSuccessful())
+ GetServerStateParser().ResetFlagInfo();
+
+ NS_IF_RELEASE(new_spec);
+}
+
+void nsImapProtocol::FolderHeaderDump(uint32_t *msgUids, uint32_t msgCount)
+{
+ FolderMsgDump(msgUids, msgCount, kHeadersRFC822andUid);
+}
+
+void nsImapProtocol::FolderMsgDump(uint32_t *msgUids, uint32_t msgCount, nsIMAPeFetchFields fields)
+{
+ // lets worry about this progress stuff later.
+ switch (fields) {
+ case kHeadersRFC822andUid:
+ SetProgressString(IMAP_RECEIVING_MESSAGE_HEADERS_OF);
+ break;
+ case kFlags:
+ SetProgressString(IMAP_RECEIVING_MESSAGE_FLAGS_OF);
+ break;
+ default:
+ SetProgressString(IMAP_FOLDER_RECEIVING_MESSAGE_OF);
+ break;
+ }
+
+ FolderMsgDumpLoop(msgUids, msgCount, fields);
+
+ SetProgressString(0);
+}
+
+void nsImapProtocol::WaitForPotentialListOfBodysToFetch(uint32_t **msgIdList, uint32_t &msgCount)
+{
+ PRIntervalTime sleepTime = kImapSleepTime;
+
+ ReentrantMonitorAutoEnter fetchListMon(m_fetchBodyListMonitor);
+ while(!m_fetchBodyListIsNew && !DeathSignalReceived())
+ fetchListMon.Wait(sleepTime);
+ m_fetchBodyListIsNew = false;
+
+ *msgIdList = m_fetchBodyIdList;
+ msgCount = m_fetchBodyCount;
+}
+
+// libmsg uses this to notify a running imap url about message bodies it should download.
+// why not just have libmsg explicitly download the message bodies?
+NS_IMETHODIMP nsImapProtocol::NotifyBodysToDownload(uint32_t *keys, uint32_t keyCount)
+{
+ ReentrantMonitorAutoEnter fetchListMon(m_fetchBodyListMonitor);
+ PR_FREEIF(m_fetchBodyIdList);
+ m_fetchBodyIdList = (uint32_t *) PR_MALLOC(keyCount * sizeof(uint32_t));
+ if (m_fetchBodyIdList)
+ memcpy(m_fetchBodyIdList, keys, keyCount * sizeof(uint32_t));
+ m_fetchBodyCount = keyCount;
+ m_fetchBodyListIsNew = true;
+ fetchListMon.Notify();
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapProtocol::GetFlagsForUID(uint32_t uid, bool *foundIt, imapMessageFlagsType *resultFlags, char **customFlags)
+{
+ int32_t i;
+
+ imapMessageFlagsType flags = m_flagState->GetMessageFlagsFromUID(uid, foundIt, &i);
+ if (*foundIt)
+ {
+ *resultFlags = flags;
+ if ((flags & kImapMsgCustomKeywordFlag) && customFlags)
+ m_flagState->GetCustomFlags(uid, customFlags);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapProtocol::GetFlagAndUidState(nsIImapFlagAndUidState **aFlagState)
+{
+ NS_ENSURE_ARG_POINTER(aFlagState);
+ NS_IF_ADDREF(*aFlagState = m_flagState);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapProtocol::GetSupportedUserFlags(uint16_t *supportedFlags)
+{
+ if (!supportedFlags)
+ return NS_ERROR_NULL_POINTER;
+
+ *supportedFlags = m_flagState->GetSupportedUserFlags();
+ return NS_OK;
+}
+void nsImapProtocol::FolderMsgDumpLoop(uint32_t *msgUids, uint32_t msgCount, nsIMAPeFetchFields fields)
+{
+ int32_t msgCountLeft = msgCount;
+ uint32_t msgsDownloaded = 0;
+ do
+ {
+ nsCString idString;
+ uint32_t msgsToDownload = msgCountLeft;
+ AllocateImapUidString(msgUids + msgsDownloaded, msgsToDownload, m_flagState, idString); // 20 * 200
+ FetchMessage(idString, fields);
+ msgsDownloaded += msgsToDownload;
+ msgCountLeft -= msgsToDownload;
+ }
+ while (msgCountLeft > 0 && !DeathSignalReceived());
+}
+
+void nsImapProtocol::HeaderFetchCompleted()
+{
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->ParseMsgHdrs(this, m_hdrDownloadCache);
+ m_hdrDownloadCache->ReleaseAll();
+
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->HeaderFetchCompleted(this);
+}
+
+
+// Use the noop to tell the server we are still here, and therefore we are willing to receive
+// status updates. The recent or exists response from the server could tell us that there is
+// more mail waiting for us, but we need to check the flags of the mail and the high water mark
+// to make sure that we do not tell the user that there is new mail when perhaps they have
+// already read it in another machine.
+
+void nsImapProtocol::PeriodicBiff()
+{
+
+ nsMsgBiffState startingState = m_currentBiffState;
+
+ if (GetServerStateParser().GetIMAPstate() == nsImapServerResponseParser::kFolderSelected)
+ {
+ Noop(); // check the latest number of messages
+ int32_t numMessages = 0;
+ m_flagState->GetNumberOfMessages(&numMessages);
+ if (GetServerStateParser().NumberOfMessages() != numMessages)
+ {
+ uint32_t id = GetServerStateParser().HighestRecordedUID() + 1;
+ nsCString fetchStr; // only update flags
+ uint32_t added = 0, deleted = 0;
+
+ deleted = m_flagState->NumberOfDeletedMessages();
+ added = numMessages;
+ if (!added || (added == deleted)) // empty keys, get them all
+ id = 1;
+
+ //sprintf(fetchStr, "%ld:%ld", id, id + GetServerStateParser().NumberOfMessages() - fFlagState->GetNumberOfMessages());
+ AppendUid(fetchStr, id);
+ fetchStr.Append(":*");
+ FetchMessage(fetchStr, kFlags);
+ if (((uint32_t) m_flagState->GetHighestNonDeletedUID() >= id) && m_flagState->IsLastMessageUnseen())
+ m_currentBiffState = nsIMsgFolder::nsMsgBiffState_NewMail;
+ else
+ m_currentBiffState = nsIMsgFolder::nsMsgBiffState_NoMail;
+ }
+ else
+ m_currentBiffState = nsIMsgFolder::nsMsgBiffState_NoMail;
+ }
+ else
+ m_currentBiffState = nsIMsgFolder::nsMsgBiffState_Unknown;
+
+ if (startingState != m_currentBiffState)
+ SendSetBiffIndicatorEvent(m_currentBiffState);
+}
+
+void nsImapProtocol::SendSetBiffIndicatorEvent(nsMsgBiffState newState)
+{
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->SetBiffStateAndUpdate(newState);
+}
+
+// We get called to see if there is mail waiting for us at the server, even if it may have been
+// read elsewhere. We just want to know if we should download headers or not.
+
+bool nsImapProtocol::CheckNewMail()
+{
+ return m_checkForNewMailDownloadsHeaders;
+}
+
+/* static */ void nsImapProtocol::LogImapUrl(const char *logMsg, nsIImapUrl *imapUrl)
+{
+ // nsImapProtocol is not always constructed before this static method is called
+ if (!IMAP)
+ IMAP = PR_NewLogModule("IMAP");
+
+ if (PR_LOG_TEST(IMAP, PR_LOG_ALWAYS))
+ {
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(imapUrl);
+ if (mailnewsUrl)
+ {
+ nsAutoCString urlSpec, unescapedUrlSpec;
+ mailnewsUrl->GetSpec(urlSpec);
+ MsgUnescapeString(urlSpec, 0, unescapedUrlSpec);
+ PR_LOG(IMAP, PR_LOG_ALWAYS, ("%s:%s", logMsg, unescapedUrlSpec.get()));
+ }
+ }
+}
+
+// log info including current state...
+void nsImapProtocol::Log(const char *logSubName, const char *extraInfo, const char *logData)
+{
+ if (PR_LOG_TEST(IMAP, PR_LOG_ALWAYS))
+ {
+ static const char nonAuthStateName[] = "NA";
+ static const char authStateName[] = "A";
+ static const char selectedStateName[] = "S";
+ const nsCString& hostName = GetImapHostName(); // initilize to empty string
+
+ int32_t logDataLen = PL_strlen(logData); // PL_strlen checks for null
+ nsCString logDataLines;
+ const char *logDataToLog;
+ int32_t lastLineEnd;
+
+ const int kLogDataChunkSize = 400; // nspr line length is 512, and we
+ // allow some space for the log preamble.
+
+ // break up buffers > 400 bytes on line boundaries.
+ if (logDataLen > kLogDataChunkSize)
+ {
+ logDataLines.Assign(logData);
+ lastLineEnd = MsgRFindChar(logDataLines, '\n', kLogDataChunkSize);
+ // null terminate the last line
+ if (lastLineEnd == kNotFound)
+ lastLineEnd = kLogDataChunkSize - 1;
+
+ logDataLines.Insert( '\0', lastLineEnd + 1);
+ logDataToLog = logDataLines.get();
+ }
+ else
+ {
+ logDataToLog = logData;
+ lastLineEnd = logDataLen;
+ }
+ switch (GetServerStateParser().GetIMAPstate())
+ {
+ case nsImapServerResponseParser::kFolderSelected:
+ if (extraInfo)
+ PR_LOG(IMAP, PR_LOG_ALWAYS, ("%x:%s:%s-%s:%s:%s: %.400s", this, hostName.get(),
+ selectedStateName, GetServerStateParser().GetSelectedMailboxName(),
+ logSubName, extraInfo, logDataToLog));
+ else
+ PR_LOG(IMAP, PR_LOG_ALWAYS, ("%x:%s:%s-%s:%s: %.400s", this, hostName.get(),
+ selectedStateName, GetServerStateParser().GetSelectedMailboxName(),
+ logSubName, logDataToLog));
+ break;
+ case nsImapServerResponseParser::kNonAuthenticated:
+ case nsImapServerResponseParser::kAuthenticated:
+ {
+ const char *stateName = (GetServerStateParser().GetIMAPstate() ==
+ nsImapServerResponseParser::kNonAuthenticated)
+ ? nonAuthStateName : authStateName;
+ if (extraInfo)
+ PR_LOG(IMAP, PR_LOG_ALWAYS, ("%x:%s:%s:%s:%s: %.400s", this,
+ hostName.get(),stateName,logSubName,extraInfo,logDataToLog));
+ else
+ PR_LOG(IMAP, PR_LOG_ALWAYS, ("%x:%s:%s:%s: %.400s",this,
+ hostName.get(),stateName,logSubName,logDataToLog));
+ }
+ }
+
+ // dump the rest of the string in < 400 byte chunks
+ while (logDataLen > kLogDataChunkSize)
+ {
+ logDataLines.Cut(0, lastLineEnd + 2); // + 2 to account for the LF and the '\0' we added
+ logDataLen = logDataLines.Length();
+ lastLineEnd = (logDataLen > kLogDataChunkSize) ? MsgRFindChar(logDataLines, '\n', kLogDataChunkSize) : kNotFound;
+ // null terminate the last line
+ if (lastLineEnd == kNotFound)
+ lastLineEnd = kLogDataChunkSize - 1;
+ logDataLines.Insert( '\0', lastLineEnd + 1);
+ logDataToLog = logDataLines.get();
+ PR_LOG(IMAP, PR_LOG_ALWAYS, ("%.400s", logDataToLog));
+ }
+ }
+}
+
+// In 4.5, this posted an event back to libmsg and blocked until it got a response.
+// We may still have to do this.It would be nice if we could preflight this value,
+// but we may not always know when we'll need it.
+uint32_t nsImapProtocol::GetMessageSize(const char * messageId,
+ bool idsAreUids)
+{
+ const char *folderFromParser = GetServerStateParser().GetSelectedMailboxName();
+ if (folderFromParser && messageId)
+ {
+ char *id = (char *)PR_CALLOC(strlen(messageId) + 1);
+ char *folderName;
+ uint32_t size;
+
+ PL_strcpy(id, messageId);
+
+ nsIMAPNamespace *nsForMailbox = nullptr;
+ m_hostSessionList->GetNamespaceForMailboxForHost(GetImapServerKey(), folderFromParser,
+ nsForMailbox);
+
+
+ if (nsForMailbox)
+ m_runningUrl->AllocateCanonicalPath(
+ folderFromParser, nsForMailbox->GetDelimiter(),
+ &folderName);
+ else
+ m_runningUrl->AllocateCanonicalPath(
+ folderFromParser,kOnlineHierarchySeparatorUnknown,
+ &folderName);
+
+ if (id && folderName)
+ {
+ if (m_imapMessageSink)
+ m_imapMessageSink->GetMessageSizeFromDB(id, &size);
+ }
+ PR_FREEIF(id);
+ PR_FREEIF(folderName);
+
+ uint32_t rv = 0;
+ if (!DeathSignalReceived())
+ rv = size;
+ return rv;
+ }
+ return 0;
+}
+
+// message id string utility functions
+/* static */bool nsImapProtocol::HandlingMultipleMessages(const nsCString & messageIdString)
+{
+ return (MsgFindCharInSet(messageIdString, ",:") != kNotFound);
+}
+
+uint32_t nsImapProtocol::CountMessagesInIdString(const char *idString)
+{
+ uint32_t numberOfMessages = 0;
+ char *uidString = PL_strdup(idString);
+
+ if (uidString)
+ {
+ // This is in the form <id>,<id>, or <id1>:<id2>
+ char curChar = *uidString;
+ bool isRange = false;
+ int32_t curToken;
+ int32_t saveStartToken=0;
+
+ for (char *curCharPtr = uidString; curChar && *curCharPtr;)
+ {
+ char *currentKeyToken = curCharPtr;
+ curChar = *curCharPtr;
+ while (curChar != ':' && curChar != ',' && curChar != '\0')
+ curChar = *curCharPtr++;
+ *(curCharPtr - 1) = '\0';
+ curToken = atol(currentKeyToken);
+ if (isRange)
+ {
+ while (saveStartToken < curToken)
+ {
+ numberOfMessages++;
+ saveStartToken++;
+ }
+ }
+
+ numberOfMessages++;
+ isRange = (curChar == ':');
+ if (isRange)
+ saveStartToken = curToken + 1;
+ }
+ PR_Free(uidString);
+ }
+ return numberOfMessages;
+}
+
+
+// It would be really nice not to have to use this method nearly as much as we did
+// in 4.5 - we need to think about this some. Some of it may just go away in the new world order
+bool nsImapProtocol::DeathSignalReceived()
+{
+ // ignore mock channel status if we've been pseudo interrupted
+ // ### need to make sure we clear pseudo interrupted status appropriately.
+ if (!GetPseudoInterrupted() && m_mockChannel)
+ {
+ nsCOMPtr<nsIRequest> request = do_QueryInterface(m_mockChannel);
+ if (request)
+ {
+ nsresult returnValue;
+ request->GetStatus(&returnValue);
+ if (NS_FAILED(returnValue))
+ return false;
+ }
+ }
+
+ // Check the other way of cancelling.
+ ReentrantMonitorAutoEnter threadDeathMon(m_threadDeathMonitor);
+ return m_threadShouldDie;
+}
+
+NS_IMETHODIMP nsImapProtocol::ResetToAuthenticatedState()
+{
+ GetServerStateParser().PreauthSetAuthenticatedState();
+ return NS_OK;
+}
+
+
+NS_IMETHODIMP nsImapProtocol::GetSelectedMailboxName(char ** folderName)
+{
+ if (!folderName) return NS_ERROR_NULL_POINTER;
+ if (GetServerStateParser().GetSelectedMailboxName())
+ *folderName =
+ PL_strdup((GetServerStateParser().GetSelectedMailboxName()));
+ return NS_OK;
+}
+
+bool nsImapProtocol::GetPseudoInterrupted()
+{
+ ReentrantMonitorAutoEnter pseudoInterruptMon(m_pseudoInterruptMonitor);
+ return m_pseudoInterrupted;
+}
+
+void nsImapProtocol::PseudoInterrupt(bool the_interrupt)
+{
+ ReentrantMonitorAutoEnter pseudoInterruptMon(m_pseudoInterruptMonitor);
+ m_pseudoInterrupted = the_interrupt;
+ if (the_interrupt)
+ Log("CONTROL", NULL, "PSEUDO-Interrupted");
+}
+
+void nsImapProtocol::SetActive(bool active)
+{
+ ReentrantMonitorAutoEnter dataMemberMon(m_dataMemberMonitor);
+ m_active = active;
+}
+
+bool nsImapProtocol::GetActive()
+{
+ ReentrantMonitorAutoEnter dataMemberMon(m_dataMemberMonitor);
+ return m_active;
+}
+
+bool nsImapProtocol::GetShowAttachmentsInline()
+{
+ bool showAttachmentsInline = true;
+ if (m_imapServerSink)
+ m_imapServerSink->GetShowAttachmentsInline(&showAttachmentsInline);
+ return showAttachmentsInline;
+
+}
+
+void nsImapProtocol::SetContentModified(IMAP_ContentModifiedType modified)
+{
+ if (m_runningUrl && m_imapMessageSink)
+ m_imapMessageSink->SetContentModified(m_runningUrl, modified);
+}
+
+
+bool nsImapProtocol::GetShouldFetchAllParts()
+{
+ if (m_runningUrl && !DeathSignalReceived())
+ {
+ nsImapContentModifiedType contentModified;
+ if (NS_SUCCEEDED(m_runningUrl->GetContentModified(&contentModified)))
+ return (contentModified == IMAP_CONTENT_FORCE_CONTENT_NOT_MODIFIED);
+ }
+ return true;
+}
+
+// Adds a set of rights for a given user on a given mailbox on the current host.
+// if userName is NULL, it means "me," or MYRIGHTS.
+void nsImapProtocol::AddFolderRightsForUser(const char *mailboxName, const char *userName, const char *rights)
+{
+ if (!userName)
+ userName = "";
+ if (m_imapServerSink)
+ m_imapServerSink->AddFolderRights(nsDependentCString(mailboxName), nsDependentCString(userName),
+ nsDependentCString(rights));
+}
+
+void nsImapProtocol::SetCopyResponseUid(const char *msgIdString)
+{
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->SetCopyResponseUid(msgIdString, m_runningUrl);
+}
+
+void nsImapProtocol::CommitNamespacesForHostEvent()
+{
+ if (m_imapServerSink)
+ m_imapServerSink->CommitNamespaces();
+}
+
+// notifies libmsg that we have new capability data for the current host
+void nsImapProtocol::CommitCapability()
+{
+ if (m_imapServerSink)
+ {
+ m_imapServerSink->SetCapability(GetServerStateParser().GetCapabilityFlag());
+ }
+}
+
+// rights is a single string of rights, as specified by RFC2086, the IMAP ACL extension.
+// Clears all rights for a given folder, for all users.
+void nsImapProtocol::ClearAllFolderRights()
+{
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->ClearFolderRights();
+}
+
+
+char* nsImapProtocol::CreateNewLineFromSocket()
+{
+ bool needMoreData = false;
+ char * newLine = nullptr;
+ uint32_t numBytesInLine = 0;
+ nsresult rv = NS_OK;
+ // we hold a ref to the input stream in case we get cancelled from the
+ // ui thread, which releases our ref to the input stream, and can
+ // cause the pipe to get deleted before the monitor the read is
+ // blocked on gets notified. When that happens, the imap thread
+ // will stay blocked.
+ nsCOMPtr <nsIInputStream> kungFuGrip = m_inputStream;
+ do
+ {
+ newLine = m_inputStreamBuffer->ReadNextLine(m_inputStream, numBytesInLine, needMoreData, &rv);
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("ReadNextLine [stream=%x nb=%u needmore=%u]\n",
+ m_inputStream.get(), numBytesInLine, needMoreData));
+
+ } while (!newLine && NS_SUCCEEDED(rv) && !DeathSignalReceived()); // until we get the next line and haven't been interrupted
+
+ kungFuGrip = nullptr;
+
+ if (NS_FAILED(rv))
+ {
+ switch (rv)
+ {
+ case NS_ERROR_UNKNOWN_HOST:
+ case NS_ERROR_UNKNOWN_PROXY_HOST:
+ AlertUserEventUsingId(IMAP_UNKNOWN_HOST_ERROR);
+ break;
+ case NS_ERROR_CONNECTION_REFUSED:
+ case NS_ERROR_PROXY_CONNECTION_REFUSED:
+ AlertUserEventUsingId(IMAP_CONNECTION_REFUSED_ERROR);
+ break;
+ case NS_ERROR_NET_TIMEOUT:
+ case NS_ERROR_NET_RESET:
+ case NS_BASE_STREAM_CLOSED:
+ case NS_ERROR_NET_INTERRUPT:
+ // we should retry on RESET, especially for SSL...
+ if ((TestFlag(IMAP_RECEIVED_GREETING) || rv == NS_ERROR_NET_RESET) &&
+ m_runningUrl && !m_retryUrlOnError)
+ {
+ bool rerunningUrl;
+ nsImapAction imapAction;
+ m_runningUrl->GetRerunningUrl(&rerunningUrl);
+ m_runningUrl->GetImapAction(&imapAction);
+ // don't rerun if we already were rerunning. And don't rerun
+ // online move/copies that timeout.
+ if (!rerunningUrl && (rv != NS_ERROR_NET_TIMEOUT ||
+ (imapAction != nsIImapUrl::nsImapOnlineCopy &&
+ imapAction != nsIImapUrl::nsImapOnlineMove)))
+ {
+ m_runningUrl->SetRerunningUrl(true);
+ m_retryUrlOnError = true;
+ break;
+ }
+ }
+ if (rv == NS_ERROR_NET_TIMEOUT)
+ AlertUserEventUsingId(IMAP_NET_TIMEOUT_ERROR);
+ else
+ AlertUserEventUsingId(TestFlag(IMAP_RECEIVED_GREETING)
+ ? IMAP_SERVER_DISCONNECTED : IMAP_SERVER_DROPPED_CONNECTION);
+ break;
+ default:
+ break;
+ }
+
+ nsAutoCString logMsg("clearing IMAP_CONNECTION_IS_OPEN - rv = ");
+ logMsg.AppendInt(static_cast<uint32_t>(rv), 16);
+ Log("CreateNewLineFromSocket", nullptr, logMsg.get());
+ ClearFlag(IMAP_CONNECTION_IS_OPEN);
+ TellThreadToDie();
+ }
+ Log("CreateNewLineFromSocket", nullptr, newLine);
+ SetConnectionStatus(newLine && numBytesInLine ? NS_OK : rv); // set > 0 if string is not null or empty
+ return newLine;
+}
+
+nsresult
+nsImapProtocol::GetConnectionStatus()
+{
+ return m_connectionStatus;
+}
+
+void
+nsImapProtocol::SetConnectionStatus(nsresult status)
+{
+ m_connectionStatus = status;
+}
+
+void
+nsImapProtocol::NotifyMessageFlags(imapMessageFlagsType flags,
+ const nsACString &keywords,
+ nsMsgKey key, uint64_t highestModSeq)
+{
+ if (m_imapMessageSink)
+ {
+ // if we're selecting the folder, don't need to report the flags; we've already fetched them.
+ if (m_imapAction != nsIImapUrl::nsImapSelectFolder &&
+ (m_imapAction != nsIImapUrl::nsImapMsgFetch ||
+ (flags & ~kImapMsgRecentFlag) != kImapMsgSeenFlag))
+ m_imapMessageSink->NotifyMessageFlags(flags, keywords, key, highestModSeq);
+ }
+}
+
+void
+nsImapProtocol::NotifySearchHit(const char * hitLine)
+{
+ nsresult rv;
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningUrl, &rv);
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->NotifySearchHit(mailnewsUrl, hitLine);
+}
+
+void nsImapProtocol::SetMailboxDiscoveryStatus(EMailboxDiscoverStatus status)
+{
+ ReentrantMonitorAutoEnter mon(m_dataMemberMonitor);
+ m_discoveryStatus = status;
+}
+
+EMailboxDiscoverStatus nsImapProtocol::GetMailboxDiscoveryStatus( )
+{
+ ReentrantMonitorAutoEnter mon(m_dataMemberMonitor);
+ return m_discoveryStatus;
+}
+
+bool
+nsImapProtocol::GetSubscribingNow()
+{
+ // ***** code me *****
+ return false;// ***** for now
+}
+
+void
+nsImapProtocol::DiscoverMailboxSpec(nsImapMailboxSpec * adoptedBoxSpec)
+{
+ nsIMAPNamespace *ns = nullptr;
+
+ NS_ASSERTION (m_hostSessionList, "fatal null host session list");
+ if (!m_hostSessionList)
+ return;
+
+ m_hostSessionList->GetDefaultNamespaceOfTypeForHost(
+ GetImapServerKey(), kPersonalNamespace, ns);
+ const char *nsPrefix = ns ? ns->GetPrefix() : 0;
+
+ if (m_specialXListMailboxes.Count() > 0)
+ {
+ int32_t hashValue = 0;
+ nsCString strHashKey(adoptedBoxSpec->mAllocatedPathName);
+ m_specialXListMailboxes.Get(strHashKey, &hashValue);
+ adoptedBoxSpec->mBoxFlags |= hashValue;
+ }
+
+ switch (m_hierarchyNameState)
+ {
+ case kXListing:
+ if (adoptedBoxSpec->mBoxFlags &
+ (kImapXListTrash|kImapAllMail|kImapInbox|kImapSent|kImapSpam|kImapDrafts))
+ {
+ nsCString mailboxName(adoptedBoxSpec->mAllocatedPathName);
+ m_specialXListMailboxes.Put(mailboxName, adoptedBoxSpec->mBoxFlags);
+ // Remember hierarchy delimiter in case this is the first time we've
+ // connected to the server and we need it to be correct for the two-level
+ // XLIST we send (INBOX is guaranteed to be in the first response).
+ if (adoptedBoxSpec->mBoxFlags & kImapInbox)
+ m_runningUrl->SetOnlineSubDirSeparator(adoptedBoxSpec->mHierarchySeparator);
+
+ }
+ NS_IF_RELEASE(adoptedBoxSpec);
+ break;
+ case kListingForCreate:
+ case kNoOperationInProgress:
+ case kDiscoverTrashFolderInProgress:
+ case kListingForInfoAndDiscovery:
+ {
+ if (ns && nsPrefix) // if no personal namespace, there can be no Trash folder
+ {
+ bool onlineTrashFolderExists = false;
+ if (m_hostSessionList)
+ {
+ if (adoptedBoxSpec->mBoxFlags & (kImapTrash|kImapXListTrash))
+ {
+ m_hostSessionList->SetOnlineTrashFolderExistsForHost(GetImapServerKey(), true);
+ onlineTrashFolderExists = true;
+ }
+ else
+ {
+ m_hostSessionList->GetOnlineTrashFolderExistsForHost(
+ GetImapServerKey(), onlineTrashFolderExists);
+ }
+ }
+
+ // Don't set the Trash flag if not using the Trash model
+ if (GetDeleteIsMoveToTrash() && !onlineTrashFolderExists &&
+ adoptedBoxSpec->mAllocatedPathName.Find(m_trashFolderName, CaseInsensitiveCompare) != -1)
+ {
+ bool trashExists = false;
+ nsCString trashMatch(CreatePossibleTrashName(nsPrefix));
+ nsCString serverTrashName;
+ m_runningUrl->AllocateCanonicalPath(trashMatch.get(),
+ ns->GetDelimiter(),
+ getter_Copies(serverTrashName));
+ if (StringBeginsWith(serverTrashName,
+ NS_LITERAL_CSTRING("INBOX/"),
+ nsCaseInsensitiveCStringComparator()))
+ {
+ nsAutoCString pathName(adoptedBoxSpec->mAllocatedPathName.get() + 6);
+ trashExists =
+ StringBeginsWith(adoptedBoxSpec->mAllocatedPathName,
+ serverTrashName,
+ nsCaseInsensitiveCStringComparator()) && /* "INBOX/" */
+ pathName.Equals(Substring(serverTrashName, 6), nsCaseInsensitiveCStringComparator());
+ }
+ else
+ trashExists = adoptedBoxSpec->mAllocatedPathName.Equals(serverTrashName, nsCaseInsensitiveCStringComparator());
+
+ if (m_hostSessionList)
+ m_hostSessionList->SetOnlineTrashFolderExistsForHost(GetImapServerKey(), trashExists);
+
+ if (trashExists)
+ adoptedBoxSpec->mBoxFlags |= kImapTrash;
+ }
+ }
+
+ // Discover the folder (shuttle over to libmsg, yay)
+ // Do this only if the folder name is not empty (i.e. the root)
+ if (!adoptedBoxSpec->mAllocatedPathName.IsEmpty())
+ {
+ if (m_hierarchyNameState == kListingForCreate)
+ adoptedBoxSpec->mBoxFlags |= kNewlyCreatedFolder;
+
+ if (m_imapServerSink)
+ {
+ bool newFolder;
+
+ m_imapServerSink->PossibleImapMailbox(adoptedBoxSpec->mAllocatedPathName,
+ adoptedBoxSpec->mHierarchySeparator,
+ adoptedBoxSpec->mBoxFlags, &newFolder);
+ // if it's a new folder to the server sink, setting discovery status to
+ // eContinueNew will cause us to get the ACL for the new folder.
+ if (newFolder)
+ SetMailboxDiscoveryStatus(eContinueNew);
+
+ bool useSubscription = false;
+
+ if (m_hostSessionList)
+ m_hostSessionList->GetHostIsUsingSubscription(GetImapServerKey(),
+ useSubscription);
+
+ if ((GetMailboxDiscoveryStatus() != eContinue) &&
+ (GetMailboxDiscoveryStatus() != eContinueNew) &&
+ (GetMailboxDiscoveryStatus() != eListMyChildren))
+ {
+ SetConnectionStatus(NS_ERROR_FAILURE);
+ }
+ else if (!adoptedBoxSpec->mAllocatedPathName.IsEmpty() &&
+ (GetMailboxDiscoveryStatus() == eListMyChildren) &&
+ (!useSubscription || GetSubscribingNow()))
+ {
+ NS_ASSERTION (false,
+ "we should never get here anymore");
+ SetMailboxDiscoveryStatus(eContinue);
+ }
+ else if (GetMailboxDiscoveryStatus() == eContinueNew)
+ {
+ if (m_hierarchyNameState == kListingForInfoAndDiscovery &&
+ !adoptedBoxSpec->mAllocatedPathName.IsEmpty() &&
+ !(adoptedBoxSpec->mBoxFlags & kNameSpace))
+ {
+ // remember the info here also
+ nsIMAPMailboxInfo *mb = new nsIMAPMailboxInfo(adoptedBoxSpec->mAllocatedPathName, adoptedBoxSpec->mHierarchySeparator);
+ m_listedMailboxList.AppendElement((void*) mb);
+ }
+ SetMailboxDiscoveryStatus(eContinue);
+ }
+ }
+ }
+ }
+ NS_IF_RELEASE( adoptedBoxSpec);
+ break;
+ case kDiscoverBaseFolderInProgress:
+ break;
+ case kDeleteSubFoldersInProgress:
+ {
+ NS_ASSERTION(m_deletableChildren, "Oops .. null m_deletableChildren\n");
+ m_deletableChildren->AppendElement((void *)ToNewCString(adoptedBoxSpec->mAllocatedPathName));
+ NS_IF_RELEASE(adoptedBoxSpec);
+ }
+ break;
+ case kListingForInfoOnly:
+ {
+ //UpdateProgressWindowForUpgrade(adoptedBoxSpec->allocatedPathName);
+ ProgressEventFunctionUsingIdWithString(IMAP_DISCOVERING_MAILBOX,
+ adoptedBoxSpec->mAllocatedPathName.get());
+ nsIMAPMailboxInfo *mb = new nsIMAPMailboxInfo(adoptedBoxSpec->mAllocatedPathName,
+ adoptedBoxSpec->mHierarchySeparator);
+ m_listedMailboxList.AppendElement((void*) mb);
+ NS_IF_RELEASE(adoptedBoxSpec);
+ }
+ break;
+ case kDiscoveringNamespacesOnly:
+ {
+ NS_IF_RELEASE(adoptedBoxSpec);
+ }
+ break;
+ default:
+ NS_ASSERTION (false, "we aren't supposed to be here");
+ break;
+ }
+}
+
+void
+nsImapProtocol::AlertUserEventUsingId(uint32_t aMessageId)
+{
+ if (m_imapServerSink)
+ {
+ bool suppressErrorMsg = false;
+
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningUrl);
+ if (mailnewsUrl)
+ mailnewsUrl->GetSuppressErrorMsgs(&suppressErrorMsg);
+
+ if (!suppressErrorMsg)
+ m_imapServerSink->FEAlertWithID(aMessageId, mailnewsUrl);
+ }
+}
+
+void
+nsImapProtocol::AlertUserEvent(const char * message)
+{
+ if (m_imapServerSink)
+ {
+ bool suppressErrorMsg = false;
+
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningUrl);
+ if (mailnewsUrl)
+ mailnewsUrl->GetSuppressErrorMsgs(&suppressErrorMsg);
+
+ if (!suppressErrorMsg)
+ m_imapServerSink->FEAlert(NS_ConvertASCIItoUTF16(message), mailnewsUrl);
+ }
+}
+
+void
+nsImapProtocol::AlertUserEventFromServer(const char * aServerEvent)
+{
+ if (m_imapServerSink && aServerEvent)
+ {
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningUrl);
+ m_imapServerSink->FEAlertFromServer(nsDependentCString(aServerEvent),
+ mailnewsUrl);
+ }
+}
+
+void nsImapProtocol::ResetProgressInfo()
+{
+ m_lastProgressTime = 0;
+ m_lastPercent = -1;
+ m_lastProgressStringId = (uint32_t) -1;
+}
+
+void nsImapProtocol::SetProgressString(int32_t stringId)
+{
+ m_progressStringId = stringId;
+ if (m_progressStringId && m_imapServerSink)
+ m_imapServerSink->GetImapStringByID(stringId, m_progressString);
+}
+
+void
+nsImapProtocol::ShowProgress()
+{
+ if (!m_progressString.IsEmpty() && m_progressStringId)
+ {
+ PRUnichar *progressString = NULL;
+ const char *mailboxName = GetServerStateParser().GetSelectedMailboxName();
+ nsString unicodeMailboxName;
+ nsresult rv = CopyMUTF7toUTF16(nsDependentCString(mailboxName),
+ unicodeMailboxName);
+ if (NS_SUCCEEDED(rv))
+ {
+ // ### should convert mailboxName to PRUnichar and change %s to %S in msg text
+ progressString = nsTextFormatter::smprintf(m_progressString.get(),
+ unicodeMailboxName.get(), ++m_progressIndex, m_progressCount);
+ if (progressString)
+ {
+ PercentProgressUpdateEvent(progressString, m_progressIndex, m_progressCount);
+ nsTextFormatter::smprintf_free(progressString);
+ }
+ }
+ }
+}
+
+void
+nsImapProtocol::ProgressEventFunctionUsingId(uint32_t aMsgId)
+{
+ if (m_imapMailFolderSink && aMsgId != m_lastProgressStringId)
+ {
+ m_imapMailFolderSink->ProgressStatus(this, aMsgId, nullptr);
+ m_lastProgressStringId = aMsgId;
+ // who's going to free this? Does ProgressStatus complete synchronously?
+ }
+}
+
+void
+nsImapProtocol::ProgressEventFunctionUsingIdWithString(uint32_t aMsgId, const
+ char * aExtraInfo)
+{
+ if (m_imapMailFolderSink)
+ {
+ nsString unicodeStr;
+ nsresult rv = CopyMUTF7toUTF16(nsDependentCString(aExtraInfo), unicodeStr);
+ if (NS_SUCCEEDED(rv))
+ m_imapMailFolderSink->ProgressStatus(this, aMsgId, unicodeStr.get());
+ }
+}
+
+void
+nsImapProtocol::PercentProgressUpdateEvent(PRUnichar *message, int64_t currentProgress, int64_t maxProgress)
+{
+ int64_t nowMS = 0;
+ int32_t percent = (100 * currentProgress) / maxProgress;
+ if (percent == m_lastPercent)
+ return; // hasn't changed, right? So just return. Do we need to clear this anywhere?
+
+ if (percent < 100) // always need to do 100%
+ {
+ nowMS = PR_IntervalToMilliseconds(PR_IntervalNow());
+ if (nowMS - m_lastProgressTime < 750)
+ return;
+ }
+
+ m_lastPercent = percent;
+ m_lastProgressTime = nowMS;
+
+ // set our max progress on the running URL
+ if (m_runningUrl)
+ {
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl(do_QueryInterface(m_runningUrl));
+ mailnewsUrl->SetMaxProgress(maxProgress);
+ }
+
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->PercentProgress(this, message, currentProgress, maxProgress);
+}
+
+ // imap commands issued by the parser
+void
+nsImapProtocol::Store(const nsCString &messageList, const char * messageData,
+ bool idsAreUid)
+{
+
+ // turn messageList back into key array and then back into a message id list,
+ // but use the flag state to handle ranges correctly.
+ nsCString messageIdList;
+ nsTArray<nsMsgKey> msgKeys;
+ if (idsAreUid)
+ ParseUidString(messageList.get(), msgKeys);
+
+ int32_t msgCountLeft = msgKeys.Length();
+ uint32_t msgsHandled = 0;
+ do
+ {
+ nsCString idString;
+
+ uint32_t msgsToHandle = msgCountLeft;
+ if (idsAreUid)
+ AllocateImapUidString(msgKeys.Elements() + msgsHandled, msgsToHandle, m_flagState, idString); // 20 * 200
+ else
+ idString.Assign(messageList);
+
+
+ msgsHandled += msgsToHandle;
+ msgCountLeft -= msgsToHandle;
+
+ IncrementCommandTagNumber();
+ const char *formatString;
+ if (idsAreUid)
+ formatString = "%s uid store %s %s\015\012";
+ else
+ formatString = "%s store %s %s\015\012";
+
+ // we might need to close this mailbox after this
+ m_closeNeededBeforeSelect = GetDeleteIsMoveToTrash() &&
+ (PL_strcasestr(messageData, "\\Deleted"));
+
+ const char *commandTag = GetServerCommandTag();
+ int protocolStringSize = PL_strlen(formatString) +
+ messageList.Length() + PL_strlen(messageData) +
+ PL_strlen(commandTag) + 1;
+ char *protocolString = (char *) PR_CALLOC( protocolStringSize );
+
+ if (protocolString)
+ {
+ PR_snprintf(protocolString, // string to create
+ protocolStringSize, // max size
+ formatString, // format string
+ commandTag, // command tag
+ idString.get(),
+ messageData);
+
+ nsresult rv = SendData(protocolString);
+ if (NS_SUCCEEDED(rv))
+ {
+ m_flagChangeCount++;
+ ParseIMAPandCheckForNewMail(protocolString);
+ if (GetServerStateParser().LastCommandSuccessful() && CheckNeeded())
+ Check();
+ }
+ PR_Free(protocolString);
+ }
+ else
+ HandleMemoryFailure();
+ }
+ while (msgCountLeft > 0 && !DeathSignalReceived());
+
+}
+
+void
+nsImapProtocol::IssueUserDefinedMsgCommand(const char *command, const char * messageList)
+{
+ IncrementCommandTagNumber();
+
+ const char *formatString;
+ formatString = "%s uid %s %s\015\012";
+
+ const char *commandTag = GetServerCommandTag();
+ int protocolStringSize = PL_strlen(formatString) +
+ PL_strlen(messageList) + PL_strlen(command) +
+ PL_strlen(commandTag) + 1;
+ char *protocolString = (char *) PR_CALLOC( protocolStringSize );
+
+ if (protocolString)
+ {
+ PR_snprintf(protocolString, // string to create
+ protocolStringSize, // max size
+ formatString, // format string
+ commandTag, // command tag
+ command,
+ messageList);
+
+ nsresult rv = SendData(protocolString);
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail(protocolString);
+ PR_Free(protocolString);
+ }
+ else
+ HandleMemoryFailure();
+}
+
+void
+nsImapProtocol::UidExpunge(const nsCString &messageSet)
+{
+ IncrementCommandTagNumber();
+ nsCString command(GetServerCommandTag());
+ command.Append(" uid expunge ");
+ command.Append(messageSet);
+ command.Append(CRLF);
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void
+nsImapProtocol::Expunge()
+{
+ uint32_t aclFlags = 0;
+ if (GetServerStateParser().ServerHasACLCapability() && m_imapMailFolderSink)
+ m_imapMailFolderSink->GetAclFlags(&aclFlags);
+
+ if (aclFlags && !(aclFlags & IMAP_ACL_EXPUNGE_FLAG))
+ return;
+ ProgressEventFunctionUsingId (IMAP_STATUS_EXPUNGING_MAILBOX);
+
+ if(gCheckDeletedBeforeExpunge)
+ {
+ GetServerStateParser().ResetSearchResultSequence();
+ Search("SEARCH DELETED", false, false);
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ nsImapSearchResultIterator *search = GetServerStateParser().CreateSearchResultIterator();
+ nsMsgKey key = search->GetNextMessageNumber();
+ delete search;
+ if (key == 0)
+ return; //no deleted messages to expunge (bug 235004)
+ }
+ }
+
+ IncrementCommandTagNumber();
+ nsAutoCString command(GetServerCommandTag());
+ command.Append(" expunge" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void
+nsImapProtocol::HandleMemoryFailure()
+{
+ PR_CEnterMonitor(this);
+ // **** jefft fix me!!!!!! ******
+ // m_imapThreadIsRunning = false;
+ // SetConnectionStatus(-1);
+ PR_CExitMonitor(this);
+}
+
+void nsImapProtocol::HandleCurrentUrlError()
+{
+ // This is to handle a move/copy failing, especially because the user
+ // cancelled the password prompt.
+ (void) m_runningUrl->GetImapAction(&m_imapAction);
+ if (m_imapAction == nsIImapUrl::nsImapOfflineToOnlineMove || m_imapAction == nsIImapUrl::nsImapAppendMsgFromFile
+ || m_imapAction == nsIImapUrl::nsImapAppendDraftFromFile)
+ {
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->OnlineCopyCompleted(this, ImapOnlineCopyStateType::kFailedCopy);
+ }
+}
+
+void nsImapProtocol::StartTLS()
+{
+ IncrementCommandTagNumber();
+ nsCString command(GetServerCommandTag());
+
+ command.Append(" STARTTLS" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::Capability()
+{
+
+ ProgressEventFunctionUsingId (IMAP_STATUS_CHECK_COMPAT);
+ IncrementCommandTagNumber();
+ nsCString command(GetServerCommandTag());
+
+ command.Append(" capability" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+ if (!gUseLiteralPlus)
+ {
+ eIMAPCapabilityFlags capabilityFlag = GetServerStateParser().GetCapabilityFlag();
+ if (capabilityFlag & kLiteralPlusCapability)
+ {
+ GetServerStateParser().SetCapabilityFlag(capabilityFlag & ~kLiteralPlusCapability);
+ }
+ }
+}
+
+void nsImapProtocol::ID()
+{
+ if (!gAppName[0])
+ return;
+ IncrementCommandTagNumber();
+ nsCString command(GetServerCommandTag());
+ command.Append(" ID (\"name\" \"");
+ command.Append(gAppName);
+ command.Append("\" \"version\" \"");
+ command.Append(gAppVersion);
+ command.Append("\")" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::EnableCondStore()
+{
+ IncrementCommandTagNumber();
+ nsCString command(GetServerCommandTag());
+
+ command.Append(" ENABLE CONDSTORE" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::StartCompressDeflate()
+{
+ // only issue a compression request if we haven't already
+ if (!TestFlag(IMAP_ISSUED_COMPRESS_REQUEST))
+ {
+ SetFlag(IMAP_ISSUED_COMPRESS_REQUEST);
+ IncrementCommandTagNumber();
+ nsCString command(GetServerCommandTag());
+
+ command.Append(" COMPRESS DEFLATE" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ {
+ ParseIMAPandCheckForNewMail();
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ rv = BeginCompressing();
+ if (NS_FAILED(rv))
+ {
+ Log("CompressDeflate", nullptr, "failed to enable compression");
+ // we can't use this connection without compression any more, so die
+ ClearFlag(IMAP_CONNECTION_IS_OPEN);
+ TellThreadToDie();
+ SetConnectionStatus(rv);
+ return;
+ }
+ }
+ }
+ }
+}
+
+nsresult nsImapProtocol::BeginCompressing()
+{
+ // wrap the streams in compression layers that compress or decompress
+ // all traffic.
+ nsRefPtr<nsMsgCompressIStream> new_in = new nsMsgCompressIStream();
+ if (!new_in)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ nsresult rv = new_in->InitInputStream(m_inputStream);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ m_inputStream = new_in;
+
+ nsRefPtr<nsMsgCompressOStream> new_out = new nsMsgCompressOStream();
+ if (!new_out)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ rv = new_out->InitOutputStream(m_outputStream);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ m_outputStream = new_out;
+ return rv;
+}
+
+void nsImapProtocol::Language()
+{
+ // only issue the language request if we haven't done so already...
+ if (!TestFlag(IMAP_ISSUED_LANGUAGE_REQUEST))
+ {
+ SetFlag(IMAP_ISSUED_LANGUAGE_REQUEST);
+ ProgressEventFunctionUsingId (IMAP_STATUS_CHECK_COMPAT);
+ IncrementCommandTagNumber();
+ nsCString command(GetServerCommandTag());
+
+ // extract the desired language attribute from prefs
+ nsresult rv = NS_OK;
+
+ // we need to parse out the first language out of this comma separated list....
+ // i.e if we have en,ja we only want to send en to the server.
+ if (mAcceptLanguages.get())
+ {
+ nsAutoCString extractedLanguage;
+ LossyCopyUTF16toASCII(mAcceptLanguages, extractedLanguage);
+ int32_t pos = extractedLanguage.FindChar(',');
+ if (pos > 0) // we have a comma separated list of languages...
+ extractedLanguage.SetLength(pos); // truncate everything after the first comma (including the comma)
+
+ if (extractedLanguage.IsEmpty())
+ return;
+
+ command.Append(" LANGUAGE ");
+ command.Append(extractedLanguage);
+ command.Append(CRLF);
+
+ rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail(nullptr, true /* ignore bad or no result from the server for this command */);
+ }
+ }
+}
+
+void nsImapProtocol::EscapeUserNamePasswordString(const char *strToEscape, nsCString *resultStr)
+{
+ if (strToEscape)
+ {
+ uint32_t i = 0;
+ uint32_t escapeStrlen = strlen(strToEscape);
+ for (i=0; i<escapeStrlen; i++)
+ {
+ if (strToEscape[i] == '\\' || strToEscape[i] == '\"')
+ {
+ resultStr->Append('\\');
+ }
+ resultStr->Append(strToEscape[i]);
+ }
+ }
+}
+
+void nsImapProtocol::InitPrefAuthMethods(int32_t authMethodPrefValue)
+{
+ // for m_prefAuthMethods, using the same flags as server capablities.
+ switch (authMethodPrefValue)
+ {
+ case nsMsgAuthMethod::none:
+ m_prefAuthMethods = kHasAuthNoneCapability;
+ break;
+ case nsMsgAuthMethod::old:
+ m_prefAuthMethods = kHasAuthOldLoginCapability;
+ break;
+ case nsMsgAuthMethod::passwordCleartext:
+ m_prefAuthMethods = kHasAuthOldLoginCapability |
+ kHasAuthLoginCapability | kHasAuthPlainCapability;
+ break;
+ case nsMsgAuthMethod::passwordEncrypted:
+ m_prefAuthMethods = kHasCRAMCapability;
+ break;
+ case nsMsgAuthMethod::NTLM:
+ m_prefAuthMethods = kHasAuthNTLMCapability | kHasAuthMSNCapability;
+ break;
+ case nsMsgAuthMethod::GSSAPI:
+ m_prefAuthMethods = kHasAuthGssApiCapability;
+ break;
+ case nsMsgAuthMethod::External:
+ m_prefAuthMethods = kHasAuthExternalCapability;
+ break;
+ case nsMsgAuthMethod::secure:
+ m_prefAuthMethods = kHasCRAMCapability |
+ kHasAuthGssApiCapability |
+ kHasAuthNTLMCapability | kHasAuthMSNCapability;
+ break;
+ default:
+ NS_ASSERTION(false, "IMAP: authMethod pref invalid");
+ // TODO log to error console
+ PR_LOG(IMAP, PR_LOG_ERROR,
+ ("IMAP: bad pref authMethod = %d\n", authMethodPrefValue));
+ // fall to any
+ case nsMsgAuthMethod::anything:
+ m_prefAuthMethods = kHasAuthOldLoginCapability |
+ kHasAuthLoginCapability | kHasAuthPlainCapability |
+ kHasCRAMCapability | kHasAuthGssApiCapability |
+ kHasAuthNTLMCapability | kHasAuthMSNCapability |
+ kHasAuthExternalCapability;
+ break;
+ }
+ NS_ASSERTION(m_prefAuthMethods != kCapabilityUndefined,
+ "IMAP: InitPrefAuthMethods() didn't work");
+}
+
+/**
+ * Changes m_currentAuthMethod to pick the best remaining one
+ * which is allowed by server and prefs and not marked failed.
+ * The order of preference and trying of auth methods is encoded here.
+ */
+nsresult nsImapProtocol::ChooseAuthMethod()
+{
+ eIMAPCapabilityFlags serverCaps = GetServerStateParser().GetCapabilityFlag();
+ eIMAPCapabilityFlags availCaps = serverCaps & m_prefAuthMethods & ~m_failedAuthMethods;
+
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("IMAP auth: server caps 0x%X, pref 0x%X, failed 0x%X, avail caps 0x%X",
+ serverCaps, m_prefAuthMethods, m_failedAuthMethods, availCaps));
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("(GSSAPI = 0x%X, CRAM = 0x%X, NTLM = 0x%X, "
+ "MSN = 0x%X, PLAIN = 0x%X, LOGIN = 0x%X, old-style IMAP login = 0x%X)"
+ "auth external IMAP login = 0x%X",
+ kHasAuthGssApiCapability, kHasCRAMCapability, kHasAuthNTLMCapability,
+ kHasAuthMSNCapability, kHasAuthPlainCapability, kHasAuthLoginCapability,
+ kHasAuthOldLoginCapability, kHasAuthExternalCapability));
+
+ if (kHasAuthExternalCapability & availCaps)
+ m_currentAuthMethod = kHasAuthExternalCapability;
+ else if (kHasAuthGssApiCapability & availCaps)
+ m_currentAuthMethod = kHasAuthGssApiCapability;
+ else if (kHasCRAMCapability & availCaps)
+ m_currentAuthMethod = kHasCRAMCapability;
+ else if (kHasAuthNTLMCapability & availCaps)
+ m_currentAuthMethod = kHasAuthNTLMCapability;
+ else if (kHasAuthMSNCapability & availCaps)
+ m_currentAuthMethod = kHasAuthMSNCapability;
+ else if (kHasAuthPlainCapability & availCaps)
+ m_currentAuthMethod = kHasAuthPlainCapability;
+ else if (kHasAuthLoginCapability & availCaps)
+ m_currentAuthMethod = kHasAuthLoginCapability;
+ else if (kHasAuthOldLoginCapability & availCaps)
+ m_currentAuthMethod = kHasAuthOldLoginCapability;
+ else
+ {
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("no remaining auth method"));
+ m_currentAuthMethod = kCapabilityUndefined;
+ return NS_ERROR_FAILURE;
+ }
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("trying auth method 0x%X", m_currentAuthMethod));
+ return NS_OK;
+}
+
+void nsImapProtocol::MarkAuthMethodAsFailed(eIMAPCapabilityFlags failedAuthMethod)
+{
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("marking auth method 0x%X failed", failedAuthMethod));
+ m_failedAuthMethods |= failedAuthMethod;
+}
+
+/**
+ * Start over, trying all auth methods again
+ */
+void nsImapProtocol::ResetAuthMethods()
+{
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("resetting (failed) auth methods"));
+ m_currentAuthMethod = kCapabilityUndefined;
+ m_failedAuthMethods = 0;
+}
+
+nsresult nsImapProtocol::AuthLogin(const char *userName, const nsCString &password, eIMAPCapabilityFlag flag)
+{
+ ProgressEventFunctionUsingId (IMAP_STATUS_SENDING_AUTH_LOGIN);
+ IncrementCommandTagNumber();
+
+ char * currentCommand=nullptr;
+ nsresult rv;
+
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("IMAP: trying auth method 0x%X", m_currentAuthMethod));
+
+ if (flag & kHasAuthExternalCapability)
+ {
+ char *base64UserName = PL_Base64Encode(userName, strlen(userName), nullptr);
+ nsAutoCString command (GetServerCommandTag());
+ command.Append(" authenticate EXTERNAL =" );
+ // rfc4422 use external with empty authorization identity - command.Append(base64UserName);
+ command.Append(CRLF);
+ PR_Free(base64UserName);
+ rv = SendData(command.get());
+ ParseIMAPandCheckForNewMail();
+ nsImapServerResponseParser &parser = GetServerStateParser();
+ if (parser.LastCommandSuccessful())
+ return NS_OK;
+ parser.SetCapabilityFlag(parser.GetCapabilityFlag() & ~kHasAuthExternalCapability);
+ }
+ else if (flag & kHasCRAMCapability)
+ {
+ NS_ENSURE_TRUE(m_imapServerSink, NS_ERROR_NULL_POINTER);
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("MD5 auth"));
+ // inform the server that we want to begin a CRAM authentication procedure...
+ nsAutoCString command (GetServerCommandTag());
+ command.Append(" authenticate CRAM-MD5" CRLF);
+ rv = SendData(command.get());
+ NS_ENSURE_SUCCESS(rv, rv);
+ ParseIMAPandCheckForNewMail();
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ char *digest = nullptr;
+ char *cramDigest = GetServerStateParser().fAuthChallenge;
+ char *decodedChallenge = PL_Base64Decode(cramDigest,
+ strlen(cramDigest), nullptr);
+ rv = m_imapServerSink->CramMD5Hash(decodedChallenge, password.get(), &digest);
+ PR_Free(decodedChallenge);
+ NS_ENSURE_SUCCESS(rv, rv);
+ NS_ENSURE_TRUE(digest, NS_ERROR_NULL_POINTER);
+ nsAutoCString encodedDigest;
+ char hexVal[8];
+
+ for (uint32_t j=0; j<16; j++)
+ {
+ PR_snprintf (hexVal,8, "%.2x", 0x0ff & (unsigned short)(digest[j]));
+ encodedDigest.Append(hexVal);
+ }
+
+ PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE, "%s %s", userName, encodedDigest.get());
+ char *base64Str = PL_Base64Encode(m_dataOutputBuf, strlen(m_dataOutputBuf), nullptr);
+ PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE, "%s" CRLF, base64Str);
+ PR_Free(base64Str);
+ PR_Free(digest);
+ rv = SendData(m_dataOutputBuf);
+ NS_ENSURE_SUCCESS(rv, rv);
+ ParseIMAPandCheckForNewMail(command.get());
+ }
+ } // if CRAM response was received
+ else if (flag & kHasAuthGssApiCapability)
+ {
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("MD5 auth"));
+
+ // Only try GSSAPI once - if it fails, its going to be because we don't
+ // have valid credentials
+ //MarkAuthMethodAsFailed(kHasAuthGssApiCapability);
+
+ // We do step1 first, so we don't try GSSAPI against a server which
+ // we can't get credentials for.
+ nsAutoCString response;
+
+ nsAutoCString service("imap@");
+ service.Append(m_realHostName);
+ rv = DoGSSAPIStep1(service.get(), userName, response);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsAutoCString command (GetServerCommandTag());
+ command.Append(" authenticate GSSAPI" CRLF);
+ rv = SendData(command.get());
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ ParseIMAPandCheckForNewMail("AUTH GSSAPI");
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ response += CRLF;
+ rv = SendData(response.get());
+ NS_ENSURE_SUCCESS(rv, rv);
+ ParseIMAPandCheckForNewMail(command.get());
+ nsresult gssrv = NS_OK;
+
+ while (GetServerStateParser().LastCommandSuccessful() &&
+ NS_SUCCEEDED(gssrv) && gssrv != NS_SUCCESS_AUTH_FINISHED)
+ {
+ nsCString challengeStr(GetServerStateParser().fAuthChallenge);
+ gssrv = DoGSSAPIStep2(challengeStr, response);
+ if (NS_SUCCEEDED(gssrv))
+ {
+ response += CRLF;
+ rv = SendData(response.get());
+ }
+ else
+ rv = SendData("*" CRLF);
+
+ NS_ENSURE_SUCCESS(rv, rv);
+ ParseIMAPandCheckForNewMail(command.get());
+ }
+ // TODO: whether it worked or not is shown by LastCommandSuccessful(), not gssrv, right?
+ }
+ }
+ else if (flag & (kHasAuthNTLMCapability | kHasAuthMSNCapability))
+ {
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("NTLM auth"));
+ nsAutoCString command (GetServerCommandTag());
+ command.Append((flag & kHasAuthNTLMCapability) ? " authenticate NTLM" CRLF
+ : " authenticate MSN" CRLF);
+ rv = SendData(command.get());
+ ParseIMAPandCheckForNewMail("AUTH NTLM"); // this just waits for ntlm step 1
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ nsAutoCString cmd;
+ rv = DoNtlmStep1(userName, password.get(), cmd);
+ NS_ENSURE_SUCCESS(rv, rv);
+ cmd += CRLF;
+ rv = SendData(cmd.get());
+ NS_ENSURE_SUCCESS(rv, rv);
+ ParseIMAPandCheckForNewMail(command.get());
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ nsCString challengeStr(GetServerStateParser().fAuthChallenge);
+ nsCString response;
+ rv = DoNtlmStep2(challengeStr, response);
+ NS_ENSURE_SUCCESS(rv, rv);
+ response += CRLF;
+ rv = SendData(response.get());
+ ParseIMAPandCheckForNewMail(command.get());
+ }
+ }
+ }
+ else if (flag & kHasAuthPlainCapability)
+ {
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("PLAIN auth"));
+ PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE, "%s authenticate plain" CRLF, GetServerCommandTag());
+ rv = SendData(m_dataOutputBuf);
+ NS_ENSURE_SUCCESS(rv, rv);
+ currentCommand = PL_strdup(m_dataOutputBuf); /* StrAllocCopy(currentCommand, GetOutputBuffer()); */
+ ParseIMAPandCheckForNewMail();
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ // RFC 4616
+ char plainstr[512]; // placeholder for "<NUL>userName<NUL>password" TODO nsAutoCString
+ int len = 1; // count for first <NUL> char
+ memset(plainstr, 0, 512);
+ PR_snprintf(&plainstr[1], 510, "%s", userName);
+ len += PL_strlen(userName);
+ len++; // count for second <NUL> char
+ PR_snprintf(&plainstr[len], 511-len, "%s", password.get());
+ len += password.Length();
+ char *base64Str = PL_Base64Encode(plainstr, len, nullptr);
+ PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE, "%s" CRLF, base64Str);
+ PR_Free(base64Str);
+ rv = SendData(m_dataOutputBuf, true /* suppress logging */);
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail(currentCommand);
+ } // if the last command succeeded
+ } // if auth plain capability
+ else if (flag & kHasAuthLoginCapability)
+ {
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("LOGIN auth"));
+ PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE, "%s authenticate login" CRLF, GetServerCommandTag());
+ rv = SendData(m_dataOutputBuf);
+ NS_ENSURE_SUCCESS(rv, rv);
+ currentCommand = PL_strdup(m_dataOutputBuf);
+ ParseIMAPandCheckForNewMail();
+
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ char *base64Str = PL_Base64Encode(userName, PL_strlen(userName), nullptr);
+ PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE, "%s" CRLF, base64Str);
+ PR_Free(base64Str);
+ rv = SendData(m_dataOutputBuf, true /* suppress logging */);
+ if (NS_SUCCEEDED(rv))
+ {
+ ParseIMAPandCheckForNewMail(currentCommand);
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ base64Str = PL_Base64Encode(password.get(), password.Length(), nullptr);
+ PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE, "%s" CRLF, base64Str);
+ PR_Free(base64Str);
+ rv = SendData(m_dataOutputBuf, true /* suppress logging */);
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail(currentCommand);
+ } // if last command successful
+ } // if last command successful
+ } // if last command successful
+ } // if has auth login capability
+ else if (flag & kHasAuthOldLoginCapability)
+ {
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("old-style auth"));
+ ProgressEventFunctionUsingId (IMAP_STATUS_SENDING_LOGIN);
+ IncrementCommandTagNumber();
+ nsCString command (GetServerCommandTag());
+ nsAutoCString escapedUserName;
+ command.Append(" login \"");
+ EscapeUserNamePasswordString(userName, &escapedUserName);
+ command.Append(escapedUserName);
+ command.Append("\" \"");
+
+ // if the password contains a \, login will fail
+ // turn foo\bar into foo\\bar
+ nsAutoCString correctedPassword;
+ EscapeUserNamePasswordString(password.get(), &correctedPassword);
+ command.Append(correctedPassword);
+ command.Append("\"" CRLF);
+ rv = SendData(command.get(), true /* suppress logging */);
+ NS_ENSURE_SUCCESS(rv, rv);
+ ParseIMAPandCheckForNewMail();
+ }
+ else if (flag & kHasAuthNoneCapability)
+ {
+ // TODO What to do? "login <username>" like POP?
+ return NS_ERROR_NOT_IMPLEMENTED;
+ }
+ else
+ {
+ PR_LOG(IMAP, PR_LOG_ERROR, ("flags param has no auth scheme selected"));
+ return NS_ERROR_ILLEGAL_VALUE;
+ }
+
+ PR_Free(currentCommand);
+ NS_ENSURE_SUCCESS(rv, rv);
+ return GetServerStateParser().LastCommandSuccessful() ?
+ NS_OK : NS_ERROR_FAILURE;
+}
+
+void nsImapProtocol::OnLSubFolders()
+{
+ // **** use to find out whether Drafts, Sent, & Templates folder
+ // exists or not even the user didn't subscribe to it
+ char *mailboxName = OnCreateServerSourceFolderPathString();
+ if (mailboxName)
+ {
+ ProgressEventFunctionUsingId(IMAP_STATUS_LOOKING_FOR_MAILBOX);
+ IncrementCommandTagNumber();
+ PR_snprintf(m_dataOutputBuf, OUTPUT_BUFFER_SIZE,"%s list \"\" \"%s\"" CRLF, GetServerCommandTag(), mailboxName);
+ nsresult rv = SendData(m_dataOutputBuf);
+#ifdef UNREADY_CODE
+ TimeStampListNow();
+#endif
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+ PR_Free(mailboxName);
+ }
+ else
+ {
+ HandleMemoryFailure();
+ }
+
+}
+
+void nsImapProtocol::OnAppendMsgFromFile()
+{
+ nsCOMPtr<nsIFile> file;
+ nsresult rv = NS_OK;
+ rv = m_runningUrl->GetMsgFile(getter_AddRefs(file));
+ if (NS_SUCCEEDED(rv) && file)
+ {
+ char *mailboxName = OnCreateServerSourceFolderPathString();
+ if (mailboxName)
+ {
+ imapMessageFlagsType flagsToSet = 0;
+ uint32_t msgFlags = 0;
+ PRTime date = 0;
+ nsCString keywords;
+ if (m_imapMessageSink)
+ m_imapMessageSink->GetCurMoveCopyMessageInfo(m_runningUrl, &date,
+ keywords, &msgFlags);
+
+ if (msgFlags & nsMsgMessageFlags::Read)
+ flagsToSet |= kImapMsgSeenFlag;
+ if (msgFlags & nsMsgMessageFlags::MDNReportSent)
+ flagsToSet |= kImapMsgMDNSentFlag;
+ // convert msg flag label (0xE000000) to imap flag label (0x0E00)
+ if (msgFlags & nsMsgMessageFlags::Labels)
+ flagsToSet |= (msgFlags & nsMsgMessageFlags::Labels) >> 16;
+ if (msgFlags & nsMsgMessageFlags::Marked)
+ flagsToSet |= kImapMsgFlaggedFlag;
+ if (msgFlags & nsMsgMessageFlags::Replied)
+ flagsToSet |= kImapMsgAnsweredFlag;
+ if (msgFlags & nsMsgMessageFlags::Forwarded)
+ flagsToSet |= kImapMsgForwardedFlag;
+
+ // If the message copied was a draft, flag it as such
+ nsImapAction imapAction;
+ rv = m_runningUrl->GetImapAction(&imapAction);
+ if (NS_SUCCEEDED(rv) && (imapAction == nsIImapUrl::nsImapAppendDraftFromFile))
+ flagsToSet |= kImapMsgDraftFlag;
+ UploadMessageFromFile(file, mailboxName, date, flagsToSet, keywords);
+ PR_Free( mailboxName );
+ }
+ else
+ {
+ HandleMemoryFailure();
+ }
+ }
+}
+
+void nsImapProtocol::UploadMessageFromFile (nsIFile* file,
+ const char* mailboxName,
+ PRTime date,
+ imapMessageFlagsType flags,
+ nsCString &keywords)
+{
+ if (!file || !mailboxName) return;
+ IncrementCommandTagNumber();
+
+ int64_t fileSize = 0;
+ int64_t totalSize;
+ uint32_t readCount;
+ char *dataBuffer = nullptr;
+ nsCString command(GetServerCommandTag());
+ nsCString escapedName;
+ CreateEscapedMailboxName(mailboxName, escapedName);
+ nsresult rv;
+ bool eof = false;
+ nsCString flagString;
+ bool hasLiteralPlus = (GetServerStateParser().GetCapabilityFlag() &
+ kLiteralPlusCapability);
+
+ nsCOMPtr <nsIInputStream> fileInputStream;
+
+ if (!escapedName.IsEmpty())
+ {
+ command.Append(" append \"");
+ command.Append(escapedName);
+ command.Append("\"");
+ if (flags || keywords.Length())
+ {
+ command.Append(" (");
+
+ if (flags)
+ {
+ SetupMessageFlagsString(flagString, flags,
+ GetServerStateParser().SupportsUserFlags());
+ command.Append(flagString);
+ }
+ if (keywords.Length())
+ {
+ if (flags)
+ command.Append(' ');
+ command.Append(keywords);
+ }
+ command.Append(")");
+ }
+
+ // date should never be 0, but just in case...
+ if (date)
+ {
+ /* Use PR_FormatTimeUSEnglish() to format the date in US English format,
+ then figure out what our local GMT offset is, and append it (since
+ PR_FormatTimeUSEnglish() can't do that.) Generate four digit years as
+ per RFC 1123 (superceding RFC 822.)
+ */
+ char szDateTime[64];
+ char dateStr[100];
+ PRExplodedTime exploded;
+ PR_ExplodeTime(date, PR_LocalTimeParameters, &exploded);
+ PR_FormatTimeUSEnglish(szDateTime, sizeof(szDateTime), "%d-%b-%Y %H:%M:%S", &exploded);
+ PRExplodedTime now;
+ PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &now);
+ int gmtoffset = (now.tm_params.tp_gmt_offset + now.tm_params.tp_dst_offset) / 60;
+ PR_snprintf(dateStr, sizeof(dateStr),
+ " \"%s %c%02d%02d\"",
+ szDateTime,
+ (gmtoffset >= 0 ? '+' : '-'),
+ ((gmtoffset >= 0 ? gmtoffset : -gmtoffset) / 60),
+ ((gmtoffset >= 0 ? gmtoffset : -gmtoffset) % 60));
+
+ command.Append(dateStr);
+ }
+ command.Append(" {");
+
+ dataBuffer = (char*) PR_CALLOC(COPY_BUFFER_SIZE+1);
+ if (!dataBuffer) goto done;
+ rv = file->GetFileSize(&fileSize);
+ NS_ASSERTION(fileSize, "got empty file in UploadMessageFromFile");
+ if (NS_FAILED(rv) || !fileSize) goto done;
+ rv = NS_NewLocalFileInputStream(getter_AddRefs(fileInputStream), file);
+ if (NS_FAILED(rv) || !fileInputStream) goto done;
+ command.AppendInt((int32_t)fileSize);
+ if (hasLiteralPlus)
+ command.Append("+}" CRLF);
+ else
+ command.Append("}" CRLF);
+
+ rv = SendData(command.get());
+ if (NS_FAILED(rv)) goto done;
+
+ if (!hasLiteralPlus)
+ ParseIMAPandCheckForNewMail();
+
+ totalSize = fileSize;
+ readCount = 0;
+ while(NS_SUCCEEDED(rv) && !eof && totalSize > 0)
+ {
+ rv = fileInputStream->Read(dataBuffer, COPY_BUFFER_SIZE, &readCount);
+ if (NS_SUCCEEDED(rv) && !readCount)
+ rv = NS_ERROR_FAILURE;
+
+ if (NS_SUCCEEDED(rv))
+ {
+ NS_ASSERTION(readCount <= (uint32_t) totalSize, "got more bytes than there should be");
+ dataBuffer[readCount] = 0;
+ rv = SendData(dataBuffer);
+ totalSize -= readCount;
+ PercentProgressUpdateEvent(nullptr, fileSize - totalSize, fileSize);
+ }
+ }
+ if (NS_SUCCEEDED(rv))
+ {
+ rv = SendData(CRLF); // complete the append
+ ParseIMAPandCheckForNewMail(command.get());
+
+ nsImapAction imapAction;
+ m_runningUrl->GetImapAction(&imapAction);
+
+ if (GetServerStateParser().LastCommandSuccessful() && (
+ imapAction == nsIImapUrl::nsImapAppendDraftFromFile || imapAction==nsIImapUrl::nsImapAppendMsgFromFile))
+ {
+ if (GetServerStateParser().GetCapabilityFlag() &
+ kUidplusCapability)
+ {
+ nsMsgKey newKey = GetServerStateParser().CurrentResponseUID();
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->SetAppendMsgUid(newKey, m_runningUrl);
+
+ // Courier imap server seems to have problems with recently
+ // appended messages. Noop seems to clear its confusion.
+ if (FolderIsSelected(mailboxName))
+ Noop();
+
+ nsCString oldMsgId;
+ rv = m_runningUrl->GetListOfMessageIds(oldMsgId);
+ if (NS_SUCCEEDED(rv) && !oldMsgId.IsEmpty())
+ {
+ bool idsAreUids = true;
+ m_runningUrl->MessageIdsAreUids(&idsAreUids);
+ Store(oldMsgId, "+FLAGS (\\Deleted)", idsAreUids);
+ UidExpunge(oldMsgId);
+ }
+ }
+ // for non UIDPLUS servers,
+ // this code used to check for imapAction==nsIImapUrl::nsImapAppendMsgFromFile, which
+ // meant we'd get into this code whenever sending a message, as well
+ // as when copying messages to an imap folder from local folders or an other imap server.
+ // This made sending a message slow when there was a large sent folder. I don't believe
+ // this code worked anyway.
+ else if (m_imapMailFolderSink && imapAction == nsIImapUrl::nsImapAppendDraftFromFile )
+ { // *** code me to search for the newly appended message
+ // go to selected state
+ nsCString messageId;
+ rv = m_imapMailFolderSink->GetMessageId(m_runningUrl, messageId);
+ if (NS_SUCCEEDED(rv) && !messageId.IsEmpty() &&
+ GetServerStateParser().LastCommandSuccessful())
+ {
+ // if the appended to folder isn't selected in the connection,
+ // select it.
+ if (!FolderIsSelected(mailboxName))
+ SelectMailbox(mailboxName);
+ else
+ Noop(); // See if this makes SEARCH work on the newly appended msg.
+
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ command = "SEARCH UNDELETED HEADER Message-ID ";
+ command.Append(messageId);
+
+ // Clean up result sequence before issuing the cmd.
+ GetServerStateParser().ResetSearchResultSequence();
+
+ Search(command.get(), true, false);
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ nsMsgKey newkey = nsMsgKey_None;
+ nsImapSearchResultIterator *searchResult =
+ GetServerStateParser().CreateSearchResultIterator();
+ newkey = searchResult->GetNextMessageNumber();
+ delete searchResult;
+ if (newkey != nsMsgKey_None)
+ m_imapMailFolderSink->SetAppendMsgUid(newkey, m_runningUrl);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+done:
+ PR_Free(dataBuffer);
+ if (fileInputStream)
+ fileInputStream->Close();
+}
+
+//caller must free using PR_Free
+char * nsImapProtocol::OnCreateServerSourceFolderPathString()
+{
+ char *sourceMailbox = nullptr;
+ char hierarchyDelimiter = 0;
+ char onlineDelimiter = 0;
+ m_runningUrl->GetOnlineSubDirSeparator(&hierarchyDelimiter);
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->GetOnlineDelimiter(&onlineDelimiter);
+
+ if (onlineDelimiter != kOnlineHierarchySeparatorUnknown &&
+ onlineDelimiter != hierarchyDelimiter)
+ m_runningUrl->SetOnlineSubDirSeparator(onlineDelimiter);
+
+ m_runningUrl->CreateServerSourceFolderPathString(&sourceMailbox);
+
+ return sourceMailbox;
+}
+
+//caller must free using PR_Free, safe to call from ui thread
+char * nsImapProtocol::GetFolderPathString()
+{
+ char *sourceMailbox = nullptr;
+ char onlineSubDirDelimiter = 0;
+ char hierarchyDelimiter = 0;
+ nsCOMPtr <nsIMsgFolder> msgFolder;
+
+ m_runningUrl->GetOnlineSubDirSeparator(&onlineSubDirDelimiter);
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_runningUrl);
+ mailnewsUrl->GetFolder(getter_AddRefs(msgFolder));
+ if (msgFolder)
+ {
+ nsCOMPtr <nsIMsgImapMailFolder> imapFolder = do_QueryInterface(msgFolder);
+ if (imapFolder)
+ {
+ imapFolder->GetHierarchyDelimiter(&hierarchyDelimiter);
+ if (hierarchyDelimiter != kOnlineHierarchySeparatorUnknown &&
+ onlineSubDirDelimiter != hierarchyDelimiter)
+ m_runningUrl->SetOnlineSubDirSeparator(hierarchyDelimiter);
+ }
+ }
+ m_runningUrl->CreateServerSourceFolderPathString(&sourceMailbox);
+
+ return sourceMailbox;
+}
+
+nsresult nsImapProtocol::CreateServerSourceFolderPathString(char **result)
+{
+ NS_ENSURE_ARG(result);
+ *result = OnCreateServerSourceFolderPathString();
+ return (*result) ? NS_OK : NS_ERROR_OUT_OF_MEMORY;
+}
+
+//caller must free using PR_Free
+char * nsImapProtocol::OnCreateServerDestinationFolderPathString()
+{
+ char *destinationMailbox = nullptr;
+ char hierarchyDelimiter = 0;
+ char onlineDelimiter = 0;
+ m_runningUrl->GetOnlineSubDirSeparator(&hierarchyDelimiter);
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->GetOnlineDelimiter(&onlineDelimiter);
+ if (onlineDelimiter != kOnlineHierarchySeparatorUnknown &&
+ onlineDelimiter != hierarchyDelimiter)
+ m_runningUrl->SetOnlineSubDirSeparator(onlineDelimiter);
+
+ m_runningUrl->CreateServerDestinationFolderPathString(&destinationMailbox);
+
+ return destinationMailbox;
+}
+
+void nsImapProtocol::OnCreateFolder(const char * aSourceMailbox)
+{
+ bool created = CreateMailboxRespectingSubscriptions(aSourceMailbox);
+ if (created)
+ {
+ m_hierarchyNameState = kListingForCreate;
+ nsCString mailboxWODelim(aSourceMailbox);
+ RemoveHierarchyDelimiter(mailboxWODelim);
+ List(mailboxWODelim.get(), false);
+ m_hierarchyNameState = kNoOperationInProgress;
+ }
+ else
+ FolderNotCreated(aSourceMailbox);
+}
+
+void nsImapProtocol::OnEnsureExistsFolder(const char * aSourceMailbox)
+{
+
+ List(aSourceMailbox, false); // how to tell if that succeeded?
+ bool exists = false;
+
+ // try converting aSourceMailbox to canonical format
+
+ nsIMAPNamespace *nsForMailbox = nullptr;
+ m_hostSessionList->GetNamespaceForMailboxForHost(GetImapServerKey(),
+ aSourceMailbox, nsForMailbox);
+ // NS_ASSERTION (nsForMailbox, "Oops .. null nsForMailbox\n");
+
+ nsCString name;
+
+ if (nsForMailbox)
+ m_runningUrl->AllocateCanonicalPath(aSourceMailbox,
+ nsForMailbox->GetDelimiter(),
+ getter_Copies(name));
+ else
+ m_runningUrl->AllocateCanonicalPath(aSourceMailbox,
+ kOnlineHierarchySeparatorUnknown,
+ getter_Copies(name));
+
+ if (m_imapServerSink)
+ m_imapServerSink->FolderVerifiedOnline(name, &exists);
+
+ if (exists)
+ {
+ Subscribe(aSourceMailbox);
+ }
+ else
+ {
+ bool created = CreateMailboxRespectingSubscriptions(aSourceMailbox);
+ if (created)
+ {
+ List(aSourceMailbox, false);
+ }
+ }
+ if (!GetServerStateParser().LastCommandSuccessful())
+ FolderNotCreated(aSourceMailbox);
+}
+
+
+void nsImapProtocol::OnSubscribe(const char * sourceMailbox)
+{
+ Subscribe(sourceMailbox);
+}
+
+void nsImapProtocol::OnUnsubscribe(const char * sourceMailbox)
+{
+ // When we try to auto-unsubscribe from \Noselect folders,
+ // some servers report errors if we were already unsubscribed
+ // from them.
+ bool lastReportingErrors = GetServerStateParser().GetReportingErrors();
+ GetServerStateParser().SetReportingErrors(false);
+ Unsubscribe(sourceMailbox);
+ GetServerStateParser().SetReportingErrors(lastReportingErrors);
+}
+
+void nsImapProtocol::RefreshACLForFolderIfNecessary(const char *mailboxName)
+{
+ if (GetServerStateParser().ServerHasACLCapability())
+ {
+ if (!m_folderNeedsACLRefreshed && m_imapMailFolderSink)
+ m_imapMailFolderSink->GetFolderNeedsACLListed(&m_folderNeedsACLRefreshed);
+ if (m_folderNeedsACLRefreshed)
+ {
+ RefreshACLForFolder(mailboxName);
+ m_folderNeedsACLRefreshed = false;
+ }
+ }
+}
+
+void nsImapProtocol::RefreshACLForFolder(const char *mailboxName)
+{
+
+ nsIMAPNamespace *ns = nullptr;
+ m_hostSessionList->GetNamespaceForMailboxForHost(GetImapServerKey(), mailboxName, ns);
+ if (ns)
+ {
+ switch (ns->GetType())
+ {
+ case kPersonalNamespace:
+ // It's a personal folder, most likely.
+ // I find it hard to imagine a server that supports ACL that doesn't support NAMESPACE,
+ // so most likely we KNOW that this is a personal, rather than the default, namespace.
+
+ // First, clear what we have.
+ ClearAllFolderRights();
+ // Now, get the new one.
+ GetMyRightsForFolder(mailboxName);
+ if (m_imapMailFolderSink)
+ {
+ uint32_t aclFlags = 0;
+ if (NS_SUCCEEDED(m_imapMailFolderSink->GetAclFlags(&aclFlags)) && aclFlags & IMAP_ACL_ADMINISTER_FLAG)
+ GetACLForFolder(mailboxName);
+ }
+
+ // We're all done, refresh the icon/flags for this folder
+ RefreshFolderACLView(mailboxName, ns);
+ break;
+ default:
+ // We know it's a public folder or other user's folder.
+ // We only want our own rights
+
+ // First, clear what we have
+ ClearAllFolderRights();
+ // Now, get the new one.
+ GetMyRightsForFolder(mailboxName);
+ // We're all done, refresh the icon/flags for this folder
+ RefreshFolderACLView(mailboxName, ns);
+ break;
+ }
+ }
+ else
+ {
+ // no namespace, not even default... can this happen?
+ NS_ASSERTION(false, "couldn't get namespace");
+ }
+}
+
+void nsImapProtocol::RefreshFolderACLView(const char *mailboxName, nsIMAPNamespace *nsForMailbox)
+{
+ nsCString canonicalMailboxName;
+
+ if (nsForMailbox)
+ m_runningUrl->AllocateCanonicalPath(mailboxName, nsForMailbox->GetDelimiter(), getter_Copies(canonicalMailboxName));
+ else
+ m_runningUrl->AllocateCanonicalPath(mailboxName, kOnlineHierarchySeparatorUnknown, getter_Copies(canonicalMailboxName));
+
+ if (m_imapServerSink)
+ m_imapServerSink->RefreshFolderRights(canonicalMailboxName);
+}
+
+void nsImapProtocol::GetACLForFolder(const char *mailboxName)
+{
+ IncrementCommandTagNumber();
+
+ nsCString command(GetServerCommandTag());
+ nsCString escapedName;
+ CreateEscapedMailboxName(mailboxName, escapedName);
+ command.Append(" getacl \"");
+ command.Append(escapedName);
+ command.Append("\"" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::OnRefreshAllACLs()
+{
+ m_hierarchyNameState = kListingForInfoOnly;
+ nsIMAPMailboxInfo *mb = NULL;
+
+ // This will fill in the list
+ List("*", true);
+
+ int32_t total = m_listedMailboxList.Count(), count = 0;
+ GetServerStateParser().SetReportingErrors(false);
+ for (int32_t i = 0; i < total; i++)
+ {
+ mb = (nsIMAPMailboxInfo *) m_listedMailboxList.ElementAt(i);
+ if (mb) // paranoia
+ {
+ char *onlineName = nullptr;
+ m_runningUrl->AllocateServerPath(PromiseFlatCString(mb->GetMailboxName()).get(), mb->GetDelimiter(), &onlineName);
+ if (onlineName)
+ {
+ RefreshACLForFolder(onlineName);
+ NS_Free(onlineName);
+ }
+ PercentProgressUpdateEvent(NULL, count, total);
+ delete mb;
+ count++;
+ }
+ }
+ m_listedMailboxList.Clear();
+
+ PercentProgressUpdateEvent(NULL, 100, 100);
+ GetServerStateParser().SetReportingErrors(true);
+ m_hierarchyNameState = kNoOperationInProgress;
+}
+
+// any state commands
+void nsImapProtocol::Logout(bool shuttingDown /* = false */,
+ bool waitForResponse /* = true */)
+{
+ if (!shuttingDown)
+ ProgressEventFunctionUsingId (IMAP_STATUS_LOGGING_OUT);
+
+/******************************************************************
+ * due to the undo functionality we cannot issule a close when logout; there
+ * is no way to do an undo if the message has been permanently expunge
+ * jt - 07/12/1999
+
+ bool closeNeeded = GetServerStateParser().GetIMAPstate() ==
+ nsImapServerResponseParser::kFolderSelected;
+
+ if (closeNeeded && GetDeleteIsMoveToTrash())
+ Close();
+********************/
+
+ IncrementCommandTagNumber();
+
+ nsCString command(GetServerCommandTag());
+
+ command.Append(" logout" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (m_transport && shuttingDown)
+ m_transport->SetTimeout(nsISocketTransport::TIMEOUT_READ_WRITE, 5);
+ // the socket may be dead before we read the response, so drop it.
+ if (NS_SUCCEEDED(rv) && waitForResponse)
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::Noop()
+{
+ //ProgressUpdateEvent("noop...");
+ IncrementCommandTagNumber();
+ nsCString command(GetServerCommandTag());
+
+ command.Append(" noop" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::XServerInfo()
+{
+
+ ProgressEventFunctionUsingId (IMAP_GETTING_SERVER_INFO);
+ IncrementCommandTagNumber();
+ nsCString command(GetServerCommandTag());
+
+ command.Append(" XSERVERINFO MANAGEACCOUNTURL MANAGELISTSURL MANAGEFILTERSURL" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::Netscape()
+{
+ ProgressEventFunctionUsingId (IMAP_GETTING_SERVER_INFO);
+ IncrementCommandTagNumber();
+
+ nsCString command(GetServerCommandTag());
+
+ command.Append(" netscape" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+
+
+void nsImapProtocol::XMailboxInfo(const char *mailboxName)
+{
+
+ ProgressEventFunctionUsingId (IMAP_GETTING_MAILBOX_INFO);
+ IncrementCommandTagNumber();
+ nsCString command(GetServerCommandTag());
+
+ command.Append(" XMAILBOXINFO \"");
+ command.Append(mailboxName);
+ command.Append("\" MANAGEURL POSTURL" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::Namespace()
+{
+
+ IncrementCommandTagNumber();
+
+ nsCString command(GetServerCommandTag());
+ command.Append(" namespace" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+
+void nsImapProtocol::MailboxData()
+{
+ IncrementCommandTagNumber();
+
+ nsCString command(GetServerCommandTag());
+ command.Append(" mailboxdata" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+
+void nsImapProtocol::GetMyRightsForFolder(const char *mailboxName)
+{
+ IncrementCommandTagNumber();
+
+ nsCString command(GetServerCommandTag());
+ nsCString escapedName;
+ CreateEscapedMailboxName(mailboxName, escapedName);
+
+ if (MailboxIsNoSelectMailbox(escapedName.get()))
+ return; // Don't issue myrights on Noselect folder
+
+ command.Append(" myrights \"");
+ command.Append(escapedName);
+ command.Append("\"" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+bool nsImapProtocol::FolderIsSelected(const char *mailboxName)
+{
+ return (GetServerStateParser().GetIMAPstate() ==
+ nsImapServerResponseParser::kFolderSelected && GetServerStateParser().GetSelectedMailboxName() &&
+ PL_strcmp(GetServerStateParser().GetSelectedMailboxName(),
+ mailboxName) == 0);
+}
+
+void nsImapProtocol::OnStatusForFolder(const char *mailboxName)
+{
+
+ if (FolderIsSelected(mailboxName))
+ {
+ int32_t prevNumMessages = GetServerStateParser().NumberOfMessages();
+ Noop();
+ // OnNewIdleMessages will cause the ui thread to update the folder
+ if (m_imapMailFolderSink && (GetServerStateParser().NumberOfRecentMessages()
+ || prevNumMessages != GetServerStateParser().NumberOfMessages()))
+ m_imapMailFolderSink->OnNewIdleMessages();
+ return;
+ }
+
+ IncrementCommandTagNumber();
+
+ nsAutoCString command(GetServerCommandTag());
+ nsCString escapedName;
+ CreateEscapedMailboxName(mailboxName, escapedName);
+
+ command.Append(" STATUS \"");
+ command.Append(escapedName);
+ command.Append("\" (UIDNEXT MESSAGES UNSEEN RECENT)" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ nsImapMailboxSpec *new_spec = GetServerStateParser().CreateCurrentMailboxSpec(mailboxName);
+ if (new_spec && m_imapMailFolderSink)
+ m_imapMailFolderSink->UpdateImapMailboxStatus(this, new_spec);
+ NS_IF_RELEASE(new_spec);
+ }
+}
+
+
+void nsImapProtocol::OnListFolder(const char * aSourceMailbox, bool aBool)
+{
+ List(aSourceMailbox, aBool);
+}
+
+
+// Returns true if the mailbox is a NoSelect mailbox.
+// If we don't know about it, returns false.
+bool nsImapProtocol::MailboxIsNoSelectMailbox(const char *mailboxName)
+{
+ bool rv = false;
+
+ nsIMAPNamespace *nsForMailbox = nullptr;
+ m_hostSessionList->GetNamespaceForMailboxForHost(GetImapServerKey(),
+ mailboxName, nsForMailbox);
+ // NS_ASSERTION (nsForMailbox, "Oops .. null nsForMailbox\n");
+
+ nsCString name;
+
+ if (nsForMailbox)
+ m_runningUrl->AllocateCanonicalPath(mailboxName,
+ nsForMailbox->GetDelimiter(),
+ getter_Copies(name));
+ else
+ m_runningUrl->AllocateCanonicalPath(mailboxName,
+ kOnlineHierarchySeparatorUnknown,
+ getter_Copies(name));
+
+ if (name.IsEmpty())
+ return false;
+
+ NS_ASSERTION(m_imapServerSink, "unexpected, no imap server sink, see bug #194335");
+ if (m_imapServerSink)
+ m_imapServerSink->FolderIsNoSelect(name, &rv);
+ return rv;
+}
+
+nsresult nsImapProtocol::SetFolderAdminUrl(const char *mailboxName)
+{
+ nsresult rv = NS_ERROR_NULL_POINTER; // if m_imapServerSink is null, rv will be this.
+
+ nsIMAPNamespace *nsForMailbox = nullptr;
+ m_hostSessionList->GetNamespaceForMailboxForHost(GetImapServerKey(),
+ mailboxName, nsForMailbox);
+
+ nsCString name;
+
+ if (nsForMailbox)
+ m_runningUrl->AllocateCanonicalPath(mailboxName,
+ nsForMailbox->GetDelimiter(),
+ getter_Copies(name));
+ else
+ m_runningUrl->AllocateCanonicalPath(mailboxName,
+ kOnlineHierarchySeparatorUnknown,
+ getter_Copies(name));
+
+ if (m_imapServerSink)
+ rv = m_imapServerSink->SetFolderAdminURL(name, nsDependentCString(GetServerStateParser().GetManageFolderUrl()));
+ return rv;
+}
+// returns true is the delete succeeded (regardless of subscription changes)
+bool nsImapProtocol::DeleteMailboxRespectingSubscriptions(const char *mailboxName)
+{
+ bool rv = true;
+ if (!MailboxIsNoSelectMailbox(mailboxName))
+ {
+ // Only try to delete it if it really exists
+ DeleteMailbox(mailboxName);
+ rv = GetServerStateParser().LastCommandSuccessful();
+ }
+
+ // We can unsubscribe even if the mailbox doesn't exist.
+ if (rv && m_autoUnsubscribe) // auto-unsubscribe is on
+ {
+ bool reportingErrors = GetServerStateParser().GetReportingErrors();
+ GetServerStateParser().SetReportingErrors(false);
+ Unsubscribe(mailboxName);
+ GetServerStateParser().SetReportingErrors(reportingErrors);
+
+ }
+ return (rv);
+}
+
+// returns true is the rename succeeded (regardless of subscription changes)
+// reallyRename tells us if we should really do the rename (true) or if we should just move subscriptions (false)
+bool nsImapProtocol::RenameMailboxRespectingSubscriptions(const char *existingName, const char *newName, bool reallyRename)
+{
+ bool rv = true;
+ if (reallyRename && !MailboxIsNoSelectMailbox(existingName))
+ {
+ RenameMailbox(existingName, newName);
+ rv = GetServerStateParser().LastCommandSuccessful();
+ }
+
+ if (rv)
+ {
+ if (m_autoSubscribe) // if auto-subscribe is on
+ {
+ bool reportingErrors = GetServerStateParser().GetReportingErrors();
+ GetServerStateParser().SetReportingErrors(false);
+ Subscribe(newName);
+ GetServerStateParser().SetReportingErrors(reportingErrors);
+ }
+ if (m_autoUnsubscribe) // if auto-unsubscribe is on
+ {
+ bool reportingErrors = GetServerStateParser().GetReportingErrors();
+ GetServerStateParser().SetReportingErrors(false);
+ Unsubscribe(existingName);
+ GetServerStateParser().SetReportingErrors(reportingErrors);
+ }
+ }
+ return (rv);
+}
+
+bool nsImapProtocol::RenameHierarchyByHand(const char *oldParentMailboxName,
+ const char *newParentMailboxName)
+{
+ bool renameSucceeded = true;
+ char onlineDirSeparator = kOnlineHierarchySeparatorUnknown;
+ m_deletableChildren = new nsVoidArray();
+
+ bool nonHierarchicalRename =
+ ((GetServerStateParser().GetCapabilityFlag() & kNoHierarchyRename)
+ || MailboxIsNoSelectMailbox(oldParentMailboxName));
+
+ if (m_deletableChildren)
+ {
+ m_hierarchyNameState = kDeleteSubFoldersInProgress;
+ nsIMAPNamespace *ns = nullptr;
+ m_hostSessionList->GetNamespaceForMailboxForHost(GetImapServerKey(),
+ oldParentMailboxName,
+ ns); // for delimiter
+ if (!ns)
+ {
+ if (!PL_strcasecmp(oldParentMailboxName, "INBOX"))
+ m_hostSessionList->GetDefaultNamespaceOfTypeForHost(GetImapServerKey(),
+ kPersonalNamespace,
+ ns);
+ }
+ if (ns)
+ {
+ nsCString pattern(oldParentMailboxName);
+ pattern += ns->GetDelimiter();
+ pattern += "*";
+ bool isUsingSubscription = false;
+ m_hostSessionList->GetHostIsUsingSubscription(GetImapServerKey(),
+ isUsingSubscription);
+
+ if (isUsingSubscription)
+ Lsub(pattern.get(), false);
+ else
+ List(pattern.get(), false);
+ }
+ m_hierarchyNameState = kNoOperationInProgress;
+
+ if (GetServerStateParser().LastCommandSuccessful())
+ renameSucceeded = // rename this, and move subscriptions
+ RenameMailboxRespectingSubscriptions(oldParentMailboxName,
+ newParentMailboxName, true);
+
+ int32_t numberToDelete = m_deletableChildren->Count();
+ int32_t childIndex;
+
+ for (childIndex = 0;
+ (childIndex < numberToDelete) && renameSucceeded; childIndex++)
+ {
+ // the imap parser has already converted to a non UTF7 string in the canonical
+ // format so convert it back
+ char *currentName = (char *) m_deletableChildren->ElementAt(childIndex);
+ if (currentName)
+ {
+ char *serverName = nullptr;
+ m_runningUrl->AllocateServerPath(currentName,
+ onlineDirSeparator,
+ &serverName);
+ PR_FREEIF(currentName);
+ currentName = serverName;
+ }
+
+ // calculate the new name and do the rename
+ nsCString newChildName(newParentMailboxName);
+ newChildName += (currentName + PL_strlen(oldParentMailboxName));
+ RenameMailboxRespectingSubscriptions(currentName,
+ newChildName.get(),
+ nonHierarchicalRename);
+ // pass in xNonHierarchicalRename to determine if we should really
+ // reanme, or just move subscriptions
+ renameSucceeded = GetServerStateParser().LastCommandSuccessful();
+ PR_FREEIF(currentName);
+ }
+
+ delete m_deletableChildren;
+ m_deletableChildren = nullptr;
+ }
+
+ return renameSucceeded;
+}
+
+bool nsImapProtocol::DeleteSubFolders(const char* selectedMailbox, bool &aDeleteSelf)
+{
+ bool deleteSucceeded = true;
+ m_deletableChildren = new nsVoidArray();
+
+ if (m_deletableChildren)
+ {
+ bool folderDeleted = false;
+
+ m_hierarchyNameState = kDeleteSubFoldersInProgress;
+ nsCString pattern(selectedMailbox);
+ char onlineDirSeparator = kOnlineHierarchySeparatorUnknown;
+ m_runningUrl->GetOnlineSubDirSeparator(&onlineDirSeparator);
+ pattern.Append(onlineDirSeparator);
+ pattern.Append('*');
+
+ if (!pattern.IsEmpty())
+ {
+ List(pattern.get(), false);
+ }
+ m_hierarchyNameState = kNoOperationInProgress;
+
+ // this should be a short list so perform a sequential search for the
+ // longest name mailbox. Deleting the longest first will hopefully
+ // prevent the server from having problems about deleting parents
+ // ** jt - why? I don't understand this.
+ int32_t numberToDelete = m_deletableChildren->Count();
+ int32_t outerIndex, innerIndex;
+
+ // intelligently decide if myself(either plain format or following the dir-separator)
+ // is in the sub-folder list
+ bool folderInSubfolderList = false; // For Performance
+ char *selectedMailboxDir = nullptr;
+ {
+ int32_t length = strlen(selectedMailbox);
+ selectedMailboxDir = (char *)PR_MALLOC(length+2);
+ if( selectedMailboxDir ) // only do the intelligent test if there is enough memory
+ {
+ strcpy(selectedMailboxDir, selectedMailbox);
+ selectedMailboxDir[length] = onlineDirSeparator;
+ selectedMailboxDir[length+1] = '\0';
+ int32_t i;
+ for( i=0; i<numberToDelete && !folderInSubfolderList; i++ )
+ {
+ char *currentName = (char *) m_deletableChildren->ElementAt(i);
+ if( !strcmp(currentName, selectedMailbox) || !strcmp(currentName, selectedMailboxDir) )
+ folderInSubfolderList = true;
+ }
+ }
+ }
+
+ deleteSucceeded = GetServerStateParser().LastCommandSuccessful();
+ for (outerIndex = 0;
+ (outerIndex < numberToDelete) && deleteSucceeded;
+ outerIndex++)
+ {
+ char* longestName = nullptr;
+ int32_t longestIndex = 0; // fix bogus warning by initializing
+ for (innerIndex = 0;
+ innerIndex < m_deletableChildren->Count();
+ innerIndex++)
+ {
+ char *currentName =
+ (char *) m_deletableChildren->ElementAt(innerIndex);
+ if (!longestName || strlen(longestName) < strlen(currentName))
+ {
+ longestName = currentName;
+ longestIndex = innerIndex;
+ }
+ }
+ // the imap parser has already converted to a non UTF7 string in
+ // the canonical format so convert it back
+ if (longestName)
+ {
+ char *serverName = nullptr;
+
+ m_deletableChildren->RemoveElementAt(longestIndex);
+ m_runningUrl->AllocateServerPath(longestName,
+ onlineDirSeparator,
+ &serverName);
+ PR_FREEIF(longestName);
+ longestName = serverName;
+ }
+
+ // some imap servers include the selectedMailbox in the list of
+ // subfolders of the selectedMailbox. Check for this so we don't
+ // delete the selectedMailbox (usually the trash and doing an
+ // empty trash)
+ // The Cyrus imap server ignores the "INBOX.Trash" constraining
+ // string passed to the list command. Be defensive and make sure
+ // we only delete children of the trash
+ if (longestName &&
+ strcmp(selectedMailbox, longestName) &&
+ !strncmp(selectedMailbox, longestName, strlen(selectedMailbox)))
+ {
+ if( selectedMailboxDir && !strcmp(selectedMailboxDir, longestName) ) // just myself
+ {
+ if( aDeleteSelf )
+ {
+ bool deleted = DeleteMailboxRespectingSubscriptions(longestName);
+ if (deleted)
+ FolderDeleted(longestName);
+ folderDeleted = deleted;
+ deleteSucceeded = deleted;
+ }
+ }
+ else
+ {
+ nsCOMPtr<nsIImapIncomingServer> imapServer = do_QueryReferent(m_server);
+ if (imapServer)
+ imapServer->ResetConnection(nsDependentCString(longestName));
+ bool deleted = false;
+ if( folderInSubfolderList ) // for performance
+ {
+ nsVoidArray* pDeletableChildren = m_deletableChildren;
+ m_deletableChildren = nullptr;
+ bool folderDeleted = true;
+ deleted = DeleteSubFolders(longestName, folderDeleted);
+ // longestName may have subfolder list including itself
+ if( !folderDeleted )
+ {
+ if (deleted)
+ deleted = DeleteMailboxRespectingSubscriptions(longestName);
+ if (deleted)
+ FolderDeleted(longestName);
+ }
+ m_deletableChildren = pDeletableChildren;
+ }
+ else
+ {
+ deleted = DeleteMailboxRespectingSubscriptions(longestName);
+ if (deleted)
+ FolderDeleted(longestName);
+ }
+ deleteSucceeded = deleted;
+ }
+ }
+ PR_FREEIF(longestName);
+ }
+
+ aDeleteSelf = folderDeleted; // feedback if myself is deleted
+ PR_Free(selectedMailboxDir);
+
+ delete m_deletableChildren;
+ m_deletableChildren = nullptr;
+ }
+ return deleteSucceeded;
+}
+
+void nsImapProtocol::FolderDeleted(const char *mailboxName)
+{
+ char onlineDelimiter = kOnlineHierarchySeparatorUnknown;
+ nsCString orphanedMailboxName;
+
+ if (mailboxName)
+ {
+ m_runningUrl->AllocateCanonicalPath(mailboxName, onlineDelimiter,
+ getter_Copies(orphanedMailboxName));
+ if (m_imapServerSink)
+ m_imapServerSink->OnlineFolderDelete(orphanedMailboxName);
+ }
+}
+
+void nsImapProtocol::FolderNotCreated(const char *folderName)
+{
+ if (folderName && m_imapServerSink)
+ m_imapServerSink->OnlineFolderCreateFailed(nsDependentCString(folderName));
+}
+
+void nsImapProtocol::FolderRenamed(const char *oldName,
+ const char *newName)
+{
+ char onlineDelimiter = kOnlineHierarchySeparatorUnknown;
+
+ if ((m_hierarchyNameState == kNoOperationInProgress) ||
+ (m_hierarchyNameState == kListingForInfoAndDiscovery))
+
+ {
+ nsCString canonicalOldName, canonicalNewName;
+ m_runningUrl->AllocateCanonicalPath(oldName,
+ onlineDelimiter,
+ getter_Copies(canonicalOldName));
+ m_runningUrl->AllocateCanonicalPath(newName,
+ onlineDelimiter,
+ getter_Copies(canonicalNewName));
+ nsCOMPtr<nsIMsgWindow> msgWindow;
+ GetMsgWindow(getter_AddRefs(msgWindow));
+ m_imapServerSink->OnlineFolderRename(msgWindow, canonicalOldName, canonicalNewName);
+ }
+}
+
+void nsImapProtocol::OnDeleteFolder(const char * sourceMailbox)
+{
+ // intelligently delete the folder
+ bool folderDeleted = true;
+ bool deleted = DeleteSubFolders(sourceMailbox, folderDeleted);
+ if( !folderDeleted )
+ {
+ if (deleted)
+ deleted = DeleteMailboxRespectingSubscriptions(sourceMailbox);
+ if (deleted)
+ FolderDeleted(sourceMailbox);
+ }
+}
+
+void nsImapProtocol::RemoveMsgsAndExpunge()
+{
+ uint32_t numberOfMessages = GetServerStateParser().NumberOfMessages();
+ if (numberOfMessages)
+ {
+ // Remove all msgs and expunge the folder (ie, compact it).
+ Store(NS_LITERAL_CSTRING("1:*"), "+FLAGS.SILENT (\\Deleted)", false); // use sequence #'s
+ if (GetServerStateParser().LastCommandSuccessful())
+ Expunge();
+ }
+}
+
+void nsImapProtocol::DeleteFolderAndMsgs(const char * sourceMailbox)
+{
+ RemoveMsgsAndExpunge();
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ // All msgs are deleted successfully - let's remove the folder itself.
+ bool reportingErrors = GetServerStateParser().GetReportingErrors();
+ GetServerStateParser().SetReportingErrors(false);
+ OnDeleteFolder(sourceMailbox);
+ GetServerStateParser().SetReportingErrors(reportingErrors);
+ }
+}
+
+void nsImapProtocol::OnRenameFolder(const char * sourceMailbox)
+{
+ char *destinationMailbox = OnCreateServerDestinationFolderPathString();
+
+ if (destinationMailbox)
+ {
+ bool renamed = RenameHierarchyByHand(sourceMailbox, destinationMailbox);
+ if (renamed)
+ FolderRenamed(sourceMailbox, destinationMailbox);
+
+ PR_Free( destinationMailbox);
+ }
+ else
+ HandleMemoryFailure();
+}
+
+void nsImapProtocol::OnMoveFolderHierarchy(const char * sourceMailbox)
+{
+ char *destinationMailbox = OnCreateServerDestinationFolderPathString();
+
+ if (destinationMailbox)
+ {
+ nsCString newBoxName;
+ newBoxName.Adopt(destinationMailbox);
+
+ char onlineDirSeparator = kOnlineHierarchySeparatorUnknown;
+ m_runningUrl->GetOnlineSubDirSeparator(&onlineDirSeparator);
+
+ nsCString oldBoxName(sourceMailbox);
+ int32_t leafStart = oldBoxName.RFindChar(onlineDirSeparator);
+ nsCString leafName;
+
+ if (-1 == leafStart)
+ leafName = oldBoxName; // this is a root level box
+ else
+ leafName = Substring(oldBoxName, leafStart+1);
+
+ if ( !newBoxName.IsEmpty() )
+ newBoxName.Append(onlineDirSeparator);
+ newBoxName.Append(leafName);
+ bool renamed = RenameHierarchyByHand(sourceMailbox,
+ newBoxName.get());
+ if (renamed)
+ FolderRenamed(sourceMailbox, newBoxName.get());
+ }
+ else
+ HandleMemoryFailure();
+}
+
+void nsImapProtocol::FindMailboxesIfNecessary()
+{
+ // biff should not discover mailboxes
+ bool foundMailboxesAlready = false;
+ nsImapAction imapAction;
+
+ // need to do this for every connection in order to see folders.
+ (void) m_runningUrl->GetImapAction(&imapAction);
+ nsresult rv = m_hostSessionList->GetHaveWeEverDiscoveredFoldersForHost(GetImapServerKey(), foundMailboxesAlready);
+ if (NS_SUCCEEDED(rv) && !foundMailboxesAlready &&
+ (imapAction != nsIImapUrl::nsImapBiff) &&
+ (imapAction != nsIImapUrl::nsImapVerifylogon) &&
+ (imapAction != nsIImapUrl::nsImapDiscoverAllBoxesUrl) &&
+ (imapAction != nsIImapUrl::nsImapUpgradeToSubscription) &&
+ !GetSubscribingNow())
+ DiscoverMailboxList();
+}
+
+void nsImapProtocol::DiscoverAllAndSubscribedBoxes()
+{
+ // used for subscribe pane
+ // iterate through all namespaces
+ uint32_t count = 0;
+ m_hostSessionList->GetNumberOfNamespacesForHost(GetImapServerKey(), count);
+
+ for (uint32_t i = 0; i < count; i++ )
+ {
+ nsIMAPNamespace *ns = nullptr;
+
+ m_hostSessionList->GetNamespaceNumberForHost(GetImapServerKey(), i,
+ ns);
+ if (ns &&
+ gHideOtherUsersFromList ? (ns->GetType() != kOtherUsersNamespace)
+ : true)
+ {
+ const char *prefix = ns->GetPrefix();
+ if (prefix)
+ {
+ if (!gHideUnusedNamespaces && *prefix &&
+ PL_strcasecmp(prefix, "INBOX.")) /* only do it for
+ non-empty namespace prefixes */
+ {
+ // Explicitly discover each Namespace, just so they're
+ // there in the subscribe UI
+ nsImapMailboxSpec *boxSpec = new nsImapMailboxSpec;
+ if (boxSpec)
+ {
+ NS_ADDREF(boxSpec);
+ boxSpec->mFolderSelected = false;
+ boxSpec->mHostName.Assign(GetImapHostName());
+ boxSpec->mConnection = this;
+ boxSpec->mFlagState = nullptr;
+ boxSpec->mDiscoveredFromLsub = true;
+ boxSpec->mOnlineVerified = true;
+ boxSpec->mBoxFlags = kNoselect;
+ boxSpec->mHierarchySeparator = ns->GetDelimiter();
+
+ m_runningUrl->AllocateCanonicalPath(ns->GetPrefix(), ns->GetDelimiter(),
+ getter_Copies(boxSpec->mAllocatedPathName));
+ boxSpec->mNamespaceForFolder = ns;
+ boxSpec->mBoxFlags |= kNameSpace;
+
+ switch (ns->GetType())
+ {
+ case kPersonalNamespace:
+ boxSpec->mBoxFlags |= kPersonalMailbox;
+ break;
+ case kPublicNamespace:
+ boxSpec->mBoxFlags |= kPublicMailbox;
+ break;
+ case kOtherUsersNamespace:
+ boxSpec->mBoxFlags |= kOtherUsersMailbox;
+ break;
+ default: // (kUnknownNamespace)
+ break;
+ }
+
+ DiscoverMailboxSpec(boxSpec);
+ }
+ else
+ HandleMemoryFailure();
+ }
+
+ nsAutoCString allPattern(prefix);
+ allPattern += '*';
+
+ nsAutoCString topLevelPattern(prefix);
+ topLevelPattern += '%';
+
+ nsAutoCString secondLevelPattern;
+
+ char delimiter = ns->GetDelimiter();
+ if (delimiter)
+ {
+ // Hierarchy delimiter might be NIL, in which case there's no hierarchy anyway
+ secondLevelPattern = prefix;
+ secondLevelPattern += '%';
+ secondLevelPattern += delimiter;
+ secondLevelPattern += '%';
+ }
+
+ nsresult rv;
+ nsCOMPtr<nsIImapIncomingServer> imapServer = do_QueryReferent(m_server, &rv);
+ if (NS_FAILED(rv) || !imapServer) return;
+
+ if (!allPattern.IsEmpty())
+ {
+ imapServer->SetDoingLsub(true);
+ Lsub(allPattern.get(), true); // LSUB all the subscribed
+ }
+ if (!topLevelPattern.IsEmpty())
+ {
+ imapServer->SetDoingLsub(false);
+ List(topLevelPattern.get(), true); // LIST the top level
+ }
+ if (!secondLevelPattern.IsEmpty())
+ {
+ imapServer->SetDoingLsub(false);
+ List(secondLevelPattern.get(), true); // LIST the second level
+ }
+ }
+ }
+ }
+}
+
+// DiscoverMailboxList() is used to actually do the discovery of folders
+// for a host. This is used both when we initially start up (and re-sync)
+// and also when the user manually requests a re-sync, by collapsing and
+// expanding a host in the folder pane. This is not used for the subscribe
+// pane.
+// DiscoverMailboxList() also gets the ACLs for each newly discovered folder
+void nsImapProtocol::DiscoverMailboxList()
+{
+ bool usingSubscription = false;
+
+ m_hostSessionList->GetHostIsUsingSubscription(GetImapServerKey(), usingSubscription);
+ // Pretend that the Trash folder doesn't exist, so we will rediscover it if we need to.
+ m_hostSessionList->SetOnlineTrashFolderExistsForHost(GetImapServerKey(), false);
+
+ // should we check a pref here, to be able to turn off XList?
+ bool hasXLIST = GetServerStateParser().GetCapabilityFlag() & kHasXListCapability;
+ if (hasXLIST && usingSubscription)
+ {
+ m_hierarchyNameState = kXListing;
+ nsAutoCString pattern("%");
+ List("%", true, true);
+ // We list the first and second levels since special folders are unlikely
+ // to be more than 2 levels deep.
+ char separator = 0;
+ m_runningUrl->GetOnlineSubDirSeparator(&separator);
+ pattern.Append(separator);
+ pattern += '%';
+ List(pattern.get(), true, true);
+ }
+
+ SetMailboxDiscoveryStatus(eContinue);
+ if (GetServerStateParser().ServerHasACLCapability())
+ m_hierarchyNameState = kListingForInfoAndDiscovery;
+ else
+ m_hierarchyNameState = kNoOperationInProgress;
+
+ // iterate through all namespaces and LSUB them.
+ uint32_t count = 0;
+ m_hostSessionList->GetNumberOfNamespacesForHost(GetImapServerKey(), count);
+ for (uint32_t i = 0; i < count; i++ )
+ {
+ nsIMAPNamespace * ns = nullptr;
+ m_hostSessionList->GetNamespaceNumberForHost(GetImapServerKey(),i,ns);
+ if (ns)
+ {
+ const char *prefix = ns->GetPrefix();
+ if (prefix)
+ {
+ // static bool gHideUnusedNamespaces = true;
+ // mscott -> WARNING!!! i where are we going to get this
+ // global variable for unused name spaces from???
+ // dmb - we should get this from a per-host preference,
+ // I'd say. But for now, just make it true;
+ if (!gHideUnusedNamespaces && *prefix &&
+ PL_strcasecmp(prefix, "INBOX.")) // only do it for
+ // non-empty namespace prefixes, and for non-INBOX prefix
+ {
+ // Explicitly discover each Namespace, so that we can
+ // create subfolders of them,
+ nsImapMailboxSpec *boxSpec = new nsImapMailboxSpec;
+ if (boxSpec)
+ {
+ NS_ADDREF(boxSpec);
+ boxSpec->mFolderSelected = false;
+ boxSpec->mHostName = GetImapHostName();
+ boxSpec->mConnection = this;
+ boxSpec->mFlagState = nullptr;
+ boxSpec->mDiscoveredFromLsub = true;
+ boxSpec->mOnlineVerified = true;
+ boxSpec->mBoxFlags = kNoselect;
+ boxSpec->mHierarchySeparator = ns->GetDelimiter();
+ // Until |AllocateCanonicalPath()| gets updated:
+ m_runningUrl->AllocateCanonicalPath(
+ ns->GetPrefix(), ns->GetDelimiter(),
+ getter_Copies(boxSpec->mAllocatedPathName));
+ boxSpec->mNamespaceForFolder = ns;
+ boxSpec->mBoxFlags |= kNameSpace;
+
+ switch (ns->GetType())
+ {
+ case kPersonalNamespace:
+ boxSpec->mBoxFlags |= kPersonalMailbox;
+ break;
+ case kPublicNamespace:
+ boxSpec->mBoxFlags |= kPublicMailbox;
+ break;
+ case kOtherUsersNamespace:
+ boxSpec->mBoxFlags |= kOtherUsersMailbox;
+ break;
+ default: // (kUnknownNamespace)
+ break;
+ }
+
+ DiscoverMailboxSpec(boxSpec);
+ }
+ else
+ HandleMemoryFailure();
+ }
+
+ // now do the folders within this namespace
+ nsCString pattern;
+ nsCString pattern2;
+ if (usingSubscription)
+ {
+ pattern.Append(prefix);
+ pattern.Append("*");
+ }
+ else
+ {
+ pattern.Append(prefix);
+ pattern.Append("%"); // mscott just need one percent right?
+ // pattern = PR_smprintf("%s%%", prefix);
+ char delimiter = ns->GetDelimiter();
+ if (delimiter)
+ {
+ // delimiter might be NIL, in which case there's no hierarchy anyway
+ pattern2 = prefix;
+ pattern2 += "%";
+ pattern2 += delimiter;
+ pattern2 += "%";
+ // pattern2 = PR_smprintf("%s%%%c%%", prefix, delimiter);
+ }
+ }
+ if (usingSubscription) // && !GetSubscribingNow()) should never get here from subscribe pane
+ Lsub(pattern.get(), true);
+ else
+ {
+ List(pattern.get(), true, hasXLIST);
+ List(pattern2.get(), true, hasXLIST);
+ }
+ }
+ }
+ }
+
+ // explicitly LIST the INBOX if (a) we're not using subscription, or (b) we are using subscription and
+ // the user wants us to always show the INBOX.
+ bool listInboxForHost = false;
+ m_hostSessionList->GetShouldAlwaysListInboxForHost(GetImapServerKey(), listInboxForHost);
+ if (!usingSubscription || listInboxForHost)
+ List("INBOX", true);
+
+ m_hierarchyNameState = kNoOperationInProgress;
+
+ MailboxDiscoveryFinished();
+
+ // Get the ACLs for newly discovered folders
+ if (GetServerStateParser().ServerHasACLCapability())
+ {
+ int32_t total = m_listedMailboxList.Count(), cnt = 0;
+ // Let's not turn this off here, since we don't turn it on after
+ // GetServerStateParser().SetReportingErrors(false);
+ if (total)
+ {
+ ProgressEventFunctionUsingId(IMAP_GETTING_ACL_FOR_FOLDER);
+ nsIMAPMailboxInfo * mb = nullptr;
+ do
+ {
+ if (m_listedMailboxList.Count() == 0)
+ break;
+
+ mb = (nsIMAPMailboxInfo *) m_listedMailboxList[0]; // get top element
+ m_listedMailboxList.RemoveElementAt(0); // XP_ListRemoveTopObject(fListedMailboxList);
+ if (mb)
+ {
+ if (FolderNeedsACLInitialized(PromiseFlatCString(mb->GetMailboxName()).get()))
+ {
+ char *onlineName = nullptr;
+ m_runningUrl->AllocateServerPath(PromiseFlatCString(mb->GetMailboxName()).get(),
+ mb->GetDelimiter(), &onlineName);
+ if (onlineName)
+ {
+ RefreshACLForFolder(onlineName);
+ PR_Free(onlineName);
+ }
+ }
+ PercentProgressUpdateEvent(NULL, cnt, total);
+ delete mb; // this is the last time we're using the list, so delete the entries here
+ cnt++;
+ }
+ } while (mb && !DeathSignalReceived());
+ }
+ }
+}
+
+bool nsImapProtocol::FolderNeedsACLInitialized(const char *folderName)
+{
+ bool rv = false;
+ m_imapServerSink->FolderNeedsACLInitialized(nsDependentCString(folderName), &rv);
+ return rv;
+}
+
+void nsImapProtocol::MailboxDiscoveryFinished()
+{
+ if (!DeathSignalReceived() && !GetSubscribingNow() &&
+ ((m_hierarchyNameState == kNoOperationInProgress) ||
+ (m_hierarchyNameState == kListingForInfoAndDiscovery)))
+ {
+ nsIMAPNamespace *ns = nullptr;
+ m_hostSessionList->GetDefaultNamespaceOfTypeForHost(GetImapServerKey(), kPersonalNamespace, ns);
+ const char *personalDir = ns ? ns->GetPrefix() : 0;
+
+ bool trashFolderExists = false;
+ bool usingSubscription = false;
+ m_hostSessionList->GetOnlineTrashFolderExistsForHost(GetImapServerKey(), trashFolderExists);
+ m_hostSessionList->GetHostIsUsingSubscription(GetImapServerKey(),usingSubscription);
+ if (!trashFolderExists && GetDeleteIsMoveToTrash() && usingSubscription)
+ {
+ // maybe we're not subscribed to the Trash folder
+ if (personalDir)
+ {
+ nsCString originalTrashName(CreatePossibleTrashName(personalDir));
+ m_hierarchyNameState = kDiscoverTrashFolderInProgress;
+ List(originalTrashName.get(), true);
+ m_hierarchyNameState = kNoOperationInProgress;
+ }
+ }
+
+ // There is no Trash folder (either LIST'd or LSUB'd), and we're using the
+ // Delete-is-move-to-Trash model, and there is a personal namespace
+ if (!trashFolderExists && GetDeleteIsMoveToTrash() && ns)
+ {
+ nsCString trashName(CreatePossibleTrashName(ns->GetPrefix()));
+ nsCString onlineTrashName;
+ m_runningUrl->AllocateServerPath(trashName.get(), ns->GetDelimiter(),
+ getter_Copies(onlineTrashName));
+
+ GetServerStateParser().SetReportingErrors(false);
+ bool created = CreateMailboxRespectingSubscriptions(onlineTrashName.get());
+ GetServerStateParser().SetReportingErrors(true);
+
+ // force discovery of new trash folder.
+ if (created)
+ {
+ m_hierarchyNameState = kDiscoverTrashFolderInProgress;
+ List(onlineTrashName.get(), false);
+ m_hierarchyNameState = kNoOperationInProgress;
+ }
+ else
+ m_hostSessionList->SetOnlineTrashFolderExistsForHost(GetImapServerKey(), true);
+ } //if trash folder doesn't exist
+ m_hostSessionList->SetHaveWeEverDiscoveredFoldersForHost(GetImapServerKey(), true);
+
+ // notify front end that folder discovery is complete....
+ if (m_imapServerSink)
+ m_imapServerSink->DiscoveryDone();
+ }
+}
+
+// returns the mailboxName with the IMAP delimiter removed from the tail end
+void nsImapProtocol::RemoveHierarchyDelimiter(nsCString &mailboxName)
+{
+ char onlineDelimiter[2] = {0, 0};
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->GetOnlineDelimiter(&onlineDelimiter[0]);
+ // take the hierarchy delimiter off the end, if any.
+ if (onlineDelimiter[0])
+ mailboxName.Trim(onlineDelimiter, false, true);
+}
+
+// returns true is the create succeeded (regardless of subscription changes)
+bool nsImapProtocol::CreateMailboxRespectingSubscriptions(const char *mailboxName)
+{
+ CreateMailbox(mailboxName);
+ bool rv = GetServerStateParser().LastCommandSuccessful();
+ if (rv && m_autoSubscribe) // auto-subscribe is on
+ {
+ // create succeeded - let's subscribe to it
+ bool reportingErrors = GetServerStateParser().GetReportingErrors();
+ GetServerStateParser().SetReportingErrors(false);
+ nsCString mailboxWODelim(mailboxName);
+ RemoveHierarchyDelimiter(mailboxWODelim);
+ OnSubscribe(mailboxWODelim.get());
+ GetServerStateParser().SetReportingErrors(reportingErrors);
+ }
+ return rv;
+}
+
+void nsImapProtocol::CreateMailbox(const char *mailboxName)
+{
+ ProgressEventFunctionUsingId (IMAP_STATUS_CREATING_MAILBOX);
+
+ IncrementCommandTagNumber();
+
+ nsCString escapedName;
+ CreateEscapedMailboxName(mailboxName, escapedName);
+ nsCString command(GetServerCommandTag());
+ command += " create \"";
+ command += escapedName;
+ command += "\"" CRLF;
+
+ nsresult rv = SendData(command.get());
+ if(NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+ // If that failed, let's list the parent folder to see if
+ // it allows inferiors, so we won't try to create sub-folders
+ // of the parent folder again in the current session.
+ if (GetServerStateParser().CommandFailed())
+ {
+ // Figure out parent folder name.
+ nsCString parentName(mailboxName);
+ char hierarchyDelimiter;
+ m_runningUrl->GetOnlineSubDirSeparator(&hierarchyDelimiter);
+ int32_t leafPos = parentName.RFindChar(hierarchyDelimiter);
+ if (leafPos > 0)
+ {
+ parentName.SetLength(leafPos);
+ List(parentName.get(), false);
+ // We still want the caller to know the create failed, so restore that.
+ GetServerStateParser().SetCommandFailed(true);
+ }
+ }
+}
+
+void nsImapProtocol::DeleteMailbox(const char *mailboxName)
+{
+
+ // check if this connection currently has the folder to be deleted selected.
+ // If so, we should close it because at least some UW servers don't like you deleting
+ // a folder you have open.
+ if (FolderIsSelected(mailboxName))
+ Close();
+
+
+ ProgressEventFunctionUsingIdWithString (IMAP_STATUS_DELETING_MAILBOX, mailboxName);
+
+ IncrementCommandTagNumber();
+
+ nsCString escapedName;
+ CreateEscapedMailboxName(mailboxName, escapedName);
+ nsCString command(GetServerCommandTag());
+ command += " delete \"";
+ command += escapedName;
+ command += "\"" CRLF;
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::RenameMailbox(const char *existingName,
+ const char *newName)
+{
+ // just like DeleteMailbox; Some UW servers don't like it.
+ if (FolderIsSelected(existingName))
+ Close();
+
+ ProgressEventFunctionUsingIdWithString (IMAP_STATUS_RENAMING_MAILBOX, existingName);
+
+ IncrementCommandTagNumber();
+
+ nsCString escapedExistingName;
+ nsCString escapedNewName;
+ CreateEscapedMailboxName(existingName, escapedExistingName);
+ CreateEscapedMailboxName(newName, escapedNewName);
+ nsCString command(GetServerCommandTag());
+ command += " rename \"";
+ command += escapedExistingName;
+ command += "\" \"";
+ command += escapedNewName;
+ command += "\"" CRLF;
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+nsCString nsImapProtocol::CreatePossibleTrashName(const char *prefix)
+{
+ nsCString returnTrash(prefix);
+ returnTrash += m_trashFolderName;
+ return returnTrash;
+}
+
+bool nsImapProtocol::GetListSubscribedIsBrokenOnServer()
+{
+ // This is a workaround for an issue with LIST(SUBSCRIBED) crashing older versions of Zimbra
+ if (GetServerStateParser().GetServerID().Find("\"NAME\" \"Zimbra\"", CaseInsensitiveCompare) != kNotFound) {
+ nsCString serverID(GetServerStateParser().GetServerID());
+ int start = serverID.Find("\"VERSION\" \"", CaseInsensitiveCompare) + 11;
+ int length = serverID.Find("\" ", start, CaseInsensitiveCompare);
+ const nsDependentCSubstring serverVersionSubstring = Substring(serverID, start, length);
+ nsCString serverVersionStr(serverVersionSubstring);
+ Version serverVersion(serverVersionStr.get());
+ Version sevenTwoThree("7.2.3_");
+ Version eightZeroZero("8.0.0_");
+ Version eightZeroThree("8.0.3_");
+ if ((serverVersion < sevenTwoThree) ||
+ ((serverVersion >= eightZeroZero) && (serverVersion < eightZeroThree)))
+ return true;
+ }
+ return false;
+}
+
+void nsImapProtocol::Lsub(const char *mailboxPattern, bool addDirectoryIfNecessary)
+{
+ ProgressEventFunctionUsingId (IMAP_STATUS_LOOKING_FOR_MAILBOX);
+
+ IncrementCommandTagNumber();
+
+ char *boxnameWithOnlineDirectory = nullptr;
+ if (addDirectoryIfNecessary)
+ m_runningUrl->AddOnlineDirectoryIfNecessary(mailboxPattern, &boxnameWithOnlineDirectory);
+
+ nsCString escapedPattern;
+ CreateEscapedMailboxName(boxnameWithOnlineDirectory ?
+ boxnameWithOnlineDirectory :
+ mailboxPattern, escapedPattern);
+
+ nsCString command (GetServerCommandTag());
+ if ((GetServerStateParser().GetCapabilityFlag() & kHasListExtendedCapability) &&
+ !GetListSubscribedIsBrokenOnServer())
+ command += " list (subscribed)";
+ else
+ command += " lsub";
+ command += " \"\" \"";
+ command += escapedPattern;
+ command += "\"" CRLF;
+
+ PR_Free(boxnameWithOnlineDirectory);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail(command.get(), true);
+}
+
+void nsImapProtocol::List(const char *mailboxPattern, bool addDirectoryIfNecessary,
+ bool useXLIST)
+{
+ ProgressEventFunctionUsingId (IMAP_STATUS_LOOKING_FOR_MAILBOX);
+
+ IncrementCommandTagNumber();
+
+ char *boxnameWithOnlineDirectory = nullptr;
+ if (addDirectoryIfNecessary)
+ m_runningUrl->AddOnlineDirectoryIfNecessary(mailboxPattern, &boxnameWithOnlineDirectory);
+
+ nsCString escapedPattern;
+ CreateEscapedMailboxName(boxnameWithOnlineDirectory ?
+ boxnameWithOnlineDirectory :
+ mailboxPattern, escapedPattern);
+
+ nsCString command (GetServerCommandTag());
+ command += useXLIST ?
+ " xlist \"\" \"" : " list \"\" \"";
+ command += escapedPattern;
+ command += "\"" CRLF;
+
+ PR_Free(boxnameWithOnlineDirectory);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail(command.get(), true);
+}
+
+void nsImapProtocol::Subscribe(const char *mailboxName)
+{
+ ProgressEventFunctionUsingIdWithString (IMAP_STATUS_SUBSCRIBE_TO_MAILBOX, mailboxName);
+
+ IncrementCommandTagNumber();
+
+ nsCString escapedName;
+ CreateEscapedMailboxName(mailboxName, escapedName);
+
+ nsCString command (GetServerCommandTag());
+ command += " subscribe \"";
+ command += escapedName;
+ command += "\"" CRLF;
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::Unsubscribe(const char *mailboxName)
+{
+ ProgressEventFunctionUsingIdWithString (IMAP_STATUS_UNSUBSCRIBE_MAILBOX, mailboxName);
+ IncrementCommandTagNumber();
+
+ nsCString escapedName;
+ CreateEscapedMailboxName(mailboxName, escapedName);
+
+ nsCString command (GetServerCommandTag());
+ command += " unsubscribe \"";
+ command += escapedName;
+ command += "\"" CRLF;
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::Idle()
+{
+ IncrementCommandTagNumber();
+
+ if (m_urlInProgress)
+ return;
+ nsAutoCString command (GetServerCommandTag());
+ command += " IDLE" CRLF;
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ {
+ m_idle = true;
+ // we'll just get back a continuation char at first.
+ // + idling...
+ ParseIMAPandCheckForNewMail();
+ // this will cause us to get notified of data or the socket getting closed.
+ // That notification will occur on the socket transport thread - we just
+ // need to poke a monitor so the imap thread will do a blocking read
+ // and parse the data.
+ nsCOMPtr <nsIAsyncInputStream> asyncInputStream = do_QueryInterface(m_inputStream);
+ if (asyncInputStream)
+ asyncInputStream->AsyncWait(this, 0, 0, nullptr);
+ }
+}
+
+// until we can fix the hang on shutdown waiting for server
+// responses, we need to not wait for the server response
+// on shutdown.
+void nsImapProtocol::EndIdle(bool waitForResponse /* = true */)
+{
+ // clear the async wait - otherwise, we seem to have trouble doing a blocking read
+ nsCOMPtr <nsIAsyncInputStream> asyncInputStream = do_QueryInterface(m_inputStream);
+ if (asyncInputStream)
+ asyncInputStream->AsyncWait(nullptr, 0, 0, nullptr);
+ nsresult rv = SendData("DONE" CRLF);
+ // set a short timeout if we don't want to wait for a response
+ if (m_transport && !waitForResponse)
+ m_transport->SetTimeout(nsISocketTransport::TIMEOUT_READ_WRITE, 5);
+ if (NS_SUCCEEDED(rv))
+ {
+ m_idle = false;
+ ParseIMAPandCheckForNewMail();
+ }
+ m_imapMailFolderSink = nullptr;
+}
+
+
+void nsImapProtocol::Search(const char * searchCriteria,
+ bool useUID,
+ bool notifyHit /* true */)
+{
+ m_notifySearchHit = notifyHit;
+ ProgressEventFunctionUsingId (IMAP_STATUS_SEARCH_MAILBOX);
+ IncrementCommandTagNumber();
+
+ nsCString protocolString(GetServerCommandTag());
+ // the searchCriteria string contains the 'search ....' string
+ if (useUID)
+ protocolString.Append(" uid");
+ protocolString.Append(" ");
+ protocolString.Append(searchCriteria);
+ // the search criteria can contain string literals, which means we
+ // need to break up the protocol string by CRLF's, and after sending CRLF,
+ // wait for the server to respond OK before sending more data
+ nsresult rv;
+ int32_t crlfIndex;
+ while (crlfIndex = protocolString.Find(CRLF), crlfIndex != kNotFound && !DeathSignalReceived())
+ {
+ nsAutoCString tempProtocolString;
+ tempProtocolString = StringHead(protocolString, crlfIndex + 2);
+ rv = SendData(tempProtocolString.get());
+ if (NS_FAILED(rv))
+ return;
+ ParseIMAPandCheckForNewMail();
+ protocolString.Cut(0, crlfIndex + 2);
+ }
+ protocolString.Append(CRLF);
+
+ rv = SendData(protocolString.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::Copy(const char * messageList,
+ const char *destinationMailbox,
+ bool idsAreUid)
+{
+ IncrementCommandTagNumber();
+
+ nsCString escapedDestination;
+ CreateEscapedMailboxName(destinationMailbox, escapedDestination);
+
+ // turn messageList back into key array and then back into a message id list,
+ // but use the flag state to handle ranges correctly.
+ nsCString messageIdList;
+ nsTArray<nsMsgKey> msgKeys;
+ if (idsAreUid)
+ ParseUidString(messageList, msgKeys);
+
+ int32_t msgCountLeft = msgKeys.Length();
+ uint32_t msgsHandled = 0;
+
+ do
+ {
+ nsCString idString;
+
+ uint32_t msgsToHandle = msgCountLeft;
+ if (idsAreUid)
+ AllocateImapUidString(msgKeys.Elements() + msgsHandled, msgsToHandle, m_flagState, idString);
+ else
+ idString.Assign(messageList);
+
+ msgsHandled += msgsToHandle;
+ msgCountLeft -= msgsToHandle;
+
+ IncrementCommandTagNumber();
+ nsAutoCString protocolString(GetServerCommandTag());
+ if (idsAreUid)
+ protocolString.Append(" uid");
+ // If it's a MOVE operation on aol servers then use 'xaol-move' cmd.
+ if ((m_imapAction == nsIImapUrl::nsImapOnlineMove) &&
+ GetServerStateParser().ServerIsAOLServer())
+ protocolString.Append(" xaol-move ");
+ else if ((m_imapAction == nsIImapUrl::nsImapOnlineMove) &&
+ GetServerStateParser().GetCapabilityFlag() & kHasMoveCapability)
+ protocolString.Append(" move ");
+ else
+ protocolString.Append(" copy ");
+
+
+ protocolString.Append(idString);
+ protocolString.Append(" \"");
+ protocolString.Append(escapedDestination);
+ protocolString.Append("\"" CRLF);
+
+ nsresult rv = SendData(protocolString.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail(protocolString.get());
+ }
+ while (msgCountLeft > 0 && !DeathSignalReceived());
+}
+
+void nsImapProtocol::NthLevelChildList(const char* onlineMailboxPrefix,
+ int32_t depth)
+{
+ NS_ASSERTION (depth >= 0,
+ "Oops ... depth must be equal or greater than 0");
+ if (depth < 0) return;
+
+ nsCString truncatedPrefix (onlineMailboxPrefix);
+ PRUnichar slash = '/';
+ if (truncatedPrefix.Last() == slash)
+ truncatedPrefix.SetLength(truncatedPrefix.Length()-1);
+
+ nsAutoCString pattern(truncatedPrefix);
+ nsAutoCString suffix;
+ int count = 0;
+ char separator = 0;
+ m_runningUrl->GetOnlineSubDirSeparator(&separator);
+ suffix.Assign(separator);
+ suffix += '%';
+
+ while (count < depth)
+ {
+ pattern += suffix;
+ count++;
+ List(pattern.get(), false);
+ }
+}
+
+void nsImapProtocol::ProcessAuthenticatedStateURL()
+{
+ nsImapAction imapAction;
+ char * sourceMailbox = nullptr;
+ m_runningUrl->GetImapAction(&imapAction);
+
+ // switch off of the imap url action and take an appropriate action
+ switch (imapAction)
+ {
+ case nsIImapUrl::nsImapLsubFolders:
+ OnLSubFolders();
+ break;
+ case nsIImapUrl::nsImapAppendMsgFromFile:
+ OnAppendMsgFromFile();
+ break;
+ case nsIImapUrl::nsImapDiscoverAllBoxesUrl:
+ NS_ASSERTION (!GetSubscribingNow(),
+ "Oops ... should not get here from subscribe UI");
+ DiscoverMailboxList();
+ break;
+ case nsIImapUrl::nsImapDiscoverAllAndSubscribedBoxesUrl:
+ DiscoverAllAndSubscribedBoxes();
+ break;
+ case nsIImapUrl::nsImapCreateFolder:
+ sourceMailbox = OnCreateServerSourceFolderPathString();
+ OnCreateFolder(sourceMailbox);
+ break;
+ case nsIImapUrl::nsImapEnsureExistsFolder:
+ sourceMailbox = OnCreateServerSourceFolderPathString();
+ OnEnsureExistsFolder(sourceMailbox);
+ break;
+ case nsIImapUrl::nsImapDiscoverChildrenUrl:
+ {
+ char *canonicalParent = nullptr;
+ m_runningUrl->CreateServerSourceFolderPathString(&canonicalParent);
+ if (canonicalParent)
+ {
+ NthLevelChildList(canonicalParent, 2);
+ PR_Free(canonicalParent);
+ }
+ break;
+ }
+ case nsIImapUrl::nsImapSubscribe:
+ sourceMailbox = OnCreateServerSourceFolderPathString();
+ OnSubscribe(sourceMailbox); // used to be called subscribe
+
+ if (GetServerStateParser().LastCommandSuccessful())
+ {
+ bool shouldList;
+ // if url is an external click url, then we should list the folder
+ // after subscribing to it, so we can select it.
+ m_runningUrl->GetExternalLinkUrl(&shouldList);
+ if (shouldList)
+ OnListFolder(sourceMailbox, true);
+ }
+ break;
+ case nsIImapUrl::nsImapUnsubscribe:
+ sourceMailbox = OnCreateServerSourceFolderPathString();
+ OnUnsubscribe(sourceMailbox);
+ break;
+ case nsIImapUrl::nsImapRefreshACL:
+ sourceMailbox = OnCreateServerSourceFolderPathString();
+ RefreshACLForFolder(sourceMailbox);
+ break;
+ case nsIImapUrl::nsImapRefreshAllACLs:
+ OnRefreshAllACLs();
+ break;
+ case nsIImapUrl::nsImapListFolder:
+ sourceMailbox = OnCreateServerSourceFolderPathString();
+ OnListFolder(sourceMailbox, false);
+ break;
+ case nsIImapUrl::nsImapFolderStatus:
+ sourceMailbox = OnCreateServerSourceFolderPathString();
+ OnStatusForFolder(sourceMailbox);
+ break;
+ case nsIImapUrl::nsImapRefreshFolderUrls:
+ sourceMailbox = OnCreateServerSourceFolderPathString();
+ XMailboxInfo(sourceMailbox);
+ if (GetServerStateParser().LastCommandSuccessful())
+ SetFolderAdminUrl(sourceMailbox);
+ break;
+ case nsIImapUrl::nsImapDeleteFolder:
+ sourceMailbox = OnCreateServerSourceFolderPathString();
+ OnDeleteFolder(sourceMailbox);
+ break;
+ case nsIImapUrl::nsImapRenameFolder:
+ sourceMailbox = OnCreateServerSourceFolderPathString();
+ OnRenameFolder(sourceMailbox);
+ break;
+ case nsIImapUrl::nsImapMoveFolderHierarchy:
+ sourceMailbox = OnCreateServerSourceFolderPathString();
+ OnMoveFolderHierarchy(sourceMailbox);
+ break;
+ case nsIImapUrl::nsImapVerifylogon:
+ break;
+ default:
+ break;
+ }
+ PR_Free(sourceMailbox);
+}
+
+void nsImapProtocol::ProcessAfterAuthenticated()
+{
+ // if we're a netscape server, and we haven't got the admin url, get it
+ bool hasAdminUrl = true;
+
+ if (NS_SUCCEEDED(m_hostSessionList->GetHostHasAdminURL(GetImapServerKey(), hasAdminUrl))
+ && !hasAdminUrl)
+ {
+ if (GetServerStateParser().ServerHasServerInfo())
+ {
+ XServerInfo();
+ if (GetServerStateParser().LastCommandSuccessful() && m_imapServerSink)
+ {
+ m_imapServerSink->SetMailServerUrls(GetServerStateParser().GetMailAccountUrl(),
+ GetServerStateParser().GetManageListsUrl(),
+ GetServerStateParser().GetManageFiltersUrl());
+ // we've tried to ask for it, so don't try again this session.
+ m_hostSessionList->SetHostHasAdminURL(GetImapServerKey(), true);
+ }
+ }
+ else if (GetServerStateParser().ServerIsNetscape3xServer())
+ {
+ Netscape();
+ if (GetServerStateParser().LastCommandSuccessful() && m_imapServerSink)
+ m_imapServerSink->SetMailServerUrls(GetServerStateParser().GetMailAccountUrl(),
+ EmptyCString(), EmptyCString());
+ }
+ }
+
+ if (GetServerStateParser().ServerHasNamespaceCapability())
+ {
+ bool nameSpacesOverridable = false;
+ bool haveNameSpacesForHost = false;
+ m_hostSessionList->GetNamespacesOverridableForHost(GetImapServerKey(), nameSpacesOverridable);
+ m_hostSessionList->GetGotNamespacesForHost(GetImapServerKey(), haveNameSpacesForHost);
+
+ // mscott: VERIFY THIS CLAUSE!!!!!!!
+ if (nameSpacesOverridable && !haveNameSpacesForHost)
+ Namespace();
+ }
+
+ // If the server supports compression, turn it on now.
+ // Choosing this spot (after login has finished) because
+ // many proxies (e.g. perdition, nginx) talk IMAP to the
+ // client until login is finished, then hand off to the
+ // backend. If we enable compression early the proxy
+ // will be confused.
+ if (UseCompressDeflate())
+ StartCompressDeflate();
+
+ if ((GetServerStateParser().GetCapabilityFlag() & kHasEnableCapability) &&
+ UseCondStore())
+ EnableCondStore();
+ if ((GetServerStateParser().GetCapabilityFlag() & kHasIDCapability) &&
+ m_sendID)
+ {
+ ID();
+ if (m_imapServerSink && !GetServerStateParser().GetServerID().IsEmpty())
+ m_imapServerSink->SetServerID(GetServerStateParser().GetServerID());
+ }
+}
+
+void nsImapProtocol::SetupMessageFlagsString(nsCString& flagString,
+ imapMessageFlagsType flags,
+ uint16_t userFlags)
+{
+ if (flags & kImapMsgSeenFlag)
+ flagString.Append("\\Seen ");
+ if (flags & kImapMsgAnsweredFlag)
+ flagString.Append("\\Answered ");
+ if (flags & kImapMsgFlaggedFlag)
+ flagString.Append("\\Flagged ");
+ if (flags & kImapMsgDeletedFlag)
+ flagString.Append("\\Deleted ");
+ if (flags & kImapMsgDraftFlag)
+ flagString.Append("\\Draft ");
+ if (flags & kImapMsgRecentFlag)
+ flagString.Append("\\Recent ");
+ if ((flags & kImapMsgForwardedFlag) &&
+ (userFlags & kImapMsgSupportForwardedFlag))
+ flagString.Append("$Forwarded "); // Not always available
+ if ((flags & kImapMsgMDNSentFlag) && (
+ userFlags & kImapMsgSupportMDNSentFlag))
+ flagString.Append("$MDNSent "); // Not always available
+
+ // eat the last space
+ if (!flagString.IsEmpty())
+ flagString.SetLength(flagString.Length()-1);
+}
+
+void nsImapProtocol::ProcessStoreFlags(const nsCString &messageIdsString,
+ bool idsAreUids,
+ imapMessageFlagsType flags,
+ bool addFlags)
+{
+ nsCString flagString;
+
+ uint16_t userFlags = GetServerStateParser().SupportsUserFlags();
+ uint16_t settableFlags = GetServerStateParser().SettablePermanentFlags();
+
+ if (!addFlags && (flags & userFlags) && !(flags & settableFlags))
+ {
+ if (m_runningUrl)
+ m_runningUrl->SetExtraStatus(nsIImapUrl::ImapStatusFlagsNotSettable);
+ return; // if cannot set any of the flags bail out
+ }
+
+ if (addFlags)
+ flagString = "+Flags (";
+ else
+ flagString = "-Flags (";
+
+ if (flags & kImapMsgSeenFlag && kImapMsgSeenFlag & settableFlags)
+ flagString .Append("\\Seen ");
+ if (flags & kImapMsgAnsweredFlag && kImapMsgAnsweredFlag & settableFlags)
+ flagString .Append("\\Answered ");
+ if (flags & kImapMsgFlaggedFlag && kImapMsgFlaggedFlag & settableFlags)
+ flagString .Append("\\Flagged ");
+ if (flags & kImapMsgDeletedFlag && kImapMsgDeletedFlag & settableFlags)
+ flagString .Append("\\Deleted ");
+ if (flags & kImapMsgDraftFlag && kImapMsgDraftFlag & settableFlags)
+ flagString .Append("\\Draft ");
+ if (flags & kImapMsgForwardedFlag && kImapMsgSupportForwardedFlag & userFlags)
+ flagString .Append("$Forwarded "); // if supported
+ if (flags & kImapMsgMDNSentFlag && kImapMsgSupportMDNSentFlag & userFlags)
+ flagString .Append("$MDNSent "); // if supported
+
+ if (flagString.Length() > 8) // if more than "+Flags ("
+ {
+ // replace the final space with ')'
+ flagString.SetCharAt(')',flagString.Length() - 1);
+
+ Store(messageIdsString, flagString.get(), idsAreUids);
+ if (m_runningUrl && idsAreUids)
+ {
+ nsCString messageIdString;
+ m_runningUrl->GetListOfMessageIds(messageIdString);
+ nsTArray<nsMsgKey> msgKeys;
+ ParseUidString(messageIdString.get(), msgKeys);
+
+ int32_t msgCount = msgKeys.Length();
+ for (int32_t i = 0; i < msgCount; i++)
+ {
+ bool found;
+ imapMessageFlagsType resultFlags;
+ // check if the flags were added/removed, and if the uid really exists.
+ nsresult rv = GetFlagsForUID(msgKeys[i], &found, &resultFlags, nullptr);
+ if (NS_FAILED(rv) || !found ||
+ (addFlags && ((flags & resultFlags) != flags)) ||
+ (!addFlags && ((flags & resultFlags) != 0)))
+ {
+ m_runningUrl->SetExtraStatus(nsIImapUrl::ImapStatusFlagChangeFailed);
+ break;
+ }
+ }
+
+ }
+ }
+}
+
+
+void nsImapProtocol::Close(bool shuttingDown /* = false */,
+ bool waitForResponse /* = true */)
+{
+ IncrementCommandTagNumber();
+
+ nsCString command(GetServerCommandTag());
+ command.Append(" close" CRLF);
+
+ if (!shuttingDown)
+ ProgressEventFunctionUsingId (IMAP_STATUS_CLOSE_MAILBOX);
+
+ GetServerStateParser().ResetFlagInfo();
+
+ nsresult rv = SendData(command.get());
+ if (m_transport && shuttingDown)
+ m_transport->SetTimeout(nsISocketTransport::TIMEOUT_READ_WRITE, 5);
+
+ if (NS_SUCCEEDED(rv) && waitForResponse)
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::XAOL_Option(const char *option)
+{
+ IncrementCommandTagNumber();
+
+ nsCString command(GetServerCommandTag());
+ command.Append(" XAOL-OPTION ");
+ command.Append(option);
+ command.Append(CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ ParseIMAPandCheckForNewMail();
+}
+
+void nsImapProtocol::Check()
+{
+ //ProgressUpdateEvent("Checking mailbox...");
+
+ IncrementCommandTagNumber();
+
+ nsCString command(GetServerCommandTag());
+ command.Append(" check" CRLF);
+
+ nsresult rv = SendData(command.get());
+ if (NS_SUCCEEDED(rv))
+ {
+ m_flagChangeCount = 0;
+ m_lastCheckTime = PR_Now();
+ ParseIMAPandCheckForNewMail();
+ }
+}
+
+nsresult nsImapProtocol::GetMsgWindow(nsIMsgWindow **aMsgWindow)
+{
+ nsresult rv;
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl =
+ do_QueryInterface(m_runningUrl, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!m_imapProtocolSink)
+ return NS_ERROR_FAILURE;
+ return m_imapProtocolSink->GetUrlWindow(mailnewsUrl, aMsgWindow);
+}
+
+/**
+ * Get password from RAM, disk (password manager) or user (dialog)
+ * @return NS_MSG_PASSWORD_PROMPT_CANCELLED
+ * (which is NS_SUCCEEDED!) when user cancelled
+ * NS_FAILED(rv) for other errors
+ */
+nsresult nsImapProtocol::GetPassword(nsCString &password,
+ bool newPasswordRequested)
+{
+ // we are in the imap thread so *NEVER* try to extract the password with UI
+ // if logon redirection has changed the password, use the cookie as the password
+ if (m_overRideUrlConnectionInfo)
+ {
+ password.Assign(m_logonCookie);
+ return NS_OK;
+ }
+
+ NS_ENSURE_TRUE(m_imapServerSink, NS_ERROR_NULL_POINTER);
+ NS_ENSURE_TRUE(m_server, NS_ERROR_NULL_POINTER);
+ nsresult rv;
+ nsCOMPtr<nsIMsgIncomingServer> server = do_QueryReferent(m_server, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Get the password already stored in mem
+ rv = server->GetPassword(password);
+ if (NS_FAILED(rv) || password.IsEmpty())
+ {
+ nsCOMPtr<nsIMsgWindow> msgWindow;
+ GetMsgWindow(getter_AddRefs(msgWindow));
+ NS_ENSURE_TRUE(msgWindow, NS_ERROR_NOT_AVAILABLE); // biff case
+
+ // Get the password from pw manager (harddisk) or user (dialog)
+ nsAutoCString pwd; // GetPasswordWithUI truncates the password on Cancel
+ rv = m_imapServerSink->AsyncGetPassword(this,
+ newPasswordRequested,
+ password);
+ if (password.IsEmpty())
+ {
+ PRIntervalTime sleepTime = kImapSleepTime;
+ m_passwordStatus = NS_OK;
+ ReentrantMonitorAutoEnter mon(m_passwordReadyMonitor);
+ while (m_password.IsEmpty() && !NS_FAILED(m_passwordStatus) &&
+ m_passwordStatus != NS_MSG_PASSWORD_PROMPT_CANCELLED &&
+ !DeathSignalReceived())
+ mon.Wait(sleepTime);
+ rv = m_passwordStatus;
+ password = m_password;
+ }
+ }
+ if (!password.IsEmpty())
+ m_lastPasswordSent = password;
+ return rv;
+}
+
+// This is called from the UI thread.
+NS_IMETHODIMP
+nsImapProtocol::OnPromptStart(bool *aResult)
+{
+ nsresult rv;
+ nsCOMPtr<nsIImapIncomingServer> imapServer = do_QueryReferent(m_server, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsIMsgWindow> msgWindow;
+
+ *aResult = false;
+ GetMsgWindow(getter_AddRefs(msgWindow));
+ nsCString password = m_lastPasswordSent;
+ rv = imapServer->PromptPassword(msgWindow, password);
+ m_password = password;
+ m_passwordStatus = rv;
+ if (!m_password.IsEmpty())
+ *aResult = true;
+
+ // Notify the imap thread that we have a password.
+ ReentrantMonitorAutoEnter passwordMon(m_passwordReadyMonitor);
+ passwordMon.Notify();
+ return rv;
+}
+
+NS_IMETHODIMP
+nsImapProtocol::OnPromptAuthAvailable()
+{
+ nsresult rv;
+ nsCOMPtr<nsIMsgIncomingServer> imapServer = do_QueryReferent(m_server, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+ m_passwordStatus = imapServer->GetPassword(m_password);
+ // Notify the imap thread that we have a password.
+ ReentrantMonitorAutoEnter passwordMon(m_passwordReadyMonitor);
+ passwordMon.Notify();
+ return m_passwordStatus;
+}
+
+NS_IMETHODIMP
+nsImapProtocol::OnPromptCanceled()
+{
+ // A prompt was cancelled, so notify the imap thread.
+ m_passwordStatus = NS_MSG_PASSWORD_PROMPT_CANCELLED;
+ ReentrantMonitorAutoEnter passwordMon(m_passwordReadyMonitor);
+ passwordMon.Notify();
+ return NS_OK;
+}
+
+bool nsImapProtocol::TryToLogon()
+{
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("try to log in"));
+ NS_ENSURE_TRUE(m_imapServerSink, false);
+ bool loginSucceeded = false;
+ bool skipLoop = false;
+ nsAutoCString password;
+ nsAutoCString userName;
+
+ nsresult rv = ChooseAuthMethod();
+ if (NS_FAILED(rv)) // all methods failed
+ {
+ // are there any matching login schemes at all?
+ if (!(GetServerStateParser().GetCapabilityFlag() & m_prefAuthMethods))
+ {
+ // Pref doesn't match server. Now, find an appropriate error msg.
+
+ // pref has plaintext pw & server claims to support encrypted pw
+ if (m_prefAuthMethods == (kHasAuthOldLoginCapability |
+ kHasAuthLoginCapability | kHasAuthPlainCapability) &&
+ GetServerStateParser().GetCapabilityFlag() & kHasCRAMCapability)
+ // tell user to change to encrypted pw
+ AlertUserEventUsingId(IMAP_AUTH_CHANGE_PLAIN_TO_ENCRYPT);
+ // pref has encrypted pw & server claims to support plaintext pw
+ else if (m_prefAuthMethods == kHasCRAMCapability &&
+ GetServerStateParser().GetCapabilityFlag() &
+ (kHasAuthOldLoginCapability | kHasAuthLoginCapability |
+ kHasAuthPlainCapability))
+ {
+ // have SSL
+ if (m_socketType == nsMsgSocketType::SSL ||
+ m_socketType == nsMsgSocketType::alwaysSTARTTLS)
+ // tell user to change to plaintext pw
+ AlertUserEventUsingId(IMAP_AUTH_CHANGE_ENCRYPT_TO_PLAIN_SSL);
+ else
+ // tell user to change to plaintext pw, with big warning
+ AlertUserEventUsingId(IMAP_AUTH_CHANGE_ENCRYPT_TO_PLAIN_NO_SSL);
+ }
+ else
+ // just "change auth method"
+ AlertUserEventUsingId(IMAP_AUTH_MECH_NOT_SUPPORTED);
+
+ skipLoop = true;
+ }
+ else
+ {
+ // try to reset failed methods and try them again
+ ResetAuthMethods();
+ rv = ChooseAuthMethod();
+ if (NS_FAILED(rv)) // all methods failed
+ {
+ PR_LOG(IMAP, PR_LOG_ERROR, ("huch? there are auth methods, and we resetted failed ones, but ChooseAuthMethod still fails."));
+ return false;
+ }
+ }
+ }
+
+ // Get username, either the stored one or from user
+ rv = m_imapServerSink->GetLoginUsername(userName);
+ if (NS_FAILED(rv) || userName.IsEmpty())
+ {
+ // The user hit "Cancel" on the dialog box
+ skipLoop = true;
+ }
+
+ /*
+ * Login can fail for various reasons:
+ * 1. Server claims to support GSSAPI, but it really doesn't.
+ * Or the client doesn't support GSSAPI, or is not logged in yet.
+ * (GSSAPI is a mechanism without password in apps).
+ * 2. Server claims to support CRAM-MD5, but it's broken and will fail despite correct password.
+ * 2.1. Some servers say they support CRAM but are so badly broken that trying it causes
+ * all subsequent login attempts to fail during this connection (bug 231303).
+ * So we use CRAM/NTLM/MSN only if enabled in prefs.
+ * Update: if it affects only some ISPs, we can maybe use the ISP DB
+ * and disable CRAM specifically for these.
+ * 3. Prefs are set to require auth methods which the server doesn't support
+ * (per CAPS or we tried and they failed).
+ * 4. User provided wrong password.
+ * 5. We tried too often and the server shut us down, so even a correct attempt
+ * will now (currently) fail.
+ * The above problems may overlap, e.g. 3. with 1. and 2., and we can't differentiate
+ * between 2. and 4., which is really unfortunate.
+ */
+
+ bool newPasswordRequested = false;
+ // remember the msgWindow before we start trying to logon, because if the
+ // server drops the connection on errors, TellThreadToDie will null out the
+ // protocolsink and we won't be able to get the msgWindow.
+ nsCOMPtr<nsIMsgWindow> msgWindow;
+ GetMsgWindow(getter_AddRefs(msgWindow));
+
+ // This loops over 1) auth methods (only one per loop) and 2) password tries (with UI)
+ while (!loginSucceeded && !skipLoop && !DeathSignalReceived())
+ {
+ // Get password
+ if (m_currentAuthMethod != kHasAuthGssApiCapability && // GSSAPI uses no pw in apps
+ m_currentAuthMethod != kHasAuthExternalCapability &&
+ m_currentAuthMethod != kHasAuthNoneCapability)
+ {
+ rv = GetPassword(password, newPasswordRequested);
+ newPasswordRequested = false;
+ if (rv == NS_MSG_PASSWORD_PROMPT_CANCELLED || NS_FAILED(rv))
+ {
+ PR_LOG(IMAP, PR_LOG_ERROR, ("IMAP: password prompt failed or user canceled it"));
+ break;
+ }
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("got new password"));
+ }
+
+ bool lastReportingErrors = GetServerStateParser().GetReportingErrors();
+ GetServerStateParser().SetReportingErrors(false); // turn off errors - we'll put up our own.
+
+ rv = AuthLogin(userName.get(), password, m_currentAuthMethod);
+
+ GetServerStateParser().SetReportingErrors(lastReportingErrors); // restore error reports
+ loginSucceeded = NS_SUCCEEDED(rv);
+
+ if (!loginSucceeded)
+ {
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("authlogin failed"));
+ MarkAuthMethodAsFailed(m_currentAuthMethod);
+ rv = ChooseAuthMethod(); // change m_currentAuthMethod to try other one next round
+
+ if (NS_FAILED(rv)) // all methods failed
+ {
+ if (m_prefAuthMethods == kHasAuthGssApiCapability)
+ {
+ // GSSAPI failed, and it's the only available method,
+ // and it's password-less, so nothing left to do.
+ AlertUserEventUsingId(IMAP_AUTH_GSSAPI_FAILED);
+ break;
+ }
+
+ // The reason that we failed might be a wrong password, so
+ // ask user what to do
+ PR_LOG(IMAP, PR_LOG_WARN, ("IMAP: ask user what to do (after login failed): new passwort, retry, cancel"));
+ if (!m_imapServerSink)
+ break;
+ // if there's no msg window, don't forget the password
+ if (!msgWindow)
+ break;
+ int32_t buttonPressed = 1;
+ rv = m_imapServerSink->PromptLoginFailed(msgWindow,
+ &buttonPressed);
+ if (NS_FAILED(rv))
+ break;
+ if (buttonPressed == 2) // 'New password' button
+ {
+ PR_LOG(IMAP, PR_LOG_WARN, ("new password button pressed."));
+ // Forget the current password
+ password.Truncate();
+ m_hostSessionList->SetPasswordForHost(GetImapServerKey(), nullptr);
+ m_imapServerSink->ForgetPassword();
+ m_password.Truncate();
+ PR_LOG(IMAP, PR_LOG_WARN, ("password resetted (nulled)"));
+ newPasswordRequested = true;
+ // Will call GetPassword() in beginning of next loop
+
+ // Try all possible auth methods again with the new password.
+ ResetAuthMethods();
+ }
+ else if (buttonPressed == 0) // Retry button
+ {
+ PR_LOG(IMAP, PR_LOG_WARN, ("retry button pressed"));
+ // Try all possible auth methods again
+ ResetAuthMethods();
+ }
+ else if (buttonPressed == 1) // Cancel button
+ {
+ PR_LOG(IMAP, PR_LOG_WARN, ("cancel button pressed"));
+ break; // Abort quickly
+ }
+
+ // TODO what is this for? When does it get set to != unknown again?
+ m_currentBiffState = nsIMsgFolder::nsMsgBiffState_Unknown;
+ SendSetBiffIndicatorEvent(m_currentBiffState);
+ } // all methods failed
+ } // login failed
+ } // while
+
+ if (loginSucceeded)
+ {
+ PR_LOG(IMAP, PR_LOG_DEBUG, ("login succeeded"));
+ bool passwordAlreadyVerified;
+ m_hostSessionList->SetPasswordForHost(GetImapServerKey(), password.get());
+ rv = m_hostSessionList->GetPasswordVerifiedOnline(GetImapServerKey(), passwordAlreadyVerified);
+ if (NS_SUCCEEDED(rv) && !passwordAlreadyVerified)
+ m_hostSessionList->SetPasswordVerifiedOnline(GetImapServerKey());
+ bool imapPasswordIsNew = !passwordAlreadyVerified;
+ if (imapPasswordIsNew)
+ {
+ if (m_currentBiffState == nsIMsgFolder::nsMsgBiffState_Unknown)
+ {
+ m_currentBiffState = nsIMsgFolder::nsMsgBiffState_NoMail;
+ SendSetBiffIndicatorEvent(m_currentBiffState);
+ }
+ m_imapServerSink->SetUserAuthenticated(true);
+ }
+
+ nsImapAction imapAction;
+ m_runningUrl->GetImapAction(&imapAction);
+ // We don't want to do any more processing if we're just
+ // verifying the ability to logon because it can leave us in
+ // a half-constructed state.
+ if (imapAction != nsIImapUrl::nsImapVerifylogon)
+ ProcessAfterAuthenticated();
+ }
+ else // login failed
+ {
+ PR_LOG(IMAP, PR_LOG_ERROR, ("login failed entirely"));
+ m_currentBiffState = nsIMsgFolder::nsMsgBiffState_Unknown;
+ SendSetBiffIndicatorEvent(m_currentBiffState);
+ HandleCurrentUrlError();
+ SetConnectionStatus(NS_ERROR_FAILURE); // stop netlib
+ }
+
+ return loginSucceeded;
+}
+
+void nsImapProtocol::UpdateFolderQuotaData(nsCString& aQuotaRoot, uint32_t aUsed, uint32_t aMax)
+{
+ NS_ASSERTION(m_imapMailFolderSink, "m_imapMailFolderSink is null!");
+
+ m_imapMailFolderSink->SetFolderQuotaData(aQuotaRoot, aUsed, aMax);
+}
+
+void nsImapProtocol::GetQuotaDataIfSupported(const char *aBoxName)
+{
+ // If server doesn't have quota support, don't do anything
+ if (! (GetServerStateParser().GetCapabilityFlag() & kQuotaCapability))
+ return;
+
+ // If it's an aol server then only issue cmd for INBOX (since all
+ // other AOL mailboxes are virtual and don't support all imap cmds).
+ nsresult rv;
+ nsCOMPtr<nsIImapIncomingServer> imapServer = do_QueryReferent(m_server, &rv);
+ if (NS_FAILED(rv))
+ return;
+
+ nsCString escapedName;
+ CreateEscapedMailboxName(aBoxName, escapedName);
+
+ IncrementCommandTagNumber();
+
+ nsAutoCString quotacommand(GetServerCommandTag());
+ quotacommand.Append(NS_LITERAL_CSTRING(" getquotaroot \""));
+ quotacommand.Append(escapedName);
+ quotacommand.Append(NS_LITERAL_CSTRING("\"" CRLF));
+
+ NS_ASSERTION(m_imapMailFolderSink, "m_imapMailFolderSink is null!");
+ if (m_imapMailFolderSink)
+ m_imapMailFolderSink->SetFolderQuotaCommandIssued(true);
+
+ nsresult quotarv = SendData(quotacommand.get());
+ if (NS_SUCCEEDED(quotarv))
+ ParseIMAPandCheckForNewMail(nullptr, true); // don't display errors.
+}
+
+bool
+nsImapProtocol::GetDeleteIsMoveToTrash()
+{
+ bool rv = false;
+ NS_ASSERTION (m_hostSessionList, "fatal... null host session list");
+ if (m_hostSessionList)
+ m_hostSessionList->GetDeleteIsMoveToTrashForHost(GetImapServerKey(), rv);
+ return rv;
+}
+
+bool
+nsImapProtocol::GetShowDeletedMessages()
+{
+ bool rv = false;
+ if (m_hostSessionList)
+ m_hostSessionList->GetShowDeletedMessagesForHost(GetImapServerKey(), rv);
+ return rv;
+}
+
+NS_IMETHODIMP nsImapProtocol::OverrideConnectionInfo(const PRUnichar *pHost, uint16_t pPort, const char *pCookieData)
+{
+ m_logonHost = NS_LossyConvertUTF16toASCII(pHost);
+ m_logonPort = pPort;
+ m_logonCookie = pCookieData;
+ m_overRideUrlConnectionInfo = true;
+ return NS_OK;
+}
+
+bool nsImapProtocol::CheckNeeded()
+{
+ if (m_flagChangeCount >= kFlagChangesBeforeCheck)
+ return true;
+
+ int32_t deltaInSeconds;
+
+ PRTime2Seconds(PR_Now() - m_lastCheckTime, &deltaInSeconds);
+
+ return (deltaInSeconds >= kMaxSecondsBeforeCheck);
+}
+
+bool nsImapProtocol::UseCondStore()
+{
+ // Check that the server is capable of cond store, and the user
+ // hasn't disabled the use of constore for this server.
+ return m_useCondStore &&
+ GetServerStateParser().GetCapabilityFlag() & kHasCondStoreCapability &&
+ GetServerStateParser().fUseModSeq;
+}
+
+bool nsImapProtocol::UseCompressDeflate()
+{
+ // Check that the server is capable of compression, and the user
+ // hasn't disabled the use of compression for this server.
+ return m_useCompressDeflate &&
+ GetServerStateParser().GetCapabilityFlag() & kHasCompressDeflateCapability;
+}
+
+//////////////////////////////////////////////////////////////////////////////////////////////
+// The following is the implementation of nsImapMockChannel and an intermediary
+// imap steam listener. The stream listener is used to make a clean binding between the
+// imap mock channel and the memory cache channel (if we are reading from the cache)
+//////////////////////////////////////////////////////////////////////////////////////////////
+
+// WARNING: the cache stream listener is intended to be accessed from the UI thread!
+// it will NOT create another proxy for the stream listener that gets passed in...
+class nsImapCacheStreamListener : public nsIStreamListener
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIREQUESTOBSERVER
+ NS_DECL_NSISTREAMLISTENER
+
+ nsImapCacheStreamListener ();
+ virtual ~nsImapCacheStreamListener();
+
+ nsresult Init(nsIStreamListener * aStreamListener, nsIImapMockChannel * aMockChannelToUse);
+protected:
+ nsCOMPtr<nsIImapMockChannel> mChannelToUse;
+ nsCOMPtr<nsIStreamListener> mListener;
+};
+
+NS_IMPL_ADDREF(nsImapCacheStreamListener)
+NS_IMPL_RELEASE(nsImapCacheStreamListener)
+
+NS_INTERFACE_MAP_BEGIN(nsImapCacheStreamListener)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIStreamListener)
+ NS_INTERFACE_MAP_ENTRY(nsIRequestObserver)
+ NS_INTERFACE_MAP_ENTRY(nsIStreamListener)
+NS_INTERFACE_MAP_END
+
+nsImapCacheStreamListener::nsImapCacheStreamListener()
+{
+}
+
+nsImapCacheStreamListener::~nsImapCacheStreamListener()
+{}
+
+nsresult nsImapCacheStreamListener::Init(nsIStreamListener * aStreamListener, nsIImapMockChannel * aMockChannelToUse)
+{
+ NS_ENSURE_ARG(aStreamListener);
+ NS_ENSURE_ARG(aMockChannelToUse);
+
+ mChannelToUse = aMockChannelToUse;
+ mListener = aStreamListener;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsImapCacheStreamListener::OnStartRequest(nsIRequest *request, nsISupports * aCtxt)
+{
+ if (!mChannelToUse)
+ {
+ NS_ERROR("OnStartRequest called after OnStopRequest");
+ return NS_ERROR_NULL_POINTER;
+ }
+ nsCOMPtr<nsILoadGroup> loadGroup;
+ mChannelToUse->GetLoadGroup(getter_AddRefs(loadGroup));
+ nsCOMPtr<nsIRequest> ourRequest = do_QueryInterface(mChannelToUse);
+ if (loadGroup)
+ loadGroup->AddRequest(ourRequest, nullptr /* context isupports */);
+ return mListener->OnStartRequest(ourRequest, aCtxt);
+}
+
+NS_IMETHODIMP
+nsImapCacheStreamListener::OnStopRequest(nsIRequest *request, nsISupports * aCtxt, nsresult aStatus)
+{
+ if (!mListener)
+ {
+ NS_ERROR("OnStopRequest called twice");
+ return NS_ERROR_NULL_POINTER;
+ }
+ nsresult rv = mListener->OnStopRequest(mChannelToUse, aCtxt, aStatus);
+ nsCOMPtr <nsILoadGroup> loadGroup;
+ mChannelToUse->GetLoadGroup(getter_AddRefs(loadGroup));
+ if (loadGroup)
+ loadGroup->RemoveRequest(mChannelToUse, nullptr, aStatus);
+
+ mListener = nullptr;
+ mChannelToUse->Close();
+ mChannelToUse = nullptr;
+ return rv;
+}
+
+NS_IMETHODIMP
+nsImapCacheStreamListener::OnDataAvailable(nsIRequest *request, nsISupports * aCtxt, nsIInputStream * aInStream, uint64_t aSourceOffset, uint32_t aCount)
+{
+ return mListener->OnDataAvailable(mChannelToUse, aCtxt, aInStream, aSourceOffset, aCount);
+}
+
+NS_IMPL_THREADSAFE_ADDREF(nsImapMockChannel)
+NS_IMPL_THREADSAFE_RELEASE(nsImapMockChannel)
+
+NS_INTERFACE_MAP_BEGIN(nsImapMockChannel)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIImapMockChannel)
+ NS_INTERFACE_MAP_ENTRY(nsIImapMockChannel)
+ NS_INTERFACE_MAP_ENTRY(nsIChannel)
+ NS_INTERFACE_MAP_ENTRY(nsIRequest)
+ NS_INTERFACE_MAP_ENTRY(nsICacheListener)
+ NS_INTERFACE_MAP_ENTRY(nsITransportEventSink)
+ NS_INTERFACE_MAP_ENTRY(nsISupportsWeakReference)
+NS_INTERFACE_MAP_END_THREADSAFE
+
+
+nsImapMockChannel::nsImapMockChannel()
+{
+ m_channelContext = nullptr;
+ m_cancelStatus = NS_OK;
+ mLoadFlags = 0;
+ mChannelClosed = false;
+ mReadingFromCache = false;
+ mTryingToReadPart = false;
+}
+
+nsImapMockChannel::~nsImapMockChannel()
+{
+ // if we're offline, we may not get to close the channel correctly.
+ // we need to do this to send the url state change notification in
+ // the case of mem and disk cache reads.
+ NS_WARN_IF_FALSE(NS_IsMainThread(), "should only access mock channel on ui thread");
+ if (!mChannelClosed)
+ Close();
+}
+
+nsresult nsImapMockChannel::NotifyStartEndReadFromCache(bool start)
+{
+ nsresult rv = NS_OK;
+ mReadingFromCache = start;
+ nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(m_url, &rv);
+ nsCOMPtr<nsIImapProtocol> imapProtocol = do_QueryReferent(m_protocol);
+ if (imapUrl)
+ {
+ nsCOMPtr<nsIImapMailFolderSink> folderSink;
+ rv = imapUrl->GetImapMailFolderSink(getter_AddRefs(folderSink));
+ if (folderSink)
+ {
+ nsCOMPtr<nsIMsgMailNewsUrl> mailUrl = do_QueryInterface(m_url);
+ rv = folderSink->SetUrlState(nullptr /* we don't know the protocol */,
+ mailUrl, start, false, m_cancelStatus);
+
+ // Required for killing ImapProtocol thread
+ if (NS_FAILED(m_cancelStatus) && imapProtocol)
+ imapProtocol->TellThreadToDie(false);
+ }
+ }
+ return rv;
+}
+
+NS_IMETHODIMP nsImapMockChannel::Close()
+{
+ if (mReadingFromCache)
+ NotifyStartEndReadFromCache(false);
+ else
+ {
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url);
+ if (mailnewsUrl)
+ {
+ nsCOMPtr<nsICacheEntryDescriptor> cacheEntry;
+ mailnewsUrl->GetMemCacheEntry(getter_AddRefs(cacheEntry));
+ if (cacheEntry)
+ cacheEntry->MarkValid();
+ // remove the channel from the load group
+ nsCOMPtr <nsILoadGroup> loadGroup;
+ GetLoadGroup(getter_AddRefs(loadGroup));
+ // if the mock channel wasn't initialized with a load group then
+ // use our load group (they may differ)
+ if (!loadGroup)
+ mailnewsUrl->GetLoadGroup(getter_AddRefs(loadGroup));
+ if (loadGroup)
+ loadGroup->RemoveRequest((nsIRequest *) this, nullptr, NS_OK);
+ }
+ }
+
+ m_channelListener = nullptr;
+ mCacheRequest = nullptr;
+ if (mTryingToReadPart)
+ {
+ // clear mem cache entry on imap part url in case it's holding
+ // onto last reference in mem cache. Need to do this on ui thread
+ nsresult rv;
+ nsCOMPtr <nsIImapUrl> imapUrl = do_QueryInterface(m_url, &rv);
+ if (imapUrl)
+ {
+ nsCOMPtr <nsIImapMailFolderSink> folderSink;
+ rv = imapUrl->GetImapMailFolderSink(getter_AddRefs(folderSink));
+ if (folderSink)
+ {
+ nsCOMPtr <nsIMsgMailNewsUrl> mailUrl = do_QueryInterface(m_url);
+ rv = folderSink->ReleaseUrlCacheEntry(mailUrl);
+ }
+ }
+ }
+ mChannelClosed = true;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::GetProgressEventSink(nsIProgressEventSink ** aProgressEventSink)
+{
+ *aProgressEventSink = mProgressEventSink;
+ NS_IF_ADDREF(*aProgressEventSink);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::SetProgressEventSink(nsIProgressEventSink * aProgressEventSink)
+{
+ mProgressEventSink = aProgressEventSink;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::GetChannelListener(nsIStreamListener **aChannelListener)
+{
+ *aChannelListener = m_channelListener;
+ NS_IF_ADDREF(*aChannelListener);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::GetChannelContext(nsISupports **aChannelContext)
+{
+ *aChannelContext = m_channelContext;
+ NS_IF_ADDREF(*aChannelContext);
+ return NS_OK;
+}
+
+// now implement our mock implementation of the channel interface...we forward all calls to the real
+// channel if we have one...otherwise we return something bogus...
+
+NS_IMETHODIMP nsImapMockChannel::SetLoadGroup(nsILoadGroup * aLoadGroup)
+{
+ m_loadGroup = aLoadGroup;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::GetLoadGroup(nsILoadGroup * *aLoadGroup)
+{
+ *aLoadGroup = m_loadGroup;
+ NS_IF_ADDREF(*aLoadGroup);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::GetOriginalURI(nsIURI* *aURI)
+{
+ // IMap does not seem to have the notion of an original URI :-(
+ // *aURI = m_originalUrl ? m_originalUrl : m_url;
+ *aURI = m_url;
+ NS_IF_ADDREF(*aURI);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::SetOriginalURI(nsIURI* aURI)
+{
+ // IMap does not seem to have the notion of an original URI :-(
+ // NS_NOTREACHED("nsImapMockChannel::SetOriginalURI");
+ // return NS_ERROR_NOT_IMPLEMENTED;
+ return NS_OK; // ignore
+}
+
+NS_IMETHODIMP nsImapMockChannel::GetURI(nsIURI* *aURI)
+{
+ *aURI = m_url;
+ NS_IF_ADDREF(*aURI);
+ return NS_OK ;
+}
+
+NS_IMETHODIMP nsImapMockChannel::SetURI(nsIURI* aURI)
+{
+ m_url = aURI;
+#ifdef DEBUG_bienvenu
+ if (!aURI)
+ printf("Clearing URI\n");
+#endif
+ if (m_url)
+ {
+ // if we don't have a progress event sink yet, get it from the url for now...
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url);
+ if (mailnewsUrl && !mProgressEventSink)
+ {
+ nsCOMPtr<nsIMsgStatusFeedback> statusFeedback;
+ mailnewsUrl->GetStatusFeedback(getter_AddRefs(statusFeedback));
+ mProgressEventSink = do_QueryInterface(statusFeedback);
+ }
+ // If this is a fetch URL and we can, get the message size from the message
+ // header and set it to be the content length.
+ // Note that for an attachment URL, this will set the content length to be
+ // equal to the size of the entire message.
+ nsCOMPtr<nsIImapUrl> imapUrl(do_QueryInterface(m_url));
+ nsImapAction imapAction;
+ imapUrl->GetImapAction(&imapAction);
+ if (imapAction == nsIImapUrl::nsImapMsgFetch)
+ {
+ nsCOMPtr<nsIMsgMessageUrl> msgUrl(do_QueryInterface(m_url));
+ if (msgUrl)
+ {
+ nsCOMPtr<nsIMsgDBHdr> msgHdr;
+ // A failure to get a message header isn't an error
+ msgUrl->GetMessageHeader(getter_AddRefs(msgHdr));
+ if (msgHdr)
+ {
+ uint32_t messageSize;
+ if (NS_SUCCEEDED(msgHdr->GetMessageSize(&messageSize)))
+ SetContentLength(messageSize);
+ }
+ }
+ }
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::Open(nsIInputStream **_retval)
+{
+ return NS_ImplementChannelOpen(this, _retval);
+}
+
+NS_IMETHODIMP
+nsImapMockChannel::OnCacheEntryAvailable(nsICacheEntryDescriptor *entry, nsCacheAccessMode access, nsresult status)
+{
+ nsresult rv = NS_OK;
+
+ // make sure we didn't close the channel before the async call back came in...
+ // hmmm....if we had write access and we canceled this mock channel then I wonder if we should
+ // be invalidating the cache entry before kicking out...
+ if (mChannelClosed)
+ {
+ entry->Doom();
+ return NS_OK;
+ }
+
+ NS_ENSURE_ARG(m_url); // kick out if m_url is null for some reason.
+
+#ifdef DEBUG_bienvenu
+ nsAutoCString entryKey("null");
+ if (entry)
+ entry->GetKey(entryKey);
+ printf("*** OnCacheEntryAvailable %s with access %d status %u\n", entryKey.get(), access, status);
+#endif
+ if (NS_SUCCEEDED(status))
+ {
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url, &rv);
+ mailnewsUrl->SetMemCacheEntry(entry);
+
+ if (mTryingToReadPart && access & nsICache::ACCESS_WRITE && !(access & nsICache::ACCESS_READ))
+ {
+ entry->Doom();
+ // whoops, we're looking for a part, but didn't find it. Fall back to fetching the whole msg.
+ nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(m_url);
+ SetupPartExtractorListener(imapUrl, m_channelListener);
+ return OpenCacheEntry();
+ }
+ // if we have write access then insert a "stream T" into the flow so data
+ // gets written to both
+ if (access & nsICache::ACCESS_WRITE && !(access & nsICache::ACCESS_READ))
+ {
+ // use a stream listener Tee to force data into the cache and to our current channel listener...
+ nsCOMPtr<nsIStreamListenerTee> tee = do_CreateInstance(NS_STREAMLISTENERTEE_CONTRACTID, &rv);
+ if (NS_SUCCEEDED(rv))
+ {
+ nsCOMPtr<nsIOutputStream> out;
+ // this will fail with the mem cache turned off, so we need to fall through
+ // to ReadFromImapConnection instead of aborting with NS_ENSURE_SUCCESS(rv,rv)
+ rv = entry->OpenOutputStream(0, getter_AddRefs(out));
+ if (NS_SUCCEEDED(rv))
+ {
+ rv = tee->Init(m_channelListener, out, nullptr);
+ m_channelListener = do_QueryInterface(tee);
+ }
+ else
+ NS_WARNING("IMAP Protocol failed to open output stream to Necko cache");
+ }
+ }
+ else
+ {
+ rv = ReadFromMemCache(entry);
+ if (NS_SUCCEEDED(rv))
+ {
+ NotifyStartEndReadFromCache(true);
+ if (access & nsICache::ACCESS_WRITE)
+ entry->MarkValid();
+ return NS_OK; // kick out if reading from the cache succeeded...
+ }
+ entry->Doom(); // doom entry if we failed to read from mem cache
+ mailnewsUrl->SetMemCacheEntry(nullptr); // we aren't going to be reading from the cache
+ }
+ } // if we got a valid entry back from the cache...
+
+ // if reading from the cache failed or if we are writing into the cache, default to ReadFromImapConnection.
+ return ReadFromImapConnection();
+}
+
+NS_IMETHODIMP
+nsImapMockChannel::OnCacheEntryDoomed(nsresult status)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+nsresult nsImapMockChannel::OpenCacheEntry()
+{
+ nsresult rv;
+ // get the cache session from our imap service...
+ nsCOMPtr<nsIImapService> imapService = do_GetService(NS_IMAPSERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsICacheSession> cacheSession;
+ rv = imapService->GetCacheSession(getter_AddRefs(cacheSession));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // we're going to need to extend this logic for the case where we're looking
+ // for a part. If we're looking for a part, we need to first ask for the part.
+ // if that comes back with a writeable cache entry, we need to doom it right
+ // away and not use it, and turn around and ask for a cache entry for the whole
+ // message, if that's available. But it seems like we shouldn't write into that
+ // cache entry if we just fetch that part - though we're doing that now. Maybe
+ // we never try to download just a single part from imap because our mime parser
+ // can't handle that, though I would think saving a single part as a file wouldn't
+ // need to go through mime...
+
+ // Open a cache entry with key = url
+ nsAutoCString urlSpec;
+ m_url->GetAsciiSpec(urlSpec);
+
+ // for now, truncate of the query part so we don't duplicate urls in the cache...
+ int32_t anchorIndex = urlSpec.RFindChar('?');
+ if (anchorIndex > 0)
+ {
+ // if we were trying to read a part, we failed - fall back and look for whole msg
+ if (mTryingToReadPart)
+ {
+ mTryingToReadPart = false;
+ urlSpec.SetLength(anchorIndex);
+ }
+ else
+ {
+ // check if this is a filter plugin requesting the message. In that case,we're not
+ // fetching a part, and we want the cache key to be just the uri.
+ nsAutoCString anchor(Substring(urlSpec, anchorIndex));
+
+ if (!anchor.EqualsLiteral("?header=filter")
+ && !anchor.EqualsLiteral("?header=attach") && !anchor.EqualsLiteral("?header=src"))
+ mTryingToReadPart = true;
+ else
+ urlSpec.SetLength(anchorIndex);
+ }
+ }
+ int32_t uidValidity = -1;
+ nsCacheAccessMode cacheAccess = nsICache::ACCESS_READ_WRITE;
+
+ nsCOMPtr <nsIImapUrl> imapUrl = do_QueryInterface(m_url, &rv);
+ if (imapUrl)
+ {
+ bool storeResultsOffline;
+ nsCOMPtr <nsIImapMailFolderSink> folderSink;
+
+ rv = imapUrl->GetImapMailFolderSink(getter_AddRefs(folderSink));
+ if (folderSink)
+ folderSink->GetUidValidity(&uidValidity);
+ imapUrl->GetStoreResultsOffline(&storeResultsOffline);
+ // If we're storing the message in the offline store, don't
+ // write to the disk cache.
+ if (storeResultsOffline)
+ cacheAccess = nsICache::ACCESS_READ;
+ }
+ // stick the uid validity in front of the url, so that if the uid validity
+ // changes, we won't re-use the wrong cache entries.
+ nsAutoCString cacheKey;
+ cacheKey.AppendInt(uidValidity, 16);
+ cacheKey.Append(urlSpec);
+ return cacheSession->AsyncOpenCacheEntry(cacheKey, cacheAccess, this, false);
+}
+
+nsresult nsImapMockChannel::ReadFromMemCache(nsICacheEntryDescriptor *entry)
+{
+ NS_ENSURE_ARG(entry);
+
+ nsCString annotation;
+ nsAutoCString entryKey;
+ nsAutoCString contentType;
+ nsresult rv = NS_OK;
+ bool shouldUseCacheEntry = false;
+
+ entry->GetKey(entryKey);
+ // if we have a part, then we should use the cache entry.
+ if (entryKey.FindChar('?') != kNotFound)
+ {
+ entry->GetMetaDataElement("contentType", getter_Copies(contentType));
+ if (!contentType.IsEmpty())
+ SetContentType(contentType);
+ shouldUseCacheEntry = true;
+ }
+ else
+ {
+ // otherwise, we have the whole msg, and we should make sure the content isn't modified.
+ rv = entry->GetMetaDataElement("ContentModified", getter_Copies(annotation));
+ if (NS_SUCCEEDED(rv) && !annotation.IsEmpty())
+ shouldUseCacheEntry = annotation.EqualsLiteral("Not Modified");
+ if (shouldUseCacheEntry)
+ {
+ uint32_t entrySize;
+
+ rv = entry->GetDataSize(&entrySize);
+ nsCOMPtr<nsIMsgMessageUrl> msgUrl(do_QueryInterface(m_url));
+ if (msgUrl)
+ {
+ nsCOMPtr<nsIMsgDBHdr> msgHdr;
+ // A failure to get a message header isn't an error
+ msgUrl->GetMessageHeader(getter_AddRefs(msgHdr));
+ if (msgHdr)
+ {
+ uint32_t messageSize;
+ if (NS_SUCCEEDED(msgHdr->GetMessageSize(&messageSize)) &&
+ messageSize != entrySize)
+ {
+ PR_LOG(IMAP, PR_LOG_WARN,
+ ("ReadFromMemCache size mismatch for %s: message %d, cache %d\n",
+ entryKey.get(), messageSize, entrySize));
+ shouldUseCacheEntry = false;
+ }
+ }
+ }
+ }
+ }
+ if (shouldUseCacheEntry)
+ {
+ nsCOMPtr<nsIInputStream> in;
+ uint32_t readCount;
+ rv = entry->OpenInputStream(0, getter_AddRefs(in));
+ NS_ENSURE_SUCCESS(rv, rv);
+ const int kFirstBlockSize = 100;
+ char firstBlock[kFirstBlockSize + 1];
+
+ rv = in->Read(firstBlock, sizeof(firstBlock), &readCount);
+ NS_ENSURE_SUCCESS(rv, rv);
+ firstBlock[kFirstBlockSize] = '\0';
+ int32_t findPos = MsgFindCharInSet(nsDependentCString(firstBlock),
+ ":\n\r", 0);
+ // Check that the first line is a header line, i.e., with a ':' in it
+ // Or that it begins with "From " because some IMAP servers allow that,
+ // even though it's technically invalid.
+ shouldUseCacheEntry = ((findPos != -1 && firstBlock[findPos] == ':') ||
+ !(strncmp(firstBlock, "From ", 5)));
+ in->Close();
+ }
+ if (shouldUseCacheEntry)
+ {
+ nsCOMPtr<nsIInputStream> in;
+ rv = entry->OpenInputStream(0, getter_AddRefs(in));
+ NS_ENSURE_SUCCESS(rv, rv);
+ // if mem cache entry is broken or empty, return error.
+ uint64_t bytesAvailable;
+ rv = in->Available(&bytesAvailable);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!bytesAvailable)
+ return NS_ERROR_FAILURE;
+
+ nsCOMPtr<nsIInputStreamPump> pump;
+ rv = NS_NewInputStreamPump(getter_AddRefs(pump), in);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // if we are going to read from the cache, then create a mock stream listener class and use it
+ nsImapCacheStreamListener * cacheListener = new nsImapCacheStreamListener();
+ NS_ADDREF(cacheListener);
+ cacheListener->Init(m_channelListener, this);
+ rv = pump->AsyncRead(cacheListener, m_channelContext);
+ NS_RELEASE(cacheListener);
+
+ if (NS_SUCCEEDED(rv)) // ONLY if we succeeded in actually starting the read should we return
+ {
+ mCacheRequest = pump;
+ nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(m_url);
+ // if the msg is unread, we should mark it read on the server. This lets
+ // the code running this url we're loading from the cache, if it cares.
+ imapUrl->SetMsgLoadingFromCache(true);
+
+ // be sure to set the cache entry's security info status as our security info status...
+ nsCOMPtr<nsISupports> securityInfo;
+ entry->GetSecurityInfo(getter_AddRefs(securityInfo));
+ SetSecurityInfo(securityInfo);
+ return NS_OK;
+ } // if AsyncRead succeeded.
+ } // if content is not modified
+ else
+ rv = NS_ERROR_FAILURE; // content is modified so return an error so we try to open it the old fashioned way
+
+ return rv;
+}
+
+// the requested url isn't in any of our caches so create an imap connection
+// to process it.
+nsresult nsImapMockChannel::ReadFromImapConnection()
+{
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(m_url);
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url);
+
+ bool localOnly = false;
+ imapUrl->GetLocalFetchOnly(&localOnly);
+ if (localOnly)
+ {
+ // This will cause an OnStartRunningUrl, and the subsequent close
+ // will then cause an OnStopRunningUrl with the cancel status.
+ NotifyStartEndReadFromCache(true);
+ Cancel(NS_MSG_ERROR_MSG_NOT_OFFLINE);
+ if (m_channelListener)
+ m_channelListener->OnStopRequest(this, m_channelContext,
+ NS_MSG_ERROR_MSG_NOT_OFFLINE);
+ return NS_MSG_ERROR_MSG_NOT_OFFLINE;
+ }
+
+ nsCOMPtr <nsILoadGroup> loadGroup;
+ GetLoadGroup(getter_AddRefs(loadGroup));
+ if (!loadGroup) // if we don't have one, the url will snag one from the msg window...
+ mailnewsUrl->GetLoadGroup(getter_AddRefs(loadGroup));
+
+ // okay, add the mock channel to the load group..
+ if (loadGroup)
+ loadGroup->AddRequest((nsIRequest *) this, nullptr /* context isupports */);
+
+ // loading the url consists of asking the server to add the url to it's imap event queue....
+ nsCOMPtr<nsIMsgIncomingServer> server;
+ rv = mailnewsUrl->GetServer(getter_AddRefs(server));
+ NS_ENSURE_SUCCESS(rv, rv);
+ nsCOMPtr<nsIImapIncomingServer> imapServer (do_QueryInterface(server, &rv));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Assume AsyncRead is always called from the UI thread.....
+ return imapServer->GetImapConnectionAndLoadUrl(imapUrl, nullptr);
+}
+
+// for messages stored in our offline cache, we have special code to handle that...
+// If it's in the local cache, we return true and we can abort the download because
+// this method does the rest of the work.
+bool nsImapMockChannel::ReadFromLocalCache()
+{
+ nsresult rv = NS_OK;
+
+ nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(m_url);
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url, &rv);
+
+ bool useLocalCache = false;
+ mailnewsUrl->GetMsgIsInLocalCache(&useLocalCache);
+ if (useLocalCache)
+ {
+ nsAutoCString messageIdString;
+
+ SetupPartExtractorListener(imapUrl, m_channelListener);
+
+ imapUrl->GetListOfMessageIds(messageIdString);
+ nsCOMPtr <nsIMsgFolder> folder;
+ rv = mailnewsUrl->GetFolder(getter_AddRefs(folder));
+ if (folder && NS_SUCCEEDED(rv))
+ {
+ // we want to create a file channel and read the msg from there.
+ nsCOMPtr<nsIInputStream> fileStream;
+ nsMsgKey msgKey = strtoul(messageIdString.get(), nullptr, 10);
+ uint32_t size;
+ int64_t offset;
+ rv = folder->GetOfflineFileStream(msgKey, &offset, &size, getter_AddRefs(fileStream));
+ // get the file channel from the folder, somehow (through the message or
+ // folder sink?) We also need to set the transfer offset to the message offset
+ if (fileStream && NS_SUCCEEDED(rv))
+ {
+ // dougt - This may break the ablity to "cancel" a read from offline mail reading.
+ // fileChannel->SetLoadGroup(m_loadGroup);
+ nsImapCacheStreamListener * cacheListener = new nsImapCacheStreamListener();
+ NS_ADDREF(cacheListener);
+ cacheListener->Init(m_channelListener, this);
+
+ // create a stream pump that will async read the specified amount of data.
+ // XXX make offset/size 64-bit ints
+ nsCOMPtr<nsIInputStreamPump> pump;
+ rv = NS_NewInputStreamPump(getter_AddRefs(pump), fileStream,
+ offset, (int64_t) size);
+ if (NS_SUCCEEDED(rv))
+ rv = pump->AsyncRead(cacheListener, m_channelContext);
+
+ NS_RELEASE(cacheListener);
+
+ if (NS_SUCCEEDED(rv)) // ONLY if we succeeded in actually starting the read should we return
+ {
+ // if the msg is unread, we should mark it read on the server. This lets
+ // the code running this url we're loading from the cache, if it cares.
+ imapUrl->SetMsgLoadingFromCache(true);
+ return true;
+ }
+ } // if we got an offline file transport
+ } // if we got the folder for this url
+ } // if use local cache
+
+ return false;
+}
+
+NS_IMETHODIMP nsImapMockChannel::AsyncOpen(nsIStreamListener *listener, nsISupports *ctxt)
+{
+ nsresult rv = NS_OK;
+
+ int32_t port;
+ if (!m_url)
+ return NS_ERROR_NULL_POINTER;
+ rv = m_url->GetPort(&port);
+ if (NS_FAILED(rv))
+ return rv;
+
+ rv = NS_CheckPortSafety(port, "imap");
+ if (NS_FAILED(rv))
+ return rv;
+
+ // set the stream listener and then load the url
+ m_channelContext = ctxt;
+ NS_ASSERTION(!m_channelListener, "shouldn't already have a listener");
+ m_channelListener = listener;
+ nsCOMPtr<nsIImapUrl> imapUrl (do_QueryInterface(m_url));
+
+ nsImapAction imapAction;
+ imapUrl->GetImapAction(&imapAction);
+
+ bool externalLink = true;
+ imapUrl->GetExternalLinkUrl(&externalLink);
+
+ if (externalLink)
+ {
+ // for security purposes, only allow imap urls originating from external sources
+ // perform a limited set of actions.
+ // Currently the allowed set includes:
+ // 1) folder selection
+ // 2) message fetch
+ // 3) message part fetch
+
+ if (! (imapAction == nsIImapUrl::nsImapSelectFolder || imapAction == nsIImapUrl::nsImapMsgFetch || imapAction == nsIImapUrl::nsImapOpenMimePart
+ || imapAction == nsIImapUrl::nsImapMsgFetchPeek))
+ return NS_ERROR_FAILURE; // abort the running of this url....it failed a security check
+ }
+
+ if (ReadFromLocalCache())
+ {
+ (void) NotifyStartEndReadFromCache(true);
+ return NS_OK;
+ }
+
+ // okay, it's not in the local cache, now check the memory cache...
+ // but we can't download for offline use from the memory cache
+ if (imapAction != nsIImapUrl::nsImapMsgDownloadForOffline)
+ {
+ rv = OpenCacheEntry();
+ if (NS_SUCCEEDED(rv))
+ return rv;
+ }
+
+ SetupPartExtractorListener(imapUrl, m_channelListener);
+ // if for some reason open cache entry failed then just default to opening an imap connection for the url
+ return ReadFromImapConnection();
+}
+
+nsresult nsImapMockChannel::SetupPartExtractorListener(nsIImapUrl * aUrl, nsIStreamListener * aConsumer)
+{
+ // if the url we are loading refers to a specific part then we need
+ // libmime to extract that part from the message for us.
+ bool refersToPart = false;
+ aUrl->GetMimePartSelectorDetected(&refersToPart);
+ if (refersToPart)
+ {
+ nsCOMPtr<nsIStreamConverterService> converter = do_GetService("@mozilla.org/streamConverters;1");
+ if (converter && aConsumer)
+ {
+ nsCOMPtr<nsIStreamListener> newConsumer;
+ converter->AsyncConvertData("message/rfc822", "*/*",
+ aConsumer, static_cast<nsIChannel *>(this), getter_AddRefs(newConsumer));
+ if (newConsumer)
+ m_channelListener = newConsumer;
+ }
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::GetLoadFlags(nsLoadFlags *aLoadFlags)
+{
+ //*aLoadFlags = nsIRequest::LOAD_NORMAL;
+ *aLoadFlags = mLoadFlags;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::SetLoadFlags(nsLoadFlags aLoadFlags)
+{
+ mLoadFlags = aLoadFlags;
+ return NS_OK; // don't fail when trying to set this
+}
+
+NS_IMETHODIMP nsImapMockChannel::GetContentType(nsACString &aContentType)
+{
+ if (m_ContentType.IsEmpty())
+ {
+ nsImapAction imapAction = 0;
+ if (m_url)
+ {
+ nsCOMPtr<nsIImapUrl> imapUrl = do_QueryInterface(m_url);
+ if (imapUrl)
+ {
+ imapUrl->GetImapAction(&imapAction);
+ }
+ }
+ if (imapAction == nsIImapUrl::nsImapSelectFolder)
+ aContentType.AssignLiteral("x-application-imapfolder");
+ else
+ aContentType.AssignLiteral("message/rfc822");
+ }
+ else
+ aContentType = m_ContentType;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::SetContentType(const nsACString &aContentType)
+{
+ nsAutoCString charset;
+ nsresult rv = NS_ParseContentType(aContentType, m_ContentType, charset);
+ if (NS_FAILED(rv) || m_ContentType.IsEmpty())
+ m_ContentType.AssignLiteral(UNKNOWN_CONTENT_TYPE);
+ return rv;
+}
+
+NS_IMETHODIMP nsImapMockChannel::GetContentCharset(nsACString &aContentCharset)
+{
+ aContentCharset.Truncate();
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::SetContentCharset(const nsACString &aContentCharset)
+{
+ NS_WARNING("nsImapMockChannel::SetContentCharset() not implemented");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsImapMockChannel::GetContentDisposition(uint32_t *aContentDisposition)
+{
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsImapMockChannel::SetContentDisposition(uint32_t aContentDisposition)
+{
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsImapMockChannel::GetContentDispositionFilename(nsAString &aContentDispositionFilename)
+{
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsImapMockChannel::SetContentDispositionFilename(const nsAString &aContentDispositionFilename)
+{
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP
+nsImapMockChannel::GetContentDispositionHeader(nsACString &aContentDispositionHeader)
+{
+ return NS_ERROR_NOT_AVAILABLE;
+}
+
+NS_IMETHODIMP nsImapMockChannel::GetContentLength(int64_t * aContentLength)
+{
+ *aContentLength = mContentLength;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsImapMockChannel::SetContentLength(int64_t aContentLength)
+{
+ mContentLength = aContentLength;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::GetOwner(nsISupports * *aPrincipal)
+{
+ *aPrincipal = mOwner;
+ NS_IF_ADDREF(*aPrincipal);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::SetOwner(nsISupports * aPrincipal)
+{
+ mOwner = aPrincipal;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::GetSecurityInfo(nsISupports * *aSecurityInfo)
+{
+ NS_IF_ADDREF(*aSecurityInfo = mSecurityInfo);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::SetSecurityInfo(nsISupports *aSecurityInfo)
+{
+ mSecurityInfo = aSecurityInfo;
+ return NS_OK;
+}
+
+////////////////////////////////////////////////////////////////////////////////
+// From nsIRequest
+////////////////////////////////////////////////////////////////////////////////
+
+NS_IMETHODIMP nsImapMockChannel::GetName(nsACString &result)
+{
+ if (m_url)
+ return m_url->GetSpec(result);
+ result.Truncate();
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::IsPending(bool *result)
+{
+ *result = m_channelListener != nullptr;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::GetStatus(nsresult *status)
+{
+ *status = m_cancelStatus;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::SetImapProtocol(nsIImapProtocol *aProtocol)
+{
+ m_protocol = do_GetWeakReference(aProtocol);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::Cancel(nsresult status)
+{
+ NS_WARN_IF_FALSE(NS_IsMainThread(),
+ "nsImapMockChannel::Cancel should only be called from UI thread");
+ m_cancelStatus = status;
+ nsCOMPtr<nsIImapProtocol> imapProtocol = do_QueryReferent(m_protocol);
+
+ // if we aren't reading from the cache and we get canceled...doom our cache entry...
+ if (m_url)
+ {
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url);
+ DoomCacheEntry(mailnewsUrl);
+ }
+
+ // Required for killing ImapProtocol thread
+ if (imapProtocol)
+ imapProtocol->TellThreadToDie(false);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsImapMockChannel::Suspend()
+{
+ NS_NOTREACHED("nsImapMockChannel::Suspend");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsImapMockChannel::Resume()
+{
+ NS_NOTREACHED("nsImapMockChannel::Resume");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsImapMockChannel::GetNotificationCallbacks(nsIInterfaceRequestor* *aNotificationCallbacks)
+{
+ *aNotificationCallbacks = mCallbacks.get();
+ NS_IF_ADDREF(*aNotificationCallbacks);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsImapMockChannel::SetNotificationCallbacks(nsIInterfaceRequestor* aNotificationCallbacks)
+{
+ mCallbacks = aNotificationCallbacks;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsImapMockChannel::OnTransportStatus(nsITransport *transport, nsresult status,
+ uint64_t progress, uint64_t progressMax)
+{
+ if (NS_FAILED(m_cancelStatus) || (mLoadFlags & LOAD_BACKGROUND) || !m_url)
+ return NS_OK;
+
+ // these transport events should not generate any status messages
+ if (status == NS_NET_STATUS_RECEIVING_FROM ||
+ status == NS_NET_STATUS_SENDING_TO)
+ return NS_OK;
+
+ if (!mProgressEventSink)
+ {
+ NS_QueryNotificationCallbacks(mCallbacks, m_loadGroup, mProgressEventSink);
+ if (!mProgressEventSink)
+ return NS_OK;
+ }
+
+ nsAutoCString host;
+ m_url->GetHost(host);
+
+ nsCOMPtr<nsIMsgMailNewsUrl> mailnewsUrl = do_QueryInterface(m_url);
+ if (mailnewsUrl)
+ {
+ nsCOMPtr<nsIMsgIncomingServer> server;
+ mailnewsUrl->GetServer(getter_AddRefs(server));
+ if (server)
+ server->GetRealHostName(host);
+ }
+ mProgressEventSink->OnStatus(this, nullptr, status,
+ NS_ConvertUTF8toUTF16(host).get());
+
+ return NS_OK;
+}
+
+
+nsIMAPMailboxInfo::nsIMAPMailboxInfo(const nsACString &aName, char aDelimiter)
+{
+ mMailboxName.Assign(aName);
+ mDelimiter = aDelimiter;
+ mChildrenListed = false;
+}
+
+nsIMAPMailboxInfo::~nsIMAPMailboxInfo()
+{
+}
+
+void nsIMAPMailboxInfo::SetChildrenListed(bool childrenListed)
+{
+ mChildrenListed = childrenListed;
+}
+
+bool nsIMAPMailboxInfo::GetChildrenListed()
+{
+ return mChildrenListed;
+}
+
+const nsACString& nsIMAPMailboxInfo::GetMailboxName()
+{
+ return mMailboxName;
+}
+
+char nsIMAPMailboxInfo::GetDelimiter()
+{
+ return mDelimiter;
+}
--- /dev/null
+/* -*- Mode: javascript; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+// SpaceHit() function: whether spacebar advances to next unread message.
+pref("mail.advance_on_spacebar", true);
+
+//mailnews.timeline_is_enabled should be set to true ONLY for perf measurement-timeline builds.
+pref("mailnews.timeline_is_enabled", false);
+
+pref("mailnews.logComposePerformance", false);
+
+pref("mail.wrap_long_lines", true);
+pref("mail.inline_attachments", true);
+pref("mail.reply_quote_inline", false);
+
+// hidden pref for controlling if the user agent string
+// is displayed in the message pane or not...
+pref("mailnews.headers.showUserAgent", false);
+
+// hidden pref for controlling if the organization string
+// is displayed in the message pane or not...
+pref("mailnews.headers.showOrganization", false);
+
+// hidden pref for controlling if the references header
+// is displayed in the message pane or not...
+pref("mailnews.headers.showReferences", false);
+
+// hidden pref for controlling if the message-id header
+// is displayed in the message pane or not...
+pref("mailnews.headers.showMessageId", false);
+
+// hidden pref for controlling if the message to a message-id
+// is opened in a new window or in the same window
+pref("mailnews.messageid.openInNewWindow", false);
+
+// hidden pref for url which will be used to open message-ids
+// in browser (%mid ist replaced with the message-id)
+pref("mailnews.messageid_browser.url", "chrome://messenger-region/locale/region.properties");
+
+
+// hidden pref for whether or not to warn when deleting filters. Default YES
+pref("mailnews.filters.confirm_delete", true);
+
+// space-delimited list of extra headers to show in msg header display area.
+pref("mailnews.headers.extraExpandedHeaders", "");
+
+// default sort order settings (when creating new folder views)
+// sort_order is an int value reflecting nsMsgViewSortOrder values
+// as defined in nsIMsgDBView.idl (ascending = 1, descending = 2)
+// sort_type is an int value reflecting nsMsgViewSortType values
+// as defined in nsIMsgDBView.idl (byDate = 18, byId = 21 etc.)
+pref("mailnews.default_sort_order", 1); // for Mail/RSS/... (nsMsgDatabase)
+pref("mailnews.default_sort_type", 18); //
+pref("mailnews.default_news_sort_order", 1); // for News (nsNewsDatabase)
+pref("mailnews.default_news_sort_type", 21); //
+
+// hidden pref for whether "sort by date" and "sort by received date" in
+// threaded mode should be based on the newest message in the thread, or on
+// the thread root
+pref("mailnews.sort_threads_by_root", false);
+
+// default view flags for new folders
+// both flags are int values reflecting nsMsgViewFlagsType values
+// as defined in nsIMsgDBView.idl (kNone = 0, kThreadedDisplay = 1 etc.)
+pref("mailnews.default_view_flags", 0); // for Mail/RSS/... (nsMsgDatabase)
+pref("mailnews.default_news_view_flags", 1); // for News (nsNewsDatabase)
+
+// If true, delete will use the direction of the sort order
+// in determining the next message to select.
+pref("mail.delete_matches_sort_order", false);
+
+// mailnews tcp read+write timeout in seconds.
+pref("mailnews.tcptimeout", 100);
+
+pref("mailnews.headers.showSender", false);
+
+// set to 0 if you don't want to ignore timestamp differences between
+// local mail folders and the value stored in the corresponding .msf file.
+// 0 was the default up to and including 1.5. I've made the default
+// be greater than one hour so daylight savings time changes don't affect us.
+// We will still always regenerate .msf files if the file size changes.
+pref("mail.db_timestamp_leeway", 4000);
+// How long should we leave idle db's open, in milliseconds.
+pref("mail.db.idle_limit", 300000);
+// How many db's should we leave open? LRU db's will be closed first
+pref("mail.db.max_open", 30);
+
+pref("mail.imap.chunk_size", 65536);
+pref("mail.imap.min_chunk_size_threshold", 98304);
+pref("mail.imap.chunk_fast", 2);
+pref("mail.imap.chunk_ideal", 4);
+pref("mail.imap.chunk_add", 8192);
+pref("mail.imap.hide_other_users", false);
+pref("mail.imap.hide_unused_namespaces", true);
+pref("mail.imap.auto_unsubscribe_from_noselect_folders", true);
+pref("mail.imap.mime_parts_on_demand", true);
+pref("mail.imap.mime_parts_on_demand_threshold", 30000);
+pref("mail.imap.use_literal_plus", true);
+pref("mail.imap.expunge_after_delete", false);
+pref("mail.imap.check_deleted_before_expunge", false);
+pref("mail.imap.expunge_option", 0);
+pref("mail.imap.expunge_threshold_number", 20);
+pref("mail.imap.hdr_chunk_size", 200);
+
+// if true, we assume that a user access a folder in the other users namespace
+// is acting as a delegate for that folder, and wishes to use the other users
+// identity when acting on messages in other users folders.
+pref("mail.imap.delegateOtherUsersFolders", false);
+pref("mail.thread_without_re", false); // if false, only thread by subject if Re:
+pref("mail.strict_threading", true); // if true, don't thread by subject at all
+pref("mail.correct_threading", true); // if true, makes sure threading works correctly always (see bug 181446)
+pref("mail.pop3.deleteFromServerOnMove", false);
+pref("mail.fixed_width_messages", true);
+pref("mail.citation_color", "#000000"); // quoted color
+pref("mail.quoted_style", 0); // 0=plain, 1=bold, 2=italic, 3=bolditalic
+pref("mail.quoted_size", 0); // 0=normal, 1=big, 2=small
+pref("mail.quoted_graphical", true); // use HTML-style quoting for displaying plain text
+pref("mail.quoteasblock", true); // use HTML-style quoting for quoting plain text
+pref("mail.strictly_mime", false);
+pref("mail.strictly_mime_headers", true);
+// 0/1 (name param is encoded in a legacy way), 2(RFC 2231 only)
+// 0 the name param is never separated to multiple lines.
+pref("mail.strictly_mime.parm_folding", 1);
+pref("mail.label_ascii_only_mail_as_us_ascii", false);
+pref("mail.file_attach_binary", false);
+pref("mail.show_headers", 1); // some
+pref("mail.pane_config.dynamic", 0);
+pref("mail.addr_book.mapit_url.format", "chrome://messenger-region/locale/region.properties");
+#ifdef MOZ_SUITE
+pref("mailnews.start_page.url", "chrome://messenger-region/locale/region.properties");
+pref("messenger.throbber.url", "chrome://messenger-region/locale/region.properties");
+pref("compose.throbber.url", "chrome://messenger-region/locale/region.properties");
+pref("addressbook.throbber.url", "chrome://messenger-region/locale/region.properties");
+pref("mail.accountwizard.deferstorage", false);
+// |false|: Show both name and address, even for people in my addressbook.
+pref("mail.showCondensedAddresses", false);
+#endif
+
+// the format for "mail.addr_book.quicksearchquery.format" is:
+// @V == the escaped value typed in the quick search bar in the addressbook
+//
+// note, changing this might require a change to SearchNameOrEmail.label in
+// messenger.dtd or searchNameAndEmail.emptytext in abMainWindow.dtd
+pref("mail.addr_book.quicksearchquery.format", "chrome://messenger/locale/messenger.properties");
+
+// values for "mail.addr_book.lastnamefirst" are:
+//0=displayname, 1=lastname first, 2=firstname first
+pref("mail.addr_book.lastnamefirst", 0);
+pref("mail.addr_book.displayName.autoGeneration", true);
+pref("mail.addr_book.displayName.lastnamefirst", "chrome://messenger/locale/messenger.properties");
+pref("mail.addr_book.show_phonetic_fields", "chrome://messenger/locale/messenger.properties");
+pref("mail.html_compose", true);
+// you can specify multiple, option headers
+// this will show up in the address picker in the compose window
+// examples: "X-Face" or "Approved,X-No-Archive"
+pref("mail.compose.other.header", "");
+pref("mail.compose.autosave", true);
+pref("mail.compose.autosaveinterval", 5); // in minutes
+
+pref("mail.default_html_action", 0); // 0=ask, 1=plain, 2=html, 3=both
+
+pref("mail.mdn.report.not_in_to_cc", 2); // 0: Never 1: Always 2: Ask me
+pref("mail.mdn.report.outside_domain", 2); // 0: Never 1: Always 2: Ask me
+pref("mail.mdn.report.other", 2); // 0: Never 1: Always 2: Ask me 3: Denial
+
+pref("mail.incorporate.return_receipt", 0); // 0: Inbox/filter 1: Sent folder
+pref("mail.request.return_receipt", 2); // 1: DSN 2: MDN 3: Both
+pref("mail.receipt.request_header_type", 0); // 0: MDN-DNT header 1: RRT header 2: Both (MC)
+pref("mail.receipt.request_return_receipt_on", false);
+pref("mail.mdn.report.enabled", true); // false: Never send true: Send sometimes
+
+pref("mail.dsn.always_request_on", false);
+pref("mail.dsn.request_on_success_on", true); // DSN request is sent with SUCCESS option
+pref("mail.dsn.request_on_failure_on", true); // DSN request is sent with FAILURE option
+pref("mail.dsn.request_on_delay_on", true); // DSN request is sent with DELAY option
+pref("mail.dsn.request_never_on", false); // DSN request is not sent with NEVER option
+pref("mail.dsn.ret_full_on", true); // DSN request is sent with RET FULL option
+
+pref("news.show_size_in_lines", true);
+pref("news.update_unread_on_expand", true);
+pref("news.get_messages_on_select", true);
+
+pref("mailnews.wraplength", 72);
+pref("mail.compose.wrap_to_window_width", false);
+
+// 0=no header, 1="<author> wrote:", 2="On <date> <author> wrote:", 3="<author> wrote On <date>:", 4=user specified
+pref("mailnews.reply_header_type", 1);
+// locale which affects date format, set empty string to use application default locale
+pref("mailnews.reply_header_locale", "");
+pref("mailnews.reply_header_authorwrote", "chrome://messenger/locale/messengercompose/composeMsgs.properties");
+pref("mailnews.reply_header_ondate", "chrome://messenger/locale/messengercompose/composeMsgs.properties");
+
+// separator to separate between date and author
+pref("mailnews.reply_header_separator", ", ");
+pref("mailnews.reply_header_colon", ":");
+pref("mailnews.reply_header_originalmessage", "chrome://messenger/locale/messengercompose/composeMsgs.properties");
+
+pref("mailnews.reply_to_self_check_all_ident", false);
+
+pref("mailnews.reply_quoting_selection", true);
+pref("mailnews.reply_quoting_selection.only_if_chars", "");
+pref("mailnews.reply_quoting_selection.multi_word", true);
+
+pref("mail.operate_on_msgs_in_collapsed_threads", false);
+pref("mail.warn_on_collapsed_thread_operation", true);
+pref("mail.warn_on_shift_delete", true);
+pref("news.warn_on_delete", true);
+pref("mail.purge_threshhold_mb", 20);
+pref("mail.prompt_purge_threshhold", true);
+pref("mail.purge.ask", true);
+
+pref("mailnews.offline_sync_mail", false);
+pref("mailnews.offline_sync_news", false);
+pref("mailnews.offline_sync_send_unsent", true);
+pref("mailnews.offline_sync_work_offline", false);
+pref("mailnews.force_ascii_search", false);
+
+pref("mailnews.send_default_charset", "chrome://messenger/locale/messenger.properties");
+pref("mailnews.view_default_charset", "chrome://messenger/locale/messenger.properties");
+pref("mailnews.force_charset_override", false); // ignore specified MIME encoding and use the default encoding for display
+pref("mailnews.reply_in_default_charset", false);
+// mailnews.disable_fallback_to_utf8.<charset>
+// don't fallback from <charset> to UTF-8 even if some characters are not found in <charset>.
+// those characters will be crippled.
+pref("mailnews.disable_fallback_to_utf8.ISO-2022-JP", false);
+pref("mailnews.localizedRe", "chrome://messenger-region/locale/region.properties");
+
+pref("mailnews.search_date_format", "chrome://messenger/locale/messenger.properties");
+pref("mailnews.search_date_separator", "chrome://messenger/locale/messenger.properties");
+pref("mailnews.search_date_leading_zeros", "chrome://messenger/locale/messenger.properties");
+
+pref("mailnews.quotingPrefs.version", 0); // used to decide whether to migrate global quoting prefs
+
+// the first time, we'll warn the user about the blind send, and they can disable the warning if they want.
+pref("mapi.blind-send.enabled", true);
+
+pref("offline.autoDetect", false); // automatically move the user offline or online based on the network connection
+
+pref("ldap_2.autoComplete.useDirectory", false);
+pref("ldap_2.autoComplete.directoryServer", "");
+
+pref("ldap_2.servers.pab.position", 1);
+pref("ldap_2.servers.pab.description", "chrome://messenger/locale/addressbook/addressBook.properties");
+pref("ldap_2.servers.pab.dirType", 2);
+pref("ldap_2.servers.pab.filename", "abook.mab");
+pref("ldap_2.servers.pab.isOffline", false);
+
+pref("ldap_2.servers.history.position", 2);
+pref("ldap_2.servers.history.description", "chrome://messenger/locale/addressbook/addressBook.properties");
+pref("ldap_2.servers.history.dirType", 2);
+pref("ldap_2.servers.history.filename", "history.mab");
+pref("ldap_2.servers.history.isOffline", false);
+
+// default mapping of addressbook properties to ldap attributes
+pref("ldap_2.servers.default.attrmap.FirstName", "givenName");
+pref("ldap_2.servers.default.attrmap.LastName", "sn,surname");
+pref("ldap_2.servers.default.attrmap.DisplayName", "cn,commonname");
+pref("ldap_2.servers.default.attrmap.NickName", "mozillaNickname,xmozillanickname");
+pref("ldap_2.servers.default.attrmap.PrimaryEmail", "mail");
+pref("ldap_2.servers.default.attrmap.SecondEmail", "mozillaSecondEmail,xmozillasecondemail");
+pref("ldap_2.servers.default.attrmap.WorkPhone", "telephoneNumber");
+pref("ldap_2.servers.default.attrmap.HomePhone", "homePhone");
+pref("ldap_2.servers.default.attrmap.FaxNumber", "facsimiletelephonenumber,fax");
+pref("ldap_2.servers.default.attrmap.PagerNumber", "pager,pagerphone");
+pref("ldap_2.servers.default.attrmap.CellularNumber", "mobile,cellphone,carphone");
+pref("ldap_2.servers.default.attrmap.WorkAddress", "street,streetaddress,postOfficeBox");
+pref("ldap_2.servers.default.attrmap.HomeAddress", "mozillaHomeStreet");
+pref("ldap_2.servers.default.attrmap.WorkAddress2", "mozillaWorkStreet2");
+pref("ldap_2.servers.default.attrmap.HomeAddress2", "mozillaHomeStreet2");
+pref("ldap_2.servers.default.attrmap.WorkCity", "l,locality");
+pref("ldap_2.servers.default.attrmap.HomeCity", "mozillaHomeLocalityName");
+pref("ldap_2.servers.default.attrmap.WorkState", "st,region");
+pref("ldap_2.servers.default.attrmap.HomeState", "mozillaHomeState");
+pref("ldap_2.servers.default.attrmap.WorkZipCode", "postalCode,zip");
+pref("ldap_2.servers.default.attrmap.HomeZipCode", "mozillaHomePostalCode");
+pref("ldap_2.servers.default.attrmap.WorkCountry", "c,countryname");
+pref("ldap_2.servers.default.attrmap.HomeCountry", "mozillaHomeCountryName");
+pref("ldap_2.servers.default.attrmap.JobTitle", "title");
+pref("ldap_2.servers.default.attrmap.Department", "ou,department,departmentnumber,orgunit");
+pref("ldap_2.servers.default.attrmap.Company", "o,company");
+pref("ldap_2.servers.default.attrmap._AimScreenName", "nsAIMid,nscpaimscreenname");
+pref("ldap_2.servers.default.attrmap.WebPage1", "mozillaWorkUrl,workurl,labeledURI");
+pref("ldap_2.servers.default.attrmap.WebPage2", "mozillaHomeUrl,homeurl");
+pref("ldap_2.servers.default.attrmap.BirthYear", "birthyear");
+pref("ldap_2.servers.default.attrmap.BirthMonth", "birthmonth");
+pref("ldap_2.servers.default.attrmap.BirthDay", "birthday");
+pref("ldap_2.servers.default.attrmap.Custom1", "mozillaCustom1,custom1");
+pref("ldap_2.servers.default.attrmap.Custom2", "mozillaCustom2,custom2");
+pref("ldap_2.servers.default.attrmap.Custom3", "mozillaCustom3,custom3");
+pref("ldap_2.servers.default.attrmap.Custom4", "mozillaCustom4,custom4");
+pref("ldap_2.servers.default.attrmap.Notes", "description,notes");
+pref("ldap_2.servers.default.attrmap.PreferMailFormat", "mozillaUseHtmlMail,xmozillausehtmlmail");
+pref("ldap_2.servers.default.attrmap.LastModifiedDate", "modifytimestamp");
+
+pref("ldap_2.user_id", 0);
+pref("ldap_2.version", 3); /* Update kCurrentListVersion in include/dirprefs.h if you change this */
+
+pref("mailnews.confirm.moveFoldersToTrash", true);
+
+// space-delimited list of extra headers to add to .msf file
+pref("mailnews.customDBHeaders", "");
+
+// close standalone message window when deleting the displayed message
+pref("mail.close_message_window.on_delete", false);
+
+#ifdef MOZ_SUITE
+pref("mailnews.reuse_message_window", true);
+#endif
+
+pref("mailnews.open_window_warning", 10); // warn user if they attempt to open more than this many messages at once
+
+pref("mailnews.start_page.enabled", false);
+
+pref("mailnews.remember_selected_message", true);
+pref("mailnews.scroll_to_new_message", true);
+
+// if true, any click on a column header other than the thread column will unthread the view
+pref("mailnews.thread_pane_column_unthreads", false);
+
+pref("mailnews.account_central_page.url", "chrome://messenger/locale/messenger.properties");
+
+/* default prefs for Mozilla 5.0 */
+pref("mail.identity.default.compose_html", true);
+pref("mail.identity.default.valid", true);
+pref("mail.identity.default.fcc", true);
+pref("mail.identity.default.fcc_folder", "mailbox://nobody@Local%20Folders/Sent");
+pref("mail.identity.default.fcc_reply_follows_parent", false);
+pref("mail.identity.default.autocompleteToMyDomain", false);
+
+pref("mail.identity.default.archive_enabled", true);
+// archive into 0: single folder, 1: yearly folder, 2: year/year-month folder
+pref("mail.identity.default.archive_granularity", 1);
+pref("mail.identity.default.archive_keep_folder_structure", false);
+
+// keep these defaults for backwards compatibility and migration
+
+// but .doBcc and .doBccList are the right ones from now on.
+pref("mail.identity.default.bcc_self", false);
+pref("mail.identity.default.bcc_others", false);
+pref("mail.identity.default.bcc_list", "");
+
+pref("mail.identity.default.draft_folder", "mailbox://nobody@Local%20Folders/Drafts");
+pref("mail.identity.default.stationery_folder", "mailbox://nobody@Local%20Folders/Templates");
+pref("mail.identity.default.directoryServer", "");
+pref("mail.identity.default.overrideGlobal_Pref", false);
+pref("mail.identity.default.auto_quote", true);
+pref("mail.identity.default.reply_on_top", 0); // 0=bottom 1=top 2=select
+pref("mail.identity.default.sig_bottom", true); // true=below quoted false=above quoted
+pref("mail.identity.default.sig_on_fwd", false); // Include signature on fwd?
+pref("mail.identity.default.sig_on_reply", true); // Include signature on re?
+
+// Suppress double-dash signature separator
+pref("mail.identity.default.suppress_signature_separator", false);
+
+// default to archives folder on same server.
+pref("mail.identity.default.archives_folder_picker_mode", "0");
+
+// Headers to always add to outgoing mail
+// examples: "header1,header2"
+// pref("mail.identity.id1.headers", "header1");
+// user_pref("mail.identity.id1.header.header1", "X-Mozilla-Rocks: True")
+pref("mail.identity.default.headers", "");
+
+// by default, only collect addresses the user sends to (outgoing)
+// incoming is all spam anyways
+#ifdef MOZ_SUITE
+pref("mail.collect_email_address_incoming", false);
+pref("mail.collect_email_address_newsgroup", false);
+#endif
+pref("mail.collect_email_address_outgoing", true);
+
+// by default, use the Collected Addressbook for collection
+pref("mail.collect_addressbook", "moz-abmdbdirectory://history.mab");
+
+pref("mail.default_sendlater_uri", "mailbox://nobody@Local%20Folders/Unsent%20Messages");
+
+pref("mail.smtpservers", "");
+pref("mail.accountmanager.accounts", "");
+
+// Last used account key value
+pref("mail.account.lastKey", 0);
+
+pref("mail.server.default.port", -1);
+pref("mail.server.default.offline_support_level", -1);
+pref("mail.server.default.leave_on_server", false);
+pref("mail.server.default.download_on_biff", false);
+pref("mail.server.default.check_time", 10);
+pref("mail.server.default.delete_by_age_from_server", false);
+pref("mail.server.default.num_days_to_leave_on_server", 7);
+pref("mail.server.default.dot_fix", true);
+pref("mail.server.default.limit_offline_message_size", false);
+pref("mail.server.default.max_size", 50);
+pref("mail.server.default.delete_mail_left_on_server", false);
+pref("mail.server.default.valid", true);
+pref("mail.server.default.abbreviate", true);
+pref("mail.server.default.isSecure", false);
+pref("mail.server.default.authMethod", 3); // cleartext password. @see nsIMsgIncomingServer.authMethod.
+pref("mail.server.default.socketType", 0); // @see nsIMsgIncomingServer.socketType
+pref("mail.server.default.override_namespaces", true);
+pref("mail.server.default.deferred_to_account", "");
+
+pref("mail.server.default.delete_model", 1);
+pref("mail.server.default.fetch_by_chunks", true);
+pref("mail.server.default.mime_parts_on_demand", true);
+// Send IMAP RFC 2971 ID Info to server
+pref("mail.server.default.send_client_info", true);
+pref("mail.server.default.always_authenticate", false);
+pref("mail.server.default.singleSignon", true);
+pref("mail.server.default.max_articles", 500);
+pref("mail.server.default.notify.on", true);
+pref("mail.server.default.mark_old_read", false);
+pref("mail.server.default.empty_trash_on_exit", false);
+// 0 = Keep Dupes, leave them alone
+// 1 = delete dupes
+// 2 = Move Dupes to trash
+// 3 = Mark Dupes as Read
+pref("mail.server.default.dup_action", 0);
+pref("mail.server.default.hidden", false);
+
+pref("mail.server.default.using_subscription", true);
+pref("mail.server.default.dual_use_folders", true);
+pref("mail.server.default.canDelete", false);
+pref("mail.server.default.login_at_startup", false);
+pref("mail.server.default.allows_specialfolders_usage", true);
+pref("mail.server.default.canCreateFolders", true);
+pref("mail.server.default.canFileMessages", true);
+
+// special enhancements for IMAP servers
+pref("mail.server.default.is_gmail", false);
+pref("mail.server.default.use_idle", true);
+// in case client or server has bugs in condstore implementation
+pref("mail.server.default.use_condstore", true);
+// in case client or server has bugs in compress implementation
+pref("mail.server.default.use_compress_deflate", true);
+// for spam
+pref("mail.server.default.spamLevel", 100); // 0 off, 100 on. not doing bool since we might have real levels one day.
+pref("mail.server.default.moveOnSpam", false);
+pref("mail.server.default.moveTargetMode", 0); // 0 == "Junk" on server, 1 == specific folder
+pref("mail.server.default.spamActionTargetAccount", "");
+pref("mail.server.default.spamActionTargetFolder", "");
+pref("mail.server.default.useWhiteList", true);
+pref("mail.server.default.whiteListAbURI", "moz-abmdbdirectory://abook.mab"); // the Personal addressbook.
+pref("mail.server.default.useServerFilter", false);
+pref("mail.server.default.serverFilterName", "SpamAssassin");
+pref("mail.server.default.serverFilterTrustFlags", 1); // 1 == trust positives, 2 == trust negatives, 3 == trust both
+pref("mail.server.default.purgeSpam", false);
+pref("mail.server.default.purgeSpamInterval", 14); // 14 days
+pref("mail.server.default.check_all_folders_for_new", false);
+// should we inhibit whitelisting of the email addresses for a server's identities?
+pref("mail.server.default.inhibitWhiteListingIdentityUser", true);
+// should we inhibit whitelisting of the domain for a server's identities?
+pref("mail.server.default.inhibitWhiteListingIdentityDomain", false);
+
+// to activate auto-sync feature (preemptive message download for imap) by default
+pref("mail.server.default.autosync_offline_stores",true);
+pref("mail.server.default.offline_download",true);
+
+// -1 means no limit, no purging of offline stores.
+pref("mail.server.default.autosync_max_age_days", -1);
+
+// This is the default store contractID for newly created servers.
+// We don't use mail.server.default because we want to ensure that the
+// store contract id is always written out to prefs.js
+pref("mail.serverDefaultStoreContractID", "@mozilla.org/msgstore/berkeleystore;1");
+// the probablilty threshold over which messages are classified as junk
+// this number is divided by 100 before it is used. The classifier can be fine tuned
+// by changing this pref. Typical values are .99, .95, .90, .5, etc.
+pref("mail.adaptivefilters.junk_threshold", 90);
+pref("mail.spam.version", 0); // used to determine when to migrate global spam settings
+pref("mail.spam.logging.enabled", false);
+pref("mail.spam.manualMark", false);
+pref("mail.spam.markAsReadOnSpam", false);
+pref("mail.spam.manualMarkMode", 0); // 0 == "move to junk folder", 1 == "delete"
+pref("mail.spam.markAsNotJunkMarksUnRead", true);
+pref("mail.spam.display.sanitize", true); // display simple html for html junk messages
+// the number of allowed bayes tokens before the database is shrunk
+pref("mailnews.bayesian_spam_filter.junk_maxtokens", 100000);
+
+// set default traits for junk and good. Index should match the values in nsIJunkMailPlugin
+pref("mailnews.traits.id.1", "mailnews@mozilla.org#good");
+pref("mailnews.traits.name.1", "Good");
+pref("mailnews.traits.enabled.1", false);
+pref("mailnews.traits.id.2", "mailnews@mozilla.org#junk");
+pref("mailnews.traits.name.2", "Junk");
+pref("mailnews.traits.enabled.2", true);
+pref("mailnews.traits.antiId.2", "mailnews@mozilla.org#good");
+// traits 3 - 1000 are reserved for use by mailnews@mozilla.org
+// the first externally defined trait will have index 1001
+pref("mailnews.traits.lastIndex", 1000);
+
+pref("mail.autoComplete.highlightNonMatches", true);
+
+// if true, we'll use the password from an incoming server with
+// matching username and domain
+pref("mail.smtp.useMatchingDomainServer", false);
+
+// if true, we'll use the password from an incoming server with
+// matching username and host name
+pref("mail.smtp.useMatchingHostNameServer", false);
+
+pref("mail.smtpserver.default.authMethod", 3); // cleartext password. @see nsIMsgIncomingServer.authMethod.
+pref("mail.smtpserver.default.try_ssl", 0); // @see nsISmtpServer.socketType
+
+// For the next 3 prefs, see <http://www.bucksch.org/1/projects/mozilla/16507>
+pref("mail.display_glyph", true); // TXT->HTML :-) etc. in viewer
+pref("mail.display_struct", true); // TXT->HTML *bold* etc. in viewer; ditto
+pref("mail.send_struct", false); // HTML->HTML *bold* etc. during Send; ditto
+// display time and date in message pane using senders timezone
+pref("mailnews.display.date_senders_timezone", false);
+// For the next 4 prefs, see <http://www.bucksch.org/1/projects/mozilla/108153>
+pref("mailnews.display.prefer_plaintext", false); // Ignore HTML parts in multipart/alternative
+pref("mailnews.display.html_as", 0); // How to display HTML/MIME parts. 0 = Render the sender's HTML; 1 = HTML->TXT->HTML; 2 = Show HTML source; 3 = Sanitize HTML; 4 = Show all body parts
+pref("mailnews.display.show_all_body_parts_menu", false); // Whether the View > Message body as > All body parts menu item is available
+pref("mailnews.display.html_sanitizer.allowed_tags.migrated", false); // whether legacy mailnews.display.html_sanitizer.allowed_tags pref has been migrated to values of the two prefs below
+pref("mailnews.display.html_sanitizer.drop_non_css_presentation", true); // whether to drop <font>, <center>, align='...', etc.
+pref("mailnews.display.html_sanitizer.drop_media", false); // whether to drop <img>, <video> and <audio>
+pref("mailnews.display.disallow_mime_handlers", 0); /* Let only a few classes process incoming data. This protects from bugs (e.g. buffer overflows) and from security loopholes (e.g. allowing unchecked HTML in some obscure classes, although the user has html_as > 0).
+This option is mainly for the UI of html_as.
+0 = allow all available classes
+1 = Use hardcoded blacklist to avoid rendering (incoming) HTML
+2 = ... and inline images
+3 = ... and some other uncommon content types
+100 = Use hardcoded whitelist to avoid even more bugs(buffer overflows).
+ This mode will limit the features available (e.g. uncommon
+ attachment types and inline images) and is for paranoid users.
+*/
+// RSS rendering options, see prior 4 prefs above.
+pref("rss.display.prefer_plaintext", false);
+pref("rss.display.html_as", 0);
+pref("rss.display.disallow_mime_handlers", 0);
+
+// Feed message display (summary or web page), on select.
+// 0 - global override, load web page
+// 1 - global override, load summary
+// 2 - use default feed folder setting from Subscribe dialog; if no setting default to 1
+pref("rss.show.summary", 1);
+
+// Feed message display (summary or web page), on open.
+// Action on double click or enter in threadpane for a feed message.
+// 0 - open content-base url in new window
+// 1 - open summary in new window
+// 2 - toggle load summary and content-base url in message pane
+// 3 - load content-base url in browser
+pref("rss.show.content-base", 0);
+
+// Feed message additional web page display.
+// 0 - no action
+// 1 - load web page in default browser, on select
+pref("rss.message.loadWebPageOnSelect", 0);
+
+// Feeds system logging, uses log4moz conventions.
+pref("Feeds.logging.console", "Info");
+
+pref("mail.forward_message_mode", 0); // 0=default as attachment 2=forward as inline with attachments, (obsolete 4.x value)1=forward as quoted (mapped to 2 in mozilla)
+pref("mail.forward_add_extension", true); // add .eml extension when forwarding as attachment
+// Prefix of for mail forwards. E.g. "Fwd" -> subject will be Fwd: <subject>
+pref("mail.forward_subject_prefix", "Fwd");
+
+pref("mail.startup.enabledMailCheckOnce", false);
+
+pref("mailnews.send_plaintext_flowed", true); // RFC 2646=======
+pref("mailnews.display.disable_format_flowed_support", false);
+pref("mailnews.nav_crosses_folders", 1); // prompt user when crossing folders
+
+// these two news.cancel.* prefs are for use by QA for automated testing. see bug #31057
+pref("news.cancel.confirm", true);
+pref("news.cancel.alert_on_success", true);
+pref("mail.SpellCheckBeforeSend", false);
+pref("mail.spellcheck.inline", true);
+pref("mail.phishing.detection.enabled", true); // enable / disable phishing detection for link clicks
+pref("mail.warn_on_send_accel_key", true);
+pref("mail.enable_autocomplete", true);
+pref("mailnews.html_domains", "");
+pref("mailnews.plaintext_domains", "");
+pref("mailnews.global_html_domains.version", 1);
+
+/////////////////////////////////////////////////////////////////
+// Privacy Controls for Handling Remote Content
+/////////////////////////////////////////////////////////////////
+// Specific plugins pref just for message content. RSS is not covered by this.
+pref("mailnews.message_display.allow_plugins", false);
+pref("mailnews.message_display.disable_remote_image", true);
+
+/////////////////////////////////////////////////////////////////
+// Trusted Mail Domains
+//
+// Specific domains can be white listed to bypass various privacy controls in Thunderbird
+// such as blocking remote images, the phishing detector, etc. This is particularly
+// useful for business deployments where images or links reference servers inside a
+// corporate intranet. For multiple domains, separate them with a comma. i.e.
+// pref("mail.trusteddomains", "mozilla.org,mozillafoundation.org");
+/////////////////////////////////////////////////////////////////
+pref("mail.trusteddomains", "");
+
+pref("mail.imap.use_status_for_biff", true);
+
+pref("mail.quota.mainwindow_threshold.show", 75); // in percent. when the quota meter starts showing up at all. decrease this for it to be more than a warning.
+pref("mail.quota.mainwindow_threshold.warning", 80); // when it gets yellow
+pref("mail.quota.mainwindow_threshold.critical", 95); // when it gets red
+
+// Pref controlling the updates on the pre-configured accounts.
+// In order to add new pre-configured accounts (after a version),
+// increase the following version number besides updating the
+// pref mail.accountmanager.appendaccounts
+pref("mailnews.append_preconfig_accounts.version", 1);
+
+// Pref controlling the updates on the pre-configured smtp servers.
+// In order to add new pre-configured smtp servers (after a version),
+// increase the following version number besides updating the
+// pref mail.smtpservers.appendsmtpservers
+pref("mail.append_preconfig_smtpservers.version", 1);
+
+pref("mail.biff.alert.show_preview", true);
+pref("mail.biff.alert.show_subject", true);
+pref("mail.biff.alert.show_sender", true);
+pref("mail.biff.alert.preview_length", 40);
+
+pref("mail.biff.play_sound", true);
+// 0 == default system sound, 1 == user specified wav
+pref("mail.biff.play_sound.type", 0);
+// _moz_mailbeep is a magic key, for the default sound.
+// otherwise, this needs to be a file url
+pref("mail.biff.play_sound.url", "");
+pref("mail.biff.show_alert", true);
+pref("mail.biff.show_tray_icon", true); // currently Windows-only
+pref("mail.biff.show_balloon", false); // currently Windows-only
+pref("mail.biff.animate_dock_icon", false);
+
+// add jitter to biff interval
+pref("mail.biff.add_interval_jitter", true);
+
+#ifdef MOZ_SUITE
+// if true, check for new mail even when opening non-mail windows
+pref("mail.biff.on_new_window", true);
+#endif
+
+// If true, the number used in the Mac OS X dock notification will be the
+// the number of "new" messages, as per the classic Thunderbird definition.
+// Defaults to false, which notifies about the number of unread messages.
+pref("mail.biff.use_new_count_in_mac_dock", false);
+
+// Content disposition for attachments (except binary files and vcards).
+// 0= Content-Disposition: inline
+// 1= Content-Disposition: attachment
+pref("mail.content_disposition_type", 1);
+
+// Experimental option to send message in the background - don't wait to close window.
+pref("mailnews.sendInBackground", false);
+// Will show a progress dialog when saving or sending a message
+pref("mailnews.show_send_progress", true);
+pref("mail.server.default.retainBy", 1);
+
+pref("mailnews.ui.junk.firstuse", true);
+pref("mailnews.ui.junk.manualMarkAsJunkMarksRead", true);
+
+// for manual upgrades of certain UI features.
+// 1 -> 2 is for the folder pane tree landing, to hide the
+// unread and total columns, see msgMail3PaneWindow.js
+pref("mail.ui.folderpane.version", 1);
+
+// for manual upgrades of certain UI features.
+#ifdef MOZ_SUITE
+pref("mailnews.ui.threadpane.version", 5);
+#else
+// Thunderbird uses this pref in msgMail3PaneWindow.js for bad reasons.
+pref("mailnews.ui.threadpane.version", 7);
+#endif
+// for manual upgrades of certain UI features.
+// 1 -> 2 is for the ab results pane tree landing
+// to hide the non default columns in the addressbook dialog
+// see abCommon.js and addressbook.js
+pref("mailnews.ui.addressbook_results.version", 1);
+// for manual upgrades of certain UI features.
+// 1 -> 2 is for the ab results pane tree landing
+// to hide the non default columns in the addressbook sidebar panel
+// see abCommon.js and addressbook-panel.js
+pref("mailnews.ui.addressbook_panel_results.version", 1);
+// for manual upgrades of certain UI features.
+// 1 -> 2 is for the ab results pane tree landing
+// to hide the non default columns in the select addresses dialog
+// see abCommon.js and abSelectAddressesDialog.js
+pref("mailnews.ui.select_addresses_results.version", 1);
+// for manual upgrades of certain UI features.
+// 1 -> 2 is for the ab results pane
+// to hide the non default columns in the advanced directory search dialog
+// see abCommon.js and ABSearchDialog.js
+pref("mailnews.ui.advanced_directory_search_results.version", 1);
+//If set to a number greater than 0, msg compose windows will be recycled in order to open them quickly
+pref("mail.compose.max_recycled_windows", 1);
+
+// default description and color prefs for tags
+// (we keep the .labels. names for backwards compatibility)
+pref("mailnews.labels.description.1", "chrome://messenger/locale/messenger.properties");
+pref("mailnews.labels.description.2", "chrome://messenger/locale/messenger.properties");
+pref("mailnews.labels.description.3", "chrome://messenger/locale/messenger.properties");
+pref("mailnews.labels.description.4", "chrome://messenger/locale/messenger.properties");
+pref("mailnews.labels.description.5", "chrome://messenger/locale/messenger.properties");
+pref("mailnews.labels.color.1", "#FF0000"); // default: red
+pref("mailnews.labels.color.2", "#FF9900"); // default: orange
+pref("mailnews.labels.color.3", "#009900"); // default: green
+pref("mailnews.labels.color.4", "#3333FF"); // default: blue
+pref("mailnews.labels.color.5", "#993399"); // default: purple
+
+//default null headers
+//example "X-Warn: XReply", list of hdrs separated by ": "
+pref("mailnews.customHeaders", "");
+
+// default msg compose font prefs
+pref("msgcompose.font_face", "");
+pref("msgcompose.font_size", "medium");
+pref("msgcompose.text_color", "#000000");
+pref("msgcompose.background_color", "#FFFFFF");
+
+// When there is no disclosed recipients (only bcc), we should address the message to empty group
+// to prevent some mail server to disclose the bcc recipients
+pref("mail.compose.add_undisclosed_recipients", true);
+
+// Set this preference to true to tell mail not to attach the source of a link to a local
+// network file (file://///<network name>/<path>/<file name>). Windows only
+pref("mail.compose.dont_attach_source_of_local_network_links", false);
+pref("mail.compose.dontWarnMail2Newsgroup", false);
+
+// these prefs (in minutes) are here to help QA test this feature
+// "mail.purge.min_delay", never purge a junk folder more than once every 480 minutes (60 mins/hour * 8 hours)
+// "mail.purge.timer_interval", fire the purge timer every 5 minutes, starting 5 minutes after we load accounts
+pref("mail.purge.min_delay", 480);
+pref("mail.purge.timer_interval", 5);
+
+// Set to false if opening a message in the standalone message window or viewing
+// it in the message pane should never mark it as read.
+pref("mailnews.mark_message_read.auto", true);
+
+// Set to true if viewing a message should mark it as read after the msg is
+// viewed in the message pane for a specified time interval in seconds.
+pref("mailnews.mark_message_read.delay", false);
+pref("mailnews.mark_message_read.delay.interval", 5); // measured in seconds
+
+// delay after which messages are showed when moving through them with cursors
+// during thread pane navigation
+pref("mailnews.threadpane_select_delay", 250); // measured in milliseconds
+
+// require a password before showing imap or local headers in thread pane
+pref("mail.password_protect_local_cache", false);
+
+// import option to skip the first record, recorded so that we can save
+// the users last used preference.
+pref("mailnews.import.text.skipfirstrecord", true);
+
+// automatically scale attached images that are displayed inline
+pref("mail.enable_automatic_image_resizing", true);
+
+#ifdef MOZ_SUITE
+#ifdef XP_WIN
+pref("ldap_2.servers.oe.uri", "moz-aboutlookdirectory://oe/");
+pref("ldap_2.servers.oe.description", "chrome://messenger/locale/addressbook/addressBook.properties");
+pref("ldap_2.servers.oe.dirType", 3);
+#endif
+#endif
+#ifdef XP_MACOSX
+pref("ldap_2.servers.osx.uri", "moz-abosxdirectory:///");
+pref("ldap_2.servers.osx.description", "chrome://messenger/locale/addressbook/addressBook.properties");
+pref("ldap_2.servers.osx.dirType", 3);
+pref("mail.notification.sound", "");
+pref("mail.notification.count.inbox_only", true);
+// Work around bug 482811 by disabling slow script warning for chrome scripts on Mac
+pref("dom.max_chrome_script_run_time", 0);
+#endif
+
+// gtk2 (*nix) lacks transparent/translucent drag support (bug 376238), so we
+// want to disable it so people can see where they are dragging things.
+// (Stock gtk drag icons will be used instead.)
+#ifdef MOZ_WIDGET_GTK2
+pref("nglayout.enable_drag_images", false);
+#endif
+
+#ifdef XP_OS2
+pref("mail.compose.max_recycled_windows", 0);
+#endif
+
+// For the Empty Junk/Trash confirmation dialogs.
+pref("mailnews.emptyJunk.dontAskAgain", false);
+pref("mailnews.emptyTrash.dontAskAgain", false);
+
+// where to fetch auto config information from.
+pref("mailnews.auto_config_url", "https://live.mozillamessaging.com/autoconfig/v1.1/");
+// Added in bug 551519. Remove when bug 545866 is fixed.
+pref("mailnews.mx_service_url", "https://live.mozillamessaging.com/dns/mx/");
+
+// -- Summary Database options
+// dontPreserveOnCopy: a space separated list of properties that are not
+// copied to the new nsIMsgHdr when a message is copied.
+// Allows extensions to control preservation of properties.
+pref("mailnews.database.summary.dontPreserveOnCopy",
+ "account msgOffset threadParent msgThreadId statusOfset flags size numLines ProtoThreadFlags label gloda-id gloda-dirty storeToken");
+
+// dontPreserveOnMove: a space separated list of properties that are not
+// copied to the new nsIMsgHdr when a message is moved.
+// Allows extensions to control preservation of properties.
+pref("mailnews.database.summary.dontPreserveOnMove",
+ "account msgOffset threadParent msgThreadId statusOfset flags size numLines ProtoThreadFlags label storeToken");
+
+// -- Global Database (gloda) options
+// Should the indexer be enabled?
+pref("mailnews.database.global.indexer.enabled", false);
+// Should we output warnings and errors to the "error console"?
+pref("mailnews.database.global.logging.console", false);
+// Should we output all output levels to stdout via dump?
+pref("mailnews.database.global.logging.dump", false);
+// Should we consider outputting all levels via the network?
+pref("mailnews.database.global.logging.net", false);
+// Rate of growth of the gloda cache, whose maximum value is 8 MiB and max is 64 MiB.
+// See more: https://developer.mozilla.org/en/Thunderbird/gloda#Cache_Size"
+pref("mailnews.database.global.datastore.cache_to_memory_permillage", 10);
+
+// default field order in the fieldmap
+pref("mailnews.import.text.fieldmap", "+0,+1,+2,+3,+4,+5,+36,+6,+7,+8,+9,+10,+11,+12,+13,+14,+15,+16,+17,+18,+19,+20,+21,+22,+23,+24,+25,+26,+27,+28,+29,+30,+31,+32,+33,+34,+35");
+
+// On networks deploying QoS, it is recommended that these be lockpref()'d,
+// since inappropriate marking can easily overwhelm bandwidth reservations
+// for certain services (i.e. EF for VoIP, AF4x for interactive video,
+// AF3x for broadcast/streaming video, etc)
+
+// default value for SMTP and POP3.
+// in a DSCP environment this should be 48 (0x30, or AF12) per RFC-4594,
+// Section 4.8 "High-Throughput Data Service Class"
+pref("mail.pop3.qos", 0);
+pref("mail.smtp.qos", 0);
+pref("mail.nntp.qos", 0);
+
+// default value for IMAP4
+// in a DSCP environment this should be 56 (0x38, or AF13), ibid.
+pref("mail.imap.qos", 0);
+
+// PgpMime Addon
+pref("mail.pgpmime.addon_url", "https://addons.mozilla.org/addon/enigmail/");
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Kai Engert <kengert@redhat.com>
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved
+ * Copyright(c) Airbus Defence and Space 2014 - All rights reserved */
+
+#include "nsICMSMessage.h"
+#include "nsICMSMessage2.h"
+#include "nsICMSMessageErrors.h"
+#include "nsICMSDecoder.h"
+#include "mimecms.h"
+#include "mimemsig.h"
+#include "nspr.h"
+#include "mimemsg.h"
+#include "mimemoz2.h"
+#include "nsIURI.h"
+#include "nsIMsgWindow.h"
+#include "nsIMsgMailNewsUrl.h"
+#include "nsIMimeMiscStatus.h"
+#include "nsIMsgSMIMEHeaderSink.h"
+#include "nsCOMPtr.h"
+#include "nsAutoPtr.h"
+#include "nsIX509Cert.h"
+#include "nsIMsgHeaderParser.h"
+#include "nsServiceManagerUtils.h"
+#include "nsComponentManagerUtils.h"
+#include "nsThreadUtils.h"
+#include "nsProxyRelease.h"
+/* secure header */
+#include "nsIArray.h"
+#include "nsIMutableArray.h"
+
+#define MIME_SUPERCLASS mimeEncryptedClass
+MimeDefClass(MimeEncryptedCMS, MimeEncryptedCMSClass,
+ mimeEncryptedCMSClass, &MIME_SUPERCLASS);
+
+static void *MimeCMS_init(MimeObject *, int (*output_fn) (const char *, int32_t, void *), void *);
+static int MimeCMS_write (const char *, int32_t, void *);
+static int MimeCMS_eof (void *, bool);
+static char * MimeCMS_generate (void *);
+static void MimeCMS_free (void *);
+
+extern int SEC_ERROR_CERT_ADDR_MISMATCH;
+
+static int MimeEncryptedCMSClassInitialize(MimeEncryptedCMSClass *clazz)
+{
+#ifdef DEBUG
+ MimeObjectClass *oclass = (MimeObjectClass *) clazz;
+ NS_ASSERTION(!oclass->class_initialized, "1.2 <mscott@netscape.com> 01 Nov 2001 17:59");
+#endif
+
+ MimeEncryptedClass *eclass = (MimeEncryptedClass *) clazz;
+ eclass->crypto_init = MimeCMS_init;
+ eclass->crypto_write = MimeCMS_write;
+ eclass->crypto_eof = MimeCMS_eof;
+ eclass->crypto_generate_html = MimeCMS_generate;
+ eclass->crypto_free = MimeCMS_free;
+
+ return 0;
+}
+
+
+typedef struct MimeCMSdata
+{
+ int (*output_fn) (const char *buf, int32_t buf_size, void *output_closure);
+ void *output_closure;
+ nsCOMPtr<nsICMSDecoder> decoder_context;
+ nsCOMPtr<nsICMSMessage> content_info;
+ bool ci_is_encrypted;
+ char *sender_addr;
+ bool decoding_failed;
+ uint32_t decoded_bytes;
+ MimeObject *self;
+ bool parent_is_encrypted_p;
+ bool parent_holds_stamp_p;
+ nsCOMPtr<nsIMsgSMIMEHeaderSink> smimeHeaderSink;
+
+ MimeCMSdata()
+ :output_fn(nullptr),
+ output_closure(nullptr),
+ ci_is_encrypted(false),
+ sender_addr(nullptr),
+ decoding_failed(false),
+ decoded_bytes(0),
+ self(nullptr),
+ parent_is_encrypted_p(false),
+ parent_holds_stamp_p(false)
+ {
+ }
+
+ ~MimeCMSdata()
+ {
+ if(sender_addr)
+ PR_Free(sender_addr);
+
+ // Do an orderly release of nsICMSDecoder and nsICMSMessage //
+ if (decoder_context)
+ {
+ nsCOMPtr<nsICMSMessage> cinfo;
+ decoder_context->Finish(getter_AddRefs(cinfo));
+ }
+ }
+} MimeCMSdata;
+
+/* SEC_PKCS7DecoderContentCallback for SEC_PKCS7DecoderStart() */
+static void MimeCMS_content_callback (void *arg, const char *buf, unsigned long length)
+{
+ int status;
+ MimeCMSdata *data = (MimeCMSdata *) arg;
+ if (!data) return;
+
+ if (!data->output_fn)
+ return;
+
+ PR_SetError(0,0);
+ status = data->output_fn (buf, length, data->output_closure);
+ if (status < 0)
+ {
+ PR_SetError(status, 0);
+ data->output_fn = 0;
+ return;
+ }
+
+ data->decoded_bytes += length;
+}
+
+bool MimeEncryptedCMS_encrypted_p (MimeObject *obj)
+{
+ bool encrypted;
+
+ if (!obj) return false;
+ if (mime_typep(obj, (MimeObjectClass *) &mimeEncryptedCMSClass))
+ {
+ MimeEncrypted *enc = (MimeEncrypted *) obj;
+ MimeCMSdata *data = (MimeCMSdata *) enc->crypto_closure;
+ if (!data || !data->content_info) return false;
+ data->content_info->ContentIsEncrypted(&encrypted);
+ return encrypted;
+ }
+ return false;
+}
+
+// extern MimeMessageClass mimeMessageClass; /* gag */
+
+static void ParseRFC822Addresses (const char *line, nsCString &names, nsCString &addresses)
+{
+ uint32_t numAddresses;
+ nsresult res;
+ nsCOMPtr<nsIMsgHeaderParser> pHeader = do_GetService(NS_MAILNEWS_MIME_HEADER_PARSER_CONTRACTID, &res);
+
+ if (NS_SUCCEEDED(res))
+ {
+ pHeader->ParseHeaderAddresses(line, getter_Copies(names),
+ getter_Copies(addresses), &numAddresses);
+ }
+}
+
+bool MimeCMSHeadersAndCertsMatch(nsICMSMessage *content_info,
+ nsIX509Cert *signerCert,
+ const char *from_addr,
+ const char *from_name,
+ const char *sender_addr,
+ const char *sender_name,
+ bool *signing_cert_without_email_address)
+{
+ nsCString cert_addr;
+ bool match = true;
+ bool foundFrom = false;
+ bool foundSender = false;
+
+ /* Find the name and address in the cert.
+ */
+ if (content_info)
+ {
+ // Extract any address contained in the cert.
+ // This will be used for testing, whether the cert contains no addresses at all.
+ content_info->GetSignerEmailAddress (getter_Copies(cert_addr));
+ }
+
+ if (signing_cert_without_email_address)
+ *signing_cert_without_email_address = cert_addr.IsEmpty();
+
+ /* Now compare them --
+ consider it a match if the address in the cert matches either the
+ address in the From or Sender field
+ */
+
+ /* If there is no addr in the cert at all, it can not match and we fail. */
+ if (cert_addr.IsEmpty())
+ {
+ match = false;
+ }
+ else
+ {
+ if (signerCert)
+ {
+ if (from_addr && *from_addr)
+ {
+ NS_ConvertASCIItoUTF16 ucs2From(from_addr);
+ if (NS_FAILED(signerCert->ContainsEmailAddress(ucs2From, &foundFrom)))
+ {
+ foundFrom = false;
+ }
+ }
+
+ if (sender_addr && *sender_addr)
+ {
+ NS_ConvertASCIItoUTF16 ucs2Sender(sender_addr);
+ if (NS_FAILED(signerCert->ContainsEmailAddress(ucs2Sender, &foundSender)))
+ {
+ foundSender = false;
+ }
+ }
+ }
+
+ if (!foundSender && !foundFrom)
+ {
+ match = false;
+ }
+ }
+
+ return match;
+}
+
+class nsSMimeVerificationListener : public nsISMimeVerificationListener
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSISMIMEVERIFICATIONLISTENER
+
+ nsSMimeVerificationListener(const char *aFromAddr, const char *aFromName,
+ const char *aSenderAddr, const char *aSenderName,
+ nsIMsgSMIMEHeaderSink *aHeaderSink, int32_t aMimeNestingLevel);
+
+ virtual ~nsSMimeVerificationListener() {}
+
+protected:
+ /**
+ * It is safe to declare this implementation as thread safe,
+ * despite not using a lock to protect the members.
+ * Because of the way the object will be used, we don't expect a race.
+ * After construction, the object is passed to another thread,
+ * but will no longer be accessed on the original thread.
+ * The other thread is unable to access/modify self's data members.
+ * When the other thread is finished, it will call into the "Notify"
+ * callback. Self's members will be accessed on the other thread,
+ * but this is fine, because there is no race with the original thread.
+ * Race-protection for XPCOM reference counting is sufficient.
+ */
+ bool mSinkIsNull;
+ nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> mHeaderSink;
+ int32_t mMimeNestingLevel;
+
+ nsCString mFromAddr;
+ nsCString mFromName;
+ nsCString mSenderAddr;
+ nsCString mSenderName;
+};
+
+class SignedStatusRunnable : public nsRunnable
+{
+public:
+ SignedStatusRunnable(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink, int32_t aNestingLevel,
+ int32_t aSignatureStatus, nsIX509Cert *aSignerCert);
+ NS_DECL_NSIRUNNABLE
+protected:
+ nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> m_sink;
+ int32_t m_nestingLevel;
+ int32_t m_signatureStatus;
+ nsCOMPtr<nsIX509Cert> m_signerCert;
+};
+
+SignedStatusRunnable::SignedStatusRunnable(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink,
+ int32_t aNestingLevel,
+ int32_t aSignatureStatus,
+ nsIX509Cert *aSignerCert) :
+ m_sink(aSink), m_nestingLevel(aNestingLevel),
+ m_signatureStatus(aSignatureStatus), m_signerCert(aSignerCert)
+{
+}
+
+NS_IMETHODIMP SignedStatusRunnable::Run()
+{
+ return m_sink->SignedStatus(m_nestingLevel, m_signatureStatus, m_signerCert);
+}
+
+
+nsresult ProxySignedStatus(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink,
+ int32_t aNestingLevel,
+ int32_t aSignatureStatus,
+ nsIX509Cert *aSignerCert)
+{
+ nsRefPtr<SignedStatusRunnable> signedStatus =
+ new SignedStatusRunnable(aSink, aNestingLevel, aSignatureStatus, aSignerCert);
+ return NS_DispatchToMainThread(signedStatus, NS_DISPATCH_SYNC);
+}
+
+/**
+*
+*/
+class SMIMEReceiptRequestStatusRunnable : public nsRunnable
+{
+public:
+ SMIMEReceiptRequestStatusRunnable(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink, unsigned char* signedContentIdentifier,
+ uint32_t signedContentIdentifierLen, uint32_t receiptsFrom, nsCString receiptsTo,
+ unsigned char* originatorSignatureValue, uint32_t originatorSignatureValueLen,
+ unsigned char* originatorContentType, uint32_t originatorContentTypeLen,
+ unsigned char* msgSigDigest, uint32_t msgSigDigestLen);
+ NS_DECL_NSIRUNNABLE
+protected:
+ nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> m_sink;
+ unsigned char* m_signedContentIdentifier;
+ uint32_t m_signedContentIdentifierLen;
+ uint32_t m_receiptsFrom;
+ nsCString m_receiptsTo;
+ unsigned char* m_originatorSignatureValue;
+ uint32_t m_originatorSignatureValueLen;
+ unsigned char* m_originatorContentType;
+ uint32_t m_originatorContentTypeLen;
+ unsigned char* m_msgSigDigest;
+ uint32_t m_msgSigDigestLen;
+};
+
+SMIMEReceiptRequestStatusRunnable::SMIMEReceiptRequestStatusRunnable(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink,
+ unsigned char* signedContentIdentifier,
+ uint32_t signedContentIdentifierLen, uint32_t receiptsFrom, nsCString receiptsTo,
+ unsigned char* originatorSignatureValue, uint32_t originatorSignatureValueLen,
+ unsigned char* originatorContentType, uint32_t originatorContentTypeLen,
+ unsigned char* msgSigDigest, uint32_t msgSigDigestLen) :
+ m_sink(aSink), m_signedContentIdentifier(signedContentIdentifier),
+ m_signedContentIdentifierLen(signedContentIdentifierLen), m_receiptsFrom(receiptsFrom),
+ m_receiptsTo(receiptsTo), m_originatorSignatureValue(originatorSignatureValue),
+ m_originatorSignatureValueLen(originatorSignatureValueLen), m_originatorContentType(originatorContentType),
+ m_originatorContentTypeLen(originatorContentTypeLen), m_msgSigDigest(msgSigDigest), m_msgSigDigestLen(msgSigDigestLen)
+{
+}
+
+NS_IMETHODIMP SMIMEReceiptRequestStatusRunnable::Run()
+{
+ return m_sink->SMIMEReceiptRequestStatus(m_signedContentIdentifier,
+ m_signedContentIdentifierLen,
+ m_receiptsFrom,
+ NS_ConvertUTF8toUTF16(m_receiptsTo),
+ m_originatorSignatureValue,
+ m_originatorSignatureValueLen,
+ m_originatorContentType,
+ m_originatorContentTypeLen,
+ m_msgSigDigest,
+ m_msgSigDigestLen);
+}
+
+
+nsresult ProxySMIMEReceiptRequestStatus(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink,
+ unsigned char* signedContentIdentifier,
+ uint32_t signedContentIdentifierLen, uint32_t receiptsFrom, nsCString receiptsTo,
+ unsigned char* originatorSignatureValue, uint32_t originatorSignatureValueLen,
+ unsigned char* originatorContentType, uint32_t originatorContentTypeLen,
+ unsigned char* msgSigDigest, uint32_t msgSigDigestLen)
+{
+ nsRefPtr<SMIMEReceiptRequestStatusRunnable> receiptRequestStatusRunnable =
+ new SMIMEReceiptRequestStatusRunnable(aSink, signedContentIdentifier, signedContentIdentifierLen, receiptsFrom,
+ receiptsTo, originatorSignatureValue, originatorSignatureValueLen,
+ originatorContentType, originatorContentTypeLen, msgSigDigest,
+ msgSigDigestLen);
+ return NS_DispatchToMainThread(receiptRequestStatusRunnable, NS_DISPATCH_SYNC);
+}
+
+/**
+*
+*/
+class SMIMEReceiptStatusRunnable : public nsRunnable
+{
+public:
+ SMIMEReceiptStatusRunnable(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink, unsigned char* signedContentIdentifier,
+ uint32_t signedContentIdentifierLen,
+ unsigned char* originatorSignatureValue, uint32_t originatorSignatureValueLen,
+ unsigned char* originatorContentType, uint32_t originatorContentTypeLen,
+ unsigned char* msgSigDigest, uint32_t msgSigDigestLen);
+ NS_DECL_NSIRUNNABLE
+protected:
+ nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> m_sink;
+ unsigned char* m_signedContentIdentifier;
+ uint32_t m_signedContentIdentifierLen;
+ unsigned char* m_originatorSignatureValue;
+ uint32_t m_originatorSignatureValueLen;
+ unsigned char* m_originatorContentType;
+ uint32_t m_originatorContentTypeLen;
+ unsigned char* m_msgSigDigest;
+ uint32_t m_msgSigDigestLen;
+};
+
+SMIMEReceiptStatusRunnable::SMIMEReceiptStatusRunnable(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink,
+ unsigned char* signedContentIdentifier,
+ uint32_t signedContentIdentifierLen,
+ unsigned char* originatorSignatureValue, uint32_t originatorSignatureValueLen,
+ unsigned char* originatorContentType, uint32_t originatorContentTypeLen,
+ unsigned char* msgSigDigest, uint32_t msgSigDigestLen) :
+ m_sink(aSink), m_signedContentIdentifier(signedContentIdentifier),
+ m_signedContentIdentifierLen(signedContentIdentifierLen), m_originatorSignatureValue(originatorSignatureValue),
+ m_originatorSignatureValueLen(originatorSignatureValueLen), m_originatorContentType(originatorContentType),
+ m_originatorContentTypeLen(originatorContentTypeLen), m_msgSigDigest(msgSigDigest), m_msgSigDigestLen(msgSigDigestLen)
+{
+}
+
+NS_IMETHODIMP SMIMEReceiptStatusRunnable::Run()
+{
+ return m_sink->SMIMEReceiptStatus(m_signedContentIdentifier,
+ m_signedContentIdentifierLen,
+ m_originatorSignatureValue,
+ m_originatorSignatureValueLen,
+ m_originatorContentType,
+ m_originatorContentTypeLen,
+ m_msgSigDigest,
+ m_msgSigDigestLen);
+}
+
+
+nsresult ProxySMIMEReceiptStatus(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink,
+ unsigned char* signedContentIdentifier,
+ uint32_t signedContentIdentifierLen,
+ unsigned char* originatorSignatureValue, uint32_t originatorSignatureValueLen,
+ unsigned char* originatorContentType, uint32_t originatorContentTypeLen,
+ unsigned char* msgSigDigest, uint32_t msgSigDigestLen)
+{
+ nsRefPtr<SMIMEReceiptStatusRunnable> receiptStatusRunnable =
+ new SMIMEReceiptStatusRunnable(aSink, signedContentIdentifier, signedContentIdentifierLen, originatorSignatureValue,
+ originatorSignatureValueLen,
+ originatorContentType, originatorContentTypeLen, msgSigDigest,
+ msgSigDigestLen);
+ return NS_DispatchToMainThread(receiptStatusRunnable, NS_DISPATCH_SYNC);
+}
+
+/**
+*
+*/
+class SecureHeaderStatusRunnable : public nsRunnable
+{
+public:
+ SecureHeaderStatusRunnable(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink,
+ nsCOMPtr<nsIMutableArray> asecureHeaders,
+ PRInt32 acanonAlgo);
+ NS_DECL_NSIRUNNABLE
+protected:
+ nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> m_sink;
+ nsCOMPtr<nsIMutableArray> m_secureHeaders;
+ PRInt32 m_canonAlgo;
+};
+
+SecureHeaderStatusRunnable::SecureHeaderStatusRunnable(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink,
+ nsCOMPtr<nsIMutableArray> asecureHeaders,
+ PRInt32 acanonAlgo) :
+ m_sink(aSink), m_secureHeaders( asecureHeaders),
+ m_canonAlgo(acanonAlgo)
+{
+}
+
+NS_IMETHODIMP SecureHeaderStatusRunnable::Run()
+{
+ return m_sink->SecureHeadersStatus(m_secureHeaders, m_canonAlgo);
+}
+
+
+nsresult ProxySecureHeaderStatus(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink,
+ nsCOMPtr<nsIMutableArray> asecureHeaders,
+ PRInt32 acanonAlgo)
+{
+ nsRefPtr<SecureHeaderStatusRunnable> secureHeaderStatus =
+ new SecureHeaderStatusRunnable(aSink, asecureHeaders, acanonAlgo);
+ return NS_DispatchToMainThread(secureHeaderStatus, NS_DISPATCH_SYNC);
+}
+
+class SecurityLabelStatusRunnable : public nsRunnable
+{
+public:
+ SecurityLabelStatusRunnable(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink,
+ nsCString securityPolicyIdentifier,
+ PRInt32 securityClassification,
+ nsCString privacyMark,
+ nsCString securityCategories);
+ NS_DECL_NSIRUNNABLE
+protected:
+ nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> m_sink;
+ nsCString m_securityPolicyIdentifier;
+ PRInt32 m_securityClassification;
+ nsCString m_privacyMark;
+ nsCString m_securityCategories;
+};
+
+SecurityLabelStatusRunnable::SecurityLabelStatusRunnable(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink,
+ nsCString securityPolicyIdentifier,
+ PRInt32 securityClassification,
+ nsCString privacyMark,
+ nsCString securityCategories) :
+ m_sink(aSink), m_securityClassification( securityClassification),
+ m_securityPolicyIdentifier(securityPolicyIdentifier), m_privacyMark(privacyMark),
+ m_securityCategories(securityCategories)
+{
+}
+
+NS_IMETHODIMP SecurityLabelStatusRunnable::Run()
+{
+ return m_sink->SecurityLabelStatus(NS_ConvertUTF8toUTF16(m_securityPolicyIdentifier),
+ m_securityClassification,
+ NS_ConvertUTF8toUTF16(m_privacyMark),
+ NS_ConvertUTF8toUTF16(m_securityCategories));
+}
+
+
+nsresult ProxySecurityLabelStatus(const nsMainThreadPtrHandle<nsIMsgSMIMEHeaderSink> &aSink,
+ nsCString securityPolicyIdentifier,
+ PRInt32 securityClassification,
+ nsCString privacyMark,
+ nsCString securityCategories)
+
+
+{
+ nsRefPtr<SecurityLabelStatusRunnable> securityLabelStatusRunnable =
+ new SecurityLabelStatusRunnable(aSink, securityPolicyIdentifier, securityClassification, privacyMark, securityCategories);
+ return NS_DispatchToMainThread(securityLabelStatusRunnable, NS_DISPATCH_SYNC);
+}
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsSMimeVerificationListener, nsISMimeVerificationListener)
+
+nsSMimeVerificationListener::nsSMimeVerificationListener(const char *aFromAddr, const char *aFromName,
+ const char *aSenderAddr, const char *aSenderName,
+ nsIMsgSMIMEHeaderSink *aHeaderSink, int32_t aMimeNestingLevel)
+{
+ mHeaderSink = new nsMainThreadPtrHolder<nsIMsgSMIMEHeaderSink>(aHeaderSink);
+ mSinkIsNull = !aHeaderSink;
+ mMimeNestingLevel = aMimeNestingLevel;
+
+ mFromAddr = aFromAddr;
+ mFromName = aFromName;
+ mSenderAddr = aSenderAddr;
+ mSenderName = aSenderName;
+}
+
+NS_IMETHODIMP nsSMimeVerificationListener::Notify(nsICMSMessage2 *aVerifiedMessage,
+ nsresult aVerificationResultCode)
+{
+ // Only continue if we have a valid pointer to the UI
+ NS_ENSURE_FALSE(mSinkIsNull, NS_OK);
+
+ NS_ENSURE_TRUE(aVerifiedMessage, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsICMSMessage> msg = do_QueryInterface(aVerifiedMessage);
+ NS_ENSURE_TRUE(msg, NS_ERROR_FAILURE);
+
+ nsCOMPtr<nsIX509Cert> signerCert;
+ msg->GetSignerCert(getter_AddRefs(signerCert));
+
+ int32_t signature_status = nsICMSMessageErrors::GENERAL_ERROR;
+
+ if (NS_FAILED(aVerificationResultCode))
+ {
+ if (NS_ERROR_MODULE_SECURITY == NS_ERROR_GET_MODULE(aVerificationResultCode))
+ signature_status = NS_ERROR_GET_CODE(aVerificationResultCode);
+ else if (NS_ERROR_NOT_IMPLEMENTED == aVerificationResultCode)
+ signature_status = nsICMSMessageErrors::VERIFY_ERROR_PROCESSING;
+ }
+ else
+ {
+ bool signing_cert_without_email_address;
+
+ bool good_p = MimeCMSHeadersAndCertsMatch(msg, signerCert,
+ mFromAddr.get(), mFromName.get(),
+ mSenderAddr.get(), mSenderName.get(),
+ &signing_cert_without_email_address);
+ if (!good_p)
+ {
+ if (signing_cert_without_email_address)
+ signature_status = nsICMSMessageErrors::VERIFY_CERT_WITHOUT_ADDRESS;
+ else
+ signature_status = nsICMSMessageErrors::VERIFY_HEADER_MISMATCH;
+ }
+ else
+ signature_status = nsICMSMessageErrors::SUCCESS;
+ }
+
+ ProxySignedStatus(mHeaderSink, mMimeNestingLevel, signature_status, signerCert);
+
+ if (signature_status == nsICMSMessageErrors::SUCCESS)
+ {
+ // Handle Security Label
+ bool hasSecurityLabel = PR_FALSE;
+ nsCString securityPolicyIdentifier;
+ PRInt32 securityClassification = -1;
+ nsCString privacyMark;
+ nsCString securityCategories;
+ msg->GetSecurityLabel(&hasSecurityLabel,
+ securityPolicyIdentifier,
+ &securityClassification,
+ privacyMark,
+ securityCategories);
+
+ if (hasSecurityLabel) {
+ ProxySecurityLabelStatus(mHeaderSink, securityPolicyIdentifier,
+ securityClassification,
+ privacyMark,
+ securityCategories);
+ }
+ }
+
+ if (signature_status == nsICMSMessageErrors::SUCCESS)
+ {
+ // Handle Signed Headers
+ nsCOMPtr<nsIMutableArray> secureHeaders;
+ PRInt32 canonAlgo;
+ msg->GetSecureHeader(getter_AddRefs(secureHeaders),&canonAlgo);
+ ProxySecureHeaderStatus(mHeaderSink, secureHeaders, canonAlgo);
+ }
+
+ if (signature_status == nsICMSMessageErrors::SUCCESS)
+ {
+ // Handle S/MIME receipt and receipt request
+ bool hasReceiptRequest = PR_FALSE;
+ bool hasReceipt = PR_FALSE;
+ unsigned char *signedContentIdentifier = NULL;
+ uint32_t signedContentIdentifierLen = 0;
+ uint32_t receiptsFrom = 0;
+ nsCString receiptsTo;
+ unsigned char *originatorSignatureValue = NULL;
+ uint32_t originatorSignatureValueLen = 0;
+ unsigned char *originatorContentType = NULL;
+ uint32_t originatorContentTypeLen = 0;
+ unsigned char *msgSigDigest = NULL;
+ uint32_t msgSigDigestLen = 0;
+
+ msg->GetReceiptRequest(&hasReceiptRequest,
+ (const unsigned char**)&signedContentIdentifier,
+ &signedContentIdentifierLen,
+ &receiptsFrom,
+ receiptsTo,
+ (const unsigned char**)&originatorSignatureValue,
+ &originatorSignatureValueLen,
+ (const unsigned char**)&originatorContentType,
+ &originatorContentTypeLen,
+ (const unsigned char**)&msgSigDigest,
+ &msgSigDigestLen);
+
+ if (!hasReceiptRequest)
+ msg->GetReceipt(&hasReceipt,
+ (const unsigned char**)&signedContentIdentifier,
+ &signedContentIdentifierLen,
+ (const unsigned char**)&originatorSignatureValue,
+ &originatorSignatureValueLen,
+ (const unsigned char**)&originatorContentType,
+ &originatorContentTypeLen,
+ (const unsigned char**)&msgSigDigest,
+ &msgSigDigestLen);
+
+ // Process receipt request
+ if (hasReceiptRequest) {
+ ProxySMIMEReceiptRequestStatus(mHeaderSink,
+ signedContentIdentifier,
+ signedContentIdentifierLen,
+ receiptsFrom,
+ receiptsTo,
+ originatorSignatureValue,
+ originatorSignatureValueLen,
+ originatorContentType,
+ originatorContentTypeLen,
+ msgSigDigest,
+ msgSigDigestLen);
+ }
+ // Process receipt
+ if (hasReceipt) {
+ ProxySMIMEReceiptStatus(mHeaderSink,
+ signedContentIdentifier,
+ signedContentIdentifierLen,
+ originatorSignatureValue,
+ originatorSignatureValueLen,
+ originatorContentType,
+ originatorContentTypeLen,
+ msgSigDigest,
+ msgSigDigestLen);
+ }
+
+ if (signedContentIdentifier)
+ PR_Free(signedContentIdentifier);
+ if (originatorSignatureValue)
+ PR_Free(originatorSignatureValue);
+ if (originatorContentType)
+ PR_Free(originatorContentType);
+ if (msgSigDigest)
+ PR_Free(msgSigDigest);
+ }
+ return NS_OK;
+}
+
+int MIMEGetRelativeCryptoNestLevel(MimeObject *obj)
+{
+ /*
+ the part id of any mimeobj is mime_part_address(obj)
+ our currently displayed crypto part is obj
+ the part shown as the toplevel object in the current window is
+ obj->options->part_to_load
+ possibly stored in the toplevel object only ???
+ but hopefully all nested mimeobject point to the same displayooptions
+
+ we need to find out the nesting level of our currently displayed crypto object
+ wrt the shown part in the toplevel window
+ */
+
+ // if we are showing the toplevel message, aTopMessageNestLevel == 0
+ int aTopMessageNestLevel = 0;
+ MimeObject *aTopShownObject = nullptr;
+ if (obj && obj->options->part_to_load) {
+ bool aAlreadyFoundTop = false;
+ for (MimeObject *walker = obj; walker; walker = walker->parent) {
+ if (aAlreadyFoundTop) {
+ if (!mime_typep(walker, (MimeObjectClass *) &mimeEncryptedClass)
+ && !mime_typep(walker, (MimeObjectClass *) &mimeMultipartSignedClass)) {
+ ++aTopMessageNestLevel;
+ }
+ }
+ if (!aAlreadyFoundTop && !strcmp(mime_part_address(walker), walker->options->part_to_load)) {
+ aAlreadyFoundTop = true;
+ aTopShownObject = walker;
+ }
+ if (!aAlreadyFoundTop && !walker->parent) {
+ // The mime part part_to_load is not a parent of the
+ // the crypto mime part passed in to this function as parameter obj.
+ // That means the crypto part belongs to another branch of the mime tree.
+ return -1;
+ }
+ }
+ }
+
+ bool CryptoObjectIsChildOfTopShownObject = false;
+ if (!aTopShownObject) {
+ // no sub part specified, top message is displayed, and
+ // our crypto object is definitively a child of it
+ CryptoObjectIsChildOfTopShownObject = true;
+ }
+
+ // if we are the child of the topmost message, aCryptoPartNestLevel == 1
+ int aCryptoPartNestLevel = 0;
+ if (obj) {
+ for (MimeObject *walker = obj; walker; walker = walker->parent) {
+ // Crypto mime objects are transparent wrt nesting.
+ if (!mime_typep(walker, (MimeObjectClass *) &mimeEncryptedClass)
+ && !mime_typep(walker, (MimeObjectClass *) &mimeMultipartSignedClass)) {
+ ++aCryptoPartNestLevel;
+ }
+ if (aTopShownObject && walker->parent == aTopShownObject) {
+ CryptoObjectIsChildOfTopShownObject = true;
+ }
+ }
+ }
+
+ if (!CryptoObjectIsChildOfTopShownObject) {
+ return -1;
+ }
+
+ return aCryptoPartNestLevel - aTopMessageNestLevel;
+}
+
+static void *MimeCMS_init(MimeObject *obj,
+ int (*output_fn) (const char *buf, int32_t buf_size, void *output_closure),
+ void *output_closure)
+{
+ MimeCMSdata *data;
+ MimeDisplayOptions *opts;
+ nsresult rv;
+
+ if (!(obj && obj->options && output_fn)) return 0;
+
+ opts = obj->options;
+ data = new MimeCMSdata;
+ if (!data) return 0;
+
+ data->self = obj;
+ data->output_fn = output_fn;
+ data->output_closure = output_closure;
+ PR_SetError(0, 0);
+ data->decoder_context = do_CreateInstance(NS_CMSDECODER_CONTRACTID, &rv);
+ if (NS_FAILED(rv))
+ {
+ delete data;
+ return 0;
+ }
+
+ rv = data->decoder_context->Start(MimeCMS_content_callback, data);
+ if (NS_FAILED(rv))
+ {
+ delete data;
+ return 0;
+ }
+
+ // XXX Fix later XXX //
+ data->parent_holds_stamp_p =
+ (obj->parent &&
+ (mime_crypto_stamped_p(obj->parent) ||
+ mime_typep(obj->parent, (MimeObjectClass *) &mimeEncryptedClass)));
+
+ data->parent_is_encrypted_p =
+ (obj->parent && MimeEncryptedCMS_encrypted_p (obj->parent));
+
+ /* If the parent of this object is a crypto-blob, then it's the grandparent
+ who would have written out the headers and prepared for a stamp...
+ (This shit sucks.)
+ */
+ if (data->parent_is_encrypted_p &&
+ !data->parent_holds_stamp_p &&
+ obj->parent && obj->parent->parent)
+ data->parent_holds_stamp_p =
+ mime_crypto_stamped_p (obj->parent->parent);
+
+ mime_stream_data *msd = (mime_stream_data *) (data->self->options->stream_closure);
+ if (msd)
+ {
+ nsIChannel *channel = msd->channel; // note the lack of ref counting...
+ if (channel)
+ {
+ nsCOMPtr<nsIURI> uri;
+ nsCOMPtr<nsIMsgWindow> msgWindow;
+ nsCOMPtr<nsIMsgHeaderSink> headerSink;
+ nsCOMPtr<nsIMsgMailNewsUrl> msgurl;
+ nsCOMPtr<nsISupports> securityInfo;
+ channel->GetURI(getter_AddRefs(uri));
+ if (uri)
+ {
+ nsAutoCString urlSpec;
+ rv = uri->GetSpec(urlSpec);
+
+ // We only want to update the UI if the current mime transaction
+ // is intended for display.
+ // If the current transaction is intended for background processing,
+ // we can learn that by looking at the additional header=filter
+ // string contained in the URI.
+ //
+ // If we find something, we do not set smimeHeaderSink,
+ // which will prevent us from giving UI feedback.
+ //
+ // If we do not find header=filter, we assume the result of the
+ // processing will be shown in the UI.
+
+ if (!strstr(urlSpec.get(), "?header=filter") &&
+ !strstr(urlSpec.get(), "&header=filter") &&
+ !strstr(urlSpec.get(), "?header=attach") &&
+ !strstr(urlSpec.get(), "&header=attach"))
+ {
+ msgurl = do_QueryInterface(uri);
+ if (msgurl)
+ msgurl->GetMsgWindow(getter_AddRefs(msgWindow));
+ if (msgWindow)
+ msgWindow->GetMsgHeaderSink(getter_AddRefs(headerSink));
+ if (headerSink)
+ headerSink->GetSecurityInfo(getter_AddRefs(securityInfo));
+ if (securityInfo)
+ data->smimeHeaderSink = do_QueryInterface(securityInfo);
+ }
+ }
+ } // if channel
+ } // if msd
+
+ return data;
+}
+
+static int
+MimeCMS_write (const char *buf, int32_t buf_size, void *closure)
+{
+ MimeCMSdata *data = (MimeCMSdata *) closure;
+ nsresult rv;
+
+ if (!data || !data->output_fn || !data->decoder_context) return -1;
+
+ PR_SetError(0, 0);
+ rv = data->decoder_context->Update(buf, buf_size);
+ data->decoding_failed = NS_FAILED(rv);
+
+ return 0;
+}
+
+void MimeCMSGetFromSender(MimeObject *obj,
+ nsCString &from_addr,
+ nsCString &from_name,
+ nsCString &sender_addr,
+ nsCString &sender_name)
+{
+ MimeHeaders *msg_headers = 0;
+
+ /* Find the headers of the MimeMessage which is the parent (or grandparent)
+ of this object (remember, crypto objects nest.) */
+ MimeObject *o2 = obj;
+ msg_headers = o2->headers;
+ while (o2 &&
+ o2->parent &&
+ !mime_typep(o2->parent, (MimeObjectClass *) &mimeMessageClass))
+ {
+ o2 = o2->parent;
+ msg_headers = o2->headers;
+ }
+
+ if (!msg_headers)
+ return;
+
+ /* Find the names and addresses in the From and/or Sender fields.
+ */
+ char *s;
+
+ /* Extract the name and address of the "From:" field. */
+ s = MimeHeaders_get(msg_headers, HEADER_FROM, false, false);
+ if (s)
+ {
+ ParseRFC822Addresses(s, from_name, from_addr);
+ PR_FREEIF(s);
+ }
+
+ /* Extract the name and address of the "Sender:" field. */
+ s = MimeHeaders_get(msg_headers, HEADER_SENDER, false, false);
+ if (s)
+ {
+ ParseRFC822Addresses(s, sender_name, sender_addr);
+ PR_FREEIF(s);
+ }
+}
+
+void MimeCMSRequestAsyncSignatureVerification(nsICMSMessage *aCMSMsg,
+ const char *aFromAddr, const char *aFromName,
+ const char *aSenderAddr, const char *aSenderName,
+ nsIMsgSMIMEHeaderSink *aHeaderSink, int32_t aMimeNestingLevel,
+ unsigned char* item_data, uint32_t item_len)
+{
+ nsCOMPtr<nsICMSMessage2> msg2 = do_QueryInterface(aCMSMsg);
+ if (!msg2)
+ return;
+
+ nsRefPtr<nsSMimeVerificationListener> listener =
+ new nsSMimeVerificationListener(aFromAddr, aFromName, aSenderAddr, aSenderName,
+ aHeaderSink, aMimeNestingLevel);
+ if (!listener)
+ return;
+
+ if (item_data)
+ msg2->AsyncVerifyDetachedSignature(listener, item_data, item_len);
+ else
+ msg2->AsyncVerifySignature(listener);
+}
+
+static int
+MimeCMS_eof (void *crypto_closure, bool abort_p)
+{
+ MimeCMSdata *data = (MimeCMSdata *) crypto_closure;
+ nsresult rv;
+ int32_t status = nsICMSMessageErrors::SUCCESS;
+
+ if (!data || !data->output_fn || !data->decoder_context) {
+ return -1;
+ }
+
+ int aRelativeNestLevel = MIMEGetRelativeCryptoNestLevel(data->self);
+
+ /* Hand an EOF to the crypto library. It may call data->output_fn.
+ (Today, the crypto library has no flushing to do, but maybe there
+ will be someday.)
+
+ We save away the value returned and will use it later to emit a
+ blurb about whether the signature validation was cool.
+ */
+
+ PR_SetError(0, 0);
+ rv = data->decoder_context->Finish(getter_AddRefs(data->content_info));
+ if (NS_FAILED(rv))
+ status = nsICMSMessageErrors::GENERAL_ERROR;
+
+ data->decoder_context = 0;
+
+ nsCOMPtr<nsIX509Cert> certOfInterest;
+
+ if (!data->smimeHeaderSink)
+ return 0;
+
+ if (aRelativeNestLevel < 0)
+ return 0;
+
+ int32_t maxNestLevel = 0;
+ data->smimeHeaderSink->MaxWantedNesting(&maxNestLevel);
+
+ if (aRelativeNestLevel > maxNestLevel)
+ return 0;
+
+ if (data->decoding_failed)
+ status = nsICMSMessageErrors::GENERAL_ERROR;
+
+ if (!data->content_info)
+ {
+ if (!data->decoded_bytes)
+ {
+ // We were unable to decode any data.
+ status = nsICMSMessageErrors::GENERAL_ERROR;
+ }
+ else
+ {
+ // Some content got decoded, but we failed to decode
+ // the final summary, probably we got truncated data.
+ status = nsICMSMessageErrors::ENCRYPT_INCOMPLETE;
+ }
+
+ // Although a CMS message could be either encrypted or opaquely signed,
+ // what we see is most likely encrypted, because if it were
+ // signed only, we probably would have been able to decode it.
+
+ data->ci_is_encrypted = true;
+ }
+ else
+ {
+ rv = data->content_info->ContentIsEncrypted(&data->ci_is_encrypted);
+
+ if (NS_SUCCEEDED(rv) && data->ci_is_encrypted) {
+ data->content_info->GetEncryptionCert(getter_AddRefs(certOfInterest));
+ }
+ else {
+ // Existing logic in mimei assumes, if !ci_is_encrypted, then it is signed.
+ // Make sure it indeed is signed.
+
+ bool testIsSigned;
+ rv = data->content_info->ContentIsSigned(&testIsSigned);
+
+ if (NS_FAILED(rv) || !testIsSigned) {
+ // Neither signed nor encrypted?
+ // We are unable to understand what we got, do not try to indicate S/Mime status.
+ return 0;
+ }
+
+ nsCString from_addr;
+ nsCString from_name;
+ nsCString sender_addr;
+ nsCString sender_name;
+
+ MimeCMSGetFromSender(data->self,
+ from_addr, from_name,
+ sender_addr, sender_name);
+
+ MimeCMSRequestAsyncSignatureVerification(data->content_info,
+ from_addr.get(), from_name.get(),
+ sender_addr.get(), sender_name.get(),
+ data->smimeHeaderSink, aRelativeNestLevel,
+ nullptr, 0);
+ }
+ }
+
+ if (data->ci_is_encrypted)
+ {
+ data->smimeHeaderSink->EncryptionStatus(
+ aRelativeNestLevel,
+ status,
+ certOfInterest
+ );
+ }
+
+ return 0;
+}
+
+static void
+MimeCMS_free (void *crypto_closure)
+{
+ MimeCMSdata *data = (MimeCMSdata *) crypto_closure;
+ if (!data) return;
+
+ delete data;
+}
+
+static char *
+MimeCMS_generate (void *crypto_closure)
+{
+ return nullptr;
+}
+
--- /dev/null
+# -*- Mode: python; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+
+XPIDL_SOURCES += [
+ 'nsIASN1Object.idl',
+ 'nsIASN1PrintableItem.idl',
+ 'nsIASN1Sequence.idl',
+ 'nsIAssociatedContentSecurity.idl',
+ 'nsIBadCertListener2.idl',
+ 'nsICMSDecoder.idl',
+ 'nsICMSEncoder.idl',
+ 'nsICMSMessage.idl',
+ 'nsICMSMessage2.idl',
+ 'nsICMSMessageErrors.idl',
+ 'nsICMSSecureMessage.idl',
+ 'nsICertOverrideService.idl',
+ 'nsICertPickDialogs.idl',
+ 'nsICertificateDialogs.idl',
+ 'nsICertificatePrincipal.idl',
+ 'nsIClientAuthDialogs.idl',
+ 'nsIDOMCryptoDialogs.idl',
+ 'nsIDataSignatureVerifier.idl',
+ 'nsIFormSigningDialog.idl',
+ 'nsIGenKeypairInfoDlg.idl',
+ 'nsIIdentityInfo.idl',
+ 'nsIKeyModule.idl',
+ 'nsIKeygenThread.idl',
+ 'nsIMsgSMIMESecureHeader.idl',
+ 'nsINSSCertCache.idl',
+ 'nsINSSVersion.idl',
+ 'nsIPK11Token.idl',
+ 'nsIPK11TokenDB.idl',
+ 'nsIPKCS11.idl',
+ 'nsIPKCS11Module.idl',
+ 'nsIPKCS11ModuleDB.idl',
+ 'nsIPKCS11Slot.idl',
+ 'nsIProtectedAuthThread.idl',
+ 'nsIRecentBadCertsService.idl',
+ 'nsISMimeCert.idl',
+ 'nsISSLCertErrorDialog.idl',
+ 'nsISSLErrorListener.idl',
+ 'nsISSLStatus.idl',
+ 'nsISignatureVerifier.idl',
+ 'nsIStreamCipher.idl',
+ 'nsITokenDialogs.idl',
+ 'nsITokenPasswordDialogs.idl',
+ 'nsIUserCertPicker.idl',
+ 'nsIX509Cert.idl',
+ 'nsIX509Cert2.idl',
+ 'nsIX509Cert3.idl',
+ 'nsIX509CertDB.idl',
+ 'nsIX509CertDB2.idl',
+ 'nsIX509CertList.idl',
+ 'nsIX509CertValidity.idl',
+]
+
+if CONFIG['MOZ_XUL']:
+ XPIDL_SOURCES += [
+ 'nsICertTree.idl',
+ ]
+
+MODULE = 'pipnss'
+
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * David Drinan <ddrinan@netscape.com>
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved */
+
+#include "nsISupports.idl"
+
+%{ C++
+#define NS_CMSMESSAGE_CONTRACTID "@mozilla.org/nsCMSMessage;1"
+%}
+
+[ptr] native UnsignedCharPtr(unsigned char);
+
+interface nsIX509Cert;
+interface nsIArray;
+interface nsIMutableArray;
+/**
+ * nsICMSMessage
+ * Interface to a CMS Message
+ */
+[uuid(a4557478-ae16-11d5-ba4b-00108303b117)]
+interface nsICMSMessage : nsISupports
+{
+ void contentIsSigned(out boolean aSigned);
+ void contentIsEncrypted(out boolean aEncrypted);
+ void getSignerCommonName(out string aName);
+ void getSignerEmailAddress(out string aEmail);
+ void getSignerCert(out nsIX509Cert scert);
+ void getEncryptionCert(out nsIX509Cert ecert);
+ void setReceiptRequest(in ACString aSignedContentIdentifier, in ACString aReceiptsTo);
+ void getReceiptRequest(out boolean aHasReceiptRequest,
+ [const,array,size_is(aSignedContentIdentifierLen)] out octet aSignedContentIdentifier,
+ out unsigned long aSignedContentIdentifierLen,
+ out unsigned long aReceiptsFrom,
+ out ACString aReceiptsTo,
+ [const,array,size_is(aOriginatorSignatureValueLen)] out octet aOriginatorSignatureValue,
+ out unsigned long aOriginatorSignatureValueLen,
+ [const,array,size_is(aOriginatorContentTypeLen)] out octet aOriginatorContentType,
+ out unsigned long aOriginatorContentTypeLen,
+ [const,array,size_is(aMsgSigDigestLen)] out octet aMsgSigDigest,
+ out unsigned long aMsgSigDigestLen);
+ void setReceipt([array,size_is(aSignedContentIdentifierLen)] in octet aSignedContentIdentifier,
+ in unsigned long aSignedContentIdentifierLen,
+ [array,size_is(aOriginatorSignatureValueLen)] in octet aOriginatorSignatureValue,
+ in unsigned long aOriginatorSignatureValueLen,
+ [array,size_is(aOriginatorContentTypeLen)] in octet aOriginatorContentType,
+ in unsigned long aOriginatorContentTypeLen,
+ [array,size_is(aMsgSigDigestLen)] in octet aMsgSigDigest,
+ in unsigned long aMsgSigDigestLen);
+ void createReceipt([const,array,size_is(encodedReceiptLen)] out octet encodedReceipt,
+ out unsigned long encodedReceiptLen);
+ void getReceipt(out boolean aHasReceipt,
+ [const,array,size_is(aSignedContentIdentifierLen)] out octet aSignedContentIdentifier,
+ out unsigned long aSignedContentIdentifierLen,
+ [const,array,size_is(aOriginatorSignatureValueLen)] out octet aOriginatorSignatureValue,
+ out unsigned long aOriginatorSignatureValueLen,
+ [const,array,size_is(aOriginatorContentTypeLen)] out octet aOriginatorContentType,
+ out unsigned long aOriginatorContentTypeLen,
+ [const,array,size_is(aMsgSigDigestLen)] out octet aMsgSigDigest,
+ out unsigned long aMsgSigDigestLen);
+ void setSecurityLabel(in ACString aSecurityPolicyIdentifier,
+ in long aSecurityClassification,
+ in ACString aPrivacyMark,
+ in ACString aSecurityCategories);
+ void getSecurityLabel(out boolean aHasSecurityLabel,
+ out ACString aSecurityPolicyIdentifier,
+ out long aSecurityClassification,
+ out ACString aPrivacyMark,
+ out ACString aSecurityCategories);
+ void verifySignature();
+ void verifyDetachedSignature(in UnsignedCharPtr aDigestData, in unsigned long aDigestDataLen);
+ void CreateEncrypted(in nsIArray aRecipientCerts);
+ void CreateSigned(in nsIX509Cert scert, in nsIX509Cert ecert, in UnsignedCharPtr aDigestData, in unsigned long aDigestDataLen, in nsIArray secureHeaders, in long canonAlgo);
+ void getSecureHeader(out nsIMutableArray secureHeaders, out long canonAlgo);
+};
+
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsISupports.idl"
+
+interface nsIInterfaceRequestor;
+
+/**
+ * nsIClientAuthDialog
+ * Provides UI for SSL client-auth dialogs.
+ */
+[scriptable, uuid(fa4c7520-1433-11d5-ba24-00108303b117)]
+interface nsIClientAuthDialogs : nsISupports
+{
+ /**
+ * display
+ * UI shown when a user is asked to do SSL client auth.
+ */
+ void ChooseCertificate(in nsIInterfaceRequestor ctx,
+ in wstring cn,
+ in wstring organization,
+ in wstring issuer,
+ [array, size_is(count)] in wstring certNickList,
+ [array, size_is(count)] in wstring certDetailsList,
+ in unsigned long count,
+ out long selectedIndex,
+ out boolean canceled);
+};
+
+[scriptable, uuid(95c4373e-bdd4-4a63-b431-f5b000367721)]
+interface nsIClientAuthUserDecision : nsISupports
+{
+ attribute boolean rememberClientAuthCertificate;
+ //Cassidian save user login
+ attribute ACString clientLogin;
+
+};
+
+%{C++
+#define NS_CLIENTAUTHDIALOGS_CONTRACTID "@mozilla.org/nsClientAuthDialogs;1"
+%}
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Copyright (c) 2008-2009 EADS DEFENCE AND SECURITY - All rights reserved. */
+
+#include "nsISupports.idl"
+
+
+
+// {A1BBE613-DA57-4766-84F0-343DAAFF6EB2}
+//static const GUID <<name>> =
+//{ 0xa1bbe613, 0xda57, 0x4766, { 0x84, 0xf0, 0x34, 0x3d, 0xaa, 0xff, 0x6e, 0xb2 } };
+
+[scriptable, uuid(A1BBE613-DA57-4766-84F0-343DAAFF6EB2)]
+interface nsIMsgSMIMESecureHeader : nsISupports
+{
+ attribute AString headerName;
+ attribute AString headerValue;
+ attribute long headerStatus;
+ attribute long headerEncrypted;
+};
\ No newline at end of file
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * David Drinan <ddrinan@netscape.com>
+ * Kai Engert <kengert@redhat.com>
+ * ESS Signed Receipts: Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ * Secure headers : Copyright (c) 2011 CASSIDIAN - All rights reserved */
+
+#include "nsISupports.h"
+#include "nsCMS.h"
+#include "CertVerifier.h"
+#include "nsNSSHelper.h"
+#include "nsNSSCertificate.h"
+#include "smime.h"
+#include "cms.h"
+#include "nsICMSMessageErrors.h"
+#include "nsIArray.h"
+#include "nsIMutableArray.h"
+#include "nsArrayUtils.h"
+#include "nsCertVerificationThread.h"
+#include "ScopedNSSTypes.h"
+#include "nsIMsgSMIMESecureHeader.h"
+#include "prlog.h"
+#include "nsIServiceManager.h"
+
+using namespace mozilla;
+using namespace mozilla::psm;
+
+#ifdef PR_LOGGING
+extern PRLogModuleInfo* gPIPNSSLog;
+#endif
+
+using namespace mozilla;
+
+static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
+
+#define NS_SMIMESECUREHEADER_CONTRACTID "@mozilla.org/messenger-smime/smime-secure-header;1"
+
+NS_IMPL_THREADSAFE_ISUPPORTS2(nsCMSMessage, nsICMSMessage,
+ nsICMSMessage2)
+
+nsCMSMessage::nsCMSMessage()
+{
+ m_cmsMsg = nullptr;
+ mHasReceiptRequest = PR_FALSE;
+ mHasReceipt = PR_FALSE;
+ mHasSecurityLabel = PR_FALSE;
+}
+nsCMSMessage::nsCMSMessage(NSSCMSMessage *aCMSMsg)
+{
+ m_cmsMsg = aCMSMsg;
+ mHasReceiptRequest = PR_FALSE;
+ mHasReceipt = PR_FALSE;
+}
+
+nsCMSMessage::~nsCMSMessage()
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return;
+
+ destructorSafeDestroyNSSReference();
+ shutdown(calledFromObject);
+}
+
+void nsCMSMessage::virtualDestroyNSSReference()
+{
+ destructorSafeDestroyNSSReference();
+}
+
+void nsCMSMessage::destructorSafeDestroyNSSReference()
+{
+ if (isAlreadyShutDown())
+ return;
+
+ if (m_cmsMsg) {
+ NSS_CMSMessage_Destroy(m_cmsMsg);
+ }
+}
+
+NS_IMETHODIMP nsCMSMessage::VerifySignature()
+{
+ return CommonVerifySignature(nullptr, 0);
+}
+
+NSSCMSSignerInfo* nsCMSMessage::GetTopLevelSignerInfo()
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return nullptr;
+
+ if (!m_cmsMsg)
+ return nullptr;
+
+ if (!NSS_CMSMessage_IsSigned(m_cmsMsg))
+ return nullptr;
+
+ NSSCMSContentInfo *cinfo = NSS_CMSMessage_ContentLevel(m_cmsMsg, 0);
+ if (!cinfo)
+ return nullptr;
+
+ NSSCMSSignedData *sigd = (NSSCMSSignedData*)NSS_CMSContentInfo_GetContent(cinfo);
+ if (!sigd)
+ return nullptr;
+
+ PR_ASSERT(NSS_CMSSignedData_SignerInfoCount(sigd) > 0);
+ return NSS_CMSSignedData_GetSignerInfo(sigd, 0);
+}
+
+NS_IMETHODIMP nsCMSMessage::GetSignerEmailAddress(char * * aEmail)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::GetSignerEmailAddress\n"));
+ NS_ENSURE_ARG(aEmail);
+
+ NSSCMSSignerInfo *si = GetTopLevelSignerInfo();
+ if (!si)
+ return NS_ERROR_FAILURE;
+
+ *aEmail = NSS_CMSSignerInfo_GetSignerEmailAddress(si);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCMSMessage::GetSignerCommonName(char ** aName)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::GetSignerCommonName\n"));
+ NS_ENSURE_ARG(aName);
+
+ NSSCMSSignerInfo *si = GetTopLevelSignerInfo();
+ if (!si)
+ return NS_ERROR_FAILURE;
+
+ *aName = NSS_CMSSignerInfo_GetSignerCommonName(si);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCMSMessage::ContentIsEncrypted(bool *isEncrypted)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::ContentIsEncrypted\n"));
+ NS_ENSURE_ARG(isEncrypted);
+
+ if (!m_cmsMsg)
+ return NS_ERROR_FAILURE;
+
+ *isEncrypted = NSS_CMSMessage_IsEncrypted(m_cmsMsg);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCMSMessage::ContentIsSigned(bool *isSigned)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::ContentIsSigned\n"));
+ NS_ENSURE_ARG(isSigned);
+
+ if (!m_cmsMsg)
+ return NS_ERROR_FAILURE;
+
+ *isSigned = NSS_CMSMessage_IsSigned(m_cmsMsg);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCMSMessage::GetSignerCert(nsIX509Cert **scert)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ NSSCMSSignerInfo *si = GetTopLevelSignerInfo();
+ if (!si)
+ return NS_ERROR_FAILURE;
+
+ if (si->cert) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::GetSignerCert got signer cert\n"));
+
+ *scert = nsNSSCertificate::Create(si->cert);
+ if (*scert) {
+ (*scert)->AddRef();
+ }
+ }
+ else {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::GetSignerCert no signer cert, do we have a cert list? %s\n",
+ (si->certList ? "yes" : "no") ));
+
+ *scert = nullptr;
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCMSMessage::GetEncryptionCert(nsIX509Cert **ecert)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsCMSMessage::SetReceiptRequest(const nsACString& aSignedContentIdentifier, const nsACString& aReceiptsTo)
+{
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::SetReceiptRequest\n"));
+
+ mHasReceiptRequest = PR_TRUE;
+ mReceiptRequestSignedContentIdentifier = aSignedContentIdentifier;
+ mReceiptRequestReceiptsTo = aReceiptsTo;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCMSMessage::GetReceiptRequest(bool *aHasReceiptRequest,
+ const uint8_t **aSignedContentIdentifier,
+ uint32_t *aSignedContentIdentifierLen,
+ uint32_t *aReceiptsFrom,
+ nsACString& aReceiptsTo,
+ const uint8_t **aOriginatorSignatureValue,
+ uint32_t *aOriginatorSignatureValueLen,
+ const uint8_t **aOriginatorContentType,
+ uint32_t *aOriginatorContentTypeLen,
+ const uint8_t **aMsgSigDigest,
+ uint32_t *aMsgSigDigestLen)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::GetReceiptRequest\n"));
+ NS_ENSURE_ARG_POINTER(aHasReceiptRequest);
+ NS_ENSURE_ARG_POINTER(aSignedContentIdentifier);
+ NS_ENSURE_ARG_POINTER(aSignedContentIdentifierLen);
+ NS_ENSURE_ARG_POINTER(aReceiptsFrom);
+ NS_ENSURE_ARG_POINTER(aOriginatorSignatureValue);
+ NS_ENSURE_ARG_POINTER(aOriginatorSignatureValueLen);
+ NS_ENSURE_ARG_POINTER(aOriginatorContentType);
+ NS_ENSURE_ARG_POINTER(aOriginatorContentTypeLen);
+ NS_ENSURE_ARG_POINTER(aMsgSigDigest);
+ NS_ENSURE_ARG_POINTER(aMsgSigDigestLen);
+
+ NSSCMSSignerInfo *si = GetTopLevelSignerInfo();
+ if (!si)
+ return NS_ERROR_FAILURE;
+
+
+ PRBool hasRecReq = aHasReceiptRequest ? PR_TRUE : PR_FALSE;
+ NSS_CMSSignerInfo_GetReceiptRequest(si,
+ &hasRecReq,
+ (unsigned char **) aSignedContentIdentifier,
+ aSignedContentIdentifierLen,
+ aReceiptsFrom,
+ getter_Copies(aReceiptsTo),
+ (unsigned char **) aOriginatorSignatureValue,
+ aOriginatorSignatureValueLen,
+ (unsigned char **) aOriginatorContentType,
+ aOriginatorContentTypeLen,
+ (unsigned char **) aMsgSigDigest,
+ aMsgSigDigestLen);
+ *aHasReceiptRequest = hasRecReq == PR_TRUE ? true:false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCMSMessage::SetReceipt(uint8_t *aSignedContentIdentifier,
+ uint32_t aSignedContentIdentifierLen,
+ uint8_t *aOriginatorSignatureValue,
+ uint32_t aOriginatorSignatureValueLen,
+ uint8_t *aOriginatorContentType,
+ uint32_t aOriginatorContentTypeLen,
+ uint8_t *aMsgSigDigest,
+ uint32_t aMsgSigDigestLen)
+{
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::SetReceipt\n"));
+
+ mHasReceipt = PR_TRUE;
+ mReceiptSignedContentIdentifier = aSignedContentIdentifier;
+ mReceiptSignedContentIdentifierLen = aSignedContentIdentifierLen;
+ mReceiptOriginatorSignatureValue = aOriginatorSignatureValue;
+ mReceiptOriginatorSignatureValueLen = aOriginatorSignatureValueLen;
+ mReceiptOriginatorContentType = aOriginatorContentType;
+ mReceiptOriginatorContentTypeLen = aOriginatorContentTypeLen;
+ mReceiptMsgSigDigest = aMsgSigDigest;
+ mReceiptMsgSigDigestLen = aMsgSigDigestLen;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCMSMessage::CreateReceipt(const uint8_t **encodedReceipt, uint32_t *encodedReceiptLen)
+{
+ SECItem receipt;
+ SECItem digest;
+ uint8_t *digestBuffer = NULL;
+ uint32_t digestBufferLen;
+ nsresult rv = NS_OK;
+ NSSCMSContentInfo *cinfo;
+ NSSCMSSignedData *sigd;
+
+ if (m_cmsMsg == NULL)
+ return NS_ERROR_FAILURE;
+
+ /* Create and encode receipt object */
+ if ( NSS_SMIMEUtil_CreateReceipt(m_cmsMsg->poolp,
+ &receipt,
+ &digestBuffer,
+ &digestBufferLen,
+ mReceiptSignedContentIdentifier,
+ mReceiptSignedContentIdentifierLen,
+ mReceiptOriginatorSignatureValue,
+ mReceiptOriginatorSignatureValueLen,
+ mReceiptOriginatorContentType,
+ mReceiptOriginatorContentTypeLen) != SECSuccess) {
+ rv = NS_ERROR_FAILURE;
+ goto loser;
+ }
+ /* Get SignedData */
+ cinfo = NSS_CMSMessage_GetContentInfo(m_cmsMsg);
+ if (cinfo == NULL) {
+ rv = NS_ERROR_FAILURE;
+ goto loser;
+ }
+ sigd = (NSSCMSSignedData*)NSS_CMSContentInfo_GetContent(cinfo);
+ if (sigd == NULL) {
+ rv = NS_ERROR_FAILURE;
+ goto loser;
+ }
+
+ digest.data = digestBuffer;
+ digest.len = digestBufferLen;
+
+ /* Set digest attribute */
+ if (NSS_CMSSignedData_SetDigestValue(sigd, SEC_OID_SHA1, &digest) != SECSuccess) {
+ rv = NS_ERROR_FAILURE;
+ goto loser;
+ }
+
+ *encodedReceipt = (uint8_t*)(receipt.data);
+ *encodedReceiptLen = receipt.len;
+
+loser:
+ if (digestBuffer != NULL)
+ PORT_Free(digestBuffer);
+
+ return rv;
+}
+
+NS_IMETHODIMP nsCMSMessage::GetReceipt(bool *aHasReceipt,
+ const uint8_t **aSignedContentIdentifier,
+ uint32_t *aSignedContentIdentifierLen,
+ const uint8_t **aOriginatorSignatureValue,
+ uint32_t *aOriginatorSignatureValueLen,
+ const uint8_t **aOriginatorContentType,
+ uint32_t *aOriginatorContentTypeLen,
+ const uint8_t **aMsgSigDigest,
+ uint32_t *aMsgSigDigestLen)
+{
+ NSSCMSContentInfo *cinfo;
+ NSSCMSSignedData *sigd;
+ NSSCMSSignerInfo *si;
+ SECItem *receipt;
+
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::GetReceipt\n"));
+ NS_ENSURE_ARG_POINTER(aHasReceipt);
+ NS_ENSURE_ARG_POINTER(aSignedContentIdentifier);
+ NS_ENSURE_ARG_POINTER(aSignedContentIdentifierLen);
+ NS_ENSURE_ARG_POINTER(aOriginatorSignatureValue);
+ NS_ENSURE_ARG_POINTER(aOriginatorSignatureValueLen);
+ NS_ENSURE_ARG_POINTER(aOriginatorContentType);
+ NS_ENSURE_ARG_POINTER(aOriginatorContentTypeLen);
+ NS_ENSURE_ARG_POINTER(aMsgSigDigest);
+ NS_ENSURE_ARG_POINTER(aMsgSigDigestLen);
+
+ si = GetTopLevelSignerInfo();
+ if (!si)
+ return NS_ERROR_FAILURE;
+
+ if (!NSS_CMSSignerInfo_HasReceipt(si))
+ return NS_OK;
+
+ cinfo = NSS_CMSMessage_ContentLevel(m_cmsMsg, 0);
+ if (!cinfo)
+ return NS_OK;
+
+ sigd = (NSSCMSSignedData*)NSS_CMSContentInfo_GetContent(cinfo);
+ if (!sigd)
+ return NS_OK;
+
+ if (NSS_CMSContentInfo_GetContentTypeTag(&(sigd->contentInfo)) != SEC_OID_SMIME_RECEIPT)
+ return NS_OK;
+
+ receipt = (SECItem*)NSS_CMSContentInfo_GetContent(&(sigd->contentInfo));
+ if (receipt == NULL)
+ return NS_ERROR_FAILURE;
+
+ // TODO uint8_t to PRUint8
+ if (NSS_SMIMEUtil_GetReceipt(si->cmsg->poolp,
+ receipt,
+ (const unsigned char **) aSignedContentIdentifier,
+ aSignedContentIdentifierLen,
+ (const unsigned char **) aOriginatorSignatureValue,
+ aOriginatorSignatureValueLen,
+ (const unsigned char **) aOriginatorContentType,
+ aOriginatorContentTypeLen) != SECSuccess)
+ return NS_ERROR_FAILURE;
+
+ if (NSS_CMSSignerInfo_GetMsgSigDigest(si, (unsigned char **) aMsgSigDigest, aMsgSigDigestLen) != SECSuccess)
+ return NS_ERROR_FAILURE;
+
+ *aHasReceipt = PR_TRUE;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCMSMessage::SetSecurityLabel(const nsACString& aSecurityPolicyIdentifier,
+ int32_t aSecurityClassification,
+ const nsACString& aPrivacyMark,
+ const nsACString& aSecurityCategories)
+{
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::SetSecurityLabel\n"));
+
+ mHasSecurityLabel = PR_TRUE;
+ mSecurityPolicyIdentifier = aSecurityPolicyIdentifier;
+ mSecurityClassification = aSecurityClassification;
+ mPrivacyMark = aPrivacyMark;
+ mSecurityCategories = aSecurityCategories;
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCMSMessage::GetSecurityLabel(bool *aHasSecurityLabel,
+ nsACString& aSecurityPolicyIdentifier,
+ int32_t *aSecurityClassification,
+ nsACString& aPrivacyMark,
+ nsACString& aSecurityCategories)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::GetSecurityLabel\n"));
+ NS_ENSURE_ARG_POINTER(aHasSecurityLabel);
+ NS_ENSURE_ARG_POINTER(aSecurityClassification);
+
+ NSSCMSSignerInfo *si = GetTopLevelSignerInfo();
+ if (!si)
+ return NS_ERROR_FAILURE;
+
+ PRBool hasSecLabel = PR_FALSE; // TCN useless aHasSecurityLabel ? PR_TRUE : PR_FALSE;
+ NSS_CMSSignerInfo_GetSecurityLabel(si,
+ &hasSecLabel,
+ getter_Copies(aSecurityPolicyIdentifier),
+ aSecurityClassification,
+ getter_Copies(aPrivacyMark),
+ getter_Copies(aSecurityCategories));
+ *aHasSecurityLabel = hasSecLabel == PR_TRUE ? true:false;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsCMSMessage::VerifyDetachedSignature(unsigned char* aDigestData, uint32_t aDigestDataLen)
+{
+ if (!aDigestData || !aDigestDataLen)
+ return NS_ERROR_FAILURE;
+
+ return CommonVerifySignature(aDigestData, aDigestDataLen);
+}
+
+nsresult nsCMSMessage::CommonVerifySignature(unsigned char* aDigestData, uint32_t aDigestDataLen)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature, content level count %d\n", NSS_CMSMessage_ContentLevelCount(m_cmsMsg)));
+ NSSCMSContentInfo *cinfo = nullptr;
+ NSSCMSSignedData *sigd = nullptr;
+ NSSCMSSignerInfo *si;
+ int32_t nsigners;
+ RefPtr<CertVerifier> certVerifier;
+ nsresult rv = NS_ERROR_FAILURE;
+
+ if (!NSS_CMSMessage_IsSigned(m_cmsMsg)) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - not signed\n"));
+ return NS_ERROR_CMS_VERIFY_NOT_SIGNED;
+ }
+
+ cinfo = NSS_CMSMessage_ContentLevel(m_cmsMsg, 0);
+ if (cinfo) {
+ // I don't like this hard cast. We should check in some way, that we really have this type.
+ sigd = (NSSCMSSignedData*)NSS_CMSContentInfo_GetContent(cinfo);
+ }
+
+ if (!sigd) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - no content info\n"));
+ rv = NS_ERROR_CMS_VERIFY_NO_CONTENT_INFO;
+ goto loser;
+ }
+
+ if (aDigestData && aDigestDataLen)
+ {
+ SECItem digest;
+ digest.data = aDigestData;
+ digest.len = aDigestDataLen;
+
+ if (NSS_CMSSignedData_SetDigestValue(sigd, SEC_OID_SHA1, &digest)) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - bad digest\n"));
+ rv = NS_ERROR_CMS_VERIFY_BAD_DIGEST;
+ goto loser;
+ }
+ }
+
+ // Import certs. Note that import failure is not a signature verification failure. //
+ if (NSS_CMSSignedData_ImportCerts(sigd, CERT_GetDefaultCertDB(), certUsageEmailRecipient, true) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - can not import certs\n"));
+ }
+
+ nsigners = NSS_CMSSignedData_SignerInfoCount(sigd);
+ PR_ASSERT(nsigners > 0);
+ si = NSS_CMSSignedData_GetSignerInfo(sigd, 0);
+
+ // See bug 324474. We want to make sure the signing cert is
+ // still valid at the current time.
+
+ certVerifier = GetDefaultCertVerifier();
+ NS_ENSURE_TRUE(certVerifier, NS_ERROR_UNEXPECTED);
+
+ {
+ SECStatus srv = certVerifier->VerifyCert(si->cert,
+ certificateUsageEmailSigner,
+ PR_Now(), nullptr /*XXX pinarg*/);
+ if (srv != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
+ ("nsCMSMessage::CommonVerifySignature - signing cert not trusted now\n"));
+ rv = NS_ERROR_CMS_VERIFY_UNTRUSTED;
+ goto loser;
+ }
+ }
+
+ // We verify the first signer info, only //
+ if (NSS_CMSSignedData_VerifySignerInfo(sigd, 0, CERT_GetDefaultCertDB(), certUsageEmailSigner) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - unable to verify signature\n"));
+
+ if (NSSCMSVS_SigningCertNotFound == si->verificationStatus) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - signing cert not found\n"));
+ rv = NS_ERROR_CMS_VERIFY_NOCERT;
+ }
+ else if(NSSCMSVS_SigningCertNotTrusted == si->verificationStatus) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - signing cert not trusted at signing time\n"));
+ rv = NS_ERROR_CMS_VERIFY_UNTRUSTED;
+ }
+ else if(NSSCMSVS_Unverified == si->verificationStatus) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - can not verify\n"));
+ rv = NS_ERROR_CMS_VERIFY_ERROR_UNVERIFIED;
+ }
+ else if(NSSCMSVS_ProcessingError == si->verificationStatus) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - processing error\n"));
+ rv = NS_ERROR_CMS_VERIFY_ERROR_PROCESSING;
+ }
+ else if(NSSCMSVS_BadSignature == si->verificationStatus) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - bad signature\n"));
+ rv = NS_ERROR_CMS_VERIFY_BAD_SIGNATURE;
+ }
+ else if(NSSCMSVS_DigestMismatch == si->verificationStatus) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - digest mismatch\n"));
+ rv = NS_ERROR_CMS_VERIFY_DIGEST_MISMATCH;
+ }
+ else if(NSSCMSVS_SignatureAlgorithmUnknown == si->verificationStatus) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - algo unknown\n"));
+ rv = NS_ERROR_CMS_VERIFY_UNKNOWN_ALGO;
+ }
+ else if(NSSCMSVS_SignatureAlgorithmUnsupported == si->verificationStatus) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - algo not supported\n"));
+ rv = NS_ERROR_CMS_VERIFY_UNSUPPORTED_ALGO;
+ }
+ else if(NSSCMSVS_MalformedSignature == si->verificationStatus) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - malformed signature\n"));
+ rv = NS_ERROR_CMS_VERIFY_MALFORMED_SIGNATURE;
+ }
+
+ goto loser;
+ }
+
+ // Save the profile. Note that save import failure is not a signature verification failure. //
+ if (NSS_SMIMESignerInfo_SaveSMIMEProfile(si) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CommonVerifySignature - unable to save smime profile\n"));
+ }
+
+ rv = NS_OK;
+loser:
+ return rv;
+}
+
+NS_IMETHODIMP nsCMSMessage::AsyncVerifySignature(
+ nsISMimeVerificationListener *aListener)
+{
+ return CommonAsyncVerifySignature(aListener, nullptr, 0);
+}
+
+NS_IMETHODIMP nsCMSMessage::AsyncVerifyDetachedSignature(
+ nsISMimeVerificationListener *aListener,
+ unsigned char* aDigestData, uint32_t aDigestDataLen)
+{
+ if (!aDigestData || !aDigestDataLen)
+ return NS_ERROR_FAILURE;
+
+ return CommonAsyncVerifySignature(aListener, aDigestData, aDigestDataLen);
+}
+
+nsresult nsCMSMessage::CommonAsyncVerifySignature(nsISMimeVerificationListener *aListener,
+ unsigned char* aDigestData, uint32_t aDigestDataLen)
+{
+ nsSMimeVerificationJob *job = new nsSMimeVerificationJob;
+
+ if (aDigestData)
+ {
+ job->digest_data = new unsigned char[aDigestDataLen];
+ memcpy(job->digest_data, aDigestData, aDigestDataLen);
+ }
+ else
+ {
+ job->digest_data = nullptr;
+ }
+
+ job->digest_len = aDigestDataLen;
+ job->mMessage = this;
+ job->mListener = aListener;
+
+ nsresult rv = nsCertVerificationThread::addJob(job);
+ if (NS_FAILED(rv))
+ delete job;
+
+ return rv;
+}
+
+class nsZeroTerminatedCertArray : public nsNSSShutDownObject
+{
+public:
+ nsZeroTerminatedCertArray()
+ :mCerts(nullptr), mPoolp(nullptr), mSize(0)
+ {
+ }
+
+ ~nsZeroTerminatedCertArray()
+ {
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return;
+
+ destructorSafeDestroyNSSReference();
+ shutdown(calledFromObject);
+ }
+
+ void virtualDestroyNSSReference()
+ {
+ destructorSafeDestroyNSSReference();
+ }
+
+ void destructorSafeDestroyNSSReference()
+ {
+ if (isAlreadyShutDown())
+ return;
+
+ if (mCerts)
+ {
+ for (uint32_t i=0; i < mSize; i++) {
+ if (mCerts[i]) {
+ CERT_DestroyCertificate(mCerts[i]);
+ }
+ }
+ }
+
+ if (mPoolp)
+ PORT_FreeArena(mPoolp, false);
+ }
+
+ bool allocate(uint32_t count)
+ {
+ // only allow allocation once
+ if (mPoolp)
+ return false;
+
+ mSize = count;
+
+ if (!mSize)
+ return false;
+
+ mPoolp = PORT_NewArena(1024);
+ if (!mPoolp)
+ return false;
+
+ mCerts = (CERTCertificate**)PORT_ArenaZAlloc(
+ mPoolp, (count+1)*sizeof(CERTCertificate*));
+
+ if (!mCerts)
+ return false;
+
+ // null array, including zero termination
+ for (uint32_t i = 0; i < count+1; i++) {
+ mCerts[i] = nullptr;
+ }
+
+ return true;
+ }
+
+ void set(uint32_t i, CERTCertificate *c)
+ {
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return;
+
+ if (i >= mSize)
+ return;
+
+ if (mCerts[i]) {
+ CERT_DestroyCertificate(mCerts[i]);
+ }
+
+ mCerts[i] = CERT_DupCertificate(c);
+ }
+
+ CERTCertificate *get(uint32_t i)
+ {
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return nullptr;
+
+ if (i >= mSize)
+ return nullptr;
+
+ return CERT_DupCertificate(mCerts[i]);
+ }
+
+ CERTCertificate **getRawArray()
+ {
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return nullptr;
+
+ return mCerts;
+ }
+
+private:
+ CERTCertificate **mCerts;
+ PLArenaPool *mPoolp;
+ uint32_t mSize;
+};
+
+NS_IMETHODIMP nsCMSMessage::CreateEncrypted(nsIArray * aRecipientCerts)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted\n"));
+ NSSCMSContentInfo *cinfo;
+ NSSCMSEnvelopedData *envd;
+ NSSCMSRecipientInfo *recipientInfo;
+ nsZeroTerminatedCertArray recipientCerts;
+ SECOidTag bulkAlgTag;
+ int keySize;
+ uint32_t i;
+ nsCOMPtr<nsIX509Cert2> nssRecipientCert;
+ nsresult rv = NS_ERROR_FAILURE;
+
+ // Check the recipient certificates //
+ uint32_t recipientCertCount;
+ aRecipientCerts->GetLength(&recipientCertCount);
+ PR_ASSERT(recipientCertCount > 0);
+
+ if (!recipientCerts.allocate(recipientCertCount)) {
+ goto loser;
+ }
+
+ for (i=0; i<recipientCertCount; i++) {
+ nsCOMPtr<nsIX509Cert> x509cert = do_QueryElementAt(aRecipientCerts, i);
+
+ nssRecipientCert = do_QueryInterface(x509cert);
+
+ if (!nssRecipientCert)
+ return NS_ERROR_FAILURE;
+
+ ScopedCERTCertificate c(nssRecipientCert->GetCert());
+ recipientCerts.set(i, c);
+ }
+
+ // Find a bulk key algorithm //
+ if (NSS_SMIMEUtil_FindBulkAlgForRecipients(recipientCerts.getRawArray(), &bulkAlgTag,
+ &keySize) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't find bulk alg for recipients\n"));
+ rv = NS_ERROR_CMS_ENCRYPT_NO_BULK_ALG;
+ goto loser;
+ }
+
+ m_cmsMsg = NSS_CMSMessage_Create(nullptr);
+ if (!m_cmsMsg) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't create new cms message\n"));
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ goto loser;
+ }
+
+ if ((envd = NSS_CMSEnvelopedData_Create(m_cmsMsg, bulkAlgTag, keySize)) == nullptr) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't create enveloped data\n"));
+ goto loser;
+ }
+
+ cinfo = NSS_CMSMessage_GetContentInfo(m_cmsMsg);
+ if (NSS_CMSContentInfo_SetContent_EnvelopedData(m_cmsMsg, cinfo, envd) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't create content enveloped data\n"));
+ goto loser;
+ }
+
+ cinfo = NSS_CMSEnvelopedData_GetContentInfo(envd);
+ if (NSS_CMSContentInfo_SetContent_Data(m_cmsMsg, cinfo, nullptr, false) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't set content data\n"));
+ goto loser;
+ }
+
+ // Create and attach recipient information //
+ for (i=0; i < recipientCertCount; i++) {
+ ScopedCERTCertificate rc(recipientCerts.get(i));
+ if ((recipientInfo = NSS_CMSRecipientInfo_Create(m_cmsMsg, rc)) == nullptr) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't create recipient info\n"));
+ goto loser;
+ }
+ if (NSS_CMSEnvelopedData_AddRecipient(envd, recipientInfo) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateEncrypted - can't add recipient info\n"));
+ goto loser;
+ }
+ }
+
+ return NS_OK;
+loser:
+ if (m_cmsMsg) {
+ NSS_CMSMessage_Destroy(m_cmsMsg);
+ m_cmsMsg = nullptr;
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP nsCMSMessage::CreateSigned(nsIX509Cert* aSigningCert, nsIX509Cert* aEncryptCert, unsigned char* aDigestData, uint32_t aDigestDataLen, nsIArray * secureHeaders, int32_t canonAlgo)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned\n"));
+ NSSCMSContentInfo *cinfo;
+ NSSCMSSignedData *sigd;
+ NSSCMSSignerInfo *signerinfo;
+ ScopedCERTCertificate scert;
+ ScopedCERTCertificate ecert;
+ nsCOMPtr<nsIX509Cert2> aSigningCert2 = do_QueryInterface(aSigningCert);
+ nsresult rv = NS_ERROR_FAILURE;
+
+ /* Get the certs */
+ if (aSigningCert2) {
+ scert = aSigningCert2->GetCert();
+ }
+ if (!scert) {
+ return NS_ERROR_FAILURE;
+ }
+
+ if (aEncryptCert) {
+ nsCOMPtr<nsIX509Cert2> aEncryptCert2 = do_QueryInterface(aEncryptCert);
+ if (aEncryptCert2) {
+ ecert = aEncryptCert2->GetCert();
+ }
+ }
+
+ /*
+ * create the message object
+ */
+ m_cmsMsg = NSS_CMSMessage_Create(nullptr); /* create a message on its own pool */
+ if (!m_cmsMsg) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't create new message\n"));
+ rv = NS_ERROR_OUT_OF_MEMORY;
+ goto loser;
+ }
+
+ /*
+ * build chain of objects: message->signedData->data
+ */
+ if ((sigd = NSS_CMSSignedData_Create(m_cmsMsg)) == nullptr) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't create signed data\n"));
+ goto loser;
+ }
+ cinfo = NSS_CMSMessage_GetContentInfo(m_cmsMsg);
+ if (NSS_CMSContentInfo_SetContent_SignedData(m_cmsMsg, cinfo, sigd)
+ != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't set content signed data\n"));
+ goto loser;
+ }
+
+ cinfo = NSS_CMSSignedData_GetContentInfo(sigd);
+
+ if (mHasReceipt) {
+ /* Set receipt content-type*/
+ if (NSS_CMSContentInfo_SetContent(m_cmsMsg, cinfo, SEC_OID_SMIME_RECEIPT, nullptr)
+ != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't set content receipt\n"));
+ goto loser;
+ }
+ } else {
+ /* we're always passing data in and detaching optionally */
+ if (NSS_CMSContentInfo_SetContent_Data(m_cmsMsg, cinfo, nullptr, true)
+ != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't set content data\n"));
+ goto loser;
+ }
+ }
+
+ /*
+ * create & attach signer information
+ */
+ if ((signerinfo = NSS_CMSSignerInfo_Create(m_cmsMsg, scert, SEC_OID_SHA1))
+ == nullptr) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't create signer info\n"));
+ goto loser;
+ }
+
+ /* we want the cert chain included for this one */
+ if (NSS_CMSSignerInfo_IncludeCerts(signerinfo, NSSCMSCM_CertChain,
+ certUsageEmailSigner)
+ != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't include signer cert chain\n"));
+ goto loser;
+ }
+
+ if (NSS_CMSSignerInfo_AddSigningTime(signerinfo, PR_Now())
+ != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add signing time\n"));
+ goto loser;
+ }
+
+ if (NSS_CMSSignerInfo_AddSMIMECaps(signerinfo) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add smime caps\n"));
+ goto loser;
+ }
+
+ //Add Secure Headers
+ if(secureHeaders!=NULL){
+
+ uint32_t nbHeaders=0;
+ SecHeaderField * headerFields= NULL;
+ secureHeaders->GetLength(&nbHeaders);
+ if(nbHeaders>0)
+ {
+ int32_t i=0;
+ headerFields = (SecHeaderField *)PORT_Alloc(nbHeaders * sizeof(SecHeaderField));
+ //init to null
+ for(i=0;i<nbHeaders;++i){
+ headerFields[i].headerName = NULL;
+ headerFields[i].headerValue = NULL;
+ }
+
+ for(i=0;i<nbHeaders;++i){
+
+ nsCOMPtr<nsIMsgSMIMESecureHeader> _secureHeader= do_QueryElementAt(secureHeaders,i);
+ if (_secureHeader){
+ nsAutoString _headerName;
+ nsAutoString _headerValue;
+ _secureHeader->GetHeaderStatus(&headerFields[i].headerStatus);
+ //_secureHeader->GetHeaderEncrypted(&headerFields[i].headerEncrypted);
+ _secureHeader->GetHeaderName(_headerName);
+ _secureHeader->GetHeaderValue(_headerValue);
+ if(_headerName.Length()>0){
+ /*headerFields[i].headerName = (char *)PORT_Alloc((_headerName.Length()+1) * sizeof (char));
+ PORT_Memcpy (headerFields[i].headerName,(char *)(NS_ConvertUTF16toUTF8(_headerName).get()),_headerName.Length());
+ headerFields[i].headerName[_headerName.Length()]='\0';*/
+ nsAutoCString hdrNameUTF8 = NS_ConvertUTF16toUTF8(_headerName);
+ headerFields[i].headerName = (char *)PORT_Alloc((hdrNameUTF8.Length()+1) * sizeof (char));
+ PORT_Memcpy (headerFields[i].headerName,(char *)hdrNameUTF8.get(),hdrNameUTF8.Length());
+ headerFields[i].headerName[hdrNameUTF8.Length()]='\0';
+
+ }
+ if(_headerValue.Length()>0){
+ /*headerFields[i].headerValue = (char *)PORT_Alloc((_headerValue.Length()+1) * sizeof (char));
+ PORT_Memcpy (headerFields[i].headerValue,(char *)(NS_ConvertUTF16toUTF8(_headerValue).get()),_headerValue.Length());
+ headerFields[i].headerValue[_headerValue.Length()]='\0';*/
+ nsAutoCString hdrValueUTF8 = NS_ConvertUTF16toUTF8(_headerValue);
+ headerFields[i].headerValue = (char *)PORT_Alloc((hdrValueUTF8.Length()+1) * sizeof (char));
+ PORT_Memcpy (headerFields[i].headerValue,(char *)hdrValueUTF8.get(),hdrValueUTF8.Length());
+ headerFields[i].headerValue[hdrValueUTF8.Length()]='\0';
+ }
+
+ }
+ }
+
+ if (NSS_CMSSignerInfo_AddSecureHeader(signerinfo, headerFields,nbHeaders,canonAlgo) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add Secure Headers\n"));
+ //free memory
+ for(i=0;i<nbHeaders;++i)
+ {
+ if(headerFields[i].headerName!=NULL)
+ PORT_Free((char *)(headerFields[i].headerName));
+ if(headerFields[i].headerValue!=NULL)
+ PORT_Free((char *)(headerFields[i].headerValue));
+ }
+ PORT_Free((SecHeaderField *)headerFields);
+ //free memory
+ goto loser;
+ }
+ //free memory
+ for(i=0;i<nbHeaders;++i)
+ {
+ if(headerFields[i].headerName!=NULL)
+ PORT_Free((char *)(headerFields[i].headerName));
+ if(headerFields[i].headerValue!=NULL)
+ PORT_Free((char *)(headerFields[i].headerValue));
+ }
+ PORT_Free((SecHeaderField *)headerFields);
+ //free memory
+ }
+ }
+ /* Add receipt request */
+ if (mHasReceiptRequest) {
+ if (NSS_CMSSignerInfo_AddReceiptRequest(signerinfo,
+ (char*)(mReceiptRequestSignedContentIdentifier.get()),
+ (char*)(mReceiptRequestReceiptsTo.get())) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add receipt request\n"));
+ goto loser;
+ }
+ }
+
+ /* Add msgSigDigest attribute for a receipt */
+ if (mHasReceipt) {
+ if (NSS_CMSSignerInfo_AddMsgSigDigest(signerinfo, mReceiptMsgSigDigest, mReceiptMsgSigDigestLen) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add msgSigDigest attribute\n"));
+ goto loser;
+ }
+ }
+
+ /* Add Security Label */
+ if (mHasSecurityLabel) {
+ if (NSS_CMSSignerInfo_AddSecurityLabel(signerinfo,
+ (char*)(mSecurityPolicyIdentifier.get()),
+ mSecurityClassification,
+ (char*)(mPrivacyMark.get()),
+ (char*)(mSecurityCategories.get())) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add security label\n"));
+ goto loser;
+ }
+ }
+
+ if (ecert) {
+ if (NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(signerinfo, ecert,
+ CERT_GetDefaultCertDB())
+ != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add smime enc key prefs\n"));
+ goto loser;
+ }
+
+ if (NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs(signerinfo, ecert,
+ CERT_GetDefaultCertDB())
+ != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add MS smime enc key prefs\n"));
+ goto loser;
+ }
+
+ // If signing and encryption cert are identical, don't add it twice.
+ bool addEncryptionCert =
+ (ecert && (!scert || !CERT_CompareCerts(ecert, scert)));
+
+ if (addEncryptionCert &&
+ NSS_CMSSignedData_AddCertificate(sigd, ecert) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add own encryption certificate\n"));
+ goto loser;
+ }
+ }
+
+ if (NSS_CMSSignedData_AddSignerInfo(sigd, signerinfo) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't add signer info\n"));
+ goto loser;
+ }
+
+ // Finally, add the pre-computed digest if passed in
+ if (aDigestData) {
+ SECItem digest;
+
+ digest.data = aDigestData;
+ digest.len = aDigestDataLen;
+
+ if (NSS_CMSSignedData_SetDigestValue(sigd, SEC_OID_SHA1, &digest)) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSMessage::CreateSigned - can't set digest value\n"));
+ goto loser;
+ }
+ }
+
+ return NS_OK;
+loser:
+ if (m_cmsMsg) {
+ NSS_CMSMessage_Destroy(m_cmsMsg);
+ m_cmsMsg = nullptr;
+ }
+ return rv;
+}
+
+NS_IMETHODIMP nsCMSMessage::GetSecureHeader( nsIMutableArray ** _secureHeaders, int32_t * canonAlgo){
+ NS_ENSURE_ARG_POINTER(_secureHeaders);
+
+ nsresult rv;
+ nsCOMPtr<nsIMutableArray> tmpSecureHeaders = do_CreateInstance(NS_ARRAY_CONTRACTID, &rv);
+ if(NS_SUCCEEDED(rv)){
+ NSSCMSSecureHeader secureHeaders;
+ int i=0;
+ int secureHeaderItem=0;
+ int ca_len = 0;
+
+ NSSCMSSignerInfo *signerinfo = GetTopLevelSignerInfo();
+ if (!signerinfo) return NS_ERROR_FAILURE;
+ if(NSS_CMSSignerInfo_GetSecureHeader(signerinfo,&secureHeaders)==SECSuccess)
+ {
+ for(secureHeaderItem=0;secureHeaderItem<2;++secureHeaderItem){
+ if(secureHeaders.element[secureHeaderItem]!=NULL){
+ switch(secureHeaders.element[secureHeaderItem]->selector){
+ case NSSCMSSecureHeaderElement_canonAlgorithm :
+ ca_len=secureHeaders.element[secureHeaderItem]->id.canonAlgorithm.len;
+ *canonAlgo=0;
+ if((ca_len>0) &&(secureHeaders.element[secureHeaderItem]->id.canonAlgorithm.data!=NULL))
+ {
+ if(ca_len == 4){
+ /* canonAlgorithm is encoded with 4 octets */
+ if((secureHeaders.element[secureHeaderItem]->id.canonAlgorithm.data[3] & 0x1) == 1){
+ *canonAlgo=1;
+ }
+ }else{
+ if(ca_len == 1){
+ /* canonAlgorithm is encoded with 1 octet */
+ if((secureHeaders.element[secureHeaderItem]->id.canonAlgorithm.data[0] & 0x1) == 1){
+ *canonAlgo=1;
+ }
+ }
+ }
+ }
+ break;
+ case NSSCMSSecureHeaderElement_secHeaderField :
+ for(i=0;secureHeaders.element[secureHeaderItem]->id.secHeaderFields[i]!=NULL;++i)
+ {
+ nsAutoString headerValue;
+ nsAutoString headerName;
+ int32_t headerStatus=0;
+ //int32_t headerEncrypted=0;
+ NSSCMSSecHeaderFieldElement * secHeaderElement = NULL;
+ secHeaderElement=secureHeaders.element[secureHeaderItem]->id.secHeaderFields[i];
+ if(secHeaderElement!=NULL){
+ int hn_len=secHeaderElement->HeaderFieldName.len;
+ if(hn_len>0){
+ char * tmp_name=(char *) PORT_Alloc((hn_len+1) * sizeof(char));
+ PORT_Memcpy(tmp_name,secHeaderElement->HeaderFieldName.data,hn_len);
+ tmp_name[hn_len]='\0';
+ headerName.Assign(NS_ConvertUTF8toUTF16(tmp_name));
+ PORT_Free((char *)tmp_name);
+ }
+ int hv_len=secHeaderElement->HeaderFieldValue.len;
+ if(hv_len>0){
+ char * tmp_value=(char *) PORT_Alloc((hv_len+1) * sizeof(char));
+ PORT_Memcpy(tmp_value,secHeaderElement->HeaderFieldValue.data,hv_len);
+ tmp_value[hv_len]='\0';
+ headerValue.Assign(NS_ConvertUTF8toUTF16(tmp_value));
+ PORT_Free((char *)tmp_value);
+ }
+ int hs_len=secHeaderElement->HeaderFieldStatus.len;
+ if((hs_len>0) && (secHeaderElement->HeaderFieldStatus.data!=NULL)){
+ PORT_Memcpy(&headerStatus,secHeaderElement->HeaderFieldStatus.data,1);
+ }
+ else{
+ headerStatus = -1;
+ }
+
+ /*int he_len=secHeaderElement->HeaderFieldEncrypted.len;
+ if((he_len>0) && (secHeaderElement->HeaderFieldEncrypted.data!=NULL)){
+ PORT_Memcpy(&headerEncrypted,secHeaderElement->HeaderFieldEncrypted.data,1);
+ }
+ else{
+ headerEncrypted = -1;
+ }*/
+
+ nsCOMPtr<nsIMsgSMIMESecureHeader> secureHeader = do_CreateInstance(NS_SMIMESECUREHEADER_CONTRACTID,&rv);
+ if(NS_SUCCEEDED(rv))
+ {
+ secureHeader->SetHeaderName(headerName);
+ secureHeader->SetHeaderValue(headerValue);
+ secureHeader->SetHeaderStatus(headerStatus);
+ //secureHeader->SetHeaderEncrypted(headerEncrypted);
+ tmpSecureHeaders->AppendElement(secureHeader,PR_FALSE);
+ }
+ }
+ }
+ break;
+ }
+ }
+ }
+ }
+ }
+ NS_ADDREF(*_secureHeaders = tmpSecureHeaders);
+
+ return NS_OK;
+}
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsCMSDecoder, nsICMSDecoder)
+
+nsCMSDecoder::nsCMSDecoder()
+: m_dcx(nullptr)
+{
+}
+
+nsCMSDecoder::~nsCMSDecoder()
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return;
+
+ destructorSafeDestroyNSSReference();
+ shutdown(calledFromObject);
+}
+
+void nsCMSDecoder::virtualDestroyNSSReference()
+{
+ destructorSafeDestroyNSSReference();
+}
+
+void nsCMSDecoder::destructorSafeDestroyNSSReference()
+{
+ if (isAlreadyShutDown())
+ return;
+
+ if (m_dcx) {
+ NSS_CMSDecoder_Cancel(m_dcx);
+ m_dcx = nullptr;
+ }
+}
+
+/* void start (in NSSCMSContentCallback cb, in voidPtr arg); */
+NS_IMETHODIMP nsCMSDecoder::Start(NSSCMSContentCallback cb, void * arg)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSDecoder::Start\n"));
+ m_ctx = new PipUIContext();
+
+ m_dcx = NSS_CMSDecoder_Start(0, cb, arg, 0, m_ctx, 0, 0);
+ if (!m_dcx) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSDecoder::Start - can't start decoder\n"));
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+/* void update (in string bug, in long len); */
+NS_IMETHODIMP nsCMSDecoder::Update(const char *buf, int32_t len)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSDecoder::Update\n"));
+ NSS_CMSDecoder_Update(m_dcx, (char *)buf, len);
+ return NS_OK;
+}
+
+/* void finish (); */
+NS_IMETHODIMP nsCMSDecoder::Finish(nsICMSMessage ** aCMSMsg)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSDecoder::Finish\n"));
+ NSSCMSMessage *cmsMsg;
+ cmsMsg = NSS_CMSDecoder_Finish(m_dcx);
+ m_dcx = nullptr;
+ if (cmsMsg) {
+ nsCMSMessage *obj = new nsCMSMessage(cmsMsg);
+ // The NSS object cmsMsg still carries a reference to the context
+ // we gave it on construction.
+ // Make sure the context will live long enough.
+ obj->referenceContext(m_ctx);
+ *aCMSMsg = obj;
+ NS_ADDREF(*aCMSMsg);
+ }
+ return NS_OK;
+}
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(nsCMSEncoder, nsICMSEncoder)
+
+nsCMSEncoder::nsCMSEncoder()
+: m_ecx(nullptr)
+{
+}
+
+nsCMSEncoder::~nsCMSEncoder()
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return;
+
+ destructorSafeDestroyNSSReference();
+ shutdown(calledFromObject);
+}
+
+void nsCMSEncoder::virtualDestroyNSSReference()
+{
+ destructorSafeDestroyNSSReference();
+}
+
+void nsCMSEncoder::destructorSafeDestroyNSSReference()
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return;
+
+ if (m_ecx)
+ NSS_CMSEncoder_Cancel(m_ecx);
+}
+
+/* void start (); */
+NS_IMETHODIMP nsCMSEncoder::Start(nsICMSMessage *aMsg, NSSCMSContentCallback cb, void * arg)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Start\n"));
+ nsCMSMessage *cmsMsg = static_cast<nsCMSMessage*>(aMsg);
+ m_ctx = new PipUIContext();
+
+ m_ecx = NSS_CMSEncoder_Start(cmsMsg->getCMS(), cb, arg, 0, 0, 0, m_ctx, 0, 0, 0, 0);
+ if (!m_ecx) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Start - can't start encoder\n"));
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+/* void update (in string aBuf, in long aLen); */
+NS_IMETHODIMP nsCMSEncoder::Update(const char *aBuf, int32_t aLen)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Update\n"));
+ if (!m_ecx || NSS_CMSEncoder_Update(m_ecx, aBuf, aLen) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Update - can't update encoder\n"));
+ return NS_ERROR_FAILURE;
+ }
+ return NS_OK;
+}
+
+/* void finish (); */
+NS_IMETHODIMP nsCMSEncoder::Finish()
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ nsresult rv = NS_OK;
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Finish\n"));
+ if (!m_ecx || NSS_CMSEncoder_Finish(m_ecx) != SECSuccess) {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Finish - can't finish encoder\n"));
+ rv = NS_ERROR_FAILURE;
+ }
+ m_ecx = nullptr;
+ return rv;
+}
+
+/* void encode (in nsICMSMessage aMsg); */
+NS_IMETHODIMP nsCMSEncoder::Encode(nsICMSMessage *aMsg)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("nsCMSEncoder::Encode\n"));
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#ifndef __NS_CMS_H__
+#define __NS_CMS_H__
+
+#include "nsISupports.h"
+#include "nsCOMPtr.h"
+#include "nsXPIDLString.h"
+#include "nsIInterfaceRequestor.h"
+#include "nsICMSMessage.h"
+#include "nsICMSMessage2.h"
+#include "nsIX509Cert3.h"
+#include "nsVerificationJob.h"
+#include "nsICMSEncoder.h"
+#include "nsICMSDecoder.h"
+#include "sechash.h"
+#include "cms.h"
+#include "nsNSSShutDown.h"
+
+#define NS_CMSMESSAGE_CID \
+ { 0xa4557478, 0xae16, 0x11d5, { 0xba,0x4b,0x00,0x10,0x83,0x03,0xb1,0x17 } }
+
+class nsCMSMessage : public nsICMSMessage,
+ public nsICMSMessage2,
+ public nsNSSShutDownObject
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSICMSMESSAGE
+ NS_DECL_NSICMSMESSAGE2
+
+ nsCMSMessage();
+ nsCMSMessage(NSSCMSMessage* aCMSMsg);
+ virtual ~nsCMSMessage();
+
+ void referenceContext(nsIInterfaceRequestor* aContext) {m_ctx = aContext;}
+ NSSCMSMessage* getCMS() {return m_cmsMsg;}
+private:
+ nsCOMPtr<nsIInterfaceRequestor> m_ctx;
+ NSSCMSMessage * m_cmsMsg;
+
+ bool mHasReceiptRequest;
+ nsCString mReceiptRequestSignedContentIdentifier;
+ nsCString mReceiptRequestReceiptsTo;
+
+ bool mHasReceipt;
+ unsigned char *mReceiptSignedContentIdentifier;
+ unsigned long mReceiptSignedContentIdentifierLen;
+ unsigned char *mReceiptOriginatorSignatureValue;
+ unsigned long mReceiptOriginatorSignatureValueLen;
+ unsigned char *mReceiptOriginatorContentType;
+ unsigned long mReceiptOriginatorContentTypeLen;
+ unsigned char *mReceiptMsgSigDigest;
+ unsigned long mReceiptMsgSigDigestLen;
+
+ bool mHasSecurityLabel;
+ nsCString mSecurityPolicyIdentifier;
+ long mSecurityClassification;
+ nsCString mPrivacyMark;
+ nsCString mSecurityCategories;
+
+ NSSCMSSignerInfo* GetTopLevelSignerInfo();
+ nsresult CommonVerifySignature(unsigned char* aDigestData, uint32_t aDigestDataLen);
+
+ nsresult CommonAsyncVerifySignature(nsISMimeVerificationListener *aListener,
+ unsigned char* aDigestData, uint32_t aDigestDataLen);
+
+ virtual void virtualDestroyNSSReference();
+ void destructorSafeDestroyNSSReference();
+
+friend class nsSMimeVerificationJob;
+};
+
+// ===============================================
+// nsCMSDecoder - implementation of nsICMSDecoder
+// ===============================================
+
+#define NS_CMSDECODER_CID \
+ { 0x9dcef3a4, 0xa3bc, 0x11d5, { 0xba, 0x47, 0x00, 0x10, 0x83, 0x03, 0xb1, 0x17 } }
+
+class nsCMSDecoder : public nsICMSDecoder,
+ public nsNSSShutDownObject
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSICMSDECODER
+
+ nsCMSDecoder();
+ virtual ~nsCMSDecoder();
+
+private:
+ nsCOMPtr<nsIInterfaceRequestor> m_ctx;
+ NSSCMSDecoderContext *m_dcx;
+ virtual void virtualDestroyNSSReference();
+ void destructorSafeDestroyNSSReference();
+};
+
+// ===============================================
+// nsCMSEncoder - implementation of nsICMSEncoder
+// ===============================================
+
+#define NS_CMSENCODER_CID \
+ { 0xa15789aa, 0x8903, 0x462b, { 0x81, 0xe9, 0x4a, 0xa2, 0xcf, 0xf4, 0xd5, 0xcb } }
+class nsCMSEncoder : public nsICMSEncoder,
+ public nsNSSShutDownObject
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSICMSENCODER
+
+ nsCMSEncoder();
+ virtual ~nsCMSEncoder();
+
+private:
+ nsCOMPtr<nsIInterfaceRequestor> m_ctx;
+ NSSCMSEncoderContext *m_ecx;
+ virtual void virtualDestroyNSSReference();
+ void destructorSafeDestroyNSSReference();
+};
+
+#endif
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Kai Engert <kengert@redhat.com>
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved */
+
+#include "nsClientAuthRemember.h"
+
+#include "nsIX509Cert.h"
+#include "mozilla/RefPtr.h"
+#include "nsCRT.h"
+#include "nsNetUtil.h"
+#include "nsNSSCertHelper.h"
+#include "nsIObserverService.h"
+#include "nsNetUtil.h"
+#include "nsISupportsPrimitives.h"
+#include "nsPromiseFlatString.h"
+#include "nsThreadUtils.h"
+#include "nsStringBuffer.h"
+#include "cert.h"
+#include "nspr.h"
+#include "pk11pub.h"
+#include "certdb.h"
+#include "sechash.h"
+#include "SharedSSLState.h"
+
+using namespace mozilla;
+using namespace mozilla::psm;
+
+NS_IMPL_THREADSAFE_ISUPPORTS2(nsClientAuthRememberService,
+ nsIObserver,
+ nsISupportsWeakReference)
+
+nsClientAuthRememberService::nsClientAuthRememberService()
+ : monitor("nsClientAuthRememberService.monitor")
+{
+}
+
+nsClientAuthRememberService::~nsClientAuthRememberService()
+{
+ RemoveAllFromMemory();
+}
+
+nsresult
+nsClientAuthRememberService::Init()
+{
+ if (!NS_IsMainThread()) {
+ NS_ERROR("nsClientAuthRememberService::Init called off the main thread");
+ return NS_ERROR_NOT_SAME_THREAD;
+ }
+
+ mSettingsTable.Init();
+
+ nsCOMPtr<nsIObserverService> observerService =
+ mozilla::services::GetObserverService();
+ if (observerService) {
+ observerService->AddObserver(this, "profile-before-change", true);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsClientAuthRememberService::Observe(nsISupports *aSubject,
+ const char *aTopic,
+ const PRUnichar *aData)
+{
+ // check the topic
+ if (!nsCRT::strcmp(aTopic, "profile-before-change")) {
+ // The profile is about to change,
+ // or is going away because the application is shutting down.
+
+ ReentrantMonitorAutoEnter lock(monitor);
+ RemoveAllFromMemory();
+ }
+
+ return NS_OK;
+}
+
+void nsClientAuthRememberService::ClearRememberedDecisions()
+{
+ ReentrantMonitorAutoEnter lock(monitor);
+ RemoveAllFromMemory();
+}
+
+void nsClientAuthRememberService::ClearAllRememberedDecisions()
+{
+ RefPtr<nsClientAuthRememberService> svc =
+ PublicSSLState()->GetClientAuthRememberService();
+ svc->ClearRememberedDecisions();
+
+ svc = PrivateSSLState()->GetClientAuthRememberService();
+ svc->ClearRememberedDecisions();
+}
+
+void
+nsClientAuthRememberService::RemoveAllFromMemory()
+{
+ mSettingsTable.Clear();
+}
+
+static nsresult
+GetCertFingerprintByOidTag(CERTCertificate* nsscert,
+ SECOidTag aOidTag,
+ nsCString &fp)
+{
+ unsigned int hash_len = HASH_ResultLenByOidTag(aOidTag);
+ nsRefPtr<nsStringBuffer> fingerprint = nsStringBuffer::Alloc(hash_len);
+ if (!fingerprint)
+ return NS_ERROR_OUT_OF_MEMORY;
+
+ PK11_HashBuf(aOidTag, (unsigned char*)fingerprint->Data(),
+ nsscert->derCert.data, nsscert->derCert.len);
+
+ SECItem fpItem;
+ fpItem.data = (unsigned char*)fingerprint->Data();
+ fpItem.len = hash_len;
+
+ fp.Adopt(CERT_Hexify(&fpItem, 1));
+ return NS_OK;
+}
+
+nsresult
+nsClientAuthRememberService::RememberDecision(const nsACString & aHostName,
+ CERTCertificate *aServerCert, CERTCertificate *aClientCert)
+{
+ // aClientCert == nullptr means: remember that user does not want to use a cert
+ NS_ENSURE_ARG_POINTER(aServerCert);
+ if (aHostName.IsEmpty())
+ return NS_ERROR_INVALID_ARG;
+
+ nsAutoCString fpStr;
+ nsresult rv = GetCertFingerprintByOidTag(aServerCert, SEC_OID_SHA256, fpStr);
+ if (NS_FAILED(rv))
+ return rv;
+
+ {
+ ReentrantMonitorAutoEnter lock(monitor);
+ if (aClientCert) {
+ nsNSSCertificate pipCert(aClientCert);
+ char *dbkey = nullptr;
+ rv = pipCert.GetDbKey(&dbkey);
+ if (NS_SUCCEEDED(rv) && dbkey) {
+ AddEntryToList(aHostName, fpStr,
+ nsDependentCString(dbkey));
+ }
+ if (dbkey) {
+ PORT_Free(dbkey);
+ }
+ }
+ else {
+ nsCString empty;
+ AddEntryToList(aHostName, fpStr, empty);
+ }
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsClientAuthRememberService::HasRememberedDecision(const nsACString & aHostName,
+ CERTCertificate *aCert,
+ nsACString & aCertDBKey,
+ bool *_retval)
+{
+ if (aHostName.IsEmpty())
+ return NS_ERROR_INVALID_ARG;
+
+ NS_ENSURE_ARG_POINTER(aCert);
+ NS_ENSURE_ARG_POINTER(_retval);
+ *_retval = false;
+
+ nsresult rv;
+ nsAutoCString fpStr;
+ rv = GetCertFingerprintByOidTag(aCert, SEC_OID_SHA256, fpStr);
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsAutoCString hostCert;
+ GetHostWithCert(aHostName, fpStr, hostCert);
+ nsClientAuthRemember settings;
+
+ {
+ ReentrantMonitorAutoEnter lock(monitor);
+ nsClientAuthRememberEntry *entry = mSettingsTable.GetEntry(hostCert.get());
+ if (!entry)
+ return NS_OK;
+ settings = entry->mSettings; // copy
+ }
+
+ aCertDBKey = settings.mDBKey;
+ *_retval = true;
+ return NS_OK;
+}
+
+nsresult
+nsClientAuthRememberService::AddEntryToList(const nsACString &aHostName,
+ const nsACString &fingerprint,
+ const nsACString &db_key)
+
+{
+ nsAutoCString hostCert;
+ GetHostWithCert(aHostName, fingerprint, hostCert);
+
+ {
+ ReentrantMonitorAutoEnter lock(monitor);
+ nsClientAuthRememberEntry *entry = mSettingsTable.PutEntry(hostCert.get());
+
+ if (!entry) {
+ NS_ERROR("can't insert a null entry!");
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ entry->mHostWithCert = hostCert;
+
+ nsClientAuthRemember &settings = entry->mSettings;
+ settings.mAsciiHost = aHostName;
+ settings.mFingerprint = fingerprint;
+ settings.mDBKey = db_key;
+ }
+
+ return NS_OK;
+}
+
+////////////////////////////////
+nsresult
+nsClientAuthRememberService::RememberDecision(const nsACString & aHostName,
+ CERTCertificate *aServerCert, CERTCertificate *aClientCert, const nsACString & aClientLogin)
+{
+ // aClientCert == NULL means: remember that user does not want to use a cert
+ NS_ENSURE_ARG_POINTER(aServerCert);
+ if (aHostName.IsEmpty())
+ return NS_ERROR_INVALID_ARG;
+
+ nsAutoCString fpStr;
+ nsresult rv = GetCertFingerprintByOidTag(aServerCert, SEC_OID_SHA256, fpStr);
+ if (NS_FAILED(rv))
+ return rv;
+
+ {
+ ReentrantMonitorAutoEnter lock(monitor);
+ if (aClientCert && aClientLogin.IsEmpty()) {
+ AddEntryToList(aHostName, fpStr,
+ nsDependentCString(aClientCert->nickname));
+ }
+ else if(aClientCert && !aClientLogin.IsEmpty()){
+ AddEntryToList(aHostName, fpStr,
+ nsDependentCString(aClientCert->nickname),
+ aClientLogin);
+ }
+ else {
+ nsCString empty;
+ AddEntryToList(aHostName, fpStr, empty);
+ }
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsClientAuthRememberService::HasRememberedDecision(const nsACString & aHostName,
+ CERTCertificate *aCert,
+ nsACString & aCertDBKey,
+ bool *_retval,
+ const nsACString & aClientLogin)
+{
+ if (aHostName.IsEmpty())
+ return NS_ERROR_INVALID_ARG;
+
+ NS_ENSURE_ARG_POINTER(aCert);
+ NS_ENSURE_ARG_POINTER(_retval);
+ *_retval = false;
+
+ nsresult rv;
+ nsAutoCString fpStr;
+ rv = GetCertFingerprintByOidTag(aCert, SEC_OID_SHA256, fpStr);
+ if (NS_FAILED(rv))
+ return rv;
+
+ nsAutoCString hostCert;
+ GetHostWithCert(aHostName, fpStr, hostCert);
+ nsClientAuthRemember settings;
+
+ {
+ ReentrantMonitorAutoEnter lock(monitor);
+ nsClientAuthRememberEntry *entry = mSettingsTable.GetEntry(hostCert.get());
+ if (!entry)
+ return NS_OK;
+ settings = entry->mSettings; // copy
+ }
+
+ aCertDBKey = settings.mDBKey;
+ if(aCertDBKey.IsEmpty() || aCertDBKey.Equals(settings.mDBKey))
+ *_retval = true;
+
+ return NS_OK;
+}
+
+nsresult
+nsClientAuthRememberService::AddEntryToList(const nsACString &aHostName,
+ const nsACString &fingerprint,
+ const nsACString &aCertDBKey,
+ const nsACString &client_login)
+
+{
+ nsAutoCString hostCert;
+ GetHostWithCert(aHostName, fingerprint, hostCert);
+
+ {
+ ReentrantMonitorAutoEnter lock(monitor);
+ nsClientAuthRememberEntry *entry = mSettingsTable.PutEntry(hostCert.get());
+
+ if (!entry) {
+ NS_ERROR("can't insert a null entry!");
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ entry->mHostWithCert = hostCert;
+
+ nsClientAuthRemember &settings = entry->mSettings;
+ settings.mAsciiHost = aHostName;
+ settings.mFingerprint = fingerprint;
+ settings.mDBKey = aCertDBKey;
+ settings.mClientLogin = client_login;
+ }
+
+ return NS_OK;
+}
+////////////////////////////////
+
+void
+nsClientAuthRememberService::GetHostWithCert(const nsACString & aHostName,
+ const nsACString & fingerprint,
+ nsACString& _retval)
+{
+ nsAutoCString hostCert(aHostName);
+ hostCert.AppendLiteral(":");
+ hostCert.Append(fingerprint);
+
+ _retval.Assign(hostCert);
+}
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Kai Engert <kengert@redhat.com>
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved */
+
+#ifndef __NSCLIENTAUTHREMEMBER_H__
+#define __NSCLIENTAUTHREMEMBER_H__
+
+#include "mozilla/ReentrantMonitor.h"
+#include "nsTHashtable.h"
+#include "nsIObserver.h"
+#include "nsIX509Cert.h"
+#include "nsAutoPtr.h"
+#include "nsNSSCertificate.h"
+#include "nsString.h"
+#include "nsWeakReference.h"
+#include "mozilla/Attributes.h"
+
+class nsClientAuthRemember
+{
+public:
+
+ nsClientAuthRemember()
+ {
+ }
+
+ nsClientAuthRemember(const nsClientAuthRemember &other)
+ {
+ this->operator=(other);
+ }
+
+ nsClientAuthRemember &operator=(const nsClientAuthRemember &other)
+ {
+ mAsciiHost = other.mAsciiHost;
+ mFingerprint = other.mFingerprint;
+ mDBKey = other.mDBKey;
+ mClientLogin = other.mClientLogin;
+ return *this;
+ }
+
+ nsCString mAsciiHost;
+ nsCString mFingerprint;
+ nsCString mDBKey;
+ nsCString mClientLogin;
+};
+
+
+// hash entry class
+class nsClientAuthRememberEntry MOZ_FINAL : public PLDHashEntryHdr
+{
+ public:
+ // Hash methods
+ typedef const char* KeyType;
+ typedef const char* KeyTypePointer;
+
+ // do nothing with aHost - we require mHead to be set before we're live!
+ nsClientAuthRememberEntry(KeyTypePointer aHostWithCertUTF8)
+ {
+ }
+
+ nsClientAuthRememberEntry(const nsClientAuthRememberEntry& toCopy)
+ {
+ mSettings = toCopy.mSettings;
+ }
+
+ ~nsClientAuthRememberEntry()
+ {
+ }
+
+ KeyType GetKey() const
+ {
+ return HostWithCertPtr();
+ }
+
+ KeyTypePointer GetKeyPointer() const
+ {
+ return HostWithCertPtr();
+ }
+
+ bool KeyEquals(KeyTypePointer aKey) const
+ {
+ return !strcmp(HostWithCertPtr(), aKey);
+ }
+
+ static KeyTypePointer KeyToPointer(KeyType aKey)
+ {
+ return aKey;
+ }
+
+ static PLDHashNumber HashKey(KeyTypePointer aKey)
+ {
+ // PL_DHashStringKey doesn't use the table parameter, so we can safely
+ // pass nullptr
+ return PL_DHashStringKey(nullptr, aKey);
+ }
+
+ enum { ALLOW_MEMMOVE = false };
+
+ // get methods
+ inline const nsCString &HostWithCert() const { return mHostWithCert; }
+
+ inline KeyTypePointer HostWithCertPtr() const
+ {
+ return mHostWithCert.get();
+ }
+
+ nsClientAuthRemember mSettings;
+ nsCString mHostWithCert;
+};
+
+class nsClientAuthRememberService MOZ_FINAL : public nsIObserver,
+ public nsSupportsWeakReference
+{
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+
+ nsClientAuthRememberService();
+ ~nsClientAuthRememberService();
+
+ nsresult Init();
+
+ static void GetHostWithCert(const nsACString & aHostName,
+ const nsACString & nickname, nsACString& _retval);
+
+ nsresult RememberDecision(const nsACString & aHostName,
+ CERTCertificate *aServerCert, CERTCertificate *aClientCert);
+ nsresult HasRememberedDecision(const nsACString & aHostName,
+ CERTCertificate *aServerCert,
+ nsACString & aCertDBKey, bool *_retval);
+
+ nsresult RememberDecision(const nsACString & aHostName,
+ CERTCertificate *aServerCert, CERTCertificate *aClientCert, const nsACString & aClientLogin);
+ nsresult HasRememberedDecision(const nsACString & aHostName,
+ CERTCertificate *aServerCert,
+ nsACString & aCertDBKey, bool *_retval,
+ const nsACString & aClientLogin);
+
+ void ClearRememberedDecisions();
+ static void ClearAllRememberedDecisions();
+
+protected:
+ mozilla::ReentrantMonitor monitor;
+ nsTHashtable<nsClientAuthRememberEntry> mSettingsTable;
+
+ void RemoveAllFromMemory();
+ nsresult AddEntryToList(const nsACString &host,
+ const nsACString &server_fingerprint,
+ const nsACString &db_key);
+
+ nsresult AddEntryToList(const nsACString &host,
+ const nsACString &server_fingerprint,
+ const nsACString &client_nickname,
+ const nsACString &db_key);
+};
+
+#endif
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. * Contributor(s):
+ * Brian Ryner <bryner@brianryner.com>
+ * Javier Delgadillo <javi@netscape.com>
+ * Kai Engert <kengert@redhat.com>
+ * Copyright (c) 2010 CASSIDIAN - All rights reserved */
+
+#include "nsNSSComponent.h"
+#include "nsNSSIOLayer.h"
+
+#include "mozilla/Telemetry.h"
+
+#include "prlog.h"
+#include "prnetdb.h"
+#include "nsIPrefService.h"
+#include "nsIClientAuthDialogs.h"
+#include "nsClientAuthRemember.h"
+#include "nsISSLErrorListener.h"
+
+#include "nsNetUtil.h"
+#include "nsPrintfCString.h"
+#include "SSLServerCertVerification.h"
+#include "nsNSSCertHelper.h"
+#include "nsNSSCleaner.h"
+
+#ifndef NSS_NO_LIBPKIX
+#include "nsIDocShell.h"
+#include "nsIDocShellTreeItem.h"
+#include "nsISecureBrowserUI.h"
+#include "nsIInterfaceRequestorUtils.h"
+#endif
+
+#include "nsCharSeparatedTokenizer.h"
+#include "nsIConsoleService.h"
+#include "PSMRunnable.h"
+#include "ScopedNSSTypes.h"
+#include "SharedSSLState.h"
+#include "mozilla/Preferences.h"
+
+#include "ssl.h"
+#include "secerr.h"
+#include "sslerr.h"
+#include "secder.h"
+#include "keyhi.h"
+
+using namespace mozilla;
+using namespace mozilla::psm;
+
+//#define DEBUG_SSL_VERBOSE //Enable this define to get minimal
+ //reports when doing SSL read/write
+
+//#define DUMP_BUFFER //Enable this define along with
+ //DEBUG_SSL_VERBOSE to dump SSL
+ //read/write buffer to a log.
+ //Uses PR_LOG except on Mac where
+ //we always write out to our own
+ //file.
+
+namespace {
+
+NSSCleanupAutoPtrClass(void, PR_FREEIF)
+
+static NS_DEFINE_CID(kNSSComponentCID, NS_NSSCOMPONENT_CID);
+
+/* SSM_UserCertChoice: enum for cert choice info */
+typedef enum {ASK, AUTO} SSM_UserCertChoice;
+
+} // unnamed namespace
+
+#ifdef PR_LOGGING
+extern PRLogModuleInfo* gPIPNSSLog;
+#endif
+
+nsNSSSocketInfo::nsNSSSocketInfo(SharedSSLState& aState, uint32_t providerFlags)
+ : mFd(nullptr),
+ mCertVerificationState(before_cert_verification),
+ mSharedState(aState),
+ mForSTARTTLS(false),
+ mSSL3Enabled(false),
+ mTLSEnabled(false),
+ mHandshakePending(true),
+ mHasCleartextPhase(false),
+ mHandshakeInProgress(false),
+ mAllowTLSIntoleranceTimeout(true),
+ mRememberClientAuthCertificate(false),
+ mHandshakeStartTime(0),
+ mFirstServerHelloReceived(false),
+ mNPNCompleted(false),
+ mHandshakeCompleted(false),
+ mJoined(false),
+ mSentClientCert(false),
+ mProviderFlags(providerFlags),
+ mSocketCreationTimestamp(TimeStamp::Now()),
+ mPlaintextBytesRead(0)
+{
+}
+
+NS_IMPL_ISUPPORTS_INHERITED2(nsNSSSocketInfo, TransportSecurityInfo,
+ nsISSLSocketControl,
+ nsIClientAuthUserDecision)
+
+NS_IMETHODIMP
+nsNSSSocketInfo::GetProviderFlags(uint32_t* aProviderFlags)
+{
+ *aProviderFlags = mProviderFlags;
+ return NS_OK;
+}
+
+nsresult
+nsNSSSocketInfo::GetHandshakePending(bool *aHandshakePending)
+{
+ *aHandshakePending = mHandshakePending;
+ return NS_OK;
+}
+
+nsresult
+nsNSSSocketInfo::SetHandshakePending(bool aHandshakePending)
+{
+ mHandshakePending = aHandshakePending;
+ return NS_OK;
+}
+
+nsresult
+nsNSSSocketInfo::SetClientLogin(const nsACString & aClientLogin)
+{
+ mClientLogin = aClientLogin;
+ return NS_OK;
+}
+
+nsresult
+nsNSSSocketInfo::GetClientLogin(nsACString & aClientLogin)
+{
+ aClientLogin = mClientLogin;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsNSSSocketInfo::GetRememberClientAuthCertificate(bool *aRememberClientAuthCertificate)
+{
+ NS_ENSURE_ARG_POINTER(aRememberClientAuthCertificate);
+ *aRememberClientAuthCertificate = mRememberClientAuthCertificate;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsNSSSocketInfo::SetRememberClientAuthCertificate(bool aRememberClientAuthCertificate)
+{
+ mRememberClientAuthCertificate = aRememberClientAuthCertificate;
+ return NS_OK;
+}
+
+void nsNSSSocketInfo::SetHasCleartextPhase(bool aHasCleartextPhase)
+{
+ mHasCleartextPhase = aHasCleartextPhase;
+}
+
+bool nsNSSSocketInfo::GetHasCleartextPhase()
+{
+ return mHasCleartextPhase;
+}
+
+NS_IMETHODIMP
+nsNSSSocketInfo::GetNotificationCallbacks(nsIInterfaceRequestor** aCallbacks)
+{
+ *aCallbacks = mCallbacks;
+ NS_IF_ADDREF(*aCallbacks);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNSSSocketInfo::SetNotificationCallbacks(nsIInterfaceRequestor* aCallbacks)
+{
+ if (!aCallbacks) {
+ mCallbacks = nullptr;
+ return NS_OK;
+ }
+
+ mCallbacks = aCallbacks;
+
+ return NS_OK;
+}
+
+#ifndef NSS_NO_LIBPKIX
+static void
+getSecureBrowserUI(nsIInterfaceRequestor * callbacks,
+ nsISecureBrowserUI ** result)
+{
+ NS_ASSERTION(result, "result parameter to getSecureBrowserUI is null");
+ *result = nullptr;
+
+ NS_ASSERTION(NS_IsMainThread(),
+ "getSecureBrowserUI called off the main thread");
+
+ if (!callbacks)
+ return;
+
+ nsCOMPtr<nsISecureBrowserUI> secureUI = do_GetInterface(callbacks);
+ if (secureUI) {
+ secureUI.forget(result);
+ return;
+ }
+
+ nsCOMPtr<nsIDocShellTreeItem> item = do_GetInterface(callbacks);
+ if (item) {
+ nsCOMPtr<nsIDocShellTreeItem> rootItem;
+ (void) item->GetSameTypeRootTreeItem(getter_AddRefs(rootItem));
+
+ nsCOMPtr<nsIDocShell> docShell = do_QueryInterface(rootItem);
+ if (docShell) {
+ (void) docShell->GetSecurityUI(result);
+ }
+ }
+}
+#endif
+
+void
+nsNSSSocketInfo::SetHandshakeCompleted(bool aResumedSession)
+{
+ if (!mHandshakeCompleted) {
+ // This will include TCP and proxy tunnel wait time
+ Telemetry::AccumulateTimeDelta(Telemetry::SSL_TIME_UNTIL_READY,
+ mSocketCreationTimestamp, TimeStamp::Now());
+
+ // If the handshake is completed for the first time from just 1 callback
+ // that means that TLS session resumption must have been used.
+ Telemetry::Accumulate(Telemetry::SSL_RESUMED_SESSION, aResumedSession);
+
+ // Remove the plain text layer as it is not needed anymore.
+ // The plain text layer is not always present - so its not a fatal error
+ // if it cannot be removed
+ PRFileDesc* poppedPlaintext =
+ PR_GetIdentitiesLayer(mFd, nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity);
+ if (poppedPlaintext) {
+ PR_PopIOLayer(mFd, nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity);
+ poppedPlaintext->dtor(poppedPlaintext);
+ }
+
+ mHandshakeCompleted = true;
+ }
+}
+
+void
+nsNSSSocketInfo::SetNegotiatedNPN(const char *value, uint32_t length)
+{
+ if (!value)
+ mNegotiatedNPN.Truncate();
+ else
+ mNegotiatedNPN.Assign(value, length);
+ mNPNCompleted = true;
+}
+
+NS_IMETHODIMP
+nsNSSSocketInfo::GetNegotiatedNPN(nsACString &aNegotiatedNPN)
+{
+ if (!mNPNCompleted)
+ return NS_ERROR_NOT_CONNECTED;
+
+ aNegotiatedNPN = mNegotiatedNPN;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNSSSocketInfo::JoinConnection(const nsACString & npnProtocol,
+ const nsACString & hostname,
+ int32_t port,
+ bool *_retval)
+{
+ *_retval = false;
+
+ // Different ports may not be joined together
+ if (port != GetPort())
+ return NS_OK;
+
+ // Make sure NPN has been completed and matches requested npnProtocol
+ if (!mNPNCompleted || !mNegotiatedNPN.Equals(npnProtocol))
+ return NS_OK;
+
+ // If this is the same hostname then the certicate status does not
+ // need to be considered. They are joinable.
+ if (GetHostName() && hostname.Equals(GetHostName())) {
+ *_retval = true;
+ return NS_OK;
+ }
+
+ // Before checking the server certificate we need to make sure the
+ // handshake has completed.
+ if (!mHandshakeCompleted || !SSLStatus() || !SSLStatus()->mServerCert)
+ return NS_OK;
+
+ // If the cert has error bits (e.g. it is untrusted) then do not join.
+ // The value of mHaveCertErrorBits is only reliable because we know that
+ // the handshake completed.
+ if (SSLStatus()->mHaveCertErrorBits)
+ return NS_OK;
+
+ // If the connection is using client certificates then do not join
+ // because the user decides on whether to send client certs to hosts on a
+ // per-domain basis.
+ if (mSentClientCert)
+ return NS_OK;
+
+ // Ensure that the server certificate covers the hostname that would
+ // like to join this connection
+
+ ScopedCERTCertificate nssCert;
+
+ nsCOMPtr<nsIX509Cert2> cert2 = do_QueryInterface(SSLStatus()->mServerCert);
+ if (cert2)
+ nssCert = cert2->GetCert();
+
+ if (!nssCert)
+ return NS_OK;
+
+ if (CERT_VerifyCertName(nssCert, PromiseFlatCString(hostname).get()) !=
+ SECSuccess)
+ return NS_OK;
+
+ // All tests pass - this is joinable
+ mJoined = true;
+ *_retval = true;
+ return NS_OK;
+}
+
+nsresult
+nsNSSSocketInfo::GetForSTARTTLS(bool* aForSTARTTLS)
+{
+ *aForSTARTTLS = mForSTARTTLS;
+ return NS_OK;
+}
+
+nsresult
+nsNSSSocketInfo::SetForSTARTTLS(bool aForSTARTTLS)
+{
+ mForSTARTTLS = aForSTARTTLS;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsNSSSocketInfo::ProxyStartSSL()
+{
+ return ActivateSSL();
+}
+
+NS_IMETHODIMP
+nsNSSSocketInfo::StartTLS()
+{
+ return ActivateSSL();
+}
+
+NS_IMETHODIMP
+nsNSSSocketInfo::SetNPNList(nsTArray<nsCString> &protocolArray)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+ if (!mFd)
+ return NS_ERROR_FAILURE;
+
+ // the npn list is a concatenated list of 8 bit byte strings.
+ nsCString npnList;
+
+ for (uint32_t index = 0; index < protocolArray.Length(); ++index) {
+ if (protocolArray[index].IsEmpty() ||
+ protocolArray[index].Length() > 255)
+ return NS_ERROR_ILLEGAL_VALUE;
+
+ npnList.Append(protocolArray[index].Length());
+ npnList.Append(protocolArray[index]);
+ }
+
+ if (SSL_SetNextProtoNego(
+ mFd,
+ reinterpret_cast<const unsigned char *>(npnList.get()),
+ npnList.Length()) != SECSuccess)
+ return NS_ERROR_FAILURE;
+
+ return NS_OK;
+}
+
+nsresult nsNSSSocketInfo::ActivateSSL()
+{
+ nsNSSShutDownPreventionLock locker;
+ if (isAlreadyShutDown())
+ return NS_ERROR_NOT_AVAILABLE;
+
+ if (SECSuccess != SSL_OptionSet(mFd, SSL_SECURITY, true))
+ return NS_ERROR_FAILURE;
+ if (SECSuccess != SSL_ResetHandshake(mFd, false))
+ return NS_ERROR_FAILURE;
+
+ mHandshakePending = true;
+
+ return NS_OK;
+}
+
+nsresult nsNSSSocketInfo::GetFileDescPtr(PRFileDesc** aFilePtr)
+{
+ *aFilePtr = mFd;
+ return NS_OK;
+}
+
+nsresult nsNSSSocketInfo::SetFileDescPtr(PRFileDesc* aFilePtr)
+{
+ mFd = aFilePtr;
+ return NS_OK;
+}
+
+#ifndef NSS_NO_LIBPKIX
+class PreviousCertRunnable : public SyncRunnableBase
+{
+public:
+ PreviousCertRunnable(nsIInterfaceRequestor * callbacks)
+ : mCallbacks(callbacks)
+ {
+ }
+
+ virtual void RunOnTargetThread()
+ {
+ nsCOMPtr<nsISecureBrowserUI> secureUI;
+ getSecureBrowserUI(mCallbacks, getter_AddRefs(secureUI));
+ nsCOMPtr<nsISSLStatusProvider> statusProvider = do_QueryInterface(secureUI);
+ if (statusProvider) {
+ nsCOMPtr<nsISSLStatus> status;
+ (void) statusProvider->GetSSLStatus(getter_AddRefs(status));
+ if (status) {
+ (void) status->GetServerCert(getter_AddRefs(mPreviousCert));
+ }
+ }
+ }
+
+ nsCOMPtr<nsIX509Cert> mPreviousCert; // out
+private:
+ nsCOMPtr<nsIInterfaceRequestor> mCallbacks; // in
+};
+#endif
+
+void nsNSSSocketInfo::GetPreviousCert(nsIX509Cert** _result)
+{
+ NS_ASSERTION(_result, "_result parameter to GetPreviousCert is null");
+ *_result = nullptr;
+
+#ifndef NSS_NO_LIBPKIX
+ RefPtr<PreviousCertRunnable> runnable(new PreviousCertRunnable(mCallbacks));
+ nsresult rv = runnable->DispatchToMainThreadAndWait();
+ NS_ASSERTION(NS_SUCCEEDED(rv), "runnable->DispatchToMainThreadAndWait() failed");
+ runnable->mPreviousCert.forget(_result);
+#endif
+}
+
+void
+nsNSSSocketInfo::SetCertVerificationWaiting()
+{
+ // mCertVerificationState may be before_cert_verification for the first
+ // handshake on the connection, or after_cert_verification for subsequent
+ // renegotiation handshakes.
+ NS_ASSERTION(mCertVerificationState != waiting_for_cert_verification,
+ "Invalid state transition to waiting_for_cert_verification");
+ mCertVerificationState = waiting_for_cert_verification;
+}
+
+// Be careful that SetCertVerificationResult does NOT get called while we are
+// processing a SSL callback function, because SSL_AuthCertificateComplete will
+// attempt to acquire locks that are already held by libssl when it calls
+// callbacks.
+void
+nsNSSSocketInfo::SetCertVerificationResult(PRErrorCode errorCode,
+ SSLErrorMessageType errorMessageType)
+{
+ NS_ASSERTION(mCertVerificationState == waiting_for_cert_verification,
+ "Invalid state transition to cert_verification_finished");
+
+ if (mFd) {
+ SECStatus rv = SSL_AuthCertificateComplete(mFd, errorCode);
+ // Only replace errorCode if there was originally no error
+ if (rv != SECSuccess && errorCode == 0) {
+ errorCode = PR_GetError();
+ errorMessageType = PlainErrorMessage;
+ if (errorCode == 0) {
+ NS_ERROR("SSL_AuthCertificateComplete didn't set error code");
+ errorCode = PR_INVALID_STATE_ERROR;
+ }
+ }
+ }
+
+ if (errorCode) {
+ SetCanceled(errorCode, errorMessageType);
+ }
+
+ if (mPlaintextBytesRead && !errorCode) {
+ Telemetry::Accumulate(Telemetry::SSL_BYTES_BEFORE_CERT_CALLBACK, mPlaintextBytesRead);
+ }
+
+ mCertVerificationState = after_cert_verification;
+}
+
+void nsNSSSocketInfo::SetHandshakeInProgress(bool aIsIn)
+{
+ mHandshakeInProgress = aIsIn;
+
+ if (mHandshakeInProgress && !mHandshakeStartTime)
+ {
+ mHandshakeStartTime = PR_IntervalNow();
+ }
+}
+
+void nsNSSSocketInfo::SetAllowTLSIntoleranceTimeout(bool aAllow)
+{
+ mAllowTLSIntoleranceTimeout = aAllow;
+}
+
+SharedSSLState& nsNSSSocketInfo::SharedState()
+{
+ return mSharedState;
+}
+
+bool nsNSSSocketInfo::HandshakeTimeout()
+{
+ if (!mAllowTLSIntoleranceTimeout)
+ return false;
+
+ if (!mHandshakeInProgress)
+ return false; // have not even sent client hello yet
+
+ if (mFirstServerHelloReceived)
+ return false;
+
+ // Now we know we are in the first handshake, and haven't received the
+ // ServerHello+Certificate sequence or the
+ // ServerHello+ChangeCipherSpec+Finished sequence.
+ //
+ // XXX: Bug 754356 - waiting to receive the Certificate or Finished messages
+ // may cause us to time out in cases where we shouldn't.
+
+ static const PRIntervalTime handshakeTimeoutInterval
+ = PR_SecondsToInterval(25);
+
+ PRIntervalTime now = PR_IntervalNow();
+ bool result = (now - mHandshakeStartTime) > handshakeTimeoutInterval;
+ return result;
+}
+
+void nsSSLIOLayerHelpers::Cleanup()
+{
+ if (mTLSIntolerantSites) {
+ delete mTLSIntolerantSites;
+ mTLSIntolerantSites = nullptr;
+ }
+
+ if (mTLSTolerantSites) {
+ delete mTLSTolerantSites;
+ mTLSTolerantSites = nullptr;
+ }
+
+ if (mRenegoUnrestrictedSites) {
+ delete mRenegoUnrestrictedSites;
+ mRenegoUnrestrictedSites = nullptr;
+ }
+
+ if (mutex) {
+ delete mutex;
+ mutex = nullptr;
+ }
+}
+
+static void
+nsHandleSSLError(nsNSSSocketInfo *socketInfo,
+ ::mozilla::psm::SSLErrorMessageType errtype,
+ PRErrorCode err)
+{
+ if (!NS_IsMainThread()) {
+ NS_ERROR("nsHandleSSLError called off the main thread");
+ return;
+ }
+
+ // SetCanceled is only called by the main thread or the socket transport
+ // thread. Whenever this function is called on the main thread, the SSL
+ // thread is blocked on it. So, no mutex is necessary for
+ // SetCanceled()/GetError*().
+ if (socketInfo->GetErrorCode()) {
+ // If the socket has been flagged as canceled,
+ // the code who did was responsible for setting the error code.
+ return;
+ }
+
+ nsresult rv;
+ NS_DEFINE_CID(nssComponentCID, NS_NSSCOMPONENT_CID);
+ nsCOMPtr<nsINSSComponent> nssComponent(do_GetService(nssComponentCID, &rv));
+ if (NS_FAILED(rv))
+ return;
+
+ nsXPIDLCString hostName;
+ socketInfo->GetHostName(getter_Copies(hostName));
+
+ int32_t port;
+ socketInfo->GetPort(&port);
+
+ // Try to get a nsISSLErrorListener implementation from the socket consumer.
+ nsCOMPtr<nsIInterfaceRequestor> cb;
+ socketInfo->GetNotificationCallbacks(getter_AddRefs(cb));
+ if (cb) {
+ nsCOMPtr<nsISSLErrorListener> sel = do_GetInterface(cb);
+ if (sel) {
+ nsIInterfaceRequestor *csi = static_cast<nsIInterfaceRequestor*>(socketInfo);
+ nsCString hostWithPortString = hostName;
+ hostWithPortString.AppendLiteral(":");
+ hostWithPortString.AppendInt(port);
+
+ bool suppressMessage = false; // obsolete, ignored
+ rv = sel->NotifySSLError(csi, err, hostWithPortString, &suppressMessage);
+ }
+ }
+
+ // We must cancel first, which sets the error code.
+ socketInfo->SetCanceled(err, PlainErrorMessage);
+ nsXPIDLString errorString;
+ socketInfo->GetErrorLogMessage(err, errtype, errorString);
+
+ if (!errorString.IsEmpty()) {
+ nsCOMPtr<nsIConsoleService> console;
+ console = do_GetService(NS_CONSOLESERVICE_CONTRACTID);
+ if (console) {
+ console->LogStringMessage(errorString.get());
+ }
+ }
+}
+
+namespace {
+
+enum Operation { reading, writing, not_reading_or_writing };
+
+int32_t checkHandshake(int32_t bytesTransfered, bool wasReading,
+ PRFileDesc* ssl_layer_fd,
+ nsNSSSocketInfo *socketInfo);
+
+nsNSSSocketInfo *
+getSocketInfoIfRunning(PRFileDesc * fd, Operation op,
+ const nsNSSShutDownPreventionLock & /*proofOfLock*/)
+{
+ if (!fd || !fd->lower || !fd->secret ||
+ fd->identity != nsSSLIOLayerHelpers::nsSSLIOLayerIdentity) {
+ NS_ERROR("bad file descriptor passed to getSocketInfoIfRunning");
+ PR_SetError(PR_BAD_DESCRIPTOR_ERROR, 0);
+ return nullptr;
+ }
+
+ nsNSSSocketInfo *socketInfo = (nsNSSSocketInfo*)fd->secret;
+
+ if (socketInfo->isAlreadyShutDown() || socketInfo->isPK11LoggedOut()) {
+ PR_SetError(PR_SOCKET_SHUTDOWN_ERROR, 0);
+ return nullptr;
+ }
+
+ if (socketInfo->GetErrorCode()) {
+ PRErrorCode err = socketInfo->GetErrorCode();
+ PR_SetError(err, 0);
+ if (op == reading || op == writing) {
+ // We must do TLS intolerance checks for reads and writes, for timeouts
+ // in particular.
+ (void) checkHandshake(-1, op == reading, fd, socketInfo);
+ }
+
+ // If we get here, it is probably because cert verification failed and this
+ // is the first I/O attempt since that failure.
+ return nullptr;
+ }
+
+ return socketInfo;
+}
+
+} // unnnamed namespace
+
+static PRStatus
+nsSSLIOLayerConnect(PRFileDesc* fd, const PRNetAddr* addr,
+ PRIntervalTime timeout)
+{
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] connecting SSL socket\n", (void*)fd));
+ nsNSSShutDownPreventionLock locker;
+ if (!getSocketInfoIfRunning(fd, not_reading_or_writing, locker))
+ return PR_FAILURE;
+
+ PRStatus status = fd->lower->methods->connect(fd->lower, addr, timeout);
+ if (status != PR_SUCCESS) {
+ PR_LOG(gPIPNSSLog, PR_LOG_ERROR, ("[%p] Lower layer connect error: %d\n",
+ (void*)fd, PR_GetError()));
+ return status;
+ }
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] Connect\n", (void*)fd));
+ return status;
+}
+
+void
+nsSSLIOLayerHelpers::getSiteKey(nsNSSSocketInfo *socketInfo, nsCSubstring &key)
+{
+ int32_t port;
+ socketInfo->GetPort(&port);
+
+ nsXPIDLCString host;
+ socketInfo->GetHostName(getter_Copies(host));
+
+ key = host + NS_LITERAL_CSTRING(":") + nsPrintfCString("%d", port);
+}
+
+// Call this function to report a site that is possibly TLS intolerant.
+// This function will return true, if the given socket is currently using TLS,
+// and it's allowed to retry. Retrying only makes sense if an older
+// protocol is enabled.
+bool
+nsSSLIOLayerHelpers::rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo)
+{
+ nsAutoCString key;
+ getSiteKey(socketInfo, key);
+
+ if (!socketInfo->IsTLSEnabled()) {
+ // We did not offer TLS but failed with an intolerant error using
+ // a different protocol. To give TLS a try on next connection attempt again
+ // drop this site from the list of intolerant sites. TLS failure might be
+ // caused only by a traffic congestion while the server is TLS tolerant.
+ removeIntolerantSite(key);
+ return false;
+ }
+
+ if (socketInfo->IsSSL3Enabled()) {
+ // Add this site to the list of TLS intolerant sites.
+ addIntolerantSite(key);
+ }
+ else {
+ return false; // doesn't make sense to retry
+ }
+
+ return socketInfo->IsTLSEnabled();
+}
+
+void
+nsSSLIOLayerHelpers::rememberTolerantSite(nsNSSSocketInfo *socketInfo)
+{
+ if (!socketInfo->IsTLSEnabled())
+ return;
+
+ nsAutoCString key;
+ getSiteKey(socketInfo, key);
+
+ MutexAutoLock lock(*mutex);
+ nsSSLIOLayerHelpers::mTLSTolerantSites->PutEntry(key);
+}
+
+bool nsSSLIOLayerHelpers::nsSSLIOLayerInitialized = false;
+PRDescIdentity nsSSLIOLayerHelpers::nsSSLIOLayerIdentity;
+PRDescIdentity nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity;
+PRIOMethods nsSSLIOLayerHelpers::nsSSLIOLayerMethods;
+PRIOMethods nsSSLIOLayerHelpers::nsSSLPlaintextLayerMethods;
+
+static PRStatus
+nsSSLIOLayerClose(PRFileDesc *fd)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (!fd)
+ return PR_FAILURE;
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] Shutting down socket\n", (void*)fd));
+
+ nsNSSSocketInfo *socketInfo = (nsNSSSocketInfo*)fd->secret;
+ NS_ASSERTION(socketInfo,"nsNSSSocketInfo was null for an fd");
+
+ return socketInfo->CloseSocketAndDestroy(locker);
+}
+
+PRStatus nsNSSSocketInfo::CloseSocketAndDestroy(
+ const nsNSSShutDownPreventionLock & /*proofOfLock*/)
+{
+ nsNSSShutDownList::trackSSLSocketClose();
+
+ PRFileDesc* popped = PR_PopIOLayer(mFd, PR_TOP_IO_LAYER);
+ NS_ASSERTION(popped &&
+ popped->identity == nsSSLIOLayerHelpers::nsSSLIOLayerIdentity,
+ "SSL Layer not on top of stack");
+
+ // The plain text layer is not always present - so its not a fatal error
+ // if it cannot be removed
+ PRFileDesc* poppedPlaintext =
+ PR_GetIdentitiesLayer(mFd, nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity);
+ if (poppedPlaintext) {
+ PR_PopIOLayer(mFd, nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity);
+ poppedPlaintext->dtor(poppedPlaintext);
+ }
+
+ PRStatus status = mFd->methods->close(mFd);
+
+ // the nsNSSSocketInfo instance can out-live the connection, so we need some
+ // indication that the connection has been closed. mFd == nullptr is that
+ // indication. This is needed, for example, when the connection is closed
+ // before we have finished validating the server's certificate.
+ mFd = nullptr;
+
+ if (status != PR_SUCCESS) return status;
+
+ popped->identity = PR_INVALID_IO_LAYER;
+ NS_RELEASE_THIS();
+ popped->dtor(popped);
+
+ return PR_SUCCESS;
+}
+
+#if defined(DEBUG_SSL_VERBOSE) && defined(DUMP_BUFFER)
+/* Dumps a (potentially binary) buffer using SSM_DEBUG.
+ (We could have used the version in ssltrace.c, but that's
+ specifically tailored to SSLTRACE. Sigh. */
+#define DUMPBUF_LINESIZE 24
+static void
+nsDumpBuffer(unsigned char *buf, int len)
+{
+ char hexbuf[DUMPBUF_LINESIZE*3+1];
+ char chrbuf[DUMPBUF_LINESIZE+1];
+ static const char *hex = "0123456789abcdef";
+ int i = 0, l = 0;
+ char ch, *c, *h;
+ if (len == 0)
+ return;
+ hexbuf[DUMPBUF_LINESIZE*3] = '\0';
+ chrbuf[DUMPBUF_LINESIZE] = '\0';
+ (void) memset(hexbuf, 0x20, DUMPBUF_LINESIZE*3);
+ (void) memset(chrbuf, 0x20, DUMPBUF_LINESIZE);
+ h = hexbuf;
+ c = chrbuf;
+
+ while (i < len)
+ {
+ ch = buf[i];
+
+ if (l == DUMPBUF_LINESIZE)
+ {
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("%s%s\n", hexbuf, chrbuf));
+ (void) memset(hexbuf, 0x20, DUMPBUF_LINESIZE*3);
+ (void) memset(chrbuf, 0x20, DUMPBUF_LINESIZE);
+ h = hexbuf;
+ c = chrbuf;
+ l = 0;
+ }
+
+ /* Convert a character to hex. */
+ *h++ = hex[(ch >> 4) & 0xf];
+ *h++ = hex[ch & 0xf];
+ h++;
+
+ /* Put the character (if it's printable) into the character buffer. */
+ if ((ch >= 0x20) && (ch <= 0x7e))
+ *c++ = ch;
+ else
+ *c++ = '.';
+ i++; l++;
+ }
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("%s%s\n", hexbuf, chrbuf));
+}
+
+#define DEBUG_DUMP_BUFFER(buf,len) nsDumpBuffer(buf,len)
+#else
+#define DEBUG_DUMP_BUFFER(buf,len)
+#endif
+
+static bool
+isNonSSLErrorThatWeAllowToRetry(int32_t err, bool withInitialCleartext)
+{
+ switch (err)
+ {
+ case PR_CONNECT_RESET_ERROR:
+ if (!withInitialCleartext)
+ return true;
+ break;
+
+ case PR_END_OF_FILE_ERROR:
+ return true;
+ }
+
+ return false;
+}
+
+static bool
+isTLSIntoleranceError(int32_t err, bool withInitialCleartext)
+{
+ // This function is supposed to decide, which error codes should
+ // be used to conclude server is TLS intolerant.
+ // Note this only happens during the initial SSL handshake.
+ //
+ // When not using a proxy we'll see a connection reset error.
+ // When using a proxy, we'll see an end of file error.
+ // In addition check for some error codes where it is reasonable
+ // to retry without TLS.
+
+ if (isNonSSLErrorThatWeAllowToRetry(err, withInitialCleartext))
+ return true;
+
+ switch (err)
+ {
+ case SSL_ERROR_BAD_MAC_ALERT:
+ case SSL_ERROR_BAD_MAC_READ:
+ case SSL_ERROR_HANDSHAKE_FAILURE_ALERT:
+ case SSL_ERROR_HANDSHAKE_UNEXPECTED_ALERT:
+ case SSL_ERROR_CLIENT_KEY_EXCHANGE_FAILURE:
+ case SSL_ERROR_ILLEGAL_PARAMETER_ALERT:
+ case SSL_ERROR_NO_CYPHER_OVERLAP:
+ case SSL_ERROR_BAD_SERVER:
+ case SSL_ERROR_BAD_BLOCK_PADDING:
+ case SSL_ERROR_UNSUPPORTED_VERSION:
+ case SSL_ERROR_PROTOCOL_VERSION_ALERT:
+ case SSL_ERROR_RX_MALFORMED_FINISHED:
+ case SSL_ERROR_BAD_HANDSHAKE_HASH_VALUE:
+ case SSL_ERROR_DECODE_ERROR_ALERT:
+ case SSL_ERROR_RX_UNKNOWN_ALERT:
+ return true;
+ }
+
+ return false;
+}
+
+class SSLErrorRunnable : public SyncRunnableBase
+{
+ public:
+ SSLErrorRunnable(nsNSSSocketInfo * infoObject,
+ ::mozilla::psm::SSLErrorMessageType errtype,
+ PRErrorCode errorCode)
+ : mInfoObject(infoObject)
+ , mErrType(errtype)
+ , mErrorCode(errorCode)
+ {
+ }
+
+ virtual void RunOnTargetThread()
+ {
+ nsHandleSSLError(mInfoObject, mErrType, mErrorCode);
+ }
+
+ RefPtr<nsNSSSocketInfo> mInfoObject;
+ ::mozilla::psm::SSLErrorMessageType mErrType;
+ const PRErrorCode mErrorCode;
+};
+
+namespace {
+
+int32_t checkHandshake(int32_t bytesTransfered, bool wasReading,
+ PRFileDesc* ssl_layer_fd,
+ nsNSSSocketInfo *socketInfo)
+{
+ // This is where we work around all of those SSL servers that don't
+ // conform to the SSL spec and shutdown a connection when we request
+ // SSL v3.1 (aka TLS). The spec says the client says what version
+ // of the protocol we're willing to perform, in our case SSL v3.1
+ // In its response, the server says which version it wants to perform.
+ // Many servers out there only know how to do v3.0. Next, we're supposed
+ // to send back the version of the protocol we requested (ie v3.1). At
+ // this point many servers's implementations are broken and they shut
+ // down the connection when they don't see the version they sent back.
+ // This is supposed to prevent a man in the middle from forcing one
+ // side to dumb down to a lower level of the protocol. Unfortunately,
+ // there are enough broken servers out there that such a gross work-around
+ // is necessary. :(
+
+ // Additional comment added in August 2006:
+ // When we begun to use TLS hello extensions, we encountered a new class of
+ // broken server, which simply stall for a very long time.
+ // We would like to shorten the timeout, but limit this shorter timeout
+ // to the handshake phase.
+ // When we arrive here for the first time (for a given socket),
+ // we know the connection is established, and the application code
+ // tried the first read or write. This triggers the beginning of the
+ // SSL handshake phase at the SSL FD level.
+ // We'll make a note of the current time,
+ // and use this to measure the elapsed time since handshake begin.
+
+ // Do NOT assume TLS intolerance on a closed connection after bad cert ui was shown.
+ // Simply retry.
+ // This depends on the fact that Cert UI will not be shown again,
+ // should the user override the bad cert.
+
+ bool handleHandshakeResultNow;
+ socketInfo->GetHandshakePending(&handleHandshakeResultNow);
+
+ bool wantRetry = false;
+
+ if (0 > bytesTransfered) {
+ int32_t err = PR_GetError();
+
+ if (handleHandshakeResultNow) {
+ if (PR_WOULD_BLOCK_ERROR == err) {
+ socketInfo->SetHandshakeInProgress(true);
+ return bytesTransfered;
+ }
+
+ if (!wantRetry // no decision yet
+ && isTLSIntoleranceError(err, socketInfo->GetHasCleartextPhase()))
+ {
+ nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers();
+ wantRetry = helpers.rememberPossibleTLSProblemSite(socketInfo);
+ }
+ }
+
+ // This is the common place where we trigger non-cert-errors on a SSL
+ // socket. This might be reached at any time of the connection.
+ //
+ // The socketInfo->GetErrorCode() check is here to ensure we don't try to
+ // do the synchronous dispatch to the main thread unnecessarily after we've
+ // already handled a certificate error. (SSLErrorRunnable calls
+ // nsHandleSSLError, which has logic to avoid replacing the error message,
+ // so without the !socketInfo->GetErrorCode(), it would just be an
+ // expensive no-op.)
+ if (!wantRetry && (IS_SSL_ERROR(err) || IS_SEC_ERROR(err)) &&
+ !socketInfo->GetErrorCode()) {
+ RefPtr<SyncRunnableBase> runnable(new SSLErrorRunnable(socketInfo,
+ PlainErrorMessage,
+ err));
+ (void) runnable->DispatchToMainThreadAndWait();
+ }
+ }
+ else if (wasReading && 0 == bytesTransfered) // zero bytes on reading, socket closed
+ {
+ if (handleHandshakeResultNow)
+ {
+ if (!wantRetry // no decision yet
+ && !socketInfo->GetHasCleartextPhase()) // mirror PR_CONNECT_RESET_ERROR treament
+ {
+ nsSSLIOLayerHelpers& helpers = socketInfo->SharedState().IOLayerHelpers();
+ wantRetry = helpers.rememberPossibleTLSProblemSite(socketInfo);
+ }
+ }
+ }
+
+ if (wantRetry) {
+ // We want to cause the network layer to retry the connection.
+ PR_SetError(PR_CONNECT_RESET_ERROR, 0);
+ if (wasReading)
+ bytesTransfered = -1;
+ }
+
+ // TLS intolerant servers only cause the first transfer to fail, so let's
+ // set the HandshakePending attribute to false so that we don't try the logic
+ // above again in a subsequent transfer.
+ if (handleHandshakeResultNow) {
+ socketInfo->SetHandshakePending(false);
+ socketInfo->SetHandshakeInProgress(false);
+ }
+
+ return bytesTransfered;
+}
+
+}
+
+static int16_t
+nsSSLIOLayerPoll(PRFileDesc * fd, int16_t in_flags, int16_t *out_flags)
+{
+ nsNSSShutDownPreventionLock locker;
+
+ if (!out_flags)
+ {
+ NS_WARNING("nsSSLIOLayerPoll called with null out_flags");
+ return 0;
+ }
+
+ *out_flags = 0;
+
+ nsNSSSocketInfo * socketInfo =
+ getSocketInfoIfRunning(fd, not_reading_or_writing, locker);
+
+ if (!socketInfo) {
+ // If we get here, it is probably because certificate validation failed
+ // and this is the first I/O operation after the failure.
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
+ ("[%p] polling SSL socket right after certificate verification failed "
+ "or NSS shutdown or SDR logout %d\n",
+ fd, (int) in_flags));
+
+ NS_ASSERTION(in_flags & PR_POLL_EXCEPT,
+ "caller did not poll for EXCEPT (canceled)");
+ // Since this poll method cannot return errors, we want the caller to call
+ // PR_Send/PR_Recv right away to get the error, so we tell that we are
+ // ready for whatever I/O they are asking for. (See getSocketInfoIfRunning).
+ *out_flags = in_flags | PR_POLL_EXCEPT; // see also bug 480619
+ return in_flags;
+ }
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
+ (socketInfo->IsWaitingForCertVerification()
+ ? "[%p] polling SSL socket during certificate verification using lower %d\n"
+ : "[%p] poll SSL socket using lower %d\n",
+ fd, (int) in_flags));
+
+ // See comments in HandshakeTimeout before moving and/or changing this block
+ if (socketInfo->HandshakeTimeout()) {
+ NS_WARNING("SSL handshake timed out");
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] handshake timed out\n", fd));
+ NS_ASSERTION(in_flags & PR_POLL_EXCEPT,
+ "caller did not poll for EXCEPT (handshake timeout)");
+ *out_flags = in_flags | PR_POLL_EXCEPT;
+ socketInfo->SetCanceled(PR_CONNECT_RESET_ERROR, PlainErrorMessage);
+ return in_flags;
+ }
+
+ // We want the handshake to continue during certificate validation, so we
+ // don't need to do anything special here. libssl automatically blocks when
+ // it reaches any point that would be unsafe to send/receive something before
+ // cert validation is complete.
+ int16_t result = fd->lower->methods->poll(fd->lower, in_flags, out_flags);
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] poll SSL socket returned %d\n",
+ (void*)fd, (int) result));
+ return result;
+}
+
+nsSSLIOLayerHelpers::nsSSLIOLayerHelpers()
+: mutex(nullptr)
+, mTLSIntolerantSites(nullptr)
+, mTLSTolerantSites(nullptr)
+, mRenegoUnrestrictedSites(nullptr)
+, mTreatUnsafeNegotiationAsBroken(false)
+, mWarnLevelMissingRFC5746(1)
+{
+}
+
+static int _PSM_InvalidInt(void)
+{
+ PR_ASSERT(!"I/O method is invalid");
+ PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+ return -1;
+}
+
+static int64_t _PSM_InvalidInt64(void)
+{
+ PR_ASSERT(!"I/O method is invalid");
+ PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+ return -1;
+}
+
+static PRStatus _PSM_InvalidStatus(void)
+{
+ PR_ASSERT(!"I/O method is invalid");
+ PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+ return PR_FAILURE;
+}
+
+static PRFileDesc *_PSM_InvalidDesc(void)
+{
+ PR_ASSERT(!"I/O method is invalid");
+ PR_SetError(PR_INVALID_METHOD_ERROR, 0);
+ return nullptr;
+}
+
+static PRStatus PSMGetsockname(PRFileDesc *fd, PRNetAddr *addr)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (!getSocketInfoIfRunning(fd, not_reading_or_writing, locker))
+ return PR_FAILURE;
+
+ return fd->lower->methods->getsockname(fd->lower, addr);
+}
+
+static PRStatus PSMGetpeername(PRFileDesc *fd, PRNetAddr *addr)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (!getSocketInfoIfRunning(fd, not_reading_or_writing, locker))
+ return PR_FAILURE;
+
+ return fd->lower->methods->getpeername(fd->lower, addr);
+}
+
+static PRStatus PSMGetsocketoption(PRFileDesc *fd, PRSocketOptionData *data)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (!getSocketInfoIfRunning(fd, not_reading_or_writing, locker))
+ return PR_FAILURE;
+
+ return fd->lower->methods->getsocketoption(fd, data);
+}
+
+static PRStatus PSMSetsocketoption(PRFileDesc *fd,
+ const PRSocketOptionData *data)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (!getSocketInfoIfRunning(fd, not_reading_or_writing, locker))
+ return PR_FAILURE;
+
+ return fd->lower->methods->setsocketoption(fd, data);
+}
+
+static int32_t PSMRecv(PRFileDesc *fd, void *buf, int32_t amount,
+ int flags, PRIntervalTime timeout)
+{
+ nsNSSShutDownPreventionLock locker;
+ nsNSSSocketInfo *socketInfo = getSocketInfoIfRunning(fd, reading, locker);
+ if (!socketInfo)
+ return -1;
+
+ if (flags != PR_MSG_PEEK && flags != 0) {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return -1;
+ }
+
+ int32_t bytesRead = fd->lower->methods->recv(fd->lower, buf, amount, flags,
+ timeout);
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] read %d bytes\n", (void*)fd, bytesRead));
+
+#ifdef DEBUG_SSL_VERBOSE
+ DEBUG_DUMP_BUFFER((unsigned char*)buf, bytesRead);
+#endif
+
+ return checkHandshake(bytesRead, true, fd, socketInfo);
+}
+
+static int32_t PSMSend(PRFileDesc *fd, const void *buf, int32_t amount,
+ int flags, PRIntervalTime timeout)
+{
+ nsNSSShutDownPreventionLock locker;
+ nsNSSSocketInfo *socketInfo = getSocketInfoIfRunning(fd, writing, locker);
+ if (!socketInfo)
+ return -1;
+
+ if (flags != 0) {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return -1;
+ }
+
+#ifdef DEBUG_SSL_VERBOSE
+ DEBUG_DUMP_BUFFER((unsigned char*)buf, amount);
+#endif
+
+ int32_t bytesWritten = fd->lower->methods->send(fd->lower, buf, amount,
+ flags, timeout);
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] wrote %d bytes\n",
+ fd, bytesWritten));
+
+ return checkHandshake(bytesWritten, false, fd, socketInfo);
+}
+
+static int32_t
+nsSSLIOLayerRead(PRFileDesc* fd, void* buf, int32_t amount)
+{
+ return PSMRecv(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);
+}
+
+static int32_t
+nsSSLIOLayerWrite(PRFileDesc* fd, const void* buf, int32_t amount)
+{
+ return PSMSend(fd, buf, amount, 0, PR_INTERVAL_NO_TIMEOUT);
+}
+
+static PRStatus PSMConnectcontinue(PRFileDesc *fd, int16_t out_flags)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (!getSocketInfoIfRunning(fd, not_reading_or_writing, locker)) {
+ return PR_FAILURE;
+ }
+
+ return fd->lower->methods->connectcontinue(fd, out_flags);
+}
+
+static int PSMAvailable(void)
+{
+ // This is called through PR_Available(), but is not implemented in PSM
+ PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+ return -1;
+}
+
+static int64_t PSMAvailable64(void)
+{
+ // This is called through PR_Available(), but is not implemented in PSM
+ PR_SetError(PR_NOT_IMPLEMENTED_ERROR, 0);
+ return -1;
+}
+
+namespace {
+class PrefObserver : public nsIObserver {
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+ PrefObserver(nsSSLIOLayerHelpers* aOwner) : mOwner(aOwner) {}
+ virtual ~PrefObserver() {}
+private:
+ nsSSLIOLayerHelpers* mOwner;
+};
+} // namespace anonymous
+
+NS_IMPL_THREADSAFE_ISUPPORTS1(PrefObserver, nsIObserver)
+
+NS_IMETHODIMP
+PrefObserver::Observe(nsISupports *aSubject, const char *aTopic,
+ const PRUnichar *someData)
+{
+ if (nsCRT::strcmp(aTopic, NS_PREFBRANCH_PREFCHANGE_TOPIC_ID) == 0) {
+ NS_ConvertUTF16toUTF8 prefName(someData);
+
+ if (prefName.Equals("security.ssl.renego_unrestricted_hosts")) {
+ nsCString unrestricted_hosts;
+ Preferences::GetCString("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts);
+ if (!unrestricted_hosts.IsEmpty()) {
+ mOwner->setRenegoUnrestrictedSites(unrestricted_hosts);
+ }
+ } else if (prefName.Equals("security.ssl.treat_unsafe_negotiation_as_broken")) {
+ bool enabled;
+ Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", &enabled);
+ mOwner->setTreatUnsafeNegotiationAsBroken(enabled);
+ } else if (prefName.Equals("security.ssl.warn_missing_rfc5746")) {
+ int32_t warnLevel = 1;
+ Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel);
+ mOwner->setWarnLevelMissingRFC5746(warnLevel);
+ }
+ }
+ return NS_OK;
+}
+
+static int32_t PlaintextRecv(PRFileDesc *fd, void *buf, int32_t amount,
+ int flags, PRIntervalTime timeout)
+{
+ // The shutdownlocker is not needed here because it will already be
+ // held higher in the stack
+ nsNSSSocketInfo *socketInfo = nullptr;
+
+ int32_t bytesRead = fd->lower->methods->recv(fd->lower, buf, amount, flags,
+ timeout);
+ if (fd->identity == nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity)
+ socketInfo = (nsNSSSocketInfo*)fd->secret;
+
+ if ((bytesRead > 0) && socketInfo)
+ socketInfo->AddPlaintextBytesRead(bytesRead);
+ return bytesRead;
+}
+
+nsSSLIOLayerHelpers::~nsSSLIOLayerHelpers()
+{
+ Preferences::RemoveObserver(mPrefObserver, "security.ssl.renego_unrestricted_hosts");
+ Preferences::RemoveObserver(mPrefObserver, "security.ssl.treat_unsafe_negotiation_as_broken");
+ Preferences::RemoveObserver(mPrefObserver, "security.ssl.warn_missing_rfc5746");
+}
+
+nsresult nsSSLIOLayerHelpers::Init()
+{
+ if (!nsSSLIOLayerInitialized) {
+ nsSSLIOLayerInitialized = true;
+ nsSSLIOLayerIdentity = PR_GetUniqueIdentity("NSS layer");
+ nsSSLIOLayerMethods = *PR_GetDefaultIOMethods();
+
+ nsSSLIOLayerMethods.available = (PRAvailableFN)PSMAvailable;
+ nsSSLIOLayerMethods.available64 = (PRAvailable64FN)PSMAvailable64;
+ nsSSLIOLayerMethods.fsync = (PRFsyncFN)_PSM_InvalidStatus;
+ nsSSLIOLayerMethods.seek = (PRSeekFN)_PSM_InvalidInt;
+ nsSSLIOLayerMethods.seek64 = (PRSeek64FN)_PSM_InvalidInt64;
+ nsSSLIOLayerMethods.fileInfo = (PRFileInfoFN)_PSM_InvalidStatus;
+ nsSSLIOLayerMethods.fileInfo64 = (PRFileInfo64FN)_PSM_InvalidStatus;
+ nsSSLIOLayerMethods.writev = (PRWritevFN)_PSM_InvalidInt;
+ nsSSLIOLayerMethods.accept = (PRAcceptFN)_PSM_InvalidDesc;
+ nsSSLIOLayerMethods.bind = (PRBindFN)_PSM_InvalidStatus;
+ nsSSLIOLayerMethods.listen = (PRListenFN)_PSM_InvalidStatus;
+ nsSSLIOLayerMethods.shutdown = (PRShutdownFN)_PSM_InvalidStatus;
+ nsSSLIOLayerMethods.recvfrom = (PRRecvfromFN)_PSM_InvalidInt;
+ nsSSLIOLayerMethods.sendto = (PRSendtoFN)_PSM_InvalidInt;
+ nsSSLIOLayerMethods.acceptread = (PRAcceptreadFN)_PSM_InvalidInt;
+ nsSSLIOLayerMethods.transmitfile = (PRTransmitfileFN)_PSM_InvalidInt;
+ nsSSLIOLayerMethods.sendfile = (PRSendfileFN)_PSM_InvalidInt;
+
+ nsSSLIOLayerMethods.getsockname = PSMGetsockname;
+ nsSSLIOLayerMethods.getpeername = PSMGetpeername;
+ nsSSLIOLayerMethods.getsocketoption = PSMGetsocketoption;
+ nsSSLIOLayerMethods.setsocketoption = PSMSetsocketoption;
+ nsSSLIOLayerMethods.recv = PSMRecv;
+ nsSSLIOLayerMethods.send = PSMSend;
+ nsSSLIOLayerMethods.connectcontinue = PSMConnectcontinue;
+
+ nsSSLIOLayerMethods.connect = nsSSLIOLayerConnect;
+ nsSSLIOLayerMethods.close = nsSSLIOLayerClose;
+ nsSSLIOLayerMethods.write = nsSSLIOLayerWrite;
+ nsSSLIOLayerMethods.read = nsSSLIOLayerRead;
+ nsSSLIOLayerMethods.poll = nsSSLIOLayerPoll;
+
+ nsSSLPlaintextLayerIdentity = PR_GetUniqueIdentity("Plaintxext PSM layer");
+ nsSSLPlaintextLayerMethods = *PR_GetDefaultIOMethods();
+ nsSSLPlaintextLayerMethods.recv = PlaintextRecv;
+ }
+
+ mutex = new Mutex("nsSSLIOLayerHelpers.mutex");
+
+ mTLSIntolerantSites = new nsTHashtable<nsCStringHashKey>();
+ mTLSIntolerantSites->Init(1);
+
+ mTLSTolerantSites = new nsTHashtable<nsCStringHashKey>();
+ // Initialize the tolerant site hashtable to 16 items at the start seems
+ // reasonable as most servers are TLS tolerant. We just want to lower
+ // the rate of hashtable array reallocation.
+ mTLSTolerantSites->Init(16);
+
+ mRenegoUnrestrictedSites = new nsTHashtable<nsCStringHashKey>();
+ mRenegoUnrestrictedSites->Init(1);
+
+ nsCString unrestricted_hosts;
+ Preferences::GetCString("security.ssl.renego_unrestricted_hosts", &unrestricted_hosts);
+ if (!unrestricted_hosts.IsEmpty()) {
+ setRenegoUnrestrictedSites(unrestricted_hosts);
+ }
+
+ bool enabled = false;
+ Preferences::GetBool("security.ssl.treat_unsafe_negotiation_as_broken", &enabled);
+ setTreatUnsafeNegotiationAsBroken(enabled);
+
+ int32_t warnLevel = 1;
+ Preferences::GetInt("security.ssl.warn_missing_rfc5746", &warnLevel);
+ setWarnLevelMissingRFC5746(warnLevel);
+
+ mPrefObserver = new PrefObserver(this);
+ Preferences::AddStrongObserver(mPrefObserver,
+ "security.ssl.renego_unrestricted_hosts");
+ Preferences::AddStrongObserver(mPrefObserver,
+ "security.ssl.treat_unsafe_negotiation_as_broken");
+ Preferences::AddStrongObserver(mPrefObserver,
+ "security.ssl.warn_missing_rfc5746");
+
+ return NS_OK;
+}
+
+void nsSSLIOLayerHelpers::clearStoredData()
+{
+ mRenegoUnrestrictedSites->Clear();
+ mTLSTolerantSites->Clear();
+ mTLSIntolerantSites->Clear();
+}
+
+void nsSSLIOLayerHelpers::addIntolerantSite(const nsCString &str)
+{
+ MutexAutoLock lock(*mutex);
+ // Remember intolerant site only if it is not known as tolerant
+ if (!mTLSTolerantSites->Contains(str))
+ mTLSIntolerantSites->PutEntry(str);
+}
+
+void nsSSLIOLayerHelpers::removeIntolerantSite(const nsCString &str)
+{
+ MutexAutoLock lock(*mutex);
+ mTLSIntolerantSites->RemoveEntry(str);
+}
+
+bool nsSSLIOLayerHelpers::isKnownAsIntolerantSite(const nsCString &str)
+{
+ MutexAutoLock lock(*mutex);
+ return mTLSIntolerantSites->Contains(str);
+}
+
+void nsSSLIOLayerHelpers::setRenegoUnrestrictedSites(const nsCString &str)
+{
+ MutexAutoLock lock(*mutex);
+
+ if (mRenegoUnrestrictedSites) {
+ delete mRenegoUnrestrictedSites;
+ mRenegoUnrestrictedSites = nullptr;
+ }
+
+ mRenegoUnrestrictedSites = new nsTHashtable<nsCStringHashKey>();
+ if (!mRenegoUnrestrictedSites)
+ return;
+
+ mRenegoUnrestrictedSites->Init(1);
+
+ nsCCharSeparatedTokenizer toker(str, ',');
+
+ while (toker.hasMoreTokens()) {
+ const nsCSubstring &host = toker.nextToken();
+ if (!host.IsEmpty()) {
+ mRenegoUnrestrictedSites->PutEntry(host);
+ }
+ }
+}
+
+bool nsSSLIOLayerHelpers::isRenegoUnrestrictedSite(const nsCString &str)
+{
+ MutexAutoLock lock(*mutex);
+ return mRenegoUnrestrictedSites->Contains(str);
+}
+
+void nsSSLIOLayerHelpers::setTreatUnsafeNegotiationAsBroken(bool broken)
+{
+ MutexAutoLock lock(*mutex);
+ mTreatUnsafeNegotiationAsBroken = broken;
+}
+
+bool nsSSLIOLayerHelpers::treatUnsafeNegotiationAsBroken()
+{
+ MutexAutoLock lock(*mutex);
+ return mTreatUnsafeNegotiationAsBroken;
+}
+
+void nsSSLIOLayerHelpers::setWarnLevelMissingRFC5746(int32_t level)
+{
+ MutexAutoLock lock(*mutex);
+ mWarnLevelMissingRFC5746 = level;
+}
+
+int32_t nsSSLIOLayerHelpers::getWarnLevelMissingRFC5746()
+{
+ MutexAutoLock lock(*mutex);
+ return mWarnLevelMissingRFC5746;
+}
+
+nsresult
+nsSSLIOLayerNewSocket(int32_t family,
+ const char *host,
+ int32_t port,
+ const char *proxyHost,
+ int32_t proxyPort,
+ PRFileDesc **fd,
+ nsISupports** info,
+ bool forSTARTTLS,
+ uint32_t flags)
+{
+
+ PRFileDesc* sock = PR_OpenTCPSocket(family);
+ if (!sock) return NS_ERROR_OUT_OF_MEMORY;
+
+ nsresult rv = nsSSLIOLayerAddToSocket(family, host, port, proxyHost, proxyPort,
+ sock, info, forSTARTTLS, flags);
+ if (NS_FAILED(rv)) {
+ PR_Close(sock);
+ return rv;
+ }
+
+ *fd = sock;
+ return NS_OK;
+}
+
+/*
+ * Function: SECStatus nsConvertCANamesToStrings()
+ * Purpose: creates CA names strings from (CERTDistNames* caNames)
+ *
+ * Arguments and return values
+ * - arena: arena to allocate strings on
+ * - caNameStrings: filled with CA names strings on return
+ * - caNames: CERTDistNames to extract strings from
+ * - return: SECSuccess if successful; error code otherwise
+ *
+ * Note: copied in its entirety from Nova code
+ */
+SECStatus nsConvertCANamesToStrings(PLArenaPool* arena, char** caNameStrings,
+ CERTDistNames* caNames)
+{
+ SECItem* dername;
+ SECStatus rv;
+ int headerlen;
+ uint32_t contentlen;
+ SECItem newitem;
+ int n;
+ char* namestring;
+
+ for (n = 0; n < caNames->nnames; n++) {
+ newitem.data = nullptr;
+ dername = &caNames->names[n];
+
+ rv = DER_Lengths(dername, &headerlen, &contentlen);
+
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ if (headerlen + contentlen != dername->len) {
+ /* This must be from an enterprise 2.x server, which sent
+ * incorrectly formatted der without the outer wrapper of
+ * type and length. Fix it up by adding the top level
+ * header.
+ */
+ if (dername->len <= 127) {
+ newitem.data = (unsigned char *) PR_Malloc(dername->len + 2);
+ if (!newitem.data) {
+ goto loser;
+ }
+ newitem.data[0] = (unsigned char)0x30;
+ newitem.data[1] = (unsigned char)dername->len;
+ (void)memcpy(&newitem.data[2], dername->data, dername->len);
+ }
+ else if (dername->len <= 255) {
+ newitem.data = (unsigned char *) PR_Malloc(dername->len + 3);
+ if (!newitem.data) {
+ goto loser;
+ }
+ newitem.data[0] = (unsigned char)0x30;
+ newitem.data[1] = (unsigned char)0x81;
+ newitem.data[2] = (unsigned char)dername->len;
+ (void)memcpy(&newitem.data[3], dername->data, dername->len);
+ }
+ else {
+ /* greater than 256, better be less than 64k */
+ newitem.data = (unsigned char *) PR_Malloc(dername->len + 4);
+ if (!newitem.data) {
+ goto loser;
+ }
+ newitem.data[0] = (unsigned char)0x30;
+ newitem.data[1] = (unsigned char)0x82;
+ newitem.data[2] = (unsigned char)((dername->len >> 8) & 0xff);
+ newitem.data[3] = (unsigned char)(dername->len & 0xff);
+ memcpy(&newitem.data[4], dername->data, dername->len);
+ }
+ dername = &newitem;
+ }
+
+ namestring = CERT_DerNameToAscii(dername);
+ if (!namestring) {
+ /* XXX - keep going until we fail to convert the name */
+ caNameStrings[n] = const_cast<char*>("");
+ }
+ else {
+ caNameStrings[n] = PORT_ArenaStrdup(arena, namestring);
+ PR_Free(namestring);
+ if (!caNameStrings[n]) {
+ goto loser;
+ }
+ }
+
+ if (newitem.data) {
+ PR_Free(newitem.data);
+ }
+ }
+
+ return SECSuccess;
+loser:
+ if (newitem.data) {
+ PR_Free(newitem.data);
+ }
+ return SECFailure;
+}
+
+/*
+ * structs and ASN1 templates for the limited scope-of-use extension
+ *
+ * CertificateScopeEntry ::= SEQUENCE {
+ * name GeneralName, -- pattern, as for NameConstraints
+ * portNumber INTEGER OPTIONAL }
+ *
+ * CertificateScopeOfUse ::= SEQUENCE OF CertificateScopeEntry
+ */
+/*
+ * CERTCertificateScopeEntry: struct for scope entry that can be consumed by
+ * the code
+ * certCertificateScopeOfUse: struct that represents the decoded extension data
+ */
+typedef struct {
+ SECItem derConstraint;
+ SECItem derPort;
+ CERTGeneralName* constraint; /* decoded constraint */
+ int port; /* decoded port number */
+} CERTCertificateScopeEntry;
+
+typedef struct {
+ CERTCertificateScopeEntry** entries;
+} certCertificateScopeOfUse;
+
+/* corresponding ASN1 templates */
+static const SEC_ASN1Template cert_CertificateScopeEntryTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, nullptr, sizeof(CERTCertificateScopeEntry) },
+ { SEC_ASN1_ANY,
+ offsetof(CERTCertificateScopeEntry, derConstraint) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_INTEGER,
+ offsetof(CERTCertificateScopeEntry, derPort) },
+ { 0 }
+};
+
+static const SEC_ASN1Template cert_CertificateScopeOfUseTemplate[] = {
+ { SEC_ASN1_SEQUENCE_OF, 0, cert_CertificateScopeEntryTemplate }
+};
+
+#if 0
+/*
+ * decodes the extension data and create CERTCertificateScopeEntry that can
+ * be consumed by the code
+ */
+static
+SECStatus cert_DecodeScopeOfUseEntries(PRArenaPool* arena, SECItem* extData,
+ CERTCertificateScopeEntry*** entries,
+ int* numEntries)
+{
+ certCertificateScopeOfUse* scope = nullptr;
+ SECStatus rv = SECSuccess;
+ int i;
+
+ *entries = nullptr; /* in case of failure */
+ *numEntries = 0; /* ditto */
+
+ scope = (certCertificateScopeOfUse*)
+ PORT_ArenaZAlloc(arena, sizeof(certCertificateScopeOfUse));
+ if (!scope) {
+ goto loser;
+ }
+
+ rv = SEC_ASN1DecodeItem(arena, (void*)scope,
+ cert_CertificateScopeOfUseTemplate, extData);
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+
+ *entries = scope->entries;
+ PR_ASSERT(*entries);
+
+ /* first, let's count 'em. */
+ for (i = 0; (*entries)[i]; i++) ;
+ *numEntries = i;
+
+ /* convert certCertificateScopeEntry sequence into what we can readily
+ * use
+ */
+ for (i = 0; i < *numEntries; i++) {
+ (*entries)[i]->constraint =
+ CERT_DecodeGeneralName(arena, &((*entries)[i]->derConstraint),
+ nullptr);
+ if ((*entries)[i]->derPort.data) {
+ (*entries)[i]->port =
+ (int)DER_GetInteger(&((*entries)[i]->derPort));
+ }
+ else {
+ (*entries)[i]->port = 0;
+ }
+ }
+
+ goto done;
+loser:
+ if (rv == SECSuccess) {
+ rv = SECFailure;
+ }
+done:
+ return rv;
+}
+
+static SECStatus cert_DecodeCertIPAddress(SECItem* genname,
+ uint32_t* constraint, uint32_t* mask)
+{
+ /* in case of failure */
+ *constraint = 0;
+ *mask = 0;
+
+ PR_ASSERT(genname->data);
+ if (!genname->data) {
+ return SECFailure;
+ }
+ if (genname->len != 8) {
+ /* the length must be 4 byte IP address with 4 byte subnet mask */
+ return SECFailure;
+ }
+
+ /* get them in the right order */
+ *constraint = PR_ntohl((uint32_t)(*genname->data));
+ *mask = PR_ntohl((uint32_t)(*(genname->data + 4)));
+
+ return SECSuccess;
+}
+
+static char* _str_to_lower(char* string)
+{
+#ifdef XP_WIN
+ return _strlwr(string);
+#else
+ int i;
+ for (i = 0; string[i] != '\0'; i++) {
+ string[i] = tolower(string[i]);
+ }
+ return string;
+#endif
+}
+
+/*
+ * Sees if the client certificate has a restriction in presenting the cert
+ * to the host: returns true if there is no restriction or if the hostname
+ * (and the port) satisfies the restriction, or false if the hostname (and
+ * the port) does not satisfy the restriction
+ */
+static bool CERT_MatchesScopeOfUse(CERTCertificate* cert, char* hostname,
+ char* hostIP, int port)
+{
+ bool rv = true; /* whether the cert can be presented */
+ SECStatus srv;
+ SECItem extData;
+ PLArenaPool* arena = nullptr;
+ CERTCertificateScopeEntry** entries = nullptr;
+ /* arrays of decoded scope entries */
+ int numEntries = 0;
+ int i;
+ char* hostLower = nullptr;
+ uint32_t hostIPAddr = 0;
+
+ PR_ASSERT(cert && hostname && hostIP);
+
+ /* find cert extension */
+ srv = CERT_FindCertExtension(cert, SEC_OID_NS_CERT_EXT_SCOPE_OF_USE,
+ &extData);
+ if (srv != SECSuccess) {
+ /* most of the time, this means the extension was not found: also,
+ * since this is not a critical extension (as of now) we may simply
+ * return true
+ */
+ goto done;
+ }
+
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ goto done;
+ }
+
+ /* decode the scope of use entries into pairs of GeneralNames and
+ * an optional port numbers
+ */
+ srv = cert_DecodeScopeOfUseEntries(arena, &extData, &entries, &numEntries);
+ if (srv != SECSuccess) {
+ /* XXX What should we do when we failed to decode the extension? This
+ * may mean either the extension was malformed or some (unlikely)
+ * fatal error on our part: my argument is that if the extension
+ * was malformed the extension "disqualifies" as a valid
+ * constraint and we may present the cert
+ */
+ goto done;
+ }
+
+ /* loop over these structures */
+ for (i = 0; i < numEntries; i++) {
+ /* determine whether the GeneralName is a DNS pattern, an IP address
+ * constraint, or else
+ */
+ CERTGeneralName* genname = entries[i]->constraint;
+
+ /* if constraint is nullptr, don't bother looking */
+ if (!genname) {
+ /* this is not a failure: just continue */
+ continue;
+ }
+
+ switch (genname->type) {
+ case certDNSName: {
+ /* we have a DNS name constraint; we should use only the host name
+ * information
+ */
+ char* pattern = nullptr;
+ char* substring = nullptr;
+
+ /* null-terminate the string */
+ genname->name.other.data[genname->name.other.len] = '\0';
+ pattern = _str_to_lower((char*)genname->name.other.data);
+
+ if (!hostLower) {
+ /* so that it's done only if necessary and only once */
+ hostLower = _str_to_lower(PL_strdup(hostname));
+ }
+
+ /* the hostname satisfies the constraint */
+ if (((substring = strstr(hostLower, pattern)) != nullptr) &&
+ /* the hostname contains the pattern */
+ (strlen(substring) == strlen(pattern)) &&
+ /* the hostname ends with the pattern */
+ ((substring == hostLower) || (*(substring-1) == '.'))) {
+ /* the hostname either is identical to the pattern or
+ * belongs to a subdomain
+ */
+ rv = true;
+ }
+ else {
+ rv = false;
+ }
+ /* clean up strings if necessary */
+ break;
+ }
+ case certIPAddress: {
+ uint32_t constraint;
+ uint32_t mask;
+ PRNetAddr addr;
+
+ if (hostIPAddr == 0) {
+ /* so that it's done only if necessary and only once */
+ PR_StringToNetAddr(hostIP, &addr);
+ hostIPAddr = addr.inet.ip;
+ }
+
+ if (cert_DecodeCertIPAddress(&(genname->name.other), &constraint,
+ &mask) != SECSuccess) {
+ continue;
+ }
+ if ((hostIPAddr & mask) == (constraint & mask)) {
+ rv = true;
+ }
+ else {
+ rv = false;
+ }
+ break;
+ }
+ default:
+ /* ill-formed entry: abort */
+ continue; /* go to the next entry */
+ }
+
+ if (!rv) {
+ /* we do not need to check the port: go to the next entry */
+ continue;
+ }
+
+ /* finally, check the optional port number */
+ if ((entries[i]->port != 0) && (port != entries[i]->port)) {
+ /* port number does not match */
+ rv = false;
+ continue;
+ }
+
+ /* we have a match */
+ PR_ASSERT(rv);
+ break;
+ }
+done:
+ /* clean up entries */
+ if (arena) {
+ PORT_FreeArena(arena, false);
+ }
+ if (hostLower) {
+ PR_Free(hostLower);
+ }
+ return rv;
+}
+#endif
+
+/*
+ * Function: SSMStatus SSM_SetUserCertChoice()
+
+ * Purpose: sets certChoice by reading the preference
+ *
+ * Arguments and return values
+ * - conn: SSMSSLDataConnection
+ * - returns: SSM_SUCCESS if successful; SSM_FAILURE otherwise
+ *
+ * Note: If done properly, this function will read the identifier strings
+ * for ASK and AUTO modes, read the selected strings from the
+ * preference, compare the strings, and determine in which mode it is
+ * in.
+ * We currently use ASK mode for UI apps and AUTO mode for UI-less
+ * apps without really asking for preferences.
+ */
+nsresult nsGetUserCertChoice(SSM_UserCertChoice* certChoice)
+{
+ char *mode = nullptr;
+ nsresult ret;
+
+ NS_ENSURE_ARG_POINTER(certChoice);
+
+ nsCOMPtr<nsIPrefBranch> pref = do_GetService(NS_PREFSERVICE_CONTRACTID);
+
+ ret = pref->GetCharPref("security.default_personal_cert", &mode);
+ if (NS_FAILED(ret)) {
+ goto loser;
+ }
+
+ if (PL_strcmp(mode, "Select Automatically") == 0) {
+ *certChoice = AUTO;
+ }
+ else if (PL_strcmp(mode, "Ask Every Time") == 0) {
+ *certChoice = ASK;
+ }
+ else {
+ // Most likely we see a nickname from a migrated cert.
+ // We do not currently support that, ask the user which cert to use.
+ *certChoice = ASK;
+ }
+
+loser:
+ if (mode) {
+ nsMemory::Free(mode);
+ }
+ return ret;
+}
+
+static bool hasExplicitKeyUsageNonRepudiation(CERTCertificate *cert)
+{
+ /* There is no extension, v1 or v2 certificate */
+ if (!cert->extensions)
+ return false;
+
+ SECStatus srv;
+ SECItem keyUsageItem;
+ keyUsageItem.data = nullptr;
+
+ srv = CERT_FindKeyUsageExtension(cert, &keyUsageItem);
+ if (srv == SECFailure)
+ return false;
+
+ unsigned char keyUsage = keyUsageItem.data[0];
+ PORT_Free (keyUsageItem.data);
+
+ return !!(keyUsage & KU_NON_REPUDIATION);
+}
+
+class ClientAuthDataRunnable : public SyncRunnableBase
+{
+public:
+ ClientAuthDataRunnable(CERTDistNames* caNames,
+ CERTCertificate** pRetCert,
+ SECKEYPrivateKey** pRetKey,
+ nsNSSSocketInfo * info,
+ CERTCertificate * serverCert)
+ : mRV(SECFailure)
+ , mErrorCodeToReport(SEC_ERROR_NO_MEMORY)
+ , mPRetCert(pRetCert)
+ , mPRetKey(pRetKey)
+ , mCANames(caNames)
+ , mSocketInfo(info)
+ , mServerCert(serverCert)
+ {
+ }
+
+ SECStatus mRV; // out
+ PRErrorCode mErrorCodeToReport; // out
+ CERTCertificate** const mPRetCert; // in/out
+ SECKEYPrivateKey** const mPRetKey; // in/out
+protected:
+ virtual void RunOnTargetThread();
+private:
+ CERTDistNames* const mCANames; // in
+ nsNSSSocketInfo * const mSocketInfo; // in
+ CERTCertificate * const mServerCert; // in
+};
+
+/*
+ * Function: SECStatus SSM_SSLGetClientAuthData()
+ * Purpose: this callback function is used to pull client certificate
+ * information upon server request
+ *
+ * Arguments and return values
+ * - arg: SSL data connection
+ * - socket: SSL socket we're dealing with
+ * - caNames: list of CA names
+ * - pRetCert: returns a pointer to a pointer to a valid certificate if
+ * successful; otherwise NULL
+ * - pRetKey: returns a pointer to a pointer to the corresponding key if
+ * successful; otherwise NULL
+ * - returns: SECSuccess if successful; error code otherwise
+ */
+SECStatus nsNSS_SSLGetClientAuthData(void* arg, PRFileDesc* socket,
+ CERTDistNames* caNames,
+ CERTCertificate** pRetCert,
+ SECKEYPrivateKey** pRetKey)
+{
+ nsNSSShutDownPreventionLock locker;
+
+ if (!socket || !caNames || !pRetCert || !pRetKey) {
+ PR_SetError(PR_INVALID_ARGUMENT_ERROR, 0);
+ return SECFailure;
+ }
+
+ RefPtr<nsNSSSocketInfo> info(
+ reinterpret_cast<nsNSSSocketInfo*>(socket->higher->secret));
+
+ CERTCertificate* serverCert = SSL_PeerCertificate(socket);
+ if (!serverCert) {
+ NS_NOTREACHED("Missing server certificate should have been detected during "
+ "server cert authentication.");
+ PR_SetError(SSL_ERROR_NO_CERTIFICATE, 0);
+ return SECFailure;
+ }
+
+ if (info->GetJoined()) {
+ // We refuse to send a client certificate when there are multiple hostnames
+ // joined on this connection, because we only show the user one hostname
+ // (mHostName) in the client certificate UI.
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG,
+ ("[%p] Not returning client cert due to previous join\n", socket));
+ *pRetCert = nullptr;
+ *pRetKey = nullptr;
+ return SECSuccess;
+ }
+
+ // XXX: This should be done asynchronously; see bug 696976
+ RefPtr<ClientAuthDataRunnable> runnable(
+ new ClientAuthDataRunnable(caNames, pRetCert, pRetKey, info, serverCert));
+ nsresult rv = runnable->DispatchToMainThreadAndWait();
+ if (NS_FAILED(rv)) {
+ PR_SetError(SEC_ERROR_NO_MEMORY, 0);
+ return SECFailure;
+ }
+
+ if (runnable->mRV != SECSuccess) {
+ PR_SetError(runnable->mErrorCodeToReport, 0);
+ } else if (*runnable->mPRetCert || *runnable->mPRetKey) {
+ // Make joinConnection prohibit joining after we've sent a client cert
+ info->SetSentClientCert();
+ }
+
+ return runnable->mRV;
+}
+
+void ClientAuthDataRunnable::RunOnTargetThread()
+{
+ PLArenaPool* arena = nullptr;
+ char** caNameStrings;
+ ScopedCERTCertificate cert;
+ ScopedSECKEYPrivateKey privKey;
+ ScopedCERTCertList certList;
+ CERTCertListNode* node;
+ ScopedCERTCertNicknames nicknames;
+ char* extracted = nullptr;
+ int keyError = 0; /* used for private key retrieval error */
+ SSM_UserCertChoice certChoice;
+ int32_t NumberOfCerts = 0;
+ void * wincx = mSocketInfo;
+ nsresult rv;
+
+ /* create caNameStrings */
+ arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
+ if (!arena) {
+ goto loser;
+ }
+
+ caNameStrings = (char**)PORT_ArenaAlloc(arena,
+ sizeof(char*)*(mCANames->nnames));
+ if (!caNameStrings) {
+ goto loser;
+ }
+
+ mRV = nsConvertCANamesToStrings(arena, caNameStrings, mCANames);
+ if (mRV != SECSuccess) {
+ goto loser;
+ }
+
+ /* get the preference */
+ if (NS_FAILED(nsGetUserCertChoice(&certChoice))) {
+ goto loser;
+ }
+
+ /* find valid user cert and key pair */
+ if (certChoice == AUTO) {
+ /* automatically find the right cert */
+
+ /* find all user certs that are valid and for SSL */
+ certList = CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(),
+ certUsageSSLClient, false,
+ true, wincx);
+ if (!certList) {
+ goto noCert;
+ }
+
+ /* filter the list to those issued by CAs supported by the server */
+ mRV = CERT_FilterCertListByCANames(certList, mCANames->nnames,
+ caNameStrings, certUsageSSLClient);
+ if (mRV != SECSuccess) {
+ goto noCert;
+ }
+
+ /* make sure the list is not empty */
+ node = CERT_LIST_HEAD(certList);
+ if (CERT_LIST_END(node, certList)) {
+ goto noCert;
+ }
+
+ ScopedCERTCertificate low_prio_nonrep_cert;
+
+ /* loop through the list until we find a cert with a key */
+ while (!CERT_LIST_END(node, certList)) {
+ /* if the certificate has restriction and we do not satisfy it
+ * we do not use it
+ */
+#if 0 /* XXX This must be re-enabled */
+ if (!CERT_MatchesScopeOfUse(node->cert, mSocketInfo->GetHostName,
+ info->GetHostIP, info->GetHostPort)) {
+ node = CERT_LIST_NEXT(node);
+ continue;
+ }
+#endif
+
+ privKey = PK11_FindKeyByAnyCert(node->cert, wincx);
+ if (privKey) {
+ if (hasExplicitKeyUsageNonRepudiation(node->cert)) {
+ privKey = nullptr;
+ // Not a prefered cert
+ if (!low_prio_nonrep_cert) // did not yet find a low prio cert
+ low_prio_nonrep_cert = CERT_DupCertificate(node->cert);
+ }
+ else {
+ // this is a good cert to present
+ cert = CERT_DupCertificate(node->cert);
+ break;
+ }
+ }
+ keyError = PR_GetError();
+ if (keyError == SEC_ERROR_BAD_PASSWORD) {
+ /* problem with password: bail */
+ goto loser;
+ }
+
+ node = CERT_LIST_NEXT(node);
+ }
+
+ if (!cert && low_prio_nonrep_cert) {
+ cert = low_prio_nonrep_cert.forget();
+ privKey = PK11_FindKeyByAnyCert(cert, wincx);
+ }
+
+ if (!cert) {
+ goto noCert;
+ }
+ }
+ else { // Not Auto => ask
+ /* Get the SSL Certificate */
+
+ nsXPIDLCString hostname;
+ mSocketInfo->GetHostName(getter_Copies(hostname));
+
+ nsAutoCString clientlogin;
+ mSocketInfo->GetClientLogin(clientlogin);
+
+ RefPtr<nsClientAuthRememberService> cars =
+ mSocketInfo->SharedState().GetClientAuthRememberService();
+
+ bool hasRemembered = false;
+ nsCString rememberedDBKey;
+ if (cars) {
+ bool found;
+ rv = cars->HasRememberedDecision(hostname, mServerCert,
+ rememberedDBKey, &found);
+ if (NS_SUCCEEDED(rv) && found) {
+ hasRemembered = true;
+ }
+ }
+
+ bool canceled = false;
+
+if (hasRemembered)
+{
+ if (rememberedDBKey.IsEmpty())
+ {
+ canceled = true;
+ }
+ else
+ {
+ nsCOMPtr<nsIX509CertDB> certdb;
+ certdb = do_GetService(NS_X509CERTDB_CONTRACTID);
+ if (certdb)
+ {
+ nsCOMPtr<nsIX509Cert> found_cert;
+ nsresult find_rv =
+ certdb->FindCertByDBKey(rememberedDBKey.get(), nullptr,
+ getter_AddRefs(found_cert));
+ if (NS_SUCCEEDED(find_rv) && found_cert) {
+ nsNSSCertificate *obj_cert = reinterpret_cast<nsNSSCertificate *>(found_cert.get());
+ if (obj_cert) {
+ cert = obj_cert->GetCert();
+
+#ifdef DEBUG_kaie
+ nsAutoString nick, nickWithSerial, details;
+ if (NS_SUCCEEDED(obj_cert->FormatUIStrings(nick,
+ nickWithSerial,
+ details))) {
+ NS_LossyConvertUTF16toASCII asc(nickWithSerial);
+ fprintf(stderr, "====> remembered serial %s\n", asc.get());
+ }
+#endif
+
+ }
+ }
+
+ if (!cert) {
+ hasRemembered = false;
+ }
+ }
+ }
+}
+
+if (!hasRemembered)
+{
+ /* user selects a cert to present */
+ nsIClientAuthDialogs *dialogs = nullptr;
+ int32_t selectedIndex = -1;
+ PRUnichar **certNicknameList = nullptr;
+ PRUnichar **certDetailsList = nullptr;
+
+ /* find all user certs that are for SSL */
+ /* note that we are allowing expired certs in this list */
+ certList = CERT_FindUserCertsByUsage(CERT_GetDefaultCertDB(),
+ certUsageSSLClient, false,
+ false, wincx);
+ if (!certList) {
+ goto noCert;
+ }
+
+ if (mCANames->nnames != 0) {
+ /* filter the list to those issued by CAs supported by the
+ * server
+ */
+ mRV = CERT_FilterCertListByCANames(certList, mCANames->nnames,
+ caNameStrings,
+ certUsageSSLClient);
+ if (mRV != SECSuccess) {
+ goto loser;
+ }
+ }
+
+ if (CERT_LIST_END(CERT_LIST_HEAD(certList), certList)) {
+ /* list is empty - no matching certs */
+ goto noCert;
+ }
+
+ /* filter it further for hostname restriction */
+ node = CERT_LIST_HEAD(certList);
+ while (!CERT_LIST_END(node, certList)) {
+ ++NumberOfCerts;
+#if 0 /* XXX Fix this */
+ if (!CERT_MatchesScopeOfUse(node->cert, conn->hostName,
+ conn->hostIP, conn->port)) {
+ CERTCertListNode* removed = node;
+ node = CERT_LIST_NEXT(removed);
+ CERT_RemoveCertListNode(removed);
+ }
+ else {
+ node = CERT_LIST_NEXT(node);
+ }
+#endif
+ node = CERT_LIST_NEXT(node);
+ }
+ if (CERT_LIST_END(CERT_LIST_HEAD(certList), certList)) {
+ goto noCert;
+ }
+
+ nicknames = getNSSCertNicknamesFromCertList(certList);
+
+ if (!nicknames) {
+ goto loser;
+ }
+
+ NS_ASSERTION(nicknames->numnicknames == NumberOfCerts, "nicknames->numnicknames != NumberOfCerts");
+
+ /* Get CN and O of the subject and O of the issuer */
+ char *ccn = CERT_GetCommonName(&mServerCert->subject);
+ void *v = ccn;
+ voidCleaner ccnCleaner(v);
+ NS_ConvertUTF8toUTF16 cn(ccn);
+
+ int32_t port;
+ mSocketInfo->GetPort(&port);
+
+ nsString cn_host_port;
+ if (ccn && strcmp(ccn, hostname) == 0) {
+ cn_host_port.Append(cn);
+ cn_host_port.AppendLiteral(":");
+ cn_host_port.AppendInt(port);
+ }
+ else {
+ cn_host_port.Append(cn);
+ cn_host_port.AppendLiteral(" (");
+ cn_host_port.AppendLiteral(":");
+ cn_host_port.AppendInt(port);
+ cn_host_port.AppendLiteral(")");
+ }
+
+ char *corg = CERT_GetOrgName(&mServerCert->subject);
+ NS_ConvertUTF8toUTF16 org(corg);
+ if (corg) PORT_Free(corg);
+
+ char *cissuer = CERT_GetOrgName(&mServerCert->issuer);
+ NS_ConvertUTF8toUTF16 issuer(cissuer);
+ if (cissuer) PORT_Free(cissuer);
+
+ certNicknameList = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * nicknames->numnicknames);
+ if (!certNicknameList)
+ goto loser;
+ certDetailsList = (PRUnichar **)nsMemory::Alloc(sizeof(PRUnichar *) * nicknames->numnicknames);
+ if (!certDetailsList) {
+ nsMemory::Free(certNicknameList);
+ goto loser;
+ }
+
+ int32_t CertsToUse;
+ for (CertsToUse = 0, node = CERT_LIST_HEAD(certList);
+ !CERT_LIST_END(node, certList) && CertsToUse < nicknames->numnicknames;
+ node = CERT_LIST_NEXT(node)
+ )
+ {
+ RefPtr<nsNSSCertificate> tempCert(nsNSSCertificate::Create(node->cert));
+
+ if (!tempCert)
+ continue;
+
+ NS_ConvertUTF8toUTF16 i_nickname(nicknames->nicknames[CertsToUse]);
+ nsAutoString nickWithSerial, details;
+
+ if (NS_FAILED(tempCert->FormatUIStrings(i_nickname, nickWithSerial, details)))
+ continue;
+
+ certNicknameList[CertsToUse] = ToNewUnicode(nickWithSerial);
+ if (!certNicknameList[CertsToUse])
+ continue;
+ certDetailsList[CertsToUse] = ToNewUnicode(details);
+ if (!certDetailsList[CertsToUse]) {
+ nsMemory::Free(certNicknameList[CertsToUse]);
+ continue;
+ }
+
+ ++CertsToUse;
+ }
+
+ /* Throw up the client auth dialog and get back the index of the selected cert */
+ nsresult rv = getNSSDialogs((void**)&dialogs,
+ NS_GET_IID(nsIClientAuthDialogs),
+ NS_CLIENTAUTHDIALOGS_CONTRACTID);
+
+ if (NS_FAILED(rv)) {
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList);
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certDetailsList);
+ goto loser;
+ }
+
+ {
+ nsPSMUITracker tracker;
+ if (tracker.isUIForbidden()) {
+ rv = NS_ERROR_NOT_AVAILABLE;
+ }
+ else {
+ rv = dialogs->ChooseCertificate(mSocketInfo, cn_host_port.get(),
+ org.get(), issuer.get(),
+ (const PRUnichar**)certNicknameList,
+ (const PRUnichar**)certDetailsList,
+ CertsToUse, &selectedIndex, &canceled);
+ }
+ }
+
+ NS_RELEASE(dialogs);
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certNicknameList);
+ NS_FREE_XPCOM_ALLOCATED_POINTER_ARRAY(CertsToUse, certDetailsList);
+
+ if (NS_FAILED(rv)) goto loser;
+
+ // even if the user has canceled, we want to remember that, to avoid repeating prompts
+ bool wantRemember = false;
+ mSocketInfo->GetRememberClientAuthCertificate(&wantRemember);
+
+ int i;
+ if (!canceled)
+ for (i = 0, node = CERT_LIST_HEAD(certList);
+ !CERT_LIST_END(node, certList);
+ ++i, node = CERT_LIST_NEXT(node)) {
+
+ if (i == selectedIndex) {
+ cert = CERT_DupCertificate(node->cert);
+ break;
+ }
+ }
+
+ if (cars && wantRemember) {
+ if(clientlogin.IsEmpty()){
+ cars->RememberDecision(hostname,
+ mServerCert,
+ canceled ? nullptr : cert.get());
+ }
+ else{
+ cars->RememberDecision(hostname,
+ mServerCert,
+ canceled ? nullptr : cert.get(),clientlogin);
+ }
+ }
+}
+
+ if (canceled) { rv = NS_ERROR_NOT_AVAILABLE; goto loser; }
+
+ if (!cert) {
+ goto loser;
+ }
+
+ /* go get the private key */
+ privKey = PK11_FindKeyByAnyCert(cert, wincx);
+ if (!privKey) {
+ keyError = PR_GetError();
+ if (keyError == SEC_ERROR_BAD_PASSWORD) {
+ /* problem with password: bail */
+ goto loser;
+ }
+ else {
+ goto noCert;
+ }
+ }
+ }
+ goto done;
+
+noCert:
+loser:
+ if (mRV == SECSuccess) {
+ mRV = SECFailure;
+ }
+done:
+ int error = PR_GetError();
+
+ if (extracted) {
+ PR_Free(extracted);
+ }
+ if (arena) {
+ PORT_FreeArena(arena, false);
+ }
+
+ *mPRetCert = cert.forget();
+ *mPRetKey = privKey.forget();
+
+ if (mRV == SECFailure) {
+ mErrorCodeToReport = error;
+ }
+}
+
+static PRFileDesc*
+nsSSLIOLayerImportFD(PRFileDesc *fd,
+ nsNSSSocketInfo *infoObject,
+ const char *host)
+{
+ nsNSSShutDownPreventionLock locker;
+ PRFileDesc* sslSock = SSL_ImportFD(nullptr, fd);
+ if (!sslSock) {
+ NS_ASSERTION(false, "NSS: Error importing socket");
+ return nullptr;
+ }
+ SSL_SetPKCS11PinArg(sslSock, (nsIInterfaceRequestor*)infoObject);
+ SSL_HandshakeCallback(sslSock, HandshakeCallback, infoObject);
+
+ // Disable this hook if we connect anonymously. See bug 466080.
+ uint32_t flags = 0;
+ infoObject->GetProviderFlags(&flags);
+ if (flags & nsISocketProvider::ANONYMOUS_CONNECT) {
+ SSL_GetClientAuthDataHook(sslSock, nullptr, infoObject);
+ } else {
+ SSL_GetClientAuthDataHook(sslSock,
+ (SSLGetClientAuthData)nsNSS_SSLGetClientAuthData,
+ infoObject);
+ }
+ if (SECSuccess != SSL_AuthCertificateHook(sslSock, AuthCertificateHook,
+ infoObject)) {
+ NS_NOTREACHED("failed to configure AuthCertificateHook");
+ goto loser;
+ }
+
+ if (SECSuccess != SSL_SetURL(sslSock, host)) {
+ NS_NOTREACHED("SSL_SetURL failed");
+ goto loser;
+ }
+
+ // This is an optimization to make sure the identity info dataset is parsed
+ // and loaded on a separate thread and can be overlapped with network latency.
+ EnsureServerVerificationInitialized();
+
+ return sslSock;
+loser:
+ if (sslSock) {
+ PR_Close(sslSock);
+ }
+ return nullptr;
+}
+
+static nsresult
+nsSSLIOLayerSetOptions(PRFileDesc *fd, bool forSTARTTLS,
+ const char *proxyHost, const char *host, int32_t port,
+ nsNSSSocketInfo *infoObject)
+{
+ nsNSSShutDownPreventionLock locker;
+ if (forSTARTTLS || proxyHost) {
+ if (SECSuccess != SSL_OptionSet(fd, SSL_SECURITY, false)) {
+ return NS_ERROR_FAILURE;
+ }
+ infoObject->SetHasCleartextPhase(true);
+ }
+
+ // Let's see if we're trying to connect to a site we know is
+ // TLS intolerant.
+ nsAutoCString key;
+ key = nsDependentCString(host) + NS_LITERAL_CSTRING(":") + nsPrintfCString("%d", port);
+
+ if (infoObject->SharedState().IOLayerHelpers().isKnownAsIntolerantSite(key)) {
+ if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_TLS, false))
+ return NS_ERROR_FAILURE;
+
+ infoObject->SetAllowTLSIntoleranceTimeout(false);
+
+ // We assume that protocols that use the STARTTLS mechanism should support
+ // modern hellos. For other protocols, if we suspect a site
+ // does not support TLS, let's also use V2 hellos.
+ // One advantage of this approach, if a site only supports the older
+ // hellos, it is more likely that we will get a reasonable error code
+ // on our single retry attempt.
+ }
+
+ PRBool enabled;
+ if (SECSuccess != SSL_OptionGet(fd, SSL_ENABLE_SSL3, &enabled)) {
+ return NS_ERROR_FAILURE;
+ }
+ infoObject->SetSSL3Enabled(enabled);
+ if (SECSuccess != SSL_OptionGet(fd, SSL_ENABLE_TLS, &enabled)) {
+ return NS_ERROR_FAILURE;
+ }
+ infoObject->SetTLSEnabled(enabled);
+
+ if (SECSuccess != SSL_OptionSet(fd, SSL_HANDSHAKE_AS_CLIENT, true)) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsSSLIOLayerHelpers& ioHelpers = infoObject->SharedState().IOLayerHelpers();
+ if (ioHelpers.isRenegoUnrestrictedSite(nsDependentCString(host))) {
+ if (SECSuccess != SSL_OptionSet(fd, SSL_REQUIRE_SAFE_NEGOTIATION, false)) {
+ return NS_ERROR_FAILURE;
+ }
+ if (SECSuccess != SSL_OptionSet(fd, SSL_ENABLE_RENEGOTIATION, SSL_RENEGOTIATE_UNRESTRICTED)) {
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ // Set the Peer ID so that SSL proxy connections work properly and to
+ // separate anonymous and/or private browsing connections.
+ uint32_t flags = infoObject->GetProviderFlags();
+ nsAutoCString peerId;
+ if (flags & nsISocketProvider::ANONYMOUS_CONNECT) { // See bug 466080
+ peerId.Append("anon:");
+ }
+ if (flags & nsISocketProvider::NO_PERMANENT_STORAGE) {
+ peerId.Append("private:");
+ }
+ peerId.Append(host);
+ peerId.Append(':');
+ peerId.AppendInt(port);
+ if (SECSuccess != SSL_SetSockPeerID(fd, peerId.get())) {
+ return NS_ERROR_FAILURE;
+ }
+
+ return NS_OK;
+}
+
+nsresult
+nsSSLIOLayerAddToSocket(int32_t family,
+ const char* host,
+ int32_t port,
+ const char* proxyHost,
+ int32_t proxyPort,
+ PRFileDesc* fd,
+ nsISupports** info,
+ bool forSTARTTLS,
+ uint32_t providerFlags)
+{
+ nsNSSShutDownPreventionLock locker;
+ PRFileDesc* layer = nullptr;
+ PRFileDesc* plaintextLayer = nullptr;
+ nsresult rv;
+ PRStatus stat;
+
+ SharedSSLState* sharedState =
+ providerFlags & nsISocketProvider::NO_PERMANENT_STORAGE ? PrivateSSLState() : PublicSSLState();
+ nsNSSSocketInfo* infoObject = new nsNSSSocketInfo(*sharedState, providerFlags);
+ if (!infoObject) return NS_ERROR_FAILURE;
+
+ NS_ADDREF(infoObject);
+ infoObject->SetForSTARTTLS(forSTARTTLS);
+ infoObject->SetHostName(host);
+ infoObject->SetPort(port);
+
+ // A plaintext observer shim is inserted so we can observe some protocol
+ // details without modifying nss
+ plaintextLayer = PR_CreateIOLayerStub(nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity,
+ &nsSSLIOLayerHelpers::nsSSLPlaintextLayerMethods);
+ if (plaintextLayer) {
+ plaintextLayer->secret = (PRFilePrivate*) infoObject;
+ stat = PR_PushIOLayer(fd, PR_TOP_IO_LAYER, plaintextLayer);
+ if (stat == PR_FAILURE) {
+ plaintextLayer->dtor(plaintextLayer);
+ plaintextLayer = nullptr;
+ }
+ }
+
+ PRFileDesc *sslSock = nsSSLIOLayerImportFD(fd, infoObject, host);
+ if (!sslSock) {
+ NS_ASSERTION(false, "NSS: Error importing socket");
+ goto loser;
+ }
+
+ infoObject->SetFileDescPtr(sslSock);
+
+ rv = nsSSLIOLayerSetOptions(sslSock, forSTARTTLS, proxyHost, host, port,
+ infoObject);
+
+ if (NS_FAILED(rv))
+ goto loser;
+
+ /* Now, layer ourselves on top of the SSL socket... */
+ layer = PR_CreateIOLayerStub(nsSSLIOLayerHelpers::nsSSLIOLayerIdentity,
+ &nsSSLIOLayerHelpers::nsSSLIOLayerMethods);
+ if (!layer)
+ goto loser;
+
+ layer->secret = (PRFilePrivate*) infoObject;
+ stat = PR_PushIOLayer(sslSock, PR_GetLayersIdentity(sslSock), layer);
+
+ if (stat == PR_FAILURE) {
+ goto loser;
+ }
+
+ nsNSSShutDownList::trackSSLSocketCreate();
+
+ PR_LOG(gPIPNSSLog, PR_LOG_DEBUG, ("[%p] Socket set up\n", (void*)sslSock));
+ infoObject->QueryInterface(NS_GET_IID(nsISupports), (void**) (info));
+
+ // We are going use a clear connection first //
+ if (forSTARTTLS || proxyHost) {
+ infoObject->SetHandshakePending(false);
+ }
+
+ infoObject->SharedState().NoteSocketCreated();
+
+ return NS_OK;
+ loser:
+ NS_IF_RELEASE(infoObject);
+ if (layer) {
+ layer->dtor(layer);
+ }
+ if (plaintextLayer) {
+ PR_PopIOLayer(fd, nsSSLIOLayerHelpers::nsSSLPlaintextLayerIdentity);
+ plaintextLayer->dtor(plaintextLayer);
+ }
+ return NS_ERROR_FAILURE;
+}
--- /dev/null
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Brian Ryner <bryner@brianryner.com>
+ * Kai Engert <kengert@redhat.com>
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved */
+
+#ifndef _NSNSSIOLAYER_H
+#define _NSNSSIOLAYER_H
+
+#include "TransportSecurityInfo.h"
+#include "nsISSLSocketControl.h"
+#include "nsIClientAuthDialogs.h"
+#include "nsNSSCertificate.h"
+#include "nsDataHashtable.h"
+#include "nsTHashtable.h"
+#include "mozilla/TimeStamp.h"
+
+namespace mozilla {
+namespace psm {
+class SharedSSLState;
+}
+}
+
+class nsIObserver;
+
+class nsNSSSocketInfo : public mozilla::psm::TransportSecurityInfo,
+ public nsISSLSocketControl,
+ public nsIClientAuthUserDecision
+{
+public:
+ nsNSSSocketInfo(mozilla::psm::SharedSSLState& aState, uint32_t providerFlags);
+
+ NS_DECL_ISUPPORTS_INHERITED
+ NS_DECL_NSISSLSOCKETCONTROL
+ NS_DECL_NSICLIENTAUTHUSERDECISION
+
+ nsresult SetForSTARTTLS(bool aForSTARTTLS);
+ nsresult GetForSTARTTLS(bool *aForSTARTTLS);
+
+ nsresult GetFileDescPtr(PRFileDesc** aFilePtr);
+ nsresult SetFileDescPtr(PRFileDesc* aFilePtr);
+
+ nsresult GetHandshakePending(bool *aHandshakePending);
+ nsresult SetHandshakePending(bool aHandshakePending);
+
+ void GetPreviousCert(nsIX509Cert** _result);
+
+ void SetHasCleartextPhase(bool aHasCleartextPhase);
+ bool GetHasCleartextPhase();
+
+ void SetHandshakeInProgress(bool aIsIn);
+ bool GetHandshakeInProgress() { return mHandshakeInProgress; }
+ void SetFirstServerHelloReceived() { mFirstServerHelloReceived = true; }
+ bool GetFirstServerHelloReceived() { return mFirstServerHelloReceived; }
+ bool HandshakeTimeout();
+
+ void SetAllowTLSIntoleranceTimeout(bool aAllow);
+
+ PRStatus CloseSocketAndDestroy(
+ const nsNSSShutDownPreventionLock & proofOfLock);
+
+ void SetNegotiatedNPN(const char *value, uint32_t length);
+ void SetHandshakeCompleted(bool aResumedSession);
+
+ bool GetJoined() { return mJoined; }
+ void SetSentClientCert() { mSentClientCert = true; }
+
+ uint32_t GetProviderFlags() const { return mProviderFlags; }
+
+ mozilla::psm::SharedSSLState& SharedState();
+
+ // XXX: These are only used on for diagnostic purposes
+ enum CertVerificationState {
+ before_cert_verification,
+ waiting_for_cert_verification,
+ after_cert_verification
+ };
+ void SetCertVerificationWaiting();
+ // Use errorCode == 0 to indicate success; in that case, errorMessageType is
+ // ignored.
+ void SetCertVerificationResult(PRErrorCode errorCode,
+ ::mozilla::psm::SSLErrorMessageType errorMessageType);
+
+ // for logging only
+ PRBool IsWaitingForCertVerification() const
+ {
+ return mCertVerificationState == waiting_for_cert_verification;
+ }
+
+ bool IsSSL3Enabled() const { return mSSL3Enabled; }
+ void SetSSL3Enabled(bool enabled) { mSSL3Enabled = enabled; }
+ bool IsTLSEnabled() const { return mTLSEnabled; }
+ void SetTLSEnabled(bool enabled) { mTLSEnabled = enabled; }
+ nsCString mClientLogin;
+
+ void AddPlaintextBytesRead(uint64_t val) { mPlaintextBytesRead += val; }
+private:
+ PRFileDesc* mFd;
+
+ CertVerificationState mCertVerificationState;
+
+ mozilla::psm::SharedSSLState& mSharedState;
+ bool mForSTARTTLS;
+ bool mSSL3Enabled;
+ bool mTLSEnabled;
+ bool mHandshakePending;
+ bool mHasCleartextPhase;
+ bool mHandshakeInProgress;
+ bool mAllowTLSIntoleranceTimeout;
+ bool mRememberClientAuthCertificate;
+ PRIntervalTime mHandshakeStartTime;
+ bool mFirstServerHelloReceived;
+
+ nsresult ActivateSSL();
+
+ nsCString mNegotiatedNPN;
+ bool mNPNCompleted;
+ bool mHandshakeCompleted;
+ bool mJoined;
+ bool mSentClientCert;
+
+ uint32_t mProviderFlags;
+ mozilla::TimeStamp mSocketCreationTimestamp;
+ uint64_t mPlaintextBytesRead;
+};
+
+class nsSSLIOLayerHelpers
+{
+public:
+ nsSSLIOLayerHelpers();
+ ~nsSSLIOLayerHelpers();
+
+ nsresult Init();
+ void Cleanup();
+
+ static bool nsSSLIOLayerInitialized;
+ static PRDescIdentity nsSSLIOLayerIdentity;
+ static PRDescIdentity nsSSLPlaintextLayerIdentity;
+ static PRIOMethods nsSSLIOLayerMethods;
+ static PRIOMethods nsSSLPlaintextLayerMethods;
+
+ mozilla::Mutex *mutex;
+ nsTHashtable<nsCStringHashKey> *mTLSIntolerantSites;
+ nsTHashtable<nsCStringHashKey> *mTLSTolerantSites;
+
+ nsTHashtable<nsCStringHashKey> *mRenegoUnrestrictedSites;
+ bool mTreatUnsafeNegotiationAsBroken;
+ int32_t mWarnLevelMissingRFC5746;
+
+ void setTreatUnsafeNegotiationAsBroken(bool broken);
+ bool treatUnsafeNegotiationAsBroken();
+
+ void setWarnLevelMissingRFC5746(int32_t level);
+ int32_t getWarnLevelMissingRFC5746();
+
+ static void getSiteKey(nsNSSSocketInfo *socketInfo, nsCSubstring &key);
+ bool rememberPossibleTLSProblemSite(nsNSSSocketInfo *socketInfo);
+ void rememberTolerantSite(nsNSSSocketInfo *socketInfo);
+
+ void addIntolerantSite(const nsCString &str);
+ void removeIntolerantSite(const nsCString &str);
+ bool isKnownAsIntolerantSite(const nsCString &str);
+
+ void setRenegoUnrestrictedSites(const nsCString &str);
+ bool isRenegoUnrestrictedSite(const nsCString &str);
+
+ void clearStoredData();
+private:
+ nsCOMPtr<nsIObserver> mPrefObserver;
+};
+
+nsresult nsSSLIOLayerNewSocket(int32_t family,
+ const char *host,
+ int32_t port,
+ const char *proxyHost,
+ int32_t proxyPort,
+ PRFileDesc **fd,
+ nsISupports **securityInfo,
+ bool forSTARTTLS,
+ uint32_t flags);
+
+nsresult nsSSLIOLayerAddToSocket(int32_t family,
+ const char *host,
+ int32_t port,
+ const char *proxyHost,
+ int32_t proxyPort,
+ PRFileDesc *fd,
+ nsISupports **securityInfo,
+ bool forSTARTTLS,
+ uint32_t flags);
+
+nsresult nsSSLIOLayerFreeTLSIntolerantSites();
+nsresult displayUnknownCertErrorAlert(nsNSSSocketInfo *infoObject, int error);
+
+#endif /* _NSNSSIOLAYER_H */
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Interfaces of the CMS implementation.
+ *
+ * $Id: cms.h,v 1.27 2012/04/25 14:50:08 gerv%gerv.net Exp $
+ */
+
+#ifndef _CMS_H_
+#define _CMS_H_
+
+#include "seccomon.h"
+
+#include "secoidt.h"
+#include "certt.h"
+#include "keyt.h"
+#include "hasht.h"
+#include "cmst.h"
+
+/************************************************************************/
+SEC_BEGIN_PROTOS
+
+/************************************************************************
+ * cmsdecode.c - CMS decoding
+ ************************************************************************/
+
+/*
+ * NSS_CMSDecoder_Start - set up decoding of a DER-encoded CMS message
+ *
+ * "poolp" - pointer to arena for message, or NULL if new pool should be created
+ * "cb", "cb_arg" - callback function and argument for delivery of inner content
+ * inner content will be stored in the message if cb is NULL.
+ * "pwfn", pwfn_arg" - callback function for getting token password
+ * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData
+ */
+extern NSSCMSDecoderContext *
+NSS_CMSDecoder_Start(PLArenaPool *poolp,
+ NSSCMSContentCallback cb, void *cb_arg,
+ PK11PasswordFunc pwfn, void *pwfn_arg,
+ NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg);
+
+/*
+ * NSS_CMSDecoder_Update - feed DER-encoded data to decoder
+ */
+extern SECStatus
+NSS_CMSDecoder_Update(NSSCMSDecoderContext *p7dcx, const char *buf, unsigned long len);
+
+/*
+ * NSS_CMSDecoder_Cancel - cancel a decoding process
+ */
+extern void
+NSS_CMSDecoder_Cancel(NSSCMSDecoderContext *p7dcx);
+
+/*
+ * NSS_CMSDecoder_Finish - mark the end of inner content and finish decoding
+ */
+extern NSSCMSMessage *
+NSS_CMSDecoder_Finish(NSSCMSDecoderContext *p7dcx);
+
+/*
+ * NSS_CMSMessage_CreateFromDER - decode a CMS message from DER encoded data
+ */
+extern NSSCMSMessage *
+NSS_CMSMessage_CreateFromDER(SECItem *DERmessage,
+ NSSCMSContentCallback cb, void *cb_arg,
+ PK11PasswordFunc pwfn, void *pwfn_arg,
+ NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg);
+
+/************************************************************************
+ * cmsencode.c - CMS encoding
+ ************************************************************************/
+
+/*
+ * NSS_CMSEncoder_Start - set up encoding of a CMS message
+ *
+ * "cmsg" - message to encode
+ * "outputfn", "outputarg" - callback function for delivery of DER-encoded output
+ * will not be called if NULL.
+ * "dest" - if non-NULL, pointer to SECItem that will hold the DER-encoded output
+ * "destpoolp" - pool to allocate DER-encoded output in
+ * "pwfn", pwfn_arg" - callback function for getting token password
+ * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData
+ * "detached_digestalgs", "detached_digests" - digests from detached content
+ */
+extern NSSCMSEncoderContext *
+NSS_CMSEncoder_Start(NSSCMSMessage *cmsg,
+ NSSCMSContentCallback outputfn, void *outputarg,
+ SECItem *dest, PLArenaPool *destpoolp,
+ PK11PasswordFunc pwfn, void *pwfn_arg,
+ NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg,
+ SECAlgorithmID **detached_digestalgs, SECItem **detached_digests);
+
+/*
+ * NSS_CMSEncoder_Update - take content data delivery from the user
+ *
+ * "p7ecx" - encoder context
+ * "data" - content data
+ * "len" - length of content data
+ */
+extern SECStatus
+NSS_CMSEncoder_Update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned long len);
+
+/*
+ * NSS_CMSEncoder_Cancel - stop all encoding
+ */
+extern SECStatus
+NSS_CMSEncoder_Cancel(NSSCMSEncoderContext *p7ecx);
+
+/*
+ * NSS_CMSEncoder_Finish - signal the end of data
+ *
+ * we need to walk down the chain of encoders and the finish them from the innermost out
+ */
+extern SECStatus
+NSS_CMSEncoder_Finish(NSSCMSEncoderContext *p7ecx);
+
+/************************************************************************
+ * cmsmessage.c - CMS message object
+ ************************************************************************/
+
+/*
+ * NSS_CMSMessage_Create - create a CMS message object
+ *
+ * "poolp" - arena to allocate memory from, or NULL if new arena should be created
+ */
+extern NSSCMSMessage *
+NSS_CMSMessage_Create(PLArenaPool *poolp);
+
+/*
+ * NSS_CMSMessage_SetEncodingParams - set up a CMS message object for encoding or decoding
+ *
+ * "cmsg" - message object
+ * "pwfn", pwfn_arg" - callback function for getting token password
+ * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData
+ * "detached_digestalgs", "detached_digests" - digests from detached content
+ *
+ * used internally.
+ */
+extern void
+NSS_CMSMessage_SetEncodingParams(NSSCMSMessage *cmsg,
+ PK11PasswordFunc pwfn, void *pwfn_arg,
+ NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg,
+ SECAlgorithmID **detached_digestalgs, SECItem **detached_digests);
+
+/*
+ * NSS_CMSMessage_Destroy - destroy a CMS message and all of its sub-pieces.
+ */
+extern void
+NSS_CMSMessage_Destroy(NSSCMSMessage *cmsg);
+
+/*
+ * NSS_CMSMessage_Copy - return a copy of the given message.
+ *
+ * The copy may be virtual or may be real -- either way, the result needs
+ * to be passed to NSS_CMSMessage_Destroy later (as does the original).
+ */
+extern NSSCMSMessage *
+NSS_CMSMessage_Copy(NSSCMSMessage *cmsg);
+
+/*
+ * NSS_CMSMessage_GetArena - return a pointer to the message's arena pool
+ */
+extern PLArenaPool *
+NSS_CMSMessage_GetArena(NSSCMSMessage *cmsg);
+
+/*
+ * NSS_CMSMessage_GetContentInfo - return a pointer to the top level contentInfo
+ */
+extern NSSCMSContentInfo *
+NSS_CMSMessage_GetContentInfo(NSSCMSMessage *cmsg);
+
+/*
+ * Return a pointer to the actual content.
+ * In the case of those types which are encrypted, this returns the *plain* content.
+ * In case of nested contentInfos, this descends and retrieves the innermost content.
+ */
+extern SECItem *
+NSS_CMSMessage_GetContent(NSSCMSMessage *cmsg);
+
+/*
+ * NSS_CMSMessage_ContentLevelCount - count number of levels of CMS content objects in this message
+ *
+ * CMS data content objects do not count.
+ */
+extern int
+NSS_CMSMessage_ContentLevelCount(NSSCMSMessage *cmsg);
+
+/*
+ * NSS_CMSMessage_ContentLevel - find content level #n
+ *
+ * CMS data content objects do not count.
+ */
+extern NSSCMSContentInfo *
+NSS_CMSMessage_ContentLevel(NSSCMSMessage *cmsg, int n);
+
+/*
+ * NSS_CMSMessage_ContainsCertsOrCrls - see if message contains certs along the way
+ */
+extern PRBool
+NSS_CMSMessage_ContainsCertsOrCrls(NSSCMSMessage *cmsg);
+
+/*
+ * NSS_CMSMessage_IsEncrypted - see if message contains a encrypted submessage
+ */
+extern PRBool
+NSS_CMSMessage_IsEncrypted(NSSCMSMessage *cmsg);
+
+/*
+ * NSS_CMSMessage_IsSigned - see if message contains a signed submessage
+ *
+ * If the CMS message has a SignedData with a signature (not just a SignedData)
+ * return true; false otherwise. This can/should be called before calling
+ * VerifySignature, which will always indicate failure if no signature is
+ * present, but that does not mean there even was a signature!
+ * Note that the content itself can be empty (detached content was sent
+ * another way); it is the presence of the signature that matters.
+ */
+extern PRBool
+NSS_CMSMessage_IsSigned(NSSCMSMessage *cmsg);
+
+/*
+ * NSS_CMSMessage_IsContentEmpty - see if content is empty
+ *
+ * returns PR_TRUE is innermost content length is < minLen
+ * XXX need the encrypted content length (why?)
+ */
+extern PRBool
+NSS_CMSMessage_IsContentEmpty(NSSCMSMessage *cmsg, unsigned int minLen);
+
+/************************************************************************
+ * cmscinfo.c - CMS contentInfo methods
+ ************************************************************************/
+
+/*
+ * NSS_CMSContentInfo_Destroy - destroy a CMS contentInfo and all of its sub-pieces.
+ */
+extern void
+NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo);
+
+/*
+ * NSS_CMSContentInfo_GetChildContentInfo - get content's contentInfo (if it exists)
+ */
+extern NSSCMSContentInfo *
+NSS_CMSContentInfo_GetChildContentInfo(NSSCMSContentInfo *cinfo);
+
+/*
+ * NSS_CMSContentInfo_SetContent - set cinfo's content type & content to CMS object
+ */
+extern SECStatus
+NSS_CMSContentInfo_SetContent(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECOidTag type, void *ptr);
+
+/*
+ * NSS_CMSContentInfo_SetContent_XXXX - typesafe wrappers for NSS_CMSContentInfo_SetType
+ * set cinfo's content type & content to CMS object
+ */
+extern SECStatus
+NSS_CMSContentInfo_SetContent_Data(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECItem *data, PRBool detached);
+
+extern SECStatus
+NSS_CMSContentInfo_SetContent_SignedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSSignedData *sigd);
+
+extern SECStatus
+NSS_CMSContentInfo_SetContent_EnvelopedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEnvelopedData *envd);
+
+extern SECStatus
+NSS_CMSContentInfo_SetContent_DigestedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSDigestedData *digd);
+
+extern SECStatus
+NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEncryptedData *encd);
+
+/*
+ * turn off streaming for this content type.
+ * This could fail with SEC_ERROR_NO_MEMORY in memory constrained conditions.
+ */
+extern SECStatus
+NSS_CMSContentInfo_SetDontStream(NSSCMSContentInfo *cinfo, PRBool dontStream);
+
+
+/*
+ * NSS_CMSContentInfo_GetContent - get pointer to inner content
+ *
+ * needs to be casted...
+ */
+extern void *
+NSS_CMSContentInfo_GetContent(NSSCMSContentInfo *cinfo);
+
+/*
+ * NSS_CMSContentInfo_GetInnerContent - get pointer to innermost content
+ *
+ * this is typically only called by NSS_CMSMessage_GetContent()
+ */
+extern SECItem *
+NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo);
+
+/*
+ * NSS_CMSContentInfo_GetContentType{Tag,OID} - find out (saving pointer to lookup result
+ * for future reference) and return the inner content type.
+ */
+extern SECOidTag
+NSS_CMSContentInfo_GetContentTypeTag(NSSCMSContentInfo *cinfo);
+
+extern SECItem *
+NSS_CMSContentInfo_GetContentTypeOID(NSSCMSContentInfo *cinfo);
+
+/*
+ * NSS_CMSContentInfo_GetContentEncAlgTag - find out (saving pointer to lookup result
+ * for future reference) and return the content encryption algorithm tag.
+ */
+extern SECOidTag
+NSS_CMSContentInfo_GetContentEncAlgTag(NSSCMSContentInfo *cinfo);
+
+/*
+ * NSS_CMSContentInfo_GetContentEncAlg - find out and return the content encryption algorithm tag.
+ */
+extern SECAlgorithmID *
+NSS_CMSContentInfo_GetContentEncAlg(NSSCMSContentInfo *cinfo);
+
+extern SECStatus
+NSS_CMSContentInfo_SetContentEncAlg(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
+ SECOidTag bulkalgtag, SECItem *parameters, int keysize);
+
+extern SECStatus
+NSS_CMSContentInfo_SetContentEncAlgID(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
+ SECAlgorithmID *algid, int keysize);
+
+extern void
+NSS_CMSContentInfo_SetBulkKey(NSSCMSContentInfo *cinfo, PK11SymKey *bulkkey);
+
+extern PK11SymKey *
+NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo *cinfo);
+
+extern int
+NSS_CMSContentInfo_GetBulkKeySize(NSSCMSContentInfo *cinfo);
+
+/************************************************************************
+ * cmsutil.c - CMS misc utility functions
+ ************************************************************************/
+
+/*
+ * NSS_CMSArray_SortByDER - sort array of objects by objects' DER encoding
+ *
+ * make sure that the order of the objects guarantees valid DER (which must be
+ * in lexigraphically ascending order for a SET OF); if reordering is necessary it
+ * will be done in place (in objs).
+ */
+extern SECStatus
+NSS_CMSArray_SortByDER(void **objs, const SEC_ASN1Template *objtemplate, void **objs2);
+
+/*
+ * NSS_CMSUtil_DERCompare - for use with NSS_CMSArray_Sort to
+ * sort arrays of SECItems containing DER
+ */
+extern int
+NSS_CMSUtil_DERCompare(void *a, void *b);
+
+/*
+ * NSS_CMSAlgArray_GetIndexByAlgID - find a specific algorithm in an array of
+ * algorithms.
+ *
+ * algorithmArray - array of algorithm IDs
+ * algid - algorithmid of algorithm to pick
+ *
+ * Returns:
+ * An integer containing the index of the algorithm in the array or -1 if
+ * algorithm was not found.
+ */
+extern int
+NSS_CMSAlgArray_GetIndexByAlgID(SECAlgorithmID **algorithmArray, SECAlgorithmID *algid);
+
+/*
+ * NSS_CMSAlgArray_GetIndexByAlgID - find a specific algorithm in an array of
+ * algorithms.
+ *
+ * algorithmArray - array of algorithm IDs
+ * algiddata - id of algorithm to pick
+ *
+ * Returns:
+ * An integer containing the index of the algorithm in the array or -1 if
+ * algorithm was not found.
+ */
+extern int
+NSS_CMSAlgArray_GetIndexByAlgTag(SECAlgorithmID **algorithmArray, SECOidTag algtag);
+
+extern const SECHashObject *
+NSS_CMSUtil_GetHashObjByAlgID(SECAlgorithmID *algid);
+
+extern const SEC_ASN1Template *
+NSS_CMSUtil_GetTemplateByTypeTag(SECOidTag type);
+
+extern size_t
+NSS_CMSUtil_GetSizeByTypeTag(SECOidTag type);
+
+extern NSSCMSContentInfo *
+NSS_CMSContent_GetContentInfo(void *msg, SECOidTag type);
+
+extern const char *
+NSS_CMSUtil_VerificationStatusToString(NSSCMSVerificationStatus vs);
+
+/************************************************************************
+ * cmssigdata.c - CMS signedData methods
+ ************************************************************************/
+
+extern NSSCMSSignedData *
+NSS_CMSSignedData_Create(NSSCMSMessage *cmsg);
+
+extern void
+NSS_CMSSignedData_Destroy(NSSCMSSignedData *sigd);
+
+/*
+ * NSS_CMSSignedData_Encode_BeforeStart - do all the necessary things to a SignedData
+ * before start of encoding.
+ *
+ * In detail:
+ * - find out about the right value to put into sigd->version
+ * - come up with a list of digestAlgorithms (which should be the union of the algorithms
+ * in the signerinfos).
+ * If we happen to have a pre-set list of algorithms (and digest values!), we
+ * check if we have all the signerinfos' algorithms. If not, this is an error.
+ */
+extern SECStatus
+NSS_CMSSignedData_Encode_BeforeStart(NSSCMSSignedData *sigd);
+
+extern SECStatus
+NSS_CMSSignedData_Encode_BeforeData(NSSCMSSignedData *sigd);
+
+/*
+ * NSS_CMSSignedData_Encode_AfterData - do all the necessary things to a SignedData
+ * after all the encapsulated data was passed through the encoder.
+ *
+ * In detail:
+ * - create the signatures in all the SignerInfos
+ *
+ * Please note that nothing is done to the Certificates and CRLs in the message - this
+ * is entirely the responsibility of our callers.
+ */
+extern SECStatus
+NSS_CMSSignedData_Encode_AfterData(NSSCMSSignedData *sigd);
+
+extern SECStatus
+NSS_CMSSignedData_Decode_BeforeData(NSSCMSSignedData *sigd);
+
+/*
+ * NSS_CMSSignedData_Decode_AfterData - do all the necessary things to a SignedData
+ * after all the encapsulated data was passed through the decoder.
+ */
+extern SECStatus
+NSS_CMSSignedData_Decode_AfterData(NSSCMSSignedData *sigd);
+
+/*
+ * NSS_CMSSignedData_Decode_AfterEnd - do all the necessary things to a SignedData
+ * after all decoding is finished.
+ */
+extern SECStatus
+NSS_CMSSignedData_Decode_AfterEnd(NSSCMSSignedData *sigd);
+
+/*
+ * NSS_CMSSignedData_GetSignerInfos - retrieve the SignedData's signer list
+ */
+extern NSSCMSSignerInfo **
+NSS_CMSSignedData_GetSignerInfos(NSSCMSSignedData *sigd);
+
+extern int
+NSS_CMSSignedData_SignerInfoCount(NSSCMSSignedData *sigd);
+
+extern NSSCMSSignerInfo *
+NSS_CMSSignedData_GetSignerInfo(NSSCMSSignedData *sigd, int i);
+
+/*
+ * NSS_CMSSignedData_GetDigestAlgs - retrieve the SignedData's digest algorithm list
+ */
+extern SECAlgorithmID **
+NSS_CMSSignedData_GetDigestAlgs(NSSCMSSignedData *sigd);
+
+/*
+ * NSS_CMSSignedData_GetContentInfo - return pointer to this signedData's contentinfo
+ */
+extern NSSCMSContentInfo *
+NSS_CMSSignedData_GetContentInfo(NSSCMSSignedData *sigd);
+
+/*
+ * NSS_CMSSignedData_GetCertificateList - retrieve the SignedData's certificate list
+ */
+extern SECItem **
+NSS_CMSSignedData_GetCertificateList(NSSCMSSignedData *sigd);
+
+extern SECStatus
+NSS_CMSSignedData_ImportCerts(NSSCMSSignedData *sigd, CERTCertDBHandle *certdb,
+ SECCertUsage certusage, PRBool keepcerts);
+
+/*
+ * NSS_CMSSignedData_HasDigests - see if we have digests in place
+ */
+extern PRBool
+NSS_CMSSignedData_HasDigests(NSSCMSSignedData *sigd);
+
+/*
+ * NSS_CMSSignedData_VerifySignerInfo - check a signature.
+ *
+ * The digests were either calculated during decoding (and are stored in the
+ * signedData itself) or set after decoding using NSS_CMSSignedData_SetDigests.
+ *
+ * The verification checks if the signing cert is valid and has a trusted chain
+ * for the purpose specified by "certusage".
+ */
+extern SECStatus
+NSS_CMSSignedData_VerifySignerInfo(NSSCMSSignedData *sigd, int i, CERTCertDBHandle *certdb,
+ SECCertUsage certusage);
+
+/*
+ * NSS_CMSSignedData_VerifyCertsOnly - verify the certs in a certs-only message
+*/
+extern SECStatus
+NSS_CMSSignedData_VerifyCertsOnly(NSSCMSSignedData *sigd,
+ CERTCertDBHandle *certdb,
+ SECCertUsage usage);
+
+extern SECStatus
+NSS_CMSSignedData_AddCertList(NSSCMSSignedData *sigd, CERTCertificateList *certlist);
+
+/*
+ * NSS_CMSSignedData_AddCertChain - add cert and its entire chain to the set of certs
+ */
+extern SECStatus
+NSS_CMSSignedData_AddCertChain(NSSCMSSignedData *sigd, CERTCertificate *cert);
+
+extern SECStatus
+NSS_CMSSignedData_AddCertificate(NSSCMSSignedData *sigd, CERTCertificate *cert);
+
+extern PRBool
+NSS_CMSSignedData_ContainsCertsOrCrls(NSSCMSSignedData *sigd);
+
+extern SECStatus
+NSS_CMSSignedData_AddSignerInfo(NSSCMSSignedData *sigd,
+ NSSCMSSignerInfo *signerinfo);
+
+extern SECStatus
+NSS_CMSSignedData_SetDigests(NSSCMSSignedData *sigd,
+ SECAlgorithmID **digestalgs,
+ SECItem **digests);
+
+extern SECStatus
+NSS_CMSSignedData_SetDigestValue(NSSCMSSignedData *sigd,
+ SECOidTag digestalgtag,
+ SECItem *digestdata);
+
+extern SECStatus
+NSS_CMSSignedData_AddDigest(PLArenaPool *poolp,
+ NSSCMSSignedData *sigd,
+ SECOidTag digestalgtag,
+ SECItem *digest);
+
+extern SECItem *
+NSS_CMSSignedData_GetDigestValue(NSSCMSSignedData *sigd, SECOidTag digestalgtag);
+
+/*
+ * NSS_CMSSignedData_CreateCertsOnly - create a certs-only SignedData.
+ *
+ * cert - base certificates that will be included
+ * include_chain - if true, include the complete cert chain for cert
+ *
+ * More certs and chains can be added via AddCertificate and AddCertChain.
+ *
+ * An error results in a return value of NULL and an error set.
+ */
+extern NSSCMSSignedData *
+NSS_CMSSignedData_CreateCertsOnly(NSSCMSMessage *cmsg, CERTCertificate *cert, PRBool include_chain);
+
+/************************************************************************
+ * cmssiginfo.c - signerinfo methods
+ ************************************************************************/
+
+extern NSSCMSSignerInfo *
+NSS_CMSSignerInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert, SECOidTag digestalgtag);
+extern NSSCMSSignerInfo *
+NSS_CMSSignerInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg, SECItem *subjKeyID, SECKEYPublicKey *pubKey, SECKEYPrivateKey *signingKey, SECOidTag digestalgtag);
+
+/*
+ * NSS_CMSSignerInfo_Destroy - destroy a SignerInfo data structure
+ */
+extern void
+NSS_CMSSignerInfo_Destroy(NSSCMSSignerInfo *si);
+
+/*
+ * NSS_CMSSignerInfo_Sign - sign something
+ *
+ */
+extern SECStatus
+NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *contentType);
+
+extern SECStatus
+NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb,
+ SECCertUsage certusage);
+
+/*
+ * NSS_CMSSignerInfo_Verify - verify the signature of a single SignerInfo
+ *
+ * Just verifies the signature. The assumption is that verification of the certificate
+ * is done already.
+ */
+extern SECStatus
+NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo, SECItem *digest, SECItem *contentType);
+
+extern NSSCMSVerificationStatus
+NSS_CMSSignerInfo_GetVerificationStatus(NSSCMSSignerInfo *signerinfo);
+
+extern SECOidData *
+NSS_CMSSignerInfo_GetDigestAlg(NSSCMSSignerInfo *signerinfo);
+
+extern SECOidTag
+NSS_CMSSignerInfo_GetDigestAlgTag(NSSCMSSignerInfo *signerinfo);
+
+extern int
+NSS_CMSSignerInfo_GetVersion(NSSCMSSignerInfo *signerinfo);
+
+extern CERTCertificateList *
+NSS_CMSSignerInfo_GetCertList(NSSCMSSignerInfo *signerinfo);
+
+/*
+ * NSS_CMSSignerInfo_GetSigningTime - return the signing time,
+ * in UTCTime format, of a CMS signerInfo.
+ *
+ * sinfo - signerInfo data for this signer
+ *
+ * Returns a pointer to XXXX (what?)
+ * A return value of NULL is an error.
+ */
+extern SECStatus
+NSS_CMSSignerInfo_GetSigningTime(NSSCMSSignerInfo *sinfo, PRTime *stime);
+
+/*
+ * Return the signing cert of a CMS signerInfo.
+ *
+ * the certs in the enclosing SignedData must have been imported already
+ */
+extern CERTCertificate *
+NSS_CMSSignerInfo_GetSigningCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb);
+
+/*
+ * NSS_CMSSignerInfo_GetSignerCommonName - return the common name of the signer
+ *
+ * sinfo - signerInfo data for this signer
+ *
+ * Returns a pointer to allocated memory, which must be freed with PORT_Free.
+ * A return value of NULL is an error.
+ */
+extern char *
+NSS_CMSSignerInfo_GetSignerCommonName(NSSCMSSignerInfo *sinfo);
+
+/*
+ * NSS_CMSSignerInfo_GetSignerEmailAddress - return the common name of the signer
+ *
+ * sinfo - signerInfo data for this signer
+ *
+ * Returns a pointer to allocated memory, which must be freed.
+ * A return value of NULL is an error.
+ */
+extern char *
+NSS_CMSSignerInfo_GetSignerEmailAddress(NSSCMSSignerInfo *sinfo);
+
+/*
+ * NSS_CMSSignerInfo_AddAuthAttr - add an attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+extern SECStatus
+NSS_CMSSignerInfo_AddAuthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr);
+
+/*
+ * NSS_CMSSignerInfo_AddUnauthAttr - add an attribute to the
+ * unauthenticated attributes of "signerinfo".
+ */
+extern SECStatus
+NSS_CMSSignerInfo_AddUnauthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr);
+
+/*
+ * NSS_CMSSignerInfo_AddSigningTime - add the signing time to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ *
+ * This is expected to be included in outgoing signed
+ * messages for email (S/MIME) but is likely useful in other situations.
+ *
+ * This should only be added once; a second call will do nothing.
+ *
+ * XXX This will probably just shove the current time into "signerinfo"
+ * but it will not actually get signed until the entire item is
+ * processed for encoding. Is this (expected to be small) delay okay?
+ */
+extern SECStatus
+NSS_CMSSignerInfo_AddSigningTime(NSSCMSSignerInfo *signerinfo, PRTime t);
+
+/*
+ * NSS_CMSSignerInfo_AddSMIMECaps - add a SMIMECapabilities attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ *
+ * This is expected to be included in outgoing signed
+ * messages for email (S/MIME).
+ */
+extern SECStatus
+NSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSignerInfo *signerinfo);
+
+/*
+ * NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ *
+ * This is expected to be included in outgoing signed messages for email (S/MIME).
+ */
+SECStatus
+NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb);
+
+/*
+ * NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo", using the OID preferred by Microsoft.
+ *
+ * This is expected to be included in outgoing signed messages for email (S/MIME),
+ * if compatibility with Microsoft mail clients is wanted.
+ */
+SECStatus
+NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb);
+
+/*
+ * NSS_CMSSignerInfo_AddCounterSignature - countersign a signerinfo
+ */
+/*
+ * NSS_CMSSignerInfo_AddSecureHeader - add Secure Header attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+extern SECStatus
+NSS_CMSSignerInfo_AddSecureHeader(NSSCMSSignerInfo *signerinfo, SecHeaderField * arrayHeaderField, int nbHeaders, long canonAlgo);
+
+/*
+ * NSS_CMSSignerInfo_GetSecureHeader - get S/MIME Secure Header attr value
+ */
+extern SECStatus
+NSS_CMSSignerInfo_GetSecureHeader(NSSCMSSignerInfo *signerinfo, NSSCMSSecureHeader *secuHeaders);
+
+/*
+ * NSS_CMSSignerInfo_AddCounterSignature - countersign a signerinfo
+ */
+extern SECStatus
+NSS_CMSSignerInfo_AddCounterSignature(NSSCMSSignerInfo *signerinfo,
+ SECOidTag digestalg, CERTCertificate signingcert);
+
+/*
+ * XXXX the following needs to be done in the S/MIME layer code
+ * after signature of a signerinfo is verified
+ */
+extern SECStatus
+NSS_SMIMESignerInfo_SaveSMIMEProfile(NSSCMSSignerInfo *signerinfo);
+
+/*
+ * NSS_CMSSignerInfo_IncludeCerts - set cert chain inclusion mode for this signer
+ */
+extern SECStatus
+NSS_CMSSignerInfo_IncludeCerts(NSSCMSSignerInfo *signerinfo, NSSCMSCertChainMode cm, SECCertUsage usage);
+
+/*
+ * NSS_CMSSignerInfo_AddReceiptRequest - add a ReceiptRequest attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+extern SECStatus
+NSS_CMSSignerInfo_AddReceiptRequest(NSSCMSSignerInfo *aSignerinfo,
+ char *aSignedContentIdentifier,
+ char *aReceiptsTo);
+
+/*
+ * NSS_CMSSignerInfo_GetReceiptRequest - get S/MIME ReceiptRequest attr value
+ */
+extern SECStatus
+NSS_CMSSignerInfo_GetReceiptRequest(NSSCMSSignerInfo *aSignerinfo,
+ PRBool *aHasReceiptRequest,
+ unsigned char **aSignedContentIdentifier,
+ unsigned int *aSignedContentIdentifierLen,
+ unsigned int *aReceiptsFrom,
+ char **aReceiptsTo,
+ unsigned char **aOriginatorSignatureValue,
+ unsigned int *aOriginatorSignatureValueLen,
+ unsigned char **aOriginatorContentType,
+ unsigned int *aOriginatorContentTypeLen,
+ unsigned char **aMsgSigDigest,
+ unsigned int *aMsgSigDigestLen);
+
+/*
+ * NSS_CMSSignerInfo_AddMsgSigDigest - add a MsgSigDigest attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+extern SECStatus
+NSS_CMSSignerInfo_AddMsgSigDigest(NSSCMSSignerInfo *aSignerinfo,
+ unsigned char *aReceiptMsgSigDigest,
+ unsigned int aReceiptMsgSigDigestLen);
+
+/*
+ * NSS_CMSSignerInfo_GetMsgSigDigest - get the MsgSigDigest attribute from the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+extern SECStatus
+NSS_CMSSignerInfo_GetMsgSigDigest(NSSCMSSignerInfo *aSignerinfo,
+ unsigned char **aReceiptMsgSigDigest,
+ unsigned int *aReceiptMsgSigDigestLen);
+
+/*
+ * NSS_CMSSignerInfo_HasReceipt - check if signer info's content-type attribute is S/MIME Receipt
+ */
+extern PRBool
+NSS_CMSSignerInfo_HasReceipt(NSSCMSSignerInfo *signerinfo);
+
+/*
+ * NSS_CMSSignerInfo_AddSecurityLabel - add a SecurityLabel attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+extern SECStatus
+NSS_CMSSignerInfo_AddSecurityLabel(NSSCMSSignerInfo *aSignerinfo,
+ char *aSecurityPolicyIdentifier,
+ int aSecurityClassification,
+ char *aPrivacyMark,
+ char *aSecurityCategories);
+
+/*
+ * NSS_CMSSignerInfo_GetSecurityLabel - get S/MIME SecurityLabel attr value
+ */
+extern SECStatus
+NSS_CMSSignerInfo_GetSecurityLabel(NSSCMSSignerInfo *aSignerinfo,
+ PRBool *aHasSecurityLabel,
+ char **aSecurityPolicyIdentifier,
+ int *aSecurityClassification,
+ char **aPrivacyMark,
+ char **aSecurityCategories);
+
+/************************************************************************
+ * cmsenvdata.c - CMS envelopedData methods
+ ************************************************************************/
+
+/*
+ * NSS_CMSEnvelopedData_Create - create an enveloped data message
+ */
+extern NSSCMSEnvelopedData *
+NSS_CMSEnvelopedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize);
+
+/*
+ * NSS_CMSEnvelopedData_Destroy - destroy an enveloped data message
+ */
+extern void
+NSS_CMSEnvelopedData_Destroy(NSSCMSEnvelopedData *edp);
+
+/*
+ * NSS_CMSEnvelopedData_GetContentInfo - return pointer to this envelopedData's contentinfo
+ */
+extern NSSCMSContentInfo *
+NSS_CMSEnvelopedData_GetContentInfo(NSSCMSEnvelopedData *envd);
+
+/*
+ * NSS_CMSEnvelopedData_AddRecipient - add a recipientinfo to the enveloped data msg
+ *
+ * rip must be created on the same pool as edp - this is not enforced, though.
+ */
+extern SECStatus
+NSS_CMSEnvelopedData_AddRecipient(NSSCMSEnvelopedData *edp, NSSCMSRecipientInfo *rip);
+
+/*
+ * NSS_CMSEnvelopedData_Encode_BeforeStart - prepare this envelopedData for encoding
+ *
+ * at this point, we need
+ * - recipientinfos set up with recipient's certificates
+ * - a content encryption algorithm (if none, 3DES will be used)
+ *
+ * this function will generate a random content encryption key (aka bulk key),
+ * initialize the recipientinfos with certificate identification and wrap the bulk key
+ * using the proper algorithm for every certificiate.
+ * it will finally set the bulk algorithm and key so that the encode step can find it.
+ */
+extern SECStatus
+NSS_CMSEnvelopedData_Encode_BeforeStart(NSSCMSEnvelopedData *envd);
+
+/*
+ * NSS_CMSEnvelopedData_Encode_BeforeData - set up encryption
+ */
+extern SECStatus
+NSS_CMSEnvelopedData_Encode_BeforeData(NSSCMSEnvelopedData *envd);
+
+/*
+ * NSS_CMSEnvelopedData_Encode_AfterData - finalize this envelopedData for encoding
+ */
+extern SECStatus
+NSS_CMSEnvelopedData_Encode_AfterData(NSSCMSEnvelopedData *envd);
+
+/*
+ * NSS_CMSEnvelopedData_Decode_BeforeData - find our recipientinfo,
+ * derive bulk key & set up our contentinfo
+ */
+extern SECStatus
+NSS_CMSEnvelopedData_Decode_BeforeData(NSSCMSEnvelopedData *envd);
+
+/*
+ * NSS_CMSEnvelopedData_Decode_AfterData - finish decrypting this envelopedData's content
+ */
+extern SECStatus
+NSS_CMSEnvelopedData_Decode_AfterData(NSSCMSEnvelopedData *envd);
+
+/*
+ * NSS_CMSEnvelopedData_Decode_AfterEnd - finish decoding this envelopedData
+ */
+extern SECStatus
+NSS_CMSEnvelopedData_Decode_AfterEnd(NSSCMSEnvelopedData *envd);
+
+
+/************************************************************************
+ * cmsrecinfo.c - CMS recipientInfo methods
+ ************************************************************************/
+
+/*
+ * NSS_CMSRecipientInfo_Create - create a recipientinfo
+ *
+ * we currently do not create KeyAgreement recipientinfos with multiple recipientEncryptedKeys
+ * the certificate is supposed to have been verified by the caller
+ */
+extern NSSCMSRecipientInfo *
+NSS_CMSRecipientInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert);
+
+extern NSSCMSRecipientInfo *
+NSS_CMSRecipientInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg,
+ SECItem *subjKeyID,
+ SECKEYPublicKey *pubKey);
+
+extern NSSCMSRecipientInfo *
+NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert(NSSCMSMessage *cmsg,
+ CERTCertificate *cert);
+
+/*
+ * NSS_CMSRecipientInfo_CreateNew - create a blank recipientinfo for
+ * applications which want to encode their own CMS structures and
+ * key exchange types.
+ */
+extern NSSCMSRecipientInfo *
+NSS_CMSRecipientInfo_CreateNew(void* pwfn_arg);
+
+/*
+ * NSS_CMSRecipientInfo_CreateFromDER - create a recipientinfo from partially
+ * decoded DER data for applications which want to encode their own CMS
+ * structures and key exchange types.
+ */
+extern NSSCMSRecipientInfo *
+NSS_CMSRecipientInfo_CreateFromDER(SECItem* input, void* pwfn_arg);
+
+extern void
+NSS_CMSRecipientInfo_Destroy(NSSCMSRecipientInfo *ri);
+
+/*
+ * NSS_CMSRecipientInfo_GetCertAndKey - retrieve the cert and key from the
+ * recipientInfo struct. If retcert or retkey are NULL, the cert or
+ * key (respectively) would not be returned). This function is a no-op if both
+ * retcert and retkey are NULL. Caller inherits ownership of the cert and key
+ * he requested (and is responsible to free them).
+ */
+SECStatus NSS_CMSRecipientInfo_GetCertAndKey(NSSCMSRecipientInfo *ri,
+ CERTCertificate** retcert, SECKEYPrivateKey** retkey);
+
+extern int
+NSS_CMSRecipientInfo_GetVersion(NSSCMSRecipientInfo *ri);
+
+extern SECItem *
+NSS_CMSRecipientInfo_GetEncryptedKey(NSSCMSRecipientInfo *ri, int subIndex);
+
+/*
+ * NSS_CMSRecipientInfo_Encode - encode an NSS_CMSRecipientInfo as ASN.1
+ */
+SECStatus NSS_CMSRecipientInfo_Encode(PLArenaPool* poolp,
+ const NSSCMSRecipientInfo *src,
+ SECItem* returned);
+
+extern SECOidTag
+NSS_CMSRecipientInfo_GetKeyEncryptionAlgorithmTag(NSSCMSRecipientInfo *ri);
+
+extern SECStatus
+NSS_CMSRecipientInfo_WrapBulkKey(NSSCMSRecipientInfo *ri, PK11SymKey *bulkkey, SECOidTag bulkalgtag);
+
+extern PK11SymKey *
+NSS_CMSRecipientInfo_UnwrapBulkKey(NSSCMSRecipientInfo *ri, int subIndex,
+ CERTCertificate *cert, SECKEYPrivateKey *privkey, SECOidTag bulkalgtag);
+
+/************************************************************************
+ * cmsencdata.c - CMS encryptedData methods
+ ************************************************************************/
+/*
+ * NSS_CMSEncryptedData_Create - create an empty encryptedData object.
+ *
+ * "algorithm" specifies the bulk encryption algorithm to use.
+ * "keysize" is the key size.
+ *
+ * An error results in a return value of NULL and an error set.
+ * (Retrieve specific errors via PORT_GetError()/XP_GetError().)
+ */
+extern NSSCMSEncryptedData *
+NSS_CMSEncryptedData_Create(NSSCMSMessage *cmsg, SECOidTag algorithm, int keysize);
+
+/*
+ * NSS_CMSEncryptedData_Destroy - destroy an encryptedData object
+ */
+extern void
+NSS_CMSEncryptedData_Destroy(NSSCMSEncryptedData *encd);
+
+/*
+ * NSS_CMSEncryptedData_GetContentInfo - return pointer to encryptedData object's contentInfo
+ */
+extern NSSCMSContentInfo *
+NSS_CMSEncryptedData_GetContentInfo(NSSCMSEncryptedData *encd);
+
+/*
+ * NSS_CMSEncryptedData_Encode_BeforeStart - do all the necessary things to a EncryptedData
+ * before encoding begins.
+ *
+ * In particular:
+ * - set the correct version value.
+ * - get the encryption key
+ */
+extern SECStatus
+NSS_CMSEncryptedData_Encode_BeforeStart(NSSCMSEncryptedData *encd);
+
+/*
+ * NSS_CMSEncryptedData_Encode_BeforeData - set up encryption
+ */
+extern SECStatus
+NSS_CMSEncryptedData_Encode_BeforeData(NSSCMSEncryptedData *encd);
+
+/*
+ * NSS_CMSEncryptedData_Encode_AfterData - finalize this encryptedData for encoding
+ */
+extern SECStatus
+NSS_CMSEncryptedData_Encode_AfterData(NSSCMSEncryptedData *encd);
+
+/*
+ * NSS_CMSEncryptedData_Decode_BeforeData - find bulk key & set up decryption
+ */
+extern SECStatus
+NSS_CMSEncryptedData_Decode_BeforeData(NSSCMSEncryptedData *encd);
+
+/*
+ * NSS_CMSEncryptedData_Decode_AfterData - finish decrypting this encryptedData's content
+ */
+extern SECStatus
+NSS_CMSEncryptedData_Decode_AfterData(NSSCMSEncryptedData *encd);
+
+/*
+ * NSS_CMSEncryptedData_Decode_AfterEnd - finish decoding this encryptedData
+ */
+extern SECStatus
+NSS_CMSEncryptedData_Decode_AfterEnd(NSSCMSEncryptedData *encd);
+
+/************************************************************************
+ * cmsdigdata.c - CMS encryptedData methods
+ ************************************************************************/
+/*
+ * NSS_CMSDigestedData_Create - create a digestedData object (presumably for encoding)
+ *
+ * version will be set by NSS_CMSDigestedData_Encode_BeforeStart
+ * digestAlg is passed as parameter
+ * contentInfo must be filled by the user
+ * digest will be calculated while encoding
+ */
+extern NSSCMSDigestedData *
+NSS_CMSDigestedData_Create(NSSCMSMessage *cmsg, SECAlgorithmID *digestalg);
+
+/*
+ * NSS_CMSDigestedData_Destroy - destroy a digestedData object
+ */
+extern void
+NSS_CMSDigestedData_Destroy(NSSCMSDigestedData *digd);
+
+/*
+ * NSS_CMSDigestedData_GetContentInfo - return pointer to digestedData object's contentInfo
+ */
+extern NSSCMSContentInfo *
+NSS_CMSDigestedData_GetContentInfo(NSSCMSDigestedData *digd);
+
+/*
+ * NSS_CMSDigestedData_Encode_BeforeStart - do all the necessary things to a DigestedData
+ * before encoding begins.
+ *
+ * In particular:
+ * - set the right version number. The contentInfo's content type must be set up already.
+ */
+extern SECStatus
+NSS_CMSDigestedData_Encode_BeforeStart(NSSCMSDigestedData *digd);
+
+/*
+ * NSS_CMSDigestedData_Encode_BeforeData - do all the necessary things to a DigestedData
+ * before the encapsulated data is passed through the encoder.
+ *
+ * In detail:
+ * - set up the digests if necessary
+ */
+extern SECStatus
+NSS_CMSDigestedData_Encode_BeforeData(NSSCMSDigestedData *digd);
+
+/*
+ * NSS_CMSDigestedData_Encode_AfterData - do all the necessary things to a DigestedData
+ * after all the encapsulated data was passed through the encoder.
+ *
+ * In detail:
+ * - finish the digests
+ */
+extern SECStatus
+NSS_CMSDigestedData_Encode_AfterData(NSSCMSDigestedData *digd);
+
+/*
+ * NSS_CMSDigestedData_Decode_BeforeData - do all the necessary things to a DigestedData
+ * before the encapsulated data is passed through the encoder.
+ *
+ * In detail:
+ * - set up the digests if necessary
+ */
+extern SECStatus
+NSS_CMSDigestedData_Decode_BeforeData(NSSCMSDigestedData *digd);
+
+/*
+ * NSS_CMSDigestedData_Decode_AfterData - do all the necessary things to a DigestedData
+ * after all the encapsulated data was passed through the encoder.
+ *
+ * In detail:
+ * - finish the digests
+ */
+extern SECStatus
+NSS_CMSDigestedData_Decode_AfterData(NSSCMSDigestedData *digd);
+
+/*
+ * NSS_CMSDigestedData_Decode_AfterEnd - finalize a digestedData.
+ *
+ * In detail:
+ * - check the digests for equality
+ */
+extern SECStatus
+NSS_CMSDigestedData_Decode_AfterEnd(NSSCMSDigestedData *digd);
+
+/************************************************************************
+ * cmsdigest.c - digestion routines
+ ************************************************************************/
+
+/*
+ * NSS_CMSDigestContext_StartMultiple - start digest calculation using all the
+ * digest algorithms in "digestalgs" in parallel.
+ */
+extern NSSCMSDigestContext *
+NSS_CMSDigestContext_StartMultiple(SECAlgorithmID **digestalgs);
+
+/*
+ * NSS_CMSDigestContext_StartSingle - same as NSS_CMSDigestContext_StartMultiple, but
+ * only one algorithm.
+ */
+extern NSSCMSDigestContext *
+NSS_CMSDigestContext_StartSingle(SECAlgorithmID *digestalg);
+
+/*
+ * NSS_CMSDigestContext_Update - feed more data into the digest machine
+ */
+extern void
+NSS_CMSDigestContext_Update(NSSCMSDigestContext *cmsdigcx, const unsigned char *data, int len);
+
+/*
+ * NSS_CMSDigestContext_Cancel - cancel digesting operation
+ */
+extern void
+NSS_CMSDigestContext_Cancel(NSSCMSDigestContext *cmsdigcx);
+
+/*
+ * NSS_CMSDigestContext_FinishMultiple - finish the digests and put them
+ * into an array of SECItems (allocated on poolp)
+ */
+extern SECStatus
+NSS_CMSDigestContext_FinishMultiple(NSSCMSDigestContext *cmsdigcx, PLArenaPool *poolp,
+ SECItem ***digestsp);
+
+/*
+ * NSS_CMSDigestContext_FinishSingle - same as NSS_CMSDigestContext_FinishMultiple,
+ * but for one digest.
+ */
+extern SECStatus
+NSS_CMSDigestContext_FinishSingle(NSSCMSDigestContext *cmsdigcx, PLArenaPool *poolp,
+ SECItem *digest);
+
+/************************************************************************
+ *
+ ************************************************************************/
+
+/* shortcuts for basic use */
+
+/*
+ * NSS_CMSDEREncode - DER Encode a CMS message, with input being
+ * the plaintext message and derOut being the output,
+ * stored in arena's pool.
+ */
+extern SECStatus
+NSS_CMSDEREncode(NSSCMSMessage *cmsg, SECItem *input, SECItem *derOut,
+ PLArenaPool *arena);
+
+
+/************************************************************************
+ *
+ ************************************************************************/
+
+/*
+ * define new S/MIME content type entries
+ *
+ * S/MIME uses the builtin PKCS7 oid types for encoding and decoding the
+ * various S/MIME content. Some applications have their own content type
+ * which is different from the standard content type defined by S/MIME.
+ *
+ * This function allows you to register new content types. There are basically
+ * Two different types of content, Wrappping content, and Data.
+ *
+ * For data types, All the functions below can be zero or NULL excext
+ * type and is isData, which should be your oid tag and PR_FALSE respectively
+ *
+ * For wrapping types, everything must be provided, or you will get encoder
+ * failures.
+ *
+ * If NSS doesn't already define the OID that you need, you can register
+ * your own with SECOID_AddEntry.
+ *
+ * Once you have defined your new content type, you can pass your new content
+ * type to NSS_CMSContentInfo_SetContent().
+ *
+ * If you are using a wrapping type you can pass your own data structure in
+ * the ptr field, but it must contain and embedded NSSCMSGenericWrappingData
+ * structure as the first element. The size you pass to
+ * NSS_CMSType_RegisterContentType is the total size of your self defined
+ * data structure. NSS_CMSContentInfo_GetContent will return that data
+ * structure from the content info. Your ASN1Template will be evaluated
+ * against that data structure.
+ */
+SECStatus NSS_CMSType_RegisterContentType(SECOidTag type,
+ SEC_ASN1Template *asn1Template, size_t size,
+ NSSCMSGenericWrapperDataDestroy destroy,
+ NSSCMSGenericWrapperDataCallback decode_before,
+ NSSCMSGenericWrapperDataCallback decode_after,
+ NSSCMSGenericWrapperDataCallback decode_end,
+ NSSCMSGenericWrapperDataCallback encode_start,
+ NSSCMSGenericWrapperDataCallback encode_before,
+ NSSCMSGenericWrapperDataCallback encode_after,
+ PRBool isData);
+
+/************************************************************************/
+SEC_END_PROTOS
+
+#endif /* _CMS_H_ */
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * CMS ASN.1 templates
+ *
+ * $Id: cmsasn1.c,v 1.12 2012/12/13 22:46:04 wtc%google.com Exp $
+ */
+
+#include "cmslocal.h"
+
+#include "cert.h"
+#include "key.h"
+#include "secasn1.h"
+#include "secitem.h"
+#include "secoid.h"
+#include "prtime.h"
+#include "secerr.h"
+
+
+extern const SEC_ASN1Template nss_cms_set_of_attribute_template[];
+
+SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate)
+SEC_ASN1_MKSUB(CERT_SetOfSignedCrlTemplate)
+SEC_ASN1_MKSUB(SECOID_AlgorithmIDTemplate)
+SEC_ASN1_MKSUB(SEC_BitStringTemplate)
+SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
+SEC_ASN1_MKSUB(SEC_PointerToOctetStringTemplate)
+SEC_ASN1_MKSUB(SEC_SetOfAnyTemplate)
+
+/* -----------------------------------------------------------------------------
+ * MESSAGE
+ * (uses NSSCMSContentInfo)
+ */
+
+/* forward declaration */
+static const SEC_ASN1Template *
+nss_cms_choose_content_template(void *src_or_dest, PRBool encoding);
+
+static const SEC_ASN1TemplateChooserPtr nss_cms_chooser
+ = nss_cms_choose_content_template;
+
+static const SEC_ASN1Template *
+nss_cms_choose_raw_content_template(void *src_or_dest, PRBool encoding);
+
+static const SEC_ASN1TemplateChooserPtr nss_cms_raw_content_chooser
+ = nss_cms_choose_raw_content_template;
+
+const SEC_ASN1Template NSSCMSMessageTemplate[] = {
+ { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
+ 0, NULL, sizeof(NSSCMSMessage) },
+ { SEC_ASN1_OBJECT_ID,
+ offsetof(NSSCMSMessage,contentInfo.contentType) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_DYNAMIC | SEC_ASN1_MAY_STREAM
+ | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(NSSCMSMessage,contentInfo.content),
+ &nss_cms_chooser },
+ { 0 }
+};
+
+static const SEC_ASN1Template NSS_PointerToCMSMessageTemplate[] = {
+ { SEC_ASN1_POINTER, 0, NSSCMSMessageTemplate }
+};
+
+/* -----------------------------------------------------------------------------
+ * ENCAPSULATED & ENCRYPTED CONTENTINFO
+ * (both use a NSSCMSContentInfo)
+ */
+static const SEC_ASN1Template NSSCMSEncapsulatedContentInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
+ 0, NULL, sizeof(NSSCMSContentInfo) },
+ { SEC_ASN1_OBJECT_ID,
+ offsetof(NSSCMSContentInfo,contentType) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_EXPLICIT | SEC_ASN1_MAY_STREAM |
+ SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
+ offsetof(NSSCMSContentInfo,rawContent),
+ SEC_ASN1_SUB(SEC_PointerToOctetStringTemplate) },
+ { 0 }
+};
+
+static const SEC_ASN1Template NSSCMSEncryptedContentInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
+ 0, NULL, sizeof(NSSCMSContentInfo) },
+ { SEC_ASN1_OBJECT_ID,
+ offsetof(NSSCMSContentInfo,contentType) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
+ offsetof(NSSCMSContentInfo,contentEncAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_MAY_STREAM |
+ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
+ offsetof(NSSCMSContentInfo,rawContent),
+ SEC_ASN1_SUB(SEC_OctetStringTemplate) },
+ { 0 }
+};
+
+/* -----------------------------------------------------------------------------
+ * SIGNED DATA
+ */
+
+const SEC_ASN1Template NSSCMSSignerInfoTemplate[];
+
+const SEC_ASN1Template NSSCMSSignedDataTemplate[] = {
+ { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
+ 0, NULL, sizeof(NSSCMSSignedData) },
+ { SEC_ASN1_INTEGER,
+ offsetof(NSSCMSSignedData,version) },
+ { SEC_ASN1_SET_OF | SEC_ASN1_XTRN,
+ offsetof(NSSCMSSignedData,digestAlgorithms),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_INLINE,
+ offsetof(NSSCMSSignedData,contentInfo),
+ NSSCMSEncapsulatedContentInfoTemplate },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
+ SEC_ASN1_XTRN | 0,
+ offsetof(NSSCMSSignedData,rawCerts),
+ SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
+ SEC_ASN1_XTRN | 1,
+ offsetof(NSSCMSSignedData,crls),
+ SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) },
+ { SEC_ASN1_SET_OF,
+ offsetof(NSSCMSSignedData,signerInfos),
+ NSSCMSSignerInfoTemplate },
+ { 0 }
+};
+
+const SEC_ASN1Template NSS_PointerToCMSSignedDataTemplate[] = {
+ { SEC_ASN1_POINTER, 0, NSSCMSSignedDataTemplate }
+};
+
+/* -----------------------------------------------------------------------------
+ * signeridentifier
+ */
+
+static const SEC_ASN1Template NSSCMSSignerIdentifierTemplate[] = {
+ { SEC_ASN1_CHOICE,
+ offsetof(NSSCMSSignerIdentifier,identifierType), NULL,
+ sizeof(NSSCMSSignerIdentifier) },
+ { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
+ offsetof(NSSCMSSignerIdentifier,id.subjectKeyID),
+ SEC_ASN1_SUB(SEC_OctetStringTemplate) ,
+ NSSCMSRecipientID_SubjectKeyID },
+ { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
+ offsetof(NSSCMSSignerIdentifier,id.issuerAndSN),
+ SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
+ NSSCMSRecipientID_IssuerSN },
+ { 0 }
+};
+
+/* -----------------------------------------------------------------------------
+ * signerinfo
+ */
+
+const SEC_ASN1Template NSSCMSSignerInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSCMSSignerInfo) },
+ { SEC_ASN1_INTEGER,
+ offsetof(NSSCMSSignerInfo,version) },
+ { SEC_ASN1_INLINE,
+ offsetof(NSSCMSSignerInfo,signerIdentifier),
+ NSSCMSSignerIdentifierTemplate },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
+ offsetof(NSSCMSSignerInfo,digestAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(NSSCMSSignerInfo,authAttr),
+ nss_cms_set_of_attribute_template },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
+ offsetof(NSSCMSSignerInfo,digestEncAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(NSSCMSSignerInfo,encDigest) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
+ offsetof(NSSCMSSignerInfo,unAuthAttr),
+ nss_cms_set_of_attribute_template },
+ { 0 }
+};
+
+/* -----------------------------------------------------------------------------
+ * ENVELOPED DATA
+ */
+
+static const SEC_ASN1Template NSSCMSOriginatorInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSCMSOriginatorInfo) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
+ SEC_ASN1_XTRN | 0,
+ offsetof(NSSCMSOriginatorInfo,rawCerts),
+ SEC_ASN1_SUB(SEC_SetOfAnyTemplate) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
+ SEC_ASN1_XTRN | 1,
+ offsetof(NSSCMSOriginatorInfo,crls),
+ SEC_ASN1_SUB(CERT_SetOfSignedCrlTemplate) },
+ { 0 }
+};
+
+const SEC_ASN1Template NSSCMSRecipientInfoTemplate[];
+
+const SEC_ASN1Template NSSCMSEnvelopedDataTemplate[] = {
+ { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
+ 0, NULL, sizeof(NSSCMSEnvelopedData) },
+ { SEC_ASN1_INTEGER,
+ offsetof(NSSCMSEnvelopedData,version) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_POINTER | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(NSSCMSEnvelopedData,originatorInfo),
+ NSSCMSOriginatorInfoTemplate },
+ { SEC_ASN1_SET_OF,
+ offsetof(NSSCMSEnvelopedData,recipientInfos),
+ NSSCMSRecipientInfoTemplate },
+ { SEC_ASN1_INLINE,
+ offsetof(NSSCMSEnvelopedData,contentInfo),
+ NSSCMSEncryptedContentInfoTemplate },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
+ offsetof(NSSCMSEnvelopedData,unprotectedAttr),
+ nss_cms_set_of_attribute_template },
+ { 0 }
+};
+
+const SEC_ASN1Template NSS_PointerToCMSEnvelopedDataTemplate[] = {
+ { SEC_ASN1_POINTER, 0, NSSCMSEnvelopedDataTemplate }
+};
+
+/* here come the 15 gazillion templates for all the v3 varieties of RecipientInfo */
+
+/* -----------------------------------------------------------------------------
+ * key transport recipient info
+ */
+
+static const SEC_ASN1Template NSSCMSRecipientIdentifierTemplate[] = {
+ { SEC_ASN1_CHOICE,
+ offsetof(NSSCMSRecipientIdentifier,identifierType), NULL,
+ sizeof(NSSCMSRecipientIdentifier) },
+ { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0,
+ offsetof(NSSCMSRecipientIdentifier,id.subjectKeyID),
+ SEC_ASN1_SUB(SEC_OctetStringTemplate) ,
+ NSSCMSRecipientID_SubjectKeyID },
+ { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
+ offsetof(NSSCMSRecipientIdentifier,id.issuerAndSN),
+ SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
+ NSSCMSRecipientID_IssuerSN },
+ { 0 }
+};
+
+
+static const SEC_ASN1Template NSSCMSKeyTransRecipientInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSCMSKeyTransRecipientInfo) },
+ { SEC_ASN1_INTEGER,
+ offsetof(NSSCMSKeyTransRecipientInfo,version) },
+ { SEC_ASN1_INLINE,
+ offsetof(NSSCMSKeyTransRecipientInfo,recipientIdentifier),
+ NSSCMSRecipientIdentifierTemplate },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
+ offsetof(NSSCMSKeyTransRecipientInfo,keyEncAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(NSSCMSKeyTransRecipientInfo,encKey) },
+ { 0 }
+};
+
+/* -----------------------------------------------------------------------------
+ * key agreement recipient info
+ */
+
+static const SEC_ASN1Template NSSCMSOriginatorPublicKeyTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSCMSOriginatorPublicKey) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
+ offsetof(NSSCMSOriginatorPublicKey,algorithmIdentifier),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
+ offsetof(NSSCMSOriginatorPublicKey,publicKey),
+ SEC_ASN1_SUB(SEC_BitStringTemplate) },
+ { 0 }
+};
+
+
+static const SEC_ASN1Template NSSCMSOriginatorIdentifierOrKeyTemplate[] = {
+ { SEC_ASN1_CHOICE,
+ offsetof(NSSCMSOriginatorIdentifierOrKey,identifierType), NULL,
+ sizeof(NSSCMSOriginatorIdentifierOrKey) },
+ { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
+ offsetof(NSSCMSOriginatorIdentifierOrKey,id.issuerAndSN),
+ SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
+ NSSCMSOriginatorIDOrKey_IssuerSN },
+ { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC |
+ SEC_ASN1_XTRN | 1,
+ offsetof(NSSCMSOriginatorIdentifierOrKey,id.subjectKeyID),
+ SEC_ASN1_SUB(SEC_PointerToOctetStringTemplate) ,
+ NSSCMSOriginatorIDOrKey_SubjectKeyID },
+ { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
+ offsetof(NSSCMSOriginatorIdentifierOrKey,id.originatorPublicKey),
+ NSSCMSOriginatorPublicKeyTemplate,
+ NSSCMSOriginatorIDOrKey_OriginatorPublicKey },
+ { 0 }
+};
+
+const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSCMSRecipientKeyIdentifier) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(NSSCMSRecipientKeyIdentifier,subjectKeyIdentifier) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
+ offsetof(NSSCMSRecipientKeyIdentifier,date) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
+ offsetof(NSSCMSRecipientKeyIdentifier,other) },
+ { 0 }
+};
+
+
+static const SEC_ASN1Template NSSCMSKeyAgreeRecipientIdentifierTemplate[] = {
+ { SEC_ASN1_CHOICE,
+ offsetof(NSSCMSKeyAgreeRecipientIdentifier,identifierType), NULL,
+ sizeof(NSSCMSKeyAgreeRecipientIdentifier) },
+ { SEC_ASN1_POINTER | SEC_ASN1_XTRN,
+ offsetof(NSSCMSKeyAgreeRecipientIdentifier,id.issuerAndSN),
+ SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
+ NSSCMSKeyAgreeRecipientID_IssuerSN },
+ { SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(NSSCMSKeyAgreeRecipientIdentifier,id.recipientKeyIdentifier),
+ NSSCMSRecipientKeyIdentifierTemplate,
+ NSSCMSKeyAgreeRecipientID_RKeyID },
+ { 0 }
+};
+
+static const SEC_ASN1Template NSSCMSRecipientEncryptedKeyTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSCMSRecipientEncryptedKey) },
+ { SEC_ASN1_INLINE,
+ offsetof(NSSCMSRecipientEncryptedKey,recipientIdentifier),
+ NSSCMSKeyAgreeRecipientIdentifierTemplate },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
+ offsetof(NSSCMSRecipientEncryptedKey,encKey),
+ SEC_ASN1_SUB(SEC_BitStringTemplate) },
+ { 0 }
+};
+
+static const SEC_ASN1Template NSSCMSKeyAgreeRecipientInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSCMSKeyAgreeRecipientInfo) },
+ { SEC_ASN1_INTEGER,
+ offsetof(NSSCMSKeyAgreeRecipientInfo,version) },
+ { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 0,
+ offsetof(NSSCMSKeyAgreeRecipientInfo,originatorIdentifierOrKey),
+ NSSCMSOriginatorIdentifierOrKeyTemplate },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_EXPLICIT |
+ SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 1,
+ offsetof(NSSCMSKeyAgreeRecipientInfo,ukm),
+ SEC_ASN1_SUB(SEC_OctetStringTemplate) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
+ offsetof(NSSCMSKeyAgreeRecipientInfo,keyEncAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_SEQUENCE_OF,
+ offsetof(NSSCMSKeyAgreeRecipientInfo,recipientEncryptedKeys),
+ NSSCMSRecipientEncryptedKeyTemplate },
+ { 0 }
+};
+
+/* -----------------------------------------------------------------------------
+ * KEK recipient info
+ */
+
+static const SEC_ASN1Template NSSCMSKEKIdentifierTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSCMSKEKIdentifier) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(NSSCMSKEKIdentifier,keyIdentifier) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
+ offsetof(NSSCMSKEKIdentifier,date) },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_OCTET_STRING,
+ offsetof(NSSCMSKEKIdentifier,other) },
+ { 0 }
+};
+
+static const SEC_ASN1Template NSSCMSKEKRecipientInfoTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSCMSKEKRecipientInfo) },
+ { SEC_ASN1_INTEGER,
+ offsetof(NSSCMSKEKRecipientInfo,version) },
+ { SEC_ASN1_INLINE,
+ offsetof(NSSCMSKEKRecipientInfo,kekIdentifier),
+ NSSCMSKEKIdentifierTemplate },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
+ offsetof(NSSCMSKEKRecipientInfo,keyEncAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(NSSCMSKEKRecipientInfo,encKey) },
+ { 0 }
+};
+
+/* -----------------------------------------------------------------------------
+ * recipient info
+ */
+const SEC_ASN1Template NSSCMSRecipientInfoTemplate[] = {
+ { SEC_ASN1_CHOICE,
+ offsetof(NSSCMSRecipientInfo,recipientInfoType), NULL,
+ sizeof(NSSCMSRecipientInfo) },
+ { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
+ offsetof(NSSCMSRecipientInfo,ri.keyAgreeRecipientInfo),
+ NSSCMSKeyAgreeRecipientInfoTemplate,
+ NSSCMSRecipientInfoID_KeyAgree },
+ { SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 2,
+ offsetof(NSSCMSRecipientInfo,ri.kekRecipientInfo),
+ NSSCMSKEKRecipientInfoTemplate,
+ NSSCMSRecipientInfoID_KEK },
+ { SEC_ASN1_INLINE,
+ offsetof(NSSCMSRecipientInfo,ri.keyTransRecipientInfo),
+ NSSCMSKeyTransRecipientInfoTemplate,
+ NSSCMSRecipientInfoID_KeyTrans },
+ { 0 }
+};
+
+/* -----------------------------------------------------------------------------
+ *
+ */
+
+const SEC_ASN1Template NSSCMSDigestedDataTemplate[] = {
+ { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
+ 0, NULL, sizeof(NSSCMSDigestedData) },
+ { SEC_ASN1_INTEGER,
+ offsetof(NSSCMSDigestedData,version) },
+ { SEC_ASN1_INLINE | SEC_ASN1_XTRN,
+ offsetof(NSSCMSDigestedData,digestAlg),
+ SEC_ASN1_SUB(SECOID_AlgorithmIDTemplate) },
+ { SEC_ASN1_INLINE,
+ offsetof(NSSCMSDigestedData,contentInfo),
+ NSSCMSEncapsulatedContentInfoTemplate },
+ { SEC_ASN1_OCTET_STRING,
+ offsetof(NSSCMSDigestedData,digest) },
+ { 0 }
+};
+
+const SEC_ASN1Template NSS_PointerToCMSDigestedDataTemplate[] = {
+ { SEC_ASN1_POINTER, 0, NSSCMSDigestedDataTemplate }
+};
+
+const SEC_ASN1Template NSSCMSEncryptedDataTemplate[] = {
+ { SEC_ASN1_SEQUENCE | SEC_ASN1_MAY_STREAM,
+ 0, NULL, sizeof(NSSCMSEncryptedData) },
+ { SEC_ASN1_INTEGER,
+ offsetof(NSSCMSEncryptedData,version) },
+ { SEC_ASN1_INLINE,
+ offsetof(NSSCMSEncryptedData,contentInfo),
+ NSSCMSEncryptedContentInfoTemplate },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_CONSTRUCTED | SEC_ASN1_CONTEXT_SPECIFIC | 1,
+ offsetof(NSSCMSEncryptedData,unprotectedAttr),
+ nss_cms_set_of_attribute_template },
+ { 0 }
+};
+
+const SEC_ASN1Template NSS_PointerToCMSEncryptedDataTemplate[] = {
+ { SEC_ASN1_POINTER, 0, NSSCMSEncryptedDataTemplate }
+};
+
+const SEC_ASN1Template NSSCMSGenericWrapperDataTemplate[] = {
+ { SEC_ASN1_INLINE,
+ offsetof(NSSCMSGenericWrapperData,contentInfo),
+ NSSCMSEncapsulatedContentInfoTemplate },
+};
+
+SEC_ASN1_CHOOSER_IMPLEMENT(NSSCMSGenericWrapperDataTemplate);
+
+const SEC_ASN1Template NSS_PointerToCMSGenericWrapperDataTemplate[] = {
+ { SEC_ASN1_POINTER, 0, NSSCMSGenericWrapperDataTemplate }
+};
+
+SEC_ASN1_CHOOSER_IMPLEMENT(NSS_PointerToCMSGenericWrapperDataTemplate);
+
+/* -----------------------------------------------------------------------------
+ *
+ */
+static const SEC_ASN1Template *
+nss_cms_choose_content_template(void *src_or_dest, PRBool encoding)
+{
+ const SEC_ASN1Template *theTemplate;
+ NSSCMSContentInfo *cinfo;
+ SECOidTag type;
+
+ PORT_Assert (src_or_dest != NULL);
+ if (src_or_dest == NULL)
+ return NULL;
+
+ cinfo = (NSSCMSContentInfo *)src_or_dest;
+ type = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
+ switch (type) {
+ default:
+ theTemplate = NSS_CMSType_GetTemplate(type);
+ break;
+ case SEC_OID_PKCS7_DATA:
+ theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate);
+ break;
+ case SEC_OID_PKCS7_SIGNED_DATA:
+ theTemplate = NSS_PointerToCMSSignedDataTemplate;
+ break;
+ case SEC_OID_PKCS7_ENVELOPED_DATA:
+ theTemplate = NSS_PointerToCMSEnvelopedDataTemplate;
+ break;
+ case SEC_OID_PKCS7_DIGESTED_DATA:
+ theTemplate = NSS_PointerToCMSDigestedDataTemplate;
+ break;
+ case SEC_OID_PKCS7_ENCRYPTED_DATA:
+ theTemplate = NSS_PointerToCMSEncryptedDataTemplate;
+ break;
+ }
+ return theTemplate;
+}
+
+static const SEC_ASN1Template *
+nss_cms_choose_raw_content_template(void *src_or_dest, PRBool encoding)
+{
+ const SEC_ASN1Template *theTemplate;
+ NSSCMSContentInfo *cinfo;
+
+ PORT_Assert (src_or_dest != NULL);
+ if (src_or_dest == NULL)
+ return NULL;
+
+ cinfo = (NSSCMSContentInfo *)src_or_dest;
+ switch (NSS_CMSContentInfo_GetContentTypeTag(cinfo)) {
+ case SEC_OID_PKCS7_DATA:
+ theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate);
+ break;
+ case SEC_OID_SMIME_RECEIPT:
+ theTemplate = SEC_ASN1_GET(SEC_PointerToAnyTemplate);
+ break;
+ default:
+ theTemplate = SEC_ASN1_GET(SEC_PointerToOctetStringTemplate);
+ break;
+ }
+ return theTemplate;
+}
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * CMS contentInfo methods.
+ *
+ * $Id: cmscinfo.c,v 1.11 2012/04/25 14:50:08 gerv%gerv.net Exp $
+ */
+
+#include "cmslocal.h"
+
+#include "pk11func.h"
+#include "secitem.h"
+#include "secoid.h"
+#include "secerr.h"
+
+
+/*
+ * NSS_CMSContentInfo_Create - create a content info
+ *
+ * version is set in the _Finalize procedures for each content type
+ */
+SECStatus
+NSS_CMSContentInfo_Private_Init(NSSCMSContentInfo *cinfo)
+{
+ if (cinfo->privateInfo) {
+ return SECSuccess;
+ }
+ cinfo->privateInfo = PORT_ZNew(NSSCMSContentInfoPrivate);
+ return (cinfo->privateInfo) ? SECSuccess : SECFailure;
+}
+
+
+static void
+nss_cmsContentInfo_private_destroy(NSSCMSContentInfoPrivate *privateInfo)
+{
+ if (privateInfo->digcx) {
+ /* must destroy digest objects */
+ NSS_CMSDigestContext_Cancel(privateInfo->digcx);
+ privateInfo->digcx = NULL;
+ }
+ if (privateInfo->ciphcx) {
+ NSS_CMSCipherContext_Destroy(privateInfo->ciphcx);
+ privateInfo->ciphcx = NULL;
+ }
+ PORT_Free(privateInfo);
+}
+
+/*
+ * NSS_CMSContentInfo_Destroy - destroy a CMS contentInfo and all of its sub-pieces.
+ */
+void
+NSS_CMSContentInfo_Destroy(NSSCMSContentInfo *cinfo)
+{
+ SECOidTag kind;
+
+ kind = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
+ switch (kind) {
+ case SEC_OID_PKCS7_ENVELOPED_DATA:
+ NSS_CMSEnvelopedData_Destroy(cinfo->content.envelopedData);
+ break;
+ case SEC_OID_PKCS7_SIGNED_DATA:
+ NSS_CMSSignedData_Destroy(cinfo->content.signedData);
+ break;
+ case SEC_OID_PKCS7_ENCRYPTED_DATA:
+ NSS_CMSEncryptedData_Destroy(cinfo->content.encryptedData);
+ break;
+ case SEC_OID_PKCS7_DIGESTED_DATA:
+ NSS_CMSDigestedData_Destroy(cinfo->content.digestedData);
+ break;
+ default:
+ NSS_CMSGenericWrapperData_Destroy(kind, cinfo->content.genericData);
+ /* XXX Anything else that needs to be "manually" freed/destroyed? */
+ break;
+ }
+ if (cinfo->privateInfo) {
+ nss_cmsContentInfo_private_destroy(cinfo->privateInfo);
+ cinfo->privateInfo = NULL;
+ }
+ if (cinfo->bulkkey) {
+ PK11_FreeSymKey(cinfo->bulkkey);
+ }
+}
+
+/*
+ * NSS_CMSContentInfo_GetChildContentInfo - get content's contentInfo (if it exists)
+ */
+NSSCMSContentInfo *
+NSS_CMSContentInfo_GetChildContentInfo(NSSCMSContentInfo *cinfo)
+{
+ NSSCMSContentInfo * ccinfo = NULL;
+ SECOidTag tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
+ switch (tag) {
+ case SEC_OID_PKCS7_SIGNED_DATA:
+ if (cinfo->content.signedData != NULL) {
+ ccinfo = &(cinfo->content.signedData->contentInfo);
+ }
+ break;
+ case SEC_OID_PKCS7_ENVELOPED_DATA:
+ if (cinfo->content.envelopedData != NULL) {
+ ccinfo = &(cinfo->content.envelopedData->contentInfo);
+ }
+ break;
+ case SEC_OID_PKCS7_DIGESTED_DATA:
+ if (cinfo->content.digestedData != NULL) {
+ ccinfo = &(cinfo->content.digestedData->contentInfo);
+ }
+ break;
+ case SEC_OID_PKCS7_ENCRYPTED_DATA:
+ if (cinfo->content.encryptedData != NULL) {
+ ccinfo = &(cinfo->content.encryptedData->contentInfo);
+ }
+ break;
+ case SEC_OID_PKCS7_DATA:
+ default:
+ if (NSS_CMSType_IsWrapper(tag)) {
+ if (cinfo->content.genericData != NULL) {
+ ccinfo = &(cinfo->content.genericData->contentInfo);
+ }
+ }
+ break;
+ }
+ if (ccinfo && !ccinfo->privateInfo) {
+ NSS_CMSContentInfo_Private_Init(ccinfo);
+ }
+ return ccinfo;
+}
+
+SECStatus
+NSS_CMSContentInfo_SetDontStream(NSSCMSContentInfo *cinfo, PRBool dontStream)
+{
+ SECStatus rv;
+
+ rv = NSS_CMSContentInfo_Private_Init(cinfo);
+ if (rv != SECSuccess) {
+ /* default is streaming, failure to get ccinfo will not effect this */
+ return dontStream ? SECFailure : SECSuccess ;
+ }
+ cinfo->privateInfo->dontStream = dontStream;
+ return SECSuccess;
+}
+
+/*
+ * NSS_CMSContentInfo_SetContent - set content type & content
+ */
+SECStatus
+NSS_CMSContentInfo_SetContent(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECOidTag type, void *ptr)
+{
+ SECStatus rv;
+
+ cinfo->contentTypeTag = SECOID_FindOIDByTag(type);
+ if (cinfo->contentTypeTag == NULL)
+ return SECFailure;
+
+ /* do not copy the oid, just create a reference */
+ rv = SECITEM_CopyItem (cmsg->poolp, &(cinfo->contentType), &(cinfo->contentTypeTag->oid));
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ cinfo->content.pointer = ptr;
+
+ if (NSS_CMSType_IsData(type) && ptr) {
+ cinfo->rawContent = ptr;
+ } else {
+ /* as we always have some inner data,
+ * we need to set it to something, just to fool the encoder enough to work on it
+ * and get us into nss_cms_encoder_notify at that point */
+ cinfo->rawContent = SECITEM_AllocItem(cmsg->poolp, NULL, 1);
+ if (cinfo->rawContent == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return SECFailure;
+ }
+ }
+
+ return SECSuccess;
+}
+
+/*
+ * NSS_CMSContentInfo_SetContent_XXXX - typesafe wrappers for NSS_CMSContentInfo_SetContent
+ */
+
+/*
+ * data == NULL -> pass in data via NSS_CMSEncoder_Update
+ * data != NULL -> take this data
+ */
+SECStatus
+NSS_CMSContentInfo_SetContent_Data(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, SECItem *data, PRBool detached)
+{
+ if (NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DATA, (void *)data) != SECSuccess)
+ return SECFailure;
+ if (detached) {
+ cinfo->rawContent = NULL;
+ }
+
+ return SECSuccess;
+}
+
+SECStatus
+NSS_CMSContentInfo_SetContent_SignedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSSignedData *sigd)
+{
+ return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_SIGNED_DATA, (void *)sigd);
+}
+
+SECStatus
+NSS_CMSContentInfo_SetContent_EnvelopedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEnvelopedData *envd)
+{
+ return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENVELOPED_DATA, (void *)envd);
+}
+
+SECStatus
+NSS_CMSContentInfo_SetContent_DigestedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSDigestedData *digd)
+{
+ return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_DIGESTED_DATA, (void *)digd);
+}
+
+SECStatus
+NSS_CMSContentInfo_SetContent_EncryptedData(NSSCMSMessage *cmsg, NSSCMSContentInfo *cinfo, NSSCMSEncryptedData *encd)
+{
+ return NSS_CMSContentInfo_SetContent(cmsg, cinfo, SEC_OID_PKCS7_ENCRYPTED_DATA, (void *)encd);
+}
+
+
+/*
+ * NSS_CMSContentInfo_GetContent - get pointer to inner content
+ *
+ * needs to be casted...
+ */
+void *
+NSS_CMSContentInfo_GetContent(NSSCMSContentInfo *cinfo)
+{
+ SECOidTag tag = (cinfo && cinfo->contentTypeTag)
+ ? cinfo->contentTypeTag->offset
+ : SEC_OID_UNKNOWN;
+ switch (tag) {
+ case SEC_OID_PKCS7_DATA:
+ case SEC_OID_SMIME_RECEIPT:
+ case SEC_OID_PKCS7_SIGNED_DATA:
+ case SEC_OID_PKCS7_ENVELOPED_DATA:
+ case SEC_OID_PKCS7_DIGESTED_DATA:
+ case SEC_OID_PKCS7_ENCRYPTED_DATA:
+ return cinfo->content.pointer;
+ default:
+ return NSS_CMSType_IsWrapper(tag) ? cinfo->content.pointer : (NSS_CMSType_IsData(tag) ? cinfo->rawContent : NULL);
+ }
+}
+
+/*
+ * NSS_CMSContentInfo_GetInnerContent - get pointer to innermost content
+ *
+ * this is typically only called by NSS_CMSMessage_GetContent()
+ */
+
+SECItem *
+NSS_CMSContentInfo_GetInnerContent(NSSCMSContentInfo *cinfo)
+{
+ NSSCMSContentInfo *ccinfo;
+ SECOidTag tag;
+ SECItem *pItem = NULL;
+
+ tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
+ if (NSS_CMSType_IsData(tag)) {
+ pItem = cinfo->content.data;
+ } else if (NSS_CMSType_IsWrapper(tag)) {
+ ccinfo = NSS_CMSContentInfo_GetChildContentInfo(cinfo);
+ if (ccinfo != NULL) {
+ pItem = NSS_CMSContentInfo_GetContent(ccinfo);
+ }
+ } else {
+ PORT_Assert(0);
+ }
+
+ return pItem;
+}
+
+
+/*
+ * NSS_CMSContentInfo_GetContentType{Tag,OID} - find out (saving pointer to lookup result
+ * for future reference) and return the inner content type.
+ */
+SECOidTag
+NSS_CMSContentInfo_GetContentTypeTag(NSSCMSContentInfo *cinfo)
+{
+ if (cinfo->contentTypeTag == NULL)
+ cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
+
+ if (cinfo->contentTypeTag == NULL)
+ return SEC_OID_UNKNOWN;
+
+ return cinfo->contentTypeTag->offset;
+}
+
+SECItem *
+NSS_CMSContentInfo_GetContentTypeOID(NSSCMSContentInfo *cinfo)
+{
+ if (cinfo->contentTypeTag == NULL)
+ cinfo->contentTypeTag = SECOID_FindOID(&(cinfo->contentType));
+
+ if (cinfo->contentTypeTag == NULL)
+ return NULL;
+
+ return &(cinfo->contentTypeTag->oid);
+}
+
+/*
+ * NSS_CMSContentInfo_GetContentEncAlgTag - find out (saving pointer to lookup result
+ * for future reference) and return the content encryption algorithm tag.
+ */
+SECOidTag
+NSS_CMSContentInfo_GetContentEncAlgTag(NSSCMSContentInfo *cinfo)
+{
+ if (cinfo->contentEncAlgTag == SEC_OID_UNKNOWN)
+ cinfo->contentEncAlgTag = SECOID_GetAlgorithmTag(&(cinfo->contentEncAlg));
+
+ return cinfo->contentEncAlgTag;
+}
+
+/*
+ * NSS_CMSContentInfo_GetContentEncAlg - find out and return the content encryption algorithm tag.
+ */
+SECAlgorithmID *
+NSS_CMSContentInfo_GetContentEncAlg(NSSCMSContentInfo *cinfo)
+{
+ return &(cinfo->contentEncAlg);
+}
+
+SECStatus
+NSS_CMSContentInfo_SetContentEncAlg(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
+ SECOidTag bulkalgtag, SECItem *parameters, int keysize)
+{
+ SECStatus rv;
+
+ rv = SECOID_SetAlgorithmID(poolp, &(cinfo->contentEncAlg), bulkalgtag, parameters);
+ if (rv != SECSuccess)
+ return SECFailure;
+ cinfo->keysize = keysize;
+ return SECSuccess;
+}
+
+SECStatus
+NSS_CMSContentInfo_SetContentEncAlgID(PLArenaPool *poolp, NSSCMSContentInfo *cinfo,
+ SECAlgorithmID *algid, int keysize)
+{
+ SECStatus rv;
+
+ rv = SECOID_CopyAlgorithmID(poolp, &(cinfo->contentEncAlg), algid);
+ if (rv != SECSuccess)
+ return SECFailure;
+ if (keysize >= 0)
+ cinfo->keysize = keysize;
+ return SECSuccess;
+}
+
+void
+NSS_CMSContentInfo_SetBulkKey(NSSCMSContentInfo *cinfo, PK11SymKey *bulkkey)
+{
+ cinfo->bulkkey = PK11_ReferenceSymKey(bulkkey);
+ cinfo->keysize = PK11_GetKeyStrength(cinfo->bulkkey, &(cinfo->contentEncAlg));
+}
+
+PK11SymKey *
+NSS_CMSContentInfo_GetBulkKey(NSSCMSContentInfo *cinfo)
+{
+ if (cinfo->bulkkey == NULL)
+ return NULL;
+
+ return PK11_ReferenceSymKey(cinfo->bulkkey);
+}
+
+int
+NSS_CMSContentInfo_GetBulkKeySize(NSSCMSContentInfo *cinfo)
+{
+ return cinfo->keysize;
+}
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * CMS decoding.
+ *
+ * $Id: cmsdecode.c,v 1.15 2012/04/25 14:50:08 gerv%gerv.net Exp $
+ */
+
+#include "cmslocal.h"
+
+#include "cert.h"
+#include "key.h"
+#include "secasn1.h"
+#include "secitem.h"
+#include "secoid.h"
+#include "prtime.h"
+#include "secerr.h"
+
+struct NSSCMSDecoderContextStr {
+ SEC_ASN1DecoderContext * dcx; /* ASN.1 decoder context */
+ NSSCMSMessage * cmsg; /* backpointer to the root message */
+ SECOidTag type; /* type of message */
+ NSSCMSContent content; /* pointer to message */
+ NSSCMSDecoderContext * childp7dcx; /* inner CMS decoder context */
+ PRBool saw_contents;
+ int error;
+ NSSCMSContentCallback cb;
+ void * cb_arg;
+ PRBool first_decoded;
+ PRBool need_indefinite_finish;
+};
+
+struct NSSCMSDecoderDataStr {
+ SECItem data; /* must be first */
+ unsigned int totalBufferSize;
+};
+
+typedef struct NSSCMSDecoderDataStr NSSCMSDecoderData;
+
+static void nss_cms_decoder_update_filter (void *arg, const char *data,
+ unsigned long len, int depth, SEC_ASN1EncodingPart data_kind);
+static SECStatus nss_cms_before_data(NSSCMSDecoderContext *p7dcx);
+static SECStatus nss_cms_after_data(NSSCMSDecoderContext *p7dcx);
+static SECStatus nss_cms_after_end(NSSCMSDecoderContext *p7dcx);
+static void nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx,
+ const unsigned char *data, unsigned long len, PRBool final);
+static NSSCMSDecoderData *nss_cms_create_decoder_data(PLArenaPool *poolp);
+
+extern const SEC_ASN1Template NSSCMSMessageTemplate[];
+
+static NSSCMSDecoderData *
+nss_cms_create_decoder_data(PLArenaPool *poolp)
+{
+ NSSCMSDecoderData *decoderData = NULL;
+
+ decoderData = (NSSCMSDecoderData *)
+ PORT_ArenaAlloc(poolp,sizeof(NSSCMSDecoderData));
+ if (!decoderData) {
+ return NULL;
+ }
+ decoderData->data.data = NULL;
+ decoderData->data.len = 0;
+ decoderData->totalBufferSize = 0;
+ return decoderData;
+}
+
+/*
+ * nss_cms_decoder_notify -
+ * this is the driver of the decoding process. It gets called by the ASN.1
+ * decoder before and after an object is decoded.
+ * at various points in the decoding process, we intercept to set up and do
+ * further processing.
+ */
+static void
+nss_cms_decoder_notify(void *arg, PRBool before, void *dest, int depth)
+{
+ NSSCMSDecoderContext *p7dcx;
+ NSSCMSContentInfo *rootcinfo, *cinfo;
+ PRBool after = !before;
+
+ p7dcx = (NSSCMSDecoderContext *)arg;
+ rootcinfo = &(p7dcx->cmsg->contentInfo);
+
+ /* XXX error handling: need to set p7dcx->error */
+
+#ifdef CMSDEBUG
+ fprintf(stderr, "%6.6s, dest = 0x%08x, depth = %d\n", before ? "before" : "after", dest, depth);
+#endif
+
+ /* so what are we working on right now? */
+ if (p7dcx->type == SEC_OID_UNKNOWN) {
+ /*
+ * right now, we are still decoding the OUTER (root) cinfo
+ * As soon as we know the inner content type, set up the info,
+ * but NO inner decoder or filter. The root decoder handles the first
+ * level children by itself - only for encapsulated contents (which
+ * are encoded as DER inside of an OCTET STRING) we need to set up a
+ * child decoder...
+ */
+ if (after && dest == &(rootcinfo->contentType)) {
+ p7dcx->type = NSS_CMSContentInfo_GetContentTypeTag(rootcinfo);
+ p7dcx->content = rootcinfo->content;
+ /* is this ready already ? need to alloc? */
+ /* XXX yes we need to alloc -- continue here */
+ }
+ } else if (NSS_CMSType_IsData(p7dcx->type)) {
+ /* this can only happen if the outermost cinfo has DATA in it */
+ /* otherwise, we handle this type implicitely in the inner decoders */
+
+ if (before && dest == &(rootcinfo->content)) {
+ /* cause the filter to put the data in the right place...
+ ** We want the ASN.1 decoder to deliver the decoded bytes to us
+ ** from now on
+ */
+ SEC_ASN1DecoderSetFilterProc(p7dcx->dcx,
+ nss_cms_decoder_update_filter,
+ p7dcx,
+ (PRBool)(p7dcx->cb != NULL));
+ } else if (after && dest == &(rootcinfo->content.data)) {
+ /* remove the filter */
+ SEC_ASN1DecoderClearFilterProc(p7dcx->dcx);
+ }
+ } else if (NSS_CMSType_IsWrapper(p7dcx->type)) {
+ if (!before || dest != &(rootcinfo->content)) {
+
+ if (p7dcx->content.pointer == NULL)
+ p7dcx->content = rootcinfo->content;
+
+ /* get this data type's inner contentInfo */
+ cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer,
+ p7dcx->type);
+
+ if (before && dest == &(cinfo->contentType)) {
+ /* at this point, set up the &%$&$ back pointer */
+ /* we cannot do it later, because the content itself
+ * is optional! */
+ switch (p7dcx->type) {
+ case SEC_OID_PKCS7_SIGNED_DATA:
+ p7dcx->content.signedData->cmsg = p7dcx->cmsg;
+ break;
+ case SEC_OID_PKCS7_DIGESTED_DATA:
+ p7dcx->content.digestedData->cmsg = p7dcx->cmsg;
+ break;
+ case SEC_OID_PKCS7_ENVELOPED_DATA:
+ p7dcx->content.envelopedData->cmsg = p7dcx->cmsg;
+ break;
+ case SEC_OID_PKCS7_ENCRYPTED_DATA:
+ p7dcx->content.encryptedData->cmsg = p7dcx->cmsg;
+ break;
+ default:
+ p7dcx->content.genericData->cmsg = p7dcx->cmsg;
+ break;
+ }
+ }
+
+ if (before && dest == &(cinfo->rawContent)) {
+ /* we want the ASN.1 decoder to deliver the decoded bytes to us
+ ** from now on
+ */
+ SEC_ASN1DecoderSetFilterProc(p7dcx->dcx,
+ nss_cms_decoder_update_filter,
+ p7dcx, (PRBool)(p7dcx->cb != NULL));
+
+
+ /* we're right in front of the data */
+ if (nss_cms_before_data(p7dcx) != SECSuccess) {
+ SEC_ASN1DecoderClearFilterProc(p7dcx->dcx);
+ /* stop all processing */
+ p7dcx->error = PORT_GetError();
+ }
+ }
+ if (after && dest == &(cinfo->rawContent)) {
+ /* we're right after of the data */
+ if (nss_cms_after_data(p7dcx) != SECSuccess)
+ p7dcx->error = PORT_GetError();
+
+ /* we don't need to see the contents anymore */
+ SEC_ASN1DecoderClearFilterProc(p7dcx->dcx);
+ }
+ }
+ } else {
+ /* unsupported or unknown message type - fail gracefully */
+ p7dcx->error = SEC_ERROR_UNSUPPORTED_MESSAGE_TYPE;
+ }
+}
+
+/*
+ * nss_cms_before_data - set up the current encoder to receive data
+ */
+static SECStatus
+nss_cms_before_data(NSSCMSDecoderContext *p7dcx)
+{
+ SECStatus rv;
+ SECOidTag childtype;
+ PLArenaPool *poolp;
+ NSSCMSDecoderContext *childp7dcx;
+ NSSCMSContentInfo *cinfo;
+ const SEC_ASN1Template *template;
+ void *mark = NULL;
+ size_t size;
+
+ poolp = p7dcx->cmsg->poolp;
+
+ /* call _Decode_BeforeData handlers */
+ switch (p7dcx->type) {
+ case SEC_OID_PKCS7_SIGNED_DATA:
+ /* we're decoding a signedData, so set up the digests */
+ rv = NSS_CMSSignedData_Decode_BeforeData(p7dcx->content.signedData);
+ break;
+ case SEC_OID_PKCS7_DIGESTED_DATA:
+ /* we're encoding a digestedData, so set up the digest */
+ rv = NSS_CMSDigestedData_Decode_BeforeData(p7dcx->content.digestedData);
+ break;
+ case SEC_OID_PKCS7_ENVELOPED_DATA:
+ rv = NSS_CMSEnvelopedData_Decode_BeforeData(
+ p7dcx->content.envelopedData);
+ break;
+ case SEC_OID_PKCS7_ENCRYPTED_DATA:
+ rv = NSS_CMSEncryptedData_Decode_BeforeData(
+ p7dcx->content.encryptedData);
+ break;
+ default:
+ rv = NSS_CMSGenericWrapperData_Decode_BeforeData(p7dcx->type,
+ p7dcx->content.genericData);
+ }
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ /* ok, now we have a pointer to cinfo */
+ /* find out what kind of data is encapsulated */
+
+ cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer, p7dcx->type);
+ childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
+
+ if (NSS_CMSType_IsData(childtype) || childtype == SEC_OID_SMIME_RECEIPT) {
+ cinfo->content.pointer = (void *) nss_cms_create_decoder_data(poolp);
+ if (cinfo->content.pointer == NULL)
+ /* set memory error */
+ return SECFailure;
+
+ p7dcx->childp7dcx = NULL;
+ return SECSuccess;
+ }
+
+ /* set up inner decoder */
+
+ if ((template = NSS_CMSUtil_GetTemplateByTypeTag(childtype)) == NULL)
+ return SECFailure;
+
+ childp7dcx = PORT_ZNew(NSSCMSDecoderContext);
+ if (childp7dcx == NULL)
+ return SECFailure;
+
+ mark = PORT_ArenaMark(poolp);
+
+ /* allocate space for the stuff we're creating */
+ size = NSS_CMSUtil_GetSizeByTypeTag(childtype);
+ childp7dcx->content.pointer = (void *)PORT_ArenaZAlloc(poolp, size);
+ if (childp7dcx->content.pointer == NULL)
+ goto loser;
+
+ /* give the parent a copy of the pointer so that it doesn't get lost */
+ cinfo->content.pointer = childp7dcx->content.pointer;
+
+ /* start the child decoder */
+ childp7dcx->dcx = SEC_ASN1DecoderStart(poolp, childp7dcx->content.pointer,
+ template);
+ if (childp7dcx->dcx == NULL)
+ goto loser;
+
+ /* the new decoder needs to notify, too */
+ SEC_ASN1DecoderSetNotifyProc(childp7dcx->dcx, nss_cms_decoder_notify,
+ childp7dcx);
+
+ /* tell the parent decoder that it needs to feed us the content data */
+ p7dcx->childp7dcx = childp7dcx;
+
+ childp7dcx->type = childtype; /* our type */
+
+ childp7dcx->cmsg = p7dcx->cmsg; /* backpointer to root message */
+
+ /* should the child decoder encounter real data,
+ ** it must give it to the caller
+ */
+ childp7dcx->cb = p7dcx->cb;
+ childp7dcx->cb_arg = p7dcx->cb_arg;
+ childp7dcx->first_decoded = PR_FALSE;
+ childp7dcx->need_indefinite_finish = PR_FALSE;
+ if (childtype == SEC_OID_PKCS7_SIGNED_DATA) {
+ childp7dcx->first_decoded = PR_TRUE;
+ }
+
+ /* now set up the parent to hand decoded data to the next level decoder */
+ p7dcx->cb = (NSSCMSContentCallback)NSS_CMSDecoder_Update;
+ p7dcx->cb_arg = childp7dcx;
+
+ PORT_ArenaUnmark(poolp, mark);
+
+ return SECSuccess;
+
+loser:
+ if (mark)
+ PORT_ArenaRelease(poolp, mark);
+ if (childp7dcx)
+ PORT_Free(childp7dcx);
+ p7dcx->childp7dcx = NULL;
+ return SECFailure;
+}
+
+static SECStatus
+nss_cms_after_data(NSSCMSDecoderContext *p7dcx)
+{
+ NSSCMSDecoderContext *childp7dcx;
+ SECStatus rv = SECFailure;
+
+ /* Handle last block. This is necessary to flush out the last bytes
+ * of a possibly incomplete block */
+ nss_cms_decoder_work_data(p7dcx, NULL, 0, PR_TRUE);
+
+ /* finish any "inner" decoders - there's no more data coming... */
+ if (p7dcx->childp7dcx != NULL) {
+ childp7dcx = p7dcx->childp7dcx;
+ if (childp7dcx->dcx != NULL) {
+ /* we started and indefinite sequence somewhere, not complete it */
+ if (childp7dcx->need_indefinite_finish) {
+ static const char lbuf[2] = { 0, 0 };
+ NSS_CMSDecoder_Update(childp7dcx, lbuf, sizeof(lbuf));
+ childp7dcx->need_indefinite_finish = PR_FALSE;
+ }
+
+ if (SEC_ASN1DecoderFinish(childp7dcx->dcx) != SECSuccess) {
+ /* do what? free content? */
+ rv = SECFailure;
+ } else {
+ rv = nss_cms_after_end(childp7dcx);
+ }
+ if (rv != SECSuccess)
+ goto done;
+ }
+ PORT_Free(p7dcx->childp7dcx);
+ p7dcx->childp7dcx = NULL;
+ }
+
+ switch (p7dcx->type) {
+ case SEC_OID_PKCS7_SIGNED_DATA:
+ /* this will finish the digests and verify */
+ rv = NSS_CMSSignedData_Decode_AfterData(p7dcx->content.signedData);
+ break;
+ case SEC_OID_PKCS7_ENVELOPED_DATA:
+ rv = NSS_CMSEnvelopedData_Decode_AfterData(
+ p7dcx->content.envelopedData);
+ break;
+ case SEC_OID_PKCS7_DIGESTED_DATA:
+ rv = NSS_CMSDigestedData_Decode_AfterData(
+ p7dcx->content.digestedData);
+ break;
+ case SEC_OID_PKCS7_ENCRYPTED_DATA:
+ rv = NSS_CMSEncryptedData_Decode_AfterData(
+ p7dcx->content.encryptedData);
+ break;
+ case SEC_OID_PKCS7_DATA:
+ /* do nothing */
+ break;
+ default:
+ rv = NSS_CMSGenericWrapperData_Decode_AfterData(p7dcx->type,
+ p7dcx->content.genericData);
+ break;
+ }
+done:
+ return rv;
+}
+
+static SECStatus
+nss_cms_after_end(NSSCMSDecoderContext *p7dcx)
+{
+ SECStatus rv = SECSuccess;
+
+ switch (p7dcx->type) {
+ case SEC_OID_PKCS7_SIGNED_DATA:
+ if (p7dcx->content.signedData)
+ rv = NSS_CMSSignedData_Decode_AfterEnd(p7dcx->content.signedData);
+ break;
+ case SEC_OID_PKCS7_ENVELOPED_DATA:
+ if (p7dcx->content.envelopedData)
+ rv = NSS_CMSEnvelopedData_Decode_AfterEnd(
+ p7dcx->content.envelopedData);
+ break;
+ case SEC_OID_PKCS7_DIGESTED_DATA:
+ if (p7dcx->content.digestedData)
+ rv = NSS_CMSDigestedData_Decode_AfterEnd(
+ p7dcx->content.digestedData);
+ break;
+ case SEC_OID_PKCS7_ENCRYPTED_DATA:
+ if (p7dcx->content.encryptedData)
+ rv = NSS_CMSEncryptedData_Decode_AfterEnd(
+ p7dcx->content.encryptedData);
+ break;
+ case SEC_OID_PKCS7_DATA:
+ break;
+ default:
+ rv = NSS_CMSGenericWrapperData_Decode_AfterEnd(p7dcx->type,
+ p7dcx->content.genericData);
+ break;
+ }
+ return rv;
+}
+
+/*
+ * nss_cms_decoder_work_data - handle decoded data bytes.
+ *
+ * This function either decrypts the data if needed, and/or calculates digests
+ * on it, then either stores it or passes it on to the next level decoder.
+ */
+static void
+nss_cms_decoder_work_data(NSSCMSDecoderContext *p7dcx,
+ const unsigned char *data, unsigned long len,
+ PRBool final)
+{
+ NSSCMSContentInfo *cinfo;
+ unsigned char *buf = NULL;
+ unsigned char *dest;
+ unsigned int offset;
+ SECStatus rv;
+
+ /*
+ * We should really have data to process, or we should be trying
+ * to finish/flush the last block. (This is an overly paranoid
+ * check since all callers are in this file and simple inspection
+ * proves they do it right. But it could find a bug in future
+ * modifications/development, that is why it is here.)
+ */
+ PORT_Assert ((data != NULL && len) || final);
+
+ cinfo = NSS_CMSContent_GetContentInfo(p7dcx->content.pointer, p7dcx->type);
+ if (!cinfo) {
+ /* The original programmer didn't expect this to happen */
+ p7dcx->error = SEC_ERROR_LIBRARY_FAILURE;
+ goto loser;
+ }
+
+ if (cinfo->privateInfo && cinfo->privateInfo->ciphcx != NULL) {
+ /*
+ * we are decrypting.
+ *
+ * XXX If we get an error, we do not want to do the digest or callback,
+ * but we want to keep decoding. Or maybe we want to stop decoding
+ * altogether if there is a callback, because obviously we are not
+ * sending the data back and they want to know that.
+ */
+
+ unsigned int outlen = 0; /* length of decrypted data */
+ unsigned int buflen; /* length available for decrypted data */
+
+ /* find out about the length of decrypted data */
+ buflen = NSS_CMSCipherContext_DecryptLength(cinfo->privateInfo->ciphcx, len, final);
+
+ /*
+ * it might happen that we did not provide enough data for a full
+ * block (decryption unit), and that there is no output available
+ */
+
+ /* no output available, AND no input? */
+ if (buflen == 0 && len == 0)
+ goto loser; /* bail out */
+
+ /*
+ * have inner decoder: pass the data on (means inner content type is NOT data)
+ * no inner decoder: we have DATA in here: either call callback or store
+ */
+ if (buflen != 0) {
+ /* there will be some output - need to make room for it */
+ /* allocate buffer from the heap */
+ buf = (unsigned char *)PORT_Alloc(buflen);
+ if (buf == NULL) {
+ p7dcx->error = SEC_ERROR_NO_MEMORY;
+ goto loser;
+ }
+ }
+
+ /*
+ * decrypt incoming data
+ * buf can still be NULL here (and buflen == 0) here if we don't expect
+ * any output (see above), but we still need to call NSS_CMSCipherContext_Decrypt to
+ * keep track of incoming data
+ */
+ rv = NSS_CMSCipherContext_Decrypt(cinfo->privateInfo->ciphcx, buf, &outlen, buflen,
+ data, len, final);
+ if (rv != SECSuccess) {
+ p7dcx->error = PORT_GetError();
+ goto loser;
+ }
+
+ PORT_Assert (final || outlen == buflen);
+
+ /* swap decrypted data in */
+ data = buf;
+ len = outlen;
+ }
+
+ if (len == 0)
+ goto done; /* nothing more to do */
+
+ /*
+ * Update the running digests with plaintext bytes (if we need to).
+ */
+ if (cinfo->privateInfo && cinfo->privateInfo->digcx)
+ NSS_CMSDigestContext_Update(cinfo->privateInfo->digcx, data, len);
+
+ /* at this point, we have the plain decoded & decrypted data
+ ** which is either more encoded DER (which we need to hand to the child
+ ** decoder) or data we need to hand back to our caller
+ */
+
+ /* pass the content back to our caller or */
+ /* feed our freshly decrypted and decoded data into child decoder */
+ if (p7dcx->cb != NULL) {
+ (*p7dcx->cb)(p7dcx->cb_arg, (const char *)data, len);
+ }
+#if 1
+ else
+#endif
+ if (NSS_CMSContentInfo_GetContentTypeTag(cinfo) == SEC_OID_PKCS7_DATA ||
+ NSS_CMSContentInfo_GetContentTypeTag(cinfo) == SEC_OID_SMIME_RECEIPT) {
+ /* store it in "inner" data item as well */
+ /* find the DATA item in the encapsulated cinfo and store it there */
+ NSSCMSDecoderData *decoderData =
+ (NSSCMSDecoderData *)cinfo->content.pointer;
+ SECItem *dataItem = &decoderData->data;
+
+ offset = dataItem->len;
+ if (dataItem->len+len > decoderData->totalBufferSize) {
+ int needLen = (dataItem->len+len) * 2;
+ dest = (unsigned char *)
+ PORT_ArenaAlloc(p7dcx->cmsg->poolp, needLen);
+ if (dest == NULL) {
+ p7dcx->error = SEC_ERROR_NO_MEMORY;
+ goto loser;
+ }
+
+ if (dataItem->len) {
+ PORT_Memcpy(dest, dataItem->data, dataItem->len);
+ }
+ decoderData->totalBufferSize = needLen;
+ dataItem->data = dest;
+ }
+
+ /* copy it in */
+ PORT_Memcpy(dataItem->data + offset, data, len);
+ dataItem->len += len;
+ }
+
+done:
+loser:
+ if (buf)
+ PORT_Free (buf);
+}
+
+/*
+ * nss_cms_decoder_update_filter - process ASN.1 data
+ *
+ * once we have set up a filter in nss_cms_decoder_notify(),
+ * all data processed by the ASN.1 decoder is also passed through here.
+ * we pass the content bytes (as opposed to length and tag bytes) on to
+ * nss_cms_decoder_work_data().
+ */
+static void
+nss_cms_decoder_update_filter (void *arg, const char *data, unsigned long len,
+ int depth, SEC_ASN1EncodingPart data_kind)
+{
+ NSSCMSDecoderContext *p7dcx;
+
+ PORT_Assert (len); /* paranoia */
+ if (len == 0)
+ return;
+
+ p7dcx = (NSSCMSDecoderContext*)arg;
+
+ p7dcx->saw_contents = PR_TRUE;
+
+ /* pass on the content bytes only */
+ if (data_kind == SEC_ASN1_Contents)
+ nss_cms_decoder_work_data(p7dcx, (const unsigned char *) data, len,
+ PR_FALSE);
+}
+
+/*
+ * NSS_CMSDecoder_Start - set up decoding of a DER-encoded CMS message
+ *
+ * "poolp" - pointer to arena for message, or NULL if new pool should be created
+ * "cb", "cb_arg" - callback function and argument for delivery of inner content
+ * "pwfn", pwfn_arg" - callback function for getting token password
+ * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData
+ */
+NSSCMSDecoderContext *
+NSS_CMSDecoder_Start(PLArenaPool *poolp,
+ NSSCMSContentCallback cb, void *cb_arg,
+ PK11PasswordFunc pwfn, void *pwfn_arg,
+ NSSCMSGetDecryptKeyCallback decrypt_key_cb,
+ void *decrypt_key_cb_arg)
+{
+ NSSCMSDecoderContext *p7dcx;
+ NSSCMSMessage *cmsg;
+
+ cmsg = NSS_CMSMessage_Create(poolp);
+ if (cmsg == NULL)
+ return NULL;
+
+ NSS_CMSMessage_SetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb,
+ decrypt_key_cb_arg, NULL, NULL);
+
+ p7dcx = PORT_ZNew(NSSCMSDecoderContext);
+ if (p7dcx == NULL) {
+ NSS_CMSMessage_Destroy(cmsg);
+ return NULL;
+ }
+
+ p7dcx->dcx = SEC_ASN1DecoderStart(cmsg->poolp, cmsg, NSSCMSMessageTemplate);
+ if (p7dcx->dcx == NULL) {
+ PORT_Free (p7dcx);
+ NSS_CMSMessage_Destroy(cmsg);
+ return NULL;
+ }
+
+ SEC_ASN1DecoderSetNotifyProc (p7dcx->dcx, nss_cms_decoder_notify, p7dcx);
+
+ p7dcx->cmsg = cmsg;
+ p7dcx->type = SEC_OID_UNKNOWN;
+
+ p7dcx->cb = cb;
+ p7dcx->cb_arg = cb_arg;
+ p7dcx->first_decoded = PR_FALSE;
+ p7dcx->need_indefinite_finish = PR_FALSE;
+ return p7dcx;
+}
+
+/*
+ * NSS_CMSDecoder_Update - feed DER-encoded data to decoder
+ */
+SECStatus
+NSS_CMSDecoder_Update(NSSCMSDecoderContext *p7dcx, const char *buf,
+ unsigned long len)
+{
+ SECStatus rv = SECSuccess;
+ if (p7dcx->dcx != NULL && p7dcx->error == 0) {
+ /* if error is set already, don't bother */
+ if ((p7dcx->type == SEC_OID_PKCS7_SIGNED_DATA)
+ && (p7dcx->first_decoded==PR_TRUE)
+ && (buf[0] == SEC_ASN1_INTEGER)) {
+ /* Microsoft Windows 2008 left out the Sequence wrapping in some
+ * of their kerberos replies. If we are here, we most likely are
+ * dealing with one of those replies. Supply the Sequence wrap
+ * as indefinite encoding (since we don't know the total length
+ * yet) */
+ static const char lbuf[2] =
+ { SEC_ASN1_SEQUENCE|SEC_ASN1_CONSTRUCTED, 0x80 };
+ rv = SEC_ASN1DecoderUpdate(p7dcx->dcx, lbuf, sizeof(lbuf));
+ if (rv != SECSuccess) {
+ goto loser;
+ }
+ /* ok, we're going to need the indefinite finish when we are done */
+ p7dcx->need_indefinite_finish = PR_TRUE;
+ }
+
+ rv = SEC_ASN1DecoderUpdate(p7dcx->dcx, buf, len);
+ }
+
+loser:
+ p7dcx->first_decoded = PR_FALSE;
+ if (rv != SECSuccess) {
+ p7dcx->error = PORT_GetError();
+ PORT_Assert (p7dcx->error);
+ if (p7dcx->error == 0)
+ p7dcx->error = -1;
+ }
+
+ if (p7dcx->error == 0)
+ return SECSuccess;
+
+ /* there has been a problem, let's finish the decoder */
+ if (p7dcx->dcx != NULL) {
+ (void) SEC_ASN1DecoderFinish (p7dcx->dcx);
+ p7dcx->dcx = NULL;
+ }
+ PORT_SetError (p7dcx->error);
+
+ return SECFailure;
+}
+
+/*
+ * NSS_CMSDecoder_Cancel - stop decoding in case of error
+ */
+void
+NSS_CMSDecoder_Cancel(NSSCMSDecoderContext *p7dcx)
+{
+ if (p7dcx->dcx != NULL)
+ (void)SEC_ASN1DecoderFinish(p7dcx->dcx);
+ NSS_CMSMessage_Destroy(p7dcx->cmsg);
+ PORT_Free(p7dcx);
+}
+
+/*
+ * NSS_CMSDecoder_Finish - mark the end of inner content and finish decoding
+ */
+NSSCMSMessage *
+NSS_CMSDecoder_Finish(NSSCMSDecoderContext *p7dcx)
+{
+ NSSCMSMessage *cmsg;
+
+ cmsg = p7dcx->cmsg;
+
+ if (p7dcx->dcx == NULL ||
+ SEC_ASN1DecoderFinish(p7dcx->dcx) != SECSuccess ||
+ nss_cms_after_end(p7dcx) != SECSuccess)
+ {
+ NSS_CMSMessage_Destroy(cmsg); /* get rid of pool if it's ours */
+ cmsg = NULL;
+ }
+
+ PORT_Free(p7dcx);
+ return cmsg;
+}
+
+NSSCMSMessage *
+NSS_CMSMessage_CreateFromDER(SECItem *DERmessage,
+ NSSCMSContentCallback cb, void *cb_arg,
+ PK11PasswordFunc pwfn, void *pwfn_arg,
+ NSSCMSGetDecryptKeyCallback decrypt_key_cb,
+ void *decrypt_key_cb_arg)
+{
+ NSSCMSDecoderContext *p7dcx;
+
+ /* first arg(poolp) == NULL => create our own pool */
+ p7dcx = NSS_CMSDecoder_Start(NULL, cb, cb_arg, pwfn, pwfn_arg,
+ decrypt_key_cb, decrypt_key_cb_arg);
+ if (p7dcx == NULL)
+ return NULL;
+ NSS_CMSDecoder_Update(p7dcx, (char *)DERmessage->data, DERmessage->len);
+ return NSS_CMSDecoder_Finish(p7dcx);
+}
+
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * CMS encoding.
+ *
+ * $Id: cmsencode.c,v 1.13 2012/04/25 14:50:08 gerv%gerv.net Exp $
+ */
+
+#include "cmslocal.h"
+
+#include "cert.h"
+#include "key.h"
+#include "secasn1.h"
+#include "secoid.h"
+#include "secitem.h"
+#include "pk11func.h"
+#include "secerr.h"
+
+struct nss_cms_encoder_output {
+ NSSCMSContentCallback outputfn;
+ void *outputarg;
+ PLArenaPool *destpoolp;
+ SECItem *dest;
+};
+
+struct NSSCMSEncoderContextStr {
+ SEC_ASN1EncoderContext * ecx; /* ASN.1 encoder context */
+ PRBool ecxupdated; /* true if data was handed in */
+ NSSCMSMessage * cmsg; /* pointer to the root message */
+ SECOidTag type; /* type tag of the current content */
+ NSSCMSContent content; /* pointer to current content */
+ struct nss_cms_encoder_output output; /* output function */
+ int error; /* error code */
+ NSSCMSEncoderContext * childp7ecx; /* link to child encoder context */
+};
+
+static SECStatus nss_cms_before_data(NSSCMSEncoderContext *p7ecx);
+static SECStatus nss_cms_after_data(NSSCMSEncoderContext *p7ecx);
+static SECStatus nss_cms_encoder_update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned long len);
+static SECStatus nss_cms_encoder_work_data(NSSCMSEncoderContext *p7ecx, SECItem *dest,
+ const unsigned char *data, unsigned long len,
+ PRBool final, PRBool innermost);
+
+extern const SEC_ASN1Template NSSCMSMessageTemplate[];
+
+/*
+ * The little output function that the ASN.1 encoder calls to hand
+ * us bytes which we in turn hand back to our caller (via the callback
+ * they gave us).
+ */
+static void
+nss_cms_encoder_out(void *arg, const char *buf, unsigned long len,
+ int depth, SEC_ASN1EncodingPart data_kind)
+{
+ struct nss_cms_encoder_output *output = (struct nss_cms_encoder_output *)arg;
+ unsigned char *dest;
+ unsigned long offset;
+
+#ifdef CMSDEBUG
+ int i;
+ const char *data_name = "unknown";
+
+ switch (data_kind) {
+ case SEC_ASN1_Identifier:
+ data_name = "identifier";
+ break;
+ case SEC_ASN1_Length:
+ data_name = "length";
+ break;
+ case SEC_ASN1_Contents:
+ data_name = "contents";
+ break;
+ case SEC_ASN1_EndOfContents:
+ data_name = "end-of-contents";
+ break;
+ }
+ fprintf(stderr, "kind = %s, depth = %d, len = %d\n", data_name, depth, len);
+ for (i=0; i < len; i++) {
+ fprintf(stderr, " %02x%s", (unsigned int)buf[i] & 0xff, ((i % 16) == 15) ? "\n" : "");
+ }
+ if ((i % 16) != 0)
+ fprintf(stderr, "\n");
+#endif
+
+ if (output->outputfn != NULL)
+ /* call output callback with DER data */
+ output->outputfn(output->outputarg, buf, len);
+
+ if (output->dest != NULL) {
+ /* store DER data in SECItem */
+ offset = output->dest->len;
+ if (offset == 0) {
+ dest = (unsigned char *)PORT_ArenaAlloc(output->destpoolp, len);
+ } else {
+ dest = (unsigned char *)PORT_ArenaGrow(output->destpoolp,
+ output->dest->data,
+ output->dest->len,
+ output->dest->len + len);
+ }
+ if (dest == NULL)
+ /* oops */
+ return;
+
+ output->dest->data = dest;
+ output->dest->len += len;
+
+ /* copy it in */
+ PORT_Memcpy(output->dest->data + offset, buf, len);
+ }
+}
+
+/*
+ * nss_cms_encoder_notify - ASN.1 encoder callback
+ *
+ * this function is called by the ASN.1 encoder before and after the encoding of
+ * every object. here, it is used to keep track of data structures, set up
+ * encryption and/or digesting and possibly set up child encoders.
+ */
+static void
+nss_cms_encoder_notify(void *arg, PRBool before, void *dest, int depth)
+{
+ NSSCMSEncoderContext *p7ecx;
+ NSSCMSContentInfo *rootcinfo, *cinfo;
+ PRBool after = !before;
+ PLArenaPool *poolp;
+ SECOidTag childtype;
+ SECItem *item;
+
+ p7ecx = (NSSCMSEncoderContext *)arg;
+ PORT_Assert(p7ecx != NULL);
+
+ rootcinfo = &(p7ecx->cmsg->contentInfo);
+ poolp = p7ecx->cmsg->poolp;
+
+#ifdef CMSDEBUG
+ fprintf(stderr, "%6.6s, dest = 0x%08x, depth = %d\n", before ? "before" : "after", dest, depth);
+#endif
+
+ /*
+ * Watch for the content field, at which point we want to instruct
+ * the ASN.1 encoder to start taking bytes from the buffer.
+ */
+ if (NSS_CMSType_IsData(p7ecx->type)) {
+ cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
+ if (before && dest == &(cinfo->rawContent)) {
+ /* just set up encoder to grab from user - no encryption or digesting */
+ if ((item = cinfo->content.data) != NULL)
+ (void)nss_cms_encoder_work_data(p7ecx, NULL, item->data, item->len, PR_TRUE, PR_TRUE);
+ else
+ SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx);
+ SEC_ASN1EncoderClearNotifyProc(p7ecx->ecx); /* no need to get notified anymore */
+ }
+ } else if (NSS_CMSType_IsWrapper(p7ecx->type)) {
+ /* when we know what the content is, we encode happily until we reach the inner content */
+ cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
+ childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
+
+ if (after && dest == &(cinfo->contentType)) {
+ /* we're right before encoding the data (if we have some or not) */
+ /* (for encrypted data, we're right before the contentEncAlg which may change */
+ /* in nss_cms_before_data because of IV calculation when setting up encryption) */
+ if (nss_cms_before_data(p7ecx) != SECSuccess)
+ p7ecx->error = PORT_GetError();
+ }
+ if (before && dest == &(cinfo->rawContent)) {
+ if (p7ecx->childp7ecx == NULL) {
+ if ((NSS_CMSType_IsData(childtype) && (item = cinfo->content.data) != NULL)) {
+ /* we are the innermost non-data and we have data - feed it in */
+ (void)nss_cms_encoder_work_data(p7ecx, NULL, item->data, item->len, PR_TRUE, PR_TRUE);
+ } else {
+ /* else we'll have to get data from user */
+ SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx);
+ }
+ } else {
+ /* if we have a nested encoder, wait for its data */
+ SEC_ASN1EncoderSetTakeFromBuf(p7ecx->ecx);
+ }
+ }
+ if (after && dest == &(cinfo->rawContent)) {
+ if (nss_cms_after_data(p7ecx) != SECSuccess)
+ p7ecx->error = PORT_GetError();
+ SEC_ASN1EncoderClearNotifyProc(p7ecx->ecx); /* no need to get notified anymore */
+ }
+ } else {
+ /* we're still in the root message */
+ if (after && dest == &(rootcinfo->contentType)) {
+ /* got the content type OID now - so find out the type tag */
+ p7ecx->type = NSS_CMSContentInfo_GetContentTypeTag(rootcinfo);
+ /* set up a pointer to our current content */
+ p7ecx->content = rootcinfo->content;
+ }
+ }
+}
+
+/*
+ * nss_cms_before_data - setup the current encoder to receive data
+ */
+static SECStatus
+nss_cms_before_data(NSSCMSEncoderContext *p7ecx)
+{
+ SECStatus rv;
+ SECOidTag childtype;
+ NSSCMSContentInfo *cinfo;
+ PLArenaPool *poolp;
+ NSSCMSEncoderContext *childp7ecx;
+ const SEC_ASN1Template *template;
+
+ poolp = p7ecx->cmsg->poolp;
+
+ /* call _Encode_BeforeData handlers */
+ switch (p7ecx->type) {
+ case SEC_OID_PKCS7_SIGNED_DATA:
+ /* we're encoding a signedData, so set up the digests */
+ rv = NSS_CMSSignedData_Encode_BeforeData(p7ecx->content.signedData);
+ break;
+ case SEC_OID_PKCS7_DIGESTED_DATA:
+ /* we're encoding a digestedData, so set up the digest */
+ rv = NSS_CMSDigestedData_Encode_BeforeData(p7ecx->content.digestedData);
+ break;
+ case SEC_OID_PKCS7_ENVELOPED_DATA:
+ rv = NSS_CMSEnvelopedData_Encode_BeforeData(p7ecx->content.envelopedData);
+ break;
+ case SEC_OID_PKCS7_ENCRYPTED_DATA:
+ rv = NSS_CMSEncryptedData_Encode_BeforeData(p7ecx->content.encryptedData);
+ break;
+ default:
+ if (NSS_CMSType_IsWrapper(p7ecx->type)) {
+ rv = NSS_CMSGenericWrapperData_Encode_BeforeData(p7ecx->type, p7ecx->content.genericData);
+ } else {
+ rv = SECFailure;
+ }
+ }
+ if (rv != SECSuccess)
+ return SECFailure;
+
+ /* ok, now we have a pointer to cinfo */
+ /* find out what kind of data is encapsulated */
+
+ cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
+ childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
+
+ if (NSS_CMSType_IsWrapper(childtype)) {
+ /* in these cases, we need to set up a child encoder! */
+ /* create new encoder context */
+ childp7ecx = PORT_ZAlloc(sizeof(NSSCMSEncoderContext));
+ if (childp7ecx == NULL)
+ return SECFailure;
+
+ /* the CHILD encoder needs to hand its encoded data to the CURRENT encoder
+ * (which will encrypt and/or digest it)
+ * this needs to route back into our update function
+ * which finds the lowest encoding context & encrypts and computes digests */
+ childp7ecx->type = childtype;
+ childp7ecx->content = cinfo->content;
+ /* use the non-recursive update function here, of course */
+ childp7ecx->output.outputfn = (NSSCMSContentCallback)nss_cms_encoder_update;
+ childp7ecx->output.outputarg = p7ecx;
+ childp7ecx->output.destpoolp = NULL;
+ childp7ecx->output.dest = NULL;
+ childp7ecx->cmsg = p7ecx->cmsg;
+ childp7ecx->ecxupdated = PR_FALSE;
+ childp7ecx->childp7ecx = NULL;
+
+ template = NSS_CMSUtil_GetTemplateByTypeTag(childtype);
+ if (template == NULL)
+ goto loser; /* cannot happen */
+
+ /* now initialize the data for encoding the first third */
+ switch (childp7ecx->type) {
+ case SEC_OID_PKCS7_SIGNED_DATA:
+ rv = NSS_CMSSignedData_Encode_BeforeStart(cinfo->content.signedData);
+ break;
+ case SEC_OID_PKCS7_ENVELOPED_DATA:
+ rv = NSS_CMSEnvelopedData_Encode_BeforeStart(cinfo->content.envelopedData);
+ break;
+ case SEC_OID_PKCS7_DIGESTED_DATA:
+ rv = NSS_CMSDigestedData_Encode_BeforeStart(cinfo->content.digestedData);
+ break;
+ case SEC_OID_PKCS7_ENCRYPTED_DATA:
+ rv = NSS_CMSEncryptedData_Encode_BeforeStart(cinfo->content.encryptedData);
+ break;
+ default:
+ rv = NSS_CMSGenericWrapperData_Encode_BeforeStart(childp7ecx->type, cinfo->content.genericData);
+ break;
+ }
+ if (rv != SECSuccess)
+ goto loser;
+
+ /*
+ * Initialize the BER encoder.
+ */
+ childp7ecx->ecx = SEC_ASN1EncoderStart(cinfo->content.pointer, template,
+ nss_cms_encoder_out, &(childp7ecx->output));
+ if (childp7ecx->ecx == NULL)
+ goto loser;
+
+ /*
+ * Indicate that we are streaming. We will be streaming until we
+ * get past the contents bytes.
+ */
+ if (!cinfo->privateInfo || !cinfo->privateInfo->dontStream)
+ SEC_ASN1EncoderSetStreaming(childp7ecx->ecx);
+
+ /*
+ * The notify function will watch for the contents field.
+ */
+ p7ecx->childp7ecx = childp7ecx;
+ SEC_ASN1EncoderSetNotifyProc(childp7ecx->ecx, nss_cms_encoder_notify, childp7ecx);
+
+ /* please note that we are NOT calling SEC_ASN1EncoderUpdate here to kick off the */
+ /* encoding process - we'll do that from the update function instead */
+ /* otherwise we'd be encoding data from a call of the notify function of the */
+ /* parent encoder (which would not work) */
+
+ } else if (NSS_CMSType_IsData(childtype)) {
+ p7ecx->childp7ecx = NULL;
+ } else {
+ /* we do not know this type */
+ p7ecx->error = SEC_ERROR_BAD_DER;
+ }
+
+ return SECSuccess;
+
+loser:
+ if (childp7ecx) {
+ if (childp7ecx->ecx)
+ SEC_ASN1EncoderFinish(childp7ecx->ecx);
+ PORT_Free(childp7ecx);
+ p7ecx->childp7ecx = NULL;
+ }
+ return SECFailure;
+}
+
+static SECStatus
+nss_cms_after_data(NSSCMSEncoderContext *p7ecx)
+{
+ SECStatus rv = SECFailure;
+
+ switch (p7ecx->type) {
+ case SEC_OID_PKCS7_SIGNED_DATA:
+ /* this will finish the digests and sign */
+ rv = NSS_CMSSignedData_Encode_AfterData(p7ecx->content.signedData);
+ break;
+ case SEC_OID_PKCS7_ENVELOPED_DATA:
+ rv = NSS_CMSEnvelopedData_Encode_AfterData(p7ecx->content.envelopedData);
+ break;
+ case SEC_OID_PKCS7_DIGESTED_DATA:
+ rv = NSS_CMSDigestedData_Encode_AfterData(p7ecx->content.digestedData);
+ break;
+ case SEC_OID_PKCS7_ENCRYPTED_DATA:
+ rv = NSS_CMSEncryptedData_Encode_AfterData(p7ecx->content.encryptedData);
+ break;
+ case SEC_OID_SMIME_RECEIPT:
+ /* do nothing */
+ break;
+ default:
+ if (NSS_CMSType_IsWrapper(p7ecx->type)) {
+ rv = NSS_CMSGenericWrapperData_Encode_AfterData(p7ecx->type, p7ecx->content.genericData);
+ } else {
+ rv = SECFailure;
+ }
+ break;
+ }
+ return rv;
+}
+
+/*
+ * nss_cms_encoder_work_data - process incoming data
+ *
+ * (from the user or the next encoding layer)
+ * Here, we need to digest and/or encrypt, then pass it on
+ */
+static SECStatus
+nss_cms_encoder_work_data(NSSCMSEncoderContext *p7ecx, SECItem *dest,
+ const unsigned char *data, unsigned long len,
+ PRBool final, PRBool innermost)
+{
+ unsigned char *buf = NULL;
+ SECStatus rv;
+ NSSCMSContentInfo *cinfo;
+
+ rv = SECSuccess; /* may as well be optimistic */
+
+ /*
+ * We should really have data to process, or we should be trying
+ * to finish/flush the last block. (This is an overly paranoid
+ * check since all callers are in this file and simple inspection
+ * proves they do it right. But it could find a bug in future
+ * modifications/development, that is why it is here.)
+ */
+ PORT_Assert ((data != NULL && len) || final);
+
+ /* we got data (either from the caller, or from a lower level encoder) */
+ cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
+ if (!cinfo) {
+ /* The original programmer didn't expect this to happen */
+ p7ecx->error = SEC_ERROR_LIBRARY_FAILURE;
+ return SECFailure;
+ }
+
+ /* Update the running digest. */
+ if (len && cinfo->privateInfo && cinfo->privateInfo->digcx != NULL)
+ NSS_CMSDigestContext_Update(cinfo->privateInfo->digcx, data, len);
+
+ /* Encrypt this chunk. */
+ if (cinfo->privateInfo && cinfo->privateInfo->ciphcx != NULL) {
+ unsigned int inlen; /* length of data being encrypted */
+ unsigned int outlen; /* length of encrypted data */
+ unsigned int buflen; /* length available for encrypted data */
+
+ inlen = len;
+ buflen = NSS_CMSCipherContext_EncryptLength(cinfo->privateInfo->ciphcx, inlen, final);
+ if (buflen == 0) {
+ /*
+ * No output is expected, but the input data may be buffered
+ * so we still have to call Encrypt.
+ */
+ rv = NSS_CMSCipherContext_Encrypt(cinfo->privateInfo->ciphcx, NULL, NULL, 0,
+ data, inlen, final);
+ if (final) {
+ len = 0;
+ goto done;
+ }
+ return rv;
+ }
+
+ if (dest != NULL)
+ buf = (unsigned char*)PORT_ArenaAlloc(p7ecx->cmsg->poolp, buflen);
+ else
+ buf = (unsigned char*)PORT_Alloc(buflen);
+
+ if (buf == NULL) {
+ rv = SECFailure;
+ } else {
+ rv = NSS_CMSCipherContext_Encrypt(cinfo->privateInfo->ciphcx, buf, &outlen, buflen,
+ data, inlen, final);
+ data = buf;
+ len = outlen;
+ }
+ if (rv != SECSuccess)
+ /* encryption or malloc failed? */
+ return rv;
+ }
+
+
+ /*
+ * at this point (data,len) has everything we'd like to give to the CURRENT encoder
+ * (which will encode it, then hand it back to the user or the parent encoder)
+ * We don't encode the data if we're innermost and we're told not to include the data
+ */
+ if (p7ecx->ecx != NULL && len && (!innermost || cinfo->rawContent != cinfo->content.pointer))
+ rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, (const char *)data, len);
+
+done:
+
+ if (cinfo->privateInfo && cinfo->privateInfo->ciphcx != NULL) {
+ if (dest != NULL) {
+ dest->data = buf;
+ dest->len = len;
+ } else if (buf != NULL) {
+ PORT_Free (buf);
+ }
+ }
+ return rv;
+}
+
+/*
+ * nss_cms_encoder_update - deliver encoded data to the next higher level
+ *
+ * no recursion here because we REALLY want to end up at the next higher encoder!
+ */
+static SECStatus
+nss_cms_encoder_update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned long len)
+{
+ /* XXX Error handling needs help. Return what? Do "Finish" on failure? */
+ return nss_cms_encoder_work_data (p7ecx, NULL, (const unsigned char *)data, len, PR_FALSE, PR_FALSE);
+}
+
+/*
+ * NSS_CMSEncoder_Start - set up encoding of a CMS message
+ *
+ * "cmsg" - message to encode
+ * "outputfn", "outputarg" - callback function for delivery of DER-encoded output
+ * will not be called if NULL.
+ * "dest" - if non-NULL, pointer to SECItem that will hold the DER-encoded output
+ * "destpoolp" - pool to allocate DER-encoded output in
+ * "pwfn", pwfn_arg" - callback function for getting token password
+ * "decrypt_key_cb", "decrypt_key_cb_arg" - callback function for getting bulk key for encryptedData
+ * "detached_digestalgs", "detached_digests" - digests from detached content
+ */
+NSSCMSEncoderContext *
+NSS_CMSEncoder_Start(NSSCMSMessage *cmsg,
+ NSSCMSContentCallback outputfn, void *outputarg,
+ SECItem *dest, PLArenaPool *destpoolp,
+ PK11PasswordFunc pwfn, void *pwfn_arg,
+ NSSCMSGetDecryptKeyCallback decrypt_key_cb, void *decrypt_key_cb_arg,
+ SECAlgorithmID **detached_digestalgs, SECItem **detached_digests)
+{
+ NSSCMSEncoderContext *p7ecx;
+ SECStatus rv;
+ NSSCMSContentInfo *cinfo;
+ SECOidTag tag;
+
+ NSS_CMSMessage_SetEncodingParams(cmsg, pwfn, pwfn_arg, decrypt_key_cb, decrypt_key_cb_arg,
+ detached_digestalgs, detached_digests);
+
+ p7ecx = (NSSCMSEncoderContext *)PORT_ZAlloc(sizeof(NSSCMSEncoderContext));
+ if (p7ecx == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ return NULL;
+ }
+
+ p7ecx->cmsg = cmsg;
+ p7ecx->output.outputfn = outputfn;
+ p7ecx->output.outputarg = outputarg;
+ p7ecx->output.dest = dest;
+ p7ecx->output.destpoolp = destpoolp;
+ p7ecx->type = SEC_OID_UNKNOWN;
+
+ cinfo = NSS_CMSMessage_GetContentInfo(cmsg);
+
+ tag = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
+ switch (tag) {
+ case SEC_OID_PKCS7_SIGNED_DATA:
+ rv = NSS_CMSSignedData_Encode_BeforeStart(cinfo->content.signedData);
+ break;
+ case SEC_OID_PKCS7_ENVELOPED_DATA:
+ rv = NSS_CMSEnvelopedData_Encode_BeforeStart(cinfo->content.envelopedData);
+ break;
+ case SEC_OID_PKCS7_DIGESTED_DATA:
+ rv = NSS_CMSDigestedData_Encode_BeforeStart(cinfo->content.digestedData);
+ break;
+ case SEC_OID_PKCS7_ENCRYPTED_DATA:
+ rv = NSS_CMSEncryptedData_Encode_BeforeStart(cinfo->content.encryptedData);
+ break;
+ default:
+ if (NSS_CMSType_IsWrapper(tag)) {
+ rv = NSS_CMSGenericWrapperData_Encode_BeforeStart(tag,
+ p7ecx->content.genericData);
+ } else {
+ rv = SECFailure;
+ }
+ break;
+ }
+ if (rv != SECSuccess) {
+ PORT_Free(p7ecx);
+ return NULL;
+ }
+
+ /* Initialize the BER encoder.
+ * Note that this will not encode anything until the first call to SEC_ASN1EncoderUpdate */
+ p7ecx->ecx = SEC_ASN1EncoderStart(cmsg, NSSCMSMessageTemplate,
+ nss_cms_encoder_out, &(p7ecx->output));
+ if (p7ecx->ecx == NULL) {
+ PORT_Free (p7ecx);
+ return NULL;
+ }
+ p7ecx->ecxupdated = PR_FALSE;
+
+ /*
+ * Indicate that we are streaming. We will be streaming until we
+ * get past the contents bytes.
+ */
+ if (!cinfo->privateInfo || !cinfo->privateInfo->dontStream)
+ SEC_ASN1EncoderSetStreaming(p7ecx->ecx);
+
+ /*
+ * The notify function will watch for the contents field.
+ */
+ SEC_ASN1EncoderSetNotifyProc(p7ecx->ecx, nss_cms_encoder_notify, p7ecx);
+
+ /* this will kick off the encoding process & encode everything up to the content bytes,
+ * at which point the notify function sets streaming mode (and possibly creates
+ * a child encoder). */
+ p7ecx->ecxupdated = PR_TRUE;
+ if (SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0) != SECSuccess) {
+ PORT_Free (p7ecx);
+ return NULL;
+ }
+
+ return p7ecx;
+}
+
+/*
+ * NSS_CMSEncoder_Update - take content data delivery from the user
+ *
+ * "p7ecx" - encoder context
+ * "data" - content data
+ * "len" - length of content data
+ *
+ * need to find the lowest level (and call SEC_ASN1EncoderUpdate on the way down),
+ * then hand the data to the work_data fn
+ */
+SECStatus
+NSS_CMSEncoder_Update(NSSCMSEncoderContext *p7ecx, const char *data, unsigned long len)
+{
+ SECStatus rv;
+ NSSCMSContentInfo *cinfo;
+ SECOidTag childtype;
+
+ if (p7ecx->error)
+ return SECFailure;
+
+ /* hand data to the innermost decoder */
+ if (p7ecx->childp7ecx) {
+ /* tell the child to start encoding, up to its first data byte, if it
+ * hasn't started yet */
+ if (!p7ecx->childp7ecx->ecxupdated) {
+ p7ecx->childp7ecx->ecxupdated = PR_TRUE;
+ if (SEC_ASN1EncoderUpdate(p7ecx->childp7ecx->ecx, NULL, 0) != SECSuccess)
+ return SECFailure;
+ }
+ /* recursion here */
+ rv = NSS_CMSEncoder_Update(p7ecx->childp7ecx, data, len);
+ } else {
+ /* we are at innermost decoder */
+ /* find out about our inner content type - must be data */
+ cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
+ if (!cinfo) {
+ /* The original programmer didn't expect this to happen */
+ p7ecx->error = SEC_ERROR_LIBRARY_FAILURE;
+ return SECFailure;
+ }
+
+ childtype = NSS_CMSContentInfo_GetContentTypeTag(cinfo);
+ if (!NSS_CMSType_IsData(childtype) && childtype != SEC_OID_SMIME_RECEIPT)
+ return SECFailure;
+ /* and we must not have preset data */
+ if (cinfo->content.data != NULL)
+ return SECFailure;
+
+ /* hand it the data so it can encode it (let DER trickle up the chain) */
+ rv = nss_cms_encoder_work_data(p7ecx, NULL, (const unsigned char *)data, len, PR_FALSE, PR_TRUE);
+ }
+ return rv;
+}
+
+/*
+ * NSS_CMSEncoder_Cancel - stop all encoding
+ *
+ * we need to walk down the chain of encoders and the finish them from the innermost out
+ */
+SECStatus
+NSS_CMSEncoder_Cancel(NSSCMSEncoderContext *p7ecx)
+{
+ SECStatus rv = SECFailure;
+
+ /* XXX do this right! */
+
+ /*
+ * Finish any inner decoders before us so that all the encoded data is flushed
+ * This basically finishes all the decoders from the innermost to the outermost.
+ * Finishing an inner decoder may result in data being updated to the outer decoder
+ * while we are already in NSS_CMSEncoder_Finish, but that's allright.
+ */
+ if (p7ecx->childp7ecx) {
+ rv = NSS_CMSEncoder_Cancel(p7ecx->childp7ecx); /* frees p7ecx->childp7ecx */
+ /* remember rv for now */
+ }
+
+ /*
+ * On the way back up, there will be no more data (if we had an
+ * inner encoder, it is done now!)
+ * Flush out any remaining data and/or finish digests.
+ */
+ rv = nss_cms_encoder_work_data(p7ecx, NULL, NULL, 0, PR_TRUE, (p7ecx->childp7ecx == NULL));
+ if (rv != SECSuccess)
+ goto loser;
+
+ p7ecx->childp7ecx = NULL;
+
+ /* kick the encoder back into working mode again.
+ * We turn off streaming stuff (which will cause the encoder to continue
+ * encoding happily, now that we have all the data (like digests) ready for it).
+ */
+ SEC_ASN1EncoderClearTakeFromBuf(p7ecx->ecx);
+ SEC_ASN1EncoderClearStreaming(p7ecx->ecx);
+
+ /* now that TakeFromBuf is off, this will kick this encoder to finish encoding */
+ rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0);
+
+loser:
+ SEC_ASN1EncoderFinish(p7ecx->ecx);
+ PORT_Free (p7ecx);
+ return rv;
+}
+
+/*
+ * NSS_CMSEncoder_Finish - signal the end of data
+ *
+ * we need to walk down the chain of encoders and the finish them from the innermost out
+ */
+SECStatus
+NSS_CMSEncoder_Finish(NSSCMSEncoderContext *p7ecx)
+{
+ SECStatus rv = SECFailure;
+ NSSCMSContentInfo *cinfo;
+
+ /*
+ * Finish any inner decoders before us so that all the encoded data is flushed
+ * This basically finishes all the decoders from the innermost to the outermost.
+ * Finishing an inner decoder may result in data being updated to the outer decoder
+ * while we are already in NSS_CMSEncoder_Finish, but that's allright.
+ */
+ if (p7ecx->childp7ecx) {
+ /* tell the child to start encoding, up to its first data byte, if it
+ * hasn't yet */
+ if (!p7ecx->childp7ecx->ecxupdated) {
+ p7ecx->childp7ecx->ecxupdated = PR_TRUE;
+ rv = SEC_ASN1EncoderUpdate(p7ecx->childp7ecx->ecx, NULL, 0);
+ if (rv != SECSuccess) {
+ NSS_CMSEncoder_Finish(p7ecx->childp7ecx); /* frees p7ecx->childp7ecx */
+ goto loser;
+ }
+ }
+ rv = NSS_CMSEncoder_Finish(p7ecx->childp7ecx); /* frees p7ecx->childp7ecx */
+ if (rv != SECSuccess)
+ goto loser;
+ }
+
+ /*
+ * On the way back up, there will be no more data (if we had an
+ * inner encoder, it is done now!)
+ * Flush out any remaining data and/or finish digests.
+ */
+ rv = nss_cms_encoder_work_data(p7ecx, NULL, NULL, 0, PR_TRUE, (p7ecx->childp7ecx == NULL));
+ if (rv != SECSuccess)
+ goto loser;
+
+ p7ecx->childp7ecx = NULL;
+
+ cinfo = NSS_CMSContent_GetContentInfo(p7ecx->content.pointer, p7ecx->type);
+ if (!cinfo) {
+ /* The original programmer didn't expect this to happen */
+ p7ecx->error = SEC_ERROR_LIBRARY_FAILURE;
+ rv = SECFailure;
+ goto loser;
+ }
+ SEC_ASN1EncoderClearTakeFromBuf(p7ecx->ecx);
+ SEC_ASN1EncoderClearStreaming(p7ecx->ecx);
+ /* now that TakeFromBuf is off, this will kick this encoder to finish encoding */
+ rv = SEC_ASN1EncoderUpdate(p7ecx->ecx, NULL, 0);
+
+ if (p7ecx->error)
+ rv = SECFailure;
+
+loser:
+ SEC_ASN1EncoderFinish(p7ecx->ecx);
+ PORT_Free (p7ecx);
+ return rv;
+}
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+ * ESS Signed Receipts/Security Labels: Eric Ballet Baz / BT Global Services / Etat francais - Ministere de la Defense
+ * ESS Signed Receipts/Security Labels: Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved */
+
+/*
+ * CMS signerInfo methods.
+ *
+ * $Id: cmssiginfo.c,v 1.37 2012/04/25 14:50:09 gerv%gerv.net Exp $
+ */
+
+#include "cmslocal.h"
+
+#include "cert.h"
+#include "key.h"
+#include "secasn1.h"
+#include "secitem.h"
+#include "secoid.h"
+#include "pk11func.h"
+#include "prtime.h"
+#include "secerr.h"
+#include "secder.h"
+#include "cryptohi.h"
+
+#include "smime.h"
+
+/* =============================================================================
+ * SIGNERINFO
+ */
+NSSCMSSignerInfo *
+nss_cmssignerinfo_create(NSSCMSMessage *cmsg, NSSCMSSignerIDSelector type,
+ CERTCertificate *cert, SECItem *subjKeyID, SECKEYPublicKey *pubKey,
+ SECKEYPrivateKey *signingKey, SECOidTag digestalgtag);
+
+NSSCMSSignerInfo *
+NSS_CMSSignerInfo_CreateWithSubjKeyID(NSSCMSMessage *cmsg, SECItem *subjKeyID,
+ SECKEYPublicKey *pubKey, SECKEYPrivateKey *signingKey, SECOidTag digestalgtag)
+{
+ return nss_cmssignerinfo_create(cmsg, NSSCMSSignerID_SubjectKeyID, NULL, subjKeyID, pubKey, signingKey, digestalgtag);
+}
+
+NSSCMSSignerInfo *
+NSS_CMSSignerInfo_Create(NSSCMSMessage *cmsg, CERTCertificate *cert, SECOidTag digestalgtag)
+{
+ return nss_cmssignerinfo_create(cmsg, NSSCMSSignerID_IssuerSN, cert, NULL, NULL, NULL, digestalgtag);
+}
+
+NSSCMSSignerInfo *
+nss_cmssignerinfo_create(NSSCMSMessage *cmsg, NSSCMSSignerIDSelector type,
+ CERTCertificate *cert, SECItem *subjKeyID, SECKEYPublicKey *pubKey,
+ SECKEYPrivateKey *signingKey, SECOidTag digestalgtag)
+{
+ void *mark;
+ NSSCMSSignerInfo *signerinfo;
+ int version;
+ PLArenaPool *poolp;
+
+ poolp = cmsg->poolp;
+
+ mark = PORT_ArenaMark(poolp);
+
+ signerinfo = (NSSCMSSignerInfo *)PORT_ArenaZAlloc(poolp, sizeof(NSSCMSSignerInfo));
+ if (signerinfo == NULL) {
+ PORT_ArenaRelease(poolp, mark);
+ return NULL;
+ }
+
+
+ signerinfo->cmsg = cmsg;
+
+ switch(type) {
+ case NSSCMSSignerID_IssuerSN:
+ signerinfo->signerIdentifier.identifierType = NSSCMSSignerID_IssuerSN;
+ if ((signerinfo->cert = CERT_DupCertificate(cert)) == NULL)
+ goto loser;
+ if ((signerinfo->signerIdentifier.id.issuerAndSN = CERT_GetCertIssuerAndSN(poolp, cert)) == NULL)
+ goto loser;
+ break;
+ case NSSCMSSignerID_SubjectKeyID:
+ signerinfo->signerIdentifier.identifierType = NSSCMSSignerID_SubjectKeyID;
+ PORT_Assert(subjKeyID);
+ if (!subjKeyID)
+ goto loser;
+
+ signerinfo->signerIdentifier.id.subjectKeyID = PORT_ArenaNew(poolp, SECItem);
+ SECITEM_CopyItem(poolp, signerinfo->signerIdentifier.id.subjectKeyID,
+ subjKeyID);
+ signerinfo->signingKey = SECKEY_CopyPrivateKey(signingKey);
+ if (!signerinfo->signingKey)
+ goto loser;
+ signerinfo->pubKey = SECKEY_CopyPublicKey(pubKey);
+ if (!signerinfo->pubKey)
+ goto loser;
+ break;
+ default:
+ goto loser;
+ }
+
+ /* set version right now */
+ version = NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN;
+ /* RFC2630 5.3 "version is the syntax version number. If the .... " */
+ if (signerinfo->signerIdentifier.identifierType == NSSCMSSignerID_SubjectKeyID)
+ version = NSS_CMS_SIGNER_INFO_VERSION_SUBJKEY;
+ (void)SEC_ASN1EncodeInteger(poolp, &(signerinfo->version), (long)version);
+
+ if (SECOID_SetAlgorithmID(poolp, &signerinfo->digestAlg, digestalgtag, NULL) != SECSuccess)
+ goto loser;
+
+ PORT_ArenaUnmark(poolp, mark);
+ return signerinfo;
+
+loser:
+ PORT_ArenaRelease(poolp, mark);
+ return NULL;
+}
+
+/*
+ * NSS_CMSSignerInfo_Destroy - destroy a SignerInfo data structure
+ */
+void
+NSS_CMSSignerInfo_Destroy(NSSCMSSignerInfo *si)
+{
+ if (si->cert != NULL)
+ CERT_DestroyCertificate(si->cert);
+
+ if (si->certList != NULL)
+ CERT_DestroyCertificateList(si->certList);
+
+ /* XXX storage ??? */
+}
+
+/*
+ * NSS_CMSSignerInfo_Sign - sign something
+ *
+ */
+SECStatus
+NSS_CMSSignerInfo_Sign(NSSCMSSignerInfo *signerinfo, SECItem *digest,
+ SECItem *contentType)
+{
+ CERTCertificate *cert;
+ SECKEYPrivateKey *privkey = NULL;
+ SECOidTag digestalgtag;
+ SECOidTag pubkAlgTag;
+ SECItem signature = { 0 };
+ SECStatus rv;
+ PLArenaPool *poolp, *tmppoolp = NULL;
+ SECAlgorithmID *algID, freeAlgID;
+ CERTSubjectPublicKeyInfo *spki;
+
+ PORT_Assert (digest != NULL);
+
+ poolp = signerinfo->cmsg->poolp;
+
+ switch (signerinfo->signerIdentifier.identifierType) {
+ case NSSCMSSignerID_IssuerSN:
+ cert = signerinfo->cert;
+
+ privkey = PK11_FindKeyByAnyCert(cert, signerinfo->cmsg->pwfn_arg);
+ if (privkey == NULL)
+ goto loser;
+ algID = &cert->subjectPublicKeyInfo.algorithm;
+ break;
+ case NSSCMSSignerID_SubjectKeyID:
+ privkey = signerinfo->signingKey;
+ signerinfo->signingKey = NULL;
+ spki = SECKEY_CreateSubjectPublicKeyInfo(signerinfo->pubKey);
+ SECKEY_DestroyPublicKey(signerinfo->pubKey);
+ signerinfo->pubKey = NULL;
+ SECOID_CopyAlgorithmID(NULL, &freeAlgID, &spki->algorithm);
+ SECKEY_DestroySubjectPublicKeyInfo(spki);
+ algID = &freeAlgID;
+ break;
+ default:
+ goto loser;
+ }
+ digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
+ /*
+ * XXX I think there should be a cert-level interface for this,
+ * so that I do not have to know about subjectPublicKeyInfo...
+ */
+ pubkAlgTag = SECOID_GetAlgorithmTag(algID);
+ if (signerinfo->signerIdentifier.identifierType == NSSCMSSignerID_SubjectKeyID) {
+ SECOID_DestroyAlgorithmID(&freeAlgID, PR_FALSE);
+ }
+
+ if (signerinfo->authAttr != NULL) {
+ SECOidTag signAlgTag;
+ SECItem encoded_attrs;
+
+ /* find and fill in the message digest attribute. */
+ rv = NSS_CMSAttributeArray_SetAttr(poolp, &(signerinfo->authAttr),
+ SEC_OID_PKCS9_MESSAGE_DIGEST, digest, PR_FALSE);
+ if (rv != SECSuccess)
+ goto loser;
+
+ if (contentType != NULL) {
+ /* if the caller wants us to, find and fill in the content type attribute. */
+ rv = NSS_CMSAttributeArray_SetAttr(poolp, &(signerinfo->authAttr),
+ SEC_OID_PKCS9_CONTENT_TYPE, contentType, PR_FALSE);
+ if (rv != SECSuccess)
+ goto loser;
+ }
+
+ if ((tmppoolp = PORT_NewArena (1024)) == NULL) {
+ PORT_SetError(SEC_ERROR_NO_MEMORY);
+ goto loser;
+ }
+
+ /*
+ * Before encoding, reorder the attributes so that when they
+ * are encoded, they will be conforming DER, which is required
+ * to have a specific order and that is what must be used for
+ * the hash/signature. We do this here, rather than building
+ * it into EncodeAttributes, because we do not want to do
+ * such reordering on incoming messages (which also uses
+ * EncodeAttributes) or our old signatures (and other "broken"
+ * implementations) will not verify. So, we want to guarantee
+ * that we send out good DER encodings of attributes, but not
+ * to expect to receive them.
+ */
+ if (NSS_CMSAttributeArray_Reorder(signerinfo->authAttr) != SECSuccess)
+ goto loser;
+
+ encoded_attrs.data = NULL;
+ encoded_attrs.len = 0;
+ if (NSS_CMSAttributeArray_Encode(tmppoolp, &(signerinfo->authAttr),
+ &encoded_attrs) == NULL)
+ goto loser;
+
+ signAlgTag = SEC_GetSignatureAlgorithmOidTag(privkey->keyType,
+ digestalgtag);
+ if (signAlgTag == SEC_OID_UNKNOWN) {
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ goto loser;
+ }
+
+ rv = SEC_SignData(&signature, encoded_attrs.data, encoded_attrs.len,
+ privkey, signAlgTag);
+ PORT_FreeArena(tmppoolp, PR_FALSE); /* awkward memory management :-( */
+ tmppoolp = 0;
+ } else {
+ rv = SGN_Digest(privkey, digestalgtag, &signature, digest);
+ }
+ SECKEY_DestroyPrivateKey(privkey);
+ privkey = NULL;
+
+ if (rv != SECSuccess)
+ goto loser;
+
+ if (SECITEM_CopyItem(poolp, &(signerinfo->encDigest), &signature)
+ != SECSuccess)
+ goto loser;
+
+ SECITEM_FreeItem(&signature, PR_FALSE);
+
+ if (SECOID_SetAlgorithmID(poolp, &(signerinfo->digestEncAlg), pubkAlgTag,
+ NULL) != SECSuccess)
+ goto loser;
+
+ return SECSuccess;
+
+loser:
+ if (signature.len != 0)
+ SECITEM_FreeItem (&signature, PR_FALSE);
+ if (privkey)
+ SECKEY_DestroyPrivateKey(privkey);
+ if (tmppoolp)
+ PORT_FreeArena(tmppoolp, PR_FALSE);
+ return SECFailure;
+}
+
+SECStatus
+NSS_CMSSignerInfo_VerifyCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb,
+ SECCertUsage certusage)
+{
+ CERTCertificate *cert;
+ PRTime stime;
+
+ if ((cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, certdb)) == NULL) {
+ signerinfo->verificationStatus = NSSCMSVS_SigningCertNotFound;
+ return SECFailure;
+ }
+
+ /*
+ * Get and convert the signing time; if available, it will be used
+ * both on the cert verification and for importing the sender
+ * email profile.
+ */
+ if (NSS_CMSSignerInfo_GetSigningTime (signerinfo, &stime) != SECSuccess)
+ stime = PR_Now(); /* not found or conversion failed, so check against now */
+
+ /*
+ * XXX This uses the signing time, if available. Additionally, we
+ * might want to, if there is no signing time, get the message time
+ * from the mail header itself, and use that. That would require
+ * a change to our interface though, and for S/MIME callers to pass
+ * in a time (and for non-S/MIME callers to pass in nothing, or
+ * maybe make them pass in the current time, always?).
+ */
+ if (CERT_VerifyCert(certdb, cert, PR_TRUE, certusage, stime,
+ signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
+ signerinfo->verificationStatus = NSSCMSVS_SigningCertNotTrusted;
+ return SECFailure;
+ }
+ return SECSuccess;
+}
+
+/*
+ * NSS_CMSSignerInfo_Verify - verify the signature of a single SignerInfo
+ *
+ * Just verifies the signature. The assumption is that verification of
+ * the certificate is done already.
+ */
+SECStatus
+NSS_CMSSignerInfo_Verify(NSSCMSSignerInfo *signerinfo,
+ SECItem *digest, /* may be NULL */
+ SECItem *contentType) /* may be NULL */
+{
+ SECKEYPublicKey *publickey = NULL;
+ NSSCMSAttribute *attr;
+ SECItem encoded_attrs;
+ CERTCertificate *cert;
+ NSSCMSVerificationStatus vs = NSSCMSVS_Unverified;
+ PLArenaPool *poolp;
+ SECOidTag digestalgtag;
+ SECOidTag pubkAlgTag;
+
+ if (signerinfo == NULL)
+ return SECFailure;
+
+ /* NSS_CMSSignerInfo_GetSigningCertificate will fail if 2nd parm is NULL
+ ** and cert has not been verified
+ */
+ cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, NULL);
+ if (cert == NULL) {
+ vs = NSSCMSVS_SigningCertNotFound;
+ goto loser;
+ }
+
+ if ((publickey = CERT_ExtractPublicKey(cert)) == NULL) {
+ vs = NSSCMSVS_ProcessingError;
+ goto loser;
+ }
+
+ digestalgtag = NSS_CMSSignerInfo_GetDigestAlgTag(signerinfo);
+ pubkAlgTag = SECOID_GetAlgorithmTag(&(signerinfo->digestEncAlg));
+ if ((pubkAlgTag == SEC_OID_UNKNOWN) || (digestalgtag == SEC_OID_UNKNOWN)) {
+ vs = NSSCMSVS_SignatureAlgorithmUnknown;
+ goto loser;
+ }
+
+ if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr)) {
+ if (contentType) {
+ /*
+ * Check content type
+ *
+ * RFC2630 sez that if there are any authenticated attributes,
+ * then there must be one for content type which matches the
+ * content type of the content being signed, and there must
+ * be one for message digest which matches our message digest.
+ * So check these things first.
+ */
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
+ SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE);
+ if (attr == NULL) {
+ vs = NSSCMSVS_MalformedSignature;
+ goto loser;
+ }
+
+ if (NSS_CMSAttribute_CompareValue(attr, contentType) == PR_FALSE) {
+ vs = NSSCMSVS_MalformedSignature;
+ goto loser;
+ }
+ }
+
+ /*
+ * Check digest
+ */
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
+ SEC_OID_PKCS9_MESSAGE_DIGEST, PR_TRUE);
+ if (attr == NULL) {
+ vs = NSSCMSVS_MalformedSignature;
+ goto loser;
+ }
+ if (!digest ||
+ NSS_CMSAttribute_CompareValue(attr, digest) == PR_FALSE) {
+ vs = NSSCMSVS_DigestMismatch;
+ goto loser;
+ }
+
+ if ((poolp = PORT_NewArena (1024)) == NULL) {
+ vs = NSSCMSVS_ProcessingError;
+ goto loser;
+ }
+
+ /*
+ * Check signature
+ *
+ * The signature is based on a digest of the DER-encoded authenticated
+ * attributes. So, first we encode and then we digest/verify.
+ * we trust the decoder to have the attributes in the right (sorted)
+ * order
+ */
+ encoded_attrs.data = NULL;
+ encoded_attrs.len = 0;
+
+ if (NSS_CMSAttributeArray_Encode(poolp, &(signerinfo->authAttr),
+ &encoded_attrs) == NULL ||
+ encoded_attrs.data == NULL || encoded_attrs.len == 0) {
+ vs = NSSCMSVS_ProcessingError;
+ goto loser;
+ }
+
+ vs = (VFY_VerifyDataDirect(encoded_attrs.data, encoded_attrs.len,
+ publickey, &(signerinfo->encDigest), pubkAlgTag,
+ digestalgtag, NULL, signerinfo->cmsg->pwfn_arg) != SECSuccess)
+ ? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
+
+ PORT_FreeArena(poolp, PR_FALSE); /* awkward memory management :-( */
+
+ } else {
+ SECItem *sig;
+
+ /* No authenticated attributes.
+ ** The signature is based on the plain message digest.
+ */
+ sig = &(signerinfo->encDigest);
+ if (sig->len == 0)
+ goto loser;
+
+ vs = (!digest ||
+ VFY_VerifyDigestDirect(digest, publickey, sig, pubkAlgTag,
+ digestalgtag, signerinfo->cmsg->pwfn_arg) != SECSuccess)
+ ? NSSCMSVS_BadSignature : NSSCMSVS_GoodSignature;
+ }
+
+ if (vs == NSSCMSVS_BadSignature) {
+ int error = PORT_GetError();
+ /*
+ * XXX Change the generic error into our specific one, because
+ * in that case we get a better explanation out of the Security
+ * Advisor. This is really a bug in the PSM error strings (the
+ * "generic" error has a lousy/wrong message associated with it
+ * which assumes the signature verification was done for the
+ * purposes of checking the issuer signature on a certificate)
+ * but this is at least an easy workaround and/or in the
+ * Security Advisor, which specifically checks for the error
+ * SEC_ERROR_PKCS7_BAD_SIGNATURE and gives more explanation
+ * in that case but does not similarly check for
+ * SEC_ERROR_BAD_SIGNATURE. It probably should, but then would
+ * probably say the wrong thing in the case that it *was* the
+ * certificate signature check that failed during the cert
+ * verification done above. Our error handling is really a mess.
+ */
+ if (error == SEC_ERROR_BAD_SIGNATURE)
+ PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
+ /*
+ * map algorithm failures to NSSCMSVS values
+ */
+ if ((error == SEC_ERROR_PKCS7_KEYALG_MISMATCH) ||
+ (error == SEC_ERROR_INVALID_ALGORITHM)) {
+ /* keep the same error code as 3.11 and before */
+ PORT_SetError(SEC_ERROR_PKCS7_BAD_SIGNATURE);
+ vs = NSSCMSVS_SignatureAlgorithmUnsupported;
+ }
+ }
+
+ if (publickey != NULL)
+ SECKEY_DestroyPublicKey (publickey);
+
+ signerinfo->verificationStatus = vs;
+
+ return (vs == NSSCMSVS_GoodSignature) ? SECSuccess : SECFailure;
+
+loser:
+ if (publickey != NULL)
+ SECKEY_DestroyPublicKey (publickey);
+
+ signerinfo->verificationStatus = vs;
+
+ PORT_SetError (SEC_ERROR_PKCS7_BAD_SIGNATURE);
+ return SECFailure;
+}
+
+NSSCMSVerificationStatus
+NSS_CMSSignerInfo_GetVerificationStatus(NSSCMSSignerInfo *signerinfo)
+{
+ return signerinfo->verificationStatus;
+}
+
+SECOidData *
+NSS_CMSSignerInfo_GetDigestAlg(NSSCMSSignerInfo *signerinfo)
+{
+ SECOidData *algdata;
+ SECOidTag algtag;
+
+ algdata = SECOID_FindOID (&(signerinfo->digestAlg.algorithm));
+ if (algdata == NULL) {
+ return algdata;
+ }
+ /* Windows may have given us a signer algorithm oid instead of a digest
+ * algorithm oid. This call will map to a signer oid to a digest one,
+ * otherwise it leaves the oid alone and let the chips fall as they may
+ * if it's not a digest oid.
+ */
+ algtag = NSS_CMSUtil_MapSignAlgs(algdata->offset);
+ if (algtag != algdata->offset) {
+ /* if the tags don't match, then we must have received a signer
+ * algorithID. Now we need to get the oid data for the digest
+ * oid, which the rest of the code is expecting */
+ algdata = SECOID_FindOIDByTag(algtag);
+ }
+
+ return algdata;
+
+}
+
+SECOidTag
+NSS_CMSSignerInfo_GetDigestAlgTag(NSSCMSSignerInfo *signerinfo)
+{
+ SECOidData *algdata;
+
+ if (!signerinfo) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SEC_OID_UNKNOWN;
+ }
+
+ algdata = NSS_CMSSignerInfo_GetDigestAlg(signerinfo);
+ if (algdata != NULL)
+ return algdata->offset;
+ else
+ return SEC_OID_UNKNOWN;
+}
+
+CERTCertificateList *
+NSS_CMSSignerInfo_GetCertList(NSSCMSSignerInfo *signerinfo)
+{
+ return signerinfo->certList;
+}
+
+int
+NSS_CMSSignerInfo_GetVersion(NSSCMSSignerInfo *signerinfo)
+{
+ unsigned long version;
+
+ /* always take apart the SECItem */
+ if (SEC_ASN1DecodeInteger(&(signerinfo->version), &version) != SECSuccess)
+ return 0;
+ else
+ return (int)version;
+}
+
+/*
+ * NSS_CMSSignerInfo_GetSigningTime - return the signing time,
+ * in UTCTime or GeneralizedTime format,
+ * of a CMS signerInfo.
+ *
+ * sinfo - signerInfo data for this signer
+ *
+ * Returns a pointer to XXXX (what?)
+ * A return value of NULL is an error.
+ */
+SECStatus
+NSS_CMSSignerInfo_GetSigningTime(NSSCMSSignerInfo *sinfo, PRTime *stime)
+{
+ NSSCMSAttribute *attr;
+ SECItem *value;
+
+ if (sinfo == NULL)
+ return SECFailure;
+
+ if (sinfo->signingTime != 0) {
+ *stime = sinfo->signingTime; /* cached copy */
+ return SECSuccess;
+ }
+
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(sinfo->authAttr, SEC_OID_PKCS9_SIGNING_TIME, PR_TRUE);
+ /* XXXX multi-valued attributes NIH */
+ if (attr == NULL || (value = NSS_CMSAttribute_GetValue(attr)) == NULL)
+ return SECFailure;
+ if (DER_DecodeTimeChoice(stime, value) != SECSuccess)
+ return SECFailure;
+ sinfo->signingTime = *stime; /* make cached copy */
+ return SECSuccess;
+}
+
+/*
+ * Return the signing cert of a CMS signerInfo.
+ *
+ * the certs in the enclosing SignedData must have been imported already
+ */
+CERTCertificate *
+NSS_CMSSignerInfo_GetSigningCertificate(NSSCMSSignerInfo *signerinfo, CERTCertDBHandle *certdb)
+{
+ CERTCertificate *cert;
+ NSSCMSSignerIdentifier *sid;
+
+ if (signerinfo->cert != NULL)
+ return signerinfo->cert;
+
+ /* no certdb, and cert hasn't been set yet? */
+ if (certdb == NULL)
+ return NULL;
+
+ /*
+ * This cert will also need to be freed, but since we save it
+ * in signerinfo for later, we do not want to destroy it when
+ * we leave this function -- we let the clean-up of the entire
+ * cinfo structure later do the destroy of this cert.
+ */
+ sid = &signerinfo->signerIdentifier;
+ switch (sid->identifierType) {
+ case NSSCMSSignerID_IssuerSN:
+ cert = CERT_FindCertByIssuerAndSN(certdb, sid->id.issuerAndSN);
+ break;
+ case NSSCMSSignerID_SubjectKeyID:
+ cert = CERT_FindCertBySubjectKeyID(certdb, sid->id.subjectKeyID);
+ break;
+ default:
+ cert = NULL;
+ break;
+ }
+
+ /* cert can be NULL at that point */
+ signerinfo->cert = cert; /* earmark it */
+
+ return cert;
+}
+
+/*
+ * NSS_CMSSignerInfo_GetSignerCommonName - return the common name of the signer
+ *
+ * sinfo - signerInfo data for this signer
+ *
+ * Returns a pointer to allocated memory, which must be freed with PORT_Free.
+ * A return value of NULL is an error.
+ */
+char *
+NSS_CMSSignerInfo_GetSignerCommonName(NSSCMSSignerInfo *sinfo)
+{
+ CERTCertificate *signercert;
+
+ /* will fail if cert is not verified */
+ if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL)
+ return NULL;
+
+ return (CERT_GetCommonName(&signercert->subject));
+}
+
+/*
+ * NSS_CMSSignerInfo_GetSignerEmailAddress - return the common name of the signer
+ *
+ * sinfo - signerInfo data for this signer
+ *
+ * Returns a pointer to allocated memory, which must be freed.
+ * A return value of NULL is an error.
+ */
+char *
+NSS_CMSSignerInfo_GetSignerEmailAddress(NSSCMSSignerInfo *sinfo)
+{
+ CERTCertificate *signercert;
+
+ if ((signercert = NSS_CMSSignerInfo_GetSigningCertificate(sinfo, NULL)) == NULL)
+ return NULL;
+
+ if (!signercert->emailAddr || !signercert->emailAddr[0])
+ return NULL;
+
+ return (PORT_Strdup(signercert->emailAddr));
+}
+
+/*
+ * NSS_CMSSignerInfo_AddAuthAttr - add an attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+SECStatus
+NSS_CMSSignerInfo_AddAuthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr)
+{
+ return NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->authAttr), attr);
+}
+
+/*
+ * NSS_CMSSignerInfo_AddUnauthAttr - add an attribute to the
+ * unauthenticated attributes of "signerinfo".
+ */
+SECStatus
+NSS_CMSSignerInfo_AddUnauthAttr(NSSCMSSignerInfo *signerinfo, NSSCMSAttribute *attr)
+{
+ return NSS_CMSAttributeArray_AddAttr(signerinfo->cmsg->poolp, &(signerinfo->unAuthAttr), attr);
+}
+
+/*
+ * NSS_CMSSignerInfo_AddSigningTime - add the signing time to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ *
+ * This is expected to be included in outgoing signed
+ * messages for email (S/MIME) but is likely useful in other situations.
+ *
+ * This should only be added once; a second call will do nothing.
+ *
+ * XXX This will probably just shove the current time into "signerinfo"
+ * but it will not actually get signed until the entire item is
+ * processed for encoding. Is this (expected to be small) delay okay?
+ */
+SECStatus
+NSS_CMSSignerInfo_AddSigningTime(NSSCMSSignerInfo *signerinfo, PRTime t)
+{
+ NSSCMSAttribute *attr;
+ SECItem stime;
+ void *mark;
+ PLArenaPool *poolp;
+
+ poolp = signerinfo->cmsg->poolp;
+
+ mark = PORT_ArenaMark(poolp);
+
+ /* create new signing time attribute */
+ if (DER_EncodeTimeChoice(NULL, &stime, t) != SECSuccess)
+ goto loser;
+
+ if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SIGNING_TIME, &stime, PR_FALSE)) == NULL) {
+ SECITEM_FreeItem (&stime, PR_FALSE);
+ goto loser;
+ }
+
+ SECITEM_FreeItem (&stime, PR_FALSE);
+
+ if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
+ goto loser;
+
+ PORT_ArenaUnmark (poolp, mark);
+
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease (poolp, mark);
+ return SECFailure;
+}
+
+/*
+ * NSS_CMSSignerInfo_AddSMIMECaps - add a SMIMECapabilities attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ *
+ * This is expected to be included in outgoing signed
+ * messages for email (S/MIME).
+ */
+SECStatus
+NSS_CMSSignerInfo_AddSMIMECaps(NSSCMSSignerInfo *signerinfo)
+{
+ NSSCMSAttribute *attr;
+ SECItem *smimecaps = NULL;
+ void *mark;
+ PLArenaPool *poolp;
+
+ poolp = signerinfo->cmsg->poolp;
+
+ mark = PORT_ArenaMark(poolp);
+
+ smimecaps = SECITEM_AllocItem(poolp, NULL, 0);
+ if (smimecaps == NULL)
+ goto loser;
+
+ /* create new signing time attribute */
+ if (NSS_SMIMEUtil_CreateSMIMECapabilities(poolp, smimecaps) != SECSuccess)
+ goto loser;
+
+ if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_PKCS9_SMIME_CAPABILITIES, smimecaps, PR_TRUE)) == NULL)
+ goto loser;
+
+ if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
+ goto loser;
+
+ PORT_ArenaUnmark (poolp, mark);
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease (poolp, mark);
+ return SECFailure;
+}
+
+/*
+ * NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ *
+ * This is expected to be included in outgoing signed messages for email (S/MIME).
+ */
+SECStatus
+NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb)
+{
+ NSSCMSAttribute *attr;
+ SECItem *smimeekp = NULL;
+ void *mark;
+ PLArenaPool *poolp;
+
+ /* verify this cert for encryption */
+ if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
+ return SECFailure;
+ }
+
+ poolp = signerinfo->cmsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+
+ smimeekp = SECITEM_AllocItem(poolp, NULL, 0);
+ if (smimeekp == NULL)
+ goto loser;
+
+ /* create new signing time attribute */
+ if (NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess)
+ goto loser;
+
+ if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL)
+ goto loser;
+
+ if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
+ goto loser;
+
+ PORT_ArenaUnmark (poolp, mark);
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease (poolp, mark);
+ return SECFailure;
+}
+
+/*
+ * NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs - add a SMIMEEncryptionKeyPreferences attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo", using the OID preferred by Microsoft.
+ *
+ * This is expected to be included in outgoing signed messages for email (S/MIME),
+ * if compatibility with Microsoft mail clients is wanted.
+ */
+SECStatus
+NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs(NSSCMSSignerInfo *signerinfo, CERTCertificate *cert, CERTCertDBHandle *certdb)
+{
+ NSSCMSAttribute *attr;
+ SECItem *smimeekp = NULL;
+ void *mark;
+ PLArenaPool *poolp;
+
+ /* verify this cert for encryption */
+ if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
+ return SECFailure;
+ }
+
+ poolp = signerinfo->cmsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+
+ smimeekp = SECITEM_AllocItem(poolp, NULL, 0);
+ if (smimeekp == NULL)
+ goto loser;
+
+ /* create new signing time attribute */
+ if (NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(poolp, smimeekp, cert) != SECSuccess)
+ goto loser;
+
+ if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE, smimeekp, PR_TRUE)) == NULL)
+ goto loser;
+
+ if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
+ goto loser;
+
+ PORT_ArenaUnmark (poolp, mark);
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease (poolp, mark);
+ return SECFailure;
+}
+
+/*
+ * NSS_CMSSignerInfo_AddCounterSignature - countersign a signerinfo
+ *
+ * 1. digest the DER-encoded signature value of the original signerinfo
+ * 2. create new signerinfo with correct version, sid, digestAlg
+ * 3. add message-digest authAttr, but NO content-type
+ * 4. sign the authAttrs
+ * 5. DER-encode the new signerInfo
+ * 6. add the whole thing to original signerInfo's unAuthAttrs
+ * as a SEC_OID_PKCS9_COUNTER_SIGNATURE attribute
+ *
+ * XXXX give back the new signerinfo?
+ */
+SECStatus
+NSS_CMSSignerInfo_AddCounterSignature(NSSCMSSignerInfo *signerinfo,
+ SECOidTag digestalg, CERTCertificate signingcert)
+{
+ /* XXXX TBD XXXX */
+ return SECFailure;
+}
+
+/*
+ * NSS_CMSSignerInfo_AddSecureHeader - add Secure Headers attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+SECStatus
+NSS_CMSSignerInfo_AddSecureHeader(NSSCMSSignerInfo *signerinfo, SecHeaderField * arrayHeaderField, int nbHeaders, long canonAlgo)
+{
+ NSSCMSAttribute *attr;
+ SECItem *secureHeaders = NULL;
+ void *mark;
+ PLArenaPool *poolp;
+
+ poolp = signerinfo->cmsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+
+ secureHeaders = SECITEM_AllocItem(poolp, NULL, 0);
+ if (secureHeaders == NULL)
+ goto loser;
+
+ /* create new secureHeaders attribute */
+ if (NSS_SMIMEUtil_CreateSecureHeader(poolp, secureHeaders, arrayHeaderField, nbHeaders, canonAlgo) != SECSuccess)
+ goto loser;
+
+ if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_SMIME_SECURE_HEADERS, secureHeaders, PR_TRUE)) == NULL)
+ goto loser;
+
+ if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
+ goto loser;
+
+ PORT_ArenaUnmark (poolp, mark);
+
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease (poolp, mark);
+ return SECFailure;
+}
+
+/*
+ * NSS_CMSSignerInfo_GetSecureHeader - get S/MIME SecureHeaders attr value
+ */
+SECStatus
+NSS_CMSSignerInfo_GetSecureHeader(NSSCMSSignerInfo *signerinfo, NSSCMSSecureHeader *secHeaders)
+{
+ return NSS_SMIMEUtil_GetSecureHeader(signerinfo, secHeaders);
+}
+
+/*
+ * XXXX the following needs to be done in the S/MIME layer code
+ * after signature of a signerinfo is verified
+ */
+SECStatus
+NSS_SMIMESignerInfo_SaveSMIMEProfile(NSSCMSSignerInfo *signerinfo)
+{
+ CERTCertificate *cert = NULL;
+ SECItem *profile = NULL;
+ NSSCMSAttribute *attr;
+ SECItem *stime = NULL;
+ SECItem *ekp;
+ CERTCertDBHandle *certdb;
+ int save_error;
+ SECStatus rv;
+ PRBool must_free_cert = PR_FALSE;
+
+ certdb = CERT_GetDefaultCertDB();
+
+ /* sanity check - see if verification status is ok (unverified does not count...) */
+ if (signerinfo->verificationStatus != NSSCMSVS_GoodSignature)
+ return SECFailure;
+
+ /* find preferred encryption cert */
+ if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr) &&
+ (attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
+ SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE, PR_TRUE)) != NULL)
+ { /* we have a SMIME_ENCRYPTION_KEY_PREFERENCE attribute! */
+ ekp = NSS_CMSAttribute_GetValue(attr);
+ if (ekp == NULL)
+ return SECFailure;
+
+ /* we assume that all certs coming with the message have been imported to the */
+ /* temporary database */
+ cert = NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(certdb, ekp);
+ if (cert == NULL)
+ return SECFailure;
+ must_free_cert = PR_TRUE;
+ }
+
+ if (cert == NULL) {
+ /* no preferred cert found?
+ * find the cert the signerinfo is signed with instead */
+ cert = NSS_CMSSignerInfo_GetSigningCertificate(signerinfo, certdb);
+ if (cert == NULL || cert->emailAddr == NULL || !cert->emailAddr[0])
+ return SECFailure;
+ }
+
+ /* verify this cert for encryption (has been verified for signing so far) */
+ /* don't verify this cert for encryption. It may just be a signing cert.
+ * that's OK, we can still save the S/MIME profile. The encryption cert
+ * should have already been saved */
+#ifdef notdef
+ if (CERT_VerifyCert(certdb, cert, PR_TRUE, certUsageEmailRecipient, PR_Now(), signerinfo->cmsg->pwfn_arg, NULL) != SECSuccess) {
+ if (must_free_cert)
+ CERT_DestroyCertificate(cert);
+ return SECFailure;
+ }
+#endif
+
+ /* XXX store encryption cert permanently? */
+
+ /*
+ * Remember the current error set because we do not care about
+ * anything set by the functions we are about to call.
+ */
+ save_error = PORT_GetError();
+
+ if (!NSS_CMSArray_IsEmpty((void **)signerinfo->authAttr)) {
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
+ SEC_OID_PKCS9_SMIME_CAPABILITIES,
+ PR_TRUE);
+ profile = NSS_CMSAttribute_GetValue(attr);
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr,
+ SEC_OID_PKCS9_SIGNING_TIME,
+ PR_TRUE);
+ stime = NSS_CMSAttribute_GetValue(attr);
+ }
+
+ rv = CERT_SaveSMimeProfile (cert, profile, stime);
+ if (must_free_cert)
+ CERT_DestroyCertificate(cert);
+
+ /*
+ * Restore the saved error in case the calls above set a new
+ * one that we do not actually care about.
+ */
+ PORT_SetError (save_error);
+
+ return rv;
+}
+
+/*
+ * NSS_CMSSignerInfo_IncludeCerts - set cert chain inclusion mode for this signer
+ */
+SECStatus
+NSS_CMSSignerInfo_IncludeCerts(NSSCMSSignerInfo *signerinfo, NSSCMSCertChainMode cm, SECCertUsage usage)
+{
+ if (signerinfo->cert == NULL)
+ return SECFailure;
+
+ /* don't leak if we get called twice */
+ if (signerinfo->certList != NULL) {
+ CERT_DestroyCertificateList(signerinfo->certList);
+ signerinfo->certList = NULL;
+ }
+
+ switch (cm) {
+ case NSSCMSCM_None:
+ signerinfo->certList = NULL;
+ break;
+ case NSSCMSCM_CertOnly:
+ signerinfo->certList = CERT_CertListFromCert(signerinfo->cert);
+ break;
+ case NSSCMSCM_CertChain:
+ signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_FALSE);
+ break;
+ case NSSCMSCM_CertChainWithRoot:
+ signerinfo->certList = CERT_CertChainFromCert(signerinfo->cert, usage, PR_TRUE);
+ break;
+ }
+
+ if (cm != NSSCMSCM_None && signerinfo->certList == NULL)
+ return SECFailure;
+
+ return SECSuccess;
+}
+
+/*
+ * NSS_CMSSignerInfo_AddReceiptRequest - add a ReceiptRequest attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+SECStatus
+NSS_CMSSignerInfo_AddReceiptRequest(NSSCMSSignerInfo *aSignerinfo,
+ char *aSignedContentIdentifier,
+ char *aReceiptsTo)
+{
+ NSSCMSAttribute *attr;
+ SECItem *receiptRequest = NULL;
+ void *mark;
+ PLArenaPool *poolp;
+
+ poolp = aSignerinfo->cmsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+
+ receiptRequest = SECITEM_AllocItem(poolp, NULL, 0);
+ if (receiptRequest == NULL)
+ goto loser;
+
+ /* create new receiptRequest attribute */
+ if (NSS_SMIMEUtil_CreateReceiptRequest(poolp, receiptRequest, aSignedContentIdentifier, aReceiptsTo) != SECSuccess)
+ goto loser;
+
+ if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_SMIME_RECEIPT_REQUEST, receiptRequest, PR_TRUE)) == NULL)
+ goto loser;
+
+ if (NSS_CMSSignerInfo_AddAuthAttr(aSignerinfo, attr) != SECSuccess)
+ goto loser;
+
+ PORT_ArenaUnmark(poolp, mark);
+
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease(poolp, mark);
+ return SECFailure;
+}
+
+/*
+ * NSS_CMSSignerInfo_GetReceiptRequest - get S/MIME ReceiptRequest values
+ */
+SECStatus
+NSS_CMSSignerInfo_GetReceiptRequest(NSSCMSSignerInfo *aSignerinfo,
+ PRBool *aHasReceiptRequest,
+ unsigned char **aSignedContentIdentifier,
+ unsigned int *aSignedContentIdentifierLen,
+ unsigned int *aReceiptsFrom,
+ char **aReceiptsTo,
+ unsigned char **aOriginatorSignatureValue,
+ unsigned int *aOriginatorSignatureValueLen,
+ unsigned char **aOriginatorContentType,
+ unsigned int *aOriginatorContentTypeLen,
+ unsigned char **aMsgSigDigest,
+ unsigned int *aMsgSigDigestLen)
+{
+ return NSS_SMIMEUtil_GetReceiptRequest(aSignerinfo,
+ aHasReceiptRequest,
+ aSignedContentIdentifier,
+ aSignedContentIdentifierLen,
+ aReceiptsFrom,
+ aReceiptsTo,
+ aOriginatorSignatureValue,
+ aOriginatorSignatureValueLen,
+ aOriginatorContentType,
+ aOriginatorContentTypeLen,
+ aMsgSigDigest,
+ aMsgSigDigestLen);
+}
+
+/*
+ * NSS_CMSSignerInfo_AddMsgSigDigest - add a MsgSigDigest attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+SECStatus
+NSS_CMSSignerInfo_AddMsgSigDigest(NSSCMSSignerInfo *aSignerinfo,
+ unsigned char *aReceiptMsgSigDigest,
+ unsigned int aReceiptMsgSigDigestLen)
+{
+ NSSCMSAttribute *attr;
+ SECItem msgSigDigest;
+ SECItem encMsgSigDigest;
+ void *mark;
+ PLArenaPool *poolp;
+ SECItem *dummy = NULL;
+
+ poolp = aSignerinfo->cmsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+
+ /* create new attribute */
+ msgSigDigest.data = aReceiptMsgSigDigest;
+ msgSigDigest.len = aReceiptMsgSigDigestLen;
+ if ((dummy = SEC_ASN1EncodeItem(poolp, &encMsgSigDigest, &msgSigDigest, SEC_ASN1_GET(SEC_OctetStringTemplate))) == NULL)
+ goto loser;
+
+ if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_SMIME_RECEIPT_MSGSIGDIGEST, &encMsgSigDigest, PR_TRUE)) == NULL)
+ goto loser;
+
+ if (NSS_CMSSignerInfo_AddAuthAttr(aSignerinfo, attr) != SECSuccess)
+ goto loser;
+
+ PORT_ArenaUnmark(poolp, mark);
+
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease(poolp, mark);
+ return SECFailure;
+}
+
+/*
+ * NSS_CMSSignerInfo_GetMsgSigDigest - get the MsgSigDigest attribute from the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+SECStatus
+NSS_CMSSignerInfo_GetMsgSigDigest(NSSCMSSignerInfo *aSignerinfo,
+ unsigned char **aReceiptMsgSigDigest,
+ unsigned int *aReceiptMsgSigDigestLen)
+{
+ NSSCMSAttribute *attr;
+ void *mark;
+ PLArenaPool *poolp;
+ SECItem decodedSECItem;
+ unsigned int len;
+
+ poolp = aSignerinfo->cmsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(aSignerinfo->authAttr, SEC_OID_SMIME_RECEIPT_MSGSIGDIGEST, PR_TRUE);
+ if (attr == NULL || attr->values == NULL || attr->values[0] == NULL)
+ goto loser;
+
+ if ((SEC_ASN1DecodeItem(poolp, &decodedSECItem, SEC_ASN1_GET(SEC_OctetStringTemplate), attr->values[0])) != SECSuccess)
+ goto loser;
+
+ len = decodedSECItem.len;
+ if (len == 0)
+ goto loser;
+
+ *aReceiptMsgSigDigest = PORT_Alloc(len);
+ PORT_Memcpy(*aReceiptMsgSigDigest, decodedSECItem.data, len);
+ *aReceiptMsgSigDigestLen = len;
+
+ PORT_ArenaUnmark(poolp, mark);
+
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease(poolp, mark);
+ return SECFailure;
+}
+
+/*
+ * NSS_CMSSignerInfo_HasReceipt - check if signer info's content-type attribute is S/MIME Receipt
+ */
+PRBool
+NSS_CMSSignerInfo_HasReceipt(NSSCMSSignerInfo *signerinfo)
+{
+ NSSCMSAttribute *attr;
+ SECOidData *smimeReceiptOid;
+
+ /* Get content-type */
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr, SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE);
+ if (attr == NULL || attr->values == NULL || attr->values[0] == NULL)
+ return PR_FALSE;
+
+ /* Compare content-type with receipt content-type */
+ smimeReceiptOid = SECOID_FindOIDByTag(SEC_OID_SMIME_RECEIPT);
+ if (!smimeReceiptOid || !NSS_CMSAttribute_CompareValue(attr, &(smimeReceiptOid->oid)))
+ return PR_FALSE;
+
+ return PR_TRUE;
+}
+
+/*
+ * NSS_CMSSignerInfo_AddSecurityLabel - add a SecurityLabel attribute to the
+ * authenticated (i.e. signed) attributes of "signerinfo".
+ */
+SECStatus
+NSS_CMSSignerInfo_AddSecurityLabel(NSSCMSSignerInfo *signerinfo,
+ char *securityPolicyIdentifier,
+ int securityClassification,
+ char *privacyMark,
+ char *securityCategories)
+{
+ NSSCMSAttribute *attr;
+ SECItem *securityLabel = NULL;
+ void *mark;
+ PLArenaPool *poolp;
+
+ poolp = signerinfo->cmsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+
+ securityLabel = SECITEM_AllocItem(poolp, NULL, 0);
+ if (securityLabel == NULL)
+ goto loser;
+
+ /* create new SecurityLabel attribute */
+ if (NSS_SMIMEUtil_CreateSecurityLabel(poolp, securityLabel, securityPolicyIdentifier, securityClassification, privacyMark, securityCategories) != SECSuccess)
+ goto loser;
+
+ if ((attr = NSS_CMSAttribute_Create(poolp, SEC_OID_SMIME_SECURITY_LABEL, securityLabel, PR_TRUE)) == NULL)
+ goto loser;
+
+ if (NSS_CMSSignerInfo_AddAuthAttr(signerinfo, attr) != SECSuccess)
+ goto loser;
+
+ PORT_ArenaUnmark (poolp, mark);
+
+ return SECSuccess;
+
+loser:
+ PORT_ArenaRelease (poolp, mark);
+ return SECFailure;
+}
+
+/*
+ * NSS_CMSSignerInfo_GetSecurityLabel - get S/MIME SecurityLabel attr value
+ */
+SECStatus
+NSS_CMSSignerInfo_GetSecurityLabel(NSSCMSSignerInfo *aSignerinfo,
+ PRBool *aHasSecurityLabel,
+ char **aSecurityPolicyIdentifier,
+ int *aSecurityClassification,
+ char **aPrivacyMark,
+ char **aSecurityCategories)
+{
+ return NSS_SMIMEUtil_GetSecurityLabel(aSignerinfo,
+ aHasSecurityLabel,
+ aSecurityPolicyIdentifier,
+ aSecurityClassification,
+ aPrivacyMark,
+ aSecurityCategories);
+}
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved */
+
+/*
+ * Header for CMS types.
+ *
+ * $Id: cmst.h,v 1.15 2012/04/25 14:50:09 gerv%gerv.net Exp $
+ */
+
+#ifndef _CMST_H_
+#define _CMST_H_
+
+#include "seccomon.h"
+#include "secoidt.h"
+#include "certt.h"
+#include "secmodt.h"
+#include "secmodt.h"
+
+#include "plarena.h"
+
+/* Non-opaque objects. NOTE, though: I want them to be treated as
+ * opaque as much as possible. If I could hide them completely,
+ * I would. (I tried, but ran into trouble that was taking me too
+ * much time to get out of.) I still intend to try to do so.
+ * In fact, the only type that "outsiders" should even *name* is
+ * NSSCMSMessage, and they should not reference its fields.
+ */
+/* rjr: PKCS #11 cert handling (pk11cert.c) does use NSSCMSRecipientInfo's.
+ * This is because when we search the recipient list for the cert and key we
+ * want, we need to invert the order of the loops we used to have. The old
+ * loops were:
+ *
+ * For each recipient {
+ * find_cert = PK11_Find_AllCert(recipient->issuerSN);
+ * [which unrolls to... ]
+ * For each slot {
+ * Log into slot;
+ * search slot for cert;
+ * }
+ * }
+ *
+ * the new loop searchs all the recipients at once on a slot. this allows
+ * PKCS #11 to order slots in such a way that logout slots don't get checked
+ * if we can find the cert on a logged in slot. This eliminates lots of
+ * spurious password prompts when smart cards are installed... so why this
+ * comment? If you make NSSCMSRecipientInfo completely opaque, you need
+ * to provide a non-opaque list of issuerSN's (the only field PKCS#11 needs
+ * and fix up pk11cert.c first. NOTE: Only S/MIME calls this special PKCS #11
+ * function.
+ */
+
+typedef struct NSSCMSMessageStr NSSCMSMessage;
+
+typedef union NSSCMSContentUnion NSSCMSContent;
+typedef struct NSSCMSContentInfoStr NSSCMSContentInfo;
+
+typedef struct NSSCMSSignedDataStr NSSCMSSignedData;
+typedef struct NSSCMSSignerInfoStr NSSCMSSignerInfo;
+typedef struct NSSCMSSignerIdentifierStr NSSCMSSignerIdentifier;
+
+typedef struct NSSCMSEnvelopedDataStr NSSCMSEnvelopedData;
+typedef struct NSSCMSOriginatorInfoStr NSSCMSOriginatorInfo;
+typedef struct NSSCMSRecipientInfoStr NSSCMSRecipientInfo;
+
+typedef struct NSSCMSDigestedDataStr NSSCMSDigestedData;
+typedef struct NSSCMSEncryptedDataStr NSSCMSEncryptedData;
+
+typedef struct NSSCMSGenericWrapperDataStr NSSCMSGenericWrapperData;
+
+typedef struct NSSCMSAttributeStr NSSCMSAttribute;
+
+typedef struct NSSCMSDecoderContextStr NSSCMSDecoderContext;
+typedef struct NSSCMSEncoderContextStr NSSCMSEncoderContext;
+
+typedef struct NSSCMSCipherContextStr NSSCMSCipherContext;
+typedef struct NSSCMSDigestContextStr NSSCMSDigestContext;
+
+typedef struct NSSCMSReceiptRequestStr NSSCMSReceiptRequest;
+typedef struct NSSCMSReceiptRequestGeneralNamesStr NSSCMSReceiptRequestGeneralNames;
+typedef struct NSSCMSReceiptStr NSSCMSReceipt;
+
+typedef struct NSSCMSSecurityLabelStr NSSCMSSecurityLabel;
+typedef struct NSSCMSSecurityLabelElementStr NSSCMSSecurityLabelElement;
+typedef struct NSSCMSSecurityLabelSecurityCategoryStr NSSCMSSecurityLabelSecurityCategory;
+
+typedef struct NSSCMSContentInfoPrivateStr NSSCMSContentInfoPrivate;
+
+typedef SECStatus (*NSSCMSGenericWrapperDataCallback)
+ (NSSCMSGenericWrapperData *);
+typedef void (*NSSCMSGenericWrapperDataDestroy)
+ (NSSCMSGenericWrapperData *);
+
+extern const SEC_ASN1Template NSSCMSGenericWrapperDataTemplate[];
+extern const SEC_ASN1Template NSS_PointerToCMSGenericWrapperDataTemplate[];
+
+SEC_ASN1_CHOOSER_DECLARE(NSS_PointerToCMSGenericWrapperDataTemplate)
+SEC_ASN1_CHOOSER_DECLARE(NSSCMSGenericWrapperDataTemplate)
+
+
+
+/*
+ * Type of function passed to NSSCMSDecode or NSSCMSDecoderStart.
+ * If specified, this is where the content bytes (only) will be "sent"
+ * as they are recovered during the decoding.
+ * And:
+ * Type of function passed to NSSCMSEncode or NSSCMSEncoderStart.
+ * This is where the DER-encoded bytes will be "sent".
+ *
+ * XXX Should just combine this with NSSCMSEncoderContentCallback type
+ * and use a simpler, common name.
+ */
+typedef void (*NSSCMSContentCallback)(void *arg, const char *buf, unsigned long len);
+
+/*
+ * Type of function passed to NSSCMSDecode or NSSCMSDecoderStart
+ * to retrieve the decryption key. This function is intended to be
+ * used for EncryptedData content info's which do not have a key available
+ * in a certificate, etc.
+ */
+typedef PK11SymKey *(*NSSCMSGetDecryptKeyCallback)(void *arg, SECAlgorithmID *algid);
+
+
+/* =============================================================================
+ * ENCAPSULATED CONTENTINFO & CONTENTINFO
+ */
+
+union NSSCMSContentUnion {
+ /* either unstructured */
+ SECItem * data;
+ /* or structured data */
+ NSSCMSDigestedData * digestedData;
+ NSSCMSEncryptedData * encryptedData;
+ NSSCMSEnvelopedData * envelopedData;
+ NSSCMSSignedData * signedData;
+ NSSCMSGenericWrapperData * genericData;
+ /* or anonymous pointer to something */
+ void * pointer;
+};
+
+struct NSSCMSContentInfoStr {
+ SECItem contentType;
+ NSSCMSContent content;
+ /* --------- local; not part of encoding --------- */
+ SECOidData * contentTypeTag;
+
+ /* additional info for encryptedData and envelopedData */
+ /* we waste this space for signedData and digestedData. sue me. */
+
+ SECAlgorithmID contentEncAlg;
+ SECItem * rawContent; /* encrypted DER, optional */
+ /* XXXX bytes not encrypted, but encoded? */
+ /* --------- local; not part of encoding --------- */
+ PK11SymKey * bulkkey; /* bulk encryption key */
+ int keysize; /* size of bulk encryption key
+ * (only used by creation code) */
+ SECOidTag contentEncAlgTag; /* oid tag of encryption algorithm
+ * (only used by creation code) */
+ NSSCMSContentInfoPrivate *privateInfo; /* place for NSS private info */
+ void *reserved; /* keep binary compatibility */
+};
+
+/* =============================================================================
+ * MESSAGE
+ */
+
+struct NSSCMSMessageStr {
+ NSSCMSContentInfo contentInfo; /* "outer" cinfo */
+ /* --------- local; not part of encoding --------- */
+ PLArenaPool * poolp;
+ PRBool poolp_is_ours;
+ int refCount;
+ /* properties of the "inner" data */
+ SECAlgorithmID ** detached_digestalgs;
+ SECItem ** detached_digests;
+ void * pwfn_arg;
+ NSSCMSGetDecryptKeyCallback decrypt_key_cb;
+ void * decrypt_key_cb_arg;
+};
+
+/* ============================================================================
+ * GENERIC WRAPPER
+ *
+ * used for user defined types.
+ */
+struct NSSCMSGenericWrapperDataStr {
+ NSSCMSContentInfo contentInfo;
+ /* ---- local; not part of encoding ------ */
+ NSSCMSMessage * cmsg;
+ /* wrapperspecific data starts here */
+};
+
+/* =============================================================================
+ * SIGNEDDATA
+ */
+
+struct NSSCMSSignedDataStr {
+ SECItem version;
+ SECAlgorithmID ** digestAlgorithms;
+ NSSCMSContentInfo contentInfo;
+ SECItem ** rawCerts;
+ CERTSignedCrl ** crls;
+ NSSCMSSignerInfo ** signerInfos;
+ /* --------- local; not part of encoding --------- */
+ NSSCMSMessage * cmsg; /* back pointer to message */
+ SECItem ** digests;
+ CERTCertificate ** certs;
+ CERTCertificateList ** certLists;
+ CERTCertificate ** tempCerts; /* temporary certs, needed
+ * for example for signature
+ * verification */
+};
+#define NSS_CMS_SIGNED_DATA_VERSION_BASIC 1 /* what we *create* */
+#define NSS_CMS_SIGNED_DATA_VERSION_EXT 3 /* what we *create* */
+
+typedef enum {
+ NSSCMSVS_Unverified = 0,
+ NSSCMSVS_GoodSignature = 1,
+ NSSCMSVS_BadSignature = 2,
+ NSSCMSVS_DigestMismatch = 3,
+ NSSCMSVS_SigningCertNotFound = 4,
+ NSSCMSVS_SigningCertNotTrusted = 5,
+ NSSCMSVS_SignatureAlgorithmUnknown = 6,
+ NSSCMSVS_SignatureAlgorithmUnsupported = 7,
+ NSSCMSVS_MalformedSignature = 8,
+ NSSCMSVS_ProcessingError = 9
+} NSSCMSVerificationStatus;
+
+typedef enum {
+ NSSCMSSignerID_IssuerSN = 0,
+ NSSCMSSignerID_SubjectKeyID = 1
+} NSSCMSSignerIDSelector;
+
+struct NSSCMSSignerIdentifierStr {
+ NSSCMSSignerIDSelector identifierType;
+ union {
+ CERTIssuerAndSN *issuerAndSN;
+ SECItem *subjectKeyID;
+ } id;
+};
+
+struct NSSCMSSignerInfoStr {
+ SECItem version;
+ NSSCMSSignerIdentifier signerIdentifier;
+ SECAlgorithmID digestAlg;
+ NSSCMSAttribute ** authAttr;
+ SECAlgorithmID digestEncAlg;
+ SECItem encDigest;
+ NSSCMSAttribute ** unAuthAttr;
+ /* --------- local; not part of encoding --------- */
+ NSSCMSMessage * cmsg; /* back pointer to message */
+ CERTCertificate * cert;
+ CERTCertificateList * certList;
+ PRTime signingTime;
+ NSSCMSVerificationStatus verificationStatus;
+ SECKEYPrivateKey * signingKey; /* Used if we're using subjKeyID*/
+ SECKEYPublicKey * pubKey;
+};
+#define NSS_CMS_SIGNER_INFO_VERSION_ISSUERSN 1 /* what we *create* */
+#define NSS_CMS_SIGNER_INFO_VERSION_SUBJKEY 3 /* what we *create* */
+
+typedef enum {
+ NSSCMSCM_None = 0,
+ NSSCMSCM_CertOnly = 1,
+ NSSCMSCM_CertChain = 2,
+ NSSCMSCM_CertChainWithRoot = 3
+} NSSCMSCertChainMode;
+
+
+
+/*
+ * SECURE HEADERS : Datas structures
+ * */
+
+typedef struct NSSCMSSecHeaderFieldElementStr NSSCMSSecHeaderFieldElement;
+
+typedef struct NSSCMSSecureHeaderElementStr NSSCMSSecureHeaderElement;
+
+typedef struct NSSCMSSecureHeaderStr NSSCMSSecureHeader;
+
+typedef struct SecHeaderFieldStr SecHeaderField;
+
+typedef enum {
+ NSSCMSSecureHeaderElement_canonAlgorithm = 0,
+ NSSCMSSecureHeaderElement_secHeaderField = 1
+} NSSCMSSecureHeaderElementSelector;
+
+struct NSSCMSSecHeaderFieldElementStr{
+ SECItem HeaderFieldName;
+ SECItem HeaderFieldValue;
+ SECItem HeaderFieldStatus;
+ /*SECItem HeaderFieldEncrypted;*/
+};
+
+struct NSSCMSSecureHeaderElementStr{
+ NSSCMSSecureHeaderElementSelector selector;
+ union {
+ SECItem canonAlgorithm;
+ NSSCMSSecHeaderFieldElement** secHeaderFields;
+ } id;
+};
+
+struct NSSCMSSecureHeaderStr {
+ NSSCMSSecureHeaderElement** element;
+};
+
+
+struct SecHeaderFieldStr{
+ char * headerName;
+ char * headerValue;
+ PRInt32 headerStatus;
+ /*PRInt32 headerEncrypted;*/
+};
+/*
+ *END SECURE HEADERS : Datas structures
+ * */
+
+/* ESS Signed Receipt Request */
+struct NSSCMSReceiptRequestGeneralNamesStr {
+ SECItem **generalNameSeq;
+};
+
+struct NSSCMSReceiptRequestStr {
+ SECItem signedContentIdentifier;
+ SECItem receiptsFrom;
+ NSSCMSReceiptRequestGeneralNames **receiptsTo;
+};
+
+/* ESS Signed Receipt */
+struct NSSCMSReceiptStr {
+ SECItem version;
+ SECItem contentType;
+ SECItem signedContentIdentifier;
+ SECItem originatorSignatureValue;
+};
+
+/* ESS Security Label */
+typedef enum {
+ NSSCMSSecurityLabelElement_securityPolicyIdentifier = 0,
+ NSSCMSSecurityLabelElement_securityClassification = 1,
+ NSSCMSSecurityLabelElement_privacyMarkPrintableString = 2,
+ NSSCMSSecurityLabelElement_privacyMarkUTF8 = 3,
+ NSSCMSSecurityLabelElement_securityCategories = 4
+} NSSCMSSecurityLabelElementSelector;
+
+struct NSSCMSSecurityLabelElementStr {
+ NSSCMSSecurityLabelElementSelector selector;
+ union {
+ SECItem securityPolicyIdentifier;
+ SECItem securityClassification;
+ SECItem privacyMarkPrintableString;
+ SECItem privacyMarkUTF8;
+ NSSCMSSecurityLabelSecurityCategory **securityCategories;
+ } id;
+};
+
+struct NSSCMSSecurityLabelStr {
+ NSSCMSSecurityLabelElement **element;
+};
+
+struct NSSCMSSecurityLabelSecurityCategoryStr {
+ SECItem securityCategoryIdentifier;
+ SECItem securityCategoryValue;
+};
+
+enum {
+ SECURITY_CATEGORY_VALUE_TYPE_UNKNOWN = 0,
+ SECURITY_CATEGORY_VALUE_TYPE_UTF8 = 1,
+ SECURITY_CATEGORY_VALUE_TYPE_INTEGER = 2
+};
+
+/* =============================================================================
+ * ENVELOPED DATA
+ */
+struct NSSCMSEnvelopedDataStr {
+ SECItem version;
+ NSSCMSOriginatorInfo * originatorInfo; /* optional */
+ NSSCMSRecipientInfo ** recipientInfos;
+ NSSCMSContentInfo contentInfo;
+ NSSCMSAttribute ** unprotectedAttr;
+ /* --------- local; not part of encoding --------- */
+ NSSCMSMessage * cmsg; /* back pointer to message */
+};
+#define NSS_CMS_ENVELOPED_DATA_VERSION_REG 0 /* what we *create* */
+#define NSS_CMS_ENVELOPED_DATA_VERSION_ADV 2 /* what we *create* */
+
+struct NSSCMSOriginatorInfoStr {
+ SECItem ** rawCerts;
+ CERTSignedCrl ** crls;
+ /* --------- local; not part of encoding --------- */
+ CERTCertificate ** certs;
+};
+
+/* -----------------------------------------------------------------------------
+ * key transport recipient info
+ */
+typedef enum {
+ NSSCMSRecipientID_IssuerSN = 0,
+ NSSCMSRecipientID_SubjectKeyID = 1,
+ NSSCMSRecipientID_BrandNew = 2
+} NSSCMSRecipientIDSelector;
+
+struct NSSCMSRecipientIdentifierStr {
+ NSSCMSRecipientIDSelector identifierType;
+ union {
+ CERTIssuerAndSN *issuerAndSN;
+ SECItem *subjectKeyID;
+ } id;
+};
+typedef struct NSSCMSRecipientIdentifierStr NSSCMSRecipientIdentifier;
+
+struct NSSCMSKeyTransRecipientInfoStr {
+ SECItem version;
+ NSSCMSRecipientIdentifier recipientIdentifier;
+ SECAlgorithmID keyEncAlg;
+ SECItem encKey;
+};
+typedef struct NSSCMSKeyTransRecipientInfoStr NSSCMSKeyTransRecipientInfo;
+
+/*
+ * View comments before NSSCMSRecipientInfoStr for purpose of this
+ * structure.
+ */
+struct NSSCMSKeyTransRecipientInfoExStr {
+ NSSCMSKeyTransRecipientInfo recipientInfo;
+ int version; /* version of this structure (0) */
+ SECKEYPublicKey *pubKey;
+};
+
+typedef struct NSSCMSKeyTransRecipientInfoExStr NSSCMSKeyTransRecipientInfoEx;
+
+#define NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_ISSUERSN 0 /* what we *create* */
+#define NSS_CMS_KEYTRANS_RECIPIENT_INFO_VERSION_SUBJKEY 2 /* what we *create* */
+
+/* -----------------------------------------------------------------------------
+ * key agreement recipient info
+ */
+struct NSSCMSOriginatorPublicKeyStr {
+ SECAlgorithmID algorithmIdentifier;
+ SECItem publicKey; /* bit string! */
+};
+typedef struct NSSCMSOriginatorPublicKeyStr NSSCMSOriginatorPublicKey;
+
+typedef enum {
+ NSSCMSOriginatorIDOrKey_IssuerSN = 0,
+ NSSCMSOriginatorIDOrKey_SubjectKeyID = 1,
+ NSSCMSOriginatorIDOrKey_OriginatorPublicKey = 2
+} NSSCMSOriginatorIDOrKeySelector;
+
+struct NSSCMSOriginatorIdentifierOrKeyStr {
+ NSSCMSOriginatorIDOrKeySelector identifierType;
+ union {
+ CERTIssuerAndSN *issuerAndSN; /* static-static */
+ SECItem *subjectKeyID; /* static-static */
+ NSSCMSOriginatorPublicKey originatorPublicKey; /* ephemeral-static */
+ } id;
+};
+typedef struct NSSCMSOriginatorIdentifierOrKeyStr NSSCMSOriginatorIdentifierOrKey;
+
+struct NSSCMSRecipientKeyIdentifierStr {
+ SECItem * subjectKeyIdentifier;
+ SECItem * date; /* optional */
+ SECItem * other; /* optional */
+};
+typedef struct NSSCMSRecipientKeyIdentifierStr NSSCMSRecipientKeyIdentifier;
+
+typedef enum {
+ NSSCMSKeyAgreeRecipientID_IssuerSN = 0,
+ NSSCMSKeyAgreeRecipientID_RKeyID = 1
+} NSSCMSKeyAgreeRecipientIDSelector;
+
+struct NSSCMSKeyAgreeRecipientIdentifierStr {
+ NSSCMSKeyAgreeRecipientIDSelector identifierType;
+ union {
+ CERTIssuerAndSN *issuerAndSN;
+ NSSCMSRecipientKeyIdentifier recipientKeyIdentifier;
+ } id;
+};
+typedef struct NSSCMSKeyAgreeRecipientIdentifierStr NSSCMSKeyAgreeRecipientIdentifier;
+
+struct NSSCMSRecipientEncryptedKeyStr {
+ NSSCMSKeyAgreeRecipientIdentifier recipientIdentifier;
+ SECItem encKey;
+};
+typedef struct NSSCMSRecipientEncryptedKeyStr NSSCMSRecipientEncryptedKey;
+
+struct NSSCMSKeyAgreeRecipientInfoStr {
+ SECItem version;
+ NSSCMSOriginatorIdentifierOrKey originatorIdentifierOrKey;
+ SECItem * ukm; /* optional */
+ SECAlgorithmID keyEncAlg;
+ NSSCMSRecipientEncryptedKey ** recipientEncryptedKeys;
+};
+typedef struct NSSCMSKeyAgreeRecipientInfoStr NSSCMSKeyAgreeRecipientInfo;
+
+#define NSS_CMS_KEYAGREE_RECIPIENT_INFO_VERSION 3 /* what we *create* */
+
+/* -----------------------------------------------------------------------------
+ * KEK recipient info
+ */
+struct NSSCMSKEKIdentifierStr {
+ SECItem keyIdentifier;
+ SECItem * date; /* optional */
+ SECItem * other; /* optional */
+};
+typedef struct NSSCMSKEKIdentifierStr NSSCMSKEKIdentifier;
+
+struct NSSCMSKEKRecipientInfoStr {
+ SECItem version;
+ NSSCMSKEKIdentifier kekIdentifier;
+ SECAlgorithmID keyEncAlg;
+ SECItem encKey;
+};
+typedef struct NSSCMSKEKRecipientInfoStr NSSCMSKEKRecipientInfo;
+
+#define NSS_CMS_KEK_RECIPIENT_INFO_VERSION 4 /* what we *create* */
+
+/* -----------------------------------------------------------------------------
+ * recipient info
+ */
+
+typedef enum {
+ NSSCMSRecipientInfoID_KeyTrans = 0,
+ NSSCMSRecipientInfoID_KeyAgree = 1,
+ NSSCMSRecipientInfoID_KEK = 2
+} NSSCMSRecipientInfoIDSelector;
+
+/*
+ * In order to preserve backwards binary compatibility when implementing
+ * creation of Recipient Info's that uses subjectKeyID in the
+ * keyTransRecipientInfo we need to stash a public key pointer in this
+ * structure somewhere. We figured out that NSSCMSKeyTransRecipientInfo
+ * is the smallest member of the ri union. We're in luck since that's
+ * the very structure that would need to use the public key. So we created
+ * a new structure NSSCMSKeyTransRecipientInfoEx which has a member
+ * NSSCMSKeyTransRecipientInfo as the first member followed by a version
+ * and a public key pointer. This way we can keep backwards compatibility
+ * without changing the size of this structure.
+ *
+ * BTW, size of structure:
+ * NSSCMSKeyTransRecipientInfo: 9 ints, 4 pointers
+ * NSSCMSKeyAgreeRecipientInfo: 12 ints, 8 pointers
+ * NSSCMSKEKRecipientInfo: 10 ints, 7 pointers
+ *
+ * The new structure:
+ * NSSCMSKeyTransRecipientInfoEx: sizeof(NSSCMSKeyTransRecipientInfo) +
+ * 1 int, 1 pointer
+ */
+
+struct NSSCMSRecipientInfoStr {
+ NSSCMSRecipientInfoIDSelector recipientInfoType;
+ union {
+ NSSCMSKeyTransRecipientInfo keyTransRecipientInfo;
+ NSSCMSKeyAgreeRecipientInfo keyAgreeRecipientInfo;
+ NSSCMSKEKRecipientInfo kekRecipientInfo;
+ NSSCMSKeyTransRecipientInfoEx keyTransRecipientInfoEx;
+ } ri;
+ /* --------- local; not part of encoding --------- */
+ NSSCMSMessage * cmsg; /* back pointer to message */
+ CERTCertificate * cert; /* recipient's certificate */
+};
+
+/* =============================================================================
+ * DIGESTED DATA
+ */
+struct NSSCMSDigestedDataStr {
+ SECItem version;
+ SECAlgorithmID digestAlg;
+ NSSCMSContentInfo contentInfo;
+ SECItem digest;
+ /* --------- local; not part of encoding --------- */
+ NSSCMSMessage * cmsg; /* back pointer */
+ SECItem cdigest; /* calculated digest */
+};
+#define NSS_CMS_DIGESTED_DATA_VERSION_DATA 0 /* what we *create* */
+#define NSS_CMS_DIGESTED_DATA_VERSION_ENCAP 2 /* what we *create* */
+
+/* =============================================================================
+ * ENCRYPTED DATA
+ */
+struct NSSCMSEncryptedDataStr {
+ SECItem version;
+ NSSCMSContentInfo contentInfo;
+ NSSCMSAttribute ** unprotectedAttr; /* optional */
+ /* --------- local; not part of encoding --------- */
+ NSSCMSMessage * cmsg; /* back pointer */
+};
+#define NSS_CMS_ENCRYPTED_DATA_VERSION 0 /* what we *create* */
+#define NSS_CMS_ENCRYPTED_DATA_VERSION_UPATTR 2 /* what we *create* */
+
+/*
+ * *****************************************************************************
+ * *****************************************************************************
+ * *****************************************************************************
+ */
+
+/*
+ * See comment above about this type not really belonging to CMS.
+ */
+struct NSSCMSAttributeStr {
+ /* The following fields make up an encoded Attribute: */
+ SECItem type;
+ SECItem ** values; /* data may or may not be encoded */
+ /* The following fields are not part of an encoded Attribute: */
+ SECOidData * typeTag;
+ PRBool encoded; /* when true, values are encoded */
+};
+
+#endif /* _CMST_H_ */
--- /dev/null
+;+#
+;+# This Source Code Form is subject to the terms of the Mozilla Public
+;+# License, v. 2.0. If a copy of the MPL was not distributed with this
+;+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+;+#
+;+# OK, this file is meant to support SUN, LINUX, AIX and WINDOWS
+;+# 1. For all unix platforms, the string ";-" means "remove this line"
+;+# 2. For all unix platforms, the string " DATA " will be removed from any
+;+# line on which it occurs.
+;+# 3. Lines containing ";+" will have ";+" removed on SUN and LINUX.
+;+# On AIX, lines containing ";+" will be removed.
+;+# 4. For all unix platforms, the string ";;" will thave the ";;" removed.
+;+# 5. For all unix platforms, after the above processing has taken place,
+;+# all characters after the first ";" on the line will be removed.
+;+# And for AIX, the first ";" will also be removed.
+;+# This file is passed directly to windows. Since ';' is a comment, all UNIX
+;+# directives are hidden behind ";", ";+", and ";-"
+;+
+;+NSS_3.2 { # NSS 3.2 release
+;+ global:
+LIBRARY smime3 ;-
+EXPORTS ;-
+NSS_CMSContentInfo_GetBulkKey;
+NSS_CMSContentInfo_GetBulkKeySize;
+NSS_CMSContentInfo_GetContent;
+NSS_CMSContentInfo_GetContentEncAlgTag;
+NSS_CMSContentInfo_GetContentTypeTag;
+NSS_CMSContentInfo_SetBulkKey;
+NSS_CMSContentInfo_SetContent;
+NSS_CMSContentInfo_SetContentEncAlg;
+NSS_CMSContentInfo_SetContent_Data;
+NSS_CMSContentInfo_SetContent_DigestedData;
+NSS_CMSContentInfo_SetContent_EncryptedData;
+NSS_CMSContentInfo_SetContent_EnvelopedData;
+NSS_CMSContentInfo_SetContent_SignedData;
+NSS_CMSDEREncode;
+NSS_CMSDecoder_Cancel;
+NSS_CMSDecoder_Finish;
+NSS_CMSDecoder_Start;
+NSS_CMSDecoder_Update;
+NSS_CMSDigestContext_Cancel;
+NSS_CMSDigestContext_FinishMultiple;
+NSS_CMSDigestContext_FinishSingle;
+NSS_CMSDigestContext_StartMultiple;
+NSS_CMSDigestContext_StartSingle;
+NSS_CMSDigestContext_Update;
+NSS_CMSDigestedData_Create;
+NSS_CMSDigestedData_Destroy;
+NSS_CMSDigestedData_GetContentInfo;
+NSS_CMSEncoder_Cancel;
+NSS_CMSEncoder_Finish;
+NSS_CMSEncoder_Start;
+NSS_CMSEncoder_Update;
+NSS_CMSEncryptedData_Create;
+NSS_CMSEncryptedData_Destroy;
+NSS_CMSEncryptedData_GetContentInfo;
+NSS_CMSEnvelopedData_AddRecipient;
+NSS_CMSEnvelopedData_Create;
+NSS_CMSEnvelopedData_Destroy;
+NSS_CMSEnvelopedData_GetContentInfo;
+NSS_CMSMessage_ContentLevel;
+NSS_CMSMessage_ContentLevelCount;
+NSS_CMSMessage_Copy;
+NSS_CMSMessage_Create;
+NSS_CMSMessage_CreateFromDER;
+NSS_CMSMessage_Destroy;
+NSS_CMSMessage_GetContent;
+NSS_CMSMessage_GetContentInfo;
+NSS_CMSRecipientInfo_Create;
+NSS_CMSRecipientInfo_Destroy;
+NSS_CMSSignedData_AddCertChain;
+NSS_CMSSignedData_AddCertList;
+NSS_CMSSignedData_AddCertificate;
+NSS_CMSSignedData_AddDigest;
+NSS_CMSSignedData_AddSignerInfo;
+NSS_CMSSignedData_Create;
+NSS_CMSSignedData_CreateCertsOnly;
+NSS_CMSSignedData_Destroy;
+NSS_CMSSignedData_GetContentInfo;
+NSS_CMSSignedData_GetDigestAlgs;
+NSS_CMSSignedData_GetSignerInfo;
+NSS_CMSSignedData_HasDigests;
+NSS_CMSSignedData_ImportCerts;
+NSS_CMSSignedData_SetDigests;
+NSS_CMSSignedData_SignerInfoCount;
+NSS_CMSSignedData_VerifyCertsOnly;
+NSS_CMSSignedData_VerifySignerInfo;
+NSS_CMSSignerInfo_AddSMIMECaps;
+NSS_CMSSignerInfo_AddSMIMEEncKeyPrefs;
+NSS_CMSSignerInfo_AddSigningTime;
+;+# Add Function for the Secure headers CASSIDIAN
+NSS_CMSSignerInfo_AddSecureHeader;
+NSS_CMSSignerInfo_GetSecureHeader;
+;+# End signed headers
+NSS_CMSSignerInfo_Create;
+NSS_CMSSignerInfo_Destroy;
+NSS_CMSSignerInfo_GetCertList;
+NSS_CMSSignerInfo_GetSignerCommonName;
+NSS_CMSSignerInfo_GetSignerEmailAddress;
+NSS_CMSSignerInfo_GetSigningCertificate;
+NSS_CMSSignerInfo_GetSigningTime;
+NSS_CMSSignerInfo_GetVerificationStatus;
+NSS_CMSSignerInfo_GetVersion;
+NSS_CMSSignerInfo_IncludeCerts;
+NSS_CMSUtil_VerificationStatusToString;
+NSS_SMIMEUtil_FindBulkAlgForRecipients;
+CERT_DecodeCertPackage;
+SEC_PKCS7AddRecipient;
+SEC_PKCS7AddSigningTime;
+SEC_PKCS7ContentType;
+SEC_PKCS7CreateData;
+SEC_PKCS7CreateEncryptedData;
+SEC_PKCS7CreateEnvelopedData;
+SEC_PKCS7CreateSignedData;
+SEC_PKCS7DecodeItem;
+SEC_PKCS7DecoderFinish;
+SEC_PKCS7DecoderStart;
+SEC_PKCS7DecoderUpdate;
+SEC_PKCS7DecryptContents;
+SEC_PKCS7DestroyContentInfo;
+SEC_PKCS7EncoderFinish;
+SEC_PKCS7EncoderStart;
+SEC_PKCS7EncoderUpdate;
+SEC_PKCS7GetCertificateList;
+SEC_PKCS7GetContent;
+SEC_PKCS7GetEncryptionAlgorithm;
+SEC_PKCS7IncludeCertChain;
+SEC_PKCS7IsContentEmpty;
+SEC_PKCS7VerifySignature;
+SEC_PKCS12AddCertAndKey;
+SEC_PKCS12AddPasswordIntegrity;
+SEC_PKCS12CreateExportContext;
+SEC_PKCS12CreatePasswordPrivSafe;
+SEC_PKCS12CreateUnencryptedSafe;
+SEC_PKCS12EnableCipher;
+SEC_PKCS12Encode;
+SEC_PKCS12DecoderImportBags;
+SEC_PKCS12DecoderFinish;
+SEC_PKCS12DecoderStart;
+SEC_PKCS12DecoderUpdate;
+SEC_PKCS12DecoderValidateBags;
+SEC_PKCS12DecoderVerify;
+SEC_PKCS12DestroyExportContext;
+SEC_PKCS12IsEncryptionAllowed;
+SEC_PKCS12SetPreferredCipher;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.2.1 { # NSS 3.2.1 release
+;+ global:
+NSSSMIME_VersionCheck;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.3 { # NSS 3.3 release
+;+ global:
+SEC_PKCS7AddCertificate;
+SEC_PKCS7CreateCertsOnly;
+SEC_PKCS7Encode;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.4 { # NSS 3.4 release
+;+ global:
+CERT_DecodeCertFromPackage;
+NSS_CMSMessage_IsSigned;
+NSS_CMSSignedData_SetDigestValue;
+NSS_SMIMESignerInfo_SaveSMIMEProfile;
+SEC_PKCS12DecoderGetCerts;
+SEC_PKCS7ContainsCertsOrCrls;
+SEC_PKCS7ContentIsEncrypted;
+SEC_PKCS7ContentIsSigned;
+SEC_PKCS7CopyContentInfo;
+SEC_PKCS7GetSignerCommonName;
+SEC_PKCS7GetSignerEmailAddress;
+SEC_PKCS7GetSigningTime;
+SEC_PKCS7SetContent;
+SEC_PKCS7VerifyDetachedSignature;
+SECMIME_DecryptionAllowed;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.4.1 { # NSS 3.4.1 release
+;+ global:
+NSS_CMSMessage_IsEncrypted;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.6 { # NSS 3.6 release
+;+ global:
+NSS_CMSSignerInfo_AddMSSMIMEEncKeyPrefs;
+NSS_CMSSignerInfo_CreateWithSubjKeyID;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.7 { # NSS 3.7 release
+;+ global:
+NSS_CMSRecipientInfo_CreateWithSubjKeyID;
+NSS_CMSRecipientInfo_CreateWithSubjKeyIDFromCert;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.7.2 { # NSS 3.7.2 release
+;+ global:
+NSS_CMSRecipientInfo_WrapBulkKey;
+NSS_CMSRecipientInfo_UnwrapBulkKey;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.8 { # NSS 3.8 release
+;+ global:
+NSS_CMSRecipientInfo_CreateNew;
+NSS_CMSRecipientInfo_CreateFromDER;
+NSS_CMSRecipientInfo_Encode;
+NSS_CMSRecipientInfo_GetCertAndKey;
+SEC_PKCS12DecoderSetTargetTokenCAs;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.9 { # NSS 3.9 release
+;+ global:
+SEC_PKCS7DecoderAbort;
+SEC_PKCS7EncoderAbort;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.9.3 { # NSS 3.9.3 release
+;+ global:
+CERT_ConvertAndDecodeCertificate;
+SEC_PKCS7EncodeItem;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.10 { # NSS 3.10 release
+;+ global:
+SEC_PKCS12DecoderIterateInit;
+SEC_PKCS12DecoderIterateNext;
+SEC_PKCS12DecryptionAllowed;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.12.2 { # NSS 3.12.2 release
+;+ global:
+SEC_PKCS12AddCertOrChainAndKey;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.12.10 { # NSS 3.12.10 release
+;+ global:
+NSS_CMSType_RegisterContentType;
+NSS_CMSContentInfo_SetDontStream;
+NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs;
+;+#
+;+# Data objects
+;+#
+;+# Don't export these DATA symbols on Windows because they don't work right.
+;+# Use the SEC_ASN1_GET / SEC_ASN1_SUB / SEC_ASN1_XTRN macros to access them.
+;+#
+;+# See nssutil for other examples.
+;+#
+;;NSSCMSGenericWrapperDataTemplate DATA ;
+;;NSS_PointerToCMSGenericWrapperDataTemplate DATA ;
+NSS_Get_NSSCMSGenericWrapperDataTemplate;
+NSS_Get_NSS_PointerToCMSGenericWrapperDataTemplate;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.13 { # NSS 3.13 release
+;+ global:
+NSSSMIME_GetVersion;
+;+ local:
+;+ *;
+;+};
+;+NSS_3.15 { # NSS 3.15 release
+;+ global:
+SEC_PKCS7VerifyDetachedSignatureAtTime;
+;+# Signed Receipt
+NSS_CMSSignerInfo_AddReceiptRequest;
+NSS_CMSSignerInfo_GetReceiptRequest;
+NSS_CMSSignerInfo_AddMsgSigDigest;
+NSS_CMSSignerInfo_GetMsgSigDigest;
+NSS_CMSSignerInfo_HasReceipt;
+NSS_SMIMEUtil_CreateReceipt;
+NSS_SMIMEUtil_GetReceipt;
+NSS_CMSSignerInfo_AddSecurityLabel;
+NSS_CMSSignerInfo_GetSecurityLabel;
+;+ local:
+;+ *;
+;+};
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+/*
+ * Header file for routines specific to S/MIME. Keep things that are pure
+ * pkcs7 out of here; this is for S/MIME policy, S/MIME interoperability, etc.
+ *
+ * $Id: smime.h,v 1.13 2012/09/21 21:58:44 wtc%google.com Exp $
+ */
+
+#ifndef _SECMIME_H_
+#define _SECMIME_H_ 1
+
+#include "cms.h"
+
+
+/************************************************************************/
+SEC_BEGIN_PROTOS
+
+/*
+ * Initialize the local recording of the user S/MIME cipher preferences.
+ * This function is called once for each cipher, the order being
+ * important (first call records greatest preference, and so on).
+ * When finished, it is called with a "which" of CIPHER_FAMILID_MASK.
+ * If the function is called again after that, it is assumed that
+ * the preferences are being reset, and the old preferences are
+ * discarded.
+ *
+ * XXX This is for a particular user, and right now the storage is
+ * XXX local, static. The preference should be stored elsewhere to allow
+ * XXX for multiple uses of one library? How does SSL handle this;
+ * XXX it has something similar?
+ *
+ * - The "which" values are defined in ciferfam.h (the SMIME_* values,
+ * for example SMIME_DES_CBC_56).
+ * - If "on" is non-zero then the named cipher is enabled, otherwise
+ * it is disabled. (It is not necessary to call the function for
+ * ciphers that are disabled, however, as that is the default.)
+ *
+ * If the cipher preference is successfully recorded, SECSuccess
+ * is returned. Otherwise SECFailure is returned. The only errors
+ * are due to failure allocating memory or bad parameters/calls:
+ * SEC_ERROR_XXX ("which" is not in the S/MIME cipher family)
+ * SEC_ERROR_XXX (function is being called more times than there
+ * are known/expected ciphers)
+ */
+extern SECStatus NSS_SMIMEUtil_EnableCipher(long which, int on);
+
+/*
+ * Initialize the local recording of the S/MIME policy.
+ * This function is called to allow/disallow a particular cipher.
+ *
+ * XXX This is for the current module, I think, so local, static storage
+ * XXX is okay. Is that correct, or could multiple uses of the same
+ * XXX library expect to operate under different policies?
+ *
+ * - The "which" values are defined in ciferfam.h (the SMIME_* values,
+ * for example SMIME_DES_CBC_56).
+ * - If "on" is non-zero then the named cipher is enabled, otherwise
+ * it is disabled.
+ */
+extern SECStatus NSS_SMIMEUtils_AllowCipher(long which, int on);
+
+/*
+ * Does the current policy allow S/MIME decryption of this particular
+ * algorithm and keysize?
+ */
+extern PRBool NSS_SMIMEUtil_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key);
+
+/*
+ * Does the current policy allow *any* S/MIME encryption (or decryption)?
+ *
+ * This tells whether or not *any* S/MIME encryption can be done,
+ * according to policy. Callers may use this to do nicer user interface
+ * (say, greying out a checkbox so a user does not even try to encrypt
+ * a message when they are not allowed to) or for any reason they want
+ * to check whether S/MIME encryption (or decryption, for that matter)
+ * may be done.
+ *
+ * It takes no arguments. The return value is a simple boolean:
+ * PR_TRUE means encryption (or decryption) is *possible*
+ * (but may still fail due to other reasons, like because we cannot
+ * find all the necessary certs, etc.; PR_TRUE is *not* a guarantee)
+ * PR_FALSE means encryption (or decryption) is not permitted
+ *
+ * There are no errors from this routine.
+ */
+extern PRBool NSS_SMIMEUtil_EncryptionPossible(void);
+
+/*
+ * NSS_SMIMEUtil_CreateSMIMECapabilities - get S/MIME capabilities attr value
+ *
+ * scans the list of allowed and enabled ciphers and construct a PKCS9-compliant
+ * S/MIME capabilities attribute value.
+ */
+extern SECStatus NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest);
+
+/*
+ * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value
+ */
+extern SECStatus NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert);
+
+/*
+ * NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value using MS oid
+ */
+extern SECStatus NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert);
+
+/*
+ * NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference - find cert marked by EncryptionKeyPreference
+ * attribute
+ */
+extern CERTCertificate *NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(CERTCertDBHandle *certdb, SECItem *DERekp);
+
+/*
+ * NSS_SMIMEUtil_FindBulkAlgForRecipients - find bulk algorithm suitable for all recipients
+ */
+extern SECStatus
+NSS_SMIMEUtil_FindBulkAlgForRecipients(CERTCertificate **rcerts, SECOidTag *bulkalgtag, int *keysize);
+
+/*
+ * Return a boolean that indicates whether the underlying library
+ * will perform as the caller expects.
+ *
+ * The only argument is a string, which should be the version
+ * identifier of the NSS library. That string will be compared
+ * against a string that represents the actual build version of
+ * the S/MIME library.
+ */
+extern PRBool NSSSMIME_VersionCheck(const char *importedVersion);
+
+/*
+ * Returns a const string of the S/MIME library version.
+ */
+extern const char *NSSSMIME_GetVersion(void);
+
+/*
+ * NSS_SMIMEUtil_CreateReceiptRequest - create a S/MIME receipt request attribute
+ */
+extern SECStatus
+NSS_SMIMEUtil_CreateReceiptRequest(PLArenaPool *aPoolp,
+ SECItem *aDest,
+ char *aSignedContentIdentifier,
+ char *aReceiptsTo);
+
+/*
+ * NSS_SMIMEUtil_GetReceiptRequest - decode S/MIME receipt request values
+ */
+extern SECStatus
+NSS_SMIMEUtil_GetReceiptRequest(NSSCMSSignerInfo *aSignerinfo,
+ PRBool *aHasReceiptRequest,
+ unsigned char **aSignedContentIdentifier,
+ unsigned int *aSignedContentIdentifierLen,
+ unsigned int *aReceiptsFrom,
+ char **aReceiptsTo,
+ unsigned char **aOriginatorSignatureValue,
+ unsigned int *aOriginatorSignatureValueLen,
+ unsigned char **aOriginatorContentType,
+ unsigned int *aOriginatorContentTypeLen,
+ unsigned char **aMsgSigDigest,
+ unsigned int *aMsgSigDigestLen);
+
+/*
+ * NSS_SMIMEUtil_CreateReceipt - create a S/MIME receipt
+ */
+extern SECStatus
+NSS_SMIMEUtil_CreateReceipt(PLArenaPool *aPoolp,
+ SECItem *aReceipt,
+ unsigned char **aReceiptDigest,
+ unsigned int *aReceiptDigestLen,
+ const unsigned char *aSignedContentIdentifier,
+ const unsigned int aSignedContentIdentifierLen,
+ const unsigned char *aOriginatorSignatureValue,
+ const unsigned int aOriginatorSignatureValueLen,
+ const unsigned char *aOriginatorContentType,
+ const unsigned int aOriginatorContentTypeLen);
+
+/*
+ * NSS_SMIMEUtil_GetReceipt - decode a S/MIME receipt
+ */
+extern SECStatus
+NSS_SMIMEUtil_GetReceipt(PLArenaPool *aPoolp,
+ SECItem *aEncodedReceipt,
+ const unsigned char **aSignedContentIdentifier,
+ unsigned int *aSignedContentIdentifierLen,
+ const unsigned char **aOriginatorSignatureValue,
+ unsigned int *aOriginatorSignatureValueLen,
+ const unsigned char **aOriginatorContentType,
+ unsigned int *aOriginatorContentTypeLen);
+
+/*
+ *
+ *
+ * NSS_SMIMEUtil_CreateSecureHeaders - create S/MIME Secure Headers attr value
+ *
+*/
+extern SECStatus
+NSS_SMIMEUtil_CreateSecureHeader(PLArenaPool *poolp, SECItem *dest, SecHeaderField * arrayHeaderField, const unsigned int nbHeaders, int canonAlgo);
+
+extern SECStatus
+NSS_SMIMEUtil_GetSecureHeader(NSSCMSSignerInfo *signerinfo, NSSCMSSecureHeader * secuHeaders);
+
+/*
+ * NSS_SMIMEUtil_CreateSecurityLabel - create S/MIME SecurityLabel attr value
+ */
+extern SECStatus NSS_SMIMEUtil_CreateSecurityLabel(PLArenaPool *aPoolp,
+ SECItem *aDest,
+ char *aSecurityPolicyIdentifier,
+ int aSecurityClassification,
+ char *aPrivacyMark,
+ char *aSecurityCategories);
+
+/*
+ * NSS_SMIMEUtil_GetSecurityLabel - get S/MIME SecurityLabel attr value
+ */
+extern SECStatus NSS_SMIMEUtil_GetSecurityLabel(NSSCMSSignerInfo *aSignerinfo,
+ PRBool *aHasSecurityLabel,
+ char **aSecurityPolicyIdentifier,
+ int *aSecurityClassification,
+ char **aPrivacyMark,
+ char **aSecurityCategories);
+
+/************************************************************************/
+SEC_END_PROTOS
+
+#endif /* _SECMIME_H_ */
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * ESS Signed Receipts/Security Labels: Raphael Fairise / BT Global Services / Etat francais - Ministere de la Defense
+ * ESS Security Labels: Eric Ballet Baz / BT Global Services / Etat francais - Ministere de la Defense
+ * Copyright (c) 2011 CASSIDIAN - All rights reserved
+ */
+
+/*
+ * Stuff specific to S/MIME policy and interoperability.
+ *
+ * $Id: smimeutil.c,v 1.25 2012/05/17 17:55:52 kaie%kuix.de Exp $
+ */
+
+#include "secmime.h"
+#include "secoid.h"
+#include "pk11func.h"
+#include "ciferfam.h" /* for CIPHER_FAMILY symbols */
+#include "secasn1.h"
+#include "secitem.h"
+#include "cert.h"
+#include "key.h"
+#include "secerr.h"
+#include "cms.h"
+#include "nss.h"
+#include "cmslocal.h"
+#include "sechash.h"
+#include "prprf.h"
+
+SEC_ASN1_MKSUB(CERT_IssuerAndSNTemplate)
+SEC_ASN1_MKSUB(SEC_OctetStringTemplate)
+SEC_ASN1_CHOOSER_DECLARE(CERT_IssuerAndSNTemplate)
+
+/* various integer's ASN.1 encoding */
+static unsigned char asn1_int40[] = { SEC_ASN1_INTEGER, 0x01, 0x28 };
+static unsigned char asn1_int64[] = { SEC_ASN1_INTEGER, 0x01, 0x40 };
+static unsigned char asn1_int128[] = { SEC_ASN1_INTEGER, 0x02, 0x00, 0x80 };
+
+/* RC2 algorithm parameters (used in smime_cipher_map) */
+static SECItem param_int40 = { siBuffer, asn1_int40, sizeof(asn1_int40) };
+static SECItem param_int64 = { siBuffer, asn1_int64, sizeof(asn1_int64) };
+static SECItem param_int128 = { siBuffer, asn1_int128, sizeof(asn1_int128) };
+
+/*
+ * XXX Would like the "parameters" field to be a SECItem *, but the
+ * encoder is having trouble with optional pointers to an ANY. Maybe
+ * once that is fixed, can change this back...
+ */
+typedef struct {
+ SECItem capabilityID;
+ SECItem parameters;
+ long cipher; /* optimization */
+} NSSSMIMECapability;
+
+static const SEC_ASN1Template NSSSMIMECapabilityTemplate[] = {
+ { SEC_ASN1_SEQUENCE,
+ 0, NULL, sizeof(NSSSMIMECapability) },
+ { SEC_ASN1_OBJECT_ID,
+ offsetof(NSSSMIMECapability,capabilityID), },
+ { SEC_ASN1_OPTIONAL | SEC_ASN1_ANY,
+ offsetof(NSSSMIMECapability,parameters), },
+ { 0, }
+};
+
+static const SEC_ASN1Template NSSSMIMECapabilitiesTemplate[] = {
+ { SEC_ASN1_SEQUENCE_OF, 0, NSSSMIMECapabilityTemplate }
+};
+
+/*
+ * NSSSMIMEEncryptionKeyPreference - if we find one of these, it needs to prompt us
+ * to store this and only this certificate permanently for the sender email address.
+ */
+typedef enum {
+ NSSSMIMEEncryptionKeyPref_IssuerSN,
+ NSSSMIMEEncryptionKeyPref_RKeyID,
+ NSSSMIMEEncryptionKeyPref_SubjectKeyID
+} NSSSMIMEEncryptionKeyPrefSelector;
+
+typedef struct {
+ NSSSMIMEEncryptionKeyPrefSelector selector;
+ union {
+ CERTIssuerAndSN *issuerAndSN;
+ NSSCMSRecipientKeyIdentifier *recipientKeyID;
+ SECItem *subjectKeyID;
+ } id;
+} NSSSMIMEEncryptionKeyPreference;
+
+extern const SEC_ASN1Template NSSCMSRecipientKeyIdentifierTemplate[];
+
+static const SEC_ASN1Template smime_encryptionkeypref_template[] = {
+ { SEC_ASN1_CHOICE,
+ offsetof(NSSSMIMEEncryptionKeyPreference,selector), NULL,
+ sizeof(NSSSMIMEEncryptionKeyPreference) },
+ { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 0
+ | SEC_ASN1_CONSTRUCTED,
+ offsetof(NSSSMIMEEncryptionKeyPreference,id.issuerAndSN),
+ SEC_ASN1_SUB(CERT_IssuerAndSNTemplate),
+ NSSSMIMEEncryptionKeyPref_IssuerSN },
+ { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | 1
+ | SEC_ASN1_CONSTRUCTED,
+ offsetof(NSSSMIMEEncryptionKeyPreference,id.recipientKeyID),
+ NSSCMSRecipientKeyIdentifierTemplate,
+ NSSSMIMEEncryptionKeyPref_RKeyID },
+ { SEC_ASN1_POINTER | SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_XTRN | 2
+ | SEC_ASN1_CONSTRUCTED,
+ offsetof(NSSSMIMEEncryptionKeyPreference,id.subjectKeyID),
+ SEC_ASN1_SUB(SEC_OctetStringTemplate),
+ NSSSMIMEEncryptionKeyPref_SubjectKeyID },
+ { 0, }
+};
+
+/*
+ *
+ * XIMF HEADERS SIGNED : ASN.1 BER
+ *
+ */
+
+static const SEC_ASN1Template NSSCMSHeaderFieldElementTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSCMSSecHeaderFieldElement) },
+ { SEC_ASN1_IA5_STRING, offsetof(NSSCMSSecHeaderFieldElement, HeaderFieldName)},
+ { SEC_ASN1_IA5_STRING, offsetof(NSSCMSSecHeaderFieldElement, HeaderFieldValue)},
+ { SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL, offsetof(NSSCMSSecHeaderFieldElement, HeaderFieldStatus)}, /* OPTIONAL, default=-1 */
+ /*{ SEC_ASN1_INTEGER | SEC_ASN1_OPTIONAL | 1, offsetof(NSSCMSSecHeaderFieldElement, HeaderFieldEncrypted)},*/ /* OPTIONAL, default=-1 */
+ { 0 }
+};
+
+static const SEC_ASN1Template NSSCMSSecureHeaderElementTemplate[] = {
+ { SEC_ASN1_CHOICE, offsetof(NSSCMSSecureHeaderElement, selector), NULL, sizeof(NSSCMSSecureHeaderElement) },
+ { SEC_ASN1_ENUMERATED, offsetof(NSSCMSSecureHeaderElement,id.canonAlgorithm),NULL,NSSCMSSecureHeaderElement_canonAlgorithm},
+ { SEC_ASN1_SET_OF, offsetof(NSSCMSSecureHeaderElement,id.secHeaderFields), NSSCMSHeaderFieldElementTemplate, NSSCMSSecureHeaderElement_secHeaderField},
+ { 0 }
+};
+
+static const SEC_ASN1Template NSSCMSSecureHeaderTemplate[] = {
+ { SEC_ASN1_SET_OF, 0, NSSCMSSecureHeaderElementTemplate},
+};
+
+
+/* ESS Signed Receipt Request */
+static const SEC_ASN1Template NSSCMSReceiptRequestReceiptsFromTemplate[] = {
+ { SEC_ASN1_INTEGER, 0, NULL },
+};
+
+const SEC_ASN1Template NSSCMSReceiptRequestGeneralNameTemplate[] = {
+ { SEC_ASN1_ANY | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) }
+};
+
+static const SEC_ASN1Template NSSCMSReceiptRequestGeneralNamesTemplate[] = {
+ { SEC_ASN1_SEQUENCE_OF, 0, NSSCMSReceiptRequestGeneralNameTemplate },
+};
+
+static const SEC_ASN1Template NSSCMSReceiptRequestTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSCMSReceiptRequest) },
+ { SEC_ASN1_OCTET_STRING, offsetof(NSSCMSReceiptRequest, signedContentIdentifier) },
+ { SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(NSSCMSReceiptRequest, receiptsFrom), NSSCMSReceiptRequestReceiptsFromTemplate },
+ { SEC_ASN1_SEQUENCE_OF, offsetof(NSSCMSReceiptRequest, receiptsTo), NSSCMSReceiptRequestGeneralNamesTemplate },
+ { 0 }
+};
+
+/* ESS Signed Receipt */
+static const SEC_ASN1Template NSSCMSReceiptTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSCMSReceipt) },
+ { SEC_ASN1_INTEGER, offsetof(NSSCMSReceipt, version) },
+ { SEC_ASN1_OBJECT_ID, offsetof(NSSCMSReceipt, contentType) },
+ { SEC_ASN1_OCTET_STRING, offsetof(NSSCMSReceipt, signedContentIdentifier) },
+ { SEC_ASN1_OCTET_STRING, offsetof(NSSCMSReceipt, originatorSignatureValue) },
+ { 0 }
+};
+
+/*
+ * ESS Security Label
+ *
+ * Implemented as a SET OF CHOICE because SET decoding is not implemented in NSS
+ */
+static const SEC_ASN1Template securityCategoryIdentifierTemplate[] = {
+ { SEC_ASN1_OBJECT_ID, 0, NULL },
+};
+
+static const SEC_ASN1Template securityCategoryValueTemplate[] = {
+ { SEC_ASN1_ANY, 0, NULL },
+};
+
+static const SEC_ASN1Template securityCategoryValueUTF8Template[] = {
+ { SEC_ASN1_UTF8_STRING | SEC_ASN1_MAY_STREAM, 0, NULL, sizeof(SECItem) },
+};
+
+static const SEC_ASN1Template securityCategoryValueIntegerTemplate[] = {
+ { SEC_ASN1_INTEGER, 0, NULL, sizeof(SECItem) },
+};
+
+static const SEC_ASN1Template NSSCMSSecurityLabelSecurityCategoryTemplate[] = {
+ { SEC_ASN1_SEQUENCE, 0, NULL, sizeof(NSSCMSSecurityLabelSecurityCategory) },
+ { SEC_ASN1_CONTEXT_SPECIFIC | 0, offsetof(NSSCMSSecurityLabelSecurityCategory, securityCategoryIdentifier), securityCategoryIdentifierTemplate },
+ { SEC_ASN1_CONTEXT_SPECIFIC | SEC_ASN1_EXPLICIT | SEC_ASN1_CONSTRUCTED | 1, offsetof(NSSCMSSecurityLabelSecurityCategory, securityCategoryValue), securityCategoryValueTemplate },
+ { 0 }
+};
+
+static const SEC_ASN1Template NSSCMSSecurityLabelElementTemplate[] = {
+ { SEC_ASN1_CHOICE, offsetof(NSSCMSSecurityLabelElement, selector), NULL, sizeof(NSSCMSSecurityLabelElement) },
+ { SEC_ASN1_OBJECT_ID, offsetof(NSSCMSSecurityLabelElement, id.securityPolicyIdentifier), NULL, NSSCMSSecurityLabelElement_securityPolicyIdentifier },
+ { SEC_ASN1_INTEGER, offsetof(NSSCMSSecurityLabelElement, id.securityClassification), NULL, NSSCMSSecurityLabelElement_securityClassification },
+ { SEC_ASN1_PRINTABLE_STRING, offsetof(NSSCMSSecurityLabelElement, id.privacyMarkPrintableString), NULL, NSSCMSSecurityLabelElement_privacyMarkPrintableString },
+ { SEC_ASN1_UTF8_STRING, offsetof(NSSCMSSecurityLabelElement, id.privacyMarkUTF8), NULL, NSSCMSSecurityLabelElement_privacyMarkUTF8 },
+ { SEC_ASN1_SET_OF, offsetof(NSSCMSSecurityLabelElement, id.securityCategories), NSSCMSSecurityLabelSecurityCategoryTemplate, NSSCMSSecurityLabelElement_securityCategories },
+ { 0 }
+};
+
+static const SEC_ASN1Template NSSCMSSecurityLabelTemplate[] = {
+ { SEC_ASN1_SET_OF, 0, NSSCMSSecurityLabelElementTemplate },
+};
+
+/* smime_cipher_map - map of SMIME symmetric "ciphers" to algtag & parameters */
+typedef struct {
+ unsigned long cipher;
+ SECOidTag algtag;
+ SECItem *parms;
+ PRBool enabled; /* in the user's preferences */
+ PRBool allowed; /* per export policy */
+} smime_cipher_map_entry;
+
+/* global: list of supported SMIME symmetric ciphers, ordered roughly by increasing strength */
+static smime_cipher_map_entry smime_cipher_map[] = {
+/* cipher algtag parms enabled allowed */
+/* ---------------------------------------------------------------------------------- */
+ { SMIME_RC2_CBC_40, SEC_OID_RC2_CBC, ¶m_int40, PR_TRUE, PR_TRUE },
+ { SMIME_DES_CBC_56, SEC_OID_DES_CBC, NULL, PR_TRUE, PR_TRUE },
+ { SMIME_RC2_CBC_64, SEC_OID_RC2_CBC, ¶m_int64, PR_TRUE, PR_TRUE },
+ { SMIME_RC2_CBC_128, SEC_OID_RC2_CBC, ¶m_int128, PR_TRUE, PR_TRUE },
+ { SMIME_DES_EDE3_168, SEC_OID_DES_EDE3_CBC, NULL, PR_TRUE, PR_TRUE },
+ { SMIME_AES_CBC_128, SEC_OID_AES_128_CBC, NULL, PR_TRUE, PR_TRUE },
+ { SMIME_AES_CBC_256, SEC_OID_AES_256_CBC, NULL, PR_TRUE, PR_TRUE }
+};
+static const int smime_cipher_map_count = sizeof(smime_cipher_map) / sizeof(smime_cipher_map_entry);
+
+/*
+ * smime_mapi_by_cipher - find index into smime_cipher_map by cipher
+ */
+static int
+smime_mapi_by_cipher(unsigned long cipher)
+{
+ int i;
+
+ for (i = 0; i < smime_cipher_map_count; i++) {
+ if (smime_cipher_map[i].cipher == cipher)
+ return i; /* bingo */
+ }
+ return -1; /* should not happen if we're consistent, right? */
+}
+
+/*
+ * NSS_SMIME_EnableCipher - this function locally records the user's preference
+ */
+SECStatus
+NSS_SMIMEUtil_EnableCipher(unsigned long which, PRBool on)
+{
+ unsigned long mask;
+ int mapi;
+
+ mask = which & CIPHER_FAMILYID_MASK;
+
+ PORT_Assert (mask == CIPHER_FAMILYID_SMIME);
+ if (mask != CIPHER_FAMILYID_SMIME)
+ /* XXX set an error! */
+ return SECFailure;
+
+ mapi = smime_mapi_by_cipher(which);
+ if (mapi < 0)
+ /* XXX set an error */
+ return SECFailure;
+
+ /* do we try to turn on a forbidden cipher? */
+ if (!smime_cipher_map[mapi].allowed && on) {
+ PORT_SetError (SEC_ERROR_BAD_EXPORT_ALGORITHM);
+ return SECFailure;
+ }
+
+ if (smime_cipher_map[mapi].enabled != on)
+ smime_cipher_map[mapi].enabled = on;
+
+ return SECSuccess;
+}
+
+
+/*
+ * this function locally records the export policy
+ */
+SECStatus
+NSS_SMIMEUtil_AllowCipher(unsigned long which, PRBool on)
+{
+ unsigned long mask;
+ int mapi;
+
+ mask = which & CIPHER_FAMILYID_MASK;
+
+ PORT_Assert (mask == CIPHER_FAMILYID_SMIME);
+ if (mask != CIPHER_FAMILYID_SMIME)
+ /* XXX set an error! */
+ return SECFailure;
+
+ mapi = smime_mapi_by_cipher(which);
+ if (mapi < 0)
+ /* XXX set an error */
+ return SECFailure;
+
+ if (smime_cipher_map[mapi].allowed != on)
+ smime_cipher_map[mapi].allowed = on;
+
+ return SECSuccess;
+}
+
+/*
+ * Based on the given algorithm (including its parameters, in some cases!)
+ * and the given key (may or may not be inspected, depending on the
+ * algorithm), find the appropriate policy algorithm specification
+ * and return it. If no match can be made, -1 is returned.
+ */
+static SECStatus
+nss_smime_get_cipher_for_alg_and_key(SECAlgorithmID *algid, PK11SymKey *key, unsigned long *cipher)
+{
+ SECOidTag algtag;
+ unsigned int keylen_bits;
+ unsigned long c;
+
+ algtag = SECOID_GetAlgorithmTag(algid);
+ switch (algtag) {
+ case SEC_OID_RC2_CBC:
+ keylen_bits = PK11_GetKeyStrength(key, algid);
+ switch (keylen_bits) {
+ case 40:
+ c = SMIME_RC2_CBC_40;
+ break;
+ case 64:
+ c = SMIME_RC2_CBC_64;
+ break;
+ case 128:
+ c = SMIME_RC2_CBC_128;
+ break;
+ default:
+ return SECFailure;
+ }
+ break;
+ case SEC_OID_DES_CBC:
+ c = SMIME_DES_CBC_56;
+ break;
+ case SEC_OID_DES_EDE3_CBC:
+ c = SMIME_DES_EDE3_168;
+ break;
+ case SEC_OID_AES_128_CBC:
+ c = SMIME_AES_CBC_128;
+ break;
+ case SEC_OID_AES_256_CBC:
+ c = SMIME_AES_CBC_256;
+ break;
+ default:
+ PORT_SetError(SEC_ERROR_INVALID_ALGORITHM);
+ return SECFailure;
+ }
+ *cipher = c;
+ return SECSuccess;
+}
+
+static PRBool
+nss_smime_cipher_allowed(unsigned long which)
+{
+ int mapi;
+
+ mapi = smime_mapi_by_cipher(which);
+ if (mapi < 0)
+ return PR_FALSE;
+ return smime_cipher_map[mapi].allowed;
+}
+
+PRBool
+NSS_SMIMEUtil_DecryptionAllowed(SECAlgorithmID *algid, PK11SymKey *key)
+{
+ unsigned long which;
+
+ if (nss_smime_get_cipher_for_alg_and_key(algid, key, &which) != SECSuccess)
+ return PR_FALSE;
+
+ return nss_smime_cipher_allowed(which);
+}
+
+
+/*
+ * NSS_SMIME_EncryptionPossible - check if any encryption is allowed
+ *
+ * This tells whether or not *any* S/MIME encryption can be done,
+ * according to policy. Callers may use this to do nicer user interface
+ * (say, greying out a checkbox so a user does not even try to encrypt
+ * a message when they are not allowed to) or for any reason they want
+ * to check whether S/MIME encryption (or decryption, for that matter)
+ * may be done.
+ *
+ * It takes no arguments. The return value is a simple boolean:
+ * PR_TRUE means encryption (or decryption) is *possible*
+ * (but may still fail due to other reasons, like because we cannot
+ * find all the necessary certs, etc.; PR_TRUE is *not* a guarantee)
+ * PR_FALSE means encryption (or decryption) is not permitted
+ *
+ * There are no errors from this routine.
+ */
+PRBool
+NSS_SMIMEUtil_EncryptionPossible(void)
+{
+ int i;
+
+ for (i = 0; i < smime_cipher_map_count; i++) {
+ if (smime_cipher_map[i].allowed)
+ return PR_TRUE;
+ }
+ return PR_FALSE;
+}
+
+
+static int
+nss_SMIME_FindCipherForSMIMECap(NSSSMIMECapability *cap)
+{
+ int i;
+ SECOidTag capIDTag;
+
+ /* we need the OIDTag here */
+ capIDTag = SECOID_FindOIDTag(&(cap->capabilityID));
+
+ /* go over all the SMIME ciphers we know and see if we find a match */
+ for (i = 0; i < smime_cipher_map_count; i++) {
+ if (smime_cipher_map[i].algtag != capIDTag)
+ continue;
+ /*
+ * XXX If SECITEM_CompareItem allowed NULLs as arguments (comparing
+ * 2 NULLs as equal and NULL and non-NULL as not equal), we could
+ * use that here instead of all of the following comparison code.
+ */
+ if (!smime_cipher_map[i].parms) {
+ if (!cap->parameters.data || !cap->parameters.len)
+ break; /* both empty: bingo */
+ if (cap->parameters.len == 2 &&
+ cap->parameters.data[0] == SEC_ASN1_NULL &&
+ cap->parameters.data[1] == 0)
+ break; /* DER NULL == NULL, bingo */
+ } else if (cap->parameters.data != NULL &&
+ cap->parameters.len == smime_cipher_map[i].parms->len &&
+ PORT_Memcmp (cap->parameters.data, smime_cipher_map[i].parms->data,
+ cap->parameters.len) == 0)
+ {
+ break; /* both not empty, same length & equal content: bingo */
+ }
+ }
+
+ if (i == smime_cipher_map_count)
+ return 0; /* no match found */
+ return smime_cipher_map[i].cipher; /* match found, point to cipher */
+}
+
+/*
+ * smime_choose_cipher - choose a cipher that works for all the recipients
+ *
+ * "scert" - sender's certificate
+ * "rcerts" - recipient's certificates
+ */
+static long
+smime_choose_cipher(CERTCertificate *scert, CERTCertificate **rcerts)
+{
+ PLArenaPool *poolp;
+ long cipher;
+ long chosen_cipher;
+ int *cipher_abilities;
+ int *cipher_votes;
+ int weak_mapi;
+ int strong_mapi;
+ int aes128_mapi;
+ int aes256_mapi;
+ int rcount, mapi, max, i;
+
+ chosen_cipher = SMIME_RC2_CBC_40; /* the default, LCD */
+ weak_mapi = smime_mapi_by_cipher(chosen_cipher);
+ aes128_mapi = smime_mapi_by_cipher(SMIME_AES_CBC_128);
+ aes256_mapi = smime_mapi_by_cipher(SMIME_AES_CBC_256);
+
+ poolp = PORT_NewArena (1024); /* XXX what is right value? */
+ if (poolp == NULL)
+ goto done;
+
+ cipher_abilities = (int *)PORT_ArenaZAlloc(poolp, smime_cipher_map_count * sizeof(int));
+ cipher_votes = (int *)PORT_ArenaZAlloc(poolp, smime_cipher_map_count * sizeof(int));
+ if (cipher_votes == NULL || cipher_abilities == NULL)
+ goto done;
+
+ /* Make triple-DES the strong cipher. */
+ strong_mapi = smime_mapi_by_cipher (SMIME_DES_EDE3_168);
+
+ /* walk all the recipient's certs */
+ for (rcount = 0; rcerts[rcount] != NULL; rcount++) {
+ SECItem *profile;
+ NSSSMIMECapability **caps;
+ int pref;
+
+ /* the first cipher that matches in the user's SMIME profile gets
+ * "smime_cipher_map_count" votes; the next one gets "smime_cipher_map_count" - 1
+ * and so on. If every cipher matches, the last one gets 1 (one) vote */
+ pref = smime_cipher_map_count;
+
+ /* find recipient's SMIME profile */
+ profile = CERT_FindSMimeProfile(rcerts[rcount]);
+
+ if (profile != NULL && profile->data != NULL && profile->len > 0) {
+ /* we have a profile (still DER-encoded) */
+ caps = NULL;
+ /* decode it */
+ if (SEC_QuickDERDecodeItem(poolp, &caps,
+ NSSSMIMECapabilitiesTemplate, profile) == SECSuccess &&
+ caps != NULL)
+ {
+ /* walk the SMIME capabilities for this recipient */
+ for (i = 0; caps[i] != NULL; i++) {
+ cipher = nss_SMIME_FindCipherForSMIMECap(caps[i]);
+ mapi = smime_mapi_by_cipher(cipher);
+ if (mapi >= 0) {
+ /* found the cipher */
+ cipher_abilities[mapi]++;
+ cipher_votes[mapi] += pref;
+ --pref;
+ }
+ }
+ }
+ } else {
+ /* no profile found - so we can only assume that the user can do
+ * the mandatory algorithms which are RC2-40 (weak crypto) and
+ * 3DES (strong crypto), unless the user has an elliptic curve
+ * key. For elliptic curve keys, RFC 5753 mandates support
+ * for AES 128 CBC. */
+ SECKEYPublicKey *key;
+ unsigned int pklen_bits;
+ KeyType key_type;
+
+ /*
+ * if recipient's public key length is > 512, vote for a strong cipher
+ * please not that the side effect of this is that if only one recipient
+ * has an export-level public key, the strong cipher is disabled.
+ *
+ * XXX This is probably only good for RSA keys. What I would
+ * really like is a function to just say; Is the public key in
+ * this cert an export-length key? Then I would not have to
+ * know things like the value 512, or the kind of key, or what
+ * a subjectPublicKeyInfo is, etc.
+ */
+ key = CERT_ExtractPublicKey(rcerts[rcount]);
+ pklen_bits = 0;
+ if (key != NULL) {
+ pklen_bits = SECKEY_PublicKeyStrengthInBits (key);
+ key_type = SECKEY_GetPublicKeyType(key);
+ SECKEY_DestroyPublicKey (key);
+ }
+
+ if (key_type == ecKey) {
+ /* While RFC 5753 mandates support for AES-128 CBC, should use
+ * AES 256 if user's key provides more than 128 bits of
+ * security strength so that symmetric key is not weak link. */
+
+ /* RC2-40 is not compatible with elliptic curve keys. */
+ chosen_cipher = SMIME_DES_EDE3_168;
+ if (pklen_bits > 256) {
+ cipher_abilities[aes256_mapi]++;
+ cipher_votes[aes256_mapi] += pref;
+ pref--;
+ }
+ cipher_abilities[aes128_mapi]++;
+ cipher_votes[aes128_mapi] += pref;
+ pref--;
+ cipher_abilities[strong_mapi]++;
+ cipher_votes[strong_mapi] += pref;
+ pref--;
+ } else {
+ if (pklen_bits > 512) {
+ /* cast votes for the strong algorithm */
+ cipher_abilities[strong_mapi]++;
+ cipher_votes[strong_mapi] += pref;
+ pref--;
+ }
+
+ /* always cast (possibly less) votes for the weak algorithm */
+ cipher_abilities[weak_mapi]++;
+ cipher_votes[weak_mapi] += pref;
+ }
+ }
+ if (profile != NULL)
+ SECITEM_FreeItem(profile, PR_TRUE);
+ }
+
+ /* find cipher that is agreeable by all recipients and that has the most votes */
+ max = 0;
+ for (mapi = 0; mapi < smime_cipher_map_count; mapi++) {
+ /* if not all of the recipients can do this, forget it */
+ if (cipher_abilities[mapi] != rcount)
+ continue;
+ /* if cipher is not enabled or not allowed by policy, forget it */
+ if (!smime_cipher_map[mapi].enabled || !smime_cipher_map[mapi].allowed)
+ continue;
+ /* now see if this one has more votes than the last best one */
+ if (cipher_votes[mapi] >= max) {
+ /* if equal number of votes, prefer the ones further down in the list */
+ /* with the expectation that these are higher rated ciphers */
+ chosen_cipher = smime_cipher_map[mapi].cipher;
+ max = cipher_votes[mapi];
+ }
+ }
+ /* if no common cipher was found, chosen_cipher stays at the default */
+
+done:
+ if (poolp != NULL)
+ PORT_FreeArena (poolp, PR_FALSE);
+
+ return chosen_cipher;
+}
+
+/*
+ * XXX This is a hack for now to satisfy our current interface.
+ * Eventually, with more parameters needing to be specified, just
+ * looking up the keysize is not going to be sufficient.
+ */
+static int
+smime_keysize_by_cipher (unsigned long which)
+{
+ int keysize;
+
+ switch (which) {
+ case SMIME_RC2_CBC_40:
+ keysize = 40;
+ break;
+ case SMIME_RC2_CBC_64:
+ keysize = 64;
+ break;
+ case SMIME_RC2_CBC_128:
+ case SMIME_AES_CBC_128:
+ keysize = 128;
+ break;
+ case SMIME_AES_CBC_256:
+ keysize = 256;
+ break;
+ case SMIME_DES_CBC_56:
+ case SMIME_DES_EDE3_168:
+ /*
+ * These are special; since the key size is fixed, we actually
+ * want to *avoid* specifying a key size.
+ */
+ keysize = 0;
+ break;
+ default:
+ keysize = -1;
+ break;
+ }
+
+ return keysize;
+}
+
+/*
+ * NSS_SMIMEUtil_FindBulkAlgForRecipients - find bulk algorithm suitable for all recipients
+ *
+ * it would be great for UI purposes if there would be a way to find out which recipients
+ * prevented a strong cipher from being used...
+ */
+SECStatus
+NSS_SMIMEUtil_FindBulkAlgForRecipients(CERTCertificate **rcerts, SECOidTag *bulkalgtag, int *keysize)
+{
+ unsigned long cipher;
+ int mapi;
+
+ cipher = smime_choose_cipher(NULL, rcerts);
+ mapi = smime_mapi_by_cipher(cipher);
+
+ *bulkalgtag = smime_cipher_map[mapi].algtag;
+ *keysize = smime_keysize_by_cipher(smime_cipher_map[mapi].cipher);
+
+ return SECSuccess;
+}
+
+/*
+ * NSS_SMIMEUtil_CreateSMIMECapabilities - get S/MIME capabilities for this instance of NSS
+ *
+ * scans the list of allowed and enabled ciphers and construct a PKCS9-compliant
+ * S/MIME capabilities attribute value.
+ *
+ * XXX Please note that, in contradiction to RFC2633 2.5.2, the capabilities only include
+ * symmetric ciphers, NO signature algorithms or key encipherment algorithms.
+ *
+ * "poolp" - arena pool to create the S/MIME capabilities data on
+ * "dest" - SECItem to put the data in
+ */
+SECStatus
+NSS_SMIMEUtil_CreateSMIMECapabilities(PLArenaPool *poolp, SECItem *dest)
+{
+ NSSSMIMECapability *cap;
+ NSSSMIMECapability **smime_capabilities;
+ smime_cipher_map_entry *map;
+ SECOidData *oiddata;
+ SECItem *dummy;
+ int i, capIndex;
+
+ /* if we have an old NSSSMIMECapability array, we'll reuse it (has the right size) */
+ /* smime_cipher_map_count + 1 is an upper bound - we might end up with less */
+ smime_capabilities = (NSSSMIMECapability **)PORT_ZAlloc((smime_cipher_map_count + 1)
+ * sizeof(NSSSMIMECapability *));
+ if (smime_capabilities == NULL)
+ return SECFailure;
+
+ capIndex = 0;
+
+ /* Add all the symmetric ciphers
+ * We walk the cipher list backwards, as it is ordered by increasing strength,
+ * we prefer the stronger cipher over a weaker one, and we have to list the
+ * preferred algorithm first */
+ for (i = smime_cipher_map_count - 1; i >= 0; i--) {
+ /* Find the corresponding entry in the cipher map. */
+ map = &(smime_cipher_map[i]);
+ if (!map->enabled)
+ continue;
+
+ /* get next SMIME capability */
+ cap = (NSSSMIMECapability *)PORT_ZAlloc(sizeof(NSSSMIMECapability));
+ if (cap == NULL)
+ break;
+ smime_capabilities[capIndex++] = cap;
+
+ oiddata = SECOID_FindOIDByTag(map->algtag);
+ if (oiddata == NULL)
+ break;
+
+ cap->capabilityID.data = oiddata->oid.data;
+ cap->capabilityID.len = oiddata->oid.len;
+ cap->parameters.data = map->parms ? map->parms->data : NULL;
+ cap->parameters.len = map->parms ? map->parms->len : 0;
+ cap->cipher = smime_cipher_map[i].cipher;
+ }
+
+ /* XXX add signature algorithms */
+ /* XXX add key encipherment algorithms */
+
+ smime_capabilities[capIndex] = NULL; /* last one - now encode */
+ dummy = SEC_ASN1EncodeItem(poolp, dest, &smime_capabilities, NSSSMIMECapabilitiesTemplate);
+
+ /* now that we have the proper encoded SMIMECapabilities (or not),
+ * free the work data */
+ for (i = 0; smime_capabilities[i] != NULL; i++)
+ PORT_Free(smime_capabilities[i]);
+ PORT_Free(smime_capabilities);
+
+ return (dummy == NULL) ? SECFailure : SECSuccess;
+}
+
+/*
+ * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value
+ *
+ * "poolp" - arena pool to create the attr value on
+ * "dest" - SECItem to put the data in
+ * "cert" - certificate that should be marked as preferred encryption key
+ * cert is expected to have been verified for EmailRecipient usage.
+ */
+SECStatus
+NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert)
+{
+ NSSSMIMEEncryptionKeyPreference ekp;
+ SECItem *dummy = NULL;
+ PLArenaPool *tmppoolp = NULL;
+
+ if (cert == NULL)
+ goto loser;
+
+ tmppoolp = PORT_NewArena(1024);
+ if (tmppoolp == NULL)
+ goto loser;
+
+ /* XXX hardcoded IssuerSN choice for now */
+ ekp.selector = NSSSMIMEEncryptionKeyPref_IssuerSN;
+ ekp.id.issuerAndSN = CERT_GetCertIssuerAndSN(tmppoolp, cert);
+ if (ekp.id.issuerAndSN == NULL)
+ goto loser;
+
+ dummy = SEC_ASN1EncodeItem(poolp, dest, &ekp, smime_encryptionkeypref_template);
+
+loser:
+ if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE);
+
+ return (dummy == NULL) ? SECFailure : SECSuccess;
+}
+
+/*
+ * NSS_SMIMEUtil_CreateSMIMEEncKeyPrefs - create S/MIME encryption key preferences attr value using MS oid
+ *
+ * "poolp" - arena pool to create the attr value on
+ * "dest" - SECItem to put the data in
+ * "cert" - certificate that should be marked as preferred encryption key
+ * cert is expected to have been verified for EmailRecipient usage.
+ */
+SECStatus
+NSS_SMIMEUtil_CreateMSSMIMEEncKeyPrefs(PLArenaPool *poolp, SECItem *dest, CERTCertificate *cert)
+{
+ SECItem *dummy = NULL;
+ PLArenaPool *tmppoolp = NULL;
+ CERTIssuerAndSN *isn;
+
+ if (cert == NULL)
+ goto loser;
+
+ tmppoolp = PORT_NewArena(1024);
+ if (tmppoolp == NULL)
+ goto loser;
+
+ isn = CERT_GetCertIssuerAndSN(tmppoolp, cert);
+ if (isn == NULL)
+ goto loser;
+
+ dummy = SEC_ASN1EncodeItem(poolp, dest, isn, SEC_ASN1_GET(CERT_IssuerAndSNTemplate));
+
+loser:
+ if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE);
+
+ return (dummy == NULL) ? SECFailure : SECSuccess;
+}
+
+/*
+ * NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference -
+ * find cert marked by EncryptionKeyPreference attribute
+ *
+ * "certdb" - handle for the cert database to look in
+ * "DERekp" - DER-encoded value of S/MIME Encryption Key Preference attribute
+ *
+ * if certificate is supposed to be found among the message's included certificates,
+ * they are assumed to have been imported already.
+ */
+CERTCertificate *
+NSS_SMIMEUtil_GetCertFromEncryptionKeyPreference(CERTCertDBHandle *certdb, SECItem *DERekp)
+{
+ PLArenaPool *tmppoolp = NULL;
+ CERTCertificate *cert = NULL;
+ NSSSMIMEEncryptionKeyPreference ekp;
+
+ tmppoolp = PORT_NewArena(1024);
+ if (tmppoolp == NULL)
+ return NULL;
+
+ /* decode DERekp */
+ if (SEC_QuickDERDecodeItem(tmppoolp, &ekp, smime_encryptionkeypref_template,
+ DERekp) != SECSuccess)
+ goto loser;
+
+ /* find cert */
+ switch (ekp.selector) {
+ case NSSSMIMEEncryptionKeyPref_IssuerSN:
+ cert = CERT_FindCertByIssuerAndSN(certdb, ekp.id.issuerAndSN);
+ break;
+ case NSSSMIMEEncryptionKeyPref_RKeyID:
+ case NSSSMIMEEncryptionKeyPref_SubjectKeyID:
+ /* XXX not supported yet - we need to be able to look up certs by SubjectKeyID */
+ break;
+ default:
+ PORT_Assert(0);
+ }
+loser:
+ if (tmppoolp) PORT_FreeArena(tmppoolp, PR_FALSE);
+
+ return cert;
+}
+
+extern const char __nss_smime_rcsid[];
+extern const char __nss_smime_sccsid[];
+
+PRBool
+NSSSMIME_VersionCheck(const char *importedVersion)
+{
+ /*
+ * This is the secret handshake algorithm.
+ *
+ * This release has a simple version compatibility
+ * check algorithm. This release is not backward
+ * compatible with previous major releases. It is
+ * not compatible with future major, minor, or
+ * patch releases.
+ */
+ volatile char c; /* force a reference that won't get optimized away */
+
+ c = __nss_smime_rcsid[0] + __nss_smime_sccsid[0];
+
+ return NSS_VersionCheck(importedVersion);
+}
+
+const char *
+NSSSMIME_GetVersion(void)
+{
+ return NSS_VERSION;
+}
+
+/*
+ *
+ *
+ * NSS_SMIMEUtil_CreateSecureHeaders - create S/MIME Secure Headers attr value
+ *
+*/
+SECStatus
+NSS_SMIMEUtil_CreateSecureHeader(PLArenaPool *poolp, SECItem *dest, SecHeaderField * arrayHeaderField, const unsigned int nbHeaders, PRInt32 canonAlgo)
+{
+ NSSCMSSecureHeaderElement** secureHeader = NULL;
+ SECItem * dummy = NULL;
+ int secureHeaderItem = 0;
+ int i=0;
+ int len=0;
+
+
+ /* Alloc 2 elements max + 1 NULL at the end = 3 elements */
+ secureHeader = (NSSCMSSecureHeaderElement**) PORT_Alloc(3 * sizeof(NSSCMSSecureHeaderElement*));
+ for (i = 0; i < 3; ++i) secureHeader[i] = NULL;
+
+ secureHeaderItem = 0;
+
+ /* CanonAlgorithm */
+ secureHeader[secureHeaderItem] = (NSSCMSSecureHeaderElement *) PORT_Alloc(sizeof(NSSCMSSecureHeaderElement));
+ secureHeader[secureHeaderItem]->selector=NSSCMSSecureHeaderElement_canonAlgorithm;
+
+
+ secureHeader[secureHeaderItem]->id.canonAlgorithm.data = (unsigned char*) PORT_Alloc(4 * sizeof(unsigned char));
+ if (secureHeader[secureHeaderItem]->id.canonAlgorithm.data == NULL) goto loser;
+ secureHeader[secureHeaderItem]->id.canonAlgorithm.data[0] = 0;
+ secureHeader[secureHeaderItem]->id.canonAlgorithm.data[1] = 0;
+ secureHeader[secureHeaderItem]->id.canonAlgorithm.data[2] = 0; /* (unsigned char) (canonAlgo>>8 & 0xFF); */
+ secureHeader[secureHeaderItem]->id.canonAlgorithm.data[3] = (unsigned char) (canonAlgo & 0xFF);
+ secureHeader[secureHeaderItem]->id.canonAlgorithm.len = 4;
+
+
+ /* Secure Header Field Element */
+ secureHeaderItem++;
+ secureHeader[secureHeaderItem] = (NSSCMSSecureHeaderElement *) PORT_Alloc(sizeof(NSSCMSSecureHeaderElement));
+ secureHeader[secureHeaderItem]->selector=NSSCMSSecureHeaderElement_secHeaderField;
+ /* Alloc table which will contain the encode result of each header element */
+ secureHeader[secureHeaderItem]->id.secHeaderFields = ( NSSCMSSecHeaderFieldElement** ) PORT_Alloc((nbHeaders + 1) * sizeof( NSSCMSSecHeaderFieldElement * ));
+
+ /* init to NULL each header element */
+ for(i=0;i<nbHeaders;++i)
+ {
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i] = NULL;
+ }
+
+ /* the last must be null */
+ secureHeader[secureHeaderItem]->id.secHeaderFields[nbHeaders] = NULL;
+
+ for(i=0;i<nbHeaders;++i)
+ {
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i] = (NSSCMSSecHeaderFieldElement *) PORT_Alloc(sizeof(NSSCMSSecHeaderFieldElement));
+
+ if(secureHeader[secureHeaderItem]->id.secHeaderFields[i] == NULL) goto loser;
+
+ /* init all *.data to null */
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldName.data = NULL;
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldValue.data = NULL;
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldStatus.data = NULL;
+ /* secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldEncrypted.data = NULL; */
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldName.len = 0;
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldValue.len = 0;
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldStatus.len = 0;
+ /* secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldEncrypted.len = 0; */
+
+ /* headername */
+ if(arrayHeaderField[i].headerName!=NULL)
+ {
+ len=PORT_Strlen((const char *)(arrayHeaderField[i].headerName));
+ if(len>0){
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldName.len=len;
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldName.data = (char *)PORT_Alloc(len * sizeof(char));
+ if(secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldName.data == NULL) goto loser;
+ PORT_Memcpy(secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldName.data,arrayHeaderField[i].headerName,len);
+ }
+ }
+ /* headervalue */
+ if(arrayHeaderField[i].headerValue!=NULL)
+ {
+ len=PORT_Strlen((const char *)arrayHeaderField[i].headerValue);
+ if(len>0){
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldValue.len=len;
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldValue.data = (char *)PORT_Alloc(len * sizeof(char));
+ if(secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldValue.data == NULL) goto loser;
+ PORT_Memcpy(secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldValue.data,arrayHeaderField[i].headerValue,len);
+ }
+ }
+ /* headerstatus */
+ if(arrayHeaderField[i].headerStatus!=-1)
+ {
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldStatus.data = (unsigned char*) PORT_Alloc(4 * sizeof(unsigned char));
+ if (secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldStatus.data == NULL) goto loser;
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldStatus.data[0] = 0;
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldStatus.data[1] = 0;
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldStatus.data[2] = (unsigned char) (arrayHeaderField[i].headerStatus>>8 & 0xFF);
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldStatus.data[3] = (unsigned char) (arrayHeaderField[i].headerStatus & 0xFF);
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldStatus.len = 4;
+ }
+
+ /* headerEncrypted */
+ /*if(arrayHeaderField[i].headerEncrypted!=-1)
+ {
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldEncrypted.data = (unsigned char*) PORT_Alloc(4 * sizeof(unsigned char));
+ if (secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldEncrypted.data == NULL) goto loser;
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldEncrypted.data[0] = 0;
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldEncrypted.data[1] = 0;
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldEncrypted.data[2] = (unsigned char) (arrayHeaderField[i].headerEncrypted>>8 & 0xFF);
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldEncrypted.data[3] = (unsigned char) (arrayHeaderField[i].headerEncrypted & 0xFF);
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldEncrypted.len = 4;
+ }*/
+
+ }
+
+ /* Now encode */
+ dummy = SEC_ASN1EncodeItem(poolp, dest, &secureHeader, NSSCMSSecureHeaderTemplate);
+
+loser:
+ /* Free memory */
+ for(secureHeaderItem=0;secureHeader[secureHeaderItem]!=NULL;++secureHeaderItem)
+ {
+
+ switch (secureHeader[secureHeaderItem]->selector)
+ {
+ case NSSCMSSecureHeaderElement_canonAlgorithm:
+ if(secureHeader[secureHeaderItem]->id.canonAlgorithm.data!=NULL)
+ {
+ PORT_Free((unsigned char *)secureHeader[secureHeaderItem]->id.canonAlgorithm.data);
+ }
+ break;
+ case NSSCMSSecureHeaderElement_secHeaderField:
+ for(i=0;secureHeader[secureHeaderItem]->id.secHeaderFields[i]!=NULL;++i)
+ {
+ if(secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldName.data != NULL){
+ PORT_Free((char *)(secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldName.data));
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldName.data=NULL;
+ }
+
+ if(secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldValue.data!=NULL){
+ PORT_Free((char*) (secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldValue.data));
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldValue.data=NULL;
+ }
+
+ if(secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldStatus.data!=NULL){
+ PORT_Free((unsigned char*) (secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldStatus.data));
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldStatus.data=NULL;
+ }
+
+ /*if(secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldEncrypted.data!=NULL){
+ PORT_Free((unsigned char*) (secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldEncrypted.data));
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i]->HeaderFieldEncrypted.data=NULL;
+ }*/
+
+ PORT_Free((NSSCMSSecHeaderFieldElement *) (secureHeader[secureHeaderItem]->id.secHeaderFields[i]) );
+ secureHeader[secureHeaderItem]->id.secHeaderFields[i] = NULL;
+ }
+
+ if(secureHeader[secureHeaderItem]->id.secHeaderFields!=NULL){
+ PORT_Free(( NSSCMSSecHeaderFieldElement** )(secureHeader[secureHeaderItem]->id.secHeaderFields));
+ secureHeader[secureHeaderItem]->id.secHeaderFields = NULL;
+ }
+ break;
+
+
+ }
+
+ if(secureHeader[secureHeaderItem]!=NULL){
+ PORT_Free((NSSCMSSecureHeaderElement *) secureHeader[secureHeaderItem]);
+ secureHeader[secureHeaderItem] = NULL;
+ }
+
+ }
+
+ if(secureHeader!=NULL)
+ {
+ PORT_Free((NSSCMSSecureHeaderElement **) secureHeader);
+ secureHeader = NULL;
+ }
+
+ return (dummy == NULL) ? SECFailure : SECSuccess;
+
+}
+
+SECStatus
+NSS_SMIMEUtil_GetSecureHeader(NSSCMSSignerInfo *signerinfo, NSSCMSSecureHeader * secuHeaders)
+{
+ NSSCMSAttribute *attr;
+ SECStatus rv;
+
+ PLArenaPool *poolp;
+ void *mark;
+
+ poolp = signerinfo->cmsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(signerinfo->authAttr, SEC_OID_SMIME_SECURE_HEADERS, PR_TRUE);
+ if (attr != NULL && attr->values != NULL && attr->values[0] != NULL)
+ {
+ rv = SEC_ASN1DecodeItem(poolp, secuHeaders, NSSCMSSecureHeaderTemplate, attr->values[0]);
+ } else {
+ rv = SECFailure;
+ }
+
+ PORT_ArenaUnmark (poolp, mark);
+ return rv;
+
+}
+
+/*
+ * NSS_SMIMEUtil_CreateReceiptRequest - create a S/MIME receipt request attribute
+ */
+SECStatus
+NSS_SMIMEUtil_CreateReceiptRequest(PLArenaPool *aPoolp,
+ SECItem *aDest,
+ char *aSignedContentIdentifier,
+ char *aReceiptsTo)
+{
+ NSSCMSReceiptRequest receiptRequest;
+ CERTGeneralName generalName;
+ SECItem *dummy = NULL;
+
+ /* signedContentIdentifier */
+ receiptRequest.signedContentIdentifier.data = (unsigned char*)aSignedContentIdentifier;
+ receiptRequest.signedContentIdentifier.len = PORT_Strlen(aSignedContentIdentifier);
+
+ /* receiptsFrom */
+ SEC_ASN1EncodeInteger(aPoolp, &(receiptRequest.receiptsFrom), 0); /* 0 = allReceipts */
+
+ /* receiptsTo */
+ generalName.type = certRFC822Name;
+ generalName.name.other.data = (unsigned char*)aReceiptsTo;
+ generalName.name.other.len = PORT_Strlen(aReceiptsTo);
+ receiptRequest.receiptsTo = PORT_Alloc(3 * sizeof(NSSCMSReceiptRequestGeneralNames*));
+ if (receiptRequest.receiptsTo == NULL)
+ goto loser;
+ receiptRequest.receiptsTo[0] = PORT_Alloc(1 * sizeof(NSSCMSReceiptRequestGeneralNames));
+ if (receiptRequest.receiptsTo[0] == NULL)
+ goto loser;
+ receiptRequest.receiptsTo[0]->generalNameSeq = PORT_Alloc(2 * sizeof(SECItem*));
+ if (receiptRequest.receiptsTo[0]->generalNameSeq == NULL)
+ goto loser;
+ receiptRequest.receiptsTo[0]->generalNameSeq[0] = CERT_EncodeGeneralName(&generalName, NULL, aPoolp);
+ if (receiptRequest.receiptsTo[0]->generalNameSeq[0] == NULL)
+ goto loser;
+ receiptRequest.receiptsTo[0]->generalNameSeq[1] = NULL;
+
+ receiptRequest.receiptsTo[1] = NULL;
+
+ /* Encode receipt request */
+ dummy = SEC_ASN1EncodeItem(aPoolp, aDest, &receiptRequest, NSSCMSReceiptRequestTemplate);
+
+loser:
+ if (receiptRequest.receiptsTo) {
+ if (receiptRequest.receiptsTo[0]) {
+ if (receiptRequest.receiptsTo[0]->generalNameSeq)
+ PORT_Free(receiptRequest.receiptsTo[0]->generalNameSeq);
+ PORT_Free(receiptRequest.receiptsTo[0]);
+ }
+ PORT_Free(receiptRequest.receiptsTo);
+ }
+
+ return (dummy == NULL) ? SECFailure : SECSuccess;
+}
+
+/*
+ * NSS_SMIMEUtil_GetReceiptRequest - decode S/MIME receipt request values
+ */
+SECStatus
+NSS_SMIMEUtil_GetReceiptRequest(NSSCMSSignerInfo *aSignerinfo,
+ PRBool *aHasReceiptRequest,
+ unsigned char **aSignedContentIdentifier,
+ unsigned int *aSignedContentIdentifierLen,
+ unsigned int *aReceiptsFrom,
+ char **aReceiptsTo,
+ unsigned char **aOriginatorSignatureValue,
+ unsigned int *aOriginatorSignatureValueLen,
+ unsigned char **aOriginatorContentType,
+ unsigned int *aOriginatorContentTypeLen,
+ unsigned char **aMsgSigDigest,
+ unsigned int *aMsgSigDigestLen)
+{
+ NSSCMSAttribute *attr;
+ SECStatus rv = SECSuccess;
+
+ PLArenaPool *poolp;
+ void *mark;
+ NSSCMSReceiptRequest receiptRequest;
+ CERTGeneralName *generalName = NULL;
+ unsigned int i;
+ unsigned int j;
+ unsigned int len;
+ unsigned long tempLongValue;
+ SECItem encodedAttrs;
+ SECOidTag digestAlgTag;
+ HASH_HashType hashType;
+
+ poolp = aSignerinfo->cmsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(aSignerinfo->authAttr, SEC_OID_SMIME_RECEIPT_REQUEST, PR_TRUE);
+
+ if (attr == NULL || attr->values == NULL || attr->values[0] == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+
+ if ((rv = SEC_ASN1DecodeItem(poolp, &receiptRequest, NSSCMSReceiptRequestTemplate, attr->values[0])) != SECSuccess)
+ goto loser;
+
+ *aHasReceiptRequest = PR_TRUE;
+
+ /* signedContentIdentifier */
+ len = receiptRequest.signedContentIdentifier.len;
+ if (len == 0) {
+ rv = SECFailure;
+ goto loser;
+ }
+ *aSignedContentIdentifier = PORT_Alloc(len);
+ PORT_Memcpy(*aSignedContentIdentifier, receiptRequest.signedContentIdentifier.data, len);
+ *aSignedContentIdentifierLen = len;
+
+ /* receiptsFrom */
+ if ((rv = SEC_ASN1DecodeInteger(&(receiptRequest.receiptsFrom), &tempLongValue)) != SECSuccess)
+ goto loser;
+ /* Process only "allReceipts" value (=0) as for now
+ TODO: process "firstTierRecipients" and "receiptList" */
+ if (tempLongValue != 0) {
+ rv = SECFailure;
+ goto loser;
+ }
+ *aReceiptsFrom = tempLongValue;
+
+ /* receiptsTo */
+ if (receiptRequest.receiptsTo != NULL) {
+ NSSCMSReceiptRequestGeneralNames **p = receiptRequest.receiptsTo;
+ /* For each GeneralNames */
+ for (i = 0; p[i] != NULL; i++) {
+ if (p[i]->generalNameSeq != NULL) {
+ /* For each GeneralName */
+ for (j = 0; p[i]->generalNameSeq[j] != NULL; j++) {
+ generalName = CERT_DecodeGeneralName(poolp, p[i]->generalNameSeq[j], NULL);
+ /* Read only first recipient address
+ TODO: read all recipients whom to send a receipt */
+ if (generalName != NULL)
+ break;
+ }
+ }
+ if (generalName != NULL)
+ break;
+ }
+ }
+
+ len = 0;
+ if (generalName != NULL && generalName->type == certRFC822Name && generalName->name.other.len > 0)
+ len = generalName->name.other.len;
+ if (len > 0) {
+ *aReceiptsTo = PORT_Alloc(len + 1);
+ PORT_Memcpy(*aReceiptsTo, generalName->name.other.data, len);
+ (*aReceiptsTo)[len] = '\0';
+ } else {
+ rv = SECFailure;
+ goto loser;
+ }
+
+ /* originatorSignatureValue */
+ len = aSignerinfo->encDigest.len;
+ if (len == 0) {
+ rv = SECFailure;
+ goto loser;
+ }
+ *aOriginatorSignatureValue = PORT_Alloc(len);
+ PORT_Memcpy(*aOriginatorSignatureValue, aSignerinfo->encDigest.data, len);
+ *aOriginatorSignatureValueLen = len;
+
+ /* originatorContentType */
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(aSignerinfo->authAttr, SEC_OID_PKCS9_CONTENT_TYPE, PR_TRUE);
+ if (attr == NULL || attr->values == NULL || attr->values[0] == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+ len = attr->values[0]->len;
+ if (len == 0) {
+ rv = SECFailure;
+ goto loser;
+ }
+ *aOriginatorContentType = PORT_Alloc(len);
+ PORT_Memcpy(*aOriginatorContentType, attr->values[0]->data, len);
+ *aOriginatorContentTypeLen = len;
+
+ /* Compute msgSigDigest (digest of the signed attributes) */
+ encodedAttrs.data = NULL;
+ encodedAttrs.len = 0;
+
+ /* Encode array of signed attributes */
+ if (NSS_CMSAttributeArray_Encode(poolp, &(aSignerinfo->authAttr), &encodedAttrs) == NULL)
+ goto loser;
+
+ /* Get digest type */
+ digestAlgTag = NSS_CMSSignerInfo_GetDigestAlgTag(aSignerinfo);
+ hashType = HASH_GetHashTypeByOidTag(digestAlgTag);
+
+ len = HASH_ResultLen(hashType);
+ if (len == 0) {
+ rv = SECFailure;
+ goto loser;
+ }
+ *aMsgSigDigest = PORT_Alloc(len);
+ *aMsgSigDigestLen = len;
+
+ /* Compute digest */
+ if ((rv = HASH_HashBuf(hashType, *aMsgSigDigest, encodedAttrs.data, encodedAttrs.len)) != SECSuccess)
+ goto loser;
+
+loser:
+ if (rv != SECSuccess)
+ *aHasReceiptRequest = PR_FALSE;
+
+ PORT_ArenaUnmark(poolp, mark);
+ return rv;
+}
+
+/*
+ * NSS_SMIMEUtil_CreateReceipt - create a S/MIME receipt
+ */
+SECStatus
+NSS_SMIMEUtil_CreateReceipt(PLArenaPool *aPoolp,
+ SECItem *aReceipt,
+ unsigned char **aReceiptDigest,
+ unsigned int *aReceiptDigestLen,
+ const unsigned char *aSignedContentIdentifier,
+ const unsigned int aSignedContentIdentifierLen,
+ const unsigned char *aOriginatorSignatureValue,
+ const unsigned int aOriginatorSignatureValueLen,
+ const unsigned char *aOriginatorContentType,
+ const unsigned int aOriginatorContentTypeLen)
+{
+ NSSCMSReceipt receipt;
+ SECItem *dummy = NULL;
+ SECItem *encodedReceipt = NULL;
+ HASH_HashType hashType;
+
+ /* version */
+ SEC_ASN1EncodeInteger(aPoolp, &(receipt.version), 1);
+
+ /* contentType */
+ receipt.contentType.data = (unsigned char*)aOriginatorContentType;
+ receipt.contentType.len = aOriginatorContentTypeLen;
+
+ /* signedContentIdentifier */
+ receipt.signedContentIdentifier.data = (unsigned char*)aSignedContentIdentifier;
+ receipt.signedContentIdentifier.len = aSignedContentIdentifierLen;
+
+ /* originatorSignatureValue */
+ receipt.originatorSignatureValue.data = (unsigned char*)aOriginatorSignatureValue;
+ receipt.originatorSignatureValue.len = aOriginatorSignatureValueLen;
+
+ /* Encode receipt */
+ encodedReceipt = SEC_ASN1EncodeItem(aPoolp, encodedReceipt, &receipt, NSSCMSReceiptTemplate);
+ if (encodedReceipt == NULL)
+ return SECFailure;
+
+ /* Compute digest of the receipt object */
+ hashType = HASH_GetHashTypeByOidTag(SEC_OID_SHA1);
+ *aReceiptDigestLen = HASH_ResultLen(hashType);
+ if (*aReceiptDigestLen == 0)
+ return SECFailure;
+ *aReceiptDigest = PORT_Alloc(*aReceiptDigestLen);
+ if (HASH_HashBuf(hashType, *aReceiptDigest, encodedReceipt->data, encodedReceipt->len) != SECSuccess)
+ return SECFailure;
+
+ /* Encapsulate receipt in octet string */
+ dummy = SEC_ASN1EncodeItem(aPoolp, aReceipt, encodedReceipt, SEC_ASN1_GET(SEC_OctetStringTemplate));
+
+ return (dummy == NULL) ? SECFailure : SECSuccess;
+}
+
+/*
+ * NSS_SMIMEUtil_GetReceipt - decode a S/MIME receipt
+ */
+SECStatus
+NSS_SMIMEUtil_GetReceipt(PLArenaPool *aPoolp,
+ SECItem *aEncodedReceipt,
+ unsigned char **aSignedContentIdentifier,
+ unsigned int *aSignedContentIdentifierLen,
+ unsigned char **aOriginatorSignatureValue,
+ unsigned int *aOriginatorSignatureValueLen,
+ unsigned char **aOriginatorContentType,
+ unsigned int *aOriginatorContentTypeLen)
+{
+ NSSCMSAttribute *attr;
+ SECStatus rv = SECSuccess;
+ NSSCMSReceipt receipt;
+ unsigned int len;
+ void *mark;
+
+ mark = PORT_ArenaMark(aPoolp);
+
+ if ((rv = SEC_ASN1DecodeItem(aPoolp, &receipt, NSSCMSReceiptTemplate, aEncodedReceipt)) != SECSuccess)
+ goto loser;
+
+ /* contentType */
+ len = receipt.contentType.len;
+ *aOriginatorContentType = PORT_Alloc(len);
+ PORT_Memcpy(*aOriginatorContentType, receipt.contentType.data, len);
+ *aOriginatorContentTypeLen = len;
+
+ /* signedContentIdentifier */
+ len = receipt.signedContentIdentifier.len;
+ *aSignedContentIdentifier = PORT_Alloc(len);
+ PORT_Memcpy(*aSignedContentIdentifier, receipt.signedContentIdentifier.data, len);
+ *aSignedContentIdentifierLen = len;
+
+ /* originatorSignatureValue */
+ len = receipt.originatorSignatureValue.len;
+ *aOriginatorSignatureValue = PORT_Alloc(len);
+ PORT_Memcpy(*aOriginatorSignatureValue, receipt.originatorSignatureValue.data, len);
+ *aOriginatorSignatureValueLen = len;
+
+loser:
+ PORT_ArenaUnmark(aPoolp, mark);
+ return rv;
+}
+/**
+ * DER-encode a dot-separated string of integers
+ * @param in data Dot-separated string of integers
+ * @param in len Length of data
+ * @param out output Pointer to a DER-encoded string which will be allocated - caller will have to PORT_Free() it
+ * @param out outputLen Length of returned output buffer
+ * @return *output or NULL if encoding failed
+ */
+void *
+NSS_SMIMEUtil_EncodeOid(const char *data, const unsigned int len, unsigned char **output, unsigned int *outputLen)
+{
+ unsigned int i;
+ unsigned int k;
+ unsigned int dotCount;
+ unsigned int *oid;
+ unsigned int n;
+ unsigned int itemCount;
+ unsigned char tempDER[5];
+
+ *outputLen = 0;
+
+ /* Count number of dot in the string */
+ dotCount = 0;
+ for (i = 0; i < len; i++)
+ if (data[i] == '.')
+ dotCount++;
+
+ if (dotCount == 0)
+ return NULL;
+
+ /* Allocate OID array of integers */
+ oid = PORT_Alloc((dotCount + 1) * sizeof(unsigned int));
+ if (oid == NULL)
+ return NULL;
+
+ /* Convert decimal, dot-separated OID string to an array of integers */
+ n = 0;
+ itemCount = 0;
+ for (i = 0; i <= len; i++) { /* Analyze all characters + 1 loop at the end */
+ if (i == len || data[i] == '.') {
+ /* Store number */
+ oid[itemCount++] = n;
+ n = 0;
+ } else if (data[i] >= '0' && data[i] <= '9') {
+ /* Add digit to number */
+ n *= 10;
+ n += data[i] - '0';
+ } else {
+ /* Unknown character */
+ PORT_Free(oid);
+ return NULL;
+ }
+ }
+
+ /* Error if less than 2 items */
+ if (itemCount < 2) {
+ PORT_Free(oid);
+ return NULL;
+ }
+
+ /* Check range of first 2 items */
+ if ((oid[0] < 2 && oid[1] > 39) ||
+ (oid[0] == 2 && oid[1] > 47) ||
+ (oid[0] > 2)) {
+ PORT_Free(oid);
+ return NULL;
+ }
+
+ /* Allocate DER-encoded buffer: 5 bytes by item maximum */
+ *output = PORT_Alloc((itemCount * 5) * sizeof(unsigned char));
+ if (*output == NULL) {
+ PORT_Free(oid);
+ return NULL;
+ }
+
+ /* DER encode the array of integers */
+ /* First byte contains first and second items */
+ (*output)[(*outputLen)++] = oid[0] * 40 + oid[1];
+ /* Next bytes */
+ for (i = 2; i < itemCount; i++) {
+ n = 0;
+ do {
+ if (n == 5) {/* 5 bytes by item maximum */
+ PORT_Free(oid);
+ return NULL;
+ }
+ tempDER[n] = oid[i] & 0x7F;
+ if (n != 0)
+ tempDER[n] |= 0x80;
+ oid[i] >>= 7;
+ n++;
+ } while (oid[i] > 0);
+ for (k = 0; k < n; k++)
+ (*output)[(*outputLen)++] = tempDER[n - 1 - k];
+ }
+
+ PORT_Free(oid);
+
+ return *output;
+}
+
+/**
+ * Decode a DER encoded OID to a dot-separated string of integers
+ * @param in data DER encoded buffer
+ * @param in len Length of data
+ * @param out output Pointer to a string which will be allocated - caller will have to PORT_Free() it
+ * @return SECSuccess or SECFailure if decoding failed
+ */
+SECStatus
+NSS_SMIMEUtil_DecodeOid(const unsigned char *data, const unsigned int len, char **output)
+{
+ unsigned int itemCount;
+ unsigned int outputCount;
+ unsigned int i;
+ unsigned int n;
+ unsigned int *oid;
+ int ret;
+
+ if (len == 0 || data[0] >= 128)
+ return SECFailure;
+
+ /* Convert DER encoded OID to an array of integers (number of values is less than 'len + 1') */
+ oid = PORT_Alloc((len + 1) * sizeof(unsigned int));
+ if (oid == NULL)
+ return SECFailure;
+
+ itemCount = 0;
+ /* Range of second item is 0-39 if first item is 0 or 1
+ * and 0-47 if first item is 2 */
+ if (data[0] < 120) {
+ oid[itemCount++] = data[0] / 40;
+ oid[itemCount++] = data[0] % 40;
+ } else {
+ oid[itemCount++] = 2;
+ oid[itemCount++] = data[0] - (2 * 40);
+ }
+
+ n = 0;
+ for (i = 1; i < len; i++) {
+ n = n * 128 + (data[i] & 0x7F);
+ if ((data[i] & 0x80) != 0x80) {
+ oid[itemCount++] = n;
+ n = 0;
+ }
+ }
+
+ /* Allocate output string: max 10 characters by number + '.' */
+ /* TODO: find a better way to compute max size of integers */
+ *output = PORT_Alloc(itemCount * (10 + 1) * sizeof(char));
+ if (*output == NULL) {
+ PORT_Free(oid);
+ return SECFailure;
+ }
+
+ outputCount = 0;
+ for (i = 0; i < itemCount; i++) {
+ if (i != 0) {
+ (*output)[outputCount] = '.';
+ outputCount++;
+ }
+ ret = PR_snprintf(&((*output)[outputCount]), 11, "%lu", oid[i]);
+ if (ret > 0 && ret < 11)
+ outputCount += ret;
+ else {
+ PORT_Free(oid);
+ return SECFailure;
+ }
+ }
+ (*output)[outputCount] = '\0';
+
+ PORT_Free(oid);
+
+ return SECSuccess;
+}
+
+/*
+ * NSS_SMIMEUtil_CreateSecurityLabel - create S/MIME SecurityLabel attr value
+ */
+SECStatus
+NSS_SMIMEUtil_CreateSecurityLabel(PLArenaPool *aPoolp,
+ SECItem *aDest,
+ char *aSecurityPolicyIdentifier,
+ PRInt32 aSecurityClassification,
+ char *aPrivacyMark,
+ char *aSecurityCategories)
+{
+ NSSCMSSecurityLabelElement **securityLabel;
+ SECItem *dummy = NULL;
+ unsigned int len;
+ unsigned int i;
+ unsigned int k;
+ unsigned int separatorCount;
+ unsigned int categoryCount;
+ unsigned int startPosition;
+ unsigned int fieldLen;
+ const char securityCategoriesSeparator = '|';
+ unsigned int securityLabelItem;
+ SECItem tempSecurityCategoryValue;
+ unsigned int tempSecurityCategoryValueType;
+ unsigned long tempSecurityCategoryValueInteger;
+ char valueChar;
+
+ /* Array of 4 elements max + 1 NULL at the end = 5 elements */
+ securityLabel = PORT_Alloc(5 * sizeof(NSSCMSSecurityLabelElement*));
+ for (i = 0; i < 5; i++)
+ securityLabel[i] = NULL;
+
+ securityLabelItem = 0;
+
+ /*
+ * securityPolicyIdentifier
+ */
+ securityLabel[securityLabelItem] = PORT_Alloc(sizeof(NSSCMSSecurityLabelElement));
+ securityLabel[securityLabelItem]->selector = NSSCMSSecurityLabelElement_securityPolicyIdentifier;
+ if (NSS_SMIMEUtil_EncodeOid(aSecurityPolicyIdentifier, PORT_Strlen(aSecurityPolicyIdentifier), &(securityLabel[securityLabelItem]->id.securityPolicyIdentifier.data), &(securityLabel[securityLabelItem]->id.securityPolicyIdentifier.len)) == NULL)
+ goto loser;
+ securityLabelItem++;
+
+ /*
+ * securityClassification
+ */
+ if (aSecurityClassification >= 0 && aSecurityClassification <= 256) {
+ securityLabel[securityLabelItem] = PORT_Alloc(sizeof(NSSCMSSecurityLabelElement));
+ securityLabel[securityLabelItem]->selector = NSSCMSSecurityLabelElement_securityClassification;
+
+ if (SEC_ASN1EncodeUnsignedInteger(aPoolp, &(securityLabel[securityLabelItem]->id.securityClassification), (unsigned int)aSecurityClassification) == NULL)
+ goto loser;
+ securityLabelItem++;
+ }
+
+ /*
+ * privacyMark
+ */
+ len = PORT_Strlen(aPrivacyMark);
+ if (len > 0) {
+ securityLabel[securityLabelItem] = PORT_Alloc(sizeof(NSSCMSSecurityLabelElement));
+ securityLabel[securityLabelItem]->selector = NSSCMSSecurityLabelElement_privacyMarkUTF8;
+
+ securityLabel[securityLabelItem]->id.privacyMarkUTF8.len = 0;
+ securityLabel[securityLabelItem]->id.privacyMarkUTF8.data = PORT_Alloc(len * sizeof(unsigned char));
+ if (securityLabel[securityLabelItem]->id.privacyMarkUTF8.data == NULL)
+ goto loser;
+ PORT_Memcpy(securityLabel[securityLabelItem]->id.privacyMarkUTF8.data, aPrivacyMark, len);
+ securityLabel[securityLabelItem]->id.privacyMarkUTF8.len = len;
+ securityLabelItem++;
+ }
+
+ /*
+ * securityCategories
+ * format: cat1_OID|cat1_type|cat1_value|cat2_OID|cat2_type|cat2_value|cat3_OID|cat3_type|cat3_value
+ *
+ * catX_type: 1 (UTF-8)
+ * 2 (integer)
+ */
+ len = PORT_Strlen(aSecurityCategories);
+ if (len > 0) {
+ separatorCount = 0;
+
+ /* Count number of separator character */
+ for (i = 0; i < len; i++)
+ if (aSecurityCategories[i] == securityCategoriesSeparator)
+ separatorCount++;
+
+ /* Separator count must be correct */
+ if (separatorCount < 2 || (((separatorCount - 2 ) % 3) != 0))
+ goto loser;
+ categoryCount = ((separatorCount - 2 ) / 3) + 1;
+
+ /* Create object */
+ securityLabel[securityLabelItem] = PORT_Alloc(sizeof(NSSCMSSecurityLabelElement));
+ securityLabel[securityLabelItem]->selector = NSSCMSSecurityLabelElement_securityCategories;
+
+ /* Allocate categoryCount + 1 NULL securityCategories */
+ securityLabel[securityLabelItem]->id.securityCategories = PORT_Alloc((categoryCount + 1) * sizeof(NSSCMSSecurityLabelSecurityCategory*));
+ if (securityLabel[securityLabelItem]->id.securityCategories == NULL)
+ goto loser;
+ for (i = 0; i < categoryCount; i++) {
+ securityLabel[securityLabelItem]->id.securityCategories[i] = PORT_Alloc(sizeof(NSSCMSSecurityLabelSecurityCategory));
+ if (securityLabel[securityLabelItem]->id.securityCategories[i] == NULL)
+ goto loser;
+ securityLabel[securityLabelItem]->id.securityCategories[i]->securityCategoryIdentifier.len = 0;
+ securityLabel[securityLabelItem]->id.securityCategories[i]->securityCategoryValue.len = 0;
+ }
+ /* Last one is NULL */
+ securityLabel[securityLabelItem]->id.securityCategories[categoryCount] = NULL;
+
+ startPosition = 0;
+
+ for (i = 0; i < categoryCount; i++) {
+ /* Search and copy securityCategoryIdentifier */
+ fieldLen = 0;
+ for (k = startPosition; k < len; k++) {
+ if (aSecurityCategories[k] == securityCategoriesSeparator) {
+ fieldLen = k - startPosition;
+ break;
+ }
+ }
+
+ if (fieldLen > 0) {
+ if (NSS_SMIMEUtil_EncodeOid(aSecurityCategories + startPosition, fieldLen, &(securityLabel[securityLabelItem]->id.securityCategories[i]->securityCategoryIdentifier.data), &(securityLabel[securityLabelItem]->id.securityCategories[i]->securityCategoryIdentifier.len)) == NULL)
+ goto loser;
+ startPosition += fieldLen + 1;
+ } else
+ goto loser;
+
+ /* Search type */
+ fieldLen = 0;
+ for (k = startPosition; k < len; k++) {
+ if (aSecurityCategories[k] == securityCategoriesSeparator) {
+ fieldLen = k - startPosition;
+ break;
+ }
+ }
+
+ if (fieldLen == 1) {
+ tempSecurityCategoryValueType = 0;
+ if (aSecurityCategories[startPosition] >= '0' && aSecurityCategories[startPosition] <= '9')
+ tempSecurityCategoryValueType = aSecurityCategories[startPosition] - '0';
+
+ startPosition += fieldLen + 1;
+ } else
+ goto loser;
+
+ /* Search and copy securityCategoryValue */
+ fieldLen = 0;
+ for (k = startPosition; k < len; k++) {
+ if (aSecurityCategories[k] == securityCategoriesSeparator) {
+ fieldLen = k - startPosition;
+ break;
+ }
+ if (k == len - 1) { /* Last character */
+ fieldLen = k - startPosition + 1;
+ break;
+ }
+ }
+
+ if (fieldLen > 0) {
+ switch (tempSecurityCategoryValueType) {
+ case SECURITY_CATEGORY_VALUE_TYPE_UTF8:
+ tempSecurityCategoryValue.data = (unsigned char*)aSecurityCategories + startPosition;
+ tempSecurityCategoryValue.len = fieldLen;
+ if (SEC_ASN1EncodeItem(aPoolp, &(securityLabel[securityLabelItem]->id.securityCategories[i]->securityCategoryValue), &tempSecurityCategoryValue, securityCategoryValueUTF8Template) == NULL)
+ goto loser;
+ break;
+ case SECURITY_CATEGORY_VALUE_TYPE_INTEGER:
+ if (fieldLen > 10)
+ goto loser;
+ /* TODO: find a better way to compute max size of integers */
+
+ tempSecurityCategoryValueInteger = 0;
+ for (k = 0; k < fieldLen; k++) {
+ valueChar = aSecurityCategories[startPosition + k];
+ if (valueChar >= '0' && valueChar <= '9') {
+ tempSecurityCategoryValueInteger *= 10;
+ tempSecurityCategoryValueInteger += valueChar - '0';
+ } else
+ goto loser;
+ }
+
+ if (SEC_ASN1EncodeUnsignedInteger(aPoolp, &tempSecurityCategoryValue, tempSecurityCategoryValueInteger) == NULL)
+ goto loser;
+
+ if (SEC_ASN1EncodeItem(aPoolp, &(securityLabel[securityLabelItem]->id.securityCategories[i]->securityCategoryValue), &tempSecurityCategoryValue, securityCategoryValueIntegerTemplate) == NULL)
+ goto loser;
+ break;
+ default:
+ goto loser;
+ break;
+ }
+
+ startPosition += fieldLen + 1;
+ } else
+ goto loser;
+
+ }
+ securityLabelItem++;
+ }
+
+ /* Encode Security Label */
+ dummy = SEC_ASN1EncodeItem(aPoolp, aDest, &securityLabel, NSSCMSSecurityLabelTemplate);
+
+loser:
+ for (i = 0; securityLabel[i] != NULL; i++) {
+ switch (securityLabel[i]->selector) {
+ case NSSCMSSecurityLabelElement_securityPolicyIdentifier:
+ if (securityLabel[i]->id.securityPolicyIdentifier.len > 0)
+ PORT_Free(securityLabel[i]->id.securityPolicyIdentifier.data);
+ break;
+ case NSSCMSSecurityLabelElement_securityClassification:
+ break;
+ case NSSCMSSecurityLabelElement_privacyMarkPrintableString:
+ if (securityLabel[i]->id.privacyMarkPrintableString.len > 0)
+ PORT_Free(securityLabel[i]->id.privacyMarkPrintableString.data);
+ break;
+ case NSSCMSSecurityLabelElement_privacyMarkUTF8:
+ if (securityLabel[i]->id.privacyMarkUTF8.len > 0)
+ PORT_Free(securityLabel[i]->id.privacyMarkUTF8.data);
+ break;
+ case NSSCMSSecurityLabelElement_securityCategories:
+ if (securityLabel[i]->id.securityCategories != NULL) {
+ for (k = 0; securityLabel[i]->id.securityCategories[k] != NULL; k++) {
+ if (securityLabel[i]->id.securityCategories[k]->securityCategoryIdentifier.len > 0)
+ PORT_Free(securityLabel[i]->id.securityCategories[k]->securityCategoryIdentifier.data);
+ PORT_Free(securityLabel[i]->id.securityCategories[k]);
+ }
+ PORT_Free(securityLabel[i]->id.securityCategories);
+ }
+ break;
+ }
+
+ PORT_Free(securityLabel[i]);
+ }
+ PORT_Free(securityLabel);
+
+ return (dummy == NULL) ? SECFailure : SECSuccess;
+}
+
+/*
+ * NSS_SMIMEUtil_GetSecurityLabel - get S/MIME SecurityLabel attr value
+ */
+SECStatus
+NSS_SMIMEUtil_GetSecurityLabel(NSSCMSSignerInfo *aSignerinfo,
+ PRBool *aHasSecurityLabel,
+ char **aSecurityPolicyIdentifier,
+ PRInt32 *aSecurityClassification,
+ char **aPrivacyMark,
+ char **aSecurityCategories)
+{
+ NSSCMSAttribute *attr;
+ SECStatus rv = SECSuccess;
+
+ PLArenaPool *poolp;
+ void *mark;
+
+ NSSCMSSecurityLabel securityLabel;
+ NSSCMSSecurityLabelElement *securityLabelElement;
+ unsigned int elementId;
+ unsigned int len;
+ char *tempBuffer;
+ const char securityCategoriesSeparator = '|';
+ unsigned int i;
+ char *oid;
+ char *tempSecurityCategories;
+ unsigned long tempLongValue;
+ SECItem tempSECItemValue;
+ int ret;
+
+ /* We have to check uniqueness of each element as we use a SET_OF CHOICE instead of a SET */
+ PRBool securityPolicyIdentifierFound = PR_FALSE;
+ PRBool securityClassificationFound = PR_FALSE;
+ PRBool privacyMarkFound = PR_FALSE;
+ PRBool securityCategoriesFound = PR_FALSE;
+
+ poolp = aSignerinfo->cmsg->poolp;
+ mark = PORT_ArenaMark(poolp);
+
+ attr = NSS_CMSAttributeArray_FindAttrByOidTag(aSignerinfo->authAttr, SEC_OID_SMIME_SECURITY_LABEL, PR_TRUE);
+
+ if (attr == NULL || attr->values == NULL || attr->values[0] == NULL) {
+ rv = SECFailure;
+ goto loser;
+ }
+
+ if ((rv = SEC_ASN1DecodeItem(poolp, &securityLabel, NSSCMSSecurityLabelTemplate, attr->values[0])) != SECSuccess)
+ goto loser;
+
+ for (elementId = 0; securityLabel.element[elementId] != NULL; elementId++) {
+
+ securityLabelElement = securityLabel.element[elementId];
+
+ switch (securityLabelElement->selector) {
+
+ case NSSCMSSecurityLabelElement_securityPolicyIdentifier:
+ /*
+ * securityPolicyIdentifier
+ */
+ if (securityPolicyIdentifierFound) {
+ rv = SECFailure;
+ break;
+ }
+ securityPolicyIdentifierFound = PR_TRUE;
+
+ if (securityLabelElement->id.securityPolicyIdentifier.len > 0 && securityLabelElement->id.securityPolicyIdentifier.data[0] < 128) {
+ tempBuffer = NULL;
+
+ if ((rv = NSS_SMIMEUtil_DecodeOid(securityLabelElement->id.securityPolicyIdentifier.data, securityLabelElement->id.securityPolicyIdentifier.len, &tempBuffer)) != SECSuccess)
+ break;
+
+ if (tempBuffer != NULL) {
+ len = PORT_Strlen(tempBuffer);
+ *aSecurityPolicyIdentifier = PORT_Alloc((len + 1) * sizeof(char));
+ PORT_Memcpy(*aSecurityPolicyIdentifier, tempBuffer, len + 1);
+ PORT_Free(tempBuffer);
+
+ *aHasSecurityLabel = PR_TRUE;
+ }
+ }
+ break;
+
+ case NSSCMSSecurityLabelElement_securityClassification:
+ /*
+ * securityClassification
+ */
+ if (securityClassificationFound) {
+ rv = SECFailure;
+ break;
+ }
+ securityClassificationFound = PR_TRUE;
+
+ if ((rv = SEC_ASN1DecodeInteger(&(securityLabelElement->id.securityClassification), &tempLongValue)) != SECSuccess)
+ break;
+
+ if (tempLongValue <= 256)
+ *aSecurityClassification = tempLongValue;
+ else {
+ rv = SECFailure;
+ break;
+ }
+ break;
+
+ case NSSCMSSecurityLabelElement_privacyMarkPrintableString:
+ /*
+ * privacyMark (PrintableString)
+ */
+ if (privacyMarkFound) {
+ rv = SECFailure;
+ break;
+ }
+ privacyMarkFound = PR_TRUE;
+
+ len = securityLabelElement->id.privacyMarkPrintableString.len;
+
+ if (len > 0) {
+ tempBuffer = PORT_Alloc((len + 1) * sizeof(char));
+ if (tempBuffer == NULL) {
+ rv = SECFailure;
+ break;
+ }
+ PORT_Memcpy(tempBuffer, securityLabelElement->id.privacyMarkPrintableString.data, len);
+ tempBuffer[len] = '\0';
+
+ *aPrivacyMark = tempBuffer;
+ }
+ break;
+
+ case NSSCMSSecurityLabelElement_privacyMarkUTF8:
+ /*
+ * privacyMark (UTF8)
+ */
+ if (privacyMarkFound) {
+ rv = SECFailure;
+ break;
+ }
+ privacyMarkFound = PR_TRUE;
+
+ len = securityLabelElement->id.privacyMarkUTF8.len;
+
+ if (len > 0) {
+ tempBuffer = PORT_Alloc((len + 1) * sizeof(char));
+ if (tempBuffer == NULL) {
+ rv = SECFailure;
+ break;
+ }
+ PORT_Memcpy(tempBuffer, securityLabelElement->id.privacyMarkUTF8.data, len);
+ tempBuffer[len] = '\0';
+
+ *aPrivacyMark = tempBuffer;
+ }
+ break;
+
+ case NSSCMSSecurityLabelElement_securityCategories:
+ /*
+ * securityCategories
+ */
+ if (securityCategoriesFound) {
+ rv = SECFailure;
+ break;
+ }
+ securityCategoriesFound = PR_TRUE;
+
+ if (securityLabelElement->id.securityCategories == NULL) {
+ rv = SECFailure;
+ break;
+ }
+
+ /* Compute size of output string buffer */
+ len = 0;
+ for (i = 0; securityLabelElement->id.securityCategories[i] != NULL; i++) {
+ oid = NULL;
+ if ((rv = NSS_SMIMEUtil_DecodeOid(securityLabelElement->id.securityCategories[i]->securityCategoryIdentifier.data, securityLabelElement->id.securityCategories[i]->securityCategoryIdentifier.len, &oid)) != SECSuccess)
+ break;
+
+ if (oid != NULL) {
+ /* Add size of securityCategoryIdentifier */
+ len += PORT_Strlen(oid);
+ PORT_Free(oid);
+
+ /* Add size of type field */
+ len += 1;
+
+ /* Add size of securityCategoryValue */
+ if (securityLabelElement->id.securityCategories[i]->securityCategoryValue.len > 2) {
+ if (securityLabelElement->id.securityCategories[i]->securityCategoryValue.data[0] == SEC_ASN1_INTEGER) /* Integer */
+ len += 10;
+ /* 10 characters max for an integer */
+ /* TODO: find a better way to compute max size of integers */
+ else /* UTF-8 and other types */
+ len += securityLabelElement->id.securityCategories[i]->securityCategoryValue.len;
+ }
+
+ /* Add size of 3 separators */
+ len += 3;
+ }
+ }
+
+ if (len > 0) {
+ /* Create buffer */
+ tempSecurityCategories = PORT_Alloc(len * sizeof(char));
+ if (tempSecurityCategories == NULL) {
+ rv = SECFailure;
+ break;
+ }
+
+ /* Fill buffer */
+ len = 0;
+ for (i = 0; securityLabelElement->id.securityCategories[i] != NULL; i++) {
+ oid = NULL;
+ if ((rv = NSS_SMIMEUtil_DecodeOid(securityLabelElement->id.securityCategories[i]->securityCategoryIdentifier.data, securityLabelElement->id.securityCategories[i]->securityCategoryIdentifier.len, &oid)) != SECSuccess)
+ break;
+
+ if (oid != NULL) {
+ /* Add securityCategoryIdentifier OID */
+ PORT_Memcpy(tempSecurityCategories + len, oid, PORT_Strlen(oid));
+ len += PORT_Strlen(oid);
+ PORT_Free(oid);
+
+ /* Add separator */
+ tempSecurityCategories[len++] = securityCategoriesSeparator;
+
+ /* Add type field */
+ if (securityLabelElement->id.securityCategories[i]->securityCategoryValue.len > 0) {
+ switch (securityLabelElement->id.securityCategories[i]->securityCategoryValue.data[0]) {
+ case SEC_ASN1_UTF8_STRING: /* UTF-8 */
+ tempSecurityCategories[len++] = '0' + SECURITY_CATEGORY_VALUE_TYPE_UTF8;
+ break;
+ case SEC_ASN1_INTEGER: /* Integer */
+ tempSecurityCategories[len++] = '0' + SECURITY_CATEGORY_VALUE_TYPE_INTEGER;
+ break;
+ default: /* Other type */
+ tempSecurityCategories[len++] = '0' + SECURITY_CATEGORY_VALUE_TYPE_UNKNOWN;
+ break;
+ }
+ }
+
+ /* Add separator */
+ tempSecurityCategories[len++] = securityCategoriesSeparator;
+
+ /* Add securityCategoryValue */
+ if (securityLabelElement->id.securityCategories[i]->securityCategoryValue.len > 2) {
+ if (securityLabelElement->id.securityCategories[i]->securityCategoryValue.data[0] == SEC_ASN1_INTEGER) { /* Integer: decode */
+
+ if ((rv = SEC_ASN1DecodeItem(poolp, &tempSECItemValue, securityCategoryValueIntegerTemplate, &(securityLabelElement->id.securityCategories[i]->securityCategoryValue))) != SECSuccess)
+ break;
+
+ if ((rv = SEC_ASN1DecodeInteger(&tempSECItemValue, &tempLongValue)) != SECSuccess)
+ break;
+
+ ret = PR_snprintf(tempSecurityCategories + len, 11, "%lu", tempLongValue);
+ /* TODO: find a better way to compute max size of integers */
+ if (ret > 0 && ret < 11)
+ len += ret;
+ else {
+ rv = SECFailure;
+ break;
+ }
+ } else { /* UTF-8 and other types: direct copy */
+ PORT_Memcpy(tempSecurityCategories + len, securityLabelElement->id.securityCategories[i]->securityCategoryValue.data + 2, securityLabelElement->id.securityCategories[i]->securityCategoryValue.len - 2);
+ len += securityLabelElement->id.securityCategories[i]->securityCategoryValue.len - 2;
+ }
+ }
+
+ /* Add separator */
+ tempSecurityCategories[len++] = securityCategoriesSeparator;
+ }
+ }
+
+ /* Overwrite last separator with \0 */
+ tempSecurityCategories[len - 1] = '\0';
+
+ *aSecurityCategories = tempSecurityCategories;
+ }
+ break;
+ }
+
+ if (rv != SECSuccess)
+ break;
+ }
+
+loser:
+ /* If something failed, forget Security Label */
+ if (rv != SECSuccess)
+ *aHasSecurityLabel = PR_FALSE;
+
+ PORT_ArenaUnmark (poolp, mark);
+ return rv;
+}
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+ * Secure Headers : Copyright (c) 2011 CASSIDIAN - All rights reserved */
+
+#include "secoid.h"
+#include "pkcs11t.h"
+#include "secitem.h"
+#include "secerr.h"
+#include "prenv.h"
+#include "plhash.h"
+#include "nssrwlk.h"
+#include "nssutil.h"
+
+/* Library identity and versioning */
+
+#if defined(DEBUG)
+#define _DEBUG_STRING " (debug)"
+#else
+#define _DEBUG_STRING ""
+#endif
+
+/*
+ * Version information for the 'ident' and 'what commands
+ *
+ * NOTE: the first component of the concatenated rcsid string
+ * must not end in a '$' to prevent rcs keyword substitution.
+ */
+const char __nss_util_rcsid[] = "$Header: NSS " NSSUTIL_VERSION _DEBUG_STRING
+ " " __DATE__ " " __TIME__ " $";
+const char __nss_util_sccsid[] = "@(#)NSS " NSSUTIL_VERSION _DEBUG_STRING
+ " " __DATE__ " " __TIME__;
+
+/* MISSI Mosaic Object ID space */
+/* USGov algorithm OID space: { 2 16 840 1 101 } */
+#define USGOV 0x60, 0x86, 0x48, 0x01, 0x65
+#define MISSI USGOV, 0x02, 0x01, 0x01
+#define MISSI_OLD_KEA_DSS MISSI, 0x0c
+#define MISSI_OLD_DSS MISSI, 0x02
+#define MISSI_KEA_DSS MISSI, 0x14
+#define MISSI_DSS MISSI, 0x13
+#define MISSI_KEA MISSI, 0x0a
+#define MISSI_ALT_KEA MISSI, 0x16
+
+#define NISTALGS USGOV, 3, 4
+#define AES NISTALGS, 1
+#define SHAXXX NISTALGS, 2
+#define DSA2 NISTALGS, 3
+
+/**
+ ** The Netscape OID space is allocated by Terry Hayes. If you need
+ ** a piece of the space, contact him at thayes@netscape.com.
+ **/
+
+/* Netscape Communications Corporation Object ID space */
+/* { 2 16 840 1 113730 } */
+#define NETSCAPE_OID 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x42
+#define NETSCAPE_CERT_EXT NETSCAPE_OID, 0x01
+#define NETSCAPE_DATA_TYPE NETSCAPE_OID, 0x02
+/* netscape directory oid - owned by Mark Smith (mcs@netscape.com) */
+#define NETSCAPE_DIRECTORY NETSCAPE_OID, 0x03
+#define NETSCAPE_POLICY NETSCAPE_OID, 0x04
+#define NETSCAPE_CERT_SERVER NETSCAPE_OID, 0x05
+#define NETSCAPE_ALGS NETSCAPE_OID, 0x06 /* algorithm OIDs */
+#define NETSCAPE_NAME_COMPONENTS NETSCAPE_OID, 0x07
+
+#define NETSCAPE_CERT_EXT_AIA NETSCAPE_CERT_EXT, 0x10
+#define NETSCAPE_CERT_SERVER_CRMF NETSCAPE_CERT_SERVER, 0x01
+
+/* these are old and should go away soon */
+#define OLD_NETSCAPE 0x60, 0x86, 0x48, 0xd8, 0x6a
+#define NS_CERT_EXT OLD_NETSCAPE, 0x01
+#define NS_FILE_TYPE OLD_NETSCAPE, 0x02
+#define NS_IMAGE_TYPE OLD_NETSCAPE, 0x03
+
+/* RSA OID name space */
+#define RSADSI 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d
+#define PKCS RSADSI, 0x01
+#define DIGEST RSADSI, 0x02
+#define CIPHER RSADSI, 0x03
+#define PKCS1 PKCS, 0x01
+#define PKCS5 PKCS, 0x05
+#define PKCS7 PKCS, 0x07
+#define PKCS9 PKCS, 0x09
+#define PKCS12 PKCS, 0x0c
+
+/* Other OID name spaces */
+#define ALGORITHM 0x2b, 0x0e, 0x03, 0x02
+#define X500 0x55
+#define X520_ATTRIBUTE_TYPE X500, 0x04
+#define X500_ALG X500, 0x08
+#define X500_ALG_ENCRYPTION X500_ALG, 0x01
+
+/** X.509 v3 Extension OID
+ ** {joint-iso-ccitt (2) ds(5) 29}
+ **/
+#define ID_CE_OID X500, 0x1d
+
+#define RFC1274_ATTR_TYPE 0x09, 0x92, 0x26, 0x89, 0x93, 0xf2, 0x2c, 0x64, 0x1
+/* #define RFC2247_ATTR_TYPE 0x09, 0x92, 0x26, 0xf5, 0x98, 0x1e, 0x64, 0x1 this is WRONG! */
+
+/* PKCS #12 name spaces */
+#define PKCS12_MODE_IDS PKCS12, 0x01
+#define PKCS12_ESPVK_IDS PKCS12, 0x02
+#define PKCS12_BAG_IDS PKCS12, 0x03
+#define PKCS12_CERT_BAG_IDS PKCS12, 0x04
+#define PKCS12_OIDS PKCS12, 0x05
+#define PKCS12_PBE_IDS PKCS12_OIDS, 0x01
+#define PKCS12_ENVELOPING_IDS PKCS12_OIDS, 0x02
+#define PKCS12_SIGNATURE_IDS PKCS12_OIDS, 0x03
+#define PKCS12_V2_PBE_IDS PKCS12, 0x01
+#define PKCS9_CERT_TYPES PKCS9, 0x16
+#define PKCS9_CRL_TYPES PKCS9, 0x17
+#define PKCS9_SMIME_IDS PKCS9, 0x10
+#define PKCS9_SMIME_ATTRS PKCS9_SMIME_IDS, 2
+#define PKCS9_SMIME_ALGS PKCS9_SMIME_IDS, 3
+#define PKCS12_VERSION1 PKCS12, 0x0a
+#define PKCS12_V1_BAG_IDS PKCS12_VERSION1, 1
+
+/* for DSA algorithm */
+/* { iso(1) member-body(2) us(840) x9-57(10040) x9algorithm(4) } */
+#define ANSI_X9_ALGORITHM 0x2a, 0x86, 0x48, 0xce, 0x38, 0x4
+
+/* for DH algorithm */
+/* { iso(1) member-body(2) us(840) x9-57(10046) number-type(2) } */
+/* need real OID person to look at this, copied the above line
+ * and added 6 to second to last value (and changed '4' to '2' */
+#define ANSI_X942_ALGORITHM 0x2a, 0x86, 0x48, 0xce, 0x3e, 0x2
+
+#define VERISIGN 0x60, 0x86, 0x48, 0x01, 0x86, 0xf8, 0x45
+
+#define PKIX 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07
+#define PKIX_CERT_EXTENSIONS PKIX, 1
+#define PKIX_POLICY_QUALIFIERS PKIX, 2
+#define PKIX_KEY_USAGE PKIX, 3
+#define PKIX_ACCESS_DESCRIPTION PKIX, 0x30
+#define PKIX_OCSP PKIX_ACCESS_DESCRIPTION, 1
+#define PKIX_CA_ISSUERS PKIX_ACCESS_DESCRIPTION, 2
+
+#define PKIX_ID_PKIP PKIX, 5
+#define PKIX_ID_REGCTRL PKIX_ID_PKIP, 1
+#define PKIX_ID_REGINFO PKIX_ID_PKIP, 2
+
+/* Microsoft Object ID space */
+/* { 1.3.6.1.4.1.311 } */
+#define MICROSOFT_OID 0x2b, 0x6, 0x1, 0x4, 0x1, 0x82, 0x37
+#define EV_NAME_ATTRIBUTE MICROSOFT_OID, 60, 2, 1
+
+/* Microsoft Crypto 2.0 ID space */
+/* { 1.3.6.1.4.1.311.10 } */
+#define MS_CRYPTO_20 MICROSOFT_OID, 10
+/* Microsoft Crypto 2.0 Extended Key Usage ID space */
+/* { 1.3.6.1.4.1.311.10.3 } */
+#define MS_CRYPTO_EKU MS_CRYPTO_20, 3
+
+#define CERTICOM_OID 0x2b, 0x81, 0x04
+#define SECG_OID CERTICOM_OID, 0x00
+
+#define ANSI_X962_OID 0x2a, 0x86, 0x48, 0xce, 0x3d
+#define ANSI_X962_CURVE_OID ANSI_X962_OID, 0x03
+#define ANSI_X962_GF2m_OID ANSI_X962_CURVE_OID, 0x00
+#define ANSI_X962_GFp_OID ANSI_X962_CURVE_OID, 0x01
+#define ANSI_X962_SIGNATURE_OID ANSI_X962_OID, 0x04
+#define ANSI_X962_SPECIFY_OID ANSI_X962_SIGNATURE_OID, 0x03
+
+/* for Camellia: iso(1) member-body(2) jisc(392)
+ * mitsubishi(200011) isl(61) security(1) algorithm(1)
+ */
+#define MITSUBISHI_ALG 0x2a,0x83,0x08,0x8c,0x9a,0x4b,0x3d,0x01,0x01
+#define CAMELLIA_ENCRYPT_OID MITSUBISHI_ALG,1
+#define CAMELLIA_WRAP_OID MITSUBISHI_ALG,3
+
+/* for SEED : iso(1) member-body(2) korea(410)
+ * kisa(200004) algorithm(1)
+ */
+#define SEED_OID 0x2a,0x83,0x1a,0x8c,0x9a,0x44,0x01
+
+#define CONST_OID static const unsigned char
+
+CONST_OID md2[] = { DIGEST, 0x02 };
+CONST_OID md4[] = { DIGEST, 0x04 };
+CONST_OID md5[] = { DIGEST, 0x05 };
+CONST_OID hmac_sha1[] = { DIGEST, 7 };
+CONST_OID hmac_sha224[] = { DIGEST, 8 };
+CONST_OID hmac_sha256[] = { DIGEST, 9 };
+CONST_OID hmac_sha384[] = { DIGEST, 10 };
+CONST_OID hmac_sha512[] = { DIGEST, 11 };
+
+CONST_OID rc2cbc[] = { CIPHER, 0x02 };
+CONST_OID rc4[] = { CIPHER, 0x04 };
+CONST_OID desede3cbc[] = { CIPHER, 0x07 };
+CONST_OID rc5cbcpad[] = { CIPHER, 0x09 };
+
+CONST_OID desecb[] = { ALGORITHM, 0x06 };
+CONST_OID descbc[] = { ALGORITHM, 0x07 };
+CONST_OID desofb[] = { ALGORITHM, 0x08 };
+CONST_OID descfb[] = { ALGORITHM, 0x09 };
+CONST_OID desmac[] = { ALGORITHM, 0x0a };
+CONST_OID sdn702DSASignature[] = { ALGORITHM, 0x0c };
+CONST_OID isoSHAWithRSASignature[] = { ALGORITHM, 0x0f };
+CONST_OID desede[] = { ALGORITHM, 0x11 };
+CONST_OID sha1[] = { ALGORITHM, 0x1a };
+CONST_OID bogusDSASignaturewithSHA1Digest[] = { ALGORITHM, 0x1b };
+CONST_OID isoSHA1WithRSASignature[] = { ALGORITHM, 0x1d };
+
+CONST_OID pkcs1RSAEncryption[] = { PKCS1, 0x01 };
+CONST_OID pkcs1MD2WithRSAEncryption[] = { PKCS1, 0x02 };
+CONST_OID pkcs1MD4WithRSAEncryption[] = { PKCS1, 0x03 };
+CONST_OID pkcs1MD5WithRSAEncryption[] = { PKCS1, 0x04 };
+CONST_OID pkcs1SHA1WithRSAEncryption[] = { PKCS1, 0x05 };
+CONST_OID pkcs1RSAOAEPEncryption[] = { PKCS1, 0x07 };
+CONST_OID pkcs1MGF1[] = { PKCS1, 0x08 };
+CONST_OID pkcs1PSpecified[] = { PKCS1, 0x09 };
+CONST_OID pkcs1RSAPSSSignature[] = { PKCS1, 10 };
+CONST_OID pkcs1SHA256WithRSAEncryption[] = { PKCS1, 11 };
+CONST_OID pkcs1SHA384WithRSAEncryption[] = { PKCS1, 12 };
+CONST_OID pkcs1SHA512WithRSAEncryption[] = { PKCS1, 13 };
+CONST_OID pkcs1SHA224WithRSAEncryption[] = { PKCS1, 14 };
+
+CONST_OID pkcs5PbeWithMD2AndDEScbc[] = { PKCS5, 0x01 };
+CONST_OID pkcs5PbeWithMD5AndDEScbc[] = { PKCS5, 0x03 };
+CONST_OID pkcs5PbeWithSha1AndDEScbc[] = { PKCS5, 0x0a };
+CONST_OID pkcs5Pbkdf2[] = { PKCS5, 12 };
+CONST_OID pkcs5Pbes2[] = { PKCS5, 13 };
+CONST_OID pkcs5Pbmac1[] = { PKCS5, 14 };
+
+CONST_OID pkcs7[] = { PKCS7 };
+CONST_OID pkcs7Data[] = { PKCS7, 0x01 };
+CONST_OID pkcs7SignedData[] = { PKCS7, 0x02 };
+CONST_OID pkcs7EnvelopedData[] = { PKCS7, 0x03 };
+CONST_OID pkcs7SignedEnvelopedData[] = { PKCS7, 0x04 };
+CONST_OID pkcs7DigestedData[] = { PKCS7, 0x05 };
+CONST_OID pkcs7EncryptedData[] = { PKCS7, 0x06 };
+
+CONST_OID pkcs9EmailAddress[] = { PKCS9, 0x01 };
+CONST_OID pkcs9UnstructuredName[] = { PKCS9, 0x02 };
+CONST_OID pkcs9ContentType[] = { PKCS9, 0x03 };
+CONST_OID pkcs9MessageDigest[] = { PKCS9, 0x04 };
+CONST_OID pkcs9SigningTime[] = { PKCS9, 0x05 };
+CONST_OID pkcs9CounterSignature[] = { PKCS9, 0x06 };
+CONST_OID pkcs9ChallengePassword[] = { PKCS9, 0x07 };
+CONST_OID pkcs9UnstructuredAddress[] = { PKCS9, 0x08 };
+CONST_OID pkcs9ExtendedCertificateAttributes[] = { PKCS9, 0x09 };
+CONST_OID pkcs9ExtensionRequest[] = { PKCS9, 14 };
+CONST_OID pkcs9SMIMECapabilities[] = { PKCS9, 15 };
+CONST_OID pkcs9FriendlyName[] = { PKCS9, 20 };
+CONST_OID pkcs9LocalKeyID[] = { PKCS9, 21 };
+
+CONST_OID pkcs9X509Certificate[] = { PKCS9_CERT_TYPES, 1 };
+CONST_OID pkcs9SDSICertificate[] = { PKCS9_CERT_TYPES, 2 };
+CONST_OID pkcs9X509CRL[] = { PKCS9_CRL_TYPES, 1 };
+
+/* RFC2630 (CMS) OIDs */
+CONST_OID cmsESDH[] = { PKCS9_SMIME_ALGS, 5 };
+CONST_OID cms3DESwrap[] = { PKCS9_SMIME_ALGS, 6 };
+CONST_OID cmsRC2wrap[] = { PKCS9_SMIME_ALGS, 7 };
+
+/* RFC2633 SMIME message attributes */
+CONST_OID smimeEncryptionKeyPreference[] = { PKCS9_SMIME_ATTRS, 11 };
+CONST_OID ms_smimeEncryptionKeyPreference[] = { MICROSOFT_OID, 0x10, 0x4 };
+
+/* RFC2634 SMIME message attributes */
+CONST_OID smimeReceiptRequest[] = { PKCS9_SMIME_ATTRS, 1 };
+CONST_OID smimeReceipt[] = { PKCS9_SMIME_IDS, 1, 1 };
+CONST_OID smimeReceiptMsgSigDigest[] = { PKCS9_SMIME_ATTRS, 5 };
+CONST_OID smimeSecurityLabel[] = { PKCS9_SMIME_ATTRS, 2 };
+/*Signed Headers*/
+CONST_OID smimeSignedHeader[] = {PKCS9_SMIME_ATTRS, 80};
+
+CONST_OID x520CommonName[] = { X520_ATTRIBUTE_TYPE, 3 };
+CONST_OID x520SurName[] = { X520_ATTRIBUTE_TYPE, 4 };
+CONST_OID x520SerialNumber[] = { X520_ATTRIBUTE_TYPE, 5 };
+CONST_OID x520CountryName[] = { X520_ATTRIBUTE_TYPE, 6 };
+CONST_OID x520LocalityName[] = { X520_ATTRIBUTE_TYPE, 7 };
+CONST_OID x520StateOrProvinceName[] = { X520_ATTRIBUTE_TYPE, 8 };
+CONST_OID x520StreetAddress[] = { X520_ATTRIBUTE_TYPE, 9 };
+CONST_OID x520OrgName[] = { X520_ATTRIBUTE_TYPE, 10 };
+CONST_OID x520OrgUnitName[] = { X520_ATTRIBUTE_TYPE, 11 };
+CONST_OID x520Title[] = { X520_ATTRIBUTE_TYPE, 12 };
+CONST_OID x520BusinessCategory[] = { X520_ATTRIBUTE_TYPE, 15 };
+CONST_OID x520PostalAddress[] = { X520_ATTRIBUTE_TYPE, 16 };
+CONST_OID x520PostalCode[] = { X520_ATTRIBUTE_TYPE, 17 };
+CONST_OID x520PostOfficeBox[] = { X520_ATTRIBUTE_TYPE, 18 };
+CONST_OID x520Name[] = { X520_ATTRIBUTE_TYPE, 41 };
+CONST_OID x520GivenName[] = { X520_ATTRIBUTE_TYPE, 42 };
+CONST_OID x520Initials[] = { X520_ATTRIBUTE_TYPE, 43 };
+CONST_OID x520GenerationQualifier[] = { X520_ATTRIBUTE_TYPE, 44 };
+CONST_OID x520DnQualifier[] = { X520_ATTRIBUTE_TYPE, 46 };
+CONST_OID x520HouseIdentifier[] = { X520_ATTRIBUTE_TYPE, 51 };
+CONST_OID x520Pseudonym[] = { X520_ATTRIBUTE_TYPE, 65 };
+
+CONST_OID nsTypeGIF[] = { NETSCAPE_DATA_TYPE, 0x01 };
+CONST_OID nsTypeJPEG[] = { NETSCAPE_DATA_TYPE, 0x02 };
+CONST_OID nsTypeURL[] = { NETSCAPE_DATA_TYPE, 0x03 };
+CONST_OID nsTypeHTML[] = { NETSCAPE_DATA_TYPE, 0x04 };
+CONST_OID nsTypeCertSeq[] = { NETSCAPE_DATA_TYPE, 0x05 };
+
+CONST_OID missiCertKEADSSOld[] = { MISSI_OLD_KEA_DSS };
+CONST_OID missiCertDSSOld[] = { MISSI_OLD_DSS };
+CONST_OID missiCertKEADSS[] = { MISSI_KEA_DSS };
+CONST_OID missiCertDSS[] = { MISSI_DSS };
+CONST_OID missiCertKEA[] = { MISSI_KEA };
+CONST_OID missiCertAltKEA[] = { MISSI_ALT_KEA };
+CONST_OID x500RSAEncryption[] = { X500_ALG_ENCRYPTION, 0x01 };
+
+/* added for alg 1485 */
+CONST_OID rfc1274Uid[] = { RFC1274_ATTR_TYPE, 1 };
+CONST_OID rfc1274Mail[] = { RFC1274_ATTR_TYPE, 3 };
+CONST_OID rfc2247DomainComponent[] = { RFC1274_ATTR_TYPE, 25 };
+
+/* Netscape private certificate extensions */
+CONST_OID nsCertExtNetscapeOK[] = { NS_CERT_EXT, 1 };
+CONST_OID nsCertExtIssuerLogo[] = { NS_CERT_EXT, 2 };
+CONST_OID nsCertExtSubjectLogo[] = { NS_CERT_EXT, 3 };
+CONST_OID nsExtCertType[] = { NETSCAPE_CERT_EXT, 0x01 };
+CONST_OID nsExtBaseURL[] = { NETSCAPE_CERT_EXT, 0x02 };
+CONST_OID nsExtRevocationURL[] = { NETSCAPE_CERT_EXT, 0x03 };
+CONST_OID nsExtCARevocationURL[] = { NETSCAPE_CERT_EXT, 0x04 };
+CONST_OID nsExtCACRLURL[] = { NETSCAPE_CERT_EXT, 0x05 };
+CONST_OID nsExtCACertURL[] = { NETSCAPE_CERT_EXT, 0x06 };
+CONST_OID nsExtCertRenewalURL[] = { NETSCAPE_CERT_EXT, 0x07 };
+CONST_OID nsExtCAPolicyURL[] = { NETSCAPE_CERT_EXT, 0x08 };
+CONST_OID nsExtHomepageURL[] = { NETSCAPE_CERT_EXT, 0x09 };
+CONST_OID nsExtEntityLogo[] = { NETSCAPE_CERT_EXT, 0x0a };
+CONST_OID nsExtUserPicture[] = { NETSCAPE_CERT_EXT, 0x0b };
+CONST_OID nsExtSSLServerName[] = { NETSCAPE_CERT_EXT, 0x0c };
+CONST_OID nsExtComment[] = { NETSCAPE_CERT_EXT, 0x0d };
+
+/* the following 2 extensions are defined for and used by Cartman(NSM) */
+CONST_OID nsExtLostPasswordURL[] = { NETSCAPE_CERT_EXT, 0x0e };
+CONST_OID nsExtCertRenewalTime[] = { NETSCAPE_CERT_EXT, 0x0f };
+
+CONST_OID nsExtAIACertRenewal[] = { NETSCAPE_CERT_EXT_AIA, 0x01 };
+CONST_OID nsExtCertScopeOfUse[] = { NETSCAPE_CERT_EXT, 0x11 };
+/* Reserved Netscape (2 16 840 1 113730 1 18) = { NETSCAPE_CERT_EXT, 0x12 }; */
+
+/* Netscape policy values */
+CONST_OID nsKeyUsageGovtApproved[] = { NETSCAPE_POLICY, 0x01 };
+
+/* Netscape other name types */
+CONST_OID netscapeNickname[] = { NETSCAPE_NAME_COMPONENTS, 0x01 };
+CONST_OID netscapeAOLScreenname[] = { NETSCAPE_NAME_COMPONENTS, 0x02 };
+
+/* OIDs needed for cert server */
+CONST_OID netscapeRecoveryRequest[] = { NETSCAPE_CERT_SERVER_CRMF, 0x01 };
+
+
+/* Standard x.509 v3 Certificate & CRL Extensions */
+CONST_OID x509SubjectDirectoryAttr[] = { ID_CE_OID, 9 };
+CONST_OID x509SubjectKeyID[] = { ID_CE_OID, 14 };
+CONST_OID x509KeyUsage[] = { ID_CE_OID, 15 };
+CONST_OID x509PrivateKeyUsagePeriod[] = { ID_CE_OID, 16 };
+CONST_OID x509SubjectAltName[] = { ID_CE_OID, 17 };
+CONST_OID x509IssuerAltName[] = { ID_CE_OID, 18 };
+CONST_OID x509BasicConstraints[] = { ID_CE_OID, 19 };
+CONST_OID x509CRLNumber[] = { ID_CE_OID, 20 };
+CONST_OID x509ReasonCode[] = { ID_CE_OID, 21 };
+CONST_OID x509HoldInstructionCode[] = { ID_CE_OID, 23 };
+CONST_OID x509InvalidDate[] = { ID_CE_OID, 24 };
+CONST_OID x509DeltaCRLIndicator[] = { ID_CE_OID, 27 };
+CONST_OID x509IssuingDistributionPoint[] = { ID_CE_OID, 28 };
+CONST_OID x509CertIssuer[] = { ID_CE_OID, 29 };
+CONST_OID x509NameConstraints[] = { ID_CE_OID, 30 };
+CONST_OID x509CRLDistPoints[] = { ID_CE_OID, 31 };
+CONST_OID x509CertificatePolicies[] = { ID_CE_OID, 32 };
+CONST_OID x509PolicyMappings[] = { ID_CE_OID, 33 };
+CONST_OID x509AuthKeyID[] = { ID_CE_OID, 35 };
+CONST_OID x509PolicyConstraints[] = { ID_CE_OID, 36 };
+CONST_OID x509ExtKeyUsage[] = { ID_CE_OID, 37 };
+CONST_OID x509FreshestCRL[] = { ID_CE_OID, 46 };
+CONST_OID x509InhibitAnyPolicy[] = { ID_CE_OID, 54 };
+
+CONST_OID x509CertificatePoliciesAnyPolicy[] = { ID_CE_OID, 32, 0 };
+
+CONST_OID x509AuthInfoAccess[] = { PKIX_CERT_EXTENSIONS, 1 };
+CONST_OID x509SubjectInfoAccess[] = { PKIX_CERT_EXTENSIONS, 11 };
+
+CONST_OID x509SIATimeStamping[] = {PKIX_ACCESS_DESCRIPTION, 0x03};
+CONST_OID x509SIACaRepository[] = {PKIX_ACCESS_DESCRIPTION, 0x05};
+
+/* pkcs 12 additions */
+CONST_OID pkcs12[] = { PKCS12 };
+CONST_OID pkcs12ModeIDs[] = { PKCS12_MODE_IDS };
+CONST_OID pkcs12ESPVKIDs[] = { PKCS12_ESPVK_IDS };
+CONST_OID pkcs12BagIDs[] = { PKCS12_BAG_IDS };
+CONST_OID pkcs12CertBagIDs[] = { PKCS12_CERT_BAG_IDS };
+CONST_OID pkcs12OIDs[] = { PKCS12_OIDS };
+CONST_OID pkcs12PBEIDs[] = { PKCS12_PBE_IDS };
+CONST_OID pkcs12EnvelopingIDs[] = { PKCS12_ENVELOPING_IDS };
+CONST_OID pkcs12SignatureIDs[] = { PKCS12_SIGNATURE_IDS };
+CONST_OID pkcs12PKCS8KeyShrouding[] = { PKCS12_ESPVK_IDS, 0x01 };
+CONST_OID pkcs12KeyBagID[] = { PKCS12_BAG_IDS, 0x01 };
+CONST_OID pkcs12CertAndCRLBagID[] = { PKCS12_BAG_IDS, 0x02 };
+CONST_OID pkcs12SecretBagID[] = { PKCS12_BAG_IDS, 0x03 };
+CONST_OID pkcs12X509CertCRLBag[] = { PKCS12_CERT_BAG_IDS, 0x01 };
+CONST_OID pkcs12SDSICertBag[] = { PKCS12_CERT_BAG_IDS, 0x02 };
+CONST_OID pkcs12PBEWithSha1And128BitRC4[] = { PKCS12_PBE_IDS, 0x01 };
+CONST_OID pkcs12PBEWithSha1And40BitRC4[] = { PKCS12_PBE_IDS, 0x02 };
+CONST_OID pkcs12PBEWithSha1AndTripleDESCBC[] = { PKCS12_PBE_IDS, 0x03 };
+CONST_OID pkcs12PBEWithSha1And128BitRC2CBC[] = { PKCS12_PBE_IDS, 0x04 };
+CONST_OID pkcs12PBEWithSha1And40BitRC2CBC[] = { PKCS12_PBE_IDS, 0x05 };
+CONST_OID pkcs12RSAEncryptionWith128BitRC4[] = { PKCS12_ENVELOPING_IDS, 0x01 };
+CONST_OID pkcs12RSAEncryptionWith40BitRC4[] = { PKCS12_ENVELOPING_IDS, 0x02 };
+CONST_OID pkcs12RSAEncryptionWithTripleDES[] = { PKCS12_ENVELOPING_IDS, 0x03 };
+CONST_OID pkcs12RSASignatureWithSHA1Digest[] = { PKCS12_SIGNATURE_IDS, 0x01 };
+
+/* pkcs 12 version 1.0 ids */
+CONST_OID pkcs12V2PBEWithSha1And128BitRC4[] = { PKCS12_V2_PBE_IDS, 0x01 };
+CONST_OID pkcs12V2PBEWithSha1And40BitRC4[] = { PKCS12_V2_PBE_IDS, 0x02 };
+CONST_OID pkcs12V2PBEWithSha1And3KeyTripleDEScbc[]= { PKCS12_V2_PBE_IDS, 0x03 };
+CONST_OID pkcs12V2PBEWithSha1And2KeyTripleDEScbc[]= { PKCS12_V2_PBE_IDS, 0x04 };
+CONST_OID pkcs12V2PBEWithSha1And128BitRC2cbc[] = { PKCS12_V2_PBE_IDS, 0x05 };
+CONST_OID pkcs12V2PBEWithSha1And40BitRC2cbc[] = { PKCS12_V2_PBE_IDS, 0x06 };
+
+CONST_OID pkcs12SafeContentsID[] = { PKCS12_BAG_IDS, 0x04 };
+CONST_OID pkcs12PKCS8ShroudedKeyBagID[] = { PKCS12_BAG_IDS, 0x05 };
+
+CONST_OID pkcs12V1KeyBag[] = { PKCS12_V1_BAG_IDS, 0x01 };
+CONST_OID pkcs12V1PKCS8ShroudedKeyBag[] = { PKCS12_V1_BAG_IDS, 0x02 };
+CONST_OID pkcs12V1CertBag[] = { PKCS12_V1_BAG_IDS, 0x03 };
+CONST_OID pkcs12V1CRLBag[] = { PKCS12_V1_BAG_IDS, 0x04 };
+CONST_OID pkcs12V1SecretBag[] = { PKCS12_V1_BAG_IDS, 0x05 };
+CONST_OID pkcs12V1SafeContentsBag[] = { PKCS12_V1_BAG_IDS, 0x06 };
+
+/* The following encoding is INCORRECT, but correcting it would create a
+ * duplicate OID in the table. So, we will leave it alone.
+ */
+CONST_OID pkcs12KeyUsageAttr[] = { 2, 5, 29, 15 };
+
+CONST_OID ansix9DSASignature[] = { ANSI_X9_ALGORITHM, 0x01 };
+CONST_OID ansix9DSASignaturewithSHA1Digest[] = { ANSI_X9_ALGORITHM, 0x03 };
+CONST_OID nistDSASignaturewithSHA224Digest[] = { DSA2, 0x01 };
+CONST_OID nistDSASignaturewithSHA256Digest[] = { DSA2, 0x02 };
+
+/* verisign OIDs */
+CONST_OID verisignUserNotices[] = { VERISIGN, 1, 7, 1, 1 };
+
+/* pkix OIDs */
+CONST_OID pkixCPSPointerQualifier[] = { PKIX_POLICY_QUALIFIERS, 1 };
+CONST_OID pkixUserNoticeQualifier[] = { PKIX_POLICY_QUALIFIERS, 2 };
+
+CONST_OID pkixOCSP[] = { PKIX_OCSP };
+CONST_OID pkixOCSPBasicResponse[] = { PKIX_OCSP, 1 };
+CONST_OID pkixOCSPNonce[] = { PKIX_OCSP, 2 };
+CONST_OID pkixOCSPCRL[] = { PKIX_OCSP, 3 };
+CONST_OID pkixOCSPResponse[] = { PKIX_OCSP, 4 };
+CONST_OID pkixOCSPNoCheck[] = { PKIX_OCSP, 5 };
+CONST_OID pkixOCSPArchiveCutoff[] = { PKIX_OCSP, 6 };
+CONST_OID pkixOCSPServiceLocator[] = { PKIX_OCSP, 7 };
+
+CONST_OID pkixCAIssuers[] = { PKIX_CA_ISSUERS };
+
+CONST_OID pkixRegCtrlRegToken[] = { PKIX_ID_REGCTRL, 1};
+CONST_OID pkixRegCtrlAuthenticator[] = { PKIX_ID_REGCTRL, 2};
+CONST_OID pkixRegCtrlPKIPubInfo[] = { PKIX_ID_REGCTRL, 3};
+CONST_OID pkixRegCtrlPKIArchOptions[] = { PKIX_ID_REGCTRL, 4};
+CONST_OID pkixRegCtrlOldCertID[] = { PKIX_ID_REGCTRL, 5};
+CONST_OID pkixRegCtrlProtEncKey[] = { PKIX_ID_REGCTRL, 6};
+CONST_OID pkixRegInfoUTF8Pairs[] = { PKIX_ID_REGINFO, 1};
+CONST_OID pkixRegInfoCertReq[] = { PKIX_ID_REGINFO, 2};
+
+CONST_OID pkixExtendedKeyUsageServerAuth[] = { PKIX_KEY_USAGE, 1 };
+CONST_OID pkixExtendedKeyUsageClientAuth[] = { PKIX_KEY_USAGE, 2 };
+CONST_OID pkixExtendedKeyUsageCodeSign[] = { PKIX_KEY_USAGE, 3 };
+CONST_OID pkixExtendedKeyUsageEMailProtect[] = { PKIX_KEY_USAGE, 4 };
+CONST_OID pkixExtendedKeyUsageTimeStamp[] = { PKIX_KEY_USAGE, 8 };
+CONST_OID pkixOCSPResponderExtendedKeyUsage[] = { PKIX_KEY_USAGE, 9 };
+CONST_OID msExtendedKeyUsageTrustListSigning[] = { MS_CRYPTO_EKU, 1 };
+
+/* OIDs for Netscape defined algorithms */
+CONST_OID netscapeSMimeKEA[] = { NETSCAPE_ALGS, 0x01 };
+
+/* Fortezza algorithm OIDs */
+CONST_OID skipjackCBC[] = { MISSI, 0x04 };
+CONST_OID dhPublicKey[] = { ANSI_X942_ALGORITHM, 0x1 };
+
+CONST_OID aes128_ECB[] = { AES, 1 };
+CONST_OID aes128_CBC[] = { AES, 2 };
+#ifdef DEFINE_ALL_AES_CIPHERS
+CONST_OID aes128_OFB[] = { AES, 3 };
+CONST_OID aes128_CFB[] = { AES, 4 };
+#endif
+CONST_OID aes128_KEY_WRAP[] = { AES, 5 };
+
+CONST_OID aes192_ECB[] = { AES, 21 };
+CONST_OID aes192_CBC[] = { AES, 22 };
+#ifdef DEFINE_ALL_AES_CIPHERS
+CONST_OID aes192_OFB[] = { AES, 23 };
+CONST_OID aes192_CFB[] = { AES, 24 };
+#endif
+CONST_OID aes192_KEY_WRAP[] = { AES, 25 };
+
+CONST_OID aes256_ECB[] = { AES, 41 };
+CONST_OID aes256_CBC[] = { AES, 42 };
+#ifdef DEFINE_ALL_AES_CIPHERS
+CONST_OID aes256_OFB[] = { AES, 43 };
+CONST_OID aes256_CFB[] = { AES, 44 };
+#endif
+CONST_OID aes256_KEY_WRAP[] = { AES, 45 };
+
+CONST_OID camellia128_CBC[] = { CAMELLIA_ENCRYPT_OID, 2};
+CONST_OID camellia192_CBC[] = { CAMELLIA_ENCRYPT_OID, 3};
+CONST_OID camellia256_CBC[] = { CAMELLIA_ENCRYPT_OID, 4};
+CONST_OID camellia128_KEY_WRAP[] = { CAMELLIA_WRAP_OID, 2};
+CONST_OID camellia192_KEY_WRAP[] = { CAMELLIA_WRAP_OID, 3};
+CONST_OID camellia256_KEY_WRAP[] = { CAMELLIA_WRAP_OID, 4};
+
+CONST_OID sha256[] = { SHAXXX, 1 };
+CONST_OID sha384[] = { SHAXXX, 2 };
+CONST_OID sha512[] = { SHAXXX, 3 };
+CONST_OID sha224[] = { SHAXXX, 4 };
+
+CONST_OID ansix962ECPublicKey[] = { ANSI_X962_OID, 0x02, 0x01 };
+CONST_OID ansix962SignaturewithSHA1Digest[] = { ANSI_X962_SIGNATURE_OID, 0x01 };
+CONST_OID ansix962SignatureRecommended[] = { ANSI_X962_SIGNATURE_OID, 0x02 };
+CONST_OID ansix962SignatureSpecified[] = { ANSI_X962_SPECIFY_OID };
+CONST_OID ansix962SignaturewithSHA224Digest[] = { ANSI_X962_SPECIFY_OID, 0x01 };
+CONST_OID ansix962SignaturewithSHA256Digest[] = { ANSI_X962_SPECIFY_OID, 0x02 };
+CONST_OID ansix962SignaturewithSHA384Digest[] = { ANSI_X962_SPECIFY_OID, 0x03 };
+CONST_OID ansix962SignaturewithSHA512Digest[] = { ANSI_X962_SPECIFY_OID, 0x04 };
+
+/* ANSI X9.62 prime curve OIDs */
+/* NOTE: prime192v1 is the same as secp192r1, prime256v1 is the
+ * same as secp256r1
+ */
+CONST_OID ansiX962prime192v1[] = { ANSI_X962_GFp_OID, 0x01 };
+CONST_OID ansiX962prime192v2[] = { ANSI_X962_GFp_OID, 0x02 };
+CONST_OID ansiX962prime192v3[] = { ANSI_X962_GFp_OID, 0x03 };
+CONST_OID ansiX962prime239v1[] = { ANSI_X962_GFp_OID, 0x04 };
+CONST_OID ansiX962prime239v2[] = { ANSI_X962_GFp_OID, 0x05 };
+CONST_OID ansiX962prime239v3[] = { ANSI_X962_GFp_OID, 0x06 };
+CONST_OID ansiX962prime256v1[] = { ANSI_X962_GFp_OID, 0x07 };
+
+/* SECG prime curve OIDs */
+CONST_OID secgECsecp112r1[] = { SECG_OID, 0x06 };
+CONST_OID secgECsecp112r2[] = { SECG_OID, 0x07 };
+CONST_OID secgECsecp128r1[] = { SECG_OID, 0x1c };
+CONST_OID secgECsecp128r2[] = { SECG_OID, 0x1d };
+CONST_OID secgECsecp160k1[] = { SECG_OID, 0x09 };
+CONST_OID secgECsecp160r1[] = { SECG_OID, 0x08 };
+CONST_OID secgECsecp160r2[] = { SECG_OID, 0x1e };
+CONST_OID secgECsecp192k1[] = { SECG_OID, 0x1f };
+CONST_OID secgECsecp224k1[] = { SECG_OID, 0x20 };
+CONST_OID secgECsecp224r1[] = { SECG_OID, 0x21 };
+CONST_OID secgECsecp256k1[] = { SECG_OID, 0x0a };
+CONST_OID secgECsecp384r1[] = { SECG_OID, 0x22 };
+CONST_OID secgECsecp521r1[] = { SECG_OID, 0x23 };
+
+/* ANSI X9.62 characteristic two curve OIDs */
+CONST_OID ansiX962c2pnb163v1[] = { ANSI_X962_GF2m_OID, 0x01 };
+CONST_OID ansiX962c2pnb163v2[] = { ANSI_X962_GF2m_OID, 0x02 };
+CONST_OID ansiX962c2pnb163v3[] = { ANSI_X962_GF2m_OID, 0x03 };
+CONST_OID ansiX962c2pnb176v1[] = { ANSI_X962_GF2m_OID, 0x04 };
+CONST_OID ansiX962c2tnb191v1[] = { ANSI_X962_GF2m_OID, 0x05 };
+CONST_OID ansiX962c2tnb191v2[] = { ANSI_X962_GF2m_OID, 0x06 };
+CONST_OID ansiX962c2tnb191v3[] = { ANSI_X962_GF2m_OID, 0x07 };
+CONST_OID ansiX962c2onb191v4[] = { ANSI_X962_GF2m_OID, 0x08 };
+CONST_OID ansiX962c2onb191v5[] = { ANSI_X962_GF2m_OID, 0x09 };
+CONST_OID ansiX962c2pnb208w1[] = { ANSI_X962_GF2m_OID, 0x0a };
+CONST_OID ansiX962c2tnb239v1[] = { ANSI_X962_GF2m_OID, 0x0b };
+CONST_OID ansiX962c2tnb239v2[] = { ANSI_X962_GF2m_OID, 0x0c };
+CONST_OID ansiX962c2tnb239v3[] = { ANSI_X962_GF2m_OID, 0x0d };
+CONST_OID ansiX962c2onb239v4[] = { ANSI_X962_GF2m_OID, 0x0e };
+CONST_OID ansiX962c2onb239v5[] = { ANSI_X962_GF2m_OID, 0x0f };
+CONST_OID ansiX962c2pnb272w1[] = { ANSI_X962_GF2m_OID, 0x10 };
+CONST_OID ansiX962c2pnb304w1[] = { ANSI_X962_GF2m_OID, 0x11 };
+CONST_OID ansiX962c2tnb359v1[] = { ANSI_X962_GF2m_OID, 0x12 };
+CONST_OID ansiX962c2pnb368w1[] = { ANSI_X962_GF2m_OID, 0x13 };
+CONST_OID ansiX962c2tnb431r1[] = { ANSI_X962_GF2m_OID, 0x14 };
+
+/* SECG characterisitic two curve OIDs */
+CONST_OID secgECsect113r1[] = {SECG_OID, 0x04 };
+CONST_OID secgECsect113r2[] = {SECG_OID, 0x05 };
+CONST_OID secgECsect131r1[] = {SECG_OID, 0x16 };
+CONST_OID secgECsect131r2[] = {SECG_OID, 0x17 };
+CONST_OID secgECsect163k1[] = {SECG_OID, 0x01 };
+CONST_OID secgECsect163r1[] = {SECG_OID, 0x02 };
+CONST_OID secgECsect163r2[] = {SECG_OID, 0x0f };
+CONST_OID secgECsect193r1[] = {SECG_OID, 0x18 };
+CONST_OID secgECsect193r2[] = {SECG_OID, 0x19 };
+CONST_OID secgECsect233k1[] = {SECG_OID, 0x1a };
+CONST_OID secgECsect233r1[] = {SECG_OID, 0x1b };
+CONST_OID secgECsect239k1[] = {SECG_OID, 0x03 };
+CONST_OID secgECsect283k1[] = {SECG_OID, 0x10 };
+CONST_OID secgECsect283r1[] = {SECG_OID, 0x11 };
+CONST_OID secgECsect409k1[] = {SECG_OID, 0x24 };
+CONST_OID secgECsect409r1[] = {SECG_OID, 0x25 };
+CONST_OID secgECsect571k1[] = {SECG_OID, 0x26 };
+CONST_OID secgECsect571r1[] = {SECG_OID, 0x27 };
+
+CONST_OID seed_CBC[] = { SEED_OID, 4 };
+
+CONST_OID evIncorporationLocality[] = { EV_NAME_ATTRIBUTE, 1 };
+CONST_OID evIncorporationState[] = { EV_NAME_ATTRIBUTE, 2 };
+CONST_OID evIncorporationCountry[] = { EV_NAME_ATTRIBUTE, 3 };
+
+#define OI(x) { siDEROID, (unsigned char *)x, sizeof x }
+#ifndef SECOID_NO_STRINGS
+#define OD(oid,tag,desc,mech,ext) { OI(oid), tag, desc, mech, ext }
+#else
+#define OD(oid,tag,desc,mech,ext) { OI(oid), tag, 0, mech, ext }
+#endif
+
+#if defined(NSS_ALLOW_UNSUPPORTED_CRITICAL)
+#define FAKE_SUPPORTED_CERT_EXTENSION SUPPORTED_CERT_EXTENSION
+#else
+#define FAKE_SUPPORTED_CERT_EXTENSION UNSUPPORTED_CERT_EXTENSION
+#endif
+
+/*
+ * NOTE: the order of these entries must mach the SECOidTag enum in secoidt.h!
+ */
+const static SECOidData oids[SEC_OID_TOTAL] = {
+ { { siDEROID, NULL, 0 }, SEC_OID_UNKNOWN,
+ "Unknown OID", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION },
+ OD( md2, SEC_OID_MD2, "MD2", CKM_MD2, INVALID_CERT_EXTENSION ),
+ OD( md4, SEC_OID_MD4,
+ "MD4", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( md5, SEC_OID_MD5, "MD5", CKM_MD5, INVALID_CERT_EXTENSION ),
+ OD( sha1, SEC_OID_SHA1, "SHA-1", CKM_SHA_1, INVALID_CERT_EXTENSION ),
+ OD( rc2cbc, SEC_OID_RC2_CBC,
+ "RC2-CBC", CKM_RC2_CBC, INVALID_CERT_EXTENSION ),
+ OD( rc4, SEC_OID_RC4, "RC4", CKM_RC4, INVALID_CERT_EXTENSION ),
+ OD( desede3cbc, SEC_OID_DES_EDE3_CBC,
+ "DES-EDE3-CBC", CKM_DES3_CBC, INVALID_CERT_EXTENSION ),
+ OD( rc5cbcpad, SEC_OID_RC5_CBC_PAD,
+ "RC5-CBCPad", CKM_RC5_CBC, INVALID_CERT_EXTENSION ),
+ OD( desecb, SEC_OID_DES_ECB,
+ "DES-ECB", CKM_DES_ECB, INVALID_CERT_EXTENSION ),
+ OD( descbc, SEC_OID_DES_CBC,
+ "DES-CBC", CKM_DES_CBC, INVALID_CERT_EXTENSION ),
+ OD( desofb, SEC_OID_DES_OFB,
+ "DES-OFB", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( descfb, SEC_OID_DES_CFB,
+ "DES-CFB", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( desmac, SEC_OID_DES_MAC,
+ "DES-MAC", CKM_DES_MAC, INVALID_CERT_EXTENSION ),
+ OD( desede, SEC_OID_DES_EDE,
+ "DES-EDE", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( isoSHAWithRSASignature, SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE,
+ "ISO SHA with RSA Signature",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs1RSAEncryption, SEC_OID_PKCS1_RSA_ENCRYPTION,
+ "PKCS #1 RSA Encryption", CKM_RSA_PKCS, INVALID_CERT_EXTENSION ),
+
+ /* the following Signing mechanisms should get new CKM_ values when
+ * values for CKM_RSA_WITH_MDX and CKM_RSA_WITH_SHA_1 get defined in
+ * PKCS #11.
+ */
+ OD( pkcs1MD2WithRSAEncryption, SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION,
+ "PKCS #1 MD2 With RSA Encryption", CKM_MD2_RSA_PKCS,
+ INVALID_CERT_EXTENSION ),
+ OD( pkcs1MD4WithRSAEncryption, SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION,
+ "PKCS #1 MD4 With RSA Encryption",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs1MD5WithRSAEncryption, SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION,
+ "PKCS #1 MD5 With RSA Encryption", CKM_MD5_RSA_PKCS,
+ INVALID_CERT_EXTENSION ),
+ OD( pkcs1SHA1WithRSAEncryption, SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION,
+ "PKCS #1 SHA-1 With RSA Encryption", CKM_SHA1_RSA_PKCS,
+ INVALID_CERT_EXTENSION ),
+
+ OD( pkcs5PbeWithMD2AndDEScbc, SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC,
+ "PKCS #5 Password Based Encryption with MD2 and DES-CBC",
+ CKM_PBE_MD2_DES_CBC, INVALID_CERT_EXTENSION ),
+ OD( pkcs5PbeWithMD5AndDEScbc, SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC,
+ "PKCS #5 Password Based Encryption with MD5 and DES-CBC",
+ CKM_PBE_MD5_DES_CBC, INVALID_CERT_EXTENSION ),
+ OD( pkcs5PbeWithSha1AndDEScbc, SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC,
+ "PKCS #5 Password Based Encryption with SHA-1 and DES-CBC",
+ CKM_NETSCAPE_PBE_SHA1_DES_CBC, INVALID_CERT_EXTENSION ),
+ OD( pkcs7, SEC_OID_PKCS7,
+ "PKCS #7", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs7Data, SEC_OID_PKCS7_DATA,
+ "PKCS #7 Data", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs7SignedData, SEC_OID_PKCS7_SIGNED_DATA,
+ "PKCS #7 Signed Data", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs7EnvelopedData, SEC_OID_PKCS7_ENVELOPED_DATA,
+ "PKCS #7 Enveloped Data",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs7SignedEnvelopedData, SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA,
+ "PKCS #7 Signed And Enveloped Data",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs7DigestedData, SEC_OID_PKCS7_DIGESTED_DATA,
+ "PKCS #7 Digested Data",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs7EncryptedData, SEC_OID_PKCS7_ENCRYPTED_DATA,
+ "PKCS #7 Encrypted Data",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9EmailAddress, SEC_OID_PKCS9_EMAIL_ADDRESS,
+ "PKCS #9 Email Address",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9UnstructuredName, SEC_OID_PKCS9_UNSTRUCTURED_NAME,
+ "PKCS #9 Unstructured Name",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9ContentType, SEC_OID_PKCS9_CONTENT_TYPE,
+ "PKCS #9 Content Type",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9MessageDigest, SEC_OID_PKCS9_MESSAGE_DIGEST,
+ "PKCS #9 Message Digest",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9SigningTime, SEC_OID_PKCS9_SIGNING_TIME,
+ "PKCS #9 Signing Time",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9CounterSignature, SEC_OID_PKCS9_COUNTER_SIGNATURE,
+ "PKCS #9 Counter Signature",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9ChallengePassword, SEC_OID_PKCS9_CHALLENGE_PASSWORD,
+ "PKCS #9 Challenge Password",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9UnstructuredAddress, SEC_OID_PKCS9_UNSTRUCTURED_ADDRESS,
+ "PKCS #9 Unstructured Address",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9ExtendedCertificateAttributes,
+ SEC_OID_PKCS9_EXTENDED_CERTIFICATE_ATTRIBUTES,
+ "PKCS #9 Extended Certificate Attributes",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9SMIMECapabilities, SEC_OID_PKCS9_SMIME_CAPABILITIES,
+ "PKCS #9 S/MIME Capabilities",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520CommonName, SEC_OID_AVA_COMMON_NAME,
+ "X520 Common Name", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520CountryName, SEC_OID_AVA_COUNTRY_NAME,
+ "X520 Country Name", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520LocalityName, SEC_OID_AVA_LOCALITY,
+ "X520 Locality Name", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520StateOrProvinceName, SEC_OID_AVA_STATE_OR_PROVINCE,
+ "X520 State Or Province Name",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520OrgName, SEC_OID_AVA_ORGANIZATION_NAME,
+ "X520 Organization Name",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520OrgUnitName, SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME,
+ "X520 Organizational Unit Name",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520DnQualifier, SEC_OID_AVA_DN_QUALIFIER,
+ "X520 DN Qualifier", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( rfc2247DomainComponent, SEC_OID_AVA_DC,
+ "RFC 2247 Domain Component",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ OD( nsTypeGIF, SEC_OID_NS_TYPE_GIF,
+ "GIF", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( nsTypeJPEG, SEC_OID_NS_TYPE_JPEG,
+ "JPEG", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( nsTypeURL, SEC_OID_NS_TYPE_URL,
+ "URL", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( nsTypeHTML, SEC_OID_NS_TYPE_HTML,
+ "HTML", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( nsTypeCertSeq, SEC_OID_NS_TYPE_CERT_SEQUENCE,
+ "Certificate Sequence",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( missiCertKEADSSOld, SEC_OID_MISSI_KEA_DSS_OLD,
+ "MISSI KEA and DSS Algorithm (Old)",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( missiCertDSSOld, SEC_OID_MISSI_DSS_OLD,
+ "MISSI DSS Algorithm (Old)",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( missiCertKEADSS, SEC_OID_MISSI_KEA_DSS,
+ "MISSI KEA and DSS Algorithm",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( missiCertDSS, SEC_OID_MISSI_DSS,
+ "MISSI DSS Algorithm",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( missiCertKEA, SEC_OID_MISSI_KEA,
+ "MISSI KEA Algorithm",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( missiCertAltKEA, SEC_OID_MISSI_ALT_KEA,
+ "MISSI Alternate KEA Algorithm",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ /* Netscape private extensions */
+ OD( nsCertExtNetscapeOK, SEC_OID_NS_CERT_EXT_NETSCAPE_OK,
+ "Netscape says this cert is OK",
+ CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
+ OD( nsCertExtIssuerLogo, SEC_OID_NS_CERT_EXT_ISSUER_LOGO,
+ "Certificate Issuer Logo",
+ CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
+ OD( nsCertExtSubjectLogo, SEC_OID_NS_CERT_EXT_SUBJECT_LOGO,
+ "Certificate Subject Logo",
+ CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
+ OD( nsExtCertType, SEC_OID_NS_CERT_EXT_CERT_TYPE,
+ "Certificate Type",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( nsExtBaseURL, SEC_OID_NS_CERT_EXT_BASE_URL,
+ "Certificate Extension Base URL",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( nsExtRevocationURL, SEC_OID_NS_CERT_EXT_REVOCATION_URL,
+ "Certificate Revocation URL",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( nsExtCARevocationURL, SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL,
+ "Certificate Authority Revocation URL",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( nsExtCACRLURL, SEC_OID_NS_CERT_EXT_CA_CRL_URL,
+ "Certificate Authority CRL Download URL",
+ CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
+ OD( nsExtCACertURL, SEC_OID_NS_CERT_EXT_CA_CERT_URL,
+ "Certificate Authority Certificate Download URL",
+ CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
+ OD( nsExtCertRenewalURL, SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL,
+ "Certificate Renewal URL",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( nsExtCAPolicyURL, SEC_OID_NS_CERT_EXT_CA_POLICY_URL,
+ "Certificate Authority Policy URL",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( nsExtHomepageURL, SEC_OID_NS_CERT_EXT_HOMEPAGE_URL,
+ "Certificate Homepage URL",
+ CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
+ OD( nsExtEntityLogo, SEC_OID_NS_CERT_EXT_ENTITY_LOGO,
+ "Certificate Entity Logo",
+ CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
+ OD( nsExtUserPicture, SEC_OID_NS_CERT_EXT_USER_PICTURE,
+ "Certificate User Picture",
+ CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
+ OD( nsExtSSLServerName, SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME,
+ "Certificate SSL Server Name",
+ CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
+ OD( nsExtComment, SEC_OID_NS_CERT_EXT_COMMENT,
+ "Certificate Comment",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( nsExtLostPasswordURL, SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL,
+ "Lost Password URL",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( nsExtCertRenewalTime, SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME,
+ "Certificate Renewal Time",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( nsKeyUsageGovtApproved, SEC_OID_NS_KEY_USAGE_GOVT_APPROVED,
+ "Strong Crypto Export Approved",
+ CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
+
+
+ /* x.509 v3 certificate extensions */
+ OD( x509SubjectDirectoryAttr, SEC_OID_X509_SUBJECT_DIRECTORY_ATTR,
+ "Certificate Subject Directory Attributes",
+ CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION),
+ OD( x509SubjectKeyID, SEC_OID_X509_SUBJECT_KEY_ID,
+ "Certificate Subject Key ID",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( x509KeyUsage, SEC_OID_X509_KEY_USAGE,
+ "Certificate Key Usage",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( x509PrivateKeyUsagePeriod, SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD,
+ "Certificate Private Key Usage Period",
+ CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
+ OD( x509SubjectAltName, SEC_OID_X509_SUBJECT_ALT_NAME,
+ "Certificate Subject Alt Name",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( x509IssuerAltName, SEC_OID_X509_ISSUER_ALT_NAME,
+ "Certificate Issuer Alt Name",
+ CKM_INVALID_MECHANISM, FAKE_SUPPORTED_CERT_EXTENSION ),
+ OD( x509BasicConstraints, SEC_OID_X509_BASIC_CONSTRAINTS,
+ "Certificate Basic Constraints",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( x509NameConstraints, SEC_OID_X509_NAME_CONSTRAINTS,
+ "Certificate Name Constraints",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( x509CRLDistPoints, SEC_OID_X509_CRL_DIST_POINTS,
+ "CRL Distribution Points",
+ CKM_INVALID_MECHANISM, FAKE_SUPPORTED_CERT_EXTENSION ),
+ OD( x509CertificatePolicies, SEC_OID_X509_CERTIFICATE_POLICIES,
+ "Certificate Policies",
+ CKM_INVALID_MECHANISM, FAKE_SUPPORTED_CERT_EXTENSION ),
+ OD( x509PolicyMappings, SEC_OID_X509_POLICY_MAPPINGS,
+ "Certificate Policy Mappings",
+ CKM_INVALID_MECHANISM, UNSUPPORTED_CERT_EXTENSION ),
+ OD( x509PolicyConstraints, SEC_OID_X509_POLICY_CONSTRAINTS,
+ "Certificate Policy Constraints",
+ CKM_INVALID_MECHANISM, FAKE_SUPPORTED_CERT_EXTENSION ),
+ OD( x509AuthKeyID, SEC_OID_X509_AUTH_KEY_ID,
+ "Certificate Authority Key Identifier",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( x509ExtKeyUsage, SEC_OID_X509_EXT_KEY_USAGE,
+ "Extended Key Usage",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( x509AuthInfoAccess, SEC_OID_X509_AUTH_INFO_ACCESS,
+ "Authority Information Access",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+
+ /* x.509 v3 CRL extensions */
+ OD( x509CRLNumber, SEC_OID_X509_CRL_NUMBER,
+ "CRL Number", CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( x509ReasonCode, SEC_OID_X509_REASON_CODE,
+ "CRL reason code", CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( x509InvalidDate, SEC_OID_X509_INVALID_DATE,
+ "Invalid Date", CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+
+ OD( x500RSAEncryption, SEC_OID_X500_RSA_ENCRYPTION,
+ "X500 RSA Encryption", CKM_RSA_X_509, INVALID_CERT_EXTENSION ),
+
+ /* added for alg 1485 */
+ OD( rfc1274Uid, SEC_OID_RFC1274_UID,
+ "RFC1274 User Id", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( rfc1274Mail, SEC_OID_RFC1274_MAIL,
+ "RFC1274 E-mail Address",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ /* pkcs 12 additions */
+ OD( pkcs12, SEC_OID_PKCS12,
+ "PKCS #12", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12ModeIDs, SEC_OID_PKCS12_MODE_IDS,
+ "PKCS #12 Mode IDs", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12ESPVKIDs, SEC_OID_PKCS12_ESPVK_IDS,
+ "PKCS #12 ESPVK IDs", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12BagIDs, SEC_OID_PKCS12_BAG_IDS,
+ "PKCS #12 Bag IDs", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12CertBagIDs, SEC_OID_PKCS12_CERT_BAG_IDS,
+ "PKCS #12 Cert Bag IDs",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12OIDs, SEC_OID_PKCS12_OIDS,
+ "PKCS #12 OIDs", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12PBEIDs, SEC_OID_PKCS12_PBE_IDS,
+ "PKCS #12 PBE IDs", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12SignatureIDs, SEC_OID_PKCS12_SIGNATURE_IDS,
+ "PKCS #12 Signature IDs",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12EnvelopingIDs, SEC_OID_PKCS12_ENVELOPING_IDS,
+ "PKCS #12 Enveloping IDs",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12PKCS8KeyShrouding, SEC_OID_PKCS12_PKCS8_KEY_SHROUDING,
+ "PKCS #12 Key Shrouding",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12KeyBagID, SEC_OID_PKCS12_KEY_BAG_ID,
+ "PKCS #12 Key Bag ID",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12CertAndCRLBagID, SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID,
+ "PKCS #12 Cert And CRL Bag ID",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12SecretBagID, SEC_OID_PKCS12_SECRET_BAG_ID,
+ "PKCS #12 Secret Bag ID",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12X509CertCRLBag, SEC_OID_PKCS12_X509_CERT_CRL_BAG,
+ "PKCS #12 X509 Cert CRL Bag",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12SDSICertBag, SEC_OID_PKCS12_SDSI_CERT_BAG,
+ "PKCS #12 SDSI Cert Bag",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12PBEWithSha1And128BitRC4,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4,
+ "PKCS #12 PBE With SHA-1 and 128 Bit RC4",
+ CKM_NETSCAPE_PBE_SHA1_128_BIT_RC4, INVALID_CERT_EXTENSION ),
+ OD( pkcs12PBEWithSha1And40BitRC4,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4,
+ "PKCS #12 PBE With SHA-1 and 40 Bit RC4",
+ CKM_NETSCAPE_PBE_SHA1_40_BIT_RC4, INVALID_CERT_EXTENSION ),
+ OD( pkcs12PBEWithSha1AndTripleDESCBC,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC,
+ "PKCS #12 PBE With SHA-1 and Triple DES-CBC",
+ CKM_NETSCAPE_PBE_SHA1_TRIPLE_DES_CBC, INVALID_CERT_EXTENSION ),
+ OD( pkcs12PBEWithSha1And128BitRC2CBC,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC,
+ "PKCS #12 PBE With SHA-1 and 128 Bit RC2 CBC",
+ CKM_NETSCAPE_PBE_SHA1_128_BIT_RC2_CBC, INVALID_CERT_EXTENSION ),
+ OD( pkcs12PBEWithSha1And40BitRC2CBC,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC,
+ "PKCS #12 PBE With SHA-1 and 40 Bit RC2 CBC",
+ CKM_NETSCAPE_PBE_SHA1_40_BIT_RC2_CBC, INVALID_CERT_EXTENSION ),
+ OD( pkcs12RSAEncryptionWith128BitRC4,
+ SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_128_BIT_RC4,
+ "PKCS #12 RSA Encryption with 128 Bit RC4",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12RSAEncryptionWith40BitRC4,
+ SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_40_BIT_RC4,
+ "PKCS #12 RSA Encryption with 40 Bit RC4",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12RSAEncryptionWithTripleDES,
+ SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_TRIPLE_DES,
+ "PKCS #12 RSA Encryption with Triple DES",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12RSASignatureWithSHA1Digest,
+ SEC_OID_PKCS12_RSA_SIGNATURE_WITH_SHA1_DIGEST,
+ "PKCS #12 RSA Encryption with Triple DES",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ /* DSA signatures */
+ OD( ansix9DSASignature, SEC_OID_ANSIX9_DSA_SIGNATURE,
+ "ANSI X9.57 DSA Signature", CKM_DSA, INVALID_CERT_EXTENSION ),
+ OD( ansix9DSASignaturewithSHA1Digest,
+ SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST,
+ "ANSI X9.57 DSA Signature with SHA-1 Digest",
+ CKM_DSA_SHA1, INVALID_CERT_EXTENSION ),
+ OD( bogusDSASignaturewithSHA1Digest,
+ SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST,
+ "FORTEZZA DSA Signature with SHA-1 Digest",
+ CKM_DSA_SHA1, INVALID_CERT_EXTENSION ),
+
+ /* verisign oids */
+ OD( verisignUserNotices, SEC_OID_VERISIGN_USER_NOTICES,
+ "Verisign User Notices",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ /* pkix oids */
+ OD( pkixCPSPointerQualifier, SEC_OID_PKIX_CPS_POINTER_QUALIFIER,
+ "PKIX CPS Pointer Qualifier",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkixUserNoticeQualifier, SEC_OID_PKIX_USER_NOTICE_QUALIFIER,
+ "PKIX User Notice Qualifier",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ OD( pkixOCSP, SEC_OID_PKIX_OCSP,
+ "PKIX Online Certificate Status Protocol",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkixOCSPBasicResponse, SEC_OID_PKIX_OCSP_BASIC_RESPONSE,
+ "OCSP Basic Response", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkixOCSPNonce, SEC_OID_PKIX_OCSP_NONCE,
+ "OCSP Nonce Extension", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkixOCSPCRL, SEC_OID_PKIX_OCSP_CRL,
+ "OCSP CRL Reference Extension",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkixOCSPResponse, SEC_OID_PKIX_OCSP_RESPONSE,
+ "OCSP Response Types Extension",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkixOCSPNoCheck, SEC_OID_PKIX_OCSP_NO_CHECK,
+ "OCSP No Check Extension",
+ CKM_INVALID_MECHANISM, SUPPORTED_CERT_EXTENSION ),
+ OD( pkixOCSPArchiveCutoff, SEC_OID_PKIX_OCSP_ARCHIVE_CUTOFF,
+ "OCSP Archive Cutoff Extension",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkixOCSPServiceLocator, SEC_OID_PKIX_OCSP_SERVICE_LOCATOR,
+ "OCSP Service Locator Extension",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ OD( pkixRegCtrlRegToken, SEC_OID_PKIX_REGCTRL_REGTOKEN,
+ "PKIX CRMF Registration Control, Registration Token",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkixRegCtrlAuthenticator, SEC_OID_PKIX_REGCTRL_AUTHENTICATOR,
+ "PKIX CRMF Registration Control, Registration Authenticator",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkixRegCtrlPKIPubInfo, SEC_OID_PKIX_REGCTRL_PKIPUBINFO,
+ "PKIX CRMF Registration Control, PKI Publication Info",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ OD( pkixRegCtrlPKIArchOptions,
+ SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS,
+ "PKIX CRMF Registration Control, PKI Archive Options",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ OD( pkixRegCtrlOldCertID, SEC_OID_PKIX_REGCTRL_OLD_CERT_ID,
+ "PKIX CRMF Registration Control, Old Certificate ID",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ OD( pkixRegCtrlProtEncKey, SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY,
+ "PKIX CRMF Registration Control, Protocol Encryption Key",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ OD( pkixRegInfoUTF8Pairs, SEC_OID_PKIX_REGINFO_UTF8_PAIRS,
+ "PKIX CRMF Registration Info, UTF8 Pairs",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ OD( pkixRegInfoCertReq, SEC_OID_PKIX_REGINFO_CERT_REQUEST,
+ "PKIX CRMF Registration Info, Certificate Request",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ OD( pkixExtendedKeyUsageServerAuth,
+ SEC_OID_EXT_KEY_USAGE_SERVER_AUTH,
+ "TLS Web Server Authentication Certificate",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ OD( pkixExtendedKeyUsageClientAuth,
+ SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH,
+ "TLS Web Client Authentication Certificate",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ OD( pkixExtendedKeyUsageCodeSign, SEC_OID_EXT_KEY_USAGE_CODE_SIGN,
+ "Code Signing Certificate",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ OD( pkixExtendedKeyUsageEMailProtect,
+ SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT,
+ "E-Mail Protection Certificate",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ OD( pkixExtendedKeyUsageTimeStamp,
+ SEC_OID_EXT_KEY_USAGE_TIME_STAMP,
+ "Time Stamping Certifcate",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+ OD( pkixOCSPResponderExtendedKeyUsage, SEC_OID_OCSP_RESPONDER,
+ "OCSP Responder Certificate",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION),
+
+ /* Netscape Algorithm OIDs */
+
+ OD( netscapeSMimeKEA, SEC_OID_NETSCAPE_SMIME_KEA,
+ "Netscape S/MIME KEA", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ /* Skipjack OID -- ### mwelch temporary */
+ OD( skipjackCBC, SEC_OID_FORTEZZA_SKIPJACK,
+ "Skipjack CBC64", CKM_SKIPJACK_CBC64, INVALID_CERT_EXTENSION ),
+
+ /* pkcs12 v2 oids */
+ OD( pkcs12V2PBEWithSha1And128BitRC4,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4,
+ "PKCS #12 V2 PBE With SHA-1 And 128 Bit RC4",
+ CKM_PBE_SHA1_RC4_128, INVALID_CERT_EXTENSION ),
+ OD( pkcs12V2PBEWithSha1And40BitRC4,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4,
+ "PKCS #12 V2 PBE With SHA-1 And 40 Bit RC4",
+ CKM_PBE_SHA1_RC4_40, INVALID_CERT_EXTENSION ),
+ OD( pkcs12V2PBEWithSha1And3KeyTripleDEScbc,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC,
+ "PKCS #12 V2 PBE With SHA-1 And 3KEY Triple DES-CBC",
+ CKM_PBE_SHA1_DES3_EDE_CBC, INVALID_CERT_EXTENSION ),
+ OD( pkcs12V2PBEWithSha1And2KeyTripleDEScbc,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC,
+ "PKCS #12 V2 PBE With SHA-1 And 2KEY Triple DES-CBC",
+ CKM_PBE_SHA1_DES2_EDE_CBC, INVALID_CERT_EXTENSION ),
+ OD( pkcs12V2PBEWithSha1And128BitRC2cbc,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC,
+ "PKCS #12 V2 PBE With SHA-1 And 128 Bit RC2 CBC",
+ CKM_PBE_SHA1_RC2_128_CBC, INVALID_CERT_EXTENSION ),
+ OD( pkcs12V2PBEWithSha1And40BitRC2cbc,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC,
+ "PKCS #12 V2 PBE With SHA-1 And 40 Bit RC2 CBC",
+ CKM_PBE_SHA1_RC2_40_CBC, INVALID_CERT_EXTENSION ),
+ OD( pkcs12SafeContentsID, SEC_OID_PKCS12_SAFE_CONTENTS_ID,
+ "PKCS #12 Safe Contents ID",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12PKCS8ShroudedKeyBagID,
+ SEC_OID_PKCS12_PKCS8_SHROUDED_KEY_BAG_ID,
+ "PKCS #12 Safe Contents ID",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12V1KeyBag, SEC_OID_PKCS12_V1_KEY_BAG_ID,
+ "PKCS #12 V1 Key Bag",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12V1PKCS8ShroudedKeyBag,
+ SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID,
+ "PKCS #12 V1 PKCS8 Shrouded Key Bag",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12V1CertBag, SEC_OID_PKCS12_V1_CERT_BAG_ID,
+ "PKCS #12 V1 Cert Bag",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12V1CRLBag, SEC_OID_PKCS12_V1_CRL_BAG_ID,
+ "PKCS #12 V1 CRL Bag",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12V1SecretBag, SEC_OID_PKCS12_V1_SECRET_BAG_ID,
+ "PKCS #12 V1 Secret Bag",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12V1SafeContentsBag, SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID,
+ "PKCS #12 V1 Safe Contents Bag",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ OD( pkcs9X509Certificate, SEC_OID_PKCS9_X509_CERT,
+ "PKCS #9 X509 Certificate",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9SDSICertificate, SEC_OID_PKCS9_SDSI_CERT,
+ "PKCS #9 SDSI Certificate",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9X509CRL, SEC_OID_PKCS9_X509_CRL,
+ "PKCS #9 X509 CRL", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9FriendlyName, SEC_OID_PKCS9_FRIENDLY_NAME,
+ "PKCS #9 Friendly Name",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9LocalKeyID, SEC_OID_PKCS9_LOCAL_KEY_ID,
+ "PKCS #9 Local Key ID",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs12KeyUsageAttr, SEC_OID_BOGUS_KEY_USAGE,
+ "Bogus Key Usage", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( dhPublicKey, SEC_OID_X942_DIFFIE_HELMAN_KEY,
+ "Diffie-Helman Public Key", CKM_DH_PKCS_DERIVE,
+ INVALID_CERT_EXTENSION ),
+ OD( netscapeNickname, SEC_OID_NETSCAPE_NICKNAME,
+ "Netscape Nickname", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ /* Cert Server specific OIDs */
+ OD( netscapeRecoveryRequest, SEC_OID_NETSCAPE_RECOVERY_REQUEST,
+ "Recovery Request OID",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ OD( nsExtAIACertRenewal, SEC_OID_CERT_RENEWAL_LOCATOR,
+ "Certificate Renewal Locator OID", CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+
+ OD( nsExtCertScopeOfUse, SEC_OID_NS_CERT_EXT_SCOPE_OF_USE,
+ "Certificate Scope-of-Use Extension", CKM_INVALID_MECHANISM,
+ SUPPORTED_CERT_EXTENSION ),
+
+ /* CMS stuff */
+ OD( cmsESDH, SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN,
+ "Ephemeral-Static Diffie-Hellman", CKM_INVALID_MECHANISM /* XXX */,
+ INVALID_CERT_EXTENSION ),
+ OD( cms3DESwrap, SEC_OID_CMS_3DES_KEY_WRAP,
+ "CMS Triple DES Key Wrap", CKM_INVALID_MECHANISM /* XXX */,
+ INVALID_CERT_EXTENSION ),
+ OD( cmsRC2wrap, SEC_OID_CMS_RC2_KEY_WRAP,
+ "CMS RC2 Key Wrap", CKM_INVALID_MECHANISM /* XXX */,
+ INVALID_CERT_EXTENSION ),
+ OD( smimeEncryptionKeyPreference, SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE,
+ "S/MIME Encryption Key Preference",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ /* AES algorithm OIDs */
+ OD( aes128_ECB, SEC_OID_AES_128_ECB,
+ "AES-128-ECB", CKM_AES_ECB, INVALID_CERT_EXTENSION ),
+ OD( aes128_CBC, SEC_OID_AES_128_CBC,
+ "AES-128-CBC", CKM_AES_CBC, INVALID_CERT_EXTENSION ),
+ OD( aes192_ECB, SEC_OID_AES_192_ECB,
+ "AES-192-ECB", CKM_AES_ECB, INVALID_CERT_EXTENSION ),
+ OD( aes192_CBC, SEC_OID_AES_192_CBC,
+ "AES-192-CBC", CKM_AES_CBC, INVALID_CERT_EXTENSION ),
+ OD( aes256_ECB, SEC_OID_AES_256_ECB,
+ "AES-256-ECB", CKM_AES_ECB, INVALID_CERT_EXTENSION ),
+ OD( aes256_CBC, SEC_OID_AES_256_CBC,
+ "AES-256-CBC", CKM_AES_CBC, INVALID_CERT_EXTENSION ),
+
+ /* More bogus DSA OIDs */
+ OD( sdn702DSASignature, SEC_OID_SDN702_DSA_SIGNATURE,
+ "SDN.702 DSA Signature", CKM_DSA_SHA1, INVALID_CERT_EXTENSION ),
+
+ OD( ms_smimeEncryptionKeyPreference,
+ SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE,
+ "Microsoft S/MIME Encryption Key Preference",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ OD( sha256, SEC_OID_SHA256, "SHA-256", CKM_SHA256, INVALID_CERT_EXTENSION),
+ OD( sha384, SEC_OID_SHA384, "SHA-384", CKM_SHA384, INVALID_CERT_EXTENSION),
+ OD( sha512, SEC_OID_SHA512, "SHA-512", CKM_SHA512, INVALID_CERT_EXTENSION),
+
+ OD( pkcs1SHA256WithRSAEncryption, SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION,
+ "PKCS #1 SHA-256 With RSA Encryption", CKM_SHA256_RSA_PKCS,
+ INVALID_CERT_EXTENSION ),
+ OD( pkcs1SHA384WithRSAEncryption, SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION,
+ "PKCS #1 SHA-384 With RSA Encryption", CKM_SHA384_RSA_PKCS,
+ INVALID_CERT_EXTENSION ),
+ OD( pkcs1SHA512WithRSAEncryption, SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION,
+ "PKCS #1 SHA-512 With RSA Encryption", CKM_SHA512_RSA_PKCS,
+ INVALID_CERT_EXTENSION ),
+
+ OD( aes128_KEY_WRAP, SEC_OID_AES_128_KEY_WRAP,
+ "AES-128 Key Wrap", CKM_NSS_AES_KEY_WRAP, INVALID_CERT_EXTENSION),
+ OD( aes192_KEY_WRAP, SEC_OID_AES_192_KEY_WRAP,
+ "AES-192 Key Wrap", CKM_NSS_AES_KEY_WRAP, INVALID_CERT_EXTENSION),
+ OD( aes256_KEY_WRAP, SEC_OID_AES_256_KEY_WRAP,
+ "AES-256 Key Wrap", CKM_NSS_AES_KEY_WRAP, INVALID_CERT_EXTENSION),
+
+ /* Elliptic Curve Cryptography (ECC) OIDs */
+ OD( ansix962ECPublicKey, SEC_OID_ANSIX962_EC_PUBLIC_KEY,
+ "X9.62 elliptic curve public key", CKM_ECDH1_DERIVE,
+ INVALID_CERT_EXTENSION ),
+ OD( ansix962SignaturewithSHA1Digest,
+ SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE,
+ "X9.62 ECDSA signature with SHA-1", CKM_ECDSA_SHA1,
+ INVALID_CERT_EXTENSION ),
+
+ /* Named curves */
+
+ /* ANSI X9.62 named elliptic curves (prime field) */
+ OD( ansiX962prime192v1, SEC_OID_ANSIX962_EC_PRIME192V1,
+ "ANSI X9.62 elliptic curve prime192v1 (aka secp192r1, NIST P-192)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962prime192v2, SEC_OID_ANSIX962_EC_PRIME192V2,
+ "ANSI X9.62 elliptic curve prime192v2",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962prime192v3, SEC_OID_ANSIX962_EC_PRIME192V3,
+ "ANSI X9.62 elliptic curve prime192v3",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962prime239v1, SEC_OID_ANSIX962_EC_PRIME239V1,
+ "ANSI X9.62 elliptic curve prime239v1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962prime239v2, SEC_OID_ANSIX962_EC_PRIME239V2,
+ "ANSI X9.62 elliptic curve prime239v2",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962prime239v3, SEC_OID_ANSIX962_EC_PRIME239V3,
+ "ANSI X9.62 elliptic curve prime239v3",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962prime256v1, SEC_OID_ANSIX962_EC_PRIME256V1,
+ "ANSI X9.62 elliptic curve prime256v1 (aka secp256r1, NIST P-256)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+
+ /* SECG named elliptic curves (prime field) */
+ OD( secgECsecp112r1, SEC_OID_SECG_EC_SECP112R1,
+ "SECG elliptic curve secp112r1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsecp112r2, SEC_OID_SECG_EC_SECP112R2,
+ "SECG elliptic curve secp112r2",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsecp128r1, SEC_OID_SECG_EC_SECP128R1,
+ "SECG elliptic curve secp128r1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsecp128r2, SEC_OID_SECG_EC_SECP128R2,
+ "SECG elliptic curve secp128r2",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsecp160k1, SEC_OID_SECG_EC_SECP160K1,
+ "SECG elliptic curve secp160k1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsecp160r1, SEC_OID_SECG_EC_SECP160R1,
+ "SECG elliptic curve secp160r1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsecp160r2, SEC_OID_SECG_EC_SECP160R2,
+ "SECG elliptic curve secp160r2",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsecp192k1, SEC_OID_SECG_EC_SECP192K1,
+ "SECG elliptic curve secp192k1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsecp224k1, SEC_OID_SECG_EC_SECP224K1,
+ "SECG elliptic curve secp224k1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsecp224r1, SEC_OID_SECG_EC_SECP224R1,
+ "SECG elliptic curve secp224r1 (aka NIST P-224)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsecp256k1, SEC_OID_SECG_EC_SECP256K1,
+ "SECG elliptic curve secp256k1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsecp384r1, SEC_OID_SECG_EC_SECP384R1,
+ "SECG elliptic curve secp384r1 (aka NIST P-384)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsecp521r1, SEC_OID_SECG_EC_SECP521R1,
+ "SECG elliptic curve secp521r1 (aka NIST P-521)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+
+ /* ANSI X9.62 named elliptic curves (characteristic two field) */
+ OD( ansiX962c2pnb163v1, SEC_OID_ANSIX962_EC_C2PNB163V1,
+ "ANSI X9.62 elliptic curve c2pnb163v1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2pnb163v2, SEC_OID_ANSIX962_EC_C2PNB163V2,
+ "ANSI X9.62 elliptic curve c2pnb163v2",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2pnb163v3, SEC_OID_ANSIX962_EC_C2PNB163V3,
+ "ANSI X9.62 elliptic curve c2pnb163v3",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2pnb176v1, SEC_OID_ANSIX962_EC_C2PNB176V1,
+ "ANSI X9.62 elliptic curve c2pnb176v1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2tnb191v1, SEC_OID_ANSIX962_EC_C2TNB191V1,
+ "ANSI X9.62 elliptic curve c2tnb191v1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2tnb191v2, SEC_OID_ANSIX962_EC_C2TNB191V2,
+ "ANSI X9.62 elliptic curve c2tnb191v2",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2tnb191v3, SEC_OID_ANSIX962_EC_C2TNB191V3,
+ "ANSI X9.62 elliptic curve c2tnb191v3",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2onb191v4, SEC_OID_ANSIX962_EC_C2ONB191V4,
+ "ANSI X9.62 elliptic curve c2onb191v4",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2onb191v5, SEC_OID_ANSIX962_EC_C2ONB191V5,
+ "ANSI X9.62 elliptic curve c2onb191v5",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2pnb208w1, SEC_OID_ANSIX962_EC_C2PNB208W1,
+ "ANSI X9.62 elliptic curve c2pnb208w1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2tnb239v1, SEC_OID_ANSIX962_EC_C2TNB239V1,
+ "ANSI X9.62 elliptic curve c2tnb239v1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2tnb239v2, SEC_OID_ANSIX962_EC_C2TNB239V2,
+ "ANSI X9.62 elliptic curve c2tnb239v2",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2tnb239v3, SEC_OID_ANSIX962_EC_C2TNB239V3,
+ "ANSI X9.62 elliptic curve c2tnb239v3",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2onb239v4, SEC_OID_ANSIX962_EC_C2ONB239V4,
+ "ANSI X9.62 elliptic curve c2onb239v4",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2onb239v5, SEC_OID_ANSIX962_EC_C2ONB239V5,
+ "ANSI X9.62 elliptic curve c2onb239v5",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2pnb272w1, SEC_OID_ANSIX962_EC_C2PNB272W1,
+ "ANSI X9.62 elliptic curve c2pnb272w1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2pnb304w1, SEC_OID_ANSIX962_EC_C2PNB304W1,
+ "ANSI X9.62 elliptic curve c2pnb304w1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2tnb359v1, SEC_OID_ANSIX962_EC_C2TNB359V1,
+ "ANSI X9.62 elliptic curve c2tnb359v1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2pnb368w1, SEC_OID_ANSIX962_EC_C2PNB368W1,
+ "ANSI X9.62 elliptic curve c2pnb368w1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansiX962c2tnb431r1, SEC_OID_ANSIX962_EC_C2TNB431R1,
+ "ANSI X9.62 elliptic curve c2tnb431r1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+
+ /* SECG named elliptic curves (characterisitic two field) */
+ OD( secgECsect113r1, SEC_OID_SECG_EC_SECT113R1,
+ "SECG elliptic curve sect113r1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect113r2, SEC_OID_SECG_EC_SECT113R2,
+ "SECG elliptic curve sect113r2",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect131r1, SEC_OID_SECG_EC_SECT131R1,
+ "SECG elliptic curve sect131r1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect131r2, SEC_OID_SECG_EC_SECT131R2,
+ "SECG elliptic curve sect131r2",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect163k1, SEC_OID_SECG_EC_SECT163K1,
+ "SECG elliptic curve sect163k1 (aka NIST K-163)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect163r1, SEC_OID_SECG_EC_SECT163R1,
+ "SECG elliptic curve sect163r1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect163r2, SEC_OID_SECG_EC_SECT163R2,
+ "SECG elliptic curve sect163r2 (aka NIST B-163)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect193r1, SEC_OID_SECG_EC_SECT193R1,
+ "SECG elliptic curve sect193r1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect193r2, SEC_OID_SECG_EC_SECT193R2,
+ "SECG elliptic curve sect193r2",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect233k1, SEC_OID_SECG_EC_SECT233K1,
+ "SECG elliptic curve sect233k1 (aka NIST K-233)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect233r1, SEC_OID_SECG_EC_SECT233R1,
+ "SECG elliptic curve sect233r1 (aka NIST B-233)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect239k1, SEC_OID_SECG_EC_SECT239K1,
+ "SECG elliptic curve sect239k1",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect283k1, SEC_OID_SECG_EC_SECT283K1,
+ "SECG elliptic curve sect283k1 (aka NIST K-283)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect283r1, SEC_OID_SECG_EC_SECT283R1,
+ "SECG elliptic curve sect283r1 (aka NIST B-283)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect409k1, SEC_OID_SECG_EC_SECT409K1,
+ "SECG elliptic curve sect409k1 (aka NIST K-409)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect409r1, SEC_OID_SECG_EC_SECT409R1,
+ "SECG elliptic curve sect409r1 (aka NIST B-409)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect571k1, SEC_OID_SECG_EC_SECT571K1,
+ "SECG elliptic curve sect571k1 (aka NIST K-571)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( secgECsect571r1, SEC_OID_SECG_EC_SECT571R1,
+ "SECG elliptic curve sect571r1 (aka NIST B-571)",
+ CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+
+ OD( netscapeAOLScreenname, SEC_OID_NETSCAPE_AOLSCREENNAME,
+ "AOL Screenname", CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+
+ OD( x520SurName, SEC_OID_AVA_SURNAME,
+ "X520 Title", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520SerialNumber, SEC_OID_AVA_SERIAL_NUMBER,
+ "X520 Serial Number", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520StreetAddress, SEC_OID_AVA_STREET_ADDRESS,
+ "X520 Street Address", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520Title, SEC_OID_AVA_TITLE,
+ "X520 Title", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520PostalAddress, SEC_OID_AVA_POSTAL_ADDRESS,
+ "X520 Postal Address", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520PostalCode, SEC_OID_AVA_POSTAL_CODE,
+ "X520 Postal Code", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520PostOfficeBox, SEC_OID_AVA_POST_OFFICE_BOX,
+ "X520 Post Office Box", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520GivenName, SEC_OID_AVA_GIVEN_NAME,
+ "X520 Given Name", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520Initials, SEC_OID_AVA_INITIALS,
+ "X520 Initials", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520GenerationQualifier, SEC_OID_AVA_GENERATION_QUALIFIER,
+ "X520 Generation Qualifier",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520HouseIdentifier, SEC_OID_AVA_HOUSE_IDENTIFIER,
+ "X520 House Identifier",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520Pseudonym, SEC_OID_AVA_PSEUDONYM,
+ "X520 Pseudonym", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ /* More OIDs */
+ OD( pkixCAIssuers, SEC_OID_PKIX_CA_ISSUERS,
+ "PKIX CA issuers access method",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs9ExtensionRequest, SEC_OID_PKCS9_EXTENSION_REQUEST,
+ "PKCS #9 Extension Request",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ /* more ECC Signature Oids */
+ OD( ansix962SignatureRecommended,
+ SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST,
+ "X9.62 ECDSA signature with recommended digest", CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansix962SignatureSpecified,
+ SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST,
+ "X9.62 ECDSA signature with specified digest", CKM_ECDSA,
+ INVALID_CERT_EXTENSION ),
+ OD( ansix962SignaturewithSHA224Digest,
+ SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE,
+ "X9.62 ECDSA signature with SHA224", CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansix962SignaturewithSHA256Digest,
+ SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE,
+ "X9.62 ECDSA signature with SHA256", CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansix962SignaturewithSHA384Digest,
+ SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE,
+ "X9.62 ECDSA signature with SHA384", CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( ansix962SignaturewithSHA512Digest,
+ SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE,
+ "X9.62 ECDSA signature with SHA512", CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+
+ /* More id-ce and id-pe OIDs from RFC 3280 */
+ OD( x509HoldInstructionCode, SEC_OID_X509_HOLD_INSTRUCTION_CODE,
+ "CRL Hold Instruction Code", CKM_INVALID_MECHANISM,
+ UNSUPPORTED_CERT_EXTENSION ),
+ OD( x509DeltaCRLIndicator, SEC_OID_X509_DELTA_CRL_INDICATOR,
+ "Delta CRL Indicator", CKM_INVALID_MECHANISM,
+ FAKE_SUPPORTED_CERT_EXTENSION ),
+ OD( x509IssuingDistributionPoint, SEC_OID_X509_ISSUING_DISTRIBUTION_POINT,
+ "Issuing Distribution Point", CKM_INVALID_MECHANISM,
+ FAKE_SUPPORTED_CERT_EXTENSION ),
+ OD( x509CertIssuer, SEC_OID_X509_CERT_ISSUER,
+ "Certificate Issuer Extension",CKM_INVALID_MECHANISM,
+ FAKE_SUPPORTED_CERT_EXTENSION ),
+ OD( x509FreshestCRL, SEC_OID_X509_FRESHEST_CRL,
+ "Freshest CRL", CKM_INVALID_MECHANISM,
+ UNSUPPORTED_CERT_EXTENSION ),
+ OD( x509InhibitAnyPolicy, SEC_OID_X509_INHIBIT_ANY_POLICY,
+ "Inhibit Any Policy", CKM_INVALID_MECHANISM,
+ FAKE_SUPPORTED_CERT_EXTENSION ),
+ OD( x509SubjectInfoAccess, SEC_OID_X509_SUBJECT_INFO_ACCESS,
+ "Subject Info Access", CKM_INVALID_MECHANISM,
+ UNSUPPORTED_CERT_EXTENSION ),
+
+ /* Camellia algorithm OIDs */
+ OD( camellia128_CBC, SEC_OID_CAMELLIA_128_CBC,
+ "CAMELLIA-128-CBC", CKM_CAMELLIA_CBC, INVALID_CERT_EXTENSION ),
+ OD( camellia192_CBC, SEC_OID_CAMELLIA_192_CBC,
+ "CAMELLIA-192-CBC", CKM_CAMELLIA_CBC, INVALID_CERT_EXTENSION ),
+ OD( camellia256_CBC, SEC_OID_CAMELLIA_256_CBC,
+ "CAMELLIA-256-CBC", CKM_CAMELLIA_CBC, INVALID_CERT_EXTENSION ),
+
+ /* PKCS 5 v2 OIDS */
+ OD( pkcs5Pbkdf2, SEC_OID_PKCS5_PBKDF2,
+ "PKCS #5 Password Based Key Dervive Function v2 ",
+ CKM_PKCS5_PBKD2, INVALID_CERT_EXTENSION ),
+ OD( pkcs5Pbes2, SEC_OID_PKCS5_PBES2,
+ "PKCS #5 Password Based Encryption v2 ",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( pkcs5Pbmac1, SEC_OID_PKCS5_PBMAC1,
+ "PKCS #5 Password Based Authentication v1 ",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( hmac_sha1, SEC_OID_HMAC_SHA1, "HMAC SHA-1",
+ CKM_SHA_1_HMAC, INVALID_CERT_EXTENSION ),
+ OD( hmac_sha224, SEC_OID_HMAC_SHA224, "HMAC SHA-224",
+ CKM_SHA224_HMAC, INVALID_CERT_EXTENSION ),
+ OD( hmac_sha256, SEC_OID_HMAC_SHA256, "HMAC SHA-256",
+ CKM_SHA256_HMAC, INVALID_CERT_EXTENSION ),
+ OD( hmac_sha384, SEC_OID_HMAC_SHA384, "HMAC SHA-384",
+ CKM_SHA384_HMAC, INVALID_CERT_EXTENSION ),
+ OD( hmac_sha512, SEC_OID_HMAC_SHA512, "HMAC SHA-512",
+ CKM_SHA512_HMAC, INVALID_CERT_EXTENSION ),
+
+ /* SIA extension OIDs */
+ OD( x509SIATimeStamping, SEC_OID_PKIX_TIMESTAMPING,
+ "SIA Time Stamping", CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+ OD( x509SIACaRepository, SEC_OID_PKIX_CA_REPOSITORY,
+ "SIA CA Repository", CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+
+ OD( isoSHA1WithRSASignature, SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE,
+ "ISO SHA-1 with RSA Signature",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ /* SEED algorithm OIDs */
+ OD( seed_CBC, SEC_OID_SEED_CBC,
+ "SEED-CBC", CKM_SEED_CBC, INVALID_CERT_EXTENSION),
+
+ OD( x509CertificatePoliciesAnyPolicy, SEC_OID_X509_ANY_POLICY,
+ "Certificate Policies AnyPolicy",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ OD( pkcs1RSAOAEPEncryption, SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION,
+ "PKCS #1 RSA-OAEP Encryption", CKM_RSA_PKCS_OAEP,
+ INVALID_CERT_EXTENSION ),
+
+ OD( pkcs1MGF1, SEC_OID_PKCS1_MGF1,
+ "PKCS #1 MGF1 Mask Generation Function", CKM_INVALID_MECHANISM,
+ INVALID_CERT_EXTENSION ),
+
+ OD( pkcs1PSpecified, SEC_OID_PKCS1_PSPECIFIED,
+ "PKCS #1 RSA-OAEP Explicitly Specified Encoding Parameters",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ OD( pkcs1RSAPSSSignature, SEC_OID_PKCS1_RSA_PSS_SIGNATURE,
+ "PKCS #1 RSA-PSS Signature", CKM_RSA_PKCS_PSS,
+ INVALID_CERT_EXTENSION ),
+
+ OD( pkcs1SHA224WithRSAEncryption, SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION,
+ "PKCS #1 SHA-224 With RSA Encryption", CKM_SHA224_RSA_PKCS,
+ INVALID_CERT_EXTENSION ),
+
+ OD( sha224, SEC_OID_SHA224, "SHA-224", CKM_SHA224, INVALID_CERT_EXTENSION),
+
+ OD( evIncorporationLocality, SEC_OID_EV_INCORPORATION_LOCALITY,
+ "Jurisdiction of Incorporation Locality Name",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( evIncorporationState, SEC_OID_EV_INCORPORATION_STATE,
+ "Jurisdiction of Incorporation State Name",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( evIncorporationCountry, SEC_OID_EV_INCORPORATION_COUNTRY,
+ "Jurisdiction of Incorporation Country Name",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( x520BusinessCategory, SEC_OID_BUSINESS_CATEGORY,
+ "Business Category",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ OD( nistDSASignaturewithSHA224Digest,
+ SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST,
+ "DSA with SHA-224 Signature",
+ CKM_INVALID_MECHANISM /* not yet defined */, INVALID_CERT_EXTENSION),
+ OD( nistDSASignaturewithSHA256Digest,
+ SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST,
+ "DSA with SHA-256 Signature",
+ CKM_INVALID_MECHANISM /* not yet defined */, INVALID_CERT_EXTENSION),
+ OD( msExtendedKeyUsageTrustListSigning,
+ SEC_OID_MS_EXT_KEY_USAGE_CTL_SIGNING,
+ "Microsoft Trust List Signing",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ /* SMIME attributes */
+ OD( smimeReceiptRequest, SEC_OID_SMIME_RECEIPT_REQUEST,
+ "S/MIME Receipt Request",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( smimeReceipt, SEC_OID_SMIME_RECEIPT,
+ "S/MIME Receipt",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( smimeReceiptMsgSigDigest, SEC_OID_SMIME_RECEIPT_MSGSIGDIGEST,
+ "S/MIME Receipt MsgSigDigest",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ OD( smimeSecurityLabel, SEC_OID_SMIME_SECURITY_LABEL,
+ "S/MIME Security Label",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+ /*Signed Header*/
+ OD( smimeSignedHeader, SEC_OID_SMIME_SECURE_HEADERS,
+ "S/MIME Signed Header",
+ CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION ),
+
+ OD( x520Name, SEC_OID_AVA_NAME,
+ "X520 Name", CKM_INVALID_MECHANISM, INVALID_CERT_EXTENSION )
+};
+
+/* PRIVATE EXTENDED SECOID Table
+ * This table is private. Its structure is opaque to the outside.
+ * It is indexed by the same SECOidTag as the oids table above.
+ * Every member of this struct must have accessor functions (set, get)
+ * and those functions must operate by value, not by reference.
+ * The addresses of the contents of this table must not be exposed
+ * by the accessor functions.
+ */
+typedef struct privXOidStr {
+ PRUint32 notPolicyFlags; /* ones complement of policy flags */
+} privXOid;
+
+static privXOid xOids[SEC_OID_TOTAL];
+
+/*
+ * now the dynamic table. The dynamic table gets build at init time.
+ * and conceivably gets modified if the user loads new crypto modules.
+ * All this static data, and the allocated data to which it points,
+ * is protected by a global reader/writer lock.
+ * The c language guarantees that global and static data that is not
+ * explicitly initialized will be initialized with zeros. If we
+ * initialize it with zeros, the data goes into the initialized data
+ * secment, and increases the size of the library. By leaving it
+ * uninitialized, it is allocated in BSS, and does NOT increase the
+ * library size.
+ */
+
+typedef struct dynXOidStr {
+ SECOidData data;
+ privXOid priv;
+} dynXOid;
+
+static NSSRWLock * dynOidLock;
+static PLArenaPool * dynOidPool;
+static PLHashTable * dynOidHash;
+static dynXOid ** dynOidTable; /* not in the pool */
+static int dynOidEntriesAllocated;
+static int dynOidEntriesUsed;
+
+/* Creates NSSRWLock and dynOidPool at initialization time.
+*/
+static SECStatus
+secoid_InitDynOidData(void)
+{
+ SECStatus rv = SECSuccess;
+
+ dynOidLock = NSSRWLock_New(1, "dynamic OID data");
+ if (!dynOidLock) {
+ return SECFailure; /* Error code should already be set. */
+ }
+ dynOidPool = PORT_NewArena(2048);
+ if (!dynOidPool) {
+ rv = SECFailure /* Error code should already be set. */;
+ }
+ return rv;
+}
+
+/* Add oidData to hash table. Caller holds write lock dynOidLock. */
+static SECStatus
+secoid_HashDynamicOiddata(const SECOidData * oid)
+{
+ PLHashEntry *entry;
+
+ if (!dynOidHash) {
+ dynOidHash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
+ PL_CompareValues, NULL, NULL);
+ if ( !dynOidHash ) {
+ return SECFailure;
+ }
+ }
+
+ entry = PL_HashTableAdd( dynOidHash, &oid->oid, (void *)oid );
+ return entry ? SECSuccess : SECFailure;
+}
+
+
+/*
+ * Lookup a Dynamic OID. Dynamic OID's still change slowly, so it's
+ * cheaper to rehash the table when it changes than it is to do the loop
+ * each time.
+ */
+static SECOidData *
+secoid_FindDynamic(const SECItem *key)
+{
+ SECOidData *ret = NULL;
+
+ if (dynOidHash) {
+ NSSRWLock_LockRead(dynOidLock);
+ if (dynOidHash) { /* must check it again with lock held. */
+ ret = (SECOidData *)PL_HashTableLookup(dynOidHash, key);
+ }
+ NSSRWLock_UnlockRead(dynOidLock);
+ }
+ if (ret == NULL) {
+ PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID);
+ }
+ return ret;
+}
+
+static dynXOid *
+secoid_FindDynamicByTag(SECOidTag tagnum)
+{
+ dynXOid *dxo = NULL;
+ int tagNumDiff;
+
+ if (tagnum < SEC_OID_TOTAL) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ return NULL;
+ }
+ tagNumDiff = tagnum - SEC_OID_TOTAL;
+
+ if (dynOidTable) {
+ NSSRWLock_LockRead(dynOidLock);
+ if (dynOidTable != NULL && /* must check it again with lock held. */
+ tagNumDiff < dynOidEntriesUsed) {
+ dxo = dynOidTable[tagNumDiff];
+ }
+ NSSRWLock_UnlockRead(dynOidLock);
+ }
+ if (dxo == NULL) {
+ PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID);
+ }
+ return dxo;
+}
+
+/*
+ * This routine is thread safe now.
+ */
+SECOidTag
+SECOID_AddEntry(const SECOidData * src)
+{
+ SECOidData * dst;
+ dynXOid **table;
+ SECOidTag ret = SEC_OID_UNKNOWN;
+ SECStatus rv;
+ int tableEntries;
+ int used;
+
+ if (!src || !src->oid.data || !src->oid.len || \
+ !src->desc || !strlen(src->desc)) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return ret;
+ }
+ if (src->supportedExtension != INVALID_CERT_EXTENSION &&
+ src->supportedExtension != UNSUPPORTED_CERT_EXTENSION &&
+ src->supportedExtension != SUPPORTED_CERT_EXTENSION ) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return ret;
+ }
+
+ if (!dynOidPool || !dynOidLock) {
+ PORT_SetError(SEC_ERROR_NOT_INITIALIZED);
+ return ret;
+ }
+
+ NSSRWLock_LockWrite(dynOidLock);
+
+ /* We've just acquired the write lock, and now we call FindOIDTag
+ ** which will acquire and release the read lock. NSSRWLock has been
+ ** designed to allow this very case without deadlock. This approach
+ ** makes the test for the presence of the OID, and the subsequent
+ ** addition of the OID to the table a single atomic write operation.
+ */
+ ret = SECOID_FindOIDTag(&src->oid);
+ if (ret != SEC_OID_UNKNOWN) {
+ /* we could return an error here, but I chose not to do that.
+ ** This way, if we add an OID to the shared library's built in
+ ** list of OIDs in some future release, and that OID is the same
+ ** as some OID that a program has been adding, the program will
+ ** not suddenly stop working.
+ */
+ goto done;
+ }
+
+ table = dynOidTable;
+ tableEntries = dynOidEntriesAllocated;
+ used = dynOidEntriesUsed;
+
+ if (used + 1 > tableEntries) {
+ dynXOid ** newTable;
+ int newTableEntries = tableEntries + 16;
+
+ newTable = (dynXOid **)PORT_Realloc(table,
+ newTableEntries * sizeof(dynXOid *));
+ if (newTable == NULL) {
+ goto done;
+ }
+ dynOidTable = table = newTable;
+ dynOidEntriesAllocated = tableEntries = newTableEntries;
+ }
+
+ /* copy oid structure */
+ dst = (SECOidData *)PORT_ArenaZNew(dynOidPool, dynXOid);
+ if (!dst) {
+ goto done;
+ }
+ rv = SECITEM_CopyItem(dynOidPool, &dst->oid, &src->oid);
+ if (rv != SECSuccess) {
+ goto done;
+ }
+ dst->desc = PORT_ArenaStrdup(dynOidPool, src->desc);
+ if (!dst->desc) {
+ goto done;
+ }
+ dst->offset = (SECOidTag)(used + SEC_OID_TOTAL);
+ dst->mechanism = src->mechanism;
+ dst->supportedExtension = src->supportedExtension;
+
+ rv = secoid_HashDynamicOiddata(dst);
+ if (rv == SECSuccess) {
+ table[used++] = (dynXOid *)dst;
+ dynOidEntriesUsed = used;
+ ret = dst->offset;
+ }
+done:
+ NSSRWLock_UnlockWrite(dynOidLock);
+ return ret;
+}
+
+
+/* normal static table processing */
+static PLHashTable *oidhash = NULL;
+static PLHashTable *oidmechhash = NULL;
+
+static PLHashNumber
+secoid_HashNumber(const void *key)
+{
+ return (PLHashNumber) key;
+}
+
+static void
+handleHashAlgSupport(char * envVal)
+{
+ char * myVal = PORT_Strdup(envVal); /* Get a copy we can alter */
+ char * arg = myVal;
+
+ while (arg && *arg) {
+ char * nextArg = PL_strpbrk(arg, ";");
+ PRUint32 notEnable;
+
+ if (nextArg) {
+ while (*nextArg == ';') {
+ *nextArg++ = '\0';
+ }
+ }
+ notEnable = (*arg == '-') ? NSS_USE_ALG_IN_CERT_SIGNATURE : 0;
+ if ((*arg == '+' || *arg == '-') && *++arg) {
+ int i;
+
+ for (i = 1; i < SEC_OID_TOTAL; i++) {
+ if (oids[i].desc && strstr(arg, oids[i].desc)) {
+ xOids[i].notPolicyFlags = notEnable |
+ (xOids[i].notPolicyFlags & ~NSS_USE_ALG_IN_CERT_SIGNATURE);
+ }
+ }
+ }
+ arg = nextArg;
+ }
+ PORT_Free(myVal); /* can handle NULL argument OK */
+}
+
+SECStatus
+SECOID_Init(void)
+{
+ PLHashEntry *entry;
+ const SECOidData *oid;
+ int i;
+ char * envVal;
+ volatile char c; /* force a reference that won't get optimized away */
+
+ c = __nss_util_rcsid[0] + __nss_util_sccsid[0];
+
+ if (oidhash) {
+ return SECSuccess; /* already initialized */
+ }
+
+ if (!PR_GetEnv("NSS_ALLOW_WEAK_SIGNATURE_ALG")) {
+ /* initialize any policy flags that are disabled by default */
+ xOids[SEC_OID_MD2 ].notPolicyFlags = ~0;
+ xOids[SEC_OID_MD4 ].notPolicyFlags = ~0;
+ xOids[SEC_OID_MD5 ].notPolicyFlags = ~0;
+ xOids[SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION ].notPolicyFlags = ~0;
+ xOids[SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION ].notPolicyFlags = ~0;
+ xOids[SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION ].notPolicyFlags = ~0;
+ xOids[SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC].notPolicyFlags = ~0;
+ xOids[SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC].notPolicyFlags = ~0;
+ }
+
+ envVal = PR_GetEnv("NSS_HASH_ALG_SUPPORT");
+ if (envVal)
+ handleHashAlgSupport(envVal);
+
+ if (secoid_InitDynOidData() != SECSuccess) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ PORT_Assert(0); /* this function should never fail */
+ return SECFailure;
+ }
+
+ oidhash = PL_NewHashTable(0, SECITEM_Hash, SECITEM_HashCompare,
+ PL_CompareValues, NULL, NULL);
+ oidmechhash = PL_NewHashTable(0, secoid_HashNumber, PL_CompareValues,
+ PL_CompareValues, NULL, NULL);
+
+ if ( !oidhash || !oidmechhash) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ PORT_Assert(0); /*This function should never fail. */
+ return(SECFailure);
+ }
+
+ for ( i = 0; i < SEC_OID_TOTAL; i++ ) {
+ oid = &oids[i];
+
+ PORT_Assert ( oid->offset == i );
+
+ entry = PL_HashTableAdd( oidhash, &oid->oid, (void *)oid );
+ if ( entry == NULL ) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ PORT_Assert(0); /*This function should never fail. */
+ return(SECFailure);
+ }
+
+ if ( oid->mechanism != CKM_INVALID_MECHANISM ) {
+ entry = PL_HashTableAdd( oidmechhash,
+ (void *)oid->mechanism, (void *)oid );
+ if ( entry == NULL ) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ PORT_Assert(0); /* This function should never fail. */
+ return(SECFailure);
+ }
+ }
+ }
+
+ PORT_Assert (i == SEC_OID_TOTAL);
+
+ return(SECSuccess);
+}
+
+SECOidData *
+SECOID_FindOIDByMechanism(unsigned long mechanism)
+{
+ SECOidData *ret;
+
+ PR_ASSERT(oidhash != NULL);
+
+ ret = PL_HashTableLookupConst ( oidmechhash, (void *)mechanism);
+ if ( ret == NULL ) {
+ PORT_SetError(SEC_ERROR_LIBRARY_FAILURE);
+ }
+
+ return (ret);
+}
+
+SECOidData *
+SECOID_FindOID(const SECItem *oid)
+{
+ SECOidData *ret;
+
+ PR_ASSERT(oidhash != NULL);
+
+ ret = PL_HashTableLookupConst ( oidhash, oid );
+ if ( ret == NULL ) {
+ ret = secoid_FindDynamic(oid);
+ if (ret == NULL) {
+ PORT_SetError(SEC_ERROR_UNRECOGNIZED_OID);
+ }
+ }
+
+ return(ret);
+}
+
+SECOidTag
+SECOID_FindOIDTag(const SECItem *oid)
+{
+ SECOidData *oiddata;
+
+ oiddata = SECOID_FindOID (oid);
+ if (oiddata == NULL)
+ return SEC_OID_UNKNOWN;
+
+ return oiddata->offset;
+}
+
+/* This really should return const. */
+SECOidData *
+SECOID_FindOIDByTag(SECOidTag tagnum)
+{
+ if (tagnum >= SEC_OID_TOTAL) {
+ return (SECOidData *)secoid_FindDynamicByTag(tagnum);
+ }
+
+ PORT_Assert((unsigned int)tagnum < SEC_OID_TOTAL);
+ return (SECOidData *)(&oids[tagnum]);
+}
+
+PRBool SECOID_KnownCertExtenOID (SECItem *extenOid)
+{
+ SECOidData * oidData;
+
+ oidData = SECOID_FindOID (extenOid);
+ if (oidData == (SECOidData *)NULL)
+ return (PR_FALSE);
+ return ((oidData->supportedExtension == SUPPORTED_CERT_EXTENSION) ?
+ PR_TRUE : PR_FALSE);
+}
+
+
+const char *
+SECOID_FindOIDTagDescription(SECOidTag tagnum)
+{
+ const SECOidData *oidData = SECOID_FindOIDByTag(tagnum);
+ return oidData ? oidData->desc : 0;
+}
+
+/* --------- opaque extended OID table accessor functions ---------------*/
+/*
+ * Any of these functions may return SECSuccess or SECFailure with the error
+ * code set to SEC_ERROR_UNKNOWN_OBJECT_TYPE if the SECOidTag is out of range.
+ */
+
+static privXOid *
+secoid_FindXOidByTag(SECOidTag tagnum)
+{
+ if (tagnum >= SEC_OID_TOTAL) {
+ dynXOid *dxo = secoid_FindDynamicByTag(tagnum);
+ return (dxo ? &dxo->priv : NULL);
+ }
+
+ PORT_Assert((unsigned int)tagnum < SEC_OID_TOTAL);
+ return &xOids[tagnum];
+}
+
+/* The Get function outputs the 32-bit value associated with the SECOidTag.
+ * Flags bits are the NSS_USE_ALG_ #defines in "secoidt.h".
+ * Default value for any algorithm is 0xffffffff (enabled for all purposes).
+ * No value is output if function returns SECFailure.
+ */
+SECStatus
+NSS_GetAlgorithmPolicy(SECOidTag tag, PRUint32 *pValue)
+{
+ privXOid * pxo = secoid_FindXOidByTag(tag);
+ if (!pxo)
+ return SECFailure;
+ if (!pValue) {
+ PORT_SetError(SEC_ERROR_INVALID_ARGS);
+ return SECFailure;
+ }
+ *pValue = ~(pxo->notPolicyFlags);
+ return SECSuccess;
+}
+
+/* The Set function modifies the stored value according to the following
+ * algorithm:
+ * policy[tag] = (policy[tag] & ~clearBits) | setBits;
+ */
+SECStatus
+NSS_SetAlgorithmPolicy(SECOidTag tag, PRUint32 setBits, PRUint32 clearBits)
+{
+ privXOid * pxo = secoid_FindXOidByTag(tag);
+ PRUint32 policyFlags;
+ if (!pxo)
+ return SECFailure;
+ /* The stored policy flags are the ones complement of the flags as
+ * seen by the user. This is not atomic, but these changes should
+ * be done rarely, e.g. at initialization time.
+ */
+ policyFlags = ~(pxo->notPolicyFlags);
+ policyFlags = (policyFlags & ~clearBits) | setBits;
+ pxo->notPolicyFlags = ~policyFlags;
+ return SECSuccess;
+}
+
+/* --------- END OF opaque extended OID table accessor functions ---------*/
+
+/* for now, this is only used in a single place, so it can remain static */
+static PRBool parentForkedAfterC_Initialize;
+
+#define SKIP_AFTER_FORK(x) if (!parentForkedAfterC_Initialize) x
+
+/*
+ * free up the oid tables.
+ */
+SECStatus
+SECOID_Shutdown(void)
+{
+ if (oidhash) {
+ PL_HashTableDestroy(oidhash);
+ oidhash = NULL;
+ }
+ if (oidmechhash) {
+ PL_HashTableDestroy(oidmechhash);
+ oidmechhash = NULL;
+ }
+ /* Have to handle the case where the lock was created, but
+ ** the pool wasn't.
+ ** I'm not going to attempt to create the lock, just to protect
+ ** the destruction of data that probably isn't initialized anyway.
+ */
+ if (dynOidLock) {
+ SKIP_AFTER_FORK(NSSRWLock_LockWrite(dynOidLock));
+ if (dynOidHash) {
+ PL_HashTableDestroy(dynOidHash);
+ dynOidHash = NULL;
+ }
+ if (dynOidPool) {
+ PORT_FreeArena(dynOidPool, PR_FALSE);
+ dynOidPool = NULL;
+ }
+ if (dynOidTable) {
+ PORT_Free(dynOidTable);
+ dynOidTable = NULL;
+ }
+ dynOidEntriesAllocated = 0;
+ dynOidEntriesUsed = 0;
+
+ SKIP_AFTER_FORK(NSSRWLock_UnlockWrite(dynOidLock));
+ SKIP_AFTER_FORK(NSSRWLock_Destroy(dynOidLock));
+ dynOidLock = NULL;
+ } else {
+ /* Since dynOidLock doesn't exist, then all the data it protects
+ ** should be uninitialized. We'll check that (in DEBUG builds),
+ ** and then make sure it is so, in case NSS is reinitialized.
+ */
+ PORT_Assert(!dynOidHash && !dynOidPool && !dynOidTable && \
+ !dynOidEntriesAllocated && !dynOidEntriesUsed);
+ dynOidHash = NULL;
+ dynOidPool = NULL;
+ dynOidTable = NULL;
+ dynOidEntriesAllocated = 0;
+ dynOidEntriesUsed = 0;
+ }
+ memset(xOids, 0, sizeof xOids);
+ return SECSuccess;
+}
+
+void UTIL_SetForkState(PRBool forked)
+{
+ parentForkedAfterC_Initialize = forked;
+}
+
+const char *
+NSSUTIL_GetVersion(void)
+{
+ return NSSUTIL_VERSION;
+}
--- /dev/null
+/* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ * Contributor(s):
+ * Dr Vipul Gupta <vipul.gupta@sun.com>, Sun Microsystems Laboratories
+ * Secure Headers : Copyright (c) 2011 CASSIDIAN - All rights reserved */
+#ifndef _SECOIDT_H_
+#define _SECOIDT_H_
+
+#include "utilrename.h"
+
+/*
+ * secoidt.h - public data structures for ASN.1 OID functions
+ *
+ * $Id: secoidt.h,v 1.31 2010/05/28 01:26:07 wtc%google.com Exp $
+ */
+
+#include "secitem.h"
+
+typedef struct SECOidDataStr SECOidData;
+typedef struct SECAlgorithmIDStr SECAlgorithmID;
+
+/*
+** An X.500 algorithm identifier
+*/
+struct SECAlgorithmIDStr {
+ SECItem algorithm;
+ SECItem parameters;
+};
+
+/*
+ * Misc object IDs - these numbers are for convenient handling.
+ * They are mapped into real object IDs
+ *
+ * NOTE: the order of these entries must mach the array "oids" of SECOidData
+ * in util/secoid.c.
+ */
+typedef enum {
+ SEC_OID_UNKNOWN = 0,
+ SEC_OID_MD2 = 1,
+ SEC_OID_MD4 = 2,
+ SEC_OID_MD5 = 3,
+ SEC_OID_SHA1 = 4,
+ SEC_OID_RC2_CBC = 5,
+ SEC_OID_RC4 = 6,
+ SEC_OID_DES_EDE3_CBC = 7,
+ SEC_OID_RC5_CBC_PAD = 8,
+ SEC_OID_DES_ECB = 9,
+ SEC_OID_DES_CBC = 10,
+ SEC_OID_DES_OFB = 11,
+ SEC_OID_DES_CFB = 12,
+ SEC_OID_DES_MAC = 13,
+ SEC_OID_DES_EDE = 14,
+ SEC_OID_ISO_SHA_WITH_RSA_SIGNATURE = 15,
+ SEC_OID_PKCS1_RSA_ENCRYPTION = 16,
+ SEC_OID_PKCS1_MD2_WITH_RSA_ENCRYPTION = 17,
+ SEC_OID_PKCS1_MD4_WITH_RSA_ENCRYPTION = 18,
+ SEC_OID_PKCS1_MD5_WITH_RSA_ENCRYPTION = 19,
+ SEC_OID_PKCS1_SHA1_WITH_RSA_ENCRYPTION = 20,
+ SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC = 21,
+ SEC_OID_PKCS5_PBE_WITH_MD5_AND_DES_CBC = 22,
+ SEC_OID_PKCS5_PBE_WITH_SHA1_AND_DES_CBC = 23,
+ SEC_OID_PKCS7 = 24,
+ SEC_OID_PKCS7_DATA = 25,
+ SEC_OID_PKCS7_SIGNED_DATA = 26,
+ SEC_OID_PKCS7_ENVELOPED_DATA = 27,
+ SEC_OID_PKCS7_SIGNED_ENVELOPED_DATA = 28,
+ SEC_OID_PKCS7_DIGESTED_DATA = 29,
+ SEC_OID_PKCS7_ENCRYPTED_DATA = 30,
+ SEC_OID_PKCS9_EMAIL_ADDRESS = 31,
+ SEC_OID_PKCS9_UNSTRUCTURED_NAME = 32,
+ SEC_OID_PKCS9_CONTENT_TYPE = 33,
+ SEC_OID_PKCS9_MESSAGE_DIGEST = 34,
+ SEC_OID_PKCS9_SIGNING_TIME = 35,
+ SEC_OID_PKCS9_COUNTER_SIGNATURE = 36,
+ SEC_OID_PKCS9_CHALLENGE_PASSWORD = 37,
+ SEC_OID_PKCS9_UNSTRUCTURED_ADDRESS = 38,
+ SEC_OID_PKCS9_EXTENDED_CERTIFICATE_ATTRIBUTES = 39,
+ SEC_OID_PKCS9_SMIME_CAPABILITIES = 40,
+ SEC_OID_AVA_COMMON_NAME = 41,
+ SEC_OID_AVA_COUNTRY_NAME = 42,
+ SEC_OID_AVA_LOCALITY = 43,
+ SEC_OID_AVA_STATE_OR_PROVINCE = 44,
+ SEC_OID_AVA_ORGANIZATION_NAME = 45,
+ SEC_OID_AVA_ORGANIZATIONAL_UNIT_NAME = 46,
+ SEC_OID_AVA_DN_QUALIFIER = 47,
+ SEC_OID_AVA_DC = 48,
+
+ SEC_OID_NS_TYPE_GIF = 49,
+ SEC_OID_NS_TYPE_JPEG = 50,
+ SEC_OID_NS_TYPE_URL = 51,
+ SEC_OID_NS_TYPE_HTML = 52,
+ SEC_OID_NS_TYPE_CERT_SEQUENCE = 53,
+ SEC_OID_MISSI_KEA_DSS_OLD = 54,
+ SEC_OID_MISSI_DSS_OLD = 55,
+ SEC_OID_MISSI_KEA_DSS = 56,
+ SEC_OID_MISSI_DSS = 57,
+ SEC_OID_MISSI_KEA = 58,
+ SEC_OID_MISSI_ALT_KEA = 59,
+
+ /* Netscape private certificate extensions */
+ SEC_OID_NS_CERT_EXT_NETSCAPE_OK = 60,
+ SEC_OID_NS_CERT_EXT_ISSUER_LOGO = 61,
+ SEC_OID_NS_CERT_EXT_SUBJECT_LOGO = 62,
+ SEC_OID_NS_CERT_EXT_CERT_TYPE = 63,
+ SEC_OID_NS_CERT_EXT_BASE_URL = 64,
+ SEC_OID_NS_CERT_EXT_REVOCATION_URL = 65,
+ SEC_OID_NS_CERT_EXT_CA_REVOCATION_URL = 66,
+ SEC_OID_NS_CERT_EXT_CA_CRL_URL = 67,
+ SEC_OID_NS_CERT_EXT_CA_CERT_URL = 68,
+ SEC_OID_NS_CERT_EXT_CERT_RENEWAL_URL = 69,
+ SEC_OID_NS_CERT_EXT_CA_POLICY_URL = 70,
+ SEC_OID_NS_CERT_EXT_HOMEPAGE_URL = 71,
+ SEC_OID_NS_CERT_EXT_ENTITY_LOGO = 72,
+ SEC_OID_NS_CERT_EXT_USER_PICTURE = 73,
+ SEC_OID_NS_CERT_EXT_SSL_SERVER_NAME = 74,
+ SEC_OID_NS_CERT_EXT_COMMENT = 75,
+ SEC_OID_NS_CERT_EXT_LOST_PASSWORD_URL = 76,
+ SEC_OID_NS_CERT_EXT_CERT_RENEWAL_TIME = 77,
+ SEC_OID_NS_KEY_USAGE_GOVT_APPROVED = 78,
+
+ /* x.509 v3 Extensions */
+ SEC_OID_X509_SUBJECT_DIRECTORY_ATTR = 79,
+ SEC_OID_X509_SUBJECT_KEY_ID = 80,
+ SEC_OID_X509_KEY_USAGE = 81,
+ SEC_OID_X509_PRIVATE_KEY_USAGE_PERIOD = 82,
+ SEC_OID_X509_SUBJECT_ALT_NAME = 83,
+ SEC_OID_X509_ISSUER_ALT_NAME = 84,
+ SEC_OID_X509_BASIC_CONSTRAINTS = 85,
+ SEC_OID_X509_NAME_CONSTRAINTS = 86,
+ SEC_OID_X509_CRL_DIST_POINTS = 87,
+ SEC_OID_X509_CERTIFICATE_POLICIES = 88,
+ SEC_OID_X509_POLICY_MAPPINGS = 89,
+ SEC_OID_X509_POLICY_CONSTRAINTS = 90,
+ SEC_OID_X509_AUTH_KEY_ID = 91,
+ SEC_OID_X509_EXT_KEY_USAGE = 92,
+ SEC_OID_X509_AUTH_INFO_ACCESS = 93,
+
+ SEC_OID_X509_CRL_NUMBER = 94,
+ SEC_OID_X509_REASON_CODE = 95,
+ SEC_OID_X509_INVALID_DATE = 96,
+ /* End of x.509 v3 Extensions */
+
+ SEC_OID_X500_RSA_ENCRYPTION = 97,
+
+ /* alg 1485 additions */
+ SEC_OID_RFC1274_UID = 98,
+ SEC_OID_RFC1274_MAIL = 99,
+
+ /* PKCS 12 additions */
+ SEC_OID_PKCS12 = 100,
+ SEC_OID_PKCS12_MODE_IDS = 101,
+ SEC_OID_PKCS12_ESPVK_IDS = 102,
+ SEC_OID_PKCS12_BAG_IDS = 103,
+ SEC_OID_PKCS12_CERT_BAG_IDS = 104,
+ SEC_OID_PKCS12_OIDS = 105,
+ SEC_OID_PKCS12_PBE_IDS = 106,
+ SEC_OID_PKCS12_SIGNATURE_IDS = 107,
+ SEC_OID_PKCS12_ENVELOPING_IDS = 108,
+ /* SEC_OID_PKCS12_OFFLINE_TRANSPORT_MODE,
+ SEC_OID_PKCS12_ONLINE_TRANSPORT_MODE, */
+ SEC_OID_PKCS12_PKCS8_KEY_SHROUDING = 109,
+ SEC_OID_PKCS12_KEY_BAG_ID = 110,
+ SEC_OID_PKCS12_CERT_AND_CRL_BAG_ID = 111,
+ SEC_OID_PKCS12_SECRET_BAG_ID = 112,
+ SEC_OID_PKCS12_X509_CERT_CRL_BAG = 113,
+ SEC_OID_PKCS12_SDSI_CERT_BAG = 114,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC4 = 115,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC4 = 116,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_TRIPLE_DES_CBC = 117,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC = 118,
+ SEC_OID_PKCS12_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC = 119,
+ SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_128_BIT_RC4 = 120,
+ SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_40_BIT_RC4 = 121,
+ SEC_OID_PKCS12_RSA_ENCRYPTION_WITH_TRIPLE_DES = 122,
+ SEC_OID_PKCS12_RSA_SIGNATURE_WITH_SHA1_DIGEST = 123,
+ /* end of PKCS 12 additions */
+
+ /* DSA signatures */
+ SEC_OID_ANSIX9_DSA_SIGNATURE = 124,
+ SEC_OID_ANSIX9_DSA_SIGNATURE_WITH_SHA1_DIGEST = 125,
+ SEC_OID_BOGUS_DSA_SIGNATURE_WITH_SHA1_DIGEST = 126,
+
+ /* Verisign OIDs */
+ SEC_OID_VERISIGN_USER_NOTICES = 127,
+
+ /* PKIX OIDs */
+ SEC_OID_PKIX_CPS_POINTER_QUALIFIER = 128,
+ SEC_OID_PKIX_USER_NOTICE_QUALIFIER = 129,
+ SEC_OID_PKIX_OCSP = 130,
+ SEC_OID_PKIX_OCSP_BASIC_RESPONSE = 131,
+ SEC_OID_PKIX_OCSP_NONCE = 132,
+ SEC_OID_PKIX_OCSP_CRL = 133,
+ SEC_OID_PKIX_OCSP_RESPONSE = 134,
+ SEC_OID_PKIX_OCSP_NO_CHECK = 135,
+ SEC_OID_PKIX_OCSP_ARCHIVE_CUTOFF = 136,
+ SEC_OID_PKIX_OCSP_SERVICE_LOCATOR = 137,
+ SEC_OID_PKIX_REGCTRL_REGTOKEN = 138,
+ SEC_OID_PKIX_REGCTRL_AUTHENTICATOR = 139,
+ SEC_OID_PKIX_REGCTRL_PKIPUBINFO = 140,
+ SEC_OID_PKIX_REGCTRL_PKI_ARCH_OPTIONS = 141,
+ SEC_OID_PKIX_REGCTRL_OLD_CERT_ID = 142,
+ SEC_OID_PKIX_REGCTRL_PROTOCOL_ENC_KEY = 143,
+ SEC_OID_PKIX_REGINFO_UTF8_PAIRS = 144,
+ SEC_OID_PKIX_REGINFO_CERT_REQUEST = 145,
+ SEC_OID_EXT_KEY_USAGE_SERVER_AUTH = 146,
+ SEC_OID_EXT_KEY_USAGE_CLIENT_AUTH = 147,
+ SEC_OID_EXT_KEY_USAGE_CODE_SIGN = 148,
+ SEC_OID_EXT_KEY_USAGE_EMAIL_PROTECT = 149,
+ SEC_OID_EXT_KEY_USAGE_TIME_STAMP = 150,
+ SEC_OID_OCSP_RESPONDER = 151,
+
+ /* Netscape Algorithm OIDs */
+ SEC_OID_NETSCAPE_SMIME_KEA = 152,
+
+ /* Skipjack OID -- ### mwelch temporary */
+ SEC_OID_FORTEZZA_SKIPJACK = 153,
+
+ /* PKCS 12 V2 oids */
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC4 = 154,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC4 = 155,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_3KEY_TRIPLE_DES_CBC = 156,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_2KEY_TRIPLE_DES_CBC = 157,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_128_BIT_RC2_CBC = 158,
+ SEC_OID_PKCS12_V2_PBE_WITH_SHA1_AND_40_BIT_RC2_CBC = 159,
+ SEC_OID_PKCS12_SAFE_CONTENTS_ID = 160,
+ SEC_OID_PKCS12_PKCS8_SHROUDED_KEY_BAG_ID = 161,
+
+ SEC_OID_PKCS12_V1_KEY_BAG_ID = 162,
+ SEC_OID_PKCS12_V1_PKCS8_SHROUDED_KEY_BAG_ID = 163,
+ SEC_OID_PKCS12_V1_CERT_BAG_ID = 164,
+ SEC_OID_PKCS12_V1_CRL_BAG_ID = 165,
+ SEC_OID_PKCS12_V1_SECRET_BAG_ID = 166,
+ SEC_OID_PKCS12_V1_SAFE_CONTENTS_BAG_ID = 167,
+ SEC_OID_PKCS9_X509_CERT = 168,
+ SEC_OID_PKCS9_SDSI_CERT = 169,
+ SEC_OID_PKCS9_X509_CRL = 170,
+ SEC_OID_PKCS9_FRIENDLY_NAME = 171,
+ SEC_OID_PKCS9_LOCAL_KEY_ID = 172,
+ SEC_OID_BOGUS_KEY_USAGE = 173,
+
+ /*Diffe Helman OIDS */
+ SEC_OID_X942_DIFFIE_HELMAN_KEY = 174,
+
+ /* Netscape other name types */
+ /* SEC_OID_NETSCAPE_NICKNAME is an otherName field of type IA5String
+ * in the subjectAltName certificate extension. NSS dropped support
+ * for SEC_OID_NETSCAPE_NICKNAME in NSS 3.13. */
+ SEC_OID_NETSCAPE_NICKNAME = 175,
+
+ /* Cert Server OIDS */
+ SEC_OID_NETSCAPE_RECOVERY_REQUEST = 176,
+
+ /* New PSM certificate management OIDs */
+ SEC_OID_CERT_RENEWAL_LOCATOR = 177,
+ SEC_OID_NS_CERT_EXT_SCOPE_OF_USE = 178,
+
+ /* CMS (RFC2630) OIDs */
+ SEC_OID_CMS_EPHEMERAL_STATIC_DIFFIE_HELLMAN = 179,
+ SEC_OID_CMS_3DES_KEY_WRAP = 180,
+ SEC_OID_CMS_RC2_KEY_WRAP = 181,
+
+ /* SMIME attributes */
+ SEC_OID_SMIME_ENCRYPTION_KEY_PREFERENCE = 182,
+
+ /* AES OIDs */
+ SEC_OID_AES_128_ECB = 183,
+ SEC_OID_AES_128_CBC = 184,
+ SEC_OID_AES_192_ECB = 185,
+ SEC_OID_AES_192_CBC = 186,
+ SEC_OID_AES_256_ECB = 187,
+ SEC_OID_AES_256_CBC = 188,
+
+ SEC_OID_SDN702_DSA_SIGNATURE = 189,
+
+ SEC_OID_MS_SMIME_ENCRYPTION_KEY_PREFERENCE = 190,
+
+ SEC_OID_SHA256 = 191,
+ SEC_OID_SHA384 = 192,
+ SEC_OID_SHA512 = 193,
+
+ SEC_OID_PKCS1_SHA256_WITH_RSA_ENCRYPTION = 194,
+ SEC_OID_PKCS1_SHA384_WITH_RSA_ENCRYPTION = 195,
+ SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION = 196,
+
+ SEC_OID_AES_128_KEY_WRAP = 197,
+ SEC_OID_AES_192_KEY_WRAP = 198,
+ SEC_OID_AES_256_KEY_WRAP = 199,
+
+ /* Elliptic Curve Cryptography (ECC) OIDs */
+ SEC_OID_ANSIX962_EC_PUBLIC_KEY = 200,
+ SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE = 201,
+
+#define SEC_OID_ANSIX962_ECDSA_SIGNATURE_WITH_SHA1_DIGEST \
+ SEC_OID_ANSIX962_ECDSA_SHA1_SIGNATURE
+
+ /* ANSI X9.62 named elliptic curves (prime field) */
+ SEC_OID_ANSIX962_EC_PRIME192V1 = 202,
+ SEC_OID_ANSIX962_EC_PRIME192V2 = 203,
+ SEC_OID_ANSIX962_EC_PRIME192V3 = 204,
+ SEC_OID_ANSIX962_EC_PRIME239V1 = 205,
+ SEC_OID_ANSIX962_EC_PRIME239V2 = 206,
+ SEC_OID_ANSIX962_EC_PRIME239V3 = 207,
+ SEC_OID_ANSIX962_EC_PRIME256V1 = 208,
+
+ /* SECG named elliptic curves (prime field) */
+ SEC_OID_SECG_EC_SECP112R1 = 209,
+ SEC_OID_SECG_EC_SECP112R2 = 210,
+ SEC_OID_SECG_EC_SECP128R1 = 211,
+ SEC_OID_SECG_EC_SECP128R2 = 212,
+ SEC_OID_SECG_EC_SECP160K1 = 213,
+ SEC_OID_SECG_EC_SECP160R1 = 214,
+ SEC_OID_SECG_EC_SECP160R2 = 215,
+ SEC_OID_SECG_EC_SECP192K1 = 216,
+ /* SEC_OID_SECG_EC_SECP192R1 is SEC_OID_ANSIX962_EC_PRIME192V1 */
+ SEC_OID_SECG_EC_SECP224K1 = 217,
+ SEC_OID_SECG_EC_SECP224R1 = 218,
+ SEC_OID_SECG_EC_SECP256K1 = 219,
+ /* SEC_OID_SECG_EC_SECP256R1 is SEC_OID_ANSIX962_EC_PRIME256V1 */
+ SEC_OID_SECG_EC_SECP384R1 = 220,
+ SEC_OID_SECG_EC_SECP521R1 = 221,
+
+ /* ANSI X9.62 named elliptic curves (characteristic two field) */
+ SEC_OID_ANSIX962_EC_C2PNB163V1 = 222,
+ SEC_OID_ANSIX962_EC_C2PNB163V2 = 223,
+ SEC_OID_ANSIX962_EC_C2PNB163V3 = 224,
+ SEC_OID_ANSIX962_EC_C2PNB176V1 = 225,
+ SEC_OID_ANSIX962_EC_C2TNB191V1 = 226,
+ SEC_OID_ANSIX962_EC_C2TNB191V2 = 227,
+ SEC_OID_ANSIX962_EC_C2TNB191V3 = 228,
+ SEC_OID_ANSIX962_EC_C2ONB191V4 = 229,
+ SEC_OID_ANSIX962_EC_C2ONB191V5 = 230,
+ SEC_OID_ANSIX962_EC_C2PNB208W1 = 231,
+ SEC_OID_ANSIX962_EC_C2TNB239V1 = 232,
+ SEC_OID_ANSIX962_EC_C2TNB239V2 = 233,
+ SEC_OID_ANSIX962_EC_C2TNB239V3 = 234,
+ SEC_OID_ANSIX962_EC_C2ONB239V4 = 235,
+ SEC_OID_ANSIX962_EC_C2ONB239V5 = 236,
+ SEC_OID_ANSIX962_EC_C2PNB272W1 = 237,
+ SEC_OID_ANSIX962_EC_C2PNB304W1 = 238,
+ SEC_OID_ANSIX962_EC_C2TNB359V1 = 239,
+ SEC_OID_ANSIX962_EC_C2PNB368W1 = 240,
+ SEC_OID_ANSIX962_EC_C2TNB431R1 = 241,
+
+ /* SECG named elliptic curves (characteristic two field) */
+ SEC_OID_SECG_EC_SECT113R1 = 242,
+ SEC_OID_SECG_EC_SECT113R2 = 243,
+ SEC_OID_SECG_EC_SECT131R1 = 244,
+ SEC_OID_SECG_EC_SECT131R2 = 245,
+ SEC_OID_SECG_EC_SECT163K1 = 246,
+ SEC_OID_SECG_EC_SECT163R1 = 247,
+ SEC_OID_SECG_EC_SECT163R2 = 248,
+ SEC_OID_SECG_EC_SECT193R1 = 249,
+ SEC_OID_SECG_EC_SECT193R2 = 250,
+ SEC_OID_SECG_EC_SECT233K1 = 251,
+ SEC_OID_SECG_EC_SECT233R1 = 252,
+ SEC_OID_SECG_EC_SECT239K1 = 253,
+ SEC_OID_SECG_EC_SECT283K1 = 254,
+ SEC_OID_SECG_EC_SECT283R1 = 255,
+ SEC_OID_SECG_EC_SECT409K1 = 256,
+ SEC_OID_SECG_EC_SECT409R1 = 257,
+ SEC_OID_SECG_EC_SECT571K1 = 258,
+ SEC_OID_SECG_EC_SECT571R1 = 259,
+
+ SEC_OID_NETSCAPE_AOLSCREENNAME = 260,
+
+ SEC_OID_AVA_SURNAME = 261,
+ SEC_OID_AVA_SERIAL_NUMBER = 262,
+ SEC_OID_AVA_STREET_ADDRESS = 263,
+ SEC_OID_AVA_TITLE = 264,
+ SEC_OID_AVA_POSTAL_ADDRESS = 265,
+ SEC_OID_AVA_POSTAL_CODE = 266,
+ SEC_OID_AVA_POST_OFFICE_BOX = 267,
+ SEC_OID_AVA_GIVEN_NAME = 268,
+ SEC_OID_AVA_INITIALS = 269,
+ SEC_OID_AVA_GENERATION_QUALIFIER = 270,
+ SEC_OID_AVA_HOUSE_IDENTIFIER = 271,
+ SEC_OID_AVA_PSEUDONYM = 272,
+
+ /* More OIDs */
+ SEC_OID_PKIX_CA_ISSUERS = 273,
+ SEC_OID_PKCS9_EXTENSION_REQUEST = 274,
+
+ /* new EC Signature oids */
+ SEC_OID_ANSIX962_ECDSA_SIGNATURE_RECOMMENDED_DIGEST = 275,
+ SEC_OID_ANSIX962_ECDSA_SIGNATURE_SPECIFIED_DIGEST = 276,
+ SEC_OID_ANSIX962_ECDSA_SHA224_SIGNATURE = 277,
+ SEC_OID_ANSIX962_ECDSA_SHA256_SIGNATURE = 278,
+ SEC_OID_ANSIX962_ECDSA_SHA384_SIGNATURE = 279,
+ SEC_OID_ANSIX962_ECDSA_SHA512_SIGNATURE = 280,
+
+ /* More id-ce and id-pe OIDs from RFC 3280 */
+ SEC_OID_X509_HOLD_INSTRUCTION_CODE = 281,
+ SEC_OID_X509_DELTA_CRL_INDICATOR = 282,
+ SEC_OID_X509_ISSUING_DISTRIBUTION_POINT = 283,
+ SEC_OID_X509_CERT_ISSUER = 284,
+ SEC_OID_X509_FRESHEST_CRL = 285,
+ SEC_OID_X509_INHIBIT_ANY_POLICY = 286,
+ SEC_OID_X509_SUBJECT_INFO_ACCESS = 287,
+
+ /* Camellia OIDs (RFC3657)*/
+ SEC_OID_CAMELLIA_128_CBC = 288,
+ SEC_OID_CAMELLIA_192_CBC = 289,
+ SEC_OID_CAMELLIA_256_CBC = 290,
+
+ /* PKCS 5 V2 OIDS */
+ SEC_OID_PKCS5_PBKDF2 = 291,
+ SEC_OID_PKCS5_PBES2 = 292,
+ SEC_OID_PKCS5_PBMAC1 = 293,
+ SEC_OID_HMAC_SHA1 = 294,
+ SEC_OID_HMAC_SHA224 = 295,
+ SEC_OID_HMAC_SHA256 = 296,
+ SEC_OID_HMAC_SHA384 = 297,
+ SEC_OID_HMAC_SHA512 = 298,
+
+ SEC_OID_PKIX_TIMESTAMPING = 299,
+ SEC_OID_PKIX_CA_REPOSITORY = 300,
+
+ SEC_OID_ISO_SHA1_WITH_RSA_SIGNATURE = 301,
+
+ SEC_OID_SEED_CBC = 302,
+
+ SEC_OID_X509_ANY_POLICY = 303,
+
+ SEC_OID_PKCS1_RSA_OAEP_ENCRYPTION = 304,
+ SEC_OID_PKCS1_MGF1 = 305,
+ SEC_OID_PKCS1_PSPECIFIED = 306,
+ SEC_OID_PKCS1_RSA_PSS_SIGNATURE = 307,
+ SEC_OID_PKCS1_SHA224_WITH_RSA_ENCRYPTION = 308,
+
+ SEC_OID_SHA224 = 309,
+
+ SEC_OID_EV_INCORPORATION_LOCALITY = 310,
+ SEC_OID_EV_INCORPORATION_STATE = 311,
+ SEC_OID_EV_INCORPORATION_COUNTRY = 312,
+ SEC_OID_BUSINESS_CATEGORY = 313,
+
+ SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA224_DIGEST = 314,
+ SEC_OID_NIST_DSA_SIGNATURE_WITH_SHA256_DIGEST = 315,
+
+ /* Microsoft Trust List Signing
+ * szOID_KP_CTL_USAGE_SIGNING
+ * where KP stands for Key Purpose
+ */
+ SEC_OID_MS_EXT_KEY_USAGE_CTL_SIGNING = 316,
+
+ /* SMIME attributes */
+ SEC_OID_SMIME_RECEIPT_REQUEST = 317,
+ SEC_OID_SMIME_RECEIPT = 318,
+ SEC_OID_SMIME_RECEIPT_MSGSIGDIGEST = 319,
+ SEC_OID_SMIME_SECURITY_LABEL = 320,
+ /* Signed Header */
+ SEC_OID_SMIME_SECURE_HEADERS = 321,
+ /* The 'name' attribute type in X.520 */
+ SEC_OID_AVA_NAME = 322,
+ SEC_OID_TOTAL
+} SECOidTag;
+
+#define SEC_OID_SECG_EC_SECP192R1 SEC_OID_ANSIX962_EC_PRIME192V1
+#define SEC_OID_SECG_EC_SECP256R1 SEC_OID_ANSIX962_EC_PRIME256V1
+#define SEC_OID_PKCS12_KEY_USAGE SEC_OID_X509_KEY_USAGE
+
+/* fake OID for DSS sign/verify */
+#define SEC_OID_SHA SEC_OID_MISS_DSS
+
+typedef enum {
+ INVALID_CERT_EXTENSION = 0,
+ UNSUPPORTED_CERT_EXTENSION = 1,
+ SUPPORTED_CERT_EXTENSION = 2
+} SECSupportExtenTag;
+
+struct SECOidDataStr {
+ SECItem oid;
+ SECOidTag offset;
+ const char * desc;
+ unsigned long mechanism;
+ SECSupportExtenTag supportedExtension;
+ /* only used for x.509 v3 extensions, so
+ that we can print the names of those
+ extensions that we don't even support */
+};
+
+/* New Opaque extended OID table API.
+ * These are algorithm policy Flags, used with functions
+ * NSS_SetAlgorithmPolicy & NSS_GetAlgorithmPolicy.
+ */
+#define NSS_USE_ALG_IN_CERT_SIGNATURE 0x00000001 /* CRLs and OCSP, too */
+#define NSS_USE_ALG_IN_CMS_SIGNATURE 0x00000002 /* used in S/MIME */
+#define NSS_USE_ALG_RESERVED 0xfffffffc /* may be used in future */
+
+/* Code MUST NOT SET or CLEAR reserved bits, and must NOT depend on them
+ * being all zeros or having any other known value. The reserved bits
+ * must be ignored.
+ */
+
+
+#endif /* _SECOIDT_H_ */