header.c #6

  • //
  • guest/
  • bryan_costales/
  • header.c
  • View
  • Commits
  • Open Download .zip Download (4 KB)
/************************************************************
** $Id: header.c,v 0.6 2003/12/15 15:03:33 bcx Exp bcx $
**
** Copyright Bryan Costales and Perforce Software, Inc. 2003
**
** This code is "open source" as defined by version 1.9 of
** the Open Source Definition from:
**
**	http://www.opensource.org/docs/definition.php.
**
** Entry points defined in this file:
**
** header_recipient():
** 	Add the passed recipients to a growing list of
** 	recipients (decomments each along the way).
** deRFC822():
** 	Strip the RFC822 comments from a recipient address.
** header_received():
** 	Check a received header to see if it was created by
**	one of our mx servers.
** header_messageid():
** 	Check a message-id header to see if it is legal.
*************************************************************/

# define EXTERN extern
# include "slow.h"

/*
** A simple minded count that avoids mallocs.
*/
int
header_recipient(char *value)
{
	char *vp;
	int count = 1;

	if (value == NULL)
		return 0;

	for (vp = value; *vp != '\0'; ++vp)
	{
		if (*vp == ',')
			++count;
	}
	return count;
}

/*
** A recipient can be buried among RFC822 comments.
** We snarf the address from the comments.
*/
char *
deRFC822(char *addr)
{
	int inquote;
	char *cp, *ep;

	if (addr == NULL)
		return NULL;

	/*
	 * First try to shortcut to an <addr> address.
	 */
	if ((cp = strchr(addr, '<')) != NULL)
	{
		++cp;
		ep = strchr(cp, '>');
		if (ep == NULL)
			return cp;
		*ep = '\0';
		while (*cp == '<')
			++cp;
		if (cp >= ep)
			return NULL;
		return cp;
	}

	/*
	 * Then remove any (comment) addr ...
	 * Include handling of nested comments (a(b))
	 */
	inquote = 0;
	for (cp = addr; *cp != '0'; ++cp)
	{
		if (*cp == '(')
		{
			++inquote;
			continue;
		}
		if (*cp == ')')
		{
			--inquote;
			continue;
		}
		if (inquote > 0)
			continue;
		if (isspace((int)*cp))
			continue;
		else
			break;
	}
	if (*cp == '\0')
		return NULL;
	for (ep = cp+1; *ep != '\0'; ++ep)
	{
		if (isspace((int)*ep))
			break;
	}
	*ep = '\0';
	return cp;
}

/*
** Process a received header to see if it was produced by one
** of our MX servers.
** If it was, return the IP number of the host that sent it to
** the MX server.
*/
PRIMARY_KEY
header_received(char *value)
{
	char **argv, **av;
	char *cp, *ep;
	PRIMARY_KEY ip;

	if (value == NULL)
		return (PRIMARY_KEY)0;


	argv = mkargv(value, ' ', TRUE);
	if (argv == NULL)
		return (PRIMARY_KEY)0;

	for (av = argv; *av != NULL; ++av)
	{
		if (strcasecmp(*av, "by") == 0)
			break;
	}
	if (*av == NULL || *(++av) == NULL)
	{
		argv = free_list(argv);
		return (PRIMARY_KEY)0;
	}

	if (is_in_list(*av, MxHosts) == FALSE)
	{
		argv = free_list(argv);
		return (PRIMARY_KEY)0;
	}

	/*
	 * This Received: header was created by
	 * one of our MX servers.
	 */
	cp = NULL;
	for (av = argv; *av != NULL; ++av)
	{
		if (strcasecmp(*av, "by") == 0)
		{
			argv = free_list(argv);
			return (PRIMARY_KEY)0;
		}
		if (strcasecmp(*av, "from") == 0)
			continue;
		if ((cp = strchr(*av, '[')) != NULL)
			break;
	}
	if (cp == NULL)
	{
		argv = free_list(argv);
		return (PRIMARY_KEY)0;
	}
	++cp;
	if ((ep = strchr(cp, ']')) == NULL)
	{
		argv = free_list(argv);
		return (PRIMARY_KEY)0;
	}
	*ep = '\0';

	if ((int)(ip = inet_addr(cp)) == -1)
	{
		argv = free_list(argv);
		return (PRIMARY_KEY)0;
	}

	argv = free_list(argv);
	ip = revbytes(ip);
	return ip;
}

/*
** The message-id: header must exist and be properly formed.
** If it exists, this routine will determine if it is properly
** formed. It must be inside angle braces and look like
** an address.
*/
bool
header_messageid(char *value)
{
	char *v, *e;

	if (value == NULL)
		return FALSE;

	v = cleanup(value);
	if (v == NULL)
		return FALSE;

	if (strchr(v, ' ') != NULL)
		return FALSE;

	if (strchr(v, '\t') != NULL)
		return FALSE;

	if (*v != '<')
		return FALSE;

	e = v + strlen(v) -1;
	if (*e != '>')
		return FALSE;

	if ((v = strchr(value, '@')) == NULL)
		return FALSE;
	if (strchr(++v, '.') == NULL)
		return FALSE;

	return TRUE;
}
# Change User Description Committed
#6 4222 bryan_costales Massive rewrite to speed up the database writes.
Using a single database now with duplicate keys
where the keys are the IP numbers. Added a purge
command and removed the garbage command. Fixed
some leaking memory bugs and properly closed the
database in a few places were it was not
properly closed. Updated the docs to reflect
this and bumped both the database version and
release number. Running on a FreeBSD 3.x machine
and a Solaris 9 machine.
#5 4030 bryan_costales Finished documenting the configuration file
Fixed a race condition and a core dump bug.
Added hooks for whitelisting and IP aliasing
Added support for Berkeley DB 4.2
Converted to htonl() and ntohl()

Known Bugs:
    ip.db cannot be shared over NFS
    IP tracking from MX hosts can fail
    A RunAsUser config option is needed.
#4 3998 bryan_costales Brought the whole distribution up to V0.9
Added a huge abount of documentation.
Added slowedit find
Created startup scripts to launch for testing
Fixed numerous bugs.
Fixed a few portablity issues.
Installed hooks for whitelisting and IP aliases.
#3 3957 bryan_costales Added rbl lookup support and testing for same.
Folded in support for smfi_stop().
Added lots of slowedit commands
Fixed a serious bug in MX lookups.
Added to documentation.
#2 3890 bryan_costales This is the 0.6 release. The following have been
added with the uses indicated:

    Source files: edit.c -- the slowedit functions
              compat.c -- missing system files
    Autoconf:     configure.ac, makefile.am config.h
              aclocal.m4 acinclude.m4 build/
    Documents:    doc/ -- html and man(1) documents
    Testing:      tests/ -- regressive testing
    TODO:          -- revised to show actual progress
#1 3838 bryan_costales This is pre-release 0.5 (rcs numbering) which includes:
    The milter source files and Makefile
    A regressive testing subdirectory with Makefile and /bin/sh scripts.
    A patches subdirectory with a patch file for V8.13 sendmail
All have been compiled and tested on a 64bit Sun Solaris 9 machine.