Пример #1
0
static int
pack_db(const char *name, const char *archive, char *path, struct rsa_key *rsa)
{
	struct packing *pack;
	unsigned char *sigret = NULL;
	unsigned int siglen = 0;

	if (packing_init(&pack, archive, TXZ) != EPKG_OK)
		return (EPKG_FATAL);

	if (rsa != NULL) {
		if (rsa_sign(path, rsa, &sigret, &siglen) != EPKG_OK) {
			packing_finish(pack);
			return (EPKG_FATAL);
		}

		if (packing_append_buffer(pack, sigret, "signature", siglen + 1) != EPKG_OK) {
			free(sigret);
			free(pack);
			return (EPKG_FATAL);
		}

		free(sigret);
	}
	packing_append_file_attr(pack, path, name, "root", "wheel", 0644);

	unlink(path);
	packing_finish(pack);

	return (EPKG_OK);
}
Пример #2
0
int
pkg_finish_repo(char *path, pem_password_cb *password_cb, char *rsa_key_path)
{
	char repo_path[MAXPATHLEN + 1];
	char repo_archive[MAXPATHLEN + 1];
	struct packing *pack;
	unsigned char *sigret = NULL;
	unsigned int siglen = 0;
	
	if (!is_dir(path)) {
	    pkg_emit_error("%s is not a directory", path);
	    return (EPKG_FATAL);
	}

	snprintf(repo_path, sizeof(repo_path), "%s/repo.sqlite", path);
	snprintf(repo_archive, sizeof(repo_archive), "%s/repo", path);

	packing_init(&pack, repo_archive, TXZ);
	if (rsa_key_path != NULL) {
		rsa_sign(repo_path, password_cb, rsa_key_path, &sigret,
				&siglen);

		packing_append_buffer(pack, sigret, "signature", siglen + 1);

		free(sigret);
	}
	packing_append_file_attr(pack, repo_path, "repo.sqlite",
	    "root", "wheel", 0644);
	unlink(repo_path);
	packing_finish(pack);

	return (EPKG_OK);
}
Пример #3
0
int
pkg_finish_repo(char *path, pem_password_cb *password_cb, char *rsa_key_path)
{
	char repo_path[MAXPATHLEN + 1];
	char repo_archive[MAXPATHLEN + 1];
	struct packing *pack;
	int max_len = 0;
	unsigned char *sigret = NULL;
	int siglen = 0;
	RSA *rsa = NULL;
	char sha256[SHA256_DIGEST_LENGTH * 2 +1];

	snprintf(repo_path, sizeof(repo_path), "%s/repo.sqlite", path);
	snprintf(repo_archive, sizeof(repo_archive), "%s/repo", path);

	packing_init(&pack, repo_archive, TXZ);
	if (rsa_key_path != NULL) {
		if (access(rsa_key_path, R_OK) == -1) {
			pkg_emit_errno("access", rsa_key_path);
			return EPKG_FATAL;
		}

		SSL_load_error_strings();

		OpenSSL_add_all_algorithms();
		OpenSSL_add_all_ciphers();

		rsa = load_rsa_private_key(rsa_key_path, password_cb);
		max_len = RSA_size(rsa);
		sigret = malloc(max_len + 1);
		memset(sigret, 0, max_len);

		sha256_file(repo_path, sha256);

		if (RSA_sign(NID_sha1, sha256, sizeof(sha256), sigret, &siglen, rsa) == 0) {
			/* XXX pass back RSA errors correctly */
			pkg_emit_error("%s: %lu", rsa_key_path, ERR_get_error());
			return EPKG_FATAL;
		}

		packing_append_buffer(pack, sigret, "signature", siglen + 1);

		free(sigret);
		RSA_free(rsa);
		ERR_free_strings();
	}
	packing_append_file(pack, repo_path, "repo.sqlite");
	unlink(repo_path);
	packing_finish(pack);

	return (EPKG_OK);
}
Пример #4
0
static int
pkg_create_from_dir(struct pkg *pkg, const char *root,
    struct packing *pkg_archive)
{
	char		 fpath[MAXPATHLEN];
	struct pkg_file	*file = NULL;
	struct pkg_dir	*dir = NULL;
	char		*m;
	int		 ret;
	const char	*mtree;
	bool		 developer;
	struct stat	 st;
	char		 sha256[SHA256_DIGEST_LENGTH * 2 + 1];
	int64_t		 flatsize = 0;
	ucl_object_t	*obj;

