发信人: zenz.hu(真)
整理人: hackerbay(2002-09-06 16:48:51), 站内信件
|
★原文转载自openbsd版zenz.hu的《eps邮件过滤进阶》★ 好吧,上次我们用eps做了一个很暴力的邮件过滤器,这次我们稍微往前走一点点,把过滤器变得稍微完满一些。
首先,我们通过研究qmail的代码,知道在.qmail文件中,如果调用一个外部程序,返回值是99的话,那么就代表不再进行下一步的邮件处理工作。而通过qmail-inject我们可以发送邮件。
知道了这些,我们就可以开始进一步把程序处理得更好些了。首先看代码,我们加了一些东西,请自己对比。
/* myfilter.c */
#include <stdio.h>
#include <eps.h>
#include <qmail.h>
char *exts[]={
".vbs",
".scr",
".exe",
".com",
".pif",
".386",
".bat",
".sys",
NULL
};
char *i_headers[]={
"From",
NULL
};
// 新加的,用于获取发件人的邮箱
char *do_address(struct header_t *h)
{
struct atom_t *aa = NULL;
struct address_t *alist = NULL, *a = NULL;
if (!(h->atoms))
return;
if (!(h->atoms->next))
return;
alist = eps_address_evaluate(h->data);
if (!alist) {
printf("%s: no valid addresses\n", h->name);
return;
}
for (a = alist; a->next; a = a->next) {
if ((a->next->user == NULL) && (a->next->address))
printf(" SYNTAX ERROR: [%s]\n", a->next->address);
else {
if (a->next->name)
return a->next->address;
else
return a->next->address;
}
}
eps_address_kill(alist);
}
// 旧的,用于检查附件的扩展名
int efilter_check_mime(struct mime_t *m)
{
int i = 0;
int p = 0;
if (!(m->filename))
return 0;
for (i = 0; exts[i]; i++) {
if (m->filename) {
p = strstr(m->filename, exts[i]);
if (p) {
return 1;
}
}
}
return 0;
}
int main(int argc, char *argv[])
{
int ret = 0;
int i;
char *frm_addr;
char *l = NULL;
struct mime_t *m = NULL;
struct header_t *h = NULL;
struct eps_t *eps = NULL;
FILE *qinject = NULL;
if (argc < 2)
eps = eps_begin(INTERFACE_STDIN, NULL);
else
eps = eps_begin(INTERFACE_FILENAME, argv[1]);
if (!eps)
return 1;
for (h = eps_next_header(eps); h; h = eps_next_header(eps)) {
if ((h->name) && (h->data)) {
for (i=0;i_headers[i]; i++) {
if (!(strcasecmp(i_headers[i],h->name))) {
frm_addr=do_address(h);
}
}
eps_header_free(eps);
}
}
for (l = eps_next_line(eps, BREAK_STOP); l; l = eps_next_line(eps, BREAK_STOP));
eps_init_mime(eps);
for (m = eps_next_mime(eps); m; m = eps_next_mime(eps)) {
if (efilter_check_mime(m)){
printf("rejected");
ret = 1;
}
}
eps_end(eps);
if (ret) {
qinject = qmail_inject();
fprintf(qinject,"From: [email protected]\n");
fprintf(qinject,"To: %s\n",frm_addr);
fprintf(qinject,"Subject: email filter warnning!\n");
fprintf(qinject,"X-mailer: Foxmail 4.1 [cn]\n");
fprintf(qinject,"Mime-Version: 1.0\n");
fprintf(qinject,"Content-Type: text/plain;\n charset=\"GB2312\"\n");
fprintf(qinject,"Content-Transfer-Encoding: quoted-printable\n\n");
fprintf(qinject,"您好,您发出的电子邮件因为包含以下被禁止的扩展名附件:\n");
fprintf(qinject,"*.vbs *.exe *.com *.pif *.scr *.bat *.386 *.sys\n");
fprintf(qinject,"所以您的邮件被过滤掉了。\n");
fprintf(qinject,"如果您确实希望包含此类文件到您的邮件当中,那么请先把他们打包。\n");
fprintf(qinject,"如果您并没有添加此类附件,那么您的电脑可能感染病毒,请杀毒后再发邮件。");
pclose(qinject);
return 99;
}
return 0;
}
编译程序
gcc -g -I/usr/include/eps -L/usr/lib -o myfilter myfilter.c -leps
然后把获得的myfilter复制到/var/vpopmail/bin目录中去,属主和组都和vdelivermail一样就可以了。
修改/var/vpopmail/domains/yourdomain/.qmail-default文件,把
| /var/vpopmail/bin/vdelivermail '' bounce-no-mailbox
改为
| /var/vpopmail/bin/myfilter
| /var/vpopmail/bin/vdelivermail '' bounce-no-mailbox
好了,你现在可以试一试这个新的邮件过滤器了。
----
来OpenBSD版看看吧!
我的QQ:2562293 |
|