1use std::env;
2use std::fs;
3use std::path::PathBuf;
4
5pub struct ProbeResult {
6 pub cert_file: Option<PathBuf>,
7 pub cert_dir: Option<PathBuf>,
8}
9
10pub fn find_certs_dirs() -> Vec<PathBuf> {
15 [
17 "/var/ssl",
18 "/usr/share/ssl",
19 "/usr/local/ssl",
20 "/usr/local/openssl",
21 "/usr/local/share",
22 "/usr/lib/ssl",
23 "/usr/ssl",
24 "/etc/openssl",
25 "/etc/pki/ca-trust/extracted/pem",
26 "/etc/pki/tls",
27 "/etc/ssl",
28 "/data/data/com.termux/files/usr/etc/tls",
29 "/boot/system/data/ssl",
30 ].iter().map(|s| PathBuf::from(*s)).filter(|p| {
31 fs::metadata(p).is_ok()
32 }).collect()
33}
34
35pub fn init_ssl_cert_env_vars() {
36 let ProbeResult { cert_file, cert_dir } = probe();
37 match cert_file {
38 Some(path) => put("SSL_CERT_FILE", path),
39 None => {}
40 }
41 match cert_dir {
42 Some(path) => put("SSL_CERT_DIR", path),
43 None => {}
44 }
45
46 fn put(var: &str, path: PathBuf) {
47 match env::var(var) {
49 Ok(..) => {}
50 Err(..) => env::set_var(var, &path),
51 }
52 }
53}
54
55pub fn probe() -> ProbeResult {
56 let mut result = ProbeResult {
57 cert_file: env::var_os("SSL_CERT_FILE").map(PathBuf::from),
58 cert_dir: env::var_os("SSL_CERT_DIR").map(PathBuf::from),
59 };
60 for certs_dir in find_certs_dirs().iter() {
61 for cert in [
64 "cert.pem",
65 "certs.pem",
66 "certs/ca-certificates.crt",
67 "certs/ca-root-nss.crt",
68 "certs/ca-bundle.crt",
69 "CARootCertificates.pem",
70 "tls-ca-bundle.pem",
71 ].iter() {
72 try(&mut result.cert_file, certs_dir.join(cert));
73 }
74 try(&mut result.cert_dir, certs_dir.join("certs"));
75 }
76 result
77}
78
79fn try(dst: &mut Option<PathBuf>, val: PathBuf) {
80 if dst.is_none() && fs::metadata(&val).is_ok() {
81 *dst = Some(val);
82 }
83}