Ensure loading of NSS module in tests

This commit is contained in:
Matteo Settenvini 2022-08-14 23:03:59 +02:00
parent 0f11e871ef
commit 9ce503e052
Signed by: matteo
GPG Key ID: 8576CC1AD97D42DF
8 changed files with 92 additions and 62 deletions

1
.gitignore vendored
View File

@ -4,3 +4,4 @@
/build /build
/target /target
/Cargo.lock /Cargo.lock
/.gdb_history

View File

@ -18,5 +18,9 @@ FetchContent_Declare(
FetchContent_MakeAvailable(Corrosion) FetchContent_MakeAvailable(Corrosion)
corrosion_import_crate(MANIFEST_PATH Cargo.toml) corrosion_import_crate(MANIFEST_PATH Cargo.toml)
get_target_property(corrosion_install_libraries nss_malcontent INTERFACE_LINK_LIBRARIES) set(sonamever 2) # mandated by NSS 3
install(IMPORTED_RUNTIME_ARTIFACTS ${corrosion_install_libraries}) get_property(corrosion_install_libraries TARGET nss_malcontent PROPERTY INTERFACE_LINK_LIBRARIES)
string(TOUPPER ${CMAKE_BUILD_TYPE} config_type_upper)
get_property(location TARGET ${corrosion_install_libraries} PROPERTY "IMPORTED_LOCATION_${config_type_upper}")
cmake_path(GET location FILENAME lib_basename)
install(FILES ${location} TYPE LIB RENAME "${lib_basename}.${sonamever}")

View File

@ -28,5 +28,5 @@ version = "1.0"
version = "0.2" version = "0.2"
[dependencies.nix] [dependencies.nix]
version = "0.24" version = "0.25"
features = [] features = []

View File

@ -6,10 +6,16 @@ extern crate bindgen;
use {std::env, std::path::PathBuf}; use {std::env, std::path::PathBuf};
fn main() { fn main() {
let out_dir = std::env::var("OUT_DIR").unwrap();
println!("cargo:rerun-if-changed=wrapper.h"); println!("cargo:rerun-if-changed=wrapper.h");
// Required by NSS 2 // Required by NSS 2
println!("cargo:rustc-link-arg=-Wl,-soname,libnss_malcontent.so.2"); println!("cargo:rustc-cdylib-link-arg=-Wl,-soname,libnss_malcontent.so.2");
// Enable dynamic loading of NSS module from OUT_DIR
// (see https://doc.rust-lang.org/cargo/reference/environment-variables.html#dynamic-library-paths)
println!("cargo:rustc-link-search={}", &out_dir);
let bindings = bindgen::Builder::default() let bindings = bindgen::Builder::default()
.header("wrapper.h") .header("wrapper.h")

View File

@ -206,8 +206,8 @@ allow-git = []
[sources.allow-org] [sources.allow-org]
# 1 or more github.com organizations to allow git sources for # 1 or more github.com organizations to allow git sources for
github = [""] # github = [""]
# 1 or more gitlab.com organizations to allow git sources for # 1 or more gitlab.com organizations to allow git sources for
gitlab = [""] # gitlab = [""]
# 1 or more bitbucket.org organizations to allow git sources for # 1 or more bitbucket.org organizations to allow git sources for
bitbucket = [""] # bitbucket = [""]

View File

@ -1,6 +1,7 @@
// SPDX-FileCopyrightText: 2022 Matteo Settenvini <matteo.settenvini@montecristosoftware.eu> // SPDX-FileCopyrightText: 2022 Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#![allow(dead_code)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs")); include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
use { use {
@ -13,28 +14,28 @@ use {
#[no_mangle] #[no_mangle]
pub extern "C" fn _nss_malcontent_gethostbyname4_r( pub extern "C" fn _nss_malcontent_gethostbyname4_r(
name: *const c_char, _name: *const c_char,
pat: *mut *mut gaih_addrtuple, _pat: *mut *mut gaih_addrtuple,
buffer: *mut c_char, _buffer: *mut c_char,
buflen: size_t, _buflen: size_t,
errnop: *mut c_int, _errnop: *mut c_int,
h_errnop: *mut c_int, _h_errnop: *mut c_int,
ttlp: *mut i32, _ttlp: *mut i32,
) -> nss_status { ) -> nss_status {
todo!() todo!()
} }
#[no_mangle] #[no_mangle]
pub extern "C" fn _nss_malcontent_gethostbyname3_r( pub extern "C" fn _nss_malcontent_gethostbyname3_r(
name: *const c_char, _name: *const c_char,
af: c_int, _af: c_int,
host: *mut hostent, _host: *mut hostent,
buffer: *mut c_char, _buffer: *mut c_char,
buflen: size_t, _buflen: size_t,
errnop: *mut c_int, _errnop: *mut c_int,
h_errnop: *mut c_int, _h_errnop: *mut c_int,
ttlp: *mut i32, _ttlp: *mut i32,
canonp: *mut *mut char, _canonp: *mut *mut char,
) -> nss_status { ) -> nss_status {
todo!() todo!()
} }
@ -88,15 +89,15 @@ pub extern "C" fn _nss_malcontent_gethostbyname_r(
#[no_mangle] #[no_mangle]
pub extern "C" fn _nss_malcontent_gethostbyaddr2_r( pub extern "C" fn _nss_malcontent_gethostbyaddr2_r(
addr: *const c_void, _addr: *const c_void,
len: socklen_t, _len: socklen_t,
af: c_int, _af: c_int,
host: *mut hostent, _host: *mut hostent,
buffer: *mut c_char, _buffer: *mut c_char,
buflen: size_t, _buflen: size_t,
errnop: *mut c_int, _errnop: *mut c_int,
h_errnop: *mut c_int, _h_errnop: *mut c_int,
ttlp: *mut i32, _ttlp: *mut i32,
) -> nss_status { ) -> nss_status {
todo!() todo!()
} }

View File

@ -1,11 +1,15 @@
// SPDX-FileCopyrightText: 2022 Matteo Settenvini <matteo.settenvini@montecristosoftware.eu> // SPDX-FileCopyrightText: 2022 Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// SPDX-License-Identifier: GPL-3.0-or-later // SPDX-License-Identifier: GPL-3.0-or-later
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(dead_code)]
use { use {
anyhow::{ensure, Result}, anyhow::{ensure, Result},
std::env,
std::ffi::CString, std::ffi::CString,
std::os::raw::c_int,
std::os::unix::fs::symlink,
std::path::PathBuf, std::path::PathBuf,
std::sync::Once, std::sync::Once,
}; };
@ -15,33 +19,27 @@ include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
static SETUP: Once = Once::new(); static SETUP: Once = Once::new();
pub fn setup() -> Result<()> { pub fn setup() -> Result<()> {
unsafe {
static mut NSS_CONFIG_STATUS: c_int = 0;
SETUP.call_once(|| {
let out_dir = PathBuf::from(env!("OUT_DIR")); let out_dir = PathBuf::from(env!("OUT_DIR"));
let nss_config_status = unsafe {
SETUP.call_once(|| {
let library_path = test_cdylib::build_current_project(); let library_path = test_cdylib::build_current_project();
let mut library_filename = library_path.file_name().unwrap().to_owned(); let mut library_filename = library_path.file_name().unwrap().to_owned();
library_filename.push(".2"); // required for NSS 2 modules library_filename.push(".2"); // required for NSS modules
let dest = out_dir.join(library_filename); let dest = out_dir.join(library_filename);
symlink(&library_path, &dest).expect(&format!( std::fs::copy(library_path, dest).unwrap();
"Unable to create symlink to library ({} -> {})",
library_path.to_string_lossy(),
dest.to_string_lossy()
));
std::env::set_var("LD_LIBRARY_PATH", out_dir);
let db = CString::new("hosts").unwrap();
let resolvers = CString::new("files malcontent [UNAVAIL=return] dns").unwrap();
NSS_CONFIG_STATUS = __nss_configure_lookup(db.as_ptr(), resolvers.as_ptr());
}); });
let db = CString::new("hosts").unwrap();
let resolvers = CString::new("malcontent [UNAVAIL=return] dns").unwrap();
__nss_configure_lookup(db.as_ptr(), resolvers.as_ptr())
};
ensure!( ensure!(
NSS_CONFIG_STATUS == 0, nss_config_status == 0,
"Unable to configure NSS to load module: __nss_configure_lookup() returned {}", "Unable to configure NSS to load module: __nss_configure_lookup() returned {}",
NSS_CONFIG_STATUS nss_config_status
); );
Ok(()) Ok(())
}
} }

View File

@ -3,13 +3,33 @@
mod common; mod common;
use anyhow::Result; use {
anyhow::{bail, Result},
libc::{freeaddrinfo, gai_strerror, getaddrinfo},
};
#[test] #[test]
fn nss_module_is_loaded() -> Result<()> { #[should_panic(expected = "not yet implemented")]
use std::net::ToSocketAddrs; fn nss_module_is_loaded() {
common::setup().unwrap();
common::setup()?; let hostname = std::ffi::CString::new("gnome.org").unwrap();
"www.google.com:443".to_socket_addrs()?; unsafe {
Ok(()) let mut addr = std::ptr::null_mut();
match getaddrinfo(
hostname.as_ptr(),
std::ptr::null(),
std::ptr::null(),
&mut addr,
) {
0 => freeaddrinfo(addr),
status => {
let error = std::ffi::CStr::from_ptr(gai_strerror(status));
panic!(
"Unable to resolve hostname, getaddrinfo returned {}",
error.to_str().unwrap()
)
}
}
};
} }