From: Lennart Poettering Date: Wed, 21 Jan 2015 03:03:33 +0000 (+0100) Subject: import: also add verification support to tar importer X-Git-Tag: v219~405 X-Git-Url: http://www.chiark.greenend.org.uk/ucgi/~ianmdlvl/git?a=commitdiff_plain;ds=sidebyside;h=0100b6e1bf682385e0939d4dd7be815d5cdf0e1a;hp=98c3800184cfc961b19d605f69d555d0cea8bb7a;p=elogind.git import: also add verification support to tar importer --- diff --git a/src/import/import-tar.c b/src/import/import-tar.c index e8afc269b..2a65f8916 100644 --- a/src/import/import-tar.c +++ b/src/import/import-tar.c @@ -41,6 +41,8 @@ struct TarImport { char *image_root; ImportJob *tar_job; + ImportJob *checksum_job; + ImportJob *signature_job; TarImportFinished on_finished; void *userdata; @@ -52,18 +54,22 @@ struct TarImport { char *temp_path; char *final_path; + + ImportVerify verify; }; TarImport* tar_import_unref(TarImport *i) { if (!i) return NULL; - if (i->tar_pid > 0) { - kill(i->tar_pid, SIGKILL); - wait_for_terminate(i->tar_pid, NULL); + if (i->tar_pid > 1) { + (void) kill(i->tar_pid, SIGKILL); + (void) wait_for_terminate(i->tar_pid, NULL); } import_job_unref(i->tar_job); + import_job_unref(i->checksum_job); + import_job_unref(i->signature_job); curl_glue_unref(i->glue); sd_event_unref(i->event); @@ -77,7 +83,6 @@ TarImport* tar_import_unref(TarImport *i) { free(i->final_path); free(i->image_root); free(i->local); - free(i); return NULL; @@ -135,12 +140,12 @@ static int tar_import_make_local_copy(TarImport *i) { r = import_make_path(i->tar_job->url, i->tar_job->etag, i->image_root, ".tar-", NULL, &i->final_path); if (r < 0) return log_oom(); - - r = import_make_local_copy(i->final_path, i->image_root, i->local, i->force_local); - if (r < 0) - return r; } + r = import_make_local_copy(i->final_path, i->image_root, i->local, i->force_local); + if (r < 0) + return r; + return 0; } @@ -153,6 +158,13 @@ static void tar_import_job_on_finished(ImportJob *j) { i = j->userdata; if (j->error != 0) { + if (j == i->checksum_job) + log_error_errno(j->error, "Failed to retrieve SHA256 checksum, cannot verify. (Try --verify=no?)"); + else if (j == i->signature_job) + log_error_errno(j->error, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)"); + else + log_error_errno(j->error, "Failed to retrieve image file. (Wrong URL?)"); + r = j->error; goto finish; } @@ -161,7 +173,14 @@ static void tar_import_job_on_finished(ImportJob *j) { * successfully, or the download was skipped because we * already have the etag. */ - j->disk_fd = safe_close(j->disk_fd); + if (i->tar_job->state != IMPORT_JOB_DONE) + return; + if (i->checksum_job && i->checksum_job->state != IMPORT_JOB_DONE) + return; + if (i->signature_job && i->signature_job->state != IMPORT_JOB_DONE) + return; + + j->disk_fd = safe_close(i->tar_job->disk_fd); if (i->tar_pid > 0) { r = wait_for_terminate_and_warn("tar", i->tar_pid, true); @@ -170,7 +189,13 @@ static void tar_import_job_on_finished(ImportJob *j) { goto finish; } - if (i->temp_path) { + if (!i->tar_job->etag_exists) { + /* This is a new download, verify it, and move it into place */ + + r = import_verify(i->tar_job, i->checksum_job, i->signature_job); + if (r < 0) + goto finish; + r = import_make_read_only(i->temp_path); if (r < 0) goto finish; @@ -233,6 +258,8 @@ static int tar_import_job_on_open_disk(ImportJob *j) { if (i->tar_pid == 0) { int null_fd; + /* Child */ + reset_all_signal_handlers(); reset_signal_mask(); assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0); @@ -274,7 +301,7 @@ static int tar_import_job_on_open_disk(ImportJob *j) { return 0; } -int tar_import_pull(TarImport *i, const char *url, const char *local, bool force_local) { +int tar_import_pull(TarImport *i, const char *url, const char *local, bool force_local, ImportVerify verify) { int r; assert(i); @@ -291,8 +318,8 @@ int tar_import_pull(TarImport *i, const char *url, const char *local, bool force r = free_and_strdup(&i->local, local); if (r < 0) return r; - i->force_local = force_local; + i->verify = verify; r = import_job_new(&i->tar_job, url, i->glue, i); if (r < 0) @@ -300,10 +327,32 @@ int tar_import_pull(TarImport *i, const char *url, const char *local, bool force i->tar_job->on_finished = tar_import_job_on_finished; i->tar_job->on_open_disk = tar_import_job_on_open_disk; + i->tar_job->calc_checksum = verify != IMPORT_VERIFY_NO; r = import_find_old_etags(url, i->image_root, DT_DIR, ".tar-", NULL, &i->tar_job->old_etags); if (r < 0) return r; - return import_job_begin(i->tar_job); + r = import_make_verification_jobs(&i->checksum_job, &i->signature_job, verify, url, i->glue, tar_import_job_on_finished, i); + if (r < 0) + return r; + + r = import_job_begin(i->tar_job); + if (r < 0) + return r; + + if (i->checksum_job) { + r = import_job_begin(i->checksum_job); + if (r < 0) + return r; + } + + if (i->signature_job) { + r = import_job_begin(i->signature_job); + if (r < 0) + return r; + } + + return 0; + } diff --git a/src/import/import-tar.h b/src/import/import-tar.h index 6a7477fee..6a2b901d8 100644 --- a/src/import/import-tar.h +++ b/src/import/import-tar.h @@ -23,6 +23,7 @@ #include "sd-event.h" #include "macro.h" +#include "import-util.h" typedef struct TarImport TarImport; @@ -33,4 +34,4 @@ TarImport* tar_import_unref(TarImport *import); DEFINE_TRIVIAL_CLEANUP_FUNC(TarImport*, tar_import_unref); -int tar_import_pull(TarImport *import, const char *rul, const char *local, bool force_local); +int tar_import_pull(TarImport *import, const char *rul, const char *local, bool force_local, ImportVerify verify); diff --git a/src/import/import-util.c b/src/import/import-util.c index a36e83bdc..0330bc1fb 100644 --- a/src/import/import-util.c +++ b/src/import/import-util.c @@ -404,7 +404,7 @@ int import_verify( r = pipe2(gpg_pipe, O_CLOEXEC); if (r < 0) - return log_error_errno(errno, "Failed to create pipe: %m"); + return log_error_errno(errno, "Failed to create pipe for gpg: %m"); sig_file = mkostemp(sig_file_path, O_RDWR); if (sig_file < 0) diff --git a/src/import/import.c b/src/import/import.c index d9cff3e23..0c215c648 100644 --- a/src/import/import.c +++ b/src/import/import.c @@ -135,7 +135,7 @@ static int pull_tar(int argc, char *argv[], void *userdata) { if (r < 0) return log_error_errno(r, "Failed to allocate importer: %m"); - r = tar_import_pull(import, url, local, arg_force); + r = tar_import_pull(import, url, local, arg_force, arg_verify); if (r < 0) return log_error_errno(r, "Failed to pull image: %m");