nmrs

repository·master·Indexed 43 days ago

https://github.com/freedesktop-rs/nmrs

An async-first Rust library providing a high-level, safe API for managing NetworkManager on Linux via D-Bus. Version 3.5.2 provides bindings for managing network devices, radios, WireGuard VPNs, and WPA-Enterprise (EAP) networks, and includes a SecretAgent for handling credentials.

Tokens
90.9K
Snippets
258
Records
360
Agent score
48%

What's inside nmrs

  1. What is nmrs?

    master

    nmrs is a high-level, asynchronous Rust library designed for managing network connections on Linux via NetworkManager over D-Bus. It provides type-safe abstractions for several networking tasks:

    • WiFi Management: Scanning, connecting, and managing wireless networks.
    • VPN Support: Support for WireGuard and OpenVPN.
    • Ethernet Control: Managing wired network connections.
    • Bluetooth: Connecting to Bluetooth network devices.
    • Real-Time Monitoring: Event-driven updates via D-Bus signals (rather than polling).
    • Async/Await: Built for modern async Rust and is runtime agnostic (compatible with Tokio, async-std, smol, etc.).
  2. Runtime compatibility and requirements

    master

    Async Runtimes

    nmrs is runtime-agnostic and works with any runtime supporting standard Rust async/await (e.g., Tokio, async-std, smol). It uses zbus for D-Bus communication, which manages its own background thread for message processing.

    System Requirements

    • Linux with NetworkManager (1.0+)
    • D-Bus system bus access
    • Appropriate permissions for network management

    Logging

    Enable logging via the log crate. Set RUST_LOG=nmrs=debug for detailed logs.

  3. Identify device types and capabilities

    master

    Use DeviceType to determine if a device is Wi-Fi, Ethernet, Bluetooth, etc. nmrs normalizes veth interfaces to DeviceType::Ethernet.

    Type Helper Methods

    On a Device instance, you can use these helpers:

    • is_wireless()
    • is_wired()
    • is_bluetooth()
    • is_loopback()
    • is_vlan()

    Capability Queries

    On a DeviceType instance (device.device_type), you can query capabilities:

    • supports_scanning(): Returns true for Wifi and WifiP2P.
    • requires_specific_object(): Returns true for Wifi and WifiP2P.
    • has_global_enabled_state(): Returns true for Wifi.
    • connection_type_str(): Returns the NM connection type string (e.g., 802-11-wireless).
    • to_code(): Returns the raw NM type code.
    let dt = &device.device_type;
    
    dt.supports_scanning();         // true for Wifi, WifiP2P
    dt.requires_specific_object();  // true for Wifi, WifiP2P
    dt.has_global_enabled_state();  // true for Wifi
    dt.connection_type_str();       // "802-11-wireless", "802-3-ethernet", etc.
    dt.to_code();                   // raw NM type code (2 for Wifi, 1 for Ethernet)
  4. Advanced configuration and architecture

    master

    For power users and library integrators, nmrs provides documentation on:

    • Async Support: Integrating with various async runtimes.
    • D-Bus Architecture: Understanding how nmrs communicates with the system bus.
    • Customization: Configuring connection options and custom timeouts.
    • Observability: Logging and debugging network interactions.
  5. Hardware and feature requirements

    master

    Specific features of nmrs require corresponding hardware and software support:

    • WiFi: Requires a WiFi adapter supported by NetworkManager and recognized by the Linux kernel. Use nmcli device status to verify.
    • Ethernet: Requires a Network Interface Card (NIC) recognized by the Linux kernel.
    • Bluetooth: Requires a Bluetooth adapter and the BlueZ stack installed and running.
    • VPN (WireGuard): Requires either the WireGuard kernel module or a userspace implementation (automatically supported by NetworkManager 1.16+).
    # Check WireGuard kernel module support
    modprobe wireguard
    lsmod | grep wireguard
    
    # Check WiFi device status
    nmcli device status
  6. Manage Secret Agent registration for GUI apps

    master

    For applet-style GUI applications, you should register a single secret agent during startup and maintain the returned SecretAgentHandle for the entire lifetime of the application.

    • Persistence: Keep the handle alive to receive credential prompts.
    • Recovery: If NetworkManager restarts, call SecretAgentHandle::reregister() once it becomes available again.
    • Termination: Dropping or unregistering the handle will stop credential prompts from reaching your application.
  7. Configure autoconnect priority

    master

    The autoconnect_priority field (type Option<i32>) determines which connection NetworkManager prefers when multiple saved connections are available.

    • Higher values are preferred (e.g., 100 takes precedence over 10).
    • Positive values (> 0): Use for preferred connections.
    • Zero (0): The default priority.
    • Negative values (< 0): Use for fallback connections (e.g., -50 is tried after -10).

    If priorities are equal, NetworkManager uses its own internal heuristics like signal strength or most recent use.

  8. What operations are affected by timeouts

    master

    Timeouts in nmrs apply to all operations that wait for NetworkManager state transitions.

    • Connection Timeouts (connection_timeout) affect:
      • connect() (Wi-Fi)
      • connect_wired() (Ethernet)
      • connect_bluetooth() (Bluetooth)
      • connect_vpn() (VPN)
    • Disconnection Timeouts (disconnect_timeout) affect:
      • disconnect() (The waiting period after requesting a disconnection)
  9. Handle non-exhaustive types in nmrs

    master

    All enums and structs in nmrs are marked as #[non_exhaustive]. To ensure your code remains compatible with future updates to the library, follow these two rules:

    1. Always include a wildcard arm (_) in match expressions when matching against enums.
    2. Do not construct structs directly. Always use the provided constructors or builder methods.
  10. How hidden network connections work in nmrs

    master

    When calling connect() with an SSID, nmrs follows this logic:

    1. Check Saved Profiles: It first checks if a saved connection profile already exists for that SSID.
    2. Reuse or Rebuild:
      • If a profile exists, WifiSecurity::Open or an empty PSK reuses it.
      • A non-empty PSK or EAP configuration builds a fresh profile with the provided credentials.
    3. Scan Visible APs: If no saved profile exists, it searches the visible access point list.
    4. Directed Probe: If the network is not visible (hidden), NetworkManager creates a connection profile with the hidden flag set and performs a directed probe request for that specific SSID.

    Note: The initial connection may take longer than visible networks due to the directed scan requirement.

  11. Understand ConnectionError categories

    master

    Errors in nmrs can be categorized to help determine if an issue is user-fixable, a configuration error, or a system-level failure:

    User-Facing Errors

    Indicate issues the user can resolve directly:

    • NotFound: Move closer to the network or check SSID spelling.
    • AuthFailed: Check password or credentials.
    • MissingPassword: Provide a non-empty password or ensure a saved profile exists.
    • Timeout: Retry or increase timeout.
    • DhcpFailed: Check network infrastructure.
    • NoWifiDevice: Check that a Wi-Fi adapter is installed.
    • NoWiredDevice: Check that an Ethernet adapter exists.

    Validation Errors

    Indicate invalid input provided to the nmrs API:

    • InvalidPrivateKey: Check WireGuard key format (base64, ~44 chars).
    • InvalidPublicKey: Check peer public key format.
    • InvalidAddress: Use CIDR notation (e.g., 10.0.0.2/24).
    • InvalidGateway: Use host:port format.
    • InvalidPeers: Add at least one peer with allowed IPs.

    System Errors

    Indicate infrastructure or environment issues:

    • Dbus / DbusOperation: Check if NetworkManager is running and D-Bus is accessible. Use the context field in DbusOperation to identify the failed operation.
    • SupplicantConfigFailed: Check wpa_supplicant configuration.
    • SupplicantTimeout: Check RADIUS server connectivity.
    • WifiNotReady: Wi-Fi device is still initializing.
    • Stuck: NetworkManager is in an unexpected state.
    • DeviceFailed: Check the provided StateReason for details.
    • ActivationFailed: Check the provided ConnectionStateReason for details.
    • BluezUnavailable: BlueZ is not running or no Bluetooth adapters are present.
    • BluetoothToggleFailed: Adapter exists but failed to power on/off.
    • MalformedSavedConnection: Saved profile is missing required keys; consider deleting it.
    • AgentRegistration: Secret agent failed to register; check context.
  12. EAP Methods and Phase 2 (Inner Authentication)

    master

    WPA-EAP authentication consists of an outer method that establishes a TLS tunnel and an inner method (Phase 2) that performs the actual credential exchange.

    Outer EAP Methods

    • EapMethod::Peap: Protected EAP. Tunnels inner auth in TLS. Common for corporate networks.
    • EapMethod::Ttls: Tunneled TLS. Flexible inner auth. Common for universities and ISPs.

    Phase 2 (Inner Authentication) Methods

    • Phase2::Mschapv2: MS-CHAPv2 (challenge-response). Typically paired with EapMethod::Peap.
    • Phase2::Pap: PAP (plaintext). Protected by the TLS tunnel. Typically paired with EapMethod::Ttls.