merge r802: require at least one service function to have succeeded.

merge r803: introduce strlset() and use it to clear authentication tokens
merge r804: remove keywords from text files
merge r805: include CVE numbers in change log
merge r806: prepare to release Ourouparia


git-svn-id: svn+ssh://svn.openpam.org/svn/openpam/branches/nooath@807 185d5e19-27fe-0310-9dcf-9bff6b9f3609
This commit is contained in:
Dag-Erling Smørgrav 2014-09-09 09:41:32 +00:00
parent bdb75a6c92
commit 89f5473b9d
15 changed files with 145 additions and 29 deletions

View file

@ -48,5 +48,3 @@ ideas:
Takanori Saneto <sanewo@ba2.so-net.ne.jp>
Wojciech A. Koszek <wkoszek@freebsd.org>
Yar Tikhiy <yar@freebsd.org>
$Id$

15
HISTORY
View file

@ -1,8 +1,15 @@
OpenPAM ?????????? 2014-??-??
OpenPAM Ourouparia 2014-09-11
- ENHANCE: When executing a chain, require at least one service
function to succeed. This mitigates fail-open scenarios caused by
misconfigurations or missing modules.
- ENHANCE: Make sure to overwrite buffers which may have contained an
authentication token when they're no longer needed.
- BUGFIX: Under certain circumstances, specifying a non-existent
module (or misspelling the name of a module) in a policy could
result in a fail-open scenario.
result in a fail-open scenario. (CVE-2014-3879)
- FEATURE: Add a search path for modules. This was implemented in
Nummularia but inadvertantly left out of the release notes.
@ -111,7 +118,7 @@ OpenPAM Lycopsida 2011-12-18
module before loading it.
- ENHANCE: added / improved input validation in many cases, including
the policy file and some function arguments.
the policy file and some function arguments. (CVE-2011-4122)
============================================================================
OpenPAM Hydrangea 2007-12-21
@ -441,5 +448,3 @@ Fixed a number of bugs in the previous release, including:
OpenPAM Calamite 2002-02-09
First (beta) release.
============================================================================
$Id$

View file

@ -54,5 +54,3 @@
directory:
# make install
$Id$

View file

@ -31,5 +31,3 @@ 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.
$Id$

2
README
View file

@ -23,5 +23,3 @@ These are some of OpenPAM's features:
this will be made configurable in a future release.
Please direct bug reports and inquiries to <des@des.no>.
$Id$

View file

@ -1,6 +1,6 @@
Release notes for OpenPAM ????????
==================================
Release notes for OpenPAM Ourouparia
====================================
This release corresponds to the code used in FreeBSD HEAD as of the
release date, and is also expected to work on almost any POSIX-like
@ -20,5 +20,3 @@ The distribution consists of the following components:
- Unit tests for limited portions of the libraries.
Please direct bug reports and inquiries to <des@des.no>.
$Id$

2
TODO
View file

@ -13,5 +13,3 @@ Before the next release:
wrapper for) openpam_log() which respects the PAM_SILENT flag and
the no_warn module option. This would eliminate the need for
FreeBSD's _pam_verbose_error().
$Id$

View file

@ -85,7 +85,7 @@ AC_CHECK_FUNCS([asprintf vasprintf])
AC_CHECK_FUNCS([dlfunc fdlopen])
AC_CHECK_FUNCS([fpurge])
AC_CHECK_FUNCS([setlogmask])
AC_CHECK_FUNCS([strlcat strlcmp strlcpy])
AC_CHECK_FUNCS([strlcat strlcmp strlcpy strlset])
saved_LIBS="${LIBS}"
LIBS=""

View file

@ -39,7 +39,7 @@
#define SECURITY_OPENPAM_VERSION_H_INCLUDED
#define OPENPAM
#define OPENPAM_VERSION 20130907
#define OPENPAM_RELEASE "Nummularia"
#define OPENPAM_VERSION 20140911
#define OPENPAM_RELEASE "Ourouparia"
#endif /* !SECURITY_OPENPAM_VERSION_H_INCLUDED */

View file

@ -18,6 +18,7 @@ noinst_HEADERS = \
openpam_strlcat.h \
openpam_strlcmp.h \
openpam_strlcpy.h \
openpam_strlset.h \
openpam_vasprintf.h
libpam_la_SOURCES = \
@ -44,9 +45,10 @@ libpam_la_SOURCES = \
openpam_set_option.c \
openpam_set_feature.c \
openpam_static.c \
openpam_straddch.c \
openpam_strlcat.c \
openpam_strlcpy.c \
openpam_straddch.c \
openpam_strlset.c \
openpam_subst.c \
openpam_vasprintf.c \
openpam_ttyconv.c \

View file

