smtpd.h revision 1.32
1/*	$OpenBSD: smtpd.h,v 1.32 2008/12/19 00:39:05 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"
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_PURGE		"/purge"
53
54#define PATH_MESSAGE		"/message"
55#define PATH_ENVELOPES		"/envelopes"
56
57#define PATH_RUNQUEUE		"/runqueue"
58#define PATH_RUNQUEUEHIGH	"/runqueue-high"
59#define PATH_RUNQUEUELOW	"/runqueue-low"
60
61/* used by newaliases */
62#define	PATH_ALIASES		"/etc/mail/aliases"
63#define	PATH_ALIASESDB		"/etc/mail/aliases.db"
64
65/* number of MX records to lookup */
66#define MXARRAYSIZE	5
67
68/* rfc5321 limits */
69#define	SMTP_TEXTLINE_MAX	1000
70#define	SMTP_CMDLINE_MAX	512
71
72#define F_STARTTLS		 0x01
73#define F_SSMTP			 0x02
74#define F_SSL			(F_SSMTP|F_STARTTLS)
75
76
77struct netaddr {
78	struct sockaddr_storage ss;
79	int masked;
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_ALIAS,
167	IMSG_LKA_MX,
168	IMSG_LKA_FORWARD,
169	IMSG_LKA_HOST,
170	IMSG_MDA_MAILBOX_FILE,
171	IMSG_MDA_MESSAGE_FILE,
172	IMSG_MFA_RCPT,
173	IMSG_MFA_MAIL,
174
175	IMSG_QUEUE_CREATE_MESSAGE,
176	IMSG_QUEUE_SUBMIT_ENVELOPE,
177	IMSG_QUEUE_REMOVE_MESSAGE,
178	IMSG_QUEUE_COMMIT_MESSAGE,
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
196#define IMSG_HEADER_SIZE	 sizeof(struct imsg_hdr)
197#define	MAX_IMSGSIZE		 16384
198
199enum blockmodes {
200	BM_NORMAL,
201	BM_NONBLOCK
202};
203
204struct ctl_conn {
205	TAILQ_ENTRY(ctl_conn)	 entry;
206	u_int8_t		 flags;
207#define CTL_CONN_NOTIFY		 0x01
208	struct imsgbuf		 ibuf;
209};
210TAILQ_HEAD(ctl_connlist, ctl_conn);
211
212typedef u_int32_t		 objid_t;
213
214struct ctl_id {
215	objid_t		 id;
216	char		 name[MAX_NAME_SIZE];
217};
218
219enum smtp_proc_type {
220	PROC_PARENT = 0,
221	PROC_SMTP,
222	PROC_MFA,
223	PROC_LKA,
224	PROC_QUEUE,
225	PROC_MDA,
226	PROC_MTA,
227	PROC_CONTROL,
228	PROC_RUNNER,
229} smtpd_process;
230
231struct peer {
232	enum smtp_proc_type	 id;
233	void			(*cb)(int, short, void *);
234};
235
236enum map_type {
237	T_SINGLE,
238	T_LIST,
239	T_HASH
240};
241
242enum map_src {
243	S_NONE,
244	S_DYN,
245	S_DNS,
246	S_FILE,
247	S_DB,
248	S_EXT
249};
250
251enum mapel_type {
252	ME_STRING,
253	ME_NET,
254	ME_NETMASK
255};
256
257struct mapel {
258	TAILQ_ENTRY(mapel)		 me_entry;
259	union mapel_data {
260		char			 med_string[MAX_LINE_SIZE];
261		struct netaddr		 med_addr;
262	}				 me_key;
263	union mapel_data		 me_val;
264};
265
266struct map {
267	TAILQ_ENTRY(map)		 m_entry;
268#define F_USED				 0x01
269#define F_DYNAMIC			 0x02
270	u_int8_t			 m_flags;
271	char				 m_name[MAX_LINE_SIZE];
272	objid_t				 m_id;
273	enum map_type			 m_type;
274	enum mapel_type			 m_eltype;
275	enum map_src			 m_src;
276	char				 m_config[MAXPATHLEN];
277	TAILQ_HEAD(mapel_list, mapel)	 m_contents;
278};
279
280enum cond_type {
281	C_ALL,
282	C_NET,
283	C_DOM
284};
285
286struct cond {
287	TAILQ_ENTRY(cond)		 c_entry;
288	objid_t				 c_map;
289	enum cond_type			 c_type;
290	struct map			*c_match;
291};
292
293enum opt_type {
294	O_RWUSER,			/* rewrite user */
295	O_RWDOMAIN,			/* rewrite domain */
296};
297
298struct opt {
299	TAILQ_ENTRY(opt)		 o_entry;
300	enum opt_type			 o_type;
301};
302
303enum action_type {
304	A_RELAY,
305	A_RELAYVIA,
306	A_MAILDIR,
307	A_MBOX,
308	A_FILENAME,
309	A_EXT
310};
311#define IS_MAILBOX(x)	((x) == A_MAILDIR || (x) == A_MBOX || (x) == A_FILENAME)
312#define IS_RELAY(x)	((x) == A_RELAY || (x) == A_RELAYVIA)
313#define IS_EXT(x)	((x) == A_EXT)
314
315struct rule {
316	TAILQ_ENTRY(rule)		 r_entry;
317	int				 r_accept;
318	struct map			*r_sources;
319	TAILQ_HEAD(condlist, cond)	 r_conditions;
320	enum action_type		 r_action;
321	union rule_dest {
322		char			 path[MAXPATHLEN];
323		struct relayhost       	 relayhost;
324#define	MAXCOMMANDLEN	256
325		char			 command[MAXCOMMANDLEN];
326	}				 r_value;
327	TAILQ_HEAD(optlist, opt)	 r_options;
328};
329
330enum path_flags {
331	F_ALIAS = 0x1,
332	F_VIRTUAL = 0x2,
333	F_EXPANDED = 0x4,
334	F_NOFORWARD = 0x8,
335	F_FORWARDED = 0x10
336};
337
338struct path {
339	TAILQ_ENTRY(path)		 entry;
340	struct rule			 rule;
341	enum path_flags			 flags;
342	u_int8_t			 forwardcnt;
343	char				 user[MAX_LOCALPART_SIZE];
344	char				 domain[MAX_DOMAINPART_SIZE];
345	char				 pw_name[MAXLOGNAME];
346	union path_data {
347		char filename[MAXPATHLEN];
348		char filter[MAXPATHLEN];
349	}				 u;
350};
351
352enum alias_type {
353	ALIAS_USERNAME,
354	ALIAS_FILENAME,
355	ALIAS_FILTER,
356	ALIAS_INCLUDE,
357	ALIAS_ADDRESS
358};
359
360struct alias {
361	TAILQ_ENTRY(alias)		entry;
362	enum alias_type			 type;
363	union alias_data {
364		char username[MAXLOGNAME];
365		char filename[MAXPATHLEN];
366		char filter[MAXPATHLEN];
367		struct path path;
368	}                                   u;
369};
370TAILQ_HEAD(aliaseslist, alias);
371
372struct submit_status {
373	u_int64_t			 id;
374	int				 code;
375	union submit_path {
376		struct path		 path;
377		char			 msgid[MAXPATHLEN];
378		char			 errormsg[MAX_LINE_SIZE];
379	}				 u;
380	struct sockaddr_storage		 ss;
381};
382
383struct message_recipient {
384	u_int64_t			 id;
385	struct sockaddr_storage		 ss;
386	struct path			 path;
387};
388
389enum message_type {
390	T_MDA_MESSAGE		= 0x1,
391	T_MTA_MESSAGE		= 0x2,
392	T_DAEMON_MESSAGE	= 0x4
393};
394
395enum message_status {
396	S_MESSAGE_LOCKFAILURE	= 0x1,
397	S_MESSAGE_PERMFAILURE	= 0x2,
398	S_MESSAGE_TEMPFAILURE	= 0x4,
399	S_MESSAGE_REJECTED	= 0x8,
400	S_MESSAGE_ACCEPTED	= 0x10,
401	S_MESSAGE_RETRY		= 0x20,
402	S_MESSAGE_EDNS		= 0x40,
403	S_MESSAGE_ECONNECT	= 0x80
404};
405
406enum message_flags {
407	F_MESSAGE_RESOLVED	= 0x1,
408	F_MESSAGE_EXPIRED	= 0x2,
409	F_MESSAGE_SCHEDULED	= 0x4,
410	F_MESSAGE_PROCESSING	= 0x8
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[MAXPATHLEN];
424	char				 message_uid[MAXPATHLEN];
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
431	struct path			 sender;
432	struct path			 recipient;
433	TAILQ_HEAD(pathlist,path)	 recipients;
434
435	u_int16_t			 rcptcount;
436
437	time_t				 creation;
438	time_t				 lasttry;
439	u_int8_t			 retry;
440	enum message_flags		 flags;
441	enum message_status		 status;
442	FILE				*datafp;
443	int				 mboxfd;
444	int				 messagefd;
445};
446
447enum batch_status {
448	S_BATCH_PERMFAILURE	= 0x1,
449	S_BATCH_TEMPFAILURE	= 0x2,
450	S_BATCH_REJECTED	= 0x4,
451	S_BATCH_ACCEPTED	= 0x8,
452	S_BATCH_RETRY		= 0x10,
453	S_BATCH_EDNS		= 0x20,
454	S_BATCH_ECONNECT	= 0x40
455};
456
457enum batch_type {
458	T_MDA_BATCH		= 0x1,
459	T_MTA_BATCH		= 0x2,
460	T_DAEMON_BATCH		= 0x4
461};
462
463enum batch_flags {
464	F_BATCH_COMPLETE	= 0x1,
465	F_BATCH_RESOLVED	= 0x2,
466	F_BATCH_SCHEDULED	= 0x4,
467	F_BATCH_EXPIRED		= 0x8,
468};
469
470struct mdaproc {
471	SPLAY_ENTRY(mdaproc)	mdaproc_nodes;
472
473	pid_t			pid;
474};
475
476struct batch {
477	SPLAY_ENTRY(batch)	 b_nodes;
478
479	u_int64_t		 id;
480	enum batch_type		 type;
481	enum batch_flags	 flags;
482
483	struct rule			 rule;
484
485	struct event			 ev;
486	struct timeval			 tv;
487	int				 peerfd;
488	struct bufferevent		*bev;
489	u_int8_t			 state;
490	struct smtpd			*env;
491
492	char				 message_id[MAXPATHLEN];
493	char				 hostname[MAXHOSTNAMELEN];
494	char				 errorline[MAX_LINE_SIZE];
495
496	int8_t				 getaddrinfo_error;
497	struct mxhost			 mxarray[MXARRAYSIZE*2];
498	u_int8_t			 mx_cnt;
499	u_int8_t			 mx_off;
500
501	time_t				 creation;
502	time_t				 lasttry;
503	u_int8_t			 retry;
504
505	struct message			message;
506	struct message			*messagep;
507	FILE				*messagefp;
508	TAILQ_HEAD(messagelist, message) messages;
509
510	enum batch_status		status;
511};
512
513enum session_state {
514	S_INIT = 0,
515	S_GREETED,
516	S_TLS,
517	S_AUTH,
518	S_HELO,
519	S_MAILREQUEST,
520	S_MAIL,
521	S_RCPTREQUEST,
522	S_RCPT,
523	S_DATAREQUEST,
524	S_DATA,
525	S_DATACONTENT,
526	S_DONE,
527	S_QUIT
528};
529
530struct ssl {
531	SPLAY_ENTRY(ssl)	 ssl_nodes;
532	char			 ssl_name[PATH_MAX];
533	char			*ssl_cert;
534	off_t			 ssl_cert_len;
535	char			*ssl_key;
536	off_t			 ssl_key_len;
537};
538
539struct listener {
540	u_int8_t		 flags;
541	int			 fd;
542	struct sockaddr_storage	 ss;
543	in_port_t		 port;
544	int			 backlog;
545	struct timeval		 timeout;
546	struct event		 ev;
547	struct smtpd		*env;
548	char			 ssl_cert_name[PATH_MAX];
549	struct ssl		*ssl;
550	void			*ssl_ctx;
551	TAILQ_ENTRY(listener)	 entry;
552};
553
554struct session_auth_req {
555	u_int64_t	session_id;
556	char		buffer[MAX_LINE_SIZE];
557};
558
559struct session_auth_reply {
560	u_int64_t	session_id;
561	u_int8_t	value;
562};
563
564enum session_flags {
565	F_EHLO		= 0x1,
566	F_QUIT		= 0x2,
567	F_8BITMIME	= 0x4,
568	F_SECURE	= 0x8,
569	F_AUTHENTICATED	= 0x10
570};
571
572struct session {
573	SPLAY_ENTRY(session)		 s_nodes;
574	u_int64_t			 s_id;
575
576	enum session_flags		 s_flags;
577	enum session_state		 s_state;
578	time_t				 s_tm;
579	int				 s_fd;
580	struct sockaddr_storage		 s_ss;
581	char				 s_hostname[MAXHOSTNAMELEN];
582	struct event			 s_ev;
583	struct bufferevent		*s_bev;
584	struct listener			*s_l;
585	struct smtpd			*s_env;
586	void				*s_ssl;
587	u_char				*s_buf;
588	int				 s_buflen;
589	struct timeval			 s_tv;
590	struct message			 s_msg;
591};
592
593struct smtpd {
594#define SMTPD_OPT_VERBOSE			 0x00000001
595#define SMTPD_OPT_NOACTION			 0x00000002
596	u_int32_t				 sc_opts;
597#define SMTPD_CONFIGURING			 0x00000001
598#define SMTPD_EXITING				 0x00000002
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
618/* aliases.c */
619int aliases_exist(struct smtpd *, char *);
620int aliases_get(struct smtpd *, struct aliaseslist *, char *);
621int aliases_virtual_exist(struct smtpd *, struct path *);
622int aliases_virtual_get(struct smtpd *, struct aliaseslist *, struct path *);
623int alias_parse(struct alias *, char *);
624
625
626/* log.c */
627void		log_init(int);
628void		log_warn(const char *, ...)
629    __attribute__ ((format (printf, 1, 2)));
630void		log_warnx(const char *, ...)
631    __attribute__ ((format (printf, 1, 2)));
632void		log_info(const char *, ...)
633    __attribute__ ((format (printf, 1, 2)));
634void		log_debug(const char *, ...)
635    __attribute__ ((format (printf, 1, 2)));
636__dead void	fatal(const char *);
637__dead void	fatalx(const char *);
638
639
640/* buffer.c */
641struct buf	*buf_open(size_t);
642struct buf	*buf_dynamic(size_t, size_t);
643int		 buf_add(struct buf *, void *, size_t);
644void		*buf_reserve(struct buf *, size_t);
645int		 buf_close(struct msgbuf *, struct buf *);
646void		 buf_free(struct buf *);
647void		 msgbuf_init(struct msgbuf *);
648void		 msgbuf_clear(struct msgbuf *);
649int		 msgbuf_write(struct msgbuf *);
650
651
652/* dns.c */
653size_t getmxbyname(char *, char ***);
654
655
656/* forward.c */
657int forwards_get(struct aliaseslist *, char *);
658
659
660/* imsg.c */
661void	 imsg_init(struct imsgbuf *, int, void (*)(int, short, void *));
662ssize_t	 imsg_read(struct imsgbuf *);
663ssize_t	 imsg_get(struct imsgbuf *, struct imsg *);
664int	 imsg_compose(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t,
665	    int, void *, u_int16_t);
666int	 imsg_composev(struct imsgbuf *, enum imsg_type, u_int32_t,
667	    pid_t, int, const struct iovec *, int);
668int	 imsg_compose_fds(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t,
669	    void *, u_int16_t, int, ...);
670struct buf *imsg_create(struct imsgbuf *, enum imsg_type, u_int32_t, pid_t,
671	    u_int16_t);
672int	 imsg_add(struct buf *, void *, u_int16_t);
673int	 imsg_append(struct imsgbuf *, struct buf *);
674int	 imsg_close(struct imsgbuf *, struct buf *);
675void	 imsg_free(struct imsg *);
676void	 imsg_event_add(struct imsgbuf *); /* needs to be provided externally */
677int	 imsg_get_fd(struct imsgbuf *, struct imsg *);
678int	 imsg_flush(struct imsgbuf *);
679void	 imsg_clear(struct imsgbuf *);
680
681/* lka.c */
682pid_t		 lka(struct smtpd *);
683
684/* mfa.c */
685pid_t		 mfa(struct smtpd *);
686int		 msg_cmp(struct message *, struct message *);
687SPLAY_PROTOTYPE(msgtree, message, nodes, msg_cmp);
688
689/* queue.c */
690pid_t		 queue(struct smtpd *);
691u_int64_t	 queue_generate_id(void);
692int		 batch_cmp(struct batch *, struct batch *);
693struct batch    *batch_by_id(struct smtpd *, u_int64_t);
694struct message	*message_by_id(struct smtpd *, struct batch *, u_int64_t);
695int		 queue_remove_batch_message(struct smtpd *, struct batch *, struct message *);
696
697/* mda.c */
698pid_t		 mda(struct smtpd *);
699int		 mdaproc_cmp(struct mdaproc *, struct mdaproc *);
700SPLAY_PROTOTYPE(mdaproctree, mdaproc, mdaproc_nodes, mdaproc_cmp);
701
702/* mta.c */
703pid_t		 mta(struct smtpd *);
704
705/* control.c */
706pid_t		 control(struct smtpd *);
707void		 session_socket_blockmode(int, enum blockmodes);
708
709/* runner.c */
710pid_t		 runner(struct smtpd *);
711SPLAY_PROTOTYPE(batchtree, batch, b_nodes, batch_cmp);
712
713
714/* smtp.c */
715pid_t		 smtp(struct smtpd *);
716void		 smtp_listener_setup(struct smtpd *, struct listener *);
717
718/* smtp_session.c */
719void		 session_init(struct listener *, struct session *);
720int		 session_cmp(struct session *, struct session *);
721void		 session_pickup(struct session *, struct submit_status *);
722void		 session_destroy(struct session *);
723SPLAY_PROTOTYPE(sessiontree, session, s_nodes, session_cmp);
724
725/* store.c */
726int store_write_header(struct batch *, struct message *, FILE *);
727int store_write_message(struct batch *, struct message *);
728int store_write_daemon(struct batch *, struct message *);
729int store_message(struct batch *, struct message *,
730    int (*)(struct batch *, struct message *));
731
732/* config.c */
733#define		 PURGE_LISTENERS	0x01
734#define		 PURGE_MAPS		0x02
735#define		 PURGE_RULES		0x04
736#define		 PURGE_SSL		0x08
737#define		 PURGE_EVERYTHING	0xff
738void		 purge_config(struct smtpd *, u_int8_t);
739void		 unconfigure(struct smtpd *);
740void		 configure(struct smtpd *);
741void		 init_peers(struct smtpd *);
742void		 config_peers(struct smtpd *, struct peer *, u_int);
743
744/* parse.y */
745int		 parse_config(struct smtpd *, const char *, int);
746int		 cmdline_symset(char *);
747
748/* ssl.c */
749void	 ssl_init(void);
750void	 ssl_transaction(struct session *);
751
752void	 ssl_session_init(struct session *);
753void	 ssl_session_destroy(struct session *);
754int	 ssl_load_certfile(struct smtpd *, const char *);
755void	 ssl_setup(struct smtpd *, struct listener *);
756int	 ssl_cmp(struct ssl *, struct ssl *);
757SPLAY_PROTOTYPE(ssltree, ssl, ssl_nodes, ssl_cmp);
758
759/* ssl_privsep.c */
760int	 ssl_ctx_use_private_key(void *, char *, off_t);
761int	 ssl_ctx_use_certificate_chain(void *, char *, off_t);
762
763/* smtpd.c */
764struct map	*map_find(struct smtpd *, objid_t);
765struct map	*map_findbyname(struct smtpd *, const char *);
766
767/* util.c */
768int		bsnprintf(char *, size_t, const char *, ...)
769    __attribute__ ((format (printf, 3, 4)));
770int		safe_fclose(FILE *);
771