Skip to content

Commit 5501b22

Browse files
committed
Add AccessRestrictionList support
1 parent dc5bba7 commit 5501b22

26 files changed

+2104
-7
lines changed

examples/network-manager-app/linux/args.gni

+1
Original file line numberDiff line numberDiff line change
@@ -22,3 +22,4 @@ chip_project_config_include_dirs = [
2222
]
2323

2424
chip_config_network_layer_ble = false
25+
chip_enable_access_restrictions = true

examples/platform/linux/AppMain.cpp

+18
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121

2222
#include <app/InteractionModelEngine.h>
2323
#include <app/clusters/network-commissioning/network-commissioning.h>
24+
#include <app/server/DefaultArlStorage.h>
2425
#include <app/server/Dnssd.h>
2526
#include <app/server/OnboardingCodesUtil.h>
2627
#include <app/server/Server.h>
@@ -103,6 +104,10 @@
103104
#include "AppMain.h"
104105
#include "CommissionableInit.h"
105106

107+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
108+
#include "ExampleAccessRestriction.h"
109+
#endif
110+
106111
#if CHIP_DEVICE_LAYER_TARGET_DARWIN
107112
#include <platform/Darwin/NetworkCommissioningDriver.h>
108113
#if CHIP_DEVICE_CONFIG_ENABLE_WIFI
@@ -121,6 +126,7 @@ using namespace chip::DeviceLayer;
121126
using namespace chip::Inet;
122127
using namespace chip::Transport;
123128
using namespace chip::app::Clusters;
129+
using namespace chip::Access;
124130

