]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rgw/test_rgw_iam_policy.cc
update ceph source to reef 18.1.2
[ceph.git] / ceph / src / test / rgw / test_rgw_iam_policy.cc
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
3 /*
4 * Ceph - scalable distributed file system
5 *
6 * Copyright (C) 2015 Red Hat
7 *
8 * This is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License version 2.1, as published by the Free Software
11 * Foundation. See file COPYING.
12 *
13 */
14
15 #include <string>
16
17 #include <boost/intrusive_ptr.hpp>
18 #include <boost/optional.hpp>
19
20 #include <gtest/gtest.h>
21
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_auth.h"
27 #include "rgw_auth_registry.h"
28 #include "rgw_iam_policy.h"
29 #include "rgw_op.h"
30 #include "rgw_process_env.h"
31 #include "rgw_sal_rados.h"
32
33
34 using std::string;
35 using std::vector;
36
37 using boost::container::flat_set;
38 using boost::intrusive_ptr;
39 using boost::make_optional;
40 using boost::none;
41
42 using rgw::auth::Identity;
43 using rgw::auth::Principal;
44
45 using rgw::ARN;
46 using rgw::IAM::Effect;
47 using rgw::IAM::Environment;
48 using rgw::Partition;
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;
82 using rgw::IAM::None;
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;
88 using rgw::Service;
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;
98
99 class FakeIdentity : public Identity {
100 const Principal id;
101 public:
102
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 {
105 ceph_abort();
106 return 0;
107 };
108
109 bool is_admin_of(const rgw_user& uid) const override {
110 ceph_abort();
111 return false;
112 }
113
114 bool is_owner_of(const rgw_user& uid) const override {
115 ceph_abort();
116 return false;
117 }
118
119 virtual uint32_t get_perm_mask() const override {
120 ceph_abort();
121 return 0;
122 }
123
124 string get_acct_name() const override {
125 abort();
126 return 0;
127 }
128
129 string get_subuser() const override {
130 abort();
131 return 0;
132 }
133
134 void to_str(std::ostream& out) const override {
135 out << id;
136 }
137
138 bool is_identity(const flat_set<Principal>& ids) const override {
139 if (id.is_wildcard() && (!ids.empty())) {
140 return true;
141 }
142 return ids.find(id) != ids.end() || ids.find(Principal::wildcard()) != ids.end();
143 }
144
145 uint32_t get_identity_type() const override {
146 return TYPE_RGW;
147 }
148 };
149
150 class PolicyTest : public ::testing::Test {
151 protected:
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;
161 public:
162 PolicyTest() {
163 cct = new CephContext(CEPH_ENTITY_TYPE_CLIENT);
164 }
165 };
166
167 TEST_F(PolicyTest, Parse1) {
168 boost::optional<Policy> p;
169
170 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
171 bufferlist::static_from_string(example1),
172 true));
173 ASSERT_TRUE(p);
174
175 EXPECT_EQ(p->text, example1);
176 EXPECT_EQ(p->version, Version::v2012_10_17);
177 EXPECT_FALSE(p->id);
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);
184 Action_t act;
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());
197 }
198
199 TEST_F(PolicyTest, Eval1) {
200 auto p = Policy(cct.get(), arbitrary_tenant,
201 bufferlist::static_from_string(example1), true);
202 Environment e;
203
204 ARN arn1(Partition::aws, Service::s3,
205 "", arbitrary_tenant, "example_bucket");
206 EXPECT_EQ(p.eval(e, none, s3ListBucket, arn1),
207 Effect::Allow);
208
209 ARN arn2(Partition::aws, Service::s3,
210 "", arbitrary_tenant, "example_bucket");
211 EXPECT_EQ(p.eval(e, none, s3PutBucketAcl, arn2),
212 Effect::Pass);
213
214 ARN arn3(Partition::aws, Service::s3,
215 "", arbitrary_tenant, "erroneous_bucket");
216 EXPECT_EQ(p.eval(e, none, s3ListBucket, arn3),
217 Effect::Pass);
218
219 }
220
221 TEST_F(PolicyTest, Parse2) {
222 boost::optional<Policy> p;
223
224 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
225 bufferlist::static_from_string(example2),
226 true));
227 ASSERT_TRUE(p);
228
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);
241 Action_t act;
242 for (auto i = 0ULL; i < s3Count; i++)
243 act[i] = 1;
244 act[s3All] = 1;
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,
255 Partition::aws);
256 EXPECT_EQ((p->statements[0].resource.begin() + 1)->service,
257 Service::s3);
258 EXPECT_TRUE((p->statements[0].resource.begin() + 1)->region.empty());
259 EXPECT_EQ((p->statements[0].resource.begin() + 1)->account,
260 arbitrary_tenant);
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());
264 }
265
266 TEST_F(PolicyTest, Eval2) {
267 auto p = Policy(cct.get(), arbitrary_tenant,
268 bufferlist::static_from_string(example2), true);
269 Environment e;
270
271 auto trueacct = FakeIdentity(
272 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
273
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),
280 Effect::Allow);
281 ARN arn2(Partition::aws, Service::s3,
282 "", arbitrary_tenant, "mybucket/myobject");
283 EXPECT_EQ(p.eval(e, trueacct, i, arn2),
284 Effect::Allow);
285 ARN arn3(Partition::aws, Service::s3,
286 "", arbitrary_tenant, "mybucket");
287 EXPECT_EQ(p.eval(e, notacct, i, arn3),
288 Effect::Pass);
289 ARN arn4(Partition::aws, Service::s3,
290 "", arbitrary_tenant, "mybucket/myobject");
291 EXPECT_EQ(p.eval(e, notacct, i, arn4),
292 Effect::Pass);
293 ARN arn5(Partition::aws, Service::s3,
294 "", arbitrary_tenant, "notyourbucket");
295 EXPECT_EQ(p.eval(e, trueacct, i, arn5),
296 Effect::Pass);
297 ARN arn6(Partition::aws, Service::s3,
298 "", arbitrary_tenant, "notyourbucket/notyourobject");
299 EXPECT_EQ(p.eval(e, trueacct, i, arn6),
300 Effect::Pass);
301
302 }
303 }
304
305 TEST_F(PolicyTest, Parse3) {
306 boost::optional<Policy> p;
307
308 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
309 bufferlist::static_from_string(example3), true));
310 ASSERT_TRUE(p);
311
312 EXPECT_EQ(p->text, example3);
313 EXPECT_EQ(p->version, Version::v2012_10_17);
314 EXPECT_FALSE(p->id);
315 ASSERT_FALSE(p->statements.empty());
316 EXPECT_EQ(p->statements.size(), 3U);
317
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);
322 Action_t act;
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());
335
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);
340 Action_t act1;
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());
353
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);
358 Action_t act2;
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;
392
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,
403 Partition::aws);
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,
407 arbitrary_tenant);
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");
419 }
420
421 TEST_F(PolicyTest, Eval3) {
422 auto p = Policy(cct.get(), arbitrary_tenant,
423 bufferlist::static_from_string(example3), true);
424 Environment em;
425 Environment tr = { { "aws:MultiFactorAuthPresent", "true" } };
426 Environment fa = { { "aws:MultiFactorAuthPresent", "false" } };
427
428 Action_t s3allow;
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;
462
463 ARN arn1(Partition::aws, Service::s3,
464 "", arbitrary_tenant, "mybucket");
465 EXPECT_EQ(p.eval(em, none, s3PutBucketPolicy, arn1),
466 Effect::Allow);
467
468 ARN arn2(Partition::aws, Service::s3,
469 "", arbitrary_tenant, "mybucket");
470 EXPECT_EQ(p.eval(em, none, s3PutBucketPolicy, arn2),
471 Effect::Allow);
472
473
474 for (auto op = 0ULL; op < s3Count; ++op) {
475 if ((op == s3ListAllMyBuckets) || (op == s3PutBucketPolicy)) {
476 continue;
477 }
478 ARN arn3(Partition::aws, Service::s3,
479 "", arbitrary_tenant, "confidential-data");
480 EXPECT_EQ(p.eval(em, none, op, arn3),
481 Effect::Pass);
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),
489 Effect::Pass);
490 ARN arn6(Partition::aws, Service::s3,
491 "", arbitrary_tenant, "confidential-data/moo");
492 EXPECT_EQ(p.eval(em, none, op, arn6),
493 Effect::Pass);
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),
501 Effect::Pass);
502 ARN arn9(Partition::aws, Service::s3,
503 "", arbitrary_tenant, "really-confidential-data");
504 EXPECT_EQ(p.eval(em, none, op, arn9),
505 Effect::Pass);
506 ARN arn10(Partition::aws, Service::s3,
507 "", arbitrary_tenant, "really-confidential-data");
508 EXPECT_EQ(p.eval(tr, none, op, arn10),
509 Effect::Pass);
510 ARN arn11(Partition::aws, Service::s3,
511 "", arbitrary_tenant, "really-confidential-data");
512 EXPECT_EQ(p.eval(fa, none, op, arn11),
513 Effect::Pass);
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);
526
527 }
528 }
529
530 TEST_F(PolicyTest, Parse4) {
531 boost::optional<Policy> p;
532
533 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
534 bufferlist::static_from_string(example4), true));
535 ASSERT_TRUE(p);
536
537 EXPECT_EQ(p->text, example4);
538 EXPECT_EQ(p->version, Version::v2012_10_17);
539 EXPECT_FALSE(p->id);
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);
546 Action_t act;
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());
559 }
560
561 TEST_F(PolicyTest, Eval4) {
562 auto p = Policy(cct.get(), arbitrary_tenant,
563 bufferlist::static_from_string(example4), true);
564 Environment e;
565
566 ARN arn1(Partition::aws, Service::iam,
567 "", arbitrary_tenant, "role/example_role");
568 EXPECT_EQ(p.eval(e, none, iamCreateRole, arn1),
569 Effect::Allow);
570
571 ARN arn2(Partition::aws, Service::iam,
572 "", arbitrary_tenant, "role/example_role");
573 EXPECT_EQ(p.eval(e, none, iamDeleteRole, arn2),
574 Effect::Pass);
575 }
576
577 TEST_F(PolicyTest, Parse5) {
578 boost::optional<Policy> p;
579
580 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
581 bufferlist::static_from_string(example5), true));
582 ASSERT_TRUE(p);
583 EXPECT_EQ(p->text, example5);
584 EXPECT_EQ(p->version, Version::v2012_10_17);
585 EXPECT_FALSE(p->id);
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);
592 Action_t act;
593 for (auto i = s3All+1; i <= iamAll; i++)
594 act[i] = 1;
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());
606 }
607
608 TEST_F(PolicyTest, Eval5) {
609 auto p = Policy(cct.get(), arbitrary_tenant,
610 bufferlist::static_from_string(example5), true);
611 Environment e;
612
613 ARN arn1(Partition::aws, Service::iam,
614 "", arbitrary_tenant, "role/example_role");
615 EXPECT_EQ(p.eval(e, none, iamCreateRole, arn1),
616 Effect::Allow);
617
618 ARN arn2(Partition::aws, Service::iam,
619 "", arbitrary_tenant, "role/example_role");
620 EXPECT_EQ(p.eval(e, none, s3ListBucket, arn2),
621 Effect::Pass);
622
623 ARN arn3(Partition::aws, Service::iam,
624 "", "", "role/example_role");
625 EXPECT_EQ(p.eval(e, none, iamCreateRole, arn3),
626 Effect::Pass);
627 }
628
629 TEST_F(PolicyTest, Parse6) {
630 boost::optional<Policy> p;
631
632 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
633 bufferlist::static_from_string(example6), true));
634 ASSERT_TRUE(p);
635 EXPECT_EQ(p->text, example6);
636 EXPECT_EQ(p->version, Version::v2012_10_17);
637 EXPECT_FALSE(p->id);
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);
644 Action_t act;
645 for (auto i = 0U; i <= stsAll; i++)
646 act[i] = 1;
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());
658 }
659
660 TEST_F(PolicyTest, Eval6) {
661 auto p = Policy(cct.get(), arbitrary_tenant,
662 bufferlist::static_from_string(example6), true);
663 Environment e;
664
665 ARN arn1(Partition::aws, Service::iam,
666 "", arbitrary_tenant, "user/A");
667 EXPECT_EQ(p.eval(e, none, iamCreateRole, arn1),
668 Effect::Allow);
669
670 ARN arn2(Partition::aws, Service::iam,
671 "", arbitrary_tenant, "user/A");
672 EXPECT_EQ(p.eval(e, none, s3ListBucket, arn2),
673 Effect::Allow);
674 }
675
676 TEST_F(PolicyTest, Parse7) {
677 boost::optional<Policy> p;
678
679 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
680 bufferlist::static_from_string(example7), true));
681 ASSERT_TRUE(p);
682
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);
691 Action_t act;
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());
708 }
709
710 TEST_F(PolicyTest, Eval7) {
711 auto p = Policy(cct.get(), arbitrary_tenant,
712 bufferlist::static_from_string(example7), true);
713 Environment e;
714
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"));
721
722 ARN arn1(Partition::aws, Service::s3,
723 "", arbitrary_tenant, "mybucket/*");
724 EXPECT_EQ(p.eval(e, subacct, s3ListBucket, arn1),
725 Effect::Allow);
726
727 ARN arn2(Partition::aws, Service::s3,
728 "", arbitrary_tenant, "mybucket/*");
729 EXPECT_EQ(p.eval(e, parentacct, s3ListBucket, arn2),
730 Effect::Pass);
731
732 ARN arn3(Partition::aws, Service::s3,
733 "", arbitrary_tenant, "mybucket/*");
734 EXPECT_EQ(p.eval(e, sub2acct, s3ListBucket, arn3),
735 Effect::Pass);
736 }
737
738 const string PolicyTest::arbitrary_tenant = "arbitrary_tenant";
739 string PolicyTest::example1 = R"(
740 {
741 "Version": "2012-10-17",
742 "Statement": {
743 "Effect": "Allow",
744 "Action": "s3:ListBucket",
745 "Resource": "arn:aws:s3:::example_bucket"
746 }
747 }
748 )";
749
750 string PolicyTest::example2 = R"(
751 {
752 "Version": "2012-10-17",
753 "Id": "S3-Account-Permissions",
754 "Statement": [{
755 "Sid": "1",
756 "Effect": "Allow",
757 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
758 "Action": "s3:*",
759 "Resource": [
760 "arn:aws:s3:::mybucket",
761 "arn:aws:s3:::mybucket/*"
762 ]
763 }]
764 }
765 )";
766
767 string PolicyTest::example3 = R"(
768 {
769 "Version": "2012-10-17",
770 "Statement": [
771 {
772 "Sid": "FirstStatement",
773 "Effect": "Allow",
774 "Action": ["s3:PutBucketPolicy"],
775 "Resource": "*"
776 },
777 {
778 "Sid": "SecondStatement",
779 "Effect": "Allow",
780 "Action": "s3:ListAllMyBuckets",
781 "Resource": "*"
782 },
783 {
784 "Sid": "ThirdStatement",
785 "Effect": "Allow",
786 "Action": [
787 "s3:List*",
788 "s3:Get*"
789 ],
790 "Resource": [
791 "arn:aws:s3:::confidential-data",
792 "arn:aws:s3:::confidential-data/*"
793 ],
794 "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
795 }
796 ]
797 }
798 )";
799
800 string PolicyTest::example4 = R"(
801 {
802 "Version": "2012-10-17",
803 "Statement": {
804 "Effect": "Allow",
805 "Action": "iam:CreateRole",
806 "Resource": "*"
807 }
808 }
809 )";
810
811 string PolicyTest::example5 = R"(
812 {
813 "Version": "2012-10-17",
814 "Statement": {
815 "Effect": "Allow",
816 "Action": "iam:*",
817 "Resource": "arn:aws:iam:::role/example_role"
818 }
819 }
820 )";
821
822 string PolicyTest::example6 = R"(
823 {
824 "Version": "2012-10-17",
825 "Statement": {
826 "Effect": "Allow",
827 "Action": "*",
828 "Resource": "arn:aws:iam:::user/A"
829 }
830 }
831 )";
832
833 string PolicyTest::example7 = R"(
834 {
835 "Version": "2012-10-17",
836 "Statement": {
837 "Effect": "Allow",
838 "Principal": {"AWS": ["arn:aws:iam:::user/A:subA"]},
839 "Action": "s3:ListBucket",
840 "Resource": "arn:aws:s3:::mybucket/*"
841 }
842 }
843 )";
844 class IPPolicyTest : public ::testing::Test {
845 protected:
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;
851 // 192.168.1.0/24
852 const rgw::IAM::MaskedIP allowedIPv4Range = { false, rgw::IAM::Address("11000000101010000000000100000000"), 24 };
853 // 192.168.1.1/32
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 };
857 // ::1
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 };
861 public:
862 IPPolicyTest() {
863 cct = new CephContext(CEPH_ENTITY_TYPE_CLIENT);
864 }
865 };
866 const string IPPolicyTest::arbitrary_tenant = "arbitrary_tenant";
867
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);
876 }
877
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);
882 }
883
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);
888 }
889
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);
894 }
895
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);
900 }
901
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"));
908 }
909
910 TEST_F(IPPolicyTest, IPEnvironment) {
911 RGWProcessEnv penv;
912 // Unfortunately RGWCivetWeb is too tightly tied to civetweb to test RGWCivetWeb::init_env.
913 RGWEnv rgw_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");
924
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());
931
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");
938
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");
946
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");
953 }
954
955 TEST_F(IPPolicyTest, ParseIPAddress) {
956 boost::optional<Policy> p;
957
958 ASSERT_NO_THROW(
959 p = Policy(cct.get(), arbitrary_tenant,
960 bufferlist::static_from_string(ip_address_full_example), true));
961 ASSERT_TRUE(p);
962
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);
975 Action_t act;
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);
1000 }
1001
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);
1012 }
1013 }
1014
1015 TEST_F(IPPolicyTest, EvalIPAddress) {
1016 auto allowp =
1017 Policy(cct.get(), arbitrary_tenant,
1018 bufferlist::static_from_string(ip_address_allow_example), true);
1019 auto denyp =
1020 Policy(cct.get(), arbitrary_tenant,
1021 bufferlist::static_from_string(ip_address_deny_example), true);
1022 auto fullp =
1023 Policy(cct.get(), arbitrary_tenant,
1024 bufferlist::static_from_string(ip_address_full_example), true);
1025 Environment e;
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");
1031
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),
1038 Effect::Pass);
1039 ARN arn2(Partition::aws, Service::s3,
1040 "", arbitrary_tenant, "example_bucket/myobject");
1041 EXPECT_EQ(fullp.eval(e, trueacct, s3ListBucket, arn2),
1042 Effect::Pass);
1043
1044 ARN arn3(Partition::aws, Service::s3,
1045 "", arbitrary_tenant, "example_bucket");
1046 EXPECT_EQ(allowp.eval(allowedIP, trueacct, s3ListBucket, arn3),
1047 Effect::Allow);
1048 ARN arn4(Partition::aws, Service::s3,
1049 "", arbitrary_tenant, "example_bucket");
1050 EXPECT_EQ(allowp.eval(blocklistedIPv6, trueacct, s3ListBucket, arn4),
1051 Effect::Pass);
1052
1053 ARN arn5(Partition::aws, Service::s3,
1054 "", arbitrary_tenant, "example_bucket");
1055 EXPECT_EQ(denyp.eval(allowedIP, trueacct, s3ListBucket, arn5),
1056 Effect::Deny);
1057 ARN arn6(Partition::aws, Service::s3,
1058 "", arbitrary_tenant, "example_bucket/myobject");
1059 EXPECT_EQ(denyp.eval(allowedIP, trueacct, s3ListBucket, arn6),
1060 Effect::Deny);
1061
1062 ARN arn7(Partition::aws, Service::s3,
1063 "", arbitrary_tenant, "example_bucket");
1064 EXPECT_EQ(denyp.eval(blocklistedIP, trueacct, s3ListBucket, arn7),
1065 Effect::Pass);
1066 ARN arn8(Partition::aws, Service::s3,
1067 "", arbitrary_tenant, "example_bucket/myobject");
1068 EXPECT_EQ(denyp.eval(blocklistedIP, trueacct, s3ListBucket, arn8),
1069 Effect::Pass);
1070
1071 ARN arn9(Partition::aws, Service::s3,
1072 "", arbitrary_tenant, "example_bucket");
1073 EXPECT_EQ(denyp.eval(blocklistedIPv6, trueacct, s3ListBucket, arn9),
1074 Effect::Pass);
1075 ARN arn10(Partition::aws, Service::s3,
1076 "", arbitrary_tenant, "example_bucket/myobject");
1077 EXPECT_EQ(denyp.eval(blocklistedIPv6, trueacct, s3ListBucket, arn10),
1078 Effect::Pass);
1079 ARN arn11(Partition::aws, Service::s3,
1080 "", arbitrary_tenant, "example_bucket");
1081 EXPECT_EQ(denyp.eval(allowedIPv6, trueacct, s3ListBucket, arn11),
1082 Effect::Deny);
1083 ARN arn12(Partition::aws, Service::s3,
1084 "", arbitrary_tenant, "example_bucket/myobject");
1085 EXPECT_EQ(denyp.eval(allowedIPv6, trueacct, s3ListBucket, arn12),
1086 Effect::Deny);
1087
1088 ARN arn13(Partition::aws, Service::s3,
1089 "", arbitrary_tenant, "example_bucket");
1090 EXPECT_EQ(fullp.eval(allowedIP, trueacct, s3ListBucket, arn13),
1091 Effect::Allow);
1092 ARN arn14(Partition::aws, Service::s3,
1093 "", arbitrary_tenant, "example_bucket/myobject");
1094 EXPECT_EQ(fullp.eval(allowedIP, trueacct, s3ListBucket, arn14),
1095 Effect::Allow);
1096
1097 ARN arn15(Partition::aws, Service::s3,
1098 "", arbitrary_tenant, "example_bucket");
1099 EXPECT_EQ(fullp.eval(blocklistedIP, trueacct, s3ListBucket, arn15),
1100 Effect::Pass);
1101 ARN arn16(Partition::aws, Service::s3,
1102 "", arbitrary_tenant, "example_bucket/myobject");
1103 EXPECT_EQ(fullp.eval(blocklistedIP, trueacct, s3ListBucket, arn16),
1104 Effect::Pass);
1105
1106 ARN arn17(Partition::aws, Service::s3,
1107 "", arbitrary_tenant, "example_bucket");
1108 EXPECT_EQ(fullp.eval(allowedIPv6, trueacct, s3ListBucket, arn17),
1109 Effect::Allow);
1110 ARN arn18(Partition::aws, Service::s3,
1111 "", arbitrary_tenant, "example_bucket/myobject");
1112 EXPECT_EQ(fullp.eval(allowedIPv6, trueacct, s3ListBucket, arn18),
1113 Effect::Allow);
1114
1115 ARN arn19(Partition::aws, Service::s3,
1116 "", arbitrary_tenant, "example_bucket");
1117 EXPECT_EQ(fullp.eval(blocklistedIPv6, trueacct, s3ListBucket, arn19),
1118 Effect::Pass);
1119 ARN arn20(Partition::aws, Service::s3,
1120 "", arbitrary_tenant, "example_bucket/myobject");
1121 EXPECT_EQ(fullp.eval(blocklistedIPv6, trueacct, s3ListBucket, arn20),
1122 Effect::Pass);
1123 }
1124
1125 string IPPolicyTest::ip_address_allow_example = R"(
1126 {
1127 "Version": "2012-10-17",
1128 "Id": "S3SimpleIPPolicyTest",
1129 "Statement": [{
1130 "Sid": "1",
1131 "Effect": "Allow",
1132 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
1133 "Action": "s3:ListBucket",
1134 "Resource": [
1135 "arn:aws:s3:::example_bucket"
1136 ],
1137 "Condition": {
1138 "IpAddress": {"aws:SourceIp": "192.168.1.0/24"}
1139 }
1140 }]
1141 }
1142 )";
1143
1144 string IPPolicyTest::ip_address_deny_example = R"(
1145 {
1146 "Version": "2012-10-17",
1147 "Id": "S3IPPolicyTest",
1148 "Statement": {
1149 "Effect": "Deny",
1150 "Sid": "IPDeny",
1151 "Action": "s3:ListBucket",
1152 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
1153 "Resource": [
1154 "arn:aws:s3:::example_bucket",
1155 "arn:aws:s3:::example_bucket/*"
1156 ],
1157 "Condition": {
1158 "NotIpAddress": {"aws:SourceIp": ["192.168.1.1/32", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]}
1159 }
1160 }
1161 }
1162 )";
1163
1164 string IPPolicyTest::ip_address_full_example = R"(
1165 {
1166 "Version": "2012-10-17",
1167 "Id": "S3IPPolicyTest",
1168 "Statement": {
1169 "Effect": "Allow",
1170 "Sid": "IPAllow",
1171 "Action": "s3:ListBucket",
1172 "Principal": "*",
1173 "Resource": [
1174 "arn:aws:s3:::example_bucket",
1175 "arn:aws:s3:::example_bucket/*"
1176 ],
1177 "Condition": {
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"]}
1180 }
1181 }
1182 }
1183 )";
1184
1185 TEST(MatchWildcards, Simple)
1186 {
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));
1203 }
1204
1205 TEST(MatchWildcards, QuestionMark)
1206 {
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));
1227 }
1228
1229 TEST(MatchWildcards, Asterisk)
1230 {
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));
1264 }
1265
1266 TEST(MatchPolicy, Action)
1267 {
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
1273 }
1274
1275 TEST(MatchPolicy, Resource)
1276 {
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
1282 }
1283
1284 TEST(MatchPolicy, ARN)
1285 {
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
1291 }
1292
1293 TEST(MatchPolicy, String)
1294 {
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
1300 }
1301
1302 Action_t set_range_bits(std::uint64_t start, std::uint64_t end)
1303 {
1304 Action_t result;
1305 for (uint64_t i = start; i < end; i++) {
1306 result.set(i);
1307 }
1308 return result;
1309 }
1310
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)
1316 {
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));
1321 }