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); }
int packing_append_tree(struct packing *pack, const char *treepath, const char *newroot) { FTS *fts = NULL; FTSENT *fts_e = NULL; size_t treelen; struct sbuf *sb; char *paths[2] = { __DECONST(char *, treepath), NULL }; treelen = strlen(treepath); fts = fts_open(paths, FTS_PHYSICAL | FTS_XDEV, NULL); if (fts == NULL) goto cleanup; sb = sbuf_new_auto(); while ((fts_e = fts_read(fts)) != NULL) { switch(fts_e->fts_info) { case FTS_D: case FTS_DEFAULT: case FTS_F: case FTS_SL: case FTS_SLNONE: /* Entries not within this tree are irrelevant. */ if (fts_e->fts_pathlen <= treelen) break; sbuf_clear(sb); /* Strip the prefix to obtain the target path */ if (newroot) /* Prepend a root if one is specified */ sbuf_cat(sb, newroot); /* +1 = skip trailing slash */ sbuf_cat(sb, fts_e->fts_path + treelen + 1); sbuf_finish(sb); packing_append_file(pack, fts_e->fts_name, sbuf_get(sb)); break; case FTS_DC: case FTS_DNR: case FTS_ERR: case FTS_NS: /* XXX error cases, check fts_e->fts_errno and * bubble up the call chain */ break; default: break; } } sbuf_free(sb); cleanup: fts_close(fts); 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); }