summaryrefslogtreecommitdiffstats
path: root/src/rgw/rgw_rest.h
diff options
context:
space:
mode:
authorMatt Benjamin <mbenjamin@redhat.com>2023-11-27 18:00:43 +0100
committerCasey Bodley <cbodley@redhat.com>2024-02-13 19:28:30 +0100
commit5afa3fc52f088d03ddd4ab42c968815af69160cb (patch)
tree3eb922d7e7d438f0bcaf2b8f6d2ba54ebb4a9d3b /src/rgw/rgw_rest.h
parentMerge pull request #55521 from ivoalmeida/snapshot-schedule-subvolume-copies (diff)
downloadceph-5afa3fc52f088d03ddd4ab42c968815af69160cb.tar.xz
ceph-5afa3fc52f088d03ddd4ab42c968815af69160cb.zip
rgw: cumulatively fix 6 AWS SigV4 request failure cases
These changes address checksum header identification and signing algorithm selection, including checksum trailer verification for signed- and unsigned-payload cases. These changes address all the actual S3 request failures I have so far been able to reproduce, with and without content checksums and/or new trailing checksum headers, and with and without SSL. Fixes: https://tracker.ceph.com/issues/63153 Specifically, it fixes the request failures that motivated the initial tracker filing. It extracts but does not validate new client content checksums if present. Validation and management of new S3 content-checksum headers will follow in a subsequent change. Signed-off-by: Matt Benjamin <mbenjamin@redhat.com> squashed commits: * wip chunk meta parsing--seem to have first AWSv4ComplMulti::ChunkMeta::create_next sort of parsing * use constexpr sarlen(...) for static array lengths throughout rgw_auth_s3.cc * link AWSv4CompleMulti::ChunkMeta to its enclosing completer * capture original content-length header before AWSv4ComplMulti overwrites it * mostly extract the trailer * fix misordered content-length, experiment w/exbuf * save leftover bytes between calls to AWSv4ComplMulti::recv_chunk() * propagate data_offset_in_stream from AWSv4ComplMulti::recv_chunk() * clean up trailer section extract * trailer section cleanup and introduce extract_helper * unrolled checksum extract--fixup * fix sv_trailer end pos, and cleanup * add proplist interface to rgw::auth::Completer and AWSv4ComplMulti * spliterate trailers * check completer props * redefine prop_map to point into already-allocated trailer_vec * hax: thread a counter onto AWSv4ComplMulti recv_body() and recv_chunk path * fix apparent bug where due to reads less than chunk_size induce a final, zero-length read that was skipped before forcing recognition of the last chunk in the stream * check only for a trailing checksum named in x-amz-trailer * don't try to match signatures when no signature provided (because streaming unsigned) * oops, fix content_length decl * fix recognition of next chunk envelope in unsigned aws-chunk case * clean up AWSv4CompMulti flags and correctly detect aws unsigned chunked * rework checksum-trailer extraction and introduce AWSv4ComplMulti::calc_v4_trailing_signature * thread const struct req_state* into AWSv4ComplMulti * large cleanup of trailer parsing, no regression * fix trailer signature calculation--checks * correctly generate final chunk hmac * typo in comment * verify trailing signature when expected (using expected final chunk signature) * move trailer_vec back onto recv_body()'s stack * remove strange completer comment * remove last_frag (now points into parsing_buf) * remove implied dependency on content_length * move trailer recognition to AWSv4ComplMulti::complete() * remove now-unused is_last_chunk() predicate * remove unused ChunkMeta::completer * responses to review comments * when trailer is sig expected, fail (only) if none present or if it does not match calculated * remove stale parse_content_length(...) decl * remove now-unused AWSv4ComplMulti::content_length * fix extract_helper end search position as in mut_extract_helper * change "\n" reserve term in get_canon_amz_hdrs() part of the sum (review) and initialize length to 0 * remove debugging code Signed-off-by: Matt Benjamin <mbenjamin@redhat.com>
Diffstat (limited to 'src/rgw/rgw_rest.h')
-rw-r--r--src/rgw/rgw_rest.h19
1 files changed, 18 insertions, 1 deletions
diff --git a/src/rgw/rgw_rest.h b/src/rgw/rgw_rest.h
index 0b6cf62ed2c..8ee587e7c7b 100644
--- a/src/rgw/rgw_rest.h
+++ b/src/rgw/rgw_rest.h
@@ -8,6 +8,7 @@
#include <string_view>
#include <boost/container/flat_set.hpp>
#include "common/sstring.hh"
+#include "common/strtol.h"
#include "common/ceph_json.h"
#include "include/ceph_assert.h" /* needed because of common/ceph_json.h */
#include "rgw_op.h"
@@ -782,6 +783,23 @@ inline void dump_header_if_nonempty(req_state* s,
}
}
+static inline int64_t parse_content_length(const char *content_length)
+{
+ int64_t len = -1;
+
+ if (*content_length == '\0') {
+ len = 0;
+ } else {
+ std::string err;
+ len = strict_strtoll(content_length, 10, &err);
+ if (!err.empty()) {
+ len = -1;
+ }
+ }
+
+ return len;
+} /* parse_content_length */
+
inline std::string compute_domain_uri(const req_state *s) {
std::string uri = (!s->info.domain.empty()) ? s->info.domain :
[&s]() -> std::string {
@@ -799,7 +817,6 @@ inline std::string compute_domain_uri(const req_state *s) {
}
extern void dump_content_length(req_state *s, uint64_t len);
-extern int64_t parse_content_length(const char *content_length);
extern void dump_etag(req_state *s,
const std::string_view& etag,
bool quoted = false);