	if (pkg_is_valid(pkg) != EPKG_OK) {
		pkg_emit_error("the package is not valid");
		return (EPKG_FATAL);
	}

	obj = pkg_annotation_lookup(pkg, "relocated");

	/*
	 * Get / compute size / checksum if not provided in the manifest
	 */
	while (pkg_files(pkg, &file) == EPKG_OK) {
		const char *pkg_path = pkg_file_path(file);
		const char *pkg_sum = pkg_file_cksum(file);

		snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
		    obj ? pkg_object_string(obj) : "", pkg_path);

		if (lstat(fpath, &st) != 0 || S_ISLNK(st.st_mode))
			continue;

		if (file->size == 0)
			file->size = (int64_t)st.st_size;
		flatsize += file->size;

		if (pkg_sum == NULL || pkg_sum[0] == '\0') {
			if (pkg->type == PKG_OLD_FILE) {
				if (md5_file(fpath, sha256) != EPKG_OK)
					return (EPKG_FATAL);
			} else {
				if (sha256_file(fpath, sha256) != EPKG_OK)
					return (EPKG_FATAL);
			}
			strlcpy(file->sum, sha256, sizeof(file->sum));
		}
	}
	pkg_set(pkg, PKG_FLATSIZE, flatsize);

	if (pkg->type == PKG_OLD_FILE) {
		const char *desc, *display, *comment;
		char oldcomment[BUFSIZ];

		pkg_old_emit_content(pkg, &m);
		packing_append_buffer(pkg_archive, m, "+CONTENTS", strlen(m));
		free(m);

		pkg_get(pkg, PKG_DESC, &desc, PKG_MESSAGE, &display, PKG_COMMENT, &comment);
		packing_append_buffer(pkg_archive, desc, "+DESC", strlen(desc));
		packing_append_buffer(pkg_archive, display, "+DISPLAY", strlen(display));
		snprintf(oldcomment, sizeof(oldcomment), "%s\n", comment);
		packing_append_buffer(pkg_archive, oldcomment, "+COMMENT", strlen(oldcomment));
	} else {
		/*
		 * Register shared libraries used by the package if
		 * SHLIBS enabled in conf.  Deletes shlib info if not.
		 */
		struct sbuf *b = sbuf_new_auto();

		pkg_register_shlibs(pkg, root);

		pkg_emit_manifest_sbuf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL);
		packing_append_buffer(pkg_archive, sbuf_data(b), "+COMPACT_MANIFEST", sbuf_len(b));
		sbuf_clear(b);
		pkg_emit_manifest_sbuf(pkg, b, 0, NULL);
		sbuf_finish(b);
		packing_append_buffer(pkg_archive, sbuf_data(b), "+MANIFEST", sbuf_len(b));
		sbuf_delete(b);
	}

	pkg_get(pkg, PKG_MTREE, &mtree);
	if (mtree != NULL)
		packing_append_buffer(pkg_archive, mtree, "+MTREE_DIRS",
		    strlen(mtree));

	while (pkg_files(pkg, &file) == EPKG_OK) {
		const char *pkg_path = pkg_file_path(file);

		snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
		    obj ? pkg_object_string(obj) : "", pkg_path);

		ret = packing_append_file_attr(pkg_archive, fpath, pkg_path,
		    file->uname, file->gname, file->perm);
		developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));
		if (developer && ret != EPKG_OK)
			return (ret);
	}

	while (pkg_dirs(pkg, &dir) == EPKG_OK) {
		const char *pkg_path = pkg_dir_path(dir);

		snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
		    obj ? pkg_object_string(obj) : "", pkg_path);

		ret = packing_append_file_attr(pkg_archive, fpath, pkg_path,
		    dir->uname, dir->gname, dir->perm);
		developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));
		if (developer && ret != EPKG_OK)
			return (ret);
	}

	return (EPKG_OK);
}
Пример #5
0
static int
pkg_create_from_dir(struct pkg *pkg, const char *root, struct packing *pkg_archive)
{
	char fpath[MAXPATHLEN];
	struct pkg_file **files;
	struct pkg_script **scripts;
	char *m;
	int i;
	const char *scriptname = NULL;

	pkg_emit_manifest(pkg, &m);

	packing_append_buffer(pkg_archive, m, "+MANIFEST", strlen(m));

	free(m);

	packing_append_buffer(pkg_archive, pkg_get(pkg, PKG_DESC), "+DESC", strlen(pkg_get(pkg, PKG_DESC)));
	packing_append_buffer(pkg_archive, pkg_get(pkg, PKG_MTREE), "+MTREE_DIRS", strlen(pkg_get(pkg, PKG_MTREE)));

	if ((scripts = pkg_scripts(pkg)) != NULL) {
		for (i = 0; scripts[i] != NULL; i++) {
			switch (pkg_script_type(scripts[i])) {
				case PKG_SCRIPT_PRE_INSTALL:
					scriptname = "+PRE_INSTALL";
					break;
				case PKG_SCRIPT_POST_INSTALL:
					scriptname = "+POST_INSTALL";
					break;
				case PKG_SCRIPT_INSTALL:
					scriptname = "+INSTALL";
					break;
				case PKG_SCRIPT_PRE_DEINSTALL:
					scriptname = "+PRE_DEINSTALL";
					break;
				case PKG_SCRIPT_POST_DEINSTALL:
					scriptname = "+POST_DEINSTALL";
					break;
				case PKG_SCRIPT_DEINSTALL:
					scriptname = "+DEINSTALL";
					break;
				case PKG_SCRIPT_PRE_UPGRADE:
					scriptname = "+PRE_UPGRADE";
					break;
				case PKG_SCRIPT_POST_UPGRADE:
					scriptname = "+POST_UPGRADE";
					break;
				case PKG_SCRIPT_UPGRADE:
					scriptname = "+UPGRADE";
					break;
			}
			packing_append_buffer(pkg_archive, pkg_script_data(scripts[i]), scriptname, strlen(pkg_script_data(scripts[i])));
		}
	}

	if ((files = pkg_files(pkg)) != NULL) {
		for (i = 0; files[i] != NULL; i++) {

			if (root != NULL)
				snprintf(fpath, sizeof(MAXPATHLEN), "%s%s", root, pkg_file_path(files[i]));
			else
				strlcpy(fpath, pkg_file_path(files[i]), MAXPATHLEN);

			packing_append_file(pkg_archive, fpath, pkg_file_path(files[i]));
		}
	}

	return (EPKG_OK);
}
Пример #6
0
static int
pkg_create_from_dir(struct pkg *pkg, const char *root,
    struct packing *pkg_archive)
{
	char		 fpath[MAXPATHLEN];
	struct pkg_file	*file = NULL;
	struct pkg_dir	*dir = NULL;
	int		 ret;
	struct stat	 st;
	int64_t		 flatsize = 0;
	int64_t		 nfiles;
	const char	*relocation;
	hardlinks_t	*hardlinks;

