diff --git a/.vscode/launch.json b/.vscode/launch.json new file mode 100644 index 0000000..3c5fd08 --- /dev/null +++ b/.vscode/launch.json @@ -0,0 +1,48 @@ +// SPDX-FileCopyrightText: 2022 Matteo Settenvini +// SPDX-License-Identifier: CC0-1.0 +{ + // Use IntelliSense to learn about possible attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "lldb", + "request": "launch", + "name": "Debug integration test 'common'", + "cargo": { + "args": [ + "test", + "--no-run", + "--test=common", + "--package=malcontent-nss" + ], + "filter": { + "name": "common", + "kind": "test" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + }, + { + "type": "lldb", + "request": "launch", + "name": "Debug integration test 'integration_test'", + "cargo": { + "args": [ + "test", + "--no-run", + "--test=integration_test", + "--package=malcontent-nss" + ], + "filter": { + "name": "integration_test", + "kind": "test" + } + }, + "args": [], + "cwd": "${workspaceFolder}" + } + ] +} \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index be3be27..82a53d3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,9 +15,8 @@ FetchContent_Declare( GIT_TAG v0.2.1 ) -set(Rust_TOOLCHAIN nightly) FetchContent_MakeAvailable(Corrosion) corrosion_import_crate(MANIFEST_PATH Cargo.toml) -get_target_property(corrosion_install_libraries malcontent-nss INTERFACE_LINK_LIBRARIES) -install(IMPORTED_RUNTIME_ARTIFACTS ${corrosion_install_libraries}) \ No newline at end of file +get_target_property(corrosion_install_libraries nss_malcontent INTERFACE_LINK_LIBRARIES) +install(IMPORTED_RUNTIME_ARTIFACTS ${corrosion_install_libraries}) diff --git a/Cargo.toml b/Cargo.toml index 8252e50..0fff316 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -10,6 +10,7 @@ license = "GPL-3.0-or-later" [lib] crate-type = ["cdylib"] +name = "nss_malcontent" [dev-dependencies.rusty-hook] version = "0.11" @@ -17,6 +18,12 @@ version = "0.11" [build-dependencies.bindgen] version = "0.60" +[dev-dependencies.test-cdylib] +version = "1.1" + +[dependencies.anyhow] +version = "1.0" + [dependencies.libc] version = "0.2" diff --git a/build.rs b/build.rs index 691df83..5ef213e 100644 --- a/build.rs +++ b/build.rs @@ -7,12 +7,17 @@ use {std::env, std::path::PathBuf}; fn main() { println!("cargo:rerun-if-changed=wrapper.h"); + + // Required by NSS 2 + println!("cargo:rustc-link-arg=-Wl,-soname,libnss_malcontent.so.2"); + let bindings = bindgen::Builder::default() .header("wrapper.h") .parse_callbacks(Box::new(bindgen::CargoCallbacks)) .newtype_enum("nss_status") .allowlist_type("nss_status") .allowlist_type("gaih_addrtuple") + .allowlist_function("__nss_configure_lookup") .generate() .expect("Unable to generate bindings"); diff --git a/src/nss_api.rs b/src/nss_api.rs index 7cad4d8..a739a30 100644 --- a/src/nss_api.rs +++ b/src/nss_api.rs @@ -4,7 +4,7 @@ include!(concat!(env!("OUT_DIR"), "/bindings.rs")); use { - core::ffi::{c_char, c_int, c_void}, + ::std::os::raw::{c_char, c_int, c_void}, libc::{hostent, size_t, socklen_t, AF_INET}, std::ptr, }; diff --git a/tests/common.rs b/tests/common.rs new file mode 100644 index 0000000..854bb99 --- /dev/null +++ b/tests/common.rs @@ -0,0 +1,47 @@ +// SPDX-FileCopyrightText: 2022 Matteo Settenvini +// SPDX-License-Identifier: GPL-3.0-or-later + +use { + anyhow::{ensure, Result}, + std::ffi::CString, + std::os::raw::c_int, + std::os::unix::fs::symlink, + std::path::PathBuf, + std::sync::Once, +}; + +include!(concat!(env!("OUT_DIR"), "/bindings.rs")); + +static SETUP: Once = Once::new(); + +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 library_path = test_cdylib::build_current_project(); + let mut library_filename = library_path.file_name().unwrap().to_owned(); + library_filename.push(".2"); // required for NSS 2 modules + + let dest = out_dir.join(library_filename); + symlink(&library_path, &dest).expect(&format!( + "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()); + }); + + ensure!( + NSS_CONFIG_STATUS == 0, + "Unable to configure NSS to load module: __nss_configure_lookup() returned {}", + NSS_CONFIG_STATUS + ); + Ok(()) + } +} diff --git a/tests/integration_test.rs b/tests/integration_test.rs new file mode 100644 index 0000000..97bccc5 --- /dev/null +++ b/tests/integration_test.rs @@ -0,0 +1,15 @@ +// SPDX-FileCopyrightText: 2022 Matteo Settenvini +// SPDX-License-Identifier: GPL-3.0-or-later + +mod common; + +use anyhow::Result; + +#[test] +fn nss_module_is_loaded() -> Result<()> { + use std::net::ToSocketAddrs; + + common::setup()?; + "www.google.com:443".to_socket_addrs()?; + Ok(()) +}