]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
rust/nfs4: Add NFSPROC4_CREATE_SESSION op parsers
authorSam Muhammed <ghostinthehive.vx@gmail.com>
Sun, 20 Feb 2022 12:15:29 +0000 (14:15 +0200)
committerVictor Julien <vjulien@oisf.net>
Fri, 4 Mar 2022 15:50:55 +0000 (16:50 +0100)
Also add respective response/request unittests
test_nfs4_request_create_session()
test_nfs4_response_create_session()

rust/src/nfs/nfs4_records.rs
rust/src/nfs/types.rs

index 7a2e44fa7be21a4323eb5225076ed40ceb6f2bd2..d6f716a9b2c3a5b093172f9dfbc8a79c5a1a501b 100644 (file)
@@ -17,7 +17,7 @@
 
 //! Nom parsers for NFSv4 records
 use nom7::bytes::streaming::{tag, take};
-use nom7::combinator::{complete, cond, map, peek, verify};
+use nom7::combinator::{complete, cond, map, peek, verify, rest};
 use nom7::error::{make_error, ErrorKind};
 use nom7::multi::{count, many_till};
 use nom7::number::streaming::{be_u32, be_u64};
@@ -60,6 +60,7 @@ pub enum Nfs4RequestContent<'a> {
     SetClientIdConfirm,
     ExchangeId(Nfs4RequestExchangeId<'a>),
     Sequence(Nfs4RequestSequence<'a>),
+    CreateSession(Nfs4RequestCreateSession<'a>),
 }
 
 #[derive(Debug,PartialEq)]
@@ -129,6 +130,34 @@ fn nfs4_parse_nfsstring(i: &[u8]) -> IResult<&[u8], &[u8]> {
     Ok((i, data))
 }
 
+#[derive(Debug, PartialEq)]
+pub struct Nfs4RequestCreateSession<'a> {
+    pub client_id: &'a[u8],
+    pub seqid: u32,
+    pub machine_name: &'a[u8],
+}
+
+fn nfs4_req_create_session(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
+    let (i, client_id) = take(8_usize)(i)?;
+    let (i, seqid) = be_u32(i)?;
+    let (i, _flags) = be_u32(i)?;
+    let (i, _fore_chan_attrs) = take(28_usize)(i)?;
+    let (i, _back_chan_attrs) = take(28_usize)(i)?;
+    let (i, _cb_program) = be_u32(i)?;
+    let (i, _) = be_u32(i)?;
+    let (i, _flavor) = be_u32(i)?;
+    let (i, _stamp) = be_u32(i)?;
+    let (i, machine_name) = nfs4_parse_nfsstring(i)?;
+    let (i, _) = rest(i)?;
+
+    let req = Nfs4RequestContent::CreateSession(Nfs4RequestCreateSession {
+        client_id,
+        seqid,
+        machine_name,
+    });
+    Ok((i, req))
+}
+
 fn nfs4_req_putfh(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent> {
     map(nfs4_parse_handle, Nfs4RequestContent::PutFH)(i)
 }
@@ -458,6 +487,7 @@ fn parse_request_compound_command(i: &[u8]) -> IResult<&[u8], Nfs4RequestContent
         NFSPROC4_SETCLIENTID_CONFIRM => nfs4_req_setclientid_confirm(i)?,
         NFSPROC4_SEQUENCE => nfs4_req_sequence(i)?,
         NFSPROC4_EXCHANGE_ID => nfs4_req_exchangeid(i)?,
+        NFSPROC4_CREATE_SESSION => nfs4_req_create_session(i)?,
         _ => { return Err(Err::Error(make_error(i, ErrorKind::Switch))); }
     };
     Ok((i, cmd_data))
@@ -506,6 +536,31 @@ pub enum Nfs4ResponseContent<'a> {
     Commit(u32),
     ExchangeId(u32, Option<Nfs4ResponseExchangeId<'a>>),
     Sequence(u32, Option<Nfs4ResponseSequence<'a>>),
+    CreateSession(u32, Option<Nfs4ResponseCreateSession<'a>>),
+}
+
+#[derive(Debug, PartialEq)]
+pub struct Nfs4ResponseCreateSession<'a> {
+    pub ssn_id: &'a[u8],
+    pub seq_id: u32,
+}
+
+fn nfs4_parse_res_create_session(i: &[u8]) -> IResult<&[u8], Nfs4ResponseCreateSession> {
+    let (i, ssn_id) = take(16_usize)(i)?;
+    let (i, seq_id) = be_u32(i)?;
+    let (i, _flags) = be_u32(i)?;
+    let (i, _fore_chan_attrs) = take(28_usize)(i)?;
+    let (i, _back_chan_attrs) = take(28_usize)(i)?;
+    Ok((i, Nfs4ResponseCreateSession {
+        ssn_id,
+        seq_id
+    }))
+}
+
+fn nfs4_res_create_session(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
+    let (i, status) = be_u32(i)?;
+    let (i, create_ssn_data) = cond(status == 0, nfs4_parse_res_create_session)(i)?;
+    Ok((i, Nfs4ResponseContent::CreateSession( status, create_ssn_data )))
 }
 
 #[derive(Debug, PartialEq)]
@@ -890,6 +945,7 @@ fn nfs4_res_compound_command(i: &[u8]) -> IResult<&[u8], Nfs4ResponseContent> {
         NFSPROC4_EXCHANGE_ID => nfs4_res_exchangeid(i)?,
         NFSPROC4_SEQUENCE => nfs4_res_sequence(i)?,
         NFSPROC4_RENEW => nfs4_res_renew(i)?,
+        NFSPROC4_CREATE_SESSION => nfs4_res_create_session(i)?,
         _ => { return Err(Err::Error(make_error(i, ErrorKind::Switch))); }
     };
     Ok((i, cmd_data))
@@ -1199,6 +1255,38 @@ mod tests {
         }
     }
 
+    #[test]
+    fn test_nfs4_request_create_session() {
+        let buf: &[u8] = &[
+            0x00, 0x00, 0x00, 0x2b, /*opcode*/
+            0xe0, 0x14, 0x82, 0x00, 0x00, 0x00, 0x02, 0xd2, // create_session
+            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x04, 0x14,
+            0x00, 0x10, 0x03, 0x88, 0x00, 0x00, 0x0d, 0x64,
+            0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+            0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01,
+            0x00, 0x00, 0x00, 0x01, 0x0c, 0x09, 0x5e, 0x92,
+            0x00, 0x00, 0x00, 0x09, 0x6e, 0x65, 0x74, 0x61,
+            0x70, 0x70, 0x2d, 0x32, 0x36, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x00, 0x00,
+        ];
+
+        let (_, request) = nfs4_req_create_session(&buf[4..]).unwrap();
+        match request {
+            Nfs4RequestContent::CreateSession( create_ssn ) => {
+                assert_eq!(create_ssn.client_id, &buf[4..12]);
+                assert_eq!(create_ssn.seqid, 1);
+                assert_eq!(create_ssn.machine_name, b"netapp-26");
+            }
+            _ => { panic!("Failure"); }
+        }
+    }
+
     #[test]
     fn test_nfs4_attrs() {
         #[rustfmt::skip]
@@ -1537,5 +1625,34 @@ mod tests {
         }
     }
 
+    #[test]
+    fn test_nfs4_response_create_session() {
+        let buf: &[u8] = &[
+            0x00, 0x00, 0x00, 0x2b, /*opcode*/
+            0x00, 0x00, 0x00, 0x00, /*status*/
+        // create_session
+            0x00, 0x00, 0x02, 0xd2, 0xe0, 0x14, 0x82, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x02,
+            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x18, 0x00,
+            0x00, 0x01, 0x40, 0x00, 0x00, 0x00, 0x02, 0x80,
+            0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x40,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+            0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x10, 0x00,
+            0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02,
+            0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
+        ];
+
+        let (_, create_ssn) = nfs4_parse_res_create_session(&buf[8..]).unwrap();
+
+        let (_, response) = nfs4_res_create_session(&buf[4..]).unwrap();
+        match response {
+            Nfs4ResponseContent::CreateSession( status, create_ssn_data) => {
+                assert_eq!(status, 0);
+                assert_eq!(create_ssn_data, Some(create_ssn));
+            }
+            _ => { panic!("Failure"); }
+        }
+    }
 
 }
index c8ddfafc11a26c6f4135fce6b4254cd24aced973..07e2cf76c966ba2a34dadee004b9f91abb148864 100644 (file)
@@ -273,6 +273,7 @@ pub const NFSPROC4_SETCLIENTID_CONFIRM: u32 = 36;
 pub const NFSPROC4_VERIFY:              u32 = 37;
 pub const NFSPROC4_WRITE:               u32 = 38;
 pub const NFSPROC4_RELEASE_LOCKOWNER:   u32 = 39;
+pub const NFSPROC4_CREATE_SESSION:      u32 = 43;
 pub const NFSPROC4_SEQUENCE:            u32 = 53;