From aaf23f35f87d65982d20ab4127f5136c3181785f Mon Sep 17 00:00:00 2001 From: Stuart Gathman Date: Tue, 25 Oct 2005 21:39:47 +0000 Subject: [PATCH] New webpage design based on ht2html. --- doc/Maxwells.gif | Bin 0 -> 32642 bytes doc/SPF.gif | Bin 0 -> 1649 bytes doc/changes.ht | 157 ++++++++++++++++ doc/credits.ht | 49 +++++ faq.html => doc/faq.ht | 2 +- logmsgs.html => doc/logmsgs.ht | 0 milter.html => doc/milter.ht | 330 +++++---------------------------- policy.html => doc/policy.ht | 0 doc/python55.gif | Bin 0 -> 2723 bytes doc/requirements.ht | 92 +++++++++ 10 files changed, 348 insertions(+), 282 deletions(-) create mode 100644 doc/Maxwells.gif create mode 100644 doc/SPF.gif create mode 100644 doc/changes.ht create mode 100644 doc/credits.ht rename faq.html => doc/faq.ht (99%) rename logmsgs.html => doc/logmsgs.ht (100%) rename milter.html => doc/milter.ht (50%) rename policy.html => doc/policy.ht (100%) create mode 100644 doc/python55.gif create mode 100644 doc/requirements.ht diff --git a/doc/Maxwells.gif b/doc/Maxwells.gif new file mode 100644 index 0000000000000000000000000000000000000000..3175fe9a083536cc3163e63985c20cd85538b529 GIT binary patch literal 32642 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 BPuc(g literal 0 HcmV?d00001 diff --git a/doc/SPF.gif b/doc/SPF.gif new file mode 100644 index 0000000000000000000000000000000000000000..88106472466a59a434cbad7ac9729403789aba76 GIT binary patch literal 1649 zcmZ?wbhEHb3}-N6IKsg2NJcg|D(3r~sprmL`1kwWqBVCpILn^hys&5Ima~WV-hBD` z|G!VxR;xbeWc2rUynK9f-=T}=Za=JPI`HMqvw;Cyt)1At>RA>1`yBz5g=A9 zep}2@iZ?}|^M=)~B}FH5Saw``rx#5+xnn`3p~+Me}RvVt7bVmMEpIwi=&z{$+MOHxvh%lO7k zHGdx&DgL%Aj~+{LFz^aUNbnc3i)?iL`04YPub*vgze;n-AF_}U6pENtkTJ)CheL|N zp@8EsizA;#LWJAKMXssLLJB)3`OLM-V0Pk5$T&M+gkuTEf14X8ij+;#nT(Vy6f}fc z9hMe7Qz=-`=+7u8_d`ZY;UHrOzlO@Hg)WRNW%&l4b6+_oYWXya$rLm^Xgs&RnZqYT zA;IbVCZgxt%f73aMDump6N0N5_0(J z1WwnTd!g#t&o0vNXo6724sRwQUxNll4JiReX116ODN}?TG94Lt3=$d{#cr6-3Nvp@ zI;tm{w{51=bDIDMHo3$Ji;DRQo*tYO9`}H8ilS6PgHGtBqYW(OMh})IB)GLLZkA4A zIM>j%aOX`a0fEjW_Cg*9N4D#g4NDn$Y&z4YZEAR-zC4i6YDRBcn-eRW;i>X-It&ks z7qAzu+sweiQxV`eB`WHq!-}SRnT{+E7^aJ^dSfW)$i~#_+Tb*`@%vppi5RXE|Cs~} zcB!sgY54Os)1rHt2UU)_wdOQi7EEwtXmk}7shM))$kdD*i#QIhWp)TSz#{Gt#SqKN zBM_(gK`1C=lUK#!<&1nC+hYB46dV{6F155?U9(w4NOb4ZNs?)Yq;zr|7Sa`Bz@RH?jk``cOBXB}9%S=K+_FLS*558p}kf2{VF845R8{GBz8@78P0 zET6td|Bw2&o6(vTFPGHzTU?CSNVJP6+%cK)!8G$XoB;tJC%1-_30gUbu1sLFzV~n1 z^p^j<%NWEPE;4<(roG$O-+x!};ntXCOY0mzM3~P?_&+Vd(aATdc}Y~n^abjNJ#XX{ zs5vL5SU5QUi)`l9H4$TEo8ZV1^MFY}qJxF0{D_k0(T;Y{z;cB$J-JnRtqyNy99=R= z!F}dRL${kpLy9C0zLQqX$`CoTNNlkaL(GhqK5;dV{g)h^A3U>=A@y*QaFd2h_|GF6 z>`LdEPfQk@U$apo`$yOHDDg@1ZjJp1A|3Ly9?$=HmfZQ JbvPIqtN}*{)dBzj literal 0 HcmV?d00001 diff --git a/doc/changes.ht b/doc/changes.ht new file mode 100644 index 0000000..3d2820b --- /dev/null +++ b/doc/changes.ht @@ -0,0 +1,157 @@ +

