Using regular expressions in sendmail.cf: map-regex-2.8
Look for changes in the file CHANGES.
The map-regex is included in sendmail-8.9. New Rulesets are available at
http://www.unix-ag.uni-hannover.de/soft/check_local/.
If you want to use regular expressions in sendmail.cf e.g. to
avoid UBE, you can use this little
map implementation. If you want to use it in your sendmail.cf, be sure
you understand, what you are doing. If you want to use the check_* rulesets
look at
http://www.informatik.uni-kiel.de/%7Eca/email/check.html
Features
- the pattern is compiled only one time
- easy to use map-lookup in sendmail.cf
- easy to install for system-administrators
- based on POSIX-regex-library (regcomp(), regerr(), regexec())
- There is an experimental ruleset for checking the header
Read the README.check_header.
- To have _SPAM_FRIENDS_ or _SPAM_HATERS_ with header checking, use
map-storage. It has also an option for
converting IPs to binary "numbers". It's usefull if you have no ABC-class
subnets and for adding fields to the header of the mail. Read the
README.map-storage.
How to install
- Download map-regex-2.8.tar and 'tar xf' it.
- Apply the patch (conf.c.patch)
to sendmail-8.8.?/src/conf.c.
- Copy map_regex.c to sendmail-8.8.?/src/.
- Edit your Makefile in sendmail-8.8.?/src/Makefiles/
DBMDEF= -DMAP_REGEX ...
# additional .o files needed
OBJADD=map_regex.o
- ./makesendmail (if it does not work "rm -r src/obj*")
- Test: ./sendmail -d72 -bt -Ctest_sendmail.cf
- Send bug-reports to:
Jan.Krueger+map@stud.uni-hannover.de
- If you want to know, how extended regular expressions work, please
read regex.ps.gz taken from lib-regex from gnu.
Troubleshooting
Link fails: undefined reference to 'regcomp' or
pattern-compile-error: : Operation not applicable
Your libc does not include a running version of POSIX-regex. Use
libregex from gnu. ftp://prep.ai.mit.edu/pub/gnu/ Filename: regex-?.?.tar.gz. Or lookup a ftp-mirror e.g.
ftp://ftp.rrzn.uni-hannover.de/pub/mirror/gnu/.
You can also use the regex-lib by Henry Spencer. ftp://ftp.funet.fi/pub/languages/C/spencer/regex.shar.gz
Your can link the regex.o from gnu or put it in a libregex.a and install it in
the same place as e.g. libdb.a. Then you can link '-lregex'.
Make sure, your compiler reads regex.h from the distribution and not
from /usr/include, otherwise sendmail will dump a core. Sometimes you must
"ln -s regex-0.12/regex.h sendmail-8.?.?/src/".
pattern-compile-error: [ ] imbalance or syntax error
If this error occurs using [^[()] syntax, your regex-lib is not POSIX
compliant. Exercise: Remove it from your libc and
put in a better one. ;-)
What is the patch doing?
The conf.c.patch adds the definition of the map-type "regex" to the
function setupmaps() in the file conf.c.
MAPDEF("regex", NULL, 0,
regex_map_init, null_map_open, null_map_close,
regex_map_lookup, null_map_store);
If you use Kname regex in your sendmail.cf,
regex_map_init() is called.
For the lookup $(name $1 $) regex_map_lookup() is used.
This is not really a patch, its only an addition: If you don't use
regex-maps in your sendmail.cf, the behaviour of sendmail is not changed.
How it works
It knows the following options:
- -n NOT
- -f case sensitive
- -b basic regular expressions (default is extended)
- -sFIELDS enable parsing capablilies (substrings () syntax)
The parameter is optional. Syntax: i.e. -s2,3 or -s1 or -s2,2,5
- -dDELIM define the delimiter (use with -s)
- -aAPPEND APPEND is appended, if matching
- -m match only (without replacing/discarding the value). APPEND is appended.
The FIELDS parameter can also be given in the lookup (overrides the -sFIELDS):
R$* $: $(parse $1 $@ FIELDS $)
This is a simple test_sendmail.cf
# regex map valid?
Kvalid regex -a@MATCH ^[0-9]+<@
Kparse regex -d@@ -s (\[([0-9]+\.[0-9]+\.[0-9]+\.[0-9]+)\]|from *([a-z.]+))+
Smatch_parse
R$* $: $(parse $1 $)
R$* @@ $* @@ $* $: $2 $| $3
R$+ $| $* $: IP: $1 $| $2
R$* $| $+ $: $1 $| host: $2
Smatch_valid
R$* $: $(valid $1 $)
In the following, the dialogue of the test is shown:
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> match_valid 123<@domain.com>
rewrite: ruleset 198 input: 123 < @ domain . com >
regex_map_lookup: key '123<@domain.com>'
rewrite: ruleset 198 returns: @ MATCH
> match_valid user75<@domain.com>
rewrite: ruleset 198 input: user75 < @ domain . com >
regex_map_lookup: key 'user75<@domain.com>'
rewrite: ruleset 198 returns: user75 < @ domain . com >
> match_parse received from hostname.domain.com [123.43.5.1]
rewrite: ruleset 199 input: received from hostname . domain . com [ 123 . 43 . 5 . 1 ]
regex_map_lookup: key 'received from hostname.domain.com[123.43.5.1]'
rewrite: ruleset 199 returns: IP : 123 . 43 . 5 . 1 $| host : hostname . domain . com
Use it with m4
Copy checkregex.m4 to sendmail-?.?.?/cf/hack. Use
HACK(checkregex, `pattern') in
your .mc-file. The parameter is optional, the default
pattern is `^[0-9]+<@'.
After this you can add "checkregex-calls" to your check_*.m4 rulesets. E.g.:
ifdef(`_CHECKREGEX_',
# check address against checkregex
R$* $: $(checkregex $1 $)
R@MATCH $#error $@ 5.1.8 $: 551 spam address. go away.)
This hook is included in check_mail3.m4
by Claus Aßmann.
Jan Krüger, Jan.Krueger+map@stud.uni-hannover.de