rust: upgrade all parsers to nom4

pull/3646/head
Pierre Chifflier 7 years ago committed by Victor Julien
parent 2f08b3eabd
commit 13b7399790

@ -143,7 +143,7 @@ impl TemplateState {
while current.len() > 0 {
match parser::parse_message(current) {
nom::IResult::Done(rem, request) => {
Ok((rem, request)) => {
current = rem;
SCLogNotice!("Request: {}", request);
@ -151,11 +151,11 @@ impl TemplateState {
tx.request = Some(request);
self.transactions.push(tx);
}
nom::IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
self.request_buffer.extend_from_slice(current);
break;
}
nom::IResult::Error(_) => {
Err(_) => {
return false;
}
}
@ -181,7 +181,7 @@ impl TemplateState {
while current.len() > 0 {
match parser::parse_message(current) {
nom::IResult::Done(rem, response) => {
Ok((rem, response)) => {
current = rem;
match self.find_request() {
@ -194,11 +194,11 @@ impl TemplateState {
None => {}
}
}
nom::IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
self.response_buffer.extend_from_slice(current);
break;
}
nom::IResult::Error(_) => {
Err(_) => {
return false;
}
}

@ -22,7 +22,6 @@ use core::{sc_detect_engine_state_free, sc_app_layer_decoder_events_free_events}
use dhcp::parser::*;
use libc;
use log::*;
use nom;
use parser::*;
use std;
use std::ffi::{CStr,CString};
@ -144,7 +143,7 @@ impl DHCPState {
pub fn parse(&mut self, input: &[u8]) -> bool {
match dhcp_parse(input) {
nom::IResult::Done(_, message) => {
Ok((_, message)) => {
let malformed_options = message.malformed_options;
let truncated_options = message.truncated_options;
self.tx_id += 1;
@ -228,7 +227,7 @@ pub extern "C" fn rs_dhcp_probing_parser(_flow: *const Flow,
let slice = build_slice!(input, input_len as usize);
match parse_header(slice) {
nom::IResult::Done(_, _) => {
Ok((_, _)) => {
return unsafe { ALPROTO_DHCP };
}
_ => {

@ -196,14 +196,14 @@ named!(pub parse_all_options<Vec<DHCPOption>>, many0!(call!(parse_option)));
pub fn dhcp_parse(input: &[u8]) -> IResult<&[u8], DHCPMessage> {
match parse_header(input) {
IResult::Done(rem, header) => {
Ok((rem, header)) => {
let mut options = Vec::new();
let mut next = rem;
let mut malformed_options = false;
let mut truncated_options = false;
loop {
match parse_option(next) {
IResult::Done(rem, option) => {
Ok((rem, option)) => {
let done = option.code == DHCP_OPT_END;
options.push(option);
next = rem;
@ -211,14 +211,10 @@ pub fn dhcp_parse(input: &[u8]) -> IResult<&[u8], DHCPMessage> {
break;
}
}
IResult::Incomplete(_) => {
Err(_) => {
truncated_options = true;
break;
}
IResult::Error(_) => {
malformed_options = true;
break;
}
}
}
let message = DHCPMessage {
@ -227,13 +223,10 @@ pub fn dhcp_parse(input: &[u8]) -> IResult<&[u8], DHCPMessage> {
malformed_options: malformed_options,
truncated_options: truncated_options,
};
return IResult::Done(next, message);
}
IResult::Error(err) => {
return IResult::Error(err);
return Ok((next, message));
}
IResult::Incomplete(incomplete) => {
return IResult::Incomplete(incomplete);
Err(err) => {
return Err(err);
}
}
}
@ -249,7 +242,7 @@ mod tests {
let payload = &pcap[24 + 16 + 42..];
match dhcp_parse(payload) {
IResult::Done(_rem, message) => {
Ok((_rem, message)) => {
let header = message.header;
assert_eq!(header.opcode, BOOTP_REQUEST);
assert_eq!(header.htype, 1);

@ -353,7 +353,7 @@ impl DNSState {
pub fn parse_request(&mut self, input: &[u8]) -> bool {
match parser::dns_parse_request(input) {
nom::IResult::Done(_, request) => {
Ok((_, request)) => {
if request.header.flags & 0x8000 != 0 {
SCLogDebug!("DNS message is not a request");
self.set_event(DNSEvent::NotRequest);
@ -371,13 +371,13 @@ impl DNSState {
self.transactions.push(tx);
return true;
}
nom::IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
// Insufficient data.
SCLogDebug!("Insufficient data while parsing DNS request");
self.set_event(DNSEvent::MalformedData);
return false;
}
nom::IResult::Error(_) => {
Err(_) => {
// Error, probably malformed data.
SCLogDebug!("An error occurred while parsing DNS request");
self.set_event(DNSEvent::MalformedData);
@ -388,7 +388,7 @@ impl DNSState {
pub fn parse_response(&mut self, input: &[u8]) -> bool {
match parser::dns_parse_response(input) {
nom::IResult::Done(_, response) => {
Ok((_, response)) => {
SCLogDebug!("Response header flags: {}", response.header.flags);
@ -408,13 +408,13 @@ impl DNSState {
self.transactions.push(tx);
return true;
}
nom::IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
// Insufficient data.
SCLogDebug!("Insufficient data while parsing DNS response");
self.set_event(DNSEvent::MalformedData);
return false;
}
nom::IResult::Error(_) => {
Err(_) => {
// Error, probably malformed data.
SCLogDebug!("An error occurred while parsing DNS response");
self.set_event(DNSEvent::MalformedData);
@ -444,7 +444,7 @@ impl DNSState {
let mut count = 0;
while self.request_buffer.len() > 0 {
let size = match nom::be_u16(&self.request_buffer) {
nom::IResult::Done(_, len) => len,
Ok((_, len)) => len,
_ => 0
} as usize;
SCLogDebug!("Have {} bytes, need {} to parse",
@ -484,7 +484,7 @@ impl DNSState {
let mut count = 0;
while self.response_buffer.len() > 0 {
let size = match nom::be_u16(&self.response_buffer) {
nom::IResult::Done(_, len) => len,
Ok((_, len)) => len,
_ => 0
} as usize;
if size > 0 && self.response_buffer.len() >= size + 2 {
@ -521,16 +521,13 @@ impl DNSState {
/// Probe input to see if it looks like DNS.
fn probe(input: &[u8]) -> bool {
match parser::dns_parse_request(input) {
nom::IResult::Done(_, _) => true,
_ => false
}
parser::dns_parse_request(input).is_ok()
}
/// Probe TCP input to see if it looks like DNS.
pub fn probe_tcp(input: &[u8]) -> bool {
match nom::be_u16(input) {
nom::IResult::Done(rem, _) => {
Ok((rem, _)) => {
return probe(rem);
},
_ => {}

@ -17,7 +17,7 @@
//! Nom parsers for DNS.
use nom::{be_u8, be_u16, be_u32};
use nom::{IResult, be_u8, be_u16, be_u32};
use nom;
use dns::dns::*;
@ -50,7 +50,7 @@ named!(pub dns_parse_header<DNSHeader>,
/// message: the complete message that start is a part of
pub fn dns_parse_name<'a, 'b>(start: &'b [u8],
message: &'b [u8])
-> nom::IResult<&'b [u8], Vec<u8>> {
-> IResult<&'b [u8], Vec<u8>> {
let mut pos = start;
let mut pivot = start;
let mut name: Vec<u8> = Vec::with_capacity(32);
@ -68,7 +68,7 @@ pub fn dns_parse_name<'a, 'b>(start: &'b [u8],
break;
} else if len & 0b1100_0000 == 0 {
match length_bytes!(pos, be_u8) {
nom::IResult::Done(rem, label) => {
Ok((rem, label)) => {
if name.len() > 0 {
name.push('.' as u8);
}
@ -76,17 +76,17 @@ pub fn dns_parse_name<'a, 'b>(start: &'b [u8],
pos = rem;
}
_ => {
return nom::IResult::Error(
error_position!(nom::ErrorKind::OctDigit, pos));
return Err(nom::Err::Error(
error_position!(pos, nom::ErrorKind::OctDigit)));
}
}
} else if len & 0b1100_0000 == 0b1100_0000 {
match be_u16(pos) {
nom::IResult::Done(rem, leader) => {
Ok((rem, leader)) => {
let offset = leader & 0x3fff;
if offset as usize > message.len() {
return nom::IResult::Error(
error_position!(nom::ErrorKind::OctDigit, pos));
return Err(nom::Err::Error(
error_position!(pos, nom::ErrorKind::OctDigit)));
}
pos = &message[offset as usize..];
if pivot == start {
@ -94,20 +94,20 @@ pub fn dns_parse_name<'a, 'b>(start: &'b [u8],
}
}
_ => {
return nom::IResult::Error(
error_position!(nom::ErrorKind::OctDigit, pos));
return Err(nom::Err::Error(
error_position!(pos, nom::ErrorKind::OctDigit)));
}
}
} else {
return nom::IResult::Error(
error_position!(nom::ErrorKind::OctDigit, pos));
return Err(nom::Err::Error(
error_position!(pos, nom::ErrorKind::OctDigit)));
}
// Return error if we've looped a certain number of times.
count += 1;
if count > 255 {
return nom::IResult::Error(
error_position!(nom::ErrorKind::OctDigit, pos));
return Err(nom::Err::Error(
error_position!(pos, nom::ErrorKind::OctDigit)));
}
}
@ -117,9 +117,9 @@ pub fn dns_parse_name<'a, 'b>(start: &'b [u8],
// diverged from each other? A straight up comparison would
// actually check the contents.
if pivot.len() != start.len() {
return nom::IResult::Done(pivot, name);
return Ok((pivot, name));
}
return nom::IResult::Done(pos, name);
return Ok((pos, name));
}
@ -134,7 +134,7 @@ pub fn dns_parse_name<'a, 'b>(start: &'b [u8],
/// multi-string TXT entry as a single quote string, similar to the
/// output of dig. Something to consider for a future version.
fn dns_parse_answer<'a>(slice: &'a [u8], message: &'a [u8], count: usize)
-> nom::IResult<&'a [u8], Vec<DNSAnswerEntry>> {
-> IResult<&'a [u8], Vec<DNSAnswerEntry>> {
let mut answers = Vec::new();
let mut input = slice;
@ -155,7 +155,7 @@ fn dns_parse_answer<'a>(slice: &'a [u8], message: &'a [u8], count: usize)
data
)
))(input) {
nom::IResult::Done(rem, val) => {
Ok((rem, val)) => {
let name = val.0;
let rrtype = val.1;
let rrclass = val.2;
@ -176,14 +176,14 @@ fn dns_parse_answer<'a>(slice: &'a [u8], message: &'a [u8], count: usize)
1
}
};
let result: nom::IResult<&'a [u8], Vec<Vec<u8>>> =
let result: IResult<&'a [u8], Vec<Vec<u8>>> =
closure!(&'a [u8], do_parse!(
rdata: many_m_n!(1, n,
apply!(dns_parse_rdata, message, rrtype))
>> (rdata)
))(data);
match result {
nom::IResult::Done(_, rdatas) => {
Ok((_, rdatas)) => {
for rdata in rdatas {
answers.push(DNSAnswerEntry{
name: name.clone(),
@ -194,31 +194,21 @@ fn dns_parse_answer<'a>(slice: &'a [u8], message: &'a [u8], count: usize)
});
}
}
nom::IResult::Error(err) => {
return nom::IResult::Error(err);
}
nom::IResult::Incomplete(needed) => {
return nom::IResult::Incomplete(needed);
}
Err(e) => { return Err(e); }
}
input = rem;
}
nom::IResult::Error(err) => {
return nom::IResult::Error(err);
}
nom::IResult::Incomplete(needed) => {
return nom::IResult::Incomplete(needed);
}
Err(e) => { return Err(e); }
}
}
return nom::IResult::Done(input, answers);
return Ok((input, answers));
}
/// Parse a DNS response.
pub fn dns_parse_response<'a>(slice: &'a [u8])
-> nom::IResult<&[u8], DNSResponse> {
-> IResult<&[u8], DNSResponse> {
let response = closure!(&'a [u8], do_parse!(
header: dns_parse_header
>> queries: count!(
@ -247,7 +237,7 @@ pub fn dns_parse_response<'a>(slice: &'a [u8])
/// apply!(complete_dns_message_buffer)
pub fn dns_parse_query<'a>(input: &'a [u8],
message: &'a [u8])
-> nom::IResult<&'a [u8], DNSQueryEntry> {
-> IResult<&'a [u8], DNSQueryEntry> {
return closure!(&'a [u8], do_parse!(
name: apply!(dns_parse_name, message) >>
rrtype: be_u16 >>
@ -263,7 +253,7 @@ pub fn dns_parse_query<'a>(input: &'a [u8],
}
pub fn dns_parse_rdata<'a>(input: &'a [u8], message: &'a [u8], rrtype: u16)
-> nom::IResult<&'a [u8], Vec<u8>>
-> IResult<&'a [u8], Vec<u8>>
{
match rrtype {
DNS_RECORD_TYPE_CNAME |
@ -297,7 +287,7 @@ pub fn dns_parse_rdata<'a>(input: &'a [u8], message: &'a [u8], rrtype: u16)
}
/// Parse a DNS request.
pub fn dns_parse_request<'a>(input: &'a [u8]) -> nom::IResult<&[u8], DNSRequest> {
pub fn dns_parse_request<'a>(input: &'a [u8]) -> IResult<&[u8], DNSRequest> {
return closure!(&'a [u8], do_parse!(
header: dns_parse_header >>
queries: count!(apply!(dns_parse_query, input),
@ -316,7 +306,6 @@ mod tests {
use dns::dns::{DNSHeader,DNSAnswerEntry};
use dns::parser::*;
use nom::IResult;
/// Parse a simple name with no pointers.
#[test]
@ -328,16 +317,9 @@ mod tests {
0x03, 0x63, 0x6f, 0x6d, 0x00, 0x00, 0x01, 0x00, /* .com.... */
];
let expected_remainder: &[u8] = &[0x00, 0x01, 0x00];
let res = dns_parse_name(buf, buf);
match res {
IResult::Done(remainder, name) => {
assert_eq!("client-cf.dropbox.com".as_bytes(), &name[..]);
assert_eq!(remainder, expected_remainder);
}
_ => {
assert!(false);
}
}
let (remainder,name) = dns_parse_name(buf, buf).unwrap();
assert_eq!("client-cf.dropbox.com".as_bytes(), &name[..]);
assert_eq!(remainder, expected_remainder);
}
/// Test parsing a name with pointers.
@ -371,32 +353,32 @@ mod tests {
let start1 = &buf[54..];
let res1 = dns_parse_name(start1, message);
assert_eq!(res1,
IResult::Done(&start1[22..],
"www.suricata-ids.org".as_bytes().to_vec()));
Ok((&start1[22..],
"www.suricata-ids.org".as_bytes().to_vec())));
// The second name starts at offset 80, but is just a pointer
// to the first.
let start2 = &buf[80..];
let res2 = dns_parse_name(start2, message);
assert_eq!(res2,
IResult::Done(&start2[2..],
"www.suricata-ids.org".as_bytes().to_vec()));
Ok((&start2[2..],
"www.suricata-ids.org".as_bytes().to_vec())));
// The third name starts at offset 94, but is a pointer to a
// portion of the first.
let start3 = &buf[94..];
let res3 = dns_parse_name(start3, message);
assert_eq!(res3,
IResult::Done(&start3[2..],
"suricata-ids.org".as_bytes().to_vec()));
Ok((&start3[2..],
"suricata-ids.org".as_bytes().to_vec())));
// The fourth name starts at offset 110, but is a pointer to a
// portion of the first.
let start4 = &buf[110..];
let res4 = dns_parse_name(start4, message);
assert_eq!(res4,
IResult::Done(&start4[2..],
"suricata-ids.org".as_bytes().to_vec()));
Ok((&start4[2..],
"suricata-ids.org".as_bytes().to_vec())));
}
#[test]
@ -429,8 +411,8 @@ mod tests {
let res = dns_parse_name(start, message);
assert_eq!(res,
IResult::Done(&start[2..],
"block.g1.dropbox.com".as_bytes().to_vec()));
Ok((&start[2..],
"block.g1.dropbox.com".as_bytes().to_vec())));
}
#[test]
@ -448,7 +430,7 @@ mod tests {
let res = dns_parse_request(pkt);
match res {
IResult::Done(rem, request) => {
Ok((rem, request)) => {
// For now we have some remainder data as there is an
// additional record type we don't parse yet.
@ -498,7 +480,7 @@ mod tests {
let res = dns_parse_response(pkt);
match res {
IResult::Done(rem, response) => {
Ok((rem, response)) => {
// The response should be full parsed.
assert_eq!(rem.len(), 0);

@ -18,7 +18,7 @@
extern crate libc;
extern crate nom;
use nom::{digit};
use nom::digit;
use std::str;
use std;
use std::str::FromStr;
@ -61,14 +61,14 @@ named!(pub ftp_pasv_response<u16>,
pub extern "C" fn rs_ftp_pasv_response(input: *const libc::uint8_t, len: libc::uint32_t) -> u16 {
let buf = unsafe{std::slice::from_raw_parts(input, len as usize)};
match ftp_pasv_response(buf) {
nom::IResult::Done(_, dport) => {
Ok((_, dport)) => {
return dport;
}
nom::IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
let buf = unsafe{std::slice::from_raw_parts(input, len as usize)};
SCLogDebug!("pasv incomplete: '{:?}'", String::from_utf8_lossy(buf));
},
nom::IResult::Error(_) => {
Err(_) => {
let buf = unsafe{std::slice::from_raw_parts(input, len as usize)};
SCLogDebug!("pasv error on '{:?}'", String::from_utf8_lossy(buf));
},
@ -93,14 +93,14 @@ named!(pub ftp_epsv_response<u16>,
pub extern "C" fn rs_ftp_epsv_response(input: *const libc::uint8_t, len: libc::uint32_t) -> u16 {
let buf = unsafe{std::slice::from_raw_parts(input, len as usize)};
match ftp_epsv_response(buf) {
nom::IResult::Done(_, dport) => {
Ok((_, dport)) => {
return dport;
},
nom::IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
let buf = unsafe{std::slice::from_raw_parts(input, len as usize)};
SCLogDebug!("epsv incomplete: '{:?}'", String::from_utf8_lossy(buf));
},
nom::IResult::Error(_) => {
Err(_) => {
let buf = unsafe{std::slice::from_raw_parts(input, len as usize)};
SCLogDebug!("epsv incomplete: '{:?}'", String::from_utf8_lossy(buf));
},

@ -29,7 +29,7 @@ use std::ffi::{CStr,CString};
use log::*;
use nom::IResult;
use nom;
#[repr(u32)]
pub enum IKEV2Event {
@ -128,7 +128,7 @@ impl IKEV2State {
/// Returns The number of messages parsed, or -1 on error
fn parse(&mut self, i: &[u8], direction: u8) -> i32 {
match parse_ikev2_header(i) {
IResult::Done(rem,ref hdr) => {
Ok((rem,ref hdr)) => {
if rem.len() == 0 && hdr.length == 28 {
return 1;
}
@ -150,7 +150,7 @@ impl IKEV2State {
tx.xid = hdr.init_spi;
tx.hdr = (*hdr).clone();
match parse_ikev2_payload_list(rem,hdr.next_payload) {
IResult::Done(_,Ok(ref p)) => {
Ok((_,Ok(ref p))) => {
for payload in p {
tx.payload_types.push(payload.hdr.next_payload_type);
match payload.content {
@ -194,12 +194,12 @@ impl IKEV2State {
self.transactions.push(tx);
1
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
SCLogDebug!("Insufficient data while parsing IKEV2 data");
self.set_event(IKEV2Event::MalformedData);
-1
},
IResult::Error(_) => {
Err(_) => {
SCLogDebug!("Error while parsing IKEV2 data");
self.set_event(IKEV2Event::MalformedData);
-1
@ -617,7 +617,7 @@ pub extern "C" fn rs_ikev2_probing_parser(_flow: *const Flow, input:*const libc:
let slice = build_slice!(input,input_len as usize);
let alproto = unsafe{ ALPROTO_IKEV2 };
match parse_ikev2_header(slice) {
IResult::Done(_, ref hdr) => {
Ok((_, ref hdr)) => {
if hdr.maj_ver != 2 || hdr.min_ver != 0 {
SCLogDebug!("ipsec_probe: could be ipsec, but with unsupported/invalid version {}.{}",
hdr.maj_ver, hdr.min_ver);
@ -634,10 +634,10 @@ pub extern "C" fn rs_ikev2_probing_parser(_flow: *const Flow, input:*const libc:
}
return alproto;
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
return ALPROTO_UNKNOWN;
},
IResult::Error(_) => {
Err(_) => {
return unsafe{ALPROTO_FAILED};
},
}

@ -17,7 +17,8 @@
use kerberos_parser::krb5_parser::parse_ap_req;
use kerberos_parser::krb5::{ApReq,Realm,PrincipalName};
use nom::{IResult, ErrorKind, le_u16};
use nom;
use nom::{ErrorKind, IResult, le_u16};
use der_parser;
use der_parser::parse_der_oid;
@ -34,16 +35,10 @@ pub struct Kerberos5Ticket {
fn parse_kerberos5_request_do(blob: &[u8]) -> IResult<&[u8], ApReq>
{
let blob = match der_parser::parse_der(blob) {
IResult::Done(_, b) => {
match b.content.as_slice() {
Ok(b) => { b },
_ => { return IResult::Error(error_position!(blob,ErrorKind::Custom(SECBLOB_KRB_FMT_ERR))); },
}
},
IResult::Incomplete(needed) => { return IResult::Incomplete(needed); },
IResult::Error(err) => { return IResult::Error(err); },
};
let (_,b) = der_parser::parse_der(blob)?;
let blob = b.as_slice().or(
Err(nom::Err::Error(error_position!(blob, ErrorKind::Custom(SECBLOB_KRB_FMT_ERR))))
)?;
do_parse!(
blob,
base_o: parse_der_oid >>
@ -59,15 +54,10 @@ fn parse_kerberos5_request_do(blob: &[u8]) -> IResult<&[u8], ApReq>
pub fn parse_kerberos5_request(blob: &[u8]) -> IResult<&[u8], Kerberos5Ticket>
{
match parse_kerberos5_request_do(blob) {
IResult::Done(rem, req) => {
let t = Kerberos5Ticket {
realm: req.ticket.realm,
sname: req.ticket.sname,
};
return IResult::Done(rem, t);
}
IResult::Incomplete(needed) => { return IResult::Incomplete(needed); },
IResult::Error(err) => { return IResult::Error(err); },
}
let (rem, req) = parse_kerberos5_request_do(blob)?;
let t = Kerberos5Ticket {
realm: req.ticket.realm,
sname: req.ticket.sname,
};
return Ok((rem, t));
}

@ -20,7 +20,8 @@
use libc;
use std;
use std::ffi::{CStr,CString};
use nom::{IResult,be_u32};
use nom;
use nom::be_u32;
use der_parser::der_read_element_header;
use kerberos_parser::krb5_parser;
use kerberos_parser::krb5::{EncryptionType,ErrorCode,MessageType,PrincipalName,Realm};
@ -107,7 +108,7 @@ impl KRB5State {
/// Returns The number of messages parsed, or -1 on error
fn parse(&mut self, i: &[u8], _direction: u8) -> i32 {
match der_read_element_header(i) {
IResult::Done(_rem,hdr) => {
Ok((_rem,hdr)) => {
// Kerberos messages start with an APPLICATION header
if hdr.class != 0b01 { return 1; }
match hdr.tag {
@ -116,7 +117,7 @@ impl KRB5State {
},
11 => {
let res = krb5_parser::parse_as_rep(i);
res.map(|kdc_rep| {
if let Ok((_,kdc_rep)) = res {
let mut tx = self.new_tx();
tx.msg_type = MessageType::KRB_AS_REP;
tx.cname = Some(kdc_rep.cname);
@ -127,7 +128,7 @@ impl KRB5State {
if test_weak_encryption(kdc_rep.enc_part.etype) {
self.set_event(KRB5Event::WeakEncryption);
}
});
};
self.req_id = 0;
},
12 => {
@ -135,7 +136,7 @@ impl KRB5State {
},
13 => {
let res = krb5_parser::parse_tgs_rep(i);
res.map(|kdc_rep| {
if let Ok((_,kdc_rep)) = res {
let mut tx = self.new_tx();
tx.msg_type = MessageType::KRB_TGS_REP;
tx.cname = Some(kdc_rep.cname);
@ -146,7 +147,7 @@ impl KRB5State {
if test_weak_encryption(kdc_rep.enc_part.etype) {
self.set_event(KRB5Event::WeakEncryption);
}
});
};
self.req_id = 0;
},
14 => {
@ -157,7 +158,7 @@ impl KRB5State {
},
30 => {
let res = krb5_parser::parse_krb_error(i);
res.map(|error| {
if let Ok((_,error)) = res {
let mut tx = self.new_tx();
tx.msg_type = MessageType(self.req_id as u32);
tx.cname = error.cname;
@ -165,19 +166,19 @@ impl KRB5State {
tx.sname = Some(error.sname);
tx.error_code = Some(error.error_code);
self.transactions.push(tx);
});
};
self.req_id = 0;
},
_ => { SCLogDebug!("unknown/unsupported tag {}", hdr.tag); },
}
0
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
SCLogDebug!("Insufficient data while parsing KRB5 data");
self.set_event(KRB5Event::MalformedData);
-1
},
IResult::Error(_) => {
Err(_) => {
SCLogDebug!("Error while parsing KRB5 data");
self.set_event(KRB5Event::MalformedData);
-1
@ -409,7 +410,7 @@ pub extern "C" fn rs_krb5_probing_parser(_flow: *const Flow, input:*const libc::
let alproto = unsafe{ ALPROTO_KRB5 };
if slice.len() <= 10 { return unsafe{ALPROTO_FAILED}; }
match der_read_element_header(slice) {
IResult::Done(rem, ref hdr) => {
Ok((rem, ref hdr)) => {
// Kerberos messages start with an APPLICATION header
if hdr.class != 0b01 { return unsafe{ALPROTO_FAILED}; }
// Tag number should be <= 30
@ -417,7 +418,7 @@ pub extern "C" fn rs_krb5_probing_parser(_flow: *const Flow, input:*const libc::
// Kerberos messages contain sequences
if rem.is_empty() || rem[0] != 0x30 { return unsafe{ALPROTO_FAILED}; }
// Check kerberos version
if let IResult::Done(rem,_hdr) = der_read_element_header(rem) {
if let Ok((rem,_hdr)) = der_read_element_header(rem) {
if rem.len() > 5 {
match (rem[2],rem[3],rem[4]) {
// Encoding of DER integer 5 (version)
@ -428,10 +429,10 @@ pub extern "C" fn rs_krb5_probing_parser(_flow: *const Flow, input:*const libc::
}
return unsafe{ALPROTO_FAILED};
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
return ALPROTO_UNKNOWN;
},
IResult::Error(_) => {
Err(_) => {
return unsafe{ALPROTO_FAILED};
},
}
@ -442,15 +443,15 @@ pub extern "C" fn rs_krb5_probing_parser_tcp(_flow: *const Flow, input:*const li
let slice = build_slice!(input,input_len as usize);
if slice.len() <= 14 { return unsafe{ALPROTO_FAILED}; }
match be_u32(slice) {
IResult::Done(rem, record_mark) => {
Ok((rem, record_mark)) => {
// protocol implementations forbid very large requests
if record_mark > 16384 { return unsafe{ALPROTO_FAILED}; }
return rs_krb5_probing_parser(_flow, rem.as_ptr(), rem.len() as u32);
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
return ALPROTO_UNKNOWN;
},
IResult::Error(_) => {
Err(_) => {
return unsafe{ALPROTO_FAILED};
},
}
@ -514,7 +515,7 @@ pub extern "C" fn rs_krb5_parse_request_tcp(_flow: *const core::Flow,
while cur_i.len() > 0 {
if state.record_ts == 0 {
match be_u32(cur_i) {
IResult::Done(rem,record) => {
Ok((rem,record)) => {
state.record_ts = record as usize;
cur_i = rem;
},
@ -572,7 +573,7 @@ pub extern "C" fn rs_krb5_parse_response_tcp(_flow: *const core::Flow,
while cur_i.len() > 0 {
if state.record_tc == 0 {
match be_u32(cur_i) {
IResult::Done(rem,record) => {
Ok((rem,record)) => {
state.record_tc = record as usize;
cur_i = rem;
},

@ -24,7 +24,7 @@ use std::mem::transmute;
use std::collections::{HashMap};
use std::ffi::CStr;
use nom::IResult;
use nom;
use log::*;
use applayer;
@ -474,7 +474,7 @@ impl NFSState {
pub fn process_request_record_lookup<'b>(&mut self, r: &RpcPacket<'b>, xidmap: &mut NFSRequestXidMap) {
match parse_nfs3_request_lookup(r.prog_data) {
IResult::Done(_, lookup) => {
Ok((_, lookup)) => {
SCLogDebug!("LOOKUP {:?}", lookup);
xidmap.file_name = lookup.name_vec;
},
@ -816,7 +816,7 @@ impl NFSState {
if nfs_version == 2 {
let size = match parse_nfs2_attribs(reply.attr_blob) {
IResult::Done(_, ref attr) => {
Ok((_, ref attr)) => {
attr.asize
},
_ => { 0 },
@ -1014,7 +1014,7 @@ impl NFSState {
while cur_i.len() > 0 { // min record size
match parse_rpc_request_partial(cur_i) {
IResult::Done(_, ref rpc_phdr) => {
Ok((_, ref rpc_phdr)) => {
let rec_size = (rpc_phdr.hdr.frag_len + 4) as usize;
//SCLogDebug!("rec_size {}/{}", rec_size, cur_i.len());
//SCLogDebug!("cur_i {:?}", cur_i);
@ -1032,9 +1032,9 @@ impl NFSState {
// lets try to parse the RPC record. Might fail with Incomplete.
match parse_rpc(cur_i) {
IResult::Done(remaining, ref rpc_record) => {
Ok((remaining, ref rpc_record)) => {
match parse_nfs3_request_write(rpc_record.prog_data) {
IResult::Done(_, ref nfs_request_write) => {
Ok((_, ref nfs_request_write)) => {
// deal with the partial nfs write data
status |= self.process_partial_write_request_record(rpc_record, nfs_request_write);
cur_i = remaining; // progress input past parsed record
@ -1044,14 +1044,15 @@ impl NFSState {
},
}
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
// we just size checked for the minimal record size above,
// so if options are used (creds/verifier), we can still
// have Incomplete data. Fall through to the buffer code
// and try again on our next iteration.
SCLogDebug!("TS data incomplete");
},
IResult::Error(_e) => {
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return 1;
@ -1066,11 +1067,11 @@ impl NFSState {
// we have the full records size worth of data,
// let's parse it
match parse_rpc(&cur_i[..rec_size]) {
IResult::Done(_, ref rpc_record) => {
Ok((_, ref rpc_record)) => {
cur_i = &cur_i[rec_size..];
status |= self.process_request_record(rpc_record);
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
cur_i = &cur_i[rec_size..]; // progress input past parsed record
// we shouldn't get incomplete as we have the full data
@ -1080,19 +1081,21 @@ impl NFSState {
status = 1;
},
IResult::Error(_e) => {
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return 1;
},
}
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
SCLogDebug!("Fragmentation required (TCP level) 2");
self.tcp_buffer_ts.extend_from_slice(cur_i);
break;
},
IResult::Error(_e) => {
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return 1;
@ -1168,7 +1171,7 @@ impl NFSState {
while cur_i.len() > 0 {
match parse_rpc_packet_header(cur_i) {
IResult::Done(_, ref rpc_hdr) => {
Ok((_, ref rpc_hdr)) => {
let rec_size = (rpc_hdr.frag_len + 4) as usize;
// see if we have all data available
if rec_size > cur_i.len() {
@ -1184,29 +1187,31 @@ impl NFSState {
// we should have enough data to parse the RPC record
match parse_rpc_reply(cur_i) {
IResult::Done(remaining, ref rpc_record) => {
Ok((remaining, ref rpc_record)) => {
match parse_nfs3_reply_read(rpc_record.prog_data) {
IResult::Done(_, ref nfs_reply_read) => {
Ok((_, ref nfs_reply_read)) => {
// deal with the partial nfs read data
status |= self.process_partial_read_reply_record(rpc_record, nfs_reply_read);
cur_i = remaining; // progress input past parsed record
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
self.set_event(NFSEvent::MalformedData);
},
IResult::Error(_e) => {
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return 1;
}
}
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
// size check was done for MINIMAL record size,
// so Incomplete is normal.
SCLogDebug!("TC data incomplete");
},
IResult::Error(_e) => {
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return 1;
@ -1220,11 +1225,11 @@ impl NFSState {
// we have the full data of the record, lets parse
match parse_rpc_reply(&cur_i[..rec_size]) {
IResult::Done(_, ref rpc_record) => {
Ok((_, ref rpc_record)) => {
cur_i = &cur_i[rec_size..]; // progress input past parsed record
status |= self.process_reply_record(rpc_record);
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
cur_i = &cur_i[rec_size..]; // progress input past parsed record
// we shouldn't get incomplete as we have the full data
@ -1234,19 +1239,21 @@ impl NFSState {
status = 1;
},
IResult::Error(_e) => {
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return 1;
}
}
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
SCLogDebug!("REPLY: insufficient data for HDR");
self.tcp_buffer_tc.extend_from_slice(cur_i);
break;
},
IResult::Error(_e) => {
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
self.set_event(NFSEvent::MalformedData);
SCLogDebug!("Parsing failed: {:?}", _e);
return 1;
@ -1261,7 +1268,7 @@ impl NFSState {
SCLogDebug!("parse_udp_ts ({})", input.len());
if input.len() > 0 {
match parse_rpc_udp_request(input) {
IResult::Done(_, ref rpc_record) => {
Ok((_, ref rpc_record)) => {
self.is_udp = true;
match rpc_record.progver {
3 => {
@ -1273,10 +1280,10 @@ impl NFSState {
_ => { status = 1; },
}
},
IResult::Incomplete(_) => {
},
IResult::Error(_e) => { SCLogDebug!("Parsing failed: {:?}", _e);
Err(nom::Err::Incomplete(_)) => {
},
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => { SCLogDebug!("Parsing failed: {:?}", _e); }
}
}
status
@ -1288,15 +1295,14 @@ impl NFSState {
SCLogDebug!("parse_udp_tc ({})", input.len());
if input.len() > 0 {
match parse_rpc_udp_reply(input) {
IResult::Done(_, ref rpc_record) => {
Ok((_, ref rpc_record)) => {
self.is_udp = true;
status |= self.process_reply_record(rpc_record);
},
IResult::Incomplete(_) => {
},
IResult::Error(_e) => {
SCLogDebug!("Parsing failed: {:?}", _e);
Err(nom::Err::Incomplete(_)) => {
},
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => { SCLogDebug!("Parsing failed: {:?}", _e); }
}
};
status
@ -1678,7 +1684,7 @@ pub extern "C" fn rs_nfs_init(context: &'static mut SuricataFileContext)
pub fn nfs_probe(i: &[u8], direction: u8) -> i8 {
if direction == STREAM_TOCLIENT {
match parse_rpc_reply(i) {
IResult::Done(_, ref rpc) => {
Ok((_, ref rpc)) => {
if rpc.hdr.frag_len >= 24 && rpc.hdr.frag_len <= 35000 && rpc.hdr.msgtype == 1 && rpc.reply_state == 0 && rpc.accept_state == 0 {
SCLogDebug!("TC PROBE LEN {} XID {} TYPE {}", rpc.hdr.frag_len, rpc.hdr.xid, rpc.hdr.msgtype);
return 1;
@ -1686,9 +1692,9 @@ pub fn nfs_probe(i: &[u8], direction: u8) -> i8 {
return -1;
}
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
match parse_rpc_packet_header (i) {
IResult::Done(_, ref rpc_hdr) => {
Ok((_, ref rpc_hdr)) => {
if rpc_hdr.frag_len >= 24 && rpc_hdr.frag_len <= 35000 && rpc_hdr.xid != 0 && rpc_hdr.msgtype == 1 {
SCLogDebug!("TC PROBE LEN {} XID {} TYPE {}", rpc_hdr.frag_len, rpc_hdr.xid, rpc_hdr.msgtype);
return 1;
@ -1696,8 +1702,8 @@ pub fn nfs_probe(i: &[u8], direction: u8) -> i8 {
return -1;
}
},
IResult::Incomplete(_) => { },
IResult::Error(_) => {
Err(nom::Err::Incomplete(_)) => { },
Err(_) => {
return -1;
},
}
@ -1705,13 +1711,13 @@ pub fn nfs_probe(i: &[u8], direction: u8) -> i8 {
return 0;
},
IResult::Error(_) => {
Err(_) => {
return -1;
},
}
} else {
match parse_rpc(i) {
IResult::Done(_, ref rpc) => {
Ok((_, ref rpc)) => {
if rpc.hdr.frag_len >= 40 && rpc.hdr.msgtype == 0 &&
rpc.rpcver == 2 && (rpc.progver == 3 || rpc.progver == 4) &&
rpc.program == 100003 &&
@ -1722,10 +1728,10 @@ pub fn nfs_probe(i: &[u8], direction: u8) -> i8 {
return -1;
}
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
return 0;
},
IResult::Error(_) => {
Err(_) => {
return -1;
},
}
@ -1735,7 +1741,7 @@ pub fn nfs_probe(i: &[u8], direction: u8) -> i8 {
pub fn nfs_probe_udp(i: &[u8], direction: u8) -> i8 {
if direction == STREAM_TOCLIENT {
match parse_rpc_udp_reply(i) {
IResult::Done(_, ref rpc) => {
Ok((_, ref rpc)) => {
if i.len() >= 32 && rpc.hdr.msgtype == 1 && rpc.reply_state == 0 && rpc.accept_state == 0 {
SCLogDebug!("TC PROBE LEN {} XID {} TYPE {}", rpc.hdr.frag_len, rpc.hdr.xid, rpc.hdr.msgtype);
return 1;
@ -1743,16 +1749,13 @@ pub fn nfs_probe_udp(i: &[u8], direction: u8) -> i8 {
return -1;
}
},
IResult::Incomplete(_) => {
return -1;
},
IResult::Error(_) => {
Err(_) => {
return -1;
},
}
} else {
match parse_rpc_udp_request(i) {
IResult::Done(_, ref rpc) => {
Ok((_, ref rpc)) => {
if i.len() >= 48 && rpc.hdr.msgtype == 0 && rpc.progver == 3 && rpc.program == 100003 {
return 1;
} else if i.len() >= 48 && rpc.hdr.msgtype == 0 && rpc.progver == 2 && rpc.program == 100003 {
@ -1762,10 +1765,7 @@ pub fn nfs_probe_udp(i: &[u8], direction: u8) -> i8 {
return -1;
}
},
IResult::Incomplete(_) => {
return -1;
},
IResult::Error(_) => {
Err(_) => {
return -1;
},
}

@ -18,7 +18,6 @@
// written by Victor Julien
use nom;
use nom::IResult;
use log::*;
use nfs::nfs::*;
@ -37,7 +36,7 @@ impl NFSState {
if r.procedure == NFSPROC3_LOOKUP {
match parse_nfs2_request_lookup(r.prog_data) {
IResult::Done(_, ar) => {
Ok((_, ar)) => {
xidmap.file_handle = ar.handle.value.to_vec();
self.xidmap_handle2name(&mut xidmap);
},
@ -47,7 +46,7 @@ impl NFSState {
};
} else if r.procedure == NFSPROC3_READ {
match parse_nfs2_request_read(r.prog_data) {
IResult::Done(_, read_record) => {
Ok((_, read_record)) => {
xidmap.chunk_offset = read_record.offset as u64;
xidmap.file_handle = read_record.handle.value.to_vec();
self.xidmap_handle2name(&mut xidmap);
@ -99,7 +98,7 @@ impl NFSState {
if xidmap.procedure == NFSPROC3_READ {
match parse_nfs2_reply_read(r.prog_data) {
IResult::Done(_, ref reply) => {
Ok((_, ref reply)) => {
SCLogDebug!("NFSv2: READ reply record");
self.process_read_record(r, reply, Some(&xidmap));
nfs_status = reply.status;
@ -110,7 +109,7 @@ impl NFSState {
}
} else {
let stat = match nom::be_u32(&r.prog_data) {
nom::IResult::Done(_, stat) => {
Ok((_, stat)) => {
stat as u32
}
_ => 0 as u32

@ -18,7 +18,6 @@
// written by Victor Julien
use nom;
use nom::IResult;
use log::*;
use core::*;
@ -45,7 +44,7 @@ impl NFSState {
} else if r.procedure == NFSPROC3_ACCESS {
match parse_nfs3_request_access(r.prog_data) {
IResult::Done(_, ar) => {
Ok((_, ar)) => {
xidmap.file_handle = ar.handle.value.to_vec();
self.xidmap_handle2name(&mut xidmap);
},
@ -55,7 +54,7 @@ impl NFSState {
};
} else if r.procedure == NFSPROC3_GETATTR {
match parse_nfs3_request_getattr(r.prog_data) {
IResult::Done(_, gar) => {
Ok((_, gar)) => {
xidmap.file_handle = gar.handle.value.to_vec();
self.xidmap_handle2name(&mut xidmap);
},
@ -65,7 +64,7 @@ impl NFSState {
};
} else if r.procedure == NFSPROC3_READDIRPLUS {
match parse_nfs3_request_readdirplus(r.prog_data) {
IResult::Done(_, rdp) => {
Ok((_, rdp)) => {
xidmap.file_handle = rdp.handle.value.to_vec();
self.xidmap_handle2name(&mut xidmap);
},
@ -75,7 +74,7 @@ impl NFSState {
};
} else if r.procedure == NFSPROC3_READ {
match parse_nfs3_request_read(r.prog_data) {
IResult::Done(_, nfs3_read_record) => {
Ok((_, nfs3_read_record)) => {
xidmap.chunk_offset = nfs3_read_record.offset;
xidmap.file_handle = nfs3_read_record.handle.value.to_vec();
self.xidmap_handle2name(&mut xidmap);
@ -86,7 +85,7 @@ impl NFSState {
};
} else if r.procedure == NFSPROC3_WRITE {
match parse_nfs3_request_write(r.prog_data) {
IResult::Done(_, w) => {
Ok((_, w)) => {
self.process_write_record(r, &w);
},
_ => {
@ -95,7 +94,7 @@ impl NFSState {
}
} else if r.procedure == NFSPROC3_CREATE {
match parse_nfs3_request_create(r.prog_data) {
IResult::Done(_, nfs3_create_record) => {
Ok((_, nfs3_create_record)) => {
xidmap.file_handle = nfs3_create_record.handle.value.to_vec();
xidmap.file_name = nfs3_create_record.name_vec;
},
@ -106,7 +105,7 @@ impl NFSState {
} else if r.procedure == NFSPROC3_REMOVE {
match parse_nfs3_request_remove(r.prog_data) {
IResult::Done(_, rr) => {
Ok((_, rr)) => {
xidmap.file_handle = rr.handle.value.to_vec();
xidmap.file_name = rr.name_vec;
},
@ -117,7 +116,7 @@ impl NFSState {
} else if r.procedure == NFSPROC3_RENAME {
match parse_nfs3_request_rename(r.prog_data) {
IResult::Done(_, rr) => {
Ok((_, rr)) => {
xidmap.file_handle = rr.from_handle.value.to_vec();
xidmap.file_name = rr.from_name_vec;
aux_file_name = rr.to_name_vec;
@ -128,7 +127,7 @@ impl NFSState {
};
} else if r.procedure == NFSPROC3_MKDIR {
match parse_nfs3_request_mkdir(r.prog_data) {
IResult::Done(_, mr) => {
Ok((_, mr)) => {
xidmap.file_handle = mr.handle.value.to_vec();
xidmap.file_name = mr.name_vec;
},
@ -138,7 +137,7 @@ impl NFSState {
};
} else if r.procedure == NFSPROC3_RMDIR {
match parse_nfs3_request_rmdir(r.prog_data) {
IResult::Done(_, rr) => {
Ok((_, rr)) => {
xidmap.file_handle = rr.handle.value.to_vec();
xidmap.file_name = rr.name_vec;
},
@ -150,7 +149,7 @@ impl NFSState {
SCLogDebug!("COMMIT, closing shop");
match parse_nfs3_request_commit(r.prog_data) {
IResult::Done(_, cr) => {
Ok((_, cr)) => {
let file_handle = cr.handle.value.to_vec();
match self.get_file_tx_by_handle(&file_handle, STREAM_TOSERVER) {
Some((tx, files, flags)) => {
@ -236,7 +235,7 @@ impl NFSState {
if xidmap.procedure == NFSPROC3_LOOKUP {
match parse_nfs3_response_lookup(r.prog_data) {
IResult::Done(_, lookup) => {
Ok((_, lookup)) => {
SCLogDebug!("LOOKUP: {:?}", lookup);
SCLogDebug!("RESPONSE LOOKUP file_name {:?}", xidmap.file_name);
@ -252,7 +251,7 @@ impl NFSState {
};
} else if xidmap.procedure == NFSPROC3_CREATE {
match parse_nfs3_response_create(r.prog_data) {
IResult::Done(_, nfs3_create_record) => {
Ok((_, nfs3_create_record)) => {
SCLogDebug!("nfs3_create_record: {:?}", nfs3_create_record);
SCLogDebug!("RESPONSE CREATE file_name {:?}", xidmap.file_name);
@ -271,7 +270,7 @@ impl NFSState {
};
} else if xidmap.procedure == NFSPROC3_READ {
match parse_nfs3_reply_read(r.prog_data) {
IResult::Done(_, ref reply) => {
Ok((_, ref reply)) => {
self.process_read_record(r, reply, Some(&xidmap));
nfs_status = reply.status;
},
@ -281,7 +280,7 @@ impl NFSState {
}
} else if xidmap.procedure == NFSPROC3_READDIRPLUS {
match parse_nfs3_response_readdirplus(r.prog_data) {
IResult::Done(_, ref reply) => {
Ok((_, ref reply)) => {
//SCLogDebug!("READDIRPLUS reply {:?}", reply);
nfs_status = reply.status;
@ -291,7 +290,7 @@ impl NFSState {
// store all handle/filename mappings
match many0_nfs3_response_readdirplus_entries(d) {
IResult::Done(_, ref entries) => {
Ok((_, ref entries)) => {
for ce in entries {
SCLogDebug!("ce {:?}", ce);
match ce.entry {
@ -324,7 +323,7 @@ impl NFSState {
// for all other record types only parse the status
else {
let stat = match nom::be_u32(&r.prog_data) {
nom::IResult::Done(_, stat) => {
Ok((_, stat)) => {
stat as u32
}
_ => 0 as u32

@ -19,7 +19,8 @@
extern crate libc;
use nom::{IResult, be_u32};
use nom;
use nom::be_u32;
use core::*;
use log::*;
@ -247,19 +248,20 @@ impl NFSState {
if creds.procedure == 0 && creds.service == 2 {
SCLogDebug!("GSS INTEGRITIY: {:?}", creds);
match parse_rpc_gssapi_integrity(r.prog_data) {
IResult::Done(_rem, rec) => {
Ok((_rem, rec)) => {
SCLogDebug!("GSS INTEGRITIY wrapper: {:?}", rec);
data = rec.data;
// store proc and serv for the reply
xidmap.gssapi_proc = creds.procedure;
xidmap.gssapi_service = creds.service;
},
IResult::Incomplete(_n) => {
Err(nom::Err::Incomplete(_n)) => {
SCLogDebug!("NFSPROC4_COMPOUND/GSS INTEGRITIY: INCOMPLETE {:?}", _n);
self.set_event(NFSEvent::MalformedData);
return 0;
},
IResult::Error(_e) => {
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
SCLogDebug!("NFSPROC4_COMPOUND/GSS INTEGRITIY: Parsing failed: {:?}", _e);
self.set_event(NFSEvent::MalformedData);
return 0;
@ -269,15 +271,16 @@ impl NFSState {
}
match parse_nfs4_request_compound(data) {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
SCLogDebug!("NFSPROC4_COMPOUND: {:?}", rd);
self.compound_request(&r, &rd, &mut xidmap);
},
IResult::Incomplete(_n) => {
Err(nom::Err::Incomplete(_n)) => {
SCLogDebug!("NFSPROC4_COMPOUND: INCOMPLETE {:?}", _n);
self.set_event(NFSEvent::MalformedData);
},
IResult::Error(_e) => {
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
SCLogDebug!("NFSPROC4_COMPOUND: Parsing failed: {:?}", _e);
self.set_event(NFSEvent::MalformedData);
},
@ -376,16 +379,17 @@ impl NFSState {
SCLogDebug!("GSS INTEGRITIY as set by call: {:?}", xidmap);
match parse_rpc_gssapi_integrity(r.prog_data) {
IResult::Done(_rem, rec) => {
Ok((_rem, rec)) => {
SCLogDebug!("GSS INTEGRITIY wrapper: {:?}", rec);
data = rec.data;
},
IResult::Incomplete(_n) => {
Err(nom::Err::Incomplete(_n)) => {
SCLogDebug!("NFSPROC4_COMPOUND/GSS INTEGRITIY: INCOMPLETE {:?}", _n);
self.set_event(NFSEvent::MalformedData);
return 0;
},
IResult::Error(_e) => {
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
SCLogDebug!("NFSPROC4_COMPOUND/GSS INTEGRITIY: Parsing failed: {:?}", _e);
self.set_event(NFSEvent::MalformedData);
return 0;
@ -393,14 +397,15 @@ impl NFSState {
}
}
match parse_nfs4_response_compound(data) {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
SCLogDebug!("COMPOUNDv4: {:?}", rd);
self.compound_response(&r, &rd, xidmap);
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
self.set_event(NFSEvent::MalformedData);
},
IResult::Error(_e) => {
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
SCLogDebug!("Parsing failed: {:?}", _e);
self.set_event(NFSEvent::MalformedData);
},

@ -29,7 +29,7 @@ use std::ffi::{CStr,CString};
use log::*;
use nom::IResult;
use nom;
#[repr(u32)]
pub enum NTPEvent {
@ -87,7 +87,7 @@ impl NTPState {
/// Returns The number of messages parsed, or -1 on error
fn parse(&mut self, i: &[u8], _direction: u8) -> i32 {
match parse_ntp(i) {
IResult::Done(_,ref msg) => {
Ok((_,ref msg)) => {
// SCLogDebug!("parse_ntp: {:?}",msg);
if msg.mode == NtpMode::SymmetricActive || msg.mode == NtpMode::Client {
let mut tx = self.new_tx();
@ -97,12 +97,12 @@ impl NTPState {
}
1
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
SCLogDebug!("Insufficient data while parsing NTP data");
self.set_event(NTPEvent::MalformedData);
-1
},
IResult::Error(_) => {
Err(_) => {
SCLogDebug!("Error while parsing NTP data");
self.set_event(NTPEvent::MalformedData);
-1
@ -347,17 +347,17 @@ pub extern "C" fn ntp_probing_parser(_flow: *const Flow, input:*const u8, input_
let slice: &[u8] = unsafe { std::slice::from_raw_parts(input as *mut u8, input_len as usize) };
let alproto = unsafe{ ALPROTO_NTP };
match parse_ntp(slice) {
IResult::Done(_, ref msg) => {
Ok((_, ref msg)) => {
if msg.version == 3 || msg.version == 4 {
return alproto;
} else {
return unsafe{ALPROTO_FAILED};
}
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
return ALPROTO_UNKNOWN;
},
IResult::Error(_) => {
Err(_) => {
return unsafe{ALPROTO_FAILED};
},
}

@ -21,32 +21,25 @@ use log::*;
use smb::ntlmssp_records::*;
use smb::smb::*;
use nom;
use nom::{IResult, ErrorKind};
use der_parser;
fn parse_secblob_get_spnego(blob: &[u8]) -> IResult<&[u8], &[u8]>
{
let (rem, base_o) = match der_parser::parse_der(blob) {
IResult::Done(rem, o) => (rem, o),
IResult::Incomplete(needed) => { return IResult::Incomplete(needed); },
IResult::Error(err) => { return IResult::Error(err); },
};
let (rem, base_o) = der_parser::parse_der(blob)?;
SCLogDebug!("parse_secblob_get_spnego: base_o {:?}", base_o);
let d = match base_o.content.as_slice() {
Err(_) => { return IResult::Error(error_position!(blob,ErrorKind::Custom(SECBLOB_NOT_SPNEGO))); },
Err(_) => { return Err(nom::Err::Error(error_position!(blob,ErrorKind::Custom(SECBLOB_NOT_SPNEGO)))); },
Ok(d) => d,
};
let (next, o) = match der_parser::parse_der_oid(d) {
IResult::Done(rem,y) => { (rem,y) },
IResult::Incomplete(needed) => { return IResult::Incomplete(needed); },
IResult::Error(err) => { return IResult::Error(err); },
};
let (next, o) = der_parser::parse_der_oid(d)?;
SCLogDebug!("parse_secblob_get_spnego: sub_o {:?}", o);
let oid = match o.content.as_oid() {
Ok(oid) => oid,
Err(_) => {
return IResult::Error(error_position!(blob,ErrorKind::Custom(SECBLOB_NOT_SPNEGO)));
return Err(nom::Err::Error(error_position!(blob,ErrorKind::Custom(SECBLOB_NOT_SPNEGO))));
},
};
SCLogDebug!("oid {}", oid.to_string());
@ -56,35 +49,28 @@ fn parse_secblob_get_spnego(blob: &[u8]) -> IResult<&[u8], &[u8]>
SCLogDebug!("SPNEGO {}", oid);
},
_ => {
return IResult::Error(error_position!(blob,ErrorKind::Custom(SECBLOB_NOT_SPNEGO)));
return Err(nom::Err::Error(error_position!(blob,ErrorKind::Custom(SECBLOB_NOT_SPNEGO))));
},
}
SCLogDebug!("parse_secblob_get_spnego: next {:?}", next);
SCLogDebug!("parse_secblob_get_spnego: DONE");
IResult::Done(rem, next)
Ok((rem, next))
}
fn parse_secblob_spnego_start(blob: &[u8]) -> IResult<&[u8], &[u8]>
{
let (rem, o) = match der_parser::parse_der(blob) {
IResult::Done(rem,o) => {
SCLogDebug!("o {:?}", o);
(rem, o)
},
IResult::Incomplete(needed) => { return IResult::Incomplete(needed); },
IResult::Error(err) => { return IResult::Error(err); },
};
let (rem, o) = der_parser::parse_der(blob)?;
let d = match o.content.as_slice() {
Ok(d) => {
SCLogDebug!("d: next data len {}",d.len());
d
},
_ => {
return IResult::Error(error_position!(blob,ErrorKind::Custom(SECBLOB_NOT_SPNEGO)));
return Err(nom::Err::Error(error_position!(blob,ErrorKind::Custom(SECBLOB_NOT_SPNEGO))));
},
};
IResult::Done(rem, d)
Ok((rem, d))
}
pub struct SpnegoRequest {
@ -100,7 +86,7 @@ fn parse_secblob_spnego(blob: &[u8]) -> Option<SpnegoRequest>
let mut ntlmssp : Option<NtlmsspData> = None;
let o = match der_parser::parse_der_sequence(blob) {
IResult::Done(_, o) => o,
Ok((_, o)) => o,
_ => { return None; },
};
for s in o {
@ -111,7 +97,7 @@ fn parse_secblob_spnego(blob: &[u8]) -> Option<SpnegoRequest>
_ => { continue; },
};
let o = match der_parser::parse_der(n) {
IResult::Done(_,x) => x,
Ok((_,x)) => x,
_ => { continue; },
};
SCLogDebug!("o {:?}", o);
@ -140,7 +126,7 @@ fn parse_secblob_spnego(blob: &[u8]) -> Option<SpnegoRequest>
der_parser::DerObjectContent::OctetString(ref os) => {
if have_kerberos {
match parse_kerberos5_request(os) {
IResult::Done(_, t) => {
Ok((_, t)) => {
kticket = Some(t)
},
_ => { },
@ -178,7 +164,7 @@ fn parse_ntlmssp_blob(blob: &[u8]) -> Option<NtlmsspData>
SCLogDebug!("NTLMSSP {:?}", blob);
match parse_ntlmssp(blob) {
IResult::Done(_, nd) => {
Ok((_, nd)) => {
SCLogDebug!("NTLMSSP TYPE {}/{} nd {:?}",
nd.msg_type, &ntlmssp_type_string(nd.msg_type), nd);
match nd.msg_type {
@ -186,7 +172,7 @@ fn parse_ntlmssp_blob(blob: &[u8]) -> Option<NtlmsspData>
},
NTLMSSP_AUTH => {
match parse_ntlm_auth_record(nd.data) {
IResult::Done(_, ad) => {
Ok((_, ad)) => {
SCLogDebug!("auth data {:?}", ad);
let mut host = ad.host.to_vec();
host.retain(|&i|i != 0x00);
@ -218,9 +204,9 @@ fn parse_ntlmssp_blob(blob: &[u8]) -> Option<NtlmsspData>
pub fn parse_secblob(blob: &[u8]) -> Option<SpnegoRequest>
{
match parse_secblob_get_spnego(blob) {
IResult::Done(_, spnego) => {
Ok((_, spnego)) => {
match parse_secblob_spnego_start(spnego) {
IResult::Done(_, spnego_start) => {
Ok((_, spnego_start)) => {
parse_secblob_spnego(spnego_start)
},
_ => {

@ -18,7 +18,6 @@
// written by Victor Julien
extern crate libc;
use nom::IResult;
use log::*;
use smb::smb::*;
@ -259,7 +258,7 @@ pub fn smb_write_dcerpc_record<'b>(state: &mut SMBState,
SCLogDebug!("called for {} bytes of data", data.len());
match parse_dcerpc_record(data) {
IResult::Done(_, dcer) => {
Ok((_, dcer)) => {
SCLogDebug!("DCERPC: version {}.{} write data {} => {:?}",
dcer.version_major, dcer.version_minor, dcer.data.len(), dcer);
@ -268,7 +267,7 @@ pub fn smb_write_dcerpc_record<'b>(state: &mut SMBState,
if dcer.packet_type == DCERPC_TYPE_REQUEST && dcer.first_frag == false {
SCLogDebug!("NOT the first frag. Need to find an existing TX");
match parse_dcerpc_request_record(dcer.data, dcer.frag_len, dcer.little_endian) {
IResult::Done(_, recr) => {
Ok((_, recr)) => {
let found = match state.get_dcerpc_tx(&hdr, &vercmd, dcer.call_id) {
Some(tx) => {
SCLogDebug!("previous CMD {} found at tx {} => {:?}",
@ -305,7 +304,7 @@ pub fn smb_write_dcerpc_record<'b>(state: &mut SMBState,
match dcer.packet_type {
DCERPC_TYPE_REQUEST => {
match parse_dcerpc_request_record(dcer.data, dcer.frag_len, dcer.little_endian) {
IResult::Done(_, recr) => {
Ok((_, recr)) => {
SCLogDebug!("DCERPC: REQUEST {:?}", recr);
if let Some(SMBTransactionTypeData::DCERPC(ref mut tdn)) = tx.type_data {
SCLogDebug!("first frag size {}", recr.data.len());
@ -333,7 +332,7 @@ pub fn smb_write_dcerpc_record<'b>(state: &mut SMBState,
parse_dcerpc_bind_record_big(dcer.data)
};
match brec {
IResult::Done(_, bindr) => {
Ok((_, bindr)) => {
SCLogDebug!("SMB DCERPC {:?} BIND {:?}", dcer, bindr);
if bindr.ifaces.len() > 0 {
@ -387,7 +386,7 @@ fn smb_dcerpc_response_bindack(
ntstatus: u32)
{
match parse_dcerpc_bindack_record(dcer.data) {
IResult::Done(_, bindackr) => {
Ok((_, bindackr)) => {
SCLogDebug!("SMB READ BINDACK {:?}", bindackr);
let found = match state.get_dcerpc_tx(&hdr, &vercmd, dcer.call_id) {
@ -461,7 +460,7 @@ fn dcerpc_response_handle<'b>(tx: &mut SMBTransaction,
match dcer.packet_type {
DCERPC_TYPE_RESPONSE => {
match parse_dcerpc_response_record(dcer.data, dcer.frag_len) {
IResult::Done(_, respr) => {
Ok((_, respr)) => {
SCLogDebug!("SMBv1 READ RESPONSE {:?}", respr);
if let Some(SMBTransactionTypeData::DCERPC(ref mut tdn)) = tx.type_data {
SCLogDebug!("CMD 11 found at tx {}", tx.id);
@ -533,7 +532,7 @@ pub fn smb_read_dcerpc_record<'b>(state: &mut SMBState,
} else {
match parse_dcerpc_record(&data) {
IResult::Done(_, dcer) => {
Ok((_, dcer)) => {
SCLogDebug!("DCERPC: version {}.{} read data {} => {:?}",
dcer.version_major, dcer.version_minor, dcer.data.len(), dcer);
@ -581,17 +580,14 @@ pub fn smb_read_dcerpc_record<'b>(state: &mut SMBState,
/// Try to find out if the input data looks like DCERPC
pub fn smb_dcerpc_probe<'b>(data: &[u8]) -> bool
{
match parse_dcerpc_record(data) {
IResult::Done(_, recr) => {
SCLogDebug!("SMB: could be DCERPC {:?}", recr);
if recr.version_major == 5 && recr.version_minor < 3 &&
recr.frag_len > 0 && recr.packet_type <= 20
if let Ok((_, recr)) = parse_dcerpc_record(data) {
SCLogDebug!("SMB: could be DCERPC {:?}", recr);
if recr.version_major == 5 && recr.version_minor < 3 &&
recr.frag_len > 0 && recr.packet_type <= 20
{
SCLogDebug!("SMB: looks like we have dcerpc");
return true;
}
},
_ => { },
}
return false;
}

@ -15,6 +15,7 @@
* 02110-1301, USA.
*/
use nom;
use nom::{rest, le_u8, be_u16, le_u16, le_u32, IResult, ErrorKind, Endianness};
#[derive(Debug,PartialEq)]
@ -28,7 +29,7 @@ pub fn parse_dcerpc_response_record(i:&[u8], frag_len: u16 )
-> IResult<&[u8], DceRpcResponseRecord>
{
if frag_len < 24 {
return IResult::Error(error_position!(i,ErrorKind::Custom(128)));
return Err(nom::Err::Error(error_position!(i,ErrorKind::Custom(128))));
}
do_parse!(i,
take!(8)
@ -51,7 +52,7 @@ pub fn parse_dcerpc_request_record(i:&[u8], frag_len: u16, little: bool)
-> IResult<&[u8], DceRpcRequestRecord>
{
if frag_len < 24 {
return IResult::Error(error_position!(i,ErrorKind::Custom(128)));
return Err(nom::Err::Error(error_position!(i,ErrorKind::Custom(128))));
}
do_parse!(i,
take!(6)

@ -30,9 +30,10 @@ use std::mem::transmute;
use std::str;
use std::ffi::CStr;
use nom::IResult;
use std::collections::HashMap;
use nom;
use core::*;
use log::*;
use applayer;
@ -1248,7 +1249,7 @@ impl SMBState {
// lost so we give up.
if input.len() > 8 {
match parse_nbss_record_partial(input) {
IResult::Done(_, ref hdr) => {
Ok((_, ref hdr)) => {
if !hdr.is_smb() {
SCLogDebug!("partial NBSS, not SMB and no known msg type {}", hdr.message_type);
self.trunc_ts();
@ -1262,16 +1263,16 @@ impl SMBState {
}
match parse_nbss_record_partial(input) {
IResult::Done(output, ref nbss_part_hdr) => {
Ok((output, ref nbss_part_hdr)) => {
SCLogDebug!("parse_nbss_record_partial ok, output len {}", output.len());
if nbss_part_hdr.message_type == NBSS_MSGTYPE_SESSION_MESSAGE {
match parse_smb_version(&nbss_part_hdr.data) {
IResult::Done(_, ref smb) => {
Ok((_, ref smb)) => {
SCLogDebug!("SMB {:?}", smb);
if smb.version == 0xff_u8 { // SMB1
SCLogDebug!("SMBv1 record");
match parse_smb_record(&nbss_part_hdr.data) {
IResult::Done(_, ref r) => {
Ok((_, ref r)) => {
if r.command == SMB1_COMMAND_WRITE_ANDX {
// see if it's a write to a pipe. We only handle those
// if complete.
@ -1295,7 +1296,7 @@ impl SMBState {
} else if smb.version == 0xfe_u8 { // SMB2
SCLogDebug!("SMBv2 record");
match parse_smb2_request_record(&nbss_part_hdr.data) {
IResult::Done(_, ref smb_record) => {
Ok((_, ref smb_record)) => {
SCLogDebug!("SMB2: partial record {}",
&smb2_command_string(smb_record.command));
if smb_record.command == SMB2_COMMAND_WRITE {
@ -1368,7 +1369,7 @@ impl SMBState {
if self.ts_gap {
SCLogDebug!("TS trying to catch up after GAP (input {})", cur_i.len());
match search_smb_record(cur_i) {
IResult::Done(_, pg) => {
Ok((_, pg)) => {
SCLogDebug!("smb record found");
let smb2_offset = cur_i.len() - pg.data.len();
if smb2_offset < 4 {
@ -1388,17 +1389,17 @@ impl SMBState {
}
while cur_i.len() > 0 { // min record size
match parse_nbss_record(cur_i) {
IResult::Done(rem, ref nbss_hdr) => {
Ok((rem, ref nbss_hdr)) => {
if nbss_hdr.message_type == NBSS_MSGTYPE_SESSION_MESSAGE {
// we have the full records size worth of data,
// let's parse it
match parse_smb_version(&nbss_hdr.data) {
IResult::Done(_, ref smb) => {
Ok((_, ref smb)) => {
SCLogDebug!("SMB {:?}", smb);
if smb.version == 0xff_u8 { // SMB1
SCLogDebug!("SMBv1 record");
match parse_smb_record(&nbss_hdr.data) {
IResult::Done(_, ref smb_record) => {
Ok((_, ref smb_record)) => {
smb1_request_record(self, smb_record);
},
_ => {
@ -1411,7 +1412,7 @@ impl SMBState {
while nbss_data.len() > 0 {
SCLogDebug!("SMBv2 record");
match parse_smb2_request_record(&nbss_data) {
IResult::Done(nbss_data_rem, ref smb_record) => {
Ok((nbss_data_rem, ref smb_record)) => {
SCLogDebug!("nbss_data_rem {}", nbss_data_rem.len());
smb2_request_record(self, smb_record);
@ -1428,7 +1429,7 @@ impl SMBState {
while nbss_data.len() > 0 {
SCLogDebug!("SMBv3 transform record");
match parse_smb3_transform_record(&nbss_data) {
IResult::Done(nbss_data_rem, ref _smb3_record) => {
Ok((nbss_data_rem, ref _smb3_record)) => {
nbss_data = nbss_data_rem;
},
_ => {
@ -1449,14 +1450,14 @@ impl SMBState {
}
cur_i = rem;
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
let consumed = self.parse_tcp_data_ts_partial(cur_i);
cur_i = &cur_i[consumed ..];
self.tcp_buffer_ts.extend_from_slice(cur_i);
break;
},
IResult::Error(_) => {
Err(_) => {
self.set_event(SMBEvent::MalformedData);
return 1;
},
@ -1477,7 +1478,7 @@ impl SMBState {
// lost so we give up.
if input.len() > 8 {
match parse_nbss_record_partial(input) {
IResult::Done(_, ref hdr) => {
Ok((_, ref hdr)) => {
if !hdr.is_smb() {
SCLogDebug!("partial NBSS, not SMB and no known msg type {}", hdr.message_type);
self.trunc_tc();
@ -1491,16 +1492,16 @@ impl SMBState {
}
match parse_nbss_record_partial(input) {
IResult::Done(output, ref nbss_part_hdr) => {
Ok((output, ref nbss_part_hdr)) => {
SCLogDebug!("parse_nbss_record_partial ok, output len {}", output.len());
if nbss_part_hdr.message_type == NBSS_MSGTYPE_SESSION_MESSAGE {
match parse_smb_version(&nbss_part_hdr.data) {
IResult::Done(_, ref smb) => {
Ok((_, ref smb)) => {
SCLogDebug!("SMB {:?}", smb);
if smb.version == 255u8 { // SMB1
SCLogDebug!("SMBv1 record");
match parse_smb_record(&nbss_part_hdr.data) {
IResult::Done(_, ref r) => {
Ok((_, ref r)) => {
SCLogDebug!("SMB1: partial record {}",
r.command);
if r.command == SMB1_COMMAND_READ_ANDX {
@ -1523,7 +1524,7 @@ impl SMBState {
} else if smb.version == 254u8 { // SMB2
SCLogDebug!("SMBv2 record");
match parse_smb2_response_record(&nbss_part_hdr.data) {
IResult::Done(_, ref smb_record) => {
Ok((_, ref smb_record)) => {
SCLogDebug!("SMB2: partial record {}",
&smb2_command_string(smb_record.command));
if smb_record.command == SMB2_COMMAND_READ {
@ -1594,7 +1595,7 @@ impl SMBState {
if self.tc_gap {
SCLogDebug!("TC trying to catch up after GAP (input {})", cur_i.len());
match search_smb_record(cur_i) {
IResult::Done(_, pg) => {
Ok((_, pg)) => {
SCLogDebug!("smb record found");
let smb2_offset = cur_i.len() - pg.data.len();
if smb2_offset < 4 {
@ -1614,17 +1615,17 @@ impl SMBState {
}
while cur_i.len() > 0 { // min record size
match parse_nbss_record(cur_i) {
IResult::Done(rem, ref nbss_hdr) => {
Ok((rem, ref nbss_hdr)) => {
if nbss_hdr.message_type == NBSS_MSGTYPE_SESSION_MESSAGE {
// we have the full records size worth of data,
// let's parse it
match parse_smb_version(&nbss_hdr.data) {
IResult::Done(_, ref smb) => {
Ok((_, ref smb)) => {
SCLogDebug!("SMB {:?}", smb);
if smb.version == 0xff_u8 { // SMB1
SCLogDebug!("SMBv1 record");
match parse_smb_record(&nbss_hdr.data) {
IResult::Done(_, ref smb_record) => {
Ok((_, ref smb_record)) => {
smb1_response_record(self, smb_record);
},
_ => {
@ -1637,7 +1638,7 @@ impl SMBState {
while nbss_data.len() > 0 {
SCLogDebug!("SMBv2 record");
match parse_smb2_response_record(&nbss_data) {
IResult::Done(nbss_data_rem, ref smb_record) => {
Ok((nbss_data_rem, ref smb_record)) => {
smb2_response_record(self, smb_record);
nbss_data = nbss_data_rem;
},
@ -1652,7 +1653,7 @@ impl SMBState {
while nbss_data.len() > 0 {
SCLogDebug!("SMBv3 transform record");
match parse_smb3_transform_record(&nbss_data) {
IResult::Done(nbss_data_rem, ref _smb3_record) => {
Ok((nbss_data_rem, ref _smb3_record)) => {
nbss_data = nbss_data_rem;
},
_ => {
@ -1663,11 +1664,11 @@ impl SMBState {
}
}
},
IResult::Incomplete(_) => {
Err(nom::Err::Incomplete(_)) => {
// not enough data to contain basic SMB hdr
// TODO event: empty NBSS_MSGTYPE_SESSION_MESSAGE
},
IResult::Error(_) => {
Err(_) => {
self.set_event(SMBEvent::MalformedData);
return 1;
},
@ -1677,7 +1678,7 @@ impl SMBState {
}
cur_i = rem;
},
IResult::Incomplete(needed) => {
Err(nom::Err::Incomplete(needed)) => {
SCLogDebug!("INCOMPLETE have {} needed {:?}", cur_i.len(), needed);
let consumed = self.parse_tcp_data_tc_partial(cur_i);
cur_i = &cur_i[consumed ..];
@ -1686,7 +1687,7 @@ impl SMBState {
self.tcp_buffer_tc.extend_from_slice(cur_i);
break;
},
IResult::Error(_) => {
Err(_) => {
self.set_event(SMBEvent::MalformedData);
return 1;
},
@ -1874,7 +1875,7 @@ pub extern "C" fn rs_smb_probe_tcp(input: *const libc::uint8_t, len: libc::uint3
{
let slice = build_slice!(input, len as usize);
match search_smb_record(slice) {
IResult::Done(_, _) => {
Ok((_, _)) => {
SCLogDebug!("smb found");
return 1;
},
@ -1883,7 +1884,7 @@ pub extern "C" fn rs_smb_probe_tcp(input: *const libc::uint8_t, len: libc::uint3
},
}
match parse_nbss_record_partial(slice) {
IResult::Done(_, ref hdr) => {
Ok((_, ref hdr)) => {
if hdr.is_smb() {
SCLogDebug!("smb found");
return 1;

@ -21,7 +21,7 @@
extern crate libc;
use nom::{IResult};
use nom;
use core::*;
use log::*;
@ -191,7 +191,7 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
let have_tx = match r.command {
SMB1_COMMAND_RENAME => {
match parse_smb_rename_request_record(r.data) {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
SCLogDebug!("RENAME {:?}", rd);
let tx_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
@ -214,18 +214,18 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
},
SMB1_COMMAND_TRANS2 => {
match parse_smb_trans2_request_record(r.data) {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
SCLogDebug!("TRANS2 DONE {:?}", rd);
if rd.subcmd == 6 {
SCLogDebug!("SET_PATH_INFO");
match parse_trans2_request_params_set_path_info(rd.setup_blob) {
IResult::Done(_, pd) => {
Ok((_, pd)) => {
SCLogDebug!("TRANS2 SET_PATH_INFO PARAMS DONE {:?}", pd);
if pd.loi == 1013 { // set disposition info
match parse_trans2_request_data_set_file_info_disposition(rd.data_blob) {
IResult::Done(_, disp) => {
Ok((_, disp)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION DONE {:?}", disp);
let tx_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
@ -237,12 +237,13 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
true
},
IResult::Incomplete(n) => {
Err(nom::Err::Incomplete(n)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION INCOMPLETE {:?}", n);
events.push(SMBEvent::MalformedData);
false
},
IResult::Error(e) => {
Err(nom::Err::Error(e)) |
Err(nom::Err::Failure(e)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION ERROR {:?}", e);
events.push(SMBEvent::MalformedData);
false
@ -250,7 +251,7 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
}
} else if pd.loi == 1010 {
match parse_trans2_request_data_set_path_info_rename(rd.data_blob) {
IResult::Done(_, ren) => {
Ok((_, ren)) => {
SCLogDebug!("TRANS2 SET_PATH_INFO DATA RENAME DONE {:?}", ren);
let tx_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
let mut newname = ren.newname.to_vec();
@ -264,12 +265,13 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
tx.vercmd.set_smb1_cmd(SMB1_COMMAND_TRANS2);
true
},
IResult::Incomplete(n) => {
Err(nom::Err::Incomplete(n)) => {
SCLogDebug!("TRANS2 SET_PATH_INFO DATA RENAME INCOMPLETE {:?}", n);
events.push(SMBEvent::MalformedData);
false
},
IResult::Error(e) => {
Err(nom::Err::Error(e)) |
Err(nom::Err::Failure(e)) => {
SCLogDebug!("TRANS2 SET_PATH_INFO DATA RENAME ERROR {:?}", e);
events.push(SMBEvent::MalformedData);
false
@ -279,12 +281,13 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
false
}
},
IResult::Incomplete(n) => {
Err(nom::Err::Incomplete(n)) => {
SCLogDebug!("TRANS2 SET_PATH_INFO PARAMS INCOMPLETE {:?}", n);
events.push(SMBEvent::MalformedData);
false
},
IResult::Error(e) => {
Err(nom::Err::Error(e)) |
Err(nom::Err::Failure(e)) => {
SCLogDebug!("TRANS2 SET_PATH_INFO PARAMS ERROR {:?}", e);
events.push(SMBEvent::MalformedData);
false
@ -293,12 +296,12 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
} else if rd.subcmd == 8 {
SCLogDebug!("SET_FILE_INFO");
match parse_trans2_request_params_set_file_info(rd.setup_blob) {
IResult::Done(_, pd) => {
Ok((_, pd)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS DONE {:?}", pd);
if pd.loi == 1013 { // set disposition info
match parse_trans2_request_data_set_file_info_disposition(rd.data_blob) {
IResult::Done(_, disp) => {
Ok((_, disp)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION DONE {:?}", disp);
let tx_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
@ -317,12 +320,13 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
true
},
IResult::Incomplete(n) => {
Err(nom::Err::Incomplete(n)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION INCOMPLETE {:?}", n);
events.push(SMBEvent::MalformedData);
false
},
IResult::Error(e) => {
Err(nom::Err::Error(e)) |
Err(nom::Err::Failure(e)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION ERROR {:?}", e);
events.push(SMBEvent::MalformedData);
false
@ -330,7 +334,7 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
}
} else if pd.loi == 1010 {
match parse_trans2_request_data_set_file_info_rename(rd.data_blob) {
IResult::Done(_, ren) => {
Ok((_, ren)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA RENAME DONE {:?}", ren);
let tx_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
let mut newname = ren.newname.to_vec();
@ -349,12 +353,13 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
tx.vercmd.set_smb1_cmd(SMB1_COMMAND_TRANS2);
true
},
IResult::Incomplete(n) => {
Err(nom::Err::Incomplete(n)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA RENAME INCOMPLETE {:?}", n);
events.push(SMBEvent::MalformedData);
false
},
IResult::Error(e) => {
Err(nom::Err::Error(e)) |
Err(nom::Err::Failure(e)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA RENAME ERROR {:?}", e);
events.push(SMBEvent::MalformedData);
false
@ -364,12 +369,13 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
false
}
},
IResult::Incomplete(n) => {
Err(nom::Err::Incomplete(n)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS INCOMPLETE {:?}", n);
events.push(SMBEvent::MalformedData);
false
},
IResult::Error(e) => {
Err(nom::Err::Error(e)) |
Err(nom::Err::Failure(e)) => {
SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS ERROR {:?}", e);
events.push(SMBEvent::MalformedData);
false
@ -379,12 +385,13 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
false
}
},
IResult::Incomplete(n) => {
Err(nom::Err::Incomplete(n)) => {
SCLogDebug!("TRANS2 INCOMPLETE {:?}", n);
events.push(SMBEvent::MalformedData);
false
},
IResult::Error(e) => {
Err(nom::Err::Error(e)) |
Err(nom::Err::Failure(e)) => {
SCLogDebug!("TRANS2 ERROR {:?}", e);
events.push(SMBEvent::MalformedData);
false
@ -393,7 +400,7 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
},
SMB1_COMMAND_READ_ANDX => {
match parse_smb_read_andx_request_record(r.data) {
IResult::Done(_, rr) => {
Ok((_, rr)) => {
SCLogDebug!("rr {:?}", rr);
// store read fid,offset in map
@ -421,7 +428,7 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
},
SMB1_COMMAND_NEGOTIATE_PROTOCOL => {
match parse_smb1_negotiate_protocol_record(r.data) {
IResult::Done(_, pr) => {
Ok((_, pr)) => {
SCLogDebug!("SMB_COMMAND_NEGOTIATE_PROTOCOL {:?}", pr);
let mut bad_dialects = false;
@ -466,7 +473,7 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
},
SMB1_COMMAND_NT_CREATE_ANDX => {
match parse_smb_create_andx_request_record(r.data) {
IResult::Done(_, cr) => {
Ok((_, cr)) => {
SCLogDebug!("Create AndX {:?}", cr);
let del = cr.create_options & 0x0000_1000 != 0;
let dir = cr.create_options & 0x0000_0001 != 0;
@ -497,7 +504,7 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
SMB1_COMMAND_TREE_CONNECT_ANDX => {
SCLogDebug!("SMB1_COMMAND_TREE_CONNECT_ANDX");
match parse_smb_connect_tree_andx_record(r.data, r) {
IResult::Done(_, tr) => {
Ok((_, tr)) => {
let name_key = SMBCommonHdr::from1(r, SMBHDR_TYPE_TREE);
let mut name_val = tr.path;
if name_val.len() > 1 {
@ -527,7 +534,7 @@ pub fn smb1_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32 {
},
SMB1_COMMAND_CLOSE => {
match parse_smb1_close_request_record(r.data) {
IResult::Done(_, cd) => {
Ok((_, cd)) => {
let mut fid = cd.fid.to_vec();
fid.extend_from_slice(&u32_as_bytes(r.ssn_id));
SCLogDebug!("closing FID {:?}/{:?}", cd.fid, fid);
@ -592,7 +599,7 @@ pub fn smb1_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32
SMB1_COMMAND_NEGOTIATE_PROTOCOL => {
SCLogDebug!("SMB1_COMMAND_NEGOTIATE_PROTOCOL response");
match parse_smb1_negotiate_protocol_response_record(r.data) {
IResult::Done(_, pr) => {
Ok((_, pr)) => {
let (have_ntx, dialect) = match state.get_negotiate_tx(1) {
Some(tx) => {
tx.set_status(r.nt_status, r.is_dos_error);
@ -649,7 +656,7 @@ pub fn smb1_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32
}
match parse_smb_connect_tree_andx_response_record(r.data) {
IResult::Done(_, tr) => {
Ok((_, tr)) => {
let name_key = SMBCommonHdr::from1(r, SMBHDR_TYPE_TREE);
let is_pipe = tr.service == "IPC".as_bytes();
let mut share_name = Vec::new();
@ -693,7 +700,7 @@ pub fn smb1_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>) -> u32
SCLogDebug!("SMB1_COMMAND_NT_CREATE_ANDX response {:08x}", r.nt_status);
if r.nt_status == SMB_NTSTATUS_SUCCESS {
match parse_smb_create_andx_response_record(r.data) {
IResult::Done(_, cr) => {
Ok((_, cr)) => {
SCLogDebug!("Create AndX {:?}", cr);
let guid_key = SMBCommonHdr::from1(r, SMBHDR_TYPE_FILENAME);
@ -795,7 +802,7 @@ pub fn smb1_trans_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
let mut events : Vec<SMBEvent> = Vec::new();
match parse_smb_trans_request_record(r.data, r) {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
SCLogDebug!("TRANS request {:?}", rd);
/* if we have a fid, store it so the response can pick it up */
@ -835,7 +842,7 @@ pub fn smb1_trans_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
let mut events : Vec<SMBEvent> = Vec::new();
match parse_smb_trans_response_record(r.data) {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
SCLogDebug!("TRANS response {:?}", rd);
// see if we have a stored fid
@ -890,7 +897,7 @@ pub fn smb1_write_request_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
parse_smb1_write_and_close_request_record(r.data)
};
match result {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
SCLogDebug!("SMBv1: write andx => {:?}", rd);
let mut file_fid = rd.fid.to_vec();
@ -960,7 +967,7 @@ pub fn smb1_read_response_record<'b>(state: &mut SMBState, r: &SmbRecord<'b>)
if r.nt_status == SMB_NTSTATUS_SUCCESS {
match parse_smb_read_andx_response_record(r.data) {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
SCLogDebug!("SMBv1: read response => {:?}", rd);
let fid_key = SMBCommonHdr::from1(r, SMBHDR_TYPE_OFFSET);

@ -300,19 +300,11 @@ pub fn parse_smb_trans_request_record_data(i: &[u8],
pub fn parse_smb_trans_request_record<'a, 'b>(i: &'a[u8], r: &SmbRecord<'b>)
-> IResult<&'a[u8], SmbRecordTransRequest<'a>>
{
let (rem, (params, pipe)) = match parse_smb_trans_request_record_params(i) {
IResult::Done(rem, (rd, p)) => (rem, (rd, p)),
IResult::Incomplete(ii) => { return IResult::Incomplete(ii); }
IResult::Error(e) => { return IResult::Error(e); }
};
let (rem, (params, pipe)) = parse_smb_trans_request_record_params(i)?;
let mut offset = 32 + (i.len() - rem.len()); // init with SMB header
SCLogDebug!("params {:?}: offset {}", params, offset);
let (rem2, n) = match smb1_get_string(rem, r, offset) {
IResult::Done(rem, rd) => (rem, rd),
IResult::Incomplete(ii) => { return IResult::Incomplete(ii); }
IResult::Error(e) => { return IResult::Error(e); }
};
let (rem2, n) = smb1_get_string(rem, r, offset)?;
offset += rem.len() - rem2.len();
SCLogDebug!("n {:?}: offset {}", n, offset);
@ -340,9 +332,8 @@ pub fn parse_smb_trans_request_record<'a, 'b>(i: &'a[u8], r: &SmbRecord<'b>)
let d = match parse_smb_trans_request_record_data(rem2,
pad1, params.param_cnt, pad2, params.data_cnt) {
IResult::Done(_, rd) => rd,
IResult::Incomplete(ii) => { return IResult::Incomplete(ii); }
IResult::Error(e) => { return IResult::Error(e); }
Ok((_, rd)) => rd,
Err(e) => { return Err(e); }
};
SCLogDebug!("d {:?}", d);
d
@ -353,7 +344,7 @@ pub fn parse_smb_trans_request_record<'a, 'b>(i: &'a[u8], r: &SmbRecord<'b>)
let res = SmbRecordTransRequest {
params: params, pipe: pipe, txname: n, data: recdata,
};
IResult::Done(&rem, res)
Ok((&rem, res))
}

@ -15,8 +15,6 @@
* 02110-1301, USA.
*/
use nom::{IResult};
use log::*;
use smb::smb_records::*;
@ -44,11 +42,11 @@ pub fn smb1_session_setup_request_host_info(r: &SmbRecord, blob: &[u8]) -> Sessi
let offset = r.data.len() - blob.len();
let blob = if offset % 2 == 1 { &blob[1..] } else { blob };
let (native_os, native_lm, primary_domain) = match smb_get_unicode_string(blob) {
IResult::Done(rem, n1) => {
Ok((rem, n1)) => {
match smb_get_unicode_string(rem) {
IResult::Done(rem, n2) => {
Ok((rem, n2)) => {
match smb_get_unicode_string(rem) {
IResult::Done(_, n3) => { (n1, n2, n3) },
Ok((_, n3)) => { (n1, n2, n3) },
_ => { (n1, n2, Vec::new()) },
}
},
@ -66,11 +64,11 @@ pub fn smb1_session_setup_request_host_info(r: &SmbRecord, blob: &[u8]) -> Sessi
}
} else {
let (native_os, native_lm, primary_domain) = match smb_get_ascii_string(blob) {
IResult::Done(rem, n1) => {
Ok((rem, n1)) => {
match smb_get_ascii_string(rem) {
IResult::Done(rem, n2) => {
Ok((rem, n2)) => {
match smb_get_ascii_string(rem) {
IResult::Done(_, n3) => { (n1, n2, n3) },
Ok((_, n3)) => { (n1, n2, n3) },
_ => { (n1, n2, Vec::new()) },
}
},
@ -95,9 +93,9 @@ pub fn smb1_session_setup_response_host_info(r: &SmbRecord, blob: &[u8]) -> Sess
let offset = r.data.len() - blob.len();
let blob = if offset % 2 == 1 { &blob[1..] } else { blob };
let (native_os, native_lm) = match smb_get_unicode_string(blob) {
IResult::Done(rem, n1) => {
Ok((rem, n1)) => {
match smb_get_unicode_string(rem) {
IResult::Done(_, n2) => (n1, n2),
Ok((_, n2)) => (n1, n2),
_ => { (n1, Vec::new()) },
}
},
@ -112,9 +110,9 @@ pub fn smb1_session_setup_response_host_info(r: &SmbRecord, blob: &[u8]) -> Sess
} else {
SCLogDebug!("session_setup_response_host_info: not unicode");
let (native_os, native_lm) = match smb_get_ascii_string(blob) {
IResult::Done(rem, n1) => {
Ok((rem, n1)) => {
match smb_get_ascii_string(rem) {
IResult::Done(_, n2) => (n1, n2),
Ok((_, n2)) => (n1, n2),
_ => { (n1, Vec::new()) },
}
},
@ -131,7 +129,7 @@ pub fn smb1_session_setup_request(state: &mut SMBState, r: &SmbRecord)
{
SCLogDebug!("SMB1_COMMAND_SESSION_SETUP_ANDX user_id {}", r.user_id);
match parse_smb_setup_andx_record(r.data) {
IResult::Done(rem, setup) => {
Ok((rem, setup)) => {
let hdr = SMBCommonHdr::new(SMBHDR_TYPE_HEADER,
r.ssn_id as u64, 0, r.multiplex_id as u64);
let tx = state.new_sessionsetup_tx(hdr);
@ -157,7 +155,7 @@ pub fn smb1_session_setup_request(state: &mut SMBState, r: &SmbRecord)
fn smb1_session_setup_update_tx(tx: &mut SMBTransaction, r: &SmbRecord)
{
match parse_smb_response_setup_andx_record(r.data) {
IResult::Done(rem, _setup) => {
Ok((rem, _setup)) => {
if let Some(SMBTransactionTypeData::SESSIONSETUP(ref mut td)) = tx.type_data {
td.response_host = Some(smb1_session_setup_response_host_info(r, rem));
}

@ -15,9 +15,10 @@
* 02110-1301, USA.
*/
use nom;
use core::*;
use log::*;
use nom::IResult;
use smb::smb::*;
use smb::smb2_records::*;
@ -117,7 +118,7 @@ pub fn smb2_read_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
smb2_read_response_record_generic(state, r);
match parse_smb2_response_read(r.data) {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
if r.nt_status == SMB_NTSTATUS_BUFFER_OVERFLOW {
SCLogDebug!("SMBv2/READ: incomplete record, expecting a follow up");
// fall through
@ -236,7 +237,7 @@ pub fn smb2_write_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
tx.request_done = true;
}
match parse_smb2_request_write(r.data) {
IResult::Done(_, wr) => {
Ok((_, wr)) => {
/* update key-guid map */
let guid_key = SMBCommonHdr::from2(r, SMBHDR_TYPE_GUID);
state.ssn2vec_map.insert(guid_key, wr.guid.to_vec());
@ -334,7 +335,7 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
SMB2_COMMAND_SET_INFO => {
SCLogDebug!("SMB2_COMMAND_SET_INFO: {:?}", r);
let have_si_tx = match parse_smb2_request_setinfo(r.data) {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
SCLogDebug!("SMB2_COMMAND_SET_INFO: {:?}", rd);
if let Some(ref ren) = rd.rename {
@ -354,12 +355,13 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
false
}
},
IResult::Incomplete(_n) => {
Err(nom::Err::Incomplete(_n)) => {
SCLogDebug!("SMB2_COMMAND_SET_INFO: {:?}", _n);
events.push(SMBEvent::MalformedData);
false
},
IResult::Error(_e) => {
Err(nom::Err::Error(_e)) |
Err(nom::Err::Failure(_e)) => {
SCLogDebug!("SMB2_COMMAND_SET_INFO: {:?}", _e);
events.push(SMBEvent::MalformedData);
false
@ -378,7 +380,7 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
}
SMB2_COMMAND_NEGOTIATE_PROTOCOL => {
match parse_smb2_request_negotiate_protocol(r.data) {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
let mut dialects : Vec<Vec<u8>> = Vec::new();
for d in rd.dialects_vec {
SCLogDebug!("dialect {:x} => {}", d, &smb2_dialect_string(d));
@ -415,7 +417,7 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
},
SMB2_COMMAND_TREE_CONNECT => {
match parse_smb2_request_tree_connect(r.data) {
IResult::Done(_, tr) => {
Ok((_, tr)) => {
let name_key = SMBCommonHdr::from2(r, SMBHDR_TYPE_TREE);
let mut name_val = tr.share_name.to_vec();
name_val.retain(|&i|i != 0x00);
@ -436,7 +438,7 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
},
SMB2_COMMAND_READ => {
match parse_smb2_request_read(r.data) {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
SCLogDebug!("SMBv2 READ: GUID {:?} requesting {} bytes at offset {}",
rd.guid, rd.rd_len, rd.rd_offset);
@ -453,7 +455,7 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
},
SMB2_COMMAND_CREATE => {
match parse_smb2_request_create(r.data) {
IResult::Done(_, cr) => {
Ok((_, cr)) => {
let del = cr.create_options & 0x0000_1000 != 0;
let dir = cr.create_options & 0x0000_0001 != 0;
@ -481,7 +483,7 @@ pub fn smb2_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
},
SMB2_COMMAND_CLOSE => {
match parse_smb2_request_close(r.data) {
IResult::Done(_, cd) => {
Ok((_, cd)) => {
let found_ts = match state.get_file_tx_by_fuid(&cd.guid.to_vec(), STREAM_TOSERVER) {
Some((tx, files, flags)) => {
if !tx.request_done {
@ -557,7 +559,7 @@ pub fn smb2_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
if r.nt_status == SMB_NTSTATUS_SUCCESS {
match parse_smb2_response_write(r.data)
{
IResult::Done(_, wr) => {
Ok((_, wr)) => {
SCLogDebug!("SMBv2: Write response => {:?}", wr);
/* search key-guid map */
@ -621,7 +623,7 @@ pub fn smb2_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
SMB2_COMMAND_CREATE => {
if r.nt_status == SMB_NTSTATUS_SUCCESS {
match parse_smb2_response_create(r.data) {
IResult::Done(_, cr) => {
Ok((_, cr)) => {
SCLogDebug!("SMBv2: Create response => {:?}", cr);
let guid_key = SMBCommonHdr::from2(r, SMBHDR_TYPE_FILENAME);
@ -668,7 +670,7 @@ pub fn smb2_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
SMB2_COMMAND_TREE_CONNECT => {
if r.nt_status == SMB_NTSTATUS_SUCCESS {
match parse_smb2_response_tree_connect(r.data) {
IResult::Done(_, tr) => {
Ok((_, tr)) => {
let name_key = SMBCommonHdr::from2(r, SMBHDR_TYPE_TREE);
let mut share_name = Vec::new();
let is_pipe = tr.share_type == 2;
@ -720,7 +722,7 @@ pub fn smb2_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
parse_smb2_response_negotiate_protocol_error(r.data)
};
match res {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
SCLogDebug!("SERVER dialect => {}", &smb2_dialect_string(rd.dialect));
state.dialect = rd.dialect;

@ -15,7 +15,6 @@
* 02110-1301, USA.
*/
use nom::IResult;
use log::*;
use smb::smb::*;
use smb::smb2::*;
@ -61,7 +60,7 @@ pub fn smb2_ioctl_request_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
{
let hdr = SMBCommonHdr::from2(r, SMBHDR_TYPE_HEADER);
match parse_smb2_request_ioctl(r.data) {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
SCLogDebug!("IOCTL request data: {:?}", rd);
let is_dcerpc = rd.is_pipe && match state.get_service_for_guid(&rd.guid) {
(_, x) => x,
@ -88,7 +87,7 @@ pub fn smb2_ioctl_response_record<'b>(state: &mut SMBState, r: &Smb2Record<'b>)
{
let hdr = SMBCommonHdr::from2(r, SMBHDR_TYPE_HEADER);
match parse_smb2_response_ioctl(r.data) {
IResult::Done(_, rd) => {
Ok((_, rd)) => {
SCLogDebug!("IOCTL response data: {:?}", rd);
let is_dcerpc = rd.is_pipe && match state.get_service_for_guid(&rd.guid) {

@ -15,8 +15,6 @@
* 02110-1301, USA.
*/
use nom::{IResult};
use log::*;
use smb::smb2_records::*;
@ -28,7 +26,7 @@ pub fn smb2_session_setup_request(state: &mut SMBState, r: &Smb2Record)
{
SCLogDebug!("SMB2_COMMAND_SESSION_SETUP: r.data.len() {}", r.data.len());
match parse_smb2_request_session_setup(r.data) {
IResult::Done(_, setup) => {
Ok((_, setup)) => {
let hdr = SMBCommonHdr::from2(r, SMBHDR_TYPE_HEADER);
let tx = state.new_sessionsetup_tx(hdr);
tx.vercmd.set_smb2_cmd(r.command);

@ -15,7 +15,8 @@
* 02110-1301, USA.
*/
use nom::{IResult, ErrorKind};
use nom;
use nom::{ErrorKind, IResult};
use log::*;
/// parse a UTF16 string that is null terminated. Normally by 2 null
@ -30,18 +31,18 @@ pub fn smb_get_unicode_string(blob: &[u8]) -> IResult<&[u8], Vec<u8>>
if c.len() == 1 && c[0] == 0 {
let rem = &c[1..];
SCLogDebug!("get_unicode_string: name {:?}", name);
return IResult::Done(rem, name)
return Ok((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)
return Ok((rem, name))
}
name.push(c[0]);
c = &c[2..];
}
IResult::Error(error_position!(blob,ErrorKind::Custom(130)))
Err(nom::Err::Error(error_position!(blob,ErrorKind::Custom(130))))
}
/// parse an ASCII string that is null terminated

@ -132,7 +132,7 @@ pub extern "C" fn rs_tftp_request(state: &mut TFTPState,
len: libc::uint32_t) -> i64 {
let buf = unsafe{std::slice::from_raw_parts(input, len as usize)};
return match tftp_request(buf) {
nom::IResult::Done(_, rqst) => {
Ok((_, rqst)) => {
state.transactions.push(rqst);
1
},

Loading…
Cancel
Save