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;
8
9 if (!bitnset(M_LOCALMAILER, to->q_mailer->m_flags))
10 return EX_OK;
11
12 if ((h = hvalue("subject", e->e_header)) = = NULL)
13 return EX_OK;
14
15 if ((len = strlen(h)) = = 0)
16 return EX_OK;
17
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
value—we 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.
|