winrm_rs/lib.rs
1//! Async `WinRM` (WS-Management) client for Rust.
2//!
3//! Provides remote command execution on Windows hosts via the `WinRM` protocol
4//! with `NTLMv2`, Basic, Kerberos, and Certificate authentication support.
5//!
6//! # Architecture
7//!
8//! The crate is structured in three layers:
9//!
10//! - **[`WinrmClient`]** -- high-level async API that manages shell lifecycle,
11//! command execution, and output polling. Callers interact exclusively with
12//! this type and its associated config/credential structs.
13//!
14//! - **`soap`** (internal) -- builds WS-Management XML envelopes for Create,
15//! Execute, Receive, Signal, and Delete operations, and parses the
16//! corresponding responses. Envelope construction uses raw `format!` strings
17//! rather than a full XML library to keep dependencies minimal.
18//!
19//! - **`ntlm`** (internal) -- implements the `NTLMv2` challenge/response handshake
20//! per MS-NLMP. Only `NTLMv2` is supported; `NTLMv1` is intentionally excluded.
21//!
22//! HTTP transport is provided by `reqwest` with `rustls-tls`.
23//!
24//! # Authentication methods
25//!
26//! | Method | Enum variant | Notes |
27//! |--------|-------------|-------|
28//! | HTTP Basic | [`AuthMethod::Basic`] | Credentials sent base64-encoded per request. Use only over HTTPS. |
29//! | `NTLMv2` | [`AuthMethod::Ntlm`] | Three-step handshake (negotiate / challenge / authenticate). Default. |
30//! | Kerberos | [`AuthMethod::Kerberos`] | SPNEGO Negotiate via system Kerberos. Requires `kerberos` feature + `kinit`. |
31//! | Certificate | [`AuthMethod::Certificate`] | TLS client certificate. Set `client_cert_pem` and `client_key_pem` on config. |
32//!
33//! # Error handling
34//!
35//! All fallible operations return `Result<T, WinrmError>`. The top-level
36//! [`WinrmError`] enum wraps transport errors ([`reqwest::Error`]), SOAP faults
37//! ([`SoapError`]), NTLM failures ([`NtlmError`]), and authentication
38//! rejections. Errors are designed for programmatic matching via `match` and
39//! for human-readable display via their [`Display`](std::fmt::Display) impls.
40//!
41//! # Shell reuse
42//!
43//! For running multiple commands on the same host, use [`WinrmClient::open_shell`]
44//! to create a [`Shell`] that persists across commands, avoiding the overhead of
45//! shell creation and deletion per command.
46//!
47//! # Cargo features
48//!
49//! - **`kerberos`** -- Enables Kerberos authentication via `cross-krb5`.
50//! - **`credssp`** -- *Experimental.* Enables `CredSSP` authentication for
51//! double-hop delegation. Pulls in `openssl` as a C dependency
52//! (required because Microsoft's `CredSSP` server has proven incompatible
53//! with `rustls` in-memory TLS — see `src/auth/credssp.rs`).
54//! The handshake is not yet fully validated end-to-end; treat as
55//! preview-quality and do not use in production.
56//!
57//! # Re-exports
58//!
59//! A few third-party types appear in this crate's public API and are
60//! re-exported for convenience:
61//!
62//! - [`SecretString`] / [`ExposeSecret`] from the `secrecy` crate —
63//! used for the `password` field of [`WinrmCredentials`].
64//! - [`CancellationToken`] from `tokio_util` — used as a parameter to
65//! the `*_with_cancel` methods of [`WinrmClient`] so callers can
66//! cooperatively cancel in-flight operations.
67//!
68//! # Example
69//! ```no_run
70//! use winrm_rs::{WinrmClient, WinrmConfig, WinrmCredentials};
71//!
72//! # async fn example() -> Result<(), winrm_rs::WinrmError> {
73//! let client = WinrmClient::new(
74//! WinrmConfig::default(),
75//! WinrmCredentials::new("administrator", "password", ""),
76//! )?;
77//!
78//! let output = client.run_powershell("win-server", "Get-Process | ConvertTo-Json").await?;
79//! println!("stdout: {}", String::from_utf8_lossy(&output.stdout));
80//! # Ok(())
81//! # }
82//! ```
83
84#[cfg(feature = "credssp")]
85mod asn1;
86mod auth;
87mod builder;
88mod client;
89mod command;
90mod config;
91mod error;
92mod ntlm;
93mod shell;
94mod soap;
95mod tls;
96mod transfer;
97mod transport;
98
99pub use builder::{NeedsCredentials, Ready, WinrmClientBuilder};
100pub use client::WinrmClient;
101pub use command::{CommandOutput, encode_powershell_command};
102pub use config::{AuthMethod, EncryptionMode, WinrmConfig, WinrmCredentials};
103pub use error::{CredSspError, NtlmError, SoapError, WinrmError};
104pub use ntlm::NtlmSession;
105pub use secrecy::{ExposeSecret, SecretString};
106pub use shell::Shell;
107pub use soap::namespaces::RESOURCE_URI_PSRP;
108pub use tokio_util::sync::CancellationToken;
109// Re-export soap types that are part of the public API
110pub use soap::ReceiveOutput;
111
112// Internal re-exports for fuzz targets only. These are NOT part of the
113// public API and may be removed or changed at any time without a SemVer
114// bump. Enabled via the `__internal` feature, consumed only by `fuzz/`.
115#[cfg(feature = "__internal")]
116#[doc(hidden)]
117pub use ntlm::parse_challenge;
118#[cfg(feature = "__internal")]
119#[doc(hidden)]
120pub use soap::{check_soap_fault, parse_command_id, parse_receive_output, parse_shell_id};