1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133
use crate::smb2::Smb2SessionSetupResp; use crate::smb2::header::commands::{SMB2_NEGOTIATE_PROTOCOL, SMB2_SESSION_SETUP}; use crate::smb2::Smb2Header; use crate::smb2::Smb2NegReq; use crate::smb2::Smb2NegResp; use crate::smb2::Smb2SessionSetupReq; use crate::Error; use crate::Result; #[derive(Clone, Debug, PartialEq)] pub enum Smb2Msg { NegReq(Smb2NegReq), NegResp(Smb2NegResp), SessionSetupReq(Smb2SessionSetupReq), SessionSetupResp(Smb2SessionSetupResp), } impl Smb2Msg { pub fn build(&self) -> Vec<u8> { match self { Self::NegReq(b) => b.build(), Self::NegResp(_) => todo!(), Self::SessionSetupReq(b) => b.build(), Self::SessionSetupResp(_) => todo!(), } } pub fn parse(raw: &[u8]) -> Result<Self> { let (_, header) = Smb2Header::parse(raw)?; return Ok(match header.command { SMB2_NEGOTIATE_PROTOCOL => { if header.is_response() { Self::NegResp(Smb2NegResp::parse(raw)?) } else { Self::NegReq(Smb2NegReq::parse(raw)?) } } SMB2_SESSION_SETUP => { if header.is_response() { Self::SessionSetupResp(Smb2SessionSetupResp::parse(raw)?) } else { todo!() } } _ => return Err(Error::Smb2UnknownCommand(header.command)), }); } } #[derive(Clone, Debug, PartialEq)] pub struct Smb2Packet { pub header: Smb2Header, pub body: Smb2Body, } impl Smb2Packet { pub fn new(header: Smb2Header, body: Smb2Body) -> Self { return Self { header, body }; } pub fn new_neg_req(header: Smb2Header, body: Smb2NegReq) -> Self { return Self::new(header, Smb2Body::NegReq(body)); } pub fn new_session_setup_req( header: Smb2Header, body: Smb2SessionSetupReq, ) -> Self { return Self::new(header, Smb2Body::SessionSetupReq(body)); } pub fn command(&self) -> u16 { return self.header.command; } pub fn build(&self) -> Vec<u8> { let mut raw = self.header.build(); raw.extend(self.body.build()); return raw; } pub fn parse(raw: &[u8]) -> Result<Self> { let (raw, header) = Smb2Header::parse(raw)?; let body = match header.command { SMB2_NEGOTIATE_PROTOCOL => { if header.is_response() { Smb2Body::NegResp(Smb2NegResp::parse(raw)?) } else { Smb2Body::NegReq(Smb2NegReq::parse(raw)?) } } SMB2_SESSION_SETUP => { if header.is_response() { Smb2Body::SessionSetupResp(Smb2SessionSetupResp::parse(raw)?) } else { todo!() } } _ => return Err(Error::Smb2UnknownCommand(header.command)), }; return Ok(Self { header, body }); } } #[derive(Clone, Debug, PartialEq)] pub enum Smb2Body { NegReq(Smb2NegReq), NegResp(Smb2NegResp), SessionSetupReq(Smb2SessionSetupReq), SessionSetupResp(Smb2SessionSetupResp), } impl Smb2Body { pub fn build(&self) -> Vec<u8> { match self { Self::NegReq(b) => b.build(), Self::NegResp(_) => todo!(), Self::SessionSetupReq(b) => b.build(), Self::SessionSetupResp(_) => todo!(), } } } impl Default for Smb2Body { fn default() -> Self { return Self::NegReq(Smb2NegReq::default()); } }