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