static void
test_macpolicy(const char *polname, const char *trylabel)
{
	char fn[64];
	char mac1[512], mac2[512];
	struct archive *ar, *aw;
	struct archive_entry *ae;
	int i, found;

	/* Create a file with the given label */
	strcpy(fn, "test_");
	strncat(fn, polname, 54);
	fn[59] = '\0';
	if (!create_labeled_file(fn, trylabel))
		return;

	/* Get the actual label. Note that it may be different than
	 * our original argument if multiple policies are loaded.
	 */
	failure("Cannot get MAC label from file");
	if (!assert(get_file_maclabel(fn, mac1, 512)))
		return;

	/* Read the file data into archive */
	assert((ar = archive_read_disk_new()) != NULL);
	ae = archive_entry_new();
	assert(ae != NULL);
	archive_entry_copy_pathname(ae, fn);

	failure("Reading disk entry failed.");
	assertEqualIntA(ar, ARCHIVE_OK,
	    archive_read_disk_entry_from_file(ar, ae, -1, NULL));

	/* Check that there is a matching xattr */
	i = archive_entry_xattr_reset(ae);
	found = 0;
	while (i--) {
		const char *name;
		const void *value;
		size_t size;
		archive_entry_xattr_next(ae, &name, &value, &size);
		if (name != NULL) {
			if (strncmp(name, "system.mac", 10) == 0) {
				if (strncmp(value, mac1,
				    (size > 512 ? 512 : size)) == 0) {
					found = 1;
					break;
				}
			}
		}
	}
	failure("No matching label in archive");
	assert(found);

	/* Write the file back to disk. Note that the file contained
	 * no data so we're only concerned with the header.
	 */
	assert((aw = archive_write_disk_new()) != NULL);
	archive_write_disk_set_options(aw, ARCHIVE_EXTRACT_XATTR);

	strncat(fn, "_out", 4); /* New name for extraction */
	fn[63] = '\0';
	archive_entry_copy_pathname(ae, fn);
	assertEqualIntA(aw, ARCHIVE_OK, archive_write_header(aw, ae));
	assertEqualIntA(aw, ARCHIVE_OK, archive_write_finish_entry(aw));

	/* Clean up */
	assertEqualInt(ARCHIVE_OK, archive_write_free(aw));
	assertEqualInt(ARCHIVE_OK, archive_read_free(ar));
	archive_entry_free(ae);

	/* Finally, verify the label of the created file */
	failure("Cannot get MAC label from file");
	if (!assert(get_file_maclabel(fn, mac2, 512)))
		return;
	failure("Original and extracted MAC labels do not match");
	assert(strncmp(mac1, mac2, 512) == 0);
}
emb_ruby_error_t emb_ruby_uncompress(){

  struct archive *input_archive;
  struct archive *output_archive;
  struct archive_entry* entry;

  int result;
  int output_flags;

  unsigned char buff[2048];
  int buffsize = 2048;
  int size;

  output_flags = ARCHIVE_EXTRACT_TIME;
  output_flags |= ARCHIVE_EXTRACT_PERM;
  output_flags |= ARCHIVE_EXTRACT_ACL;
  output_flags |= ARCHIVE_EXTRACT_FFLAGS;

  input_archive = archive_read_new();
  output_archive = archive_write_disk_new();

  archive_read_support_filter_gzip(input_archive);
  archive_read_support_format_tar(input_archive);
  //archive_read_support_format_raw(a);

  archive_write_disk_set_options(output_archive, output_flags);
  archive_write_disk_set_standard_lookup(output_archive);

  result = archive_read_open_memory(input_archive, (void*)binary_data, binary_size);

  if (result != ARCHIVE_OK) {
    fprintf(stderr, "%s\n", archive_error_string(input_archive));
    return E_UNCOMPRESS_ERROR;
  }


  for (;;) {

    /**
     * Read new header from memory
     */
    result = archive_read_next_header(input_archive, &entry);
    // EOF
    if (result == ARCHIVE_EOF) {
      break;
    }
    // error handling
    if (result != ARCHIVE_OK) {
      fprintf(stderr, "%s\n", archive_error_string(input_archive));
      emd_ruby_uncompress_cleanup(input_archive, output_archive);
      return E_UNCOMPRESS_ERROR;
    }

    /**
     * Write new header into disk
     */
    result = archive_write_header(output_archive, entry);
    // error handling
    if (result != ARCHIVE_OK) {
      fprintf(stderr, "%s\n", archive_error_string(output_archive));
      emd_ruby_uncompress_cleanup(input_archive, output_archive);
      return E_UNCOMPRESS_ERROR;
    }

    /**
     * copy the data
     */
     result = emb_ruby_uncompress_copy_data(input_archive, output_archive);
     if (result != ARCHIVE_OK) {
          fprintf(stderr, "%s\n", archive_error_string(output_archive));
          emd_ruby_uncompress_cleanup(input_archive, output_archive);
          return E_UNCOMPRESS_ERROR;
      }

      /**
       * Write the trailing
       */
       result = archive_write_finish_entry(output_archive);
       if (result != ARCHIVE_OK) {
            fprintf(stderr, "%s\n", archive_error_string(output_archive));
            emd_ruby_uncompress_cleanup(input_archive, output_archive);
            return E_UNCOMPRESS_ERROR;
        }

  }

  emd_ruby_uncompress_cleanup(input_archive, output_archive);

  return E_SUCCESS;

}
Beispiel #3
0
static bool ExtractArchive(const char *zip_file, const char *out_dir)
{
   struct archive *input = archive_read_new();
   archive_read_support_format_all(input);
   archive_read_support_compression_all(input);
   struct archive *output = archive_write_disk_new();
   archive_write_disk_set_options(output, ARCHIVE_EXTRACT_TIME);
   archive_write_disk_set_standard_lookup(output);
   int hRes;
   const int BLOCK_SIZE = 65536;
   int r = archive_read_open_filename(input, zip_file, BLOCK_SIZE);

   if (r != ARCHIVE_OK)
   {
      extraction_error = IDS_BADARCHIVE;
      return false;
   }

   // libarchive can only extract into the current directory, so we
   // need to set it and restore it.
   char original_dir[MAX_PATH];
   char *cRet = getcwd(original_dir, sizeof(original_dir));
   hRes = chdir(out_dir);
   
   bool retval = true;
   while (true)
   {
      struct archive_entry *entry;
      r = archive_read_next_header(input, &entry);
      if (r == ARCHIVE_EOF)
         break;
      
      if (r != ARCHIVE_OK)
      {
         extraction_error = IDS_BADARCHIVE;
         retval = false;
         break;
      }
      r = archive_write_header(output, entry);
      if (r != ARCHIVE_OK)
      {
		 const char *msg = archive_error_string(output);
         extraction_error = IDS_UNKNOWNERROR;
         retval = false;
         break;
      }

      if (archive_entry_size(entry) > 0)
      {
         r = CopyArchiveData(input, output);
         if (r != ARCHIVE_OK)
         {
            const char *msg = archive_error_string(output);
            extraction_error = IDS_UNKNOWNERROR;
            retval = false;
            break;
         }
      }
      r = archive_write_finish_entry(output);
      if (r != ARCHIVE_OK)
      {
         extraction_error = IDS_UNKNOWNERROR;
         retval = false;
         break;
      }

      // Extraction went OK; process Windows messages
      ClearMessageQueue();
   }
   archive_read_close(input);
   archive_read_free(input);
   archive_write_close(output);
   archive_write_free(output);

   // Go back to original working directory
   hRes = chdir(original_dir);

   return retval;
}
Beispiel #4
0
// -----------------------------------------------------------------------------
bool extract(const char* spath, const char* dpath)
{
    DEBUGLOGB;

    int      retc;
    bool     okay = false;
    archive* sorc = archive_read_new();
    archive* dest = archive_write_disk_new();

    if( !sorc || !dest )
    {
        DEBUGLOGE;
        DEBUGLOGS("  (1) - unable to create new read & write archive objects");
        return okay;
    }

    archive_read_support_filter_all(sorc);
    archive_read_support_format_all(sorc);

    archive_write_disk_set_options(dest, ARCHIVE_EXTRACT_TIME);

    if( (retc = archive_read_open_filename(sorc, spath, 64*1024)) != ARCHIVE_OK )
    {
        int         errn = archive_errno(sorc);
        const char* errs = archive_error_string(sorc);

        DEBUGLOGE;
        DEBUGLOGP("  (2) - unable to open archive (%d:%d)\n%s\n%s\n", retc, errn, errs, spath);
        return okay;
    }

    archive_entry* entry;

    while( true )
    {
        if( (retc = archive_read_next_header(sorc, &entry)) == ARCHIVE_EOF )
        {
            DEBUGLOGS("archive_read_next_header returned 'eof'");
            okay = true;
            break;
        }

        if( retc != ARCHIVE_OK )
        {
            DEBUGLOGS("archive_read_next_header returned 'archive not ok' error");
            break;
        }

        char    destPath[PATH_MAX];
        strvcpy(destPath, dpath);
        strvcat(destPath, archive_entry_pathname(entry));

        DEBUGLOGP("extracting %s\n", destPath);

        archive_entry_set_pathname(entry, destPath);

        if( (retc = archive_write_header(dest, entry)) != ARCHIVE_OK )
        {
            DEBUGLOGS("archive_write_header returned 'archive not ok' error");
            break;
        }

        copyData(sorc, dest);

        if( (retc = archive_write_finish_entry(dest)) != ARCHIVE_OK )
        {
            DEBUGLOGS("archive_write_finish returned 'archive not ok' error");
            break;
        }
    }

    archive_write_free(dest);
    archive_read_free(sorc);

    DEBUGLOGE;
    return okay;
}
int extractArchive(const char* filename, const char* directory) {
	struct archive *a;
	struct archive *ext;
	struct archive_entry *entry;
	int r;
	int flags = ARCHIVE_EXTRACT_TIME;
	int warnCount = 0;
	int dirlen = strlen(directory);
	a = archive_read_new();
	ext = archive_write_disk_new();
	archive_write_disk_set_options(ext, flags);
	/*
	 * Note: archive_write_disk_set_standard_lookup() is useful
	 * here, but it requires library routines that can add 500k or
	 * more to a static executable.
	 */
	archive_read_support_compression_gzip(a);
	archive_read_support_format_tar(a);
	/*
	 * On my system, enabling other archive formats adds 20k-30k
	 * each.  Enabling gzip decompression adds about 20k.
	 * Enabling bzip2 is more expensive because the libbz2 library
	 * isn't very well factored.
	 */
	if (filename != NULL && strcmp(filename, "-") == 0)
		filename = NULL;
	if ((r = archive_read_open_file(a, filename, 10240))) {
		printf("%s\n", archive_error_string(a));
		return -1;
	}
	while (true) {
		r = archive_read_next_header(a, &entry);
		if (r == ARCHIVE_EOF)
			break;
		if (r != ARCHIVE_OK) {
			printf("%s\n", archive_error_string(a));
			return -1;
		}
		//Set entry to be extracted under the given directory
		const char* path = archive_entry_pathname(entry);
		int pathlength = dirlen + strlen(path) + 2; //One for / and the other for '\0'
		char newPath[pathlength];
		snprintf(newPath, pathlength, "%s/%s", directory, path);
		archive_entry_set_pathname(entry, newPath);

		r = archive_write_header(ext, entry);
		if (r != ARCHIVE_OK) {
			printf("%s\n", archive_error_string(ext));
			warnCount++;
		} else {
			copy_data(a, ext);
			r = archive_write_finish_entry(ext);
			if (r != ARCHIVE_OK) {
				printf("%s\n", archive_error_string(ext));
				warnCount++;
			}
		}
	}
	archive_read_close(a);
	//archive_read_free(a);
	return warnCount;
}
Beispiel #6
0
/*
 * The main archive extract function, loops over the archive entries and unpack
 * them at the right place.
 */
