1 /* Copyright (C) 2000-2004 Thomas Bopp, Thorsten Hampel, Ludger Merkens
3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License
14 * along with this program; if not, write to the Free Software
15 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 * $Id: pop3.pike,v 1.1 2008/03/31 13:39:57 exodusd Exp $
19 inherit "/net/coal/login";
20 inherit "/net/base/line";
24 class pop3 : public login,line{
31 #define STATE_AUTHORIZATION 1
32 #define STATE_TRANSACTION 2
33 #define STATE_UPDATE 3
35 int _state = STATE_AUTHORIZATION;
36 string sServer = _Server->query_config("server");
40 void send_ok(string msg)
42 LOG("Sending ok ("+msg+")");
43 send_message("+OK " + msg + "\r\n");
49 void send_err(string msg)
51 LOG("Sending error ("+msg+")");
52 send_message("-ERR " + msg + "\r\n");
60 STATE_AUTHORIZATION: ([
84 return "<1234."+time()+"@"+sServer+">";
92 send_ok("POP3 Server ready " + greeting());
95 string tohex(string what)
98 for ( int q = 0; q < strlen(what); q++ ) {
100 i |= what[strlen(what)-1-q];
102 return sprintf("%x", i);
106 * Authenticate to the pop server.
108 * @param string user - the current user.
109 * @param string auth - the authorization string.
112 void apop(string user, string auth)
114 if ( oUser->check_user_password_md5(greeting(), auth) )
115 send_ok("maildrop has 0 message (0 octets)");
117 send_err("authentification failed");
123 void auth(string type)
125 LOG("auth("+type+")");
126 send_err("Unrecognized authentication type");
134 oUser = _Persistence->lookup_user(u);
135 if ( !objectp(oUser) )
136 send_err("no such user ("+u+")");
137 send_ok("user, now send pass");
143 string status_mailbox()
145 return oUser->get_identifier()+"'s maildrop has " +
146 oMailBox->get_num_messages() + " messages ("+
147 oMailBox->get_size() + " octets)";
155 if ( oUser->check_user_password(p) ) {
156 oMailBox = _Server->get_module("mailbox")->get_mailbox(oUser);
158 send_ok(status_mailbox());
159 _state = STATE_TRANSACTION;
160 LOG("login ok..."+sprintf("%O", get_user_object()));
163 send_err("Password does not match");
171 send_ok(oMailBox->get_num_messages() + " " + oMailBox->get_size());
180 for ( int i = 0; i < oMailBox->get_num_messages(); i++ ) {
181 send_message((i+1) + " " + oMailBox->get_message_size(i) +"\r\n");
183 send_message(".\r\n");
191 send_ok(oMailBox->get_message_size(num-1)+ " octets");
192 send_message(oMailBox->retrieve_message(num-1));
193 send_message("\r\n.\r\n");
201 if ( oMailBox->delete_message(num-1) )
202 send_ok("message "+ num + " deleted");
204 send_err("failed to delete message");
212 send_ok("Capability list follows");
213 foreach(indices(mCmd[_state]), string idx) {
214 send_message(idx + "\r\n");
216 send_message(".\r\n");
222 * Returns the unique id for a message, (object-id)
224 * @param int num - the message to identify
229 send_ok(num + " " + oMailBox->get_message_id(num-1));
230 send_message(".\r\n");
236 void top(int num, int l)
239 string message = oMailBox->retrieve_message(num-1);
241 int i = search(message, "\r\n");
242 header = message[..i-1];
243 send_message(header);
244 body = message[i+2..];
245 array lines = body / "\n";
246 if ( l >= sizeof(lines) )
247 send_message(body + "\r\n.\r\n");
249 send_message((lines[..l-1]*"\n")+ "\r\n.\r\n");
259 _state = STATE_AUTHORIZATION;
260 oMailBox->cleanup(); // remove all messages scheduled for deletion
261 int messages_left = (objectp(oMailBox) ? oMailBox->get_num_messages() : 0);
262 send_ok("steam POP3 server signing off (" + messages_left +
272 void process_command(string cmd)
276 commands = cmd / " ";
278 for ( int i = 0; i < sizeof(commands); i++ ) {
279 mixed token = commands[i];
280 int l = strlen(token);
282 if ( sscanf(token, "%d", token) && strlen((string)token)==l)
285 function f = mCmd[_state][commands[0]];
286 if ( functionp(f) ) {
287 if ( sizeof(commands) == 1 )
293 send_err("command not recognized");
298 string get_socket_name() { return "pop3"; }