diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-07 18:45:59 +0000 |
commit | 19fcec84d8d7d21e796c7624e521b60d28ee21ed (patch) | |
tree | 42d26aa27d1e3f7c0b8bd3fd14e7d7082f5008dc /src/rgw/rgw_cors_s3.cc | |
parent | Initial commit. (diff) | |
download | ceph-upstream.tar.xz ceph-upstream.zip |
Adding upstream version 16.2.11+ds.upstream/16.2.11+dsupstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/rgw/rgw_cors_s3.cc')
-rw-r--r-- | src/rgw/rgw_cors_s3.cc | 245 |
1 files changed, 245 insertions, 0 deletions
diff --git a/src/rgw/rgw_cors_s3.cc b/src/rgw/rgw_cors_s3.cc new file mode 100644 index 000000000..0275156d2 --- /dev/null +++ b/src/rgw/rgw_cors_s3.cc @@ -0,0 +1,245 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab ft=cpp + +/* + * Ceph - scalable distributed file system + * + * Copyright (C) 2013 eNovance SAS <licensing@enovance.com> + * + * This is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License version 2.1, as published by the Free Software + * Foundation. See file COPYING. + * + */ + +#include <string.h> +#include <limits.h> + +#include <iostream> +#include <map> + +#include "include/types.h" + +#include "rgw_cors_s3.h" +#include "rgw_user.h" + +#define dout_context g_ceph_context +#define dout_subsys ceph_subsys_rgw + + +void RGWCORSRule_S3::to_xml(XMLFormatter& f) { + + f.open_object_section("CORSRule"); + /*ID if present*/ + if (id.length() > 0) { + f.dump_string("ID", id); + } + /*AllowedMethods*/ + if (allowed_methods & RGW_CORS_GET) + f.dump_string("AllowedMethod", "GET"); + if (allowed_methods & RGW_CORS_PUT) + f.dump_string("AllowedMethod", "PUT"); + if (allowed_methods & RGW_CORS_DELETE) + f.dump_string("AllowedMethod", "DELETE"); + if (allowed_methods & RGW_CORS_HEAD) + f.dump_string("AllowedMethod", "HEAD"); + if (allowed_methods & RGW_CORS_POST) + f.dump_string("AllowedMethod", "POST"); + if (allowed_methods & RGW_CORS_COPY) + f.dump_string("AllowedMethod", "COPY"); + /*AllowedOrigins*/ + for(set<string>::iterator it = allowed_origins.begin(); + it != allowed_origins.end(); + ++it) { + string host = *it; + f.dump_string("AllowedOrigin", host); + } + /*AllowedHeader*/ + for(set<string>::iterator it = allowed_hdrs.begin(); + it != allowed_hdrs.end(); ++it) { + f.dump_string("AllowedHeader", *it); + } + /*MaxAgeSeconds*/ + if (max_age != CORS_MAX_AGE_INVALID) { + f.dump_unsigned("MaxAgeSeconds", max_age); + } + /*ExposeHeader*/ + for(list<string>::iterator it = exposable_hdrs.begin(); + it != exposable_hdrs.end(); ++it) { + f.dump_string("ExposeHeader", *it); + } + f.close_section(); +} + +bool RGWCORSRule_S3::xml_end(const char *el) { + XMLObjIter iter = find("AllowedMethod"); + XMLObj *obj; + /*Check all the allowedmethods*/ + obj = iter.get_next(); + if (obj) { + for( ; obj; obj = iter.get_next()) { + const char *s = obj->get_data().c_str(); + ldpp_dout(dpp, 10) << "RGWCORSRule::xml_end, el : " << el << ", data : " << s << dendl; + if (strcasecmp(s, "GET") == 0) { + allowed_methods |= RGW_CORS_GET; + } else if (strcasecmp(s, "POST") == 0) { + allowed_methods |= RGW_CORS_POST; + } else if (strcasecmp(s, "DELETE") == 0) { + allowed_methods |= RGW_CORS_DELETE; + } else if (strcasecmp(s, "HEAD") == 0) { + allowed_methods |= RGW_CORS_HEAD; + } else if (strcasecmp(s, "PUT") == 0) { + allowed_methods |= RGW_CORS_PUT; + } else if (strcasecmp(s, "COPY") == 0) { + allowed_methods |= RGW_CORS_COPY; + } else { + return false; + } + } + } + /*Check the id's len, it should be less than 255*/ + XMLObj *xml_id = find_first("ID"); + if (xml_id != NULL) { + string data = xml_id->get_data(); + if (data.length() > 255) { + ldpp_dout(dpp, 0) << "RGWCORSRule has id of length greater than 255" << dendl; + return false; + } + ldpp_dout(dpp, 10) << "RGWCORRule id : " << data << dendl; + id = data; + } + /*Check if there is atleast one AllowedOrigin*/ + iter = find("AllowedOrigin"); + if (!(obj = iter.get_next())) { + ldpp_dout(dpp, 0) << "RGWCORSRule does not have even one AllowedOrigin" << dendl; + return false; + } + for( ; obj; obj = iter.get_next()) { + ldpp_dout(dpp, 10) << "RGWCORSRule - origin : " << obj->get_data() << dendl; + /*Just take the hostname*/ + string host = obj->get_data(); + if (validate_name_string(host) != 0) + return false; + allowed_origins.insert(allowed_origins.end(), host); + } + /*Check of max_age*/ + iter = find("MaxAgeSeconds"); + if ((obj = iter.get_next())) { + char *end = NULL; + + unsigned long long ull = strtoull(obj->get_data().c_str(), &end, 10); + if (*end != '\0') { + ldpp_dout(dpp, 0) << "RGWCORSRule's MaxAgeSeconds " << obj->get_data() << " is an invalid integer" << dendl; + return false; + } + if (ull >= 0x100000000ull) { + max_age = CORS_MAX_AGE_INVALID; + } else { + max_age = (uint32_t)ull; + } + ldpp_dout(dpp, 10) << "RGWCORSRule : max_age : " << max_age << dendl; + } + /*Check and update ExposeHeader*/ + iter = find("ExposeHeader"); + if ((obj = iter.get_next())) { + for(; obj; obj = iter.get_next()) { + ldpp_dout(dpp, 10) << "RGWCORSRule - exp_hdr : " << obj->get_data() << dendl; + exposable_hdrs.push_back(obj->get_data()); + } + } + /*Check and update AllowedHeader*/ + iter = find("AllowedHeader"); + if ((obj = iter.get_next())) { + for(; obj; obj = iter.get_next()) { + ldpp_dout(dpp, 10) << "RGWCORSRule - allowed_hdr : " << obj->get_data() << dendl; + string s = obj->get_data(); + if (validate_name_string(s) != 0) + return false; + allowed_hdrs.insert(allowed_hdrs.end(), s); + } + } + return true; +} + +void RGWCORSConfiguration_S3::to_xml(ostream& out) { + XMLFormatter f; + f.open_object_section_in_ns("CORSConfiguration", XMLNS_AWS_S3); + for(list<RGWCORSRule>::iterator it = rules.begin(); + it != rules.end(); ++it) { + (static_cast<RGWCORSRule_S3 &>(*it)).to_xml(f); + } + f.close_section(); + f.flush(out); +} + +bool RGWCORSConfiguration_S3::xml_end(const char *el) { + XMLObjIter iter = find("CORSRule"); + RGWCORSRule_S3 *obj; + if (!(obj = static_cast<RGWCORSRule_S3 *>(iter.get_next()))) { + ldpp_dout(dpp, 0) << "CORSConfiguration should have atleast one CORSRule" << dendl; + return false; + } + for(; obj; obj = static_cast<RGWCORSRule_S3 *>(iter.get_next())) { + rules.push_back(*obj); + } + return true; +} + +class CORSRuleID_S3 : public XMLObj { + public: + CORSRuleID_S3() {} + ~CORSRuleID_S3() override {} +}; + +class CORSRuleAllowedOrigin_S3 : public XMLObj { + public: + CORSRuleAllowedOrigin_S3() {} + ~CORSRuleAllowedOrigin_S3() override {} +}; + +class CORSRuleAllowedMethod_S3 : public XMLObj { + public: + CORSRuleAllowedMethod_S3() {} + ~CORSRuleAllowedMethod_S3() override {} +}; + +class CORSRuleAllowedHeader_S3 : public XMLObj { + public: + CORSRuleAllowedHeader_S3() {} + ~CORSRuleAllowedHeader_S3() override {} +}; + +class CORSRuleMaxAgeSeconds_S3 : public XMLObj { + public: + CORSRuleMaxAgeSeconds_S3() {} + ~CORSRuleMaxAgeSeconds_S3() override {} +}; + +class CORSRuleExposeHeader_S3 : public XMLObj { + public: + CORSRuleExposeHeader_S3() {} + ~CORSRuleExposeHeader_S3() override {} +}; + +XMLObj *RGWCORSXMLParser_S3::alloc_obj(const char *el) { + if (strcmp(el, "CORSConfiguration") == 0) { + return new RGWCORSConfiguration_S3(dpp); + } else if (strcmp(el, "CORSRule") == 0) { + return new RGWCORSRule_S3(dpp); + } else if (strcmp(el, "ID") == 0) { + return new CORSRuleID_S3; + } else if (strcmp(el, "AllowedOrigin") == 0) { + return new CORSRuleAllowedOrigin_S3; + } else if (strcmp(el, "AllowedMethod") == 0) { + return new CORSRuleAllowedMethod_S3; + } else if (strcmp(el, "AllowedHeader") == 0) { + return new CORSRuleAllowedHeader_S3; + } else if (strcmp(el, "MaxAgeSeconds") == 0) { + return new CORSRuleMaxAgeSeconds_S3; + } else if (strcmp(el, "ExposeHeader") == 0) { + return new CORSRuleExposeHeader_S3; + } + return NULL; +} + |