@ -63,7 +63,7 @@ openpam_dispatch(pam_handle_t *pamh,
int flags)
{
pam_chain_t *chain;
int err, fail, r;
int err, fail, nsuccess, r;
int debug;
ENTER();
@ -101,7 +101,9 @@ openpam_dispatch(pam_handle_t *pamh,
}
/* execute */
for (err = fail = 0; chain != NULL; chain = chain->next) {
err = PAM_SUCCESS;
fail = nsuccess = 0;
for (; chain != NULL; chain = chain->next) {
if (chain->module->func[primitive] == NULL) {
openpam_log(PAM_LOG_ERROR, "%s: no %s()",
chain->module->path, pam_sm_func_name[primitive]);
@ -126,7 +128,8 @@ openpam_dispatch(pam_handle_t *pamh,
if (r == PAM_IGNORE)
continue;
if (r == PAM_SUCCESS) {
if (r == PAM_SUCCESS) {
++nsuccess;
/*
* For pam_setcred() and pam_chauthtok() with the
* PAM_PRELIM_CHECK flag, treat "sufficient" as
@ -148,7 +151,7 @@ openpam_dispatch(pam_handle_t *pamh,
* fail. If a required module fails, record the
* return code from the first required module to fail.
*/
if (err == 0)
if (err == PAM_SUCCESS)
err = r;
if ((chain->flag == PAM_REQUIRED ||
chain->flag == PAM_BINDING) && !fail) {
@ -170,6 +173,18 @@ openpam_dispatch(pam_handle_t *pamh,
if (!fail && err != PAM_NEW_AUTHTOK_REQD)
err = PAM_SUCCESS;
/*
* Require the chain to be non-empty, and at least one module
* in the chain to be successful, so that we don't fail open.
*/
if (err == PAM_SUCCESS && nsuccess < 1) {
openpam_log(PAM_LOG_ERROR,
"all modules were unsuccessful for %s()",
pam_sm_func_name[primitive]);
err = PAM_SYSTEM_ERR;
}
RETURNC(err);
}

View file

@ -0,0 +1,58 @@
/*-
* Copyright (c) 2011-2012 Dag-Erling Smørgrav
* All rights reserved.
*
* 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 above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
*
* $Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifndef HAVE_STRLSET
#include <stddef.h>
#include "openpam_strlset.h"
/*
* like memset(3), but stops at the first NUL byte and NUL-terminates the
* result. Returns the number of bytes that were written, not including
* the terminating NUL.
*/
size_t
openpam_strlset(char *str, int ch, size_t size)
{
size_t len;
for (len = 0; *str && size > 1; ++len, --size)
*str++ = ch;
*str = '\0';
return (++len);
}
#endif

View file

@ -0,0 +1,41 @@
/*-
* Copyright (c) 2011 Dag-Erling Smørgrav
* All rights reserved.
*
* 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 above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above 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 AND CONTRIBUTORS ``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 OR CONTRIBUTORS 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.
*
* $Id$
*/
#ifndef OPENPAM_STRLSET_H_INCLUDED
#define OPENPAM_STRLSET_H_INCLUDED
#ifndef HAVE_STRLSET
size_t openpam_strlset(char *, int, size_t);
#undef strlset
#define strlset(arg, ...) openpam_strlset(arg, __VA_ARGS__)
#endif
#endif

View file

@ -55,6 +55,7 @@
#include <security/pam_appl.h>
#include "openpam_impl.h"
#include "openpam_strlset.h"
int openpam_ttyconv_timeout = 0;
@ -366,7 +367,7 @@ openpam_ttyconv(int n,
fail:
for (i = 0; i < n; ++i) {
if (aresp[i].resp != NULL) {
memset(aresp[i].resp, 0, strlen(aresp[i].resp));
strlset(aresp[i].resp, 0, PAM_MAX_RESP_SIZE);
FREE(aresp[i].resp);
}
}

View file

@ -48,6 +48,7 @@
#include <security/openpam.h>
#include "openpam_impl.h"
#include "openpam_strlset.h"
static const char authtok_prompt[] = "Password:";
static const char authtok_prompt_remote[] = "Password for %u@%h:";
@ -140,16 +141,21 @@ pam_get_authtok(pam_handle_t *pamh,
if (twice) {
r = pam_prompt(pamh, style, &resp2, "Retype %s", prompt);
if (r != PAM_SUCCESS) {
strlset(resp, 0, PAM_MAX_RESP_SIZE);
FREE(resp);
RETURNC(r);
}
if (strcmp(resp, resp2) != 0)
if (strcmp(resp, resp2) != 0) {
strlset(resp, 0, PAM_MAX_RESP_SIZE);
FREE(resp);
}
strlset(resp2, 0, PAM_MAX_RESP_SIZE);
FREE(resp2);
}
if (resp == NULL)
RETURNC(PAM_TRY_AGAIN);
r = pam_set_item(pamh, item, resp);
strlset(resp, 0, PAM_MAX_RESP_SIZE);
FREE(resp);
if (r != PAM_SUCCESS)
RETURNC(r);