"Fossies" - the Fresh Open Source Software Archive

Member "snort-2.9.17/src/file-process/libs/file_lib.c" (16 Oct 2020, 11740 Bytes) of package /linux/misc/snort-2.9.17.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "file_lib.c" see the Fossies "Dox" file reference documentation and the latest Fossies "Diffs" side-by-side code changes report: 2.9.16.1_vs_2.9.17.

    1 /*
    2  **
    3  **
    4  **  Copyright (C) 2014-2020 Cisco and/or its affiliates. All rights reserved.
    5  **  Copyright (C) 2012-2013 Sourcefire, Inc.
    6  **
    7  **  This program is free software; you can redistribute it and/or modify
    8  **  it under the terms of the GNU General Public License Version 2 as
    9  **  published by the Free Software Foundation.  You may not use, modify or
   10  **  distribute this program under any other version of the GNU General
   11  **  Public License.
   12  **
   13  **  This program is distributed in the hope that it will be useful,
   14  **  but WITHOUT ANY WARRANTY; without even the implied warranty of
   15  **  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   16  **  GNU General Public License for more details.
   17  **
   18  **  You should have received a copy of the GNU General Public License
   19  **  along with this program; if not, write to the Free Software
   20  **  Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
   21  **
   22  **  Author(s):  Hui Cao <hcao@sourcefire.com>
   23  **
   24  **  NOTES
   25  **  5.25.12 - Initial Source Code. Hcao
   26  */
   27 
   28 #ifdef HAVE_CONFIG_H
   29 #include <config.h>
   30 #endif
   31 
   32 #include "sf_types.h"
   33 #include "file_lib.h"
   34 #include "file_identifier.h"
   35 #include "file_config.h"
   36 #include <sys/types.h>
   37 #include <stdio.h>
   38 #include <stdlib.h>
   39 #include <string.h>
   40 #include "sf_sechash.h"
   41 
   42 #include "util.h"
   43 #include "file_capture.h"
   44 
   45 static inline int get_data_size_from_depth_limit(FileContext* context, FileProcessType type, int data_size)
   46 {
   47     FileConfig *file_config =  (FileConfig *)context->file_config;
   48     uint64_t max_depth;
   49 
   50     if (!file_config)
   51         return data_size;
   52 
   53     switch(type)
   54     {
   55     case SNORT_FILE_TYPE_ID:
   56         max_depth = file_config->file_type_depth;
   57         break;
   58     case SNORT_FILE_SHA256:
   59         max_depth = file_config->file_signature_depth;
   60         break;
   61     default:
   62         return data_size;
   63     }
   64 
   65     if (context->processed_bytes > max_depth)
   66         data_size = -1;
   67     else if (context->processed_bytes + data_size > max_depth)
   68         data_size = (int)(max_depth - context->processed_bytes);
   69 
   70     return data_size;
   71 
   72 }
   73 
   74 /* stop file type identification */
   75 static inline void _finalize_file_type (FileContext* context)
   76 {
   77     if (SNORT_FILE_TYPE_CONTINUE ==  context->file_type_id)
   78         context->file_type_id = SNORT_FILE_TYPE_UNKNOWN;
   79     context->file_type_context = NULL;
   80 }
   81 /*
   82  * Main File type processing function
   83  * We use file type context to decide file type across packets
   84  *
   85  * File type detection is completed either when
   86  * 1) file is completed or
   87  * 2) file type depth is reached or
   88  * 3) file magics are exhausted in depth
   89  *
   90  */
   91 void file_type_id( FileContext* context, uint8_t* file_data,
   92         int size, FilePosition position)
   93 {
   94     int data_size;
   95 
   96     if (!context)
   97         return;
   98 
   99     /* file type already found and no magics to continue*/
  100     if (context->file_type_id && !context->file_type_context)
  101         return;
  102 
  103     /* Check whether file type depth is reached*/
  104     data_size = get_data_size_from_depth_limit(context, SNORT_FILE_TYPE_ID, size);
  105 
  106     if (data_size < 0)
  107     {
  108         _finalize_file_type(context);
  109         return;
  110     }
  111 
  112     file_identifiers_match(file_data, data_size, context);
  113 
  114     /* Check whether file transfer is done or type depth is reached*/
  115     if ( (position == SNORT_FILE_END)  || (position == SNORT_FILE_FULL) ||
  116          (data_size != size) )
  117     {
  118         _finalize_file_type(context);
  119     }
  120 }
  121 
  122 void file_signature_sha256(FileContext* context, uint8_t* file_data,
  123         int size, FilePosition position)
  124 {
  125     int data_size;
  126 
  127     if (!context)
  128         return;
  129 
  130     data_size = get_data_size_from_depth_limit(context, SNORT_FILE_SHA256, size);
  131 
  132     if (data_size != size)
  133     {
  134         context->file_state.sig_state = FILE_SIG_DEPTH_FAIL;
  135         return;
  136     }
  137 
  138     switch (position)
  139     {
  140     case SNORT_FILE_START:
  141         if (!context->file_signature_context)
  142             context->file_signature_context = SnortAlloc(sizeof(SHA256CONTEXT));
  143         SHA256INIT((SHA256CONTEXT *)context->file_signature_context);
  144         SHA256UPDATE((SHA256CONTEXT *)context->file_signature_context, file_data, data_size);
  145         if(context->file_state.sig_state == FILE_SIG_FLUSH)
  146         {
  147             static uint8_t file_signature_context_backup[sizeof(SHA256CONTEXT)];
  148             context->sha256 = SnortAlloc(SHA256_HASH_SIZE);
  149             memcpy(file_signature_context_backup, context->file_signature_context, sizeof(SHA256CONTEXT));
  150 
  151             SHA256FINAL(context->sha256, (SHA256CONTEXT *)context->file_signature_context);
  152             memcpy(context->file_signature_context, file_signature_context_backup, sizeof(SHA256CONTEXT));
  153         }
  154         break;
  155     case SNORT_FILE_MIDDLE:
  156         if (!context->file_signature_context)
  157             context->file_signature_context = SnortAlloc(sizeof(SHA256CONTEXT));
  158         SHA256UPDATE((SHA256CONTEXT *)context->file_signature_context, file_data, data_size);
  159         if(context->file_state.sig_state == FILE_SIG_FLUSH)
  160         {
  161             static uint8_t file_signature_context_backup[sizeof(SHA256CONTEXT)];
  162             if(!context->sha256)
  163                 context->sha256 = SnortAlloc(SHA256_HASH_SIZE);
  164             memcpy(file_signature_context_backup, context->file_signature_context, sizeof(SHA256CONTEXT));
  165 
  166             SHA256FINAL(context->sha256, (SHA256CONTEXT *)context->file_signature_context);
  167             memcpy(context->file_signature_context, file_signature_context_backup, sizeof(SHA256CONTEXT));
  168         }
  169         break;
  170     case SNORT_FILE_END:
  171         if (!context->file_signature_context)
  172             context->file_signature_context = SnortAlloc(sizeof(SHA256CONTEXT));
  173         if (context->processed_bytes == 0)
  174             SHA256INIT((SHA256CONTEXT *)context->file_signature_context);
  175         SHA256UPDATE((SHA256CONTEXT *)context->file_signature_context, file_data, data_size);
  176         if(!context->sha256)
  177             context->sha256 = SnortAlloc(SHA256_HASH_SIZE);
  178         SHA256FINAL(context->sha256, (SHA256CONTEXT *)context->file_signature_context);
  179         context->file_state.sig_state = FILE_SIG_DONE;
  180         break;
  181     case SNORT_FILE_FULL:
  182         if (!context->file_signature_context)
  183             context->file_signature_context = SnortAlloc(sizeof (SHA256CONTEXT));
  184         SHA256INIT((SHA256CONTEXT *)context->file_signature_context);
  185         SHA256UPDATE((SHA256CONTEXT *)context->file_signature_context, file_data, data_size);
  186         if(!context->sha256)
  187             context->sha256 = SnortAlloc(SHA256_HASH_SIZE);
  188         SHA256FINAL(context->sha256, (SHA256CONTEXT *)context->file_signature_context);
  189         context->file_state.sig_state = FILE_SIG_DONE;
  190         break;
  191     default:
  192         break;
  193     }
  194 }
  195 
  196 /*File context management*/
  197 
  198 FileContext *file_context_create(void)
  199 {
  200     FileContext *context = (FileContext *)SnortAlloc(sizeof(*context));
  201     return (context);
  202 }
  203 
  204 static inline void cleanDynamicContext (FileContext *context)
  205 {
  206     if (context->file_signature_context)
  207         free(context->file_signature_context);
  208     if(context->sha256)
  209         free(context->sha256);
  210     if(context->file_capture)
  211         file_capture_stop(context);
  212     if(context->file_name && context->file_name_saved)
  213         free(context->file_name);
  214 }
  215 
  216 void file_context_reset(FileContext *context)
  217 {
  218     cleanDynamicContext(context);
  219     memset(context, 0, sizeof(*context));
  220 
  221 }
  222 
  223 void file_context_free(void *ctx)
  224 {
  225     FileContext *context = (FileContext *)ctx;
  226     if (!context || context->attached_file_entry)
  227         return;
  228     cleanDynamicContext(context);
  229     free(context);
  230 }
  231 
  232 /*File properties*/
  233 /*Only set the pointer for performance, no deep copy*/
  234 void file_name_set (FileContext *context, uint8_t *file_name, uint32_t name_size,
  235         bool save_in_context)
  236 {
  237     uint8_t *name = file_name;
  238     if (!context)
  239     {
  240         FILE_ERROR("Failed to set file name: no context");
  241         return;
  242     }
  243     if (save_in_context)
  244     {
  245         if (context->file_name && context->file_name_saved)
  246             free(context->file_name);
  247         name = SnortAlloc(name_size);
  248         memcpy(name, file_name, name_size);
  249         context->file_name_saved = true;
  250     }
  251     context->file_name = name;
  252     context->file_name_size = name_size;
  253 }
  254 
  255 /* Return 1: file name available,
  256  *        0: file name is unavailable
  257  */
  258 
  259 int file_name_get (FileContext *context, uint8_t **file_name, uint32_t *name_size)
  260 {
  261     if (!context)
  262     {
  263         FILE_ERROR("Failed to fetch file name: no context");
  264         return 0;
  265     }
  266     if (file_name)
  267         *file_name = context->file_name;
  268     else
  269     {
  270         FILE_ERROR("Failed to fetch file name: name parameter NULL");
  271         return 0;
  272     }
  273     if (name_size)
  274         *name_size = context->file_name_size;
  275     else
  276     {
  277         FILE_ERROR("Failed to fetch file name: size parameter NULL");
  278         return 0;
  279     }
  280     FILE_DEBUG("File name fetched from context: %s, size %d",(char*)(*file_name),*name_size);
  281     return 1;
  282 }
  283 
  284 void file_size_set (FileContext *context, uint64_t file_size)
  285 {
  286     if (!context)
  287     {
  288         FILE_ERROR("Failed to set file size: no context");
  289         return;
  290     }
  291     context->file_size = file_size;
  292 
  293 }
  294 
  295 uint64_t file_size_get (FileContext *context)
  296 {
  297     if (!context)
  298     {
  299         FILE_ERROR("Failed to fetch file size: no context");
  300         return 0;
  301     }
  302     FILE_DEBUG("File size fetched from context: %d",context->file_size);
  303     return (context->file_size);
  304 }
  305 
  306 void file_direction_set (FileContext *context, bool upload)
  307 {
  308     if (!context)
  309         return;
  310     context->upload = upload;
  311 
  312 }
  313 
  314 bool file_direction_get (FileContext *context)
  315 {
  316     if (!context)
  317         return false;
  318     return (context->upload);
  319 
  320 }
  321 
  322 void file_sig_sha256_set (FileContext *context, uint8_t * signature)
  323 {
  324     if (!context)
  325         return;
  326     context->sha256= signature;
  327 }
  328 
  329 uint8_t* file_sig_sha256_get (FileContext *context)
  330 {
  331     if (!context)
  332         return NULL;
  333     return (context->sha256);
  334 }
  335 
  336 char* file_type_name(void* conf, uint32_t id)
  337 {
  338     RuleInfo *info;
  339     if (SNORT_FILE_TYPE_UNKNOWN == id)
  340         return ("Unknown file type, done!");
  341     else if (SNORT_FILE_TYPE_CONTINUE == id)
  342         return ("Undecided file type, continue...");
  343     info = file_rule_get(conf, id);
  344     if (info != NULL)
  345         return info->type;
  346     else
  347         return NULL;
  348 }
  349 
  350 bool file_IDs_from_type(const void *conf, const char *type,
  351      uint32_t **ids, uint32_t *count)
  352 {
  353     if ( !type )
  354         return false;
  355 
  356     return get_ids_from_type(conf, type, ids, count);
  357 }
  358 
  359 bool file_IDs_from_type_version(const  void *conf, const char *type,
  360     const char *version, uint32_t **ids, uint32_t *count )
  361 {
  362     if ( !type || !version )
  363         return false;
  364 
  365     return get_ids_from_type_version(conf, type, version, ids, count);
  366 }
  367 
  368 bool file_IDs_from_group(const void *conf, const char *group,
  369      uint32_t **ids, uint32_t *count)
  370 {
  371     if ( !group )
  372         return false;
  373 
  374     return get_ids_from_group(conf, group, ids, count);
  375 }
  376 
  377 #if defined(DEBUG_MSGS) || defined (REG_TEST)
  378 /*
  379  * Print a 32-byte hash value.
  380  */
  381 void file_sha256_print(unsigned char *hash)
  382 {
  383     printf("SHA256: %02X%02X %02X%02X %02X%02X %02X%02X "
  384             "%02X%02X %02X%02X %02X%02X %02X%02X "
  385             "%02X%02X %02X%02X %02X%02X %02X%02X "
  386             "%02X%02X %02X%02X %02X%02X %02X%02X\n",
  387             hash[0], hash[1], hash[2], hash[3],
  388             hash[4], hash[5], hash[6], hash[7],
  389             hash[8], hash[9], hash[10], hash[11],
  390             hash[12], hash[13], hash[14], hash[15],
  391             hash[16], hash[17], hash[18], hash[19],
  392             hash[20], hash[21], hash[22], hash[23],
  393             hash[24], hash[25], hash[26], hash[27],
  394             hash[28], hash[29], hash[30], hash[31]);
  395 }
  396 #endif