Java Runtime.exec() not sending emails as from the command line
java, linux, macos
Solution
`Runtime.exec(String)` does not execute the entire string by pasting it into a UNIX shell and running it. This is because it's a huge security flaw.
Imagine you did this:
runtime.exec("Hello "+name+" | mail ...");
I could then set `name` to `; rm -rf /*; echo` or `&& cat /etc/passwd`, or some other shell injection code.
So, Java is breaking up your command into parts:
More precisely, the command string is broken into tokens using a StringTokenizer created by the call new StringTokenizer(command) with no further modification of the character categories. The tokens produced by the tokenizer are then placed in the new string array cmdarray, in the same order.
Ultimately, you are running the `echo` command alone, with parameters such as `|` and `mail`. The `echo` command will just print these out to standard output, which you don't collect. It will never invoke the `mail` command.
You shouldn't use the `mail` command to send mail from Java, due to the security risks involved. You should use the JavaMail package which provides a safe and convenient API for sending mail. The UNIX `mail` command works by connecting to a `sendmail` daemon running on the local machine on port 25, and JavaMail can do this too.
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMessage.RecipientType;
public class SendMail {
public static sendMail(String from, String to, String subject, String body)
throws MessagingException
{
final Properties p = new Properties();
p.put("mail.smtp.host", "localhost");
final Message msg = new MimeMessage(Session.getDefaultInstance(p));
msg.setFrom(new InternetAddress(from));
msg.addRecipient(RecipientType.TO, new InternetAddress(to));
msg.setSubject(subject);
msg.setText(body);
Transport.send(msg);
}
}
Problem
I'm creating a java application and one of the features I would like to add is sending a generated email out to users. I have set up mail on my Macbook and I can send emails from the command line just fine. I'm having an issue sending emails when I call runtime.exec(). Anyone have any idea why it will not execute and send the emails? ``` Runtime runtime = Runtime.getRuntime(); try { runtime.exec("echo This is the body | mail -s Subject -F myemail@gmail.com"); } catch ( Exception e ) { // TODO Auto-generated catch block e.printStackTrace(); } ``` I don't get any errors and everything compiles fine. I just don't get any emails sent out. If anyone could hel it would be much appreciated thanks.