]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
pull-job: add helpers to detect requests for authentication, and accept bearer tokens
authorLennart Poettering <lennart@amutable.com>
Fri, 7 Nov 2025 07:31:34 +0000 (08:31 +0100)
committerLennart Poettering <lennart@amutable.com>
Thu, 19 Feb 2026 14:05:14 +0000 (15:05 +0100)
src/import/pull-job.c
src/import/pull-job.h

index 12bdf4c99402493e7592ea71851a11fdc2290f5d..80197d6c57e625a229d25bafd5e83f5242017974 100644 (file)
@@ -30,6 +30,10 @@ static int http_status_etag_exists(CURLcode status) {
         return status == 304;
 }
 
+static int http_status_need_authentication(CURLcode status) {
+        return status == 401;
+}
+
 void pull_job_close_disk_fd(PullJob *j) {
         if (!j)
                 return;
@@ -65,6 +69,7 @@ PullJob* pull_job_unref(PullJob *j) {
         if (j->free_userdata)
                 j->free_userdata(j->userdata);
         free(j->description);
+        free(j->authentication_challenge);
 
         return mfree(j);
 }
@@ -204,6 +209,10 @@ void pull_job_curl_on_finished(CurlGlue *g, CURL *curl, CURLcode result) {
                         j->etag_exists = true;
                         r = 0;
                         goto finish;
+                } else if (http_status_need_authentication(status)) {
+                        log_info("Access to image requires authentication.");
+                        r = -ENOKEY;
+                        goto finish;
                 } else if (status >= 300) {
 
                         if (status == 404 && j->on_not_found) {
@@ -580,6 +589,19 @@ static size_t pull_job_header_callback(void *contents, size_t size, size_t nmemb
                 goto fail;
         }
 
+        if (http_status_need_authentication(status)) {
+                _cleanup_free_ char *challenge = NULL;
+
+                r = curl_header_strdup(contents, sz, "WWW-Authenticate:", &challenge);
+                if (r < 0) {
+                        log_oom();
+                        goto fail;
+                }
+                if (r > 0)
+                        free_and_replace(j->authentication_challenge, challenge);
+                return sz;
+        }
+
         if (http_status_ok(status) || http_status_etag_exists(status)) {
                 /* Check Etag on OK and etag exists responses. */
 
@@ -846,3 +868,13 @@ int pull_job_set_accept(PullJob *j, char * const *l) {
 
         return pull_job_add_request_header(j, f);
 }
+
+int pull_job_set_bearer_token(PullJob *j, const char *token) {
+        assert(j);
+
+        _cleanup_free_ char *f = strjoin("Authorization: Bearer ", token);
+        if (!f)
+                return -ENOMEM;
+
+        return pull_job_add_request_header(j, f);
+}
index 7dd3a4cff7961a7f8518f27d37165d54d830f731..bfbdb8cced694076013cd0dc5b53b124a882f31a 100644 (file)
@@ -87,6 +87,8 @@ typedef struct PullJob {
 
         bool sync;
         bool force_memory;
+
+        char *authentication_challenge;
 } PullJob;
 
 int pull_job_new(PullJob **ret, const char *url, CurlGlue *glue, void *userdata);
@@ -100,5 +102,6 @@ void pull_job_close_disk_fd(PullJob *j);
 
 int pull_job_add_request_header(PullJob *j, const char *hdr);
 int pull_job_set_accept(PullJob *j, char * const *l);
+int pull_job_set_bearer_token(PullJob *j, const char *token);
 
 DEFINE_TRIVIAL_CLEANUP_FUNC(PullJob*, pull_job_unref);