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

Refactor locking, kb interactive changes and add authorized_keys api #448

Merged
merged 12 commits into from
Dec 6, 2023
25 changes: 12 additions & 13 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -59,15 +59,15 @@ endif()
# micro version is changed with a set of small changes or bugfixes anywhere in the project.
set(LIBNETCONF2_MAJOR_VERSION 3)
set(LIBNETCONF2_MINOR_VERSION 0)
set(LIBNETCONF2_MICRO_VERSION 2)
set(LIBNETCONF2_MICRO_VERSION 3)
set(LIBNETCONF2_VERSION ${LIBNETCONF2_MAJOR_VERSION}.${LIBNETCONF2_MINOR_VERSION}.${LIBNETCONF2_MICRO_VERSION})

# Version of the library
# Major version is changed with every backward non-compatible API/ABI change in libyang, minor version changes
# with backward compatible change and micro version is connected with any internal change of the library.
set(LIBNETCONF2_MAJOR_SOVERSION 4)
set(LIBNETCONF2_MINOR_SOVERSION 0)
set(LIBNETCONF2_MICRO_SOVERSION 2)
set(LIBNETCONF2_MINOR_SOVERSION 1)
set(LIBNETCONF2_MICRO_SOVERSION 0)
set(LIBNETCONF2_SOVERSION_FULL ${LIBNETCONF2_MAJOR_SOVERSION}.${LIBNETCONF2_MINOR_SOVERSION}.${LIBNETCONF2_MICRO_SOVERSION})
set(LIBNETCONF2_SOVERSION ${LIBNETCONF2_MAJOR_SOVERSION})

