build: initial skeleton

Add initial build system integration.
This commit is contained in:
Matteo Settenvini 2025-02-21 18:55:16 +01:00
commit be565d948b
Signed by: matteo
GPG key ID: 1C1B12600D81DE05
37 changed files with 3870 additions and 0 deletions

28
crates/nss/Cargo.toml Normal file
View file

@ -0,0 +1,28 @@
# SPDX-FileCopyrightText: Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
# SPDX-License-Identifier: CC0-1.0
[package]
name = "parental-ctrls-nss"
description = "linux-parental-controls: NSS module to block DNS queries to adult domains"
license = { workspace = true }
edition = { workspace = true }
version = { workspace = true }
authors = { workspace = true }
homepage = { workspace = true }
repository = { workspace = true }
[lib]
name = "nss_parental_ctrls"
path = "src/lib.rs"
crate-type = ["cdylib"]
[profile.release]
panic = "unwind" # We rely on this
[build-dependencies]
bindgen = { workspace = true }
[dependencies]
libc = { workspace = true }
nix = { workspace = true }

30
crates/nss/build.rs Normal file
View file

@ -0,0 +1,30 @@
// SPDX-FileCopyrightText: Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// SPDX-License-Identifier: EUPL-1.2
use {std::env, std::path::PathBuf};
fn main() {
println!("cargo:rerun-if-changed=wrapper.hpp");
// Required by NSS
println!("cargo:rustc-cdylib-link-arg=-Wl,-soname,libnss_parental_ctrls.so.2");
let bindings = bindgen::Builder::default()
.header("wrapper.hpp")
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.newtype_enum("nss_status")
.allowlist_type("nss_status")
.newtype_enum("HErrno")
.allowlist_type("HErrno")
.newtype_enum("EaiRetcode")
.allowlist_type("EaiRetcode")
.allowlist_type("gaih_addrtuple")
.allowlist_function("__nss_configure_lookup")
.generate()
.expect("Unable to generate bindings");
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_path.join("bindings.rs"))
.expect("Couldn't write bindings!");
}

View file

@ -0,0 +1,8 @@
// SPDX-FileCopyrightText: Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// SPDX-License-Identifier: EUPL-1.2
pub fn set_if_valid<T>(ptr: *mut T, val: T) {
if !ptr.is_null() {
unsafe { *ptr = val };
}
}

133
crates/nss/src/lib.rs Normal file
View file

@ -0,0 +1,133 @@
// SPDX-FileCopyrightText: 2022 Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// SPDX-License-Identifier: EUPL-1.2
mod helpers;
mod nss_bindings;
use {
crate::helpers::set_if_valid,
crate::nss_bindings::{HErrno, gaih_addrtuple, nss_status},
libc::{AF_INET, hostent, size_t, socklen_t},
nix::errno::Errno,
std::os::raw::{c_char, c_int, c_void},
std::ptr,
};
// -------------- by host ---------------
#[unsafe(no_mangle)]
pub extern "C" fn _nss_parental_ctrls_gethostbyname4_r(
_name: *const c_char,
_pat: *mut *mut gaih_addrtuple,
_buffer: *mut c_char,
_buflen: size_t,
_errnop: *mut Errno,
_h_errnop: *mut HErrno,
_ttlp: *mut i32,
) -> nss_status {
todo!()
}
#[unsafe(no_mangle)]
pub extern "C" fn _nss_parental_ctrls_gethostbyname3_r(
_name: *const c_char,
_af: c_int,
_host: *mut hostent,
_buffer: *mut c_char,
_buflen: size_t,
_errnop: *mut Errno,
_h_errnop: *mut HErrno,
_ttlp: *mut i32,
_canonp: *mut *mut char,
) -> nss_status {
todo!()
}
#[unsafe(no_mangle)]
pub extern "C" fn _nss_parental_ctrls_gethostbyname2_r(
name: *const c_char,
af: c_int,
host: *mut hostent,
buffer: *mut c_char,
buflen: size_t,
errnop: *mut Errno,
h_errnop: *mut HErrno,
) -> nss_status {
_nss_parental_ctrls_gethostbyname3_r(
name,
af,
host,
buffer,
buflen,
errnop,
h_errnop,
ptr::null_mut(),
ptr::null_mut(),
)
}
#[unsafe(no_mangle)]
pub extern "C" fn _nss_parental_ctrls_gethostbyname_r(
name: *const c_char,
host: *mut hostent,
buffer: *mut c_char,
buflen: size_t,
errnop: *mut Errno,
h_errnop: *mut HErrno,
) -> nss_status {
_nss_parental_ctrls_gethostbyname3_r(
name,
AF_INET,
host,
buffer,
buflen,
errnop,
h_errnop,
ptr::null_mut(),
ptr::null_mut(),
)
}
// ----------------- by addr -----------------
#[unsafe(no_mangle)]
pub extern "C" fn _nss_parental_ctrls_gethostbyaddr2_r(
_addr: *const c_void,
_len: socklen_t,
_af: c_int,
_host: *mut hostent,
_buffer: *mut c_char,
_buflen: size_t,
errnop: *mut Errno,
h_errnop: *mut HErrno,
_ttlp: *mut i32,
) -> nss_status {
set_if_valid(errnop, Errno::from_raw(0));
set_if_valid(h_errnop, HErrno::Success);
todo!()
}
#[unsafe(no_mangle)]
pub extern "C" fn _nss_parental_ctrls_gethostbyaddr_r(
addr: *const c_void,
len: socklen_t,
af: c_int,
host: *mut hostent,
buffer: *mut c_char,
buflen: size_t,
errnop: *mut Errno,
h_errnop: *mut HErrno,
) -> nss_status {
_nss_parental_ctrls_gethostbyaddr2_r(
addr,
len,
af,
host,
buffer,
buflen,
errnop,
h_errnop,
ptr::null_mut(),
)
}

View file

@ -0,0 +1,7 @@
// SPDX-FileCopyrightText: Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
// SPDX-License-Identifier: EUPL-1.2
#![allow(dead_code)]
#![allow(non_camel_case_types)]
#![allow(non_upper_case_globals)]
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));

43
crates/nss/wrapper.hpp Normal file
View file

@ -0,0 +1,43 @@
/*
* SPDX-FileCopyrightText: Matteo Settenvini <matteo.settenvini@montecristosoftware.eu>
* SPDX-License-Identifier: EUPL-1.2
*/
#include <nss.h>
#include <netdb.h>
// Work around enums in netdb.h defined as macros instead :-p
enum class HErrno {
Success = 0,
HostNotFound = HOST_NOT_FOUND,
TryAgain = TRY_AGAIN,
NoRecovery = NO_RECOVERY,
NoData = NO_DATA,
#ifdef __USE_MISC
Internal = NETDB_INTERNAL,
#endif
};
enum class EaiRetcode {
Success = 0,
BadFlags = EAI_BADFLAGS,
NoName = EAI_NONAME,
Fail = EAI_FAIL,
Family = EAI_FAMILY,
SockType = EAI_SOCKTYPE,
Service = EAI_SERVICE,
Memory = EAI_MEMORY,
System = EAI_SYSTEM,
Overflow = EAI_OVERFLOW,
#ifdef __USE_GNU
NoData = EAI_NODATA,
AddrFamily = EAI_ADDRFAMILY,
InProgress = EAI_INPROGRESS,
Canceled = EAI_CANCELED,
NotCanceled = EAI_NOTCANCELED,
AllDone = EAI_ALLDONE,
Interrupted = EAI_INTR,
IdnEncode = EAI_IDN_ENCODE,
#endif /* __USE_GNU */
};