Exemplo n.º 1
0
int
_ds_set_signature (DSPAM_CTX * CTX, struct _ds_spam_signature *SIG,
                   const char *signature)
{
  struct _sqlite_drv_storage *s = (struct _sqlite_drv_storage *) CTX->storage;
  unsigned long length;
  char *mem;
  char scratch[1024];
  buffer *query;
  char *err=NULL;

  if (s->dbh == NULL)
  {
    LOGDEBUG ("_ds_set_signature; invalid database handle (NULL)");
    return EINVAL;
  }

  query = buffer_create (NULL);
  if (query == NULL)
  {
    LOG (LOG_CRIT, ERR_MEM_ALLOC);
    return EUNKNOWN;
  }

  mem = calloc (1, 2 + (257*SIG->length)/254);
  if (mem == NULL)
  {
    LOG (LOG_CRIT, ERR_MEM_ALLOC);
    buffer_destroy(query);
    return EUNKNOWN;
  }

  length = sqlite_encode_binary(SIG->data, SIG->length, (unsigned char *) mem);
  if (length<0) {
   LOG(LOG_ERR, "sqlite_encode_binary() failed on error %d", length);
   buffer_destroy(query);
   return EFAILURE;
  }

  snprintf (scratch, sizeof (scratch),
            "insert into dspam_signature_data(signature, created_on, data) "
            "values(\"%s\", date('now'), '",
            signature);
  buffer_cat (query, scratch);
  buffer_cat (query, mem);
  buffer_cat (query, "')");

  if ((sqlite_exec(s->dbh, query->data, NULL, NULL, &err))!=SQLITE_OK)
  {
    _sqlite_drv_query_error (err, query->data);
    buffer_destroy(query);
    free(mem);
    return EFAILURE;
  }

  free (mem);
  buffer_destroy(query);
  return 0;
}
Exemplo n.º 2
0
char *daemon_getline(THREAD_CTX *TTX, int timeout) {
    struct timeval tv;
    char *p, *q, *pop;
    char buf[1024];
    int total_wait = 0;
    long recv_len;
    fd_set fds;
    int i;

    pop = pop_buffer(TTX);
    while(!pop && total_wait<timeout) {
        if (__daemon_run == 0)
            return NULL;
        total_wait++;
        tv.tv_sec = 1;
        tv.tv_usec = 0;
        FD_ZERO(&fds);
        FD_SET(TTX->sockfd, &fds);
        i = select(TTX->sockfd+1, &fds, NULL, NULL, &tv);
        if (i<=0)
            continue;

        recv_len = recv(TTX->sockfd, buf, sizeof(buf)-1, 0);
        buf[recv_len] = 0;
        if (recv_len == 0)
            return NULL;
        for(p=q=buf,i=0; i<recv_len; i++) {
            if (*q) {
                *p = *q;
                p++;
            }
            q++;
        }
        *p = 0;
        buffer_cat(TTX->packet_buffer, buf);
        pop = pop_buffer(TTX);
    }

#ifdef VERBOSE
    LOGDEBUG("SRECV: %s", pop);
#endif

    return pop;
}
Exemplo n.º 3
0
int _ds_degenerate_message(DSPAM_CTX *CTX, buffer * header, buffer * body)
{
  char *decode = NULL;
  struct nt_node *node_nt, *node_header;
  struct nt_c c_nt, c_nt2;
  int i = 0;
  char heading[1024];

  if (! CTX->message)
  {
    LOG (LOG_WARNING, "_ds_degenerate_message() failed: CTX->message is NULL");
    return EUNKNOWN;
  }

  /* Iterate through each component and create large header/body buffers */

  node_nt = c_nt_first (CTX->message->components, &c_nt);
  while (node_nt != NULL)
  {
    struct _ds_message_part *block = (struct _ds_message_part *) node_nt->ptr;

#ifdef VERBOSE
    LOGDEBUG ("Processing component %d", i);
#endif

    if (! block->headers || ! block->headers->items)
    {
#ifdef VERBOSE
      LOGDEBUG ("  : End of Message Identifier");
#endif
    }

    else
    {
      struct _ds_header_field *current_header;

      /* Accumulate the headers */
      node_header = c_nt_first (block->headers, &c_nt2);
      while (node_header != NULL)
      {
        current_header = (struct _ds_header_field *) node_header->ptr;
        snprintf (heading, sizeof (heading),
                  "%s: %s\n", current_header->heading,
                  current_header->data);
        buffer_cat (header, heading);
        node_header = c_nt_next (block->headers, &c_nt2);
      }

      decode = block->body->data;

      if (block->media_type == MT_TEXT    ||
               block->media_type == MT_MESSAGE ||
               block->media_type == MT_UNKNOWN ||
               (block->media_type == MT_MULTIPART && !i))
      {
        /* Accumulate the bodies, skip attachments */

        if (
             (   block->encoding == EN_BASE64
              || block->encoding == EN_QUOTED_PRINTABLE)
            && ! block->original_signed_body)
        {
          if (block->content_disposition != PCD_ATTACHMENT)
          {
            LOGDEBUG ("decoding message block from encoding type %d",
                      block->encoding);
            decode = _ds_decode_block (block);
          }
        }

        /* We found a tokenizable body component, add prefilters */

        if (decode)
        {
          char *decode2 = NULL;
          char *decode3 = NULL;

          /* -- PREFILTERS BEGIN -- */

          /* Hexadecimal 8-Bit Encodings */

          if (block->encoding == EN_8BIT) {
            decode2 = _ds_decode_hex8bit(decode);
          } else {
            decode2 = strdup(decode);
          }

          /* HTML-Specific Filters */

          if (decode2) {
            if (block->media_subtype == MST_HTML) {
              decode3 = _ds_strip_html(decode2);
            } else {
              decode3 = strdup(decode2);
            }
            free(decode2);
          }

          /* -- PREFILTERS END -- */

          if (decode3) {
            buffer_cat (body, decode3);
            free(decode3);
          }

          /* If we've decoded the body, save the original copy */
          if (decode != block->body->data)
          {
            block->original_signed_body = block->body;
            block->body = buffer_create (decode);
            free (decode);
          }
        }
      }
    }
#ifdef VERBOSE
    LOGDEBUG ("Getting next message component");
#endif
    node_nt = c_nt_next (CTX->message->components, &c_nt);
    i++;
  } /* while (node_nt != NULL) */

  if (header->data == NULL)
    buffer_cat (header, " ");

  if (body->data == NULL)
    buffer_cat (body, " ");

  return 0;
}
Exemplo n.º 4
0
int
_ds_setall_spamrecords (DSPAM_CTX * CTX, ds_diction_t diction)
{
  struct _sqlite_drv_storage *s = (struct _sqlite_drv_storage *) CTX->storage;
  struct _ds_spam_stat stat, stat2;
  ds_term_t ds_term;
  ds_cursor_t ds_c;
  buffer *query;
  char scratch[1024];
  char *err=NULL;
  int update_one = 0;

  if (s->dbh == NULL)
  {
    LOGDEBUG ("_ds_setall_spamrecords: invalid database handle (NULL)");
    return EINVAL;
  }

  if (CTX->operating_mode == DSM_CLASSIFY &&
        (CTX->training_mode != DST_TOE ||
          (diction->whitelist_token == 0 && (!(CTX->flags & DSF_NOISE)))))
    return 0;

  query = buffer_create (NULL);
  if (query == NULL)
  {
    LOG (LOG_CRIT, ERR_MEM_ALLOC);
    return EUNKNOWN;
  }

  if (s->control_token == 0)
  {
    ds_c = ds_diction_cursor(diction);
    ds_term = ds_diction_next(ds_c);
    if (ds_term == NULL)
    {
      stat.spam_hits = 0;
      stat.innocent_hits = 0;
    }
    else
    {
      stat.spam_hits = ds_term->s.spam_hits;
      stat.innocent_hits = ds_term->s.innocent_hits;
    }
    ds_diction_close(ds_c);
  }
  else
  {
    ds_diction_getstat(diction, s->control_token, &stat);
  }

  snprintf (scratch, sizeof (scratch),
            "update dspam_token_data set last_hit = date('now'), "
            "spam_hits = max(0, spam_hits %s %d), "
            "innocent_hits = max(0, innocent_hits %s %d) "
            "where token in(",
            (stat.spam_hits > s->control_sh) ? "+" : "-",
            abs (stat.spam_hits - s->control_sh),
            (stat.innocent_hits > s->control_ih) ? "+" : "-",
            abs (stat.innocent_hits - s->control_ih));

  buffer_cat (query, scratch);

  ds_c = ds_diction_cursor(diction);
  ds_term = ds_diction_next(ds_c);
  while(ds_term)
  {
    int wrote_this = 0;
    if (CTX->training_mode == DST_TOE          && 
        CTX->classification == DSR_NONE        &&
	CTX->operating_mode == DSM_CLASSIFY    &&
        diction->whitelist_token != ds_term->key  &&
        (!ds_term->name || strncmp(ds_term->name, "bnr.", 4)))  
    {
      ds_term = ds_diction_next(ds_c);
      continue;
    }

    if (!(ds_term->s.status & TST_DIRTY)) {
      ds_term = ds_diction_next(ds_c);
      continue;
    }

    ds_diction_getstat(diction, ds_term->key, &stat2);

    if (!(stat2.status & TST_DISK))
    {
      char insert[1024];

        snprintf(insert, sizeof (insert),
                 "insert into dspam_token_data(token, spam_hits, "
                 "innocent_hits, last_hit) values('%" LLU_FMT_SPEC "', %ld, %ld, "
                 "date('now'))",
                 ds_term->key,
                 stat2.spam_hits > 0 ? (long) 1 : (long) 0, 
                 stat2.innocent_hits > 0 ? (long) 1 : (long) 0);

      if ((sqlite_exec(s->dbh, insert, NULL, NULL, &err)) != SQLITE_OK)
      {
        stat2.status |= TST_DISK;
        free(err);
      }
    }

    if ((stat2.status & TST_DISK))
    {
      snprintf (scratch, sizeof (scratch), "'%" LLU_FMT_SPEC "'", ds_term->key);
      buffer_cat (query, scratch);
      update_one = 1;
      wrote_this = 1;
      ds_term->s.status |= TST_DISK;
    }
    ds_term = ds_diction_next(ds_c);
    if (ds_term && wrote_this) 
      buffer_cat (query, ",");
  }
  ds_diction_close(ds_c);

  if (query->used && query->data[strlen (query->data) - 1] == ',')
  {
    query->used--;
    query->data[strlen (query->data) - 1] = 0;

  }

  buffer_cat (query, ")");

  LOGDEBUG("Control: [%ld %ld] [%ld %ld]", s->control_sh, s->control_ih, stat.spam_hits, stat.innocent_hits);

  if (update_one)
  {
    if ((sqlite_exec(s->dbh, query->data, NULL, NULL, &err))!=SQLITE_OK)
    {
      _sqlite_drv_query_error (err, query->data);
      buffer_destroy(query);
      return EFAILURE;
    }
  }

  buffer_destroy (query);
  return 0;
}
Exemplo n.º 5
0
int
_ds_getall_spamrecords (DSPAM_CTX * CTX, ds_diction_t diction)
{
  struct _sqlite_drv_storage *s = (struct _sqlite_drv_storage *) CTX->storage;
  buffer *query;
  ds_term_t ds_term;
  ds_cursor_t ds_c;
  char scratch[1024];
  struct _ds_spam_stat stat;
  unsigned long long token = 0;
  char *err=NULL, **row;
  int nrow, ncolumn, get_one = 0, i;

  if (s->dbh == NULL)
  {
    LOGDEBUG ("_ds_getall_spamrecords: invalid database handle (NULL)");
    return EINVAL;
  }

  stat.spam_hits = 0;
  stat.innocent_hits = 0;

  query = buffer_create (NULL);
  if (query == NULL)
  {
    LOG (LOG_CRIT, ERR_MEM_ALLOC);
    return EUNKNOWN;
  }

  snprintf (scratch, sizeof (scratch),
            "select token, spam_hits, innocent_hits "
            "from dspam_token_data where token in(");

  buffer_cat (query, scratch);
  ds_c = ds_diction_cursor(diction);
  ds_term = ds_diction_next(ds_c);
  while(ds_term)
  {
    snprintf (scratch, sizeof (scratch), "'%" LLU_FMT_SPEC "'", ds_term->key);
    buffer_cat (query, scratch);
    ds_term->s.innocent_hits = 0;
    ds_term->s.spam_hits = 0;
    ds_term->s.probability = 0;
    ds_term->s.status &= ~TST_DISK;
    ds_term = ds_diction_next(ds_c);
    if (ds_term != NULL)
      buffer_cat (query, ",");
    get_one = 1;
  }
  ds_diction_close(ds_c);
  buffer_cat (query, ")");

#ifdef VERBOSE
  LOGDEBUG ("sqlite query length: %ld\n", query->used);
  _sqlite_drv_query_error (strdup("VERBOSE DEBUG (INFO ONLY - NOT AN ERROR)"), query->data);
#endif

  if (!get_one) 
    return 0;

  if ((sqlite_get_table(s->dbh, query->data, &row, &nrow, &ncolumn, &err))
      !=SQLITE_OK)
  {
    _sqlite_drv_query_error (err, query->data);
    buffer_destroy(query);
    return EFAILURE;
  }

  if (nrow < 1) {
    sqlite_free_table(row);
    buffer_destroy(query);
    return 0;
  }

  if (row == NULL)
    return 0;

  stat.probability = 0;
  stat.status |= TST_DISK;
  for(i=1;i<=nrow;i++) {
    token = strtoull (row[(i*ncolumn)], NULL, 0);
    stat.spam_hits = strtol (row[1+(i*ncolumn)], NULL, 0);
    stat.innocent_hits = strtol (row[2+(i*ncolumn)], NULL, 0);

    if (stat.spam_hits < 0)
      stat.spam_hits = 0;
    if (stat.innocent_hits < 0)
      stat.innocent_hits = 0;

    ds_diction_addstat(diction, token, &stat);
  }

  sqlite_free_table(row);

  ds_c = ds_diction_cursor(diction);
  ds_term = ds_diction_next(ds_c);
  while(ds_term && !s->control_token) {
    if (ds_term->s.spam_hits && ds_term->s.innocent_hits) {
      s->control_token = ds_term->key;
      s->control_sh = ds_term->s.spam_hits;
      s->control_ih = ds_term->s.innocent_hits;
    }
    ds_term = ds_diction_next(ds_c);
  }
  ds_diction_close(ds_c);

  if (!s->control_token)
  {
     ds_c = ds_diction_cursor(diction);
     ds_term = ds_diction_next(ds_c);
     s->control_token = ds_term->key;
     s->control_sh = ds_term->s.spam_hits;
     s->control_ih = ds_term->s.innocent_hits;
     ds_diction_close(ds_c);
  }

  buffer_destroy (query);
  return 0;
}
Exemplo n.º 6
0
int _ds_delall_spamrecords (DSPAM_CTX * CTX, ds_diction_t diction)
{
  struct _sqlite_drv_storage *s = (struct _sqlite_drv_storage *) CTX->storage;
  ds_term_t ds_term;
  ds_cursor_t ds_c;
  buffer *query;
  char *err=NULL;
  char scratch[1024];
  char queryhead[1024];
  int writes = 0;

  if (diction->items < 1)
    return 0;

  if (s->dbh == NULL)
  {
    LOGDEBUG ("_ds_delall_spamrecords: invalid database handle (NULL)");
    return EINVAL;
  }

  query = buffer_create (NULL);
  if (query == NULL)
  {
    LOG (LOG_CRIT, ERR_MEM_ALLOC);
    return EUNKNOWN;
  }

  snprintf (queryhead, sizeof(queryhead),
            "delete from dspam_token_data "
            "where token in(");

  buffer_cat (query, queryhead);

  ds_c = ds_diction_cursor(diction);
  ds_term = ds_diction_next(ds_c);
  while (ds_term)
  {
    snprintf (scratch, sizeof (scratch), "'%" LLU_FMT_SPEC "'", ds_term->key);
    buffer_cat (query, scratch);
    ds_term = ds_diction_next(ds_c);
   
    if (writes > 2500 || ds_term == NULL) {
      buffer_cat (query, ")");

      if ((sqlite_exec(s->dbh, query->data, NULL, NULL, &err))!=SQLITE_OK)
      {
        _sqlite_drv_query_error (err, query->data);
        buffer_destroy(query);
        return EFAILURE;
      }

      buffer_copy(query, queryhead);
      writes = 0;
   
    } else { 
      writes++;
      if (ds_term)
        buffer_cat (query, ",");
    }
  }
  ds_diction_close(ds_c);

  if (writes) {
    buffer_cat (query, ")");

    if ((sqlite_exec(s->dbh, query->data, NULL, NULL, &err))!=SQLITE_OK)
    {
      _sqlite_drv_query_error (err, query->data);
      buffer_destroy(query);
      return EFAILURE;
    }
  }

  buffer_destroy (query);
  return 0;
}
Exemplo n.º 7
0
buffer * read_sock(THREAD_CTX *TTX, AGENT_CTX *ATX) {
    buffer *message;
    int body = 0, line = 1;
    char *buf;
    int strip = _ds_match_attribute(agent_config, "Broken", "lineStripping");
    int parseto = _ds_match_attribute(agent_config, "ParseToHeaders", "on");

    message = buffer_create(NULL);
    if (message == NULL) {
        LOG(LOG_CRIT, ERR_MEM_ALLOC);
        return NULL;
    }

    if (_ds_match_attribute(agent_config, "DataSource", "document")) {
        buffer_cat(message, ".\n\n");
        body = 1;
    }

    while ((buf = daemon_getline(TTX, 300))!=NULL) {
        chomp(buf);

        if (!strcmp(buf, ".")) {
            free(buf);
            return message;
        }

        if (strip) {
            size_t len = strlen(buf);

            while (len>1 && buf[len-2]==13) {
                buf[len-2] = buf[len-1];
                buf[len-1] = 0;
                len--;
            }
        }

        if (line > 1 || strncmp (buf, "From QUARANTINE", 15))
        {
            if (parseto) {
                if (buf[0] == 0)
                    body = 1;
                if (!body && !strncasecmp(buf, "To: ", 4))
                    process_parseto(ATX, buf);
            }

            if (buffer_cat (message, buf) || buffer_cat(message, "\n"))
            {
                LOG (LOG_CRIT, ERR_MEM_ALLOC);
                goto bail;
            }
        }

        /* Use the original user id if we are reversing a false positive */
        if (ATX->source         == DSS_ERROR      &&
                ATX->classification == DSR_ISINNOCENT &&
                ATX->operating_mode == DSM_PROCESS    &&
                !strncasecmp (buf, "X-DSPAM-User: ", 14))
        {
            char user[MAX_USERNAME_LENGTH];
            strlcpy (user, buf + 14, sizeof (user));
            chomp (user);
            nt_destroy (ATX->users);
            ATX->users = nt_create (NT_CHAR);
            if (ATX->users == NULL)
            {
                LOG(LOG_CRIT, ERR_MEM_ALLOC);
                goto bail;
            }
            nt_add (ATX->users, user);
        }

        free(buf);
        line++;
    }

    return NULL;

bail:
    buffer_destroy(message);
    return NULL;
}