hackedteam/vector-ipa

View on GitHub
src/match_users_string.c

Summary

Maintainability
Test Coverage
/*
    MODULE -- Module to match an user based on string matching

    Copyright (C) Alberto Ornaghi

    $Id: match_users_string.c 2653 2010-07-06 07:31:19Z alor $
*/

#include <main.h>
#include <hook.h>
#include <packet.h>

#include <match.h>
#include <match_users.h>

/* global vars */

struct string_node {
   int type;
   char tag[MAX_TAG_LEN];
   char *string;
   LIST_ENTRY (string_node) next;
};

static LIST_HEAD(, string_node) string_root;
static pthread_mutex_t string_mutex = PTHREAD_MUTEX_INITIALIZER;

/* proto */

void match_user_string_add(char *value, char *tag, int type);
void match_user_string(struct packet_object *po);
struct string_node * user_string_search(const char *data, size_t len);

/*******************************************/

void match_user_string_add(char *value, char *tag, int type)
{
   struct string_node *e;

   /*
    * remove the hook. we must do this because we are called on every reload list.
    * otherwise the hook will be setup multiple time
    */
   hook_del(HOOK_PACKET_TCP, match_user_string);

   /* add the hook on TCP packet, this will pass us all the HTTP packets to look into */
   hook_add(HOOK_PACKET_TCP, match_user_string);

   /* create the element for the list */
   SAFE_CALLOC(e, 1, sizeof(struct string_node));

   e->type = type;
   snprintf(e->tag, MAX_TAG_LEN-1, "%s", tag);
   e->string = strdup(value);

   pthread_mutex_lock(&string_mutex);
   LIST_INSERT_HEAD(&string_root, e, next);
   pthread_mutex_unlock(&string_mutex);
}


void match_user_string_clear(void)
{
   struct string_node *e, *tmp;

   pthread_mutex_lock(&string_mutex);

   /* remove all the elements */
   LIST_FOREACH_SAFE(e, &string_root, next, tmp) {
      SAFE_FREE(e->string);
      LIST_REMOVE(e, next);
      SAFE_FREE(e);
   }

   pthread_mutex_unlock(&string_mutex);
}


struct string_node * user_string_search(const char *data, size_t len)
{
   struct string_node *e;

   pthread_mutex_lock(&string_mutex);

   LIST_FOREACH(e, &string_root, next) {
      /*
       * check if the string is present in the packet
       * XXX - we should implement string matching that cross
       * the packet boundary
       */

      if (memmem(data, len, e->string, strlen(e->string))) {
         pthread_mutex_unlock(&string_mutex);
         return e;
      }
   }

   pthread_mutex_unlock(&string_mutex);

   return NULL;
}


void match_user_string(struct packet_object *po)
{
   struct string_node *e;
   struct timeval tv;

   /* search into this packets all the possible string patterns */
   e = user_string_search((const char *)po->DATA.data, po->DATA.len);

   /* if found, tag it */
   if (e) {

      DEBUG_MSG(D_INFO, "STRING MATCHED: %s [%s]", e->string, e->tag);

      gettimeofday(&tv, NULL);

      /* tag the packet */
      snprintf(po->tag, MAX_TAG_LEN-1, "%s", e->tag);

      if (e->type == STRING_CLIENT) {
         active_user_add(&po->L3.src, NULL, e->tag, tv);
      } else if (e->type == STRING_SERVER) {
         active_user_add(&po->L3.dst, NULL, e->tag, tv);
      }
   }

}

/* EOF */

// vim:ts=3:expandtab