Skip to content

Commit 3cef693

Browse files
authored
Merge pull request #33 from alexcrichton/add-unsafe-functions
Deprecate env-var-writing functions
2 parents a9a9f3e + 9e937c0 commit 3cef693

File tree

1 file changed

+63
-14
lines changed

1 file changed

+63
-14
lines changed

src/lib.rs

+63-14
Original file line numberDiff line numberDiff line change
@@ -43,16 +43,45 @@ 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())
49+
}
50+
51+
/// Deprecated as this isn't sound, use [`init_openssl_env_vars`] instead.
52+
#[doc(hidden)]
53+
#[deprecated(note = "this function is not safe, use `init_openssl_env_vars` instead")]
54+
pub fn init_ssl_cert_env_vars() {
55+
unsafe {
56+
init_openssl_env_vars();
57+
}
4758
}
4859

4960
/// Probe for SSL certificates on the system, then configure the SSL certificate `SSL_CERT_FILE`
5061
/// and `SSL_CERT_DIR` environment variables in this process for OpenSSL to use.
5162
///
5263
/// Preconfigured values in the environment variables will not be overwritten if the paths they
5364
/// point to exist and are accessible.
54-
pub fn init_ssl_cert_env_vars() {
55-
try_init_ssl_cert_env_vars();
65+
///
66+
/// # Safety
67+
///
68+
/// This function is not safe because it mutates the process's environment
69+
/// variables which is generally not safe. See the [documentation in libstd][doc]
70+
/// for information about why setting environment variables is not safe.
71+
///
72+
/// If possible use the [`probe`] function and directly configure OpenSSL
73+
/// methods instead of relying on environment variables.
74+
///
75+
/// [doc]: https://doc.rust-lang.org/stable/std/env/fn.set_var.html#safety
76+
pub unsafe fn init_openssl_env_vars() {
77+
try_init_openssl_env_vars();
78+
}
79+
80+
/// Deprecated as this isn't sound, use [`try_init_openssl_env_vars`] instead.
81+
#[doc(hidden)]
82+
#[deprecated(note = "use try_init_openssl_env_vars instead, this function is not safe")]
83+
pub fn try_init_ssl_cert_env_vars() -> bool {
84+
unsafe { try_init_openssl_env_vars() }
5685
}
5786

5887
/// Probe for SSL certificates on the system, then configure the SSL certificate `SSL_CERT_FILE`
@@ -64,23 +93,43 @@ pub fn init_ssl_cert_env_vars() {
6493
/// Returns `true` if any certificate file or directory was found while probing.
6594
/// Combine this with `has_ssl_cert_env_vars()` to check whether previously configured environment
6695
/// variables are valid.
67-
pub fn try_init_ssl_cert_env_vars() -> bool {
68-
let ProbeResult { cert_file, cert_dir } = probe();
96+
///
97+
/// # Safety
98+
///
99+
/// This function is not safe because it mutates the process's environment
100+
/// variables which is generally not safe. See the [documentation in libstd][doc]
101+
/// for information about why setting environment variables is not safe.
102+
///
103+
/// If possible use the [`probe`] function and directly configure OpenSSL
104+
/// methods instead of relying on environment variables.
105+
///
106+
/// [doc]: https://doc.rust-lang.org/stable/std/env/fn.set_var.html#safety
107+
pub unsafe fn try_init_openssl_env_vars() -> bool {
108+
let ProbeResult {
109+
cert_file,
110+
cert_dir,
111+
} = probe();
69112
// we won't be overwriting existing env variables because if they're valid probe() will have
70113
// returned them unchanged
71114
if let Some(path) = &cert_file {
72-
put(ENV_CERT_FILE, path);
115+
unsafe {
116+
put(ENV_CERT_FILE, path);
117+
}
73118
}
74119
if let Some(path) = &cert_dir {
75-
put(ENV_CERT_DIR, path);
120+
unsafe {
121+
put(ENV_CERT_DIR, path);
122+
}
76123
}
77124

78-
fn put(var: &str, path: &Path) {
125+
unsafe fn put(var: &str, path: &Path) {
79126
// Avoid calling `setenv` if the variable already has the same contents. This avoids a
80127
// crash when called from out of perl <5.38 (Debian Bookworm is at 5.36), as old versions
81128
// of perl tend to manipulate the `environ` pointer directly.
82129
if env::var_os(var).as_deref() != Some(path.as_os_str()) {
83-
env::set_var(var, path);
130+
unsafe {
131+
env::set_var(var, path);
132+
}
84133
}
85134
}
86135

@@ -99,17 +148,17 @@ pub fn has_ssl_cert_env_vars() -> bool {
99148
}
100149

101150
fn probe_from_env() -> ProbeResult {
102-
let var = |name| {
103-
env::var_os(name)
104-
.map(PathBuf::from)
105-
.filter(|p| p.exists())
106-
};
151+
let var = |name| env::var_os(name).map(PathBuf::from).filter(|p| p.exists());
107152
ProbeResult {
108153
cert_file: var(ENV_CERT_FILE),
109154
cert_dir: var(ENV_CERT_DIR),
110155
}
111156
}
112157

158+
/// Probe the current system for the "cert file" and "cert dir" variables that
159+
/// OpenSSL typically requires.
160+
///
161+
/// The probe result is returned as a [`ProbeResult`] structure here.
113162
pub fn probe() -> ProbeResult {
114163
let mut result = probe_from_env();
115164
for certs_dir in cert_dirs_iter() {

0 commit comments

Comments
 (0)