001: /****************************************************************
002: * Licensed to the Apache Software Foundation (ASF) under one *
003: * or more contributor license agreements. See the NOTICE file *
004: * distributed with this work for additional information *
005: * regarding copyright ownership. The ASF licenses this file *
006: * to you under the Apache License, Version 2.0 (the *
007: * "License"); you may not use this file except in compliance *
008: * with the License. You may obtain a copy of the License at *
009: * *
010: * http://www.apache.org/licenses/LICENSE-2.0 *
011: * *
012: * Unless required by applicable law or agreed to in writing, *
013: * software distributed under the License is distributed on an *
014: * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY *
015: * KIND, either express or implied. See the License for the *
016: * specific language governing permissions and limitations *
017: * under the License. *
018: ****************************************************************/package org.apache.james.transport.mailets.smime;
019:
020: import org.apache.mailet.Mail;
021:
022: import javax.mail.MessagingException;
023: import javax.mail.internet.MimeBodyPart;
024: import javax.mail.internet.MimeMessage;
025: import javax.mail.internet.MimeMultipart;
026:
027: import java.io.IOException;
028:
029: /**
030: * <p>Puts a <I>server-side</I> SMIME signature on a message.<br>
031: * It is a concrete subclass of {@link SMIMEAbstractSign}, with very few modifications to it.</p>
032: * <p>A text file with an explanation text is attached to the original message,
033: * and the resulting message with all its attachments is signed.
034: * The resulting appearence of the message is almost unchanged: only an extra attachment
035: * and the signature are added.</p>
036: *
037: * <P>Handles the following init parameters (will comment only the differences from {@link SMIMEAbstractSign}):</P>
038: * <ul>
039: * <li><debug>.</li>
040: * <li><keyStoreFileName>.</li>
041: * <li><keyStorePassword>.</li>
042: * <li><keyAlias>.</li>
043: * <li><keyAliasPassword>.</li>
044: * <li><keyStoreType>.</li>
045: * <li><postmasterSigns>. The default is <CODE>true</CODE>.</li>
046: * <li><rebuildFrom>. The default is <CODE>true</CODE>.</li>
047: * <li><signerName>.</li>
048: * <li><explanationText>. There is a default explanation string template in English,
049: * displaying also all the headers of the original message (see {@link #getExplanationText}).</li>
050: * </ul>
051: * @version CVS $Revision: 494012 $ $Date: 2007-01-08 11:23:58 +0100 (Mo, 08 Jan 2007) $
052: * @since 2.2.1
053: */
054: public class SMIMESign extends SMIMEAbstractSign {
055:
056: /**
057: * Return a string describing this mailet.
058: *
059: * @return a string describing this mailet
060: */
061: public String getMailetInfo() {
062: return "SMIME Signature Mailet";
063: }
064:
065: /**
066: *
067: */
068: protected String[] getAllowedInitParameters() {
069: String[] allowedArray = { "debug", "keyStoreFileName",
070: "keyStorePassword", "keyStoreType", "keyAlias",
071: "keyAliasPassword", "signerName", "postmasterSigns",
072: "rebuildFrom", "explanationText" };
073: return allowedArray;
074: }
075:
076: /* ******************************************************************** */
077: /* ****************** Begin of setters and getters ******************** */
078: /* ******************************************************************** */
079:
080: /**
081: * If the <CODE><explanationText></CODE> init parameter is missing
082: * returns the following default explanation template string:
083: * <pre><code>
084: * The message this file is attached to has been signed on the server by
085: * "[signerName]" <[signerAddress]>
086: * to certify that the sender is known and truly has the following address (reverse-path):
087: * [reversePath]
088: * and that the original message has the following message headers:
089: *
090: * [headers]
091: *
092: * The signature envelopes this attachment too.
093: * Please check the signature integrity.
094: *
095: * "[signerName]" <[signerAddress]>
096: * </code></pre>
097: */
098: public String getExplanationText() {
099: String explanationText = super .getExplanationText();
100: if (explanationText == null) {
101: explanationText = "The message this file is attached to has been signed on the server by\r\n"
102: + "\t\"[signerName]\" <[signerAddress]>"
103: + "\r\nto certify that the sender is known and truly has the following address (reverse-path):\r\n"
104: + "\t[reversePath]"
105: + "\r\nand that the original message has the following message headers:\r\n"
106: + "\r\n[headers]"
107: + "\r\n\r\nThe signature envelopes this attachment too."
108: + "\r\nPlease check the signature integrity."
109: + "\r\n\r\n"
110: + "\t\"[signerName]\" <[signerAddress]>";
111: }
112:
113: return explanationText;
114: }
115:
116: /**
117: * If the <CODE><postmasterSigns></CODE> init parameter is missing sets it to <I>true</I>.
118: */
119: protected void initPostmasterSigns() {
120: setPostmasterSigns((getInitParameter("postmasterSigns") == null) ? true
121: : new Boolean(getInitParameter("postmasterSigns"))
122: .booleanValue());
123: }
124:
125: /**
126: * If the <CODE><rebuildFrom></CODE> init parameter is missing sets it to <I>true</I>.
127: */
128: protected void initRebuildFrom() throws MessagingException {
129: setRebuildFrom((getInitParameter("rebuildFrom") == null) ? true
130: : new Boolean(getInitParameter("rebuildFrom"))
131: .booleanValue());
132: if (isDebug()) {
133: if (isRebuildFrom()) {
134: log("Will modify the \"From:\" header.");
135: } else {
136: log("Will leave the \"From:\" header unchanged.");
137: }
138: }
139: }
140:
141: /* ******************************************************************** */
142: /* ****************** End of setters and getters ********************** */
143: /* ******************************************************************** */
144:
145: /**
146: * A text file with the massaged contents of {@link #getExplanationText}
147: * is attached to the original message.
148: */
149: protected MimeBodyPart getWrapperBodyPart(Mail mail)
150: throws MessagingException, IOException {
151:
152: String explanationText = getExplanationText();
153:
154: // if there is no explanation text there should be no wrapping
155: if (explanationText == null) {
156: return null;
157: }
158:
159: MimeMessage originalMessage = mail.getMessage();
160:
161: MimeBodyPart messagePart = new MimeBodyPart();
162: MimeBodyPart signatureReason = new MimeBodyPart();
163:
164: String contentType = originalMessage.getContentType();
165: Object content = originalMessage.getContent();
166:
167: if (contentType != null && content != null) {
168: messagePart.setContent(content, contentType);
169: } else {
170: throw new MessagingException(
171: "Either the content type or the content is null");
172: }
173:
174: String headers = getMessageHeaders(originalMessage);
175:
176: signatureReason.setText(getReplacedExplanationText(
177: getExplanationText(), getSignerName(), getKeyHolder()
178: .getSignerAddress(), mail.getSender()
179: .toString(), headers));
180:
181: signatureReason.setFileName("SignatureExplanation.txt");
182:
183: MimeMultipart wrapperMultiPart = new MimeMultipart();
184:
185: wrapperMultiPart.addBodyPart(messagePart);
186: wrapperMultiPart.addBodyPart(signatureReason);
187:
188: MimeBodyPart wrapperBodyPart = new MimeBodyPart();
189:
190: wrapperBodyPart.setContent(wrapperMultiPart);
191:
192: return wrapperBodyPart;
193: }
194:
195: }
|