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
use crate::smb2::Smb2NegResp;
use crate::smb2::Smb2NegReq;
use crate::smb2::Smb2SessionSetupResp;
use crate::smb2::Smb2SessionSetupReq;
use crate::SmbNegResp;
use crate::Error;
use crate::smb1::Smb1NegReq;
use crate::SmbMsg;
use crate::smb2::Smb2Msg;
use crate::Result;
use std::io;
use std::io::{Read, Write};
use std::net::TcpStream;

pub const SMB_TCP_PORT: u16 = 445;

/// Sends a raw SMB request over TCP and receives the response.
pub fn send_recv(
    stream: &mut TcpStream,
    raw_req: &[u8],
) -> io::Result<Vec<u8>> {
    let req_len = (raw_req.len() as u32) & 0x00ffffff;

    let mut bytes = req_len.to_be_bytes().to_vec();
    bytes.extend(raw_req);
    stream.write(&bytes)?;

    let mut resp_len_bytes = [0 as u8; 4];
    stream.read_exact(&mut resp_len_bytes)?;
    let resp_len = u32::from_be_bytes(resp_len_bytes) & 0x00ffffff;

    let mut raw_resp: Vec<u8> = vec![0; resp_len as usize];
    stream.read_exact(&mut raw_resp)?;

    return Ok(raw_resp);
}

/// Sends a SMB packet and receives the response packet.
pub fn send_recv_msg(
    stream: &mut TcpStream,
    req_packet: &SmbMsg,
) -> Result<SmbMsg> {
    let raw_resp = send_recv(stream, &req_packet.build())?;
    return SmbMsg::parse(&raw_resp);
}

pub fn send_recv_negotiate_msg(
    stream: &mut TcpStream,
    req_neg: &Smb1NegReq,
) -> Result<SmbNegResp> {
    let raw_resp = send_recv(stream, &req_neg.build())?;

    let resp_msg = SmbMsg::parse(&raw_resp)?;

    match resp_msg {
        SmbMsg::V1(_) => {
            todo!("SMB1 Negotiation response")
        },
        SmbMsg::V2(msg2) => {
            match msg2 {
                Smb2Msg::NegResp(msg) => Ok(SmbNegResp::V2(msg)),
                _ => Err(Error::Smb2UnexpectedResponse(msg2)),
            }
        }
    }
}


/// Sends a SMB2 request and receives the response.
pub fn send_recv_msg2(
    stream: &mut TcpStream,
    req_packet: &Smb2Msg,
) -> Result<Smb2Msg> {
    let raw_resp = send_recv(stream, &req_packet.build())?;
    return Smb2Msg::parse(&raw_resp);
}

pub fn send_recv_negotiate2(
    stream: &mut TcpStream,
    req: &Smb2NegReq,
) -> Result<Smb2NegResp> {
    let raw_resp = send_recv(stream, &req.build())?;

    let resp_msg =  Smb2Msg::parse(&raw_resp)?;
    match resp_msg {
        Smb2Msg::NegResp(msg) => Ok(msg),
        _ => Err(Error::Smb2UnexpectedResponse(resp_msg))
    }
}


pub fn send_recv_session_setup2(
    stream: &mut TcpStream,
    req: &Smb2SessionSetupReq,
) -> Result<Smb2SessionSetupResp> {
    let raw_resp = send_recv(stream, &req.build())?;

    let resp_msg =  Smb2Msg::parse(&raw_resp)?;
    match resp_msg {
        Smb2Msg::SessionSetupResp(msg) => Ok(msg),
        _ => Err(Error::Smb2UnexpectedResponse(resp_msg))
    }
}