ze-filter  (ze-filter-0.8.0-develop-180218)
ze-decode.c
Go to the documentation of this file.
1 /*
2  *
3  * ze-filter - Mail Server Filter for sendmail
4  *
5  * Copyright (c) 2001-2018 - Jose-Marcio Martins da Cruz
6  *
7  * Auteur : Jose Marcio Martins da Cruz
8  * jose.marcio.mc@gmail.org
9  *
10  * Historique :
11  * Creation : janvier 2002
12  *
13  * This program is free software, but with restricted license :
14  *
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
19  *
20  * More details about ze-filter license can be found at ze-filter
21  * web site : http://foss.jose-marcio.org
22  */
23 
24 #include <ze-sys.h>
25 #include "ze-libjc.h"
26 #include "ze-decode.h"
27 
28 static int htoi(int);
29 static char *def_ext_attr_chars();
30 static char *def_attr_chars();
31 
32 
33 /* ****************************************************************************
34  * *
35  * *
36  **************************************************************************** */
37 bool
39  char *s;
40 {
41  return is_rfc1521_encoded(s);
42 }
43 
44 /* ****************************************************************************
45  * *
46  * *
47  **************************************************************************** */
48 int
49 decode_rfc2047(out, in, sz)
50  char *out;
51  char *in;
52  size_t sz;
53 {
54  return decode_rfc1521(out, in, sz);
55 }
56 
57 /* ****************************************************************************
58  * *
59  * *
60  **************************************************************************** */
61 bool
63  char *s;
64 {
65  char *expr = "=[?].*[?][qQbB][?].*[?]=";
66 
67  return zeStrRegex(s, expr, NULL, NULL, TRUE);
68 }
69 
70 /* ****************************************************************************
71  * *
72  * *
73  **************************************************************************** */
74 int
75 decode_rfc1521(out, in, sz)
76  char *out;
77  char *in;
78  size_t sz;
79 {
80  char *q = out, *p = in;
81  char *expr = "=[?].*[?][qQbB][?].*[?]=";
82  long pi, pf;
83 
84  if (out == NULL)
85  return 0;
86  if (in == NULL)
87  {
88  strlcpy(out, "", sz);
89  return 0;
90  }
91  if (!is_rfc1521_encoded(in))
92  {
93  strlcpy(out, in, sz);
94  return strlen(out);
95  }
96 
97  p = in;
98  if (zeStrRegex(p, expr, &pi, &pf, TRUE))
99  {
100  if (pi < sz)
101  {
102  strncpy(q, p, pi);
103  q[pi] = '\0';
104  p += pi;
105  q += pi;
106  sz -= pi;
107  } else
108  sz = 0;
109  }
110 
111  for (; (sz > 0) && zeStrRegex(p, expr, &pi, &pf, TRUE); p += pf)
112  {
113  long ki, kf;
114  char strin[1024], strout[1024];
115 
116  if (pi != 0)
117  {
118  ZE_LogMsgWarning(0, "error zeStrRegex...");
119  sz = 0;
120  continue;
121  }
122 
123  if (zeStrRegex(p, "=[?].*[?][qQ][?]", &ki, &kf, TRUE))
124  {
125  int nb = pf - kf - 2;
126 
127  if (nb < 0)
128  continue;
129  memset(strin, 0, sizeof (strin));
130  if (nb >= (sizeof (strin) - 1))
131  {
132  sz = 0;
133  break;
134  } else
135  strncpy(strin, p + kf, nb);
136  (void) qp_decode(strout, strin, sizeof (strout));
137  strlcpy(q, strout, sz);
138  sz -= strlen(q);
139  q += strlen(q);
140  continue;
141  }
142  if (zeStrRegex(p, "=[?].*[?][bB][?]", &ki, &kf, TRUE))
143  {
144  int nb = pf - kf - 2;
145  size_t no;
146 
147  if (nb < 0)
148  continue;
149  memset(strin, 0, sizeof (strin));
150  if (nb >= (sizeof (strin) - 1))
151  {
152  sz = 0;
153  break;
154  } else
155  strncpy(strin, p + kf, nb);
156 
157  no = sizeof (strout);
158  (void) base64_decode(strout, strin, &no, NULL);
159  strlcpy(q, strout, sz);
160  sz -= strlen(q);
161  q += strlen(q);
162  continue;
163  }
164  }
165  strlcpy(q, p, sz);
166 
167  return strlen(out);
168 }
169 
170 /* ****************************************************************************
171  * *
172  * *
173  **************************************************************************** */
174 bool
176  char *s;
177 {
178  bool res = FALSE;
179 
180  char *attr_chars = def_attr_chars();
181  char *ext_attr_chars = def_ext_attr_chars();
182  char rexp[256];
183 
184  if (attr_chars != NULL && ext_attr_chars != NULL)
185  {
186  snprintf(rexp, sizeof (rexp), "[%s]*'.*'[%s]*", attr_chars, ext_attr_chars);
187 
188  ZE_MessageInfo(19, "RFC2231 regex : %s", rexp);
189 
190  res = zeStrRegex(s, rexp, NULL, NULL, TRUE);
191  }
192  return res;
193 }
194 
195 /* ****************************************************************************
196  * *
197  * *
198  **************************************************************************** */
199 int
200 decode_rfc2231(out, in, sz)
201  char *out;
202  char *in;
203  size_t sz;
204 {
205  char *q = out, *p = in, *pi = in;
206 
207  if (!is_rfc2231_encoded(in))
208  {
209  strlcpy(out, in, sz);
210  return 0;
211  }
212 
213  memset(q, 0, strlen(pi));
214  if ((p = strchr(pi, '\'')) == NULL)
215  return 0;
216  pi = ++p;
217  if ((p = strchr(pi, '\'')) == NULL)
218  return 0;
219 
220  p++;
221  while (*p != '\0')
222  {
223  switch (*p)
224  {
225  case '%':
226  if ((strlen(p) >= 2) && isxdigit((int) p[1]) && isxdigit((int) p[2]))
227  {
228  int x = 16 * htoi(p[1]) + htoi(p[2]);
229 
230  if (x > 127)
231  x = '_';
232  *q++ = x;
233  p += 3;
234  } else
235  p++;
236  break;
237  default:
238  *q++ = *p++;
239  }
240  }
241  *q = '\0';
242  return 1;
243 }
244 
245 /* ****************************************************************************
246  * *
247  * *
248  **************************************************************************** */
249 
250 static char *
251 def_attr_chars()
252 {
253  static char *chars = NULL;
254  static char *p;
255 
256  if (chars == NULL)
257  {
258  int c;
259 
260  if ((chars = malloc(256)) == NULL)
261  return "ERROR";
262  memset(chars, 0, 256);
263  for (p = chars, c = 0x20; c < 0x7F; c++)
264  {
265  if (strchr(" *'%", c) == NULL && strchr(TSPECIALS, c) == NULL)
266  *p++ = c;
267  }
268  *p = '\0';
269  }
270 
271  return chars;
272 }
273 
274 /* ****************************************************************************
275  * *
276  * *
277  **************************************************************************** */
278 
279 static char *
280 def_ext_attr_chars()
281 {
282  static char *chars = NULL;
283  static char *p;
284 
285  if (chars == NULL)
286  {
287  int c;
288 
289  if ((chars = malloc(256)) == NULL)
290  return "ERROR";
291  memset(chars, 0, 256);
292  for (p = chars, c = 0x20; c < 0x7F; c++)
293  {
294  if (strchr(" *'", c) == NULL && strchr(TSPECIALS, c) == NULL)
295  *p++ = c;
296  }
297  *p = '\0';
298  }
299 
300  return chars;
301 }
302 
303 /* ****************************************************************************
304  * *
305  * *
306  **************************************************************************** */
307 
308 static int
309 htoi(c)
310  int c;
311 {
312  char *HCHARS = "0123456789ABCDEF";
313  char *p;
314 
315  if ((p = strchr(HCHARS, toupper(c))) != NULL)
316  return (int) (p - HCHARS);
317  return 0;
318 }
319 
320 
321 /* ****************************************************************************
322  * *
323  * *
324  **************************************************************************** */
325 #define ISCHARINSTR(s,c) (((s) == NULL) || (strchr((s),(c)) == NULL))
326 int
327 strascii(s, exa, exb)
328  char *s;
329  char *exa;
330  char *exb;
331 {
332  int i;
333  char c;
334  char ascii[128];
335 
336  if (s == NULL || strlen(s) == 0)
337  return 0;
338 
339  memset(ascii, 0, sizeof (ascii));
340  for (i = 0, c = 0x20; c < 0x7F; c++)
341  {
342 #if 0
343  if ((exa == NULL || strchr(exa, c) == NULL) &&
344  (exb == NULL || strchr(exb, c) == NULL))
345 #else
346  if (ISCHARINSTR(exa, c) && ISCHARINSTR(exb, c))
347 #endif
348  ascii[i++] = c;
349  }
350  return strspn(s, ascii);
351 }
int decode_rfc2231(char *out, char *in, size_t sz)
Definition: ze-decode.c:200
#define ISCHARINSTR(s, c)
Definition: ze-decode.c:325
int qp_decode(char *, char *, size_t)
Definition: ze-qp.c:33
#define FALSE
Definition: macros.h:160
#define strlcpy
Definition: zeString.h:32
bool zeStrRegex(char *, char *, long *, long *, bool)
Definition: zeStrings.c:544
#define strchr
Definition: ze-sys.h:218
bool is_rfc2047_encoded(char *s)
Definition: ze-decode.c:38
#define TSPECIALS
Definition: ze-decode.h:42
#define ZE_MessageInfo(level,...)
Definition: zeSyslog.h:90
int nb
Definition: ze-connopen.c:61
int decode_rfc2047(char *out, char *in, size_t sz)
Definition: ze-decode.c:49
#define TRUE
Definition: macros.h:157
#define ZE_LogMsgWarning(level,...)
Definition: zeSyslog.h:112
int base64_decode(char *, char *, size_t *, size_t *)
Definition: ze-base64.c:94
int decode_rfc1521(char *out, char *in, size_t sz)
Definition: ze-decode.c:75
bool is_rfc2231_encoded(char *s)
Definition: ze-decode.c:175
bool is_rfc1521_encoded(char *s)
Definition: ze-decode.c:62
int strascii(char *s, char *exa, char *exb)
Definition: ze-decode.c:327