Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add back unix socket option and call api directly when creating unix endpoint #1505

Merged
merged 4 commits into from
Dec 7, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -46,16 +46,16 @@ endif()
# Generic version of not only the library. Major version is reserved for really big changes of the project,
# minor version changes with added functionality (new tool, functionality of the tool or library, ...) and
# micro version is changed with a set of small changes or bugfixes anywhere in the project.
set(NP2SRV_VERSION 2.2.4)
set(NP2SRV_VERSION 2.2.5)

# libyang required version
set(LIBYANG_DEP_VERSION 2.1.87)
set(LIBYANG_DEP_SOVERSION 2.37.1)
set(LIBYANG_DEP_SOVERSION_MAJOR 2)

# libnetconf2 required version
set(LIBNETCONF2_DEP_VERSION 3.0.0)
set(LIBNETCONF2_DEP_SOVERSION 4.0.0)
set(LIBNETCONF2_DEP_VERSION 3.0.3)
set(LIBNETCONF2_DEP_SOVERSION 4.1.0)
set(LIBNETCONF2_DEP_SOVERSION_MAJOR 4)

# sysrepo required version
Expand All @@ -80,7 +80,7 @@ option(ENABLE_URL "Enable URL capability" ON)
set(THREAD_COUNT 3 CACHE STRING "Number of threads accepting new sessions and handling requests")
set(POLL_IO_TIMEOUT 10 CACHE STRING "Timeout in milliseconds of polling sessions for new data. It is also used for synchronization of low level IO such as sending a reply while a notification is being sent")
set(YANG_MODULE_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/yang/modules/netopeer2" CACHE STRING "Directory where to copy the YANG modules to")
set(SCRIPT_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/netopeer2" CACHE STRING "Directory where to copy the install scripts to")
set(DATA_DIR "${CMAKE_INSTALL_PREFIX}/${CMAKE_INSTALL_DATADIR}/netopeer2" CACHE STRING "Directory with shared netopeer2 data")

# script options
option(INSTALL_MODULES "Install required modules into sysrepo" ON)
Expand Down Expand Up @@ -341,7 +341,8 @@ include_directories(${PROJECT_BINARY_DIR})

# install the modules and scripts
install(DIRECTORY "${PROJECT_SOURCE_DIR}/modules/" DESTINATION ${YANG_MODULE_DIR})
install(DIRECTORY "${PROJECT_SOURCE_DIR}/scripts/" DESTINATION ${SCRIPT_DIR} USE_SOURCE_PERMISSIONS)
install(DIRECTORY "${PROJECT_SOURCE_DIR}/scripts/" DESTINATION ${DATA_DIR}/scripts USE_SOURCE_PERMISSIONS)
install(DIRECTORY "${PROJECT_SOURCE_DIR}/pam/" DESTINATION ${DATA_DIR}/pam USE_SOURCE_PERMISSIONS)

# install the binary, required modules, and default configuration
install(TARGETS netopeer2-server DESTINATION ${CMAKE_INSTALL_SBINDIR})
Expand All @@ -359,7 +360,7 @@ if(INSTALL_MODULES)
set(ENV{LN2_MODULE_DIR} \"${LN2_YANG_MODULE_DIR}\")
set(ENV{SYSREPOCTL_EXECUTABLE} \"${SYSREPOCTL_EXECUTABLE}\")
set(ENV{SYSREPOCFG_EXECUTABLE} \"${SYSREPOCFG_EXECUTABLE}\")
execute_process(COMMAND \"\$ENV{DESTDIR}${SCRIPT_DIR}/setup.sh\" RESULT_VARIABLE SETUP_RES)
execute_process(COMMAND \"\$ENV{DESTDIR}${DATA_DIR}/scripts/setup.sh\" RESULT_VARIABLE SETUP_RES)
if(NOT SETUP_RES EQUAL \"0\")
message(FATAL_ERROR \" scripts/setup.sh failed: \${SETUP_RES}\")
endif()
Expand All @@ -373,7 +374,7 @@ if(GENERATE_HOSTKEY)
message(STATUS \"Generating a new RSA host key \\\"genkey\\\" if not already added...\")
set(ENV{SYSREPOCTL_EXECUTABLE} \"${SYSREPOCTL_EXECUTABLE}\")
set(ENV{SYSREPOCFG_EXECUTABLE} \"${SYSREPOCFG_EXECUTABLE}\")
execute_process(COMMAND \"\$ENV{DESTDIR}${SCRIPT_DIR}/merge_hostkey.sh\" RESULT_VARIABLE MERGE_HOSTKEY_RES)
execute_process(COMMAND \"\$ENV{DESTDIR}${DATA_DIR}/scripts/merge_hostkey.sh\" RESULT_VARIABLE MERGE_HOSTKEY_RES)
if(NOT MERGE_HOSTKEY_RES EQUAL \"0\")
message(FATAL_ERROR \" scripts/merge_hostkey.sh failed: \${MERGE_HOSTKEY_RES}\")
endif()
Expand All @@ -384,7 +385,7 @@ if(MERGE_LISTEN_CONFIG)
message(STATUS \"Merging default server listen configuration if there is none...\")
set(ENV{SYSREPOCTL_EXECUTABLE} \"${SYSREPOCTL_EXECUTABLE}\")
set(ENV{SYSREPOCFG_EXECUTABLE} \"${SYSREPOCFG_EXECUTABLE}\")
execute_process(COMMAND \"\$ENV{DESTDIR}${SCRIPT_DIR}/merge_config.sh\" RESULT_VARIABLE MERGE_CONFIG_RES)
execute_process(COMMAND \"\$ENV{DESTDIR}${DATA_DIR}/scripts/merge_config.sh\" RESULT_VARIABLE MERGE_CONFIG_RES)
if(NOT MERGE_CONFIG_RES EQUAL \"0\")
message(FATAL_ERROR \" scripts/merge_config.sh failed: \${MERGE_CONFIG_RES}\")
endif()
Expand Down Expand Up @@ -417,7 +418,7 @@ add_custom_target(cleancache
)

# uninstall
add_custom_target(uninstall ${SCRIPT_DIR}/remove.sh
add_custom_target(uninstall ${DATA_DIR}/scripts/remove.sh
COMMAND "${CMAKE_COMMAND}" -P "${CMAKE_MODULE_PATH}/uninstall.cmake"
COMMENT "Removing netopeer2 modules from sysrepo..."
)
11 changes: 11 additions & 0 deletions pam/netopeer2.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#%PAM-1.0
auth requisite pam_nologin.so
auth include common-auth
account requisite pam_nologin.so
account include common-account
password include common-password
session required pam_loginuid.so
session include common-session
session optional pam_keyinit.so force revoke
session optional pam_lastlog.so showfailed
session optional pam_motd.so
20 changes: 7 additions & 13 deletions scripts/merge_config.sh
Original file line number Diff line number Diff line change
Expand Up @@ -68,19 +68,13 @@ if [ -f "$AUTHORIZED_KEYS_FILE" ]; then
echo "-- Added user \"${CURRENT_USER}\" that can authenticate with a key pair from his authorized_keys to the server configuration..."
echo "--"
else
# authorized_keys doesn't exist, get the user's pw hash from /etc/shadow and use that for authentication
CURRENT_USER_PW_HASH=$(awk -v user="$CURRENT_USER" -F':' '$1 == user {print $2}' /etc/shadow)
if [ -n "$CURRENT_USER_PW_HASH" ]; then
# only add the user if his password hash is not empty
AUTH_CONFIG="<password>${CURRENT_USER_PW_HASH}</password>"
echo "--"
echo "-- Added user \"${CURRENT_USER}\" that can authenticate with his password to the server configuration..."
echo "--"
else
echo "--"
echo "-- No user was added to the server configuration, you will need to add one manually..."
echo "--"
fi
# authorized_keys file doesn't exist, leave the authentication to the system
AUTH_CONFIG="<keyboard-interactive xmlns=\"urn:cesnet:libnetconf2-netconf-server\">
<use-system-auth/>
</keyboard-interactive>"
echo "--"
echo "-- Added user \"${CURRENT_USER}\" that can authenticate with his password to the server configuration..."
echo "--"
fi

if [ -n "$AUTH_CONFIG" ]; then
Expand Down
6 changes: 6 additions & 0 deletions scripts/remove.sh
Original file line number Diff line number Diff line change
Expand Up @@ -70,3 +70,9 @@ SCTL_MODULES=`$SYSREPOCTL -l`
# uninstall np2 and ln2 modules
UNINSTALL_CMD "${NP2_MODULES[@]}"
UNINSTALL_CMD "${LN2_MODULES[@]}"

# remove PAM service file if it exists
if [ -f "/etc/pam.d/netopeer2.conf" ]; then
echo "-- Removing PAM service file /etc/pam.d/netopeer2.conf"
rm /etc/pam.d/netopeer2.conf
fi
12 changes: 12 additions & 0 deletions scripts/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -140,3 +140,15 @@ if [ ! -z "${CMD_INSTALL}" ]; then
exit $rc
fi
fi

# copy the PAM service file to /etc/pam.d
if [ ! -d "/etc/pam.d" ]; then
echo "-- Skipping PAM service file /etc/pam.d/netopeer2.conf, because directory /etc/pam.d not found"
elif [ -f "/etc/pam.d/netopeer2.conf" ]; then
echo "-- Skipping PAM service file /etc/pam.d/netopeer2.conf, because it already exists"
elif [ ! -w "/etc/pam.d" ]; then
echo "-- Skipping PAM service file /etc/pam.d/netopeer2.conf, because of no write permission"
else
echo "-- Installing PAM service file to /etc/pam.d/netopeer2.conf"
cp ../pam/netopeer2.conf /etc/pam.d/
fi
2 changes: 1 addition & 1 deletion src/common.c
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@
#include "log.h"
#include "netconf_monitoring.h"

struct np2srv np2srv = {0};
struct np2srv np2srv = {.unix_mode = -1, .unix_uid = -1, .unix_gid = -1};

int
np_ignore_rpc(sr_session_ctx_t *ev_sess, sr_event_t event, int *rc)
Expand Down
5 changes: 5 additions & 0 deletions src/common.h
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,11 @@ struct np2srv {
sr_subscription_ctx_t *sr_nacm_stats_sub; /**< sysrepo NACM global stats subscription context */
sr_subscription_ctx_t *sr_notif_sub; /**< sysrepo notification subscription context */

const char *unix_path; /**< path to the UNIX socket to listen on */
mode_t unix_mode; /**< UNIX socket mode */
uid_t unix_uid; /**< UNIX socket UID */
gid_t unix_gid; /**< UNIX socket GID */

uint32_t sr_timeout; /**< timeout in ms for all sysrepo functions */
const char *ext_data_path; /**< path to the data file with data for LY ext data callback */

Expand Down
55 changes: 54 additions & 1 deletion src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -601,6 +601,12 @@ server_init(void)
#ifdef NC_ENABLED_SSH_TLS
/* set ln2 call home call backs and data */
nc_server_ch_set_dispatch_data(np2srv_acquire_ctx_cb, np2srv_release_ctx_cb, np2srv.sr_conn, np2srv_new_session_cb, NULL);

/* set PAM service name */
if (nc_server_ssh_set_pam_conf_filename("netopeer2.conf")) {
ERR("Setting PAM configuration filename failed.");
goto error;
}
#endif /* NC_ENABLED_SSH_TLS */

/* set capabilities for the NETCONF Notifications */
Expand All @@ -615,6 +621,14 @@ server_init(void)
/* set libnetconf2 global PRC callback */
nc_set_global_rpc_clb(np2srv_rpc_cb);

/* UNIX socket */
if (np2srv.unix_path) {
if (nc_server_add_endpt_unix_socket_listen("unix", np2srv.unix_path, np2srv.unix_mode,
np2srv.unix_uid, np2srv.unix_gid)) {
goto error;
}
}

/* restore a previous confirmed commit if restore file exists */
ncc_try_restore();

Expand Down Expand Up @@ -1061,6 +1075,8 @@ main(int argc, char *argv[])
int daemonize = 1, verb = 0;
const char *pidfile = NP2SRV_PID_FILE_PATH;
char *ptr;
struct passwd *pwd;
struct group *grp;
struct sigaction action;
sigset_t block_mask;

Expand All @@ -1087,7 +1103,7 @@ main(int argc, char *argv[])
np2srv.server_dir = SERVER_DIR;

/* process command line options */
while ((c = getopt(argc, argv, "dFhVp:f:t:x:v:c:")) != -1) {
while ((c = getopt(argc, argv, "dFhVp:f:U::m:u:g:t:x:v:c:")) != -1) {
switch (c) {
case 'd':
daemonize = 0;
Expand Down Expand Up @@ -1138,6 +1154,43 @@ main(int argc, char *argv[])
case 'f':
np2srv.server_dir = optarg;
break;
case 'U':
/* optional argument */
if (!optarg && (optind < argc) && (argv[optind][0] != '-')) {
/* assume the parameter is the optional argument */
optarg = argv[optind++];
}
np2srv.unix_path = optarg ? optarg : NP2SRV_UNIX_SOCK_PATH;
break;
case 'm':
np2srv.unix_mode = strtoul(optarg, &ptr, 8);
if (*ptr || (np2srv.unix_mode > 0777)) {
ERR("Invalid UNIX socket mode \"%s\".", optarg);
return EXIT_FAILURE;
}
break;
case 'u':
np2srv.unix_uid = strtoul(optarg, &ptr, 10);
if (*ptr) {
pwd = getpwnam(optarg);
if (!pwd) {
ERR("Invalid UNIX socket UID/user \"%s\".", optarg);
return EXIT_FAILURE;
}
np2srv.unix_uid = pwd->pw_uid;
}
break;
case 'g':
np2srv.unix_gid = strtoul(optarg, &ptr, 10);
if (*ptr) {
grp = getgrnam(optarg);
if (!grp) {
ERR("Invalid UNIX socket GID/group \"%s\".", optarg);
return EXIT_FAILURE;
}
np2srv.unix_gid = grp->gr_gid;
}
break;
case 't':
np2srv.sr_timeout = strtoul(optarg, &ptr, 10);
if (*ptr) {
Expand Down
19 changes: 2 additions & 17 deletions tests/np_test.c
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,8 @@ np_glob_setup_np2(void **state, const char *test_name, const char **modules)
close(fd);

/* exec the server */
execl(NP_BINARY_DIR "/netopeer2-server", NP_BINARY_DIR "/netopeer2-server", "-d", "-v3", "-t10", "-p", pidfile_path, "-f", server_dir, "-x", extdata_path, NULL);
execl(NP_BINARY_DIR "/netopeer2-server", NP_BINARY_DIR "/netopeer2-server", "-d", "-v3", "-t10", "-p", pidfile_path,
"-U", sock_path, "-m 600", "-f", server_dir, "-x", extdata_path, NULL);

child_error:
printf("Child execution failed\n");
Expand Down Expand Up @@ -283,22 +284,6 @@ np_glob_setup_np2(void **state, const char *test_name, const char **modules)
return 1;
}

/* prepare UNIX socket data for server configuration in the data store */
if (sr_set_item_str(st->sr_sess, "/ietf-netconf-server:netconf-server/listen/endpoint[name='unix']/libnetconf2-netconf-server:unix-socket/path", sock_path, NULL, 0) != SR_ERR_OK) {
SETUP_FAIL_LOG;
return 1;
}
if (sr_set_item_str(st->sr_sess, "/ietf-netconf-server:netconf-server/listen/endpoint[name='unix']/libnetconf2-netconf-server:unix-socket/mode", "600", NULL, 0) != SR_ERR_OK) {
SETUP_FAIL_LOG;
return 1;
}

/* apply the configuration */
if (sr_apply_changes(st->sr_sess, 0)) {
SETUP_FAIL_LOG;
return 1;
}

/* acquire context */
if (!(st->ctx = sr_acquire_context(st->conn))) {
SETUP_FAIL_LOG;
Expand Down