@@ -188,6 +188,30 @@ class IcdManagementFabricDelegate : public FabricTable::Delegate
188
188
IcdManagementFabricDelegate gFabricDelegate ;
189
189
IcdManagementAttributeAccess gAttribute ;
190
190
191
+ /* *
192
+ * @brief Function checks if the client as admin permissions to the cluster in the commandPath
193
+ *
194
+ * @param[out] isClientAdmin True : Client has admin permissions
195
+ * False : Client does not have admin permissions
196
+ * If an error ocurs, isClientAdmin is not changed
197
+ * @return CHIP_ERROR
198
+ */
199
+ CHIP_ERROR CheckAdmin (CommandHandler * commandObj, const ConcreteCommandPath & commandPath, bool & isClientAdmin)
200
+ {
201
+ RequestPath requestPath{ .cluster = commandPath.mClusterId , .endpoint = commandPath.mEndpointId };
202
+ CHIP_ERROR err = GetAccessControl ().Check (commandObj->GetSubjectDescriptor (), requestPath, Privilege::kAdminister );
203
+ if (CHIP_NO_ERROR == err)
204
+ {
205
+ isClientAdmin = true ;
206
+ }
207
+ else if (CHIP_ERROR_ACCESS_DENIED == err)
208
+ {
209
+ isClientAdmin = false ;
210
+ err = CHIP_NO_ERROR;
211
+ }
212
+ return err;
213
+ }
214
+
191
215
} // namespace
192
216
193
217
/*
@@ -198,22 +222,32 @@ PersistentStorageDelegate * ICDManagementServer::mStorage = nullptr;
198
222
Crypto::SymmetricKeystore * ICDManagementServer::mSymmetricKeystore = nullptr ;
199
223
ICDConfigurationData * ICDManagementServer::mICDConfigurationData = nullptr ;
200
224
201
- Status ICDManagementServer::RegisterClient (FabricIndex fabric_index, NodeId node_id, uint64_t monitored_subject, ByteSpan key ,
202
- Optional<ByteSpan> verification_key, bool isAdmin , uint32_t & icdCounter)
225
+ Status ICDManagementServer::RegisterClient (CommandHandler * commandObj, const ConcreteCommandPath & commandPath ,
226
+ const Commands::RegisterClient::DecodableType & commandData , uint32_t & icdCounter)
203
227
{
228
+ FabricIndex fabricIndex = commandObj->GetAccessingFabricIndex ();
229
+ NodeId nodeId = commandData.checkInNodeID ;
230
+ uint64_t monitoredSubject = commandData.monitoredSubject ;
231
+ ByteSpan key = commandData.key ;
232
+ Optional<ByteSpan> verificationKey = commandData.verificationKey ;
233
+ bool isClientAdmin = false ;
234
+
235
+ // Check if client is admin
236
+ VerifyOrReturnError (CHIP_NO_ERROR == CheckAdmin (commandObj, commandPath, isClientAdmin), InteractionModel::Status::Failure);
237
+
204
238
bool isFirstEntryForFabric = false ;
205
- ICDMonitoringTable table (*mStorage , fabric_index , mICDConfigurationData ->GetClientsSupportedPerFabric (), mSymmetricKeystore );
239
+ ICDMonitoringTable table (*mStorage , fabricIndex , mICDConfigurationData ->GetClientsSupportedPerFabric (), mSymmetricKeystore );
206
240
207
241
// Get current entry, if exists
208
242
ICDMonitoringEntry entry (mSymmetricKeystore );
209
- CHIP_ERROR err = table.Find (node_id , entry);
243
+ CHIP_ERROR err = table.Find (nodeId , entry);
210
244
if (CHIP_NO_ERROR == err)
211
245
{
212
246
// Existing entry: Validate Key if, and only if, the ISD does NOT have administrator permissions
213
- if (!isAdmin )
247
+ if (!isClientAdmin )
214
248
{
215
- VerifyOrReturnError (verification_key .HasValue (), InteractionModel::Status::Failure);
216
- VerifyOrReturnError (entry.IsKeyEquivalent (verification_key .Value ()), InteractionModel::Status::Failure);
249
+ VerifyOrReturnError (verificationKey .HasValue (), InteractionModel::Status::Failure);
250
+ VerifyOrReturnError (entry.IsKeyEquivalent (verificationKey .Value ()), InteractionModel::Status::Failure);
217
251
}
218
252
}
219
253
else if (CHIP_ERROR_NOT_FOUND == err)
@@ -231,8 +265,8 @@ Status ICDManagementServer::RegisterClient(FabricIndex fabric_index, NodeId node
231
265
}
232
266
233
267
// Save
234
- entry.checkInNodeID = node_id ;
235
- entry.monitoredSubject = monitored_subject ;
268
+ entry.checkInNodeID = nodeId ;
269
+ entry.monitoredSubject = monitoredSubject ;
236
270
if (entry.keyHandleValid )
237
271
{
238
272
entry.DeleteKey ();
@@ -262,19 +296,27 @@ Status ICDManagementServer::RegisterClient(FabricIndex fabric_index, NodeId node
262
296
return InteractionModel::Status::Success;
263
297
}
264
298
265
- Status ICDManagementServer::UnregisterClient (FabricIndex fabric_index, NodeId node_id, Optional<ByteSpan> verificationKey ,
266
- bool isAdmin )
299
+ Status ICDManagementServer::UnregisterClient (CommandHandler * commandObj, const ConcreteCommandPath & commandPath ,
300
+ const Commands::UnregisterClient::DecodableType & commandData )
267
301
{
268
- ICDMonitoringTable table (*mStorage , fabric_index, mICDConfigurationData ->GetClientsSupportedPerFabric (), mSymmetricKeystore );
302
+ FabricIndex fabricIndex = commandObj->GetAccessingFabricIndex ();
303
+ NodeId nodeId = commandData.checkInNodeID ;
304
+ Optional<ByteSpan> verificationKey = commandData.verificationKey ;
305
+ bool isClientAdmin = false ;
306
+
307
+ // Check if client is admin
308
+ VerifyOrReturnError (CHIP_NO_ERROR == CheckAdmin (commandObj, commandPath, isClientAdmin), InteractionModel::Status::Failure);
309
+
310
+ ICDMonitoringTable table (*mStorage , fabricIndex, mICDConfigurationData ->GetClientsSupportedPerFabric (), mSymmetricKeystore );
269
311
270
312
// Get current entry, if exists
271
313
ICDMonitoringEntry entry (mSymmetricKeystore );
272
- CHIP_ERROR err = table.Find (node_id , entry);
314
+ CHIP_ERROR err = table.Find (nodeId , entry);
273
315
VerifyOrReturnError (CHIP_ERROR_NOT_FOUND != err, InteractionModel::Status::NotFound);
274
316
VerifyOrReturnError (CHIP_NO_ERROR == err, InteractionModel::Status::Failure);
275
317
276
318
// Existing entry: Validate Key if, and only if, the ISD has NOT administrator permissions
277
- if (!isAdmin )
319
+ if (!isClientAdmin )
278
320
{
279
321
VerifyOrReturnError (verificationKey.HasValue (), InteractionModel::Status::Failure);
280
322
VerifyOrReturnError (entry.IsKeyEquivalent (verificationKey.Value ()), InteractionModel::Status::Failure);
@@ -291,7 +333,7 @@ Status ICDManagementServer::UnregisterClient(FabricIndex fabric_index, NodeId no
291
333
return InteractionModel::Status::Success;
292
334
}
293
335
294
- Status ICDManagementServer::StayActiveRequest (FabricIndex fabric_index )
336
+ Status ICDManagementServer::StayActiveRequest (FabricIndex fabricIndex )
295
337
{
296
338
// TODO: Implementent stay awake logic for end device
297
339
// https://github.com/project-chip/connectedhomeip/issues/24259
@@ -304,22 +346,6 @@ void ICDManagementServer::TriggerICDMTableUpdatedEvent()
304
346
ICDNotifier::GetInstance ().BroadcastICDManagementEvent (ICDListener::ICDManagementEvents::kTableUpdated );
305
347
}
306
348
307
- CHIP_ERROR ICDManagementServer::CheckAdmin (CommandHandler * commandObj, const ConcreteCommandPath & commandPath, bool & isAdmin)
308
- {
309
- RequestPath requestPath{ .cluster = commandPath.mClusterId , .endpoint = commandPath.mEndpointId };
310
- CHIP_ERROR err = GetAccessControl ().Check (commandObj->GetSubjectDescriptor (), requestPath, Privilege::kAdminister );
311
- if (CHIP_NO_ERROR == err)
312
- {
313
- isAdmin = true ;
314
- }
315
- else if (CHIP_ERROR_ACCESS_DENIED == err)
316
- {
317
- isAdmin = false ;
318
- err = CHIP_NO_ERROR;
319
- }
320
- return err;
321
- }
322
-
323
349
void ICDManagementServer::Init (PersistentStorageDelegate & storage, Crypto::SymmetricKeystore * symmetricKeystore,
324
350
ICDConfigurationData & icdConfigurationData)
325
351
{
@@ -339,17 +365,10 @@ void ICDManagementServer::Init(PersistentStorageDelegate & storage, Crypto::Symm
339
365
bool emberAfIcdManagementClusterRegisterClientCallback (CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
340
366
const Commands::RegisterClient::DecodableType & commandData)
341
367
{
342
- InteractionModel::Status status = InteractionModel::Status::Failure;
343
- bool isAdmin = false ;
344
- uint32_t icdCounter = 0 ;
345
- ICDManagementServer server;
368
+ uint32_t icdCounter = 0 ;
346
369
347
- if (CHIP_NO_ERROR == server.CheckAdmin (commandObj, commandPath, isAdmin))
348
- {
349
- status =
350
- server.RegisterClient (commandObj->GetAccessingFabricIndex (), commandData.checkInNodeID , commandData.monitoredSubject ,
351
- commandData.key , commandData.verificationKey , isAdmin, icdCounter);
352
- }
370
+ ICDManagementServer server;
371
+ InteractionModel::Status status = server.RegisterClient (commandObj, commandPath, commandData, icdCounter);
353
372
354
373
if (InteractionModel::Status::Success == status)
355
374
{
@@ -371,15 +390,8 @@ bool emberAfIcdManagementClusterRegisterClientCallback(CommandHandler * commandO
371
390
bool emberAfIcdManagementClusterUnregisterClientCallback (CommandHandler * commandObj, const ConcreteCommandPath & commandPath,
372
391
const Commands::UnregisterClient::DecodableType & commandData)
373
392
{
374
- InteractionModel::Status status = InteractionModel::Status::Failure;
375
- bool isAdmin = false ;
376
393
ICDManagementServer server;
377
-
378
- if (CHIP_NO_ERROR == server.CheckAdmin (commandObj, commandPath, isAdmin))
379
- {
380
- status = server.UnregisterClient (commandObj->GetAccessingFabricIndex (), commandData.checkInNodeID ,
381
- commandData.verificationKey , isAdmin);
382
- }
394
+ InteractionModel::Status status = server.UnregisterClient (commandObj, commandPath, commandData);
383
395
384
396
commandObj->AddStatus (commandPath, status);
385
397
return true ;
0 commit comments