package davmail.imap; import java.net.Socket; import java.util.StringTokenizer; import java.util.List; import java.io.IOException; import davmail.AbstractConnection; import davmail.DavGatewayTray; import davmail.exchange.ExchangeSession; /** * Dav Gateway smtp connection implementation. * Still alpha code : need to find a way to handle message ids */ public class ImapConnection extends AbstractConnection { protected static final int INITIAL = 0; protected static final int AUTHENTICATED = 1; // Initialize the streams and start the thread public ImapConnection(Socket clientSocket) { super(clientSocket); } public void run() { String line; StringTokenizer tokens; try { sendClient("* OK Davmail Imap Server ready"); for (; ;) { line = readClient(); // unable to read line, connection closed ? if (line == null) { break; } tokens = new StringTokenizer(line); if (tokens.hasMoreTokens()) { String commandId = tokens.nextToken(); if (tokens.hasMoreTokens()) { String command = tokens.nextToken(); if ("LOGOUT".equalsIgnoreCase(command)) { sendClient("* BYE Closing connection"); sendClient(commandId + " OK Completed"); break; } if ("capability".equalsIgnoreCase(command)) { sendClient("* CAPABILITY IMAP4REV1"); sendClient(commandId + " OK CAPABILITY completed"); } else if ("login".equalsIgnoreCase(command)) { parseCredentials(tokens); session = new ExchangeSession(); try { session.login(userName, password); sendClient(commandId + " OK Authenticated"); state = AUTHENTICATED; } catch (Exception e) { DavGatewayTray.error("Authentication failed",e); sendClient(commandId + " NO LOGIN failed"); state = INITIAL; } } else { if (state != AUTHENTICATED) { sendClient(commandId + " BAD command authentication required"); } else { if ("lsub".equalsIgnoreCase(command)) { /* TODO : implement 2 lsub "" "*" * LSUB () "/" INBOX/sent-mail * LSUB () "/" Trash * LSUB () "/" INBOX/spam * LSUB () "/" Envoy&AOk-s * LSUB () "/" Drafts 2 OK LSUB completed */ sendClient(commandId + " OK LSUB completed"); } else if ("list".equalsIgnoreCase(command)) { /* TODO : implement */ sendClient(commandId + " OK LIST completed"); } else if ("select".equalsIgnoreCase(command)) { if (tokens.hasMoreTokens()) { String folderName = removeQuotes(tokens.nextToken()); ExchangeSession.Folder folder = session.selectFolder(folderName); sendClient("* " + folder.childCount + " EXISTS"); sendClient("* " + folder.unreadCount + " RECENT"); // TODO : implement, compute session message ids //sendClient("* [UNSEEN 1] first unseen message in inbox"); sendClient(commandId + " OK [READ-WRITE] SELECT completed"); } else { sendClient(commandId + " BAD command unrecognized"); } } else if ("uid".equalsIgnoreCase(command)) { if (tokens.hasMoreTokens() && "fetch".equalsIgnoreCase(tokens.nextToken())) { if (tokens.hasMoreTokens()) { String parameter = tokens.nextToken(); if ("1:*".equals(parameter)) { List messages = session.getAllMessages(); for (ExchangeSession.Message message : messages) { sendClient("* FETCH (UID " + message.uid + " FLAGS ())"); } sendClient(commandId + " OK UID FETCH completed"); } else { sendClient(commandId + " BAD command unrecognized"); } } else { sendClient(commandId + " BAD command unrecognized"); } } else { sendClient(commandId + " BAD command unrecognized"); } } else { sendClient(commandId + " BAD command unrecognized"); } } } } else { sendClient(commandId + " BAD missing command"); } } else { sendClient("BAD Null 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(); } /** * Decode SMTP credentials */ protected void parseCredentials(StringTokenizer tokens) throws IOException { if (tokens.hasMoreTokens()) { userName = removeQuotes(tokens.nextToken()); } else { throw new IOException("Invalid credentials"); } if (tokens.hasMoreTokens()) { password = removeQuotes(tokens.nextToken()); } else { throw new IOException("Invalid credentials"); } int backslashindex = userName.indexOf("\\"); if (backslashindex > 0) { userName = userName.substring(0, backslashindex) + userName.substring(backslashindex + 1); } } protected String removeQuotes(String value) { String result = value; if (result.startsWith("\"")) { result = result.substring(1); } if (result.endsWith("\"")) { result = result.substring(0, result.length() - 1); } return result; } public void sendMessage(StringBuffer buffer) throws Exception { // TODO implement } }