Exemplo n.º 1
0
void Writer::set_format_helper(struct archive *ar, int format)
{
    std::string error_msg;

    switch(format) {
        case Archive::FORMAT_AR_BSD:
            archive_write_set_format_ar_bsd(ar);
            break;
        case Archive::FORMAT_AR_SVR4:
            archive_write_set_format_ar_svr4(ar);
            break;
        case Archive::FORMAT_CPIO:
            archive_write_set_format_cpio(ar);
            break;
        case Archive::FORMAT_CPIO_NEWC:
            archive_write_set_format_cpio_newc(ar);
            break;
        case Archive::FORMAT_MTREE:
            archive_write_set_format_mtree(ar);
            break;
        case Archive::FORMAT_TAR:
        case Archive::FORMAT_TAR_PAX_RESTRICTED:
            archive_write_set_format_pax_restricted(ar);
            break;
        case Archive::FORMAT_TAR_PAX_INTERCHANGE:
            archive_write_set_format_pax(ar);
            break;
        case Archive::FORMAT_TAR_USTAR:
            archive_write_set_format_ustar(ar);
            break;
        default:
            error_msg = "unknown or unsupported archive format";
            throw Error(error_msg);
    }
}
Exemplo n.º 2
0
void
pkg_sign_gpg(const char *name, const char *output)
{
	struct archive *pkg;
	struct archive_entry *entry, *hash_entry, *sign_entry;
	int fd;
	struct stat sb;
	char *hash_file, *signature_file, *tmp, *pkgname, hash[SHA512_DIGEST_STRING_LENGTH];
	unsigned char block[65536];
	off_t i, size;
	size_t block_len, signature_len;

	if ((fd = open(name, O_RDONLY)) == -1)
		err(EXIT_FAILURE, "Cannot open binary package %s", name);
	if (fstat(fd, &sb) == -1)
		err(EXIT_FAILURE, "Cannot stat %s", name);

	entry = archive_entry_new();
	archive_entry_copy_stat(entry, &sb);

	pkgname = extract_pkgname(fd);
	hash_file = xasprintf(hash_template, pkgname,
	    (long long)archive_entry_size(entry));
	free(pkgname);

	for (i = 0; i < archive_entry_size(entry); i += block_len) {
		if (i + (off_t)sizeof(block) < archive_entry_size(entry))
			block_len = sizeof(block);
		else
			block_len = archive_entry_size(entry) % sizeof(block);
		if (read(fd, block, block_len) != (ssize_t)block_len)
			err(2, "short read");
		hash_block(block, block_len, hash);
		tmp = xasprintf("%s%s\n", hash_file, hash);
		free(hash_file);
		hash_file = tmp;
	}
	tmp = xasprintf("%s%s", hash_file, hash_trailer);
	free(hash_file);
	hash_file = tmp;

	if (detached_gpg_sign(hash_file, strlen(hash_file), &signature_file,
	    &signature_len, gpg_keyring_sign, gpg_sign_as))
		err(EXIT_FAILURE, "Cannot sign hash file");

	lseek(fd, 0, SEEK_SET);

	sign_entry = archive_entry_clone(entry);
	hash_entry = archive_entry_clone(entry);
	pkgname = strrchr(name, '/');
	archive_entry_set_pathname(entry, pkgname != NULL ? pkgname + 1 : name);
	archive_entry_set_pathname(hash_entry, HASH_FNAME);
	archive_entry_set_pathname(sign_entry, GPG_SIGNATURE_FNAME);
	archive_entry_set_size(hash_entry, strlen(hash_file));
	archive_entry_set_size(sign_entry, signature_len);

	pkg = archive_write_new();
	archive_write_set_compression_none(pkg);
	archive_write_set_format_ar_bsd(pkg);
	archive_write_open_filename(pkg, output);

	archive_write_header(pkg, hash_entry);
	archive_write_data(pkg, hash_file, strlen(hash_file));
	archive_write_finish_entry(pkg);
	archive_entry_free(hash_entry);

	archive_write_header(pkg, sign_entry);
	archive_write_data(pkg, signature_file, signature_len);
	archive_write_finish_entry(pkg);
	archive_entry_free(sign_entry);

	size = archive_entry_size(entry);
	archive_write_header(pkg, entry);

	for (i = 0; i < size; i += block_len) {
		if (i + (off_t)sizeof(block) < size)
			block_len = sizeof(block);
		else
			block_len = size % sizeof(block);
		if (read(fd, block, block_len) != (ssize_t)block_len)
			err(2, "short read");
		archive_write_data(pkg, block, block_len);
	}
	archive_write_finish_entry(pkg);
	archive_entry_free(entry);

	archive_write_finish(pkg);

	close(fd);

	exit(0);
}