1262266Sbapt/*
2289123Sbapt * Copyright (c) 2008-2014, Simon Schubert <2@0x2c.org>.
3262266Sbapt * Copyright (c) 2008 The DragonFly Project.  All rights reserved.
4262266Sbapt *
5262266Sbapt * This code is derived from software contributed to The DragonFly Project
6289123Sbapt * by Simon Schubert <2@0x2c.org> and
7262266Sbapt * Matthias Schmidt <matthias@dragonflybsd.org>.
8262266Sbapt *
9262266Sbapt * Redistribution and use in source and binary forms, with or without
10262266Sbapt * modification, are permitted provided that the following conditions
11262266Sbapt * are met:
12262266Sbapt *
13262266Sbapt * 1. Redistributions of source code must retain the above copyright
14262266Sbapt *    notice, this list of conditions and the following disclaimer.
15262266Sbapt * 2. Redistributions in binary form must reproduce the above copyright
16262266Sbapt *    notice, this list of conditions and the following disclaimer in
17262266Sbapt *    the documentation and/or other materials provided with the
18262266Sbapt *    distribution.
19262266Sbapt * 3. Neither the name of The DragonFly Project nor the names of its
20262266Sbapt *    contributors may be used to endorse or promote products derived
21262266Sbapt *    from this software without specific, prior written permission.
22262266Sbapt *
23262266Sbapt * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24262266Sbapt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25262266Sbapt * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
26262266Sbapt * FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE
27262266Sbapt * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
28262266Sbapt * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
29262266Sbapt * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30262266Sbapt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31262266Sbapt * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32262266Sbapt * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
33262266Sbapt * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34262266Sbapt * SUCH DAMAGE.
35262266Sbapt */
36262266Sbapt
37262266Sbapt#ifndef DMA_H
38262266Sbapt#define DMA_H
39262266Sbapt
40262266Sbapt#include <sys/types.h>
41262266Sbapt#include <sys/queue.h>
42262266Sbapt#include <sys/socket.h>
43262266Sbapt#include <arpa/nameser.h>
44262266Sbapt#include <arpa/inet.h>
45262266Sbapt#include <openssl/ssl.h>
46262266Sbapt#include <netdb.h>
47289123Sbapt#include <sysexits.h>
48262266Sbapt
49262266Sbapt#define VERSION	"DragonFly Mail Agent " DMA_VERSION
50262266Sbapt
51262266Sbapt#define BUF_SIZE	2048
52304587Sbapt#define ERRMSG_SIZE	1024
53262266Sbapt#define USERNAME_SIZE	50
54262266Sbapt#define MIN_RETRY	300		/* 5 minutes */
55262266Sbapt#define MAX_RETRY	(3*60*60)	/* retry at least every 3 hours */
56262266Sbapt#define MAX_TIMEOUT	(5*24*60*60)	/* give up after 5 days */
57262266Sbapt#define SLEEP_TIMEOUT	30		/* check for queue flush every 30 seconds */
58262266Sbapt#ifndef PATH_MAX
59262266Sbapt#define PATH_MAX	1024		/* Max path len */
60262266Sbapt#endif
61262266Sbapt#define	SMTP_PORT	25		/* Default SMTP port */
62262266Sbapt#define CON_TIMEOUT	(5*60)		/* Connection timeout per RFC5321 */
63262266Sbapt
64262266Sbapt#define STARTTLS	0x002		/* StartTLS support */
65262266Sbapt#define SECURETRANS	0x004		/* SSL/TLS in general */
66262266Sbapt#define NOSSL		0x008		/* Do not use SSL */
67262266Sbapt#define DEFER		0x010		/* Defer mails */
68262266Sbapt#define INSECURE	0x020		/* Allow plain login w/o encryption */
69262266Sbapt#define FULLBOUNCE	0x040		/* Bounce the full message */
70262266Sbapt#define TLS_OPP		0x080		/* Opportunistic STARTTLS */
71262266Sbapt#define NULLCLIENT	0x100		/* Nullclient support */
72262266Sbapt
73262266Sbapt#ifndef CONF_PATH
74262266Sbapt#error Please define CONF_PATH
75262266Sbapt#endif
76262266Sbapt
77262266Sbapt#ifndef LIBEXEC_PATH
78262266Sbapt#error Please define LIBEXEC_PATH
79262266Sbapt#endif
80262266Sbapt
81262266Sbapt#define SPOOL_FLUSHFILE	"flush"
82262266Sbapt
83262266Sbapt#ifndef DMA_ROOT_USER
84262266Sbapt#define DMA_ROOT_USER	"mail"
85262266Sbapt#endif
86262266Sbapt#ifndef DMA_GROUP
87262266Sbapt#define DMA_GROUP	"mail"
88262266Sbapt#endif
89262266Sbapt
90262266Sbapt#ifndef MBOX_STRICT
91262266Sbapt#define MBOX_STRICT	0
92262266Sbapt#endif
93262266Sbapt
94262266Sbapt
95262266Sbaptstruct stritem {
96262266Sbapt	SLIST_ENTRY(stritem) next;
97262266Sbapt	char *str;
98262266Sbapt};
99262266SbaptSLIST_HEAD(strlist, stritem);
100262266Sbapt
101262266Sbaptstruct alias {
102262266Sbapt	LIST_ENTRY(alias) next;
103262266Sbapt	char *alias;
104262266Sbapt	struct strlist dests;
105262266Sbapt};
106262266SbaptLIST_HEAD(aliases, alias);
107262266Sbapt
108262266Sbaptstruct qitem {
109262266Sbapt	LIST_ENTRY(qitem) next;
110262266Sbapt	const char *sender;
111262266Sbapt	char *addr;
112262266Sbapt	char *queuefn;
113262266Sbapt	char *mailfn;
114262266Sbapt	char *queueid;
115262266Sbapt	FILE *queuef;
116262266Sbapt	FILE *mailf;
117262266Sbapt	int remote;
118262266Sbapt};
119262266SbaptLIST_HEAD(queueh, qitem);
120262266Sbapt
121262266Sbaptstruct queue {
122262266Sbapt	struct queueh queue;
123262266Sbapt	char *id;
124262266Sbapt	FILE *mailf;
125262266Sbapt	char *tmpf;
126262266Sbapt	const char *sender;
127262266Sbapt};
128262266Sbapt
129262266Sbaptstruct config {
130262266Sbapt	const char *smarthost;
131262266Sbapt	int port;
132262266Sbapt	const char *aliases;
133262266Sbapt	const char *spooldir;
134262266Sbapt	const char *authpath;
135262266Sbapt	const char *certfile;
136262266Sbapt	int features;
137262266Sbapt	const char *mailname;
138262266Sbapt	const char *masquerade_host;
139262266Sbapt	const char *masquerade_user;
140262266Sbapt
141262266Sbapt	/* XXX does not belong into config */
142262266Sbapt	SSL *ssl;
143262266Sbapt};
144262266Sbapt
145262266Sbapt
146262266Sbaptstruct authuser {
147262266Sbapt	SLIST_ENTRY(authuser) next;
148262266Sbapt	char *login;
149262266Sbapt	char *password;
150262266Sbapt	char *host;
151262266Sbapt};
152262266SbaptSLIST_HEAD(authusers, authuser);
153262266Sbapt
154262266Sbapt
155262266Sbaptstruct mx_hostentry {
156262266Sbapt	char		host[MAXDNAME];
157262266Sbapt	char		addr[INET6_ADDRSTRLEN];
158262266Sbapt	int		pref;
159262266Sbapt	struct addrinfo	ai;
160262266Sbapt	struct sockaddr_storage	sa;
161262266Sbapt};
162262266Sbapt
163262266Sbapt
164262266Sbapt/* global variables */
165262266Sbaptextern struct aliases aliases;
166262266Sbaptextern struct config config;
167262266Sbaptextern struct strlist tmpfs;
168262266Sbaptextern struct authusers authusers;
169262266Sbaptextern char username[USERNAME_SIZE];
170262266Sbaptextern uid_t useruid;
171262266Sbaptextern const char *logident_base;
172262266Sbapt
173262266Sbaptextern char neterr[ERRMSG_SIZE];
174262266Sbaptextern char errmsg[ERRMSG_SIZE];
175262266Sbapt
176262266Sbapt/* aliases_parse.y */
177262266Sbaptint yyparse(void);
178289123Sbaptint yywrap(void);
179289123Sbaptint yylex(void);
180262266Sbaptextern FILE *yyin;
181262266Sbapt
182262266Sbapt/* conf.c */
183262266Sbaptvoid trim_line(char *);
184262266Sbaptvoid parse_conf(const char *);
185262266Sbaptvoid parse_authfile(const char *);
186262266Sbapt
187262266Sbapt/* crypto.c */
188262266Sbaptvoid hmac_md5(unsigned char *, int, unsigned char *, int, unsigned char *);
189262266Sbaptint smtp_auth_md5(int, char *, char *);
190262266Sbaptint smtp_init_crypto(int, int);
191262266Sbapt
192262266Sbapt/* dns.c */
193262266Sbaptint dns_get_mx_list(const char *, int, struct mx_hostentry **, int);
194262266Sbapt
195262266Sbapt/* net.c */
196262266Sbaptchar *ssl_errstr(void);
197262266Sbaptint read_remote(int, int, char *);
198262266Sbaptssize_t send_remote_command(int, const char*, ...)  __attribute__((__nonnull__(2), __format__ (__printf__, 2, 3)));
199262266Sbaptint deliver_remote(struct qitem *);
200262266Sbapt
201262266Sbapt/* base64.c */
202262266Sbaptint base64_encode(const void *, int, char **);
203262266Sbaptint base64_decode(const char *, void *);
204262266Sbapt
205262266Sbapt/* dma.c */
206262266Sbapt#define EXPAND_ADDR	1
207262266Sbapt#define EXPAND_WILDCARD	2
208262266Sbaptint add_recp(struct queue *, const char *, int);
209262266Sbaptvoid run_queue(struct queue *);
210262266Sbapt
211262266Sbapt/* spool.c */
212262266Sbaptint newspoolf(struct queue *);
213262266Sbaptint linkspool(struct queue *);
214262266Sbaptint load_queue(struct queue *);
215262266Sbaptvoid delqueue(struct qitem *);
216262266Sbaptint acquirespool(struct qitem *);
217262266Sbaptvoid dropspool(struct queue *, struct qitem *);
218262266Sbaptint flushqueue_since(unsigned int);
219262266Sbaptint flushqueue_signal(void);
220262266Sbapt
221262266Sbapt/* local.c */
222262266Sbaptint deliver_local(struct qitem *);
223262266Sbapt
224262266Sbapt/* mail.c */
225262266Sbaptvoid bounce(struct qitem *, const char *);
226262266Sbaptint readmail(struct queue *, int, int);
227262266Sbapt
228262266Sbapt/* util.c */
229262266Sbaptconst char *hostname(void);
230262266Sbaptvoid setlogident(const char *, ...) __attribute__((__format__ (__printf__, 1, 2)));
231262266Sbaptvoid errlog(int, const char *, ...) __attribute__((__format__ (__printf__, 2, 3)));
232262266Sbaptvoid errlogx(int, const char *, ...) __attribute__((__format__ (__printf__, 2, 3)));
233262266Sbaptvoid set_username(void);
234262266Sbaptvoid deltmp(void);
235262266Sbaptint do_timeout(int, int);
236262266Sbaptint open_locked(const char *, int, ...);
237262266Sbaptchar *rfc822date(void);
238262266Sbaptint strprefixcmp(const char *, const char *);
239262266Sbaptvoid init_random(void);
240262266Sbapt
241262266Sbapt#endif
242