Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add API for using custom SSLSocketFactory #277

Closed
t101jv opened this issue Jul 2, 2020 · 6 comments
Closed

Add API for using custom SSLSocketFactory #277

t101jv opened this issue Jul 2, 2020 · 6 comments

Comments

@t101jv
Copy link

t101jv commented Jul 2, 2020

Hi, our service is using this mailing library and we are getting the following integration error with our fips compliance configuration.

ERROR 2020-07-02 18:29:11,118 [pool-14-thread-4] com.oracle.pic.announcements.management.email.DynSmtpHealthCheck: dyn healthcheck failed
org.simplejavamail.mailer.internal.MailerException: Was unable to connect to SMTP server
at org.simplejavamail.mailer.internal.TestConnectionClosure.executeClosure(TestConnectionClosure.java:57)
at org.simplejavamail.mailer.internal.AbstractProxyServerSyncingClosure.run(AbstractProxyServerSyncingClosure.java:56)
at org.simplejavamail.mailer.internal.MailerImpl.testConnection(MailerImpl.java:303)
at org.simplejavamail.mailer.internal.MailerImpl.testConnection(MailerImpl.java:292)
at com.oracle.pic.announcements.management.email.SimpleMailSender.testConnection(SimpleMailSender.java:23)
at com.oracle.pic.announcements.management.email.DynSmtpHealthCheck.check(DynSmtpHealthCheck.java:26)
at com.codahale.metrics.health.HealthCheck.execute(HealthCheck.java:320)
at com.oracle.pic.announcements.common.health.DownstreamServicesHealthcheck$AsyncHealthCheck.lambda$new$0(DownstreamServicesHealthcheck.java:146)
at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
at java.util.concurrent.FutureTask.runAndReset(FutureTask.java:308)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$301(ScheduledThreadPoolExecutor.java:180)
at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:294)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)
Caused by: javax.mail.MessagingException: Could not convert socket to TLS
at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2140)
at com.sun.mail.smtp.SMTPTransport.protocolConnect(SMTPTransport.java:734)
at javax.mail.Service.connect(Service.java:342)
at javax.mail.Service.connect(Service.java:222)
at javax.mail.Service.connect(Service.java:171)
at org.simplejavamail.mailer.internal.util.TransportRunner.runOnSessionTransport(TransportRunner.java:75)
at org.simplejavamail.mailer.internal.util.TransportRunner.connect(TransportRunner.java:60)
at org.simplejavamail.mailer.internal.TestConnectionClosure.executeClosure(TestConnectionClosure.java:54)
... 14 common frames omitted
Caused by: java.io.IOException: Can't create MailSSLSocketFactory
at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:517)
at com.sun.mail.smtp.SMTPTransport.startTLS(SMTPTransport.java:2135)
... 21 common frames omitted
Caused by: java.security.KeyManagementException: FIPS mode: only SunJSSE TrustManagers may be used
at sun.security.ssl.SSLContextImpl.chooseTrustManager(SSLContextImpl.java:120)
at sun.security.ssl.SSLContextImpl.engineInit(SSLContextImpl.java:83)
at javax.net.ssl.SSLContext.init(SSLContext.java:282)
at com.sun.mail.util.MailSSLSocketFactory.newAdapteeFactory(MailSSLSocketFactory.java:109)
at com.sun.mail.util.MailSSLSocketFactory.(MailSSLSocketFactory.java:96)
at com.sun.mail.util.MailSSLSocketFactory.(MailSSLSocketFactory.java:70)
at com.sun.mail.util.SocketFetcher.startTLS(SocketFetcher.java:509)
... 22 common frames

If the socketfactory config is exposed we can inject our own class and configure the trustmanager.

@bbottema
Copy link
Owner

bbottema commented Jul 5, 2020

I haven't tested it, but I think you can already do that, by manually setting the sslsocketfactory property on the Session object (but it won't work in combination with authenticated proxy):

Session session = mailer.getSession();
session.getProperties().put("mail.smtp.ssl.socketFactory", yourSSLSocketFactory);

Here are some more details you could look into: https://stackoverflow.com/a/34773907/441662

In fact I came across some old unused code in the library specifically for configuring such a ConnectionFactory, but it is untested (see this gist).

KeyStoreInfo optionalKeyStoreInfo = new KeyStoreInfo(keyStorePath, password, type); // without type param defaults to "JKS"
KeyStoreInfo trustKeyStoreInfo = new KeyStoreInfo(keyStorePath, password, type);
SSLSocketFactory yourSSLSocketFactory = new SSLConfiguration(optionalKeyStoreInfo, trustKeyStoreInfo).getSSLSocketFactory();

Session session = mailer.getSession();
session.getProperties().put("mail.smtp.ssl.socketFactory", yourSSLSocketFactory);

If you could please check if this works for you, then I know what to do to integrate this into the library behind a better API.

Other than that, do you have suggestions how you would like the API design to be regarding providing a custom SSLSocketFactory or a class (for mail.smtp.ssl.socketFactory.class)?

@t101jv
Copy link
Author

t101jv commented Jul 6, 2020

Setting the property on the mailer session worked for us. Thank you very much, you saved us a lot of effort.

I think a method on the mailer builder would be an appropriate api.

@bbottema
Copy link
Owner

bbottema commented Jul 6, 2020

Setting the property on the mailer session worked for us. Thank you very much, you saved us a lot of effort.

I think a method on the mailer builder would be an appropriate api.

So did you do this with the code I gave you? Did you use one or two key stores?

@t101jv
Copy link
Author

t101jv commented Jul 6, 2020

I did this:
Properties mailerProps = mailer.getSession().getProperties(); mailerProps.put("mail.smtp.ssl.socketFactory.class", FIPSCompatibleMailSSLSocketFactory.class.getCanonicalName());

Would you like me to test configuring keystores?

@bbottema bbottema modified the milestones: 6.2.0, 6.x.0 Jul 10, 2020
@bbottema bbottema changed the title Expose mail.smtp.ssl.socketFactory and mail.smtp.ssl.socketFactory.class config Add API for using custom SSLSocketFactory Jul 11, 2020
@bbottema
Copy link
Owner

I've added the following methods:

mailerBuilder
   .withCustomSSLFactoryClass(theClassName)
   .withCustomSSLFactoryInstance(theInstance) // takes precedence
   .buildMailer();

Including property support:

simplejavamail.custom.sslfactory.class=

@bbottema bbottema modified the milestones: 6.x.0, 6.3.0 Jul 11, 2020
@bbottema
Copy link
Owner

Released in 6.3.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants