View Javadoc

1   /************************************************************************
2    * Copyright (c) 2000-2006 The Apache Software Foundation.             *
3    * All rights reserved.                                                *
4    * ------------------------------------------------------------------- *
5    * Licensed under the Apache License, Version 2.0 (the "License"); you *
6    * may not use this file except in compliance with the License. You    *
7    * may obtain a copy of the License at:                                *
8    *                                                                     *
9    *     http://www.apache.org/licenses/LICENSE-2.0                      *
10   *                                                                     *
11   * Unless required by applicable law or agreed to in writing, software *
12   * distributed under the License is distributed on an "AS IS" BASIS,   *
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or     *
14   * implied.  See the License for the specific language governing       *
15   * permissions and limitations under the License.                      *
16   ***********************************************************************/
17  
18  package org.apache.james.transport.mailets.smime;
19  
20  import org.apache.mailet.Mail;
21  
22  import javax.mail.MessagingException;
23  import javax.mail.internet.MimeBodyPart;
24  import javax.mail.internet.MimeMessage;
25  import javax.mail.internet.MimeMultipart;
26  
27  import java.io.IOException;
28  
29  /***
30   * <p>Puts a <I>server-side</I> SMIME signature on a message.<br>
31   * It is a concrete subclass of {@link SMIMEAbstractSign}, with very few modifications to it.</p>
32   * <p>A text file with an explanation text is attached to the original message,
33   * and the resulting message with all its attachments is signed.
34   * The resulting appearence of the message is almost unchanged: only an extra attachment
35   * and the signature are added.</p>
36   *
37   *  <P>Handles the following init parameters (will comment only the differences from {@link SMIMEAbstractSign}):</P>
38   * <ul>
39   * <li>&lt;debug&gt;.</li>
40   * <li>&lt;keyStoreFileName&gt;.</li>
41   * <li>&lt;keyStorePassword&gt;.</li>
42   * <li>&lt;keyAlias&gt;.</li>
43   * <li>&lt;keyAliasPassword&gt;.</li>
44   * <li>&lt;keyStoreType&gt;.</li>
45   * <li>&lt;postmasterSigns&gt;. The default is <CODE>true</CODE>.</li>
46   * <li>&lt;rebuildFrom&gt;. The default is <CODE>true</CODE>.</li>
47   * <li>&lt;signerName&gt;.</li>
48   * <li>&lt;explanationText&gt;. There is a default explanation string template in English,
49   * displaying also all the headers of the original message (see {@link #getExplanationText}).</li>
50   * </ul>
51   * @version CVS $Revision: 365582 $ $Date: 2006-01-03 08:51:21 +0000 (mar, 03 gen 2006) $
52   * @since 2.2.1
53   */
54  public class SMIMESign extends SMIMEAbstractSign {
55      
56      /***
57       * Return a string describing this mailet.
58       *
59       * @return a string describing this mailet
60       */
61      public String getMailetInfo() {
62          return "SMIME Signature Mailet";
63      }
64      
65      /***
66       *
67       */
68      protected  String[] getAllowedInitParameters() {
69          String[] allowedArray = {
70              "debug",
71              "keyStoreFileName",
72              "keyStorePassword",
73              "keyStoreType",
74              "keyAlias",
75              "keyAliasPassword",
76              "signerName",
77              "postmasterSigns",
78              "rebuildFrom",
79              "explanationText"
80          };
81          return allowedArray;
82      }
83      
84       /* ******************************************************************** */
85      /* ****************** Begin of setters and getters ******************** */
86      /* ******************************************************************** */    
87      
88      /***
89       * If the <CODE>&lt;explanationText&gt;</CODE> init parameter is missing
90       * returns the following default explanation template string:
91       * <pre><code>
92       * The message this file is attached to has been signed on the server by
93       *     "[signerName]" <[signerAddress]>
94       * to certify that the sender is known and truly has the following address (reverse-path):
95       *     [reversePath]
96       * and that the original message has the following message headers:
97       *
98       * [headers]
99       *
100      * The signature envelopes this attachment too.
101      * Please check the signature integrity.
102      *
103      *     "[signerName]" <[signerAddress]>
104      * </code></pre>
105      */
106     public String getExplanationText() {
107         String explanationText = super.getExplanationText();
108         if (explanationText == null) {
109             explanationText = "The message this file is attached to has been signed on the server by\r\n"
110             + "\t\"[signerName]\" <[signerAddress]>"
111             + "\r\nto certify that the sender is known and truly has the following address (reverse-path):\r\n"
112             + "\t[reversePath]"
113             + "\r\nand that the original message has the following message headers:\r\n"
114             + "\r\n[headers]"
115             + "\r\n\r\nThe signature envelopes this attachment too."
116             + "\r\nPlease check the signature integrity."
117             + "\r\n\r\n"
118             + "\t\"[signerName]\" <[signerAddress]>";
119         }
120         
121         return explanationText;
122     }
123     
124     /***
125      * If the <CODE>&lt;postmasterSigns&gt;</CODE> init parameter is missing sets it to <I>true</I>.
126      */
127     protected void initPostmasterSigns() {
128         setPostmasterSigns((getInitParameter("postmasterSigns") == null) ? true : new Boolean(getInitParameter("postmasterSigns")).booleanValue());
129     }
130     
131     /***
132      * If the <CODE>&lt;rebuildFrom&gt;</CODE> init parameter is missing sets it to <I>true</I>.
133      */
134     protected void initRebuildFrom() throws MessagingException {
135         setRebuildFrom((getInitParameter("rebuildFrom") == null) ? true : new Boolean(getInitParameter("rebuildFrom")).booleanValue());
136         if (isDebug()) {
137             if (isRebuildFrom()) {
138                 log("Will modify the \"From:\" header.");
139             } else {
140                 log("Will leave the \"From:\" header unchanged.");
141             }
142         }
143     }
144     
145     /* ******************************************************************** */
146     /* ****************** End of setters and getters ********************** */
147     /* ******************************************************************** */
148     
149     /***
150      * A text file with the massaged contents of {@link #getExplanationText}
151      * is attached to the original message.
152      */    
153     protected MimeBodyPart getWrapperBodyPart(Mail mail) throws MessagingException, IOException {
154         
155         String explanationText = getExplanationText();
156         
157         // if there is no explanation text there should be no wrapping
158         if (explanationText == null) {
159             return null;
160         }
161 
162             MimeMessage originalMessage = mail.getMessage();
163 
164             MimeBodyPart messagePart = new MimeBodyPart();
165             MimeBodyPart signatureReason = new MimeBodyPart();
166             
167             String contentType = originalMessage.getContentType();
168             Object content = originalMessage.getContent();
169             
170             if (contentType != null && content != null) {
171             messagePart.setContent(content, contentType);
172             } else {
173                 throw new MessagingException("Either the content type or the content is null");
174             }
175             
176             String headers = getMessageHeaders(originalMessage);
177             
178             signatureReason.setText(getReplacedExplanationText(getExplanationText(),
179                                                                getSignerName(),
180                                                                getKeyHolder().getSignerAddress(),
181                                                                mail.getSender().toString(),
182                                                                headers));
183             
184             signatureReason.setFileName("SignatureExplanation.txt");
185             
186             MimeMultipart wrapperMultiPart = new MimeMultipart();
187             
188             wrapperMultiPart.addBodyPart(messagePart);
189             wrapperMultiPart.addBodyPart(signatureReason);
190             
191             MimeBodyPart wrapperBodyPart = new MimeBodyPart();
192             
193             wrapperBodyPart.setContent(wrapperMultiPart);
194             
195             return wrapperBodyPart;
196     }
197         
198 }
199