Skip to content

Commit

Permalink
Merge pull request #1171 from CESNET/devel
Browse files Browse the repository at this point in the history
Devel merge
  • Loading branch information
michalvasko authored Mar 15, 2022
2 parents e6cdbb9 + 8ca0394 commit 068ce48
Show file tree
Hide file tree
Showing 59 changed files with 1,798 additions and 3,698 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -179,4 +179,4 @@ jobs:
- name: Test
shell: bash
working-directory: ${{ github.workspace }}/build
run: ctest --output-on-failure
run: ctest --output-on-failure -j4
6 changes: 3 additions & 3 deletions .github/workflows/devel-push.yml
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ jobs:
cd libyang
mkdir build
cd build
CC=${{ matrix.config.cc }} cmake -DCMAKE_BUILD_TYPE=${{ matrix.config.dep-build-type }} -DENABLE_BUILD_TESTS=OFF ..
CC=${{ matrix.config.cc }} cmake -DCMAKE_BUILD_TYPE=${{ matrix.config.dep-build-type }} -DENABLE_TESTS=OFF ..
make -j2
sudo make install
Expand All @@ -110,7 +110,7 @@ jobs:
cd libnetconf2
mkdir build
cd build
CC=${{ matrix.config.cc }} cmake -DCMAKE_BUILD_TYPE=${{ matrix.config.build-type }} -DENABLE_BUILD_TESTS=OFF ..
CC=${{ matrix.config.cc }} cmake -DCMAKE_BUILD_TYPE=${{ matrix.config.build-type }} -DENABLE_TESTS=OFF ..
make -j2
sudo make install
Expand All @@ -137,7 +137,7 @@ jobs:
- name: Test
shell: bash
working-directory: ${{ github.workspace }}/build
run: ctest --output-on-failure
run: ctest --output-on-failure -j4

- name: Upload to Coverity.com
shell: bash
Expand Down
67 changes: 56 additions & 11 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -43,17 +43,24 @@ 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.0.35)
set(NP2SRV_VERSION 2.1.16)

# libyang required SO version
# libyang required version
set(LIBYANG_DEP_VERSION 2.0.128)
set(LIBYANG_DEP_SOVERSION 2.14.0)
set(LIBYANG_DEP_SOVERSION_MAJOR 2)

# Version of sysrepo that this netopeer2 version depends on
set(SYSREPO_DEP_VERSION 2.0.33)
set(SYSREPO_DEP_SOVERSION 6.4.0)
set(SYSREPO_DEP_SOVERSION_MAJOR 6)
# libnetconf2 required version
set(LIBNETCONF2_DEP_VERSION 2.1.3)
set(LIBNETCONF2_DEP_SOVERSION 3.1.0)
set(LIBNETCONF2_DEP_SOVERSION_MAJOR 3)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -std=gnu99")
# sysrepo required version
set(SYSREPO_DEP_VERSION 2.1.36)
set(SYSREPO_DEP_SOVERSION 7.3.0)
set(SYSREPO_DEP_SOVERSION_MAJOR 7)

set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -Wall -Wextra -std=gnu99")

#
# options
Expand All @@ -68,7 +75,6 @@ option(ENABLE_COVERAGE "Build code coverage report from tests" OFF)
option(BUILD_CLI "Build and install neotpeer2-cli" ON)
option(ENABLE_URL "Enable URL capability" ON)
set(THREAD_COUNT 5 CACHE STRING "Number of threads accepting new sessions and handling requests")
set(NACM_RECOVERY_UID 0 CACHE STRING "NACM recovery session UID that has unrestricted access")
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")

