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 */