Skip to content

Commit 833e9c3

Browse files
committed
-added 'certificate' option
- tweaked the dashboard look
1 parent 0766b0f commit 833e9c3

File tree

4 files changed

+222
-115
lines changed

4 files changed

+222
-115
lines changed

src/cli.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,10 @@ pub struct Cli {
8080
/// Bind to a specific source IP address (e.g., 192.168.10.0)
8181
#[arg(long)]
8282
pub source: Option<String>,
83+
84+
/// Path to a custom TLS certificate file (PEM or DER format)
85+
#[arg(long)]
86+
pub certificate: Option<std::path::PathBuf>,
8387
}
8488

8589
pub async fn run(args: Cli) -> Result<()> {
@@ -126,6 +130,7 @@ pub fn build_config(args: &Cli) -> RunConfig {
126130
experimental: args.experimental,
127131
interface: args.interface.clone(),
128132
source_ip: args.source.clone(),
133+
certificate_path: args.certificate.clone(),
129134
}
130135
}
131136

src/engine/cloudflare.rs

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,43 @@ impl CloudflareClient {
5555
}
5656
}
5757

58+
// Load custom certificate if provided
59+
if let Some(ref cert_path) = cfg.certificate_path {
60+
// Check file extension
61+
let ext = cert_path.extension()
62+
.and_then(|e| e.to_str())
63+
.map(|e| e.to_lowercase());
64+
65+
let valid_extensions = ["pem", "crt", "cer", "der"];
66+
if let Some(ref ext) = ext {
67+
if !valid_extensions.contains(&ext.as_str()) {
68+
return Err(anyhow::anyhow!(
69+
"Invalid certificate file extension '{}'. Expected one of: {}",
70+
ext,
71+
valid_extensions.join(", ")
72+
));
73+
}
74+
} else {
75+
return Err(anyhow::anyhow!(
76+
"Certificate file has no extension. Expected one of: {}",
77+
valid_extensions.join(", ")
78+
));
79+
}
80+
81+
let cert_data = std::fs::read(cert_path)
82+
.with_context(|| format!("failed to read certificate from {}", cert_path.display()))?;
83+
84+
// Parse based on file extension
85+
let cert = match ext.as_deref() {
86+
Some("der") => reqwest::Certificate::from_der(&cert_data)
87+
.with_context(|| format!("failed to parse DER certificate from {}", cert_path.display()))?,
88+
_ => reqwest::Certificate::from_pem(&cert_data)
89+
.with_context(|| format!("failed to parse PEM certificate from {}", cert_path.display()))?,
90+
};
91+
92+
builder = builder.add_root_certificate(cert);
93+
}
94+
5895
let http = builder
5996
.build()
6097
.context("failed to build http client")?;

src/model.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ pub struct RunConfig {
2020
pub experimental: bool,
2121
pub interface: Option<String>,
2222
pub source_ip: Option<String>,
23+
pub certificate_path: Option<std::path::PathBuf>,
2324
}
2425

2526
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]

0 commit comments

Comments
 (0)