Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Managed ACL: Add AccessRestrictionList support #34932

Merged
merged 28 commits into from
Aug 27, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
28 commits
Select commit Hold shift + click to select a range
c2fdd06
Add AccessRestrictionList support
tleacmcsa Jul 30, 2024
20f0b6a
Update src/access/AccessConfig.h
tleacmcsa Aug 19, 2024
04651f9
Reworked data manipulators and other cleanup
tleacmcsa Aug 20, 2024
03ea9d0
Fixed encode/decode so reading CommissioningARL and Arl attributes work
tleacmcsa Aug 21, 2024
cbff3b5
Merge branch 'project-chip:master' into arl-feature
tleacmcsa Aug 21, 2024
5a161e7
Reworked ARL storage
tleacmcsa Aug 22, 2024
459bee4
Review fixes
tleacmcsa Aug 22, 2024
d0928e7
Fixed GetEntries vector pointer arg
tleacmcsa Aug 22, 2024
dcc85c7
Updated core restriction logic/integration
tleacmcsa Aug 22, 2024
a3d1300
Restyled by clang-format
restyled-commits Aug 22, 2024
81effc2
fixed include check for renamed AccessRestrictionProvider.h file
tleacmcsa Aug 22, 2024
1c34d96
M-ACL updates
tleacmcsa Aug 23, 2024
d46ab30
Merge branch 'project-chip:master' into arl-feature
tleacmcsa Aug 23, 2024
9809516
Add plumbing for subject descriptor IsCommissioning field
tcarmelveilleux Aug 23, 2024
8ac75f8
Fix crash
tcarmelveilleux Aug 23, 2024
b151a0f
Use new IsCommissioning in ARL check
tleacmcsa Aug 23, 2024
1d463a0
Updates for review comments
tleacmcsa Aug 25, 2024
92bec3f
Merge remote-tracking branch 'upstream/master' into arl-feature
tleacmcsa Aug 25, 2024
b1ae8e3
restyled
tleacmcsa Aug 25, 2024
7cf925c
Review updates
tleacmcsa Aug 26, 2024
9dc45e8
Merge remote-tracking branch 'upstream/master' into arl-feature
tleacmcsa Aug 26, 2024
d27dfb6
restyled
tleacmcsa Aug 26, 2024
91d4f19
Merge remote-tracking branch 'upstream/master' into arl-feature
tleacmcsa Aug 26, 2024
cbcd55a
Updated ARL tests per review comments
tleacmcsa Aug 26, 2024
25bd650
work around nuttx and jsoncpp contention
tleacmcsa Aug 27, 2024
31a7ddd
Merge branch 'master' into arl-feature
tleacmcsa Aug 27, 2024
141c555
Review comments and nuttx build failure fix attempt
tleacmcsa Aug 27, 2024
3d976bf
review updates
tleacmcsa Aug 27, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions examples/network-manager-app/linux/args.gni
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,6 @@ chip_project_config_include_dirs = [
]

chip_config_network_layer_ble = false

