ze-filter  (ze-filter-0.8.0-develop-180218)
mlfi_body.c
Go to the documentation of this file.
1 
2 /*
3  *
4  * ze-filter - Mail Server Filter for sendmail
5  *
6  * Copyright (c) 2001-2018 - Jose-Marcio Martins da Cruz
7  *
8  * Auteur : Jose Marcio Martins da Cruz
9  * jose.marcio.mc@gmail.org
10  *
11  * Historique :
12  * Creation : janvier 2002
13  *
14  * This program is free software, but with restricted license :
15  *
16  *
17  * This program is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
20  *
21  * More details about ze-filter license can be found at ze-filter
22  * web site : http://foss.jose-marcio.org
23  */
24 
25 /* ****************************************************************************
26  * *
27  * *
28  ******************************************************************************/
29 
30 sfsistat
31 mlfi_body(ctx, bodyp, bodylen)
32  SMFICTX *ctx;
33  unsigned char *bodyp;
34  size_t bodylen;
35 {
36  CTXPRIV_T *priv = MLFIPRIV(ctx);
37  int result = SMFIS_CONTINUE;
39 
40  static pthread_mutex_t st_mutex = PTHREAD_MUTEX_INITIALIZER;
41  static kstats_T st_time = KSTATS_INITIALIZER;
42 
44 
45  ZE_MessageInfo(12, "Entering mlfi_body...");
46 
47  stats_inc(STAT_BYTES, bodylen);
48 
49  if (priv == NULL) {
50  result = SMFIS_TEMPFAIL;
51  goto fin;
52  }
53 
55 
56  /*
57  ** Add here spool file creation
58  ** or better, uncomment this...
59  */
60  if (!spool_file_is_open(priv)) {
61  /*
62  * open a file to store this message
63  */
64  if (!spool_file_create(priv)) {
65  result = SMFIS_TEMPFAIL;
66 
67  goto fin;
68  }
69  }
70 #if 0
71  /*
72  * Message with passport ???
73  */
74  if (priv->nb_rcpt == 1 && priv->pass_ok)
75  goto fin;
76 #endif
77 
78  sm_macro_update(ctx, priv->sm);
79 
80  if (bodyp == NULL) {
81  ZE_MessageError(9, "%s : bodyp = NULL", CONNID_STR(priv->id));
82  result = SMFIS_TEMPFAIL;
83 
84  goto fin;
85  }
86 #if 1
87  priv->msg_size += bodylen;
88  priv->nb_bytes += bodylen;
89 #endif
90 
91 #if defined(_FFR_CLEAN_MSG_BUF)
92  bodylen = buf_clean_rc((char *) bodyp, bodylen);
93 #endif
94 
95  /*
96  * output body block to spool file
97  */
98  if (!spool_file_write(priv, (char *) bodyp, bodylen)) {
99  ZE_LogMsgWarning(0, "%s spool_file_write error", CONNID_STR(priv->id));
100  (void) spool_file_forget(priv);
101  }
102 #if 0
103  priv->msg_size += bodylen;
104  priv->nb_bytes += bodylen;
105 #endif
106 
107 
108  if (priv->body_nb == 0 && IS_UNKNOWN(priv->netclass.class)) {
109  char buf[256];
110  header_T *h = priv->headers;
111  int i;
112  bool doit = FALSE;
113 
114  if (bodylen > sizeof (buf) - 1)
115  goto ok;
116 
118  goto ok;
119 
120  i = 0;
121  while (i < bodylen && isspace(bodyp[i]))
122  i++;
123 
124  memcpy(buf, bodyp + i, bodylen - i);
125  buf[bodylen - i] = '\0';
126 
127  while ((i = strlen(buf)) > 0) {
128  if (!isspace(buf[i - 1]))
129  break;
130  buf[i - 1] = '\0';
131  }
132 
133  if (strlen(buf) >= cf_get_int(CF_MIN_BODY_LENGTH))
134  goto ok;
135 
136  {
137  char **cmd;
138 
139  for (cmd = SYMPA_CMDS; (*cmd != NULL); cmd++) {
140  ZE_MessageInfo(12, "Checking body : %s %s", buf, *cmd);
141  if (zeStrRegex(buf, *cmd, NULL, NULL, TRUE))
142  goto ok;
143  }
144 
145  h = priv->headers;
146  while ((h = get_msgheader_next(h, "Subject")) != NULL) {
147  if (h->value == NULL)
148  continue;
149 
150  for (cmd = SYMPA_CMDS; (*cmd != NULL); cmd++) {
151  ZE_MessageInfo(12, "Checking Subject %s %s", h->value, *cmd);
152  if (zeStrRegex(h->value, *cmd, NULL, NULL, TRUE))
153  goto ok;
154  }
155  }
156  }
157 
158  /*
159  * autres ???
160  */
161 #if 0
162  if (0) {
163  char *p, *q;
164  int i;
165 
166  while (p != NULL && *p != '\0') {
167  if ((p = strpbrk(p, " \t\n")) != NULL) {
168  i++;
169  p++;
170  continue;
171  }
172  }
173  }
174 #endif
175 
176  ZE_MessageInfo(12, "%s : This is a short message...",
177  CONNID_STR(priv->id), strlen(buf));
178  priv->msg_short = TRUE;
179  }
180 
181 ok:
182 
183  priv->body_nb++;
184  /*
185  **
186  */
187  ZE_MessageInfo(12, "%s : Check X-files : %s",
188  CONNID_STR(priv->id),
189  ((cf_get_int(CF_XFILES) != OPT_OK) ? "YES" : "NO"));
190  extract_attachments = (cf_get_int(CF_XFILES) != OPT_OK) ||
193  if (extract_attachments) {
194  if ((bodyp != NULL) && (bodylen > 0)) {
195  if (priv->body_res_scan == 0) {
196  priv->body_res_scan = scan_block(CONNID_STR(priv->id),
197  priv->body_chunk,
198  SZ_CHUNK,
199  (char *) bodyp,
200  bodylen,
201  &priv->body_scan_state,
202  &priv->tcontent, &priv->lcontent);
203  ZE_MessageInfo(12, "%s : Check X-files : %s",
204  CONNID_STR(priv->id),
205  cf_get_int(CF_XFILES) != OPT_OK ? "YES" : "NO");
206  if (priv->body_res_scan != 0) {
207  ZE_MessageWarning(11, "%-12s - scan_chunk res = %d",
208  CONNID_STR(priv->id), priv->body_res_scan);
209  result = SMFIS_REJECT;
210  (void) jsmfi_setreply(ctx, "554", "5.7.1", "Binary message");
212  goto fin;
213  }
214  }
215  }
216  }
217 
218 fin:
220  MUTEX_LOCK(&st_mutex);
221  zeKStatsUpdate(&st_time, (double) (tfms - tims));
222  MUTEX_UNLOCK(&st_mutex);
223  /*
224  * continue processing
225  */
226  return result;
227 }
#define SZ_CHUNK
Definition: ze-filter.h:98
bool spool_file_create(CTXPRIV_T *)
Definition: ze-spool.c:50
#define CF_LOG_ATTACHMENTS
Definition: cfh-defs.h:59
void stats_inc(int, long)
Definition: ze-stats.c:401
#define CF_REJECT_SHORT_BODIES
Definition: cfh-defs.h:178
#define SMFIS_TEMPFAIL
int scan_block(char *, char *, long, char *, long, int *, content_field_T *, content_field_T **)
Definition: ze-scanmail.c:51
int jsmfi_setreply(SMFICTX *, char *, char *, char *)
Definition: ze-libmilter.c:99
#define MUTEX_UNLOCK(mutex)
Definition: macros.h:101
bool ok
Definition: ze-connopen.c:59
#define MUTEX_LOCK(mutex)
Definition: macros.h:93
#define CF_XFILES
Definition: cfh-defs.h:92
#define FALSE
Definition: macros.h:160
#define MSG_BINARY_MESSAGE
Definition: ze-reply.h:85
#define SMFIS_CONTINUE
#define SMFIS_REJECT
bool zeStrRegex(char *, char *, long *, long *, bool)
Definition: zeStrings.c:544
#define OPT_YES
Definition: ze-cf.h:45
size_t buf_clean_rc(char *, size_t)
Definition: ze-buffer.c:75
sfsistat mlfi_body(SMFICTX *ctx, unsigned char *bodyp, size_t bodylen)
Definition: mlfi_body.c:31
int cf_get_int(int id)
Definition: ze-cf.c:803
#define MLFIPRIV(ctx)
#define INIT_CALLBACK(p, which)
Definition: ze-filter.c:125
#define OPT_OK
Definition: ze-cf.h:47
void sm_macro_update(SMFICTX *, sm_mac_T *)
Definition: ze-smmacros.c:150
#define CF_SCANNER_ACTION
Definition: cfh-defs.h:97
CONNID_T id
bool spool_file_forget(CTXPRIV_T *)
Definition: ze-spool.c:245
unsigned long msg_size
content_field_T tcontent
#define INIT_CALLBACK_DELAY()
Definition: ze-filter.c:135
void zeKStatsUpdate(kstats_T *, double)
Definition: zeKStats.c:101
char * value
Definition: ze-headers.h:36
int extract_attachments(content_field_T *, attachment_T **)
Definition: ze-mimelist.c:330
#define IS_UNKNOWN(class)
Definition: ze-netclass.h:51
bool spool_file_write(CTXPRIV_T *, char *, size_t)
Definition: ze-spool.c:201
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
#define CALLBACK_BODY
Definition: ze-callback.h:35
#define TRUE
Definition: macros.h:157
#define ZE_MessageWarning(level,...)
Definition: zeSyslog.h:92
unsigned long nb_bytes
#define STAT_BYTES
Definition: ze-stats.h:27
#define memcpy(d, s, n)
Definition: ze-sys.h:224
#define KSTATS_INITIALIZER
Definition: zeKStats.h:36
#define ZE_MessageError(level,...)
Definition: zeSyslog.h:93
content_field_T * lcontent
char body_chunk[SZ_CHUNK]
header_T * headers
bool spool_file_is_open(CTXPRIV_T *)
Definition: ze-spool.c:291
#define ZE_LogMsgWarning(level,...)
Definition: zeSyslog.h:112
sm_mac_T * sm
int body_scan_state
#define CF_MIN_BODY_LENGTH
Definition: cfh-defs.h:179
#define CONNID_STR(connid)
Definition: ze-filter.h:113
#define CHECK_CALLBACK_DELAY()
Definition: ze-filter.c:146
netclass_T netclass
void log_msg_context(SMFICTX *ctx, char *why)
header_T * get_msgheader_next(header_T *, char *)
Definition: ze-headers.c:175