From 495d09810aa9ad6ed70ad0cf122e12007f2b8ae1 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Wed, 15 Feb 2023 10:47:04 -0500 Subject: [PATCH] aws_sigv4: fall back to UNSIGNED-PAYLOAD for sign_as_s3 all s3 requests default to UNSIGNED-PAYLOAD and add the required x-amz-content-sha256 header. this allows CURLAUTH_AWS_SIGV4 to correctly sign s3 requests to amazon with no additional configuration Signed-off-by: Casey Bodley Closes #9995 --- docs/libcurl/opts/CURLOPT_AWS_SIGV4.3 | 4 + lib/http_aws_sigv4.c | 195 ++++++++++++++++++-------- tests/data/Makefile.inc | 1 + tests/data/test1970 | 74 ++++++++++ tests/data/test1971 | 70 +++++++++ tests/data/test1972 | 79 +++++++++++ tests/data/test1973 | 75 ++++++++++ tests/data/test1974 | 73 ++++++++++ tests/data/test1975 | 70 +++++++++ tests/libtest/Makefile.inc | 19 +++ tests/libtest/lib1970.c | 73 ++++++++++ tests/libtest/lib1971.c | 83 +++++++++++ tests/libtest/lib1972.c | 84 +++++++++++ tests/libtest/lib1973.c | 72 ++++++++++ tests/libtest/lib1974.c | 65 +++++++++ tests/libtest/lib1975.c | 85 +++++++++++ 16 files changed, 1067 insertions(+), 55 deletions(-) create mode 100644 tests/data/test1970 create mode 100644 tests/data/test1971 create mode 100644 tests/data/test1972 create mode 100644 tests/data/test1973 create mode 100644 tests/data/test1974 create mode 100644 tests/data/test1975 create mode 100644 tests/libtest/lib1970.c create mode 100644 tests/libtest/lib1971.c create mode 100644 tests/libtest/lib1972.c create mode 100644 tests/libtest/lib1973.c create mode 100644 tests/libtest/lib1974.c create mode 100644 tests/libtest/lib1975.c diff --git a/docs/libcurl/opts/CURLOPT_AWS_SIGV4.3 b/docs/libcurl/opts/CURLOPT_AWS_SIGV4.3 index dfc0be8d67..d4519fc95b 100644 --- a/docs/libcurl/opts/CURLOPT_AWS_SIGV4.3 +++ b/docs/libcurl/opts/CURLOPT_AWS_SIGV4.3 @@ -101,5 +101,9 @@ calculation. For POST requests, this is a checksum of the provided \fICURLOPT_POSTFIELDS(3)\fP. Otherwise, it's the checksum of an empty buffer. For requests like PUT, you can provide your own checksum in a HTTP header named \fBx-provider2-content-sha256\fP. +.PP +For \fBaws:s3\fP, a \fBx-amz-content-sha256\fP header is added to every request +if not already present. For s3 requests with unknown payload, this header takes +the special value "UNSIGNED-PAYLOAD". .SH "SEE ALSO" .BR CURLOPT_HEADEROPT "(3), " CURLOPT_HTTPHEADER "(3), " diff --git a/lib/http_aws_sigv4.c b/lib/http_aws_sigv4.c index f8ce1695e8..c64e3ec2ca 100644 --- a/lib/http_aws_sigv4.c +++ b/lib/http_aws_sigv4.c @@ -58,13 +58,15 @@ #define TIMESTAMP_SIZE 17 -static void sha256_to_hex(char *dst, unsigned char *sha, size_t dst_l) +/* hex-encoded with trailing null */ +#define SHA256_HEX_LENGTH (2 * SHA256_DIGEST_LENGTH + 1) + +static void sha256_to_hex(char *dst, unsigned char *sha) { int i; - DEBUGASSERT(dst_l >= 65); - for(i = 0; i < 32; ++i) { - msnprintf(dst + (i * 2), dst_l - (i * 2), "%02x", sha[i]); + for(i = 0; i < SHA256_DIGEST_LENGTH; ++i) { + msnprintf(dst + (i * 2), SHA256_HEX_LENGTH - (i * 2), "%02x", sha[i]); } } @@ -135,6 +137,7 @@ static CURLcode make_headers(struct Curl_easy *data, char *timestamp, char *provider1, char **date_header, + char *content_sha256_header, struct dynbuf *canonical_headers, struct dynbuf *signed_headers) { @@ -189,6 +192,13 @@ static CURLcode make_headers(struct Curl_easy *data, } + if (*content_sha256_header) { + tmp_head = curl_slist_append(head, content_sha256_header); + if(!tmp_head) + goto fail; + head = tmp_head; + } + for(l = data->set.headers; l; l = l->next) { tmp_head = curl_slist_append(head, l->data); if(!tmp_head) @@ -267,6 +277,9 @@ fail: } #define CONTENT_SHA256_KEY_LEN (MAX_SIGV4_LEN + sizeof("X--Content-Sha256")) +/* add 2 for ": " between header name and value */ +#define CONTENT_SHA256_HDR_LEN (CONTENT_SHA256_KEY_LEN + 2 + \ + SHA256_HEX_LENGTH) /* try to parse a payload hash from the content-sha256 header */ static char *parse_content_sha_hdr(struct Curl_easy *data, @@ -300,6 +313,67 @@ static char *parse_content_sha_hdr(struct Curl_easy *data, return value; } +static CURLcode calc_payload_hash(struct Curl_easy *data, + unsigned char *sha_hash, char *sha_hex) +{ + const char *post_data = data->set.postfields; + size_t post_data_len = 0; + CURLcode ret = CURLE_OUT_OF_MEMORY; + + if(post_data) { + if(data->set.postfieldsize < 0) + post_data_len = strlen(post_data); + else + post_data_len = (size_t)data->set.postfieldsize; + } + ret = Curl_sha256it(sha_hash, (const unsigned char *) post_data, + post_data_len); + if(ret) + goto fail; + + sha256_to_hex(sha_hex, sha_hash); +fail: + return ret; +} + +#define S3_UNSIGNED_PAYLOAD "UNSIGNED-PAYLOAD" + +static CURLcode calc_s3_payload_hash(struct Curl_easy *data, + Curl_HttpReq httpreq, char *provider1, + unsigned char *sha_hash, + char *sha_hex, char *header) +{ + bool empty_method = (httpreq == HTTPREQ_GET || httpreq == HTTPREQ_HEAD); + /* The request method or filesize indicate no request payload */ + bool empty_payload = (empty_method || data->set.filesize == 0); + /* The POST payload is in memory */ + bool post_payload = (httpreq == HTTPREQ_POST && data->set.postfields); + CURLcode ret = CURLE_OUT_OF_MEMORY; + + if(empty_payload || post_payload) { + /* Calculate a real hash when we know the request payload */ + ret = calc_payload_hash(data, sha_hash, sha_hex); + if(ret) + goto fail; + ret = CURLE_OUT_OF_MEMORY; + } + else { + /* Fall back to s3's UNSIGNED-PAYLOAD */ + size_t len = sizeof(S3_UNSIGNED_PAYLOAD) - 1; + DEBUGASSERT(len < SHA256_HEX_LENGTH); /* 16 < 65 */ + memcpy(sha_hex, S3_UNSIGNED_PAYLOAD, len); + sha_hex[len] = 0; + } + + /* format the required content-sha256 header */ + msnprintf(header, CONTENT_SHA256_HDR_LEN, + "x-%s-content-sha256: %s", provider1, sha_hex); + + ret = CURLE_OK; +fail: + return ret; +} + CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) { CURLcode ret = CURLE_OUT_OF_MEMORY; @@ -310,6 +384,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) char provider1[MAX_SIGV4_LEN + 1]=""; char region[MAX_SIGV4_LEN + 1]=""; char service[MAX_SIGV4_LEN + 1]=""; + bool sign_as_s3 = false; const char *hostname = conn->host.name; time_t clock; struct tm tm; @@ -318,20 +393,21 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) struct dynbuf canonical_headers; struct dynbuf signed_headers; char *date_header = NULL; + Curl_HttpReq httpreq; + const char *method = NULL; char *payload_hash = NULL; size_t payload_hash_len = 0; - const char *post_data = data->set.postfields; - size_t post_data_len = 0; - unsigned char sha_hash[32]; - char sha_hex[65]; + unsigned char sha_hash[SHA256_DIGEST_LENGTH]; + char sha_hex[SHA256_HEX_LENGTH]; + char content_sha256_hdr[CONTENT_SHA256_HDR_LEN + 2] = ""; /* add \r\n */ char *canonical_request = NULL; char *request_type = NULL; char *credential_scope = NULL; char *str_to_sign = NULL; const char *user = data->state.aptr.user ? data->state.aptr.user : ""; char *secret = NULL; - unsigned char sign0[32] = {0}; - unsigned char sign1[32] = {0}; + unsigned char sign0[SHA256_DIGEST_LENGTH] = {0}; + unsigned char sign1[SHA256_DIGEST_LENGTH] = {0}; char *auth_headers = NULL; DEBUGASSERT(!proxy); @@ -408,6 +484,30 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) } } + Curl_http_method(data, conn, &method, &httpreq); + + /* AWS S3 requires a x-amz-content-sha256 header, and supports special + * values like UNSIGNED-PAYLOAD */ + sign_as_s3 = (strcasecompare(provider0, "aws") && + strcasecompare(service, "s3")); + + payload_hash = parse_content_sha_hdr(data, provider1, &payload_hash_len); + + if(!payload_hash) { + if(sign_as_s3) + ret = calc_s3_payload_hash(data, httpreq, provider1, sha_hash, + sha_hex, content_sha256_hdr); + else + ret = calc_payload_hash(data, sha_hash, sha_hex); + if(ret) + goto fail; + ret = CURLE_OUT_OF_MEMORY; + + payload_hash = sha_hex; + /* may be shorter than SHA256_HEX_LENGTH, like S3_UNSIGNED_PAYLOAD */ + payload_hash_len = strlen(sha_hex); + } + #ifdef DEBUGBUILD { char *force_timestamp = getenv("CURL_FORCETIME"); @@ -429,54 +529,37 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) } ret = make_headers(data, hostname, timestamp, provider1, - &date_header, &canonical_headers, &signed_headers); + &date_header, content_sha256_hdr, + &canonical_headers, &signed_headers); if(ret) goto fail; ret = CURLE_OUT_OF_MEMORY; + if(*content_sha256_hdr) { + /* make_headers() needed this without the \r\n for canonicalization */ + size_t hdrlen = strlen(content_sha256_hdr); + DEBUGASSERT(hdrlen + 3 < sizeof(content_sha256_hdr)); + memcpy(content_sha256_hdr + hdrlen, "\r\n", 3); + } + memcpy(date, timestamp, sizeof(date)); date[sizeof(date) - 1] = 0; - payload_hash = parse_content_sha_hdr(data, provider1, &payload_hash_len); - - if(!payload_hash) { - if(post_data) { - if(data->set.postfieldsize < 0) - post_data_len = strlen(post_data); - else - post_data_len = (size_t)data->set.postfieldsize; - } - if(Curl_sha256it(sha_hash, (const unsigned char *) post_data, - post_data_len)) - goto fail; - - sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex)); - payload_hash = sha_hex; - payload_hash_len = strlen(sha_hex); - } - - { - Curl_HttpReq httpreq; - const char *method; - - Curl_http_method(data, conn, &method, &httpreq); - - canonical_request = - curl_maprintf("%s\n" /* HTTPRequestMethod */ - "%s\n" /* CanonicalURI */ - "%s\n" /* CanonicalQueryString */ - "%s\n" /* CanonicalHeaders */ - "%s\n" /* SignedHeaders */ - "%.*s", /* HashedRequestPayload in hex */ - method, - data->state.up.path, - data->state.up.query ? data->state.up.query : "", - Curl_dyn_ptr(&canonical_headers), - Curl_dyn_ptr(&signed_headers), - (int)payload_hash_len, payload_hash); - if(!canonical_request) - goto fail; - } + canonical_request = + curl_maprintf("%s\n" /* HTTPRequestMethod */ + "%s\n" /* CanonicalURI */ + "%s\n" /* CanonicalQueryString */ + "%s\n" /* CanonicalHeaders */ + "%s\n" /* SignedHeaders */ + "%.*s", /* HashedRequestPayload in hex */ + method, + data->state.up.path, + data->state.up.query ? data->state.up.query : "", + Curl_dyn_ptr(&canonical_headers), + Curl_dyn_ptr(&signed_headers), + (int)payload_hash_len, payload_hash); + if(!canonical_request) + goto fail; /* provider 0 lowercase */ Curl_strntolower(provider0, provider0, strlen(provider0)); @@ -493,7 +576,7 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) strlen(canonical_request))) goto fail; - sha256_to_hex(sha_hex, sha_hash, sizeof(sha_hex)); + sha256_to_hex(sha_hex, sha_hash); /* provider 0 uppercase */ Curl_strntoupper(provider0, provider0, strlen(provider0)); @@ -527,20 +610,22 @@ CURLcode Curl_output_aws_sigv4(struct Curl_easy *data, bool proxy) HMAC_SHA256(sign0, sizeof(sign0), request_type, strlen(request_type), sign1); HMAC_SHA256(sign1, sizeof(sign1), str_to_sign, strlen(str_to_sign), sign0); - sha256_to_hex(sha_hex, sign0, sizeof(sha_hex)); + sha256_to_hex(sha_hex, sign0); /* provider 0 uppercase */ auth_headers = curl_maprintf("Authorization: %s4-HMAC-SHA256 " "Credential=%s/%s, " "SignedHeaders=%s, " "Signature=%s\r\n" - "%s\r\n", + "%s\r\n" + "%s", /* optional sha256 header includes \r\n */ provider0, user, credential_scope, Curl_dyn_ptr(&signed_headers), sha_hex, - date_header); + date_header, + content_sha256_hdr); if(!auth_headers) { goto fail; } diff --git a/tests/data/Makefile.inc b/tests/data/Makefile.inc index 846087642b..1726526910 100644 --- a/tests/data/Makefile.inc +++ b/tests/data/Makefile.inc @@ -226,6 +226,7 @@ test1916 test1917 test1918 test1919 \ test1933 test1934 test1935 test1936 test1937 test1938 test1939 test1940 \ test1941 test1942 test1943 test1944 test1945 test1946 test1947 test1948 \ test1955 test1956 test1957 test1958 test1959 test1960 \ +test1970 test1971 test1972 test1973 test1974 test1975 \ \ test2000 test2001 test2002 test2003 test2004 \ \ diff --git a/tests/data/test1970 b/tests/data/test1970 new file mode 100644 index 0000000000..1fbe60b459 --- /dev/null +++ b/tests/data/test1970 @@ -0,0 +1,74 @@ + + + +HTTP +CURLOPT_AWS_SIGV4 + + + +# Server-side + + +HTTP/1.1 302 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Content-Length: 0 +Location: /%TESTNUMBER0002 + + + +HTTP/1.1 200 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Content-Length: 0 + + + + +# Client-side + + +http + +# this relies on the debug feature which allow to set the time + +SSL +debug +crypto + + +CURL_FORCEHOST=1 + + + +HTTP AWS_SIGV4 for AWS S3: UPLOAD with INFILESIZE=0 + + +lib%TESTNUMBER + + + +http://exam.ple.com:9000/aws_sigv4/testapi/test exam.ple.com:9000:%HOSTIP:%HTTPPORT + + + +# Verify data after the test has been "shot" + + +^User-Agent:.* +^Content-Type:.* +^Accept:.* + + +PUT /aws_sigv4/testapi/test HTTP/1.1 +Host: exam.ple.com:9000 +Authorization: AWS4-HMAC-SHA256 Credential=xxx/19700101/us-east-1/s3/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=a028756f42a859122e9609c1f90cae4b272d6b03bf60d9fd354138176dfa2260 +X-Amz-Date: 19700101T000000Z +x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +Content-Length: 0 + + + + diff --git a/tests/data/test1971 b/tests/data/test1971 new file mode 100644 index 0000000000..c311d176f8 --- /dev/null +++ b/tests/data/test1971 @@ -0,0 +1,70 @@ + + + +HTTP +CURLOPT_AWS_SIGV4 + + + +# Server-side + + +HTTP/1.1 100 Continue + +HTTP/1.1 200 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Content-Length: 0 + + + + +# Client-side + + +http + +# this relies on the debug feature which allow to set the time + +SSL +debug +crypto + + +CURL_FORCEHOST=1 + + + +HTTP AWS_SIGV4 for AWS S3: UPLOAD with unknown INFILESIZE + + +lib%TESTNUMBER + + + +http://exam.ple.com:9000/aws_sigv4/testapi/test exam.ple.com:9000:%HOSTIP:%HTTPPORT + + + +# Verify data after the test has been "shot" + + +^User-Agent:.* +^Content-Type:.* +^Accept:.* + + +PUT /aws_sigv4/testapi/test HTTP/1.1 +Host: exam.ple.com:9000 +Authorization: AWS4-HMAC-SHA256 Credential=xxx/19700101/us-east-1/s3/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=4a6e9b4af0542ffb83744c6852f8e1bfec14f2a67e6f6f037b39f172f79d62af +X-Amz-Date: 19700101T000000Z +x-amz-content-sha256: UNSIGNED-PAYLOAD +Transfer-Encoding: chunked +Expect: 100-continue + +0 + + + + diff --git a/tests/data/test1972 b/tests/data/test1972 new file mode 100644 index 0000000000..70c183737e --- /dev/null +++ b/tests/data/test1972 @@ -0,0 +1,79 @@ + + + +HTTP +CURLOPT_AWS_SIGV4 + + + +# Server-side + + +HTTP/1.1 302 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Content-Length: 0 +Location: /%TESTNUMBER0002 + + + +HTTP/1.1 200 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Content-Length: 0 + + + + +# Client-side + + +http + +# this relies on the debug feature which allow to set the time + +SSL +debug +crypto + + +CURL_FORCEHOST=1 + + + +HTTP AWS_SIGV4 for AWS S3: MIMEPOST + + +lib%TESTNUMBER + + + +http://exam.ple.com:9000/aws_sigv4/testapi/test exam.ple.com:9000:%HOSTIP:%HTTPPORT + + + +# Verify data after the test has been "shot" + + +^User-Agent:.* +^Content-Type:.* +^Accept:.* + + +POST /aws_sigv4/testapi/test HTTP/1.1 +Host: exam.ple.com:9000 +Authorization: AWS4-HMAC-SHA256 Credential=xxx/19700101/us-east-1/s3/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=eaee0f1c5984ad5d81c8bc7805f28c7b83b35322de654b2ace18cb8cf6d5a9cb +X-Amz-Date: 19700101T000000Z +x-amz-content-sha256: UNSIGNED-PAYLOAD +Content-Length: 142 + +--------------------------3433323135333231 +Content-Disposition: attachment; name="foo" + +bar +--------------------------3433323135333231-- + + + diff --git a/tests/data/test1973 b/tests/data/test1973 new file mode 100644 index 0000000000..559fd5fc7e --- /dev/null +++ b/tests/data/test1973 @@ -0,0 +1,75 @@ + + + +HTTP +CURLOPT_AWS_SIGV4 + + + +# Server-side + + +HTTP/1.1 302 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Content-Length: 0 +Location: /%TESTNUMBER0002 + + + +HTTP/1.1 200 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Content-Length: 0 + + + + +# Client-side + + +http + +# this relies on the debug feature which allow to set the time + +SSL +debug +crypto + + +CURL_FORCEHOST=1 + + + +HTTP AWS_SIGV4 for AWS S3: POSTFIELDS + + +lib%TESTNUMBER + + + +http://exam.ple.com:9000/aws_sigv4/testapi/test exam.ple.com:9000:%HOSTIP:%HTTPPORT + + + +# Verify data after the test has been "shot" + + +^User-Agent:.* +^Content-Type:.* +^Accept:.* + + +POST /aws_sigv4/testapi/test HTTP/1.1 +Host: exam.ple.com:9000 +Authorization: AWS4-HMAC-SHA256 Credential=xxx/19700101/us-east-1/s3/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=7eb34202214384872221b99a9c671b7517891ac6af56b0aff24ec51adf62b10a +X-Amz-Date: 19700101T000000Z +x-amz-content-sha256: 4b02e333ccf7cf530ddee3e10ebe54e935500b5e570e68650d63d743e8bbc045 +Content-Length: 12 + +post fields + + + diff --git a/tests/data/test1974 b/tests/data/test1974 new file mode 100644 index 0000000000..9b5bb84756 --- /dev/null +++ b/tests/data/test1974 @@ -0,0 +1,73 @@ + + + +HTTP +CURLOPT_AWS_SIGV4 + + + +# Server-side + + +HTTP/1.1 302 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Content-Length: 0 +Location: /%TESTNUMBER0002 + + + +HTTP/1.1 200 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Content-Length: 0 + + + + +# Client-side + + +http + +# this relies on the debug feature which allow to set the time + +SSL +debug +crypto + + +CURL_FORCEHOST=1 + + + +HTTP AWS_SIGV4 for AWS S3: GET + + +lib%TESTNUMBER + + + +http://exam.ple.com:9000/aws_sigv4/testapi/test exam.ple.com:9000:%HOSTIP:%HTTPPORT + + + +# Verify data after the test has been "shot" + + +^User-Agent:.* +^Content-Type:.* +^Accept:.* + + +GET /aws_sigv4/testapi/test HTTP/1.1 +Host: exam.ple.com:9000 +Authorization: AWS4-HMAC-SHA256 Credential=xxx/19700101/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=e6270423932feafe9b00ca5d60c9ed566be649f9ca9676144288273945153021 +X-Amz-Date: 19700101T000000Z +x-amz-content-sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 + + + + diff --git a/tests/data/test1975 b/tests/data/test1975 new file mode 100644 index 0000000000..09256de040 --- /dev/null +++ b/tests/data/test1975 @@ -0,0 +1,70 @@ + + + +HTTP +CURLOPT_AWS_SIGV4 + + + +# Server-side + + +HTTP/1.1 100 Continue + +HTTP/1.1 200 OK +Date: Thu, 09 Nov 2010 14:49:00 GMT +Server: test-server/fake +Content-Type: text/html +Content-Length: 0 + + + + +# Client-side + + +http + +# this relies on the debug feature which allow to set the time + +SSL +debug +crypto + + +CURL_FORCEHOST=1 + + + +HTTP AWS_SIGV4 for AWS S3: UPLOAD with given x-amz-content-sha256 + + +lib%TESTNUMBER + + + +http://exam.ple.com:9000/aws_sigv4/testapi/test exam.ple.com:9000:%HOSTIP:%HTTPPORT + + + +# Verify data after the test has been "shot" + + +^User-Agent:.* +^Content-Type:.* +^Accept:.* + + +PUT /aws_sigv4/testapi/test HTTP/1.1 +Host: exam.ple.com:9000 +Authorization: AWS4-HMAC-SHA256 Credential=xxx/19700101/us-east-1/s3/aws4_request, SignedHeaders=content-type;host;x-amz-content-sha256;x-amz-date, Signature=a028756f42a859122e9609c1f90cae4b272d6b03bf60d9fd354138176dfa2260 +X-Amz-Date: 19700101T000000Z +Transfer-Encoding: chunked +X-Amz-Content-Sha256: e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855 +Expect: 100-continue + +0 + + + + diff --git a/tests/libtest/Makefile.inc b/tests/libtest/Makefile.inc index 615e76e3d1..626d43fd20 100644 --- a/tests/libtest/Makefile.inc +++ b/tests/libtest/Makefile.inc @@ -70,6 +70,7 @@ noinst_PROGRAMS = chkhostname libauthretry libntlmconnect \ lib1933 lib1934 lib1935 lib1936 lib1937 lib1938 lib1939 lib1940 \ lib1945 lib1946 lib1947 lib1948 lib1955 lib1956 lib1957 lib1958 lib1959 \ lib1960 \ + lib1970 lib1971 lib1972 lib1973 lib1974 lib1975 \ lib2301 lib2302 lib2304 lib2305 \ lib2402 \ lib2502 \ @@ -798,6 +799,24 @@ lib1959_CPPFLAGS = $(AM_CPPFLAGS) lib1960_SOURCES = lib1960.c $(SUPPORTFILES) lib1960_LDADD = $(TESTUTIL_LIBS) +lib1970_SOURCES = lib1970.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib1970_LDADD = $(TESTUTIL_LIBS) + +lib1971_SOURCES = lib1971.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib1971_LDADD = $(TESTUTIL_LIBS) + +lib1972_SOURCES = lib1972.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib1972_LDADD = $(TESTUTIL_LIBS) + +lib1973_SOURCES = lib1973.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib1973_LDADD = $(TESTUTIL_LIBS) + +lib1974_SOURCES = lib1974.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib1974_LDADD = $(TESTUTIL_LIBS) + +lib1975_SOURCES = lib1975.c $(SUPPORTFILES) $(TESTUTIL) $(WARNLESS) +lib1975_LDADD = $(TESTUTIL_LIBS) + lib2301_SOURCES = lib2301.c $(SUPPORTFILES) lib2301_LDADD = $(TESTUTIL_LIBS) diff --git a/tests/libtest/lib1970.c b/tests/libtest/lib1970.c new file mode 100644 index 0000000000..ff86fdd2c1 --- /dev/null +++ b/tests/libtest/lib1970.c @@ -0,0 +1,73 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2022, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "test.h" + +#include "memdebug.h" + +int test(char *URL) +{ + CURL *curl; + CURLcode res = TEST_ERR_MAJOR_BAD; + struct curl_slist *list = NULL; + struct curl_slist *connect_to = NULL; + + if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + curl = curl_easy_init(); + if(!curl) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_UPLOAD, 1L); + test_setopt(curl, CURLOPT_INFILESIZE, 0L); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_AWS_SIGV4, "aws:amz:us-east-1:s3"); + test_setopt(curl, CURLOPT_USERPWD, "xxx"); + test_setopt(curl, CURLOPT_HEADER, 0L); + test_setopt(curl, CURLOPT_URL, URL); + list = curl_slist_append(list, "Content-Type: application/json"); + if(!list) + goto test_cleanup; + test_setopt(curl, CURLOPT_HTTPHEADER, list); + if(libtest_arg2) { + connect_to = curl_slist_append(connect_to, libtest_arg2); + } + test_setopt(curl, CURLOPT_CONNECT_TO, connect_to); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_slist_free_all(connect_to); + curl_slist_free_all(list); + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib1971.c b/tests/libtest/lib1971.c new file mode 100644 index 0000000000..173fc2f12b --- /dev/null +++ b/tests/libtest/lib1971.c @@ -0,0 +1,83 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2022, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "test.h" + +#include "memdebug.h" + +static size_t read_callback(char *buffer, size_t size, size_t nitems, + void *userdata) +{ + (void)buffer; /* unused */ + (void)size; /* unused */ + (void)nitems; /* unused */ + (void)userdata; /* unused */ + return 0; +} + +int test(char *URL) +{ + CURL *curl; + CURLcode res = TEST_ERR_MAJOR_BAD; + struct curl_slist *list = NULL; + struct curl_slist *connect_to = NULL; + + if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + curl = curl_easy_init(); + if(!curl) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_UPLOAD, 1L); + test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_AWS_SIGV4, "aws:amz:us-east-1:s3"); + test_setopt(curl, CURLOPT_USERPWD, "xxx"); + test_setopt(curl, CURLOPT_HEADER, 0L); + test_setopt(curl, CURLOPT_URL, URL); + list = curl_slist_append(list, "Content-Type: application/json"); + if(!list) + goto test_cleanup; + test_setopt(curl, CURLOPT_HTTPHEADER, list); + if(libtest_arg2) { + connect_to = curl_slist_append(connect_to, libtest_arg2); + } + test_setopt(curl, CURLOPT_CONNECT_TO, connect_to); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_slist_free_all(connect_to); + curl_slist_free_all(list); + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib1972.c b/tests/libtest/lib1972.c new file mode 100644 index 0000000000..c21e8da937 --- /dev/null +++ b/tests/libtest/lib1972.c @@ -0,0 +1,84 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2022, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "test.h" + +#include "memdebug.h" + +int test(char *URL) +{ + CURL *curl; + curl_mime *mime = NULL; + curl_mimepart *part = NULL; + CURLcode res = TEST_ERR_MAJOR_BAD; + struct curl_slist *list = NULL; + struct curl_slist *connect_to = NULL; + + if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + curl = curl_easy_init(); + if(!curl) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + mime = curl_mime_init(curl); + if(!mime) + goto test_cleanup; + part = curl_mime_addpart(mime); + if(!part) + goto test_cleanup; + curl_mime_name(part, "foo"); + curl_mime_data(part, "bar", CURL_ZERO_TERMINATED); + + test_setopt(curl, CURLOPT_MIMEPOST, mime); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_AWS_SIGV4, "aws:amz:us-east-1:s3"); + test_setopt(curl, CURLOPT_USERPWD, "xxx"); + test_setopt(curl, CURLOPT_HEADER, 0L); + test_setopt(curl, CURLOPT_URL, URL); + list = curl_slist_append(list, "Content-Type: application/json"); + if(!list) + goto test_cleanup; + test_setopt(curl, CURLOPT_HTTPHEADER, list); + if(libtest_arg2) { + connect_to = curl_slist_append(connect_to, libtest_arg2); + } + test_setopt(curl, CURLOPT_CONNECT_TO, connect_to); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_slist_free_all(connect_to); + curl_slist_free_all(list); + curl_easy_cleanup(curl); + curl_mime_free(mime); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib1973.c b/tests/libtest/lib1973.c new file mode 100644 index 0000000000..d95744fcb5 --- /dev/null +++ b/tests/libtest/lib1973.c @@ -0,0 +1,72 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2022, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "test.h" + +#include "memdebug.h" + +int test(char *URL) +{ + CURL *curl; + CURLcode res = TEST_ERR_MAJOR_BAD; + struct curl_slist *list = NULL; + struct curl_slist *connect_to = NULL; + + if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + curl = curl_easy_init(); + if(!curl) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_POSTFIELDS, "post fields\n"); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_AWS_SIGV4, "aws:amz:us-east-1:s3"); + test_setopt(curl, CURLOPT_USERPWD, "xxx"); + test_setopt(curl, CURLOPT_HEADER, 0L); + test_setopt(curl, CURLOPT_URL, URL); + list = curl_slist_append(list, "Content-Type: application/json"); + if(!list) + goto test_cleanup; + test_setopt(curl, CURLOPT_HTTPHEADER, list); + if(libtest_arg2) { + connect_to = curl_slist_append(connect_to, libtest_arg2); + } + test_setopt(curl, CURLOPT_CONNECT_TO, connect_to); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_slist_free_all(connect_to); + curl_slist_free_all(list); + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib1974.c b/tests/libtest/lib1974.c new file mode 100644 index 0000000000..948d44df9d --- /dev/null +++ b/tests/libtest/lib1974.c @@ -0,0 +1,65 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2022, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "test.h" + +#include "memdebug.h" + +int test(char *URL) +{ + CURL *curl; + CURLcode res = TEST_ERR_MAJOR_BAD; + struct curl_slist *connect_to = NULL; + + if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + curl = curl_easy_init(); + if(!curl) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_AWS_SIGV4, "aws:amz:us-east-1:s3"); + test_setopt(curl, CURLOPT_USERPWD, "xxx"); + test_setopt(curl, CURLOPT_HEADER, 0L); + test_setopt(curl, CURLOPT_URL, URL); + if(libtest_arg2) { + connect_to = curl_slist_append(connect_to, libtest_arg2); + } + test_setopt(curl, CURLOPT_CONNECT_TO, connect_to); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_slist_free_all(connect_to); + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} diff --git a/tests/libtest/lib1975.c b/tests/libtest/lib1975.c new file mode 100644 index 0000000000..bca0c763f8 --- /dev/null +++ b/tests/libtest/lib1975.c @@ -0,0 +1,85 @@ +/*************************************************************************** + * _ _ ____ _ + * Project ___| | | | _ \| | + * / __| | | | |_) | | + * | (__| |_| | _ <| |___ + * \___|\___/|_| \_\_____| + * + * Copyright (C) 1998 - 2022, Daniel Stenberg, , et al. + * + * This software is licensed as described in the file COPYING, which + * you should have received as part of this distribution. The terms + * are also available at https://curl.haxx.se/docs/copyright.html. + * + * You may opt to use, copy, modify, merge, publish, distribute and/or sell + * copies of the Software, and permit persons to whom the Software is + * furnished to do so, under the terms of the COPYING file. + * + * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY + * KIND, either express or implied. + * + * SPDX-License-Identifier: curl + * + ***************************************************************************/ +#include "test.h" + +#include "memdebug.h" + +static size_t read_callback(char *buffer, size_t size, size_t nitems, + void *userdata) +{ + (void)buffer; /* unused */ + (void)size; /* unused */ + (void)nitems; /* unused */ + (void)userdata; /* unused */ + return 0; +} + +int test(char *URL) +{ + CURL *curl; + CURLcode res = TEST_ERR_MAJOR_BAD; + struct curl_slist *list = NULL; + struct curl_slist *connect_to = NULL; + + if(curl_global_init(CURL_GLOBAL_ALL) != CURLE_OK) { + fprintf(stderr, "curl_global_init() failed\n"); + return TEST_ERR_MAJOR_BAD; + } + + curl = curl_easy_init(); + if(!curl) { + fprintf(stderr, "curl_easy_init() failed\n"); + curl_global_cleanup(); + return TEST_ERR_MAJOR_BAD; + } + + test_setopt(curl, CURLOPT_UPLOAD, 1L); + test_setopt(curl, CURLOPT_READFUNCTION, read_callback); + test_setopt(curl, CURLOPT_VERBOSE, 1L); + test_setopt(curl, CURLOPT_AWS_SIGV4, "aws:amz:us-east-1:s3"); + test_setopt(curl, CURLOPT_USERPWD, "xxx"); + test_setopt(curl, CURLOPT_HEADER, 0L); + test_setopt(curl, CURLOPT_URL, URL); + list = curl_slist_append(list, "Content-Type: application/json"); + if(!list) + goto test_cleanup; + curl_slist_append(list, "X-Amz-Content-Sha256: " + "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855"); + test_setopt(curl, CURLOPT_HTTPHEADER, list); + if(libtest_arg2) { + connect_to = curl_slist_append(connect_to, libtest_arg2); + } + test_setopt(curl, CURLOPT_CONNECT_TO, connect_to); + + res = curl_easy_perform(curl); + +test_cleanup: + + curl_slist_free_all(connect_to); + curl_slist_free_all(list); + curl_easy_cleanup(curl); + curl_global_cleanup(); + + return res; +} -- 2.47.3