Expand Down Expand Up @@ -122,7 +128,6 @@ set(SERVER_SRC
src/common.c
src/netconf.c
src/netconf_monitoring.c
src/netconf_acm.c
src/netconf_nmda.c
src/netconf_subscribed_notifications.c
src/netconf_confirmed_commit.c
Expand Down Expand Up @@ -212,7 +217,7 @@ if(LIBSSH_FOUND)
endif()

# dependencies - libnetconf2 (now, because we need to configure outselves based on it)
find_package(LibNETCONF2 REQUIRED)
find_package(LibNETCONF2 ${LIBNETCONF2_DEP_SOVERSION} REQUIRED)
include_directories(${LIBNETCONF2_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBNETCONF2_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBNETCONF2_LIBRARIES})
Expand Down Expand Up @@ -271,14 +276,28 @@ if(ENABLE_URL)
endif()
endif()

# libsystemd
if(NOT PKG_CONFIG_FOUND AND NOT SYSTEMD_UNIT_DIR)
set(SYSTEMD_UNIT_DIR "/usr/lib/systemd/system")
endif()
find_package(LibSystemd)
if(LIBSYSTEMD_FOUND)
set(NP2SRV_HAVE_SYSTEMD 1)
target_link_libraries(netopeer2-server ${LIBSYSTEMD_LIBRARIES})
include_directories(${LIBSYSTEMD_INCLUDE_DIRS})
message(STATUS "systemd system service unit path: ${SYSTEMD_UNIT_DIR}")
else()
message(WARNING "Disabling netopeer2-server systemd support because libsystemd was not found.")
endif()

# pthread
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
find_package(Threads REQUIRED)
target_link_libraries(netopeer2-server ${CMAKE_THREAD_LIBS_INIT})
list(APPEND CMAKE_REQUIRED_FLAGS ${CMAKE_THREAD_LIBS_INIT})

# libyang
find_package(LibYANG ${LIBYANG_DEP_SOVERSION_MAJOR} REQUIRED)
find_package(LibYANG ${LIBYANG_DEP_SOVERSION} REQUIRED)
target_link_libraries(netopeer2-server ${LIBYANG_LIBRARIES})
include_directories(${LIBYANG_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_INCLUDES ${LIBYANG_INCLUDE_DIRS})
Expand All @@ -291,8 +310,25 @@ include_directories(${SYSREPO_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_INCLUDES ${SYSREPO_INCLUDE_DIRS})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${SYSREPO_LIBRARIES})

# find sysrepoctl to be used for installation and tests
if (NOT SYSREPOCTL_EXECUTABLE)
find_program(SYSREPOCTL_EXECUTABLE sysrepoctl)
endif()
if (NOT SYSREPOCTL_EXECUTABLE)
message(FATAL_ERROR "Unable to find sysrepoctl, set SYSREPOCTL_EXECUTABLE manually.")
endif()

# find sysrepocfg to be used for installation and tests
if (NOT SYSREPOCFG_EXECUTABLE)
find_program(SYSREPOCFG_EXECUTABLE sysrepocfg)
endif()
if (NOT SYSREPOCFG_EXECUTABLE)
message(FATAL_ERROR "Unable to find sysrepocfg, set SYSREPOCFG_EXECUTABLE manually.")
endif()

# generate files
configure_file("${PROJECT_SOURCE_DIR}/src/config.h.in" "${PROJECT_BINARY_DIR}/config.h" ESCAPE_QUOTES @ONLY)
configure_file("${PROJECT_SOURCE_DIR}/service/netopeer2-server.service.in" "${PROJECT_BINARY_DIR}/netopeer2-server.service" @ONLY)
include_directories(${PROJECT_BINARY_DIR})

# set script dir
Expand All @@ -304,13 +340,18 @@ install(DIRECTORY "${PROJECT_SOURCE_DIR}/modules/" DESTINATION ${YANG_MODULE_DIR
# install the binary, required modules, and default configuration
install(TARGETS netopeer2-server DESTINATION ${CMAKE_INSTALL_BINDIR})
install(FILES ${PROJECT_SOURCE_DIR}/doc/netopeer2-server.8 DESTINATION ${CMAKE_INSTALL_MANDIR}/man8)
if(NP2SRV_HAVE_SYSTEMD)
install(FILES ${PROJECT_BINARY_DIR}/netopeer2-server.service DESTINATION ${SYSTEMD_UNIT_DIR})
endif()
if(INSTALL_MODULES)
install(CODE "
message(STATUS \"Installing missing sysrepo modules...\")
set(ENV{NP2_MODULE_DIR} \"${YANG_MODULE_DIR}\")
set(ENV{NP2_MODULE_PERMS} \"${MODULES_PERMS}\")
set(ENV{NP2_MODULE_OWNER} \"${MODULES_OWNER}\")
set(ENV{NP2_MODULE_GROUP} \"${MODULES_GROUP}\")
set(ENV{SYSREPOCTL_EXECUTABLE} \"${SYSREPOCTL_EXECUTABLE}\")
set(ENV{SYSREPOCFG_EXECUTABLE} \"${SYSREPOCFG_EXECUTABLE}\")
execute_process(COMMAND \"${SCRIPT_DIR}/setup.sh\" RESULT_VARIABLE SETUP_RES)
if(NOT SETUP_RES EQUAL \"0\")
message(FATAL_ERROR \" scripts/setup.sh failed: \${SETUP_RES}\")
Expand All @@ -322,6 +363,8 @@ endif()
if(GENERATE_HOSTKEY)
install(CODE "
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 ${SCRIPT_DIR}/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}\")
Expand All @@ -331,6 +374,8 @@ endif()
if(MERGE_LISTEN_CONFIG)
install(CODE "
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 ${SCRIPT_DIR}/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}\")
Expand Down
21 changes: 18 additions & 3 deletions CMakeModules/FindLibNETCONF2.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
# LIBNETCONF2_FOUND - system has LibNETCONF2
# LIBNETCONF2_INCLUDE_DIRS - the LibNETCONF2 include directory
# LIBNETCONF2_LIBRARIES - Link these to use LibNETCONF2
# LIBNETCONF2_VERSION - SO version of the found libNETCONF2 library
# LIBNETCONF2_ENABLED_SSH - LibNETCONF2 was compiled with SSH support
# LIBNETCONF2_ENABLED_TLS - LibNETCONF2 was compiled with TLS support
#
# Author Michal Vasko <[email protected]>
# Copyright (c) 2020 CESNET, z.s.p.o.
# Copyright (c) 2021 CESNET, z.s.p.o.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
Expand All @@ -34,7 +35,6 @@
# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
#
include(FindPackageHandleStandardArgs)
include(CheckSymbolExists)

if(LIBNETCONF2_LIBRARIES AND LIBNETCONF2_INCLUDE_DIRS)
# in cache already
Expand Down Expand Up @@ -68,13 +68,28 @@ else()
${CMAKE_INSTALL_PREFIX}/lib
)

if(LIBNETCONF2_INCLUDE_DIR)
find_path(NC_VERSION_PATH "nc_version.h" HINTS ${LIBNETCONF2_INCLUDE_DIR})
if(NOT NC_VERSION_PATH)
message(STATUS "libnetconf2 version header not found, assuming libnetconf2 is too old and cannot be used!")
set(LIBNETCONF2_INCLUDE_DIR "LIBNETCONF2_INCLUDE_DIR-NOTFOUND")
set(LIBNETCONF2_LIBRARY "LIBNETCONF2_LIBRARY-NOTFOUND")
else()
file(READ "${NC_VERSION_PATH}/nc_version.h" NC_VERSION_FILE)
string(REGEX MATCH "#define NC_VERSION \"[0-9]+\\.[0-9]+\\.[0-9]+\"" NC_VERSION_MACRO "${NC_VERSION_FILE}")
string(REGEX MATCH "[0-9]+\\.[0-9]+\\.[0-9]+" LIBNETCONF2_VERSION "${NC_VERSION_MACRO}")
endif()
endif()

set(LIBNETCONF2_INCLUDE_DIRS ${LIBNETCONF2_INCLUDE_DIR})
set(LIBNETCONF2_LIBRARIES ${LIBNETCONF2_LIBRARY})
mark_as_advanced(LIBNETCONF2_INCLUDE_DIRS LIBNETCONF2_LIBRARIES)

# handle the QUIETLY and REQUIRED arguments and set SYSREPO_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(LibNETCONF2 DEFAULT_MSG LIBNETCONF2_LIBRARY LIBNETCONF2_INCLUDE_DIR)
find_package_handle_standard_args(LibNETCONF2 FOUND_VAR LIBNETCONF2_FOUND
REQUIRED_VARS LIBNETCONF2_LIBRARY LIBNETCONF2_INCLUDE_DIR
VERSION_VAR LIBNETCONF2_VERSION)

# check the configured options and make them available through cmake
list(INSERT CMAKE_REQUIRED_INCLUDES 0 "${LIBNETCONF2_INCLUDE_DIR}")
Expand Down
83 changes: 83 additions & 0 deletions CMakeModules/FindLibSystemd.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
# - Try to find LibSystemd, it is expected find_package(PkgConfig) was called before
#
# Once done this will define
#
# LIBSYSTEMD_FOUND - system has LibSystemd
# LIBSYSTEMD_INCLUDE_DIRS - the LibSystemd include directory
# LIBSYSTEMD_LIBRARIES - link these to use LibSystemd
# SYSTEMD_UNIT_DIR - directory with systemd system unit files
#
# Author Michal Vasko <[email protected]>
# Copyright (c) 2022 CESNET, z.s.p.o.
#
# 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 copyright
# notice, this list of conditions and the following disclaimer.
# 2. Redistributions in binary form must reproduce the copyright
# notice, this list of conditions and the following disclaimer in the
# documentation and/or other materials provided with the distribution.
# 3. The name of the author may not be used to endorse or promote products
# derived from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 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.
#
include(FindPackageHandleStandardArgs)

if(LIBSYSTEMD_LIBRARIES AND LIBSYSTEMD_INCLUDE_DIRS AND SYSTEMD_UNIT_DIR)
# in cache already
set(LIBSYSTEMD_FOUND TRUE)
else()
find_path(LIBSYSTEMD_INCLUDE_DIR
NAMES
systemd/sd-daemon.h
PATHS
/usr/include
/usr/local/include
/opt/local/include
/sw/include
${CMAKE_INCLUDE_PATH}
${CMAKE_INSTALL_PREFIX}/include
)

find_library(LIBSYSTEMD_LIBRARY
NAMES
systemd
libsystemd
PATHS
/usr/lib
/usr/lib64
/usr/local/lib
/usr/local/lib64
/opt/local/lib
/sw/lib
${CMAKE_LIBRARY_PATH}
${CMAKE_INSTALL_PREFIX}/lib
)

if(NOT SYSTEMD_UNIT_DIR)
execute_process(COMMAND ${PKG_CONFIG_EXECUTABLE} --define-variable=rootprefix=${CMAKE_INSTALL_PREFIX} --variable=systemdsystemunitdir systemd
OUTPUT_VARIABLE SYSTEMD_UNIT_DIR)
string(REGEX REPLACE "[ \t\n]+" "" SYSTEMD_UNIT_DIR "${SYSTEMD_UNIT_DIR}")
endif()

set(LIBSYSTEMD_INCLUDE_DIRS ${LIBSYSTEMD_INCLUDE_DIR})
set(LIBSYSTEMD_LIBRARIES ${LIBSYSTEMD_LIBRARY})
mark_as_advanced(LIBSYSTEMD_INCLUDE_DIRS LIBSYSTEMD_LIBRARIES)

# handle the QUIETLY and REQUIRED arguments and set LIBSYSTEMD_FOUND to TRUE
# if all listed variables are TRUE
find_package_handle_standard_args(LibSystemd FOUND_VAR LIBSYSTEMD_FOUND
REQUIRED_VARS LIBSYSTEMD_LIBRARY LIBSYSTEMD_INCLUDE_DIR SYSTEMD_UNIT_DIR)
endif()
31 changes: 11 additions & 20 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ the `distro` directory.

### Optional

* pkg-config & libsystemd (to support `netopeer2-server` systemd service)
* cmocka >= 1.0.1 (for [tests](#Tests))
* valgrind (for enhanced testing)
* gcov (for code coverage)
Expand Down Expand Up @@ -105,29 +106,20 @@ a table with the exact data format.
| 0 | `uint32_t` | NETCONF session ID |
| 1 | `char *` | NETCONF username |

It is also possible to communicate a specific NETCONF error back to the server. The error format must be `NETCONF`
and the meaning of every piece of data corresponds to the [rpc-error](https://tools.ietf.org/html/rfc6241#section-4.3)
elements. All the expected types are strings (`char *`). Arbitrary optional elements can be skipped by being set to
an empty string.

| Index | Mandatory | Name |
|:----- |:---------:|:----:|
| 0 | yes | `error-type` |
| 1 | yes | `error-tag` |
| 2 | yes | `error-message` |
| 3 | no | `error-app-tag` |
| 4 | no | `error-path` |
| n | no | `error-info` element |
| n + 1 | no | `error-info` value |
It is also possible to communicate a specific `NETCONF` error back to the server, use *sysrepo* utility functions
to create it.

### CLI

A command-line NETCONF client `netopeer2-cli` is included and build/installed by default. This can be
A simple command-line NETCONF client `netopeer2-cli` is included and build/installed by default. This can be
adjusted by an option:
```
BUILD_CLI:ON
```

There is also a separate [netconf-cli](https://github.com/CESNET/netconf-cli) project that you may want to
give a try if you need an advanced and more user-friendly command-line NETCONF client.

### Tests

There are several tests included and built with [cmocka](https://cmocka.org/). The tests
Expand Down Expand Up @@ -166,11 +158,10 @@ $ make coverage

## NACM

This NETCONF server implements full *ietf-netconf-acm* access control that **bypasses** *sysrepo*
file system access control. NACM is enabled by default, so users other than `root` will not be
allowed to *write* any data but should be granted *read* and *execute* permissions unless
the access was modified by a NACM extension. When deploying this server, it is strongly advised
to configure NACM properly.
This NETCONF server uses *ietf-netconf-acm* access control of *sysrepo*. NACM is enabled by default,
so except for the recovery user, no others will be allowed to *write* any data but should be granted
*read* and *execute* permissions unless the access was modified by a NACM extension. When deploying
this server, it is strongly advised to configure NACM properly.

## Server configuration

Expand Down
Loading

0 comments on commit 068ce48

Please sign in to comment.