Skip to content

Commit

Permalink
[JENKINS-2206] Configuration to use TLS
Browse files Browse the repository at this point in the history
- new option in jelly config form to enable/disable TLS usage
- new attribute to handle boolean option
- new javaMail properties used when TLS option is selected
- validation of default TLS port 587 if no port is defined by user
- testEmail method modified to use new parameter
- Spanish translation for new form field added
  • Loading branch information
Nelson Alvarez committed Dec 5, 2019
1 parent e0fc1a9 commit 287b562
Show file tree
Hide file tree
Showing 3 changed files with 49 additions and 10 deletions.
53 changes: 44 additions & 9 deletions src/main/java/hudson/tasks/Mailer.java
Original file line number Diff line number Diff line change
Expand Up @@ -297,6 +297,11 @@ public static final class DescriptorImpl extends BuildStepDescriptor<Publisher>
*/
private boolean useSsl;

/**
* If true use TLS on port 587 (standard STARTTLS) unless <code>smtpPort</code> is set.
*/
private boolean useTls;

/**
* The SMTP port to use for sending e-mail. Null for default to the environment,
* which is usually <tt>25</tt>.
Expand Down Expand Up @@ -343,17 +348,20 @@ public void setReplyToAddress(String address) {
* @return mail session based on the underlying session parameters.
*/
public Session createSession() {
return createSession(smtpHost,smtpPort,useSsl,getSmtpAuthUserName(),getSmtpAuthPasswordSecret());
return createSession(smtpHost,smtpPort,useSsl,useTls,getSmtpAuthUserName(),getSmtpAuthPasswordSecret());
}
private static Session createSession(String smtpHost, String smtpPort, boolean useSsl, String smtpAuthUserName, Secret smtpAuthPassword) {
private static Session createSession(String smtpHost, String smtpPort, boolean useSsl, boolean useTls, String smtpAuthUserName, Secret smtpAuthPassword) {
final String SMTP_PORT_PROPERTY = "mail.smtp.port";
final String SMTP_SOCKETFACTORY_PORT_PROPERTY = "mail.smtp.socketFactory.port";

smtpPort = fixEmptyAndTrim(smtpPort);
smtpAuthUserName = fixEmptyAndTrim(smtpAuthUserName);

Properties props = new Properties(System.getProperties());
if(fixEmptyAndTrim(smtpHost)!=null)
props.put("mail.smtp.host",smtpHost);
if (smtpPort!=null) {
props.put("mail.smtp.port", smtpPort);
props.put(SMTP_PORT_PROPERTY, smtpPort);
}
if (useSsl) {
/* This allows the user to override settings by setting system properties but
Expand All @@ -362,16 +370,35 @@ private static Session createSession(String smtpHost, String smtpPort, boolean u
* and thats done in mail sender, and it would be a bit of a hack to get it all to
* coordinate, and we can make it work through setting mail.smtp properties.
*/
if (props.getProperty("mail.smtp.socketFactory.port") == null) {
if (props.getProperty(SMTP_SOCKETFACTORY_PORT_PROPERTY) == null) {
String port = smtpPort==null?"465":smtpPort;
props.put("mail.smtp.port", port);
props.put("mail.smtp.socketFactory.port", port);
props.put(SMTP_PORT_PROPERTY, port);
props.put(SMTP_SOCKETFACTORY_PORT_PROPERTY, port);
}
if (props.getProperty("mail.smtp.socketFactory.class") == null) {
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
// TODO SocketFactory properties are now discouraged. Using (`mail.smtp.ssl.enable`, "true") should suffice
// https://javaee.github.io/javamail/FAQ#commonmistakes
// Example also found at https://javaee.github.io/javamail/FAQ#smtpssl
props.put("mail.smtp.socketFactory.class","javax.net.ssl.SSLSocketFactory");
}
props.put("mail.smtp.socketFactory.fallback", "false");
}
if(useTls){
/* This allows the user to override settings by setting system properties and
* also allows us to use the default STARTTLS port, 587, if no port is already set.
* Only the properties included below are required to use STARTTLS and they are
* not expected to be enabled simultaneously with SSL (it will actually throw a
* "javax.net.ssl.SSLException: Unrecognized SSL message, plaintext connection?"
* if SMTP server expects only TLS).
*/
if (props.getProperty(SMTP_SOCKETFACTORY_PORT_PROPERTY) == null) {
String port = smtpPort==null?"587":smtpPort;
props.put(SMTP_PORT_PROPERTY, port);
props.put(SMTP_SOCKETFACTORY_PORT_PROPERTY, port);
}
props.put("mail.smtp.starttls.enable", "true");
props.put("mail.smtp.starttls.required", "true");
}
if(smtpAuthUserName!=null)
props.put("mail.smtp.auth","true");

Expand All @@ -395,6 +422,7 @@ protected PasswordAuthentication getPasswordAuthentication() {
@Override
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {

// TODO try-with-resources for BulkChange instance?
BulkChange b = new BulkChange(this);
// Nested Describable (SMTPAuthentication) is not set to null in case it is not configured.
// To mitigate that, it is being set to null before (so it gets set to sent value or null correctly) and, in
Expand Down Expand Up @@ -541,6 +569,12 @@ public void setUseSsl(boolean useSsl) {
save();
}

@DataBoundSetter
public void setUseTls(boolean useTls) {
this.useTls = useTls;
save();
}

@DataBoundSetter
public void setSmtpPort(String smtpPort) {
this.smtpPort = smtpPort;
Expand Down Expand Up @@ -635,6 +669,7 @@ public FormValidation doCheckDefaultSuffix(@QueryParameter String value) {
* @param username plaintext username for SMTP authentication
* @param password secret password for SMTP authentication
* @param useSsl if set to {@code true} SSL is used
* @param useTls if set to {@code true} TLS is used
* @param smtpPort port to use for SMTP transfer
* @param charset charset of the underlying MIME-mail message
* @param sendTestMailTo mail address to send test mail to
Expand All @@ -644,7 +679,7 @@ public FormValidation doCheckDefaultSuffix(@QueryParameter String value) {
public FormValidation doSendTestMail(
@QueryParameter String smtpHost, @QueryParameter String adminAddress, @QueryParameter boolean authentication,
@QueryParameter String username, @QueryParameter Secret password,
@QueryParameter boolean useSsl, @QueryParameter String smtpPort, @QueryParameter String charset,
@QueryParameter boolean useSsl, @QueryParameter boolean useTls, @QueryParameter String smtpPort, @QueryParameter String charset,
@QueryParameter String sendTestMailTo) throws IOException {
try {
// TODO 1.590+ Jenkins.getActiveInstance
Expand All @@ -660,7 +695,7 @@ public FormValidation doSendTestMail(
password = null;
}

MimeMessage msg = new MimeMessage(createSession(smtpHost, smtpPort, useSsl, username, password));
MimeMessage msg = new MimeMessage(createSession(smtpHost, smtpPort, useSsl, useTls, username, password));
msg.setSubject(Messages.Mailer_TestMail_Subject(testEmailCount.incrementAndGet()), charset);
msg.setText(Messages.Mailer_TestMail_Content(testEmailCount.get(), jenkins.getDisplayName()), charset);
msg.setFrom(stringToAddress(adminAddress, charset));
Expand Down
5 changes: 4 additions & 1 deletion src/main/resources/hudson/tasks/Mailer/global.jelly
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,9 @@ THE SOFTWARE.
<f:entry title="${%Use SSL}" field="useSsl">
<f:checkbox />
</f:entry>
<f:entry title="${%Use TLS}" field="useTls">
<f:checkbox />
</f:entry>
<f:entry title="${%SMTP Port}" field="smtpPort">
<f:textbox />
</f:entry>
Expand All @@ -52,7 +55,7 @@ THE SOFTWARE.
<f:entry title="${%Test e-mail recipient}">
<f:textbox name="sendTestMailTo"/>
</f:entry>
<f:validateButton method="sendTestMail" title="${%Test configuration}" with="sendTestMailTo,smtpHost,adminAddress,authentication,username,password,useSsl,smtpPort,charset" />
<f:validateButton method="sendTestMail" title="${%Test configuration}" with="sendTestMailTo,smtpHost,adminAddress,authentication,username,password,useSsl,useTls,smtpPort,charset" />
</f:optionalBlock>
</f:section>
</j:jelly>
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ Sender\ E-mail\ Address=Direcci\u00F3n de remitente
System\ Admin\ E-mail\ Address=Direcci\u00F3n de email del administrador del sistema
Jenkins\ URL=Direcci\u00F3n web de Jenkins
Use\ SSL=Usar seguridad SSL
Use\ TLS=Usar seguridad TLS (STARTTLS)
SMTP\ Port=Puerto de SMTP
Reply-To\ Address=Direcci\u00F3n para la respuesta
Charset=Juego de caracteres

0 comments on commit 287b562

Please sign in to comment.