diff --git a/modules/core-module/src/main/java/org/simplejavamail/api/email/EmailPopulatingBuilder.java b/modules/core-module/src/main/java/org/simplejavamail/api/email/EmailPopulatingBuilder.java
index 36afe4bdd..685c03aa1 100644
--- a/modules/core-module/src/main/java/org/simplejavamail/api/email/EmailPopulatingBuilder.java
+++ b/modules/core-module/src/main/java/org/simplejavamail/api/email/EmailPopulatingBuilder.java
@@ -1,12 +1,12 @@
package org.simplejavamail.api.email;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.simplejavamail.api.internal.clisupport.model.Cli;
import org.simplejavamail.api.internal.clisupport.model.CliBuilderApiType;
import org.simplejavamail.api.mailer.config.Pkcs12Config;
import javax.activation.DataSource;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.mail.Message;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
@@ -1127,10 +1127,12 @@ public interface EmailPopulatingBuilder {
* Signs this email with an S/MIME signature, so the receiving client
* can verify whether the email content was tampered with.
*
- * Note: this only works in combination with the {@value org.simplejavamail.internal.modules.SMIMEModule#NAME}.
+ * Note: this only works in combination with the {@value org.simplejavamail.internal.modules.SMIMEModule#NAME}.
+ * Note: You can also configure your Mailer
instance do sign all emails by default (also has better performance).
*
* @see S/MIME on Wikipedia
* @see Primer on S/MIME
+ * @see org.simplejavamail.api.mailer.MailerGenericBuilder#signByDefaultWithSmime(Pkcs12Config)
*/
@Cli.ExcludeApi(reason = "delegated method contains CLI compatible arguments")
EmailPopulatingBuilder signWithSmime(@NotNull Pkcs12Config pkcs12Config);
diff --git a/modules/core-module/src/main/java/org/simplejavamail/api/mailer/Mailer.java b/modules/core-module/src/main/java/org/simplejavamail/api/mailer/Mailer.java
index e81ff2828..83729f0aa 100644
--- a/modules/core-module/src/main/java/org/simplejavamail/api/mailer/Mailer.java
+++ b/modules/core-module/src/main/java/org/simplejavamail/api/mailer/Mailer.java
@@ -2,19 +2,19 @@
import org.hazlewood.connor.bottema.emailaddress.EmailAddressCriteria;
import org.hazlewood.connor.bottema.emailaddress.EmailAddressValidator;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.simplejavamail.MailException;
import org.simplejavamail.api.email.Email;
+import org.simplejavamail.api.mailer.config.EmailGovernance;
import org.simplejavamail.api.mailer.config.OperationalConfig;
import org.simplejavamail.api.mailer.config.ProxyConfig;
import org.simplejavamail.api.mailer.config.ServerConfig;
import org.simplejavamail.api.mailer.config.TransportStrategy;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.mail.Message;
import javax.mail.Session;
import javax.mail.Transport;
-import java.util.EnumSet;
import java.util.concurrent.Future;
/**
@@ -148,10 +148,8 @@ public interface Mailer {
OperationalConfig getOperationalConfig();
/**
- * @return The effective validation criteria used for email validation. Returns an empty set if no validation should be done.
- * @see MailerGenericBuilder#withEmailAddressCriteria(EnumSet)
- * @see EmailAddressCriteria
+ * @return The effective governance applied to each email (default S/MIME signing, email addresscriteria for validation etc.).
*/
@NotNull
- EnumSet getEmailAddressCriteria();
+ EmailGovernance getEmailGovernance();
}
diff --git a/modules/core-module/src/main/java/org/simplejavamail/api/mailer/MailerGenericBuilder.java b/modules/core-module/src/main/java/org/simplejavamail/api/mailer/MailerGenericBuilder.java
index 84b4c3e0b..47da2ae11 100644
--- a/modules/core-module/src/main/java/org/simplejavamail/api/mailer/MailerGenericBuilder.java
+++ b/modules/core-module/src/main/java/org/simplejavamail/api/mailer/MailerGenericBuilder.java
@@ -1,14 +1,17 @@
package org.simplejavamail.api.mailer;
import org.hazlewood.connor.bottema.emailaddress.EmailAddressCriteria;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.simplejavamail.api.internal.clisupport.model.Cli;
import org.simplejavamail.api.internal.clisupport.model.CliBuilderApiType;
import org.simplejavamail.api.mailer.config.LoadBalancingStrategy;
+import org.simplejavamail.api.mailer.config.Pkcs12Config;
import org.simplejavamail.api.mailer.config.TransportStrategy;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.mail.Session;
+import java.io.File;
+import java.io.InputStream;
import java.util.EnumSet;
import java.util.List;
import java.util.Map;
@@ -226,6 +229,53 @@ public interface MailerGenericBuilder> {
*/
T withEmailAddressCriteria(@NotNull EnumSet emailAddressCriteria);
+ /**
+ * Signs this all emails by default with an S/MIME signature, so the receiving client
+ * can verify whether the email content was tampered with.
+ *
+ * Note: this only works in combination with the {@value org.simplejavamail.internal.modules.SMIMEModule#NAME}.
+ *
+ * @see S/MIME on Wikipedia
+ * @see Primer on S/MIME
+ * @see org.simplejavamail.api.email.EmailPopulatingBuilder#signWithSmime(Pkcs12Config)
+ * @see #clearSignByDefaultWithSmime()
+ */
+ @Cli.ExcludeApi(reason = "delegated method contains CLI compatible arguments")
+ T signByDefaultWithSmime(@NotNull Pkcs12Config pkcs12Config);
+
+ /**
+ * Delegates to {@link #signByDefaultWithSmime(InputStream, String, String, String)}.
+ *
+ * Note: this only works in combination with the {@value org.simplejavamail.internal.modules.SMIMEModule#NAME}.
+ *
+ * @param pkcs12StoreFile The key store file to use to find the indicated key
+ * @param storePassword The store's password
+ * @param keyAlias The name of the certificate in the key store to use
+ * @param keyPassword The password of the certificate
+ */
+ T signByDefaultWithSmime(@NotNull File pkcs12StoreFile, @NotNull String storePassword, @NotNull String keyAlias, @NotNull String keyPassword);
+
+ /**
+ * Delegates to {@link #signByDefaultWithSmime(byte[], String, String, String)}.
+ *
+ * Note: this only works in combination with the {@value org.simplejavamail.internal.modules.SMIMEModule#NAME}.
+ */
+ @Cli.ExcludeApi(reason = "Is duplicate API from CLI point of view")
+ T signByDefaultWithSmime(@NotNull InputStream pkcs12StoreStream, @NotNull String storePassword, @NotNull String keyAlias, @NotNull String keyPassword);
+
+ /**
+ * Delegates to {@link #signByDefaultWithSmime(Pkcs12Config)}.
+ *
+ * Note: this only works in combination with the {@value org.simplejavamail.internal.modules.SMIMEModule#NAME}.
+ *
+ * @param pkcs12StoreData The key store file to use to find the indicated key
+ * @param storePassword The store's password
+ * @param keyAlias The name of the certificate in the key store to use
+ * @param keyPassword The password of the certificate
+ */
+ @Cli.ExcludeApi(reason = "Is duplicate API from CLI point of view")
+ T signByDefaultWithSmime(@NotNull byte[] pkcs12StoreData, @NotNull String storePassword, @NotNull String keyAlias, @NotNull String keyPassword);
+
/**
* For advanced use cases.
*
@@ -580,6 +630,13 @@ public interface MailerGenericBuilder> {
*/
T clearEmailAddressCriteria();
+ /**
+ * Removes S/MIME signing, so emails won't be signed by default.
+ *
+ * @see #signByDefaultWithSmime(Pkcs12Config)
+ */
+ T clearSignByDefaultWithSmime();
+
/**
* Removes all trusted hosts from the list.
*
@@ -651,6 +708,13 @@ public interface MailerGenericBuilder> {
@Nullable
EnumSet getEmailAddressCriteria();
+ /**
+ * @see #signByDefaultWithSmime(Pkcs12Config)
+ * @see #signByDefaultWithSmime(InputStream, String, String, String)
+ */
+ @Nullable
+ Pkcs12Config getPkcs12ConfigForSmimeSigning();
+
/**
* Returns the user set ExecutorService or else null as the default ExecutorService is not created until the {@link org.simplejavamail.api.mailer.config.OperationalConfig} is created for the
* new {@link Mailer} instance.
diff --git a/modules/core-module/src/main/java/org/simplejavamail/api/mailer/config/EmailGovernance.java b/modules/core-module/src/main/java/org/simplejavamail/api/mailer/config/EmailGovernance.java
new file mode 100644
index 000000000..0f68041b7
--- /dev/null
+++ b/modules/core-module/src/main/java/org/simplejavamail/api/mailer/config/EmailGovernance.java
@@ -0,0 +1,36 @@
+package org.simplejavamail.api.mailer.config;
+
+import org.hazlewood.connor.bottema.emailaddress.EmailAddressCriteria;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.simplejavamail.api.email.EmailPopulatingBuilder;
+import org.simplejavamail.api.mailer.MailerGenericBuilder;
+
+import java.io.InputStream;
+import java.util.EnumSet;
+
+/**
+ * Governance for all emails being sent through the current {@link org.simplejavamail.api.mailer.Mailer} instance.
+ *
+ * In simpeler terms: this class represents actions taken or configuration used by default for each individual email sent through the current mailer. For example, you might want to S/MIME sign all
+ * emails by default. You can do it manually on each email of course, but then the keystore used for this not reused.
+ */
+public interface EmailGovernance {
+
+ /**
+ * @return The effective validation criteria used for email validation. Returns an empty set if no validation should be done.
+ * @see MailerGenericBuilder#withEmailAddressCriteria(EnumSet)
+ * @see EmailAddressCriteria
+ */
+ @NotNull
+ EnumSet getEmailAddressCriteria();
+
+ /**
+ * @see EmailPopulatingBuilder#signWithSmime(Pkcs12Config)
+ * @see EmailPopulatingBuilder#signWithSmime(InputStream, String, String, String)
+ * @see MailerGenericBuilder#signByDefaultWithSmime(Pkcs12Config)
+ * @see MailerGenericBuilder#signByDefaultWithSmime(InputStream, String, String, String)
+ */
+ @Nullable
+ Pkcs12Config getPkcs12ConfigForSmimeSigning();
+}
diff --git a/modules/core-module/src/main/java/org/simplejavamail/internal/modules/SMIMEModule.java b/modules/core-module/src/main/java/org/simplejavamail/internal/modules/SMIMEModule.java
index 3f523d2bf..a299169ce 100644
--- a/modules/core-module/src/main/java/org/simplejavamail/internal/modules/SMIMEModule.java
+++ b/modules/core-module/src/main/java/org/simplejavamail/internal/modules/SMIMEModule.java
@@ -1,5 +1,7 @@
package org.simplejavamail.internal.modules;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.simplejavamail.api.email.AttachmentResource;
import org.simplejavamail.api.email.Email;
import org.simplejavamail.api.email.OriginalSmimeDetails;
@@ -9,8 +11,6 @@
import org.simplejavamail.api.internal.smimesupport.model.SmimeDetails;
import org.simplejavamail.api.mailer.config.Pkcs12Config;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimePart;
@@ -70,7 +70,8 @@ public interface SMIMEModule {
boolean verifyValidSignature(@NotNull MimeMessage mimeMessage, @NotNull OriginalSmimeDetails messageSmimeDetails);
@NotNull
- MimeMessage signAndOrEncryptEmail(@NotNull final Session session, @NotNull final MimeMessage messageToProtect, @NotNull final Email emailContainingSmimeDetails);
+ MimeMessage signAndOrEncryptEmail(@NotNull final Session session, @NotNull final MimeMessage messageToProtect, @NotNull final Email emailContainingSmimeDetails,
+ @Nullable final Pkcs12Config defaultSmimeSigningStore);
@NotNull
MimeMessage signMessage(@Nullable Session session, @NotNull MimeMessage message, @NotNull Pkcs12Config pkcs12Config);
diff --git a/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/EmailConverter.java b/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/EmailConverter.java
index 197055915..d2a78044c 100644
--- a/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/EmailConverter.java
+++ b/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/EmailConverter.java
@@ -428,11 +428,29 @@ public static MimeMessage emailToMimeMessage(@NotNull final Email email) {
}
/**
- * Refer to {@link MimeMessageProducerHelper#produceMimeMessage(Email, Session)}.
+ * Refer to {@link MimeMessageProducerHelper#produceMimeMessage(Email, Session, Pkcs12Config)}.
+ */
+ public static MimeMessage emailToMimeMessage(@NotNull final Email email, @NotNull final Session session, @NotNull final Pkcs12Config defaultSmimeSigningStore) {
+ try {
+ return MimeMessageProducerHelper.produceMimeMessage(
+ checkNonEmptyArgument(email, "email"),
+ checkNonEmptyArgument(session, "session"),
+ checkNonEmptyArgument(defaultSmimeSigningStore, "defaultSmimeSigningStore"));
+ } catch (UnsupportedEncodingException | MessagingException e) {
+ // this should never happen, so we don't acknowledge this exception (and simply bubble up)
+ throw new IllegalStateException(e.getMessage(), e);
+ }
+ }
+
+ /**
+ * Delegates to {@link MimeMessageProducerHelper#produceMimeMessage(Email, Session, Pkcs12Config)} with empty S/MIME signing store.
*/
public static MimeMessage emailToMimeMessage(@NotNull final Email email, @NotNull final Session session) {
try {
- return MimeMessageProducerHelper.produceMimeMessage(checkNonEmptyArgument(email, "email"), checkNonEmptyArgument(session, "session"));
+ return MimeMessageProducerHelper.produceMimeMessage(
+ checkNonEmptyArgument(email, "email"),
+ checkNonEmptyArgument(session, "session"),
+ null);
} catch (UnsupportedEncodingException | MessagingException e) {
// this should never happen, so we don't acknowledge this exception (and simply bubble up)
throw new IllegalStateException(e.getMessage(), e);
diff --git a/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageProducer.java b/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageProducer.java
index 9fe2bd889..ff35684de 100644
--- a/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageProducer.java
+++ b/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageProducer.java
@@ -1,10 +1,11 @@
package org.simplejavamail.converter.internal.mimemessage;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.simplejavamail.api.email.Email;
+import org.simplejavamail.api.mailer.config.Pkcs12Config;
import org.simplejavamail.internal.modules.ModuleLoader;
-import org.jetbrains.annotations.NotNull;
-
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
@@ -37,7 +38,7 @@ public abstract class MimeMessageProducer {
*/
abstract boolean compatibleWithEmail(@NotNull Email email);
- final MimeMessage populateMimeMessage(@NotNull final Email email, @NotNull Session session)
+ final MimeMessage populateMimeMessage(@NotNull final Email email, @NotNull Session session, @Nullable final Pkcs12Config defaultSmimeSigningStore)
throws MessagingException, UnsupportedEncodingException {
checkArgumentNotEmpty(email, "email is missing");
checkArgumentNotEmpty(session, "session is needed, it cannot be attached later");
@@ -80,7 +81,7 @@ public String toString() {
3. DKIM signing
*/
if (ModuleLoader.smimeModuleAvailable()) {
- message = ModuleLoader.loadSmimeModule().signAndOrEncryptEmail(session, message, email);
+ message = ModuleLoader.loadSmimeModule().signAndOrEncryptEmail(session, message, email, defaultSmimeSigningStore);
}
if (!valueNullOrEmpty(email.getDkimSigningDomain())) {
diff --git a/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageProducerHelper.java b/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageProducerHelper.java
index 136597568..3cd10a3f8 100644
--- a/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageProducerHelper.java
+++ b/modules/simple-java-mail/src/main/java/org/simplejavamail/converter/internal/mimemessage/MimeMessageProducerHelper.java
@@ -1,8 +1,10 @@
package org.simplejavamail.converter.internal.mimemessage;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.simplejavamail.api.email.Email;
+import org.simplejavamail.api.mailer.config.Pkcs12Config;
-import org.jetbrains.annotations.NotNull;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
@@ -34,10 +36,10 @@ public final class MimeMessageProducerHelper {
private MimeMessageProducerHelper() {
}
- public static MimeMessage produceMimeMessage(@NotNull Email email, @NotNull Session session) throws UnsupportedEncodingException, MessagingException {
+ public static MimeMessage produceMimeMessage(@NotNull Email email, @NotNull Session session, @Nullable final Pkcs12Config defaultSmimeSigningStore) throws UnsupportedEncodingException, MessagingException {
for (MimeMessageProducer mimeMessageProducer : mimeMessageProducers) {
if (mimeMessageProducer.compatibleWithEmail(email)) {
- return mimeMessageProducer.populateMimeMessage(email, session);
+ return mimeMessageProducer.populateMimeMessage(email, session, defaultSmimeSigningStore);
}
}
throw new IllegalStateException("no compatible MimeMessageProducer found for email");
diff --git a/modules/simple-java-mail/src/main/java/org/simplejavamail/email/internal/EmailPopulatingBuilderImpl.java b/modules/simple-java-mail/src/main/java/org/simplejavamail/email/internal/EmailPopulatingBuilderImpl.java
index 6a887c9ab..06123d4ca 100644
--- a/modules/simple-java-mail/src/main/java/org/simplejavamail/email/internal/EmailPopulatingBuilderImpl.java
+++ b/modules/simple-java-mail/src/main/java/org/simplejavamail/email/internal/EmailPopulatingBuilderImpl.java
@@ -73,10 +73,6 @@
import static org.simplejavamail.config.ConfigLoader.Property.EMBEDDEDIMAGES_DYNAMICRESOLUTION_OUTSIDE_BASE_DIR;
import static org.simplejavamail.config.ConfigLoader.Property.EMBEDDEDIMAGES_DYNAMICRESOLUTION_OUTSIDE_BASE_URL;
import static org.simplejavamail.config.ConfigLoader.Property.SMIME_ENCRYPTION_CERTIFICATE;
-import static org.simplejavamail.config.ConfigLoader.Property.SMIME_SIGNING_KEYSTORE;
-import static org.simplejavamail.config.ConfigLoader.Property.SMIME_SIGNING_KEYSTORE_PASSWORD;
-import static org.simplejavamail.config.ConfigLoader.Property.SMIME_SIGNING_KEY_ALIAS;
-import static org.simplejavamail.config.ConfigLoader.Property.SMIME_SIGNING_KEY_PASSWORD;
import static org.simplejavamail.config.ConfigLoader.getBooleanProperty;
import static org.simplejavamail.config.ConfigLoader.getProperty;
import static org.simplejavamail.config.ConfigLoader.getStringProperty;
@@ -366,14 +362,6 @@ public class EmailPopulatingBuilderImpl implements InternalEmailPopulatingBuilde
if (hasProperty(DEFAULT_SUBJECT)) {
withSubject((String) getProperty(DEFAULT_SUBJECT));
}
- if (hasProperty(SMIME_SIGNING_KEYSTORE)) {
- signWithSmime(Pkcs12Config.builder()
- .pkcs12Store(assumeNonNull(getStringProperty(SMIME_SIGNING_KEYSTORE)))
- .storePassword(checkNonEmptyArgument(getStringProperty(SMIME_SIGNING_KEYSTORE_PASSWORD), "Keystore password property"))
- .keyAlias(checkNonEmptyArgument(getStringProperty(SMIME_SIGNING_KEY_ALIAS), "Key alias property"))
- .keyPassword(checkNonEmptyArgument(getStringProperty(SMIME_SIGNING_KEY_PASSWORD), "Key password property"))
- .build());
- }
if (hasProperty(SMIME_ENCRYPTION_CERTIFICATE)) {
encryptWithSmime(assumeNonNull(getStringProperty(SMIME_ENCRYPTION_CERTIFICATE)));
}
diff --git a/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/MailerHelper.java b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/MailerHelper.java
index cc8065b6c..9acc4414b 100644
--- a/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/MailerHelper.java
+++ b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/MailerHelper.java
@@ -8,6 +8,7 @@
import org.simplejavamail.api.email.AttachmentResource;
import org.simplejavamail.api.email.Email;
import org.simplejavamail.api.email.Recipient;
+import org.simplejavamail.api.mailer.config.Pkcs12Config;
import org.simplejavamail.internal.modules.ModuleLoader;
import org.slf4j.Logger;
@@ -139,11 +140,11 @@ public static MimeMessage signMessageWithDKIM(@NotNull final MimeMessage message
/**
* Depending on the Email configuration, signs and then encrypts message (both steps optional), using the S/MIME module.
*
- * @see org.simplejavamail.internal.modules.SMIMEModule#signAndOrEncryptEmail(Session, MimeMessage, Email)
+ * @see org.simplejavamail.internal.modules.SMIMEModule#signAndOrEncryptEmail(Session, MimeMessage, Email, Pkcs12Config)
*/
@SuppressWarnings("unused")
- public static MimeMessage signAndOrEncryptMessageWithSmime(@NotNull final Session session, @NotNull final MimeMessage messageToProtect, @NotNull final Email emailContainingSmimeDetails) {
+ public static MimeMessage signAndOrEncryptMessageWithSmime(@NotNull final Session session, @NotNull final MimeMessage messageToProtect, @NotNull final Email emailContainingSmimeDetails, @Nullable final Pkcs12Config defaultSmimeSigningStore) {
return ModuleLoader.loadSmimeModule()
- .signAndOrEncryptEmail(session, messageToProtect, emailContainingSmimeDetails);
+ .signAndOrEncryptEmail(session, messageToProtect, emailContainingSmimeDetails, defaultSmimeSigningStore);
}
}
diff --git a/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/EmailGovernanceImpl.java b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/EmailGovernanceImpl.java
new file mode 100644
index 000000000..aa80223f6
--- /dev/null
+++ b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/EmailGovernanceImpl.java
@@ -0,0 +1,47 @@
+package org.simplejavamail.mailer.internal;
+
+import org.hazlewood.connor.bottema.emailaddress.EmailAddressCriteria;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.simplejavamail.api.mailer.config.EmailGovernance;
+import org.simplejavamail.api.mailer.config.Pkcs12Config;
+
+import java.util.EnumSet;
+
+/**
+ * @see EmailGovernance
+ */
+class EmailGovernanceImpl implements EmailGovernance {
+ @NotNull private final EnumSet emailAddressCriteria;
+ @Nullable private final Pkcs12Config pkcs12ConfigForSmimeSigning;
+
+ EmailGovernanceImpl(@NotNull final EnumSet emailAddressCriteria, @Nullable final Pkcs12Config pkcs12ConfigForSmimeSigning) {
+ this.emailAddressCriteria = emailAddressCriteria;
+ this.pkcs12ConfigForSmimeSigning = pkcs12ConfigForSmimeSigning;
+ }
+
+ @Override
+ public String toString() {
+ final StringBuilder sb = new StringBuilder("EmailGovernanceImpl{");
+ sb.append("emailAddressCriteria=").append(emailAddressCriteria);
+ sb.append(", pkcs12ConfigForSmimeSigning=").append(pkcs12ConfigForSmimeSigning);
+ sb.append('}');
+ return sb.toString();
+ }
+
+ /**
+ * @see EmailGovernance#getEmailAddressCriteria()
+ */
+ @Override
+ public @NotNull EnumSet getEmailAddressCriteria() {
+ return emailAddressCriteria;
+ }
+
+ /**
+ * @see EmailGovernance#getPkcs12ConfigForSmimeSigning()
+ */
+ @Override
+ public @Nullable Pkcs12Config getPkcs12ConfigForSmimeSigning() {
+ return pkcs12ConfigForSmimeSigning;
+ }
+}
\ No newline at end of file
diff --git a/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerException.java b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerException.java
index 815d6dc5c..aeee4e1c3 100644
--- a/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerException.java
+++ b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerException.java
@@ -8,6 +8,8 @@
@SuppressWarnings("serial")
class MailerException extends MailException {
+ static final String ERROR_READING_SMIME_FROM_INPUTSTREAM = "Was unable to read S/MIME data from input stream";
+ static final String ERROR_READING_FROM_FILE = "Error reading from file: %s";
static final String INVALID_PROXY_SLL_COMBINATION = "Proxy is not supported for SSL connections (this is a limitation by the underlying JavaMail framework)";
static final String GENERIC_ERROR = "Third party error";
static final String INVALID_ENCODING = "Encoding not accepted";
diff --git a/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerGenericBuilderImpl.java b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerGenericBuilderImpl.java
index a4eb24739..d72cd5b9e 100644
--- a/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerGenericBuilderImpl.java
+++ b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerGenericBuilderImpl.java
@@ -1,16 +1,23 @@
package org.simplejavamail.mailer.internal;
+import edu.umd.cs.findbugs.annotations.SuppressFBWarnings;
import org.hazlewood.connor.bottema.emailaddress.EmailAddressCriteria;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.simplejavamail.api.mailer.CustomMailer;
import org.simplejavamail.api.mailer.MailerGenericBuilder;
+import org.simplejavamail.api.mailer.config.EmailGovernance;
import org.simplejavamail.api.mailer.config.LoadBalancingStrategy;
import org.simplejavamail.api.mailer.config.OperationalConfig;
+import org.simplejavamail.api.mailer.config.Pkcs12Config;
import org.simplejavamail.api.mailer.config.ProxyConfig;
import org.simplejavamail.config.ConfigLoader.Property;
import org.simplejavamail.internal.modules.ModuleLoader;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.io.InputStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.EnumSet;
@@ -21,10 +28,15 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
+import static java.lang.String.format;
import static org.simplejavamail.config.ConfigLoader.Property.DEFAULT_CONNECTIONPOOL_CLUSTER_KEY;
import static org.simplejavamail.config.ConfigLoader.Property.PROXY_HOST;
import static org.simplejavamail.config.ConfigLoader.Property.PROXY_PASSWORD;
import static org.simplejavamail.config.ConfigLoader.Property.PROXY_USERNAME;
+import static org.simplejavamail.config.ConfigLoader.Property.SMIME_SIGNING_KEYSTORE;
+import static org.simplejavamail.config.ConfigLoader.Property.SMIME_SIGNING_KEYSTORE_PASSWORD;
+import static org.simplejavamail.config.ConfigLoader.Property.SMIME_SIGNING_KEY_ALIAS;
+import static org.simplejavamail.config.ConfigLoader.Property.SMIME_SIGNING_KEY_PASSWORD;
import static org.simplejavamail.config.ConfigLoader.getStringProperty;
import static org.simplejavamail.config.ConfigLoader.hasProperty;
import static org.simplejavamail.config.ConfigLoader.valueOrProperty;
@@ -32,8 +44,12 @@
import static org.simplejavamail.config.ConfigLoader.valueOrPropertyAsInteger;
import static org.simplejavamail.config.ConfigLoader.valueOrPropertyAsString;
import static org.simplejavamail.internal.util.MiscUtil.checkArgumentNotEmpty;
+import static org.simplejavamail.internal.util.MiscUtil.readInputStreamToBytes;
import static org.simplejavamail.internal.util.MiscUtil.valueNullOrEmpty;
import static org.simplejavamail.internal.util.Preconditions.assumeNonNull;
+import static org.simplejavamail.internal.util.Preconditions.checkNonEmptyArgument;
+import static org.simplejavamail.mailer.internal.MailerException.ERROR_READING_FROM_FILE;
+import static org.simplejavamail.mailer.internal.MailerException.ERROR_READING_SMIME_FROM_INPUTSTREAM;
/**
* @see MailerGenericBuilder
@@ -82,13 +98,19 @@ abstract class MailerGenericBuilderImpl> i
*/
@NotNull
private Integer sessionTimeout;
-
+
/**
* @see MailerGenericBuilder#withEmailAddressCriteria(EnumSet)
*/
@NotNull
private EnumSet emailAddressCriteria;
+ /**
+ * @see MailerGenericBuilder#signByDefaultWithSmime(Pkcs12Config)
+ */
+ @Nullable
+ private Pkcs12Config pkcs12ConfigForSmimeSigning;
+
/**
* @see MailerGenericBuilder#withExecutorService(ExecutorService)
*/
@@ -216,6 +238,15 @@ abstract class MailerGenericBuilderImpl> i
}
this.emailAddressCriteria = EmailAddressCriteria.RFC_COMPLIANT.clone();
+
+ if (hasProperty(SMIME_SIGNING_KEYSTORE)) {
+ signByDefaultWithSmime(Pkcs12Config.builder()
+ .pkcs12Store(assumeNonNull(getStringProperty(SMIME_SIGNING_KEYSTORE)))
+ .storePassword(checkNonEmptyArgument(getStringProperty(SMIME_SIGNING_KEYSTORE_PASSWORD), "Keystore password property"))
+ .keyAlias(checkNonEmptyArgument(getStringProperty(SMIME_SIGNING_KEY_ALIAS), "Key alias property"))
+ .keyPassword(checkNonEmptyArgument(getStringProperty(SMIME_SIGNING_KEY_PASSWORD), "Key password property"))
+ .build());
+ }
}
/**
@@ -241,6 +272,13 @@ private void validateProxy() {
}
}
}
+
+ /**
+ * For internal use.
+ */
+ EmailGovernance buildEmailGovernance() {
+ return new EmailGovernanceImpl(assumeNonNull(getEmailAddressCriteria()), getPkcs12ConfigForSmimeSigning());
+ }
/**
* For internal use.
@@ -369,6 +407,70 @@ public T withEmailAddressCriteria(@NotNull final EnumSet e
return (T) this;
}
+ /**
+ * @param pkcs12StoreFile The file containing the keystore
+ * @param storePassword The password to get keys from the store
+ * @param keyAlias The key we need for signing
+ * @param keyPassword The password for the key
+ *
+ * @see MailerGenericBuilder#signByDefaultWithSmime(File, String, String, String)
+ */
+ @Override
+ @SuppressFBWarnings(value = "OBL_UNSATISFIED_OBLIGATION", justification = "Input stream being created should not be closed here")
+ public T signByDefaultWithSmime(@NotNull final File pkcs12StoreFile, @NotNull final String storePassword, @NotNull final String keyAlias, @NotNull final String keyPassword) {
+ try {
+ return signByDefaultWithSmime(new FileInputStream(pkcs12StoreFile), storePassword, keyAlias, keyPassword);
+ } catch (IOException e) {
+ throw new MailerException(format(ERROR_READING_FROM_FILE, pkcs12StoreFile), e);
+ }
+ }
+
+ /**
+ * @param pkcs12StoreStream The data (file) input stream containing the keystore
+ * @param storePassword The password to get keys from the store
+ * @param keyAlias The key we need for signing
+ * @param keyPassword The password for the key
+ *
+ * @see MailerGenericBuilder#signByDefaultWithSmime(InputStream, String, String, String)
+ */
+ @Override
+ public T signByDefaultWithSmime(@NotNull final InputStream pkcs12StoreStream, @NotNull final String storePassword, @NotNull final String keyAlias, @NotNull final String keyPassword) {
+ final byte[] pkcs12StoreData;
+ try {
+ pkcs12StoreData = readInputStreamToBytes(pkcs12StoreStream);
+ } catch (IOException e) {
+ throw new MailerException(ERROR_READING_SMIME_FROM_INPUTSTREAM, e);
+ }
+ return signByDefaultWithSmime(pkcs12StoreData, storePassword, keyAlias, keyPassword);
+ }
+
+ /**
+ * @param pkcs12StoreData The data (file) input stream containing the keystore
+ * @param storePassword The password to get keys from the store
+ * @param keyAlias The key we need for signing
+ * @param keyPassword The password for the key
+ *
+ * @see MailerGenericBuilder#signByDefaultWithSmime(InputStream, String, String, String)
+ */
+ @Override
+ public T signByDefaultWithSmime(@NotNull final byte[] pkcs12StoreData, @NotNull final String storePassword, @NotNull final String keyAlias, @NotNull final String keyPassword) {
+ return signByDefaultWithSmime(Pkcs12Config.builder()
+ .pkcs12Store(pkcs12StoreData)
+ .storePassword(storePassword)
+ .keyAlias(keyAlias)
+ .keyPassword(keyPassword)
+ .build());
+ }
+
+ /**
+ * @see MailerGenericBuilder#signByDefaultWithSmime(Pkcs12Config)
+ */
+ @Override
+ public T signByDefaultWithSmime(@NotNull final Pkcs12Config pkcs12Config) {
+ this.pkcs12ConfigForSmimeSigning = pkcs12Config;
+ return (T) this;
+ }
+
/**
* @see MailerGenericBuilder#withExecutorService(ExecutorService)
*/
@@ -658,7 +760,7 @@ public T clearProxy() {
return (T) withProxy(null, null, null, null)
.withProxyBridgePort(DEFAULT_PROXY_BRIDGE_PORT);
}
-
+
/**
* @see MailerGenericBuilder#clearEmailAddressCriteria()
*/
@@ -666,6 +768,15 @@ public T clearProxy() {
public T clearEmailAddressCriteria() {
return withEmailAddressCriteria(EnumSet.noneOf(EmailAddressCriteria.class));
}
+
+ /**
+ * @see MailerGenericBuilder#clearSignByDefaultWithSmime()
+ */
+ @Override
+ public T clearSignByDefaultWithSmime() {
+ this.pkcs12ConfigForSmimeSigning = null;
+ return (T) this;
+ }
/**
* @see MailerGenericBuilder#clearTrustedSSLHosts()
@@ -763,6 +874,15 @@ public EnumSet getEmailAddressCriteria() {
return emailAddressCriteria;
}
+ /**
+ * @see MailerGenericBuilder#getPkcs12ConfigForSmimeSigning()
+ */
+ @Override
+ @Nullable
+ public Pkcs12Config getPkcs12ConfigForSmimeSigning() {
+ return pkcs12ConfigForSmimeSigning;
+ }
+
/**
* @see MailerGenericBuilder#getExecutorService()
*/
diff --git a/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerImpl.java b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerImpl.java
index be04bd7f7..9b5941f7d 100644
--- a/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerImpl.java
+++ b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerImpl.java
@@ -1,6 +1,5 @@
package org.simplejavamail.mailer.internal;
-import org.hazlewood.connor.bottema.emailaddress.EmailAddressCriteria;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;
import org.simplejavamail.MailException;
@@ -8,6 +7,7 @@
import org.simplejavamail.api.internal.authenticatedsockssupport.socks5server.AnonymousSocks5Server;
import org.simplejavamail.api.mailer.AsyncResponse;
import org.simplejavamail.api.mailer.Mailer;
+import org.simplejavamail.api.mailer.config.EmailGovernance;
import org.simplejavamail.api.mailer.config.OperationalConfig;
import org.simplejavamail.api.mailer.config.ProxyConfig;
import org.simplejavamail.api.mailer.config.ServerConfig;
@@ -72,7 +72,7 @@ public class MailerImpl implements Mailer {
* @see org.simplejavamail.api.mailer.MailerGenericBuilder#withEmailAddressCriteria(EnumSet)
*/
@NotNull
- private final EnumSet emailAddressCriteria;
+ private final EmailGovernance emailGovernance;
/**
* @see org.simplejavamail.api.mailer.MailerRegularBuilder#withTransportStrategy(TransportStrategy)
@@ -95,7 +95,7 @@ public class MailerImpl implements Mailer {
MailerImpl(@NotNull final MailerFromSessionBuilderImpl fromSessionBuilder) {
this(null,
null,
- fromSessionBuilder.getEmailAddressCriteria(),
+ fromSessionBuilder.buildEmailGovernance(),
fromSessionBuilder.buildProxyConfig(),
fromSessionBuilder.getSession(),
fromSessionBuilder.buildOperationalConfig());
@@ -104,17 +104,17 @@ public class MailerImpl implements Mailer {
MailerImpl(@NotNull final MailerRegularBuilderImpl regularBuilder) {
this(regularBuilder.buildServerConfig(),
regularBuilder.getTransportStrategy(),
- regularBuilder.getEmailAddressCriteria(),
+ regularBuilder.buildEmailGovernance(),
regularBuilder.buildProxyConfig(),
null,
regularBuilder.buildOperationalConfig());
}
- MailerImpl(@Nullable ServerConfig serverConfig, @Nullable TransportStrategy transportStrategy, @NotNull EnumSet emailAddressCriteria, @NotNull ProxyConfig proxyConfig,
+ MailerImpl(@Nullable ServerConfig serverConfig, @Nullable TransportStrategy transportStrategy, @NotNull EmailGovernance emailGovernance, @NotNull ProxyConfig proxyConfig,
@Nullable Session session, @NotNull OperationalConfig operationalConfig) {
this.serverConfig = serverConfig;
this.transportStrategy = transportStrategy;
- this.emailAddressCriteria = emailAddressCriteria;
+ this.emailGovernance = emailGovernance;
this.proxyConfig = proxyConfig;
if (session == null) {
session = createMailSession(checkNonEmptyArgument(serverConfig, "serverConfig"), checkNonEmptyArgument(transportStrategy, "transportStrategy"));
@@ -323,7 +323,7 @@ public final void sendMail(final Email email) {
@Nullable
public final AsyncResponse sendMail(final Email email, @SuppressWarnings("SameParameterValue") final boolean async) {
if (validate(email)) {
- SendMailClosure sendMailClosure = new SendMailClosure(operationalConfig, session, email, proxyServer, async, operationalConfig.isTransportModeLoggingOnly(),
+ SendMailClosure sendMailClosure = new SendMailClosure(operationalConfig, emailGovernance, session, email, proxyServer, async, operationalConfig.isTransportModeLoggingOnly(),
smtpConnectionCounter);
if (!async) {
@@ -346,7 +346,7 @@ public final AsyncResponse sendMail(final Email email, @SuppressWarnings("SamePa
@SuppressWarnings({"SameReturnValue"})
public boolean validate(@NotNull final Email email)
throws MailException {
- return MailerHelper.validate(email, emailAddressCriteria);
+ return MailerHelper.validate(email, emailGovernance.getEmailAddressCriteria());
}
/**
@@ -407,11 +407,11 @@ public OperationalConfig getOperationalConfig() {
}
/**
- * @see Mailer#getEmailAddressCriteria()
+ * @see Mailer#getEmailGovernance()
*/
@Override
@NotNull
- public EnumSet getEmailAddressCriteria() {
- return emailAddressCriteria;
+ public EmailGovernance getEmailGovernance() {
+ return emailGovernance;
}
}
\ No newline at end of file
diff --git a/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerRegularBuilderImpl.java b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerRegularBuilderImpl.java
index 005bf0479..2eaa9b3d0 100644
--- a/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerRegularBuilderImpl.java
+++ b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/MailerRegularBuilderImpl.java
@@ -193,14 +193,14 @@ public MailerRegularBuilderImpl withCustomSSLFactoryInstance(@Nullable final SSL
public Mailer buildMailer() {
return new MailerImpl(this);
}
-
+
/**
* For internal use.
*/
ServerConfig buildServerConfig() {
vallidateServerConfig();
final int serverPort = SimpleOptional.ofNullable(port).orElse(transportStrategy.getDefaultServerPort());
- return new ServerConfigImpl(assumeNonNull(getHost()), serverPort, getUsername(), getPassword(), customSSLFactory, customSSLFactoryInstance);
+ return new ServerConfigImpl(assumeNonNull(getHost()), serverPort, username, password, customSSLFactory, customSSLFactoryInstance);
}
private void vallidateServerConfig() {
diff --git a/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/SendMailClosure.java b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/SendMailClosure.java
index 53c67479a..6b1070fe1 100644
--- a/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/SendMailClosure.java
+++ b/modules/simple-java-mail/src/main/java/org/simplejavamail/mailer/internal/SendMailClosure.java
@@ -1,14 +1,15 @@
package org.simplejavamail.mailer.internal;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
import org.simplejavamail.api.email.Email;
import org.simplejavamail.api.internal.authenticatedsockssupport.socks5server.AnonymousSocks5Server;
+import org.simplejavamail.api.mailer.config.EmailGovernance;
import org.simplejavamail.api.mailer.config.OperationalConfig;
import org.simplejavamail.converter.internal.mimemessage.MimeMessageProducerHelper;
import org.simplejavamail.mailer.internal.util.SessionLogger;
import org.simplejavamail.mailer.internal.util.TransportRunner;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.internet.MimeMessage;
@@ -26,15 +27,18 @@
class SendMailClosure extends AbstractProxyServerSyncingClosure {
@NotNull private final OperationalConfig operationalConfig;
+ @NotNull private final EmailGovernance emailGovernance;
@NotNull private final Session session;
@NotNull private final Email email;
private final boolean asyncForLoggingPurpose;
private final boolean transportModeLoggingOnly;
- SendMailClosure(@NotNull OperationalConfig operationalConfig, @NotNull Session session, @NotNull Email email, @Nullable AnonymousSocks5Server proxyServer, boolean asyncForLoggingPurpose,
+ SendMailClosure(@NotNull OperationalConfig operationalConfig, @NotNull EmailGovernance emailGovernance, @NotNull Session session, @NotNull Email email, @Nullable AnonymousSocks5Server proxyServer,
+ boolean asyncForLoggingPurpose,
boolean transportModeLoggingOnly, @NotNull AtomicInteger smtpConnectionCounter) {
super(smtpConnectionCounter, proxyServer);
this.operationalConfig = operationalConfig;
+ this.emailGovernance = emailGovernance;
this.session = session;
this.email = email;
this.asyncForLoggingPurpose = asyncForLoggingPurpose;
@@ -47,7 +51,7 @@ public void executeClosure() {
LOGGER.trace("sending email...");
try {
// fill and send wrapped mime message parts
- final MimeMessage message = MimeMessageProducerHelper.produceMimeMessage(email, session);
+ final MimeMessage message = MimeMessageProducerHelper.produceMimeMessage(email, session, emailGovernance.getPkcs12ConfigForSmimeSigning());
SessionLogger.logSession(session, asyncForLoggingPurpose, "mail");
message.saveChanges(); // some headers and id's will be set for this specific message
diff --git a/modules/simple-java-mail/src/test/java/org/simplejavamail/mailer/MailerLiveTest.java b/modules/simple-java-mail/src/test/java/org/simplejavamail/mailer/MailerLiveTest.java
index 6371a2cdd..7bdf4cbdb 100644
--- a/modules/simple-java-mail/src/test/java/org/simplejavamail/mailer/MailerLiveTest.java
+++ b/modules/simple-java-mail/src/test/java/org/simplejavamail/mailer/MailerLiveTest.java
@@ -131,6 +131,37 @@ public void createMailSession_OutlookMessageSmimeSignTest()
.build());
}
+ @Test
+ public void createMailSession_OutlookMessageDefaultSmimeSignTest()
+ throws IOException, MessagingException, ExecutionException, InterruptedException {
+ // override the default from the @Before test
+ mailer = MailerBuilder
+ .withSMTPServer("localhost", SERVER_PORT)
+ .signByDefaultWithSmime(new File(RESOURCES_PKCS + "/smime_keystore.pkcs12"), "letmein", "smime_test_user_alias", "letmein")
+ .buildMailer();
+
+ EmailPopulatingBuilder builder = readOutlookMessage("test-messages/HTML mail with replyto and attachment and embedded image.msg");
+ Email email = assertSendingEmail(builder, false, true, false, true, false);
+
+ // verify that S/MIME was indeed only configured on the mailer instance
+ assertThat(mailer.getEmailGovernance().getPkcs12ConfigForSmimeSigning()).isNotNull();
+ assertThat(builder.getPkcs12ConfigForSmimeSigning()).isNull();
+ assertThat(email.getPkcs12ConfigForSmimeSigning()).isNull();
+
+ verifyReceivedOutlookEmail(email, true, false);
+
+ EmailAssert.assertThat(email).wasNotMergedWithSmimeSignedMessage();
+
+ EmailAssert.assertThat(email).hasOriginalSmimeDetails(OriginalSmimeDetailsImpl.builder()
+ .smimeMode(SmimeMode.SIGNED)
+ .smimeMime("multipart/signed")
+ .smimeProtocol("application/pkcs7-signature")
+ .smimeMicalg("sha-256")
+ .smimeSignedBy("Benny Bottema")
+ .smimeSignatureValid(true)
+ .build());
+ }
+
@Test
public void testOutlookMessageWithNestedOutlookMessageAttachment()
throws IOException {
diff --git a/modules/simple-java-mail/src/test/java/org/simplejavamail/mailer/internal/MailerImplTest.java b/modules/simple-java-mail/src/test/java/org/simplejavamail/mailer/internal/MailerImplTest.java
index 9c38a3f08..763128aae 100644
--- a/modules/simple-java-mail/src/test/java/org/simplejavamail/mailer/internal/MailerImplTest.java
+++ b/modules/simple-java-mail/src/test/java/org/simplejavamail/mailer/internal/MailerImplTest.java
@@ -1,12 +1,13 @@
package org.simplejavamail.mailer.internal;
import org.hazlewood.connor.bottema.emailaddress.EmailAddressCriteria;
+import org.jetbrains.annotations.NotNull;
import org.junit.Before;
import org.junit.Test;
-import org.simplejavamail.api.mailer.config.OperationalConfig;
+import org.simplejavamail.api.mailer.Mailer;
+import org.simplejavamail.api.mailer.config.EmailGovernance;
import org.simplejavamail.api.mailer.config.ProxyConfig;
-import org.jetbrains.annotations.NotNull;
import javax.mail.Session;
import java.util.Arrays;
import java.util.Collections;
@@ -14,15 +15,13 @@
import java.util.Properties;
import static java.util.EnumSet.noneOf;
-import static java.util.UUID.randomUUID;
-import static java.util.concurrent.Executors.newSingleThreadExecutor;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
-import static org.simplejavamail.api.mailer.config.LoadBalancingStrategy.ROUND_ROBIN;
import static org.simplejavamail.api.mailer.config.TransportStrategy.SMTP;
import static org.simplejavamail.api.mailer.config.TransportStrategy.SMTPS;
import static org.simplejavamail.api.mailer.config.TransportStrategy.SMTP_TLS;
+import static org.simplejavamail.util.TestDataHelper.loadPkcs12KeyStore;
import static testutil.EmailHelper.createDummyOperationalConfig;
public class MailerImplTest {
@@ -36,18 +35,13 @@ public void setup() {
session = Session.getInstance(new Properties());
}
- @NotNull
- private ProxyConfig createEmptyProxyConfig() {
- return new ProxyConfigImpl(null, null, null, null, null);
- }
-
@Test
public void trustAllHosts_PLAIN() {
- new MailerImpl(null, SMTP, noneOf(EmailAddressCriteria.class), createEmptyProxyConfig(), session, createDummyOperationalConfig(EMPTY_LIST, true, false));
+ new MailerImpl(null, SMTP, createDummyEmailGovernance(), createEmptyProxyConfig(), session, createDummyOperationalConfig(EMPTY_LIST, true, false));
assertThat(session.getProperties().getProperty("mail.smtp.ssl.trust")).isEqualTo("*");
assertThat(session.getProperties().getProperty("mail.smtp.ssl.checkserveridentity")).isNull();
assertThat(session.getProperties().getProperty("mail.smtps.ssl.checkserveridentity")).isNull();
- new MailerImpl(null, SMTP, noneOf(EmailAddressCriteria.class), createEmptyProxyConfig(), session, createDummyOperationalConfig(EMPTY_LIST, false, true));
+ new MailerImpl(null, SMTP, createDummyEmailGovernance(), createEmptyProxyConfig(), session, createDummyOperationalConfig(EMPTY_LIST, false, true));
assertThat(session.getProperties().getProperty("mail.smtp.ssl.trust")).isNull();
assertThat(session.getProperties().getProperty("mail.smtp.ssl.checkserveridentity")).isNull();
assertThat(session.getProperties().getProperty("mail.smtps.ssl.checkserveridentity")).isNull();
@@ -57,11 +51,11 @@ public void trustAllHosts_PLAIN() {
public void trustAllHosts_SMTPS() {
ProxyConfig proxyBypassingMock = mock(ProxyConfig.class);
when(proxyBypassingMock.requiresProxy()).thenReturn(false);
- new MailerImpl(null, SMTPS, noneOf(EmailAddressCriteria.class), proxyBypassingMock, session, createDummyOperationalConfig(EMPTY_LIST, true, false));
+ new MailerImpl(null, SMTPS, createDummyEmailGovernance(), proxyBypassingMock, session, createDummyOperationalConfig(EMPTY_LIST, true, false));
assertThat(session.getProperties().getProperty("mail.smtps.ssl.trust")).isEqualTo("*");
assertThat(session.getProperties().getProperty("mail.smtp.ssl.checkserveridentity")).isNull();
assertThat(session.getProperties().getProperty("mail.smtps.ssl.checkserveridentity")).isEqualTo("false");
- new MailerImpl(null, SMTPS, noneOf(EmailAddressCriteria.class), proxyBypassingMock, session, createDummyOperationalConfig(EMPTY_LIST, false, true));
+ new MailerImpl(null, SMTPS, createDummyEmailGovernance(), proxyBypassingMock, session, createDummyOperationalConfig(EMPTY_LIST, false, true));
assertThat(session.getProperties().getProperty("mail.smtps.ssl.trust")).isNull();
assertThat(session.getProperties().getProperty("mail.smtp.ssl.checkserveridentity")).isNull();
assertThat(session.getProperties().getProperty("mail.smtps.ssl.checkserveridentity")).isEqualTo("true");
@@ -69,11 +63,11 @@ public void trustAllHosts_SMTPS() {
@Test
public void trustAllHosts_SMTP_TLS() {
- new MailerImpl(null, SMTP_TLS, noneOf(EmailAddressCriteria.class), createEmptyProxyConfig(), session, createDummyOperationalConfig(EMPTY_LIST, true, false));
+ new MailerImpl(null, SMTP_TLS, createDummyEmailGovernance(), createEmptyProxyConfig(), session, createDummyOperationalConfig(EMPTY_LIST, true, false));
assertThat(session.getProperties().getProperty("mail.smtp.ssl.trust")).isEqualTo("*");
assertThat(session.getProperties().getProperty("mail.smtp.ssl.checkserveridentity")).isEqualTo("false");
assertThat(session.getProperties().getProperty("mail.smtps.ssl.checkserveridentity")).isNull();
- new MailerImpl(null, SMTP_TLS, noneOf(EmailAddressCriteria.class), createEmptyProxyConfig(), session, createDummyOperationalConfig(EMPTY_LIST, false, true));
+ new MailerImpl(null, SMTP_TLS, createDummyEmailGovernance(), createEmptyProxyConfig(), session, createDummyOperationalConfig(EMPTY_LIST, false, true));
assertThat(session.getProperties().getProperty("mail.smtps.ssl.trust")).isNull();
assertThat(session.getProperties().getProperty("mail.smtp.ssl.checkserveridentity")).isEqualTo("true");
assertThat(session.getProperties().getProperty("mail.smtps.ssl.checkserveridentity")).isNull();
@@ -81,26 +75,48 @@ public void trustAllHosts_SMTP_TLS() {
@Test
public void trustHosts() {
- new MailerImpl(null, SMTP, noneOf(EmailAddressCriteria.class), createEmptyProxyConfig(), session, createDummyOperationalConfig(asList(), false, false));
+ new MailerImpl(null, SMTP, createDummyEmailGovernance(), createEmptyProxyConfig(), session, createDummyOperationalConfig(asList(), false, false));
assertThat(session.getProperties().getProperty("mail.smtp.ssl.trust")).isNull();
assertThat(session.getProperties().getProperty("mail.smtp.ssl.checkserveridentity")).isNull();
assertThat(session.getProperties().getProperty("mail.smtps.ssl.checkserveridentity")).isNull();
- new MailerImpl(null, SMTP, noneOf(EmailAddressCriteria.class), createEmptyProxyConfig(), session, createDummyOperationalConfig(asList("a"), false, false));
+ new MailerImpl(null, SMTP, createDummyEmailGovernance(), createEmptyProxyConfig(), session, createDummyOperationalConfig(asList("a"), false, false));
assertThat(session.getProperties().getProperty("mail.smtp.ssl.trust")).isEqualTo("a");
assertThat(session.getProperties().getProperty("mail.smtp.ssl.checkserveridentity")).isNull();
assertThat(session.getProperties().getProperty("mail.smtps.ssl.checkserveridentity")).isNull();
- new MailerImpl(null, SMTP, noneOf(EmailAddressCriteria.class), createEmptyProxyConfig(), session, createDummyOperationalConfig(asList("a", "b"), false, false));
+ new MailerImpl(null, SMTP, createDummyEmailGovernance(), createEmptyProxyConfig(), session, createDummyOperationalConfig(asList("a", "b"), false, false));
assertThat(session.getProperties().getProperty("mail.smtp.ssl.trust")).isEqualTo("a b");
assertThat(session.getProperties().getProperty("mail.smtp.ssl.checkserveridentity")).isNull();
assertThat(session.getProperties().getProperty("mail.smtps.ssl.checkserveridentity")).isNull();
- new MailerImpl(null, SMTP, noneOf(EmailAddressCriteria.class), createEmptyProxyConfig(), session, createDummyOperationalConfig(asList("a", "b", "c"), false, true));
+ new MailerImpl(null, SMTP, createDummyEmailGovernance(), createEmptyProxyConfig(), session, createDummyOperationalConfig(asList("a", "b", "c"), false, true));
assertThat(session.getProperties().getProperty("mail.smtp.ssl.trust")).isEqualTo("a b c");
assertThat(session.getProperties().getProperty("mail.smtp.ssl.checkserveridentity")).isNull();
assertThat(session.getProperties().getProperty("mail.smtps.ssl.checkserveridentity")).isNull();
}
-
+
+ @Test
+ public void testSignWithSmime_WithConfigObject() {
+ final EmailGovernanceImpl emailGovernance = new EmailGovernanceImpl(noneOf(EmailAddressCriteria.class), loadPkcs12KeyStore());
+ final Mailer mailer = new MailerImpl(null, SMTP, emailGovernance, createEmptyProxyConfig(), session, createDummyOperationalConfig(EMPTY_LIST, true, false));
+
+ assertThat(mailer.getEmailGovernance().getPkcs12ConfigForSmimeSigning()).isNotNull();
+ assertThat(mailer.getEmailGovernance().getPkcs12ConfigForSmimeSigning().getPkcs12StoreData()).isNotNull();
+ assertThat(mailer.getEmailGovernance().getPkcs12ConfigForSmimeSigning().getStorePassword()).isEqualTo("letmein".toCharArray());
+ assertThat(mailer.getEmailGovernance().getPkcs12ConfigForSmimeSigning().getKeyAlias()).isEqualTo("smime_test_user_alias");
+ assertThat(mailer.getEmailGovernance().getPkcs12ConfigForSmimeSigning().getKeyPassword()).isEqualTo("letmein".toCharArray());
+ }
+
@NotNull
private List asList(String... args) {
return Arrays.asList(args);
}
+
+ @NotNull
+ private ProxyConfig createEmptyProxyConfig() {
+ return new ProxyConfigImpl(null, null, null, null, null);
+ }
+
+ @NotNull
+ private EmailGovernance createDummyEmailGovernance() {
+ return new EmailGovernanceImpl(noneOf(EmailAddressCriteria.class), null);
+ }
}
\ No newline at end of file
diff --git a/modules/smime-module/src/main/java/org/simplejavamail/internal/smimesupport/SMIMESupport.java b/modules/smime-module/src/main/java/org/simplejavamail/internal/smimesupport/SMIMESupport.java
index b41e6c15f..399690841 100644
--- a/modules/smime-module/src/main/java/org/simplejavamail/internal/smimesupport/SMIMESupport.java
+++ b/modules/smime-module/src/main/java/org/simplejavamail/internal/smimesupport/SMIMESupport.java
@@ -36,6 +36,7 @@
import org.simplejavamail.internal.smimesupport.builder.SmimeParseResultBuilder;
import org.simplejavamail.internal.smimesupport.model.OriginalSmimeDetailsImpl;
import org.simplejavamail.internal.smimesupport.model.SmimeDetailsImpl;
+import org.simplejavamail.internal.util.SimpleOptional;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -351,6 +352,7 @@ public String getSignedByAddress(@NotNull AttachmentResource smimeAttachment) {
throw new SmimeException(format(ERROR_EXTRACTING_SIGNEDBY_FROM_SMIME_SIGNED_ATTACHMENT, smimeAttachment), e);
}
}
+
/**
* Delegates to {@link #determineSMIMESigned(MimePart)} and {@link #getSignedByAddress(SMIMESigned)}.
*
@@ -434,10 +436,15 @@ private static SignerInformationVerifier getVerifier(X509Certificate certificate
@NotNull
@Override
- public MimeMessage signAndOrEncryptEmail(@Nullable final Session session, @NotNull final MimeMessage messageToProtect, @NotNull final Email emailContainingSmimeDetails) {
+ public MimeMessage signAndOrEncryptEmail(@Nullable final Session session, @NotNull final MimeMessage messageToProtect, @NotNull final Email emailContainingSmimeDetails,
+ @Nullable final Pkcs12Config defaultSmimeSigningStore) {
MimeMessage result = messageToProtect;
- if (emailContainingSmimeDetails.getPkcs12ConfigForSmimeSigning() != null) {
- result = signMessage(session, result, emailContainingSmimeDetails.getPkcs12ConfigForSmimeSigning());
+
+ final Pkcs12Config pkcs12Config = SimpleOptional
+ .ofNullable(emailContainingSmimeDetails.getPkcs12ConfigForSmimeSigning())
+ .orMaybe(defaultSmimeSigningStore);
+ if (pkcs12Config != null) {
+ result = signMessage(session, result, pkcs12Config);
}
if (emailContainingSmimeDetails.getX509CertificateForSmimeEncryption() != null) {
result = encryptMessage(session, result, emailContainingSmimeDetails.getX509CertificateForSmimeEncryption());
diff --git a/modules/spring-module/src/test/resources/pkcs12/smime_keystore.pkcs12 b/modules/spring-module/src/test/resources/pkcs12/smime_keystore.pkcs12
new file mode 100644
index 000000000..621868f34
Binary files /dev/null and b/modules/spring-module/src/test/resources/pkcs12/smime_keystore.pkcs12 differ