void
extract(const char *extname, const char *filename)
{
    struct archive *a;
    struct archive *ext;
    struct archive_entry *entry;
    int flags = ARCHIVE_EXTRACT_TIME;
    int r;

    char *control_filename = psprintf("%s.control", extname);
    int cflen = strlen(control_filename);

    a = archive_read_new();
    ext = archive_write_disk_new();
    archive_write_disk_set_options(ext, flags);

    /*
     * Do we care enough about the .so size to limit ourselves here? We might
     * want to reconsider and use archive_read_support_format_all() and
     * archive_read_support_filter_all() rather than just tar.gz.
     */
    archive_read_support_format_tar(a);
    archive_read_support_filter_gzip(a);

    if ((archive_read_open_filename(a, filename, 10240)))
        ereport(ERROR,
                (errcode(ERRCODE_INVALID_PARAMETER_VALUE),
                 errmsg("Failed to open archive \"%s\"", filename),
                 errdetail("%s", archive_error_string(a))));

    elog(DEBUG1, "Unpacking archive \"%s\"", filename);

    for (;;)
    {
        char *path;
        struct archive_entry *target;

        r = archive_read_next_header(a, &entry);
        if (r == ARCHIVE_EOF)
            break;

        if (r != ARCHIVE_OK)
            ereport(ERROR,
                    (errcode(ERRCODE_UNDEFINED_FILE),
                     errmsg("%s", archive_error_string(a))));

        target = archive_entry_clone(entry);
        path   = (char *)archive_entry_pathname(target);
        path   = (char *)compute_target_path(path, control_filename, cflen);
        archive_entry_set_pathname(target, path);

        elog(DEBUG1, "Extracting \"%s\" to \"%s\"",
             archive_entry_pathname(entry), path);

        r = archive_write_header(ext, target);

        if (r != ARCHIVE_OK)
            ereport(WARNING,
                    (errcode(ERRCODE_IO_ERROR),
                     errmsg("%s", archive_error_string(ext))));
        else
        {
            copy_data(a, ext);
            r = archive_write_finish_entry(ext);
            if (r != ARCHIVE_OK)
                ereport(ERROR,
                        (errcode(ERRCODE_IO_ERROR),
                         errmsg("%s", archive_error_string(ext))));
        }
        archive_entry_free(target);
    }

    archive_read_close(a);
    archive_read_free(a);
}
bool ExtractArchive(const char *zip_file, const char *out_dir)
{
   struct archive *input = archive_read_new();
   archive_read_support_format_all(input);
   archive_read_support_compression_all(input);
   struct archive *output = archive_write_disk_new();
   archive_write_disk_set_options(output, ARCHIVE_EXTRACT_TIME);
   archive_write_disk_set_standard_lookup(output);
   const int BLOCK_SIZE = 65536;
   int r = archive_read_open_filename(input, zip_file, BLOCK_SIZE);

   if (r != ARCHIVE_OK)
   {
      debug(("Error opening archive %s: %s\n", zip_file, archive_error_string(input)));
      extraction_error = IDS_BADARCHIVE;
      return false;
   }

   // libarchive can only extract into the current directory, so we
   // need to set it and restore it.
   char original_dir[MAX_PATH];
   getcwd(original_dir, sizeof(original_dir));
   chdir(out_dir);
   
   bool retval = true;
   while (true)
   {
      struct archive_entry *entry;
      r = archive_read_next_header(input, &entry);
      if (r == ARCHIVE_EOF)
         break;
      
      if (r != ARCHIVE_OK)
      {
         debug(("Error reading archive header: %s\n", archive_error_string(input)));
         extraction_error = IDS_BADARCHIVE;
         retval = false;
         break;
      }
      r = archive_write_header(output, entry);
      if (r != ARCHIVE_OK)
      {
         debug(("Error writing archive header: %s\n", archive_error_string(input)));
         extraction_error = IDS_UNKNOWNERROR;
         retval = false;
         break;
      }

      if (archive_entry_size(entry) > 0)
      {
         r = CopyArchiveData(input, output);
         if (r != ARCHIVE_OK)
         {
            debug(("CopyArchiveData error: %s\n", archive_error_string(input)));
            extraction_error = IDS_UNKNOWNERROR;
            retval = false;
            break;
         }
      }
      r = archive_write_finish_entry(output);
      if (r != ARCHIVE_OK)
      {
         debug(("write_finish_entry error: %s\n", archive_error_string(input)));
         extraction_error = IDS_UNKNOWNERROR;
         retval = false;
         break;
      }

      debug(("Archive file %s extracted\n", archive_entry_pathname(entry)));
      
      // Extraction went OK; process Windows messages
      ClearMessageQueue();  // Check for user hitting abort button

      // Check for user abort
      if (abort_download)
      {
         retval = false;
         break;
      }
   }
   archive_read_close(input);
   archive_read_free(input);
   archive_write_close(output);
   archive_write_free(output);

   // Go back to original working directory
   chdir(original_dir);

   return retval;
}
Beispiel #8
0
static void *
extract(void *p)
{
	struct archive *a;
	struct archive *ext;
	struct archive_entry *entry;
	int r;
	int flags;
	struct extract_data *data = (struct extract_data *)p;
	flags = data->flags;

	a = archive_read_new();
	ext = archive_write_disk_new();
	archive_write_disk_set_options(ext, flags);
	/*
	 * Note: archive_write_disk_set_standard_lookup() is useful
	 * here, but it requires library routines that can add 500k or
	 * more to a static executable.
	 */
	archive_read_support_format_all(a);
	archive_read_support_filter_all(a);

	/*
	 * On my system, enabling other archive formats adds 20k-30k
	 * each.  Enabling gzip decompression adds about 20k.
	 * Enabling bzip2 is more expensive because the libbz2 library
	 * isn't very well factored.
	 */
	char* FIFO = alloca(strlen(get_tmpdir())+strlen(FIFO_FILE_NAME)+1);
	sprintf(FIFO, "%s%s", get_tmpdir(), FIFO_FILE_NAME);
	if ((r = archive_read_open_filename(a, FIFO, 4096))) {
		ERROR("archive_read_open_filename(): %s %d",
		    archive_error_string(a), r);
		pthread_exit((void *)-1);
	}
	for (;;) {
		r = archive_read_next_header(a, &entry);
		if (r == ARCHIVE_EOF)
			break;
		if (r != ARCHIVE_OK) {
			ERROR("archive_read_next_header(): %s %d",
			    archive_error_string(a), 1);
			pthread_exit((void *)-1);
		}

		if (debug)
			TRACE("Extracting %s", archive_entry_pathname(entry));

		r = archive_write_header(ext, entry);
		if (r != ARCHIVE_OK)
			TRACE("archive_write_header(): %s",
			    archive_error_string(ext));
		else {
			copy_data(a, ext);
			r = archive_write_finish_entry(ext);
			if (r != ARCHIVE_OK)  {
				ERROR("archive_write_finish_entry(): %s",
				    archive_error_string(ext));
				pthread_exit((void *)-1);
			}
		}

	}

	archive_read_close(a);
	archive_read_free(a);
	pthread_exit((void *)0);
}