ExtMail服务器社区's Archiver

hzqbbc 发表于 2003-2-14 13:34

dfbb牛写的一个可对base64解码并过滤的补丁

发信人: dfbb (赵无忌☆星心相随), 信区: FreeBSD
标 题: Re: 被迫搞邮件过滤,请大家支持
发信站: BBS 水木清华站 (Thu Feb 13 09:17:37 2003), 转信

Post一个我写的给Postfix的补丁,是用来匹配Base64编码过滤的
适用于postfix-1.1.11-20021115,不过最新的postfix自己改一下就
可以.这个补丁不会被Wietse Venema接受,他老人家明确反对这么干.
现在的Content Filter只能明文匹配.


------------------------BEGIN--------------------------------------
diff -urN postfix-1.1.11-20021115/src/cleanup/cleanup.h postfix-1.1.11-20021115.
--- postfix-1.1.11-20021115/src/cleanup/cleanup.h  Sat Oct 26 04:26:33 2002
+++ postfix-1.1.11-20021115.new/src/cleanup/cleanup.h  Fri Nov 22 02:58:47 2002
@@ -25,6 +25,7 @@
#include <mail_stream.h>
#include <mail_conf.h>
#include <mime_state.h>
+#include <base64_code.h>

/*
  * These state variables are accessed by many functions, and there is only
@@ -66,6 +67,8 @@
   NVTABLE *attr;     /* queue file attribute list */
   MIME_STATE *mime_state;    /* MIME state engine */
   int   mime_errs;     /* MIME error flags */
+  int   text_seen;     /* MIME text type SEEN */
+  int   base64_seen;    /* MIME base64 encoding SEEN */
   char  *filter;      /* from header/body patterns */
} CLEANUP_STATE;

diff -urN postfix-1.1.11-20021115/src/cleanup/cleanup_message.c postfix-1.1.11-2
--- postfix-1.1.11-20021115/src/cleanup/cleanup_message.c  Tue Oct 29 06:14:18
+++ postfix-1.1.11-20021115.new/src/cleanup/cleanup_message.c  Fri Nov 22 04:22
@@ -85,6 +85,9 @@

#include "cleanup.h"

+#define STR(x) vstring_str(x)
+#define LEN(x) VSTRING_LEN(x)
+
/* cleanup_out_header - output one header as a bunch of records */

static void cleanup_out_header(CLEANUP_STATE *state, VSTRING *header_buf)
@@ -358,10 +361,19 @@
   CLEANUP_STATE *state = (CLEANUP_STATE *) context;
   const char *myname = "cleanup_header_callback";
   char  *hdrval;
+  struct type_map {
+  const char *name;
+  const char *type;
+  };
   struct code_map {
  const char *name;
  const char *encoding;
   };
+  static struct type_map type_map[] = {
+  "text/html;", MAIL_ATTR_ENC_7BIT,
+  "text/plain;", MAIL_ATTR_ENC_7BIT,
+  0,
+  };
   static struct code_map code_map[] = { /* RFC 2045 */
  "7bit", MAIL_ATTR_ENC_7BIT,
  "8bit", MAIL_ATTR_ENC_8BIT,
@@ -371,9 +383,16 @@
  0,
   };
   struct code_map *cmp;
+  struct type_map *tmp;
   MAPS  *checks;
   const char *map_class;

+  static VSTRING *src_buf= 0;
+  static VSTRING *base64_buf = 0;
+  src_buf = vstring_alloc(1024);
+  base64_buf = vstring_alloc(1024);
+
+
   if (msg_verbose)
  msg_info("%s: &#39;%s&#39;", myname, vstring_str(header_buf));

