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><debug>.</li>
40 * <li><keyStoreFileName>.</li>
41 * <li><keyStorePassword>.</li>
42 * <li><keyAlias>.</li>
43 * <li><keyAliasPassword>.</li>
44 * <li><keyStoreType>.</li>
45 * <li><postmasterSigns>. The default is <CODE>true</CODE>.</li>
46 * <li><rebuildFrom>. The default is <CODE>true</CODE>.</li>
47 * <li><signerName>.</li>
48 * <li><explanationText>. 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
86
87
88 /***
89 * If the <CODE><explanationText></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><postmasterSigns></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><rebuildFrom></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
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
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