smtpd.h revision 1.22
1/*	$OpenBSD: smtpd.h,v 1.22 2008/12/07 03:14:24 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/* 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	PROC_RUNNER,
255} smtpd_process;
256
257struct peer {
258	enum smtp_proc_type	 id;
259	void			(*cb)(int, short, void *);
260};
261
262enum map_type {
263	T_SINGLE,
264	T_LIST,
265	T_HASH
266};
267
268enum map_src {
269	S_NONE,
270	S_DYN,
271	S_DNS,
272	S_FILE,
273	S_DB,
274	S_EXT
275};
276
277enum mapel_type {
278	ME_STRING,
279	ME_NET,
280	ME_NETMASK
281};
282
283struct mapel {
284	TAILQ_ENTRY(mapel)		 me_entry;
285	union mapel_data {
286		char			 med_string[MAX_LINE_SIZE];
287		struct netaddr		 med_addr;
288	}				 me_key;
289	union mapel_data		 me_val;
290};
291
292struct map {
293	TAILQ_ENTRY(map)		 m_entry;
294#define F_USED				 0x01
295#define F_DYNAMIC			 0x02
296	u_int8_t			 m_flags;
297	char				 m_name[MAX_LINE_SIZE];
298	objid_t				 m_id;
299	enum map_type			 m_type;
300	enum mapel_type			 m_eltype;
301	enum map_src			 m_src;
302	char				 m_config[MAXPATHLEN];
303	TAILQ_HEAD(mapel_list, mapel)	 m_contents;
304};
305
306enum cond_type {
307	C_ALL,
308	C_NET,
309	C_DOM
310};
311
312struct cond {
313	TAILQ_ENTRY(cond)		 c_entry;
314	objid_t				 c_map;
315	enum cond_type			 c_type;
316	struct map			*c_match;
317};
318
319enum opt_type {
320	O_RWUSER,			/* rewrite user */
321	O_RWDOMAIN,			/* rewrite domain */
322};
323
324struct opt {
325	TAILQ_ENTRY(opt)		 o_entry;
326	enum opt_type			 o_type;
327};
328
329enum action_type {
330	A_RELAY,
331	A_RELAYVIA,
332	A_MAILDIR,
333	A_MBOX,
334	A_FILENAME,
335	A_EXT
336};
337#define IS_MAILBOX(x)	((x) == A_MAILDIR || (x) == A_MBOX || (x) == A_FILENAME)
338#define IS_RELAY(x)	((x) == A_RELAY || (x) == A_RELAYVIA)
339#define IS_EXT(x)	((x) == A_EXT)
340
341struct rule {
342	TAILQ_ENTRY(rule)		 r_entry;
343	int				 r_accept;
344	struct map			*r_sources;
345	TAILQ_HEAD(condlist, cond)	 r_conditions;
346	enum action_type		 r_action;
347	union rule_dest {
348		char			 path[MAXPATHLEN];
349		struct relayhost       	 relayhost;
350#define	MAXCOMMANDLEN	256
351		char			 command[MAXCOMMANDLEN];
352	}				 r_value;
353	TAILQ_HEAD(optlist, opt)	 r_options;
354};
355
356enum path_flags {
357	F_ALIAS = 0x1,
358	F_VIRTUAL = 0x2,
359	F_EXPANDED = 0x4,
360	F_NOFORWARD = 0x8,
361	F_FORWARDED = 0x10
362};
363
364struct path {
365	TAILQ_ENTRY(path)		 entry;
366	struct rule			 rule;
367	enum path_flags			 flags;
368	u_int8_t			 forwardcnt;
369	char				 user[MAX_LOCALPART_SIZE];
370	char				 domain[MAX_DOMAINPART_SIZE];
371	char				 pw_name[MAXLOGNAME];
372	union path_data {
373		char filename[MAXPATHLEN];
374		char filter[MAXPATHLEN];
375	}				 u;
376};
377
378enum alias_type {
379	ALIAS_USERNAME,
380	ALIAS_FILENAME,
381	ALIAS_FILTER,
382	ALIAS_INCLUDE,
383	ALIAS_ADDRESS
384};
385
386struct alias {
387	TAILQ_ENTRY(alias)		entry;
388	enum alias_type			 type;
389	union alias_data {
390		char username[MAXLOGNAME];
391		char filename[MAXPATHLEN];
392		char filter[MAXPATHLEN];
393		struct path path;
394	}                                   u;
395};
396TAILQ_HEAD(aliaseslist, alias);
397
398struct submit_status {
399	u_int64_t			 id;
400	int				 code;
401	union submit_path {
402		struct path		 path;
403		char			 msgid[MAXPATHLEN];
404		char			 errormsg[MAX_LINE_SIZE];
405	}				 u;
406	struct sockaddr_storage		 ss;
407};
408
409struct message_recipient {
410	u_int64_t			 id;
411	struct sockaddr_storage		 ss;
412	struct path			 path;
413};
414
415enum message_type {
416	T_MDA_MESSAGE		= 0x1,
417	T_MTA_MESSAGE		= 0x2,
418	T_DAEMON_MESSAGE	= 0x4
419};
420
421enum message_status {
422	S_MESSAGE_PERMFAILURE	= 0x1,
423	S_MESSAGE_TEMPFAILURE	= 0x2,
424	S_MESSAGE_REJECTED	= 0x4,
425	S_MESSAGE_ACCEPTED	= 0x8,
426	S_MESSAGE_RETRY		= 0x10,
427	S_MESSAGE_EDNS		= 0x20,
428	S_MESSAGE_ECONNECT	= 0x40
429};
430
431enum message_flags {
432	F_MESSAGE_RESOLVED	= 0x1,
433	F_MESSAGE_EXPIRED	= 0x2,
434	F_MESSAGE_SCHEDULED	= 0x4,
435	F_MESSAGE_PROCESSING	= 0x8
436};
437
438struct message {
439	SPLAY_ENTRY(message)		 nodes;
440	TAILQ_ENTRY(message)		 entry;
441
442	enum message_type		 type;
443
444	u_int64_t			 id;
445	u_int64_t			 session_id;
446	u_int64_t			 batch_id;
447
448	char				 message_id[MAXPATHLEN];
449	char				 message_uid[MAXPATHLEN];
450
451	char				 session_helo[MAXHOSTNAMELEN];
452	char				 session_hostname[MAXHOSTNAMELEN];
453	char				 session_errorline[MAX_LINE_SIZE];
454	struct sockaddr_storage		 session_ss;
455
456	struct path			 sender;
457	struct path			 recipient;
458	TAILQ_HEAD(pathlist,path)	 recipients;
459
460	u_int16_t			 rcptcount;
461
462	time_t				 creation;
463	time_t				 lasttry;
464	u_int8_t			 retry;
465	enum message_flags		 flags;
466	enum message_status		 status;
467	FILE				*datafp;
468	int				 mboxfd;
469	int				 messagefd;
470};
471
472enum batch_status {
473	S_BATCH_PERMFAILURE	= 0x1,
474	S_BATCH_TEMPFAILURE	= 0x2,
475	S_BATCH_REJECTED	= 0x4,
476	S_BATCH_ACCEPTED	= 0x8,
477	S_BATCH_RETRY		= 0x10,
478	S_BATCH_EDNS		= 0x20,
479	S_BATCH_ECONNECT	= 0x40
480};
481
482enum batch_type {
483	T_MDA_BATCH		= 0x1,
484	T_MTA_BATCH		= 0x2,
485	T_DAEMON_BATCH		= 0x4
486};
487
488enum batch_flags {
489	F_BATCH_COMPLETE	= 0x1,
490	F_BATCH_RESOLVED	= 0x2,
491	F_BATCH_SCHEDULED	= 0x4,
492	F_BATCH_EXPIRED		= 0x8,
493};
494
495struct mdaproc {
496	SPLAY_ENTRY(mdaproc)	mdaproc_nodes;
497
498	pid_t			pid;
499};
500
501struct batch {
502	SPLAY_ENTRY(batch)	 b_nodes;
503
504	u_int64_t		 id;
505	enum batch_type		 type;
506	enum batch_flags	 flags;
507
508	struct rule			 rule;
509
510	struct event			 ev;
511	struct timeval			 tv;
512	int				 peerfd;
513	struct bufferevent		*bev;
514	u_int8_t			 state;
515	struct smtpd			*env;
516
517	char				 message_id[MAXPATHLEN];
518	char				 hostname[MAXHOSTNAMELEN];
519	char				 errorline[MAX_LINE_SIZE];
520
521	int8_t				 getaddrinfo_error;
522	struct mxhost			 mxarray[MXARRAYSIZE*2];
523	u_int8_t			 mx_cnt;
524	u_int8_t			 mx_off;
525
526	time_t				 creation;
527	time_t				 lasttry;
528	u_int8_t			 retry;
529
530	struct message			message;
531	struct message			*messagep;
532	FILE				*messagefp;
533	TAILQ_HEAD(messagelist, message) messages;
534
535	enum batch_status		status;
536};
537
538enum session_state {
539	S_INIT = 0,
540	S_GREETED,
541	S_TLS,
542	S_AUTH,
543	S_HELO,
544	S_MAILREQUEST,
545	S_MAIL,
546	S_RCPTREQUEST,
547	S_RCPT,
548	S_DATAREQUEST,
549	S_DATA,
550	S_DATACONTENT,
551	S_DONE,
552	S_QUIT
553};
554
555struct ssl {
556	SPLAY_ENTRY(ssl)	 ssl_nodes;
557	char			 ssl_name[PATH_MAX];
558	char			*ssl_cert;
559	off_t			 ssl_cert_len;
560	char			*ssl_key;
561	off_t			 ssl_key_len;
562};
563
564struct listener {
565	u_int8_t		 flags;
566	int			 fd;
567	struct sockaddr_storage	 ss;
568	in_port_t		 port;
569	int			 backlog;
570	struct timeval		 timeout;
571	struct event		 ev;
572	struct smtpd		*env;
573	char			 ssl_cert_name[PATH_MAX];
574	struct ssl		*ssl;
575	void			*ssl_ctx;
576	TAILQ_ENTRY(listener)	 entry;
577};
578
579struct session_auth_req {
580	u_int64_t	session_id;
581	char		buffer[MAX_LINE_SIZE];
582};
583
584struct session_auth_reply {
585	u_int64_t	session_id;
586	u_int8_t	value;
587};
588
589enum session_flags {
590	F_EHLO		= 0x1,
591	F_QUIT		= 0x2,
592	F_8BITMIME	= 0x4,
593	F_SECURE	= 0x8,
594	F_AUTHENTICATED	= 0x10
595};
596
597struct session {
598	SPLAY_ENTRY(session)		 s_nodes;
599	u_int64_t			 s_id;
600
601	enum session_flags		 s_flags;
602	enum session_state		 s_state;
603	time_t				 s_tm;
604	int				 s_fd;
605	struct sockaddr_storage		 s_ss;
606	char				 s_hostname[MAXHOSTNAMELEN];
607	struct event			 s_ev;
608	struct bufferevent		*s_bev;
609	struct listener			*s_l;
610	struct smtpd			*s_env;
611	void				*s_ssl;
612	u_char				*s_buf;
613	int				 s_buflen;
614	struct timeval			 s_tv;
615	struct message			 s_msg;
616};
617
618struct smtpd {
619#define SMTPD_OPT_VERBOSE			 0x00000001
620#define SMTPD_OPT_NOACTION			 0x00000002
621	u_int32_t				 sc_opts;
622#define SMTPD_CONFIGURING			 0x00000001
623#define SMTPD_EXITING				 0x00000002
624	u_int32_t				 sc_flags;
625	struct timeval				 sc_qintval;
626	struct event				 sc_ev;
627	int					 sc_pipes[PROC_COUNT]
628						    [PROC_COUNT][2];
629	struct imsgbuf				*sc_ibufs[PROC_COUNT];
630	struct passwd				*sc_pw;
631	char					 sc_hostname[MAXHOSTNAMELEN];
632	TAILQ_HEAD(listenerlist, listener)	 sc_listeners;
633	TAILQ_HEAD(maplist, map)		*sc_maps;
634	TAILQ_HEAD(rulelist, rule)		*sc_rules;
635	SPLAY_HEAD(sessiontree, session)	 sc_sessions;
636	SPLAY_HEAD(msgtree, message)		 sc_messages;
637	SPLAY_HEAD(ssltree, ssl)		 sc_ssl;
638
639	SPLAY_HEAD(batchtree, batch)		batch_queue;
640	SPLAY_HEAD(mdaproctree, mdaproc)	mdaproc_queue;
641};
642
643/* aliases.c */
644int aliases_exist(struct smtpd *, char *);
645int aliases_get(struct smtpd *, struct aliaseslist *, char *);
646int aliases_virtual_exist(struct smtpd *, struct path *);
647int aliases_virtual_get(struct smtpd *, struct aliaseslist *, struct path *);
648
649
650/* log.c */
651void		log_init(int);
652void		log_warn(const char *, ...)
653    __attribute__ ((format (printf, 1, 2)));
654void		log_warnx(const char *, ...)
655    __attribute__ ((format (printf, 1, 2)));
656void		log_info(const char *, ...)
657    __attribute__ ((format (printf, 1, 2)));
658void		log_debug(const char *, ...)
659    __attribute__ ((format (printf, 1, 2)));
660__dead void	fatal(const char *);
661__dead void	fatalx(const char *);
662
663
664/* buffer.c */
665struct buf	*buf_open(size_t);
666struct buf	*buf_dynamic(size_t, size_t);
667int		 buf_add(struct buf *, void *, size_t);
668void		*buf_reserve(struct buf *, size_t);
669int		 buf_close(struct msgbuf *, struct buf *);
670void		 buf_free(struct buf *);
671void		 msgbuf_init(struct msgbuf *);
672void		 msgbuf_clear(struct msgbuf *);
673int		 msgbuf_write(struct msgbuf *);
674
675
676/* dns.c */
677size_t getmxbyname(char *, char ***);
678
679
680/* forward.c */
681int forwards_get(struct aliaseslist *, char *);
682
683
684/* imsg.c */
685void	 imsg_init(struct imsgbuf *, int, void (*)(int, short, void *));
686ssize_t	 imsg_read(struct imsgbuf *);
687ssize_t	 imsg_get(struct imsgbuf *, struct imsg *);
688int	 imsg_compose(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t,
689	    int, void *, u_int16_t);
690int	 imsg_composev(struct imsgbuf *, enum imsg_type, u_int32_t,
691	    pid_t, int, const struct iovec *, int);
692int	 imsg_compose_fds(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t,
693	    void *, u_int16_t, int, ...);
694struct buf *imsg_create(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t,
695	    u_int16_t);
696int	 imsg_add(struct buf *, void *, u_int16_t);
697int	 imsg_append(struct imsgbuf *, struct buf *);
698int	 imsg_close(struct imsgbuf *, struct buf *);
699void	 imsg_free(struct imsg *);
700void	 imsg_event_add(struct imsgbuf *); /* needs to be provided externally */
701int	 imsg_get_fd(struct imsgbuf *, struct imsg *);
702int	 imsg_flush(struct imsgbuf *);
703void	 imsg_clear(struct imsgbuf *);
704
705/* lka.c */
706pid_t		 lka(struct smtpd *);
707
708/* mfa.c */
709pid_t		 mfa(struct smtpd *);
710int		 msg_cmp(struct message *, struct message *);
711SPLAY_PROTOTYPE(msgtree, message, nodes, msg_cmp);
712
713/* queue.c */
714pid_t		 queue(struct smtpd *);
715u_int64_t	 queue_generate_id(void);
716int		 batch_cmp(struct batch *, struct batch *);
717struct batch    *batch_by_id(struct smtpd *, u_int64_t);
718struct message	*message_by_id(struct smtpd *, struct batch *, u_int64_t);
719int		 queue_remove_batch_message(struct smtpd *, struct batch *, struct message *);
720
721/* mda.c */
722pid_t		 mda(struct smtpd *);
723int		 mdaproc_cmp(struct mdaproc *, struct mdaproc *);
724SPLAY_PROTOTYPE(mdaproctree, mdaproc, mdaproc_nodes, mdaproc_cmp);
725
726/* mta.c */
727pid_t		 mta(struct smtpd *);
728
729/* control.c */
730pid_t		 control(struct smtpd *);
731void		 session_socket_blockmode(int, enum blockmodes);
732
733/* runner.c */
734pid_t		 runner(struct smtpd *);
735SPLAY_PROTOTYPE(batchtree, batch, b_nodes, batch_cmp);
736
737
738/* smtp.c */
739pid_t		 smtp(struct smtpd *);
740void		 smtp_listener_setup(struct smtpd *, struct listener *);
741
742/* smtp_session.c */
743void		 session_init(struct listener *, struct session *);
744void		 session_read(struct bufferevent *, void *);
745void		 session_write(struct bufferevent *, void *);
746void		 session_error(struct bufferevent *, short, void *);
747int		 session_cmp(struct session *, struct session *);
748void		 session_msg_submit(struct session *);
749void		 session_pickup(struct session *, struct submit_status *);
750void		 session_destroy(struct session *);
751SPLAY_PROTOTYPE(sessiontree, session, s_nodes, session_cmp);
752
753/* store.c */
754int store_write_header(struct batch *, struct message *, FILE *);
755int store_write_message(struct batch *, struct message *);
756int store_write_daemon(struct batch *, struct message *);
757int store_message(struct batch *, struct message *,
758    int (*)(struct batch *, struct message *));
759
760/* config.c */
761#define		 PURGE_LISTENERS	0x01
762#define		 PURGE_MAPS		0x02
763#define		 PURGE_RULES		0x04
764#define		 PURGE_SSL		0x08
765#define		 PURGE_EVERYTHING	0xff
766void		 purge_config(struct smtpd *, u_int8_t);
767void		 unconfigure(struct smtpd *);
768void		 configure(struct smtpd *);
769void		 init_peers(struct smtpd *);
770void		 config_peers(struct smtpd *, struct peer *, u_int);
771
772/* parse.y */
773int		 parse_config(struct smtpd *, const char *, int);
774int		 cmdline_symset(char *);
775
776/* ssl.c */
777void	 ssl_init(void);
778void	 ssl_transaction(struct session *);
779
780void	 ssl_session_init(struct session *);
781void	 ssl_session_destroy(struct session *);
782int	 ssl_load_certfile(struct smtpd *, const char *);
783void	 ssl_setup(struct smtpd *, struct listener *);
784int	 ssl_cmp(struct ssl *, struct ssl *);
785SPLAY_PROTOTYPE(ssltree, ssl, ssl_nodes, ssl_cmp);
786
787/* ssl_privsep.c */
788int	 ssl_ctx_use_private_key(void *, char *, off_t);
789int	 ssl_ctx_use_certificate_chain(void *, char *, off_t);
790
791/* smtpd.c */
792struct map	*map_find(struct smtpd *, objid_t);
793struct map	*map_findbyname(struct smtpd *, const char *);
794