Skip to content

Commit 0149d30

Browse files
committed
CASE: Extract CAT IDs from current session and add them to the Accessor
1 parent 725d191 commit 0149d30

File tree

3 files changed

+86
-7
lines changed

3 files changed

+86
-7
lines changed

matter/src/data_model/core.rs

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -220,7 +220,13 @@ impl DataModel {
220220
fn sess_to_accessor(&self, sess: &Session) -> Accessor {
221221
match sess.get_session_mode() {
222222
SessionMode::Case(c) => {
223-
let subject = AccessorSubjects::new(sess.get_peer_node_id().unwrap_or_default());
223+
let mut subject =
224+
AccessorSubjects::new(sess.get_peer_node_id().unwrap_or_default());
225+
for i in c.cat_ids {
226+
if i != 0 {
227+
let _ = subject.add(i);
228+
}
229+
}
224230
Accessor::new(c.fab_idx, subject, AuthMode::Case, self.acl_mgr.clone())
225231
}
226232
SessionMode::Pase => Accessor::new(

matter/tests/common/im_engine.rs

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use matter::{
3737
network::Address,
3838
packet::PacketPool,
3939
proto_demux::ProtoCtx,
40-
session::{CloneData, SessionMgr, SessionMode},
40+
session::{CloneData, NocCatIds, SessionMgr, SessionMode},
4141
},
4242
transport::{proto_demux::HandleProto, session::CaseDetails},
4343
utils::writebuf::WriteBuf,
@@ -69,6 +69,7 @@ pub struct ImInput<'a> {
6969
action: OpCode,
7070
data: &'a dyn ToTLV,
7171
peer_id: u64,
72+
cat_ids: NocCatIds,
7273
}
7374

7475
pub const IM_ENGINE_PEER_ID: u64 = 445566;
@@ -78,12 +79,17 @@ impl<'a> ImInput<'a> {
7879
action,
7980
data,
8081
peer_id: IM_ENGINE_PEER_ID,
82+
cat_ids: Default::default(),
8183
}
8284
}
8385

8486
pub fn set_peer_node_id(&mut self, peer: u64) {
8587
self.peer_id = peer;
8688
}
89+
90+
pub fn set_cat_ids(&mut self, cat_ids: &NocCatIds) {
91+
self.cat_ids = *cat_ids;
92+
}
8793
}
8894

8995
impl ImEngine {
@@ -146,7 +152,7 @@ impl ImEngine {
146152
std::net::IpAddr::V4(Ipv4Addr::new(127, 0, 0, 1)),
147153
5542,
148154
)),
149-
SessionMode::Case(CaseDetails::new(1, &Default::default())),
155+
SessionMode::Case(CaseDetails::new(1, &input.cat_ids)),
150156
);
151157
let sess_idx = sess_mgr.clone_session(&clone_data).unwrap();
152158
let sess = sess_mgr.get_session_handle(sess_idx);

matter/tests/data_model/acl_and_dataver.rs

Lines changed: 71 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
*/
1717

