Skip to content

AvivNaaman/smb-rs

Repository files navigation

smb-rs: The SMB2 Client in Rust

Build Crates.io docs.rs

This project is the first rust implementation of SMB2 & 3 client -- the protocol that powers Windows file sharing and remote services. The project is designed to be used as a crate, but also includes a CLI tool for basic operations.

While most current implementations are mostly bindings to C libraries (such as libsmb2, samba, or windows' own libraries), this project is a full implementation in Rust, with no dependencies on C libraries!

Getting started

Running the project's CLI is as simple as executing:

cargo run -- --help

Check out the info and the copy sub-commands for more information.

For advanced usage, and crate usage, see the Advanced Usage section.

Features

  • ✅ SMB 2.X & 3.X support.
  • ✅ Async (tokio), Multi-threaded, or Single-threaded client.
  • ✅ Compression & Encryption support.
  • ✅ Transport using SMB over TCP (445), over NetBIOS (139), and over QUIC (443).
  • ✅ NTLM & Kerberos authentication (using the sspi crate).
  • ✅ Cross-platform (Windows, Linux, MacOS).

You are welcome to see the project's roadmap in the GitHub Project.

Using the crate

Check out the Client struct, exported from the smb crate, to initiate a connection to an SMB server:

use smb::{Client, ClientConfig, UncPath, FileCreateArgs, FileAccessMask, ReadAt};
use std::str::FromStr;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    // instantiate the client
    let client = Client::new(ClientConfig::default());
    
    // Connect to a share
    let target_path = UncPath::from_str(r"\\server\share").unwrap();
    client.share_connect(&target_path, "username", "password".to_string()).await?;
    
    // And open a file on the server
    let file_to_open = target_path.with_path("file.txt");
    let file_open_args = FileCreateArgs::make_open_existing(FileAccessMask::new().with_generic_read(true));
    let resource = client.create_file(&file_to_open, &file_open_args).await?;

    // now, you can do a bunch of operations against `file`, and close it at the end.
    let file = resource.unwrap_file();
    let mut data: [u8; 1024] = [0; 1024];
    file.read_at(&mut data, 0).await?;

    // and close
    file.close().await?;
    Ok(())
}

Check out the docs.rs for more information regarding usage.

Development

To set up a development environment, you may use any supported rust version.

  • It is highly recommended to use rust nightly, and install pre-commit hooks (using pip install pre-commit && pre-commit install)
  • Before committing your changes, run cargo fmt to format the code, and cargo clippy to check for linting issues.
  • Run crate tests once you are ready to commit. Read tests' README.md before proceeding!