View Javadoc

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