]> git.proxmox.com Git - ceph.git/blob - ceph/src/test/rgw/test_rgw_iam_policy.cc
update sources to ceph Nautilus 14.2.1
[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/rgw_auth.h"
27 #include "rgw/rgw_iam_policy.h"
28 #include "rgw/rgw_op.h"
29
30
31 using std::string;
32 using std::vector;
33
34 using boost::container::flat_set;
35 using boost::intrusive_ptr;
36 using boost::make_optional;
37 using boost::none;
38
39 using rgw::auth::Identity;
40 using rgw::auth::Principal;
41
42 using rgw::IAM::ARN;
43 using rgw::IAM::Effect;
44 using rgw::IAM::Environment;
45 using rgw::IAM::Partition;
46 using rgw::IAM::Policy;
47 using rgw::IAM::s3All;
48 using rgw::IAM::s3Count;
49 using rgw::IAM::s3GetAccelerateConfiguration;
50 using rgw::IAM::s3GetBucketAcl;
51 using rgw::IAM::s3GetBucketCORS;
52 using rgw::IAM::s3GetBucketLocation;
53 using rgw::IAM::s3GetBucketLogging;
54 using rgw::IAM::s3GetBucketNotification;
55 using rgw::IAM::s3GetBucketPolicy;
56 using rgw::IAM::s3GetBucketRequestPayment;
57 using rgw::IAM::s3GetBucketTagging;
58 using rgw::IAM::s3GetBucketVersioning;
59 using rgw::IAM::s3GetBucketWebsite;
60 using rgw::IAM::s3GetLifecycleConfiguration;
61 using rgw::IAM::s3GetObject;
62 using rgw::IAM::s3GetObjectAcl;
63 using rgw::IAM::s3GetObjectVersionAcl;
64 using rgw::IAM::s3GetObjectTorrent;
65 using rgw::IAM::s3GetObjectTagging;
66 using rgw::IAM::s3GetObjectVersion;
67 using rgw::IAM::s3GetObjectVersionTagging;
68 using rgw::IAM::s3GetObjectVersionTorrent;
69 using rgw::IAM::s3GetReplicationConfiguration;
70 using rgw::IAM::s3ListAllMyBuckets;
71 using rgw::IAM::s3ListBucket;
72 using rgw::IAM::s3ListBucket;
73 using rgw::IAM::s3ListBucketMultipartUploads;
74 using rgw::IAM::s3ListBucketVersions;
75 using rgw::IAM::s3ListMultipartUploadParts;
76 using rgw::IAM::None;
77 using rgw::IAM::s3PutBucketAcl;
78 using rgw::IAM::s3PutBucketPolicy;
79 using rgw::IAM::Service;
80 using rgw::IAM::TokenID;
81 using rgw::IAM::Version;
82 using rgw::IAM::Action_t;
83 using rgw::IAM::NotAction_t;
84 using rgw::IAM::iamCreateRole;
85 using rgw::IAM::iamDeleteRole;
86 using rgw::IAM::iamAll;
87 using rgw::IAM::stsAll;
88
89 class FakeIdentity : public Identity {
90 const Principal id;
91 public:
92
93 explicit FakeIdentity(Principal&& id) : id(std::move(id)) {}
94 uint32_t get_perms_from_aclspec(const DoutPrefixProvider* dpp, const aclspec_t& aclspec) const override {
95 ceph_abort();
96 return 0;
97 };
98
99 bool is_admin_of(const rgw_user& uid) const override {
100 ceph_abort();
101 return false;
102 }
103
104 bool is_owner_of(const rgw_user& uid) const override {
105 ceph_abort();
106 return false;
107 }
108
109 virtual uint32_t get_perm_mask() const override {
110 ceph_abort();
111 return 0;
112 }
113
114 uint32_t get_identity_type() const override {
115 abort();
116 return 0;
117 }
118
119 string get_acct_name() const override {
120 abort();
121 return 0;
122 }
123
124 void to_str(std::ostream& out) const override {
125 out << id;
126 }
127
128 bool is_identity(const flat_set<Principal>& ids) const override {
129 if (id.is_wildcard() && (!ids.empty())) {
130 return true;
131 }
132 return ids.find(id) != ids.end() || ids.find(Principal::wildcard()) != ids.end();
133 }
134 };
135
136 class PolicyTest : public ::testing::Test {
137 protected:
138 intrusive_ptr<CephContext> cct;
139 static const string arbitrary_tenant;
140 static string example1;
141 static string example2;
142 static string example3;
143 static string example4;
144 static string example5;
145 static string example6;
146 public:
147 PolicyTest() {
148 cct = new CephContext(CEPH_ENTITY_TYPE_CLIENT);
149 }
150 };
151
152 TEST_F(PolicyTest, Parse1) {
153 boost::optional<Policy> p;
154
155 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
156 bufferlist::static_from_string(example1)));
157 ASSERT_TRUE(p);
158
159 EXPECT_EQ(p->text, example1);
160 EXPECT_EQ(p->version, Version::v2012_10_17);
161 EXPECT_FALSE(p->id);
162 EXPECT_FALSE(p->statements[0].sid);
163 EXPECT_FALSE(p->statements.empty());
164 EXPECT_EQ(p->statements.size(), 1U);
165 EXPECT_TRUE(p->statements[0].princ.empty());
166 EXPECT_TRUE(p->statements[0].noprinc.empty());
167 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
168 Action_t act;
169 act[s3ListBucket] = 1;
170 EXPECT_EQ(p->statements[0].action, act);
171 EXPECT_EQ(p->statements[0].notaction, None);
172 ASSERT_FALSE(p->statements[0].resource.empty());
173 ASSERT_EQ(p->statements[0].resource.size(), 1U);
174 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::aws);
175 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::s3);
176 EXPECT_TRUE(p->statements[0].resource.begin()->region.empty());
177 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
178 EXPECT_EQ(p->statements[0].resource.begin()->resource, "example_bucket");
179 EXPECT_TRUE(p->statements[0].notresource.empty());
180 EXPECT_TRUE(p->statements[0].conditions.empty());
181 }
182
183 TEST_F(PolicyTest, Eval1) {
184 auto p = Policy(cct.get(), arbitrary_tenant,
185 bufferlist::static_from_string(example1));
186 Environment e;
187
188 EXPECT_EQ(p.eval(e, none, s3ListBucket,
189 ARN(Partition::aws, Service::s3,
190 "", arbitrary_tenant, "example_bucket")),
191 Effect::Allow);
192
193 EXPECT_EQ(p.eval(e, none, s3PutBucketAcl,
194 ARN(Partition::aws, Service::s3,
195 "", arbitrary_tenant, "example_bucket")),
196 Effect::Pass);
197
198 EXPECT_EQ(p.eval(e, none, s3ListBucket,
199 ARN(Partition::aws, Service::s3,
200 "", arbitrary_tenant, "erroneous_bucket")),
201 Effect::Pass);
202
203 }
204
205 TEST_F(PolicyTest, Parse2) {
206 boost::optional<Policy> p;
207
208 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
209 bufferlist::static_from_string(example2)));
210 ASSERT_TRUE(p);
211
212 EXPECT_EQ(p->text, example2);
213 EXPECT_EQ(p->version, Version::v2012_10_17);
214 EXPECT_EQ(*p->id, "S3-Account-Permissions");
215 ASSERT_FALSE(p->statements.empty());
216 EXPECT_EQ(p->statements.size(), 1U);
217 EXPECT_EQ(*p->statements[0].sid, "1");
218 EXPECT_FALSE(p->statements[0].princ.empty());
219 EXPECT_EQ(p->statements[0].princ.size(), 1U);
220 EXPECT_EQ(*p->statements[0].princ.begin(),
221 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
222 EXPECT_TRUE(p->statements[0].noprinc.empty());
223 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
224 Action_t act;
225 for (auto i = 0ULL; i < s3Count; i++)
226 act[i] = 1;
227 act[s3All] = 1;
228 EXPECT_EQ(p->statements[0].action, act);
229 EXPECT_EQ(p->statements[0].notaction, None);
230 ASSERT_FALSE(p->statements[0].resource.empty());
231 ASSERT_EQ(p->statements[0].resource.size(), 2U);
232 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::aws);
233 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::s3);
234 EXPECT_TRUE(p->statements[0].resource.begin()->region.empty());
235 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
236 EXPECT_EQ(p->statements[0].resource.begin()->resource, "mybucket");
237 EXPECT_EQ((p->statements[0].resource.begin() + 1)->partition,
238 Partition::aws);
239 EXPECT_EQ((p->statements[0].resource.begin() + 1)->service,
240 Service::s3);
241 EXPECT_TRUE((p->statements[0].resource.begin() + 1)->region.empty());
242 EXPECT_EQ((p->statements[0].resource.begin() + 1)->account,
243 arbitrary_tenant);
244 EXPECT_EQ((p->statements[0].resource.begin() + 1)->resource, "mybucket/*");
245 EXPECT_TRUE(p->statements[0].notresource.empty());
246 EXPECT_TRUE(p->statements[0].conditions.empty());
247 }
248
249 TEST_F(PolicyTest, Eval2) {
250 auto p = Policy(cct.get(), arbitrary_tenant,
251 bufferlist::static_from_string(example2));
252 Environment e;
253
254 auto trueacct = FakeIdentity(
255 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
256
257 auto notacct = FakeIdentity(
258 Principal::tenant("some-other-account"));
259 for (auto i = 0ULL; i < s3Count; ++i) {
260 EXPECT_EQ(p.eval(e, trueacct, i,
261 ARN(Partition::aws, Service::s3,
262 "", arbitrary_tenant, "mybucket")),
263 Effect::Allow);
264 EXPECT_EQ(p.eval(e, trueacct, i,
265 ARN(Partition::aws, Service::s3,
266 "", arbitrary_tenant, "mybucket/myobject")),
267 Effect::Allow);
268
269 EXPECT_EQ(p.eval(e, notacct, i,
270 ARN(Partition::aws, Service::s3,
271 "", arbitrary_tenant, "mybucket")),
272 Effect::Pass);
273 EXPECT_EQ(p.eval(e, notacct, i,
274 ARN(Partition::aws, Service::s3,
275 "", arbitrary_tenant, "mybucket/myobject")),
276 Effect::Pass);
277
278 EXPECT_EQ(p.eval(e, trueacct, i,
279 ARN(Partition::aws, Service::s3,
280 "", arbitrary_tenant, "notyourbucket")),
281 Effect::Pass);
282 EXPECT_EQ(p.eval(e, trueacct, i,
283 ARN(Partition::aws, Service::s3,
284 "", arbitrary_tenant, "notyourbucket/notyourobject")),
285 Effect::Pass);
286
287 }
288 }
289
290 TEST_F(PolicyTest, Parse3) {
291 boost::optional<Policy> p;
292
293 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
294 bufferlist::static_from_string(example3)));
295 ASSERT_TRUE(p);
296
297 EXPECT_EQ(p->text, example3);
298 EXPECT_EQ(p->version, Version::v2012_10_17);
299 EXPECT_FALSE(p->id);
300 ASSERT_FALSE(p->statements.empty());
301 EXPECT_EQ(p->statements.size(), 3U);
302
303 EXPECT_EQ(*p->statements[0].sid, "FirstStatement");
304 EXPECT_TRUE(p->statements[0].princ.empty());
305 EXPECT_TRUE(p->statements[0].noprinc.empty());
306 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
307 Action_t act;
308 act[s3PutBucketPolicy] = 1;
309 EXPECT_EQ(p->statements[0].action, act);
310 EXPECT_EQ(p->statements[0].notaction, None);
311 ASSERT_FALSE(p->statements[0].resource.empty());
312 ASSERT_EQ(p->statements[0].resource.size(), 1U);
313 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::wildcard);
314 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::wildcard);
315 EXPECT_EQ(p->statements[0].resource.begin()->region, "*");
316 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
317 EXPECT_EQ(p->statements[0].resource.begin()->resource, "*");
318 EXPECT_TRUE(p->statements[0].notresource.empty());
319 EXPECT_TRUE(p->statements[0].conditions.empty());
320
321 EXPECT_EQ(*p->statements[1].sid, "SecondStatement");
322 EXPECT_TRUE(p->statements[1].princ.empty());
323 EXPECT_TRUE(p->statements[1].noprinc.empty());
324 EXPECT_EQ(p->statements[1].effect, Effect::Allow);
325 Action_t act1;
326 act1[s3ListAllMyBuckets] = 1;
327 EXPECT_EQ(p->statements[1].action, act1);
328 EXPECT_EQ(p->statements[1].notaction, None);
329 ASSERT_FALSE(p->statements[1].resource.empty());
330 ASSERT_EQ(p->statements[1].resource.size(), 1U);
331 EXPECT_EQ(p->statements[1].resource.begin()->partition, Partition::wildcard);
332 EXPECT_EQ(p->statements[1].resource.begin()->service, Service::wildcard);
333 EXPECT_EQ(p->statements[1].resource.begin()->region, "*");
334 EXPECT_EQ(p->statements[1].resource.begin()->account, arbitrary_tenant);
335 EXPECT_EQ(p->statements[1].resource.begin()->resource, "*");
336 EXPECT_TRUE(p->statements[1].notresource.empty());
337 EXPECT_TRUE(p->statements[1].conditions.empty());
338
339 EXPECT_EQ(*p->statements[2].sid, "ThirdStatement");
340 EXPECT_TRUE(p->statements[2].princ.empty());
341 EXPECT_TRUE(p->statements[2].noprinc.empty());
342 EXPECT_EQ(p->statements[2].effect, Effect::Allow);
343 Action_t act2;
344 act2[s3ListMultipartUploadParts] = 1;
345 act2[s3ListBucket] = 1;
346 act2[s3ListBucketVersions] = 1;
347 act2[s3ListAllMyBuckets] = 1;
348 act2[s3ListBucketMultipartUploads] = 1;
349 act2[s3GetObject] = 1;
350 act2[s3GetObjectVersion] = 1;
351 act2[s3GetObjectAcl] = 1;
352 act2[s3GetObjectVersionAcl] = 1;
353 act2[s3GetObjectTorrent] = 1;
354 act2[s3GetObjectVersionTorrent] = 1;
355 act2[s3GetAccelerateConfiguration] = 1;
356 act2[s3GetBucketAcl] = 1;
357 act2[s3GetBucketCORS] = 1;
358 act2[s3GetBucketVersioning] = 1;
359 act2[s3GetBucketRequestPayment] = 1;
360 act2[s3GetBucketLocation] = 1;
361 act2[s3GetBucketPolicy] = 1;
362 act2[s3GetBucketNotification] = 1;
363 act2[s3GetBucketLogging] = 1;
364 act2[s3GetBucketTagging] = 1;
365 act2[s3GetBucketWebsite] = 1;
366 act2[s3GetLifecycleConfiguration] = 1;
367 act2[s3GetReplicationConfiguration] = 1;
368 act2[s3GetObjectTagging] = 1;
369 act2[s3GetObjectVersionTagging] = 1;
370
371 EXPECT_EQ(p->statements[2].action, act2);
372 EXPECT_EQ(p->statements[2].notaction, None);
373 ASSERT_FALSE(p->statements[2].resource.empty());
374 ASSERT_EQ(p->statements[2].resource.size(), 2U);
375 EXPECT_EQ(p->statements[2].resource.begin()->partition, Partition::aws);
376 EXPECT_EQ(p->statements[2].resource.begin()->service, Service::s3);
377 EXPECT_TRUE(p->statements[2].resource.begin()->region.empty());
378 EXPECT_EQ(p->statements[2].resource.begin()->account, arbitrary_tenant);
379 EXPECT_EQ(p->statements[2].resource.begin()->resource, "confidential-data");
380 EXPECT_EQ((p->statements[2].resource.begin() + 1)->partition,
381 Partition::aws);
382 EXPECT_EQ((p->statements[2].resource.begin() + 1)->service, Service::s3);
383 EXPECT_TRUE((p->statements[2].resource.begin() + 1)->region.empty());
384 EXPECT_EQ((p->statements[2].resource.begin() + 1)->account,
385 arbitrary_tenant);
386 EXPECT_EQ((p->statements[2].resource.begin() + 1)->resource,
387 "confidential-data/*");
388 EXPECT_TRUE(p->statements[2].notresource.empty());
389 ASSERT_FALSE(p->statements[2].conditions.empty());
390 ASSERT_EQ(p->statements[2].conditions.size(), 1U);
391 EXPECT_EQ(p->statements[2].conditions[0].op, TokenID::Bool);
392 EXPECT_EQ(p->statements[2].conditions[0].key, "aws:MultiFactorAuthPresent");
393 EXPECT_FALSE(p->statements[2].conditions[0].ifexists);
394 ASSERT_FALSE(p->statements[2].conditions[0].vals.empty());
395 EXPECT_EQ(p->statements[2].conditions[0].vals.size(), 1U);
396 EXPECT_EQ(p->statements[2].conditions[0].vals[0], "true");
397 }
398
399 TEST_F(PolicyTest, Eval3) {
400 auto p = Policy(cct.get(), arbitrary_tenant,
401 bufferlist::static_from_string(example3));
402 Environment em;
403 Environment tr = { { "aws:MultiFactorAuthPresent", "true" } };
404 Environment fa = { { "aws:MultiFactorAuthPresent", "false" } };
405
406 Action_t s3allow;
407 s3allow[s3ListMultipartUploadParts] = 1;
408 s3allow[s3ListBucket] = 1;
409 s3allow[s3ListBucketVersions] = 1;
410 s3allow[s3ListAllMyBuckets] = 1;
411 s3allow[s3ListBucketMultipartUploads] = 1;
412 s3allow[s3GetObject] = 1;
413 s3allow[s3GetObjectVersion] = 1;
414 s3allow[s3GetObjectAcl] = 1;
415 s3allow[s3GetObjectVersionAcl] = 1;
416 s3allow[s3GetObjectTorrent] = 1;
417 s3allow[s3GetObjectVersionTorrent] = 1;
418 s3allow[s3GetAccelerateConfiguration] = 1;
419 s3allow[s3GetBucketAcl] = 1;
420 s3allow[s3GetBucketCORS] = 1;
421 s3allow[s3GetBucketVersioning] = 1;
422 s3allow[s3GetBucketRequestPayment] = 1;
423 s3allow[s3GetBucketLocation] = 1;
424 s3allow[s3GetBucketPolicy] = 1;
425 s3allow[s3GetBucketNotification] = 1;
426 s3allow[s3GetBucketLogging] = 1;
427 s3allow[s3GetBucketTagging] = 1;
428 s3allow[s3GetBucketWebsite] = 1;
429 s3allow[s3GetLifecycleConfiguration] = 1;
430 s3allow[s3GetReplicationConfiguration] = 1;
431 s3allow[s3GetObjectTagging] = 1;
432 s3allow[s3GetObjectVersionTagging] = 1;
433
434 EXPECT_EQ(p.eval(em, none, s3PutBucketPolicy,
435 ARN(Partition::aws, Service::s3,
436 "", arbitrary_tenant, "mybucket")),
437 Effect::Allow);
438
439 EXPECT_EQ(p.eval(em, none, s3PutBucketPolicy,
440 ARN(Partition::aws, Service::s3,
441 "", arbitrary_tenant, "mybucket")),
442 Effect::Allow);
443
444
445 for (auto op = 0ULL; op < s3Count; ++op) {
446 if ((op == s3ListAllMyBuckets) || (op == s3PutBucketPolicy)) {
447 continue;
448 }
449 EXPECT_EQ(p.eval(em, none, op,
450 ARN(Partition::aws, Service::s3,
451 "", arbitrary_tenant, "confidential-data")),
452 Effect::Pass);
453 EXPECT_EQ(p.eval(tr, none, op,
454 ARN(Partition::aws, Service::s3,
455 "", arbitrary_tenant, "confidential-data")),
456 s3allow[op] ? Effect::Allow : Effect::Pass);
457 EXPECT_EQ(p.eval(fa, none, op,
458 ARN(Partition::aws, Service::s3,
459 "", arbitrary_tenant, "confidential-data")),
460 Effect::Pass);
461
462 EXPECT_EQ(p.eval(em, none, op,
463 ARN(Partition::aws, Service::s3,
464 "", arbitrary_tenant, "confidential-data/moo")),
465 Effect::Pass);
466 EXPECT_EQ(p.eval(tr, none, op,
467 ARN(Partition::aws, Service::s3,
468 "", arbitrary_tenant, "confidential-data/moo")),
469 s3allow[op] ? Effect::Allow : Effect::Pass);
470 EXPECT_EQ(p.eval(fa, none, op,
471 ARN(Partition::aws, Service::s3,
472 "", arbitrary_tenant, "confidential-data/moo")),
473 Effect::Pass);
474
475 EXPECT_EQ(p.eval(em, none, op,
476 ARN(Partition::aws, Service::s3,
477 "", arbitrary_tenant, "really-confidential-data")),
478 Effect::Pass);
479 EXPECT_EQ(p.eval(tr, none, op,
480 ARN(Partition::aws, Service::s3,
481 "", arbitrary_tenant, "really-confidential-data")),
482 Effect::Pass);
483 EXPECT_EQ(p.eval(fa, none, op,
484 ARN(Partition::aws, Service::s3,
485 "", arbitrary_tenant, "really-confidential-data")),
486 Effect::Pass);
487
488 EXPECT_EQ(p.eval(em, none, op,
489 ARN(Partition::aws, Service::s3,
490 "", arbitrary_tenant,
491 "really-confidential-data/moo")), Effect::Pass);
492 EXPECT_EQ(p.eval(tr, none, op,
493 ARN(Partition::aws, Service::s3,
494 "", arbitrary_tenant,
495 "really-confidential-data/moo")), Effect::Pass);
496 EXPECT_EQ(p.eval(fa, none, op,
497 ARN(Partition::aws, Service::s3,
498 "", arbitrary_tenant,
499 "really-confidential-data/moo")), Effect::Pass);
500
501 }
502 }
503
504 TEST_F(PolicyTest, Parse4) {
505 boost::optional<Policy> p;
506
507 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
508 bufferlist::static_from_string(example4)));
509 ASSERT_TRUE(p);
510
511 EXPECT_EQ(p->text, example4);
512 EXPECT_EQ(p->version, Version::v2012_10_17);
513 EXPECT_FALSE(p->id);
514 EXPECT_FALSE(p->statements[0].sid);
515 EXPECT_FALSE(p->statements.empty());
516 EXPECT_EQ(p->statements.size(), 1U);
517 EXPECT_TRUE(p->statements[0].princ.empty());
518 EXPECT_TRUE(p->statements[0].noprinc.empty());
519 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
520 Action_t act;
521 act[iamCreateRole] = 1;
522 EXPECT_EQ(p->statements[0].action, act);
523 EXPECT_EQ(p->statements[0].notaction, None);
524 ASSERT_FALSE(p->statements[0].resource.empty());
525 ASSERT_EQ(p->statements[0].resource.size(), 1U);
526 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::wildcard);
527 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::wildcard);
528 EXPECT_EQ(p->statements[0].resource.begin()->region, "*");
529 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
530 EXPECT_EQ(p->statements[0].resource.begin()->resource, "*");
531 EXPECT_TRUE(p->statements[0].notresource.empty());
532 EXPECT_TRUE(p->statements[0].conditions.empty());
533 }
534
535 TEST_F(PolicyTest, Eval4) {
536 auto p = Policy(cct.get(), arbitrary_tenant,
537 bufferlist::static_from_string(example4));
538 Environment e;
539
540 EXPECT_EQ(p.eval(e, none, iamCreateRole,
541 ARN(Partition::aws, Service::iam,
542 "", arbitrary_tenant, "role/example_role")),
543 Effect::Allow);
544
545 EXPECT_EQ(p.eval(e, none, iamDeleteRole,
546 ARN(Partition::aws, Service::iam,
547 "", arbitrary_tenant, "role/example_role")),
548 Effect::Pass);
549 }
550
551 TEST_F(PolicyTest, Parse5) {
552 boost::optional<Policy> p;
553
554 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
555 bufferlist::static_from_string(example5)));
556 ASSERT_TRUE(p);
557 EXPECT_EQ(p->text, example5);
558 EXPECT_EQ(p->version, Version::v2012_10_17);
559 EXPECT_FALSE(p->id);
560 EXPECT_FALSE(p->statements[0].sid);
561 EXPECT_FALSE(p->statements.empty());
562 EXPECT_EQ(p->statements.size(), 1U);
563 EXPECT_TRUE(p->statements[0].princ.empty());
564 EXPECT_TRUE(p->statements[0].noprinc.empty());
565 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
566 Action_t act;
567 for (auto i = s3All+1; i <= iamAll; i++)
568 act[i] = 1;
569 EXPECT_EQ(p->statements[0].action, act);
570 EXPECT_EQ(p->statements[0].notaction, None);
571 ASSERT_FALSE(p->statements[0].resource.empty());
572 ASSERT_EQ(p->statements[0].resource.size(), 1U);
573 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::aws);
574 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::iam);
575 EXPECT_EQ(p->statements[0].resource.begin()->region, "");
576 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
577 EXPECT_EQ(p->statements[0].resource.begin()->resource, "role/example_role");
578 EXPECT_TRUE(p->statements[0].notresource.empty());
579 EXPECT_TRUE(p->statements[0].conditions.empty());
580 }
581
582 TEST_F(PolicyTest, Eval5) {
583 auto p = Policy(cct.get(), arbitrary_tenant,
584 bufferlist::static_from_string(example5));
585 Environment e;
586
587 EXPECT_EQ(p.eval(e, none, iamCreateRole,
588 ARN(Partition::aws, Service::iam,
589 "", arbitrary_tenant, "role/example_role")),
590 Effect::Allow);
591
592 EXPECT_EQ(p.eval(e, none, s3ListBucket,
593 ARN(Partition::aws, Service::iam,
594 "", arbitrary_tenant, "role/example_role")),
595 Effect::Pass);
596
597 EXPECT_EQ(p.eval(e, none, iamCreateRole,
598 ARN(Partition::aws, Service::iam,
599 "", "", "role/example_role")),
600 Effect::Pass);
601 }
602
603 TEST_F(PolicyTest, Parse6) {
604 boost::optional<Policy> p;
605
606 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
607 bufferlist::static_from_string(example6)));
608 ASSERT_TRUE(p);
609 EXPECT_EQ(p->text, example6);
610 EXPECT_EQ(p->version, Version::v2012_10_17);
611 EXPECT_FALSE(p->id);
612 EXPECT_FALSE(p->statements[0].sid);
613 EXPECT_FALSE(p->statements.empty());
614 EXPECT_EQ(p->statements.size(), 1U);
615 EXPECT_TRUE(p->statements[0].princ.empty());
616 EXPECT_TRUE(p->statements[0].noprinc.empty());
617 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
618 Action_t act;
619 for (auto i = 0U; i <= stsAll; i++)
620 act[i] = 1;
621 EXPECT_EQ(p->statements[0].action, act);
622 EXPECT_EQ(p->statements[0].notaction, None);
623 ASSERT_FALSE(p->statements[0].resource.empty());
624 ASSERT_EQ(p->statements[0].resource.size(), 1U);
625 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::aws);
626 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::iam);
627 EXPECT_EQ(p->statements[0].resource.begin()->region, "");
628 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
629 EXPECT_EQ(p->statements[0].resource.begin()->resource, "user/A");
630 EXPECT_TRUE(p->statements[0].notresource.empty());
631 EXPECT_TRUE(p->statements[0].conditions.empty());
632 }
633
634 TEST_F(PolicyTest, Eval6) {
635 auto p = Policy(cct.get(), arbitrary_tenant,
636 bufferlist::static_from_string(example6));
637 Environment e;
638
639 EXPECT_EQ(p.eval(e, none, iamCreateRole,
640 ARN(Partition::aws, Service::iam,
641 "", arbitrary_tenant, "user/A")),
642 Effect::Allow);
643
644 EXPECT_EQ(p.eval(e, none, s3ListBucket,
645 ARN(Partition::aws, Service::iam,
646 "", arbitrary_tenant, "user/A")),
647 Effect::Allow);
648 }
649
650 const string PolicyTest::arbitrary_tenant = "arbitrary_tenant";
651 string PolicyTest::example1 = R"(
652 {
653 "Version": "2012-10-17",
654 "Statement": {
655 "Effect": "Allow",
656 "Action": "s3:ListBucket",
657 "Resource": "arn:aws:s3:::example_bucket"
658 }
659 }
660 )";
661
662 string PolicyTest::example2 = R"(
663 {
664 "Version": "2012-10-17",
665 "Id": "S3-Account-Permissions",
666 "Statement": [{
667 "Sid": "1",
668 "Effect": "Allow",
669 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
670 "Action": "s3:*",
671 "Resource": [
672 "arn:aws:s3:::mybucket",
673 "arn:aws:s3:::mybucket/*"
674 ]
675 }]
676 }
677 )";
678
679 string PolicyTest::example3 = R"(
680 {
681 "Version": "2012-10-17",
682 "Statement": [
683 {
684 "Sid": "FirstStatement",
685 "Effect": "Allow",
686 "Action": ["s3:PutBucketPolicy"],
687 "Resource": "*"
688 },
689 {
690 "Sid": "SecondStatement",
691 "Effect": "Allow",
692 "Action": "s3:ListAllMyBuckets",
693 "Resource": "*"
694 },
695 {
696 "Sid": "ThirdStatement",
697 "Effect": "Allow",
698 "Action": [
699 "s3:List*",
700 "s3:Get*"
701 ],
702 "Resource": [
703 "arn:aws:s3:::confidential-data",
704 "arn:aws:s3:::confidential-data/*"
705 ],
706 "Condition": {"Bool": {"aws:MultiFactorAuthPresent": "true"}}
707 }
708 ]
709 }
710 )";
711
712 string PolicyTest::example4 = R"(
713 {
714 "Version": "2012-10-17",
715 "Statement": {
716 "Effect": "Allow",
717 "Action": "iam:CreateRole",
718 "Resource": "*"
719 }
720 }
721 )";
722
723 string PolicyTest::example5 = R"(
724 {
725 "Version": "2012-10-17",
726 "Statement": {
727 "Effect": "Allow",
728 "Action": "iam:*",
729 "Resource": "arn:aws:iam:::role/example_role"
730 }
731 }
732 )";
733
734 string PolicyTest::example6 = R"(
735 {
736 "Version": "2012-10-17",
737 "Statement": {
738 "Effect": "Allow",
739 "Action": "*",
740 "Resource": "arn:aws:iam:::user/A"
741 }
742 }
743 )";
744 class IPPolicyTest : public ::testing::Test {
745 protected:
746 intrusive_ptr<CephContext> cct;
747 static const string arbitrary_tenant;
748 static string ip_address_allow_example;
749 static string ip_address_deny_example;
750 static string ip_address_full_example;
751 // 192.168.1.0/24
752 const rgw::IAM::MaskedIP allowedIPv4Range = { false, rgw::IAM::Address("11000000101010000000000100000000"), 24 };
753 // 192.168.1.1/32
754 const rgw::IAM::MaskedIP blacklistedIPv4 = { false, rgw::IAM::Address("11000000101010000000000100000001"), 32 };
755 // 2001:db8:85a3:0:0:8a2e:370:7334/128
756 const rgw::IAM::MaskedIP allowedIPv6 = { true, rgw::IAM::Address("00100000000000010000110110111000100001011010001100000000000000000000000000000000100010100010111000000011011100000111001100110100"), 128 };
757 // ::1
758 const rgw::IAM::MaskedIP blacklistedIPv6 = { true, rgw::IAM::Address(1), 128 };
759 // 2001:db8:85a3:0:0:8a2e:370:7330/124
760 const rgw::IAM::MaskedIP allowedIPv6Range = { true, rgw::IAM::Address("00100000000000010000110110111000100001011010001100000000000000000000000000000000100010100010111000000011011100000111001100110000"), 124 };
761 public:
762 IPPolicyTest() {
763 cct = new CephContext(CEPH_ENTITY_TYPE_CLIENT);
764 }
765 };
766 const string IPPolicyTest::arbitrary_tenant = "arbitrary_tenant";
767
768 TEST_F(IPPolicyTest, MaskedIPOperations) {
769 EXPECT_EQ(stringify(allowedIPv4Range), "192.168.1.0/24");
770 EXPECT_EQ(stringify(blacklistedIPv4), "192.168.1.1/32");
771 EXPECT_EQ(stringify(allowedIPv6), "2001:db8:85a3:0:0:8a2e:370:7334/128");
772 EXPECT_EQ(stringify(allowedIPv6Range), "2001:db8:85a3:0:0:8a2e:370:7330/124");
773 EXPECT_EQ(stringify(blacklistedIPv6), "0:0:0:0:0:0:0:1/128");
774 EXPECT_EQ(allowedIPv4Range, blacklistedIPv4);
775 EXPECT_EQ(allowedIPv6Range, allowedIPv6);
776 }
777
778 TEST_F(IPPolicyTest, asNetworkIPv4Range) {
779 auto actualIPv4Range = rgw::IAM::Condition::as_network("192.168.1.0/24");
780 ASSERT_TRUE(actualIPv4Range.is_initialized());
781 EXPECT_EQ(*actualIPv4Range, allowedIPv4Range);
782 }
783
784 TEST_F(IPPolicyTest, asNetworkIPv4) {
785 auto actualIPv4 = rgw::IAM::Condition::as_network("192.168.1.1");
786 ASSERT_TRUE(actualIPv4.is_initialized());
787 EXPECT_EQ(*actualIPv4, blacklistedIPv4);
788 }
789
790 TEST_F(IPPolicyTest, asNetworkIPv6Range) {
791 auto actualIPv6Range = rgw::IAM::Condition::as_network("2001:db8:85a3:0:0:8a2e:370:7330/124");
792 ASSERT_TRUE(actualIPv6Range.is_initialized());
793 EXPECT_EQ(*actualIPv6Range, allowedIPv6Range);
794 }
795
796 TEST_F(IPPolicyTest, asNetworkIPv6) {
797 auto actualIPv6 = rgw::IAM::Condition::as_network("2001:db8:85a3:0:0:8a2e:370:7334");
798 ASSERT_TRUE(actualIPv6.is_initialized());
799 EXPECT_EQ(*actualIPv6, allowedIPv6);
800 }
801
802 TEST_F(IPPolicyTest, asNetworkInvalid) {
803 EXPECT_FALSE(rgw::IAM::Condition::as_network(""));
804 EXPECT_FALSE(rgw::IAM::Condition::as_network("192.168.1.1/33"));
805 EXPECT_FALSE(rgw::IAM::Condition::as_network("2001:db8:85a3:0:0:8a2e:370:7334/129"));
806 EXPECT_FALSE(rgw::IAM::Condition::as_network("192.168.1.1:"));
807 EXPECT_FALSE(rgw::IAM::Condition::as_network("1.2.3.10000"));
808 }
809
810 TEST_F(IPPolicyTest, IPEnvironment) {
811 // Unfortunately RGWCivetWeb is too tightly tied to civetweb to test RGWCivetWeb::init_env.
812 RGWEnv rgw_env;
813 RGWUserInfo user;
814 RGWRados rgw_rados;
815 rgw_env.set("REMOTE_ADDR", "192.168.1.1");
816 rgw_env.set("HTTP_HOST", "1.2.3.4");
817 req_state rgw_req_state(cct.get(), &rgw_env, &user, 0);
818 rgw_build_iam_environment(&rgw_rados, &rgw_req_state);
819 auto ip = rgw_req_state.env.find("aws:SourceIp");
820 ASSERT_NE(ip, rgw_req_state.env.end());
821 EXPECT_EQ(ip->second, "192.168.1.1");
822
823 ASSERT_EQ(cct.get()->_conf.set_val("rgw_remote_addr_param", "SOME_VAR"), 0);
824 EXPECT_EQ(cct.get()->_conf->rgw_remote_addr_param, "SOME_VAR");
825 rgw_req_state.env.clear();
826 rgw_build_iam_environment(&rgw_rados, &rgw_req_state);
827 ip = rgw_req_state.env.find("aws:SourceIp");
828 EXPECT_EQ(ip, rgw_req_state.env.end());
829
830 rgw_env.set("SOME_VAR", "192.168.1.2");
831 rgw_req_state.env.clear();
832 rgw_build_iam_environment(&rgw_rados, &rgw_req_state);
833 ip = rgw_req_state.env.find("aws:SourceIp");
834 ASSERT_NE(ip, rgw_req_state.env.end());
835 EXPECT_EQ(ip->second, "192.168.1.2");
836
837 ASSERT_EQ(cct.get()->_conf.set_val("rgw_remote_addr_param", "HTTP_X_FORWARDED_FOR"), 0);
838 rgw_env.set("HTTP_X_FORWARDED_FOR", "192.168.1.3");
839 rgw_req_state.env.clear();
840 rgw_build_iam_environment(&rgw_rados, &rgw_req_state);
841 ip = rgw_req_state.env.find("aws:SourceIp");
842 ASSERT_NE(ip, rgw_req_state.env.end());
843 EXPECT_EQ(ip->second, "192.168.1.3");
844
845 rgw_env.set("HTTP_X_FORWARDED_FOR", "192.168.1.4, 4.3.2.1, 2001:db8:85a3:8d3:1319:8a2e:370:7348");
846 rgw_req_state.env.clear();
847 rgw_build_iam_environment(&rgw_rados, &rgw_req_state);
848 ip = rgw_req_state.env.find("aws:SourceIp");
849 ASSERT_NE(ip, rgw_req_state.env.end());
850 EXPECT_EQ(ip->second, "192.168.1.4");
851 }
852
853 TEST_F(IPPolicyTest, ParseIPAddress) {
854 boost::optional<Policy> p;
855
856 ASSERT_NO_THROW(p = Policy(cct.get(), arbitrary_tenant,
857 bufferlist::static_from_string(ip_address_full_example)));
858 ASSERT_TRUE(p);
859
860 EXPECT_EQ(p->text, ip_address_full_example);
861 EXPECT_EQ(p->version, Version::v2012_10_17);
862 EXPECT_EQ(*p->id, "S3IPPolicyTest");
863 EXPECT_FALSE(p->statements.empty());
864 EXPECT_EQ(p->statements.size(), 1U);
865 EXPECT_EQ(*p->statements[0].sid, "IPAllow");
866 EXPECT_FALSE(p->statements[0].princ.empty());
867 EXPECT_EQ(p->statements[0].princ.size(), 1U);
868 EXPECT_EQ(*p->statements[0].princ.begin(),
869 Principal::wildcard());
870 EXPECT_TRUE(p->statements[0].noprinc.empty());
871 EXPECT_EQ(p->statements[0].effect, Effect::Allow);
872 Action_t act;
873 act[s3ListBucket] = 1;
874 EXPECT_EQ(p->statements[0].action, act);
875 EXPECT_EQ(p->statements[0].notaction, None);
876 ASSERT_FALSE(p->statements[0].resource.empty());
877 ASSERT_EQ(p->statements[0].resource.size(), 2U);
878 EXPECT_EQ(p->statements[0].resource.begin()->partition, Partition::aws);
879 EXPECT_EQ(p->statements[0].resource.begin()->service, Service::s3);
880 EXPECT_TRUE(p->statements[0].resource.begin()->region.empty());
881 EXPECT_EQ(p->statements[0].resource.begin()->account, arbitrary_tenant);
882 EXPECT_EQ(p->statements[0].resource.begin()->resource, "example_bucket");
883 EXPECT_EQ((p->statements[0].resource.begin() + 1)->resource, "example_bucket/*");
884 EXPECT_TRUE(p->statements[0].notresource.empty());
885 ASSERT_FALSE(p->statements[0].conditions.empty());
886 ASSERT_EQ(p->statements[0].conditions.size(), 2U);
887 EXPECT_EQ(p->statements[0].conditions[0].op, TokenID::IpAddress);
888 EXPECT_EQ(p->statements[0].conditions[0].key, "aws:SourceIp");
889 ASSERT_FALSE(p->statements[0].conditions[0].vals.empty());
890 EXPECT_EQ(p->statements[0].conditions[0].vals.size(), 2U);
891 EXPECT_EQ(p->statements[0].conditions[0].vals[0], "192.168.1.0/24");
892 EXPECT_EQ(p->statements[0].conditions[0].vals[1], "::1");
893 boost::optional<rgw::IAM::MaskedIP> convertedIPv4 = rgw::IAM::Condition::as_network(p->statements[0].conditions[0].vals[0]);
894 EXPECT_TRUE(convertedIPv4.is_initialized());
895 if (convertedIPv4.is_initialized()) {
896 EXPECT_EQ(*convertedIPv4, allowedIPv4Range);
897 }
898
899 EXPECT_EQ(p->statements[0].conditions[1].op, TokenID::NotIpAddress);
900 EXPECT_EQ(p->statements[0].conditions[1].key, "aws:SourceIp");
901 ASSERT_FALSE(p->statements[0].conditions[1].vals.empty());
902 EXPECT_EQ(p->statements[0].conditions[1].vals.size(), 2U);
903 EXPECT_EQ(p->statements[0].conditions[1].vals[0], "192.168.1.1/32");
904 EXPECT_EQ(p->statements[0].conditions[1].vals[1], "2001:0db8:85a3:0000:0000:8a2e:0370:7334");
905 boost::optional<rgw::IAM::MaskedIP> convertedIPv6 = rgw::IAM::Condition::as_network(p->statements[0].conditions[1].vals[1]);
906 EXPECT_TRUE(convertedIPv6.is_initialized());
907 if (convertedIPv6.is_initialized()) {
908 EXPECT_EQ(*convertedIPv6, allowedIPv6);
909 }
910 }
911
912 TEST_F(IPPolicyTest, EvalIPAddress) {
913 auto allowp = Policy(cct.get(), arbitrary_tenant,
914 bufferlist::static_from_string(ip_address_allow_example));
915 auto denyp = Policy(cct.get(), arbitrary_tenant,
916 bufferlist::static_from_string(ip_address_deny_example));
917 auto fullp = Policy(cct.get(), arbitrary_tenant,
918 bufferlist::static_from_string(ip_address_full_example));
919 Environment e;
920 Environment allowedIP, blacklistedIP, allowedIPv6, blacklistedIPv6;
921 allowedIP["aws:SourceIp"] = "192.168.1.2";
922 allowedIPv6["aws:SourceIp"] = "::1";
923 blacklistedIP["aws:SourceIp"] = "192.168.1.1";
924 blacklistedIPv6["aws:SourceIp"] = "2001:0db8:85a3:0000:0000:8a2e:0370:7334";
925
926 auto trueacct = FakeIdentity(
927 Principal::tenant("ACCOUNT-ID-WITHOUT-HYPHENS"));
928 // Without an IP address in the environment then evaluation will always pass
929 EXPECT_EQ(allowp.eval(e, trueacct, s3ListBucket,
930 ARN(Partition::aws, Service::s3,
931 "", arbitrary_tenant, "example_bucket")),
932 Effect::Pass);
933 EXPECT_EQ(fullp.eval(e, trueacct, s3ListBucket,
934 ARN(Partition::aws, Service::s3,
935 "", arbitrary_tenant, "example_bucket/myobject")),
936 Effect::Pass);
937
938 EXPECT_EQ(allowp.eval(allowedIP, trueacct, s3ListBucket,
939 ARN(Partition::aws, Service::s3,
940 "", arbitrary_tenant, "example_bucket")),
941 Effect::Allow);
942 EXPECT_EQ(allowp.eval(blacklistedIPv6, trueacct, s3ListBucket,
943 ARN(Partition::aws, Service::s3,
944 "", arbitrary_tenant, "example_bucket")),
945 Effect::Pass);
946
947
948 EXPECT_EQ(denyp.eval(allowedIP, trueacct, s3ListBucket,
949 ARN(Partition::aws, Service::s3,
950 "", arbitrary_tenant, "example_bucket")),
951 Effect::Deny);
952 EXPECT_EQ(denyp.eval(allowedIP, trueacct, s3ListBucket,
953 ARN(Partition::aws, Service::s3,
954 "", arbitrary_tenant, "example_bucket/myobject")),
955 Effect::Deny);
956
957 EXPECT_EQ(denyp.eval(blacklistedIP, trueacct, s3ListBucket,
958 ARN(Partition::aws, Service::s3,
959 "", arbitrary_tenant, "example_bucket")),
960 Effect::Pass);
961 EXPECT_EQ(denyp.eval(blacklistedIP, trueacct, s3ListBucket,
962 ARN(Partition::aws, Service::s3,
963 "", arbitrary_tenant, "example_bucket/myobject")),
964 Effect::Pass);
965
966 EXPECT_EQ(denyp.eval(blacklistedIPv6, trueacct, s3ListBucket,
967 ARN(Partition::aws, Service::s3,
968 "", arbitrary_tenant, "example_bucket")),
969 Effect::Pass);
970 EXPECT_EQ(denyp.eval(blacklistedIPv6, trueacct, s3ListBucket,
971 ARN(Partition::aws, Service::s3,
972 "", arbitrary_tenant, "example_bucket/myobject")),
973 Effect::Pass);
974 EXPECT_EQ(denyp.eval(allowedIPv6, trueacct, s3ListBucket,
975 ARN(Partition::aws, Service::s3,
976 "", arbitrary_tenant, "example_bucket")),
977 Effect::Deny);
978 EXPECT_EQ(denyp.eval(allowedIPv6, trueacct, s3ListBucket,
979 ARN(Partition::aws, Service::s3,
980 "", arbitrary_tenant, "example_bucket/myobject")),
981 Effect::Deny);
982
983 EXPECT_EQ(fullp.eval(allowedIP, trueacct, s3ListBucket,
984 ARN(Partition::aws, Service::s3,
985 "", arbitrary_tenant, "example_bucket")),
986 Effect::Allow);
987 EXPECT_EQ(fullp.eval(allowedIP, trueacct, s3ListBucket,
988 ARN(Partition::aws, Service::s3,
989 "", arbitrary_tenant, "example_bucket/myobject")),
990 Effect::Allow);
991
992 EXPECT_EQ(fullp.eval(blacklistedIP, trueacct, s3ListBucket,
993 ARN(Partition::aws, Service::s3,
994 "", arbitrary_tenant, "example_bucket")),
995 Effect::Pass);
996 EXPECT_EQ(fullp.eval(blacklistedIP, trueacct, s3ListBucket,
997 ARN(Partition::aws, Service::s3,
998 "", arbitrary_tenant, "example_bucket/myobject")),
999 Effect::Pass);
1000
1001 EXPECT_EQ(fullp.eval(allowedIPv6, trueacct, s3ListBucket,
1002 ARN(Partition::aws, Service::s3,
1003 "", arbitrary_tenant, "example_bucket")),
1004 Effect::Allow);
1005 EXPECT_EQ(fullp.eval(allowedIPv6, trueacct, s3ListBucket,
1006 ARN(Partition::aws, Service::s3,
1007 "", arbitrary_tenant, "example_bucket/myobject")),
1008 Effect::Allow);
1009
1010 EXPECT_EQ(fullp.eval(blacklistedIPv6, trueacct, s3ListBucket,
1011 ARN(Partition::aws, Service::s3,
1012 "", arbitrary_tenant, "example_bucket")),
1013 Effect::Pass);
1014 EXPECT_EQ(fullp.eval(blacklistedIPv6, trueacct, s3ListBucket,
1015 ARN(Partition::aws, Service::s3,
1016 "", arbitrary_tenant, "example_bucket/myobject")),
1017 Effect::Pass);
1018 }
1019
1020 string IPPolicyTest::ip_address_allow_example = R"(
1021 {
1022 "Version": "2012-10-17",
1023 "Id": "S3SimpleIPPolicyTest",
1024 "Statement": [{
1025 "Sid": "1",
1026 "Effect": "Allow",
1027 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
1028 "Action": "s3:ListBucket",
1029 "Resource": [
1030 "arn:aws:s3:::example_bucket"
1031 ],
1032 "Condition": {
1033 "IpAddress": {"aws:SourceIp": "192.168.1.0/24"}
1034 }
1035 }]
1036 }
1037 )";
1038
1039 string IPPolicyTest::ip_address_deny_example = R"(
1040 {
1041 "Version": "2012-10-17",
1042 "Id": "S3IPPolicyTest",
1043 "Statement": {
1044 "Effect": "Deny",
1045 "Sid": "IPDeny",
1046 "Action": "s3:ListBucket",
1047 "Principal": {"AWS": ["arn:aws:iam::ACCOUNT-ID-WITHOUT-HYPHENS:root"]},
1048 "Resource": [
1049 "arn:aws:s3:::example_bucket",
1050 "arn:aws:s3:::example_bucket/*"
1051 ],
1052 "Condition": {
1053 "NotIpAddress": {"aws:SourceIp": ["192.168.1.1/32", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]}
1054 }
1055 }
1056 }
1057 )";
1058
1059 string IPPolicyTest::ip_address_full_example = R"(
1060 {
1061 "Version": "2012-10-17",
1062 "Id": "S3IPPolicyTest",
1063 "Statement": {
1064 "Effect": "Allow",
1065 "Sid": "IPAllow",
1066 "Action": "s3:ListBucket",
1067 "Principal": "*",
1068 "Resource": [
1069 "arn:aws:s3:::example_bucket",
1070 "arn:aws:s3:::example_bucket/*"
1071 ],
1072 "Condition": {
1073 "IpAddress": {"aws:SourceIp": ["192.168.1.0/24", "::1"]},
1074 "NotIpAddress": {"aws:SourceIp": ["192.168.1.1/32", "2001:0db8:85a3:0000:0000:8a2e:0370:7334"]}
1075 }
1076 }
1077 }
1078 )";
1079
1080 TEST(MatchWildcards, Simple)
1081 {
1082 EXPECT_TRUE(match_wildcards("", ""));
1083 EXPECT_TRUE(match_wildcards("", "", MATCH_CASE_INSENSITIVE));
1084 EXPECT_FALSE(match_wildcards("", "abc"));
1085 EXPECT_FALSE(match_wildcards("", "abc", MATCH_CASE_INSENSITIVE));
1086 EXPECT_FALSE(match_wildcards("abc", ""));
1087 EXPECT_FALSE(match_wildcards("abc", "", MATCH_CASE_INSENSITIVE));
1088 EXPECT_TRUE(match_wildcards("abc", "abc"));
1089 EXPECT_TRUE(match_wildcards("abc", "abc", MATCH_CASE_INSENSITIVE));
1090 EXPECT_FALSE(match_wildcards("abc", "abC"));
1091 EXPECT_TRUE(match_wildcards("abc", "abC", MATCH_CASE_INSENSITIVE));
1092 EXPECT_FALSE(match_wildcards("abC", "abc"));
1093 EXPECT_TRUE(match_wildcards("abC", "abc", MATCH_CASE_INSENSITIVE));
1094 EXPECT_FALSE(match_wildcards("abc", "abcd"));
1095 EXPECT_FALSE(match_wildcards("abc", "abcd", MATCH_CASE_INSENSITIVE));
1096 EXPECT_FALSE(match_wildcards("abcd", "abc"));
1097 EXPECT_FALSE(match_wildcards("abcd", "abc", MATCH_CASE_INSENSITIVE));
1098 }
1099
1100 TEST(MatchWildcards, QuestionMark)
1101 {
1102 EXPECT_FALSE(match_wildcards("?", ""));
1103 EXPECT_FALSE(match_wildcards("?", "", MATCH_CASE_INSENSITIVE));
1104 EXPECT_TRUE(match_wildcards("?", "a"));
1105 EXPECT_TRUE(match_wildcards("?", "a", MATCH_CASE_INSENSITIVE));
1106 EXPECT_TRUE(match_wildcards("?bc", "abc"));
1107 EXPECT_TRUE(match_wildcards("?bc", "abc", MATCH_CASE_INSENSITIVE));
1108 EXPECT_TRUE(match_wildcards("a?c", "abc"));
1109 EXPECT_TRUE(match_wildcards("a?c", "abc", MATCH_CASE_INSENSITIVE));
1110 EXPECT_FALSE(match_wildcards("abc", "a?c"));
1111 EXPECT_FALSE(match_wildcards("abc", "a?c", MATCH_CASE_INSENSITIVE));
1112 EXPECT_FALSE(match_wildcards("a?c", "abC"));
1113 EXPECT_TRUE(match_wildcards("a?c", "abC", MATCH_CASE_INSENSITIVE));
1114 EXPECT_TRUE(match_wildcards("ab?", "abc"));
1115 EXPECT_TRUE(match_wildcards("ab?", "abc", MATCH_CASE_INSENSITIVE));
1116 EXPECT_TRUE(match_wildcards("a?c?e", "abcde"));
1117 EXPECT_TRUE(match_wildcards("a?c?e", "abcde", MATCH_CASE_INSENSITIVE));
1118 EXPECT_TRUE(match_wildcards("???", "abc"));
1119 EXPECT_TRUE(match_wildcards("???", "abc", MATCH_CASE_INSENSITIVE));
1120 EXPECT_FALSE(match_wildcards("???", "abcd"));
1121 EXPECT_FALSE(match_wildcards("???", "abcd", MATCH_CASE_INSENSITIVE));
1122 }
1123
1124 TEST(MatchWildcards, Asterisk)
1125 {
1126 EXPECT_TRUE(match_wildcards("*", ""));
1127 EXPECT_TRUE(match_wildcards("*", "", MATCH_CASE_INSENSITIVE));
1128 EXPECT_FALSE(match_wildcards("", "*"));
1129 EXPECT_FALSE(match_wildcards("", "*", MATCH_CASE_INSENSITIVE));
1130 EXPECT_FALSE(match_wildcards("*a", ""));
1131 EXPECT_FALSE(match_wildcards("*a", "", MATCH_CASE_INSENSITIVE));
1132 EXPECT_TRUE(match_wildcards("*a", "a"));
1133 EXPECT_TRUE(match_wildcards("*a", "a", MATCH_CASE_INSENSITIVE));
1134 EXPECT_TRUE(match_wildcards("a*", "a"));
1135 EXPECT_TRUE(match_wildcards("a*", "a", MATCH_CASE_INSENSITIVE));
1136 EXPECT_TRUE(match_wildcards("a*c", "ac"));
1137 EXPECT_TRUE(match_wildcards("a*c", "ac", MATCH_CASE_INSENSITIVE));
1138 EXPECT_TRUE(match_wildcards("a*c", "abbc"));
1139 EXPECT_TRUE(match_wildcards("a*c", "abbc", MATCH_CASE_INSENSITIVE));
1140 EXPECT_FALSE(match_wildcards("a*c", "abbC"));
1141 EXPECT_TRUE(match_wildcards("a*c", "abbC", MATCH_CASE_INSENSITIVE));
1142 EXPECT_TRUE(match_wildcards("a*c*e", "abBce"));
1143 EXPECT_TRUE(match_wildcards("a*c*e", "abBce", MATCH_CASE_INSENSITIVE));
1144 EXPECT_TRUE(match_wildcards("http://*.example.com",
1145 "http://www.example.com"));
1146 EXPECT_TRUE(match_wildcards("http://*.example.com",
1147 "http://www.example.com", MATCH_CASE_INSENSITIVE));
1148 EXPECT_FALSE(match_wildcards("http://*.example.com",
1149 "http://www.Example.com"));
1150 EXPECT_TRUE(match_wildcards("http://*.example.com",
1151 "http://www.Example.com", MATCH_CASE_INSENSITIVE));
1152 EXPECT_TRUE(match_wildcards("http://example.com/*",
1153 "http://example.com/index.html"));
1154 EXPECT_TRUE(match_wildcards("http://example.com/*/*.jpg",
1155 "http://example.com/fun/smiley.jpg"));
1156 // note: parsing of * is not greedy, so * does not match 'bc' here
1157 EXPECT_FALSE(match_wildcards("a*c", "abcc"));
1158 EXPECT_FALSE(match_wildcards("a*c", "abcc", MATCH_CASE_INSENSITIVE));
1159 }
1160
1161 TEST(MatchPolicy, Action)
1162 {
1163 constexpr auto flag = MATCH_POLICY_ACTION;
1164 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
1165 EXPECT_TRUE(match_policy("a:b:c", "A:B:C", flag)); // case insensitive
1166 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
1167 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
1168 }
1169
1170 TEST(MatchPolicy, Resource)
1171 {
1172 constexpr auto flag = MATCH_POLICY_RESOURCE;
1173 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
1174 EXPECT_FALSE(match_policy("a:b:c", "A:B:C", flag)); // case sensitive
1175 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
1176 EXPECT_TRUE(match_policy("a:*", "a:b:c", flag)); // can span segments
1177 }
1178
1179 TEST(MatchPolicy, ARN)
1180 {
1181 constexpr auto flag = MATCH_POLICY_ARN;
1182 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
1183 EXPECT_TRUE(match_policy("a:b:c", "A:B:C", flag)); // case insensitive
1184 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
1185 EXPECT_FALSE(match_policy("a:*", "a:b:c", flag)); // cannot span segments
1186 }
1187
1188 TEST(MatchPolicy, String)
1189 {
1190 constexpr auto flag = MATCH_POLICY_STRING;
1191 EXPECT_TRUE(match_policy("a:b:c", "a:b:c", flag));
1192 EXPECT_FALSE(match_policy("a:b:c", "A:B:C", flag)); // case sensitive
1193 EXPECT_TRUE(match_policy("a:*:e", "a:bcd:e", flag));
1194 EXPECT_TRUE(match_policy("a:*", "a:b:c", flag)); // can span segments
1195 }