pkg: clean support for repositories
Rework the way the bootstrap fetches pkg, by implementing a full support for the repositories, the boostrap will now loop over all available repo and try to fetch the full package from there. It will at the first valid package found. Fallback to packagesite (which has been deprecated for a while) if needed, by transforming it into a repo, if no repo is found. MFC After: 3 weeks
This commit is contained in:
+120
-38
@@ -59,6 +59,8 @@ struct config_entry {
|
|||||||
bool main_only; /* Only set in pkg.conf. */
|
bool main_only; /* Only set in pkg.conf. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static struct repositories repositories = STAILQ_HEAD_INITIALIZER(repositories);
|
||||||
|
|
||||||
static struct config_entry c[] = {
|
static struct config_entry c[] = {
|
||||||
[PACKAGESITE] = {
|
[PACKAGESITE] = {
|
||||||
PKG_CONFIG_STRING,
|
PKG_CONFIG_STRING,
|
||||||
@@ -211,7 +213,7 @@ boolstr_to_bool(const char *str)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
config_parse(const ucl_object_t *obj, pkg_conf_file_t conftype)
|
config_parse(const ucl_object_t *obj)
|
||||||
{
|
{
|
||||||
FILE *buffp;
|
FILE *buffp;
|
||||||
char *buf = NULL;
|
char *buf = NULL;
|
||||||
@@ -238,29 +240,9 @@ config_parse(const ucl_object_t *obj, pkg_conf_file_t conftype)
|
|||||||
memset(buf, 0, bufsz);
|
memset(buf, 0, bufsz);
|
||||||
rewind(buffp);
|
rewind(buffp);
|
||||||
|
|
||||||
if (conftype == CONFFILE_PKG) {
|
|
||||||
for (j = 0; j < strlen(key); ++j)
|
for (j = 0; j < strlen(key); ++j)
|
||||||
fputc(toupper(key[j]), buffp);
|
fputc(toupper(key[j]), buffp);
|
||||||
fflush(buffp);
|
fflush(buffp);
|
||||||
} else if (conftype == CONFFILE_REPO) {
|
|
||||||
if (strcasecmp(key, "url") == 0)
|
|
||||||
fputs("PACKAGESITE", buffp);
|
|
||||||
else if (strcasecmp(key, "mirror_type") == 0)
|
|
||||||
fputs("MIRROR_TYPE", buffp);
|
|
||||||
else if (strcasecmp(key, "signature_type") == 0)
|
|
||||||
fputs("SIGNATURE_TYPE", buffp);
|
|
||||||
else if (strcasecmp(key, "fingerprints") == 0)
|
|
||||||
fputs("FINGERPRINTS", buffp);
|
|
||||||
else if (strcasecmp(key, "pubkey") == 0)
|
|
||||||
fputs("PUBKEY", buffp);
|
|
||||||
else if (strcasecmp(key, "enabled") == 0) {
|
|
||||||
if ((cur->type != UCL_BOOLEAN) ||
|
|
||||||
!ucl_object_toboolean(cur))
|
|
||||||
goto cleanup;
|
|
||||||
} else
|
|
||||||
continue;
|
|
||||||
fflush(buffp);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (i = 0; i < CONFIG_SIZE; i++) {
|
for (i = 0; i < CONFIG_SIZE; i++) {
|
||||||
if (strcmp(buf, c[i].key) == 0)
|
if (strcmp(buf, c[i].key) == 0)
|
||||||
@@ -324,7 +306,7 @@ config_parse(const ucl_object_t *obj, pkg_conf_file_t conftype)
|
|||||||
if (c[i].envset)
|
if (c[i].envset)
|
||||||
continue;
|
continue;
|
||||||
/* Prevent overriding ABI, ASSUME_ALWAYS_YES, etc. */
|
/* Prevent overriding ABI, ASSUME_ALWAYS_YES, etc. */
|
||||||
if (conftype != CONFFILE_PKG && c[i].main_only == true)
|
if (c[i].main_only == true)
|
||||||
continue;
|
continue;
|
||||||
switch (c[i].type) {
|
switch (c[i].type) {
|
||||||
case PKG_CONFIG_LIST:
|
case PKG_CONFIG_LIST:
|
||||||
@@ -336,12 +318,91 @@ config_parse(const ucl_object_t *obj, pkg_conf_file_t conftype)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
|
||||||
free(temp_config);
|
free(temp_config);
|
||||||
fclose(buffp);
|
fclose(buffp);
|
||||||
free(buf);
|
free(buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_mirror_type(struct repository *r, const char *mt)
|
||||||
|
{
|
||||||
|
if (strcasecmp(mt, "srv") == 0)
|
||||||
|
r->mirror_type = MIRROR_SRV;
|
||||||
|
r->mirror_type = MIRROR_NONE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static bool
|
||||||
|
parse_signature_type(struct repository *repo, const char *st)
|
||||||
|
{
|
||||||
|
if (strcasecmp(st, "FINGERPRINTS") == 0)
|
||||||
|
repo->signature_type = SIGNATURE_FINGERPRINT;
|
||||||
|
else if (strcasecmp(st, "PUBKEY") == 0)
|
||||||
|
repo->signature_type = SIGNATURE_PUBKEY;
|
||||||
|
else if (strcasecmp(st, "NONE") == 0)
|
||||||
|
repo->signature_type = SIGNATURE_NONE;
|
||||||
|
else {
|
||||||
|
warnx("Signature type %s is not supported for bootstraping,"
|
||||||
|
" ignoring repository %s", st, repo->name);
|
||||||
|
free(repo->url);
|
||||||
|
free(repo->name);
|
||||||
|
free(repo->fingerprints);
|
||||||
|
free(repo->pubkey);
|
||||||
|
free(repo);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return (true);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
parse_repo(const ucl_object_t *o)
|
||||||
|
{
|
||||||
|
const ucl_object_t *cur;
|
||||||
|
const char *key;
|
||||||
|
ucl_object_iter_t it = NULL;
|
||||||
|
|
||||||
|
struct repository *repo = calloc(1, sizeof(struct repository));
|
||||||
|
if (repo == NULL)
|
||||||
|
err(EXIT_FAILURE, "calloc");
|
||||||
|
|
||||||
|
repo->name = strdup(ucl_object_key(o));
|
||||||
|
if (repo->name == NULL)
|
||||||
|
err(EXIT_FAILURE, "strdup");
|
||||||
|
while ((cur = ucl_iterate_object(o, &it, true))) {
|
||||||
|
key = ucl_object_key(cur);
|
||||||
|
if (key == NULL)
|
||||||
|
continue;
|
||||||
|
if (strcasecmp(key, "url") == 0) {
|
||||||
|
repo->url = strdup(ucl_object_tostring(cur));
|
||||||
|
if (repo->url == NULL)
|
||||||
|
err(EXIT_FAILURE, "strdup");
|
||||||
|
} else if (strcasecmp(key, "mirror_type") == 0) {
|
||||||
|
parse_mirror_type(repo, ucl_object_tostring(cur));
|
||||||
|
} else if (strcasecmp(key, "signature_type") == 0) {
|
||||||
|
if (!parse_signature_type(repo, ucl_object_tostring(cur)))
|
||||||
|
return;
|
||||||
|
} else if (strcasecmp(key, "fingerprints") == 0) {
|
||||||
|
repo->fingerprints = strdup(ucl_object_tostring(cur));
|
||||||
|
if (repo->fingerprints == NULL)
|
||||||
|
err(EXIT_FAILURE, "strdup");
|
||||||
|
} else if (strcasecmp(key, "pubkey") == 0) {
|
||||||
|
repo->pubkey = strdup(ucl_object_tostring(cur));
|
||||||
|
if (repo->pubkey == NULL)
|
||||||
|
err(EXIT_FAILURE, "strdup");
|
||||||
|
} else if (strcasecmp(key, "enabled") == 0) {
|
||||||
|
if ((cur->type != UCL_BOOLEAN) ||
|
||||||
|
!ucl_object_toboolean(cur)) {
|
||||||
|
free(repo->url);
|
||||||
|
free(repo->name);
|
||||||
|
free(repo);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
STAILQ_INSERT_TAIL(&repositories, repo, next);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
/*-
|
/*-
|
||||||
* Parse new repo style configs in style:
|
* Parse new repo style configs in style:
|
||||||
* Name:
|
* Name:
|
||||||
@@ -367,8 +428,7 @@ parse_repo_file(ucl_object_t *obj, const char *requested_repo)
|
|||||||
|
|
||||||
if (requested_repo != NULL && strcmp(requested_repo, key) != 0)
|
if (requested_repo != NULL && strcmp(requested_repo, key) != 0)
|
||||||
continue;
|
continue;
|
||||||
|
parse_repo(cur);
|
||||||
config_parse(cur, CONFFILE_REPO);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -379,8 +439,12 @@ read_conf_file(const char *confpath, const char *requested_repo,
|
|||||||
{
|
{
|
||||||
struct ucl_parser *p;
|
struct ucl_parser *p;
|
||||||
ucl_object_t *obj = NULL;
|
ucl_object_t *obj = NULL;
|
||||||
|
const char *abi = pkg_get_myabi();
|
||||||
|
if (abi == NULL)
|
||||||
|
errx(EXIT_FAILURE, "Fail do determine ABI");
|
||||||
|
|
||||||
p = ucl_parser_new(0);
|
p = ucl_parser_new(0);
|
||||||
|
ucl_parser_register_variable(p, "ABI", abi);
|
||||||
|
|
||||||
if (!ucl_parser_add_file(p, confpath)) {
|
if (!ucl_parser_add_file(p, confpath)) {
|
||||||
if (errno != ENOENT)
|
if (errno != ENOENT)
|
||||||
@@ -397,7 +461,7 @@ read_conf_file(const char *confpath, const char *requested_repo,
|
|||||||
"configuration file %s", confpath);
|
"configuration file %s", confpath);
|
||||||
else {
|
else {
|
||||||
if (conftype == CONFFILE_PKG)
|
if (conftype == CONFFILE_PKG)
|
||||||
config_parse(obj, conftype);
|
config_parse(obj);
|
||||||
else if (conftype == CONFFILE_REPO)
|
else if (conftype == CONFFILE_REPO)
|
||||||
parse_repo_file(obj, requested_repo);
|
parse_repo_file(obj, requested_repo);
|
||||||
}
|
}
|
||||||
@@ -408,7 +472,7 @@ read_conf_file(const char *confpath, const char *requested_repo,
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static void
|
||||||
load_repositories(const char *repodir, const char *requested_repo)
|
load_repositories(const char *repodir, const char *requested_repo)
|
||||||
{
|
{
|
||||||
struct dirent *ent;
|
struct dirent *ent;
|
||||||
@@ -416,12 +480,9 @@ load_repositories(const char *repodir, const char *requested_repo)
|
|||||||
char *p;
|
char *p;
|
||||||
size_t n;
|
size_t n;
|
||||||
char path[MAXPATHLEN];
|
char path[MAXPATHLEN];
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
if ((d = opendir(repodir)) == NULL)
|
if ((d = opendir(repodir)) == NULL)
|
||||||
return (1);
|
return;
|
||||||
|
|
||||||
while ((ent = readdir(d))) {
|
while ((ent = readdir(d))) {
|
||||||
/* Trim out 'repos'. */
|
/* Trim out 'repos'. */
|
||||||
@@ -437,7 +498,6 @@ load_repositories(const char *repodir, const char *requested_repo)
|
|||||||
continue;
|
continue;
|
||||||
if (read_conf_file(path, requested_repo,
|
if (read_conf_file(path, requested_repo,
|
||||||
CONFFILE_REPO)) {
|
CONFFILE_REPO)) {
|
||||||
ret = 1;
|
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -445,8 +505,6 @@ load_repositories(const char *repodir, const char *requested_repo)
|
|||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
closedir(d);
|
closedir(d);
|
||||||
|
|
||||||
return (ret);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
@@ -508,8 +566,7 @@ config_init(const char *requested_repo)
|
|||||||
}
|
}
|
||||||
|
|
||||||
STAILQ_FOREACH(cv, c[REPOS_DIR].list, next)
|
STAILQ_FOREACH(cv, c[REPOS_DIR].list, next)
|
||||||
if (load_repositories(cv->value, requested_repo))
|
load_repositories(cv->value, requested_repo);
|
||||||
goto finalize;
|
|
||||||
|
|
||||||
finalize:
|
finalize:
|
||||||
if (c[ABI].val == NULL && c[ABI].value == NULL) {
|
if (c[ABI].val == NULL && c[ABI].value == NULL) {
|
||||||
@@ -520,8 +577,6 @@ config_init(const char *requested_repo)
|
|||||||
c[ABI].val = abi;
|
c[ABI].val = abi;
|
||||||
}
|
}
|
||||||
|
|
||||||
subst_packagesite(c[ABI].value != NULL ? c[ABI].value : c[ABI].val);
|
|
||||||
|
|
||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -560,6 +615,33 @@ config_bool(pkg_config_key k, bool *val)
|
|||||||
return (0);
|
return (0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct repositories *
|
||||||
|
config_get_repositories(void)
|
||||||
|
{
|
||||||
|
if (STAILQ_EMPTY(&repositories)) {
|
||||||
|
/* Fall back to PACKAGESITE - deprecated - */
|
||||||
|
struct repository *r = calloc(1, sizeof(r));
|
||||||
|
if (r == NULL)
|
||||||
|
err(EXIT_FAILURE, "calloc");
|
||||||
|
r->name = strdup("fallback");
|
||||||
|
if (r->name == NULL)
|
||||||
|
err(EXIT_FAILURE, "strdup");
|
||||||
|
subst_packagesite(c[ABI].value != NULL ? c[ABI].value : c[ABI].val);
|
||||||
|
r->url = c[PACKAGESITE].value;
|
||||||
|
if (c[SIGNATURE_TYPE].value != NULL)
|
||||||
|
if (!parse_signature_type(r, c[SIGNATURE_TYPE].value))
|
||||||
|
exit(EXIT_FAILURE);
|
||||||
|
if (c[MIRROR_TYPE].value != NULL)
|
||||||
|
parse_mirror_type(r, c[MIRROR_TYPE].value);
|
||||||
|
if (c[PUBKEY].value != NULL)
|
||||||
|
r->pubkey = c[PUBKEY].value;
|
||||||
|
if (c[FINGERPRINTS].value != NULL)
|
||||||
|
r->fingerprints = c[FINGERPRINTS].value;
|
||||||
|
STAILQ_INSERT_TAIL(&repositories, r, next);
|
||||||
|
}
|
||||||
|
return (&repositories);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
config_finish(void) {
|
config_finish(void) {
|
||||||
int i;
|
int i;
|
||||||
|
|||||||
@@ -30,6 +30,7 @@
|
|||||||
#define _PKG_CONFIG_H
|
#define _PKG_CONFIG_H
|
||||||
|
|
||||||
#include <paths.h>
|
#include <paths.h>
|
||||||
|
#include <sys/queue.h>
|
||||||
|
|
||||||
#define URL_SCHEME_PREFIX "pkg+"
|
#define URL_SCHEME_PREFIX "pkg+"
|
||||||
|
|
||||||
@@ -58,9 +59,32 @@ typedef enum {
|
|||||||
CONFFILE_REPO,
|
CONFFILE_REPO,
|
||||||
} pkg_conf_file_t;
|
} pkg_conf_file_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
SIGNATURE_NONE = 0,
|
||||||
|
SIGNATURE_FINGERPRINT,
|
||||||
|
SIGNATURE_PUBKEY,
|
||||||
|
} signature_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
MIRROR_NONE = 0,
|
||||||
|
MIRROR_SRV,
|
||||||
|
} mirror_t;
|
||||||
|
|
||||||
|
struct repository {
|
||||||
|
char *name;
|
||||||
|
char *url;
|
||||||
|
mirror_t mirror_type;
|
||||||
|
signature_t signature_type;
|
||||||
|
char *fingerprints;
|
||||||
|
char *pubkey;
|
||||||
|
STAILQ_ENTRY(repository) next;
|
||||||
|
};
|
||||||
|
STAILQ_HEAD(repositories, repository);
|
||||||
|
|
||||||
int config_init(const char *);
|
int config_init(const char *);
|
||||||
void config_finish(void);
|
void config_finish(void);
|
||||||
int config_string(pkg_config_key, const char **);
|
int config_string(pkg_config_key, const char **);
|
||||||
int config_bool(pkg_config_key, bool *);
|
int config_bool(pkg_config_key, bool *);
|
||||||
|
struct repositories *config_get_repositories(void);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
+51
-56
@@ -255,7 +255,7 @@ install_pkg_static(const char *path, const char *pkgpath, bool force)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
fetch_to_fd(const char *url, char *path, const char *fetchOpts)
|
fetch_to_fd(struct repository *repo, const char *url, char *path, const char *fetchOpts)
|
||||||
{
|
{
|
||||||
struct url *u;
|
struct url *u;
|
||||||
struct dns_srvinfo *mirrors, *current;
|
struct dns_srvinfo *mirrors, *current;
|
||||||
@@ -267,18 +267,11 @@ fetch_to_fd(const char *url, char *path, const char *fetchOpts)
|
|||||||
ssize_t r;
|
ssize_t r;
|
||||||
char buf[10240];
|
char buf[10240];
|
||||||
char zone[MAXHOSTNAMELEN + 13];
|
char zone[MAXHOSTNAMELEN + 13];
|
||||||
static const char *mirror_type = NULL;
|
|
||||||
|
|
||||||
max_retry = 3;
|
max_retry = 3;
|
||||||
current = mirrors = NULL;
|
current = mirrors = NULL;
|
||||||
remote = NULL;
|
remote = NULL;
|
||||||
|
|
||||||
if (mirror_type == NULL && config_string(MIRROR_TYPE, &mirror_type)
|
|
||||||
!= 0) {
|
|
||||||
warnx("No MIRROR_TYPE defined");
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if ((fd = mkstemp(path)) == -1) {
|
if ((fd = mkstemp(path)) == -1) {
|
||||||
warn("mkstemp()");
|
warn("mkstemp()");
|
||||||
return (-1);
|
return (-1);
|
||||||
@@ -294,7 +287,7 @@ fetch_to_fd(const char *url, char *path, const char *fetchOpts)
|
|||||||
while (remote == NULL) {
|
while (remote == NULL) {
|
||||||
if (retry == max_retry) {
|
if (retry == max_retry) {
|
||||||
if (strcmp(u->scheme, "file") != 0 &&
|
if (strcmp(u->scheme, "file") != 0 &&
|
||||||
strcasecmp(mirror_type, "srv") == 0) {
|
repo->mirror_type == MIRROR_SRV) {
|
||||||
snprintf(zone, sizeof(zone),
|
snprintf(zone, sizeof(zone),
|
||||||
"_%s._tcp.%s", u->scheme, u->host);
|
"_%s._tcp.%s", u->scheme, u->host);
|
||||||
mirrors = dns_getsrvinfo(zone);
|
mirrors = dns_getsrvinfo(zone);
|
||||||
@@ -653,24 +646,32 @@ parse_cert(int fd) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
verify_pubsignature(int fd_pkg, int fd_sig)
|
verify_pubsignature(int fd_pkg, int fd_sig, struct repository *r)
|
||||||
{
|
{
|
||||||
struct pubkey *pk;
|
struct pubkey *pk;
|
||||||
const char *pubkey;
|
|
||||||
char *data;
|
char *data;
|
||||||
struct pkgsign_ctx *sctx;
|
struct pkgsign_ctx *sctx;
|
||||||
size_t datasz;
|
size_t datasz;
|
||||||
bool ret;
|
bool ret;
|
||||||
|
const char *pubkey;
|
||||||
|
|
||||||
pk = NULL;
|
pk = NULL;
|
||||||
pubkey = NULL;
|
|
||||||
sctx = NULL;
|
sctx = NULL;
|
||||||
data = NULL;
|
data = NULL;
|
||||||
ret = false;
|
ret = false;
|
||||||
if (config_string(PUBKEY, &pubkey) != 0) {
|
|
||||||
warnx("No CONFIG_PUBKEY defined");
|
if (r != NULL) {
|
||||||
|
if (r->pubkey == NULL) {
|
||||||
|
warnx("No CONFIG_PUBKEY defined for %s", r->name);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
pubkey = r->pubkey;
|
||||||
|
} else {
|
||||||
|
if (config_string(PUBKEY, &pubkey) != 0) {
|
||||||
|
warnx("No CONFIG_PUBKEY defined for %s", r->name);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if ((pk = read_pubkey(fd_sig)) == NULL) {
|
if ((pk = read_pubkey(fd_sig)) == NULL) {
|
||||||
warnx("Error reading signature");
|
warnx("Error reading signature");
|
||||||
@@ -703,8 +704,8 @@ verify_pubsignature(int fd_pkg, int fd_sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Verify the signature. */
|
/* Verify the signature. */
|
||||||
printf("Verifying signature with public key %s... ", pubkey);
|
printf("Verifying signature with public key %s.a.. ", r->pubkey);
|
||||||
if (pkgsign_verify_data(sctx, data, datasz, pubkey, NULL, 0, pk->sig,
|
if (pkgsign_verify_data(sctx, data, datasz, r->pubkey, NULL, 0, pk->sig,
|
||||||
pk->siglen) == false) {
|
pk->siglen) == false) {
|
||||||
fprintf(stderr, "Signature is not valid\n");
|
fprintf(stderr, "Signature is not valid\n");
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
@@ -723,7 +724,7 @@ verify_pubsignature(int fd_pkg, int fd_sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
verify_signature(int fd_pkg, int fd_sig)
|
verify_signature(int fd_pkg, int fd_sig, struct repository *r)
|
||||||
{
|
{
|
||||||
struct fingerprint_list *trusted, *revoked;
|
struct fingerprint_list *trusted, *revoked;
|
||||||
struct fingerprint *fingerprint;
|
struct fingerprint *fingerprint;
|
||||||
@@ -742,10 +743,18 @@ verify_signature(int fd_pkg, int fd_sig)
|
|||||||
ret = false;
|
ret = false;
|
||||||
|
|
||||||
/* Read and parse fingerprints. */
|
/* Read and parse fingerprints. */
|
||||||
if (config_string(FINGERPRINTS, &fingerprints) != 0) {
|
if (r != NULL) {
|
||||||
warnx("No CONFIG_FINGERPRINTS defined");
|
if (r->fingerprints == NULL) {
|
||||||
|
warnx("No FINGERPRINTS defined for %s", r->name);
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
fingerprints = r->fingerprints;
|
||||||
|
} else {
|
||||||
|
if (config_string(FINGERPRINTS, &fingerprints) != 0) {
|
||||||
|
warnx("No FINGERPRINTS defined");
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
snprintf(path, MAXPATHLEN, "%s/trusted", fingerprints);
|
snprintf(path, MAXPATHLEN, "%s/trusted", fingerprints);
|
||||||
if ((trusted = load_fingerprints(path, &trusted_count)) == NULL) {
|
if ((trusted = load_fingerprints(path, &trusted_count)) == NULL) {
|
||||||
@@ -833,7 +842,7 @@ verify_signature(int fd_pkg, int fd_sig)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
bootstrap_pkg(bool force, const char *fetchOpts)
|
bootstrap_pkg(bool force, const char *fetchOpts, struct repository *repo)
|
||||||
{
|
{
|
||||||
int fd_pkg, fd_sig;
|
int fd_pkg, fd_sig;
|
||||||
int ret;
|
int ret;
|
||||||
@@ -841,28 +850,18 @@ bootstrap_pkg(bool force, const char *fetchOpts)
|
|||||||
char tmppkg[MAXPATHLEN];
|
char tmppkg[MAXPATHLEN];
|
||||||
char tmpsig[MAXPATHLEN];
|
char tmpsig[MAXPATHLEN];
|
||||||
const char *packagesite;
|
const char *packagesite;
|
||||||
const char *signature_type;
|
|
||||||
char pkgstatic[MAXPATHLEN];
|
char pkgstatic[MAXPATHLEN];
|
||||||
const char *bootstrap_name;
|
const char *bootstrap_name;
|
||||||
|
|
||||||
fd_sig = -1;
|
fd_sig = -1;
|
||||||
ret = -1;
|
ret = -1;
|
||||||
|
|
||||||
if (config_string(PACKAGESITE, &packagesite) != 0) {
|
printf("Bootstrapping pkg from %s, please wait...\n", repo->url);
|
||||||
warnx("No PACKAGESITE defined");
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (config_string(SIGNATURE_TYPE, &signature_type) != 0) {
|
|
||||||
warnx("Error looking up SIGNATURE_TYPE");
|
|
||||||
return (-1);
|
|
||||||
}
|
|
||||||
|
|
||||||
printf("Bootstrapping pkg from %s, please wait...\n", packagesite);
|
|
||||||
|
|
||||||
/* Support pkg+http:// for PACKAGESITE which is the new format
|
/* Support pkg+http:// for PACKAGESITE which is the new format
|
||||||
in 1.2 to avoid confusion on why http://pkg.FreeBSD.org has
|
in 1.2 to avoid confusion on why http://pkg.FreeBSD.org has
|
||||||
no A record. */
|
no A record. */
|
||||||
|
packagesite = repo->url;
|
||||||
if (strncmp(URL_SCHEME_PREFIX, packagesite,
|
if (strncmp(URL_SCHEME_PREFIX, packagesite,
|
||||||
strlen(URL_SCHEME_PREFIX)) == 0)
|
strlen(URL_SCHEME_PREFIX)) == 0)
|
||||||
packagesite += strlen(URL_SCHEME_PREFIX);
|
packagesite += strlen(URL_SCHEME_PREFIX);
|
||||||
@@ -873,53 +872,44 @@ bootstrap_pkg(bool force, const char *fetchOpts)
|
|||||||
snprintf(tmppkg, MAXPATHLEN, "%s/%s.XXXXXX",
|
snprintf(tmppkg, MAXPATHLEN, "%s/%s.XXXXXX",
|
||||||
getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP,
|
getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP,
|
||||||
bootstrap_name);
|
bootstrap_name);
|
||||||
if ((fd_pkg = fetch_to_fd(url, tmppkg, fetchOpts)) != -1)
|
if ((fd_pkg = fetch_to_fd(repo, url, tmppkg, fetchOpts)) != -1)
|
||||||
break;
|
break;
|
||||||
bootstrap_name = NULL;
|
bootstrap_name = NULL;
|
||||||
}
|
}
|
||||||
if (bootstrap_name == NULL)
|
if (bootstrap_name == NULL)
|
||||||
goto fetchfail;
|
goto fetchfail;
|
||||||
|
|
||||||
if (signature_type != NULL &&
|
if (repo->signature_type == SIGNATURE_FINGERPRINT) {
|
||||||
strcasecmp(signature_type, "NONE") != 0) {
|
|
||||||
if (strcasecmp(signature_type, "FINGERPRINTS") == 0) {
|
|
||||||
|
|
||||||
snprintf(tmpsig, MAXPATHLEN, "%s/%s.sig.XXXXXX",
|
snprintf(tmpsig, MAXPATHLEN, "%s/%s.sig.XXXXXX",
|
||||||
getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP,
|
getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP,
|
||||||
bootstrap_name);
|
bootstrap_name);
|
||||||
snprintf(url, MAXPATHLEN, "%s/Latest/%s.sig",
|
snprintf(url, MAXPATHLEN, "%s/Latest/%s.sig",
|
||||||
packagesite, bootstrap_name);
|
packagesite, bootstrap_name);
|
||||||
|
|
||||||
if ((fd_sig = fetch_to_fd(url, tmpsig, fetchOpts)) == -1) {
|
if ((fd_sig = fetch_to_fd(repo, url, tmpsig, fetchOpts)) == -1) {
|
||||||
fprintf(stderr, "Signature for pkg not "
|
fprintf(stderr, "Signature for pkg not "
|
||||||
"available.\n");
|
"available.\n");
|
||||||
goto fetchfail;
|
goto fetchfail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verify_signature(fd_pkg, fd_sig) == false)
|
if (verify_signature(fd_pkg, fd_sig, repo) == false)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else if (strcasecmp(signature_type, "PUBKEY") == 0) {
|
} else if (repo->signature_type == SIGNATURE_PUBKEY) {
|
||||||
|
|
||||||
snprintf(tmpsig, MAXPATHLEN,
|
snprintf(tmpsig, MAXPATHLEN,
|
||||||
"%s/%s.pubkeysig.XXXXXX",
|
"%s/%s.pubkeysig.XXXXXX",
|
||||||
getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP,
|
getenv("TMPDIR") ? getenv("TMPDIR") : _PATH_TMP,
|
||||||
bootstrap_name);
|
bootstrap_name);
|
||||||
snprintf(url, MAXPATHLEN, "%s/Latest/%s.pubkeysig",
|
snprintf(url, MAXPATHLEN, "%s/Latest/%s.pubkeysig",
|
||||||
packagesite, bootstrap_name);
|
repo->url, bootstrap_name);
|
||||||
|
|
||||||
if ((fd_sig = fetch_to_fd(url, tmpsig, fetchOpts)) == -1) {
|
if ((fd_sig = fetch_to_fd(repo, url, tmpsig, fetchOpts)) == -1) {
|
||||||
fprintf(stderr, "Signature for pkg not "
|
fprintf(stderr, "Signature for pkg not "
|
||||||
"available.\n");
|
"available.\n");
|
||||||
goto fetchfail;
|
goto fetchfail;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verify_pubsignature(fd_pkg, fd_sig) == false)
|
if (verify_pubsignature(fd_pkg, fd_sig, repo) == false)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
|
||||||
warnx("Signature type %s is not supported for "
|
|
||||||
"bootstrapping.", signature_type);
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0)
|
if ((ret = extract_pkg_static(fd_pkg, pkgstatic, MAXPATHLEN)) == 0)
|
||||||
@@ -929,18 +919,15 @@ bootstrap_pkg(bool force, const char *fetchOpts)
|
|||||||
|
|
||||||
fetchfail:
|
fetchfail:
|
||||||
for (int j = 0; bootstrap_names[j] != NULL; j++) {
|
for (int j = 0; bootstrap_names[j] != NULL; j++) {
|
||||||
warnx("Attempted to fetch %s/Latest/%s", packagesite,
|
warnx("Attempted to fetch %s/Latest/%s", repo->url,
|
||||||
bootstrap_names[j]);
|
bootstrap_names[j]);
|
||||||
}
|
}
|
||||||
warnx("Error: %s", fetchLastErrString);
|
warnx("Error: %s", fetchLastErrString);
|
||||||
if (fetchLastErrCode == FETCH_RESOLV) {
|
if (fetchLastErrCode == FETCH_RESOLV) {
|
||||||
fprintf(stderr, "Address resolution failed for %s.\n", packagesite);
|
fprintf(stderr, "Address resolution failed for %s.\n", packagesite);
|
||||||
fprintf(stderr, "Consider changing PACKAGESITE.\n");
|
|
||||||
} else {
|
} else {
|
||||||
fprintf(stderr, "A pre-built version of pkg could not be found for "
|
fprintf(stderr, "A pre-built version of pkg could not be found for "
|
||||||
"your system.\n");
|
"your system.\n");
|
||||||
fprintf(stderr, "Consider changing PACKAGESITE or installing it from "
|
|
||||||
"ports: 'ports-mgmt/pkg'.\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cleanup:
|
cleanup:
|
||||||
@@ -1024,7 +1011,7 @@ bootstrap_pkg_local(const char *pkgpath, bool force)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verify_signature(fd_pkg, fd_sig) == false)
|
if (verify_signature(fd_pkg, fd_sig, NULL) == false)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
} else if (strcasecmp(signature_type, "PUBKEY") == 0) {
|
} else if (strcasecmp(signature_type, "PUBKEY") == 0) {
|
||||||
@@ -1037,7 +1024,7 @@ bootstrap_pkg_local(const char *pkgpath, bool force)
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (verify_pubsignature(fd_pkg, fd_sig) == false)
|
if (verify_pubsignature(fd_pkg, fd_sig, NULL) == false)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@@ -1105,6 +1092,7 @@ main(int argc, char *argv[])
|
|||||||
signed char ch;
|
signed char ch;
|
||||||
const char *fetchOpts;
|
const char *fetchOpts;
|
||||||
char *command;
|
char *command;
|
||||||
|
struct repositories *repositories;
|
||||||
|
|
||||||
activation_test = false;
|
activation_test = false;
|
||||||
add_pkg = false;
|
add_pkg = false;
|
||||||
@@ -1232,6 +1220,8 @@ main(int argc, char *argv[])
|
|||||||
fetchDebug = 1;
|
fetchDebug = 1;
|
||||||
|
|
||||||
if ((bootstrap_only && force) || access(pkgpath, X_OK) == -1) {
|
if ((bootstrap_only && force) || access(pkgpath, X_OK) == -1) {
|
||||||
|
struct repository *repo;
|
||||||
|
int ret = 0;
|
||||||
/*
|
/*
|
||||||
* To allow 'pkg -N' to be used as a reliable test for whether
|
* To allow 'pkg -N' to be used as a reliable test for whether
|
||||||
* a system is configured to use pkg, don't bootstrap pkg
|
* a system is configured to use pkg, don't bootstrap pkg
|
||||||
@@ -1272,7 +1262,12 @@ main(int argc, char *argv[])
|
|||||||
if (pkg_query_yes_no() == 0)
|
if (pkg_query_yes_no() == 0)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
}
|
}
|
||||||
if (bootstrap_pkg(force, fetchOpts) != 0)
|
repositories = config_get_repositories();
|
||||||
|
STAILQ_FOREACH(repo, repositories, next) {
|
||||||
|
if ((ret = bootstrap_pkg(force, fetchOpts, repo)) == 0)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (ret != 0)
|
||||||
exit(EXIT_FAILURE);
|
exit(EXIT_FAILURE);
|
||||||
config_finish();
|
config_finish();
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user