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