suricata
util-magic.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2013 Open Information Security Foundation
2  *
3  * You can copy, redistribute or modify this Program under the terms of
4  * the GNU General Public License version 2 as published by the Free
5  * Software Foundation.
6  *
7  * This program is distributed in the hope that it will be useful,
8  * but WITHOUT ANY WARRANTY; without even the implied warranty of
9  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10  * GNU General Public License for more details.
11  *
12  * You should have received a copy of the GNU General Public License
13  * version 2 along with this program; if not, write to the Free Software
14  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
15  * 02110-1301, USA.
16  */
17 
18 /**
19  * \file
20  *
21  * \author Victor Julien <victor@inliniac.net>
22  *
23  * Wrappers and tests for libmagic usage.
24  *
25  * Libmagic's API is not thread safe. The data the pointer returned by
26  * magic_buffer is overwritten by the next magic_buffer call. This is
27  * why we need to lock calls and copy the returned string.
28  */
29 
30 #include "suricata-common.h"
31 
32 #include "conf.h"
33 
34 #include "util-unittest.h"
35 #include "util-magic.h"
36 
37 #ifdef HAVE_MAGIC
38 static magic_t g_magic_ctx = NULL;
39 static SCMutex g_magic_lock;
40 
41 /**
42  * \brief Initialize the "magic" context.
43  */
44 int MagicInit(void)
45 {
46  BUG_ON(g_magic_ctx != NULL);
47 
48  SCEnter();
49 
50  const char *filename = NULL;
51  FILE *fd = NULL;
52 
53  SCMutexInit(&g_magic_lock, NULL);
54  SCMutexLock(&g_magic_lock);
55 
56  g_magic_ctx = magic_open(0);
57  if (g_magic_ctx == NULL) {
58  SCLogError(SC_ERR_MAGIC_OPEN, "magic_open failed: %s",
59  magic_error(g_magic_ctx));
60  goto error;
61  }
62 
63  (void)ConfGet("magic-file", &filename);
64 
65 
66  if (filename != NULL) {
67  if (strlen(filename) == 0) {
68  /* set filename to NULL on *nix systems so magic_load uses system
69  * default path (see man libmagic) */
70  SCLogConfig("using system default magic-file");
71  filename = NULL;
72  }
73  else {
74  SCLogConfig("using magic-file %s", filename);
75 
76  if ( (fd = fopen(filename, "r")) == NULL) {
77  SCLogWarning(SC_ERR_FOPEN, "Error opening file: \"%s\": %s",
78  filename, strerror(errno));
79  goto error;
80  }
81  fclose(fd);
82  }
83  }
84 
85  if (magic_load(g_magic_ctx, filename) != 0) {
86  SCLogError(SC_ERR_MAGIC_LOAD, "magic_load failed: %s",
87  magic_error(g_magic_ctx));
88  goto error;
89  }
90 
91  SCMutexUnlock(&g_magic_lock);
92  SCReturnInt(0);
93 
94 error:
95  if (g_magic_ctx != NULL) {
96  magic_close(g_magic_ctx);
97  g_magic_ctx = NULL;
98  }
99 
100  SCMutexUnlock(&g_magic_lock);
101  SCReturnInt(-1);
102 }
103 
104 /**
105  * \brief Find the magic value for a buffer.
106  *
107  * \param buf the buffer
108  * \param buflen length of the buffer
109  *
110  * \retval result pointer to null terminated string
111  */
112 char *MagicGlobalLookup(const uint8_t *buf, uint32_t buflen)
113 {
114  const char *result = NULL;
115  char *magic = NULL;
116 
117  SCMutexLock(&g_magic_lock);
118 
119  if (buf != NULL && buflen > 0) {
120  result = magic_buffer(g_magic_ctx, (void *)buf, (size_t)buflen);
121  if (result != NULL) {
122  magic = SCStrdup(result);
123  if (unlikely(magic == NULL)) {
124  SCLogError(SC_ERR_MEM_ALLOC, "Unable to dup magic");
125  }
126  }
127  }
128 
129  SCMutexUnlock(&g_magic_lock);
130  SCReturnPtr(magic, "const char");
131 }
132 
133 /**
134  * \brief Find the magic value for a buffer.
135  *
136  * \param buf the buffer
137  * \param buflen length of the buffer
138  *
139  * \retval result pointer to null terminated string
140  */
141 char *MagicThreadLookup(magic_t *ctx, const uint8_t *buf, uint32_t buflen)
142 {
143  const char *result = NULL;
144  char *magic = NULL;
145 
146  if (buf != NULL && buflen > 0) {
147  result = magic_buffer(*ctx, (void *)buf, (size_t)buflen);
148  if (result != NULL) {
149  magic = SCStrdup(result);
150  if (unlikely(magic == NULL)) {
151  SCLogError(SC_ERR_MEM_ALLOC, "Unable to dup magic");
152  }
153  }
154  }
155 
156  SCReturnPtr(magic, "const char");
157 }
158 
159 void MagicDeinit(void)
160 {
161  SCMutexLock(&g_magic_lock);
162  if (g_magic_ctx != NULL) {
163  magic_close(g_magic_ctx);
164  g_magic_ctx = NULL;
165  }
166  SCMutexUnlock(&g_magic_lock);
167  SCMutexDestroy(&g_magic_lock);
168 }
169 
170 #ifdef UNITTESTS
171 
172 #if defined OS_FREEBSD || defined OS_DARWIN
173 #define MICROSOFT_OFFICE_DOC "OLE 2 Compound Document"
174 #else
175 #define MICROSOFT_OFFICE_DOC "Microsoft Office Document"
176 #endif
177 
178 /** \test magic lib calls -- init */
179 static int MagicInitTest01(void)
180 {
181  int result = 0;
182  magic_t magic_ctx;
183 
184  magic_ctx = magic_open(0);
185  if (magic_ctx == NULL) {
186  printf("failure retrieving magic_ctx\n");
187  return 0;
188  }
189 
190  if (magic_load(magic_ctx, NULL) == -1) {
191  printf("failure magic_load\n");
192  goto end;
193  }
194 
195  result = 1;
196  end:
197  magic_close(magic_ctx);
198  return result;
199 }
200 
201 /** \test magic init through api */
202 static int MagicInitTest02(void)
203 {
204  if (g_magic_ctx != NULL) {
205  printf("g_magic_ctx != NULL at start of the test: ");
206  return 0;
207  }
208 
209  if (MagicInit() < 0) {
210  printf("MagicInit() failure\n");
211  return 0;
212  }
213 
214  if (g_magic_ctx == NULL) {
215  printf("g_magic_ctx == NULL: ");
216  return 0;
217  }
218 
219  MagicDeinit();
220 
221  if (g_magic_ctx != NULL) {
222  printf("g_magic_ctx != NULL at end of the test: ");
223  return 0;
224  }
225 
226  return 1;
227 }
228 
229 /** \test magic lib calls -- lookup */
230 static int MagicDetectTest01(void)
231 {
232  magic_t magic_ctx;
233  char *result = NULL;
234  char buffer[] = { 0x25, 'P', 'D', 'F', '-', '1', '.', '3', 0x0d, 0x0a};
235  size_t buffer_len = sizeof(buffer);
236  int retval = 0;
237 
238  magic_ctx = magic_open(0);
239  if (magic_ctx == NULL) {
240  printf("failure retrieving magic_ctx\n");
241  return 0;
242  }
243 
244  if (magic_load(magic_ctx, NULL) == -1) {
245  printf("magic_load failure\n");
246  goto end;
247  }
248 
249  result = (char *)magic_buffer(magic_ctx, (void *)buffer, buffer_len);
250  if (result == NULL || strncmp(result, "PDF document", 12) != 0) {
251  printf("result %p:%s, not \"PDF document\": ", result,result?result:"(null)");
252  goto end;
253  }
254 
255  retval = 1;
256 end:
257  magic_close(magic_ctx);
258  return retval;
259 }
260 #if 0
261 /** \test magic lib calls -- lookup */
262 static int MagicDetectTest02(void)
263 {
264  magic_t magic_ctx;
265  char *result = NULL;
266 
267  char buffer[] = {
268  0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1,
269  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
270  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
271  0x3e, 0x00, 0x03, 0x00, 0xfe, 0xff, 0x09, 0x00,
272 
273  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
274  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
275  0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
276  0x00, 0x10, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
277 
278  0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
279  0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00,
280  0x97, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
281  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
282  };
283  size_t buffer_len = sizeof(buffer);
284  int retval = 0;
285 
286  magic_ctx = magic_open(0);
287  if (magic_ctx == NULL) {
288  printf("failure retrieving magic_ctx\n");
289  return 0;
290  }
291 
292  if (magic_load(magic_ctx, NULL) == -1) {
293  printf("magic_load failure\n");
294  goto end;
295  }
296 
297  result = (char *)magic_buffer(magic_ctx, (void *)buffer, buffer_len);
298  if (result == NULL || strcmp(result, MICROSOFT_OFFICE_DOC) != 0) {
299  printf("result %p:%s, not \"Microsoft Office Document\": ", result,result?result:"(null)");
300  goto end;
301  }
302 
303  retval = 1;
304 end:
305  magic_close(magic_ctx);
306  return retval;
307 }
308 #endif
309 /** \test magic lib calls -- lookup */
310 static int MagicDetectTest03(void)
311 {
312  char buffer[] = {
313  0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x00,
314  0x00, 0x00, 0x0b, 0x55, 0x2a, 0x36, 0x5e, 0xc6,
315  0x32, 0x0c, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00,
316  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x6d, 0x69,
317 
318  0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70,
319  0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
320  0x6e, 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6f, 0x61,
321  0x73, 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x65, 0x6e,
322 
323  0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74,
324  0x2e, 0x74, 0x65, 0x78, 0x74, 0x50, 0x4b, 0x03,
325  0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
326  0x55, 0x2a, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
327 
328  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a,
329  0x00, 0x00, 0x00, 0x43, 0x6f, 0x6e, 0x66, 0x69,
330  0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
331  0x73, 0x32, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75,
332 
333  0x73, 0x62, 0x61, 0x72, 0x2f, 0x50, 0x4b, 0x03,
334  0x04, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0b,
335  };
336  size_t buffer_len = sizeof(buffer);
337 
338  magic_t magic_ctx = magic_open(0);
339  FAIL_IF_NULL(magic_ctx);
340 
341  FAIL_IF(magic_load(magic_ctx, NULL) == -1);
342 
343  char *result = (char *)magic_buffer(magic_ctx, (void *)buffer, buffer_len);
344  FAIL_IF_NULL(result);
345 
346  char *str = strstr(result, "OpenDocument Text");
347  FAIL_IF_NULL(str);
348 
349  magic_close(magic_ctx);
350  PASS;
351 }
352 
353 /** \test magic lib calls -- lookup */
354 static int MagicDetectTest04(void)
355 {
356  magic_t magic_ctx;
357  char *result = NULL;
358 
359  char buffer[] = {
360  0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x08,
361  0x00, 0x00, 0x52, 0x7b, 0x86, 0x3c, 0x8b, 0x70,
362  0x96, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00,
363  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x6d, 0x69,
364 
365  0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70,
366  0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
367  0x6e, 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x73, 0x75,
368  0x6e, 0x2e, 0x78, 0x6d, 0x6c, 0x2e, 0x62, 0x61,
369 
370  0x73, 0x65, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00,
371  0x00, 0x08, 0x00, 0x00, 0x52, 0x7b, 0x86, 0x3c,
372  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
373  0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
374 
375  0x4d, 0x45, 0x54, 0x41, 0x2d, 0x49, 0x4e, 0x46,
376  0x2f, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00,
377  0x08, 0x08, 0x00, 0xa8, 0x42, 0x1d, 0x37, 0x5d,
378  0xa7, 0xb2, 0xc1, 0xde, 0x01, 0x00, 0x00, 0x7e,
379 
380  0x04, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x63,
381  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x78,
382  0x6d, 0x6c, 0x95, 0x54, 0x4d, 0x6f, 0xdb, 0x30,
383  0x0c, 0xbd, 0xe7, 0x57, 0x18, 0x02, 0x06, 0x6c,
384 
385  0x07, 0xc5, 0xe9, 0xb6, 0xc3, 0x22, 0xc4, 0x29,
386  0x86, 0x7d, 0x00, 0x05, 0x8a, 0x9d, 0xb2, 0x43,
387  0x8f, 0xb2, 0x24, 0xa7, 0xc2, 0x64, 0xc9, 0x15,
388  };
389  size_t buffer_len = sizeof(buffer);
390  int retval = 0;
391 
392  magic_ctx = magic_open(0);
393  if (magic_ctx == NULL) {
394  printf("failure retrieving magic_ctx\n");
395  return 0;
396  }
397 
398  if (magic_load(magic_ctx, NULL) == -1) {
399  printf("magic_load failure\n");
400  goto end;
401  }
402 
403  result = (char *)magic_buffer(magic_ctx, (void *)buffer, buffer_len);
404  if (result == NULL || strncmp(result, "OpenOffice.org 1.x", 18) != 0) {
405  printf("result %p:%s, not \"OpenOffice.org 1.x\": ", result,result?result:"(null)");
406  goto end;
407  }
408 
409  retval = 1;
410 end:
411  magic_close(magic_ctx);
412  return retval;
413 }
414 
415 /** \test magic api calls -- lookup */
416 static int MagicDetectTest05(void)
417 {
418  const char *result = NULL;
419  uint8_t buffer[] = { 0x25, 'P', 'D', 'F', '-', '1', '.', '3', 0x0d, 0x0a};
420  size_t buffer_len = sizeof(buffer);
421  int retval = 0;
422 
423  if (MagicInit() < 0) {
424  printf("MagicInit() failure\n");
425  return 0;
426  }
427 
428  result = MagicGlobalLookup(buffer, buffer_len);
429  if (result == NULL || strncmp(result, "PDF document", 12) != 0) {
430  printf("result %p:%s, not \"PDF document\": ", result,result?result:"(null)");
431  goto end;
432  }
433 
434  retval = 1;
435 end:
436  MagicDeinit();
437  return retval;
438 }
439 #if 0
440 /** \test magic api calls -- lookup */
441 static int MagicDetectTest06(void)
442 {
443  const char *result = NULL;
444  uint8_t buffer[] = {
445  0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1,
446  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
447  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
448  0x3e, 0x00, 0x03, 0x00, 0xfe, 0xff, 0x09, 0x00,
449 
450  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
451  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
452  0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
453  0x00, 0x10, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
454 
455  0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
456  0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00,
457  0x97, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
458  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
459  };
460  size_t buffer_len = sizeof(buffer);
461  int retval = 0;
462 
463  if (MagicInit() < 0) {
464  printf("MagicInit() failure\n");
465  return 0;
466  }
467 
468  result = MagicGlobalLookup(buffer, buffer_len);
469  if (result == NULL || strcmp(result, MICROSOFT_OFFICE_DOC) != 0) {
470  printf("result %p:%s, not \"Microsoft Office Document\": ", result,result?result:"(null)");
471  goto end;
472  }
473 
474  retval = 1;
475 
476 end:
477  MagicDeinit();
478  return retval;
479 }
480 #endif
481 /** \test magic api calls -- lookup */
482 static int MagicDetectTest07(void)
483 {
484  const char *result = NULL;
485  uint8_t buffer[] = {
486  0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x00,
487  0x00, 0x00, 0x0b, 0x55, 0x2a, 0x36, 0x5e, 0xc6,
488  0x32, 0x0c, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00,
489  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x6d, 0x69,
490 
491  0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70,
492  0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
493  0x6e, 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6f, 0x61,
494  0x73, 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x65, 0x6e,
495 
496  0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74,
497  0x2e, 0x74, 0x65, 0x78, 0x74, 0x50, 0x4b, 0x03,
498  0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
499  0x55, 0x2a, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
500 
501  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a,
502  0x00, 0x00, 0x00, 0x43, 0x6f, 0x6e, 0x66, 0x69,
503  0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
504  0x73, 0x32, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75,
505 
506  0x73, 0x62, 0x61, 0x72, 0x2f, 0x50, 0x4b, 0x03,
507  0x04, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0b,
508  };
509  size_t buffer_len = sizeof(buffer);
510 
511  FAIL_IF(MagicInit() < 0);
512 
513  result = MagicGlobalLookup(buffer, buffer_len);
514  FAIL_IF_NULL(result);
515 
516  char *str = strstr(result, "OpenDocument Text");
517  FAIL_IF_NULL(str);
518 
519  MagicDeinit();
520  PASS;
521 }
522 
523 /** \test magic api calls -- lookup */
524 static int MagicDetectTest08(void)
525 {
526  const char *result = NULL;
527  uint8_t buffer[] = {
528  0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x08,
529  0x00, 0x00, 0x52, 0x7b, 0x86, 0x3c, 0x8b, 0x70,
530  0x96, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00,
531  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x6d, 0x69,
532 
533  0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70,
534  0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
535  0x6e, 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x73, 0x75,
536  0x6e, 0x2e, 0x78, 0x6d, 0x6c, 0x2e, 0x62, 0x61,
537 
538  0x73, 0x65, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00,
539  0x00, 0x08, 0x00, 0x00, 0x52, 0x7b, 0x86, 0x3c,
540  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
541  0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
542 
543  0x4d, 0x45, 0x54, 0x41, 0x2d, 0x49, 0x4e, 0x46,
544  0x2f, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00,
545  0x08, 0x08, 0x00, 0xa8, 0x42, 0x1d, 0x37, 0x5d,
546  0xa7, 0xb2, 0xc1, 0xde, 0x01, 0x00, 0x00, 0x7e,
547 
548  0x04, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x63,
549  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x78,
550  0x6d, 0x6c, 0x95, 0x54, 0x4d, 0x6f, 0xdb, 0x30,
551 
552  0x0c, 0xbd, 0xe7, 0x57, 0x18, 0x02, 0x06, 0x6c,
553  0x07, 0xc5, 0xe9, 0xb6, 0xc3, 0x22, 0xc4, 0x29,
554  0x86, 0x7d, 0x00, 0x05, 0x8a, 0x9d, 0xb2, 0x43,
555  0x8f, 0xb2, 0x24, 0xa7, 0xc2, 0x64, 0xc9, 0x15,
556  };
557  size_t buffer_len = sizeof(buffer);
558  int retval = 0;
559 
560  if (MagicInit() < 0) {
561  printf("MagicInit() failure\n");
562  return 0;
563  }
564 
565  result = MagicGlobalLookup(buffer, buffer_len);
566  if (result == NULL || strncmp(result, "OpenOffice.org 1.x", 18) != 0) {
567  printf("result %p:%s, not \"OpenOffice.org 1.x\": ", result,result?result:"(null)");
568  goto end;
569  }
570 
571  retval = 1;
572 end:
573  MagicDeinit();
574  return retval;
575 }
576 #if 0
577 /** \test magic api calls -- make sure memory is shared */
578 static int MagicDetectTest09(void)
579 {
580  const char *result1 = NULL;
581  const char *result2 = NULL;
582  uint8_t buffer[] = { 0x25, 'P', 'D', 'F', '-', '1', '.', '3', 0x0d, 0x0a};
583  size_t buffer_len = sizeof(buffer);
584  int retval = 0;
585 
586  if (MagicInit() < 0) {
587  printf("MagicInit() failure\n");
588  return 0;
589  }
590 
591  result1 = MagicGlobalLookup(buffer, buffer_len);
592  if (result1 == NULL || strncmp(result1, "PDF document", 12) != 0) {
593  printf("result %p:%s, not \"PDF document\": ", result1,result1?result1:"(null)");
594  goto end;
595  }
596 
597  result2 = MagicGlobalLookup(buffer, buffer_len);
598  if (result2 == NULL || strncmp(result2, "PDF document", 12) != 0) {
599  printf("result %p:%s, not \"PDF document\": ", result2,result2?result2:"(null)");
600  goto end;
601  }
602 
603  if (result1 != result2) {
604  printf("pointers not equal, weird... %p != %p: ", result1, result2);
605  goto end;
606  }
607 
608  retval = 1;
609 end:
610  MagicDeinit();
611  return retval;
612 }
613 #endif
614 /** \test results in valgrind warning about invalid read, tested with
615  * file 5.09 and 5.11 */
616 static int MagicDetectTest10ValgrindError(void)
617 {
618  const char *result = NULL;
619  uint8_t buffer[] = {
620  0xFF,0xD8,0xFF,0xE0,0x00,0x10,0x4A,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2C,
621  0x01,0x2C,0x00,0x00,0xFF,0xFE,0x00,0x4C,0x53,0x69,0x67,0x6E,0x61,0x74,0x75,0x72,
622  0x65,0x3A,0x34,0x31,0x31,0x65,0x33,0x38,0x61,0x61,0x61,0x31,0x37,0x65,0x33,0x30,
623  0x66,0x30,0x32,0x38,0x62,0x61,0x30,0x31,0x36,0x32,0x36,0x37,0x66,0x66,0x30,0x31,
624  0x36,0x36,0x61,0x65,0x35,0x39,0x65,0x38,0x31,0x39,0x62,0x61,0x32,0x34,0x63,0x39,
625  0x62,0x31,0x33,0x37,0x33,0x62,0x31,0x61,0x35,0x61,0x38,0x65,0x64,0x63,0x36,0x30,
626  0x65,0x37,0xFF,0xE2,0x02,0x2C,0x49,0x43,0x43,0x5F,0x50,0x52,0x4F,0x46,0x49,0x4C,
627  0x45,0x00,0x01,0x01,0x00,0x00,0x02,0x1C,0x41,0x44,0x42,0x45,0x02,0x10,0x00,0x00,
628  0x6D,0x6E,0x74,0x72,0x52,0x47,0x42,0x20,0x58,0x59,0x5A,0x20,0x07,0xCF,0x00,0x05,
629  0x00,0x09,0x00,0x15,0x00,0x0B,0x00,0x21,0x61,0x63,0x73,0x70,0x41,0x50,0x50,0x4C,
630  0x00,0x00,0x00,0x00,0x6E,0x6F,0x6E,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
631  };
632  size_t buffer_len = sizeof(buffer);
633  int retval = 0;
634 
635  if (MagicInit() < 0) {
636  printf("MagicInit() failure\n");
637  return 0;
638  }
639 
640  result = MagicGlobalLookup(buffer, buffer_len);
641  if (result == NULL || strncmp(result, "JPEG", 4) != 0) {
642  printf("result %p:%s, not \"JPEG\": ", result,result?result:"(null)");
643  goto end;
644  }
645 
646  retval = 1;
647 end:
648  MagicDeinit();
649  return retval;
650 }
651 
652 #endif /* UNITTESTS */
653 #endif
654 
656 {
657 #ifdef HAVE_MAGIC
658 #ifdef UNITTESTS
659  UtRegisterTest("MagicInitTest01", MagicInitTest01);
660  UtRegisterTest("MagicInitTest02", MagicInitTest02);
661  UtRegisterTest("MagicDetectTest01", MagicDetectTest01);
662  //UtRegisterTest("MagicDetectTest02", MagicDetectTest02, 1);
663  UtRegisterTest("MagicDetectTest03", MagicDetectTest03);
664  UtRegisterTest("MagicDetectTest04", MagicDetectTest04);
665  UtRegisterTest("MagicDetectTest05", MagicDetectTest05);
666  //UtRegisterTest("MagicDetectTest06", MagicDetectTest06, 1);
667  UtRegisterTest("MagicDetectTest07", MagicDetectTest07);
668  UtRegisterTest("MagicDetectTest08", MagicDetectTest08);
669  /* fails in valgrind, somehow it returns different pointers then.
670  UtRegisterTest("MagicDetectTest09", MagicDetectTest09, 1); */
671 
672  UtRegisterTest("MagicDetectTest10ValgrindError",
673  MagicDetectTest10ValgrindError);
674 #endif /* UNITTESTS */
675 #endif /* HAVE_MAGIC */
676 }
677 
#define SCMutex
#define BUG_ON(x)
#define PASS
Pass the test.
#define unlikely(expr)
Definition: util-optimize.h:35
#define FAIL_IF(expr)
Fail a test if expression evaluates to false.
Definition: util-unittest.h:71
#define SCMutexLock(mut)
int ConfGet(const char *name, const char **vptr)
Retrieve the value of a configuration node.
Definition: conf.c:331
#define str(s)
#define SCMutexUnlock(mut)
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
void UtRegisterTest(const char *name, int(*TestFn)(void))
Register unit test.
#define SCEnter(...)
Definition: util-debug.h:337
#define SCMutexInit(mut, mutattrs)
#define SCReturnInt(x)
Definition: util-debug.h:341
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
#define SCReturnPtr(x, type)
Definition: util-debug.h:353
#define SCStrdup(a)
Definition: util-mem.h:268
#define FAIL_IF_NULL(expr)
Fail a test if expression evaluates to NULL.
Definition: util-unittest.h:89
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
void MagicRegisterTests(void)
Definition: util-magic.c:655
#define SCMutexDestroy