summarylogtreecommitdiffstats
diff options
context:
space:
mode:
authorRich Li2015-06-10 18:24:44 -0600
committerRich Li2015-06-10 18:24:44 -0600
commit09f03a310067c2285547a658428097dc1e5da5ed (patch)
tree5b2d18fa7d187b668f572deef7551e94dcf93e14
downloadaur-09f03a310067c2285547a658428097dc1e5da5ed.tar.gz
Import version 0.3.2 from old AUR
-rw-r--r--.SRCINFO52
-rw-r--r--PKGBUILD112
-rw-r--r--README.Postfix13
-rw-r--r--spamass-milter-0.3.1-authuser.patch91
-rw-r--r--spamass-milter-0.3.1-group.patch104
-rw-r--r--spamass-milter-0.3.1-ipv6.patch297
-rw-r--r--spamass-milter-0.3.1-pathnames.patch21
-rw-r--r--spamass-milter-0.3.2-auth-no-ssf.patch28
-rw-r--r--spamass-milter-0.3.2-bits.patch289
-rw-r--r--spamass-milter-0.3.2-rcvd.patch23
-rw-r--r--spamass-milter-0.3.2-rundir.patch30
-rw-r--r--spamass-milter-0.3.2-syntax.patch248
-rw-r--r--spamass-milter-postfix-sysconfig.systemd5
-rw-r--r--spamass-milter-postfix-tmpfs.conf1
-rw-r--r--spamass-milter-root.service30
-rw-r--r--spamass-milter-sysconfig.systemd14
-rw-r--r--spamass-milter-tmpfs.conf1
-rw-r--r--spamass-milter.install53
-rw-r--r--spamass-milter.service29
19 files changed, 1441 insertions, 0 deletions
diff --git a/.SRCINFO b/.SRCINFO
new file mode 100644
index 000000000000..4101ad848862
--- /dev/null
+++ b/.SRCINFO
@@ -0,0 +1,52 @@
+pkgbase = spamass-milter
+ pkgdesc = Sendmail Milter that pipes incoming mail through SpamAssassin
+ pkgver = 0.3.2
+ pkgrel = 1
+ url = http://savannah.nongnu.org/projects/spamass-milt/
+ install = spamass-milter.install
+ arch = i686
+ arch = x86_64
+ license = GPL
+ makedepends = libmilter
+ depends = gcc-libs
+ depends = spamassassin
+ optdepends = postfix
+ backup = etc/spamass-milter
+ backup = etc/spamass-milter-postfix
+ source = http://savannah.nongnu.org/download/spamass-milt/spamass-milter-0.3.2.tar.bz2
+ source = README.Postfix
+ source = spamass-milter-0.3.2-syntax.patch
+ source = spamass-milter-0.3.1-authuser.patch
+ source = spamass-milter-0.3.2-rcvd.patch
+ source = spamass-milter-0.3.2-bits.patch
+ source = spamass-milter-0.3.1-group.patch
+ source = spamass-milter-0.3.1-ipv6.patch
+ source = spamass-milter-0.3.2-auth-no-ssf.patch
+ source = spamass-milter-0.3.1-pathnames.patch
+ source = spamass-milter-0.3.2-rundir.patch
+ source = spamass-milter.service
+ source = spamass-milter-root.service
+ source = spamass-milter-sysconfig.systemd
+ source = spamass-milter-postfix-sysconfig.systemd
+ source = spamass-milter-tmpfs.conf
+ source = spamass-milter-postfix-tmpfs.conf
+ md5sums = 740b4bcb93eca2bbc3863d0042b26533
+ md5sums = 3078db471451e6adac707a73ade23e87
+ md5sums = cfb0dee6bbb313a6e8543c34b1393508
+ md5sums = 169ba77357bd335dc93df9e628d81a03
+ md5sums = 8473057996babb7604b055af877f45fe
+ md5sums = 4ee23ad135c4047394eaf2e67a030639
+ md5sums = 97f25427d538b0f6c8272ec99e46047a
+ md5sums = 0742164b9a9e8a2982e48f49aa334df7
+ md5sums = cd5e7ccd449a504ca6cc818d3be486a8
+ md5sums = 30d62411628d38a9fa5305b163b0335a
+ md5sums = 9b36f5a673707ea4d58091e2ce90a928
+ md5sums = fab87c1281e39813c42c89fb4175fba0
+ md5sums = eaf68d706b935d65fc2085ba8daa2a2e
+ md5sums = 3f2e2c728cc30199154a3884025a597a
+ md5sums = 61ac8b0d834fb462446d645047cdbb7b
+ md5sums = c3712b881f68bbc9e78e7f9b4ba5253d
+ md5sums = 590981f73d554b670821c28ed3521a0f
+
+pkgname = spamass-milter
+
diff --git a/PKGBUILD b/PKGBUILD
new file mode 100644
index 000000000000..3de2a77bfe04
--- /dev/null
+++ b/PKGBUILD
@@ -0,0 +1,112 @@
+# Maintainer: Rich Li <rich at dranek com>
+# Contributor: Florian "Bluewind" Pritz <flo@xssn.at>
+# Note that all of the patches and systemd stuff is courtesy of Fedora's packaging, extracted from spamass-milter-0.3.2-9.fc18.src.rpm
+# I updated a few of the Fedora files to reflect the slightly different directory structure for Arch
+pkgname=spamass-milter
+pkgver=0.3.2
+pkgrel=1
+pkgdesc="Sendmail Milter that pipes incoming mail through SpamAssassin"
+arch=(i686 x86_64)
+url="http://savannah.nongnu.org/projects/spamass-milt/"
+license=('GPL')
+depends=(gcc-libs spamassassin)
+makedepends=(libmilter)
+optdepends=("postfix")
+backup=(etc/spamass-milter etc/spamass-milter-postfix)
+install="spamass-milter.install"
+source=("http://savannah.nongnu.org/download/spamass-milt/$pkgname-$pkgver.tar.bz2"
+ README.Postfix
+ spamass-milter-0.3.2-syntax.patch
+ spamass-milter-0.3.1-authuser.patch
+ spamass-milter-0.3.2-rcvd.patch
+ spamass-milter-0.3.2-bits.patch
+ spamass-milter-0.3.1-group.patch
+ spamass-milter-0.3.1-ipv6.patch
+ spamass-milter-0.3.2-auth-no-ssf.patch
+ spamass-milter-0.3.1-pathnames.patch
+ spamass-milter-0.3.2-rundir.patch
+ spamass-milter.service
+ spamass-milter-root.service
+ spamass-milter-sysconfig.systemd
+ spamass-milter-postfix-sysconfig.systemd
+ spamass-milter-tmpfs.conf
+ spamass-milter-postfix-tmpfs.conf
+ )
+md5sums=(
+ '740b4bcb93eca2bbc3863d0042b26533'
+ '3078db471451e6adac707a73ade23e87'
+ 'cfb0dee6bbb313a6e8543c34b1393508'
+ '169ba77357bd335dc93df9e628d81a03'
+ '8473057996babb7604b055af877f45fe'
+ '4ee23ad135c4047394eaf2e67a030639'
+ '97f25427d538b0f6c8272ec99e46047a'
+ '0742164b9a9e8a2982e48f49aa334df7'
+ 'cd5e7ccd449a504ca6cc818d3be486a8'
+ '30d62411628d38a9fa5305b163b0335a'
+ '9b36f5a673707ea4d58091e2ce90a928'
+ 'fab87c1281e39813c42c89fb4175fba0'
+ 'eaf68d706b935d65fc2085ba8daa2a2e'
+ '3f2e2c728cc30199154a3884025a597a'
+ '61ac8b0d834fb462446d645047cdbb7b'
+ 'c3712b881f68bbc9e78e7f9b4ba5253d'
+ '590981f73d554b670821c28ed3521a0f'
+ )
+
+
+prepare() {
+ cd "$srcdir/$pkgname-$pkgver"
+ # These are all Fedora patches
+ cp "$srcdir/README.Postfix" .
+ # Fix compiler warnings
+ patch -p1 < "$srcdir/spamass-milter-0.3.2-syntax.patch"
+ # Add -I option to ignore (don't check) mail from authenticated users
+ # (#437506, #496767) http://savannah.nongnu.org/bugs/?21046
+ patch -p1 < "$srcdir/spamass-milter-0.3.1-authuser.patch"
+ # Fix received-header generation
+ patch -p1 < "$srcdir/spamass-milter-0.3.2-rcvd.patch"
+ # Add authentication info to dummy Received-header
+ patch -p1 < "$srcdir/spamass-milter-0.3.2-bits.patch"
+ # Add -g option for group-writable socket for Postfix support
+ patch -p1 < "$srcdir/spamass-milter-0.3.1-group.patch"
+ # Add ipv6 whitelisting support
+ patch -p1 < "$srcdir/spamass-milter-0.3.1-ipv6.patch"
+ # Help for users authenticating to postfix
+ patch -p1 < "$srcdir/spamass-milter-0.3.2-auth-no-ssf.patch"
+ # Two documentation updates
+ patch -p1 < "$srcdir/spamass-milter-0.3.1-pathnames.patch"
+ patch -p1 < "$srcdir/spamass-milter-0.3.2-rundir.patch"
+}
+
+build() {
+ cd "$srcdir/$pkgname-$pkgver"
+ ./configure --prefix=/usr --sbindir=/usr/bin
+ make
+}
+
+package() {
+ cd "$srcdir/$pkgname-$pkgver"
+ make DESTDIR="$pkgdir" install
+
+ # Prep for socket used for postfix?
+ #install -m 711 -d "$pkgdir/run/spamass-milter"
+ #install -m 750 -d "$pkgdir/run/spamass-milter/postfix"
+
+ # Home dir
+ install -m 755 -d "$pkgdir/var/lib/spamass-milter"
+
+ # Systemd units
+ install -m 644 -D "$srcdir/spamass-milter.service" "$pkgdir/usr/lib/systemd/system/spamass-milter.service"
+ install -m 644 -D "$srcdir/spamass-milter-root.service" "$pkgdir/usr/lib/systemd/system/spamass-milter-root.service"
+
+ # Config (for systemd)
+ install -m 644 -D "$srcdir/spamass-milter-sysconfig.systemd" "$pkgdir/etc/spamass-milter"
+ install -m 644 -D "$srcdir/spamass-milter-postfix-sysconfig.systemd" "$pkgdir/etc/spamass-milter-postfix"
+
+ # tmpfiles
+ install -m 755 -d "$pkgdir/usr/lib/tmpfiles.d"
+ install -m 644 "$srcdir/spamass-milter-tmpfs.conf" "$pkgdir/usr/lib/tmpfiles.d/spamass-milter.conf"
+ install -m 644 "$srcdir/spamass-milter-postfix-tmpfs.conf" "$pkgdir/usr/lib/tmpfiles.d/spamass-milter-postfix.conf"
+}
+
+# vim:set ts=2 sw=2 et:
+
diff --git a/README.Postfix b/README.Postfix
new file mode 100644
index 000000000000..c4b9eb54eaa0
--- /dev/null
+++ b/README.Postfix
@@ -0,0 +1,13 @@
+Installing the spamass-milter-postfix package changes the default behaviour
+of spamass-milter to be more Postfix-friendly, i.e.:
+
+ The Unix-domain socket used for MTA communication is changed to
+ /var/run/spamass-milter/postfix/sock, and that socket is
+ writable by the postfix group.
+
+To configure Postfix to use the milter, add to /etc/postfix/main.cf:
+
+ smtpd_milters = unix:/var/run/spamass-milter/postfix/sock
+
+For further information, see:
+http://www.postfix.org/MILTER_README.html
diff --git a/spamass-milter-0.3.1-authuser.patch b/spamass-milter-0.3.1-authuser.patch
new file mode 100644
index 000000000000..7d3c7c539425
--- /dev/null
+++ b/spamass-milter-0.3.1-authuser.patch
@@ -0,0 +1,91 @@
+diff -up spamass-milter-0.3.1/spamass-milter.cpp.authuser spamass-milter-0.3.1/spamass-milter.cpp
+--- spamass-milter-0.3.1/spamass-milter.cpp.authuser 2010-03-23 21:04:56.976920217 +0000
++++ spamass-milter-0.3.1/spamass-milter.cpp 2010-03-23 21:07:12.508020535 +0000
+@@ -172,6 +172,7 @@ char *spambucket;
+ bool flag_full_email = false; /* pass full email address to spamc */
+ bool flag_expand = false; /* alias/virtusertable expansion */
+ bool warnedmacro = false; /* have we logged that we couldn't fetch a macro? */
++bool ignore_authenticated_senders = false; /* authenticated users bypass spam checks */
+
+ // {{{ main()
+
+@@ -179,7 +180,7 @@ int
+ main(int argc, char* argv[])
+ {
+ int c, err = 0;
+- const char *args = "fd:mMp:P:r:u:D:i:b:B:e:x";
++ const char *args = "fd:mMp:P:r:u:D:i:Ib:B:e:x";
+ char *sock = NULL;
+ bool dofork = false;
+ char *pidfilename = NULL;
+@@ -211,6 +212,10 @@ main(int argc, char* argv[])
+ debug(D_MISC, "Parsing ignore list");
+ parse_networklist(optarg, &ignorenets);
+ break;
++ case 'I':
++ debug(D_MISC, "Ignore authenticated senders");
++ ignore_authenticated_senders = true;
++ break;
+ case 'm':
+ dontmodifyspam = true;
+ smfilter.xxfi_flags &= ~SMFIF_CHGBODY;
+@@ -278,7 +283,7 @@ main(int argc, char* argv[])
+ cout << PACKAGE_NAME << " - Version " << PACKAGE_VERSION << endl;
+ cout << "SpamAssassin Sendmail Milter Plugin" << endl;
+ cout << "Usage: spamass-milter -p socket [-b|-B bucket] [-d xx[,yy...]] [-D host]" << endl;
+- cout << " [-e defaultdomain] [-f] [-i networks] [-m] [-M]" << endl;
++ cout << " [-e defaultdomain] [-f] [-i networks] [-I] [-m] [-M]" << endl;
+ cout << " [-P pidfile] [-r nn] [-u defaultuser] [-x]" << endl;
+ cout << " [-- spamc args ]" << endl;
+ cout << " -p socket: path to create socket" << endl;
+@@ -292,6 +297,7 @@ main(int argc, char* argv[])
+ cout << " -f: fork into background" << endl;
+ cout << " -i: skip (ignore) checks from these IPs or netblocks" << endl;
+ cout << " example: -i 192.168.12.5,10.0.0.0/8,172.16.0.0/255.255.0.0" << endl;
++ cout << " -I: skip (ignore) checks if sender is authenticated" << endl;
+ cout << " -m: don't modify body, Content-type: or Subject:" << endl;
+ cout << " -M: don't modify the message at all" << endl;
+ cout << " -P pidfile: Put processid in pidfile" << endl;
+@@ -746,6 +752,22 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
+ }
+ /* debug(D_ALWAYS, "ZZZ got private context %p", sctx); */
+
++ if (ignore_authenticated_senders)
++ {
++ char *auth_authen;
++
++ auth_authen = smfi_getsymval(ctx, const_cast<char *>("{auth_authen}"));
++ debug(D_MISC, "auth_authen=%s", auth_authen ?: "<unauthenticated>");
++
++ if (auth_authen)
++ {
++ debug(D_MISC, "sender authenticated (%s) - accepting message",
++ auth_authen);
++ debug(D_FUNC, "mlfi_envfrom: exit ignore");
++ return SMFIS_ACCEPT;
++ }
++ }
++
+ debug(D_FUNC, "mlfi_envfrom: enter");
+ try {
+ // launch new SpamAssassin
+diff -up spamass-milter-0.3.1/spamass-milter.1.in.authuser spamass-milter-0.3.1/spamass-milter.1.in
+--- spamass-milter-0.3.1/spamass-milter.1.in.authuser 2004-03-18 18:37:08.000000000 +0000
++++ spamass-milter-0.3.1/spamass-milter.1.in 2010-03-23 21:06:27.148897685 +0000
+@@ -14,6 +14,7 @@
+ .Op Fl e Ar defaultdomain
+ .Op Fl f
+ .Op Fl i Ar networks
++.Op Fl I
+ .Op Fl m
+ .Op Fl M
+ .Op Fl P Ar pidfile
+@@ -119,6 +120,8 @@ Multiple
+ flags will append to the list.
+ For example, if you list all your internal networks, no outgoing emails
+ will be filtered.
++.It Fl I
++Ignores messages if the sender has authenticated via SMTP AUTH.
+ .It Fl m
+ Disables modification of the
+ .Ql Subject:
diff --git a/spamass-milter-0.3.1-group.patch b/spamass-milter-0.3.1-group.patch
new file mode 100644
index 000000000000..1e2a418a3cdf
--- /dev/null
+++ b/spamass-milter-0.3.1-group.patch
@@ -0,0 +1,104 @@
+Add option -g group to have the milter create a group-writeable socket
+for communication with the MTA and set the GID of the socket to the
+specified group. This makes it possible to use the milter via a
+unix-domain socket with Postfix as the MTA (Postfix doesn't run as
+root and would otherwise be unable to use the socket).
+
+http://bugzilla.redhat.com/452248
+
+diff -up spamass-milter-0.3.1/spamass-milter.cpp.group spamass-milter-0.3.1/spamass-milter.cpp
+--- spamass-milter-0.3.1/spamass-milter.cpp.group 2010-03-24 13:30:19.030834527 +0000
++++ spamass-milter-0.3.1/spamass-milter.cpp 2010-03-24 13:40:54.712898107 +0000
+@@ -89,6 +89,8 @@
+ #endif
+ #include <errno.h>
+
++#include <grp.h>
++
+ // C++ includes
+ #include <cstdio>
+ #include <cstddef>
+@@ -180,8 +182,9 @@ int
+ main(int argc, char* argv[])
+ {
+ int c, err = 0;
+- const char *args = "fd:mMp:P:r:u:D:i:Ib:B:e:x";
++ const char *args = "fd:mMp:P:r:u:D:i:Ib:B:e:xg:";
+ char *sock = NULL;
++ char *group = NULL;
+ bool dofork = false;
+ char *pidfilename = NULL;
+ FILE *pidfile = NULL;
+@@ -228,6 +231,9 @@ main(int argc, char* argv[])
+ case 'p':
+ sock = strdup(optarg);
+ break;
++ case 'g':
++ group = strdup(optarg);
++ break;
+ case 'P':
+ pidfilename = strdup(optarg);
+ break;
+@@ -287,6 +293,7 @@ main(int argc, char* argv[])
+ cout << " [-P pidfile] [-r nn] [-u defaultuser] [-x]" << endl;
+ cout << " [-- spamc args ]" << endl;
+ cout << " -p socket: path to create socket" << endl;
++ cout << " -g group: socket group (perms to 660 as well)" << endl;
+ cout << " -b bucket: redirect spam to this mail address. The orignal" << endl;
+ cout << " recipient(s) will not receive anything." << endl;
+ cout << " -B bucket: add this mail address as a BCC recipient of spam." << endl;
+@@ -354,6 +361,30 @@ main(int argc, char* argv[])
+ } else {
+ debug(D_MISC, "smfi_register succeeded");
+ }
++
++ if (group)
++ {
++ struct group *gr;
++
++ (void) smfi_opensocket(0);
++ gr = getgrnam(group);
++ if (gr)
++ {
++ int rc;
++ rc = chown(sock, (uid_t)-1, gr->gr_gid);
++ if (!rc)
++ {
++ (void) chmod(sock, 0660);
++ } else {
++ perror("group option, chown");
++ exit(EX_NOPERM);
++ }
++ } else {
++ perror("group option, getgrnam");
++ exit(EX_NOUSER);
++ }
++ }
++
+ debug(D_ALWAYS, "spamass-milter %s starting", PACKAGE_VERSION);
+ err = smfi_main();
+ debug(D_ALWAYS, "spamass-milter %s exiting", PACKAGE_VERSION);
+diff -up spamass-milter-0.3.1/spamass-milter.1.in.group spamass-milter-0.3.1/spamass-milter.1.in
+--- spamass-milter-0.3.1/spamass-milter.1.in.group 2010-03-24 13:30:19.026834927 +0000
++++ spamass-milter-0.3.1/spamass-milter.1.in 2010-03-24 13:30:19.033834685 +0000
+@@ -13,6 +13,7 @@
+ .Op Fl D Ar host
+ .Op Fl e Ar defaultdomain
+ .Op Fl f
++.Op Fl g Ar group
+ .Op Fl i Ar networks
+ .Op Fl I
+ .Op Fl m
+@@ -108,6 +109,12 @@ flag.
+ Causes
+ .Nm
+ to fork into the background.
++.It Fl g Ar group
++Makes the socket for communication with the MTA group-writable (mode 0750)
++and sets the socket's group to
++.Ar group .
++This option is intended for use with MTA's like Postfix that do not run as
++root, and is incompatible with Sendmail usage.
+ .It Fl i Ar networks
+ Ignores messages if the originating IP is in the network(s) listed.
+ The message will be passed through without calling SpamAssassin at all.
diff --git a/spamass-milter-0.3.1-ipv6.patch b/spamass-milter-0.3.1-ipv6.patch
new file mode 100644
index 000000000000..6fb14676fce6
--- /dev/null
+++ b/spamass-milter-0.3.1-ipv6.patch
@@ -0,0 +1,297 @@
+diff -up spamass-milter-0.3.1/spamass-milter.cpp.ipv6 spamass-milter-0.3.1/spamass-milter.cpp
+--- spamass-milter-0.3.1/spamass-milter.cpp.ipv6 2010-09-23 16:26:36.227224902 +0100
++++ spamass-milter-0.3.1/spamass-milter.cpp 2010-09-23 17:25:22.307099331 +0100
+@@ -88,6 +88,7 @@
+ #include "subst_poll.h"
+ #endif
+ #include <errno.h>
++#include <netdb.h>
+
+ #include <grp.h>
+
+@@ -718,12 +719,18 @@ mlfi_connect(SMFICTX * ctx, char *hostna
+ sctx = (struct context *)malloc(sizeof(*sctx));
+ if (!hostaddr)
+ {
++ static struct sockaddr_in localhost;
++
+ /* not a socket; probably a local user calling sendmail directly */
+ /* set to 127.0.0.1 */
+- sctx->connect_ip.s_addr = htonl(INADDR_LOOPBACK);
++ strcpy(sctx->connect_ip, "127.0.0.1");
++ localhost.sin_family = AF_INET;
++ localhost.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
++ hostaddr = (struct sockaddr*) &localhost;
+ } else
+ {
+- sctx->connect_ip = ((struct sockaddr_in *) hostaddr)->sin_addr;
++ getnameinfo(hostaddr, sizeof(struct sockaddr_in6),
++ sctx->connect_ip, 63, NULL, 0, NI_NUMERICHOST);
+ }
+ sctx->assassin = NULL;
+ sctx->helo = NULL;
+@@ -758,12 +765,12 @@ mlfi_connect(SMFICTX * ctx, char *hostna
+ debug(D_ALWAYS, "smfi_setpriv failed!");
+ return SMFIS_TEMPFAIL;
+ }
+- /* debug(D_ALWAYS, "ZZZ set private context to %p", sctx); */
+
+- if (ip_in_networklist(sctx->connect_ip, &ignorenets))
++ debug(D_NET, "Checking %s against:", sctx->connect_ip);
++ if (ip_in_networklist(hostaddr, &ignorenets))
+ {
+ debug(D_NET, "%s is in our ignore list - accepting message",
+- inet_ntoa(sctx->connect_ip));
++ sctx->connect_ip);
+ debug(D_FUNC, "mlfi_connect: exit ignore");
+ return SMFIS_ACCEPT;
+ }
+@@ -807,7 +814,6 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
+ debug(D_ALWAYS, "smfi_getpriv failed!");
+ return SMFIS_TEMPFAIL;
+ }
+- /* debug(D_ALWAYS, "ZZZ got private context %p", sctx); */
+
+ if (ignore_authenticated_senders)
+ {
+@@ -835,7 +841,7 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
+ return SMFIS_TEMPFAIL;
+ };
+
+- assassin->set_connectip(string(inet_ntoa(sctx->connect_ip)));
++ assassin->set_connectip(string(sctx->connect_ip));
+
+ // Store a pointer to the assassin object in our context struct
+ sctx->assassin = assassin;
+@@ -2128,69 +2134,135 @@ void parse_networklist(char *string, str
+ {
+ char *tnet = strsep(&token, "/");
+ char *tmask = token;
+- struct in_addr net, mask;
++ struct in_addr net;
++ struct in6_addr net6;
+
+ if (list->num_nets % 10 == 0)
+- list->nets = (struct net*)realloc(list->nets, sizeof(*list->nets) * (list->num_nets + 10));
++ list->nets = (union net*)realloc(list->nets, sizeof(*list->nets) * (list->num_nets + 10));
+
+- if (!inet_aton(tnet, &net))
++ if (inet_pton(AF_INET, tnet, &net))
+ {
+- fprintf(stderr, "Could not parse \"%s\" as a network\n", tnet);
+- exit(1);
+- }
++ struct in_addr mask;
++
++ if (tmask)
++ {
++ if (strchr(tmask, '.') == NULL)
++ {
++ /* CIDR */
++ unsigned int bits;
++ int ret;
++ ret = sscanf(tmask, "%u", &bits);
++ if (ret != 1 || bits > 32)
++ {
++ fprintf(stderr,"%s: bad CIDR value", tmask);
++ exit(1);
++ }
++ mask.s_addr = htonl(~((1L << (32 - bits)) - 1) & 0xffffffff);
++ } else if (!inet_pton(AF_INET6, tmask, &mask))
++ {
++ fprintf(stderr, "Could not parse \"%s\" as a netmask\n", tmask);
++ exit(1);
++ }
++ } else
++ mask.s_addr = 0xffffffff;
+
+- if (tmask)
+- {
+- if (strchr(tmask, '.') == NULL)
++ net.s_addr = net.s_addr & mask.s_addr;
++ list->nets[list->num_nets].net4.af = AF_INET;
++ list->nets[list->num_nets].net4.network = net;
++ list->nets[list->num_nets].net4.netmask = mask;
++ } else if (inet_pton(AF_INET6, tnet, &net6))
++ {
++ int mask;
++
++ if (tmask)
+ {
+- /* CIDR */
+- unsigned int bits;
+- int ret;
+- ret = sscanf(tmask, "%u", &bits);
+- if (ret != 1 || bits > 32)
++ if (sscanf(tmask, "%d", &mask) != 1 || mask > 128)
+ {
+ fprintf(stderr,"%s: bad CIDR value", tmask);
+ exit(1);
+ }
+- mask.s_addr = htonl(~((1L << (32 - bits)) - 1) & 0xffffffff);
+- } else if (!inet_aton(tmask, &mask))
+- {
+- fprintf(stderr, "Could not parse \"%s\" as a netmask\n", tmask);
+- exit(1);
+- }
++ } else
++ mask = 128;
++
++ list->nets[list->num_nets].net6.af = AF_INET6;
++ list->nets[list->num_nets].net6.network = net6;
++ list->nets[list->num_nets].net6.netmask = mask;
+ } else
+- mask.s_addr = 0xffffffff;
++ {
++ fprintf(stderr, "Could not parse \"%s\" as a network\n", tnet);
++ exit(1);
++ }
+
+ {
+- char *snet = strdup(inet_ntoa(net));
+- debug(D_MISC, "Adding %s/%s to network list", snet, inet_ntoa(mask));
+- free(snet);
++ int af = list->nets[list->num_nets].net.af;
++ char addrbuf[INET6_ADDRSTRLEN];
++ char maskbuf[4];
++ char *maskstr;
++
++ if (af == AF_INET6) {
++ inet_ntop(af, &list->nets[list->num_nets].net6.network,
++ addrbuf, INET6_ADDRSTRLEN);
++ sprintf(maskbuf, "%d", list->nets[list->num_nets].net6.netmask);
++ maskstr = maskbuf;
++ list->nets[list->num_nets].net6.addrstr = strdup(addrbuf);
++ list->nets[list->num_nets].net6.maskstr = strdup(maskbuf);
++ } else
++ {
++ inet_ntop(af, &list->nets[list->num_nets].net4.network,
++ addrbuf, INET6_ADDRSTRLEN);
++ maskstr = inet_ntoa(list->nets[list->num_nets].net4.netmask);
++ list->nets[list->num_nets].net4.addrstr = strdup(addrbuf);
++ list->nets[list->num_nets].net4.maskstr = strdup(maskstr);
++ }
++ debug(D_MISC, "Added %s/%s to network list", addrbuf, maskstr);
+ }
+
+- net.s_addr = net.s_addr & mask.s_addr;
+- list->nets[list->num_nets].network = net;
+- list->nets[list->num_nets].netmask = mask;
+ list->num_nets++;
+ }
+ free(string);
+ }
+
+-int ip_in_networklist(struct in_addr ip, struct networklist *list)
++int ip_in_networklist(struct sockaddr *addr, struct networklist *list)
+ {
+ int i;
+
+ if (list->num_nets == 0)
+ return 0;
+-
+- debug(D_NET, "Checking %s against:", inet_ntoa(ip));
++
+ for (i = 0; i < list->num_nets; i++)
+ {
+- debug(D_NET, "%s", inet_ntoa(list->nets[i].network));
+- debug(D_NET, "/%s", inet_ntoa(list->nets[i].netmask));
+- if ((ip.s_addr & list->nets[i].netmask.s_addr) == list->nets[i].network.s_addr)
+- {
+- debug(D_NET, "Hit!");
+- return 1;
++ if (list->nets[i].net.af == AF_INET && addr->sa_family == AF_INET)
++ {
++ struct in_addr ip = ((struct sockaddr_in *)addr)->sin_addr;
++
++ debug(D_NET, "%s/%s", list->nets[i].net4.addrstr, list->nets[i].net4.maskstr);
++ if ((ip.s_addr & list->nets[i].net4.netmask.s_addr) == list->nets[i].net4.network.s_addr)
++ {
++ debug(D_NET, "Hit!");
++ return 1;
++ }
++ } else if (list->nets[i].net.af == AF_INET6 && addr->sa_family == AF_INET6)
++ {
++ u_int8_t *ip = ((struct sockaddr_in6 *)addr)->sin6_addr.s6_addr;
++ int mask, j;
++
++ debug(D_NET, "%s/%s", list->nets[i].net6.addrstr, list->nets[i].net6.maskstr);
++ mask = list->nets[i].net6.netmask;
++ for (j = 0; j < 16 && mask > 0; j++, mask -= 8)
++ {
++ unsigned char bytemask;
++
++ bytemask = (mask < 8) ? ~((1L << (8 - mask)) - 1) : 0xff;
++
++ if ((ip[j] & bytemask) != (list->nets[i].net6.network.s6_addr[j] & bytemask))
++ break;
++ }
++
++ if (mask <= 0)
++ {
++ debug(D_NET, "Hit!");
++ return 1;
++ }
+ }
+ }
+
+diff -up spamass-milter-0.3.1/spamass-milter.h.ipv6 spamass-milter-0.3.1/spamass-milter.h
+--- spamass-milter-0.3.1/spamass-milter.h.ipv6 2010-09-23 16:26:36.224160445 +0100
++++ spamass-milter-0.3.1/spamass-milter.h 2010-09-23 17:00:16.487410690 +0100
+@@ -56,16 +56,34 @@ sfsistat mlfi_abort(SMFICTX*);
+ extern struct smfiDesc smfilter;
+
+ /* struct describing a single network */
+-struct net
++union net
+ {
+- struct in_addr network;
+- struct in_addr netmask;
++ struct
++ {
++ uint8_t af;
++ } net;
++ struct
++ {
++ uint8_t af;
++ struct in_addr network;
++ struct in_addr netmask;
++ char *addrstr;
++ char *maskstr;
++ } net4;
++ struct
++ {
++ uint8_t af;
++ struct in6_addr network;
++ int netmask; /* Just the number of bits for IPv6 */
++ char *addrstr;
++ char *maskstr;
++ } net6;
+ };
+
+ /* an array of networks */
+ struct networklist
+ {
+- struct net *nets;
++ union net *nets;
+ int num_nets;
+ };
+
+@@ -162,7 +180,7 @@ public:
+ /* Private data structure to carry per-client data between calls */
+ struct context
+ {
+- struct in_addr connect_ip; // remote IP address
++ char connect_ip[64]; // remote IP address
+ char *helo;
+ char *our_fqdn;
+ char *sender_address;
+@@ -184,7 +202,7 @@ string::size_type find_nocase(const stri
+ int cmp_nocase_partial(const string&, const string&);
+ void closeall(int fd);
+ void parse_networklist(char *string, struct networklist *list);
+-int ip_in_networklist(struct in_addr ip, struct networklist *list);
++int ip_in_networklist(struct sockaddr *addr, struct networklist *list);
+ void parse_debuglevel(char* string);
+ char *strlwr(char *str);
+ void warnmacro(const char *macro, const char *scope);
diff --git a/spamass-milter-0.3.1-pathnames.patch b/spamass-milter-0.3.1-pathnames.patch
new file mode 100644
index 000000000000..8c90367f830d
--- /dev/null
+++ b/spamass-milter-0.3.1-pathnames.patch
@@ -0,0 +1,21 @@
+diff -up spamass-milter-0.3.1/README.pathnames spamass-milter-0.3.1/README
+--- spamass-milter-0.3.1/README.pathnames 2010-03-23 20:54:37.630904869 +0000
++++ spamass-milter-0.3.1/README 2010-03-23 20:55:22.007964867 +0000
+@@ -42,7 +42,7 @@ put the spamass-milter binary and set th
+ you want to use. YOU WILL MOST LIKELY HAVE TO EDIT THE VARIABLES ON
+ TOP OF THIS FILE.
+
+-Then start the daemon via /etc/init.d/spamass-milter start and make
++Then start the daemon via /etc/rc.d/init.d/spamass-milter start and make
+ sure it didn't crash/terminate immediately. If it does, there should
+ usually be syslog output.
+
+@@ -54,7 +54,7 @@ Now you need to make sendmail use the pl
+ configuring sendmail through m4 & the sendmail.mc files. In this case
+ adding the lines
+
+-INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/sendmail/spamass.sock, F=, T=C:15m;S:4m;R:4m;E:10m')dnl
++INPUT_MAIL_FILTER(`spamassassin', `S=unix:/var/run/spamass-milter/spamass-milter.sock, F=, T=C:15m;S:4m;R:4m;E:10m')dnl
+ define(`confMILTER_MACROS_ENVRCPT',confMILTER_MACROS_ENVRCPT`, b, r, v, Z')dnl
+
+ should do the trick. Of course you need to modify the path of the
diff --git a/spamass-milter-0.3.2-auth-no-ssf.patch b/spamass-milter-0.3.2-auth-no-ssf.patch
new file mode 100644
index 000000000000..ce3817330d1e
--- /dev/null
+++ b/spamass-milter-0.3.2-auth-no-ssf.patch
@@ -0,0 +1,28 @@
+This change is to help users with Postfix that aren't using the -I option
+to not pass mail from authenticated users through SpamAssassin. Postfix,
+unlike Sendmail, does not provide the {auth_ssf} macro, so in the case
+where mail is from an authenticated user, the modified code can now add
+an (authenticated) hint in the dummy Received: header (where Sendmail would
+add (authenticated bits=nnn)), and this is scored favourably by SpamAssassin.
+
+http://bugzilla.redhat.com/730308
+
+--- spamass-milter-0.3.2/spamass-milter.cpp
++++ spamass-milter-0.3.2/spamass-milter.cpp
+@@ -1046,9 +1046,14 @@
+
+ rec_header = (string) "Received: from " + macro_s + " (" + macro__ + ")\r\n\t";
+
+- if (strlen(macro_auth_ssf))
++ if (strlen(macro_auth_authen))
+ {
+- rec_header += (string) "(authenticated bits=" + macro_auth_ssf + ")\r\n\t";
++ rec_header += (string) "(authenticated";
++ if (strlen(macro_auth_ssf))
++ {
++ rec_header += (string) " bits=" + macro_auth_ssf;
++ }
++ rec_header += (string) ")\r\n\t";
+ }
+
+ rec_header += (string) "by " + macro_j + " (" + macro_v + "/" + macro_Z + ") with " +
diff --git a/spamass-milter-0.3.2-bits.patch b/spamass-milter-0.3.2-bits.patch
new file mode 100644
index 000000000000..8b1cc75ff7de
--- /dev/null
+++ b/spamass-milter-0.3.2-bits.patch
@@ -0,0 +1,289 @@
+Add authenticated bits information into the dummy generated
+Received-header for SpamAssassin to facilitate adding a rule
+to score mail from authenticated clients.
+
+Discussion:
+http://bugzilla.redhat.com/496769
+http://www.gossamer-threads.com/lists/spamassassin/users/146948
+
+This patch also moves some of the macro collection to the
+ENVFROM callback, where the required macros are available by default.
+
+diff -up spamass-milter-0.3.2/README.bits spamass-milter-0.3.2/README
+--- spamass-milter-0.3.2/README.bits 2008-04-23 17:11:42.000000000 +0100
++++ spamass-milter-0.3.2/README 2011-02-15 11:02:47.877271392 +0000
+@@ -55,15 +55,26 @@ configuring sendmail through m4 & the se
+ adding the lines
+
+ INPUT_MAIL_FILTER(`spamassassin', `S=local:/var/run/sendmail/spamass.sock, F=, T=C:15m;S:4m;R:4m;E:10m')dnl
+-define(`confMILTER_MACROS_CONNECT',`t, b, j, _, {daemon_name}, {if_name}, {if_addr}')dnl
+-define(`confMILTER_MACROS_HELO',`s, {tls_version}, {cipher}, {cipher_bits}, {cert_subject}, {cert_issuer}')dnl
+-define(`confMILTER_MACROS_ENVRCPT',`r, v, Z')dnl
++define(`confMILTER_MACROS_ENVRCPT',confMILTER_MACROS_ENVRCPT`, b, r, v, Z')dnl
+
+ should do the trick. Of course you need to modify the path of the
+ socket if you put another one into the startup script. The timeouts
+ have been increased somewhat because SpamAssassin may chew on it for a
+ little while on a slow machine.
+
++If you are using multiple milter mail filters on your mail server, you may
++have overridden the default values of some of the confMILTER_MACROS_*
++macros whilst configuring the other filters. You need to ensure that at
++least the following values are present:
++
++confMILTER_MACROS_CONNECT must include the {j} and {_} macros
++(all included by default)
++
++confMILTER_MACROS_ENVFROM must include the {i}, {auth_authen} and {auth_ssf}
++macros (all included by default)
++
++confMILTER_MACROS_ENVRCPT must include the {b}, {r}, {v}, and {Z} macros
++
+ Now recreate sendmail.cf, restart sendmail and experiment around a bit
+ with the setup to make sure it is working.
+
+diff -up spamass-milter-0.3.2/spamass-milter.cpp.bits spamass-milter-0.3.2/spamass-milter.cpp
+--- spamass-milter-0.3.2/spamass-milter.cpp.bits 2011-02-15 10:53:49.349259089 +0000
++++ spamass-milter-0.3.2/spamass-milter.cpp 2011-02-15 10:53:49.353259721 +0000
+@@ -678,6 +678,7 @@ sfsistat
+ mlfi_connect(SMFICTX * ctx, char *hostname, _SOCK_ADDR * hostaddr)
+ {
+ struct context *sctx;
++ const char *macro_j, *macro__;
+ int rv;
+
+ debug(D_FUNC, "mlfi_connect: enter");
+@@ -695,8 +696,31 @@ mlfi_connect(SMFICTX * ctx, char *hostna
+ }
+ sctx->assassin = NULL;
+ sctx->helo = NULL;
+-
+- /* store a pointer to it with setpriv */
++ sctx->our_fqdn = NULL;
++ sctx->sender_address = NULL;
++ sctx->queueid = NULL;
++ sctx->auth_authen = NULL;
++ sctx->auth_ssf = NULL;
++
++ /* store our FQDN */
++ macro_j = smfi_getsymval(ctx, const_cast<char *>("j"));
++ if (!macro_j)
++ {
++ macro_j = "localhost";
++ warnmacro("j", "CONNECT");
++ }
++ sctx->our_fqdn = strdup(macro_j);
++
++ /* store the validated sending site's address */
++ macro__ = smfi_getsymval(ctx, const_cast<char *>("_"));
++ if (!macro__)
++ {
++ macro__ = "unknown";
++ warnmacro("_", "CONNECT");
++ }
++ sctx->sender_address = strdup(macro__);
++
++ /* store a pointer to our private data with setpriv */
+ rv = smfi_setpriv(ctx, sctx);
+ if (rv != MI_SUCCESS)
+ {
+@@ -745,7 +769,7 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
+ {
+ SpamAssassin* assassin;
+ struct context *sctx = (struct context *)smfi_getpriv(ctx);
+- const char *queueid;
++ const char *queueid, *macro_auth_ssf, *macro_auth_authen;
+
+ if (sctx == NULL)
+ {
+@@ -787,17 +811,44 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
+
+ // remember the MAIL FROM address
+ assassin->set_from(string(envfrom[0]));
+-
++
++ // remember the queueid for this message
+ queueid=smfi_getsymval(ctx, const_cast<char *>("i"));
+ if (!queueid)
+ {
+ queueid="unknown";
+ warnmacro("i", "ENVFROM");
+ }
+- assassin->queueid = queueid;
+-
++ sctx->queueid = strdup(queueid);
+ debug(D_MISC, "queueid=%s", queueid);
+
++ // remember the SMTP AUTH login name
++ macro_auth_authen = smfi_getsymval(ctx, const_cast<char *>("{auth_authen}"));
++ if (!macro_auth_authen)
++ {
++ macro_auth_authen = "";
++ // Don't issue a warning for the auth_authen macro as
++ // it is likely to be unset much of the time - it's
++ // only set if the client has authenticated.
++ //
++ // Similarly, we only issue warnings for the other
++ // auth-related macros if {auth_authen) is available.
++ //
++ // warnmacro("auth_authen", "ENVFROM");
++ }
++ sctx->auth_authen = strdup(macro_auth_authen);
++
++ // remember the SASL cipher bits
++ macro_auth_ssf = smfi_getsymval(ctx, const_cast<char *>("{auth_ssf}"));
++ if (!macro_auth_ssf)
++ {
++ macro_auth_ssf = "";
++ if (strlen(macro_auth_authen)) {
++ warnmacro("auth_ssf", "ENVFROM");
++ }
++ }
++ sctx->auth_ssf = strdup(macro_auth_ssf);
++
+ // tell Milter to continue
+ debug(D_FUNC, "mlfi_envfrom: exit");
+
+@@ -888,7 +939,8 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
+
+ */
+ const char *macro_b, *macro_i, *macro_j, *macro_r,
+- *macro_s, *macro_v, *macro_Z, *macro__;
++ *macro_s, *macro_v, *macro_Z, *macro__,
++ *macro_auth_ssf, *macro_auth_authen;
+ char date[32];
+
+ /* RFC 822 date. */
+@@ -903,20 +955,13 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
+ }
+
+ /* queue ID */
+- macro_i = smfi_getsymval(ctx, const_cast<char *>("i"));
+- if (!macro_i)
+- {
+- macro_i = "unknown";
+- warnmacro("i", "ENVRCPT");
+- }
++ macro_i = sctx->queueid;
+
+- /* FQDN of this site */
+- macro_j = smfi_getsymval(ctx, const_cast<char *>("j"));
+- if (!macro_j)
+- {
+- macro_j = "localhost";
+- warnmacro("j", "ENVRCPT");
+- }
++ /* FQDN */
++ macro_j = sctx->our_fqdn;
++
++ /* Sender address */
++ macro__ = sctx->sender_address;
+
+ /* Protocol used to receive the message */
+ macro_r = smfi_getsymval(ctx, const_cast<char *>("r"));
+@@ -925,7 +970,11 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
+ macro_r = "SMTP";
+ warnmacro("r", "ENVRCPT");
+ }
+-
++
++ /* SMTP AUTH details */
++ macro_auth_authen = sctx->auth_authen;
++ macro_auth_ssf = sctx->auth_ssf;
++
+ /* Sendmail currently cannot pass us the {s} macro, but
+ I do not know why. Leave this in for the day sendmail is
+ fixed. Until that day, use the value remembered by
+@@ -953,22 +1002,25 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
+ warnmacro("Z", "ENVRCPT");
+ }
+
+- /* Validated sending site's address */
+- macro__ = smfi_getsymval(ctx, const_cast<char *>("_"));
+- if (!macro__)
++ assassin->output((string)"X-Envelope-From: "+assassin->from()+"\r\n");
++ assassin->output((string)"X-Envelope-To: "+envrcpt[0]+"\r\n");
++
++ string rec_header;
++
++ rec_header = (string) "Received: from " + macro_s + " (" + macro__ + ")\r\n\t";
++
++ if (strlen(macro_auth_ssf))
+ {
+- macro__ = "unknown";
+- warnmacro("_", "ENVRCPT");
++ rec_header += (string) "(authenticated bits=" + macro_auth_ssf + ")\r\n\t";
+ }
+
+- assassin->output((string)"X-Envelope-From: "+assassin->from()+"\r\n");
+- assassin->output((string)"X-Envelope-To: "+envrcpt[0]+"\r\n");
++ rec_header += (string) "by " + macro_j + " (" + macro_v + "/" + macro_Z + ") with " +
++ macro_r + " id " + macro_i + ";\r\n\t" +
++ macro_b + "\r\n\t" +
++ "(envelope-from " + assassin->from() + ")\r\n";
+
+- assassin->output((string)
+- "Received: from "+macro_s+" ("+macro__+")\r\n\t"+
+- "by "+macro_j+" ("+macro_v+"/"+macro_Z+") with "+macro_r+" id "+macro_i+";\r\n\t"+
+- macro_b+"\r\n\t"+
+- "(envelope-from "+assassin->from()+")\r\n");
++ debug(D_SPAMC, "Received header for spamc: %s", rec_header.c_str());
++ assassin->output(rec_header);
+
+ } else
+ assassin->output((string)"X-Envelope-To: "+envrcpt[0]+"\r\n");
+@@ -1214,16 +1266,27 @@ mlfi_close(SMFICTX* ctx)
+ {
+ struct context *sctx;
+ debug(D_FUNC, "mlfi_close");
+-
++
+ sctx = (struct context*)smfi_getpriv(ctx);
+ if (sctx == NULL)
+ return SMFIS_ACCEPT;
+
+ if (sctx->helo)
+ free(sctx->helo);
++ if (sctx->our_fqdn)
++ free(sctx->our_fqdn);
++ if (sctx->sender_address)
++ free(sctx->sender_address);
++ if (sctx->queueid)
++ free(sctx->queueid);
++ if (sctx->auth_authen)
++ free(sctx->auth_authen);
++ if (sctx->auth_ssf)
++ free(sctx->auth_ssf);
++
+ free(sctx);
+ smfi_setpriv(ctx, NULL);
+-
++
+ return SMFIS_ACCEPT;
+ }
+
+diff -up spamass-milter-0.3.2/spamass-milter.h.bits spamass-milter-0.3.2/spamass-milter.h
+--- spamass-milter-0.3.2/spamass-milter.h.bits 2011-02-15 10:53:49.342257983 +0000
++++ spamass-milter-0.3.2/spamass-milter.h 2011-02-15 10:53:49.354259879 +0000
+@@ -154,9 +154,6 @@ public:
+ // List of recipients after alias/virtusertable expansion
+ list <string> expandedrcpt;
+
+- // the sendmail queue id for this message; used for logging
+- string queueid;
+-
+ // Process handling variables
+ pid_t pid;
+ int pipe_io[2][2];
+@@ -167,6 +164,11 @@ struct context
+ {
+ struct in_addr connect_ip; // remote IP address
+ char *helo;
++ char *our_fqdn;
++ char *sender_address;
++ char *queueid;
++ char *auth_authen;
++ char *auth_ssf;
+ SpamAssassin *assassin; // pointer to the SA object if we're processing a message
+ };
+
diff --git a/spamass-milter-0.3.2-rcvd.patch b/spamass-milter-0.3.2-rcvd.patch
new file mode 100644
index 000000000000..7db55b12aab6
--- /dev/null
+++ b/spamass-milter-0.3.2-rcvd.patch
@@ -0,0 +1,23 @@
+The code in spamass-milter.cpp that tries to create a
+Sendmail-compatible header was broken and generated a header
+that was incorrectly parsed by SpamAssassin.
+
+This is mostly fixed now apart from the space that needs
+adding prior to the "(" between macro_j and macro_v.
+
+https://savannah.nongnu.org/bugs/index.php?17178
+http://bugs.debian.org/510665
+http://bugzilla.redhat.com/496763
+
+diff -up spamass-milter-0.3.2/spamass-milter.cpp.rcvd spamass-milter-0.3.2/spamass-milter.cpp
+--- spamass-milter-0.3.2/spamass-milter.cpp.rcvd 2011-02-15 10:46:55.000000000 +0000
++++ spamass-milter-0.3.2/spamass-milter.cpp 2011-02-15 10:50:25.538111680 +0000
+@@ -966,7 +966,7 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
+
+ assassin->output((string)
+ "Received: from "+macro_s+" ("+macro__+")\r\n\t"+
+- "by "+macro_j+"("+macro_v+"/"+macro_Z+") with "+macro_r+" id "+macro_i+";\r\n\t"+
++ "by "+macro_j+" ("+macro_v+"/"+macro_Z+") with "+macro_r+" id "+macro_i+";\r\n\t"+
+ macro_b+"\r\n\t"+
+ "(envelope-from "+assassin->from()+")\r\n");
+
diff --git a/spamass-milter-0.3.2-rundir.patch b/spamass-milter-0.3.2-rundir.patch
new file mode 100644
index 000000000000..ec08358ddea6
--- /dev/null
+++ b/spamass-milter-0.3.2-rundir.patch
@@ -0,0 +1,30 @@
+diff -up spamass-milter-0.3.2/README.orig spamass-milter-0.3.2/README
+--- spamass-milter-0.3.2/README.orig 2011-07-25 15:23:45.490316629 +0100
++++ spamass-milter-0.3.2/README 2011-07-25 15:27:47.647628663 +0100
+@@ -54,7 +54,7 @@ Now you need to make sendmail use the pl
+ configuring sendmail through m4 & the sendmail.mc files. In this case
+ adding the lines
+
+-INPUT_MAIL_FILTER(`spamassassin', `S=unix:/var/run/spamass-milter/spamass-milter.sock, F=, T=C:15m;S:4m;R:4m;E:10m')dnl
++INPUT_MAIL_FILTER(`spamassassin', `S=unix:/run/spamass-milter/spamass-milter.sock, F=, T=C:15m;S:4m;R:4m;E:10m')dnl
+ define(`confMILTER_MACROS_ENVRCPT',confMILTER_MACROS_ENVRCPT`, b, r, v, Z')dnl
+
+ should do the trick. Of course you need to modify the path of the
+diff -up spamass-milter-0.3.2/README.Postfix.orig spamass-milter-0.3.2/README.Postfix
+--- spamass-milter-0.3.2/README.Postfix.orig 2011-07-21 16:37:39.731590093 +0100
++++ spamass-milter-0.3.2/README.Postfix 2011-07-25 15:26:45.575801806 +0100
+@@ -2,12 +2,12 @@ Installing the spamass-milter-postfix pa
+ of spamass-milter to be more Postfix-friendly, i.e.:
+
+ The Unix-domain socket used for MTA communication is changed to
+- /var/run/spamass-milter/postfix/sock, and that socket is
++ /run/spamass-milter/postfix/sock, and that socket is
+ writable by the postfix group.
+
+ To configure Postfix to use the milter, add to /etc/postfix/main.cf:
+
+- smtpd_milters = unix:/var/run/spamass-milter/postfix/sock
++ smtpd_milters = unix:/run/spamass-milter/postfix/sock
+
+ For further information, see:
+ http://www.postfix.org/MILTER_README.html
diff --git a/spamass-milter-0.3.2-syntax.patch b/spamass-milter-0.3.2-syntax.patch
new file mode 100644
index 000000000000..3d1bc683e56e
--- /dev/null
+++ b/spamass-milter-0.3.2-syntax.patch
@@ -0,0 +1,248 @@
+Fix compiler warnings in recent gcc versions, mainly relating to deprecated
+conversions from string constants to char *.
+
+Most of these relate to missing "const" declarations in the libmilter API
+so I just used const_cast to clear them. For non libmilter-related issues,
+I tried to fix them more cleanly.
+
+The only other change of note is to check the result of the fwrite()
+function and log a warning if all of the data wasn't written (this is in
+the spambucket code).
+
+diff -up spamass-milter-0.3.2/spamass-milter.cpp.syntax spamass-milter-0.3.2/spamass-milter.cpp
+--- spamass-milter-0.3.2/spamass-milter.cpp.syntax 2011-02-14 21:53:02.000000000 +0000
++++ spamass-milter-0.3.2/spamass-milter.cpp 2011-02-15 10:09:59.748036059 +0000
+@@ -129,9 +129,11 @@ int daemon(int nochdir, int noclose);
+
+ static const char Id[] = "$Id: spamass-milter.cpp,v 1.94 2011/02/14 21:50:53 dnelson Exp $";
+
++static char FilterName[] = "SpamAssassin";
++
+ struct smfiDesc smfilter =
+ {
+- "SpamAssassin", // filter name
++ FilterName, // filter name
+ SMFI_VERSION, // version code -- leave untouched
+ SMFIF_ADDHDRS|SMFIF_CHGHDRS|SMFIF_CHGBODY, // flags
+ mlfi_connect, // info filter callback
+@@ -357,7 +359,7 @@ main(int argc, char* argv[])
+ // }}}
+
+ /* Update a header if SA changes it, or add it if it is new. */
+-void update_or_insert(SpamAssassin* assassin, SMFICTX* ctx, string oldstring, t_setter setter, char *header )
++void update_or_insert(SpamAssassin* assassin, SMFICTX* ctx, string oldstring, t_setter setter, const char *header )
+ {
+ string::size_type eoh1 = assassin->d().find("\n\n");
+ string::size_type eoh2 = assassin->d().find("\n\r\n");
+@@ -383,12 +385,12 @@ void update_or_insert(SpamAssassin* assa
+ if (oldsize > 0)
+ {
+ debug(D_UORI, "u_or_i: changing");
+- smfi_chgheader(ctx, header, 1, newstring.size() > 0 ?
++ smfi_chgheader(ctx, const_cast<char*>(header), 1, newstring.size() > 0 ?
+ cstr : NULL );
+ } else if (newstring.size() > 0)
+ {
+ debug(D_UORI, "u_or_i: inserting");
+- smfi_addheader(ctx, header, cstr);
++ smfi_addheader(ctx, const_cast<char*>(header), cstr);
+ }
+ } else
+ {
+@@ -448,7 +450,7 @@ assassinate(SMFICTX* ctx, SpamAssassin*
+ if (do_reject)
+ {
+ debug(D_MISC, "Rejecting");
+- smfi_setreply(ctx, "550", "5.7.1", "Blocked by SpamAssassin");
++ smfi_setreply(ctx, const_cast<char*>("550"), const_cast<char*>("5.7.1"), const_cast<char*>("Blocked by SpamAssassin"));
+
+
+ if (flag_bucket)
+@@ -457,14 +459,11 @@ assassinate(SMFICTX* ctx, SpamAssassin*
+ send another copy. The milter API will not let you send the
+ message AND return a failure code to the sender, so this is
+ the only way to do it. */
+- char *popen_argv[3];
++ char sendmail_prog[] = SENDMAIL;
++ char * const popen_argv[3] = { sendmail_prog, spambucket, NULL };
+ FILE *p;
+ pid_t pid;
+
+- popen_argv[0] = SENDMAIL;
+- popen_argv[1] = spambucket;
+- popen_argv[2] = NULL;
+-
+ debug(D_COPY, "calling %s %s", SENDMAIL, spambucket);
+ p = popenv(popen_argv, "w", &pid);
+ if (!p)
+@@ -473,7 +472,10 @@ assassinate(SMFICTX* ctx, SpamAssassin*
+ } else
+ {
+ // Send message provided by SpamAssassin
+- fwrite(assassin->d().c_str(), assassin->d().size(), 1, p);
++ if (fwrite(assassin->d().c_str(), assassin->d().size(), 1, p) != 1)
++ {
++ debug(D_COPY, "fwrite incomplete (%s) when copying to spambucket", strerror(errno));
++ }
+ fclose(p); p = NULL;
+ waitpid(pid, NULL, 0);
+ }
+@@ -494,7 +496,7 @@ assassinate(SMFICTX* ctx, SpamAssassin*
+ // time. Note, this may generate multiple X-Spam-Orig-To
+ // headers, but that's okay.
+ while( !assassin->recipients.empty()) {
+- if ( smfi_addheader( ctx, "X-Spam-Orig-To", (char *)assassin->recipients.front().c_str()) != MI_SUCCESS ) {
++ if ( smfi_addheader( ctx, const_cast<char *>("X-Spam-Orig-To"), (char *)assassin->recipients.front().c_str()) != MI_SUCCESS ) {
+ throw string( "Failed to save recipient" );
+ }
+
+@@ -737,7 +739,7 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
+ {
+ SpamAssassin* assassin;
+ struct context *sctx = (struct context *)smfi_getpriv(ctx);
+- char *queueid;
++ const char *queueid;
+
+ if (sctx == NULL)
+ {
+@@ -764,7 +766,7 @@ mlfi_envfrom(SMFICTX* ctx, char** envfro
+ // remember the MAIL FROM address
+ assassin->set_from(string(envfrom[0]));
+
+- queueid=smfi_getsymval(ctx,"i");
++ queueid=smfi_getsymval(ctx, const_cast<char *>("i"));
+ if (!queueid)
+ {
+ queueid="unknown";
+@@ -802,14 +804,11 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
+ /* open a pipe to sendmail so we can do address expansion */
+
+ char buf[1024];
+- char *popen_argv[4];
++ char sendmail_prog[] = SENDMAIL;
++ char sendmail_mode[] = "-bv";
++ char * const popen_argv[4] = { sendmail_prog, sendmail_mode, envrcpt[0], NULL };
+ pid_t pid;
+
+- popen_argv[0] = SENDMAIL;
+- popen_argv[1] = "-bv";
+- popen_argv[2] = envrcpt[0];
+- popen_argv[3] = NULL;
+-
+ debug(D_RCPT, "calling %s -bv %s", SENDMAIL, envrcpt[0]);
+
+ p = popenv(popen_argv, "r", &pid);
+@@ -871,7 +870,7 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
+ char date[32];
+
+ /* RFC 822 date. */
+- macro_b = smfi_getsymval(ctx, "b");
++ macro_b = smfi_getsymval(ctx, const_cast<char *>("b"));
+ if (!macro_b)
+ {
+ time_t tval;
+@@ -882,7 +881,7 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
+ }
+
+ /* queue ID */
+- macro_i = smfi_getsymval(ctx, "i");
++ macro_i = smfi_getsymval(ctx, const_cast<char *>("i"));
+ if (!macro_i)
+ {
+ macro_i = "unknown";
+@@ -890,7 +889,7 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
+ }
+
+ /* FQDN of this site */
+- macro_j = smfi_getsymval(ctx, "j");
++ macro_j = smfi_getsymval(ctx, const_cast<char *>("j"));
+ if (!macro_j)
+ {
+ macro_j = "localhost";
+@@ -898,7 +897,7 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
+ }
+
+ /* Protocol used to receive the message */
+- macro_r = smfi_getsymval(ctx, "r");
++ macro_r = smfi_getsymval(ctx, const_cast<char *>("r"));
+ if (!macro_r)
+ {
+ macro_r = "SMTP";
+@@ -910,14 +909,14 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
+ fixed. Until that day, use the value remembered by
+ mlfi_helo()
+ */
+- macro_s = smfi_getsymval(ctx, "s");
++ macro_s = smfi_getsymval(ctx, const_cast<char *>("s"));
+ if (!macro_s)
+ macro_s = sctx->helo;
+ if (!macro_s)
+ macro_s = "nohelo";
+
+ /* Sendmail binary version */
+- macro_v = smfi_getsymval(ctx, "v");
++ macro_v = smfi_getsymval(ctx, const_cast<char *>("v"));
+ if (!macro_v)
+ {
+ macro_v = "8.13.0";
+@@ -925,7 +924,7 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
+ }
+
+ /* Sendmail .cf version */
+- macro_Z = smfi_getsymval(ctx, "Z");
++ macro_Z = smfi_getsymval(ctx, const_cast<char *>("Z"));
+ if (!macro_Z)
+ {
+ macro_Z = "8.13.0";
+@@ -933,7 +932,7 @@ mlfi_envrcpt(SMFICTX* ctx, char** envrcp
+ }
+
+ /* Validated sending site's address */
+- macro__ = smfi_getsymval(ctx, "_");
++ macro__ = smfi_getsymval(ctx, const_cast<char *>("_"));
+ if (!macro__)
+ {
+ macro__ = "unknown";
+@@ -1321,10 +1320,10 @@ void SpamAssassin::Connect()
+ // XXX arbitrary 100-argument max
+ int argc = 0;
+ char** argv = (char**) malloc(100*sizeof(char*));
+- argv[argc++] = SPAMC;
++ argv[argc++] = strdup(SPAMC);
+ if (flag_sniffuser)
+ {
+- argv[argc++] = "-u";
++ argv[argc++] = strdup("-u");
+ if ( expandedrcpt.size() != 1 )
+ {
+ // More (or less?) than one recipient, so we pass the default
+@@ -1349,7 +1348,7 @@ void SpamAssassin::Connect()
+ }
+ if (spamdhost)
+ {
+- argv[argc++] = "-d";
++ argv[argc++] = strdup("-d");
+ argv[argc++] = spamdhost;
+ }
+ if (spamc_argc)
+@@ -2091,7 +2090,7 @@ char *strlwr(char *str)
+ }
+
+ /* Log a message about missing milter macros, but only the first time */
+-void warnmacro(char *macro, char *scope)
++void warnmacro(const char *macro, const char *scope)
+ {
+ if (warnedmacro)
+ return;
+diff -up spamass-milter-0.3.2/spamass-milter.h.syntax spamass-milter-0.3.2/spamass-milter.h
+--- spamass-milter-0.3.2/spamass-milter.h.syntax 2011-02-14 21:53:02.000000000 +0000
++++ spamass-milter-0.3.2/spamass-milter.h 2011-02-15 10:06:33.788736593 +0000
+@@ -185,7 +185,7 @@ void parse_networklist(char *string, str
+ int ip_in_networklist(struct in_addr ip, struct networklist *list);
+ void parse_debuglevel(char* string);
+ char *strlwr(char *str);
+-void warnmacro(char *macro, char *scope);
++void warnmacro(const char *macro, const char *scope);
+ FILE *popenv(char *const argv[], const char *type, pid_t *pid);
+
+ #endif
diff --git a/spamass-milter-postfix-sysconfig.systemd b/spamass-milter-postfix-sysconfig.systemd
new file mode 100644
index 000000000000..7607d86969ac
--- /dev/null
+++ b/spamass-milter-postfix-sysconfig.systemd
@@ -0,0 +1,5 @@
+# For Postfix support, use a postfix-group-writable socket
+# for communication with the MTA
+# This uses a Debian-style chrooted postfix
+SOCKET="/var/spool/postfix/spamass/spamass.sock"
+SOCKET_OPTIONS="-g postfix"
diff --git a/spamass-milter-postfix-tmpfs.conf b/spamass-milter-postfix-tmpfs.conf
new file mode 100644
index 000000000000..4b4a1fade0e9
--- /dev/null
+++ b/spamass-milter-postfix-tmpfs.conf
@@ -0,0 +1 @@
+d /var/spool/postfix/spamass 750 sa-milt postfix
diff --git a/spamass-milter-root.service b/spamass-milter-root.service
new file mode 100644
index 000000000000..2db402a50df8
--- /dev/null
+++ b/spamass-milter-root.service
@@ -0,0 +1,30 @@
+# Note: this unit file runs spamass-milter as the privileged user root,
+# which is necessary for using the milter's -x option for performing
+# virtusertable and alias expansion. If you are not using the -x option,
+# there is no need for the milter to run as root and it is best not to do so,
+# using the spamass-milter.service unit instead of this one.
+
+[Unit]
+Description = Mail filter for SpamAssassin
+Wants = spamassassin.service
+After = syslog.target
+After = local-fs.target
+After = network.target
+After = spamassassin.service
+Before = sendmail.service
+Before = postfix.service
+Conflicts = spamass-milter.service
+
+[Service]
+Type = simple
+UMask = 0022
+Environment = SOCKET=/run/spamass-milter/spamass-milter.sock SOCKET_OPTIONS= EXTRA_FLAGS=
+EnvironmentFile = -/etc/spamass-milter
+EnvironmentFile = -/etc/spamass-milter-postfix
+ExecStartPre = /usr/bin/chown -R root /run/spamass-milter
+ExecStart = /usr/bin/spamass-milter $SOCKET_OPTIONS -p $SOCKET $EXTRA_FLAGS
+ExecStopPost = /usr/bin/chown -R sa-milt /run/spamass-milter
+
+[Install]
+WantedBy = multi-user.target
+
diff --git a/spamass-milter-sysconfig.systemd b/spamass-milter-sysconfig.systemd
new file mode 100644
index 000000000000..995ab3042c79
--- /dev/null
+++ b/spamass-milter-sysconfig.systemd
@@ -0,0 +1,14 @@
+### Override for your different local config if necessary
+#SOCKET=/run/spamass-milter/spamass-milter.sock
+
+### You may add configuration parameters here, see spamass-milter(1)
+###
+### Note that the -x option for expanding aliases and virtusertable entries
+### only works if spamass-milter is run as root; you will need to use
+### spamass-milter-root.service instead of spamass-milter.service if you
+### wish to do this but otherwise it's best to run as the unprivileged user
+### sa-milt by using the normal spamass-milter.service
+#EXTRA_FLAGS="-m -r 15"
+
+# Some sane defaults (don't modify message too much; reject if score is too high; ignore authenticated senders; ignore outgoing mail)
+EXTRA_FLAGS="-m -r 15 -I -i 127.0.0.1"
diff --git a/spamass-milter-tmpfs.conf b/spamass-milter-tmpfs.conf
new file mode 100644
index 000000000000..621426eee4cd
--- /dev/null
+++ b/spamass-milter-tmpfs.conf
@@ -0,0 +1 @@
+d /run/spamass-milter 711 sa-milt sa-milt
diff --git a/spamass-milter.install b/spamass-milter.install
new file mode 100644
index 000000000000..d2a4b77355fc
--- /dev/null
+++ b/spamass-milter.install
@@ -0,0 +1,53 @@
+setup_user() {
+ /usr/bin/getent group sa-milt >/dev/null || (/usr/bin/groupadd -r sa-milt && echo "Added sa-milt group")
+ /usr/bin/getent passwd sa-milt >/dev/null || \
+ (/usr/bin/useradd -r -g sa-milt -d /var/lib/spamass-milter \
+ -s /usr/bin/nologin -c "SpamAssassin Milter" sa-milt && echo "Added sa-milt user")
+ # Fix homedir for upgrades
+ /usr/bin/usermod --home /var/lib/spamass-milter sa-milt &>/dev/null
+
+ # This is needed because the milter needs to "give away" the MTA communication
+ # socket to the postfix group, and it needs to be a member of the group to do
+ # that.
+ # (Adds sa-milt user to postfix group if postfix group exists)
+ /usr/bin/getent group postfix >/dev/null && /usr/bin/usermod -a -G postfix sa-milt
+}
+
+# arg 1: the new package version
+post_install() {
+ setup_user
+ systemctl daemon-reload
+ systemd-tmpfiles --create /usr/lib/tmpfiles.d/spamass-milter.conf
+ systemd-tmpfiles --create /usr/lib/tmpfiles.d/spamass-milter-postfix.conf
+ echo "Use the systemd unit spamass-milter.service or spamass-milter-root.service depending on your needs."
+}
+
+# arg 1: the new package version
+# arg 2: the old package version
+post_upgrade() {
+ setup_user
+ systemctl daemon-reload
+ systemd-tmpfiles --create /usr/lib/tmpfiles.d/spamass-milter.conf
+ systemd-tmpfiles --create /usr/lib/tmpfiles.d/spamass-milter-postfix.conf
+ systemctl try-restart spamass-milter.service
+ systemctl try-restart spamass-milter-root.service
+}
+
+# arg 1: the old package version
+pre_remove() {
+ echo "Stopping and disabling spamass-milter service(s)"
+ systemctl disable spamass-milter.service
+ systemctl disable spamass-milter-root.service
+ systemctl stop spamass-milter.service
+ systemctl stop spamass-milter-root.service
+}
+
+# arg 1: the old package version
+post_remove() {
+ systemctl daemon-reload
+ /usr/bin/userdel sa-milt && echo "Removed sa-milt user"
+ # Since sa-milt should be the only user in the sa-milt group, by default removing the user will also remove the group. But we add this extra check just in case.
+ /usr/bin/getent group sa-milt >/dev/null || (/usr/bin/groupdel sa-milt && echo "Removed sa-milt group")
+}
+
+# vim:set ts=2 sw=2 et:
diff --git a/spamass-milter.service b/spamass-milter.service
new file mode 100644
index 000000000000..7a947af741a2
--- /dev/null
+++ b/spamass-milter.service
@@ -0,0 +1,29 @@
+# Note: this unit file runs spamass-milter as the unprivileged user sa-milt,
+# which is not compatible with the milter's -x option for performing
+# virtusertable and alias expansion. If you are not using the -x option,
+# there is no need for the milter to run as root and it is best not to do so.
+# However, if you are using the -x option, you will need to run the milter as
+# root and should use the spamass-milter-root.service unit instead of this one.
+
+[Unit]
+Description = Mail filter for SpamAssassin
+Wants = spamassassin.service
+After = syslog.target
+After = local-fs.target
+After = network.target
+After = spamassassin.service
+Before = sendmail.service
+Before = postfix.service
+Conflicts = spamass-milter-root.service
+
+[Service]
+Type = simple
+UMask = 0022
+Environment = SOCKET=/run/spamass-milter/spamass-milter.sock SOCKET_OPTIONS= EXTRA_FLAGS=
+EnvironmentFile = -/etc/spamass-milter
+EnvironmentFile = -/etc/spamass-milter-postfix
+User = sa-milt
+ExecStart = /usr/bin/spamass-milter $SOCKET_OPTIONS -p $SOCKET $EXTRA_FLAGS
+
+[Install]
+WantedBy = multi-user.target