retvalue pull_getrules(struct pull_rule **rules) { struct pull_rule *pull = NULL; retvalue r; r = configfile_parse("pulls", IGNORABLE(unknownfield), configparser_pull_rule_init, linkedlistfinish, "pull rule", pullconfigfields, ARRAYCOUNT(pullconfigfields), &pull); if (RET_IS_OK(r)) *rules = pull; else if (r == RET_NOTHING) { assert (pull == NULL); *rules = NULL; r = RET_OK; } else { // TODO special handle unknownfield pull_freerules(pull); } return r; }
static bool key_good_enough(const struct requested_key *req, const gpgme_signature_t signatures, const char *releasegpg, const char *release) { const struct known_key *k = req->key; gpgme_signature_t sig; for (sig = signatures ; sig != NULL ; sig = sig->next) { const char *fpr = sig->fpr; size_t l = strlen(sig->fpr); int i; bool key_expired = false; /* dito */ if (req->subkey < 0) { /* any subkey is allowed */ for(i = 0 ; i < k->count ; i++) { const struct known_subkey *s = &k->subkeys[i]; if (s->name_len > l) continue; if (memcmp(s->name, fpr + (l - s->name_len), s->name_len) != 0) continue; key_expired = k->subkeys[i].expired; break; } if (i >= k->count) continue; } else { const struct known_subkey *s; assert (req->subkey < k->count); s = &k->subkeys[req->subkey]; if (memcmp(s->name, fpr + (l - s->name_len), s->name_len) != 0) continue; key_expired = k->subkeys[req->subkey].expired; } /* this key we look for. if it is acceptable, we are finished. if it is not acceptable, we still have to look at the other signatures, as a signature with another subkey is following */ switch (gpg_err_code(sig->status)) { case GPG_ERR_NO_ERROR: if (! key_expired) return true; if (req->allow_bad && IGNORABLE(expiredkey)) { if (verbose >= 0) fprintf(stderr, "WARNING: valid signature in '%s' with parent-expired '%s' is accepted as requested!\n", releasegpg, fpr); return true; } fprintf(stderr, "Not accepting valid signature in '%s' with parent-EXPIRED '%s'\n", releasegpg, fpr); if (verbose >= 0) fprintf(stderr, "(To ignore it append a ! to the key and run reprepro with --ignore=expiredkey)\n"); /* not accepted */ continue; case GPG_ERR_KEY_EXPIRED: if (req->allow_bad && IGNORABLE(expiredkey)) { if (verbose >= 0) fprintf(stderr, "WARNING: valid signature in '%s' with expired '%s' is accepted as requested!\n", releasegpg, fpr); return true; } fprintf(stderr, "Not accepting valid signature in '%s' with EXPIRED '%s'\n", releasegpg, fpr); if (verbose >= 0) fprintf(stderr, "(To ignore it append a ! to the key and run reprepro with --ignore=expiredkey)\n"); /* not accepted */ continue; case GPG_ERR_CERT_REVOKED: if (req->allow_bad && IGNORABLE(revokedkey)) { if (verbose >= 0) fprintf(stderr, "WARNING: valid signature in '%s' with revoked '%s' is accepted as requested!\n", releasegpg, fpr); return RET_OK; } fprintf(stderr, "Not accepting valid signature in '%s' with REVOKED '%s'\n", releasegpg, fpr); if (verbose >= 0) fprintf(stderr, "(To ignore it append a ! to the key and run reprepro with --ignore=revokedkey)\n"); /* not accepted */ continue; case GPG_ERR_SIG_EXPIRED: if (req->allow_bad && IGNORABLE(expiredsignature)) { if (verbose >= 0) fprintf(stderr, "WARNING: valid but expired signature in '%s' with '%s' is accepted as requested!\n", releasegpg, fpr); return RET_OK; } fprintf(stderr, "Not accepting valid but EXPIRED signature in '%s' with '%s'\n", releasegpg, fpr); if (verbose >= 0) fprintf(stderr, "(To ignore it append a ! to the key and run reprepro with --ignore=expiredsignature)\n"); /* not accepted */ continue; case GPG_ERR_BAD_SIGNATURE: case GPG_ERR_NO_PUBKEY: /* not accepted */ continue; case GPG_ERR_GENERAL: fprintf(stderr, "gpgme returned an general error verifing signature with '%s' in '%s'!\n" "Try running gpg --verify '%s' '%s' manually for hints what is happening.\n" "If this does not print any errors, retry the command causing this message.\n", fpr, releasegpg, releasegpg, release); continue; /* there sadly no more is a way to make sure we have * all possible ones handled */ default: break; } fprintf(stderr, "Error checking signature (gpgme returned unexpected value %d)!\n" "Please file a bug report, so reprepro can handle this in the future.\n", gpg_err_code(sig->status)); return false; } return false; }
retvalue tracking_parse(struct distribution *d, struct configiterator *iter) { enum trackingflags { tf_keep, tf_all, tf_minimal, tf_includechanges, tf_includebyhand, tf_includelogs, tf_keepsources, tf_needsources, tf_embargoalls, tf_COUNT /* must be last */ }; static const struct constant trackingflags[] = { {"keep", tf_keep}, {"all", tf_all}, {"minimal", tf_minimal}, {"includechanges", tf_includechanges}, {"includelogs", tf_includelogs}, {"includebyhand", tf_includebyhand}, {"keepsources", tf_keepsources}, {"needsources", tf_needsources}, {"embargoalls", tf_embargoalls}, {NULL, -1} }; bool flags[tf_COUNT]; retvalue r; int modecount; assert (d->tracking == dt_NONE); memset(flags, 0, sizeof(flags)); r = config_getflags(iter, "Tracking", trackingflags, flags, IGNORABLE(unknownfield), ""); assert (r != RET_NOTHING); if (RET_WAS_ERROR(r)) return r; modecount = flags[tf_keep]?1:0 + flags[tf_minimal]?1:0 + flags[tf_all]?1:0; if (modecount > 1) { fprintf(stderr, "Error parsing config file %s, line %u:\n" "Only one of 'keep','all' or 'minimal' can be in one Tracking header.\n", config_filename(iter), config_line(iter)); return RET_ERROR; } if (modecount < 1) { fprintf(stderr, "Error parsing config file %s, line %u, column %u:\n" "Tracking mode ('keep','all' or 'minimal') expected.\n", config_filename(iter), config_line(iter), config_column(iter)); return RET_ERROR; } if (flags[tf_keep]) d->tracking = dt_KEEP; else if (flags[tf_minimal]) d->tracking = dt_MINIMAL; else d->tracking = dt_ALL; d->trackingoptions.includechanges = flags[tf_includechanges]; d->trackingoptions.includebyhand = flags[tf_includebyhand]; d->trackingoptions.includelogs = flags[tf_includelogs]; d->trackingoptions.keepsources = flags[tf_keepsources]; d->trackingoptions.needsources = flags[tf_needsources]; if (flags[tf_needsources]) fprintf(stderr, "Warning parsing config file %s, line %u:\n" "'needsources' ignored as not yet supported.\n", config_filename(iter), config_line(iter)); d->trackingoptions.embargoalls = flags[tf_embargoalls]; if (flags[tf_embargoalls]) fprintf(stderr, "Warning parsing config file %s, line %u:\n" "'embargoall' ignored as not yet supported.\n", config_filename(iter), config_line(iter)); return RET_OK; }