smtpd.h revision 1.458
1169689Skan/*	$OpenBSD: smtpd.h,v 1.458 2014/04/30 08:23:43 reyk Exp $	*/
2169689Skan
3169689Skan/*
4169689Skan * Copyright (c) 2008 Gilles Chehade <gilles@poolp.org>
5169689Skan * Copyright (c) 2008 Pierre-Yves Ritschard <pyr@openbsd.org>
6169689Skan * Copyright (c) 2012 Eric Faurot <eric@openbsd.org>
7169689Skan *
8169689Skan * Permission to use, copy, modify, and distribute this software for any
9169689Skan * purpose with or without fee is hereby granted, provided that the above
10169689Skan * copyright notice and this permission notice appear in all copies.
11169689Skan *
12169689Skan * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
13169689Skan * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
14169689Skan * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
15169689Skan * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
16169689Skan * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
17169689Skan * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
18169689Skan * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
19169689Skan */
20169689Skan
21169689Skan#ifndef nitems
22169689Skan#define nitems(_a) (sizeof((_a)) / sizeof((_a)[0]))
23169689Skan#endif
24169689Skan
25169689Skan#include "smtpd-defines.h"
26169689Skan#include "smtpd-api.h"
27169689Skan#include "ioev.h"
28169689Skan#include "iobuf.h"
29169689Skan
30169689Skan#define CONF_FILE		 "/etc/mail/smtpd.conf"
31169689Skan#define MAILNAME_FILE		 "/etc/mail/mailname"
32169689Skan#define CA_FILE			 "/etc/ssl/cert.pem"
33169689Skan
34169689Skan#define PROC_COUNT		 6
35169689Skan
36169689Skan#define MAX_HOPS_COUNT		 100
37169689Skan#define	DEFAULT_MAX_BODY_SIZE	(35*1024*1024)
38169689Skan#define MAX_TAG_SIZE		 32
39169689Skan#define	MAX_FILTER_NAME		 32
40169689Skan
41169689Skan#define	EXPAND_BUFFER		 1024
42169689Skan
43169689Skan#define SMTPD_QUEUE_EXPIRY	 (4 * 24 * 60 * 60)
44169689Skan#define SMTPD_SOCKET		 "/var/run/smtpd.sock"
45169689Skan#ifndef SMTPD_NAME
46169689Skan#define	SMTPD_NAME		 "OpenSMTPD"
47169689Skan#endif
48169689Skan#define	SMTPD_VERSION		 "5.4.3"
49169689Skan#define SMTPD_SESSION_TIMEOUT	 300
50169689Skan#define SMTPD_BACKLOG		 5
51169689Skan
52169689Skan#define	PATH_SMTPCTL		"/usr/sbin/smtpctl"
53169689Skan
54169689Skan#define PATH_OFFLINE		"/offline"
55169689Skan#define PATH_PURGE		"/purge"
56169689Skan#define PATH_TEMPORARY		"/temporary"
57169689Skan
58169689Skan#define	PATH_FILTERS		"/usr/libexec/smtpd"
59169689Skan#define	PATH_TABLES		"/usr/libexec/smtpd"
60169689Skan
61169689Skan
62169689Skan/*
63169689Skan * RFC 5322 defines these characters as valid, some of them are
64169689Skan * potentially dangerous and need to be escaped.
65169689Skan */
66169689Skan#define	MAILADDR_ALLOWED       	"!#$%&'*/?^`{|}~+-=_"
67169689Skan#define	MAILADDR_ESCAPE		"!#$%&'*/?^`{|}~"
68169689Skan
69169689Skan
70169689Skan#define F_STARTTLS		0x01
71169689Skan#define F_SMTPS			0x02
72169689Skan#define	F_TLS_OPTIONAL		0x04
73169689Skan#define F_SSL		       (F_STARTTLS | F_SMTPS)
74169689Skan#define F_AUTH			0x08
75169689Skan#define	F_BACKUP		0x10	/* XXX - MUST BE SYNC-ED WITH RELAY_BACKUP */
76169689Skan#define	F_STARTTLS_REQUIRE	0x20
77169689Skan#define	F_AUTH_REQUIRE		0x40
78169689Skan#define	F_LMTP			0x80
79169689Skan#define	F_MASK_SOURCE		0x100
80169689Skan#define	F_TLS_VERIFY		0x200
81169689Skan
82169689Skan/* must match F_* for mta */
83169689Skan#define RELAY_STARTTLS		0x01
84169689Skan#define RELAY_SMTPS		0x02
85169689Skan#define	RELAY_TLS_OPTIONAL     	0x04
86#define RELAY_SSL		(RELAY_STARTTLS | RELAY_SMTPS)
87#define RELAY_AUTH		0x08
88#define RELAY_BACKUP		0x10	/* XXX - MUST BE SYNC-ED WITH F_BACKUP */
89#define RELAY_MX		0x20
90#define RELAY_LMTP		0x80
91#define	RELAY_TLS_VERIFY	0x200
92
93#define MTA_EXT_DSN		0x400
94
95struct userinfo {
96	char username[SMTPD_MAXLOGNAME];
97	char directory[SMTPD_MAXPATHLEN];
98	uid_t uid;
99	gid_t gid;
100};
101
102struct netaddr {
103	struct sockaddr_storage ss;
104	int bits;
105};
106
107struct relayhost {
108	uint16_t flags;
109	char hostname[SMTPD_MAXHOSTNAMELEN];
110	uint16_t port;
111	char pki_name[SMTPD_MAXPATHLEN];
112	char authtable[SMTPD_MAXPATHLEN];
113	char authlabel[SMTPD_MAXPATHLEN];
114	char sourcetable[SMTPD_MAXPATHLEN];
115	char heloname[SMTPD_MAXHOSTNAMELEN];
116	char helotable[SMTPD_MAXPATHLEN];
117};
118
119struct credentials {
120	char username[SMTPD_MAXLINESIZE];
121	char password[SMTPD_MAXLINESIZE];
122};
123
124struct destination {
125	char	name[SMTPD_MAXHOSTNAMELEN];
126};
127
128struct source {
129	struct sockaddr_storage	addr;
130};
131
132struct addrname {
133	struct sockaddr_storage	addr;
134	char			name[SMTPD_MAXHOSTNAMELEN];
135};
136
137union lookup {
138	struct expand		*expand;
139	struct credentials	 creds;
140	struct netaddr		 netaddr;
141	struct source		 source;
142	struct destination	 domain;
143	struct userinfo		 userinfo;
144	struct mailaddr		 mailaddr;
145	struct addrname		 addrname;
146};
147
148/*
149 * Bump IMSG_VERSION whenever a change is made to enum imsg_type.
150 * This will ensure that we can never use a wrong version of smtpctl with smtpd.
151 */
152#define	IMSG_VERSION		10
153
154enum imsg_type {
155	IMSG_NONE,
156
157	IMSG_CTL_OK,
158	IMSG_CTL_FAIL,
159
160	IMSG_CTL_GET_DIGEST,
161	IMSG_CTL_GET_STATS,
162	IMSG_CTL_LIST_MESSAGES,
163	IMSG_CTL_LIST_ENVELOPES,
164	IMSG_CTL_MTA_SHOW_HOSTS,
165	IMSG_CTL_MTA_SHOW_RELAYS,
166	IMSG_CTL_MTA_SHOW_ROUTES,
167	IMSG_CTL_MTA_SHOW_HOSTSTATS,
168	IMSG_CTL_MTA_BLOCK,
169	IMSG_CTL_MTA_UNBLOCK,
170	IMSG_CTL_MTA_SHOW_BLOCK,
171	IMSG_CTL_PAUSE_EVP,
172	IMSG_CTL_PAUSE_MDA,
173	IMSG_CTL_PAUSE_MTA,
174	IMSG_CTL_PAUSE_SMTP,
175	IMSG_CTL_PROFILE,
176	IMSG_CTL_PROFILE_DISABLE,
177	IMSG_CTL_PROFILE_ENABLE,
178	IMSG_CTL_RESUME_EVP,
179	IMSG_CTL_RESUME_MDA,
180	IMSG_CTL_RESUME_MTA,
181	IMSG_CTL_RESUME_SMTP,
182	IMSG_CTL_RESUME_ROUTE,
183	IMSG_CTL_REMOVE,
184	IMSG_CTL_SCHEDULE,
185	IMSG_CTL_SHOW_STATUS,
186	IMSG_CTL_SHUTDOWN,
187	IMSG_CTL_TRACE_DISABLE,
188	IMSG_CTL_TRACE_ENABLE,
189	IMSG_CTL_UPDATE_TABLE,
190	IMSG_CTL_VERBOSE,
191
192	IMSG_CTL_SMTP_SESSION,
193
194	IMSG_CONF_START,
195	IMSG_CONF_END,
196
197	IMSG_STAT_INCREMENT,
198	IMSG_STAT_DECREMENT,
199	IMSG_STAT_SET,
200
201	IMSG_LKA_AUTHENTICATE,
202	IMSG_LKA_OPEN_FORWARD,
203	IMSG_LKA_ENVELOPE_SUBMIT,
204	IMSG_LKA_ENVELOPE_COMMIT,
205
206	IMSG_QUEUE_DELIVER,
207	IMSG_QUEUE_DELIVERY_OK,
208	IMSG_QUEUE_DELIVERY_TEMPFAIL,
209	IMSG_QUEUE_DELIVERY_PERMFAIL,
210	IMSG_QUEUE_DELIVERY_LOOP,
211	IMSG_QUEUE_ENVELOPE_COMMIT,
212	IMSG_QUEUE_ENVELOPE_REMOVE,
213	IMSG_QUEUE_ENVELOPE_SCHEDULE,
214	IMSG_QUEUE_ENVELOPE_SUBMIT,
215	IMSG_QUEUE_HOLDQ_HOLD,
216	IMSG_QUEUE_HOLDQ_RELEASE,
217	IMSG_QUEUE_MESSAGE_COMMIT,
218	IMSG_QUEUE_MESSAGE_ROLLBACK,
219	IMSG_QUEUE_SMTP_SESSION,
220	IMSG_QUEUE_TRANSFER,
221
222	IMSG_MDA_DELIVERY_OK,
223	IMSG_MDA_DELIVERY_TEMPFAIL,
224	IMSG_MDA_DELIVERY_PERMFAIL,
225	IMSG_MDA_DELIVERY_LOOP,
226	IMSG_MDA_DELIVERY_HOLD,
227	IMSG_MDA_DONE,
228	IMSG_MDA_FORK,
229	IMSG_MDA_HOLDQ_RELEASE,
230	IMSG_MDA_LOOKUP_USERINFO,
231	IMSG_MDA_KILL,
232	IMSG_MDA_OPEN_MESSAGE,
233
234	IMSG_MFA_SMTP_RESPONSE,
235
236	IMSG_MTA_DELIVERY_OK,
237	IMSG_MTA_DELIVERY_TEMPFAIL,
238	IMSG_MTA_DELIVERY_PERMFAIL,
239	IMSG_MTA_DELIVERY_LOOP,
240	IMSG_MTA_DELIVERY_HOLD,
241	IMSG_MTA_DNS_HOST,
242	IMSG_MTA_DNS_HOST_END,
243	IMSG_MTA_DNS_PTR,
244	IMSG_MTA_DNS_MX,
245	IMSG_MTA_DNS_MX_PREFERENCE,
246	IMSG_MTA_HOLDQ_RELEASE,
247	IMSG_MTA_LOOKUP_CREDENTIALS,
248	IMSG_MTA_LOOKUP_SOURCE,
249	IMSG_MTA_LOOKUP_HELO,
250	IMSG_MTA_OPEN_MESSAGE,
251	IMSG_MTA_SCHEDULE,
252	IMSG_MTA_SSL_INIT,
253	IMSG_MTA_SSL_VERIFY_CERT,
254	IMSG_MTA_SSL_VERIFY_CHAIN,
255	IMSG_MTA_SSL_VERIFY,
256
257	IMSG_SCHED_ENVELOPE_BOUNCE,
258	IMSG_SCHED_ENVELOPE_DELIVER,
259	IMSG_SCHED_ENVELOPE_EXPIRE,
260	IMSG_SCHED_ENVELOPE_INJECT,
261	IMSG_SCHED_ENVELOPE_REMOVE,
262	IMSG_SCHED_ENVELOPE_TRANSFER,
263
264	IMSG_SMTP_AUTHENTICATE,
265	IMSG_SMTP_DNS_PTR,
266	IMSG_SMTP_MESSAGE_COMMIT,
267	IMSG_SMTP_MESSAGE_CREATE,
268	IMSG_SMTP_MESSAGE_ROLLBACK,
269	IMSG_SMTP_MESSAGE_OPEN,
270	IMSG_SMTP_EXPAND_RCPT,
271	IMSG_SMTP_LOOKUP_HELO,
272	IMSG_SMTP_SSL_INIT,
273	IMSG_SMTP_SSL_VERIFY_CERT,
274	IMSG_SMTP_SSL_VERIFY_CHAIN,
275	IMSG_SMTP_SSL_VERIFY,
276
277	IMSG_SMTP_REQ_CONNECT,
278	IMSG_SMTP_REQ_HELO,
279	IMSG_SMTP_REQ_MAIL,
280	IMSG_SMTP_REQ_RCPT,
281	IMSG_SMTP_REQ_DATA,
282	IMSG_SMTP_REQ_EOM,
283	IMSG_SMTP_EVENT_RSET,
284	IMSG_SMTP_EVENT_COMMIT,
285	IMSG_SMTP_EVENT_ROLLBACK,
286	IMSG_SMTP_EVENT_DISCONNECT,
287
288	IMSG_CA_PRIVENC,
289	IMSG_CA_PRIVDEC
290};
291
292enum blockmodes {
293	BM_NORMAL,
294	BM_NONBLOCK
295};
296
297enum smtp_proc_type {
298	PROC_PARENT = 0,
299	PROC_LKA,
300	PROC_QUEUE,
301	PROC_CONTROL,
302	PROC_SCHEDULER,
303	PROC_PONY,
304
305	PROC_FILTER,
306	PROC_CLIENT,
307};
308
309enum table_type {
310	T_NONE		= 0,
311	T_DYNAMIC	= 0x01,	/* table with external source	*/
312	T_LIST		= 0x02,	/* table holding a list		*/
313	T_HASH		= 0x04,	/* table holding a hash table	*/
314};
315
316struct table {
317	char				 t_name[SMTPD_MAXLINESIZE];
318	enum table_type			 t_type;
319	char				 t_config[SMTPD_MAXPATHLEN];
320
321	struct dict			 t_dict;
322
323	void				*t_handle;
324	struct table_backend		*t_backend;
325	void				*t_iter;
326};
327
328struct table_backend {
329	const unsigned int	services;
330	int	(*config)(struct table *);
331	void   *(*open)(struct table *);
332	int	(*update)(struct table *);
333	void	(*close)(void *);
334	int	(*lookup)(void *, const char *, enum table_service, union lookup *);
335	int	(*fetch)(void *, enum table_service, union lookup *);
336};
337
338
339enum dest_type {
340	DEST_DOM,
341	DEST_VDOM
342};
343
344enum action_type {
345	A_NONE,
346	A_RELAY,
347	A_RELAYVIA,
348	A_MAILDIR,
349	A_MBOX,
350	A_FILENAME,
351	A_MDA,
352	A_LMTP
353};
354
355enum decision {
356	R_REJECT,
357	R_ACCEPT
358};
359
360struct rule {
361	TAILQ_ENTRY(rule)		r_entry;
362	enum decision			r_decision;
363	uint8_t				r_nottag;
364	char				r_tag[MAX_TAG_SIZE];
365
366	uint8_t				r_notsources;
367	struct table		       *r_sources;
368
369	uint8_t				r_notsenders;
370	struct table		       *r_senders;
371
372	uint8_t				r_notrecipients;
373	struct table		       *r_recipients;
374
375	uint8_t				r_notdestination;
376	enum dest_type			r_desttype;
377	struct table		       *r_destination;
378
379	enum action_type		r_action;
380	union rule_dest {
381		char			buffer[EXPAND_BUFFER];
382		struct relayhost	relayhost;
383	}				r_value;
384
385	struct mailaddr		       *r_as;
386	struct table		       *r_mapping;
387	struct table		       *r_userbase;
388	time_t				r_qexpire;
389	uint8_t				r_forwardonly;
390};
391
392struct delivery_mda {
393	enum action_type	method;
394	char			usertable[SMTPD_MAXPATHLEN];
395	char			username[SMTPD_MAXLOGNAME];
396	char			buffer[EXPAND_BUFFER];
397};
398
399struct delivery_mta {
400	struct relayhost	relay;
401};
402
403enum bounce_type {
404	B_ERROR,
405	B_WARNING,
406	B_DSN
407};
408
409enum dsn_ret {
410	DSN_RETFULL = 1,
411	DSN_RETHDRS
412};
413
414struct delivery_bounce {
415	enum bounce_type	type;
416	time_t			delay;
417	time_t			expire;
418	enum dsn_ret		dsn_ret;
419        int			mta_without_dsn;
420};
421
422enum expand_type {
423	EXPAND_INVALID,
424	EXPAND_USERNAME,
425	EXPAND_FILENAME,
426	EXPAND_FILTER,
427	EXPAND_INCLUDE,
428	EXPAND_ADDRESS,
429	EXPAND_ERROR
430};
431
432struct expandnode {
433	RB_ENTRY(expandnode)	entry;
434	TAILQ_ENTRY(expandnode)	tq_entry;
435	enum expand_type	type;
436	int			sameuser;
437	int			alias;
438	struct rule	       *rule;
439	struct expandnode      *parent;
440	unsigned int		depth;
441	struct table   	       *mapping;
442	struct table   	       *userbase;
443	union {
444		/*
445		 * user field handles both expansion user and system user
446		 * so we MUST make it large enough to fit a mailaddr user
447		 */
448		char		user[SMTPD_MAXLOCALPARTSIZE];
449		char		buffer[EXPAND_BUFFER];
450		struct mailaddr	mailaddr;
451	}			u;
452};
453
454struct expand {
455	RB_HEAD(expandtree, expandnode)	 tree;
456	TAILQ_HEAD(xnodes, expandnode)	*queue;
457	int				 alias;
458	size_t				 nb_nodes;
459	struct rule			*rule;
460	struct expandnode		*parent;
461};
462
463#define DSN_SUCCESS 0x01
464#define DSN_FAILURE 0x02
465#define DSN_DELAY   0x04
466#define DSN_NEVER   0x08
467
468#define	DSN_ENVID_LEN	100
469
470#define	SMTPD_ENVELOPE_VERSION		2
471struct envelope {
472	TAILQ_ENTRY(envelope)		entry;
473
474	char				tag[MAX_TAG_SIZE];
475
476	uint32_t			version;
477	uint64_t			id;
478	enum envelope_flags		flags;
479
480	char				smtpname[SMTPD_MAXHOSTNAMELEN];
481	char				helo[SMTPD_MAXHOSTNAMELEN];
482	char				hostname[SMTPD_MAXHOSTNAMELEN];
483	char				errorline[SMTPD_MAXLINESIZE];
484	struct sockaddr_storage		ss;
485
486	struct mailaddr			sender;
487	struct mailaddr			rcpt;
488	struct mailaddr			dest;
489
490	enum delivery_type		type;
491	union {
492		struct delivery_mda	mda;
493		struct delivery_mta	mta;
494		struct delivery_bounce	bounce;
495	}				agent;
496
497	uint16_t			retry;
498	time_t				creation;
499	time_t				expire;
500	time_t				lasttry;
501	time_t				nexttry;
502	time_t				lastbounce;
503
504	struct mailaddr			dsn_orcpt;
505	char				dsn_envid[DSN_ENVID_LEN+1];
506	uint8_t				dsn_notify;
507	enum dsn_ret			dsn_ret;
508
509	uint8_t				esc_class;
510	uint8_t				esc_code;
511};
512
513struct listener {
514	uint16_t       		 flags;
515	int			 fd;
516	struct sockaddr_storage	 ss;
517	in_port_t		 port;
518	struct timeval		 timeout;
519	struct event		 ev;
520	char			 pki_name[SMTPD_MAXPATHLEN];
521	char			 tag[MAX_TAG_SIZE];
522	char			 authtable[SMTPD_MAXLINESIZE];
523	char			 hostname[SMTPD_MAXHOSTNAMELEN];
524	char			 hostnametable[SMTPD_MAXPATHLEN];
525	TAILQ_ENTRY(listener)	 entry;
526};
527
528struct smtpd {
529	char				sc_conffile[SMTPD_MAXPATHLEN];
530	size_t				sc_maxsize;
531
532#define SMTPD_OPT_VERBOSE		0x00000001
533#define SMTPD_OPT_NOACTION		0x00000002
534	uint32_t			sc_opts;
535
536#define SMTPD_EXITING			0x00000001
537#define SMTPD_MDA_PAUSED		0x00000002
538#define SMTPD_MTA_PAUSED		0x00000004
539#define SMTPD_SMTP_PAUSED		0x00000008
540#define SMTPD_MDA_BUSY			0x00000010
541#define SMTPD_MTA_BUSY			0x00000020
542#define SMTPD_BOUNCE_BUSY		0x00000040
543#define SMTPD_SMTP_DISABLED		0x00000080
544	uint32_t			sc_flags;
545
546#define QUEUE_COMPRESSION      		0x00000001
547#define QUEUE_ENCRYPTION      		0x00000002
548#define QUEUE_EVPCACHE			0x00000004
549	uint32_t			sc_queue_flags;
550	char			       *sc_queue_key;
551	size_t				sc_queue_evpcache_size;
552
553	size_t				sc_mda_max_session;
554	size_t				sc_mda_max_user_session;
555	size_t				sc_mda_task_hiwat;
556	size_t				sc_mda_task_lowat;
557	size_t				sc_mda_task_release;
558
559	size_t				sc_mta_max_deferred;
560
561	size_t				sc_scheduler_max_inflight;
562	size_t				sc_scheduler_max_evp_batch_size;
563	size_t				sc_scheduler_max_msg_batch_size;
564	size_t				sc_scheduler_max_schedule;
565
566	int				sc_qexpire;
567#define MAX_BOUNCE_WARN			4
568	time_t				sc_bounce_warn[MAX_BOUNCE_WARN];
569	char				sc_hostname[SMTPD_MAXHOSTNAMELEN];
570	struct stat_backend	       *sc_stat;
571	struct compress_backend	       *sc_comp;
572
573	time_t					 sc_uptime;
574
575	TAILQ_HEAD(listenerlist, listener)	*sc_listeners;
576
577	TAILQ_HEAD(rulelist, rule)		*sc_rules;
578
579	struct dict			       *sc_pki_dict;
580	struct dict			       *sc_ssl_dict;
581
582	struct dict			       *sc_tables_dict;		/* keyed lookup	*/
583
584	struct dict			       *sc_limits_dict;
585
586	struct dict				sc_filters;
587	uint32_t				filtermask;
588};
589
590#define	TRACE_DEBUG	0x0001
591#define	TRACE_IMSG	0x0002
592#define	TRACE_IO	0x0004
593#define	TRACE_SMTP	0x0008
594#define	TRACE_MFA	0x0010
595#define	TRACE_MTA	0x0020
596#define	TRACE_BOUNCE	0x0040
597#define	TRACE_SCHEDULER	0x0080
598#define	TRACE_LOOKUP	0x0100
599#define	TRACE_STAT	0x0200
600#define	TRACE_RULES	0x0400
601#define	TRACE_MPROC	0x0800
602#define	TRACE_EXPAND	0x1000
603#define	TRACE_TABLES	0x2000
604#define	TRACE_QUEUE	0x4000
605
606#define PROFILE_TOSTAT	0x0001
607#define PROFILE_IMSG	0x0002
608#define PROFILE_QUEUE	0x0004
609#define PROFILE_BUFFERS	0x0008
610
611struct forward_req {
612	uint64_t			id;
613	uint8_t				status;
614
615	char				user[SMTPD_MAXLOGNAME];
616	uid_t				uid;
617	gid_t				gid;
618	char				directory[SMTPD_MAXPATHLEN];
619};
620
621struct deliver {
622	char			to[SMTPD_MAXPATHLEN];
623	char			from[SMTPD_MAXPATHLEN];
624	char			user[SMTPD_MAXLOGNAME];
625	short			mode;
626
627	struct userinfo		userinfo;
628};
629
630#define MAX_FILTER_PER_CHAIN	16
631struct filter {
632	int			chain;
633	int			done;
634	char			name[MAX_FILTER_NAME];
635	char			path[SMTPD_MAXPATHLEN];
636	char			filters[MAX_FILTER_NAME][MAX_FILTER_PER_CHAIN];
637};
638
639struct mta_host {
640	SPLAY_ENTRY(mta_host)	 entry;
641	struct sockaddr		*sa;
642	char			*ptrname;
643	int			 refcount;
644	size_t			 nconn;
645	time_t			 lastconn;
646	time_t			 lastptrquery;
647
648#define HOST_IGNORE	0x01
649	int			 flags;
650};
651
652struct mta_mx {
653	TAILQ_ENTRY(mta_mx)	 entry;
654	struct mta_host		*host;
655	int			 preference;
656};
657
658struct mta_domain {
659	SPLAY_ENTRY(mta_domain)	 entry;
660	char			*name;
661	int			 flags;
662	TAILQ_HEAD(, mta_mx)	 mxs;
663	int			 mxstatus;
664	int			 refcount;
665	size_t			 nconn;
666	time_t			 lastconn;
667	time_t			 lastmxquery;
668};
669
670struct mta_source {
671	SPLAY_ENTRY(mta_source)	 entry;
672	struct sockaddr		*sa;
673	int			 refcount;
674	size_t			 nconn;
675	time_t			 lastconn;
676};
677
678struct mta_connector {
679	struct mta_source		*source;
680	struct mta_relay		*relay;
681
682#define CONNECTOR_ERROR_FAMILY		0x0001
683#define CONNECTOR_ERROR_SOURCE		0x0002
684#define CONNECTOR_ERROR_MX		0x0004
685#define CONNECTOR_ERROR_ROUTE_NET	0x0008
686#define CONNECTOR_ERROR_ROUTE_SMTP	0x0010
687#define CONNECTOR_ERROR_ROUTE		0x0018
688#define CONNECTOR_ERROR_BLOCKED		0x0020
689#define CONNECTOR_ERROR			0x00ff
690
691#define CONNECTOR_LIMIT_HOST		0x0100
692#define CONNECTOR_LIMIT_ROUTE		0x0200
693#define CONNECTOR_LIMIT_SOURCE		0x0400
694#define CONNECTOR_LIMIT_RELAY		0x0800
695#define CONNECTOR_LIMIT_CONN		0x1000
696#define CONNECTOR_LIMIT_DOMAIN		0x2000
697#define CONNECTOR_LIMIT			0xff00
698
699#define CONNECTOR_NEW			0x10000
700#define CONNECTOR_WAIT			0x20000
701	int				 flags;
702
703	int				 refcount;
704	size_t				 nconn;
705	time_t				 lastconn;
706};
707
708struct mta_route {
709	SPLAY_ENTRY(mta_route)	 entry;
710	uint64_t		 id;
711	struct mta_source	*src;
712	struct mta_host		*dst;
713#define ROUTE_NEW		0x01
714#define ROUTE_RUNQ		0x02
715#define ROUTE_KEEPALIVE		0x04
716#define ROUTE_DISABLED		0xf0
717#define ROUTE_DISABLED_NET	0x10
718#define ROUTE_DISABLED_SMTP	0x20
719	int			 flags;
720	int			 nerror;
721	int			 penalty;
722	int			 refcount;
723	size_t			 nconn;
724	time_t			 lastconn;
725	time_t			 lastdisc;
726	time_t			 lastpenalty;
727};
728
729struct mta_limits {
730	size_t	maxconn_per_host;
731	size_t	maxconn_per_route;
732	size_t	maxconn_per_source;
733	size_t	maxconn_per_connector;
734	size_t	maxconn_per_relay;
735	size_t	maxconn_per_domain;
736
737	time_t	conndelay_host;
738	time_t	conndelay_route;
739	time_t	conndelay_source;
740	time_t	conndelay_connector;
741	time_t	conndelay_relay;
742	time_t	conndelay_domain;
743
744	time_t	discdelay_route;
745
746	size_t	max_mail_per_session;
747	time_t	sessdelay_transaction;
748	time_t	sessdelay_keepalive;
749
750	size_t	max_failures_per_session;
751
752	int	family;
753
754	int	task_hiwat;
755	int	task_lowat;
756	int	task_release;
757};
758
759struct mta_relay {
760	SPLAY_ENTRY(mta_relay)	 entry;
761	uint64_t		 id;
762
763	struct mta_domain	*domain;
764	struct mta_limits	*limits;
765	int			 flags;
766	char			*backupname;
767	int			 backuppref;
768	char			*sourcetable;
769	uint16_t		 port;
770	char			*pki_name;
771	char			*authtable;
772	char			*authlabel;
773	char			*helotable;
774	char			*heloname;
775	char			*secret;
776
777	int			 state;
778	size_t			 ntask;
779	TAILQ_HEAD(, mta_task)	 tasks;
780
781	struct tree		 connectors;
782	size_t			 sourceloop;
783	time_t			 lastsource;
784	time_t			 nextsource;
785
786	int			 fail;
787	char			*failstr;
788
789#define RELAY_WAIT_MX		0x01
790#define RELAY_WAIT_PREFERENCE	0x02
791#define RELAY_WAIT_SECRET	0x04
792#define RELAY_WAIT_LIMITS	0x08
793#define RELAY_WAIT_SOURCE	0x10
794#define RELAY_WAIT_CONNECTOR	0x20
795#define RELAY_WAITMASK		0x3f
796	int			 status;
797
798	int			 refcount;
799	size_t			 nconn;
800	size_t			 nconn_ready;
801	time_t			 lastconn;
802};
803
804struct mta_envelope {
805	TAILQ_ENTRY(mta_envelope)	 entry;
806	uint64_t			 id;
807	uint64_t			 session;
808	time_t				 creation;
809	char				*dest;
810	char				*rcpt;
811	struct mta_task			*task;
812	int				 delivery;
813
814	int				 ext;
815	char				*dsn_orcpt;
816	char				dsn_envid[DSN_ENVID_LEN+1];
817	uint8_t				dsn_notify;
818	enum dsn_ret			dsn_ret;
819
820	char				 status[SMTPD_MAXLINESIZE];
821};
822
823struct mta_task {
824	TAILQ_ENTRY(mta_task)		 entry;
825	struct mta_relay		*relay;
826	uint32_t			 msgid;
827	TAILQ_HEAD(, mta_envelope)	 envelopes;
828	char				*sender;
829};
830
831struct passwd;
832
833struct queue_backend {
834	int	(*init)(struct passwd *, int);
835};
836
837struct compress_backend {
838	size_t	(*compress_chunk)(void *, size_t, void *, size_t);
839	size_t	(*uncompress_chunk)(void *, size_t, void *, size_t);
840	int	(*compress_file)(FILE *, FILE *);
841	int	(*uncompress_file)(FILE *, FILE *);
842};
843
844/* auth structures */
845enum auth_type {
846	AUTH_BSD,
847	AUTH_PWD,
848};
849
850struct auth_backend {
851	int	(*authenticate)(char *, char *);
852};
853
854
855/* delivery_backend */
856struct delivery_backend {
857	int	allow_root;
858	void	(*open)(struct deliver *);
859};
860
861struct scheduler_backend {
862	int	(*init)(void);
863
864	int	(*insert)(struct scheduler_info *);
865	size_t	(*commit)(uint32_t);
866	size_t	(*rollback)(uint32_t);
867
868	int	(*update)(struct scheduler_info *);
869	int	(*delete)(uint64_t);
870	int	(*hold)(uint64_t, uint64_t);
871	int	(*release)(int, uint64_t, int);
872
873	int	(*batch)(int, struct scheduler_batch *);
874
875	size_t	(*messages)(uint32_t, uint32_t *, size_t);
876	size_t	(*envelopes)(uint64_t, struct evpstate *, size_t);
877	int	(*schedule)(uint64_t);
878	int	(*remove)(uint64_t);
879	int	(*suspend)(uint64_t);
880	int	(*resume)(uint64_t);
881};
882
883enum stat_type {
884	STAT_COUNTER,
885	STAT_TIMESTAMP,
886	STAT_TIMEVAL,
887	STAT_TIMESPEC,
888};
889
890struct stat_value {
891	enum stat_type	type;
892	union stat_v {
893		size_t		counter;
894		time_t		timestamp;
895		struct timeval	tv;
896		struct timespec	ts;
897	} u;
898};
899
900#define	STAT_KEY_SIZE	1024
901struct stat_kv {
902	void	*iter;
903	char	key[STAT_KEY_SIZE];
904	struct stat_value	val;
905};
906
907struct stat_backend {
908	void	(*init)(void);
909	void	(*close)(void);
910	void	(*increment)(const char *, size_t);
911	void	(*decrement)(const char *, size_t);
912	void	(*set)(const char *, const struct stat_value *);
913	int	(*iter)(void **, char **, struct stat_value *);
914};
915
916struct stat_digest {
917	time_t			 startup;
918	time_t			 timestamp;
919
920	size_t			 clt_connect;
921	size_t			 clt_disconnect;
922
923	size_t			 evp_enqueued;
924	size_t			 evp_dequeued;
925
926	size_t			 evp_expired;
927	size_t			 evp_removed;
928	size_t			 evp_bounce;
929
930	size_t			 dlv_ok;
931	size_t			 dlv_permfail;
932	size_t			 dlv_tempfail;
933	size_t			 dlv_loop;
934};
935
936
937struct mproc {
938	pid_t		 pid;
939	char		*name;
940	int		 proc;
941	void		(*handler)(struct mproc *, struct imsg *);
942	struct imsgbuf	 imsgbuf;
943
944	char		*m_buf;
945	size_t		 m_alloc;
946	size_t		 m_pos;
947	uint32_t	 m_type;
948	uint32_t	 m_peerid;
949	pid_t		 m_pid;
950	int		 m_fd;
951
952	int		 enable;
953	short		 events;
954	struct event	 ev;
955	void		*data;
956
957	off_t		 msg_in;
958	off_t		 msg_out;
959	off_t		 bytes_in;
960	off_t		 bytes_out;
961	size_t		 bytes_queued;
962	size_t		 bytes_queued_max;
963};
964
965struct msg {
966	const uint8_t	*pos;
967	const uint8_t	*end;
968};
969
970extern enum smtp_proc_type	smtpd_process;
971
972extern int verbose;
973extern int profiling;
974
975extern struct mproc *p_control;
976extern struct mproc *p_parent;
977extern struct mproc *p_lka;
978extern struct mproc *p_queue;
979extern struct mproc *p_scheduler;
980extern struct mproc *p_pony;
981
982extern struct smtpd	*env;
983extern void (*imsg_callback)(struct mproc *, struct imsg *);
984
985struct imsgproc {
986	pid_t			pid;
987	struct event		ev;
988	struct imsgbuf	       *ibuf;
989	char		       *path;
990	char		       *name;
991	void		      (*cb)(struct imsg *, void *);
992	void		       *cb_arg;
993};
994
995/* inter-process structures */
996
997struct bounce_req_msg {
998	uint64_t		evpid;
999	time_t			timestamp;
1000	struct delivery_bounce	bounce;
1001};
1002
1003enum mfa_resp_status {
1004	MFA_OK,
1005	MFA_FAIL,
1006	MFA_CLOSE,
1007};
1008
1009enum dns_error {
1010	DNS_OK = 0,
1011	DNS_RETRY,
1012	DNS_EINVAL,
1013	DNS_ENONAME,
1014	DNS_ENOTFOUND,
1015};
1016
1017enum lka_resp_status {
1018	LKA_OK,
1019	LKA_TEMPFAIL,
1020	LKA_PERMFAIL
1021};
1022
1023enum ca_resp_status {
1024	CA_OK,
1025	CA_FAIL
1026};
1027
1028struct ca_cert_req_msg {
1029	uint64_t		reqid;
1030	char			name[SMTPD_MAXHOSTNAMELEN];
1031};
1032
1033struct ca_cert_resp_msg {
1034	uint64_t		reqid;
1035	enum ca_resp_status	status;
1036	char		       *cert;
1037	off_t			cert_len;
1038};
1039
1040struct ca_vrfy_req_msg {
1041	uint64_t		reqid;
1042	char			pkiname[SMTPD_MAXHOSTNAMELEN];
1043	unsigned char  	       *cert;
1044	off_t			cert_len;
1045	size_t			n_chain;
1046	size_t			chain_offset;
1047	unsigned char	      **chain_cert;
1048	off_t		       *chain_cert_len;
1049};
1050
1051struct ca_vrfy_resp_msg {
1052	uint64_t		reqid;
1053	enum ca_resp_status	status;
1054};
1055
1056
1057/* aliases.c */
1058int aliases_get(struct expand *, const char *);
1059int aliases_virtual_check(struct table *, const struct mailaddr *);
1060int aliases_virtual_get(struct expand *, const struct mailaddr *);
1061int alias_parse(struct expandnode *, const char *);
1062
1063
1064/* auth.c */
1065struct auth_backend *auth_backend_lookup(enum auth_type);
1066
1067
1068/* bounce.c */
1069void bounce_add(uint64_t);
1070void bounce_fd(int);
1071
1072
1073/* ca.c */
1074int	 ca_X509_verify(void *, void *, const char *, const char *, const char **);
1075void	 ca_imsg(struct mproc *, struct imsg *);
1076void	 ca_init(void);
1077int	 ca_engine_init(void);
1078
1079/* compress_backend.c */
1080struct compress_backend *compress_backend_lookup(const char *);
1081size_t	compress_chunk(void *, size_t, void *, size_t);
1082size_t	uncompress_chunk(void *, size_t, void *, size_t);
1083int	compress_file(FILE *, FILE *);
1084int	uncompress_file(FILE *, FILE *);
1085
1086/* config.c */
1087#define PURGE_LISTENERS		0x01
1088#define PURGE_TABLES		0x02
1089#define PURGE_RULES		0x04
1090#define PURGE_PKI		0x08
1091#define PURGE_PKI_KEYS		0x10
1092#define PURGE_EVERYTHING	0x0f
1093void purge_config(uint8_t);
1094void init_pipes(void);
1095void config_process(enum smtp_proc_type);
1096void config_peer(enum smtp_proc_type);
1097void config_done(void);
1098
1099
1100/* control.c */
1101pid_t control(void);
1102int control_create_socket(void);
1103
1104
1105/* crypto.c */
1106int	crypto_setup(const char *, size_t);
1107int	crypto_encrypt_file(FILE *, FILE *);
1108int	crypto_decrypt_file(FILE *, FILE *);
1109size_t	crypto_encrypt_buffer(const char *, size_t, char *, size_t);
1110size_t	crypto_decrypt_buffer(const char *, size_t, char *, size_t);
1111
1112
1113/* delivery.c */
1114struct delivery_backend *delivery_backend_lookup(enum action_type);
1115
1116
1117/* dns.c */
1118void dns_imsg(struct mproc *, struct imsg *);
1119
1120
1121/* enqueue.c */
1122int		 enqueue(int, char **);
1123
1124
1125/* envelope.c */
1126void envelope_set_errormsg(struct envelope *, char *, ...);
1127void envelope_set_esc_class(struct envelope *, enum enhanced_status_class);
1128void envelope_set_esc_code(struct envelope *, enum enhanced_status_code);
1129int envelope_load_buffer(struct envelope *, const char *, size_t);
1130int envelope_dump_buffer(const struct envelope *, char *, size_t);
1131
1132
1133/* expand.c */
1134int expand_cmp(struct expandnode *, struct expandnode *);
1135void expand_insert(struct expand *, struct expandnode *);
1136struct expandnode *expand_lookup(struct expand *, struct expandnode *);
1137void expand_clear(struct expand *);
1138void expand_free(struct expand *);
1139int expand_line(struct expand *, const char *, int);
1140int expand_to_text(struct expand *, char *, size_t);
1141RB_PROTOTYPE(expandtree, expandnode, nodes, expand_cmp);
1142
1143
1144/* forward.c */
1145int forwards_get(int, struct expand *);
1146
1147
1148/* imsgproc.c */
1149void imsgproc_init(void);
1150struct imsgproc *imsgproc_fork(const char *, const char *,
1151    void (*)(struct imsg *, void *), void *);
1152void imsgproc_set_read(struct imsgproc *);
1153void imsgproc_set_write(struct imsgproc *);
1154void imsgproc_set_read_write(struct imsgproc *);
1155void imsgproc_reset_callback(struct imsgproc *, void (*)(struct imsg *, void *), void *);
1156
1157/* limit.c */
1158void limit_mta_set_defaults(struct mta_limits *);
1159int limit_mta_set(struct mta_limits *, const char*, int64_t);
1160
1161/* lka.c */
1162pid_t lka(void);
1163
1164
1165/* lka_session.c */
1166void lka_session(uint64_t, struct envelope *);
1167void lka_session_forward_reply(struct forward_req *, int);
1168
1169
1170/* log.c */
1171void vlog(int, const char *, va_list);
1172
1173
1174/* mda.c */
1175void mda_postfork(void);
1176void mda_postprivdrop(void);
1177void mda_imsg(struct mproc *, struct imsg *);
1178
1179
1180/* mfa.c */
1181pid_t mfa(void);
1182void mfa_ready(void);
1183
1184
1185/* mfa_session.c */
1186void mfa_filter_prepare(void);
1187void mfa_filter_init(void);
1188void mfa_filter_connect(uint64_t, const struct sockaddr *,
1189    const struct sockaddr *, const char *);
1190void mfa_filter_mailaddr(uint64_t, int, const struct mailaddr *);
1191void mfa_filter_line(uint64_t, int, const char *);
1192void mfa_filter_eom(uint64_t, int, size_t);
1193void mfa_filter(uint64_t, int);
1194void mfa_filter_event(uint64_t, int);
1195void mfa_build_fd_chain(uint64_t, int);
1196
1197
1198/* mproc.c */
1199int mproc_fork(struct mproc *, const char*, const char *);
1200void mproc_init(struct mproc *, int);
1201void mproc_clear(struct mproc *);
1202void mproc_enable(struct mproc *);
1203void mproc_disable(struct mproc *);
1204void mproc_event_add(struct mproc *);
1205void m_compose(struct mproc *, uint32_t, uint32_t, pid_t, int, void *, size_t);
1206void m_composev(struct mproc *, uint32_t, uint32_t, pid_t, int,
1207    const struct iovec *, int);
1208void m_forward(struct mproc *, struct imsg *);
1209void m_create(struct mproc *, uint32_t, uint32_t, pid_t, int);
1210void m_add(struct mproc *, const void *, size_t);
1211void m_add_int(struct mproc *, int);
1212void m_add_u32(struct mproc *, uint32_t);
1213void m_add_size(struct mproc *, size_t);
1214void m_add_time(struct mproc *, time_t);
1215void m_add_string(struct mproc *, const char *);
1216void m_add_data(struct mproc *, const void *, size_t);
1217void m_add_evpid(struct mproc *, uint64_t);
1218void m_add_msgid(struct mproc *, uint32_t);
1219void m_add_id(struct mproc *, uint64_t);
1220void m_add_sockaddr(struct mproc *, const struct sockaddr *);
1221void m_add_mailaddr(struct mproc *, const struct mailaddr *);
1222void m_add_envelope(struct mproc *, const struct envelope *);
1223void m_close(struct mproc *);
1224void m_flush(struct mproc *);
1225
1226void m_msg(struct msg *, struct imsg *);
1227int  m_is_eom(struct msg *);
1228void m_end(struct msg *);
1229void m_get_int(struct msg *, int *);
1230void m_get_size(struct msg *, size_t *);
1231void m_get_u32(struct msg *, uint32_t *);
1232void m_get_time(struct msg *, time_t *);
1233void m_get_string(struct msg *, const char **);
1234void m_get_data(struct msg *, const void **, size_t *);
1235void m_get_evpid(struct msg *, uint64_t *);
1236void m_get_msgid(struct msg *, uint32_t *);
1237void m_get_id(struct msg *, uint64_t *);
1238void m_get_sockaddr(struct msg *, struct sockaddr *);
1239void m_get_mailaddr(struct msg *, struct mailaddr *);
1240void m_get_envelope(struct msg *, struct envelope *);
1241
1242
1243/* mta.c */
1244void mta_postfork(void);
1245void mta_postprivdrop(void);
1246void mta_imsg(struct mproc *, struct imsg *);
1247void mta_route_ok(struct mta_relay *, struct mta_route *);
1248void mta_route_error(struct mta_relay *, struct mta_route *);
1249void mta_route_down(struct mta_relay *, struct mta_route *);
1250void mta_route_collect(struct mta_relay *, struct mta_route *);
1251void mta_source_error(struct mta_relay *, struct mta_route *, const char *);
1252void mta_delivery_log(struct mta_envelope *, const char *, const char *, int, const char *);
1253void mta_delivery_notify(struct mta_envelope *);
1254struct mta_task *mta_route_next_task(struct mta_relay *, struct mta_route *);
1255const char *mta_host_to_text(struct mta_host *);
1256const char *mta_relay_to_text(struct mta_relay *);
1257
1258/* mta_session.c */
1259void mta_session(struct mta_relay *, struct mta_route *);
1260void mta_session_imsg(struct mproc *, struct imsg *);
1261
1262
1263/* parse.y */
1264int parse_config(struct smtpd *, const char *, int);
1265int cmdline_symset(char *);
1266
1267
1268/* queue.c */
1269pid_t queue(void);
1270void queue_flow_control(void);
1271
1272
1273/* queue_backend.c */
1274uint32_t queue_generate_msgid(void);
1275uint64_t queue_generate_evpid(uint32_t);
1276int queue_init(const char *, int);
1277int queue_message_create(uint32_t *);
1278int queue_message_delete(uint32_t);
1279int queue_message_commit(uint32_t);
1280int queue_message_fd_r(uint32_t);
1281int queue_message_fd_rw(uint32_t);
1282int queue_message_corrupt(uint32_t);
1283int queue_envelope_create(struct envelope *);
1284int queue_envelope_delete(uint64_t);
1285int queue_envelope_load(uint64_t, struct envelope *);
1286int queue_envelope_update(struct envelope *);
1287int queue_envelope_walk(struct envelope *);
1288
1289
1290/* ruleset.c */
1291struct rule *ruleset_match(const struct envelope *);
1292
1293
1294/* scheduler.c */
1295pid_t scheduler(void);
1296
1297
1298/* scheduler_bakend.c */
1299struct scheduler_backend *scheduler_backend_lookup(const char *);
1300void scheduler_info(struct scheduler_info *, struct envelope *);
1301time_t scheduler_compute_schedule(struct scheduler_info *);
1302
1303
1304/* pony.c */
1305pid_t pony(void);
1306void pony_imsg(struct mproc *, struct imsg *);
1307
1308
1309/* smtp.c */
1310void smtp_postfork(void);
1311void smtp_postprivdrop(void);
1312void smtp_imsg(struct mproc *, struct imsg *);
1313void smtp_configure(void);
1314void smtp_collect(void);
1315
1316
1317/* smtp_session.c */
1318int smtp_session(struct listener *, int, const struct sockaddr_storage *,
1319    const char *);
1320void smtp_session_imsg(struct mproc *, struct imsg *);
1321
1322
1323/* smtpd.c */
1324void imsg_dispatch(struct mproc *, struct imsg *);
1325void post_fork(int);
1326const char *proc_name(enum smtp_proc_type);
1327const char *proc_title(enum smtp_proc_type);
1328const char *imsg_to_str(int);
1329void log_imsg(int, int, struct imsg *);
1330
1331
1332/* ssl_smtpd.c */
1333void   *ssl_mta_init(void *, char *, off_t);
1334void   *ssl_smtp_init(void *, void *, void *);
1335
1336
1337/* stat_backend.c */
1338struct stat_backend	*stat_backend_lookup(const char *);
1339void	stat_increment(const char *, size_t);
1340void	stat_decrement(const char *, size_t);
1341void	stat_set(const char *, const struct stat_value *);
1342struct stat_value *stat_counter(size_t);
1343struct stat_value *stat_timestamp(time_t);
1344struct stat_value *stat_timeval(struct timeval *);
1345struct stat_value *stat_timespec(struct timespec *);
1346
1347
1348/* table.c */
1349struct table *table_find(const char *, const char *);
1350struct table *table_create(const char *, const char *, const char *,
1351    const char *);
1352int	table_config(struct table *);
1353int	table_open(struct table *);
1354int	table_update(struct table *);
1355void	table_close(struct table *);
1356int	table_check_use(struct table *, uint32_t, uint32_t);
1357int	table_check_type(struct table *, uint32_t);
1358int	table_check_service(struct table *, uint32_t);
1359int	table_lookup(struct table *, const char *, enum table_service,
1360    union lookup *);
1361int	table_fetch(struct table *, enum table_service, union lookup *);
1362void table_destroy(struct table *);
1363void table_add(struct table *, const char *, const char *);
1364void table_delete(struct table *, const char *);
1365int table_domain_match(const char *, const char *);
1366int table_netaddr_match(const char *, const char *);
1367int table_mailaddr_match(const char *, const char *);
1368void	table_open_all(void);
1369void	table_dump_all(void);
1370void	table_close_all(void);
1371const void	*table_get(struct table *, const char *);
1372int table_parse_lookup(enum table_service, const char *, const char *,
1373    union lookup *);
1374
1375
1376/* to.c */
1377int email_to_mailaddr(struct mailaddr *, char *);
1378int text_to_netaddr(struct netaddr *, const char *);
1379int text_to_mailaddr(struct mailaddr *, const char *);
1380int text_to_relayhost(struct relayhost *, const char *);
1381int text_to_userinfo(struct userinfo *, const char *);
1382int text_to_credentials(struct credentials *, const char *);
1383int text_to_expandnode(struct expandnode *, const char *);
1384uint64_t text_to_evpid(const char *);
1385uint32_t text_to_msgid(const char *);
1386const char *sa_to_text(const struct sockaddr *);
1387const char *ss_to_text(const struct sockaddr_storage *);
1388const char *time_to_text(time_t);
1389const char *duration_to_text(time_t);
1390const char *relayhost_to_text(const struct relayhost *);
1391const char *rule_to_text(struct rule *);
1392const char *sockaddr_to_text(struct sockaddr *);
1393const char *mailaddr_to_text(const struct mailaddr *);
1394const char *expandnode_to_text(struct expandnode *);
1395
1396/* util.c */
1397typedef struct arglist arglist;
1398struct arglist {
1399	char	**list;
1400	uint	  num;
1401	uint	  nalloc;
1402};
1403void addargs(arglist *, char *, ...)
1404	__attribute__((format(printf, 2, 3)));
1405int bsnprintf(char *, size_t, const char *, ...)
1406	__attribute__((format (printf, 3, 4)));
1407int mkdirs(char *, mode_t);
1408int safe_fclose(FILE *);
1409int hostname_match(const char *, const char *);
1410int valid_localpart(const char *);
1411int valid_domainpart(const char *);
1412int secure_file(int, char *, char *, uid_t, int);
1413int  lowercase(char *, const char *, size_t);
1414void xlowercase(char *, const char *, size_t);
1415int  uppercase(char *, const char *, size_t);
1416uint64_t generate_uid(void);
1417int availdesc(void);
1418int ckdir(const char *, mode_t, uid_t, gid_t, int);
1419int rmtree(char *, int);
1420int mvpurge(char *, char *);
1421int mktmpfile(void);
1422const char *parse_smtp_response(char *, size_t, char **, int *);
1423void *xmalloc(size_t, const char *);
1424void *xcalloc(size_t, size_t, const char *);
1425char *xstrdup(const char *, const char *);
1426void *xmemdup(const void *, size_t, const char *);
1427char *strip(char *);
1428void iobuf_xinit(struct iobuf *, size_t, size_t, const char *);
1429void iobuf_xfqueue(struct iobuf *, const char *, const char *, ...);
1430void log_envelope(const struct envelope *, const char *, const char *,
1431    const char *);
1432void session_socket_blockmode(int, enum blockmodes);
1433void session_socket_no_linger(int);
1434int session_socket_error(int);
1435int getmailname(char *, size_t);
1436int base64_encode(unsigned char const *, size_t, char *, size_t);
1437int base64_decode(char const *, unsigned char *, size_t);
1438
1439
1440/* waitq.c */
1441int  waitq_wait(void *, void (*)(void *, void *, void *), void *);
1442void waitq_run(void *, void *);
1443
1444/* runq.c */
1445struct runq;
1446
1447int runq_init(struct runq **, void (*)(struct runq *, void *));
1448int runq_schedule(struct runq *, time_t, void (*)(struct runq *, void *), void *);
1449int runq_delay(struct runq *, unsigned int, void (*)(struct runq *, void *), void *);
1450int runq_cancel(struct runq *, void (*)(struct runq *, void *), void *);
1451int runq_pending(struct runq *, void (*)(struct runq *, void *), void *, time_t *);
1452int runq_next(struct runq *, void (**)(struct runq *, void *), void **, time_t *);
1453