smtpd.h revision 1.17
1/*	$OpenBSD: smtpd.h,v 1.17 2008/12/03 17:58:00 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		 8
23#define READ_BUF_SIZE		 32768
24#define MAX_NAME_SIZE		 64
25
26/* sizes include the tailing '\0' */
27#define MAX_LINE_SIZE		 1024
28#define MAX_LOCALPART_SIZE	 65
29#define MAX_DOMAINPART_SIZE	 MAXHOSTNAMELEN
30
31/* return and forward path size */
32#define MAX_PATH_SIZE		 256
33
34/*#define SMTPD_CONNECT_TIMEOUT	 (60)*/
35#define SMTPD_CONNECT_TIMEOUT	 (10)
36#define SMTPD_QUEUE_INTERVAL	 (15 * 60)
37#define SMTPD_QUEUE_MAXINTERVAL	 (4 * 60 * 60)
38#define SMTPD_QUEUE_EXPIRY	 (4 * 24 * 60 * 60)
39#define SMTPD_USER		 "_smtpd"
40#define SMTPD_SOCKET		 "/var/run/smtpd.sock"
41#define SMTPD_BANNER		 "220 %s OpenSMTPD\r\n"
42#define SMTPD_SESSION_TIMEOUT	 300
43
44#define RCPTBUFSZ		 256
45
46#define	DIRHASH_BUCKETS		 4096
47
48#define PATH_SPOOL		"/var/spool/smtpd"
49
50#define PATH_INCOMING		"/incoming"
51#define PATH_QUEUE		"/queue"
52#define PATH_MESSAGE		"/message"
53#define PATH_ENVELOPES		"/envelopes"
54
55#define PATH_RUNQUEUE		"/runqueue"
56#define PATH_RUNQUEUEHIGH	"/runqueue-high"
57#define PATH_RUNQUEUELOW	"/runqueue-low"
58
59/* used by newaliases */
60#define	PATH_ALIASES		"/etc/mail/aliases"
61#define	PATH_ALIASESDB		"/etc/mail/aliases.db"
62
63/* number of MX records to lookup */
64#define MXARRAYSIZE	5
65
66
67#define F_STARTTLS		 0x01
68#define F_SSMTP			 0x02
69#define F_SSL			(F_SSMTP|F_STARTTLS)
70
71
72struct netaddr {
73	struct sockaddr_storage ss;
74	int masked;
75};
76
77struct relayhost {
78	u_int8_t flags;
79	char hostname[MAXHOSTNAMELEN];
80	u_int16_t port;
81};
82
83struct mxhost {
84	u_int8_t flags;
85	struct sockaddr_storage ss;
86};
87
88/* buffer specific headers */
89struct buf {
90	TAILQ_ENTRY(buf)	 entry;
91	u_char			*buf;
92	size_t			 size;
93	size_t			 max;
94	size_t			 wpos;
95	size_t			 rpos;
96	int			 fd;
97};
98
99struct msgbuf {
100	TAILQ_HEAD(, buf)	 bufs;
101	u_int32_t		 queued;
102	int			 fd;
103};
104
105struct buf_read {
106	u_char			 buf[READ_BUF_SIZE];
107	u_char			*rptr;
108	size_t			 wpos;
109};
110
111struct imsg_fd  {
112	TAILQ_ENTRY(imsg_fd)	 entry;
113	int			 fd;
114	u_int32_t		 id;
115};
116
117struct imsgbuf {
118	TAILQ_HEAD(, imsg_fd)	 fds;
119	struct buf_read		 r;
120	struct msgbuf		 w;
121	struct event		 ev;
122	void			(*handler)(int, short, void *);
123	int			 fd;
124	pid_t			 pid;
125	short			 events;
126	void			*data;
127	u_int32_t		 id;
128};
129
130struct imsg_hdr {
131	u_int16_t		 type;
132	u_int16_t		 len;
133	u_int32_t		 peerid;
134	pid_t			 pid;
135};
136
137struct imsg {
138	struct imsg_hdr		 hdr;
139	u_int32_t		 id;
140	void			*data;
141};
142
143enum imsg_type {
144	IMSG_NONE,
145	IMSG_CTL_OK,		/* answer to smtpctl requests */
146	IMSG_CTL_FAIL,
147	IMSG_CTL_SHUTDOWN,
148	IMSG_CONF_START,
149	IMSG_CONF_SSL,
150	IMSG_CONF_SSL_CERT,
151	IMSG_CONF_SSL_KEY,
152	IMSG_CONF_LISTENER,
153	IMSG_CONF_MAP,
154	IMSG_CONF_RULE,
155	IMSG_CONF_CONDITION,
156	IMSG_CONF_OPTION,
157	IMSG_CONF_END,
158	IMSG_CONF_RELOAD,
159	IMSG_LKA_LOOKUP_MAIL,
160	IMSG_LKA_LOOKUP_RCPT,
161	IMSG_LKA_ALIAS_LOOKUP,
162	IMSG_LKA_VUSER_LOOKUP,
163	IMSG_LKA_ALIAS_RESULT,
164	IMSG_LKA_VUSER_RESULT,
165	IMSG_LKA_ALIAS_RESULT_ACK,
166	IMSG_LKA_ALIAS_SCHEDULE,
167	IMSG_LKA_ALIAS_END,
168	IMSG_LKA_NO_ALIAS,
169	IMSG_LKA_MX_LOOKUP,
170	IMSG_LKA_FORWARD_LOOKUP,
171	IMSG_LKA_HOSTNAME_LOOKUP,
172	IMSG_MDA_MAILBOX_FILE,
173	IMSG_MDA_MESSAGE_FILE,
174	IMSG_MDA_MAILBOX_FILE_ERROR,
175	IMSG_MDA_MESSAGE_FILE_ERROR,
176	IMSG_MFA_RPATH_SUBMIT,
177	IMSG_MFA_RCPT_SUBMIT,
178	IMSG_MFA_DATA_SUBMIT,
179	IMSG_MFA_LOOKUP_MAIL,
180	IMSG_MFA_LOOKUP_RCPT,
181
182	IMSG_QUEUE_CREATE_MESSAGE,
183	IMSG_QUEUE_SUBMIT_ENVELOPE,
184	IMSG_QUEUE_REMOVE_MESSAGE,
185	IMSG_QUEUE_COMMIT_MESSAGE,
186
187	IMSG_QUEUE_REMOVE_SUBMISSION,
188	IMSG_QUEUE_CREATE_MESSAGE_FILE,
189	IMSG_QUEUE_DELETE_MESSAGE_FILE,
190	IMSG_QUEUE_MESSAGE_SUBMIT,
191	IMSG_QUEUE_MESSAGE_UPDATE,
192	IMSG_QUEUE_MESSAGE_COMPLETE,
193	IMSG_QUEUE_MESSAGE_ACK,
194	IMSG_QUEUE_BATCH_COMPLETE,
195	IMSG_QUEUE_BATCH_CLOSE,
196	IMSG_QUEUE_MESSAGE_FD,
197	IMSG_QUEUE_MESSAGE_FILE,
198
199	IMSG_QUEUE_ACCEPTED_CLOSE,
200	IMSG_QUEUE_RETRY_CLOSE,
201	IMSG_QUEUE_REJECTED_CLOSE,
202
203	IMSG_QUEUE_RECIPIENT_ACCEPTED,
204	IMSG_QUEUE_RECIPIENT_UPDATED,
205
206	IMSG_CREATE_BATCH,
207	IMSG_BATCH_APPEND,
208	IMSG_BATCH_CLOSE,
209
210	IMSG_SMTP_MESSAGE_ID,
211
212	IMSG_SMTP_MESSAGE_FILE,
213	IMSG_SMTP_SUBMIT_ACK,
214	IMSG_SMTP_HOSTNAME_ANSWER,
215	IMSG_PARENT_MAILBOX_OPEN,
216	IMSG_PARENT_MESSAGE_OPEN,
217	IMSG_PARENT_MAILBOX_RENAME,
218
219	IMSG_PARENT_AUTHENTICATE
220};
221
222#define IMSG_HEADER_SIZE	 sizeof(struct imsg_hdr)
223#define	MAX_IMSGSIZE		 16384
224
225enum blockmodes {
226	BM_NORMAL,
227	BM_NONBLOCK
228};
229
230struct ctl_conn {
231	TAILQ_ENTRY(ctl_conn)	 entry;
232	u_int8_t		 flags;
233#define CTL_CONN_NOTIFY		 0x01
234	struct imsgbuf		 ibuf;
235};
236TAILQ_HEAD(ctl_connlist, ctl_conn);
237
238typedef u_int32_t		 objid_t;
239
240struct ctl_id {
241	objid_t		 id;
242	char		 name[MAX_NAME_SIZE];
243};
244
245enum smtp_proc_type {
246	PROC_PARENT = 0,
247	PROC_SMTP,
248	PROC_MFA,
249	PROC_LKA,
250	PROC_QUEUE,
251	PROC_MDA,
252	PROC_MTA,
253	PROC_CONTROL,
254} smtpd_process;
255
256struct peer {
257	enum smtp_proc_type	 id;
258	void			(*cb)(int, short, void *);
259};
260
261enum map_type {
262	T_SINGLE,
263	T_LIST,
264	T_HASH
265};
266
267enum map_src {
268	S_NONE,
269	S_DYN,
270	S_DNS,
271	S_FILE,
272	S_DB,
273	S_EXT
274};
275
276enum mapel_type {
277	ME_STRING,
278	ME_NET,
279	ME_NETMASK
280};
281
282struct mapel {
283	TAILQ_ENTRY(mapel)		 me_entry;
284	union mapel_data {
285		char			 med_string[MAX_LINE_SIZE];
286		struct netaddr		 med_addr;
287	}				 me_key;
288	union mapel_data		 me_val;
289};
290
291struct map {
292	TAILQ_ENTRY(map)		 m_entry;
293#define F_USED				 0x01
294#define F_DYNAMIC			 0x02
295	u_int8_t			 m_flags;
296	char				 m_name[MAX_LINE_SIZE];
297	objid_t				 m_id;
298	enum map_type			 m_type;
299	enum mapel_type			 m_eltype;
300	enum map_src			 m_src;
301	char				 m_config[MAXPATHLEN];
302	TAILQ_HEAD(mapel_list, mapel)	 m_contents;
303};
304
305enum cond_type {
306	C_ALL,
307	C_NET,
308	C_DOM
309};
310
311struct cond {
312	TAILQ_ENTRY(cond)		 c_entry;
313	objid_t				 c_map;
314	enum cond_type			 c_type;
315	struct map			*c_match;
316};
317
318enum opt_type {
319	O_RWUSER,			/* rewrite user */
320	O_RWDOMAIN,			/* rewrite domain */
321};
322
323struct opt {
324	TAILQ_ENTRY(opt)		 o_entry;
325	enum opt_type			 o_type;
326};
327
328enum action_type {
329	A_RELAY,
330	A_RELAYVIA,
331	A_MAILDIR,
332	A_MBOX,
333	A_FILENAME,
334	A_EXT
335};
336#define IS_MAILBOX(x)	((x) == A_MAILDIR || (x) == A_MBOX || (x) == A_FILENAME)
337#define IS_RELAY(x)	((x) == A_RELAY || (x) == A_RELAYVIA)
338#define IS_EXT(x)	((x) == A_EXT)
339
340struct rule {
341	TAILQ_ENTRY(rule)		 r_entry;
342	int				 r_accept;
343	struct map			*r_sources;
344	TAILQ_HEAD(condlist, cond)	 r_conditions;
345	enum action_type		 r_action;
346	union {
347		char			 path[MAXPATHLEN];
348		struct relayhost       	 relayhost;
349#define	MAXCOMMANDLEN	256
350		char			 command[MAXCOMMANDLEN];
351	}				 r_value;
352	TAILQ_HEAD(optlist, opt)	 r_options;
353};
354
355enum path_flags {
356	F_ALIAS = 0x1,
357	F_VIRTUAL = 0x2,
358	F_EXPANDED = 0x4,
359	F_NOFORWARD = 0x8,
360	F_FORWARDED = 0x10
361};
362
363struct path {
364	TAILQ_ENTRY(path)		 entry;
365	struct rule			 rule;
366	enum path_flags			 flags;
367	u_int8_t			 forwardcnt;
368	char				 user[MAX_LOCALPART_SIZE];
369	char				 domain[MAX_DOMAINPART_SIZE];
370	char				 pw_name[MAXLOGNAME];
371	union {
372		char filename[MAXPATHLEN];
373		char filter[MAXPATHLEN];
374	} u;
375};
376
377enum alias_type {
378	ALIAS_USERNAME,
379	ALIAS_FILENAME,
380	ALIAS_FILTER,
381	ALIAS_INCLUDE,
382	ALIAS_ADDRESS
383};
384
385struct alias {
386	TAILQ_ENTRY(alias)		entry;
387	enum alias_type			 type;
388	union {
389		char username[MAXLOGNAME];
390		char filename[MAXPATHLEN];
391		char filter[MAXPATHLEN];
392		struct path path;
393	} u;
394};
395TAILQ_HEAD(aliaseslist, alias);
396
397struct submit_status {
398	u_int64_t			 id;
399	int				 code;
400	union {
401		struct path		 path;
402		char			 msgid[MAXPATHLEN];
403		char			 errormsg[MAX_LINE_SIZE];
404	} u;
405	struct sockaddr_storage		 ss;
406};
407
408struct message_recipient {
409	u_int64_t			 id;
410	struct sockaddr_storage		 ss;
411	struct path			 path;
412};
413
414enum message_type {
415	T_MDA_MESSAGE		= 0x1,
416	T_MTA_MESSAGE		= 0x2,
417	T_DAEMON_MESSAGE	= 0x4
418};
419
420enum message_status {
421	S_MESSAGE_PERMFAILURE	= 0x1,
422	S_MESSAGE_TEMPFAILURE	= 0x2,
423	S_MESSAGE_REJECTED	= 0x4,
424	S_MESSAGE_ACCEPTED	= 0x8,
425	S_MESSAGE_RETRY		= 0x10,
426	S_MESSAGE_EDNS		= 0x20,
427	S_MESSAGE_ECONNECT	= 0x40
428};
429
430enum message_flags {
431	F_MESSAGE_RESOLVED	= 0x1,
432	F_MESSAGE_EXPIRED	= 0x2,
433	F_MESSAGE_SCHEDULED	= 0x4,
434	F_MESSAGE_PROCESSING	= 0x8
435};
436
437struct message {
438	SPLAY_ENTRY(message)		 nodes;
439	TAILQ_ENTRY(message)		 entry;
440
441	enum message_type		 type;
442
443	u_int64_t			 id;
444	u_int64_t			 session_id;
445	u_int64_t			 batch_id;
446
447	char				 message_id[MAXPATHLEN];
448	char				 message_uid[MAXPATHLEN];
449
450	char				 session_helo[MAXHOSTNAMELEN];
451	char				 session_hostname[MAXHOSTNAMELEN];
452	char				 session_errorline[MAX_LINE_SIZE];
453	struct sockaddr_storage		 session_ss;
454
455	struct path			 sender;
456	struct path			 recipient;
457	TAILQ_HEAD(pathlist,path)	 recipients;
458
459	u_int16_t			 rcptcount;
460
461	time_t				 creation;
462	time_t				 lasttry;
463	u_int8_t			 retry;
464	enum message_flags		 flags;
465	enum message_status		 status;
466	FILE				*datafp;
467	int				 mboxfd;
468	int				 messagefd;
469};
470
471enum batch_status {
472	S_BATCH_PERMFAILURE	= 0x1,
473	S_BATCH_TEMPFAILURE	= 0x2,
474	S_BATCH_REJECTED	= 0x4,
475	S_BATCH_ACCEPTED	= 0x8,
476	S_BATCH_RETRY		= 0x10,
477	S_BATCH_EDNS		= 0x20,
478	S_BATCH_ECONNECT	= 0x40
479};
480
481enum batch_type {
482	T_MDA_BATCH		= 0x1,
483	T_MTA_BATCH		= 0x2,
484	T_DAEMON_BATCH		= 0x4
485};
486
487enum batch_flags {
488	F_BATCH_COMPLETE	= 0x1,
489	F_BATCH_RESOLVED	= 0x2,
490	F_BATCH_SCHEDULED	= 0x4,
491	F_BATCH_EXPIRED		= 0x8,
492};
493
494struct mdaproc {
495	SPLAY_ENTRY(mdaproc)	mdaproc_nodes;
496
497	pid_t			pid;
498};
499
500struct batch {
501	SPLAY_ENTRY(batch)	 b_nodes;
502
503	u_int64_t		 id;
504	enum batch_type		 type;
505	enum batch_flags	 flags;
506
507	struct rule			 rule;
508
509	struct event			 ev;
510	struct timeval			 tv;
511	int				 peerfd;
512	struct bufferevent		*bev;
513	u_int8_t			 state;
514	struct smtpd			*env;
515
516	char				 message_id[MAXPATHLEN];
517	char				 hostname[MAXHOSTNAMELEN];
518	char				 errorline[MAX_LINE_SIZE];
519
520	u_int8_t			 getaddrinfo_error;
521	struct mxhost			 mxarray[MXARRAYSIZE*2];
522	u_int8_t			 mx_cnt;
523	u_int8_t			 mx_off;
524
525	time_t				 creation;
526	time_t				 lasttry;
527	u_int8_t			 retry;
528
529	struct message			message;
530	struct message			*messagep;
531	FILE				*messagefp;
532	TAILQ_HEAD(messagelist, message) messages;
533
534	enum batch_status		status;
535};
536
537enum session_state {
538	S_INIT = 0,
539	S_GREETED,
540	S_TLS,
541	S_AUTH,
542	S_HELO,
543	S_MAILREQUEST,
544	S_MAIL,
545	S_RCPTREQUEST,
546	S_RCPT,
547	S_DATA,
548	S_DATACONTENT,
549	S_DONE,
550	S_QUIT
551};
552
553struct ssl {
554	SPLAY_ENTRY(ssl)	 ssl_nodes;
555	char			 ssl_name[PATH_MAX];
556	char			*ssl_cert;
557	off_t			 ssl_cert_len;
558	char			*ssl_key;
559	off_t			 ssl_key_len;
560};
561
562struct listener {
563	u_int8_t		 flags;
564	int			 fd;
565	struct sockaddr_storage	 ss;
566	in_port_t		 port;
567	int			 backlog;
568	struct timeval		 timeout;
569	struct event		 ev;
570	struct smtpd		*env;
571	char			 ssl_cert_name[PATH_MAX];
572	struct ssl		*ssl;
573	void			*ssl_ctx;
574	TAILQ_ENTRY(listener)	 entry;
575};
576
577struct session_auth_req {
578	u_int64_t	session_id;
579	char		buffer[MAX_LINE_SIZE];
580};
581
582struct session_auth_reply {
583	u_int64_t	session_id;
584	u_int8_t	value;
585};
586
587enum session_flags {
588	F_EHLO		= 0x1,
589	F_QUIT		= 0x2,
590	F_8BITMIME	= 0x4,
591	F_SECURE	= 0x8,
592	F_AUTHENTICATED	= 0x10
593};
594
595struct session {
596	SPLAY_ENTRY(session)		 s_nodes;
597	u_int64_t			 s_id;
598
599	enum session_flags		 s_flags;
600	enum session_state		 s_state;
601	time_t				 s_tm;
602	int				 s_fd;
603	struct sockaddr_storage		 s_ss;
604	char				 s_hostname[MAXHOSTNAMELEN];
605	struct event			 s_ev;
606	struct bufferevent		*s_bev;
607	struct listener			*s_l;
608	struct smtpd			*s_env;
609	void				*s_ssl;
610	u_char				*s_buf;
611	int				 s_buflen;
612	struct timeval			 s_tv;
613	struct message			 s_msg;
614};
615
616struct smtpd {
617#define SMTPD_OPT_VERBOSE			 0x00000001
618#define SMTPD_OPT_NOACTION			 0x00000002
619	u_int32_t				 sc_opts;
620#define SMTPD_CONFIGURING			 0x00000001
621#define SMTPD_EXITING				 0x00000002
622	u_int32_t				 sc_flags;
623	struct timeval				 sc_qintval;
624	struct event				 sc_ev;
625	struct event				 sc_rqev;
626	int					 sc_pipes[PROC_COUNT]
627						    [PROC_COUNT][2];
628	struct imsgbuf				*sc_ibufs[PROC_COUNT];
629	struct passwd				*sc_pw;
630	char					 sc_hostname[MAXHOSTNAMELEN];
631	TAILQ_HEAD(listenerlist, listener)	 sc_listeners;
632	TAILQ_HEAD(maplist, map)		*sc_maps;
633	TAILQ_HEAD(rulelist, rule)		*sc_rules;
634	SPLAY_HEAD(sessiontree, session)	 sc_sessions;
635	SPLAY_HEAD(msgtree, message)		 sc_messages;
636	SPLAY_HEAD(ssltree, ssl)		 sc_ssl;
637
638	SPLAY_HEAD(batchtree, batch)		batch_queue;
639	SPLAY_HEAD(mdaproctree, mdaproc)	mdaproc_queue;
640};
641
642/* aliases.c */
643int aliases_exist(struct smtpd *, char *);
644int aliases_get(struct smtpd *, struct aliaseslist *, char *);
645int aliases_virtual_exist(struct smtpd *, struct path *);
646int aliases_virtual_get(struct smtpd *, struct aliaseslist *, struct path *);
647
648
649/* log.c */
650void		log_init(int);
651void		log_warn(const char *, ...);
652void		log_warnx(const char *, ...);
653void		log_info(const char *, ...);
654void		log_debug(const char *, ...);
655__dead void	fatal(const char *);
656__dead void	fatalx(const char *);
657
658
659/* buffer.c */
660struct buf	*buf_open(size_t);
661struct buf	*buf_dynamic(size_t, size_t);
662int		 buf_add(struct buf *, void *, size_t);
663void		*buf_reserve(struct buf *, size_t);
664int		 buf_close(struct msgbuf *, struct buf *);
665void		 buf_free(struct buf *);
666void		 msgbuf_init(struct msgbuf *);
667void		 msgbuf_clear(struct msgbuf *);
668int		 msgbuf_write(struct msgbuf *);
669
670
671/* dns.c */
672size_t getmxbyname(char *, char ***);
673
674
675/* forward.c */
676int forwards_get(struct aliaseslist *, char *);
677
678
679/* imsg.c */
680void	 imsg_init(struct imsgbuf *, int, void (*)(int, short, void *));
681ssize_t	 imsg_read(struct imsgbuf *);
682ssize_t	 imsg_get(struct imsgbuf *, struct imsg *);
683int	 imsg_compose(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t,
684	    int, void *, u_int16_t);
685int	 imsg_composev(struct imsgbuf *, enum imsg_type, u_int32_t,
686	    pid_t, int, const struct iovec *, int);
687int	 imsg_compose_fds(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t,
688	    void *, u_int16_t, int, ...);
689struct buf *imsg_create(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t,
690	    u_int16_t);
691int	 imsg_add(struct buf *, void *, u_int16_t);
692int	 imsg_append(struct imsgbuf *, struct buf *);
693int	 imsg_close(struct imsgbuf *, struct buf *);
694void	 imsg_free(struct imsg *);
695void	 imsg_event_add(struct imsgbuf *); /* needs to be provided externally */
696int	 imsg_get_fd(struct imsgbuf *, struct imsg *);
697int	 imsg_flush(struct imsgbuf *);
698void	 imsg_clear(struct imsgbuf *);
699
700/* lka.c */
701pid_t		 lka(struct smtpd *);
702
703/* mfa.c */
704pid_t		 mfa(struct smtpd *);
705int		 msg_cmp(struct message *, struct message *);
706SPLAY_PROTOTYPE(msgtree, message, nodes, msg_cmp);
707
708/* queue.c */
709pid_t		 queue(struct smtpd *);
710u_int64_t	 queue_generate_id(void);
711int		 batch_cmp(struct batch *, struct batch *);
712struct batch    *batch_by_id(struct smtpd *, u_int64_t);
713struct message	*message_by_id(struct smtpd *, struct batch *, u_int64_t);
714int		 queue_remove_batch_message(struct smtpd *, struct batch *, struct message *);
715SPLAY_PROTOTYPE(batchtree, batch, b_nodes, batch_cmp);
716
717/* mda.c */
718pid_t		 mda(struct smtpd *);
719int		 mdaproc_cmp(struct mdaproc *, struct mdaproc *);
720SPLAY_PROTOTYPE(mdaproctree, mdaproc, mdaproc_nodes, mdaproc_cmp);
721
722/* mta.c */
723pid_t		 mta(struct smtpd *);
724
725/* control.c */
726pid_t		 control(struct smtpd *);
727void		 session_socket_blockmode(int, enum blockmodes);
728
729/* smtp.c */
730pid_t		 smtp(struct smtpd *);
731void		 smtp_listener_setup(struct smtpd *, struct listener *);
732
733/* smtp_session.c */
734void		 session_init(struct listener *, struct session *);
735void		 session_read(struct bufferevent *, void *);
736void		 session_write(struct bufferevent *, void *);
737void		 session_error(struct bufferevent *, short, void *);
738int		 session_cmp(struct session *, struct session *);
739void		 session_msg_submit(struct session *);
740void		 session_pickup(struct session *, struct submit_status *);
741void		 session_destroy(struct session *);
742SPLAY_PROTOTYPE(sessiontree, session, s_nodes, session_cmp);
743
744/* store.c */
745int store_write_header(struct batch *, struct message *, FILE *);
746int store_write_message(struct batch *, struct message *);
747int store_write_daemon(struct batch *, struct message *);
748int store_message(struct batch *, struct message *,
749    int (*)(struct batch *, struct message *));
750
751/* config.c */
752#define		 PURGE_LISTENERS	0x01
753#define		 PURGE_MAPS		0x02
754#define		 PURGE_RULES		0x04
755#define		 PURGE_SSL		0x08
756#define		 PURGE_EVERYTHING	0xff
757void		 purge_config(struct smtpd *, u_int8_t);
758void		 unconfigure(struct smtpd *);
759void		 configure(struct smtpd *);
760void		 init_peers(struct smtpd *);
761void		 config_peers(struct smtpd *, struct peer *, u_int);
762
763/* parse.y */
764int		 parse_config(struct smtpd *, const char *, int);
765int		 cmdline_symset(char *);
766
767/* ssl.c */
768void	 ssl_init(void);
769void	 ssl_transaction(struct session *);
770
771void	 ssl_session_init(struct session *);
772void	 ssl_session_destroy(struct session *);
773int	 ssl_load_certfile(struct smtpd *, const char *);
774void	 ssl_setup(struct smtpd *, struct listener *);
775int	 ssl_cmp(struct ssl *, struct ssl *);
776SPLAY_PROTOTYPE(ssltree, ssl, ssl_nodes, ssl_cmp);
777
778/* ssl_privsep.c */
779int	 ssl_ctx_use_private_key(void *, char *, off_t);
780int	 ssl_ctx_use_certificate_chain(void *, char *, off_t);
781
782/* smtpd.c */
783struct map	*map_find(struct smtpd *, objid_t);
784struct map	*map_findbyname(struct smtpd *, const char *);
785