You are viewing a plain text version of this content. The canonical link for it is here.
Posted to scm@geronimo.apache.org by ri...@apache.org on 2006/12/07 23:05:26 UTC
svn commit: r483693 - in /geronimo/javamail/trunk:
geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/
geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/
Author: rickmcguire
Date: Thu Dec 7 14:05:25 2006
New Revision: 483693
URL: http://svn.apache.org/viewvc?view=rev&rev=483693
Log:
GERONIMO-2439 add secure transport support to POP3 (i.e., SSL)
Modified:
geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3CommandFactory.java
geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Connection.java
geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java
geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Response.java
geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3ResponseBuilder.java
geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java
geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3CommandFactory.java
geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Connection.java
geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java
geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Response.java
geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3ResponseBuilder.java
geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java
Modified: geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3CommandFactory.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3CommandFactory.java?view=diff&rev=483693&r1=483692&r2=483693
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3CommandFactory.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3CommandFactory.java Thu Dec 7 14:05:25 2006
@@ -184,5 +184,52 @@
}
};
}
+
+ public static POP3Command getCOMMAND_CAPA() {
+ return new POP3Command() {
+ public String getCommand() {
+ return "CAPA" + CRLF;
+ }
+
+ public boolean isMultiLineResponse() {
+ return true;
+ }
+ };
+ }
+ public static POP3Command getCOMMAND_AUTH(final String protocol) {
+ return new POP3Command() {
+ public String getCommand() {
+ return "AUTH " + protocol + CRLF;
+ }
+
+ public boolean isMultiLineResponse() {
+ return false;
+ }
+ };
+ }
+
+ public static POP3Command getCOMMAND_AUTH(final String protocol, final String initialResponse) {
+ return new POP3Command() {
+ public String getCommand() {
+ return "AUTH " + protocol + " " + initialResponse + CRLF;
+ }
+
+ public boolean isMultiLineResponse() {
+ return false;
+ }
+ };
+ }
+
+ public static POP3Command getCOMMAND_ChallengeReply(final String command) {
+ return new POP3Command() {
+ public String getCommand() {
+ return command + CRLF;
+ }
+
+ public boolean isMultiLineResponse() {
+ return false;
+ }
+ };
+ }
}
Modified: geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Connection.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Connection.java?view=diff&rev=483693&r1=483692&r2=483693
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Connection.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Connection.java Thu Dec 7 14:05:25 2006
@@ -24,7 +24,9 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
-import java.net.InetSocketAddress;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
import java.net.Socket;
import javax.mail.MessagingException;
@@ -38,9 +40,24 @@
* @version $Rev$ $Date$
*/
+
public class POP3Connection {
- private Socket soc;
+ protected static final String MAIL_SSLFACTORY_CLASS = "mail.SSLSocketFactory.class";
+
+ protected static final String MAIL_POP3_FACTORY_CLASS = "socketFactory.class";
+
+ protected static final String MAIL_POP3_FACTORY_FALLBACK = "socketFactory.fallback";
+
+ protected static final String MAIL_POP3_FACTORY_PORT = "socketFactory.port";
+
+ protected static final String MAIL_POP3_LOCALADDRESS = "localAddress";
+
+ protected static final String MAIL_POP3_LOCALPORT = "localPort";
+
+ protected static final String MAIL_POP3_TIMEOUT = "timeout";
+
+ private Socket socket;
private Session session;
@@ -51,18 +68,28 @@
private PrintWriter writer;
private BufferedReader reader;
+
+ private String protocol;
+
+ private boolean sslConnection;
- POP3Connection(Session session, String host, int port) {
+ POP3Connection(Session session, String host, int port, boolean sslConnection, String protocol) {
this.session = session;
this.host = host;
this.port = port;
+ this.sslConnection = sslConnection;
+ this.protocol = protocol;
}
public void open() throws Exception {
try {
- soc = new Socket();
- soc.connect(new InetSocketAddress(host, port));
+
+ if (!sslConnection) {
+ getConnectedSocket();
+ } else {
+ getConnectedSSLSocket();
+ }
if (session.getDebug()) {
session.getDebugOut().println("Connection successful " + this.toString());
@@ -86,7 +113,7 @@
void close() throws Exception {
try {
- soc.close();
+ socket.close();
if (session.getDebug()) {
session.getDebugOut().println("Connection successfuly closed " + this.toString());
}
@@ -99,17 +126,17 @@
}
public synchronized POP3Response sendCommand(POP3Command cmd) throws MessagingException {
- if (soc.isConnected()) {
+ if (socket.isConnected()) {
// if the underlying output stream is down
// attempt to rebuild the writer
- if (soc.isOutputShutdown()) {
+ if (socket.isOutputShutdown()) {
buildOutputWriter();
}
// if the underlying inout stream is down
// attempt to rebuild the reader
- if (soc.isInputShutdown()) {
+ if (socket.isInputShutdown()) {
buildInputReader();
}
@@ -135,7 +162,7 @@
private void buildInputReader() throws MessagingException {
try {
- reader = new BufferedReader(new InputStreamReader(soc.getInputStream()));
+ reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
throw new MessagingException("Error obtaining input stream " + this.toString(), e);
}
@@ -143,7 +170,7 @@
private void buildOutputWriter() throws MessagingException {
try {
- writer = new PrintWriter(new BufferedOutputStream(soc.getOutputStream()));
+ writer = new PrintWriter(new BufferedOutputStream(socket.getOutputStream()));
} catch (IOException e) {
throw new MessagingException("Error obtaining output stream " + this.toString(), e);
}
@@ -151,5 +178,387 @@
public String toString() {
return "POP3Connection host: " + host + " port: " + port;
+ }
+
+
+ /**
+ * Creates a connected socket
+ *
+ * @exception MessagingException
+ */
+ protected void getConnectedSocket() throws IOException {
+
+ // the socket factory can be specified via a session property. By
+ // default, we just directly
+ // instantiate a socket without using a factor.
+ String socketFactory = getProtocolProperty(MAIL_POP3_FACTORY_CLASS);
+
+ // there are several protocol properties that can be set to tune the
+ // created socket. We need to
+ // retrieve those bits before creating the socket.
+ int timeout = getIntProtocolProperty(MAIL_POP3_TIMEOUT, -1);
+ InetAddress localAddress = null;
+ // see if we have a local address override.
+ String localAddrProp = getProtocolProperty(MAIL_POP3_LOCALADDRESS);
+ if (localAddrProp != null) {
+ localAddress = InetAddress.getByName(localAddrProp);
+ }
+
+ // check for a local port...default is to allow socket to choose.
+ int localPort = getIntProtocolProperty(MAIL_POP3_LOCALPORT, 0);
+
+ socket = null;
+
+ // if there is no socket factory defined (normal), we just create a
+ // socket directly.
+ if (socketFactory == null) {
+ socket = new Socket(host, port, localAddress, localPort);
+ }
+
+ else {
+ try {
+ int socketFactoryPort = getIntProtocolProperty(MAIL_POP3_FACTORY_PORT, -1);
+
+ // we choose the port used by the socket based on overrides.
+ Integer portArg = new Integer(socketFactoryPort == -1 ? port : socketFactoryPort);
+
+ // use the current context loader to resolve this.
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ Class factoryClass = loader.loadClass(socketFactory);
+
+ // done indirectly, we need to invoke the method using
+ // reflection.
+ // This retrieves a factory instance.
+ Method getDefault = factoryClass.getMethod("getDefault", new Class[0]);
+ Object defFactory = getDefault.invoke(new Object(), new Object[0]);
+
+ // now that we have the factory, there are two different
+ // createSocket() calls we use,
+ // depending on whether we have a localAddress override.
+
+ if (localAddress != null) {
+ // retrieve the createSocket(String, int, InetAddress, int)
+ // method.
+ Class[] createSocketSig = new Class[] { String.class, Integer.TYPE, InetAddress.class, Integer.TYPE };
+ Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
+
+ Object[] createSocketArgs = new Object[] { host, portArg, localAddress, new Integer(localPort) };
+ socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
+ } else {
+ // retrieve the createSocket(String, int) method.
+ Class[] createSocketSig = new Class[] { String.class, Integer.TYPE };
+ Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
+
+ Object[] createSocketArgs = new Object[] { host, portArg };
+ socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
+ }
+ } catch (Throwable e) {
+ // if a socket factory is specified, then we may need to fall
+ // back to a default. This behavior
+ // is controlled by (surprise) more session properties.
+ if (isProtocolPropertyTrue(MAIL_POP3_FACTORY_FALLBACK)) {
+ socket = new Socket(host, port, localAddress, localPort);
+ }
+ // we have an exception. We're going to throw an IOException,
+ // which may require unwrapping
+ // or rewrapping the exception.
+ else {
+ // we have an exception from the reflection, so unwrap the
+ // base exception
+ if (e instanceof InvocationTargetException) {
+ e = ((InvocationTargetException) e).getTargetException();
+ }
+
+
+ // throw this as an IOException, with the original exception
+ // attached.
+ IOException ioe = new IOException("Error connecting to " + host + ", " + port);
+ ioe.initCause(e);
+ throw ioe;
+ }
+ }
+ }
+
+ if (timeout >= 0) {
+ socket.setSoTimeout(timeout);
+ }
+ }
+
+ /**
+ * Creates a connected SSL socket for an initial SSL connection.
+ *
+ * @exception MessagingException
+ */
+ protected void getConnectedSSLSocket() throws IOException {
+
+ if (session.getDebug()) {
+ session.getDebugOut().println("Attempting SSL socket connection to server " + host + ":" + port);
+ }
+ // the socket factory can be specified via a protocol property, a
+ // session property, and if all else
+ // fails (which it usually does), we fall back to the standard factory
+ // class.
+ String socketFactory = getProtocolProperty(MAIL_POP3_FACTORY_CLASS, getSessionProperty(MAIL_SSLFACTORY_CLASS,
+ "javax.net.ssl.SSLSocketFactory"));
+
+ // there are several protocol properties that can be set to tune the
+ // created socket. We need to
+ // retrieve those bits before creating the socket.
+ int timeout = getIntProtocolProperty(MAIL_POP3_TIMEOUT, -1);
+ InetAddress localAddress = null;
+ // see if we have a local address override.
+ String localAddrProp = getProtocolProperty(MAIL_POP3_LOCALADDRESS);
+ if (localAddrProp != null) {
+ localAddress = InetAddress.getByName(localAddrProp);
+ }
+
+ // check for a local port...default is to allow socket to choose.
+ int localPort = getIntProtocolProperty(MAIL_POP3_LOCALPORT, 0);
+
+ socket = null;
+
+ // if there is no socket factory defined (normal), we just create a
+ // socket directly.
+ if (socketFactory == null) {
+ System.out.println("SocketFactory was null so creating the connection using a default");
+ socket = new Socket(host, port, localAddress, localPort);
+ }
+
+ else {
+ // we'll try this with potentially two different factories if we're
+ // allowed to fall back.
+ boolean fallback = isProtocolPropertyTrue(MAIL_POP3_FACTORY_FALLBACK);
+ while(true) {
+ try {
+
+
+ if (socket != null) {
+ if (socket.isConnected())
+ break;
+ }
+
+ if (session.getDebug()) {
+ session.getDebugOut().println("Creating SSL socket using factory " + socketFactory);
+ }
+
+ int socketFactoryPort = getIntProtocolProperty(MAIL_POP3_FACTORY_PORT, -1);
+
+ // we choose the port used by the socket based on overrides.
+ Integer portArg = new Integer(socketFactoryPort == -1 ? port : socketFactoryPort);
+
+ // use the current context loader to resolve this.
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ Class factoryClass = loader.loadClass(socketFactory);
+
+ // done indirectly, we need to invoke the method using
+ // reflection.
+ // This retrieves a factory instance.
+ Method getDefault = factoryClass.getMethod("getDefault", new Class[0]);
+ Object defFactory = getDefault.invoke(new Object(), new Object[0]);
+
+ // now that we have the factory, there are two different
+ // createSocket() calls we use,
+ // depending on whether we have a localAddress override.
+
+ if (localAddress != null) {
+ // retrieve the createSocket(String, int, InetAddress,
+ // int) method.
+ Class[] createSocketSig = new Class[] { String.class, Integer.TYPE, InetAddress.class,
+ Integer.TYPE };
+ Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
+
+ Object[] createSocketArgs = new Object[] { host, portArg, localAddress, new Integer(localPort) };
+ socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
+ } else {
+ // retrieve the createSocket(String, int) method.
+ Class[] createSocketSig = new Class[] { String.class, Integer.TYPE };
+ Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
+
+ Object[] createSocketArgs = new Object[] { host, portArg };
+ socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
+ }
+ } catch (Throwable e) {
+ // if we're allowed to fallback, then use the default
+ // factory and try this again. We only
+ // allow this to happen once.
+ if (session.getDebug()) {
+ session.getDebugOut().println("First attempt at creating SSL socket failed, falling back to default factory");
+ }
+ if (fallback) {
+ socketFactory = "javax.net.ssl.SSLSocketFactory";
+ fallback = false;
+ continue;
+ }
+ // we have an exception. We're going to throw an
+ // IOException, which may require unwrapping
+ // or rewrapping the exception.
+ else {
+ // we have an exception from the reflection, so unwrap
+ // the base exception
+ if (e instanceof InvocationTargetException) {
+ e = ((InvocationTargetException) e).getTargetException();
+ }
+
+ if (session.getDebug()) {
+ session.getDebugOut().println("Failure creating SSL socket: " + e);
+ }
+ // throw this as an IOException, with the original
+ // exception attached.
+ IOException ioe = new IOException("Error connecting to " + host + ", " + port);
+ ioe.initCause(e);
+ throw ioe;
+ }
+ }
+ }
+ }
+
+ if (timeout >= 0) {
+ socket.setSoTimeout(timeout);
+ }
+ }
+
+ /**
+ * Process a session property as a boolean value, returning either true or
+ * false.
+ *
+ * @return True if the property value is "true". Returns false for any other
+ * value (including null).
+ */
+ protected boolean isProtocolPropertyTrue(String name) {
+ // the name we're given is the least qualified part of the name. We
+ // construct the full property name
+ // using the protocol ("pop3").
+ String fullName = "mail." + protocol + "." + name;
+ return isSessionPropertyTrue(fullName);
+ }
+
+ /**
+ * Process a session property as a boolean value, returning either true or
+ * false.
+ *
+ * @return True if the property value is "true". Returns false for any other
+ * value (including null).
+ */
+ protected boolean isSessionPropertyTrue(String name) {
+ String property = session.getProperty(name);
+ if (property != null) {
+ return property.equals("true");
+ }
+ return false;
+ }
+
+ /**
+ * Get a property associated with this mail session as an integer value.
+ * Returns the default value if the property doesn't exist or it doesn't
+ * have a valid int value.
+ *
+ * @param name
+ * The name of the property.
+ * @param defaultValue
+ * The default value to return if the property doesn't exist.
+ *
+ * @return The property value converted to an int.
+ */
+ protected int getIntProtocolProperty(String name, int defaultValue) {
+ // the name we're given is the least qualified part of the name. We
+ // construct the full property name
+ // using the protocol (pop3).
+ String fullName = "mail." + protocol + "." + name;
+ return getIntSessionProperty(fullName, defaultValue);
+ }
+
+ /**
+ * Get a property associated with this mail session as an integer value.
+ * Returns the default value if the property doesn't exist or it doesn't
+ * have a valid int value.
+ *
+ * @param name
+ * The name of the property.
+ * @param defaultValue
+ * The default value to return if the property doesn't exist.
+ *
+ * @return The property value converted to an int.
+ */
+ protected int getIntSessionProperty(String name, int defaultValue) {
+ String result = getSessionProperty(name);
+ if (result != null) {
+ try {
+ // convert into an int value.
+ return Integer.parseInt(result);
+ } catch (NumberFormatException e) {
+ }
+ }
+ // return default value if it doesn't exist is isn't convertable.
+ return defaultValue;
+ }
+
+ /**
+ * Get a property associated with this mail session. Returns the provided
+ * default if it doesn't exist.
+ *
+ * @param name
+ * The name of the property.
+ * @param defaultValue
+ * The default value to return if the property doesn't exist.
+ *
+ * @return The property value (returns defaultValue if the property has not
+ * been set).
+ */
+ protected String getSessionProperty(String name, String defaultValue) {
+ String result = session.getProperty(name);
+ if (result == null) {
+ return defaultValue;
+ }
+ return result;
+ }
+
+ /**
+ * Get a property associated with this mail session. Returns the provided
+ * default if it doesn't exist.
+ *
+ * @param name
+ * The name of the property.
+ * @param defaultValue
+ * The default value to return if the property doesn't exist.
+ *
+ * @return The property value (returns defaultValue if the property has not
+ * been set).
+ */
+ protected String getProtocolProperty(String name, String defaultValue) {
+ // the name we're given is the least qualified part of the name. We
+ // construct the full property name
+ // using the protocol ("pop3").
+ String fullName = "mail." + protocol + "." + name;
+ return getSessionProperty(fullName, defaultValue);
+ }
+
+ /**
+ * Get a property associated with this mail protocol.
+ *
+ * @param name
+ * The name of the property.
+ *
+ * @return The property value (returns null if the property has not been
+ * set).
+ */
+ protected String getProtocolProperty(String name) {
+ // the name we're given is the least qualified part of the name. We
+ // construct the full property name
+ // using the protocol ("pop3").
+ String fullName = "mail." + protocol + "." + name;
+ return getSessionProperty(fullName);
+ }
+
+ /**
+ * Get a property associated with this mail session.
+ *
+ * @param name
+ * The name of the property.
+ *
+ * @return The property value (returns null if the property has not been
+ * set).
+ */
+ protected String getSessionProperty(String name) {
+ return session.getProperty(name);
}
}
Modified: geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java?view=diff&rev=483693&r1=483692&r2=483693
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java Thu Dec 7 14:05:25 2006
@@ -39,4 +39,6 @@
public final static int OK = 0;
public final static int ERR = 1;
+
+ public final static int CHALLENGE = 2;
}
Modified: geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Response.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Response.java?view=diff&rev=483693&r1=483692&r2=483693
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Response.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Response.java Thu Dec 7 14:05:25 2006
@@ -33,9 +33,10 @@
public interface POP3Response {
/**
- * Returns the response OK or ERR
+ * Returns the response OK, CHALLENGE or ERR
* <ul>
* <li>OK --> +OK in pop3 spec
+ * <li>CHALLENGE --> + in pop3 spec
* <li>ERR --> -ERR in pop3 spec
* </ul>
*/
Modified: geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3ResponseBuilder.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3ResponseBuilder.java?view=diff&rev=483693&r1=483692&r2=483693
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3ResponseBuilder.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3ResponseBuilder.java Thu Dec 7 14:05:25 2006
@@ -76,6 +76,12 @@
} else if (line.startsWith("-ERR")) {
status = ERR;
line = removeStatusField(line);
+ }else if (line.startsWith("+")) {
+ status = CHALLENGE;
+ line = removeStatusField(line);
+ if (isMultiLineResponse) {
+ data = getMultiLineResponse(session, reader);
+ }
} else {
throw new MessagingException("Unexpected response: " + line);
}
Modified: geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java?view=diff&rev=483693&r1=483692&r2=483693
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.3.1_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java Thu Dec 7 14:05:25 2006
@@ -37,11 +37,45 @@
private POP3Connection pop3Con;
- public POP3Store(Session session, URLName urlName) {
- super(session, urlName);
+ protected static final int DEFAULT_MAIL_POP3_PORT = 110;
+ private boolean sslConnection;
+ private int defaultPort;
+
+ private String protocol;
+ public POP3Store(Session session, URLName name) {
+ this(session, name, "pop3", DEFAULT_MAIL_POP3_PORT, false);
}
/**
+ * Common constructor used by the POP3Store and POP3SSLStore classes
+ * to do common initialization of defaults.
+ *
+ * @param session
+ * The host session instance.
+ * @param name
+ * The URLName of the target.
+ * @param protocol
+ * The protocol type ("pop3"). This helps us in
+ * retrieving protocol-specific session properties.
+ * @param defaultPort
+ * The default port used by this protocol. For pop3, this will
+ * be 110. The default for pop3 with ssl is 995.
+ * @param sslConnection
+ * Indicates whether an SSL connection should be used to initial
+ * contact the server. This is different from the STARTTLS
+ * support, which switches the connection to SSL after the
+ * initial startup.
+ */
+ protected POP3Store(Session session, URLName name, String protocol, int defaultPort, boolean sslConnection) {
+ super(session, name);
+ this.protocol = protocol;
+
+ // these are defaults based on what the superclass specifies.
+ this.sslConnection = sslConnection;
+ this.defaultPort = defaultPort;
+
+ }
+ /**
* @see javax.mail.Store#getDefaultFolder()
*
* There is only INBOX supported in POP3 so the default folder is inbox
@@ -91,7 +125,7 @@
try {
portNum = Integer.parseInt(portstring);
} catch (NumberFormatException e) {
- portNum = 110;
+ portNum = defaultPort;
}
}
}
@@ -100,7 +134,7 @@
* Obtaining a connection to the server.
*
*/
- pop3Con = new POP3Connection(this.session, host, portNum);
+ pop3Con = new POP3Connection(this.session, host, portNum, sslConnection, protocol);
try {
pop3Con.open();
} catch (Exception e) {
Modified: geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3CommandFactory.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3CommandFactory.java?view=diff&rev=483693&r1=483692&r2=483693
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3CommandFactory.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3CommandFactory.java Thu Dec 7 14:05:25 2006
@@ -184,5 +184,52 @@
}
};
}
+
+ public static POP3Command getCOMMAND_CAPA() {
+ return new POP3Command() {
+ public String getCommand() {
+ return "CAPA" + CRLF;
+ }
+
+ public boolean isMultiLineResponse() {
+ return true;
+ }
+ };
+ }
+ public static POP3Command getCOMMAND_AUTH(final String protocol) {
+ return new POP3Command() {
+ public String getCommand() {
+ return "AUTH " + protocol + CRLF;
+ }
+
+ public boolean isMultiLineResponse() {
+ return false;
+ }
+ };
+ }
+
+ public static POP3Command getCOMMAND_AUTH(final String protocol, final String initialResponse) {
+ return new POP3Command() {
+ public String getCommand() {
+ return "AUTH " + protocol + " " + initialResponse + CRLF;
+ }
+
+ public boolean isMultiLineResponse() {
+ return false;
+ }
+ };
+ }
+
+ public static POP3Command getCOMMAND_ChallengeReply(final String command) {
+ return new POP3Command() {
+ public String getCommand() {
+ return command + CRLF;
+ }
+
+ public boolean isMultiLineResponse() {
+ return false;
+ }
+ };
+ }
}
Modified: geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Connection.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Connection.java?view=diff&rev=483693&r1=483692&r2=483693
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Connection.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Connection.java Thu Dec 7 14:05:25 2006
@@ -24,7 +24,9 @@
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
-import java.net.InetSocketAddress;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.InetAddress;
import java.net.Socket;
import javax.mail.MessagingException;
@@ -38,9 +40,24 @@
* @version $Rev$ $Date$
*/
+
public class POP3Connection {
- private Socket soc;
+ protected static final String MAIL_SSLFACTORY_CLASS = "mail.SSLSocketFactory.class";
+
+ protected static final String MAIL_POP3_FACTORY_CLASS = "socketFactory.class";
+
+ protected static final String MAIL_POP3_FACTORY_FALLBACK = "socketFactory.fallback";
+
+ protected static final String MAIL_POP3_FACTORY_PORT = "socketFactory.port";
+
+ protected static final String MAIL_POP3_LOCALADDRESS = "localAddress";
+
+ protected static final String MAIL_POP3_LOCALPORT = "localPort";
+
+ protected static final String MAIL_POP3_TIMEOUT = "timeout";
+
+ private Socket socket;
private Session session;
@@ -51,18 +68,28 @@
private PrintWriter writer;
private BufferedReader reader;
+
+ private String protocol;
+
+ private boolean sslConnection;
- POP3Connection(Session session, String host, int port) {
+ POP3Connection(Session session, String host, int port, boolean sslConnection, String protocol) {
this.session = session;
this.host = host;
this.port = port;
+ this.sslConnection = sslConnection;
+ this.protocol = protocol;
}
public void open() throws Exception {
try {
- soc = new Socket();
- soc.connect(new InetSocketAddress(host, port));
+
+ if (!sslConnection) {
+ getConnectedSocket();
+ } else {
+ getConnectedSSLSocket();
+ }
if (session.getDebug()) {
session.getDebugOut().println("Connection successful " + this.toString());
@@ -86,7 +113,7 @@
void close() throws Exception {
try {
- soc.close();
+ socket.close();
if (session.getDebug()) {
session.getDebugOut().println("Connection successfuly closed " + this.toString());
}
@@ -99,17 +126,17 @@
}
public synchronized POP3Response sendCommand(POP3Command cmd) throws MessagingException {
- if (soc.isConnected()) {
+ if (socket.isConnected()) {
// if the underlying output stream is down
// attempt to rebuild the writer
- if (soc.isOutputShutdown()) {
+ if (socket.isOutputShutdown()) {
buildOutputWriter();
}
// if the underlying inout stream is down
// attempt to rebuild the reader
- if (soc.isInputShutdown()) {
+ if (socket.isInputShutdown()) {
buildInputReader();
}
@@ -135,7 +162,7 @@
private void buildInputReader() throws MessagingException {
try {
- reader = new BufferedReader(new InputStreamReader(soc.getInputStream()));
+ reader = new BufferedReader(new InputStreamReader(socket.getInputStream()));
} catch (IOException e) {
throw new MessagingException("Error obtaining input stream " + this.toString(), e);
}
@@ -143,7 +170,7 @@
private void buildOutputWriter() throws MessagingException {
try {
- writer = new PrintWriter(new BufferedOutputStream(soc.getOutputStream()));
+ writer = new PrintWriter(new BufferedOutputStream(socket.getOutputStream()));
} catch (IOException e) {
throw new MessagingException("Error obtaining output stream " + this.toString(), e);
}
@@ -151,5 +178,387 @@
public String toString() {
return "POP3Connection host: " + host + " port: " + port;
+ }
+
+
+ /**
+ * Creates a connected socket
+ *
+ * @exception MessagingException
+ */
+ protected void getConnectedSocket() throws IOException {
+
+ // the socket factory can be specified via a session property. By
+ // default, we just directly
+ // instantiate a socket without using a factor.
+ String socketFactory = getProtocolProperty(MAIL_POP3_FACTORY_CLASS);
+
+ // there are several protocol properties that can be set to tune the
+ // created socket. We need to
+ // retrieve those bits before creating the socket.
+ int timeout = getIntProtocolProperty(MAIL_POP3_TIMEOUT, -1);
+ InetAddress localAddress = null;
+ // see if we have a local address override.
+ String localAddrProp = getProtocolProperty(MAIL_POP3_LOCALADDRESS);
+ if (localAddrProp != null) {
+ localAddress = InetAddress.getByName(localAddrProp);
+ }
+
+ // check for a local port...default is to allow socket to choose.
+ int localPort = getIntProtocolProperty(MAIL_POP3_LOCALPORT, 0);
+
+ socket = null;
+
+ // if there is no socket factory defined (normal), we just create a
+ // socket directly.
+ if (socketFactory == null) {
+ socket = new Socket(host, port, localAddress, localPort);
+ }
+
+ else {
+ try {
+ int socketFactoryPort = getIntProtocolProperty(MAIL_POP3_FACTORY_PORT, -1);
+
+ // we choose the port used by the socket based on overrides.
+ Integer portArg = new Integer(socketFactoryPort == -1 ? port : socketFactoryPort);
+
+ // use the current context loader to resolve this.
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ Class factoryClass = loader.loadClass(socketFactory);
+
+ // done indirectly, we need to invoke the method using
+ // reflection.
+ // This retrieves a factory instance.
+ Method getDefault = factoryClass.getMethod("getDefault", new Class[0]);
+ Object defFactory = getDefault.invoke(new Object(), new Object[0]);
+
+ // now that we have the factory, there are two different
+ // createSocket() calls we use,
+ // depending on whether we have a localAddress override.
+
+ if (localAddress != null) {
+ // retrieve the createSocket(String, int, InetAddress, int)
+ // method.
+ Class[] createSocketSig = new Class[] { String.class, Integer.TYPE, InetAddress.class, Integer.TYPE };
+ Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
+
+ Object[] createSocketArgs = new Object[] { host, portArg, localAddress, new Integer(localPort) };
+ socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
+ } else {
+ // retrieve the createSocket(String, int) method.
+ Class[] createSocketSig = new Class[] { String.class, Integer.TYPE };
+ Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
+
+ Object[] createSocketArgs = new Object[] { host, portArg };
+ socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
+ }
+ } catch (Throwable e) {
+ // if a socket factory is specified, then we may need to fall
+ // back to a default. This behavior
+ // is controlled by (surprise) more session properties.
+ if (isProtocolPropertyTrue(MAIL_POP3_FACTORY_FALLBACK)) {
+ socket = new Socket(host, port, localAddress, localPort);
+ }
+ // we have an exception. We're going to throw an IOException,
+ // which may require unwrapping
+ // or rewrapping the exception.
+ else {
+ // we have an exception from the reflection, so unwrap the
+ // base exception
+ if (e instanceof InvocationTargetException) {
+ e = ((InvocationTargetException) e).getTargetException();
+ }
+
+
+ // throw this as an IOException, with the original exception
+ // attached.
+ IOException ioe = new IOException("Error connecting to " + host + ", " + port);
+ ioe.initCause(e);
+ throw ioe;
+ }
+ }
+ }
+
+ if (timeout >= 0) {
+ socket.setSoTimeout(timeout);
+ }
+ }
+
+ /**
+ * Creates a connected SSL socket for an initial SSL connection.
+ *
+ * @exception MessagingException
+ */
+ protected void getConnectedSSLSocket() throws IOException {
+
+ if (session.getDebug()) {
+ session.getDebugOut().println("Attempting SSL socket connection to server " + host + ":" + port);
+ }
+ // the socket factory can be specified via a protocol property, a
+ // session property, and if all else
+ // fails (which it usually does), we fall back to the standard factory
+ // class.
+ String socketFactory = getProtocolProperty(MAIL_POP3_FACTORY_CLASS, getSessionProperty(MAIL_SSLFACTORY_CLASS,
+ "javax.net.ssl.SSLSocketFactory"));
+
+ // there are several protocol properties that can be set to tune the
+ // created socket. We need to
+ // retrieve those bits before creating the socket.
+ int timeout = getIntProtocolProperty(MAIL_POP3_TIMEOUT, -1);
+ InetAddress localAddress = null;
+ // see if we have a local address override.
+ String localAddrProp = getProtocolProperty(MAIL_POP3_LOCALADDRESS);
+ if (localAddrProp != null) {
+ localAddress = InetAddress.getByName(localAddrProp);
+ }
+
+ // check for a local port...default is to allow socket to choose.
+ int localPort = getIntProtocolProperty(MAIL_POP3_LOCALPORT, 0);
+
+ socket = null;
+
+ // if there is no socket factory defined (normal), we just create a
+ // socket directly.
+ if (socketFactory == null) {
+ System.out.println("SocketFactory was null so creating the connection using a default");
+ socket = new Socket(host, port, localAddress, localPort);
+ }
+
+ else {
+ // we'll try this with potentially two different factories if we're
+ // allowed to fall back.
+ boolean fallback = isProtocolPropertyTrue(MAIL_POP3_FACTORY_FALLBACK);
+ while(true) {
+ try {
+
+
+ if (socket != null) {
+ if (socket.isConnected())
+ break;
+ }
+
+ if (session.getDebug()) {
+ session.getDebugOut().println("Creating SSL socket using factory " + socketFactory);
+ }
+
+ int socketFactoryPort = getIntProtocolProperty(MAIL_POP3_FACTORY_PORT, -1);
+
+ // we choose the port used by the socket based on overrides.
+ Integer portArg = new Integer(socketFactoryPort == -1 ? port : socketFactoryPort);
+
+ // use the current context loader to resolve this.
+ ClassLoader loader = Thread.currentThread().getContextClassLoader();
+ Class factoryClass = loader.loadClass(socketFactory);
+
+ // done indirectly, we need to invoke the method using
+ // reflection.
+ // This retrieves a factory instance.
+ Method getDefault = factoryClass.getMethod("getDefault", new Class[0]);
+ Object defFactory = getDefault.invoke(new Object(), new Object[0]);
+
+ // now that we have the factory, there are two different
+ // createSocket() calls we use,
+ // depending on whether we have a localAddress override.
+
+ if (localAddress != null) {
+ // retrieve the createSocket(String, int, InetAddress,
+ // int) method.
+ Class[] createSocketSig = new Class[] { String.class, Integer.TYPE, InetAddress.class,
+ Integer.TYPE };
+ Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
+
+ Object[] createSocketArgs = new Object[] { host, portArg, localAddress, new Integer(localPort) };
+ socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
+ } else {
+ // retrieve the createSocket(String, int) method.
+ Class[] createSocketSig = new Class[] { String.class, Integer.TYPE };
+ Method createSocket = factoryClass.getMethod("createSocket", createSocketSig);
+
+ Object[] createSocketArgs = new Object[] { host, portArg };
+ socket = (Socket) createSocket.invoke(defFactory, createSocketArgs);
+ }
+ } catch (Throwable e) {
+ // if we're allowed to fallback, then use the default
+ // factory and try this again. We only
+ // allow this to happen once.
+ if (session.getDebug()) {
+ session.getDebugOut().println("First attempt at creating SSL socket failed, falling back to default factory");
+ }
+ if (fallback) {
+ socketFactory = "javax.net.ssl.SSLSocketFactory";
+ fallback = false;
+ continue;
+ }
+ // we have an exception. We're going to throw an
+ // IOException, which may require unwrapping
+ // or rewrapping the exception.
+ else {
+ // we have an exception from the reflection, so unwrap
+ // the base exception
+ if (e instanceof InvocationTargetException) {
+ e = ((InvocationTargetException) e).getTargetException();
+ }
+
+ if (session.getDebug()) {
+ session.getDebugOut().println("Failure creating SSL socket: " + e);
+ }
+ // throw this as an IOException, with the original
+ // exception attached.
+ IOException ioe = new IOException("Error connecting to " + host + ", " + port);
+ ioe.initCause(e);
+ throw ioe;
+ }
+ }
+ }
+ }
+
+ if (timeout >= 0) {
+ socket.setSoTimeout(timeout);
+ }
+ }
+
+ /**
+ * Process a session property as a boolean value, returning either true or
+ * false.
+ *
+ * @return True if the property value is "true". Returns false for any other
+ * value (including null).
+ */
+ protected boolean isProtocolPropertyTrue(String name) {
+ // the name we're given is the least qualified part of the name. We
+ // construct the full property name
+ // using the protocol ("pop3").
+ String fullName = "mail." + protocol + "." + name;
+ return isSessionPropertyTrue(fullName);
+ }
+
+ /**
+ * Process a session property as a boolean value, returning either true or
+ * false.
+ *
+ * @return True if the property value is "true". Returns false for any other
+ * value (including null).
+ */
+ protected boolean isSessionPropertyTrue(String name) {
+ String property = session.getProperty(name);
+ if (property != null) {
+ return property.equals("true");
+ }
+ return false;
+ }
+
+ /**
+ * Get a property associated with this mail session as an integer value.
+ * Returns the default value if the property doesn't exist or it doesn't
+ * have a valid int value.
+ *
+ * @param name
+ * The name of the property.
+ * @param defaultValue
+ * The default value to return if the property doesn't exist.
+ *
+ * @return The property value converted to an int.
+ */
+ protected int getIntProtocolProperty(String name, int defaultValue) {
+ // the name we're given is the least qualified part of the name. We
+ // construct the full property name
+ // using the protocol (pop3).
+ String fullName = "mail." + protocol + "." + name;
+ return getIntSessionProperty(fullName, defaultValue);
+ }
+
+ /**
+ * Get a property associated with this mail session as an integer value.
+ * Returns the default value if the property doesn't exist or it doesn't
+ * have a valid int value.
+ *
+ * @param name
+ * The name of the property.
+ * @param defaultValue
+ * The default value to return if the property doesn't exist.
+ *
+ * @return The property value converted to an int.
+ */
+ protected int getIntSessionProperty(String name, int defaultValue) {
+ String result = getSessionProperty(name);
+ if (result != null) {
+ try {
+ // convert into an int value.
+ return Integer.parseInt(result);
+ } catch (NumberFormatException e) {
+ }
+ }
+ // return default value if it doesn't exist is isn't convertable.
+ return defaultValue;
+ }
+
+ /**
+ * Get a property associated with this mail session. Returns the provided
+ * default if it doesn't exist.
+ *
+ * @param name
+ * The name of the property.
+ * @param defaultValue
+ * The default value to return if the property doesn't exist.
+ *
+ * @return The property value (returns defaultValue if the property has not
+ * been set).
+ */
+ protected String getSessionProperty(String name, String defaultValue) {
+ String result = session.getProperty(name);
+ if (result == null) {
+ return defaultValue;
+ }
+ return result;
+ }
+
+ /**
+ * Get a property associated with this mail session. Returns the provided
+ * default if it doesn't exist.
+ *
+ * @param name
+ * The name of the property.
+ * @param defaultValue
+ * The default value to return if the property doesn't exist.
+ *
+ * @return The property value (returns defaultValue if the property has not
+ * been set).
+ */
+ protected String getProtocolProperty(String name, String defaultValue) {
+ // the name we're given is the least qualified part of the name. We
+ // construct the full property name
+ // using the protocol ("pop3").
+ String fullName = "mail." + protocol + "." + name;
+ return getSessionProperty(fullName, defaultValue);
+ }
+
+ /**
+ * Get a property associated with this mail protocol.
+ *
+ * @param name
+ * The name of the property.
+ *
+ * @return The property value (returns null if the property has not been
+ * set).
+ */
+ protected String getProtocolProperty(String name) {
+ // the name we're given is the least qualified part of the name. We
+ // construct the full property name
+ // using the protocol ("pop3").
+ String fullName = "mail." + protocol + "." + name;
+ return getSessionProperty(fullName);
+ }
+
+ /**
+ * Get a property associated with this mail session.
+ *
+ * @param name
+ * The name of the property.
+ *
+ * @return The property value (returns null if the property has not been
+ * set).
+ */
+ protected String getSessionProperty(String name) {
+ return session.getProperty(name);
}
}
Modified: geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java?view=diff&rev=483693&r1=483692&r2=483693
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Constants.java Thu Dec 7 14:05:25 2006
@@ -39,4 +39,6 @@
public final static int OK = 0;
public final static int ERR = 1;
+
+ public final static int CHALLENGE = 2;
}
Modified: geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Response.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Response.java?view=diff&rev=483693&r1=483692&r2=483693
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Response.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Response.java Thu Dec 7 14:05:25 2006
@@ -33,9 +33,10 @@
public interface POP3Response {
/**
- * Returns the response OK or ERR
+ * Returns the response OK, CHALLENGE or ERR
* <ul>
* <li>OK --> +OK in pop3 spec
+ * <li>CHALLENGE --> + in pop3 spec
* <li>ERR --> -ERR in pop3 spec
* </ul>
*/
Modified: geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3ResponseBuilder.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3ResponseBuilder.java?view=diff&rev=483693&r1=483692&r2=483693
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3ResponseBuilder.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3ResponseBuilder.java Thu Dec 7 14:05:25 2006
@@ -76,6 +76,12 @@
} else if (line.startsWith("-ERR")) {
status = ERR;
line = removeStatusField(line);
+ }else if (line.startsWith("+")) {
+ status = CHALLENGE;
+ line = removeStatusField(line);
+ if (isMultiLineResponse) {
+ data = getMultiLineResponse(session, reader);
+ }
} else {
throw new MessagingException("Unexpected response: " + line);
}
Modified: geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java
URL: http://svn.apache.org/viewvc/geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java?view=diff&rev=483693&r1=483692&r2=483693
==============================================================================
--- geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java (original)
+++ geronimo/javamail/trunk/geronimo-javamail_1.4_provider/src/main/java/org/apache/geronimo/javamail/store/pop3/POP3Store.java Thu Dec 7 14:05:25 2006
@@ -37,11 +37,45 @@
private POP3Connection pop3Con;
- public POP3Store(Session session, URLName urlName) {
- super(session, urlName);
+ protected static final int DEFAULT_MAIL_POP3_PORT = 110;
+ private boolean sslConnection;
+ private int defaultPort;
+
+ private String protocol;
+ public POP3Store(Session session, URLName name) {
+ this(session, name, "pop3", DEFAULT_MAIL_POP3_PORT, false);
}
/**
+ * Common constructor used by the POP3Store and POP3SSLStore classes
+ * to do common initialization of defaults.
+ *
+ * @param session
+ * The host session instance.
+ * @param name
+ * The URLName of the target.
+ * @param protocol
+ * The protocol type ("pop3"). This helps us in
+ * retrieving protocol-specific session properties.
+ * @param defaultPort
+ * The default port used by this protocol. For pop3, this will
+ * be 110. The default for pop3 with ssl is 995.
+ * @param sslConnection
+ * Indicates whether an SSL connection should be used to initial
+ * contact the server. This is different from the STARTTLS
+ * support, which switches the connection to SSL after the
+ * initial startup.
+ */
+ protected POP3Store(Session session, URLName name, String protocol, int defaultPort, boolean sslConnection) {
+ super(session, name);
+ this.protocol = protocol;
+
+ // these are defaults based on what the superclass specifies.
+ this.sslConnection = sslConnection;
+ this.defaultPort = defaultPort;
+
+ }
+ /**
* @see javax.mail.Store#getDefaultFolder()
*
* There is only INBOX supported in POP3 so the default folder is inbox
@@ -91,7 +125,7 @@
try {
portNum = Integer.parseInt(portstring);
} catch (NumberFormatException e) {
- portNum = 110;
+ portNum = defaultPort;
}
}
}
@@ -100,7 +134,7 @@
* Obtaining a connection to the server.
*
*/
- pop3Con = new POP3Connection(this.session, host, portNum);
+ pop3Con = new POP3Connection(this.session, host, portNum, sslConnection, protocol);
try {
pop3Con.open();
} catch (Exception e) {