Skip to content

Commit

Permalink
Install ACL for group messaging test (#15158)
Browse files Browse the repository at this point in the history
* Install ACL for group messaging test

Group messaging test will of course fail without an installed ACL
that permits the tested IM operations via group auth mode.

Install an ACL during the test so it can succeed.

Also, complete the work to transcode Group and PASE subjects from
the cluster level (not encoded in a NodeId) to the system level
(encoded in a NodeId).

Part of #14985
  • Loading branch information
mlepage-google authored and pull[bot] committed Aug 8, 2023
1 parent 4246e03 commit 3d49ce0
Show file tree
Hide file tree
Showing 4 changed files with 194 additions and 59 deletions.
5 changes: 5 additions & 0 deletions src/access/AccessControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -317,6 +317,10 @@ bool AccessControl::IsValid(const Entry & entry)
SuccessOrExit(entry.GetSubjectCount(subjectCount));
SuccessOrExit(entry.GetTargetCount(targetCount));

ChipLogDetail(DataManagement, "AccessControl: validating f=%u p=%c a=%c s=%d t=%d", fabricIndex,
GetPrivilegeStringForLogging(privilege), GetAuthModeStringForLogging(authMode), static_cast<int>(subjectCount),
static_cast<int>(targetCount));

// Fabric index must be defined.
VerifyOrExit(fabricIndex != kUndefinedFabricIndex, log = "invalid fabric index");

Expand All @@ -338,6 +342,7 @@ bool AccessControl::IsValid(const Entry & entry)
SuccessOrExit(entry.GetSubject(i, subject));
const bool kIsCase = authMode == AuthMode::kCase;
const bool kIsGroup = authMode == AuthMode::kGroup;
ChipLogDetail(DataManagement, " validating subject 0x" ChipLogFormatX64, ChipLogValueX64(subject));
VerifyOrExit((kIsCase && IsValidCaseNodeId(subject)) || (kIsGroup && IsValidGroupNodeId(subject)), log = "invalid subject");
}

Expand Down
57 changes: 55 additions & 2 deletions src/app/clusters/access-control-server/access-control-server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,12 @@ namespace AccessControlCluster = chip::app::Clusters::AccessControl;

namespace {

struct Subject
{
NodeId nodeId;
AccessControlCluster::AuthMode authMode;
};

struct AccessControlEntryCodec
{
static CHIP_ERROR Convert(AuthMode from, AccessControlCluster::AuthMode & to)
Expand Down Expand Up @@ -127,6 +133,48 @@ struct AccessControlEntryCodec
return CHIP_NO_ERROR;
}

static CHIP_ERROR Convert(NodeId from, Subject & to)
{
if (IsOperationalNodeId(from) || IsCASEAuthTag(from))
{
to = { .nodeId = from, .authMode = AccessControlCluster::AuthMode::kCase };
}
else if (IsGroupId(from))
{
to = { .nodeId = GroupIdFromNodeId(from), .authMode = AccessControlCluster::AuthMode::kGroup };
}
else if (IsPAKEKeyId(from))
{
to = { .nodeId = PAKEKeyIdFromNodeId(from), .authMode = AccessControlCluster::AuthMode::kPase };
}
else
{
return CHIP_ERROR_INVALID_ARGUMENT;
}
return CHIP_NO_ERROR;
}

static CHIP_ERROR Convert(Subject from, NodeId & to)
{
switch (from.authMode)
{
case AccessControlCluster::AuthMode::kPase:
ReturnErrorCodeIf(from.nodeId & ~kMaskPAKEKeyId, CHIP_ERROR_INVALID_ARGUMENT);
to = NodeIdFromPAKEKeyId(static_cast<PasscodeId>(from.nodeId));
break;
case AccessControlCluster::AuthMode::kCase:
to = from.nodeId;
break;
case AccessControlCluster::AuthMode::kGroup:
ReturnErrorCodeIf(from.nodeId & ~kMaskGroupId, CHIP_ERROR_INVALID_ARGUMENT);
to = NodeIdFromGroupId(static_cast<GroupId>(from.nodeId));
break;
default:
return CHIP_ERROR_INVALID_ARGUMENT;
}
return CHIP_NO_ERROR;
}

static CHIP_ERROR Convert(const AccessControl::Entry::Target & from, AccessControlCluster::Structs::Target::Type & to)
{
if (from.flags & AccessControl::Entry::Target::kCluster)
Expand Down Expand Up @@ -202,7 +250,10 @@ struct AccessControlEntryCodec
{
for (size_t i = 0; i < subjectCount; ++i)
{
ReturnErrorOnFailure(entry.GetSubject(i, subjectBuffer[i]));
Subject subject;
ReturnErrorOnFailure(entry.GetSubject(i, subject.nodeId));
ReturnErrorOnFailure(Convert(subject.nodeId, subject));
subjectBuffer[i] = subject.nodeId;
}
staging.subjects.SetNonNull(subjectBuffer, subjectCount);
}
Expand Down Expand Up @@ -251,7 +302,9 @@ struct AccessControlEntryCodec
auto iterator = staging.subjects.Value().begin();
while (iterator.Next())
{
ReturnErrorOnFailure(entry.AddSubject(nullptr, iterator.GetValue()));
Subject subject = { .nodeId = iterator.GetValue(), .authMode = staging.authMode };
ReturnErrorOnFailure(Convert(subject, subject.nodeId));
ReturnErrorOnFailure(entry.AddSubject(nullptr, subject.nodeId));
}
ReturnErrorOnFailure(iterator.GetStatus());
}
Expand Down
24 changes: 24 additions & 0 deletions src/app/tests/suites/TestGroupMessaging.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,30 @@ tests:
{ FabricIndex: 1, GroupId: 0x0102, GroupKeySetID: 0x01a2 },
]

- label: "Install ACLs for test"
cluster: "Access Control"
command: "writeAttribute"
attribute: "ACL"
arguments:
value: [
# Any CASE can admin
{
FabricIndex: 1,
Privilege: 5,
AuthMode: 2,
Subjects: null,
Targets: null,
},
# These groups can operate
{
FabricIndex: 1,
Privilege: 3,
AuthMode: 3,
Subjects: [0x0101, 0x0102],
Targets: null,
},
]

# Test Pair 1 : Sends a Group Write Attribute
- label: "Group Write Attribute"
command: "writeAttribute"
Expand Down
Loading

0 comments on commit 3d49ce0

Please sign in to comment.