1f67bedddSMatthias Schmidt /* 237d59876SJohn Marino * Copyright (c) 2008-2014, Simon Schubert <2@0x2c.org>. 3f67bedddSMatthias Schmidt * Copyright (c) 2008 The DragonFly Project. All rights reserved. 4f67bedddSMatthias Schmidt * 5f67bedddSMatthias Schmidt * This code is derived from software contributed to The DragonFly Project 637d59876SJohn Marino * by Simon Schubert <2@0x2c.org> and 7f67bedddSMatthias Schmidt * Matthias Schmidt <matthias@dragonflybsd.org>. 8f67bedddSMatthias Schmidt * 9f67bedddSMatthias Schmidt * Redistribution and use in source and binary forms, with or without 10f67bedddSMatthias Schmidt * modification, are permitted provided that the following conditions 11f67bedddSMatthias Schmidt * are met: 12f67bedddSMatthias Schmidt * 13f67bedddSMatthias Schmidt * 1. Redistributions of source code must retain the above copyright 14f67bedddSMatthias Schmidt * notice, this list of conditions and the following disclaimer. 15f67bedddSMatthias Schmidt * 2. Redistributions in binary form must reproduce the above copyright 16f67bedddSMatthias Schmidt * notice, this list of conditions and the following disclaimer in 17f67bedddSMatthias Schmidt * the documentation and/or other materials provided with the 18f67bedddSMatthias Schmidt * distribution. 19f67bedddSMatthias Schmidt * 3. Neither the name of The DragonFly Project nor the names of its 20f67bedddSMatthias Schmidt * contributors may be used to endorse or promote products derived 21f67bedddSMatthias Schmidt * from this software without specific, prior written permission. 22f67bedddSMatthias Schmidt * 23f67bedddSMatthias Schmidt * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 24f67bedddSMatthias Schmidt * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 25f67bedddSMatthias Schmidt * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 26f67bedddSMatthias Schmidt * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 27f67bedddSMatthias Schmidt * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, 28f67bedddSMatthias Schmidt * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING, 29f67bedddSMatthias Schmidt * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 30f67bedddSMatthias Schmidt * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 31f67bedddSMatthias Schmidt * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 32f67bedddSMatthias Schmidt * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 33f67bedddSMatthias Schmidt * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 34f67bedddSMatthias Schmidt * SUCH DAMAGE. 35f67bedddSMatthias Schmidt */ 36f67bedddSMatthias Schmidt 37f67bedddSMatthias Schmidt #ifndef DMA_H 38f67bedddSMatthias Schmidt #define DMA_H 39f67bedddSMatthias Schmidt 403021968aSSimon Schubert #include <sys/types.h> 41f67bedddSMatthias Schmidt #include <sys/queue.h> 423021968aSSimon Schubert #include <sys/socket.h> 433021968aSSimon Schubert #include <arpa/nameser.h> 443021968aSSimon Schubert #include <arpa/inet.h> 453021968aSSimon Schubert #include <openssl/ssl.h> 463021968aSSimon Schubert #include <netdb.h> 4792fe556dSDaniel Fojt #include <sysexits.h> 48f67bedddSMatthias Schmidt 49c8b07ee5SSascha Wildner #define VERSION "DragonFly Mail Agent " DMA_VERSION 50f67bedddSMatthias Schmidt 51f67bedddSMatthias Schmidt #define BUF_SIZE 2048 5292fe556dSDaniel Fojt #define ERRMSG_SIZE 1024 53c8b07ee5SSascha Wildner #define USERNAME_SIZE 50 5492fe556dSDaniel Fojt #define EHLO_RESPONSE_SIZE BUF_SIZE 55f67bedddSMatthias Schmidt #define MIN_RETRY 300 /* 5 minutes */ 56f67bedddSMatthias Schmidt #define MAX_RETRY (3*60*60) /* retry at least every 3 hours */ 57f67bedddSMatthias Schmidt #define MAX_TIMEOUT (5*24*60*60) /* give up after 5 days */ 5814dfb991SJoris Giovannangeli #define SLEEP_TIMEOUT 30 /* check for queue flush every 30 seconds */ 59144b337dSSimon Schubert #ifndef PATH_MAX 60f67bedddSMatthias Schmidt #define PATH_MAX 1024 /* Max path len */ 61144b337dSSimon Schubert #endif 6201c2a160SMatthias Schmidt #define SMTP_PORT 25 /* Default SMTP port */ 63c8b07ee5SSascha Wildner #define CON_TIMEOUT (5*60) /* Connection timeout per RFC5321 */ 64f67bedddSMatthias Schmidt 6501c2a160SMatthias Schmidt #define STARTTLS 0x002 /* StartTLS support */ 6692fe556dSDaniel Fojt #define SECURETRANSFER 0x004 /* SSL/TLS in general */ 676ef9fe01SMatthias Schmidt #define NOSSL 0x008 /* Do not use SSL */ 6801c2a160SMatthias Schmidt #define DEFER 0x010 /* Defer mails */ 6901c2a160SMatthias Schmidt #define INSECURE 0x020 /* Allow plain login w/o encryption */ 705ca28cf6SSimon Schubert #define FULLBOUNCE 0x040 /* Bounce the full message */ 71c8b07ee5SSascha Wildner #define TLS_OPP 0x080 /* Opportunistic STARTTLS */ 7214dfb991SJoris Giovannangeli #define NULLCLIENT 0x100 /* Nullclient support */ 7301c2a160SMatthias Schmidt 74f4e61a9fSSimon 'corecode' Schubert #ifndef CONF_PATH 75c8b07ee5SSascha Wildner #error Please define CONF_PATH 76f4e61a9fSSimon 'corecode' Schubert #endif 77f67bedddSMatthias Schmidt 78c8b07ee5SSascha Wildner #ifndef LIBEXEC_PATH 79c8b07ee5SSascha Wildner #error Please define LIBEXEC_PATH 80c8b07ee5SSascha Wildner #endif 81c8b07ee5SSascha Wildner 8214dfb991SJoris Giovannangeli #define SPOOL_FLUSHFILE "flush" 8314dfb991SJoris Giovannangeli 8414dfb991SJoris Giovannangeli #ifndef DMA_ROOT_USER 85c8b07ee5SSascha Wildner #define DMA_ROOT_USER "mail" 8614dfb991SJoris Giovannangeli #endif 8714dfb991SJoris Giovannangeli #ifndef DMA_GROUP 88c8b07ee5SSascha Wildner #define DMA_GROUP "mail" 8914dfb991SJoris Giovannangeli #endif 90c8b07ee5SSascha Wildner 91c8b07ee5SSascha Wildner #ifndef MBOX_STRICT 92c8b07ee5SSascha Wildner #define MBOX_STRICT 0 93c8b07ee5SSascha Wildner #endif 94c8b07ee5SSascha Wildner 95c8b07ee5SSascha Wildner 96f67bedddSMatthias Schmidt struct stritem { 97f67bedddSMatthias Schmidt SLIST_ENTRY(stritem) next; 98f67bedddSMatthias Schmidt char *str; 99f67bedddSMatthias Schmidt }; 100f67bedddSMatthias Schmidt SLIST_HEAD(strlist, stritem); 101f67bedddSMatthias Schmidt 102f67bedddSMatthias Schmidt struct alias { 103f67bedddSMatthias Schmidt LIST_ENTRY(alias) next; 104f67bedddSMatthias Schmidt char *alias; 105f67bedddSMatthias Schmidt struct strlist dests; 106f67bedddSMatthias Schmidt }; 107f67bedddSMatthias Schmidt LIST_HEAD(aliases, alias); 108f67bedddSMatthias Schmidt 109f67bedddSMatthias Schmidt struct qitem { 110f67bedddSMatthias Schmidt LIST_ENTRY(qitem) next; 111f67bedddSMatthias Schmidt const char *sender; 112f67bedddSMatthias Schmidt char *addr; 113f67bedddSMatthias Schmidt char *queuefn; 114f4e61a9fSSimon 'corecode' Schubert char *mailfn; 115f67bedddSMatthias Schmidt char *queueid; 1169afa363fSSimon Schubert FILE *queuef; 117f4e61a9fSSimon 'corecode' Schubert FILE *mailf; 1184a23bd3dSMatthias Schmidt int remote; 119f67bedddSMatthias Schmidt }; 120f67bedddSMatthias Schmidt LIST_HEAD(queueh, qitem); 121f67bedddSMatthias Schmidt 122f67bedddSMatthias Schmidt struct queue { 123f67bedddSMatthias Schmidt struct queueh queue; 124405f48eeSSimon Schubert char *id; 1259afa363fSSimon Schubert FILE *mailf; 126f67bedddSMatthias Schmidt char *tmpf; 1271c9e6b7bSSimon Schubert const char *sender; 128f67bedddSMatthias Schmidt }; 129f67bedddSMatthias Schmidt 130f67bedddSMatthias Schmidt struct config { 131ca259d14SSimon Schubert const char *smarthost; 132f67bedddSMatthias Schmidt int port; 133ca259d14SSimon Schubert const char *aliases; 134ca259d14SSimon Schubert const char *spooldir; 135ca259d14SSimon Schubert const char *authpath; 136ca259d14SSimon Schubert const char *certfile; 137f67bedddSMatthias Schmidt int features; 138ca259d14SSimon Schubert const char *mailname; 139c8b07ee5SSascha Wildner const char *masquerade_host; 140c8b07ee5SSascha Wildner const char *masquerade_user; 14192fe556dSDaniel Fojt const unsigned char *fingerprint; 142ca259d14SSimon Schubert 143ca259d14SSimon Schubert /* XXX does not belong into config */ 144f67bedddSMatthias Schmidt SSL *ssl; 145f67bedddSMatthias Schmidt }; 146f67bedddSMatthias Schmidt 147f67bedddSMatthias Schmidt 148f67bedddSMatthias Schmidt struct authuser { 149f67bedddSMatthias Schmidt SLIST_ENTRY(authuser) next; 150f67bedddSMatthias Schmidt char *login; 151f67bedddSMatthias Schmidt char *password; 152f67bedddSMatthias Schmidt char *host; 153f67bedddSMatthias Schmidt }; 154f67bedddSMatthias Schmidt SLIST_HEAD(authusers, authuser); 155f67bedddSMatthias Schmidt 156f4e61a9fSSimon 'corecode' Schubert 1573021968aSSimon Schubert struct mx_hostentry { 1583021968aSSimon Schubert char host[MAXDNAME]; 1593021968aSSimon Schubert char addr[INET6_ADDRSTRLEN]; 1603021968aSSimon Schubert int pref; 1613021968aSSimon Schubert struct addrinfo ai; 1623021968aSSimon Schubert struct sockaddr_storage sa; 1633021968aSSimon Schubert }; 1643021968aSSimon Schubert 16592fe556dSDaniel Fojt struct smtp_auth_mechanisms { 16692fe556dSDaniel Fojt int cram_md5; 16792fe556dSDaniel Fojt int login; 16892fe556dSDaniel Fojt }; 16992fe556dSDaniel Fojt 17092fe556dSDaniel Fojt struct smtp_features { 17192fe556dSDaniel Fojt struct smtp_auth_mechanisms auth; 17292fe556dSDaniel Fojt int starttls; 17392fe556dSDaniel Fojt }; 1743021968aSSimon Schubert 175f4e61a9fSSimon 'corecode' Schubert /* global variables */ 176f67bedddSMatthias Schmidt extern struct aliases aliases; 177ca259d14SSimon Schubert extern struct config config; 178f4e61a9fSSimon 'corecode' Schubert extern struct strlist tmpfs; 179f4e61a9fSSimon 'corecode' Schubert extern struct authusers authusers; 180c8b07ee5SSascha Wildner extern char username[USERNAME_SIZE]; 181c8b07ee5SSascha Wildner extern uid_t useruid; 1821da0a9f2SSimon Schubert extern const char *logident_base; 183f67bedddSMatthias Schmidt 184c8b07ee5SSascha Wildner extern char neterr[ERRMSG_SIZE]; 185c8b07ee5SSascha Wildner extern char errmsg[ERRMSG_SIZE]; 186a5a8a1a4SSimon Schubert 187f67bedddSMatthias Schmidt /* conf.c */ 188f4e61a9fSSimon 'corecode' Schubert void trim_line(char *); 189ca259d14SSimon Schubert void parse_conf(const char *); 190ca259d14SSimon Schubert void parse_authfile(const char *); 191f67bedddSMatthias Schmidt 192f67bedddSMatthias Schmidt /* crypto.c */ 193c8b07ee5SSascha Wildner void hmac_md5(unsigned char *, int, unsigned char *, int, unsigned char *); 194405f48eeSSimon Schubert int smtp_auth_md5(int, char *, char *); 19592fe556dSDaniel Fojt int smtp_init_crypto(int, int, struct smtp_features*); 196f67bedddSMatthias Schmidt 1973021968aSSimon Schubert /* dns.c */ 1983021968aSSimon Schubert int dns_get_mx_list(const char *, int, struct mx_hostentry **, int); 1993021968aSSimon Schubert 200f67bedddSMatthias Schmidt /* net.c */ 201f4e61a9fSSimon 'corecode' Schubert char *ssl_errstr(void); 202f4e61a9fSSimon 'corecode' Schubert int read_remote(int, int, char *); 20314dfb991SJoris Giovannangeli ssize_t send_remote_command(int, const char*, ...) __attribute__((__nonnull__(2), __format__ (__printf__, 2, 3))); 20492fe556dSDaniel Fojt int perform_server_greeting(int, struct smtp_features*); 205c8b07ee5SSascha Wildner int deliver_remote(struct qitem *); 206f67bedddSMatthias Schmidt 207f67bedddSMatthias Schmidt /* base64.c */ 208f4e61a9fSSimon 'corecode' Schubert int base64_encode(const void *, int, char **); 209f4e61a9fSSimon 'corecode' Schubert int base64_decode(const char *, void *); 210f67bedddSMatthias Schmidt 211f67bedddSMatthias Schmidt /* dma.c */ 212c8b07ee5SSascha Wildner #define EXPAND_ADDR 1 213c8b07ee5SSascha Wildner #define EXPAND_WILDCARD 2 2141c9e6b7bSSimon Schubert int add_recp(struct queue *, const char *, int); 21530833a29SSimon Schubert void run_queue(struct queue *); 216f4e61a9fSSimon 'corecode' Schubert 217f4e61a9fSSimon 'corecode' Schubert /* spool.c */ 2181c9e6b7bSSimon Schubert int newspoolf(struct queue *); 2191c9e6b7bSSimon Schubert int linkspool(struct queue *); 2201da0a9f2SSimon Schubert int load_queue(struct queue *); 221f4e61a9fSSimon 'corecode' Schubert void delqueue(struct qitem *); 22224c80b2bSSascha Wildner int acquirespool(struct qitem *); 2239afa363fSSimon Schubert void dropspool(struct queue *, struct qitem *); 22414dfb991SJoris Giovannangeli int flushqueue_since(unsigned int); 22514dfb991SJoris Giovannangeli int flushqueue_signal(void); 226f4e61a9fSSimon 'corecode' Schubert 227f4e61a9fSSimon 'corecode' Schubert /* local.c */ 228c8b07ee5SSascha Wildner int deliver_local(struct qitem *); 2291da0a9f2SSimon Schubert 23030833a29SSimon Schubert /* mail.c */ 231b9c8dce8SSascha Wildner void bounce(struct qitem *, const char *) __attribute__((__noreturn__)); 232ff48fce6SSimon Schubert int readmail(struct queue *, int, int); 23330833a29SSimon Schubert 2341da0a9f2SSimon Schubert /* util.c */ 2351da0a9f2SSimon Schubert const char *hostname(void); 236*577b958fSDaniel Fojt const char *systemhostname(void); 23714dfb991SJoris Giovannangeli void setlogident(const char *, ...) __attribute__((__format__ (__printf__, 1, 2))); 238b9c8dce8SSascha Wildner void errlog(int, const char *, ...) __attribute__((__format__ (__printf__, 2, 3))) __attribute__((__noreturn__)); 239b9c8dce8SSascha Wildner void errlogx(int, const char *, ...) __attribute__((__format__ (__printf__, 2, 3))) __attribute__((__noreturn__)); 2401da0a9f2SSimon Schubert void set_username(void); 2411da0a9f2SSimon Schubert void deltmp(void); 242c8b07ee5SSascha Wildner int do_timeout(int, int); 2431da0a9f2SSimon Schubert int open_locked(const char *, int, ...); 2441da0a9f2SSimon Schubert char *rfc822date(void); 2451da0a9f2SSimon Schubert int strprefixcmp(const char *, const char *); 246c8b07ee5SSascha Wildner void init_random(void); 2471da0a9f2SSimon Schubert 248f67bedddSMatthias Schmidt #endif 249