smtpd.h revision 1.104
1/*	$OpenBSD: smtpd.h,v 1.104 2009/04/24 10:02:35 jacekm Exp $	*/
2
3/*
4 * Copyright (c) 2008 Gilles Chehade <gilles@openbsd.org>
5 * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
6 *
7 * Permission to use, copy, modify, and distribute this software for any
8 * purpose with or without fee is hereby granted, provided that the above
9 * copyright notice and this permission notice appear in all copies.
10 *
11 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
12 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
13 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
14 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
15 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
16 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
17 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
18 */
19
20#define CONF_FILE		 "/etc/mail/smtpd.conf"
21#define MAX_LISTEN		 16
22#define PROC_COUNT		 9
23#define READ_BUF_SIZE		 32768
24#define MAX_NAME_SIZE		 64
25
26#define MAX_HOPS_COUNT		 100
27
28/* sizes include the tailing '\0' */
29#define MAX_LINE_SIZE		 1024
30#define MAX_LOCALPART_SIZE	 65
31#define MAX_DOMAINPART_SIZE	 MAXHOSTNAMELEN
32#define MAX_ID_SIZE		 64
33
34/* return and forward path size */
35#define MAX_PATH_SIZE		 256
36
37/*#define SMTPD_CONNECT_TIMEOUT	 (60)*/
38#define SMTPD_CONNECT_TIMEOUT	 (10)
39#define SMTPD_QUEUE_INTERVAL	 (15 * 60)
40#define SMTPD_QUEUE_MAXINTERVAL	 (4 * 60 * 60)
41#define SMTPD_QUEUE_EXPIRY	 (4 * 24 * 60 * 60)
42#define SMTPD_USER		 "_smtpd"
43#define SMTPD_SOCKET		 "/var/run/smtpd.sock"
44#define SMTPD_BANNER		 "220 %s ESMTP OpenSMTPD"
45#define SMTPD_SESSION_TIMEOUT	 300
46#define SMTPD_BACKLOG		 5
47
48#define	PATH_MAILLOCAL		"/usr/libexec/mail.local"
49
50#define	DIRHASH_BUCKETS		 4096
51
52#define PATH_SPOOL		"/var/spool/smtpd"
53
54#define PATH_ENQUEUE		"/enqueue"
55#define PATH_INCOMING		"/incoming"
56#define PATH_QUEUE		"/queue"
57#define PATH_PURGE		"/purge"
58
59#define PATH_MESSAGE		"/message"
60#define PATH_ENVELOPES		"/envelopes"
61
62#define PATH_RUNQUEUE		"/runqueue"
63#define PATH_RUNQUEUEHIGH	"/runqueue-high"
64#define PATH_RUNQUEUELOW	"/runqueue-low"
65
66#define PATH_OFFLINE		"/offline"
67
68/* number of MX records to lookup */
69#define MXARRAYSIZE	5
70#define MAX_MX_COUNT	10
71
72/* rfc5321 limits */
73#define	SMTP_TEXTLINE_MAX	1000
74#define	SMTP_CMDLINE_MAX	512
75#define	SMTP_ANYLINE_MAX	SMTP_TEXTLINE_MAX
76
77#define F_STARTTLS		 0x01
78#define F_SMTPS			 0x02
79#define F_AUTH			 0x04
80#define F_SSL			(F_SMTPS|F_STARTTLS)
81
82
83struct netaddr {
84	struct sockaddr_storage ss;
85	int bits;
86};
87
88struct relayhost {
89	u_int8_t flags;
90	char hostname[MAXHOSTNAMELEN];
91	u_int16_t port;
92};
93
94struct mxhost {
95	TAILQ_ENTRY(mxhost)	 entry;
96	u_int8_t flags;
97	struct sockaddr_storage ss;
98	char credentials[MAX_LINE_SIZE];
99};
100
101/* buffer specific headers */
102struct buf {
103	TAILQ_ENTRY(buf)	 entry;
104	u_char			*buf;
105	size_t			 size;
106	size_t			 max;
107	size_t			 wpos;
108	size_t			 rpos;
109	int			 fd;
110};
111
112struct msgbuf {
113	TAILQ_HEAD(, buf)	 bufs;
114	u_int32_t		 queued;
115	int			 fd;
116};
117
118struct buf_read {
119	u_char			 buf[READ_BUF_SIZE];
120	u_char			*rptr;
121	size_t			 wpos;
122};
123
124struct imsg_fd  {
125	TAILQ_ENTRY(imsg_fd)	 entry;
126	int			 fd;
127	u_int32_t		 id;
128};
129
130struct imsgbuf {
131	TAILQ_HEAD(, imsg_fd)	 fds;
132	struct buf_read		 r;
133	struct msgbuf		 w;
134	struct event		 ev;
135	void			(*handler)(int, short, void *);
136	int			 fd;
137	pid_t			 pid;
138	short			 events;
139	void			*data;
140	u_int32_t		 id;
141};
142
143struct imsg_hdr {
144	u_int16_t		 type;
145	u_int16_t		 len;
146	u_int32_t		 peerid;
147	pid_t			 pid;
148};
149
150struct imsg {
151	struct imsg_hdr		 hdr;
152	u_int32_t		 id;
153	void			*data;
154};
155
156enum imsg_type {
157	IMSG_NONE,
158	IMSG_CTL_OK,		/* answer to smtpctl requests */
159	IMSG_CTL_FAIL,
160	IMSG_CTL_SHUTDOWN,
161	IMSG_CONF_START,
162	IMSG_CONF_SSL,
163	IMSG_CONF_SSL_CERT,
164	IMSG_CONF_SSL_KEY,
165	IMSG_CONF_LISTENER,
166	IMSG_CONF_MAP,
167	IMSG_CONF_RULE,
168	IMSG_CONF_CONDITION,
169	IMSG_CONF_OPTION,
170	IMSG_CONF_END,
171	IMSG_CONF_RELOAD,
172	IMSG_LKA_MAIL,
173	IMSG_LKA_RCPT,
174	IMSG_LKA_MX,
175	IMSG_LKA_MX_END,
176	IMSG_LKA_HOST,
177	IMSG_MDA_MAILBOX_FILE,
178	IMSG_MDA_MESSAGE_FILE,
179	IMSG_MFA_RCPT,
180	IMSG_MFA_MAIL,
181
182	IMSG_QUEUE_CREATE_MESSAGE,
183	IMSG_QUEUE_SUBMIT_ENVELOPE,
184	IMSG_QUEUE_COMMIT_ENVELOPES,
185	IMSG_QUEUE_REMOVE_MESSAGE,
186	IMSG_QUEUE_COMMIT_MESSAGE,
187	IMSG_QUEUE_TEMPFAIL,
188	IMSG_QUEUE_STATS,
189
190	IMSG_QUEUE_REMOVE_SUBMISSION,
191	IMSG_QUEUE_MESSAGE_UPDATE,
192	IMSG_QUEUE_MESSAGE_FD,
193	IMSG_QUEUE_MESSAGE_FILE,
194
195	IMSG_RUNNER_UPDATE_ENVELOPE,
196	IMSG_RUNNER_STATS,
197	IMSG_RUNNER_SCHEDULE,
198
199	IMSG_BATCH_CREATE,
200	IMSG_BATCH_APPEND,
201	IMSG_BATCH_CLOSE,
202
203	IMSG_PARENT_ENQUEUE_OFFLINE,
204	IMSG_PARENT_FORWARD_OPEN,
205	IMSG_PARENT_MAILBOX_OPEN,
206	IMSG_PARENT_MESSAGE_OPEN,
207	IMSG_PARENT_MAILBOX_RENAME,
208	IMSG_PARENT_STATS,
209
210	IMSG_PARENT_AUTHENTICATE,
211	IMSG_PARENT_SEND_CONFIG,
212
213	IMSG_MDA_PAUSE,
214	IMSG_MTA_PAUSE,
215	IMSG_SMTP_PAUSE,
216	IMSG_SMTP_STATS,
217
218	IMSG_MDA_RESUME,
219	IMSG_MTA_RESUME,
220	IMSG_SMTP_RESUME,
221
222	IMSG_STATS,
223
224	IMSG_SMTP_ENQUEUE
225};
226
227#define IMSG_HEADER_SIZE	 sizeof(struct imsg_hdr)
228#define	MAX_IMSGSIZE		 16384
229
230enum blockmodes {
231	BM_NORMAL,
232	BM_NONBLOCK
233};
234
235struct ctl_conn {
236	TAILQ_ENTRY(ctl_conn)	 entry;
237	u_int8_t		 flags;
238#define CTL_CONN_NOTIFY		 0x01
239	struct imsgbuf		 ibuf;
240};
241TAILQ_HEAD(ctl_connlist, ctl_conn);
242
243typedef u_int32_t		 objid_t;
244
245struct ctl_id {
246	objid_t		 id;
247	char		 name[MAX_NAME_SIZE];
248};
249
250enum smtp_proc_type {
251	PROC_PARENT = 0,
252	PROC_SMTP,
253	PROC_MFA,
254	PROC_LKA,
255	PROC_QUEUE,
256	PROC_MDA,
257	PROC_MTA,
258	PROC_CONTROL,
259	PROC_RUNNER,
260} smtpd_process;
261
262struct peer {
263	enum smtp_proc_type	 id;
264	void			(*cb)(int, short, void *);
265};
266
267enum map_type {
268	T_SINGLE,
269	T_LIST,
270	T_HASH
271};
272
273enum map_src {
274	S_NONE,
275	S_DYN,
276	S_DNS,
277	S_FILE,
278	S_DB,
279	S_EXT
280};
281
282enum mapel_type {
283	ME_STRING,
284	ME_NET,
285	ME_NETMASK
286};
287
288struct mapel {
289	TAILQ_ENTRY(mapel)		 me_entry;
290	union mapel_data {
291		char			 med_string[MAX_LINE_SIZE];
292		struct netaddr		 med_addr;
293	}				 me_key;
294	union mapel_data		 me_val;
295};
296
297struct map {
298	TAILQ_ENTRY(map)		 m_entry;
299#define F_USED				 0x01
300#define F_DYNAMIC			 0x02
301	u_int8_t			 m_flags;
302	char				 m_name[MAX_LINE_SIZE];
303	objid_t				 m_id;
304	enum map_type			 m_type;
305	enum mapel_type			 m_eltype;
306	enum map_src			 m_src;
307	char				 m_config[MAXPATHLEN];
308	TAILQ_HEAD(mapel_list, mapel)	 m_contents;
309};
310
311enum cond_type {
312	C_ALL,
313	C_NET,
314	C_DOM
315};
316
317struct cond {
318	TAILQ_ENTRY(cond)		 c_entry;
319	objid_t				 c_map;
320	enum cond_type			 c_type;
321	struct map			*c_match;
322};
323
324enum opt_type {
325	O_RWUSER,			/* rewrite user */
326	O_RWDOMAIN,			/* rewrite domain */
327};
328
329struct opt {
330	TAILQ_ENTRY(opt)		 o_entry;
331	enum opt_type			 o_type;
332};
333
334enum action_type {
335	A_INVALID,
336	A_RELAY,
337	A_RELAYVIA,
338	A_MAILDIR,
339	A_MBOX,
340	A_FILENAME,
341	A_EXT
342};
343#define IS_MAILBOX(x)	((x) == A_MAILDIR || (x) == A_MBOX || (x) == A_FILENAME)
344#define IS_RELAY(x)	((x) == A_RELAY || (x) == A_RELAYVIA)
345#define IS_EXT(x)	((x) == A_EXT)
346
347struct rule {
348	TAILQ_ENTRY(rule)		 r_entry;
349	int				 r_accept;
350	struct map			*r_sources;
351	TAILQ_HEAD(condlist, cond)	 r_conditions;
352	enum action_type		 r_action;
353	union rule_dest {
354		char			 path[MAXPATHLEN];
355		struct relayhost       	 relayhost;
356#define	MAXCOMMANDLEN	256
357		char			 command[MAXCOMMANDLEN];
358	}				 r_value;
359	TAILQ_HEAD(optlist, opt)	 r_options;
360};
361
362enum path_flags {
363	F_ALIAS = 0x1,
364	F_VIRTUAL = 0x2,
365	F_EXPANDED = 0x4,
366	F_NOFORWARD = 0x8,
367	F_FORWARDED = 0x10,
368	F_ACCOUNT = 0x20,
369};
370
371struct path {
372	TAILQ_ENTRY(path)		 entry;
373	struct rule			 rule;
374	enum path_flags			 flags;
375	u_int8_t			 forwardcnt;
376	char				 user[MAX_LOCALPART_SIZE];
377	char				 domain[MAX_DOMAINPART_SIZE];
378	char				 pw_name[MAXLOGNAME];
379	union path_data {
380		char filename[MAXPATHLEN];
381		char filter[MAXPATHLEN];
382	}				 u;
383};
384
385enum alias_type {
386	ALIAS_USERNAME,
387	ALIAS_FILENAME,
388	ALIAS_FILTER,
389	ALIAS_INCLUDE,
390	ALIAS_ADDRESS
391};
392
393struct alias {
394	TAILQ_ENTRY(alias)		entry;
395	enum alias_type			 type;
396	union alias_data {
397		char username[MAXLOGNAME];
398		char filename[MAXPATHLEN];
399		char filter[MAXPATHLEN];
400		struct path path;
401	}                                   u;
402};
403TAILQ_HEAD(aliaseslist, alias);
404
405enum message_type {
406	T_MDA_MESSAGE		= 0x1,
407	T_MTA_MESSAGE		= 0x2,
408	T_DAEMON_MESSAGE	= 0x4
409};
410
411enum message_status {
412	S_MESSAGE_LOCKFAILURE	= 0x1,
413	S_MESSAGE_PERMFAILURE	= 0x2,
414	S_MESSAGE_TEMPFAILURE	= 0x4,
415	S_MESSAGE_REJECTED	= 0x8,
416	S_MESSAGE_ACCEPTED	= 0x10,
417	S_MESSAGE_RETRY		= 0x20,
418	S_MESSAGE_EDNS		= 0x40,
419	S_MESSAGE_ECONNECT	= 0x80
420};
421
422enum message_flags {
423	F_MESSAGE_RESOLVED	= 0x1,
424	F_MESSAGE_SCHEDULED	= 0x2,
425	F_MESSAGE_PROCESSING	= 0x4,
426	F_MESSAGE_AUTHENTICATED	= 0x8,
427	F_MESSAGE_ENQUEUED	= 0x10,
428	F_MESSAGE_FORCESCHEDULE	= 0x20
429};
430
431struct message {
432	TAILQ_ENTRY(message)		 entry;
433
434	enum message_type		 type;
435
436	u_int64_t			 id;
437	u_int64_t			 session_id;
438	u_int64_t			 batch_id;
439
440	char				 message_id[MAX_ID_SIZE];
441	char				 message_uid[MAX_ID_SIZE];
442
443	char				 session_helo[MAXHOSTNAMELEN];
444	char				 session_hostname[MAXHOSTNAMELEN];
445	char				 session_errorline[MAX_LINE_SIZE];
446	struct sockaddr_storage		 session_ss;
447	struct path			 session_rcpt;
448
449	struct path			 sender;
450	struct path			 recipient;
451
452	time_t				 creation;
453	time_t				 lasttry;
454	u_int8_t			 retry;
455	enum message_flags		 flags;
456	enum message_status		 status;
457};
458
459enum batch_status {
460	S_BATCH_PERMFAILURE	= 0x1,
461	S_BATCH_TEMPFAILURE	= 0x2,
462	S_BATCH_REJECTED	= 0x4,
463	S_BATCH_ACCEPTED	= 0x8,
464	S_BATCH_RETRY		= 0x10,
465	S_BATCH_EDNS		= 0x20,
466	S_BATCH_ECONNECT	= 0x40
467};
468
469enum batch_type {
470	T_MDA_BATCH		= 0x1,
471	T_MTA_BATCH		= 0x2,
472	T_DAEMON_BATCH		= 0x4
473};
474
475enum batch_flags {
476	F_BATCH_COMPLETE	= 0x1,
477	F_BATCH_RESOLVED	= 0x2,
478	F_BATCH_SCHEDULED	= 0x4,
479	F_BATCH_EXPIRED		= 0x8,
480};
481
482enum child_type {
483	CHILD_INVALID,
484	CHILD_MDA,
485	CHILD_ENQUEUE_OFFLINE
486};
487
488struct mdaproc {
489	SPLAY_ENTRY(mdaproc)	mdaproc_nodes;
490
491	pid_t			pid;
492	enum child_type		type;
493};
494
495struct batch {
496	SPLAY_ENTRY(batch)	 b_nodes;
497
498	u_int64_t		 id;
499	u_int64_t		 session_id;
500	enum batch_type		 type;
501	enum batch_flags	 flags;
502
503	struct rule			 rule;
504
505	struct smtpd			*env;
506
507	char				 message_id[MAX_ID_SIZE];
508	char				 hostname[MAXHOSTNAMELEN];
509	char				 errorline[MAX_LINE_SIZE];
510
511	char				 session_helo[MAXHOSTNAMELEN];
512	char				 session_hostname[MAXHOSTNAMELEN];
513	struct sockaddr_storage		 session_ss;
514
515	time_t				 creation;
516	time_t				 lasttry;
517	u_int8_t			 retry;
518
519	struct session			*sessionp;
520
521	struct message			message;
522	struct message			*messagep;
523	FILE				*messagefp;
524	TAILQ_HEAD(messagelist, message) messages;
525
526	enum batch_status		status;
527};
528
529enum session_state {
530	S_INIT = 0,
531	S_GREETED,
532	S_TLS,
533	S_AUTH_INIT,
534	S_AUTH_USERNAME,
535	S_AUTH_PASSWORD,
536	S_AUTH_FINALIZE,
537	S_HELO,
538	S_MAILREQUEST,
539	S_MAIL,
540	S_RCPTREQUEST,
541	S_RCPT,
542	S_DATAREQUEST,
543	S_DATA,
544	S_DATACONTENT,
545	S_DONE,
546	S_QUIT
547};
548#define	IS_AUTH(x)	((x) == S_AUTH_INIT || (x) == S_AUTH_USERNAME || (x) == S_AUTH_PASSWORD || (x) == S_AUTH_FINALIZE)
549
550struct ssl {
551	SPLAY_ENTRY(ssl)	 ssl_nodes;
552	char			 ssl_name[PATH_MAX];
553	char			*ssl_cert;
554	off_t			 ssl_cert_len;
555	char			*ssl_key;
556	off_t			 ssl_key_len;
557};
558
559struct listener {
560	u_int8_t		 flags;
561	int			 fd;
562	struct sockaddr_storage	 ss;
563	in_port_t		 port;
564	struct timeval		 timeout;
565	struct event		 ev;
566	struct smtpd		*env;
567	char			 ssl_cert_name[PATH_MAX];
568	struct ssl		*ssl;
569	void			*ssl_ctx;
570	TAILQ_ENTRY(listener)	 entry;
571};
572
573struct session_auth_req {
574	u_int64_t	session_id;
575	char		buffer[MAX_LINE_SIZE];
576};
577
578struct session_auth_reply {
579	u_int64_t	session_id;
580	u_int8_t	value;
581};
582
583enum session_flags {
584	F_EHLO		= 0x1,
585	F_QUIT		= 0x2,
586	F_8BITMIME	= 0x4,
587	F_SECURE	= 0x8,
588	F_AUTHENTICATED	= 0x10,
589	F_PEERHASTLS	= 0x20,
590	F_PEERHASAUTH	= 0x40,
591	F_EVLOCKED	= 0x80
592};
593
594struct session {
595	SPLAY_ENTRY(session)		 s_nodes;
596	u_int64_t			 s_id;
597
598	enum session_flags		 s_flags;
599	enum session_state		 s_state;
600	int				 s_fd;
601	struct sockaddr_storage		 s_ss;
602	char				 s_hostname[MAXHOSTNAMELEN];
603	struct event			 s_ev;
604	struct bufferevent		*s_bev;
605	struct listener			*s_l;
606	struct smtpd			*s_env;
607	void				*s_ssl;
608	u_char				*s_buf;
609	int				 s_buflen;
610	struct timeval			 s_tv;
611	struct message			 s_msg;
612	size_t				 rcptcount;
613
614	struct session_auth_req		 s_auth;
615
616	struct batch			*batch;
617	TAILQ_HEAD(mxhostlist, mxhost) mxhosts;
618
619	FILE				*datafp;
620	int				 mboxfd;
621	int				 messagefd;
622};
623
624struct smtpd {
625#define SMTPD_OPT_VERBOSE			 0x00000001
626#define SMTPD_OPT_NOACTION			 0x00000002
627	u_int32_t				 sc_opts;
628#define SMTPD_CONFIGURING			 0x00000001
629#define SMTPD_EXITING				 0x00000002
630#define SMTPD_MDA_PAUSED		       	 0x00000004
631#define SMTPD_MTA_PAUSED		       	 0x00000008
632#define SMTPD_SMTP_PAUSED		       	 0x00000010
633	u_int32_t				 sc_flags;
634	struct timeval				 sc_qintval;
635	u_int32_t				 sc_maxconn;
636	struct event				 sc_ev;
637	int					 *sc_pipes[PROC_COUNT]
638						     [PROC_COUNT];
639	struct imsgbuf				*sc_ibufs[PROC_COUNT];
640	int					 sc_instances[PROC_COUNT];
641	int					 sc_instance;
642	struct passwd				*sc_pw;
643	char					 sc_hostname[MAXHOSTNAMELEN];
644	TAILQ_HEAD(listenerlist, listener)	 sc_listeners;
645	TAILQ_HEAD(maplist, map)		*sc_maps;
646	TAILQ_HEAD(rulelist, rule)		*sc_rules;
647	SPLAY_HEAD(sessiontree, session)	 sc_sessions;
648	SPLAY_HEAD(msgtree, message)		 sc_messages;
649	SPLAY_HEAD(ssltree, ssl)		 sc_ssl;
650
651	SPLAY_HEAD(batchtree, batch)		batch_queue;
652	SPLAY_HEAD(mdaproctree, mdaproc)	mdaproc_queue;
653	SPLAY_HEAD(lkatree, lkasession)		lka_sessions;
654};
655
656struct s_parent {
657	time_t		start;
658};
659
660struct s_queue {
661	size_t		inserts_local;
662	size_t		inserts_remote;
663};
664
665struct s_runner {
666	size_t		active;
667};
668
669struct s_session {
670	size_t		sessions;
671	size_t		sessions_active;
672
673	size_t		smtps;
674	size_t		smtps_active;
675
676	size_t		starttls;
677	size_t		starttls_active;
678
679	size_t		aborted;
680	size_t		timeout;
681};
682
683struct stats {
684	int			fd;
685	union u_stats {
686		struct s_parent	parent;
687		struct s_queue	queue;
688		struct s_runner	runner;
689		struct s_session smtp;
690		struct s_session mta;
691	}			u;
692};
693
694struct sched {
695	int			fd;
696	char			mid[MAX_ID_SIZE];
697	int			ret;
698};
699
700struct submit_status {
701	u_int64_t			 id;
702	int				 code;
703	union submit_path {
704		struct path		 path;
705		char			 msgid[MAX_ID_SIZE];
706		char			 errormsg[MAX_LINE_SIZE];
707	}				 u;
708	enum message_flags		 flags;
709	struct sockaddr_storage		 ss;
710	struct message			 msg;
711};
712
713struct forward_req {
714	u_int64_t			 id;
715	u_int8_t			 status;
716	char				 pw_name[MAXLOGNAME];
717};
718
719struct mxreq {
720	u_int64_t id;
721	char hostname[MAXHOSTNAMELEN];
722	struct rule rule;
723};
724
725struct mxrep {
726	u_int64_t id;
727	int getaddrinfo_error;
728	struct mxhost mxhost;
729};
730
731enum lkasession_flags {
732	F_ERROR		= 0x1
733};
734
735struct lkasession {
736	SPLAY_ENTRY(lkasession)		 nodes;
737	u_int64_t			 id;
738
739	struct path			 path;
740	struct aliaseslist		 aliaseslist;
741	u_int8_t			 iterations;
742	u_int32_t			 pending;
743	enum lkasession_flags		 flags;
744	struct message			 message;
745	struct submit_status		 ss;
746};
747
748/* aliases.c */
749int aliases_exist(struct smtpd *, char *);
750int aliases_get(struct smtpd *, struct aliaseslist *, char *);
751int aliases_virtual_exist(struct smtpd *, struct path *);
752int aliases_virtual_get(struct smtpd *, struct aliaseslist *, struct path *);
753int alias_parse(struct alias *, char *);
754
755
756/* log.c */
757void		log_init(int);
758void		log_warn(const char *, ...)
759    __attribute__ ((format (printf, 1, 2)));
760void		log_warnx(const char *, ...)
761    __attribute__ ((format (printf, 1, 2)));
762void		log_info(const char *, ...)
763    __attribute__ ((format (printf, 1, 2)));
764void		log_debug(const char *, ...)
765    __attribute__ ((format (printf, 1, 2)));
766__dead void	fatal(const char *);
767__dead void	fatalx(const char *);
768
769
770/* buffer.c */
771struct buf	*buf_open(size_t);
772struct buf	*buf_dynamic(size_t, size_t);
773int		 buf_add(struct buf *, void *, size_t);
774void		*buf_reserve(struct buf *, size_t);
775int		 buf_close(struct msgbuf *, struct buf *);
776void		 buf_free(struct buf *);
777void		 msgbuf_init(struct msgbuf *);
778void		 msgbuf_clear(struct msgbuf *);
779int		 msgbuf_write(struct msgbuf *);
780
781
782/* dns.c */
783int		 getmxbyname(char *, char ***);
784
785
786/* forward.c */
787int forwards_get(int, struct aliaseslist *);
788
789
790/* imsg.c */
791void	 imsg_init(struct imsgbuf *, int, void (*)(int, short, void *));
792ssize_t	 imsg_read(struct imsgbuf *);
793ssize_t	 imsg_get(struct imsgbuf *, struct imsg *);
794int	 imsg_compose(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t,
795	    int, void *, u_int16_t);
796int	 imsg_composev(struct imsgbuf *, enum imsg_type, u_int32_t,
797	    pid_t, int, const struct iovec *, int);
798int	 imsg_compose_fds(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t,
799	    void *, u_int16_t, int, ...);
800struct buf *imsg_create(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t,
801	    u_int16_t);
802int	 imsg_add(struct buf *, void *, u_int16_t);
803int	 imsg_append(struct imsgbuf *, struct buf *);
804int	 imsg_close(struct imsgbuf *, struct buf *);
805void	 imsg_free(struct imsg *);
806void	 imsg_event_add(struct imsgbuf *); /* needs to be provided externally */
807int	 imsg_get_fd(struct imsgbuf *, struct imsg *);
808int	 imsg_flush(struct imsgbuf *);
809void	 imsg_clear(struct imsgbuf *);
810
811/* lka.c */
812pid_t		 lka(struct smtpd *);
813int		 lkasession_cmp(struct lkasession *, struct lkasession *);
814SPLAY_PROTOTYPE(lkatree, lkasession, nodes, lkasession_cmp);
815
816/* mfa.c */
817pid_t		 mfa(struct smtpd *);
818int		 msg_cmp(struct message *, struct message *);
819
820/* queue.c */
821pid_t		 queue(struct smtpd *);
822u_int64_t	 queue_generate_id(void);
823int		 queue_remove_batch_message(struct smtpd *, struct batch *,
824 		     struct message *);
825int		 queue_load_envelope(struct message *, char *);
826int		 queue_update_envelope(struct message *);
827int		 queue_remove_envelope(struct message *);
828int		 batch_cmp(struct batch *, struct batch *);
829struct batch    *batch_by_id(struct smtpd *, u_int64_t);
830struct message	*message_by_id(struct smtpd *, struct batch *, u_int64_t);
831u_int16_t	 queue_hash(char *);
832
833/* queue_shared.c */
834int		 queue_create_layout_message(char *, char *);
835void		 queue_delete_layout_message(char *, char *);
836int		 queue_record_layout_envelope(char *, struct message *);
837int		 queue_remove_layout_envelope(char *, struct message *);
838int		 queue_commit_layout_message(char *, struct message *);
839int		 queue_open_layout_messagefile(char *, struct message *);
840int		 enqueue_create_layout(char *);
841void		 enqueue_delete_message(char *);
842int		 enqueue_record_envelope(struct message *);
843int		 enqueue_remove_envelope(struct message *);
844int		 enqueue_commit_message(struct message *);
845int		 enqueue_open_messagefile(struct message *);
846int		 queue_create_incoming_layout(char *);
847void		 queue_delete_incoming_message(char *);
848int		 queue_record_incoming_envelope(struct message *);
849int		 queue_remove_incoming_envelope(struct message *);
850int		 queue_commit_incoming_message(struct message *);
851int		 queue_open_incoming_message_file(struct message *);
852int		 queue_open_message_file(char *msgid);
853void		 queue_message_update(struct message *);
854void		 queue_delete_message(char *);
855struct qwalk	*qwalk_new(char *);
856int		 qwalk(struct qwalk *, char *);
857void		 qwalk_close(struct qwalk *);
858void		 show_queue(char *, int);
859
860u_int16_t	queue_hash(char *);
861
862/* map.c */
863char		*map_dblookup(struct smtpd *, char *, char *);
864
865/* mda.c */
866pid_t		 mda(struct smtpd *);
867int		 mdaproc_cmp(struct mdaproc *, struct mdaproc *);
868SPLAY_PROTOTYPE(mdaproctree, mdaproc, mdaproc_nodes, mdaproc_cmp);
869
870/* mta.c */
871pid_t		 mta(struct smtpd *);
872
873/* control.c */
874pid_t		 control(struct smtpd *);
875void		 session_socket_blockmode(int, enum blockmodes);
876
877/* enqueue.c */
878int		 enqueue(int, char **);
879int		 enqueue_offline(int, char **);
880
881/* runner.c */
882pid_t		 runner(struct smtpd *);
883SPLAY_PROTOTYPE(batchtree, batch, b_nodes, batch_cmp);
884
885
886/* smtp.c */
887pid_t		 smtp(struct smtpd *);
888void		 smtp_listener_setup(struct smtpd *, struct listener *);
889
890/* smtp_session.c */
891void		 session_init(struct listener *, struct session *);
892int		 session_cmp(struct session *, struct session *);
893void		 session_pickup(struct session *, struct submit_status *);
894void		 session_destroy(struct session *);
895void		 session_respond(struct session *, char *, ...)
896		    __attribute__ ((format (printf, 2, 3)));
897
898SPLAY_PROTOTYPE(sessiontree, session, s_nodes, session_cmp);
899
900/* store.c */
901int store_write_header(struct batch *, struct message *, FILE *, int);
902int store_write_message(struct batch *, struct message *);
903int store_write_daemon(struct batch *, struct message *);
904int store_message(struct batch *, struct message *,
905    int (*)(struct batch *, struct message *));
906
907/* config.c */
908#define		 PURGE_LISTENERS	0x01
909#define		 PURGE_MAPS		0x02
910#define		 PURGE_RULES		0x04
911#define		 PURGE_SSL		0x08
912#define		 PURGE_EVERYTHING	0xff
913void		 purge_config(struct smtpd *, u_int8_t);
914void		 unconfigure(struct smtpd *);
915void		 configure(struct smtpd *);
916void		 init_peers(struct smtpd *);
917void		 config_pipes(struct smtpd *, struct peer *, u_int);
918void		 config_peers(struct smtpd *, struct peer *, u_int);
919
920/* parse.y */
921int		 parse_config(struct smtpd *, const char *, int);
922int		 cmdline_symset(char *);
923
924/* ssl.c */
925void	 ssl_init(void);
926void	 ssl_transaction(struct session *);
927
928void	 ssl_session_init(struct session *);
929void	 ssl_session_destroy(struct session *);
930int	 ssl_load_certfile(struct smtpd *, const char *);
931void	 ssl_setup(struct smtpd *, struct listener *);
932int	 ssl_cmp(struct ssl *, struct ssl *);
933SPLAY_PROTOTYPE(ssltree, ssl, ssl_nodes, ssl_cmp);
934
935/* ssl_privsep.c */
936int	 ssl_ctx_use_private_key(void *, char *, off_t);
937int	 ssl_ctx_use_certificate_chain(void *, char *, off_t);
938
939/* smtpd.c */
940struct map	*map_find(struct smtpd *, objid_t);
941struct map	*map_findbyname(struct smtpd *, const char *);
942
943/* util.c */
944typedef struct arglist arglist;
945struct arglist {
946	char    **list;
947	u_int   num;
948	u_int   nalloc;
949};
950void		 addargs(arglist *, char *, ...)
951		     __attribute__((format(printf, 2, 3)));
952int		 bsnprintf(char *, size_t, const char *, ...)
953    __attribute__ ((format (printf, 3, 4)));
954int		 safe_fclose(FILE *);
955struct passwd 	*safe_getpwnam(const char *);
956struct passwd 	*safe_getpwuid(uid_t);
957int		 hostname_match(char *, char *);
958int		 recipient_to_path(struct path *, char *);
959int		 valid_localpart(char *);
960int		 valid_domainpart(char *);
961char		*ss_to_text(struct sockaddr_storage *);
962int		 valid_message_id(char *);
963int		 valid_message_uid(char *);
964char		*time_to_text(time_t);
965int		 secure_file(int, char *, struct passwd *);
966void		 lowercase(char *, char *, size_t);
967