net.markenwerk.utils.mail.dkim.DkimMessage Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of utils-mail-dkim Show documentation
Show all versions of utils-mail-dkim Show documentation
A DKIM library for JavaMail
/*
* Copyright (c) 2015 Torsten Krause, Markenwerk GmbH.
*
* This file is part of 'A DKIM library for JavaMail', hereafter
* called 'this library', identified by the following coordinates:
*
* groupID: net.markenwerk
* artifactId: utils-mail-dkim
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*
* See the LICENSE and NOTICE files in the root directory for further
* information.
*
* This file incorporates work covered by the following copyright and
* permission notice:
*
* Copyright 2008 The Apache Software Foundation or its licensors, as
* applicable.
*
* Licensed 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.
*
* A licence was granted to the ASF by Florian Sager on 30 November 2008
*/
package net.markenwerk.utils.mail.dkim;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.OutputStream;
import java.util.Enumeration;
import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeUtility;
import com.sun.mail.smtp.SMTPMessage;
import net.markenwerk.utils.data.fetcher.BufferedFetcher;
/**
* Extension of SMTPMessage for the inclusion of a DKIM signature.
*
* @author Torsten Krause (tk at markenwerk dot net)
* @author Florian Sager
* @since 1.0.0
*/
public class DkimMessage extends SMTPMessage {
private static byte[] NL = { (byte) '\r', (byte) '\n' };
private DkimSigner signer;
private String encodedBody;
/**
* Created a new {@code DkimMessage} from the given {@link MimeMessage} and
* {@link DkimSigner}.
*
* @param message
* The {@link MimeMessage} to be signed.
* @param signer
* The {@link DkimSigner} to sign the message with.
* @throws MessagingException
* If constructing this {@code DkimMessage} failed.
*/
public DkimMessage(MimeMessage message, DkimSigner signer) throws MessagingException {
super(message);
this.signer = signer;
}
/**
* Output the message as an RFC 822 format stream, without specified
* headers. If the saved
flag is not set, the
* saveChanges
method is called. If the modified
* flag is not set and the content
array is not null, the
* content
array is written directly, after writing the
* appropriate message headers.
*
* This method enhances the JavaMail method
* {@link MimeMessage#writeTo(OutputStream, String[])} See the according Sun
* license, this contribution is CDDL.
*
* @exception MessagingException
* @exception IOException
* if an error occurs writing to the stream or if an error is
* generated by the javax.activation layer.
*/
@Override
public void writeTo(OutputStream os, String[] ignoreList) throws IOException, MessagingException {
// inside saveChanges it is assured that content encodings are set in
// all parts of the body
if (!saved) {
saveChanges();
}
ByteArrayOutputStream bodyBuffer = new ByteArrayOutputStream();
if (modified) {
// write out the body from the dataHandler through the
// encodingOutputStream into the bodyBuffer
OutputStream encodingOutputStream = MimeUtility.encode(bodyBuffer, getEncoding());
getDataHandler().writeTo(encodingOutputStream);
encodingOutputStream.flush();
encodingOutputStream.close();
} else if (null == content) {
// write the provided contentStream into the bodyBuffer
new BufferedFetcher().copy(getContentStream(), bodyBuffer, true, false);
bodyBuffer.flush();
bodyBuffer.close();
} else {
// just write the readily available content into the bodyBuffer
bodyBuffer.write(content);
bodyBuffer.flush();
bodyBuffer.close();
}
encodedBody = bodyBuffer.toString();
// second, sign the message
String signatureHeaderLine = signer.sign(this);
// write the 'DKIM-Signature' header, all other headers and a clear \r\n
writeln(os, signatureHeaderLine);
@SuppressWarnings("unchecked")
Enumeration headerLines = getNonMatchingHeaderLines(ignoreList);
while (headerLines.hasMoreElements()) {
writeln(os, headerLines.nextElement());
}
writeln(os);
os.flush();
// write the message body
os.write(bodyBuffer.toByteArray());
os.flush();
}
protected String getEncodedBody() {
return encodedBody;
}
@Override
public void setAllow8bitMIME(boolean allow) {
// don't allow to switch to 8-bit MIME, instead 7-bit ASCII should be
// kept because in forwarding scenarios a change to
// Content-Transfer-Encoding to 7-bit ASCII breaks the DKIM signature
super.setAllow8bitMIME(false);
}
private static void writeln(OutputStream out) throws IOException {
out.write(NL);
}
private static void writeln(OutputStream out, String string) throws IOException {
byte[] bytes = getBytes(string);
out.write(bytes);
out.write(NL);
}
private static byte[] getBytes(String string) {
char[] chars = string.toCharArray();
byte[] bytes = new byte[chars.length];
for (int i = 0, n = chars.length; i < n; i++) {
bytes[i] = (byte) chars[i];
}
return bytes;
}
}
© 2015 - 2024 Weber Informatics LLC | Privacy Policy