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