ze-filter  (ze-filter-0.8.0-develop-180218)
mlfi_envfrom.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 
31 sfsistat
32 mlfi_envfrom(ctx, envfrom)
33  SMFICTX *ctx;
34  char **envfrom;
35 {
36  CTXPRIV_T *priv = MLFIPRIV(ctx);
37  int result = SMFIS_CONTINUE;
38  char *sm_msgid = NULL;
39 
41 
42  if (priv == NULL)
43  return SMFIS_TEMPFAIL;
44 
46 
47  sm_macro_update(ctx, priv->sm);
48 
49  if (envfrom == NULL) {
50  ZE_MessageError(9, "%s : envfrom = NULL", CONNID_STR(priv->id));
51  result = SMFIS_TEMPFAIL;
52  goto fin;
53  }
54 
55  sm_msgid = sm_macro_get_str(priv->sm, "i");
56  if (sm_msgid != NULL) {
57  FREE(priv->sm_msgid);
58  if ((priv->sm_msgid = strdup(sm_msgid)) == NULL)
59  ZE_LogSysError("strdup(sm_msgid) error ");
60  ZE_MessageInfo(19, "msgid : %s", sm_msgid);
61  }
62 
63  priv->nb_from++;
64  priv->nb_mbadrcpt = 0;
65  FREE(priv->env_from);
66 
67  if (result == SMFIS_CONTINUE) {
68  char *auth_type = NULL;
69  char *auth_authen = NULL;
70 
72  auth_type = sm_macro_get_str(priv->sm, "{auth_type}");
73  auth_authen = sm_macro_get_str(priv->sm, "{auth_authen}");
74  if ((auth_type != NULL) && (strlen(auth_type) > 0) ||
75  (auth_authen != NULL) && (strlen(auth_authen) > 0)) {
76  /*
77  * XXX JOE
78  */
80  priv->netclass.class = NET_AUTH;
82  sizeof (priv->netclass.label));
83 
84  ZE_MessageInfo(10, "%-12s : IP=(%s), AUTH=(%s), LOGIN=(%s), FROM=(%s)",
85  CONNID_STR(priv->id),
86  STRNULL(priv->peer_addr, "0.0.0.0"),
87  STREMPTY(auth_type, "???"),
88  STREMPTY(auth_authen, "???"), STRNULL(envfrom[0], "NULL"));
89  }
90  }
91 
92  if ((envfrom[0] == NULL) || (strlen(envfrom[0]) == 0)) {
93  ZE_LogMsgWarning(0, "%-12s : envfrom[0] : %s",
94  CONNID_STR(priv->id), STRNULL(envfrom[0], "NULL"));
95  result = SMFIS_TEMPFAIL;
96  goto fin;
97  }
98 
99  if ((priv->env_from = strdup(envfrom[0])) == NULL) {
100  ZE_LogSysError("%-12s : strdup env_from", CONNID_STR(priv->id));
101  result = SMFIS_TEMPFAIL;
102  goto fin;
103  }
104 
105  /*
106  * check msg rate
107  */
108  result = check_msgrate(ctx);
109  if (result != SMFIS_CONTINUE)
110  goto fin;
111 
112  /*
113  * check msg rate
114  */
115  result = check_msgcount(ctx);
116  if (result != SMFIS_CONTINUE)
117  goto fin;
118 
119  /*
120  * Is SMTP client using STARTTLS ?
121  */
122  if (IS_UNKNOWN(priv->netclass.class)) {
123  /*
124  * XXX CERT
125  */
126  }
127 
128  if (IS_UNKNOWN(priv->netclass.class))
129  result = validate_connection(ctx);
130 
131  if (result != SMFIS_CONTINUE)
132  goto fin;
133 
134 #if _FFR_MODULES
135  /*
136  ** ze-filter modules
137  **
138  */
139  if (do_module_callback(ctx, 0, &result))
140  goto fin;
141  if (result != SMFIS_CONTINUE)
142  goto fin;
143 #endif /* _FFR_MODULES */
144 
145  /*
146  * Check EHLO content
147  */
148  if (IS_UNKNOWN(priv->netclass.class)) {
149  uint32_t ehlo_flags;
150 
151  ehlo_flags = priv->ehlo_flags;
152  if (ehlo_flags != 0) {
153  ZE_MessageNotice(11, "%-12s BAD HELO : Flags=0x%08X",
154  CONNID_STR(priv->id), ehlo_flags);
155  }
156 
157  if (ehlo_flags != 0 && cf_get_int(CF_REJECT_BADEHLO) != OPT_OK) {
158  (void) jsmfi_setreply(ctx, "550", "5.7.1", MSG_BADHELO);
159  result = SMFIS_REJECT;
160 
162 
163  goto fin;
164  }
165  }
166 
167  /*
168  * update bounce rate
169  */
170  if (strstr(priv->env_from, "<>") != NULL) {
172  priv->peer_name, 1, time(NULL));
173 
174  ZE_MessageInfo(11, "%-12s Bounce from %s", CONNID_STR(priv->id),
175  priv->peer_addr);
176  }
177 #if _FFR_MODULES
178  /*
179  ** ze-filter modules
180  **
181  */
182  if (do_module_callback(ctx, 0, &result))
183  goto fin;
184  if (result != SMFIS_CONTINUE)
185  goto fin;
186 #endif /* _FFR_MODULES */
187 
188  /*
189  * XXX JOE ???
190  */
191  /*
192  * check MAIL command syntax
193  */
194  {
195  char fbuf[256];
196  char *user, *domain;
197 
198  if (!zeStrRegex(priv->env_from, "<.*>", NULL, NULL, TRUE)) {
199  ZE_MessageInfo(9, "%-12s : ENV FROM Syntax Error : %s",
200  CONNID_STR(priv->id), priv->env_from);
201 
202  /*
203  * JOE XXX Reject ***/
204  if (IS_UNKNOWN(priv->netclass.class)) {
205 
206  }
207  }
208 
209  memset(fbuf, 0, sizeof (fbuf));
210  (void) extract_email_address(fbuf, priv->env_from, sizeof (fbuf));
211  user = fbuf;
212  domain = strrchr(fbuf, '@');
213  if (domain != NULL)
214  *domain++ = '\0';
215 
216  if (domain == NULL
217  || zeStrRegex(domain, "^[a-z][-a-z.]+[.][-a-z.]+$", NULL, NULL, TRUE)) {
218 
219  }
220  }
221 
222  /*
223  * Check BAD Sender MX
224  */
226  char *mail_host = NULL;
227  char buf[256];
228 
229  memset(buf, 0, sizeof (buf));
230 
231  if (!zeStrRegex(priv->env_from, "<>", NULL, NULL, FALSE)) {
232  extract_host_from_email_address(buf, priv->env_from, sizeof (buf));
233  mail_host = strchr(buf, '@');
234  if (mail_host != NULL)
235  mail_host++;
236  else
237  mail_host = buf;
238  }
239 
240  ZE_MessageInfo(12, "%-12s : mail_host = %s", CONNID_STR(priv->id),
241  STRNULL(mail_host, "NULL SENDER"));
242 
243  if (mail_host != NULL && strlen(mail_host) > 0) {
244  if (zeStrRegex(mail_host, "[^a-zA-Z0-9.-]", NULL, NULL, TRUE)) {
245  if (IS_UNKNOWN(priv->netclass.class))
246  ZE_MessageInfo(11, "%-12s : Bad mail_host = %s", CONNID_STR(priv->id),
247  mail_host);
248  } else {
249  result = check_sender_mx(ctx, mail_host);
250  if (result != SMFIS_CONTINUE) {
251  (void) livehistory_add_entry(priv->peer_addr, time(NULL), 1,
252  LH_BADMX);
253  goto fin;
254  }
255  }
256  }
257  }
258 
259  /*
260  * Check content to MAIL FROM parameter
261  */
262  if (cf_get_int(CF_SPAM_REGEX) == OPT_YES) {
263  ZE_LogMsgDebug(15, "check_from_content");
264  if (shall_check_content(ctx)) {
265  int score_min = cf_get_int(CF_REGEX_MAX_SCORE);
266  int score = 0;
267 
268  score = check_regex(CONNID_STR(priv->id), priv->peer_addr,
269  priv->env_from, MAIL_FROM);
270  priv->rawScores.headers += score;
271  if (score >= score_min) {
272  result = SMFIS_REJECT;
273 
275  (void) jsmfi_setreply(ctx, "550", "5.7.1", MSG_FROM_CONTENTS);
277 
278  goto fin;
279  }
280  }
281  }
282 
283  /*
284  * end...
285  */
286 fin:
288 
289  /*
290  * continue processing
291  */
292  return result;
293 }
int check_regex(char *, char *, char *, int)
Definition: ze-mailregex.c:295
int smtprate_add_entry(int, char *, char *, int, time_t)
Definition: ze-smtprate.c:363
msg_scores_T rawScores
void stats_inc(int, long)
Definition: ze-stats.c:401
#define SMFIS_TEMPFAIL
#define strrchr
Definition: ze-sys.h:219
sfsistat mlfi_envfrom(SMFICTX *ctx, char **envfrom)
Definition: mlfi_envfrom.c:32
int jsmfi_setreply(SMFICTX *, char *, char *, char *)
Definition: ze-libmilter.c:99
#define FREE(x)
Definition: macros.h:37
char * peer_addr
#define STRNULL(x, r)
Definition: macros.h:81
#define LH_BADMX
#define FALSE
Definition: macros.h:160
#define SMFIS_CONTINUE
#define SMFIS_REJECT
#define strlcpy
Definition: zeString.h:32
bool zeStrRegex(char *, char *, long *, long *, bool)
Definition: zeStrings.c:544
char * extract_email_address(char *, char *, size_t)
#define OPT_YES
Definition: ze-cf.h:45
bool shall_check_content(SMFICTX *)
#define CF_CHECK_BAD_SENDER_MX
Definition: cfh-defs.h:174
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 strchr
Definition: ze-sys.h:218
#define OPT_OK
Definition: ze-cf.h:47
void sm_macro_update(SMFICTX *, sm_mac_T *)
Definition: ze-smmacros.c:150
CONNID_T id
sfsistat check_msgrate(SMFICTX *)
#define ZE_MessageNotice(level,...)
Definition: zeSyslog.h:91
#define INIT_CALLBACK_DELAY()
Definition: ze-filter.c:135
#define ZE_LogMsgDebug(level,...)
Definition: zeSyslog.h:109
#define CF_REJECT_BADEHLO
Definition: cfh-defs.h:171
#define IS_UNKNOWN(class)
Definition: ze-netclass.h:51
#define CALLBACK_MAIL
Definition: ze-callback.h:30
#define MSG_FROM_CONTENTS
Definition: ze-reply.h:149
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
#define OPT_NO
Definition: ze-cf.h:44
char * extract_host_from_email_address(char *, char *, size_t)
#define TRUE
Definition: macros.h:157
#define RATE_BOUNCE
Definition: ze-smtprate.h:53
#define NET_AUTH
Definition: ze-netclass.h:36
sfsistat check_msgcount(SMFICTX *)
#define ZE_LogSysError(...)
Definition: zeSyslog.h:129
#define ZE_MessageError(level,...)
Definition: zeSyslog.h:93
#define CLR_NET_CLASS(class, which)
Definition: ze-netclass.h:55
sfsistat validate_connection(SMFICTX *)
#define STREMPTY(x, r)
Definition: macros.h:82
char * peer_name
#define ZE_LogMsgWarning(level,...)
Definition: zeSyslog.h:112
char * env_from
bool do_module_callback(SMFICTX *ctx, int step, int *result)
Definition: ze-mod-tools.c:84
uint32_t ehlo_flags
#define MSG_HELO_CONTENTS
Definition: ze-reply.h:165
sm_mac_T * sm
#define CF_REGEX_MAX_SCORE
Definition: cfh-defs.h:118
#define STAT_FROM_CONTENTS
Definition: ze-stats.h:54
#define CONNID_STR(connid)
Definition: ze-filter.h:113
#define CHECK_CALLBACK_DELAY()
Definition: ze-filter.c:146
#define MAIL_FROM
Definition: ze-mailregex.h:41
int check_sender_mx(SMFICTX *, char *)
Definition: ze-mxcheck.c:72
#define CF_SPAM_REGEX
Definition: cfh-defs.h:116
netclass_T netclass
int livehistory_add_entry(char *, time_t, int, int)
#define MSG_BADHELO
Definition: ze-reply.h:195
char label[32]
Definition: ze-netclass.h:72
char * sm_macro_get_str(sm_mac_T *, char *)
Definition: ze-smmacros.c:191
#define NET_CLASS_LABEL(class)
Definition: ze-netclass.h:57
void log_msg_context(SMFICTX *ctx, char *why)
#define SET_NET_CLASS(class, which)
Definition: ze-netclass.h:53
long uint32_t
Definition: ze-sys.h:489
char domain[]
char * sm_msgid