Skip to content
Commits on Source (10)
test_task:
container:
matrix:
image: registry.fedoraproject.org/fedora:rawhide
image: registry.fedoraproject.org/fedora:latest
image: centos:centos7
image: centos:centos6
build_script: tests/build.sh
config_script: tests/config.sh
run_httpd_background_script: /usr/sbin/httpd -DFOREGROUND
test_script: tests/run.sh
.git
tests/Dockerfile
language: generic
sudo: required
services:
- docker
install: true
stages:
- build-and-test
matrix:
include:
- stage: build-and-test
env: fedora=rawhide
- stage: build-and-test
env: fedora=28
- stage: build-and-test
env: centos=centos7
- stage: build-and-test
env: centos=centos6
before_script:
- if test -n "$fedora" ; then sed -i "s#^FROM.*#FROM registry.fedoraproject.org/fedora:$fedora#" tests/Dockerfile ; fi
- if test -n "$centos" ; then sed -i "s#^FROM.*#FROM centos:$centos#" tests/Dockerfile ; fi
script:
- docker build -t mod_authnz_pam -f tests/Dockerfile .
- docker run --name mod_authnz_pam --rm -d mod_authnz_pam
- docker exec mod_authnz_pam tests/run.sh
......@@ -111,7 +111,7 @@ should build and install the module.
License
-------
Copyright 2014--2016 Jan Pazdziora
Copyright 2014--2018 Jan Pazdziora
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
......
/*
* Copyright 2014--2016 Jan Pazdziora
* Copyright 2014--2018 Jan Pazdziora
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
......@@ -17,7 +17,9 @@
#include <security/pam_appl.h>
#include "apr_general.h"
#include "apr_strings.h"
#include "apr_md5.h"
#include "ap_config.h"
#include "ap_provider.h"
......@@ -142,6 +144,34 @@ module AP_MODULE_DECLARE_DATA authnz_pam_module;
#define SHOW_MODULE "mod_authnz_pam: "
#endif
#if AP_MODULE_MAGIC_AT_LEAST(20100625,0)
static APR_OPTIONAL_FN_TYPE(ap_authn_cache_store) *authn_cache_store = NULL;
// copied from socache implementations of dbm and dbd @ http://svn.eu.apache.org/viewvc?view=revision&revision=957072
static void opt_retr(void) {
authn_cache_store = APR_RETRIEVE_OPTIONAL_FN(ap_authn_cache_store);
}
void store_password_to_cache(request_rec * r, const char * login, const char * password) {
if (!(authn_cache_store && login && password)) {
return;
}
unsigned char salt[16];
char hash[61];
if (apr_generate_random_bytes(salt, sizeof(salt)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
SHOW_MODULE "apr_generate_random_bytes failed, will not cache password");
return;
}
if (apr_bcrypt_encode(password, 5, salt, sizeof(salt), hash, sizeof(hash)) != APR_SUCCESS) {
ap_log_rerror(APLOG_MARK, APLOG_WARNING, 0, r,
SHOW_MODULE "apr_bcrypt_encode failed, will not cache password");
return;
}
authn_cache_store(r, "PAM", login, NULL, hash);
}
#endif
#define _REMOTE_USER_ENV_NAME "REMOTE_USER"
#define _EXTERNAL_AUTH_ERROR_ENV_NAME "EXTERNAL_AUTH_ERROR"
#define _PAM_STEP_AUTH 1
......@@ -167,6 +197,11 @@ static authn_status pam_authenticate_with_login_password(request_rec * r, const
param = login;
stage = "PAM authentication failed for user";
ret = pam_authenticate(pamh, PAM_SILENT | PAM_DISALLOW_NULL_AUTHTOK);
#if AP_MODULE_MAGIC_AT_LEAST(20100625,0)
if (ret == PAM_SUCCESS) {
store_password_to_cache(r, login, password);
}
#endif
}
if ((ret == PAM_SUCCESS) && (steps & _PAM_STEP_ACCOUNT)) {
param = login;
......@@ -275,6 +310,9 @@ static void register_hooks(apr_pool_t * p) {
ap_hook_auth_checker(check_user_access, NULL, NULL, APR_HOOK_MIDDLE);
#endif
APR_REGISTER_OPTIONAL_FN(pam_authenticate_with_login_password);
#if AP_MODULE_MAGIC_AT_LEAST(20100625,0)
ap_hook_optional_fn_retrieve(opt_retr, NULL, NULL, APR_HOOK_MIDDLE);
#endif
}
#ifdef AP_DECLARE_MODULE
......
......@@ -7,12 +7,13 @@
Summary: PAM authorization checker and PAM Basic Authentication provider
Name: mod_authnz_pam
Version: 1.1.0
Version: 1.2.0
Release: 1%{?dist}
License: ASL 2.0
Group: System Environment/Daemons
URL: http://www.adelton.com/apache/mod_authnz_pam/
Source0: http://www.adelton.com/apache/mod_authnz_pam/%{name}-%{version}.tar.gz
BuildRequires: gcc
BuildRequires: httpd-devel
BuildRequires: pam-devel
BuildRequires: pkgconfig
......@@ -63,10 +64,19 @@ install -Dp -m 0644 authnz_pam.confx $RPM_BUILD_ROOT%{_httpd_confdir}/authnz_pam
%{_httpd_moddir}/*.so
%changelog
* Tue Jul 17 2018 Jan Pazdziora <jpazdziora@redhat.com> - 1.2.0-1
- Add support for mod_authn_socache.
* Fri Feb 23 2018 Jan Pazdziora <jpazdziora@redhat.com> - 1.1.0-8
- https://fedoraproject.org/wiki/Packaging:C_and_C%2B%2B#BuildRequires_and_Requires
* Fri Feb 09 2018 Igor Gnatenko <ignatenkobrain@fedoraproject.org> - 1.1.0-7
- Escape macros in %%changelog
* Tue Nov 22 2016 Jan Pazdziora <jpazdziora@redhat.com> - 1.1.0-1
- Logging improvements; success logging moved from notice to info level.
- Fix redirect for AuthPAMExpiredRedirect with Basic Auth.
- Fix AuthPAMExpiredRedirect %s escaping on Apache 2.2.
- Fix AuthPAMExpiredRedirect %%s escaping on Apache 2.2.
* Mon Mar 21 2016 Jan Pazdziora <jpazdziora@redhat.com> - 1.0.2-1
- 1319166 - the Requires(pre) httpd does not seem to be needed.
......
FROM registry.fedoraproject.org/fedora
COPY . /src/
WORKDIR /src
RUN tests/build.sh
RUN tests/config.sh
ENTRYPOINT [ "/usr/sbin/httpd", "-DFOREGROUND" ]
LoadModule authn_socache_module modules/mod_authn_socache.so
ScriptAlias /authn-cached /var/www/cgi-bin/auth.cgi
<Location /authn-cached>
AuthBasicProvider socache PAM
AuthnCacheProvideFor PAM
AuthnCacheTimeout 10
</Location>
#!/bin/bash
echo "Content-Type: text/plain"
echo "Pragma: no-cache"
echo
if [ -n "$REMOTE_USER" ] ; then
echo "User $REMOTE_USER."
else
echo "Not authenticated."
fi
LoadModule authnz_pam_module modules/mod_authnz_pam.so
ScriptAlias /authz /var/www/cgi-bin/auth.cgi
<Location /authz>
AuthType Basic
AuthName "private area"
AuthBasicProvider file
AuthUserFile /etc/htpasswd
Require pam-account web
</Location>
ScriptAlias /authn /var/www/cgi-bin/auth.cgi
<LocationMatch ^/authn>
AuthType Basic
AuthName "private area"
AuthBasicProvider PAM
AuthPAMService web
Require valid-user
</LocationMatch>
#!/bin/bash
set -e
set -x
DNF=yum
BUILDDEP_PROVIDER=yum-utils
BUILDDEP=yum-builddep
if type dnf 2> /dev/null ; then
DNF=dnf
BUILDDEP_PROVIDER='dnf-command(builddep)'
BUILDDEP='dnf builddep'
fi
$DNF install -y rpm-build "$BUILDDEP_PROVIDER"
$BUILDDEP -y mod_authnz_pam.spec
NAME_VERSION=$( rpm -q --qf '%{name}-%{version}\n' --specfile mod_authnz_pam.spec | head -1 )
mkdir .$NAME_VERSION
cp -rp * .$NAME_VERSION
mv .$NAME_VERSION $NAME_VERSION
mkdir -p ~/rpmbuild/SOURCES
tar cvzf ~/rpmbuild/SOURCES/$NAME_VERSION.tar.gz $NAME_VERSION
rpmbuild -bb --define "dist $( rpm --eval '%{dist}' ).localbuild" mod_authnz_pam.spec
$DNF install -y ~/rpmbuild/RPMS/*/$NAME_VERSION-*.localbuild.*.rpm
#!/bin/bash
set -e
set -x
sed -i 's/^MaxClients.*/MaxClients 1/' /etc/httpd/conf/httpd.conf
mkdir -p /etc/pam-auth
cp -p tests/auth.cgi /var/www/cgi-bin/auth.cgi
cp -p tests/pam-exec /usr/bin/pam-exec
cp tests/pam-web /etc/pam.d/web
chmod a+x /var/log/httpd
touch /var/log/httpd/pam_exec.log
chown apache /var/log/httpd/pam_exec.log
cp tests/auth.conf /etc/httpd/conf.d/
if rpm -ql httpd | grep mod_authn_socache ; then
cat tests/auth-socache.conf >> /etc/httpd/conf.d/auth.conf
fi
htpasswd -bc /etc/htpasswd alice Tajnost
#!/bin/bash
echo "$0: $PAM_TYPE $PAM_USER"
if [ "$PAM_TYPE" == 'auth' ] || [ "$PAM_TYPE" == 'account' ] ; then
PAM_FILE="/etc/pam-auth/$PAM_USER"
if ! [ -f $PAM_FILE ] ; then
echo "No [$PAM_FILE] for user [$PAM_USER]" >&2
exit 2
fi
if [ $PAM_TYPE == 'account' ] ; then
# For account check, existing file is enough to allow access
echo "$0: account [$PAM_USER] ok"
exit 0
fi
# For auth, we compare the passwords
read PASSWORD
read CHECK_PASSWORD < $PAM_FILE
if [ "$PASSWORD" == "$CHECK_PASSWORD" ] ; then
echo "$0: auth [$PAM_USER] ok"
exit 0
fi
echo "Provided password [$PASSWORD] does not match expected [$CHECK_PASSWORD]" >&2
exit 3
fi
echo "Unsupported PAM_TYPE [$PAM_TYPE]" >&2
exit 4
auth optional pam_exec.so debug expose_authtok log=/var/log/httpd/pam_exec.log /usr/bin/pam-exec
account required pam_exec.so debug log=/var/log/httpd/pam_exec.log /usr/bin/pam-exec
#!/bin/bash
set -e
set -x
echo "Wait for the HTTP server to start ..."
for i in $( seq 1 10 ) ; do
if curl -s -o /dev/null http://localhost/ ; then
break
fi
sleep 3
done
echo "Testing Require pam-account"
curl -s -D /dev/stdout -o /dev/null http://localhost/authz | tee /dev/stderr | grep 401
curl -u alice:Tajnost -s -D /dev/stdout -o /dev/null http://localhost/authz | tee /dev/stderr | grep 401
touch /etc/pam-auth/alice
curl -u alice:Tajnost -s http://localhost/authz | tee /dev/stderr | grep 'User alice'
echo "Testing AuthBasicProvider PAM"
curl -s -D /dev/stdout -o /dev/null http://localhost/authn | tee /dev/stderr | grep 401
curl -u bob:Secret -s -D /dev/stdout -o /dev/null http://localhost/authn | tee /dev/stderr | grep 401
touch /etc/pam-auth/bob
curl -u bob:Secret -s -D /dev/stdout -o /dev/null http://localhost/authn | tee /dev/stderr | grep 401
echo Secret > /etc/pam-auth/bob
curl -u bob:Secret -s http://localhost/authn | tee /dev/stderr | grep 'User bob'
echo Secret2 > /etc/pam-auth/bob
curl -u bob:Secret -s -D /dev/stdout -o /dev/null http://localhost/authn | tee /dev/stderr | grep 401
if rpm -ql httpd | grep mod_authn_socache ; then
echo "Testing AuthBasicProvider socache PAM + AuthnCacheProvideFor PAM"
curl -s -D /dev/stdout -o /dev/null http://localhost/authn | tee /dev/stderr | grep 401
curl -u bob:Secret -s -D /dev/stdout -o /dev/null http://localhost/authn-cached | tee /dev/stderr | grep 401
echo Secret > /etc/pam-auth/bob
curl -u bob:Secret -s http://localhost/authn-cached | tee /dev/stderr | grep 'User bob'
echo Secret2 > /etc/pam-auth/bob
curl -u bob:Secret -s -D /dev/stdout -o /dev/null http://localhost/authn | tee /dev/stderr | grep 401
curl -u bob:Secret -s http://localhost/authn-cached | tee /dev/stderr | grep 'User bob'
sleep 11
curl -u bob:Secret -s -D /dev/stdout -o /dev/null http://localhost/authn-cached | tee /dev/stderr | grep 401
fi