From 8520befe602e9b90d455342068a623f2cf89f631 Mon Sep 17 00:00:00 2001 From: Ian C Date: Thu, 4 Dec 2003 01:54:55 +0000 Subject: This commit was generated by cvs2svn to compensate for changes in r2, which included commits to RCS files with non-trunk default branches. --- INSTALL | 22 ++ LICENSE | 341 +++++++++++++++++++++++++++ doc/INSTRUCTION | 151 ++++++++++++ doc/README | 25 ++ src/Makefile | 102 ++++++++ src/config.c | 715 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ src/config.h | 80 +++++++ src/dbase.c | 281 ++++++++++++++++++++++ src/dbase.h | 86 +++++++ src/dstring.c | 111 +++++++++ src/dstring.h | 86 +++++++ src/global.h | 44 ++++ src/kbs.c | 147 ++++++++++++ src/kbsrc | 91 ++++++++ src/msg.h | 45 ++++ src/pop3.c | 530 +++++++++++++++++++++++++++++++++++++++++ src/pop3.h | 90 +++++++ src/rexp.c | 63 +++++ src/rexp.h | 52 +++++ src/util.c | 79 +++++++ src/util.h | 58 +++++ 21 files changed, 3199 insertions(+) create mode 100644 INSTALL create mode 100644 LICENSE create mode 100644 doc/INSTRUCTION create mode 100644 doc/README create mode 100644 src/Makefile create mode 100644 src/config.c create mode 100644 src/config.h create mode 100644 src/dbase.c create mode 100644 src/dbase.h create mode 100644 src/dstring.c create mode 100644 src/dstring.h create mode 100644 src/global.h create mode 100644 src/kbs.c create mode 100644 src/kbsrc create mode 100644 src/msg.h create mode 100644 src/pop3.c create mode 100644 src/pop3.h create mode 100644 src/rexp.c create mode 100644 src/rexp.h create mode 100644 src/util.c create mode 100644 src/util.h diff --git a/INSTALL b/INSTALL new file mode 100644 index 0000000..5674bb7 --- /dev/null +++ b/INSTALL @@ -0,0 +1,22 @@ + +This program does not unfortunately use the configure script, but I have been +careful to write is as portably as possible to unix systems. + +To build the software, type the following: + + cd src + make depend + make + +Then copy the kbs executable wherever you want. + + +Other or broken systems +======================= + +If the Makefile is not usable on your system, you simply need to compile all +the .c files and produce a single kbs object. E.g. (using the cc command +as an example): + + cd src + cc -o casm *.c diff --git a/LICENSE b/LICENSE new file mode 100644 index 0000000..abd3cf7 --- /dev/null +++ b/LICENSE @@ -0,0 +1,341 @@ + 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) 19yy + + 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) 19yy 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. + diff --git a/doc/INSTRUCTION b/doc/INSTRUCTION new file mode 100644 index 0000000..d4ffc69 --- /dev/null +++ b/doc/INSTRUCTION @@ -0,0 +1,151 @@ + +Usage +===== + + kbs + + +Description +=========== + +kbs works on the simple premise that most people know who will be sending them +email, or at least have a few trusted domains. It also makes it easy for +a special keyword in a subject header to be used. + + +Config file format +================== + +The kbs config file is read from $HOME/.kbsrc and is in the form: + +[config settings] + +[trusted settings] + +[domain settings] + +Note it is *highly* recommended to set .kbsrc to be only readable by the +user - this is as passwords are stored in there. + +Blank lines and text proceeded with a hash (#) are ignored. + +Each token is delimited with white space - if the value you want to use +includes spaces, simple quote them (with either single or double quotes). + +Note that escapes aren't used (to make regular expression writing easier), so +if you want to include a quote in a string, simply use the other sort of quote. +If you want both, you're stuck! + +To see and example kbsrc file, see kbsrc in the src directory. + + +Config settings +=============== + +The config settings are in the general form: + + set variable=value + +And understand the following variables: + + + hostname The Fully Qualified Domain Name of the POP3 server. + Defaults to localhost. + + port The port number to connect to. + Defaults to 110. + + username The username to give to the server. + Defaults to guest. + + password The password to give to the server. + Defaults to an empty string. + + log Log information to the given file (note the file is + appended to). + If not used, or is an illegal path, logging is to + stdout. + + delete_log Logs deleted messages to the given file, which is + appended to. + If not used, or is an illegal path, logging is to + $HOME/.kbs-deletelog. + + timeout Number of seconds to allow for no response from the + server. + Defaults to 60 seconds. + + casesense Whether regular expressions are case sensitive. + Defaults to case insensitive (off). + + dejunk Whether subjects are dejunked before checking. + Dejunking here means that anything an alphanumeric + character is stripped, and all contiguos white space + is reduced to one space. + Defaults to off. + + blockhtml Whether messages that are pure HTML (content part just + reported as "text/html" are blocked. + Defaults to off. + + testmode Whether things will be really deleted, or just + the actions logged. Note that the delete_log is still + filled out as if the deletion occured. + Defaults to off, though it is recommended to use this + for early runs to ensure your rules are not too harsh + (or too easy for that matter). + + +Trusted settings +================ + +These define users and domains for which mail is let thorugh, regardless of +other tests. + + trusted_users + { + username + [username] + } + + trusted_domains + { + domain + [domain] + } + + +Domain settings +=============== + +These define the rules applied to a certain domain. Note the order these +appear in is important, as the first match when checking domain names will +be used. + + domain + { + [default block|allow] + [block_user ] + [allow_subject ] + [block_subject ] + } + +The default says what to do if neither the allow_subject or block_subject are +matched. If not specified, the default is to allow. + +The block user allows a specific username to be blocked. For instance, I've +noticed that spammers have a great love of emailing from your username at +a different domain. + +The allow_subject means that subjects that match that regular expression are +always let through. + +The block_subject means that subjects that match that regular expression are +always blocked and deleted. + +Note that multiple allow_subject and block_subject commands can be in one +domain. + + +------------------------------------------------------------------------------- +$Id: INSTRUCTION,v 1.1.1.1 2003-12-04 01:54:55 ianc Exp $ diff --git a/doc/README b/doc/README new file mode 100644 index 0000000..facf09f --- /dev/null +++ b/doc/README @@ -0,0 +1,25 @@ + kbs - A simple (very) POP3 filter + ================================= + + Copyright 2003 Ian Cowburn + + + 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 + + + See INSTRUCTION for instructions on use. + +------------------------------------------------------------------------------- +$Id: README,v 1.1.1.1 2003-12-04 01:54:55 ianc Exp $ diff --git a/src/Makefile b/src/Makefile new file mode 100644 index 0000000..22cc523 --- /dev/null +++ b/src/Makefile @@ -0,0 +1,102 @@ +# kbs - Simple, easily fooled, POP3 spam filter +# +# Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) +# +# 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 +# +# ------------------------------------------------------------------------- +# +# $Id: Makefile,v 1.1.1.1 2003-12-04 01:54:55 ianc Exp $ +# + +CFLAGS += -g + +TARGET = kbs + +SOURCE = kbs.c \ + pop3.c \ + config.c \ + rexp.c \ + dbase.c \ + dstring.c \ + util.c + +OBJECTS = kbs.o \ + pop3.o \ + config.o \ + rexp.o \ + dbase.o \ + dstring.o \ + util.o + +$(TARGET): $(OBJECTS) + $(CC) $(CLAGS) -o $(TARGET) $(OBJECTS) + +clean: + rm -f $(TARGET) $(OBJECTS) core + +depend: + make clean + makedepend -- $(CFLAGS) -- $(SOURCE) + if test -e Makefile ; then rm -f Makefile.bak ; fi + +# DO NOT DELETE THIS LINE -- make depend depends on it + +kbs.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h +kbs.o: /usr/include/sys/_types.h /usr/include/machine/_types.h +kbs.o: /usr/include/limits.h /usr/include/sys/limits.h +kbs.o: /usr/include/machine/_limits.h /usr/include/sys/syslimits.h +kbs.o: /usr/include/stdio.h /usr/include/string.h /usr/include/strings.h +kbs.o: /usr/include/stdarg.h /usr/include/time.h /usr/include/sys/timespec.h +kbs.o: /usr/include/errno.h global.h config.h pop3.h msg.h rexp.h util.h +pop3.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h +pop3.o: /usr/include/sys/_types.h /usr/include/machine/_types.h +pop3.o: /usr/include/string.h /usr/include/strings.h /usr/include/stdio.h +pop3.o: /usr/include/stdarg.h /usr/include/ctype.h /usr/include/runetype.h +pop3.o: /usr/include/sys/types.h /usr/include/machine/endian.h +pop3.o: /usr/include/sys/select.h /usr/include/sys/_sigset.h +pop3.o: /usr/include/sys/_timeval.h /usr/include/sys/timespec.h +pop3.o: /usr/include/sys/socket.h /usr/include/sys/_iovec.h +pop3.o: /usr/include/machine/param.h /usr/include/netinet/in.h +pop3.o: /usr/include/netinet6/in6.h /usr/include/netinet/tcp.h +pop3.o: /usr/include/netdb.h global.h pop3.h msg.h dstring.h util.h +config.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h +config.o: /usr/include/sys/_types.h /usr/include/machine/_types.h +config.o: /usr/include/string.h /usr/include/strings.h /usr/include/stdio.h +config.o: /usr/include/errno.h /usr/include/ctype.h /usr/include/runetype.h +config.o: global.h config.h dstring.h dbase.h msg.h rexp.h util.h +rexp.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h +rexp.o: /usr/include/sys/_types.h /usr/include/machine/_types.h global.h +rexp.o: rexp.h +dbase.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h +dbase.o: /usr/include/sys/_types.h /usr/include/machine/_types.h +dbase.o: /usr/include/string.h /usr/include/strings.h /usr/include/stdio.h +dbase.o: /usr/include/ctype.h /usr/include/runetype.h global.h dbase.h msg.h +dbase.o: dstring.h config.h rexp.h util.h +dstring.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h +dstring.o: /usr/include/sys/_types.h /usr/include/machine/_types.h +dstring.o: /usr/include/string.h /usr/include/strings.h /usr/include/stdio.h +dstring.o: /usr/include/stdarg.h /usr/include/ctype.h /usr/include/runetype.h +dstring.o: /usr/include/sys/types.h /usr/include/machine/endian.h +dstring.o: /usr/include/sys/select.h /usr/include/sys/_sigset.h +dstring.o: /usr/include/sys/_timeval.h /usr/include/sys/timespec.h +dstring.o: /usr/include/sys/socket.h /usr/include/sys/_iovec.h +dstring.o: /usr/include/machine/param.h /usr/include/netinet/in.h +dstring.o: /usr/include/netinet6/in6.h /usr/include/netinet/tcp.h +dstring.o: /usr/include/netdb.h global.h dstring.h util.h +util.o: /usr/include/stdlib.h /usr/include/sys/cdefs.h +util.o: /usr/include/sys/_types.h /usr/include/machine/_types.h +util.o: /usr/include/string.h /usr/include/strings.h /usr/include/stdio.h +util.o: global.h util.h diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..af55d58 --- /dev/null +++ b/src/config.c @@ -0,0 +1,715 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + Config + +*/ +static const char id[]="$Id$"; + +#include +#include +#include +#include +#include + +#include "global.h" +#include "config.h" +#include "dstring.h" +#include "dbase.h" +#include "rexp.h" +#include "util.h" + + +/* ---------------------------------------- TYPES +*/ +typedef enum { + TOK_Expression, + TOK_Set, + TOK_OpenBracket, + TOK_CloseBracket, + TOK_Domain, + TOK_TrustedUsers, + TOK_TrustedDomains, + TOK_Default, + TOK_BlockUser, + TOK_AllowSubject, + TOK_BlockSubject, + TOK_VarHostname, + TOK_VarPort, + TOK_VarUsername, + TOK_VarPassword, + TOK_VarLog, + TOK_VarTimeout, + TOK_VarCasesense, + TOK_VarDejunk, + TOK_VarTestmode, + TOK_VarBlockHTML, + TOK_VarDeletelog, + TOK_ConstOn, + TOK_ConstOff, + TOK_ConstBlock, + TOK_ConstAllow, + TOK_EOF + } Token; + +typedef struct Command + { + const char *cmd; + Token token; + } Command; + + +/* ---------------------------------------- GLOBALS +*/ +static DString error; +static char *hostname="localhost"; +static char *username="nobody"; +static char *password=""; +static char *log=""; +static char *deletelog=""; +static int port=110; +static int timeout=60; +static int casesense=FALSE; +static int dejunk=FALSE; +static int testmode=FALSE; +static int blockhtml=FALSE; + + +/* ---------------------------------------- COMMAND TABLE +*/ +static const Command cmd_table[]= + { + /* Commands and main tokens + */ + {"set", TOK_Set}, + {"trusted_users", TOK_TrustedUsers}, + {"trusted_domains", TOK_TrustedDomains}, + {"{", TOK_OpenBracket}, + {"}", TOK_CloseBracket}, + {"domain", TOK_Domain}, + {"default", TOK_Default}, + {"block_user", TOK_BlockUser}, + {"allow_subject", TOK_AllowSubject}, + {"block_subject", TOK_BlockSubject}, + + /* Variables + */ + {"hostname", TOK_VarHostname}, + {"port", TOK_VarPort}, + {"username", TOK_VarUsername}, + {"password", TOK_VarPassword}, + {"log", TOK_VarLog}, + {"timeout", TOK_VarTimeout}, + {"casesense", TOK_VarCasesense}, + {"dejunk", TOK_VarDejunk}, + {"testmode", TOK_VarTestmode}, + {"blockhtml", TOK_VarBlockHTML}, + + /* Constants + */ + {"on", TOK_ConstOn}, + {"off", TOK_ConstOff}, + {"block", TOK_ConstBlock}, + {"allow", TOK_ConstAllow}, + + /* End of table + */ + {NULL, TOK_EOF} + }; + + +/* ---------------------------------------- REQUIRED PROTOS +*/ +static Token GetToken(FILE *fp, DString ret); + + +/* ---------------------------------------- COMMAND HANDLERS +*/ +static int DoSet(FILE *fp) +{ +# define TYPE_STR 0 +# define TYPE_INT 1 +# define TYPE_ONOFF 2 + + static const struct VarTable + { + Token token; + int type; + void *ptr; + } var_table[]= + { + {TOK_VarHostname, TYPE_STR, (void *)&hostname}, + {TOK_VarPort, TYPE_INT, (void *)&port}, + {TOK_VarUsername, TYPE_STR, (void *)&username}, + {TOK_VarPassword, TYPE_STR, (void *)&password}, + {TOK_VarLog, TYPE_STR, (void *)&log}, + {TOK_VarTimeout, TYPE_INT, (void *)&timeout}, + {TOK_VarCasesense, TYPE_ONOFF, (void *)&casesense}, + {TOK_VarDejunk, TYPE_ONOFF, (void *)&dejunk}, + {TOK_VarTestmode, TYPE_ONOFF, (void *)&testmode}, + {TOK_VarBlockHTML, TYPE_ONOFF, (void *)&blockhtml}, + {TOK_VarDeletelog, TYPE_STR, (void *)&deletelog}, + {TOK_EOF,0,NULL} + }; + + const struct VarTable *vt=NULL; + DString ds; + Token tok; + int status=TRUE; + int f; + + ds=DSInit(); + + tok=GetToken(fp,ds); + + for(f=0;var_table[f].token!=TOK_EOF && !vt;f++) + if (var_table[f].token==tok) + vt=var_table+f; + + if (vt) + { + char **cp; + int *ip; + + switch(vt->type) + { + case TYPE_STR: + cp=vt->ptr; + tok=GetToken(fp,ds); + *cp=CopyStr(ds->text); + break; + + case TYPE_INT: + ip=vt->ptr; + tok=GetToken(fp,ds); + *ip=atoi(ds->text); + break; + + case TYPE_ONOFF: + ip=vt->ptr; + tok=GetToken(fp,ds); + + switch(tok) + { + case TOK_ConstOn: + *ip=TRUE; + break; + + case TOK_ConstOff: + *ip=FALSE; + break; + + default: + status=FALSE; + DSAddCP(error,"Expected on/off. Got: "); + DSAddDS(error,ds); + } + break; + } + } + else + { + status=FALSE; + DSAddCP(error,"Unrecognised variable: "); + DSAddDS(error,ds); + } + + DSFree(ds); + +# undef TYPE_STR +# undef TYPE_INT +# undef TYPE_ONOFF + + return status; +} + + +static int DoDomain(FILE *fp) +{ + DString ds; + Token tok; + int status=TRUE; + Domain *domain; + + ds=DSInit(); + + tok=GetToken(fp,ds); + + if (tok!=TOK_Expression) + { + DSAddCP(error,"Domain must be followed by expression. Got: "); + DSAddDS(error,ds); + DSFree(ds); + return FALSE; + } + + if (RExpSearch(ds->text,"dummy")==RE_BadExpression) + { + DSAddCP(error,"Bad regular expression: "); + DSAddDS(error,ds); + DSFree(ds); + return FALSE; + } + + domain=DBNewDomain(ds->text); + + tok=GetToken(fp,ds); + + if (tok!=TOK_OpenBracket) + { + DSAddCP(error,"Missing opening bracket in domain"); + DSFree(ds); + return FALSE; + } + + while((tok=GetToken(fp,ds))!=TOK_CloseBracket) + { + if (tok==TOK_EOF) + { + DSAddCP(error,"Missing close bracket in domain"); + DSFree(ds); + return FALSE; + } + + switch(tok) + { + case TOK_Default: + switch(GetToken(fp,ds)) + { + case TOK_ConstAllow: + DBDefault(domain,FALSE); + break; + + case TOK_ConstBlock: + DBDefault(domain,TRUE); + break; + + default: + DSAddCP(error,"Unexpected value in default command: "); + DSAddDS(error,ds); + DSFree(ds); + return FALSE; + break; + } + + break; + + case TOK_BlockUser: + GetToken(fp,ds); + DBBlockUser(domain,ds->text); + break; + + case TOK_AllowSubject: + GetToken(fp,ds); + + if (RExpSearch(ds->text,"dummy")==RE_BadExpression) + { + DSAddCP(error,"Bad regular expression: "); + DSAddDS(error,ds); + DSFree(ds); + return FALSE; + } + + DBAllowSubject(domain,ds->text); + break; + + case TOK_BlockSubject: + GetToken(fp,ds); + + if (RExpSearch(ds->text,"dummy")==RE_BadExpression) + { + DSAddCP(error,"Bad regular expression: "); + DSAddDS(error,ds); + DSFree(ds); + return FALSE; + } + + DBBlockSubject(domain,ds->text); + break; + + default: + DSAddCP(error,"Unexpected string in domain command: "); + DSAddDS(error,ds); + DSFree(ds); + return FALSE; + break; + } + } + + DSFree(ds); + + return TRUE; +} + + +static int DoTrustedUsers(FILE *fp) +{ + DString ds; + Token tok; + int status=TRUE; + + ds=DSInit(); + + tok=GetToken(fp,ds); + + if (tok!=TOK_OpenBracket) + { + DSAddCP(error,"Missing opening bracket in trusted_users"); + DSFree(ds); + return FALSE; + } + + while((tok=GetToken(fp,ds))!=TOK_CloseBracket) + { + if (tok==TOK_EOF) + { + DSAddCP(error,"Missing close bracket in trusted_users"); + DSFree(ds); + return FALSE; + } + + DBTrustedUser(ds->text); + } + + DSFree(ds); + + return TRUE; +} + + +static int DoTrustedDomains(FILE *fp) +{ + DString ds; + Token tok; + int status=TRUE; + + ds=DSInit(); + + tok=GetToken(fp,ds); + + if (tok!=TOK_OpenBracket) + { + DSAddCP(error,"Missing opening bracket in trusted_domains"); + return FALSE; + } + + while((tok=GetToken(fp,ds))!=TOK_CloseBracket) + { + if (tok==TOK_EOF) + { + DSAddCP(error,"Missing close bracket in trusted_domains"); + return FALSE; + } + + DBTrustedDomain(ds->text); + } + + return TRUE; +} + + +/* ---------------------------------------- PRVIVATE FUNCTIONS +*/ +static int Getc(FILE *fp) +{ + int ch; + + ch=fgetc(fp); + + if (ch=='#') + { + ch=fgetc(fp); + + while(ch!=EOF && ch!='\n') + ch=fgetc(fp); + } + + return ch; +} + + +static int SkipWS(FILE *fp) +{ + int ch; + + ch=Getc(fp); + + while(isspace(ch)) + ch=Getc(fp); + + if (ch==EOF) + return FALSE; + else + { + ungetc(ch,fp); + return TRUE; + } +} + + +static Token FindToken(const char *p) +{ + int f; + + for(f=0;cmd_table[f].cmd;f++) + if (strcmp(cmd_table[f].cmd,p)==0) + return cmd_table[f].token; + + return TOK_Expression; +} + + +static int IsTerm(int ch) +{ + return isspace(ch) || ch=='#'; +} + + +static Token GetToken(FILE *fp, DString ret) +{ + int ch; + int done=FALSE; + int quote=0; + Token tok; + + ret=DSReset(ret); + + if (feof(fp)) + { + DSAddCP(ret,"EOF"); + return TOK_EOF; + } + + if (!SkipWS(fp)) + { + DSAddCP(ret,"EOF"); + return TOK_EOF; + } + + while(!done) + { + ch=fgetc(fp); + + if (quote) + { + if (ch==EOF) + { + done=TRUE; + + DSAddCP(error,"Unexpected EOF in string"); + tok=TOK_EOF; + } + else if (ch==quote) + { + done=TRUE; + tok=FindToken(ret->text); + } + else + { + DSAddChar(ret,ch); + } + } + else + { + if (ch==EOF) + { + done=TRUE; + + if (ret->len) + tok=FindToken(ret->text); + else + tok=TOK_EOF; + } + else if (IsTerm(ch)) + { + ungetc(ch,fp); + done=TRUE; + tok=FindToken(ret->text); + } + else if (ch=='\'' || ch=='"') + { + quote=ch; + } + else + { + DSAddChar(ret,ch); + } + } + } + + return tok; +} + + +static int Parse(FILE *fp) +{ + DString txt; + Token tok; + char *p; + + txt=DSInit(); + + while((tok=GetToken(fp,txt))!=TOK_EOF) + { + int ok=TRUE; + + switch(tok) + { + case TOK_Set: + if (!DoSet(fp)) + ok=FALSE; + break; + + case TOK_Domain: + if (!DoDomain(fp)) + ok=FALSE; + break; + + case TOK_TrustedUsers: + if (!DoTrustedUsers(fp)) + ok=FALSE; + break; + + case TOK_TrustedDomains: + if (!DoTrustedDomains(fp)) + ok=FALSE; + break; + + case TOK_Expression: + DSAddCP(error,"Unknown command in config file: "); + DSAddDS(error,txt); + ok=FALSE; + break; + + default: + DSAddCP(error,"Unexpected token in config file: "); + DSAddDS(error,txt); + ok=FALSE; + break; + } + + if (!ok) + break; + + txt=DSReset(txt); + } + + DSFree(txt); + + return error->len==0; +} + + +/* ---------------------------------------- INTERFACES +*/ + +int ConfigLoad(void) +{ + DString ds; + FILE *fp; + int ret; + + error=DSInit(); + + if (!getenv("HOME")) + return FALSE; + + ds=DSInit(); + + DSAddCP(ds,getenv("HOME")); + DSAddChar(ds,'/'); + DSAddCP(ds,".kbsrc"); + + if ((fp=fopen(ds->text,"r"))) + ret=Parse(fp); + else + ret=FALSE; + + DSFree(ds); + + return ret; +} + + +const char *ConfigError(void) +{ + if (strlen(error->text)) + return error->text; + else + return strerror(errno); +} + + +const char *ConfigString(ConfigStringVar var) +{ + switch(var) + { + case CONFIG_HOSTNAME: + return hostname; + + case CONFIG_USERNAME: + return username; + + case CONFIG_PASSWORD: + return password; + + case CONFIG_LOG: + return log; + + case CONFIG_DELETE_LOG: + return deletelog; + + default: + return ""; + } +} + + +int ConfigInt(ConfigIntVar var) +{ + switch(var) + { + case CONFIG_PORT: + return port; + + case CONFIG_TIMEOUT: + return timeout; + + case CONFIG_CASESENSE: + return casesense; + + case CONFIG_DEJUNK: + return dejunk; + + case CONFIG_TESTMODE: + return testmode; + + case CONFIG_BLOCKHTML: + return blockhtml; + + default: + return 0; + } +} + + +/* END OF FILE */ diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..a2ddc78 --- /dev/null +++ b/src/config.h @@ -0,0 +1,80 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + $Id$ + + Config file. + +*/ + +#ifndef KBS_CONFIG_H +#define KBS_CONFIG_H + + +/* ---------------------------------------- VARIABLE NAMES +*/ + +/* char* variables +*/ +typedef enum + { + CONFIG_HOSTNAME, + CONFIG_USERNAME, + CONFIG_PASSWORD, + CONFIG_LOG, + CONFIG_DELETE_LOG + } ConfigStringVar; + + +/* int/boolean variables +*/ +typedef enum + { + CONFIG_PORT, + CONFIG_TIMEOUT, + CONFIG_CASESENSE, + CONFIG_DEJUNK, + CONFIG_TESTMODE, + CONFIG_BLOCKHTML + } ConfigIntVar; + +/* ---------------------------------------- INTERFACES +*/ + +/* Loads in config file. Returns FALSE for problems. +*/ +int ConfigLoad(void); + + +/* Returns a reason for config load failure +*/ +const char *ConfigError(void); + + +/* Query interfaces for variables +*/ +const char *ConfigString(ConfigStringVar var); +int ConfigInt(ConfigIntVar var); + +#endif + +/* END OF FILE */ diff --git a/src/dbase.c b/src/dbase.c new file mode 100644 index 0000000..5eca1a9 --- /dev/null +++ b/src/dbase.c @@ -0,0 +1,281 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + Rules database + +*/ +static const char id[]="$Id$"; + +#include +#include +#include +#include +#include + +#include "global.h" +#include "dbase.h" +#include "dstring.h" +#include "config.h" +#include "rexp.h" +#include "util.h" + + +/* ---------------------------------------- TYPES +*/ +struct Domain + { + char *name; + int def_block; + int no_user; + int no_block; + int no_allow; + char **user; + char **block; + char **allow; + Domain *next; + Domain *prev; + }; + + +/* ---------------------------------------- GLOBALS +*/ +static Domain *head; +static Domain *tail; + +static int no_trusted_users=0; +static int no_trusted_domains=0; + +static char **trusted_user=NULL; +static char **trusted_domain=NULL; + + +/* ---------------------------------------- PRVIVATE FUNCTIONS +*/ +static int IsTrustedUser(const char *username) +{ + int f; + + for(f=0;fname,domain)==RE_Found) + return dom; + + dom=dom->next; + } + + return NULL; +} + + +static void DeJunk(DString ds, const char *p) +{ + int last_ws=FALSE; + + while(*p) + { + if (isspace(*p)) + { + if (!last_ws) + DSAddChar(ds,' '); + + last_ws=TRUE; + } + else + last_ws=FALSE; + + if (isalnum(*p)) + { + DSAddChar(ds,*p); + } + + p++; + } +} + + +/* ---------------------------------------- INTERFACES +*/ +Domain *DBNewDomain(const char *regexp) +{ + Domain *dom; + + dom=Malloc(sizeof *dom); + + dom->name=CopyStr(regexp); + dom->def_block=FALSE; + + dom->no_user=0; + dom->no_block=0; + dom->no_allow=0; + + dom->user=NULL; + dom->block=NULL; + dom->allow=NULL; + + if (tail) + tail->next=dom; + else + head=tail=dom; + + dom->prev=tail; + dom->next=NULL; + + return dom; +} + + +void DBDefault(Domain *domain, int block) +{ + domain->def_block=block; +} + + +void DBBlockUser(Domain *domain, const char *username) +{ + domain->no_user++; + domain->user=Realloc(domain->user,sizeof(char *)*domain->no_user); + domain->user[domain->no_user-1]=CopyStr(username); +} + + +void DBAllowSubject(Domain *domain, const char *regexp) +{ + domain->no_allow++; + domain->allow=Realloc(domain->allow,sizeof(char *)*domain->no_allow); + domain->allow[domain->no_allow-1]=CopyStr(regexp); +} + + +void DBBlockSubject(Domain *domain, const char *regexp) +{ + domain->no_block++; + domain->block=Realloc(domain->block,sizeof(char *)*domain->no_block); + domain->block[domain->no_block-1]=CopyStr(regexp); +} + + +void DBTrustedUser(const char *username) +{ + no_trusted_users++; + trusted_user=Realloc(trusted_user,sizeof(char *)*no_trusted_users); + trusted_user[no_trusted_users-1]=CopyStr(username); +} + + +void DBTrustedDomain(const char *domain) +{ + no_trusted_domains++; + trusted_domain=Realloc(trusted_domain,sizeof(char *)*no_trusted_domains); + trusted_domain[no_trusted_domains-1]=CopyStr(domain); +} + + +int DBBlockMessage(const POP3Message *msg) +{ + DString ds; + const Domain *dom; + int f; + + if (IsTrustedDomain(msg->from_domain)) + return FALSE; + + if (IsTrustedUser(msg->from_uname)) + return FALSE; + + if (!(dom=GetDomain(msg->from_domain))) + return FALSE; + + for(f=0;fno_user;f++) + { + if (ConfigInt(CONFIG_CASESENSE)) + { + if (strcmp(dom->user[f],msg->from_uname)==0) + return TRUE; + } + else + { + if (strcasecmp(dom->user[f],msg->from_uname)==0) + return TRUE; + } + } + + ds=DSInit(); + + if (ConfigInt(CONFIG_DEJUNK)) + DeJunk(ds,msg->subject); + else + DSAddCP(ds,msg->subject); + + for(f=0;fno_allow;f++) + { + if (RExpSearch(dom->allow[f],ds->text)==RE_Found) + { + DSFree(ds); + return FALSE; + } + } + + for(f=0;fno_block;f++) + { + if (RExpSearch(dom->block[f],ds->text)==RE_Found) + { + DSFree(ds); + return TRUE; + } + } + + DSFree(ds); + return dom->def_block; +} + + +/* END OF FILE */ diff --git a/src/dbase.h b/src/dbase.h new file mode 100644 index 0000000..df64927 --- /dev/null +++ b/src/dbase.h @@ -0,0 +1,86 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + $Id$ + + Rules database + +*/ + +#ifndef KBS_DBASE_H +#define KBS_DBASE_H + +#include "msg.h" + +/* ---------------------------------------- TYPES +*/ +struct Domain; + +typedef struct Domain Domain; + + +/* ---------------------------------------- INTERFACES +*/ + +/* Add a new domain and define the regular expression that defines it +*/ +Domain *DBNewDomain(const char *regexp); + + +/* Define the default mode for a domain +*/ +void DBDefault(Domain *domain, int block); + + +/* Adds a disallowed username for a domain +*/ +void DBBlockUser(Domain *domain, const char *username); + + +/* Add an allowable subject for a domain +*/ +void DBAllowSubject(Domain *domain, const char *regexp); + + +/* Adds a disallowed subject for a domain +*/ +void DBBlockSubject(Domain *domain, const char *regexp); + + +/* Adds a trusted username +*/ +void DBTrustedUser(const char *username); + + +/* Adds a trusted domain +*/ +void DBTrustedDomain(const char *domain); + + +/* Returns TRUE if message is to be blocked +*/ +int DBBlockMessage(const POP3Message *msg); + + +#endif + +/* END OF FILE */ diff --git a/src/dstring.c b/src/dstring.c new file mode 100644 index 0000000..e614e83 --- /dev/null +++ b/src/dstring.c @@ -0,0 +1,111 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + Dynamic strings + +*/ +static const char id[]="$Id$"; + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "global.h" +#include "dstring.h" +#include "util.h" + + +/* ---------------------------------------- CONSTANTS +*/ +#define BLOCKSIZE 512 + + +/* ---------------------------------------- INTERFACES +*/ +DString DSInit(void) +{ + DString ds; + + ds=Malloc(sizeof *ds); + + ds->len=0; + ds->text=Malloc(BLOCKSIZE); + ds->text[0]=0; + + return ds; +} + + +void DSFree(DString ds) +{ + free(ds->text); + free(ds); +} + + +DString DSReset(DString ds) +{ + DSFree(ds); + return DSInit(); +} + + +DString DSAddChar(DString to, char c) +{ + if (((to->len+2)%BLOCKSIZE)==0) + { + to->text=Realloc(to->text,(((to->len+2)/BLOCKSIZE)+1)*BLOCKSIZE); + } + + to->text[to->len++]=c; + to->text[to->len]=0; +} + + +DString DSAddCP(DString to, const char *from) +{ + to->len+=strlen(from); + to->text=Realloc(to->text,(((to->len+1)/BLOCKSIZE)+1)*BLOCKSIZE); + + strcat(to->text,from); +} + + +DString DSAddDS(DString to, const DString from) +{ + to->len+=from->len; + to->text=Realloc(to->text,(((to->len+1)/BLOCKSIZE)+1)*BLOCKSIZE); + + strcat(to->text,from->text); +} + + +/* END OF FILE */ diff --git a/src/dstring.h b/src/dstring.h new file mode 100644 index 0000000..db6454f --- /dev/null +++ b/src/dstring.h @@ -0,0 +1,86 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + $Id$ + + Dynamic strings + +*/ + +#ifndef KBS_DSTRING_H +#define KBS_DSTRING_H + +/* ---------------------------------------- TYPES +*/ +typedef struct + { + size_t len; + char *text; + } *DString; + +/* ---------------------------------------- INTERFACES +*/ + +/* Sets a DString up for use. Note when reusing the same DString, remember + to call DSReset() and get the return. + + Returns the new DString. +*/ +DString DSInit(); + + +/* Frees a DString. +*/ +void DSFree(DString ds); + + +/* Resets a string. Basically calls DSFree() then DSInit(). + + Returns the parameter. +*/ +DString DSReset(DString ds); + + +/* Adds a character onto a DString. + + Returns the passed DString. +*/ +DString DSAddChar(DString to, char c); + + +/* Adds a nul-terminated char pointer onto a DString. + + Returns the passed DString. +*/ +DString DSAddCP(DString to, const char *p); + + +/* Adds another DString. + + Returns the passed to DString. +*/ +DString DSAddDS(DString to, const DString from); + + +#endif + +/* END OF FILE */ diff --git a/src/global.h b/src/global.h new file mode 100644 index 0000000..6fcfe52 --- /dev/null +++ b/src/global.h @@ -0,0 +1,44 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + $Id$ + + Global include + +*/ + +#ifndef KBS_GLOBAL_H +#define KBS_GLOBAL_H + +/* ---------------------------------------- MACROS +*/ +#ifndef TRUE +#define TRUE 1 +#endif + +#ifndef FALSE +#define FALSE 0 +#endif + +#endif + +/* END OF FILE */ diff --git a/src/kbs.c b/src/kbs.c new file mode 100644 index 0000000..25afe5f --- /dev/null +++ b/src/kbs.c @@ -0,0 +1,147 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + +*/ +static const char id[]="$Id$"; + +#include +#include +#include +#include +#include +#include +#include + +#include "global.h" +#include "config.h" +#include "pop3.h" +#include "dbase.h" +#include "util.h" + +/* ---------------------------------------- MACROS +*/ +#define LOG (logfp ? logfp:stderr) + + +/* ---------------------------------------- TYPES +*/ + + +/* ---------------------------------------- GLOBALS +*/ +static const char *name=NULL; +static FILE *logfp=NULL; + + +/* ---------------------------------------- PROTOS +*/ + + +/* ---------------------------------------- MAIN +*/ +int main(int argc, char *argv[]) +{ + POP3Message *msg; + + if (strchr(argv[0],'/')) + name=strchr(argv[0],'/')+1; + else + name=argv[0]; + + if (!ConfigLoad()) + { + fprintf(stderr,"%s\n",ConfigError()); + exit(EXIT_FAILURE); + } + + switch(POP3Connect(ConfigString(CONFIG_HOSTNAME), + ConfigInt(CONFIG_PORT), + ConfigString(CONFIG_USERNAME), + ConfigString(CONFIG_PASSWORD), + ConfigInt(CONFIG_TIMEOUT))) + { + case POP3_OK: + break; + + case POP3_COMMERROR: + fprintf(LOG,"Comms error (errno = %d)\n",errno); + exit(EXIT_FAILURE); + break; + + case POP3_NOCONNECT: + fprintf(LOG,"No connection to host (errno = %d)\n",errno); + exit(EXIT_FAILURE); + break; + + case POP3_BADUSER: + fprintf(LOG,"Bad username\n"); + exit(EXIT_FAILURE); + break; + + case POP3_BADPASSWD: + fprintf(LOG,"Bad password\n"); + exit(EXIT_FAILURE); + break; + + default: + break; + } + + if ((msg=POP3GetList())) + { + int f; + int tot=0; + int block=0; + + for(f=0;msg[f].to;f++) + { + tot++; + printf("Num %d\n",msg[f].id); + printf(" From : %s@%s\n",msg[f].from_uname,msg[f].from_domain); + printf(" Subject : %s\n",msg[f].subject); + + if (DBBlockMessage(msg+f)) + { + printf(" BLOCKED : YES\n\n"); + block++; + } + else + printf(" BLOCKED : NO\n\n"); + } + + printf("%d messages, %d blocked\n",tot,block); + + POP3FreeList(msg); + } + else + { + printf("No messages\n"); + } + + return EXIT_SUCCESS; +} + + +/* ---------------------------------------- UTIL +*/ + +/* END OF FILE */ diff --git a/src/kbsrc b/src/kbsrc new file mode 100644 index 0000000..e59e512 --- /dev/null +++ b/src/kbsrc @@ -0,0 +1,91 @@ +# Simple example KBS config file +# + +# Set variables +# +set hostname mail.myisp.co.uk +set username foobar +set password raboof +set casesense off +set dejunk on +set testmode on + + +# Trusted people (from my address book) +# +trusted_users +{ + family@aol.com + fred@foobar.org + mailinglist@wibblesticks.com +} + +trusted_domains +{ + my-place-of-work.com + freebsd.org +} + + +# Domain based rules +# +# Remember that the domain is defined in the form of a regular expression! +# + +# Anyone who doesn't know me, has to include the string ansi-c to +# get through from a .net address. +# +domain "\.net$" +{ + default block + allow_subject ".*ansi-c.*" +} + +# 'Blacklist' a specific domain +# +domain "^wretched-hive-of-scum-and-villainy\.com$" +{ + default block +} + + +# Or alternatively apply general rules to all untrusted messages +# +domain "." +{ + default allow + + # Apologies in advance if you have the same user ID as me... + # + block_user emailname + + # Obviously, things like "credit card" will not be blocked from the bank + # as that's in the trusted_domains. + # + # And some of these may be accidently found in normal words, so remember + # to check the delete logs once in a while. + # + # And to avoid insulting anyone, there are some obvious words missing + # from this example list... If you're old enough, add them yourself. + # + # And finally remember a few variants - spelling isn't what it once was + # amongst spammers... + # + block_subject ".* ?penis ?.*" + block_subject ".* ?teenz ?.*" + block_subject ".* ?viagra ?.*" + block_subject ".* ?free all you can download ?.*" + block_subject ".* ?mortgage ?.*" + block_subject ".* ?credit card ?.*" + block_subject ".* ?miracle pill ?.*" + block_subject ".* ?teenage girl ?.*" + block_subject ".* ?video tape ?.*" + block_subject ".* ?sexy? ?.*" + block_subject ".* ?naked ?.*" + block_subject ".* ?nigeria ?.*" + + # Why would anyone sane want to use my username in a subject? + # I know who I am! + # + block_subject "emailname@my-isp.co.uk" +} diff --git a/src/msg.h b/src/msg.h new file mode 100644 index 0000000..314e9a7 --- /dev/null +++ b/src/msg.h @@ -0,0 +1,45 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + $Id$ + + Defines a POP3 message + +*/ + +#ifndef KBS_MSG_H +#define KBS_MSG_H + +typedef struct + { + int id; + char *to; + char *from; + char *from_uname; + char *from_domain; + char *subject; + char *content_type; + } POP3Message; + +#endif + +/* END OF FILE */ diff --git a/src/pop3.c b/src/pop3.c new file mode 100644 index 0000000..8fd2750 --- /dev/null +++ b/src/pop3.c @@ -0,0 +1,530 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + POP3 Interface + +*/ +static const char id[]="$Id$"; + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#include "global.h" +#include "pop3.h" +#include "dstring.h" +#include "util.h" + + +/* ---------------------------------------- CONSTANTS +*/ +#define BLOCKSIZE 512 + +#define HDR_UNKNOWN -1 +#define HDR_SUBJECT 0 +#define HDR_FROM 1 +#define HDR_TO 2 +#define HDR_CONTENT_TYPE 3 + +/* ---------------------------------------- TYPES +*/ + + +/* ---------------------------------------- GLOBALS +*/ +static int sock; +static int timeout; +static int connected=FALSE; + + +/* ---------------------------------------- PRIVATE FUNCTIONS +*/ +static void Chomp(char *p) +{ + size_t l; + + l=strlen(p); + + if (l && p[l-1]=='\012') + { + p[--l]=0; + } + + if (l && p[l-1]=='\015') + { + p[--l]=0; + } +} + + +static char *ChompQuotesWS(char *p) +{ + size_t l; + + l=strlen(p); + + while (l && (p[l-1]=='"' || isspace(p[l-1]))) + { + p[--l]=0; + } + + while (l && (p[0]=='"' || isspace(p[0]))) + memmove(p,p+1,--l); + + return p; +} + + +static int Connect(const char *hostname, int port) +{ + struct hostent *remote; + struct sockaddr_in addr; + + if (!(remote=gethostbyname(hostname))) + { + return FALSE; + } + + memcpy(&addr.sin_addr,remote->h_addr,remote->h_length); + + if ((sock=socket(PF_INET,SOCK_STREAM,0))==-1) + return FALSE; + + addr.sin_family=AF_INET; + addr.sin_port=htons(port); + + if (connect(sock,(const void *)&addr,sizeof(addr))==-1) + return FALSE; + + return TRUE; +} + + +static int SendSock(const char *p, size_t len) +{ + size_t sent=0; + + while(senttext); + + return TRUE; +} + + +static int GetResponse(DString ret) +{ + DString t; + int flag; + + t=DSInit(); + + if (GetLine(t)) + flag=t->text[0]=='+'; + else + flag=FALSE; + + if (ret) + DSAddDS(ret,t); + + DSFree(t); + + return flag; +} + + +static int GetMultiLine(DString ret) +{ + int flag; + + if (GetLine(ret)) + flag=TRUE; + else + flag=FALSE; + + return flag; +} + + +static void ParseHeader(POP3Message *msg, char *line) +{ + static const struct + { + const char *text; + int type; + } field[]= + { + {"Subject: ", HDR_SUBJECT}, + {"From: ", HDR_FROM}, + {"To: ", HDR_TO}, + {"Content-type: ", HDR_CONTENT_TYPE}, + {"Content-Type: ", HDR_CONTENT_TYPE}, + {NULL, HDR_UNKNOWN} + }; + + int f; + int type=HDR_UNKNOWN; + + for(f=0;type==HDR_UNKNOWN && field[f].text;f++) + if (strncmp(field[f].text,line,strlen(field[f].text))==0) + { + type=field[f].type; + line+=strlen(field[f].text); + } + + switch(type) + { + case HDR_SUBJECT: + msg->subject=CopyStr(line); + break; + + case HDR_FROM: + if (strchr(line,'<')) + { + char *t[3]; + + for(f=0;f<3 && t[f-1];f++) + t[f]=strtok(f==0 ? line:NULL,"<>@"); + + msg->from=CopyStr(t[0] ? ChompQuotesWS(t[0]) : "UNKNOWN"); + msg->from_uname=CopyStr(t[1] ? t[1] : "UNKNOWN"); + msg->from_domain=CopyStr(t[2] ? t[2] : "UNKNOWN"); + } + else + { + char *t[2]; + + for(f=0;f<2 && t[f-1];f++) + t[f]=strtok(f==0 ? line:NULL,"@"); + + msg->from=CopyStr("UNKNOWN"); + msg->from_uname=CopyStr(t[0] ? t[0] : "UNKNOWN"); + msg->from_domain=CopyStr(t[1] ? t[1] : "UNKNOWN"); + } + break; + + case HDR_TO: + msg->to=CopyStr(line); + break; + + case HDR_CONTENT_TYPE: + msg->content_type=CopyStr(line); + break; + + default: + break; + } +} + + +/* ---------------------------------------- INTERFACES +*/ + +POP3Status POP3Connect(const char *hostname, int port, + const char *username, const char *passwd, + int t) +{ + timeout=t; + connected=FALSE; + + if (port==0) + { + struct servent *ent; + + if ((ent=getservbyname("pop3","tcp"))) + port=ntohs(ent->s_port); + else + port=110; + } + + if (!Connect(hostname,port)) + return POP3_NOCONNECT; + + if (!GetResponse(NULL)) + return POP3_COMMERROR; + + if (Send("USER ",username,(const char *)NULL)!=1) + return POP3_COMMERROR; + + if (!GetResponse(NULL)) + return POP3_BADUSER; + + if (Send("PASS ",passwd,(const char *)NULL)!=1) + return POP3_COMMERROR; + + if(!GetResponse(NULL)) + return POP3_BADPASSWD; + + connected=TRUE; + + return POP3_OK; +} + + +POP3Message *POP3GetList(void) +{ + POP3Message *msg=NULL; + DString t; + char *p; + int no; + int f; + + if (!connected) + return NULL; + + t=DSInit(); + + Send("STAT",(const char *)NULL); + + if (!GetResponse(t)) + goto end; + + p=strtok(t->text," "); + + if (p) + p=strtok(NULL," "); + + if (!p) + goto end; + + no=atoi(p); + + msg=Malloc(sizeof *msg * (no+1)); + + for(f=0;ftext,".")==0) + done=TRUE; + else + { + ParseHeader(msg+f,t->text); + } + } + + if (!msg[f].to) + msg[f].to=CopyStr("UNKNOWN"); + + if (!msg[f].from) + msg[f].from=CopyStr("UNKNOWN"); + + if (!msg[f].from_uname) + msg[f].from_uname=CopyStr("UNKNOWN"); + + if (!msg[f].from_domain) + msg[f].from_domain=CopyStr("UNKNOWN"); + + if (!msg[f].subject) + msg[f].subject=CopyStr("UNKNOWN"); + + if (!msg[f].content_type) + msg[f].content_type=CopyStr("UNKNOWN"); + } + + msg[no].id=0; + msg[no].to=NULL; + msg[no].from=NULL; + msg[no].from_uname=NULL; + msg[no].from_domain=NULL; + msg[no].subject=NULL; + +end: + DSFree(t); + return msg; +} + + +POP3Status POP3Delete(int msg) +{ + return POP3_OK; +} + + +void POP3Logoff(void) +{ + Send("QUIT",(const char *)NULL); + GetResponse(NULL); +} + + +void POP3FreeList(POP3Message *list) +{ + if (list) + { + int f; + + for(f=0;list[f].to;f++) + { + free(list[f].to); + free(list[f].from); + free(list[f].from_uname); + free(list[f].from_domain); + free(list[f].subject); + } + + free(list); + } +} + + +/* END OF FILE */ diff --git a/src/pop3.h b/src/pop3.h new file mode 100644 index 0000000..c684634 --- /dev/null +++ b/src/pop3.h @@ -0,0 +1,90 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + $Id$ + + POP3 Interface + +*/ + +#ifndef KBS_POP3_H +#define KBS_POP3_H + +#include "msg.h" + +/* ---------------------------------------- TYPES AND CONSTANTS +*/ +typedef enum + { + POP3_OK, + POP3_COMMERROR, + POP3_NOCONNECT, + POP3_BADUSER, + POP3_BADPASSWD + } POP3Status; + +/* ---------------------------------------- INTERFACES +*/ + +/* Connect to a POP3 server. Pass a port number of zero to use the + default. Returns POP_OK if connected OK, otherwise one of the POP_x errors. +*/ +POP3Status POP3Connect(const char *hostname, int port, + const char *username, const char *passwd, + int timeout); + + +/* Collect information from the POP3 server. Returns a list of POP3Messages, + terminated with a NULL to entry, or NULL for not connected or error. + Note that fields that weren't present in a message will be set to + "UNKOWN". + + Note that if the TOP command is unimplemented on the server, then all the + fields in the message will be set to UNKNOWN. + + Obviously, this isn't much use. +*/ +POP3Message *POP3GetList(void); + + +/* Deletes the specified message. Returns POP_OK if deleted OK, otherwise + one of the POP_x errors. + + Remember that POP3 messages are number 1 .. N (so use the id field in + POP3Message). +*/ +POP3Status POP3Delete(int msg); + + +/* Logoff +*/ +void POP3Logoff(void); + + +/* Couresy function to free a message list. +*/ +void POP3FreeList(POP3Message *list); + + +#endif + +/* END OF FILE */ diff --git a/src/rexp.c b/src/rexp.c new file mode 100644 index 0000000..0311c44 --- /dev/null +++ b/src/rexp.c @@ -0,0 +1,63 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + Common utilities + +*/ +static const char id[]="$Id$"; + +#include +#include + +#include "global.h" +#include "rexp.h" +#include "config.h" + + +/* ---------------------------------------- INTERFACES +*/ + +RExpStatus RExpSearch(const char *regexpr, const char *string) +{ + regex_t re; + int flags; + int res; + + flags=REG_EXTENDED|REG_NOSUB; + + if (!ConfigInt(CONFIG_CASESENSE)) + flags|=REG_ICASE; + + if (regcomp(&re,regexpr,flags)) + return RE_BadExpression; + + res=regexec(&re,string,0,NULL,0); + + regfree(&re); + + /* printf("RExpSearch(%s,%s)=%d\n",regexpr,string,res); */ + + return res ? RE_NotFound : RE_Found; +} + + +/* END OF FILE */ diff --git a/src/rexp.h b/src/rexp.h new file mode 100644 index 0000000..04d1bb6 --- /dev/null +++ b/src/rexp.h @@ -0,0 +1,52 @@ +/* + + kbs - Simple, easily fooled, REXP spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + $Id$ + + Regular expressions + +*/ + +#ifndef KBS_REXP_H +#define KBS_REXP_H + +#include + +/* ---------------------------------------- INTERFACES +*/ + +typedef enum + { + RE_Found, + RE_NotFound, + RE_BadExpression, + } RExpStatus; + + +/* Search string for regexpr +*/ +RExpStatus RExpSearch(const char *regexpr, const char *string); + + +#endif + +/* END OF FILE */ diff --git a/src/util.c b/src/util.c new file mode 100644 index 0000000..b65ac01 --- /dev/null +++ b/src/util.c @@ -0,0 +1,79 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + Common utilities + +*/ +static const char id[]="$Id$"; + +#include +#include +#include + +#include "global.h" +#include "util.h" + + +/* ---------------------------------------- INTERFACES +*/ + +char *CopyStr(const char *p) +{ + char *new; + + new=Malloc(strlen(p)+1); + strcpy(new,p); + return new; +} + + +void *F_Malloc(const char *file, int line, size_t len) +{ + void *new; + + if (!(new=malloc(len))) + { + fprintf(stderr,"Unable to allocate %lu bytes for %s:%d\n", + (unsigned long)len,file,line); + exit(EXIT_FAILURE); + } + + return new; +} + + +void *F_Realloc(const char *file, int line, void *p, size_t len) +{ + void *new; + + if (!(new=realloc(p,len))) + { + fprintf(stderr,"Unable to reallocate %lu bytes for %s:%d\n", + (unsigned long)len,file,line); + exit(EXIT_FAILURE); + } + + return new; +} + + +/* END OF FILE */ diff --git a/src/util.h b/src/util.h new file mode 100644 index 0000000..f37eb12 --- /dev/null +++ b/src/util.h @@ -0,0 +1,58 @@ +/* + + kbs - Simple, easily fooled, POP3 spam filter + + Copyright (C) 2003 Ian Cowburn (ianc@noddybox.demon.co.uk) + + 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 + + ------------------------------------------------------------------------- + + $Id$ + + Common utilities + +*/ + +#ifndef KBS_UTIL_H +#define KBS_UTIL_H + +#include + +/* ---------------------------------------- INTERFACES +*/ + +#define Malloc(l) F_Malloc(__FILE__,__LINE__,(l)) +#define Realloc(p,l) F_Realloc(__FILE__,__LINE__,(p),(l)) + + +/* Copy a string +*/ +char *CopyStr(const char *p); + + +/* Malloc wrapper. Just use free() to free. +*/ +void *F_Malloc(const char *file, int line, size_t len); + + +/* Realloc wrapper. Just use free() to free. +*/ +void *F_Realloc(const char *file, int line, void *p, size_t len); + + +#endif + +/* END OF FILE */ -- cgit v1.2.3