takproto 0.4.2

Rust library for TAK (Team Awareness Kit) Protocol - send CoT messages to TAK servers with mTLS support
Documentation
//! Production solution: Trust the server's self-signed certificate
//!
//! This is the recommended approach instead of danger_accept_invalid_certs.
//! It maintains proper certificate validation while trusting specific self-signed certs.
//!
//! First, extract the server's certificate:
//! ```bash
//! openssl s_client -connect SERVER:PORT -showcerts < /dev/null 2>/dev/null | \
//!     openssl x509 -outform PEM > server_cert.pem
//! ```
//!
//! Then run:
//! ```bash
//! cargo run --example trust_server_cert --features openssl-p12 -- \
//!     <server:port> <server_name> <p12_file> <password> <server_cert.pem>
//! ```

use takproto::{TakClient, TlsConfigBuilder, CotEventBuilder};
use takproto::helpers::contact;

#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
    let args: Vec<String> = std::env::args().collect();
    if args.len() < 6 {
        eprintln!("Usage: {} <server:port> <server_name> <p12_file> <password> <server_cert.pem>", args[0]);
        eprintln!("\nFirst extract the server's certificate:");
        eprintln!("  openssl s_client -connect SERVER:PORT -showcerts < /dev/null 2>/dev/null | \\");
        eprintln!("      openssl x509 -outform PEM > server_cert.pem");
        std::process::exit(1);
    }

    let server_addr = &args[1];
    let server_name = &args[2];
    let p12_file = &args[3];
    let password = &args[4];
    let server_cert = &args[5];

    println!("===================================================");
    println!("Production Solution: Trust Specific Server Cert");
    println!("===================================================");
    println!("Server: {}", server_addr);
    println!("P12: {}", p12_file);
    println!("Server Cert: {}", server_cert);
    println!("\n✓ Maintains full certificate validation");
    println!("✓ Only trusts the specific server cert you provide\n");

    println!("Loading P12 and trusting server certificate...");
    let tls_config = TlsConfigBuilder::new()
        .with_p12(p12_file, password)?
        .with_additional_root_cert(server_cert)?  // Trust the server's cert
        .build()?;
    println!("✓ TLS configuration created\n");

    println!("Connecting to {}...", server_addr);
    let mut client = TakClient::connect_tls(server_addr, server_name, tls_config).await?;
    println!("✓ Connected with proper certificate validation!\n");

    println!("Negotiating protocol...");
    client.negotiate_protocol(1, 60).await?;
    println!("✓ Protocol negotiated (protobuf mode)\n");

    println!("Sending test event...");
    let event = CotEventBuilder::new()
        .uid("TRUSTED-CERT-TEST")
        .cot_type("a-f-G-U-C")
        .lat_lon(39.377445, -76.832160)
        .hae(10.0)
        .ce_le(9.9, 9.9)
        .how("m-g")
        .stale_minutes(5)
        .with_contact(contact("TrustedCertTest", None))
        .build()?;

    client.send_cot_event(event).await?;
    println!("✓ Event sent successfully!\n");

    println!("===================================================");
    println!("✅ PRODUCTION SOLUTION WORKS!");
    println!("===================================================");
    println!("This is the recommended approach:");
    println!("- Maintains proper certificate validation");
    println!("- Works reliably with TAK servers  ");
    println!("- Only trusts certificates you explicitly provide");
    println!("\nCheck TAK client for 'TRUSTED-CERT-TEST' marker.");

    Ok(())
}