Recent Changes

+ +Python milter has been moved to +pymilter Sourceforge +project for development and release downloads. + +

New website design

+ +Hey, I'm no artist, so I just used the + package +by Barry Warsaw. The mascot +is by Christian Hafner, +or maybe his wife. I chose Maxwell's daemon because it tirelessly +and invisibly sorts molecules, just as milters sort mail. +Cristian has also provided a fun + +simulation that lets you try your hand at sorting molecules. + +

0.8.4

+ +Release 0.8.4 makes configuring SPF policy via access.db actually work. +The honeypot idea is enhanced by auto-whitelisting recipients of +email sent from selected domains. Whitelisted messages are then used +to train the honeypot. This makes the honeypot screener entirely self +training. The smfi_progress() API is now automatically supported when present. +An optional idx parameter to milter.addheader() invokes smfi_insheader(). + +

0.8.3

+ +Release 0.8.3 uses the standard logging module, and supports configuring +more detailed SPF policy via the sendmail access map. SMTP AUTH connections +are considered INTERNAL. Preventing forgery between internal domains is +just a matter of specifying the user-domain map - I'll define something +for the next version. We now send DSNs when mail is quarantined (rejecting +if DSN fails) and for SPF syntax errors (PermError). There is an +experimental option to add a Sender header when it is missing and the From +domain doesn't match the MAIL FROM domain. Next release, we may start +renaming and replacing an existing Sender header when neither it nor the +From domain matches MAIL FROM. Since bogus MAIL FROMs are rejected +(to varying degrees depending on the configured SPF policy), and +both Sender and From and displayed by default in many email clients, +this provides some phishing protection without rejecting mail based +on headers. + +

0.8.2

+ +Release 0.8.2 has changes to SPF to bring it +in line with the newly official RFC. It adds +SES +support (the original SES without body hash) for pysrs-0.30.10, and honeypot +support for pydspam-1.1.9. There is a new method in the base milter module. +milter.set_exception_policy(i) lets you choose a policy of CONTINUE, REJECT, or +TEMPFAIL (default) for untrapped exceptions encountered in a milter callback. + +

0.8.0

+ +Release 0.8.0 is the first Sourceforge +release. It supports Python-2.4, and provides an option to accept mail +that gets an SPF softfail or fails the 3 strikes rule, provided the +alleged sender accepts a DSN explaining the problem. Python-2.3 is +no longer supported by the reworked mime.py module, although API changes +could be backported. There are too many incompatible changes to the +python email package. + +

Older Releases

+ +Release 0.7.2 tightens the authentication screws with a "3 strikes and +you're out" policy. A sender must have a valid PTR, HELO, or SPF record +to send email. Specific senders can be whitelisted using the +"delegate" option in the spf configuration section by adding a +default SPF record for them. The PTR and HELO are required +by RFC anyway, so this is not an unreasonable requirement. +There is now a coherent policy for an SPF softfail result. A softfail +is accepted if there is a valid PTR or HELO, or if the domain +is listed in the "accept_softfail" option of the spf configuration section. +A neutral result is accepted by default if there is a valid PTR or +HELO, (and the SPF record was not guessed), unless the domain is listed in the +"reject_neutral" option. Common forms of PTR records for dynamic IPs are +recognized, and do not count as a valid PTR. This does not prevent anyone +from sending mail from a dynamic IP - they just need to configure a +valid HELO name or publish an SPF record. +

+As SPF adoption continues to rise, forged spam is not getting through. So +spammers are publishing their SPF records as predicted. The 0.7.2 RPM +now provides the rhsbl sendmail hack so that spammer domains +can be blacklisted. With the RPM installed, add a line like the following +to your sendmail.mc. +

