Skip to content

Commit 3ea7c1a

Browse files
committed
Deprecate env-var-writing functions
Replace them with `unsafe` equivalents with documentation indicating that you probably shouldn't rely on them. Not the best solution but given the age of this crate there's not really a whole lot else that can be done. Closes #30
1 parent a9a9f3e commit 3ea7c1a

File tree

1 file changed

+71
-12
lines changed

1 file changed

+71
-12
lines changed

src/lib.rs

Lines changed: 71 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,41 @@ fn cert_dirs_iter() -> impl Iterator<Item = &'static Path> {
4343
#[cfg(target_os = "haiku")]
4444
"/boot/system/data/ssl",
4545
]
46-
.iter().map(Path::new).filter(|p| p.exists())
46+
.iter()
47+
.map(Path::new)
48+
.filter(|p| p.exists())
4749
}
4850

4951
/// Probe for SSL certificates on the system, then configure the SSL certificate `SSL_CERT_FILE`
5052
/// and `SSL_CERT_DIR` environment variables in this process for OpenSSL to use.
5153
///
5254
/// Preconfigured values in the environment variables will not be overwritten if the paths they
5355
/// point to exist and are accessible.
56+
#[deprecated(note = "this function is not safe, use `init_openssl_env_vars` instead")]
5457
pub fn init_ssl_cert_env_vars() {
55-
try_init_ssl_cert_env_vars();
58+
unsafe {
59+
init_openssl_env_vars();
60+
}
61+
}
62+
63+
/// Probe for SSL certificates on the system, then configure the SSL certificate `SSL_CERT_FILE`
64+
/// and `SSL_CERT_DIR` environment variables in this process for OpenSSL to use.
65+
///
66+
/// Preconfigured values in the environment variables will not be overwritten if the paths they
67+
/// point to exist and are accessible.
68+
///
69+
/// # Safety
70+
///
71+
/// This function is not safe because it mutates the process's environment
72+
/// variables which is generally not safe. See the [documentation in libstd][doc]
73+
/// for information about why setting environment variables is not safe.
74+
///
75+
/// If possible use the [`probe`] function and directly configure OpenSSL
76+
/// methods instead of relying on environment variables.
77+
///
78+
/// [doc]: https://doc.rust-lang.org/stable/std/env/fn.set_var.html#safety
79+
pub unsafe fn init_openssl_env_vars() {
80+
try_init_openssl_env_vars();
5681
}
5782

5883
/// Probe for SSL certificates on the system, then configure the SSL certificate `SSL_CERT_FILE`
@@ -64,23 +89,57 @@ pub fn init_ssl_cert_env_vars() {
6489
/// Returns `true` if any certificate file or directory was found while probing.
6590
/// Combine this with `has_ssl_cert_env_vars()` to check whether previously configured environment
6691
/// variables are valid.
92+
#[deprecated(note = "use try_init_openssl_env_vars instead, this function is not safe")]
6793
pub fn try_init_ssl_cert_env_vars() -> bool {
68-
let ProbeResult { cert_file, cert_dir } = probe();
94+
unsafe { try_init_openssl_env_vars() }
95+
}
96+
97+
/// Probe for SSL certificates on the system, then configure the SSL certificate `SSL_CERT_FILE`
98+
/// and `SSL_CERT_DIR` environment variables in this process for OpenSSL to use.
99+
///
100+
/// Preconfigured values in the environment variables will not be overwritten if the paths they
101+
/// point to exist and are accessible.
102+
///
103+
/// Returns `true` if any certificate file or directory was found while probing.
104+
/// Combine this with `has_ssl_cert_env_vars()` to check whether previously configured environment
105+
/// variables are valid.
106+
///
107+
/// # Safety
108+
///
109+
/// This function is not safe because it mutates the process's environment
110+
/// variables which is generally not safe. See the [documentation in libstd][doc]
111+
/// for information about why setting environment variables is not safe.
112+
///
113+
/// If possible use the [`probe`] function and directly configure OpenSSL
114+
/// methods instead of relying on environment variables.
115+
///
116+
/// [doc]: https://doc.rust-lang.org/stable/std/env/fn.set_var.html#safety
117+
pub unsafe fn try_init_openssl_env_vars() -> bool {
118+
let ProbeResult {
119+
cert_file,
120+
cert_dir,
121+
} = probe();
69122
// we won't be overwriting existing env variables because if they're valid probe() will have
70123
// returned them unchanged
71124
if let Some(path) = &cert_file {
72-
put(ENV_CERT_FILE, path);
125+
unsafe {
126+
put(ENV_CERT_FILE, path);
127+
}
73128
}
74129
if let Some(path) = &cert_dir {
75-
put(ENV_CERT_DIR, path);
130+
unsafe {
131+
put(ENV_CERT_DIR, path);
132+
}
76133
}
77134

78-
fn put(var: &str, path: &Path) {
135+
unsafe fn put(var: &str, path: &Path) {
79136
// Avoid calling `setenv` if the variable already has the same contents. This avoids a
80137
// crash when called from out of perl <5.38 (Debian Bookworm is at 5.36), as old versions
81138
// of perl tend to manipulate the `environ` pointer directly.
82139
if env::var_os(var).as_deref() != Some(path.as_os_str()) {
83-
env::set_var(var, path);
140+
unsafe {
141+
env::set_var(var, path);
142+
}
84143
}
85144
}
86145

@@ -99,17 +158,17 @@ pub fn has_ssl_cert_env_vars() -> bool {
99158
}
100159

101160
fn probe_from_env() -> ProbeResult {
102-
let var = |name| {
103-
env::var_os(name)
104-
.map(PathBuf::from)
105-
.filter(|p| p.exists())
106-
};
161+
let var = |name| env::var_os(name).map(PathBuf::from).filter(|p| p.exists());
107162
ProbeResult {
108163
cert_file: var(ENV_CERT_FILE),
109164
cert_dir: var(ENV_CERT_DIR),
110165
}
111166
}
112167

168+
/// Probe the current system for the "cert file" and "cert dir" variables that
169+
/// OpenSSL typically requires.
170+
///
171+
/// The probe result is returned as a [`ProbeResult`] structure here.
113172
pub fn probe() -> ProbeResult {
114173
let mut result = probe_from_env();
115174
for certs_dir in cert_dirs_iter() {

0 commit comments

Comments
 (0)