1818
use matter::{
19-
acl::{AclEntry, AuthMode, Target},
19+
acl::{gen_noc_cat, AclEntry, AuthMode, Target},
2020
data_model::{
2121
objects::{AttrValue, EncodeValue, Privilege},
2222
system_model::access_control,
@@ -30,6 +30,7 @@ use matter::{
3030
messages::{msg, GenericPath},
3131
},
3232
tlv::{self, ElementType, FromTLV, TLVArray, TLVElement, TLVWriter, TagType},
33+
transport::session::NocCatIds,
3334
};
3435

3536
use crate::{
@@ -77,6 +78,7 @@ fn gen_read_reqs_output<'a>(
7778
fn handle_write_reqs(
7879
im: &mut ImEngine,
7980
peer_node_id: u64,
81+
peer_cat_ids: Option<&NocCatIds>,
8082
input: &[AttrData],
8183
expected: &[AttrStatus],
8284
) {
@@ -85,6 +87,9 @@ fn handle_write_reqs(
8587

8688
let mut input = ImInput::new(OpCode::WriteRequest, &write_req);
8789
input.set_peer_node_id(peer_node_id);
90+
if let Some(cat_ids) = peer_cat_ids {
91+
input.set_cat_ids(cat_ids);
92+
}
8893
let (_, out_buf) = im.process(&input, &mut out_buf);
8994

9095
tlv::print_tlv_list(out_buf);
@@ -263,7 +268,7 @@ fn wc_write_attribute() {
263268

264269
// Test 1: Wildcard write to an attribute without permission should return
265270
// no error
266-
handle_write_reqs(&mut im, peer, input0, &[]);
271+
handle_write_reqs(&mut im, peer, None, input0, &[]);
267272
{
268273
let node = im.dm.node.read().unwrap();
269274
let echo = node.get_cluster(0, echo_cluster::ID).unwrap();
@@ -287,6 +292,7 @@ fn wc_write_attribute() {
287292
handle_write_reqs(
288293
&mut im,
289294
peer,
295+
None,
290296
input0,
291297
&[AttrStatus::new(&ep0_att, IMStatusCode::Sucess, 0)],
292298
);
@@ -307,6 +313,7 @@ fn wc_write_attribute() {
307313
handle_write_reqs(
308314
&mut im,
309315
peer,
316+
None,
310317
input1,
311318
&[
312319
AttrStatus::new(&ep0_att, IMStatusCode::Sucess, 0),
@@ -350,7 +357,7 @@ fn exact_write_attribute() {
350357

351358
// Test 1: Exact write to an attribute without permission should return
352359
// Unsupported Access Error
353-
handle_write_reqs(&mut im, peer, input, expected_fail);
360+
handle_write_reqs(&mut im, peer, None, input, expected_fail);
354361
assert_eq!(
355362
AttrValue::Uint16(ATTR_WRITE_DEFAULT_VALUE),
356363
read_cluster_id_write_attr(&im, 0)
@@ -363,7 +370,62 @@ fn exact_write_attribute() {
363370

364371
// Test 1: Exact write to an attribute with permission should grant
365372
// access
366-
handle_write_reqs(&mut im, peer, input, expected_success);
373+
handle_write_reqs(&mut im, peer, None, input, expected_success);
374+
assert_eq!(AttrValue::Uint16(val0), read_cluster_id_write_attr(&im, 0));
375+
}
376+
377+
#[test]
378+
/// Ensure that an write attribute without a wildcard returns an error when the
379+
/// ACL disallows the access, and returns success once access is granted to the CAT ID
380+
/// The Accessor CAT version is one more than that in the ACL
381+
fn exact_write_attribute_noc_cat() {
382+
let _ = env_logger::try_init();
383+
let val0 = 10;
384+
let attr_data0 = |tag, t: &mut TLVWriter| {
385+
let _ = t.u16(tag, val0);
386+
};
387+
388+
let ep0_att = GenericPath::new(
389+
Some(0),
390+
Some(echo_cluster::ID),
391+
Some(echo_cluster::Attributes::AttWrite as u32),
392+
);
393+
394+
let input = &[AttrData::new(
395+
None,
396+
AttrPath::new(&ep0_att),
397+
EncodeValue::Closure(&attr_data0),
398+
)];
399+
let expected_fail = &[AttrStatus::new(
400+
&ep0_att,
401+
IMStatusCode::UnsupportedAccess,
402+
0,
403+
)];
404+
let expected_success = &[AttrStatus::new(&ep0_att, IMStatusCode::Sucess, 0)];
405+
406+
let peer = 98765;
407+
/* CAT in NOC is 1 more, in version, than that in ACL */
408+
let noc_cat = gen_noc_cat(0xABCD, 2);
409+
let cat_in_acl = gen_noc_cat(0xABCD, 1);
410+
let cat_ids = [noc_cat, 0, 0];
411+
let mut im = ImEngine::new();
412+
413+
// Test 1: Exact write to an attribute without permission should return
414+
// Unsupported Access Error
415+
handle_write_reqs(&mut im, peer, Some(&cat_ids), input, expected_fail);
416+
assert_eq!(
417+
AttrValue::Uint16(ATTR_WRITE_DEFAULT_VALUE),
418+
read_cluster_id_write_attr(&im, 0)
419+
);
420+
421+
// Add ACL to allow our peer to access any endpoint
422+
let mut acl = AclEntry::new(1, Privilege::ADMIN, AuthMode::Case);
423+
acl.add_subject(cat_in_acl).unwrap();
424+
im.acl_mgr.add(acl).unwrap();
425+
426+
// Test 1: Exact write to an attribute with permission should grant
427+
// access
428+
handle_write_reqs(&mut im, peer, Some(&cat_ids), input, expected_success);
367429
assert_eq!(AttrValue::Uint16(val0), read_cluster_id_write_attr(&im, 0));
368430
}
369431

@@ -399,6 +461,7 @@ fn insufficient_perms_write() {
399461
handle_write_reqs(
400462
&mut im,
401463
peer,
464+
None,
402465
input0,
403466
&[AttrStatus::new(
404467
&ep0_att,
@@ -466,6 +529,7 @@ fn write_with_runtime_acl_add() {
466529
handle_write_reqs(
467530
&mut im,
468531
peer,
532+
None,
469533
// write to echo-cluster attribute, write to acl attribute, write to echo-cluster attribute
470534
&[input0, acl_input, input0],
471535
&[
@@ -623,6 +687,7 @@ fn test_write_data_ver() {
623687
handle_write_reqs(
624688
&mut im,
625689
peer,
690+
None,
626691
input_correct_dataver,
627692
&[AttrStatus::new(&ep0_attwrite, IMStatusCode::Sucess, 0)],
628693
);
@@ -638,6 +703,7 @@ fn test_write_data_ver() {
638703
handle_write_reqs(
639704
&mut im,
640705
peer,
706+
None,
641707
input_correct_dataver,
642708
&[AttrStatus::new(
643709
&ep0_attwrite,
@@ -660,6 +726,7 @@ fn test_write_data_ver() {
660726
handle_write_reqs(
661727
&mut im,
662728
peer,
729+
None,
663730
input_correct_dataver,
664731
&[AttrStatus::new(&ep0_attwrite, IMStatusCode::Sucess, 0)],
665732
);

0 commit comments

Comments
 (0)