]> git.proxmox.com Git - ceph.git/blame - ceph/src/test/rgw/test_rgw_iam_policy.cc
update sources to 12.2.7
[ceph.git] / ceph / src / test / rgw / test_rgw_iam_policy.cc
CommitLineData
31f18b77
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3/*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2015 Red Hat
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15#include <string>
16
17#include <boost/intrusive_ptr.hpp>
18#include <boost/optional.hpp>
19
20#include <gtest/gtest.h>
21
b32b8144 22#include "include/stringify.h"
31f18b77
FG
23#include "common/code_environment.h"
24#include "common/ceph_context.h"
25#include "global/global_init.h"
26#include "rgw/rgw_auth.h"
27#include "rgw/rgw_iam_policy.h"
b32b8144 28#include "rgw/rgw_op.h"
31f18b77
FG
29
30
31using std::string;
32using std::vector;
33
34using boost::container::flat_set;
35using boost::intrusive_ptr;
36using boost::make_optional;
37using boost::none;
38using boost::optional;
39
40using rgw::auth::Identity;
41using rgw::auth::Principal;
42
43using rgw::IAM::ARN;
44using rgw::IAM::Effect;
45using rgw::IAM::Environment;
46using rgw::IAM::Partition;
47using rgw::IAM::Policy;
48using rgw::IAM::s3All;
49using rgw::IAM::s3Count;
50using rgw::IAM::s3GetAccelerateConfiguration;
51using rgw::IAM::s3GetBucketAcl;
52using rgw::IAM::s3GetBucketCORS;
53using rgw::IAM::s3GetBucketLocation;
54using rgw::IAM::s3GetBucketLogging;
55using rgw::IAM::s3GetBucketNotification;
56using rgw::IAM::s3GetBucketPolicy;
57using rgw::IAM::s3GetBucketRequestPayment;
58using rgw::IAM::s3GetBucketTagging;
59using rgw::IAM::s3GetBucketVersioning;
60using rgw::IAM::s3GetBucketWebsite;
61using rgw::IAM::s3GetLifecycleConfiguration;
62using rgw::IAM::s3GetObject;
63using rgw::IAM::s3GetObjectAcl;
64using rgw::IAM::s3GetObjectVersionAcl;
65using rgw::IAM::s3GetObjectTorrent;
d2e6a577 66using rgw::IAM::s3GetObjectTagging;
31f18b77 67using rgw::IAM::s3GetObjectVersion;
d2e6a577 68using rgw::IAM::s3GetObjectVersionTagging;
31f18b77
FG
69using rgw::IAM::s3GetObjectVersionTorrent;
70using rgw::IAM::s3GetReplicationConfiguration;
71using rgw::IAM::s3ListAllMyBuckets;
72using rgw::IAM::s3ListBucket;
73using rgw::IAM::s3ListBucket;
28e407b8 74using rgw::IAM::s3ListBucketMultipartUploads;
31f18b77
FG
75using rgw::IAM::s3ListBucketVersions;
76using rgw::IAM::s3ListMultipartUploadParts;
77using rgw::IAM::s3None;
78using rgw::IAM::s3PutBucketAcl;
79using rgw::IAM::s3PutBucketPolicy;
80using rgw::IAM::Service;
81using rgw::IAM::TokenID;
82using rgw::IAM::Version;
83
84class FakeIdentity : public Identity {
85 const Principal id;
86public:
87
88 FakeIdentity(Principal&& id) : id(std::move(id)) {}
89 uint32_t get_perms_from_aclspec(const aclspec_t& aclspec) const override {
90 abort();
91 return 0;
92 };
93
94 bool is_admin_of(const rgw_user& uid) const override {
95 abort();
96 return false;
97 }
98
99 bool is_owner_of(const rgw_user& uid) const override {
100 abort();
101 return false;
102 }
103
104 virtual uint32_t get_perm_mask() const override {
105 abort();
106 return 0;
107 }
108
109 void to_str(std::ostream& out) const override {
b32b8144 110 out << id;
31f18b77
FG
111 }
112
113 bool is_identity(const flat_set<Principal>& ids) const override {
b32b8144
FG
114 if (id.is_wildcard() && (!ids.empty())) {
115 return true;
116 }
117 return ids.find(id) != ids.end() || ids.find(Principal::wildcard()) != ids.end();
31f18b77
FG
118 }
119};
120
121class PolicyTest : public ::testing::Test {
122protected:
123 intrusive_ptr<CephContext> cct;
124 static const string arbitrary_tenant;
125 static string example1;
126 static string example2;
127 static string example3;
128public:
129 PolicyTest() {
130 cct = new CephContext(CEPH_ENTITY_TYPE_CLIENT);
131 }
132};
133
134TEST_F(PolicyTest, Parse1) {
135 optional<Policy> p;
136
137 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
138 bufferlist::static_from_string(example1)));
139 ASSERT_TRUE(p);
140
141 EXPECT_EQ(p->text, example1);
142 EXPECT_EQ(p->version, Version::v2012_10_17);
143 EXPECT_FALSE(p->id);
144 EXPECT_FALSE(p->statements[0].sid);
145 EXPECT_FALSE(p->statements.empty());
146 EXPECT_EQ(p->statements.size(), 1U);
147 EXPECT_TRUE(p->statements[0].princ.empty());
148 EXPECT_TRUE(p->statements[0].noprinc.empty());
149 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
150 EXPECT_EQ(p->statements[0].action, s3ListBucket);
151 EXPECT_EQ(p->statements[0].notaction, s3None);
152 ASSERT_FALSE(p->statements[0].resource.empty());
153 ASSERT_EQ(p->statements[0].resource.size(), 1U);
154 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::aws);
155 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::s3);
156 EXPECT_TRUE(p->statements[0].resource.begin()->region.empty());
157 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
158 EXPECT_EQ(p->statements[0].resource.begin()->resource, "example_bucket");
159 EXPECT_TRUE(p->statements[0].notresource.empty());
160 EXPECT_TRUE(p->statements[0].conditions.empty());
161}
162
163TEST_F(PolicyTest, Eval1) {
164 auto p = Policy(cct.get(), arbitrary_tenant,
165 bufferlist::static_from_string(example1));
166 Environment e;
167
168 EXPECT_EQ(p.eval(e, none, s3ListBucket,
169 ARN(Partition::aws, Service::s3,
170 "", arbitrary_tenant, "example_bucket")),
171 Effect::Allow);
172
173 EXPECT_EQ(p.eval(e, none, s3PutBucketAcl,
174 ARN(Partition::aws, Service::s3,
175 "", arbitrary_tenant, "example_bucket")),
176 Effect::Pass);
177
178 EXPECT_EQ(p.eval(e, none, s3ListBucket,
179 ARN(Partition::aws, Service::s3,
180 "", arbitrary_tenant, "erroneous_bucket")),
181 Effect::Pass);
182
183}
184
185TEST_F(PolicyTest, Parse2) {
186 optional<Policy> p;
187
188 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
189 bufferlist::static_from_string(example2)));
190 ASSERT_TRUE(p);
191
192 EXPECT_EQ(p->text, example2);
193 EXPECT_EQ(p->version, Version::v2012_10_17);
194 EXPECT_EQ(*p->id, "S3-Account-Permissions");
195 ASSERT_FALSE(p->statements.empty());
196 EXPECT_EQ(p->statements.size(), 1U);
197 EXPECT_EQ(*p->statements[0].sid, "1");
198 EXPECT_FALSE(p->statements[0].princ.empty());
199 EXPECT_EQ(p->statements[0].princ.size(), 1U);
200 EXPECT_EQ(*p->statements[0].princ.begin(),
201 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
202 EXPECT_TRUE(p->statements[0].noprinc.empty());
203 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
204 EXPECT_EQ(p->statements[0].action, s3All);
205 EXPECT_EQ(p->statements[0].notaction, s3None);
206 ASSERT_FALSE(p->statements[0].resource.empty());
207 ASSERT_EQ(p->statements[0].resource.size(), 2U);
208 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::aws);
209 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::s3);
210 EXPECT_TRUE(p->statements[0].resource.begin()->region.empty());
211 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
212 EXPECT_EQ(p->statements[0].resource.begin()->resource, "mybucket");
213 EXPECT_EQ((p->statements[0].resource.begin() + 1)->partition,
214 Partition::aws);
215 EXPECT_EQ((p->statements[0].resource.begin() + 1)->service,
216 Service::s3);
217 EXPECT_TRUE((p->statements[0].resource.begin() + 1)->region.empty());
218 EXPECT_EQ((p->statements[0].resource.begin() + 1)->account,
219 arbitrary_tenant);
220 EXPECT_EQ((p->statements[0].resource.begin() + 1)->resource, "mybucket/*");
221 EXPECT_TRUE(p->statements[0].notresource.empty());
222 EXPECT_TRUE(p->statements[0].conditions.empty());
223}
224
225TEST_F(PolicyTest, Eval2) {
226 auto p = Policy(cct.get(), arbitrary_tenant,
227 bufferlist::static_from_string(example2));
228 Environment e;
229
230 auto trueacct = FakeIdentity(
231 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
232
233 auto notacct = FakeIdentity(
234 Principal::tenant("some-other-account"));
235 for (auto i = 0ULL; i < s3Count; ++i) {
236 EXPECT_EQ(p.eval(e, trueacct, 1ULL << i,
237 ARN(Partition::aws, Service::s3,
238 "", arbitrary_tenant, "mybucket")),
239 Effect::Allow);
240 EXPECT_EQ(p.eval(e, trueacct, 1ULL << i,
241 ARN(Partition::aws, Service::s3,
242 "", arbitrary_tenant, "mybucket/myobject")),
243 Effect::Allow);
244
245 EXPECT_EQ(p.eval(e, notacct, 1ULL << i,
246 ARN(Partition::aws, Service::s3,
247 "", arbitrary_tenant, "mybucket")),
248 Effect::Pass);
249 EXPECT_EQ(p.eval(e, notacct, 1ULL << i,
250 ARN(Partition::aws, Service::s3,
251 "", arbitrary_tenant, "mybucket/myobject")),
252 Effect::Pass);
253
254 EXPECT_EQ(p.eval(e, trueacct, 1ULL << i,
255 ARN(Partition::aws, Service::s3,
256 "", arbitrary_tenant, "notyourbucket")),
257 Effect::Pass);
258 EXPECT_EQ(p.eval(e, trueacct, 1ULL << i,
259 ARN(Partition::aws, Service::s3,
260 "", arbitrary_tenant, "notyourbucket/notyourobject")),
261 Effect::Pass);
262
263 }
264}
265
266TEST_F(PolicyTest, Parse3) {
267 optional<Policy> p;
268
269 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
270 bufferlist::static_from_string(example3)));
271 ASSERT_TRUE(p);
272
273 EXPECT_EQ(p->text, example3);
274 EXPECT_EQ(p->version, Version::v2012_10_17);
275 EXPECT_FALSE(p->id);
276 ASSERT_FALSE(p->statements.empty());
277 EXPECT_EQ(p->statements.size(), 3U);
278
279 EXPECT_EQ(*p->statements[0].sid, "FirstStatement");
280 EXPECT_TRUE(p->statements[0].princ.empty());
281 EXPECT_TRUE(p->statements[0].noprinc.empty());
282 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
283 EXPECT_EQ(p->statements[0].action, s3PutBucketPolicy);
284 EXPECT_EQ(p->statements[0].notaction, s3None);
285 ASSERT_FALSE(p->statements[0].resource.empty());
286 ASSERT_EQ(p->statements[0].resource.size(), 1U);
287 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::wildcard);
288 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::wildcard);
289 EXPECT_EQ(p->statements[0].resource.begin()->region, "*");
290 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
291 EXPECT_EQ(p->statements[0].resource.begin()->resource, "*");
292 EXPECT_TRUE(p->statements[0].notresource.empty());
293 EXPECT_TRUE(p->statements[0].conditions.empty());
294
295 EXPECT_EQ(*p->statements[1].sid, "SecondStatement");
296 EXPECT_TRUE(p->statements[1].princ.empty());
297 EXPECT_TRUE(p->statements[1].noprinc.empty());
298 EXPECT_EQ(p->statements[1].effect, Effect::Allow);
299 EXPECT_EQ(p->statements[1].action, s3ListAllMyBuckets);
300 EXPECT_EQ(p->statements[1].notaction, s3None);
301 ASSERT_FALSE(p->statements[1].resource.empty());
302 ASSERT_EQ(p->statements[1].resource.size(), 1U);
303 EXPECT_EQ(p->statements[1].resource.begin()->partition, Partition::wildcard);
304 EXPECT_EQ(p->statements[1].resource.begin()->service, Service::wildcard);
305 EXPECT_EQ(p->statements[1].resource.begin()->region, "*");
306 EXPECT_EQ(p->statements[1].resource.begin()->account, arbitrary_tenant);
307 EXPECT_EQ(p->statements[1].resource.begin()->resource, "*");
308 EXPECT_TRUE(p->statements[1].notresource.empty());
309 EXPECT_TRUE(p->statements[1].conditions.empty());
310
311 EXPECT_EQ(*p->statements[2].sid, "ThirdStatement");
312 EXPECT_TRUE(p->statements[2].princ.empty());
313 EXPECT_TRUE(p->statements[2].noprinc.empty());
314 EXPECT_EQ(p->statements[2].effect, Effect::Allow);
315 EXPECT_EQ(p->statements[2].action, (s3ListMultipartUploadParts |
316 s3ListBucket | s3ListBucketVersions |
317 s3ListAllMyBuckets |
28e407b8 318 s3ListBucketMultipartUploads |
31f18b77
FG
319 s3GetObject | s3GetObjectVersion |
320 s3GetObjectAcl | s3GetObjectVersionAcl |
321 s3GetObjectTorrent |
322 s3GetObjectVersionTorrent |
323 s3GetAccelerateConfiguration |
324 s3GetBucketAcl | s3GetBucketCORS |
325 s3GetBucketVersioning |
326 s3GetBucketRequestPayment |
327 s3GetBucketLocation |
328 s3GetBucketPolicy |
329 s3GetBucketNotification |
330 s3GetBucketLogging |
331 s3GetBucketTagging |
332 s3GetBucketWebsite |
333 s3GetLifecycleConfiguration |
d2e6a577
FG
334 s3GetReplicationConfiguration |
335 s3GetObjectTagging |
336 s3GetObjectVersionTagging));
31f18b77
FG
337 EXPECT_EQ(p->statements[2].notaction, s3None);
338 ASSERT_FALSE(p->statements[2].resource.empty());
339 ASSERT_EQ(p->statements[2].resource.size(), 2U);
340 EXPECT_EQ(p->statements[2].resource.begin()->partition, Partition::aws);
341 EXPECT_EQ(p->statements[2].resource.begin()->service, Service::s3);
342 EXPECT_TRUE(p->statements[2].resource.begin()->region.empty());
343 EXPECT_EQ(p->statements[2].resource.begin()->account, arbitrary_tenant);
344 EXPECT_EQ(p->statements[2].resource.begin()->resource, "confidential-data");
345 EXPECT_EQ((p->statements[2].resource.begin() + 1)->partition,
346 Partition::aws);
347 EXPECT_EQ((p->statements[2].resource.begin() + 1)->service, Service::s3);
348 EXPECT_TRUE((p->statements[2].resource.begin() + 1)->region.empty());
349 EXPECT_EQ((p->statements[2].resource.begin() + 1)->account,
350 arbitrary_tenant);
351 EXPECT_EQ((p->statements[2].resource.begin() + 1)->resource,
352 "confidential-data/*");
353 EXPECT_TRUE(p->statements[2].notresource.empty());
354 ASSERT_FALSE(p->statements[2].conditions.empty());
355 ASSERT_EQ(p->statements[2].conditions.size(), 1U);
356 EXPECT_EQ(p->statements[2].conditions[0].op, TokenID::Bool);
357 EXPECT_EQ(p->statements[2].conditions[0].key, "aws:MultiFactorAuthPresent");
358 EXPECT_FALSE(p->statements[2].conditions[0].ifexists);
359 ASSERT_FALSE(p->statements[2].conditions[0].vals.empty());
360 EXPECT_EQ(p->statements[2].conditions[0].vals.size(), 1U);
361 EXPECT_EQ(p->statements[2].conditions[0].vals[0], "true");
362}
363
364TEST_F(PolicyTest, Eval3) {
365 auto p = Policy(cct.get(), arbitrary_tenant,
366 bufferlist::static_from_string(example3));
367 Environment em;
368 Environment tr = { { "aws:MultiFactorAuthPresent", "true" } };
369 Environment fa = { { "aws:MultiFactorAuthPresent", "false" } };
370
371 auto s3allow = (s3ListMultipartUploadParts | s3ListBucket |
372 s3ListBucketVersions | s3ListAllMyBuckets |
28e407b8 373 s3ListBucketMultipartUploads | s3GetObject |
31f18b77
FG
374 s3GetObjectVersion | s3GetObjectAcl | s3GetObjectVersionAcl |
375 s3GetObjectTorrent | s3GetObjectVersionTorrent |
376 s3GetAccelerateConfiguration | s3GetBucketAcl |
377 s3GetBucketCORS | s3GetBucketVersioning |
378 s3GetBucketRequestPayment | s3GetBucketLocation |
379 s3GetBucketPolicy | s3GetBucketNotification |
380 s3GetBucketLogging | s3GetBucketTagging |
381 s3GetBucketWebsite | s3GetLifecycleConfiguration |
d2e6a577
FG
382 s3GetReplicationConfiguration |
383 s3GetObjectTagging | s3GetObjectVersionTagging);
31f18b77
FG
384
385 EXPECT_EQ(p.eval(em, none, s3PutBucketPolicy,
386 ARN(Partition::aws, Service::s3,
387 "", arbitrary_tenant, "mybucket")),
388 Effect::Allow);
389
390 EXPECT_EQ(p.eval(em, none, s3PutBucketPolicy,
391 ARN(Partition::aws, Service::s3,
392 "", arbitrary_tenant, "mybucket")),
393 Effect::Allow);
394
395
396 for (auto i = 0ULL; i < s3Count; ++i) {
397 auto op = 1ULL << i;
398 if ((op == s3ListAllMyBuckets) || (op == s3PutBucketPolicy)) {
399 continue;
400 }
401
402 EXPECT_EQ(p.eval(em, none, op,
403 ARN(Partition::aws, Service::s3,
404 "", arbitrary_tenant, "confidential-data")),
405 Effect::Pass);
406 EXPECT_EQ(p.eval(tr, none, op,
407 ARN(Partition::aws, Service::s3,
408 "", arbitrary_tenant, "confidential-data")),
409 op & s3allow ? Effect::Allow : Effect::Pass);
410 EXPECT_EQ(p.eval(fa, none, op,
411 ARN(Partition::aws, Service::s3,
412 "", arbitrary_tenant, "confidential-data")),
413 Effect::Pass);
414
415 EXPECT_EQ(p.eval(em, none, op,
416 ARN(Partition::aws, Service::s3,
417 "", arbitrary_tenant, "confidential-data/moo")),
418 Effect::Pass);
419 EXPECT_EQ(p.eval(tr, none, op,
420 ARN(Partition::aws, Service::s3,
421 "", arbitrary_tenant, "confidential-data/moo")),
422 op & s3allow ? Effect::Allow : Effect::Pass);
423 EXPECT_EQ(p.eval(fa, none, op,
424 ARN(Partition::aws, Service::s3,
425 "", arbitrary_tenant, "confidential-data/moo")),
426 Effect::Pass);
427
428 EXPECT_EQ(p.eval(em, none, op,
429 ARN(Partition::aws, Service::s3,
430 "", arbitrary_tenant, "really-confidential-data")),
431 Effect::Pass);
432 EXPECT_EQ(p.eval(tr, none, op,
433 ARN(Partition::aws, Service::s3,
434 "", arbitrary_tenant, "really-confidential-data")),
435 Effect::Pass);
436 EXPECT_EQ(p.eval(fa, none, op,
437 ARN(Partition::aws, Service::s3,
438 "", arbitrary_tenant, "really-confidential-data")),
439 Effect::Pass);
440
441 EXPECT_EQ(p.eval(em, none, op,
442 ARN(Partition::aws, Service::s3,
443 "", arbitrary_tenant,
444 "really-confidential-data/moo")), Effect::Pass);
445 EXPECT_EQ(p.eval(tr, none, op,
446 ARN(Partition::aws, Service::s3,
447 "", arbitrary_tenant,
448 "really-confidential-data/moo")), Effect::Pass);
449 EXPECT_EQ(p.eval(fa, none, op,
450 ARN(Partition::aws, Service::s3,
451 "", arbitrary_tenant,
452 "really-confidential-data/moo")), Effect::Pass);
453
454 }
455}
456
457const string PolicyTest::arbitrary_tenant = "arbitrary_tenant";
458string PolicyTest::example1 = R"(
459{
460 "Version": "2012-10-17",
461 "Statement": {
462 "Effect": "Allow",
463 "Action": "s3:ListBucket",
464 "Resource": "arn:aws:s3:::example_bucket"
465 }
466}
467)";
468
469string PolicyTest::example2 = R"(
470{
471 "Version": "2012-10-17",
472 "Id": "S3-Account-Permissions",
473 "Statement": [{
474 "Sid": "1",
475 "Effect": "Allow",
476 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
477 "Action": "s3:*",
478 "Resource": [
479 "arn:aws:s3:::mybucket",
480 "arn:aws:s3:::mybucket/*"
481 ]
482 }]
483}
484)";
485
486string PolicyTest::example3 = R"(
487{
488 "Version": "2012-10-17",
489 "Statement": [
490 {
491 "Sid": "FirstStatement",
492 "Effect": "Allow",
493 "Action": ["s3:PutBucketPolicy"],
494 "Resource": "*"
495 },
496 {
497 "Sid": "SecondStatement",
498 "Effect": "Allow",
499 "Action": "s3:ListAllMyBuckets",
500 "Resource": "*"
501 },
502 {
503 "Sid": "ThirdStatement",
504 "Effect": "Allow",
505 "Action": [
506 "s3:List*",
507 "s3:Get*"
508 ],
509 "Resource": [
510 "arn:aws:s3:::confidential-data",
511 "arn:aws:s3:::confidential-data/*"
512 ],
513 "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
514 }
515 ]
516}
517)";
d2e6a577 518
b32b8144
FG
519class IPPolicyTest : public ::testing::Test {
520protected:
521 intrusive_ptr<CephContext> cct;
522 static const string arbitrary_tenant;
523 static string ip_address_allow_example;
524 static string ip_address_deny_example;
525 static string ip_address_full_example;
526 // 192.168.1.0/24
527 const rgw::IAM::MaskedIP allowedIPv4Range = { false, rgw::IAM::Address("11000000101010000000000100000000"), 24 };
528 // 192.168.1.1/32
529 const rgw::IAM::MaskedIP blacklistedIPv4 = { false, rgw::IAM::Address("11000000101010000000000100000001"), 32 };
530 // 2001:db8:85a3:0:0:8a2e:370:7334/128
531 const rgw::IAM::MaskedIP allowedIPv6 = { true, rgw::IAM::Address("00100000000000010000110110111000100001011010001100000000000000000000000000000000100010100010111000000011011100000111001100110100"), 128 };
532 // ::1
533 const rgw::IAM::MaskedIP blacklistedIPv6 = { true, rgw::IAM::Address(1), 128 };
534 // 2001:db8:85a3:0:0:8a2e:370:7330/124
535 const rgw::IAM::MaskedIP allowedIPv6Range = { true, rgw::IAM::Address("00100000000000010000110110111000100001011010001100000000000000000000000000000000100010100010111000000011011100000111001100110000"), 124 };
536public:
537 IPPolicyTest() {
538 cct = new CephContext(CEPH_ENTITY_TYPE_CLIENT);
539 }
540};
541const string IPPolicyTest::arbitrary_tenant = "arbitrary_tenant";
542
543TEST_F(IPPolicyTest, MaskedIPOperations) {
544 EXPECT_EQ(stringify(allowedIPv4Range), "192.168.1.0/24");
545 EXPECT_EQ(stringify(blacklistedIPv4), "192.168.1.1/32");
546 EXPECT_EQ(stringify(allowedIPv6), "2001:db8:85a3:0:0:8a2e:370:7334/128");
547 EXPECT_EQ(stringify(allowedIPv6Range), "2001:db8:85a3:0:0:8a2e:370:7330/124");
548 EXPECT_EQ(stringify(blacklistedIPv6), "0:0:0:0:0:0:0:1/128");
549 EXPECT_EQ(allowedIPv4Range, blacklistedIPv4);
550 EXPECT_EQ(allowedIPv6Range, allowedIPv6);
551}
552
553TEST_F(IPPolicyTest, asNetworkIPv4Range) {
554 auto actualIPv4Range = rgw::IAM::Condition::as_network("192.168.1.0/24");
555 ASSERT_TRUE(actualIPv4Range.is_initialized());
556 EXPECT_EQ(*actualIPv4Range, allowedIPv4Range);
557}
558
559TEST_F(IPPolicyTest, asNetworkIPv4) {
560 auto actualIPv4 = rgw::IAM::Condition::as_network("192.168.1.1");
561 ASSERT_TRUE(actualIPv4.is_initialized());
562 EXPECT_EQ(*actualIPv4, blacklistedIPv4);
563}
564
565TEST_F(IPPolicyTest, asNetworkIPv6Range) {
566 auto actualIPv6Range = rgw::IAM::Condition::as_network("2001:db8:85a3:0:0:8a2e:370:7330/124");
567 ASSERT_TRUE(actualIPv6Range.is_initialized());
568 EXPECT_EQ(*actualIPv6Range, allowedIPv6Range);
569}
570
571TEST_F(IPPolicyTest, asNetworkIPv6) {
572 auto actualIPv6 = rgw::IAM::Condition::as_network("2001:db8:85a3:0:0:8a2e:370:7334");
573 ASSERT_TRUE(actualIPv6.is_initialized());
574 EXPECT_EQ(*actualIPv6, allowedIPv6);
575}
576
577TEST_F(IPPolicyTest, asNetworkInvalid) {
578 EXPECT_FALSE(rgw::IAM::Condition::as_network(""));
579 EXPECT_FALSE(rgw::IAM::Condition::as_network("192.168.1.1/33"));
580 EXPECT_FALSE(rgw::IAM::Condition::as_network("2001:db8:85a3:0:0:8a2e:370:7334/129"));
581 EXPECT_FALSE(rgw::IAM::Condition::as_network("192.168.1.1:"));
582 EXPECT_FALSE(rgw::IAM::Condition::as_network("1.2.3.10000"));
583}
584
585TEST_F(IPPolicyTest, IPEnvironment) {
586 // Unfortunately RGWCivetWeb is too tightly tied to civetweb to test RGWCivetWeb::init_env.
587 RGWEnv rgw_env;
588 RGWUserInfo user;
589 RGWRados rgw_rados;
590 rgw_env.set("REMOTE_ADDR", "192.168.1.1");
591 rgw_env.set("HTTP_HOST", "1.2.3.4");
592 req_state rgw_req_state(cct.get(), &rgw_env, &user);
593 Environment iam_env = rgw_build_iam_environment(&rgw_rados, &rgw_req_state);
594 auto ip = iam_env.find("aws:SourceIp");
595 ASSERT_NE(ip, iam_env.end());
596 EXPECT_EQ(ip->second, "192.168.1.1");
597
598 ASSERT_EQ(cct.get()->_conf->set_val("rgw_remote_addr_param", "SOME_VAR"), 0);
599 EXPECT_EQ(cct.get()->_conf->rgw_remote_addr_param, "SOME_VAR");
600 iam_env = rgw_build_iam_environment(&rgw_rados, &rgw_req_state);
601 ip = iam_env.find("aws:SourceIp");
602 EXPECT_EQ(ip, iam_env.end());
603
604 rgw_env.set("SOME_VAR", "192.168.1.2");
605 iam_env = rgw_build_iam_environment(&rgw_rados, &rgw_req_state);
606 ip = iam_env.find("aws:SourceIp");
607 ASSERT_NE(ip, iam_env.end());
608 EXPECT_EQ(ip->second, "192.168.1.2");
609
610 ASSERT_EQ(cct.get()->_conf->set_val("rgw_remote_addr_param", "HTTP_X_FORWARDED_FOR"), 0);
611 rgw_env.set("HTTP_X_FORWARDED_FOR", "192.168.1.3");
612 iam_env = rgw_build_iam_environment(&rgw_rados, &rgw_req_state);
613 ip = iam_env.find("aws:SourceIp");
614 ASSERT_NE(ip, iam_env.end());
615 EXPECT_EQ(ip->second, "192.168.1.3");
616
617 rgw_env.set("HTTP_X_FORWARDED_FOR", "192.168.1.4, 4.3.2.1, 2001:db8:85a3:8d3:1319:8a2e:370:7348");
618 iam_env = rgw_build_iam_environment(&rgw_rados, &rgw_req_state);
619 ip = iam_env.find("aws:SourceIp");
620 ASSERT_NE(ip, iam_env.end());
621 EXPECT_EQ(ip->second, "192.168.1.4");
622}
623
624TEST_F(IPPolicyTest, ParseIPAddress) {
625 optional<Policy> p;
626
627 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
628 bufferlist::static_from_string(ip_address_full_example)));
629 ASSERT_TRUE(p);
630
631 EXPECT_EQ(p->text, ip_address_full_example);
632 EXPECT_EQ(p->version, Version::v2012_10_17);
633 EXPECT_EQ(*p->id, "S3IPPolicyTest");
634 EXPECT_FALSE(p->statements.empty());
635 EXPECT_EQ(p->statements.size(), 1U);
636 EXPECT_EQ(*p->statements[0].sid, "IPAllow");
637 EXPECT_FALSE(p->statements[0].princ.empty());
638 EXPECT_EQ(p->statements[0].princ.size(), 1U);
639 EXPECT_EQ(*p->statements[0].princ.begin(),
640 Principal::wildcard());
641 EXPECT_TRUE(p->statements[0].noprinc.empty());
642 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
643 EXPECT_EQ(p->statements[0].action, s3ListBucket);
644 EXPECT_EQ(p->statements[0].notaction, s3None);
645 ASSERT_FALSE(p->statements[0].resource.empty());
646 ASSERT_EQ(p->statements[0].resource.size(), 2U);
647 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::aws);
648 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::s3);
649 EXPECT_TRUE(p->statements[0].resource.begin()->region.empty());
650 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
651 EXPECT_EQ(p->statements[0].resource.begin()->resource, "example_bucket");
652 EXPECT_EQ((p->statements[0].resource.begin() + 1)->resource, "example_bucket/*");
653 EXPECT_TRUE(p->statements[0].notresource.empty());
654 ASSERT_FALSE(p->statements[0].conditions.empty());
655 ASSERT_EQ(p->statements[0].conditions.size(), 2U);
656 EXPECT_EQ(p->statements[0].conditions[0].op, TokenID::IpAddress);
657 EXPECT_EQ(p->statements[0].conditions[0].key, "aws:SourceIp");
658 ASSERT_FALSE(p->statements[0].conditions[0].vals.empty());
659 EXPECT_EQ(p->statements[0].conditions[0].vals.size(), 2U);
660 EXPECT_EQ(p->statements[0].conditions[0].vals[0], "192.168.1.0/24");
661 EXPECT_EQ(p->statements[0].conditions[0].vals[1], "::1");
662 optional<rgw::IAM::MaskedIP> convertedIPv4 = rgw::IAM::Condition::as_network(p->statements[0].conditions[0].vals[0]);
663 EXPECT_TRUE(convertedIPv4.is_initialized());
664 if (convertedIPv4.is_initialized()) {
665 EXPECT_EQ(*convertedIPv4, allowedIPv4Range);
666 }
667
668 EXPECT_EQ(p->statements[0].conditions[1].op, TokenID::NotIpAddress);
669 EXPECT_EQ(p->statements[0].conditions[1].key, "aws:SourceIp");
670 ASSERT_FALSE(p->statements[0].conditions[1].vals.empty());
671 EXPECT_EQ(p->statements[0].conditions[1].vals.size(), 2U);
672 EXPECT_EQ(p->statements[0].conditions[1].vals[0], "192.168.1.1/32");
673 EXPECT_EQ(p->statements[0].conditions[1].vals[1], "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
674 optional<rgw::IAM::MaskedIP> convertedIPv6 = rgw::IAM::Condition::as_network(p->statements[0].conditions[1].vals[1]);
675 EXPECT_TRUE(convertedIPv6.is_initialized());
676 if (convertedIPv6.is_initialized()) {
677 EXPECT_EQ(*convertedIPv6, allowedIPv6);
678 }
679}
680
681TEST_F(IPPolicyTest, EvalIPAddress) {
682 auto allowp = Policy(cct.get(), arbitrary_tenant,
683 bufferlist::static_from_string(ip_address_allow_example));
684 auto denyp = Policy(cct.get(), arbitrary_tenant,
685 bufferlist::static_from_string(ip_address_deny_example));
686 auto fullp = Policy(cct.get(), arbitrary_tenant,
687 bufferlist::static_from_string(ip_address_full_example));
688 Environment e;
689 Environment allowedIP, blacklistedIP, allowedIPv6, blacklistedIPv6;
690 allowedIP["aws:SourceIp"] = "192.168.1.2";
691 allowedIPv6["aws:SourceIp"] = "::1";
692 blacklistedIP["aws:SourceIp"] = "192.168.1.1";
693 blacklistedIPv6["aws:SourceIp"] = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
694
695 auto trueacct = FakeIdentity(
696 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
697 // Without an IP address in the environment then evaluation will always pass
698 EXPECT_EQ(allowp.eval(e, trueacct, s3ListBucket,
699 ARN(Partition::aws, Service::s3,
700 "", arbitrary_tenant, "example_bucket")),
701 Effect::Pass);
702 EXPECT_EQ(fullp.eval(e, trueacct, s3ListBucket,
703 ARN(Partition::aws, Service::s3,
704 "", arbitrary_tenant, "example_bucket/myobject")),
705 Effect::Pass);
706
707 EXPECT_EQ(allowp.eval(allowedIP, trueacct, s3ListBucket,
708 ARN(Partition::aws, Service::s3,
709 "", arbitrary_tenant, "example_bucket")),
710 Effect::Allow);
711 EXPECT_EQ(allowp.eval(blacklistedIPv6, trueacct, s3ListBucket,
712 ARN(Partition::aws, Service::s3,
713 "", arbitrary_tenant, "example_bucket")),
714 Effect::Pass);
715
716
717 EXPECT_EQ(denyp.eval(allowedIP, trueacct, s3ListBucket,
718 ARN(Partition::aws, Service::s3,
719 "", arbitrary_tenant, "example_bucket")),
720 Effect::Deny);
721 EXPECT_EQ(denyp.eval(allowedIP, trueacct, s3ListBucket,
722 ARN(Partition::aws, Service::s3,
723 "", arbitrary_tenant, "example_bucket/myobject")),
724 Effect::Deny);
725
726 EXPECT_EQ(denyp.eval(blacklistedIP, trueacct, s3ListBucket,
727 ARN(Partition::aws, Service::s3,
728 "", arbitrary_tenant, "example_bucket")),
729 Effect::Pass);
730 EXPECT_EQ(denyp.eval(blacklistedIP, trueacct, s3ListBucket,
731 ARN(Partition::aws, Service::s3,
732 "", arbitrary_tenant, "example_bucket/myobject")),
733 Effect::Pass);
734
735 EXPECT_EQ(denyp.eval(blacklistedIPv6, trueacct, s3ListBucket,
736 ARN(Partition::aws, Service::s3,
737 "", arbitrary_tenant, "example_bucket")),
738 Effect::Pass);
739 EXPECT_EQ(denyp.eval(blacklistedIPv6, trueacct, s3ListBucket,
740 ARN(Partition::aws, Service::s3,
741 "", arbitrary_tenant, "example_bucket/myobject")),
742 Effect::Pass);
743 EXPECT_EQ(denyp.eval(allowedIPv6, trueacct, s3ListBucket,
744 ARN(Partition::aws, Service::s3,
745 "", arbitrary_tenant, "example_bucket")),
746 Effect::Deny);
747 EXPECT_EQ(denyp.eval(allowedIPv6, trueacct, s3ListBucket,
748 ARN(Partition::aws, Service::s3,
749 "", arbitrary_tenant, "example_bucket/myobject")),
750 Effect::Deny);
751
752 EXPECT_EQ(fullp.eval(allowedIP, trueacct, s3ListBucket,
753 ARN(Partition::aws, Service::s3,
754 "", arbitrary_tenant, "example_bucket")),
755 Effect::Allow);
756 EXPECT_EQ(fullp.eval(allowedIP, trueacct, s3ListBucket,
757 ARN(Partition::aws, Service::s3,
758 "", arbitrary_tenant, "example_bucket/myobject")),
759 Effect::Allow);
760
761 EXPECT_EQ(fullp.eval(blacklistedIP, trueacct, s3ListBucket,
762 ARN(Partition::aws, Service::s3,
763 "", arbitrary_tenant, "example_bucket")),
764 Effect::Pass);
765 EXPECT_EQ(fullp.eval(blacklistedIP, trueacct, s3ListBucket,
766 ARN(Partition::aws, Service::s3,
767 "", arbitrary_tenant, "example_bucket/myobject")),
768 Effect::Pass);
769
770 EXPECT_EQ(fullp.eval(allowedIPv6, trueacct, s3ListBucket,
771 ARN(Partition::aws, Service::s3,
772 "", arbitrary_tenant, "example_bucket")),
773 Effect::Allow);
774 EXPECT_EQ(fullp.eval(allowedIPv6, trueacct, s3ListBucket,
775 ARN(Partition::aws, Service::s3,
776 "", arbitrary_tenant, "example_bucket/myobject")),
777 Effect::Allow);
778
779 EXPECT_EQ(fullp.eval(blacklistedIPv6, trueacct, s3ListBucket,
780 ARN(Partition::aws, Service::s3,
781 "", arbitrary_tenant, "example_bucket")),
782 Effect::Pass);
783 EXPECT_EQ(fullp.eval(blacklistedIPv6, trueacct, s3ListBucket,
784 ARN(Partition::aws, Service::s3,
785 "", arbitrary_tenant, "example_bucket/myobject")),
786 Effect::Pass);
787}
788
789string IPPolicyTest::ip_address_allow_example = R"(
790{
791 "Version": "2012-10-17",
792 "Id": "S3SimpleIPPolicyTest",
793 "Statement": [{
794 "Sid": "1",
795 "Effect": "Allow",
796 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
797 "Action": "s3:ListBucket",
798 "Resource": [
799 "arn:aws:s3:::example_bucket"
800 ],
801 "Condition": {
802 "IpAddress": {"aws:SourceIp": "192.168.1.0/24"}
803 }
804 }]
805}
806)";
807
808string IPPolicyTest::ip_address_deny_example = R"(
809{
810 "Version": "2012-10-17",
811 "Id": "S3IPPolicyTest",
812 "Statement": {
813 "Effect": "Deny",
814 "Sid": "IPDeny",
815 "Action": "s3:ListBucket",
816 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
817 "Resource": [
818 "arn:aws:s3:::example_bucket",
819 "arn:aws:s3:::example_bucket/*"
820 ],
821 "Condition": {
822 "NotIpAddress": {"aws:SourceIp": ["192.168.1.1/32", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]}
823 }
824 }
825}
826)";
827
828string IPPolicyTest::ip_address_full_example = R"(
829{
830 "Version": "2012-10-17",
831 "Id": "S3IPPolicyTest",
832 "Statement": {
833 "Effect": "Allow",
834 "Sid": "IPAllow",
835 "Action": "s3:ListBucket",
836 "Principal": "*",
837 "Resource": [
838 "arn:aws:s3:::example_bucket",
839 "arn:aws:s3:::example_bucket/*"
840 ],
841 "Condition": {
842 "IpAddress": {"aws:SourceIp": ["192.168.1.0/24", "::1"]},
843 "NotIpAddress": {"aws:SourceIp": ["192.168.1.1/32", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]}
844 }
845 }
846}
847)";
848
d2e6a577
FG
849TEST(MatchWildcards, Simple)
850{
851 EXPECT_TRUE(match_wildcards("", ""));
852 EXPECT_TRUE(match_wildcards("", "", MATCH_CASE_INSENSITIVE));
853 EXPECT_FALSE(match_wildcards("", "abc"));
854 EXPECT_FALSE(match_wildcards("", "abc", MATCH_CASE_INSENSITIVE));
855 EXPECT_FALSE(match_wildcards("abc", ""));
856 EXPECT_FALSE(match_wildcards("abc", "", MATCH_CASE_INSENSITIVE));
857 EXPECT_TRUE(match_wildcards("abc", "abc"));
858 EXPECT_TRUE(match_wildcards("abc", "abc", MATCH_CASE_INSENSITIVE));
859 EXPECT_FALSE(match_wildcards("abc", "abC"));
860 EXPECT_TRUE(match_wildcards("abc", "abC", MATCH_CASE_INSENSITIVE));
861 EXPECT_FALSE(match_wildcards("abC", "abc"));
862 EXPECT_TRUE(match_wildcards("abC", "abc", MATCH_CASE_INSENSITIVE));
863 EXPECT_FALSE(match_wildcards("abc", "abcd"));
864 EXPECT_FALSE(match_wildcards("abc", "abcd", MATCH_CASE_INSENSITIVE));
865 EXPECT_FALSE(match_wildcards("abcd", "abc"));
866 EXPECT_FALSE(match_wildcards("abcd", "abc", MATCH_CASE_INSENSITIVE));
867}
868
869TEST(MatchWildcards, QuestionMark)
870{
871 EXPECT_FALSE(match_wildcards("?", ""));
872 EXPECT_FALSE(match_wildcards("?", "", MATCH_CASE_INSENSITIVE));
873 EXPECT_TRUE(match_wildcards("?", "a"));
874 EXPECT_TRUE(match_wildcards("?", "a", MATCH_CASE_INSENSITIVE));
875 EXPECT_TRUE(match_wildcards("?bc", "abc"));
876 EXPECT_TRUE(match_wildcards("?bc", "abc", MATCH_CASE_INSENSITIVE));
877 EXPECT_TRUE(match_wildcards("a?c", "abc"));
878 EXPECT_TRUE(match_wildcards("a?c", "abc", MATCH_CASE_INSENSITIVE));
879 EXPECT_FALSE(match_wildcards("abc", "a?c"));
880 EXPECT_FALSE(match_wildcards("abc", "a?c", MATCH_CASE_INSENSITIVE));
881 EXPECT_FALSE(match_wildcards("a?c", "abC"));
882 EXPECT_TRUE(match_wildcards("a?c", "abC", MATCH_CASE_INSENSITIVE));
883 EXPECT_TRUE(match_wildcards("ab?", "abc"));
884 EXPECT_TRUE(match_wildcards("ab?", "abc", MATCH_CASE_INSENSITIVE));
885 EXPECT_TRUE(match_wildcards("a?c?e", "abcde"));
886 EXPECT_TRUE(match_wildcards("a?c?e", "abcde", MATCH_CASE_INSENSITIVE));
887 EXPECT_TRUE(match_wildcards("???", "abc"));
888 EXPECT_TRUE(match_wildcards("???", "abc", MATCH_CASE_INSENSITIVE));
889 EXPECT_FALSE(match_wildcards("???", "abcd"));
890 EXPECT_FALSE(match_wildcards("???", "abcd", MATCH_CASE_INSENSITIVE));
891}
892
893TEST(MatchWildcards, Asterisk)
894{
895 EXPECT_TRUE(match_wildcards("*", ""));
896 EXPECT_TRUE(match_wildcards("*", "", MATCH_CASE_INSENSITIVE));
897 EXPECT_FALSE(match_wildcards("", "*"));
898 EXPECT_FALSE(match_wildcards("", "*", MATCH_CASE_INSENSITIVE));
899 EXPECT_FALSE(match_wildcards("*a", ""));
900 EXPECT_FALSE(match_wildcards("*a", "", MATCH_CASE_INSENSITIVE));
901 EXPECT_TRUE(match_wildcards("*a", "a"));
902 EXPECT_TRUE(match_wildcards("*a", "a", MATCH_CASE_INSENSITIVE));
903 EXPECT_TRUE(match_wildcards("a*", "a"));
904 EXPECT_TRUE(match_wildcards("a*", "a", MATCH_CASE_INSENSITIVE));
905 EXPECT_TRUE(match_wildcards("a*c", "ac"));
906 EXPECT_TRUE(match_wildcards("a*c", "ac", MATCH_CASE_INSENSITIVE));
907 EXPECT_TRUE(match_wildcards("a*c", "abbc"));
908 EXPECT_TRUE(match_wildcards("a*c", "abbc", MATCH_CASE_INSENSITIVE));
909 EXPECT_FALSE(match_wildcards("a*c", "abbC"));
910 EXPECT_TRUE(match_wildcards("a*c", "abbC", MATCH_CASE_INSENSITIVE));
911 EXPECT_TRUE(match_wildcards("a*c*e", "abBce"));
912 EXPECT_TRUE(match_wildcards("a*c*e", "abBce", MATCH_CASE_INSENSITIVE));
913 EXPECT_TRUE(match_wildcards("http://*.example.com",
914 "http://www.example.com"));
915 EXPECT_TRUE(match_wildcards("http://*.example.com",
916 "http://www.example.com", MATCH_CASE_INSENSITIVE));
917 EXPECT_FALSE(match_wildcards("http://*.example.com",
918 "http://www.Example.com"));
919 EXPECT_TRUE(match_wildcards("http://*.example.com",
920 "http://www.Example.com", MATCH_CASE_INSENSITIVE));
921 EXPECT_TRUE(match_wildcards("http://example.com/*",
922 "http://example.com/index.html"));
923 EXPECT_TRUE(match_wildcards("http://example.com/*/*.jpg",
924 "http://example.com/fun/smiley.jpg"));
925 // note: parsing of * is not greedy, so * does not match 'bc' here
926 EXPECT_FALSE(match_wildcards("a*c", "abcc"));
927 EXPECT_FALSE(match_wildcards("a*c", "abcc", MATCH_CASE_INSENSITIVE));
928}
929
930TEST(MatchPolicy, Action)
931{
932 constexpr auto flag = MATCH_POLICY_ACTION;
933 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
934 EXPECT_TRUE(match_policy("a:b:c", "A:B:C", flag)); // case insensitive
935 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
936 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
937}
938
939TEST(MatchPolicy, Resource)
940{
941 constexpr auto flag = MATCH_POLICY_RESOURCE;
942 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
943 EXPECT_FALSE(match_policy("a:b:c", "A:B:C", flag)); // case sensitive
944 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
945 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
946}
947
948TEST(MatchPolicy, ARN)
949{
950 constexpr auto flag = MATCH_POLICY_ARN;
951 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
952 EXPECT_TRUE(match_policy("a:b:c", "A:B:C", flag)); // case insensitive
953 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
954 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
955}
956
957TEST(MatchPolicy, String)
958{
959 constexpr auto flag = MATCH_POLICY_STRING;
960 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
961 EXPECT_FALSE(match_policy("a:b:c", "A:B:C", flag)); // case sensitive
962 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
963 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
964}