Пример #1
0
///
/// Returns the file type of a given input file.
/// fn is provided so that error messages can be printed.
///
hashlist::hashfile_format hashlist::identify_format(class display *ocb,
						    const std::string &fn,
						    FILE *handle)
{
    char buf[MAX_STRING_LENGTH];

    // Find the header 
    if ((fgets(buf,MAX_STRING_LENGTH,handle)) == NULL) {
	return file_unknown;
    }

    chop_line(buf);

    if ( ! STRINGS_EQUAL(buf,HASHDEEP_HEADER_10)) {
	return file_unknown;
    }

    // Find which hashes are in this file
    if ((fgets(buf,MAX_STRING_LENGTH,handle)) == NULL) {
	return file_unknown;
    }

    chop_line(buf);

    // We don't use STRINGS_EQUAL here because we only care about
    // the first ten characters for right now. 
    if (strncasecmp("%%%% size,",buf,10))  {
	return file_unknown;
    }

    /**
     * Remember previously loaded hashes.
     */
    std::string previously_enabled_algorithms = last_enabled_algorithms; 
    
    // Skip the "%%%% size," when parsing the list of hashes 
    enable_hashing_algorithms_from_hashdeep_file(ocb,fn,buf + 10);
    

    // If the set of hashes now in use doesn't match those previously in use,
    // give a warning.
    if (previously_enabled_algorithms.size()>0
	&& previously_enabled_algorithms != last_enabled_algorithms){
	if(ocb) ocb->error("%s: Hashes not in same format as previously loaded",
				 fn.c_str());
    }
    return file_hashdeep_10;
}
Пример #2
0
/// @brief Read the next entry in a file of known hashes and convert 
/// it to a Filedata 
///
/// @param s State variable
/// @param f Structure where to store the data we read
///
/// @return Returns true if there is no entry to read or on error. 
/// Otherwise, false.
bool sig_file_next(state *s, Filedata ** f)
{
  if (NULL == s or NULL == f or NULL == s->known_handle)
    return true;

  char buffer[MAX_STR_LEN];
  memset(buffer,0,MAX_STR_LEN);
  if (NULL == fgets(buffer,MAX_STR_LEN,s->known_handle))
    return true;

  s->line_number++;
  chop_line(buffer);

  try 
  {
    *f = new Filedata(std::string(buffer),s->known_fn);
  }
  catch (std::bad_alloc)
  {
    // This can happen on a badly formatted line, or a blank one.
    // We don't display errors on blank lines.
    if (strlen(buffer) > 0)
      print_error(s,
		  "%s: Bad hash in line %llu", 
		  s->known_fn, 
		  s->line_number);

    return true;
  }

  return false;
}
Пример #3
0
/// Open a file of known hashes and determine if it's valid
///
/// @param s State variable
/// @param fn filename to open
/// 
/// @return Returns false success, true on error
bool sig_file_open(state *s, const char * fn)
{
  if (NULL == s or NULL == fn)
    return true;

  s->known_handle = fopen(fn,"rb");
  if (NULL == s->known_handle)
  {
    if ( ! (MODE(mode_silent)) )
      perror(fn);
    return true;
  }

  // The first line of the file should contain a valid ssdeep header. 
  char buffer[MAX_STR_LEN];
  if (NULL == fgets(buffer,MAX_STR_LEN,s->known_handle))
  {
    if ( ! (MODE(mode_silent)) )
      perror(fn);
    fclose(s->known_handle);
    return true;
  }

  chop_line(buffer);

  if (strncmp(buffer,SSDEEPV1_0_HEADER,MAX_STR_LEN) and 
      strncmp(buffer,SSDEEPV1_1_HEADER,MAX_STR_LEN)) 
  {
    if ( ! (MODE(mode_silent)) )
      print_error(s,"%s: Invalid file header.", fn);
    fclose(s->known_handle);
    return true;
  }

  // We've now read the first line
  s->line_number = 1;
  s->known_fn = strdup(fn);

  return false;
}
Пример #4
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Read and parse syslinux config file.
//
// return:
//   0: ok, 1: error
//
int read_config_file(void)
{
  FILE *f;
  char *s, *t, buf[MAX_CONFIG_LINE_LEN];
  unsigned u, menu_idx = 0, label_size = 0, append_size = 0;
  menu_t *menu_ptr = NULL, **menu_next = &menu;

  menu_default = calloc(1, sizeof *menu_default);

  if(!(f = fopen(syslinux_config_file(), "r"))) return 1;

  while((s = fgets(buf, sizeof buf, f))) {
    chop_line(s);
    s = skip_spaces(s);
    if(!*s || *s == '#') continue;
    t = skip_nonspaces(s);
    if(*t) *t++ = 0;
    t = skip_spaces(t);

    if(!strcasecmp(s, "timeout")) {
      timeout = atoi(t);
      continue;
    }

    if(!strcasecmp(s, "default")) {
      menu_default->label = strdup(t);
      u = strlen(t);
      if(u > label_size) label_size = u;
      continue;
    }

    if(!strcasecmp(s, "label")) {
      menu_ptr = *menu_next = calloc(1, sizeof **menu_next);
      menu_next = &menu_ptr->next;
      menu_idx++;
      menu_ptr->label = menu_ptr->menu_label = strdup(t);
      u = strlen(t);
      if(u > label_size) label_size = u;
      continue;
    }

    if(!strcasecmp(s, "kernel") && menu_ptr) {
      menu_ptr->kernel = strdup(t);
      continue;
    }

    if(!strcasecmp(s, "linux") && menu_ptr) {
      menu_ptr->linux = strdup(t);
      continue;
    }

    if(!strcasecmp(s, "localboot") && menu_ptr) {
      menu_ptr->localboot = strdup(t);
      continue;
    }

    if(!strcasecmp(s, "initrd") && menu_ptr) {
      menu_ptr->initrd = strdup(t);
      continue;
    }

    if(!strcasecmp(s, "append")) {
      (menu_ptr ?: menu_default)->append = strdup(t);
      u = strlen(t);
      if(u > append_size) append_size = u;
      continue;
    }

    if(!strcasecmp(s, "ipappend")) {
      (menu_ptr ?: menu_default)->ipappend = strdup(t);
      continue;
    }
Пример #5
0
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
// Read and parse syslinux config file.
//
// return:
//   0: ok, 1: error
//
int read_config_file(const char *filename)
{
  FILE *f;
  char *s, *t, buf[MAX_CONFIG_LINE_LEN];
  unsigned u, top_level = 0, text = 0;

  if(!strcmp(filename, "~")) {
    top_level = 1;
    filename = syslinux_config_file();
    gfx_menu.entries = 0;
    gfx_menu.label_size = 0;
    gfx_menu.arg_size = 0;
    menu_ptr = NULL;
    menu_next = &menu;
    menu_default = calloc(1, sizeof *menu_default);
  }

  if(!(f = fopen(filename, "r"))) return 1;

  while((s = fgets(buf, sizeof buf, f))) {
    chop_line(s);
    s = skipspace(s);
    if(!*s || *s == '#') continue;
    t = skip_nonspaces(s);
    if(*t) *t++ = 0;
    t = skipspace(t);

    if(!strcasecmp(s, "endtext")) {
      text = 0;
      continue;
    }

    if (text)
      continue;

    if(!strcasecmp(s, "timeout")) {
      timeout = atoi(t);
      continue;
    }

    if(!strcasecmp(s, "default")) {
      menu_default->label = strdup(t);
      u = strlen(t);
      if(u > gfx_menu.label_size) gfx_menu.label_size = u;
      continue;
    }

    if(!strcasecmp(s, "label")) {
      menu_ptr = *menu_next = calloc(1, sizeof **menu_next);
      menu_next = &menu_ptr->next;
      gfx_menu.entries++;
      menu_ptr->label = menu_ptr->menu_label = strdup(t);
      u = strlen(t);
      if(u > gfx_menu.label_size) gfx_menu.label_size = u;
      continue;
    }

    if(!strcasecmp(s, "kernel") && menu_ptr) {
      menu_ptr->kernel = strdup(t);
      continue;
    }

    if(!strcasecmp(s, "linux") && menu_ptr) {
      menu_ptr->linux = strdup(t);
      continue;
    }

    if(!strcasecmp(s, "localboot") && menu_ptr) {
      menu_ptr->localboot = strdup(t);
      continue;
    }

    if(!strcasecmp(s, "initrd") && menu_ptr) {
      menu_ptr->initrd = strdup(t);
      continue;
    }

    if(!strcasecmp(s, "append")) {
      (menu_ptr ?: menu_default)->append = strdup(t);
      u = strlen(t);
      if(u > gfx_menu.arg_size) gfx_menu.arg_size = u;
      continue;
    }

    if(!strcasecmp(s, "ipappend")) {
      (menu_ptr ?: menu_default)->ipappend = strdup(t);
      continue;
    }
Пример #6
0
//
// Loads a file of known hashes.
// First identifies the file type, then reads the file.
 //
hashlist::loadstatus_t 
hashlist::load_hash_file(display *ocb,const std::string &fn)
{
  loadstatus_t status = loadstatus_ok;
  hashfile_format type;

  FILE *hl_handle = fopen(fn.c_str(),"rb");
  if (NULL == hl_handle)
  {
    if (ocb) 
      ocb->error("%s: %s", fn.c_str(), strerror(errno));
    return status_file_error;
  }
  
  type = identify_format(ocb,fn,hl_handle);
  if (file_unknown == type)
  {
    if (ocb) 
      ocb->error("%s: Unable to identify file format", fn.c_str());
    fclose(hl_handle);
    hl_handle = 0;
    return status_unknown_filetype;
  }

  bool contains_bad_lines = false;
  bool record_valid;

  // We start our counter at line number two for the two lines
  // of header we've already read
  uint64_t line_number = 2;

  // TODO: Read the line directly into a std::string
  char line[MAX_STRING_LENGTH];	
  while (fgets(line,MAX_STRING_LENGTH,hl_handle)) 
  {
    line_number++;			
    
    // Lines starting with a pound sign are comments and can be ignored
    if ('#' == line[0])
      continue;

    // C++ typically fails with a bad_alloc, but you can make it return null
    // http://www.cplusplus.com/reference/std/new/bad_alloc/
    // http://www.cplusplus.com/reference/std/new/nothrow/
    file_data_t *t = new (std::nothrow) file_data_t(); 
    if (NULL == t)
    {
      ocb->fatal_error("%s: Out of memory in line %"PRIu64,
		       fn.c_str(), line_number);
    }
    
    chop_line(line);
    record_valid = true;

    // Convert the input line to a string for easier manipulations
    std::string line_as_string(line);
    std::vector<std::string> fields = split(line_as_string,',');

    size_t column_number;
    for (column_number=0 ; column_number<fields.size() ; column_number++)
    {
      std::string word = fields[column_number];

      // The first column should always be the file size
      if (0 == column_number)
      {
	t->file_bytes = (uint64_t)strtoll(word.c_str(),NULL,10);
	continue;
      }

      if (column_number == filename_column)
      {
	// If the filename contained commas, it was split 
	// incorrectly by the 'split' statememt above. The filename
	// will be split across more than one column.
	// As such we need to 'find' everything
	// in the string starting with the current location.
	// The result should be closer to the end of the string than
	// the start, so we can use rfind. (This also avoids a problem
	// when the filename is the same as one of the hashes, which
	// happens now and again.)
	size_t start = line_as_string.rfind(word);
	t->file_name = line_as_string.substr(start,std::string::npos);

	// This should be the last column, so we break out now.
	break;
      }

      // All other columns should contain a valid hash in hex
      if ( !algorithm_t::valid_hash(hash_column[column_number],word))
      {
	if (ocb) 
	  ocb->error("%s: Invalid %s hash in line %"PRIu64,
		     fn.c_str(), 
		     hashes[hash_column[column_number]].name.c_str(),
		     line_number);
	contains_bad_lines = true;
	record_valid = false;
	// Break out (done = true) and then process the next line
	break;
      }
      
      // Convert the hash to a std::string and save it
      lowercase(word);
      t->hash_hex[hash_column[column_number]] = word;
    }

    if (record_valid) 
      add_fdt(t);
  }

  fclose(hl_handle);
  hl_handle = 0;

  if (contains_bad_lines)
    return status_contains_bad_hashes;
    
  return status;
}
Пример #7
0
static Param_Type *create_param_type (char *line)
{
   Param_Type *p;
   char *name, *type, *mode, *min, *max, *value, *prompt;

   p = (Param_Type *) _pf_malloc (sizeof (Param_Type));
   if (p == NULL) return NULL;

   if (NULL == (p->name = _pf_create_string (line)))
     {
	goto free_and_return_error;
     }

   /* p->name is special.  See comment in pf.h */
   if (-1 == chop_line (line, &name, &type, &mode, &value, &min, &max, &prompt))
     {
	goto free_and_return_error;
     }

   p->name[strlen (name)] = 0;

   if (type == NULL)
     {
	p->type = PF_COMMENT_TYPE;
	return p;
     }

   if (-1 == parse_type (type, &p->type))
     {
	goto free_and_return_error;
     }

   if (-1 == _pf_parse_mode (mode, &p->mode))
     {
	goto free_and_return_error;
     }

   if (min != NULL)
     {
	if (NULL == (p->min = _pf_unescape_string (min)))
	  goto free_and_return_error;
     }

   if (max != NULL)
     {
	if (NULL == (p->max = _pf_unescape_string (max)))
	  goto free_and_return_error;
     }

   if (value != NULL)
     {
	if (NULL == (p->value = _pf_unescape_string (value)))
	  goto free_and_return_error;

	/* This is a weakness in the definition of parameter files.  There
	 * seems to be NO WAY to have a parameter whose value begins with
	 * a ')' character.  Actually, I think there is but the existing
	 * practice seems to defeat my solution.
	 */
	if (*p->value == ')')
	  p->flags |= PF_INDIRECT_VALUE;
     }

   if (prompt != NULL)
     {
	if (NULL == (p->prompt = _pf_unescape_string (prompt)))
	  goto free_and_return_error;
     }

   return p;

   free_and_return_error:

   if ((p != NULL) && (p->name != NULL))
     {
	pf_error ("Error processing parameter/line %s", p->name);
     }

   free_param_type (p);
   return NULL;
}