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