/* * ImapProxy - a caching IMAP proxy daemon * Copyright (C) 2002 Steven Van Acker * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * */ #ifndef __DATABASE_H__ #define __DATABASE_H__ #include #include #include #define DB_STRING_LENGTH 128 /* * The status field of a record indicates the state it is in. * There are 6 fields within the status field, each * with another meaning. * the *_MASK values are used to mask out the value * for a certain field in the status field. * For example: * status = 0x00614143 & DB_STATE_SERVER_MASK = 0x00000100 = DB_STATE_SERVER_NONE * */ /* states the connection to the server can be in */ #define DB_STATE_SERVER_CONNECTION_MASK 0x0000000f #define DB_STATE_SERVER_NOT_CONNECTED 0x00000001 /* no server connection */ #define DB_STATE_SERVER_CONNECTION_STARTED 0x00000002 /* connection has been initiated but not established (non blocking) */ #define DB_STATE_SERVER_CONNECTED 0x00000003 /* connection to server exists */ /* states the client can be in */ #define DB_STATE_CLIENT_MASK 0x000000f0 #define DB_STATE_CLIENT_NOT_AUTHENTICATED 0x00000010 #define DB_STATE_CLIENT_SENT_AUTHENTICATE_COMMAND 0x00000020 #define DB_STATE_CLIENT_SENT_LOGIN_COMMAND 0x00000030 #define DB_STATE_CLIENT_SENT_USERNAME 0x00000040 #define DB_STATE_CLIENT_SENT_PASSWORD 0x00000050 #define DB_STATE_CLIENT_AUTHENTICATED 0x00000060 #define DB_STATE_CLIENT_SENT_LOGOUT_COMMAND 0x00000070 /* states the server can be in, once it is connected */ #define DB_STATE_SERVER_MASK 0x00000f00 #define DB_STATE_SERVER_NONE 0x00000100 #define DB_STATE_SERVER_SENT_GREETING 0x00000200 #define DB_STATE_SERVER_SENT_CAPABILITY_REPLY 0x00000300 #define DB_STATE_SERVER_SENT_USERNAME_REPLY 0x00000400 #define DB_STATE_SERVER_SENT_PASSWORD_REPLY 0x00000500 #define DB_STATE_SERVER_SENT_LOGIN_OK 0x00000600 #define DB_STATE_SERVER_SENT_LOGIN_FAILED 0x00000700 /* states the proxy can be in */ #define DB_STATE_PROXY_MASK 0x0000f000 #define DB_STATE_PROXY_NONE 0x00001000 #define DB_STATE_PROXY_SENT_GREETING_TO_CLIENT 0x00002000 #define DB_STATE_PROXY_SENT_USERNAME_REPLY_TO_CLIENT 0x00003000 #define DB_STATE_PROXY_SENT_PASSWORD_REPLY_TO_CLIENT 0x00004000 #define DB_STATE_PROXY_SENT_CAPABILITY_COMMAND_TO_SERVER 0x00005000 #define DB_STATE_PROXY_SENT_AUTHENTICATE_COMMAND_TO_SERVER 0x00006000 #define DB_STATE_PROXY_SENT_LOGIN_COMMAND_TO_SERVER 0x00007000 #define DB_STATE_PROXY_SENT_USERNAME_TO_SERVER 0x00008000 #define DB_STATE_PROXY_SENT_PASSWORD_TO_SERVER 0x00009000 #define DB_STATE_PROXY_SENT_LOGIN_OK_TO_CLIENT 0x0000a000 #define DB_STATE_PROXY_SENT_LOGIN_FAILED_TO_CLIENT 0x0000b000 /* misc states */ #define DB_STATE_MISC_MASK 0x000f0000 #define DB_STATE_MISC_NONE 0x00010000 #define DB_STATE_MISC_REMOVE_RECORD 0x00020000 /* this flag indicates that the record is about to be removed from the list of records */ /* record states */ #define DB_STATE_RECORD_MASK 0x00f00000 #define DB_STATE_RECORD_NONE 0x00100000 #define DB_STATE_RECORD_READY_TO_FORK 0x00200000 /* record is ready to be forked off */ #define DB_STATE_RECORD_FORKED_CHILD 0x00300000 /* the record is currently forked (can only happen in the child */ #define DB_STATE_RECORD_INACTIVE 0x00400000 /* record is inactive, meaning that there is a server connection but no client connection */ #define DB_STATE_RECORD_ACTIVE 0x00500000 /* record is active : both a server connection and client connection exist. * also, the record is forked */ #define DB_STATE_RECORD_TEMPORARY 0x00600000 /* temporary state means that the client is in the process of logging in. * in this state, a client connection exists, but no server connection. */ /* capability states */ #define DB_STATE_CAPABILITY_MASK 0x0f000000 #define DB_STATE_CAPABILITY_NONE 0x01000000 #define DB_STATE_CAPABILITY_LOGIN 0x02000000 /* server allows only LOGIN */ #define DB_STATE_CAPABILITY_AUTH_LOGIN 0x03000000 /* server allows AUTHENTICATE LOGIN */ /* The IPC codes are the values sent from child to parent, * when the child terminates. */ /* IPC codes sent from child to parent */ #define DB_IPC_RETURNCODE_NORMAL 0x00000001 /* normal exit */ #define DB_IPC_RETURNCODE_SERVER_CLOSED 0x00000002 /* server connection was closed */ #define DB_IPC_RETURNCODE_CLIENT_CLOSED 0x00000003 /* client connection was closed */ #define DB_IPC_RETURNCODE_SERVER_ERROR 0x00000004 /* an error occured on the server connection */ #define DB_IPC_RETURNCODE_CLIENT_ERROR 0x00000005 /* an error occured on the client connection */ /* The message states indicate if we want to just forward the data stream, or process it. */ /* these states specify what needs to happen with a message */ #define DB_MESSAGE_UNCHECKED 0x00000001 /* the message is unchecked. This happens at the start of a message, * when not enough bytes were received to make up a command */ #define DB_MESSAGE_PASSTHROUGH 0x00000002 /* passthrough means that the data stream is being forwarded to client/server * without processing it. */ #define DB_MESSAGE_PROCESS 0x00000003 /* the message is in process mode. this means that the entire message * will be stored in a record, and then processed. */ typedef struct db_record_t DB_record; struct message_t { char **lines; /* each line is terminated by a \r\n * a new line is started with every literal string * (so each line ends with a {123}\r\n) */ int count; /* number of lines */ int completed; /* indicates whether or not the message was completely received */ int literalcountdown; /* number of bytes till the end of the literal string */ int status; /* status of the message. see the defines */ }; struct db_record_t { char username[DB_STRING_LENGTH], password[DB_STRING_LENGTH]; /* username and password belonging to this record */ int clientsocket, serversocket; /* client and server connection socket */ pid_t pid; /* pid of the forked process handling data for this record. */ int clientidlesince; /* time in seconds since the client last sent something (only in TEMPORARY state ! */ int serverlastnoop; /* time in seconds since we last sent a NOOP to the server */ int serveridlesince; /* time in seconds since we started sending NOOP's */ int status; /* status of the record. see the defines */ char *clientauthtag; /* the tag used with the client's authenticate command */ char *proxyauthtag; /* the tag used with the proxy's authenticate command */ struct message_t clientmessage, servermessage; /* current client and server message */ int ipcfd[2]; /* sockets for the ipc messages */ struct in_addr clientlocaladdress; /* the address of the client connecting to the proxy */ unsigned short clientlocalport; /* the local port of the client */ unsigned short proxylocalport; /* the local port of the proxy when connecting to the server */ int reuse; DB_record *next,*prev; }; extern DB_record *DB_start; /* start of the record list */ extern DB_record *DB_end; /* end of the record list */ extern int db_add(DB_record *); extern int db_del(DB_record *); extern int db_cleanup(DB_record *); extern int db_init_record(DB_record *); extern int db_append_to_client_message(DB_record *,char *); extern int db_append_to_server_message(DB_record *,char *); extern int db_delete_client_message(DB_record *); extern int db_delete_server_message(DB_record *); extern int db_create_new_line_in_client_message(DB_record *); extern int db_create_new_line_in_server_message(DB_record *); extern int db_append_to_message(DB_record *,char *,int); extern int db_create_new_line_in_message(DB_record *,int); extern int db_delete_message(DB_record *, int); extern char *db_get_server_message(DB_record *,int); extern char *db_get_client_message(DB_record *,int); extern int db_get_state(DB_record *,int); extern int db_get_server_connection_state(DB_record *); extern int db_get_client_state(DB_record *); extern int db_get_server_state(DB_record *); extern int db_get_proxy_state(DB_record *); extern int db_get_misc_state(DB_record *); extern int db_get_record_state(DB_record *); extern int db_get_capability_state(DB_record *); extern void db_set_state(DB_record *,int,int); extern void db_set_server_connection_state(DB_record *,int); extern void db_set_client_state(DB_record *,int); extern void db_set_server_state(DB_record *,int); extern void db_set_proxy_state(DB_record *,int); extern void db_set_misc_state(DB_record *,int); extern void db_set_record_state(DB_record *,int); extern void db_set_capability_state(DB_record *,int); extern DB_record *db_find_record(DB_record *,char *,char *); extern void db_print_state(DB_record *); extern char *db_get_state_string(int); extern void db_log_stats(); extern char *db_get_record_info(DB_record *); #endif /* __DATABASE_H__ */