smtpd.h revision 1.141
1/*	$OpenBSD: smtpd.h,v 1.141 2009/09/12 09:38:45 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#include			 <imsg.h>
21
22#ifndef nitems
23#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
24#endif
25
26#define IMSG_SIZE_CHECK(p) do {					\
27	if (IMSG_DATA_SIZE(&imsg) != sizeof(*p))		\
28		fatalx("bad length imsg received");		\
29} while (0)
30#define IMSG_DATA_SIZE(imsg)	((imsg)->hdr.len - IMSG_HEADER_SIZE)
31
32#define CONF_FILE		 "/etc/mail/smtpd.conf"
33#define MAX_LISTEN		 16
34#define PROC_COUNT		 9
35#define MAX_NAME_SIZE		 64
36
37#define MAX_HOPS_COUNT		 100
38
39/* sizes include the tailing '\0' */
40#define MAX_LINE_SIZE		 1024
41#define MAX_LOCALPART_SIZE	 65
42#define MAX_DOMAINPART_SIZE	 MAXHOSTNAMELEN
43#define MAX_ID_SIZE		 64
44
45/* return and forward path size */
46#define MAX_PATH_SIZE		 256
47
48/*#define SMTPD_CONNECT_TIMEOUT	 (60)*/
49#define SMTPD_CONNECT_TIMEOUT	 (10)
50#define SMTPD_QUEUE_INTERVAL	 (15 * 60)
51#define SMTPD_QUEUE_MAXINTERVAL	 (4 * 60 * 60)
52#define SMTPD_QUEUE_EXPIRY	 (4 * 24 * 60 * 60)
53#define SMTPD_USER		 "_smtpd"
54#define SMTPD_SOCKET		 "/var/run/smtpd.sock"
55#define SMTPD_BANNER		 "220 %s ESMTP OpenSMTPD"
56#define SMTPD_SESSION_TIMEOUT	 300
57#define SMTPD_BACKLOG		 5
58
59#define	PATH_MAILLOCAL		"/usr/libexec/mail.local"
60#define	PATH_SMTPCTL		"/usr/sbin/smtpctl"
61
62#define	DIRHASH_BUCKETS		 4096
63
64#define PATH_SPOOL		"/var/spool/smtpd"
65
66#define PATH_ENQUEUE		"/enqueue"
67#define PATH_INCOMING		"/incoming"
68#define PATH_QUEUE		"/queue"
69#define PATH_PURGE		"/purge"
70
71#define PATH_MESSAGE		"/message"
72#define PATH_ENVELOPES		"/envelopes"
73
74#define PATH_RUNQUEUE		"/runqueue"
75#define PATH_RUNQUEUEHIGH	"/runqueue-high"
76#define PATH_RUNQUEUELOW	"/runqueue-low"
77
78#define PATH_OFFLINE		"/offline"
79#define PATH_BOUNCE		"/bounce"
80
81/* number of MX records to lookup */
82#define MAX_MX_COUNT		10
83
84/* max response delay under flood conditions */
85#define MAX_RESPONSE_DELAY	60
86
87/* how many responses per state are undelayed */
88#define FAST_RESPONSES		2
89
90/* rfc5321 limits */
91#define	SMTP_DATALINE_MAX	1000
92#define	SMTP_CMDLINE_MAX	512
93#define	SMTP_ANYLINE_MAX	SMTP_DATALINE_MAX
94
95#define F_STARTTLS		 0x01
96#define F_SMTPS			 0x02
97#define F_AUTH			 0x04
98#define F_SSL			(F_SMTPS|F_STARTTLS)
99
100#define F_SCERT			0x01
101#define F_CCERT			0x02
102
103#define ADVERTISE_TLS(s) \
104	((s)->s_l->flags & F_STARTTLS && !((s)->s_flags & F_SECURE))
105
106#define ADVERTISE_AUTH(s) \
107	((s)->s_l->flags & F_AUTH && (s)->s_flags & F_SECURE && \
108	 !((s)->s_flags & F_AUTHENTICATED))
109
110struct netaddr {
111	struct sockaddr_storage ss;
112	int bits;
113};
114
115struct relayhost {
116	u_int8_t flags;
117	char hostname[MAXHOSTNAMELEN];
118	u_int16_t port;
119	char cert[PATH_MAX];
120};
121
122struct mxhost {
123	TAILQ_ENTRY(mxhost)	 entry;
124	struct sockaddr_storage ss;
125};
126
127enum imsg_type {
128	IMSG_NONE,
129	IMSG_CTL_OK,		/* answer to smtpctl requests */
130	IMSG_CTL_FAIL,
131	IMSG_CTL_SHUTDOWN,
132	IMSG_CONF_START,
133	IMSG_CONF_SSL,
134	IMSG_CONF_SSL_CERT,
135	IMSG_CONF_SSL_KEY,
136	IMSG_CONF_LISTENER,
137	IMSG_CONF_MAP,
138	IMSG_CONF_MAP_CONTENT,
139	IMSG_CONF_RULE,
140	IMSG_CONF_RULE_SOURCE,
141	IMSG_CONF_CONDITION,
142	IMSG_CONF_OPTION,
143	IMSG_CONF_END,
144	IMSG_CONF_RELOAD,
145	IMSG_LKA_MAIL,
146	IMSG_LKA_RCPT,
147	IMSG_LKA_SECRET,
148	IMSG_MDA_FINALIZE,
149	IMSG_MFA_RCPT,
150	IMSG_MFA_MAIL,
151
152	IMSG_QUEUE_CREATE_MESSAGE,
153	IMSG_QUEUE_SUBMIT_ENVELOPE,
154	IMSG_QUEUE_COMMIT_ENVELOPES,
155	IMSG_QUEUE_REMOVE_MESSAGE,
156	IMSG_QUEUE_COMMIT_MESSAGE,
157	IMSG_QUEUE_TEMPFAIL,
158	IMSG_QUEUE_STATS,
159
160	IMSG_QUEUE_REMOVE_SUBMISSION,
161	IMSG_QUEUE_MESSAGE_UPDATE,
162	IMSG_QUEUE_MESSAGE_FD,
163	IMSG_QUEUE_MESSAGE_FILE,
164
165	IMSG_RUNNER_UPDATE_ENVELOPE,
166	IMSG_RUNNER_STATS,
167	IMSG_RUNNER_SCHEDULE,
168
169	IMSG_BATCH_CREATE,
170	IMSG_BATCH_APPEND,
171	IMSG_BATCH_CLOSE,
172
173	IMSG_PARENT_ENQUEUE_OFFLINE,
174	IMSG_PARENT_FORWARD_OPEN,
175	IMSG_PARENT_MAILBOX_OPEN,
176	IMSG_PARENT_MESSAGE_OPEN,
177	IMSG_PARENT_MAILDIR_RENAME,
178	IMSG_PARENT_MAILDIR_FAIL,
179	IMSG_PARENT_STATS,
180
181	IMSG_PARENT_AUTHENTICATE,
182	IMSG_PARENT_SEND_CONFIG,
183
184	IMSG_MDA_PAUSE,
185	IMSG_MTA_PAUSE,
186	IMSG_SMTP_PAUSE,
187	IMSG_SMTP_STATS,
188
189	IMSG_MDA_RESUME,
190	IMSG_MTA_RESUME,
191	IMSG_SMTP_RESUME,
192
193	IMSG_STATS,
194
195	IMSG_SMTP_ENQUEUE,
196
197	IMSG_DNS_A,
198	IMSG_DNS_A_END,
199	IMSG_DNS_MX,
200	IMSG_DNS_PTR
201};
202
203enum blockmodes {
204	BM_NORMAL,
205	BM_NONBLOCK
206};
207
208struct imsgev {
209	struct imsgbuf		 ibuf;
210	void			(*handler)(int, short, void *);
211	struct event		 ev;
212	void			*data;
213	short			 events;
214};
215
216struct ctl_conn {
217	TAILQ_ENTRY(ctl_conn)	 entry;
218	u_int8_t		 flags;
219#define CTL_CONN_NOTIFY		 0x01
220	struct imsgev		 iev;
221};
222TAILQ_HEAD(ctl_connlist, ctl_conn);
223
224typedef u_int32_t		 objid_t;
225
226struct ctl_id {
227	objid_t		 id;
228	char		 name[MAX_NAME_SIZE];
229};
230
231enum smtp_proc_type {
232	PROC_PARENT = 0,
233	PROC_SMTP,
234	PROC_MFA,
235	PROC_LKA,
236	PROC_QUEUE,
237	PROC_MDA,
238	PROC_MTA,
239	PROC_CONTROL,
240	PROC_RUNNER,
241} smtpd_process;
242
243struct peer {
244	enum smtp_proc_type	 id;
245	void			(*cb)(int, short, void *);
246};
247
248enum map_type {
249	T_SINGLE,
250	T_LIST,
251	T_HASH
252};
253
254enum map_src {
255	S_NONE,
256	S_DYN,
257	S_DNS,
258	S_FILE,
259	S_DB,
260	S_EXT
261};
262
263enum mapel_type {
264	ME_STRING,
265	ME_NET,
266	ME_NETMASK
267};
268
269struct mapel {
270	TAILQ_ENTRY(mapel)		 me_entry;
271	union mapel_data {
272		char			 med_string[MAX_LINE_SIZE];
273		struct netaddr		 med_addr;
274	}				 me_key;
275	union mapel_data		 me_val;
276};
277
278struct map {
279	TAILQ_ENTRY(map)		 m_entry;
280#define F_USED				 0x01
281#define F_DYNAMIC			 0x02
282	u_int8_t			 m_flags;
283	char				 m_name[MAX_LINE_SIZE];
284	objid_t				 m_id;
285	enum map_type			 m_type;
286	enum mapel_type			 m_eltype;
287	enum map_src			 m_src;
288	char				 m_config[MAXPATHLEN];
289	TAILQ_HEAD(mapel_list, mapel)	 m_contents;
290};
291
292enum cond_type {
293	C_ALL,
294	C_NET,
295	C_DOM
296};
297
298struct cond {
299	TAILQ_ENTRY(cond)		 c_entry;
300	objid_t				 c_map;
301	enum cond_type			 c_type;
302	struct map			*c_match;
303};
304
305enum opt_type {
306	O_RWUSER,			/* rewrite user */
307	O_RWDOMAIN,			/* rewrite domain */
308};
309
310struct opt {
311	TAILQ_ENTRY(opt)		 o_entry;
312	enum opt_type			 o_type;
313};
314
315enum action_type {
316	A_INVALID,
317	A_RELAY,
318	A_RELAYVIA,
319	A_MAILDIR,
320	A_MBOX,
321	A_FILENAME,
322	A_EXT
323};
324#define IS_MAILBOX(x)	((x) == A_MAILDIR || (x) == A_MBOX || (x) == A_FILENAME)
325#define IS_RELAY(x)	((x) == A_RELAY || (x) == A_RELAYVIA)
326#define IS_EXT(x)	((x) == A_EXT)
327
328struct rule {
329	TAILQ_ENTRY(rule)		 r_entry;
330	int				 r_accept;
331	struct map			*r_sources;
332	TAILQ_HEAD(condlist, cond)	 r_conditions;
333	enum action_type		 r_action;
334	union rule_dest {
335		char			 path[MAXPATHLEN];
336		struct relayhost       	 relayhost;
337#define	MAXCOMMANDLEN	256
338		char			 command[MAXCOMMANDLEN];
339	}				 r_value;
340	TAILQ_HEAD(optlist, opt)	 r_options;
341};
342
343enum path_flags {
344	F_PATH_ALIAS = 0x1,
345	F_PATH_VIRTUAL = 0x2,
346	F_PATH_EXPANDED = 0x4,
347	F_PATH_NOFORWARD = 0x8,
348	F_PATH_FORWARDED = 0x10,
349	F_PATH_ACCOUNT = 0x20,
350	F_PATH_AUTHENTICATED = 0x40,
351};
352
353struct path {
354	TAILQ_ENTRY(path)		 entry;
355	struct rule			 rule;
356	enum path_flags			 flags;
357	u_int8_t			 forwardcnt;
358	char				 user[MAX_LOCALPART_SIZE];
359	char				 domain[MAX_DOMAINPART_SIZE];
360	char				 pw_name[MAXLOGNAME];
361	union path_data {
362		char filename[MAXPATHLEN];
363		char filter[MAXPATHLEN];
364	}				 u;
365};
366
367enum alias_type {
368	ALIAS_USERNAME,
369	ALIAS_FILENAME,
370	ALIAS_FILTER,
371	ALIAS_INCLUDE,
372	ALIAS_ADDRESS
373};
374
375struct alias {
376	TAILQ_ENTRY(alias)		entry;
377	enum alias_type			 type;
378	union alias_data {
379		char username[MAXLOGNAME];
380		char filename[MAXPATHLEN];
381		char filter[MAXPATHLEN];
382		struct path path;
383	}                                   u;
384};
385TAILQ_HEAD(aliaseslist, alias);
386
387enum message_type {
388	T_MDA_MESSAGE		= 0x1,
389	T_MTA_MESSAGE		= 0x2,
390	T_BOUNCE_MESSAGE	= 0x4
391};
392
393enum message_status {
394	S_MESSAGE_LOCKFAILURE	= 0x1,
395	S_MESSAGE_PERMFAILURE	= 0x2,
396	S_MESSAGE_TEMPFAILURE	= 0x4,
397	S_MESSAGE_REJECTED	= 0x8,
398	S_MESSAGE_ACCEPTED	= 0x10,
399	S_MESSAGE_RETRY		= 0x20,
400	S_MESSAGE_EDNS		= 0x40,
401	S_MESSAGE_ECONNECT	= 0x80
402};
403
404enum message_flags {
405	F_MESSAGE_RESOLVED	= 0x1,
406	F_MESSAGE_SCHEDULED	= 0x2,
407	F_MESSAGE_PROCESSING	= 0x4,
408	F_MESSAGE_AUTHENTICATED	= 0x8,
409	F_MESSAGE_ENQUEUED	= 0x10,
410	F_MESSAGE_FORCESCHEDULE	= 0x20,
411	F_MESSAGE_BOUNCE	= 0x40
412};
413
414struct message {
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
435	time_t				 creation;
436	time_t				 lasttry;
437	u_int8_t			 retry;
438	enum message_flags		 flags;
439	enum message_status		 status;
440};
441
442enum batch_status {
443	S_BATCH_PERMFAILURE	= 0x1,
444	S_BATCH_TEMPFAILURE	= 0x2,
445	S_BATCH_REJECTED	= 0x4,
446	S_BATCH_ACCEPTED	= 0x8,
447	S_BATCH_RETRY		= 0x10,
448	S_BATCH_EDNS		= 0x20,
449	S_BATCH_ECONNECT	= 0x40
450};
451
452enum batch_type {
453	T_MDA_BATCH		= 0x1,
454	T_MTA_BATCH		= 0x2,
455	T_BOUNCE_BATCH		= 0x4
456};
457
458struct batch {
459	SPLAY_ENTRY(batch)	 b_nodes;
460
461	u_int64_t		 id;
462	enum batch_type		 type;
463	struct rule		 rule;
464
465	struct smtpd		*env;
466
467	char			 message_id[MAX_ID_SIZE];
468	char			 hostname[MAXHOSTNAMELEN];
469	char			 errorline[MAX_LINE_SIZE];
470
471	struct session		*sessionp;
472
473	struct message		 message;
474	struct message		*messagep;
475	FILE			*messagefp;
476	TAILQ_HEAD(, message)	 messages;
477
478	int			 mboxfd;
479	int			 datafd;
480	int			 cleanup_parent;
481
482	enum batch_status	 status;
483};
484
485enum child_type {
486	CHILD_INVALID,
487	CHILD_DAEMON,
488	CHILD_MDA,
489	CHILD_ENQUEUE_OFFLINE
490};
491
492struct child {
493	SPLAY_ENTRY(child)	 entry;
494
495	pid_t			 pid;
496	enum child_type		 type;
497	enum smtp_proc_type	 title;
498	struct batch		 mda_batch;
499};
500
501enum session_state {
502	S_INIT = 0,
503	S_GREETED,
504	S_TLS,
505	S_AUTH_INIT,
506	S_AUTH_USERNAME,
507	S_AUTH_PASSWORD,
508	S_AUTH_FINALIZE,
509	S_HELO,
510	S_MAIL_MFA,
511	S_MAIL_QUEUE,
512	S_MAIL,
513	S_RCPT_MFA,
514	S_RCPT,
515	S_DATA,
516	S_DATA_QUEUE,
517	S_DATACONTENT,
518	S_DONE,
519	S_QUIT
520};
521#define STATE_COUNT	18
522
523struct ssl {
524	SPLAY_ENTRY(ssl)	 ssl_nodes;
525	char			 ssl_name[PATH_MAX];
526	char			*ssl_cert;
527	off_t			 ssl_cert_len;
528	char			*ssl_key;
529	off_t			 ssl_key_len;
530	u_int8_t		 flags;
531};
532
533struct listener {
534	u_int8_t		 flags;
535	int			 fd;
536	struct sockaddr_storage	 ss;
537	in_port_t		 port;
538	struct timeval		 timeout;
539	struct event		 ev;
540	struct smtpd		*env;
541	char			 ssl_cert_name[PATH_MAX];
542	struct ssl		*ssl;
543	void			*ssl_ctx;
544	TAILQ_ENTRY(listener)	 entry;
545};
546
547struct auth {
548	u_int64_t	 id;
549	char		 user[MAXLOGNAME];
550	char		 pass[MAX_LINE_SIZE];
551	int		 success;
552};
553
554enum session_flags {
555	F_EHLO		= 0x1,
556	F_QUIT		= 0x2,
557	F_8BITMIME	= 0x4,
558	F_SECURE	= 0x8,
559	F_AUTHENTICATED	= 0x10,
560	F_PEERHASTLS	= 0x20,
561	F_PEERHASAUTH	= 0x40,
562	F_WRITEONLY	= 0x80
563};
564
565struct session {
566	SPLAY_ENTRY(session)		 s_nodes;
567	u_int64_t			 s_id;
568
569	enum session_flags		 s_flags;
570	enum session_state		 s_state;
571	int				 s_fd;
572	struct sockaddr_storage		 s_ss;
573	char				 s_hostname[MAXHOSTNAMELEN];
574	struct event			 s_ev;
575	struct bufferevent		*s_bev;
576	struct listener			*s_l;
577	struct smtpd			*s_env;
578	void				*s_ssl;
579	u_char				*s_buf;
580	int				 s_buflen;
581	struct timeval			 s_tv;
582	struct message			 s_msg;
583	short				 s_nresp[STATE_COUNT];
584	size_t				 rcptcount;
585	long				 s_datalen;
586
587	struct auth			 s_auth;
588
589	char				 credentials[MAX_LINE_SIZE];
590
591	struct batch			*batch;
592	TAILQ_HEAD(mxhostlist, mxhost) mxhosts;
593
594	FILE				*datafp;
595	int				 mboxfd;
596	int				 messagefd;
597};
598
599struct smtpd {
600	char					 sc_conffile[MAXPATHLEN];
601
602#define SMTPD_OPT_VERBOSE			 0x00000001
603#define SMTPD_OPT_NOACTION			 0x00000002
604	u_int32_t				 sc_opts;
605#define SMTPD_CONFIGURING			 0x00000001
606#define SMTPD_EXITING				 0x00000002
607#define SMTPD_MDA_PAUSED		       	 0x00000004
608#define SMTPD_MTA_PAUSED		       	 0x00000008
609#define SMTPD_SMTP_PAUSED		       	 0x00000010
610	u_int32_t				 sc_flags;
611	struct timeval				 sc_qintval;
612	u_int32_t				 sc_maxconn;
613	struct event				 sc_ev;
614	int					 *sc_pipes[PROC_COUNT]
615							[PROC_COUNT];
616	struct imsgev				*sc_ievs[PROC_COUNT];
617	int					 sc_instances[PROC_COUNT];
618	int					 sc_instance;
619	char					*sc_title[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, *sc_maps_reload;
624	TAILQ_HEAD(rulelist, rule)		*sc_rules, *sc_rules_reload;
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(childtree, child)		 children;
631	SPLAY_HEAD(lkatree, lkasession)		 lka_sessions;
632
633	struct stats				*stats;
634};
635
636struct s_parent {
637	time_t		start;
638};
639
640struct s_queue {
641	size_t		inserts_local;
642	size_t		inserts_remote;
643};
644
645struct s_runner {
646	size_t		active;
647};
648
649struct s_session {
650	size_t		sessions;
651	size_t		sessions_active;
652
653	size_t		smtps;
654	size_t		smtps_active;
655
656	size_t		starttls;
657	size_t		starttls_active;
658
659	size_t		read_error;
660	size_t		read_timeout;
661	size_t		read_eof;
662	size_t		write_error;
663	size_t		write_timeout;
664	size_t		write_eof;
665	size_t		toofast;
666	size_t		tempfail;
667	size_t		linetoolong;
668	size_t		cmdlinetoolong;
669	size_t		datalinetoolong;
670	size_t		delays;
671};
672
673struct s_mda {
674	size_t		write_error;
675};
676
677struct stats {
678	struct s_parent		 parent;
679	struct s_queue		 queue;
680	struct s_runner		 runner;
681	struct s_session	 mta;
682	struct s_mda		 mda;
683	struct s_session	 smtp;
684};
685
686struct sched {
687	int			fd;
688	char			mid[MAX_ID_SIZE];
689	int			ret;
690};
691
692struct reload {
693	int			fd;
694	int			ret;
695};
696
697struct submit_status {
698	u_int64_t			 id;
699	int				 code;
700	union submit_path {
701		struct path		 path;
702		char			 msgid[MAX_ID_SIZE];
703		char			 errormsg[MAX_LINE_SIZE];
704	}				 u;
705	enum message_flags		 flags;
706	struct sockaddr_storage		 ss;
707	struct message			 msg;
708};
709
710struct forward_req {
711	u_int64_t			 id;
712	u_int8_t			 status;
713	char				 pw_name[MAXLOGNAME];
714};
715
716struct dns {
717	u_int64_t		 id;
718	char			 host[MAXHOSTNAMELEN];
719	int			 port;
720	int			 error;
721	struct sockaddr_storage	 ss;
722	struct smtpd		*env;
723	struct dns		*next;
724};
725
726struct secret {
727	u_int64_t		 id;
728	char			 host[MAXHOSTNAMELEN];
729	char			 secret[MAX_LINE_SIZE];
730};
731
732enum lkasession_flags {
733	F_ERROR		= 0x1
734};
735
736struct lkasession {
737	SPLAY_ENTRY(lkasession)		 nodes;
738	u_int64_t			 id;
739
740	struct path			 path;
741	struct aliaseslist		 aliaseslist;
742	u_int8_t			 iterations;
743	u_int32_t			 pending;
744	enum lkasession_flags		 flags;
745	struct message			 message;
746	struct submit_status		 ss;
747};
748
749/* aliases.c */
750int aliases_exist(struct smtpd *, char *);
751int aliases_get(struct smtpd *, struct aliaseslist *, char *);
752int aliases_virtual_exist(struct smtpd *, struct path *);
753int aliases_virtual_get(struct smtpd *, struct aliaseslist *, struct path *);
754int alias_parse(struct alias *, char *);
755
756/* authenticate.c */
757int authenticate_user(char *, char *);
758
759/* bounce.c */
760void bounce_process(struct smtpd *, struct message *);
761int bounce_session(struct smtpd *, int, struct message *);
762int bounce_session_switch(struct smtpd *, FILE *, enum session_state *, char *,
763	struct message *);
764
765/* log.c */
766void		log_init(int);
767void		log_warn(const char *, ...)
768    __attribute__ ((format (printf, 1, 2)));
769void		log_warnx(const char *, ...)
770    __attribute__ ((format (printf, 1, 2)));
771void		log_info(const char *, ...)
772    __attribute__ ((format (printf, 1, 2)));
773void		log_debug(const char *, ...)
774    __attribute__ ((format (printf, 1, 2)));
775__dead void	fatal(const char *);
776__dead void	fatalx(const char *);
777
778
779/* dns.c */
780void		 dns_query_a(struct smtpd *, char *, int, u_int64_t);
781void		 dns_query_mx(struct smtpd *, char *, int, u_int64_t);
782void		 dns_query_ptr(struct smtpd *, struct sockaddr_storage *,
783		     u_int64_t);
784void		 dns_async(struct smtpd *, struct imsgev *, int,
785		     struct dns *);
786
787
788/* forward.c */
789int forwards_get(int, struct aliaseslist *);
790
791/* smtpd.c */
792int	 child_cmp(struct child *, struct child *);
793SPLAY_PROTOTYPE(childtree, child, entry, child_cmp);
794void	 imsg_event_add(struct imsgev *);
795int	 imsg_compose_event(struct imsgev *, u_int16_t, u_int32_t, pid_t,
796	    int, void *, u_int16_t);
797
798/* lka.c */
799pid_t		 lka(struct smtpd *);
800int		 lkasession_cmp(struct lkasession *, struct lkasession *);
801SPLAY_PROTOTYPE(lkatree, lkasession, nodes, lkasession_cmp);
802
803/* mfa.c */
804pid_t		 mfa(struct smtpd *);
805int		 msg_cmp(struct message *, struct message *);
806
807/* queue.c */
808pid_t		 queue(struct smtpd *);
809u_int64_t	 queue_generate_id(void);
810int		 queue_remove_batch_message(struct smtpd *, struct batch *,
811 		     struct message *);
812int		 queue_load_envelope(struct message *, char *);
813int		 queue_update_envelope(struct message *);
814int		 queue_remove_envelope(struct message *);
815int		 batch_cmp(struct batch *, struct batch *);
816struct batch    *batch_by_id(struct smtpd *, u_int64_t);
817struct message	*message_by_id(struct smtpd *, struct batch *, u_int64_t);
818u_int16_t	 queue_hash(char *);
819
820/* queue_shared.c */
821int		 queue_create_layout_message(char *, char *);
822void		 queue_delete_layout_message(char *, char *);
823int		 queue_record_layout_envelope(char *, struct message *);
824int		 queue_remove_layout_envelope(char *, struct message *);
825int		 queue_commit_layout_message(char *, struct message *);
826int		 queue_open_layout_messagefile(char *, struct message *);
827int		 enqueue_create_layout(char *);
828void		 enqueue_delete_message(char *);
829int		 enqueue_record_envelope(struct message *);
830int		 enqueue_remove_envelope(struct message *);
831int		 enqueue_commit_message(struct message *);
832int		 enqueue_open_messagefile(struct message *);
833int		 bounce_create_layout(char *, struct message *);
834void		 bounce_delete_message(char *);
835int		 bounce_record_envelope(struct message *);
836int		 bounce_remove_envelope(struct message *);
837int		 bounce_commit_message(struct message *);
838int		 bounce_record_message(struct message *);
839int		 queue_create_incoming_layout(char *);
840void		 queue_delete_incoming_message(char *);
841int		 queue_record_incoming_envelope(struct message *);
842int		 queue_remove_incoming_envelope(struct message *);
843int		 queue_commit_incoming_message(struct message *);
844int		 queue_open_incoming_message_file(struct message *);
845int		 queue_open_message_file(char *msgid);
846void		 queue_message_update(struct message *);
847void		 queue_delete_message(char *);
848struct qwalk	*qwalk_new(char *);
849int		 qwalk(struct qwalk *, char *);
850void		 qwalk_close(struct qwalk *);
851void		 show_queue(char *, int);
852
853u_int16_t	queue_hash(char *);
854
855/* map.c */
856char		*map_dblookup(struct smtpd *, char *, char *);
857
858/* mda.c */
859pid_t		 mda(struct smtpd *);
860
861/* mta.c */
862pid_t		 mta(struct smtpd *);
863
864/* control.c */
865pid_t		 control(struct smtpd *);
866void		 session_socket_blockmode(int, enum blockmodes);
867
868/* enqueue.c */
869int		 enqueue(int, char **);
870int		 enqueue_offline(int, char **);
871
872/* runner.c */
873pid_t		 runner(struct smtpd *);
874void		 message_reset_flags(struct message *);
875SPLAY_PROTOTYPE(batchtree, batch, b_nodes, batch_cmp);
876
877
878/* smtp.c */
879pid_t		 smtp(struct smtpd *);
880
881/* smtp_session.c */
882void		 session_init(struct listener *, struct session *);
883int		 session_cmp(struct session *, struct session *);
884void		 session_pickup(struct session *, struct submit_status *);
885void		 session_destroy(struct session *);
886void		 session_respond(struct session *, char *, ...)
887		    __attribute__ ((format (printf, 2, 3)));
888void		 session_bufferevent_new(struct session *);
889
890SPLAY_PROTOTYPE(sessiontree, session, s_nodes, session_cmp);
891
892/* config.c */
893#define		 PURGE_LISTENERS	0x01
894#define		 PURGE_MAPS		0x02
895#define		 PURGE_RULES		0x04
896#define		 PURGE_SSL		0x08
897#define		 PURGE_EVERYTHING	0xff
898void		 purge_config(struct smtpd *, u_int8_t);
899void		 unconfigure(struct smtpd *);
900void		 configure(struct smtpd *);
901void		 init_pipes(struct smtpd *);
902void		 config_pipes(struct smtpd *, struct peer *, u_int);
903void		 config_peers(struct smtpd *, struct peer *, u_int);
904
905/* parse.y */
906int		 parse_config(struct smtpd *, const char *, int);
907int		 cmdline_symset(char *);
908
909/* ssl.c */
910void	 ssl_init(void);
911void	 ssl_transaction(struct session *);
912
913void	 ssl_session_init(struct session *);
914void	 ssl_session_destroy(struct session *);
915int	 ssl_load_certfile(struct smtpd *, const char *, u_int8_t);
916void	 ssl_setup(struct smtpd *, struct listener *);
917int	 ssl_cmp(struct ssl *, struct ssl *);
918SPLAY_PROTOTYPE(ssltree, ssl, ssl_nodes, ssl_cmp);
919
920/* ssl_privsep.c */
921int	 ssl_ctx_use_private_key(void *, char *, off_t);
922int	 ssl_ctx_use_certificate_chain(void *, char *, off_t);
923
924/* map.c */
925struct map	*map_find(struct smtpd *, objid_t);
926struct map	*map_findbyname(struct smtpd *, const char *);
927
928/* util.c */
929typedef struct arglist arglist;
930struct arglist {
931	char    **list;
932	u_int   num;
933	u_int   nalloc;
934};
935void		 addargs(arglist *, char *, ...)
936		     __attribute__((format(printf, 2, 3)));
937int		 bsnprintf(char *, size_t, const char *, ...)
938    __attribute__ ((format (printf, 3, 4)));
939int		 safe_fclose(FILE *);
940int		 hostname_match(char *, char *);
941int		 recipient_to_path(struct path *, char *);
942int		 valid_localpart(char *);
943int		 valid_domainpart(char *);
944char		*ss_to_text(struct sockaddr_storage *);
945int		 valid_message_id(char *);
946int		 valid_message_uid(char *);
947char		*time_to_text(time_t);
948int		 secure_file(int, char *, struct passwd *, int);
949void		 lowercase(char *, char *, size_t);
950void		 message_set_errormsg(struct message *, char *, ...);
951char		*message_get_errormsg(struct message *);
952