From 9ce503e052bce9289601e3a9c051d3423e3111f0 Mon Sep 17 00:00:00 2001 From: Matteo Settenvini Date: Sun, 14 Aug 2022 23:03:59 +0200 Subject: [PATCH] Ensure loading of NSS module in tests --- .gitignore | 1 + CMakeLists.txt | 8 ++++-- Cargo.toml | 2 +- build.rs | 8 +++++- deny.toml | 6 ++--- src/nss_api.rs | 51 ++++++++++++++++++++------------------- tests/common.rs | 46 +++++++++++++++++------------------ tests/integration_test.rs | 32 +++++++++++++++++++----- 8 files changed, 92 insertions(+), 62 deletions(-) diff --git a/.gitignore b/.gitignore index 884cd63..619e22c 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ /build /target /Cargo.lock +/.gdb_history \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index 82a53d3..ac97827 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -18,5 +18,9 @@ FetchContent_Declare( FetchContent_MakeAvailable(Corrosion) corrosion_import_crate(MANIFEST_PATH Cargo.toml) -get_target_property(corrosion_install_libraries nss_malcontent INTERFACE_LINK_LIBRARIES) -install(IMPORTED_RUNTIME_ARTIFACTS ${corrosion_install_libraries}) +set(sonamever 2) # mandated by NSS 3 +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}") diff --git a/Cargo.toml b/Cargo.toml index 0fff316..fb7a74e 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -28,5 +28,5 @@ version = "1.0" version = "0.2" [dependencies.nix] -version = "0.24" +version = "0.25" features = [] diff --git a/build.rs b/build.rs index 5ef213e..b9fce41 100644 --- a/build.rs +++ b/build.rs @@ -6,10 +6,16 @@ extern crate bindgen; use {std::env, std::path::PathBuf}; fn main() { + let out_dir = std::env::var("OUT_DIR").unwrap(); + println!("cargo:rerun-if-changed=wrapper.h"); // 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() .header("wrapper.h") diff --git a/deny.toml b/deny.toml index 9c0d61b..5646371 100644 --- a/deny.toml +++ b/deny.toml @@ -206,8 +206,8 @@ allow-git = [] [sources.allow-org] # 1 or more github.com organizations to allow git sources for -github = [""] +# github = [""] # 1 or more gitlab.com organizations to allow git sources for -gitlab = [""] +# gitlab = [""] # 1 or more bitbucket.org organizations to allow git sources for -bitbucket = [""] +# bitbucket = [""] diff --git a/src/nss_api.rs b/src/nss_api.rs index a739a30..aca8d7d 100644 --- a/src/nss_api.rs +++ b/src/nss_api.rs @@ -1,6 +1,7 @@ // SPDX-FileCopyrightText: 2022 Matteo Settenvini // SPDX-License-Identifier: GPL-3.0-or-later +#![allow(dead_code)] include!(concat!(env!("OUT_DIR"), "/bindings.rs")); use { @@ -13,28 +14,28 @@ use { #[no_mangle] pub extern "C" fn _nss_malcontent_gethostbyname4_r( - name: *const c_char, - pat: *mut *mut gaih_addrtuple, - buffer: *mut c_char, - buflen: size_t, - errnop: *mut c_int, - h_errnop: *mut c_int, - ttlp: *mut i32, + _name: *const c_char, + _pat: *mut *mut gaih_addrtuple, + _buffer: *mut c_char, + _buflen: size_t, + _errnop: *mut c_int, + _h_errnop: *mut c_int, + _ttlp: *mut i32, ) -> nss_status { todo!() } #[no_mangle] pub extern "C" fn _nss_malcontent_gethostbyname3_r( - name: *const c_char, - af: c_int, - host: *mut hostent, - buffer: *mut c_char, - buflen: size_t, - errnop: *mut c_int, - h_errnop: *mut c_int, - ttlp: *mut i32, - canonp: *mut *mut char, + _name: *const c_char, + _af: c_int, + _host: *mut hostent, + _buffer: *mut c_char, + _buflen: size_t, + _errnop: *mut c_int, + _h_errnop: *mut c_int, + _ttlp: *mut i32, + _canonp: *mut *mut char, ) -> nss_status { todo!() } @@ -88,15 +89,15 @@ pub extern "C" fn _nss_malcontent_gethostbyname_r( #[no_mangle] pub extern "C" fn _nss_malcontent_gethostbyaddr2_r( - addr: *const c_void, - len: socklen_t, - af: c_int, - host: *mut hostent, - buffer: *mut c_char, - buflen: size_t, - errnop: *mut c_int, - h_errnop: *mut c_int, - ttlp: *mut i32, + _addr: *const c_void, + _len: socklen_t, + _af: c_int, + _host: *mut hostent, + _buffer: *mut c_char, + _buflen: size_t, + _errnop: *mut c_int, + _h_errnop: *mut c_int, + _ttlp: *mut i32, ) -> nss_status { todo!() } diff --git a/tests/common.rs b/tests/common.rs index 854bb99..4e6b9cb 100644 --- a/tests/common.rs +++ b/tests/common.rs @@ -1,11 +1,15 @@ // SPDX-FileCopyrightText: 2022 Matteo Settenvini // 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 { anyhow::{ensure, Result}, + std::env, std::ffi::CString, - std::os::raw::c_int, - std::os::unix::fs::symlink, std::path::PathBuf, std::sync::Once, }; @@ -15,33 +19,27 @@ 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; + let out_dir = PathBuf::from(env!("OUT_DIR")); + let nss_config_status = unsafe { 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 + library_filename.push(".2"); // required for NSS 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()); + std::fs::copy(library_path, dest).unwrap(); }); - ensure!( - NSS_CONFIG_STATUS == 0, - "Unable to configure NSS to load module: __nss_configure_lookup() returned {}", - NSS_CONFIG_STATUS - ); - Ok(()) - } + 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!( + 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 index 97bccc5..493ccc5 100644 --- a/tests/integration_test.rs +++ b/tests/integration_test.rs @@ -3,13 +3,33 @@ mod common; -use anyhow::Result; +use { + anyhow::{bail, Result}, + libc::{freeaddrinfo, gai_strerror, getaddrinfo}, +}; #[test] -fn nss_module_is_loaded() -> Result<()> { - use std::net::ToSocketAddrs; +#[should_panic(expected = "not yet implemented")] +fn nss_module_is_loaded() { + common::setup().unwrap(); - common::setup()?; - "www.google.com:443".to_socket_addrs()?; - Ok(()) + let hostname = std::ffi::CString::new("gnome.org").unwrap(); + unsafe { + 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() + ) + } + } + }; }