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