D.3 Reject Excess 8-Bit Characters

Much of the spam email that arrives from the Far East (especially Korea and China) is sent with Subject: headers that contain unencoded 8-bit characters. Because 8-bit characters in the Subject: header are illegal, it is perfectly OK to reject such email.

In this section we show you how to write a routine that can reject 8-bit Subject: headers using the checkcompat( ) routine. In the following example, the numbers to the left are for reference and are not a part of the code.

1  int
2  checkcompat(to, e)
3          register ADDRESS *to;
4          register ENVELOPE *e;
5  {
6          char *cp, *h;
7          int len, cnt;
9          if (!bitnset(M_LOCALMAILER, to->q_mailer->m_flags))
10                 return EX_OK;
12         if ((h = hvalue("subject", e->e_header)) =  = NULL)
13                 return EX_OK;
15         if ((len = strlen(h)) =  = 0)
16                 return EX_OK;
18         cnt = 0;
19         for (cp = h; *cp != ''; ++cp)
20         {
21                 if ((*cp & 0x80) != 0)
22                         ++cnt;
23         }
24         if ((cnt * 2) > len)
25         {
26                 e->e_flags |= EF_NO_BODY_RETN;
27                 e->e_message = "553 Cannot accept eight-bit subjects";
28                 to->q_status = "5.7.1";
29                 return EX_UNAVAILABLE;
30         }
31         return EX_OK;
32 }

We begin (line 2) by declaring checkcompat( ) the same way it is declared inside conf.c. The two arguments (*to and *e) passed to it are described in the first section of this appendix.

Our routine for rejecting 8-bit characters in the Subject: header requires four local variables (line 6). The *h will point to the value of the Subject: header. The *cp will be walked through *h looking for eight-bit characters. The len will hold the length of the Subject: header's value. The cnt will hold the count of 8-bit characters found.

Before we check the Subject: header, however, we need to make sure the message is being delivered locally. We don't need to screen outbound or relayed mail. We do that (line 9) by checking to see if the M_LOCALMAILER flag (the F=l delivery agent flag, F=l (lowercase L)) was set, which returns EX_OK if it was not.

Next, we fetch the Subject: header's value (line 12) by calling hvalue( ). If there is no Subject: header (if hvalue returns NULL), we accept the message by returning EX_OK.

We calculate the length of the Subject: header's value (line 15) and save the length in len. If the length is zero (line 15)that is, if the Subject: header was present but lacked a valuewe accept the message by returning EX_OK.

If the Subject: header has a value, we next scan the value (line 19) looking for any characters that have the 8-bit set (line 21). Each such 8-bit character that is found causes the count in cnt to increment.

After all the characters in the Subject: header have been checked, we determine if more than half have the 8-bit set (line 24). If so, we reject the message with the error 553 Cannot accept eight-bit subjects.

If fewer than half of the characters have the 8-bit set, we accept the message. This is purely arbitrary. You might prefer to reject the message if even a single character has the 8-bit set.

    Part I: Build and Install
    Part II: Administration
    Part III: The Configuration File