ews-java-api
ews-java-api copied to clipboard
Self-signed certificates accepted by default
By default an EwsSSLProtocolSocketFactory
is configured, which uses an EwsX509TrustManager
, which accepts all self-signed certificates by default. This is a major security risk.
Our ews-java-api repo is a bit out-of-date, so I don't have a PR, but the following should be done:
- Remove
EwsSSLProtocolSocketFactory
- Remove
EwsX509TrustManager
- Do not set a registry on the
HttpClientConnectionManager
s by default - Allow library users to specify a
SSLConnectionSocketFactory
, if they do this pass a custom registry to theHttpClientConnectionManager
. This way they can specify a custom trust level themselves.
See https://github.com/eveoh/ews-java-api/commit/f276356614865b3cb5658bff4374110cc9722d4c for a fix based on a somewhat older ews-java-api version.
It seems impossible to ignore certificate. I tried a solution provided on StackOverflow by replacing the trust manager. However, it seems the EWS module either does not the default SSL factory or it overrides this. Is there a method on ExchangeServer class which can be called to ignore certificate checks?
Hi @johnbester,
this is my simplified implementation to accept/ignore certificates. If you do some more logic in the isTrusted()
method, you can make it fit your needs. Actually it'll accept all certs.
public class CustomExchangeService extends ExchangeService
{
private static final Logger LOGGER = LoggerFactory.getLogger(CustomExchangeService.class);
public CustomExchangeService(ExchangeVersion requestedServerVersion) throws Exception
{
super(requestedServerVersion);
initializeHttpClient();
}
private void initializeHttpClient() throws Exception
{
Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory>create()
.register(EWSConstants.HTTP_SCHEME, new PlainConnectionSocketFactory())
.register(EWSConstants.HTTPS_SCHEME, EwsSSLProtocolSocketFactory.build(
null, NoopHostnameVerifier.INSTANCE
))
.build();
HttpClientConnectionManager httpConnectionManager = new PoolingHttpClientConnectionManager(registry);
AuthenticationStrategy authStrategy = new CookieProcessingTargetAuthenticationStrategy();
httpClient = HttpClients.custom()
.setConnectionManager(httpConnectionManager)
.setTargetAuthenticationStrategy(authStrategy)
.setSSLContext(new SSLContextBuilder().loadTrustMaterial(null, new TrustStrategy()
{
public boolean isTrusted(X509Certificate[] arg0, String arg1) throws CertificateException
{
for (X509Certificate certificate : arg0)
{
LOGGER.debug("Check isTrusted for {}.", certificate.toString());
}
return true;
}
}).build())
.build();
}
}
Thanks - this should do the trick!
@OS-JaR & @johnbester The code worked after slight modification(adding a trust manager), however its working for sending email but could not able to make it work for subscribeToPullNotifications. It seems the method uses original ExchangeServer instead of custom one created. Could you please suggest the solution?
Is there any reason why the insecure EwsX509TrustManager
is still not removed?
If this class can't be removed there should be at least a big waring in JavaDoc explaining that this TrustManager is insecure plus I would mark the class as deprecated.
Is there any reason why the insecure EwsX509TrustManager is still not removed?
This project is dead, buggy and unmaintained. I would simply advise against using it.