PR: 19180 git-svn-id: https://svn.apache.org/repos/asf/ant/core/trunk@274636 13f79535-47bb-0310-9956-ffa450edef68master
@@ -307,6 +307,9 @@ The implementation only with JavaMail (encoding="MIME"). | |||||
Implementation with plain mail remains to do. | Implementation with plain mail remains to do. | ||||
Bugzilla Report 5969. | Bugzilla Report 5969. | ||||
* <mail> and mailloger support SMTP over TLS/SSL | |||||
Bugzilla Report 19180. | |||||
* <zipfileset> can now be defined in the main body of a project | * <zipfileset> can now be defined in the main body of a project | ||||
and referred to with refid="xyz". Bugzilla Report 17007. | and referred to with refid="xyz". Bugzilla Report 17007. | ||||
@@ -13,7 +13,7 @@ | |||||
This task can send mail using either plain | This task can send mail using either plain | ||||
text, UU encoding, or MIME format mail, depending on what is available.<br/> | text, UU encoding, or MIME format mail, depending on what is available.<br/> | ||||
<br/> | <br/> | ||||
If you need SMTP auth, you have to use MIME (and therefore to install JavaMail).<br/><br/> | |||||
SMTP auth and SSL/TLS require JavaMail and are only available in MIME format.<br/><br/> | |||||
Attachments may be sent using nested | Attachments may be sent using nested | ||||
<a href="../CoreTypes/fileset.html">fileset</a> elements.</p> | <a href="../CoreTypes/fileset.html">fileset</a> elements.</p> | ||||
<p><strong>Note:</strong> This task may depend on external libraries | <p><strong>Note:</strong> This task may depend on external libraries | ||||
@@ -113,6 +113,12 @@ Library Dependencies</a> for more information. | |||||
<td valign="center">Yes, if SMTP auth is required on your SMTP server<br/> | <td valign="center">Yes, if SMTP auth is required on your SMTP server<br/> | ||||
the email message will be then sent using Mime and requires JavaMail</td> | the email message will be then sent using Mime and requires JavaMail</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td valign="top">ssl</td> | |||||
<td valign="top">"true", "on" or "yes" accepted here<br/> | |||||
indicates whether you need TLS/SSL</td> | |||||
<td valign="center">No</td> | |||||
</tr> | |||||
<tr> | <tr> | ||||
<td valign="top">encoding</td> | <td valign="top">encoding</td> | ||||
<td valign="top">Specifies the encoding to use for the content of the email. | <td valign="top">Specifies the encoding to use for the content of the email. | ||||
@@ -137,6 +137,13 @@ control for turning off success or failure messages individually.</p> | |||||
<td width="63%">Yes, if SMTP auth is required on your SMTP server<br/> | <td width="63%">Yes, if SMTP auth is required on your SMTP server<br/> | ||||
the email message will be then sent using Mime and requires JavaMail</td> | the email message will be then sent using Mime and requires JavaMail</td> | ||||
</tr> | </tr> | ||||
<tr> | |||||
<td width="337">MailLogger.ssl</td> | |||||
<td width="63%">on or true if ssl is needed<br/> | |||||
This feature requires JavaMail</td> | |||||
<td width="63%"> | |||||
no</td> | |||||
</tr> | |||||
<tr> | <tr> | ||||
<td width="337">MailLogger.from</td> | <td width="337">MailLogger.from</td> | ||||
<td width="63%">Mail "from" address</td> | <td width="63%">Mail "from" address</td> | ||||
@@ -10,6 +10,15 @@ | |||||
</message> | </message> | ||||
</mail> | </mail> | ||||
</target> | </target> | ||||
<target name="test2"> | |||||
<!-- this test is supposed to bring a build exception because SSL is not allowed with plain encoding --> | |||||
<mail host="localhost" port="465" from="joe@abc.com" to="laura@xyz.com" subject="hello" encoding="plain" ssl="true"> | |||||
<message> | |||||
Hi Laura, how are you doing ? | |||||
</message> | |||||
</mail> | |||||
</target> | |||||
</project> | </project> |
@@ -157,16 +157,18 @@ public class MailLogger extends DefaultLogger { | |||||
int port = Integer.parseInt(getValue(properties,"port",String.valueOf(MailMessage.DEFAULT_PORT))); | int port = Integer.parseInt(getValue(properties,"port",String.valueOf(MailMessage.DEFAULT_PORT))); | ||||
String user = getValue(properties, "user", ""); | String user = getValue(properties, "user", ""); | ||||
String password = getValue(properties, "password", ""); | String password = getValue(properties, "password", ""); | ||||
boolean ssl = Project.toBoolean(getValue(properties, | |||||
"ssl", "off")); | |||||
String from = getValue(properties, "from", null); | String from = getValue(properties, "from", null); | ||||
String replytoList = getValue(properties,"replyto",""); | String replytoList = getValue(properties,"replyto",""); | ||||
String toList = getValue(properties, prefix + ".to", null); | String toList = getValue(properties, prefix + ".to", null); | ||||
String subject = getValue(properties, prefix + ".subject", | String subject = getValue(properties, prefix + ".subject", | ||||
(success) ? "Build Success" : "Build Failure"); | (success) ? "Build Success" : "Build Failure"); | ||||
if (user.equals("") && password.equals("")) { | |||||
if (user.equals("") && password.equals("") && !ssl) { | |||||
sendMail(mailhost, port, from, replytoList, toList, subject, buffer.substring(0)); | sendMail(mailhost, port, from, replytoList, toList, subject, buffer.substring(0)); | ||||
} | } | ||||
else { | else { | ||||
sendMimeMail(event.getProject(), mailhost, port, user, password, from, replytoList, toList, subject, buffer.substring(0)); | |||||
sendMimeMail(event.getProject(), mailhost, port, user, password, ssl, from, replytoList, toList, subject, buffer.substring(0)); | |||||
} | } | ||||
} catch (Exception e) { | } catch (Exception e) { | ||||
System.out.println("MailLogger failed to send e-mail!"); | System.out.println("MailLogger failed to send e-mail!"); | ||||
@@ -256,15 +258,16 @@ public class MailLogger extends DefaultLogger { | |||||
* @param port mail server port number | * @param port mail server port number | ||||
* @param user user name for SMTP auth | * @param user user name for SMTP auth | ||||
* @param password password for SMTP auth | * @param password password for SMTP auth | ||||
* @param ssl if true send message over SSL | |||||
* @param from from address | * @param from from address | ||||
* @param replyToString comma-separated replyto list | * @param replyToString comma-separated replyto list | ||||
* @param toString comma-separated recipient list | * @param toString comma-separated recipient list | ||||
* @param subject mail subject | * @param subject mail subject | ||||
* @param message mail body | * @param message mail body | ||||
* @exception IOException thrown if sending message fails | |||||
*/ | */ | ||||
private void sendMimeMail(Project project, String host, int port, String user, String password, String from, String replyToString, String toString, | |||||
String subject, String message) throws IOException { | |||||
private void sendMimeMail(Project project, String host, int port, String user, String password, boolean ssl, | |||||
String from, String replyToString, String toString, | |||||
String subject, String message) { | |||||
// convert the replyTo string into a vector of emailaddresses | // convert the replyTo string into a vector of emailaddresses | ||||
Mailer mailer = null; | Mailer mailer = null; | ||||
try { | try { | ||||
@@ -280,6 +283,7 @@ public class MailLogger extends DefaultLogger { | |||||
mailer.setPort(port); | mailer.setPort(port); | ||||
mailer.setUser(user); | mailer.setUser(user); | ||||
mailer.setPassword(password); | mailer.setPassword(password); | ||||
mailer.setSSL(ssl); | |||||
Message mymessage = new Message(message); | Message mymessage = new Message(message); | ||||
mymessage.setProject(project); | mymessage.setProject(project); | ||||
mailer.setMessage(mymessage); | mailer.setMessage(mymessage); | ||||
@@ -108,7 +108,6 @@ public class EmailTask | |||||
} | } | ||||
} | } | ||||
private String encoding = AUTO; | private String encoding = AUTO; | ||||
/** host running SMTP */ | /** host running SMTP */ | ||||
private String host = "localhost"; | private String host = "localhost"; | ||||
@@ -146,6 +145,8 @@ public class EmailTask | |||||
private String user=null; | private String user=null; | ||||
/** Password for SMTP auth */ | /** Password for SMTP auth */ | ||||
private String password=null; | private String password=null; | ||||
/** indicate if the user wishes SSL-TLS */ | |||||
private boolean SSL = false; | |||||
/** | /** | ||||
* sets the user for SMTP auth; this requires JavaMail | * sets the user for SMTP auth; this requires JavaMail | ||||
@@ -165,6 +166,15 @@ public class EmailTask | |||||
this.password = password; | this.password = password; | ||||
} | } | ||||
/** | |||||
* tells if the user needs to send his data over SSL | |||||
* @param SSL | |||||
* @since ant 1.6 | |||||
*/ | |||||
public void setSSL(boolean SSL) { | |||||
this.SSL = SSL; | |||||
} | |||||
/** | /** | ||||
* Allows the build writer to choose the preferred encoding method | * Allows the build writer to choose the preferred encoding method | ||||
* | * | ||||
@@ -466,9 +476,14 @@ public class EmailTask | |||||
} | } | ||||
} | } | ||||
// SMTP auth only allowed with MIME mail | // SMTP auth only allowed with MIME mail | ||||
if (autoFound==false && ((user !=null) || (password != null)) && (encoding.equals(UU) || encoding.equals(PLAIN))) { | |||||
if (autoFound==false && ((user !=null) || (password != null) ) && (encoding.equals(UU) || encoding.equals(PLAIN))) { | |||||
throw new BuildException("SMTP auth only possible with MIME mail"); | throw new BuildException("SMTP auth only possible with MIME mail"); | ||||
} | } | ||||
// SSL only allowed with MIME mail | |||||
if (autoFound==false && (SSL) && (encoding.equals(UU) || encoding.equals(PLAIN))) { | |||||
throw new BuildException("SSL only possible with MIME mail"); | |||||
} | |||||
// try UU format | // try UU format | ||||
if (encoding.equals(UU) | if (encoding.equals(UU) | ||||
@@ -564,6 +579,7 @@ public class EmailTask | |||||
mailer.setPort(port); | mailer.setPort(port); | ||||
mailer.setUser(user); | mailer.setUser(user); | ||||
mailer.setPassword(password); | mailer.setPassword(password); | ||||
mailer.setSSL(SSL); | |||||
mailer.setMessage(message); | mailer.setMessage(message); | ||||
mailer.setFrom(from); | mailer.setFrom(from); | ||||
mailer.setReplyToList(replyToList); | mailer.setReplyToList(replyToList); | ||||
@@ -69,6 +69,7 @@ public abstract class Mailer { | |||||
protected int port = -1; | protected int port = -1; | ||||
protected String user = null; | protected String user = null; | ||||
protected String password = null; | protected String password = null; | ||||
protected boolean SSL = false; | |||||
protected Message message; | protected Message message; | ||||
protected EmailAddress from; | protected EmailAddress from; | ||||
protected Vector replyToList = null; | protected Vector replyToList = null; | ||||
@@ -103,6 +104,7 @@ public abstract class Mailer { | |||||
* Sets the user for smtp auth | * Sets the user for smtp auth | ||||
* | * | ||||
* @param user | * @param user | ||||
* @since ant 1.6 | |||||
*/ | */ | ||||
public void setUser(String user) { | public void setUser(String user) { | ||||
this.user = user; | this.user = user; | ||||
@@ -112,11 +114,22 @@ public abstract class Mailer { | |||||
* Sets the password for smtp auth | * Sets the password for smtp auth | ||||
* | * | ||||
* @param password | * @param password | ||||
* @since ant 1.6 | |||||
*/ | */ | ||||
public void setPassword(String password) { | public void setPassword(String password) { | ||||
this.password = password; | this.password = password; | ||||
} | } | ||||
/** | |||||
* Sets whether the user wants to send the mail through SSL | |||||
* | |||||
* @param SSL | |||||
* @since ant 1.6 | |||||
*/ | |||||
public void setSSL(boolean SSL) { | |||||
this.SSL = SSL; | |||||
} | |||||
/** | /** | ||||
* Sets the message | * Sets the message | ||||
* | * | ||||
@@ -66,6 +66,7 @@ import java.util.Enumeration; | |||||
import java.util.Properties; | import java.util.Properties; | ||||
import java.util.StringTokenizer; | import java.util.StringTokenizer; | ||||
import java.util.Vector; | import java.util.Vector; | ||||
import java.security.Security; | |||||
import javax.activation.DataHandler; | import javax.activation.DataHandler; | ||||
import javax.activation.FileDataSource; | import javax.activation.FileDataSource; | ||||
@@ -157,6 +158,19 @@ public class MimeMailer extends Mailer { | |||||
// alcohol :-) | // alcohol :-) | ||||
Session sesh; | Session sesh; | ||||
Authenticator auth; | Authenticator auth; | ||||
if (SSL) { | |||||
try { | |||||
java.security.Provider p=(java.security.Provider)Class.forName( "com.sun.net.ssl.internal.ssl.Provider").newInstance(); | |||||
Security.addProvider(p); | |||||
} | |||||
catch (Exception e) { | |||||
throw new BuildException("could not instantiate ssl security provider, check that you have JSSE in your classpath"); | |||||
} | |||||
final String SSL_FACTORY = "javax.net.ssl.SSLSocketFactory"; | |||||
// SMTP provider | |||||
props.put( "mail.smtp.socketFactory.class", SSL_FACTORY); | |||||
props.put( "mail.smtp.socketFactory.fallback", "false"); | |||||
} | |||||
if (user==null && password == null) { | if (user==null && password == null) { | ||||
sesh = Session.getDefaultInstance(props, null); | sesh = Session.getDefaultInstance(props, null); | ||||
} | } | ||||
@@ -165,7 +179,6 @@ public class MimeMailer extends Mailer { | |||||
auth = new SimpleAuthenticator(user,password); | auth = new SimpleAuthenticator(user,password); | ||||
sesh = Session.getInstance(props,auth); | sesh = Session.getInstance(props,auth); | ||||
} | } | ||||
//create the message | //create the message | ||||
MimeMessage msg = new MimeMessage(sesh); | MimeMessage msg = new MimeMessage(sesh); | ||||
MimeMultipart attachments = new MimeMultipart(); | MimeMultipart attachments = new MimeMultipart(); | ||||
@@ -52,9 +52,8 @@ | |||||
* <http://www.apache.org/>. | * <http://www.apache.org/>. | ||||
*/ | */ | ||||
package org.apache.tools.ant.taskdefs; | |||||
package org.apache.tools.ant.taskdefs.email; | |||||
import java.io.File; | |||||
import org.apache.tools.ant.BuildFileTest; | import org.apache.tools.ant.BuildFileTest; | ||||
/** | /** | ||||
@@ -62,19 +61,22 @@ import org.apache.tools.ant.BuildFileTest; | |||||
* to simulate sending mail and to catch the output in text files or streams | * to simulate sending mail and to catch the output in text files or streams | ||||
* @author <a href="mailto:levylambert@tiscali-dsl.de">Antoine Levy-Lambert</a> | * @author <a href="mailto:levylambert@tiscali-dsl.de">Antoine Levy-Lambert</a> | ||||
*/ | */ | ||||
public class EmailTaskTest extends BuildFileTest { | |||||
public class EmailTaskTest extends BuildFileTest { | |||||
public EmailTaskTest(String name) { | |||||
public EmailTaskTest(String name) { | |||||
super(name); | super(name); | ||||
} | } | ||||
public void setUp() { | public void setUp() { | ||||
configureProject("src/etc/testcases/taskdefs/mail.xml"); | |||||
configureProject("src/etc/testcases/taskdefs/email/mail.xml"); | |||||
} | } | ||||
public void test1() { | public void test1() { | ||||
expectBuildException("test1", "SMTP auth only possible with MIME mail"); | expectBuildException("test1", "SMTP auth only possible with MIME mail"); | ||||
} | } | ||||
public void test2() { | |||||
expectBuildException("test2", "SSL only possible with MIME mail"); | |||||
} | |||||
} | } |