Skip to content

Commit 6be675d

Browse files
committed
Yield multiple certificate directories
1 parent 86ffc6f commit 6be675d

File tree

1 file changed

+25
-17
lines changed

1 file changed

+25
-17
lines changed

src/lib.rs

Lines changed: 25 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
use std::env;
2+
use std::ffi::{OsStr, OsString};
23
use std::path::{Path, PathBuf};
34

45
/// Probe for SSL certificates on the system, then configure the SSL certificate `SSL_CERT_FILE`
@@ -30,27 +31,36 @@ pub unsafe fn try_init_openssl_env_vars() -> bool {
3031
// returned them unchanged
3132
if let Some(path) = &cert_file {
3233
unsafe {
33-
put(ENV_CERT_FILE, path);
34+
put(ENV_CERT_FILE, path.as_os_str());
3435
}
3536
}
36-
if let Some(path) = &cert_dir {
37+
38+
if !cert_dir.is_empty() {
39+
let mut joined = OsString::new();
40+
for (i, path) in cert_dir.iter().enumerate() {
41+
if i != 0 {
42+
joined.push(":");
43+
}
44+
joined.push(path.as_os_str());
45+
}
46+
3747
unsafe {
38-
put(ENV_CERT_DIR, path);
48+
put(ENV_CERT_DIR, &joined);
3949
}
4050
}
4151

42-
unsafe fn put(var: &str, path: &Path) {
52+
unsafe fn put(var: &str, path: &OsStr) {
4353
// Avoid calling `setenv` if the variable already has the same contents. This avoids a
4454
// crash when called from out of perl <5.38 (Debian Bookworm is at 5.36), as old versions
4555
// of perl tend to manipulate the `environ` pointer directly.
46-
if env::var_os(var).as_deref() != Some(path.as_os_str()) {
56+
if env::var_os(var).as_deref() != Some(path) {
4757
unsafe {
4858
env::set_var(var, path);
4959
}
5060
}
5161
}
5262

53-
cert_file.is_some() || cert_dir.is_some()
63+
cert_file.is_some() || !cert_dir.is_empty()
5464
}
5565

5666
/// Probe the current system for the "cert file" and "cert dir" variables that
@@ -70,14 +80,9 @@ pub fn probe() -> ProbeResult {
7080
}
7181

7282
for certs_dir in candidate_cert_dirs() {
73-
if result.cert_dir.is_none() {
74-
let cert_dir = PathBuf::from(certs_dir);
75-
if cert_dir.exists() {
76-
result.cert_dir = Some(cert_dir);
77-
}
78-
}
79-
if result.cert_dir.is_some() {
80-
break;
83+
let cert_dir = PathBuf::from(certs_dir);
84+
if cert_dir.exists() {
85+
result.cert_dir.push(cert_dir);
8186
}
8287
}
8388

@@ -103,20 +108,23 @@ pub fn candidate_cert_dirs() -> impl Iterator<Item = &'static Path> {
103108
/// Returns `true` if either variable is set to an existing file or directory.
104109
pub fn has_ssl_cert_env_vars() -> bool {
105110
let probe = ProbeResult::from_env();
106-
probe.cert_file.is_some() || probe.cert_dir.is_some()
111+
probe.cert_file.is_some() || !probe.cert_dir.is_empty()
107112
}
108113

109114
pub struct ProbeResult {
110115
pub cert_file: Option<PathBuf>,
111-
pub cert_dir: Option<PathBuf>,
116+
pub cert_dir: Vec<PathBuf>,
112117
}
113118

114119
impl ProbeResult {
115120
fn from_env() -> ProbeResult {
116121
let var = |name| env::var_os(name).map(PathBuf::from).filter(|p| p.exists());
117122
ProbeResult {
118123
cert_file: var(ENV_CERT_FILE),
119-
cert_dir: var(ENV_CERT_DIR),
124+
cert_dir: match var(ENV_CERT_DIR) {
125+
Some(p) => vec![p],
126+
None => vec![],
127+
},
120128
}
121129
}
122130
}

0 commit comments

Comments
 (0)