125131
// Network comissioning implementation
126132
namespace {
@@ -593,6 +599,18 @@ void ChipLinuxAppMainLoop(AppMainLoopImplementation * impl)
593599
chip::app::RuntimeOptionsProvider::Instance().SetSimulateNoInternalTime(
594600
LinuxDeviceOptions::GetInstance().mSimulateNoInternalTime);
595601

602+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
603+
if (LinuxDeviceOptions::GetInstance().accessRestrictionEntries.HasValue())
604+
{
605+
initParams.accessRestriction = new ExampleAccessRestriction();
606+
initParams.arlStorage = new app::DefaultArlStorage();
607+
for (const auto & entry : LinuxDeviceOptions::GetInstance().accessRestrictionEntries.Value())
608+
{
609+
VerifyOrDie(AccessRestriction::CreateCommissioningEntry(entry) == CHIP_NO_ERROR);
610+
}
611+
}
612+
#endif
613+
596614
// Init ZCL Data Model and CHIP App Server
597615
Server::GetInstance().Init(initParams);
598616

examples/platform/linux/BUILD.gn

+2
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
# limitations under the License.
1414

1515
import("//build_overrides/chip.gni")
16+
import("//build_overrides/jsoncpp.gni")
1617
import("${chip_root}/examples/common/pigweed/pigweed_rpcs.gni")
1718
import("${chip_root}/src/app/common_flags.gni")
1819
import("${chip_root}/src/lib/core/core.gni")
@@ -94,6 +95,7 @@ source_set("app-main") {
9495
"${chip_root}/src/controller:gen_check_chip_controller_headers",
9596
"${chip_root}/src/lib",
9697
"${chip_root}/src/platform/logging:default",
98+
jsoncpp_root,
9799
]
98100
deps = [
99101
":ota-test-event-trigger",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
/*
2+
*
3+
* Copyright (c) 2024 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+
/*
20+
* AccessRestriction implementation for Linux examples.
21+
*/
22+
23+
#pragma once
24+
25+
#include <access/AccessRestriction.h>
26+
27+
namespace chip {
28+
namespace Access {
29+
30+
class ExampleAccessRestriction : public AccessRestriction
31+
{
32+
public:
33+
class ExampleAccessRestrictionEntryListener : public AccessRestriction::EntryListener
34+
{
35+
void OnEntryChanged(FabricIndex fabricIndex, size_t index, SharedPtr<AccessRestriction::Entry> entry,
36+
ChangeType changeType) override
37+
{
38+
ChipLogProgress(NotSpecified, "AccessRestriction Entry changed: fabricIndex %d, index %ld, changeType %d", fabricIndex,
39+
index, static_cast<int>(changeType));
40+
}
41+
42+
void OnFabricRestrictionReviewUpdate(FabricIndex fabricIndex, uint64_t token, const char * instruction,
43+
const char * redirectUrl) override
44+
{}
45+
};
46+
47+
ExampleAccessRestriction() : AccessRestriction() { AccessRestriction::AddListener(listener); }
48+
49+
~ExampleAccessRestriction() { AccessRestriction::RemoveListener(listener); }
50+
51+
protected:
52+
CHIP_ERROR DoRequestFabricRestrictionReview(const FabricIndex fabricIndex, uint64_t token, const std::vector<Entry> & arl)
53+
{
54+
// this example simply removes all restrictions
55+
while (Access::GetAccessControl().GetAccessRestriction()->DeleteEntry(0, fabricIndex) == CHIP_NO_ERROR)
56+
;
57+
58+
return CHIP_NO_ERROR;
59+
}
60+
61+
private:
62+
ExampleAccessRestrictionEntryListener listener;
63+
};
64+
65+
} // namespace Access
66+
} // namespace chip

examples/platform/linux/Options.cpp

+60
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@
2626
#include <app/server/OnboardingCodesUtil.h>
2727

2828
#include <crypto/CHIPCryptoPAL.h>
29+
#include <json/json.h>
2930
#include <lib/core/CHIPError.h>
3031
#include <lib/support/Base64.h>
3132
#include <lib/support/BytesToHex.h>
@@ -47,6 +48,11 @@
4748

4849
using namespace chip;
4950
using namespace chip::ArgParser;
51+
using namespace chip::Platform;
52+
53+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
54+
using namespace chip::Access;
55+
#endif
5056

5157
namespace {
5258
LinuxDeviceOptions gDeviceOptions;
@@ -82,6 +88,9 @@ enum
8288
kDeviceOption_TraceFile,
8389
kDeviceOption_TraceLog,
8490
kDeviceOption_TraceDecode,
91+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
92+
kDeviceOption_UseAccessRestrictions,
93+
#endif
8594
kOptionCSRResponseCSRIncorrectType,
8695
kOptionCSRResponseCSRNonceIncorrectType,
8796
kOptionCSRResponseCSRNonceTooLong,
@@ -154,6 +163,9 @@ OptionDef sDeviceOptionDefs[] = {
154163
{ "trace_log", kArgumentRequired, kDeviceOption_TraceLog },
155164
{ "trace_decode", kArgumentRequired, kDeviceOption_TraceDecode },
156165
#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
166+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
167+
{ "enable-access-restrictions", kArgumentRequired, kDeviceOption_UseAccessRestrictions },
168+
#endif // CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
157169
{ "cert_error_csr_incorrect_type", kNoArgument, kOptionCSRResponseCSRIncorrectType },
158170
{ "cert_error_csr_existing_keypair", kNoArgument, kOptionCSRResponseCSRExistingKeyPair },
159171
{ "cert_error_csr_nonce_incorrect_type", kNoArgument, kOptionCSRResponseCSRNonceIncorrectType },
@@ -280,6 +292,9 @@ const char * sDeviceOptionHelp =
280292
" --trace_decode <1/0>\n"
281293
" A value of 1 enables traces decoding, 0 disables this (default 0).\n"
282294
#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
295+
" --enable-access-restrictions <CommissioningARL JSON>\n"
296+
" Enable ACL cluster access restrictions with the provided JSON CommissioningARL. Example:\n"
297+
" \"[{\\\"endpoint\\\": 1,\\\"cluster\\\": 2,\\\"restrictions\\\": [{\\\"type\\\": 0,\\\"id\\\": 3}]}]\"\n"
283298
" --cert_error_csr_incorrect_type\n"
284299
" Configure the CSRResponse to be built with an invalid CSR type.\n"
285300
" --cert_error_csr_existing_keypair\n"
@@ -320,6 +335,39 @@ const char * sDeviceOptionHelp =
320335
#endif
321336
"\n";
322337

338+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
339+
bool ParseAccessRestrictionEntriesFromJson(const char * jsonString, std::vector<SharedPtr<AccessRestriction::Entry>> & entries)
340+
{
341+
Json::Value root;
342+
Json::Reader reader;
343+
VerifyOrReturnValue(reader.parse(jsonString, root), false);
344+
345+
for (Json::Value::const_iterator eIt = root.begin(); eIt != root.end(); eIt++)
346+
{
347+
auto entry = MakeShared<AccessRestriction::Entry>();
348+
349+
entry->endpointNumber = (*eIt)["endpoint"].asInt();
350+
entry->clusterId = (*eIt)["cluster"].asInt();
351+
352+
Json::Value restrictions = (*eIt)["restrictions"];
353+
for (Json::Value::const_iterator rIt = restrictions.begin(); rIt != restrictions.end(); rIt++)
354+
{
355+
AccessRestriction::Restriction restriction;
356+
restriction.restrictionType = static_cast<AccessRestriction::Type>((*rIt)["type"].asInt());
357+
if ((*rIt).isMember("id"))
358+
{
359+
restriction.id.SetValue((*rIt)["id"].asInt());
360+
}
361+
entry->restrictions.push_back(restriction);
362+
}
363+
364+
entries.push_back(entry);
365+
}
366+
367+
return true;
368+
}
369+
#endif // CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
370+
323371
bool Base64ArgToVector(const char * arg, size_t maxSize, std::vector<uint8_t> & outVector)
324372
{
325373
size_t maxBase64Size = BASE64_ENCODED_LEN(maxSize);
@@ -529,6 +577,18 @@ bool HandleOption(const char * aProgram, OptionSet * aOptions, int aIdentifier,
529577
break;
530578
#endif // CHIP_CONFIG_TRANSPORT_TRACE_ENABLED
531579

580+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
581+
case kDeviceOption_UseAccessRestrictions: {
582+
std::vector<SharedPtr<AccessRestriction::Entry>> accessRestrictionEntries;
583+
retval = ParseAccessRestrictionEntriesFromJson(aValue, accessRestrictionEntries);
584+
if (retval)
585+
{
586+
LinuxDeviceOptions::GetInstance().accessRestrictionEntries.SetValue(std::move(accessRestrictionEntries));
587+
}
588+
}
589+
break;
590+
#endif // CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
591+
532592
case kOptionCSRResponseCSRIncorrectType:
533593
LinuxDeviceOptions::GetInstance().mCSRResponseOptions.csrIncorrectType = true;
534594
break;

examples/platform/linux/Options.h

+8
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
#include <string>
2929
#include <vector>
3030

31+
#include <access/AccessConfig.h>
3132
#include <inet/InetInterface.h>
3233
#include <lib/core/CHIPError.h>
3334
#include <lib/core/Optional.h>
@@ -38,6 +39,10 @@
3839
#include <credentials/DeviceAttestationCredsProvider.h>
3940
#include <testing/CustomCSRResponse.h>
4041

42+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
43+
#include <access/AccessRestriction.h>
44+
#endif
45+
4146
struct LinuxDeviceOptions
4247
{
4348
chip::PayloadContents payload;
@@ -81,6 +86,9 @@ struct LinuxDeviceOptions
8186
#if CONFIG_BUILD_FOR_HOST_UNIT_TEST
8287
int32_t subscriptionCapacity = CHIP_IM_MAX_NUM_SUBSCRIPTIONS;
8388
int32_t subscriptionResumptionRetryIntervalSec = -1;
89+
#endif
90+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
91+
chip::Optional<std::vector<chip::Platform::SharedPtr<chip::Access::AccessRestriction::Entry>>> accessRestrictionEntries;
8492
#endif
8593
static LinuxDeviceOptions & GetInstance();
8694
};

src/access/AccessConfig.h

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
/*
2+
*
3+
* Copyright (c) 2020-2024 Project CHIP Authors
4+
*
5+
* Licensed under the Apache License, Version 2.0 (the "License");
6+
* you may not use this file except in compliance with the License.
7+
* You may obtain a copy of the License at
8+
*
9+
* http://www.apache.org/licenses/LICENSE-2.0
10+
*
11+
* Unless required by applicable law or agreed to in writing, software
12+
* distributed under the License is distributed on an "AS IS" BASIS,
13+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
* See the License for the specific language governing permissions and
15+
* limitations under the License.
16+
*/
17+
18+
#pragma once
19+
20+
#if CHIP_HAVE_CONFIG_H
21+
#include <access/AccessBuildConfig.h>
22+
#endif

src/access/AccessControl.cpp

+18-1
Original file line numberDiff line numberDiff line change
@@ -325,7 +325,11 @@ void AccessControl::RemoveEntryListener(EntryListener & listener)
325325

326326
bool AccessControl::IsAccessRestrictionListSupported() const
327327
{
328-
return false; // not yet supported
328+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
329+
return mAccessRestriction != nullptr;
330+
#else
331+
return false;
332+
#endif
329333
}
330334

331335
CHIP_ERROR AccessControl::Check(const SubjectDescriptor & subjectDescriptor, const RequestPath & requestPath,
@@ -352,6 +356,19 @@ CHIP_ERROR AccessControl::Check(const SubjectDescriptor & subjectDescriptor, con
352356
VerifyOrReturnError(requestPath.requestType != RequestType::kRequestTypeUnknown, CHIP_ERROR_INVALID_ARGUMENT);
353357
}
354358

359+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
360+
if (mAccessRestriction != nullptr)
361+
{
362+
CHIP_ERROR result = mAccessRestriction->Check(subjectDescriptor, requestPath);
363+
if (result != CHIP_NO_ERROR)
364+
{
365+
ChipLogProgress(DataManagement, "AccessControl: %s",
366+
(result == CHIP_ERROR_ACCESS_DENIED) ? "denied (restricted)" : "denied (restriction error)");
367+
return result;
368+
}
369+
}
370+
#endif
371+
355372
{
356373
CHIP_ERROR result = mDelegate->Check(subjectDescriptor, requestPath, requestPrivilege);
357374
if (result != CHIP_ERROR_NOT_IMPLEMENTED)

src/access/AccessControl.h

+19
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,12 @@
1818

1919
#pragma once
2020

21+
#include <access/AccessConfig.h>
22+
23+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
24+
#include "AccessRestriction.h"
25+
#endif
26+
2127
#include "Privilege.h"
2228
#include "RequestPath.h"
2329
#include "SubjectDescriptor.h"
@@ -627,6 +633,13 @@ class AccessControl
627633
// Removes a listener from the listener list, if in the list.
628634
void RemoveEntryListener(EntryListener & listener);
629635

636+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
637+
// Set an optional AcceessRestriction object for MNGD feature.
638+
void SetAccessRestriction(AccessRestriction * accessRestriction) { mAccessRestriction = accessRestriction; }
639+
640+
AccessRestriction * GetAccessRestriction() { return mAccessRestriction; }
641+
#endif
642+
630643
/**
631644
* Check whether or not Access Restriction List is supported.
632645
*
@@ -638,6 +651,8 @@ class AccessControl
638651
* Check whether access (by a subject descriptor, to a request path,
639652
* requiring a privilege) should be allowed or denied.
640653
*
654+
* If an AccessRestriction object is set, it will be checked for additional access restrictions.
655+
*
641656
* @retval #CHIP_ERROR_ACCESS_DENIED if denied.
642657
* @retval other errors should also be treated as denied.
643658
* @retval #CHIP_NO_ERROR if allowed.
@@ -662,6 +677,10 @@ class AccessControl
662677
DeviceTypeResolver * mDeviceTypeResolver = nullptr;
663678

664679
EntryListener * mEntryListener = nullptr;
680+
681+
#if CHIP_CONFIG_USE_ACCESS_RESTRICTIONS
682+
AccessRestriction * mAccessRestriction;
683+
#endif
665684
};
666685

667686
/**

0 commit comments

Comments
 (0)