From: Victor Julien Date: Sat, 10 Mar 2018 08:57:44 +0000 (+0100) Subject: smb: move common parsing funcs into own file X-Git-Tag: suricata-4.1.0-beta1~81 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0ed00cf104f1cd776898c69237d5ffe25152b3f1;p=thirdparty%2Fsuricata.git smb: move common parsing funcs into own file --- diff --git a/rust/src/smb/mod.rs b/rust/src/smb/mod.rs index 7a3e518390..80fd362f43 100644 --- a/rust/src/smb/mod.rs +++ b/rust/src/smb/mod.rs @@ -15,6 +15,7 @@ * 02110-1301, USA. */ +pub mod smb_records; pub mod smb1_records; pub mod smb2_records; pub mod nbss_records; diff --git a/rust/src/smb/smb1.rs b/rust/src/smb/smb1.rs index 197143e826..26c954839e 100644 --- a/rust/src/smb/smb1.rs +++ b/rust/src/smb/smb1.rs @@ -604,12 +604,12 @@ pub fn smb1_trans_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) pipe.fid.to_vec()); } - let (sername, is_dcerpc) = get_service_for_nameslice(&rd.txname.name); + let (sername, is_dcerpc) = get_service_for_nameslice(&rd.txname.tx_name); SCLogDebug!("service: {} dcerpc {}", sername, is_dcerpc); if is_dcerpc { // store tx name so the response also knows this is dcerpc let txn_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_TXNAME); - state.ssn2vec_map.insert(txn_hdr, rd.txname.name.to_vec()); + state.ssn2vec_map.insert(txn_hdr, rd.txname.tx_name); // trans request will tell us the max size of the response // if there is more response data, it will first give a diff --git a/rust/src/smb/smb1_records.rs b/rust/src/smb/smb1_records.rs index ef18a4c2a2..b0d11b39bd 100644 --- a/rust/src/smb/smb1_records.rs +++ b/rust/src/smb/smb1_records.rs @@ -18,6 +18,7 @@ use log::*; use nom::{rest, le_u8, le_u16, le_u32, le_u64, IResult}; use smb::smb::*; +use smb::smb_records::*; #[derive(Debug,PartialEq)] pub struct Smb1WriteRequestRecord<'a> { @@ -167,7 +168,7 @@ named!(pub parse_smb_connect_tree_andx_record, pub struct SmbRecordTransRequest<'a> { pub params: SmbRecordTransRequestParams, pub pipe: Option>, - pub txname: SmbRecordTransRequestTxname<'a>, + pub txname: SmbRecordTransRequestTxname<>, pub data: SmbRecordTransRequestData<'a>, } @@ -231,29 +232,29 @@ named!(pub parse_smb_trans_request_record_params<(SmbRecordTransRequestParams, O ); #[derive(Debug,PartialEq)] -pub struct SmbRecordTransRequestTxname<'a> { - pub name: &'a[u8], +pub struct SmbRecordTransRequestTxname<> { + pub tx_name: Vec, } -pub fn parse_smb_trans_request_tx_name_ascii(i: &[u8]) +fn parse_smb_trans_request_tx_name_ascii(i: &[u8]) -> IResult<&[u8], SmbRecordTransRequestTxname> { do_parse!(i, - name: take_until_and_consume!("\0") + name: smb_get_ascii_string >> (SmbRecordTransRequestTxname { - name: name, + tx_name: name, }) ) } -pub fn parse_smb_trans_request_tx_name_unicode(i: &[u8], offset: usize) +fn parse_smb_trans_request_tx_name_unicode(i: &[u8], offset: usize) -> IResult<&[u8], SmbRecordTransRequestTxname> { do_parse!(i, cond!(offset % 2 == 1, take!(1)) - >> name: take_until_and_consume!("\0\0\0") + >> name: smb_get_unicode_string >> (SmbRecordTransRequestTxname { - name: name, + tx_name: name, }) ) } diff --git a/rust/src/smb/smb1_session.rs b/rust/src/smb/smb1_session.rs index 77ca72058c..e60db179cf 100644 --- a/rust/src/smb/smb1_session.rs +++ b/rust/src/smb/smb1_session.rs @@ -15,10 +15,11 @@ * 02110-1301, USA. */ -use nom::{IResult, ErrorKind}; +use nom::{IResult}; use log::*; +use smb::smb_records::*; use smb::smb1_records::*; use smb::smb::*; use smb::events::*; @@ -37,40 +38,6 @@ pub struct SessionSetupResponse { pub native_lm: Vec, } -/// parse a UTF16 string that is null terminated. Normally by 2 null -/// bytes, but at the end of the data it can also be a single null. -/// Skip every second byte. -pub fn smb_get_unicode_string(blob: &[u8]) -> IResult<&[u8], Vec> -{ - SCLogDebug!("get_unicode_string: blob {} {:?}", blob.len(), blob); - let mut name : Vec = Vec::new(); - let mut c = blob; - while c.len() >= 1 { - if c.len() == 1 && c[0] == 0 { - let rem = &c[1..]; - SCLogDebug!("get_unicode_string: name {:?}", name); - return IResult::Done(rem, name) - } else if c.len() == 1 { - break; - } else if c[0] == 0 && c[1] == 0 { - let rem = &c[2..]; - SCLogDebug!("get_unicode_string: name {:?}", name); - return IResult::Done(rem, name) - } - name.push(c[0]); - c = &c[2..]; - //SCLogNotice!("get_unicode_string: c {:?}", c); - } - IResult::Error(error_code!(ErrorKind::Custom(130))) -} - -/// parse an ASCII string that is null terminated -named!(pub smb_get_ascii_string>, - do_parse!( - s: take_until_and_consume!("\x00") - >> ( s.to_vec() ) -)); - pub fn smb1_session_setup_request_host_info(r: &SmbRecord, blob: &[u8]) -> SessionSetupRequest { if blob.len() > 1 && r.has_unicode_support() { diff --git a/rust/src/smb/smb_records.rs b/rust/src/smb/smb_records.rs new file mode 100644 index 0000000000..660b1697e9 --- /dev/null +++ b/rust/src/smb/smb_records.rs @@ -0,0 +1,53 @@ +/* Copyright (C) 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. + */ + +use nom::{IResult, ErrorKind}; +use log::*; + +/// parse a UTF16 string that is null terminated. Normally by 2 null +/// bytes, but at the end of the data it can also be a single null. +/// Skip every second byte. +pub fn smb_get_unicode_string(blob: &[u8]) -> IResult<&[u8], Vec> +{ + SCLogDebug!("get_unicode_string: blob {} {:?}", blob.len(), blob); + let mut name : Vec = Vec::new(); + let mut c = blob; + while c.len() >= 1 { + if c.len() == 1 && c[0] == 0 { + let rem = &c[1..]; + SCLogDebug!("get_unicode_string: name {:?}", name); + return IResult::Done(rem, name) + } else if c.len() == 1 { + break; + } else if c[0] == 0 && c[1] == 0 { + let rem = &c[2..]; + SCLogDebug!("get_unicode_string: name {:?}", name); + return IResult::Done(rem, name) + } + name.push(c[0]); + c = &c[2..]; + } + IResult::Error(error_code!(ErrorKind::Custom(130))) +} + +/// parse an ASCII string that is null terminated +named!(pub smb_get_ascii_string>, + do_parse!( + s: take_until_and_consume!("\x00") + >> ( s.to_vec() ) +)); +