Skip to content
GitLab
Projects
Groups
Snippets
Help
Loading...
Help
Help
Support
Community forum
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
S
sso
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
8
Issues
8
List
Boards
Labels
Service Desk
Milestones
Merge Requests
0
Merge Requests
0
Operations
Operations
Incidents
Analytics
Analytics
Repository
Value Stream
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
ai
sso
Commits
ab32b14d
Commit
ab32b14d
authored
Jul 02, 2016
by
godog
Browse files
Options
Browse Files
Download
Plain Diff
Merge branch 'apache24'
parents
66f6744f
cb308bf6
Changes
10
Hide whitespace changes
Inline
Side-by-side
Showing
10 changed files
with
383 additions
and
61 deletions
+383
-61
configure.ac
configure.ac
+4
-19
debian/control
debian/control
+2
-1
src/mod_sso/Makefile.am
src/mod_sso/Makefile.am
+1
-1
src/mod_sso/mod_sso.c
src/mod_sso/mod_sso.c
+298
-31
src/mod_sso/mod_sso.h
src/mod_sso/mod_sso.h
+4
-0
src/mod_sso/test/.gitignore
src/mod_sso/test/.gitignore
+2
-0
src/mod_sso/test/Makefile.am
src/mod_sso/test/Makefile.am
+1
-1
src/mod_sso/test/httpd_integration_test.py
src/mod_sso/test/httpd_integration_test.py
+23
-8
src/mod_sso/test/test-httpd-2.2.conf
src/mod_sso/test/test-httpd-2.2.conf
+0
-0
src/mod_sso/test/test-httpd-2.4.conf
src/mod_sso/test/test-httpd-2.4.conf
+48
-0
No files found.
configure.ac
View file @
ab32b14d
...
...
@@ -5,7 +5,7 @@ AC_LANG(C++)
AM_INIT_AUTOMAKE([dist-bzip2 foreign])
AC_CONFIG_HEADERS(src/sso/config.h)
AC_CONFIG_MACRO_DIR([m4])
AC_DISABLE_SHARED
dnl
AC_DISABLE_SHARED
dnl Program checks.
AC_PROG_CC
...
...
@@ -39,27 +39,12 @@ dnl Checks for apxs.
if test "$build_mod_sso" != "no" ; then
AX_WITH_APXS()
APACHE_CFLAGS="-I`${APXS} -q INCLUDEDIR`"
AC_ARG_WITH(apr_config,
AC_HELP_STRING([[--with-apr-config=FILE]],
[Path to apr-config program]),
[ apr_config="$withval" ],
[AC_PATH_PROGS(apr_config,
[apr-config apr-0-config apr-1-config],
[no],
[$PATH:/usr/sbin/:/usr/local/apache2/bin]
)]
)
if test "$apr_config" != "no" ; then
AC_MSG_CHECKING('APR includes')
APACHE_CFLAGS="$APACHE_CFLAGS -I`${apr_config} --includedir`"
AC_MSG_RESULT($APACHE_CFLAGS)
AC_MSG_CHECKING('APR libs')
APR_LIBS="`${apr_config} --link-libtool --libs`"
AC_MSG_RESULT($APR_LIBS)
fi
AC_SUBST(APACHE_CFLAGS)
APACHE_LIBEXEC_DIR="`${APXS} -q LIBEXECDIR`"
AC_SUBST(APACHE_LIBEXEC_DIR)
PKG_CHECK_MODULES(APR, [apr-1, apr-util-1])
AC_SUBST(APR_CFLAGS)
AC_SUBST(APR_LIBS)
fi
AM_CONDITIONAL(ENABLE_MOD_SSO, [ test "$build_mod_sso" != "no" ])
...
...
debian/control
View file @
ab32b14d
...
...
@@ -4,7 +4,8 @@ Priority: extra
Maintainer: Autistici/Inventati <debian@autistici.org>
Build-Depends: debhelper (>= 5), apache2-prefork-dev | apache2-threaded-dev,
autoconf, automake, libtool, python-dev, python-support, swig,
libpam-dev, python-setuptools
libpam-dev, python-setuptools, python-flup, pkg-config, libz-dev,
python-werkzeug, python-mox, python-flask, python-nose, apache2-bin | apache2
Standards-Version: 3.7.2
Package: ai-sso
...
...
src/mod_sso/Makefile.am
View file @
ab32b14d
...
...
@@ -8,7 +8,7 @@ noinst_DATA = mod_sso.la
SSO_LIBS
=
$(top_builddir)
/src/sso/libsso.la
libmod_sso_la_SOURCES
=
mod_sso.c mod_sso.h sso_utils.c
libmod_sso_la_CPPFLAGS
=
$(APACHE_CFLAGS)
$(AM_CPPFLAGS)
libmod_sso_la_CPPFLAGS
=
$(APACHE_CFLAGS)
$(A
PR_CFLAGS)
$(A
M_CPPFLAGS)
libmod_sso_la_LDFLAGS
=
-module
libmod_sso_la_LIBADD
=
$(SSO_LIBS)
...
...
src/mod_sso/mod_sso.c
View file @
ab32b14d
...
...
@@ -37,6 +37,11 @@
#include "mod_sso.h"
#if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
#define SSO_REQUIRE_NAME "sso"
#include "mod_auth.h"
#endif
extern
module
AP_MODULE_DECLARE_DATA
sso_module
;
typedef
struct
{
...
...
@@ -46,10 +51,27 @@ typedef struct {
// Note: public_key is a binary buffer (non zero-terminated).
const
unsigned
char
*
public_key
;
// All known groups (2.4: unused).
apr_array_header_t
*
groups
;
}
modsso_config
;
typedef
const
char
*
(
*
CMD_HAND_TYPE
)
();
static
char
*
groups_array_to_commasep_string
(
apr_pool_t
*
p
,
apr_array_header_t
*
groups
)
{
return
apr_array_pstrcat
(
p
,
groups
,
','
);
}
static
char
*
groups_charp_to_string
(
apr_pool_t
*
p
,
const
char
**
groups
)
{
apr_array_header_t
*
arr
=
apr_array_make
(
p
,
1
,
sizeof
(
char
*
));
const
char
**
gptr
;
for
(
gptr
=
groups
;
*
gptr
;
gptr
++
)
{
*
(
const
char
**
)
apr_array_push
(
arr
)
=
*
gptr
;
}
return
groups_array_to_commasep_string
(
p
,
arr
);
}
/**
* Create a modsso_config structure.
*
...
...
@@ -70,7 +92,8 @@ static void *create_modsso_config(apr_pool_t *p, char *s)
newcfg
->
service
=
NULL
;
newcfg
->
domain
=
NULL
;
newcfg
->
public_key
=
NULL
;
newcfg
->
groups
=
NULL
;
// Return the created configuration struct.
return
(
void
*
)
newcfg
;
}
...
...
@@ -85,11 +108,13 @@ static void *merge_modsso_config(apr_pool_t *p, void *base, void *add)
newcfg
->
login_server
=
cadd
->
login_server
?
cadd
->
login_server
:
cbase
->
login_server
;
newcfg
->
service
=
cadd
->
service
?
cadd
->
service
:
cbase
->
service
;
newcfg
->
domain
=
cadd
->
domain
?
cadd
->
domain
:
cbase
->
domain
;
newcfg
->
public_key
=
cbase
->
public_key
;
if
(
cadd
->
public_key
)
{
newcfg
->
public_key
=
cadd
->
public_key
;
}
}
// Groups are not merged, last takes precedence (if set).
newcfg
->
groups
=
cadd
->
groups
?
cadd
->
groups
:
cbase
->
groups
;
return
(
void
*
)
newcfg
;
}
...
...
@@ -393,11 +418,16 @@ static int mod_sso_method_handler(request_rec *r)
// Return immediately if there's nothing to do (check the AuthType)
type
=
ap_auth_type
(
r
);
if
(
!
type
||
strcasecmp
(
type
,
"SSO"
)
!=
0
)
{
ap_log_error
(
APLOG_MARK
,
APLOG_DEBUG
,
0
,
r
->
server
,
"sso: invalid authentication type
\"
%s
\"
"
,
type
);
return
DECLINED
;
}
sso_cookie_name
=
get_cookie_name
(
r
);
ap_log_error
(
APLOG_MARK
,
APLOG_DEBUG
,
0
,
r
->
server
,
"sso: cookie_name
\"
%s
\"
"
,
sso_cookie_name
);
// Check if the required parameters are defined.
if
(
!
check_config
(
r
,
s_cfg
))
{
return
HTTP_INTERNAL_SERVER_ERROR
;
...
...
@@ -406,13 +436,15 @@ static int mod_sso_method_handler(request_rec *r)
// Parse the service into host/path (guess it if not specified).
if
(
parse_service
(
r
,
s_cfg
,
&
service
,
&
service_host
,
&
service_path
)
!=
0
)
{
ap_log_error
(
APLOG_MARK
,
APLOG_ERR
,
0
,
r
->
server
,
"sso: could not parse service
\"
%s
\"
"
,
s_cfg
->
service
);
"sso: could not parse service
\"
%s
\"
"
,
s_cfg
->
service
);
return
HTTP_BAD_REQUEST
;
}
// Handle /sso_logout
sso_logout_path
=
apr_pstrcat
(
r
->
pool
,
service_path
,
"sso_logout"
,
NULL
);
ap_log_error
(
APLOG_MARK
,
APLOG_DEBUG
,
0
,
r
->
server
,
"sso: logout?
\"
%s
\"
\"
%s
\"
"
,
sso_logout_path
,
uri
);
if
(
!
strcmp
(
uri
,
sso_logout_path
))
{
modsso_del_cookie
(
r
,
sso_cookie_name
);
return
http_sendstring
(
r
,
"OK"
);
...
...
@@ -420,6 +452,8 @@ static int mod_sso_method_handler(request_rec *r)
// Handle /sso_login
sso_login_path
=
apr_pstrcat
(
r
->
pool
,
service_path
,
"sso_login"
,
NULL
);
ap_log_error
(
APLOG_MARK
,
APLOG_DEBUG
,
0
,
r
->
server
,
"sso: login?
\"
%s
\"
\"
%s
\"
"
,
sso_login_path
,
uri
);
if
(
!
strcmp
(
uri
,
sso_login_path
))
{
struct
modsso_params
params
;
char
*
redir
;
...
...
@@ -453,6 +487,7 @@ static int mod_sso_method_handler(request_rec *r)
return
DECLINED
;
}
#if MODULE_MAGIC_NUMBER_MAJOR < 20100714
struct
modsso_auth_req
{
apr_array_header_t
*
groups
;
apr_array_header_t
*
users
;
...
...
@@ -536,27 +571,13 @@ static void mod_sso_parse_requirements(request_rec *r,
*
(
const
char
**
)
apr_array_push
(
auth
->
groups
)
=
NULL
;
}
}
static
char
*
encode_groups
(
apr_pool_t
*
p
,
apr_array_header_t
*
groups
)
{
apr_array_header_t
*
arr
=
apr_array_make
(
p
,
(
groups
->
nelts
-
1
)
*
2
-
1
,
sizeof
(
const
char
*
));
int
i
;
/* Create a temporary array with strings and commas. */
for
(
i
=
0
;
i
<
groups
->
nelts
-
1
;
i
++
)
{
if
(
i
>
0
)
{
*
(
const
char
**
)
apr_array_push
(
arr
)
=
","
;
}
*
(
const
char
**
)
apr_array_push
(
arr
)
=
((
const
char
**
)
groups
->
elts
)[
i
];
}
return
apr_array_pstrcat
(
p
,
arr
,
0
);
}
#endif
static
int
redirect_to_login_server
(
request_rec
*
r
,
const
char
*
login_server
,
const
char
*
service_host
,
const
char
*
service
,
apr_array_header_t
*
groups
)
const
char
*
*
groups
)
{
char
*
dest
,
*
login_url
;
dest
=
full_uri
(
r
,
service_host
);
...
...
@@ -567,18 +588,21 @@ static int redirect_to_login_server(request_rec *r,
"&d="
,
modsso_url_encode
(
r
->
pool
,
dest
),
NULL
);
if
(
!
apr_is_empty_array
(
groups
)
)
{
if
(
groups
)
{
login_url
=
apr_pstrcat
(
r
->
pool
,
login_url
,
"&g="
,
encode_groups
(
r
->
pool
,
groups
),
groups_charp_to_string
(
r
->
pool
,
groups
),
NULL
);
}
ap_log_error
(
APLOG_MARK
,
APLOG_INFO
,
0
,
r
->
server
,
"sso: unauthorized access to %s"
,
dest
);
ap_log_error
(
APLOG_MARK
,
APLOG_DEBUG
,
0
,
r
->
server
,
"sso: redirecting to %s"
,
login_url
);
return
http_redirect
(
r
,
login_url
);
}
#if MODULE_MAGIC_NUMBER_MAJOR < 20100714
static
char
*
pkey_to_string
(
const
unsigned
char
*
pkey
,
char
*
buf
)
{
static
const
char
*
hex
=
"0123456789ABCDEF"
;
char
*
o
=
buf
;
...
...
@@ -591,13 +615,151 @@ static char *pkey_to_string(const unsigned char *pkey, char *buf) {
*
o
=
'\0'
;
return
buf
;
}
#endif
/**
* Apache authentication handler for mod_sso.
*
* @param r Pointer to the request_rec structure.
*/
static
int
mod_sso_authenticate_user
(
request_rec
*
r
)
#if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
static
int
mod_sso_check_access_ex
(
request_rec
*
r
)
{
const
char
*
type
,
*
uri
;
const
char
*
sso_login_path
,
*
sso_logout_path
;
const
char
*
service
=
NULL
,
*
service_host
=
NULL
,
*
service_path
=
NULL
;
modsso_config
*
s_cfg
=
(
modsso_config
*
)
ap_get_module_config
(
r
->
per_dir_config
,
&
sso_module
);
type
=
ap_auth_type
(
r
);
if
(
type
==
NULL
||
apr_strnatcasecmp
(
type
,
"sso"
)
!=
0
)
{
return
DECLINED
;
}
// Check if the required parameters are defined.
if
(
!
check_config
(
r
,
s_cfg
))
{
return
HTTP_INTERNAL_SERVER_ERROR
;
}
uri
=
r
->
uri
;
if
(
parse_service
(
r
,
s_cfg
,
&
service
,
&
service_host
,
&
service_path
)
!=
0
)
{
ap_log_error
(
APLOG_MARK
,
APLOG_ERR
,
0
,
r
->
server
,
"sso (check_access_ex): could not parse service (cfg->service=%s)"
,
s_cfg
->
service
);
return
HTTP_BAD_REQUEST
;
}
// Everyone is allowed access to /sso_login and /sso_logout
sso_logout_path
=
apr_pstrcat
(
r
->
pool
,
service_path
,
"sso_logout"
,
NULL
);
sso_login_path
=
apr_pstrcat
(
r
->
pool
,
service_path
,
"sso_login"
,
NULL
);
if
(
!
strcmp
(
uri
,
sso_logout_path
)
||
!
strcmp
(
uri
,
sso_login_path
))
{
return
OK
;
}
return
DECLINED
;
}
static
int
mod_sso_check_user_id
(
request_rec
*
r
)
{
const
char
*
type
,
*
sso_cookie_name
,
*
sso_cookie
;
const
char
*
service
=
NULL
,
*
service_host
=
NULL
,
*
service_path
=
NULL
;
int
retval
,
err
,
do_redirect
=
1
;
const
char
**
required_groups
;
modsso_config
*
s_cfg
=
(
modsso_config
*
)
ap_get_module_config
(
r
->
per_dir_config
,
&
sso_module
);
//apr_array_header_t *sso_validate_groups = NULL;
type
=
ap_auth_type
(
r
);
if
(
type
==
NULL
||
apr_strnatcasecmp
(
type
,
"sso"
)
!=
0
)
{
return
DECLINED
;
}
// If this is a sub-request, pass existing credentials, if any.
if
(
!
ap_is_initial_req
(
r
))
{
if
(
r
->
main
!=
NULL
)
{
r
->
user
=
r
->
main
->
user
;
}
else
if
(
r
->
prev
!=
NULL
)
{
r
->
user
=
r
->
prev
->
user
;
}
if
(
r
->
user
!=
NULL
)
{
return
OK
;
}
}
sso_cookie_name
=
get_cookie_name
(
r
);
// Check if the required parameters are defined.
if
(
!
check_config
(
r
,
s_cfg
))
{
return
HTTP_INTERNAL_SERVER_ERROR
;
}
if
(
parse_service
(
r
,
s_cfg
,
&
service
,
&
service_host
,
&
service_path
)
!=
0
)
{
ap_log_error
(
APLOG_MARK
,
APLOG_ERR
,
0
,
r
->
server
,
"sso (check_user_id): could not parse service (cfg->service=%s)"
,
s_cfg
->
service
);
return
HTTP_BAD_REQUEST
;
}
// Fetch the list of desired groups set (eventually) by group_check_authorization.
required_groups
=
(
const
char
**
)
apr_table_get
(
r
->
notes
,
"SSO_REQUIRED_GROUPS"
);
// Test for valid cookie
sso_cookie
=
get_cookie
(
r
,
sso_cookie_name
);
if
(
sso_cookie
!=
NULL
)
{
sso_ticket_t
t
;
#if 0
// Print some debugging information about the service
{
char pkeybuf[512];
const char *host_hdr = apr_table_get(r->headers_in, "Host");
if (!host_hdr) {
host_hdr = "null";
}
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
"sso request: uri=%s, service=%s, orig=%s, host=%s, tkt=%s, pkey=%s",
r->uri, service, s_cfg->service, host_hdr, sso_cookie,
pkey_to_string(s_cfg->public_key, pkeybuf));
}
#endif
err
=
sso_ticket_open
(
&
t
,
sso_cookie
,
s_cfg
->
public_key
);
if
(
err
!=
SSO_OK
)
{
ap_log_error
(
APLOG_MARK
,
APLOG_WARNING
,
0
,
r
->
server
,
"sso: ticket decoding error: %s"
,
sso_strerror
(
err
));
}
else
{
err
=
sso_validate
(
t
,
s_cfg
->
service
,
s_cfg
->
domain
,
required_groups
);
if
(
err
!=
SSO_OK
)
{
ap_log_error
(
APLOG_MARK
,
APLOG_WARNING
,
0
,
r
->
server
,
"sso: validation error: %s"
,
sso_strerror
(
err
));
}
else
{
// Don't do this: t->groups wil be freed by sso_ticket_free
// apr_table_setn(r->notes, "SSO_GROUPS", (char *)(t->groups));
apr_table_setn
(
r
->
subprocess_env
,
"SSO_SERVICE"
,
apr_pstrdup
(
r
->
pool
,
service
));
r
->
user
=
apr_pstrdup
(
r
->
pool
,
t
->
user
);
ap_log_error
(
APLOG_MARK
,
APLOG_DEBUG
,
0
,
r
->
server
,
"sso: authorized user '%s'"
,
r
->
user
);
retval
=
OK
;
do_redirect
=
0
;
}
sso_ticket_free
(
t
);
}
}
if
(
!
do_redirect
)
{
return
retval
;
}
// Redirect to login server
return
redirect_to_login_server
(
r
,
s_cfg
->
login_server
,
service_host
,
service
,
required_groups
);
}
#else
static
int
mod_sso_check_user_id
(
request_rec
*
r
)
{
const
char
*
type
,
*
sso_cookie_name
,
*
sso_cookie
,
*
uri
;
const
char
*
sso_login_path
,
*
sso_logout_path
;
...
...
@@ -609,10 +771,22 @@ static int mod_sso_authenticate_user(request_rec *r)
ap_get_module_config
(
r
->
per_dir_config
,
&
sso_module
);
type
=
ap_auth_type
(
r
);
if
(
!
type
||
strcasecmp
(
type
,
"SSO
"
)
!=
0
)
{
if
(
type
==
NULL
||
apr_strnatcasecmp
(
type
,
"sso
"
)
!=
0
)
{
return
DECLINED
;
}
// If this is a sub-request, pass existing credentials, if any.
if
(
!
ap_is_initial_req
(
r
))
{
if
(
r
->
main
!=
NULL
)
{
r
->
user
=
r
->
main
->
user
;
}
else
if
(
r
->
prev
!=
NULL
)
{
r
->
user
=
r
->
prev
->
user
;
}
if
(
r
->
user
!=
NULL
)
{
return
OK
;
}
}
sso_cookie_name
=
get_cookie_name
(
r
);
// Check if the required parameters are defined.
...
...
@@ -624,7 +798,7 @@ static int mod_sso_authenticate_user(request_rec *r)
if
(
parse_service
(
r
,
s_cfg
,
&
service
,
&
service_host
,
&
service_path
)
!=
0
)
{
ap_log_error
(
APLOG_MARK
,
APLOG_ERR
,
0
,
r
->
server
,
"sso (
authenticate_user
): could not parse service (cfg->service=%s)"
,
"sso (
check_user_id
): could not parse service (cfg->service=%s)"
,
s_cfg
->
service
);
return
HTTP_BAD_REQUEST
;
}
...
...
@@ -693,12 +867,91 @@ static int mod_sso_authenticate_user(request_rec *r)
}
// Redirect to login server
return
redirect_to_login_server
(
r
,
s_cfg
->
login_server
,
service_host
,
service
,
a
uth
.
group
s
);
return
redirect_to_login_server
(
r
,
s_cfg
->
login_server
,
service_host
,
service
,
a
pr_is_empty_array
(
auth
.
groups
)
?
NULL
:
(
const
char
**
)
auth
.
groups
->
elt
s
);
}
#endif
/* apache 2.2 */
/**
* Apache authorization check callback for mod_sso.
*/
#if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
static
char
**
groups_array_to_charpp
(
apr_pool_t
*
p
,
apr_array_header_t
*
groups
)
{
int
i
;
char
**
pp
,
**
ptr
;
pp
=
(
char
**
)
apr_palloc
(
p
,
sizeof
(
char
*
)
*
(
groups
->
nelts
+
1
));
for
(
ptr
=
pp
,
i
=
0
;
i
<
groups
->
nelts
;
i
++
)
{
*
ptr
++
=
APR_ARRAY_IDX
(
groups
,
i
,
char
*
);
}
*
ptr
=
NULL
;
return
pp
;
}
static
apr_array_header_t
*
required_groups_array
(
request_rec
*
r
,
const
void
*
parsed_require_args
)
{
const
ap_expr_info_t
*
expr
=
parsed_require_args
;
const
char
*
err
=
NULL
;
const
char
*
require
,
*
w
,
*
t
;
apr_array_header_t
*
grouparr
=
apr_array_make
(
r
->
pool
,
1
,
sizeof
(
char
*
));
require
=
ap_expr_str_exec
(
r
,
expr
,
&
err
);
if
(
err
)
{
return
NULL
;
}
t
=
require
;
while
((
w
=
ap_getword_conf
(
r
->
pool
,
&
t
))
&&
w
[
0
])
{
*
(
const
char
**
)
apr_array_push
(
grouparr
)
=
w
;
}
return
grouparr
;
}
static
char
**
required_groups_charpp
(
request_rec
*
r
,
const
void
*
parsed_require_args
)
{
apr_array_header_t
*
arr
=
required_groups_array
(
r
,
parsed_require_args
);
if
(
!
arr
)
{
return
NULL
;
}
return
groups_array_to_charpp
(
r
->
pool
,
arr
);
}
// This function will be called twice: first, before any authn
// handlers are executed, and we return AUTHZ_DENIED_NO_USER to tell
// Apache that we need a user. This should cause it to invoke
// mod_sso_check_user_id, and then call this function again.
static
authz_status
group_check_authorization
(
request_rec
*
r
,
const
char
*
require_args
,
const
void
*
parsed_require_args
)
{
// Do we have a user? All ok then! We assume that the request was
// validated by mod_sso_check_user_id using the value of
// SSO_REQUIRED_GROUPS we set earlier.
if
(
r
->
user
)
{
return
AUTHZ_GRANTED
;
}
// Set the list of groups in the request notes, so that the
// sso authn handler can retrieve it and validate the ticket.
apr_table_setn
(
r
->
notes
,
"SSO_REQUIRED_GROUPS"
,
(
char
*
)
required_groups_charpp
(
r
,
parsed_require_args
));
return
AUTHZ_DENIED_NO_USER
;
}
static
const
char
*
group_parse_config
(
cmd_parms
*
cmd
,
const
char
*
require_line
,
const
void
**
parsed_require_line
)
{
const
char
*
expr_err
=
NULL
;
ap_expr_info_t
*
expr
;
expr
=
ap_expr_parse_cmd
(
cmd
,
require_line
,
AP_EXPR_FLAG_STRING_RESULT
,
&
expr_err
,
NULL
);
if
(
expr_err
)
{
return
apr_pstrcat
(
cmd
->
temp_pool
,
"Cannot parse expression in require line: "
,
expr_err
,
NULL
);
}
*
parsed_require_line
=
expr
;
return
NULL
;
}
#else
static
int
mod_sso_auth_checker
(
request_rec
*
r
)
{
const
char
*
uri
,
*
type
;
...
...
@@ -707,7 +960,7 @@ static int mod_sso_auth_checker(request_rec *r)
char
*
sso_logout_path
,
*
sso_login_path
;
modsso_config
*
s_cfg
;
// We already did everything in mod_sso_
authenticate_user
(),
// We already did everything in mod_sso_
check_user_id
(),
// so just succeed (if SSO is active).
type
=
ap_auth_type
(
r
);
if
(
type
&&
!
strcasecmp
(
type
,
"SSO"
)
&&
r
->
user
)
{
...
...
@@ -732,7 +985,15 @@ static int mod_sso_auth_checker(request_rec *r)
return
DECLINED
;
}
#endif
#if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
static
const
authz_provider
authz_sso_group_provider
=
{
&
group_check_authorization
,
&
group_parse_config
,
};
#endif
/**
* Apache register_hooks callback for mod_sso.
...
...
@@ -744,10 +1005,16 @@ static int mod_sso_auth_checker(request_rec *r)
*/
static
void
mod_sso_register_hooks
(
apr_pool_t
*
p
)
{
static
const
char
*
const
mssoPost
[]
=
{
"sso_module"
,
NULL
};
ap_hook_handler
(
mod_sso_method_handler
,
NULL
,
NULL
,
APR_HOOK_FIRST
);
ap_hook_auth_checker
(
mod_sso_auth_checker
,
NULL
,
mssoPost
,
APR_HOOK_MIDDLE
);
ap_hook_check_user_id
(
mod_sso_authenticate_user
,
NULL
,
NULL
,
APR_HOOK_MIDDLE
);
#if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
ap_hook_check_authn
(
mod_sso_check_user_id
,
NULL
,
NULL
,
APR_HOOK_FIRST
,
AP_AUTH_INTERNAL_PER_CONF
);
ap_hook_check_access_ex
(
mod_sso_check_access_ex
,
NULL
,
NULL
,
APR_HOOK_MIDDLE
,
AP_AUTH_INTERNAL_PER_CONF
);
ap_register_auth_provider
(
p
,
AUTHZ_PROVIDER_GROUP
,
"group"
,
"0"
,
&
authz_sso_group_provider
,
AP_AUTH_INTERNAL_PER_CONF
);
#else
static
const
char
*
const
authzSucc
[]
=
{
"mod_sso.c"
,
NULL
};
ap_hook_check_user_id
(
mod_sso_check_user_id
,
NULL
,
NULL
,
APR_HOOK_MIDDLE
);
ap_hook_auth_checker
(
mod_sso_auth_checker
,
NULL
,
authzSucc
,
APR_HOOK_MIDDLE
);
#endif
}
/*
...
...
src/mod_sso/mod_sso.h
View file @
ab32b14d
...
...
@@ -26,6 +26,10 @@
#include "ap_config.h"
#include "apr_strings.h"
#ifdef APLOG_USE_MODULE
APLOG_USE_MODULE
(
sso
);
#endif
/* overwrite package vars set by apache */
#undef PACKAGE_BUGREPORT
#undef PACKAGE_NAME
...
...
src/mod_sso/test/.gitignore
View file @
ab32b14d
public.key
*_unittest
*.log
*.trs
src/mod_sso/test/Makefile.am
View file @
ab32b14d
...
...
@@ -6,7 +6,7 @@ check_PROGRAMS = \
EXTRA_DIST
=
httpd_integration_test.py
TESTS
=
$(check_PROGRAMS)
AM_CPPFLAGS
+=
$(APACHE_CFLAGS)
$(GTEST_CPPFLAGS)
AM_CPPFLAGS
+=
$(APACHE_CFLAGS)
$(
APR_CFLAGS)
$(
GTEST_CPPFLAGS)
AM_LDFLAGS
+=
$(GTEST_LDFLAGS)
LDADD
=
$(builddir)
/../libmod_sso.la
$(GTEST_LIBS)
$(APR_LIBS)
-laprutil-1
...
...
src/mod_sso/test/httpd_integration_test.py
View file @
ab32b14d
...
...
@@ -17,6 +17,9 @@ for exe in (APACHE_BIN, APXS_BIN):
if
not
os
.
path
.
exists
(
exe
):
raise
Exception
(
'%s not found, this test cannot run'
%
exe
)
# Use 2.4 ocnfiguration.
APACHE_CONFIG
=
'test-httpd-2.4.conf'
devnull
=
open
(
os
.
devnull
)
...
...
@@ -27,10 +30,12 @@ def _start_httpd(public_key):
env
[
'TESTROOT'
]
=
os
.
getcwd
()
env
[
'MODULEDIR'
]
=
subprocess
.
check_output
(
[
APXS_BIN
,
'-q'
,
'LIBEXECDIR'
],
stderr
=
devnull
).
strip
()
cmd
=
[
APACHE_BIN
,
"-f"
,
os
.
path
.
join
(
os
.
getcwd
(),
"test-httpd.conf"
),
"-X"
]
cmd
=
[
APACHE_BIN
,
"-f"
,
os
.
path
.
join
(
os
.
getcwd
(),
APACHE_CONFIG
),
"-X"
]
if
os
.
getenv
(
'STRACE'
):
cmd
=
[
'strace'
,
'-s'
,
'256'
,
'-f'
]
+
cmd
if
os
.
getenv
(
'VALGRIND'
):
cmd
=
[
'valgrind'
]
+
cmd
httpd
=
subprocess
.
Popen
(
cmd
,
env
=
env
)
print
'httpd pid:'
,
httpd
.
pid
...
...
@@ -136,12 +141,17 @@ class HttpdIntegrationTest(unittest.TestCase):
def
mkcookie
(
tkt
):
return
"SSO_test=%s"
%
tkt
# Set to a non-empty string when testing the SSOGroups directive
# (normally only the requested groups are generated).
#extra_groups = "&g=group1,group2,group3"
extra_groups
=
''
# Tests have a name so that we can recognize failures.
checks
=
[
(
"index -> redirect"
,
{
"url"
:
"/index.html"
,
"status"
:
302
,
"location"
:
"https://login.example.com/?s=service.example.com%2F&d=https%3A%2F%2Fservice.example.com%2Findex.html"
}),
"location"
:
"https://login.example.com/?s=service.example.com%2F&d=https%3A%2F%2Fservice.example.com%2Findex.html"
+
extra_groups
}),
(
"index with cookie -> ok"
,
{
"url"
:
"/index.html"
,
"cookie"
:
mkcookie
(
self
.
_ticket
()),
...
...
@@ -151,12 +161,12 @@ class HttpdIntegrationTest(unittest.TestCase):
{
"url"
:
"/index.html"
,
"cookie"
:
mkcookie
(
'blahblah'
*
8
),
"status"
:
302
,
"location"
:
"https://login.example.com/?s=service.example.com%2F&d=https%3A%2F%2Fservice.example.com%2Findex.html"
}),
"location"
:
"https://login.example.com/?s=service.example.com%2F&d=https%3A%2F%2Fservice.example.com%2Findex.html"
+
extra_groups
}),
(
"protected-user -> redirect"
,
{
"url"
:
"/protected-user/index.html"
,
"status"
:
302
,
"location"
:
"https://login.example.com/?s=service.example.com%2F&d=https%3A%2F%2Fservice.example.com%2Fprotected-user%2Findex.html"
}),
"location"
:
"https://login.example.com/?s=service.example.com%2F&d=https%3A%2F%2Fservice.example.com%2Fprotected-user%2Findex.html"
+
extra_groups
}),
(
"protected-user with cookie -> ok"
,
{
"url"
:
"/protected-user/index.html"
,
"cookie"
:
mkcookie
(
self
.
_ticket
()),
...
...
@@ -170,28 +180,32 @@ class HttpdIntegrationTest(unittest.TestCase):
(
"protected-group -> redirect"
,
{
"url"
:
"/protected-group/index.html"
,
"status"
:
302
,
"location"
:
"https://login.example.com/?s=service.example.com%2F&d=https%3A%2F%2Fservice.example.com%2Fprotected-group%2Findex.html
&g=group1"
}),
"location"
:
"https://login.example.com/?s=service.example.com%2F&d=https%3A%2F%2Fservice.example.com%2Fprotected-group%2Findex.html
"
+
(
extra_groups
if
extra_groups
else
"&g=group1"
)
}),
(
"protected-group with cookie -> ok"
,
{
"url"
:
"/protected-group/index.html"
,
"cookie"
:
mkcookie
(
self
.
_ticket
()),
"status"
:
200
,
"body"
:
"ok"
}),
#("protected-group with cookie wrong group -> unauthorized",
# {"url": "/protected-group/index.html",
# "cookie": mkcookie(self._ticket(group="group2")),