11use std:: env;
2+ use std:: ffi:: { OsStr , OsString } ;
23use 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.
104109pub 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
109114pub struct ProbeResult {
110115 pub cert_file : Option < PathBuf > ,
111- pub cert_dir : Option < PathBuf > ,
116+ pub cert_dir : Vec < PathBuf > ,
112117}
113118
114119impl 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