1 /*
2 
3  Copyright (C) 1999-2004 IC & S  dbmail@ic-s.nl
4  Copyright (c) 2004-2012 NFG Net Facilities Group BV support@nfg.nl
5 
6  This program is free software; you can redistribute it and/or
7  modify it under the terms of the GNU General Public License
8  as published by the Free Software Foundation; either
9  version 2 of the License, or (at your option) any later
10  version.
11 
12  This program is distributed in the hope that it will be useful,
13  but WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  GNU General Public License for more details.
16 
17  You should have received a copy of the GNU General Public License
18  along with this program; if not, write to the Free Software
19  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 */
21 
22 /**
23  * \file dbmailtypes.h
24  *
25  * all data type definitions used within the dbmail package should
26  * be declared here.
27  *
28  */
29 
30 #ifndef DBMAILTYPES_H
31 #define DBMAILTYPES_H
32 
33 #include "dbmail.h"
34 #include "dm_mempool.h"
35 
36 // start worker threads per client
37 //#define DM_CLIENT_THREADS
38 
39 /** max length of search query */
40 #define MAX_SEARCH_LEN 2048
41 
42 #define MIME_FIELD_MAX 128
43 #define MIME_VALUE_MAX 4096
44 
45 #define MAXSOCKETS 256
46 
47 #define UID_SIZE 96
48 #define IPNUM_LEN 32
49 #define IPLEN 32
50 #define BACKLOG 128
51 
52 #define DM_SOCKADDR_LEN 108
53 #define DM_USERNAME_LEN 255
54 
55 /** string length of configuration values */
56 #define FIELDSIZE 1024
57 
58 /** Maximal size available for comparision CLOB with string constant inside
59  * simple SELECT ... WHERE ... statement */
60 #define DM_ORA_MAX_BYTES_LOB_CMP 4000
61 
62 typedef enum {
63 	DM_DRIVER_SQLITE	= 1,
64 	DM_DRIVER_MYSQL		= 2,
65 	DM_DRIVER_POSTGRESQL	= 3,
66 	DM_DRIVER_ORACLE	= 4
67 } Driver_T;
68 
69 typedef enum {
70 	DM_EQUERY 	= -1,
71 	DM_SUCCESS 	= 0,
72 	DM_EGENERAL 	= 1
73 } DbmailErrorCodes;
74 
75 /** Status fields for messages *
76  *
77  * Please note that db.c uses 'status < MESSAGE_STATUS_DELETE'
78  * and these numbers go into the database as magic values,
79  * so don't change them unless you want to break things badly.
80  * */
81 typedef enum {
82 	MESSAGE_STATUS_NEW     = 0,
83 	MESSAGE_STATUS_SEEN    = 1,
84 	MESSAGE_STATUS_DELETE  = 2,
85 	MESSAGE_STATUS_PURGE   = 3,
86 	MESSAGE_STATUS_UNUSED  = 4,
87 	MESSAGE_STATUS_INSERT  = 5,
88 	MESSAGE_STATUS_ERROR   = 6
89 } MessageStatus_T;
90 
91 /** Field_T is used for storing configuration values */
92 typedef char Field_T[FIELDSIZE];
93 
94 /** size of a TimeString_T field */
95 #define TIMESTRING_SIZE 30
96 
97 /** TimeString_T is used for holding timestring */
98 typedef char TimeString_T[TIMESTRING_SIZE];
99 
100 /** parameters for the database connection */
101 typedef struct {
102 	Field_T dburi;
103 	Driver_T db_driver; //
104 	Field_T driver;         /**< database driver: mysql, pgsql, sqlite */
105 	Field_T authdriver;     /**< authentication driver: sql, ldap */
106 	Field_T sortdriver;     /**< sort driver: sieve or nothing at all */
107 	Field_T host;		/**< hostname or ip address of database server */
108 	Field_T user;		/**< username to connect with */
109 	Field_T pass;		/**< password of user */
110 	Field_T db;		/**< name of database to connect with */
111 	unsigned int port;	/**< port number of database server */
112 	Field_T sock;		/**< path to local unix socket (local connection) */
113 	Field_T pfx;		/**< prefix for tables e.g. dbmail_ */
114 	unsigned int max_db_connections; /**< maximum connections the pool will create with the database */
115 	unsigned int serverid;	/**< unique id for dbmail instance used in clusters */
116 	Field_T encoding;	/**< character encoding to use */
117 	unsigned int query_time_info;
118 	unsigned int query_time_notice;
119 	unsigned int query_time_warning;
120 	unsigned int query_timeout;
121 } DBParam_T;
122 
123 enum DBMAIL_MESSAGE_CLASS {
124 	DBMAIL_MESSAGE,
125 	DBMAIL_MESSAGE_PART
126 };
127 
128 enum DBMAIL_MESSAGE_FILTER_TYPES {
129 	DBMAIL_MESSAGE_FILTER_FULL = 1,
130 	DBMAIL_MESSAGE_FILTER_HEAD,
131 	DBMAIL_MESSAGE_FILTER_BODY
132 };
133 
134 typedef struct {
135 	// Memory Pool
136 	Mempool_T pool;
137 	gboolean freepool;
138 
139 	// ID
140 	uint64_t id;
141 	uint64_t msg_idnr;
142 
143 	// scanned values
144 	const char *charset;
145 	time_t internal_date;
146 	int internal_date_gmtoff;
147 	String_T envelope_recipient;
148 
149 	// Data access
150 	enum DBMAIL_MESSAGE_CLASS klass;
151 	GMimeObject *content;
152 	GMimeStream *stream;
153 	String_T crlf;
154 
155 	// Mappings
156 	GHashTable *header_dict;
157 	GTree *header_name;
158 	GTree *header_value;
159 
160 	// storage
161 	int part_key;
162 	int part_depth;
163 	int part_order;
164 
165 } DbmailMessage;
166 
167 /**********************************************************************
168  *                              POP3
169 **********************************************************************/
170 
171 struct message {
172 	uint64_t msize;	  /**< message size */
173 	uint64_t messageid;  /**< messageid (from database) */
174 	uint64_t realmessageid; /**< ? */
175 	char uidl[UID_SIZE]; /**< unique id */
176 	MessageStatus_T messagestatus;
177 	MessageStatus_T virtual_messagestatus;
178 };
179 
180 
181 /**********************************************************************
182  *                              IMAP
183 **********************************************************************/
184 
185 enum IMAP_COMMAND_TYPES {
186 	IMAP_COMM_NONE,                 // 0
187 	IMAP_COMM_CAPABILITY,           // 1
188 	IMAP_COMM_NOOP,                 // 2
189 	IMAP_COMM_LOGOUT,               // 3
190 	IMAP_COMM_AUTH,                 // 4
191 	IMAP_COMM_LOGIN,                // 5
192 	IMAP_COMM_SELECT,               // 6
193 	IMAP_COMM_EXAMINE,              // 7
194 	IMAP_COMM_ENABLE,               // 8
195 	IMAP_COMM_CREATE,               // 9
196 	IMAP_COMM_DELETE,               // 10
197 	IMAP_COMM_RENAME,               // 11
198 	IMAP_COMM_SUBSCRIBE,            // 12
199 	IMAP_COMM_UNSUBSCRIBE,          // 13
200 	IMAP_COMM_LIST,                 // 14
201 	IMAP_COMM_LSUB,                 // 15
202 	IMAP_COMM_STATUS,               // 16
203 	IMAP_COMM_APPEND,               // 17
204 	IMAP_COMM_CHECK,                // 18
205 	IMAP_COMM_CLOSE,                // 19
206 	IMAP_COMM_EXPUNGE,              // 20
207 	IMAP_COMM_SEARCH,               // 21
208 	IMAP_COMM_FETCH,                // 22
209 	IMAP_COMM_STORE,                // 23
210 	IMAP_COMM_COPY,                 // 24
211 	IMAP_COMM_UID,                  // 25
212 	IMAP_COMM_SORT,                 // 26
213 	IMAP_COMM_GETQUOTAROOT,         // 27
214 	IMAP_COMM_GETQUOTA,             // 28
215 	IMAP_COMM_SETACL,               // 29
216 	IMAP_COMM_DELETEACL,            // 30
217 	IMAP_COMM_GETACL,               // 31
218 	IMAP_COMM_LISTRIGHTS,           // 32
219 	IMAP_COMM_MYRIGHTS,             // 33
220 	IMAP_COMM_NAMESPACE,            // 34
221 	IMAP_COMM_THREAD,               // 35
222 	IMAP_COMM_UNSELECT,             // 36
223 	IMAP_COMM_IDLE,                 // 37
224 	IMAP_COMM_STARTTLS,             // 38
225 	IMAP_COMM_ID,                   // 39
226 	IMAP_COMM_LAST                  // 40
227 };
228 
229 typedef enum {
230 	CLIENTSTATE_ANY 			= -1,
231 	CLIENTSTATE_INITIAL_CONNECT		= 0,
232 	CLIENTSTATE_NON_AUTHENTICATED		= 1,
233 	CLIENTSTATE_AUTHENTICATED		= 2,
234 	CLIENTSTATE_SELECTED			= 3,
235 	CLIENTSTATE_LOGOUT			= 4,
236 	CLIENTSTATE_QUIT			= 5,
237 	CLIENTSTATE_ERROR			= 6,
238 	CLIENTSTATE_QUIT_QUEUED			= 7
239 } ClientState_T;
240 
241 typedef struct {
242 	unsigned int condstore : 1;
243 	unsigned int qresync   : 1;
244 } ImapEnabled_T;
245 
246 enum {
247 	IMAP_FLAG_SEEN,
248 	IMAP_FLAG_ANSWERED,
249 	IMAP_FLAG_DELETED,
250 	IMAP_FLAG_FLAGGED,
251 	IMAP_FLAG_DRAFT,
252 	IMAP_FLAG_RECENT
253 };
254 
255 enum IMAP4_PERMISSION {
256 	IMAPPERM_READ		= 0x01,
257 	IMAPPERM_READWRITE	= 0x02
258 };
259 
260 enum IMAP4_FLAG_ACTIONS {
261 	IMAPFA_NONE,
262 	IMAPFA_REPLACE,
263 	IMAPFA_ADD,
264 	IMAPFA_REMOVE
265 };
266 
267 enum BODY_FETCH_ITEM_TYPES {
268 	BFIT_TEXT               = 1,
269 	BFIT_HEADER             = 2,
270 	BFIT_MIME               = 3,
271 	BFIT_HEADER_FIELDS      = 4,
272 	BFIT_HEADER_FIELDS_NOT  = 5,
273 	BFIT_ALL                = 6
274 };
275 
276 
277 // thread manager structures
278 //
279 
280 // client_thread
281 typedef struct  {
282 	Mempool_T pool;
283 	int sock;
284 	SSL *ssl;                       /* SSL/TLS context for this client */
285 	gboolean ssl_state;		/* SSL_accept done or not */
286 	struct sockaddr caddr;
287 	socklen_t caddr_len;
288 	struct sockaddr saddr;
289 	socklen_t saddr_len;
290 	void (*cb_close) (void *);	/* termination callback */
291 } client_sock;
292 
293 //
294 
295 #define TLS_SEGMENT	262144
296 #define CLIENT_OK	0
297 #define CLIENT_AGAIN	1
298 #define CLIENT_ERR	2
299 #define CLIENT_EOF	4
300 
301 typedef struct {
302 	Mempool_T pool;
303 	client_sock *sock;
304 	int rx, tx;                     /* read and write filehandles */
305 	uint64_t bytes_rx;		/* read byte counter */
306 	uint64_t bytes_tx;		/* write byte counter */
307 
308 	pthread_mutex_t lock;
309 	int client_state;		/* CLIENT_OK, CLIENT_AGAIN, CLIENT_EOF */
310 	int deferred;                   // deferred cleanup counter
311 
312 	struct event *pev;		/* self-pipe event */
313 	void (*cb_pipe) (void *);	/* callback for self-pipe events */
314 
315 	struct event *rev, *wev;  	/* read event, write event */
316 	void (*cb_time) (void *);
317 	void (*cb_write) (void *);
318 	int (*cb_error) (int fd, int error, void *);
319 
320 	Cram_T auth;                    /* authentication context for cram-md5 */
321 	uint64_t authlog_id;
322 
323 	Field_T clientname;             /* resolved client name */
324 
325 	char src_ip[NI_MAXHOST+1];	/* client IP-number */
326 	char src_port[NI_MAXSERV+1];	/* client port number */
327 
328 	char dst_ip[NI_MAXHOST+1];	/* server IP-number */
329 	char dst_port[NI_MAXSERV+1];      /* server port number */
330 
331 	struct timeval timeout;		/**< timeout on socket */
332 
333 	int service_before_smtp;
334 
335 	char tls_wbuf[TLS_SEGMENT];	/* buffer to write during tls session */
336 	uint64_t tls_wbuf_n;		/* number of octets to write during tls session */
337 
338 	uint64_t rbuff_size;              /* size of string-literals */
339 	String_T read_buffer;		/* input buffer */
340 	uint64_t read_buffer_offset;	/* input buffer offset */
341 
342 	String_T write_buffer;		/* output buffer */
343 	uint64_t write_buffer_offset;	/* output buffer offset */
344 
345 	uint64_t len;			/* crlf decoded octets read by last ci_read(ln) call */
346 } ClientBase_T;
347 
348 struct http_sock {
349 	char address[128];
350 	unsigned short port;
351 };
352 
353 typedef struct {
354 	Mempool_T pool;
355 	ClientBase_T *ci;
356 	ClientState_T state;			/**< session state */
357 	void (*handle_input) (void *);
358 
359 	int error_count;		/**< number of errors that have occured */
360 	int was_apop;			/**< 1 if session was  session was apop (no plaintext password) */
361 	int SessionResult;		/**< what happened during the session */
362 
363 	int parser_state;
364 	int command_state;
365 	int command_type;		/* command type */
366 	List_T args;			/* command args (allocated char *) */
367 
368 	String_T rbuff;			/* input buffer */
369 
370 	char *username;
371 	char *password;
372 	char hostname[64];
373 	char *apop_stamp;		/**< timestamp for APOP */
374 
375 	uint64_t useridnr;			/**< Used by timsieved */
376 	uint64_t totalsize;		/**< total size of messages */
377 	uint64_t virtual_totalsize;
378 	uint64_t totalmessages; 		/**< number of messages */
379 	uint64_t virtual_totalmessages;
380 
381 	List_T messagelst;		/** list of messages */
382 	List_T from;			// lmtp senders
383 	List_T rcpt;			// lmtp recipients
384 } ClientSession_T;
385 
386 typedef struct {
387 	int no_daemonize;
388 	int log_verbose;
389 	char *pidFile;
390 	int timeout;
391 	int login_timeout;
392 	char **iplist;                  // Allocated memory.
393 	Field_T port;
394 	Field_T ssl_port;
395 	int ipcount;
396 	int socketcount;
397 	int ssl_socketcount;
398 	int *listenSockets;             // Allocated memory.
399 	int *ssl_listenSockets;         // Allocated memory.
400 	int service_before_smtp;
401 	gboolean authlog;
402 	gboolean ssl;
403 	int backlog;
404 	int resolveIP;
405 	struct evhttp **evhs;           // http server sockets list
406 	Field_T service_name;
407         Field_T process_name;
408 	Field_T serverUser;
409         Field_T serverGroup;
410 	Field_T socket;
411 	Field_T log;
412 	Field_T error_log;
413 	Field_T pid_dir;
414         Field_T tls_cafile;
415         Field_T tls_cert;
416         Field_T tls_key;
417         Field_T tls_ciphers;
418 	int (*ClientHandler) (client_sock *);
419 	void (*cb) (struct evhttp_request *, void *);
420 	GTree *security_actions;
421 } ServerConfig_T;
422 
423 
424 
425 /**********************************************************************
426  *                               IMAP
427  *********************************************************************/
428 
429 /* maximum size of a mailbox name */
430 #define IMAP_MAX_MAILBOX_NAMELEN 255
431 
432 /* length of internaldate string
433  * DD-MMM-YYYY hh:mm:ss +HHMM
434  * 12345678901234567890123456 */
435 #define IMAP_INTERNALDATE_LEN 27
436 
437 /* length of database date string
438    YYYY-MM-DD HH:MM:SS
439    1234567890123456789 */
440 #define SQL_INTERNALDATE_LEN 32
441 
442 /* max length of number/dots part specifier */
443 #define IMAP_MAX_PARTSPEC_LEN 100
444 
445 /*
446  * search data types
447  */
448 
449 enum IMAP_SEARCH_TYPES {
450 	IST_SET = 1,
451 	IST_UIDSET,
452 	IST_FLAG,
453 	IST_KEYWORD,
454 	IST_UNKEYWORD,
455 	IST_SORT,
456 	IST_HDR,
457 	IST_HDRDATE_BEFORE,
458 	IST_HDRDATE_ON,
459 	IST_HDRDATE_SINCE,
460 	IST_IDATE,
461 	IST_DATA_BODY,
462 	IST_DATA_TEXT,
463 	IST_SIZE_LARGER,
464 	IST_SIZE_SMALLER,
465 	IST_SUBSEARCH_AND,
466 	IST_SUBSEARCH_OR,
467 	IST_SUBSEARCH_NOT
468 };
469 
470 typedef enum {
471 	SEARCH_UNORDERED = 0,
472 	SEARCH_SORTED,
473 	SEARCH_THREAD_ORDEREDSUBJECT,
474 	SEARCH_THREAD_REFERENCES
475 } search_order;
476 
477 typedef struct {
478 	int type;
479 	uint64_t size;
480 	char table[MAX_SEARCH_LEN];
481 	char order[MAX_SEARCH_LEN];
482 	char field[MAX_SEARCH_LEN];
483 	char op[MAX_SEARCH_LEN];
484 	char search[MAX_SEARCH_LEN];
485 	char hdrfld[MIME_FIELD_MAX];
486 //	int match;
487 	GTree *found;
488 	gboolean reverse;
489 	gboolean searched;
490 	gboolean merged;
491 } search_key;
492 
493 
494 
495 typedef struct {
496 	int itemtype;		/* the item to be fetched */
497 	int argstart;		/* start index in the arg array */
498 	int argcnt;		/* number of args belonging to this bodyfetch */
499 	guint64 octetstart, octetcnt;	/* number of octets to be retrieved */
500 
501 	char partspec[IMAP_MAX_PARTSPEC_LEN];	/* part specifier (i.e. '2.1.3' */
502 
503 	gchar *hdrnames;
504 	gchar *hdrplist;
505 	GTree *headers;
506 	GList *names;
507 } body_fetch;
508 
509 
510 typedef struct {
511 	gboolean noseen;		/* set the seen flag ? */
512 	gboolean msgparse_needed;
513 	gboolean hdrparse_needed;
514 
515 	/* helpers */
516 	gboolean setseen;
517 	gboolean isfirstfetchout;
518 
519 	/* fetch elements */
520 	gboolean getUID;
521 	gboolean getSize;
522 	gboolean getFlags;
523 	gboolean getInternalDate;
524 	gboolean getEnvelope;
525 	gboolean getMIME_IMB;
526 	gboolean getMIME_IMB_noextension;
527 	gboolean getRFC822Header;
528 	gboolean getRFC822Text;
529 	gboolean getRFC822Peek;
530 	gboolean getRFC822;
531 	gboolean getBodyTotal;
532 	gboolean getBodyTotalPeek;
533 
534 	/* condstore */
535 	uint64_t changedsince;
536 	/* qresync */
537 	gboolean vanished;
538 
539 	List_T   bodyfetch;
540 } fetch_items;
541 
542 typedef struct {
543 	uint64_t uidvalidity;
544 	uint64_t modseq;
545 	String_T known_uids;
546 	String_T known_seqset;
547 	String_T known_uidset;
548 } qresync_args;
549 
550 
551 /************************************************************************
552  *                      simple cache mechanism
553  ***********************************************************************/
554 
555 /*
556  * cached message info
557  */
558 #define IMAP_NFLAGS 6
559 typedef struct { // map dbmail_messages
560 	uint64_t mailbox_id;
561 	uint64_t msn;
562 	uint64_t uid;
563 	uint64_t rfcsize;
564 	uint64_t seq;
565 	// physmessage_id
566 	uint64_t phys_id;
567         // expunge flag
568         int expunge;
569         // expunged (pushed to client), can be removed
570         int expunged;
571 	int status;
572 	char internaldate[IMAP_INTERNALDATE_LEN];
573 	int flags[IMAP_NFLAGS];
574 	// reference dbmail_keywords
575 	GList *keywords;
576 } MessageInfo;
577 
578 
579 /*************************************************************************
580 *                                 SIEVE
581 *************************************************************************/
582 
583 /*
584  * A struct to hold info about a Sieve script
585  */
586 typedef struct {
587 	char name[512];
588 	int active;
589 } sievescript_info;
590 /*
591  * A struct to say which Sieve allocations
592  * will need an associated free.
593  */
594 typedef struct {
595 	int free_interp  : 1; // t
596 	int free_script  : 1; // s
597 	int free_support : 1; // p
598 	int free_error   : 1; // e
599 	int free_message : 1; // m
600 	int free_action  : 1; // a
601 } sievefree;
602 
603 
604 #define SA_KEEP		1
605 #define SA_DISCARD	2
606 #define SA_REDIRECT	3
607 #define SA_REJECT	4
608 #define SA_FILEINTO	5
609 
610 typedef struct sort_action {
611 	int method;
612 	char *destination;
613 	char *message;
614 } sort_action;
615 
616 typedef enum {
617 	ACL_RIGHT_LOOKUP, // l
618 	ACL_RIGHT_READ, // r
619 	ACL_RIGHT_SEEN, // s
620 	ACL_RIGHT_WRITE, // w
621 	ACL_RIGHT_INSERT, // i
622 	ACL_RIGHT_POST, // p
623 	ACL_RIGHT_CREATE, // k - also set with c
624 	ACL_RIGHT_DELETE, // x - also set with d
625 	ACL_RIGHT_DELETED, // t - also set with d
626 	ACL_RIGHT_EXPUNGE, // e - also set with d
627 	ACL_RIGHT_ADMINISTER, // a
628 	ACL_RIGHT_NONE
629 } ACLRight;
630 
631 struct  ACLMap {
632 	int lookup_flag;
633 	int read_flag;
634 	int seen_flag;
635 	int write_flag;
636 	int insert_flag;
637 	int post_flag;
638 	int create_flag;
639 	int delete_flag;
640 	int deleted_flag;
641 	int expunge_flag;
642 	int administer_flag;
643 };
644 
645 
646 /* Depending upon where the mailbox spec comes from,
647  * we may or may not create it on the fly and auto-subscribe
648  * to it. Some of these will resolve to the same action;
649  * see db_find_create_mailbox in db.c to find which.
650  */
651 typedef enum {
652 	BOX_NONE,        /* No mailbox yet. */
653 	BOX_UNKNOWN,     /* Not gonna create. */
654 	BOX_ADDRESSPART, /* Not gonna create. */
655 	BOX_BRUTEFORCE,  /* Autocreate, no perms checks and skip Sieve scripts. */
656 	BOX_COMMANDLINE, /* Autocreate. */
657 	BOX_SORTING,     /* Autocreate. */
658 	BOX_DEFAULT,     /* Autocreate. */
659 	BOX_IMAP         /* Autocreate, no subscribe */
660 } mailbox_source;
661 
662 typedef enum {
663 	SQL_TO_DATE,
664 	SQL_TO_DATETIME,
665 	SQL_TO_UNIXEPOCH,
666 	SQL_TO_CHAR,
667 	SQL_CURRENT_TIMESTAMP,
668 	SQL_EXPIRE,
669 	SQL_WITHIN,
670 	SQL_BINARY,
671 	SQL_SENSITIVE_LIKE,
672 	SQL_INSENSITIVE_LIKE,
673 	SQL_ENCODE_ESCAPE,
674 	SQL_STRCASE,
675 	SQL_PARTIAL,
676 	SQL_IGNORE,
677 	SQL_RETURNING,
678 	SQL_TABLE_EXISTS,
679 	SQL_ESCAPE_COLUMN,
680 	SQL_COMPARE_BLOB
681 } sql_fragment;
682 #endif
683