Line data Source code
1 : /*
2 : *
3 : * Copyright (c) 2021 Project CHIP Authors
4 : * All rights reserved.
5 : *
6 : * Licensed under the Apache License, Version 2.0 (the "License");
7 : * you may not use this file except in compliance with the License.
8 : * You may obtain a copy of the License at
9 : *
10 : * http://www.apache.org/licenses/LICENSE-2.0
11 : *
12 : * Unless required by applicable law or agreed to in writing, software
13 : * distributed under the License is distributed on an "AS IS" BASIS,
14 : * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 : * See the License for the specific language governing permissions and
16 : * limitations under the License.
17 : */
18 :
19 : #pragma once
20 :
21 : #include "Privilege.h"
22 : #include "RequestPath.h"
23 : #include "SubjectDescriptor.h"
24 :
25 : #include <lib/core/CHIPCore.h>
26 : #include <lib/core/Global.h>
27 : #include <lib/support/CodeUtils.h>
28 :
29 : // Dump function for use during development only (0 for disabled, non-zero for enabled).
30 : #define CHIP_ACCESS_CONTROL_DUMP_ENABLED 0
31 :
32 : namespace chip {
33 : namespace Access {
34 :
35 : class AccessControl
36 : {
37 : public:
38 : /**
39 : * Used by access control to determine if a device type resolves to an endpoint.
40 : */
41 : struct DeviceTypeResolver
42 : {
43 : public:
44 3 : virtual ~DeviceTypeResolver() = default;
45 :
46 : virtual bool IsDeviceTypeOnEndpoint(DeviceTypeId deviceType, EndpointId endpoint) = 0;
47 : };
48 :
49 : /**
50 : * Handle to an entry in the access control list.
51 : *
52 : * Must be prepared (`AccessControl::PrepareEntry`) or read (`AccessControl::ReadEntry`) before first use.
53 : */
54 : class Entry
55 : {
56 : public:
57 : struct Target
58 : {
59 : using Flags = unsigned;
60 : static constexpr Flags kCluster = 1 << 0;
61 : static constexpr Flags kEndpoint = 1 << 1;
62 : static constexpr Flags kDeviceType = 1 << 2;
63 : Flags flags = 0;
64 : ClusterId cluster;
65 : EndpointId endpoint;
66 : DeviceTypeId deviceType;
67 : };
68 :
69 : class Delegate
70 : {
71 : public:
72 : Delegate() = default;
73 :
74 : Delegate(const Delegate &) = delete;
75 : Delegate & operator=(const Delegate &) = delete;
76 :
77 27 : virtual ~Delegate() = default;
78 :
79 0 : virtual void Release() {}
80 :
81 : // Simple getters
82 0 : virtual CHIP_ERROR GetAuthMode(AuthMode & authMode) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
83 0 : virtual CHIP_ERROR GetFabricIndex(FabricIndex & fabricIndex) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
84 0 : virtual CHIP_ERROR GetPrivilege(Privilege & privilege) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
85 :
86 : // Simple setters
87 0 : virtual CHIP_ERROR SetAuthMode(AuthMode authMode) { return CHIP_ERROR_NOT_IMPLEMENTED; }
88 0 : virtual CHIP_ERROR SetFabricIndex(FabricIndex fabricIndex) { return CHIP_ERROR_NOT_IMPLEMENTED; }
89 0 : virtual CHIP_ERROR SetPrivilege(Privilege privilege) { return CHIP_ERROR_NOT_IMPLEMENTED; }
90 :
91 : // Subjects
92 0 : virtual CHIP_ERROR GetSubjectCount(size_t & count) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
93 0 : virtual CHIP_ERROR GetSubject(size_t index, NodeId & subject) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
94 0 : virtual CHIP_ERROR SetSubject(size_t index, NodeId subject) { return CHIP_ERROR_NOT_IMPLEMENTED; }
95 0 : virtual CHIP_ERROR AddSubject(size_t * index, NodeId subject) { return CHIP_ERROR_NOT_IMPLEMENTED; }
96 0 : virtual CHIP_ERROR RemoveSubject(size_t index) { return CHIP_ERROR_NOT_IMPLEMENTED; }
97 :
98 : // Targets
99 0 : virtual CHIP_ERROR GetTargetCount(size_t & count) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
100 0 : virtual CHIP_ERROR GetTarget(size_t index, Target & target) const { return CHIP_ERROR_NOT_IMPLEMENTED; }
101 0 : virtual CHIP_ERROR SetTarget(size_t index, const Target & target) { return CHIP_ERROR_NOT_IMPLEMENTED; }
102 0 : virtual CHIP_ERROR AddTarget(size_t * index, const Target & target) { return CHIP_ERROR_NOT_IMPLEMENTED; }
103 0 : virtual CHIP_ERROR RemoveTarget(size_t index) { return CHIP_ERROR_NOT_IMPLEMENTED; }
104 : };
105 :
106 0 : Entry() = default;
107 :
108 : Entry(Entry && other) : mDelegate(other.mDelegate) { other.mDelegate = &mDefaultDelegate.get(); }
109 :
110 : Entry & operator=(Entry && other)
111 : {
112 : if (this != &other)
113 : {
114 : mDelegate->Release();
115 : mDelegate = other.mDelegate;
116 : other.mDelegate = &mDefaultDelegate.get();
117 : }
118 : return *this;
119 : }
120 :
121 : Entry(const Entry &) = delete;
122 : Entry & operator=(const Entry &) = delete;
123 :
124 0 : ~Entry() { mDelegate->Release(); }
125 :
126 : // Simple getters
127 0 : CHIP_ERROR GetAuthMode(AuthMode & authMode) const { return mDelegate->GetAuthMode(authMode); }
128 0 : CHIP_ERROR GetFabricIndex(FabricIndex & fabricIndex) const { return mDelegate->GetFabricIndex(fabricIndex); }
129 0 : CHIP_ERROR GetPrivilege(Privilege & privilege) const { return mDelegate->GetPrivilege(privilege); }
130 :
131 : // Simple setters
132 0 : CHIP_ERROR SetAuthMode(AuthMode authMode) { return mDelegate->SetAuthMode(authMode); }
133 0 : CHIP_ERROR SetFabricIndex(FabricIndex fabricIndex) { return mDelegate->SetFabricIndex(fabricIndex); }
134 0 : CHIP_ERROR SetPrivilege(Privilege privilege) { return mDelegate->SetPrivilege(privilege); }
135 :
136 : /**
137 : * Gets the number of subjects.
138 : *
139 : * @param [out] count The number of subjects.
140 : */
141 0 : CHIP_ERROR GetSubjectCount(size_t & count) const { return mDelegate->GetSubjectCount(count); }
142 :
143 : /**
144 : * Gets the specified subject.
145 : *
146 : * @param [in] index The index of the subject to get.
147 : * @param [out] subject The subject into which to get.
148 : */
149 0 : CHIP_ERROR GetSubject(size_t index, NodeId & subject) const { return mDelegate->GetSubject(index, subject); }
150 :
151 : /**
152 : * Sets the specified subject.
153 : *
154 : * @param [in] index The index of the subject to set.
155 : * @param [in] subject The subject from which to set.
156 : */
157 : CHIP_ERROR SetSubject(size_t index, NodeId subject) { return mDelegate->SetSubject(index, subject); }
158 :
159 : /**
160 : * Adds the specified subject.
161 : *
162 : * @param [out] index The index of the added subject, if not null.
163 : * @param [in] subject The subject to add.
164 : */
165 0 : CHIP_ERROR AddSubject(size_t * index, NodeId subject) { return mDelegate->AddSubject(index, subject); }
166 :
167 : /**
168 : * Removes the specified subject.
169 : *
170 : * @param [in] index The index of the subject to delete.
171 : */
172 : CHIP_ERROR RemoveSubject(size_t index) { return mDelegate->RemoveSubject(index); }
173 :
174 : /**
175 : * Gets the number of targets.
176 : *
177 : * @param [out] count The number of targets.
178 : */
179 0 : CHIP_ERROR GetTargetCount(size_t & count) const { return mDelegate->GetTargetCount(count); }
180 :
181 : /**
182 : * Gets the specified target.
183 : *
184 : * @param [in] index The index of the target to get.
185 : * @param [out] target The target into which to get.
186 : */
187 0 : CHIP_ERROR GetTarget(size_t index, Target & target) const { return mDelegate->GetTarget(index, target); }
188 :
189 : /**
190 : * Sets the specified target.
191 : *
192 : * @param [in] index The index of the target to set.
193 : * @param [in] target The target from which to set.
194 : */
195 : CHIP_ERROR SetTarget(size_t index, const Target & target) { return mDelegate->SetTarget(index, target); }
196 :
197 : /**
198 : * Adds the specified target.
199 : *
200 : * @param [out] index The index of the added target, if not null.
201 : * @param [in] target The target to add.
202 : */
203 0 : CHIP_ERROR AddTarget(size_t * index, const Target & target) { return mDelegate->AddTarget(index, target); }
204 :
205 : /**
206 : * Removes the specified target.
207 : *
208 : * @param [in] index The index of the target to delete.
209 : */
210 : CHIP_ERROR RemoveTarget(size_t index) { return mDelegate->RemoveTarget(index); }
211 :
212 0 : bool HasDefaultDelegate() const { return mDelegate == &mDefaultDelegate.get(); }
213 :
214 1416 : const Delegate & GetDelegate() const { return *mDelegate; }
215 :
216 1251 : Delegate & GetDelegate() { return *mDelegate; }
217 :
218 0 : void SetDelegate(Delegate & delegate)
219 : {
220 0 : mDelegate->Release();
221 0 : mDelegate = &delegate;
222 0 : }
223 :
224 0 : void ResetDelegate()
225 : {
226 0 : mDelegate->Release();
227 0 : mDelegate = &mDefaultDelegate.get();
228 0 : }
229 :
230 : private:
231 : static Global<Delegate> mDefaultDelegate;
232 : Delegate * mDelegate = &mDefaultDelegate.get();
233 : };
234 :
235 : /**
236 : * Handle to an entry iterator in the access control list.
237 : *
238 : * Must be initialized (`AccessControl::Entries`) before first use.
239 : */
240 : class EntryIterator
241 : {
242 : public:
243 : class Delegate
244 : {
245 : public:
246 2 : Delegate() = default;
247 :
248 : Delegate(const Delegate &) = delete;
249 : Delegate & operator=(const Delegate &) = delete;
250 :
251 29 : virtual ~Delegate() = default;
252 :
253 53 : virtual void Release() {}
254 :
255 0 : virtual CHIP_ERROR Next(Entry & entry) { return CHIP_ERROR_SENTINEL; }
256 : };
257 :
258 0 : EntryIterator() = default;
259 :
260 : EntryIterator(const EntryIterator &) = delete;
261 : EntryIterator & operator=(const EntryIterator &) = delete;
262 :
263 0 : ~EntryIterator() { mDelegate->Release(); }
264 :
265 0 : CHIP_ERROR Next(Entry & entry) { return mDelegate->Next(entry); }
266 :
267 : const Delegate & GetDelegate() const { return *mDelegate; }
268 :
269 56 : Delegate & GetDelegate() { return *mDelegate; }
270 :
271 56 : void SetDelegate(Delegate & delegate)
272 : {
273 56 : mDelegate->Release();
274 56 : mDelegate = &delegate;
275 56 : }
276 :
277 : void ResetDelegate()
278 : {
279 : mDelegate->Release();
280 : mDelegate = &mDefaultDelegate.get();
281 : }
282 :
283 : private:
284 : static Global<Delegate> mDefaultDelegate;
285 : Delegate * mDelegate = &mDefaultDelegate.get();
286 : };
287 :
288 : /**
289 : * Used by access control to notify of changes in access control list.
290 : */
291 : class EntryListener
292 : {
293 : public:
294 : enum class ChangeType
295 : {
296 : kAdded = 1,
297 : kRemoved = 2,
298 : kUpdated = 3
299 : };
300 :
301 1 : virtual ~EntryListener() = default;
302 :
303 : /**
304 : * Notifies of a change in the access control list.
305 : *
306 : * The fabric is indicated by its own parameter. If available, a subject descriptor will
307 : * have more detail (and its fabric index will match). A best effort is made to provide
308 : * the latest value of the changed entry.
309 : *
310 : * @param [in] subjectDescriptor Optional (if available) subject descriptor for this operation.
311 : * @param [in] fabric Index of fabric in which entry has changed.
312 : * @param [in] index Index of entry to which has changed (relative to fabric).
313 : * @param [in] entry Optional (best effort) latest value of entry which has changed.
314 : * @param [in] changeType Type of change.
315 : */
316 : virtual void OnEntryChanged(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t index,
317 : const Entry * entry, ChangeType changeType) = 0;
318 :
319 : private:
320 : EntryListener * mNext = nullptr;
321 :
322 : friend class AccessControl;
323 : };
324 :
325 : class Delegate
326 : {
327 : public:
328 : Delegate() = default;
329 :
330 : Delegate(const Delegate &) = delete;
331 : Delegate & operator=(const Delegate &) = delete;
332 :
333 12 : virtual ~Delegate() = default;
334 :
335 0 : virtual void Release() {}
336 :
337 0 : virtual CHIP_ERROR Init() { return CHIP_NO_ERROR; }
338 0 : virtual void Finish() {}
339 :
340 : // Capabilities
341 0 : virtual CHIP_ERROR GetMaxEntriesPerFabric(size_t & value) const
342 : {
343 0 : value = 0;
344 0 : return CHIP_NO_ERROR;
345 : }
346 :
347 0 : virtual CHIP_ERROR GetMaxSubjectsPerEntry(size_t & value) const
348 : {
349 0 : value = 0;
350 0 : return CHIP_NO_ERROR;
351 : }
352 :
353 0 : virtual CHIP_ERROR GetMaxTargetsPerEntry(size_t & value) const
354 : {
355 0 : value = 0;
356 0 : return CHIP_NO_ERROR;
357 : }
358 :
359 0 : virtual CHIP_ERROR GetMaxEntryCount(size_t & value) const
360 : {
361 0 : value = 0;
362 0 : return CHIP_NO_ERROR;
363 : }
364 :
365 : // Actualities
366 0 : virtual CHIP_ERROR GetEntryCount(FabricIndex fabric, size_t & value) const
367 : {
368 0 : value = 0;
369 0 : return CHIP_NO_ERROR;
370 : }
371 :
372 0 : virtual CHIP_ERROR GetEntryCount(size_t & value) const
373 : {
374 0 : value = 0;
375 0 : return CHIP_NO_ERROR;
376 : }
377 :
378 : // Preparation
379 0 : virtual CHIP_ERROR PrepareEntry(Entry & entry) { return CHIP_NO_ERROR; }
380 :
381 : // CRUD
382 0 : virtual CHIP_ERROR CreateEntry(size_t * index, const Entry & entry, FabricIndex * fabricIndex) { return CHIP_NO_ERROR; }
383 0 : virtual CHIP_ERROR ReadEntry(size_t index, Entry & entry, const FabricIndex * fabricIndex) const { return CHIP_NO_ERROR; }
384 0 : virtual CHIP_ERROR UpdateEntry(size_t index, const Entry & entry, const FabricIndex * fabricIndex) { return CHIP_NO_ERROR; }
385 0 : virtual CHIP_ERROR DeleteEntry(size_t index, const FabricIndex * fabricIndex) { return CHIP_NO_ERROR; }
386 :
387 : // Iteration
388 0 : virtual CHIP_ERROR Entries(EntryIterator & iterator, const FabricIndex * fabricIndex) const { return CHIP_NO_ERROR; }
389 :
390 : // Check
391 : // Return CHIP_NO_ERROR if allowed, CHIP_ERROR_ACCESS_DENIED if denied,
392 : // CHIP_ERROR_NOT_IMPLEMENTED to use the default check algorithm (against entries),
393 : // or any other CHIP_ERROR if another error occurred.
394 0 : virtual CHIP_ERROR Check(const SubjectDescriptor & subjectDescriptor, const RequestPath & requestPath,
395 : Privilege requestPrivilege)
396 : {
397 0 : return CHIP_ERROR_ACCESS_DENIED;
398 : }
399 : };
400 :
401 1 : AccessControl() = default;
402 :
403 : AccessControl(const AccessControl &) = delete;
404 : AccessControl & operator=(const AccessControl &) = delete;
405 :
406 38 : ~AccessControl()
407 : {
408 : // Never-initialized AccessControl instances will not have the delegate set.
409 38 : if (IsInitialized())
410 : {
411 0 : mDelegate->Release();
412 : }
413 38 : }
414 :
415 : /**
416 : * Initialize the access control module. Must be called before first use.
417 : *
418 : * @return CHIP_NO_ERROR on success, CHIP_ERROR_INCORRECT_STATE if called more than once,
419 : * CHIP_ERROR_INVALID_ARGUMENT if delegate is null, or other fatal error.
420 : */
421 : CHIP_ERROR Init(AccessControl::Delegate * delegate, DeviceTypeResolver & deviceTypeResolver);
422 :
423 : /**
424 : * Deinitialize the access control module. Must be called when finished.
425 : */
426 : void Finish();
427 :
428 : // Capabilities
429 : CHIP_ERROR GetMaxEntriesPerFabric(size_t & value) const
430 : {
431 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
432 : return mDelegate->GetMaxEntriesPerFabric(value);
433 : }
434 :
435 : CHIP_ERROR GetMaxSubjectsPerEntry(size_t & value) const
436 : {
437 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
438 : return mDelegate->GetMaxSubjectsPerEntry(value);
439 : }
440 :
441 : CHIP_ERROR GetMaxTargetsPerEntry(size_t & value) const
442 : {
443 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
444 : return mDelegate->GetMaxTargetsPerEntry(value);
445 : }
446 :
447 : CHIP_ERROR GetMaxEntryCount(size_t & value) const
448 : {
449 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
450 : return mDelegate->GetMaxEntryCount(value);
451 : }
452 :
453 : // Actualities
454 0 : CHIP_ERROR GetEntryCount(FabricIndex fabric, size_t & value) const
455 : {
456 0 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
457 0 : return mDelegate->GetEntryCount(fabric, value);
458 : }
459 :
460 : CHIP_ERROR GetEntryCount(size_t & value) const
461 : {
462 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
463 : return mDelegate->GetEntryCount(value);
464 : }
465 :
466 : /**
467 : * Prepares an entry.
468 : *
469 : * An entry must be prepared or read (`ReadEntry`) before first use.
470 : *
471 : * @param [in] entry Entry to prepare.
472 : */
473 0 : CHIP_ERROR PrepareEntry(Entry & entry)
474 : {
475 0 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
476 0 : return mDelegate->PrepareEntry(entry);
477 : }
478 :
479 : /**
480 : * Creates an entry in the access control list.
481 : *
482 : * @param [in] subjectDescriptor Optional subject descriptor for this operation.
483 : * @param [in] fabric Index of fabric in which to create entry.
484 : * @param [out] index (If not nullptr) index of created entry (relative to fabric).
485 : * @param [in] entry Entry from which created entry is copied.
486 : */
487 : CHIP_ERROR CreateEntry(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t * index, const Entry & entry);
488 :
489 : /**
490 : * Creates an entry in the access control list.
491 : *
492 : * @param [out] index Entry index of created entry, if not null. May be relative to `fabricIndex`.
493 : * @param [in] entry Entry from which to copy.
494 : * @param [out] fabricIndex Fabric index of created entry, if not null, in which case entry `index` will be relative to fabric.
495 : */
496 : CHIP_ERROR CreateEntry(size_t * index, const Entry & entry, FabricIndex * fabricIndex = nullptr)
497 : {
498 : ReturnErrorCodeIf(!IsValid(entry), CHIP_ERROR_INVALID_ARGUMENT);
499 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
500 : return mDelegate->CreateEntry(index, entry, fabricIndex);
501 : }
502 :
503 : /**
504 : * Reads an entry in the access control list.
505 : *
506 : * @param [in] fabric Index of fabric in which to read entry.
507 : * @param [in] index Index of entry to read (relative to fabric).
508 : * @param [in] entry Entry into which read entry is copied.
509 : */
510 0 : CHIP_ERROR ReadEntry(FabricIndex fabric, size_t index, Entry & entry) const
511 : {
512 0 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
513 0 : return mDelegate->ReadEntry(index, entry, &fabric);
514 : }
515 :
516 : /**
517 : * Reads an entry from the access control list.
518 : *
519 : * @param [in] index Entry index of entry to read. May be relative to `fabricIndex`.
520 : * @param [out] entry Entry into which to copy.
521 : * @param [in] fabricIndex Fabric to which entry `index` is relative, if not null.
522 : */
523 : CHIP_ERROR ReadEntry(size_t index, Entry & entry, const FabricIndex * fabricIndex = nullptr) const
524 : {
525 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
526 : return mDelegate->ReadEntry(index, entry, fabricIndex);
527 : }
528 :
529 : /**
530 : * Updates an entry in the access control list.
531 : *
532 : * @param [in] subjectDescriptor Optional subject descriptor for this operation.
533 : * @param [in] fabric Index of fabric in which to update entry.
534 : * @param [in] index Index of entry to update (relative to fabric).
535 : * @param [in] entry Entry from which updated entry is copied.
536 : */
537 : CHIP_ERROR UpdateEntry(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t index, const Entry & entry);
538 :
539 : /**
540 : * Updates an entry in the access control list.
541 : *
542 : * @param [in] index Entry index of entry to update, if not null. May be relative to `fabricIndex`.
543 : * @param [in] entry Entry from which to copy.
544 : * @param [in] fabricIndex Fabric to which entry `index` is relative, if not null.
545 : */
546 : CHIP_ERROR UpdateEntry(size_t index, const Entry & entry, const FabricIndex * fabricIndex = nullptr)
547 : {
548 : ReturnErrorCodeIf(!IsValid(entry), CHIP_ERROR_INVALID_ARGUMENT);
549 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
550 : return mDelegate->UpdateEntry(index, entry, fabricIndex);
551 : }
552 :
553 : /**
554 : * Deletes an entry in the access control list.
555 : *
556 : * @param [in] subjectDescriptor Optional subject descriptor for this operation.
557 : * @param [in] fabric Index of fabric in which to delete entry.
558 : * @param [in] index Index of entry to delete (relative to fabric).
559 : */
560 : CHIP_ERROR DeleteEntry(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t index);
561 :
562 : /**
563 : * Deletes an entry from the access control list.
564 : *
565 : * @param [in] index Entry index of entry to delete. May be relative to `fabricIndex`.
566 : * @param [in] fabricIndex Fabric to which entry `index` is relative, if not null.
567 : */
568 : CHIP_ERROR DeleteEntry(size_t index, const FabricIndex * fabricIndex = nullptr)
569 : {
570 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
571 : return mDelegate->DeleteEntry(index, fabricIndex);
572 : }
573 :
574 : /**
575 : * @brief Remove all ACL entries for the given fabricIndex
576 : *
577 : * @param[in] fabricIndex fabric index for which to remove all entries
578 : */
579 0 : CHIP_ERROR DeleteAllEntriesForFabric(FabricIndex fabricIndex)
580 : {
581 0 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
582 :
583 0 : CHIP_ERROR stickyError = CHIP_NO_ERROR;
584 :
585 : // Remove access control entries in reverse order (it could be any order, but reverse order
586 : // will cause less churn in persistent storage).
587 0 : size_t aclCount = 0;
588 0 : if (GetEntryCount(fabricIndex, aclCount) == CHIP_NO_ERROR)
589 : {
590 0 : while (aclCount)
591 : {
592 0 : CHIP_ERROR err = DeleteEntry(nullptr, fabricIndex, --aclCount);
593 0 : stickyError = (stickyError == CHIP_NO_ERROR) ? err : stickyError;
594 : }
595 : }
596 :
597 0 : return stickyError;
598 : }
599 :
600 : /**
601 : * Iterates over entries in the access control list.
602 : *
603 : * @param [in] fabric Fabric over which to iterate entries.
604 : * @param [out] iterator Iterator controlling the iteration.
605 : */
606 : CHIP_ERROR Entries(FabricIndex fabric, EntryIterator & iterator) const
607 : {
608 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
609 : return mDelegate->Entries(iterator, &fabric);
610 : }
611 :
612 : /**
613 : * Iterates over entries in the access control list.
614 : *
615 : * @param [out] iterator Iterator controlling the iteration.
616 : * @param [in] fabricIndex Iteration is confined to fabric, if not null.
617 : */
618 0 : CHIP_ERROR Entries(EntryIterator & iterator, const FabricIndex * fabricIndex = nullptr) const
619 : {
620 0 : VerifyOrReturnError(IsInitialized(), CHIP_ERROR_INCORRECT_STATE);
621 0 : return mDelegate->Entries(iterator, fabricIndex);
622 : }
623 :
624 : // Adds a listener to the end of the listener list, if not already in the list.
625 : void AddEntryListener(EntryListener & listener);
626 :
627 : // Removes a listener from the listener list, if in the list.
628 : void RemoveEntryListener(EntryListener & listener);
629 :
630 : /**
631 : * Check whether access (by a subject descriptor, to a request path,
632 : * requiring a privilege) should be allowed or denied.
633 : *
634 : * @retval #CHIP_ERROR_ACCESS_DENIED if denied.
635 : * @retval other errors should also be treated as denied.
636 : * @retval #CHIP_NO_ERROR if allowed.
637 : */
638 : CHIP_ERROR Check(const SubjectDescriptor & subjectDescriptor, const RequestPath & requestPath, Privilege requestPrivilege);
639 :
640 : #if CHIP_ACCESS_CONTROL_DUMP_ENABLED
641 : CHIP_ERROR Dump(const Entry & entry);
642 : #endif
643 :
644 : private:
645 1011 : bool IsInitialized() const { return (mDelegate != nullptr); }
646 :
647 : bool IsValid(const Entry & entry);
648 :
649 : void NotifyEntryChanged(const SubjectDescriptor * subjectDescriptor, FabricIndex fabric, size_t index, const Entry * entry,
650 : EntryListener::ChangeType changeType);
651 :
652 : private:
653 : Delegate * mDelegate = nullptr;
654 :
655 : DeviceTypeResolver * mDeviceTypeResolver = nullptr;
656 :
657 : EntryListener * mEntryListener = nullptr;
658 : };
659 :
660 : /**
661 : * Get the global instance set by SetAccessControl, or the default.
662 : *
663 : * Calls to this function must be synchronized externally.
664 : */
665 : AccessControl & GetAccessControl();
666 :
667 : /**
668 : * Set the global instance returned by GetAccessControl.
669 : *
670 : * Calls to this function must be synchronized externally.
671 : */
672 : void SetAccessControl(AccessControl & accessControl);
673 :
674 : /**
675 : * Reset the global instance to the default.
676 : *
677 : * Calls to this function must be synchronized externally.
678 : */
679 : void ResetAccessControlToDefault();
680 :
681 : } // namespace Access
682 : } // namespace chip
|