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  if (str == NULL) {
348  printf("result %s, not \"OpenDocument Text\": ", str);
349  FAIL;
350  }
351 
352  magic_close(magic_ctx);
353  PASS;
354 }
355 
356 /** \test magic lib calls -- lookup */
357 static int MagicDetectTest04(void)
358 {
359  magic_t magic_ctx;
360  char *result = NULL;
361 
362  char buffer[] = {
363  0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x08,
364  0x00, 0x00, 0x52, 0x7b, 0x86, 0x3c, 0x8b, 0x70,
365  0x96, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00,
366  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x6d, 0x69,
367 
368  0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70,
369  0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
370  0x6e, 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x73, 0x75,
371  0x6e, 0x2e, 0x78, 0x6d, 0x6c, 0x2e, 0x62, 0x61,
372 
373  0x73, 0x65, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00,
374  0x00, 0x08, 0x00, 0x00, 0x52, 0x7b, 0x86, 0x3c,
375  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
376  0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
377 
378  0x4d, 0x45, 0x54, 0x41, 0x2d, 0x49, 0x4e, 0x46,
379  0x2f, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00,
380  0x08, 0x08, 0x00, 0xa8, 0x42, 0x1d, 0x37, 0x5d,
381  0xa7, 0xb2, 0xc1, 0xde, 0x01, 0x00, 0x00, 0x7e,
382 
383  0x04, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x63,
384  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x78,
385  0x6d, 0x6c, 0x95, 0x54, 0x4d, 0x6f, 0xdb, 0x30,
386  0x0c, 0xbd, 0xe7, 0x57, 0x18, 0x02, 0x06, 0x6c,
387 
388  0x07, 0xc5, 0xe9, 0xb6, 0xc3, 0x22, 0xc4, 0x29,
389  0x86, 0x7d, 0x00, 0x05, 0x8a, 0x9d, 0xb2, 0x43,
390  0x8f, 0xb2, 0x24, 0xa7, 0xc2, 0x64, 0xc9, 0x15,
391  };
392  size_t buffer_len = sizeof(buffer);
393  int retval = 0;
394 
395  magic_ctx = magic_open(0);
396  if (magic_ctx == NULL) {
397  printf("failure retrieving magic_ctx\n");
398  return 0;
399  }
400 
401  if (magic_load(magic_ctx, NULL) == -1) {
402  printf("magic_load failure\n");
403  goto end;
404  }
405 
406  result = (char *)magic_buffer(magic_ctx, (void *)buffer, buffer_len);
407  if (result == NULL || strncmp(result, "OpenOffice.org 1.x", 18) != 0) {
408  printf("result %p:%s, not \"OpenOffice.org 1.x\": ", result,result?result:"(null)");
409  goto end;
410  }
411 
412  retval = 1;
413 end:
414  magic_close(magic_ctx);
415  return retval;
416 }
417 
418 /** \test magic api calls -- lookup */
419 static int MagicDetectTest05(void)
420 {
421  const char *result = NULL;
422  uint8_t buffer[] = { 0x25, 'P', 'D', 'F', '-', '1', '.', '3', 0x0d, 0x0a};
423  size_t buffer_len = sizeof(buffer);
424  int retval = 0;
425 
426  if (MagicInit() < 0) {
427  printf("MagicInit() failure\n");
428  return 0;
429  }
430 
431  result = MagicGlobalLookup(buffer, buffer_len);
432  if (result == NULL || strncmp(result, "PDF document", 12) != 0) {
433  printf("result %p:%s, not \"PDF document\": ", result,result?result:"(null)");
434  goto end;
435  }
436 
437  retval = 1;
438 end:
439  MagicDeinit();
440  return retval;
441 }
442 #if 0
443 /** \test magic api calls -- lookup */
444 static int MagicDetectTest06(void)
445 {
446  const char *result = NULL;
447  uint8_t buffer[] = {
448  0xd0, 0xcf, 0x11, 0xe0, 0xa1, 0xb1, 0x1a, 0xe1,
449  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
450  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
451  0x3e, 0x00, 0x03, 0x00, 0xfe, 0xff, 0x09, 0x00,
452 
453  0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
454  0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
455  0x96, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
456  0x00, 0x10, 0x00, 0x00, 0x98, 0x00, 0x00, 0x00,
457 
458  0x01, 0x00, 0x00, 0x00, 0xfe, 0xff, 0xff, 0xff,
459  0x00, 0x00, 0x00, 0x00, 0x90, 0x00, 0x00, 0x00,
460  0x97, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff,
461  0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
462  };
463  size_t buffer_len = sizeof(buffer);
464  int retval = 0;
465 
466  if (MagicInit() < 0) {
467  printf("MagicInit() failure\n");
468  return 0;
469  }
470 
471  result = MagicGlobalLookup(buffer, buffer_len);
472  if (result == NULL || strcmp(result, MICROSOFT_OFFICE_DOC) != 0) {
473  printf("result %p:%s, not \"Microsoft Office Document\": ", result,result?result:"(null)");
474  goto end;
475  }
476 
477  retval = 1;
478 
479 end:
480  MagicDeinit();
481  return retval;
482 }
483 #endif
484 /** \test magic api calls -- lookup */
485 static int MagicDetectTest07(void)
486 {
487  const char *result = NULL;
488  uint8_t buffer[] = {
489  0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x00,
490  0x00, 0x00, 0x0b, 0x55, 0x2a, 0x36, 0x5e, 0xc6,
491  0x32, 0x0c, 0x27, 0x00, 0x00, 0x00, 0x27, 0x00,
492  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x6d, 0x69,
493 
494  0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70,
495  0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
496  0x6e, 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x6f, 0x61,
497  0x73, 0x69, 0x73, 0x2e, 0x6f, 0x70, 0x65, 0x6e,
498 
499  0x64, 0x6f, 0x63, 0x75, 0x6d, 0x65, 0x6e, 0x74,
500  0x2e, 0x74, 0x65, 0x78, 0x74, 0x50, 0x4b, 0x03,
501  0x04, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0b,
502  0x55, 0x2a, 0x36, 0x00, 0x00, 0x00, 0x00, 0x00,
503 
504  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x1a,
505  0x00, 0x00, 0x00, 0x43, 0x6f, 0x6e, 0x66, 0x69,
506  0x67, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e,
507  0x73, 0x32, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75,
508 
509  0x73, 0x62, 0x61, 0x72, 0x2f, 0x50, 0x4b, 0x03,
510  0x04, 0x14, 0x00, 0x08, 0x00, 0x08, 0x00, 0x0b,
511  };
512  size_t buffer_len = sizeof(buffer);
513 
514  FAIL_IF(MagicInit() < 0);
515 
516  result = MagicGlobalLookup(buffer, buffer_len);
517  FAIL_IF_NULL(result);
518 
519  char *str = strstr(result, "OpenDocument Text");
520  if (str == NULL) {
521  printf("result %s, not \"OpenDocument Text\": ", str);
522  FAIL;
523  }
524 
525  MagicDeinit();
526  PASS;
527 }
528 
529 /** \test magic api calls -- lookup */
530 static int MagicDetectTest08(void)
531 {
532  const char *result = NULL;
533  uint8_t buffer[] = {
534  0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00, 0x08,
535  0x00, 0x00, 0x52, 0x7b, 0x86, 0x3c, 0x8b, 0x70,
536  0x96, 0x08, 0x1c, 0x00, 0x00, 0x00, 0x1c, 0x00,
537  0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x6d, 0x69,
538 
539  0x6d, 0x65, 0x74, 0x79, 0x70, 0x65, 0x61, 0x70,
540  0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f,
541  0x6e, 0x2f, 0x76, 0x6e, 0x64, 0x2e, 0x73, 0x75,
542  0x6e, 0x2e, 0x78, 0x6d, 0x6c, 0x2e, 0x62, 0x61,
543 
544  0x73, 0x65, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00,
545  0x00, 0x08, 0x00, 0x00, 0x52, 0x7b, 0x86, 0x3c,
546  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
547  0x00, 0x00, 0x00, 0x00, 0x09, 0x00, 0x00, 0x00,
548 
549  0x4d, 0x45, 0x54, 0x41, 0x2d, 0x49, 0x4e, 0x46,
550  0x2f, 0x50, 0x4b, 0x03, 0x04, 0x14, 0x00, 0x00,
551  0x08, 0x08, 0x00, 0xa8, 0x42, 0x1d, 0x37, 0x5d,
552  0xa7, 0xb2, 0xc1, 0xde, 0x01, 0x00, 0x00, 0x7e,
553 
554  0x04, 0x00, 0x00, 0x0b, 0x00, 0x00, 0x00, 0x63,
555  0x6f, 0x6e, 0x74, 0x65, 0x6e, 0x74, 0x2e, 0x78,
556  0x6d, 0x6c, 0x95, 0x54, 0x4d, 0x6f, 0xdb, 0x30,
557 
558  0x0c, 0xbd, 0xe7, 0x57, 0x18, 0x02, 0x06, 0x6c,
559  0x07, 0xc5, 0xe9, 0xb6, 0xc3, 0x22, 0xc4, 0x29,
560  0x86, 0x7d, 0x00, 0x05, 0x8a, 0x9d, 0xb2, 0x43,
561  0x8f, 0xb2, 0x24, 0xa7, 0xc2, 0x64, 0xc9, 0x15,
562  };
563  size_t buffer_len = sizeof(buffer);
564  int retval = 0;
565 
566  if (MagicInit() < 0) {
567  printf("MagicInit() failure\n");
568  return 0;
569  }
570 
571  result = MagicGlobalLookup(buffer, buffer_len);
572  if (result == NULL || strncmp(result, "OpenOffice.org 1.x", 18) != 0) {
573  printf("result %p:%s, not \"OpenOffice.org 1.x\": ", result,result?result:"(null)");
574  goto end;
575  }
576 
577  retval = 1;
578 end:
579  MagicDeinit();
580  return retval;
581 }
582 #if 0
583 /** \test magic api calls -- make sure memory is shared */
584 static int MagicDetectTest09(void)
585 {
586  const char *result1 = NULL;
587  const char *result2 = NULL;
588  uint8_t buffer[] = { 0x25, 'P', 'D', 'F', '-', '1', '.', '3', 0x0d, 0x0a};
589  size_t buffer_len = sizeof(buffer);
590  int retval = 0;
591 
592  if (MagicInit() < 0) {
593  printf("MagicInit() failure\n");
594  return 0;
595  }
596 
597  result1 = MagicGlobalLookup(buffer, buffer_len);
598  if (result1 == NULL || strncmp(result1, "PDF document", 12) != 0) {
599  printf("result %p:%s, not \"PDF document\": ", result1,result1?result1:"(null)");
600  goto end;
601  }
602 
603  result2 = MagicGlobalLookup(buffer, buffer_len);
604  if (result2 == NULL || strncmp(result2, "PDF document", 12) != 0) {
605  printf("result %p:%s, not \"PDF document\": ", result2,result2?result2:"(null)");
606  goto end;
607  }
608 
609  if (result1 != result2) {
610  printf("pointers not equal, weird... %p != %p: ", result1, result2);
611  goto end;
612  }
613 
614  retval = 1;
615 end:
616  MagicDeinit();
617  return retval;
618 }
619 #endif
620 /** \test results in valgrind warning about invalid read, tested with
621  * file 5.09 and 5.11 */
622 static int MagicDetectTest10ValgrindError(void)
623 {
624  const char *result = NULL;
625  uint8_t buffer[] = {
626  0xFF,0xD8,0xFF,0xE0,0x00,0x10,0x4A,0x46,0x49,0x46,0x00,0x01,0x01,0x01,0x01,0x2C,
627  0x01,0x2C,0x00,0x00,0xFF,0xFE,0x00,0x4C,0x53,0x69,0x67,0x6E,0x61,0x74,0x75,0x72,
628  0x65,0x3A,0x34,0x31,0x31,0x65,0x33,0x38,0x61,0x61,0x61,0x31,0x37,0x65,0x33,0x30,
629  0x66,0x30,0x32,0x38,0x62,0x61,0x30,0x31,0x36,0x32,0x36,0x37,0x66,0x66,0x30,0x31,
630  0x36,0x36,0x61,0x65,0x35,0x39,0x65,0x38,0x31,0x39,0x62,0x61,0x32,0x34,0x63,0x39,
631  0x62,0x31,0x33,0x37,0x33,0x62,0x31,0x61,0x35,0x61,0x38,0x65,0x64,0x63,0x36,0x30,
632  0x65,0x37,0xFF,0xE2,0x02,0x2C,0x49,0x43,0x43,0x5F,0x50,0x52,0x4F,0x46,0x49,0x4C,
633  0x45,0x00,0x01,0x01,0x00,0x00,0x02,0x1C,0x41,0x44,0x42,0x45,0x02,0x10,0x00,0x00,
634  0x6D,0x6E,0x74,0x72,0x52,0x47,0x42,0x20,0x58,0x59,0x5A,0x20,0x07,0xCF,0x00,0x05,
635  0x00,0x09,0x00,0x15,0x00,0x0B,0x00,0x21,0x61,0x63,0x73,0x70,0x41,0x50,0x50,0x4C,
636  0x00,0x00,0x00,0x00,0x6E,0x6F,0x6E,0x65,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
637  };
638  size_t buffer_len = sizeof(buffer);
639  int retval = 0;
640 
641  if (MagicInit() < 0) {
642  printf("MagicInit() failure\n");
643  return 0;
644  }
645 
646  result = MagicGlobalLookup(buffer, buffer_len);
647  if (result == NULL || strncmp(result, "JPEG", 4) != 0) {
648  printf("result %p:%s, not \"JPEG\": ", result,result?result:"(null)");
649  goto end;
650  }
651 
652  retval = 1;
653 end:
654  MagicDeinit();
655  return retval;
656 }
657 
658 #endif /* UNITTESTS */
659 #endif
660 
662 {
663 #ifdef HAVE_MAGIC
664 #ifdef UNITTESTS
665  UtRegisterTest("MagicInitTest01", MagicInitTest01);
666  UtRegisterTest("MagicInitTest02", MagicInitTest02);
667  UtRegisterTest("MagicDetectTest01", MagicDetectTest01);
668  //UtRegisterTest("MagicDetectTest02", MagicDetectTest02, 1);
669  UtRegisterTest("MagicDetectTest03", MagicDetectTest03);
670  UtRegisterTest("MagicDetectTest04", MagicDetectTest04);
671  UtRegisterTest("MagicDetectTest05", MagicDetectTest05);
672  //UtRegisterTest("MagicDetectTest06", MagicDetectTest06, 1);
673  UtRegisterTest("MagicDetectTest07", MagicDetectTest07);
674  UtRegisterTest("MagicDetectTest08", MagicDetectTest08);
675  /* fails in valgrind, somehow it returns different pointers then.
676  UtRegisterTest("MagicDetectTest09", MagicDetectTest09, 1); */
677 
678  UtRegisterTest("MagicDetectTest10ValgrindError",
679  MagicDetectTest10ValgrindError);
680 #endif /* UNITTESTS */
681 #endif /* HAVE_MAGIC */
682 }
683 
#define SCMutexDestroy(x)
#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
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 SCMutexInit(mut, mutattr)
#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 SCReturnInt(x)
Definition: util-debug.h:341
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
#define FAIL
Definition: util-unittest.h:60
#define SCMutex
#define SCMutexLock(mut)
#define SCReturnPtr(x, type)
Definition: util-debug.h:353
#define SCStrdup(a)
Definition: util-mem.h:220
#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:661