Matter SDK Coverage Report
Current view: top level - access - AccessControl.h (source / functions) Coverage Total Hit
Test: SHA:b879ecb8e99e175eea0a293a888bda853da2b19c Lines: 16.7 % 114 19
Test Date: 2025-01-17 19:00:11 Functions: 17.9 % 78 14

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

Generated by: LCOV version 2.0-1