Expand Down Expand Up @@ -160,8 +160,7 @@ set(format_sources
examples/*.h*
src/*.c
src/*.h
tests/*.c
tests/pam/*.c)
tests/*.c)

#
# checks
Expand Down Expand Up @@ -225,6 +224,9 @@ target_link_libraries(netconf2 ${CMAKE_THREAD_LIBS_INIT})
set(CMAKE_REQUIRED_LIBRARIES pthread)
check_function_exists(pthread_rwlockattr_setkind_np HAVE_PTHREAD_RWLOCKATTR_SETKIND_NP)

# header file compatibility - shadow.h
check_include_file("shadow.h" HAVE_SHADOW)

if(ENABLE_SSH_TLS)
# dependencies - openssl
find_package(OpenSSL 3.0.0 REQUIRED)
Expand Down Expand Up @@ -255,18 +257,15 @@ if(ENABLE_SSH_TLS)
if(LibPAM_FOUND)
set(HAVE_LIBPAM TRUE)

# enable PAM test if a PAM header file contains a declaration of a function pam_start_confdir
if (LIBPAM_HAVE_CONFDIR)
message(STATUS "LibPAM found, version >= 1.4, enabled PAM tests")
else()
message(STATUS "LibPAM found, version < 1.4, disabled PAM tests")
endif()

target_link_libraries(netconf2 ${LIBPAM_LIBRARIES})
list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBPAM_LIBRARIES})
include_directories(${LIBPAM_INCLUDE_DIRS})

message(STATUS "SSH Keyboard Interactive system method: Linux PAM")
elseif(HAVE_SHADOW)
message(STATUS "SSH Keyboard Interactive system method: local users")
else()
message(WARNING "LibPAM not found, PAM-based keyboard-interactive SSH server authentication method is disabled")
message(WARNING "SSH Keyboard Interactive system method: disabled")
endif()

# set compiler flag
Expand Down
9 changes: 0 additions & 9 deletions CMakeModules/FindLibPAM.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,6 @@
# LIBPAM_FOUND - system has LibPAM
# LIBPAM_INCLUDE_DIRS - the LibPAM include directory
# LIBPAM_LIBRARIES - link these to use LibPAM
# LIBPAM_HAVE_CONFDIR - LibPAM version >= 1.4
#
# Author Roman Janota <[email protected]>
# Copyright (c) 2022 CESNET, z.s.p.o.
Expand Down Expand Up @@ -63,14 +62,6 @@ else()

if(LIBPAM_INCLUDE_DIR AND LIBPAM_LIBRARY)
set(LIBPAM_FOUND TRUE)
# there is no reliable way to check the version of PAM, so see if the declaration of a function pam_start_confdir
# is in the header file (added in PAM 1.4)
file(STRINGS ${LIBPAM_INCLUDE_DIR}/security/pam_appl.h PAM_CONFDIR REGEX "pam_start_confdir")
if ("${PAM_CONFDIR}" STREQUAL "")
set(LIBPAM_HAVE_CONFDIR FALSE)
else()
set(LIBPAM_HAVE_CONFDIR TRUE)
endif()
else()
set(LIBPAM_FOUND FALSE)
endif()
Expand Down
18 changes: 15 additions & 3 deletions doc/libnetconf.doc
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,9 @@
*
* - ::nc_server_set_capab_withdefaults()
* - ::nc_server_set_capability()
* - ::nc_server_endpt_count()
* - ::nc_server_add_endpt_unix_socket_listen()
* - ::nc_server_del_endpt_unix_socket()
*
* Server Configuration
* ===
Expand Down Expand Up @@ -348,8 +351,7 @@
*
* If you wish not to create the __YANG data__ yourself, you may use the library's functions to do this for you.
* For example ::nc_server_config_add_address_port() creates __YANG data__ corresponding to an SSH/TLS endpoint.
* The variant for UNIX socket is ::nc_server_config_add_unix_socket(). You can then apply this data
* by calling ::nc_server_config_setup_data() (or ::nc_server_config_setup_diff() for diff).
* You can then apply this data by calling ::nc_server_config_setup_data() (or ::nc_server_config_setup_diff() for diff).
* See *examples/server.c* for a simple example.
*
* You may also create entries in the keystore or truststore. For example the asymmetric key and certificate entries
Expand All @@ -368,7 +370,6 @@
* - ::nc_server_config_setup_path()
*
* - ::nc_server_config_add_address_port()
* - ::nc_server_config_add_unix_socket()
* - ::nc_server_config_del_endpt()
* - ::nc_server_config_add_keystore_asym_key()
* - ::nc_server_config_del_keystore_asym_key()
Expand All @@ -390,6 +391,14 @@
* Another option for authorized clients is to reference another endpoint's clients, however be careful not to create a cyclic reference
* (see ::nc_server_config_add_ssh_endpoint_client_ref()). An authorized client MUST authenticate to all of it's configured authentication methods.
*
* \anchor ln2doc_kbdint
* The Keyboard Interactive authentication method is also supported. It can be done in three ways.
* If libpam is found, Linux PAM is used to handle the authentication. You need to specify the service name using ::nc_server_ssh_set_pam_conf_filename().
* Else if the standard functions for accessing local users are found on the system, they are used. The only Keyboard Interactive challenge will be the given
* user's password (that is if he's found on the system).
* Either way, you can always define your own callback to perform the authentication, see ::nc_server_ssh_set_interactive_auth_clb().
* The callback has a higher priority than the other two methods.
*
* There are also some other optional settings.
*
* Functions List
Expand All @@ -414,6 +423,9 @@
* - ::nc_server_config_add_ssh_endpoint_client_ref()
* - ::nc_server_config_del_ssh_endpoint_client_ref()
*
* - ::nc_server_ssh_set_pam_conf_filename()
* - ::nc_server_ssh_set_interactive_auth_clb()
*
* TLS
* ===
*
Expand Down
95 changes: 46 additions & 49 deletions modules/[email protected]
Original file line number Diff line number Diff line change
Expand Up @@ -265,35 +265,46 @@ module libnetconf2-netconf-server {
"Grouping for the SSH Keyboard interactive authentication method.";

container keyboard-interactive {
presence "Indicates that PAM configuration file name has been configured.
This statement is present so the mandatory descendant
nodes do not imply that this node must be
configured.";
presence "Indicates that the given client supports the SSH Keyboard Interactive authentication method.";
description
"Keyboard interactive SSH authentication method.";
leaf pam-config-file-name {
type string;

reference
"RFC 4256:
Roytak marked this conversation as resolved.
Show resolved Hide resolved
Generic Message Exchange Authentication for
the Secure Shell Protocol (SSH)";

choice method {
mandatory true;
}
leaf pam-config-file-dir {
type string;
description
"Method to perform the authentication with.";

container use-system-auth {
presence
"Indicates that the system will handle the authentication.";

description
"Authentication is done using the system's mechanisms.";
}
}
}
}

grouping endpoint-reference-grouping {
description
"Reference to another endpoint. The purpose is to use the referenced endpoint's authentication mechanisms.
If a connection occurs on an endpoint, the connecting user will be tried to be authenticated
using the given endpoint's defined methods. If the user wasn't authenticated and the endpoint
references another endpoint, the authentication will be tried again. However, this time
using the referenced endpoint's mechanisms. The references can be
multiple, however there must not be a cycle.";
"Grouping for the endpoint reference.";

leaf endpoint-reference {
type leafref {
path "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:name";
}
description
"Reference to another endpoint. The purpose is to use the referenced endpoint's authentication mechanisms.
If a connection occurs on an endpoint, the connecting user will be tried to be authenticated
using the given endpoint's defined methods. If the user wasn't authenticated and the endpoint
references another endpoint, the authentication will be tried again. However, this time
using the referenced endpoint's mechanisms. The references can be
multiple, however there must not be a cycle.";
}
}

Expand Down Expand Up @@ -357,67 +368,53 @@ module libnetconf2-netconf-server {
}
}

augment "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:transport/ncs:ssh/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication" {
augment "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:transport/ncs:ssh" +
"/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication" {
uses ssh-authentication-params-grouping;
}

augment "/ncs:netconf-server/ncs:call-home/ncs:netconf-client/ncs:endpoints/ncs:endpoint/ncs:transport/ncs:ssh/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication" {
augment "/ncs:netconf-server/ncs:call-home/ncs:netconf-client/ncs:endpoints" +
"/ncs:endpoint/ncs:transport/ncs:ssh/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication" {
uses ssh-authentication-params-grouping;
}

augment "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:transport/ncs:ssh/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication/ncs:users/ncs:user" {
augment "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:transport/ncs:ssh" +
"/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication/ncs:users/ncs:user" {
uses keyboard-interactive-grouping;
}

augment "/ncs:netconf-server/ncs:call-home/ncs:netconf-client/ncs:endpoints/ncs:endpoint/ncs:transport/ncs:ssh/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication/ncs:users/ncs:user" {
augment "/ncs:netconf-server/ncs:call-home/ncs:netconf-client/ncs:endpoints" +
"/ncs:endpoint/ncs:transport/ncs:ssh/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication/ncs:users/ncs:user" {
uses keyboard-interactive-grouping;
}

augment "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:transport" {
case unix-socket {
container unix-socket {
description
"Defines a new transport called UNIX socket.";
leaf path {
type string;
mandatory true;
}
leaf mode {
type string {
pattern '[0124567]{3}';
}
}
leaf uid {
type uint16;
}
leaf gid {
type uint16;
}
}
}
}

augment "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:transport/ncs:ssh/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication" {
augment "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:transport/ncs:ssh" +
"/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication" {
uses endpoint-reference-grouping;
}

augment "/ncs:netconf-server/ncs:call-home/ncs:netconf-client/ncs:endpoints/ncs:endpoint/ncs:transport/ncs:ssh/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication" {
augment "/ncs:netconf-server/ncs:call-home/ncs:netconf-client/ncs:endpoints" +
"/ncs:endpoint/ncs:transport/ncs:ssh/ncs:ssh/ncs:ssh-server-parameters/ncs:client-authentication" {
uses endpoint-reference-grouping;
}

augment "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:transport/ncs:tls/ncs:tls/ncs:tls-server-parameters/ncs:client-authentication" {
augment "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:transport/ncs:tls" +
"/ncs:tls/ncs:tls-server-parameters/ncs:client-authentication" {
uses endpoint-reference-grouping;
}

augment "/ncs:netconf-server/ncs:call-home/ncs:netconf-client/ncs:endpoints/ncs:endpoint/ncs:transport/ncs:tls/ncs:tls/ncs:tls-server-parameters/ncs:client-authentication" {
augment "/ncs:netconf-server/ncs:call-home/ncs:netconf-client/ncs:endpoints" +
"/ncs:endpoint/ncs:transport/ncs:tls/ncs:tls/ncs:tls-server-parameters/ncs:client-authentication" {
uses endpoint-reference-grouping;
}

augment "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:transport/ncs:tls/ncs:tls/ncs:tls-server-parameters/ncs:client-authentication" {
augment "/ncs:netconf-server/ncs:listen/ncs:endpoint/ncs:transport/ncs:tls" +
"/ncs:tls/ncs:tls-server-parameters/ncs:client-authentication" {
uses certificate-revocation-list-grouping;
}

augment "/ncs:netconf-server/ncs:call-home/ncs:netconf-client/ncs:endpoints/ncs:endpoint/ncs:transport/ncs:tls/ncs:tls/ncs:tls-server-parameters/ncs:client-authentication" {
augment "/ncs:netconf-server/ncs:call-home/ncs:netconf-client/ncs:endpoints" +
"/ncs:endpoint/ncs:transport/ncs:tls/ncs:tls/ncs:tls-server-parameters/ncs:client-authentication" {
uses certificate-revocation-list-grouping;
}
}
10 changes: 0 additions & 10 deletions src/config.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -34,21 +34,11 @@
*/
#cmakedefine HAVE_SHADOW

/*
* Support for crypt.h
*/
#cmakedefine HAVE_CRYPT

/*
* Support for keyboard-interactive SSH authentication method
*/
#cmakedefine HAVE_LIBPAM

/*
* Support for older PAM versions
*/
#cmakedefine LIBPAM_HAVE_CONFDIR

/*
* Location of installed YANG modules on the system
*/
Expand Down
Loading