Some(SMBTransactionTypeData::IOCTL(ref x)) => {
js.set_string("function", &fsctl_func_to_string(x.func));
},
+ Some(SMBTransactionTypeData::SETFILEPATHINFO(ref x)) => {
+ let mut name_raw = x.filename.to_vec();
+ name_raw.retain(|&i|i != 0x00);
+ if name_raw.len() > 0 {
+ let name = String::from_utf8_lossy(&name_raw);
+ js.set_string("filename", &name);
+ } else {
+ // name suggestion from Bro
+ js.set_string("filename", "<share_root>");
+ }
+ if x.delete_on_close {
+ js.set_string("access", "delete on close");
+ } else {
+ js.set_string("access", "normal");
+ }
+
+ match x.subcmd {
+ 8 => {
+ js.set_string("subcmd", "SET_FILE_INFO");
+ },
+ 6 => {
+ js.set_string("subcmd", "SET_PATH_INFO");
+ },
+ _ => { },
+ }
+
+ match x.loi {
+ 1013 => { // Set Disposition Information
+ js.set_string("level_of_interest", "Set Disposition Information");
+ },
+ _ => { },
+ }
+
+ let gs = fuid_to_string(&x.fid);
+ js.set_string("fuid", &gs);
+ },
_ => { },
}
return js;
SESSIONSETUP(SMBTransactionSessionSetup),
IOCTL(SMBTransactionIoctl),
RENAME(SMBTransactionRename),
+ SETFILEPATHINFO(SMBTransactionSetFilePathInfo),
+}
+
+// Used for Trans2 SET_PATH_INFO and SET_FILE_INFO
+#[derive(Debug)]
+pub struct SMBTransactionSetFilePathInfo {
+ pub subcmd: u16,
+ pub loi: u16,
+ pub delete_on_close: bool,
+ pub filename: Vec<u8>,
+ pub fid: Vec<u8>,
+}
+
+impl SMBTransactionSetFilePathInfo {
+ pub fn new(filename: Vec<u8>, fid: Vec<u8>, subcmd: u16, loi: u16, delete_on_close: bool)
+ -> SMBTransactionSetFilePathInfo
+ {
+ return SMBTransactionSetFilePathInfo {
+ filename: filename, fid: fid,
+ subcmd: subcmd,
+ loi: loi,
+ delete_on_close: delete_on_close,
+ }
+ }
+}
+
+impl SMBState {
+ pub fn new_setfileinfo_tx(&mut self, filename: Vec<u8>, fid: Vec<u8>,
+ subcmd: u16, loi: u16, delete_on_close: bool)
+ -> (&mut SMBTransaction)
+ {
+ let mut tx = self.new_tx();
+
+ tx.type_data = Some(SMBTransactionTypeData::SETFILEPATHINFO(
+ SMBTransactionSetFilePathInfo::new(
+ filename, fid, subcmd, loi, delete_on_close)));
+ tx.request_done = true;
+ tx.response_done = self.tc_trunc; // no response expected if tc is truncated
+
+ SCLogDebug!("SMB: TX SETFILEPATHINFO created: ID {}", tx.id);
+ self.transactions.push(tx);
+ let tx_ref = self.transactions.last_mut();
+ return tx_ref.unwrap();
+ }
+
+ pub fn new_setpathinfo_tx(&mut self, filename: Vec<u8>,
+ subcmd: u16, loi: u16, delete_on_close: bool)
+ -> (&mut SMBTransaction)
+ {
+ let mut tx = self.new_tx();
+
+ let fid : Vec<u8> = Vec::new();
+ tx.type_data = Some(SMBTransactionTypeData::SETFILEPATHINFO(
+ SMBTransactionSetFilePathInfo::new(filename, fid,
+ subcmd, loi, delete_on_close)));
+ tx.request_done = true;
+ tx.response_done = self.tc_trunc; // no response expected if tc is truncated
+
+ SCLogDebug!("SMB: TX SETFILEPATHINFO created: ID {}", tx.id);
+ self.transactions.push(tx);
+ let tx_ref = self.transactions.last_mut();
+ return tx_ref.unwrap();
+ }
}
#[derive(Debug)]
IResult::Done(_, pd) => {
SCLogDebug!("TRANS2 SET_PATH_INFO PARAMS DONE {:?}", pd);
- if pd.loi == 1010 {
+ if pd.loi == 1013 { // set disposition info
+ match parse_trans2_request_data_set_file_info_disposition(rd.data_blob) {
+ IResult::Done(_, disp) => {
+ SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION DONE {:?}", disp);
+ let tx_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
+
+ let tx = state.new_setpathinfo_tx(pd.oldname,
+ rd.subcmd, pd.loi, disp.delete);
+ tx.hdr = tx_hdr;
+ tx.request_done = true;
+ tx.vercmd.set_smb1_cmd(SMB1_COMMAND_TRANS2);
+ true
+
+ },
+ IResult::Incomplete(n) => {
+ SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION INCOMPLETE {:?}", n);
+ events.push(SMBEvent::MalformedData);
+ false
+ },
+ IResult::Error(e) => {
+ SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION ERROR {:?}", e);
+ events.push(SMBEvent::MalformedData);
+ false
+ },
+ }
+ } else if pd.loi == 1010 {
match parse_trans2_request_data_set_path_info_rename(rd.data_blob) {
IResult::Done(_, ren) => {
SCLogDebug!("TRANS2 SET_PATH_INFO DATA RENAME DONE {:?}", ren);
IResult::Done(_, pd) => {
SCLogDebug!("TRANS2 SET_FILE_INFO PARAMS DONE {:?}", pd);
- if pd.loi == 1010 {
+ if pd.loi == 1013 { // set disposition info
+ match parse_trans2_request_data_set_file_info_disposition(rd.data_blob) {
+ IResult::Done(_, disp) => {
+ SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION DONE {:?}", disp);
+ let tx_hdr = SMBCommonHdr::from1(r, SMBHDR_TYPE_GENERICTX);
+
+ let mut frankenfid = pd.fid.to_vec();
+ frankenfid.extend_from_slice(&u32_as_bytes(r.ssn_id));
+
+ let filename = match state.guid2name_map.get(&frankenfid) {
+ Some(n) => n.to_vec(),
+ None => b"<unknown>".to_vec(),
+ };
+ let tx = state.new_setfileinfo_tx(filename, pd.fid.to_vec(),
+ rd.subcmd, pd.loi, disp.delete);
+ tx.hdr = tx_hdr;
+ tx.request_done = true;
+ tx.vercmd.set_smb1_cmd(SMB1_COMMAND_TRANS2);
+ true
+
+ },
+ IResult::Incomplete(n) => {
+ SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION INCOMPLETE {:?}", n);
+ events.push(SMBEvent::MalformedData);
+ false
+ },
+ IResult::Error(e) => {
+ SCLogDebug!("TRANS2 SET_FILE_INFO DATA DISPOSITION ERROR {:?}", e);
+ events.push(SMBEvent::MalformedData);
+ false
+ },
+ }
+ } else if pd.loi == 1010 {
match parse_trans2_request_data_set_file_info_rename(rd.data_blob) {
IResult::Done(_, ren) => {
SCLogDebug!("TRANS2 SET_FILE_INFO DATA RENAME DONE {:?}", ren);
}))
);
+#[derive(Debug,PartialEq)]
+pub struct Trans2RecordParamSetFileInfoDisposition<> {
+ pub delete: bool,
+}
+
+named!(pub parse_trans2_request_data_set_file_info_disposition<Trans2RecordParamSetFileInfoDisposition>,
+ do_parse!(
+ delete: le_u8
+ >> _reserved: take!(3)
+ >> (Trans2RecordParamSetFileInfoDisposition {
+ delete: delete & 1 == 1,
+ })
+));
+
#[derive(Debug,PartialEq)]
pub struct Trans2RecordParamSetFileInfo<'a> {
pub fid: &'a[u8],