1 /* GNU Mailutils -- a suite of utilities for electronic mail 2 Copyright (C) 1999-2021 Free Software Foundation, Inc. 3 4 GNU Mailutils is free software; you can redistribute it and/or modify 5 it under the terms of the GNU General Public License as published by 6 the Free Software Foundation; either version 3, or (at your option) 7 any later version. 8 9 GNU Mailutils is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 GNU General Public License for more details. 13 14 You should have received a copy of the GNU General Public License 15 along with GNU Mailutils. If not, see <http://www.gnu.org/licenses/>. */ 16 17 #ifndef _IMAP4D_H 18 #define _IMAP4D_H 1 19 20 #ifdef HAVE_CONFIG_H 21 #include <config.h> 22 #endif 23 24 #define _QNX_SOURCE 25 26 #include <sys/types.h> 27 #ifdef HAVE_SECURITY_PAM_APPL_H 28 # include <security/pam_appl.h> 29 #endif 30 31 #ifdef HAVE_SHADOW_H 32 #include <shadow.h> 33 #endif 34 35 #include <errno.h> 36 #include <limits.h> 37 #include <stdio.h> 38 #include <stdlib.h> 39 #include <unistd.h> 40 #include <string.h> 41 #include <setjmp.h> 42 #include <sys/wait.h> 43 #include <sys/types.h> 44 #include <syslog.h> 45 #include <pwd.h> 46 #include <grp.h> 47 #include <stdarg.h> 48 #include <sys/time.h> 49 #include <sys/stat.h> 50 #include <dirent.h> 51 #include <fcntl.h> 52 #include <signal.h> 53 #include <sys/socket.h> 54 #include <netinet/in.h> 55 #include <arpa/inet.h> 56 #include <netdb.h> 57 58 #ifdef HAVE_ALLOCA_H 59 # include <alloca.h> 60 #endif 61 62 #ifdef HAVE_STRINGS_H 63 # include <strings.h> 64 #endif 65 66 #ifdef HAVE_PATHS_H 67 # include <paths.h> 68 #endif 69 #include <sysexits.h> 70 71 #include <mailutils/address.h> 72 #include <mailutils/attribute.h> 73 #include <mailutils/body.h> 74 #include <mailutils/daemon.h> 75 #include <mailutils/envelope.h> 76 #include <mailutils/errno.h> 77 #include <mailutils/error.h> 78 #include <mailutils/filter.h> 79 #include <mailutils/folder.h> 80 #include <mailutils/header.h> 81 #include <mailutils/iterator.h> 82 #include <mailutils/list.h> 83 #include <mailutils/mailbox.h> 84 #include <mailutils/message.h> 85 #include <mailutils/mime.h> 86 #include <mailutils/util.h> 87 #include <mailutils/mu_auth.h> 88 #include <mailutils/nls.h> 89 #include <mailutils/parse822.h> 90 #include <mailutils/registrar.h> 91 #include <mailutils/stream.h> 92 #include <mailutils/stdstream.h> 93 #include <mailutils/tls.h> 94 #include <mailutils/url.h> 95 #include <mailutils/daemon.h> 96 #include <mailutils/pam.h> 97 #include <mailutils/acl.h> 98 #include <mailutils/server.h> 99 #include <mailutils/wordsplit.h> 100 #include <mailutils/alloc.h> 101 #include <mailutils/cctype.h> 102 #include <mailutils/cstr.h> 103 #include <mailutils/io.h> 104 #include <mailutils/prog.h> 105 #include <mailutils/imapio.h> 106 #include <mailutils/imaputil.h> 107 #include <mailutils/msgset.h> 108 #include <mailutils/syslog.h> 109 110 #include <mu_umaxtostr.h> 111 #include <muaux.h> 112 113 #ifdef __cplusplus 114 extern "C" { 115 #endif 116 117 typedef struct imap4d_tokbuf *imap4d_tokbuf_t; 118 119 struct imap4d_session; 120 121 struct imap4d_command 122 { 123 const char *name; 124 int (*func) (struct imap4d_session *, struct imap4d_command *, 125 imap4d_tokbuf_t); 126 int states; 127 int failure; 128 int success; 129 char *tag; 130 }; 131 132 /* Global variables and constants*/ 133 #define STATE_NONE (0) 134 #define STATE_NONAUTH (1 << 0) 135 #define STATE_AUTH (1 << 1) 136 #define STATE_SEL (1 << 2) 137 #define STATE_LOGOUT (1 << 3) 138 139 #define STATE_ALL (STATE_NONE | STATE_NONAUTH | STATE_AUTH | STATE_SEL \ 140 | STATE_LOGOUT) 141 142 /* Response code. */ 143 #define RESP_OK 0 144 #define RESP_BAD 1 145 #define RESP_NO 2 146 #define RESP_BYE 3 147 #define RESP_NONE 4 148 #define RESP_PREAUTH 5 149 150 /* Error values. */ 151 #define OK 0 152 #define ERR_NO_MEM 1 153 #define ERR_NO_OFILE 2 154 #define ERR_NO_IFILE 3 155 #define ERR_TIMEOUT 4 156 #define ERR_SIGNAL 5 157 #define ERR_TLS 6 158 #define ERR_MAILBOX_CORRUPTED 7 159 #define ERR_TERMINATE 8 160 #define ERR_STREAM_CREATE 9 161 162 /* Namespace numbers */ 163 #define NS_PERSONAL 0 164 #define NS_OTHER 1 165 #define NS_SHARED 2 166 #define NS_MAX 3 167 168 /* IMAP4D capability names */ 169 #define IMAP_CAPA_STARTTLS "STARTTLS" 170 #define IMAP_CAPA_LOGINDISABLED "LOGINDISABLED" 171 #define IMAP_CAPA_XTLSREQUIRED "XTLSREQUIRED" 172 173 /* Preauth types */ 174 enum imap4d_preauth 175 { 176 preauth_none, 177 preauth_stdio, 178 preauth_ident, 179 preauth_prog 180 }; 181 182 /* TLS modes */ 183 enum tls_mode 184 { 185 tls_unspecified, 186 tls_no, 187 tls_ondemand, 188 tls_required, 189 tls_connection 190 }; 191 192 struct imap4d_session 193 { 194 enum tls_mode tls_mode; 195 struct mu_tls_config *tls_conf; 196 }; 197 198 struct imap4d_srv_config 199 { 200 struct mu_srv_config m_cfg; 201 enum tls_mode tls_mode; 202 struct mu_tls_config tls_conf; 203 }; 204 205 extern struct imap4d_command imap4d_command_table[]; 206 extern mu_mailbox_t mbox; 207 extern char *real_homedir; 208 extern int state; 209 extern size_t children; 210 extern int is_virtual; 211 extern struct mu_auth_data *auth_data; 212 extern const char *program_version; 213 214 extern int login_disabled; 215 extern enum imap4d_preauth preauth_mode; 216 extern char *preauth_program; 217 extern int preauth_only; 218 extern int ident_port; 219 extern char *ident_keyfile; 220 extern int ident_encrypt_only; 221 extern unsigned int idle_timeout; 222 extern int imap4d_transcript; 223 extern mu_list_t imap4d_id_list; 224 extern int imap4d_argc; 225 extern char **imap4d_argv; 226 extern jmp_buf child_jmp; 227 extern struct mu_tls_config global_tls_conf; 228 extern int global_tls_mode; 229 230 extern int test_mode; 231 extern int silent_expunge; 232 233 /* Input functions */ 234 extern mu_stream_t iostream; 235 extern int io_untagged_response (int, const char *, ...) MU_PRINTFLIKE(2,3); 236 extern int io_sendf (const char *, ...) MU_PRINTFLIKE(1,2); 237 extern int io_send_bytes (const char *buf, size_t size); 238 extern int io_send_qstring (const char *); 239 extern int io_send_astring (const char *); 240 extern int io_send_literal (const char *); 241 extern int io_copy_out (mu_stream_t str, size_t size); 242 extern int io_completion_response (struct imap4d_command *, int, 243 const char *, ...) MU_PRINTFLIKE(3,4); 244 extern int io_stream_completion_response (mu_stream_t str, 245 struct imap4d_command *command, 246 int rc, 247 const char *format, ...) 248 MU_PRINTFLIKE(4,5); 249 void io_getline (char **pbuf, size_t *psize, size_t *pnbytes); 250 void io_setio (int, int, struct mu_tls_config *); 251 void io_flush (void); 252 int io_wait_input (int); 253 void io_enable_crlf (int); 254 255 imap4d_tokbuf_t imap4d_tokbuf_init (void); 256 void imap4d_tokbuf_destroy (imap4d_tokbuf_t *tok); 257 int imap4d_tokbuf_argc (imap4d_tokbuf_t tok); 258 char *imap4d_tokbuf_getarg (imap4d_tokbuf_t tok, int n); 259 void imap4d_readline (imap4d_tokbuf_t tok); 260 imap4d_tokbuf_t imap4d_tokbuf_from_string (char *str); 261 262 263 #define IMAP4_ARG_TAG 0 264 #define IMAP4_ARG_COMMAND 1 265 #define IMAP4_ARG_1 2 266 #define IMAP4_ARG_2 3 267 #define IMAP4_ARG_3 4 268 #define IMAP4_ARG_4 5 269 270 /* Specialized buffer parsing */ 271 struct imap4d_parsebuf 272 { 273 imap4d_tokbuf_t tok; 274 int arg; /* Argument number in tok */ 275 char *tokptr; /* Current token */ 276 size_t tokoff; /* Offset of next delimiter in tokptr */ 277 int save_char; /* Character saved from tokptr[tokoff] */ 278 char *token; /* Pointer to the current token */ 279 const char *delim; /* Array of delimiters */ 280 char *peek_ptr; /* Peeked token */ 281 jmp_buf errjmp; 282 char *err_text; 283 void *data; 284 }; 285 286 typedef struct imap4d_parsebuf *imap4d_parsebuf_t; 287 288 void imap4d_parsebuf_exit (imap4d_parsebuf_t pb, char *text); 289 char *imap4d_parsebuf_peek (imap4d_parsebuf_t pb); 290 char *imap4d_parsebuf_next (imap4d_parsebuf_t pb, int req); 291 int imap4d_with_parsebuf (imap4d_tokbuf_t tok, int arg, 292 const char *delim, 293 int (*thunk) (imap4d_parsebuf_t), void *data, 294 char **err_text); 295 #define imap4d_parsebuf_token(p) ((p)->token) 296 #define imap4d_parsebuf_data(p) ((p)->data) 297 298 /* Imap4 commands */ 299 extern int imap4d_append (struct imap4d_session *, 300 struct imap4d_command *, imap4d_tokbuf_t); 301 extern int imap4d_authenticate (struct imap4d_session *, 302 struct imap4d_command *, imap4d_tokbuf_t); 303 extern void imap4d_auth_capability (struct imap4d_session *); 304 extern int imap4d_capability (struct imap4d_session *, 305 struct imap4d_command *, imap4d_tokbuf_t); 306 extern int imap4d_check (struct imap4d_session *, 307 struct imap4d_command *, imap4d_tokbuf_t); 308 extern int imap4d_close (struct imap4d_session *, 309 struct imap4d_command *, imap4d_tokbuf_t); 310 extern int imap4d_unselect (struct imap4d_session *, 311 struct imap4d_command *, imap4d_tokbuf_t); 312 extern int imap4d_copy (struct imap4d_session *, 313 struct imap4d_command *, imap4d_tokbuf_t); 314 extern int imap4d_copy0 (imap4d_tokbuf_t, int isuid, char **err_text); 315 extern int imap4d_create (struct imap4d_session *, 316 struct imap4d_command *, imap4d_tokbuf_t); 317 extern int imap4d_delete (struct imap4d_session *, 318 struct imap4d_command *, imap4d_tokbuf_t); 319 extern int imap4d_examine (struct imap4d_session *, 320 struct imap4d_command *, imap4d_tokbuf_t); 321 extern int imap4d_expunge (struct imap4d_session *, 322 struct imap4d_command *, imap4d_tokbuf_t); 323 extern int imap4d_fetch (struct imap4d_session *, 324 struct imap4d_command *, imap4d_tokbuf_t); 325 extern int imap4d_fetch0 (imap4d_tokbuf_t tok, int isuid, char **err_text); 326 extern int imap4d_list (struct imap4d_session *, 327 struct imap4d_command *, imap4d_tokbuf_t); 328 extern int imap4d_login (struct imap4d_session *, 329 struct imap4d_command *, imap4d_tokbuf_t); 330 extern int imap4d_logout (struct imap4d_session *, 331 struct imap4d_command *, imap4d_tokbuf_t); 332 extern int imap4d_noop (struct imap4d_session *, 333 struct imap4d_command *, imap4d_tokbuf_t); 334 extern int imap4d_rename (struct imap4d_session *, 335 struct imap4d_command *, imap4d_tokbuf_t); 336 extern int imap4d_preauth_setup (int fd); 337 extern int imap4d_search (struct imap4d_session *, 338 struct imap4d_command *, imap4d_tokbuf_t); 339 extern int imap4d_search0 (imap4d_tokbuf_t, int isuid, char **repyptr); 340 extern int imap4d_select (struct imap4d_session *, 341 struct imap4d_command *, imap4d_tokbuf_t); 342 extern int imap4d_select0 (struct imap4d_command *, const char *, int); 343 extern int imap4d_select_status (void); 344 extern int imap4d_starttls (struct imap4d_session *, 345 struct imap4d_command *, imap4d_tokbuf_t); 346 int starttls_init (mu_m_server_t msrv); 347 int starttls_server_check (struct imap4d_srv_config *cfg, char const *srvid); 348 void tls_encryption_on (struct imap4d_session *); 349 extern int imap4d_status (struct imap4d_session *, 350 struct imap4d_command *, imap4d_tokbuf_t); 351 extern int imap4d_store (struct imap4d_session *, 352 struct imap4d_command *, imap4d_tokbuf_t); 353 extern int imap4d_store0 (imap4d_tokbuf_t, int, char **); 354 355 mu_property_t open_subscription (void); 356 extern int imap4d_subscribe (struct imap4d_session *, 357 struct imap4d_command *, imap4d_tokbuf_t); 358 extern int imap4d_unsubscribe (struct imap4d_session *, 359 struct imap4d_command *, imap4d_tokbuf_t); 360 extern int imap4d_lsub (struct imap4d_session *, 361 struct imap4d_command *, imap4d_tokbuf_t); 362 363 extern int imap4d_uid (struct imap4d_session *, 364 struct imap4d_command *, imap4d_tokbuf_t); 365 extern int imap4d_namespace (struct imap4d_session *, 366 struct imap4d_command *, imap4d_tokbuf_t); 367 extern int imap4d_version (struct imap4d_session *, 368 struct imap4d_command *, imap4d_tokbuf_t); 369 extern int imap4d_idle (struct imap4d_session *, 370 struct imap4d_command *, imap4d_tokbuf_t); 371 extern int imap4d_id (struct imap4d_session *, 372 struct imap4d_command *, imap4d_tokbuf_t); 373 374 extern int imap4d_check_home_dir (const char *dir, uid_t uid, gid_t gid); 375 376 /* Shared between fetch and store */ 377 extern void fetch_flags0 (const char *prefix, mu_message_t msg, int isuid); 378 379 /* Permissions for creating intermediate directories. 380 FIXME: These should better be configurable. */ 381 #define MKDIR_PERMISSIONS 0700 382 int make_interdir (const char *name, int delim, int perms); 383 384 /* Synchronisation on simultaneous access. */ 385 extern int imap4d_sync (void); 386 extern void imap4d_sync_invalidate (void); 387 extern int imap4d_sync_flags (size_t); 388 extern size_t uid_to_msgno (size_t); 389 extern void imap4d_set_observer (mu_mailbox_t mbox); 390 391 /* Signal handling. */ 392 extern RETSIGTYPE imap4d_master_signal (int); 393 extern RETSIGTYPE imap4d_child_signal (int); 394 extern int imap4d_bye (int); 395 extern int imap4d_bye_command (int, struct imap4d_command *); 396 void imap4d_enter_critical (void); 397 void imap4d_leave_critical (void); 398 399 /* Namespace functions */ 400 struct namespace_prefix 401 { 402 char *prefix; /* Prefix string */ 403 int delim; /* Delimiter character */ 404 char *dir; /* Directory in the file system */ 405 char *scheme; /* Mailbox URL scheme (type) */ 406 mu_record_t record; /* The corresponding record */ 407 int ns; /* Namespace */ 408 }; 409 410 struct namespace 411 { 412 char const *name; 413 int mode; /* File mode for creating new mailboxes */ 414 mu_list_t prefixes; /* List of prefixes (struct namespace_prefix */ 415 }; 416 417 void namespace_init (void); 418 struct namespace *namespace_lookup (char const *name); 419 420 char *namespace_translate_name (char const *name, 421 struct namespace_prefix const **pfx); 422 char *namespace_get_name (char const *name, mu_record_t *rec, int *mode); 423 424 char *namespace_decode_delim (struct namespace_prefix const *pfx, 425 char const *src); 426 char *namespace_encode_delim (struct namespace_prefix const *pfx, 427 char const *src); 428 void translate_delim (char *dst, char const *src, int dst_delim, int src_delim); 429 430 431 int imap4d_session_setup (char *username); 432 int imap4d_session_setup0 (void); 433 void imap4d_child_signal_setup (RETSIGTYPE (*handler) (int signo)); 434 435 /* Capability functions */ 436 extern void imap4d_capability_add (const char *str); 437 extern void imap4d_capability_remove (const char *str); 438 extern void imap4d_capability_init (void); 439 440 /* Helper functions. */ 441 442 extern int util_start (char *); 443 extern int util_getstate (void); 444 extern int util_do_command (struct imap4d_session *, imap4d_tokbuf_t); 445 extern struct imap4d_command *util_getcommand (char *, 446 struct imap4d_command []); 447 448 enum datetime_parse_mode /* how to parse date/time strings */ 449 { 450 datetime_default, /* default mode */ 451 datetime_date_only, /* return only date part, ignore time and TZ */ 452 datetime_time_only /* return only time and TZ, ignore date */ 453 }; 454 455 extern int util_parse_internal_date (char *date, time_t *timep, 456 enum datetime_parse_mode flag); 457 extern int util_parse_822_date (const char *date, time_t *timep, 458 enum datetime_parse_mode flag); 459 extern int util_parse_ctime_date (const char *date, time_t *timep, 460 enum datetime_parse_mode flag); 461 extern char *util_localname (void); 462 463 void util_print_flags (mu_attribute_t attr); 464 int util_attribute_matches_flag (mu_attribute_t attr, const char *item); 465 int util_uidvalidity (mu_mailbox_t smbox, unsigned long *uidvp); 466 467 468 void util_bye (void); 469 void util_chdir (const char *homedir); 470 int is_atom (const char *s); 471 int util_isdelim (const char *str); 472 int util_trim_nl (char *s, size_t len); 473 474 int set_xscript_level (int xlev); 475 void xscript_declare_client_payload (size_t len); 476 477 int imap4d_init_tls_server (struct mu_tls_config *); 478 479 struct imap4d_auth 480 { 481 /* input */ 482 struct imap4d_command *command; 483 char *auth_type; 484 /* output */ 485 char *username; 486 int response; 487 }; 488 489 enum imap4d_auth_result 490 { 491 imap4d_auth_nosup = 0, 492 imap4d_auth_ok = MU_ERR_USER0, 493 imap4d_auth_resp = MU_ERR_USER1, 494 imap4d_auth_fail = MU_ERR_USER2 495 }; 496 497 typedef enum imap4d_auth_result 498 (*imap4d_auth_handler_fp) (struct imap4d_auth *); 499 500 extern void auth_add (char *name, imap4d_auth_handler_fp handler); 501 extern void auth_remove (char *name); 502 503 #ifdef WITH_GSSAPI 504 extern void auth_gssapi_init (void); 505 #else 506 # define auth_gssapi_init() 507 #endif 508 509 #ifdef WITH_GSASL 510 extern void auth_gsasl_init (void); 511 #else 512 # define auth_gsasl_init() 513 #endif 514 515 /* Quota support */ 516 void quota_setup (void); 517 int quota_check (mu_off_t size); 518 void quota_update (mu_off_t size); 519 520 #ifdef __cplusplus 521 } 522 #endif 523 524 #endif /* _IMAP4D_H */ 525