	if (pkg_is_valid(pkg) != EPKG_OK) {
		pkg_emit_error("the package is not valid");
		return (EPKG_FATAL);
	}

	relocation = pkg_kv_get(&pkg->annotations, "relocated");
	if (relocation == NULL)
		relocation = "";
	if (pkg_rootdir != NULL)
		relocation = pkg_rootdir;

	/*
	 * Get / compute size / checksum if not provided in the manifest
	 */

	nfiles = kh_count(pkg->filehash);
	counter_init("file sizes/checksums", nfiles);

	hardlinks = kh_init_hardlinks();
	while (pkg_files(pkg, &file) == EPKG_OK) {

		snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
		    relocation, file->path);

		if (lstat(fpath, &st) == -1) {
			pkg_emit_error("file '%s' is missing", fpath);
			return (EPKG_FATAL);
		}

		if (file->size == 0)
			file->size = (int64_t)st.st_size;

		if (st.st_nlink == 1 || !check_for_hardlink(hardlinks, &st)) {
			flatsize += file->size;
		}

		file->sum = pkg_checksum_generate_file(fpath,
		    PKG_HASH_TYPE_SHA256_HEX);
		if (file->sum == NULL)
			return (EPKG_FATAL);

		counter_count();
	}
	kh_destroy_hardlinks(hardlinks);

	counter_end();

	pkg->flatsize = flatsize;

	if (pkg->type == PKG_OLD_FILE) {
		pkg_emit_error("Cannot create an old format package");
		return (EPKG_FATAL);
	} else {
		/*
		 * Register shared libraries used by the package if
		 * SHLIBS enabled in conf.  Deletes shlib info if not.
		 */
		struct sbuf *b = sbuf_new_auto();

		pkg_analyse_files(NULL, pkg, root);

		pkg_emit_manifest_sbuf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL);
		packing_append_buffer(pkg_archive, sbuf_data(b), "+COMPACT_MANIFEST", sbuf_len(b));
		sbuf_clear(b);
		pkg_emit_manifest_sbuf(pkg, b, 0, NULL);
		sbuf_finish(b);
		packing_append_buffer(pkg_archive, sbuf_data(b), "+MANIFEST", sbuf_len(b));
		sbuf_delete(b);
	}

	counter_init("packing files", nfiles);

	while (pkg_files(pkg, &file) == EPKG_OK) {

		snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
		    relocation, file->path);

		ret = packing_append_file_attr(pkg_archive, fpath, file->path,
		    file->uname, file->gname, file->perm, file->fflags);
		if (developer_mode && ret != EPKG_OK)
			return (ret);
		counter_count();
	}

	counter_end();

	nfiles = kh_count(pkg->dirhash);
	counter_init("packing directories", nfiles);

	while (pkg_dirs(pkg, &dir) == EPKG_OK) {
		snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
		    relocation, dir->path);

		ret = packing_append_file_attr(pkg_archive, fpath, dir->path,
		    dir->uname, dir->gname, dir->perm, dir->fflags);
		if (developer_mode && ret != EPKG_OK)
			return (ret);
		counter_count();
	}

	counter_end();

	return (EPKG_OK);
}
Пример #7
0
static int
pkg_create_from_dir(struct pkg *pkg, const char *root,
                    struct packing *pkg_archive)
{
    char		 fpath[MAXPATHLEN + 1];
    struct pkg_file	*file = NULL;
    struct pkg_dir	*dir = NULL;
    char		*m;
    int		 ret;
    const char	*mtree;
    bool		 developer;
    struct stat	 st;
    char		 sha256[SHA256_DIGEST_LENGTH * 2 + 1];

