1 /*
2  * ImapProxy - a caching IMAP proxy daemon
3  * Copyright (C) 2002 Steven Van Acker
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
18  *
19  */
20 
21 
22 #ifndef __DATABASE_H__
23 #define __DATABASE_H__
24 
25 #include <sys/types.h>
26 #include <unistd.h>
27 #include <netinet/in.h>
28 
29 #define DB_STRING_LENGTH 128
30 
31 /*
32  * The status field of a record indicates the state it is in.
33  * There are 6 fields within the status field, each
34  * with another meaning.
35  * the *_MASK values are used to mask out the value
36  * for a certain field in the status field.
37  * For example:
38  * 	status = 0x00614143 & DB_STATE_SERVER_MASK = 0x00000100 = DB_STATE_SERVER_NONE
39  *
40  */
41 
42 /* states the connection to the server can be in */
43 #define DB_STATE_SERVER_CONNECTION_MASK				0x0000000f
44 #define DB_STATE_SERVER_NOT_CONNECTED				0x00000001	/* no server connection */
45 #define DB_STATE_SERVER_CONNECTION_STARTED			0x00000002	/* connection has been initiated but not established (non blocking) */
46 #define DB_STATE_SERVER_CONNECTED				0x00000003	/* connection to server exists */
47 
48 /* states the client can be in */
49 #define DB_STATE_CLIENT_MASK					0x000000f0
50 #define DB_STATE_CLIENT_NOT_AUTHENTICATED			0x00000010
51 #define DB_STATE_CLIENT_SENT_AUTHENTICATE_COMMAND		0x00000020
52 #define DB_STATE_CLIENT_SENT_LOGIN_COMMAND			0x00000030
53 #define DB_STATE_CLIENT_SENT_USERNAME				0x00000040
54 #define DB_STATE_CLIENT_SENT_PASSWORD                   	0x00000050
55 #define DB_STATE_CLIENT_AUTHENTICATED                   	0x00000060
56 #define DB_STATE_CLIENT_SENT_LOGOUT_COMMAND			0x00000070
57 
58 /* states the server can be in, once it is connected */
59 #define DB_STATE_SERVER_MASK					0x00000f00
60 #define DB_STATE_SERVER_NONE					0x00000100
61 #define DB_STATE_SERVER_SENT_GREETING                   	0x00000200
62 #define DB_STATE_SERVER_SENT_CAPABILITY_REPLY			0x00000300
63 #define DB_STATE_SERVER_SENT_USERNAME_REPLY			0x00000400
64 #define DB_STATE_SERVER_SENT_PASSWORD_REPLY			0x00000500
65 #define DB_STATE_SERVER_SENT_LOGIN_OK				0x00000600
66 #define DB_STATE_SERVER_SENT_LOGIN_FAILED			0x00000700
67 
68 /* states the proxy can be in */
69 #define DB_STATE_PROXY_MASK					0x0000f000
70 #define DB_STATE_PROXY_NONE					0x00001000
71 #define DB_STATE_PROXY_SENT_GREETING_TO_CLIENT			0x00002000
72 #define DB_STATE_PROXY_SENT_USERNAME_REPLY_TO_CLIENT		0x00003000
73 #define DB_STATE_PROXY_SENT_PASSWORD_REPLY_TO_CLIENT		0x00004000
74 #define DB_STATE_PROXY_SENT_CAPABILITY_COMMAND_TO_SERVER	0x00005000
75 #define DB_STATE_PROXY_SENT_AUTHENTICATE_COMMAND_TO_SERVER	0x00006000
76 #define DB_STATE_PROXY_SENT_LOGIN_COMMAND_TO_SERVER		0x00007000
77 #define DB_STATE_PROXY_SENT_USERNAME_TO_SERVER			0x00008000
78 #define DB_STATE_PROXY_SENT_PASSWORD_TO_SERVER			0x00009000
79 #define DB_STATE_PROXY_SENT_LOGIN_OK_TO_CLIENT			0x0000a000
80 #define DB_STATE_PROXY_SENT_LOGIN_FAILED_TO_CLIENT		0x0000b000
81 
82 /* misc states */
83 #define DB_STATE_MISC_MASK					0x000f0000
84 #define DB_STATE_MISC_NONE					0x00010000
85 #define DB_STATE_MISC_REMOVE_RECORD				0x00020000	/* this flag indicates that the record is about to be removed from the list of records */
86 
87 /* record states */
88 #define DB_STATE_RECORD_MASK					0x00f00000
89 #define DB_STATE_RECORD_NONE					0x00100000
90 #define DB_STATE_RECORD_READY_TO_FORK				0x00200000	/* record is ready to be forked off */
91 #define DB_STATE_RECORD_FORKED_CHILD				0x00300000	/* the record is currently forked (can only happen in the child */
92 #define DB_STATE_RECORD_INACTIVE				0x00400000	/* record is inactive, meaning that there is a server connection but no client connection */
93 #define DB_STATE_RECORD_ACTIVE					0x00500000	/* record is active : both a server connection and client connection exist.
94 										 * also, the record is forked */
95 #define DB_STATE_RECORD_TEMPORARY				0x00600000	/* temporary state means that the client is in the process of logging in.
96 										 * in this state, a client connection exists, but no server connection. */
97 
98 /* capability states */
99 #define DB_STATE_CAPABILITY_MASK				0x0f000000
100 #define DB_STATE_CAPABILITY_NONE				0x01000000
101 #define DB_STATE_CAPABILITY_LOGIN				0x02000000	/* server allows only LOGIN */
102 #define DB_STATE_CAPABILITY_AUTH_LOGIN				0x03000000	/* server allows AUTHENTICATE LOGIN */
103 
104 /* The IPC codes are the values sent from child to parent,
105  * when the child terminates.
106  */
107 
108 /* IPC codes sent from child to parent */
109 #define DB_IPC_RETURNCODE_NORMAL				0x00000001	/* normal exit */
110 #define DB_IPC_RETURNCODE_SERVER_CLOSED				0x00000002	/* server connection was closed */
111 #define DB_IPC_RETURNCODE_CLIENT_CLOSED				0x00000003	/* client connection was closed */
112 #define DB_IPC_RETURNCODE_SERVER_ERROR				0x00000004	/* an error occured on the server connection */
113 #define DB_IPC_RETURNCODE_CLIENT_ERROR				0x00000005	/* an error occured on the client connection */
114 
115 /* The message states indicate if we want to just forward the data stream, or process it.
116  */
117 
118 /* these states specify what needs to happen with a message */
119 #define DB_MESSAGE_UNCHECKED					0x00000001	/* the message is unchecked. This happens at the start of a message,
120 										 * when not enough bytes were received to make up a command */
121 #define DB_MESSAGE_PASSTHROUGH					0x00000002	/* passthrough means that the data stream is being forwarded to client/server
122 										 * without processing it. */
123 #define DB_MESSAGE_PROCESS					0x00000003	/* the message is in process mode. this means that the entire message
124 										 * will be stored in a record, and then processed. */
125 
126 typedef struct db_record_t DB_record;
127 
128 struct message_t
129 {
130     char **lines;		/* each line is terminated by a \r\n
131 				 * a new line is started with every literal string
132 				 * (so each line ends with a {123}\r\n)
133 				 */
134     int count;			/* number of lines */
135     int completed;		/* indicates whether or not the message was completely received */
136     int literalcountdown;	/* number of bytes till the end of the literal string */
137     int status;			/* status of the message. see the defines */
138 };
139 
140 
141 struct db_record_t
142 {
143     char username[DB_STRING_LENGTH], password[DB_STRING_LENGTH];	/* username and password belonging to this record */
144 
145     int clientsocket, serversocket;					/* client and server connection socket */
146     pid_t pid;								/* pid of the forked process handling data for this record. */
147 
148     int clientidlesince;						/* time in seconds since the client last sent something (only in TEMPORARY state ! */
149     int serverlastnoop;							/* time in seconds since we last sent a NOOP to the server */
150     int serveridlesince;						/* time in seconds since we started sending NOOP's */
151 
152     int status;								/* status of the record. see the defines */
153 
154     char *clientauthtag; 						/* the tag used with the client's authenticate command */
155     char *proxyauthtag; 						/* the tag used with the proxy's authenticate command */
156 
157     struct message_t clientmessage, servermessage;			/* current client and server message */
158 
159     int ipcfd[2];							/* sockets for the ipc messages */
160 
161     struct in_addr clientlocaladdress;					/* the address of the client connecting to the proxy */
162     unsigned short clientlocalport;					/* the local port of the client */
163     unsigned short proxylocalport;					/* the local port of the proxy when connecting to the server */
164 
165     int reuse;
166 
167     DB_record *next,*prev;
168 };
169 
170 extern DB_record *DB_start;	/* start of the record list */
171 extern DB_record *DB_end;	/* end of the record list */
172 
173 extern int db_add(DB_record *);
174 extern int db_del(DB_record *);
175 extern int db_cleanup(DB_record *);
176 extern int db_init_record(DB_record *);
177 
178 extern int db_append_to_client_message(DB_record *,char *);
179 extern int db_append_to_server_message(DB_record *,char *);
180 extern int db_delete_client_message(DB_record *);
181 extern int db_delete_server_message(DB_record *);
182 extern int db_create_new_line_in_client_message(DB_record *);
183 extern int db_create_new_line_in_server_message(DB_record *);
184 
185 extern int db_append_to_message(DB_record *,char *,int);
186 extern int db_create_new_line_in_message(DB_record *,int);
187 extern int db_delete_message(DB_record *, int);
188 
189 extern char *db_get_server_message(DB_record *,int);
190 extern char *db_get_client_message(DB_record *,int);
191 
192 extern int db_get_state(DB_record *,int);
193 extern int db_get_server_connection_state(DB_record *);
194 extern int db_get_client_state(DB_record *);
195 extern int db_get_server_state(DB_record *);
196 extern int db_get_proxy_state(DB_record *);
197 extern int db_get_misc_state(DB_record *);
198 extern int db_get_record_state(DB_record *);
199 extern int db_get_capability_state(DB_record *);
200 
201 extern void db_set_state(DB_record *,int,int);
202 extern void db_set_server_connection_state(DB_record *,int);
203 extern void db_set_client_state(DB_record *,int);
204 extern void db_set_server_state(DB_record *,int);
205 extern void db_set_proxy_state(DB_record *,int);
206 extern void db_set_misc_state(DB_record *,int);
207 extern void db_set_record_state(DB_record *,int);
208 extern void db_set_capability_state(DB_record *,int);
209 
210 extern DB_record *db_find_record(DB_record *,char *,char *);
211 
212 extern void db_print_state(DB_record *);
213 extern char *db_get_state_string(int);
214 extern void db_log_stats();
215 extern char *db_get_record_info(DB_record *);
216 
217 #endif	/* __DATABASE_H__ */
218 
219