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); }
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); }
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); }
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); }
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); }
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); }
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); }
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); }