suricata
util-file.c
Go to the documentation of this file.
1 /* Copyright (C) 2007-2012 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  * \author Pablo Rincon <pablo.rincon.crespo@gmail.com>
23  *
24  */
25 
26 #include "suricata-common.h"
27 #include "suricata.h"
28 #include "debug.h"
29 #include "flow.h"
30 #include "stream.h"
31 #include "stream-tcp.h"
32 #include "runmodes.h"
33 #include "util-hash.h"
34 #include "util-debug.h"
35 #include "util-memcmp.h"
36 #include "util-print.h"
37 #include "app-layer-parser.h"
38 #include "util-validate.h"
39 
40 extern int g_detect_disabled;
41 
42 /** \brief switch to force filestore on all files
43  * regardless of the rules.
44  */
45 static int g_file_force_filestore = 0;
46 
47 /** \brief switch to force magic checks on all files
48  * regardless of the rules.
49  */
50 static int g_file_force_magic = 0;
51 
52 /** \brief switch to force md5 calculation on all files
53  * regardless of the rules.
54  */
55 static int g_file_force_md5 = 0;
56 
57 /** \brief switch to force sha1 calculation on all files
58  * regardless of the rules.
59  */
60 static int g_file_force_sha1 = 0;
61 
62 /** \brief switch to force sha256 calculation on all files
63  * regardless of the rules.
64  */
65 static int g_file_force_sha256 = 0;
66 
67 /** \brief switch to force tracking off all files
68  * regardless of the rules.
69  */
70 static int g_file_force_tracking = 0;
71 
72 /** \brief switch to use g_file_store_reassembly_depth
73  * to reassembly files
74  */
75 static int g_file_store_enable = 0;
76 
77 /** \brief stream_config.reassembly_depth equivalent
78  * for files
79  */
80 static uint32_t g_file_store_reassembly_depth = 0;
81 
82 /* prototypes */
83 static void FileFree(File *);
84 #ifdef HAVE_NSS
85 static void FileEndSha256(File *ff);
86 #endif
87 
89 {
90  g_file_force_filestore = 1;
91 }
92 
94 {
95  g_file_force_magic = 1;
96 }
97 
99 {
100  g_file_force_md5 = 1;
101 }
102 
104 {
105  g_file_force_sha1 = 1;
106 }
107 
109 {
110  g_file_force_sha256 = 1;
111 }
112 
114 {
115  return g_file_force_filestore;
116 }
117 
118 void FileReassemblyDepthEnable(uint32_t size)
119 {
120  g_file_store_enable = 1;
121  g_file_store_reassembly_depth = size;
122 }
123 
124 uint32_t FileReassemblyDepth(void)
125 {
126  if (g_file_store_enable == 1)
127  return g_file_store_reassembly_depth;
128  else
130 }
131 
132 int FileForceMagic(void)
133 {
134  return g_file_force_magic;
135 }
136 
137 int FileForceMd5(void)
138 {
139  return g_file_force_md5;
140 }
141 
142 int FileForceSha1(void)
143 {
144  return g_file_force_sha1;
145 }
146 
148 {
149  return g_file_force_sha256;
150 }
151 
153 {
154  g_file_force_tracking = 1;
155 }
156 
157 /**
158  * \brief Function to parse forced file hashing configuration.
159  */
161 {
162  BUG_ON(conf == NULL);
163 
164  ConfNode *forcehash_node = NULL;
165 
166  /* legacy option */
167  const char *force_md5 = ConfNodeLookupChildValue(conf, "force-md5");
168  if (force_md5 != NULL) {
169  SCLogWarning(SC_ERR_DEPRECATED_CONF, "deprecated 'force-md5' option "
170  "found. Please use 'force-hash: [md5]' instead");
171 
172  if (ConfValIsTrue(force_md5)) {
173 #ifdef HAVE_NSS
175  SCLogInfo("forcing md5 calculation for logged files");
176 #else
177  SCLogInfo("md5 calculation requires linking against libnss");
178 #endif
179  }
180  }
181 
182  if (conf != NULL)
183  forcehash_node = ConfNodeLookupChild(conf, "force-hash");
184 
185  if (forcehash_node != NULL) {
186  ConfNode *field = NULL;
187 
188  TAILQ_FOREACH(field, &forcehash_node->head, next) {
189  if (strcasecmp("md5", field->val) == 0) {
190 #ifdef HAVE_NSS
192  SCLogConfig("forcing md5 calculation for logged or stored files");
193 #else
194  SCLogInfo("md5 calculation requires linking against libnss");
195 #endif
196  }
197 
198  if (strcasecmp("sha1", field->val) == 0) {
199 #ifdef HAVE_NSS
201  SCLogConfig("forcing sha1 calculation for logged or stored files");
202 #else
203  SCLogInfo("sha1 calculation requires linking against libnss");
204 #endif
205  }
206 
207  if (strcasecmp("sha256", field->val) == 0) {
208 #ifdef HAVE_NSS
210  SCLogConfig("forcing sha256 calculation for logged or stored files");
211 #else
212  SCLogInfo("sha256 calculation requires linking against libnss");
213 #endif
214  }
215  }
216  }
217 }
218 
219 uint16_t FileFlowToFlags(const Flow *flow, uint8_t direction)
220 {
221  uint16_t flags = 0;
222 
223  if (direction == STREAM_TOSERVER) {
224  if (flow->file_flags & FLOWFILE_NO_STORE_TS) {
225  flags |= FILE_NOSTORE;
226  }
227 
228  if (flow->file_flags & FLOWFILE_NO_MAGIC_TS) {
229  flags |= FILE_NOMAGIC;
230  }
231 
232  if (flow->file_flags & FLOWFILE_NO_MD5_TS) {
233  flags |= FILE_NOMD5;
234  }
235 
236  if (flow->file_flags & FLOWFILE_NO_SHA1_TS) {
237  flags |= FILE_NOSHA1;
238  }
239 
240  if (flow->file_flags & FLOWFILE_NO_SHA256_TS) {
241  flags |= FILE_NOSHA256;
242  }
243  } else {
244  if (flow->file_flags & FLOWFILE_NO_STORE_TC) {
245  flags |= FILE_NOSTORE;
246  }
247 
248  if (flow->file_flags & FLOWFILE_NO_MAGIC_TC) {
249  flags |= FILE_NOMAGIC;
250  }
251 
252  if (flow->file_flags & FLOWFILE_NO_MD5_TC) {
253  flags |= FILE_NOMD5;
254  }
255 
256  if (flow->file_flags & FLOWFILE_NO_SHA1_TC) {
257  flags |= FILE_NOSHA1;
258  }
259 
260  if (flow->file_flags & FLOWFILE_NO_SHA256_TC) {
261  flags |= FILE_NOSHA256;
262  }
263  }
264  return flags;
265 }
266 
267 static int FileMagicSize(void)
268 {
269  /** \todo make this size configurable */
270  return 512;
271 }
272 
273 /**
274  * \brief get the size of the file data
275  *
276  * This doesn't reflect how much of the file we have in memory, just the
277  * total size of filedata so far.
278  */
279 uint64_t FileDataSize(const File *file)
280 {
281  if (file != NULL && file->sb != NULL) {
282  SCLogDebug("returning %"PRIu64,
283  file->sb->stream_offset + file->sb->buf_offset);
284  return file->sb->stream_offset + file->sb->buf_offset;
285  }
286  SCLogDebug("returning 0 (default)");
287  return 0;
288 }
289 
290 /**
291  * \brief get the size of the file
292  *
293  * This doesn't reflect how much of the file we have in memory, just the
294  * total size of file so far.
295  */
296 uint64_t FileTrackedSize(const File *file)
297 {
298  if (file != NULL) {
299  return file->size;
300  }
301  return 0;
302 }
303 
304 /** \brief test if file is ready to be pruned
305  *
306  * If a file is in the 'CLOSED' state, it means it has been processed
307  * completely by the pipeline in the correct direction. So we can
308  * prune it then.
309  *
310  * For other states, as well as for files we may not need to track
311  * until the close state, more specific checks are done.
312  *
313  * Also does house keeping within the file: move streaming buffer
314  * forward if possible.
315  *
316  * \retval 1 prune (free) this file
317  * \retval 0 file not ready to be freed
318  */
319 static int FilePruneFile(File *file)
320 {
321  SCEnter();
322 
323  /* file is done when state is closed+, logging/storing is done (if any) */
324  SCLogDebug("file->state %d. Is >= FILE_STATE_CLOSED: %s",
325  file->state, (file->state >= FILE_STATE_CLOSED) ? "yes" : "no");
326  if (file->state >= FILE_STATE_CLOSED) {
327  SCReturnInt(1);
328  }
329 
330 #ifdef HAVE_MAGIC
331  if (!(file->flags & FILE_NOMAGIC)) {
332  /* need magic but haven't set it yet, bail out */
333  if (file->magic == NULL)
334  SCReturnInt(0);
335  else
336  SCLogDebug("file->magic %s", file->magic);
337  } else {
338  SCLogDebug("file->flags & FILE_NOMAGIC == true");
339  }
340 #endif
341  uint64_t left_edge = FileDataSize(file);
342  if (file->flags & FILE_STORE) {
343  left_edge = MIN(left_edge,file->content_stored);
344  }
345  if (file->flags & FILE_USE_DETECT) {
346  left_edge = MIN(left_edge, file->content_inspected);
347 
348  /* if file has inspect window and min size set, we
349  * do some house keeping here */
350  if (file->inspect_window != 0 && file->inspect_min_size != 0) {
351  uint32_t window = file->inspect_window;
352  if (file->sb->stream_offset == 0)
353  window = MAX(window, file->inspect_min_size);
354 
355  uint64_t file_size = FileDataSize(file);
356  uint64_t data_size = file_size - file->sb->stream_offset;
357 
358  SCLogDebug("window %"PRIu32", file_size %"PRIu64", data_size %"PRIu64,
359  window, file_size, data_size);
360 
361  if (data_size > (window * 3)) {
362  left_edge = file_size - window;
363  SCLogDebug("file->content_inspected now %"PRIu64, left_edge);
364  file->content_inspected = left_edge;
365  }
366  }
367  }
368 
369  if (left_edge) {
370  StreamingBufferSlideToOffset(file->sb, left_edge);
371  }
372 
373  SCReturnInt(0);
374 }
375 
377 {
378  File *file = ffc->head;
379  File *prev = NULL;
380 
381  while (file) {
382  if (FilePruneFile(file) == 0) {
383  prev = file;
384  file = file->next;
385  continue;
386  }
387 
388  SCLogDebug("removing file %p", file);
389 
390  File *file_next = file->next;
391 
392  if (prev)
393  prev->next = file_next;
394  /* update head and tail */
395  if (file == ffc->head)
396  ffc->head = file_next;
397  if (file == ffc->tail)
398  ffc->tail = prev;
399 
400  FileFree(file);
401  file = file_next;
402  }
403 }
404 
405 /**
406  * \brief allocate a FileContainer
407  *
408  * \retval new newly allocated FileContainer
409  * \retval NULL error
410  */
412 {
413  FileContainer *new = SCMalloc(sizeof(FileContainer));
414  if (unlikely(new == NULL)) {
415  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating mem");
416  return NULL;
417  }
418  memset(new, 0, sizeof(FileContainer));
419  new->head = new->tail = NULL;
420  return new;
421 }
422 
423 /**
424  * \brief Recycle a FileContainer
425  *
426  * \param ffc FileContainer
427  */
429 {
430  if (ffc == NULL)
431  return;
432 
433  File *cur = ffc->head;
434  File *next = NULL;
435  for (;cur != NULL; cur = next) {
436  next = cur->next;
437  FileFree(cur);
438  }
439  ffc->head = ffc->tail = NULL;
440 }
441 
442 /**
443  * \brief Free a FileContainer
444  *
445  * \param ffc FileContainer
446  */
448 {
449  if (ffc == NULL)
450  return;
451 
452  File *ptr = ffc->head;
453  File *next = NULL;
454  for (;ptr != NULL; ptr = next) {
455  next = ptr->next;
456  FileFree(ptr);
457  }
458  ffc->head = ffc->tail = NULL;
459  SCFree(ffc);
460 }
461 
462 /**
463  * \brief Alloc a new File
464  *
465  * \param name character array containing the name (not a string)
466  * \param name_len length in bytes of the name
467  *
468  * \retval new File object or NULL on error
469  */
470 static File *FileAlloc(const uint8_t *name, uint16_t name_len)
471 {
472  File *new = SCMalloc(sizeof(File));
473  if (unlikely(new == NULL)) {
474  SCLogError(SC_ERR_MEM_ALLOC, "Error allocating mem");
475  return NULL;
476  }
477  memset(new, 0, sizeof(File));
478 
479  new->name = SCMalloc(name_len);
480  if (new->name == NULL) {
481  SCFree(new);
482  return NULL;
483  }
484 
485  new->name_len = name_len;
486  memcpy(new->name, name, name_len);
487 
488  new->sid_cnt = 0;
489  new->sid_max = 8;
490  /* SCMalloc() is allowed to fail here because sid well be checked later on */
491  new->sid = SCMalloc(sizeof(uint32_t) * new->sid_max);
492  if (new->sid == NULL)
493  new->sid_max = 0;
494 
495  return new;
496 }
497 
498 static void FileFree(File *ff)
499 {
500  if (ff == NULL)
501  return;
502 
503  if (ff->name != NULL)
504  SCFree(ff->name);
505  if (ff->sid != NULL)
506  SCFree(ff->sid);
507 #ifdef HAVE_MAGIC
508  /* magic returned by libmagic is strdup'd by MagicLookup. */
509  if (ff->magic != NULL)
510  SCFree(ff->magic);
511 #endif
512  if (ff->sb != NULL) {
513  StreamingBufferFree(ff->sb);
514  }
515 
516 #ifdef HAVE_NSS
517  if (ff->md5_ctx)
518  HASH_Destroy(ff->md5_ctx);
519  if (ff->sha1_ctx)
520  HASH_Destroy(ff->sha1_ctx);
521  if (ff->sha256_ctx)
522  HASH_Destroy(ff->sha256_ctx);
523 #endif
524  SCFree(ff);
525 }
526 
528 {
529  if (ffc->head == NULL || ffc->tail == NULL) {
530  ffc->head = ffc->tail = ff;
531  } else {
532  ffc->tail->next = ff;
533  ffc->tail = ff;
534  }
535 }
536 
537 /**
538  * \brief Tag a file for storing
539  *
540  * \param ff The file to store
541  */
542 int FileStore(File *ff)
543 {
544  ff->flags |= FILE_STORE;
545  SCReturnInt(0);
546 }
547 
548 /**
549  * \brief Set the TX id for a file
550  *
551  * \param ff The file to store
552  * \param txid the tx id
553  */
554 int FileSetTx(File *ff, uint64_t txid)
555 {
556  SCLogDebug("ff %p txid %"PRIu64, ff, txid);
557  if (ff != NULL)
558  ff->txid = txid;
559  SCReturnInt(0);
560 }
561 
563 {
564  if (ffc && ffc->tail) {
565  (void)FileSetTx(ffc->tail, tx_id);
566  }
567 }
568 
569 /**
570  * \brief check if we have stored enough
571  *
572  * \param ff file
573  *
574  * \retval 0 limit not reached yet
575  * \retval 1 limit reached
576  */
577 static int FileStoreNoStoreCheck(File *ff)
578 {
579  SCEnter();
580 
581  if (ff == NULL) {
582  SCReturnInt(0);
583  }
584 
585  if (ff->flags & FILE_NOSTORE) {
586  if (ff->state == FILE_STATE_OPENED &&
587  FileDataSize(ff) >= (uint64_t)FileMagicSize())
588  {
589  SCReturnInt(1);
590  }
591  }
592 
593  SCReturnInt(0);
594 }
595 
596 static int AppendData(File *file, const uint8_t *data, uint32_t data_len)
597 {
598  if (StreamingBufferAppendNoTrack(file->sb, data, data_len) != 0) {
599  SCReturnInt(-1);
600  }
601 
602 #ifdef HAVE_NSS
603  if (file->md5_ctx) {
604  HASH_Update(file->md5_ctx, data, data_len);
605  }
606  if (file->sha1_ctx) {
607  HASH_Update(file->sha1_ctx, data, data_len);
608  }
609  if (file->sha256_ctx) {
610  HASH_Update(file->sha256_ctx, data, data_len);
611  }
612 #endif
613  SCReturnInt(0);
614 }
615 
616 /** \internal
617  * \brief Store/handle a chunk of file data in the File structure
618  *
619  * \param ff the file
620  * \param data data chunk
621  * \param data_len data chunk len
622  *
623  * \retval 0 ok
624  * \retval -1 error
625  * \retval -2 no store for this file
626  */
627 static int FileAppendDataDo(File *ff, const uint8_t *data, uint32_t data_len)
628 {
629  SCEnter();
630 #ifdef DEBUG_VALIDATION
631  BUG_ON(ff == NULL);
632 #endif
633 
634  ff->size += data_len;
635 
636  if (ff->state != FILE_STATE_OPENED) {
637  if (ff->flags & FILE_NOSTORE) {
638  SCReturnInt(-2);
639  }
640  SCReturnInt(-1);
641  }
642 
643  if ((ff->flags & FILE_USE_DETECT) == 0 &&
644  FileStoreNoStoreCheck(ff) == 1) {
645 #ifdef HAVE_NSS
646  int hash_done = 0;
647  /* no storage but forced hashing */
648  if (ff->md5_ctx) {
649  HASH_Update(ff->md5_ctx, data, data_len);
650  hash_done = 1;
651  }
652  if (ff->sha1_ctx) {
653  HASH_Update(ff->sha1_ctx, data, data_len);
654  hash_done = 1;
655  }
656  if (ff->sha256_ctx) {
657  HASH_Update(ff->sha256_ctx, data, data_len);
658  hash_done = 1;
659  }
660 
661  if (hash_done)
662  SCReturnInt(0);
663 #endif
664  if (g_file_force_tracking || (!(ff->flags & FILE_NOTRACK)))
665  SCReturnInt(0);
666 
668  SCLogDebug("flowfile state transitioned to FILE_STATE_TRUNCATED");
669  SCReturnInt(-2);
670  }
671 
672  SCLogDebug("appending %"PRIu32" bytes", data_len);
673 
674  int r = AppendData(ff, data, data_len);
675  if (r != 0) {
676  ff->state = FILE_STATE_ERROR;
677  SCReturnInt(r);
678  }
679 
680  SCReturnInt(0);
681 }
682 
683 /**
684  * \brief Store/handle a chunk of file data in the File structure
685  * The last file in the FileContainer will be used.
686  *
687  * \param ffc FileContainer used to append to
688  * \param data data chunk
689  * \param data_len data chunk len
690  *
691  * \retval 0 ok
692  * \retval -1 error
693  * \retval -2 no store for this file
694  */
695 int FileAppendData(FileContainer *ffc, const uint8_t *data, uint32_t data_len)
696 {
697  SCEnter();
698 
699  if (ffc == NULL || ffc->tail == NULL || data == NULL || data_len == 0) {
700  SCReturnInt(-1);
701  }
702  int r = FileAppendDataDo(ffc->tail, data, data_len);
703  SCReturnInt(r);
704 }
705 
706 /**
707  * \brief Store/handle a chunk of file data in the File structure
708  * The file with 'track_id' in the FileContainer will be used.
709  *
710  * \param ffc FileContainer used to append to
711  * \param track_id id to lookup the file
712  * \param data data chunk
713  * \param data_len data chunk len
714  *
715  * \retval 0 ok
716  * \retval -1 error
717  * \retval -2 no store for this file
718  */
719 int FileAppendDataById(FileContainer *ffc, uint32_t track_id,
720  const uint8_t *data, uint32_t data_len)
721 {
722  SCEnter();
723 
724  if (ffc == NULL || ffc->tail == NULL || data == NULL || data_len == 0) {
725  SCReturnInt(-1);
726  }
727  File *ff = ffc->head;
728  for ( ; ff != NULL; ff = ff->next) {
729  if (track_id == ff->file_track_id) {
730  int r = FileAppendDataDo(ff, data, data_len);
731  SCReturnInt(r);
732  }
733  }
734  SCReturnInt(-1);
735 }
736 
737 /**
738  * \brief Store/handle a chunk of file data in the File structure
739  * The file with 'track_id' in the FileContainer will be used.
740  *
741  * \param ffc FileContainer used to append to
742  * \param track_id id to lookup the file
743  * \param data data chunk
744  * \param data_len data chunk len
745  *
746  * \retval 0 ok
747  * \retval -1 error
748  * \retval -2 no store for this file
749  */
750 int FileAppendGAPById(FileContainer *ffc, uint32_t track_id,
751  const uint8_t *data, uint32_t data_len)
752 {
753  SCEnter();
754 
755  if (ffc == NULL || ffc->tail == NULL || data == NULL || data_len == 0) {
756  SCReturnInt(-1);
757  }
758  File *ff = ffc->head;
759  for ( ; ff != NULL; ff = ff->next) {
760  if (track_id == ff->file_track_id) {
761  ff->flags |= FILE_HAS_GAPS;
764  SCLogDebug("FILE_HAS_GAPS set");
765 
766  int r = FileAppendDataDo(ff, data, data_len);
767  SCReturnInt(r);
768  }
769  }
770  SCReturnInt(-1);
771 }
772 
773 void FileSetInspectSizes(File *file, const uint32_t win, const uint32_t min)
774 {
775  file->inspect_window = win;
776  file->inspect_min_size = min;
777 }
778 
779 /**
780  * \brief Sets the offset range for a file.
781  *
782  * \param ffc the container
783  * \param start start offset
784  * \param end end offset
785  *
786  * \retval 0 ok
787  * \retval -1 error
788  */
789 int FileSetRange(FileContainer *ffc, uint64_t start, uint64_t end)
790 {
791  SCEnter();
792 
793  if (ffc == NULL || ffc->tail == NULL) {
794  SCReturnInt(-1);
795  }
796  ffc->tail->start = start;
797  ffc->tail->end = end;
798  SCReturnInt(0);
799 }
800 
801 /**
802  * \brief Open a new File
803  *
804  * \param ffc flow container
805  * \param sbcfg buffer config
806  * \param name filename character array
807  * \param name_len filename len
808  * \param data initial data
809  * \param data_len initial data len
810  * \param flags open flags
811  *
812  * \retval ff flowfile object
813  *
814  * \note filename is not a string, so it's not nul terminated.
815  */
816 static File *FileOpenFile(FileContainer *ffc, const StreamingBufferConfig *sbcfg,
817  const uint8_t *name, uint16_t name_len,
818  const uint8_t *data, uint32_t data_len, uint16_t flags)
819 {
820  SCEnter();
821 
822  //PrintRawDataFp(stdout, name, name_len);
823 
824  File *ff = FileAlloc(name, name_len);
825  if (ff == NULL) {
826  SCReturnPtr(NULL, "File");
827  }
828 
829  ff->sb = StreamingBufferInit(sbcfg);
830  if (ff->sb == NULL) {
831  FileFree(ff);
832  SCReturnPtr(NULL, "File");
833  }
834  SCLogDebug("ff->sb %p", ff->sb);
835 
836  if (flags & FILE_STORE || g_file_force_filestore) {
837  FileStore(ff);
838  } else if (flags & FILE_NOSTORE) {
839  SCLogDebug("not storing this file");
840  ff->flags |= FILE_NOSTORE;
841  }
842  if (flags & FILE_NOMAGIC) {
843  SCLogDebug("not doing magic for this file");
844  ff->flags |= FILE_NOMAGIC;
845  }
846  if (flags & FILE_NOMD5) {
847  SCLogDebug("not doing md5 for this file");
848  ff->flags |= FILE_NOMD5;
849  }
850  if (flags & FILE_NOSHA1) {
851  SCLogDebug("not doing sha1 for this file");
852  ff->flags |= FILE_NOSHA1;
853  }
854  if (flags & FILE_NOSHA256) {
855  SCLogDebug("not doing sha256 for this file");
856  ff->flags |= FILE_NOSHA256;
857  }
858  if (!g_detect_disabled && flags & FILE_USE_DETECT) {
859  SCLogDebug("considering content_inspect tracker when pruning");
860  ff->flags |= FILE_USE_DETECT;
861  }
862 
863 #ifdef HAVE_NSS
864  if (!(ff->flags & FILE_NOMD5) || g_file_force_md5) {
865  ff->md5_ctx = HASH_Create(HASH_AlgMD5);
866  if (ff->md5_ctx != NULL) {
867  HASH_Begin(ff->md5_ctx);
868  }
869  }
870  if (!(ff->flags & FILE_NOSHA1) || g_file_force_sha1) {
871  ff->sha1_ctx = HASH_Create(HASH_AlgSHA1);
872  if (ff->sha1_ctx != NULL) {
873  HASH_Begin(ff->sha1_ctx);
874  }
875  }
876  if (!(ff->flags & FILE_NOSHA256) || g_file_force_sha256) {
877  ff->sha256_ctx = HASH_Create(HASH_AlgSHA256);
878  if (ff->sha256_ctx != NULL) {
879  HASH_Begin(ff->sha256_ctx);
880  }
881  }
882 #endif
883 
884  ff->state = FILE_STATE_OPENED;
885  SCLogDebug("flowfile state transitioned to FILE_STATE_OPENED");
886 
887  ff->fd = -1;
888 
889  FileContainerAdd(ffc, ff);
890 
891  if (data != NULL) {
892  ff->size += data_len;
893  if (AppendData(ff, data, data_len) != 0) {
894  ff->state = FILE_STATE_ERROR;
895  SCReturnPtr(NULL, "File");
896  }
897  SCLogDebug("file size is now %"PRIu64, FileTrackedSize(ff));
898  }
899 
900  SCReturnPtr(ff, "File");
901 }
902 
903 /**
904  * \retval 0 ok
905  * \retval -1 failed */
907  uint32_t track_id, const uint8_t *name, uint16_t name_len,
908  const uint8_t *data, uint32_t data_len, uint16_t flags)
909 {
910  File *ff = FileOpenFile(ffc, sbcfg, name, name_len, data, data_len, flags);
911  if (ff == NULL)
912  return -1;
913 
914  ff->file_track_id = track_id;
915  return 0;
916 }
917 
918 int FileCloseFilePtr(File *ff, const uint8_t *data,
919  uint32_t data_len, uint16_t flags)
920 {
921  SCEnter();
922 
923  if (ff == NULL) {
924  SCReturnInt(-1);
925  }
926 
927  if (ff->state != FILE_STATE_OPENED) {
928  SCReturnInt(-1);
929  }
930 
931  if (data != NULL) {
932  ff->size += data_len;
933  if (ff->flags & FILE_NOSTORE) {
934 #ifdef HAVE_NSS
935  /* no storage but hashing */
936  if (ff->md5_ctx)
937  HASH_Update(ff->md5_ctx, data, data_len);
938  if (ff->sha1_ctx)
939  HASH_Update(ff->sha1_ctx, data, data_len);
940  if (ff->sha256_ctx)
941  HASH_Update(ff->sha256_ctx, data, data_len);
942 #endif
943  } else {
944  if (AppendData(ff, data, data_len) != 0) {
945  ff->state = FILE_STATE_ERROR;
946  SCReturnInt(-1);
947  }
948  }
949  }
950 
951  if ((flags & FILE_TRUNCATED) || (ff->flags & FILE_HAS_GAPS)) {
953  SCLogDebug("flowfile state transitioned to FILE_STATE_TRUNCATED");
954 
955  if (flags & FILE_NOSTORE) {
956  SCLogDebug("not storing this file");
957  ff->flags |= FILE_NOSTORE;
958  } else {
959 #ifdef HAVE_NSS
960  if (g_file_force_sha256 && ff->sha256_ctx) {
961  FileEndSha256(ff);
962  }
963 #endif
964  }
965  } else {
966  ff->state = FILE_STATE_CLOSED;
967  SCLogDebug("flowfile state transitioned to FILE_STATE_CLOSED");
968 
969 #ifdef HAVE_NSS
970  if (ff->md5_ctx) {
971  unsigned int len = 0;
972  HASH_End(ff->md5_ctx, ff->md5, &len, sizeof(ff->md5));
973  ff->flags |= FILE_MD5;
974  }
975  if (ff->sha1_ctx) {
976  unsigned int len = 0;
977  HASH_End(ff->sha1_ctx, ff->sha1, &len, sizeof(ff->sha1));
978  ff->flags |= FILE_SHA1;
979  }
980  if (ff->sha256_ctx) {
981  FileEndSha256(ff);
982  }
983 #endif
984  }
985 
986  SCReturnInt(0);
987 }
988 
989 /**
990  * \brief Close a File
991  *
992  * \param ffc the container
993  * \param data final data if any
994  * \param data_len data len if any
995  * \param flags flags
996  *
997  * \retval 0 ok
998  * \retval -1 error
999  */
1000 int FileCloseFile(FileContainer *ffc, const uint8_t *data,
1001  uint32_t data_len, uint16_t flags)
1002 {
1003  SCEnter();
1004 
1005  if (ffc == NULL || ffc->tail == NULL) {
1006  SCReturnInt(-1);
1007  }
1008 
1009  if (FileCloseFilePtr(ffc->tail, data, data_len, flags) == -1) {
1010  SCReturnInt(-1);
1011  }
1012 
1013  SCReturnInt(0);
1014 }
1015 
1016 int FileCloseFileById(FileContainer *ffc, uint32_t track_id,
1017  const uint8_t *data, uint32_t data_len, uint16_t flags)
1018 {
1019  SCEnter();
1020 
1021  if (ffc == NULL || ffc->tail == NULL) {
1022  SCReturnInt(-1);
1023  }
1024 
1025  File *ff = ffc->head;
1026  for ( ; ff != NULL; ff = ff->next) {
1027  if (track_id == ff->file_track_id) {
1028  int r = FileCloseFilePtr(ff, data, data_len, flags);
1029  SCReturnInt(r);
1030  }
1031  }
1032  SCReturnInt(-1);
1033 }
1034 
1035 /**
1036  * \brief disable file storage for a flow
1037  *
1038  * \param f *LOCKED* flow
1039  * \param direction flow direction
1040  */
1041 void FileDisableStoring(Flow *f, uint8_t direction)
1042 {
1043  File *ptr = NULL;
1044 
1045  SCEnter();
1046 
1048 
1049  if (direction == STREAM_TOSERVER)
1051  else
1053 
1054  FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, f->alstate, direction);
1055  if (ffc != NULL) {
1056  for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) {
1057  /* if we're already storing, we'll continue */
1058  if (!(ptr->flags & FILE_STORE)) {
1059  SCLogDebug("not storing this file");
1060  ptr->flags |= FILE_NOSTORE;
1061  }
1062  }
1063  }
1064  SCReturn;
1065 }
1066 
1067 /**
1068  * \brief disable file magic lookups for this flow
1069  *
1070  * \param f *LOCKED* flow
1071  * \param direction flow direction
1072  */
1073 void FileDisableMagic(Flow *f, uint8_t direction)
1074 {
1075  File *ptr = NULL;
1076 
1077  SCEnter();
1078 
1080 
1081  if (direction == STREAM_TOSERVER)
1083  else
1085 
1086  FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, f->alstate, direction);
1087  if (ffc != NULL) {
1088  for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) {
1089  SCLogDebug("disabling magic for file %p from direction %s",
1090  ptr, direction == STREAM_TOSERVER ? "toserver":"toclient");
1091  ptr->flags |= FILE_NOMAGIC;
1092  }
1093  }
1094 
1095  SCReturn;
1096 }
1097 
1098 /**
1099  * \brief disable file md5 calc for this flow
1100  *
1101  * \param f *LOCKED* flow
1102  * \param direction flow direction
1103  */
1104 void FileDisableMd5(Flow *f, uint8_t direction)
1105 {
1106  File *ptr = NULL;
1107 
1108  SCEnter();
1109 
1111 
1112  if (direction == STREAM_TOSERVER)
1114  else
1116 
1117  FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, f->alstate, direction);
1118  if (ffc != NULL) {
1119  for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) {
1120  SCLogDebug("disabling md5 for file %p from direction %s",
1121  ptr, direction == STREAM_TOSERVER ? "toserver":"toclient");
1122  ptr->flags |= FILE_NOMD5;
1123 
1124 #ifdef HAVE_NSS
1125  /* destroy any ctx we may have so far */
1126  if (ptr->md5_ctx != NULL) {
1127  HASH_Destroy(ptr->md5_ctx);
1128  ptr->md5_ctx = NULL;
1129  }
1130 #endif
1131  }
1132  }
1133 
1134  SCReturn;
1135 }
1136 
1137 /**
1138  * \brief disable file sha1 calc for this flow
1139  *
1140  * \param f *LOCKED* flow
1141  * \param direction flow direction
1142 */
1143 void FileDisableSha1(Flow *f, uint8_t direction)
1144 {
1145  File *ptr = NULL;
1146 
1147  SCEnter();
1148 
1150 
1151  if (direction == STREAM_TOSERVER)
1153  else
1155 
1156  FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, f->alstate, direction);
1157  if (ffc != NULL) {
1158  for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) {
1159  SCLogDebug("disabling sha1 for file %p from direction %s",
1160  ptr, direction == STREAM_TOSERVER ? "toserver":"toclient");
1161  ptr->flags |= FILE_NOSHA1;
1162 
1163 #ifdef HAVE_NSS
1164  /* destroy any ctx we may have so far */
1165  if (ptr->sha1_ctx != NULL) {
1166  HASH_Destroy(ptr->sha1_ctx);
1167  ptr->sha1_ctx = NULL;
1168  }
1169 #endif
1170  }
1171  }
1172 
1173  SCReturn;
1174 }
1175 
1176 /**
1177  * \brief disable file sha256 calc for this flow
1178  *
1179  * \param f *LOCKED* flow
1180  * \param direction flow direction
1181  */
1182 void FileDisableSha256(Flow *f, uint8_t direction)
1183 {
1184  File *ptr = NULL;
1185 
1186  SCEnter();
1187 
1189 
1190  if (direction == STREAM_TOSERVER)
1192  else
1194 
1195  FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, f->alstate, direction);
1196  if (ffc != NULL) {
1197  for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) {
1198  SCLogDebug("disabling sha256 for file %p from direction %s",
1199  ptr, direction == STREAM_TOSERVER ? "toserver":"toclient");
1200  ptr->flags |= FILE_NOSHA256;
1201 
1202 #ifdef HAVE_NSS
1203  /* destroy any ctx we may have so far */
1204  if (ptr->sha256_ctx != NULL) {
1205  HASH_Destroy(ptr->sha256_ctx);
1206  ptr->sha256_ctx = NULL;
1207  }
1208 #endif
1209  }
1210  }
1211 
1212  SCReturn;
1213 }
1214 
1215 /**
1216  * \brief disable file size tracking for this flow
1217  *
1218  * \param f *LOCKED* flow
1219  * \param direction flow direction
1220  */
1221 void FileDisableFilesize(Flow *f, uint8_t direction)
1222 {
1223  File *ptr = NULL;
1224 
1225  SCEnter();
1226 
1228 
1229  if (direction == STREAM_TOSERVER)
1231  else
1233 
1234  FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, f->alstate, direction);
1235  if (ffc != NULL) {
1236  for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) {
1237  SCLogDebug("disabling size tracking for file %p from direction %s",
1238  ptr, direction == STREAM_TOSERVER ? "toserver":"toclient");
1239  ptr->flags |= FILE_NOTRACK;
1240  }
1241  }
1242 
1243  SCReturn;
1244 }
1245 
1246 
1247 /**
1248  * \brief set no store flag, close file if needed
1249  *
1250  * \param ff file
1251  */
1252 static void FileDisableStoringForFile(File *ff)
1253 {
1254  SCEnter();
1255 
1256  if (ff == NULL) {
1257  SCReturn;
1258  }
1259 
1260  SCLogDebug("not storing this file");
1261  ff->flags |= FILE_NOSTORE;
1262 
1263  if (ff->state == FILE_STATE_OPENED && FileDataSize(ff) >= (uint64_t)FileMagicSize()) {
1264  if (g_file_force_md5 == 0 && g_file_force_sha1 == 0 && g_file_force_sha256 == 0
1265  && g_file_force_tracking == 0) {
1266  (void)FileCloseFilePtr(ff, NULL, 0,
1268  }
1269  }
1270 }
1271 
1272 /**
1273  * \brief disable file storing for files in a transaction
1274  *
1275  * \param f *LOCKED* flow
1276  * \param direction flow direction
1277  * \param tx_id transaction id
1278  */
1279 void FileDisableStoringForTransaction(Flow *f, uint8_t direction, uint64_t tx_id)
1280 {
1281  File *ptr = NULL;
1282 
1284 
1285  SCEnter();
1286 
1287  FileContainer *ffc = AppLayerParserGetFiles(f->proto, f->alproto, f->alstate, direction);
1288  if (ffc != NULL) {
1289  for (ptr = ffc->head; ptr != NULL; ptr = ptr->next) {
1290  if (ptr->txid == tx_id) {
1291  if (ptr->flags & FILE_STORE) {
1292  /* weird, already storing -- let it continue*/
1293  SCLogDebug("file is already being stored");
1294  } else {
1295  FileDisableStoringForFile(ptr);
1296  }
1297  }
1298  }
1299  }
1300 
1301  SCReturn;
1302 }
1303 
1304 /**
1305  * \brief flag a file with id "file_id" to be stored.
1306  *
1307  * \param fc file store
1308  * \param file_id the file's id
1309  */
1310 void FileStoreFileById(FileContainer *fc, uint32_t file_id)
1311 {
1312  File *ptr = NULL;
1313 
1314  SCEnter();
1315 
1316  if (fc != NULL) {
1317  for (ptr = fc->head; ptr != NULL; ptr = ptr->next) {
1318  if (ptr->file_track_id == file_id) {
1319  FileStore(ptr);
1320  }
1321  }
1322  }
1323 }
1324 
1326 {
1327  File *ptr = NULL;
1328 
1329  SCEnter();
1330 
1331  if (fc != NULL) {
1332  for (ptr = fc->head; ptr != NULL; ptr = ptr->next) {
1333  if (ptr->txid == tx_id) {
1334  FileStore(ptr);
1335  }
1336  }
1337  }
1338 }
1339 
1341 {
1342  File *ptr = NULL;
1343 
1344  SCEnter();
1345 
1346  if (fc != NULL) {
1347  for (ptr = fc->head; ptr != NULL; ptr = ptr->next) {
1348  FileStore(ptr);
1349  }
1350  }
1351 }
1352 
1354 {
1355  File *ptr = NULL;
1356 
1357  SCEnter();
1358 
1359  if (fc != NULL) {
1360  for (ptr = fc->head; ptr != NULL; ptr = ptr->next) {
1361  if (ptr->state == FILE_STATE_OPENED) {
1362  FileCloseFilePtr(ptr, NULL, 0, FILE_TRUNCATED);
1363  }
1364  }
1365  }
1366 }
1367 
1368 /**
1369  * \brief Finish the SHA256 calculation.
1370  */
1371 #ifdef HAVE_NSS
1372 static void FileEndSha256(File *ff)
1373 {
1374  if (!(ff->flags & FILE_SHA256) && ff->sha256_ctx) {
1375  unsigned int len = 0;
1376  HASH_End(ff->sha256_ctx, ff->sha256, &len, sizeof(ff->sha256));
1377  ff->flags |= FILE_SHA256;
1378  }
1379 }
1380 #endif
int g_detect_disabled
Definition: suricata.c:218
uint16_t flags
void FileDisableStoringForTransaction(Flow *f, uint8_t direction, uint64_t tx_id)
disable file storing for files in a transaction
Definition: util-file.c:1279
#define SCLogDebug(...)
Definition: util-debug.h:335
#define MAX(x, y)
StreamingBuffer * StreamingBufferInit(const StreamingBufferConfig *cfg)
#define TAILQ_FOREACH(var, head, field)
Definition: queue.h:350
struct HtpBodyChunk_ * next
int FileForceSha256(void)
Definition: util-file.c:147
TcpStreamCnf stream_config
Definition: stream-tcp.h:106
#define BUG_ON(x)
uint8_t proto
Definition: flow.h:344
FileContainer * FileContainerAlloc(void)
allocate a FileContainer
Definition: util-file.c:411
#define FLOWFILE_NO_SHA256_TS
Definition: flow.h:126
#define unlikely(expr)
Definition: util-optimize.h:35
#define FILE_SHA256
Definition: util-file.h:43
uint64_t size
Definition: util-file.h:89
void FileDisableFilesize(Flow *f, uint8_t direction)
disable file size tracking for this flow
Definition: util-file.c:1221
void FileDisableSha1(Flow *f, uint8_t direction)
disable file sha1 calc for this flow
Definition: util-file.c:1143
void FileDisableMd5(Flow *f, uint8_t direction)
disable file md5 calc for this flow
Definition: util-file.c:1104
uint64_t FileDataSize(const File *file)
get the size of the file data
Definition: util-file.c:279
#define FILE_NOTRACK
Definition: util-file.h:48
#define MIN(x, y)
uint64_t content_inspected
Definition: util-file.h:86
#define FILE_STORE
Definition: util-file.h:46
#define FILE_NOMAGIC
Definition: util-file.h:37
int fd
Definition: util-file.h:71
char * val
Definition: conf.h:34
void FileContainerSetTx(FileContainer *ffc, uint64_t tx_id)
Definition: util-file.c:562
ConfNode * ConfNodeLookupChild(const ConfNode *node, const char *name)
Lookup a child configuration node by name.
Definition: conf.c:815
struct File_ * next
Definition: util-file.h:77
int FileCloseFileById(FileContainer *ffc, uint32_t track_id, const uint8_t *data, uint32_t data_len, uint16_t flags)
Definition: util-file.c:1016
void FileReassemblyDepthEnable(uint32_t size)
Definition: util-file.c:118
StreamingBuffer * sb
Definition: util-file.h:67
void FileForceSha1Enable(void)
Definition: util-file.c:103
int FileForceMd5(void)
Definition: util-file.c:137
#define FILE_NOSHA1
Definition: util-file.h:40
uint32_t inspect_min_size
Definition: util-file.h:91
void FileForceTrackingEnable(void)
Definition: util-file.c:152
uint64_t start
Definition: util-file.h:92
#define FLOWFILE_NO_MAGIC_TS
Definition: flow.h:111
uint32_t FileReassemblyDepth(void)
Definition: util-file.c:124
void * alstate
Definition: flow.h:438
#define FLOWFILE_NO_MD5_TS
Definition: flow.h:118
void StreamingBufferFree(StreamingBuffer *sb)
#define FLOWFILE_NO_MAGIC_TC
Definition: flow.h:112
const char * ConfNodeLookupChildValue(const ConfNode *node, const char *name)
Lookup the value of a child configuration node by name.
Definition: conf.c:843
int FileStore(File *ff)
Tag a file for storing.
Definition: util-file.c:542
uint16_t flags
Definition: util-file.h:64
void FileStoreAllFilesForTx(FileContainer *fc, uint64_t tx_id)
Definition: util-file.c:1325
#define FLOWFILE_NO_SIZE_TS
Definition: flow.h:130
uint64_t end
Definition: util-file.h:93
uint32_t * sid
Definition: util-file.h:95
void FileStoreFileById(FileContainer *fc, uint32_t file_id)
flag a file with id "file_id" to be stored.
Definition: util-file.c:1310
void FileDisableMagic(Flow *f, uint8_t direction)
disable file magic lookups for this flow
Definition: util-file.c:1073
void StreamingBufferSlideToOffset(StreamingBuffer *sb, uint64_t offset)
slide to absolute offset
#define FILE_HAS_GAPS
Definition: util-file.h:50
#define SCLogError(err_code,...)
Macro used to log ERROR messages.
Definition: util-debug.h:294
void FileForceHashParseCfg(ConfNode *conf)
Function to parse forced file hashing configuration.
Definition: util-file.c:160
void FileContainerFree(FileContainer *ffc)
Free a FileContainer.
Definition: util-file.c:447
void FileForceMagicEnable(void)
Definition: util-file.c:93
#define DEBUG_ASSERT_FLOW_LOCKED(f)
uint64_t txid
Definition: util-file.h:68
#define SCEnter(...)
Definition: util-debug.h:337
int FileSetRange(FileContainer *ffc, uint64_t start, uint64_t end)
Sets the offset range for a file.
Definition: util-file.c:789
#define FLOWFILE_NO_MD5_TC
Definition: flow.h:119
void FileForceFilestoreEnable(void)
Definition: util-file.c:88
void FileSetInspectSizes(File *file, const uint32_t win, const uint32_t min)
Definition: util-file.c:773
void FileDisableStoring(Flow *f, uint8_t direction)
disable file storage for a flow
Definition: util-file.c:1041
#define SCReturnInt(x)
Definition: util-debug.h:341
#define FILE_MD5
Definition: util-file.h:39
void FilePrune(FileContainer *ffc)
Definition: util-file.c:376
void FileStoreAllFiles(FileContainer *fc)
Definition: util-file.c:1340
uint32_t inspect_window
Definition: util-file.h:90
#define SCLogWarning(err_code,...)
Macro used to log WARNING messages.
Definition: util-debug.h:281
uint32_t reassembly_depth
Definition: stream-tcp.h:60
int ConfValIsTrue(const char *val)
Check if a value is true.
Definition: conf.c:566
#define FILE_SHA1
Definition: util-file.h:41
int FileForceFilestore(void)
Definition: util-file.c:113
int FileForceMagic(void)
Definition: util-file.c:132
Definition: conf.h:32
#define FILE_NOSHA256
Definition: util-file.h:42
#define SCMalloc(a)
Definition: util-mem.h:222
int FileAppendGAPById(FileContainer *ffc, uint32_t track_id, const uint8_t *data, uint32_t data_len)
Store/handle a chunk of file data in the File structure The file with &#39;track_id&#39; in the FileContainer...
Definition: util-file.c:750
#define FILE_USE_DETECT
Definition: util-file.h:49
void FileContainerAdd(FileContainer *ffc, File *ff)
Definition: util-file.c:527
void FileForceSha256Enable(void)
Definition: util-file.c:108
#define SCLogInfo(...)
Macro used to log INFORMATIONAL messages.
Definition: util-debug.h:254
void FileContainerRecycle(FileContainer *ffc)
Recycle a FileContainer.
Definition: util-file.c:428
#define SCFree(a)
Definition: util-mem.h:322
#define FLOWFILE_NO_SHA1_TS
Definition: flow.h:122
#define FLOWFILE_NO_STORE_TS
Definition: flow.h:115
uint16_t tx_id
#define FLOWFILE_NO_SIZE_TC
Definition: flow.h:131
#define STREAM_TOSERVER
Definition: stream.h:31
#define SCReturnPtr(x, type)
Definition: util-debug.h:353
FileState state
Definition: util-file.h:66
int FileOpenFileWithId(FileContainer *ffc, const StreamingBufferConfig *sbcfg, uint32_t track_id, const uint8_t *name, uint16_t name_len, const uint8_t *data, uint32_t data_len, uint16_t flags)
Open a new File.
Definition: util-file.c:906
int StreamingBufferAppendNoTrack(StreamingBuffer *sb, const uint8_t *data, uint32_t data_len)
add data w/o tracking a segment
int FileCloseFile(FileContainer *ffc, const uint8_t *data, uint32_t data_len, uint16_t flags)
Close a File.
Definition: util-file.c:1000
int FileSetTx(File *ff, uint64_t txid)
Set the TX id for a file.
Definition: util-file.c:554
uint16_t FileFlowToFlags(const Flow *flow, uint8_t direction)
Definition: util-file.c:219
uint64_t content_stored
Definition: util-file.h:88
uint32_t file_track_id
Definition: util-file.h:69
#define FILE_TRUNCATED
Definition: util-file.h:36
int FileForceSha1(void)
Definition: util-file.c:142
int FileAppendDataById(FileContainer *ffc, uint32_t track_id, const uint8_t *data, uint32_t data_len)
Store/handle a chunk of file data in the File structure The file with &#39;track_id&#39; in the FileContainer...
Definition: util-file.c:719
uint64_t FileTrackedSize(const File *file)
get the size of the file
Definition: util-file.c:296
void FileForceMd5Enable(void)
Definition: util-file.c:98
#define SCReturn
Definition: util-debug.h:339
#define FLOWFILE_NO_SHA1_TC
Definition: flow.h:123
uint8_t len
void FileDisableSha256(Flow *f, uint8_t direction)
disable file sha256 calc for this flow
Definition: util-file.c:1182
uint16_t file_flags
Definition: flow.h:381
AppProto alproto
application level protocol
Definition: flow.h:409
FileContainer * AppLayerParserGetFiles(uint8_t ipproto, AppProto alproto, void *alstate, uint8_t direction)
int FileAppendData(FileContainer *ffc, const uint8_t *data, uint32_t data_len)
Store/handle a chunk of file data in the File structure The last file in the FileContainer will be us...
Definition: util-file.c:695
struct SCLogConfig_ SCLogConfig
Holds the config state used by the logging api.
#define FLOWFILE_NO_SHA256_TC
Definition: flow.h:127
#define FILE_NOSTORE
Definition: util-file.h:45
#define FLOWFILE_NO_STORE_TC
Definition: flow.h:116
int FileCloseFilePtr(File *ff, const uint8_t *data, uint32_t data_len, uint16_t flags)
Definition: util-file.c:918
Flow data structure.
Definition: flow.h:325
uint8_t * name
Definition: util-file.h:73
void FileTruncateAllOpenFiles(FileContainer *fc)
Definition: util-file.c:1353
#define FILE_NOMD5
Definition: util-file.h:38