ze-filter  (ze-filter-0.8.0-develop-180218)
ze-netclass.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 #include <ze-sys.h>
26 
27 #include "ze-filter.h"
28 
29 /* ***************************************************************************
30  * *
31  * *
32  *****************************************************************************/
33 int DecodeNetClass(char *, char *, size_t);
34 
35 static int EnvDefinedNetClassEquiv(char *);
36 
37 
38 /* ***************************************************************************
39  * *
40  * *
41  *****************************************************************************/
42 #define SET_LABEL(s, sz, label) \
43  do { \
44  if ((s) != NULL && (sz) > 0) \
45  strlcpy((s), (label), (sz)); \
46  } while (0)
47 
48 int
49 GetClientNetClass(ip, name, class, label, sz)
50  char *ip;
51  char *name;
52  netclass_T *class;
53  char *label;
54  size_t sz;
55 {
56  int ret = NET_UNKNOWN;
57  char bClass[256];
58  char bEquiv[256];
59  bool found = FALSE;
60 
61  SET_LABEL(label, sz, "UNKNOWN");
62 
63  if (ip == NULL)
64  return NET_UNKNOWN;
65 
66  if (STREQUAL(ip, "127.0.0.1")) {
67  SET_LABEL(label, sz, "LOCAL");
68  return NET_LOCAL;
69  }
70 
71  if (STRNCASEEQUAL(ip, "ipv6:", strlen("ipv6:")))
72  ip += strlen("ipv6:");
73 
74 #if 0
75  if (STREQUAL(ip, "::1")) {
76  SET_LABEL(label, sz, "OTHER");
77  return NET_OTHER;
78  }
79 #endif
80 
81  memset(bClass, 0, sizeof (bClass));
82  found = db_policy_check("NetClass", ip, bClass, sizeof (bClass));
83  if (!found && name != NULL)
84  found = db_policy_check("NetClass", name, bClass, sizeof (bClass));
85  if (!found)
86  return NET_UNKNOWN;
87 
88  /*
89  * ret = NET_OTHER;
90  */
91 
92  SET_LABEL(label, sz, bClass);
93 
94  ZE_MessageInfo(12, " NetClass : %s %s %s", ip, STRNULL(name, "-"),
95  bClass);
96 
97  ret = DecodeNetClass(bClass, NULL, 0);
98  if (ret != NET_UNKNOWN)
99  return ret;
100 
101  ret = EnvDefinedNetClassEquiv(bClass);
102  if (ret != NET_UNKNOWN)
103  return ret;
104 
105  memset(bEquiv, 0, sizeof (bEquiv));
106  found = db_policy_check("NetClassEquiv", bClass, bEquiv, sizeof (bEquiv));
107  if (!found)
108  return NET_UNKNOWN;
109 
110  ret = DecodeNetClass(bEquiv, NULL, 0);
111  ZE_MessageInfo(12, " NetClassEquiv : %s %s 0x%04x %s %s", ip,
112  STRNULL(name, "-"), ret, bClass, bEquiv);
113  if (ret != NET_UNKNOWN)
114  return ret;
115 
116  return ret;
117 }
118 
119 /* ***************************************************************************
120  * *
121  * *
122  *****************************************************************************/
123 int
124 DecodeNetClass(class, label, sz)
125  char *class;
126  char *label;
127  size_t sz;
128 {
129  int code = NET_UNKNOWN;
130  int argc;
131  char *argv[32];
132  int i;
133 
134  char *tclass = NULL;
135 
136  assert(class != NULL);
137 
138  if (strlen(class) == 0)
139  return NET_UNKNOWN;
140 
141  tclass = strdup(class);
142  if (tclass == NULL) {
143  ZE_LogSysError("Can't strdup(class = %s) error", class);
144  return NET_UNKNOWN;
145  }
146 
147  argc = zeStr2Tokens(class, 32, argv, "+, ");
148  for (i = 0; i < argc && code == NET_UNKNOWN; i++) {
149  if ((i == 0) && (label != NULL))
150  SET_LABEL(label, sz, argv[i]);
151 
152  if (strcasecmp(argv[i], "LOCAL") == 0)
153  code = NET_LOCAL;
154 
155  if (strcasecmp(argv[i], "DOMAIN") == 0)
156  code = NET_DOMAIN;
157 
158  if (strcasecmp(argv[i], "FRIEND") == 0)
159  code = NET_FRIEND;
160 
161  if (strcasecmp(argv[i], "OTHER") == 0)
162  code = NET_OTHER;
163 
164  if (strcasecmp(argv[i], "UNKNOWN") == 0)
165  code = NET_UNKNOWN;
166  }
167  FREE(tclass);
168 
169  return code;
170 }
171 
172 /* ***************************************************************************
173  * *
174  * *
175  *****************************************************************************/
176 typedef struct {
177  bool ok;
178  int netcode;
179  char *buf;
180  int nb;
181  char *classes[32];
182 } EnvClass_T;
183 
184 #define KCLASS_INIT {FALSE, NET_UNKNOWN, NULL, 0}
185 
186 #define FILL_KCLASS(kC, eStr, code) \
187  do { \
188  if (!(kC)->ok) { \
189  char *env = getenv(eStr); \
190  if (env != NULL) { \
191  (kC)->buf = strdup(env); \
192  if ((kC)->buf != NULL) { \
193  (kC)->nb = zeStr2Tokens((kC)->buf, 32, (kC)->classes, ",+ "); \
194  (kC)->netcode = (code); \
195  (kC)->ok = TRUE; \
196  } else { \
197  } \
198  } \
199  } \
200  } while (0)
201 
202 #define CHECK_KCLASS(kC, class, code) \
203  do { \
204  if ((kC)->ok) { \
205  int i; \
206  for (i = 0; i < (kC)->nb; i++) { \
207  if (strcasecmp(class, (kC)->classes[i]) == 0) \
208  code = (kC)->netcode; \
209  } \
210  } \
211  } while (0)
212 
213 
214 static int
215 EnvDefinedNetClassEquiv(class)
216  char *class;
217 {
218  int result = NET_UNKNOWN;
219 
220  static EnvClass_T kLocal = KCLASS_INIT;
221  static EnvClass_T kDomain = KCLASS_INIT;
222  static EnvClass_T kFriend = KCLASS_INIT;
223  static EnvClass_T kOther = KCLASS_INIT;
224 
225  int i;
226 
227  if (class == NULL || strlen(class) == 0)
228  return NET_UNKNOWN;
229 
230  FILL_KCLASS(&kLocal, "NETCLASS_LOCAL", NET_LOCAL);
231  FILL_KCLASS(&kDomain, "NETCLASS_DOMAIN", NET_DOMAIN);
232  FILL_KCLASS(&kFriend, "NETCLASS_FRIEND", NET_FRIEND);
233  FILL_KCLASS(&kOther, "NETCLASS_OTHER", NET_OTHER);
234 
235  CHECK_KCLASS(&kLocal, class, result);
236  if (result != NET_UNKNOWN)
237  return result;
238  CHECK_KCLASS(&kDomain, class, result);
239  if (result != NET_UNKNOWN)
240  return result;
241  CHECK_KCLASS(&kFriend, class, result);
242  if (result != NET_UNKNOWN)
243  return result;
244  CHECK_KCLASS(&kOther, class, result);
245  if (result != NET_UNKNOWN)
246  return result;
247 
248  return NET_UNKNOWN;
249 }
#define NET_DOMAIN
Definition: ze-netclass.h:34
#define FREE(x)
Definition: macros.h:37
#define STRNULL(x, r)
Definition: macros.h:81
#define STRNCASEEQUAL(a, b, n)
Definition: macros.h:75
#define NET_UNKNOWN
Definition: ze-netclass.h:31
int GetClientNetClass(char *ip, char *name, netclass_T *class, char *label, size_t sz)
Definition: ze-netclass.c:49
#define FALSE
Definition: macros.h:160
#define STREQUAL(a, b)
Definition: macros.h:78
#define NET_FRIEND
Definition: ze-netclass.h:35
int zeStr2Tokens(char *, int, char **, char *)
Definition: zeStrings.c:610
#define KCLASS_INIT
Definition: ze-netclass.c:184
bool db_policy_check(char *prefix, char *key, char *bufout, size_t szbuf)
Definition: ze-dbpolicy.c:141
#define NET_OTHER
Definition: ze-netclass.h:37
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
#define NET_LOCAL
Definition: ze-netclass.h:33
char * buf
Definition: ze-netclass.c:179
#define CHECK_KCLASS(kC, class, code)
Definition: ze-netclass.c:202
#define ZE_LogSysError(...)
Definition: zeSyslog.h:129
#define SET_LABEL(s, sz, label)
Definition: ze-netclass.c:42
#define FILL_KCLASS(kC, eStr, code)
Definition: ze-netclass.c:186
int DecodeNetClass(char *, char *, size_t)
Definition: ze-netclass.c:124