From: Jing Wenjun Date: Thu, 19 Jan 2017 13:26:17 +0000 (+0800) Subject: rgw: swift: The http referer should be parsed to compare in swift API X-Git-Tag: v11.2.1~166^2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=refs%2Fpull%2F13780%2Fhead;p=ceph.git rgw: swift: The http referer should be parsed to compare in swift API The http referer should be parsed to compare with the url set on the container read acl. If we set .r:www.example.com on container read acl, we should parse the hostname 'www.example.com' of the http referer like 'http://www.example.com' from the http request. Fixes: http://tracker.ceph.com/issues/18685 Signed-off-by: Jing Wenjun (cherry picked from commit 941dfad67174ae3ec517e76bf4028c50fb46fe82) --- diff --git a/src/rgw/rgw_acl.h b/src/rgw/rgw_acl.h index 7ca2ce89a0f55..ff44004f9add3 100644 --- a/src/rgw/rgw_acl.h +++ b/src/rgw/rgw_acl.h @@ -8,6 +8,9 @@ #include #include +#include +#include + #include "common/debug.h" #include "rgw_basic_types.h" @@ -214,20 +217,20 @@ struct ACLReferer { perm(perm) { } - bool is_match(std::string http_referer) const { - if (http_referer == url_spec) { - return true; + bool is_match(boost::string_ref http_referer) const { + const auto http_host = get_http_host(http_referer); + if (!http_host || http_host->length() < url_spec.length()) { + return false; } - if (http_referer.length() < url_spec.length()) { - return false; + if (http_host->compare(url_spec) == 0) { + return true; } if ('.' == url_spec[0]) { /* Wildcard support: a referer matches the spec when its last char are * perfectly equal to spec. */ - return !http_referer.compare(http_referer.length() - url_spec.length(), - url_spec.length(), url_spec); + return http_host->ends_with(url_spec); } return false; @@ -246,6 +249,26 @@ struct ACLReferer { DECODE_FINISH(bl); } void dump(Formatter *f) const; + +private: + boost::optional get_http_host(const boost::string_ref url) const { + size_t pos = url.find("://"); + if (pos == boost::string_ref::npos || url.starts_with("://") || + url.ends_with("://") || url.ends_with('@')) { + return boost::none; + } + boost::string_ref url_sub = url.substr(pos + strlen("://")); + pos = url_sub.find('@'); + if (pos != boost::string_ref::npos) { + url_sub = url_sub.substr(pos + 1); + } + pos = url_sub.find_first_of("/:"); + if (pos == boost::string_ref::npos) { + /* no port or path exists */ + return url_sub; + } + return url_sub.substr(0, pos); + } }; WRITE_CLASS_ENCODER(ACLReferer)