From 62cd783942b901b86a1e846779591c765103b7ed Mon Sep 17 00:00:00 2001 From: Alexander Reelsen Date: Wed, 9 Dec 2015 10:04:15 +0100 Subject: [PATCH] Watcher: Fix sending of emails In order to be able to send emails, the thread context classs loader must be set to the watcher plugin class loader (and reset afterwards), otherwise some javax.activation classes needed to create mime attachments cannot be found. In addition the activation jar dependency has been removed. Closes elastic/elasticsearch#1066 Closes elastic/elasticsearch#708 Original commit: elastic/x-pack-elasticsearch@10042375ec90c564cb24f8058001a52d0c696fe9 --- elasticsearch/x-pack/build.gradle | 1 - .../plugin-metadata/plugin-security.policy | 7 +++++ .../actions/email/service/Account.java | 27 +++++++++++++++++++ 3 files changed, 34 insertions(+), 1 deletion(-) diff --git a/elasticsearch/x-pack/build.gradle b/elasticsearch/x-pack/build.gradle index 6177348c490..f3dbd004d1b 100644 --- a/elasticsearch/x-pack/build.gradle +++ b/elasticsearch/x-pack/build.gradle @@ -33,7 +33,6 @@ dependencies { compile 'com.google.guava:guava:16.0.1' // needed by watcher and shield tests for jimfs compile 'com.google.code.findbugs:jsr305:3.0.1' // TODO: remove this compile 'com.sun.mail:javax.mail:1.5.3' - compile 'javax.activation:activation:1.1.1' testCompile 'org.subethamail:subethasmtp:3.1.7' // common test deps diff --git a/elasticsearch/x-pack/src/main/plugin-metadata/plugin-security.policy b/elasticsearch/x-pack/src/main/plugin-metadata/plugin-security.policy index 1195dcbd196..9d28ff039ef 100644 --- a/elasticsearch/x-pack/src/main/plugin-metadata/plugin-security.policy +++ b/elasticsearch/x-pack/src/main/plugin-metadata/plugin-security.policy @@ -4,4 +4,11 @@ grant { // needed to set expert SSL options, etc permission java.lang.RuntimePermission "setFactory"; + + // needed when sending emails for javax.activation + // otherwise a classnotfound exception is thrown due to trying + // to load the class with the application class loader + permission java.lang.RuntimePermission "setContextClassLoader"; + permission java.lang.RuntimePermission "getClassLoader"; + }; diff --git a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/actions/email/service/Account.java b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/actions/email/service/Account.java index 0d11598da76..421fb8e3ce8 100644 --- a/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/actions/email/service/Account.java +++ b/elasticsearch/x-pack/watcher/src/main/java/org/elasticsearch/watcher/actions/email/service/Account.java @@ -99,6 +99,7 @@ public class Account { } transport.connect(config.smtp.host, config.smtp.port, user, password); + ClassLoader contextClassLoader = null; try { MimeMessage message = profile.toMimeMessage(email, session); String mid = message.getMessageID(); @@ -108,6 +109,17 @@ public class Account { // we need to add it back message.setHeader(Profile.MESSAGE_ID_HEADER, mid); } + + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + // unprivileged code such as scripts do not have SpecialPermission + sm.checkPermission(new SpecialPermission()); + } + contextClassLoader = AccessController.doPrivileged((PrivilegedAction) () -> Thread.currentThread().getContextClassLoader()); + // if we cannot get the context class loader, changing does not make sense, as we run into the danger of not being able to change it back + if (contextClassLoader != null) { + setContextClassLoader(this.getClass().getClassLoader()); + } transport.sendMessage(message, message.getAllRecipients()); } finally { try { @@ -115,10 +127,25 @@ public class Account { } catch (MessagingException me) { logger.error("failed to close email transport for account [" + config.name + "]"); } + if (contextClassLoader != null) { + setContextClassLoader(contextClassLoader); + } } return email; } + private void setContextClassLoader(final ClassLoader classLoader) { + SecurityManager sm = System.getSecurityManager(); + if (sm != null) { + // unprivileged code such as scripts do not have SpecialPermission + sm.checkPermission(new SpecialPermission()); + } + AccessController.doPrivileged((PrivilegedAction) () -> { + Thread.currentThread().setContextClassLoader(classLoader); + return null; + }); + } + static class Config { static final String SMTP_SETTINGS_PREFIX = "mail.smtp.";