From 9d4590cf21ea070170908d2c1a27e9880b59b939a607c989c6d34ccf30337f60 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Thu, 19 Mar 2020 10:06:58 +0000 Subject: [PATCH] Accepting request 786335 from home:scarabeus_iv:branches:devel:tools - Add patch to fix crash when testing fprintd: * fix-pam-module-output-crash.patch - Fix build without python2 that is atm being removed from Tumbleweed - Use cmake macros for build OBS-URL: https://build.opensuse.org/request/show/786335 OBS-URL: https://build.opensuse.org/package/show/devel:tools/pam_wrapper?expand=0&rev=24 --- fix-pam-module-output-crash.patch | 321 ++++++++++++++++++++++++++++++ pam_wrapper.changes | 8 + pam_wrapper.spec | 51 ++--- 3 files changed, 348 insertions(+), 32 deletions(-) create mode 100644 fix-pam-module-output-crash.patch diff --git a/fix-pam-module-output-crash.patch b/fix-pam-module-output-crash.patch new file mode 100644 index 0000000..62b4b34 --- /dev/null +++ b/fix-pam-module-output-crash.patch @@ -0,0 +1,321 @@ +From 00fc7d7151408e53728a0df8868ad75dc0c00a7d Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Wed, 22 Jan 2020 11:50:37 +0100 +Subject: [PATCH 1/4] python: Fix crash when the PAM module outputs too much + data + +This code expected each input (whether echo on or echo off input), +to generate at most one info or error output, which is obviously not +correct. A PAM module with external inputs can throw dozens of messages +and warnings even if the only expected input is a password. + +Allocate those placeholder arrays to be as big as possible to accomodate +chatty PAM modules. + +Closes: https://bugzilla.samba.org/show_bug.cgi?id=14245 + +Signed-off-by: Bastien Nocera +--- + src/python/pypamtest.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +diff --git a/src/python/pypamtest.c b/src/python/pypamtest.c +index 905c652..c4d0b07 100644 +--- a/src/python/pypamtest.c ++++ b/src/python/pypamtest.c +@@ -852,8 +852,8 @@ static int fill_conv_data(PyObject *py_echo_off, + return ENOMEM; + } + +- conv_data->out_info = new_conv_list(conv_count); +- conv_data->out_err = new_conv_list(conv_count); ++ conv_data->out_info = new_conv_list(PAM_CONV_MSG_MAX); ++ conv_data->out_err = new_conv_list(PAM_CONV_MSG_MAX); + if (conv_data->out_info == NULL || conv_data->out_err == NULL) { + free_conv_data(conv_data); + return ENOMEM; +-- +2.24.1 + + +From e106274e4195aa3bc5f87d469c5555764b3becf0 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Wed, 22 Jan 2020 12:17:03 +0100 +Subject: [PATCH 2/4] modules: Add pam_chatty module + +Add a simple PAM module that will output "num_lines" lines of PAM info +and/or error output. + +Signed-off-by: Bastien Nocera +--- + src/modules/CMakeLists.txt | 2 +- + src/modules/pam_chatty.c | 176 +++++++++++++++++++++++++++++++++++++ + 2 files changed, 177 insertions(+), 1 deletion(-) + create mode 100644 src/modules/pam_chatty.c + +diff --git a/src/modules/CMakeLists.txt b/src/modules/CMakeLists.txt +index 8e13a0b..e956f4c 100644 +--- a/src/modules/CMakeLists.txt ++++ b/src/modules/CMakeLists.txt +@@ -1,6 +1,6 @@ + project(pam_wrapper-modules C) + +-set(PAM_MODULES pam_matrix pam_get_items pam_set_items) ++set(PAM_MODULES pam_matrix pam_get_items pam_set_items pam_chatty) + + set(PAM_LIBRARIES pam) + if (HAVE_PAM_MISC) +diff --git a/src/modules/pam_chatty.c b/src/modules/pam_chatty.c +new file mode 100644 +index 0000000..5ffed5c +--- /dev/null ++++ b/src/modules/pam_chatty.c +@@ -0,0 +1,176 @@ ++/* ++ * Copyright (c) 2015 Andreas Schneider ++ * Copyright (c) 2015 Jakub Hrozek ++ * Copyright (c) 2020 Bastien Nocera ++ * ++ * This program is free software: you can redistribute it and/or modify ++ * it under the terms of the GNU General Public License as published by ++ * the Free Software Foundation, either version 3 of the License, or ++ * (at your option) any later version. ++ * ++ * This program is distributed in the hope that it will be useful, ++ * but WITHOUT ANY WARRANTY; without even the implied warranty of ++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ++ * GNU General Public License for more details. ++ * ++ * You should have received a copy of the GNU General Public License ++ * along with this program. If not, see . ++ */ ++ ++#include "config.h" ++ ++#include ++#include ++#include ++ ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++#include ++ ++#ifndef discard_const ++#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) ++#endif ++ ++#ifndef discard_const_p ++#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) ++#endif ++ ++#ifdef HAVE_SECURITY_PAM_APPL_H ++#include ++#endif ++#ifdef HAVE_SECURITY_PAM_MODULES_H ++#include ++#endif ++#ifdef HAVE_SECURITY_PAM_EXT_H ++#include ++#endif ++ ++#include "pwrap_compat.h" ++ ++#define VERBOSE_KEY "verbose" ++#define ERROR_KEY "error" ++#define INFO_KEY "info" ++#define NUM_LINES_KEY "num_lines=" ++ ++#define DEFAULT_NUM_LINES 3 ++ ++/* We only return up to 16 messages from the PAM conversation. ++ * Value from src/python/pypamtest.c */ ++#define PAM_CONV_MSG_MAX 16 ++ ++#define PAM_CHATTY_FLG_VERBOSE (1 << 0) ++#define PAM_CHATTY_FLG_ERROR (1 << 1) ++#define PAM_CHATTY_FLG_INFO (1 << 1) ++ ++#ifndef discard_const ++#define discard_const(ptr) ((void *)((uintptr_t)(ptr))) ++#endif ++ ++#ifndef discard_const_p ++#define discard_const_p(type, ptr) ((type *)discard_const(ptr)) ++#endif ++ ++static int pam_chatty_conv(pam_handle_t *pamh, ++ const int msg_style, ++ const char *msg) ++{ ++ int ret; ++ const struct pam_conv *conv; ++ const struct pam_message *mesg[1]; ++ struct pam_response *r; ++ struct pam_message *pam_msg; ++ ++ ret = pam_get_item(pamh, PAM_CONV, (const void **) &conv); ++ if (ret != PAM_SUCCESS) { ++ return ret; ++ } ++ ++ pam_msg = malloc(sizeof(struct pam_message)); ++ if (pam_msg == NULL) { ++ return PAM_BUF_ERR; ++ } ++ ++ pam_msg->msg_style = msg_style; ++ pam_msg->msg = discard_const_p(char, msg); ++ ++ mesg[0] = (const struct pam_message *) pam_msg; ++ ret = conv->conv(1, mesg, &r, conv->appdata_ptr); ++ free(pam_msg); ++ ++ return ret; ++} ++ ++/* Evaluate command line arguments and store info about them in the ++ * pam_matrix context ++ */ ++static unsigned int parse_args(int argc, ++ const char *argv[], ++ unsigned int *num_lines) ++{ ++ unsigned int flags = 0; ++ ++ *num_lines = DEFAULT_NUM_LINES; ++ ++ for (; argc-- > 0; ++argv) { ++ if (strncmp(*argv, NUM_LINES_KEY, strlen(NUM_LINES_KEY)) == 0) { ++ if (*(*argv+strlen(NUM_LINES_KEY)) != '\0') { ++ *num_lines = atoi(*argv+strlen(NUM_LINES_KEY)); ++ if (*num_lines <= DEFAULT_NUM_LINES) ++ *num_lines = DEFAULT_NUM_LINES; ++ if (*num_lines > PAM_CONV_MSG_MAX) ++ *num_lines = PAM_CONV_MSG_MAX; ++ } ++ } else if (strncmp(*argv, VERBOSE_KEY, ++ strlen(VERBOSE_KEY)) == 0) { ++ flags |= PAM_CHATTY_FLG_VERBOSE; ++ } else if (strncmp(*argv, ERROR_KEY, ++ strlen(ERROR_KEY)) == 0) { ++ flags |= PAM_CHATTY_FLG_ERROR; ++ } else if (strncmp(*argv, INFO_KEY, ++ strlen(INFO_KEY)) == 0) { ++ flags |= PAM_CHATTY_FLG_INFO; ++ } ++ } ++ ++ return flags; ++} ++ ++PAM_EXTERN int ++pam_sm_authenticate(pam_handle_t *pamh, int flags, ++ int argc, const char *argv[]) ++{ ++ unsigned int optflags, num_lines; ++ ++ optflags = parse_args (argc, argv, &num_lines); ++ if (!(optflags & PAM_CHATTY_FLG_VERBOSE)) ++ return PAM_SUCCESS; ++ ++ if (optflags & PAM_CHATTY_FLG_INFO) { ++ unsigned int i; ++ ++ for (i = 0; i < num_lines; i++) { ++ pam_chatty_conv(pamh, ++ PAM_TEXT_INFO, ++ "Authentication succeeded"); ++ } ++ } ++ ++ if (optflags & PAM_CHATTY_FLG_ERROR) { ++ unsigned int i; ++ ++ for (i = 0; i < num_lines; i++) { ++ pam_chatty_conv(pamh, ++ PAM_ERROR_MSG, ++ "Authentication generated an error"); ++ } ++ } ++ ++ return PAM_SUCCESS; ++} +-- +2.24.1 + + +From 348ee7d7fe2e426bc099347b37357710e4f1cf47 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Wed, 22 Jan 2020 12:21:05 +0100 +Subject: [PATCH 3/4] tests: Add service file for chatty module + +So we can test it. + +Signed-off-by: Bastien Nocera +--- + tests/CMakeLists.txt | 3 +++ + tests/services/chatty.in | 1 + + 2 files changed, 4 insertions(+) + create mode 100644 tests/services/chatty.in + +diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt +index 997c15e..eb0477c 100644 +--- a/tests/CMakeLists.txt ++++ b/tests/CMakeLists.txt +@@ -22,6 +22,9 @@ configure_file(services/matrix_py.in ${CMAKE_CURRENT_BINARY_DIR}/services/matrix + + configure_file(services/pwrap_get_set.in ${CMAKE_CURRENT_BINARY_DIR}/services/pwrap_get_set @ONLY) + ++set(PAM_CHATTY_PATH "${CMAKE_BINARY_DIR}/src/modules/pam_chatty.so") ++configure_file(services/chatty.in ${CMAKE_CURRENT_BINARY_DIR}/services/chatty @ONLY) ++ + if (OSX) + set(TEST_ENVIRONMENT DYLD_FORCE_FLAT_NAMESPACE=1;DYLD_INSERT_LIBRARIES=${PAM_WRAPPER_LOCATION};PAM_WRAPPER=1;PAM_WRAPPER_SERVICE_DIR=${CMAKE_CURRENT_BINARY_DIR}/services}) + add_definitions(-DOSX) +diff --git a/tests/services/chatty.in b/tests/services/chatty.in +new file mode 100644 +index 0000000..0099b50 +--- /dev/null ++++ b/tests/services/chatty.in +@@ -0,0 +1 @@ ++auth required @PAM_CHATTY_PATH@ verbose num_lines=16 info error +-- +2.24.1 + + +From 3a130534011d4d13399cc7626a0a2b92e90e1ab6 Mon Sep 17 00:00:00 2001 +From: Bastien Nocera +Date: Wed, 22 Jan 2020 12:22:30 +0100 +Subject: [PATCH 4/4] tests: Add test for verbose PAM modules + +Signed-off-by: Bastien Nocera +--- + tests/pypamtest_test.py | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/tests/pypamtest_test.py b/tests/pypamtest_test.py +index 32ef65d..db66490 100755 +--- a/tests/pypamtest_test.py ++++ b/tests/pypamtest_test.py +@@ -115,6 +115,11 @@ class PyPamTestRunTest(unittest.TestCase): + self.assertSequenceEqual(res.info, (u'Authentication succeeded',)) + self.assertSequenceEqual(res.errors, ()) + ++ def test_run_chatty_auth(self): ++ neo_password = "secret" ++ tc = pypamtest.TestCase(pypamtest.PAMTEST_AUTHENTICATE) ++ res = pypamtest.run_pamtest("neo", "chatty", [tc], [ neo_password ]) ++ + def test_repr(self): + tc = pypamtest.TestCase(pypamtest.PAMTEST_CHAUTHTOK, 1, 2) + r = repr(tc) +-- +2.24.1 + diff --git a/pam_wrapper.changes b/pam_wrapper.changes index 278cb98..969b59d 100644 --- a/pam_wrapper.changes +++ b/pam_wrapper.changes @@ -1,3 +1,11 @@ +------------------------------------------------------------------- +Thu Mar 19 08:07:02 UTC 2020 - Tomáš Chvátal + +- Add patch to fix crash when testing fprintd: + * fix-pam-module-output-crash.patch +- Fix build without python2 that is atm being removed from Tumbleweed +- Use cmake macros for build + ------------------------------------------------------------------- Mon Dec 9 15:11:23 UTC 2019 - Andreas Schneider diff --git a/pam_wrapper.spec b/pam_wrapper.spec index 4ad0e75..280d246 100644 --- a/pam_wrapper.spec +++ b/pam_wrapper.spec @@ -1,7 +1,7 @@ # # spec file for package pam_wrapper # -# Copyright (c) 2019 SUSE LLC +# Copyright (c) 2020 SUSE LLC # # All modifications and additions to the file contributed by third parties # remain the property of their copyright owners, unless otherwise agreed @@ -22,31 +22,29 @@ # Do NOT create library package or a devel package! # ############################# NOTE ################################## - +%bcond_without python2 Name: pam_wrapper Version: 1.0.7 Release: 0 - Summary: A tool to test PAM applications and PAM modules License: GPL-3.0-or-later -Group: Development/Libraries/C and C++ -URL: http://cwrap.org/ - +URL: https://cwrap.org/ Source0: https://ftp.samba.org/pub/cwrap/%{name}-%{version}.tar.gz Source1: %{name}-rpmlintrc - Patch0: pam_wrapper-1.0.8-fix_with_latest_pam.patch - +Patch1: fix-pam-module-output-crash.patch BuildRequires: cmake BuildRequires: doxygen BuildRequires: libcmocka-devel BuildRequires: pam-devel +BuildRequires: pkgconfig BuildRequires: python-rpm-macros -BuildRequires: pkgconfig(python2) BuildRequires: pkgconfig(python3) - -Recommends: pkg-config Recommends: cmake +Recommends: pkgconfig +%if %{with python2} +BuildRequires: pkgconfig(python2) +%endif %description This component of cwrap allows you to either test your PAM (Linux-PAM @@ -63,7 +61,6 @@ development/testing. %package -n libpamtest0 Summary: A tool to test PAM applications and PAM modules -Group: Development/Libraries/C and C++ Requires: pam_wrapper = %{version}-%{release} %description -n libpamtest0 @@ -72,12 +69,10 @@ testing of modules. %package -n libpamtest-devel Summary: A tool to test PAM applications and PAM modules -Group: Development/Libraries/C and C++ Requires: libpamtest0 = %{version}-%{release} Requires: pam_wrapper = %{version}-%{release} - -Recommends: pkg-config Recommends: cmake +Recommends: pkgconfig %description -n libpamtest-devel If you plan to develop tests for a PAM module, you can use this library, @@ -86,14 +81,12 @@ files for libpamtest %package -n libpamtest-devel-doc Summary: The libpamtest API documentation -Group: Development/Libraries/C and C++ %description -n libpamtest-devel-doc Documentation for libpamtest development. %package -n python2-libpamtest Summary: A python wrapper for libpamtest -Group: Development/Libraries/C and C++ Requires: libpamtest0 = %{version}-%{release} Requires: pam_wrapper = %{version}-%{release} @@ -104,7 +97,6 @@ the header files for libpamtest %package -n python3-libpamtest Summary: A python wrapper for libpamtest -Group: Development/Libraries/C and C++ Requires: libpamtest0 = %{version}-%{release} Requires: pam_wrapper = %{version}-%{release} @@ -121,9 +113,8 @@ the header files for libpamtest %cmake \ -DUNIT_TESTING=ON \ -DCMAKE_SKIP_RPATH:BOOL=OFF - -make %{?_smp_mflags} VERBOSE=1 -make %{?_smp_mflags} doc +%cmake_build +%cmake_build doc %install %cmake_install @@ -132,15 +123,11 @@ make %{?_smp_mflags} doc %ctest %post -p /sbin/ldconfig - %postun -p /sbin/ldconfig - %post -n libpamtest0 -p /sbin/ldconfig - %postun -n libpamtest0 -p /sbin/ldconfig %files -%defattr(-,root,root) %doc AUTHORS README ChangeLog %license LICENSE %{_libdir}/libpam_wrapper.so* @@ -150,19 +137,18 @@ make %{?_smp_mflags} doc %{_libdir}/cmake/pam_wrapper/pam_wrapper-config.cmake %dir %{_libdir}/pam_wrapper %{_libdir}/pam_wrapper/pam_matrix.so +%{_libdir}/pam_wrapper/pam_chatty.so %{_libdir}/pam_wrapper/pam_get_items.so %{_libdir}/pam_wrapper/pam_set_items.so -%{_mandir}/man1/pam_wrapper.1* -%{_mandir}/man8/pam_matrix.8* -%{_mandir}/man8/pam_get_items.8* -%{_mandir}/man8/pam_set_items.8* +%{_mandir}/man1/pam_wrapper.1%{?ext_man} +%{_mandir}/man8/pam_matrix.8%{?ext_man} +%{_mandir}/man8/pam_get_items.8%{?ext_man} +%{_mandir}/man8/pam_set_items.8%{?ext_man} %files -n libpamtest0 -%defattr(-,root,root,-) %{_libdir}/libpamtest.so.* %files -n libpamtest-devel -%defattr(-,root,root,-) %{_libdir}/libpamtest.so %{_libdir}/pkgconfig/libpamtest.pc %dir %{_libdir}/cmake/libpamtest @@ -171,11 +157,12 @@ make %{?_smp_mflags} doc %{_includedir}/libpamtest.h %files -n libpamtest-devel-doc -%defattr(-,root,root) %doc build/doc/html +%if %{with python2} %files -n python2-libpamtest %{python2_sitearch}/pypamtest.so +%endif %files -n python3-libpamtest %{python3_sitearch}/pypamtest.so