summaryrefslogtreecommitdiff
path: root/mail/exim
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@FreeBSD.org>2015-07-27 19:42:14 +0000
committerVsevolod Stakhov <vsevolod@FreeBSD.org>2015-07-27 19:42:14 +0000
commit5eac9528f705745b0bcdb7fa3939218e8a7d2350 (patch)
tree7568e990f007d0ae21b961d9ca4f7239ca15fc33 /mail/exim
parentBump here too. (diff)
- Update to 4.86 [1]
- Add experimental INTERNATIONAL option - Add experimental SOCKS option - Removed rspamd extra patch (included by default now) - Removed xclient patch (broken and not used) Relnotes: ftp://ftp.exim.org/pub/exim/exim4/NewStuff [1]
Notes
Notes: svn path=/head/; revision=393028
Diffstat (limited to 'mail/exim')
-rw-r--r--mail/exim/Makefile17
-rw-r--r--mail/exim/distinfo4
-rw-r--r--mail/exim/files/extra-patch-rspamd489
-rw-r--r--mail/exim/files/extra-patch-xclient424
-rw-r--r--mail/exim/files/patch-src__EDITME2
-rw-r--r--mail/exim/options9
6 files changed, 20 insertions, 925 deletions
diff --git a/mail/exim/Makefile b/mail/exim/Makefile
index 1df7b7fef5a6..2af62dc4335c 100644
--- a/mail/exim/Makefile
+++ b/mail/exim/Makefile
@@ -3,7 +3,6 @@
PORTNAME= exim
PORTVERSION?= ${EXIM_VERSION}
-PORTREVISION?= 2
CATEGORIES= mail ipv6
MASTER_SITES= EXIM/exim4/:exim
DISTNAME= ${PORTNAME}-${EXIM_VERSION}
@@ -48,6 +47,7 @@ EMBEDDED_PERL_USE= perl5=run,build
EXIMON_USE= xorg=x11,xaw,xt
GNUTLS_LIB_DEPENDS= libgnutls.so:${PORTSDIR}/security/gnutls
ICONV_USES= iconv:lib,build
+INTERNATIONAL_LIB_DEPENDS= libidn.so:${PORTSDIR}/dns/libidn
MYSQL_USE= mysql=yes
OPENLDAP_USE= openldap=yes
PGSQL_USES= pgsql
@@ -57,8 +57,6 @@ SA_EXIM_RUN_DEPENDS= ${LOCALBASE}/bin/spamc:${PORTSDIR}/mail/spamassassin
SPF_LIB_DEPENDS= libspf2.so:${PORTSDIR}/mail/libspf2
SQLITE_USE= sqlite=yes
SQLITE_USES= pkgconfig
-XCLIENT_EXTRA_PATCHES= ${FILESDIR}/extra-patch-xclient
-RSPAMD_EXTRA_PATCHES= ${FILESDIR}/extra-patch-rspamd
.include <bsd.port.options.mk>
@@ -97,7 +95,7 @@ MASTER_SITES+= http://marc.merlins.org/linux/exim/files/:sa_exim \
DISTFILES+= sa-exim-${SA_EXIM_VERSION}.tar.gz:sa_exim
.endif
-EXIM_VERSION= 4.85
+EXIM_VERSION= 4.86
SA_EXIM_VERSION=4.2
EXIM_INSTALL_ARG+= "-no_chown" "-no_symlink"
@@ -220,6 +218,17 @@ SEDLIST+= -e 's,^\# (EXPERIMENTAL_DANE=),\1,'
SEDLIST+= -e 's,^\# (EXPERIMENTAL_EVENT=),\1,'
.endif
+.if ${PORT_OPTIONS:MINTERNATIONAL}
+SEDLIST+= -e 's,^\# (EXPERIMENTAL_INTERNATIONAL=),\1,' \
+ -e 's,XX_IDN_LIBS_XX,-L${LOCALBASE}/lib -lidn,'
+.else
+SEDLIST+= -e 's,XX_IDN_LIBS_XX,,'
+.endif
+
+.if ${PORT_OPTIONS:MSOCKS}
+SEDLIST+= -e 's,^\# (EXPERIMENTAL_SOCKS=),\1,'
+.endif
+
.if !${PORT_OPTIONS:MPRDR}
SEDLIST+= -e 's,^\# (DISABLE_PRDR=),\1,'
.endif
diff --git a/mail/exim/distinfo b/mail/exim/distinfo
index 85b8ed35af52..65381a0fec4b 100644
--- a/mail/exim/distinfo
+++ b/mail/exim/distinfo
@@ -1,4 +1,4 @@
-SHA256 (exim/exim-4.85.tar.bz2) = 13211f2bbc5400d095a9b4be075eb1347e0d98676fdfe4be8a3b4d56281daaa4
-SIZE (exim/exim-4.85.tar.bz2) = 1784150
+SHA256 (exim/exim-4.86.tar.bz2) = f1ccf2ce2ea51b7fbbf160e7e0e41d24ca401cf44a185128ad99ea04635fc456
+SIZE (exim/exim-4.86.tar.bz2) = 1804807
SHA256 (exim/sa-exim-4.2.tar.gz) = 72e0a735547f18b05785e6c58a71d24623858f0f5234a5dc0e24cb453999e99a
SIZE (exim/sa-exim-4.2.tar.gz) = 66575
diff --git a/mail/exim/files/extra-patch-rspamd b/mail/exim/files/extra-patch-rspamd
deleted file mode 100644
index ccca1e8cb25a..000000000000
--- a/mail/exim/files/extra-patch-rspamd
+++ /dev/null
@@ -1,489 +0,0 @@
-diff -ruN src/expand.c src/expand.c
---- src/expand.c 2015-01-16 15:21:40.000000000 +0200
-+++ src/expand.c 2015-01-16 15:21:51.000000000 +0200
-@@ -652,6 +652,7 @@
- { "sn8", vtype_filter_int, &filter_sn[8] },
- { "sn9", vtype_filter_int, &filter_sn[9] },
- #ifdef WITH_CONTENT_SCAN
-+ { "spam_action", vtype_stringptr, &spam_action },
- { "spam_bar", vtype_stringptr, &spam_bar },
- { "spam_report", vtype_stringptr, &spam_report },
- { "spam_score", vtype_stringptr, &spam_score },
-diff -ruN src/globals.c src/globals.c
---- src/globals.c 2015-01-16 15:21:40.000000000 +0200
-+++ src/globals.c 2015-01-16 15:21:51.000000000 +0200
-@@ -1276,6 +1276,7 @@
- uschar *spamd_address = US"127.0.0.1 783";
- uschar *spam_bar = NULL;
- uschar *spam_report = NULL;
-+uschar *spam_action = NULL;
- uschar *spam_score = NULL;
- uschar *spam_score_int = NULL;
- #endif
-diff -ruN src/globals.h src/globals.h
---- src/globals.h 2015-01-16 15:21:40.000000000 +0200
-+++ src/globals.h 2015-01-16 15:21:51.000000000 +0200
-@@ -819,6 +819,7 @@
- extern uschar *spamd_address; /* address for the spamassassin daemon */
- extern uschar *spam_bar; /* the spam "bar" (textual representation of spam_score) */
- extern uschar *spam_report; /* the spamd report (multiline) */
-+extern uschar *spam_action; /* the spamd action */
- extern uschar *spam_score; /* the spam score (float) */
- extern uschar *spam_score_int; /* spam_score * 10 (int) */
- #endif
-diff -ruN src/spam.c src/spam.c
---- src/spam.c 2015-01-16 15:21:40.000000000 +0200
-+++ src/spam.c 2015-01-16 15:21:51.000000000 +0200
-@@ -14,12 +14,20 @@
- uschar spam_score_buffer[16];
- uschar spam_score_int_buffer[16];
- uschar spam_bar_buffer[128];
-+uschar spam_action_buffer[32];
- uschar spam_report_buffer[32600];
- uschar prev_user_name[128] = "";
- int spam_ok = 0;
- int spam_rc = 0;
- uschar *prev_spamd_address_work = NULL;
-
-+/* push formatted line into vector */
-+static int spam_push_line(struct iovec *iov, int i, const char *fmt, ...);
-+/* write io vector to the socket */
-+static int spam_write_vector(int sock, size_t size, struct iovec *iov, time_t now);
-+/* poll socket to obtain write readiness */
-+static int spam_poll_socket (int sock, time_t start);
-+
- int
- spam(uschar **listptr)
- {
-@@ -31,10 +39,11 @@
- FILE *mbox_file;
- int spamd_sock = -1;
- uschar spamd_buffer[32600];
-- int i, j, offset, result;
-+ int i, j, offset, result, is_rspamd;
- uschar spamd_version[8];
-+ uschar spamd_short_result[8];
- uschar spamd_score_char;
-- double spamd_threshold, spamd_score;
-+ double spamd_threshold, spamd_score, spamd_reject_score;
- int spamd_report_offset;
- uschar *p,*q;
- int override = 0;
-@@ -128,8 +137,15 @@
- spamd_address_container *this_spamd =
- (spamd_address_container *)store_get(sizeof(spamd_address_container));
-
-+ /* Check for spamd variant */
-+ if( Ustrstr(address, "variant=rspamd") != NULL ) {
-+ this_spamd->is_rspamd = 1;
-+ }
-+ else {
-+ this_spamd->is_rspamd = 0;
-+ }
- /* grok spamd address and port */
-- if (sscanf(CS address, "%23s %u", this_spamd->tcp_addr, &(this_spamd->tcp_port)) != 2)
-+ if (sscanf(CS address, "%23s %hu", this_spamd->tcp_addr, &(this_spamd->tcp_port)) != 2)
- {
- log_write(0, LOG_MAIN,
- "spam acl condition: warning - invalid spamd address: '%s'", address);
-@@ -174,6 +190,7 @@
- spamd_address_vector[current_server]->tcp_port,
- 5 ) > -1) {
- /* connection OK */
-+ is_rspamd = spamd_address_vector[current_server]->is_rspamd;
- break;
- };
-
-@@ -210,12 +227,28 @@
- }
-
- server.sun_family = AF_UNIX;
-- Ustrcpy(server.sun_path, spamd_address_work);
-+ p = Ustrstr(spamd_address_work, "variant=rspamd");
-+ if( p != NULL ) {
-+ is_rspamd = TRUE;
-+ /* strip spaces */
-+ p --;
-+ while (p > spamd_address_work && isspace (*p)) {
-+ p --;
-+ }
-+ Ustrncpy(server.sun_path, spamd_address_work, p - spamd_address_work + 1);
-+ /* zero terminate */
-+ server.sun_path[p - spamd_address_work + 1] = 0;
-+ }
-+ else {
-+ is_rspamd = FALSE;
-+ Ustrcpy(server.sun_path, spamd_address_work);
-+ }
-+
-
- if (connect(spamd_sock, (struct sockaddr *) &server, sizeof(struct sockaddr_un)) < 0) {
- log_write(0, LOG_MAIN|LOG_PANIC,
- "malware acl condition: spamd: unable to connect to UNIX socket %s (%s)",
-- spamd_address_work, strerror(errno) );
-+ server.sun_path, strerror(errno) );
- (void)fclose(mbox_file);
- (void)close(spamd_sock);
- return DEFER;
-@@ -231,22 +264,67 @@
- return DEFER;
- }
-
-+ (void)fcntl(spamd_sock, F_SETFL, O_NONBLOCK);
- /* now we are connected to spamd on spamd_sock */
-- (void)string_format(spamd_buffer,
-- sizeof(spamd_buffer),
-- "REPORT SPAMC/1.2\r\nUser: %s\r\nContent-length: %ld\r\n\r\n",
-- user_name,
-- mbox_size);
-+ if (is_rspamd) {
-+ /* rspamd variant */
-+ int r, request_p = 0;
-+ const char *helo;
-+ struct iovec *request_v;
-+
-+ request_v = store_get(sizeof(struct iovec) * (8 + recipients_count));
-+ if (request_v == NULL) {
-+ (void)close(spamd_sock);
-+ log_write(0, LOG_MAIN|LOG_PANIC,
-+ "spam acl condition: store_get failed: %s", strerror(errno));
-+ (void)fclose(mbox_file);
-+ (void)close(spamd_sock);
-+ return DEFER;
-+ }
-+ r = 0;
-+ r += spam_push_line(request_v, request_p++, "CHECK RSPAMC/1.3\r\n");
-+ r += spam_push_line(request_v, request_p++, "Content-length: %lu\r\n", mbox_size);
-+ r += spam_push_line(request_v, request_p++, "Queue-Id: %s\r\n", message_id);
-+ r += spam_push_line(request_v, request_p++, "From: <%s>\r\n", sender_address);
-+ r += spam_push_line(request_v, request_p++, "Recipient-Number: %d\r\n", recipients_count);
-+ /* copy all recipients as well */
-+ for (i = 0; i < recipients_count; i ++)
-+ r += spam_push_line(request_v, request_p++, "Rcpt: <%s>\r\n", recipients_list[i].address);
-+ if ((helo = expand_string(US"$sender_helo_name")) != NULL && *helo != '\0')
-+ r += spam_push_line(request_v, request_p++, "Helo: %s\r\n", helo);
-+ if (sender_host_address != NULL)
-+ r += spam_push_line(request_v, request_p++, "IP: %s\r\n", sender_host_address);
-+ r += spam_push_line(request_v, request_p++, "\r\n");
-+ if (spam_write_vector (spamd_sock, request_p, request_v, start) < 0) {
-+ (void)close(spamd_sock);
-+ log_write(0, LOG_MAIN|LOG_PANIC,
-+ "spam acl condition: spamd (rspamd) send failed: %s", strerror(errno));
-+ (void)fclose(mbox_file);
-+ (void)close(spamd_sock);
-+ return DEFER;
-+ }
-+ }
-+ else {
-+ /* spamassassin variant */
-+ struct iovec req_iov;
-+ (void)string_format(spamd_buffer,
-+ sizeof(spamd_buffer),
-+ "REPORT SPAMC/1.2\r\nUser: %s\r\nContent-length: %ld\r\n\r\n",
-+ user_name,
-+ mbox_size);
-+ /* send our request */
-+ req_iov.iov_len = Ustrlen(spamd_buffer);
-+ req_iov.iov_base = spamd_buffer;
-+ if (spam_write_vector (spamd_sock, 1, &req_iov, start) < 0) {
-+ (void)close(spamd_sock);
-+ log_write(0, LOG_MAIN|LOG_PANIC,
-+ "spam acl condition: spamd send failed: %s", strerror(errno));
-+ (void)fclose(mbox_file);
-+ (void)close(spamd_sock);
-+ return DEFER;
-+ };
-+ }
-
-- /* send our request */
-- if (send(spamd_sock, spamd_buffer, Ustrlen(spamd_buffer), 0) < 0) {
-- (void)close(spamd_sock);
-- log_write(0, LOG_MAIN|LOG_PANIC,
-- "spam acl condition: spamd send failed: %s", strerror(errno));
-- (void)fclose(mbox_file);
-- (void)close(spamd_sock);
-- return DEFER;
-- };
-
- /* now send the file */
- /* spamd sometimes accepts conections but doesn't read data off
-@@ -349,60 +427,93 @@
- /* reading done */
- (void)close(spamd_sock);
-
-- /* dig in the spamd output and put the report in a multiline header, if requested */
-- if( sscanf(CS spamd_buffer,"SPAMD/%7s 0 EX_OK\r\nContent-length: %*u\r\n\r\n%lf/%lf\r\n%n",
-- spamd_version,&spamd_score,&spamd_threshold,&spamd_report_offset) != 3 ) {
--
-- /* try to fall back to pre-2.50 spamd output */
-- if( sscanf(CS spamd_buffer,"SPAMD/%7s 0 EX_OK\r\nSpam: %*s ; %lf / %lf\r\n\r\n%n",
-- spamd_version,&spamd_score,&spamd_threshold,&spamd_report_offset) != 3 ) {
-+ if (!is_rspamd) {
-+ /* dig in the spamd output and put the report in a multiline header, if requested */
-+ if( sscanf(CS spamd_buffer,"SPAMD/%7s 0 EX_OK\r\nContent-length: %*u\r\n\r\n%lf/%lf\r\n%n",
-+ spamd_version,&spamd_score,&spamd_threshold,&spamd_report_offset) != 3 ) {
-+
-+ /* try to fall back to pre-2.50 spamd output */
-+ if( sscanf(CS spamd_buffer,"SPAMD/%7s 0 EX_OK\r\nSpam: %*s ; %lf / %lf\r\n\r\n%n",
-+ spamd_version,&spamd_score,&spamd_threshold,&spamd_report_offset) != 3 ) {
-+ log_write(0, LOG_MAIN|LOG_PANIC,
-+ "spam acl condition: cannot parse spamd output");
-+ return DEFER;
-+ };
-+ };
-+
-+ if( spamd_score >= spamd_threshold ) {
-+ Ustrcpy(spam_action_buffer, "reject");
-+ }
-+ else {
-+ Ustrcpy(spam_action_buffer, "no action");
-+ }
-+ }
-+ else {
-+ /* rspamd variant of reply */
-+ int r;
-+ if( (r = sscanf(CS spamd_buffer,"RSPAMD/%7s 0 EX_OK\r\nMetric: default; %7s %lf / %lf / %lf\r\n%n",
-+ spamd_version,spamd_short_result,&spamd_score,&spamd_threshold,&spamd_reject_score,&spamd_report_offset)) != 5 ) {
- log_write(0, LOG_MAIN|LOG_PANIC,
-- "spam acl condition: cannot parse spamd output");
-+ "spam acl condition: cannot parse spamd output: %d", r);
- return DEFER;
- };
-- };
-+ /* now parse action */
-+ p = &spamd_buffer[spamd_report_offset];
-+
-+ if( Ustrncmp(p, "Action: ", sizeof("Action: ") - 1) == 0 ) {
-+ p += sizeof("Action: ") - 1;
-+ q = &spam_action_buffer[0];
-+ while (*p && *p != '\r' && (q - spam_action_buffer) < sizeof(spam_action_buffer) - 1) {
-+ *q++ = *p++;
-+ }
-+ *q = '\0';
-+ }
-+ }
-
- /* Create report. Since this is a multiline string,
- we must hack it into shape first */
- p = &spamd_buffer[spamd_report_offset];
- q = spam_report_buffer;
- while (*p != '\0') {
-- /* skip \r */
-- if (*p == '\r') {
-- p++;
-- continue;
-- };
-- *q = *p;
-- q++;
-- if (*p == '\n') {
-- /* add an extra space after the newline to ensure
-- that it is treated as a header continuation line */
-- *q = ' ';
-- q++;
-- };
-- p++;
-+ /* skip \r */
-+ if (*p == '\r') {
-+ p++;
-+ continue;
-+ };
-+ *q = *p;
-+ q++;
-+ if (*p == '\n') {
-+ /* add an extra space after the newline to ensure
-+ that it is treated as a header continuation line */
-+ *q = ' ';
-+ q++;
-+ };
-+ p++;
- };
- /* NULL-terminate */
- *q = '\0';
- q--;
- /* cut off trailing leftovers */
- while (*q <= ' ') {
-- *q = '\0';
-- q--;
-+ *q = '\0';
-+ q--;
- };
-+
-+ /* common spamd actions */
- spam_report = spam_report_buffer;
-+ spam_action = spam_action_buffer;
-
- /* create spam bar */
- spamd_score_char = spamd_score > 0 ? '+' : '-';
- j = abs((int)(spamd_score));
- i = 0;
- if( j != 0 ) {
-- while((i < j) && (i <= MAX_SPAM_BAR_CHARS))
-- spam_bar_buffer[i++] = spamd_score_char;
-+ while((i < j) && (i <= MAX_SPAM_BAR_CHARS))
-+ spam_bar_buffer[i++] = spamd_score_char;
- }
- else{
-- spam_bar_buffer[0] = '/';
-- i = 1;
-+ spam_bar_buffer[0] = '/';
-+ i = 1;
- }
- spam_bar_buffer[i] = '\0';
- spam_bar = spam_bar_buffer;
-@@ -418,12 +529,12 @@
-
- /* compare threshold against score */
- if (spamd_score >= spamd_threshold) {
-- /* spam as determined by user's threshold */
-- spam_rc = OK;
-+ /* spam as determined by user's threshold */
-+ spam_rc = OK;
- }
- else {
-- /* not spam */
-- spam_rc = FAIL;
-+ /* not spam */
-+ spam_rc = FAIL;
- };
-
- /* remember expanded spamd_address if needed */
-@@ -443,4 +554,126 @@
- };
- }
-
-+#ifdef __GNUC__
-+static int
-+spam_push_line(struct iovec *iov, const int i, const char *fmt, ...) __attribute__ ((format (printf, 3, 4)));
-+#endif
-+static int
-+spam_push_line(struct iovec *iov, const int i, const char *fmt, ...)
-+{
-+ va_list ap;
-+ size_t len;
-+ char buf[512];
-+
-+ va_start(ap, fmt);
-+ len = vsnprintf(buf, sizeof(buf), fmt, ap);
-+ va_end(ap);
-+
-+ iov[i].iov_base = string_copy(US buf);
-+ iov[i].iov_len = len;
-+
-+ if (len >= sizeof(buf)) {
-+ log_write(0, LOG_MAIN, "rspam: error, string was longer than %d", (int)sizeof(buf));
-+ return (-1);
-+ }
-+
-+ return 0;
-+}
-+
-+static int
-+spam_write_vector(int sock, size_t size, struct iovec *iov, time_t start)
-+{
-+ int r, i;
-+
-+ for (;;) {
-+ if (spam_poll_socket(sock, start) == -1) {
-+ return -1;
-+ }
-+ r = writev(sock, iov, size);
-+ if (r == -1) {
-+ if (errno == EINTR)
-+ continue;
-+
-+ log_write(0, LOG_MAIN|LOG_PANIC,
-+ "spam acl condition: %s on spamd socket", strerror(errno));
-+ return -1;
-+ }
-+ else {
-+ /* check for partial writev */
-+ for (i = 0; i < size; i ++) {
-+ if (r >= iov[i].iov_len) {
-+ r -= iov[i].iov_len;
-+ }
-+ else {
-+ /* partial iov write */
-+ iov[i].iov_base += r;
-+ break;
-+ }
-+ if (r == 0)
-+ break;
-+ }
-+
-+ if (i == size - 1 && r == 0) {
-+ /* we have written everything */
-+ break;
-+ }
-+ else {
-+ /* move iov to the last unreaded element */
-+ iov = &iov[i];
-+ size -= i;
-+ }
-+ }
-+ }
-+
-+ return 0;
-+
-+}
-+
-+static int
-+spam_poll_socket (int sock, time_t start)
-+{
-+#ifndef NO_POLL_H
-+ struct pollfd pollfd;
-+#else /* Patch posted by Erik ? for OS X */
-+ struct timeval select_tv; /* and applied by PH */
-+ fd_set select_fd;
-+#endif
-+ int r;
-+
-+#ifndef NO_POLL_H
-+ pollfd.fd = sock;
-+ pollfd.events = POLLOUT;
-+#endif
-+ for (;;) {
-+#ifndef NO_POLL_H
-+ r = poll(&pollfd, 1, 1000);
-+
-+/* Patch posted by Erik ? for OS X and applied by PH */
-+#else
-+ select_tv.tv_sec = 1;
-+ select_tv.tv_usec = 0;
-+ FD_ZERO(&select_fd);
-+ FD_SET(sock, &select_fd);
-+ r = select(sock+1, NULL, &select_fd, NULL, &select_tv);
-+#endif
-+/* End Erik's patch */
-+
-+ if (r == -1 && errno == EINTR)
-+ continue;
-+ else if (r < 1) {
-+ if (r == -1)
-+ log_write(0, LOG_MAIN|LOG_PANIC,
-+ "spam acl condition: %s on spamd socket", strerror(errno));
-+ else {
-+ if (time(NULL) - start < SPAMD_TIMEOUT)
-+ continue;
-+
-+ log_write(0, LOG_MAIN|LOG_PANIC,
-+ "spam acl condition: timed out writing spamd socket");
-+ }
-+ }
-+ return r;
-+ }
-+}
-+
- #endif
-diff -ruN src/spam.h src/spam.h
---- src/spam.h 2015-01-16 15:21:40.000000000 +0200
-+++ src/spam.h 2015-01-16 15:21:51.000000000 +0200
-@@ -22,7 +22,8 @@
-
- typedef struct spamd_address_container {
- uschar tcp_addr[24];
-- unsigned int tcp_port;
-+ unsigned short int tcp_port;
-+ unsigned is_rspamd:1;
- } spamd_address_container;
-
- #endif
diff --git a/mail/exim/files/extra-patch-xclient b/mail/exim/files/extra-patch-xclient
deleted file mode 100644
index 7ba87a11c9ab..000000000000
--- a/mail/exim/files/extra-patch-xclient
+++ /dev/null
@@ -1,424 +0,0 @@
-diff --git src/globals.c src/globals.c
-index 5db858b..b7c718a 100644
---- src/globals.c
-+++ src/globals.c
-@@ -691,6 +691,7 @@ uschar *helo_try_verify_hosts = NULL;
- BOOL helo_verified = FALSE;
- BOOL helo_verify_failed = FALSE;
- uschar *helo_verify_hosts = NULL;
-+uschar *xclient_allow_hosts = NULL;
- const uschar *hex_digits = CUS"0123456789abcdef";
- uschar *hold_domains = NULL;
- BOOL host_checking = FALSE;
-diff --git src/globals.h src/globals.h
-index 8d83be7..f35e99c 100644
---- src/globals.h
-+++ src/globals.h
-@@ -424,6 +424,7 @@ extern uschar *helo_lookup_domains; /* If these given, lookup host name */
- extern uschar *helo_try_verify_hosts; /* Soft check HELO argument for these */
- extern BOOL helo_verified; /* True if HELO verified */
- extern BOOL helo_verify_failed; /* True if attempt failed */
-+extern uschar *xclient_allow_hosts; /* Allow XCLIENT command for specified hosts */
- extern uschar *helo_verify_hosts; /* Hard check HELO argument for these */
- extern const uschar *hex_digits; /* Used in several places */
- extern uschar *hold_domains; /* Hold up deliveries to these */
-diff --git src/macros.h src/macros.h
-index b878b41..eec812d 100644
---- src/macros.h
-+++ src/macros.h
-@@ -726,7 +726,7 @@ is "empty". */
-
- enum { SCH_NONE, SCH_AUTH, SCH_DATA, SCH_EHLO, SCH_ETRN, SCH_EXPN, SCH_HELO,
- SCH_HELP, SCH_MAIL, SCH_NOOP, SCH_QUIT, SCH_RCPT, SCH_RSET, SCH_STARTTLS,
-- SCH_VRFY };
-+ SCH_VRFY, SCH_XCLIENT };
-
- /* Returns from host_find_by{name,dns}() */
-
-diff --git src/readconf.c src/readconf.c
-index bba5325..a375851 100644
---- src/readconf.c
-+++ src/readconf.c
-@@ -444,7 +444,8 @@ static optionlist optionlist_config[] = {
- { "uucp_from_pattern", opt_stringptr, &uucp_from_pattern },
- { "uucp_from_sender", opt_stringptr, &uucp_from_sender },
- { "warn_message_file", opt_stringptr, &warn_message_file },
-- { "write_rejectlog", opt_bool, &write_rejectlog }
-+ { "write_rejectlog", opt_bool, &write_rejectlog },
-+ { "xclient_allow_hosts", opt_stringptr, &xclient_allow_hosts },
- };
-
- static int optionlist_config_size =
-diff --git src/smtp_in.c src/smtp_in.c
-index cb1a869..8a8b157 100644
---- src/smtp_in.c
-+++ src/smtp_in.c
-@@ -67,10 +67,10 @@ enum {
- /* These commands are required to be synchronized, i.e. to be the last in a
- block of commands when pipelining. */
-
-- HELO_CMD, EHLO_CMD, DATA_CMD, /* These are listed in the pipelining */
-- VRFY_CMD, EXPN_CMD, NOOP_CMD, /* RFC as requiring synchronization */
-- ETRN_CMD, /* This by analogy with TURN from the RFC */
-- STARTTLS_CMD, /* Required by the STARTTLS RFC */
-+ HELO_CMD, EHLO_CMD, XCLIENT_CMD, DATA_CMD, /* These are listed in the pipelining */
-+ VRFY_CMD, EXPN_CMD, NOOP_CMD, /* RFC as requiring synchronization */
-+ ETRN_CMD, /* This by analogy with TURN from the RFC */
-+ STARTTLS_CMD, /* Required by the STARTTLS RFC */
-
- /* This is a dummy to identify the non-sync commands when pipelining */
-
-@@ -156,6 +156,7 @@ static smtp_cmd_list cmd_list[] = {
- { "rset", sizeof("rset")-1, RSET_CMD, FALSE, FALSE }, /* First */
- { "helo", sizeof("helo")-1, HELO_CMD, TRUE, FALSE },
- { "ehlo", sizeof("ehlo")-1, EHLO_CMD, TRUE, FALSE },
-+ { "xclient", sizeof("xclient")-1, XCLIENT_CMD, TRUE, FALSE },
- { "auth", sizeof("auth")-1, AUTH_CMD, TRUE, TRUE },
- #ifdef SUPPORT_TLS
- { "starttls", sizeof("starttls")-1, STARTTLS_CMD, FALSE, FALSE },
-@@ -188,7 +189,7 @@ It must be kept in step with the SCH_xxx enumerations. */
-
- static uschar *smtp_names[] =
- {
-- US"NONE", US"AUTH", US"DATA", US"EHLO", US"ETRN", US"EXPN", US"HELO",
-+ US"NONE", US"AUTH", US"DATA", US"EHLO", US"ETRN", US"EXPN", US"HELO", US"XCLIENT",
- US"HELP", US"MAIL", US"NOOP", US"QUIT", US"RCPT", US"RSET", US"STARTTLS",
- US"VRFY" };
-
-@@ -895,8 +896,259 @@ log_write(0, LOG_MAIN, "no MAIL in SMTP connection from %s D=%s%s",
- readconf_printtime(time(NULL) - smtp_connection_start), s);
- }
-
-+/*************************************************
-+* Decode byte-string in xtext *
-+*************************************************/
-+
-+/* This function decodes a string in xtextformat as defined in RFC 1891 and
-+required by the SMTP XCLIENT extension. We put the result in a piece of
-+store of equal length - it cannot be longer than this. Although in general the
-+result of decoding an xtext may be binary, in the context in which it is used
-+by Exim (for decoding the value of XCLIENT command), the result is
-+expected to be an addr-spec. We therefore add on a terminating zero, for
-+convenience.
-+
-+Arguments:
-+ code points to the coded string
-+ end points to the end of coded string
-+ ptr where to put the pointer to the result, which is in
-+ dynamic store
-+
-+Returns: the number of bytes in the result, excluding the final zero;
-+ -1 if the input is malformed
-+*/
-+
-+int
-+xclient_xtextdecode(uschar *code, uschar *end, uschar **ptr)
-+{
-+register int x;
-+uschar *result = store_get(end - code + 1);
-+*ptr = result;
-+
-+while (code < end)
-+ {
-+ x = (*code++);
-+ if (x < 33 || x > 127 || x == '=') return -1;
-+ if (x == '+')
-+ {
-+ register int y;
-+ if (!isxdigit((x = (*code++)))) return -1;
-+ y = ((isdigit(x))? x - '0' : (tolower(x) - 'a' + 10)) << 4;
-+ if (!isxdigit((x = (*code++)))) return -1;
-+ *result++ = y | ((isdigit(x))? x - '0' : (tolower(x) - 'a' + 10));
-+ }
-+ else *result++ = x;
-+ }
-+
-+*result = 0;
-+return result - *ptr;
-+}
-+
-+/*************************************************
-+* Check XCLIENT line and set sender_address *
-+*************************************************/
-+
-+
-+/* Check the format of a XCLIENT line.
-+ * XCLIENT Command syntax
-+ *
-+ * An example client-server conversation is given at the end of this document.
-+ *
-+ * In SMTP server EHLO replies, the keyword associated with this extension is XCLIENT. It is followed by the names of the attributes that the XCLIENT implementation supports.
-+ *
-+ * The XCLIENT command may be sent at any time, except in the middle of a mail delivery transaction (i.e. between MAIL and DOT, or MAIL and RSET).
-+ * The XCLIENT command may be pipelined when the server supports ESMTP command pipelining.
-+ * To avoid triggering spamware detectors, the command should be sent at the end of a command group.
-+ *
-+ * The syntax of XCLIENT requests is described below.
-+ * Upper case and quoted strings specify terminals, lowercase strings specify meta terminals, and SP is whitespace.
-+ * Although command and attribute names are shown in upper case, they are in fact case insensitive.
-+ *
-+ * xclient-command = XCLIENT 1*( SP attribute-name"="attribute-value )
-+ *
-+ * attribute-name = ( NAME | ADDR | PORT | HELO | PROTO | LOGIN)
-+ *
-+ * attribute-value = xtext
-+ *
-+ * Attribute values are xtext encoded as per RFC 1891.
-+ * The NAME attribute specifies an SMTP client hostname (not an SMTP client address), [UNAVAILABLE] when client hostname lookup failed due to a permanent error, or [TEMPUNAVAIL] when the lookup error condition was transient.
-+ *
-+ * The ADDR attribute specifies an SMTP client numerical IPv4 network address, an IPv6 address prefixed with IPV6:, or [UNAVAILABLE] when the address information is unavailable. Address information is not enclosed with [].
-+ *
-+ * The PORT attribute specifies the SMTP client TCP port number as a decimal number, or [UNAVAILABLE] when the information is unavailable.
-+ * The HELO attribute specifies an SMTP HELO parameter value, or the value [UNAVAILABLE] when the information is unavailable.
-+ * The PROTO attribute specifies either SMTP or ESMTP.
-+ *
-+ * Note 1: syntactically valid NAME and HELO attribute-value elements can be up to 255 characters long.
-+ * The client must not send XCLIENT commands that exceed the 512 character limit for SMTP commands.
-+ * To avoid exceeding the limit the client should send the information in multiple XCLIENT commands; for example, send NAME and ADDR first, then HELO and PROTO.
-+ *
-+ * Note 2: [UNAVAILABLE], [TEMPUNAVAIL] and IPV6: may be specified in upper case, lower case or mixed case.
-+Argument:
-+ s the data portion of the line (already past any white space)
-+
-+Returns: TRUE
-+ FALSE
-+*/
-+
-+/* XCLIENT MACROS */
-+#define XCLIENT_UNAVAIL US"[UNAVAILABLE]"
-+#define XCLIENT_TEMPUNAVAIL US"[TEMPUNAVAIL]"
-+
-+static BOOL
-+smtp_handle_xclient(uschar *s)
-+{
-+ uschar *p, *c, *end, *decoded_buf;
-+ int len;
-+ enum {
-+ XCLIENT_READ_COMMAND = 0,
-+ XCLIENT_READ_VALUE,
-+ XCLIENT_SKIP_SPACES
-+ } state = XCLIENT_SKIP_SPACES;
-+ enum {
-+ XCLIENT_CMD_ADDR = 0,
-+ XCLIENT_CMD_NAME,
-+ XCLIENT_CMD_PORT,
-+ XCLIENT_CMD_PROTO,
-+ XCLIENT_CMD_LOGIN,
-+ XCLIENT_CMD_HELO,
-+ XCLIENT_CMD_UNKNOWN
-+ } xclient_cmd = XCLIENT_CMD_UNKNOWN;
-+
-+ p = s;
-+ end = s + Ustrlen(s);
-+
-+ while (p < end) {
-+ switch (state) {
-+ case XCLIENT_READ_COMMAND:
-+ if (*p != '=') {
-+ p ++;
-+ }
-+ else {
-+ if (c == p) {
-+ return FALSE;
-+ }
-+ if (p - c == 4) {
-+ if (strncmpic(c, US"ADDR", 4) == 0) {
-+ xclient_cmd = XCLIENT_CMD_ADDR;
-+ }
-+ else if (strncmpic(c, US"NAME", 4) == 0) {
-+ xclient_cmd = XCLIENT_CMD_NAME;
-+ }
-+ else if (strncmpic(c, US"PORT", 4) == 0) {
-+ xclient_cmd = XCLIENT_CMD_PORT;
-+ }
-+ else if (strncmpic(c, US"HELO", 4) == 0) {
-+ xclient_cmd = XCLIENT_CMD_HELO;
-+ }
-+ }
-+ else if (p - c == 5) {
-+ if (strncmpic(c, US"PROTO", 5) == 0) {
-+ xclient_cmd = XCLIENT_CMD_PROTO;
-+ }
-+ else if (strncmpic(c, US"LOGIN", 5) == 0) {
-+ xclient_cmd = XCLIENT_CMD_LOGIN;
-+ }
-+ }
-+ else {
-+ return FALSE;
-+ }
-+ p ++;
-+ c = p;
-+ state = XCLIENT_READ_VALUE;
-+ }
-+ break;
-+ case XCLIENT_READ_VALUE:
-+ if (isspace (*p) || p == end - 1) {
-+ len = p - c;
-+ if (p == end - 1) {
-+ len ++;
-+ p ++;
-+ }
-+ if (len == 0) {
-+ return FALSE;
-+ }
-+ if ((len == 13 && (strncmpic(c, XCLIENT_UNAVAIL, 13) == 0) ||
-+ strncmpic(c, XCLIENT_TEMPUNAVAIL, 13) == 0)) {
-+ decoded_buf = NULL;
-+ }
-+ else if ((len = xclient_xtextdecode(c, p, &decoded_buf)) == -1) {
-+ return FALSE;
-+ }
-+ switch (xclient_cmd) {
-+ case XCLIENT_CMD_ADDR:
-+ sender_host_address = decoded_buf ? string_copy_malloc(decoded_buf) : NULL;
-+ break;
-+ case XCLIENT_CMD_NAME:
-+ sender_host_name = decoded_buf ? string_copy_malloc(decoded_buf) : NULL;
-+ break;
-+ case XCLIENT_CMD_HELO:
-+ sender_helo_name = decoded_buf ? string_copy_malloc(decoded_buf) : NULL;
-+ break;
-+ case XCLIENT_CMD_PORT:
-+ sender_host_port = decoded_buf ? Uatoi(decoded_buf) : 0;
-+ break;
-+ case XCLIENT_CMD_LOGIN:
-+ if (decoded_buf != NULL) {
-+ authenticated_id = string_copy_malloc(decoded_buf);
-+ sender_host_authenticated = "xclient";
-+ authentication_failed = FALSE;
-+ }
-+ else {
-+ authenticated_id = NULL;
-+ sender_host_authenticated = NULL;
-+ }
-+ break;
-+ case XCLIENT_CMD_PROTO:
-+ if (decoded_buf != NULL) {
-+ if (len == 4 && strncmpic(decoded_buf, US"SMTP", 4) == 0) {
-+ esmtp = FALSE;
-+ }
-+ else if (len == 5 && strncmpic(decoded_buf, US"ESMTP", 5) == 0) {
-+ esmtp = TRUE;
-+ }
-+ else {
-+ return FALSE;
-+ }
-+ }
-+ else {
-+ return FALSE;
-+ }
-+ break;
-+ }
-+ p ++;
-+ state = XCLIENT_SKIP_SPACES;
-+ }
-+ else {
-+ p ++;
-+ }
-+ break;
-+ case XCLIENT_SKIP_SPACES:
-+ if (isspace (*p)) {
-+ p ++;
-+ }
-+ else {
-+ c = p;
-+ state = XCLIENT_READ_COMMAND;
-+ }
-+ break;
-+ default:
-+ return FALSE;
-+ }
-+ }
-
-
-+ if (state == XCLIENT_SKIP_SPACES) {
-+ host_build_sender_fullhost();
-+ return TRUE;
-+ }
-+
-+ return FALSE;
-+}
-+
-+#undef XCLIENT_UNAVAIL
-+#undef XCLIENT_TEMPUNAVAIL
-+
- /*************************************************
- * Check HELO line and set sender_helo_name *
- *************************************************/
-@@ -1189,6 +1441,11 @@ while (done <= 0)
- bsmtp_transaction_linecount = receive_linecount;
- break;
-
-+ /* Handle XCLIENT command */
-+ case XCLIENT_CMD:
-+ smtp_handle_xclient(smtp_cmd_data);
-+ break;
-+
-
- /* The MAIL FROM command requires an address as an operand. All we
- do here is to parse it for syntactic correctness. The form "<>" is
-@@ -3190,6 +3447,12 @@ while (done <= 0)
- tls_advertised = TRUE;
- }
- #endif
-+
-+ if (verify_check_host(&xclient_allow_hosts) != FAIL)
-+ {
-+ s = string_cat(s, &size, &ptr, smtp_code, 3);
-+ s = string_cat(s, &size, &ptr, US"-XCLIENT\r\n", 10);
-+ }
-
- #ifdef EXPERIMENTAL_PRDR
- /* Per Recipient Data Response, draft by Eric A. Hall extending RFC */
-@@ -3241,7 +3504,42 @@ while (done <= 0)
- toomany = FALSE;
- break; /* HELO/EHLO */
-
-+ case XCLIENT_CMD:
-+ HAD(SCH_XCLIENT);
-+ smtp_mailcmd_count++;
-+ if (helo_required && !helo_seen)
-+ {
-+ smtp_printf("503 HELO or EHLO required\r\n");
-+ log_write(0, LOG_MAIN|LOG_REJECT, "rejected XCLIENT from %s: no "
-+ "HELO/EHLO given", host_and_ident(FALSE));
-+ break;
-+ }
-+
-+ /* Check for an operand */
-+ if (smtp_cmd_data[0] == 0)
-+ {
-+ done = synprot_error(L_smtp_syntax_error, 501, NULL,
-+ US"XCLIENT must have at least one operand");
-+ break;
-+ }
-+
-+ if(verify_check_host(&xclient_allow_hosts) == FAIL)
-+ {
-+ done = synprot_error(L_smtp_syntax_error, 550, NULL,
-+ US"XCLIENT is not allowed");
-+ break;
-+ }
-+ if(smtp_handle_xclient(smtp_cmd_data) == FALSE)
-+ {
-+ done = synprot_error(L_smtp_syntax_error, 501, NULL,
-+ US"bad command parameter syntax");
-+ break;
-+ }
-+ smtp_code = US"220"; /* Default status code */
-+
-+ smtp_printf("%s XCLIENT success\r\n", smtp_code);
-
-+ break; /* XCLIENT */
- /* The MAIL command requires an address as an operand. All we do
- here is to parse it for syntactic correctness. The form "<>" is
- a special case which converts into an empty string. The start/end
-@@ -4139,6 +4437,8 @@ while (done <= 0)
- verify_check_host(&tls_advertise_hosts) != FAIL)
- Ustrcat(buffer, " STARTTLS");
- #endif
-+ if (verify_check_host(&xclient_allow_hosts) != FAIL)
-+ Ustrcat(buffer, " XCLIENT");
- Ustrcat(buffer, " HELO EHLO MAIL RCPT DATA");
- Ustrcat(buffer, " NOOP QUIT RSET HELP");
- if (acl_smtp_etrn != NULL) Ustrcat(buffer, " ETRN");
diff --git a/mail/exim/files/patch-src__EDITME b/mail/exim/files/patch-src__EDITME
index 1725c6839eff..1a0d07016d9c 100644
--- a/mail/exim/files/patch-src__EDITME
+++ b/mail/exim/files/patch-src__EDITME
@@ -123,7 +123,7 @@
# but of course there may need to be other things in CFLAGS and EXTRALIBS_EXIM
# as well.
+CFLAGS=XX_CFLAGS_XX XX_SPF_FLAGS_XX XX_SRS_FLAGS_XX XX_SQLITE_FLAGS_XX
-+EXTRALIBS=XX_TCP_WRAPPERS_LIBS_XX XX_PAM_LIBS_XX XX_ICONV_LIBS_XX XX_SPF_LIBS_XX XX_SRS_LIBS_XX XX_RADIUS_LIBS_XX XX_SQLITE_LIBS_XX XX_DMARC_LIBS_XX XX_REDIS_LIBS_XX XX_DYNAMIC_LDFLAGS_XX
++EXTRALIBS=XX_TCP_WRAPPERS_LIBS_XX XX_PAM_LIBS_XX XX_ICONV_LIBS_XX XX_SPF_LIBS_XX XX_SRS_LIBS_XX XX_RADIUS_LIBS_XX XX_SQLITE_LIBS_XX XX_DMARC_LIBS_XX XX_REDIS_LIBS_XX XX_DYNAMIC_LDFLAGS_XX XX_IDN_LIBS_XX
#
# To use a name other than exim in the tcpwrappers config file,
# e.g. if you're running multiple daemons with different access lists,
diff --git a/mail/exim/options b/mail/exim/options
index d5cc88b9d27d..c45ac125ff49 100644
--- a/mail/exim/options
+++ b/mail/exim/options
@@ -18,8 +18,7 @@ OPTIONS_DEFINE+= ALT_CONFIG_PREFIX \
READLINE \
SUID \
TCP_WRAPPERS \
- WISHLIST \
- XCLIENT
+ WISHLIST
OPTIONS_DEFAULT+= AUTH_CRAM_MD5 \
AUTH_DOVECOT \
@@ -61,7 +60,7 @@ OPTIONS_GROUP_LOOKUP= CDB BDB DNSDB DSEARCH LSEARCH MYSQL NIS OPENLDAP PGSQL RED
LOOKUP_DESC= Lookup support
OPTIONS_GROUP_STORAGE= MAILDIR MAILSTORE MBX
STORAGE_DESC= Supported storage formats
-OPTIONS_GROUP_EXPERIMENTAL= CERTNAMES DANE DCC DMARC DSN EVENT PROXY SPF RSPAMD
+OPTIONS_GROUP_EXPERIMENTAL= CERTNAMES DANE DCC DMARC DSN EVENT INTERNATIONAL PROXY SOCKS SPF
EXPERIMENTAL_DESC= Experimental options
OPTIONS_GROUP= AUTH LOOKUP STORAGE EXPERIMENTAL
@@ -90,6 +89,7 @@ EMBEDDED_PERL_DESC= Enable embedded Perl interpreter
EVENT_DESC= Messages events support (TPDA namely)
EXIMON_DESC= Build eximon monitor (requires X libraries)
ICONV_DESC= Enable header charset conversion
+INTERNATIONAL_DESC= Enable support for the transmission of UTF-8 envelope addresses
LISTMATCH_RHS_DESC= Enable pre-4.77 behaviour for match_*
LMTP_DESC= RFC2033 SMTP over command pipe transport
LSEARCH_DESC= Enable wildcarded-file lookups
@@ -110,12 +110,11 @@ READLINE_DESC= Enable readline(3) library
REDIS_DESC= Enable redis lookups (experimental)
SASLAUTHD_DESC= Enable use of Cyrus SASL auth daemon
SA_EXIM_DESC= Build with Spamassassin local scan
+SOCKS_DESC= Enable smtp transport via socks5 proxies
SPF_DESC= Enable Sender Policy Framework checking
-RSPAMD_DESC= Build with Rspamd support
SQLITE_DESC= Enable SQLite lookups
SRS_DESC= Enable Sender Rewriting Scheme
SUID_DESC= Install the exim binary suid root
TCP_WRAPPERS_DESC= Enable /etc/hosts.allow access control
GNUTLS_DESC= Use GnuTLS instead of OpenSSL for TLS
WISHLIST_DESC= Include the unsupported patches
-XCLIENT_DESC= Enable XCLIENT command in exim