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