rewriting email headers

Arley Carter arc at twinds.com
Fri Sep 6 18:04:51 EDT 2002


I  would like to strip the headers from email originating from out NAT'ed
network 182.168.1.0
and replace it with the ip of the cyrus mail server that resides out on the
external network.  I have doing this with checkcompat in conf.c, using the
example in Chapter 20 of the O'Reilly sendmail book.  However, I have had no
success here

The arguments for addheader have changed in sendmail 8.12.5 since the book
was
writen, (8.8 I believe)  it takes 4 arguments now instead of three as in the
example   The correct arguments for 8.12.5  are:
addheader(name of field, value of field, flag, envelope).  I
Below is the code I have modified and used.

/* Checkcompat subroutine from O'Reilly Sendmail v2 Chap 20 p 294. Removes
Internal addresses from Received from header.  Makes everything appear as it
originates from the mail hub on the public net.  This is needed because some
mail servers refuse to accept mail if they can't resolve the  Received from
header.  */

# define OUR_NET_IN_HEX 0x4152f3E0 /* external net 65.82.243.224 in hex */
# define OUR_NETMASK 0xfffffff8   /* 255.255.255.248 */
/* # define OUR_NET_IN_HEX 0xc0a80100 * / /* 192.168.1.0 in hex */
/* # define OUR_NETMASK 0xffffff00 */ /* 255.255.255.0 */
# define LOOP_CHECK "X-Loop-Check"

checkcompat(to, e)
        register ADDRESS *to;
        register ENVELOPE *e;
{
        HDR *h;
        int cnt;

        if (RealHostAddr.sa.sa_family == 0)
        {
                /* this is a locally submitted message */
                return EX_OK;
        }
        if (RealHostAddr.sa.sa_family != AF_INET ||
        (RealHostAddr.sin.sin_addr.s_addr & OUR_NETMASK) != OUR_NET_IN_HEX)
        {
                /* not received from the internal network */
                return EX_OK;
        }
        if (hvalue(LOOP_CHECK, e->e_header) != NULL)
        {
                /* We've stripped them once already */
                return EX_OK;
        }
        addheader(LOOP_CHECK, "loop check", 0, &e->e_header);

        for (cnt = 0, h = e->e_header; h != NULL; h = h->h_link)
        {
               if (strcasecmp(h->h_field, "received") != 0)
                       continue;
               if (cnt++ == 0)
                       continue;
               clrbitmap(h->h_mflags);
               h->h_flags |= H_ACHECK;
        }
        return (EX_OK);
}

The use of   &e->e_header as the fourth argument to addheader generates a
warning about passing an incompatible pointer type.

The substitution that should happen, suppressing the real ip of the sending
machine on the internal net happens where strcasecmp find the "received"
header and clears that field with clrbitmap.
H_ACHECK should cause the header to be discarded.

However, this isn't happening.  From is still from the internal network
address not from the mail server address.  Message ID also reflects the
internal network.  I believe this can be changed by setting Message Id to
H_ACHECK on the client machine's conf.c   Another question this raises is it
is easy enough to do this
on a unix baix in conf.c.  Where is this value set on a windows box?

I don't see where the From field is being reset to the mail server machine's
ip unless sendmail should be filling this field with the mail server's ip
automagically when it finds the blank from field we cleared out here in
another part of the sendmail code.

Can somebody clue me in where I am going off the trail here?






More information about the Info-cyrus mailing list