product-os-proxy 0.0.19

Product OS : Proxy builds on the work of hudsucker, taking it to the next level with a man-in-the-middle proxy server that can tunnel traffic through a VPN utilising Product OS : VPN.
//! Basic proxy example
//!
//! This example demonstrates how to create a simple MITM proxy server.
//!
//! To run: cargo run --example basic_proxy --features="default"

use product_os_proxy::{
    NetworkProxy, NetworkProxyCertificateAuthority, NetworkProxyCertificateAuthorityManaged,
    NetworkProxyCompression, NetworkProxyNetwork, Proxy,
};

#[tokio::main]
async fn main() -> Result<(), product_os_utilities::ProductOSError> {
    // Initialize tracing
    tracing_subscriber::fmt()
        .with_max_level(tracing::Level::INFO)
        .try_init()
        .ok();

    tracing::info!("Starting basic proxy example");

    // Configure the proxy
    let config = NetworkProxy {
        enable: true,
        network: NetworkProxyNetwork {
            secure: true,
            host: "127.0.0.1".to_string(),
            port: 8888, // Listen on port 8888
            listen_all_interfaces: false,
            allow_insecure: false,
            insecure_port: 8889,
        },
        certificate_authority: Some(NetworkProxyCertificateAuthority {
            managed: Some(NetworkProxyCertificateAuthorityManaged {
                enabled: true,
                serve_cert_endpoint: true,
                ..Default::default()
            }),
            ..Default::default()
        }),
        compression: NetworkProxyCompression::None,
        custom_requester: false,
        enable_tunnel: false,
        ..Default::default()
    };

    // Create and start the proxy
    let mut proxy = Proxy::new(config);

    let managed = Proxy::load_or_create_managed_certificate_authority(None)?;
    tracing::info!(
        "Managed CA path: {}",
        managed.cert_path.unwrap_or_default().display()
    );
    tracing::info!("Proxy starting on http://127.0.0.1:{}", proxy.get_port());
    tracing::info!("Configure your browser to use this proxy");
    tracing::info!("Press Ctrl+C to stop");

    // Start the proxy (runs in background after startup succeeds)
    proxy.run().await?;

    // Keep the main task alive
    tokio::signal::ctrl_c()
        .await
        .map_err(|e| product_os_utilities::ProductOSError::GenericError(e.to_string()))?;

    tracing::info!("Shutting down proxy...");

    // Stop the proxy gracefully
    if let Err(e) = proxy.halt().await {
        tracing::error!("Error stopping proxy: {:?}", e);
    }

    tracing::info!("Proxy stopped");
    Ok(())
}