예제 #1
0
int
pkg_delete_dirs(struct pkgdb *db, struct pkg *pkg, int force)
{
	struct pkg_dir *dir = NULL;
	int64_t nbpackage;

	while (pkg_dirs(pkg, &dir) == EPKG_OK) {
		nbpackage = 0;

		if (pkgdb_is_dir_used(db, pkg_dir_path(dir), &nbpackage) != EPKG_OK)
			return (EPKG_FATAL);

		if (nbpackage > 1)
			continue;

		if (pkg_dir_try(dir)) {
			if (rmdir(pkg_dir_path(dir)) == -1 && errno != ENOTEMPTY && force != 1)
				pkg_emit_errno("rmdir", pkg_dir_path(dir));
		} else {
			if (rmdir(pkg_dir_path(dir)) == -1 && force != 1)
				pkg_emit_errno("rmdir", pkg_dir_path(dir));
		}
	}

	return (EPKG_OK);
}
예제 #2
0
파일: utils.c 프로젝트: baloo/pkgng
int
sha256_file(const char *path, char out[SHA256_DIGEST_LENGTH * 2 + 1])
{
	FILE *fp;
	char buffer[BUFSIZ];
	unsigned char hash[SHA256_DIGEST_LENGTH];
	size_t r = 0;
	SHA256_CTX sha256;

	if ((fp = fopen(path, "rb")) == NULL) {
		pkg_emit_errno("fopen", path);
		return EPKG_FATAL;
	}

	SHA256_Init(&sha256);

	while ((r = fread(buffer, 1, BUFSIZ, fp)) > 0)
		SHA256_Update(&sha256, buffer, r);

	if (ferror(fp) != 0) {
		fclose(fp);
		out[0] = '\0';
		pkg_emit_errno("fread", path);
		return EPKG_FATAL;
	}

	fclose(fp);

	SHA256_Final(hash, &sha256);
	sha256_hash(hash, out);

	return (EPKG_OK);
}
예제 #3
0
파일: fetch.c 프로젝트: Moscarda/pkg
static int
pkg_repo_binary_create_symlink(struct pkg *pkg, const char *fname,
	const char *dir)
{
	const char *ext, *dest_fname;
	char link_dest_tmp[MAXPATHLEN], link_dest[MAXPATHLEN];

	/* Create symlink from full pkgname */
	ext = strrchr(fname, '.');
	pkg_snprintf(link_dest, sizeof(link_dest), "%S/%n-%v%S",
		dir, pkg, pkg, ext ? ext : "");
	snprintf(link_dest_tmp, sizeof(link_dest_tmp), "%s.new", link_dest);

	/* Ignore errors here */
	(void)unlink(link_dest_tmp);

	/* Trim the path to just the filename. */
	if ((dest_fname = strrchr(fname, '/')) != NULL)
		++dest_fname;
	if (symlink(dest_fname, link_dest_tmp) == -1) {
		pkg_emit_errno("symlink", link_dest);
		return (EPKG_FATAL);
	}

	if (rename(link_dest_tmp, link_dest) == -1) {
		pkg_emit_errno("rename", link_dest);
		unlink(link_dest_tmp);
		return (EPKG_FATAL);
	}

	return (EPKG_OK);
}
예제 #4
0
파일: packing.c 프로젝트: Absolight/pkg
int
packing_append_buffer(struct packing *pack, const char *buffer,
    const char *path, int size)
{
	struct archive_entry *entry;
	int ret = EPKG_OK;

	entry = archive_entry_new();
	archive_entry_clear(entry);
	archive_entry_set_filetype(entry, AE_IFREG);
	archive_entry_set_perm(entry, 0644);
	archive_entry_set_gname(entry, "wheel");
	archive_entry_set_uname(entry, "root");
	archive_entry_set_pathname(entry, path);
	archive_entry_set_size(entry, size);
	if (archive_write_header(pack->awrite, entry) == -1) {
		pkg_emit_errno("archive_write_header", path);
		ret = EPKG_FATAL;
		goto cleanup;
	}

	if (archive_write_data(pack->awrite, buffer, size) == -1) {
		pkg_emit_errno("archive_write_data", path);
		ret = EPKG_FATAL;
	}

cleanup:
	archive_entry_free(entry);

	return (ret);
}
예제 #5
0
파일: pkg_delete.c 프로젝트: rakhij/pkg
int
pkg_delete_dirs(__unused struct pkgdb *db, struct pkg *pkg, bool force)
{
	struct pkg_dir	*dir = NULL;
	ucl_object_t *obj;
	char		fpath[MAXPATHLEN];

	while (pkg_dirs(pkg, &dir) == EPKG_OK) {
		if (dir->keep == 1)
			continue;

		obj = pkg_annotation_lookup(pkg, "relocated");
		snprintf(fpath, sizeof(fpath), "%s%s",
		    obj ? pkg_object_string(obj) : "" , pkg_dir_path(dir) );

		if (pkg_dir_try(dir)) {
			if (rmdir(fpath) == -1 &&
			    errno != ENOTEMPTY && errno != EBUSY && !force)
				pkg_emit_errno("rmdir", fpath);
		} else {
			if (rmdir(fpath) == -1 && !force)
				pkg_emit_errno("rmdir", fpath);
		}
	}

	return (EPKG_OK);
}
예제 #6
0
static void
rm_rf(const char *path)
{
	DIR *d;
	struct dirent *e;
	struct stat st;
	char filepath[MAXPATHLEN];

	if ((d = opendir(path)) == NULL) {
		pkg_emit_errno("opendir", path);
		return;
	}

	while ((e = readdir(d)) != NULL) {
		if (strcmp(e->d_name, ".") == 0 || strcmp(e->d_name, "..") == 0)
			continue;
		snprintf(filepath, sizeof(filepath), "%s/%s", path, e->d_name);
		if (lstat(filepath, &st) != 0) {
			pkg_emit_errno("lstat", filepath);
			continue;
		}
		if (S_ISDIR(st.st_mode))
			rm_rf(filepath);
		remove(filepath);
	}
	closedir(d);
}
예제 #7
0
int
packing_init(struct packing **pack, const char *path, pkg_formats format)
{
	char archive_path[MAXPATHLEN];
	const char *ext;

	assert(pack != NULL);

	if ((*pack = calloc(1, sizeof(struct packing))) == NULL) {
		pkg_emit_errno("calloc", "packing");
		return (EPKG_FATAL);
	}

	(*pack)->aread = archive_read_disk_new();
	archive_read_disk_set_standard_lookup((*pack)->aread);
	archive_read_disk_set_symlink_physical((*pack)->aread);

	if (!is_dir(path)) {
		(*pack)->pass = false;
		(*pack)->awrite = archive_write_new();
		archive_write_set_format_pax_restricted((*pack)->awrite);
		ext = packing_set_format((*pack)->awrite, format);
		if (ext == NULL) {
			archive_read_close((*pack)->aread);
			archive_read_free((*pack)->aread);
			archive_write_close((*pack)->awrite);
			archive_write_free((*pack)->awrite);
			*pack = NULL;
			return EPKG_FATAL; /* error set by _set_format() */
		}
		snprintf(archive_path, sizeof(archive_path), "%s.%s", path,
		    ext);

		pkg_debug(1, "Packing to file '%s'", archive_path);
		if (archive_write_open_filename(
		    (*pack)->awrite, archive_path) != ARCHIVE_OK) {
			pkg_emit_errno("archive_write_open_filename",
			    archive_path);
			archive_read_close((*pack)->aread);
			archive_read_free((*pack)->aread);
			archive_write_close((*pack)->awrite);
			archive_write_free((*pack)->awrite);
			*pack = NULL;
			return EPKG_FATAL;
		}
	} else { /* pass mode directly write to the disk */
		pkg_debug(1, "Packing to directory '%s' (pass mode)", path);
		(*pack)->pass = true;
		(*pack)->awrite = archive_write_disk_new();
		archive_write_disk_set_options((*pack)->awrite,
		    EXTRACT_ARCHIVE_FLAGS);
	}

	(*pack)->resolver = archive_entry_linkresolver_new();
	archive_entry_linkresolver_set_strategy((*pack)->resolver,
	    ARCHIVE_FORMAT_TAR_PAX_RESTRICTED);

	return (EPKG_OK);
}
예제 #8
0
파일: utils.c 프로젝트: baloo/pkgng
int
file_to_buffer(const char *path, char **buffer, off_t *sz)
{
	int fd = -1;
	struct stat st;
	int retcode = EPKG_OK;

	assert(path != NULL && path[0] != '\0');
	assert(buffer != NULL);
	assert(sz != NULL);

	if ((fd = open(path, O_RDONLY)) == -1) {
		pkg_emit_errno("open", path);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (fstat(fd, &st) == -1) {
		close(fd);
		pkg_emit_errno("fstat", path);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if ((*buffer = malloc(st.st_size + 1)) == NULL) {
		close(fd);
		pkg_emit_errno("malloc", "");
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	if (read(fd, *buffer, st.st_size) == -1) {
		close(fd);
		pkg_emit_errno("read", path);
		retcode = EPKG_FATAL;
		goto cleanup;
	}

	cleanup:
	if (fd > 0)
		close(fd);

	if (retcode == EPKG_OK) {
		(*buffer)[st.st_size] = '\0';
		*sz = st.st_size;
	} else {
		*buffer = NULL;
		*sz = -1;
	}
	return (retcode);
}
예제 #9
0
파일: utils.c 프로젝트: dpl0/pkg
int
sha256_fd(int fd, char out[SHA256_DIGEST_LENGTH * 2 + 1])
{
	int my_fd = -1;
	FILE *fp = NULL;
	char buffer[BUFSIZ];
	unsigned char hash[SHA256_DIGEST_LENGTH];
	size_t r = 0;
	int ret = EPKG_OK;
	SHA256_CTX sha256;

	out[0] = '\0';

	/* Duplicate the fd so that fclose(3) does not close it. */
	if ((my_fd = dup(fd)) == -1) {
		pkg_emit_errno("dup", "");
		ret = EPKG_FATAL;
		goto cleanup;
	}

	if ((fp = fdopen(my_fd, "rb")) == NULL) {
		pkg_emit_errno("fdopen", "");
		ret = EPKG_FATAL;
		goto cleanup;
	}

	SHA256_Init(&sha256);

	while ((r = fread(buffer, 1, BUFSIZ, fp)) > 0)
		SHA256_Update(&sha256, buffer, r);

	if (ferror(fp) != 0) {
		pkg_emit_errno("fread", "");
		ret = EPKG_FATAL;
		goto cleanup;
	}

	SHA256_Final(hash, &sha256);
	sha256_hash(hash, out);
cleanup:

	if (fp != NULL)
		fclose(fp);
	else if (my_fd != -1)
		close(my_fd);
	(void)lseek(fd, 0, SEEK_SET);

	return (ret);
}
예제 #10
0
static void
rmdir_p(struct pkgdb *db, struct pkg *pkg, char *dir, const char *prefix_r)
{
	char *tmp;
	int64_t cnt;
	char fullpath[MAXPATHLEN];

	if (unlinkat(pkg->rootfd, dir, AT_REMOVEDIR) == -1 &&
	    errno != ENOTEMPTY && errno != EBUSY) {
		pkg_emit_errno("unlinkat", dir);
	}

	tmp = strrchr(dir, '/');
	if (tmp == dir)
		return;

	tmp[0] = '\0';
	tmp = strrchr(dir, '/');
	tmp[1] = '\0';

	snprintf(fullpath, sizeof(fullpath), "/%s", dir);
	if (pkgdb_is_dir_used(db, dir, &cnt) != EPKG_OK)
		return;

	if (cnt > 1)
		return;

	if (strcmp(prefix_r, dir) == 0)
		return;

	rmdir_p(db, pkg, dir, prefix_r);
}
예제 #11
0
int
pkg_delete_files(struct pkg *pkg, int force)
{
	struct pkg_file *file = NULL;
	char sha256[SHA256_DIGEST_LENGTH * 2 + 1];
	const char *path;

	while (pkg_files(pkg, &file) == EPKG_OK) {
		path = pkg_file_path(file);

		/* Regular files and links */
		/* check sha256 */
		if (!force && pkg_file_sha256(file)[0] != '\0') {
			if (sha256_file(path, sha256) == -1) {
				pkg_emit_error("sha256 calculation failed for '%s'",
					  path);
			} else if (strcmp(sha256, pkg_file_sha256(file)) != 0) {
				pkg_emit_error("%s fails original SHA256 checksum,"
							   " not removing", path);
				continue;
			}
		}

		if (unlink(path) == -1) {
			pkg_emit_errno("unlink", path);
			continue;
		}
	}

	return (EPKG_OK);
}
예제 #12
0
파일: rsa.c 프로젝트: AlexanderThaller/pkg
int
rsa_sign(char *path, struct rsa_key *rsa, unsigned char **sigret, unsigned int *siglen)
{
	char errbuf[1024];
	int max_len = 0, ret;
	char sha256[SHA256_DIGEST_LENGTH * 2 +1];

	if (access(rsa->path, R_OK) == -1) {
		pkg_emit_errno("access", rsa->path);
		return (EPKG_FATAL);
	}

	if (rsa->key == NULL && _load_rsa_private_key(rsa) != EPKG_OK) {
		pkg_emit_error("can't load key from %s", rsa->path);
		return (EPKG_FATAL);
	}

	max_len = RSA_size(rsa->key);
	*sigret = calloc(1, max_len + 1);

	sha256_file(path, sha256);

	ret = RSA_sign(NID_sha1, sha256, sizeof(sha256), *sigret, siglen, rsa->key);
	if (ret == 0) {
		/* XXX pass back RSA errors correctly */
		pkg_emit_error("%s: %s", rsa->path,
		   ERR_error_string(ERR_get_error(), errbuf));
		return (EPKG_FATAL);
	}

	return (EPKG_OK);
}
예제 #13
0
파일: pkg_delete.c 프로젝트: ongbe/pkgng
int
pkg_delete_files(struct pkg *pkg, bool force)
{
	struct pkg_file	*file = NULL;
	char		 sha256[SHA256_DIGEST_LENGTH * 2 + 1];
	const char	*path;

	while (pkg_files(pkg, &file) == EPKG_OK) {
		const char *sum = pkg_file_cksum(file);

		if (file->keep == 1)
			continue;

		path = pkg_file_path(file);

		/* Regular files and links */
		/* check sha256 */
		if (!force && sum[0] != '\0') {
			if (sha256_file(path, sha256) != EPKG_OK)
				continue;
			if (strcmp(sha256, sum)) {
				pkg_emit_error("%s fails original SHA256 "
				    "checksum, not removing", path);
				continue;
			}
		}

		if (unlink(path) == -1) {
			pkg_emit_errno("unlink", path);
			continue;
		}
	}

	return (EPKG_OK);
}
예제 #14
0
파일: pkg_create.c 프로젝트: rakhij/pkg
static struct packing *
pkg_create_archive(const char *outdir, struct pkg *pkg, pkg_formats format,
    unsigned required_flags)
{
	char		*pkg_path = NULL;
	struct packing	*pkg_archive = NULL;
	const char	*pkgname, *pkgversion;

	/*
	 * Ensure that we have all the information we need
	 */
	if (pkg->type != PKG_OLD_FILE)
		assert((pkg->flags & required_flags) == required_flags);

	if (mkdirs(outdir) != EPKG_OK)
		return NULL;

	pkg_get(pkg, PKG_NAME, &pkgname, PKG_VERSION, &pkgversion);
	if (asprintf(&pkg_path, "%s/%s-%s", outdir, pkgname, pkgversion) == -1) {
		pkg_emit_errno("asprintf", "");
		return (NULL);
	}

	if (packing_init(&pkg_archive, pkg_path, format) != EPKG_OK)
		pkg_archive = NULL;

	free(pkg_path);

	return pkg_archive;
}
예제 #15
0
파일: fetch.c 프로젝트: O2Graphics/pkg
int
pkg_fetch_file_tmp(struct pkg_repo *repo, const char *url, char *dest,
	time_t t)
{
	int fd = -1;
	int retcode = EPKG_FATAL;

	fd = mkstemp(dest);

	if (fd == -1) {
		pkg_emit_errno("mkstemp", dest);
		return(EPKG_FATAL);
	}

	retcode = pkg_fetch_file_to_fd(repo, url, fd, &t, 0, -1);

	if (t != 0) {
		struct timeval ftimes[2] = {
			{
			.tv_sec = t,
			.tv_usec = 0
			},
			{
			.tv_sec = t,
			.tv_usec = 0
			}
		};
예제 #16
0
파일: pkg_create.c 프로젝트: junovitch/pkg
static struct packing *
pkg_create_archive(const char *outdir, struct pkg *pkg, pkg_formats format,
    unsigned required_flags)
{
	char		*pkg_path = NULL;
	struct packing	*pkg_archive = NULL;

	/*
	 * Ensure that we have all the information we need
	 */
	if (pkg->type != PKG_OLD_FILE)
		assert((pkg->flags & required_flags) == required_flags);

	if (mkdirs(outdir) != EPKG_OK)
		return NULL;

	if (pkg_asprintf(&pkg_path, "%S/%n-%v", outdir, pkg, pkg) == -1) {
		pkg_emit_errno("pkg_asprintf", "");
		return (NULL);
	}

	if (packing_init(&pkg_archive, pkg_path, format, false) != EPKG_OK)
		pkg_archive = NULL;

	free(pkg_path);

	return pkg_archive;
}
예제 #17
0
파일: utils.c 프로젝트: baloo/pkgng
int
mkdirs(const char *_path)
{
	char path[MAXPATHLEN + 1];
	char *p;

	strlcpy(path, _path, sizeof(path));
	p = path;
	if (*p == '/')
		p++;

	for (;;) {
		if ((p = strchr(p, '/')) != NULL)
			*p = '\0';

		if (mkdir(path, S_IRWXU | S_IRWXG | S_IRWXO) < 0)
			if (errno != EEXIST && errno != EISDIR) {
				pkg_emit_errno("mkdir", path);
				return (EPKG_FATAL);
			}

		/* that was the last element of the path */
		if (p == NULL)
			break;

		*p = '/';
		p++;
	}

	return (EPKG_OK);
}
예제 #18
0
파일: query.c 프로젝트: baitisj/pkg
static struct pkg_repo_it*
pkg_repo_binary_it_new(struct pkg_repo *repo, sqlite3_stmt *s, short flags)
{
	struct pkg_repo_it *it;
	struct pkgdb fakedb;

	it = malloc(sizeof(*it));
	if (it == NULL) {
		pkg_emit_errno("malloc", "pkg_repo_it");
		sqlite3_finalize(s);
		return (NULL);
	}

	it->ops = &pkg_repo_binary_it_ops;
	it->flags = flags;
	it->repo = repo;

	fakedb.sqlite = PRIV_GET(repo);
	it->data = pkgdb_it_new_sqlite(&fakedb, s, PKG_REMOTE, flags);

	if (it->data == NULL) {
		free(it);
		return (NULL);
	}

	return (it);
}
예제 #19
0
파일: rsa.c 프로젝트: HardenedBSD/pkg
int
rsa_verify_cert(const char *path, unsigned char *key, int keylen,
    unsigned char *sig, int siglen, int fd)
{
	int ret;
	bool need_close = false;
	struct rsa_verify_cbdata cbdata;

	if (fd == -1) {
		if ((fd = open(path, O_RDONLY)) == -1) {
			pkg_emit_errno("fopen", path);
			return (EPKG_FATAL);
		}
		need_close = true;
	}
	(void)lseek(fd, 0, SEEK_SET);

	cbdata.key = key;
	cbdata.keylen = keylen;
	cbdata.sig = sig;
	cbdata.siglen = siglen;

	SSL_load_error_strings();
	OpenSSL_add_all_algorithms();
	OpenSSL_add_all_ciphers();

	ret = pkg_emit_sandbox_call(rsa_verify_cert_cb, fd, &cbdata);
	if (need_close)
		close(fd);

	return (ret);
}
예제 #20
0
파일: pkg_config.c 프로젝트: dumbbell/pkg
static void
connect_evpipe(const char *evpipe) {
	struct stat st;
	struct sockaddr_un sock;
	int flag = O_WRONLY;

	if (stat(evpipe, &st) != 0) {
		pkg_emit_error("No such event pipe: %s", evpipe);
		return;
	}

	if (!S_ISFIFO(st.st_mode) && !S_ISSOCK(st.st_mode)) {
		pkg_emit_error("%s is not a fifo or socket", evpipe);
		return;
	}

	if (S_ISFIFO(st.st_mode)) {
		flag |= O_NONBLOCK;
		if ((eventpipe = open(evpipe, flag)) == -1)
			pkg_emit_errno("open event pipe", evpipe);
		return;
	}

	if (S_ISSOCK(st.st_mode)) {
		if ((eventpipe = socket(AF_UNIX, SOCK_STREAM, 0)) == -1) {
			pkg_emit_errno("Open event pipe", evpipe);
			return;
		}
		memset(&sock, 0, sizeof(struct sockaddr_un));
		sock.sun_family = AF_UNIX;
		if (strlcpy(sock.sun_path, evpipe, sizeof(sock.sun_path)) >=
		    sizeof(sock.sun_path)) {
			pkg_emit_error("Socket path too long: %s", evpipe);
			close(eventpipe);
			eventpipe = -1;
			return;
		}

		if (connect(eventpipe, (struct sockaddr *)&sock, SUN_LEN(&sock)) == -1) {
			pkg_emit_errno("Connect event pipe", evpipe);
			close(eventpipe);
			eventpipe = -1;
			return;
		}
	}

}
예제 #21
0
파일: update.c 프로젝트: renchap/pkg
static int
pkg_add_from_manifest(FILE *f, char *buf, const char *origin, long offset,
		const char *manifest_digest, const char *local_arch, sqlite3 *sqlite,
		struct pkg_manifest_parser **parser, struct pkg **p)
{
	int rc = EPKG_OK;
	struct pkg *pkg;
	const char *local_origin, *pkg_arch;

	if (buf == NULL && fseek(f, offset, SEEK_SET) == -1) {
		pkg_emit_errno("fseek", "invalid manifest offset");
		return (EPKG_FATAL);
	}

	if (*p == NULL) {
		rc = pkg_new(p, PKG_REMOTE);
		if (rc != EPKG_OK)
			return (EPKG_FATAL);
	} else {
		pkg_reset(*p, PKG_REMOTE);
	}

	pkg = *p;

	pkg_manifest_parser_new(parser);
	if (buf == NULL) {
		rc = pkg_parse_manifest_file_ev(pkg, f, *parser);
	} else {
		rc = pkg_parse_manifest_ev(pkg, buf, offset, *parser);
	}
	if (rc != EPKG_OK) {
		goto cleanup;
	}
	rc = pkg_is_valid(pkg);
	if (rc != EPKG_OK) {
		goto cleanup;
	}

	/* Ensure that we have a proper origin and arch*/
	pkg_get(pkg, PKG_ORIGIN, &local_origin, PKG_ARCH, &pkg_arch);
	if (local_origin == NULL || strcmp(local_origin, origin) != 0) {
		pkg_emit_error("manifest contains origin %s while we wanted to add origin %s",
				local_origin ? local_origin : "NULL", origin);
		rc = EPKG_FATAL;
		goto cleanup;
	}
	if (pkg_arch == NULL || strcmp(pkg_arch, local_arch) != 0) {
		pkg_emit_error("package %s is built for %s arch, and local arch is %s",
				origin, pkg_arch ? pkg_arch : "NULL", local_arch);
		rc = EPKG_FATAL;
		goto cleanup;
	}

	rc = pkgdb_repo_add_package(pkg, NULL, sqlite, manifest_digest, true, false);

cleanup:
	return (rc);
}
예제 #22
0
int
pkg_option_new(struct pkg_option **option)
{
	if ((*option = calloc(1, sizeof(struct pkg_option))) == NULL) {
		pkg_emit_errno("calloc", "pkg_user");
		return (EPKG_FATAL);
	}
	return (EPKG_OK);
}
예제 #23
0
int
pkg_user_new(struct pkg_user **u)
{
	if ((*u = calloc(1, sizeof(struct pkg_user))) == NULL) {
		pkg_emit_errno("calloc", "pkg_user");
		return (EPKG_FATAL);
	}

	return (EPKG_OK);
}
예제 #24
0
int
pkg_group_new(struct pkg_group **g)
{
	if ((*g = calloc(1, sizeof(struct pkg_group))) == NULL) {
		pkg_emit_errno("calloc", "pkg_group");
		return (EPKG_FATAL);
	}

	return (EPKG_OK);
}
예제 #25
0
파일: rsa.c 프로젝트: HardenedBSD/pkg
int
rsa_verify(const char *path, const char *key, unsigned char *sig,
    unsigned int sig_len, int fd)
{
	int ret;
	bool need_close = false;
	struct rsa_verify_cbdata cbdata;
	char *key_buf;
	off_t key_len;

	if (file_to_buffer(key, (char**)&key_buf, &key_len) != EPKG_OK) {
		pkg_emit_errno("rsa_verify", "cannot read key");
		return (EPKG_FATAL);
	}

	if (fd == -1) {
		if ((fd = open(path, O_RDONLY)) == -1) {
			pkg_emit_errno("fopen", path);
			free(key_buf);
			return (EPKG_FATAL);
		}
		need_close = true;
	}
	(void)lseek(fd, 0, SEEK_SET);

	cbdata.key = key_buf;
	cbdata.keylen = key_len;
	cbdata.sig = sig;
	cbdata.siglen = sig_len;

	SSL_load_error_strings();
	OpenSSL_add_all_algorithms();
	OpenSSL_add_all_ciphers();

	ret = pkg_emit_sandbox_call(rsa_verify_cb, fd, &cbdata);
	if (need_close)
		close(fd);

	free(key_buf);

	return (ret);
}
예제 #26
0
int
pkg_delete_dirs(__unused struct pkgdb *db, struct pkg *pkg, bool force)
{
	struct pkg_dir	*dir = NULL;

	while (pkg_dirs(pkg, &dir) == EPKG_OK) {
		if (dir->keep == 1)
			continue;

		if (pkg_dir_try(dir)) {
			if (rmdir(pkg_dir_path(dir)) == -1 &&
			    errno != ENOTEMPTY && errno != EBUSY && !force)
				pkg_emit_errno("rmdir", pkg_dir_path(dir));
		} else {
			if (rmdir(pkg_dir_path(dir)) == -1 && !force)
				pkg_emit_errno("rmdir", pkg_dir_path(dir));
		}
	}

	return (EPKG_OK);
}
예제 #27
0
파일: pkg_repo.c 프로젝트: dnaeon/pkgng
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);
}
예제 #28
0
void
pkg_delete_file(struct pkg *pkg, struct pkg_file *file, unsigned force)
{
	const char *sum = pkg_file_cksum(file);
	const char *path;
	const char *prefix_rel;
	struct stat st;
	size_t len;
	char sha256[SHA256_DIGEST_LENGTH * 2 + 1];

	pkg_open_root_fd(pkg);

	path = pkg_file_path(file);
	path++;

	pkg_get(pkg, PKG_PREFIX, &prefix_rel);
	prefix_rel++;
	len = strlen(prefix_rel);

	/* Regular files and links */
	/* check sha256 */
	if (!force && sum[0] != '\0') {
		if (fstatat(pkg->rootfd, path, &st, AT_SYMLINK_NOFOLLOW) == -1) {
			pkg_emit_error("cannot stat %s: %s", path, strerror(errno));
			return;
		}
		if (S_ISLNK(st.st_mode)) {
			if (pkg_symlink_cksumat(pkg->rootfd, path, NULL,
			    sha256) != EPKG_OK)
				return;
		}
		else {
			if (sha256_fileat(pkg->rootfd, path, sha256) != EPKG_OK)
				return;
		}
		if (strcmp(sha256, sum)) {
			pkg_emit_error("%s fails original SHA256 "
				"checksum, not removing", path);
			return;
		}
	}

	if (unlinkat(pkg->rootfd, path, 0) == -1) {
		if (force < 2)
			pkg_emit_errno("unlinkat", path);
		return;
	}

	/* do not bother about directories not in prefix */
	if ((strncmp(prefix_rel, path, len) == 0) && path[len] == '/')
		pkg_add_dir_to_del(pkg, path, NULL);
}
예제 #29
0
파일: pkg.c 프로젝트: gavinatkinson/pkg
int
pkg_new(struct pkg **pkg, pkg_t type)
{
	if ((*pkg = calloc(1, sizeof(struct pkg))) == NULL) {
		pkg_emit_errno("calloc", "pkg");
		return EPKG_FATAL;
	}

	(*pkg)->fields = ucl_object_typed_new(UCL_OBJECT);
	(*pkg)->type = type;

	return (EPKG_OK);
}
예제 #30
0
int
pkg_new(struct pkg **pkg, pkg_t type)
{
	if ((*pkg = calloc(1, sizeof(struct pkg))) == NULL) {
		pkg_emit_errno("calloc", "pkg");
		return EPKG_FATAL;
	}

	(*pkg)->type = type;
	(*pkg)->rootfd = -1;

	return (EPKG_OK);
}