Matter SDK Coverage Report
Current view: top level - access - AccessControl.h (source / functions) Coverage Total Hit
Test: SHA:3f9cd168e84cd831b7699126f5296f5c5498690f Lines: 79.2 % 178 141
Test Date: 2026-04-27 19:52:19 Functions: 71.8 % 103 74

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

Generated by: LCOV version 2.0-1