diff options
Diffstat (limited to 'src/import/pull-common.c')
-rw-r--r-- | src/import/pull-common.c | 121 |
1 files changed, 63 insertions, 58 deletions
diff --git a/src/import/pull-common.c b/src/import/pull-common.c index 5ddc0c56f4..62a9195cc4 100644 --- a/src/import/pull-common.c +++ b/src/import/pull-common.c @@ -218,37 +218,40 @@ int pull_make_path(const char *url, const char *etag, const char *image_root, co return 0; } -int pull_make_settings_job( +int pull_make_auxiliary_job( PullJob **ret, const char *url, + int (*strip_suffixes)(const char *name, char **ret), + const char *suffix, CurlGlue *glue, PullJobFinished on_finished, void *userdata) { - _cleanup_free_ char *last_component = NULL, *ll = NULL, *settings_url = NULL; + _cleanup_free_ char *last_component = NULL, *ll = NULL, *auxiliary_url = NULL; _cleanup_(pull_job_unrefp) PullJob *job = NULL; const char *q; int r; assert(ret); assert(url); + assert(strip_suffixes); assert(glue); r = import_url_last_component(url, &last_component); if (r < 0) return r; - r = tar_strip_suffixes(last_component, &ll); + r = strip_suffixes(last_component, &ll); if (r < 0) return r; - q = strjoina(ll, ".nspawn"); + q = strjoina(ll, suffix); - r = import_url_change_last_component(url, q, &settings_url); + r = import_url_change_last_component(url, q, &auxiliary_url); if (r < 0) return r; - r = pull_job_new(&job, settings_url, glue, userdata); + r = pull_job_new(&job, auxiliary_url, glue, userdata); if (r < 0) return r; @@ -320,45 +323,39 @@ int pull_make_verification_jobs( return 0; } -int pull_verify(PullJob *main_job, - PullJob *settings_job, - PullJob *checksum_job, - PullJob *signature_job) { - - _cleanup_close_pair_ int gpg_pipe[2] = { -1, -1 }; +static int verify_one(PullJob *checksum_job, PullJob *job) { _cleanup_free_ char *fn = NULL; - _cleanup_close_ int sig_file = -1; - const char *p, *line; - char sig_file_path[] = "/tmp/sigXXXXXX", gpg_home[] = "/tmp/gpghomeXXXXXX"; - _cleanup_(sigkill_waitp) pid_t pid = 0; - bool gpg_home_created = false; + const char *line, *p; int r; - assert(main_job); - assert(main_job->state == PULL_JOB_DONE); + assert(checksum_job); - if (!checksum_job) + if (!job) return 0; - assert(main_job->calc_checksum); - assert(main_job->checksum); - assert(checksum_job->state == PULL_JOB_DONE); + assert(IN_SET(job->state, PULL_JOB_DONE, PULL_JOB_FAILED)); - if (!checksum_job->payload || checksum_job->payload_size <= 0) { - log_error("Checksum is empty, cannot verify."); - return -EBADMSG; - } + /* Don't verify the checksum if we didn't actually successfully download something new */ + if (job->state != PULL_JOB_DONE) + return 0; + if (job->error != 0) + return 0; + if (job->etag_exists) + return 0; - r = import_url_last_component(main_job->url, &fn); + assert(job->calc_checksum); + assert(job->checksum); + + r = import_url_last_component(job->url, &fn); if (r < 0) return log_oom(); if (!filename_is_valid(fn)) { - log_error("Cannot verify checksum, could not determine valid server-side file name."); + log_error("Cannot verify checksum, could not determine server-side file name."); return -EBADMSG; } - line = strjoina(main_job->checksum, " *", fn, "\n"); + line = strjoina(job->checksum, " *", fn, "\n"); p = memmem(checksum_job->payload, checksum_job->payload_size, @@ -366,47 +363,55 @@ int pull_verify(PullJob *main_job, strlen(line)); if (!p || (p != (char*) checksum_job->payload && p[-1] != '\n')) { - log_error("DOWNLOAD INVALID: Checksum did not check out, payload has been tampered with."); + log_error("DOWNLOAD INVALID: Checksum of %s file did not checkout, file has been tampered with.", fn); return -EBADMSG; } - log_info("SHA256 checksum of %s is valid.", main_job->url); + log_info("SHA256 checksum of %s is valid.", job->url); + return 1; +} - assert(!settings_job || IN_SET(settings_job->state, PULL_JOB_DONE, PULL_JOB_FAILED)); +int pull_verify(PullJob *main_job, + PullJob *roothash_job, + PullJob *settings_job, + PullJob *checksum_job, + PullJob *signature_job) { - if (settings_job && - settings_job->state == PULL_JOB_DONE && - settings_job->error == 0 && - !settings_job->etag_exists) { + _cleanup_close_pair_ int gpg_pipe[2] = { -1, -1 }; + _cleanup_free_ char *fn = NULL; + _cleanup_close_ int sig_file = -1; + char sig_file_path[] = "/tmp/sigXXXXXX", gpg_home[] = "/tmp/gpghomeXXXXXX"; + _cleanup_(sigkill_waitp) pid_t pid = 0; + bool gpg_home_created = false; + int r; - _cleanup_free_ char *settings_fn = NULL; + assert(main_job); + assert(main_job->state == PULL_JOB_DONE); - assert(settings_job->calc_checksum); - assert(settings_job->checksum); + if (!checksum_job) + return 0; - r = import_url_last_component(settings_job->url, &settings_fn); - if (r < 0) - return log_oom(); + assert(main_job->calc_checksum); + assert(main_job->checksum); - if (!filename_is_valid(settings_fn)) { - log_error("Cannot verify checksum, could not determine server-side settings file name."); - return -EBADMSG; - } + assert(checksum_job->state == PULL_JOB_DONE); - line = strjoina(settings_job->checksum, " *", settings_fn, "\n"); + if (!checksum_job->payload || checksum_job->payload_size <= 0) { + log_error("Checksum is empty, cannot verify."); + return -EBADMSG; + } - p = memmem(checksum_job->payload, - checksum_job->payload_size, - line, - strlen(line)); + r = verify_one(checksum_job, main_job); + if (r < 0) + return r; - if (!p || (p != (char*) checksum_job->payload && p[-1] != '\n')) { - log_error("DOWNLOAD INVALID: Checksum of settings file did not checkout, settings file has been tampered with."); - return -EBADMSG; - } + r = verify_one(checksum_job, roothash_job); + if (r < 0) + return r; - log_info("SHA256 checksum of %s is valid.", settings_job->url); - } + r = verify_one(checksum_job, settings_job); + if (r < 0) + return r; if (!signature_job) return 0; |