From efd2967e060a3a7ca3de589a23511bb38151ed8b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 24 Feb 2021 12:45:26 +0100 Subject: swrap: introduce a socket_wrapper_noop.so and socket_wrapper.h to provide noop stubs Applications with the need to call socket_wrapper_enabled() should link against -lsocket_wrapper_noop in order to resolve the symbol at link time. BUG: https://bugzilla.samba.org/show_bug.cgi?id=14640 Signed-off-by: Stefan Metzmacher Reviewed-by: Andreas Schneider --- CMakeLists.txt | 10 ++++++ doc/socket_wrapper.1 | 45 +++++++++++++++++-------- doc/socket_wrapper.1.adoc | 23 +++++++++++++ socket_wrapper_noop.pc.cmake | 8 +++++ src/CMakeLists.txt | 32 ++++++++++++++++++ src/socket_wrapper.c | 8 ++--- src/socket_wrapper.h | 64 +++++++++++++++++++++++++++++++++++ src/socket_wrapper_noop.c | 57 +++++++++++++++++++++++++++++++ tests/CMakeLists.txt | 3 +- tests/test_public_functions.c | 78 +++++++++++++++++++++++++++++++++++++++++++ 10 files changed, 310 insertions(+), 18 deletions(-) create mode 100644 socket_wrapper_noop.pc.cmake create mode 100644 src/socket_wrapper.h create mode 100644 src/socket_wrapper_noop.c create mode 100644 tests/test_public_functions.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 13be7fb..8927ebb 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -71,6 +71,16 @@ install( pkgconfig ) +configure_file(socket_wrapper_noop.pc.cmake ${CMAKE_CURRENT_BINARY_DIR}/socket_wrapper_noop.pc @ONLY) +install( + FILES + ${CMAKE_CURRENT_BINARY_DIR}/socket_wrapper_noop.pc + DESTINATION + ${CMAKE_INSTALL_LIBDIR}/pkgconfig + COMPONENT + pkgconfig +) + # cmake config files configure_file(socket_wrapper-config-version.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/socket_wrapper-config-version.cmake @ONLY) configure_file(socket_wrapper-config.cmake.in ${CMAKE_CURRENT_BINARY_DIR}/socket_wrapper-config.cmake @ONLY) diff --git a/doc/socket_wrapper.1 b/doc/socket_wrapper.1 index 0272c63..b6363cd 100644 --- a/doc/socket_wrapper.1 +++ b/doc/socket_wrapper.1 @@ -1,13 +1,13 @@ '\" t .\" Title: socket_wrapper .\" Author: Samba Team -.\" Generator: Asciidoctor 2.0.12 -.\" Date: 2021-02-02 +.\" Generator: Asciidoctor 2.0.10 +.\" Date: 2021-02-24 .\" Manual: \ \& .\" Source: \ \& .\" Language: English .\" -.TH "SOCKET_WRAPPER" "1" "2021-02-02" "\ \&" "\ \&" +.TH "SOCKET_WRAPPER" "1" "2021-02-24" "\ \&" "\ \&" .ie \n(.g .ds Aq \(aq .el .ds Aq ' .ss \n[.ss] 0 @@ -214,54 +214,73 @@ to be usable. .sp .if n .RS 4 .nf -.fam C # Open a console and create a directory for the unix sockets. $ mktemp \-d /tmp/tmp.bQRELqDrhM -.fam .fi .if n .RE .sp .if n .RS 4 .nf -.fam C # Then start nc to listen for network traffic using the temporary directory. $ LD_PRELOAD=libsocket_wrapper.so \(rs SOCKET_WRAPPER_DIR=/tmp/tmp.bQRELqDrhM \(rs SOCKET_WRAPPER_DEFAULT_IFACE=10 nc \-v \-l 127.0.0.10 7 -.fam .fi .if n .RE .sp .if n .RS 4 .nf -.fam C # (If nc, listens on 0.0.0.0 then listener will be open on 127.0.0.10 because # it is the default interface) -.fam .fi .if n .RE .sp .if n .RS 4 .nf -.fam C # Now open another console and start \(aqnc\(aq as a client to connect to the server: $ LD_PRELOAD=libsocket_wrapper.so \(rs SOCKET_WRAPPER_DIR=/tmp/tmp.bQRELqDrhM \(rs SOCKET_WRAPPER_DEFAULT_IFACE=100 nc \-v 127.0.0.10 7 -.fam .fi .if n .RE .sp .if n .RS 4 .nf -.fam C # (The client will use the address 127.0.0.100 when connecting to the server) # Now you can type \(aqHello!\(aq which will be sent to the server and should appear # in the console output of the server. -.fam .fi .if n .RE +.SH "PUBLIC FUNCTIONS" +.sp +Socket wrapper advanced helpers. +.sp +Applications with the need to alter their behaviour when +socket wrapper is active, can link use these functions. +.sp +By default it\(cqs required for applications to use any of these +functions as libsocket_wrapper.so is injected at runtime via +LD_PRELOAD. +.sp +Applications using these functions should link against +libsocket_wrapper_noop.so by using \-lsocket_wrapper_noop, +or implement their own noop stubs. +.sp +#include +.sp +bool socket_wrapper_enabled(void); +.sp +.RS 4 +.ie n \{\ +\h'-04'\(bu\h'+03'\c +.\} +.el \{\ +. sp -1 +. IP \(bu 2.3 +.\} +This returns true when socket wrapper is actively in use. +.RE .SH "RESOURCES" .sp \fBProject web site:\fP \c diff --git a/doc/socket_wrapper.1.adoc b/doc/socket_wrapper.1.adoc index 9519fd4..fd0b745 100644 --- a/doc/socket_wrapper.1.adoc +++ b/doc/socket_wrapper.1.adoc @@ -133,6 +133,29 @@ EXAMPLE # Now you can type 'Hello!' which will be sent to the server and should appear # in the console output of the server. +PUBLIC FUNCTIONS +---------------- + +Socket wrapper advanced helpers. + +Applications with the need to alter their behaviour when +socket wrapper is active, can link use these functions. + +By default it's required for applications to use any of these +functions as libsocket_wrapper.so is injected at runtime via +LD_PRELOAD. + +Applications using these functions should link against +libsocket_wrapper_noop.so by using -lsocket_wrapper_noop, +or implement their own noop stubs. + +#include + +bool socket_wrapper_enabled(void); + +- This returns true when socket wrapper is actively in use. + + RESOURCES --------- diff --git a/socket_wrapper_noop.pc.cmake b/socket_wrapper_noop.pc.cmake new file mode 100644 index 0000000..5c8ac49 --- /dev/null +++ b/socket_wrapper_noop.pc.cmake @@ -0,0 +1,8 @@ +libdir=@CMAKE_INSTALL_FULL_LIBDIR@ +includedir=@CMAKE_INSTALL_FULL_INCLUDEDIR@ + +Name: @PROJECT_NAME@ +Description: The socket_wrapper_noop library +Version: @PROJECT_VERSION@ +Libs: -L${libdir} -lsocket_wrapper_noop +Cflags: -I${includedir} diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 73f8cd0..ac56c86 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -27,3 +27,35 @@ install(TARGETS socket_wrapper ) set(SOCKET_WRAPPER_LOCATION "${CMAKE_CURRENT_BINARY_DIR}/${CMAKE_SHARED_LIBRARY_PREFIX}socket_wrapper${CMAKE_SHARED_LIBRARY_SUFFIX}" PARENT_SCOPE) + +add_library(socket_wrapper_noop SHARED socket_wrapper_noop.c) +target_include_directories(socket_wrapper_noop + PRIVATE + ${CMAKE_BINARY_DIR}) +target_compile_options(socket_wrapper_noop + PRIVATE + ${DEFAULT_C_COMPILE_FLAGS} + -D_GNU_SOURCE) +target_link_libraries(socket_wrapper_noop ${SWRAP_REQUIRED_LIBRARIES} ${CMAKE_THREAD_LIBS_INIT}) +set_target_properties(socket_wrapper_noop + PROPERTIES + VERSION ${LIBRARY_VERSION} + SOVERSION ${LIBRARY_SOVERSION}) +if (DEFINED DEFAULT_LINK_FLAGS) + set_target_properties(socket_wrapper_noop + PROPERTIES + LINK_FLAGS ${DEFAULT_LINK_FLAGS}) +endif() + +install(TARGETS socket_wrapper_noop + RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} + LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} +) + +install( + FILES + ${CMAKE_CURRENT_SOURCE_DIR}/socket_wrapper.h + DESTINATION + ${CMAKE_INSTALL_INCLUDEDIR} +) diff --git a/src/socket_wrapper.c b/src/socket_wrapper.c index 22e0246..63de148 100644 --- a/src/socket_wrapper.c +++ b/src/socket_wrapper.c @@ -2,8 +2,8 @@ * BSD 3-Clause License * * Copyright (c) 2005-2008, Jelmer Vernooij - * Copyright (c) 2006-2018, Stefan Metzmacher - * Copyright (c) 2013-2018, Andreas Schneider + * Copyright (c) 2006-2021, Stefan Metzmacher + * Copyright (c) 2013-2021, Andreas Schneider * Copyright (c) 2014-2017, Michael Adam * Copyright (c) 2016-2018, Anoop C S * All rights reserved. @@ -86,6 +86,8 @@ #endif #include +#include "socket_wrapper.h" + enum swrap_dbglvl_e { SWRAP_LOG_ERROR = 0, SWRAP_LOG_WARN, @@ -392,8 +394,6 @@ static pthread_mutex_t mtu_update_mutex = PTHREAD_MUTEX_INITIALIZER; /* Function prototypes */ -bool socket_wrapper_enabled(void); - #if ! defined(HAVE_CONSTRUCTOR_ATTRIBUTE) && defined(HAVE_PRAGMA_INIT) /* xlC and other oldschool compilers support (only) this */ #pragma init (swrap_constructor) diff --git a/src/socket_wrapper.h b/src/socket_wrapper.h new file mode 100644 index 0000000..f1a97e8 --- /dev/null +++ b/src/socket_wrapper.h @@ -0,0 +1,64 @@ +/* + * BSD 3-Clause License + * + * Copyright (c) 2005-2008, Jelmer Vernooij + * Copyright (c) 2006-2021, Stefan Metzmacher + * Copyright (c) 2013-2021, Andreas Schneider + * Copyright (c) 2014-2017, Michael Adam + * Copyright (c) 2016-2018, Anoop C S + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +#ifndef __SOCKET_WRAPPER_H__ +#define __SOCKET_WRAPPER_H__ 1 + +#include + +/* + Socket wrapper advanced helpers. + + Applications with the need to alter their behaviour when + socket wrapper is active, can link use these functions. + + By default it's required for applications to use any of these + functions as libsocket_wrapper.so is injected at runtime via + LD_PRELOAD. + + Applications using these functions should link against + libsocket_wrapper_noop.so by using -lsocket_wrapper_noop, + or implement their own noop stubs. +*/ + +/* + * This returns true when socket wrapper is actively in use. + */ +bool socket_wrapper_enabled(void); + +#endif /* __SOCKET_WRAPPER_H__ */ diff --git a/src/socket_wrapper_noop.c b/src/socket_wrapper_noop.c new file mode 100644 index 0000000..45aff8f --- /dev/null +++ b/src/socket_wrapper_noop.c @@ -0,0 +1,57 @@ +/* + * BSD 3-Clause License + * + * Copyright (c) 2005-2008, Jelmer Vernooij + * Copyright (c) 2006-2021, Stefan Metzmacher + * Copyright (c) 2013-2021, Andreas Schneider + * Copyright (c) 2014-2017, Michael Adam + * Copyright (c) 2016-2018, Anoop C S + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * 3. Neither the name of the author nor the names of its contributors + * may be used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + */ + +/* + Socket wrapper noop library. + + Applications with the need to alter their behaviour when + socket wrapper is active, can link to this with -lsocket_wrapper_noop + in order to call get the required public functions at link time. + + During runtime these are overloaded with LD_PRELOAD by the real + libsocket_wrapper.so. +*/ + +#include "config.h" +#include "stdbool.h" +#include "socket_wrapper.h" + +bool socket_wrapper_enabled(void) +{ + return false; +} diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index db36bf3..2f98af1 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -56,6 +56,7 @@ set(SWRAP_TESTS test_echo_udp_sendmsg_recvmsg test_swrap_unit test_max_sockets + test_public_functions test_close_failure test_tcp_socket_overwrite ${SWRAP_THREADED_TESTS}) @@ -111,7 +112,7 @@ foreach(_SWRAP_TEST ${SWRAP_TESTS}) add_cmocka_test(${_SWRAP_TEST} SOURCES ${_SWRAP_TEST}.c COMPILE_OPTIONS ${DEFAULT_C_COMPILE_FLAGS} -D_GNU_SOURCE - LINK_LIBRARIES ${TORTURE_LIBRARY} + LINK_LIBRARIES ${TORTURE_LIBRARY} socket_wrapper_noop LINK_OPTIONS ${DEFAULT_LINK_FLAGS}) add_cmocka_test_environment(${_SWRAP_TEST}) endforeach() diff --git a/tests/test_public_functions.c b/tests/test_public_functions.c new file mode 100644 index 0000000..11d03ef --- /dev/null +++ b/tests/test_public_functions.c @@ -0,0 +1,78 @@ +#include "torture.h" + +#include +#include +#include +#include +#include + +#include + +static int setup_enabled(void **state) +{ + torture_setup_socket_dir(state); + + return 0; +} + +static int teardown_enabled(void **state) +{ + torture_teardown_socket_dir(state); + + return 0; +} + +static int setup_disabled(void **state) +{ + (void) state; /* unused */ + + unsetenv("SOCKET_WRAPPER_DIR"); + unsetenv("SOCKET_WRAPPER_DEFAULT_IFACE"); + unsetenv("SOCKET_WRAPPER_PCAP_FILE"); + + return 0; +} + +static int teardown_disabled(void **state) +{ + (void) state; /* unused */ + + return 0; +} + +static void test_call_enabled_true(void **state) +{ + char *s = getenv("SOCKET_WRAPPER_DIR"); + + (void) state; /* unused */ + + assert_true(socket_wrapper_enabled()); + assert_true(s != NULL); +} + +static void test_call_enabled_false(void **state) +{ + char *s = getenv("SOCKET_WRAPPER_DIR"); + + (void) state; /* unused */ + + assert_false(socket_wrapper_enabled()); + assert_false(s != NULL); +} + +int main(void) { + int rc; + + const struct CMUnitTest max_sockets_tests[] = { + cmocka_unit_test_setup_teardown(test_call_enabled_true, + setup_enabled, + teardown_enabled), + cmocka_unit_test_setup_teardown(test_call_enabled_false, + setup_disabled, + teardown_disabled), + }; + + rc = cmocka_run_group_tests(max_sockets_tests, NULL, NULL); + + return rc; +} -- cgit