From d22c170c3880e35986830666212b92bddc0bd0bd Mon Sep 17 00:00:00 2001 From: Victor Julien Date: Sat, 21 Jul 2018 10:06:18 +0200 Subject: [PATCH] nfs: move v2 parsing into own file --- rust/src/nfs/mod.rs | 1 + rust/src/nfs/nfs.rs | 99 --------------------------------- rust/src/nfs/nfs2.rs | 128 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 129 insertions(+), 99 deletions(-) create mode 100644 rust/src/nfs/nfs2.rs diff --git a/rust/src/nfs/mod.rs b/rust/src/nfs/mod.rs index b9922eee5d..17cfc724d3 100644 --- a/rust/src/nfs/mod.rs +++ b/rust/src/nfs/mod.rs @@ -22,6 +22,7 @@ pub mod nfs2_records; pub mod nfs3_records; pub mod nfs4_records; pub mod nfs; +pub mod nfs2; pub mod nfs3; pub mod nfs4; pub mod log; diff --git a/rust/src/nfs/nfs.rs b/rust/src/nfs/nfs.rs index 7cbcf31f08..97ac175c35 100644 --- a/rust/src/nfs/nfs.rs +++ b/rust/src/nfs/nfs.rs @@ -24,7 +24,6 @@ use std::mem::transmute; use std::collections::{HashMap}; use std::ffi::CStr; -use nom; use nom::IResult; use log::*; @@ -511,72 +510,6 @@ impl NFSState { } } - /// complete request record - fn process_request_record_v2<'b>(&mut self, r: &RpcPacket<'b>) -> u32 { - SCLogDebug!("NFSv2 REQUEST {} procedure {} ({}) blob size {}", - r.hdr.xid, r.procedure, self.requestmap.len(), r.prog_data.len()); - - let mut xidmap = NFSRequestXidMap::new(r.progver, r.procedure, 0); - let aux_file_name = Vec::new(); - - if r.procedure == NFSPROC3_LOOKUP { - match parse_nfs2_request_lookup(r.prog_data) { - IResult::Done(_, ar) => { - xidmap.file_handle = ar.handle.value.to_vec(); - self.xidmap_handle2name(&mut xidmap); - }, - _ => { - self.set_event(NFSEvent::MalformedData); - }, - }; - } else if r.procedure == NFSPROC3_READ { - match parse_nfs2_request_read(r.prog_data) { - IResult::Done(_, read_record) => { - xidmap.chunk_offset = read_record.offset as u64; - xidmap.file_handle = read_record.handle.value.to_vec(); - self.xidmap_handle2name(&mut xidmap); - }, - _ => { - self.set_event(NFSEvent::MalformedData); - }, - }; - } - - if !(r.procedure == NFSPROC3_COMMIT || // commit handled separately - r.procedure == NFSPROC3_WRITE || // write handled in file tx - r.procedure == NFSPROC3_READ) // read handled in file tx at reply - { - let mut tx = self.new_tx(); - tx.xid = r.hdr.xid; - tx.procedure = r.procedure; - tx.request_done = true; - tx.file_name = xidmap.file_name.to_vec(); - tx.file_handle = xidmap.file_handle.to_vec(); - tx.nfs_version = r.progver as u16; - - if r.procedure == NFSPROC3_RENAME { - tx.type_data = Some(NFSTransactionTypeData::RENAME(aux_file_name)); - } - - tx.auth_type = r.creds_flavor; - match r.creds { - RpcRequestCreds::Unix(ref u) => { - tx.request_machine_name = u.machine_name_buf.to_vec(); - tx.request_uid = u.uid; - tx.request_gid = u.gid; - }, - _ => { }, - } - SCLogDebug!("NFSv2 TX created: ID {} XID {} PROCEDURE {}", - tx.id, tx.xid, tx.procedure); - self.transactions.push(tx); - } - - SCLogDebug!("NFSv2: TS creating xidmap {}", r.hdr.xid); - self.requestmap.insert(r.hdr.xid, xidmap); - 0 - } - pub fn new_file_tx(&mut self, file_handle: &Vec, file_name: &Vec, direction: u8) -> (&mut NFSTransaction, &mut FileContainer, u16) { @@ -692,38 +625,6 @@ impl NFSState { return self.process_write_record(r, w); } - fn process_reply_record_v2<'b>(&mut self, r: &RpcReplyPacket<'b>, xidmap: &NFSRequestXidMap) -> u32 { - let mut nfs_status = 0; - let resp_handle = Vec::new(); - - if xidmap.procedure == NFSPROC3_READ { - match parse_nfs2_reply_read(r.prog_data) { - IResult::Done(_, ref reply) => { - SCLogDebug!("NFSv2 READ reply record"); - self.process_read_record(r, reply, Some(&xidmap)); - nfs_status = reply.status; - }, - _ => { - self.set_event(NFSEvent::MalformedData); - }, - } - } else { - let stat = match nom::be_u32(&r.prog_data) { - nom::IResult::Done(_, stat) => { - stat as u32 - } - _ => 0 as u32 - }; - nfs_status = stat; - } - SCLogDebug!("REPLY {} to procedure {} blob size {}", - r.hdr.xid, xidmap.procedure, r.prog_data.len()); - - self.mark_response_tx_done(r.hdr.xid, r.reply_state, nfs_status, &resp_handle); - - 0 - } - fn process_reply_record<'b>(&mut self, r: &RpcReplyPacket<'b>) -> u32 { let mut xidmap; match self.requestmap.remove(&r.hdr.xid) { diff --git a/rust/src/nfs/nfs2.rs b/rust/src/nfs/nfs2.rs new file mode 100644 index 0000000000..f699886245 --- /dev/null +++ b/rust/src/nfs/nfs2.rs @@ -0,0 +1,128 @@ +/* Copyright (C) 2017-2018 Open Information Security Foundation + * + * You can copy, redistribute or modify this Program under the terms of + * the GNU General Public License version 2 as published by the Free + * Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * version 2 along with this program; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA + * 02110-1301, USA. + */ + +// written by Victor Julien + +use nom; +use nom::IResult; +use log::*; + +use nfs::nfs::*; +use nfs::types::*; +use nfs::rpc_records::*; +use nfs::nfs2_records::*; + +impl NFSState { + /// complete request record + pub fn process_request_record_v2<'b>(&mut self, r: &RpcPacket<'b>) -> u32 { + SCLogDebug!("NFSv2: REQUEST {} procedure {} ({}) blob size {}", + r.hdr.xid, r.procedure, self.requestmap.len(), r.prog_data.len()); + + let mut xidmap = NFSRequestXidMap::new(r.progver, r.procedure, 0); + let aux_file_name = Vec::new(); + + if r.procedure == NFSPROC3_LOOKUP { + match parse_nfs2_request_lookup(r.prog_data) { + IResult::Done(_, ar) => { + xidmap.file_handle = ar.handle.value.to_vec(); + self.xidmap_handle2name(&mut xidmap); + }, + _ => { + self.set_event(NFSEvent::MalformedData); + }, + }; + } else if r.procedure == NFSPROC3_READ { + match parse_nfs2_request_read(r.prog_data) { + IResult::Done(_, read_record) => { + xidmap.chunk_offset = read_record.offset as u64; + xidmap.file_handle = read_record.handle.value.to_vec(); + self.xidmap_handle2name(&mut xidmap); + }, + _ => { + self.set_event(NFSEvent::MalformedData); + }, + }; + } + + if !(r.procedure == NFSPROC3_COMMIT || // commit handled separately + r.procedure == NFSPROC3_WRITE || // write handled in file tx + r.procedure == NFSPROC3_READ) // read handled in file tx at reply + { + let mut tx = self.new_tx(); + tx.xid = r.hdr.xid; + tx.procedure = r.procedure; + tx.request_done = true; + tx.file_name = xidmap.file_name.to_vec(); + tx.file_handle = xidmap.file_handle.to_vec(); + tx.nfs_version = r.progver as u16; + + if r.procedure == NFSPROC3_RENAME { + tx.type_data = Some(NFSTransactionTypeData::RENAME(aux_file_name)); + } + + tx.auth_type = r.creds_flavor; + match r.creds { + RpcRequestCreds::Unix(ref u) => { + tx.request_machine_name = u.machine_name_buf.to_vec(); + tx.request_uid = u.uid; + tx.request_gid = u.gid; + }, + _ => { }, + } + SCLogDebug!("NFSv2: TX created: ID {} XID {} PROCEDURE {}", + tx.id, tx.xid, tx.procedure); + self.transactions.push(tx); + } + + SCLogDebug!("NFSv2: TS creating xidmap {}", r.hdr.xid); + self.requestmap.insert(r.hdr.xid, xidmap); + 0 + } + + pub fn process_reply_record_v2<'b>(&mut self, r: &RpcReplyPacket<'b>, xidmap: &NFSRequestXidMap) -> u32 { + let mut nfs_status = 0; + let resp_handle = Vec::new(); + + if xidmap.procedure == NFSPROC3_READ { + match parse_nfs2_reply_read(r.prog_data) { + IResult::Done(_, ref reply) => { + SCLogDebug!("NFSv2: READ reply record"); + self.process_read_record(r, reply, Some(&xidmap)); + nfs_status = reply.status; + }, + _ => { + self.set_event(NFSEvent::MalformedData); + }, + } + } else { + let stat = match nom::be_u32(&r.prog_data) { + nom::IResult::Done(_, stat) => { + stat as u32 + } + _ => 0 as u32 + }; + nfs_status = stat; + } + SCLogDebug!("NFSv2: REPLY {} to procedure {} blob size {}", + r.hdr.xid, xidmap.procedure, r.prog_data.len()); + + self.mark_response_tx_done(r.hdr.xid, r.reply_state, nfs_status, &resp_handle); + + 0 + } + +}