    if (pkg_is_valid(pkg) != EPKG_OK) {
        pkg_emit_error("the package is not valid");
        return (EPKG_FATAL);
    }
    /*
     * if the checksum is not provided in the manifest recompute it
     */
    while (pkg_files(pkg, &file) == EPKG_OK) {
        const char *pkg_path = pkg_file_path(file);
        const char *pkg_sum = pkg_file_cksum(file);

        if (root != NULL)
            snprintf(fpath, sizeof(fpath), "%s%s", root, pkg_path);
        else
            strlcpy(fpath, pkg_path, sizeof(fpath));

        if ((pkg_sum == NULL || pkg_sum[0] == '\0') &&
                lstat(fpath, &st) == 0 && !S_ISLNK(st.st_mode)) {
            if (sha256_file(fpath, sha256) != EPKG_OK)
                return (EPKG_FATAL);
            strlcpy(file->sum, sha256, sizeof(file->sum));
        }
    }

    /*
     * Register shared libraries used by the package if SHLIBS
     * enabled in conf.  Deletes shlib info if not.
     */
    pkg_register_shlibs(pkg);

    pkg_emit_manifest(pkg, &m);
    packing_append_buffer(pkg_archive, m, "+MANIFEST", strlen(m));
    free(m);

    pkg_get(pkg, PKG_MTREE, &mtree);
    if (mtree != NULL)
        packing_append_buffer(pkg_archive, mtree, "+MTREE_DIRS",
                              strlen(mtree));

    while (pkg_files(pkg, &file) == EPKG_OK) {
        const char *pkg_path = pkg_file_path(file);

        if (root != NULL)
            snprintf(fpath, sizeof(fpath), "%s%s", root, pkg_path);
        else
            strlcpy(fpath, pkg_path, sizeof(fpath));

        ret = packing_append_file_attr(pkg_archive, fpath, pkg_path,
                                       file->uname, file->gname, file->perm);
        pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer);
        if (developer && ret != EPKG_OK)
            return (ret);
    }

    while (pkg_dirs(pkg, &dir) == EPKG_OK) {
        const char *pkg_path = pkg_dir_path(dir);
        if (root != NULL)
            snprintf(fpath, sizeof(fpath), "%s%s", root, pkg_path);
        else
            strlcpy(fpath, pkg_dir_path(dir), sizeof(fpath));

        ret = packing_append_file_attr(pkg_archive, fpath, pkg_path,
                                       dir->uname, dir->gname, dir->perm);
        pkg_config_bool(PKG_CONFIG_DEVELOPER_MODE, &developer);
        if (developer && ret != EPKG_OK)
            return (ret);
    }

    return (EPKG_OK);
}
Пример #8
0
static int
pkg_create_from_dir(struct pkg *pkg, const char *root,
    struct packing *pkg_archive)
{
	char		 fpath[MAXPATHLEN];
	struct pkg_file	*file = NULL;
	struct pkg_dir	*dir = NULL;
	char		*m;
	int		 ret;
	bool		 developer;
	struct stat	 st;
	char		 sha256[SHA256_DIGEST_LENGTH * 2 + 1];
	int64_t		 flatsize = 0;
	const char	*relocation;
	struct hardlinks *hardlinks = NULL;