# This enables AccessRestrictionList (ARL) support used by the NIM sample app
chip_enable_access_restrictions = true
Original file line number Diff line number Diff line change
Expand Up @@ -1623,16 +1623,23 @@ endpoint 0 {
server cluster AccessControl {
emits event AccessControlEntryChanged;
emits event AccessControlExtensionChanged;
emits event AccessRestrictionEntryChanged;
emits event FabricRestrictionReviewUpdate;
callback attribute acl;
callback attribute extension;
callback attribute subjectsPerAccessControlEntry;
callback attribute targetsPerAccessControlEntry;
callback attribute accessControlEntriesPerFabric;
callback attribute commissioningARL;
callback attribute arl;
callback attribute generatedCommandList;
callback attribute acceptedCommandList;
callback attribute attributeList;
ram attribute featureMap default = 0;
ram attribute featureMap default = 1;
callback attribute clusterRevision;

handle command ReviewFabricRestrictions;
handle command ReviewFabricRestrictionsResponse;
}

server cluster BasicInformation {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -314,6 +314,24 @@
"define": "ACCESS_CONTROL_CLUSTER",
"side": "server",
"enabled": 1,
"commands": [
{
"name": "ReviewFabricRestrictions",
"code": 0,
"mfgCode": null,
"source": "client",
"isIncoming": 1,
"isEnabled": 1
},
{
"name": "ReviewFabricRestrictionsResponse",
"code": 1,
"mfgCode": null,
"source": "server",
"isIncoming": 0,
"isEnabled": 1
}
],
"attributes": [
{
"name": "ACL",
Expand Down Expand Up @@ -395,6 +413,38 @@
"maxInterval": 65534,
"reportableChange": 0
},
{
"name": "CommissioningARL",
"code": 5,
"mfgCode": null,
"side": "server",
"type": "array",
"included": 1,
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": null,
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
"reportableChange": 0
},
{
"name": "ARL",
"code": 6,
"mfgCode": null,
"side": "server",
"type": "array",
"included": 1,
"storageOption": "External",
"singleton": 0,
"bounded": 0,
"defaultValue": "",
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
"reportableChange": 0
},
{
"name": "GeneratedCommandList",
"code": 65528,
Expand Down Expand Up @@ -453,7 +503,7 @@
"storageOption": "RAM",
"singleton": 0,
"bounded": 0,
"defaultValue": "0",
"defaultValue": "1",
"reportable": 1,
"minInterval": 1,
"maxInterval": 65534,
Expand Down Expand Up @@ -490,6 +540,20 @@
"mfgCode": null,
"side": "server",
"included": 1
},
{
"name": "AccessRestrictionEntryChanged",
"code": 2,
"mfgCode": null,
"side": "server",
"included": 1
},
{
"name": "FabricRestrictionReviewUpdate",
"code": 3,
"mfgCode": null,
"side": "server",
"included": 1
}
]
},
Expand Down
27 changes: 27 additions & 0 deletions examples/platform/linux/AppMain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,10 @@
#include "AppMain.h"
#include "CommissionableInit.h"

#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
#include "ExampleAccessRestrictionProvider.h"
#endif

#if CHIP_DEVICE_LAYER_TARGET_DARWIN
#include <platform/Darwin/NetworkCommissioningDriver.h>
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
Expand All @@ -121,6 +125,7 @@ using namespace chip::DeviceLayer;
using namespace chip::Inet;
using namespace chip::Transport;
using namespace chip::app::Clusters;
using namespace chip::Access;

// Network comissioning implementation
namespace {
Expand Down Expand Up @@ -180,6 +185,10 @@ Optional<app::Clusters::NetworkCommissioning::Instance> sWiFiNetworkCommissionin
app::Clusters::NetworkCommissioning::Instance sEthernetNetworkCommissioningInstance(kRootEndpointId, &sEthernetDriver);
#endif // CHIP_APP_MAIN_HAS_ETHERNET_DRIVER

#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
auto exampleAccessRestrictionProvider = std::make_unique<ExampleAccessRestrictionProvider>();
#endif

void EnableThreadNetworkCommissioning()
{
#if CHIP_APP_MAIN_HAS_THREAD_DRIVER
Expand Down Expand Up @@ -593,9 +602,27 @@ void ChipLinuxAppMainLoop(AppMainLoopImplementation * impl)
chip::app::RuntimeOptionsProvider::Instance().SetSimulateNoInternalTime(
LinuxDeviceOptions::GetInstance().mSimulateNoInternalTime);

#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
initParams.accessRestrictionProvider = exampleAccessRestrictionProvider.get();
#endif

// Init ZCL Data Model and CHIP App Server
Server::GetInstance().Init(initParams);

#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
if (LinuxDeviceOptions::GetInstance().commissioningArlEntries.HasValue())
{
exampleAccessRestrictionProvider->SetCommissioningEntries(
LinuxDeviceOptions::GetInstance().commissioningArlEntries.Value());
}

if (LinuxDeviceOptions::GetInstance().arlEntries.HasValue())
{
// This example use of the ARL feature proactively installs the provided entries on fabric index 1
exampleAccessRestrictionProvider->SetEntries(1, LinuxDeviceOptions::GetInstance().arlEntries.Value());
}
#endif

#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
// Set ReadHandler Capacity for Subscriptions
chip::app::InteractionModelEngine::GetInstance()->SetHandlerCapacityForSubscriptions(
Expand Down
2 changes: 2 additions & 0 deletions examples/platform/linux/BUILD.gn
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
# limitations under the License.

import("//build_overrides/chip.gni")
import("//build_overrides/jsoncpp.gni")
import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni")
import("${chip_root}/src/app/common_flags.gni")
import("${chip_root}/src/lib/core/core.gni")
Expand Down Expand Up @@ -94,6 +95,7 @@ source_set("app-main") {
"${chip_root}/src/controller:gen_check_chip_controller_headers",
"${chip_root}/src/lib",
"${chip_root}/src/platform/logging:default",
jsoncpp_root,
]
deps = [
":ota-test-event-trigger",
Expand Down
55 changes: 55 additions & 0 deletions examples/platform/linux/ExampleAccessRestrictionProvider.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
*
* Copyright (c) 2024 Project CHIP Authors
* All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/

/*
* AccessRestriction implementation for Linux examples.
*/

#pragma once

#include <access/AccessRestrictionProvider.h>
#include <app-common/zap-generated/cluster-objects.h>
#include <app/EventLogging.h>

namespace chip {
namespace Access {

class ExampleAccessRestrictionProvider : public AccessRestrictionProvider
{
public:
ExampleAccessRestrictionProvider() : AccessRestrictionProvider() {}

~ExampleAccessRestrictionProvider() {}

protected:
CHIP_ERROR DoRequestFabricRestrictionReview(const FabricIndex fabricIndex, uint64_t token, const std::vector<Entry> & arl)
{
// this example simply removes all restrictions and will generate AccessRestrictionEntryChanged events
Access::GetAccessControl().GetAccessRestrictionProvider()->SetEntries(fabricIndex, std::vector<Entry>{});

chip::app::Clusters::AccessControl::Events::FabricRestrictionReviewUpdate::Type event{ .token = token,
.fabricIndex = fabricIndex };
EventNumber eventNumber;
ReturnErrorOnFailure(chip::app::LogEvent(event, kRootEndpointId, eventNumber));

return CHIP_NO_ERROR;
Comment on lines +48 to +50
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
ReturnErrorOnFailure(chip::app::LogEvent(event, kRootEndpointId, eventNumber));
return CHIP_NO_ERROR;
return chip::app::LogEvent(event, kRootEndpointId, eventNumber);

}
};

} // namespace Access
} // namespace chip
77 changes: 77 additions & 0 deletions examples/platform/linux/Options.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include <app/server/OnboardingCodesUtil.h>

#include <crypto/CHIPCryptoPAL.h>
#include <json/json.h>
#include <lib/core/CHIPError.h>
#include <lib/support/Base64.h>
#include <lib/support/BytesToHex.h>
Expand All @@ -47,6 +48,11 @@

using namespace chip;
using namespace chip::ArgParser;
using namespace chip::Platform;

#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
using namespace chip::Access;
#endif

namespace {
LinuxDeviceOptions gDeviceOptions;
Expand Down Expand Up @@ -82,6 +88,10 @@ enum
kDeviceOption_TraceFile,
kDeviceOption_TraceLog,
kDeviceOption_TraceDecode,
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
kDeviceOption_CommissioningArlEntries,
kDeviceOption_ArlEntries,
#endif
kOptionCSRResponseCSRIncorrectType,
kOptionCSRResponseCSRNonceIncorrectType,
kOptionCSRResponseCSRNonceTooLong,
Expand Down Expand Up @@ -154,6 +164,10 @@ OptionDef sDeviceOptionDefs[] = {
{ "trace_log", kArgumentRequired, kDeviceOption_TraceLog },
{ "trace_decode", kArgumentRequired, kDeviceOption_TraceDecode },
#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
{ "commissioning-arl-entries", kArgumentRequired, kDeviceOption_CommissioningArlEntries },
{ "arl-entries", kArgumentRequired, kDeviceOption_ArlEntries },
#endif // CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
{ "cert_error_csr_incorrect_type", kNoArgument, kOptionCSRResponseCSRIncorrectType },
{ "cert_error_csr_existing_keypair", kNoArgument, kOptionCSRResponseCSRExistingKeyPair },
{ "cert_error_csr_nonce_incorrect_type", kNoArgument, kOptionCSRResponseCSRNonceIncorrectType },
Expand Down Expand Up @@ -280,6 +294,14 @@ const char * sDeviceOptionHelp =
" --trace_decode <1/0>\n"
" A value of 1 enables traces decoding, 0 disables this (default 0).\n"
#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
" --commissioning-arl-entries <CommissioningARL JSON>\n"
" Enable ACL cluster access restrictions used during commissioning with the provided JSON. Example:\n"
" \"[{\\\"endpoint\\\": 1,\\\"cluster\\\": 1105,\\\"restrictions\\\": [{\\\"type\\\": 0,\\\"id\\\": 0}]}]\"\n"
" --arl-entries <ARL JSON>\n"
" Enable ACL cluster access restrictions applied to fabric index 1 with the provided JSON. Example:\n"
" \"[{\\\"endpoint\\\": 1,\\\"cluster\\\": 1105,\\\"restrictions\\\": [{\\\"type\\\": 0,\\\"id\\\": 0}]}]\"\n"
#endif // CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
" --cert_error_csr_incorrect_type\n"
" Configure the CSRResponse to be built with an invalid CSR type.\n"
" --cert_error_csr_existing_keypair\n"
Expand Down Expand Up @@ -320,6 +342,39 @@ const char * sDeviceOptionHelp =
#endif
"\n";

#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
bool ParseAccessRestrictionEntriesFromJson(const char * jsonString, std::vector<AccessRestrictionProvider::Entry> & entries)
{
Json::Value root;
Json::Reader reader;
VerifyOrReturnValue(reader.parse(jsonString, root), false);

for (Json::Value::const_iterator eIt = root.begin(); eIt != root.end(); eIt++)
{
AccessRestrictionProvider::Entry entry;

entry.endpointNumber = static_cast<EndpointId>((*eIt)["endpoint"].asUInt());
entry.clusterId = static_cast<ClusterId>((*eIt)["cluster"].asUInt());

Json::Value restrictions = (*eIt)["restrictions"];
for (Json::Value::const_iterator rIt = restrictions.begin(); rIt != restrictions.end(); rIt++)
{
AccessRestrictionProvider::Restriction restriction;
restriction.restrictionType = static_cast<AccessRestrictionProvider::Type>((*rIt)["type"].asUInt());
if ((*rIt).isMember("id"))
{
restriction.id.SetValue((*rIt)["id"].asUInt());
}
entry.restrictions.push_back(restriction);
}

entries.push_back(entry);
}

return true;
}
#endif // CHIP_CONFIG_USE_ACCESS_RESTRICTIONS

bool Base64ArgToVector(const char * arg, size_t maxSize, std::vector<uint8_t> & outVector)
{
size_t maxBase64Size = BASE64_ENCODED_LEN(maxSize);
Expand Down Expand Up @@ -529,6 +584,28 @@ bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier,
break;
#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED

#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
// TODO(#35189): change to use a path to JSON files instead
case kDeviceOption_CommissioningArlEntries: {
std::vector<AccessRestrictionProvider::Entry> entries;
retval = ParseAccessRestrictionEntriesFromJson(aValue, entries);
if (retval)
{
LinuxDeviceOptions::GetInstance().commissioningArlEntries.SetValue(std::move(entries));
}
}
break;
case kDeviceOption_ArlEntries: {
std::vector<AccessRestrictionProvider::Entry> entries;
retval = ParseAccessRestrictionEntriesFromJson(aValue, entries);
if (retval)
{
LinuxDeviceOptions::GetInstance().arlEntries.SetValue(std::move(entries));
}
}
break;
#endif // CHIP_CONFIG_USE_ACCESS_RESTRICTIONS

case kOptionCSRResponseCSRIncorrectType:
LinuxDeviceOptions::GetInstance().mCSRResponseOptions.csrIncorrectType = true;
break;
Expand Down
Loading
Loading