kftray-portforward 0.27.30

KFtray library with port forwarding logic
Documentation
use anyhow::{Context, Result};
use log::{debug, info, warn};

#[cfg(target_os = "macos")]
use security_framework::certificate::SecCertificate;
#[cfg(target_os = "macos")]
use security_framework::trust_settings::{Domain, TrustSettings, TrustSettingsForCertificate};


#[cfg(target_os = "macos")]
pub async fn install_ca_certificate_native(ca_cert_der: &[u8]) -> Result<()> {
    info!("Installing CA certificate using native macOS Security Framework");


    let _cert = SecCertificate::from_der(ca_cert_der)
        .context("Failed to create SecCertificate from DER data")?;





    warn!("Native certificate installation requires admin privileges and special entitlements");
    info!("Falling back to osascript method for proper admin authentication");

    Err(anyhow::anyhow!("Native installation not fully implemented, using fallback"))
}


#[cfg(target_os = "macos")]
pub async fn is_ca_installed_native(ca_cert_der: &[u8]) -> Result<bool> {

    if ca_cert_der.is_empty() {
        debug!("Empty certificate DER data provided");
        return Ok(false);
    }


    let target_cert = match SecCertificate::from_der(ca_cert_der) {
        Ok(cert) => {
            debug!("Successfully created SecCertificate from DER data ({} bytes)", ca_cert_der.len());
            cert
        },
        Err(e) => {
            debug!("Failed to create SecCertificate from DER data ({} bytes): {}", ca_cert_der.len(), e);
            debug!("DER data starts with: {:02X?}", &ca_cert_der[..ca_cert_der.len().min(16)]);
            return Ok(false);
        }
    };


    let trust_settings = TrustSettings::new(Domain::System);
    match trust_settings.tls_trust_settings_for_certificate(&target_cert) {
        Ok(Some(settings)) => {
            debug!("Certificate found in system trust settings");
            return Ok(is_certificate_trusted(&settings));
        }
        Ok(None) => debug!("Certificate not found in system trust settings"),
        Err(e) => debug!("Error checking system trust settings: {}", e),
    }


    let trust_settings = TrustSettings::new(Domain::Admin);
    match trust_settings.tls_trust_settings_for_certificate(&target_cert) {
        Ok(Some(settings)) => {
            debug!("Certificate found in admin trust settings");
            return Ok(is_certificate_trusted(&settings));
        }
        Ok(None) => debug!("Certificate not found in admin trust settings"),
        Err(e) => debug!("Error checking admin trust settings: {}", e),
    }


    let trust_settings = TrustSettings::new(Domain::User);
    match trust_settings.tls_trust_settings_for_certificate(&target_cert) {
        Ok(Some(settings)) => {
            debug!("Certificate found in user trust settings");
            return Ok(is_certificate_trusted(&settings));
        }
        Ok(None) => debug!("Certificate not found in user trust settings"),
        Err(e) => debug!("Error checking user trust settings: {}", e),
    }


    match is_certificate_in_keychain(&target_cert).await {
        Ok(found) => {
            if found {
                info!("Certificate found in keychain but may not be explicitly trusted");
                Ok(true)
            } else {
                debug!("Certificate not found in any keychain");
                Ok(false)
            }
        }
        Err(e) => {
            warn!("Error checking keychain for certificate: {}", e);
            Ok(false)
        }
    }
}


#[cfg(target_os = "macos")]
pub async fn remove_ca_certificate_native(ca_cert_der: &[u8]) -> Result<()> {
    info!("Removing CA certificate using native macOS Security Framework");


    let _target_cert = SecCertificate::from_der(ca_cert_der)
        .context("Failed to create SecCertificate from DER data")?;

    let removal_attempted = false;
    let mut removal_errors = Vec::new();



    warn!("Native certificate removal not fully implemented");
    removal_errors.push("native removal not implemented".to_string());

    if removal_attempted {
        if !removal_errors.is_empty() {
            warn!("Certificate removed but some errors occurred: {:?}", removal_errors);
        }
        Ok(())
    } else {
        Err(anyhow::anyhow!(
            "Failed to remove certificate from any keychain: {}",
            removal_errors.join(", ")
        ))
    }
}



#[cfg(target_os = "macos")]
fn is_certificate_trusted(settings: &TrustSettingsForCertificate) -> bool {

    match settings {
        TrustSettingsForCertificate::TrustRoot => {
            debug!("Certificate explicitly trusted as root");
            true
        }
        TrustSettingsForCertificate::TrustAsRoot => {
            debug!("Certificate trusted as root");
            true
        }
        TrustSettingsForCertificate::Deny => {
            debug!("Certificate explicitly denied");
            false
        }
        TrustSettingsForCertificate::Unspecified => {
            debug!("Certificate trust unspecified (not explicitly trusted)");
            false
        }
        _ => {
            debug!("Certificate has other trust settings");
            true
        }
    }
}


#[cfg(target_os = "macos")]
async fn is_certificate_in_keychain(_cert: &SecCertificate) -> Result<bool> {


    debug!("Certificate keychain search not fully implemented with high-level APIs");
    Ok(false)
}


#[cfg(not(target_os = "macos"))]
pub async fn install_ca_certificate_native(_ca_cert_der: &[u8]) -> Result<()> {
    Err(anyhow::anyhow!("Native macOS certificate installation not available on this platform"))
}

#[cfg(not(target_os = "macos"))]
pub async fn is_ca_installed_native(_ca_cert_der: &[u8]) -> Result<bool> {
    Ok(false)
}

#[cfg(not(target_os = "macos"))]
pub async fn remove_ca_certificate_native(_ca_cert_der: &[u8]) -> Result<()> {
    Err(anyhow::anyhow!("Native macOS certificate removal not available on this platform"))
}