JAMES-1856 Rename crypto mailet package to mailets for name resolution
Project: http://git-wip-us.apache.org/repos/asf/james-project/repo Commit: http://git-wip-us.apache.org/repos/asf/james-project/commit/a72d89b4 Tree: http://git-wip-us.apache.org/repos/asf/james-project/tree/a72d89b4 Diff: http://git-wip-us.apache.org/repos/asf/james-project/diff/a72d89b4 Branch: refs/heads/master Commit: a72d89b47e5e2b4a49596286c49a8ba4754ad20c Parents: 2fb4458 Author: Benoit Tellier <[email protected]> Authored: Mon Nov 14 10:15:08 2016 +0700 Committer: Benoit Tellier <[email protected]> Committed: Thu Nov 17 15:26:18 2016 +0700 ---------------------------------------------------------------------- .../james/transport/mailet/AbstractSign.java | 714 ------------------- .../transport/mailet/SMIMECheckSignature.java | 228 ------ .../james/transport/mailet/SMIMEDecrypt.java | 169 ----- .../james/transport/mailet/SMIMESign.java | 216 ------ .../org/apache/james/transport/mailet/Sign.java | 207 ------ .../apache/james/transport/mailet/package.html | 21 - .../james/transport/mailets/AbstractSign.java | 714 +++++++++++++++++++ .../transport/mailets/SMIMECheckSignature.java | 228 ++++++ .../james/transport/mailets/SMIMEDecrypt.java | 169 +++++ .../james/transport/mailets/SMIMESign.java | 216 ++++++ .../apache/james/transport/mailets/Sign.java | 207 ++++++ .../apache/james/transport/mailets/package.html | 21 + 12 files changed, 1555 insertions(+), 1555 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/james-project/blob/a72d89b4/mailet/crypto/src/main/java/org/apache/james/transport/mailet/AbstractSign.java ---------------------------------------------------------------------- diff --git a/mailet/crypto/src/main/java/org/apache/james/transport/mailet/AbstractSign.java b/mailet/crypto/src/main/java/org/apache/james/transport/mailet/AbstractSign.java deleted file mode 100644 index 044572a..0000000 --- a/mailet/crypto/src/main/java/org/apache/james/transport/mailet/AbstractSign.java +++ /dev/null @@ -1,714 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - - - -package org.apache.james.transport.mailet; - -import org.apache.james.transport.KeyHolder; -import org.apache.james.transport.SMIMEAttributeNames; -import org.apache.mailet.base.GenericMailet; -import org.apache.mailet.Mail; -import org.apache.mailet.MailAddress; -import org.apache.mailet.base.RFC2822Headers; - -import javax.mail.MessagingException; -import javax.mail.Session; -import javax.mail.internet.InternetAddress; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; -import javax.mail.internet.ParseException; - -import java.io.IOException; -import java.util.Enumeration; -import java.lang.reflect.Constructor; - -/** - * <P>Abstract mailet providing common SMIME signature services. - * It can be subclassed to make authoring signing mailets simple. - * By extending it and overriding one or more of the following methods a new behaviour can - * be quickly created without the author having to address any issue other than - * the relevant one:</P> - * <ul> - * <li>{@link #initDebug}, {@link #setDebug} and {@link #isDebug} manage the debugging mode.</li> - * <li>{@link #initExplanationText}, {@link #setExplanationText} and {@link #getExplanationText} manage the text of - * an attachment that will be added to explain the meaning of this server-side signature.</li> - * <li>{@link #initKeyHolder}, {@link #setKeyHolder} and {@link #getKeyHolder} manage the {@link KeyHolder} object that will - * contain the keys and certificates and will do the crypto work.</li> - * <li>{@link #initPostmasterSigns}, {@link #setPostmasterSigns} and {@link #isPostmasterSigns} - * determines whether messages originated by the Postmaster will be signed or not.</li> - * <li>{@link #initRebuildFrom}, {@link #setRebuildFrom} and {@link #isRebuildFrom} - * determines whether the "From:" header will be rebuilt to neutralize the wrong behaviour of - * some MUAs like Microsoft Outlook Express.</li> - * <li>{@link #initSignerName}, {@link #setSignerName} and {@link #getSignerName} manage the name - * of the signer to be shown in the explanation text.</li> - * <li>{@link #isOkToSign} controls whether the mail can be signed or not.</li> - * <li>The abstract method {@link #getWrapperBodyPart} returns the massaged {@link javax.mail.internet.MimeBodyPart} - * that will be signed, or null if the message has to be signed "as is".</li> - * </ul> - * - * <P>Handles the following init parameters:</P> - * <ul> - * <li><keyHolderClass>: Sets the class of the KeyHolder object that will handle the cryptography functions, - * for example org.apache.james.security.SMIMEKeyHolder for SMIME.</li> - * <li><debug>: if <CODE>true</CODE> some useful information is logged. - * The default is <CODE>false</CODE>.</li> - * <li><keyStoreFileName>: the {@link java.security.KeyStore} full file name.</li> - * <li><keyStorePassword>: the <CODE>KeyStore</CODE> password. - * If given, it is used to check the integrity of the keystore data, - * otherwise, if null, the integrity of the keystore is not checked.</li> - * <li><keyAlias>: the alias name to use to search the Key using {@link java.security.KeyStore#getKey}. - * The default is to look for the first and only alias in the keystore; - * if zero or more than one is found a {@link java.security.KeyStoreException} is thrown.</li> - * <li><keyAliasPassword>: the alias password. The default is to use the <CODE>KeyStore</CODE> password. - * At least one of the passwords must be provided.</li> - * <li><keyStoreType>: the type of the keystore. The default will use {@link java.security.KeyStore#getDefaultType}.</li> - * <li><postmasterSigns>: if <CODE>true</CODE> the message will be signed even if the sender is the Postmaster. - * The default is <CODE>false</CODE>.</li></li> - * <li><rebuildFrom>: If <CODE>true</CODE> will modify the "From:" header. - * For more info see {@link #isRebuildFrom}. - * The default is <CODE>false</CODE>.</li> - * <li><signerName>: the name of the signer to be shown in the explanation text. - * The default is to use the "CN=" property of the signing certificate.</li> - * <li><explanationText>: the text of an explanation of the meaning of this server-side signature. - * May contain the following substitution patterns (see also {@link #getReplacedExplanationText}): - * <CODE>[signerName]</CODE>, <CODE>[signerAddress]</CODE>, <CODE>[reversePath]</CODE>, <CODE>[headers]</CODE>. - * It should be included in the signature. - * The actual presentation of the text depends on the specific concrete mailet subclass: - * see for example {@link SMIMESign}. - * The default is to not have any explanation text.</li> - * </ul> - * @version CVS $Revision$ $Date$ - * @since 2.2.1 - */ -public abstract class AbstractSign extends GenericMailet { - - private static final String HEADERS_PATTERN = "[headers]"; - - private static final String SIGNER_NAME_PATTERN = "[signerName]"; - - private static final String SIGNER_ADDRESS_PATTERN = "[signerAddress]"; - - private static final String REVERSE_PATH_PATTERN = "[reversePath]"; - - /** - * Holds value of property debug. - */ - private boolean debug; - - /** - * Holds value of property keyHolderClass. - */ - private Class<?> keyHolderClass; - - /** - * Holds value of property explanationText. - */ - private String explanationText; - - /** - * Holds value of property keyHolder. - */ - private KeyHolder keyHolder; - - /** - * Holds value of property postmasterSigns. - */ - private boolean postmasterSigns; - - /** - * Holds value of property rebuildFrom. - */ - private boolean rebuildFrom; - - /** - * Holds value of property signerName. - */ - private String signerName; - - /** - * Gets the expected init parameters. - * @return An array containing the parameter names allowed for this mailet. - */ - protected abstract String[] getAllowedInitParameters(); - - /* ******************************************************************** */ - /* ****************** Begin of setters and getters ******************** */ - /* ******************************************************************** */ - - /** - * Initializer for property debug. - */ - protected void initDebug() { - setDebug((getInitParameter("debug") == null) ? false : Boolean.valueOf(getInitParameter("debug"))); - } - - /** - * Getter for property debug. - * @return Value of property debug. - */ - public boolean isDebug() { - return this.debug; - } - - /** - * Setter for property debug. - * @param debug New value of property debug. - */ - public void setDebug(boolean debug) { - this.debug = debug; - } - - /** - * Initializer for property keyHolderClass. - */ - protected void initKeyHolderClass() throws MessagingException { - String keyHolderClassName = getInitParameter("keyHolderClass"); - if (keyHolderClassName == null) { - throw new MessagingException("<keyHolderClass> parameter missing."); - } - try { - setKeyHolderClass(Class.forName(keyHolderClassName)); - } catch (ClassNotFoundException cnfe) { - throw new MessagingException("The specified <keyHolderClass> does not exist: " + keyHolderClassName); - } - if (isDebug()) { - log("keyHolderClass: " + getKeyHolderClass()); - } - } - - /** - * Getter for property keyHolderClass. - * @return Value of property keyHolderClass. - */ - public Class<?> getKeyHolderClass() { - return this.keyHolderClass; - } - - /** - * Setter for property keyHolderClass. - * @param keyHolderClass New value of property keyHolderClass. - */ - public void setKeyHolderClass(Class<?> keyHolderClass) { - this.keyHolderClass = keyHolderClass; - } - - /** - * Initializer for property explanationText. - */ - protected void initExplanationText() { - setExplanationText(getInitParameter("explanationText")); - if (isDebug()) { - log("Explanation text:\r\n" + getExplanationText()); - } - } - - /** - * Getter for property explanationText. - * Text to be used in the SignatureExplanation.txt file. - * @return Value of property explanationText. - */ - public String getExplanationText() { - return this.explanationText; - } - - /** - * Setter for property explanationText. - * @param explanationText New value of property explanationText. - */ - public void setExplanationText(String explanationText) { - this.explanationText = explanationText; - } - - /** - * Initializer for property keyHolder. - */ - protected void initKeyHolder() throws Exception { - Constructor<?> keyHolderConstructor; - try { - keyHolderConstructor = keyHolderClass.getConstructor(new Class[] {String.class, String.class, String.class, String.class, String.class}); - } catch (NoSuchMethodException nsme) { - throw new MessagingException("The needed constructor does not exist: " - + keyHolderClass + "(String, String, String, String, String)"); - } - - - String keyStoreFileName = getInitParameter("keyStoreFileName"); - if (keyStoreFileName == null) { - throw new MessagingException("<keyStoreFileName> parameter missing."); - } - - String keyStorePassword = getInitParameter("keyStorePassword"); - if (keyStorePassword == null) { - throw new MessagingException("<keyStorePassword> parameter missing."); - } - String keyAliasPassword = getInitParameter("keyAliasPassword"); - if (keyAliasPassword == null) { - keyAliasPassword = keyStorePassword; - if (isDebug()) { - log("<keyAliasPassword> parameter not specified: will default to the <keyStorePassword> parameter."); - } - } - - String keyStoreType = getInitParameter("keyStoreType"); - if (keyStoreType == null) { - if (isDebug()) { - log("<keyStoreType> parameter not specified: the default will be as appropriate to the keyStore requested."); - } - } - - String keyAlias = getInitParameter("keyAlias"); - if (keyAlias == null) { - if (isDebug()) { - log("<keyAlias> parameter not specified: will look for the first one in the keystore."); - } - } - - if (isDebug()) { - StringBuilder logBuffer = - new StringBuilder(1024) - .append("KeyStore related parameters:") - .append(" keyStoreFileName=").append(keyStoreFileName) - .append(", keyStoreType=").append(keyStoreType) - .append(", keyAlias=").append(keyAlias) - .append(" "); - log(logBuffer.toString()); - } - - // Certificate preparation - Object[] parameters = {keyStoreFileName, keyStorePassword, keyAlias, keyAliasPassword, keyStoreType}; - setKeyHolder((KeyHolder)keyHolderConstructor.newInstance(parameters)); - - if (isDebug()) { - log("Subject Distinguished Name: " + getKeyHolder().getSignerDistinguishedName()); - } - - if (getKeyHolder().getSignerAddress() == null) { - throw new MessagingException("Signer address missing in the certificate."); - } - } - - /** - * Getter for property keyHolder. - * It is <CODE>protected</CODE> instead of <CODE>public</CODE> for security reasons. - * @return Value of property keyHolder. - */ - protected KeyHolder getKeyHolder() { - return this.keyHolder; - } - - /** - * Setter for property keyHolder. - * It is <CODE>protected</CODE> instead of <CODE>public</CODE> for security reasons. - * @param keyHolder New value of property keyHolder. - */ - protected void setKeyHolder(KeyHolder keyHolder) { - this.keyHolder = keyHolder; - } - - /** - * Initializer for property postmasterSigns. - */ - protected void initPostmasterSigns() { - setPostmasterSigns((getInitParameter("postmasterSigns") == null) ? false : Boolean.valueOf(getInitParameter("postmasterSigns"))); - } - - /** - * Getter for property postmasterSigns. - * If true will sign messages signed by the postmaster. - * @return Value of property postmasterSigns. - */ - public boolean isPostmasterSigns() { - return this.postmasterSigns; - } - - /** - * Setter for property postmasterSigns. - * @param postmasterSigns New value of property postmasterSigns. - */ - public void setPostmasterSigns(boolean postmasterSigns) { - this.postmasterSigns = postmasterSigns; - } - - /** - * Initializer for property rebuildFrom. - */ - protected void initRebuildFrom() throws MessagingException { - setRebuildFrom((getInitParameter("rebuildFrom") == null) ? false : Boolean.valueOf(getInitParameter("rebuildFrom"))); - if (isDebug()) { - if (isRebuildFrom()) { - log("Will modify the \"From:\" header."); - } else { - log("Will leave the \"From:\" header unchanged."); - } - } - } - - /** - * Getter for property rebuildFrom. - * If true will modify the "From:" header. - * <P>The modification is as follows: - * assuming that the signer mail address in the signer certificate is <I>[email protected]></I> - * and that <I>From: "John Smith" <[email protected]></I> - * we will get <I>From: "John Smith" <[email protected]>" <[email protected]></I>.</P> - * <P>If the "ReplyTo:" header is missing or empty it will be set to the original "From:" header.</P> - * <P>Such modification is necessary to achieve a correct behaviour - * with some mail clients (e.g. Microsoft Outlook Express).</P> - * @return Value of property rebuildFrom. - */ - public boolean isRebuildFrom() { - return this.rebuildFrom; - } - - /** - * Setter for property rebuildFrom. - * @param rebuildFrom New value of property rebuildFrom. - */ - public void setRebuildFrom(boolean rebuildFrom) { - this.rebuildFrom = rebuildFrom; - } - - /** - * Initializer for property signerName. - */ - protected void initSignerName() { - setSignerName(getInitParameter("signerName")); - if (getSignerName() == null) { - if (getKeyHolder() == null) { - throw new RuntimeException("initKeyHolder() must be invoked before initSignerName()"); - } - setSignerName(getKeyHolder().getSignerCN()); - if (isDebug()) { - log("<signerName> parameter not specified: will use the certificate signer \"CN=\" attribute."); - } - } - } - - /** - * Getter for property signerName. - * @return Value of property signerName. - */ - public String getSignerName() { - return this.signerName; - } - - /** - * Setter for property signerName. - * @param signerName New value of property signerName. - */ - public void setSignerName(String signerName) { - this.signerName = signerName; - } - - /* ******************************************************************** */ - /* ****************** End of setters and getters ********************** */ - /* ******************************************************************** */ - - /** - * Mailet initialization routine. - */ - public void init() throws MessagingException { - - // check that all init parameters have been declared in allowedInitParameters - checkInitParameters(getAllowedInitParameters()); - - try { - initDebug(); - if (isDebug()) { - log("Initializing"); - } - - initKeyHolderClass(); - initKeyHolder(); - initSignerName(); - initPostmasterSigns(); - initRebuildFrom(); - initExplanationText(); - - - } catch (MessagingException me) { - throw me; - } catch (Exception e) { - log("Exception thrown", e); - throw new MessagingException("Exception thrown", e); - } finally { - if (isDebug()) { - StringBuilder logBuffer = - new StringBuilder(1024) - .append("Other parameters:") - .append(", signerName=").append(getSignerName()) - .append(", postmasterSigns=").append(postmasterSigns) - .append(", rebuildFrom=").append(rebuildFrom) - .append(" "); - log(logBuffer.toString()); - } - } - - } - - /** - * Service does the hard work, and signs - * - * @param mail the mail to sign - * @throws MessagingException if a problem arises signing the mail - */ - public void service(Mail mail) throws MessagingException { - - try { - if (!isOkToSign(mail)) { - return; - } - - MimeBodyPart wrapperBodyPart = getWrapperBodyPart(mail); - - MimeMessage originalMessage = mail.getMessage(); - - // do it - MimeMultipart signedMimeMultipart; - if (wrapperBodyPart != null) { - signedMimeMultipart = getKeyHolder().generate(wrapperBodyPart); - } else { - signedMimeMultipart = getKeyHolder().generate(originalMessage); - } - - MimeMessage newMessage = new MimeMessage(Session.getDefaultInstance(System.getProperties(), - null)); - @SuppressWarnings("unchecked") - Enumeration<String> headerEnum = originalMessage.getAllHeaderLines(); - while (headerEnum.hasMoreElements()) { - newMessage.addHeaderLine((String) headerEnum.nextElement()); - } - - newMessage.setSender(new InternetAddress(getKeyHolder().getSignerAddress(), getSignerName())); - - if (isRebuildFrom()) { - // builds a new "mixed" "From:" header - InternetAddress modifiedFromIA = new InternetAddress(getKeyHolder().getSignerAddress(), mail.getSender().toString()); - newMessage.setFrom(modifiedFromIA); - - // if the original "ReplyTo:" header is missing sets it to the original "From:" header - newMessage.setReplyTo(originalMessage.getReplyTo()); - } - - newMessage.setContent(signedMimeMultipart, signedMimeMultipart.getContentType()); - String messageId = originalMessage.getMessageID(); - newMessage.saveChanges(); - if (messageId != null) { - newMessage.setHeader(RFC2822Headers.MESSAGE_ID, messageId); - } - - mail.setMessage(newMessage); - - // marks this mail as server-signed - mail.setAttribute(SMIMEAttributeNames.SMIME_SIGNING_MAILET, this.getClass().getName()); - // it is valid for us by definition (signed here by us) - mail.setAttribute(SMIMEAttributeNames.SMIME_SIGNATURE_VALIDITY, "valid"); - - // saves the trusted server signer address - // warning: should be same as the mail address in the certificate, but it is not guaranteed - mail.setAttribute(SMIMEAttributeNames.SMIME_SIGNER_ADDRESS, getKeyHolder().getSignerAddress()); - - if (isDebug()) { - log("Message signed, reverse-path: " + mail.getSender() + ", Id: " + messageId); - } - - } catch (MessagingException me) { - log("MessagingException found - could not sign!", me); - throw me; - } catch (Exception e) { - log("Exception found", e); - throw new MessagingException("Exception thrown - could not sign!", e); - } - - } - - - /** - * <P>Checks if the mail can be signed.</P> - * <P>Rules:</P> - * <OL> - * <LI>The reverse-path != null (it is not a bounce).</LI> - * <LI>The sender user must have been SMTP authenticated.</LI> - * <LI>Either:</LI> - * <UL> - * <LI>The reverse-path is the postmaster address and {@link #isPostmasterSigns} returns <I>true</I></LI> - * <LI>or the reverse-path == the authenticated user - * and there is at least one "From:" address == reverse-path.</LI>. - * </UL> - * <LI>The message has not already been signed (mimeType != <I>multipart/signed</I> - * and != <I>application/pkcs7-mime</I>).</LI> - * </OL> - * @param mail The mail object to check. - * @return True if can be signed. - */ - protected boolean isOkToSign(Mail mail) throws MessagingException { - - MailAddress reversePath = mail.getSender(); - - // Is it a bounce? - if (reversePath == null) { - return false; - } - - String authUser = (String) mail.getAttribute("org.apache.james.SMTPAuthUser"); - // was the sender user SMTP authorized? - if (authUser == null) { - return false; - } - - // The sender is the postmaster? - if (getMailetContext().getPostmaster().equals(reversePath)) { - // should not sign postmaster sent messages? - if (!isPostmasterSigns()) { - return false; - } - } else { - // is the reverse-path user different from the SMTP authorized user? - if (!reversePath.getLocalPart().equals(authUser)) { - return false; - } - // is there no "From:" address same as the reverse-path? - if (!fromAddressSameAsReverse(mail)) { - return false; - } - } - - - // if already signed return false - MimeMessage mimeMessage = mail.getMessage(); - return !(mimeMessage.isMimeType("multipart/signed") - || mimeMessage.isMimeType("application/pkcs7-mime")); - - } - - /** - * Creates the {@link javax.mail.internet.MimeBodyPart} that will be signed. - * For example, may attach a text file explaining the meaning of the signature, - * or an XML file containing information that can be checked by other MTAs. - * @param mail The mail to massage. - * @return The massaged MimeBodyPart to sign, or null to have the whole message signed "as is". - */ - protected abstract MimeBodyPart getWrapperBodyPart(Mail mail) throws MessagingException, IOException; - - /** - * Utility method that checks if there is at least one address in the "From:" header - * same as the <i>reverse-path</i>. - * @param mail The mail to check. - * @return True if an address is found, false otherwise. - */ - protected final boolean fromAddressSameAsReverse(Mail mail) { - - MailAddress reversePath = mail.getSender(); - - if (reversePath == null) { - return false; - } - - try { - InternetAddress[] fromArray = (InternetAddress[]) mail.getMessage().getFrom(); - if (fromArray != null) { - for (InternetAddress aFromArray : fromArray) { - MailAddress mailAddress; - try { - mailAddress = new MailAddress(aFromArray); - } catch (ParseException pe) { - log("Unable to parse a \"FROM\" header address: " + aFromArray.toString() + "; ignoring."); - continue; - } - if (mailAddress.equals(reversePath)) { - return true; - } - } - } - } catch (MessagingException me) { - log("Unable to parse the \"FROM\" header; ignoring."); - } - - return false; - - } - - /** - * Utility method for obtaining a string representation of the Message's headers - * @param message The message to extract the headers from. - * @return The string containing the headers. - */ - protected final String getMessageHeaders(MimeMessage message) throws MessagingException { - @SuppressWarnings("unchecked") - Enumeration<String> heads = message.getAllHeaderLines(); - StringBuilder headBuffer = new StringBuilder(1024); - while(heads.hasMoreElements()) { - headBuffer.append(heads.nextElement().toString()).append("\r\n"); - } - return headBuffer.toString(); - } - - /** - * Prepares the explanation text making substitutions in the <I>explanationText</I> template string. - * Utility method that searches for all occurrences of some pattern strings - * and substitute them with the appropriate params. - * @param explanationText The template string for the explanation text. - * @param signerName The string that will replace the <CODE>[signerName]</CODE> pattern. - * @param signerAddress The string that will replace the <CODE>[signerAddress]</CODE> pattern. - * @param reversePath The string that will replace the <CODE>[reversePath]</CODE> pattern. - * @param headers The string that will replace the <CODE>[headers]</CODE> pattern. - * @return The actual explanation text string with all replacements done. - */ - protected final String getReplacedExplanationText(String explanationText, String signerName, - String signerAddress, String reversePath, String headers) { - - String replacedExplanationText = explanationText; - - replacedExplanationText = getReplacedString(replacedExplanationText, SIGNER_NAME_PATTERN, signerName); - replacedExplanationText = getReplacedString(replacedExplanationText, SIGNER_ADDRESS_PATTERN, signerAddress); - replacedExplanationText = getReplacedString(replacedExplanationText, REVERSE_PATH_PATTERN, reversePath); - replacedExplanationText = getReplacedString(replacedExplanationText, HEADERS_PATTERN, headers); - - return replacedExplanationText; - } - - /** - * Searches the <I>template</I> String for all occurrences of the <I>pattern</I> string - * and creates a new String substituting them with the <I>actual</I> String. - * @param template The template String to work on. - * @param pattern The string to search for the replacement. - * @param actual The actual string to use for the replacement. - */ - private String getReplacedString(String template, String pattern, String actual) { - if (actual != null) { - StringBuilder sb = new StringBuilder(template.length()); - int fromIndex = 0; - int index; - while ((index = template.indexOf(pattern, fromIndex)) >= 0) { - sb.append(template.substring(fromIndex, index)); - sb.append(actual); - fromIndex = index + pattern.length(); - } - if (fromIndex < template.length()){ - sb.append(template.substring(fromIndex)); - } - return sb.toString(); - } else { - return template; - } - } - -} - http://git-wip-us.apache.org/repos/asf/james-project/blob/a72d89b4/mailet/crypto/src/main/java/org/apache/james/transport/mailet/SMIMECheckSignature.java ---------------------------------------------------------------------- diff --git a/mailet/crypto/src/main/java/org/apache/james/transport/mailet/SMIMECheckSignature.java b/mailet/crypto/src/main/java/org/apache/james/transport/mailet/SMIMECheckSignature.java deleted file mode 100644 index d7b34bd..0000000 --- a/mailet/crypto/src/main/java/org/apache/james/transport/mailet/SMIMECheckSignature.java +++ /dev/null @@ -1,228 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - - - -package org.apache.james.transport.mailet; - -import java.io.IOException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.List; - -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; - -import org.apache.james.transport.KeyStoreHolder; -import org.apache.james.transport.SMIMESignerInfo; -import org.apache.mailet.base.GenericMailet; -import org.apache.mailet.Mail; -import org.apache.mailet.MailetConfig; -import org.bouncycastle.cms.CMSException; -import org.bouncycastle.mail.smime.SMIMEException; -import org.bouncycastle.mail.smime.SMIMESigned; - -/** - * <p> - * Verifies the s/mime signature of a message. The s/mime signing ensure that - * the private key owner is the real sender of the message. To be checked by - * this mailet the s/mime signature must contain the actual signature, the - * signer's certificate and optionally a set of certificate that can be used to - * create a chain of trust that starts from the signer's certificate and leads - * to a known trusted certificate. - * </p> - * <p> - * This check is composed by two steps: firstly it's ensured that the signature - * is valid, then it's checked if a chain of trust starting from the signer - * certificate and that leads to a trusted certificate can be created. The first - * check verifies that the the message has not been modified after the signature - * was put and that the signer's certificate was valid at the time of the - * signing. The latter should ensure that the signer is who he declare to be. - * </p> - * <p> - * The results of the checks perfomed by this mailet are wrote as a mail - * attribute which default name is org.apache.james.SMIMECheckSignature (it can - * be changed using the mailet parameter <code>mailAttribute</code>). After - * the check this attribute will contain a list of SMIMESignerInfo object, one - * for each message's signer. These objects contain the signer's certificate and - * the trust path. - * </p> - * <p> - * Optionally, specifying the parameter <code>strip</code>, the signature of - * the message can be stripped after the check. The message will become a - * standard message without an attached s/mime signature. - * </p> - * <p> - * The configuration parameter of this mailet are summerized below. The firsts - * defines the location, the format and the password of the keystore containing - * the certificates that are considered trusted. Note: only the trusted certificate - * entries are read, the key ones are not. - * <ul> - * <li>keyStoreType (default: jks): Certificate store format . "jks" is the - * standard java certificate store format, but pkcs12 is also quite common and - * compatible with standard email clients like Outlook Express and Thunderbird. - * <li>keyStoreFileName (default: JAVA_HOME/jre/lib/security/cacert): Certificate - * store path. - * <li>keyStorePassword (default: ""): Certificate store password. - * </ul> - * Other parameters configure the behavior of the mailet: - * <ul> - * <li>strip (default: false): Defines if the s/mime signature of the message - * have to be stripped after the check or not. Possible values are true and - * false. - * <li>mailAttribute (default: org.apache.james.SMIMECheckSignature): - * specifies in which attribute the check results will be written. - * <li>onlyTrusted (default: true): Usually a message signature to be - * considered by this mailet as authentic must be valid and trusted. Setting - * this mailet parameter to "false" the last condition is relaxed and also - * "untrusted" signature are considered will be considered as authentic. - * </ul> - * </p> - * - */ -public class SMIMECheckSignature extends GenericMailet { - - protected KeyStoreHolder trustedCertificateStore; - - protected boolean stripSignature = false; - protected boolean onlyTrusted = true; - - protected String mailAttribute = "org.apache.james.SMIMECheckSignature"; - - public SMIMECheckSignature() { - super(); - - } - - public void init() throws MessagingException { - MailetConfig config = getMailetConfig(); - - String stripSignatureConf = config.getInitParameter("strip"); - if (stripSignatureConf != null) stripSignature = Boolean.valueOf(stripSignatureConf); - - String onlyTrustedConf = config.getInitParameter("onlyTrusted"); - if (onlyTrustedConf != null) onlyTrusted = Boolean.valueOf(onlyTrustedConf); - - String mailAttributeConf = config.getInitParameter("mailAttribute"); - if (mailAttributeConf != null) mailAttribute = mailAttributeConf; - - - String type = config.getInitParameter("keyStoreType"); - String file = config.getInitParameter("keyStoreFileName"); - String password = config.getInitParameter("keyStorePassword"); - - try { - if (file != null) trustedCertificateStore = new KeyStoreHolder(file, password, type); - else { - log("No trusted store path specified, using default store."); - trustedCertificateStore = new KeyStoreHolder(password); - } - } catch (Exception e) { - throw new MessagingException("Error loading the trusted certificate store", e); - } - - } - /** - * @see org.apache.mailet.Matcher#match(org.apache.mailet.Mail) - */ - public void service(Mail mail) throws MessagingException { - // I extract the MimeMessage from the mail object and I check if the - // mime type of the mail is one of the mime types that can contain a - // signature. - MimeMessage message = mail.getMessage(); - - // strippedMessage will contain the signed content of the message - MimeBodyPart strippedMessage =null; - - List<SMIMESignerInfo> signers=null; - - try { - Object obj = message.getContent(); - SMIMESigned signed; - if (obj instanceof MimeMultipart) signed = new SMIMESigned((MimeMultipart)message.getContent()); - else if (obj instanceof SMIMESigned) signed = (SMIMESigned) obj; - else if (obj instanceof byte[]) signed = new SMIMESigned(message); - else signed = null; - - if (signed != null) { - signers = trustedCertificateStore.verifySignatures(signed); - strippedMessage = signed.getContent(); - } else log("Content not identified as signed"); - - // These errors are logged but they don't cause the - // message to change its state. The message - // is considered as not signed and the process will - // go on. - } catch (CMSException e) { - log("Error during the analysis of the signed message", e); - signers = null; - } catch (IOException e) { - log("IO error during the analysis of the signed message", e); - signers = null; - } catch (SMIMEException e) { - log("Error during the analysis of the signed message", e); - signers = null; - } catch (Exception e) { - e.printStackTrace(); - log("Generic error occured during the analysis of the message", e); - signers = null; - } - - // If at least one mail signer is found - // the mail attributes are set. - if (signers != null) { - ArrayList<X509Certificate> signerinfolist = new ArrayList<X509Certificate>(); - - for (SMIMESignerInfo info : signers) { - if (info.isSignValid() - && (!onlyTrusted || info.getCertPath() != null)) { - signerinfolist.add(info.getSignerCertificate()); - } - } - - if (signerinfolist.size() > 0) { - mail.setAttribute(mailAttribute, signerinfolist); - } else { - // if no valid signers are found the message is not modified. - strippedMessage = null; - } - } - - if (stripSignature && strippedMessage != null) { - try { - Object obj = strippedMessage.getContent(); - if (obj instanceof Multipart) { - message.setContent((Multipart) obj); - } else { - message.setContent(obj, strippedMessage.getContentType()); - } - message.saveChanges(); - mail.setMessage(message); - } catch (Exception e) { - throw new MessagingException( - "Error during the extraction of the signed content from the message.", - e); - } - } - } - -} http://git-wip-us.apache.org/repos/asf/james-project/blob/a72d89b4/mailet/crypto/src/main/java/org/apache/james/transport/mailet/SMIMEDecrypt.java ---------------------------------------------------------------------- diff --git a/mailet/crypto/src/main/java/org/apache/james/transport/mailet/SMIMEDecrypt.java b/mailet/crypto/src/main/java/org/apache/james/transport/mailet/SMIMEDecrypt.java deleted file mode 100644 index 2d24e6c..0000000 --- a/mailet/crypto/src/main/java/org/apache/james/transport/mailet/SMIMEDecrypt.java +++ /dev/null @@ -1,169 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - - - -package org.apache.james.transport.mailet; - -import java.io.IOException; -import java.security.GeneralSecurityException; -import java.security.cert.X509Certificate; -import java.util.ArrayList; -import java.util.Collection; - -import javax.mail.MessagingException; -import javax.mail.Multipart; -import javax.mail.Part; -import javax.mail.internet.MimeMessage; - -import org.apache.james.transport.SMIMEKeyHolder; -import org.apache.mailet.Mail; -import org.apache.mailet.MailetConfig; -import org.apache.mailet.base.GenericMailet; -import org.bouncycastle.cms.CMSException; -import org.bouncycastle.cms.RecipientId; -import org.bouncycastle.cms.RecipientInformation; -import org.bouncycastle.cms.RecipientInformationStore; -import org.bouncycastle.cms.jcajce.JceKeyTransEnvelopedRecipient; -import org.bouncycastle.mail.smime.SMIMEEnveloped; -import org.bouncycastle.mail.smime.SMIMEUtil; - -/** - * This mailet decrypts a s/mime encrypted message. It takes as input an - * encrypted message and it tries to dechiper it using the key specified in its - * configuration. If the decryption is successful the mail will be changed and - * it will contain the decrypted message. The mail attribute - * <code>org.apache.james.SMIMEDecrypt</code> will contain the public - * certificate of the key used in the process. - * - * The configuration parameters of this mailet are summarized below. The firsts - * define the keystore where the key that will be used to decrypt messages is - * saved. - * <ul> - * <li>keyStoreType (default: system dependent): defines the type of the store. - * Usually jks, pkcs12 or pkcs7</li> - * <li>keyStoreFileName (mandatory): private key store path.</li> - * <li>keyStorePassword (default: ""): private key store password</li> - * </ul> - * The other parameters define which private key have to be used. (if the store - * contains more than one key). - * <ul> - * <li>keyAlias: private key alias.</li> - * <li>keyPass: private key password</li> - * </ul> - * - */ -public class SMIMEDecrypt extends GenericMailet { - - private SMIMEKeyHolder keyHolder; - protected String mailAttribute = "org.apache.james.SMIMEDecrypt"; - - public void init() throws MessagingException { - super.init(); - - MailetConfig config = getMailetConfig(); - - String privateStoreType = config.getInitParameter("keyStoreType"); - - String privateStoreFile = config.getInitParameter("keyStoreFileName"); - if (privateStoreFile == null) throw new MessagingException("No keyStoreFileName specified"); - - String privateStorePass = config.getInitParameter("keyStorePassword"); - - String keyAlias= config.getInitParameter("keyAlias"); - String keyPass = config.getInitParameter("keyAliasPassword"); - - String mailAttributeConf = config.getInitParameter("mailAttribute"); - if (mailAttributeConf != null) mailAttribute = mailAttributeConf; - - try { - keyHolder = new SMIMEKeyHolder(privateStoreFile, privateStorePass, keyAlias, keyPass, privateStoreType); - } catch (IOException e) { - throw new MessagingException("Error loading keystore", e); - } catch (GeneralSecurityException e) { - throw new MessagingException("Error loading keystore", e); - } - - - } - - /** - * @see org.apache.mailet.Mailet#service(org.apache.mailet.Mail) - */ - public void service(Mail mail) throws MessagingException { - MimeMessage message = mail.getMessage(); - Part strippedMessage = null; - log("Starting message decryption.."); - if (message.isMimeType("application/x-pkcs7-mime") || message.isMimeType("application/pkcs7-mime")) { - try { - SMIMEEnveloped env = new SMIMEEnveloped(message); - RecipientInformationStore informationStore = env.getRecipientInfos(); - @SuppressWarnings("unchecked") - Collection<RecipientInformation> recipients = informationStore.getRecipients(); - for (RecipientInformation info : recipients) { - RecipientId id = info.getRID(); - if (id.match(keyHolder.getCertificate())) { - try { - JceKeyTransEnvelopedRecipient recipient = new JceKeyTransEnvelopedRecipient(keyHolder.getPrivateKey()); - // strippedMessage contains the decrypted message. - strippedMessage = SMIMEUtil.toMimeBodyPart(info.getContent(recipient)); - log("Encrypted message decrypted"); - } catch (Exception e) { - throw new MessagingException("Error during the decryption of the message", e); - } - } else { - log("Found an encrypted message but it isn't encrypted for the supplied key"); - } - } - } catch (CMSException e) { - throw new MessagingException("Error during the decryption of the message",e); - } - } - - // if the decryption has been successful.. - if (strippedMessage != null) { - // I put the private key's public certificate as a mailattribute. - // I create a list of certificate because I want to minic the - // behavior of the SMIMEVerifySignature mailet. In that way - // it is possible to reuse the same matchers to analyze - // the result of the operation. - ArrayList<X509Certificate> list = new ArrayList<X509Certificate>(1); - list.add(keyHolder.getCertificate()); - mail.setAttribute(mailAttribute, list); - - // I start the message stripping. - try { - MimeMessage newmex = new MimeMessage(message); - Object obj = strippedMessage.getContent(); - if (obj instanceof Multipart) { - log("The message is multipart, content type "+((Multipart)obj).getContentType()); - newmex.setContent((Multipart)obj); - } else { - newmex.setContent(obj, strippedMessage.getContentType()); - newmex.setDisposition(null); - } - newmex.saveChanges(); - mail.setMessage(newmex); - } catch (IOException e) { - log("Error during the strip of the encrypted message"); - throw new MessagingException("Error during the stripping of the encrypted message",e); - } - } - } -} http://git-wip-us.apache.org/repos/asf/james-project/blob/a72d89b4/mailet/crypto/src/main/java/org/apache/james/transport/mailet/SMIMESign.java ---------------------------------------------------------------------- diff --git a/mailet/crypto/src/main/java/org/apache/james/transport/mailet/SMIMESign.java b/mailet/crypto/src/main/java/org/apache/james/transport/mailet/SMIMESign.java deleted file mode 100644 index 5972e6a..0000000 --- a/mailet/crypto/src/main/java/org/apache/james/transport/mailet/SMIMESign.java +++ /dev/null @@ -1,216 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - - - -package org.apache.james.transport.mailet; - -import org.apache.mailet.Mail; - -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; - -import java.io.IOException; - -/** - * <p>Puts a <I>server-side</I> SMIME signature on a message. - * It is a concrete subclass of {@link Sign}, with very few modifications to it, - * to specialize for SMIME.</p> - * - * <P>Handles the following init parameters (will comment only the differences from {@link AbstractSign}):</P> - * <ul> - * <li><debug>.</li> - * <li><keyStoreFileName>.</li> - * <li><keyStorePassword>.</li> - * <li><keyAlias>.</li> - * <li><keyAliasPassword>.</li> - * <li><keyStoreType>.</li> - * <li><postmasterSigns>. The default is <CODE>true</CODE>.</li> - * <li><rebuildFrom>. The default is <CODE>true</CODE>.</li> - * <li><signerName>.</li> - * <li><explanationText>. There is a default explanation string template in English, - * displaying also all the headers of the original message (see {@link #getExplanationText}).</li> - * </ul> - * @version CVS $Revision$ $Date$ - * @since 2.3.0 - */ -public class SMIMESign extends Sign { - - /** - * Return a string describing this mailet. - * - * @return a string describing this mailet - */ - public String getMailetInfo() { - return "SMIME Signature Mailet"; - } - - /** - * - */ - protected String[] getAllowedInitParameters() { - return new String[]{ - "debug", - "keyStoreFileName", - "keyStorePassword", - "keyStoreType", - "keyAlias", - "keyAliasPassword", - "signerName", - "postmasterSigns", - "rebuildFrom", - "explanationText" - }; - } - - /* ******************************************************************** */ - /* ****************** Begin of setters and getters ******************** */ - /* ******************************************************************** */ - - /** - * Gets text offering an explanation. - * If the <CODE><explanationText></CODE> init parameter is missing - * returns the following default explanation template string: - * <pre><code> - * The message this file is attached to has been signed on the server by - * "[signerName]" <[signerAddress]> - * to certify that the sender is known and truly has the following address (reverse-path): - * [reversePath] - * and that the original message has the following message headers: - * - * [headers] - * - * The signature envelopes this attachment too. - * Please check the signature integrity. - * - * "[signerName]" <[signerAddress]> - * </code></pre> - */ - public String getExplanationText() { - String explanationText = super.getExplanationText(); - if (explanationText == null) { - explanationText = "The message this file is attached to has been signed on the server by\r\n" - + "\t\"[signerName]\" <[signerAddress]>" - + "\r\nto certify that the sender is known and truly has the following address (reverse-path):\r\n" - + "\t[reversePath]" - + "\r\nand that the original message has the following message headers:\r\n" - + "\r\n[headers]" - + "\r\n\r\nThe signature envelopes this attachment too." - + "\r\nPlease check the signature integrity." - + "\r\n\r\n" - + "\t\"[signerName]\" <[signerAddress]>"; - } - - return explanationText; - } - - /** - * Initializer for property keyHolderClass. - * Hardcodes it to {@link org.apache.james.transport.SMIMEKeyHolder}. - */ - protected void initKeyHolderClass() throws MessagingException { - String keyHolderClassName = "org.apache.james.security.SMIMEKeyHolder"; - try { - setKeyHolderClass(Class.forName(keyHolderClassName)); - } catch (ClassNotFoundException cnfe) { - throw new MessagingException(keyHolderClassName + "does not exist."); - } - if (isDebug()) { - log("keyHolderClass: " + getKeyHolderClass()); - } - } - - /** - * If the <CODE><postmasterSigns></CODE> init parameter is missing sets it to <I>true</I>. - */ - protected void initPostmasterSigns() { - setPostmasterSigns((getInitParameter("postmasterSigns") == null) ? true : Boolean.valueOf(getInitParameter("postmasterSigns"))); - } - - /** - * If the <CODE><rebuildFrom></CODE> init parameter is missing sets it to <I>true</I>. - */ - protected void initRebuildFrom() throws MessagingException { - setRebuildFrom((getInitParameter("rebuildFrom") == null) ? true : Boolean.valueOf(getInitParameter("rebuildFrom"))); - if (isDebug()) { - if (isRebuildFrom()) { - log("Will modify the \"From:\" header."); - } else { - log("Will leave the \"From:\" header unchanged."); - } - } - } - - /* ******************************************************************** */ - /* ****************** End of setters and getters ********************** */ - /* ******************************************************************** */ - - /** - * A text file with the massaged contents of {@link #getExplanationText} - * is attached to the original message. - */ - protected MimeBodyPart getWrapperBodyPart(Mail mail) throws MessagingException, IOException { - - String explanationText = getExplanationText(); - - // if there is no explanation text there should be no wrapping - if (explanationText == null) { - return null; - } - - MimeMessage originalMessage = mail.getMessage(); - - MimeBodyPart messagePart = new MimeBodyPart(); - MimeBodyPart signatureReason = new MimeBodyPart(); - - String contentType = originalMessage.getContentType(); - Object content = originalMessage.getContent(); - - if (contentType != null && content != null) { - messagePart.setContent(content, contentType); - } else { - throw new MessagingException("Either the content type or the content is null"); - } - - String headers = getMessageHeaders(originalMessage); - - signatureReason.setText(getReplacedExplanationText(getExplanationText(), - getSignerName(), - getKeyHolder().getSignerAddress(), - mail.getSender().toString(), - headers)); - - signatureReason.setFileName("SignatureExplanation.txt"); - - MimeMultipart wrapperMultiPart = new MimeMultipart(); - - wrapperMultiPart.addBodyPart(messagePart); - wrapperMultiPart.addBodyPart(signatureReason); - - MimeBodyPart wrapperBodyPart = new MimeBodyPart(); - - wrapperBodyPart.setContent(wrapperMultiPart); - - return wrapperBodyPart; - } - -} - http://git-wip-us.apache.org/repos/asf/james-project/blob/a72d89b4/mailet/crypto/src/main/java/org/apache/james/transport/mailet/Sign.java ---------------------------------------------------------------------- diff --git a/mailet/crypto/src/main/java/org/apache/james/transport/mailet/Sign.java b/mailet/crypto/src/main/java/org/apache/james/transport/mailet/Sign.java deleted file mode 100644 index 98cade8..0000000 --- a/mailet/crypto/src/main/java/org/apache/james/transport/mailet/Sign.java +++ /dev/null @@ -1,207 +0,0 @@ -/**************************************************************** - * Licensed to the Apache Software Foundation (ASF) under one * - * or more contributor license agreements. See the NOTICE file * - * distributed with this work for additional information * - * regarding copyright ownership. The ASF licenses this file * - * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 * - * * - * Unless required by applicable law or agreed to in writing, * - * software distributed under the License is distributed on an * - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * - * KIND, either express or implied. See the License for the * - * specific language governing permissions and limitations * - * under the License. * - ****************************************************************/ - - - -package org.apache.james.transport.mailet; - -import org.apache.mailet.Mail; - -import javax.mail.MessagingException; -import javax.mail.internet.MimeBodyPart; -import javax.mail.internet.MimeMessage; -import javax.mail.internet.MimeMultipart; - -import java.io.IOException; - -/** - * <p>Puts a <I>server-side</I> signature on a message. - * It is a concrete subclass of {@link AbstractSign}, with very few modifications to it.</p> - * <p>A text file with an explanation text is attached to the original message, - * and the resulting message with all its attachments is signed. - * The resulting appearence of the message is almost unchanged: only an extra attachment - * and the signature are added.</p> - *<p>The kind of signuture depends on the value of the <keyHolderClass> init parameter. - * - * <P>Handles the following init parameters (will comment only the differences from {@link AbstractSign}):</P> - * <ul> - * <li><keyHolderClass>: Sets the class of the KeyHolder object that will handle the cryptography functions, - * for example org.apache.james.security.SMIMEKeyHolder for SMIME.</li> - * <li><debug>.</li> - * <li><keyStoreFileName>.</li> - * <li><keyStorePassword>.</li> - * <li><keyAlias>.</li> - * <li><keyAliasPassword>.</li> - * <li><keyStoreType>.</li> - * <li><postmasterSigns>. The default is <CODE>true</CODE>.</li> - * <li><rebuildFrom>. The default is <CODE>true</CODE>.</li> - * <li><signerName>.</li> - * <li><explanationText>. There is a default explanation string template in English, - * displaying also all the headers of the original message (see {@link #getExplanationText}).</li> - * </ul> - * @version CVS $Revision$ $Date$ - * @since 2.2.1 - */ -public class Sign extends AbstractSign { - - /** - * Return a string describing this mailet. - * - * @return a string describing this mailet - */ - public String getMailetInfo() { - return "Signature Mailet"; - } - - /** - * - */ - protected String[] getAllowedInitParameters() { - return new String[]{ - "keyHolderClass", - "debug", - "keyStoreFileName", - "keyStorePassword", - "keyStoreType", - "keyAlias", - "keyAliasPassword", - "signerName", - "postmasterSigns", - "rebuildFrom", - "explanationText" - }; - } - - /* ******************************************************************** */ - /* ****************** Begin of setters and getters ******************** */ - /* ******************************************************************** */ - - /** - * Gets text offering an explanation. - * If the <CODE><explanationText></CODE> init parameter is missing - * returns the following default explanation template string: - * <pre><code> - * The message this file is attached to has been signed on the server by - * "[signerName]" <[signerAddress]> - * to certify that the sender is known and truly has the following address (reverse-path): - * [reversePath] - * and that the original message has the following message headers: - * - * [headers] - * - * The signature envelopes this attachment too. - * Please check the signature integrity. - * - * "[signerName]" <[signerAddress]> - * </code></pre> - */ - public String getExplanationText() { - String explanationText = super.getExplanationText(); - if (explanationText == null) { - explanationText = "The message this file is attached to has been signed on the server by\r\n" - + "\t\"[signerName]\" <[signerAddress]>" - + "\r\nto certify that the sender is known and truly has the following address (reverse-path):\r\n" - + "\t[reversePath]" - + "\r\nand that the original message has the following message headers:\r\n" - + "\r\n[headers]" - + "\r\n\r\nThe signature envelopes this attachment too." - + "\r\nPlease check the signature integrity." - + "\r\n\r\n" - + "\t\"[signerName]\" <[signerAddress]>"; - } - - return explanationText; - } - - /** - * If the <CODE><postmasterSigns></CODE> init parameter is missing sets it to <I>true</I>. - */ - protected void initPostmasterSigns() { - setPostmasterSigns((getInitParameter("postmasterSigns") == null) ? true : Boolean.valueOf(getInitParameter("postmasterSigns"))); - } - - /** - * If the <CODE><rebuildFrom></CODE> init parameter is missing sets it to <I>true</I>. - */ - protected void initRebuildFrom() throws MessagingException { - setRebuildFrom((getInitParameter("rebuildFrom") == null) ? true : Boolean.valueOf(getInitParameter("rebuildFrom"))); - if (isDebug()) { - if (isRebuildFrom()) { - log("Will modify the \"From:\" header."); - } else { - log("Will leave the \"From:\" header unchanged."); - } - } - } - - /* ******************************************************************** */ - /* ****************** End of setters and getters ********************** */ - /* ******************************************************************** */ - - /** - * A text file with the massaged contents of {@link #getExplanationText} - * is attached to the original message. - */ - protected MimeBodyPart getWrapperBodyPart(Mail mail) throws MessagingException, IOException { - - String explanationText = getExplanationText(); - - // if there is no explanation text there should be no wrapping - if (explanationText == null) { - return null; - } - - MimeMessage originalMessage = mail.getMessage(); - - MimeBodyPart messagePart = new MimeBodyPart(); - MimeBodyPart signatureReason = new MimeBodyPart(); - - String contentType = originalMessage.getContentType(); - Object content = originalMessage.getContent(); - - if (contentType != null && content != null) { - messagePart.setContent(content, contentType); - } else { - throw new MessagingException("Either the content type or the content is null"); - } - - String headers = getMessageHeaders(originalMessage); - - signatureReason.setText(getReplacedExplanationText(getExplanationText(), - getSignerName(), - getKeyHolder().getSignerAddress(), - mail.getSender().toString(), - headers)); - - signatureReason.setFileName("SignatureExplanation.txt"); - - MimeMultipart wrapperMultiPart = new MimeMultipart(); - - wrapperMultiPart.addBodyPart(messagePart); - wrapperMultiPart.addBodyPart(signatureReason); - - MimeBodyPart wrapperBodyPart = new MimeBodyPart(); - - wrapperBodyPart.setContent(wrapperMultiPart); - - return wrapperBodyPart; - } - -} - http://git-wip-us.apache.org/repos/asf/james-project/blob/a72d89b4/mailet/crypto/src/main/java/org/apache/james/transport/mailet/package.html ---------------------------------------------------------------------- diff --git a/mailet/crypto/src/main/java/org/apache/james/transport/mailet/package.html b/mailet/crypto/src/main/java/org/apache/james/transport/mailet/package.html deleted file mode 100644 index 2dcfc17..0000000 --- a/mailet/crypto/src/main/java/org/apache/james/transport/mailet/package.html +++ /dev/null @@ -1,21 +0,0 @@ -<!-- - Licensed to the Apache Software Foundation (ASF) under one - or more contributor license agreements. See the NOTICE file - distributed with this work for additional information - regarding copyright ownership. The ASF licenses this file - to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 - - Unless required by applicable law or agreed to in writing, - software distributed under the License is distributed on an - "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - KIND, either express or implied. See the License for the - specific language governing permissions and limitations - under the License. ---> -<body> -<p>Cryptographic mail processing agents.</p> -</body> --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