+HACK(rhsbl,`blackholes.example.com',"550 Rejected: " $&{RHS} " has been spamming our customers.")dnl
+
+

+Of course, spammers are now starting to register +throwaway domains. The next thing we need is a custom DNS server, +in Python, that +can recognize patterns. For instance, one spammer registers ded304.com, +ded305.com, ded306.com, etc. We also need the custom DNS server to +let SPF classic clients check SES (which will be part of pysrs). +The Twisted Python +framework provides a custom DNS server - but I +would like a smaller implementation for our use. +

+The RPM for release 0.7.0 moves the config file and socket locations to +/etc/mail and /var/run/milter respectively. We now parse Microsoft CID records +- but only hotmail.com uses them. They seem to have applied for a patent on +the brilliant idea of examining the mail headers to see who the message is +from. We aren't doing that here, so not to worry - but I am not a lawyer, so +if you are worried, change spf.py around line 626 to return None instead of +calling CIDParser(). There is a new option to reject mail with no PTR +and no SPF. +

+Microsoft is pushing an anti-opensource license for their pending patent +along with their sender-ID proposal before the IETF. +It is royalty free - but requires anyone distributing a binary they've +compiled from source to sign a license agreement. The Apache Software +Foundation explains +the problem with sender-ID, and Debian concurs. Since +the Microsoft license is +incompatible with free +software in general and the GPL in +particular, Python milter will not be able to implement sender-ID in its +current form. This was, no doubt, Microsoft's intent all along. +

+Sender-ID attempts to do for RFC2822 headers what SPF does for RFC2821 headers. +Unlike SPF, it has never been tried, and is encumbered by a stupid patent. I +recommend ignoring it and continuing to implement and improve SPF until a +working and unencumbered proposal for RFC2822 headers surfaces. + +

+ +SPF logo +Release 0.6.6 adds support for SPF, +a protocol to prevent forging of the envelope from address. +SPF support requires pydns. +The included spf.py module is an updated version of the original 1.6 +version at wayforward.net. +The updated version tracks the draft RFC and test suite. +

+The FAQ addresses how to get started with SPF. +

+Release 0.6.1 adds a full milter based dspam application. +

+I have selected the +dspam bayes filter project and +packaged it for python. +Release 0.6.0 offers a simple application of dspam I call "header triage", +which rejects messages with spammy headers. +To use header triage, you must have DSPAM installed, +and select a dictionary that is well moderated by someone who gets +lots of spam. That dictionary can be used to block spam that is +obvious from the headers (e.g. X-Mailer and Subject) before it ties +up any more resources. I have yet to see any false positives from this +approach (check the milter log), but if there are, the sender will +get a REJECT with the message "Your message looks spammy." + diff --git a/doc/credits.ht b/doc/credits.ht new file mode 100644 index 0000000..30b0e60 --- /dev/null +++ b/doc/credits.ht @@ -0,0 +1,49 @@ +

CREDITS

+ +Jim Niemira +wrote the original C module and some quick +and dirty python to use it. +Stuart D. Gathman +took that kludge and added threading and context objects to it, wrote a proper +OO wrapper (Milter.py) that handles attachments, did lots of testing, packaged +it with distutils, and generally transformed it from a quick hack to a +real, usable Python extension. + +

Other contributors (in random order):

+ +
+
Christian Hafner +
for the pymilter mascot image of + + Maxwell's daemon +
Dave MacQuigg +
for noticing that smfi_insheader wasn't supported, and creating + a template to help first time pymilter users create their own milter. +
Terence Way +
for providing a Python port of SPF +
Scott Kitterman +
for doing lots of testing and debugging of SPF against draft standard, + and for putting up a web page that validates SPF records using spf.py +
Alexander Kourakos +
for plugging several memory leaks +
George Graf at Vienna University of Economics and Business Administration +
for handling None passed to setreply and chgheader. +
Deron Meranda +
for IPv6 patches +
Jason Erikson +
for handling NULL hostaddr in connect callback. +
John Draper +
for porting Python milter to OpenBSD, and starting to work on tutorials + then pointing out that it would be easier to just write the MTA in Python. +
Eric S. Johansson +
for helpful design discussions while working on camram +
Alex Savguira +
for finding bugs with international headers and + suggesting the scan_zip option. +
Business Management Systems +
for hosting the website, and providing paying clients who need milter + service so I can work on it as part of my day job. +
+ +If I have left anybody out, send me a reminder: +stuart@bmsi.com diff --git a/faq.html b/doc/faq.ht similarity index 99% rename from faq.html rename to doc/faq.ht index 6838ed7..206df0a 100644 --- a/faq.html +++ b/doc/faq.ht @@ -22,7 +22,7 @@ shows you how to install libmilter with a separate invocation of make.
  • Q. Why is mfapi.h not found when I try to compile Python milter on RedHat 7.2?

    A. RedHat forgot to include the header in the RPM. See the -RedHat 7.2 requirements. +RedHat 7.2 requirements.

    Running Python Milter

    diff --git a/logmsgs.html b/doc/logmsgs.ht similarity index 100% rename from logmsgs.html rename to doc/logmsgs.ht diff --git a/milter.html b/doc/milter.ht similarity index 50% rename from milter.html rename to doc/milter.ht index d2298c2..5a465e1 100644 --- a/milter.html +++ b/doc/milter.ht @@ -1,33 +1,28 @@ - - - - -Python Milters -

    -Viewable With Any Browser -Your vote? I Disagree I Agree -

    + +Maxwell's Daemon: pymilter mascot

    Sendmail Milters in Python

    by Jim Niemira and Stuart D. Gathman
    This web page is written by Stuart D. Gathman
    and
    sponsored by Business Management Systems, Inc.
    -Last updated Oct 20, 2005

    +Last updated Oct 25, 2005 See the FAQ | Download now | -Subscribe to mailing list | +Subscribe to mailing list | Overview | pydspam | libdspam @@ -45,181 +40,6 @@ separation features to enhance security. Even better, sendmail 8.13 supports socket maps, which makes pysrs much more efficient and secure. I recommend upgrading. -

    Recent Changes

    - -Python milter has been moved to -pymilter Sourceforge -project for development and release downloads. -

    -Release 0.8.4 makes configuring SPF policy via access.db actually work. -The honeypot idea is enhanced by auto-whitelisting recipients of -email sent from selected domains. Whitelisted messages are then used -to train the honeypot. This makes the honeypot screener entirely self -training. The smfi_progress() API is now automatically supported when present. -An optional idx parameter to milter.addheader() invokes smfi_insheader(). -

    -Release 0.8.3 uses the standard logging module, and supports configuring -more detailed SPF policy via the sendmail access map. SMTP AUTH connections -are considered INTERNAL. Preventing forgery between internal domains is -just a matter of specifying the user-domain map - I'll define something -for the next version. We now send DSNs when mail is quarantined (rejecting -if DSN fails) and for SPF syntax errors (PermError). There is an -experimental option to add a Sender header when it is missing and the From -domain doesn't match the MAIL FROM domain. Next release, we may start -renaming and replacing an existing Sender header when neither it nor the -From domain matches MAIL FROM. Since bogus MAIL FROMs are rejected -(to varying degrees depending on the configured SPF policy), and -both Sender and From and displayed by default in many email clients, -this provides some phishing protection without rejecting mail based -on headers. -

    -Release 0.8.2 has changes to SPF to bring it -in line with the newly official RFC. It adds -SES -support (the original SES without body hash) for pysrs-0.30.10, and honeypot -support for pydspam-1.1.9. There is a new method in the base milter module. -milter.set_exception_policy(i) lets you choose a policy of CONTINUE, REJECT, or -TEMPFAIL (default) for untrapped exceptions encountered in a milter callback. -

    -Release 0.8.0 is the first Sourceforge -release. It supports Python-2.4, and provides an option to accept mail -that gets an SPF softfail or fails the 3 strikes rule, provided the -alleged sender accepts a DSN explaining the problem. Python-2.3 is -no longer supported by the reworked mime.py module, although API changes -could be backported. There are too many incompatible changes to the -python email package. -

    -Release 0.7.2 tightens the authentication screws with a "3 strikes and -you're out" policy. A sender must have a valid PTR, HELO, or SPF record -to send email. Specific senders can be whitelisted using the -"delegate" option in the spf configuration section by adding a -default SPF record for them. The PTR and HELO are required -by RFC anyway, so this is not an unreasonable requirement. -There is now a coherent policy for an SPF softfail result. A softfail -is accepted if there is a valid PTR or HELO, or if the domain -is listed in the "accept_softfail" option of the spf configuration section. -A neutral result is accepted by default if there is a valid PTR or -HELO, (and the SPF record was not guessed), unless the domain is listed in the -"reject_neutral" option. Common forms of PTR records for dynamic IPs are -recognized, and do not count as a valid PTR. This does not prevent anyone -from sending mail from a dynamic IP - they just need to configure a -valid HELO name or publish an SPF record. -

    -As SPF adoption continues to rise, forged spam is not getting through. So -spammers are publishing their SPF records as predicted. The 0.7.2 RPM -now provides the rhsbl sendmail hack so that spammer domains -can be blacklisted. With the RPM installed, add a line like the following -to your sendmail.mc. -

    -HACK(rhsbl,`blackholes.example.com',"550 Rejected: " $&{RHS} " has been spamming our customers.")dnl
    -
    -

    -Of course, spammers are now starting to register -throwaway domains. The next thing we need is a custom DNS server, -in Python, that -can recognize patterns. For instance, one spammer registers ded304.com, -ded305.com, ded306.com, etc. We also need the custom DNS server to -let SPF classic clients check SES (which will be part of pysrs). -The Twisted Python -framework provides a custom DNS server - but I -would like a smaller implementation for our use. -

    -The RPM for release 0.7.0 moves the config file and socket locations to -/etc/mail and /var/run/milter respectively. We now parse Microsoft CID records -- but only hotmail.com uses them. They seem to have applied for a patent on -the brilliant idea of examining the mail headers to see who the message is -from. We aren't doing that here, so not to worry - but I am not a lawyer, so -if you are worried, change spf.py around line 626 to return None instead of -calling CIDParser(). There is a new option to reject mail with no PTR -and no SPF. -

    -Microsoft is pushing an anti-opensource license for their pending patent -along with their sender-ID proposal before the IETF. -It is royalty free - but requires anyone distributing a binary they've -compiled from source to sign a license agreement. The Apache Software -Foundation explains -the problem with sender-ID, and Debian concurs. Since -the Microsoft license is -incompatible with free -software in general and the GPL in -particular, Python milter will not be able to implement sender-ID in its -current form. This was, no doubt, Microsoft's intent all along. -

    -Sender-ID attempts to do for RFC2822 headers what SPF does for RFC2821 headers. -Unlike SPF, it has never been tried, and is encumbered by a stupid patent. I -recommend ignoring it and continuing to implement and improve SPF until a -working and unencumbered proposal for RFC2822 headers surfaces. - -

    - -SPF logo -Release 0.6.6 adds support for SPF, -a protocol to prevent forging of the envelope from address. -SPF support requires pydns. -The included spf.py module is an updated version of the original 1.6 -version at wayforward.net. -The updated version tracks the draft RFC and test suite. -

    -The FAQ addresses how to get started with SPF. -

    -Release 0.6.1 adds a full milter based dspam application. -

    -I have selected the -dspam bayes filter project and -packaged it for python. -Release 0.6.0 offers a simple application of dspam I call "header triage", -which rejects messages with spammy headers. -To use header triage, you must have DSPAM installed, -and select a dictionary that is well moderated by someone who gets -lots of spam. That dictionary can be used to block spam that is -obvious from the headers (e.g. X-Mailer and Subject) before it ties -up any more resources. I have yet to see any false positives from this -approach (check the milter log), but if there are, the sender will -get a REJECT with the message "Your message looks spammy." - -

    Enough Already!

    - -Nearly a dozen people have emailed me begging for a feature to copy -outgoing and/or incoming mail to a backup directory by user. Ok, it -looks like this is a most requested feature for 0.5.6. In the meantime, -here are some things to consider: -
      -
    • If you want to equivalent of a Bcc added to each message, this -is very easy to do in the python code for bms.py. See below. -
    • If you want to copy to a file in a directory (thus avoiding having to -set up aliases), this is slightly more involved. The bms.py milter already -copies the message to a temporary file for use in replacing the message body -when banned attachments are found. You have to open a file, and copy the -Mesage object to it in eom(). -
    • Finally, you are probably aware that most email clients already -keep a copy of outgoing mail? Presumably there is a good reason for -keeping another copy on the server. -
    -

    -To Bcc a message, call self.add_recipient(rcpt) in envfrom after -determining whether you want to copy (e.g. whether the sender is local). For -example, -

    -  def envfrom(...
    -    ...
    -    if len(t) == 2:
    -      self.rejectvirus = t[1] in reject_virus_from
    -      if t[0] in wiretap_users.get(t[1],()):
    -	self.add_recipient(wiretap_dest)
    -      if t[1] == 'mydomain.com':
    -        self.add_recipient('<copy-%s>' % t[0])
    -      ...
    -
    -

    -To make this a generic feature requires thinking about how the configuration -would look. Feel free to make specific suggestions about config file -entries. Be sure to handle both Bcc and file copies, and designating what -mail should be copied. How should "outgoing" be defined? Implementing it is -easy once the configuration is designed. -

    Overview

    This package provides a robust toolkit for Python 0.5.5 RedHat 7.3gcc-2.962.3.38.13.1 0.7.2 +RedHat 7.3gcc-2.962.4.18.13.5 +0.8.4 RedHat 8.0gcc-3.22.2.18.12.6 0.5.2 Debian Linuxgcc-2.95.22.1.18.12.0 @@ -412,8 +234,8 @@ me if you successfully install milter on a system not mentioned below. 0.3.4 AIX-4.1.5gcc-2.95.22.1.38.12.3 0.4.2 -AIX-4.1.5gcc-2.95.22.2.38.13.1 -0.7.1 +AIX-4.1.5gcc-2.95.22.4.18.13.1 +0.8.4 Slackware 7.1??8.12.1 0.3.8 Slackware 9.0gcc-3.2.22.2.38.12.9 @@ -427,108 +249,54 @@ me if you successfully install milter on a system not mentioned below. FreeBSDgcc-2.95.32.2.2? 0.5.5 FreeBSD 4.4gcc-2.95.3?8.12.10 -0.6.6 - +0.6.6 -

    Requirements

    +

    Enough Already!

    - -
  • While the miltermodule will work with python 1.5, you probably -want to use python 2.0 or better. The python code uses a number of -python 2 features. -
  • Python must be configured with thread support. This is because -sendmail's libmilter requires thread support. -
  • You must compile sendmail with libmilter enabled. In versions of -sendmail prior to 8.12 libmilter is marked FFR (For Future Release) and -is not installed by default. -Sendmail 8.12 still does not enable libmilter by default. You must -explicitly select the "MILTER" option when compiling. -
  • Python milter has been tested against sendmail-8.11 and sendmail-8.12. -
  • Python milter must be compiled for the specific version of sendmail -it will run with. (Since the result is dynamically loaded, there could -conceivably be multiple versions available and selected at startup - but -that will have to wait.) This situation may only exist for sendmail -versions prior to 8.12. The protocol seems designed for backward -compatibility - and 8.12 is the first official milter release. -
  • Mea Culpa! After reading the Python Style guide, I realize that -my Python code is not up to snuff. Apparently mixed tabs and spaces -are anathema to those using Windows editors, where tabs can be expanded using -any arbitrary algorithm. Other than that, my -intuition matched Guido's pretty well - although I like to indent by 2 -rather than 4. I will arrange to have tabs expanded to spaces when -exporting new versions. Until then, beware! -
  • - -

    AIX 4.1.5 Requirements

    -To create sendmail RPMs for AIX, you can download my AIX 4.1.5 spec files -for sendmail-8.11.5 -or sendmail-8.12.3. If you have -not already set it up, I use a dummy RPM package -to represent the stuff that comes with AIX. You might also want -my python-2.1.1 spec file for AIX. It -does not include Tk or curses modules, sorry. If y'all trust me, you can -download rpms for AIX 4.x from my AIX RPM directory. +Nearly a dozen people have emailed me begging for a feature to copy +outgoing and/or incoming mail to a backup directory by user. Ok, it +looks like this is a most requested feature for 0.5.6. In the meantime, +here are some things to consider: +
      +
    • If you want to equivalent of a Bcc added to each message, this +is very easy to do in the python code for bms.py. See below. +
    • If you want to copy to a file in a directory (thus avoiding having to +set up aliases), this is slightly more involved. The bms.py milter already +copies the message to a temporary file for use in replacing the message body +when banned attachments are found. You have to open a file, and copy the +Mesage object to it in eom(). +
    • Finally, you are probably aware that most email clients already +keep a copy of outgoing mail? Presumably there is a good reason for +keeping another copy on the server. +

    -Sendmail-8.12 renames -libsmutil.a to libsm.a. Unfortunately, libsm.a is an important AIX system -shared library. Therefore, I rename libsm.a back to libsmutil.a for -AIX. This presents a problem for setup.py. - -

    RedHat 7.2 Requirements

    - -If you are running Redhat 7.2, the distributed version of sendmail -now enables libmilter by default. RedHat 7.2 bundles -the development libraries with the main sendmail package, so -there is no sendmail-devel package. However, they forgot to include the -headers! So you'll have to get the SRPM and modify it. I suggest -moving the static libs to a devel package and adding the headers. If -this is too much trouble, you can get the mfapi.h -header for sendmail-8.6.11 from here and manually install it as -/usr/include/libmilter/mfapi.h. +To Bcc a message, call self.add_recipient(rcpt) in envfrom after +determining whether you want to copy (e.g. whether the sender is local). For +example, +
    +  def envfrom(...
    +    ...
    +    if len(t) == 2:
    +      self.rejectvirus = t[1] in reject_virus_from
    +      if t[0] in wiretap_users.get(t[1],()):
    +	self.add_recipient(wiretap_dest)
    +      if t[1] == 'mydomain.com':
    +        self.add_recipient('<copy-%s>' % t[0])
    +      ...
    +

    -If you do modify the SRPM, I suggest renaming libsmutil.a -to libsm.a - just like sendmail-8.12 will. If you manually install -mfapi.h or don't rename libsmutil.a, you'll -need to force libs = ["milter", "smutil"] in setup.py. -

    -If you have installed python2, and want -python-milter to use python2, add python=python2 to setup.cfg -and build with python2 setup.py bdist_rpm. +To make this a generic feature requires thinking about how the configuration +would look. Feel free to make specific suggestions about config file +entries. Be sure to handle both Bcc and file copies, and designating what +mail should be copied. How should "outgoing" be defined? Implementing it is +easy once the configuration is designed. -

    Redhat 6.2 Requirements

    - -If you are running Redhat 6.2, the distributed version of sendmail -does not enable libmilter. You can download the Redhat 7.2 sendmail.spec -modified to compile on RedHat 6.2: - -sendmail-rhmilter.spec. The -SRPM for sendmail-8.11.6 is available from -Redhat under - -Errata for RH6.2. But that doesn't include the latest security -patches since RH6.2 is no longer supported. -

    -If y'all trust me, you can pick up source and binary sendmail RPMs for RH6.2 -from my linux downloads directory. -The lastest RPMs were built by taking a RH7.2 SRPMS and removing some -RPM features from the spec file that RH6.2 doesn't support, then -recompiling on RH6.2. You can check this by installing the RH7.2 SRPM, -then diffing my sendmail.spec with theirs. Then run -"rpm -bb sendmail-rhmilter.spec" when you are satisfied. -

    -If you have installed python2, and want -python-milter to use python2, add python=python2 to setup.cfg -and build with python2 setup.py bdist_rpm. -You'll need to install the sendmail-devel package to compile milter.


    - [ Valid HTML 3.2! ] + [ Valid HTML 3.2! ] - [ Powered By Red Hat Linux ] + [ Powered By Red Hat Linux ]

    - - diff --git a/policy.html b/doc/policy.ht similarity index 100% rename from policy.html rename to doc/policy.ht diff --git a/doc/python55.gif b/doc/python55.gif new file mode 100644 index 0000000000000000000000000000000000000000..b7c0b9d59e1b7cf6e6216a9e664a0099c11e686f GIT binary patch literal 2723 zcmZ?wbhEHb)Mqef_|Cxa|NsB*-@m_q|Ni;&=lAa2yLRo`xpU`^9Xqyn@7}Fjx2|2g zcInckbLPyMGG$6nPftrrOLcX1adB~Wc6M@da#U1QP*9MUmzR^1lclAlp`oFsrlz8z zqJ)HmfPer82M5Hsy<4}!^+PmA1qCHVMm84}Ia*j~Dk@3{2xy3lgETNOIBF;a8YpOp z^DFSPTWTm~ds-$t8n#3_87PRaDGJOAbnHp;x;i;)Nm1b0?xgBKOHTuZVo$^FNQCD!&7PbrS-$qu@^q-sf3WO0z?-Pu`t znj^1HPRjN&Jl7M|9BFZ^B`DcRbMKVmt4pemPR`ofojj*F=r#Wy=meZCh&*~tzj*7G&R zM<*vOsS0dKa!U3xyt^c8Pj}>;BCo5nld2;vBONuiGzU(}aymCT>iLr7HC3L)frb_u z;!BDg_cVKEduq?p8Vcgy$0K4iq=4Po281!SHz-m#Cq|sfLAzmhq~3d969axS6eEv1HZ?AH~lnWW2A*f6$R zmX{QHdx|P@$P%`5NAMOe4xWeDKU>3%CRgH+*DRt#xf|ism7hz$W-&J zMzBq_x@loE>s+D#CJmNG4HvsKmP|?FcI3=yU}sqQ;6s!!!=6Mx#*It?7bEn1KizYb zol)#8Rq|kw!zO0m1iwl~rXO7#%$y$>wrTWk=#=c5pyVZ0mvf=lQYz;%ula=;hYyA% z&N#>+_N?TChCfR~mY-x)MB+K_XEv98*>BvizRG&uA~?`k_JW|B#Cp%b7E6JWR6d~& z3BxJz(+whoxSuUp#Hp4YFtJm>P2>;gXCUXZ6Catyc4-vOS91ICfLT(! z`=E!CIZsmuZ{h;QqY_0YI6Q@B-(hHzaPxS`=s4+=V4KLZH;*{@i@rDH=)!Cg7cITS|*mu^ouyQiP^J+O<;Ov@oBL{M~$MJP~(T_KvlMI z5ss&#vJ+2;2MZW>aCiC$wn>D9FiHFGn4#<whqbGX%C; z{7GzP_7PkA#DUGZ=1}AnK@Zpe+ZJ>&ho*>DUTC&7o1nw@W)X+0z+n|X!!8-FCCO_l zTE#^Kms_bE=$c?9p>S$J2Se^71%--Mi31K?L01+qzcoG{v(KT+WX>a3HqV1go~&s4 z8`{rNl(D!WZev4Zz=ReC0S3mV8+KfJNdnAL7gR(9+4(aR7@HLn9Mc}NdT^akO`74w z-nOA#Lnf(Nb)mECx~nUhIux*+b_j5d>HjH2-~n1zxp4qcnkaN?DT zgLv@*7L~dL){q&>T3>IuxvmT3%?@Ce5!Gzh?)t!LDxoNpd~%6P&{cNvh(ptSq2DjPkoXk zA!QJ$I%Pqt*#t)3jovPzGLDu8Vn>8$Hn4DuDYE+M9O7m%KCbcOL5sS}L&2HCLK3GO z*gXv%31$UIKRHv_DOaGNwC%wWnYaYj03SyCwJTh-uUu$VTEWOUCBs?z!Ue8kpGI~! zgC@m88>a6vOyZmNSlE$IbGb@OBAecYR^=NGY%qV?j0h`;M0|Kre4j)+afXzHWlP#yA zMPZS8o9m2&GKm389WvTGjAk&WK65xCD3Zvh_CMmGpo2o%&8Q1pmMts2%{dNBs!VJ# zZ9ACi@!_t>ih!$ya~H5JED)64@PWD5#fh&=qghg8Bb#SSBYWZv7H*b@Yyk{R0yYxN z(mf2^3N3m(S5uj)Z#-ynQs86Q%ycH=#RfJn4o2>27mg~QFyPR>;2@B2!BzEILW|)S z2HunzO^TmxG0W^=5VH$tQ987s&8tO`?`Vjazjz{tlgL8Rpce-v*dAI1uzX;3oN(`X z(*jm+kL60q9j`@J9b+++c*OQ>#sSB)U?De`Ca;#MeyS25W3?=lIPE-Q)A$To*(M$2 zwG22S-nXDNd0~oJnvt-q%|`CTNs64=4o#W{jh*pYi|n}~EDi}3%w{>=;aKZ)ho4ic ziFI$5qleT!ALR`f*n$-n3Z)e^N?i~*ps;;C1GhzlD~n>g^c@HBU8w@h=Y$0q6#sMk zIy$>M=jSP~FbfzmFfcHN7iE@|q~<9kRVui9x;f|Pm8BMyq!uX{=^5*pE99pscqQg3 P7+LBl7+PAIFjxZsrd{}U literal 0 HcmV?d00001 diff --git a/doc/requirements.ht b/doc/requirements.ht new file mode 100644 index 0000000..d590f6b --- /dev/null +++ b/doc/requirements.ht @@ -0,0 +1,92 @@ +

    Requirements

    + + +
  • While the miltermodule will work with python 1.5, you probably +want to use python 2.0 or better. The python code uses a number of +python 2 features. The email support requires python 2.4. +
  • Python must be configured with thread support. This is because +sendmail's libmilter requires thread support. +
  • You must compile sendmail with libmilter enabled. In versions of +sendmail prior to 8.12 libmilter is marked FFR (For Future Release) and +is not installed by default. +Sendmail 8.12 still does not enable libmilter by default. You must +explicitly select the "MILTER" option when compiling. +
  • Python milter has been tested against sendmail-8.11 and sendmail-8.12. +
  • Python milter must be compiled for the specific version of sendmail +it will run with. (Since the result is dynamically loaded, there could +conceivably be multiple versions available and selected at startup - but +that will have to wait.) This situation may only exist for sendmail +versions prior to 8.12. The protocol seems designed for backward +compatibility - and 8.12 is the first official milter release. +
  • Mea Culpa! After reading the Python Style guide, I realize that +my Python code is not up to snuff. Apparently mixed tabs and spaces +are anathema to those using Windows editors, where tabs can be expanded using +any arbitrary algorithm. Other than that, my +intuition matched Guido's pretty well - although I like to indent by 2 +rather than 4. I will arrange to have tabs expanded to spaces when +exporting new versions. Until then, beware! +
  • + +

    AIX 4.1.5 Requirements

    +To create sendmail RPMs for AIX, you can download my AIX 4.1.5 spec files +for sendmail-8.11.5 +or sendmail-8.12.3. If you have +not already set it up, I use a dummy RPM package +to represent the stuff that comes with AIX. You might also want +my python-2.1.1 spec file for AIX. It +does not include Tk or curses modules, sorry. If y'all trust me, you can +download rpms for AIX 4.x from my AIX RPM directory. +

    +Sendmail-8.12 renames +libsmutil.a to libsm.a. Unfortunately, libsm.a is an important AIX system +shared library. Therefore, I rename libsm.a back to libsmutil.a for +AIX. This presents a problem for setup.py. + +

    RedHat 7.2 Requirements

    + +If you are running Redhat 7.2, the distributed version of sendmail +now enables libmilter by default. RedHat 7.2 bundles +the development libraries with the main sendmail package, so +there is no sendmail-devel package. However, they forgot to include the +headers! So you'll have to get the SRPM and modify it. I suggest +moving the static libs to a devel package and adding the headers. If +this is too much trouble, you can get the mfapi.h +header for sendmail-8.6.11 from here and manually install it as +/usr/include/libmilter/mfapi.h. +

    +If you do modify the SRPM, I suggest renaming libsmutil.a +to libsm.a - just like sendmail-8.12 will. If you manually install +mfapi.h or don't rename libsmutil.a, you'll +need to force libs = ["milter", "smutil"] in setup.py. +

    +If you have installed python2, and want +python-milter to use python2, add python=python2 to setup.cfg +and build with python2 setup.py bdist_rpm. + +

    Redhat 6.2 Requirements

    + +If you are running Redhat 6.2, the distributed version of sendmail +does not enable libmilter. You can download the Redhat 7.2 sendmail.spec +modified to compile on RedHat 6.2: + +sendmail-rhmilter.spec. The +SRPM for sendmail-8.11.6 is available from +Redhat under + +Errata for RH6.2. But that doesn't include the latest security +patches since RH6.2 is no longer supported. +

    +If y'all trust me, you can pick up source and binary sendmail RPMs for RH6.2 +from my linux downloads directory. +The lastest RPMs were built by taking a RH7.2 SRPMS and removing some +RPM features from the spec file that RH6.2 doesn't support, then +recompiling on RH6.2. You can check this by installing the RH7.2 SRPM, +then diffing my sendmail.spec with theirs. Then run +"rpm -bb sendmail-rhmilter.spec" when you are satisfied. +

    +If you have installed python2, and want +python-milter to use python2, add python=python2 to setup.cfg +and build with python2 setup.py bdist_rpm. +You'll need to install the sendmail-devel package to compile milter. +