1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 * Ceph - scalable distributed file system
6 * Copyright (C) 2015 Red Hat
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.
17 #include <boost/intrusive_ptr.hpp>
18 #include <boost/optional.hpp>
20 #include <gtest/gtest.h>
22 #include "include/stringify.h"
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"
28 #include "rgw/rgw_op.h"
34 using boost::container::flat_set
;
35 using boost::intrusive_ptr
;
36 using boost::make_optional
;
39 using rgw::auth::Identity
;
40 using rgw::auth::Principal
;
43 using rgw::IAM::Effect
;
44 using rgw::IAM::Environment
;
46 using rgw::IAM::Policy
;
47 using rgw::IAM::s3All
;
48 using rgw::IAM::s3Count
;
49 using rgw::IAM::s3GetAccelerateConfiguration
;
50 using rgw::IAM::s3GetBucketAcl
;
51 using rgw::IAM::s3GetBucketCORS
;
52 using rgw::IAM::s3GetBucketLocation
;
53 using rgw::IAM::s3GetBucketLogging
;
54 using rgw::IAM::s3GetBucketNotification
;
55 using rgw::IAM::s3GetBucketPolicy
;
56 using rgw::IAM::s3GetBucketPolicyStatus
;
57 using rgw::IAM::s3GetBucketPublicAccessBlock
;
58 using rgw::IAM::s3GetBucketRequestPayment
;
59 using rgw::IAM::s3GetBucketTagging
;
60 using rgw::IAM::s3GetBucketVersioning
;
61 using rgw::IAM::s3GetBucketWebsite
;
62 using rgw::IAM::s3GetLifecycleConfiguration
;
63 using rgw::IAM::s3GetObject
;
64 using rgw::IAM::s3GetObjectAcl
;
65 using rgw::IAM::s3GetObjectVersionAcl
;
66 using rgw::IAM::s3GetObjectTorrent
;
67 using rgw::IAM::s3GetObjectTagging
;
68 using rgw::IAM::s3GetObjectVersion
;
69 using rgw::IAM::s3GetObjectVersionTagging
;
70 using rgw::IAM::s3GetObjectVersionTorrent
;
71 using rgw::IAM::s3GetPublicAccessBlock
;
72 using rgw::IAM::s3GetReplicationConfiguration
;
73 using rgw::IAM::s3ListAllMyBuckets
;
74 using rgw::IAM::s3ListBucket
;
75 using rgw::IAM::s3ListBucket
;
76 using rgw::IAM::s3ListBucketMultipartUploads
;
77 using rgw::IAM::s3ListBucketVersions
;
78 using rgw::IAM::s3ListMultipartUploadParts
;
80 using rgw::IAM::s3PutBucketAcl
;
81 using rgw::IAM::s3PutBucketPolicy
;
82 using rgw::IAM::s3GetBucketObjectLockConfiguration
;
83 using rgw::IAM::s3GetObjectRetention
;
84 using rgw::IAM::s3GetObjectLegalHold
;
86 using rgw::IAM::TokenID
;
87 using rgw::IAM::Version
;
88 using rgw::IAM::Action_t
;
89 using rgw::IAM::NotAction_t
;
90 using rgw::IAM::iamCreateRole
;
91 using rgw::IAM::iamDeleteRole
;
92 using rgw::IAM::iamAll
;
93 using rgw::IAM::stsAll
;
94 using rgw::IAM::allCount
;
96 class FakeIdentity
: public Identity
{
100 explicit FakeIdentity(Principal
&& id
) : id(std::move(id
)) {}
101 uint32_t get_perms_from_aclspec(const DoutPrefixProvider
* dpp
, const aclspec_t
& aclspec
) const override
{
106 bool is_admin_of(const rgw_user
& uid
) const override
{
111 bool is_owner_of(const rgw_user
& uid
) const override
{
116 virtual uint32_t get_perm_mask() const override
{
121 uint32_t get_identity_type() const override
{
126 string
get_acct_name() const override
{
131 void to_str(std::ostream
& out
) const override
{
135 bool is_identity(const flat_set
<Principal
>& ids
) const override
{
136 if (id
.is_wildcard() && (!ids
.empty())) {
139 return ids
.find(id
) != ids
.end() || ids
.find(Principal::wildcard()) != ids
.end();
143 class PolicyTest
: public ::testing::Test
{
145 intrusive_ptr
<CephContext
> cct
;
146 static const string arbitrary_tenant
;
147 static string example1
;
148 static string example2
;
149 static string example3
;
150 static string example4
;
151 static string example5
;
152 static string example6
;
153 static string example7
;
156 cct
= new CephContext(CEPH_ENTITY_TYPE_CLIENT
);
160 TEST_F(PolicyTest
, Parse1
) {
161 boost::optional
<Policy
> p
;
163 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
164 bufferlist::static_from_string(example1
)));
167 EXPECT_EQ(p
->text
, example1
);
168 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
170 EXPECT_FALSE(p
->statements
[0].sid
);
171 EXPECT_FALSE(p
->statements
.empty());
172 EXPECT_EQ(p
->statements
.size(), 1U);
173 EXPECT_TRUE(p
->statements
[0].princ
.empty());
174 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
175 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
177 act
[s3ListBucket
] = 1;
178 EXPECT_EQ(p
->statements
[0].action
, act
);
179 EXPECT_EQ(p
->statements
[0].notaction
, None
);
180 ASSERT_FALSE(p
->statements
[0].resource
.empty());
181 ASSERT_EQ(p
->statements
[0].resource
.size(), 1U);
182 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::aws
);
183 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::s3
);
184 EXPECT_TRUE(p
->statements
[0].resource
.begin()->region
.empty());
185 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
186 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "example_bucket");
187 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
188 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
191 TEST_F(PolicyTest
, Eval1
) {
192 auto p
= Policy(cct
.get(), arbitrary_tenant
,
193 bufferlist::static_from_string(example1
));
196 EXPECT_EQ(p
.eval(e
, none
, s3ListBucket
,
197 ARN(Partition::aws
, Service::s3
,
198 "", arbitrary_tenant
, "example_bucket")),
201 EXPECT_EQ(p
.eval(e
, none
, s3PutBucketAcl
,
202 ARN(Partition::aws
, Service::s3
,
203 "", arbitrary_tenant
, "example_bucket")),
206 EXPECT_EQ(p
.eval(e
, none
, s3ListBucket
,
207 ARN(Partition::aws
, Service::s3
,
208 "", arbitrary_tenant
, "erroneous_bucket")),
213 TEST_F(PolicyTest
, Parse2
) {
214 boost::optional
<Policy
> p
;
216 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
217 bufferlist::static_from_string(example2
)));
220 EXPECT_EQ(p
->text
, example2
);
221 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
222 EXPECT_EQ(*p
->id
, "S3-Account-Permissions");
223 ASSERT_FALSE(p
->statements
.empty());
224 EXPECT_EQ(p
->statements
.size(), 1U);
225 EXPECT_EQ(*p
->statements
[0].sid
, "1");
226 EXPECT_FALSE(p
->statements
[0].princ
.empty());
227 EXPECT_EQ(p
->statements
[0].princ
.size(), 1U);
228 EXPECT_EQ(*p
->statements
[0].princ
.begin(),
229 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
230 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
231 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
233 for (auto i
= 0ULL; i
< s3Count
; i
++)
236 EXPECT_EQ(p
->statements
[0].action
, act
);
237 EXPECT_EQ(p
->statements
[0].notaction
, None
);
238 ASSERT_FALSE(p
->statements
[0].resource
.empty());
239 ASSERT_EQ(p
->statements
[0].resource
.size(), 2U);
240 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::aws
);
241 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::s3
);
242 EXPECT_TRUE(p
->statements
[0].resource
.begin()->region
.empty());
243 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
244 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "mybucket");
245 EXPECT_EQ((p
->statements
[0].resource
.begin() + 1)->partition
,
247 EXPECT_EQ((p
->statements
[0].resource
.begin() + 1)->service
,
249 EXPECT_TRUE((p
->statements
[0].resource
.begin() + 1)->region
.empty());
250 EXPECT_EQ((p
->statements
[0].resource
.begin() + 1)->account
,
252 EXPECT_EQ((p
->statements
[0].resource
.begin() + 1)->resource
, "mybucket/*");
253 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
254 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
257 TEST_F(PolicyTest
, Eval2
) {
258 auto p
= Policy(cct
.get(), arbitrary_tenant
,
259 bufferlist::static_from_string(example2
));
262 auto trueacct
= FakeIdentity(
263 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
265 auto notacct
= FakeIdentity(
266 Principal::tenant("some-other-account"));
267 for (auto i
= 0ULL; i
< s3Count
; ++i
) {
268 EXPECT_EQ(p
.eval(e
, trueacct
, i
,
269 ARN(Partition::aws
, Service::s3
,
270 "", arbitrary_tenant
, "mybucket")),
272 EXPECT_EQ(p
.eval(e
, trueacct
, i
,
273 ARN(Partition::aws
, Service::s3
,
274 "", arbitrary_tenant
, "mybucket/myobject")),
277 EXPECT_EQ(p
.eval(e
, notacct
, i
,
278 ARN(Partition::aws
, Service::s3
,
279 "", arbitrary_tenant
, "mybucket")),
281 EXPECT_EQ(p
.eval(e
, notacct
, i
,
282 ARN(Partition::aws
, Service::s3
,
283 "", arbitrary_tenant
, "mybucket/myobject")),
286 EXPECT_EQ(p
.eval(e
, trueacct
, i
,
287 ARN(Partition::aws
, Service::s3
,
288 "", arbitrary_tenant
, "notyourbucket")),
290 EXPECT_EQ(p
.eval(e
, trueacct
, i
,
291 ARN(Partition::aws
, Service::s3
,
292 "", arbitrary_tenant
, "notyourbucket/notyourobject")),
298 TEST_F(PolicyTest
, Parse3
) {
299 boost::optional
<Policy
> p
;
301 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
302 bufferlist::static_from_string(example3
)));
305 EXPECT_EQ(p
->text
, example3
);
306 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
308 ASSERT_FALSE(p
->statements
.empty());
309 EXPECT_EQ(p
->statements
.size(), 3U);
311 EXPECT_EQ(*p
->statements
[0].sid
, "FirstStatement");
312 EXPECT_TRUE(p
->statements
[0].princ
.empty());
313 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
314 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
316 act
[s3PutBucketPolicy
] = 1;
317 EXPECT_EQ(p
->statements
[0].action
, act
);
318 EXPECT_EQ(p
->statements
[0].notaction
, None
);
319 ASSERT_FALSE(p
->statements
[0].resource
.empty());
320 ASSERT_EQ(p
->statements
[0].resource
.size(), 1U);
321 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::wildcard
);
322 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::wildcard
);
323 EXPECT_EQ(p
->statements
[0].resource
.begin()->region
, "*");
324 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
325 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "*");
326 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
327 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
329 EXPECT_EQ(*p
->statements
[1].sid
, "SecondStatement");
330 EXPECT_TRUE(p
->statements
[1].princ
.empty());
331 EXPECT_TRUE(p
->statements
[1].noprinc
.empty());
332 EXPECT_EQ(p
->statements
[1].effect
, Effect::Allow
);
334 act1
[s3ListAllMyBuckets
] = 1;
335 EXPECT_EQ(p
->statements
[1].action
, act1
);
336 EXPECT_EQ(p
->statements
[1].notaction
, None
);
337 ASSERT_FALSE(p
->statements
[1].resource
.empty());
338 ASSERT_EQ(p
->statements
[1].resource
.size(), 1U);
339 EXPECT_EQ(p
->statements
[1].resource
.begin()->partition
, Partition::wildcard
);
340 EXPECT_EQ(p
->statements
[1].resource
.begin()->service
, Service::wildcard
);
341 EXPECT_EQ(p
->statements
[1].resource
.begin()->region
, "*");
342 EXPECT_EQ(p
->statements
[1].resource
.begin()->account
, arbitrary_tenant
);
343 EXPECT_EQ(p
->statements
[1].resource
.begin()->resource
, "*");
344 EXPECT_TRUE(p
->statements
[1].notresource
.empty());
345 EXPECT_TRUE(p
->statements
[1].conditions
.empty());
347 EXPECT_EQ(*p
->statements
[2].sid
, "ThirdStatement");
348 EXPECT_TRUE(p
->statements
[2].princ
.empty());
349 EXPECT_TRUE(p
->statements
[2].noprinc
.empty());
350 EXPECT_EQ(p
->statements
[2].effect
, Effect::Allow
);
352 act2
[s3ListMultipartUploadParts
] = 1;
353 act2
[s3ListBucket
] = 1;
354 act2
[s3ListBucketVersions
] = 1;
355 act2
[s3ListAllMyBuckets
] = 1;
356 act2
[s3ListBucketMultipartUploads
] = 1;
357 act2
[s3GetObject
] = 1;
358 act2
[s3GetObjectVersion
] = 1;
359 act2
[s3GetObjectAcl
] = 1;
360 act2
[s3GetObjectVersionAcl
] = 1;
361 act2
[s3GetObjectTorrent
] = 1;
362 act2
[s3GetObjectVersionTorrent
] = 1;
363 act2
[s3GetAccelerateConfiguration
] = 1;
364 act2
[s3GetBucketAcl
] = 1;
365 act2
[s3GetBucketCORS
] = 1;
366 act2
[s3GetBucketVersioning
] = 1;
367 act2
[s3GetBucketRequestPayment
] = 1;
368 act2
[s3GetBucketLocation
] = 1;
369 act2
[s3GetBucketPolicy
] = 1;
370 act2
[s3GetBucketNotification
] = 1;
371 act2
[s3GetBucketLogging
] = 1;
372 act2
[s3GetBucketTagging
] = 1;
373 act2
[s3GetBucketWebsite
] = 1;
374 act2
[s3GetLifecycleConfiguration
] = 1;
375 act2
[s3GetReplicationConfiguration
] = 1;
376 act2
[s3GetObjectTagging
] = 1;
377 act2
[s3GetObjectVersionTagging
] = 1;
378 act2
[s3GetBucketObjectLockConfiguration
] = 1;
379 act2
[s3GetObjectRetention
] = 1;
380 act2
[s3GetObjectLegalHold
] = 1;
381 act2
[s3GetBucketPolicyStatus
] = 1;
382 act2
[s3GetBucketPublicAccessBlock
] = 1;
383 act2
[s3GetPublicAccessBlock
] = 1;
385 EXPECT_EQ(p
->statements
[2].action
, act2
);
386 EXPECT_EQ(p
->statements
[2].notaction
, None
);
387 ASSERT_FALSE(p
->statements
[2].resource
.empty());
388 ASSERT_EQ(p
->statements
[2].resource
.size(), 2U);
389 EXPECT_EQ(p
->statements
[2].resource
.begin()->partition
, Partition::aws
);
390 EXPECT_EQ(p
->statements
[2].resource
.begin()->service
, Service::s3
);
391 EXPECT_TRUE(p
->statements
[2].resource
.begin()->region
.empty());
392 EXPECT_EQ(p
->statements
[2].resource
.begin()->account
, arbitrary_tenant
);
393 EXPECT_EQ(p
->statements
[2].resource
.begin()->resource
, "confidential-data");
394 EXPECT_EQ((p
->statements
[2].resource
.begin() + 1)->partition
,
396 EXPECT_EQ((p
->statements
[2].resource
.begin() + 1)->service
, Service::s3
);
397 EXPECT_TRUE((p
->statements
[2].resource
.begin() + 1)->region
.empty());
398 EXPECT_EQ((p
->statements
[2].resource
.begin() + 1)->account
,
400 EXPECT_EQ((p
->statements
[2].resource
.begin() + 1)->resource
,
401 "confidential-data/*");
402 EXPECT_TRUE(p
->statements
[2].notresource
.empty());
403 ASSERT_FALSE(p
->statements
[2].conditions
.empty());
404 ASSERT_EQ(p
->statements
[2].conditions
.size(), 1U);
405 EXPECT_EQ(p
->statements
[2].conditions
[0].op
, TokenID::Bool
);
406 EXPECT_EQ(p
->statements
[2].conditions
[0].key
, "aws:MultiFactorAuthPresent");
407 EXPECT_FALSE(p
->statements
[2].conditions
[0].ifexists
);
408 ASSERT_FALSE(p
->statements
[2].conditions
[0].vals
.empty());
409 EXPECT_EQ(p
->statements
[2].conditions
[0].vals
.size(), 1U);
410 EXPECT_EQ(p
->statements
[2].conditions
[0].vals
[0], "true");
413 TEST_F(PolicyTest
, Eval3
) {
414 auto p
= Policy(cct
.get(), arbitrary_tenant
,
415 bufferlist::static_from_string(example3
));
417 Environment tr
= { { "aws:MultiFactorAuthPresent", "true" } };
418 Environment fa
= { { "aws:MultiFactorAuthPresent", "false" } };
421 s3allow
[s3ListMultipartUploadParts
] = 1;
422 s3allow
[s3ListBucket
] = 1;
423 s3allow
[s3ListBucketVersions
] = 1;
424 s3allow
[s3ListAllMyBuckets
] = 1;
425 s3allow
[s3ListBucketMultipartUploads
] = 1;
426 s3allow
[s3GetObject
] = 1;
427 s3allow
[s3GetObjectVersion
] = 1;
428 s3allow
[s3GetObjectAcl
] = 1;
429 s3allow
[s3GetObjectVersionAcl
] = 1;
430 s3allow
[s3GetObjectTorrent
] = 1;
431 s3allow
[s3GetObjectVersionTorrent
] = 1;
432 s3allow
[s3GetAccelerateConfiguration
] = 1;
433 s3allow
[s3GetBucketAcl
] = 1;
434 s3allow
[s3GetBucketCORS
] = 1;
435 s3allow
[s3GetBucketVersioning
] = 1;
436 s3allow
[s3GetBucketRequestPayment
] = 1;
437 s3allow
[s3GetBucketLocation
] = 1;
438 s3allow
[s3GetBucketPolicy
] = 1;
439 s3allow
[s3GetBucketNotification
] = 1;
440 s3allow
[s3GetBucketLogging
] = 1;
441 s3allow
[s3GetBucketTagging
] = 1;
442 s3allow
[s3GetBucketWebsite
] = 1;
443 s3allow
[s3GetLifecycleConfiguration
] = 1;
444 s3allow
[s3GetReplicationConfiguration
] = 1;
445 s3allow
[s3GetObjectTagging
] = 1;
446 s3allow
[s3GetObjectVersionTagging
] = 1;
447 s3allow
[s3GetBucketObjectLockConfiguration
] = 1;
448 s3allow
[s3GetObjectRetention
] = 1;
449 s3allow
[s3GetObjectLegalHold
] = 1;
450 s3allow
[s3GetBucketPolicyStatus
] = 1;
451 s3allow
[s3GetBucketPublicAccessBlock
] = 1;
452 s3allow
[s3GetPublicAccessBlock
] = 1;
454 EXPECT_EQ(p
.eval(em
, none
, s3PutBucketPolicy
,
455 ARN(Partition::aws
, Service::s3
,
456 "", arbitrary_tenant
, "mybucket")),
459 EXPECT_EQ(p
.eval(em
, none
, s3PutBucketPolicy
,
460 ARN(Partition::aws
, Service::s3
,
461 "", arbitrary_tenant
, "mybucket")),
465 for (auto op
= 0ULL; op
< s3Count
; ++op
) {
466 if ((op
== s3ListAllMyBuckets
) || (op
== s3PutBucketPolicy
)) {
469 EXPECT_EQ(p
.eval(em
, none
, op
,
470 ARN(Partition::aws
, Service::s3
,
471 "", arbitrary_tenant
, "confidential-data")),
473 EXPECT_EQ(p
.eval(tr
, none
, op
,
474 ARN(Partition::aws
, Service::s3
,
475 "", arbitrary_tenant
, "confidential-data")),
476 s3allow
[op
] ? Effect::Allow
: Effect::Pass
);
477 EXPECT_EQ(p
.eval(fa
, none
, op
,
478 ARN(Partition::aws
, Service::s3
,
479 "", arbitrary_tenant
, "confidential-data")),
482 EXPECT_EQ(p
.eval(em
, none
, op
,
483 ARN(Partition::aws
, Service::s3
,
484 "", arbitrary_tenant
, "confidential-data/moo")),
486 EXPECT_EQ(p
.eval(tr
, none
, op
,
487 ARN(Partition::aws
, Service::s3
,
488 "", arbitrary_tenant
, "confidential-data/moo")),
489 s3allow
[op
] ? Effect::Allow
: Effect::Pass
);
490 EXPECT_EQ(p
.eval(fa
, none
, op
,
491 ARN(Partition::aws
, Service::s3
,
492 "", arbitrary_tenant
, "confidential-data/moo")),
495 EXPECT_EQ(p
.eval(em
, none
, op
,
496 ARN(Partition::aws
, Service::s3
,
497 "", arbitrary_tenant
, "really-confidential-data")),
499 EXPECT_EQ(p
.eval(tr
, none
, op
,
500 ARN(Partition::aws
, Service::s3
,
501 "", arbitrary_tenant
, "really-confidential-data")),
503 EXPECT_EQ(p
.eval(fa
, none
, op
,
504 ARN(Partition::aws
, Service::s3
,
505 "", arbitrary_tenant
, "really-confidential-data")),
508 EXPECT_EQ(p
.eval(em
, none
, op
,
509 ARN(Partition::aws
, Service::s3
,
510 "", arbitrary_tenant
,
511 "really-confidential-data/moo")), Effect::Pass
);
512 EXPECT_EQ(p
.eval(tr
, none
, op
,
513 ARN(Partition::aws
, Service::s3
,
514 "", arbitrary_tenant
,
515 "really-confidential-data/moo")), Effect::Pass
);
516 EXPECT_EQ(p
.eval(fa
, none
, op
,
517 ARN(Partition::aws
, Service::s3
,
518 "", arbitrary_tenant
,
519 "really-confidential-data/moo")), Effect::Pass
);
524 TEST_F(PolicyTest
, Parse4
) {
525 boost::optional
<Policy
> p
;
527 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
528 bufferlist::static_from_string(example4
)));
531 EXPECT_EQ(p
->text
, example4
);
532 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
534 EXPECT_FALSE(p
->statements
[0].sid
);
535 EXPECT_FALSE(p
->statements
.empty());
536 EXPECT_EQ(p
->statements
.size(), 1U);
537 EXPECT_TRUE(p
->statements
[0].princ
.empty());
538 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
539 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
541 act
[iamCreateRole
] = 1;
542 EXPECT_EQ(p
->statements
[0].action
, act
);
543 EXPECT_EQ(p
->statements
[0].notaction
, None
);
544 ASSERT_FALSE(p
->statements
[0].resource
.empty());
545 ASSERT_EQ(p
->statements
[0].resource
.size(), 1U);
546 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::wildcard
);
547 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::wildcard
);
548 EXPECT_EQ(p
->statements
[0].resource
.begin()->region
, "*");
549 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
550 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "*");
551 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
552 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
555 TEST_F(PolicyTest
, Eval4
) {
556 auto p
= Policy(cct
.get(), arbitrary_tenant
,
557 bufferlist::static_from_string(example4
));
560 EXPECT_EQ(p
.eval(e
, none
, iamCreateRole
,
561 ARN(Partition::aws
, Service::iam
,
562 "", arbitrary_tenant
, "role/example_role")),
565 EXPECT_EQ(p
.eval(e
, none
, iamDeleteRole
,
566 ARN(Partition::aws
, Service::iam
,
567 "", arbitrary_tenant
, "role/example_role")),
571 TEST_F(PolicyTest
, Parse5
) {
572 boost::optional
<Policy
> p
;
574 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
575 bufferlist::static_from_string(example5
)));
577 EXPECT_EQ(p
->text
, example5
);
578 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
580 EXPECT_FALSE(p
->statements
[0].sid
);
581 EXPECT_FALSE(p
->statements
.empty());
582 EXPECT_EQ(p
->statements
.size(), 1U);
583 EXPECT_TRUE(p
->statements
[0].princ
.empty());
584 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
585 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
587 for (auto i
= s3All
+1; i
<= iamAll
; i
++)
589 EXPECT_EQ(p
->statements
[0].action
, act
);
590 EXPECT_EQ(p
->statements
[0].notaction
, None
);
591 ASSERT_FALSE(p
->statements
[0].resource
.empty());
592 ASSERT_EQ(p
->statements
[0].resource
.size(), 1U);
593 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::aws
);
594 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::iam
);
595 EXPECT_EQ(p
->statements
[0].resource
.begin()->region
, "");
596 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
597 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "role/example_role");
598 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
599 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
602 TEST_F(PolicyTest
, Eval5
) {
603 auto p
= Policy(cct
.get(), arbitrary_tenant
,
604 bufferlist::static_from_string(example5
));
607 EXPECT_EQ(p
.eval(e
, none
, iamCreateRole
,
608 ARN(Partition::aws
, Service::iam
,
609 "", arbitrary_tenant
, "role/example_role")),
612 EXPECT_EQ(p
.eval(e
, none
, s3ListBucket
,
613 ARN(Partition::aws
, Service::iam
,
614 "", arbitrary_tenant
, "role/example_role")),
617 EXPECT_EQ(p
.eval(e
, none
, iamCreateRole
,
618 ARN(Partition::aws
, Service::iam
,
619 "", "", "role/example_role")),
623 TEST_F(PolicyTest
, Parse6
) {
624 boost::optional
<Policy
> p
;
626 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
627 bufferlist::static_from_string(example6
)));
629 EXPECT_EQ(p
->text
, example6
);
630 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
632 EXPECT_FALSE(p
->statements
[0].sid
);
633 EXPECT_FALSE(p
->statements
.empty());
634 EXPECT_EQ(p
->statements
.size(), 1U);
635 EXPECT_TRUE(p
->statements
[0].princ
.empty());
636 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
637 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
639 for (auto i
= 0U; i
<= stsAll
; i
++)
641 EXPECT_EQ(p
->statements
[0].action
, act
);
642 EXPECT_EQ(p
->statements
[0].notaction
, None
);
643 ASSERT_FALSE(p
->statements
[0].resource
.empty());
644 ASSERT_EQ(p
->statements
[0].resource
.size(), 1U);
645 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::aws
);
646 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::iam
);
647 EXPECT_EQ(p
->statements
[0].resource
.begin()->region
, "");
648 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
649 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "user/A");
650 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
651 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
654 TEST_F(PolicyTest
, Eval6
) {
655 auto p
= Policy(cct
.get(), arbitrary_tenant
,
656 bufferlist::static_from_string(example6
));
659 EXPECT_EQ(p
.eval(e
, none
, iamCreateRole
,
660 ARN(Partition::aws
, Service::iam
,
661 "", arbitrary_tenant
, "user/A")),
664 EXPECT_EQ(p
.eval(e
, none
, s3ListBucket
,
665 ARN(Partition::aws
, Service::iam
,
666 "", arbitrary_tenant
, "user/A")),
670 TEST_F(PolicyTest
, Parse7
) {
671 boost::optional
<Policy
> p
;
673 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
674 bufferlist::static_from_string(example7
)));
677 EXPECT_EQ(p
->text
, example7
);
678 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
679 ASSERT_FALSE(p
->statements
.empty());
680 EXPECT_EQ(p
->statements
.size(), 1U);
681 EXPECT_FALSE(p
->statements
[0].princ
.empty());
682 EXPECT_EQ(p
->statements
[0].princ
.size(), 1U);
683 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
684 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
686 act
[s3ListBucket
] = 1;
687 EXPECT_EQ(p
->statements
[0].action
, act
);
688 EXPECT_EQ(p
->statements
[0].notaction
, None
);
689 ASSERT_FALSE(p
->statements
[0].resource
.empty());
690 ASSERT_EQ(p
->statements
[0].resource
.size(), 1U);
691 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::aws
);
692 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::s3
);
693 EXPECT_TRUE(p
->statements
[0].resource
.begin()->region
.empty());
694 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
695 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "mybucket/*");
696 EXPECT_TRUE(p
->statements
[0].princ
.begin()->is_user());
697 EXPECT_FALSE(p
->statements
[0].princ
.begin()->is_wildcard());
698 EXPECT_EQ(p
->statements
[0].princ
.begin()->get_tenant(), "");
699 EXPECT_EQ(p
->statements
[0].princ
.begin()->get_id(), "A:subA");
700 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
701 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
704 TEST_F(PolicyTest
, Eval7
) {
705 auto p
= Policy(cct
.get(), arbitrary_tenant
,
706 bufferlist::static_from_string(example7
));
709 auto subacct
= FakeIdentity(
710 Principal::user(std::move(""), "A:subA"));
711 auto parentacct
= FakeIdentity(
712 Principal::user(std::move(""), "A"));
713 auto sub2acct
= FakeIdentity(
714 Principal::user(std::move(""), "A:sub2A"));
716 EXPECT_EQ(p
.eval(e
, subacct
, s3ListBucket
,
717 ARN(Partition::aws
, Service::s3
,
718 "", arbitrary_tenant
, "mybucket/*")),
721 EXPECT_EQ(p
.eval(e
, parentacct
, s3ListBucket
,
722 ARN(Partition::aws
, Service::s3
,
723 "", arbitrary_tenant
, "mybucket/*")),
726 EXPECT_EQ(p
.eval(e
, sub2acct
, s3ListBucket
,
727 ARN(Partition::aws
, Service::s3
,
728 "", arbitrary_tenant
, "mybucket/*")),
732 const string
PolicyTest::arbitrary_tenant
= "arbitrary_tenant";
733 string
PolicyTest::example1
= R
"(
735 "Version
": "2012-10-17",
738 "Action
": "s3
:ListBucket
",
739 "Resource
": "arn
:aws
:s3:::example_bucket
"
744 string
PolicyTest::example2
= R
"(
746 "Version
": "2012-10-17",
747 "Id
": "S3
-Account
-Permissions
",
751 "Principal
": {"AWS
": ["arn
:aws
:iam::ACCOUNT
-ID
-WITHOUT
-HYPHENS
:root
"]},
754 "arn
:aws
:s3:::mybucket
",
755 "arn
:aws
:s3:::mybucket
/*"
761 string PolicyTest::example3 = R"(
763 "Version": "2012-10-17",
766 "Sid": "FirstStatement",
768 "Action": ["s3:PutBucketPolicy"],
772 "Sid": "SecondStatement",
774 "Action": "s3:ListAllMyBuckets",
778 "Sid": "ThirdStatement",
785 "arn:aws:s3:::confidential-data",
786 "arn:aws:s3:::confidential-data/*"
788 "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
794 string PolicyTest::example4 = R"(
796 "Version": "2012-10-17",
799 "Action": "iam:CreateRole",
805 string PolicyTest::example5 = R"(
807 "Version": "2012-10-17",
811 "Resource": "arn:aws:iam:::role/example_role"
816 string PolicyTest::example6 = R"(
818 "Version": "2012-10-17",
822 "Resource": "arn:aws:iam:::user/A"
827 string PolicyTest::example7 = R"(
829 "Version": "2012-10-17",
832 "Principal": {"AWS": ["arn:aws:iam:::user/A:subA"]},
833 "Action": "s3:ListBucket",
834 "Resource": "arn:aws:s3:::mybucket/*"
838 class IPPolicyTest : public ::testing::Test {
840 intrusive_ptr<CephContext> cct;
841 static const string arbitrary_tenant;
842 static string ip_address_allow_example;
843 static string ip_address_deny_example;
844 static string ip_address_full_example;
846 const rgw::IAM::MaskedIP allowedIPv4Range = { false, rgw::IAM::Address("11000000101010000000000100000000"), 24 };
848 const rgw::IAM::MaskedIP blacklistedIPv4 = { false, rgw::IAM::Address("11000000101010000000000100000001"), 32 };
849 // 2001:db8:85a3:0:0:8a2e:370:7334/128
850 const rgw::IAM::MaskedIP allowedIPv6 = { true, rgw::IAM::Address("00100000000000010000110110111000100001011010001100000000000000000000000000000000100010100010111000000011011100000111001100110100"), 128 };
852 const rgw::IAM::MaskedIP blacklistedIPv6 = { true, rgw::IAM::Address(1), 128 };
853 // 2001:db8:85a3:0:0:8a2e:370:7330/124
854 const rgw::IAM::MaskedIP allowedIPv6Range = { true, rgw::IAM::Address("00100000000000010000110110111000100001011010001100000000000000000000000000000000100010100010111000000011011100000111001100110000"), 124 };
857 cct = new CephContext(CEPH_ENTITY_TYPE_CLIENT);
860 const string IPPolicyTest::arbitrary_tenant = "arbitrary_tenant";
862 TEST_F(IPPolicyTest, MaskedIPOperations) {
863 EXPECT_EQ(stringify(allowedIPv4Range), "192.168.1.0/24");
864 EXPECT_EQ(stringify(blacklistedIPv4), "192.168.1.1/32");
865 EXPECT_EQ(stringify(allowedIPv6), "2001:db8:85a3:0:0:8a2e:370:7334/128");
866 EXPECT_EQ(stringify(allowedIPv6Range), "2001:db8:85a3:0:0:8a2e:370:7330/124");
867 EXPECT_EQ(stringify(blacklistedIPv6), "0:0:0:0:0:0:0:1/128");
868 EXPECT_EQ(allowedIPv4Range, blacklistedIPv4);
869 EXPECT_EQ(allowedIPv6Range, allowedIPv6);
872 TEST_F(IPPolicyTest, asNetworkIPv4Range) {
873 auto actualIPv4Range = rgw::IAM::Condition::as_network("192.168.1.0/24");
874 ASSERT_TRUE(actualIPv4Range.is_initialized());
875 EXPECT_EQ(*actualIPv4Range, allowedIPv4Range);
878 TEST_F(IPPolicyTest, asNetworkIPv4) {
879 auto actualIPv4 = rgw::IAM::Condition::as_network("192.168.1.1");
880 ASSERT_TRUE(actualIPv4.is_initialized());
881 EXPECT_EQ(*actualIPv4, blacklistedIPv4);
884 TEST_F(IPPolicyTest, asNetworkIPv6Range) {
885 auto actualIPv6Range = rgw::IAM::Condition::as_network("2001:db8:85a3:0:0:8a2e:370:7330/124");
886 ASSERT_TRUE(actualIPv6Range.is_initialized());
887 EXPECT_EQ(*actualIPv6Range, allowedIPv6Range);
890 TEST_F(IPPolicyTest, asNetworkIPv6) {
891 auto actualIPv6 = rgw::IAM::Condition::as_network("2001:db8:85a3:0:0:8a2e:370:7334");
892 ASSERT_TRUE(actualIPv6.is_initialized());
893 EXPECT_EQ(*actualIPv6, allowedIPv6);
896 TEST_F(IPPolicyTest, asNetworkInvalid) {
897 EXPECT_FALSE(rgw::IAM::Condition::as_network(""));
898 EXPECT_FALSE(rgw::IAM::Condition::as_network("192.168.1.1/33"));
899 EXPECT_FALSE(rgw::IAM::Condition::as_network("2001:db8:85a3:0:0:8a2e:370:7334/129"));
900 EXPECT_FALSE(rgw::IAM::Condition::as_network("192.168.1.1:"));
901 EXPECT_FALSE(rgw::IAM::Condition::as_network("1.2.3.10000"));
904 TEST_F(IPPolicyTest, IPEnvironment) {
905 // Unfortunately RGWCivetWeb is too tightly tied to civetweb to test RGWCivetWeb::init_env.
907 rgw::sal::RGWRadosStore store;
908 rgw::sal::RGWRadosUser user(&store);
909 rgw_env.set("REMOTE_ADDR", "192.168.1.1");
910 rgw_env.set("HTTP_HOST", "1.2.3.4");
911 req_state rgw_req_state(cct.get(), &rgw_env, &user, 0);
912 rgw_build_iam_environment(&store, &rgw_req_state);
913 auto ip = rgw_req_state.env.find("aws:SourceIp");
914 ASSERT_NE(ip, rgw_req_state.env.end());
915 EXPECT_EQ(ip->second, "192.168.1.1");
917 ASSERT_EQ(cct.get()->_conf.set_val("rgw_remote_addr_param", "SOME_VAR"), 0);
918 EXPECT_EQ(cct.get()->_conf->rgw_remote_addr_param, "SOME_VAR");
919 rgw_req_state.env.clear();
920 rgw_build_iam_environment(&store, &rgw_req_state);
921 ip = rgw_req_state.env.find("aws:SourceIp");
922 EXPECT_EQ(ip, rgw_req_state.env.end());
924 rgw_env.set("SOME_VAR", "192.168.1.2");
925 rgw_req_state.env.clear();
926 rgw_build_iam_environment(&store, &rgw_req_state);
927 ip = rgw_req_state.env.find("aws:SourceIp");
928 ASSERT_NE(ip, rgw_req_state.env.end());
929 EXPECT_EQ(ip->second, "192.168.1.2");
931 ASSERT_EQ(cct.get()->_conf.set_val("rgw_remote_addr_param", "HTTP_X_FORWARDED_FOR"), 0);
932 rgw_env.set("HTTP_X_FORWARDED_FOR", "192.168.1.3");
933 rgw_req_state.env.clear();
934 rgw_build_iam_environment(&store, &rgw_req_state);
935 ip = rgw_req_state.env.find("aws:SourceIp");
936 ASSERT_NE(ip, rgw_req_state.env.end());
937 EXPECT_EQ(ip->second, "192.168.1.3");
939 rgw_env.set("HTTP_X_FORWARDED_FOR", "192.168.1.4, 4.3.2.1, 2001:db8:85a3:8d3:1319:8a2e:370:7348");
940 rgw_req_state.env.clear();
941 rgw_build_iam_environment(&store, &rgw_req_state);
942 ip = rgw_req_state.env.find("aws:SourceIp");
943 ASSERT_NE(ip, rgw_req_state.env.end());
944 EXPECT_EQ(ip->second, "192.168.1.4");
947 TEST_F(IPPolicyTest, ParseIPAddress) {
948 boost::optional<Policy> p;
950 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
951 bufferlist::static_from_string(ip_address_full_example)));
954 EXPECT_EQ(p->text, ip_address_full_example);
955 EXPECT_EQ(p->version, Version::v2012_10_17);
956 EXPECT_EQ(*p->id, "S3IPPolicyTest");
957 EXPECT_FALSE(p->statements.empty());
958 EXPECT_EQ(p->statements.size(), 1U);
959 EXPECT_EQ(*p->statements[0].sid, "IPAllow");
960 EXPECT_FALSE(p->statements[0].princ.empty());
961 EXPECT_EQ(p->statements[0].princ.size(), 1U);
962 EXPECT_EQ(*p->statements[0].princ.begin(),
963 Principal::wildcard());
964 EXPECT_TRUE(p->statements[0].noprinc.empty());
965 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
967 act[s3ListBucket] = 1;
968 EXPECT_EQ(p->statements[0].action, act);
969 EXPECT_EQ(p->statements[0].notaction, None);
970 ASSERT_FALSE(p->statements[0].resource.empty());
971 ASSERT_EQ(p->statements[0].resource.size(), 2U);
972 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::aws);
973 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::s3);
974 EXPECT_TRUE(p->statements[0].resource.begin()->region.empty());
975 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
976 EXPECT_EQ(p->statements[0].resource.begin()->resource, "example_bucket");
977 EXPECT_EQ((p->statements[0].resource.begin() + 1)->resource, "example_bucket/*");
978 EXPECT_TRUE(p->statements[0].notresource.empty());
979 ASSERT_FALSE(p->statements[0].conditions.empty());
980 ASSERT_EQ(p->statements[0].conditions.size(), 2U);
981 EXPECT_EQ(p->statements[0].conditions[0].op, TokenID::IpAddress);
982 EXPECT_EQ(p->statements[0].conditions[0].key, "aws:SourceIp");
983 ASSERT_FALSE(p->statements[0].conditions[0].vals.empty());
984 EXPECT_EQ(p->statements[0].conditions[0].vals.size(), 2U);
985 EXPECT_EQ(p->statements[0].conditions[0].vals[0], "192.168.1.0/24");
986 EXPECT_EQ(p->statements[0].conditions[0].vals[1], "::1");
987 boost::optional<rgw::IAM::MaskedIP> convertedIPv4 = rgw::IAM::Condition::as_network(p->statements[0].conditions[0].vals[0]);
988 EXPECT_TRUE(convertedIPv4.is_initialized());
989 if (convertedIPv4.is_initialized()) {
990 EXPECT_EQ(*convertedIPv4, allowedIPv4Range);
993 EXPECT_EQ(p->statements[0].conditions[1].op, TokenID::NotIpAddress);
994 EXPECT_EQ(p->statements[0].conditions[1].key, "aws:SourceIp");
995 ASSERT_FALSE(p->statements[0].conditions[1].vals.empty());
996 EXPECT_EQ(p->statements[0].conditions[1].vals.size(), 2U);
997 EXPECT_EQ(p->statements[0].conditions[1].vals[0], "192.168.1.1/32");
998 EXPECT_EQ(p->statements[0].conditions[1].vals[1], "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
999 boost::optional<rgw::IAM::MaskedIP> convertedIPv6 = rgw::IAM::Condition::as_network(p->statements[0].conditions[1].vals[1]);
1000 EXPECT_TRUE(convertedIPv6.is_initialized());
1001 if (convertedIPv6.is_initialized()) {
1002 EXPECT_EQ(*convertedIPv6, allowedIPv6);
1006 TEST_F(IPPolicyTest, EvalIPAddress) {
1007 auto allowp = Policy(cct.get(), arbitrary_tenant,
1008 bufferlist::static_from_string(ip_address_allow_example));
1009 auto denyp = Policy(cct.get(), arbitrary_tenant,
1010 bufferlist::static_from_string(ip_address_deny_example));
1011 auto fullp = Policy(cct.get(), arbitrary_tenant,
1012 bufferlist::static_from_string(ip_address_full_example));
1014 Environment allowedIP, blacklistedIP, allowedIPv6, blacklistedIPv6;
1015 allowedIP["aws:SourceIp"] = "192.168.1.2";
1016 allowedIPv6["aws:SourceIp"] = "::1";
1017 blacklistedIP["aws:SourceIp"] = "192.168.1.1";
1018 blacklistedIPv6["aws:SourceIp"] = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
1020 auto trueacct = FakeIdentity(
1021 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
1022 // Without an IP address in the environment then evaluation will always pass
1023 EXPECT_EQ(allowp.eval(e, trueacct, s3ListBucket,
1024 ARN(Partition::aws, Service::s3,
1025 "", arbitrary_tenant, "example_bucket")),
1027 EXPECT_EQ(fullp.eval(e, trueacct, s3ListBucket,
1028 ARN(Partition::aws, Service::s3,
1029 "", arbitrary_tenant, "example_bucket/myobject")),
1032 EXPECT_EQ(allowp.eval(allowedIP, trueacct, s3ListBucket,
1033 ARN(Partition::aws, Service::s3,
1034 "", arbitrary_tenant, "example_bucket")),
1036 EXPECT_EQ(allowp.eval(blacklistedIPv6, trueacct, s3ListBucket,
1037 ARN(Partition::aws, Service::s3,
1038 "", arbitrary_tenant, "example_bucket")),
1042 EXPECT_EQ(denyp.eval(allowedIP, trueacct, s3ListBucket,
1043 ARN(Partition::aws, Service::s3,
1044 "", arbitrary_tenant, "example_bucket")),
1046 EXPECT_EQ(denyp.eval(allowedIP, trueacct, s3ListBucket,
1047 ARN(Partition::aws, Service::s3,
1048 "", arbitrary_tenant, "example_bucket/myobject")),
1051 EXPECT_EQ(denyp.eval(blacklistedIP, trueacct, s3ListBucket,
1052 ARN(Partition::aws, Service::s3,
1053 "", arbitrary_tenant, "example_bucket")),
1055 EXPECT_EQ(denyp.eval(blacklistedIP, trueacct, s3ListBucket,
1056 ARN(Partition::aws, Service::s3,
1057 "", arbitrary_tenant, "example_bucket/myobject")),
1060 EXPECT_EQ(denyp.eval(blacklistedIPv6, trueacct, s3ListBucket,
1061 ARN(Partition::aws, Service::s3,
1062 "", arbitrary_tenant, "example_bucket")),
1064 EXPECT_EQ(denyp.eval(blacklistedIPv6, trueacct, s3ListBucket,
1065 ARN(Partition::aws, Service::s3,
1066 "", arbitrary_tenant, "example_bucket/myobject")),
1068 EXPECT_EQ(denyp.eval(allowedIPv6, trueacct, s3ListBucket,
1069 ARN(Partition::aws, Service::s3,
1070 "", arbitrary_tenant, "example_bucket")),
1072 EXPECT_EQ(denyp.eval(allowedIPv6, trueacct, s3ListBucket,
1073 ARN(Partition::aws, Service::s3,
1074 "", arbitrary_tenant, "example_bucket/myobject")),
1077 EXPECT_EQ(fullp.eval(allowedIP, trueacct, s3ListBucket,
1078 ARN(Partition::aws, Service::s3,
1079 "", arbitrary_tenant, "example_bucket")),
1081 EXPECT_EQ(fullp.eval(allowedIP, trueacct, s3ListBucket,
1082 ARN(Partition::aws, Service::s3,
1083 "", arbitrary_tenant, "example_bucket/myobject")),
1086 EXPECT_EQ(fullp.eval(blacklistedIP, trueacct, s3ListBucket,
1087 ARN(Partition::aws, Service::s3,
1088 "", arbitrary_tenant, "example_bucket")),
1090 EXPECT_EQ(fullp.eval(blacklistedIP, trueacct, s3ListBucket,
1091 ARN(Partition::aws, Service::s3,
1092 "", arbitrary_tenant, "example_bucket/myobject")),
1095 EXPECT_EQ(fullp.eval(allowedIPv6, trueacct, s3ListBucket,
1096 ARN(Partition::aws, Service::s3,
1097 "", arbitrary_tenant, "example_bucket")),
1099 EXPECT_EQ(fullp.eval(allowedIPv6, trueacct, s3ListBucket,
1100 ARN(Partition::aws, Service::s3,
1101 "", arbitrary_tenant, "example_bucket/myobject")),
1104 EXPECT_EQ(fullp.eval(blacklistedIPv6, trueacct, s3ListBucket,
1105 ARN(Partition::aws, Service::s3,
1106 "", arbitrary_tenant, "example_bucket")),
1108 EXPECT_EQ(fullp.eval(blacklistedIPv6, trueacct, s3ListBucket,
1109 ARN(Partition::aws, Service::s3,
1110 "", arbitrary_tenant, "example_bucket/myobject")),
1114 string IPPolicyTest::ip_address_allow_example = R"(
1116 "Version": "2012-10-17",
1117 "Id": "S3SimpleIPPolicyTest",
1121 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
1122 "Action": "s3:ListBucket",
1124 "arn:aws:s3:::example_bucket"
1127 "IpAddress": {"aws:SourceIp": "192.168.1.0/24"}
1133 string IPPolicyTest::ip_address_deny_example = R"(
1135 "Version": "2012-10-17",
1136 "Id": "S3IPPolicyTest",
1140 "Action": "s3:ListBucket",
1141 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
1143 "arn:aws:s3:::example_bucket",
1144 "arn:aws:s3:::example_bucket/*"
1147 "NotIpAddress": {"aws:SourceIp": ["192.168.1.1/32", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]}
1153 string IPPolicyTest::ip_address_full_example = R"(
1155 "Version": "2012-10-17",
1156 "Id": "S3IPPolicyTest",
1160 "Action": "s3:ListBucket",
1163 "arn:aws:s3:::example_bucket",
1164 "arn:aws:s3:::example_bucket/*"
1167 "IpAddress": {"aws:SourceIp": ["192.168.1.0/24", "::1"]},
1168 "NotIpAddress": {"aws:SourceIp": ["192.168.1.1/32", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]}
1174 TEST(MatchWildcards, Simple)
1176 EXPECT_TRUE(match_wildcards("", ""));
1177 EXPECT_TRUE(match_wildcards("", "", MATCH_CASE_INSENSITIVE));
1178 EXPECT_FALSE(match_wildcards("", "abc"));
1179 EXPECT_FALSE(match_wildcards("", "abc", MATCH_CASE_INSENSITIVE));
1180 EXPECT_FALSE(match_wildcards("abc", ""));
1181 EXPECT_FALSE(match_wildcards("abc", "", MATCH_CASE_INSENSITIVE));
1182 EXPECT_TRUE(match_wildcards("abc", "abc"));
1183 EXPECT_TRUE(match_wildcards("abc", "abc", MATCH_CASE_INSENSITIVE));
1184 EXPECT_FALSE(match_wildcards("abc", "abC"));
1185 EXPECT_TRUE(match_wildcards("abc", "abC", MATCH_CASE_INSENSITIVE));
1186 EXPECT_FALSE(match_wildcards("abC", "abc"));
1187 EXPECT_TRUE(match_wildcards("abC", "abc", MATCH_CASE_INSENSITIVE));
1188 EXPECT_FALSE(match_wildcards("abc", "abcd"));
1189 EXPECT_FALSE(match_wildcards("abc", "abcd", MATCH_CASE_INSENSITIVE));
1190 EXPECT_FALSE(match_wildcards("abcd", "abc"));
1191 EXPECT_FALSE(match_wildcards("abcd", "abc", MATCH_CASE_INSENSITIVE));
1194 TEST(MatchWildcards, QuestionMark)
1196 EXPECT_FALSE(match_wildcards("?", ""));
1197 EXPECT_FALSE(match_wildcards("?", "", MATCH_CASE_INSENSITIVE));
1198 EXPECT_TRUE(match_wildcards("?", "a"));
1199 EXPECT_TRUE(match_wildcards("?", "a", MATCH_CASE_INSENSITIVE));
1200 EXPECT_TRUE(match_wildcards("?bc", "abc"));
1201 EXPECT_TRUE(match_wildcards("?bc", "abc", MATCH_CASE_INSENSITIVE));
1202 EXPECT_TRUE(match_wildcards("a?c", "abc"));
1203 EXPECT_TRUE(match_wildcards("a?c", "abc", MATCH_CASE_INSENSITIVE));
1204 EXPECT_FALSE(match_wildcards("abc", "a?c"));
1205 EXPECT_FALSE(match_wildcards("abc", "a?c", MATCH_CASE_INSENSITIVE));
1206 EXPECT_FALSE(match_wildcards("a?c", "abC"));
1207 EXPECT_TRUE(match_wildcards("a?c", "abC", MATCH_CASE_INSENSITIVE));
1208 EXPECT_TRUE(match_wildcards("ab?", "abc"));
1209 EXPECT_TRUE(match_wildcards("ab?", "abc", MATCH_CASE_INSENSITIVE));
1210 EXPECT_TRUE(match_wildcards("a?c?e", "abcde"));
1211 EXPECT_TRUE(match_wildcards("a?c?e", "abcde", MATCH_CASE_INSENSITIVE));
1212 EXPECT_TRUE(match_wildcards("???", "abc"));
1213 EXPECT_TRUE(match_wildcards("???", "abc", MATCH_CASE_INSENSITIVE));
1214 EXPECT_FALSE(match_wildcards("???", "abcd"));
1215 EXPECT_FALSE(match_wildcards("???", "abcd", MATCH_CASE_INSENSITIVE));
1218 TEST(MatchWildcards, Asterisk)
1220 EXPECT_TRUE(match_wildcards("*", ""));
1221 EXPECT_TRUE(match_wildcards("*", "", MATCH_CASE_INSENSITIVE));
1222 EXPECT_FALSE(match_wildcards("", "*"));
1223 EXPECT_FALSE(match_wildcards("", "*", MATCH_CASE_INSENSITIVE));
1224 EXPECT_FALSE(match_wildcards("*a", ""));
1225 EXPECT_FALSE(match_wildcards("*a", "", MATCH_CASE_INSENSITIVE));
1226 EXPECT_TRUE(match_wildcards("*a", "a"));
1227 EXPECT_TRUE(match_wildcards("*a", "a", MATCH_CASE_INSENSITIVE));
1228 EXPECT_TRUE(match_wildcards("a*", "a"));
1229 EXPECT_TRUE(match_wildcards("a*", "a", MATCH_CASE_INSENSITIVE));
1230 EXPECT_TRUE(match_wildcards("a*c", "ac"));
1231 EXPECT_TRUE(match_wildcards("a*c", "ac", MATCH_CASE_INSENSITIVE));
1232 EXPECT_TRUE(match_wildcards("a*c", "abbc"));
1233 EXPECT_TRUE(match_wildcards("a*c", "abbc", MATCH_CASE_INSENSITIVE));
1234 EXPECT_FALSE(match_wildcards("a*c", "abbC"));
1235 EXPECT_TRUE(match_wildcards("a*c", "abbC", MATCH_CASE_INSENSITIVE));
1236 EXPECT_TRUE(match_wildcards("a*c*e", "abBce"));
1237 EXPECT_TRUE(match_wildcards("a*c*e", "abBce", MATCH_CASE_INSENSITIVE));
1238 EXPECT_TRUE(match_wildcards("http://*.example.com",
1239 "http://www.example.com"));
1240 EXPECT_TRUE(match_wildcards("http://*.example.com",
1241 "http://www.example.com", MATCH_CASE_INSENSITIVE));
1242 EXPECT_FALSE(match_wildcards("http://*.example.com",
1243 "http://www.Example.com"));
1244 EXPECT_TRUE(match_wildcards("http://*.example.com",
1245 "http://www.Example.com", MATCH_CASE_INSENSITIVE));
1246 EXPECT_TRUE(match_wildcards("http://example.com/*",
1247 "http://example.com/index.html"));
1248 EXPECT_TRUE(match_wildcards("http://example.com/*/*.jpg",
1249 "http://example.com/fun/smiley.jpg"));
1250 // note: parsing of * is not greedy, so * does not match 'bc' here
1251 EXPECT_FALSE(match_wildcards("a*c", "abcc"));
1252 EXPECT_FALSE(match_wildcards("a*c", "abcc", MATCH_CASE_INSENSITIVE));
1255 TEST(MatchPolicy, Action)
1257 constexpr auto flag = MATCH_POLICY_ACTION;
1258 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
1259 EXPECT_TRUE(match_policy("a:b:c", "A:B:C", flag)); // case insensitive
1260 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
1261 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
1264 TEST(MatchPolicy, Resource)
1266 constexpr auto flag = MATCH_POLICY_RESOURCE;
1267 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
1268 EXPECT_FALSE(match_policy("a:b:c", "A:B:C", flag)); // case sensitive
1269 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
1270 EXPECT_TRUE(match_policy("a:*", "a:b:c", flag)); // can span segments
1273 TEST(MatchPolicy, ARN)
1275 constexpr auto flag = MATCH_POLICY_ARN;
1276 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
1277 EXPECT_TRUE(match_policy("a:b:c", "A:B:C", flag)); // case insensitive
1278 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
1279 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
1282 TEST(MatchPolicy, String)
1284 constexpr auto flag = MATCH_POLICY_STRING;
1285 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
1286 EXPECT_FALSE(match_policy("a:b:c", "A:B:C", flag)); // case sensitive
1287 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
1288 EXPECT_TRUE(match_policy("a:*", "a:b:c", flag)); // can span segments
1291 Action_t set_range_bits(std::uint64_t start, std::uint64_t end)
1294 for (uint64_t i = start; i < end; i++) {
1300 using rgw::IAM::s3AllValue;
1301 using rgw::IAM::stsAllValue;
1302 using rgw::IAM::allValue;
1303 using rgw::IAM::iamAllValue;
1304 TEST(set_cont_bits, iamconsts)
1306 EXPECT_EQ(s3AllValue, set_range_bits(0, s3All));
1307 EXPECT_EQ(iamAllValue, set_range_bits(s3All+1, iamAll));
1308 EXPECT_EQ(stsAllValue, set_range_bits(iamAll+1, stsAll));
1309 EXPECT_EQ(allValue , set_range_bits(0, allCount));