2006-12-12 18:57:24 -05:00
|
|
|
package davmail.pop;
|
|
|
|
|
|
|
|
import davmail.AbstractConnection;
|
|
|
|
import davmail.DavGatewayTray;
|
|
|
|
import davmail.exchange.ExchangeSession;
|
|
|
|
|
|
|
|
import java.net.Socket;
|
|
|
|
import java.net.UnknownHostException;
|
|
|
|
import java.util.*;
|
|
|
|
import java.io.IOException;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Dav Gateway pop connection implementation
|
|
|
|
*/
|
|
|
|
public class PopConnection extends AbstractConnection {
|
|
|
|
protected static final int INITIAL = 0;
|
|
|
|
protected static final int USER = 1;
|
|
|
|
protected static final int AUTHENTICATED = 2;
|
|
|
|
private List<ExchangeSession.Message> messages;
|
|
|
|
|
|
|
|
// Initialize the streams and start the thread
|
2006-12-14 10:14:18 -05:00
|
|
|
public PopConnection(Socket clientSocket) {
|
|
|
|
super(clientSocket);
|
2006-12-12 18:57:24 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
public long getTotalMessagesLength() {
|
|
|
|
int result = 0;
|
|
|
|
for (ExchangeSession.Message message : messages) {
|
|
|
|
result += message.size;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
public void printList() throws IOException {
|
|
|
|
int i = 1;
|
|
|
|
for (ExchangeSession.Message message : messages) {
|
|
|
|
sendClient(i++ + " " + message.size);
|
|
|
|
}
|
|
|
|
sendClient(".");
|
|
|
|
}
|
|
|
|
|
|
|
|
public void printUidList() throws IOException {
|
|
|
|
int i = 1;
|
|
|
|
for (ExchangeSession.Message message : messages) {
|
|
|
|
sendClient(i++ + " " + message.uid);
|
|
|
|
}
|
|
|
|
sendClient(".");
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
public void run() {
|
|
|
|
String line;
|
|
|
|
StringTokenizer tokens;
|
|
|
|
|
|
|
|
try {
|
|
|
|
sendOK("DavMail POP ready at " + new Date());
|
|
|
|
|
|
|
|
for (; ;) {
|
|
|
|
line = readClient();
|
|
|
|
// unable to read line, connection closed ?
|
|
|
|
if (line == null) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
tokens = new StringTokenizer(line);
|
|
|
|
if (tokens.hasMoreTokens()) {
|
|
|
|
String command = tokens.nextToken();
|
|
|
|
|
|
|
|
if ("QUIT".equalsIgnoreCase(command)) {
|
|
|
|
sendOK("Bye");
|
|
|
|
break;
|
|
|
|
} else if ("USER".equalsIgnoreCase(command)) {
|
|
|
|
userName = null;
|
|
|
|
password = null;
|
|
|
|
session = null;
|
|
|
|
if (tokens.hasMoreTokens()) {
|
|
|
|
userName = tokens.nextToken();
|
|
|
|
sendOK("USER : " + userName);
|
|
|
|
state = USER;
|
|
|
|
} else {
|
|
|
|
sendERR("invalid syntax");
|
|
|
|
state = INITIAL;
|
|
|
|
}
|
|
|
|
} else if ("PASS".equalsIgnoreCase(command)) {
|
|
|
|
if (state != USER) {
|
|
|
|
sendERR("invalid state");
|
|
|
|
state = INITIAL;
|
|
|
|
} else if (!tokens.hasMoreTokens()) {
|
|
|
|
sendERR("invalid syntax");
|
|
|
|
} else {
|
|
|
|
password = tokens.nextToken();
|
|
|
|
try {
|
2006-12-14 10:14:18 -05:00
|
|
|
session = new ExchangeSession();
|
2006-12-12 18:57:24 -05:00
|
|
|
session.login(userName, password);
|
|
|
|
messages = session.getAllMessages();
|
|
|
|
sendOK("PASS");
|
|
|
|
state = AUTHENTICATED;
|
|
|
|
} catch (UnknownHostException e) {
|
|
|
|
DavGatewayTray.error("Connection failed",e);
|
|
|
|
sendERR("Connection failed : "+e+" "+e.getMessage());
|
|
|
|
// close connection
|
|
|
|
break;
|
|
|
|
} catch (Exception e) {
|
|
|
|
DavGatewayTray.error("Authentication failed",e);
|
|
|
|
sendERR("authentication failed : "+e+" "+e.getMessage());
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else if ("CAPA".equalsIgnoreCase(command)) {
|
|
|
|
sendERR("unknown command");
|
|
|
|
} else if (state != AUTHENTICATED) {
|
|
|
|
sendERR("invalid state not authenticated");
|
|
|
|
} else {
|
|
|
|
if ("STAT".equalsIgnoreCase(command)) {
|
|
|
|
sendOK(messages.size() + " " +
|
|
|
|
getTotalMessagesLength());
|
|
|
|
} else if ("LIST".equalsIgnoreCase(command)) {
|
|
|
|
sendOK(messages.size() +
|
|
|
|
" messages (" + getTotalMessagesLength() +
|
|
|
|
" octets)");
|
|
|
|
printList();
|
|
|
|
} else if ("UIDL".equalsIgnoreCase(command)) {
|
|
|
|
sendOK(messages.size() +
|
|
|
|
" messages (" + getTotalMessagesLength() +
|
|
|
|
" octets)");
|
|
|
|
printUidList();
|
|
|
|
} else if ("RETR".equalsIgnoreCase(command)) {
|
|
|
|
if (tokens.hasMoreTokens()) {
|
|
|
|
try {
|
|
|
|
int messageNumber = Integer.valueOf(tokens.
|
|
|
|
nextToken()) - 1;
|
|
|
|
sendOK("");
|
|
|
|
messages.get(messageNumber).write(os);
|
|
|
|
sendClient("");
|
|
|
|
sendClient(".");
|
|
|
|
} catch (Exception e) {
|
|
|
|
DavGatewayTray.error("Error retreiving message",e);
|
|
|
|
sendERR("error retreiving message " + e.getMessage());
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
sendERR("invalid message number");
|
|
|
|
}
|
|
|
|
} else if ("DELE".equalsIgnoreCase(command)) {
|
|
|
|
if (tokens.hasMoreTokens()) {
|
|
|
|
try {
|
|
|
|
int messageNumber = Integer.valueOf(tokens.
|
|
|
|
nextToken()) - 1;
|
|
|
|
messages.get(messageNumber).delete();
|
|
|
|
sendOK("DELETE");
|
|
|
|
} catch (Exception e) {
|
|
|
|
DavGatewayTray.error("Error deleting message",e);
|
|
|
|
sendERR("error deleting message");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
sendERR("invalid message number");
|
|
|
|
}
|
|
|
|
} else if ("TOP".equalsIgnoreCase(command)) {
|
|
|
|
try {
|
|
|
|
int firstMessage = Integer.valueOf(tokens.
|
|
|
|
nextToken()) - 1;
|
|
|
|
int lastMessage = Integer.valueOf(tokens.
|
|
|
|
nextToken()) - 1;
|
|
|
|
for (int i = firstMessage; i <= lastMessage; i++) {
|
|
|
|
messages.get(i).printHeaders(os);
|
|
|
|
sendClient("");
|
|
|
|
sendClient(".");
|
|
|
|
}
|
|
|
|
sendOK("TOP");
|
|
|
|
} catch (Exception e) {
|
|
|
|
sendERR("error retreiving top of messages");
|
|
|
|
}
|
|
|
|
} else if ("RSET".equalsIgnoreCase(command)) {
|
|
|
|
sendOK("RSET");
|
|
|
|
} else {
|
|
|
|
sendERR("unknown command");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
} else {
|
|
|
|
sendERR("unknown command");
|
|
|
|
}
|
|
|
|
|
|
|
|
os.flush();
|
|
|
|
}
|
|
|
|
} catch (IOException e) {
|
|
|
|
DavGatewayTray.error("Exception handling client",e);
|
|
|
|
} finally {
|
|
|
|
try {
|
|
|
|
client.close();
|
|
|
|
} catch (IOException e2) {
|
|
|
|
DavGatewayTray.debug("Exception closing client",e2);
|
|
|
|
}
|
|
|
|
try {
|
|
|
|
if (session != null) {
|
|
|
|
session.close();
|
|
|
|
}
|
|
|
|
} catch (IOException e3) {
|
|
|
|
DavGatewayTray.debug("Exception closing gateway",e3);
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
DavGatewayTray.resetIcon();
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sendOK(String message) throws IOException {
|
|
|
|
sendClient("+OK ", message);
|
|
|
|
}
|
|
|
|
|
|
|
|
public void sendERR(String message) throws IOException {
|
|
|
|
sendClient("-ERR ", message);
|
|
|
|
}
|
|
|
|
}
|