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"
27 #include "rgw_auth_registry.h"
28 #include "rgw_iam_policy.h"
30 #include "rgw_process_env.h"
31 #include "rgw_sal_rados.h"
37 using boost::container::flat_set
;
38 using boost::intrusive_ptr
;
39 using boost::make_optional
;
42 using rgw::auth::Identity
;
43 using rgw::auth::Principal
;
46 using rgw::IAM::Effect
;
47 using rgw::IAM::Environment
;
49 using rgw::IAM::Policy
;
50 using rgw::IAM::s3All
;
51 using rgw::IAM::s3Count
;
52 using rgw::IAM::s3GetAccelerateConfiguration
;
53 using rgw::IAM::s3GetBucketAcl
;
54 using rgw::IAM::s3GetBucketCORS
;
55 using rgw::IAM::s3GetBucketLocation
;
56 using rgw::IAM::s3GetBucketLogging
;
57 using rgw::IAM::s3GetBucketNotification
;
58 using rgw::IAM::s3GetBucketPolicy
;
59 using rgw::IAM::s3GetBucketPolicyStatus
;
60 using rgw::IAM::s3GetBucketPublicAccessBlock
;
61 using rgw::IAM::s3GetBucketEncryption
;
62 using rgw::IAM::s3GetBucketRequestPayment
;
63 using rgw::IAM::s3GetBucketTagging
;
64 using rgw::IAM::s3GetBucketVersioning
;
65 using rgw::IAM::s3GetBucketWebsite
;
66 using rgw::IAM::s3GetLifecycleConfiguration
;
67 using rgw::IAM::s3GetObject
;
68 using rgw::IAM::s3GetObjectAcl
;
69 using rgw::IAM::s3GetObjectVersionAcl
;
70 using rgw::IAM::s3GetObjectTorrent
;
71 using rgw::IAM::s3GetObjectTagging
;
72 using rgw::IAM::s3GetObjectVersion
;
73 using rgw::IAM::s3GetObjectVersionTagging
;
74 using rgw::IAM::s3GetObjectVersionTorrent
;
75 using rgw::IAM::s3GetPublicAccessBlock
;
76 using rgw::IAM::s3GetReplicationConfiguration
;
77 using rgw::IAM::s3ListAllMyBuckets
;
78 using rgw::IAM::s3ListBucket
;
79 using rgw::IAM::s3ListBucketMultipartUploads
;
80 using rgw::IAM::s3ListBucketVersions
;
81 using rgw::IAM::s3ListMultipartUploadParts
;
83 using rgw::IAM::s3PutBucketAcl
;
84 using rgw::IAM::s3PutBucketPolicy
;
85 using rgw::IAM::s3GetBucketObjectLockConfiguration
;
86 using rgw::IAM::s3GetObjectRetention
;
87 using rgw::IAM::s3GetObjectLegalHold
;
89 using rgw::IAM::TokenID
;
90 using rgw::IAM::Version
;
91 using rgw::IAM::Action_t
;
92 using rgw::IAM::NotAction_t
;
93 using rgw::IAM::iamCreateRole
;
94 using rgw::IAM::iamDeleteRole
;
95 using rgw::IAM::iamAll
;
96 using rgw::IAM::stsAll
;
97 using rgw::IAM::allCount
;
99 class FakeIdentity
: public Identity
{
103 explicit FakeIdentity(Principal
&& id
) : id(std::move(id
)) {}
104 uint32_t get_perms_from_aclspec(const DoutPrefixProvider
* dpp
, const aclspec_t
& aclspec
) const override
{
109 bool is_admin_of(const rgw_user
& uid
) const override
{
114 bool is_owner_of(const rgw_user
& uid
) const override
{
119 virtual uint32_t get_perm_mask() const override
{
124 string
get_acct_name() const override
{
129 string
get_subuser() const override
{
134 void to_str(std::ostream
& out
) const override
{
138 bool is_identity(const flat_set
<Principal
>& ids
) const override
{
139 if (id
.is_wildcard() && (!ids
.empty())) {
142 return ids
.find(id
) != ids
.end() || ids
.find(Principal::wildcard()) != ids
.end();
145 uint32_t get_identity_type() const override
{
150 class PolicyTest
: public ::testing::Test
{
152 intrusive_ptr
<CephContext
> cct
;
153 static const string arbitrary_tenant
;
154 static string example1
;
155 static string example2
;
156 static string example3
;
157 static string example4
;
158 static string example5
;
159 static string example6
;
160 static string example7
;
163 cct
= new CephContext(CEPH_ENTITY_TYPE_CLIENT
);
167 TEST_F(PolicyTest
, Parse1
) {
168 boost::optional
<Policy
> p
;
170 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
171 bufferlist::static_from_string(example1
),
175 EXPECT_EQ(p
->text
, example1
);
176 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
178 EXPECT_FALSE(p
->statements
[0].sid
);
179 EXPECT_FALSE(p
->statements
.empty());
180 EXPECT_EQ(p
->statements
.size(), 1U);
181 EXPECT_TRUE(p
->statements
[0].princ
.empty());
182 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
183 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
185 act
[s3ListBucket
] = 1;
186 EXPECT_EQ(p
->statements
[0].action
, act
);
187 EXPECT_EQ(p
->statements
[0].notaction
, None
);
188 ASSERT_FALSE(p
->statements
[0].resource
.empty());
189 ASSERT_EQ(p
->statements
[0].resource
.size(), 1U);
190 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::aws
);
191 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::s3
);
192 EXPECT_TRUE(p
->statements
[0].resource
.begin()->region
.empty());
193 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
194 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "example_bucket");
195 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
196 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
199 TEST_F(PolicyTest
, Eval1
) {
200 auto p
= Policy(cct
.get(), arbitrary_tenant
,
201 bufferlist::static_from_string(example1
), true);
204 ARN
arn1(Partition::aws
, Service::s3
,
205 "", arbitrary_tenant
, "example_bucket");
206 EXPECT_EQ(p
.eval(e
, none
, s3ListBucket
, arn1
),
209 ARN
arn2(Partition::aws
, Service::s3
,
210 "", arbitrary_tenant
, "example_bucket");
211 EXPECT_EQ(p
.eval(e
, none
, s3PutBucketAcl
, arn2
),
214 ARN
arn3(Partition::aws
, Service::s3
,
215 "", arbitrary_tenant
, "erroneous_bucket");
216 EXPECT_EQ(p
.eval(e
, none
, s3ListBucket
, arn3
),
221 TEST_F(PolicyTest
, Parse2
) {
222 boost::optional
<Policy
> p
;
224 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
225 bufferlist::static_from_string(example2
),
229 EXPECT_EQ(p
->text
, example2
);
230 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
231 EXPECT_EQ(*p
->id
, "S3-Account-Permissions");
232 ASSERT_FALSE(p
->statements
.empty());
233 EXPECT_EQ(p
->statements
.size(), 1U);
234 EXPECT_EQ(*p
->statements
[0].sid
, "1");
235 EXPECT_FALSE(p
->statements
[0].princ
.empty());
236 EXPECT_EQ(p
->statements
[0].princ
.size(), 1U);
237 EXPECT_EQ(*p
->statements
[0].princ
.begin(),
238 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
239 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
240 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
242 for (auto i
= 0ULL; i
< s3Count
; i
++)
245 EXPECT_EQ(p
->statements
[0].action
, act
);
246 EXPECT_EQ(p
->statements
[0].notaction
, None
);
247 ASSERT_FALSE(p
->statements
[0].resource
.empty());
248 ASSERT_EQ(p
->statements
[0].resource
.size(), 2U);
249 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::aws
);
250 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::s3
);
251 EXPECT_TRUE(p
->statements
[0].resource
.begin()->region
.empty());
252 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
253 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "mybucket");
254 EXPECT_EQ((p
->statements
[0].resource
.begin() + 1)->partition
,
256 EXPECT_EQ((p
->statements
[0].resource
.begin() + 1)->service
,
258 EXPECT_TRUE((p
->statements
[0].resource
.begin() + 1)->region
.empty());
259 EXPECT_EQ((p
->statements
[0].resource
.begin() + 1)->account
,
261 EXPECT_EQ((p
->statements
[0].resource
.begin() + 1)->resource
, "mybucket/*");
262 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
263 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
266 TEST_F(PolicyTest
, Eval2
) {
267 auto p
= Policy(cct
.get(), arbitrary_tenant
,
268 bufferlist::static_from_string(example2
), true);
271 auto trueacct
= FakeIdentity(
272 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
274 auto notacct
= FakeIdentity(
275 Principal::tenant("some-other-account"));
276 for (auto i
= 0ULL; i
< s3Count
; ++i
) {
277 ARN
arn1(Partition::aws
, Service::s3
,
278 "", arbitrary_tenant
, "mybucket");
279 EXPECT_EQ(p
.eval(e
, trueacct
, i
, arn1
),
281 ARN
arn2(Partition::aws
, Service::s3
,
282 "", arbitrary_tenant
, "mybucket/myobject");
283 EXPECT_EQ(p
.eval(e
, trueacct
, i
, arn2
),
285 ARN
arn3(Partition::aws
, Service::s3
,
286 "", arbitrary_tenant
, "mybucket");
287 EXPECT_EQ(p
.eval(e
, notacct
, i
, arn3
),
289 ARN
arn4(Partition::aws
, Service::s3
,
290 "", arbitrary_tenant
, "mybucket/myobject");
291 EXPECT_EQ(p
.eval(e
, notacct
, i
, arn4
),
293 ARN
arn5(Partition::aws
, Service::s3
,
294 "", arbitrary_tenant
, "notyourbucket");
295 EXPECT_EQ(p
.eval(e
, trueacct
, i
, arn5
),
297 ARN
arn6(Partition::aws
, Service::s3
,
298 "", arbitrary_tenant
, "notyourbucket/notyourobject");
299 EXPECT_EQ(p
.eval(e
, trueacct
, i
, arn6
),
305 TEST_F(PolicyTest
, Parse3
) {
306 boost::optional
<Policy
> p
;
308 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
309 bufferlist::static_from_string(example3
), true));
312 EXPECT_EQ(p
->text
, example3
);
313 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
315 ASSERT_FALSE(p
->statements
.empty());
316 EXPECT_EQ(p
->statements
.size(), 3U);
318 EXPECT_EQ(*p
->statements
[0].sid
, "FirstStatement");
319 EXPECT_TRUE(p
->statements
[0].princ
.empty());
320 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
321 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
323 act
[s3PutBucketPolicy
] = 1;
324 EXPECT_EQ(p
->statements
[0].action
, act
);
325 EXPECT_EQ(p
->statements
[0].notaction
, None
);
326 ASSERT_FALSE(p
->statements
[0].resource
.empty());
327 ASSERT_EQ(p
->statements
[0].resource
.size(), 1U);
328 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::wildcard
);
329 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::wildcard
);
330 EXPECT_EQ(p
->statements
[0].resource
.begin()->region
, "*");
331 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
332 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "*");
333 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
334 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
336 EXPECT_EQ(*p
->statements
[1].sid
, "SecondStatement");
337 EXPECT_TRUE(p
->statements
[1].princ
.empty());
338 EXPECT_TRUE(p
->statements
[1].noprinc
.empty());
339 EXPECT_EQ(p
->statements
[1].effect
, Effect::Allow
);
341 act1
[s3ListAllMyBuckets
] = 1;
342 EXPECT_EQ(p
->statements
[1].action
, act1
);
343 EXPECT_EQ(p
->statements
[1].notaction
, None
);
344 ASSERT_FALSE(p
->statements
[1].resource
.empty());
345 ASSERT_EQ(p
->statements
[1].resource
.size(), 1U);
346 EXPECT_EQ(p
->statements
[1].resource
.begin()->partition
, Partition::wildcard
);
347 EXPECT_EQ(p
->statements
[1].resource
.begin()->service
, Service::wildcard
);
348 EXPECT_EQ(p
->statements
[1].resource
.begin()->region
, "*");
349 EXPECT_EQ(p
->statements
[1].resource
.begin()->account
, arbitrary_tenant
);
350 EXPECT_EQ(p
->statements
[1].resource
.begin()->resource
, "*");
351 EXPECT_TRUE(p
->statements
[1].notresource
.empty());
352 EXPECT_TRUE(p
->statements
[1].conditions
.empty());
354 EXPECT_EQ(*p
->statements
[2].sid
, "ThirdStatement");
355 EXPECT_TRUE(p
->statements
[2].princ
.empty());
356 EXPECT_TRUE(p
->statements
[2].noprinc
.empty());
357 EXPECT_EQ(p
->statements
[2].effect
, Effect::Allow
);
359 act2
[s3ListMultipartUploadParts
] = 1;
360 act2
[s3ListBucket
] = 1;
361 act2
[s3ListBucketVersions
] = 1;
362 act2
[s3ListAllMyBuckets
] = 1;
363 act2
[s3ListBucketMultipartUploads
] = 1;
364 act2
[s3GetObject
] = 1;
365 act2
[s3GetObjectVersion
] = 1;
366 act2
[s3GetObjectAcl
] = 1;
367 act2
[s3GetObjectVersionAcl
] = 1;
368 act2
[s3GetObjectTorrent
] = 1;
369 act2
[s3GetObjectVersionTorrent
] = 1;
370 act2
[s3GetAccelerateConfiguration
] = 1;
371 act2
[s3GetBucketAcl
] = 1;
372 act2
[s3GetBucketCORS
] = 1;
373 act2
[s3GetBucketVersioning
] = 1;
374 act2
[s3GetBucketRequestPayment
] = 1;
375 act2
[s3GetBucketLocation
] = 1;
376 act2
[s3GetBucketPolicy
] = 1;
377 act2
[s3GetBucketNotification
] = 1;
378 act2
[s3GetBucketLogging
] = 1;
379 act2
[s3GetBucketTagging
] = 1;
380 act2
[s3GetBucketWebsite
] = 1;
381 act2
[s3GetLifecycleConfiguration
] = 1;
382 act2
[s3GetReplicationConfiguration
] = 1;
383 act2
[s3GetObjectTagging
] = 1;
384 act2
[s3GetObjectVersionTagging
] = 1;
385 act2
[s3GetBucketObjectLockConfiguration
] = 1;
386 act2
[s3GetObjectRetention
] = 1;
387 act2
[s3GetObjectLegalHold
] = 1;
388 act2
[s3GetBucketPolicyStatus
] = 1;
389 act2
[s3GetBucketPublicAccessBlock
] = 1;
390 act2
[s3GetPublicAccessBlock
] = 1;
391 act2
[s3GetBucketEncryption
] = 1;
393 EXPECT_EQ(p
->statements
[2].action
, act2
);
394 EXPECT_EQ(p
->statements
[2].notaction
, None
);
395 ASSERT_FALSE(p
->statements
[2].resource
.empty());
396 ASSERT_EQ(p
->statements
[2].resource
.size(), 2U);
397 EXPECT_EQ(p
->statements
[2].resource
.begin()->partition
, Partition::aws
);
398 EXPECT_EQ(p
->statements
[2].resource
.begin()->service
, Service::s3
);
399 EXPECT_TRUE(p
->statements
[2].resource
.begin()->region
.empty());
400 EXPECT_EQ(p
->statements
[2].resource
.begin()->account
, arbitrary_tenant
);
401 EXPECT_EQ(p
->statements
[2].resource
.begin()->resource
, "confidential-data");
402 EXPECT_EQ((p
->statements
[2].resource
.begin() + 1)->partition
,
404 EXPECT_EQ((p
->statements
[2].resource
.begin() + 1)->service
, Service::s3
);
405 EXPECT_TRUE((p
->statements
[2].resource
.begin() + 1)->region
.empty());
406 EXPECT_EQ((p
->statements
[2].resource
.begin() + 1)->account
,
408 EXPECT_EQ((p
->statements
[2].resource
.begin() + 1)->resource
,
409 "confidential-data/*");
410 EXPECT_TRUE(p
->statements
[2].notresource
.empty());
411 ASSERT_FALSE(p
->statements
[2].conditions
.empty());
412 ASSERT_EQ(p
->statements
[2].conditions
.size(), 1U);
413 EXPECT_EQ(p
->statements
[2].conditions
[0].op
, TokenID::Bool
);
414 EXPECT_EQ(p
->statements
[2].conditions
[0].key
, "aws:MultiFactorAuthPresent");
415 EXPECT_FALSE(p
->statements
[2].conditions
[0].ifexists
);
416 ASSERT_FALSE(p
->statements
[2].conditions
[0].vals
.empty());
417 EXPECT_EQ(p
->statements
[2].conditions
[0].vals
.size(), 1U);
418 EXPECT_EQ(p
->statements
[2].conditions
[0].vals
[0], "true");
421 TEST_F(PolicyTest
, Eval3
) {
422 auto p
= Policy(cct
.get(), arbitrary_tenant
,
423 bufferlist::static_from_string(example3
), true);
425 Environment tr
= { { "aws:MultiFactorAuthPresent", "true" } };
426 Environment fa
= { { "aws:MultiFactorAuthPresent", "false" } };
429 s3allow
[s3ListMultipartUploadParts
] = 1;
430 s3allow
[s3ListBucket
] = 1;
431 s3allow
[s3ListBucketVersions
] = 1;
432 s3allow
[s3ListAllMyBuckets
] = 1;
433 s3allow
[s3ListBucketMultipartUploads
] = 1;
434 s3allow
[s3GetObject
] = 1;
435 s3allow
[s3GetObjectVersion
] = 1;
436 s3allow
[s3GetObjectAcl
] = 1;
437 s3allow
[s3GetObjectVersionAcl
] = 1;
438 s3allow
[s3GetObjectTorrent
] = 1;
439 s3allow
[s3GetObjectVersionTorrent
] = 1;
440 s3allow
[s3GetAccelerateConfiguration
] = 1;
441 s3allow
[s3GetBucketAcl
] = 1;
442 s3allow
[s3GetBucketCORS
] = 1;
443 s3allow
[s3GetBucketVersioning
] = 1;
444 s3allow
[s3GetBucketRequestPayment
] = 1;
445 s3allow
[s3GetBucketLocation
] = 1;
446 s3allow
[s3GetBucketPolicy
] = 1;
447 s3allow
[s3GetBucketNotification
] = 1;
448 s3allow
[s3GetBucketLogging
] = 1;
449 s3allow
[s3GetBucketTagging
] = 1;
450 s3allow
[s3GetBucketWebsite
] = 1;
451 s3allow
[s3GetLifecycleConfiguration
] = 1;
452 s3allow
[s3GetReplicationConfiguration
] = 1;
453 s3allow
[s3GetObjectTagging
] = 1;
454 s3allow
[s3GetObjectVersionTagging
] = 1;
455 s3allow
[s3GetBucketObjectLockConfiguration
] = 1;
456 s3allow
[s3GetObjectRetention
] = 1;
457 s3allow
[s3GetObjectLegalHold
] = 1;
458 s3allow
[s3GetBucketPolicyStatus
] = 1;
459 s3allow
[s3GetBucketPublicAccessBlock
] = 1;
460 s3allow
[s3GetPublicAccessBlock
] = 1;
461 s3allow
[s3GetBucketEncryption
] = 1;
463 ARN
arn1(Partition::aws
, Service::s3
,
464 "", arbitrary_tenant
, "mybucket");
465 EXPECT_EQ(p
.eval(em
, none
, s3PutBucketPolicy
, arn1
),
468 ARN
arn2(Partition::aws
, Service::s3
,
469 "", arbitrary_tenant
, "mybucket");
470 EXPECT_EQ(p
.eval(em
, none
, s3PutBucketPolicy
, arn2
),
474 for (auto op
= 0ULL; op
< s3Count
; ++op
) {
475 if ((op
== s3ListAllMyBuckets
) || (op
== s3PutBucketPolicy
)) {
478 ARN
arn3(Partition::aws
, Service::s3
,
479 "", arbitrary_tenant
, "confidential-data");
480 EXPECT_EQ(p
.eval(em
, none
, op
, arn3
),
482 ARN
arn4(Partition::aws
, Service::s3
,
483 "", arbitrary_tenant
, "confidential-data");
484 EXPECT_EQ(p
.eval(tr
, none
, op
, arn4
),
485 s3allow
[op
] ? Effect::Allow
: Effect::Pass
);
486 ARN
arn5(Partition::aws
, Service::s3
,
487 "", arbitrary_tenant
, "confidential-data");
488 EXPECT_EQ(p
.eval(fa
, none
, op
, arn5
),
490 ARN
arn6(Partition::aws
, Service::s3
,
491 "", arbitrary_tenant
, "confidential-data/moo");
492 EXPECT_EQ(p
.eval(em
, none
, op
, arn6
),
494 ARN
arn7(Partition::aws
, Service::s3
,
495 "", arbitrary_tenant
, "confidential-data/moo");
496 EXPECT_EQ(p
.eval(tr
, none
, op
, arn7
),
497 s3allow
[op
] ? Effect::Allow
: Effect::Pass
);
498 ARN
arn8(Partition::aws
, Service::s3
,
499 "", arbitrary_tenant
, "confidential-data/moo");
500 EXPECT_EQ(p
.eval(fa
, none
, op
, arn8
),
502 ARN
arn9(Partition::aws
, Service::s3
,
503 "", arbitrary_tenant
, "really-confidential-data");
504 EXPECT_EQ(p
.eval(em
, none
, op
, arn9
),
506 ARN
arn10(Partition::aws
, Service::s3
,
507 "", arbitrary_tenant
, "really-confidential-data");
508 EXPECT_EQ(p
.eval(tr
, none
, op
, arn10
),
510 ARN
arn11(Partition::aws
, Service::s3
,
511 "", arbitrary_tenant
, "really-confidential-data");
512 EXPECT_EQ(p
.eval(fa
, none
, op
, arn11
),
514 ARN
arn12(Partition::aws
, Service::s3
,
515 "", arbitrary_tenant
,
516 "really-confidential-data/moo");
517 EXPECT_EQ(p
.eval(em
, none
, op
, arn12
), Effect::Pass
);
518 ARN
arn13(Partition::aws
, Service::s3
,
519 "", arbitrary_tenant
,
520 "really-confidential-data/moo");
521 EXPECT_EQ(p
.eval(tr
, none
, op
, arn13
), Effect::Pass
);
522 ARN
arn14(Partition::aws
, Service::s3
,
523 "", arbitrary_tenant
,
524 "really-confidential-data/moo");
525 EXPECT_EQ(p
.eval(fa
, none
, op
, arn14
), Effect::Pass
);
530 TEST_F(PolicyTest
, Parse4
) {
531 boost::optional
<Policy
> p
;
533 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
534 bufferlist::static_from_string(example4
), true));
537 EXPECT_EQ(p
->text
, example4
);
538 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
540 EXPECT_FALSE(p
->statements
[0].sid
);
541 EXPECT_FALSE(p
->statements
.empty());
542 EXPECT_EQ(p
->statements
.size(), 1U);
543 EXPECT_TRUE(p
->statements
[0].princ
.empty());
544 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
545 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
547 act
[iamCreateRole
] = 1;
548 EXPECT_EQ(p
->statements
[0].action
, act
);
549 EXPECT_EQ(p
->statements
[0].notaction
, None
);
550 ASSERT_FALSE(p
->statements
[0].resource
.empty());
551 ASSERT_EQ(p
->statements
[0].resource
.size(), 1U);
552 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::wildcard
);
553 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::wildcard
);
554 EXPECT_EQ(p
->statements
[0].resource
.begin()->region
, "*");
555 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
556 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "*");
557 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
558 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
561 TEST_F(PolicyTest
, Eval4
) {
562 auto p
= Policy(cct
.get(), arbitrary_tenant
,
563 bufferlist::static_from_string(example4
), true);
566 ARN
arn1(Partition::aws
, Service::iam
,
567 "", arbitrary_tenant
, "role/example_role");
568 EXPECT_EQ(p
.eval(e
, none
, iamCreateRole
, arn1
),
571 ARN
arn2(Partition::aws
, Service::iam
,
572 "", arbitrary_tenant
, "role/example_role");
573 EXPECT_EQ(p
.eval(e
, none
, iamDeleteRole
, arn2
),
577 TEST_F(PolicyTest
, Parse5
) {
578 boost::optional
<Policy
> p
;
580 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
581 bufferlist::static_from_string(example5
), true));
583 EXPECT_EQ(p
->text
, example5
);
584 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
586 EXPECT_FALSE(p
->statements
[0].sid
);
587 EXPECT_FALSE(p
->statements
.empty());
588 EXPECT_EQ(p
->statements
.size(), 1U);
589 EXPECT_TRUE(p
->statements
[0].princ
.empty());
590 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
591 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
593 for (auto i
= s3All
+1; i
<= iamAll
; i
++)
595 EXPECT_EQ(p
->statements
[0].action
, act
);
596 EXPECT_EQ(p
->statements
[0].notaction
, None
);
597 ASSERT_FALSE(p
->statements
[0].resource
.empty());
598 ASSERT_EQ(p
->statements
[0].resource
.size(), 1U);
599 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::aws
);
600 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::iam
);
601 EXPECT_EQ(p
->statements
[0].resource
.begin()->region
, "");
602 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
603 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "role/example_role");
604 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
605 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
608 TEST_F(PolicyTest
, Eval5
) {
609 auto p
= Policy(cct
.get(), arbitrary_tenant
,
610 bufferlist::static_from_string(example5
), true);
613 ARN
arn1(Partition::aws
, Service::iam
,
614 "", arbitrary_tenant
, "role/example_role");
615 EXPECT_EQ(p
.eval(e
, none
, iamCreateRole
, arn1
),
618 ARN
arn2(Partition::aws
, Service::iam
,
619 "", arbitrary_tenant
, "role/example_role");
620 EXPECT_EQ(p
.eval(e
, none
, s3ListBucket
, arn2
),
623 ARN
arn3(Partition::aws
, Service::iam
,
624 "", "", "role/example_role");
625 EXPECT_EQ(p
.eval(e
, none
, iamCreateRole
, arn3
),
629 TEST_F(PolicyTest
, Parse6
) {
630 boost::optional
<Policy
> p
;
632 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
633 bufferlist::static_from_string(example6
), true));
635 EXPECT_EQ(p
->text
, example6
);
636 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
638 EXPECT_FALSE(p
->statements
[0].sid
);
639 EXPECT_FALSE(p
->statements
.empty());
640 EXPECT_EQ(p
->statements
.size(), 1U);
641 EXPECT_TRUE(p
->statements
[0].princ
.empty());
642 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
643 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
645 for (auto i
= 0U; i
<= stsAll
; i
++)
647 EXPECT_EQ(p
->statements
[0].action
, act
);
648 EXPECT_EQ(p
->statements
[0].notaction
, None
);
649 ASSERT_FALSE(p
->statements
[0].resource
.empty());
650 ASSERT_EQ(p
->statements
[0].resource
.size(), 1U);
651 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::aws
);
652 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::iam
);
653 EXPECT_EQ(p
->statements
[0].resource
.begin()->region
, "");
654 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
655 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "user/A");
656 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
657 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
660 TEST_F(PolicyTest
, Eval6
) {
661 auto p
= Policy(cct
.get(), arbitrary_tenant
,
662 bufferlist::static_from_string(example6
), true);
665 ARN
arn1(Partition::aws
, Service::iam
,
666 "", arbitrary_tenant
, "user/A");
667 EXPECT_EQ(p
.eval(e
, none
, iamCreateRole
, arn1
),
670 ARN
arn2(Partition::aws
, Service::iam
,
671 "", arbitrary_tenant
, "user/A");
672 EXPECT_EQ(p
.eval(e
, none
, s3ListBucket
, arn2
),
676 TEST_F(PolicyTest
, Parse7
) {
677 boost::optional
<Policy
> p
;
679 ASSERT_NO_THROW(p
= Policy(cct
.get(), arbitrary_tenant
,
680 bufferlist::static_from_string(example7
), true));
683 EXPECT_EQ(p
->text
, example7
);
684 EXPECT_EQ(p
->version
, Version::v2012_10_17
);
685 ASSERT_FALSE(p
->statements
.empty());
686 EXPECT_EQ(p
->statements
.size(), 1U);
687 EXPECT_FALSE(p
->statements
[0].princ
.empty());
688 EXPECT_EQ(p
->statements
[0].princ
.size(), 1U);
689 EXPECT_TRUE(p
->statements
[0].noprinc
.empty());
690 EXPECT_EQ(p
->statements
[0].effect
, Effect::Allow
);
692 act
[s3ListBucket
] = 1;
693 EXPECT_EQ(p
->statements
[0].action
, act
);
694 EXPECT_EQ(p
->statements
[0].notaction
, None
);
695 ASSERT_FALSE(p
->statements
[0].resource
.empty());
696 ASSERT_EQ(p
->statements
[0].resource
.size(), 1U);
697 EXPECT_EQ(p
->statements
[0].resource
.begin()->partition
, Partition::aws
);
698 EXPECT_EQ(p
->statements
[0].resource
.begin()->service
, Service::s3
);
699 EXPECT_TRUE(p
->statements
[0].resource
.begin()->region
.empty());
700 EXPECT_EQ(p
->statements
[0].resource
.begin()->account
, arbitrary_tenant
);
701 EXPECT_EQ(p
->statements
[0].resource
.begin()->resource
, "mybucket/*");
702 EXPECT_TRUE(p
->statements
[0].princ
.begin()->is_user());
703 EXPECT_FALSE(p
->statements
[0].princ
.begin()->is_wildcard());
704 EXPECT_EQ(p
->statements
[0].princ
.begin()->get_tenant(), "");
705 EXPECT_EQ(p
->statements
[0].princ
.begin()->get_id(), "A:subA");
706 EXPECT_TRUE(p
->statements
[0].notresource
.empty());
707 EXPECT_TRUE(p
->statements
[0].conditions
.empty());
710 TEST_F(PolicyTest
, Eval7
) {
711 auto p
= Policy(cct
.get(), arbitrary_tenant
,
712 bufferlist::static_from_string(example7
), true);
715 auto subacct
= FakeIdentity(
716 Principal::user(std::move(""), "A:subA"));
717 auto parentacct
= FakeIdentity(
718 Principal::user(std::move(""), "A"));
719 auto sub2acct
= FakeIdentity(
720 Principal::user(std::move(""), "A:sub2A"));
722 ARN
arn1(Partition::aws
, Service::s3
,
723 "", arbitrary_tenant
, "mybucket/*");
724 EXPECT_EQ(p
.eval(e
, subacct
, s3ListBucket
, arn1
),
727 ARN
arn2(Partition::aws
, Service::s3
,
728 "", arbitrary_tenant
, "mybucket/*");
729 EXPECT_EQ(p
.eval(e
, parentacct
, s3ListBucket
, arn2
),
732 ARN
arn3(Partition::aws
, Service::s3
,
733 "", arbitrary_tenant
, "mybucket/*");
734 EXPECT_EQ(p
.eval(e
, sub2acct
, s3ListBucket
, arn3
),
738 const string
PolicyTest::arbitrary_tenant
= "arbitrary_tenant";
739 string
PolicyTest::example1
= R
"(
741 "Version
": "2012-10-17",
744 "Action
": "s3
:ListBucket
",
745 "Resource
": "arn
:aws
:s3:::example_bucket
"
750 string
PolicyTest::example2
= R
"(
752 "Version
": "2012-10-17",
753 "Id
": "S3
-Account
-Permissions
",
757 "Principal
": {"AWS
": ["arn
:aws
:iam::ACCOUNT
-ID
-WITHOUT
-HYPHENS
:root
"]},
760 "arn
:aws
:s3:::mybucket
",
761 "arn
:aws
:s3:::mybucket
/*"
767 string PolicyTest::example3 = R"(
769 "Version": "2012-10-17",
772 "Sid": "FirstStatement",
774 "Action": ["s3:PutBucketPolicy"],
778 "Sid": "SecondStatement",
780 "Action": "s3:ListAllMyBuckets",
784 "Sid": "ThirdStatement",
791 "arn:aws:s3:::confidential-data",
792 "arn:aws:s3:::confidential-data/*"
794 "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
800 string PolicyTest::example4 = R"(
802 "Version": "2012-10-17",
805 "Action": "iam:CreateRole",
811 string PolicyTest::example5 = R"(
813 "Version": "2012-10-17",
817 "Resource": "arn:aws:iam:::role/example_role"
822 string PolicyTest::example6 = R"(
824 "Version": "2012-10-17",
828 "Resource": "arn:aws:iam:::user/A"
833 string PolicyTest::example7 = R"(
835 "Version": "2012-10-17",
838 "Principal": {"AWS": ["arn:aws:iam:::user/A:subA"]},
839 "Action": "s3:ListBucket",
840 "Resource": "arn:aws:s3:::mybucket/*"
844 class IPPolicyTest : public ::testing::Test {
846 intrusive_ptr<CephContext> cct;
847 static const string arbitrary_tenant;
848 static string ip_address_allow_example;
849 static string ip_address_deny_example;
850 static string ip_address_full_example;
852 const rgw::IAM::MaskedIP allowedIPv4Range = { false, rgw::IAM::Address("11000000101010000000000100000000"), 24 };
854 const rgw::IAM::MaskedIP blocklistedIPv4 = { false, rgw::IAM::Address("11000000101010000000000100000001"), 32 };
855 // 2001:db8:85a3:0:0:8a2e:370:7334/128
856 const rgw::IAM::MaskedIP allowedIPv6 = { true, rgw::IAM::Address("00100000000000010000110110111000100001011010001100000000000000000000000000000000100010100010111000000011011100000111001100110100"), 128 };
858 const rgw::IAM::MaskedIP blocklistedIPv6 = { true, rgw::IAM::Address(1), 128 };
859 // 2001:db8:85a3:0:0:8a2e:370:7330/124
860 const rgw::IAM::MaskedIP allowedIPv6Range = { true, rgw::IAM::Address("00100000000000010000110110111000100001011010001100000000000000000000000000000000100010100010111000000011011100000111001100110000"), 124 };
863 cct = new CephContext(CEPH_ENTITY_TYPE_CLIENT);
866 const string IPPolicyTest::arbitrary_tenant = "arbitrary_tenant";
868 TEST_F(IPPolicyTest, MaskedIPOperations) {
869 EXPECT_EQ(stringify(allowedIPv4Range), "192.168.1.0/24");
870 EXPECT_EQ(stringify(blocklistedIPv4), "192.168.1.1/32");
871 EXPECT_EQ(stringify(allowedIPv6), "2001:db8:85a3:0:0:8a2e:370:7334/128");
872 EXPECT_EQ(stringify(allowedIPv6Range), "2001:db8:85a3:0:0:8a2e:370:7330/124");
873 EXPECT_EQ(stringify(blocklistedIPv6), "0:0:0:0:0:0:0:1/128");
874 EXPECT_EQ(allowedIPv4Range, blocklistedIPv4);
875 EXPECT_EQ(allowedIPv6Range, allowedIPv6);
878 TEST_F(IPPolicyTest, asNetworkIPv4Range) {
879 auto actualIPv4Range = rgw::IAM::Condition::as_network("192.168.1.0/24");
880 ASSERT_TRUE(actualIPv4Range.is_initialized());
881 EXPECT_EQ(*actualIPv4Range, allowedIPv4Range);
884 TEST_F(IPPolicyTest, asNetworkIPv4) {
885 auto actualIPv4 = rgw::IAM::Condition::as_network("192.168.1.1");
886 ASSERT_TRUE(actualIPv4.is_initialized());
887 EXPECT_EQ(*actualIPv4, blocklistedIPv4);
890 TEST_F(IPPolicyTest, asNetworkIPv6Range) {
891 auto actualIPv6Range = rgw::IAM::Condition::as_network("2001:db8:85a3:0:0:8a2e:370:7330/124");
892 ASSERT_TRUE(actualIPv6Range.is_initialized());
893 EXPECT_EQ(*actualIPv6Range, allowedIPv6Range);
896 TEST_F(IPPolicyTest, asNetworkIPv6) {
897 auto actualIPv6 = rgw::IAM::Condition::as_network("2001:db8:85a3:0:0:8a2e:370:7334");
898 ASSERT_TRUE(actualIPv6.is_initialized());
899 EXPECT_EQ(*actualIPv6, allowedIPv6);
902 TEST_F(IPPolicyTest, asNetworkInvalid) {
903 EXPECT_FALSE(rgw::IAM::Condition::as_network(""));
904 EXPECT_FALSE(rgw::IAM::Condition::as_network("192.168.1.1/33"));
905 EXPECT_FALSE(rgw::IAM::Condition::as_network("2001:db8:85a3:0:0:8a2e:370:7334/129"));
906 EXPECT_FALSE(rgw::IAM::Condition::as_network("192.168.1.1:"));
907 EXPECT_FALSE(rgw::IAM::Condition::as_network("1.2.3.10000"));
910 TEST_F(IPPolicyTest, IPEnvironment) {
912 // Unfortunately RGWCivetWeb is too tightly tied to civetweb to test RGWCivetWeb::init_env.
914 rgw::sal::RadosStore store;
915 std::unique_ptr<rgw::sal::User> user = store.get_user(rgw_user());
916 rgw_env.set("REMOTE_ADDR", "192.168.1.1");
917 rgw_env.set("HTTP_HOST", "1.2.3.4");
918 req_state rgw_req_state(cct.get(), penv, &rgw_env, 0);
919 rgw_req_state.set_user(user);
920 rgw_build_iam_environment(&store, &rgw_req_state);
921 auto ip = rgw_req_state.env.find("aws:SourceIp");
922 ASSERT_NE(ip, rgw_req_state.env.end());
923 EXPECT_EQ(ip->second, "192.168.1.1");
925 ASSERT_EQ(cct.get()->_conf.set_val("rgw_remote_addr_param", "SOME_VAR"), 0);
926 EXPECT_EQ(cct.get()->_conf->rgw_remote_addr_param, "SOME_VAR");
927 rgw_req_state.env.clear();
928 rgw_build_iam_environment(&store, &rgw_req_state);
929 ip = rgw_req_state.env.find("aws:SourceIp");
930 EXPECT_EQ(ip, rgw_req_state.env.end());
932 rgw_env.set("SOME_VAR", "192.168.1.2");
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.2");
939 ASSERT_EQ(cct.get()->_conf.set_val("rgw_remote_addr_param", "HTTP_X_FORWARDED_FOR"), 0);
940 rgw_env.set("HTTP_X_FORWARDED_FOR", "192.168.1.3");
941 rgw_req_state.env.clear();
942 rgw_build_iam_environment(&store, &rgw_req_state);
943 ip = rgw_req_state.env.find("aws:SourceIp");
944 ASSERT_NE(ip, rgw_req_state.env.end());
945 EXPECT_EQ(ip->second, "192.168.1.3");
947 rgw_env.set("HTTP_X_FORWARDED_FOR", "192.168.1.4, 4.3.2.1, 2001:db8:85a3:8d3:1319:8a2e:370:7348");
948 rgw_req_state.env.clear();
949 rgw_build_iam_environment(&store, &rgw_req_state);
950 ip = rgw_req_state.env.find("aws:SourceIp");
951 ASSERT_NE(ip, rgw_req_state.env.end());
952 EXPECT_EQ(ip->second, "192.168.1.4");
955 TEST_F(IPPolicyTest, ParseIPAddress) {
956 boost::optional<Policy> p;
959 p = Policy(cct.get(), arbitrary_tenant,
960 bufferlist::static_from_string(ip_address_full_example), true));
963 EXPECT_EQ(p->text, ip_address_full_example);
964 EXPECT_EQ(p->version, Version::v2012_10_17);
965 EXPECT_EQ(*p->id, "S3IPPolicyTest");
966 EXPECT_FALSE(p->statements.empty());
967 EXPECT_EQ(p->statements.size(), 1U);
968 EXPECT_EQ(*p->statements[0].sid, "IPAllow");
969 EXPECT_FALSE(p->statements[0].princ.empty());
970 EXPECT_EQ(p->statements[0].princ.size(), 1U);
971 EXPECT_EQ(*p->statements[0].princ.begin(),
972 Principal::wildcard());
973 EXPECT_TRUE(p->statements[0].noprinc.empty());
974 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
976 act[s3ListBucket] = 1;
977 EXPECT_EQ(p->statements[0].action, act);
978 EXPECT_EQ(p->statements[0].notaction, None);
979 ASSERT_FALSE(p->statements[0].resource.empty());
980 ASSERT_EQ(p->statements[0].resource.size(), 2U);
981 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::aws);
982 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::s3);
983 EXPECT_TRUE(p->statements[0].resource.begin()->region.empty());
984 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
985 EXPECT_EQ(p->statements[0].resource.begin()->resource, "example_bucket");
986 EXPECT_EQ((p->statements[0].resource.begin() + 1)->resource, "example_bucket/*");
987 EXPECT_TRUE(p->statements[0].notresource.empty());
988 ASSERT_FALSE(p->statements[0].conditions.empty());
989 ASSERT_EQ(p->statements[0].conditions.size(), 2U);
990 EXPECT_EQ(p->statements[0].conditions[0].op, TokenID::IpAddress);
991 EXPECT_EQ(p->statements[0].conditions[0].key, "aws:SourceIp");
992 ASSERT_FALSE(p->statements[0].conditions[0].vals.empty());
993 EXPECT_EQ(p->statements[0].conditions[0].vals.size(), 2U);
994 EXPECT_EQ(p->statements[0].conditions[0].vals[0], "192.168.1.0/24");
995 EXPECT_EQ(p->statements[0].conditions[0].vals[1], "::1");
996 boost::optional<rgw::IAM::MaskedIP> convertedIPv4 = rgw::IAM::Condition::as_network(p->statements[0].conditions[0].vals[0]);
997 EXPECT_TRUE(convertedIPv4.is_initialized());
998 if (convertedIPv4.is_initialized()) {
999 EXPECT_EQ(*convertedIPv4, allowedIPv4Range);
1002 EXPECT_EQ(p->statements[0].conditions[1].op, TokenID::NotIpAddress);
1003 EXPECT_EQ(p->statements[0].conditions[1].key, "aws:SourceIp");
1004 ASSERT_FALSE(p->statements[0].conditions[1].vals.empty());
1005 EXPECT_EQ(p->statements[0].conditions[1].vals.size(), 2U);
1006 EXPECT_EQ(p->statements[0].conditions[1].vals[0], "192.168.1.1/32");
1007 EXPECT_EQ(p->statements[0].conditions[1].vals[1], "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
1008 boost::optional<rgw::IAM::MaskedIP> convertedIPv6 = rgw::IAM::Condition::as_network(p->statements[0].conditions[1].vals[1]);
1009 EXPECT_TRUE(convertedIPv6.is_initialized());
1010 if (convertedIPv6.is_initialized()) {
1011 EXPECT_EQ(*convertedIPv6, allowedIPv6);
1015 TEST_F(IPPolicyTest, EvalIPAddress) {
1017 Policy(cct.get(), arbitrary_tenant,
1018 bufferlist::static_from_string(ip_address_allow_example), true);
1020 Policy(cct.get(), arbitrary_tenant,
1021 bufferlist::static_from_string(ip_address_deny_example), true);
1023 Policy(cct.get(), arbitrary_tenant,
1024 bufferlist::static_from_string(ip_address_full_example), true);
1026 Environment allowedIP, blocklistedIP, allowedIPv6, blocklistedIPv6;
1027 allowedIP.emplace("aws:SourceIp","192.168.1.2");
1028 allowedIPv6.emplace("aws:SourceIp", "::1");
1029 blocklistedIP.emplace("aws:SourceIp", "192.168.1.1");
1030 blocklistedIPv6.emplace("aws:SourceIp", "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
1032 auto trueacct = FakeIdentity(
1033 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
1034 // Without an IP address in the environment then evaluation will always pass
1035 ARN arn1(Partition::aws, Service::s3,
1036 "", arbitrary_tenant, "example_bucket");
1037 EXPECT_EQ(allowp.eval(e, trueacct, s3ListBucket, arn1),
1039 ARN arn2(Partition::aws, Service::s3,
1040 "", arbitrary_tenant, "example_bucket/myobject");
1041 EXPECT_EQ(fullp.eval(e, trueacct, s3ListBucket, arn2),
1044 ARN arn3(Partition::aws, Service::s3,
1045 "", arbitrary_tenant, "example_bucket");
1046 EXPECT_EQ(allowp.eval(allowedIP, trueacct, s3ListBucket, arn3),
1048 ARN arn4(Partition::aws, Service::s3,
1049 "", arbitrary_tenant, "example_bucket");
1050 EXPECT_EQ(allowp.eval(blocklistedIPv6, trueacct, s3ListBucket, arn4),
1053 ARN arn5(Partition::aws, Service::s3,
1054 "", arbitrary_tenant, "example_bucket");
1055 EXPECT_EQ(denyp.eval(allowedIP, trueacct, s3ListBucket, arn5),
1057 ARN arn6(Partition::aws, Service::s3,
1058 "", arbitrary_tenant, "example_bucket/myobject");
1059 EXPECT_EQ(denyp.eval(allowedIP, trueacct, s3ListBucket, arn6),
1062 ARN arn7(Partition::aws, Service::s3,
1063 "", arbitrary_tenant, "example_bucket");
1064 EXPECT_EQ(denyp.eval(blocklistedIP, trueacct, s3ListBucket, arn7),
1066 ARN arn8(Partition::aws, Service::s3,
1067 "", arbitrary_tenant, "example_bucket/myobject");
1068 EXPECT_EQ(denyp.eval(blocklistedIP, trueacct, s3ListBucket, arn8),
1071 ARN arn9(Partition::aws, Service::s3,
1072 "", arbitrary_tenant, "example_bucket");
1073 EXPECT_EQ(denyp.eval(blocklistedIPv6, trueacct, s3ListBucket, arn9),
1075 ARN arn10(Partition::aws, Service::s3,
1076 "", arbitrary_tenant, "example_bucket/myobject");
1077 EXPECT_EQ(denyp.eval(blocklistedIPv6, trueacct, s3ListBucket, arn10),
1079 ARN arn11(Partition::aws, Service::s3,
1080 "", arbitrary_tenant, "example_bucket");
1081 EXPECT_EQ(denyp.eval(allowedIPv6, trueacct, s3ListBucket, arn11),
1083 ARN arn12(Partition::aws, Service::s3,
1084 "", arbitrary_tenant, "example_bucket/myobject");
1085 EXPECT_EQ(denyp.eval(allowedIPv6, trueacct, s3ListBucket, arn12),
1088 ARN arn13(Partition::aws, Service::s3,
1089 "", arbitrary_tenant, "example_bucket");
1090 EXPECT_EQ(fullp.eval(allowedIP, trueacct, s3ListBucket, arn13),
1092 ARN arn14(Partition::aws, Service::s3,
1093 "", arbitrary_tenant, "example_bucket/myobject");
1094 EXPECT_EQ(fullp.eval(allowedIP, trueacct, s3ListBucket, arn14),
1097 ARN arn15(Partition::aws, Service::s3,
1098 "", arbitrary_tenant, "example_bucket");
1099 EXPECT_EQ(fullp.eval(blocklistedIP, trueacct, s3ListBucket, arn15),
1101 ARN arn16(Partition::aws, Service::s3,
1102 "", arbitrary_tenant, "example_bucket/myobject");
1103 EXPECT_EQ(fullp.eval(blocklistedIP, trueacct, s3ListBucket, arn16),
1106 ARN arn17(Partition::aws, Service::s3,
1107 "", arbitrary_tenant, "example_bucket");
1108 EXPECT_EQ(fullp.eval(allowedIPv6, trueacct, s3ListBucket, arn17),
1110 ARN arn18(Partition::aws, Service::s3,
1111 "", arbitrary_tenant, "example_bucket/myobject");
1112 EXPECT_EQ(fullp.eval(allowedIPv6, trueacct, s3ListBucket, arn18),
1115 ARN arn19(Partition::aws, Service::s3,
1116 "", arbitrary_tenant, "example_bucket");
1117 EXPECT_EQ(fullp.eval(blocklistedIPv6, trueacct, s3ListBucket, arn19),
1119 ARN arn20(Partition::aws, Service::s3,
1120 "", arbitrary_tenant, "example_bucket/myobject");
1121 EXPECT_EQ(fullp.eval(blocklistedIPv6, trueacct, s3ListBucket, arn20),
1125 string IPPolicyTest::ip_address_allow_example = R"(
1127 "Version": "2012-10-17",
1128 "Id": "S3SimpleIPPolicyTest",
1132 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
1133 "Action": "s3:ListBucket",
1135 "arn:aws:s3:::example_bucket"
1138 "IpAddress": {"aws:SourceIp": "192.168.1.0/24"}
1144 string IPPolicyTest::ip_address_deny_example = R"(
1146 "Version": "2012-10-17",
1147 "Id": "S3IPPolicyTest",
1151 "Action": "s3:ListBucket",
1152 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
1154 "arn:aws:s3:::example_bucket",
1155 "arn:aws:s3:::example_bucket/*"
1158 "NotIpAddress": {"aws:SourceIp": ["192.168.1.1/32", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]}
1164 string IPPolicyTest::ip_address_full_example = R"(
1166 "Version": "2012-10-17",
1167 "Id": "S3IPPolicyTest",
1171 "Action": "s3:ListBucket",
1174 "arn:aws:s3:::example_bucket",
1175 "arn:aws:s3:::example_bucket/*"
1178 "IpAddress": {"aws:SourceIp": ["192.168.1.0/24", "::1"]},
1179 "NotIpAddress": {"aws:SourceIp": ["192.168.1.1/32", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]}
1185 TEST(MatchWildcards, Simple)
1187 EXPECT_TRUE(match_wildcards("", ""));
1188 EXPECT_TRUE(match_wildcards("", "", MATCH_CASE_INSENSITIVE));
1189 EXPECT_FALSE(match_wildcards("", "abc"));
1190 EXPECT_FALSE(match_wildcards("", "abc", MATCH_CASE_INSENSITIVE));
1191 EXPECT_FALSE(match_wildcards("abc", ""));
1192 EXPECT_FALSE(match_wildcards("abc", "", MATCH_CASE_INSENSITIVE));
1193 EXPECT_TRUE(match_wildcards("abc", "abc"));
1194 EXPECT_TRUE(match_wildcards("abc", "abc", MATCH_CASE_INSENSITIVE));
1195 EXPECT_FALSE(match_wildcards("abc", "abC"));
1196 EXPECT_TRUE(match_wildcards("abc", "abC", MATCH_CASE_INSENSITIVE));
1197 EXPECT_FALSE(match_wildcards("abC", "abc"));
1198 EXPECT_TRUE(match_wildcards("abC", "abc", MATCH_CASE_INSENSITIVE));
1199 EXPECT_FALSE(match_wildcards("abc", "abcd"));
1200 EXPECT_FALSE(match_wildcards("abc", "abcd", MATCH_CASE_INSENSITIVE));
1201 EXPECT_FALSE(match_wildcards("abcd", "abc"));
1202 EXPECT_FALSE(match_wildcards("abcd", "abc", MATCH_CASE_INSENSITIVE));
1205 TEST(MatchWildcards, QuestionMark)
1207 EXPECT_FALSE(match_wildcards("?", ""));
1208 EXPECT_FALSE(match_wildcards("?", "", MATCH_CASE_INSENSITIVE));
1209 EXPECT_TRUE(match_wildcards("?", "a"));
1210 EXPECT_TRUE(match_wildcards("?", "a", MATCH_CASE_INSENSITIVE));
1211 EXPECT_TRUE(match_wildcards("?bc", "abc"));
1212 EXPECT_TRUE(match_wildcards("?bc", "abc", MATCH_CASE_INSENSITIVE));
1213 EXPECT_TRUE(match_wildcards("a?c", "abc"));
1214 EXPECT_TRUE(match_wildcards("a?c", "abc", MATCH_CASE_INSENSITIVE));
1215 EXPECT_FALSE(match_wildcards("abc", "a?c"));
1216 EXPECT_FALSE(match_wildcards("abc", "a?c", MATCH_CASE_INSENSITIVE));
1217 EXPECT_FALSE(match_wildcards("a?c", "abC"));
1218 EXPECT_TRUE(match_wildcards("a?c", "abC", MATCH_CASE_INSENSITIVE));
1219 EXPECT_TRUE(match_wildcards("ab?", "abc"));
1220 EXPECT_TRUE(match_wildcards("ab?", "abc", MATCH_CASE_INSENSITIVE));
1221 EXPECT_TRUE(match_wildcards("a?c?e", "abcde"));
1222 EXPECT_TRUE(match_wildcards("a?c?e", "abcde", MATCH_CASE_INSENSITIVE));
1223 EXPECT_TRUE(match_wildcards("???", "abc"));
1224 EXPECT_TRUE(match_wildcards("???", "abc", MATCH_CASE_INSENSITIVE));
1225 EXPECT_FALSE(match_wildcards("???", "abcd"));
1226 EXPECT_FALSE(match_wildcards("???", "abcd", MATCH_CASE_INSENSITIVE));
1229 TEST(MatchWildcards, Asterisk)
1231 EXPECT_TRUE(match_wildcards("*", ""));
1232 EXPECT_TRUE(match_wildcards("*", "", MATCH_CASE_INSENSITIVE));
1233 EXPECT_FALSE(match_wildcards("", "*"));
1234 EXPECT_FALSE(match_wildcards("", "*", MATCH_CASE_INSENSITIVE));
1235 EXPECT_FALSE(match_wildcards("*a", ""));
1236 EXPECT_FALSE(match_wildcards("*a", "", MATCH_CASE_INSENSITIVE));
1237 EXPECT_TRUE(match_wildcards("*a", "a"));
1238 EXPECT_TRUE(match_wildcards("*a", "a", MATCH_CASE_INSENSITIVE));
1239 EXPECT_TRUE(match_wildcards("a*", "a"));
1240 EXPECT_TRUE(match_wildcards("a*", "a", MATCH_CASE_INSENSITIVE));
1241 EXPECT_TRUE(match_wildcards("a*c", "ac"));
1242 EXPECT_TRUE(match_wildcards("a*c", "ac", MATCH_CASE_INSENSITIVE));
1243 EXPECT_TRUE(match_wildcards("a*c", "abbc"));
1244 EXPECT_TRUE(match_wildcards("a*c", "abbc", MATCH_CASE_INSENSITIVE));
1245 EXPECT_FALSE(match_wildcards("a*c", "abbC"));
1246 EXPECT_TRUE(match_wildcards("a*c", "abbC", MATCH_CASE_INSENSITIVE));
1247 EXPECT_TRUE(match_wildcards("a*c*e", "abBce"));
1248 EXPECT_TRUE(match_wildcards("a*c*e", "abBce", MATCH_CASE_INSENSITIVE));
1249 EXPECT_TRUE(match_wildcards("http://*.example.com",
1250 "http://www.example.com"));
1251 EXPECT_TRUE(match_wildcards("http://*.example.com",
1252 "http://www.example.com", MATCH_CASE_INSENSITIVE));
1253 EXPECT_FALSE(match_wildcards("http://*.example.com",
1254 "http://www.Example.com"));
1255 EXPECT_TRUE(match_wildcards("http://*.example.com",
1256 "http://www.Example.com", MATCH_CASE_INSENSITIVE));
1257 EXPECT_TRUE(match_wildcards("http://example.com/*",
1258 "http://example.com/index.html"));
1259 EXPECT_TRUE(match_wildcards("http://example.com/*/*.jpg",
1260 "http://example.com/fun/smiley.jpg"));
1261 // note: parsing of * is not greedy, so * does not match 'bc' here
1262 EXPECT_FALSE(match_wildcards("a*c", "abcc"));
1263 EXPECT_FALSE(match_wildcards("a*c", "abcc", MATCH_CASE_INSENSITIVE));
1266 TEST(MatchPolicy, Action)
1268 constexpr auto flag = MATCH_POLICY_ACTION;
1269 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
1270 EXPECT_TRUE(match_policy("a:b:c", "A:B:C", flag)); // case insensitive
1271 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
1272 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
1275 TEST(MatchPolicy, Resource)
1277 constexpr auto flag = MATCH_POLICY_RESOURCE;
1278 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
1279 EXPECT_FALSE(match_policy("a:b:c", "A:B:C", flag)); // case sensitive
1280 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
1281 EXPECT_TRUE(match_policy("a:*", "a:b:c", flag)); // can span segments
1284 TEST(MatchPolicy, ARN)
1286 constexpr auto flag = MATCH_POLICY_ARN;
1287 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
1288 EXPECT_TRUE(match_policy("a:b:c", "A:B:C", flag)); // case insensitive
1289 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
1290 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
1293 TEST(MatchPolicy, String)
1295 constexpr auto flag = MATCH_POLICY_STRING;
1296 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
1297 EXPECT_FALSE(match_policy("a:b:c", "A:B:C", flag)); // case sensitive
1298 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
1299 EXPECT_TRUE(match_policy("a:*", "a:b:c", flag)); // can span segments
1302 Action_t set_range_bits(std::uint64_t start, std::uint64_t end)
1305 for (uint64_t i = start; i < end; i++) {
1311 using rgw::IAM::s3AllValue;
1312 using rgw::IAM::stsAllValue;
1313 using rgw::IAM::allValue;
1314 using rgw::IAM::iamAllValue;
1315 TEST(set_cont_bits, iamconsts)
1317 EXPECT_EQ(s3AllValue, set_range_bits(0, s3All));
1318 EXPECT_EQ(iamAllValue, set_range_bits(s3All+1, iamAll));
1319 EXPECT_EQ(stsAllValue, set_range_bits(iamAll+1, stsAll));
1320 EXPECT_EQ(allValue , set_range_bits(0, allCount));