mailfront-2.12/0000755000000000000000000000000013213777177010336 5ustar mailfront-2.12/ANNOUNCEMENT0000644000000000000000000001047712467132135012151 0ustar Version 2.12 of mailfront is now available at: http://untroubled.org/mailfront/ ------------------------------------------------------------------------------ Changes in version 2.12 - Added ability for rbl plugin to capture messages before rejecting them. - Fixed broken use of -lbg-sysdeps in modules. - Fixed missing plugin-rbl in installed image. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- mailfront Mail server network protocol front-ends Bruce Guenter Version 2.12 2015-02-12 This is mailfront, a package containing customizeable network front-ends for mail servers. It contains complete SMTP, QMQP, QMTP, and POP3 front-ends as well as an authentication module for IMAP. The mail delivery front-ends also contain internal address filtering features. Two SMTP back-ends are provided. One delivers mail to qmail-queue, mimicking most of the behavior of qmail-smtpd, with the addition of support for SMTP AUTH. The other rejects all SMTP commands if $SMTPREJECT is set, and execs its command line otherwise (in order to run the above program). A mailing list has been set up to discuss this and other packages. To subscribe, send an email to: bgware-subscribe@lists.untroubled.org A mailing list archive is available at: http://lists.untroubled.org/?list=bgware Development versions of mailfront are available at: https://github.com/bruceg/mailfront Requirements: - bglibs version 2.01 - cvm version 0.97 - Lua version 5 or later (optional) Installation: - Build the sources by running "make". - To build the Lua plugin, run "make lua". - After the package has been compiled, run "make install" as root. Configuration: - To take advantage of the SMTP AUTH features, make sure you have a CVM authentication program (some are included with the cvm package itself). - Run a CVM authentication module to provide the AUTH feature. Example: To run cvm-vmailmgr as a daemon: exec /usr/local/bin/softlimit -m 9000000 \ /usr/local/bin/cvm-vmailmgr /tmp/.cvm-vmailmgr 2>&1 - Configure your mail system to use the SMTP back-end with the appropriate environment variables. Example using tcpserver (highly recommended): #!/bin/sh QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` MAXSMTPD=`head -1 /var/qmail/control/concurrencyincoming` if [ -z "$QMAILDUID" -o -z "$NOFILESGID" -o -z "$MAXSMTPD" ]; then echo $0: QMAILDUID, NOFILESGID, or MAXSMTPD is unset exit 1 fi exec \ /usr/local/bin/envdir /etc/smtpfront \ /usr/local/bin/softlimit -m 2000000 \ /usr/local/bin/tcpserver -v -R -H \ -l "`head -1 /var/qmail/control/me`" -x /etc/tcp.smtp.cdb \ -c "$MAXSMTPD" -u "$QMAILDUID" -g "$NOFILESGID" 0 25 \ /usr/local/bin/smtpfront-qmail 2>&1 /etc/smtpfront/CVM_SASL_PLAIN: cvm-local:/tmp/.cvm-vmailmgr Example using xinetd with TCP Wrappers: /etc/xinetd.d/smtp: # default: on # description: smtp service smtp { disable = no flags = REUSE NAMEINARGS socket_type = stream protocol = tcp wait = no user = qmaild server = /usr/sbin/tcpd server_args = /var/qmail/bin/tcp-env -R /usr/local/sbin/smtpfront-wrapper log_on_success += USERID log_on_failure += USERID } /usr/local/sbin/smtpfront-wrapper: #!/bin/sh CVM_SASL_PLAIN=cvm-local:/tmp/.cvm-unix export CVM_SASL_PLAIN CVM_SASL_LOGIN=cvm-local:/tmp/.cvm-unix export CVM_SASL_LOGIN exec /usr/local/bin/smtpfront-qmail 2>> /tmp/smtpfront-errs.txt This project was initiated at FutureQuest, Inc. We are releasing it as an open-source project because we felt it would be useful to others, as well as to repay our debt of gratitude to the larger open-source community for the excellent packages we have enjoyed. For more details, you may contact FutureQuest, Inc. at: FutureQuest, Inc. PO BOX 623127 Oviedo FL 32762-3127 USA http://www.FutureQuest.net/ ossi@FutureQuest.net This package is Copyright(C) 2015 Bruce Guenter or FutureQuest, Inc., and may be copied according to the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 or a later version. A copy of this license is included with this package. This package comes with no warranty of any kind. mailfront-2.12/AUTOFILES0000644000000000000000000000015412467132135011601 0ustar AUTOFILES Makefile SRCFILES TARGETS conf-bin conf-cc conf-ccso conf-include conf-ld conf-qmail warn-auto.sh mailfront-2.12/COPYING0000644000000000000000000004311012467132135011355 0ustar GNU GENERAL PUBLIC LICENSE Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This General Public License applies to most of the Free Software Foundation's software and to any other program whose authors commit to using it. (Some other Free Software Foundation software is covered by the GNU Library General Public License instead.) You can apply it to your programs, too. When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. We protect your rights with two steps: (1) copyright the software, and (2) offer you this license which gives you legal permission to copy, distribute and/or modify the software. Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. The precise terms and conditions for copying, distribution and modification follow. GNU GENERAL PUBLIC LICENSE TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 0. This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" means either the Program or any derivative work under copyright law: that is to say, a work containing the Program or a portion of it, either verbatim or with modifications and/or translated into another language. (Hereinafter, translation is included without limitation in the term "modification".) Each licensee is addressed as "you". Activities other than copying, distribution and modification are not covered by this License; they are outside its scope. The act of running the Program is not restricted, and the output from the Program is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. 1. You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the notices that refer to this License and to the absence of any warranty; and give any other recipients of the Program a copy of this License along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. 2. You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: a) You must cause the modified files to carry prominent notices stating that you changed the files and the date of any change. b) You must cause any work that you distribute or publish, that in whole or in part contains or is derived from the Program or any part thereof, to be licensed as a whole at no charge to all third parties under the terms of this License. c) If the modified program normally reads commands interactively when run, you must cause it, when started running for such interactive use in the most ordinary way, to print or display an announcement including an appropriate copyright notice and a notice that there is no warranty (or else, saying that you provide a warranty) and that users may redistribute the program under these conditions, and telling the user how to view a copy of this License. (Exception: if the Program itself is interactive but does not normally print such an announcement, your work based on the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, and can be reasonably considered independent and separate works in themselves, then this License, and its terms, do not apply to those sections when you distribute them as separate works. But when you distribute the same sections as part of a whole which is a work based on the Program, the distribution of the whole must be on the terms of this License, whose permissions for other licensees extend to the entire whole, and thus to each and every part regardless of who wrote it. Thus, it is not the intent of this section to claim rights or contest your rights to work written entirely by you; rather, the intent is to exercise the right to control the distribution of derivative or collective works based on the Program. In addition, mere aggregation of another work not based on the Program with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. 3. You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: a) Accompany it with the complete corresponding machine-readable source code, which must be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, b) Accompany it with a written offer, valid for at least three years, to give any third party, for a charge no more than your cost of physically performing source distribution, a complete machine-readable copy of the corresponding source code, to be distributed under the terms of Sections 1 and 2 above on a medium customarily used for software interchange; or, c) Accompany it with the information you received as to the offer to distribute corresponding source code. (This alternative is allowed only for noncommercial distribution and only if you received the program in object code or executable form with such an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source code means all the source code for all modules it contains, plus any associated interface definition files, plus the scripts used to control compilation and installation of the executable. However, as a special exception, the source code distributed need not include anything that is normally distributed (in either source or binary form) with the major components (compiler, kernel, and so on) of the operating system on which the executable runs, unless that component itself accompanies the executable. If distribution of executable or object code is made by offering access to copy from a designated place, then offering equivalent access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. 4. You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. 5. You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by modifying or distributing the Program (or any work based on the Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. 6. Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. 7. If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not excuse you from the conditions of this License. If you cannot distribute so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not distribute the Program at all. For example, if a patent license would not permit royalty-free redistribution of the Program by all those who receive copies directly or indirectly through you, then the only way you could satisfy both it and this License would be to refrain entirely from distribution of the Program. If any portion of this section is held invalid or unenforceable under any particular circumstance, the balance of the section is intended to apply and the section as a whole is intended to apply in other circumstances. It is not the purpose of this section to induce you to infringe any patents or other property right claims or to contest validity of any such claims; this section has the sole purpose of protecting the integrity of the free software distribution system, which is implemented by public license practices. Many people have made generous contributions to the wide range of software distributed through that system in reliance on consistent application of that system; it is up to the author/donor to decide if he or she is willing to distribute software through any other system and a licensee cannot impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. 8. If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. 9. The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. Each version is given a distinguishing version number. If the Program specifies a version number of this License which applies to it and "any later version", you have the option of following the terms and conditions either of that version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. 10. If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. NO WARRANTY 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. END OF TERMS AND CONDITIONS How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. Copyright (C) This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Also add information on how to contact you by electronic and paper mail. If the program is interactive, make it output a short notice like this when it starts in an interactive mode: Gnomovision version 69, Copyright (C) year name of author Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. The hypothetical commands `show w' and `show c' should show the appropriate parts of the General Public License. Of course, the commands you use may be called something other than `show w' and `show c'; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: Yoyodyne, Inc., hereby disclaims all copyright interest in the program `Gnomovision' (which makes passes at compilers) written by James Hacker. , 1 April 1989 Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may consider it more useful to permit linking proprietary applications with the library. If this is what you want to do, use the GNU Library General Public License instead of this License. mailfront-2.12/ChangeLog0000644000000000000000000052723312467132135012111 0ustar ------------------------------------------------------------------------ r554 | bruce | 2007-09-27 15:23:24 -0600 (Thu, 27 Sep 2007) | 2 lines Changed paths: M /trunk/NEWS Added note about API documentation. ------------------------------------------------------------------------ r553 | bruce | 2007-09-27 15:20:52 -0600 (Thu, 27 Sep 2007) | 2 lines Changed paths: A /trunk/EXTRADIST M /trunk/makedist.py M /trunk/plugin-api.html D /trunk/plugin-prototype.c D /trunk/plugin-prototype.html A /trunk/plugin-template.c (from /trunk/plugin-prototype.c:542) A /trunk/plugin-template.html (from /trunk/plugin-prototype.html:542) Small reorganization of the template plugin and links. ------------------------------------------------------------------------ r552 | bruce | 2007-09-27 14:19:06 -0600 (Thu, 27 Sep 2007) | 2 lines Changed paths: M /trunk/TODO M /trunk/mailfront.c M /trunk/plugin-api.html Made mailfront call the reset hooks early on message permanent errors. ------------------------------------------------------------------------ r551 | bruce | 2007-09-27 09:47:22 -0600 (Thu, 27 Sep 2007) | 2 lines Changed paths: M /trunk/TODO A /trunk/tests/plugin-qmail-validate Added tests for plugin-qmail-validate. ------------------------------------------------------------------------ r550 | bruce | 2007-09-27 09:16:21 -0600 (Thu, 27 Sep 2007) | 2 lines Changed paths: M /trunk/tests.inc Tweaked the tests to report unexpected startup messages. ------------------------------------------------------------------------ r549 | bruce | 2007-09-27 00:08:52 -0600 (Thu, 27 Sep 2007) | 2 lines Changed paths: M /trunk/tests/smtpfront-auth-login M /trunk/tests/smtpfront-auth-plain M /trunk/tests/smtpfront-require-auth Removed dependancy on qmail-validate in tests. ------------------------------------------------------------------------ r548 | bruce | 2007-09-27 00:01:29 -0600 (Thu, 27 Sep 2007) | 3 lines Changed paths: M /trunk/backend-echo.c Restored the ability of backend-echo.c to report data bytes when a temporary file is in use. ------------------------------------------------------------------------ r547 | bruce | 2007-09-26 15:47:16 -0600 (Wed, 26 Sep 2007) | 2 lines Changed paths: M /trunk/plugin-api.html Missed a paragraph in the API document. ------------------------------------------------------------------------ r546 | bruce | 2007-09-26 14:52:29 -0600 (Wed, 26 Sep 2007) | 3 lines Changed paths: M /trunk/mailfront.html A /trunk/plugin-api.html Wrote a plugin API document, moving some technical information out of the main page. ------------------------------------------------------------------------ r545 | bruce | 2007-09-25 15:38:33 -0600 (Tue, 25 Sep 2007) | 4 lines Changed paths: M /trunk/TODO M /trunk/backend-echo.c M /trunk/backend-qmail.c M /trunk/builtins.c A /trunk/mailfront-internal.h (from /trunk/mailfront.h:544) M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/modules.c M /trunk/plugin-add-received.c M /trunk/plugin-mailrules.c M /trunk/protocol-smtp.c M /trunk/session.c Moved all internal implementation declarations into their own header, and purged all modules of references to those internals (most notably direct access to the session structure). ------------------------------------------------------------------------ r544 | bruce | 2007-09-25 14:51:58 -0600 (Tue, 25 Sep 2007) | 4 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/modules.c Moved several global variables into the session structure. They have been added to the end of the structure to retain ABI compatibility with existing plugins. ------------------------------------------------------------------------ r543 | bruce | 2007-09-25 12:36:30 -0600 (Tue, 25 Sep 2007) | 3 lines Changed paths: M /trunk/plugin-add-received.html M /trunk/protocol-smtp.html Document use of ${PROTO}LOCALHOST (and others) in the SMTP protocol and the add-received plugin. ------------------------------------------------------------------------ r542 | bruce | 2007-09-24 17:20:01 -0600 (Mon, 24 Sep 2007) | 2 lines Changed paths: M /trunk/makedist.py A /trunk/plugin-prototype.c (from /trunk/plugin.c:534) A /trunk/plugin-prototype.html (from /trunk/plugin.html:534) D /trunk/plugin.c D /trunk/plugin.html Renamed the prototype to plugin-prototype.c and added it to the web site files. ------------------------------------------------------------------------ r541 | bruce | 2007-09-03 12:02:39 -0600 (Mon, 03 Sep 2007) | 2 lines Changed paths: M /trunk/NEWS M /trunk/plugin-clamav.c M /trunk/plugin-clamav.html Modified the ClamAV plugin to prefer $CLAMAV_* settings over $CLAMD_* ------------------------------------------------------------------------ r540 | bruce | 2007-01-22 15:38:27 -0600 (Mon, 22 Jan 2007) | 2 lines Changed paths: M /trunk/NEWS M /trunk/plugin-clamav.c M /trunk/plugin-clamav.html Added a maximum message size scanning limit to the clamav plugin. ------------------------------------------------------------------------ r539 | bruce | 2007-01-22 15:08:25 -0600 (Mon, 22 Jan 2007) | 2 lines Changed paths: M /trunk/NEWS M /trunk/plugin-clamav.c M /trunk/plugin-clamav.html Added a separate send timeout to the virus scanner. ------------------------------------------------------------------------ r538 | bruce | 2007-01-22 10:18:01 -0600 (Mon, 22 Jan 2007) | 3 lines Changed paths: M /trunk/NEWS M /trunk/plugin-clamav.c Fixed a bug in the ClamAV plugin with handling port numbers when using multiple IPs. ------------------------------------------------------------------------ r537 | bruce | 2007-01-22 10:13:00 -0600 (Mon, 22 Jan 2007) | 2 lines Changed paths: M /trunk/NEWS M /trunk/plugin-clamav.c M /trunk/plugin-clamav.html Added a separate connect timeout to the ClamAV plugin. ------------------------------------------------------------------------ r536 | bruce | 2007-01-04 15:27:37 -0600 (Thu, 04 Jan 2007) | 3 lines Changed paths: M /trunk/NEWS M /trunk/plugin-check-fqdn.c M /trunk/plugin-check-fqdn.html Modified the check-fqdn plugin to append $DEFAULTHOST and $DEFAULTDOMAIN to addresses if necessary. ------------------------------------------------------------------------ r535 | bruce | 2007-01-04 15:23:23 -0600 (Thu, 04 Jan 2007) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.c M /trunk/session.c Fixed the main mailfront program to clean up temporary files properly. ------------------------------------------------------------------------ r534 | bruce | 2006-12-18 18:05:49 -0600 (Mon, 18 Dec 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/protocol-smtp.c Modified the SMTP protocol module to export the SASL authentication information internally. ------------------------------------------------------------------------ r533 | bruce | 2006-12-18 17:23:51 -0600 (Mon, 18 Dec 2006) | 3 lines Changed paths: M /trunk/tests/pop3front-maildir-state Sort the results of find in a test to compensate for filesystems that record filenames out of order. ------------------------------------------------------------------------ r532 | bruce | 2006-12-18 16:53:26 -0600 (Mon, 18 Dec 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 1.11 ------------------------------------------------------------------------ r531 | bruce | 2006-11-15 15:43:25 -0600 (Wed, 15 Nov 2006) | 1 line Changed paths: A /tags/1.10 (from /trunk:530) Tagged version 1.10 ------------------------------------------------------------------------ r530 | bruce | 2006-11-15 15:27:30 -0600 (Wed, 15 Nov 2006) | 3 lines Changed paths: M /trunk/tests/plugin-reject M /trunk/tests/plugins-prepend M /trunk/tests/plugins-remove M /trunk/tests/rules-databytes M /trunk/tests/rules-databytes2 M /trunk/tests/smtpfront-databytes Adjusted tests to account for mailfront properly picking up ${PROTO}LOCALHOST now. ------------------------------------------------------------------------ r529 | bruce | 2006-11-12 23:06:50 -0600 (Sun, 12 Nov 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-maildir.c Fixed pop3front-maildir breakage on dietlibc/uClibc and empty maildirs. Thanks Wayne Marshall ------------------------------------------------------------------------ r528 | bruce | 2006-11-12 22:39:29 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/INSTHIER M /trunk/spec Added the header files to the installed image. ------------------------------------------------------------------------ r527 | bruce | 2006-11-12 21:59:55 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c M /trunk/pop3front-auth.c Fixed two more cases where the UCSPI-TCP protocol was assumed. ------------------------------------------------------------------------ r526 | bruce | 2006-11-12 21:58:48 -0600 (Sun, 12 Nov 2006) | 3 lines Changed paths: A /trunk/getprotoenv.c M /trunk/mailfront.h M /trunk/mailfront=x M /trunk/plugin-add-received.c M /trunk/protocol-smtp.c Made the getprotoenv function global, and use it in the SMTP protocol instead of only looking for $TCPLOCALHOST. ------------------------------------------------------------------------ r525 | bruce | 2006-11-12 15:20:01 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/plugin.c Added some comments to the prototype plugin file. ------------------------------------------------------------------------ r524 | bruce | 2006-11-12 15:11:02 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.html M /trunk/plugin-clamav.html Fixed up some documentation for the temporary file change. ------------------------------------------------------------------------ r523 | bruce | 2006-11-12 15:09:13 -0600 (Sun, 12 Nov 2006) | 3 lines Changed paths: M /trunk/mailfront.c M /trunk/tests/plugin-force-file Use $TMPDIR instead of $TMPPATH for the temporary file base path, as most other programs also use this variable. ------------------------------------------------------------------------ r522 | bruce | 2006-11-12 14:59:47 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/mailfront.html A /trunk/plugin-force-file.c A /trunk/plugin-force-file.html A /trunk/plugin-force-file=so A /trunk/tests/plugin-force-file Added a plugin to force creation of a temporary file. ------------------------------------------------------------------------ r521 | bruce | 2006-11-12 14:42:40 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/backend-echo.c M /trunk/backend-qmail.c M /trunk/mailfront.h M /trunk/modules.c M /trunk/plugin-add-received.c M /trunk/plugin-check-fqdn.c M /trunk/plugin-clamav.c M /trunk/plugin-counters.c M /trunk/plugin-cvm-validate.c M /trunk/plugin-mailrules.c M /trunk/plugin-patterns.c M /trunk/plugin-qmail-validate.c M /trunk/plugin-reject.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c M /trunk/plugin.c M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/protocol-smtp.c Added a version number to the plugin ABI to prevent semantic mismatches. ------------------------------------------------------------------------ r520 | bruce | 2006-11-12 14:39:16 -0600 (Sun, 12 Nov 2006) | 2 lines Changed paths: M /trunk/backend-echo.c Adapted the backend to work both with and without a temporary file. ------------------------------------------------------------------------ r519 | bruce | 2006-11-11 22:35:27 -0600 (Sat, 11 Nov 2006) | 3 lines Changed paths: M /trunk/backend-qmail.c M /trunk/plugin-add-received.c Modified the qmail backend and the add-received plugin to work both with or without a temporary file. ------------------------------------------------------------------------ r518 | bruce | 2006-11-11 22:22:37 -0600 (Sat, 11 Nov 2006) | 2 lines Changed paths: M /trunk/mailfront.c Fixed some parts of the optional temporary file semantics. ------------------------------------------------------------------------ r517 | bruce | 2006-11-11 21:58:15 -0600 (Sat, 11 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/backend-qmail.c M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/modules.c M /trunk/plugin-clamav.c M /trunk/plugin.c Reverted change 513, making the temporary file optional again. ------------------------------------------------------------------------ r516 | bruce | 2006-11-09 00:22:57 -0600 (Thu, 09 Nov 2006) | 3 lines Changed paths: M /trunk/backend-echo.c Modified the echo backend to get its data from the temporary file and not use the data_block call. ------------------------------------------------------------------------ r515 | bruce | 2006-11-09 00:21:49 -0600 (Thu, 09 Nov 2006) | 3 lines Changed paths: M /trunk/plugin-add-received.c Modified the add-received plugin to write the headers directly to the temporary file instead of calling the data_block backend plugin. ------------------------------------------------------------------------ r514 | bruce | 2006-11-09 00:03:57 -0600 (Thu, 09 Nov 2006) | 2 lines Changed paths: M /trunk/backend-qmail.c M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-add-received.c M /trunk/plugin-counters.c M /trunk/plugin-patterns.c M /trunk/plugin.c Added the temporary file descriptor to the data_start plugin call. ------------------------------------------------------------------------ r513 | bruce | 2006-11-08 23:56:29 -0600 (Wed, 08 Nov 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/backend-qmail.c M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/modules.c M /trunk/plugin-clamav.c M /trunk/plugin.c Made the temporary file semantics mandatory and dropped the flags field from the plugins. ------------------------------------------------------------------------ r512 | bruce | 2006-11-08 23:06:47 -0600 (Wed, 08 Nov 2006) | 3 lines Changed paths: M /trunk/backend-qmail.c Modified the qmail backend to use the temporary file provided by mailfront instead of piping the message to qmail-queue piecemeal. ------------------------------------------------------------------------ r511 | bruce | 2006-11-08 16:37:54 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/INSTHIER Added the ClamAV plugin to the installer. ------------------------------------------------------------------------ r510 | bruce | 2006-11-08 16:29:00 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO A /trunk/plugin-clamav.c A /trunk/plugin-clamav.html A /trunk/plugin-clamav=so Added a ClamAV virus scanner plugin. ------------------------------------------------------------------------ r509 | bruce | 2006-11-08 15:45:16 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/mailfront.c Free the temporary file name string after it is used. ------------------------------------------------------------------------ r508 | bruce | 2006-11-08 15:00:14 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: A /trunk/plugin.c A /trunk/plugin.html Added the prototype plugin files to svn. ------------------------------------------------------------------------ r507 | bruce | 2006-11-08 14:51:39 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.c M /trunk/mailfront.h Added a flag bit to make the creation of a temporary file optional. ------------------------------------------------------------------------ r506 | bruce | 2006-11-08 14:47:46 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.h M /trunk/modules.c Added a flags word to the plugin API. ------------------------------------------------------------------------ r505 | bruce | 2006-11-08 14:41:28 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/backend-echo.c M /trunk/backend-qmail.c M /trunk/mailfront.c M /trunk/mailfront.h Modified the plugin API to save messages to a temporary file. ------------------------------------------------------------------------ r504 | bruce | 2006-11-08 14:22:17 -0600 (Wed, 08 Nov 2006) | 3 lines Changed paths: M /trunk/backend-echo.c M /trunk/backend-qmail.c M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/mailfront.html M /trunk/plugin-accept-recipient.html M /trunk/plugin-accept-sender.html M /trunk/plugin-accept.html M /trunk/plugin-add-received.html M /trunk/plugin-check-fqdn.html M /trunk/plugin-counters.html M /trunk/plugin-cvm-validate.html M /trunk/plugin-mailrules.html M /trunk/plugin-patterns.html M /trunk/plugin-qmail-validate.html M /trunk/plugin-reject.html M /trunk/plugin-relayclient.html M /trunk/plugin-require-auth.html M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/protocol-smtp.c Renamed the "data_end" event to "message_end", and added a plugin documentation note about it. ------------------------------------------------------------------------ r503 | bruce | 2006-11-08 13:57:03 -0600 (Wed, 08 Nov 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped up the version to 1.10 in anticipation of a plugin API change. ------------------------------------------------------------------------ r502 | bruce | 2006-09-07 15:49:14 -0600 (Thu, 07 Sep 2006) | 1 line Changed paths: A /tags/1.01 (from /trunk:501) Tagged version 1.01 ------------------------------------------------------------------------ r501 | bruce | 2006-09-07 14:12:45 -0600 (Thu, 07 Sep 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/plugin-counters.c M /trunk/tests/smtpfront-databytes Fixed a bug in the counters plugin that triggered a problem in the SMTP protocol when handling the SIZE=# parameter. ------------------------------------------------------------------------ r500 | bruce | 2006-09-01 23:29:12 -0600 (Fri, 01 Sep 2006) | 5 lines Changed paths: M /trunk/NEWS M /trunk/TODO M /trunk/backend-echo.c M /trunk/backend-qmail.c M /trunk/builtins.c M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-check-fqdn.c M /trunk/plugin-counters.c M /trunk/plugin-cvm-validate.c M /trunk/plugin-mailrules.c M /trunk/plugin-qmail-validate.c M /trunk/plugin-reject.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/protocol-smtp.c M /trunk/tests/plugin-reject Reverted revisions 496:HEAD. These changes were aimed at moving SMTP SIZE= handling into counters. This is effectively impossible since it needs to handle when a mail rule matches and sets the size, which short cuts the counters out. ------------------------------------------------------------------------ r499 | bruce | 2006-09-01 23:02:56 -0600 (Fri, 01 Sep 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/protocol-smtp.c Moved the find_param function from the SMTP protocol into mailfront.c ------------------------------------------------------------------------ r498 | bruce | 2006-09-01 22:48:10 -0600 (Fri, 01 Sep 2006) | 2 lines Changed paths: M /trunk/plugin-counters.c M /trunk/protocol-smtp.c M /trunk/tests/plugin-reject Moved generation of the SIZE=# EHLO response into plugin-counters ------------------------------------------------------------------------ r497 | bruce | 2006-09-01 22:36:40 -0600 (Fri, 01 Sep 2006) | 2 lines Changed paths: M /trunk/TODO M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/protocol-smtp.c Added SMTP EHLO response generation to handle_helo. ------------------------------------------------------------------------ r496 | bruce | 2006-08-30 23:53:00 -0600 (Wed, 30 Aug 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO M /trunk/backend-echo.c M /trunk/backend-qmail.c M /trunk/builtins.c M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-check-fqdn.c M /trunk/plugin-counters.c M /trunk/plugin-cvm-validate.c M /trunk/plugin-mailrules.c M /trunk/plugin-qmail-validate.c M /trunk/plugin-reject.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/protocol-smtp.c Modified the plugin API to pass down SMTP parameters. ------------------------------------------------------------------------ r495 | bruce | 2006-08-30 23:52:28 -0600 (Wed, 30 Aug 2006) | 2 lines Changed paths: A /trunk/tests/pop3front-auth-split Added a test for pop3front-auth splitting the username properly. ------------------------------------------------------------------------ r494 | bruce | 2006-08-30 21:40:53 -0600 (Wed, 30 Aug 2006) | 2 lines Changed paths: M /trunk/INSTHIER M /trunk/NEWS A /trunk/builtins.c M /trunk/mailfront.h M /trunk/mailfront=x M /trunk/modules.c D /trunk/plugin-accept-recipient.c D /trunk/plugin-accept-recipient=so D /trunk/plugin-accept-sender.c D /trunk/plugin-accept-sender=so D /trunk/plugin-accept.c D /trunk/plugin-accept=so Moved the accept* plugins to a list of builtins. ------------------------------------------------------------------------ r493 | bruce | 2006-08-30 11:11:04 -0600 (Wed, 30 Aug 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.html M /trunk/qmqpfront-qmail.sh M /trunk/qmtpfront-qmail.sh M /trunk/smtpfront-qmail.sh Reversed the order of cvm-validate and qmail-validate in the wrapper scripts (and documentation) due to the semantics of the two plugins. ------------------------------------------------------------------------ r492 | bruce | 2006-08-30 11:09:26 -0600 (Wed, 30 Aug 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 1.01 ------------------------------------------------------------------------ r491 | bruce | 2006-08-30 00:50:18 -0600 (Wed, 30 Aug 2006) | 2 lines Changed paths: A /trunk/tests/plugin-cvm-validate Added a test for the CVM validate plugin. ------------------------------------------------------------------------ r490 | bruce | 2006-08-29 09:39:00 -0600 (Tue, 29 Aug 2006) | 2 lines Changed paths: M /trunk/README.in Updated email address and version requirements in the README. ------------------------------------------------------------------------ r489 | bruce | 2006-08-29 09:38:07 -0600 (Tue, 29 Aug 2006) | 1 line Changed paths: A /tags/1.0 (from /trunk:488) Tagged version 1.0 ------------------------------------------------------------------------ r488 | bruce | 2006-08-29 09:27:19 -0600 (Tue, 29 Aug 2006) | 2 lines Changed paths: M /trunk/spec Updated the spec for the new conf files and requirements. ------------------------------------------------------------------------ r487 | bruce | 2006-08-29 09:24:19 -0600 (Tue, 29 Aug 2006) | 2 lines Changed paths: M /trunk/INSTHIER Add the missing accept*.so modules to the installed image. ------------------------------------------------------------------------ r486 | bruce | 2006-08-29 09:23:59 -0600 (Tue, 29 Aug 2006) | 3 lines Changed paths: M /trunk/protocol-smtp.c Moved variable declaration line above function statements to fix a problem with older compilers. ------------------------------------------------------------------------ r485 | bruce | 2006-08-29 09:22:34 -0600 (Tue, 29 Aug 2006) | 2 lines Changed paths: M /trunk/TODO Removed done item from the TODO list. ------------------------------------------------------------------------ r484 | bruce | 2006-08-28 21:25:25 -0600 (Mon, 28 Aug 2006) | 4 lines Changed paths: M /trunk/TODO M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-add-received.c M /trunk/plugin-counters.c M /trunk/plugin-mailrules.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c M /trunk/protocol-smtp.c M /trunk/session.c Converted all of the session numbers and strings to dictionaries to allow plugins to exchange data without needing to define new fields in the session structure. ------------------------------------------------------------------------ r483 | bruce | 2006-08-28 07:23:53 -0600 (Mon, 28 Aug 2006) | 2 lines Changed paths: M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c Converted all silent dies into a response function in QMQP and QMTP. ------------------------------------------------------------------------ r482 | bruce | 2006-08-25 18:09:34 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/TODO Updated the TODO list. ------------------------------------------------------------------------ r481 | bruce | 2006-08-25 18:04:45 -0600 (Fri, 25 Aug 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.html M /trunk/qmqpfront-qmail.sh M /trunk/qmtpfront-qmail.sh M /trunk/smtpfront-qmail.sh Modified the *front-qmail wrapper scripts to included the expected list of plugins, and modified the documentation to make note of this fact. ------------------------------------------------------------------------ r480 | bruce | 2006-08-25 17:51:30 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/modules.c Fixed a few bugs in the new plugin loading implementation. ------------------------------------------------------------------------ r479 | bruce | 2006-08-25 17:32:25 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.html M /trunk/modules.c A /trunk/tests/plugin-reject (from /trunk/tests/smtpfront-reject:467) A /trunk/tests/plugins-prepend A /trunk/tests/plugins-remove D /trunk/tests/smtpfront-reject Added support for prepending and removing plugins from the list. ------------------------------------------------------------------------ r478 | bruce | 2006-08-25 16:27:05 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/modules.c Tag all modules with their loaded name. ------------------------------------------------------------------------ r477 | bruce | 2006-08-25 15:04:01 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/protocol-smtp=so D /trunk/sasl-stub.c D /trunk/smtp-respond.c D /trunk/smtp.h Removed some unused files. ------------------------------------------------------------------------ r476 | bruce | 2006-08-25 14:59:34 -0600 (Fri, 25 Aug 2006) | 3 lines Changed paths: M /trunk/protocol-smtp.c Eliminate the use of the temporary response and string manipulations in the SMTP protocol. ------------------------------------------------------------------------ r475 | bruce | 2006-08-25 14:58:53 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.c Move output flushing after final into respond_line. ------------------------------------------------------------------------ r474 | bruce | 2006-08-25 14:51:27 -0600 (Fri, 25 Aug 2006) | 3 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/protocol-smtp.c M /trunk/qmtp-respond.c M /trunk/qmtp.h Moved all response line splitting code into mailfront, leaving the protocol modules to implement a single respond_line function. ------------------------------------------------------------------------ r473 | bruce | 2006-08-25 14:22:43 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/protocol-smtp.c M /trunk/smtp-respond.c Move logging of error messages into a common respond function. ------------------------------------------------------------------------ r472 | bruce | 2006-08-25 14:15:15 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/smtp-respond.c A further simplification of smtp_respond. ------------------------------------------------------------------------ r471 | bruce | 2006-08-25 14:13:56 -0600 (Fri, 25 Aug 2006) | 3 lines Changed paths: M /trunk/protocol-smtp.c M /trunk/smtp-respond.c M /trunk/smtp.h Dropped the smtp_respond_part function, resulting in a simplification of smtp_respond. ------------------------------------------------------------------------ r470 | bruce | 2006-08-25 13:48:12 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/protocol-smtp.c M /trunk/smtp-respond.c M /trunk/smtp.h Renamed the SMTP respond functions as well. ------------------------------------------------------------------------ r469 | bruce | 2006-08-25 13:44:23 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/protocol-qmqp.c M /trunk/protocol-qmtp.c M /trunk/qmtp-respond.c M /trunk/qmtp.h Greatly simplified (and renamed) the QM[QT]P respond function. ------------------------------------------------------------------------ r468 | bruce | 2006-08-25 12:54:05 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.c Moved the session_init call to a much less stupid location. ------------------------------------------------------------------------ r467 | bruce | 2006-08-25 12:21:44 -0600 (Fri, 25 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/session.c Added a (for now) trivial session initialization function. ------------------------------------------------------------------------ r466 | bruce | 2006-08-24 12:42:42 -0600 (Thu, 24 Aug 2006) | 3 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-add-received.c Moved several session variables used only in the add-received plugin into that plugin. ------------------------------------------------------------------------ r465 | bruce | 2006-08-23 14:59:43 -0600 (Wed, 23 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/protocol-smtp.c Added a plugin hook to capture the SMTP HELO/EHLO commands. ------------------------------------------------------------------------ r464 | bruce | 2006-08-03 14:54:36 -0600 (Thu, 03 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.html Reformatted the PLUGIN line. ------------------------------------------------------------------------ r463 | bruce | 2006-08-01 23:35:50 -0600 (Tue, 01 Aug 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/plugin-accept-recipient.c M /trunk/plugin-accept-sender.c M /trunk/plugin-accept.c M /trunk/plugin-add-received.c M /trunk/plugin-check-fqdn.c M /trunk/plugin-counters.c M /trunk/plugin-cvm-validate.c M /trunk/plugin-mailrules.c M /trunk/plugin-patterns.c M /trunk/plugin-qmail-validate.c M /trunk/plugin-reject.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c Removed the useless STRUCT_PLUGIN macro. ------------------------------------------------------------------------ r462 | bruce | 2006-08-01 23:31:30 -0600 (Tue, 01 Aug 2006) | 3 lines Changed paths: M /trunk/smtp-respond.c Fixed the SMTP response system to flush output only after all of a set of lines have been output, instead of after each line. ------------------------------------------------------------------------ r461 | bruce | 2006-07-31 21:46:54 -0600 (Mon, 31 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.c Fixed a couple corner cases in response handling. ------------------------------------------------------------------------ r460 | bruce | 2006-07-31 21:41:00 -0600 (Mon, 31 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.c Added missing call to backend->init ------------------------------------------------------------------------ r459 | bruce | 2006-07-31 15:47:52 -0600 (Mon, 31 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.c Make sure not to short-circuit calls to plugins' init and reset functions. ------------------------------------------------------------------------ r458 | bruce | 2006-07-31 09:57:32 -0600 (Mon, 31 Jul 2006) | 2 lines Changed paths: M /trunk/qmqpfront-echo.sh M /trunk/qmqpfront-qmail.sh M /trunk/qmtpfront-echo.sh M /trunk/qmtpfront-qmail.sh M /trunk/smtpfront-echo.sh M /trunk/smtpfront-qmail.sh Forgot the "$@" trailing argument to the commands. ------------------------------------------------------------------------ r457 | bruce | 2006-07-30 14:32:26 -0600 (Sun, 30 Jul 2006) | 2 lines Changed paths: M /trunk/TODO M /trunk/mailfront.html M /trunk/plugin-add-received.html M /trunk/plugin-counters.html A /trunk/plugin-cvm-validate.html A /trunk/plugin-mailrules.html M /trunk/plugin-patterns.html M /trunk/plugin-qmail-validate.html A /trunk/plugin-reject.html M /trunk/plugin-relayclient.html A /trunk/plugin-require-auth.html Finished the plugin documentation. ------------------------------------------------------------------------ r456 | bruce | 2006-07-30 13:43:29 -0600 (Sun, 30 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c M /trunk/protocol-qmqp.c Removed the session.relayclient variable. ------------------------------------------------------------------------ r455 | bruce | 2006-07-30 00:39:06 -0600 (Sun, 30 Jul 2006) | 2 lines Changed paths: M /trunk/TODO M /trunk/mailfront.html M /trunk/plugin-accept-recipient.html M /trunk/plugin-accept-sender.html M /trunk/plugin-accept.html A /trunk/plugin-add-received.html A /trunk/plugin-check-fqdn.html A /trunk/plugin-counters.html M /trunk/plugin-patterns.html M /trunk/plugin-qmail-validate.html M /trunk/plugin-relayclient.html More documentation reworking. ------------------------------------------------------------------------ r454 | bruce | 2006-07-29 22:58:38 -0600 (Sat, 29 Jul 2006) | 3 lines Changed paths: M /trunk/backend-echo.html M /trunk/backend-qmail.html M /trunk/mailfront.html M /trunk/plugin-accept-recipient.html M /trunk/plugin-accept-sender.html M /trunk/plugin-accept.html M /trunk/plugin-patterns.html M /trunk/plugin-qmail-validate.html M /trunk/plugin-relayclient.html M /trunk/protocol-qmqp.html M /trunk/protocol-qmtp.html M /trunk/protocol-smtp.html Renamed the titles in the HTML files to make it more obvious what the actual protocol/plugin/backend name is. ------------------------------------------------------------------------ r453 | bruce | 2006-07-29 22:54:30 -0600 (Sat, 29 Jul 2006) | 3 lines Changed paths: M /trunk/mailfront.html A /trunk/plugin-accept-recipient.html A /trunk/plugin-accept-sender.html A /trunk/plugin-accept.html Added documentation for the 3 new accept plugins, and a note about configuration to match the previous built-in configuration. ------------------------------------------------------------------------ r452 | bruce | 2006-07-29 22:47:20 -0600 (Sat, 29 Jul 2006) | 5 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.c M /trunk/mailfront.html M /trunk/plugin-qmail-validate.c M /trunk/tests/patterns-after M /trunk/tests/patterns-general M /trunk/tests/patterns-header M /trunk/tests/patterns-message M /trunk/tests/patterns-normal M /trunk/tests/received M /trunk/tests/rules-asterisk M /trunk/tests/rules-both M /trunk/tests/rules-cdb M /trunk/tests/rules-databytes M /trunk/tests/rules-databytes2 M /trunk/tests/rules-defaultmsg M /trunk/tests/rules-empty M /trunk/tests/rules-header-add M /trunk/tests/rules-list M /trunk/tests/rules-maxhops M /trunk/tests/rules-multiline M /trunk/tests/rules-negate M /trunk/tests/rules-noop M /trunk/tests/rules-rcptlist M /trunk/tests/rules-recip M /trunk/tests/rules-selector M /trunk/tests/rules-sender M /trunk/tests/smtpfront-auth-login M /trunk/tests/smtpfront-auth-plain M /trunk/tests/smtpfront-databytes M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests/smtpfront-maxrcpts M /trunk/tests/smtpfront-reject M /trunk/tests/smtpfront-require-auth M /trunk/tests.inc Modified mailfront to "fail closed". That is, if no plugin explicitly accepts a sender or recipient, mailfront considers it rejected. This prevents default configurations from becoming open relays, at the expense of slightly more confusing configuration. ------------------------------------------------------------------------ r451 | bruce | 2006-07-29 22:42:25 -0600 (Sat, 29 Jul 2006) | 3 lines Changed paths: A /trunk/plugin-accept-recipient.c (from /trunk/plugin-accept.c:448) A /trunk/plugin-accept-recipient=so (from /trunk/plugin-accept=so:448) A /trunk/plugin-accept-sender.c (from /trunk/plugin-accept.c:448) A /trunk/plugin-accept-sender=so (from /trunk/plugin-accept=so:448) Added trivial plugins to accept only the sender or recipient address, which will be needed for normal qmail installations. ------------------------------------------------------------------------ r450 | bruce | 2006-07-29 22:31:00 -0600 (Sat, 29 Jul 2006) | 2 lines Changed paths: M /trunk/INSTHIER A /trunk/qmqpfront-echo.sh A /trunk/qmqpfront-echo=sh A /trunk/qmqpfront-qmail.sh A /trunk/qmqpfront-qmail=sh A /trunk/qmtpfront-echo.sh A /trunk/qmtpfront-echo=sh A /trunk/qmtpfront-qmail.sh A /trunk/qmtpfront-qmail=sh A /trunk/smtpfront-echo.sh A /trunk/smtpfront-echo=sh A /trunk/smtpfront-qmail.sh A /trunk/smtpfront-qmail=sh Added wrapper shell scripts in place of the old program names. ------------------------------------------------------------------------ r449 | bruce | 2006-07-29 22:23:41 -0600 (Sat, 29 Jul 2006) | 3 lines Changed paths: M /trunk/plugin-reject=so M /trunk/plugin-require-auth=so The reject and require-auth plugins don't actually need libbg, so don't specify that library in the linkage. ------------------------------------------------------------------------ r448 | bruce | 2006-07-29 22:23:11 -0600 (Sat, 29 Jul 2006) | 2 lines Changed paths: A /trunk/plugin-accept.c A /trunk/plugin-accept=so Added a trivial 'accept' plugin, which accepts all senders and recipients. ------------------------------------------------------------------------ r447 | bruce | 2006-07-29 22:22:33 -0600 (Sat, 29 Jul 2006) | 4 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/mailfront.html M /trunk/modules.c D /trunk/tests/module-detect Simplified the command line handling in mailfront to always require protocol and backend names on the command line, and added the option to also specify plugins. ------------------------------------------------------------------------ r446 | bruce | 2006-07-29 22:09:59 -0600 (Sat, 29 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront=x A /trunk/modules.c (from /trunk/plugins.c:442) D /trunk/plugins.c Renamed plugins.c to modules.c ------------------------------------------------------------------------ r445 | bruce | 2006-07-29 21:49:38 -0600 (Sat, 29 Jul 2006) | 2 lines Changed paths: M /trunk/TODO A /trunk/backend-echo.html A /trunk/backend-qmail.html (from /trunk/qmail-backend.html:412) M /trunk/mailfront.html D /trunk/patterns.html A /trunk/plugin-patterns.html (from /trunk/patterns.html:412) A /trunk/plugin-qmail-validate.html (from /trunk/qmail-validate.html:412) A /trunk/plugin-relayclient.html A /trunk/protocol-qmqp.html A /trunk/protocol-qmtp.html A /trunk/protocol-smtp.html (from /trunk/smtpfront.html:412) D /trunk/qmail-backend.html D /trunk/qmail-validate.html D /trunk/smtpfront.html Started rewriting the documentation for the new modular architecture. ------------------------------------------------------------------------ r444 | bruce | 2006-07-29 21:49:14 -0600 (Sat, 29 Jul 2006) | 3 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 1.0, adding a note about the major changes in this release. ------------------------------------------------------------------------ r443 | bruce | 2006-07-29 21:48:39 -0600 (Sat, 29 Jul 2006) | 2 lines Changed paths: M /trunk/INSTHIER Fixed up installation instructions. ------------------------------------------------------------------------ r442 | bruce | 2006-07-28 16:49:40 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-add-received.c M /trunk/plugins.c M /trunk/protocol-smtp.c Moved the "protocol" and "backend" into the "session" structure. ------------------------------------------------------------------------ r441 | bruce | 2006-07-28 16:18:25 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/INSTHIER Add the protocol modules to INSTHIER and make all modules executable. ------------------------------------------------------------------------ r440 | bruce | 2006-07-28 13:29:29 -0600 (Fri, 28 Jul 2006) | 3 lines Changed paths: M /trunk/mailfront.c A /trunk/tests/module-detect Fixed up the logic for determining which protocol and backend based on command line arguments, and added a test for it. ------------------------------------------------------------------------ r439 | bruce | 2006-07-28 13:09:20 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h D /trunk/mailfront=l A /trunk/mailfront=x (from /trunk/mailfront=l:433) M /trunk/plugins.c A /trunk/protocol-qmqp.c (from /trunk/qmqp-mainloop.c:436) A /trunk/protocol-qmqp=so A /trunk/protocol-qmtp.c (from /trunk/qmtp-mainloop.c:436) A /trunk/protocol-qmtp=so A /trunk/protocol-smtp.c (from /trunk/smtp-commands.c:421) A /trunk/protocol-smtp=so D /trunk/qmqp-mainloop.c D /trunk/qmqp=l D /trunk/qmqpfront.c D /trunk/qmqpfront=x D /trunk/qmtp-mainloop.c M /trunk/qmtp-respond.c M /trunk/qmtp.h D /trunk/qmtp=l D /trunk/qmtpfront.c D /trunk/qmtpfront=x D /trunk/smtp-commands.c D /trunk/smtp-mainloop.c M /trunk/smtp-respond.c M /trunk/smtp.h D /trunk/smtp=l D /trunk/smtpfront.c D /trunk/smtpfront=x M /trunk/tests/qmqpfront-echo M /trunk/tests/qmtpfront-echo M /trunk/tests/received M /trunk/tests/rules-rcptlist M /trunk/tests/smtpfront-reject M /trunk/tests/smtpgreeting M /trunk/tests.inc Moved all protocols into dynamically loaded modules. ------------------------------------------------------------------------ r438 | bruce | 2006-07-28 11:57:28 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/tests/received Modified the received test to use spac-tests's loops. ------------------------------------------------------------------------ r437 | bruce | 2006-07-28 11:29:51 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/INSTHIER M /trunk/backend-echo.c A /trunk/backend-echo=so (from /trunk/plugin-counters=so:426) M /trunk/backend-qmail.c A /trunk/backend-qmail=so (from /trunk/plugin-counters=so:426) M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/plugin-add-received.c M /trunk/plugins.c D /trunk/qmail=l D /trunk/qmqpfront-echo.c D /trunk/qmqpfront-echo=x D /trunk/qmqpfront-qmail.c D /trunk/qmqpfront-qmail=x A /trunk/qmqpfront.c (from /trunk/qmqpfront-echo.c:435) A /trunk/qmqpfront=x (from /trunk/qmqpfront-echo=x:435) D /trunk/qmtpfront-echo.c D /trunk/qmtpfront-echo=x D /trunk/qmtpfront-qmail.c D /trunk/qmtpfront-qmail=x A /trunk/qmtpfront.c (from /trunk/qmtpfront-echo.c:435) A /trunk/qmtpfront=x (from /trunk/qmtpfront-echo=x:435) D /trunk/smtpfront-echo.c D /trunk/smtpfront-echo=x D /trunk/smtpfront-qmail.c D /trunk/smtpfront-qmail=x A /trunk/smtpfront.c (from /trunk/smtpfront-echo.c:435) A /trunk/smtpfront=x (from /trunk/smtpfront-echo=x:435) M /trunk/tests/qmqpfront-echo M /trunk/tests/qmtpfront-echo M /trunk/tests/received M /trunk/tests/rules-rcptlist M /trunk/tests/smtpfront-reject M /trunk/tests/smtpgreeting M /trunk/tests.inc Made all the backends dynamically loadable too. ------------------------------------------------------------------------ r436 | bruce | 2006-07-28 10:46:40 -0600 (Fri, 28 Jul 2006) | 4 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/smtp-mainloop.c Moved the duplicated call to handle_init out of the protocols and into mailfront.c. This breaks a protocol_init function out of protocol_mainloop. ------------------------------------------------------------------------ r435 | bruce | 2006-07-28 10:38:33 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.c M /trunk/mailfront.h M /trunk/qmqpfront-echo.c M /trunk/qmqpfront-echo=x M /trunk/qmqpfront-qmail.c M /trunk/qmqpfront-qmail=x M /trunk/qmtp-respond.c M /trunk/qmtpfront-echo.c M /trunk/qmtpfront-echo=x M /trunk/qmtpfront-qmail.c M /trunk/qmtpfront-qmail=x M /trunk/smtp-respond.c M /trunk/smtpfront-echo.c M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail.c M /trunk/smtpfront-qmail=x Moved main from individual files into mailfront.c ------------------------------------------------------------------------ r434 | bruce | 2006-07-28 10:30:32 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: D /trunk/backend-reject.c A /trunk/plugin-reject.c (from /trunk/backend-reject.c:432) A /trunk/plugin-reject=so (from /trunk/plugin-counters=so:426) D /trunk/qmqpfront-reject.c D /trunk/qmqpfront-reject=x D /trunk/qmtpfront-reject.c D /trunk/qmtpfront-reject=x D /trunk/smtpfront-reject.c D /trunk/smtpfront-reject=x M /trunk/tests/smtpfront-reject Moved the reject backend into a plugin. ------------------------------------------------------------------------ r433 | bruce | 2006-07-28 10:16:59 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: A /trunk/mailfront.c (from /trunk/std-handle.c:424) M /trunk/mailfront=l D /trunk/std-handle.c Renamed std-handle.c to mailfront.c ------------------------------------------------------------------------ r432 | bruce | 2006-07-28 10:14:21 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/backend-reject.c M /trunk/qmqpfront-reject.c M /trunk/qmtpfront-reject.c M /trunk/smtpfront-reject.c Moved the -reject main routine into backend-reject.c ------------------------------------------------------------------------ r431 | bruce | 2006-07-28 09:46:59 -0600 (Fri, 28 Jul 2006) | 3 lines Changed paths: M /trunk/plugin-require-auth.c M /trunk/std-handle.html M /trunk/tests/smtpfront-require-auth Since the require-auth plugin is optional, there is no need for it to check for $REQUIRE_AUTH. ------------------------------------------------------------------------ r430 | bruce | 2006-07-28 09:44:43 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/plugins.c M /trunk/qmqpfront-echo.c M /trunk/qmqpfront-qmail.c M /trunk/qmqpfront-reject.c M /trunk/qmtpfront-echo.c M /trunk/qmtpfront-qmail.c M /trunk/qmtpfront-reject.c M /trunk/smtpfront-echo.c M /trunk/smtpfront-qmail.c M /trunk/smtpfront-reject.c M /trunk/tests/smtpfront-auth-login M /trunk/tests/smtpfront-auth-plain M /trunk/tests/smtpfront-require-auth Removed the default plugins list. ------------------------------------------------------------------------ r429 | bruce | 2006-07-28 09:17:46 -0600 (Fri, 28 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/qmqp-mainloop.c M /trunk/qmqpfront-echo.c M /trunk/qmqpfront-qmail.c M /trunk/qmqpfront-reject.c M /trunk/qmtp-mainloop.c M /trunk/qmtpfront-echo.c M /trunk/qmtpfront-qmail.c M /trunk/qmtpfront-reject.c M /trunk/smtp-mainloop.c M /trunk/smtpfront-echo.c M /trunk/smtpfront-qmail.c M /trunk/smtpfront-reject.c Renamed all the protocol main loops to "protocol_mainloop" ------------------------------------------------------------------------ r428 | bruce | 2006-07-26 17:39:56 -0600 (Wed, 26 Jul 2006) | 3 lines Changed paths: M /trunk/plugins.c M /trunk/std-handle.html M /trunk/tests.inc Renamed $PLUGINS_PATH to $MODULE_PATH, as that path will also include frontends and backends. ------------------------------------------------------------------------ r427 | bruce | 2006-07-26 17:26:50 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: D /trunk/null-validate.c Removed unused null validation plugin. ------------------------------------------------------------------------ r426 | bruce | 2006-07-26 17:23:41 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/plugin-add-received=so M /trunk/plugin-check-fqdn=so M /trunk/plugin-counters=so M /trunk/plugin-cvm-validate=so M /trunk/plugin-mailrules=so M /trunk/plugin-patterns=so M /trunk/plugin-qmail-validate.c M /trunk/plugin-qmail-validate=so M /trunk/plugin-relayclient=so M /trunk/plugin-require-auth=so Removed the last vestiges of the PLUGIN macro. ------------------------------------------------------------------------ r425 | bruce | 2006-07-26 17:08:32 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/TODO A /trunk/backend-echo.c (from /trunk/echo-backend.c:412) A /trunk/backend-qmail.c (from /trunk/qmail-backend.c:412) A /trunk/backend-reject.c (from /trunk/reject-backend.c:412) D /trunk/echo-backend.c D /trunk/qmail-backend.c M /trunk/qmail=l M /trunk/qmqpfront-echo=x M /trunk/qmqpfront-reject=x M /trunk/qmtpfront-echo=x M /trunk/qmtpfront-reject=x D /trunk/reject-backend.c M /trunk/smtpfront-echo=x M /trunk/smtpfront-reject=x Renamed all backend code files to backend-*. ------------------------------------------------------------------------ r424 | bruce | 2006-07-26 17:03:05 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO M /trunk/mailfront.h M /trunk/mailfront=l M /trunk/plugins.c M /trunk/qmqpfront-echo.c M /trunk/qmqpfront-echo=x M /trunk/qmqpfront-qmail.c M /trunk/qmqpfront-reject.c M /trunk/qmtpfront-echo.c M /trunk/qmtpfront-echo=x M /trunk/qmtpfront-qmail.c M /trunk/qmtpfront-reject.c M /trunk/smtpfront-echo.c M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail.c M /trunk/smtpfront-reject.c M /trunk/std-handle.c M /trunk/tests/patterns-after M /trunk/tests/patterns-general M /trunk/tests/patterns-header M /trunk/tests/patterns-message M /trunk/tests/patterns-normal M /trunk/tests/qmqpfront-echo M /trunk/tests/qmtpfront-echo M /trunk/tests/received M /trunk/tests/rules-asterisk M /trunk/tests/rules-both M /trunk/tests/rules-cdb M /trunk/tests/rules-databytes M /trunk/tests/rules-databytes2 M /trunk/tests/rules-defaultmsg M /trunk/tests/rules-empty M /trunk/tests/rules-header-add M /trunk/tests/rules-list M /trunk/tests/rules-maxhops M /trunk/tests/rules-multiline M /trunk/tests/rules-negate M /trunk/tests/rules-noop M /trunk/tests/rules-rcptlist M /trunk/tests/rules-recip M /trunk/tests/rules-selector M /trunk/tests/rules-sender M /trunk/tests/smtpfront-bad-bounce M /trunk/tests/smtpfront-content M /trunk/tests/smtpfront-databytes M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests/smtpfront-maxrcpts M /trunk/tests.inc Switched all validation routines from hard-plugged to dynamically plugged. ------------------------------------------------------------------------ r423 | bruce | 2006-07-26 16:38:55 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/plugin-cvm-validate=so Added the missing -lcvm-v2client library needed for the cvm-validate plugin. ------------------------------------------------------------------------ r422 | bruce | 2006-07-26 16:36:34 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: A /trunk/conf-modules Added missing config file. ------------------------------------------------------------------------ r421 | bruce | 2006-07-26 16:36:06 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/session.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c Moved the global struct session into session.c ------------------------------------------------------------------------ r420 | bruce | 2006-07-26 16:24:44 -0600 (Wed, 26 Jul 2006) | 3 lines Changed paths: D /trunk/BIN A /trunk/INSTHIER (from /trunk/BIN:412) A /trunk/plugin-add-received=so A /trunk/plugin-check-fqdn=so A /trunk/plugin-counters=so A /trunk/plugin-cvm-validate=so A /trunk/plugin-mailrules=so A /trunk/plugin-patterns=so A /trunk/plugin-qmail-validate=so A /trunk/plugin-relayclient=so A /trunk/plugin-require-auth=so Compile all the plugins into shared objects, and install them in `conf-modules`. ------------------------------------------------------------------------ r419 | bruce | 2006-07-26 16:23:02 -0600 (Wed, 26 Jul 2006) | 3 lines Changed paths: M /trunk/plugin-qmail-validate.c Make sure conf_qmail is included statically if qmail-validate is being compiled as a plugin. ------------------------------------------------------------------------ r418 | bruce | 2006-07-26 16:22:16 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront=l Add plugins.o object to the mailfront library, missed in last commit. ------------------------------------------------------------------------ r417 | bruce | 2006-07-26 16:21:45 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.h A /trunk/plugins.c M /trunk/qmqpfront-echo=x M /trunk/qmqpfront-qmail=x M /trunk/qmqpfront-reject=x M /trunk/qmtpfront-echo=x M /trunk/qmtpfront-qmail=x M /trunk/qmtpfront-reject=x M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x M /trunk/std-handle.c M /trunk/std-handle.html Added support for loading plugins dynamically. ------------------------------------------------------------------------ r416 | bruce | 2006-07-26 15:35:33 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/plugin-add-received.c M /trunk/plugin-check-fqdn.c M /trunk/plugin-counters.c M /trunk/plugin-cvm-validate.c M /trunk/plugin-mailrules.c M /trunk/plugin-patterns.c M /trunk/plugin-qmail-validate.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c Added a macro for defining the struct plugin in plugins. ------------------------------------------------------------------------ r415 | bruce | 2006-07-26 15:19:08 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/null-validate.c M /trunk/plugin-add-received.c M /trunk/plugin-check-fqdn.c M /trunk/plugin-counters.c M /trunk/plugin-cvm-validate.c M /trunk/plugin-mailrules.c M /trunk/plugin-patterns.c M /trunk/plugin-qmail-validate.c M /trunk/plugin-relayclient.c M /trunk/plugin-require-auth.c M /trunk/std-handle.c Renamed "module" to "plugin" in all relevant files. ------------------------------------------------------------------------ r414 | bruce | 2006-07-26 15:16:11 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: D /trunk/add-received.c D /trunk/check-fqdn.c D /trunk/counters.c D /trunk/cvm-validate.c M /trunk/mailfront=l D /trunk/mailrules.c D /trunk/patterns.c A /trunk/plugin-add-received.c (from /trunk/add-received.c:412) A /trunk/plugin-check-fqdn.c (from /trunk/check-fqdn.c:412) A /trunk/plugin-counters.c (from /trunk/counters.c:412) A /trunk/plugin-cvm-validate.c (from /trunk/cvm-validate.c:412) A /trunk/plugin-mailrules.c (from /trunk/mailrules.c:412) A /trunk/plugin-patterns.c (from /trunk/patterns.c:412) A /trunk/plugin-qmail-validate.c (from /trunk/qmail-validate.c:412) A /trunk/plugin-relayclient.c (from /trunk/relayclient.c:412) A /trunk/plugin-require-auth.c (from /trunk/require-auth.c:412) D /trunk/qmail-validate.c M /trunk/qmail=l D /trunk/relayclient.c D /trunk/require-auth.c Renamed the module source files to add a "plugin-" prefix. ------------------------------------------------------------------------ r413 | bruce | 2006-07-26 11:28:49 -0600 (Wed, 26 Jul 2006) | 2 lines Changed paths: A /trunk/mailfront=l Added missing file. ------------------------------------------------------------------------ r412 | bruce | 2006-07-22 23:25:02 -0600 (Sat, 22 Jul 2006) | 2 lines Changed paths: M /trunk/TODO M /trunk/require-auth.c M /trunk/std-handle.c Modularization: final module (I hope) -- require-auth. ------------------------------------------------------------------------ r411 | bruce | 2006-07-22 23:18:51 -0600 (Sat, 22 Jul 2006) | 2 lines Changed paths: M /trunk/TODO M /trunk/add-received.c M /trunk/mailrules.c D /trunk/mailrules.h M /trunk/relayclient.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/std-handle.c Modularization: made mailrules a module. ------------------------------------------------------------------------ r410 | bruce | 2006-07-22 23:12:19 -0600 (Sat, 22 Jul 2006) | 3 lines Changed paths: M /trunk/counters.c M /trunk/mailfront.h M /trunk/mailrules.c M /trunk/std-handle.c Fixed up counter handling slightly, required to move things out of std-handle.c and still maintain proper semantics. ------------------------------------------------------------------------ r409 | bruce | 2006-07-22 22:43:57 -0600 (Sat, 22 Jul 2006) | 3 lines Changed paths: M /trunk/TODO A /trunk/check-fqdn.c A /trunk/counters.c M /trunk/mailfront.h M /trunk/patterns.c M /trunk/std-handle.c Modularization: made patterns a proper module and added a module for various counters -- too many recipients, hops, or bytes. ------------------------------------------------------------------------ r408 | bruce | 2006-07-22 10:40:50 -0600 (Sat, 22 Jul 2006) | 2 lines Changed paths: M /trunk/TODO M /trunk/add-received.c M /trunk/mailfront.h M /trunk/mailrules.c M /trunk/mailrules.h M /trunk/patterns.c M /trunk/qmail-backend.c M /trunk/qmqp=l M /trunk/qmqpfront-echo=x M /trunk/qmqpfront-qmail=x M /trunk/qmqpfront-reject=x M /trunk/qmtp=l M /trunk/qmtpfront-echo=x M /trunk/qmtpfront-qmail=x M /trunk/qmtpfront-reject=x M /trunk/relayclient.c A /trunk/session.c M /trunk/smtp=l M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x M /trunk/std-handle.c Moved rules-specific environment variables into session-generic code. ------------------------------------------------------------------------ r407 | bruce | 2006-07-22 10:12:06 -0600 (Sat, 22 Jul 2006) | 3 lines Changed paths: M /trunk/TODO M /trunk/add-received.c M /trunk/cvm-validate.c M /trunk/echo-backend.c M /trunk/mailfront.h M /trunk/qmail-backend.c M /trunk/qmail-validate.c M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/reject-backend.c M /trunk/relayclient.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/std-handle.c Moved the session parameter back into a global, simplifying a lot of function calls (and some code). ------------------------------------------------------------------------ r406 | bruce | 2006-07-22 09:42:23 -0600 (Sat, 22 Jul 2006) | 2 lines Changed paths: M /trunk/TODO A /trunk/add-received.c M /trunk/mailfront.h M /trunk/qmqp=l M /trunk/qmtp=l M /trunk/smtp=l M /trunk/std-handle.c Modularization: moved Received: header generation into a module. ------------------------------------------------------------------------ r405 | bruce | 2006-07-22 08:57:46 -0600 (Sat, 22 Jul 2006) | 2 lines Changed paths: M /trunk/relayclient.c M /trunk/std-handle.c Removed the extraneous authenticated logic out of std-handle.c ------------------------------------------------------------------------ r404 | bruce | 2006-07-21 18:03:23 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/qmqp=l M /trunk/qmtp=l A /trunk/relayclient.c A /trunk/require-auth.c M /trunk/smtp=l M /trunk/std-handle.c Modularization: moved relayclient + authenticated logic into a module. ------------------------------------------------------------------------ r403 | bruce | 2006-07-21 17:44:12 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/cvm-validate.c M /trunk/mailfront.h M /trunk/std-handle.c Modularization: moved CVM validation of recipients into a module. ------------------------------------------------------------------------ r402 | bruce | 2006-07-21 17:37:29 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/null-validate.c M /trunk/qmail-validate.c M /trunk/std-handle.c Modularization: made backend validation a module. ------------------------------------------------------------------------ r401 | bruce | 2006-07-21 17:19:28 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/std-handle.c Modularization: start of the dynamic module framework. ------------------------------------------------------------------------ r400 | bruce | 2006-07-21 16:42:34 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/reject-backend.c M /trunk/smtp-commands.c M /trunk/std-handle.c Modularization: eliminated globals maxdatabytes, maxhops, and maxrcpts. ------------------------------------------------------------------------ r399 | bruce | 2006-07-21 16:11:02 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/echo-backend.c M /trunk/mailfront.h M /trunk/qmail-backend.c M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/reject-backend.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/std-handle.c Modularization: moved the session from a global to a parameter. ------------------------------------------------------------------------ r398 | bruce | 2006-07-21 15:41:11 -0600 (Fri, 21 Jul 2006) | 3 lines Changed paths: M /trunk/mailfront.h M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/reject-backend.c M /trunk/smtp-commands.c M /trunk/std-handle.c More modularization: move the protocol and helo_domain parameters into the session structure. ------------------------------------------------------------------------ r397 | bruce | 2006-07-21 15:28:37 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/qmqp-mainloop.c M /trunk/reject-backend.c M /trunk/smtp-commands.c M /trunk/std-handle.c Starting modularization: move several globals into a session structure. ------------------------------------------------------------------------ r396 | bruce | 2006-07-21 15:28:12 -0600 (Fri, 21 Jul 2006) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.99 ------------------------------------------------------------------------ r395 | bruce | 2006-07-18 16:19:36 -0600 (Tue, 18 Jul 2006) | 1 line Changed paths: A /tags/0.98.1 (from /trunk:394) Tagged version 0.98.1 ------------------------------------------------------------------------ r394 | bruce | 2005-10-29 12:54:15 -0600 (Sat, 29 Oct 2005) | 4 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c Fixed the $REQUIRE_AUTH feature to properly check for $RELAYCLIENT being set by looking up $RELAYCLIENT before (and after) checking the sender against mail rules. ------------------------------------------------------------------------ r393 | bruce | 2005-10-29 12:48:10 -0600 (Sat, 29 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.98.1 ------------------------------------------------------------------------ r392 | bruce | 2005-10-26 11:34:57 -0600 (Wed, 26 Oct 2005) | 1 line Changed paths: A /tags/0.98 (from /trunk:391) Tagged version 0.98 ------------------------------------------------------------------------ r391 | bruce | 2005-10-26 11:29:55 -0600 (Wed, 26 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS Added note to NEWS about MSA support. ------------------------------------------------------------------------ r390 | bruce | 2005-10-26 11:22:24 -0600 (Wed, 26 Oct 2005) | 2 lines Changed paths: M /trunk/imapfront.html M /trunk/msa.html M /trunk/pop3front.html M /trunk/smtpfront.html Added links for all RFC references. ------------------------------------------------------------------------ r389 | bruce | 2005-10-25 22:43:43 -0600 (Tue, 25 Oct 2005) | 2 lines Changed paths: M /trunk/TODO Updated the TODO document. ------------------------------------------------------------------------ r388 | bruce | 2005-10-25 22:43:34 -0600 (Tue, 25 Oct 2005) | 2 lines Changed paths: A /trunk/tests/qmqpfront-echo A /trunk/tests/qmtpfront-echo Added simple tests for the QMQP/QMTP front-ends. ------------------------------------------------------------------------ r387 | bruce | 2005-10-25 17:26:31 -0600 (Tue, 25 Oct 2005) | 2 lines Changed paths: M /trunk/msa.html M /trunk/smtpfront.html Cleaned up the MSA documentation. ------------------------------------------------------------------------ r386 | bruce | 2005-10-25 17:20:37 -0600 (Tue, 25 Oct 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.h D /trunk/msa.c M /trunk/qmqp=l M /trunk/qmtp=l M /trunk/smtp=l M /trunk/std-handle.c M /trunk/std-handle.html M /trunk/tests/patterns-after M /trunk/tests/patterns-general M /trunk/tests/patterns-header M /trunk/tests/patterns-message M /trunk/tests/patterns-normal M /trunk/tests/received M /trunk/tests/rules-asterisk M /trunk/tests/rules-both M /trunk/tests/rules-cdb M /trunk/tests/rules-databytes M /trunk/tests/rules-databytes2 M /trunk/tests/rules-defaultmsg M /trunk/tests/rules-empty M /trunk/tests/rules-header-add M /trunk/tests/rules-list M /trunk/tests/rules-maxhops M /trunk/tests/rules-multiline M /trunk/tests/rules-negate M /trunk/tests/rules-noop M /trunk/tests/rules-rcptlist M /trunk/tests/rules-recip M /trunk/tests/rules-selector M /trunk/tests/rules-sender M /trunk/tests/smtpfront-auth-login M /trunk/tests/smtpfront-auth-plain M /trunk/tests/smtpfront-bad-bounce M /trunk/tests/smtpfront-content M /trunk/tests/smtpfront-databytes M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests/smtpfront-maxrcpts M /trunk/tests/smtpfront-quotes M /trunk/tests/smtpfront-require-auth Moved most of the MSA functionality into std-handle.c, making FQDNs unconditionally mandatory. ------------------------------------------------------------------------ r385 | bruce | 2005-10-25 00:14:06 -0600 (Tue, 25 Oct 2005) | 3 lines Changed paths: M /trunk/std-handle.html Fixed the std-handle HTML documentation to not mirror the SMTP front end documentation. ------------------------------------------------------------------------ r384 | bruce | 2005-10-24 15:17:43 -0600 (Mon, 24 Oct 2005) | 2 lines Changed paths: M /trunk/reject-backend.c M /trunk/responses.c M /trunk/responses.h M /trunk/std-handle.c Moved the duplicated number_ok and response_ok functions into responses.c ------------------------------------------------------------------------ r383 | bruce | 2005-10-24 15:09:30 -0600 (Mon, 24 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS A /trunk/qmqpfront-reject.c (from /trunk/smtpfront-reject.c:382) A /trunk/qmqpfront-reject=x (from /trunk/smtpfront-reject=x:382) A /trunk/qmtpfront-reject.c (from /trunk/smtpfront-reject.c:382) A /trunk/qmtpfront-reject=x (from /trunk/smtpfront-reject=x:382) M /trunk/reject-backend.c Added QMQP and QMTP "reject" front ends, for completeness. ------------------------------------------------------------------------ r382 | bruce | 2005-10-24 15:01:32 -0600 (Mon, 24 Oct 2005) | 2 lines Changed paths: A /trunk/reject-backend.c (from /trunk/smtpfront-reject.c:378) M /trunk/smtpfront-reject.c M /trunk/smtpfront-reject=x Broke apart the reject backend to make it useable for the other protocols. ------------------------------------------------------------------------ r381 | bruce | 2005-10-24 14:55:03 -0600 (Mon, 24 Oct 2005) | 3 lines Changed paths: M /trunk/smtpfront.html A /trunk/std-handle.html (from /trunk/smtpfront.html:376) Broke the SMTP documentation into its two logical parts, separating out the parts the belong to std-handle.c ------------------------------------------------------------------------ r380 | bruce | 2005-10-24 14:51:22 -0600 (Mon, 24 Oct 2005) | 2 lines Changed paths: M /trunk/qmail-validate.c M /trunk/qmqp=l M /trunk/qmqpfront-qmail=x M /trunk/qmtp=l M /trunk/qmtpfront-qmail=x M /trunk/smtp=l M /trunk/smtpfront-qmail=x M /trunk/std-handle.c Moved the CVM validation hook out of qmail-validate and into std-handle. ------------------------------------------------------------------------ r379 | bruce | 2005-10-24 14:49:57 -0600 (Mon, 24 Oct 2005) | 2 lines Changed paths: M /trunk/tests/smtpfront-require-auth Fixed up message for "authentication required". ------------------------------------------------------------------------ r378 | bruce | 2005-10-24 14:45:02 -0600 (Mon, 24 Oct 2005) | 2 lines Changed paths: M /trunk/smtpfront-reject.c Skip going through std-handle.c for the simple reject backend. ------------------------------------------------------------------------ r377 | bruce | 2005-10-22 00:20:20 -0600 (Sat, 22 Oct 2005) | 2 lines Changed paths: M /trunk/std-handle.c Fix up the SMTP code for the "authentication required" message. ------------------------------------------------------------------------ r376 | bruce | 2005-10-22 00:17:12 -0600 (Sat, 22 Oct 2005) | 4 lines Changed paths: M /trunk/NEWS M /trunk/smtpfront.html M /trunk/std-handle.c A /trunk/tests/smtpfront-require-auth Added support for rejecting all mail unless client is authenticated (either as a relay client or with SMTP authentication) if $REQUIRE_AUTH is set. ------------------------------------------------------------------------ r375 | bruce | 2005-10-21 16:04:51 -0600 (Fri, 21 Oct 2005) | 2 lines Changed paths: M /trunk/smtp-mainloop.c Added a missing extended mail system status code to a response here. ------------------------------------------------------------------------ r374 | bruce | 2005-10-20 23:01:40 -0600 (Thu, 20 Oct 2005) | 2 lines Changed paths: M /trunk/tests/patterns-after M /trunk/tests/patterns-general M /trunk/tests/patterns-header M /trunk/tests/patterns-message M /trunk/tests/patterns-normal M /trunk/tests/rules-databytes M /trunk/tests/rules-databytes2 M /trunk/tests/rules-header-add M /trunk/tests/rules-maxhops M /trunk/tests/smtpfront-auth-login M /trunk/tests/smtpfront-auth-plain M /trunk/tests/smtpfront-bad-bounce M /trunk/tests/smtpfront-content M /trunk/tests/smtpfront-databytes M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests/smtpfront-maxnotimpl M /trunk/tests/smtpfront-maxrcpts M /trunk/tests/smtpfront-reject Adjusted messages in the tests to match the current strings. ------------------------------------------------------------------------ r373 | bruce | 2005-10-20 22:55:56 -0600 (Thu, 20 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-maildir.c M /trunk/tests/pop3front-maildir-state Truncate UIDL responses to 70 characters as per RFC 1939. ------------------------------------------------------------------------ r372 | bruce | 2005-10-20 22:11:31 -0600 (Thu, 20 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/cvm-validate.c M /trunk/mailrules.c M /trunk/msa.c M /trunk/qmail-backend.c M /trunk/qmail-validate.c M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/responses.c M /trunk/responses.h M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/std-handle.c Added enhanced mail system status codes (RFC 1893/2034). ------------------------------------------------------------------------ r371 | bruce | 2005-10-20 14:15:47 -0600 (Thu, 20 Oct 2005) | 2 lines Changed paths: M /trunk/smtpfront-reject.c Eliminate unused variable warnings in smtpfront-reject.c ------------------------------------------------------------------------ r370 | bruce | 2005-10-19 22:56:28 -0600 (Wed, 19 Oct 2005) | 3 lines Changed paths: M /trunk/msa.c M /trunk/msa.html Added support for adding a default host and domain to addresses that are missing them in MSA mode. ------------------------------------------------------------------------ r369 | bruce | 2005-10-18 17:05:55 -0600 (Tue, 18 Oct 2005) | 2 lines Changed paths: M /trunk/echo-backend.c A /trunk/null-validate.c (from /trunk/echo-backend.c:342) M /trunk/qmqpfront-echo=x M /trunk/qmtpfront-echo=x M /trunk/smtpfront-echo=x Broke the stub validate routines out of echo-backend.c ------------------------------------------------------------------------ r368 | bruce | 2005-10-18 17:03:50 -0600 (Tue, 18 Oct 2005) | 3 lines Changed paths: M /trunk/mailfront.h A /trunk/msa.c A /trunk/msa.html M /trunk/qmqp=l M /trunk/qmtp=l M /trunk/smtp=l M /trunk/smtpfront.html M /trunk/std-handle.c Added the start of hooks and documentation on RFC 2476 "Message Submission Agent" mode. ------------------------------------------------------------------------ r367 | bruce | 2005-10-14 11:29:46 -0600 (Fri, 14 Oct 2005) | 3 lines Changed paths: M /trunk/mailrules.c M /trunk/responses.c Use the RESPONSE macro for all "const response resp_*" definitions to make searching the sources easier. ------------------------------------------------------------------------ r366 | bruce | 2005-10-13 14:04:20 -0600 (Thu, 13 Oct 2005) | 4 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c M /trunk/tests/smtpfront-bad-bounce Removed the "bounce must have a single recipient" rule, as it is currently causing more problems (with address checkers) than it is solving (spammers no longer use this technique). ------------------------------------------------------------------------ r365 | bruce | 2005-10-13 10:45:02 -0600 (Thu, 13 Oct 2005) | 2 lines Changed paths: M /trunk/qmail-backend.c Fixed an "assignment discards qualifiers" warning. ------------------------------------------------------------------------ r364 | bruce | 2005-10-13 10:43:50 -0600 (Thu, 13 Oct 2005) | 2 lines Changed paths: M /trunk/qmail-backend.c Tweaked permanent qmail-queue failure error message. ------------------------------------------------------------------------ r363 | bruce | 2005-10-12 16:38:23 -0600 (Wed, 12 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c A /trunk/tests/smtpfront-maxrcpts Fixed one-off bug in counting recipients for $MAXRCPTS. ------------------------------------------------------------------------ r362 | bruce | 2005-10-12 16:35:54 -0600 (Wed, 12 Oct 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.98. ------------------------------------------------------------------------ r361 | bruce | 2005-10-05 00:12:51 -0600 (Wed, 05 Oct 2005) | 1 line Changed paths: A /tags/0.97 (from /trunk:360) Tagged version 0.97 ------------------------------------------------------------------------ r360 | bruce | 2005-10-04 23:44:14 -0600 (Tue, 04 Oct 2005) | 2 lines Changed paths: M /trunk/spec Renamed "Copyright:" field in spec to "License:". ------------------------------------------------------------------------ r359 | bruce | 2005-10-04 11:37:31 -0600 (Tue, 04 Oct 2005) | 4 lines Changed paths: M /trunk/NEWS M /trunk/cvm-validate.c Fixed typo in the CVM lookup code that would prevent the proper operation of lookup secrets. Thanks Dale Woolridge ------------------------------------------------------------------------ r358 | bruce | 2005-09-22 16:12:14 -0600 (Thu, 22 Sep 2005) | 2 lines Changed paths: M /trunk/qmail-backend.c Fixed typo in a comparison operator. ------------------------------------------------------------------------ r357 | bruce | 2005-09-22 15:46:06 -0600 (Thu, 22 Sep 2005) | 3 lines Changed paths: M /trunk/qmail-backend.c M /trunk/qmail-backend.html Fixed up the qmail backend to properly follow qmail's semantics for qmail-queue exit codes from 1 to 10. ------------------------------------------------------------------------ r356 | bruce | 2005-09-22 15:14:52 -0600 (Thu, 22 Sep 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/qmail-backend.c M /trunk/qmail-backend.html Add support to the qmail backend for custom qmail-queue error messages taken from $QQERRMSG_#. ------------------------------------------------------------------------ r355 | bruce | 2005-08-12 14:27:15 -0600 (Fri, 12 Aug 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c M /trunk/pop3front-auth.c Clear session timeouts (via alarm) before executing authenticated commands in imapfront-auth and pop3front-auth. ------------------------------------------------------------------------ r354 | bruce | 2005-08-12 14:26:34 -0600 (Fri, 12 Aug 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.97 ------------------------------------------------------------------------ r353 | bruce | 2005-07-12 00:02:25 -0600 (Tue, 12 Jul 2005) | 1 line Changed paths: A /tags/0.96 (from /trunk:352) Tagged version 0.96 ------------------------------------------------------------------------ r352 | bruce | 2005-07-11 23:52:10 -0600 (Mon, 11 Jul 2005) | 2 lines Changed paths: M /trunk/spec Depend on the new bglibs that has the fixed glob functions. ------------------------------------------------------------------------ r351 | bruce | 2005-07-10 23:13:15 -0600 (Sun, 10 Jul 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c M /trunk/mailrules.html M /trunk/tests/rules-asterisk Switched Pattern matching from the simpler mechanism (originated in multilog) to standard shell glob. ------------------------------------------------------------------------ r350 | bruce | 2005-07-08 13:17:38 -0600 (Fri, 08 Jul 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/smtp-respond.c Fixed extern/static conflicting definition of "line" in smtp-respond.c. Thanks Gerrit Pape ------------------------------------------------------------------------ r349 | bruce | 2005-07-08 13:09:30 -0600 (Fri, 08 Jul 2005) | 2 lines Changed paths: M /trunk/TODO Replaced todo item about negation with one for selectors. ------------------------------------------------------------------------ r348 | bruce | 2005-07-08 12:26:22 -0600 (Fri, 08 Jul 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/sasl-stub.c A /trunk/tests/smtpfront-reject Fixed smtpfront-reject crashing on receipt of EHLO. Thanks Janos Farkas ------------------------------------------------------------------------ r347 | bruce | 2005-07-08 00:25:39 -0600 (Fri, 08 Jul 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/constants.h M /trunk/smtp-commands.c A /trunk/tests/smtpfront-quotes Fixed the SMTP front-end's inability to handle quoted or escaped characters, or to strip source routing addresses. ------------------------------------------------------------------------ r346 | bruce | 2005-07-08 00:19:44 -0600 (Fri, 08 Jul 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.96 ------------------------------------------------------------------------ r345 | bruce | 2005-06-10 15:12:59 -0600 (Fri, 10 Jun 2005) | 1 line Changed paths: A /tags/0.95 (from /trunk:344) Tagged version 0.95 ------------------------------------------------------------------------ r344 | bruce | 2005-06-10 15:08:45 -0600 (Fri, 10 Jun 2005) | 2 lines Changed paths: M /trunk/spec Fixed install stage in spec. ------------------------------------------------------------------------ r343 | bruce | 2005-06-10 13:39:20 -0600 (Fri, 10 Jun 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c A /trunk/tests/rules-databytes2 Fixed bug in handling of environment variables when applying multiple rules to the same message. ------------------------------------------------------------------------ r342 | bruce | 2005-06-10 12:23:48 -0600 (Fri, 10 Jun 2005) | 2 lines Changed paths: A /trunk/BIN M /trunk/README.in D /trunk/insthier.c M /trunk/spec Switch installation procedure to use new bg-installer from bglibs-1.022 ------------------------------------------------------------------------ r341 | bruce | 2005-06-09 23:31:00 -0600 (Thu, 09 Jun 2005) | 2 lines Changed paths: M /trunk/tests/patterns-after M /trunk/tests/patterns-general M /trunk/tests/patterns-header M /trunk/tests/patterns-message M /trunk/tests/patterns-normal M /trunk/tests/rules-asterisk M /trunk/tests/rules-both M /trunk/tests/rules-cdb M /trunk/tests/rules-databytes M /trunk/tests/rules-defaultmsg M /trunk/tests/rules-empty M /trunk/tests/rules-header-add M /trunk/tests/rules-list M /trunk/tests/rules-maxhops M /trunk/tests/rules-multiline M /trunk/tests/rules-negate M /trunk/tests/rules-noop M /trunk/tests/rules-recip M /trunk/tests/rules-selector M /trunk/tests/rules-sender M /trunk/tests/smtpfront-databytes M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests/smtpfront-maxnotimpl M /trunk/tests.inc Made the test scripts more portable (tested with ash). ------------------------------------------------------------------------ r340 | bruce | 2005-06-09 16:47:14 -0600 (Thu, 09 Jun 2005) | 3 lines Changed paths: M /trunk/tests.inc Fixed the selftests to use the invoking user's UID/GID. Thanks Janos Farkas ------------------------------------------------------------------------ r339 | bruce | 2005-06-09 16:46:01 -0600 (Thu, 09 Jun 2005) | 4 lines Changed paths: M /trunk/NEWS M /trunk/patterns.c M /trunk/tests/patterns-header Fixed bug in header pattern matching that made it only look at the first header line. Thanks Janos Farkas ------------------------------------------------------------------------ r338 | bruce | 2005-06-09 16:44:36 -0600 (Thu, 09 Jun 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.95 ------------------------------------------------------------------------ r337 | bruce | 2005-06-02 00:35:50 -0600 (Thu, 02 Jun 2005) | 1 line Changed paths: A /tags/0.94 (from /trunk:336) Tagged version 0.94 ------------------------------------------------------------------------ r336 | bruce | 2005-06-01 23:35:05 -0600 (Wed, 01 Jun 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/cvm-validate.c M /trunk/imapfront-auth.c M /trunk/imapfront-auth=x M /trunk/pop3front-auth.c M /trunk/pop3front-auth=x M /trunk/qmqpfront-echo=x M /trunk/qmqpfront-qmail=x M /trunk/qmtpfront-echo=x M /trunk/qmtpfront-qmail=x D /trunk/sasl-auth.c D /trunk/sasl-auth.h M /trunk/sasl-stub.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtp.h M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x Switched to CVM 2 support, with new SASL library etc. ------------------------------------------------------------------------ r335 | bruce | 2005-06-01 23:20:37 -0600 (Wed, 01 Jun 2005) | 2 lines Changed paths: M /trunk/tests.inc Use cvm-pwfile instead of a shell script for testing authentication. ------------------------------------------------------------------------ r334 | bruce | 2005-06-01 23:19:59 -0600 (Wed, 01 Jun 2005) | 2 lines Changed paths: M /trunk/makedist.py Put the ChangeLog on the web site. ------------------------------------------------------------------------ r333 | bruce | 2005-06-01 19:30:29 -0600 (Wed, 01 Jun 2005) | 2 lines Changed paths: M /trunk/README.in M /trunk/spec Document the current version requirements. ------------------------------------------------------------------------ r332 | bruce | 2005-05-30 23:45:10 -0600 (Mon, 30 May 2005) | 2 lines Changed paths: M /trunk/tests/rules-rcptlist Fixed up a test that was broken by recent changes to spac-tests ------------------------------------------------------------------------ r331 | bruce | 2005-05-30 23:13:09 -0600 (Mon, 30 May 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/patterns.c M /trunk/patterns.html A /trunk/tests/patterns-header Added support for restricting patterns to match only in headers. ------------------------------------------------------------------------ r330 | bruce | 2005-05-30 23:02:27 -0600 (Mon, 30 May 2005) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.94 ------------------------------------------------------------------------ r329 | bruce | 2005-04-21 11:21:00 -0600 (Thu, 21 Apr 2005) | 1 line Changed paths: A /tags/0.93 (from /trunk:328) Tagged version 0.93 ------------------------------------------------------------------------ r328 | bruce | 2005-04-21 11:02:44 -0600 (Thu, 21 Apr 2005) | 2 lines Changed paths: M /trunk/README.in Use the new @YEAR@ macro in the copyright statement. ------------------------------------------------------------------------ r327 | bruce | 2005-04-21 00:31:47 -0600 (Thu, 21 Apr 2005) | 3 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c M /trunk/imapfront.html M /trunk/pop3front-auth.c M /trunk/pop3front-maildir.c M /trunk/pop3front.html M /trunk/std-handle.c M /trunk/timeout.c Added seperate $AUTH_TIMEOUT and $AUTH_SESSION_TIMEOUT overrides for the authentication front-ends (imapfront-auth and pop3front-auth). ------------------------------------------------------------------------ r326 | bruce | 2004-12-04 11:59:06 -0600 (Sat, 04 Dec 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c A /trunk/tests/rules-rcptlist Fixed bug in handling multiple sender or recipient specific rules. ------------------------------------------------------------------------ r325 | bruce | 2004-12-04 11:58:13 -0600 (Sat, 04 Dec 2004) | 4 lines Changed paths: M /trunk/NEWS M /trunk/cvm-validate.c M /trunk/smtpfront.html Modified the CVM lookup secret handling to use $CVM_LOOKUP_SECRET just like the latest CVM code, falling back to $LOOKUP_SECRET if that isn't set. ------------------------------------------------------------------------ r324 | bruce | 2004-12-03 12:26:40 -0600 (Fri, 03 Dec 2004) | 5 lines Changed paths: M /trunk/NEWS M /trunk/patterns.c A /trunk/tests/patterns-general Fixed bug in pattern matching where the pattern was longer than the line that would other match. This relied on the erroneous assumption that patterns would always be shorter than the lines they were intended to match. ------------------------------------------------------------------------ r323 | bruce | 2004-12-03 10:56:18 -0600 (Fri, 03 Dec 2004) | 2 lines Changed paths: A /trunk/tests/rules-databytes (from /trunk/tests/smtpfront-databytes:320) Added test to ensure databytes is being obeyed. ------------------------------------------------------------------------ r322 | bruce | 2004-12-02 10:03:00 -0600 (Thu, 02 Dec 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c Fixed omission of not resetting maxdatabytes, which could be set by a rule, after checking for sender rules. ------------------------------------------------------------------------ r321 | bruce | 2004-12-02 10:01:36 -0600 (Thu, 02 Dec 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c Fixed bug in parsing the databytes column in mail rules. ------------------------------------------------------------------------ r320 | bruce | 2004-10-29 16:03:27 -0600 (Fri, 29 Oct 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.93 ------------------------------------------------------------------------ r319 | bruce | 2004-10-29 16:01:42 -0600 (Fri, 29 Oct 2004) | 1 line Changed paths: A /tags/0.92 (from /trunk:318) Tagged version 0.92 ------------------------------------------------------------------------ r318 | bruce | 2004-10-29 15:56:13 -0600 (Fri, 29 Oct 2004) | 2 lines Changed paths: M /trunk/tests.inc Use the newer "-n" format for head/tail. ------------------------------------------------------------------------ r317 | bruce | 2004-03-25 16:49:51 -0600 (Thu, 25 Mar 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c Fixed bug: Only set $MAILDIR in imapfront-auth if the CVM set it. Thanks Charlie Brady. ------------------------------------------------------------------------ r316 | bruce | 2004-03-11 12:20:12 -0600 (Thu, 11 Mar 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/patterns.c M /trunk/tests/patterns-normal Fixed bug in pattern handling that would cause a bogus "out of memory" error if the patterns file had a blank line. ------------------------------------------------------------------------ r315 | bruce | 2004-03-06 22:29:04 -0600 (Sat, 06 Mar 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/qmqp-mainloop.c Fixed bug in QMQP front-end that prevented it from accepting relayed messages (relayclient wasn't getting set properly). ------------------------------------------------------------------------ r314 | bruce | 2004-03-06 22:25:47 -0600 (Sat, 06 Mar 2004) | 2 lines Changed paths: M /trunk/insthier.c Added qmqpfront-echo and qmtpfront-echo test front-ends to insthier. ------------------------------------------------------------------------ r313 | bruce | 2004-03-06 22:25:00 -0600 (Sat, 06 Mar 2004) | 2 lines Changed paths: M /trunk/smtpfront-echo.c Fixed program name. ------------------------------------------------------------------------ r312 | bruce | 2004-03-06 22:24:47 -0600 (Sat, 06 Mar 2004) | 2 lines Changed paths: M /trunk/NEWS A /trunk/qmqpfront-echo.c (from /trunk/smtpfront-echo.c:293) A /trunk/qmqpfront-echo=x (from /trunk/smtpfront-echo=x:302) A /trunk/qmtpfront-echo.c (from /trunk/smtpfront-echo.c:293) A /trunk/qmtpfront-echo=x (from /trunk/smtpfront-echo=x:302) Added qmqpfront-echo and qmtpfront-echo test front-ends. ------------------------------------------------------------------------ r311 | bruce | 2004-03-06 22:12:36 -0600 (Sat, 06 Mar 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.92 ------------------------------------------------------------------------ r310 | bruce | 2004-03-05 17:14:35 -0600 (Fri, 05 Mar 2004) | 2 lines Changed paths: M /trunk/smtp-mainloop.c Show a message if the connection drops or times out during a command. ------------------------------------------------------------------------ r309 | bruce | 2004-03-05 16:47:38 -0600 (Fri, 05 Mar 2004) | 2 lines Changed paths: M /trunk/spec Depend on bglibs version 1.016 ------------------------------------------------------------------------ r308 | bruce | 2004-03-05 12:54:31 -0600 (Fri, 05 Mar 2004) | 1 line Changed paths: A /tags/0.91 (from /trunk:307) Tagged version 0.91 ------------------------------------------------------------------------ r307 | bruce | 2004-03-04 17:19:03 -0600 (Thu, 04 Mar 2004) | 2 lines Changed paths: M /trunk/TODO Added notes about better MIME patterns. ------------------------------------------------------------------------ r306 | bruce | 2004-03-04 17:08:43 -0600 (Thu, 04 Mar 2004) | 2 lines Changed paths: M /trunk/patterns.html Added new signature identified by James Triplett on the qmail mailing list. ------------------------------------------------------------------------ r305 | bruce | 2004-03-04 16:59:18 -0600 (Thu, 04 Mar 2004) | 2 lines Changed paths: M /trunk/NEWS Fixed typo in news about Received: header changes. ------------------------------------------------------------------------ r304 | bruce | 2004-03-04 16:58:20 -0600 (Thu, 04 Mar 2004) | 4 lines Changed paths: M /trunk/mailfront.h M /trunk/smtp-commands.c M /trunk/std-handle.c M /trunk/tests/received Try #3 at proper Received: header generation. This time, ${PROTO}LOCALIP and ${PROTO}REMOTEIP don't need to be set (which was the behavior before the last change). ------------------------------------------------------------------------ r303 | bruce | 2004-03-03 23:16:37 -0600 (Wed, 03 Mar 2004) | 3 lines Changed paths: M /trunk/echo-backend.c A /trunk/tests/received Dump the Received: header in the echo backend, so I can use it to test for proper header generation. ------------------------------------------------------------------------ r302 | bruce | 2004-03-03 23:16:00 -0600 (Wed, 03 Mar 2004) | 2 lines Changed paths: M /trunk/imapfront-auth=x M /trunk/pop3front-auth=x M /trunk/pop3front-maildir=x M /trunk/qmqpfront-qmail=x M /trunk/qmtpfront-qmail=x M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x M /trunk/spec Switched to bglibs 1.015 using -lbg. ------------------------------------------------------------------------ r301 | bruce | 2004-03-03 23:14:50 -0600 (Wed, 03 Mar 2004) | 3 lines Changed paths: M /trunk/std-handle.c M /trunk/tests/patterns-after M /trunk/tests/rules-header-add M /trunk/tests/rules-maxhops M /trunk/tests/smtpfront-bad-bounce M /trunk/tests/smtpfront-content M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received Fixed up handling of cases where ${PROTO}LOCALHOST or ${PROTO}REMOTEHOST is unset; require ${PROTO}LOCALIP and ${PROTO}REMOTEIP to be set. ------------------------------------------------------------------------ r300 | bruce | 2004-03-02 17:52:41 -0600 (Tue, 02 Mar 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c Fixed the generated Received: headers to always put the local host name in the comment if tcpserver looked it up. ------------------------------------------------------------------------ r299 | bruce | 2004-02-10 14:51:57 -0600 (Tue, 10 Feb 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c Explicitly set $MAILDIR in imapfront-auth for Courier-IMAP's imapd. Thanks Bernhard Graf ------------------------------------------------------------------------ r298 | bruce | 2004-02-10 13:14:39 -0600 (Tue, 10 Feb 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/cvm-validate.c Fixed a bug in the CVM lookup code that would cause failures if $LOOKUP_SECRET was not set. Thanks Bernhard Graf ------------------------------------------------------------------------ r297 | bruce | 2004-02-10 13:12:43 -0600 (Tue, 10 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.91 ------------------------------------------------------------------------ r296 | bruce | 2004-02-09 16:13:58 -0600 (Mon, 09 Feb 2004) | 1 line Changed paths: A /tags/0.90 (from /trunk:295) Tagged version 0.90 ------------------------------------------------------------------------ r295 | bruce | 2004-02-09 16:08:24 -0600 (Mon, 09 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c M /trunk/mailrules.html D /trunk/mailrules2.html A /trunk/tests/rules-negate Added support for negation of rule patterns. ------------------------------------------------------------------------ r294 | bruce | 2004-02-09 15:38:54 -0600 (Mon, 09 Feb 2004) | 2 lines Changed paths: M /trunk/tests/pop3front-auth M /trunk/tests/smtpgreeting M /trunk/tests.inc Use explicit paths when running programs. ------------------------------------------------------------------------ r293 | bruce | 2004-02-09 14:49:00 -0600 (Mon, 09 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c M /trunk/mailrules.html M /trunk/mailrules2.html A /trunk/tests/rules-selector Added support for explicit sender/recipient selection. ------------------------------------------------------------------------ r292 | bruce | 2004-02-09 13:49:06 -0600 (Mon, 09 Feb 2004) | 2 lines Changed paths: A /trunk/mailrules2.html Checked in interim mailrules v2 documentation. ------------------------------------------------------------------------ r291 | bruce | 2004-02-09 12:30:51 -0600 (Mon, 09 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/patterns.c M /trunk/tests/patterns-normal Fixed a bug in handling patterns that are not after a blank line. ------------------------------------------------------------------------ r290 | bruce | 2004-02-09 12:30:04 -0600 (Mon, 09 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.90 ------------------------------------------------------------------------ r289 | bruce | 2004-02-07 15:01:55 -0600 (Sat, 07 Feb 2004) | 1 line Changed paths: A /tags/0.89 (from /trunk:288) Tagged version 0.89 ------------------------------------------------------------------------ r288 | bruce | 2004-02-07 14:54:22 -0600 (Sat, 07 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/qmail-backend.c M /trunk/qmail-backend.html M /trunk/qmail-validate.c Allow overriding the qmail home directory with $QMAILHOME. ------------------------------------------------------------------------ r287 | bruce | 2004-02-07 14:48:55 -0600 (Sat, 07 Feb 2004) | 2 lines Changed paths: M /trunk/README.in Bumped up the copyright year. ------------------------------------------------------------------------ r286 | bruce | 2004-02-07 14:47:38 -0600 (Sat, 07 Feb 2004) | 2 lines Changed paths: M /trunk/qmail-backend.c Block SIGPIPE from killing the front-end if qmail-queue dies. ------------------------------------------------------------------------ r285 | bruce | 2004-02-06 14:05:08 -0600 (Fri, 06 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtpfront.html A /trunk/tests/smtpfront-maxnotimpl Drop connections after $MAXNOTIMPL unimplemented commands are given. ------------------------------------------------------------------------ r284 | bruce | 2004-02-06 12:40:28 -0600 (Fri, 06 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.89, fixing up the NEWS file. ------------------------------------------------------------------------ r283 | bruce | 2004-02-06 12:40:01 -0600 (Fri, 06 Feb 2004) | 1 line Changed paths: M /trunk/TODO ------------------------------------------------------------------------ r282 | bruce | 2004-02-06 12:27:58 -0600 (Fri, 06 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c M /trunk/mailrules.html A /trunk/tests/rules-noop Added a new "no-op" mail rule type. ------------------------------------------------------------------------ r281 | bruce | 2004-02-06 12:20:31 -0600 (Fri, 06 Feb 2004) | 2 lines Changed paths: M /trunk/mailrules.c Make namelen a pre-initialized constant. ------------------------------------------------------------------------ r280 | bruce | 2004-02-06 12:18:19 -0600 (Fri, 06 Feb 2004) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailfront.h A /trunk/patterns.c A /trunk/patterns.html M /trunk/qmqp=l M /trunk/qmtp=l M /trunk/smtp=l M /trunk/smtpfront.html M /trunk/std-handle.c A /trunk/tests/patterns-after A /trunk/tests/patterns-message A /trunk/tests/patterns-normal Added support for content pattern rejection. ------------------------------------------------------------------------ r279 | bruce | 2004-02-05 17:33:58 -0600 (Thu, 05 Feb 2004) | 2 lines Changed paths: M /trunk/std-handle.c Pre-initialize the value of maxdatabytes so SMTP can report it. ------------------------------------------------------------------------ r278 | bruce | 2004-02-05 17:28:55 -0600 (Thu, 05 Feb 2004) | 2 lines Changed paths: M /trunk/mailrules.c Fixed one (last?) bug in rules_getenvu. ------------------------------------------------------------------------ r277 | bruce | 2004-02-05 17:14:49 -0600 (Thu, 05 Feb 2004) | 3 lines Changed paths: M /trunk/std-handle.c Skip character-by-character processing of data bytes after the last header byte is processed. ------------------------------------------------------------------------ r276 | bruce | 2004-02-05 17:04:21 -0600 (Thu, 05 Feb 2004) | 3 lines Changed paths: M /trunk/std-handle.c Don't bother incrementing the line position if it's already past any possible useful values. ------------------------------------------------------------------------ r275 | bruce | 2004-02-05 15:33:51 -0600 (Thu, 05 Feb 2004) | 4 lines Changed paths: M /trunk/mailrules.c Fixed two bugs in the new rules_getenvu function: 1. missing external environment variables caused a seg fault 2. external environment variable values were ignored ------------------------------------------------------------------------ r274 | bruce | 2004-02-05 13:11:36 -0600 (Thu, 05 Feb 2004) | 3 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c Defer looking up $RELAYCLIENT and $MAXRCPTS so they can be set in mail rules; use the new rules_getenvu to look up $MAXHOPS. ------------------------------------------------------------------------ r273 | bruce | 2004-02-05 11:54:09 -0600 (Thu, 05 Feb 2004) | 3 lines Changed paths: M /trunk/mailrules.c M /trunk/mailrules.h M /trunk/std-handle.c Handle the databytes rules column by setting an internal environment variable. ------------------------------------------------------------------------ r272 | bruce | 2004-01-27 12:58:39 -0600 (Tue, 27 Jan 2004) | 2 lines Changed paths: M /trunk/smtpfront.html Fixed minor typo in description of databytes handling. ------------------------------------------------------------------------ r271 | bruce | 2004-01-05 23:08:42 -0600 (Mon, 05 Jan 2004) | 2 lines Changed paths: M /trunk/README.in Updated documentation to make note of seperation between cvm and bglibs. ------------------------------------------------------------------------ r270 | bruce | 2003-12-01 15:43:59 -0600 (Mon, 01 Dec 2003) | 1 line Changed paths: A /tags/0.88 (from /trunk:269) Tagged version 0.88 ------------------------------------------------------------------------ r269 | bruce | 2003-12-01 14:28:40 -0600 (Mon, 01 Dec 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO M /trunk/sasl-auth.c Export CVM data after authentication. ------------------------------------------------------------------------ r268 | bruce | 2003-12-01 13:38:52 -0600 (Mon, 01 Dec 2003) | 2 lines Changed paths: M /trunk/spec Depend on the latest version of bglibs. ------------------------------------------------------------------------ r267 | bruce | 2003-11-27 14:52:32 -0600 (Thu, 27 Nov 2003) | 2 lines Changed paths: M /trunk/TODO Fixed RFC numbers for enhanced status codes. ------------------------------------------------------------------------ r266 | bruce | 2003-11-27 14:52:15 -0600 (Thu, 27 Nov 2003) | 2 lines Changed paths: A /trunk/tests/imapfront-auth-login A /trunk/tests/imapfront-auth-plain Added tests for imapfront-auth AUTHENTICATE command. ------------------------------------------------------------------------ r265 | bruce | 2003-11-27 14:31:43 -0600 (Thu, 27 Nov 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c A /trunk/tests/imapfront-auth M /trunk/tests.inc Added support for IMAP string literals, and tests for imapfront-auth. ------------------------------------------------------------------------ r264 | bruce | 2003-11-26 17:00:52 -0600 (Wed, 26 Nov 2003) | 2 lines Changed paths: M /trunk/mailrules.html Fixed documentation on syntax of setting environment variables in rules. ------------------------------------------------------------------------ r263 | bruce | 2003-11-20 15:47:46 -0600 (Thu, 20 Nov 2003) | 2 lines Changed paths: M /trunk/spec Fixed typo: building depends on cvm-devel, not cvm. ------------------------------------------------------------------------ r262 | bruce | 2003-11-20 15:33:41 -0600 (Thu, 20 Nov 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c A /trunk/tests/rules-header-add A /trunk/tests/rules-maxhops Defer looking up $MAXHOPS and $HEADER_ADD and use rules_getenv instead. ------------------------------------------------------------------------ r261 | bruce | 2003-11-17 22:21:01 -0600 (Mon, 17 Nov 2003) | 2 lines Changed paths: M /trunk/spec Added dependancy notes regarding bglibs and cvm libraries. ------------------------------------------------------------------------ r260 | bruce | 2003-11-17 22:13:03 -0600 (Mon, 17 Nov 2003) | 2 lines Changed paths: M /trunk/std-handle.c Make rcpt_count unsigned, to match the values its compared against. ------------------------------------------------------------------------ r259 | bruce | 2003-11-17 22:12:07 -0600 (Mon, 17 Nov 2003) | 2 lines Changed paths: M /trunk/sasl-auth.c M /trunk/sasl-stub.c Fixup the include path for recent cvm libraries. ------------------------------------------------------------------------ r258 | bruce | 2003-11-17 21:07:40 -0600 (Mon, 17 Nov 2003) | 2 lines Changed paths: M /trunk/README.in M /trunk/makedist.py Converted lists.em.ca to lists.untroubled.org ------------------------------------------------------------------------ r257 | bruce | 2003-11-08 15:13:37 -0600 (Sat, 08 Nov 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtpfront.html M /trunk/std-handle.c Added MAXRCPTS patch from Marcelo Augusto . ------------------------------------------------------------------------ r256 | bruce | 2003-09-15 12:12:36 -0600 (Mon, 15 Sep 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c M /trunk/tests/rules-cdb M /trunk/tests/rules-list Fixed handling of "@domain" entries in mailrules lists and CDB files. ------------------------------------------------------------------------ r255 | bruce | 2003-09-15 11:42:15 -0600 (Mon, 15 Sep 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.88 ------------------------------------------------------------------------ r254 | bruce | 2003-08-28 15:52:15 -0600 (Thu, 28 Aug 2003) | 2 lines Changed paths: M /trunk/tests.inc Removed testing echo hook. ------------------------------------------------------------------------ r253 | bruce | 2003-08-28 15:50:49 -0600 (Thu, 28 Aug 2003) | 1 line Changed paths: A /tags/0.87 (from /trunk:252) Tagged version 0.87 ------------------------------------------------------------------------ r252 | bruce | 2003-08-28 14:04:30 -0600 (Thu, 28 Aug 2003) | 2 lines Changed paths: D /trunk/mailrules2.html A /trunk/mailrulesx.html (from /trunk/mailrules2.html:251) Renamed mailrules v2 to vX, as there may be an intermediate v2 step. ------------------------------------------------------------------------ r251 | bruce | 2003-08-27 18:09:22 -0600 (Wed, 27 Aug 2003) | 2 lines Changed paths: A /trunk/mailrules2.html Rewrote the mailrules v2 documentation to use a compiled file format. ------------------------------------------------------------------------ r250 | bruce | 2003-08-27 17:17:10 -0600 (Wed, 27 Aug 2003) | 2 lines Changed paths: M /trunk/tests/pop3front-auth-login M /trunk/tests/pop3front-auth-plain M /trunk/tests/pop3front-auth-userpass M /trunk/tests/smtpfront-auth-login M /trunk/tests/smtpfront-auth-plain M /trunk/tests.inc Use a locally generated CVM for testing. ------------------------------------------------------------------------ r249 | bruce | 2003-08-27 16:26:03 -0600 (Wed, 27 Aug 2003) | 2 lines Changed paths: M /trunk/tests/smtpfront-bad-bounce M /trunk/tests/smtpfront-content M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests.inc Really fixed the sizes, forgot to export the new variables. ------------------------------------------------------------------------ r248 | bruce | 2003-08-27 14:59:44 -0600 (Wed, 27 Aug 2003) | 2 lines Changed paths: M /trunk/tests/smtpfront-bad-bounce M /trunk/tests/smtpfront-content M /trunk/tests/smtpfront-looping-delivered-to M /trunk/tests/smtpfront-looping-received M /trunk/tests.inc Adjusted tests for new link protocol handling. ------------------------------------------------------------------------ r247 | bruce | 2003-08-26 17:51:50 -0600 (Tue, 26 Aug 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c Added the link protocol (ie TCP or TCP6) to the Received: header. ------------------------------------------------------------------------ r246 | bruce | 2003-08-26 16:50:03 -0600 (Tue, 26 Aug 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c Fixed the Received: header generation to match the syntax described in RFC 2821. ------------------------------------------------------------------------ r245 | bruce | 2003-07-17 13:50:15 -0600 (Thu, 17 Jul 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/std-handle.c A /trunk/tests/smtpfront-looping-delivered-to A /trunk/tests/smtpfront-looping-received Fixed a bug that prevented looping email detection from working. ------------------------------------------------------------------------ r244 | bruce | 2003-07-17 13:05:19 -0600 (Thu, 17 Jul 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version to 0.87 ------------------------------------------------------------------------ r243 | bruce | 2003-05-28 14:56:18 -0600 (Wed, 28 May 2003) | 1 line Changed paths: A /tags/0.86 (from /trunk:242) Tagged version 0.86 ------------------------------------------------------------------------ r242 | bruce | 2003-05-28 14:51:04 -0600 (Wed, 28 May 2003) | 2 lines Changed paths: M /trunk/TODO Added notes about address handling reorganization. ------------------------------------------------------------------------ r241 | bruce | 2003-05-28 14:48:10 -0600 (Wed, 28 May 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-commands.c M /trunk/smtpfront.html A /trunk/tests/smtpfront-databytes Added support for RFC 1870 ESMTP SIZE extension. ------------------------------------------------------------------------ r240 | bruce | 2003-05-28 14:05:25 -0600 (Wed, 28 May 2003) | 2 lines Changed paths: M /trunk/NEWS A /trunk/cvm-validate.c M /trunk/mailfront.h M /trunk/qmail-validate.c M /trunk/qmqpfront-qmail=x M /trunk/qmtpfront-qmail=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront.html Added CVM validation of recipient addresses. ------------------------------------------------------------------------ r239 | bruce | 2003-05-27 13:20:19 -0600 (Tue, 27 May 2003) | 2 lines Changed paths: M /trunk/README.in Added note about Subversion repository. ------------------------------------------------------------------------ r238 | bruce | 2003-05-27 13:19:15 -0600 (Tue, 27 May 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-commands.c Make SMTP front end log invalid commands. ------------------------------------------------------------------------ r237 | bruce | 2003-05-27 12:52:36 -0600 (Tue, 27 May 2003) | 2 lines Changed paths: M /trunk/qmtp-respond.c M /trunk/qmtp.h Moved the internal respond_* functions to static. ------------------------------------------------------------------------ r236 | bruce | 2003-05-22 22:51:18 -0600 (Thu, 22 May 2003) | 3 lines Changed paths: M /trunk/qmail-backend.c M /trunk/smtp-respond.c Restore former behavior of only logging errors (and qmail message acceptance data). ------------------------------------------------------------------------ r235 | bruce | 2003-05-22 22:39:12 -0600 (Thu, 22 May 2003) | 3 lines Changed paths: M /trunk/qmail-backend.c No longer need to log message delivery status, as the front-end code logs all responses. ------------------------------------------------------------------------ r234 | bruce | 2003-05-22 22:34:51 -0600 (Thu, 22 May 2003) | 2 lines Changed paths: M /trunk/smtp-respond.c M /trunk/smtp.h Restored the previously deleted logging messages. ------------------------------------------------------------------------ r233 | bruce | 2003-04-30 18:09:16 -0600 (Wed, 30 Apr 2003) | 3 lines Changed paths: M /trunk/README.in Added (tweaked) documentation additions from "Bryan Curnutt" ------------------------------------------------------------------------ r232 | bruce | 2003-03-24 14:35:51 -0600 (Mon, 24 Mar 2003) | 2 lines Changed paths: M /trunk/NEWS Added missing NEWS line item about $HEADER_ADD. ------------------------------------------------------------------------ r231 | bruce | 2003-03-24 14:35:02 -0600 (Mon, 24 Mar 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bump up version number. ------------------------------------------------------------------------ r230 | bruce | 2003-03-24 14:34:21 -0600 (Mon, 24 Mar 2003) | 2 lines Changed paths: M /trunk/smtpfront.html M /trunk/std-handle.c Allow for addition of user specified headers with $HEADER_ADD ------------------------------------------------------------------------ r229 | bruce | 2003-03-24 14:23:07 -0600 (Mon, 24 Mar 2003) | 2 lines Changed paths: M /trunk/smtp-respond.c Move the \n handling into the primary respond function. ------------------------------------------------------------------------ r228 | bruce | 2003-03-24 14:17:29 -0600 (Mon, 24 Mar 2003) | 3 lines Changed paths: M /trunk/echo-backend.c M /trunk/mailrules.c M /trunk/qmail-backend.c M /trunk/qmail-validate.c M /trunk/qmqp-mainloop.c M /trunk/qmtp-mainloop.c M /trunk/qmtp-respond.c M /trunk/responses.c M /trunk/responses.h M /trunk/smtp-commands.c M /trunk/smtp-respond.c M /trunk/smtpfront-reject.c Instead of using (inconvenient) pointers to link multi-line messages, just treat '\n' as a separator within the message itself. ------------------------------------------------------------------------ r227 | bruce | 2003-03-06 11:58:02 -0600 (Thu, 06 Mar 2003) | 2 lines Changed paths: M /trunk/README.in Added note about QMQP and QMTP front-ends. ------------------------------------------------------------------------ r226 | bruce | 2003-03-05 17:28:29 -0600 (Wed, 05 Mar 2003) | 1 line Changed paths: A /tags/0.85 (from /trunk:225) Tagged version 0.85 ------------------------------------------------------------------------ r225 | bruce | 2003-03-05 17:05:05 -0600 (Wed, 05 Mar 2003) | 2 lines Changed paths: M /trunk/TODO Added some things to do. ------------------------------------------------------------------------ r224 | bruce | 2003-03-05 14:57:18 -0600 (Wed, 05 Mar 2003) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtpfront.html Documented the fixup header. ------------------------------------------------------------------------ r223 | bruce | 2003-03-05 14:38:08 -0600 (Wed, 05 Mar 2003) | 2 lines Changed paths: M /trunk/qmtp-respond.c If multiple responses are give, separate them with LF chars. ------------------------------------------------------------------------ r222 | bruce | 2003-03-05 14:36:53 -0600 (Wed, 05 Mar 2003) | 4 lines Changed paths: M /trunk/qmqp=l M /trunk/qmtp=l M /trunk/smtp=l M /trunk/std-handle.c Added code to add a second "Received:" header before the normal one that can be used to fix up mismatches between incoming and outgoing hostnames or IPs. ------------------------------------------------------------------------ r221 | bruce | 2003-03-05 14:34:11 -0600 (Wed, 05 Mar 2003) | 2 lines Changed paths: M /trunk/responses.c M /trunk/responses.h Remove the unused response, and add a OOM one. ------------------------------------------------------------------------ r220 | bruce | 2003-03-05 14:32:55 -0600 (Wed, 05 Mar 2003) | 2 lines Changed paths: M /trunk/README.in Fix up the copyright years. ------------------------------------------------------------------------ r219 | bruce | 2003-03-04 11:33:59 -0600 (Tue, 04 Mar 2003) | 2 lines Changed paths: A /trunk/tests/smtpfront-content Test to make sure escaping on SMTP is handled correctly. ------------------------------------------------------------------------ r218 | bruce | 2003-03-04 11:33:38 -0600 (Tue, 04 Mar 2003) | 2 lines Changed paths: M /trunk/echo-backend.c Properly reset the number of bytes received. ------------------------------------------------------------------------ r217 | bruce | 2003-03-04 11:01:42 -0600 (Tue, 04 Mar 2003) | 2 lines Changed paths: M /trunk/smtp-commands.c Fixed broken leading period handling. ------------------------------------------------------------------------ r216 | bruce | 2003-03-04 01:01:59 -0600 (Tue, 04 Mar 2003) | 2 lines Changed paths: M /trunk/std-handle.c The second line uses two spaces, for continuity with qmail. ------------------------------------------------------------------------ r215 | bruce | 2003-03-04 00:55:23 -0600 (Tue, 04 Mar 2003) | 2 lines Changed paths: M /trunk/insthier.c Install the new QMQP and QMTP programs. ------------------------------------------------------------------------ r214 | bruce | 2003-03-03 17:49:14 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/std-handle.c Use str_cat#s functions to shrink code size. ------------------------------------------------------------------------ r213 | bruce | 2003-03-03 17:42:29 -0600 (Mon, 03 Mar 2003) | 4 lines Changed paths: M /trunk/std-handle.c Set up {local,remote}_{host,ip} at init time, instead of when building the Received: header; modularize building the date string into a seperate function. ------------------------------------------------------------------------ r212 | bruce | 2003-03-03 17:34:42 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/smtp-commands.c Removed extraneous reset that was blowing away SMTP response messages. ------------------------------------------------------------------------ r211 | bruce | 2003-03-03 16:51:13 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/qmtpfront-qmail.c Fixed typo: program name is qmtpfront-qmail, not smtpfront-qmail ------------------------------------------------------------------------ r210 | bruce | 2003-03-03 16:50:16 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/NEWS A /trunk/qmqp-mainloop.c A /trunk/qmqp=l A /trunk/qmqpfront-qmail.c A /trunk/qmqpfront-qmail=x Added QMQP front-end with qmail back-end. ------------------------------------------------------------------------ r209 | bruce | 2003-03-03 16:47:08 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/qmtp-mainloop.c Log the sender and recipient addresses. ------------------------------------------------------------------------ r208 | bruce | 2003-03-03 16:45:38 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/mailfront.h A /trunk/netstring.c M /trunk/qmtp-mainloop.c M /trunk/qmtp=l Moved the netstring reading code into a separate object. ------------------------------------------------------------------------ r207 | bruce | 2003-03-03 16:10:48 -0600 (Mon, 03 Mar 2003) | 2 lines Changed paths: M /trunk/imapfront-auth=x M /trunk/pop3front-auth=x M /trunk/pop3front-maildir=x M /trunk/qmtpfront-qmail=x M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x M /trunk/spec Switched to new (revised) bglibs library scheme. ------------------------------------------------------------------------ r206 | bruce | 2003-02-18 18:03:40 -0600 (Tue, 18 Feb 2003) | 1 line Changed paths: M /trunk/NEWS ------------------------------------------------------------------------ r205 | bruce | 2002-12-18 16:06:41 -0600 (Wed, 18 Dec 2002) | 2 lines Changed paths: M /trunk/std-handle.c Reject the message outright if more than one recipient was given. ------------------------------------------------------------------------ r204 | bruce | 2002-12-18 14:17:32 -0600 (Wed, 18 Dec 2002) | 2 lines Changed paths: M /trunk/NEWS Added comment about new bglibs usage. ------------------------------------------------------------------------ r203 | bruce | 2002-12-17 17:09:38 -0600 (Tue, 17 Dec 2002) | 2 lines Changed paths: M /trunk/imapfront-auth=x M /trunk/pop3front-auth=x M /trunk/pop3front-maildir=x M /trunk/qmtpfront-qmail=x M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x Switched to new bglibs library paths. ------------------------------------------------------------------------ r202 | bruce | 2002-12-17 17:08:51 -0600 (Tue, 17 Dec 2002) | 2 lines Changed paths: M /trunk/README.in Added installation notes. ------------------------------------------------------------------------ r201 | bruce | 2002-12-16 17:49:47 -0600 (Mon, 16 Dec 2002) | 2 lines Changed paths: M /trunk/imapfront-auth.c M /trunk/mailrules.c M /trunk/pop3front-maildir.c M /trunk/qmail-backend.c M /trunk/qmtp-mainloop.c M /trunk/qmtp-respond.c M /trunk/sasl-auth.c M /trunk/sasl-auth.h M /trunk/smtp-respond.c M /trunk/std-handle.c Renamed variables to eliminate global/local shadow declarations. ------------------------------------------------------------------------ r200 | bruce | 2002-12-16 17:27:34 -0600 (Mon, 16 Dec 2002) | 2 lines Changed paths: D /trunk/README A /trunk/README.in (from /trunk/README:196) Moved to a templated README system, generated by spac-dist. ------------------------------------------------------------------------ r199 | bruce | 2002-12-16 17:26:50 -0600 (Mon, 16 Dec 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped version from 0.82 to 0.85 (0.82 was not released). ------------------------------------------------------------------------ r198 | bruce | 2002-12-16 17:07:29 -0600 (Mon, 16 Dec 2002) | 2 lines Changed paths: D /trunk/README.CVS Removed extraneous CVS instructions. ------------------------------------------------------------------------ r197 | bruce | 2002-11-29 15:19:08 -0600 (Fri, 29 Nov 2002) | 2 lines Changed paths: M /trunk/std-handle.c Clarified the logic of handle_sender and handle_recipient. ------------------------------------------------------------------------ r196 | bruce | 2002-11-19 17:21:55 -0600 (Tue, 19 Nov 2002) | 1 line Changed paths: A /branches Created branches directory ------------------------------------------------------------------------ r195 | bruce | 2002-11-19 17:21:55 -0600 (Tue, 19 Nov 2002) | 1 line Changed paths: A /tags Created tags directory ------------------------------------------------------------------------ r194 | bruce | 2002-11-08 23:36:03 -0600 (Fri, 08 Nov 2002) | 4 lines Changed paths: M /trunk/echo-backend.c M /trunk/mailfront.h M /trunk/qmail-backend.c M /trunk/qmail-validate.c D /trunk/qmail.h M /trunk/qmtpfront-qmail.c M /trunk/smtpfront-qmail.c M /trunk/smtpfront-reject.c M /trunk/std-handle.c Renamed the qmail_ functions to standard backend_ naming. Removed the qmail.h header file. Added a call to backend_validate_init to std-handle.c. ------------------------------------------------------------------------ r193 | bruce | 2002-11-08 23:20:28 -0600 (Fri, 08 Nov 2002) | 2 lines Changed paths: M /trunk/qmtpfront-qmail.c M /trunk/smtpfront-qmail.c Removed duplicate relayclient and authenticated handling. ------------------------------------------------------------------------ r192 | bruce | 2002-11-08 23:03:40 -0600 (Fri, 08 Nov 2002) | 2 lines Changed paths: M /trunk/std-handle.c Fixed typo with maxdatabytes. ------------------------------------------------------------------------ r191 | bruce | 2002-11-08 23:03:22 -0600 (Fri, 08 Nov 2002) | 2 lines Changed paths: A /trunk/qmtpfront-qmail.c A /trunk/qmtpfront-qmail=x Added QMTP-qmail main routine. ------------------------------------------------------------------------ r190 | bruce | 2002-11-08 22:53:54 -0600 (Fri, 08 Nov 2002) | 5 lines Changed paths: M /trunk/echo-backend.c M /trunk/mailfront.h M /trunk/qmtp-mainloop.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtpfront-qmail.c M /trunk/smtpfront-reject.c M /trunk/std-handle.c Renamed handle and validate functions: handle_* => backend_handle_* validate_* => backend_validate_* std_handle_* => handle_* ------------------------------------------------------------------------ r189 | bruce | 2002-11-08 22:36:01 -0600 (Fri, 08 Nov 2002) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtp.h M /trunk/smtp=l Removed the duplicated code in std-handle.c ------------------------------------------------------------------------ r188 | bruce | 2002-11-08 22:35:35 -0600 (Fri, 08 Nov 2002) | 3 lines Changed paths: A /trunk/std-handle.c Pulled a lot of common code from the SMTP library into this shared module. ------------------------------------------------------------------------ r187 | bruce | 2002-11-08 22:34:33 -0600 (Fri, 08 Nov 2002) | 2 lines Changed paths: M /trunk/NEWS A /trunk/qmtp-mainloop.c A /trunk/qmtp-respond.c A /trunk/qmtp.h A /trunk/qmtp=l Added a QMTP back-end. ------------------------------------------------------------------------ r186 | bruce | 2002-11-07 19:42:05 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-commands.c Fixed internal variable transposition bug. ------------------------------------------------------------------------ r185 | bruce | 2002-11-07 19:41:51 -0600 (Thu, 07 Nov 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/VERSION Bumped up version. ------------------------------------------------------------------------ r184 | bruce | 2002-09-27 23:41:02 -0600 (Fri, 27 Sep 2002) | 2 lines Changed paths: M /trunk/README M /trunk/VERSION Bumped version to 0.81. ------------------------------------------------------------------------ r183 | bruce | 2002-09-25 17:10:10 -0600 (Wed, 25 Sep 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-commands.c Abort the DATA command immediately if the databytes limit is reached. ------------------------------------------------------------------------ r182 | bruce | 2002-09-25 17:08:57 -0600 (Wed, 25 Sep 2002) | 2 lines Changed paths: M /trunk/tests/rules-asterisk Test for "*" pattern matching "". ------------------------------------------------------------------------ r181 | bruce | 2002-09-25 17:00:10 -0600 (Wed, 25 Sep 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c Make the "*" pattern properly match all strings. ------------------------------------------------------------------------ r180 | bruce | 2002-09-25 16:53:02 -0600 (Wed, 25 Sep 2002) | 2 lines Changed paths: M /trunk/smtp-commands.c Remove extraneous reset of mail/rcpt state. ------------------------------------------------------------------------ r179 | bruce | 2002-09-25 16:51:48 -0600 (Wed, 25 Sep 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-commands.c Accept bounces after the first one by properly resetting state. ------------------------------------------------------------------------ r178 | bruce | 2002-09-25 16:49:50 -0600 (Wed, 25 Sep 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/mailrules.c Apply maxdatabytes even if $DATABYTES is not set. ------------------------------------------------------------------------ r177 | bruce | 2002-09-24 20:53:06 -0600 (Tue, 24 Sep 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/qmail-backend.c Fixed handling of environment variables in mail rules. ------------------------------------------------------------------------ r176 | bruce | 2002-09-17 19:29:32 -0600 (Tue, 17 Sep 2002) | 4 lines Changed paths: M /trunk/mailrules.c M /trunk/mailrules.h Fix prototype for rules_getenv to return const data. Fix rules_getenv to call getenv if no suitable variable was found. Fix rules_getenv to return the *last* matching result. ------------------------------------------------------------------------ r175 | bruce | 2002-09-13 19:46:30 -0600 (Fri, 13 Sep 2002) | 2 lines Changed paths: M /trunk/tests/rules-defaultmsg Fixed deferred message. ------------------------------------------------------------------------ r174 | bruce | 2002-09-13 19:46:15 -0600 (Fri, 13 Sep 2002) | 2 lines Changed paths: M /trunk/README Bumped up version. ------------------------------------------------------------------------ r173 | bruce | 2002-09-13 04:38:07 -0600 (Fri, 13 Sep 2002) | 2 lines Changed paths: M /trunk/mailrules.html Added some more examples. ------------------------------------------------------------------------ r172 | bruce | 2002-09-13 04:37:33 -0600 (Fri, 13 Sep 2002) | 2 lines Changed paths: M /trunk/mailrules.c Added a default handler. ------------------------------------------------------------------------ r171 | bruce | 2002-09-11 17:31:39 -0600 (Wed, 11 Sep 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r170 | bruce | 2002-09-11 16:29:27 -0600 (Wed, 11 Sep 2002) | 2 lines Changed paths: M /trunk/mailrules.c M /trunk/mailrules.html M /trunk/tests/rules-cdb M /trunk/tests/rules-defaultmsg M /trunk/tests/rules-list M /trunk/tests/rules-recip M /trunk/tests/rules-sender Fixed z/d semantics to match qmail-remote, QMQP, and QMTP. ------------------------------------------------------------------------ r169 | bruce | 2002-09-11 16:20:08 -0600 (Wed, 11 Sep 2002) | 2 lines Changed paths: M /trunk/mailrules.html Clarified the note on escapes. ------------------------------------------------------------------------ r168 | bruce | 2002-09-11 16:17:12 -0600 (Wed, 11 Sep 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/qmail-validate.c Added support for wildcards in rcpthosts and morercpthosts.cdb. ------------------------------------------------------------------------ r167 | bruce | 2002-08-27 21:13:21 -0600 (Tue, 27 Aug 2002) | 2 lines Changed paths: M /trunk/mailrules.c M /trunk/mailrules.html M /trunk/tests/rules-recip M /trunk/tests/rules-sender Added support for "pass-through" rules. ------------------------------------------------------------------------ r166 | bruce | 2002-08-26 20:28:27 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/mailrules.html Added note that the qmail rules are only an example. ------------------------------------------------------------------------ r165 | bruce | 2002-08-26 20:20:24 -0600 (Mon, 26 Aug 2002) | 3 lines Changed paths: M /trunk/NEWS M /trunk/qmail-validate.c Properly lowercase the sender address before looking it up in badmailfrom. ------------------------------------------------------------------------ r164 | bruce | 2002-08-26 03:35:44 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/README M /trunk/mailrules.html Clarified interpretation of empty or missing columns. ------------------------------------------------------------------------ r163 | bruce | 2002-08-26 03:35:19 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: A /trunk/tests/rules-defaultmsg Test default messages. ------------------------------------------------------------------------ r162 | bruce | 2002-08-26 03:35:08 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/mailrules.c Properly set up different default messages for each type of rule. ------------------------------------------------------------------------ r161 | bruce | 2002-08-26 03:28:45 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/mailrules.c Fixed handling of empty resposes. ------------------------------------------------------------------------ r160 | bruce | 2002-08-26 03:08:27 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/mailrules.html Added note about empty pattern matching. ------------------------------------------------------------------------ r159 | bruce | 2002-08-26 03:07:12 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: A /trunk/tests/rules-empty Added test for empty pattern. ------------------------------------------------------------------------ r158 | bruce | 2002-08-26 03:06:57 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r157 | bruce | 2002-08-26 03:05:35 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/NEWS Added note about mail rules processing and sponsorship. ------------------------------------------------------------------------ r156 | bruce | 2002-08-26 03:04:35 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/VERSION Bumped version. ------------------------------------------------------------------------ r155 | bruce | 2002-08-26 03:04:02 -0600 (Mon, 26 Aug 2002) | 3 lines Changed paths: M /trunk/smtp-commands.c Fixed bounce to multiple recipient logic to properly reject the data command after the condition is discovered. ------------------------------------------------------------------------ r154 | bruce | 2002-08-26 03:03:25 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/smtpfront.html Added note about bounce to multiple recipient handling. ------------------------------------------------------------------------ r153 | bruce | 2002-08-26 02:57:39 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: M /trunk/smtp=l M /trunk/smtpfront-echo=x M /trunk/smtpfront-reject=x Added necessary linkage for mailrules implementation. ------------------------------------------------------------------------ r152 | bruce | 2002-08-26 02:57:17 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: A /trunk/tests/rules-asterisk A /trunk/tests/rules-both A /trunk/tests/rules-cdb A /trunk/tests/rules-list A /trunk/tests/rules-multiline A /trunk/tests/rules-recip A /trunk/tests/rules-sender Added mail rules tests. ------------------------------------------------------------------------ r151 | bruce | 2002-08-26 02:57:12 -0600 (Mon, 26 Aug 2002) | 2 lines Changed paths: A /trunk/mailrules.c A /trunk/mailrules.html Added mail rules implementation and documentation. ------------------------------------------------------------------------ r150 | bruce | 2002-08-26 02:56:38 -0600 (Mon, 26 Aug 2002) | 3 lines Changed paths: M /trunk/qmail-validate.html M /trunk/smtpfront.html Added notes about new mail rules interface, and the addition of $RELAYCLIENT and authentication handling to all back-ends. ------------------------------------------------------------------------ r149 | bruce | 2002-08-26 02:55:46 -0600 (Mon, 26 Aug 2002) | 4 lines Changed paths: M /trunk/smtp-commands.c Call the mailrules API at the appropriate places. Add $RELAYCLIENT handling here from qmail-validate. Add authenticated handleing here. ------------------------------------------------------------------------ r148 | bruce | 2002-08-25 21:26:30 -0600 (Sun, 25 Aug 2002) | 2 lines Changed paths: M /trunk/qmail-backend.c Use mailrules API to get/export environment variables. ------------------------------------------------------------------------ r147 | bruce | 2002-08-25 21:24:29 -0600 (Sun, 25 Aug 2002) | 3 lines Changed paths: M /trunk/mailrules.h M /trunk/smtp-mainloop.c M /trunk/smtp.h Moved maxdatabytes saving and restoring into mailrules. Added environment API to mailrules. ------------------------------------------------------------------------ r146 | bruce | 2002-08-20 18:12:20 -0600 (Tue, 20 Aug 2002) | 2 lines Changed paths: M /trunk/smtp-mainloop.c Set up relayclient and saved_maxdatabytes, and init mail rules. ------------------------------------------------------------------------ r145 | bruce | 2002-08-20 18:11:46 -0600 (Tue, 20 Aug 2002) | 2 lines Changed paths: A /trunk/mailrules.h Added initial API for mail rules processing. ------------------------------------------------------------------------ r144 | bruce | 2002-08-20 18:10:23 -0600 (Tue, 20 Aug 2002) | 2 lines Changed paths: M /trunk/echo-backend.c M /trunk/mailfront.h M /trunk/smtpfront-qmail.c Add seperate validate_(sender|recipient) routines. ------------------------------------------------------------------------ r143 | bruce | 2002-08-20 18:09:56 -0600 (Tue, 20 Aug 2002) | 3 lines Changed paths: M /trunk/smtpfront-reject.c Add seperate validate_(sender|recipient) routines. Explicitly set relayclient and authenticated to false. ------------------------------------------------------------------------ r142 | bruce | 2002-08-20 18:07:10 -0600 (Tue, 20 Aug 2002) | 2 lines Changed paths: M /trunk/smtp.h Export relayclient and saved_maxdatabytes state. ------------------------------------------------------------------------ r141 | bruce | 2002-08-19 18:24:00 -0600 (Mon, 19 Aug 2002) | 2 lines Changed paths: M /trunk/smtp-commands.c Completed other half of single-recipient-bounce logic. ------------------------------------------------------------------------ r140 | bruce | 2002-08-19 18:22:31 -0600 (Mon, 19 Aug 2002) | 2 lines Changed paths: M /trunk/smtp-commands.c Tweaked single-recipient-bounce logic to apply before any parsing. ------------------------------------------------------------------------ r139 | bruce | 2002-08-13 04:35:57 -0600 (Tue, 13 Aug 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-mainloop.c Fixed handling of SMTPGREETING and TCPLOCALHOST. ------------------------------------------------------------------------ r138 | bruce | 2002-08-09 20:07:21 -0600 (Fri, 09 Aug 2002) | 2 lines Changed paths: M /trunk/README M /trunk/VERSION Bumped up version. ------------------------------------------------------------------------ r137 | bruce | 2002-08-08 17:18:45 -0600 (Thu, 08 Aug 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/qmail-validate.c Add wildcard code for badrcptto to smtpfront-qmail. ------------------------------------------------------------------------ r136 | bruce | 2002-07-15 23:58:02 -0600 (Mon, 15 Jul 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/insthier.c Added missing imapfront-auth. ------------------------------------------------------------------------ r135 | bruce | 2002-06-20 18:24:41 -0600 (Thu, 20 Jun 2002) | 2 lines Changed paths: M /trunk/spec Added build requirement for bglibs. ------------------------------------------------------------------------ r134 | bruce | 2002-06-20 16:22:41 -0600 (Thu, 20 Jun 2002) | 2 lines Changed paths: M /trunk/README M /trunk/VERSION Bumped up version number. ------------------------------------------------------------------------ r133 | bruce | 2002-06-20 16:20:27 -0600 (Thu, 20 Jun 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/sasl-auth.c Provide better credential information, as well as logging failures. ------------------------------------------------------------------------ r132 | bruce | 2002-06-18 23:38:50 -0600 (Tue, 18 Jun 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth=x M /trunk/sasl-auth.c Log SASL authenticated username. ------------------------------------------------------------------------ r131 | bruce | 2002-06-18 21:21:16 -0600 (Tue, 18 Jun 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/imapfront-auth.c Fixed missing "OK" bug in imapfront-auth. ------------------------------------------------------------------------ r130 | bruce | 2002-06-06 18:28:58 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/spec Added missing include/library flags. ------------------------------------------------------------------------ r129 | bruce | 2002-06-06 18:25:47 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/README M /trunk/VERSION Bumped up version. ------------------------------------------------------------------------ r128 | bruce | 2002-06-06 18:22:32 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO M /trunk/imapfront-auth=x M /trunk/imapfront.html M /trunk/pop3front-auth=x M /trunk/pop3front-maildir=x M /trunk/pop3front.html M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x M /trunk/smtpfront.html M /trunk/timeout.c Added support for a session timeout. ------------------------------------------------------------------------ r127 | bruce | 2002-06-06 18:12:04 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO M /trunk/smtp-commands.c A /trunk/tests/smtpfront-bad-bounce M /trunk/tests.inc Reject bounces with multiple recipients. ------------------------------------------------------------------------ r126 | bruce | 2002-06-06 17:58:45 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r125 | bruce | 2002-06-06 17:47:17 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/TODO M /trunk/imapfront-auth.c M /trunk/imapfront-auth=x M /trunk/pop3-mainloop.c M /trunk/pop3=l M /trunk/smtp-mainloop.c M /trunk/smtp=l A /trunk/timeout.c Merged the common timeout code into one place. ------------------------------------------------------------------------ r124 | bruce | 2002-06-06 17:34:54 -0600 (Thu, 06 Jun 2002) | 2 lines Changed paths: M /trunk/TODO Revised pattern matching plan. ------------------------------------------------------------------------ r123 | bruce | 2002-06-04 20:59:49 -0600 (Tue, 04 Jun 2002) | 2 lines Changed paths: M /trunk/imapfront-auth.c M /trunk/imapfront-auth=x M /trunk/insthier.c M /trunk/iobytes.c M /trunk/mailfront.h M /trunk/pop3-mainloop.c M /trunk/pop3-response.c M /trunk/pop3front-auth.c M /trunk/pop3front-auth=x M /trunk/pop3front-maildir.c M /trunk/pop3front-maildir=x M /trunk/qmail-backend.c M /trunk/qmail-validate.c M /trunk/sasl-auth.c M /trunk/sasl-stub.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtp-respond.c M /trunk/smtp.h M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail.c M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject.c M /trunk/smtpfront-reject=x Switched to using external bglibs. ------------------------------------------------------------------------ r122 | bruce | 2002-06-04 20:41:30 -0600 (Tue, 04 Jun 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r121 | bruce | 2002-05-07 23:04:48 -0600 (Tue, 07 May 2002) | 2 lines Changed paths: M /trunk/README A /trunk/imapfront.html M /trunk/mailfront.html Added some IMAP documentation. ------------------------------------------------------------------------ r120 | bruce | 2002-05-07 22:23:04 -0600 (Tue, 07 May 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r119 | bruce | 2002-05-07 21:15:51 -0600 (Tue, 07 May 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r118 | bruce | 2002-05-07 20:28:57 -0600 (Tue, 07 May 2002) | 2 lines Changed paths: M /trunk/imapfront-auth.c Added support for the AUTHENTICATE command. ------------------------------------------------------------------------ r117 | bruce | 2002-05-07 20:28:43 -0600 (Tue, 07 May 2002) | 2 lines Changed paths: M /trunk/pop3front-auth.c M /trunk/sasl-auth.c M /trunk/sasl-auth.h M /trunk/sasl-stub.c M /trunk/smtp-commands.c Updated the SASL interface to allow one or two arguments. ------------------------------------------------------------------------ r116 | bruce | 2002-05-07 19:17:47 -0600 (Tue, 07 May 2002) | 2 lines Changed paths: A /trunk/imapfront-auth.c A /trunk/imapfront-auth=x Added first try at an IMAP authentication front end. ------------------------------------------------------------------------ r115 | bruce | 2002-05-06 20:55:23 -0600 (Mon, 06 May 2002) | 2 lines Changed paths: A /trunk/tests/smtpgreeting Added test for $SMTPGREETING. ------------------------------------------------------------------------ r114 | bruce | 2002-05-06 20:55:16 -0600 (Mon, 06 May 2002) | 2 lines Changed paths: M /trunk/tests.inc Fixed pop3front-auth function. ------------------------------------------------------------------------ r113 | bruce | 2002-05-06 20:54:57 -0600 (Mon, 06 May 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r112 | bruce | 2002-05-06 20:50:23 -0600 (Mon, 06 May 2002) | 2 lines Changed paths: M /trunk/mailfront.html M /trunk/smtpfront.html Updated documentation. ------------------------------------------------------------------------ r111 | bruce | 2002-05-06 20:49:42 -0600 (Mon, 06 May 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/smtp-mainloop.c M /trunk/smtp.h M /trunk/smtpfront-echo.c M /trunk/smtpfront-qmail.c M /trunk/smtpfront-reject.c Added support for $SMTPGREETING. ------------------------------------------------------------------------ r110 | bruce | 2002-04-17 20:31:28 -0600 (Wed, 17 Apr 2002) | 3 lines Changed paths: M /trunk/pop3-mainloop.c M /trunk/pop3.h M /trunk/pop3front-auth.c M /trunk/pop3front-maildir.c Allow for "sanitized" versions of some commands to be logged, for example to strip passwords. ------------------------------------------------------------------------ r109 | bruce | 2002-04-17 20:03:43 -0600 (Wed, 17 Apr 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/pop3-mainloop.c M /trunk/pop3-response.c M /trunk/pop3.h Modified pop3front to log all commands, not just errors. ------------------------------------------------------------------------ r108 | bruce | 2002-02-12 22:56:11 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/NEWS Typo. ------------------------------------------------------------------------ r107 | bruce | 2002-02-12 22:41:15 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/README M /trunk/VERSION un-bumped version number. ------------------------------------------------------------------------ r106 | bruce | 2002-02-12 22:23:01 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/README.CVS M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r105 | bruce | 2002-02-12 22:19:22 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-auth=x M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x Replace use of "socket" library with the "net" library. ------------------------------------------------------------------------ r104 | bruce | 2002-02-12 21:03:07 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/README M /trunk/VERSION *** empty log message *** ------------------------------------------------------------------------ r103 | bruce | 2002-02-12 21:01:33 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-auth.c Log the username. ------------------------------------------------------------------------ r102 | bruce | 2002-02-12 20:11:16 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/qmail-validate.c Fixed one-off bug in badmailfrom handling. ------------------------------------------------------------------------ r101 | bruce | 2002-02-12 20:05:57 -0600 (Tue, 12 Feb 2002) | 3 lines Changed paths: D /trunk/log.c D /trunk/log.h M /trunk/mailfront.h M /trunk/qmail-backend.c M /trunk/smtp-commands.c M /trunk/smtp-respond.c M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x Converted smtpfront to use the msg library, and dropped the custom log functions. ------------------------------------------------------------------------ r100 | bruce | 2002-02-12 20:05:26 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/NEWS *** empty log message *** ------------------------------------------------------------------------ r99 | bruce | 2002-02-12 19:58:46 -0600 (Tue, 12 Feb 2002) | 3 lines Changed paths: A /trunk/iobytes.c M /trunk/pop3=l M /trunk/pop3front-maildir.c M /trunk/smtp-mainloop.c M /trunk/smtp=l Moved the I/O byte reporting into a common module, and added the hook to the SMTP front end. ------------------------------------------------------------------------ r98 | bruce | 2002-02-12 19:48:30 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/tests.inc *** empty log message *** ------------------------------------------------------------------------ r97 | bruce | 2002-02-12 19:48:18 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Converted to using msg for errors. ------------------------------------------------------------------------ r96 | bruce | 2002-02-12 17:55:42 -0600 (Tue, 12 Feb 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r95 | bruce | 2002-02-12 17:55:24 -0600 (Tue, 12 Feb 2002) | 3 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-maildir.c Added an exit hook to pop3front-maildir to print the number of bytes input and output. ------------------------------------------------------------------------ r94 | bruce | 2002-02-06 18:25:49 -0600 (Wed, 06 Feb 2002) | 2 lines Changed paths: M /trunk/tests/pop3front-auth-userpass A /trunk/tests/pop3front-maildir-flags A /trunk/tests/pop3front-maildir-last A /trunk/tests/pop3front-maildir-sort A /trunk/tests/pop3front-maildir-state M /trunk/tests.inc Updated and added tests. ------------------------------------------------------------------------ r93 | bruce | 2002-02-01 17:30:06 -0600 (Fri, 01 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Use strchr instead of scanning for flags by hand. ------------------------------------------------------------------------ r92 | bruce | 2002-02-01 17:27:38 -0600 (Fri, 01 Feb 2002) | 2 lines Changed paths: M /trunk/NEWS *** empty log message *** ------------------------------------------------------------------------ r91 | bruce | 2002-02-01 17:26:55 -0600 (Fri, 01 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Implemented the obsolete LAST command. ------------------------------------------------------------------------ r90 | bruce | 2002-02-01 17:07:18 -0600 (Fri, 01 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Sort the messages in the maildir (by numerical value). ------------------------------------------------------------------------ r89 | bruce | 2002-02-01 04:08:13 -0600 (Fri, 01 Feb 2002) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Scan the messages for a "read" flag. ------------------------------------------------------------------------ r88 | bruce | 2002-02-01 04:01:13 -0600 (Fri, 01 Feb 2002) | 3 lines Changed paths: M /trunk/pop3front-maildir.c Modified the flags handling to properly *add* instead of replacing the flags. ------------------------------------------------------------------------ r87 | bruce | 2002-01-31 18:25:15 -0600 (Thu, 31 Jan 2002) | 2 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-maildir.c Properly tag read messages on QUIT. ------------------------------------------------------------------------ r86 | bruce | 2002-01-31 18:24:28 -0600 (Thu, 31 Jan 2002) | 2 lines Changed paths: M /trunk/README M /trunk/VERSION Bumped version number. ------------------------------------------------------------------------ r85 | bruce | 2002-01-11 18:54:40 -0600 (Fri, 11 Jan 2002) | 2 lines Changed paths: M /trunk/tests/pop3front-auth M /trunk/tests/pop3front-auth-userpass Fixed extra period. ------------------------------------------------------------------------ r84 | bruce | 2002-01-11 18:54:29 -0600 (Fri, 11 Jan 2002) | 2 lines Changed paths: M /trunk/README Touched date. ------------------------------------------------------------------------ r83 | bruce | 2002-01-11 04:29:35 -0600 (Fri, 11 Jan 2002) | 3 lines Changed paths: M /trunk/pop3-mainloop.c M /trunk/pop3front.html M /trunk/smtp-mainloop.c Added $TIMEOUT handling to the POP3 modules. Minor adjustment to SMTP $TIMEOUT handling. ------------------------------------------------------------------------ r82 | bruce | 2002-01-11 04:28:02 -0600 (Fri, 11 Jan 2002) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r81 | bruce | 2002-01-09 21:59:26 -0600 (Wed, 09 Jan 2002) | 3 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-maildir.c DELE needed to add deleted messages to the appropriate counters so STAT could account for the difference. ------------------------------------------------------------------------ r80 | bruce | 2001-12-28 00:31:52 -0600 (Fri, 28 Dec 2001) | 2 lines Changed paths: M /trunk/pop3front.html Documented the MAX_CUR/NEW_MESSAGES options. ------------------------------------------------------------------------ r79 | bruce | 2001-12-28 00:25:07 -0600 (Fri, 28 Dec 2001) | 3 lines Changed paths: M /trunk/pop3front-maildir.c Minor optimization: only update the count pointer after the loop is complete. ------------------------------------------------------------------------ r78 | bruce | 2001-12-28 00:23:54 -0600 (Fri, 28 Dec 2001) | 3 lines Changed paths: M /trunk/pop3front-maildir.c Add optional individual count limits on both the cur and new subdirectories. ------------------------------------------------------------------------ r77 | bruce | 2001-12-27 22:32:41 -0600 (Thu, 27 Dec 2001) | 2 lines Changed paths: M /trunk/pop3front-auth=x M /trunk/pop3front-maildir=x Added missing msg/msg.a library. ------------------------------------------------------------------------ r76 | bruce | 2001-12-27 22:32:23 -0600 (Thu, 27 Dec 2001) | 2 lines Changed paths: M /trunk/pop3-response.c Output all error responses to the logs. ------------------------------------------------------------------------ r75 | bruce | 2001-12-24 05:38:59 -0600 (Mon, 24 Dec 2001) | 5 lines Changed paths: M /trunk/pop3front-maildir.c Fixed two message corruption bugs in dump_msg: - periods at the start of a line weren't escaped and - if the line after the last requested line of the body spanned buffers, the first part of it would be written. ------------------------------------------------------------------------ r74 | bruce | 2001-12-23 05:53:24 -0600 (Sun, 23 Dec 2001) | 2 lines Changed paths: M /trunk/pop3-mainloop.c Added timeout option. ------------------------------------------------------------------------ r73 | bruce | 2001-12-23 05:52:52 -0600 (Sun, 23 Dec 2001) | 2 lines Changed paths: M /trunk/pop3front-auth.c Fixed some response strings, added program string. ------------------------------------------------------------------------ r72 | bruce | 2001-12-23 05:52:26 -0600 (Sun, 23 Dec 2001) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Fixed some debug strings, add program string. ------------------------------------------------------------------------ r71 | bruce | 2001-12-17 04:35:01 -0600 (Mon, 17 Dec 2001) | 2 lines Changed paths: A /trunk/COPYING M /trunk/README M /trunk/TODO M /trunk/VERSION *** empty log message *** ------------------------------------------------------------------------ r70 | bruce | 2001-12-17 04:30:55 -0600 (Mon, 17 Dec 2001) | 2 lines Changed paths: A /trunk/spec Added missing spec file. ------------------------------------------------------------------------ r69 | bruce | 2001-11-22 23:13:54 -0600 (Thu, 22 Nov 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-maildir.c M /trunk/pop3front.html Added a maximum accessable message count option. ------------------------------------------------------------------------ r68 | bruce | 2001-10-18 23:20:17 -0600 (Thu, 18 Oct 2001) | 2 lines Changed paths: M /trunk/pop3front-maildir=x This module doesn't need CVM, so don't link against it. ------------------------------------------------------------------------ r67 | bruce | 2001-10-18 23:19:57 -0600 (Thu, 18 Oct 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/pop3front-auth=x M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x Added missing socket.lib linker option. ------------------------------------------------------------------------ r66 | bruce | 2001-10-18 23:13:41 -0600 (Thu, 18 Oct 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/README M /trunk/VERSION Bumped up the version number. ------------------------------------------------------------------------ r65 | bruce | 2001-10-17 22:30:12 -0600 (Wed, 17 Oct 2001) | 2 lines Changed paths: M /trunk/insthier.c Added pop3front-* programs. ------------------------------------------------------------------------ r64 | bruce | 2001-09-21 21:35:17 -0600 (Fri, 21 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r63 | bruce | 2001-09-21 18:33:35 -0600 (Fri, 21 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/README *** empty log message *** ------------------------------------------------------------------------ r62 | bruce | 2001-09-21 18:32:13 -0600 (Fri, 21 Sep 2001) | 3 lines Changed paths: M /trunk/smtp-commands.c Log the MAIL and RCPT parameters always, not just when they are accepted by handle_sender and handle_recipient. ------------------------------------------------------------------------ r61 | bruce | 2001-09-14 22:32:27 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: A /trunk/tests/pop3front-auth M /trunk/tests/smtpfront-auth-plain More testing... ------------------------------------------------------------------------ r60 | bruce | 2001-09-14 21:31:50 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: A /trunk/tests A /trunk/tests/pop3front-auth-login A /trunk/tests/pop3front-auth-plain A /trunk/tests/pop3front-auth-userpass A /trunk/tests/smtpfront-auth-login A /trunk/tests/smtpfront-auth-plain A /trunk/tests.inc Added tests of the auth mechanisms. ------------------------------------------------------------------------ r59 | bruce | 2001-09-14 21:31:37 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS *** empty log message *** ------------------------------------------------------------------------ r58 | bruce | 2001-09-14 21:31:30 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/sasl-auth.c Abort the authentication if the response string starts with '*'. ------------------------------------------------------------------------ r57 | bruce | 2001-09-14 21:31:06 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/sasl-auth.c Properly skip spaces after the mechanism name. ------------------------------------------------------------------------ r56 | bruce | 2001-09-14 21:29:56 -0600 (Fri, 14 Sep 2001) | 3 lines Changed paths: M /trunk/smtp-commands.c Log the sender and recipient addresses. Provide a success response when authentication succeeds. ------------------------------------------------------------------------ r55 | bruce | 2001-09-14 21:29:15 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/mailfront.h M /trunk/smtp.h Moved several SMTP specific function declarations into smtp.h ------------------------------------------------------------------------ r54 | bruce | 2001-09-14 21:28:49 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/smtp-respond.c Use the more efficient putsflush(CRLF) form. ------------------------------------------------------------------------ r53 | bruce | 2001-09-14 05:47:04 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/README M /trunk/TODO M /trunk/VERSION *** empty log message *** ------------------------------------------------------------------------ r52 | bruce | 2001-09-14 05:45:26 -0600 (Fri, 14 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/qmail-validate.c Lowercase domain names before comparing them. ------------------------------------------------------------------------ r51 | bruce | 2001-09-13 00:03:25 -0600 (Thu, 13 Sep 2001) | 2 lines Changed paths: M /trunk/README M /trunk/pop3front-auth=x M /trunk/pop3front-maildir=x A /trunk/pop3front.html M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x *** empty log message *** ------------------------------------------------------------------------ r50 | bruce | 2001-09-09 05:35:20 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r49 | bruce | 2001-09-09 05:29:22 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: M /trunk/pop3front-maildir.c Added support for TOP command. ------------------------------------------------------------------------ r48 | bruce | 2001-09-09 05:29:00 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: M /trunk/pop3front-auth.c M /trunk/pop3front-auth=x Added support for the AUTH command. ------------------------------------------------------------------------ r47 | bruce | 2001-09-09 05:28:36 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: M /trunk/mailfront.html *** empty log message *** ------------------------------------------------------------------------ r46 | bruce | 2001-09-09 05:28:21 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: A /trunk/sasl-auth.c A /trunk/sasl-auth.h A /trunk/sasl-stub.c D /trunk/smtp-auth-stub.c D /trunk/smtp-auth.c M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtp.h M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x Moved the SMTP specific SASL AUTH code to a new more generic module. ------------------------------------------------------------------------ r45 | bruce | 2001-09-09 05:26:07 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: M /trunk/pop3-response.c Use new CRLF constant. ------------------------------------------------------------------------ r44 | bruce | 2001-09-09 05:25:17 -0600 (Sun, 09 Sep 2001) | 2 lines Changed paths: A /trunk/constants.h M /trunk/mailfront.h M /trunk/pop3.h M /trunk/smtp.h Moved a bunch of the character constants into a seperate module. ------------------------------------------------------------------------ r43 | bruce | 2001-09-07 18:13:51 -0600 (Fri, 07 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS *** empty log message *** ------------------------------------------------------------------------ r42 | bruce | 2001-09-07 06:41:57 -0600 (Fri, 07 Sep 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/README M /trunk/TODO A /trunk/VERSION *** empty log message *** ------------------------------------------------------------------------ r41 | bruce | 2001-09-07 06:40:17 -0600 (Fri, 07 Sep 2001) | 2 lines Changed paths: M /trunk/smtp-auth.c Revised to use new cvm-sasl structure. ------------------------------------------------------------------------ r40 | bruce | 2001-09-07 06:39:44 -0600 (Fri, 07 Sep 2001) | 2 lines Changed paths: M /trunk/smtp-mainloop.c Use ibuf_getstr_crlf in favour of smtp_get_line. ------------------------------------------------------------------------ r39 | bruce | 2001-09-07 06:39:26 -0600 (Fri, 07 Sep 2001) | 3 lines Changed paths: M /trunk/smtp.h Redefined the character macros to add type. Use the new ibuf_getstr_crlf function. ------------------------------------------------------------------------ r38 | bruce | 2001-09-07 06:34:32 -0600 (Fri, 07 Sep 2001) | 2 lines Changed paths: A /trunk/pop3=l *** empty log message *** ------------------------------------------------------------------------ r37 | bruce | 2001-09-07 06:34:11 -0600 (Fri, 07 Sep 2001) | 2 lines Changed paths: A /trunk/pop3-mainloop.c A /trunk/pop3-response.c A /trunk/pop3.h A /trunk/pop3front-auth.c A /trunk/pop3front-auth=x A /trunk/pop3front-maildir.c A /trunk/pop3front-maildir=x Added a new POP3 server pair. ------------------------------------------------------------------------ r36 | bruce | 2001-08-24 20:53:06 -0600 (Fri, 24 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront.html Added (temporary) link for cvm-sasl.html. ------------------------------------------------------------------------ r35 | bruce | 2001-08-24 20:37:13 -0600 (Fri, 24 Aug 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/README M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r34 | bruce | 2001-08-24 20:34:12 -0600 (Fri, 24 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront.html Noted use of SMTP AUTH. ------------------------------------------------------------------------ r33 | bruce | 2001-08-10 22:05:38 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/NEWS M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r32 | bruce | 2001-08-10 20:05:57 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/smtp-respond.c Renamed NL to LF. ------------------------------------------------------------------------ r31 | bruce | 2001-08-10 20:05:43 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/README.CVS M /trunk/TODO M /trunk/mailfront.html *** empty log message *** ------------------------------------------------------------------------ r30 | bruce | 2001-08-10 20:05:26 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/mailfront.h Added an "authenticated" state variable. ------------------------------------------------------------------------ r29 | bruce | 2001-08-10 20:02:44 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront-qmail.c Allow authenticated sessions to relay. ------------------------------------------------------------------------ r28 | bruce | 2001-08-10 20:02:08 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/smtp-commands.c M /trunk/smtp-mainloop.c M /trunk/smtp.h Added hooks for SMTP AUTH. ------------------------------------------------------------------------ r27 | bruce | 2001-08-10 20:01:55 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x Link against the full SMTP AUTH implementation. ------------------------------------------------------------------------ r26 | bruce | 2001-08-10 20:01:38 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront-reject=x Link against the SMTP AUTH stubs. ------------------------------------------------------------------------ r25 | bruce | 2001-08-10 20:01:11 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: A /trunk/smtp-auth-stub.c First check-in of the dummy SMTP AUTH stub functions. ------------------------------------------------------------------------ r24 | bruce | 2001-08-10 20:00:56 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: A /trunk/smtp-auth.c First check-in of the main SMTP AUTH support module. ------------------------------------------------------------------------ r23 | bruce | 2001-08-10 19:54:02 -0600 (Fri, 10 Aug 2001) | 2 lines Changed paths: M /trunk/qmail-validate.c Use the new dict_load_list to load the dictionaries. ------------------------------------------------------------------------ r22 | bruce | 2001-08-08 20:12:37 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront-echo=x M /trunk/smtpfront-qmail=x M /trunk/smtpfront-reject=x Added missing iopoll.o object. ------------------------------------------------------------------------ r21 | bruce | 2001-08-08 20:11:15 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: M /trunk/README *** empty log message *** ------------------------------------------------------------------------ r20 | bruce | 2001-08-08 20:05:02 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: A /trunk/makedist.py Added distribution file. ------------------------------------------------------------------------ r19 | bruce | 2001-08-08 20:04:54 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: A /trunk/NEWS A /trunk/README A /trunk/README.CVS A /trunk/mailfront.html A /trunk/qmail-backend.html A /trunk/qmail-validate.html A /trunk/smtpfront.html Added documentation. ------------------------------------------------------------------------ r18 | bruce | 2001-08-08 20:04:36 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: M /trunk/insthier.c *** empty log message *** ------------------------------------------------------------------------ r17 | bruce | 2001-08-08 20:01:53 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: D /trunk/architecture.txt D /trunk/features.txt Translated into the HTML documentation and removed. ------------------------------------------------------------------------ r16 | bruce | 2001-08-08 19:59:02 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: M /trunk/TODO *** empty log message *** ------------------------------------------------------------------------ r15 | bruce | 2001-08-08 19:58:49 -0600 (Wed, 08 Aug 2001) | 2 lines Changed paths: A /trunk/smtpfront-echo.c A /trunk/smtpfront-echo=x D /trunk/smtpfront-test.c D /trunk/smtpfront-test=x Renamed smtpfront-test to smtpfront-echo. ------------------------------------------------------------------------ r14 | bruce | 2001-08-07 23:19:39 -0600 (Tue, 07 Aug 2001) | 2 lines Changed paths: M /trunk/features.txt M /trunk/smtp-commands.c Handle RFC 1869 extended RCPT TO: and MAIL FROM: parameters. ------------------------------------------------------------------------ r13 | bruce | 2001-08-07 23:18:36 -0600 (Tue, 07 Aug 2001) | 2 lines Changed paths: M /trunk/insthier.c Adapted to new insthier framework. ------------------------------------------------------------------------ r12 | bruce | 2001-08-07 22:48:17 -0600 (Tue, 07 Aug 2001) | 2 lines Changed paths: M /trunk/features.txt Added badrcptto handling to the qmail backend. ------------------------------------------------------------------------ r11 | bruce | 2001-08-07 22:47:31 -0600 (Tue, 07 Aug 2001) | 2 lines Changed paths: M /trunk/qmail-validate.c Added badrcptto handling. ------------------------------------------------------------------------ r10 | bruce | 2001-08-07 22:47:09 -0600 (Tue, 07 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront-reject.c Added a missing include. ------------------------------------------------------------------------ r9 | bruce | 2001-08-03 23:16:22 -0600 (Fri, 03 Aug 2001) | 2 lines Changed paths: M /trunk/smtpfront-qmail.c M /trunk/smtpfront-test.c Fixed up the program names. ------------------------------------------------------------------------ r8 | bruce | 2001-08-03 23:16:12 -0600 (Fri, 03 Aug 2001) | 2 lines Changed paths: M /trunk/qmail-validate.c Renamed an internal function. ------------------------------------------------------------------------ r7 | bruce | 2001-08-03 23:15:42 -0600 (Fri, 03 Aug 2001) | 2 lines Changed paths: A /trunk/smtpfront-reject.c A /trunk/smtpfront-reject=x Added a simple reject-everything server. ------------------------------------------------------------------------ r6 | bruce | 2001-08-03 23:15:12 -0600 (Fri, 03 Aug 2001) | 2 lines Changed paths: D /trunk/smtpfront-qmail-er.c D /trunk/smtpfront-qmail-er=x Removed this FutureQuest internal program. ------------------------------------------------------------------------ r5 | bruce | 2001-06-15 21:25:12 -0600 (Fri, 15 Jun 2001) | 2 lines Changed paths: M /trunk/qmail-validate.c M /trunk/smtpfront-qmail-er=x M /trunk/smtpfront-qmail=x Added support for verifying addresses against control/morercpthosts.cdb. ------------------------------------------------------------------------ r4 | bruce | 2001-06-15 21:24:48 -0600 (Fri, 15 Jun 2001) | 3 lines Changed paths: M /trunk/smtp-commands.c Totally rewrote the DATA command to handle the message content in fixed space (as opposed to allocated space for each line). ------------------------------------------------------------------------ r3 | bruce | 2001-06-15 21:23:52 -0600 (Fri, 15 Jun 2001) | 2 lines Changed paths: M /trunk/smtp-mainloop.c M /trunk/smtp.h Renamed databytes to maxdatabytes. ------------------------------------------------------------------------ r2 | bruce | 2001-06-15 21:23:16 -0600 (Fri, 15 Jun 2001) | 2 lines Changed paths: M /trunk/TODO M /trunk/features.txt *** empty log message *** ------------------------------------------------------------------------ r1 | bruce | 2001-06-15 19:33:05 -0600 (Fri, 15 Jun 2001) | 2 lines Changed paths: A /trunk A /trunk/TODO A /trunk/architecture.txt A /trunk/echo-backend.c A /trunk/features.txt A /trunk/insthier.c A /trunk/log.c A /trunk/log.h A /trunk/mailfront.h A /trunk/qmail-backend.c A /trunk/qmail-validate.c A /trunk/qmail.h A /trunk/qmail=l A /trunk/responses.c A /trunk/responses.h A /trunk/smtp-commands.c A /trunk/smtp-mainloop.c A /trunk/smtp-respond.c A /trunk/smtp.h A /trunk/smtp=l A /trunk/smtpfront-qmail-er.c A /trunk/smtpfront-qmail-er=x A /trunk/smtpfront-qmail.c A /trunk/smtpfront-qmail=x A /trunk/smtpfront-test.c A /trunk/smtpfront-test=x Initial revision ------------------------------------------------------------------------ mailfront-2.12/FILES0000644000000000000000000000327612467132135011120 0ustar ANNOUNCEMENT AUTOFILES COPYING ChangeLog FILES INSTHIER Makefile NEWS README SRCFILES TARGETS TODO VERSION backend-echo.c backend-echo.html backend-qmail.c backend-qmail.html backend-queuedir.c backend-queuedir.html builtins.c conf-bin conf-cc conf-ccso conf-include conf-ld conf-modules conf-qmail constants.h getprotoenv.c imapfront-auth.c imapfront.html iobytes.c mailfront-2.12.spec mailfront-internal.h mailfront.c mailfront.h mailfront.html mailrules.html mailrulesx.html modules.c msa.html netstring.c plugin-accept-recipient.html plugin-accept-sender.html plugin-accept.html plugin-add-received.c plugin-add-received.html plugin-api.html plugin-check-fqdn.c plugin-check-fqdn.html plugin-clamav.c plugin-clamav.html plugin-counters.c plugin-counters.html plugin-cvm-authenticate.c plugin-cvm-authenticate.html plugin-cvm-validate.c plugin-cvm-validate.html plugin-force-file.html plugin-lua.c plugin-lua.html plugin-mailrules.c plugin-mailrules.html plugin-patterns.c plugin-patterns.html plugin-qmail-validate.c plugin-qmail-validate.html plugin-rbl.c plugin-rbl.html plugin-reject.html plugin-relayclient.html plugin-require-auth.html plugin-spamassassin.c plugin-spamassassin.html plugin-starttls-ucspi.c plugin-starttls-ucspi.html plugin-template.c plugin-template.html pop3-capa.c pop3-mainloop.c pop3-response.c pop3.h pop3front-auth.c pop3front-maildir.c pop3front.html protocol-qmqp.c protocol-qmqp.html protocol-qmtp.c protocol-qmtp.html protocol-smtp.c protocol-smtp.html qmqpfront-echo.sh qmqpfront-qmail.sh qmtp-respond.c qmtp.h qmtpfront-echo.sh qmtpfront-qmail.sh queuedir.c responses.c responses.h session.c smtpfront-echo.sh smtpfront-qmail.sh std-handle.html testcvm.c tests.sh timeout.c warn-auto.sh mailfront-2.12/INSTHIER0000644000000000000000000000163012467132135011473 0ustar >bin c:::755::imapfront-auth c:::755::mailfront c:::755::pop3front-auth c:::755::pop3front-maildir c:::755::qmqpfront-echo c:::755::qmqpfront-qmail c:::755::qmtpfront-echo c:::755::qmtpfront-qmail c:::755::smtpfront-echo c:::755::smtpfront-qmail >modules c:::755::backend-echo.so c:::755::backend-qmail.so c:::755::backend-queuedir.so c:::755::plugin-add-received.so c:::755::plugin-check-fqdn.so c:::755::plugin-clamav.so c:::755::plugin-counters.so c:::755::plugin-cvm-authenticate.so c:::755::plugin-cvm-validate.so c?:::755::plugin-lua.so c:::755::plugin-mailrules.so c:::755::plugin-patterns.so c:::755::plugin-qmail-validate.so c:::755::plugin-rbl.so c:::755::plugin-spamassassin.so c:::755::plugin-starttls-ucspi.so c:::755::protocol-qmqp.so c:::755::protocol-qmtp.so c:::755::protocol-smtp.so >include d:::755:mailfront c:::755:mailfront:constants.h c:::755:mailfront:mailfront.h c:::755:mailfront:responses.h mailfront-2.12/Makefile0000644000000000000000000002031613213777177012000 0ustar # Don't edit Makefile! Use conf-* for configuration. # # Generated by spac see http://untroubled.org/spac/ SHELL=/bin/sh DEFAULT: all all: libraries programs docs auto_testcvm.c: echo \#define TESTCVM_UID $$(id -u) > $@ echo \#define TESTCVM_GID $$(id -g) >> $@ echo \#define TESTCVM_PWD \"$$(pwd)\" >> $@ backend-echo.so: makeso backend-echo.c mailfront.h responses.h constants.h ./makeso backend-echo.c -lbg backend-qmail.so: makeso backend-qmail.c mailfront.h responses.h constants.h conf_qmail.c ./makeso backend-qmail.c -lbg backend-queuedir.so: makeso backend-queuedir.c mailfront.h responses.h constants.h queuedir.c ./makeso backend-queuedir.c queuedir.c -lbg builtins.o: compile builtins.c mailfront-internal.h mailfront.h responses.h constants.h ./compile builtins.c clean: TARGETS rm -f `cat TARGETS` clean-spac: clean AUTOFILES rm -f `cat AUTOFILES` compile: conf-cc ( echo '#!/bin/sh'; \ echo 'source=$$1; shift'; \ echo 'base=`echo "$$source" | sed -e s:\\\\.c$$::`'; \ echo exec `head -n 1 conf-cc` -I. '-o $${base}.o -c $$source $${1+"$$@"}'; \ ) >compile chmod 755 compile conf_modules.c: conf-modules head -n 1 conf-modules | \ sed -e 's/"/\\"/g' \ -e 's/^/const char conf_modules[] = "/' \ -e 's/$$/";/' >conf_modules.c conf_qmail.c: conf-qmail head -n 1 conf-qmail | \ sed -e 's/"/\\"/g' \ -e 's/^/const char conf_qmail[] = "/' \ -e 's/$$/";/' >conf_qmail.c dl.lib: compile load @echo -n 'Checking for -ldl: ' @echo 'main() { ; }' >trylib-ldl.c @{ ./compile trylib-ldl.c && ./load trylib-ldl -ldl; } >/dev/null 2>&1 \ && { echo -ldl >dl.lib; echo yes; } \ || { echo -n >dl.lib; echo no; } @rm -f trylib-ldl.c trylib-ldl.o trylib-ldl docs: getprotoenv.o: compile getprotoenv.c mailfront.h responses.h constants.h ./compile getprotoenv.c imapfront-auth: imapfront-auth.o load timeout.o socket.lib ./load imapfront-auth timeout.o -lcvm-sasl -lcvm-v2client -lbg `cat socket.lib` imapfront-auth.o: compile imapfront-auth.c ./compile imapfront-auth.c install: INSTHIER conf-bin conf-modules conf-include bg-installer -v load chmod 755 load lua: plugin-lua.so mailfront: mailfront.o load builtins.o getprotoenv.o iobytes.o modules.o responses.o session.o timeout.o socket.lib dl.lib ./load mailfront builtins.o getprotoenv.o iobytes.o modules.o responses.o session.o timeout.o -lbg -rdynamic `cat socket.lib` `cat dl.lib` mailfront.o: compile mailfront.c mailfront-internal.h mailfront.h responses.h constants.h ./compile mailfront.c makelib: ( echo '#!/bin/sh'; \ echo 'lib="$$1"; shift';\ echo 'rm -f "$$lib"';\ echo 'ar cr "$$lib" $${1+"$$@"}';\ echo 'ranlib "$$lib"';\ ) >makelib chmod 755 makelib makeso: conf-ccso conf-ld ( echo '#!/bin/sh'; \ echo 'source=$$1; shift'; \ echo 'base=`echo "$$source" | sed -e s:\\\\.c$$::`'; \ echo exec `head -n 1 conf-ccso` -DSHARED -I. -L. '-o $${base}.so $$source $${1+"$$@"}'; \ ) >makeso chmod 755 makeso modules.o: compile modules.c mailfront-internal.h mailfront.h responses.h constants.h conf_modules.c ./compile modules.c plugin-add-received.so: makeso plugin-add-received.c mailfront.h responses.h constants.h ./makeso plugin-add-received.c -lbg plugin-check-fqdn.so: makeso plugin-check-fqdn.c mailfront.h responses.h constants.h ./makeso plugin-check-fqdn.c -lbg plugin-clamav.so: makeso plugin-clamav.c mailfront.h responses.h constants.h ./makeso plugin-clamav.c -lbg plugin-counters.so: makeso plugin-counters.c mailfront.h responses.h constants.h ./makeso plugin-counters.c -lbg plugin-cvm-authenticate.so: makeso plugin-cvm-authenticate.c mailfront.h responses.h constants.h ./makeso plugin-cvm-authenticate.c -lcvm-sasl -lcvm-v2client -lbg plugin-cvm-validate.so: makeso plugin-cvm-validate.c mailfront.h responses.h constants.h ./makeso plugin-cvm-validate.c -lcvm-v2client -lbg plugin-lua.so: makeso plugin-lua.c mailfront.h responses.h constants.h ./makeso plugin-lua.c -lbg -llua5.1 -I/usr/include/lua5.1 plugin-mailrules.so: makeso plugin-mailrules.c mailfront.h responses.h constants.h ./makeso plugin-mailrules.c -lbg plugin-patterns.so: makeso plugin-patterns.c mailfront.h responses.h constants.h ./makeso plugin-patterns.c -lbg plugin-qmail-validate.so: makeso plugin-qmail-validate.c mailfront.h responses.h constants.h conf_qmail.c ./makeso plugin-qmail-validate.c -lbg plugin-rbl.so: makeso plugin-rbl.c mailfront.h responses.h constants.h queuedir.c ./makeso plugin-rbl.c queuedir.c -lbg plugin-spamassassin.so: makeso plugin-spamassassin.c mailfront.h responses.h constants.h ./makeso plugin-spamassassin.c -lbg plugin-starttls-ucspi.so: makeso plugin-starttls-ucspi.c mailfront.h responses.h constants.h ./makeso plugin-starttls-ucspi.c -lbg pop3-capa.o: compile pop3-capa.c pop3.h constants.h ./compile pop3-capa.c pop3-mainloop.o: compile pop3-mainloop.c pop3.h constants.h ./compile pop3-mainloop.c pop3-response.o: compile pop3-response.c pop3.h constants.h ./compile pop3-response.c pop3.a: makelib iobytes.o timeout.o pop3-capa.o pop3-mainloop.o pop3-response.o ./makelib pop3.a iobytes.o timeout.o pop3-capa.o pop3-mainloop.o pop3-response.o pop3front-auth: pop3front-auth.o load pop3.a socket.lib ./load pop3front-auth pop3.a -lcvm-sasl -lcvm-v2client -lbg `cat socket.lib` pop3front-auth.o: compile pop3front-auth.c pop3.h constants.h ./compile pop3front-auth.c pop3front-maildir: pop3front-maildir.o load pop3.a ./load pop3front-maildir pop3.a -lbg -lcvm-sasl -lcvm-v2client pop3front-maildir.o: compile pop3front-maildir.c pop3.h constants.h ./compile pop3front-maildir.c programs: mailfront imapfront-auth pop3front-maildir pop3front-auth testcvm qmqpfront-echo smtpfront-echo qmtpfront-qmail qmtpfront-echo qmqpfront-qmail smtpfront-qmail protocol-qmqp.so: makeso protocol-qmqp.c mailfront.h responses.h constants.h qmtp.h qmtp-respond.c netstring.c ./makeso protocol-qmqp.c qmtp-respond.c netstring.c -lbg protocol-qmtp.so: makeso protocol-qmtp.c mailfront.h responses.h constants.h qmtp.h qmtp-respond.c netstring.c ./makeso protocol-qmtp.c qmtp-respond.c netstring.c -lbg protocol-smtp.so: makeso protocol-smtp.c mailfront.h responses.h constants.h ./makeso protocol-smtp.c -lbg qmqpfront-echo: warn-auto.sh qmqpfront-echo.sh cat warn-auto.sh qmqpfront-echo.sh >qmqpfront-echo chmod 755 qmqpfront-echo qmqpfront-qmail: warn-auto.sh qmqpfront-qmail.sh cat warn-auto.sh qmqpfront-qmail.sh >qmqpfront-qmail chmod 755 qmqpfront-qmail qmtpfront-echo: warn-auto.sh qmtpfront-echo.sh cat warn-auto.sh qmtpfront-echo.sh >qmtpfront-echo chmod 755 qmtpfront-echo qmtpfront-qmail: warn-auto.sh qmtpfront-qmail.sh cat warn-auto.sh qmtpfront-qmail.sh >qmtpfront-qmail chmod 755 qmtpfront-qmail responses.o: compile responses.c responses.h ./compile responses.c session.o: compile session.c mailfront-internal.h mailfront.h responses.h constants.h ./compile session.c smtpfront-echo: warn-auto.sh smtpfront-echo.sh cat warn-auto.sh smtpfront-echo.sh >smtpfront-echo chmod 755 smtpfront-echo smtpfront-qmail: warn-auto.sh smtpfront-qmail.sh cat warn-auto.sh smtpfront-qmail.sh >smtpfront-qmail chmod 755 smtpfront-qmail socket.lib: compile load @echo -n 'Checking for socket libraries: ' @echo 'main() { ; }' >trylib-lsocket.c @{ ./compile trylib-lsocket.c && ./load trylib-lsocket -lsocket -lnsl; } >/dev/null 2>&1 \ && { echo -lsocket -lnsl >socket.lib; echo -lsocket -lnsl; } \ || { : >socket.lib; echo no; } @rm -f trylib-lsocket.c trylib-lsocket.o trylib-lsocket testcvm: testcvm.o load ./load testcvm -lcvm-module -lbg testcvm.o: compile testcvm.c auto_testcvm.c ./compile testcvm.c timeout.o: compile timeout.c ./compile timeout.c mailfront-2.12/NEWS0000644000000000000000000005752612467132135011041 0ustar ------------------------------------------------------------------------------- Changes in version 2.12 - Added ability for rbl plugin to capture messages before rejecting them. - Fixed broken use of -lbg-sysdeps in modules. - Fixed missing plugin-rbl in installed image. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 2.11 - Updated for bglibs v2 Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 2.10 - Added new "rbl" plugin, to block messages from IPs in an RBL. - Added new "queuedir" backend, to save messages to simple files. - Make sure plugin reset functions get called before exiting. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 2.01 - Added missing plugin-starttls-ucspi to installed files. - Added support for limiting the number of messages to plugin-counters. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 2.00 - This version updates the plugin API to add new features: - Capabilities reported by the SMTP EHLO response can be added by plugins. - Plugins are passed any SMTP parameters given with the sender and recipient commands. - Plugins can add new commands to the SMTP protocol. Plugins compiled for previous versions of mailfront will not work without recompiling. The short-circuit on accept logic has also been eliminated to fix a semantic issue. - SMTP AUTH support has been moved into a new plugin, cvm-authenticate. Existing installations relying on SMTP AUTH support will need to make sure they are using this new plugin. The smtpfront-qmail wrapper has been modified to provide this additional plugin. - Fixed plugin-add-received to add the "IPv6:" prefix in the Received: header when the protocol is TCP6. - Added plugin starttls-ucspi to implement STARTTLS using ucspi-tls. - SMTP AUTH can now be restricted to TLS-enabled sessions. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.21 - Added controls for pop3front-auth to limit the number of USER commands and authentication failures allowed per session. - Added control to imapfront-auth to limit the number of authentication failures allowed per session. - Modified the clamav plugin to use the newer INSTREAM protocol. - imapfront-auth now sets $DOVECONF_ENV in Dovecot mode in order to avoid having Dovecot imapd reset it through doveconf. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.20 - Added Lua scripting plugin (optional, build with 'make lua'). - Modified the qmail backend to evaluate $QMAILQUEUE as late as possible. This allows more options for changing $QMAILQUEUE in plugins. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.18 - Added support for running Dovecot IMAP from imapfront-auth. See imapfront.html for details on how to set this up. - Moved more trivial plugins into builtins. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.17 - Added support for rejecting whole messages when the recipient count is exceeded in plugin-counters. - Made the check-fqdn plugin explicitly reject empty recipients. - Added a sender domain restriction to the check-fqdn plugin. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.16 - Added missing plugin-spamassassin.so to installation. - Fix bug in handling invalid message numbers in retrieving messages in pop3front-maildir. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.15 - Added a SpamAssassin scanning plugin. - Optimized pop3front-maildir to avoid stat'ing each message twice, and to use sizes recorded in the filename to avoid stat'ing entirely. See pop3front.html for details on the filenames. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.12 - Fixed problem with overwriting existing session data items. - Fixed several problems with handling of databytes in rules. - Fixed crash in plugin cvm-validate when the lookup secret was unset. - pop3front-auth now supports a no-argument variant on the AUTH command, used by KMail to test for authentication modes, and documented in http://www.tools.ietf.org/html/draft-myers-sasl-pop3-05 Thanks Bernhard Graf for the initial patch - pop3front-auth and -maildir now support the CAPA command. Thanks Bernhard Graf for the initial patch - Made imapfront-auth more compatible with Courier IMAP by adding extra bits to the CAPABILITY command. Thanks Bernhard Graf. - plugin-cvm-validate handles modules that provide an "out of scope" fact by passing to the next plugin. - Fixed handling of addresses without a domain in @file rules. Thanks Jorge Valdes Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.11 - Fixed the main mailfront program to clean up temporary files properly. - Modified the SMTP protocol module to export the SASL authentication information internally. - Modified the check-fqdn plugin to append $DEFAULTHOST and $DEFAULTDOMAIN to addresses if necessary. - Added separate connect and send timeouts and a maximum message size to the ClamAV plugin, and fixed a bug with handling port numbers when using multiple IPs. - Modified the ClamAV plugin to prefer $CLAMAV_* settings over $CLAMD_* - Added plugin API documentation. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.10 - Added a ClamAV virus scanner plugin. Note: Using this plugin will cause mailfront to save messages to temporary files. See mailfront.html for details. - Modified the plugin API to add a version code, a flags word, and to (optionally) save messages to a temporary file. - Fixed a few cases where the UCSPI-TCP protocol was assumed. - Fixed pop3front-maildir breakage on dietlibc/uClibc and empty maildirs. Thanks Wayne Marshall. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.01 - Fixed a bug in the counters plugin that triggered a problem in the SMTP protocol when handling the SIZE=# parameter. - Reversed the order of cvm-validate and qmail-validate in the wrapper scripts (and documentation) due to the semantics of the two plugins. - Added a list of built-in plugins. The list currently contains the three accept* plugins, which are extremely trivial. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 1.0 Mailfront has been rewritten to be totally modular. The core mailfront program loads the protocol, backend, and all plugin behaviors at run time from shared objects. The previous commands, such as smtpfront-qmail, are now shell script wrappers for the main "mailfront" command, and as such are depricated in favor of using "mailfront" directly. The *front-qmail wrappers preload all the plugins that were previously compiled into the corresponding programs: check-fqdn counters mailrules relayclient cvm-validate qmail-validate add-received patterns accept-sender NOTE: The *front-reject backends have been dropped in favor of a plugin. In addition, the $REQUIRE_AUTH feature has been moved to another plugin. If you used this backend or feature you will need to adjust your configuration accordingly. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.98.1 - Fixed the $REQUIRE_AUTH feature to properly check for $RELAYCLIENT being set. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.98 - Added enhanced mail system status codes (RFC 1893/2034). - Added support for rejecting all mail unless client is authenticated (either as a relay client or with SMTP authentication) if $REQUIRE_AUTH is set. - Full domain names are now required in all addresses except for the null sender. - Removed the "bounce must have a single recipient" rule, as it is currently causing more problems (with address checkers) than it is solving (spammers no longer use this technique). - Fixed one-off bug in counting recipients for $MAXRCPTS. - Truncate UIDL responses to 70 characters as per RFC 1939. - Added QMQP and QMTP "reject" front ends, for completeness. The enhanced mail system status codes together with the $REQUIRE_AUTH change should make smtpfront compliant with RFC 2476's requirements for a "message submission agent", suitable for use on TCP port 587. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.97 - Add support to the qmail backend for custom qmail-queue error messages taken from $QQERRMSG_#. - Clear session timeouts (via alarm) before executing authenticated commands in imapfront-auth and pop3front-auth. - Fixed typo in the CVM lookup code that would prevent the proper operation of lookup secrets. Thanks Dale Woolridge. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.96 - Switched Pattern matching from the simpler mechanism (originated in multilog) to standard shell glob. - Fixed the SMTP front-end's inability to handle quoted or escaped characters, or to strip source routing addresses. - Fixed smtpfront-reject crashing on receipt of EHLO. Thanks Janos Farkas. - Fixed extern/static conflict in smtp-respond.c. Thanks Gerrit Pape. NOTE: The pattern matching change has the (small) potential to break existing rules' behavior, if the rules were depending on specific behavior of the more simplistic pattern matching used previously. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.95 - Fixed bug in header pattern matching that made it only look at the first header line. Thanks Janos Farkas. - Fixed bug in handling of environment variables when applying multiple rules to the same message. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.94 - Switched to CVM 2 support. - Added support for restricting patterns to match only in headers. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.93 - Fixed bug in pattern matching where the pattern was longer than the line that would other match. - Fixed bug in parsing the databytes column in mail rules. - Fixed omission of not resetting maxdatabytes, which could be set by a rule, after checking for sender rules. - Fixed bug in handling multiple sender or recipient specific rules. - Modified the CVM lookup secret handling to use $CVM_LOOKUP_SECRET just like the latest CVM code, falling back to $LOOKUP_SECRET if that isn't set. - Added seperate $AUTH_TIMEOUT and $AUTH_SESSION_TIMEOUT overrides for the authentication front-ends (imapfront-auth and pop3front-auth). Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.92 - Fixed bug in QMQP front-end that prevented it from accepting relayed messages (relayclient wasn't getting set properly). - Added qmqpfront-echo and qmtpfront-echo test front-ends, for completeness. - Fixed bug in pattern handling that would cause a bogus "out of memory" error if the patterns file had a blank line. - Fixed bug: Only set $MAILDIR in imapfront-auth if the CVM set it. Thanks Charlie Brady. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.91 - Fixed a bug in the CVM lookup code that would cause failures if $LOOKUP_SECRET was not set. Thanks Bernhard Graf. - Explicitly set $MAILDIR in imapfront-auth, to provide the variable for Courier-IMAP's imapd. Thanks Bernhard Graf. - Fixed the generated Received: headers to always put the remote host name in the comment if tcpserver looked it up. This fixes problems with SpamAssassin flagging messages as having forged sender addresses. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.90 - Added support for explicit application of mail rules to senders or recipients, as well as negation of rule patterns. - Fixed a bug in handling patterns that are not after a blank line. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.89 - Added support for content pattern rejection. - Added a new "no-op" mail rule type. - Defer looking up $MAXRCPTS and $RELAYCLIENT as well so that they can be set in the mailrules. - Drop connections after $MAXNOTIMPL unimplemented commands are given. - The qmail home directory may be overridden with $QMAILHOME. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.88 - Fixed handling of "@domain" entries in mailrules lists and CDB files. - Added patch from Marcelo Augusto to allow for limits on the maximum number of recipients per message. - Defer looking up $MAXHOPS and $HEADER_ADD so that they can be set in the mailrules. - Added support for IMAP string literals in imapfront-auth. - smtpfront now exports CVM environment variables after authentication. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.87 - Fixed a bug that prevented looping email detection from working. - Fixed the Received: header generation to match the syntax described in RFC 2821. - Added the link protocol (ie TCP or TCP6) to the Received: header. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.86 - Allow for addition of user-specified headers with $HEADER_ADD. - SMTP front end now logs invalid commands. - Added a hook for CVM validation of recipient addresses. - Added support for RFC 1870 ESMTP SIZE extension. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.85 - Added a QMTP front-end, with many features in common with the SMTP front-end (excluding authentication, of course). - Added a QMQP front-end. - The front-ends optionally add an extra "fixup" Received: header if $FIXUP_RECEIVED_HOST and $FIXUP_RECEIVED_IP are set and differ from $TCPLOCALHOST and $TCPLOCALIP. - Fixed internal variable transposition bug in smtp-commands.c. - Switched to bglibs 1.006 library scheme. - Fixed bug: aborting DATA command does not work, must only give responses once all the data is received. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.81 - Fixed bug: the qmail backend didn't honour $QMAILQUEUE. - Fixed bug: environment variables set multiple times in mail rules would use the first value. - Fixed bug: databytes would not be set internally if $DATABYTES was not set. - Fixed bug: all bounces following the first in a single connection would be rejected. - Fixed bug: The "*" pattern failed to match the empty string. - Abort the DATA command immediately if the databytes limit is reached. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.80 - Fixed bug: setting $SMTPGREETING caused smtpfront to crash when issued HELO or EHLO commands. - Fixed bug: lookups in badmailfrom in smtpfront-qmail did not properly lowercase the address. - Fixed bug: qmail-validate didn't handle wildcards in rcpthosts or morercpthosts.cdb. - Added sender and recipient pattern matching to all SMTP front-ends. See mailrules.html for full details. Development of this version has been sponsored by Mitel Networks Corporation. http://www.mitel.com/ http://www.e-smith.com/ ------------------------------------------------------------------------------- Changes in version 0.77 - Added missing imapfront-auth to insthier. - Made smtpfront-qmail handle wildcards in badrcptto. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.76 - Fixed missing "OK" bug in imapfront-auth. - Log SASL authenticated credentials and failures. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.75 - Modified pop3front to log all commands and responses. - Added support for $SMTPGREETING to smtpfront. - Added an IMAP front end. Works with Courier IMAP presently. - Switched to using external bglibs. - smtpfront rejects bounce messages with multiple recipients. See http://www.ornl.gov/its/archives/mailing-lists/qmail/2001/12/msg00405.html - Added a session timeout, controlled by $SESSION_TIMEOUT, defaults to 24 hours. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.74 - Modified quit code in pop3front to properly tag only read messages as "read". - Implemented the obsolete LAST command. - Messages are now sorted in numerical order of their UID. - Added an exit hook to both pop3front and smtpfront to print the number of bytes input and output. - Fixed a one-off bug in handling "@domain" entries in badmailfrom in smtpfront-qmail. - pop3front-auth now logs the user name. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.73 - Fixed bugs in the RETR/TOP function of pop3front-maildir which would cause message corruption. - Fixed bugs in the DELE/STAT functions of pop3front-maildir which neglected to remove the deleted message count/bytes from the totals reported by STAT. - Added a "maximum message count" option to pop3front-maildir, which limits the number of visible messages. - Added timeouts to pop3front. - All POP3 error responses are now printed to stderr. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.72 - This version includes a one-off bug fix in the CVM client code. - Added the missing pop3front-* targets in insthier.c - Added missing Solaris/SysV -lsocket -lnsl linker flags. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.71 - Log the parameters to the MAIL and RCPT commands in smtpfront. - Fixed missing lowercase conversion when handling validating domain names against rcpthosts and company. - Fixed a number of bugs in the SASL implementation. SMTP AUTH PLAIN and/or LOGIN have now been tested with Mozilla Mail (PLAIN), Pegasus (PLAIN I think), PMMail (LOGIN), The Bat (PLAIN), Eudora (LOGIN), and Outlook Express (LOGIN). Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.70 - Added a POP3 authenticator and maildir handler, complete with support for the RFC 1734 AUTH command. If you can believe it, the maildir portion is actually smaller than qmail-pop3d, and just as functional! - Fixed the AUTH PLAIN mechanism in the cvm-sasl library. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- Changes in version 0.60 - Adds support for the SMTP AUTH command, supporting LOGIN, PLAIN, and CRAM-MD5 mechanisms via CVM. Development of this version has been sponsored by FutureQuest, Inc. ossi@FutureQuest.net http://www.FutureQuest.net/ ------------------------------------------------------------------------------- mailfront-2.12/README0000644000000000000000000000742512467132135011213 0ustar mailfront Mail server network protocol front-ends Bruce Guenter Version 2.12 2015-02-12 This is mailfront, a package containing customizeable network front-ends for mail servers. It contains complete SMTP, QMQP, QMTP, and POP3 front-ends as well as an authentication module for IMAP. The mail delivery front-ends also contain internal address filtering features. Two SMTP back-ends are provided. One delivers mail to qmail-queue, mimicking most of the behavior of qmail-smtpd, with the addition of support for SMTP AUTH. The other rejects all SMTP commands if $SMTPREJECT is set, and execs its command line otherwise (in order to run the above program). A mailing list has been set up to discuss this and other packages. To subscribe, send an email to: bgware-subscribe@lists.untroubled.org A mailing list archive is available at: http://lists.untroubled.org/?list=bgware Development versions of mailfront are available at: https://github.com/bruceg/mailfront Requirements: - bglibs version 2.01 - cvm version 0.97 - Lua version 5 or later (optional) Installation: - Build the sources by running "make". - To build the Lua plugin, run "make lua". - After the package has been compiled, run "make install" as root. Configuration: - To take advantage of the SMTP AUTH features, make sure you have a CVM authentication program (some are included with the cvm package itself). - Run a CVM authentication module to provide the AUTH feature. Example: To run cvm-vmailmgr as a daemon: exec /usr/local/bin/softlimit -m 9000000 \ /usr/local/bin/cvm-vmailmgr /tmp/.cvm-vmailmgr 2>&1 - Configure your mail system to use the SMTP back-end with the appropriate environment variables. Example using tcpserver (highly recommended): #!/bin/sh QMAILDUID=`id -u qmaild` NOFILESGID=`id -g qmaild` MAXSMTPD=`head -1 /var/qmail/control/concurrencyincoming` if [ -z "$QMAILDUID" -o -z "$NOFILESGID" -o -z "$MAXSMTPD" ]; then echo $0: QMAILDUID, NOFILESGID, or MAXSMTPD is unset exit 1 fi exec \ /usr/local/bin/envdir /etc/smtpfront \ /usr/local/bin/softlimit -m 2000000 \ /usr/local/bin/tcpserver -v -R -H \ -l "`head -1 /var/qmail/control/me`" -x /etc/tcp.smtp.cdb \ -c "$MAXSMTPD" -u "$QMAILDUID" -g "$NOFILESGID" 0 25 \ /usr/local/bin/smtpfront-qmail 2>&1 /etc/smtpfront/CVM_SASL_PLAIN: cvm-local:/tmp/.cvm-vmailmgr Example using xinetd with TCP Wrappers: /etc/xinetd.d/smtp: # default: on # description: smtp service smtp { disable = no flags = REUSE NAMEINARGS socket_type = stream protocol = tcp wait = no user = qmaild server = /usr/sbin/tcpd server_args = /var/qmail/bin/tcp-env -R /usr/local/sbin/smtpfront-wrapper log_on_success += USERID log_on_failure += USERID } /usr/local/sbin/smtpfront-wrapper: #!/bin/sh CVM_SASL_PLAIN=cvm-local:/tmp/.cvm-unix export CVM_SASL_PLAIN CVM_SASL_LOGIN=cvm-local:/tmp/.cvm-unix export CVM_SASL_LOGIN exec /usr/local/bin/smtpfront-qmail 2>> /tmp/smtpfront-errs.txt This project was initiated at FutureQuest, Inc. We are releasing it as an open-source project because we felt it would be useful to others, as well as to repay our debt of gratitude to the larger open-source community for the excellent packages we have enjoyed. For more details, you may contact FutureQuest, Inc. at: FutureQuest, Inc. PO BOX 623127 Oviedo FL 32762-3127 USA http://www.FutureQuest.net/ ossi@FutureQuest.net This package is Copyright(C) 2015 Bruce Guenter or FutureQuest, Inc., and may be copied according to the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 or a later version. A copy of this license is included with this package. This package comes with no warranty of any kind. mailfront-2.12/SRCFILES0000644000000000000000000000143212467132135011460 0ustar INSTHIER backend-echo.c backend-qmail.c backend-queuedir.c builtins.c conf-modules constants.h getprotoenv.c imapfront-auth.c iobytes.c mailfront-internal.h mailfront.c mailfront.h modules.c netstring.c plugin-add-received.c plugin-check-fqdn.c plugin-clamav.c plugin-counters.c plugin-cvm-authenticate.c plugin-cvm-validate.c plugin-lua.c plugin-mailrules.c plugin-patterns.c plugin-qmail-validate.c plugin-rbl.c plugin-spamassassin.c plugin-starttls-ucspi.c pop3-capa.c pop3-mainloop.c pop3-response.c pop3.h pop3front-auth.c pop3front-maildir.c protocol-qmqp.c protocol-qmtp.c protocol-smtp.c qmqpfront-echo.sh qmqpfront-qmail.sh qmtp-respond.c qmtp.h qmtpfront-echo.sh qmtpfront-qmail.sh queuedir.c responses.c responses.h session.c smtpfront-echo.sh smtpfront-qmail.sh testcvm.c timeout.c mailfront-2.12/TARGETS0000644000000000000000000000156312467132135011364 0ustar all auto_testcvm.c backend-echo.so backend-qmail.so backend-queuedir.so builtins.o clean clean-spac compile conf_modules.c conf_qmail.c dl.lib docs getprotoenv.o imapfront-auth imapfront-auth.o install iobytes.o libraries load lua mailfront mailfront.o makelib makeso modules.o plugin-add-received.so plugin-check-fqdn.so plugin-clamav.so plugin-counters.so plugin-cvm-authenticate.so plugin-cvm-validate.so plugin-lua.so plugin-mailrules.so plugin-patterns.so plugin-qmail-validate.so plugin-rbl.so plugin-spamassassin.so plugin-starttls-ucspi.so pop3-capa.o pop3-mainloop.o pop3-response.o pop3.a pop3front-auth pop3front-auth.o pop3front-maildir pop3front-maildir.o programs protocol-qmqp.so protocol-qmtp.so protocol-smtp.so qmqpfront-echo qmqpfront-qmail qmtpfront-echo qmtpfront-qmail responses.o session.o smtpfront-echo smtpfront-qmail socket.lib testcvm testcvm.o timeout.o mailfront-2.12/TODO0000644000000000000000000000250612467132135011016 0ustar - Fix SASL "Authentication failed" message to include EMSS code - Write install document. - Build up TLS support. - Tests: - Test application of environment variables in mail rules - Add hooks for plugins to load or (temporarily) disable the operation of other plugins? New plugin: starttls - Add support for RFC 2487 STARTTLS as a plugin Plugin: clamav - Add tests (not sure how to emulate the daemon properly) Plugin: lua - Fix hooks that can modify strings to actually allow modification Plugin: patterns - Add better MIME attachment discrimination to patterns, instead of just keying on a blank line. Plugin: mailrules - Add variable substitution to rule variable setting (ie x=${y} etc) - Allow selecting based on authentication state. Protocol: SMTP - Build a shared routine for breaking out the domain name. - Add RFC 2034/3463 enhanced status codes to all responses. - Add some information about authentication into the headers (?) - Handle $LOCALIPHOST (all back-ends): rewrite envelope recipient addresses of the form box@[a.b.c.d], where a.b.c.d is a local IP address, to box@$LOCALIPHOST. (low priority) - pop3front: - Properly re-parse flags in cmd_quit - Split the generic protocol handling bits from pop3front-maildir (low priority -- who wants anything but maildir?) mailfront-2.12/VERSION0000644000000000000000000000001712467132135011371 0ustar mailfront 2.12 mailfront-2.12/backend-echo.c0000644000000000000000000000417712467132135013003 0ustar #include #include #include #include #include #include #include "mailfront.h" static response resp = { 250, 0 }; static str tmp; static unsigned long databytes = 0; static const response* reset(void) { databytes = 0; return 0; } static int str_cat_params(str* s, const str* param) { striter i; striter_loop(&i, param, 0) if (!str_cat3s(s, " [", i.startptr, "]")) return 0; return 1; } static const response* sender(str* s, str* params) { str_copys(&tmp, "Sender='"); str_cat(&tmp, s); str_cats(&tmp, "'."); str_cat_params(&tmp, params); resp.message = tmp.s; return &resp; } static const response* recipient(str* r, str* params) { str_copys(&tmp, "Recipient='"); str_cat(&tmp, r); str_cats(&tmp, "'."); str_cat_params(&tmp, params); resp.message = tmp.s; return &resp; } static const response* data_block(const char* bytes, unsigned long len) { if (databytes == 0) { /* First line is always Received, log the first two lines. */ const char* ch; ch = strchr(bytes, '\n'); str_copyb(&tmp, bytes, ch-bytes); bytes = ch + 1; if ((ch = strchr(bytes, '\n')) != 0) str_catb(&tmp, bytes, ch-bytes); msg1(tmp.s); } databytes += len; return 0; } static const response* message_end(int fd) { struct stat st; char buf[1024]; long rd; char* lf; char* ptr; if (fd >= 0) { /* Log the first two lines of the message, usually a Received: header */ lseek(fd, 0, SEEK_SET); rd = read(fd, buf, sizeof buf - 1); buf[rd] = 0; if ((lf = strchr(buf, LF)) != 0) { str_copyb(&tmp, buf, lf-buf); ptr = lf + 1; if ((lf = strchr(ptr, LF)) != 0) str_catb(&tmp, ptr, lf-ptr); msg1(tmp.s); } fstat(fd, &st); databytes = st.st_size; } str_copys(&tmp, "Received "); str_catu(&tmp, databytes); str_cats(&tmp, " bytes."); resp.message = tmp.s; return &resp; (void)fd; } struct plugin backend = { .version = PLUGIN_VERSION, .reset = reset, .sender = sender, .recipient = recipient, .data_block = data_block, .message_end = message_end, }; mailfront-2.12/backend-echo.html0000644000000000000000000000056512467132135013522 0ustar

Mailfront

Backend: echo


The echo backend is a very simple module that does no delivery at all. Instead it just echos the sender, recipients, data, and the number of bytes in the message into the logs. Its primary use is for testing, when delivering a message is not necessary.

mailfront-2.12/backend-qmail.c0000644000000000000000000001367412467132135013172 0ustar #include #include #include #include #include #include #include #include #include #include "mailfront.h" #include "conf_qmail.c" static RESPONSE(no_write,451,"4.3.0 Writing data to qmail-queue failed."); static RESPONSE(no_pipe,451,"4.3.0 Could not open pipe to qmail-queue."); static RESPONSE(no_fork,451,"4.3.0 Could not start qmail-queue."); static RESPONSE(no_chdir,451,"4.3.0 Could not change to the qmail directory."); static RESPONSE(qq_crashed,451,"4.3.0 qmail-queue crashed."); static str buffer; static unsigned long databytes; static const char* qqargs[2] = { 0, 0 }; static int qqpid = -1; static int qqepipe[2] = { -1, -1 }; static int qqmpipe[2] = { -1, -1 }; static void close_qqpipe(void) { if (qqepipe[0] != -1) close(qqepipe[0]); if (qqepipe[1] != -1) close(qqepipe[1]); if (qqmpipe[0] != -1) close(qqmpipe[0]); if (qqmpipe[1] != -1) close(qqmpipe[1]); qqepipe[0] = qqepipe[1] = qqmpipe[0] = qqmpipe[1] = -1; } static const response* reset(void) { close_qqpipe(); str_truncate(&buffer, 0); return 0; } static const response* do_sender(str* sender, str* params) { if (!str_catc(&buffer, 'F') || !str_cat(&buffer, sender) || !str_catc(&buffer, 0)) return &resp_oom; return 0; (void)params; } static const response* do_recipient(str* recipient, str* params) { if (!str_catc(&buffer, 'T') || !str_cat(&buffer, recipient) || !str_catc(&buffer, 0)) return &resp_oom; return 0; (void)params; } static const response *start_qq(int msgfd, int envfd) { const char* qh; qqargs[0] = session_getenv("QMAILQUEUE"); if (qqargs[0] == 0) qqargs[0] = "bin/qmail-queue"; if ((qh = session_getenv("QMAILHOME")) == 0) qh = conf_qmail; if (chdir(qh) == -1) return &resp_no_chdir; if ((qqpid = fork()) == -1) { close_qqpipe(); return &resp_no_fork; } if (qqpid == 0) { if (!session_exportenv()) exit(51); if (dup2(msgfd, 0) == -1) exit(120); if (dup2(envfd, 1) == -1) exit(120); close_qqpipe(); execvp(qqargs[0], (char**)qqargs); exit(120); } return 0; } static const response* data_start(int fd) { const response* resp_qq; sig_pipe_block(); if (pipe(qqepipe) == -1) return &resp_no_pipe; if (fd < 0) { if (pipe(qqmpipe) == -1) { close_qqpipe(); return &resp_no_pipe; } resp_qq = start_qq(qqmpipe[0], qqepipe[0]); if (resp_qq != 0) { return resp_qq; } } databytes = 0; return 0; (void)fd; } static int retry_write(int fd, const char* bytes, unsigned long len) { while (len) { unsigned long written = write(fd, bytes, len); if (written == (unsigned long)-1) return 0; len -= written; bytes += written; } return 1; } static const response* data_block(const char* bytes, unsigned long len) { if (qqmpipe[1] >= 0) { if (!retry_write(qqmpipe[1], bytes, len)) return &resp_no_write; databytes += len; } return 0; } static void parse_status(int status, response* resp) { char var[20]; const char* message; resp->number = (status <= 40 && status >= 11) ? 554 : 451; memcpy(var, "QQERRMSG_", 9); strcpy(var+9, utoa(status)); if ((message = session_getenv(var)) == 0) { switch (status) { case 11: message = "5.1.3 Address too long."; break; case 31: message = "5.3.0 Message refused."; break; case 51: message = "4.3.0 Out of memory."; break; case 52: message = "4.3.0 Timeout."; break; case 53: message = "4.3.0 Write error (queue full?)."; break; case 54: message = "4.3.0 Unable to read the message or envelope."; break; case 55: message = "4.3.0 Unable to read a configuration file."; break; case 56: message = "4.3.0 Network problem."; break; case 61: message = "4.3.0 Problem with the qmail home directory."; break; case 62: message = "4.3.0 Problem with the qmail queue directory."; break; case 63: message = "4.3.0 Problem with queue/pid."; break; case 64: message = "4.3.0 Problem with queue/mess."; break; case 65: message = "4.3.0 Problem with queue/intd."; break; case 66: message = "4.3.0 Problem with queue/todo."; break; case 71: message = "4.3.0 Message refused by mail server."; break; case 72: message = "4.3.0 Connection to mail server timed out."; break; case 73: message = "4.3.0 Connection to mail server rejected."; break; case 74: message = "4.3.0 Communication with mail server failed."; break; case 81: message = "4.3.0 Internal qmail-queue bug."; break; case 91: message = "4.3.0 Envelope format error."; break; default: message = (resp->number >= 500) ? "5.3.0 Message rejected by qmail-queue." : "4.3.0 Temporary qmail-queue failure."; } } resp->message = message; } static const response* message_end(int fd) { static response resp; const response* resp_qq; int status; struct stat st; if (fd < 0) { close(qqmpipe[1]); qqmpipe[1] = -1; } else { if (lseek(fd, 0, SEEK_SET) != 0) return &resp_internal; if (fstat(fd, &st) != 0) return &resp_internal; databytes = st.st_size; resp_qq = start_qq(fd, qqepipe[0]); if (resp_qq != 0) { return resp_qq; } } if (!retry_write(qqepipe[1], buffer.s, buffer.len+1)) return &resp_no_write; close_qqpipe(); if (waitpid(qqpid, &status, WUNTRACED) == -1) return &resp_qq_crashed; if (!WIFEXITED(status)) return &resp_qq_crashed; if ((status = WEXITSTATUS(status)) != 0) parse_status(status, &resp); else { str_copys(&buffer, "2.6.0 Accepted message qp "); str_catu(&buffer, qqpid); str_cats(&buffer, " bytes "); str_catu(&buffer, databytes); msg1(buffer.s); resp.number = 250; resp.message = buffer.s; } return &resp; (void)fd; } struct plugin backend = { .version = PLUGIN_VERSION, .reset = reset, .sender = do_sender, .recipient = do_recipient, .data_start = data_start, .data_block = data_block, .message_end = message_end, }; mailfront-2.12/backend-qmail.html0000644000000000000000000000144112467132135013701 0ustar

Mailfront

Backend: qmail


Features:

  • The qmail home directory is compiled into the program, and defaults to /var/qmail, but may be overridden by $QMAILHOME.
  • Messages are delivered through the executable named in $QMAILQUEUE, or $QMAILHOME/bin/qmail-queue if it is not set.
  • If qmail-queue exits non-zero, the qmail backend looks for an error message in $QQERRMSG_#, where # is the exit code of qmail-queue. As usual, exit codes between 11 and 40 indicate permanent errors, and all others indicate temporary errors.
  • The qmail-queue PID is logged in success messages for correlation with the qmail logs.
mailfront-2.12/backend-queuedir.c0000644000000000000000000000057612467132135013707 0ustar #include "mailfront.h" static const response* init(void) { queuedir_init("QUEUEDIR"); return 0; } struct plugin backend = { .version = PLUGIN_VERSION, .init = init, .reset = queuedir_reset, .sender = queuedir_sender, .recipient = queuedir_recipient, .data_start = queuedir_data_start, .data_block = queuedir_data_block, .message_end = queuedir_message_end, }; mailfront-2.12/backend-queuedir.html0000644000000000000000000000220212467132135014415 0ustar

mailfront

Backend: queuedir


This backend writes messages into individual files in a named directory. The files are written to temporary files with unique filenames and moved into the final directory when the contents are complete.

The file format is as follows:

  1. The envelope sender address, followed by a NUL byte.
  2. A list of envelope recipient addresses, each followed by a NUL byte.
  3. A terminating NUL byte.
  4. The full message data.

Configuration

$QUEUEDIR
The destination top-level directory under which messages are written.
$QUEUEDIR_DEST
The subdirectory of $QUEUEDIR into which completed messages are moved. (defaults to "new")
$QUEUEDIR_NOSYNC
If set, the destination file is not synced to disk before the backend reports success.
$QUEUEDIR_TMP
The subdirectory of $QUEUEDIR into which temporary files are written. (defaults to "tmp")
mailfront-2.12/builtins.c0000644000000000000000000000337612467132135012331 0ustar #include #include "mailfront-internal.h" static RESPONSE(accept,250,0); static RESPONSE(ok, 250, 0); static RESPONSE(mustauth, 530, "5.7.1 You must authenticate first."); static response resp; static const response* accept(str* s, str* params) { return &resp_accept; (void)s; (void)params; } static const response* reject(str* s, str* params) { const char* sr; if ((sr = session_getenv("SMTPREJECT")) != 0 || (sr = session_getenv("REJECT")) != 0) { if (sr[0] == '-') { ++sr; resp.number = 553; } else resp.number = 451; resp.message = (sr[0] != 0) ? sr : "You are not allowed to use this mail server."; return &resp; } return 0; (void)s; (void)params; } static const response* relayclient_recip(str* recipient, str* params) { const char* relayclient = session_getenv("RELAYCLIENT"); if (relayclient != 0) { str_cats(recipient, relayclient); return &resp_ok; } else if (session_getnum("authenticated", 0)) return &resp_ok; return 0; (void)params; } static const response* require_auth(str* s, str* params) { if (!session_getnum("authenticated", 0) && session_getenv("RELAYCLIENT") == 0) return &resp_mustauth; return 0; (void)s; (void)params; } struct plugin builtin_plugins[] = { { .name = "accept", .sender = accept, .recipient = accept, }, { .name = "accept-recipient", .recipient = accept, }, { .name = "accept-sender", .sender = accept, }, { .name = "force-file", .flags = FLAG_NEED_FILE, }, { .name = "reject", .sender = reject, }, { .name = "relayclient", .recipient = relayclient_recip, }, { .name = "require-auth", .sender = require_auth, }, { .name = 0 } }; mailfront-2.12/conf-bin0000644000000000000000000000007612467132135011744 0ustar /usr/local/bin Programs will be installed in this directory. mailfront-2.12/conf-cc0000644000000000000000000000010412467132135011551 0ustar gcc -W -Wall -Wshadow -O -g This will be used to compile .c files. mailfront-2.12/conf-ccso0000644000000000000000000000017312467132135012121 0ustar gcc -W -Wall -Wshadow -O -g -I/usr/local/include -fPIC -shared This will be used to compile .c files into shared objects. mailfront-2.12/conf-include0000644000000000000000000000011012467132135012604 0ustar /usr/local/include C header files will be installed in this directory. mailfront-2.12/conf-ld0000644000000000000000000000010612467132135011565 0ustar gcc -s This will be used to link .o and .a files into an executable. mailfront-2.12/conf-modules0000644000000000000000000000010712467132135012637 0ustar /usr/local/lib/mailfront Modules will be installed in this directory. mailfront-2.12/conf-qmail0000644000000000000000000000005612467132135012275 0ustar /var/qmail This is the qmail home directory. mailfront-2.12/constants.h0000644000000000000000000000045212467132135012511 0ustar #ifndef MAIL_FRONT__CONSTANTS__H__ #define MAIL_FRONT__CONSTANTS__H__ #define AT '@' #define CR ((char)13) #define LF ((char)10) #define SPACE ((char)32) #define TAB ((char)9) #define COLON ':' #define LBRACE '<' #define RBRACE '>' #define PERIOD '.' #define ESCAPE '\\' #define QUOTE '"' #endif mailfront-2.12/debian/0000755000000000000000000000000013213777177011560 5ustar mailfront-2.12/debian/changelog0000644000000000000000000002060113213777177013431 0ustar mailfront (2.12-0.1) unstable; urgency=medium * Non-maintainer upload * Drop patches, upstream * Disable rbl tests, they seems to be flaky and requiring an internet connection (moreover, the rbl plugin is a new one). * New upstream release, fixing the bglibs incompatibility (Closes: #831596) * Change build-dependency to pick up unversioned libbg-dev package * Add lua dependency and plugin -- Gianfranco Costamagna Tue, 12 Dec 2017 17:06:23 +0100 mailfront (1.16-1.1) unstable; urgency=medium * Non-maintainer upload. * Apply patches from myself and Valerie Young to make build reproducible. (Closes: #777431, #847020) -- Chris Lamb Thu, 28 Sep 2017 09:38:21 +0100 mailfront (1.16-1) unstable; urgency=low * new upstream version. -- Gerrit Pape Thu, 15 Apr 2010 01:32:03 +0000 mailfront (1.11-1) unstable; urgency=low * debian/control: fix spelling in long description (thx Simon Waters, closes: #390053). * new upstream version. * debian/rules: adapt. * debian/diff/no-sfqmail-tests.diff,debian/diff/tests-find-sort.diff: remove; obsolete. * debian/implicit: update to revision a09db2e. * debian/README.Debian.diet: remove for now. * debian/mailfront.docs: remove debian/README.Debian.diet. * debian/control: Build-Depends: libbg1-dev, libcvm1-dev; Standards-Version: 3.7.3.0. * debian/diff/0001-Makefile-avoid-rpath.diff: new; Makefile: avoid rpath. -- Gerrit Pape Sat, 03 May 2008 07:09:38 +0000 mailfront (0.98-2) unstable; urgency=low * debian/diff/tests-find-sort.diff: new: sort output from find (closes: #361557). -- Gerrit Pape Sun, 16 Apr 2006 13:31:57 +0000 mailfront (0.98-1) unstable; urgency=low * new upstream version. * debian/diff/no-sfqmail-tests.diff: adapt. -- Gerrit Pape Wed, 2 Nov 2005 20:54:07 +0000 mailfront (0.97-1) unstable; urgency=low * new upstream version. * debian/control: Standards-Version: 3.6.2.0. * debian/rules: cleanup. -- Gerrit Pape Wed, 5 Oct 2005 11:33:18 +0000 mailfront (0.96-1) unstable; urgency=low * new upstream version. * debian/diff/static-vs-global.diff: remove; fixed upstream. * debian/mailfront.NEWS.Debian: new; note about pattern matching change. -- Gerrit Pape Sun, 17 Jul 2005 19:58:10 +0000 mailfront (0.95-1) unstable; urgency=low * new upstream version. * debian/control: Build-Depends: bglibs-dev (>> 1.022-0); Build-Depends: cvm (>> 0.71-0), freecdb for selftests. * debian/diff/no-sfqmail-tests.diff: new; skip smtpfront-auth-login and smtpfront-auth-plain selftests. * debian/rules: install: don't install target directories, make install now does; use $install_prefix with new bg-installer; build: run selftests. -- Gerrit Pape Fri, 17 Jun 2005 16:27:24 +0000 mailfront (0.94-1) unstable; urgency=low * new upstream version. * debian/control: Build-Depends: bglibs-dev (>> 1.020-0), cvm-dev (>> 0.71-0). * debian/diff/diet-pop3front.diff: remove; obsolete (with dietlibc 0.29). * debian/rules: use upstream install target. -- Gerrit Pape Mon, 6 Jun 2005 18:39:02 +0000 mailfront (0.93-1) unstable; urgency=low * new upstream version. * debian/control: remove version restrictions from Build-Depends: bglibs-dev, cvm-dev. * debian/copyright: 2005. * debian/diff/svn-20041206.diff: remove; obsolete. * debian/diff/diet-pop3front.diff: new; fix linker failure with diet libc with programs that have main() in pop3-mainloop.o, included in pop3.a archive. -- Gerrit Pape Sun, 24 Apr 2005 16:57:49 +0000 mailfront (0.92-3) unstable; urgency=low * debian/diff/static-vs-global.diff: new; rename static variable which also is defined globally (closes: #287632). * debian/README.Debian.diet: typo. * debian/control: start short description lowercase. * debian/rules: cleanup; handle patches and configure stage more gracefully. * debian/etc/smtpfront-qmail/log/run: let svlogd add human-readable timestamps. -- Gerrit Pape Thu, 27 Jan 2005 09:00:57 +0000 mailfront (0.92-2) unstable; urgency=low * debian/diff/svn-20041206.diff: new; bug fixes from upstream svn: - Fixed bug in pattern matching where the pattern was longer than the line that would other match. - Fixed bug in parsing the databytes column in mail rules. - Fixed omission of not resetting maxdatabytes, which could be set by a rule, after checking for sender rules. - Fixed bug in handling multiple sender or recipient specific rules. - Modified the CVM lookup secret handling to use $CVM_LOOKUP_SECRET just like the latest CVM code, falling back to $LOOKUP_SECRET if that isn't set. * debian/rules: enable target patch-stamp. -- Gerrit Pape Mon, 6 Dec 2004 13:18:23 +0000 mailfront (0.92-1) unstable; urgency=low * new upstream version. * debian/rules: support "diet" in DEB_BUILD_OPTIONS; add target configure-stamp; disable target patch-stamp; cleanup. * debian/diff/patterns.diff: remove; fixed upstream. * debian/implicit: update to revision 1.10. * debian/copyright: minor. * debian/control: Build-Depends: bglibs-dev (>> 1.018-0), cvm-dev (>> 0.20-0). * debian/README.Debian.diet: new; how to build package with diet libc. * debian/mailfront.docs: add debian/README.Debian.diet. -- Gerrit Pape Sun, 7 Nov 2004 12:09:43 +0000 mailfront (0.91-1) unstable; urgency=low * new upstream version. * debian/rules: Build-Depends: bglibs-dev (>> 1.017-0); enable target patch-stamp. * debian/implicit: update to revision 1.8. * debian/diff/patterns.diff: new; see: http://thread.gmane.org/gmane.comp.sysutils.bgware/1443 -- Gerrit Pape Tue, 30 Mar 2004 13:17:51 +0000 mailfront (0.90-1) unstable; urgency=low * new upstream version. * debian/implicit: update to revision 1.5. * debian/mailfront.docs: add html docs; install html documentation into /usr/share/doc/mailfront/ (no subdirectory). * debian/htmldocs: remove; obsolete. * debian/rules: don't explicitly install htmldocs, use implicit rules; minor. -- Gerrit Pape Tue, 10 Feb 2004 11:01:19 +0000 mailfront (0.88-2) unstable; urgency=low * debian/control: no longer Build-Depends: debhelper. * debian/rules: stop using debhelper, use implicit rules. * debian/implicit: new; implicit Makefile rules. * debian/README.Debian: rename to debian/mailfront.README.Debian; minor. * debian/compat, debian/dirs, debian/examples: remove; obsolete. * debian/doc: rename to debian/mailfront.docs. -- Gerrit Pape Mon, 5 Jan 2004 10:51:10 +0000 mailfront (0.88-1) unstable; urgency=low * new upstream version. * debian/control: Standards-Version: 3.6.1.0; Build-Depends: bglibs-dev (>> 1.011-0), cvm-dev (>> 0.18-0) (closes: #223189). -- Gerrit Pape Wed, 10 Dec 2003 09:35:04 +0000 mailfront (0.87-1) unstable; urgency=low * new upstream version. * debian/diff/count-received.diff: remove, fixed upstream. * debian/rules: disable target patch. * debian/etc/smtpfront-qmail/run, debian/etc/smtpfront-qmail/log/run: utilize the chpst program from the runit package. * debian/control: Recommends: runit (>> 0.11.0-0), ipsvd. -- Gerrit Pape Fri, 29 Aug 2003 11:06:03 +0200 mailfront (0.86-2) unstable; urgency=low * debian/diff/count-received.diff: new; from upstream: fix mail loop detection (Received: header counting). * debian/rules: add target patch: applies patches in debian/diff; reverse apply patches in target clean. -- Gerrit Pape Fri, 18 Jul 2003 15:22:21 +0200 mailfront (0.86-1) unstable; urgency=low * new upstream version. * debian/htmldocs: new; lists upstream doc files in html. * debian/rules: install upstream doc files in html. * debian/etc/smtpfront-qmail/: example uses tcpsvd, svlogd, ./peers. * debian/control: Standards-Version: 3.5.10; adapt description. * debian/README.Debian: adapt. * debian/man/pop3front.8, debian/man/smtpfront.8: adapt. -- Gerrit Pape Fri, 30 May 2003 09:36:29 +0200 mailfront (0.85-1) unstable; urgency=low * initial release (closes: #186864). -- Gerrit Pape Sun, 30 Mar 2003 18:11:42 +0200 mailfront-2.12/debian/control0000644000000000000000000000157413213777177013172 0ustar Source: mailfront Section: mail Priority: extra Maintainer: Gerrit Pape Build-Depends: libbg-dev, liblua5.1-0-dev, libcvm1-dev, cvm, freecdb Standards-Version: 3.7.3.0 Package: mailfront Architecture: any Depends: ${shlibs:Depends} Recommends: runit, ipsvd Description: mail server network protocol front-ends mailfront is a set of customizable network front-ends for mail servers. It contains complete SMTP, QMQP, QMTP, and POP3 front-ends as well as an authentication module for IMAP. The mail delivery front-ends also contain internal address filtering features. . Two SMTP back-ends are provided. One delivers mail to qmail-queue, mimicking most of the behavior of qmail-smtpd, with the addition of support for SMTP AUTH. The other rejects all SMTP commands if $SMTPREJECT is set, and execs its command line otherwise (in order to run the above program). mailfront-2.12/debian/copyright0000644000000000000000000000077513213777177013524 0ustar This package was debianized by Gerrit Pape on Sun, 30 Mar 2003 16:09:09 +0200. It was downloaded from http://untroubled.org/mailfront/ Upstream Author: Bruce Guenter Copyright: This package is Copyright(C) 2005 Bruce Guenter or FutureQuest, Inc., and may be copied according to the GNU GENERAL PUBLIC LICENSE (GPL) Version 2 or a later version. This package comes with no warranty of any kind. The full text of the GPL can be found at /usr/share/common-licenses/GPL-2. mailfront-2.12/debian/diff/0000755000000000000000000000000013213777177012470 5ustar mailfront-2.12/debian/etc/0000755000000000000000000000000013213777177012333 5ustar mailfront-2.12/debian/etc/smtpfront-qmail/0000755000000000000000000000000013213777177015470 5ustar mailfront-2.12/debian/etc/smtpfront-qmail/log/0000755000000000000000000000000013213777177016251 5ustar mailfront-2.12/debian/etc/smtpfront-qmail/log/run0000644000000000000000000000007713213777177017004 0ustar #!/bin/sh exec chpst -ulog svlogd -tt /var/log/smtpfront-qmail mailfront-2.12/debian/etc/smtpfront-qmail/peers/0000755000000000000000000000000013213777177016606 5ustar mailfront-2.12/debian/etc/smtpfront-qmail/peers/1270000644000000000000000000000001613213777177017037 0ustar +RELAYCLIENT= mailfront-2.12/debian/etc/smtpfront-qmail/run0000644000000000000000000000031113213777177016212 0ustar #!/bin/sh exec 2>&1 exec env SMTPGREETING="`hostname -f`" chpst -m3000000 \ tcpsvd -vhl0 -uqmaild -i./peers \ -c56 -C'14:421 per host concurrency limit reached\r\n' \ 0 25 smtpfront-qmail mailfront-2.12/debian/implicit0000644000000000000000000000675113213777177013326 0ustar # $Id: a09db2e42c8b6a2d820754d741558e5894944746 $ .PHONY: deb-checkdir deb-checkuid deb-checkdir: @test -e debian/control || sh -cx '! : wrong directory' deb-checkuid: @test "`id -u`" -eq 0 || sh -cx '! : need root privileges' %.deb: %.deb-docs %.deb-DEBIAN @rm -f $*.deb $*.deb-checkdir $*.deb-docs $*.deb-docs-base \ $*.deb-docs-docs $*.deb-docs-examples $*.deb-DEBIAN \ $*.deb-DEBIAN-dir $*.deb-DEBIAN-scripts $*.deb-DEBIAN-md5sums %.udeb: %.deb-DEBIAN @rm -f $*.deb $*.deb-checkdir $*.deb-DEBIAN $*.deb-DEBIAN-dir \ $*.deb-DEBIAN-scripts $*.deb-DEBIAN-md5sums %.deb-checkdir: install @test -d debian/$* || sh -cx '! : directory debian/$* missing' @test "`id -u`" -eq 0 || sh -cx '! : need root privileges' %.deb-docs-base: install : implicit @rm -f debian/$*/usr/share/doc/$*/* || : @install -d -m0755 debian/$*/usr/share/doc/$* : debian/$*/usr/share/doc/$*/ @sh -cx 'install -m0644 debian/copyright debian/$*/usr/share/doc/$*/' @sh -cx 'install -m0644 debian/changelog \ debian/$*/usr/share/doc/$*/changelog.Debian' @test ! -r changelog || \ sh -cx 'install -m0644 changelog debian/$*/usr/share/doc/$*/' @test -r debian/$*/usr/share/doc/$*/changelog || \ sh -cx 'mv debian/$*/usr/share/doc/$*/changelog.Debian \ debian/$*/usr/share/doc/$*/changelog' @test -s debian/$*/usr/share/doc/$*/changelog || \ sh -cx 'rm -f debian/$*/usr/share/doc/$*/changelog' @gzip -9n debian/$*/usr/share/doc/$*/changelog* %.deb-docs-docs: %.deb-docs-base @for i in `cat debian/$*.docs 2>/dev/null || :`; do \ if test -d $$i; then \ sh -cx "install -d -m0755 debian/$*/usr/share/doc/$*/$${i##*/}" && \ for j in $$i/*; do \ sh -cx "install -m0644 $$j \ debian/$*/usr/share/doc/$*/$${i##*/}/" || exit 1; \ done || exit 1; \ continue; \ fi; \ sh -cx "install -m0644 $$i debian/$*/usr/share/doc/$*/" || exit 1; \ done @test ! -r debian/$*.README.Debian || \ sh -cx 'install -m0644 debian/$*.README.Debian \ debian/$*/usr/share/doc/$*/README.Debian' @if test -r debian/$*.NEWS.Debian; then \ sh -cx 'install -m0644 debian/$*.NEWS.Debian \ debian/$*/usr/share/doc/$*/NEWS.Debian && \ gzip -9n debian/$*/usr/share/doc/$*/NEWS.Debian'; \ fi %.deb-docs-examples: %.deb-docs-docs @rm -rf debian/$*/usr/share/doc/$*/examples : debian/$*/usr/share/doc/$*/examples/ @test ! -r debian/$*.examples || \ install -d -m0755 debian/$*/usr/share/doc/$*/examples @for i in `cat debian/$*.examples 2>/dev/null || :`; do \ sh -cx "install -m0644 $$i debian/$*/usr/share/doc/$*/examples/" \ || exit 1; \ done %.deb-docs: %.deb-checkdir %.deb-docs-base %.deb-docs-docs %.deb-docs-examples : debian/$*/usr/share/doc/$*/ ok %.deb-DEBIAN-base: install @rm -rf debian/$*/DEBIAN : debian/$*/DEBIAN/ @install -d -m0755 debian/$*/DEBIAN @for i in conffiles shlibs templates; do \ test ! -r debian/$*.$$i || \ sh -cx "install -m0644 debian/$*.$$i debian/$*/DEBIAN/$$i" \ || exit 1; \ done %.deb-DEBIAN-scripts: %.deb-DEBIAN-base @for i in preinst prerm postinst postrm config; do \ test ! -r debian/$*.$$i || \ sh -cx "install -m0755 debian/$*.$$i debian/$*/DEBIAN/$$i" \ || exit 1; \ done %.deb-DEBIAN-md5sums: %.deb-DEBIAN-base %.deb-docs : debian/$*/DEBIAN/md5sums @rm -f debian/$*/DEBIAN/md5sums @cd debian/$* && find * -path 'DEBIAN' -prune -o \ -type f -exec md5sum {} \; | LC_ALL=C sort >>DEBIAN/md5sums %.deb-DEBIAN: %.deb-checkdir %.deb-DEBIAN-base %.deb-DEBIAN-scripts \ %.deb-DEBIAN-md5sums : debian/$*/DEBIAN/ ok mailfront-2.12/debian/mailfront.NEWS.Debian0000644000000000000000000000065213213777177015435 0ustar mailfront (0.96-1) unstable; urgency=low * This version switches pattern matching from the simpler mechanism (originated in multilog) to standard shell glob. This change has the (small) potential to break existing rules' behavior, if the rules were depending on specific behavior of the more simplistic pattern matching used previously. -- Gerrit Pape Sun, 17 Jul 2005 19:40:05 +0000 mailfront-2.12/debian/mailfront.README.Debian0000644000000000000000000000050513213777177015613 0ustar mailfront for Debian -------------------- The mailfront network front-end programs are installed in /usr/sbin/. An example smtpfront-qmail service directory for the use with programs from the ipsvd and runit packages is in /usr/share/doc/mailfront/etc/. -- Gerrit Pape , Thu, 29 May 2003 16:28:19 +0200 mailfront-2.12/debian/mailfront.docs0000644000000000000000000000005513213777177014425 0ustar ANNOUNCEMENT NEWS README TODO VERSION *.html mailfront-2.12/debian/man/0000755000000000000000000000000013213777177012333 5ustar mailfront-2.12/debian/man/imapfront-auth.80000644000000000000000000000120213213777177015355 0ustar .TH imapfront-auth 8 .SH NAME imapfront-auth \- IMAP Front End .SH SYNOPSIS .B imapfront-auth .I program [ .I args \fR... ] .SH DESCRIPTION .B imapfront-auth provides IMAP authentication using CVM modules. The .I LOGIN command is authenticated via the CVM named by .IR $CVM_SASL_PLAIN . If authentication succeeds, it sets up the environment and executes .IR program . It also offers RFC 1734 compliant AUTH support through ``cvm-sasl''. The environment is set up for use with Courier IMAP. .SH SEE ALSO smtpfront(8), pop2fron(8) .P http://untroubled.org/mailfront/ http://untroubled.org/cvm/ http://untroubled.org/mailfront/cvm-sasl.html mailfront-2.12/debian/man/pop3front-auth.80000644000000000000000000000002513213777177015312 0ustar .so man8/pop3front.8 mailfront-2.12/debian/man/pop3front-maildir.80000644000000000000000000000002513213777177015772 0ustar .so man8/pop3front.8 mailfront-2.12/debian/man/pop3front.80000644000000000000000000000255713213777177014367 0ustar .TH pop3front 8 .SH NAME pop2front \- POP3 Front End .SH SYNOPSIS .B pop3front-auth .I cvm .I program [ .I args \fR... ] .P .B pop3front-maildir [ .I default-maildir ] .SH DESCRIPTION The POP3 front end is composed of two pieces: an authentication front end and a transfer back-end. .P Connections are timed out after .I $TIMEOUT seconds of inactivity (defaults to 1200 seconds or 20 minutes), or .I $SESSION_TIMEOUT seconds after the connection was established (defaults to 86400 seconds or 24 hours). .P .B pop3front-auth authenticates the username and password sent by the client using the named .IR cvm . If successful, it sets up the environment and executes .IR program . It also offers RFC 1734 complient AUTH support through ``cvm-sasl''. .P .B pop3front-maildir serves messages via POP3 out of a maildir. If .I $MAILBOX is set, its contents are used as the path to the mailbox, otherwise the .I default-mailbox argument must be present. If .I $MAX_MESSAGES is set, the total number of accessable messages will be limited to that number. In addition, if either of .I $MAX_CUR_MESSAGES or .I $MAX_NEW_MESSAGES are set, the total number of accessable messages in the "cur" and "new" subdirectories respectively will each be limited to that number. .SH SEE ALSO smtpfront(8) .P /usr/share/doc/mailfront/html/cvm-sasl.html http://untroubled.org/mailfront/ http://untroubled.org/cvm/ mailfront-2.12/debian/man/smtpfront-echo.80000644000000000000000000000002513213777177015371 0ustar .so man8/smtpfront.8 mailfront-2.12/debian/man/smtpfront-qmail.80000644000000000000000000000002513213777177015556 0ustar .so man8/smtpfront.8 mailfront-2.12/debian/man/smtpfront-reject.80000644000000000000000000000002513213777177015727 0ustar .so man8/smtpfront.8 mailfront-2.12/debian/man/smtpfront.80000644000000000000000000000520513213777177014462 0ustar .TH smtpfront 8 .SH NAME smtpfront \- SMTP Front Ends .SH SYNOPSIS .B smtpfront .SH DESCRIPTION The code for SMTP is divided internally into two sections: front-end and back-end code. The front-end code handles the low-level details of the protocol. The back-end code handles the validation and delivery details in a protocol-independant fashion. .SH FEATURES The following features are common to all SMTP front-ends: .IP o 2 Validates senders and recipients according to ``mailrules'' processing. .IP o 2 If .I $RELAYCLIENT is set, all recipient addresses not rejected by mail rules are allowed, and its contents are appended to each recipient address. Back-end validation is omitted. .IP o 2 Handles RFC 2554 SMTP authentication. After authentication all recipients not rejected by mail rules are allowed, and back-end validation is omitted. .IP o 2 Automatically handles either bare NL or RFC 821/2821 compliant CR/NL end-of-line conventions. .IP o 2 Rejects messages that exceed .I $DATABYTES bytes in the body. .IP o 2 Times out connections after .I $TIMEOUT seconds of inactivity (defaults to 1200 seconds or 20 minutes), or .I $SESSION_TIMEOUT seconds after the connection was established (defaults to 86400 seconds or 24 hours). .IP o 2 Counts the number of "Received:" and "Delivered-To:" headers, and rejects the message if more than .I $MAXHOPS of either are seen (defaults to 100). .IP o 2 All error responses are logged. .IP o 2 Handles (ignores) RFC 1869 extended parameters on the ``RCPT TO:'' and ``MAIL FROM:'' commands. .IP o 2 Initial greeting message is configureable by .IR $SMTPGREETING . .IP o 2 Rejects bounce messages (messages with an empty envelope sender) that attempt to deliver to multiple recipients. .IP o 2 Optionally adds a fixup "Received:" header for hosts that have different incoming and outgoing hostnames or IPs. Set .I $FIXUP_RECEIVED_HOST and .I $FIXUP_RECEIVED_IP if you want this header added. .SH BACK ENDS .TP .B smtpfront-echo Uses the echo backend to simply echo back the sender and recipient parameters, and the size of the data to the client. .TP .B smtpfront-qmail Uses the ``qmail validation features'' to validate addresses, and the ``qmail backend'' to deliver messages. .TP .B smtpfront-reject If .I $SMTPREJECT is set, all SMTP commands are rejected with this message. If the message starts with a "-", a permanent error number is used and the leading "-" is stripped. If .I $SMTPREJECT is not set, it execs its command line. .SH SEE ALSO pop3front(8) .P /usr/share/doc/mailfront/html/mailrules.html /usr/share/doc/mailfront/html/qmail-validate.html /usr/share/doc/mailfront/html/qmail-backend.html http://untroubled.org/mailfront/ mailfront-2.12/debian/rules0000755000000000000000000000600313213777177012637 0ustar #!/usr/bin/make -f CC =gcc CFLAGS =-W -Wall -Wshadow -O2 -g STRIP =strip ifneq (,$(findstring nostrip,$(DEB_BUILD_OPTIONS))) STRIP =: nostrip endif DIR =$(shell pwd)/debian/mailfront patch: deb-checkdir patch-stamp patch-stamp: for i in `ls -1 debian/diff/*.diff || :`; do \ patch -p1 <$$i || exit 1; \ done touch patch-stamp configure: deb-checkdir configure-stamp configure-stamp: patch-stamp for i in conf-*; do \ test -e $${i%'{orig}'}'{orig}' || cp -v $$i $$i'{orig}'; \ done echo '/usr/sbin' >conf-bin echo '/usr/include/bglibs' >conf-bgincs echo '/usr/lib' >conf-bglibs echo '$(CC) $(CFLAGS)' >conf-cc echo '$(CC) $(CFLAGS) -fPIC -shared' >conf-ccso echo '$(CC)' >conf-ld echo '/usr/include' >conf-include echo '/usr/lib/mailfront' >conf-modules echo '/var/lib/qmail' >conf-qmail touch configure-stamp build: deb-checkdir build-stamp build-stamp: configure-stamp $(MAKE) $(MAKE) lua sh tests.sh touch build-stamp clean: deb-checkdir deb-checkuid $(MAKE) clean for i in `ls *'{orig}' || :`; do mv -vf $$i $${i%'{orig}'}; done ! test -e patch-stamp || \ for i in `ls -1r debian/diff/*.diff || :`; do patch -p1 -R <$$i; done rm -f patch-stamp configure-stamp build-stamp install-stamp rm -rf '$(DIR)' rm -f debian/files debian/substvars changelog install: deb-checkdir deb-checkuid install-stamp install-stamp: build-stamp rm -rf '$(DIR)' $(MAKE) install install_prefix='$(DIR)' chmod 644 '$(DIR)'/usr/include/mailfront/*.h for i in '$(DIR)'/usr/sbin/*; do \ test "`head -c2 $$i`" = '#!' || $(STRIP) -R .comment -R .note $$i; \ done $(STRIP) -R .note -R .comment --strip-unneeded \ '$(DIR)'/usr/lib/mailfront/*.so # man pages install -d -m0755 '$(DIR)'/usr/share/man/man8 for i in debian/man/*.8; do \ install -m0644 $$i '$(DIR)'/usr/share/man/man8/ || exit 1; \ done for i in '$(DIR)'/usr/share/man/man8/*.8; do \ test "`head -c4 $$i`" != '.so ' || \ (ln -s "`head -n1 $$i |cut -c10-`".gz $$i.gz && rm -f $$i) \ || exit 1; \ done gzip -9n '$(DIR)'/usr/share/man/man8/*.8 # service directories install -d -m0755 \ '$(DIR)'/usr/share/doc/mailfront/etc/smtpfront-qmail/log install -m0644 debian/etc/smtpfront-qmail/run \ '$(DIR)'/usr/share/doc/mailfront/etc/smtpfront-qmail/run install -m0644 debian/etc/smtpfront-qmail/log/run \ '$(DIR)'/usr/share/doc/mailfront/etc/smtpfront-qmail/log/run install -d -m0755 \ '$(DIR)'/usr/share/doc/mailfront/etc/smtpfront-qmail/peers install -m0644 debian/etc/smtpfront-qmail/peers/127 \ '$(DIR)'/usr/share/doc/mailfront/etc/smtpfront-qmail/peers/127 # changelog test -r changelog || ln -s ChangeLog changelog # fix directory permissions find '$(DIR)' -type d -print0 | xargs -0r chmod 0755 touch install-stamp binary: binary-indep binary-arch binary-indep: binary-arch: deb-checkdir deb-checkuid install-stamp mailfront.deb dpkg-shlibdeps '$(DIR)'/usr/sbin/* dpkg-gencontrol -isp -pmailfront -P'$(DIR)' dpkg -b '$(DIR)' .. .PHONY: patch configure build clean install binary-indep binary-arch binary include debian/implicit mailfront-2.12/getprotoenv.c0000644000000000000000000000076312467132135013051 0ustar #include #include #include #include #include "mailfront.h" static const char* proto; const char* getprotoenv(const char* name) { static str fullname; const char* env; if (proto == 0) if ((proto = getenv("PROTO")) == 0) proto = "TCP"; if (name == 0 || *name == 0) return proto; wrap_str(str_copy2s(&fullname, proto, name)); if ((env = getenv(fullname.s)) != 0 && env[0] == 0) env = 0; return env; } mailfront-2.12/imapfront-auth.c0000644000000000000000000002475212467132135013437 0ustar /* imapfront-auth.c - IMAP authentication front-end * Copyright (C) 2008 Bruce Guenter or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include #include #include #include #include #include const char program[] = "imapfront-auth"; const int msg_show_pid = 1; #define MAX_ARGC 16 #define QUOTE '"' #define ESCAPE '\\' #define LBRACE '{' #define RBRACE '}' static const char NOTAG[] = "*"; static const char CONT[] = "+"; static const char* capability; static const char* cvm; static const char* domain; static char** nextcmd; static str tag; static str line; static str cmd; static str line_args[MAX_ARGC]; static int line_argc; static int auth_count; static int auth_max; static struct sasl_auth saslauth = { .prefix = "+ " }; void log_start(const char* tagstr) { obuf_puts(&errbuf, program); obuf_putc(&errbuf, '['); obuf_putu(&errbuf, getpid()); obuf_puts(&errbuf, "]: "); if (tagstr) { obuf_puts(&errbuf, tagstr); obuf_putc(&errbuf, ' '); } } void log_str(const char* msg) { obuf_puts(&errbuf, msg); } void log_end(void) { obuf_putsflush(&errbuf, "\n"); } void logmsg(const char* tagstr, const char* msg) { log_start(tagstr); log_str(msg); log_end(); } void respond_start(const char* tagstr) { if (tagstr == 0) tagstr = tag.s; log_start(tagstr); if (!obuf_puts(&outbuf, tagstr) || !obuf_putc(&outbuf, ' ')) exit(1); } void respond_str(const char* msg) { log_str(msg); if (!obuf_puts(&outbuf, msg)) exit(1); } void respond_end(void) { log_end(); if (!obuf_putsflush(&outbuf, CRLF)) exit(1); } void respond(const char* tagstr, const char* msg) { respond_start(tagstr); respond_str(msg); respond_end(); } #if 0 static int isctl(char ch) { return (ch > 0x1f) && (ch < 0x7f); } static int isquotedspecial(char ch) { return (ch == QUOTE) || (ch == ESCAPE); } static int isatomspecial(char ch) { switch (ch) { case '(': case ')': case '{': case ' ': case '%': case '*': return 0; } return !isctl(ch) && !isquotedspecial(ch); } static int isatom(char ch) { return !isatomspecial(ch); } static int istag(char ch) { return isatom(ch) && (ch != '+'); } #endif /* This parser is rather liberal in what it accepts: The IMAP standard mandates seperate character sets for tags, commands, unquoted strings. Since they all must be seperated by spaces, this parser allows all non-whitespace characters for each of the above. */ static int parse_line(void) { #define RESPOND(T,S) do{ respond(T,S); return 0; }while(0) unsigned i; unsigned len; const char* ptr; str* arg; /* Parse out the command tag */ str_truncate(&tag, 0); for (i = 0, ptr = line.s; i < line.len && isspace(*ptr); ++i, ++ptr) ; for (; i < line.len && !isspace(*ptr); ++i, ++ptr) str_catc(&tag, line.s[i]); if (!tag.len) RESPOND(NOTAG, "BAD Syntax error"); if (i >= line.len) RESPOND(0, "BAD Syntax error"); /* Parse out the command itself */ str_truncate(&cmd, 0); for (; i < line.len && isspace(*ptr); ++i, ++ptr) ; for (; i < line.len && !isspace(*ptr); ++i, ++ptr) str_catc(&cmd, line.s[i]); if (!cmd.len) RESPOND(0, "BAD Syntax error"); /* Parse out the command-line args */ for (line_argc = 0; line_argc < MAX_ARGC; ++line_argc) { arg = &line_args[line_argc]; str_truncate(arg, 0); for (; i < line.len && isspace(*ptr); ++i, ++ptr) ; if (i >= line.len) break; switch (*ptr) { case LBRACE: /* Handle a string literal */ ++i, ++ptr; if (!isdigit(*ptr)) RESPOND(0, "BAD Syntax error: missing integer"); for (len = 0; i < line.len && *ptr != RBRACE; ++i, ++ptr) { if (!isdigit(*ptr)) RESPOND(0, "BAD Syntax error: invalid integer"); len = len * 10 + *ptr - '0'; } ++i, ++ptr; if (*ptr != 0) RESPOND(0, "BAD Syntax error: missing LF after integer"); str_ready(arg, len); respond(CONT, "OK"); if (len > 0) ibuf_read(&inbuf, arg->s, len); arg->s[arg->len = len] = 0; ibuf_getstr_crlf(&inbuf, &line); i = 0; ptr = line.s; break; case QUOTE: /* Handle a quoted string */ for (++i, ++ptr; i < line.len && *ptr != QUOTE; ++i, ++ptr) { if (*ptr == ESCAPE) { if (++i >= line.len) break; ++ptr; } str_catc(arg, *ptr); } if (i >= line.len || *ptr != QUOTE) RESPOND(0, "BAD Syntax error: unterminated quoted string"); ++i, ++ptr; break; default: /* Normal case is very simple */ for (; i < line.len && !isspace(*ptr); ++i, ++ptr) str_catc(arg, *ptr); } } for (; i < line.len && isspace(*ptr); ++i, ++ptr) ; if (i < line.len) RESPOND(0, "BAD Too many command arguments"); return 1; } void cmd_noop(void) { respond(0, "OK NOOP completed"); } void cmd_logout(void) { respond(NOTAG, "Logging out"); respond(0, "OK LOGOUT completed"); exit(0); } void cmd_capability(void) { const char *p; respond_start(NOTAG); respond_str("CAPABILITY IMAP4rev1"); if (*capability != 0) { respond_str(" "); respond_str(capability); } if ((p = getenv("IMAP_ACL")) && atoi(p)) respond_str(" ACL ACL2=UNION"); if ((p = getenv("OUTBOX")) && *p) { respond_str(" XCOURIEROUTBOX=INBOX"); respond_str(p); } if ((p = getenv("IMAP_MOVE_EXPUNGE_TO_TRASH")) && atoi(p)) respond_str(" XMAGICTRASH"); respond_end(); respond(0, "OK CAPABILITY completed"); } static int setup_env(void) { const char* s; const char* colon; struct stat st; if (cvm_fact_mailbox != 0 && (s = getenv("SETUP_ENV")) != 0 && strcmp(s, "dovecot") == 0) { /* This tells Dovecot that its environment has already been set up. */ if (putenv("DOVECONF_ENV=1") != 0) return 0; /* Use the file type to set the prefix to mbox: or maildir: * Assume missing files are mboxes. */ s = (stat(cvm_fact_mailbox, &st) == 0 && S_ISDIR(st.st_mode)) ? "maildir:" : "mbox:"; /* Use cmd for temporary storage of the substituted mailbox name */ if (!str_copys(&cmd, s)) return 0; s = cvm_fact_mailbox; while ((colon = strchr(s, ':')) != 0) { if (!str_catb(&cmd, s, colon-s) || !str_catb(&cmd, "::", 2)) return 0; s = colon + 1; } if (!str_cats(&cmd, s)) return 0; cvm_fact_mailbox = cmd.s; } return cvm_setenv() && setenv("IMAPLOGINTAG", tag.s, 1) == 0 && setenv("AUTHENTICATED", cvm_fact_username, 1) == 0; } void do_exec(void) { if (!cvm_setugid()) respond(0, "NO Internal error: could not set UID/GID"); else if (!setup_env()) respond(0, "NO Internal error: could not set environment"); else { alarm(0); execvp(nextcmd[0], nextcmd); respond(0, "NO Could not execute second stage"); } exit(1); } void cmd_login(int argc, str* argv) { int cr; if (argc != 2) respond(0, "BAD LOGIN command requires exactly two arguments"); else { if ((cr = cvm_authenticate_password(cvm, argv[0].s, domain, argv[1].s, 1)) == 0) do_exec(); else respond(0, "NO LOGIN failed"); ++auth_count; if (auth_max > 0 && auth_count >= auth_max) exit(0); } } void cmd_authenticate(int argc, str* argv) { int i; if (argc == 1) i = sasl_auth2(&saslauth, argv[0].s, 0); else if (argc == 2) i = sasl_auth2(&saslauth, argv[0].s, argv[1].s); else { respond(0, "BAD AUTHENTICATE command requires only one or two arguments"); return; } if (i == 0) do_exec(); respond_start(0); respond_str("NO AUTHENTICATE failed: "); respond_str(sasl_auth_msg(&i)); respond_end(); ++auth_count; if (auth_max > 0 && auth_count >= auth_max) exit(0); } struct command { const char* name; void (*fn0)(void); void (*fn1)(int argc, str* argv); }; struct command commands[] = { { "CAPABILITY", cmd_capability, 0 }, { "NOOP", cmd_noop, 0 }, { "LOGOUT", cmd_logout, 0 }, { "LOGIN", 0, cmd_login }, { "AUTHENTICATE", 0, cmd_authenticate }, { 0, 0, 0 } }; static void dispatch_line(void) { struct command* c; str_upper(&cmd); for (c = commands; c->name != 0; ++c) { if (str_diffs(&cmd, c->name) == 0) { if (line_argc == 0) { if (c->fn0 == 0) respond(0, "BAD Syntax error: command requires arguments"); else c->fn0(); } else { if (c->fn1 == 0) respond(0, "BAD Syntax error: command requires no arguments"); else c->fn1(line_argc, line_args); } return; } } respond(0, "BAD Unimplemented command"); } static int startup(int argc, char* argv[]) { const char* tmp; if (argc < 2) { respond(NOTAG, "NO Usage: imapfront-auth imapd [args ...]"); return 0; } if ((tmp = getenv("MAXAUTHFAIL")) != 0) auth_max = strtoul(tmp, 0, 10); if ((domain = cvm_ucspi_domain()) == 0) domain = "unknown"; nextcmd = argv + 1; if ((cvm = getenv("CVM_SASL_PLAIN")) == 0) { respond(NOTAG, "NO $CVM_SASL_PLAIN is not set"); return 0; } if (!sasl_auth_init(&saslauth)) { respond(NOTAG, "NO Could not initialize SASL AUTH"); return 0; } if ((capability = getenv("IMAP_CAPABILITY")) == 0 && (capability = getenv("CAPABILITY")) == 0) capability = ""; if (strncasecmp(capability, "IMAP4rev1", 9) == 0) capability += 9; while (isspace(*capability)) ++capability; return 1; } const int authenticating = 1; extern void set_timeout(void); int main(int argc, char* argv[]) { set_timeout(); if (!startup(argc, argv)) return 0; respond(NOTAG, "OK imapfront ready."); while (ibuf_getstr_crlf(&inbuf, &line)) { if (parse_line()) dispatch_line(); } if (ibuf_timedout(&inbuf)) respond(NOTAG, "NO Connection timed out"); return 0; } mailfront-2.12/imapfront.html0000644000000000000000000000302712467132135013212 0ustar

MailFront

IMAP Front End


imapfront-auth

Usage: imapfront-auth PROGRAM [ ARGS ... ]

imapfront-auth provides IMAP authentication using CVM modules. The LOGIN command is authenticated via the CVM named by $CVM_SASL_PLAIN. If authentication succeeds, it sets up the environment and executes PROGRAM. It also offers RFC 1734 compliant AUTH support through cvm-sasl.

Connections are timed out after $AUTH_TIMEOUT (or $TIMEOUT if that is not set) seconds of inactivity (defaults to 1200 seconds or 20 minutes), or $AUTH_SESSION_TIMEOUT (or $SESSION_TIMEOUT if that is not set) seconds after the connection was established (defaults to 86400 seconds or 24 hours).

If $MAXAUTHFAIL is set, no more than the specified number of authentication failures may occur. After this limits are reached, the client is disconnected.

By default, the environment for the executed PROGRAM is set up for use with Courier IMAP. If $SETUP_ENV is set to dovecot, imapfront-auth will try to detect the type of mailbox in use and set $MAIL accordingly. See the Dovecot documentation for version 2 and version 1 for more details.

mailfront-2.12/iobytes.c0000644000000000000000000000215012467132135012143 0ustar /* iobytes.c - Report the number of I/O bytes * Copyright (C) 2008 Bruce Guenter * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ #include #include #include void report_io_bytes(void) { static str tmp; if (str_copys(&tmp, "bytes in: ") && str_catu(&tmp, inbuf.io.offset) && str_cats(&tmp, " bytes out: ") && str_catu(&tmp, outbuf.io.offset)) msg1(tmp.s); } mailfront-2.12/mailfront-2.12.spec0000644000000000000000000000230312467132135013550 0ustar Name: mailfront Summary: Mail server network protocol front-ends Version: 2.12 Release: 1 License: GPL Group: Utilities/System Source: http://untroubled.org/mailfront/mailfront-2.12.tar.gz BuildRoot: %{_tmppath}/mailfront-buildroot BuildRequires: bglibs >= 1.101 BuildRequires: cvm-devel >= 0.81 URL: http://untroubled.org/mailfront/ Packager: Bruce Guenter %description This is mailfront, a package containing customizeable network front-ends for mail servers. Handles POP3, QMQP, QMTP, SMTP, and IMAP (authentication only). %package devel Summary: Mailfront development bits Group: Development/Libraries %description devel Headers for building modules (front-ends, plugins, and back-ends) for mailfront. %prep %setup echo "gcc %{optflags}" >conf-cc echo "gcc %{optflags} -fPIC -shared" >conf-ccso echo "gcc -s -rdynamic" >conf-ld echo %{_bindir} >conf-bin echo %{_libdir}/mailfront >conf-modules echo %{_includedir} >conf-include %build make %install rm -fr %{buildroot} make install_prefix=%{buildroot} install %clean rm -rf %{buildroot} %files %defattr(-,root,root) %doc ANNOUNCEMENT COPYING NEWS README *.html %{_bindir}/* %{_libdir}/mailfront %files devel %{_includedir}/mailfront mailfront-2.12/mailfront-internal.h0000644000000000000000000000155212467132135014304 0ustar #ifndef MAIL_FRONT__MAILFRONT_INTERNAL__H__ #define MAIL_FRONT__MAILFRONT_INTERNAL__H__ #include "mailfront.h" #include struct session { struct protocol* protocol; struct plugin* backend; struct ghash strs; struct ghash nums; str env; int fd; struct plugin* plugin_list; struct plugin* plugin_tail; unsigned flags; const char* module_path; }; GHASH_DECL(session_strs,const char*,const char*); GHASH_DECL(session_nums,const char*,unsigned long); extern struct session session; /* From builtins.c */ extern struct plugin builtin_plugins[]; /* From modules.c */ extern void add_plugin(struct plugin*); extern const response* load_modules(const char* protocol_name, const char* backend_name, const char** plugins); /* From session.c */ extern void session_init(void); #endif /* MAIL_FRONT__MAILFRONT_INTERNAL__H__ */ mailfront-2.12/mailfront.c0000644000000000000000000001624512467132135012472 0ustar #include #include #include #include #include #include #include #include "mailfront-internal.h" static RESPONSE(no_sender,550,"5.1.0 Mail system is not configured to accept that sender"); static RESPONSE(no_rcpt,550,"5.1.0 Mail system is not configured to accept that recipient"); const char UNKNOWN[] = "unknown"; const int msg_show_pid = 1; const char program[] = "mailfront"; const int authenticating = 0; extern void set_timeout(void); extern void report_io_bytes(void); static str tmp_prefix; static str no_params; static void exitfn(void) { handle_reset(); report_io_bytes(); } #define MODULE_CALL(NAME,PARAMS,RESET) do{ \ struct plugin* plugin; \ const response* tmp; \ for (plugin = session.plugin_list; plugin != 0; plugin = plugin->next) { \ if (plugin->NAME != 0) { \ if ((tmp = plugin->NAME PARAMS) != 0) { \ if (!response_ok(tmp)) { \ if (RESET) \ handle_reset(); \ return tmp; \ } \ if (resp == 0) \ resp = tmp; \ } \ } \ } \ } while(0) static const response* handle_init(void) { const response* resp = 0; atexit(exitfn); set_timeout(); MODULE_CALL(init, (), 0); if (session.backend->init != 0) return session.backend->init(); return 0; } const response* handle_helo(str* host, str* capabilities) { const response* resp = 0; MODULE_CALL(helo, (host, capabilities), 0); session_setstr("helo_domain", host->s); if (session.backend->helo != 0) return session.backend->helo(host, capabilities); return 0; } const response* handle_reset(void) { const response* resp = 0; if (session.fd >= 0) { close(session.fd); session.fd = -1; } if (session.backend->reset != 0) session.backend->reset(); MODULE_CALL(reset, (), 0); return resp; } const response* handle_sender(str* sender, str* params) { const response* resp = 0; const response* tmpresp = 0; if (params == 0) { no_params.len = 0; params = &no_params; } MODULE_CALL(sender, (sender, params), 0); if (resp == 0) return &resp_no_sender; if (session.backend->sender != 0) if (!response_ok(tmpresp = session.backend->sender(sender, params))) return tmpresp; if (resp == 0 || resp->message == 0) resp = tmpresp; return resp; } const response* handle_recipient(str* recip, str* params) { const response* resp = 0; const response* hresp = 0; if (params == 0) { no_params.len = 0; params = &no_params; } MODULE_CALL(recipient, (recip, params), 0); if (resp == 0) return &resp_no_rcpt; if (session.backend->recipient != 0) if (!response_ok(hresp = session.backend->recipient(recip, params))) return hresp; if (resp == 0 || resp->message == 0) resp = hresp; return resp; } static const response* data_response; const response* handle_data_start(void) { const response* resp = 0; if (session.fd >= 0) { close(session.fd); session.fd = -1; } if (session.flags & FLAG_NEED_FILE) { if ((session.fd = scratchfile()) == -1) return &resp_internal; } data_response = 0; if (session.backend->data_start != 0) resp = session.backend->data_start(session.fd); if (response_ok(resp)) MODULE_CALL(data_start, (session.fd), 1); if (!response_ok(resp)) { handle_reset(); data_response = resp; } return resp; } void handle_data_bytes(const char* bytes, unsigned len) { const response* r; struct plugin* plugin; if (!response_ok(data_response)) return; for (plugin = session.plugin_list; plugin != 0; plugin = plugin->next) if (plugin->data_block != 0) if ((r = plugin->data_block(bytes, len)) != 0 && !response_ok(r)) { handle_reset(); data_response = r; return; } if (session.backend->data_block != 0) session.backend->data_block(bytes, len); if (session.fd >= 0) if (write(session.fd, bytes, len) != (ssize_t)len) { handle_reset(); data_response = &resp_internal; } } const response* handle_message_end(void) { const response* resp = 0; if (!response_ok(data_response)) return data_response; MODULE_CALL(message_end, (session.fd), 1); if (session.backend->message_end != 0) resp = session.backend->message_end(session.fd); if (session.fd >= 0) close(session.fd); session.fd = -1; if (!response_ok(resp)) handle_reset(); return resp; } int respond_line(unsigned number, int final, const char* msg, unsigned long len) { static str line; if (number >= 400) { line.len = 0; str_catu(&line, number); str_catc(&line, ' '); str_catb(&line, msg, len); msg1(line.s); } if (!session.protocol->respond_line(number, final, msg, len)) return 0; if (final) if (!obuf_flush(&outbuf)) return 0; return 1; } int respond_multiline(unsigned number, int final, const char* msg) { const char* nl; while ((nl = strchr(msg, '\n')) != 0) { if (!respond_line(number, 0, msg, nl-msg)) return 0; msg = nl + 1; } return respond_line(number, final, msg, strlen(msg)); } int respond(const response* resp) { return respond_multiline(resp->number, 1, resp->message); } const response* backend_data_block(const char* data, unsigned long len) { return (session.fd >= 0) ? ( (write(session.fd, data, len) != (ssize_t)len) ? &resp_internal : 0 ) : ( (session.backend->data_block != 0) ? session.backend->data_block(data, len) : 0 ); } int scratchfile(void) { str filename = {0,0,0}; int fd; if ((fd = path_mktemp(tmp_prefix.s, &filename)) != -1) unlink(filename.s); str_free(&filename); return fd; } struct command* commands; static int collect_commands(void) { const struct plugin* plugin; const struct command* cmd; int i = 0; for (cmd = session.backend->commands; cmd != 0 && cmd->name != 0; ++cmd, ++i) ; for (plugin = session.plugin_list; plugin != 0; plugin = plugin->next) for (cmd = plugin->commands; cmd != 0 && cmd->name != 0; ++cmd, ++i) ; if ((commands = malloc((i+1) * sizeof *commands)) == 0) return 0; i = 0; for (cmd = session.backend->commands; cmd != 0 && cmd->name != 0; ++cmd, ++i) commands[i] = *cmd; for (plugin = session.plugin_list; plugin != 0; plugin = plugin->next) for (cmd = plugin->commands; cmd != 0 && cmd->name != 0; ++cmd, ++i) commands[i] = *cmd; commands[i].name = 0; return 1; } int main(int argc, char* argv[]) { const response* resp; const char* tmp; if (argc < 3) die1(111, "Protocol or backend name are missing from the command line"); if ((tmp = getenv("TMPDIR")) == 0) tmp = "/tmp"; if (!str_copy2s(&tmp_prefix, tmp, "/mailfront.tmp.")) die_oom(111); session_init(); if ((resp = load_modules(argv[1], argv[2], (const char**)(argv+3))) != 0 || (resp = handle_init()) != 0) { if (session.protocol != 0) { respond(resp); return 1; } else die1(1, resp->message); } if (!collect_commands()) { respond(&resp_oom); return 1; } if (session.protocol->init != 0) if (session.protocol->init()) return 1; return session.protocol->mainloop(commands); } mailfront-2.12/mailfront.h0000644000000000000000000000701112467132135012466 0ustar #ifndef MAIL_FRONT__MAILFRONT__H__ #define MAIL_FRONT__MAILFRONT__H__ #include "responses.h" #include #include #include "constants.h" #define FLAG_NEED_FILE (1<<0) #define PLUGIN_VERSION 3 struct command { const char* name; int (*fn_enabled)(void); int (*fn_noparam)(void); int (*fn_hasparam)(str* param); }; struct plugin { unsigned version; struct plugin* next; const char* name; unsigned flags; const struct command* commands; const response* (*init)(void); const response* (*helo)(str* hostname, str* capabilities); const response* (*reset)(void); const response* (*sender)(str* address, str* params); const response* (*recipient)(str* address, str* params); const response* (*data_start)(int fd); const response* (*data_block)(const char* bytes, unsigned long len); const response* (*message_end)(int fd); }; #define PROTOCOL_VERSION 3 struct protocol { unsigned version; const char* name; int (*respond_line)(unsigned number, int final, const char* msg, unsigned long len); int (*init)(void); int (*mainloop)(const struct command* commands); }; /* From getprotoenv.c */ extern const char* getprotoenv(const char*); /* From mailfront.c */ extern const char UNKNOWN[]; extern const response* handle_helo(str* host, str* capabilities); extern const response* handle_reset(void); extern const response* handle_sender(str* sender, str* params); extern const response* handle_recipient(str* recip, str* params); extern const response* handle_data_start(void); extern void handle_data_bytes(const char* bytes, unsigned len); extern const response* handle_message_end(void); extern int respond(const response*); extern int respond_line(unsigned number, int final, const char* msg, unsigned long len); extern int respond_multiline(unsigned number, int final, const char* msg); extern const response* backend_data_block(const char* data, unsigned long len); extern int scratchfile(void); /* From modules.c */ extern const response* load_plugin(struct plugin** pptr, const char* name); extern const response* load_backend(struct plugin** bptr, const char* name); extern struct plugin* switch_backend(struct plugin* backend); /* From netstring.c */ int get_netstring_len(ibuf* in, unsigned long* i); int get_netstring(ibuf* in, str* s); /* From queuedir.c */ extern void queuedir_init(const char* prefix); extern const response* queuedir_reset(void); extern const response* queuedir_sender(str* address, str* params); extern const response* queuedir_recipient(str* address, str* params); extern const response* queuedir_data_start(int fd); extern const response* queuedir_data_block(const char* bytes, unsigned long len); extern const response* queuedir_message_end(int fd); /* From session.c */ extern const char* session_protocol(void); extern const char* session_getenv(const char* name); extern unsigned long session_getenvu(const char* name); extern int session_exportenv(void); extern int session_putenv(const char* s); extern int session_setenv(const char* name, const char* value, int overwrite); extern void session_resetenv(void); extern void session_delnum(const char* name); extern void session_delstr(const char* name); extern unsigned long session_getnum(const char* name, unsigned long dflt); extern int session_hasnum(const char* name, unsigned long* num); extern const char* session_getstr(const char* name); extern void session_setnum(const char* name, unsigned long value); extern void session_setstr(const char* name, const char* value); #endif /* MAIL_FRONT__MAILFRONT__H__ */ mailfront-2.12/mailfront.html0000644000000000000000000001120512467132135013203 0ustar

MailFront

POP3 Front End
IMAP Front End
Plugin API


Overview

The mailfront program acts as a driver container, loading up a protocol module, a backend module, and a list of plugins at run time. All protocols are completely interchangeable, as are the backends.

Configuration

The protocol and backend modules are specified as the first two command line arguments. The remainder of the command line arguments specify lists of plugins.

If $PLUGINS is set, it contains a list of plugins, separated by colons, that will be loaded after the plugins specified on the command line. If $MODULE_PATH is set, it specifies the directory in which modules will be loaded. Otherwise, the built in module path will be used, which is configured by editing the file conf-modules before building.

Each plugin name may be one of following three forms:

-name
The previously loaded plugin called "name" is removed from list. The special name "*" means to empty the entire list.
+name
The named plugin is loaded and placed at the front of the list.
name
The named plugin is loaded and placed at the back of the list.

Note that in both cases where a plugin is loaded, it is first removed from the list if it was previously loaded. It is not possible for the same module to be loaded multiple times.

A configuration that would match previous installations of mailfront using the qmail backend would use the following list of plugins:

check-fqdn:counters:mailrules:relayclient:cvm-validate:qmail-validate:add-received:patterns

The included *front-qmail shell script wrappers for the mailfront program are preconfigured to load the above list of plugins before any of their command line arguments or $PLUGINS.

Protocols

The protocol module is responsible for all interaction at the network I/O level with the client. It links into the system by calling down to the handler wrappers provided by mailfront, which in turn dispatches calls to the plugins and finally the backend. The following protocols are available:

Plugins

Plugins are used to enhance or alter the behavior of mailfront. Without any plugins loaded, mailfront does not accept any senders or recipients. Plugins may intercept and modify all aspects of a message. The following plugins are included in the main package:

Backends

The backend is the final stage in incoming mail handling, and is responsible for passing the message on to the mail system. It is invoked only if no plugin generated an error. The following backends are available:

Temporary Files

Some plugins require the use of a temporary file, either to be able to modify contents after receiving a message or to fulfill external timing requirements. These plugins are noted in their documentation above. The temporary files are created in the directory named by $TMPDIR (defaults to "/tmp").

mailfront-2.12/mailrules.html0000644000000000000000000001523012467132135013207 0ustar

MailFront

SMTP Front Ends

Mail Rules Specification


Selection

The use of mail rules is controlled by the environment variable $MAILRULES. This variable specifies the path to the mail rules file. If $MAILRULES is set but the path that it points to cannot be opened, processing will fail with a temporary error. There is no default value -- if it is not set, mail rules processing is disabled.

The rules listed are applied before any other sender or recipient processing is done (such as checking against qmail's badmailfrom file).

Syntax

Each rule in the file occupies a single line. Blank lines and lines starting with "#" are ignored as comments.

Selector Lines

Selector lines specify when the following rules are to be applied. A selector line starts with a colon (":"). The following selectors are defined:

:sender
Apply the following rules only to senders. Any recipient pattern present in the rule is ignored.
:recipient
Apply the following rules only to recipients.
Rules that precede a selector are categorized as follows (for compatibility with existing rules:
  • If the rule has a recipient pattern of "*" (which matches everything), it will be applied as a sender only rule.
  • All other rules are applied as recipient rules.

Rule Lines

Each rule line starts with one of the following prefixes:

k
Accept the sender or recipient.
z
Reject the sender or recipient with a temporary error code.
d
Reject the sender or recipient with a permanent error code.
n
NO-OP: apply the databytes, relayclient, and/or environment settings, but continue processing further rules.
p
Pass the sender or recipient on to the next processing state (ie $RELAYCLIENT or back-end validation).
The remainder of the line consists of a series of fields seperated by colons (":"). The fields are:
  1. Sender: A pattern applied to the envelope sender address.
  2. Recipient: A pattern applied to the envelope recipient address.
  3. Response: The response message that will be given to the client with the numerical code. The default for this message depends on the line's prefix.
  4. Data Bytes: Reduces the maximum message size to the lesser of the current limit (as set at startup by $DATABYTES) and the specified number. This message size limit is reset to its original value before after each message. If empty or missing, no changes are made.
  5. Relay Client: If present, the current recipient address is suffixed with this string. Only useful for "k" rules.
  6. Environment: Environment variables to set as a result of matching this rule. This field contains a list of assignments seperated by commas. Each assignment is formatted as NAME=VALUE. If a value needs to contain a comma, it must be quoted as follows: \..

Escaping

The following escape sequences are recognized in all the fields:

  • \n newline (replaced with a CR+LF pair on output)
  • \### character with octal value ### (exactly 3 digits)
  • \\ backslash
  • \: colon

Patterns

Pattern Syntax

Patterns are globs, similar to UNIX shell-style wildcards (but quite different from full regular expressions).
Pattern Matches
* Any sequence of characters (including the empty sequence).
? Any single character.
[seq] A single occurance of any character in seq.
[!seq] A single occurance of any character not in seq.
Any other character matches itself, without regard for case. Patterns containing only "*" match anything. Note: An empty pattern matches only the empty string.

Special Patterns

The following patterns are treated specially:

[[@filename]]
Matches the domain portion of the address against the control file named filename. Typical uses would be "[[@rcpthosts]]" and "[[@morercpthosts.cdb]]" in the recipient field.
[[filename]]
Matches the entire address against the control file named filename. A typical use would be "[[badmailfrom]]" in the sender field.
If filename ends with .cdb, the control file is opened as a CDB file. Addresses are translated to lower-case before doing CDB lookups. Otherwise, control files are plain text lists, with one entry per line. Empty lines and lines starting with "#" are ignored. Lines starting with "@" match only the domain portion of the address. All comparisons are case insensitive. Missing CDB files are silently ignored. Missing text files cause an error message at startup.

Negation

Prefixing the pattern with a ! inverts the result of the match. That is, if the pattern match does not succeed, the rule will succeed instead of failing. This applies to all patterns including the special patterns above.

Semantics

Each rule is applied in the order they are listed in the rules file until one matches. At that point, the command that triggered the rule search is accepted, deferred, or rejected depending on the rule type. If the sender is not accepted, no recipients can be accepted, as usual. As long as at least one recipient is accepted the message data may be accepted.

Examples

qmail Rules

The following rules provide the functionality similar to that available in qmail-smtpd. Please note that the qmail validation routines already provide this functionality. These rules are listed for illustrative purposes only.

:sender
d[[/var/qmail/control/badmailfrom]]:*:sorry, your envelope sender is in my badmailfrom list (#5.7.1)
:recipient
k*:[[@/var/qmail/control/rcpthosts]]
k*:[[@/var/qmail/control/morercpthosts.cdb]]

Abused Patterns

The following rules block old exploitable addresses that are still commonly probed: bang paths, multiple domains, and percent hacks.

d*:*!*: Sorry, we don't allow that here
d*:*@*@*: Sorry, we don't allow that here
d*:*%*: Sorry, percent hack not accepted here
mailfront-2.12/mailrulesx.html0000644000000000000000000002300412467132135013375 0ustar

MailFront

SMTP Front Ends

Mail Rules Specification

Mail Rules Specification vX


The current mail rules specification is lacking in several areas:

  • There is no way to select rules based on the state of environment variables (such as $RELAYCLIENT or $TCPREMOTEIP.
  • There is no way to select rules based on the SMTP authentication state.
  • It is difficult to seperate sender processing from recipient processing.
  • The dictionary and CDB lookups don't support wildcarding (minor).
This document proposes an improved mail rules specification that addresses these problems.

Selection

The use of mail rules is controlled by the environment variable $MAILRULES. This variable specifies the path to the compiled mail rules file. If $MAILRULES is set but the path that it points to cannot be opened, processing will fail with a temporary error. There is no default value -- if it is not set, mail rules processing is disabled.

The rules listed are applied before any other sender or recipient processing is done (such as checking against qmail's badmailfrom file).

Compiled File Format

The mail rules must be compiled to a binary format. The binary file contains a signature header followed by rules, and terminated with a 32-bit CRC check code of all the data in the file. All numbers are unsigned 32-bit LSB unless otherwise indicated. A string consisists of a length number followed by that many bytes of data.

Signature Header

  1. Unique signature string.
  2. Rule count.

Rule

  1. Rule size: total number of bytes in this rule.
  2. Rule type: single byte code indicating what type of rule this is and when it should get executed. The format of remainder of the data in the rule is dependant on this value.
    • 0: Connection/Setup
    • 1: Sender validation
    • 2: Recipient validation
  3. Conditions: count of the number of conditions (C).
  4. (C) conditions containing:
    1. Negation flag: single byte boolean
    2. Comparison type: single byte code:
      • 0: Is defined
      • 1: Exact match
      • 2: Pattern match
      • 3: File lookup, whole string
      • 4: File lookup, domain portion
      • 5: CDB lookup, whole string
      • 6: CDB lookup, domain portion
    3. Variable name: string
    4. Comparison value: string
  5. Assignments: count of the number of assignments (A).
  6. (A) assignments containing:
    1. Set (1) / unset (0) flag byte
    2. Variable name
    3. Assigned value
  7. Action: single byte code indicating the action this rule is to take:
    • 0: NO-OP
    • 1: PASS
    • 2: ACCEPT, followed by message string.
    • 3: DEFER, followed by message string.
    • 4: REJECT, followed by message string.
    • 5: DEFER-ALL, followed by message string.
    • 6: REJECT-ALL, followed by message string.
  8. Message: string containing the response message.

Variables

The following variables are internally defined.

  • authenticated: Defined if SMTP authentication has succeeded.
  • sender: The envelope sender address.
  • recipient: The current envelope recipient address.
  • databytes: The current maximum message size.
All other variable names are taken from environment variables.

Variable Substitution

Response messages and assignment values undergo variable substition. All instances of $NAME or ${NAME} in these strings are replaced with the contents of the named variable.

Pattern Syntax

A pattern is a string of stars and non-stars. It matches any concatenation of strings matched by all the stars and non-stars in the same order. A non-star matches itself. A star before the end of pattern matches any string that does not include the next character in pattern. A star at the end of pattern matches any string. Patterns containing only "*" match anything. Note: An empty pattern matches only the empty string.

Semantics

Each rule is applied in the order they are listed in the rules file until one matches. At that point, the command that triggered the rule search is accepted, deferred, or rejected depending on the rule type. If the sender is not accepted, no recipients can be accepted, as usual. As long as at least one recipient is accepted the message data may be accepted.

Text File Format

Syntax

Rules are seperated into sections by one of the following lines:

[connect]
Connection validation
[sender]
Sender validation
[recipient]
Recipient validation

Each rule in the file occupies a series of lines. Empty lines are used to seperate rules within the file. Lines starting with "#" are ignored. The rule contains the following sections:

  1. Conditions: a list of zero or more conditions. Each condition has a format from the following list. All conditions must be true for the rule to execute. A rule with no conditions always matches.
    • !CONDITION True if the condition (one of the below) is false.
    • VAR=VALUE True if the variable named VAR is defined and matches "VALUE" exactly.
    • VAR~PATTERN True if the variable VAR is defined and matches the pattern "PATTERN".
    • VAR True if the variable VAR is defined (even if it has been assigned an empty string).
    Sender-only rules must contain the condition "!recipient".
  2. Action: One of the following:
    :ACCEPT
    Accept the sender or recipient.
    :DEFER
    Reject the sender or recipient with a temporary error code.
    :REJECT
    Reject the sender or recipient with a permanent error code.
    :DEFER-ALL
    Reject the message with a temporary error (rejects all past and future recipients, and resets the state).
    :REJECT-ALL
    Reject the message with a permanent error.
    :PASS
    Pass the sender or recipient on to the next processing state (ie $RELAYCLIENT or back-end validation).
    The action may be followed by another colon (":") and a response message that will be given to the client. The default for this message depends on the action.
  3. Assignments: A list of environment variables to set or unset as a result of matching this rule, one per line. Each assignment is formatted as NAME=VALUE (note, no quotes, the value ends at the end of the line). The special names databytes, sender, and recipient are handled specially. Assignment to recipient when handling a sender, and vice versa has no effect.

Escaping

The following escape sequences are recognized in all the fields:

  • \n newline (replaced with a CR+LF pair on output)
  • \### character with octal value ### (exactly 3 digits)
  • \\ backslash
  • \: colon

Special Patterns

The following patterns are treated specially:

[[@filename]]
Matches the domain portion of the address against the control file named filename. Typical uses would be "recipient~[[@rcpthosts]]" and "recipient~[[@morercpthosts.cdb]]".
[[filename]]
Matches the entire address against the control file named filename. A typical use would be "sender~[[badmailfrom]]".
If filename ends with .cdb, the control file is opened as a CDB file. Addresses are translated to lower-case before doing CDB lookups. Otherwise, control files are plain text lists, with one entry per line. Empty lines and lines starting with "#" are ignored. Lines starting with "@" match only the domain portion of the address. All comparisons are case insensitive. Missing CDB files are silently ignored. Missing text files cause an error message at startup.

Examples

qmail Rules

The following rules provide the functionality available in qmail-smtpd:

[sender]
sender~[[/var/qmail/control/badmailfrom]]
:REJECT:Sorry, your envelope sender is in my badmailfrom list (#5.7.1)

[recipient]
$RELAYCLIENT
:ACCEPT:Accepted
recipient=${recipient}$RELAYCLIENT

authenticated
:ACCEPT:Accepted

recipient~[[@/var/qmail/control/rcpthosts]]
:ACCEPT:Accepted

recipient~[[@/var/qmail/control/morercpthosts.cdb]]
:ACCEPT:Accepted

:REJECT:Sorry, that domain isn't in my list of allowed rcpthosts

Missing Features

The following features are absent from this description, and could be added:

  • Extended variable expansion: Borrow the following parameter/variable expansion features from bash:
    ${parameter:-word}
    ${parameter:+word}
    ${parameter:offset}
    ${parameter:offset:length}
    ${#parameter}
    ${parameter#word}
    ${parameter##word}
    ${parameter%word}
    ${parameter%%word}
    ${parameter/pattern/string}
    ${parameter//pattern/string}

mailfront-2.12/modules.c0000644000000000000000000001075612467132135012150 0ustar #include #include #include #include #include "mailfront-internal.h" #include "conf_modules.c" static response resp_load = { 451, 0 }; static RESPONSE(backend_version,451,"4.3.0 Backend ABI version mismatch"); static RESPONSE(plugin_version,451,"4.3.0 Plugin ABI version mismatch"); static RESPONSE(protocol_version,451,"4.3.0 Protocol ABI version mismatch"); static void append_plugin(struct plugin* plugin) { plugin->next = 0; if (session.plugin_tail == 0) session.plugin_list = plugin; else session.plugin_tail->next = plugin; session.plugin_tail = plugin; } static void prepend_plugin(struct plugin* plugin) { plugin->next = session.plugin_list; session.plugin_list = plugin; if (session.plugin_tail == 0) session.plugin_tail = plugin; } static struct plugin* remove_plugin(const char* name) { struct plugin* curr; struct plugin* prev; if (name[0] == '*' && name[1] == 0) session.plugin_list = session.plugin_tail = 0; else { for (prev = 0, curr = session.plugin_list; curr != 0; prev = curr, curr = curr->next) { if (strcmp(curr->name, name) == 0) { if (((prev == 0) ? (session.plugin_list = curr->next) : (prev->next = curr->next)) == 0) session.plugin_tail = prev; return curr; } } } return 0; } static void* load_object(const char* type, const char* name) { static str tmpstr; void* handle; void* ptr; str_copyf(&tmpstr, "s{/}s{-}s{.so}", session.module_path, type, name); if ((handle = dlopen(tmpstr.s, RTLD_NOW | RTLD_LOCAL)) == 0 || (ptr = dlsym(handle, type)) == 0) { str_copyf(&tmpstr, "{4.3.0 Error loading }s{ }s{: }s", type, name, dlerror()); resp_load.message = tmpstr.s; return 0; } return ptr; } static struct plugin* find_builtin_plugin(const char* name) { int i; for (i = 0; builtin_plugins[i].name != 0; ++i) { if (strcmp(builtin_plugins[i].name, name) == 0) return &builtin_plugins[i]; } return 0; } const response* load_plugin(struct plugin** pptr, const char* name) { struct plugin* plugin; if ((plugin = find_builtin_plugin(name)) == 0) { if ((plugin = load_object("plugin", name)) == 0) return &resp_load; if (plugin->version != PLUGIN_VERSION) return &resp_plugin_version; if ((plugin->name = strdup(name)) == 0) return &resp_oom; } *pptr = plugin; return 0; } static const response* load_add_plugin(const char* name) { struct plugin* plugin; const response* r; void (*add)(struct plugin*); if (name[0] == '-') { remove_plugin(++name); return 0; } if (name[0] == '+') { ++name; add = prepend_plugin; } else add = append_plugin; if ((plugin = remove_plugin(name)) == 0) { if ((r = load_plugin(&plugin, name)) != 0) return r; } add(plugin); session.flags |= plugin->flags; return 0; } static const response* load_plugins(const char* list) { const char* start; const char* end; long len; const response* resp; for (start = list; *start != 0; start = end) { end = start; while (*end != 0 && *end != ':') ++end; len = end - start; if (len > 0) { char copy[len+1]; memcpy(copy, start, len); copy[len] = 0; if ((resp = load_add_plugin(copy)) != 0) return resp; } if (*end == ':') ++end; } return 0; } const response* load_backend(struct plugin** bptr, const char* name) { struct plugin* backend; if ((backend = load_object("backend", name)) == 0) return &resp_load; if (backend->version != PLUGIN_VERSION) return &resp_backend_version; *bptr = backend; return 0; } struct plugin* switch_backend(struct plugin* backend) { struct plugin* old; old = session.backend; session.backend = backend; session.flags |= backend->flags; return old; } const response* load_modules(const char* protocol_name, const char* backend_name, const char** plugins) { const char* env; const response* r; if ((session.module_path = getenv("MODULE_PATH")) == 0) session.module_path = conf_modules; if ((session.protocol = load_object("protocol", protocol_name)) == 0) return &resp_load; if (session.protocol->version != PROTOCOL_VERSION) return &resp_protocol_version; if ((r = load_backend(&session.backend, backend_name)) != 0) return r; session.flags |= session.backend->flags; while (*plugins != 0) if ((r = load_plugins(*plugins++)) != 0) return r; if ((env = getenv("PLUGINS")) != 0) return load_plugins(env); return 0; } mailfront-2.12/msa.html0000644000000000000000000001176212467132135012000 0ustar

MailFront

SMTP Front Ends

Message Submission Agent


Summary

An MSA (message submission agent) is a mail component specifically designed to accept mail submitted by an MUA (message user agent, or mail client) for further delivery or relaying. This is in contrast to a MTA (message transfer agent) which is designed to accept mail from other MTAs primarily for local delivery. The most important standard governing the behavior of an MSA is RFC 2476. All modules described as being "MSA compliant" can fill the role described by the standard.

RFC 2476 Details

Section Description Status
Requirements
3.2 A null return path, that is, MAIL FROM:<>, is permitted and MUST be accepted. (MUAs need to generate null return-path messages for a variety of reasons, including disposition notifications.) Yes
4.1 Unless covered by a more precise response code, response code 554 is to be used to reject a MAIL FROM, RCPT TO, or DATA command that contains something improper. Enhanced status code 5.6.0 is to be used if no other code is more specific. Yes
4.2 The MSA MUST ensure that all domains in the envelope are fully-qualified. Yes
4.2 If the MSA examines or alters the message text in way, except to add trace header fields [RFC 821 / RFC 2821], it MUST ensure that all domains in address header fields are fully-qualified. N/A
4.2 Reply code 554 is to be used to reject a MAIL FROM, RCPT TO, or DATA command which contains improper domain references. Yes
5.1 Reply code 501 is to be used to reject a MAIL FROM or RCPT TO command that contains a detectably improper address. N/A
5.1 When addresses are resolved after submission of the message body, reply code 554 with enhanced status code 5.6.2 is to be used after end-of-data, if the message contains invalid addresses in the header. N/A
6.4 Reply code 554 is used for syntactic problems in the data. Reply code 501 is used if the command itself is not syntactically valid. Reply code 550 with enhanced status code 5.7.1 is used to reject based on the submitting user. Reply code 550 with enhanced status code 5.7.0 is used if the message violates site policy. N/A
7 The MSA MUST NOT accept ETRN. [RFC 1985] Yes
7 The MSA MUST NOT send the SMTP 521 Reply Code [RFC 1845] Yes
8.1 The MSA MUST ensure that any address it places in a 'Sender' field is in fact a valid mail address. N/A
Recommendations
3.2 If an MSA is not able to determine a return path to the submitting user, from a valid MAIL FROM, a valid source IP address, or based on authenticated identity, then the MSA SHOULD immediately reject the message. A message can be immediately rejected by returning a 550 code to the MAIL FROM command. N/A
4.2 Local conventions that permit single-level domains SHOULD reject, rather than expand, incomplete multi-level domains. N/A
5.1 An MSA SHOULD reject messages with illegal syntax in a sender or recipient envelope address. N/A
5.1 If the MSA examines or alters the message text in way, except to add trace header fields, it SHOULD reject messages with illegal address syntax in address header fields. N/A
5.2 The MSA SHOULD log message errors, especially apparent misconfigurations of client software. No
7 The MSA SHOULD accept pipelining. [RFC 2197] Yes
7 The MSA SHOULD send error codes. [RFC 2034] Yes
7 The MSA SHOULD send extended response codes. [RFC 1893] Yes
7 The MSA SHOULD support DSN. [RFC 1891] No
7 The MSA SHOULD accept 8-bit MIME data. [RFC 1652] Yes?
mailfront-2.12/netstring.c0000644000000000000000000000125512467132135012507 0ustar #include #include #include "mailfront.h" int get_netstring_len(ibuf* in, unsigned long* i) /* Returns: 1 good number, 0 format error, -1 EOF */ { char c; *i = 0; for (*i = 0; ibuf_getc(in, &c); *i = (*i * 10) + (c - '0')) { if (c == ':') return 1; if (c < '0' || c > '9') return 0; } return -1; } int get_netstring(ibuf* in, str* s) { unsigned long len; char ch; switch (get_netstring_len(in, &len)) { case -1: return -1; case 0: return 0; } if (!str_ready(s, len)) return -1; s->s[len] = 0; if (!ibuf_read(in, s->s, len)) return -1; s->len = len; if (!ibuf_getc(in, &ch)) return -1; return ch == ','; } mailfront-2.12/plugin-accept-recipient.html0000644000000000000000000000075612467132135015734 0ustar

mailfront

Plugin: accept-recipient


This plugin is used to explicitly accept all recipients. As such, it only makes sense to place this module following all others that may reject recipients.

Configuration

None

Sender Action

None

Recipient Action

Accepts all recipients.

Data Action

None

Message Action

None

mailfront-2.12/plugin-accept-sender.html0000644000000000000000000000074212467132135015225 0ustar

mailfront

Plugin: accept-sender


This plugin is used to explicitly accept all senders. As such, it only makes sense to place this module following all others that may reject senders.

Configuration

None

Sender Action

Accepts all senders.

Recipient Action

None

Data Action

None

Message Action

None

mailfront-2.12/plugin-accept.html0000644000000000000000000000106712467132135013750 0ustar

mailfront

Plugin: accept


This plugin is used to explicitly accept all senders and recipients. As such, it only makes sense to place this module following all others that may reject senders or recipients. This plugin is primarily of use in testing.

Configuration

None

Sender Action

Accepts all senders.

Recipient Action

Accepts all recipients.

Data Action

None

Message Action

None

mailfront-2.12/plugin-add-received.c0000644000000000000000000000715012467132135014302 0ustar #include #include #include #include #include #include "mailfront.h" static str received; static str fixup_host; static str fixup_ip; static const char* linkproto; static const char* local_host; static str local_ip; static const char* remote_host; static str remote_ip; static const char* date_string(void) { static char datebuf[64]; time_t now = time(0); struct tm* tm = gmtime(&now); strftime(datebuf, sizeof datebuf - 1, "%d %b %Y %H:%M:%S -0000", tm); return datebuf; } static int str_catfromby(str* s, const char* helo_domain, const char* host, const str* ip) { if (ip->len == 0) ip = 0; if (helo_domain == 0) helo_domain = (host != 0) ? host : (ip != 0) ? ip->s : UNKNOWN; if (!str_cats(s, helo_domain)) return 0; if (host != 0 || ip != 0) { if (!str_cats(s, " (")) return 0; if (host != 0) { if (!str_cats(s, host)) return 0; if (ip != 0) if (!str_catc(s, ' ')) return 0; } if (ip != 0) if (!str_catc(s, '[') || !str_cat(s, ip) || !str_catc(s, ']')) return 0; if (!str_catc(s, ')')) return 0; } return 1; } static int fixup_received(str* s) { if (local_host && local_ip.len > 0 && fixup_host.len > 0 && fixup_ip.len > 0 && (strcasecmp(local_host, fixup_host.s) != 0 || strcasecmp(local_ip.s, fixup_ip.s) != 0)) { if (!str_cat3s(s, "Received: from ", local_host, " (")) return 0; if (!str_cat4s(s, local_host, " [", local_ip.s, "])\n" " by ")) return 0; if (!str_cat(s, &fixup_host)) return 0; if (!str_cats(s, " ([")) return 0; if (!str_cat(s, &fixup_ip)) return 0; if (!str_cat3s(s, "]); ", date_string(), "\n")) return 0; } return 1; } static int add_header_add(str* s) { const char* add = session_getenv("HEADER_ADD"); if (add != 0) { if (!str_cats(s, add)) return 0; if (!str_catc(s, '\n')) return 0; } return 1; } static int build_received(str* s) { if (!str_cats(s, "Received: from ")) return 0; if (!str_catfromby(s, session_getstr("helo_domain"), remote_host, &remote_ip)) return 0; if (!str_cats(s, "\n by ")) return 0; if (!str_catfromby(s, local_host, 0, &local_ip)) return 0; if (!str_cat4s(s, "\n with ", session_protocol(), " via ", linkproto)) return 0; if (!str_cat3s(s, "; ", date_string(), "\n")) return 0; return 1; } static int str_copyip(str* s, const char* ip, int is_ipv6) { s->len = 0; if (ip != 0) { if (is_ipv6 && !str_copys(s, "IPv6:")) return 0; return str_cats(s, ip); } return 1; } static const response* init(void) { const char* tmp; int is_ipv6; linkproto = getprotoenv(0); is_ipv6 = linkproto != 0 && strcasecmp(linkproto, "TCP6") == 0; if (!str_copyip(&local_ip, getprotoenv("LOCALIP"), is_ipv6)) return &resp_oom; if (!str_copyip(&remote_ip, getprotoenv("REMOTEIP"), is_ipv6)) return &resp_oom; local_host = getprotoenv("LOCALHOST"); remote_host = getprotoenv("REMOTEHOST"); if ((tmp = getenv("FIXUP_RECEIVED_HOST")) != 0) { if (!str_copys(&fixup_host, tmp)) return &resp_oom; str_strip(&fixup_host); } if ((tmp = getenv("FIXUP_RECEIVED_IP")) != 0) { if (!str_copys(&fixup_ip, tmp)) return &resp_oom; str_strip(&fixup_ip); } return 0; } static const response* data_start(int fd) { received.len = 0; if (!fixup_received(&received) || !add_header_add(&received) || !build_received(&received)) return &resp_internal; return backend_data_block(received.s, received.len); (void)fd; } struct plugin plugin = { .version = PLUGIN_VERSION, .init = init, .data_start = data_start, }; mailfront-2.12/plugin-add-received.html0000644000000000000000000000304612467132135015024 0ustar

mailfront

Plugin: add-received


This plugin adds headers to the start of the message as detailed below.

Configuration

$FIXUP_RECEIVED_HOST
Received host to match
$FIXUP_RECEIVED_IP
Received IP to match
$HEADER_ADD
Additional headers
$PROTO
This and the following four environment variables are inserted into their respective parts in the standard Received: header described below.
${$PROTO}LOCALHOST
${$PROTO}LOCALIP
${$PROTO}REMOTEHOST
${$PROTO}REMOTEIP

Sender Action

None

Recipient Action

None

Data Action

If $FIXUP_RECEIVED_HOST and $FIXUP_RECEIVED_IP are set and do not exactly match the current local host and IP, a Received: header is added to show a transition from one to the other. Then a standard Received: header is added. Finally, if $HEADER_ADD is set, its contents are added to the message headers.

The standard Received: header has the following format:

Received: from helo_domain (remotehost [remoteip]
        by localhost ([remoteip])
        with protocol via transport; date

Message Action

None

mailfront-2.12/plugin-api.html0000644000000000000000000002645312467132135013270 0ustar

mailfront

Plugin API


Overview

Plugins hook into the mail system at 5 main points:

  1. when the system is started or reset,
  2. when the sender address is received,
  3. when a recipient address is received,
  4. when data is received, and
  5. when the message is completed.

At each of these events, mailfront goes through the list of loaded plugins. For each plugin that has a handler for such an event, mailfront calls that handler. If the handler returns an error, no further handlers are called; otherwise control passes to the next handler. The return code passed back to the protocol is either the error response, if any was encountered, or the first non-error response. If the sender or recipient handlers of all the plugins return no response, the address is considered rejected, and it is not passed on to the back end. This is done to prevent the default configuration from being an open relay. Plugins may modify the sender or recipient address, as well as the message body.

A template plugin is included as a starting point for developing new plugins.

Plugin Structure

A mailfront plugin needs to define exactly one public symbol, "plugin". All other public symbols are ignored. That symbol is to be defined as follows:

struct plugin plugin = {
  .version = PLUGIN_VERSION,
  .flags = 0,
  .commands = commands,
  .init = init,
  .helo = helo,
  .reset = reset,
  .sender = sender,
  .recipient = recipient,
  .data_start = data_start,
  .data_block = data_block,
  .message_end = message_end,
};

All items in this structure except for .version may be omitted if they are not needed. The .version field is a constant set to prevent loading of plugins that were built for an incompatible API. The .flags field controls how certain parts of the plugin are called, and may be zero or more flags values (see below) ored together. The remainder of the fields are hook functions which, if present, are called at the appropriate times in the message handling process.

Note that backend modules have identical structure to plugins described here, except that the single required public symbol is named backend instead of plugin. The backend hook functions are also always the last ones called (with the exception of data_start described below). Protocol modules have an entirely different structure.

Flags

FLAG_NEED_FILE
If set, a temporary file is created and all message data is written to it. The file descriptor for this temporary file is passed to the .data_start and .message_end hooks.

Commands

The commands entry allows for the definition of new SMTP commands in a plugin. To add commands, set it to an array of struct command containing:

struct command
{
  const char* name;
  int (*fn_enabled)(void);
  int (*fn_noparam)(void);
  int (*fn_hasparam)(str* param);
};

The last command in the array must be followed by a termination record, with name set to NULL.

All of the commands provided by plugins are collected together in the order they are found and passed to the protocol module. Commands in plugins override any built-in commands of the same name.

The fn_enabled member is an optional pointer to a function which returns non-zero if the command is available for use. If this function is not present, the command is considered always enabled.

Two command functions are allowed: fn_noparam is for commands that must not have a parameter, and fn_hasparam is for commands that require a parameter. Since there is no regular grammar for SMTP command parameters, the entire text following the command is passed to the function with no modifications except for stripping leading extraneous spaces and the trailing line ending.

Hook Functions

All hook functions return a response pointer or NULL. This structure consists of two elements: an unsigned SMTP response code number and an ASCII message. If the plugin returns a NULL response, processing continues to the next plugin in the chain (ie pass-through). If the plugin returns a response and the response number is greater than or equal to 400 (ie an error), then no further hooks in the chain are called. Response numbers less than 400 are treated as acceptance. The first acceptance response is remembered, but subsequent plugins are still called. If the response was an error, the error is passed back through the protocol, otherwise processing continues to the backend. Protocols that do not use the SMTP numbers (such as QMTP) will translate the number into something appropriate. Error numbers between 400 and 499 inclusive are considered "temporary" errors. All others are considered "permanent" failures (ie reject).

All string parameters are passed as type str* and are modifiable. If their value is changed, all subsequent plugins and the backend will see the modified form, as will the protocol module. See the bglibs str documentation module for functions to use in manipulating these objects.

Sender and recipient SMTP parameters are passed as a str* containing a NUL delimited list of KEYWORD=VALUE pairs. If the parameter keyword was not followed by a value in the SMTP conversation, the =VALUE portion will not be present in the string.

Be aware that the sender and recipient hooks may be called before the message data is handled (as with the SMTP protocol) or after (as with the QMQP and QMTP protocol). In either case, the reset hook will always be called at least once before the message is started, and the message_end hook is called after the message has been completely transmitted.

const response* init(void)
This hook is called once after all the plugins have been loaded.
const response* reset(void)
This hook is called when preparing to start a new message, with the intent that all modules will flush any data specific to the message, as well as after error responses to the sender address or data, and after the SMTP HELO command.
const response* helo(str* hostname, str* capabilities)
This hook is called when the SMTP HELO or EHLO commands are issued. As yet nothing actually uses the hostname string. Other protocols will not call this hook. The capabilities variable contains a list of SMTP EHLO response capabilities, each followed by a newline.
const response* sender(str* address, str* params)
This hook is called after a sender email address is transmitted by the client, and is called exactly once per message.
const response* recipient(str* address, str* params)
This hook is called after a sender email address is transmitted by the client, and may be called zero or more times per message.
const response* data_start(int fd)
This hook is called when the sender starts transmitting the message data. Note that the backend is initialized before calling the plugin hooks, in order that plugins may send extra header data to the backend in this hook.
const response* data_block(const char* bytes, unsigned long len)
This hook is called as blocks of data are received from the sender.
const response* message_end(int fd)
This hook is called when the message has been completely transmitted by the sender.

Session Data

The session structure contains all the current session data, including pointers to the protocol module, the backend module, environment variables, temporary message file descriptor, and internal named strings and numbers. Plugins may use these internal named data items to store information for internal use or to pass to other plugins with the following functions. Note that the string and number tables are independent and may contain items with the same names without conflicts. The named strings work like environment variables but are not exposed when subprograms are executed. The numbers work similarly, but the data type is unsigned long instead of a string pointer.

const char* session_protocol(void)
Returns the name of the protocol front end module.
void session_delnum(const char* name)
Delete the named number from the session.
void session_delstr(const char* name)
Delete the named string from the session.
unsigned long session_getnum(const char* name, unsigned long dflt)
Get the named number from the session. If the name is not present, dflt is returned.
int session_hasnum(const char* name, unsigned long* num)
Returns true if the named number is present in the session.
const char* session_getstr(const char* name)
Fetch the named string from the session. If the name is not present, NULL is returned.
void session_setnum(const char* name, unsigned long value)
Set the named number in the session.
void session_setstr(const char* name, const char* value)
Set the named string in the session.

Library Functions

const response* backend_data_block(const char* data, unsigned long len)
This routine writes a block of data directly to the backend. It takes care of handling both writing to the temporary file if it was created or writing directly to the backend module.
const char* getprotoenv(const char* name)
Fetch the environment variable with the given name prefixed by the value of $PROTO. For example, if $PROTO is set to "TCP" (as with tcpserver), then getprotoenv("LOCALIP") will get the environment variable named "TCPLOCALIP".
int scratchfile(void)
Create a new temporary file descriptor opened for reading and writing. The temporary filename is unlinked before returning so that the temporary file will be deleted as soon as it is closed (by the plugin or when mailfront exits).

Hints

Rewriting the message body

Plugins that need to rewrite the message of the body should do so in the message_end hook. Create a new temporary file descriptor with scratchfile() and write the complete new message to it. Then move the new temporary file over to the existing one with the following sequence:

dup2(tmpfd, fd);
close(tmpfd);

Be sure to rewind the original file descriptor with lseek(fd,SEEK_SET,0) before using it, since the file position will normally be at the very end of the data.

mailfront-2.12/plugin-check-fqdn.c0000644000000000000000000000442212467132135013770 0ustar #include #include "mailfront.h" static RESPONSE(nodomain,554,"5.1.2 Address is missing a domain name"); static RESPONSE(nofqdn,554,"5.1.2 Address does not contain a fully qualified domain name"); static RESPONSE(notemptyrcpt,554,"5.1.2 Recipient address may not be empty"); static RESPONSE(notemptysender,554,"5.1.2 Empty sender address prohibited"); static RESPONSE(wrongdomain,554,"5.1.2 Sender contains a disallowed domain"); static const response* check_fqdn(str* s) { int at; int dot; const char* name; if ((at = str_findlast(s, '@')) <= 0) { if ((name = session_getenv("DEFAULTHOST")) != 0) { at = s->len; if (!str_catc(s, '@') || !str_cats(s, name)) return &resp_oom; } else return &resp_nodomain; } if ((dot = str_findlast(s, '.')) < at) { if ((name = session_getenv("DEFAULTDOMAIN")) != 0) { if (!str_catc(s, '.') || !str_cats(s, name)) return &resp_oom; } else return &resp_nofqdn; } return 0; } static const response* check_domains(const str* s, const char* domains) { unsigned int at; unsigned int i; int atend; if ((at = str_findlast(s, '@')) == (unsigned)-1) { return &resp_notemptysender; } ++at; for (;;) { /* Skip any leading or doubled colons */ while (*domains == ':') ++domains; /* Hit end of string without a match */ if (*domains == 0) return &resp_wrongdomain; for (atend = 0, i = 0; !atend && at+i < s->len; ++i) { if (tolower(s->s[at+i]) != tolower(*domains)) break; ++domains; atend = *domains == ':' || *domains == 0; } if (atend && at+i == s->len) return 0; /* Skip to next domain in list */ while (*domains != ':' && *domains != 0) ++domains; } } static const response* sender(str* s, str* params) { const response* r; const char* domains; if (s->len != 0) { if ((r = check_fqdn(s)) != 0) return r; } if ((domains = session_getenv("SENDER_DOMAINS")) != 0) return check_domains(s, domains); return 0; (void)params; } static const response* recipient(str* s, str* params) { if (s->len == 0) return &resp_notemptyrcpt; return check_fqdn(s); (void)params; } struct plugin plugin = { .version = PLUGIN_VERSION, .sender = sender, .recipient = recipient, }; mailfront-2.12/plugin-check-fqdn.html0000644000000000000000000000203112467132135014504 0ustar

mailfront

Plugin: check-fqdn


Configuration

$DEFAULTDOMAIN
If set, the contents of this variable are appended to all sender or recipient addresses that have a partial host name (missing at least one "."). (no default)
$DEFAULTHOST
If set, the contents of this variable are appended to all sender or recipient addresses that are missing a host name. (no default)
$SENDER_DOMAINS
A colon-separated list of domains to restrict the sender.

Sender Action

If the sender address is not empty and it either contains no "@" or contains no "." in the part of the address following the "@", the address is rejected. Otherwise no action.

Recipient Action

Same as the sender action, with no exception for empty addresses.

Data Action

None

Message Action

None

mailfront-2.12/plugin-clamav.c0000644000000000000000000001003512467132135013225 0ustar #include "mailfront.h" #include #include #include #include #include #include #include #include static RESPONSE(no_hostname,451,"4.3.0 Could not resolve virus scanner hostname"); static RESPONSE(no_scan,451,"4.3.0 Could not virus scan message"); static response resp_virus = { 554, 0 }; #define MAX_IPS 16 #define MAX_CHUNK_SIZE 0xffffffffUL static str line; static int try_connect(const ipv4addr* ip, ipv4port port, unsigned long timeout) { int sock; if ((sock = socket_tcp()) >= 0) { if (socket_connect4_timeout(sock, ip, port, timeout)) return sock; close(sock); } return -1; } static int copystream(int fd, size_t size, obuf* out) { unsigned char prefix[4]; uint32_pack_msb(size, prefix); if (!obuf_write(out, (char*)prefix, 4)) return 0; if (!obuf_copyfromfd(fd, out)) return 0; memset(prefix, 0, 4); return obuf_write(out, (char*)prefix, 4); } static const response* message_end(int fd) { const char* hostname; const char* tmp; ipv4port cmdport; ipv4addr ips[MAX_IPS]; int ip_count; int i; int offset; int result; struct timeval tv; int sock; unsigned long timeout; unsigned long connect_timeout; unsigned long send_timeout; unsigned long maxsize; ibuf netin; obuf netout; struct stat st; if ((hostname = session_getenv("CLAMAV_HOST")) != 0 || (hostname = session_getenv("CLAMD_HOST")) != 0) { if (fstat(fd, &st) != 0) return &resp_internal; /* For simplicity, this plugin just sends a single chunk, but each * chunk is limited to 2^32 bytes by the protocol. */ if (st.st_size > 0xffffffffLL) { warn1("ClamAV scanning skipped: message larger than chunk size"); return 0; } if ((tmp = session_getenv("CLAMAV_MAXSIZE")) != 0 && (maxsize = strtoul(tmp, (char**)&tmp, 10)) != 0 && *tmp == 0) { if (st.st_size > (ssize_t)maxsize){ warn1("ClamAV scanning skipped: message larger than maximum"); return 0; } } if (((tmp = session_getenv("CLAMAV_PORT")) == 0 && (tmp = session_getenv("CLAMD_PORT")) == 0) || (cmdport = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) cmdport = 3310; if (((tmp = session_getenv("CLAMAV_TIMEOUT")) == 0 && (tmp = session_getenv("CLAMD_TIMEOUT")) == 0) || (timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) timeout = 5000; if ((tmp = session_getenv("CLAMAV_CONNECT_TIMEOUT")) == 0 || (connect_timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) connect_timeout = timeout; if ((tmp = session_getenv("CLAMAV_SEND_TIMEOUT")) == 0 || (send_timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) send_timeout = timeout; if ((ip_count = resolve_ipv4name_n(hostname, ips, MAX_IPS)) <= 0) return &resp_no_hostname; gettimeofday(&tv, 0); offset = (tv.tv_sec ^ tv.tv_usec) % ip_count; for (i = 0; i < ip_count; ++i) { const ipv4addr* addr = &ips[(i + offset) % ip_count]; if (lseek(fd, 0, SEEK_SET) != 0) return &resp_internal; if ((sock = try_connect(addr, cmdport, connect_timeout)) < 0) continue; if (obuf_init(&netout, sock, 0, 0, 0)) { netout.io.timeout = send_timeout; result = obuf_puts(&netout, "nINSTREAM\n") && copystream(fd, st.st_size, &netout) && obuf_close(&netout); obuf_close(&netout); if (result) { if (ibuf_init(&netin, sock, 0, IOBUF_NEEDSCLOSE, 0)) { netin.io.timeout = timeout; result = ibuf_getstr(&netin, &line, LF); ibuf_close(&netin); sock = -1; if (result) { if (memcmp(line.s, "stream: ", 8) == 0) { str_lcut(&line, 8); str_rstrip(&line); if (str_diffs(&line, "OK") == 0) return 0; str_splices(&line, 0, 0, "5.7.0 Virus scan failed: "); resp_virus.message = line.s; return &resp_virus; } } } } } if (sock >= 0) close(sock); } } return &resp_no_scan; } struct plugin plugin = { .version = PLUGIN_VERSION, .flags = FLAG_NEED_FILE, .message_end = message_end, }; mailfront-2.12/plugin-clamav.html0000644000000000000000000000471712467132135013761 0ustar

mailfront

Plugin: clamav


This plugin scans messages against a ClamAV server. If the message data is detected as having a virus, the message is rejected, and the error response contains the virus name as detected by ClamAV. This scanner only operates over TCP/IP sockets (either remotely or locally).

Notes: This plugin requires ClamAV version 0.95 or later, and will only scan messages 4GB or smaller due to implementation limitations. It also causes mailfront to save messages to temporary files.

Configuration

$CLAMAV_CONNECT_TIMEOUT
The maximum amount of time to wait for a response when connecting to a ClamAV scanner, in milliseconds. (defaults to $CLAMAV_TIMEOUT below)
$CLAMAV_MAXSIZE
The maximum message size to be scanned, in bytes. This limit is useful for avoiding overloading the scanning system(s). If the incoming message is larger than this threshold, a warning is printed and no scanning is done. If unset or set to "0", there is no limit.
$CLAMAV_HOST
The hostname of the ClamAV scanner. If this name resolves to multiple IP addresses, all of them are tried in sequence (starting at a random point) until one scans the message.
$CLAMAV_PORT
Use this TCP port number for the command/response data. (defaults to 3310)
$CLAMAV_SEND_TIMEOUT
The maximum amount of time to wait for the output buffer to clear when sending data to a ClamAV scanner, in milliseconds. (defaults to $CLAMAV_TIMEOUT below)
$CLAMAV_TIMEOUT
The maximum amount of time to wait for a response from the ClamAV scanner, in milliseconds. (defaults to 5000)
$CLAMD_HOST
Sets the scanner host address if $CLAMAV_HOST is unset.
$CLAMD_PORT
Sets the scanner port address if $CLAMAV_PORT is unset.
$CLAMD_TIMEOUT
Sets the timeout value if $CLAMAV_TIMEOUT is unset.

Sender Action

None

Recipient Action

None

Data Action

None

Message Action

The message is scanned when all the data has been completely transmitted (to prevent timeout issues with sending data to the ClamAV server).

mailfront-2.12/plugin-counters.c0000644000000000000000000001271012467132135013626 0ustar #include "mailfront.h" #include #include #include static RESPONSE(too_big, 552, "5.2.3 The message would exceed the maximum message size."); static RESPONSE(too_long, 552, "5.2.3 Sorry, that message exceeds the maximum message length."); static RESPONSE(hops, 554, "5.6.0 This message is looping, too many hops."); static RESPONSE(manyrcpt, 550, "5.5.3 Too many recipients"); static RESPONSE(manymsgs, 550, "5.5.0 Too many messages"); static unsigned rcpt_count = 0; static unsigned msg_count = 0; static unsigned long data_bytes; /* Total number of data bytes */ static unsigned count_rec; /* Count of the Received: headers */ static unsigned count_dt; /* Count of the Delivered-To: headers */ static int in_header; /* True until a blank line is seen */ static unsigned linepos; /* The number of bytes since the last LF */ static int in_rec; /* True if we might be seeing Received: */ static int in_dt; /* True if we might be seeing Delivered-To: */ static unsigned long minenv(const char* sname, const char* name) { unsigned long u; unsigned long value = session_getenvu(name); u = 0; if (value > 0) if (!session_hasnum(sname, &u) || u > value) { session_setnum(sname, value); return value; } return u; } static const response* init(void) { /* This MUST be done in the init section to make sure the SMTP * greeting displays the current value. */ minenv("maxdatabytes", "DATABYTES"); return 0; } static const response* helo(str* hostname, str* capabilities) { if (!str_cats(capabilities, "SIZE ")) return &resp_oom; if (!str_catu(capabilities, session_getnum("maxdatabytes", 0))) return &resp_oom; if (!str_catc(capabilities, '\n')) return &resp_oom; return 0; (void)hostname; } static const response* reset(void) { minenv("maxdatabytes", "DATABYTES"); rcpt_count = 0; return 0; } static const char* find_param(const str* params, const char* name) { const long len = strlen(name); striter i; striter_loop(&i, params, 0) { if (strncasecmp(i.startptr, name, len) == 0) { if (i.startptr[len] == '0') return i.startptr + len; if (i.startptr[len] == '=') return i.startptr + len + 1; } } return 0; } static const response* sender(str* r, str* params) { unsigned long maxdatabytes; unsigned long size; const char* param; minenv("maxmsgs", "MAXMSGS"); if (msg_count >= session_getnum("maxmsgs", ~0UL)) return &resp_manymsgs; /* This MUST be done as a sender match to make sure SMTP "MAIL FROM" * commands with a SIZE parameter can be rejected properly. */ minenv("maxdatabytes", "DATABYTES"); minenv("maxrcpts", "MAXRCPTS"); /* Look up the size limit after handling the sender, in order to honour limits set in the mail rules. */ maxdatabytes = session_getnum("maxdatabytes", ~0UL); if ((param = find_param(params, "SIZE")) != 0 && (size = strtoul(param, (char**)¶m, 10)) > 0 && *param == 0 && size > maxdatabytes) return &resp_too_big; (void)r; return 0; (void)params; } static const response* recipient(str* r, str* params) { unsigned long maxrcpts = minenv("maxrcpts", "MAXRCPTS"); minenv("maxdatabytes", "DATABYTES"); ++rcpt_count; if (maxrcpts > 0 && rcpt_count > maxrcpts) return &resp_manyrcpt; return 0; (void)r; (void)params; } static const response* start(int fd) { unsigned long maxhops; minenv("maxmsgs", "MAXMSGS"); if (msg_count >= session_getnum("maxmsgs", ~0UL)) return &resp_manymsgs; if (session_getenv("MAXRCPTS_REJECT")){ unsigned long maxrcpts = minenv("maxrcpts", "MAXRCPTS"); if (maxrcpts > 0 && rcpt_count > maxrcpts) return &resp_manyrcpt; } minenv("maxdatabytes", "DATABYTES"); if ((maxhops = session_getenvu("MAXHOPS")) == 0) maxhops = 100; session_setnum("maxhops", maxhops); data_bytes = 0; count_rec = 0; count_dt = 0; in_header = 1; linepos = 0; in_rec = 1; in_dt = 1; return 0; (void)fd; } static const response* block(const char* bytes, unsigned long len) { unsigned i; const char* p; const unsigned long maxdatabytes = session_getnum("maxdatabytes", ~0UL); const unsigned long maxhops = session_getnum("maxhops", 100); data_bytes += len; if (maxdatabytes > 0 && data_bytes > maxdatabytes) return &resp_too_long; for (i = 0, p = bytes; in_header && i < len; ++i, ++p) { char ch = *p; if (ch == LF) { if (linepos == 0) in_header = 0; linepos = 0; in_rec = in_dt = in_header; } else { if (in_header && linepos < 13) { if (in_rec) { if (ch != "received:"[linepos] && ch != "RECEIVED:"[linepos]) in_rec = 0; else if (linepos >= 8) { in_dt = in_rec = 0; if (++count_rec > maxhops) return &resp_hops; } } if (in_dt) { if (ch != "delivered-to:"[linepos] && ch != "DELIVERED-TO:"[linepos]) in_dt = 0; else if (linepos >= 12) { in_dt = in_rec = 0; if (++count_dt > maxhops) return &resp_hops; } } ++linepos; } } } return 0; } static const response* end(int fd) { if (session_getenv("MAXRCPTS_REJECT")){ unsigned long maxrcpts = minenv("maxrcpts", "MAXRCPTS"); if (maxrcpts > 0 && rcpt_count > maxrcpts) return &resp_manyrcpt; } ++msg_count; return 0; (void)fd; } struct plugin plugin = { .version = PLUGIN_VERSION, .init = init, .helo = helo, .reset = reset, .sender = sender, .recipient = recipient, .data_start = start, .data_block = block, .message_end = end, }; mailfront-2.12/plugin-counters.html0000644000000000000000000000273412467132135014355 0ustar

mailfront

Plugin: counters


This plugin maintains and enforces several counters.

Configuration

$MAXMSGS
The maximum message count
$MAXRCPTS
The maximum recipient limit
$MAXRCPTS_REJECT
If set (to anything), messages that have more than $MAXRCPTS recipients will have the message rejected rather than just the excess recipients.
$MAXHOPS
The maximum hop limit (defaults to 100)
$DATABYTES
The maximum message size limit

Sender Action

If the maximum message count has been reached, the sender is rejected. Otherwise no action.

Recipient Action

If the maximum recipient limit has been exceeded for the current message, this recipient is rejected. Otherwise no action.

Data Action

If the maximum recipient limit has been exceeded and $MAXRCPTS_REJECT is set, the message is rejected. If the message is larger than the maximum message size, it is rejected. If more than the maximum hop limit of either "Received:" or "Delivered-To:" headers are present in the message, it is rejected. Otherwise no action.

Message Action

If the maximum recipient limit has been exceeded and $MAXRCPTS_REJECT is set, the message is rejected.

mailfront-2.12/plugin-cvm-authenticate.c0000644000000000000000000000416212467132135015227 0ustar #include "mailfront.h" #include #include #include #include static RESPONSE(authfail, 421, "4.3.0 Failed to initialize AUTH"); static RESPONSE(auth_already, 503, "5.5.1 You are already authenticated."); static RESPONSE(authenticated, 235, "2.7.0 Authentication succeeded."); static struct sasl_auth saslauth = { .prefix = "334 " }; static str auth_caps; static int require_tls; static int enabled(void) { return (sasl_mechanisms != 0) && (!require_tls || (session_getnum("tls_state", 0) > 0)); } static int cmd_AUTH(str* param) { int i; if (session_getnum("authenticated", 0)) return respond(&resp_auth_already); if ((i = sasl_auth1(&saslauth, param)) != 0) { const char* msg = sasl_auth_msg(&i); return respond_line(i, 1, msg, strlen(msg)); } else { session_setnum("authenticated", 1); session_delstr("helo_domain"); session_setstr("auth_user", cvm_fact_username); session_setnum("auth_uid", cvm_fact_userid); session_setnum("auth_gid", cvm_fact_groupid); if (cvm_fact_realname != 0) session_setstr("auth_realname", cvm_fact_realname); if (cvm_fact_domain != 0) session_setstr("auth_domain", cvm_fact_domain); if (cvm_fact_mailbox != 0) session_setstr("auth_mailbox", cvm_fact_mailbox); respond(&resp_authenticated); } return 1; } static struct command commands[] = { { "AUTH", .fn_enabled = enabled, .fn_hasparam = cmd_AUTH }, { .name = 0 } }; static const response* init(void) { require_tls = getenv("AUTH_REQUIRES_TLS") != 0; if (!sasl_auth_init(&saslauth)) return &resp_authfail; if (sasl_mechanisms != 0) { switch (sasl_auth_caps(&auth_caps)) { case 0: break; case 1: break; default: return &resp_authfail; } } return 0; } static const response* helo(str* hostname, str* capabilities) { if (enabled()) if (!str_cat(capabilities, &auth_caps) || !str_catc(capabilities, '\n')) return &resp_oom; return 0; (void)hostname; } struct plugin plugin = { .version = PLUGIN_VERSION, .flags = 0, .commands = commands, .init = init, .helo = helo, }; mailfront-2.12/plugin-cvm-authenticate.html0000644000000000000000000000203212467132135015743 0ustar

mailfront

Plugin: cvm-authenticate


This plugin uses a CVM to validate recipient addresses.

Configuration

This module is configured by the CVM SASL library.

Additionally, it recognizes the following environment variable:

$AUTH_REQUIRES_TLS
Only offer authentication when the client is using an encrypted connection, to avoid sending a password over an insecure connection. This checks that TLS has been negotiated by the starttls-ucspi plugin.

Commands

AUTH
Implements the SMTP service extension for authentication, as specified by RFC 2554.

Sender Action

None

Recipient Action

None

Data Action

None

Message Action

None

mailfront-2.12/plugin-cvm-validate.c0000644000000000000000000000464212467132135014345 0ustar #include #include #include "mailfront.h" #include #include static const char* lookup_secret; static const char* cvm_lookup; static int cred_count; static RESPONSE(norcpt,553,"5.1.1 Sorry, that recipient does not exist."); static RESPONSE(failed,451,"4.1.0 Sorry, I could not verify that recipient (internal temporary error)."); static const response* validate_init(void) { if ((cvm_lookup = getenv("CVM_LOOKUP")) != 0) { if ((lookup_secret = getenv("CVM_LOOKUP_SECRET")) == 0) lookup_secret = getenv("LOOKUP_SECRET"); /* Invoking CVMs in cvm-command mode without $CVM_LOOKUP_SECRET set * will fail, since the CVM will be expecting additional credentials * to validate. To prevent this failure, set $CVM_LOOKUP_SECRET to * an empty string. */ if (lookup_secret == 0) { if (putenv("CVM_LOOKUP_SECRET=") != 0) return &resp_oom; /* Also set the lookup secret to an empty string internally to * avoid NULL pointer issues later. */ lookup_secret = ""; } /* Match the behavior of the current CVM code base: If * $CVM_LOOKUP_SECRET is set to an empty string, treat it as if no * lookup secret is required. */ cred_count = (*lookup_secret == 0) ? 2 : 3; } return 0; } static const response* validate_recipient(str* recipient, str* params) { struct cvm_credential creds[3]; unsigned i; unsigned long u; const response* r = &resp_failed; if (cvm_lookup == 0) return 0; if ((i = str_findlast(recipient, '@')) == (unsigned)-1) return 0; memset(creds, 0, sizeof creds); creds[0].type = CVM_CRED_ACCOUNT; creds[1].type = CVM_CRED_DOMAIN; creds[2].type = CVM_CRED_SECRET; if (str_copyb(&creds[0].value, recipient->s, i) && str_copyb(&creds[1].value, recipient->s+i+1, recipient->len-i-1) && str_copys(&creds[2].value, lookup_secret)) { switch (cvm_authenticate(cvm_lookup, cred_count, creds)) { case 0: r = 0; break; case CVME_PERMFAIL: /* Return a "pass" result if the CVM declared the address to be * out of scope. */ r = (cvm_client_fact_uint(CVM_FACT_OUTOFSCOPE, &u) == 0 && u == 1) ? 0 : &resp_norcpt; } } str_free(&creds[0].value); str_free(&creds[1].value); str_free(&creds[2].value); return r; (void)params; } struct plugin plugin = { .version = PLUGIN_VERSION, .init = validate_init, .recipient = validate_recipient, }; mailfront-2.12/plugin-cvm-validate.html0000644000000000000000000000156712467132135015072 0ustar

mailfront

Plugin: cvm-validate


This plugin uses a CVM to validate recipient addresses.

Configuration

$CVM_LOOKUP
The name of the CVM to invoke
$CVM_LOOKUP_SECRET
The secret to pass to the CVM (defaults to the value of $LOOKUP_SECRET)
$LOOKUP_SECRET
The secret to pass to the CVM

Sender Action

None

Recipient Action

Calls the given CVM, passing the recipient address as the account and domain name along with the lookup secret. If the CVM rejects the recipient, the plugin rejects the recipient. Otherwise no action.

Data Action

None

Message Action

None

mailfront-2.12/plugin-force-file.html0000644000000000000000000000077712467132135014533 0ustar

mailfront

Plugin: force-file


This plugin forces mailfront to save messages to a temporary file, even if no other plugin may require it. This is primarily only useful for debugging.

Configuration

None

Sender Action

None

Recipient Action

None

Data Action

Reports an error if no temporary file was created.

Message Action

None

mailfront-2.12/plugin-lua.c0000644000000000000000000001377012467132135012554 0ustar #include #include #include #include #include "mailfront.h" static int l_msg(lua_State *L) { int i; for (i = 1; i <= lua_gettop(L); i++) msg1(lua_tostring(L, i)); return 0; } static int l_getenv(lua_State *L) { int i; const int nparams = lua_gettop(L); for (i = 1; i < nparams; i++) { const char* name = lua_tostring(L, i); const char* value = session_getenv(name); if (value == 0) lua_pushnil(L); else lua_pushstring(L, value); } return nparams; } static int l_putenv(lua_State *L) { const int nparams = lua_gettop(L); int i; for (i = 1; i < nparams; i++) { if (!session_putenv(lua_tostring(L, i))) { lua_pushstring(L, "Out of memory"); lua_error(L); } } return 0; } static int l_setenv(lua_State *L) { if (lua_gettop(L) != 3) { lua_pushstring(L, "Incorrect number of parameters to setenv"); lua_error(L); } const char* name = lua_tostring(L, 1); const char* value = lua_tostring(L, 2); int overwrite = lua_tointeger(L, 3); if (!session_setenv(name, value, overwrite)) { lua_pushstring(L, "setenv failed"); lua_error(L); } return 0; } static int l_delnum(lua_State *L) { const int nparams = lua_gettop(L); int i; for (i = 1; i < nparams; i++) session_delnum(lua_tostring(L, i)); return 0; } static int l_delstr(lua_State *L) { const int nparams = lua_gettop(L); int i; for (i = 1; i < nparams; i++) session_delstr(lua_tostring(L, i)); return 0; } static int l_getnum(lua_State *L) { if (lua_gettop(L) != 2) { lua_pushstring(L, "Incorrect number of parameters to getnum"); lua_error(L); } const char* name = lua_tostring(L, 1); unsigned long dflt = lua_tonumber(L, 2); lua_pushnumber(L, session_getnum(name, dflt)); return 1; } static int l_getstr(lua_State *L) { const int nparams = lua_gettop(L); int i; for (i = 1; i < nparams; i++) { const char* s = session_getstr(lua_tostring(L, i)); if (s != 0) lua_pushstring(L, s); else lua_pushnil(L); } return nparams; } static int l_setnum(lua_State *L) { if (lua_gettop(L) != 2) { lua_pushstring(L, "Incorrect number of parameters to setnum"); lua_error(L); } const char* name = lua_tostring(L, 1); unsigned long value = lua_tonumber(L, 2); session_setnum(name, value); return 0; } static int l_setstr(lua_State *L) { if (lua_gettop(L) != 2) { lua_pushstring(L, "Incorrect number of parameters to setstr"); lua_error(L); } const char* name = lua_tostring(L, 1); const char* value = lua_tostring(L, 2); session_setstr(name, value); return 0; } static const luaL_Reg library[] = { { "msg", l_msg }, { "getenv", l_getenv }, { "putenv", l_putenv }, { "setenv", l_setenv }, { "delnum", l_delnum }, { "delstr", l_delstr }, { "getnum", l_getnum }, { "getstr", l_getstr }, { "setnum", l_setnum }, { "setstr", l_setstr }, { NULL, NULL } }; static lua_State* L = 0; static const response* get_response(void) { static response resp; static str msgcopy; const char* msg; resp.number = lua_tonumber(L, -2); msg = lua_tostring(L, -1); if (msg == 0 || *msg == 0) { resp.message = (resp.number < 400) ? "OK" : (resp.number < 500) ? "Deferred" : "Rejected"; } else { if (!str_copys(&msgcopy, msg)) return &resp_oom; resp.message = msgcopy.s; } lua_pop(L, 2); return (resp.number > 0) ? &resp : 0; } static int setup(const char* name) { if (L != 0) { lua_getfield(L, LUA_GLOBALSINDEX, name); if (lua_isfunction(L, -1)) return 1; lua_pop(L, 1); } return 0; } static const response* callit(int nparams) { int code; if ((code = lua_pcall(L, nparams, 2, 0)) != 0) { msgf("{Lua error: }d{ (}s{)}", code, lua_tostring(L, -1)); lua_pop(L, 1); return &resp_internal; } return get_response(); } static const response* init(void) { const char* env; const luaL_Reg *lp; env = session_getenv("LUA_SCRIPT"); if (env != 0) { L = luaL_newstate(); if (L == 0) return &resp_oom; switch (luaL_loadfile(L, env)) { case LUA_ERRMEM: return &resp_oom; case 0: break; case LUA_ERRFILE: msg3("Cannot read \"", env, "\""); return &resp_internal; case LUA_ERRSYNTAX: msg3("Syntax error in \"", env, "\""); return &resp_internal; default: return &resp_internal; } for (lp = library; lp->name != 0; lp++) lua_register(L, lp->name, lp->func); return callit(0); } return 0; } static const response* reset(void) { if (setup("reset")) return callit(0); return 0; } static const response* helo(str* hostname, str* capabilities) { if (setup("helo")) { lua_pushlstring(L, hostname->s, hostname->len); lua_pushlstring(L, capabilities->s, capabilities->len); return callit(2); } return 0; } static const response* sender(str* address, str* params) { if (setup("sender")) { lua_pushlstring(L, address->s, address->len); lua_pushlstring(L, params->s, params->len); return callit(2); } return 0; (void)params; } static const response* recipient(str* address, str* params) { if (setup("recipient")) { lua_pushlstring(L, address->s, address->len); lua_pushlstring(L, params->s, params->len); return callit(2); } return 0; (void)params; } static const response* data_start(int fd) { if (setup("data_start")) { lua_pushinteger(L, fd); return callit(1); } return 0; } static const response* data_block(const char* bytes, unsigned long len) { if (setup("data_block")) { lua_pushlstring(L, bytes, len); return callit(1); } return 0; } static const response* message_end(int fd) { if (setup("message_end")) { lua_pushinteger(L, fd); return callit(1); } return 0; } struct plugin plugin = { .version = PLUGIN_VERSION, .flags = 0, .init = init, .reset = reset, .helo = helo, .sender = sender, .recipient = recipient, .data_start = data_start, .data_block = data_block, .message_end = message_end, }; mailfront-2.12/plugin-lua.html0000644000000000000000000000506612467132135013275 0ustar

mailfront

Plugin: lua


This plugin allows for extending mailfront using Lua. All actions in the mailfront plugin API are exposed through calls to functions of the same name in the script, with the exception of the "init" function. For this function, the return from the script itself is used. The functions are passed the same parameters as described in the API. The return value from these functions is a numeric SMTP response code followed by a message. If the number is zero or nil, it is treated as an NULL response. If the message is missing, the script wrapper provides a simple one based on the response code.

Configuration

$LUA_SCRIPT
The file name of the Lua script to load. If not set, this plugin does nothing.

Library

The plugin registers some mailfront functions for script use:

getenv(...)
Returns the (string) value of each of the named session environment variables.
getnum(name, default)
Returns the named session number, or default if it is not set.
getstr(...)
Returns the (string) value of each of the named session strings.
msg(...)
Outputs one message line (into the logs) for each parameter. The script is responsible for formatting.
putenv(...)
Puts the given environment strings into the session environment. The strings must be in the form "NAME=VALUE"
setenv(name, value, overwrite)
Sets a session environment variable which may be used by other plugins to modify their behavior. Does not return any values. Raises an error if any problems occur.
setnum(name, value)
Sets the named session number. These numbers may be used by other plugins to modify their behavior. For example, the counters plugin uses the minimum value of the session environment variable $DATABYTES and the session number maxdatabytes for the maximum message size.
setstr(name, value)
Sets the named session string. These strings may be used by other plugins to modify their behavior. For example, the add-received plugin uses the helo_domain string in the header(s) it generates.
mailfront-2.12/plugin-mailrules.c0000644000000000000000000002404012467132135013760 0ustar #include #include #include #include "mailfront.h" #include #include #include #include #include static RESPONSE(erropen,421,"4.3.0 Could not open $MAILRULES file"); static RESPONSE(syntax,421,"4.3.0 Syntax error in $MAILRULES"); static RESPONSE(erropenref,421,"4.3.0 Error opening file referenced from $MAILRULES"); #define NUL 0 /* rule tables ************************************************************* */ struct pattern { str pattern; dict* file; struct cdb* cdb; int negated; }; struct rule { int code; struct pattern sender; struct pattern recipient; str response; str relayclient; str environment; unsigned long databytes; struct rule* next; }; static struct rule* sender_rules = 0; static struct rule* recip_rules = 0; static struct rule** current_rules = 0; static void append_rule(struct rule* r) { static struct rule* sender_tail = 0; static struct rule* recip_tail = 0; struct rule** head; struct rule** tail; if (current_rules != 0) tail = ((head = current_rules) == &sender_rules) ? &sender_tail : &recip_tail; else if (r->recipient.pattern.len == 1 && r->recipient.pattern.s[0] == '*') { head = &sender_rules; tail = &sender_tail; } else { head = &recip_rules; tail = &recip_tail; } if (*tail == 0) *head = r; else (*tail)->next = r; *tail = r; } static struct rule* alloc_rule(void) { struct rule* r; if ((r = malloc(sizeof *r)) != 0) memset(r, 0, sizeof *r); return r; } #if 0 static void free_rule(struct rule* r) { str_free(&r->sender.pattern); str_free(&r->recipient.pattern); str_free(&r->response); str_free(&r->relayclient); str_free(&r->environment); free(r); } #endif /* embeded filename handling *********************************************** */ static dict cdb_files; static struct cdb* open_cdb(const str* filename) { int fd; struct cdb* c; if ((c = malloc(sizeof *c)) == 0) return 0; fd = open(filename->s, O_RDONLY); cdb_init(c, fd); if (!dict_add(&cdb_files, filename, c)) return 0; return c; } static int lower(str* s) { str_lower(s); return 1; } static dict text_files; static dict* load_text(const str* filename) { dict* d; if ((d = malloc(sizeof *d)) == 0) return 0; memset(d, 0, sizeof *d); if (!dict_load_list(d, filename->s, 1, lower)) return 0; if (!dict_add(&text_files, filename, d)) return 0; return d; } static int is_special(const str* pattern) { long len = pattern->len; return len > 5 && pattern->s[0] == '[' && pattern->s[1] == '[' && pattern->s[len-2] == ']' && pattern->s[len-1] == ']'; } static int is_cdb(const str* filename) { const char* end = filename->s + filename->len; return filename->len > 4 && end[-4] == '.' && end[-3] == 'c' && end[-2] == 'd' && end[-1] == 'b'; } static str filename; static int extract_filename(const str* pattern) { if (!is_special(pattern)) return 0; if (pattern->s[2] == '@') str_copyb(&filename, pattern->s+3, pattern->len-5); else str_copyb(&filename, pattern->s+2, pattern->len-4); return 1; } static int try_load(struct pattern* pattern) { if (extract_filename(&pattern->pattern)) { if (is_cdb(&filename)) return (pattern->cdb = open_cdb(&filename)) != 0; else return (pattern->file = load_text(&filename)) != 0; } return 1; } static void apply_environment(const str* s) { unsigned i; unsigned len; for (i = 0; i < s->len; i += len + 1) { len = strlen(s->s + i); session_putenv(s->s + i); } } /* file parsing ************************************************************ */ static int isoctal(int ch) { return ch >= '0' && ch <= '8'; } static const char* parse_uint(const char* ptr, char sep, unsigned long* out) { for (*out = 0; *ptr != 0 && *ptr != sep; ++ptr) { if (*ptr >= '0' && *ptr <= '9') *out = (*out * 10) + (*ptr - '0'); else return 0; } return ptr; } static const char* parse_char(const char* ptr, char* out) { int o; switch (*ptr) { case 0: return ptr; case '\\': switch (*++ptr) { case 'n': *out = '\n'; break; case '0': case '1': case '2': case '3': case '4': case '5': case '6': case '7': o = *ptr - '0'; if (isoctal(ptr[1])) { o = (o << 3) | (*++ptr - '0'); if (isoctal(ptr[1])) o = (o << 3) | (*++ptr - '0'); } *out = 0; break; default: *out = *ptr; } break; default: *out = *ptr; } return ptr + 1; } static const char* parse_str(const char* ptr, char sep, str* out) { char ch = 0; /* str_truncate(out, 0); */ for (;;) { if (*ptr == sep || *ptr == NUL) return ptr; ptr = parse_char(ptr, &ch); str_catc(out, ch); } return ptr; } static const char* parse_pattern(const char* ptr, char sep, struct pattern* out) { while (*ptr != sep && *ptr == '!') { out->negated = !out->negated; ++ptr; } return parse_str(ptr, sep, &out->pattern); } static void parse_env(const char* ptr, str* out) { while (ptr && *ptr != 0) if ((ptr = parse_str(ptr, ',', out)) != 0) { str_catc(out, 0); if (*ptr == ',') ++ptr; } } static const response* add(const char* l) { struct rule* r; if (*l != 'k' && *l != 'd' && *l != 'z' && *l != 'p' && *l != 'n') return 0; r = alloc_rule(); r->code = *l++; if ((l = parse_pattern(l, ':', &r->sender)) != 0 && *l == ':') if ((l = parse_pattern(l+1, ':', &r->recipient)) != 0 && *l == ':') if ((l = parse_str(l+1, ':', &r->response)) != 0 && *l == ':') if ((l = parse_uint(l+1, ':', &r->databytes)) != 0) if (*l == ':' && (l = parse_str(l+1, ':', &r->relayclient)) != 0 && *l == ':') parse_env(l+1, &r->environment); if (l == 0) return &resp_syntax; append_rule(r); /* Pre-load text files and pre-open CDB files */ if (!try_load(&r->sender)) return &resp_erropenref; if (!try_load(&r->recipient)) return &resp_erropenref; return 0; } static int loaded = 0; static const response* init(void) { const char* path; str rule = {0,0,0}; ibuf in; const response* r; if ((path = getenv("MAILRULES")) == 0) return 0; loaded = 1; if (!ibuf_open(&in, path, 0)) return &resp_erropen; while (ibuf_getstr(&in, &rule, LF)) { str_strip(&rule); if (rule.len == 0) continue; if (rule.s[0] == ':') { switch (rule.s[1]) { case 's': current_rules = &sender_rules; break; case 'r': current_rules = &recip_rules; break; default: return &resp_syntax; } } else if ((r = add(rule.s)) != 0) return r; } ibuf_close(&in); str_free(&rule); return 0; } static const response* reset(void) { if (loaded) { session_resetenv(); session_delnum("maxdatabytes"); } return 0; } /* rule application ******************************************************** */ static int matches(const struct pattern* pattern, const str* addr, const str* atdomain) { static str domain; int result; if (pattern->cdb != 0) { if (pattern->pattern.s[2] == '@') { result = (atdomain->len == 0) ? 0 : cdb_find(pattern->cdb, atdomain->s+1, atdomain->len-1) != 0; } else { result = (cdb_find(pattern->cdb, addr->s, addr->len) != 0) ? 1 : cdb_find(pattern->cdb, atdomain->s, atdomain->len) != 0; } } else if (pattern->file != 0) { if (pattern->pattern.s[2] == '@') { if (atdomain->len > 0) { str_copyb(&domain, atdomain->s+1, atdomain->len-1); result = dict_get(pattern->file, &domain) != 0; } else result = 0; } else { result = (dict_get(pattern->file, addr) != 0) ? 1 : dict_get(pattern->file, atdomain) != 0; } } else result = str_case_glob(addr, &pattern->pattern); if (pattern->negated) result = !result; return result; } static const response* build_response(int type, const str* message) { static response resp; unsigned code; const char* defmsg; switch (type) { case 'p': return 0; case 'n': return 0; case 'k': code = 250; defmsg = "OK"; break; case 'd': code = 553; defmsg = "Rejected"; break; case 'z': code = 451; defmsg = "Deferred"; break; default: code = 451; defmsg = "Temporary failure"; break; } resp.number = code; resp.message = (message->len == 0) ? defmsg : message->s; return &resp; } static const response* apply_rule(const struct rule* rule) { const response* resp; unsigned long maxdatabytes; resp = build_response(rule->code, &rule->response); apply_environment(&rule->environment); maxdatabytes = session_getnum("maxdatabytes", ~0UL); if (maxdatabytes == 0 || (rule->databytes > 0 && maxdatabytes > rule->databytes)) session_setnum("maxdatabytes", rule->databytes); return resp; } static void copy_addr(const str* addr, str* saved, str* domain) { int at; str_copy(saved, addr); str_lower(saved); if ((at = str_findlast(saved, '@')) != -1) str_copyb(domain, saved->s + at, saved->len - at); else str_truncate(domain, 0); } static str saved_sender; static str sender_domain; static const response* validate_sender(str* sender, str* params) { struct rule* rule; const response* r; if (!loaded) return 0; copy_addr(sender, &saved_sender, &sender_domain); for (rule = sender_rules; rule != 0; rule = rule->next) if (matches(&rule->sender, &saved_sender, &sender_domain)) { r = apply_rule(rule); if (rule->code != 'n') return r; } return 0; (void)params; } static str laddr; static str rdomain; static const response* validate_recipient(str* recipient, str* params) { struct rule* rule; const response* r; if (!loaded) return 0; copy_addr(recipient, &laddr, &rdomain); for (rule = recip_rules; rule != 0; rule = rule->next) if (matches(&rule->sender, &saved_sender, &sender_domain) && matches(&rule->recipient, &laddr, &rdomain)) { str_cat(recipient, &rule->relayclient); r = apply_rule(rule); if (rule->code != 'n') return r; } return 0; (void)params; } struct plugin plugin = { .version = PLUGIN_VERSION, .init = init, .reset = reset, .sender = validate_sender, .recipient = validate_recipient, }; mailfront-2.12/plugin-mailrules.html0000644000000000000000000000134012467132135014500 0ustar

mailfront

Plugin: mailrules


This plugin applies a list of rules to sender and/or recipient addresses. See the mail rules specification for a description of how the rules are specified and applied.

Configuration

$MAILRULES
The location of the mail rules file. If not set, no processing is done.

Sender Action

See the mail rules specification.

Recipient Action

See the mail rules specification.

Data Action

None

Message Action

None

mailfront-2.12/plugin-patterns.c0000644000000000000000000000674712467132135013641 0ustar #include #include #include #include #include #include #include "mailfront.h" struct pattern { int mode; str s; const char* message; }; #define T_AFTER_BLANK ('\\') #define T_RESPONSE ('=') #define T_COMMENT ('#') #define T_HEADER (':') #define T_NORMAL (0) static response resp_patmatch = { 554, 0 }; static struct pattern* pattern_list; static str responses; static unsigned pattern_count; static int linemode; static unsigned linepos; static unsigned linemax = 256; static char* linebuf; static int patterns_read(const char* filename) { ibuf in; int mode; unsigned i; unsigned count; str line = {0,0,0}; const char* currmsg = "This message contains prohibited content"; if (!ibuf_open(&in, filename, 0)) return 0; count = 0; /* Count the number of non-comment lines. */ while (ibuf_getstr(&in, &line, LF)) { str_rstrip(&line); if (line.len > 0 && line.s[0] != T_COMMENT) { if (line.s[0] == T_RESPONSE) /* Pre-allocate room for the responses */ wrap_str(str_catb(&responses, line.s+1, line.len)); else ++count; } } responses.len = 0; /* Allocate the lines. */ if ((pattern_list = malloc(count * sizeof *pattern_list)) == 0) die_oom(111); if (!ibuf_rewind(&in)) die1sys(111, "Could not rewind patterns file"); memset(pattern_list, 0, count * sizeof *pattern_list); for (i = 0; i < count && ibuf_getstr(&in, &line, LF); ) { str_rstrip(&line); if (line.len > 0) { switch (mode = line.s[0]) { case T_COMMENT: continue; case T_RESPONSE: currmsg = responses.s + responses.len; str_catb(&responses, line.s+1, line.len); continue; case T_AFTER_BLANK: case T_HEADER: break; default: mode = T_NORMAL; } pattern_list[i].mode = mode; wrap_str(str_copyb(&pattern_list[i].s, line.s+1, line.len-1)); pattern_list[i].message = currmsg; ++i; } } pattern_count = i; ibuf_close(&in); str_free(&line); return 1; } static const response* init(int fd) { const char* tmp; unsigned u; if ((tmp = session_getenv("PATTERNS")) != 0) if (!patterns_read(tmp)) warn3sys("Could not read patterns file '", tmp, "'"); if ((tmp = session_getenv("PATTERNS_LINEMAX")) != 0) if ((u = strtoul(tmp, (char**)&tmp, 10)) > 0 && *tmp == 0) linemax = u; if ((linebuf = malloc(linemax+1)) == 0) die_oom(111); linemode = T_HEADER; linepos = 0; return 0; (void)fd; } static const response* check_line(void) { unsigned i; struct pattern* p; const str fakeline = { linebuf, linepos, 0 }; linebuf[linepos] = 0; for (p = pattern_list, i = 0; i < pattern_count; ++i, ++p) { if ((p->mode == T_NORMAL || p->mode == linemode) && str_glob(&fakeline, &p->s)) { resp_patmatch.message = p->message; return &resp_patmatch; } } return 0; } static const response* check(const char* bytes, unsigned long len) { const char* p; const char* const end = bytes + len; const response* r; if (linebuf == 0) return 0; for (p = bytes; p < end; ++p) { const char ch = *p; if (ch == LF) { if (linepos > 0) { if ((r = check_line()) != 0) return r; if (linemode != T_HEADER) linemode = T_NORMAL; } else linemode = T_AFTER_BLANK; linepos = 0; } else { if (linepos < linemax) linebuf[linepos++] = ch; } } return 0; } struct plugin plugin = { .version = PLUGIN_VERSION, .data_start = init, .data_block = check, }; mailfront-2.12/plugin-patterns.html0000644000000000000000000000442012467132135014345 0ustar

MailFront

SMTP Front Ends

Plugin: patterns


This module provides an ability for rejecting messages based on simple patterns in their content.

Configuration

$PATTERNS
If set, the named file is loaded and parsed (see below), and pattern matching is enabled.
$PATTERNS_LINEMAX
Line buffer size (defaults to 256)
$PATTERNS_RESP
Response message to give when a pattern is matched (defaults to "This message contains prohibited content")

Sender Action

None

Recipient Action

None

Data Action

Each line of the data sent from the client is loaded into a line buffer (with a maximum size as above) and then scanned against the patterns listed in the configuration file. If any pattern matches, the message is rejected.

Message Action

None

Patterns File Format

The patterns file contains a list of standard glob-style patterns. Each line of the file starts with a control character, which is not part of the pattern itself:

#
Comment line, ignored.
=
Sets the response text given when a message is rejected. All following patterns use this response until the next response line. Including this in the patterns file overrides the value of $PATTERNS_RESP.
:
The pattern will be applied only in the header.
\
The pattern will be applied only after a blank line.
Anything else
A normal pattern, applied to any non-blank line.

The following patterns list is a much simplified version of Russell Nelson's qmail-smtpd virus scan patch. In particular, it doesn't actually do any kind of checking if the blank line really marked a MIME boundary or not.

=We don't accept email with executable content (#5.3.4)
\TVqQAAMAA*
\TVpQAAIAA*
\TVpAALQAc*
\TVpyAXkAX*
\TVrmAU4AA*
\TVrhARwAk*
\TVoFAQUAA*
\TVoAAAQAA*
\TVoIARMAA*
\TVouARsAA*
\TVrQAT8AA*
\TVoAAAEAAA*
mailfront-2.12/plugin-qmail-validate.c0000644000000000000000000000475312467132135014666 0ustar #include #include "mailfront.h" #include #include #include #include "conf_qmail.c" #include static RESPONSE(accept,250,0); static RESPONSE(no_chdir,451,"4.3.0 Could not change to the qmail directory."); static RESPONSE(badmailfrom,553,"5.1.0 Sorry, your envelope sender is in my badmailfrom list."); static RESPONSE(bmt,553,"5.1.1 Sorry, that address is in my badrcptto list."); static dict bmf; static dict rh; static dict brt; static str tmp; static int mrh_fd; static struct cdb mrh; static int lower(str* s) { str_lower(s); return 1; } static const response* validate_init(void) { const char* qh; if ((qh = getenv("QMAILHOME")) == 0) qh = conf_qmail; if (chdir(qh) == -1) return &resp_no_chdir; if (!dict_load_list(&bmf, "control/badmailfrom", 0, lower)) return &resp_internal; if (!dict_load_list(&rh, "control/rcpthosts", 0, lower)) return &resp_internal; if (!dict_load_list(&brt, "control/badrcptto", 0, lower)) return &resp_internal; if ((mrh_fd = open("control/morercpthosts.cdb", O_RDONLY)) != -1) cdb_init(&mrh, mrh_fd); return 0; } static const response* validate_sender(str* sender, str* params) { int at; str_copy(&tmp, sender); str_lower(&tmp); if (dict_get(&bmf, &tmp) != 0) return &resp_badmailfrom; if ((at = str_findlast(sender, '@')) > 0) { str_copyb(&tmp, sender->s + at, sender->len - at); str_lower(&tmp); if (dict_get(&bmf, &tmp)) return &resp_badmailfrom; } return &resp_accept; (void)params; } static const response* validate_recipient(str* recipient, str* params) { int at; str_copy(&tmp, recipient); str_lower(&tmp); if (dict_get(&brt, &tmp) != 0) return &resp_bmt; if ((at = str_findlast(recipient, '@')) > 0) { str_copyb(&tmp, recipient->s + at, recipient->len - at); str_lower(&tmp); if (dict_get(&brt, &tmp)) return &resp_bmt; ++at; str_copyb(&tmp, recipient->s + at, recipient->len - at); str_lower(&tmp); for (;;) { if (dict_get(&rh, &tmp)) return &resp_accept; /* NOTE: qmail-newmrh automatically lowercases the keys in this CDB */ if (mrh_fd != -1 && cdb_find(&mrh, tmp.s, tmp.len) == 1) return &resp_accept; if ((at = str_findnext(&tmp, '.', 1)) <= 0) break; str_lcut(&tmp, at); } } return 0; (void)params; } struct plugin plugin = { .version = PLUGIN_VERSION, .init = validate_init, .sender = validate_sender, .recipient = validate_recipient, }; mailfront-2.12/plugin-qmail-validate.html0000644000000000000000000000167312467132135015406 0ustar

MailFront

Plugin: qmail-validate


Configuration

$QMAILHOME
The directory in which qmail resides (defaults to the contents of conf-qmail, which is typically "/var/qmail") The control files listed below are all located in the control subdirectory of this path.

Sender Action

If the sender address is listed in the badmailfrom control file, the sender is rejected. Otherwise no action.

Recipient Action

If the recipient is listed in the badrcptto control file, it is rejected. If the domain of the recipient address is not listed in either the rcpthosts or morercpthosts.cdb control files, the recipient is rejected. Otherwise no action.

Data Action

None

Message Action

None

mailfront-2.12/plugin-rbl.c0000644000000000000000000000735412467132135012553 0ustar #include #include #include #include #include #include #include "mailfront.h" static enum msgstatus { na, good, bad } msgstatus; static response rbl_blocked; static RESPONSE(dnserror, 451, "4.3.0 DNS error doing RBL lookup"); static int debug = 0; static int queuedir = 0; static const response* make_response(int code, const char* status, const char* msg) { static str resp_str; unsigned int i; if (!str_copyf(&resp_str, "s{: }s", status, msg)) return &resp_oom; for (i = 0; i < resp_str.len; ++i) if (resp_str.s[i] < 32 || resp_str.s[i] > 126) resp_str.s[i] = '?'; rbl_blocked.number = code; rbl_blocked.message = resp_str.s; return 0; } static const char* make_name(const ipv4addr* ip, const char* rbl) { char iprbuf[16]; static str name; wrap_str(str_copyb(&name, iprbuf, fmt_ipv4addr_reverse(iprbuf, ip))); wrap_str(str_catc(&name, '.')); wrap_str(str_cats(&name, rbl)); return name.s; } static const response* test_rbl(const char* rbl, enum msgstatus status, const ipv4addr* ip) { static struct dns_result txt; int i; const char* query = make_name(ip, rbl); if (dns_txt(&txt, query) < 0) return &resp_dnserror; if (txt.count == 0) return 0; if (debug) { msgf("{rbl: }s{:}", rbl); for (i = 0; i < txt.count; ++i) msg1(txt.rr.name[i]); } msgstatus = status; return make_response(451, "Blocked", txt.rr.name[0]); /* 451 temporary, 553 permanent */ } static const response* test_rbls(const char* rbls, enum msgstatus status, const ipv4addr* ip) { const char* comma; const response* r; static str rbl; while ((comma = strchr(rbls, ',')) != 0) { wrap_str(str_copyb(&rbl, rbls, comma-rbls)); if ((r = test_rbl(rbl.s, status, ip)) != 0) return r; rbls = comma + 1; } return test_rbl(rbls, status, ip); } static const response* init(void) { const char* blacklist; const response* r; const char* e; ipv4addr ip; debug = session_getenv("RBL_DEBUG") != 0; if ((blacklist = session_getenv("RBL_BLACKLISTS")) == 0 || *blacklist == 0) { if (debug) msg1("{rbl: No blacklists, skipping}"); return 0; } queuedir = session_getenv("RBL_QUEUEDIR") != 0; if (queuedir) queuedir_init("RBL_QUEUEDIR"); /* Can only handle IPv4 sessions */ if ((e = session_getenv("TCPREMOTEIP")) == 0) { if (debug) msg1("{rbl: $TCPREMOTEIP is unset, skipping RBL tests}"); return 0; } if (!ipv4_scan(e, &ip)) { msgf("{rbl: Cannot parse IP '}s{'}", e); return 0; } if ((r = test_rbls(blacklist, bad, &ip)) != 0) return r; return 0; } static const response* sender(str* address, str* params) { const response* r; if (msgstatus == bad) { if (queuedir) { if ((r = queuedir_sender(address, params)) != 0) return r; } else return &rbl_blocked; } return 0; } static const response* recipient(str* address, str* params) { return queuedir && msgstatus == bad ? queuedir_recipient(address, params): 0; } static const response* data_start(int fd) { return queuedir && msgstatus == bad ? queuedir_data_start(fd) : 0; } static const response* data_block(const char* bytes, unsigned long len) { return queuedir && msgstatus == bad ? queuedir_data_block(bytes, len) : 0; } static const response* message_end(int fd) { const response* r; if (msgstatus == bad) { if (queuedir) { if ((r = queuedir_message_end(fd)) != 0) return r; } return &rbl_blocked; } return 0; } struct plugin plugin = { .version = PLUGIN_VERSION, .flags = 0, .init = init, .reset = queuedir_reset, .sender = sender, .recipient = recipient, .data_start = data_start, .data_block = data_block, .message_end = message_end, }; mailfront-2.12/plugin-rbl.html0000644000000000000000000000155112467132135013266 0ustar

mailfront

Plugin: rbl


This plugin looks up the remote IP of the client in a list of RBLs, and blocks all messages if it is listed.

Configuration

RBL_BLACKLISTS
The list of RBL domain names to search, separated by commas (,). If this list is empty, no action is taken.
RBL_DEBUG
If set, this plugin will provide extra output which may be useful in diagnosing RBL issues.
RBL_QUEUEDIR
If set and the client is listed on one of the listed RBLs, capture the message into the named directory and then reject instead of rejecting earlier. See the queuedir backend for more details on settings (prefixed by RBL_).
mailfront-2.12/plugin-reject.html0000644000000000000000000000157312467132135013767 0ustar

mailfront

Plugin: reject


This plugin optionally rejects all senders with a configurable message.

Configuration

$SMTPREJECT
The reject message to issue to clients (defaults to the value of $REJECT)
$REJECT
The reject message to issue to clients

Sender Action

If either $SMTPREJECT or $REJECT are set, all addresses are rejected with the given message. If the text of the message starts with a "-", it is skipped and the rejection uses a permanent failure code (ie bounce); otherwise a temporary failure code is used. If neither are set, no action.

Recipient Action

None

Data Action

None

Message Action

None

mailfront-2.12/plugin-relayclient.html0000644000000000000000000000136212467132135015022 0ustar

mailfront

Plugin: relayclient


This plugin is used to explicitly accept recipients if the sender is considered authenticated, either by having $RELAYCLIENT set or by using SMTP authentication.

Configuration

$RELAYCLIENT
See below.

Sender Action

None

Recipient Action

If $RELAYCLIENT is set, its value is appended to the recipient and the recipient is accepted. If the sender has completed SMTP authentication, the recipient is left unchanged and is accepted. Otherwise no action.

Data Action

None

Message Action

None

mailfront-2.12/plugin-require-auth.html0000644000000000000000000000104612467132135015121 0ustar

mailfront

Plugin: require-auth


This plugin requires that the connection be authenticated.

Configuration

$RELAYCLIENT
See below.

Sender Action

If SMTP authentication has not been completed and $RELAYCLIENT is not set, the sender is rejected. Otherwise no action.

Recipient Action

None

Data Action

None

Message Action

None

mailfront-2.12/plugin-spamassassin.c0000644000000000000000000001210012467132135014462 0ustar #include "mailfront.h" #include #include #include #include #include #include #include static RESPONSE(no_hostname,451,"4.3.0 Could not resolve SpamAssassin hostname"); static RESPONSE(no_scan,451,"4.3.0 Could not SpamAssassin scan message"); static response resp_isspam = { 554, "5.3.0 Spam detected, message refused" }; #define MAX_IPS 16 static str line; static int try_connect(const ipv4addr* ip, ipv4port port, unsigned long timeout) { int sock; if ((sock = socket_tcp()) >= 0) { if (socket_connect4_timeout(sock, ip, port, timeout)) return sock; close(sock); } return -1; } static int try_connect_unix(const char* path, unsigned long timeout) { int sock; if ((sock = socket_unixstr()) >= 0) { if (socket_connectu_timeout(sock, path, timeout)) return sock; close(sock); } return -1; } static unsigned long timeout; static unsigned long connect_timeout; static unsigned long send_timeout; static unsigned long maxsize; static const char* user; static int reject_spam; static int isspam; static int copyit(ibuf* netin, int fdout) { unsigned i; while (ibuf_getstr(netin, &line, LF)) { if (write(fdout, line.s, line.len) != line.len) return 0; if (str_case_starts(&line, "X-Spam-Status:")) { for (i = 14; i < line.len && line.s[i] == ' '; ++i) ; isspam = line.s[i] == 'Y' || line.s[i] == 'y'; break; } if (line.s[0] == LF) break; } return ibuf_copytofd(netin, fdout); } static int scanit(int fd, int fdout, int sock, const struct stat* st) { ibuf netin; obuf netout; if (ibuf_init(&netin, sock, 0, IOBUF_NEEDSCLOSE, 0)) { netin.io.timeout = timeout; if (obuf_init(&netout, sock, 0, 0, 0)) { netout.io.timeout = send_timeout; obuf_putf(&netout, "{PROCESS SPAMC/1.2\r\n}" "{Content-Length: }lu{\r\n}", st->st_size); if (user) obuf_putf(&netout, "{User: }s{\r\n}", user); obuf_puts(&netout, "\r\n"); obuf_copyfromfd(fd, &netout); if (obuf_flush(&netout)) { if (socket_shutdown(sock, 0, 1)) { if (ibuf_getstr(&netin, &line, LF)) { str_rstrip(&line); if (str_diffs(&line, "SPAMD/1.1 0 EX_OK") == 0) { while (ibuf_getstr(&netin, &line, LF)) { str_rstrip(&line); if (line.len == 0) { if (copyit(&netin, fdout)) { dup2(fdout, fd); close(fdout); obuf_close(&netout); ibuf_close(&netin); return 1; } } } } } } } obuf_close(&netout); } ibuf_close(&netin); } return 0; } static const response* message_end(int fd) { const char* hostname; const char* path; const char* tmp; ipv4port port; ipv4addr ips[MAX_IPS]; int ip_count; int i; int offset; struct timeval tv; int sock; struct stat st; int fdout; hostname = 0; if ((path = session_getenv("SPAMD_PATH")) != 0 || (hostname = session_getenv("SPAMD_HOST")) != 0) { if ((tmp = session_getenv("SPAMD_MAXSIZE")) != 0 && (maxsize = strtoul(tmp, (char**)&tmp, 10)) != 0 && *tmp == 0) { if (fstat(fd, &st) != 0) return &resp_internal; if (st.st_size > (ssize_t)maxsize){ warn1("SpamAssassin scanning skipped: message larger than maximum"); return 0; } } if ((tmp = session_getenv("SPAMD_PORT")) == 0 || (port = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) port = 783; if ((tmp = session_getenv("SPAMD_TIMEOUT")) == 0 || (timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) timeout = 5000; if ((tmp = session_getenv("SPAMD_CONNECT_TIMEOUT")) == 0 || (connect_timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) connect_timeout = timeout; if ((tmp = session_getenv("SPAMD_SEND_TIMEOUT")) == 0 || (send_timeout = strtoul(tmp, (char**)&tmp, 10)) == 0 || *tmp != 0) send_timeout = timeout; user = session_getenv("SPAMD_USER"); if ((tmp = session_getenv("SPAMD_REJECT")) != 0) { reject_spam = 1; if (tmp[0] != 0) resp_isspam.message = tmp; } else reject_spam = 0; isspam = 0; if ((ip_count = resolve_ipv4name_n(hostname, ips, MAX_IPS)) <= 0) return &resp_no_hostname; if ((fdout = scratchfile()) == -1) return &resp_internal; if (path != 0) { if (lseek(fd, 0, SEEK_SET) != 0) return &resp_internal; if ((sock = try_connect_unix(path, connect_timeout)) >= 0) if (scanit(fd, fdout, sock, &st)) { return (reject_spam && isspam) ? &resp_isspam : 0; } } else { gettimeofday(&tv, 0); offset = (tv.tv_sec ^ tv.tv_usec) % ip_count; for (i = 0; i < ip_count; ++i) { const ipv4addr* addr = &ips[(i + offset) % ip_count]; if (lseek(fd, 0, SEEK_SET) != 0) return &resp_internal; if ((sock = try_connect(addr, port, connect_timeout)) < 0) continue; if (scanit(fd, fdout, sock, &st)) { return (reject_spam && isspam) ? &resp_isspam : 0; } } } } return &resp_no_scan; } struct plugin plugin = { .version = PLUGIN_VERSION, .flags = FLAG_NEED_FILE, .message_end = message_end, }; mailfront-2.12/plugin-spamassassin.html0000644000000000000000000000520712467132135015216 0ustar

mailfront

Plugin: spamassassin


This plugin scans messages against a SpamAssassin server. The original message is replaced with the rewritten message sent by the scanner, which will contain the results of the SpamAssassin scan in the headers. This plugin can communicate with a scanner over TCP/IP or local UNIX domain sockets.

Note: This plugin causes mailfront to save messages to temporary files.

Configuration

$SPAMD_CONNECT_TIMEOUT
The maximum amount of time to wait for a response when connecting to a SpamAssassin scanner, in milliseconds. (defaults to $SPAMD_TIMEOUT below)
$SPAMD_MAXSIZE
The maximum message size to be scanned, in bytes. This limit is useful for avoiding overloading the scanning system(s). If the incoming message is larger than this threshold, a warning is printed and no scanning is done. If unset or set to "0", there is no limit.
$SPAMD_HOST
The hostname of the SpamAssassin scanner. This setting only applies if $SPAMD_PATH is not set. If this name resolves to multiple IP addresses, all of them are tried in sequence (starting at a random point) until one scans the message.
$SPAMD_PATH
The file path to the local SpamAssassin server socket. Overrides the setting of $SPAMD_HOST.
$SPAMD_PORT
Use this TCP port number for the command/response data. (defaults to 783)
$SPAMD_REJECT
If this is set, the plugin will reject all messages that are flagged as spam. If $SPAMD_REJECT is not an empty string, that string will be used as the reject message.
$SPAMD_SEND_TIMEOUT
The maximum amount of time to wait for the output buffer to clear when sending data to a SpamAssassin scanner, in milliseconds. (defaults to $SPAMD_TIMEOUT below)
$SPAMD_TIMEOUT
The maximum amount of time to wait for a response from the SpamAssassin scanner, in milliseconds. (defaults to 5000)
$SPAMD_USER
If set, the plugin will tell the scanner to use the configuration for the named user instead of a default configuration.

Sender Action

None

Recipient Action

None

Data Action

None

Message Action

The message is scanned when all the data has been completely transmitted (to prevent timeout issues with sending data to the SpamAssassin server).

mailfront-2.12/plugin-starttls-ucspi.c0000644000000000000000000000425312467132135014770 0ustar #include "mailfront.h" #include #include #include static RESPONSE(start, 220, "2.0.0 Ready to start TLS"); static RESPONSE(earlytalker, 500, "5.5.1 Unexpected pipelined commands following STARTTLS"); static int tls_available = 0; static const response* init(void) { tls_available = getenv("UCSPITLS") != 0; return 0; } static const response* helo(str* hostname, str* capabilities) { if (tls_available) if (!str_cats(capabilities, "STARTTLS\n")) return &resp_oom; return 0; (void)hostname; } static int starttls(void) { int fd; char *fdstr; int extrachars = 0; char c; /* STARTTLS must be the last command in a pipeline, otherwise we can * create a security risk (see CVE-2011-0411). Close input and * check for any extra pipelined commands, so we can give an error * message. Note that this will cause an error on the filehandle, * since we have closed it. */ close(0); while (!ibuf_eof(&inbuf) && !ibuf_error(&inbuf)) { if (ibuf_getc(&inbuf, &c)) ++extrachars; } if (!(fdstr=getenv("SSLCTLFD"))) return 0; if ((fd = atoi(fdstr)) <= 0) return 0; if (write(fd, "y", 1) < 1) return 0; if (!(fdstr=getenv("SSLREADFD"))) return 0; if ((fd = atoi(fdstr)) <= 0) return 0; if (dup2(fd, 0) != 0) return 0; if (!(fdstr=getenv("SSLWRITEFD"))) return 0; if ((fd = atoi(fdstr)) <= 0) return 0; if (dup2(fd, 1) != 1) return 0; /* Re-initialize stdin and clear input buffer */ ibuf_init(&inbuf,0,0,IOBUF_NEEDSCLOSE, 4096); if (extrachars) respond(&resp_earlytalker); return 1; } static int enabled(void) { return tls_available; } static int cmd_STARTTLS(void) { if (!respond(&resp_start)) return 0; if (!starttls()) return 0; tls_available = 0; session_setnum("tls_state", 1); /* Remove UCSPITLS from environment to indicate it no longer available. */ unsetenv("UCSPITLS"); return 1; } static const struct command commands[] = { { "STARTTLS", .fn_enabled = enabled, .fn_noparam = cmd_STARTTLS }, { .name = 0 } }; struct plugin plugin = { .version = PLUGIN_VERSION, .commands = commands, .init = init, .helo = helo, }; mailfront-2.12/plugin-starttls-ucspi.html0000644000000000000000000000167612467132135015520 0ustar

mailfront

Plugin: starttls-ucspi


This plugin uses ucspi-tls to implement the STARTTLS SMTP command, which is used to begin TLS encryption on a plaintext SMTP connection.

Configuration

This module is configured by the following environment variable:

UCSPITLS
Instructs mailfront to offer the STARTTLS command. This variable is removed from the environment after TLS has been negotiated.

Commands

STARTTLS
Implements the SMTP service extension for secure smtp over transport layer security, as specified by RFC 3207.

Sender Action

None

Recipient Action

None

Data Action

None

Message Action

None

mailfront-2.12/plugin-template.c0000644000000000000000000000551212467132135013601 0ustar /* Prototype plugin file. * Remove any functions that are not needed. */ #include "mailfront.h" /* The init function is called once after the plugin is loaded. */ static const response* init(void) { return 0; } /* The helo function is called once by the SMTP protocol when either the * HELO or EHLO command is issued. The parameter is the hostname given * in the command. */ static const response* helo(str* hostname, str* capabilities) { return 0; } /* The reset function is called at least once per message before any of * the envelope or data is processed. */ static const response* reset(void) { return 0; } /* The sender function is called exactly once per message. The parameter * is the sender email addres, and may be modified. */ static const response* sender(str* address, str* params) { return 0; } /* The recipient function is called one or more times per message, once * for each recipient. The parameter is the recipient email address, * and may be modified. */ static const response* recipient(str* address, str* params) { return 0; } /* The data_start function is called when the sender starts transmitting * data. Depending on the protocol, this may happen before (QMTP) or * after (SMTP) the envelope is processed. The parameter is the file * descriptor of the temporary file, or -1 if none was created. */ static const response* data_start(int fd) { return 0; } /* The data_block function is called once for each block of data * received by the protocol. If this function returns an error * response, further data blocks will be received but not processed. */ static const response* data_block(const char* bytes, unsigned long len) { } /* The message_end function is called after both the message envelope * and data have been completely transmitted. The parameter is the file * descriptor of the temporary file, or -1 if none was created. */ static const response* message_end(int fd) { return 0; } /* To define a new command, write the function that will be executed * when the command is invoked, and add it to a "struct command" array * as below. The function is passed the entire command argument, and * must handle sending responses itself. Return positive for success or * 0 to disconnect. */ static int cmd_X_CMD0(void) { return 1; } static int cmd_X_CMD1(str* param) { return 1; } static const struct command commands[] = { { "X-CMD0", .fn_noparam = cmd_X_CMD0 }, { "X-CMD1", .fn_hasparam = cmd_X_CMD1 }, { 0, 0 } }; /* Plugins must export this structure. * Remove any of the entries that are not used (ie 0 or NULL). */ struct plugin plugin = { .version = PLUGIN_VERSION, .flags = 0, .commands = commands, .init = init, .helo = helo, .reset = reset, .sender = sender, .recipient = recipient, .data_start = data_start, .data_block = data_block, .message_end = message_end, }; mailfront-2.12/plugin-template.html0000644000000000000000000000063512467132135014324 0ustar

mailfront

Plugin: accept


This plugin ...

Configuration

None

(defaults to )

Commands

None

Sender Action

None

Recipient Action

None

Data Action

None

Message Action

None

mailfront-2.12/pop3-capa.c0000644000000000000000000000305612467132135012256 0ustar /* pop3-capa.c -- POP3 CAPA command * Copyright (C) 2008 Bruce Guenter or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include "pop3.h" static const char caps[] = "PIPELINING\r\n" "TOP\r\n" "UIDL\r\n" "USER\r\n"; static str auth_resp; void cmd_capa(void) { int sasl; if ((sasl = sasl_auth_caps(&auth_resp)) == -1 || (sasl == 1 && auth_resp.len <= 5)) { respond(err_internal); return; } respond(ok); if (sasl) { obuf_puts(&outbuf, "SASL "); obuf_write(&outbuf, auth_resp.s + 5, auth_resp.len - 5); obuf_puts(&outbuf, CRLF); } obuf_puts(&outbuf, caps); respond("."); } mailfront-2.12/pop3-mainloop.c0000644000000000000000000000432212467132135013165 0ustar /* pop3-mainloop.c - POP3 server main loop * Copyright (C) 2008 Bruce Guenter or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include "pop3.h" const int msg_show_pid = 1; static str line; static str cmd; static str arg; static int parse_line(void) { unsigned i; i = 0; while (i < line.len && line.s[i] != SPACE) ++i; if (!str_copyb(&cmd, line.s, i)) return 0; while (i < line.len && line.s[i] == SPACE) ++i; if (!str_copyb(&arg, line.s+i, line.len-i)) return 0; str_upper(&cmd); return 1; } static void dispatch_line(void) { command* c; for (c = commands; c->name != 0; ++c) { if (str_diffs(&cmd, c->name) == 0) { logmsg(c->sanitized ? c->sanitized : line.s); if (arg.len == 0) { if (c->fn0 == 0) respond(err_syntax); else c->fn0(); } else { if (c->fn1 == 0) respond(err_syntax); else c->fn1(&arg); } return; } } logmsg(line.s); respond(err_unimpl); } extern void set_timeout(void); int main(int argc, char* argv[]) { set_timeout(); if (!startup(argc, argv)) return 0; respond(ok); while (ibuf_getstr_crlf(&inbuf, &line)) { if (!parse_line()) respond(err_internal); else dispatch_line(); } if (ibuf_timedout(&inbuf)) respond("-ERR Connection timed out"); return 0; } mailfront-2.12/pop3-response.c0000644000000000000000000000321612467132135013206 0ustar /* pop3-response.c - POP3 responses * Copyright (C) 2008 Bruce Guenter or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include #include #include "pop3.h" const char err_internal[] = "-ERR Internal error"; const char err_unimpl[] = "-ERR Unimplemented"; const char ok[] = "+OK "; const char err_syntax[] = "-ERR Syntax error"; void logmsg(const char* msg) { obuf_puts(&errbuf, program); obuf_putc(&errbuf, '['); obuf_putu(&errbuf, getpid()); obuf_puts(&errbuf, "]: "); obuf_puts(&errbuf, msg); obuf_putc(&errbuf, '\n'); obuf_flush(&errbuf); } void respond(const char* msg) { logmsg(msg); if (!obuf_puts(&outbuf, msg) || !obuf_putsflush(&outbuf, CRLF)) exit(1); } mailfront-2.12/pop3.h0000644000000000000000000000105112467132135011352 0ustar #ifndef MAIL_FRONT__POP3__H__ #define MAIL_FRONT__POP3__H__ #include "constants.h" struct str; struct command { const char* name; void (*fn0)(void); void (*fn1)(const struct str* s); const char* sanitized; }; typedef struct command command; extern const char err_internal[]; extern const char err_unimpl[]; extern const char ok[]; extern const char err_syntax[]; extern void logmsg(const char* msg); extern void respond(const char*); extern void cmd_capa(void); extern command commands[]; extern int startup(int argc, char* argv[]); #endif mailfront-2.12/pop3front-auth.c0000644000000000000000000001007012467132135013356 0ustar /* pop3front-auth.c -- POP3 authentication front-end * Copyright (C) 2008 Bruce Guenter or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include #include #include #include #include "pop3.h" const char program[] = "pop3front-auth"; const int authenticating = 1; static const char* cvm; static char** nextcmd; static const char* domain; static str user; static unsigned user_count; static unsigned user_max; static unsigned auth_count; static unsigned auth_max; static struct sasl_auth saslauth = { .prefix = "+ " }; static void do_exec(void) { if (!cvm_setugid() || !cvm_setenv()) respond(err_internal); else { alarm(0); execvp(nextcmd[0], nextcmd); respond("-ERR Could not execute second stage"); } _exit(1); } static void cmd_auth_none(void) { static str auth_resp; striter i; switch (sasl_auth_caps(&auth_resp)) { case 0: respond(ok); break; case 1: if (auth_resp.len <= 5) { respond(err_internal); return; } respond(ok); str_lcut(&auth_resp, 5); str_strip(&auth_resp); striter_loop(&i, &auth_resp, ' ') { obuf_write(&outbuf, i.startptr, i.len); obuf_puts(&outbuf, CRLF); } break; default: respond(err_internal); return; } respond("."); } static void cmd_auth(const str* s) { int i; if ((i = sasl_auth1(&saslauth, s)) == 0) do_exec(); obuf_write(&outbuf, "-ERR ", 5); respond(sasl_auth_msg(&i)); ++auth_count; if (auth_max > 0 && auth_count >= auth_max) exit(0); } static void cmd_user(const str* s) { ++user_count; if (user_max > 0 && user_count > user_max) { respond("-ERR Too many USER commands issued"); exit(0); } if (!str_copy(&user, s)) respond(err_internal); else respond(ok); } static void cmd_pass(const str* s) { if (user.len == 0) respond("-ERR Send USER first"); else { int cr; if ((cr = cvm_authenticate_password(cvm, user.s, domain, s->s, 1)) == 0) do_exec(); str_truncate(&user, 0); if (cr == CVME_PERMFAIL) respond("-ERR Authentication failed"); else respond(err_internal); ++auth_count; if (auth_max > 0 && auth_count >= auth_max) exit(0); } } static void cmd_quit(void) { respond(ok); exit(0); } command commands[] = { { "CAPA", cmd_capa, 0, 0 }, { "AUTH", cmd_auth_none, cmd_auth, 0 }, { "PASS", 0, cmd_pass, "PASS XXXXXXXX" }, { "QUIT", cmd_quit, 0, 0 }, { "USER", 0, cmd_user, 0 }, { 0, 0, 0, 0 } }; int startup(int argc, char* argv[]) { static const char usage[] = "usage: pop3front-auth cvm program [args...]\n"; const char* tmp; if ((tmp = getenv("MAXUSERCMD")) != 0) user_max = strtoul(tmp, 0, 10); if ((tmp = getenv("MAXAUTHFAIL")) != 0) auth_max = strtoul(tmp, 0, 10); if ((domain = cvm_ucspi_domain()) == 0) domain = "unknown"; if (argc < 3) { obuf_putsflush(&errbuf, usage); return 0; } cvm = argv[1]; nextcmd = argv+2; if (!sasl_auth_init(&saslauth)) { respond("-ERR Could not initialize SASL AUTH"); return 0; } return 1; } mailfront-2.12/pop3front-maildir.c0000644000000000000000000002572412467132135014052 0ustar /* pop3front-maildir.c -- POP3 main program * Copyright (C) 2008 Bruce Guenter or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include #include #include #include #include #include #include #include "pop3.h" typedef struct { const char* filename; unsigned long size; int read; int deleted; int uid_len; } msg; #define MSG_DELETED ((unsigned long)-1) const char program[] = "pop3front-maildir"; const int authenticating = 0; static str msg_filenames; static msg* msgs; static long max_count; static long max_new_count; static long max_cur_count; static long new_count; static long cur_count; static long del_count; static long msg_count; static long msg_bytes; static long del_bytes; static str tmp; static long scan_dir(const char* subdir, str* list, long* countptr, long max) { DIR* dir; direntry* entry; long count; if ((dir = opendir(subdir)) == 0) return 0; count = 0; while (!(max_count > 0 && msg_count >= max_count) && !(max > 0 && count >= max) && (entry = readdir(dir)) != 0) { if (entry->d_name[0] == '.') continue; if (!str_copys(&tmp, subdir)) return 0; if (!str_catc(&tmp, '/')) return 0; if (!str_cats(&tmp, entry->d_name)) return 0; if (!str_cat(list, &tmp)) return 0; if (!str_catc(list, 0)) return 0; ++count; ++msg_count; } closedir(dir); *countptr = count; return 1; } static void make_msg(msg* m, const char* filename) { struct stat s; const char* c; const char* base = filename + 4; m->filename = filename; m->size = 0; m->read = 0; m->deleted = 0; m->uid_len = strlen(base); /* Parse out flags */ if ((c = memchr(base, ':', m->uid_len)) != 0) { if (c[1] == '2' && c[2] == ',') if (strchr(c+3, 'S') != 0) m->read = 1; m->uid_len = c - base; } /* Parse out Maildir++ message size indicators */ if ((c = memchr(base, ',', m->uid_len)) != 0 && c[1] != 0 && c[2] == '=') { long left = m->uid_len - (c - base); m->uid_len = c - base; /* There may be more than one size indicator, like "UID,W=###,S=###" */ /* Prefer the W (RFC822.SIZE) size over S (raw byte count). */ while (c != 0) { const char* end = memchr(c + 1, ',', left - 1); if ((c[1] == 'W' || (c[1] == 'S' && m->size == 0)) && c[2] == '=') { m->size = strtoul(c + 3, 0, 10); } left -= end - c; c = end; } } /* The UID length is limited to 70 characters RFC 1939 section 7 */ if (m->uid_len > 70) m->uid_len = 70; /* If no size indicator, stat the message to find the size */ if (m->size == 0) { if (stat(filename, &s) == -1) m->size = 0, m->deleted = 1; else m->size = s.st_size; } msg_bytes += m->size; } static int fn_compare(const str_sortentry* a, const str_sortentry* b) { if (a->str[4] < '0' || a->str[4] > '9' || b->str[4] < '0' || b->str[4] > '9') return strcmp(a->str+4, b->str+4); else { int at = atoi(a->str+4); int bt = atoi(b->str+4); return at - bt; } } static int scan_maildir(void) { long pos; long i; msg_bytes = 0; if (!str_truncate(&msg_filenames, 0)) return 0; msg_count = 0; if (!scan_dir("cur", &msg_filenames, &cur_count, max_cur_count)) return 0; if (!scan_dir("new", &msg_filenames, &new_count, max_new_count)) return 0; if (msg_count == 0) return 1; if (!str_sort(&msg_filenames, 0, -1, fn_compare)) return 0; del_count = 0; del_bytes = 0; if (msgs != 0) free(msgs); if ((msgs = malloc(msg_count * sizeof msgs[0])) == 0) return 0; for (i = pos = 0; i < msg_count; pos += strlen(msg_filenames.s+pos)+1, ++i) make_msg(&msgs[i], msg_filenames.s + pos); return 1; } static int msgnum_check(long i) { if (i <= 0 || i > msg_count) respond("-ERR Message number out of range"); else if (msgs[i-1].deleted) respond("-ERR Message was deleted"); else return 1; return 0; } static long msgnum(const str* arg) { long i; char* end; if ((i = strtol(arg->s, &end, 10)) < 0 || *end != 0) respond(err_syntax); else if (msgnum_check(i)) return i; return 0; } static void dump_msg(long num, long bodylines) { ibuf in; static char buf[4096]; int in_header; /* True until a blank line is seen */ int sol; /* True if at start of line */ if (!ibuf_open(&in, msgs[num-1].filename, 0)) return respond("-ERR Could not open that message"); respond(ok); sol = in_header = 1; while (ibuf_read(&in, buf, sizeof buf) || in.count) { const char* ptr = buf; const char* end = buf + in.count; while (ptr < end) { const char* lfptr; if (sol) { if (!in_header) if (--bodylines < 0) break; if (*ptr == '.') obuf_putc(&outbuf, '.'); } if ((lfptr = memchr(ptr, LF, end-ptr)) == 0) { obuf_write(&outbuf, ptr, end-ptr); ptr = end; sol = 0; } else { if (in_header && lfptr == ptr) in_header = 0; obuf_write(&outbuf, ptr, lfptr-ptr); obuf_puts(&outbuf, CRLF); ptr = lfptr + 1; sol = 1; } } } ibuf_close(&in); obuf_puts(&outbuf, CRLF); respond("."); } /* Mark a maildir filename with the named flag */ static int add_flag(str* fn, char flag) { int c; /* If the filename has no flags, append them */ if ((c = str_findfirst(fn, ':')) == -1) { if (!str_cats(fn, ":2,")) return 0; } else { /* If it has a colon (start of flags), see if they are a type we * recognize, and bail out if they aren't */ if (fn->s[c+1] != '2' || fn->s[c+2] != ',') return 1; /* Scan through the flag characters and return success * if the message is already marked with the flag */ if (strchr(fn->s+c+3, flag) != 0) return 1; } return str_catc(fn, flag); } /* Commands ******************************************************************/ static void cmd_dele(const str* arg) { long i; if ((i = msgnum(arg)) == 0) return; --i; del_bytes += msgs[i].size; del_count++; msgs[i].deleted = 1; respond(ok); } static void cmd_last(void) { long last; long i; for (last = i = 0; i < msg_count; i++) if (msgs[i].read) last = i + 1; if (!str_copys(&tmp, "+OK ") || !str_cati(&tmp, last)) respond(err_internal); respond(tmp.s); } static void cmd_list(void) { long i; respond(ok); for (i = 0; i < msg_count; i++) { if (!msgs[i].deleted) { obuf_putu(&outbuf, i+1); obuf_putc(&outbuf, SPACE); obuf_putu(&outbuf, msgs[i].size); obuf_puts(&outbuf, CRLF); } } respond("."); } static void cmd_list_one(const str* arg) { long i; if ((i = msgnum(arg)) == 0) return; if (!str_copys(&tmp, "+OK ") || !str_catu(&tmp, i) || !str_catc(&tmp, SPACE) || !str_catu(&tmp, msgs[i-1].size)) respond(err_internal); else respond(tmp.s); } static void cmd_noop(void) { respond(ok); } static void cmd_quit(void) { long i; for (i = 0; i < msg_count; i++) { const char* fn = msgs[i].filename; if (msgs[i].deleted) unlink(fn); /* Logic: * 1. move all messages into "cur" * 2. tag all read messages without flags with a read flag (:2,S) * Note: no real opportunity to report errors, * so just continue when we hit one. */ else { if (!str_copys(&tmp, "cur/")) continue; if (!str_cats(&tmp, fn+4)) continue; if (msgs[i].read && !add_flag(&tmp, 'S')) continue; rename(fn, tmp.s); } } respond(ok); exit(0); } static void cmd_rset(void) { if (!scan_maildir()) { respond(err_internal); exit(1); } respond(ok); } static void cmd_stat(void) { if (!str_copys(&tmp, "+OK ") || !str_catu(&tmp, msg_count - del_count) || !str_catc(&tmp, SPACE) || !str_catu(&tmp, msg_bytes - del_bytes)) respond(err_internal); else respond(tmp.s); } static void cmd_top(const str* arg) { long num; long lines; char* end; if ((num = strtol(arg->s, &end, 10)) < 0) return respond(err_syntax); if (!msgnum_check(num)) return; while (*end == SPACE) ++end; if (*end == 0) { msgs[num-1].read = 1; return dump_msg(num, LONG_MAX); } if ((lines = strtol(end, &end, 10)) < 0 || *end != 0) return respond(err_syntax); dump_msg(num, lines); } static void cmd_uidl(void) { long i; respond(ok); for (i = 0; i < msg_count; i++) { msg* m = &msgs[i]; if (!m->deleted) { const char* fn = m->filename + 4; obuf_putu(&outbuf, i+1); obuf_putc(&outbuf, SPACE); obuf_write(&outbuf, fn, m->uid_len); obuf_puts(&outbuf, CRLF); } } respond("."); } static void cmd_uidl_one(const str* arg) { long i; if ((i = msgnum(arg)) != 0) { msg* m = &msgs[i-1]; const char* fn = m->filename + 4; if (!str_copys(&tmp, "+OK ") || !str_catu(&tmp, i) || !str_catc(&tmp, SPACE) || !str_catb(&tmp, fn, m->uid_len)) respond(err_internal); else respond(tmp.s); } } command commands[] = { { "CAPA", cmd_capa, 0, 0 }, { "DELE", 0, cmd_dele, 0 }, { "LAST", cmd_last, 0, 0 }, { "LIST", cmd_list, cmd_list_one, 0 }, { "NOOP", cmd_noop, 0, 0 }, { "QUIT", cmd_quit, 0, 0 }, { "RETR", 0, cmd_top, 0 }, { "RSET", cmd_rset, 0, 0 }, { "STAT", cmd_stat, 0, 0 }, { "TOP", 0, cmd_top, 0 }, { "UIDL", cmd_uidl, cmd_uidl_one, 0 }, { 0, 0, 0, 0 } }; extern void report_io_bytes(void); int startup(int argc, char* argv[]) { const char* env; if (argc > 2) { msg3("usage: ", program, " [default-maildir]"); return 0; } if ((env = getenv("MAX_MESSAGES")) != 0) max_count = atol(env); if ((env = getenv("MAX_CUR_MESSAGES")) != 0) max_cur_count = atol(env); if ((env = getenv("MAX_NEW_MESSAGES")) != 0) max_new_count = atol(env); if ((env = getenv("MAILBOX")) == 0) { if (argc < 2) { error1("Mailbox not specified"); return 0; } env = argv[1]; } if (chdir(env) == -1) { respond("-ERR Could not chdir to maildir"); return 0; } if (!scan_maildir()) { respond("-ERR Could not access maildir"); return 0; } atexit(report_io_bytes); return 1; } mailfront-2.12/pop3front.html0000644000000000000000000000453012467132135013145 0ustar

MailFront

POP3 Front End


The POP3 front end is composed of two pieces: an authentication front end and a transfer back-end.

Connections are timed out after $TIMEOUT seconds of inactivity (defaults to 1200 seconds or 20 minutes), or $SESSION_TIMEOUT seconds after the connection was established (defaults to 86400 seconds or 24 hours).

pop3front-auth

Usage: pop3front-auth CVM PROGRAM [ ARGS ... ]

pop3front-auth authenticates the username and password sent by the client using the named CVM. If successful, it sets up the environment and executes PROGRAM. It also offers RFC 1734 complient AUTH support through cvm-sasl.

If $AUTH_TIMEOUT or $AUTH_SESSION_TIMEOUT are set, they override $TIMEOUT and $SESSION_TIMEOUT respectively.

If $MAXUSERCMD is set, no more than the specified number of the USER command may be issued. If $MAXAUTHFAIL is set, no more than the specified number of authentication failures may occur. After these limits are reached, the client is disconnected.

pop3front-maildir

Usage: pop3front-maildir [ DEFAULT-MAILDIR ]

pop3front-maildir serves messages via POP3 out of a maildir. If $MAILBOX is set, its contents are used as the path to the mailbox, otherwise the DEFAULT-MAILDIR argument must be present. If $MAX_MESSAGES is set, the total number of accessable messages will be limited to that number. In addition, if either of $MAX_CUR_MESSAGES or $MAX_NEW_MESSAGES are set, the total number of accessable messages in the cur and new subdirectories respectively will each be limited to that number.

If the filenames in the maildir contain a size indicator, as specified here for Courier IMAP and here for Dovecot, this program will avoid using stat to calculate the file size. This is a significant performance optimization on systems with either very large or very many mailboxes.

mailfront-2.12/protocol-qmqp.c0000644000000000000000000000466012467132135013312 0ustar #include #include #include #include #include #include #include #include "mailfront.h" #include "qmtp.h" static const response* resp; static char buf[8192]; static str line; static void die(const char* msg) { response r = { 451, msg }; respond(&r); exit(111); } static void get_wrapper(ibuf* in) { unsigned long wraplen; switch (get_netstring_len(in, &wraplen)) { case -1: exit(0); case 0: die("Invalid wrapper netstring"); } } static void get_body(ibuf* in) { unsigned long bodylen; char nl; switch (get_netstring_len(in, &bodylen)) { case -1: exit(0); case 0: die("Invalid message body netstring"); } if (bodylen == 0) die("Zero length message"); if (response_ok(resp)) resp = handle_data_start(); while (bodylen > 0) { unsigned long len = sizeof buf; if (len > bodylen) len = bodylen; if (!ibuf_read(in, buf, len) && in->count == 0) die("EOF while reading body"); if (response_ok(resp)) handle_data_bytes(buf, in->count); bodylen -= in->count; } if (!ibuf_getc(in, &nl)) die("EOF while reading comma"); if (nl != ',') die("Invalid netstring terminator"); } static void get_sender(ibuf* in) { switch (get_netstring(in, &line)) { case -1: die("EOF while reading sender address"); case 0: die("Invalid sender netstring"); } msg3("sender <", line.s, ">"); if (response_ok(resp)) resp = handle_sender(&line, 0); } static void get_recips(ibuf* in) { char ch; while (ibuf_peek(in, &ch)) { if (ch == ',') return; switch (get_netstring(in, &line)) { case -1: die("EOF while reading recipient list"); case 0: die("Invalid recipient netstring"); } msg3("recipient <", line.s, ">"); if (response_ok(resp)) resp = handle_recipient(&line, 0); } die("EOF before end of recipient list"); } static void get_package(ibuf* in) { resp = handle_reset(); get_wrapper(in); get_body(in); get_sender(in); get_recips(in); if (response_ok(resp)) resp = handle_message_end(); if (!resp) resp = &resp_accepted_message; if (!respond(resp)) die("EOF while sending response"); } static int mainloop(const struct command* commands) { alarm(3600); get_package(&inbuf); return 0; (void)commands; } struct protocol protocol = { .version = PROTOCOL_VERSION, .name = "QMQP", .respond_line = qmtp_respond_line, .mainloop = mainloop, }; mailfront-2.12/protocol-qmqp.html0000644000000000000000000000101112467132135014017 0ustar

MailFront

Protocol: qmqp


The QMQP protocol module implements the Quick Mail Queueing Protocol created by D. J. Bernstein, the creator of qmail. The protocol is designed for the specific situation where one system (without a mail queue) sends its mail to another system for queueing (distinct from relaying).

mailfront-2.12/protocol-qmtp.c0000644000000000000000000000542612467132135013316 0ustar #include #include #include #include #include #include #include #include "mailfront.h" #include "qmtp.h" static const response* resp; static char buf[8192]; static str line; static str tmp; static void die(const char* msg) { response r = { 451, msg }; respond(&r); exit(111); } static void get_body(ibuf* in) { unsigned long bodylen; char nl; switch (get_netstring_len(in, &bodylen)) { case -1: exit(0); case 0: die("Invalid message body netstring"); } if (bodylen == 0) die("Zero length message"); --bodylen; if (!ibuf_getc(in, &nl)) die("EOF while reading body NL"); if (nl != LF) die("Cannot handle non-LF line terminator"); if (response_ok(resp)) resp = handle_data_start(); while (bodylen > 0) { unsigned long len = sizeof buf; if (len > bodylen) len = bodylen; if (!ibuf_read(in, buf, len) && in->count == 0) die("EOF while reading body"); if (response_ok(resp)) handle_data_bytes(buf, in->count); bodylen -= in->count; } if (!ibuf_getc(in, &nl)) die("EOF while reading comma"); if (nl != ',') die("Invalid netstring terminator"); } static void get_sender(ibuf* in) { switch (get_netstring(in, &line)) { case -1: die("EOF while reading sender address"); case 0: die("Invalid sender netstring"); } msg3("sender <", line.s, ">"); if (response_ok(resp)) resp = handle_sender(&line, 0); } static void get_recips(ibuf* in) { unsigned long i; switch (get_netstring(in, &line)) { case -1: die("EOF while reading recipient list"); case 0: die("Invalid recipient netstring"); } for (i = 0; response_ok(resp) && i < line.len; i++) { unsigned long j; unsigned long len; for (len = 0, j = i; j < line.len; ++j) { if (line.s[j] == ':') break; if (line.s[j] < '0' || line.s[j] > '9') die("Invalid netstring length"); len = len * 10 + line.s[j] - '0'; } ++j; if (j + len > line.len) die("Netstring length too long"); if (line.s[j+len] != ',') die("Netstring missing comma"); str_copyb(&tmp, line.s+j, len); msg3("recipient <", tmp.s, ">"); if (response_ok(resp)) resp = handle_recipient(&tmp, 0); i = j + len; } } static void get_package(ibuf* in) { resp = handle_reset(); get_body(in); get_sender(in); get_recips(in); if (response_ok(resp)) resp = handle_message_end(); if (!resp) resp = &resp_accepted_message; if (!respond(resp)) die("EOF while sending response"); } static int mainloop(const struct command* commands) { alarm(3600); for (;;) get_package(&inbuf); return 0; (void)commands; } struct protocol protocol = { .version = PROTOCOL_VERSION, .name = "QMTP", .respond_line = qmtp_respond_line, .mainloop = mainloop, }; mailfront-2.12/protocol-qmtp.html0000644000000000000000000000065412467132135014036 0ustar

MailFront

Protocol: qmtp


The QMTP protocol module implements the Quick Mail Transfer Protocol created by D. J. Bernstein, the creator of qmail. The protocol is designed for high speed mail transmission between MTAs.

mailfront-2.12/protocol-smtp.c0000644000000000000000000002106412467132135013314 0ustar #include #include #include #include "mailfront.h" #include #include extern struct protocol protocol; static str line = {0,0,0}; static str domain_name = {0,0,0}; static unsigned long maxnotimpl = 0; static str str_welcome; static str cmd; static str arg; static str addr; static str params; static str init_capabilities; static RESPONSE(no_mail, 503, "5.5.1 You must send MAIL FROM: first"); static RESPONSE(vrfy, 252, "2.5.2 Send some mail, I'll try my best."); static RESPONSE(help, 214, "2.0.0 Help not available."); static RESPONSE(no_rcpt, 503, "5.5.1 You must send RCPT TO: first"); static RESPONSE(data_ok, 354, "End your message with a period on a line by itself."); static RESPONSE(ok, 250, "2.3.0 OK"); static RESPONSE(unimp, 500, "5.5.1 Not implemented."); static RESPONSE(badaddr, 501, "5.5.2 Syntax error in address parameter."); static RESPONSE(needsparam, 501, "5.5.2 Syntax error, command requires a parameter."); static RESPONSE(noparam, 501, "5.5.2 Syntax error, no parameters allowed."); static RESPONSE(toomanyunimp, 503, "5.5.0 Too many unimplemented commands.\n5.5.0 Closing connection."); static RESPONSE(goodbye, 221, "2.0.0 Good bye."); static int saw_mail = 0; static int saw_rcpt = 0; static const response* parse_addr_arg(void) { unsigned i; char term; int quoted; if (!str_truncate(&addr, 0)) return &resp_oom; if (!str_truncate(¶ms, 0)) return &resp_oom; addr.len = 0; if ((i = str_findfirst(&arg, LBRACE) + 1) != 0) term = RBRACE; else { term = SPACE; if ((i = str_findfirst(&arg, COLON) + 1) == 0) if ((i = str_findfirst(&arg, SPACE) + 1) == 0) return &resp_badaddr; while (i < arg.len && arg.s[i] == SPACE) ++i; } for (quoted = 0; i < arg.len && (quoted || arg.s[i] != term); ++i) { switch (arg.s[i]) { case QUOTE: quoted = !quoted; break; case ESCAPE: ++i; /* fall through */ default: if (!str_catc(&addr, arg.s[i])) return &resp_oom; } } ++i; if (i > arg.len) return &resp_badaddr; while (i < arg.len && arg.s[i] == SPACE) ++i; if (!str_copyb(¶ms, arg.s+i, arg.len-i)) return &resp_oom; str_subst(¶ms, ' ', 0); /* strip source routing */ if (addr.s[0] == AT && (i = str_findfirst(&addr, COLON) + 1) != 0) str_lcut(&addr, i); return 0; } static int QUIT(void) { respond(&resp_goodbye); exit(0); return 0; } static int HELP(void) { return respond(&resp_help); } static int HELO(void) { const response* resp; if (response_ok(resp = handle_reset())) resp = handle_helo(&arg, &line); return (resp != 0) ? respond(resp) : respond_line(250, 1, domain_name.s, domain_name.len); } static int EHLO(void) { const response* resp; protocol.name = "ESMTP"; line.len = 0; if (!response_ok(resp = handle_reset()) || !response_ok(resp = handle_helo(&arg, &line))) return respond(resp); if (!str_cat(&line, &init_capabilities)) { respond(&resp_oom); return 0; } if (!respond_line(250, 0, domain_name.s, domain_name.len)) return 0; return respond_multiline(250, 1, line.s); } static void do_reset(void) { const response* resp; if (!response_ok(resp = handle_reset())) { respond(resp); exit(0); } saw_rcpt = 0; saw_mail = 0; } // FIXME: if rules_reset fails, exit static int MAIL(void) { const response* resp; msg2("MAIL ", arg.s); do_reset(); if ((resp = parse_addr_arg()) == 0) { if ((resp = handle_sender(&addr, ¶ms)) == 0) resp = &resp_accepted_sender; if (number_ok(resp)) { saw_mail = 1; } } return respond(resp); } static int RCPT(void) { const response* resp; msg2("RCPT ", arg.s); if (!saw_mail) return respond(&resp_no_mail); if ((resp = parse_addr_arg()) == 0) { if ((resp = handle_recipient(&addr, ¶ms)) == 0) resp = &resp_accepted_recip; if (number_ok(resp)) saw_rcpt = 1; } return respond(resp); } static int RSET(void) { do_reset(); return respond(&resp_ok); } static char data_buf[4096]; static unsigned long data_bytes; static unsigned data_bufpos; static void data_start(void) { data_bytes = data_bufpos = 0; } static void data_byte(char ch) { data_buf[data_bufpos++] = ch; ++data_bytes; if (data_bufpos >= sizeof data_buf) { handle_data_bytes(data_buf, data_bufpos); data_bufpos = 0; } } static void message_end(void) { if (data_bufpos) handle_data_bytes(data_buf, data_bufpos); } static int copy_body(void) { int sawcr = 0; /* Was the last character a CR */ unsigned linepos = 0; /* The number of bytes since the last LF */ int sawperiod = 0; /* True if the first character was a period */ char ch; data_start(); while (ibuf_getc(&inbuf, &ch)) { switch (ch) { case LF: if (sawperiod && linepos == 0) { message_end(); return 1; } data_byte(ch); sawperiod = sawcr = linepos = 0; break; case CR: if (sawcr) { data_byte(CR); ++linepos; } sawcr = 1; break; default: if (ch == PERIOD && !sawperiod && linepos == 0) sawperiod = 1; else { sawperiod = 0; if (sawcr) { data_byte(CR); ++linepos; sawcr = 0; } data_byte(ch); ++linepos; } } } return 0; } static int DATA(void) { const response* resp; if (!saw_mail) return respond(&resp_no_mail); if (!saw_rcpt) return respond(&resp_no_rcpt); if (!response_ok(resp = handle_data_start())) return respond(resp); if (!respond(&resp_data_ok)) return 0; if (!copy_body()) { do_reset(); return 0; } if ((resp = handle_message_end()) == 0) resp = &resp_accepted_message; return respond(resp); } static int NOOP(void) { return respond(&resp_ok); } static int VRFY(void) { return respond(&resp_vrfy); } typedef int (*dispatch_fn)(void); struct dispatch { const char* cmd; dispatch_fn fn; }; static struct dispatch dispatch_table[] = { { "DATA", DATA }, { "EHLO", EHLO }, { "HELO", HELO }, { "HELP", HELP }, { "MAIL", MAIL }, { "NOOP", NOOP }, { "QUIT", QUIT }, { "RCPT", RCPT }, { "RSET", RSET }, { "VRFY", VRFY }, { 0, 0 } }; static int parse_line(void) { unsigned i; for (i = 0; i < line.len; i++) { if (line.s[i] == SPACE || line.s[i] == TAB) { unsigned j = i; while (j < line.len && (line.s[j] == SPACE || line.s[j] == TAB)) ++j; return str_copyb(&cmd, line.s, i) && str_copyb(&arg, line.s+j, line.len-j); } } return str_copy(&cmd, &line) && str_truncate(&arg, 0); } int smtp_dispatch(const struct command* commands) { static unsigned long notimpl = 0; struct dispatch* d; const struct command* c; if (!parse_line()) return 1; for (c = commands; c->name != 0; c++) if (strcasecmp(c->name, cmd.s) == 0) { if (c->fn_enabled == 0 || c->fn_enabled()) { notimpl = 0; if (arg.len == 0) { if (c->fn_noparam == 0) return respond(&resp_noparam); return c->fn_noparam(); } else { if (c->fn_hasparam == 0) return respond(&resp_needsparam); return c->fn_hasparam(&arg); } } } for (d = dispatch_table; d->cmd != 0; ++d) if (strcasecmp(d->cmd, cmd.s) == 0) { notimpl = 0; return d->fn(); } msg3(cmd.s, " ", arg.s); if (maxnotimpl > 0 && ++notimpl > maxnotimpl) { respond(&resp_toomanyunimp); return 0; } return respond(&resp_unimp); } static int init(void) { const char* tmp; if ((tmp = getprotoenv("LOCALHOST")) == 0) tmp = UNKNOWN; str_copys(&domain_name, tmp); if ((tmp = getenv("SMTPGREETING")) != 0) str_copys(&str_welcome, tmp); else { str_copy(&str_welcome, &domain_name); str_cats(&str_welcome, " mailfront"); } str_cats(&str_welcome, " ESMTP"); if ((tmp = getenv("MAXNOTIMPL")) != 0) maxnotimpl = strtoul(tmp, 0, 10); if (!str_cats(&init_capabilities, "8BITMIME\nENHANCEDSTATUSCODES\nPIPELINING")) { respond(&resp_oom); return 1; } return 0; } static int mainloop(const struct command* commands) { if (!respond_line(220, 1, str_welcome.s, str_welcome.len)) return 0; while (ibuf_getstr_crlf(&inbuf, &line)) if (!smtp_dispatch(commands)) { if (ibuf_eof(&inbuf)) msg1("Connection dropped"); if (ibuf_timedout(&inbuf)) msg1("Timed out"); return 1; } return 0; } static int smtp_respond_line(unsigned num, int final, const char* msg, unsigned long len) { return obuf_putu(&outbuf, num) && obuf_putc(&outbuf, final ? ' ' : '-') && obuf_write(&outbuf, msg, len) && obuf_puts(&outbuf, CRLF); } struct protocol protocol = { .version = PROTOCOL_VERSION, .name = "SMTP", .respond_line = smtp_respond_line, .init = init, .mainloop = mainloop, }; mailfront-2.12/protocol-smtp.html0000644000000000000000000000333012467132135014032 0ustar

MailFront

Protocol: smtp


The SMTP protocol module has the following features:

  • Handles RFC 2554 SMTP authentication. Note that the require-auth plugin and/or the relayclient plugin will need to be loaded to make use of this authentication.
  • Automatically handles either bare NL or RFC 821 / RFC 2821 compliant CR/NL end-of-line conventions.
  • Times out connections after $TIMEOUT seconds of inactivity (defaults to 1200 seconds or 20 minutes), or $SESSION_TIMEOUT seconds after the connection was established (defaults to 86400 seconds or 24 hours).
  • All error responses are logged.
  • Handles (ignores) RFC 1869 extended parameters on the RCPT TO: and MAIL FROM: commands.
  • Initial greeting message is configureable by $SMTPGREETING. If that is not set, the greeting is generated based on the domain name in ${$PROTO}LOCALHOST set by the invoking UCSPI server such as tcpserver.
  • Supports RFC 1870 SMTP Service Extension for Message Size Declaration.
  • If $MAXNOTIMPL is set, clients are disconnected if they send more than the specified number of commands that result in a "500 Not implemented." error.
mailfront-2.12/qmqpfront-echo.sh0000644000000000000000000000005612467132135013623 0ustar exec "$(dirname $0)"/mailfront qmqp echo "$@" mailfront-2.12/qmqpfront-qmail.sh0000644000000000000000000000021312467132135014003 0ustar exec "$(dirname $0)"/mailfront qmqp qmail check-fqdn counters mailrules relayclient cvm-validate qmail-validate add-received patterns "$@" mailfront-2.12/qmtp-respond.c0000644000000000000000000000132412467132135013120 0ustar #include #include "responses.h" #include "qmtp.h" #include #include int qmtp_respond_line(unsigned num, int final, const char* msg, unsigned long len) { static str resp; char c; if (resp.len > 0) if (!str_catc(&resp, '\n')) return 0; if (!str_catb(&resp, msg, len)) return 0; if (final) { c = (num >= 500) ? 'D' : (num >= 400 || num < 200) ? 'Z' : 'K'; if (!obuf_putu(&outbuf, resp.len + 1)) return 0; if (!obuf_putc(&outbuf, ':')) return 0; if (!obuf_putc(&outbuf, c)) return 0; if (!obuf_write(&outbuf, resp.s, resp.len)) return 0; if (!obuf_putc(&outbuf, ',')) return 0; resp.len = 0; } return 1; } mailfront-2.12/qmtp.h0000644000000000000000000000024612467132135011457 0ustar #ifndef MAIL_FRONT__QMTP__H__ #define MAIL_FRONT__QMTP__H__ #include "responses.h" extern int qmtp_respond_line(unsigned, int, const char*, unsigned long); #endif mailfront-2.12/qmtpfront-echo.sh0000644000000000000000000000005612467132135013626 0ustar exec "$(dirname $0)"/mailfront qmtp echo "$@" mailfront-2.12/qmtpfront-qmail.sh0000644000000000000000000000021312467132135014006 0ustar exec "$(dirname $0)"/mailfront qmtp qmail check-fqdn counters mailrules relayclient cvm-validate qmail-validate add-received patterns "$@" mailfront-2.12/queuedir.c0000644000000000000000000001057312467132135012320 0ustar #include "mailfront.h" #include #include #include #include #include #include #include #include #include static str destpath; static str temppath; static str destname; static str tempname; static int tmpfd; static obuf msgbuf; static const char* env_prefix; static str env_tmpdir; static str env_destdir; static str env_nosync; static RESPONSE(createerr, 451, "4.3.0 Error creating queue file"); static RESPONSE(writeerr, 451, "4.3.0 Error writing queue file"); static RESPONSE(configerr, 451, "4.3.0 Missing backend configuration parameter"); void queuedir_init(const char* prefix) { env_prefix = prefix; wrap_str(str_copy2s(&env_tmpdir, prefix, "_TMP")); wrap_str(str_copy2s(&env_destdir, prefix, "_DEST")); wrap_str(str_copy2s(&env_nosync, prefix, "_NOSYNC")); } const response* queuedir_reset(void) { if (tempname.len) unlink(tempname.s); if (destname.len) unlink(destname.s); tempname.len = destname.len = 0; return 0; } static int make_filename(str* s, const struct timeval* tv, pid_t pid) { return str_copyf(s, "d{.}06d{.}d", tv->tv_sec, tv->tv_usec, pid); } static const response* make_filenames(void) { static str filename; pid_t pid = getpid(); for (;;) { struct timeval tv; struct stat st; gettimeofday(&tv, 0); if (!make_filename(&filename, &tv, pid)) return &resp_oom; if (!str_copyf(&tempname, "S{/}S", &temppath, &filename)) return &resp_oom; if (lstat(tempname.s, &st) == 0) continue; if (errno != ENOENT) return &resp_internal; if (!str_copyf(&destname, "S{/}S", &destpath, &filename)) return &resp_oom; if (lstat(destname.s, &st) != 0) { if (errno != ENOENT) return &resp_internal; return 0; } sleep(1); } } const response* queuedir_sender(str* address, str* params) { const response* r; const char* destdir = session_getenv(env_prefix); const char* tempsubdir = session_getenv(env_tmpdir.s); const char* destsubdir = session_getenv(env_destdir.s); if (destdir == 0) return &resp_configerr; if (tempsubdir == 0) tempsubdir = "tmp"; if (destsubdir == 0) destsubdir = "new"; if (!str_copyf(&destpath, "s{/}s", destdir, destsubdir) || !str_copyf(&temppath, "s{/}s", destdir, tempsubdir)) return &resp_oom; if ((r = make_filenames()) != 0) return r; obuf_close(&msgbuf); if (!obuf_open(&msgbuf, tempname.s, OBUF_CREATE | OBUF_EXCLUSIVE, 0666, 0)) return &resp_createerr; if (!obuf_putstr(&msgbuf, address) || !obuf_putc(&msgbuf, 0)) { queuedir_reset(); return &resp_writeerr; } return 0; (void)params; } const response* queuedir_recipient(str* address, str* params) { if (!obuf_putstr(&msgbuf, address) || !obuf_putc(&msgbuf, 0)) return &resp_writeerr; return 0; (void)params; } const response* queuedir_data_start(int fd) { /* Sender hasn't been sent, so save the message to a temporary file. */ if (destname.len == 0) { if ((tmpfd = scratchfile()) < 0) return &resp_writeerr; } else { tmpfd = 0; if (!obuf_putc(&msgbuf, 0)) return &resp_writeerr; } return 0; (void)fd; } const response* queuedir_data_block(const char* bytes, unsigned long len) { if (tmpfd > 0) { if ((unsigned long)write(tmpfd, bytes, len) != len) return &resp_writeerr; } else if (!obuf_write(&msgbuf, bytes, len)) return &resp_writeerr; return 0; } const response* queuedir_message_end(int fd) { int dosync = session_getenv(env_nosync.s) == 0; /* If using a temporary file, copy it to the output. */ if (tmpfd > 0) { if (lseek(tmpfd, SEEK_SET, 0) != 0 || !obuf_copyfromfd(tmpfd, &msgbuf)) { close(tmpfd); tmpfd = 0; return &resp_writeerr; } close(tmpfd); tmpfd = 0; } /* Flush and close the output. */ if ((dosync && !obuf_sync(&msgbuf)) || !obuf_close(&msgbuf)) { queuedir_reset(); return &resp_writeerr; } if (link(tempname.s, destname.s) != 0) { queuedir_reset(); return &resp_writeerr; } if (dosync) { if ((fd = open(destpath.s, O_DIRECTORY | O_RDONLY)) < 0) { queuedir_reset(); return &resp_internal; } if (fsync(fd) != 0) { queuedir_reset(); return &resp_writeerr; } close(fd); } unlink(tempname.s); tempname.len = 0; destname.len = 0; return 0; } mailfront-2.12/responses.c0000644000000000000000000000066112467132135012513 0ustar #include "responses.h" RESPONSE(accepted_message, 250, "2.6.0 Message accepted."); RESPONSE(accepted_sender, 250, "2.1.0 Sender accepted."); RESPONSE(accepted_recip, 250, "2.1.5 Recipient accepted."); RESPONSE(internal, 451, "4.3.0 Internal error."); RESPONSE(oom, 451, "4.3.0 Out of memory."); int number_ok(const response* r) { return r->number < 400; } int response_ok(const response* r) { return r == 0 || number_ok(r); } mailfront-2.12/responses.h0000644000000000000000000000103112467132135012510 0ustar #ifndef MAIL_FRONT__RESPONSES__H__ #define MAIL_FRONT__RESPONSES__H__ struct response { unsigned number; const char* message; }; typedef struct response response; extern const response resp_accepted_message; extern const response resp_accepted_sender; extern const response resp_accepted_recip; extern const response resp_internal; extern const response resp_oom; #define RESPONSE(NAME,CODE,MSG) const response resp_##NAME = {CODE,MSG} extern int number_ok(const response* r); extern int response_ok(const response* r); #endif mailfront-2.12/session.c0000644000000000000000000000617112467132135012157 0ustar #include #include #include #include #include "mailfront-internal.h" struct session session = { .protocol = 0, }; const char* session_protocol(void) { return session.protocol->name; } const char* session_getenv(const char* name) { const char* s; if ((s = envstr_get(&session.env, name)) == 0) s = getenv(name); return s; } static unsigned long min_u_s(unsigned long u, const char* s) { unsigned long newu; if (s != 0) { if ((newu = strtoul(s, (char**)&s, 10)) != 0 && *s == 0 && (u == 0 || newu < u)) u = newu; } return u; } /* Returns the smallest non-zero value set */ unsigned long session_getenvu(const char* name) { unsigned i; const unsigned namelen = strlen(name); unsigned long val; val = min_u_s(0, getenv(name)); for (i = 0; i < session.env.len; i += strlen(session.env.s + i) + 1) { if (memcmp(session.env.s + i, name, namelen) == 0 && session.env.s[i + namelen] == '=') val = min_u_s(val, session.env.s + i + namelen + 1); } return val; } int session_exportenv(void) { unsigned i; for (i = 0; i < session.env.len; i += strlen(session.env.s + i) + 1) if (putenv(session.env.s + i) != 0) return 0; return 1; } int session_putenv(const char* s) { if (session.env.len > 0) if (!str_catc(&session.env, 0)) return 0; return str_catb(&session.env, s, strlen(s) + 1); } int session_setenv(const char* name, const char* value, int overwrite) { return envstr_set(&session.env, name, value, overwrite); } void session_resetenv(void) { session.env.len = 0; } GHASH_DEFN(session_strs,const char*,const char*, adt_hashsp,adt_cmpsp,0,adt_copysp,0,adt_freesp); GHASH_DEFN(session_nums,const char*,unsigned long, adt_hashsp,adt_cmpsp,0,0,0,0); void session_delnum(const char* name) { session_nums_remove(&session.nums, &name); } void session_delstr(const char* name) { session_strs_remove(&session.strs, &name); } const char* session_getstr(const char* name) { struct session_strs_entry* p; if ((p = session_strs_get(&session.strs, &name)) == 0) return 0; return p->data; } void session_setstr(const char* name, const char* value) { /* FIXME: use _set when bglibs 1.103 is released */ session_strs_remove(&session.nums, &name); if (session_strs_add(&session.strs, &name, &value) == 0) die_oom(111); } int session_hasnum(const char* name, unsigned long* num) { struct session_nums_entry* p; if ((p = session_nums_get(&session.nums, &name)) == 0) return 0; if (num != 0) *num = p->data; return 1; } unsigned long session_getnum(const char* name, unsigned long dflt) { struct session_nums_entry* p; if ((p = session_nums_get(&session.nums, &name)) == 0) return dflt; return p->data; } void session_setnum(const char* name, unsigned long value) { /* FIXME: use _set when bglibs 1.103 is released */ session_nums_remove(&session.nums, &name); if (session_nums_add(&session.nums, &name, &value) == 0) die_oom(111); } void session_init(void) { memset(&session, 0, sizeof session); session.fd = -1; session_strs_init(&session.strs); session_nums_init(&session.nums); } mailfront-2.12/smtpfront-echo.sh0000644000000000000000000000005612467132135013630 0ustar exec "$(dirname $0)"/mailfront smtp echo "$@" mailfront-2.12/smtpfront-qmail.sh0000644000000000000000000000023412467132135014013 0ustar exec "$(dirname $0)"/mailfront smtp qmail cvm-authenticate check-fqdn counters mailrules relayclient cvm-validate qmail-validate add-received patterns "$@" mailfront-2.12/std-handle.html0000644000000000000000000000442112467132135013235 0ustar

MailFront

Standard Handlers


Overview

The most useful protocol front-ends and delivery back-ends are joined by a set of standard handlers. These handlers integrate the operation of mail rules, pattern matching, several miscellaneous options and back-end validation and delivery functions.

Features

The following features are common to all front-ends that use the standard handlers:

  • Validates senders and recipients according to mail rules processing.
  • Requires all addresses except the null sender to contain a fully qualified domain name.
  • If $RELAYCLIENT is set, all recipient addresses not rejected by mail rules are allowed, and its contents are appended to each recipient address. Back-end validation is omitted.
  • Rejects messages that exceed $DATABYTES bytes in length.
  • Counts the number of "Received:" and "Delivered-To:" headers, and rejects the message if more than $MAXHOPS of either are seen (defaults to 100).
  • Optionally adds a fixup "Received:" header for hosts that have different incoming and outgoing hostnames or IPs. Set $FIXUP_RECEIVED_HOST and $FIXUP_RECEIVED_IP if you want this header added.
  • Optional user-specified headers may be added by setting $HEADER_ADD.
  • If $CVM_LOOKUP is set, recipients are sent to the named CVM to see if they are valid. If CVM_LOOKUP_SECRET or $LOOKUP_SECRET are set and not empty, the value is sent as a single credential to the CVM.
  • If $MAXRCPTS is set, the number of recipients allowed per message is limited to that number.
  • Support for pattern matching in the message data.
  • Support for adding additional plugins at run time. Set $PLUGINS to a colon separated list of plugin names, and optionally set $MODULE_PATH to the directory in which those plugins are contained.
  • If $PLUGINS includes require-auth, all mail is rejected unless either $RELAYCLIENT is set or the sender authenticates.

mailfront-2.12/testcvm.c0000644000000000000000000000167612467132135012166 0ustar #include #include #include #include "auto_testcvm.c" const char program[] = "testcvm"; int cvm_module_init(void) { return 0; } int cvm_module_lookup(void) { if (cvm_module_credentials[CVM_CRED_ACCOUNT].s == 0) return CVME_NOCRED; if (str_diffs(&cvm_module_credentials[CVM_CRED_ACCOUNT], "testuser")) return CVME_PERMFAIL; return 0; } int cvm_module_authenticate(void) { CVM_CRED_REQUIRED(PASSWORD); if (str_diffs(&cvm_module_credentials[CVM_CRED_PASSWORD], "testpass")) return CVME_PERMFAIL; return 0; } int cvm_module_results(void) { cvm_fact_username = "testuser"; cvm_fact_userid = TESTCVM_UID; cvm_fact_groupid = TESTCVM_GID; cvm_fact_realname = "Test User"; cvm_fact_directory = TESTCVM_PWD "/tests-tmp"; cvm_fact_shell = "/bin/false"; cvm_fact_mailbox = TESTCVM_PWD "/tests-tmp/mail:box"; cvm_fact_groupname = 0; return 0; } void cvm_module_stop(void) { } mailfront-2.12/tests.sh0000644000000000000000000022113713213777177012042 0ustar #!/bin/sh src=`pwd` tmp=$src/tests-tmp rm -rf $tmp mkdir -p $tmp PATH="$src:/bin:/usr/bin:/usr/local/bin" tests_failed=0 tests_count=0 _UID=`id -u` _GID=`id -g` usage() { echo "usage: sh $0 [-v]" } vecho() { :; } while getopts v flag do case $flag in v) vecho() { echo "$*"; } ;; *) usage; exit 1 ;; esac done smtpfront() { $src/mailfront smtp "$@" 2>&1 \ | sed -e '/^220 local.host mailfront ESMTP/d; s/\[[0123456789]*\]:/[#]:/' } sfecho() { $src/mailfront smtp echo "$@" 2>/dev/null \ | grep -v '^220 local.host mailfront ESMTP' } pfauth() { $src/pop3front-auth "$@" echo Yes. 2>/dev/null \ | tail -n +2 } ifauth() { $src/imapfront-auth sh -c 'echo Yes: $IMAPLOGINTAG' 2>/dev/null \ | grep -v '^\* OK imapfront ready.' } pfmaildir() { $src/pop3front-maildir "$@" 2>/dev/null \ | tail -n +2 } maildir=$tmp/Maildir maildir() { rm -rf $maildir mkdir -p $maildir/cur mkdir -p $maildir/new mkdir -p $maildir/tmp } tstmsg() { fn=$1 { echo "Header: foo" echo echo "body" } >$maildir/$fn } setup_queuedir() { export QUEUEDIR=$tmp/queuedir mkdir -p $tmp/queuedir/new $tmp/queuedir/tmp } dump_queuedir() { echo queuedir tmp: $( find $QUEUEDIR/tmp -type f | wc -l ) new: $( find $QUEUEDIR/new -type f | wc -l ) find $QUEUEDIR/new -type f | while read file do echo "===== queued file =====" cat -v "$file" echo "=====" rm -f "$file" done rm -f $QUEUEDIR/tmp/* } cleanup_queuedir() { rm -rf $QUEUEDIR } PROTO=TEST TESTLOCALIP=1.2.3.4 TESTREMOTEIP=5.6.7.8 TESTLOCALHOST=local.host TESTREMOTEHOST=remote.host CVM_PWFILE_PATH=$tmp/pwfile MODULE_PATH=$src PLUGINS=accept export PROTO TESTLOCALIP TESTREMOTEIP TESTLOCALHOST TESTREMOTEHOST export MAILRULES DATABYTES MAXHOPS PATTERNS MAXNOTIMPL export PLUGINS MODULE_PATH run_compare_test() { local name=$1 shift sed -e "s:@SOURCE@:$src:g" -e "s:@TMPDIR@:$tmp:g" -e "s:@UID@:$_UID:" -e "s:@GID@:$_GID:" >$tmp/expected ( runtest "$@" 2>&1 ) 2>&1 >$tmp/actual-raw cat -v $tmp/actual-raw >$tmp/actual if ! cmp $tmp/expected $tmp/actual >/dev/null 2>&1 then echo "Test $name $* failed:" ( cd $tmp; diff -U 9999 expected actual | tail -n +3; echo; ) tests_failed=$(($tests_failed+1)) fi rm -f $tmp/expected $tmp/actual tests_count=$(($tests_count+1)) } ##### Test tests/rules-negate ##### runtest() { PLUGINS=mailrules:accept cat >$tmp/rules < MAIL FROM: EOF rm -f $tmp/rules } vecho "Running test tests/rules-negate " run_compare_test tests/rules-negate <$tmp/patterns < RCPT TO: DATA before after . EOF echo cat >$tmp/patterns < RCPT TO: DATA before after . EOF rm -f $tmp/patterns } vecho "Running test tests/patterns-after " run_compare_test tests/patterns-after < RCPT TO: RCPT TO: DATA . EOF sfecho < RCPT TO: DATA . EOF sfecho < RCPT TO: RCPT TO: DATA . EOF } vecho "Running test tests/smtpfront-bad-bounce " run_compare_test tests/smtpfront-bad-bounce </dev/null < RCPT TO: EOF } vecho "Running test tests/plugin-reject 'rej'" run_compare_test tests/plugin-reject 'rej' < RCPT TO: DATA Received: foo . EOF echo sfecho < RCPT TO: DATA Received: foo Received: foo . EOF } vecho "Running test tests/plugin-counters-looping-received " run_compare_test tests/plugin-counters-looping-received </dev/null ls $maildir/cur ls $maildir/new echo UIDL | pfmaildir $maildir echo LIST | pfmaildir $maildir } vecho "Running test tests/pop3front-maildir-size " run_compare_test tests/pop3front-maildir-size < RCPT TO:<"you, yourself, and you"@example.com> RCPT TO: RCPT TO:<@somewhere,@elsewhere:two@example.com> EOF } vecho "Running test tests/smtpfront-quotes " run_compare_test tests/smtpfront-quotes <$tmp/patterns < RCPT TO: DATA header1: data header2: another field not also . EOF echo cat >$tmp/patterns < RCPT TO: DATA header not also . EOF rm -f $tmp/patterns } vecho "Running test tests/patterns-header " run_compare_test tests/patterns-header < #RCPT TO: #DATA #Subject: test #. #EOF # #dump_queuedir # #cleanup_queuedir # #unset RBL_BLACKLISTS RBL_DEBUG RBL_QUEUEDIR TCPLOCALIP QUEUEDIR #rm -rf $tmp/queuedir $tmp/queuedir #} #vecho "Running test tests/plugin-rbl '127.0.0.2' 'false'" #run_compare_test tests/plugin-rbl '127.0.0.2' 'false' < #mailfront[#]: 451 Blocked: http://www.spamhaus.org/sbl/query/SBL233 #451 Blocked: http://www.spamhaus.org/sbl/query/SBL233^M #mailfront[#]: RCPT TO: #mailfront[#]: 503 5.5.1 You must send MAIL FROM: first #503 5.5.1 You must send MAIL FROM: first^M #mailfront[#]: 503 5.5.1 You must send MAIL FROM: first #503 5.5.1 You must send MAIL FROM: first^M #mailfront[#]: Subject: test #mailfront[#]: 500 5.5.1 Not implemented. #500 5.5.1 Not implemented.^M #mailfront[#]: . #mailfront[#]: 500 5.5.1 Not implemented. #500 5.5.1 Not implemented.^M #mailfront[#]: bytes in: 71 bytes out: 243 #queuedir tmp: 0 new: 0 #END_OF_TEST_RESULTS # #vecho "Running test tests/plugin-rbl '127.0.0.2' 'true'" #run_compare_test tests/plugin-rbl '127.0.0.2' 'true' < #250 Sender='somewhere'.^M #mailfront[#]: RCPT TO: #250 Recipient='elsewhere'.^M #354 End your message with a period on a line by itself.^M #mailfront[#]: Subject: test #mailfront[#]: 451 Blocked: http://www.spamhaus.org/sbl/query/SBL233 #451 Blocked: http://www.spamhaus.org/sbl/query/SBL233^M #mailfront[#]: bytes in: 71 bytes out: 213 #queuedir tmp: 0 new: 1 #===== queued file ===== #somewhere^@elsewhere^@^@Subject: test #===== #END_OF_TEST_RESULTS # #vecho "Running test tests/plugin-rbl '127.0.0.99' 'false'" #run_compare_test tests/plugin-rbl '127.0.0.99' 'false' < #250 Sender='somewhere'.^M #mailfront[#]: RCPT TO: #250 Recipient='elsewhere'.^M #354 End your message with a period on a line by itself.^M #mailfront[#]: Subject: test #250 Received 14 bytes.^M #mailfront[#]: bytes in: 71 bytes out: 182 #queuedir tmp: 0 new: 0 #END_OF_TEST_RESULTS # #vecho "Running test tests/plugin-rbl '127.0.0.99' 'true'" #run_compare_test tests/plugin-rbl '127.0.0.99' 'true' < #250 Sender='somewhere'.^M #mailfront[#]: RCPT TO: #250 Recipient='elsewhere'.^M #354 End your message with a period on a line by itself.^M #mailfront[#]: Subject: test #250 Received 14 bytes.^M #mailfront[#]: bytes in: 71 bytes out: 182 #queuedir tmp: 0 new: 0 #END_OF_TEST_RESULTS # ##### Test tests/rules-empty ##### runtest() { PLUGINS=mailrules:accept cat >$tmp/rules < MAIL FROM: EOF rm -f $tmp/rules } vecho "Running test tests/rules-empty " run_compare_test tests/rules-empty <$tmp/rules < MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: EOF rm -f $tmp/rules } vecho "Running test tests/rules-sender " run_compare_test tests/rules-sender < script.lua echo sfecho lua add-received counters < SIZE=13 RCPT TO: RCPT TO: DATA Header: one . EOF } doit < MAIL FROM: MAIL FROM: MAIL FROM: RCPT TO:<> RCPT TO: RCPT TO: RCPT TO: EOF unset DEFAULTDOMAIN DEFAULTHOST } vecho "Running test tests/plugin-check-fqdn '' ''" run_compare_test tests/plugin-check-fqdn '' '' </dev/null < RCPT TO: EOF } vecho "Running test tests/plugins-remove 'reject'" run_compare_test tests/plugins-remove 'reject' <$tmp/rules < +12,0:@example.com-> EOF cat < EOF MAILRULES=$tmp/rules sfecho < MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: EOF rm -f $tmp/rules $tmp/list.cdb $tmp/atlist.cdb } vecho "Running test tests/rules-cdb " run_compare_test tests/rules-cdb </dev/null < RCPT TO: EOF } vecho "Running test tests/plugins-prepend " run_compare_test tests/plugins-prepend <$tmp/rules < RCPT TO: RCPT TO: MAIL FROM: RCPT TO: RCPT TO: EOF rm -f $tmp/rules } vecho "Running test tests/rules-selector " run_compare_test tests/rules-selector <$tmp/rules < MAIL FROM: SIZE MAIL FROM: SIZE= MAIL FROM: SIZE=100 MAIL FROM: SIZE=123 MAIL FROM: SIZE=124 RCPT TO: EOF rm -f $tmp/rules } vecho "Running test tests/rules-databytes " run_compare_test tests/rules-databytes < MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: EOF unset SENDER_DOMAINS } vecho "Running test tests/plugin-check-fqdn-domains " run_compare_test tests/plugin-check-fqdn-domains <$tmp/rules < MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM:<> MAIL FROM:<1@2@example.com@example.com> EOF rm -f $tmp/rules } vecho "Running test tests/rules-asterisk " run_compare_test tests/rules-asterisk <$QMAILHOME/control/badmailfrom echo @badfrom.com >>$QMAILHOME/control/badmailfrom echo rcpthost.com >$QMAILHOME/control/rcpthosts echo .subrcpthost.com >>$QMAILHOME/control/rcpthosts echo badrcpt@example.com >$QMAILHOME/control/badrcptto echo @badrcpt.com >>$QMAILHOME/control/badrcptto cdbmake $QMAILHOME/control/morercpthosts.cdb $QMAILHOME/tmp < +20,0:.submorercpthost.com-> EOF sfecho < MAIL FROM: MAIL FROM: RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: EOF rm -r $QMAILHOME unset QMAILHOME } vecho "Running test tests/plugin-qmail-validate " run_compare_test tests/plugin-qmail-validate < MAIL FROM: SIZE MAIL FROM: SIZE= MAIL FROM: SIZE=100 EOF DATABYTES=123 export DATABYTES sfecho < MAIL FROM: SIZE MAIL FROM: SIZE= MAIL FROM: SIZE=100 MAIL FROM: SIZE=123 MAIL FROM: SIZE=124 RCPT TO: EOF } vecho "Running test tests/plugin-counters-databytes " run_compare_test tests/plugin-counters-databytes < RCPT TO: DATA Subject: test foo .. bar . MAIL FROM: RCPT TO: DATA Subject: test foo .. bar . EOF } vecho "Running test tests/smtpfront-content " run_compare_test tests/smtpfront-content < RCPT TO: RCPT TO: EOF CVM_LOOKUP_SECRET=test export CVM_LOOKUP_SECRET echo sfecho < RCPT TO: RCPT TO: EOF unset CVM_LOOKUP CVM_LOOKUP_SECRET } vecho "Running test tests/plugin-cvm-validate " run_compare_test tests/plugin-cvm-validate < RCPT TO: AUTH LOGIN dGVzdHVzZXI= dGVzdHBhc3x= AUTH LOGIN dGVzdHVzZXI= dGVzdHBhc3M= AUTH LOGIN MAIL FROM: RCPT TO: EOF sfecho << EOF AUTH LOGIN dGVzdHVzZXI= dGVzdHBhc3M= EOF sfecho < RCPT TO: EOF unset CVM_SASL_PLAIN } vecho "Running test tests/plugin-cvm-auth-login " run_compare_test tests/plugin-cvm-auth-login <&1 >/dev/null < RCPT TO: DATA . EOF } vecho "Running test tests/received '' '' '' '' ''" run_compare_test tests/received '' '' '' '' '' </dev/null QUIT NO QUIT QUIT AGAIN EOF } vecho "Running test tests/pop3front-auth " run_compare_test tests/pop3front-auth </dev/null echo } vecho "Running test tests/qmtpfront-echo " run_compare_test tests/qmtpfront-echo </dev/null USER testuser PASS testpass EOF pfauth $src/testcvm </dev/null USER testuser PASS testpasx EOF } vecho "Running test tests/pop3front-auth-userpass " run_compare_test tests/pop3front-auth-userpass < RCPT TO: DATA . EOF unset TMPDIR } vecho "Running test tests/plugin-force-file '/tmp' ''" run_compare_test tests/plugin-force-file '/tmp' '' <$tmp/rules < RCPT TO: DATA . EOF sfecho < RCPT TO: DATA . EOF rm -f $tmp/rules } vecho "Running test tests/rules-header-add " run_compare_test tests/rules-header-add </dev/null RCPT TO: EOF dump_queuedir smtpfront queuedir accept < RCPT TO: DATA Subject: testing . EOF dump_queuedir cleanup_queuedir } vecho "Running test tests/backend-queuedir " run_compare_test tests/backend-queuedir < 250 2.1.0 Sender accepted.^M mailfront[#]: RCPT TO: 250 2.1.5 Recipient accepted.^M mailfront[#]: bytes in: 42 bytes out: 91 queuedir tmp: 0 new: 0 mailfront[#]: MAIL FROM: 250 2.1.0 Sender accepted.^M mailfront[#]: RCPT TO: 250 2.1.5 Recipient accepted.^M 354 End your message with a period on a line by itself.^M 250 2.6.0 Message accepted.^M mailfront[#]: bytes in: 67 bytes out: 177 queuedir tmp: 0 new: 1 ===== queued file ===== somewhere^@elsewhere^@^@Subject: testing ===== END_OF_TEST_RESULTS ##### Test tests/rules-databytes3 ##### runtest() { PLUGINS=mailrules:counters:accept DATABYTES=1000 export DATABYTES cat >$tmp/rules < MAIL FROM: SIZE MAIL FROM: SIZE= MAIL FROM: SIZE=100 MAIL FROM: SIZE=123 MAIL FROM: SIZE=124 RCPT TO: MAIL FROM: RCPT TO: DATA datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata . EHLO hostname MAIL FROM: RCPT TO: DATA datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata datadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadatadata . EOF rm -f $tmp/rules } vecho "Running test tests/rules-databytes3 " run_compare_test tests/rules-databytes3 < $maildir/new/1.2.3 < RCPT TO: AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M= MAIL FROM: RCPT TO: EOF unset CVM_SASL_PLAIN unset REQUIRE_AUTH } vecho "Running test tests/plugin-require-auth " run_compare_test tests/plugin-require-auth <$tmp/patterns < RCPT TO: DATA before after . EOF rm -f $tmp/patterns } vecho "Running test tests/patterns-normal " run_compare_test tests/patterns-normal < RCPT TO: DATA Delivered-To: foo . EOF echo sfecho < RCPT TO: DATA Delivered-To: foo Delivered-To: foo . EOF } vecho "Running test tests/plugin-counters-looping-delivered-to " run_compare_test tests/plugin-counters-looping-delivered-to < EOF } vecho "Running test tests/smtpfront-addrfail " run_compare_test tests/smtpfront-addrfail < RCPT TO: RCPT TO: RCPT TO: RCPT TO: DATA . EOF MAXRCPTS_REJECT=1 export MAXRCPTS_REJECT sfecho < RCPT TO: RCPT TO: RCPT TO: RCPT TO: DATA . EOF unset MAXRCPTS unset MAXRCPTS_REJECT } vecho "Running test tests/plugin-counters-maxrcpts " run_compare_test tests/plugin-counters-maxrcpts </dev/null echo } vecho "Running test tests/qmqpfront-echo " run_compare_test tests/qmqpfront-echo </dev/null << EOF \ | grep -v '^\* OK imapfront ready.' 1 login testuser testpass EOF env SETUP_ENV=dovecot \ $src/imapfront-auth sh -c 'echo MAIL=$MAIL' 2>/dev/null << EOF \ | grep -v '^\* OK imapfront ready.' 1 login testuser testpass EOF mkdir "$tmp"/mail:box env SETUP_ENV=dovecot \ $src/imapfront-auth sh -c 'echo MAIL=$MAIL' 2>/dev/null << EOF \ | grep -v '^\* OK imapfront ready.' 1 login testuser testpass EOF rmdir "$tmp"/mail:box } vecho "Running test tests/imapfront-mailenv " run_compare_test tests/imapfront-mailenv <$tmp/rules <$tmp/list <$tmp/atlist < MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: MAIL FROM: EOF rm -f $tmp/rules $tmp/list $tmp/atlist } vecho "Running test tests/rules-list " run_compare_test tests/rules-list < RCPT TO: DATA . MAIL FROM: RCPT TO: DATA . EOF unset MAXMSGS } vecho "Running test tests/plugin-counters-maxmsgs " run_compare_test tests/plugin-counters-maxmsgs <$tmp/rules < MAIL FROM: MAIL FROM: EOF rm -f $tmp/rules } vecho "Running test tests/rules-multiline " run_compare_test tests/rules-multiline <$tmp/rules < SIZE=10000 RCPT TO: DATA testing . EHLO hostname MAIL FROM: SIZE=10000 RCPT TO: RCPT TO: DATA testing . EHLO hostname MAIL FROM: SIZE=10000 RCPT TO: RCPT TO: RCPT TO: DATA testing . EOF rm -f $tmp/rules } vecho "Running test tests/rules-databytes2 " run_compare_test tests/rules-databytes2 <$tmp/rules < RCPT TO: EOF rm -f $tmp/rules } vecho "Running test tests/rules-noop " run_compare_test tests/rules-noop <$tmp/rules < RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: EOF rm -f $tmp/rules } vecho "Running test tests/rules-recip " run_compare_test tests/rules-recip <$tmp/rules <$tmp/list <$tmp/atlist </dev/null | tail -n +2 MAIL FROM: RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: RCPT TO: EOF rm -f $tmp/rules $tmp/list $tmp/atlist } vecho "Running test tests/rules-rcptlist " run_compare_test tests/rules-rcptlist <&1 >/dev/null < RCPT TO: DATA . EOF PROTO=TEST unset TCP6LOCALHOST TCP6LOCALIP TCP6REMOTEHOST TCP6REMOTEIP } vecho "Running test tests/received-ipv6 " run_compare_test tests/received-ipv6 <$tmp/rules < RCPT TO: MAIL FROM: RCPT TO: RCPT TO: MAIL FROM: RCPT TO: RCPT TO: EOF rm -f $tmp/rules } vecho "Running test tests/rules-both " run_compare_test tests/rules-both <$tmp/patterns < RCPT TO: DATA Subject: $subject . EOF rm -f $tmp/patterns } vecho "Running test tests/patterns-general 'xwordx'" run_compare_test tests/patterns-general 'xwordx' <$tmp/rules < RCPT TO: DATA Received: hop1 Received: hop2 . EOF MAILRULES=$tmp/rules sfecho < RCPT TO: DATA Received: hop1 Received: hop1 . EOF rm -f $tmp/rules } vecho "Running test tests/rules-maxhops " run_compare_test tests/rules-maxhops < RCPT TO: AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3x= AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M= AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M= MAIL FROM: RCPT TO: EOF sfecho << EOF AUTH PLAIN dGVzdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M= EOF sfecho < RCPT TO: EOF sfecho << EOF AUTH PLAIN XXXXdHVzZXIAdGVzdHVzZXIAdGVzdHBhc3M= EOF unset CVM_SASL_PLAIN } vecho "Running test tests/plugin-cvm-auth-plain " run_compare_test tests/plugin-cvm-auth-plain <$tmp/rules < MAIL FROM: MAIL FROM: RCPT TO: RCPT TO: RCPT TO: EOF rm -f $tmp/rules } vecho "Running test tests/rules-defaultmsg " run_compare_test tests/rules-defaultmsg <$tmp/patterns < RCPT TO: DATA before after . EOF rm -f $tmp/patterns } vecho "Running test tests/patterns-message " run_compare_test tests/patterns-message < or FutureQuest, Inc. * Development of this program was sponsored by FutureQuest, Inc. * * This program is free software; you can redistribute it and/or modify it * under the terms of version 2 of the GNU General Public License as * published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * * Contact information: * FutureQuest Inc. * PO BOX 623127 * Oviedo FL 32762-3127 USA * http://www.FutureQuest.net/ * ossi@FutureQuest.net */ #include #include #include #include #include unsigned long timeout; unsigned long session_timeout; extern const int authenticating; static void handle_alarm(int unused) { exit(0); (void)unused; } void set_timeout(void) { const char* tmp; timeout = 0; if ((authenticating && (tmp = getenv("AUTH_TIMEOUT")) != 0) || (tmp = getenv("TIMEOUT")) != 0) timeout = strtoul(tmp, 0, 10); if (timeout <= 0) timeout = 1200; inbuf.io.timeout = timeout * 1000; outbuf.io.timeout = timeout * 1000; session_timeout = 0; if ((authenticating && (tmp = getenv("AUTH_SESSION_TIMEOUT")) != 0) || (tmp = getenv("SESSION_TIMEOUT")) != 0) session_timeout = strtoul(tmp, 0, 10); if (session_timeout <= 0) timeout = 86400; sig_alarm_catch(handle_alarm); alarm(session_timeout); } mailfront-2.12/warn-auto.sh0000644000000000000000000000010012467132135012563 0ustar #!/bin/sh # WARNING: This file was auto-generated. Do not edit!