svn commit: r304534 - vendor/dma/20160806
Baptiste Daroussin
bapt at FreeBSD.org
Sat Aug 20 16:29:09 UTC 2016
Author: bapt
Date: Sat Aug 20 16:29:08 2016
New Revision: 304534
URL: https://svnweb.freebsd.org/changeset/base/304534
Log:
tag import of Dragonfly Mail Agent 20160806
Added:
vendor/dma/20160806/
- copied from r304532, vendor/dma/dist/
Replaced:
vendor/dma/20160806/VERSION
- copied unchanged from r304533, vendor/dma/dist/VERSION
vendor/dma/20160806/dma-mbox-create.c
- copied unchanged from r304533, vendor/dma/dist/dma-mbox-create.c
vendor/dma/20160806/dma.c
- copied unchanged from r304533, vendor/dma/dist/dma.c
vendor/dma/20160806/dma.h
- copied unchanged from r304533, vendor/dma/dist/dma.h
vendor/dma/20160806/dns.c
- copied unchanged from r304533, vendor/dma/dist/dns.c
vendor/dma/20160806/local.c
- copied unchanged from r304533, vendor/dma/dist/local.c
vendor/dma/20160806/net.c
- copied unchanged from r304533, vendor/dma/dist/net.c
Copied: vendor/dma/20160806/VERSION (from r304533, vendor/dma/dist/VERSION)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ vendor/dma/20160806/VERSION Sat Aug 20 16:29:08 2016 (r304534, copy of r304533, vendor/dma/dist/VERSION)
@@ -0,0 +1 @@
+v0.11
Copied: vendor/dma/20160806/dma-mbox-create.c (from r304533, vendor/dma/dist/dma-mbox-create.c)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ vendor/dma/20160806/dma-mbox-create.c Sat Aug 20 16:29:08 2016 (r304534, copy of r304533, vendor/dma/dist/dma-mbox-create.c)
@@ -0,0 +1,160 @@
+/*
+ * Copyright (c) 2010-2014, Simon Schubert <2 at 0x2c.org>.
+ * Copyright (c) 2008 The DragonFly Project. All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Simon Schubert <2 at 0x2c.org>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific, prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+/*
+ * This binary is setuid root. Use extreme caution when touching
+ * user-supplied information. Keep the root window as small as possible.
+ */
+
+#include <sys/param.h>
+#include <sys/stat.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <grp.h>
+#include <paths.h>
+#include <pwd.h>
+#include <stdio.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include "dma.h"
+
+
+static void
+logfail(int exitcode, const char *fmt, ...)
+{
+ int oerrno = errno;
+ va_list ap;
+ char outs[1024];
+
+ outs[0] = 0;
+ if (fmt != NULL) {
+ va_start(ap, fmt);
+ vsnprintf(outs, sizeof(outs), fmt, ap);
+ va_end(ap);
+ }
+
+ errno = oerrno;
+ if (*outs != 0)
+ syslog(LOG_ERR, errno ? "%s: %m" : "%s", outs);
+ else
+ syslog(LOG_ERR, errno ? "%m" : "unknown error");
+
+ exit(exitcode);
+}
+
+/*
+ * Create a mbox in /var/mail for a given user, or make sure
+ * the permissions are correct for dma.
+ */
+
+int
+main(int argc, char **argv)
+{
+ const char *user;
+ struct passwd *pw;
+ struct group *gr;
+ uid_t user_uid;
+ gid_t mail_gid;
+ int error;
+ char fn[PATH_MAX+1];
+ int f;
+
+ openlog("dma-mbox-create", 0, LOG_MAIL);
+
+ errno = 0;
+ gr = getgrnam(DMA_GROUP);
+ if (!gr)
+ logfail(EX_CONFIG, "cannot find dma group `%s'", DMA_GROUP);
+
+ mail_gid = gr->gr_gid;
+
+ if (setgid(mail_gid) != 0)
+ logfail(EX_NOPERM, "cannot set gid to %d (%s)", mail_gid, DMA_GROUP);
+ if (getegid() != mail_gid)
+ logfail(EX_NOPERM, "cannot set gid to %d (%s), still at %d", mail_gid, DMA_GROUP, getegid());
+
+ /*
+ * We take exactly one argument: the username.
+ */
+ if (argc != 2) {
+ errno = 0;
+ logfail(EX_USAGE, "no arguments");
+ }
+ user = argv[1];
+
+ syslog(LOG_NOTICE, "creating mbox for `%s'", user);
+
+ /* the username may not contain a pathname separator */
+ if (strchr(user, '/')) {
+ errno = 0;
+ logfail(EX_DATAERR, "path separator in username `%s'", user);
+ exit(1);
+ }
+
+ /* verify the user exists */
+ errno = 0;
+ pw = getpwnam(user);
+ if (!pw)
+ logfail(EX_NOUSER, "cannot find user `%s'", user);
+
+ user_uid = pw->pw_uid;
+
+ error = snprintf(fn, sizeof(fn), "%s/%s", _PATH_MAILDIR, user);
+ if (error < 0 || (size_t)error >= sizeof(fn)) {
+ if (error >= 0) {
+ errno = 0;
+ logfail(EX_USAGE, "mbox path too long");
+ }
+ logfail(EX_CANTCREAT, "cannot build mbox path for `%s/%s'", _PATH_MAILDIR, user);
+ }
+
+ f = open(fn, O_RDONLY|O_CREAT|O_NOFOLLOW, 0600);
+ if (f < 0)
+ logfail(EX_NOINPUT, "cannt open mbox `%s'", fn);
+
+ if (fchown(f, user_uid, mail_gid))
+ logfail(EX_OSERR, "cannot change owner of mbox `%s'", fn);
+
+ if (fchmod(f, 0620))
+ logfail(EX_OSERR, "cannot change permissions of mbox `%s'", fn);
+
+ /* file should be present with the right owner and permissions */
+
+ syslog(LOG_NOTICE, "successfully created mbox for `%s'", user);
+
+ return (0);
+}
Copied: vendor/dma/20160806/dma.c (from r304533, vendor/dma/dist/dma.c)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ vendor/dma/20160806/dma.c Sat Aug 20 16:29:08 2016 (r304534, copy of r304533, vendor/dma/dist/dma.c)
@@ -0,0 +1,632 @@
+/*
+ * Copyright (c) 2008-2014, Simon Schubert <2 at 0x2c.org>.
+ * Copyright (c) 2008 The DragonFly Project. All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Simon Schubert <2 at 0x2c.org>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific, prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#include "dfcompat.h"
+
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/stat.h>
+#include <sys/time.h>
+#include <sys/wait.h>
+
+#include <dirent.h>
+#include <err.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <inttypes.h>
+#include <paths.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <syslog.h>
+#include <unistd.h>
+
+#include "dma.h"
+
+
+static void deliver(struct qitem *);
+
+struct aliases aliases = LIST_HEAD_INITIALIZER(aliases);
+struct strlist tmpfs = SLIST_HEAD_INITIALIZER(tmpfs);
+struct authusers authusers = LIST_HEAD_INITIALIZER(authusers);
+char username[USERNAME_SIZE];
+uid_t useruid;
+const char *logident_base;
+char errmsg[ERRMSG_SIZE];
+
+static int daemonize = 1;
+static int doqueue = 0;
+
+struct config config = {
+ .smarthost = NULL,
+ .port = 25,
+ .aliases = "/etc/aliases",
+ .spooldir = "/var/spool/dma",
+ .authpath = NULL,
+ .certfile = NULL,
+ .features = 0,
+ .mailname = NULL,
+ .masquerade_host = NULL,
+ .masquerade_user = NULL,
+};
+
+
+static void
+sighup_handler(int signo)
+{
+ (void)signo; /* so that gcc doesn't complain */
+}
+
+static char *
+set_from(struct queue *queue, const char *osender)
+{
+ const char *addr;
+ char *sender;
+
+ if (osender) {
+ addr = osender;
+ } else if (getenv("EMAIL") != NULL) {
+ addr = getenv("EMAIL");
+ } else {
+ if (config.masquerade_user)
+ addr = config.masquerade_user;
+ else
+ addr = username;
+ }
+
+ if (!strchr(addr, '@')) {
+ const char *from_host = hostname();
+
+ if (config.masquerade_host)
+ from_host = config.masquerade_host;
+
+ if (asprintf(&sender, "%s@%s", addr, from_host) <= 0)
+ return (NULL);
+ } else {
+ sender = strdup(addr);
+ if (sender == NULL)
+ return (NULL);
+ }
+
+ if (strchr(sender, '\n') != NULL) {
+ errno = EINVAL;
+ return (NULL);
+ }
+
+ queue->sender = sender;
+ return (sender);
+}
+
+static int
+read_aliases(void)
+{
+ yyin = fopen(config.aliases, "r");
+ if (yyin == NULL) {
+ /*
+ * Non-existing aliases file is not a fatal error
+ */
+ if (errno == ENOENT)
+ return (0);
+ /* Other problems are. */
+ return (-1);
+ }
+ if (yyparse())
+ return (-1); /* fatal error, probably malloc() */
+ fclose(yyin);
+ return (0);
+}
+
+static int
+do_alias(struct queue *queue, const char *addr)
+{
+ struct alias *al;
+ struct stritem *sit;
+ int aliased = 0;
+
+ LIST_FOREACH(al, &aliases, next) {
+ if (strcmp(al->alias, addr) != 0)
+ continue;
+ SLIST_FOREACH(sit, &al->dests, next) {
+ if (add_recp(queue, sit->str, EXPAND_ADDR) != 0)
+ return (-1);
+ }
+ aliased = 1;
+ }
+
+ return (aliased);
+}
+
+int
+add_recp(struct queue *queue, const char *str, int expand)
+{
+ struct qitem *it, *tit;
+ struct passwd *pw;
+ char *host;
+ int aliased = 0;
+
+ it = calloc(1, sizeof(*it));
+ if (it == NULL)
+ return (-1);
+ it->addr = strdup(str);
+ if (it->addr == NULL)
+ return (-1);
+
+ it->sender = queue->sender;
+ host = strrchr(it->addr, '@');
+ if (host != NULL &&
+ (strcmp(host + 1, hostname()) == 0 ||
+ strcmp(host + 1, "localhost") == 0)) {
+ *host = 0;
+ }
+ LIST_FOREACH(tit, &queue->queue, next) {
+ /* weed out duplicate dests */
+ if (strcmp(tit->addr, it->addr) == 0) {
+ free(it->addr);
+ free(it);
+ return (0);
+ }
+ }
+ LIST_INSERT_HEAD(&queue->queue, it, next);
+
+ /**
+ * Do local delivery if there is no @.
+ * Do not do local delivery when NULLCLIENT is set.
+ */
+ if (strrchr(it->addr, '@') == NULL && (config.features & NULLCLIENT) == 0) {
+ it->remote = 0;
+ if (expand) {
+ aliased = do_alias(queue, it->addr);
+ if (!aliased && expand == EXPAND_WILDCARD)
+ aliased = do_alias(queue, "*");
+ if (aliased < 0)
+ return (-1);
+ if (aliased) {
+ LIST_REMOVE(it, next);
+ } else {
+ /* Local destination, check */
+ pw = getpwnam(it->addr);
+ if (pw == NULL)
+ goto out;
+ /* XXX read .forward */
+ endpwent();
+ }
+ }
+ } else {
+ it->remote = 1;
+ }
+
+ return (0);
+
+out:
+ free(it->addr);
+ free(it);
+ return (-1);
+}
+
+static struct qitem *
+go_background(struct queue *queue)
+{
+ struct sigaction sa;
+ struct qitem *it;
+ pid_t pid;
+
+ if (daemonize && daemon(0, 0) != 0) {
+ syslog(LOG_ERR, "can not daemonize: %m");
+ exit(EX_OSERR);
+ }
+ daemonize = 0;
+
+ bzero(&sa, sizeof(sa));
+ sa.sa_handler = SIG_IGN;
+ sigaction(SIGCHLD, &sa, NULL);
+
+ LIST_FOREACH(it, &queue->queue, next) {
+ /* No need to fork for the last dest */
+ if (LIST_NEXT(it, next) == NULL)
+ goto retit;
+
+ pid = fork();
+ switch (pid) {
+ case -1:
+ syslog(LOG_ERR, "can not fork: %m");
+ exit(EX_OSERR);
+ break;
+
+ case 0:
+ /*
+ * Child:
+ *
+ * return and deliver mail
+ */
+retit:
+ /*
+ * If necessary, acquire the queue and * mail files.
+ * If this fails, we probably were raced by another
+ * process. It is okay to be raced if we're supposed
+ * to flush the queue.
+ */
+ setlogident("%s", it->queueid);
+ switch (acquirespool(it)) {
+ case 0:
+ break;
+ case 1:
+ if (doqueue)
+ exit(EX_OK);
+ syslog(LOG_WARNING, "could not lock queue file");
+ exit(EX_SOFTWARE);
+ default:
+ exit(EX_SOFTWARE);
+ }
+ dropspool(queue, it);
+ return (it);
+
+ default:
+ /*
+ * Parent:
+ *
+ * fork next child
+ */
+ break;
+ }
+ }
+
+ syslog(LOG_CRIT, "reached dead code");
+ exit(EX_SOFTWARE);
+}
+
+static void
+deliver(struct qitem *it)
+{
+ int error;
+ unsigned int backoff = MIN_RETRY, slept;
+ struct timeval now;
+ struct stat st;
+
+ snprintf(errmsg, sizeof(errmsg), "unknown bounce reason");
+
+retry:
+ syslog(LOG_INFO, "<%s> trying delivery", it->addr);
+
+ if (it->remote)
+ error = deliver_remote(it);
+ else
+ error = deliver_local(it);
+
+ switch (error) {
+ case 0:
+ delqueue(it);
+ syslog(LOG_INFO, "<%s> delivery successful", it->addr);
+ exit(EX_OK);
+
+ case 1:
+ if (stat(it->queuefn, &st) != 0) {
+ syslog(LOG_ERR, "lost queue file `%s'", it->queuefn);
+ exit(EX_SOFTWARE);
+ }
+ if (gettimeofday(&now, NULL) == 0 &&
+ (now.tv_sec - st.st_mtim.tv_sec > MAX_TIMEOUT)) {
+ snprintf(errmsg, sizeof(errmsg),
+ "Could not deliver for the last %d seconds. Giving up.",
+ MAX_TIMEOUT);
+ goto bounce;
+ }
+ for (slept = 0; slept < backoff;) {
+ slept += SLEEP_TIMEOUT - sleep(SLEEP_TIMEOUT);
+ if (flushqueue_since(slept)) {
+ backoff = MIN_RETRY;
+ goto retry;
+ }
+ }
+ if (slept >= backoff) {
+ /* pick the next backoff between [1.5, 2.5) times backoff */
+ backoff = backoff + backoff / 2 + random() % backoff;
+ if (backoff > MAX_RETRY)
+ backoff = MAX_RETRY;
+ }
+ goto retry;
+
+ case -1:
+ default:
+ break;
+ }
+
+bounce:
+ bounce(it, errmsg);
+ /* NOTREACHED */
+}
+
+void
+run_queue(struct queue *queue)
+{
+ struct qitem *it;
+
+ if (LIST_EMPTY(&queue->queue))
+ return;
+
+ it = go_background(queue);
+ deliver(it);
+ /* NOTREACHED */
+}
+
+static void
+show_queue(struct queue *queue)
+{
+ struct qitem *it;
+ int locked = 0; /* XXX */
+
+ if (LIST_EMPTY(&queue->queue)) {
+ printf("Mail queue is empty\n");
+ return;
+ }
+
+ LIST_FOREACH(it, &queue->queue, next) {
+ printf("ID\t: %s%s\n"
+ "From\t: %s\n"
+ "To\t: %s\n",
+ it->queueid,
+ locked ? "*" : "",
+ it->sender, it->addr);
+
+ if (LIST_NEXT(it, next) != NULL)
+ printf("--\n");
+ }
+}
+
+/*
+ * TODO:
+ *
+ * - alias processing
+ * - use group permissions
+ * - proper sysexit codes
+ */
+
+int
+main(int argc, char **argv)
+{
+ struct sigaction act;
+ char *sender = NULL;
+ struct queue queue;
+ int i, ch;
+ int nodot = 0, showq = 0, queue_only = 0;
+ int recp_from_header = 0;
+
+ set_username();
+
+ /*
+ * We never run as root. If called by root, drop permissions
+ * to the mail user.
+ */
+ if (geteuid() == 0 || getuid() == 0) {
+ struct passwd *pw;
+
+ errno = 0;
+ pw = getpwnam(DMA_ROOT_USER);
+ if (pw == NULL) {
+ if (errno == 0)
+ errx(EX_CONFIG, "user '%s' not found", DMA_ROOT_USER);
+ else
+ err(EX_OSERR, "cannot drop root privileges");
+ }
+
+ if (setuid(pw->pw_uid) != 0)
+ err(EX_OSERR, "cannot drop root privileges");
+
+ if (geteuid() == 0 || getuid() == 0)
+ errx(EX_OSERR, "cannot drop root privileges");
+ }
+
+ atexit(deltmp);
+ init_random();
+
+ bzero(&queue, sizeof(queue));
+ LIST_INIT(&queue.queue);
+
+ if (strcmp(argv[0], "mailq") == 0) {
+ argv++; argc--;
+ showq = 1;
+ if (argc != 0)
+ errx(EX_USAGE, "invalid arguments");
+ goto skipopts;
+ } else if (strcmp(argv[0], "newaliases") == 0) {
+ logident_base = "dma";
+ setlogident(NULL);
+
+ if (read_aliases() != 0)
+ errx(EX_SOFTWARE, "could not parse aliases file `%s'", config.aliases);
+ exit(EX_OK);
+ }
+
+ opterr = 0;
+ while ((ch = getopt(argc, argv, ":A:b:B:C:d:Df:F:h:iL:N:no:O:q:r:R:tUV:vX:")) != -1) {
+ switch (ch) {
+ case 'A':
+ /* -AX is being ignored, except for -A{c,m} */
+ if (optarg[0] == 'c' || optarg[0] == 'm') {
+ break;
+ }
+ /* else FALLTRHOUGH */
+ case 'b':
+ /* -bX is being ignored, except for -bp */
+ if (optarg[0] == 'p') {
+ showq = 1;
+ break;
+ } else if (optarg[0] == 'q') {
+ queue_only = 1;
+ break;
+ }
+ /* else FALLTRHOUGH */
+ case 'D':
+ daemonize = 0;
+ break;
+ case 'L':
+ logident_base = optarg;
+ break;
+ case 'f':
+ case 'r':
+ sender = optarg;
+ break;
+
+ case 't':
+ recp_from_header = 1;
+ break;
+
+ case 'o':
+ /* -oX is being ignored, except for -oi */
+ if (optarg[0] != 'i')
+ break;
+ /* else FALLTRHOUGH */
+ case 'O':
+ break;
+ case 'i':
+ nodot = 1;
+ break;
+
+ case 'q':
+ /* Don't let getopt slup up other arguments */
+ if (optarg && *optarg == '-')
+ optind--;
+ doqueue = 1;
+ break;
+
+ /* Ignored options */
+ case 'B':
+ case 'C':
+ case 'd':
+ case 'F':
+ case 'h':
+ case 'N':
+ case 'n':
+ case 'R':
+ case 'U':
+ case 'V':
+ case 'v':
+ case 'X':
+ break;
+
+ case ':':
+ if (optopt == 'q') {
+ doqueue = 1;
+ break;
+ }
+ /* FALLTHROUGH */
+
+ default:
+ fprintf(stderr, "invalid argument: `-%c'\n", optopt);
+ exit(EX_USAGE);
+ }
+ }
+ argc -= optind;
+ argv += optind;
+ opterr = 1;
+
+ if (argc != 0 && (showq || doqueue))
+ errx(EX_USAGE, "sending mail and queue operations are mutually exclusive");
+
+ if (showq + doqueue > 1)
+ errx(EX_USAGE, "conflicting queue operations");
+
+skipopts:
+ if (logident_base == NULL)
+ logident_base = "dma";
+ setlogident(NULL);
+
+ act.sa_handler = sighup_handler;
+ act.sa_flags = 0;
+ sigemptyset(&act.sa_mask);
+ if (sigaction(SIGHUP, &act, NULL) != 0)
+ syslog(LOG_WARNING, "can not set signal handler: %m");
+
+ parse_conf(CONF_PATH "/dma.conf");
+
+ if (config.authpath != NULL)
+ parse_authfile(config.authpath);
+
+ if (showq) {
+ if (load_queue(&queue) < 0)
+ errlog(EX_NOINPUT, "can not load queue");
+ show_queue(&queue);
+ return (0);
+ }
+
+ if (doqueue) {
+ flushqueue_signal();
+ if (load_queue(&queue) < 0)
+ errlog(EX_NOINPUT, "can not load queue");
+ run_queue(&queue);
+ return (0);
+ }
+
+ if (read_aliases() != 0)
+ errlog(EX_SOFTWARE, "could not parse aliases file `%s'", config.aliases);
+
+ if ((sender = set_from(&queue, sender)) == NULL)
+ errlog(EX_SOFTWARE, NULL);
+
+ if (newspoolf(&queue) != 0)
+ errlog(EX_CANTCREAT, "can not create temp file in `%s'", config.spooldir);
+
+ setlogident("%s", queue.id);
+
+ for (i = 0; i < argc; i++) {
+ if (add_recp(&queue, argv[i], EXPAND_WILDCARD) != 0)
+ errlogx(EX_DATAERR, "invalid recipient `%s'", argv[i]);
+ }
+
+ if (LIST_EMPTY(&queue.queue) && !recp_from_header)
+ errlogx(EX_NOINPUT, "no recipients");
+
+ if (readmail(&queue, nodot, recp_from_header) != 0)
+ errlog(EX_NOINPUT, "can not read mail");
+
+ if (LIST_EMPTY(&queue.queue))
+ errlogx(EX_NOINPUT, "no recipients");
+
+ if (linkspool(&queue) != 0)
+ errlog(EX_CANTCREAT, "can not create spools");
+
+ /* From here on the mail is safe. */
+
+ if (config.features & DEFER || queue_only)
+ return (0);
+
+ run_queue(&queue);
+
+ /* NOTREACHED */
+ return (0);
+}
Copied: vendor/dma/20160806/dma.h (from r304533, vendor/dma/dist/dma.h)
==============================================================================
--- /dev/null 00:00:00 1970 (empty, because file is newly added)
+++ vendor/dma/20160806/dma.h Sat Aug 20 16:29:08 2016 (r304534, copy of r304533, vendor/dma/dist/dma.h)
@@ -0,0 +1,241 @@
+/*
+ * Copyright (c) 2008-2014, Simon Schubert <2 at 0x2c.org>.
+ * Copyright (c) 2008 The DragonFly Project. All rights reserved.
+ *
+ * This code is derived from software contributed to The DragonFly Project
+ * by Simon Schubert <2 at 0x2c.org> and
+ * Matthias Schmidt <matthias at dragonflybsd.org>.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in
+ * the documentation and/or other materials provided with the
+ * distribution.
+ * 3. Neither the name of The DragonFly Project nor the names of its
+ * contributors may be used to endorse or promote products derived
+ * from this software without specific, prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
+ * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+ * COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
+ * INCIDENTAL, SPECIAL, EXEMPLARY OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
+ * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
+ * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#ifndef DMA_H
+#define DMA_H
+
+#include <sys/types.h>
+#include <sys/queue.h>
+#include <sys/socket.h>
+#include <arpa/nameser.h>
+#include <arpa/inet.h>
+#include <openssl/ssl.h>
+#include <netdb.h>
+#include <sysexits.h>
+
+#define VERSION "DragonFly Mail Agent " DMA_VERSION
+
+#define BUF_SIZE 2048
+#define ERRMSG_SIZE 1024
+#define USERNAME_SIZE 50
+#define MIN_RETRY 300 /* 5 minutes */
+#define MAX_RETRY (3*60*60) /* retry at least every 3 hours */
+#define MAX_TIMEOUT (5*24*60*60) /* give up after 5 days */
+#define SLEEP_TIMEOUT 30 /* check for queue flush every 30 seconds */
+#ifndef PATH_MAX
+#define PATH_MAX 1024 /* Max path len */
+#endif
+#define SMTP_PORT 25 /* Default SMTP port */
+#define CON_TIMEOUT (5*60) /* Connection timeout per RFC5321 */
+
+#define STARTTLS 0x002 /* StartTLS support */
+#define SECURETRANS 0x004 /* SSL/TLS in general */
+#define NOSSL 0x008 /* Do not use SSL */
+#define DEFER 0x010 /* Defer mails */
+#define INSECURE 0x020 /* Allow plain login w/o encryption */
+#define FULLBOUNCE 0x040 /* Bounce the full message */
+#define TLS_OPP 0x080 /* Opportunistic STARTTLS */
+#define NULLCLIENT 0x100 /* Nullclient support */
+
+#ifndef CONF_PATH
+#error Please define CONF_PATH
+#endif
+
+#ifndef LIBEXEC_PATH
+#error Please define LIBEXEC_PATH
+#endif
+
+#define SPOOL_FLUSHFILE "flush"
+
+#ifndef DMA_ROOT_USER
+#define DMA_ROOT_USER "mail"
+#endif
+#ifndef DMA_GROUP
+#define DMA_GROUP "mail"
+#endif
+
+#ifndef MBOX_STRICT
+#define MBOX_STRICT 0
+#endif
+
+
+struct stritem {
+ SLIST_ENTRY(stritem) next;
+ char *str;
+};
+SLIST_HEAD(strlist, stritem);
+
+struct alias {
+ LIST_ENTRY(alias) next;
+ char *alias;
+ struct strlist dests;
+};
+LIST_HEAD(aliases, alias);
+
+struct qitem {
+ LIST_ENTRY(qitem) next;
+ const char *sender;
+ char *addr;
+ char *queuefn;
+ char *mailfn;
+ char *queueid;
+ FILE *queuef;
+ FILE *mailf;
+ int remote;
+};
+LIST_HEAD(queueh, qitem);
+
+struct queue {
+ struct queueh queue;
+ char *id;
+ FILE *mailf;
+ char *tmpf;
+ const char *sender;
+};
+
+struct config {
+ const char *smarthost;
+ int port;
+ const char *aliases;
+ const char *spooldir;
+ const char *authpath;
+ const char *certfile;
+ int features;
+ const char *mailname;
+ const char *masquerade_host;
+ const char *masquerade_user;
+
+ /* XXX does not belong into config */
+ SSL *ssl;
+};
+
+
+struct authuser {
+ SLIST_ENTRY(authuser) next;
+ char *login;
+ char *password;
+ char *host;
+};
+SLIST_HEAD(authusers, authuser);
+
+
+struct mx_hostentry {
+ char host[MAXDNAME];
+ char addr[INET6_ADDRSTRLEN];
+ int pref;
+ struct addrinfo ai;
+ struct sockaddr_storage sa;
+};
+
+
+/* global variables */
+extern struct aliases aliases;
+extern struct config config;
+extern struct strlist tmpfs;
+extern struct authusers authusers;
+extern char username[USERNAME_SIZE];
+extern uid_t useruid;
+extern const char *logident_base;
+
+extern char neterr[ERRMSG_SIZE];
+extern char errmsg[ERRMSG_SIZE];
+
+/* aliases_parse.y */
+int yyparse(void);
+int yywrap(void);
+int yylex(void);
+extern FILE *yyin;
+
+/* conf.c */
+void trim_line(char *);
+void parse_conf(const char *);
+void parse_authfile(const char *);
+
+/* crypto.c */
+void hmac_md5(unsigned char *, int, unsigned char *, int, unsigned char *);
+int smtp_auth_md5(int, char *, char *);
+int smtp_init_crypto(int, int);
+
+/* dns.c */
+int dns_get_mx_list(const char *, int, struct mx_hostentry **, int);
+
+/* net.c */
*** DIFF OUTPUT TRUNCATED AT 1000 LINES ***
More information about the svn-src-all
mailing list