D.3 Reject Excess 8-Bit CharactersMuch 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. |