Blame SOURCES/openscap-1.3.6-http_error_fix-PR_1805.patch

5a421d
From d2790140325a3d77264937c38d5076899c824dd4 Mon Sep 17 00:00:00 2001
5a421d
From: =?UTF-8?q?Jan=20=C4=8Cern=C3=BD?= <jcerny@redhat.com>
5a421d
Date: Fri, 10 Sep 2021 10:11:00 +0200
5a421d
Subject: [PATCH] Fail download on HTTP errors
5a421d
5a421d
When the HTTP server returns status code greater than or equal 400,
5a421d
the download will fail.
5a421d
5a421d
Resolves: rhbz#2002733
5a421d
---
5a421d
 src/common/oscap_acquire.c | 20 ++++++++++++++++++--
5a421d
 tests/DS/test_ds_misc.sh   | 15 +++++++++++++++
5a421d
 2 files changed, 33 insertions(+), 2 deletions(-)
5a421d
5a421d
diff --git a/src/common/oscap_acquire.c b/src/common/oscap_acquire.c
5a421d
index cd9bfc36f6..8f4991751f 100644
5a421d
--- a/src/common/oscap_acquire.c
5a421d
+++ b/src/common/oscap_acquire.c
5a421d
@@ -328,6 +328,14 @@ char* oscap_acquire_url_download(const char *url, size_t* memory_size)
5a421d
 
5a421d
 	CURLcode res;
5a421d
 
5a421d
+	/* CURLOPT_FAILONERROR - request failure on HTTP response >= 400 */
5a421d
+	res = curl_easy_setopt(curl, CURLOPT_FAILONERROR, true);
5a421d
+	if (res != 0) {
5a421d
+		curl_easy_cleanup(curl);
5a421d
+		oscap_seterr(OSCAP_EFAMILY_NET, "Failed to set CURLOPT_FAILONERROR: %s", curl_easy_strerror(res));
5a421d
+		return NULL;
5a421d
+	}
5a421d
+
5a421d
 	res = curl_easy_setopt(curl, CURLOPT_URL, url);
5a421d
 	if (res != 0) {
5a421d
 		curl_easy_cleanup(curl);
5a421d
@@ -387,14 +395,22 @@ char* oscap_acquire_url_download(const char *url, size_t* memory_size)
5a421d
 	}
5a421d
 
5a421d
 	res = curl_easy_perform(curl);
5a421d
-	curl_easy_cleanup(curl);
5a421d
 
5a421d
 	if (res != 0) {
5a421d
-		oscap_seterr(OSCAP_EFAMILY_NET, "Download failed: %s", curl_easy_strerror(res));
5a421d
+		if (res == CURLE_HTTP_RETURNED_ERROR) {
5a421d
+			long http_code = 0;
5a421d
+			curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &http_code);
5a421d
+			oscap_seterr(OSCAP_EFAMILY_NET, "Download failed: %s: %ld", curl_easy_strerror(res), http_code);
5a421d
+		} else {
5a421d
+			oscap_seterr(OSCAP_EFAMILY_NET, "Download failed: %s", curl_easy_strerror(res));
5a421d
+		}
5a421d
+		curl_easy_cleanup(curl);
5a421d
 		oscap_buffer_free(buffer);
5a421d
 		return NULL;
5a421d
 	}
5a421d
 
5a421d
+	curl_easy_cleanup(curl);
5a421d
+
5a421d
 	*memory_size = oscap_buffer_get_length(buffer);
5a421d
 	char* data = oscap_buffer_bequeath(buffer); // get data and free buffer struct
5a421d
 	return data;
5a421d
diff --git a/tests/DS/test_ds_misc.sh b/tests/DS/test_ds_misc.sh
5a421d
index 4d2dfc449a..159007518e 100755
5a421d
--- a/tests/DS/test_ds_misc.sh
5a421d
+++ b/tests/DS/test_ds_misc.sh
5a421d
@@ -250,6 +250,19 @@ function test_ds_continue_without_remote_resources() {
5a421d
 	rm -f "$result" "$oval_result"
5a421d
 }
5a421d
 
5a421d
+function test_ds_error_remote_resources() {
5a421d
+	local DS="${srcdir}/$1"
5a421d
+	local PROFILE="$2"
5a421d
+	local result=$(mktemp)
5a421d
+	local stderr=$(mktemp)
5a421d
+
5a421d
+	$OSCAP xccdf eval --fetch-remote-resources --profile "$PROFILE" --results "$result" "$DS" 2>"$stderr" || ret=$?
5a421d
+	grep -q "Downloading: https://www.example.com/security/data/oval/oval.xml.bz2 ... error" "$stderr"
5a421d
+	grep -q "OpenSCAP Error: Download failed: HTTP response code said error: 404" "$stderr"
5a421d
+
5a421d
+	rm -f "$result" "$stderr"
5a421d
+}
5a421d
+
5a421d
 function test_source_date_epoch() {
5a421d
 	local xccdf="$srcdir/sds_multiple_oval/multiple-oval-xccdf.xml"
5a421d
 	local result="$(mktemp)"
5a421d
@@ -286,7 +299,9 @@ test_run "eval_cpe" test_eval_cpe eval_cpe/sds.xml
5a421d
 test_run "test_eval_complex" test_eval_complex
5a421d
 test_run "sds_add_multiple_oval_twice_in_row" sds_add_multiple_twice
5a421d
 test_run "test_ds_1_2_continue_without_remote_resources" test_ds_continue_without_remote_resources ds_continue_without_remote_resources/remote_content_1.2.ds.xml xccdf_com.example.www_profile_test_remote_res
5a421d
+test_run "test_ds_1_2_error_remote_resources" test_ds_error_remote_resources ds_continue_without_remote_resources/remote_content_1.2.ds.xml xccdf_com.example.www_profile_test_remote_res
5a421d
 test_run "test_ds_1_3_continue_without_remote_resources" test_ds_continue_without_remote_resources ds_continue_without_remote_resources/remote_content_1.3.ds.xml xccdf_com.example.www_profile_test_remote_res
5a421d
+test_run "test_ds_1_3_error_remote_resources" test_ds_error_remote_resources ds_continue_without_remote_resources/remote_content_1.3.ds.xml xccdf_com.example.www_profile_test_remote_res
5a421d
 test_run "test_source_date_epoch" test_source_date_epoch
5a421d
 
5a421d
 test_exit