From: John Gibson Date: Sun, 24 Dec 2017 20:44:54 +0000 (-0500) Subject: rgw: Fixed several bugs in policies related to IP Addresses. X-Git-Tag: v12.2.3~207^2~5 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=9f7aeb4bd52bbdaef4ffd0127b38c3084e95a706;p=ceph.git rgw: Fixed several bugs in policies related to IP Addresses. Comparisons of two individual IP addresses caused an assertion error. The text conversion of IPv4 addresses was using raw byte values instead of the converted number. NotIpAddress condition now works with multiple values. http://tracker.ceph.com/issues/20991 Signed-off-by: John Gibson (cherry picked from commit ca21596c95aa3871d14ac9112840d3b1101a8635) --- diff --git a/src/rgw/rgw_iam_policy.cc b/src/rgw/rgw_iam_policy.cc index 745d28afffb7..435df059c8f4 100644 --- a/src/rgw/rgw_iam_policy.cc +++ b/src/rgw/rgw_iam_policy.cc @@ -932,7 +932,7 @@ ostream& operator <<(ostream& m, const MaskedIP& ip) { for (int j = 7; j >= 0; --j) { b |= (ip.addr[(i * 8) + j] << j); } - m << b; + m << (unsigned int) b; if (i != 0) { m << "."; } @@ -1039,8 +1039,24 @@ bool Condition::eval(const Environment& env) const { return shortible(std::equal_to(), as_network, s, vals); case TokenID::NotIpAddress: - return shortible(ceph::not_fn(std::equal_to()), as_network, s, - vals); + { + auto xc = as_network(s); + if (!xc) { + return false; + } + + for (const string& d : vals) { + auto xd = as_network(d); + if (!xd) { + continue; + } + + if (xc == xd) { + return false; + } + } + return true; + } #if 0 // Amazon Resource Names! (Does S3 need this?) @@ -1060,7 +1076,6 @@ optional Condition::as_network(const string& s) { } m.v6 = (s.find(':') == string::npos) ? false : true; - auto slash = s.find('/'); if (slash == string::npos) { m.prefix = m.v6 ? 128 : 32; @@ -1104,11 +1119,12 @@ optional Condition::as_network(const string& s) { m.addr |= Address(a.sin6_addr.s6_addr[14]) << 112; m.addr |= Address(a.sin6_addr.s6_addr[15]) << 120; } else { - struct sockaddr_in a; - if (inet_pton(AF_INET, p->c_str(), static_cast(&a.sin_addr)) != 1) { + struct in_addr a; + if (inet_pton(AF_INET, p->c_str(), static_cast(&a)) != 1) { return none; } - m.addr = ntohl(a.sin_addr.s_addr); + + m.addr = ntohl(a.s_addr); } return m; diff --git a/src/rgw/rgw_iam_policy.h b/src/rgw/rgw_iam_policy.h index 59117456e0cc..032840151a6f 100644 --- a/src/rgw/rgw_iam_policy.h +++ b/src/rgw/rgw_iam_policy.h @@ -250,8 +250,9 @@ std::ostream& operator <<(std::ostream& m, const MaskedIP& ip); string to_string(const MaskedIP& m); inline bool operator ==(const MaskedIP& l, const MaskedIP& r) { - auto shift = std::max((l.v6 ? 128 : 32) - l.prefix, - (r.v6 ? 128 : 32) - r.prefix); + auto shift = std::max((l.v6 ? 128 : 32) - ((int) l.prefix), + (r.v6 ? 128 : 32) - ((int) r.prefix)); + ceph_assert(shift >= 0); return (l.addr >> shift) == (r.addr >> shift); }