diff -x .git* -x bsd -ruN ./freebsd/contrib/dma/conf.c ./dma/conf.c --- ./freebsd/contrib/dma/conf.c 2021-06-14 22:02:27.368720000 +0200 +++ ./dma/conf.c 2021-06-14 21:13:02.806895000 +0200 @@ -236,7 +236,7 @@ } else if (strcmp(word, "OPPORTUNISTIC_TLS") == 0 && data == NULL) config.features |= TLS_OPP; else if (strcmp(word, "SECURETRANSFER") == 0 && data == NULL) - config.features |= SECURETRANS; + config.features |= SECURETRANSFER; else if (strcmp(word, "DEFER") == 0 && data == NULL) config.features |= DEFER; else if (strcmp(word, "INSECURE") == 0 && data == NULL) diff -x .git* -x bsd -ruN ./freebsd/contrib/dma/crypto.c ./dma/crypto.c --- ./freebsd/contrib/dma/crypto.c 2021-06-14 22:02:27.370522000 +0200 +++ ./dma/crypto.c 2021-06-14 21:13:02.807867000 +0200 @@ -46,8 +46,6 @@ #include "dma.h" -int verify_server_fingerprint(const X509 *cert); - static int init_cert_file(SSL_CTX *ctx, const char *path) { @@ -80,7 +78,7 @@ return (0); } -int +static int verify_server_fingerprint(const X509 *cert) { unsigned char fingerprint[EVP_MAX_MD_SIZE] = {0}; @@ -145,7 +143,7 @@ /* * If the user wants STARTTLS, we have to send EHLO here */ - if (((feature & SECURETRANS) != 0) && + if (((feature & SECURETRANSFER) != 0) && (feature & STARTTLS) != 0) { /* TLS init phase, disable SSL_write */ config.features |= NOSSL; @@ -161,6 +159,10 @@ return (0); } } + } else { + syslog(LOG_ERR, "remote delivery deferred: could not perform server greeting: %s", + neterr); + return (1); } /* End of TLS init phase, enable SSL_write/read */ diff -x .git* -x bsd -ruN ./freebsd/contrib/dma/dfcompat.c ./dma/dfcompat.c --- ./freebsd/contrib/dma/dfcompat.c 2021-06-14 22:02:27.373888000 +0200 +++ ./dma/dfcompat.c 2021-06-14 21:13:02.808511000 +0200 @@ -96,7 +96,7 @@ void *nptr; nptr = realloc(ptr, size); - if (!nptr && ptr) + if (!nptr && ptr && size != 0) free(ptr); return (nptr); } diff -x .git* -x bsd -ruN ./freebsd/contrib/dma/dma.8 ./dma/dma.8 --- ./freebsd/contrib/dma/dma.8 2021-06-14 22:02:27.383641000 +0200 +++ ./dma/dma.8 2021-06-14 21:13:02.810769000 +0200 @@ -82,7 +82,7 @@ .Pp All other .Ar mode Ns -s are are ignored. +s are ignored. .It Fl D Don't run in the background. Useful for debugging. @@ -216,7 +216,7 @@ Path to the .Sq auth.conf file. -.It Ic SECURETRANS Xo +.It Ic SECURETRANSFER Xo (boolean, default=commented) .Xc Uncomment if you want TLS/SSL secured transfer. @@ -225,8 +225,10 @@ .Xc Uncomment if you want to use STARTTLS. Only useful together with -.Sq SECURETRANS . +.Sq SECURETRANSFER . .It Ic FINGERPRINT Xo +(string, default=empty) +.Xc Pin the server certificate by specifying its SHA256 fingerprint. Only makes sense if you use a smarthost. .It Ic OPPORTUNISTIC_TLS Xo @@ -240,7 +242,7 @@ be encrypted if the remote server supports STARTTLS, but an unencrypted delivery will still be made if the negotiation fails. Only useful together with -.Sq SECURETRANS +.Sq SECURETRANSFER and .Sq STARTTLS . .It Ic CERTFILE Xo @@ -314,6 +316,7 @@ .Ql Sm off Va username @percolator . .Sm on .It Ic NULLCLIENT Xo +(boolean, default=commented) .Xc Bypass aliases and local delivery, and instead forward all mails to the defined diff -x .git* -x bsd -ruN ./freebsd/contrib/dma/dma.c ./dma/dma.c --- ./freebsd/contrib/dma/dma.c 2021-06-14 22:02:27.388322000 +0200 +++ ./dma/dma.c 2021-06-14 21:13:02.811568000 +0200 @@ -331,8 +331,8 @@ switch (error) { case 0: - delqueue(it); syslog(LOG_INFO, "<%s> delivery successful", it->addr); + delqueue(it); exit(EX_OK); case 1: @@ -422,9 +422,10 @@ { struct sigaction act; char *sender = NULL; + char *own_name = NULL; struct queue queue; int i, ch; - int nodot = 0, showq = 0, queue_only = 0; + int nodot = 0, showq = 0, queue_only = 0, newaliases = 0; int recp_from_header = 0; set_username(); @@ -458,19 +459,17 @@ bzero(&queue, sizeof(queue)); LIST_INIT(&queue.queue); - if (strcmp(basename(argv[0]), "mailq") == 0) { + own_name = basename(argv[0]); + + if (strcmp(own_name, "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); + } else if (strcmp(own_name, "newaliases") == 0) { + newaliases = 1; + goto skipopts; } opterr = 0; @@ -481,7 +480,7 @@ if (optarg[0] == 'c' || optarg[0] == 'm') { break; } - /* else FALLTRHOUGH */ + /* Else FALLTHROUGH */ case 'b': /* -bX is being ignored, except for -bp */ if (optarg[0] == 'p') { @@ -491,7 +490,7 @@ queue_only = 1; break; } - /* else FALLTRHOUGH */ + /* Else FALLTHROUGH */ case 'D': daemonize = 0; break; @@ -511,7 +510,7 @@ /* -oX is being ignored, except for -oi */ if (optarg[0] != 'i') break; - /* else FALLTRHOUGH */ + /* Else FALLTHROUGH */ case 'O': break; case 'i': @@ -545,7 +544,7 @@ doqueue = 1; break; } - /* FALLTHROUGH */ + /* Else FALLTHROUGH */ default: fprintf(stderr, "invalid argument: `-%c'\n", optopt); @@ -595,6 +594,9 @@ if (read_aliases() != 0) errlog(EX_SOFTWARE, "could not parse aliases file `%s'", config.aliases); + + if (newaliases) + return(0); if ((sender = set_from(&queue, sender)) == NULL) errlog(EX_SOFTWARE, NULL); diff -x .git* -x bsd -ruN ./freebsd/contrib/dma/dma.h ./dma/dma.h --- ./freebsd/contrib/dma/dma.h 2021-06-14 22:02:27.391863000 +0200 +++ ./dma/dma.h 2021-06-14 21:13:02.813099000 +0200 @@ -63,7 +63,7 @@ #define CON_TIMEOUT (5*60) /* Connection timeout per RFC5321 */ #define STARTTLS 0x002 /* StartTLS support */ -#define SECURETRANS 0x004 /* SSL/TLS in general */ +#define SECURETRANSFER 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 */ @@ -239,6 +239,7 @@ /* util.c */ const char *hostname(void); +const char *systemhostname(void); void setlogident(const char *, ...) __attribute__((__format__ (__printf__, 1, 2))); void errlog(int, const char *, ...) __attribute__((__format__ (__printf__, 2, 3))); void errlogx(int, const char *, ...) __attribute__((__format__ (__printf__, 2, 3))); diff -x .git* -x bsd -ruN ./freebsd/contrib/dma/dns.c ./dma/dns.c --- ./freebsd/contrib/dma/dns.c 2021-01-03 20:47:34.984202000 +0100 +++ ./dma/dns.c 2021-06-14 21:13:02.813807000 +0200 @@ -271,11 +271,6 @@ *he = hosts; return (err); - - free(ans); - if (hosts != NULL) - free(hosts); - return (err); } #if defined(TESTING) diff -x .git* -x bsd -ruN ./freebsd/contrib/dma/local.c ./dma/local.c --- ./freebsd/contrib/dma/local.c 2021-06-14 22:02:27.393147000 +0200 +++ ./dma/local.c 2021-06-14 21:13:02.815194000 +0200 @@ -82,7 +82,7 @@ for (i = 3; i <= maxfd; ++i) close(i); - execl(LIBEXEC_PATH "/dma-mbox-create", "dma-mbox-create", name, NULL); + execl(LIBEXEC_PATH "/dma-mbox-create", "dma-mbox-create", name, (char *)NULL); syslog(LOG_ERR, "cannot execute "LIBEXEC_PATH"/dma-mbox-create: %m"); exit(EX_SOFTWARE); diff -x .git* -x bsd -ruN ./freebsd/contrib/dma/mail.c ./dma/mail.c --- ./freebsd/contrib/dma/mail.c 2021-06-14 22:02:27.394899000 +0200 +++ ./dma/mail.c 2021-06-14 21:13:02.815956000 +0200 @@ -72,7 +72,7 @@ error = fprintf(bounceq.mailf, "Received: from MAILER-DAEMON\n" "\tid %s\n" - "\tby %s (%s);\n" + "\tby %s (%s on %s);\n" "\t%s\n" "X-Original-To: <%s>\n" "From: MAILER-DAEMON <>\n" @@ -90,7 +90,7 @@ "%s\n" "\n", bounceq.id, - hostname(), VERSION, + hostname(), VERSION, systemhostname(), rfc822date(), it->addr, it->sender, @@ -190,8 +190,7 @@ switch (*s) { case ' ': case '\t': - s++; - /* continue */ + ps->state = MAIN; break; default: @@ -200,6 +199,7 @@ goto newaddr; return (0); } + break; case QUIT: return (0); @@ -364,12 +364,12 @@ "Received: from %s (uid %d)\n" "\t(envelope-from %s)\n" "\tid %s\n" - "\tby %s (%s);\n" + "\tby %s (%s on %s);\n" "\t%s\n", username, useruid, queue->sender, queue->id, - hostname(), VERSION, + hostname(), VERSION, systemhostname(), rfc822date()); if ((ssize_t)error < 0) return (-1); diff -x .git* -x bsd -ruN ./freebsd/contrib/dma/net.c ./dma/net.c --- ./freebsd/contrib/dma/net.c 2021-06-14 22:02:27.397574000 +0200 +++ ./dma/net.c 2021-06-14 21:13:02.817077000 +0200 @@ -95,7 +95,7 @@ strcat(cmd, "\r\n"); len = strlen(cmd); - if (((config.features & SECURETRANS) != 0) && + if (((config.features & SECURETRANSFER) != 0) && ((config.features & NOSSL) == 0)) { while ((s = SSL_write(config.ssl, (const char*)cmd, len)) <= 0) { s = SSL_get_error(config.ssl, s); @@ -148,7 +148,7 @@ memmove(buff, buff + pos, len - pos); len -= pos; pos = 0; - if (((config.features & SECURETRANS) != 0) && + if (((config.features & SECURETRANSFER) != 0) && (config.features & NOSSL) == 0) { if ((rlen = SSL_read(config.ssl, buff + len, sizeof(buff) - len)) == -1) { strlcpy(neterr, ssl_errstr(), sizeof(neterr)); @@ -271,7 +271,7 @@ // LOGIN if (features->auth.login) { if ((config.features & INSECURE) != 0 || - (config.features & SECURETRANS) != 0) { + (config.features & SECURETRANSFER) != 0) { /* Send AUTH command according to RFC 2554 */ send_remote_command(fd, "AUTH LOGIN"); if (read_remote(fd, 0, NULL) != 3) { @@ -347,7 +347,7 @@ close_connection(int fd) { if (config.ssl != NULL) { - if (((config.features & SECURETRANS) != 0) && + if (((config.features & SECURETRANSFER) != 0) && ((config.features & NOSSL) == 0)) SSL_shutdown(config.ssl); SSL_free(config.ssl); @@ -497,7 +497,7 @@ } while (0) /* Check first reply from remote host */ - if ((config.features & SECURETRANS) == 0 || + if ((config.features & SECURETRANSFER) == 0 || (config.features & STARTTLS) != 0) { config.features |= NOSSL; READ_REMOTE_CHECK("connect", 2); @@ -505,7 +505,7 @@ config.features &= ~NOSSL; } - if ((config.features & SECURETRANS) != 0) { + if ((config.features & SECURETRANSFER) != 0) { error = smtp_init_crypto(fd, config.features, &features); if (error == 0) syslog(LOG_DEBUG, "SSL initialization successful"); diff -x .git* -x bsd -ruN ./freebsd/contrib/dma/util.c ./dma/util.c --- ./freebsd/contrib/dma/util.c 2021-06-14 22:02:27.400298000 +0200 +++ ./dma/util.c 2021-06-14 21:13:02.819633000 +0200 @@ -99,6 +99,25 @@ } local: + snprintf(name, sizeof(name), "%s", systemhostname()); + + initialized = 1; + return (name); +} + +const char * +systemhostname(void) +{ +#ifndef HOST_NAME_MAX +#define HOST_NAME_MAX 255 +#endif + static char name[HOST_NAME_MAX+1]; + static int initialized = 0; + char *s; + + if (initialized) + return (name); + if (gethostname(name, sizeof(name)) != 0) *name = 0; /*