Author: norman Date: Tue Jul 12 17:40:49 2011 New Revision: 1145691 URL: http://svn.apache.org/viewvc?rev=1145691&view=rev Log: Add support for encrypted Headers and Body of the message when using JPA. This work is a modified version of the classes attached to MAILBOX-102. Thanks again to Valluripalli, Sai for the code. We love contributions :)
Added: james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/EncryptDecryptHelper.java james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAEncryptedMessage.java Modified: james/mailbox/trunk/jpa/pom.xml james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java james/mailbox/trunk/pom.xml Modified: james/mailbox/trunk/jpa/pom.xml URL: http://svn.apache.org/viewvc/james/mailbox/trunk/jpa/pom.xml?rev=1145691&r1=1145690&r2=1145691&view=diff ============================================================================== --- james/mailbox/trunk/jpa/pom.xml (original) +++ james/mailbox/trunk/jpa/pom.xml Tue Jul 12 17:40:49 2011 @@ -48,7 +48,10 @@ <groupId>${javax.mail.groupId}</groupId> <artifactId>${javax.mail.artifactId}</artifactId> </dependency> - + <dependency> + <groupId>org.jasypt</groupId> + <artifactId>jasypt</artifactId> + </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit-dep</artifactId> @@ -100,7 +103,7 @@ </property> <property> <name>metaDataFactory</name> - <value>jpa(Types=org.apache.james.mailbox.jpa.mail.model.JPAUserFlag;org.apache.james.mailbox.jpa.mail.model.JPAHeader;org.apache.james.mailbox.jpa.mail.model.JPAMailbox;org.apache.james.mailbox.jpa.mail.model.openjpa.AbstractJPAMessage;org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMessage;org.apache.james.mailbox.jpa.mail.model.openjpa.JPAStreamingMessage;org.apache.james.mailbox.jpa.mail.model.JPAProperty;org.apache.james.mailbox.jpa.user.model.JPASubscription)</value> + <value>jpa(Types=org.apache.james.mailbox.jpa.mail.model.JPAUserFlag;org.apache.james.mailbox.jpa.mail.model.JPAMailbox;org.apache.james.mailbox.jpa.mail.model.openjpa.AbstractJPAMessage;org.apache.james.mailbox.jpa.mail.model.openjpa.JPAEncryptedMessage;org.apache.james.mailbox.jpa.mail.model.openjpa.JPAMessage;org.apache.james.mailbox.jpa.mail.model.openjpa.JPAStreamingMessage;org.apache.james.mailbox.jpa.mail.model.JPAProperty;org.apache.james.mailbox.jpa.user.model.JPASubscription)</value> </property> </toolProperties> </configuration> Added: james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/EncryptDecryptHelper.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/EncryptDecryptHelper.java?rev=1145691&view=auto ============================================================================== --- james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/EncryptDecryptHelper.java (added) +++ james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/EncryptDecryptHelper.java Tue Jul 12 17:40:49 2011 @@ -0,0 +1,66 @@ +/**************************************************************** + * 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.mailbox.jpa.mail.model.openjpa; + +import org.jasypt.encryption.pbe.StandardPBEByteEncryptor; + +/** + * Helper class for encrypt and de-crypt data + * + * + */ +public class EncryptDecryptHelper { + + // Use one static instance as it is thread safe + private static StandardPBEByteEncryptor encryptor = new StandardPBEByteEncryptor(); + + + /** + * Set the password for encrypt / de-crypt. This MUST be done before + * the usage of {@link #getDecrypted(byte[])} and {@link #getEncrypted(byte[])}. + * + * So to be safe its the best to call this in a constructor + * + * @param pass + */ + public static void init(String pass) { + encryptor.setPassword(pass); + } + + /** + * Encrypt the given array and return the encrypted one + * + * @param array + * @return enc-array + */ + public static byte[] getEncrypted(byte[] array) { + return encryptor.encrypt(array); + } + + /** + * Decrypt the given array and return the de-crypted one + * + * @param array + * @return dec-array + */ + public static byte[] getDecrypted(byte[] array) { + return encryptor.decrypt(array); + } + +} Added: james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAEncryptedMessage.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAEncryptedMessage.java?rev=1145691&view=auto ============================================================================== --- james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAEncryptedMessage.java (added) +++ james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/mail/model/openjpa/JPAEncryptedMessage.java Tue Jul 12 17:40:49 2011 @@ -0,0 +1,115 @@ +/**************************************************************** + * 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.mailbox.jpa.mail.model.openjpa; + +import java.io.ByteArrayInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.Date; + +import javax.mail.Flags; +import javax.mail.internet.SharedInputStream; +import javax.persistence.Basic; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.FetchType; +import javax.persistence.Lob; +import javax.persistence.Table; + +import org.apache.commons.io.IOUtils; +import org.apache.james.mailbox.MailboxException; +import org.apache.james.mailbox.jpa.mail.model.JPAMailbox; +import org.apache.james.mailbox.store.mail.model.Message; +import org.apache.james.mailbox.store.mail.model.impl.PropertyBuilder; +import org.apache.openjpa.persistence.Externalizer; +import org.apache.openjpa.persistence.Factory; + +@Entity(name="Message") +@Table(name="JAMES_MAIL") +public class JPAEncryptedMessage extends AbstractJPAMessage { + + /** The value for the body field. Lazy loaded */ + /** We use a max length to represent 1gb data. Thats prolly overkill, but who knows */ + @Basic(optional = false, fetch = FetchType.LAZY) + @Column(name = "MAIL_BYTES", length = 1048576000, nullable = false) + @Externalizer("EncryptDecryptHelper.getEncrypted") + @Factory("EncryptDecryptHelper.getDecrypted") + @Lob private byte[] body; + + + /** The value for the header field. Lazy loaded */ + /** We use a max length to represent 1gb data. Thats prolly overkill, but who knows */ + @Basic(optional = false, fetch = FetchType.LAZY) + @Column(name = "HEADER_BYTES", length = 10485760, nullable = false) + @Externalizer("EncryptDecryptHelper.getEncrypted") + @Factory("EncryptDecryptHelper.getDecrypted") + @Lob private byte[] header; + + @Deprecated + public JPAEncryptedMessage() {} + + public JPAEncryptedMessage(JPAMailbox mailbox,Date internalDate, int size, Flags flags, SharedInputStream content, int bodyStartOctet, final PropertyBuilder propertyBuilder) throws MailboxException { + super(mailbox, internalDate, flags, size ,bodyStartOctet, propertyBuilder); + try { + int headerEnd = bodyStartOctet -2; + if (headerEnd < 0) { + headerEnd = 0; + } + this.header = IOUtils.toByteArray(content.newStream(0, headerEnd)); + this.body = IOUtils.toByteArray(content.newStream(getBodyStartOctet(), -1)); + + } catch (IOException e) { + throw new MailboxException("Unable to parse message",e); + } + } + + /** + * Create a copy of the given message + * + * @param message + * @throws MailboxException + */ + public JPAEncryptedMessage(JPAMailbox mailbox, long uid, long modSeq, Message<?> message) throws MailboxException{ + super(mailbox, uid, modSeq, message); + try { + this.body = IOUtils.toByteArray(message.getBodyContent()); + this.header = IOUtils.toByteArray(message.getHeaderContent()); + } catch (IOException e) { + throw new MailboxException("Unable to parse message",e); + } + } + + + /* + * (non-Javadoc) + * @see org.apache.james.mailbox.store.mail.model.Message#getBodyContent() + */ + public InputStream getBodyContent() throws IOException { + return new ByteArrayInputStream(body); + } + + /* + * (non-Javadoc) + * @see org.apache.james.mailbox.store.mail.model.Message#getHeaderContent() + */ + public InputStream getHeaderContent() throws IOException { + return new ByteArrayInputStream(header); + } + +} Modified: james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java?rev=1145691&r1=1145690&r2=1145691&view=diff ============================================================================== --- james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java (original) +++ james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMailboxManager.java Tue Jul 12 17:40:49 2011 @@ -25,6 +25,8 @@ import org.apache.james.mailbox.MailboxP import org.apache.james.mailbox.MailboxSession; import org.apache.james.mailbox.jpa.JPAMailboxManager; import org.apache.james.mailbox.jpa.JPAMailboxSessionMapperFactory; +import org.apache.james.mailbox.jpa.mail.model.openjpa.EncryptDecryptHelper; +import org.apache.james.mailbox.jpa.openjpa.OpenJPAMessageManager.AdvancedFeature; import org.apache.james.mailbox.store.Authenticator; import org.apache.james.mailbox.store.JVMMailboxPathLocker; import org.apache.james.mailbox.store.StoreMessageManager; @@ -36,20 +38,34 @@ import org.apache.james.mailbox.store.ma */ public class OpenJPAMailboxManager extends JPAMailboxManager { - private boolean useStreaming; + private AdvancedFeature feature; public OpenJPAMailboxManager(JPAMailboxSessionMapperFactory mapperFactory, Authenticator authenticator, MailboxPathLocker locker, boolean useStreaming) { super(mapperFactory, authenticator, locker); - this.useStreaming = useStreaming; + if (useStreaming) { + feature = AdvancedFeature.Streaming; + } else { + feature = AdvancedFeature.None; + } } + public OpenJPAMailboxManager(JPAMailboxSessionMapperFactory mapperFactory, Authenticator authenticator, MailboxPathLocker locker, String encryptPass) { + super(mapperFactory, authenticator, locker); + if (encryptPass != null) { + EncryptDecryptHelper.init(encryptPass); + feature = AdvancedFeature.Encryption; + } else { + feature = AdvancedFeature.None; + } + } + public OpenJPAMailboxManager(JPAMailboxSessionMapperFactory mapperFactory, Authenticator authenticator) { this(mapperFactory, authenticator, new JVMMailboxPathLocker(), false); } @Override protected StoreMessageManager<Long> createMessageManager(Mailbox<Long> mailboxRow, MailboxSession session) throws MailboxException { - StoreMessageManager<Long> result = new OpenJPAMessageManager(getMapperFactory(), getMessageSearchIndex(), getEventDispatcher(), mailboxRow, useStreaming); + StoreMessageManager<Long> result = new OpenJPAMessageManager(getMapperFactory(), getMessageSearchIndex(), getEventDispatcher(), mailboxRow, feature); return result; } } Modified: james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java URL: http://svn.apache.org/viewvc/james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java?rev=1145691&r1=1145690&r2=1145691&view=diff ============================================================================== --- james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java (original) +++ james/mailbox/trunk/jpa/src/main/java/org/apache/james/mailbox/jpa/openjpa/OpenJPAMessageManager.java Tue Jul 12 17:40:49 2011 @@ -27,6 +27,7 @@ import javax.mail.internet.SharedInputSt import org.apache.james.mailbox.MailboxException; import org.apache.james.mailbox.jpa.JPAMessageManager; import org.apache.james.mailbox.jpa.mail.model.JPAMailbox; +import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAEncryptedMessage; import org.apache.james.mailbox.jpa.mail.model.openjpa.JPAStreamingMessage; import org.apache.james.mailbox.store.MailboxEventDispatcher; import org.apache.james.mailbox.store.MailboxSessionMapperFactory; @@ -40,30 +41,40 @@ import org.apache.james.mailbox.store.se */ public class OpenJPAMessageManager extends JPAMessageManager { - private final boolean useStreaming; + private final AdvancedFeature feature; + public static enum AdvancedFeature { + None, + Streaming, + Encryption + } + public OpenJPAMessageManager(MailboxSessionMapperFactory<Long> mapperFactory, MessageSearchIndex<Long> index, MailboxEventDispatcher<Long> dispatcher, Mailbox<Long> mailbox) throws MailboxException { - this(mapperFactory, index, dispatcher, mailbox, false); + this(mapperFactory, index, dispatcher, mailbox, AdvancedFeature.None); } public OpenJPAMessageManager(MailboxSessionMapperFactory<Long> mapperFactory, MessageSearchIndex<Long> index, - MailboxEventDispatcher<Long> dispatcher, Mailbox<Long> mailbox, final boolean useStreaming) throws MailboxException { + MailboxEventDispatcher<Long> dispatcher, Mailbox<Long> mailbox, final AdvancedFeature f) throws MailboxException { super(mapperFactory, index, dispatcher, mailbox); - this.useStreaming = useStreaming; + this.feature = f; } @Override protected Message<Long> createMessage(Date internalDate, int size, int bodyStartOctet, SharedInputStream content, Flags flags, PropertyBuilder propertyBuilder) throws MailboxException { - if (useStreaming) { - int headerEnd = bodyStartOctet -2; - if (headerEnd < 0) { - headerEnd = 0; - } + int headerEnd = bodyStartOctet -2; + if (headerEnd < 0) { + headerEnd = 0; + } + switch (feature) { + case Streaming: return new JPAStreamingMessage((JPAMailbox) getMailboxEntity(), internalDate, size, flags, content, bodyStartOctet, propertyBuilder); - } else { + case Encryption: + return new JPAEncryptedMessage((JPAMailbox) getMailboxEntity(), internalDate, size, flags, content, bodyStartOctet, propertyBuilder); + default: return super.createMessage(internalDate, size, bodyStartOctet, content, flags, propertyBuilder); } + } Modified: james/mailbox/trunk/pom.xml URL: http://svn.apache.org/viewvc/james/mailbox/trunk/pom.xml?rev=1145691&r1=1145690&r2=1145691&view=diff ============================================================================== --- james/mailbox/trunk/pom.xml (original) +++ james/mailbox/trunk/pom.xml Tue Jul 12 17:40:49 2011 @@ -715,6 +715,11 @@ <artifactId>geronimo-jpa_2.0_spec</artifactId> <version>1.1</version> </dependency> + <dependency> + <groupId>org.jasypt</groupId> + <artifactId>jasypt</artifactId> + <version>1.7.1</version> + </dependency> <!-- END OpenJPA --------------------------------------------------------------------- To unsubscribe, e-mail: server-dev-unsubscr...@james.apache.org For additional commands, e-mail: server-dev-h...@james.apache.org