use std::env; | |
use std::fs; | |
use std::path::PathBuf; | |
pub struct ProbeResult { | |
pub cert_file: Option<PathBuf>, | |
pub cert_dir: Option<PathBuf>, | |
} | |
/// Probe the system for the directory in which CA certificates should likely be | |
/// found. | |
/// | |
/// This will only search known system locations. | |
pub fn find_certs_dirs() -> Vec<PathBuf> { | |
// see http://gagravarr.org/writing/openssl-certs/others.shtml | |
[ | |
"/var/ssl", | |
"/usr/share/ssl", | |
"/usr/local/ssl", | |
"/usr/local/openssl", | |
"/usr/local/share", | |
"/usr/lib/ssl", | |
"/usr/ssl", | |
"/etc/openssl", | |
"/etc/pki/ca-trust/extracted/pem", | |
"/etc/pki/tls", | |
"/etc/ssl", | |
"/data/data/com.termux/files/usr/etc/tls", | |
"/boot/system/data/ssl", | |
].iter().map(|s| PathBuf::from(*s)).filter(|p| { | |
fs::metadata(p).is_ok() | |
}).collect() | |
} | |
pub fn init_ssl_cert_env_vars() { | |
let ProbeResult { cert_file, cert_dir } = probe(); | |
match cert_file { | |
Some(path) => put("SSL_CERT_FILE", path), | |
None => {} | |
} | |
match cert_dir { | |
Some(path) => put("SSL_CERT_DIR", path), | |
None => {} | |
} | |
fn put(var: &str, path: PathBuf) { | |
// Don't stomp over what anyone else has set | |
match env::var(var) { | |
Ok(..) => {} | |
Err(..) => env::set_var(var, &path), | |
} | |
} | |
} | |
pub fn probe() -> ProbeResult { | |
let mut result = ProbeResult { | |
cert_file: env::var_os("SSL_CERT_FILE").map(PathBuf::from), | |
cert_dir: env::var_os("SSL_CERT_DIR").map(PathBuf::from), | |
}; | |
for certs_dir in find_certs_dirs().iter() { | |
// cert.pem looks to be an openssl 1.0.1 thing, while | |
// certs/ca-certificates.crt appears to be a 0.9.8 thing | |
for cert in [ | |
"cert.pem", | |
"certs.pem", | |
"certs/ca-certificates.crt", | |
"certs/ca-root-nss.crt", | |
"certs/ca-bundle.crt", | |
"CARootCertificates.pem", | |
"tls-ca-bundle.pem", | |
].iter() { | |
try(&mut result.cert_file, certs_dir.join(cert)); | |
} | |
try(&mut result.cert_dir, certs_dir.join("certs")); | |
} | |
result | |
} | |
fn try(dst: &mut Option<PathBuf>, val: PathBuf) { | |
if dst.is_none() && fs::metadata(&val).is_ok() { | |
*dst = Some(val); | |
} | |
} |