build UPDATE make libpam an optional dependency
If not available, PAM-based kbint auth is disabled
but the method can still be used if a callback is
set.
Refs #396
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5da86a5..e2013cd 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -261,18 +261,23 @@
endif()
# libpam
- find_package(LibPAM REQUIRED)
+ find_package(LibPAM)
+ 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")
+ # 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})
else()
- message(STATUS "LibPAM found, version < 1.4, disabled PAM tests")
+ message(WARNING "LibPAM not found, PAM-based keyboard-interactive SSH server authentication method is disabled")
endif()
-
- target_link_libraries(netconf2 ${LIBPAM_LIBRARIES})
- list(APPEND CMAKE_REQUIRED_LIBRARIES ${LIBPAM_LIBRARIES})
- include_directories(${LIBPAM_INCLUDE_DIRS})
endif()
# dependencies - libval
diff --git a/src/config.h.in b/src/config.h.in
index 9ccc702..3e134cc 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -1,10 +1,11 @@
/**
* @file config.h
* @author Radek Krejci <rkrejci@cesnet.cz>
+ * @author Michal Vasko <mvasko@cesnet.cz>
* @brief libnetconf2 various configuration settings.
*
* @copyright
- * Copyright (c) 2015 - 2017 CESNET, z.s.p.o.
+ * Copyright (c) 2015 - 2022 CESNET, z.s.p.o.
*
* This source code is licensed under BSD 3-Clause License (the "License").
* You may not use this file except in compliance with the License.
@@ -39,6 +40,11 @@
#cmakedefine HAVE_CRYPT
/*
+ * Support for keyboard-interactive SSH authentication method
+ */
+#cmakedefine HAVE_LIBPAM
+
+/*
* Support for older PAM versions
*/
#cmakedefine LIBPAM_HAVE_CONFDIR
diff --git a/src/session_server_ssh.c b/src/session_server_ssh.c
index 11b347b..9907a33 100644
--- a/src/session_server_ssh.c
+++ b/src/session_server_ssh.c
@@ -23,11 +23,13 @@
#ifdef HAVE_CRYPT
#include <crypt.h>
#endif
+#ifdef HAVE_LIBPAM
+ #include <security/pam_appl.h>
+#endif
#include <errno.h>
#include <fcntl.h>
#include <pwd.h>
-#include <security/pam_appl.h>
#include <stdlib.h>
#include <string.h>
#include <sys/stat.h>
@@ -180,23 +182,24 @@
API int
nc_server_ssh_set_pam_conf_path(const char *conf_name, const char *conf_dir)
{
+#ifdef HAVE_LIBPAM
free(server_opts.conf_name);
free(server_opts.conf_dir);
server_opts.conf_name = NULL;
server_opts.conf_dir = NULL;
if (conf_dir) {
-#ifdef LIBPAM_HAVE_CONFDIR
+# ifdef LIBPAM_HAVE_CONFDIR
server_opts.conf_dir = strdup(conf_dir);
if (!(server_opts.conf_dir)) {
ERRMEM;
return -1;
}
-#else
+# else
ERR(NULL, "Failed to set PAM config directory because of old version of PAM. "
"Put the config file in the system directory (usually /etc/pam.d/).");
return -1;
-#endif
+# endif
}
if (conf_name) {
@@ -208,6 +211,13 @@
}
return 0;
+#else
+ (void)conf_name;
+ (void)conf_dir;
+
+ ERR(NULL, "PAM-based SSH authentication is not supported.");
+ return -1;
+#endif
}
API void
@@ -984,6 +994,8 @@
}
}
+#ifdef HAVE_LIBPAM
+
/**
* @brief PAM conversation function, which serves as a callback for exchanging messages between the client and a PAM module.
*
@@ -1168,13 +1180,13 @@
conv.appdata_ptr = &clb_data;
/* initialize PAM and see if the given configuration file exists */
-#ifdef LIBPAM_HAVE_CONFDIR
+# ifdef LIBPAM_HAVE_CONFDIR
/* PAM version >= 1.4 */
ret = pam_start_confdir(server_opts.conf_name, session->username, &conv, server_opts.conf_dir, &pam_h);
-#else
+# else
/* PAM version < 1.4 */
ret = pam_start(server_opts.conf_name, session->username, &conv, &pam_h);
-#endif
+# endif
if (ret != PAM_SUCCESS) {
ERR(NULL, "PAM error occurred (%s).\n", pam_strerror(pam_h, ret));
goto cleanup;
@@ -1219,6 +1231,8 @@
return ret;
}
+#endif
+
static void
nc_sshcb_auth_kbdint(struct nc_session *session, ssh_message msg)
{
@@ -1226,8 +1240,14 @@
if (server_opts.interactive_auth_clb) {
auth_ret = server_opts.interactive_auth_clb(session, msg, server_opts.interactive_auth_data);
- } else if (nc_pam_auth(session, msg) == PAM_SUCCESS) {
- auth_ret = 0;
+ } else {
+#ifdef HAVE_LIBPAM
+ if (nc_pam_auth(session, msg) == PAM_SUCCESS) {
+ auth_ret = 0;
+ }
+#else
+ ERR(session, "PAM-based SSH authentication is not supported.");
+#endif
}
/* We have already sent a reply */