	if (pkg_is_valid(pkg) != EPKG_OK) {
		pkg_emit_error("the package is not valid");
		return (EPKG_FATAL);
	}

	relocation = pkg_kv_get(&pkg->annotations, "relocated");
	if (relocation == NULL)
		relocation = "";

	/*
	 * Get / compute size / checksum if not provided in the manifest
	 */
	while (pkg_files(pkg, &file) == EPKG_OK) {

		snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
		    relocation, file->path);

		if (lstat(fpath, &st) == -1) {
			pkg_emit_error("file '%s' is missing", fpath);
			return (EPKG_FATAL);
		}

		if (file->size == 0)
			file->size = (int64_t)st.st_size;

		if (st.st_nlink == 1 || !check_for_hardlink(&hardlinks, &st)) {
			flatsize += file->size;
		}

		if (S_ISLNK(st.st_mode)) {

			if (file->sum[0] == '\0') {
				if (pkg_symlink_cksum(fpath, root, sha256) == EPKG_OK)
					strlcpy(file->sum, sha256, sizeof(file->sum));
				else
					return (EPKG_FATAL);
			}
		}
		else {
			if (file->sum[0] == '\0') {
				if (pkg->type == PKG_OLD_FILE) {
					if (md5_file(fpath, sha256) != EPKG_OK)
						return (EPKG_FATAL);
				} else {
					if (sha256_file(fpath, sha256) != EPKG_OK)
						return (EPKG_FATAL);
				}
				strlcpy(file->sum, sha256, sizeof(file->sum));
			}
		}
	}
	pkg->flatsize = flatsize;
	HASH_FREE(hardlinks, free);

	if (pkg->type == PKG_OLD_FILE) {
		char oldcomment[BUFSIZ];

		pkg_old_emit_content(pkg, &m);
		packing_append_buffer(pkg_archive, m, "+CONTENTS", strlen(m));
		free(m);

		packing_append_buffer(pkg_archive, pkg->desc, "+DESC", strlen(pkg->desc));
		packing_append_buffer(pkg_archive, pkg->message, "+DISPLAY", strlen(pkg->message));
		pkg_snprintf(oldcomment, sizeof(oldcomment), "%c\n", pkg);
		packing_append_buffer(pkg_archive, oldcomment, "+COMMENT", strlen(oldcomment));
	} else {
		/*
		 * Register shared libraries used by the package if
		 * SHLIBS enabled in conf.  Deletes shlib info if not.
		 */
		struct sbuf *b = sbuf_new_auto();

		pkg_analyse_files(NULL, pkg, root);

		pkg_emit_manifest_sbuf(pkg, b, PKG_MANIFEST_EMIT_COMPACT, NULL);
		packing_append_buffer(pkg_archive, sbuf_data(b), "+COMPACT_MANIFEST", sbuf_len(b));
		sbuf_clear(b);
		pkg_emit_manifest_sbuf(pkg, b, 0, NULL);
		sbuf_finish(b);
		packing_append_buffer(pkg_archive, sbuf_data(b), "+MANIFEST", sbuf_len(b));
		sbuf_delete(b);
	}

	while (pkg_files(pkg, &file) == EPKG_OK) {

		snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
		    relocation, file->path);

		ret = packing_append_file_attr(pkg_archive, fpath, file->path,
		    file->uname, file->gname, file->perm);
		developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));
		if (developer && ret != EPKG_OK)
			return (ret);
	}

	while (pkg_dirs(pkg, &dir) == EPKG_OK) {
		snprintf(fpath, sizeof(fpath), "%s%s%s", root ? root : "",
		    relocation, dir->path);

		ret = packing_append_file_attr(pkg_archive, fpath, dir->path,
		    dir->uname, dir->gname, dir->perm);
		developer = pkg_object_bool(pkg_config_get("DEVELOPER_MODE"));
		if (developer && ret != EPKG_OK)
			return (ret);
	}

	return (EPKG_OK);
}