1 /* 2 ** 3 ** Copyright (c) 2010-2017 The SquirrelMail Project Team 4 ** Copyright (c) 2002-2010 Dave McMurtrie 5 ** 6 ** Licensed under the GNU GPL. For full terms see the file COPYING. 7 ** 8 ** This file is part of SquirrelMail IMAP Proxy. 9 ** 10 ** Facility: 11 ** 12 ** imapproxy.h 13 ** 14 ** Abstract: 15 ** 16 ** Common definitions and function prototypes for the IMAP proxy server. 17 ** 18 ** Authors: 19 ** 20 ** Dave McMurtrie <davemcmurtrie@hotmail.com> 21 ** 22 ** Version: 23 ** 24 ** $Id: imapproxy.h 14647 2017-01-27 20:53:57Z pdontthink $ 25 ** 26 ** Modification History: 27 ** 28 ** $Log$ 29 ** 30 ** Revision 1.30 2009/10/16 14:35:17 dave64 31 ** Applied patch by Jose Luis Tallon to improve server connect retry logic. 32 ** 33 ** Revision 1.29 2009/10/16 14:29:21 dave64 34 ** Applied patch by Jose Luis Tallon to allow for default config options. 35 ** 36 ** Revision 1.28 2008/10/20 13:22:19 dave64 37 ** Applied patch by Michael M. Slusarz to support XPROXYREUSE. 38 ** 39 ** Revision 1.27 2007/11/15 11:11:46 dave64 40 ** Added pidfile support patch by Jose Luis Tallón. 41 ** 42 ** Revision 1.26 2007/05/31 12:07:41 dave64 43 ** Applied ipv6 patch by Antonio Querubin. 44 ** 45 ** Revision 1.25 2007/05/31 11:46:00 dave64 46 ** Applied OpenSSL threads patch by Jan Grant. 47 ** 48 ** Revision 1.24 2005/07/06 11:51:25 dgm 49 ** Added enable_admin_commands to struct ProxyConfig 50 ** 51 ** Revision 1.23 2005/06/15 12:13:40 dgm 52 ** Changed all long int values to int. Changed logouttime in 53 ** IMAPConnectionContext to time_t. Added atoui function 54 ** prototype. Patch by Dave Steinberg and Jarno Huuskonen to 55 ** allow chroot. 56 ** 57 ** Revision 1.22 2005/01/12 17:51:19 dgm 58 ** Applied patch by David Lancaster to provide force_tls 59 ** config option. 60 ** 61 ** Revision 1.21 2005/01/12 16:50:59 dgm 62 ** cache_size and cache_expiration_time in struct ProxyConfig now 63 ** declared as unsigned int instead of unsigned long. 64 ** 65 ** Revision 1.20 2004/11/10 15:35:13 dgm 66 ** Changed LiteralBytesRemaining from signed long to unsigned long. 67 ** 68 ** Revision 1.19 2004/10/11 18:00:42 dgm 69 ** Added foreground_mode configuration option. 70 ** 71 ** Revision 1.18 2004/03/11 15:17:58 dgm 72 ** SELECT_BUF_SIZE size changed from 1024 to BUFSIZE which is 73 ** currently 4096 74 ** 75 ** Revision 1.17 2004/02/24 15:21:01 dgm 76 ** Added support for SELECT caching. 77 ** 78 ** Revision 1.16 2003/11/14 15:06:14 dgm 79 ** Patch by Geoffrey Hort <g.hort@unsw.edu.au> to include listen_address 80 ** config option. Also, I changed the default buffer size from 81 ** 1024 to 4096. 82 ** 83 ** Revision 1.15 2003/10/09 15:05:01 dgm 84 ** Added tcp keepalive support. 85 ** 86 ** Revision 1.14 2003/07/14 16:41:18 dgm 87 ** Applied patch by William Yodlowsky <wyodlows@andromeda.rutgers.edu> to 88 ** allow TLS to work on machines without /dev/random. 89 ** 90 ** Revision 1.13 2003/05/20 19:18:00 dgm 91 ** Comment changes only. 92 ** 93 ** Revision 1.12 2003/05/15 12:30:39 dgm 94 ** include netinet/in.h 95 ** 96 ** Revision 1.11 2003/05/13 11:38:53 dgm 97 ** Patches by Ken Murchison <ken@oceana.com> to clean up build process. 98 ** 99 ** Revision 1.10 2003/05/06 12:09:12 dgm 100 ** Applied patches by Ken Murchison <ken@oceana.com> to add SSL 101 ** support and remove old base64 functions. 102 ** 103 ** Revision 1.9 2003/04/16 12:19:29 dgm 104 ** Added support for syslog configuration. 105 ** Added base64 routine prototypes that I previously forgot. 106 ** 107 ** Revision 1.8 2003/03/19 13:24:50 dgm 108 ** Applied patch by Devrim Seral <devrim@gazi.edu.tr> to allow 109 ** the default configfile to be configurable via a configure script. 110 ** (Lots of configures in that sentence, huh?) 111 ** 112 ** Revision 1.7 2003/02/20 12:40:08 dgm 113 ** Added UNSELECT support. 114 ** 115 ** Revision 1.6 2003/02/19 13:03:35 dgm 116 ** Added LITERAL_PASSWORD and NON_LITERAL_PASSWORD definitions. 117 ** 118 ** Revision 1.5 2003/01/22 15:33:53 dgm 119 ** Changed Get_Server_sd() function prototype to reflect the addition of 120 ** the literal password flag. 121 ** 122 ** Revision 1.4 2002/12/19 21:41:32 dgm 123 ** Added support for global configuration. 124 ** 125 ** Revision 1.3 2002/08/30 13:21:42 dgm 126 ** Added total client logins counter to IMAPCounter struct 127 ** 128 ** Revision 1.2 2002/08/29 16:33:46 dgm 129 ** Added CountTime field to struct IMAPCounter. 130 ** Removed #define for max number of open file descriptors since 131 ** we now determine rlimit dynamically instead. 132 ** Added POLL_TIMEOUT stuff. 133 ** 134 ** Revision 1.1 2002/07/03 11:21:12 dgm 135 ** Initial revision 136 ** 137 */ 138 139 140 #ifndef __IMAPPROXY_H 141 #define __IMAPPROXY_H 142 143 #include <netdb.h> 144 #include <pthread.h> 145 #include <netinet/in.h> 146 #include <time.h> 147 #include "config.h" 148 149 #if HAVE_LIBSSL 150 #include <openssl/ssl.h> 151 #include <openssl/md5.h> 152 #include <openssl/rand.h> 153 #include <limits.h> 154 #endif 155 156 #ifndef PR_SET_NO_NEW_PRIVS 157 #define PR_SET_NO_NEW_PRIVS 38 158 #endif 159 160 161 /* 162 * Common definitions 163 */ 164 #define PGM "in.imapproxyd" 165 #define IMAP_UNTAGGED_OK "* OK " /* untagged OK response */ 166 #define IMAP_TAGGED_OK "1 OK " /* tagged OK response */ 167 #define BUFSIZE 8192 /* default buffer size */ 168 #define MAX_CONN_BACKLOG 5 /* tcp connection backlog */ 169 #define MAXTAGLEN 256 /* max IMAP tag length */ 170 #define MAXMAILBOXNAME 512 /* max mailbox name length */ 171 #define MAXUSERNAMELEN 256 /* max username length */ 172 #define MAXPASSWDLEN 8192 /* max passwd length */ 173 #define POLL_TIMEOUT_MINUTES 30 /* Poll timeout in minutes */ 174 #define POLL_TIMEOUT (POLL_TIMEOUT_MINUTES * 60000) 175 #define SELECT_BUF_SIZE BUFSIZE /* max length of a SELECT */ 176 /* string we can cache */ 177 #define SELECT_CACHE_EXP 10 /* # of seconds before we */ 178 /* expire a SELECT cache */ 179 #define SELECT_STATUS_BUF_SIZE 256 /* size of select status */ 180 181 #ifndef DEFAULT_CONFIG_FILE 182 #define DEFAULT_CONFIG_FILE "/etc/imapproxy.conf" 183 #endif 184 #ifndef DEFAULT_PID_FILE 185 #define DEFAULT_PID_FILE "/var/run/imapproxy.pid" 186 #endif 187 188 #define LITERAL_PASSWORD 1 189 #define NON_LITERAL_PASSWORD 0 190 #define UNSELECT_SUPPORTED 1 191 #define UNSELECT_NOT_SUPPORTED 0 192 #define STARTTLS_SUPPORTED 1 193 #define STARTTLS_NOT_SUPPORTED 0 194 #define LOGIN_DISABLED 1 195 #define LOGIN_NOT_DISABLED 0 196 197 198 #define DEFAULT_SERVER_CONNECT_RETRIES 10 199 #define DEFAULT_SERVER_CONNECT_DELAY 5 200 201 /* 202 * One IMAPServerDescriptor will be globally allocated such that each thread 203 * can save the time of doing host lookups, service lookups, and filling 204 * in the sockaddr_storage struct. 205 */ 206 struct IMAPServerDescriptor 207 { 208 struct addrinfo *airesults; /* IMAP server info (top of addrinfo 209 list from getaddrinfo() */ 210 struct addrinfo *srv; /* IMAP server active socket info */ 211 }; 212 213 214 /* 215 * IMAPSelectCaches provide for caching of SELECT output from an IMAP server 216 */ 217 struct IMAPSelectCache 218 { 219 time_t ISCTime; 220 char MailboxName[ MAXMAILBOXNAME ]; 221 char SelectString[ SELECT_BUF_SIZE ]; 222 char SelectStatus[ SELECT_STATUS_BUF_SIZE ]; 223 }; 224 225 226 /* 227 * IMAPConnectionDescriptors contain the info needed to communicate on an 228 * IMAP connection. 229 */ 230 struct IMAPConnectionDescriptor 231 { 232 int sd; /* socket descriptor */ 233 #if HAVE_LIBSSL 234 SSL *tls; /* TLS connection context */ 235 #endif 236 struct IMAPSelectCache ISC; /* Cached SELECT data */ 237 struct IMAPConnectionContext *ICC; /* backreference the ICC */ 238 unsigned int reused; /* Was the connection reused? */ 239 }; 240 241 242 /* 243 * IMAPTransactionDescriptors facilitate multi-line buffered reads from 244 * IMAP servers and clients. 245 */ 246 struct IMAPTransactionDescriptor 247 { 248 struct IMAPConnectionDescriptor *conn; 249 char ReadBuf[ BUFSIZE ]; /* Read Buffer */ 250 unsigned int BytesInReadBuffer; /* bytes left in read buffer */ 251 unsigned int ReadBytesProcessed; /* bytes already processed in read buf */ 252 unsigned int LiteralBytesRemaining; /* num of bytes left as literal */ 253 unsigned char NonSyncLiteral; /* rfc2088 alert flag */ 254 unsigned char MoreData; /* flag to tell caller "more data" */ 255 unsigned char TraceOn; /* trace this transaction? */ 256 }; 257 258 259 /* 260 * IMAPConnectionContext structures are used to cache connection info on 261 * a per-user basis. 262 */ 263 struct IMAPConnectionContext 264 { 265 struct IMAPConnectionDescriptor *server_conn; 266 char username[MAXUSERNAMELEN]; /* username connected on this sd */ 267 char hashedpw[16]; /* md5 hash copy of password */ 268 time_t logouttime; /* time the user logged out last */ 269 struct IMAPConnectionContext *next; /* linked list next pointer */ 270 }; 271 272 273 /* 274 * One ProxyConfig structure will be used globally to keep track of 275 * configurable options. All of these options are set by reading values 276 * from the global config file except for support_unselect. That's set 277 * based on the CAPABILITY string from the real IMAP server. 278 */ 279 struct ProxyConfig 280 { 281 char *listen_port; /* port we bind to */ 282 char *listen_addr; /* address we bind to */ 283 char *server_hostname; /* server we proxy to */ 284 char *server_port; /* port we proxy to */ 285 unsigned int server_connect_retries; /* connect retries to IMAP server */ 286 unsigned int server_connect_delay; /* delay between connection retry rounds */ 287 unsigned int cache_size; /* number of cache slots */ 288 unsigned int cache_expiration_time; /* cache exp time in seconds */ 289 unsigned int send_tcp_keepalives; /* flag to send keepalives */ 290 unsigned int enable_select_cache; /* flag to enable select cache */ 291 unsigned int foreground_mode; /* flag to enable fg mode */ 292 char *proc_username; /* username to run as */ 293 char *proc_groupname; /* groupname to run as */ 294 char *stat_filename; /* mmap()ed stat filename */ 295 char *protocol_log_filename; /* global trace filename */ 296 char *syslog_facility; /* syslog log facility */ 297 char *syslog_prioritymask; /* syslog priority mask */ 298 char *tls_ca_file; /* file with CA certs */ 299 char *tls_ca_path; /* path to directory CA certs */ 300 char *tls_cert_file; /* file with client cert */ 301 char *tls_key_file; /* file with client priv key */ 302 char *tls_ciphers; /* TLS Cipher suite */ 303 unsigned int tls_verify_server; /* flag to require server cert validation */ 304 unsigned int tls_no_tlsv1; /* flag to disable TLSv1 */ 305 unsigned int tls_no_tlsv1_1; /* flag to disable TLSv1.1 */ 306 unsigned int tls_no_tlsv1_2; /* flag to disable TLSv1.2 */ 307 unsigned int force_tls; /* flag to force TLS */ 308 unsigned int enable_admin_commands; /* flag to enable admin cmds */ 309 unsigned char support_unselect; /* unselect support flag */ 310 unsigned char support_starttls; /* starttls support flag */ 311 unsigned char login_disabled; /* login disabled flag */ 312 char *chroot_directory; /* chroot(2) into this dir */ 313 char *preauth_command; /* arbitrary pre-authentication command */ 314 char *auth_sasl_plain_username; /* authentication username under SASL PLAIN */ 315 char *auth_sasl_plain_password; /* authentication password under SASL PLAIN */ 316 char *auth_shared_secret; /* REQUIRED shared secret in leiu of a user password when using LOGIN command with SASL PLAIN authentication */ 317 unsigned int ipversion; /* limit DNS requests to AF_INET or AF_INET6 */ 318 unsigned int dnsrr; /* cycle through all DNS entries we got */ 319 }; 320 321 322 /* 323 * One IMAPCounter structure will be used globally to keep track of 324 * several different things that we want to keep a count of, purely for 325 * diagnostic, or usage tracking purposes. 326 * 327 * IMPORTANT NOTE: No attempt is made to guarantee that these counters 328 * will be completely accurate. No mutex is ever taken out when these 329 * counters are updated. This was done for performance -- these numbers 330 * aren't considered important enough to waste time locking a mutex to 331 * guarantee their accuracy. 332 */ 333 struct IMAPCounter 334 { 335 time_t StartTime; 336 time_t CountTime; 337 unsigned int CurrentClientConnections; 338 unsigned int PeakClientConnections; 339 unsigned int InUseServerConnections; 340 unsigned int PeakInUseServerConnections; 341 unsigned int RetainedServerConnections; 342 unsigned int PeakRetainedServerConnections; 343 unsigned int TotalClientConnectionsAccepted; 344 unsigned int TotalClientLogins; 345 unsigned int TotalServerConnectionsCreated; 346 unsigned int TotalServerConnectionsReused; 347 unsigned int TotalSelectCommands; 348 unsigned int SelectCacheHits; 349 unsigned int SelectCacheMisses; 350 }; 351 352 353 354 typedef struct IMAPServerDescriptor ISD_Struct; 355 typedef struct IMAPTransactionDescriptor ITD_Struct; 356 typedef struct IMAPConnectionDescriptor ICD_Struct; 357 typedef struct IMAPConnectionContext ICC_Struct; 358 typedef struct IMAPCounter IMAPCounter_Struct; 359 typedef struct ProxyConfig ProxyConfig_Struct; 360 typedef struct IMAPSelectCache ISC_Struct; 361 362 /* 363 * Function prototypes for external entry points. 364 */ 365 extern int IMAP_Write( ICD_Struct *, const void *, int ); 366 extern int IMAP_Read( ICD_Struct *, void *, int ); 367 extern int IMAP_Line_Read( ITD_Struct * ); 368 extern int IMAP_Literal_Read( ITD_Struct * ); 369 extern void HandleRequest( int ); 370 extern char *memtok( char *, char *, char ** ); 371 extern int imparse_isatom( const char * ); 372 extern ICD_Struct *Get_Server_conn( char *, char *, const char *, const char *, unsigned char, char *, char * ); 373 extern void ICC_Logout( ICC_Struct * ); 374 extern void ICC_Recycle( unsigned int ); 375 extern void ICC_Recycle_Loop( void ); 376 extern void LockMutex( pthread_mutex_t * ); 377 extern void UnLockMutex( pthread_mutex_t * ); 378 extern void SetDefaultConfigValues(ProxyConfig_Struct *); 379 extern void SetConfigOptions( char * ); 380 extern void SetLogOptions( void ); 381 extern int Handle_Select_Command( ITD_Struct *, ITD_Struct *, ISC_Struct *, char *, int ); 382 extern unsigned int Is_Safe_Command( char *Command ); 383 extern void Invalidate_Cache_Entry( ISC_Struct * ); 384 extern int atoui( const char *, unsigned int * ); 385 386 387 #ifndef MD5_DIGEST_LENGTH 388 #define MD5_DIGEST_LENGTH 16 /* When would it ever be different? */ 389 #endif 390 extern void ssl_thread_setup(const char * fn); 391 392 393 #endif /* __IMAPPROXY_H */ 394 395