Java/Network Protocol/Email
Содержание
- 1 A Client to Send SMTP Mail
- 2 Get Email Message Example
- 3 Mailer: Sends an email message
- 4 Pure Java Email client
- 5 Read a file return mail headers one at a time
- 6 Sender -- send an email message
- 7 Sender -- send an email message with attachment
- 8 Sending Mail
- 9 Sending Mail Using Sockets
- 10 SendMime -- send a multi-part MIME email message
- 11 TestOpenMailRelay -- send self-returning SPAM to check for relay sites
A Client to Send SMTP Mail
import java.awt.*;
import javax.swing.*;
/**
* Example program from Chapter 1 Programming Spiders, Bots and Aggregators in
* Java Copyright 2001 by Jeff Heaton
*
* SendMail is an example of client sockets. This program presents a simple
* dialog box that prompts the user for information about how to send a mail.
*
* @author Jeff Heaton
* @version 1.0
*/
/*
* Using the SMTP Program
*
* To use the program in Listing 1.2, you must know the address of an SMTP
* server usually provided by your ISP. If you are unsure of your SMTP server,
* you should contact your ISP"s customer service. In order for outbound e-mail
* messages to be sent, your e-mail program must have this address. Once it
* does, you can enter who is sending the e-mail (if you are sending it, you
* would type your e-mail address in) and who will be on the receiving end. This
* is usually entered under the Reply To field of your e-mail program. Both of
* these addresses must be valid. If they are invalid, the e-mail may not be
* sent. After you have entered these addresses, you should continue by entering
* the subject, writing the actual message, and then clicking send. Note
*
* For more information on how to compile examples in this book, see Appendix E
* "How to Compile Examples Under Windows."
*
* As stated earlier, to send an e-mail with this program, you must enter who is
* sending the message. You may be thinking that you could enter any e-mail
* address you want here, right? Yes, this is true; as long as the SMTP server
* allows it, this program will allow you to impersonate anyone you enter into
* the To address field. However, as previously stated, a savvy Internet user
* can tell whether the e-mail address is fake.
*
* After the mention of possible misrepresentation of identity on the sender"s
* end, you may now be asking yourself, Is this program dangerous? This
* program is no more dangerous than any e-mail client (such as Microsoft
* Outlook Express or Eudora) that also requires you to tell it who you are. In
* general, all e-mail programs must request both your identity and that of the
* SMTP server. Examining the SMTP Server
*
* You will now be shown how this program works. We will begin by looking at how
* a client socket is created. When the client socket is first instantiated, you
* must specify two parameters. First, you must specify the host to connect to;
* second, you must specify the port number (e.g., 80) you would like to connect
* on. These two items are generally passed into the constructor. The following
* line of code (from Listing 1.2) accomplishes this:
*
* java.net.Socket s =new java.net.Socket( _smtp.getText(),25 );
*
* This line of code creates a new socket, named s. The first parameter to the
* constructor, _smtp .getText(), specifies the address to connect to. Here it
* is being read directly from a text field. The second parameter specifies the
* port to connect to. (The port for SMTP is 25.) Table 1.1 shows a listing of
* the ports associated with most Internet services. The hostname is retrieved
* from the _smtp class level variable, which is the JTextField control that the
* SMTP hostname is entered into.
*
* If any errors occur while you are making the connection to the specified
* host, the Socket constructor will throw an IOException. Once this connection
* is made, input and output streams are obtained from the Socket.getInputStream
* and Socket.getOutputStream methods. This is done with the following lines of
* code from Listing 1.2:
*
* _out = new java.io.PrintWriter(s.getOutputStream());
* _in = new java.io.BufferedReader(new java.io.InputStreamReader(s.getInputStream()));
*
* These low-level stream types are only capable of reading binary data. Because
* this data is needed in text format, filters are used to wrap the lower-level
* input and output streams obtained from the socket.
*
* In the code above, the output stream has been wrapped in a PrintWriter
* object. This is because PrintWriter allows the program to output text to the
* socket in a similar manner to the way an application would write data to the
* System.out object by using the print and println methods. The application
* presented here uses the println method to send commands to the SMTP server.
* As you can see in the code, the InputStream object has also been wrapped; in
* this case, it has been wrapped in a BufferedReader. Before this could happen,
* however, this object must first have been wrapped in an InputStreamReader
* object as shown here:
*
* _in = new java.io.BufferedReader(new
* java.io.InputStreamReader(s.getInputStream()));
*
* This is done because the BufferedReader object provides reads that are made
* up of lines of text instead of individual bytes. This way, the program can
* read text up to a carriage return without having to parse the individual
* characters. This is done with the readLine method.
*
* You will now be shown how each command is sent to the SMTP server. Each of
* these commands that is sent results in a response being issued from the SMTP
* server. For the protocol to work correctly, each response must be read by the
* SMTP client program. These responses start with a number and then they give a
* textual description of what the result was. A full-featured SMTP client
* should examine these codes and ensure that no error has occurred.
*
* For the purposes of the SendMail example, we will simple ignore these
* responses because most are informational and not needed. Instead, for our
* purposes, the response will be read in and displayed to the _output list box.
* Commands that have been sent to the server are displayed in this list with a
* C: prefix to indicate that they are from the client. Responses returned from
* the SMTP server will be displayed with the S: prefix.
*
* To accomplish this, the example program will use the send method. The send
* method accepts a single String parameter to indicate the SMTP command to be
* issued. Once this command is sent, the send method awaits a response from the
* SMTP host. The portion of Listing 1.2 that contains the send method is
* displayed here:
*
* protected void send(String s) throws java.io.IOException {
// Send the SMTP command
if(s!=null) {
_model.addElement("C:"+s);
_out.println(s);
_out.flush(); }
// Wait for the response
String line = _in.readLine();
if(line!=null) {
_model.addElement("S:"+line);
}
}
*
* As you can see, the send method does not handle the exceptions that might
* occur from its commands. Instead, they are thrown to the calling method as
* indicated by the throws clause of the function declaration. The variable s is
* checked to see if it is null. If s is null, then no command is to be sent and
* only a response is sought. If s is not null, then the value of s is logged
* and then sent to the socket. After this happens, the flush command is given
* to the socket to ensure that the command was actually sent and not just
* buffered. Once the command is sent, the readLine method is called to await
* the response from the server. If a response is sent, then it is logged.
*
* Once the socket is created and the input and output objects are created, the
* SMTP session can begin. The following commands manage the entire SMTP
* session:
*
* send(null);
* send("HELO " + java.net.InetAddress.getLocalHost().getHostName() );
* send("MAIL FROM: " + _from.getText() ); send("RCPT TO: " + _to.getText() );
* send("DATA");
* _out.println("Subject:" + _subject.getText()); _out.println(
* _body.getText() ); send("."); s.close();
*
* Tip
*
* Refer to Table 1.4 in the preceding section to review the details of what
* each of the SMTP commands actually means.
*
* The rest of the SendMail program (as seen in Listing 1.2) is a typical Swing
* application. The graphical user interface (GUI) layout for this application
* was created using VisualCaf?. The VisualCaf? comments have been left in to
* allow the form"s GUI layout to be edited by VisualCaf? if you are using it.
* If you are using an environment other than VisualCaf?, you may safely delete
* the VisualCaf? comments (lines starting in //). The VisualCaf? code only
* consists of comments and does not need to be deleted to run on other
* platforms.
*
*/
public class SendMail extends javax.swing.JFrame {
/**
* The constructor. Do all basic setup for this application.
*/
public SendMail() {
//{{INIT_CONTROLS
setTitle("SendMail Example");
getContentPane().setLayout(null);
setSize(736, 312);
setVisible(false);
JLabel1.setText("From:");
getContentPane().add(JLabel1);
JLabel1.setBounds(12, 12, 36, 12);
JLabel2.setText("To:");
getContentPane().add(JLabel2);
JLabel2.setBounds(12, 48, 36, 12);
JLabel3.setText("Subject:");
getContentPane().add(JLabel3);
JLabel3.setBounds(12, 84, 48, 12);
JLabel4.setText("SMTP Server:");
getContentPane().add(JLabel4);
JLabel4.setBounds(12, 120, 84, 12);
getContentPane().add(_from);
_from.setBounds(96, 12, 300, 24);
getContentPane().add(_to);
_to.setBounds(96, 48, 300, 24);
getContentPane().add(_subject);
_subject.setBounds(96, 84, 300, 24);
getContentPane().add(_smtp);
_smtp.setBounds(96, 120, 300, 24);
getContentPane().add(_scrollPane2);
_scrollPane2.setBounds(12, 156, 384, 108);
_body.setText("Enter your message here.");
_scrollPane2.getViewport().add(_body);
_body.setBounds(0, 0, 381, 105);
Send.setText("Send");
Send.setActionCommand("Send");
getContentPane().add(Send);
Send.setBounds(60, 276, 132, 24);
Cancel.setText("Cancel");
Cancel.setActionCommand("Cancel");
getContentPane().add(Cancel);
Cancel.setBounds(216, 276, 120, 24);
getContentPane().add(_scrollPane);
_scrollPane.setBounds(408, 12, 312, 288);
getContentPane().add(_output);
_output.setBounds(408, 12, 309, 285);
//}}
//{{INIT_MENUS
//}}
//{{REGISTER_LISTENERS
SymAction lSymAction = new SymAction();
Send.addActionListener(lSymAction);
Cancel.addActionListener(lSymAction);
//}}
_output.setModel(_model);
_model.addElement("Server output displayed here:");
_scrollPane.getViewport().setView(_output);
_scrollPane2.getViewport().setView(_body);
}
/**
* Moves the app to the correct position when it is made visible.
*
* @param b
* True to make visible, false to make invisible.
*/
public void setVisible(boolean b) {
if (b)
setLocation(50, 50);
super.setVisible(b);
}
/**
* The main function basically just creates a new object, then shows it.
*
* @param args
* Command line arguments. Not used in this application.
*/
static public void main(String args[]) {
(new SendMail()).show();
}
/**
* Created by VisualCafe. Sets the window size.
*/
public void addNotify() {
// Record the size of the window prior to
// calling parents addNotify.
Dimension size = getSize();
super.addNotify();
if (frameSizeAdjusted)
return;
frameSizeAdjusted = true;
// Adjust size of frame according to the
// insets and menu bar
Insets insets = getInsets();
javax.swing.JMenuBar menuBar = getRootPane().getJMenuBar();
int menuBarHeight = 0;
if (menuBar != null)
menuBarHeight = menuBar.getPreferredSize().height;
setSize(insets.left + insets.right + size.width, insets.top
+ insets.bottom + size.height + menuBarHeight);
}
// Used by addNotify
boolean frameSizeAdjusted = false;
//{{DECLARE_CONTROLS
/**
* A label.
*/
javax.swing.JLabel JLabel1 = new javax.swing.JLabel();
/**
* A label.
*/
javax.swing.JLabel JLabel2 = new javax.swing.JLabel();
/**
* A label.
*/
javax.swing.JLabel JLabel3 = new javax.swing.JLabel();
/**
* A label.
*/
javax.swing.JLabel JLabel4 = new javax.swing.JLabel();
/**
* Who this message is from.
*/
javax.swing.JTextField _from = new javax.swing.JTextField();
/**
* Who this message is to.
*/
javax.swing.JTextField _to = new javax.swing.JTextField();
/**
* The subject of this message.
*/
javax.swing.JTextField _subject = new javax.swing.JTextField();
/**
* The SMTP server to use to send this message.
*/
javax.swing.JTextField _smtp = new javax.swing.JTextField();
/**
* A scroll pane.
*/
javax.swing.JScrollPane _scrollPane2 = new javax.swing.JScrollPane();
/**
* The body of this email message.
*/
javax.swing.JTextArea _body = new javax.swing.JTextArea();
/**
* The send button.
*/
javax.swing.JButton Send = new javax.swing.JButton();
/**
* The cancel button.
*/
javax.swing.JButton Cancel = new javax.swing.JButton();
/**
* A scroll pain.
*/
javax.swing.JScrollPane _scrollPane = new javax.swing.JScrollPane();
/**
* The output area. Server messages are displayed here.
*/
javax.swing.JList _output = new javax.swing.JList();
//}}
/**
* The list of items added to the output list box.
*/
javax.swing.DefaultListModel _model = new javax.swing.DefaultListModel();
/**
* Input from the socket.
*/
java.io.BufferedReader _in;
/**
* Output to the socket.
*/
java.io.PrintWriter _out;
//{{DECLARE_MENUS
//}}
/**
* Internal class created by VisualCafe to route the events to the correct
* functions.
*
* @author VisualCafe
* @version 1.0
*/
class SymAction implements java.awt.event.ActionListener {
/**
* Route the event to the correction method.
*
* @param event
* The event.
*/
public void actionPerformed(java.awt.event.ActionEvent event) {
Object object = event.getSource();
if (object == Send)
Send_actionPerformed(event);
else if (object == Cancel)
Cancel_actionPerformed(event);
}
}
/**
* Called to actually send a string of text to the socket. This method makes
* note of the text sent and the response in the JList output box. Pass a
* null value to simply wait for a response.
*
* @param s
* A string to be sent to the socket. null to just wait for a
* response.
* @exception java.io.IOException
*/
protected void send(String s) throws java.io.IOException {
// Send the SMTP command
if (s != null) {
_model.addElement("C:" + s);
_out.println(s);
_out.flush();
}
// Wait for the response
String line = _in.readLine();
if (line != null) {
_model.addElement("S:" + line);
}
}
/**
* Called when the send button is clicked. Actually sends the mail message.
*
* @param event
* The event.
*/
void Send_actionPerformed(java.awt.event.ActionEvent event) {
try {
java.net.Socket s = new java.net.Socket(_smtp.getText(), 25);
_out = new java.io.PrintWriter(s.getOutputStream());
_in = new java.io.BufferedReader(new java.io.InputStreamReader(s
.getInputStream()));
send(null);
send("HELO " + java.net.InetAddress.getLocalHost().getHostName());
send("MAIL FROM: " + _from.getText());
send("RCPT TO: " + _to.getText());
send("DATA");
_out.println("Subject:" + _subject.getText());
_out.println(_body.getText());
send(".");
s.close();
} catch (Exception e) {
_model.addElement("Error: " + e);
}
}
/**
* Called when cancel is clicked. End the application.
*
* @param event
* The event.
*/
void Cancel_actionPerformed(java.awt.event.ActionEvent event) {
System.exit(0);
}
}
Get Email Message Example
// Fetching Mail
import java.io.*;
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;
public class GetMessageExample {
public static void main(String args[]) throws Exception {
if (args.length != 3) {
System.err.println("Usage: java MailExample host username password");
System.exit(-1);
}
String host = args[0];
String username = args[1];
String password = args[2];
// Create empty properties
Properties props = new Properties();
// Get session
Session session = Session.getDefaultInstance(props, null);
// Get the store
Store store = session.getStore("pop3");
store.connect(host, username, password);
// Get folder
Folder folder = store.getFolder("INBOX");
folder.open(Folder.READ_ONLY);
BufferedReader reader = new BufferedReader(new InputStreamReader(
System.in));
// Get directory
Message message[] = folder.getMessages();
for (int i = 0, n = message.length; i < n; i++) {
System.out.println(i + ": " + message[i].getFrom()[0] + "\t"
+ message[i].getSubject());
System.out.println("Read message? [YES to read/QUIT to end]");
String line = reader.readLine();
if ("YES".equalsIgnoreCase(line)) {
System.out.println(message[i].getContent());
} else if ("QUIT".equalsIgnoreCase(line)) {
break;
}
}
// Close connection
folder.close(false);
store.close();
}
}
Mailer: Sends an email message
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java
* language and environment is gratefully acknowledged.
*
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/
import java.util.*;
import javax.mail.*;
import javax.mail.internet.*;
/** Mailer. No relation to Norman. Sends an email message.
* My old Sender class, recast as a Bean for use in JSP"s & elsewhere.
* Example usage:
* <pre>
* Mailer mb = new Mailer();
* mb.setFrom("orders@YourDomain.ru");
* mb.addTo("orders@YourDomain.ru");
* mb.setSubject("LHBOOKS ORDER!!");
* mb.setBody(order.toString());
* mb.setServer(application.getInitParameter("mail.server.smtp"));
* try {
* mb.doSend();
* } catch (MessagingException ex) {
* ...
* }
* </pre>
* @author Ian F. Darwin
* @version $Id: Mailer.java,v 1.16 2004/01/31 01:26:05 ian Exp $
*/
public class Mailer {
/** The javamail session object. */
protected Session session;
/** The sender"s email address */
protected String from;
/** The subject of the message. */
protected String subject;
/** The recipient ("To:"), as Strings. */
protected ArrayList toList = new ArrayList();
/** The CC list, as Strings. */
protected ArrayList ccList = new ArrayList();
/** The BCC list, as Strings. */
protected ArrayList bccList = new ArrayList();
/** The text of the message. */
protected String body;
/** The SMTP relay host */
protected String mailHost;
/** The verbosity setting */
protected boolean verbose;
/** Get from */
public String getFrom() {
return from;
}
/** Set from */
public void setFrom(String fm) {
from = fm;
}
/** Get subject */
public String getSubject() {
return subject;
}
/** Set subject */
public void setSubject(String subj) {
subject = subj;
}
// SETTERS/GETTERS FOR TO: LIST
/** Get tolist, as an array of Strings */
public ArrayList getToList() {
return toList;
}
/** Set to list to an ArrayList of Strings */
public void setToList(ArrayList to) {
toList = to;
}
/** Set to as a string like "tom, mary, robin@host". Loses any
* previously-set values. */
public void setToList(String s) {
toList = tokenize(s);
}
/** Add one "to" recipient */
public void addTo(String to) {
toList.add(to);
}
// SETTERS/GETTERS FOR CC: LIST
/** Get cclist, as an array of Strings */
public ArrayList getCcList() {
return ccList;
}
/** Set cc list to an ArrayList of Strings */
public void setCcList(ArrayList cc) {
ccList = cc;
}
/** Set cc as a string like "tom, mary, robin@host". Loses any
* previously-set values. */
public void setCcList(String s) {
ccList = tokenize(s);
}
/** Add one "cc" recipient */
public void addCc(String cc) {
ccList.add(cc);
}
// SETTERS/GETTERS FOR BCC: LIST
/** Get bcclist, as an array of Strings */
public ArrayList getBccList() {
return bccList;
}
/** Set bcc list to an ArrayList of Strings */
public void setBccList(ArrayList bcc) {
bccList = bcc;
}
/** Set bcc as a string like "tom, mary, robin@host". Loses any
* previously-set values. */
public void setBccList(String s) {
bccList = tokenize(s);
}
/** Add one "bcc" recipient */
public void addBcc(String bcc) {
bccList.add(bcc);
}
// SETTER/GETTER FOR MESSAGE BODY
/** Get message */
public String getBody() {
return body;
}
/** Set message */
public void setBody(String text) {
body = text;
}
// SETTER/GETTER FOR VERBOSITY
/** Get verbose */
public boolean isVerbose() {
return verbose;
}
/** Set verbose */
public void setVerbose(boolean v) {
verbose = v;
}
/** Check if all required fields have been set before sending.
* Normally called e.g., by a JSP before calling doSend.
* Is also called by doSend for verification.
*/
public boolean isComplete() {
if (from == null || from.length()==0) {
System.err.println("doSend: no FROM");
return false;
}
if (subject == null || subject.length()==0) {
System.err.println("doSend: no SUBJECT");
return false;
}
if (toList.size()==0) {
System.err.println("doSend: no recipients");
return false;
}
if (body == null || body.length()==0) {
System.err.println("doSend: no body");
return false;
}
if (mailHost == null || mailHost.length()==0) {
System.err.println("doSend: no server host");
return false;
}
return true;
}
public void setServer(String s) {
mailHost = s;
}
/** Send the message.
*/
public synchronized void doSend() throws MessagingException {
if (!isComplete())
throw new IllegalArgumentException(
"doSend called before message was complete");
/** Properties object used to pass props into the MAIL API */
Properties props = new Properties();
props.put("mail.smtp.host", mailHost);
// Create the Session object
if (session == null) {
session = Session.getDefaultInstance(props, null);
if (verbose)
session.setDebug(true); // Verbose!
}
// create a message
final Message mesg = new MimeMessage(session);
InternetAddress[] addresses;
// TO Address list
addresses = new InternetAddress[toList.size()];
for (int i=0; i<addresses.length; i++)
addresses[i] = new InternetAddress((String)toList.get(i));
mesg.setRecipients(Message.RecipientType.TO, addresses);
// From Address
mesg.setFrom(new InternetAddress(from));
// CC Address list
addresses = new InternetAddress[ccList.size()];
for (int i=0; i<addresses.length; i++)
addresses[i] = new InternetAddress((String)ccList.get(i));
mesg.setRecipients(Message.RecipientType.CC, addresses);
// BCC Address list
addresses = new InternetAddress[bccList.size()];
for (int i=0; i<addresses.length; i++)
addresses[i] = new InternetAddress((String)bccList.get(i));
mesg.setRecipients(Message.RecipientType.BCC, addresses);
// The Subject
mesg.setSubject(subject);
// Now the message body.
mesg.setText(body);
// Finally, send the message! (use static Transport method)
// Do this in a Thread as it sometimes is too slow for JServ
// new Thread() {
// public void run() {
// try {
Transport.send(mesg);
// } catch (MessagingException e) {
// throw new IllegalArgumentException(
// "Transport.send() threw: " + e.toString());
// }
// }
// }.start();
}
/** Convenience method that does it all with one call.
* @param mailhost - SMTP server host
* @param recipient - domain address of email (user@host.domain)
* @param sender - your email address
* @param subject - the subject line
* @param message - the entire message body as a String with embedded \n"s
*/
public static void send(String mailhost,
String recipient, String sender, String subject, String message)
throws MessagingException {
Mailer m = new Mailer();
m.setServer(mailhost);
m.addTo(recipient);
m.setFrom(sender);
m.setSubject(subject);
m.setBody(message);
m.doSend();
}
/** Convert a list of addresses to an ArrayList. This will work
* for simple names like "tom, mary@foo.ru, 123.45@c$.ru"
* but will fail on certain complex (but RFC-valid) names like
* "(Darwin, Ian) <http://www.darwinsys.ru/>".
* Or even "Ian Darwin <http://www.darwinsys.ru/>".
*/
protected ArrayList tokenize(String s) {
ArrayList al = new ArrayList();
StringTokenizer tf = new StringTokenizer(s, ",");
// For each word found in the line
while (tf.hasMoreTokens()) {
// trim blanks, and add to list.
al.add(tf.nextToken().trim());
}
return al;
}
}
Pure Java Email client
Read a file return mail headers one at a time
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java
* language and environment is gratefully acknowledged.
*
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/
import java.io.BufferedReader;
import java.io.FileNotFoundException;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.mail.Header;
/**
* Read a file return mail headers one at a time.
*/
public class ReadHeaders {
protected BufferedReader is;
/** Construct */
public ReadHeaders(BufferedReader f) {
is = f;
}
/** Main program showing how to use it */
public static void main(String[] av) {
switch (av.length) {
case 0:
ReadHeaders r = new ReadHeaders(new BufferedReader(
new InputStreamReader(System.in)));
printit(r);
break;
default:
for (int i = 0; i < av.length; i++)
try {
ReadHeaders rr = new ReadHeaders(new BufferedReader(
new FileReader(av[i])));
printit(rr);
} catch (FileNotFoundException e) {
System.err.println(e);
}
break;
}
}
/** Simple demo showing how to use it */
public static void printit(ReadHeaders r) {
while (r.more()) {
Header h = r.next();
System.out.println(h.getValue());
}
}
String inputLine;
/** check to see if more headers available */
public boolean more() {
if (is == null)
return false;
try {
inputLine = is.readLine();
if (inputLine == null || inputLine.length() == 0) {
is.close();
is = null;
}
} catch (IOException e) {
System.out.println("IOException: " + e);
is = null;
return false;
}
return true;
}
public Header next() {
int pos = inputLine.indexOf(":");
if (pos < 0)
return new Header("??", inputLine);
return new Header(inputLine.substring(0, pos), inputLine
.substring(pos + 1));
}
}
Sender -- send an email message
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java
* language and environment is gratefully acknowledged.
*
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/
import java.util.Properties;
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;
/**
* sender -- send an email message.
*
* @author Ian F. Darwin
* @version $Id: Sender.java,v 1.2 2000/11/25 17:55:00 ian Exp $
*/
public class Sender {
/** The message recipient. */
protected String message_recip = "spam-magnet@darwinsys.ru";
/* What"s it all about, Alfie? */
protected String message_subject = "Re: your mail";
/** The message CC recipient. */
protected String message_cc = "nobody@erewhon.ru";
/** The message body */
protected String message_body = "I am unable to attend to your message, as I am busy sunning"
+ "myself on the beach in Maui, where it is warm and peaceful."
+ "Perhaps when I return I"ll get around to reading your mail."
+ "Or perhaps not.";
/** The JavaMail session object */
protected Session session;
/** The JavaMail message object */
protected Message mesg;
/** Do the work: send the mail to the SMTP server. */
public void doSend() {
// We need to pass info to the mail server as a Properties, since
// JavaMail (wisely) allows room for LOTS of properties...
Properties props = new Properties();
// Your LAN must define the local SMTP server as "mailhost"
// for this simple-minded version to be able to send mail...
props.put("mail.smtp.host", "mailhost");
// Create the Session object
session = Session.getDefaultInstance(props, null);
session.setDebug(true); // Verbose!
try {
// create a message
mesg = new MimeMessage(session);
// From Address - this should come from a Properties...
mesg.setFrom(new InternetAddress("nobody@host.domain"));
// TO Address
InternetAddress toAddress = new InternetAddress(message_recip);
mesg.addRecipient(Message.RecipientType.TO, toAddress);
// CC Address
InternetAddress ccAddress = new InternetAddress(message_cc);
mesg.addRecipient(Message.RecipientType.CC, ccAddress);
// The Subject
mesg.setSubject(message_subject);
// Now the message body.
mesg.setText(message_body);
// XXX I18N: use setText(msgText.getText(), charset)
// Finally, send the message!
Transport.send(mesg);
} catch (MessagingException ex) {
while ((ex = (MessagingException) ex.getNextException()) != null) {
ex.printStackTrace();
}
}
}
/** Simple test case driver */
public static void main(String[] av) {
Sender sm = new Sender();
sm.doSend();
}
}
Sender -- send an email message with attachment
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java
* language and environment is gratefully acknowledged.
*
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/
import java.util.Properties;
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;
/**
* sender -- send an email message. If you give more than one file, each file
* will be sent to the same recipient with the same subject, so you generally
* don"t want to.
*
* @author Ian F. Darwin
* @version $Id: Sender2.java,v 1.8 2004/03/20 20:52:35 ian Exp $
*/
public class Sender2 {
/** The message recipient. */
protected String message_recip;
/* What"s it all about, Alfie? */
protected String message_subject;
/** The message CC recipient. */
protected String message_cc;
/** The message body */
protected String message_body;
/** The JavaMail session object */
protected Session session;
/** The JavaMail message object */
protected Message mesg;
/** Properties object used to pass props into the MAIL API */
Properties props = new Properties();
/** Construct a Sender2 object */
public Sender2() throws MessagingException {
// Your LAN must define the local SMTP as "mailhost"
// for this simple-minded version to be able to send mail...
props.put("mail.smtp.host", "mailhost");
finish();
}
/**
* Construct a Sender2 object.
*
* @param hostName -
* the name of the host to send to/via.
*/
public Sender2(String hostName) throws MessagingException {
props.put("mail.smtp.host", hostName);
finish();
}
private void finish() {
// Create the Session object
session = Session.getDefaultInstance(props, null);
// session.setDebug(true); // Verbose!
// create a message
mesg = new MimeMessage(session);
}
public void sendFile(String fileName) throws MessagingException {
// Now the message body.
setBody(message_body);
sendFile();
}
/**
* Send the file with no filename, assuming you"ve already called the
* setBody() method.
*/
public void sendFile() {
try {
// Finally, send the message! (use static Transport method)
Transport.send(mesg);
} catch (MessagingException ex) {
while ((ex = (MessagingException) ex.getNextException()) != null) {
ex.printStackTrace();
}
}
}
/**
* Stub for providing help on usage You can write a longer help than this,
* certainly.
*/
protected static void usage(int returnValue) {
System.err
.println("Usage: Sender2 [-t to][-c cc][-f from][-s subj] file ...");
System.exit(returnValue);
}
public void addRecipient(String message_recip) throws MessagingException {
// TO Address
InternetAddress toAddress = new InternetAddress(message_recip);
mesg.addRecipient(Message.RecipientType.TO, toAddress);
}
public void addCCRecipient(String message_cc) throws MessagingException {
// CC Address
InternetAddress ccAddress = new InternetAddress(message_cc);
mesg.addRecipient(Message.RecipientType.CC, ccAddress);
}
public void setFrom(String sender) throws MessagingException {
// From Address - this should come from a Properties...
mesg.setFrom(new InternetAddress(sender));
}
public void setSubject(String message_subject) throws MessagingException {
// The Subject
mesg.setSubject(message_subject);
}
/** Set the message body. */
public void setBody(String message_body) throws MessagingException {
mesg.setText(message_body);
// XXX I18N: use setText(msgText.getText(), charset)
}
/** Driver to parse options and control Sender */
public static void main(String[] args) {
try {
Sender2 sm = new Sender2();
// XXX sm.setMailHost();
sm.props.put("mail.smtp.host", "");
sm.addRecipient("www@www.net");
sm.addCCRecipient("");
sm.setFrom("");
sm.setSubject("");
sm.sendFile("");
} catch (MessagingException e) {
System.err.println(e);
}
}
}
Sending Mail
import java.util.Properties;
import javax.mail.*;
import javax.mail.internet.*;
public class MailExample {
public static void main(String args[]) throws Exception {
if (args.length != 3) {
System.err.println("Usage: java MailExample host from to");
System.exit(-1);
}
String host = args[0];
String from = args[1];
String to = args[2];
// Get system properties
Properties props = System.getProperties();
// Setup mail server
props.put("mail.smtp.host", host);
// Get session
Session session = Session.getDefaultInstance(props, null);
// Define message
MimeMessage message = new MimeMessage(session);
message.setFrom(new InternetAddress(from));
message.addRecipient(Message.RecipientType.TO, new InternetAddress(to));
message.setSubject("The Subject");
message.setText("The Message");
// Send message
Transport.send(message);
}
}
Sending Mail Using Sockets
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
public class SMTPDemo {
public static void main(String args[]) throws IOException,
UnknownHostException {
String msgFile = "file.txt";
String from = "jexp@jexp.ru";
String to = "yourEmail@yourServer.ru";
String mailHost = "yourHost";
SMTP mail = new SMTP(mailHost);
if (mail != null) {
if (mail.send(new FileReader(msgFile), from, to)) {
System.out.println("Mail sent.");
} else {
System.out.println("Connect to SMTP server failed!");
}
}
System.out.println("Done.");
}
static class SMTP {
private final static int SMTP_PORT = 25;
InetAddress mailHost;
InetAddress localhost;
BufferedReader in;
PrintWriter out;
public SMTP(String host) throws UnknownHostException {
mailHost = InetAddress.getByName(host);
localhost = InetAddress.getLocalHost();
System.out.println("mailhost = " + mailHost);
System.out.println("localhost= " + localhost);
System.out.println("SMTP constructor done\n");
}
public boolean send(FileReader msgFileReader, String from, String to)
throws IOException {
Socket smtpPipe;
InputStream inn;
OutputStream outt;
BufferedReader msg;
msg = new BufferedReader(msgFileReader);
smtpPipe = new Socket(mailHost, SMTP_PORT);
if (smtpPipe == null) {
return false;
}
inn = smtpPipe.getInputStream();
outt = smtpPipe.getOutputStream();
in = new BufferedReader(new InputStreamReader(inn));
out = new PrintWriter(new OutputStreamWriter(outt), true);
if (inn == null || outt == null) {
System.out.println("Failed to open streams to socket.");
return false;
}
String initialID = in.readLine();
System.out.println(initialID);
System.out.println("HELO " + localhost.getHostName());
out.println("HELO " + localhost.getHostName());
String welcome = in.readLine();
System.out.println(welcome);
System.out.println("MAIL From:<" + from + ">");
out.println("MAIL From:<" + from + ">");
String senderOK = in.readLine();
System.out.println(senderOK);
System.out.println("RCPT TO:<" + to + ">");
out.println("RCPT TO:<" + to + ">");
String recipientOK = in.readLine();
System.out.println(recipientOK);
System.out.println("DATA");
out.println("DATA");
String line;
while ((line = msg.readLine()) != null) {
out.println(line);
}
System.out.println(".");
out.println(".");
String acceptedOK = in.readLine();
System.out.println(acceptedOK);
System.out.println("QUIT");
out.println("QUIT");
return true;
}
}
}
SendMime -- send a multi-part MIME email message
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java
* language and environment is gratefully acknowledged.
*
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/
import java.io.IOException;
import java.util.Properties;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
/**
* SendMime -- send a multi-part MIME email message.
*
* @author Ian F. Darwin
* @version $Id: SendMime.java,v 1.8 2003/05/31 21:18:35 ian Exp $
*/
public class SendMime {
/** The message recipient. */
protected String message_recip = "spam-magnet@darwinsys.ru";
/* What"s it all about, Alfie? */
protected String message_subject = "Re: your mail";
/** The message CC recipient. */
protected String message_cc = "nobody@erewhon.ru";
/** The text/plain message body */
protected String message_body = "I am unable to attend to your message, as I am busy sunning "
+ "myself on the beach in Maui, where it is warm and peaceful. "
+ "Perhaps when I return I"ll get around to reading your mail. "
+ "Or perhaps not.";
/* The text/html data. */
protected String html_data = "<HTML><HEAD><TITLE>My Goodness</TITLE></HEAD>"
+ "<BODY><P>You <EM>do</EM> look a little "
+ "<font color=green>GREEN</FONT>"
+ "around the edges..."
+ "</BODY></HTML>";
/** The JavaMail session object */
protected Session session;
/** The JavaMail message object */
protected Message mesg;
/** Do the work: send the mail to the SMTP server. */
public void doSend() throws IOException, MessagingException {
// Create the Session object
session = Session.getDefaultInstance(null, null);
session.setDebug(true); // Verbose!
try {
// create a message
mesg = new MimeMessage(session);
// From Address - this should come from a Properties...
mesg.setFrom(new InternetAddress("nobody@host.domain"));
// TO Address
InternetAddress toAddress = new InternetAddress(message_recip);
mesg.addRecipient(Message.RecipientType.TO, toAddress);
// CC Address
InternetAddress ccAddress = new InternetAddress(message_cc);
mesg.addRecipient(Message.RecipientType.CC, ccAddress);
// The Subject
mesg.setSubject(message_subject);
// Now the message body.
Multipart mp = new MimeMultipart();
BodyPart textPart = new MimeBodyPart();
textPart.setText(message_body); // sets type to "text/plain"
BodyPart pixPart = new MimeBodyPart();
pixPart.setContent(html_data, "text/html");
// Collect the Parts into the MultiPart
mp.addBodyPart(textPart);
mp.addBodyPart(pixPart);
// Put the MultiPart into the Message
mesg.setContent(mp);
// Finally, send the message!
Transport.send(mesg);
} catch (MessagingException ex) {
System.err.println(ex);
ex.printStackTrace(System.err);
}
}
/** Simple test case driver */
public static void main(String[] av) throws Exception {
SendMime sm = new SendMime();
sm.doSend();
}
}
TestOpenMailRelay -- send self-returning SPAM to check for relay sites
/*
* Copyright (c) Ian F. Darwin, http://www.darwinsys.ru/, 1996-2002.
* All rights reserved. Software written by Ian F. Darwin and others.
* $Id: LICENSE,v 1.8 2004/02/09 03:33:38 ian Exp $
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS""
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
* Java, the Duke mascot, and all variants of Sun"s Java "steaming coffee
* cup" logo are trademarks of Sun Microsystems. Sun"s, and James Gosling"s,
* pioneering role in inventing and promulgating (and standardizing) the Java
* language and environment is gratefully acknowledged.
*
* The pioneering role of Dennis Ritchie and Bjarne Stroustrup, of AT&T, for
* inventing predecessor languages C and C++ is also gratefully acknowledged.
*/
import java.awt.BorderLayout;
import java.awt.Container;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PipedInputStream;
import java.io.PipedOutputStream;
import java.io.PrintStream;
import java.util.Properties;
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.swing.JButton;
import javax.swing.JFrame;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTextArea;
import javax.swing.JTextField;
import javax.swing.SwingUtilities;
/** TestOpenMailRelay -- send self-returning SPAM to check for relay sites.
* @author Ian F. Darwin
* @version $Id: TestOpenMailRelay.java,v 1.13 2004/03/20 20:52:35 ian Exp $
*/
class TestOpenMailRelay {
/** Where to refer people that find the test messages on their system. */
public final static String RSS_SITE = "http://mail-abuse.org/rss/";
/** Where the test messages will be collected. */
public final static String MY_TARGET = "spam-magnet@darwinsys.ru";
/** Driver to parse options and control Sender */
public static void main(String[] args) throws IOException {
if (args.length == 0) {
new TestOpenMailRelayGUI().setVisible(true);
} else {
for (int i=0; i<args.length; i++) {
process(args[i]);
}
}
}
/** Try the given mail server, writing output to System.out */
public static void process(String suspect_relay) {
process(suspect_relay, System.out);
}
/** Try the given mail server, writing output to the given PrintStream */
public static void process(String suspect_relay, PrintStream pw) {
pw.println("processs: trying: " + suspect_relay);
try {
// Redirect all output from mail API to the given stream.
System.setOut(pw);
System.setErr(pw);
Sender2 sm = new Sender2(suspect_relay);
sm.addRecipient("nobody@erewhon.moc");
sm.setFrom(MY_TARGET);
sm.setSubject("Testing for open mail relay, see " + RSS_SITE);
sm.setBody("This mail is an attempt to confirm that site " +
suspect_relay + "\n" + "is in fact an open mail relay site.\n"
+ "For more information on the problem of open mail relays,\n"
+ "please visit site "
+ RSS_SITE
+ "\n"
+ "Please join the fight against spam by closing all open mail relays!\n"
+ "If this open relay has been closed, please accept our thanks.\n");
sm.sendFile("");
} catch (MessagingException e) {
pw.println(e);
} catch (Exception e) {
pw.println(e);
}
}
}
/** GUI for TestOpenMailRelay, lets you run it multiple times in one JVM
* to avoid startup delay.
*
* Starts each in its own Thread for faster return to ready state.
*
* Uses PipedI/OStreams to capture system.out/err into a window.
*/
public class TestOpenMailRelayGUI extends JFrame {
public static void main(String unused[]) throws IOException {
new TestOpenMailRelayGUI().setVisible(true);
}
/** The one-line textfield for the user to type Host name/IP */
protected JTextField hostTextField;
/** The push button to start a test; a field so can disable/enable it. */
protected JButton goButton;
/** Multi-line text area for results. */
protected JTextArea results;
/** The piped stream for the main class to write into "results" */
protected PrintStream ps;
/** The piped stream to read from "ps" into "results" */
protected BufferedReader iis;
/** This inner class is the action handler both for pressing
* the "Try" button and also for pressing <ENTER> in the text
* field. It gets the IP name/address from the text field
* and passes it to process() in the main class. Run in the
* GUI Dispatch thread to avoid messing the GUI. -- tmurtagh.
*/
ActionListener runner = new ActionListener() {
public void actionPerformed(ActionEvent evt) {
goButton.setEnabled(false);
SwingUtilities.invokeLater(new Thread() {
public void run() {
String host = hostTextField.getText().trim();
ps.println("Trying " + host);
TestOpenMailRelay.process(host, ps);
goButton.setEnabled(true);
}
});
}
};
/** Construct a GUI and some I/O plumbing to get the output
* of "TestOpenMailRelay" into the "results" textfield.
*/
public TestOpenMailRelayGUI() throws IOException {
super("Tests for Open Mail Relays");
PipedInputStream is;
PipedOutputStream os;
JPanel p;
Container cp = getContentPane();
cp.add(BorderLayout.NORTH, p = new JPanel());
// The entry label and text field.
p.add(new JLabel("Host:"));
p.add(hostTextField = new JTextField(10));
hostTextField.addActionListener(runner);
p.add(goButton = new JButton("Try"));
goButton.addActionListener(runner);
JButton cb;
p.add(cb = new JButton("Clear Log"));
cb.addActionListener(new ActionListener() {
public void actionPerformed(ActionEvent evt) {
results.setText("");
}
});
JButton sb;
p.add(sb = new JButton("Save Log"));
sb.setEnabled(false);
results = new JTextArea(20, 60);
// Add the text area to the main part of the window (CENTER).
// Wrap it in a JScrollPane to make it scroll automatically.
cp.add(BorderLayout.CENTER, new JScrollPane(results));
setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
pack(); // end of GUI portion
// Create a pair of Piped Streams.
is = new PipedInputStream();
os = new PipedOutputStream(is);
iis = new BufferedReader(new InputStreamReader(is, "ISO8859_1"));
ps = new PrintStream(os);
// Construct and start a Thread to copy data from "is" to "os".
new Thread() {
public void run() {
try {
String line;
while ((line = iis.readLine()) != null) {
results.append(line);
results.append("\n");
}
} catch (IOException ex) {
JOptionPane.showMessageDialog(null,
"*** Input or Output error ***\n" + ex, "Error",
JOptionPane.ERROR_MESSAGE);
}
}
}.start();
}
}
class Sender {
/** The message recipient. */
protected String message_recip = "spam-magnet@darwinsys.ru";
/* What"s it all about, Alfie? */
protected String message_subject = "Re: your mail";
/** The message CC recipient. */
protected String message_cc = "nobody@erewhon.ru";
/** The message body */
protected String message_body = "I am unable to attend to your message, as I am busy sunning"
+ "myself on the beach in Maui, where it is warm and peaceful."
+ "Perhaps when I return I"ll get around to reading your mail."
+ "Or perhaps not.";
/** The JavaMail session object */
protected Session session;
/** The JavaMail message object */
protected Message mesg;
/** Do the work: send the mail to the SMTP server. */
public void doSend() {
// We need to pass info to the mail server as a Properties, since
// JavaMail (wisely) allows room for LOTS of properties...
Properties props = new Properties();
// Your LAN must define the local SMTP server as "mailhost"
// for this simple-minded version to be able to send mail...
props.put("mail.smtp.host", "mailhost");
// Create the Session object
session = Session.getDefaultInstance(props, null);
session.setDebug(true); // Verbose!
try {
// create a message
mesg = new MimeMessage(session);
// From Address - this should come from a Properties...
mesg.setFrom(new InternetAddress("nobody@host.domain"));
// TO Address
InternetAddress toAddress = new InternetAddress(message_recip);
mesg.addRecipient(Message.RecipientType.TO, toAddress);
// CC Address
InternetAddress ccAddress = new InternetAddress(message_cc);
mesg.addRecipient(Message.RecipientType.CC, ccAddress);
// The Subject
mesg.setSubject(message_subject);
// Now the message body.
mesg.setText(message_body);
// XXX I18N: use setText(msgText.getText(), charset)
// Finally, send the message!
Transport.send(mesg);
} catch (MessagingException ex) {
while ((ex = (MessagingException) ex.getNextException()) != null) {
ex.printStackTrace();
}
}
}
/** Simple test case driver */
public static void main(String[] av) {
Sender sm = new Sender();
sm.doSend();
}
}
class Sender2 {
/** The message recipient. */
protected String message_recip;
/* What"s it all about, Alfie? */
protected String message_subject;
/** The message CC recipient. */
protected String message_cc;
/** The message body */
protected String message_body;
/** The JavaMail session object */
protected Session session;
/** The JavaMail message object */
protected Message mesg;
/** Properties object used to pass props into the MAIL API */
Properties props = new Properties();
/** Construct a Sender2 object */
public Sender2() throws MessagingException {
// Your LAN must define the local SMTP as "mailhost"
// for this simple-minded version to be able to send mail...
props.put("mail.smtp.host", "mailhost");
finish();
}
/** Construct a Sender2 object.
* @param hostName - the name of the host to send to/via.
*/
public Sender2(String hostName) throws MessagingException {
props.put("mail.smtp.host", hostName);
finish();
}
private void finish() {
// Create the Session object
session = Session.getDefaultInstance(props, null);
// session.setDebug(true); // Verbose!
// create a message
mesg = new MimeMessage(session);
}
public void sendFile(String fileName) throws MessagingException {
// Now the message body.
setBody(message_body);
sendFile();
}
/** Send the file with no filename, assuming you"ve already called
* the setBody() method.
*/
public void sendFile() {
try {
// Finally, send the message! (use static Transport method)
Transport.send(mesg);
} catch (MessagingException ex) {
while ((ex = (MessagingException) ex.getNextException()) != null) {
ex.printStackTrace();
}
}
}
/** Stub for providing help on usage You can write a longer help than this,
* certainly.
*/
protected static void usage(int returnValue) {
System.err
.println("Usage: Sender2 [-t to][-c cc][-f from][-s subj] file ...");
System.exit(returnValue);
}
public void addRecipient(String message_recip) throws MessagingException {
// TO Address
InternetAddress toAddress = new InternetAddress(message_recip);
mesg.addRecipient(Message.RecipientType.TO, toAddress);
}
public void addCCRecipient(String message_cc) throws MessagingException {
// CC Address
InternetAddress ccAddress = new InternetAddress(message_cc);
mesg.addRecipient(Message.RecipientType.CC, ccAddress);
}
public void setFrom(String sender) throws MessagingException {
// From Address - this should come from a Properties...
mesg.setFrom(new InternetAddress(sender));
}
public void setSubject(String message_subject) throws MessagingException {
// The Subject
mesg.setSubject(message_subject);
}
/** Set the message body. */
public void setBody(String message_body) throws MessagingException {
mesg.setText(message_body);
// XXX I18N: use setText(msgText.getText(), charset)
}
/** Driver to parse options and control Sender */
public static void main(String[] args) {
try {
Sender2 sm = new Sender2();
// XXX sm.setMailHost();
sm.props.put("mail.smtp.host", "");
sm.addRecipient("www@www.net");
sm.addCCRecipient("");
sm.setFrom("");
sm.setSubject("");
sm.sendFile("");
} catch (MessagingException e) {
System.err.println(e);
}
}
}