@@ -391,14 +410,28 @@
  && (CHECK(MIME_HDR_PRIMARY, cleanup_header_checks, VAR_HEADER_CHECKS)
   ││ CHECK(MIME_HDR_MULTIPART, cleanup_mimehdr_checks, VAR_MIMEHDR_CHECKS)
   ││ CHECK(MIME_HDR_NESTED, cleanup_nesthdr_checks, VAR_NESTHDR_CHECKS))) {
-  char  *header = vstring_str(header_buf);
+  const char *header = vstring_str(header_buf);
  const char *value;
+  char *base64;
+
+  if(extract_base64_header(src_buf,header) !=0 ) {
+    base64_decode(base64_buf,STR(src_buf),LEN(src_buf));
+    base64 = vstring_str(base64_buf);
+  }else{
+    base64 = vstring_str(header_buf);
+  }
+
+

-  if ((value = maps_find(checks, header, 0)) != 0) {
-    if (cleanup_act(state, "header", header, value, map_class)
+  if ((value = maps_find(checks, base64, 0)) != 0) {
+    if (cleanup_act(state, "header", base64, value, map_class)
    == CLEANUP_ACT_DROP)
+    vstring_free(src_buf);
+    vstring_free(base64_buf);
    return;
  }
+  vstring_free(src_buf);
+  vstring_free(base64_buf);
   }

   /*
@@ -419,14 +452,31 @@
   while (ISSPACE(*hdrval))
  hdrval++;
   /* trimblanks(hdrval, 0)[0] = 0; */
+  if (hdr_opts->type == HDR_CONTENT_TYPE) {
+  for (tmp = type_map; tmp->name != 0; tmp++) {
+    if (strncasecmp(hdrval, tmp->name, strlen(tmp->name)) == 0) {
+
+    state->text_seen = 1;
+    break;
+    }else{
+    state->text_seen = 0;
+    }
+  }
+  }
+
   if (hdr_opts->type == HDR_CONTENT_TRANSFER_ENCODING) {
  for (cmp = code_map; cmp->name != 0; cmp++) {
    if (strcasecmp(hdrval, cmp->name) == 0) {
+
+    if(strcasecmp(cmp->name,"base64") == 0)
+      state->base64_seen = 1;
+    else
+      state->base64_seen = 0;
    if (strcmp(cmp->encoding, MAIL_ATTR_ENC_8BIT) == 0)
      nvtable_update(state->attr, MAIL_ATTR_ENCODING,
          cmp->encoding);
    break;
-    }
+    }
  }
   }

@@ -595,7 +645,10 @@
             off_t offset)
{
   CLEANUP_STATE *state = (CLEANUP_STATE *) context;
-
+  static VSTRING *src_buf = 0;
+  static VSTRING *base64_buf = 0;
+  src_buf = vstring_alloc(1024);
+  base64_buf = vstring_alloc(1024);
   /*
   * Crude message body content filter for emergencies. This code has
   * several problems: it sees one line at a time; it looks at long lines
@@ -607,12 +660,23 @@
  && (var_body_check_len == 0 ││ offset < var_body_check_len)) {
  const char *value;

-  if ((value = maps_find(cleanup_body_checks, buf, 0)) != 0) {
-    if (cleanup_act(state, "body", buf, value, VAR_BODY_CHECKS)
+  if(state->text_seen == 1 && state->base64_seen == 1){  /* base64 decode */
+    vstring_strcpy(src_buf,buf);
+    base64_decode(base64_buf,STR(src_buf),LEN(src_buf));
+  }else{
+    vstring_strcpy(base64_buf,buf);
+  }
+
+  if ((value = maps_find(cleanup_body_checks, STR(base64_buf), 0)) != 0) {
+    if (cleanup_act(state, "body", STR(base64_buf), value, VAR_BODY_CHECKS)
    == CLEANUP_ACT_DROP)
+    vstring_free(src_buf);
+    vstring_free(base64_buf);
    return;
  }
   }
+  vstring_free(src_buf);
+  vstring_free(base64_buf);
   cleanup_out(state, type, buf, len);
}

diff -urN postfix-1.1.11-20021115/src/util/base64_code.c postfix-1.1.11-20021115
--- postfix-1.1.11-20021115/src/util/base64_code.c Tue Jan 8 08:55:04 2002
+++ postfix-1.1.11-20021115.new/src/util/base64_code.c Fri Nov 22 04:15:58 2002
@@ -145,6 +145,37 @@
   return (result);
}

+VSTRING *extract_base64_header (VSTRING *result, const char *in)
+{
+ const char *o, *p, *q;
+
+ VSTRING_RESET(result);
+ q = in;
+ while ((p = strstr (q, "=?")))
+ {
+  for (q = p + 2;
+   0x20 < *q && *q < 0x7f && !strchr ("()<>@,;:"/[]?.=", *q);
+   q++)
+   ;
+  if (q[0] != &#39;?&#39; ││ !strchr ("BbQq", q[1]) ││ q[2] != &#39;?&#39;)
+   continue;
+  for (q = q + 3; 0x20 < *q && *q < 0x7f && *q != &#39;?&#39;; q++)
+   ;
+  if (q[0] != &#39;?&#39; ││ q[1] != &#39;=&#39;)
+  {
+   --q;
+   continue;
+  }
+
+  if((o = strstr (in, "?B?"))) {
+    vstring_strncpy(result,o+3,q-o-3);
+      return result;
+  }
+ }
+
+ return(0);
+}
+
#ifdef TEST

/*
diff -urN postfix-1.1.11-20021115/src/util/base64_code.h postfix-1.1.11-20021115
--- postfix-1.1.11-20021115/src/util/base64_code.h Mon Oct 15 22:45:49 2001
+++ postfix-1.1.11-20021115.new/src/util/base64_code.h Fri Nov 22 03:33:43 2002
@@ -21,6 +21,7 @@
  */
extern VSTRING *base64_encode(VSTRING *, const char *, int);
extern VSTRING *base64_decode(VSTRING *, const char *, int);
+extern VSTRING *extract_base64_header (VSTRING *, const char *);

/* LICENSE
/* .ad
------------------------------END----------------------------------------






【 在 delphij (make universe...) 的大作中提到: 】
: 只是打算做,应该是自己的系统,我可能要写一个反病毒的模块。
: 其实不想做内容过滤,因为这东西在理论上已经证明是不可行的,
: 但如果被要求的话,有点经验也没坏处。
: 初步打算基于postfix的接口。现在正在琢磨方案,有什么建议吗?
: 我计划和入侵检测结合一下。


--

沧海一声笑
滔滔两岸潮
浮沉随浪只记今朝
来!共进一杯
让我们歌〖笑傲江湖〗到通宵!!!


※ 来源:・BBS 水木清华站 smth.edu.cn・[FROM: 210.52.3.200]


页: [1]

Powered by Discuz! Archiver 7.0.0  © 2001-2009 Comsenz Inc.