summaryrefslogtreecommitdiff
path: root/src/import
diff options
context:
space:
mode:
Diffstat (limited to 'src/import')
-rw-r--r--src/import/meson.build77
-rw-r--r--src/import/pull-common.c34
-rw-r--r--src/import/pull-job.c48
-rw-r--r--src/import/pull-job.h8
-rw-r--r--src/import/pull-raw.c13
-rw-r--r--src/import/pull-tar.c12
6 files changed, 178 insertions, 14 deletions
diff --git a/src/import/meson.build b/src/import/meson.build
new file mode 100644
index 0000000000..f0ed92b4c2
--- /dev/null
+++ b/src/import/meson.build
@@ -0,0 +1,77 @@
+systemd_importd_sources = files('''
+ importd.c
+'''.split())
+
+systemd_pull_sources = files('''
+ pull.c
+ pull-raw.c
+ pull-raw.h
+ pull-tar.c
+ pull-tar.h
+ pull-job.c
+ pull-job.h
+ pull-common.c
+ pull-common.h
+ import-common.c
+ import-common.h
+ import-compress.c
+ import-compress.h
+ curl-util.c
+ curl-util.h
+ qcow2-util.c
+ qcow2-util.h
+'''.split())
+
+systemd_import_sources = files('''
+ import.c
+ import-raw.c
+ import-raw.h
+ import-tar.c
+ import-tar.h
+ import-common.c
+ import-common.h
+ import-compress.c
+ import-compress.h
+ qcow2-util.c
+ qcow2-util.h
+'''.split())
+
+systemd_export_sources = files('''
+ export.c
+ export-tar.c
+ export-tar.h
+ export-raw.c
+ export-raw.h
+ import-common.c
+ import-common.h
+ import-compress.c
+ import-compress.h
+'''.split())
+
+if conf.get('ENABLE_IMPORTD', 0) == 1
+ install_data('org.freedesktop.import1.conf',
+ install_dir : dbuspolicydir)
+ install_data('org.freedesktop.import1.service',
+ install_dir : dbussystemservicedir)
+
+ custom_target(
+ 'org.freedesktop.import1.policy',
+ input : 'org.freedesktop.import1.policy.in',
+ output : 'org.freedesktop.import1.policy',
+ command : intltool_command,
+ install : install_polkit,
+ install_dir : polkitpolicydir)
+
+ install_data('import-pubring.gpg',
+ install_dir : rootlibexecdir)
+ # TODO: shouldn't this be in pkgdatadir?
+endif
+
+tests += [
+ [['src/import/test-qcow2.c',
+ 'src/import/qcow2-util.c',
+ 'src/import/qcow2-util.h'],
+ [libshared],
+ [libz],
+ 'HAVE_ZLIB', 'manual'],
+]
diff --git a/src/import/pull-common.c b/src/import/pull-common.c
index 62a9195cc4..78840dd882 100644
--- a/src/import/pull-common.c
+++ b/src/import/pull-common.c
@@ -275,6 +275,7 @@ int pull_make_verification_jobs(
_cleanup_(pull_job_unrefp) PullJob *checksum_job = NULL, *signature_job = NULL;
int r;
+ const char *chksums = NULL;
assert(ret_checksum_job);
assert(ret_signature_job);
@@ -284,10 +285,16 @@ int pull_make_verification_jobs(
assert(glue);
if (verify != IMPORT_VERIFY_NO) {
- _cleanup_free_ char *checksum_url = NULL;
+ _cleanup_free_ char *checksum_url = NULL, *fn = NULL;
- /* Queue job for the SHA256SUMS file for the image */
- r = import_url_change_last_component(url, "SHA256SUMS", &checksum_url);
+ /* Queue jobs for the checksum file for the image. */
+ r = import_url_last_component(url, &fn);
+ if (r < 0)
+ return r;
+
+ chksums = strjoina(fn, ".sha256");
+
+ r = import_url_change_last_component(url, chksums, &checksum_url);
if (r < 0)
return r;
@@ -362,6 +369,15 @@ static int verify_one(PullJob *checksum_job, PullJob *job) {
line,
strlen(line));
+ if (!p) {
+ line = strjoina(job->checksum, " ", fn, "\n");
+
+ p = memmem(checksum_job->payload,
+ checksum_job->payload_size,
+ line,
+ strlen(line));
+ }
+
if (!p || (p != (char*) checksum_job->payload && p[-1] != '\n')) {
log_error("DOWNLOAD INVALID: Checksum of %s file did not checkout, file has been tampered with.", fn);
return -EBADMSG;
@@ -378,7 +394,6 @@ int pull_verify(PullJob *main_job,
PullJob *signature_job) {
_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;
@@ -416,6 +431,9 @@ int pull_verify(PullJob *main_job,
if (!signature_job)
return 0;
+ if (checksum_job->style == VERIFICATION_PER_FILE)
+ signature_job = checksum_job;
+
assert(signature_job->state == PULL_JOB_DONE);
if (!signature_job->payload || signature_job->payload_size <= 0) {
@@ -507,9 +525,11 @@ int pull_verify(PullJob *main_job,
cmd[k++] = "--keyring=" VENDOR_KEYRING_PATH;
cmd[k++] = "--verify";
- cmd[k++] = sig_file_path;
- cmd[k++] = "-";
- cmd[k++] = NULL;
+ if (checksum_job->style == VERIFICATION_PER_DIRECTORY) {
+ cmd[k++] = sig_file_path;
+ cmd[k++] = "-";
+ cmd[k++] = NULL;
+ }
stdio_unset_cloexec();
diff --git a/src/import/pull-job.c b/src/import/pull-job.c
index 70aaa5c291..320c21305a 100644
--- a/src/import/pull-job.c
+++ b/src/import/pull-job.c
@@ -22,9 +22,11 @@
#include "alloc-util.h"
#include "fd-util.h"
#include "hexdecoct.h"
+#include "import-util.h"
#include "io-util.h"
#include "machine-pool.h"
#include "parse-util.h"
+#include "pull-common.h"
#include "pull-job.h"
#include "string-util.h"
#include "strv.h"
@@ -73,6 +75,31 @@ static void pull_job_finish(PullJob *j, int ret) {
j->on_finished(j);
}
+static int pull_job_restart(PullJob *j) {
+ int r;
+ char *chksum_url = NULL;
+
+ r = import_url_change_last_component(j->url, "SHA256SUMS", &chksum_url);
+ if (r < 0)
+ return r;
+
+ free(j->url);
+ j->url = chksum_url;
+ j->state = PULL_JOB_INIT;
+ j->payload = mfree(j->payload);
+ j->payload_size = 0;
+ j->payload_allocated = 0;
+ j->written_compressed = 0;
+ j->written_uncompressed = 0;
+ j->written_since_last_grow = 0;
+
+ r = pull_job_begin(j);
+ if (r < 0)
+ return r;
+
+ return 0;
+}
+
void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
PullJob *j = NULL;
CURLcode code;
@@ -102,6 +129,26 @@ void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
r = 0;
goto finish;
} else if (status >= 300) {
+ if (status == 404 && j->style == VERIFICATION_PER_FILE) {
+
+ /* retry pull job with SHA256SUMS file */
+ r = pull_job_restart(j);
+ if (r < 0)
+ goto finish;
+
+ code = curl_easy_getinfo(j->curl, CURLINFO_RESPONSE_CODE, &status);
+ if (code != CURLE_OK) {
+ log_error("Failed to retrieve response code: %s", curl_easy_strerror(code));
+ r = -EIO;
+ goto finish;
+ }
+
+ if (status == 0) {
+ j->style = VERIFICATION_PER_DIRECTORY;
+ return;
+ }
+ }
+
log_error("HTTP request to %s failed with code %li.", j->url, status);
r = -EIO;
goto finish;
@@ -528,6 +575,7 @@ int pull_job_new(PullJob **ret, const char *url, CurlGlue *glue, void *userdata)
j->content_length = (uint64_t) -1;
j->start_usec = now(CLOCK_MONOTONIC);
j->compressed_max = j->uncompressed_max = 64LLU * 1024LLU * 1024LLU * 1024LLU; /* 64GB safety limit */
+ j->style = VERIFICATION_STYLE_UNSET;
j->url = strdup(url);
if (!j->url)
diff --git a/src/import/pull-job.h b/src/import/pull-job.h
index 3a152a50e3..412b66cf22 100644
--- a/src/import/pull-job.h
+++ b/src/import/pull-job.h
@@ -42,6 +42,12 @@ typedef enum PullJobState {
_PULL_JOB_STATE_INVALID = -1,
} PullJobState;
+typedef enum VerificationStyle {
+ VERIFICATION_STYLE_UNSET,
+ VERIFICATION_PER_FILE, /* SuSE-style ".sha256" files with inline signature */
+ VERIFICATION_PER_DIRECTORY, /* Ubuntu-style SHA256SUM files with detach SHA256SUM.gpg signatures */
+} VerificationStyle;
+
#define PULL_JOB_IS_COMPLETE(j) (IN_SET((j)->state, PULL_JOB_DONE, PULL_JOB_FAILED))
struct PullJob {
@@ -94,6 +100,8 @@ struct PullJob {
bool grow_machine_directory;
uint64_t written_since_last_grow;
+
+ VerificationStyle style;
};
int pull_job_new(PullJob **job, const char *url, CurlGlue *glue, void *userdata);
diff --git a/src/import/pull-raw.c b/src/import/pull-raw.c
index 60a769e944..a15eac1f1f 100644
--- a/src/import/pull-raw.c
+++ b/src/import/pull-raw.c
@@ -478,11 +478,9 @@ static void raw_pull_job_on_finished(PullJob *j) {
} else if (j == i->settings_job) {
if (j->error != 0)
log_info_errno(j->error, "Settings file could not be retrieved, proceeding without.");
- } else if (j->error != 0) {
+ } else if (j->error != 0 && j != i->signature_job) {
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?)");
@@ -500,6 +498,13 @@ static void raw_pull_job_on_finished(PullJob *j) {
if (!raw_pull_is_done(i))
return;
+ if (i->checksum_job->style == VERIFICATION_PER_DIRECTORY && i->signature_job->error != 0) {
+ log_error_errno(j->error, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)");
+
+ r = i->signature_job->error;
+ goto finish;
+ }
+
if (i->roothash_job)
i->roothash_job->disk_fd = safe_close(i->roothash_job->disk_fd);
if (i->settings_job)
@@ -575,7 +580,6 @@ static int raw_pull_job_on_open_disk_generic(
const char *extra,
char **temp_path) {
- _cleanup_free_ char *p = NULL;
int r;
assert(i);
@@ -744,6 +748,7 @@ int raw_pull_start(
if (i->checksum_job) {
i->checksum_job->on_progress = raw_pull_job_on_progress;
+ i->checksum_job->style = VERIFICATION_PER_FILE;
r = pull_job_begin(i->checksum_job);
if (r < 0)
diff --git a/src/import/pull-tar.c b/src/import/pull-tar.c
index 91833d6174..d4b599ba95 100644
--- a/src/import/pull-tar.c
+++ b/src/import/pull-tar.c
@@ -298,11 +298,9 @@ static void tar_pull_job_on_finished(PullJob *j) {
if (j == i->settings_job) {
if (j->error != 0)
log_info_errno(j->error, "Settings file could not be retrieved, proceeding without.");
- } else if (j->error != 0) {
+ } else if (j->error != 0 && j != i->signature_job) {
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?)");
@@ -317,6 +315,13 @@ static void tar_pull_job_on_finished(PullJob *j) {
if (!tar_pull_is_done(i))
return;
+ if (i->checksum_job->style == VERIFICATION_PER_DIRECTORY && i->signature_job->error != 0) {
+ log_error_errno(j->error, "Failed to retrieve signature file, cannot verify. (Try --verify=no?)");
+
+ r = i->signature_job->error;
+ goto finish;
+ }
+
i->tar_job->disk_fd = safe_close(i->tar_job->disk_fd);
if (i->settings_job)
i->settings_job->disk_fd = safe_close(i->settings_job->disk_fd);
@@ -547,6 +552,7 @@ int tar_pull_start(
if (i->checksum_job) {
i->checksum_job->on_progress = tar_pull_job_on_progress;
+ i->checksum_job->style = VERIFICATION_PER_FILE;
r = pull_job_begin(i->checksum_job);
if (r < 0)