Compare commits
No commits in common. "master" and "holder-of-key" have entirely different histories.
master
...
holder-of-
|
@ -1,2 +0,0 @@
|
|||
( (nil . ((indent-tabs-mode . nil)))
|
||||
(c-mode . ((c-basic-offset . 4))) )
|
|
@ -1,10 +0,0 @@
|
|||
*.lo
|
||||
*.la
|
||||
*.o
|
||||
*.slo
|
||||
aclocal.m4
|
||||
config.*
|
||||
configure
|
||||
Makefile
|
||||
.libs/
|
||||
.vscode/
|
15
.travis.yml
15
.travis.yml
|
@ -1,15 +0,0 @@
|
|||
dist: bionic
|
||||
language: c
|
||||
addons:
|
||||
apt:
|
||||
packages:
|
||||
- apache2-dev
|
||||
- libglib2.0-dev
|
||||
- liblasso3-dev
|
||||
- libssl-dev
|
||||
|
||||
script:
|
||||
- ./autogen.sh
|
||||
- ./configure CFLAGS=-Werror
|
||||
- make
|
||||
- make distfile
|
149
COPYING
149
COPYING
|
@ -1,21 +1,3 @@
|
|||
mod_auth_mellon is distributed under the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the
|
||||
License, or (at your option) any later version.
|
||||
|
||||
In addition, as a special exception, permission is granted to link the code
|
||||
of this release of mod_mellon with the OpenSSL project's "OpenSSL" library
|
||||
(or with modified versions of it that use the same licence as the "OpenSSL"
|
||||
library), and distribute the linked executables. You must obey the GNU
|
||||
General Public License version 2 in all respects for all of the code used
|
||||
other than "OpenSSL". If you modify the code, you may extend this exception
|
||||
to your version of the code, but you are not obligated to do so. If you do
|
||||
not wish to do so, delete this exception statement from your version.
|
||||
|
||||
|
||||
|
||||
The full text of the GNU General Public License:
|
||||
===============================================================================
|
||||
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 2, June 1991
|
||||
|
||||
|
@ -355,134 +337,3 @@ proprietary programs. If your program is a subroutine library, you may
|
|||
consider it more useful to permit linking proprietary applications with the
|
||||
library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License.
|
||||
|
||||
|
||||
|
||||
The full text of the OpenSSL License:
|
||||
===============================================================================
|
||||
|
||||
LICENSE ISSUES
|
||||
==============
|
||||
|
||||
The OpenSSL toolkit stays under a dual license, i.e. both the conditions of
|
||||
the OpenSSL License and the original SSLeay license apply to the toolkit.
|
||||
See below for the actual license texts. Actually both licenses are BSD-style
|
||||
Open Source licenses. In case of any license issues related to OpenSSL
|
||||
please contact openssl-core@openssl.org.
|
||||
|
||||
OpenSSL License
|
||||
---------------
|
||||
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2011 The OpenSSL Project. 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. All advertising materials mentioning features or use of this
|
||||
* software must display the following acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit. (http://www.openssl.org/)"
|
||||
*
|
||||
* 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to
|
||||
* endorse or promote products derived from this software without
|
||||
* prior written permission. For written permission, please contact
|
||||
* openssl-core@openssl.org.
|
||||
*
|
||||
* 5. Products derived from this software may not be called "OpenSSL"
|
||||
* nor may "OpenSSL" appear in their names without prior written
|
||||
* permission of the OpenSSL Project.
|
||||
*
|
||||
* 6. Redistributions of any form whatsoever must retain the following
|
||||
* acknowledgment:
|
||||
* "This product includes software developed by the OpenSSL Project
|
||||
* for use in the OpenSSL Toolkit (http://www.openssl.org/)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY
|
||||
* EXPRESSED 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 OpenSSL PROJECT OR
|
||||
* ITS 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.
|
||||
* ====================================================================
|
||||
*
|
||||
* This product includes cryptographic software written by Eric Young
|
||||
* (eay@cryptsoft.com). This product includes software written by Tim
|
||||
* Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*/
|
||||
|
||||
Original SSLeay License
|
||||
-----------------------
|
||||
|
||||
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
||||
* All rights reserved.
|
||||
*
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
* 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 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. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* "This product includes cryptographic software written by
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``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.
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
|
286
ECP.rst
286
ECP.rst
|
@ -1,286 +0,0 @@
|
|||
Guide to using ECP
|
||||
==================
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
The **Enhanced Client or Proxy** (ECP) profile of SAML2
|
||||
|
||||
The Enhanced Client or Proxy (ECP) Profile supports several SSO use
|
||||
cases, in particular:
|
||||
|
||||
* Clients with capabilities beyond those of a browser, allowing them
|
||||
to more actively participate in IdP discovery and message flow.
|
||||
|
||||
* Using a proxy server, for example a WAP gateway in front of a mobile
|
||||
device which has limited functionality.
|
||||
|
||||
* When other bindings are precluded (e.g. where the client does not
|
||||
support redirects, or when auto form post is not possible without
|
||||
Javascript, or when the artifact binding is ruled out because the
|
||||
identity provider and service provider cannot directly communicate.
|
||||
|
||||
An enhanced client or proxy (ECP) is a system entity that knows how to
|
||||
contact an appropriate identity provider, possibly in a
|
||||
context-dependent fashion, and also supports the Reverse SOAP (PAOS)
|
||||
binding.
|
||||
|
||||
An example scenario enabled by ECP profile is as follows: A principal,
|
||||
wielding an ECP, uses it to either access a resource at a service
|
||||
provider, or access an identity provider such that the service
|
||||
provider and desired resource are understood or implicit. The
|
||||
principal authenticates (or has already authenticated) with the
|
||||
identity provider [1]_, which then produces an authentication assertion
|
||||
(possibly with input from the service provider). The service provider
|
||||
then consumes the assertion and subsequently establishes a security
|
||||
context for the principal. During this process, a name identifier
|
||||
might also be established between the providers for the principal,
|
||||
subject to the parameters of the interaction and the consent of the
|
||||
principal.
|
||||
|
||||
SAML2 Profile for ECP (Section 4.2) defines these steps for an ECP
|
||||
transaction:
|
||||
|
||||
1. ECP issues HTTP Request to SP
|
||||
2. SP issues <AuthnRequest> to ECP using PAOS
|
||||
3. ECP determines IdP
|
||||
4. ECP conveys <AuthnRequest> to IdP using SOAP
|
||||
5. IdP identifies principal
|
||||
6. IdP issues <Response> to ECP, targeted at SP using SOAP
|
||||
7. ECP conveys <Response> to SP using PAOS
|
||||
8. SP grants or denies access to principal
|
||||
|
||||
mod_auth_mellon and ECP
|
||||
-----------------------
|
||||
|
||||
mod_auth_mellon plays the role of the SP in an ECP transaction.
|
||||
|
||||
mod_auth_mellon utilizes the Lasso library to provide it's SAML2
|
||||
functionality. Fully functioning SAML2 ECP support in Lasso is
|
||||
relatively new. When mod_auth_mellon is built it detects the presence
|
||||
of SAML2 ECP in Lasso and only compiles in the ECP code in
|
||||
mod_auth_mellon if it's present in Lasso.
|
||||
|
||||
How does mod_auth_mellon recognize a request is from an ECP client?
|
||||
```````````````````````````````````````````````````````````````````
|
||||
|
||||
In Step 1. when the ECP client issues the HTTP Request to the SP it
|
||||
**MUST** include `application/vnd.paos+xml` as a mime type in the HTTP
|
||||
`Accept` header field and include an HTTP `PAOS` header specifying a
|
||||
PAOS version of `urn:liberty:paos:2003-08` and an ECP service
|
||||
declaration of `urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp` [2]_,
|
||||
for example::
|
||||
|
||||
Accept: text/html, application/vnd.paos+xml
|
||||
PAOS: ver="urn:liberty:paos:2003-08";"urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp"
|
||||
|
||||
If mod_auth_mellon sees this in the incoming request it knows the
|
||||
client is ECP aware and capable. If authentication is required
|
||||
mod_auth_mellon will initiate an ECP flow.
|
||||
|
||||
The role of IdP's in ECP
|
||||
````````````````````````
|
||||
|
||||
The SAML2 ECP profile states it is the ECP client which determines the
|
||||
IdP that will be used for authentication. This is in contrast to the
|
||||
Web SSO flow where the SP determines the IdP. However, the ECP
|
||||
protocol permits an SP to send the ECP client a list of IdP's it
|
||||
trusts. It is optional if the SP sends an IDPList, if it does the ECP
|
||||
client should select the IdP from the SP provided IDPList otherwise
|
||||
the ECP client is free to select any IdP it wishes.
|
||||
|
||||
If the mellon configuration option `MellonECPSendIDPList` is true then
|
||||
mod_auth_mellon will include an IDPList when it returns a PAOS
|
||||
<AuthnRequest> to the ECP client.
|
||||
|
||||
To build the IDPList mod_auth_mellon scans it's list of loaded IdP's
|
||||
selecting those which are ECP capable. To support ECP an IdP must
|
||||
advertise the SingleSignOn service utilizing the SOAP binding.
|
||||
|
||||
ECP specific mod_auth_mellon configuration directives
|
||||
`````````````````````````````````````````````````````
|
||||
|
||||
These configuration directives are specific to ECP:
|
||||
|
||||
MellonECPSendIDPList
|
||||
If `On` mod_auth_mellon will send an IdP list to the ECP client
|
||||
containing only those IdP's capable of ECP flow. The ECP client
|
||||
should select an IdP only from this list. If this option is `Off`
|
||||
no IdP list will be sent and the ECP client is free to select any
|
||||
IdP.
|
||||
|
||||
Example ECP client
|
||||
``````````````````
|
||||
|
||||
To illustrate a simple ECP client based on Lasso we'll use the Lasso
|
||||
Python binding (as opposed to pseudo code, Python is quite
|
||||
readable). All error checking and another necessary ancillary code has
|
||||
been eliminated in order to clearly illustrate only the ECP
|
||||
operations.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import lasso
|
||||
import requests
|
||||
|
||||
ecp = lasso.Ecp(server)
|
||||
session = requests.Session()
|
||||
|
||||
MEDIA_TYPE_PAOS = 'application/vnd.paos+xml'
|
||||
PAOS_HEADER = 'ver="%s";"%s"' % (lasso.PAOS_HREF,lasso.ECP_HREF)
|
||||
|
||||
# Step 1: Request protected resource, indicate ECP capable
|
||||
response = session.get(protected, headers={'Accept': MEDIA_TYPE_PAOS,
|
||||
'PAOS': PAOS_HEADER})
|
||||
|
||||
# Process returned PAOS wrapped <AuthnRequest>
|
||||
ecp.processAuthnRequestMsg(response.text)
|
||||
|
||||
# Post SOAP wrapped <AuthnRequest> to IdP, use Digest Auth to authenticate
|
||||
response = session.post(ecp.msgUrl,
|
||||
data=ecp.msgBody,
|
||||
auth=requests.auth.HTTPDigestAuth(user, password)
|
||||
headers={'Content-Type': 'text/xml'})
|
||||
|
||||
# Process returned SOAP wrapped <Assertion> from IdP
|
||||
ecp.processResponseMsg(response.text)
|
||||
|
||||
# Post PASO wrapped <Assertion> to SP, response is protected resource
|
||||
response = session.post(ecp.msgUrl,
|
||||
data=ecp.msgBody,
|
||||
headers={'Content-Type': 'application/vnd.paos+xml'})
|
||||
|
||||
|
||||
mod_auth_mellon internal ECP implementation notes
|
||||
-------------------------------------------------
|
||||
|
||||
|
||||
Notes on ECP vs. Web SSO flow
|
||||
`````````````````````````````
|
||||
|
||||
Web SSO (Single Sign-On) flow is by far the most common and what
|
||||
most people are familiar with when they think of SAML. The Web SSO
|
||||
profile is designed so that browsers ignorant of SAML can perform
|
||||
SAML authentication without modification. This is accomplished with
|
||||
existing HTTP paradigms such as redirects, form posts, etc. which a
|
||||
browser will process normally yielding the desired result.
|
||||
|
||||
ECP (Enhanced Client or Proxy) is a different SAML profile that
|
||||
also accomplishes SSO (Single Sign-On). The distinction is an ECP
|
||||
client is fully SAML aware and actively participates in the SAML
|
||||
conversation.
|
||||
|
||||
Web SSO and ECP have very different flows, mod_auth_mellon must
|
||||
support both flows. mod_auth_mellon is a SP (Service Provider).
|
||||
|
||||
IdP Selection Differences
|
||||
`````````````````````````
|
||||
|
||||
With Web SSO the SP determines the IdP and redirects there.
|
||||
|
||||
With ECP the ECP client determines the IdP, the SP has no a prori
|
||||
knowledge of the target IdP, although the SP may provide a
|
||||
suggested list of IdP's when responding to the ECP client.
|
||||
|
||||
Since with ECP it is the ECP client which selects the IdP the set of
|
||||
IdP's loaded into mod_auth_mellon are not relevant **except** if
|
||||
`MellonECPSendIDPList` is enabled. In this case mod_auth_mellon will
|
||||
filter the set of loaded IdP's and forward those IdP's supporting
|
||||
SingleSignOn with the SOAP binding.
|
||||
|
||||
Apache request processing pipeline
|
||||
``````````````````````````````````
|
||||
|
||||
Apache implements a request processing pipeline composed of
|
||||
stages. An Apache extension module can participate in the pipeline
|
||||
by asking to be called at specific stages (steps) by registering a
|
||||
hook function for that stage. Final content returned to the HTTP
|
||||
client in the HTTP response is generated in the "handler", one of
|
||||
the final stages in the request processing pipeline.
|
||||
|
||||
One of the stages in the request pipeline is determining
|
||||
authentication and authorization for protected resources. If a
|
||||
resource is protected and the authentication and authorization
|
||||
pipeline stages deny access or fail the request processing pipeline
|
||||
is aborted early, a non-success HTTP response is returned, the
|
||||
content handler is never reached.
|
||||
|
||||
With Web SSO if authentication needs to be performed a redirect will
|
||||
be returned that redirects to a SAML endpoint (login) on our SP. This
|
||||
in turn generates the SAML <AuthnRequest> with a redirect to the
|
||||
IdP. All of this is very vanilla standard HTTP easily accommodated by
|
||||
Apache's request processing pipeline which is designed to handle these
|
||||
types of flows.
|
||||
|
||||
ECP requires special handling
|
||||
`````````````````````````````
|
||||
|
||||
However ECP has a very different flow. When an ECP client sends a
|
||||
request to the SP it includes a special HTTP headers indicating it is
|
||||
ECP capable. If the SP determines the resource is protected and
|
||||
authentication is needed and the client has signaled it is ECP capable
|
||||
then the SP responds successfully (200) with a SAML <AuthnRequest>
|
||||
wrapped in PAOS. *This is very different than conventional HTTP
|
||||
request processing.* Here we have a case where there is a protected
|
||||
resource that has **not** been authenticated yet the web server will
|
||||
responds with an HTTP 200 success and content! One might normally
|
||||
expect a HTTP 401 or redirect response for a protected resource when
|
||||
there is no authenticated user. *This is clearly contrary to the
|
||||
expectations of Apache's request processing pipeline.*
|
||||
|
||||
Reaching the Apache content handler
|
||||
```````````````````````````````````
|
||||
|
||||
In order to be able to return a successful (HTTP 200) PAOS response
|
||||
when doing the ECP we have to reach the part of Apache's request
|
||||
processing pipeline that generates the response. In Apache terminology
|
||||
this is called a (content) handler.
|
||||
|
||||
At an early stage we detect if authentication is required. For the
|
||||
normal Web SSO profile we would redirect the client back to our login
|
||||
endpoint which will be handled by our handler in a different
|
||||
request. But for ECP the current request must proceed. We set a flag
|
||||
on the request indicating ECP authentication is required. The pipeline
|
||||
continues. When the pipeline reaches the authentication and
|
||||
authorization stages we check the ECP flag on the request, if ECP
|
||||
authentication is indicated we lie and tell the pipeline the user is
|
||||
authenticated and authorized. We do this only so we can reach the
|
||||
handler stage (otherwise because the request is for a protected
|
||||
resource the pipeline would terminate with an error). Despite our
|
||||
having forced authentication and authorization to be valid for the
|
||||
protected resource the request processing pipeline *will not return the
|
||||
protected resource* because we will subsequently intercept the request
|
||||
in our handler before the pipeline reaches the point of returning the
|
||||
protected resource.
|
||||
|
||||
At the handler stage
|
||||
````````````````````
|
||||
|
||||
Once our handler is invoked it has 3 possible actions to perform:
|
||||
|
||||
1. The request is for one of our SAML endpoints (e.g. login,
|
||||
logout, metadata, etc.) We dispatch to the handler for the specific
|
||||
action. We detect this case by matching the request URI to our SAML
|
||||
endpoints. We signal to the pipeline that our hook handled the request.
|
||||
|
||||
2. The request is for a protected resource and needs ECP
|
||||
authentication performed. We detect this case by examining the ECP flag
|
||||
set on the request by an earlier hook function. The request URI is
|
||||
for the protected resource and has nothing to do with our SAML
|
||||
endpoints. We generate the PAOS <AuthnRequest> and respond with
|
||||
success (200) and signal to the pipeline that our hook handled the
|
||||
request. Note, we have not returned the protected resource, instead
|
||||
we've returned the PAOS request.
|
||||
|
||||
3. The request has nothing to do with us, we decline to handle
|
||||
it. The pipeline proceeds to the next handler.
|
||||
|
||||
|
||||
.. [1] The means by which a principal authenticates with an identity
|
||||
provider is outside of the scope of SAML. Typically an ECP
|
||||
client will utilize an HTTP authentication method when posting
|
||||
the <AuthnRequest> SOAP message to the IdP.
|
||||
|
||||
.. [2] Contrary to most HTTP headers the values in the PAOS header must
|
||||
be enclosed in double quotes. A semicolon is used to separate
|
||||
the values.
|
53
Makefile.in
53
Makefile.in
|
@ -1,52 +1,39 @@
|
|||
|
||||
# Source files. mod_auth_mellon.c must be the first file.
|
||||
SRC=mod_auth_mellon.c \
|
||||
auth_mellon_cache.c \
|
||||
auth_mellon_config.c \
|
||||
auth_mellon_cookie.c \
|
||||
auth_mellon_diagnostics.c \
|
||||
auth_mellon_handler.c \
|
||||
auth_mellon_cache.c auth_mellon_config.c \
|
||||
auth_mellon_cookie.c auth_mellon_handler.c \
|
||||
auth_mellon_util.c \
|
||||
auth_mellon_session.c \
|
||||
auth_mellon_httpclient.c
|
||||
|
||||
# Documentation files
|
||||
USER_GUIDE_FILES=\
|
||||
doc/user_guide/mellon_user_guide.adoc \
|
||||
doc/user_guide/Guardfile \
|
||||
doc/user_guide/README \
|
||||
doc/user_guide/images/chrome_SAML_Chrome_Panel.png \
|
||||
doc/user_guide/images/chrome_SAML_Chrome_Panel.svg \
|
||||
doc/user_guide/images/saml-tracer.png \
|
||||
doc/user_guide/images/saml-tracer.svg \
|
||||
doc/user_guide/images/saml-web-sso.svg
|
||||
|
||||
|
||||
# Files to include when making a .tar.gz-file for distribution
|
||||
DISTFILES=$(SRC) \
|
||||
auth_mellon.h \
|
||||
auth_mellon_compat.h \
|
||||
lasso_compat.h \
|
||||
config.h.in \
|
||||
configure \
|
||||
configure.ac \
|
||||
Makefile.in \
|
||||
autogen.sh \
|
||||
README.md \
|
||||
ECP.rst \
|
||||
TODO \
|
||||
README \
|
||||
COPYING \
|
||||
NEWS \
|
||||
mellon_create_metadata.sh \
|
||||
$(USER_GUIDE_FILES)
|
||||
.tarball-version \
|
||||
tools/git-version-gen
|
||||
debian/auth_mellon.conf \
|
||||
debian/auth_mellon.load \
|
||||
debian/changelog \
|
||||
debian/compat \
|
||||
debian/control \
|
||||
debian/copyright \
|
||||
debian/dirs \
|
||||
debian/docs \
|
||||
debian/install \
|
||||
debian/rules
|
||||
|
||||
.tarball-version:
|
||||
echo @PACKAGE_VERSION@ > $@-t && mv $@-t $@
|
||||
|
||||
all: mod_auth_mellon.la
|
||||
|
||||
mod_auth_mellon.la: $(SRC) auth_mellon.h auth_mellon_compat.h
|
||||
@APXS2@ -Wc,"-std=c99 @MELLON_CFLAGS@ @OPENSSL_CFLAGS@ @LASSO_CFLAGS@ @CURL_CFLAGS@ @GLIB_CFLAGS@ @CFLAGS@" -Wl,"@OPENSSL_LIBS@ @LASSO_LIBS@ @CURL_LIBS@ @GLIB_LIBS@" -Wc,-Wall -Wc,-g -c $(SRC)
|
||||
mod_auth_mellon.la: $(SRC) auth_mellon.h
|
||||
@APXS2@ -Wc,"@OPENSSL_CFLAGS@ @LASSO_CFLAGS@ @CURL_CFLAGS@" -Wl,"@OPENSSL_LIBS@ @LASSO_LIBS@ @CURL_LIBS@" -Wc,-Wall -Wc,-g -c $(SRC)
|
||||
|
||||
|
||||
# Building configure (for distribution)
|
||||
|
@ -56,8 +43,6 @@ configure: configure.ac
|
|||
@NAMEVER@.tar.gz: $(DISTFILES)
|
||||
tar -c --transform="s#^#@NAMEVER@/#" -vzf $@ $(DISTFILES)
|
||||
|
||||
@NAMEVER@.tar.bz2: $(DISTFILES)
|
||||
tar -c --transform="s#^#@NAMEVER@/#" -vjf $@ $(DISTFILES)
|
||||
|
||||
.PHONY: install
|
||||
install: mod_auth_mellon.la
|
||||
|
@ -69,7 +54,6 @@ distfile: @NAMEVER@.tar.gz
|
|||
.PHONY: clean
|
||||
clean:
|
||||
rm -f mod_auth_mellon.la
|
||||
rm -f $(SRC:%.c=%.o)
|
||||
rm -f $(SRC:%.c=%.lo)
|
||||
rm -f $(SRC:%.c=%.slo)
|
||||
rm -rf .libs/
|
||||
|
@ -84,6 +68,3 @@ distclean: clean
|
|||
.PHONY: fullclean
|
||||
fullclean: distclean
|
||||
rm -f configure aclocal.m4
|
||||
|
||||
.PHONY: dist-bzip2
|
||||
dist-bzip2: @NAMEVER@.tar.bz2
|
||||
|
|
443
NEWS
443
NEWS
|
@ -1,434 +1,6 @@
|
|||
Version 0.14.2
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Security fixes:
|
||||
|
||||
* [CVE-2019-3878] Authentication bypass when Apache is used as a
|
||||
reverse proxy
|
||||
|
||||
If Apache is configured as a reverse proxy with mod_auth_mellon for
|
||||
authentication, the authentication can be bypassed by adding SAML
|
||||
2.0 ECP headers to the request.
|
||||
|
||||
This vulnerability affects mod_auth_mellon 0.11.0 and newer.
|
||||
|
||||
This vulnerability is due to both mod_auth_mellon and mod_proxy
|
||||
registering as handlers for the requests, with the same
|
||||
priority. When mod_auth_mellon handles the request first, it will
|
||||
trigger a ECP authentication request. If mod_proxy handles it first,
|
||||
it will forward it to the backend server.
|
||||
|
||||
Which module handles it first depends on the order modules are
|
||||
loaded by Apache.
|
||||
|
||||
This vulnerability is fixes by specifically registering that the
|
||||
mod_auth_mellon handler should run before mod_proxy.
|
||||
|
||||
Thanks to Jakub Hrozek and John Dennis at RedHat for fixing this
|
||||
vulnerability.
|
||||
|
||||
* [CVE-2019-3877] Redirect URL validation bypass
|
||||
|
||||
Version 0.14.1 and older of mod_auth_mellon allows the redirect URL
|
||||
validation to be bypassed by specifying an URL with backslashes
|
||||
instead of forward slashes. Browsers silently convert backslashes to
|
||||
forward slashes, which allows an attacker to bypass the redirect URL
|
||||
validation by using `%5c` in the ReturnTo-parameter. E.g.:
|
||||
|
||||
https://sp.example.org/mellon/logout?ReturnTo=https:%5c%5cmalicious.example.org/
|
||||
|
||||
This version fixes that issue by rejecting all URLs with
|
||||
backslashes.
|
||||
|
||||
Thanks to Eric Chamberland for discovering this vulnerability.
|
||||
|
||||
|
||||
Version 0.14.1
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* Fix environment variables in MellonCond
|
||||
* Fix detection of AJAX requests
|
||||
* Fix trailing semi-colon in Set-Cookie header
|
||||
|
||||
Version 0.14.0
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Backwards incompatible changes:
|
||||
|
||||
This version switches the default signature algorithm used when
|
||||
signing messages from rsa-sha1 to rsa-sha256. If your IdP does not
|
||||
allow messages to be signed with that algorithm, you need to add a
|
||||
setting switching back to the old algorithm:
|
||||
|
||||
MellonSignatureMethod rsa-sha1
|
||||
|
||||
Note that this only affects messages sent from mod_auth_mellon to your
|
||||
IdP. It does not affect authentication responses or other messages
|
||||
sent from your IdP to mod_auth_mellon.
|
||||
|
||||
New features:
|
||||
|
||||
* Many improvements in what is logged during various errors.
|
||||
|
||||
* Diagnostics logging, which creates a detailed log during request
|
||||
processing.
|
||||
|
||||
* Add support for selecting which signature algorithm is used when
|
||||
signing messages, and switch to rsa-sha256 by default.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* Fix segmentation fault in POST replay functionality on empty value.
|
||||
|
||||
* Fix incorrect error check for many `lasso_*`-functions.
|
||||
|
||||
* Fix case sensitive match on MellonUser attribute name.
|
||||
|
||||
|
||||
Version 0.13.1
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Security fix:
|
||||
|
||||
Fix a cross-site session transfer vulnerability. mod_auth_mellon
|
||||
version 0.13.0 and older failed to validate that the session specified
|
||||
in the user's session cookie was created for the web site the user
|
||||
actually accesses.
|
||||
|
||||
If two different web sites are hosted on the same web server, and both
|
||||
web sites use mod_auth_mellon for authentication, this vulnerability
|
||||
makes it possible for an attacker with access to one of the web sites
|
||||
to copy their session cookie to the other web site, and then use the
|
||||
same session to get access to the other web site.
|
||||
|
||||
Thanks to François Kooman for reporting this vulnerability.
|
||||
|
||||
This vulnerability has been assigned CVE-2017-6807.
|
||||
|
||||
Note: The fix for this vunlerability makes mod_auth_mellon validate
|
||||
that the cookie parameters used when creating the session match the
|
||||
cookie parameters that should be used when accessing the current
|
||||
page. If you currently use mod_auth_mellon across multiple subdomains,
|
||||
you must make sure that you set the `MellonCookie`-option to the same
|
||||
value on all domains.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* Fix segmentation fault if a (trusted) identity provider returns a
|
||||
SAML 2.0 attribute without a Name.
|
||||
|
||||
* Fix segmentation fault if MellonPostReplay is enabled but
|
||||
MellonPostDirectory is not set.
|
||||
|
||||
|
||||
Version 0.13.0
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Security fix:
|
||||
|
||||
Fix a denial of service attack in the logout handler, which allows a
|
||||
remote attacker to crash the Apache worker process with a segmentation
|
||||
fault. This is caused by a null-pointer dereference when processing a
|
||||
malformed logout message.
|
||||
|
||||
New features:
|
||||
|
||||
* Allow MellonSecureCookie to be configured to enable just one of the
|
||||
"httponly" of "secure" flags, instead of always enabling both flags.
|
||||
|
||||
* Support per-module log level with Apache 2.4.
|
||||
|
||||
* Allow disabling the Cache-Control HTTP response header.
|
||||
|
||||
* Add support for SameSite cookie parameter.
|
||||
|
||||
Bug fixes:
|
||||
|
||||
* Fix MellonProbeDiscoveryIdP redirecting to the wrong IdP if no IdPs
|
||||
respond to the probe request.
|
||||
|
||||
* Fix mod_auth_mellon interfering with other Apache authentication
|
||||
modules even when it is disabled for a path.
|
||||
|
||||
* Fix wrong HTTP status code being returned in some cases during user
|
||||
permission checks.
|
||||
|
||||
* Fix default POST size limit to actually be 1 MB.
|
||||
|
||||
* Fix error if authentication response is missing the optional
|
||||
Conditions-element.
|
||||
|
||||
* Fix AJAX requests being redirected to the IdP.
|
||||
|
||||
* Fix wrong content type for ECP authentication request responses.
|
||||
|
||||
In addition there are various fixes for errors in the documentation,
|
||||
as well as internal code changes that do not have any user visible
|
||||
effects.
|
||||
|
||||
|
||||
Version 0.12.0
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Security fixes:
|
||||
|
||||
* [CVE-2016-2145] Fix DOS attack (Apache worker process crash) due to
|
||||
incorrect error handling when reading POST data from client.
|
||||
|
||||
* [CVE-2016-2146] Fix DOS attack (Apache worker process crash /
|
||||
resource exhaustion) due to missing size checks when reading
|
||||
POST data.
|
||||
|
||||
In addition this release contains the following new features and fixes:
|
||||
|
||||
* Add MellonRedirectDomains option to limit the sites that
|
||||
mod_auth_mellon can redirect to. This option is enabled by default.
|
||||
|
||||
* Add support for ECP service options in PAOS requests.
|
||||
|
||||
* Fix AssertionConsumerService lookup for PAOS requests.
|
||||
|
||||
|
||||
Version 0.11.1
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Security fixes:
|
||||
|
||||
* [CVE-2016-2145] Fix DOS attack (Apache worker process crash) due to
|
||||
incorrect error handling when reading POST data from client.
|
||||
|
||||
* [CVE-2016-2146] Fix DOS attack (Apache worker process crash /
|
||||
resource exhaustion) due to missing size checks when reading
|
||||
POST data.
|
||||
|
||||
|
||||
Version 0.11.0
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
* Add SAML 2.0 ECP support.
|
||||
|
||||
* The MellonDecode option has been disabled. It was used to decode
|
||||
attributes in a Feide-specific encoding that is no longer used.
|
||||
|
||||
* Set max-age=0 in Cache-Control header, to ensure that all browsers
|
||||
verifies the data on each request.
|
||||
|
||||
* MellonMergeEnvVars On now accepts second optional parameter, the
|
||||
separator to be used instead of the default ';'.
|
||||
|
||||
* Add option MellonEnvVarsSetCount to specify if the number of values
|
||||
for any attribute should also be stored in environment variable
|
||||
suffixed _N.
|
||||
|
||||
* Add option MellonEnvVarsIndexStart to specify if environment variables
|
||||
for multi-valued attributes should start indexing with 0 (default) or
|
||||
with 1.
|
||||
|
||||
* Bugfixes:
|
||||
|
||||
* Fix error about missing authentication with DirectoryIndex in
|
||||
Apache 2.4.
|
||||
|
||||
|
||||
Version 0.10.0
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
* Make sure that we fail in the unlikely case where OpenSSL is not able
|
||||
to provide us with a secure session id.
|
||||
|
||||
* Increase the number of key-value pairs in the session to 2048.
|
||||
|
||||
* Add MellonMergeEnvVars-option to store multi-valued attributes in
|
||||
a single environment variable, separated with ';'.
|
||||
|
||||
* Bugfixes:
|
||||
|
||||
* Fix the [MAP] option for MellonCond.
|
||||
|
||||
* Fix cookie deletion for the session cookie. (Logout is not dependent
|
||||
on the cookie being deleted, so this only fixes the cookie showing
|
||||
up after the session is deleted.)
|
||||
|
||||
|
||||
Version 0.9.1
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
* Bugfixes:
|
||||
|
||||
* Fix session offset calculation that prevented us from having
|
||||
active sessions at once.
|
||||
|
||||
* Run mod_auth_mellon request handler before most other handlers,
|
||||
so that other handlers cannot block it by accident.
|
||||
|
||||
|
||||
Version 0.9.0
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
* Set the AssertionConsumerServiceURL attribute in authentication
|
||||
requests.
|
||||
|
||||
* Bugfixes:
|
||||
|
||||
* Fix use of uninitialized data during logout.
|
||||
|
||||
* Fix session entry overflow leading to segmentation faults.
|
||||
|
||||
* Fix looking up sessions by NameID, which is used during logout.
|
||||
|
||||
|
||||
Version 0.8.1
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
This is a security release with fixes backported from version 0.9.1.
|
||||
|
||||
It turned out that session overflow bugs fixes in version 0.9.0 and
|
||||
0.9.1 can lead to information disclosure, where data from one session
|
||||
is leaked to another session. Depending on how this data is used by the
|
||||
web application, this may lead to data from one session being disclosed
|
||||
to an user in a different session. (CVE-2014-8566)
|
||||
|
||||
In addition to the information disclosure, this release contains some
|
||||
fixes for logout processing, where logout requests would crash the
|
||||
Apache web server. (CVE-2014-8567)
|
||||
|
||||
|
||||
Version 0.8.0
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
* Add support for receiving HTTP-Artifact identifiers as POST data.
|
||||
|
||||
* Simplify caching headers.
|
||||
|
||||
* Map login errors into more appropriate HTTP error codes than
|
||||
400 Bad Request.
|
||||
|
||||
* Add MellonNoSuccessErrorPage option to redirect to a error page on login
|
||||
failure.
|
||||
|
||||
* Turn session storage into a dynamic pool of memory, which means that
|
||||
attribute values (and other items) can have arbitrary sizes as long as
|
||||
they fit in the session as a whole.
|
||||
|
||||
* Various bugfixes:
|
||||
|
||||
* Fix for compatibility with recent versions of CURL.
|
||||
|
||||
* Fix broken option MellonDoNotVerifyLogoutSignature.
|
||||
|
||||
* Fix deadlock that could occur during logout processing.
|
||||
|
||||
* Fix some compile warnings.
|
||||
|
||||
* Fix some NULL derefernce bugs that may lead to segmentation faults.
|
||||
|
||||
* Fix a minor memory leak during IdP metadata loading.
|
||||
|
||||
|
||||
Version 0.7.0
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
* Add MellonSPentityId to control entityId in autogenerated metadata
|
||||
|
||||
* Fix compatibility with Apache 2.4.
|
||||
|
||||
* Handle empty RelayState the same as missing RelayState.
|
||||
|
||||
* Add MellonSetEvnNoPrefix directive to set environment variables
|
||||
without "MELLON_"-prefix.
|
||||
|
||||
|
||||
Version 0.6.1
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
* Fix the POST replay functionality when multiple users logging in
|
||||
at once.
|
||||
|
||||
* Add a fallback for the case where the POST replay data has expired
|
||||
before the user logs in.
|
||||
|
||||
|
||||
Version 0.6.0
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
Backwards-incompatible changes:
|
||||
|
||||
* The POST replay functionality has been disabled by default, and the
|
||||
automatic creation of the MellonPostDirectory target directory has been
|
||||
removed. If you want to use the POST replay functionality, take a
|
||||
look at the README file for instructions for how to enable this.
|
||||
|
||||
* Start discovery service when accessing the login endpoint. We used
|
||||
to bypass the discovery service in this case, and just pick the first
|
||||
IdP. This has been changed to send a request to the discovery service
|
||||
instead, if one is configured.
|
||||
|
||||
* The MellonLockFile default path has been changed to:
|
||||
/var/run/mod_auth_mellon.lock
|
||||
This only affects platforms where a lock file is required and
|
||||
where Apache doesn't have write access to that directory during
|
||||
startup. (Apache can normally create files in that directory
|
||||
during startup.)
|
||||
|
||||
Other changes:
|
||||
|
||||
* Fix support for SOAP logout.
|
||||
|
||||
* Local logout when IdP does not support SAML 2.0 Single Logout.
|
||||
|
||||
* MellonDoNotVerifyLogoutSignature option to disable logout signature
|
||||
validation.
|
||||
|
||||
* Support for relative file paths in configuration.
|
||||
|
||||
* The debian build-directory has been removed from the repository.
|
||||
|
||||
* Various cleanups and bugfixes:
|
||||
|
||||
* Fix cookie parsing header parsing for some HTTP libraries.
|
||||
|
||||
* Fix inheritance of MellonAuthnContextClassRef option.
|
||||
|
||||
* Use ap_set_content_type() instead of accessing request->content_type.
|
||||
|
||||
* README indentation cleanups.
|
||||
|
||||
* Support for even older versions of GLib.
|
||||
|
||||
* Fixes for error handling during session initialization.
|
||||
|
||||
* Directly link with GLib rather than relying on the Lasso library
|
||||
linking to it for us.
|
||||
|
||||
* Some code cleanups.
|
||||
|
||||
|
||||
Version 0.5.0
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
* Honour MellonProbeDiscoveryIdP order when sending probes.
|
||||
|
||||
* MellonAuthnContextClassRef configuration directive, to limit
|
||||
authentication to specific authentication methods.
|
||||
|
||||
* Support for the HTTP-POST binding when sending authentication
|
||||
requests to the IdP.
|
||||
|
||||
* MellonSubjectConfirmationDataAddressCheck option to disable received
|
||||
address checking.
|
||||
|
||||
* Various cleanups and bugfixes:
|
||||
|
||||
* Support for older versions of GLib and APR.
|
||||
|
||||
* Send the correct SP entityID to the discovery service.
|
||||
|
||||
* Do not set response headers twice.
|
||||
|
||||
* Several cleanups in the code that starts authentication.
|
||||
Version 0.4.1
|
||||
|
||||
* Honour MellonProbeDiscoveryIdP order when sending probes
|
||||
|
||||
Version 0.4.0
|
||||
---------------------------------------------------------------------------
|
||||
|
@ -453,7 +25,6 @@ Version 0.4.0
|
|||
|
||||
* Several bugfixes.
|
||||
|
||||
|
||||
Version 0.3.0
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
@ -465,7 +36,6 @@ Version 0.3.0
|
|||
|
||||
* Various bugfixes.
|
||||
|
||||
|
||||
Version 0.2.7
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
@ -473,13 +43,11 @@ Version 0.2.7
|
|||
|
||||
* Shibboleth 2 interoperability
|
||||
|
||||
|
||||
Version 0.2.6
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
* Fix XSS/DOS vulnerability in repost handler.
|
||||
|
||||
|
||||
Version 0.2.5
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
@ -487,7 +55,6 @@ Version 0.2.5
|
|||
|
||||
* Fix HTTP response splitting vulnerability.
|
||||
|
||||
|
||||
Version 0.2.4
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
|
@ -496,27 +63,23 @@ Version 0.2.4
|
|||
* Mark session as disabled as soon as logout starts, in case the IdP
|
||||
doesn't respond.
|
||||
|
||||
|
||||
Version 0.2.3
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
* Bugfix for session lifetime. Take the session lifetime from the
|
||||
SessionNotOnOrAfter attribute if it is present.
|
||||
|
||||
|
||||
Version 0.2.2
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
* Improve metadata autogeneration: cleanup certificate, allow Organizarion
|
||||
element data to be supplied from Apache configuration
|
||||
|
||||
|
||||
Version 0.2.1
|
||||
---------------------------------------------------------------------------
|
||||
|
||||
* Make SAML authentication assertion and Lasso session available in the
|
||||
environment.
|
||||
|
||||
environement.
|
||||
|
||||
Version 0.2.0
|
||||
---------------------------------------------------------------------------
|
||||
|
|
|
@ -1,11 +1,15 @@
|
|||
# mod_auth_mellon
|
||||
===========================================================================
|
||||
README file for mod_auth_mellon
|
||||
===========================================================================
|
||||
|
||||
mod_auth_mellon is an authentication module for Apache. It authenticates
|
||||
the user against a SAML 2.0 IdP, and grants access to directories
|
||||
mod_auth_mellon is a authentication module for apache. It authenticates
|
||||
the user against a SAML 2.0 IdP, and and grants access to directories
|
||||
depending on attributes received from the IdP.
|
||||
|
||||
|
||||
## Dependencies
|
||||
===========================================================================
|
||||
Dependencies
|
||||
===========================================================================
|
||||
|
||||
mod_auth_mellon has four dependencies:
|
||||
* pkg-config
|
||||
|
@ -13,71 +17,74 @@ mod_auth_mellon has four dependencies:
|
|||
* OpenSSL
|
||||
* lasso (>=2.1)
|
||||
|
||||
You will also require development headers and tools for all of the
|
||||
You will also require developement headers and tools for all of the
|
||||
dependencies.
|
||||
|
||||
If OpenSSL or lasso are installed in a "strange" directory, then you may
|
||||
have to specify the directory containing "lasso.pc" and/or "openssl.pc" in
|
||||
the PKG_CONFIG_PATH environment variable. For example, if OpenSSL is
|
||||
the PKG_CONFIG_PATH environment variable. For example, if openssl is
|
||||
installed in /usr/local/openssl (with openssl.pc in
|
||||
/usr/local/openssl/lib/pkgconfig/) and lasso is installed in /opt/lasso
|
||||
(lasso.pc in /opt/lasso/lib/pkgconfig/), then you can set PKG_CONFIG_PATH
|
||||
before running configure like this:
|
||||
```
|
||||
|
||||
PKG_CONFIG_PATH=/usr/local/openssl/lib/pkgconfig:/opt/lasso/lib/pkgconfig
|
||||
export PKG_CONFIG_PATH
|
||||
```
|
||||
|
||||
|
||||
If Apache is installed in a "strange" directory, then you may have to
|
||||
specify the path to apxs2 using the `--with-apxs2=/full/path/to/apxs2`
|
||||
specify the path to apxs2 using the --with-apxs2=/full/path/to/apxs2
|
||||
option to configure. If, for example, Apache is installed in /opt/apache,
|
||||
with apxs2 in /opt/apache/bin, then you run
|
||||
```
|
||||
|
||||
./configure --with-apxs2=/opt/apache2/bin/apxs2
|
||||
```
|
||||
Note that, depending on your distribution, apxs2 may be named apxs.
|
||||
|
||||
Note that, depending on your distribution, apxs2 may be named apxs.
|
||||
|
||||
|
||||
## Installing mod_auth_mellon
|
||||
===========================================================================
|
||||
Installing mod_auth_mellon
|
||||
===========================================================================
|
||||
|
||||
mod_auth_mellon uses autoconf, and can be installed by running the
|
||||
following commands:
|
||||
```
|
||||
|
||||
./configure
|
||||
make
|
||||
make install
|
||||
```
|
||||
|
||||
|
||||
## Configuring mod_auth_mellon
|
||||
===========================================================================
|
||||
Configuring mod_auth_mellon
|
||||
===========================================================================
|
||||
|
||||
Here we are going to assume that your web server's hostname is
|
||||
Here we are going to assume that your web servers hostname is
|
||||
'example.com', and that the directory you are going to protect is
|
||||
'https://example.com/secret/'. We are also going to assume that you have
|
||||
'http://example.com/secret/'. We are also going to assume that you have
|
||||
configured your web site to use SSL.
|
||||
|
||||
You need to edit the configuration file for your web server. Depending on
|
||||
your distribution, it may be named '/etc/apache/httpd.conf' or something
|
||||
different.
|
||||
|
||||
You need to add a LoadModule directive for mod_auth_mellon. This will
|
||||
|
||||
You need to add a LoadModule directove for mod_auth_mellon. This will
|
||||
look similar to this:
|
||||
```
|
||||
|
||||
LoadModule auth_mellon_module /usr/lib/apache2/modules/mod_auth_mellon.so
|
||||
```
|
||||
|
||||
To find the full path to mod_auth_mellon.so, you may run:
|
||||
```
|
||||
|
||||
apxs2 -q LIBEXECDIR
|
||||
```
|
||||
|
||||
This will print the path where Apache stores modules. mod_auth_mellon.so
|
||||
will be stored in that directory.
|
||||
|
||||
You will also need to make sure that Apache's authn_core module is also
|
||||
enabled. Most likely you also want authz_user to be enabled.
|
||||
|
||||
After you have added the LoadModule directive, you must add configuration
|
||||
for mod_auth_mellon. The following is an example configuration:
|
||||
|
||||
```ApacheConf
|
||||
|
||||
###########################################################################
|
||||
# Global configuration for mod_auth_mellon. This configuration is shared by
|
||||
# every virtual server and location in this instance of apache.
|
||||
|
@ -90,25 +97,19 @@ for mod_auth_mellon. The following is an example configuration:
|
|||
# Default: MellonCacheSize 100
|
||||
MellonCacheSize 100
|
||||
|
||||
# MellonCacheEntrySize sets the maximum size for a single session entry in
|
||||
# bytes. When mod_auth_mellon reaches this limit, it cannot store any more
|
||||
# data in the session and will return an error. The minimum entry size is
|
||||
# 65536 bytes, values lower than that will be ignored and the minimum will
|
||||
# be used.
|
||||
# Default: MellonCacheEntrySize 196608
|
||||
|
||||
# MellonLockFile is the full path to a file used for synchronizing access
|
||||
# to the session data. The path should only be used by one instance of
|
||||
# apache at a time. The server must be restarted before any changes to this
|
||||
# option takes effect.
|
||||
# Default: MellonLockFile "/var/run/mod_auth_mellon.lock"
|
||||
MellonLockFile "/var/run/mod_auth_mellon.lock"
|
||||
# Default: MellonLockFile "/tmp/mellonLock"
|
||||
MellonLockFile "/tmp/mellonLock"
|
||||
|
||||
# MellonPostDirectory is the full path of a directory where POST requests
|
||||
# are saved during authentication. This directory must writable by the
|
||||
# Apache user. It should not be writable (or readable) by other users.
|
||||
# Default: None
|
||||
# Example: MellonPostDirectory "/var/cache/mod_auth_mellon_postdata"
|
||||
# are saved during authentication. This directory must be owned by the
|
||||
# Apache user and be mode 700. We will attempt to create it if it does not
|
||||
# exist.
|
||||
# Default: MellonPostDirectory "/var/tmp/mellonpost"
|
||||
MellonPostDirectory "/var/tmp/mellonpost"
|
||||
|
||||
# MellonPostTTL is the delay in seconds before a saved POST request can
|
||||
# be flushed.
|
||||
|
@ -116,31 +117,13 @@ MellonLockFile "/var/run/mod_auth_mellon.lock"
|
|||
MellonPostTTL 900
|
||||
|
||||
# MellonPostSize is the maximum size for saved POST requests
|
||||
# Default: MellonPostSize 1048576 (1 MB)
|
||||
MellonPostSize 1048576
|
||||
# Default: MellonPostSize 1073741824 (1 MB)
|
||||
MellonPostSize 1073741824
|
||||
|
||||
# MellonPostCount is the maximum amount of saved POST requests
|
||||
# MellonPostCount is the maxmimum amount of saved POST requests
|
||||
# Default: MellonPostCount 100
|
||||
MellonPostCount 100
|
||||
|
||||
# MellonDiagnosticsFile If Mellon was built with diagnostic capability
|
||||
# then diagnostic is written here, it may be either a filename or a pipe.
|
||||
# If it's a filename then the resulting path is relative to the ServerRoot.
|
||||
# If the value is preceeded by the pipe character "|" it should be followed
|
||||
# by a path to a program to receive the log information on its standard input.
|
||||
# This is a server context directive, hence it may be specified in the
|
||||
# main server config area or within a <VirtualHost> directive.
|
||||
# Default: logs/mellon_diagnostics
|
||||
MellonDiagnosticsFile logs/mellon_diagnostics
|
||||
|
||||
# MellonDiagnosticsEnable If Mellon was built with diagnostic capability
|
||||
# then this is a list of words controlling diagnostic output.
|
||||
# Currently only On and Off are supported.
|
||||
# This is a server context directive, hence it may be specified in the
|
||||
# main server config area or within a <VirtualHost> directive.
|
||||
# Default: Off
|
||||
MellonDiagnosticsEnable Off
|
||||
|
||||
###########################################################################
|
||||
# End of global configuration for mod_auth_mellon.
|
||||
###########################################################################
|
||||
|
@ -150,9 +133,7 @@ MellonDiagnosticsEnable Off
|
|||
<Location /secret>
|
||||
|
||||
# These are standard Apache apache configuration directives.
|
||||
# You must have enabled Apache's authn_core and authz_user modules.
|
||||
# See http://httpd.apache.org/docs/2.4/mod/mod_authn_core.html and
|
||||
# http://httpd.apache.org/docs/2.4/mod/mod_authz_user.html
|
||||
# See http://httpd.apache.org/docs/2.2/mod/core.html for information
|
||||
# about them.
|
||||
Require valid-user
|
||||
AuthType "Mellon"
|
||||
|
@ -168,10 +149,6 @@ MellonDiagnosticsEnable Off
|
|||
# the user. If the user isn't authorized, then we won't
|
||||
# populate the environment, but we won't deny the user
|
||||
# access either.
|
||||
#
|
||||
# You can also use this to set up the Mellon SSO paramaters
|
||||
# transparently at the top level of your site, and then use
|
||||
# "auth" to protect individual paths elsewhere in the site.
|
||||
# "auth": We will populate the environment with information about
|
||||
# the user if he is authorized. If he is authenticated
|
||||
# (logged in), but not authorized (according to the
|
||||
|
@ -179,17 +156,22 @@ MellonDiagnosticsEnable Off
|
|||
# return a 403 Forbidden error. If he isn't authenticated
|
||||
# then we will redirect him to the login page of the IdP.
|
||||
#
|
||||
# There is a special handling of AJAX requests, that are
|
||||
# identified by the "X-Requested-With: XMLHttpRequest" HTTP
|
||||
# header. Since no user interaction can happen there,
|
||||
# we always fail unauthenticated (not logged in) requests
|
||||
# with a 403 Forbidden error without redirecting to the IdP.
|
||||
#
|
||||
# Default: MellonEnable "off"
|
||||
MellonEnable "auth"
|
||||
|
||||
# MellonDecoder is an obsolete option which is a no-op but is
|
||||
# still accepted for backwards compatibility.
|
||||
# MellonDecoder is used to select which decoder mod_auth_mellon
|
||||
# will use when decoding attribute values.
|
||||
# There are two possible values: "none" and "feide". "none" is the
|
||||
# default.
|
||||
# They have the following meanings:
|
||||
# "none": mod_auth_mellon will store the attribute as it is
|
||||
# received from the IdP. This is the default behaviour.
|
||||
# "feide": FEIDE currently stores several values in a single
|
||||
# AttributeValue element. The values are base64 encoded
|
||||
# and separated by a underscore. This decoder reverses
|
||||
# this encoding.
|
||||
# Default: MellonDecoder "none"
|
||||
MellonDecoder "none"
|
||||
|
||||
# MellonVariable is used to select the name of the cookie which
|
||||
# mod_auth_mellon should use to remember the session id. If you
|
||||
|
@ -197,11 +179,10 @@ MellonDiagnosticsEnable Off
|
|||
# you will have to choose a different name for the cookie for each
|
||||
# site.
|
||||
# Default: "cookie"
|
||||
MellonVariable "cookie"
|
||||
MellonVariable "cookie"
|
||||
|
||||
# Whether the cookie set by auth_mellon should have HttpOnly and
|
||||
# secure flags set. Once "On" - both flags will be set. Values
|
||||
# "httponly" or "secure" will respectively set only one flag.
|
||||
# MellonSecureCookie enforces the HttpOnly and secure flags
|
||||
# for the mod_mellon cookie
|
||||
# Default: Off
|
||||
MellonSecureCookie On
|
||||
|
||||
|
@ -216,73 +197,25 @@ MellonDiagnosticsEnable Off
|
|||
# Default: /
|
||||
MellonCookiePath /
|
||||
|
||||
# MellonCookieSameSite allows control over the SameSite value used
|
||||
# for the authentication cookie.
|
||||
# The setting accepts values of "Strict" or "Lax"
|
||||
# If not set, the SameSite attribute is not set on the cookie.
|
||||
# Default: not set
|
||||
# MellonCookieSameSite lax
|
||||
|
||||
# MellonUser selects which attribute we should use for the username.
|
||||
# The username is passed on to other apache modules and to the web
|
||||
# page the user visits. NAME_ID is an attribute which we set to
|
||||
# the id we get from the IdP.
|
||||
# Note: If MellonUser refers to a multi-valued attribute, any single
|
||||
# value from that attribute may be used. Do not rely on it selecting a
|
||||
# specific value.
|
||||
# Default: MellonUser "NAME_ID"
|
||||
MellonUser "NAME_ID"
|
||||
MellonUser "NAME_ID"
|
||||
|
||||
# MellonIdP selects in which attribute we should dump the remote
|
||||
# IdP entityId. This is passed to other apache modules and to
|
||||
# IdP providerId. This is passed to other apache modules and to
|
||||
# the web pages the user visits.
|
||||
# Default: none
|
||||
# MellonIdP "IDP"
|
||||
# MellonIdP "IDP"
|
||||
|
||||
# MellonSetEnv configuration directives allows you to map
|
||||
# attribute names received from the IdP to names you choose
|
||||
# yourself. The syntax is 'MellonSetEnv <local name> <IdP name>'.
|
||||
# You can list multiple MellonSetEnv directives.
|
||||
# Default. None set.
|
||||
MellonSetEnv "e-mail" "mail"
|
||||
|
||||
# MellonSetEnvNoPrefix is identical to MellonSetEnv, except this
|
||||
# does not prepend 'MELLON_' to the constructed environment variable.
|
||||
# The syntax is 'MellonSetEnvNoPrefix <local name> <IdP name>'.
|
||||
# You can list multiple MellonSetEnvNoPrefix directives.
|
||||
# Default. None set.
|
||||
MellonSetEnvNoPrefix "DISPLAY_NAME" "displayName"
|
||||
|
||||
# MellonEnvPrefix changes the string the variables passed from the
|
||||
# IdP are prefixed with.
|
||||
# Default: MELLON_
|
||||
MellonEnvPrefix "NOLLEM_"
|
||||
|
||||
# MellonMergeEnvVars merges multiple values of environment variables
|
||||
# set using MellonSetEnv into single variable:
|
||||
# ie: MYENV_VAR => val1;val2;val3 instead of default behaviour of:
|
||||
# MYENV_VAR_0 => val1, MYENV_VAR_1 => val2 ... etc.
|
||||
# Second optional parameter specifies the separator, to override the
|
||||
# default semicolon.
|
||||
# Default: MellonMergeEnvVars Off
|
||||
MellonMergeEnvVars On
|
||||
MellonMergeEnvVars On ":"
|
||||
|
||||
# MellonEnvVarsIndexStart specifies if environment variables for
|
||||
# multi-valued attributes should start indexing from 0 or 1
|
||||
# The syntax is 'MellonEnvVarsIndexStart <0|1>'.
|
||||
# Default: MellonEnvVarsIndexStart 0
|
||||
MellonEnvVarsIndexStart 1
|
||||
|
||||
# MellonEnvVarsSetCount specifies if number of values for any given
|
||||
# attribute should also be stored in variable suffixed _N.
|
||||
# ie: if user is member of two groups, the following will be set:
|
||||
# MELLON__groups=group1
|
||||
# MELLON__groups_0=group1
|
||||
# MELLON__groups_1=group2
|
||||
# MELLON__groups_N=2
|
||||
# Default: MellonEnvVarsSetCount Off
|
||||
MellonEnvVarsSetCount On
|
||||
MellonSetEnv "e-mail" "mail"
|
||||
|
||||
# If MellonSessionDump is set, then the SAML session will be
|
||||
# available in the MELLON_SESSION environment variable
|
||||
|
@ -307,10 +240,10 @@ MellonDiagnosticsEnable Off
|
|||
# attribute, the last overrides the previous ones.
|
||||
#
|
||||
# Default: None set.
|
||||
MellonRequire "eduPersonAffiliation" "student" "employee"
|
||||
MellonRequire "eduPersonAffiliation" "student" "employee"
|
||||
|
||||
# MellonCond provides the same function as MellonRequire, with
|
||||
# extra functionality (MellonRequire is retained for backward
|
||||
# extra functionnality (MellonRequire is retained for backward
|
||||
# compatibility). The syntax is
|
||||
# 'MellonCond <attribute name> <value> [<options>]'
|
||||
#
|
||||
|
@ -329,14 +262,14 @@ MellonDiagnosticsEnable Off
|
|||
# are substituted.
|
||||
# %{num} Same as %n, with num being a number that may be
|
||||
# greater than 9.
|
||||
# %{ENV:x} Substitute Apache environment variable x.
|
||||
# %% Escape substitution to get a literal %.
|
||||
# %{ENV:x} Substitute Apache environement variable x.
|
||||
# %% Escape substitution to get a litteral %.
|
||||
#
|
||||
# <options> is an optional, comma-separated list of option
|
||||
# enclosed with brackets. Here is an example: [NOT,NC]
|
||||
# encloseed with brackets. Here is an example: [NOT,NC]
|
||||
# The valid options are:
|
||||
# OR If this MellonCond evaluated to false, then the
|
||||
# next one will be checked. If it evaluates to true,
|
||||
# OR If this MellonCond evaluted to false, then the
|
||||
# next one will be checked. If it evalutes to true,
|
||||
# then the overall check succeeds.
|
||||
# NOT This MellonCond evaluates to true if the attribute
|
||||
# does not match the value.
|
||||
|
@ -357,9 +290,9 @@ MellonDiagnosticsEnable Off
|
|||
# option has effect on a following MellonRequire directive.
|
||||
#
|
||||
# Default: none set
|
||||
# MellonCond "mail" "@example\.net$" [OR,REG]
|
||||
# MellonCond "mail" "@example\.com$" [OR,REG]
|
||||
# MellonCond "uid" "superuser"
|
||||
# MellonCond "mail" "@example\.net$" [OR,REG]
|
||||
# MellonCond "mail" "@example\.com$" [OR,REG]
|
||||
# MellonCond "uid" "superuser"
|
||||
|
||||
# MellonEndpointPath selects which directory mod_auth_mellon
|
||||
# should assume contains the SAML 2.0 endpoints. Any request to
|
||||
|
@ -369,7 +302,7 @@ MellonDiagnosticsEnable Off
|
|||
# the directory. The directory must be a sub-directory of this
|
||||
# <Location ...>.
|
||||
# Default: MellonEndpointPath "/mellon"
|
||||
MellonEndpointPath "/secret/endpoint"
|
||||
MellonEndpointPath "/secret/endpoint"
|
||||
|
||||
# MellonDefaultLoginPath is the location where one should be
|
||||
# redirected after an IdP-initiated login. Default is "/"
|
||||
|
@ -387,7 +320,7 @@ MellonDiagnosticsEnable Off
|
|||
# mod_auth_mellon will redirect the user to if he returns from the
|
||||
# IdP without a cookie with a session id.
|
||||
# Note that the user may also get this error if he for some reason
|
||||
# loses the cookie between being redirected to the IdP's login page
|
||||
# loses the cookie between being redirected to the IdPs login page
|
||||
# and returning from it.
|
||||
# If this option is unset, then mod_auth_mellon will return a
|
||||
# 400 Bad Request error if the cookie is missing.
|
||||
|
@ -395,17 +328,11 @@ MellonDiagnosticsEnable Off
|
|||
MellonNoCookieErrorPage "https://example.com/no_cookie.html"
|
||||
|
||||
# MellonSPMetadataFile is the full path to the file containing
|
||||
# the metadata for this service provider.
|
||||
# If mod_auth_mellon was compiled against Lasso version 2.2.2
|
||||
# or higher, this option is optional. Otherwise, it is mandatory.
|
||||
# Default: None set.
|
||||
# the metadata for this service provider.
|
||||
# Default: if not set, metadata will be autogenerated
|
||||
MellonSPMetadataFile /etc/apache2/mellon/sp-metadata.xml
|
||||
|
||||
# If you choose to autogenerate metadata, this option
|
||||
# can be used to control the SP entityId
|
||||
# MellonSPentityId "https://www.example.net/foo"
|
||||
#
|
||||
# If you choose to autogenerate metadata, these options
|
||||
# If you choose to autogenerate metadata, these option
|
||||
# can be used to fill the <Organization> element. They
|
||||
# all follow the syntax "option [lang] value":
|
||||
# MellonOrganizationName "random-service"
|
||||
|
@ -417,9 +344,9 @@ MellonDiagnosticsEnable Off
|
|||
# key of the service provider. The .pem-file cannot be encrypted
|
||||
# with a password. If built with lasso-2.2.2 or higher, the
|
||||
# private key only needs to be readable by root, otherwise it has
|
||||
# to be readable by the Apache pseudo user.
|
||||
# to be reasbable by the Apache pseudo user.
|
||||
# Default: None set.
|
||||
MellonSPPrivateKeyFile /etc/apache2/mellon/sp-private-key.pem
|
||||
MellonSPPrivateKeyFile /etc/apache2/mellon/sp-private-key.pem
|
||||
|
||||
# MellonSPCertFile is a .pem file with the certificate for the
|
||||
# service provider. This directive is optional.
|
||||
|
@ -428,31 +355,31 @@ MellonDiagnosticsEnable Off
|
|||
|
||||
# MellonIdPMetadataFile is the full path to the file which contains
|
||||
# metadata for the IdP you are authenticating against. This
|
||||
# directive is required. Multiple IdP metadata can be configured
|
||||
# directive is required. Mutliple IdP metadata can be configured
|
||||
# by using multiple MellonIdPMetadataFile directives.
|
||||
#
|
||||
# If your lasso library is recent enough (higher than 2.3.5),
|
||||
# then MellonIdPMetadataFile will accept an XML file containing
|
||||
# descriptors for multiple IdP. An optional validating chain can
|
||||
# be supplied as a second argument to MellonIdPMetadataFile. If
|
||||
# omitted, no metadata validation will take place.
|
||||
# ommitted, no metadata validation will take place.
|
||||
#
|
||||
# Default: None set.
|
||||
MellonIdPMetadataFile /etc/apache2/mellon/idp-metadata.xml
|
||||
MellonIdPMetadataFile /etc/apache2/mellon/idp-metadata.xml
|
||||
|
||||
# MellonIdPMetadataGlob is a glob(3) pattern enabled alternative
|
||||
# to MellonIdPMetadataFile. Like MellonIdPMetadataFile it will
|
||||
# accept an optional validating chain if lasso is recent enough.
|
||||
#
|
||||
# Default: None set.
|
||||
#MellonIdPMetadataGlob /etc/apache2/mellon/*-metadata.xml
|
||||
#MellonIdPMetadataGlob /etc/apache2/mellon/*-metadata.xml
|
||||
|
||||
# MellonIdpPublicKeyFile is the full path of the public key of the
|
||||
# IdP. This parameter is optional if the public key is embedded
|
||||
# in the IdP's metadata file, or if a certificate authority is
|
||||
# used. This parameter cannot be used if multiple IdP are configured.
|
||||
# Default: None set.
|
||||
MellonIdPPublicKeyFile /etc/apache2/mellon/idp-public-key.pem
|
||||
MellonIdPPublicKeyFile /etc/apache2/mellon/idp-public-key.pem
|
||||
|
||||
# MellonIdPCAFile is the full path to the certificate of the
|
||||
# certificate authority. This can be used instead of an
|
||||
|
@ -461,7 +388,7 @@ MellonDiagnosticsEnable Off
|
|||
MellonIdPCAFile /etc/apache2/mellon/ca.pem
|
||||
|
||||
# MellonIdPIgnore lists IdP entityId that should not loaded
|
||||
# from XML federation metadata files. This is useful if an
|
||||
# from XML federation metadata files. This is usefull if an
|
||||
# IdP cause bugs. Multiple entityId may be specified through
|
||||
# single MellonIdPIgnore, and multiple MellonIdPIgnore are allowed.
|
||||
# Default: None set.
|
||||
|
@ -469,16 +396,16 @@ MellonDiagnosticsEnable Off
|
|||
|
||||
# MellonDiscoveryURL is the URL for IdP discovery service.
|
||||
# This is used for selecting among multiple configured IdP.
|
||||
# On initial user authentication, it is redirected to the
|
||||
# On initiali user authentication, it is redirected to the
|
||||
# IdP discovery URL, with the following arguments set:
|
||||
#
|
||||
# entityID SP entityId URL, where our metadata
|
||||
# are published.
|
||||
# returnIDParam Argument that IdP discovery must send back.
|
||||
# entityID SP providerID URL, where our metadata
|
||||
# are pubblished.
|
||||
# retueniDParam Argument that IdP discovery must send back.
|
||||
# return Return URL the IdP discovery should return to.
|
||||
#
|
||||
# The IdP discovery must redirect the user to the return URL,
|
||||
# with returnIDParam set to the selected IdP entityId.
|
||||
# with retueniDParam set to the selected IdP providerID.
|
||||
#
|
||||
# The builtin:get-metadata discovery URL is not supported anymore
|
||||
# starting with 0.3.1. See MellonProbeDiscoveryTimeout for
|
||||
|
@ -503,9 +430,6 @@ MellonDiagnosticsEnable Off
|
|||
|
||||
# MellonProbeDiscoveryIdP can be used to restrict the
|
||||
# list of IdP queried by the IdP probe discovery service.
|
||||
# If probe discovery fails and this is provided, an
|
||||
# HTTP error 500 is returned, instead of proceeding
|
||||
# with first available IdP.
|
||||
#
|
||||
# Default unset, which means that all configured IdP are
|
||||
# queried.
|
||||
|
@ -513,101 +437,30 @@ MellonDiagnosticsEnable Off
|
|||
# MellonProbeDiscoveryIdP http://idp2.example.net/saml/metadata
|
||||
|
||||
# This option will make the SAML authentication assertion
|
||||
# available in the MELLON_SAML_RESPONSE environment
|
||||
# available in the MELLON_SAML_RESPONSE environement
|
||||
# variable. This assertion holds a verifiable signature
|
||||
# that can be checked again. Default is Off.
|
||||
MellonSamlResponseDump Off
|
||||
MellonSamlResponseDump Off
|
||||
|
||||
# This option will make the Lasso session available in
|
||||
# the MELLON_SESSION environment variable. Default is Off.
|
||||
MellonSessionDump Off
|
||||
|
||||
# This option will request specific authentication security-level
|
||||
# through the AuthnContextClassRef element of the AuthnRequest It will
|
||||
# also request enforcement of this level when receiving an
|
||||
# authenticating Assertion.
|
||||
# If the assertion does not have the required security level, an HTTP
|
||||
# Forbidden status code is returned to the browser.
|
||||
# MellonAuthnContextClassRef "urn:oasis:names:tc:SAML:2.0:ac:classes:Kerberos"
|
||||
# MellonAuthnContextClassRef "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
|
||||
# MellonAuthnContextClassRef "urn:oasis:names:tc:SAML:2.0:ac:classes:SoftwarePKI"
|
||||
|
||||
# This option will set the "Comparsion" attribute within the AuthnRequest
|
||||
# It could be set to "exact", "minimum", "maximum" or "better"
|
||||
# MellonAuthnContextComparisonType "minimum"
|
||||
|
||||
# MellonSubjectConfirmationDataAddressCheck is used to control
|
||||
# the checking of client IP address against the address returned by the
|
||||
# IdP in Address attribute of the SubjectConfirmationData node. Can be useful if your SP is
|
||||
# behind a reverse proxy or any kind of strange network topology making IP address of client
|
||||
# different for the IdP and the SP. Default is on.
|
||||
# MellonSubjectConfirmationDataAddressCheck On
|
||||
|
||||
# Does not check signature on logout messages exchanges with idp1
|
||||
# MellonDoNotVerifyLogoutSignature http://idp1.example.com/saml/metadata
|
||||
|
||||
# Whether to enable replay of POST requests after authentication. When this option is
|
||||
# enabled, POST requests that trigger authentication will be saved until the
|
||||
# authentication is completed, and then replayed. If this option isn't enabled,
|
||||
# the requests will be turned into normal GET requests after authentication.
|
||||
#
|
||||
# Note that if this option is enabled, you must also
|
||||
# set the MellonPostDirectory option in the server configuration.
|
||||
#
|
||||
# The default is that it is "Off".
|
||||
# MellonPostReplay Off
|
||||
|
||||
# Page to redirect to if the IdP sends an error in response to
|
||||
# the authentication request.
|
||||
#
|
||||
# Example:
|
||||
# MellonNoSuccessErrorPage https://sp.example.org/login_failed.html
|
||||
#
|
||||
# The default is to not redirect, but rather send a
|
||||
# 401 Unautorized error.
|
||||
|
||||
# This option controls whether to include a list of IDP's when
|
||||
# sending an ECP PAOS <AuthnRequest> message to an ECP client.
|
||||
MellonECPSendIDPList Off
|
||||
|
||||
# This option controls whether the Cache-control header is sent
|
||||
# back in responses.
|
||||
# Default: On
|
||||
# MellonSendCacheControlHeader Off
|
||||
|
||||
# List of domains that we allow redirects to.
|
||||
# The special name "[self]" means the domain of the current request.
|
||||
# The domain names can also use wildcards.
|
||||
#
|
||||
# Example:
|
||||
# * Allow redirects to example.com and all subdomains:
|
||||
# MellonRedirectDomains example.com *.example.com
|
||||
# * Allow redirects to the host running mod_auth_mellon, as well as the
|
||||
# web page at www.example.com:
|
||||
# MellonRedirectDomains [self] www.example.com
|
||||
# * Allow redirects to all domains:
|
||||
# MellonRedirectDomains *
|
||||
#
|
||||
# Default:
|
||||
# MellonRedirectDomains [self]
|
||||
MellonRedirectDomains [self]
|
||||
|
||||
# This option controls the signature method used to sign SAML
|
||||
# messages generated by Mellon, it may be one of the following
|
||||
# (depending if feature was supported when Mellon was built):
|
||||
#
|
||||
# rsa-sha1
|
||||
# rsa-sha256
|
||||
# rsa-sha384
|
||||
# rsa-sha512
|
||||
#
|
||||
# Default: rsa-sha256
|
||||
# MellonSignatureMethod
|
||||
# the MELLON_SESSION environement variable. Default is Off.
|
||||
MellonSessionDump Off
|
||||
|
||||
# This option will request specific authentication security-level
|
||||
# through the AuthnContextClassRef element of the AuthnRequest It will
|
||||
# also request enforcement of this level when receiving an
|
||||
# authenticating Assertion.
|
||||
# If the assertion does not have the required security level, an HTTP
|
||||
# Forbidden status code is returned to the browser.
|
||||
# MellonAuthnContextClassRef "urn:oasis:names:tc:SAML:2.0:ac:classes:Kerberos"
|
||||
# MellonAuthnContextClassRef "urn:oasis:names:tc:SAML:2.0:ac:classes:PasswordProtectedTransport"
|
||||
# MellonAuthnContextClassRef "urn:oasis:names:tc:SAML:2.0:ac:classes:SoftwarePKI"
|
||||
</Location>
|
||||
```
|
||||
|
||||
## Service provider metadata
|
||||
|
||||
===========================================================================
|
||||
Service provider metadata
|
||||
===========================================================================
|
||||
|
||||
The contents of the metadata will depend on your hostname and on what path
|
||||
you selected with the MellonEndpointPath configuration directive. You can
|
||||
|
@ -616,10 +469,9 @@ can just let it be autogenerated.
|
|||
|
||||
The following is an example of metadata for the example configuration:
|
||||
|
||||
```xml
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
|
||||
<EntityDescriptor
|
||||
entityID="https://example.com"
|
||||
entityID="examlpe.com"
|
||||
xmlns="urn:oasis:names:tc:SAML:2.0:metadata">
|
||||
<SPSSODescriptor
|
||||
AuthnRequestsSigned="false"
|
||||
|
@ -638,27 +490,26 @@ The following is an example of metadata for the example configuration:
|
|||
Location="https://example.com/secret/endpoint/postResponse" />
|
||||
</SPSSODescriptor>
|
||||
</EntityDescriptor>
|
||||
```
|
||||
|
||||
You should update `entityID="https://example.com"` and the two Location
|
||||
attributes. Note that '/secret/endpoint' in the two Location attributes matches
|
||||
the path set in MellonEndpointPath.
|
||||
|
||||
To use the HTTP-Artifact binding instead of the HTTP-POST binding, change
|
||||
You should update entityID="example.com" and the two Location attributes.
|
||||
Note that '/secret/endpoint' in the two Location attributes matches the
|
||||
path set in MellonEndpointPath.
|
||||
|
||||
To use HTTP-Artifact binding instead of the HTTP-POST binding, change
|
||||
the AssertionConsumerService-element to something like this:
|
||||
|
||||
```xml
|
||||
<AssertionConsumerService
|
||||
index="0"
|
||||
isDefault="true"
|
||||
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
||||
Location="https://example.com/secret/endpoint/artifactResponse" />
|
||||
```
|
||||
|
||||
The metadata are published at the 'endpoint/metadata' URL.
|
||||
|
||||
|
||||
## Using mod_auth_mellon
|
||||
===========================================================================
|
||||
Using mod_auth_mellon
|
||||
===========================================================================
|
||||
|
||||
After you have set up mod_auth_mellon, you should be able to visit (in our
|
||||
example) https://example.com/secret/, and be redirected to the IdP's login
|
||||
|
@ -667,35 +518,29 @@ https://example.com/secret/, and get the contents of that page.
|
|||
|
||||
When authenticating a user, mod_auth_mellon will set some environment
|
||||
variables to the attributes it received from the IdP. The name of the
|
||||
variables will be `MELLON_<attribute name>`. If you have specified a
|
||||
different name with the MellonSetEnv or MellonSetEnvNoPrefix configuration
|
||||
directive, then that name will be used instead. In the case of MellonSetEnv,
|
||||
the name will still be prefixed by `MELLON_`.
|
||||
variables will be MELLON_<attribute name>. If you have specified a
|
||||
different name with the MellonSetEnv configuration directive, then that
|
||||
name will be used instead. The name will still be prefixed by 'MELLON_'.
|
||||
|
||||
The value of the attribute will be base64 decoded.
|
||||
|
||||
mod_auth_mellon supports multivalued attributes with the following format:
|
||||
<base64 encoded value>_<base64 encoded value>_<base 64 encoded value>...
|
||||
|
||||
If an attribute has multiple values, then they will be stored as
|
||||
`MELLON_<name>_0`, `MELLON_<name>_1`, `MELLON_<name>_2`, ...
|
||||
MELLON_<name>_0, MELLON_<name>_1, MELLON_<name>_2, ...
|
||||
|
||||
Since mod_auth_mellon doesn't know which attributes may have multiple
|
||||
values, it will store every attribute at least twice: once named
|
||||
`MELLON_<name>`, and once named `<MELLON_<name>_0`.
|
||||
values, it will store every attribute at least twice. Once named
|
||||
MELLON_<name>, and once named <MELLON_<name>_0.
|
||||
|
||||
In the case of multivalued attributes, `MELLON_<name>` will contain the first
|
||||
In the case of multivalued attributes MELLON_<name> will contain the first
|
||||
value.
|
||||
|
||||
NOTE:
|
||||
|
||||
If MellonMergeEnvVars is set to On, multiple values of attributes
|
||||
will be stored in single environment variable, separated by semicolons:
|
||||
```
|
||||
MELLON_<name>="value1;value2;value3[;valueX]"
|
||||
```
|
||||
and variables `MELLON_<name>_0`, `MELLON_<name>_1`, `MELLON_<name>_2`, ...
|
||||
will not be created.
|
||||
|
||||
The following code is a simple PHP script which prints out all the
|
||||
The following code is a simple php-script which prints out all the
|
||||
variables:
|
||||
|
||||
```php
|
||||
<?php
|
||||
header('Content-Type: text/plain');
|
||||
|
||||
|
@ -705,25 +550,26 @@ foreach($_SERVER as $key=>$value) {
|
|||
}
|
||||
}
|
||||
?>
|
||||
```
|
||||
|
||||
|
||||
## Manual login
|
||||
===========================================================================
|
||||
Manual login
|
||||
===========================================================================
|
||||
|
||||
It is possible to manually trigger login operations. This can be done by
|
||||
accessing "<endpoint path>/login". That endpoint accepts three parameters:
|
||||
|
||||
- `ReturnTo`: A mandatory parameter which contains the URL we should return
|
||||
- ReturnTo: A mandatory parameter which contains the URL we should return
|
||||
to after login.
|
||||
- `IdP`: The entity ID of the IdP we should send a login request to. This
|
||||
- IdP: The entity ID of the IdP we should send a login request to. This
|
||||
parameter is optional.
|
||||
- `IsPassive`: This parameter can be set to "true" to send a passive
|
||||
- IsPassive: This parameter can be set to "true" to send a passive
|
||||
authentication request to the IdP.
|
||||
|
||||
===========================================================================
|
||||
Logging out
|
||||
===========================================================================
|
||||
|
||||
## Logging out
|
||||
|
||||
mod_auth_mellon supports both IdP-initiated and SP-initiated logout
|
||||
mod_auth_mellon supports both IdP initiated and SP initiated logout
|
||||
through the same endpoint. The endpoint is located at
|
||||
"<endpoint path>/logout". "<endpoint path>/logoutRequest" is an alias for
|
||||
this endpoint, provided for compatibility with version 0.0.6 and earlier of
|
||||
|
@ -736,27 +582,28 @@ located at "https://www.example.com/secret", and the mellon endpoints are
|
|||
located under "https://www.example.com/secret/endpoint", then the web site
|
||||
could contain a link element like the following:
|
||||
|
||||
```html
|
||||
<a href="/secret/endpoint/logout?ReturnTo=https://www.example.org/logged_out.html">Log out</a>
|
||||
```
|
||||
<a href=
|
||||
"/secret/endpoint/logout?ReturnTo=https://www.example.org/logged_out.html"
|
||||
>Log out</a>
|
||||
|
||||
This will return the user to "https://www.example.org/logged_out.html"
|
||||
after the logout operation has completed.
|
||||
|
||||
|
||||
## Probe IdP discovery
|
||||
===========================================================================
|
||||
Probe IdP discovery
|
||||
===========================================================================
|
||||
|
||||
mod_auth_mellon has an IdP probe discovery service that sends HTTP GET
|
||||
to IdP and picks the first that answers. This can be used as a poor
|
||||
man's failover setup that redirects to your organisation internal IdP.
|
||||
Here is a sample configuration:
|
||||
```ApacheConf
|
||||
MellonEndpointPath "/saml"
|
||||
(...)
|
||||
MellonDiscoveryUrl "/saml/probeDisco"
|
||||
MellonProbeDiscoveryTimeout 1
|
||||
```
|
||||
The SP will send an HTTP GET to each configured IdP entityId URL until
|
||||
|
||||
MellonEndpointPath "/saml"
|
||||
(...)
|
||||
MellonDiscoveryUrl "/saml/probeDisco"
|
||||
MellonProbeDiscoveryTimeout 1
|
||||
|
||||
The SP will sends HTTP GET to each configured IdP providerId URL until
|
||||
it gets an HTTP 200 response within the 1 second timeout. It will then
|
||||
proceed with that IdP.
|
||||
|
||||
|
@ -768,151 +615,39 @@ you will want to configure external IdP in mod_auth_mellon, but not
|
|||
use them for IdP probe discovery. The MellonProbeDiscoveryIdP
|
||||
directive can be used to limit the usable IdP for probe discovery:
|
||||
|
||||
```ApacheConf
|
||||
MellonEndpointPath "/saml"
|
||||
(...)
|
||||
MellonDiscoveryUrl "/saml/probeDisco"
|
||||
MellonProbeDiscoveryTimeout 1
|
||||
MellonProbeDiscoveryIdP "https://idp1.example.net/saml/metadata"
|
||||
MellonProbeDiscoveryIdP "https://idp2.example.net/saml/metadata"
|
||||
```
|
||||
MellonEndpointPath "/saml"
|
||||
(...)
|
||||
MellonDiscoveryUrl "/saml/probeDisco"
|
||||
MellonProbeDiscoveryTimeout 1
|
||||
MellonProbeDiscoveryIdP "https://idp1.example.net/saml/metadata"
|
||||
MellonProbeDiscoveryIdP "https://idp2.example.net/saml/metadata"
|
||||
|
||||
===========================================================================
|
||||
Subject Confirmation Method: holder of key
|
||||
===========================================================================
|
||||
|
||||
## Replaying POST requests
|
||||
The holder of key subject confirmation method allows to check the client
|
||||
certificate of an SSL session against a certificate passed by the identity
|
||||
provider in the authenticating assertion. It removes the use of a PKI or
|
||||
of certificate attributes for access control of SSL authenticated user on
|
||||
service providers.
|
||||
|
||||
By default, POST requests received when the user isn't logged in are turned
|
||||
into GET requests after authentication. mod_auth_mellon can instead save
|
||||
the received POST request and replay/repost it after authentication. To
|
||||
enable this:
|
||||
To enable the holder of key check you must add the following directive to your
|
||||
SSL virtualhost:
|
||||
|
||||
1. Create a data directory where mod_auth_mellon can store the saved data:
|
||||
SSLOptions +StdEnvVars +ExportCertData
|
||||
|
||||
mkdir /var/cache/mod_auth_mellon_postdata
|
||||
It's needed for mod_mellon to extract the client certificate value form the
|
||||
SSL_CLIENT_CERT environment variable.
|
||||
|
||||
2. Set the appropriate permissions on this directory. It needs to be
|
||||
accessible for the web server, but nobody else.
|
||||
===========================================================================
|
||||
Contributors
|
||||
===========================================================================
|
||||
|
||||
chown www-data /var/cache/mod_auth_mellon_postdata
|
||||
chgrp www-data /var/cache/mod_auth_mellon_postdata
|
||||
chmod 0700 /var/cache/mod_auth_mellon_postdata
|
||||
|
||||
3. Set the MellonPostDirectory option in your server configuration:
|
||||
|
||||
MellonPostDirectory "/var/cache/mod_auth_mellon_postdata"
|
||||
|
||||
4. Enable POST replay functionality for the locations you want:
|
||||
|
||||
<Location /secret>
|
||||
MellonEnable auth
|
||||
[...]
|
||||
MellonPostReplay On
|
||||
</Location>
|
||||
|
||||
After you restart Apache to activate the new configuration, any POST
|
||||
requests that trigger authentication should now be stored while the
|
||||
user logs in.
|
||||
|
||||
|
||||
## Example to support both SAML and Basic Auth
|
||||
|
||||
The below snippet will allow for preemptive basic auth (such as from a REST client)
|
||||
for the "/auth" path, but if accessed interactively will trigger SAML auth with
|
||||
mod_auth_mellon.
|
||||
|
||||
```ApacheConf
|
||||
<Location />
|
||||
MellonEnable "info"
|
||||
MellonVariable "cookie"
|
||||
MellonEndpointPath "/sso"
|
||||
Mellon... # Other parameters as needed
|
||||
</Location>
|
||||
|
||||
<Location /auth>
|
||||
<If "-n req('Authorization')">
|
||||
AuthName "My Auth"
|
||||
AuthBasicProvider ldap
|
||||
AuthType basic
|
||||
AuthLDAP* # Other basic auth config parms as needed
|
||||
|
||||
require ldap-group ....
|
||||
</If>
|
||||
<Else>
|
||||
Require valid-user
|
||||
AuthType "Mellon"
|
||||
MellonEnable "auth"
|
||||
</Else>
|
||||
</Location>
|
||||
```
|
||||
|
||||
|
||||
## Mellon & User Agent Caching behavior
|
||||
|
||||
For each content within an Apache Location enabled with "info" or "auth",
|
||||
mod_auth_mellon sends by default the HTTP/1.1 Cache-Control header with value
|
||||
`private, must-revalidate`:
|
||||
|
||||
- `private` protects content against caching by any proxy servers.
|
||||
- `must-revalidate` obligates the user agent to revalidate maybe locally
|
||||
cached or stored content each time on accessing location.
|
||||
|
||||
This default behavior ensures that the user agent never shows cached static
|
||||
HTML pages after logout without revalidating. So the user can't be
|
||||
misled about a malfunction of the logout procedure. Revalidating content after
|
||||
logout leads to a new authentication procedure via mellon.
|
||||
|
||||
But mod_auth_mellon will never prohibit specifically any user agent from
|
||||
caching or storing content locally, that has to be revalidated. So that during
|
||||
the session, a user agent only revalidates data by the server `304 Not Modified`
|
||||
response, and does not have to download content again.
|
||||
|
||||
For special content types like images it could make sense to disable
|
||||
revalidation completely, so that user agents can provide cached and stored
|
||||
content directly to the user. This can be achieved by using other Apache
|
||||
modules mod_headers and mod_setenvif. E.g. for PNG images:
|
||||
|
||||
* Using Apache 2.2 configuration options:
|
||||
|
||||
SetEnvIf Request_URI "\.png$" DISABLE_REVALIDATION
|
||||
Header always unset Cache-Control env=DISABLE_REVALIDATION
|
||||
|
||||
* In Apache 2.4, there's a shorter notation:
|
||||
|
||||
Header always unset Cache-Control expr=%{CONTENT_TYPE}==image/png
|
||||
|
||||
Editing, appending, and overwriting headers is possible in other cases.
|
||||
|
||||
|
||||
## Support
|
||||
|
||||
There's a mailing list for discussion and support.
|
||||
|
||||
* To subscribe: https://sympa.uninett.no/lists/uninett.no/subscribe/modmellon
|
||||
* List archives: https://sympa.uninett.no/lists/uninett.no/arc/modmellon
|
||||
|
||||
|
||||
## Reporting security vulnerabilities
|
||||
|
||||
For reporting security vulnerabilities in mod_auth_mellon, please contact
|
||||
the maintainer directly at the following email address:
|
||||
|
||||
olav.morken@uninett.no
|
||||
|
||||
This allows us to coordinate the disclosure of the vulnerability with the
|
||||
fixes for the vulnerability.
|
||||
|
||||
|
||||
## Contributors
|
||||
|
||||
Thanks to [Emmanuel Dreyfus](mailto:manu@netbsd.org) for many new features,
|
||||
Thanks to Emmanuel Dreyfus <manu@netbsd.org> for many new features,
|
||||
including:
|
||||
- Metadata autogeneration support.
|
||||
- Support for multiple IdPs.
|
||||
- IdP discovery service support.
|
||||
- SOAP logout support.
|
||||
|
||||
[Benjamin Dauvergne](mailto:bdauvergne@entrouvert.com) has contributed many
|
||||
patches, both with bugfixes and new features:
|
||||
- Cookie settings, for specifying domain and path of cookie.
|
||||
- Support for SAML 2.0 authentication contexts.
|
||||
- Support for running behind a reverse proxy.
|
||||
- Logout improvements, including support for local logout.
|
|
@ -0,0 +1,4 @@
|
|||
TODO for auth_mellon:
|
||||
|
||||
* Change session storage to use less than 64KiB/session.
|
||||
* Optimize session lookup.
|
374
auth_mellon.h
374
auth_mellon.h
|
@ -1,7 +1,7 @@
|
|||
/*
|
||||
*
|
||||
* auth_mellon.h: an authentication apache module
|
||||
* Copyright © 2003-2007 UNINETT (http://www.uninett.no/)
|
||||
* Copyright © 2003-2007 UNINETT (http://www.uninett.no/)
|
||||
*
|
||||
* 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
|
||||
|
@ -22,11 +22,6 @@
|
|||
#ifndef MOD_AUTH_MELLON_H
|
||||
#define MOD_AUTH_MELLON_H
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#include <stdbool.h>
|
||||
#include <strings.h>
|
||||
|
||||
#include <lasso/lasso.h>
|
||||
#include <lasso/xml/saml-2.0/samlp2_authn_request.h>
|
||||
#include <lasso/xml/saml-2.0/samlp2_logout_request.h>
|
||||
|
@ -38,7 +33,6 @@
|
|||
#include <lasso/xml/saml-2.0/saml2_authn_statement.h>
|
||||
#include <lasso/xml/saml-2.0/saml2_audience_restriction.h>
|
||||
#include <lasso/xml/misc_text_node.h>
|
||||
#include "lasso_compat.h"
|
||||
|
||||
/* The following are redefined in ap_config_auto.h */
|
||||
#undef PACKAGE_BUGREPORT
|
||||
|
@ -70,38 +64,22 @@
|
|||
#include "mod_ssl.h"
|
||||
|
||||
|
||||
/* Backwards-compatibility helpers. */
|
||||
#include "auth_mellon_compat.h"
|
||||
|
||||
|
||||
/* Size definitions for the session cache.
|
||||
*/
|
||||
#define AM_CACHE_KEYSIZE 120
|
||||
#define AM_CACHE_ENVSIZE 2048
|
||||
#define AM_CACHE_VARSIZE 128
|
||||
#define AM_CACHE_VALSIZE 512-AM_CACHE_VARSIZE
|
||||
#define AM_CACHE_ENVSIZE 128
|
||||
#define AM_CACHE_USERSIZE 512
|
||||
#define AM_CACHE_DEFAULT_ENTRY_SIZE 196608
|
||||
#define AM_CACHE_MIN_ENTRY_SIZE 65536
|
||||
|
||||
/* Internal error codes */
|
||||
#define AM_ERROR_INVALID_PAOS_HEADER 1
|
||||
#define AM_ERROR_MISSING_PAOS_HEADER 2
|
||||
#define AM_ERROR_MISSING_PAOS_MEDIA_TYPE 3
|
||||
#define AM_CACHE_MAX_LASSO_IDENTITY_SIZE 1024
|
||||
#define AM_CACHE_MAX_LASSO_SESSION_SIZE 32768
|
||||
#define AM_CACHE_MAX_LASSO_SAML_RESPONSE_SIZE 65536
|
||||
|
||||
|
||||
#ifdef ENABLE_DIAGNOSTICS
|
||||
typedef enum {
|
||||
AM_DIAG_FLAG_ENABLED = (1 << 0),
|
||||
AM_DIAG_FLAG_DISABLE = 0,
|
||||
AM_DIAG_FLAG_ENABLE_ALL = ~0,
|
||||
} am_diag_flags_t;
|
||||
#endif
|
||||
|
||||
/* This is the length of the id we use (for session IDs and
|
||||
* replaying POST data).
|
||||
/* This is the length of the session id we use.
|
||||
*/
|
||||
#define AM_ID_LENGTH 32
|
||||
#define AM_SESSION_ID_LENGTH 32
|
||||
|
||||
#define MEDIA_TYPE_PAOS "application/vnd.paos+xml"
|
||||
|
||||
#define am_get_srv_cfg(s) (am_srv_cfg_rec *)ap_get_module_config((s)->module_config, &auth_mellon_module)
|
||||
|
||||
|
@ -109,11 +87,6 @@ typedef enum {
|
|||
|
||||
#define am_get_dir_cfg(r) (am_dir_cfg_rec *)ap_get_module_config((r)->per_dir_config, &auth_mellon_module)
|
||||
|
||||
#define am_get_req_cfg(r) (am_req_cfg_rec *)ap_get_module_config((r)->request_config, &auth_mellon_module)
|
||||
|
||||
#ifdef ENABLE_DIAGNOSTICS
|
||||
#define am_get_diag_cfg(s) (&(am_get_srv_cfg((s)))->diag_cfg)
|
||||
#endif
|
||||
|
||||
typedef struct am_mod_cfg_rec {
|
||||
int cache_size;
|
||||
|
@ -123,35 +96,20 @@ typedef struct am_mod_cfg_rec {
|
|||
int post_count;
|
||||
apr_size_t post_size;
|
||||
|
||||
int entry_size;
|
||||
|
||||
/* These variables can't be allowed to change after the session store
|
||||
* has been initialized. Therefore we copy them before initializing
|
||||
* the session store.
|
||||
*/
|
||||
int init_cache_size;
|
||||
const char *init_lock_file;
|
||||
apr_size_t init_entry_size;
|
||||
|
||||
apr_shm_t *cache;
|
||||
apr_global_mutex_t *lock;
|
||||
} am_mod_cfg_rec;
|
||||
|
||||
|
||||
#ifdef ENABLE_DIAGNOSTICS
|
||||
typedef struct am_diag_cfg_rec {
|
||||
const char *filename;
|
||||
apr_file_t *fd;
|
||||
am_diag_flags_t flags;
|
||||
apr_table_t *dir_cfg_emitted;
|
||||
} am_diag_cfg_rec;
|
||||
#endif
|
||||
|
||||
typedef struct am_srv_cfg_rec {
|
||||
am_mod_cfg_rec *mc;
|
||||
#ifdef ENABLE_DIAGNOSTICS
|
||||
am_diag_cfg_rec diag_cfg;
|
||||
#endif
|
||||
} am_srv_cfg_rec;
|
||||
|
||||
typedef enum {
|
||||
|
@ -162,10 +120,10 @@ typedef enum {
|
|||
} am_enable_t;
|
||||
|
||||
typedef enum {
|
||||
am_samesite_default,
|
||||
am_samesite_lax,
|
||||
am_samesite_strict
|
||||
} am_samesite_t;
|
||||
am_decoder_default,
|
||||
am_decoder_none,
|
||||
am_decoder_feide,
|
||||
} am_decoder_t;
|
||||
|
||||
typedef enum {
|
||||
AM_COND_FLAG_NULL = 0x000, /* No flags */
|
||||
|
@ -185,30 +143,6 @@ typedef enum {
|
|||
|
||||
extern const char *am_cond_options[];
|
||||
|
||||
/*
|
||||
* am_file_data_t is used to maintain information about a file:
|
||||
*
|
||||
* * The filesystem pathname
|
||||
* * Stat information about the file (e.g. type, size, times, etc.)
|
||||
* * If and when the file was stat'ed or read
|
||||
* * Error code of failed operation and error string description
|
||||
* * Contents of the file
|
||||
* * Flag indicating if contents were generated instead of being read
|
||||
* from a file.
|
||||
*/
|
||||
typedef struct am_file_data_t {
|
||||
apr_pool_t *pool; /* allocation pool */
|
||||
const char *path; /* filesystem pathname, NULL for generated file */
|
||||
apr_time_t stat_time; /* when stat was performed, zero indicates never */
|
||||
apr_finfo_t finfo; /* stat data */
|
||||
char *contents; /* file contents */
|
||||
apr_time_t read_time; /* when contents was read, zero indicates never */
|
||||
apr_status_t rv; /* most recent result value */
|
||||
const char *strerror; /* if rv is error then this is error description */
|
||||
bool generated; /* true if contents generated instead of being
|
||||
read from path */
|
||||
} am_file_data_t;
|
||||
|
||||
typedef struct {
|
||||
const char *varname;
|
||||
int flags;
|
||||
|
@ -218,8 +152,8 @@ typedef struct {
|
|||
} am_cond_t;
|
||||
|
||||
typedef struct am_metadata {
|
||||
am_file_data_t *metadata; /* Metadata file with one or many IdP */
|
||||
am_file_data_t *chain; /* Validating chain */
|
||||
const char *file; /* Metadata file with one or many IdP */
|
||||
const char *chain; /* Validating chain */
|
||||
} am_metadata_t;
|
||||
|
||||
typedef struct am_dir_cfg_rec {
|
||||
|
@ -227,21 +161,19 @@ typedef struct am_dir_cfg_rec {
|
|||
*/
|
||||
am_enable_t enable_mellon;
|
||||
|
||||
/* The decoder attribute is used to specify which decoder we should use
|
||||
* when parsing attributes.
|
||||
*/
|
||||
am_decoder_t decoder;
|
||||
|
||||
const char *varname;
|
||||
int secure;
|
||||
int http_only;
|
||||
const char *merge_env_vars;
|
||||
int env_vars_index_start;
|
||||
int env_vars_count_in_n;
|
||||
const char *cookie_domain;
|
||||
const char *cookie_path;
|
||||
am_samesite_t cookie_samesite;
|
||||
apr_array_header_t *cond;
|
||||
apr_hash_t *envattr;
|
||||
const char *env_prefix;
|
||||
const char *userattr;
|
||||
const char *idpattr;
|
||||
LassoSignatureMethod signature_method;
|
||||
int dump_session;
|
||||
int dump_saml_response;
|
||||
|
||||
|
@ -253,16 +185,15 @@ typedef struct am_dir_cfg_rec {
|
|||
const char *endpoint_path;
|
||||
|
||||
/* Lasso configuration variables. */
|
||||
am_file_data_t *sp_metadata_file;
|
||||
am_file_data_t *sp_private_key_file;
|
||||
am_file_data_t *sp_cert_file;
|
||||
const char *sp_metadata_file;
|
||||
const char *sp_private_key_file;
|
||||
const char *sp_cert_file;
|
||||
apr_array_header_t *idp_metadata;
|
||||
am_file_data_t *idp_public_key_file;
|
||||
am_file_data_t *idp_ca_file;
|
||||
const char *idp_public_key_file;
|
||||
const char *idp_ca_file;
|
||||
GList *idp_ignore;
|
||||
|
||||
/* metadata autogeneration helper */
|
||||
char *sp_entity_id;
|
||||
apr_hash_t *sp_org_name;
|
||||
apr_hash_t *sp_org_display_name;
|
||||
apr_hash_t *sp_org_url;
|
||||
|
@ -273,9 +204,6 @@ typedef struct am_dir_cfg_rec {
|
|||
/* No cookie error page. */
|
||||
const char *no_cookie_error_page;
|
||||
|
||||
/* Authorization error page. */
|
||||
const char *no_success_error_page;
|
||||
|
||||
/* Login path for IdP initiated logins */
|
||||
const char *login_path;
|
||||
|
||||
|
@ -292,80 +220,32 @@ typedef struct am_dir_cfg_rec {
|
|||
/* AuthnContextClassRef list */
|
||||
apr_array_header_t *authn_context_class_ref;
|
||||
|
||||
/* AuthnContextComparisonType */
|
||||
const char *authn_context_comparison_type;
|
||||
|
||||
/* Controls the checking of SubjectConfirmationData.Address attribute */
|
||||
int subject_confirmation_data_address_check;
|
||||
|
||||
/* MellonDoNotVerifyLogoutSignature idp set */
|
||||
apr_hash_t *do_not_verify_logout_signature;
|
||||
|
||||
/* Controls whether the cache control header is set */
|
||||
int send_cache_control_header;
|
||||
|
||||
/* Whether we should replay POST data after authentication. */
|
||||
int post_replay;
|
||||
|
||||
/* Cached lasso server object. */
|
||||
LassoServer *server;
|
||||
|
||||
/* Whether to send an ECP client a list of IdP's */
|
||||
int ecp_send_idplist;
|
||||
|
||||
/* List of domains we can redirect to. */
|
||||
const char * const *redirect_domains;
|
||||
} am_dir_cfg_rec;
|
||||
|
||||
/* Bitmask for PAOS service options */
|
||||
typedef enum {
|
||||
ECP_SERVICE_OPTION_CHANNEL_BINDING = 1,
|
||||
ECP_SERVICE_OPTION_HOLDER_OF_KEY = 2,
|
||||
ECP_SERVICE_OPTION_WANT_AUTHN_SIGNED = 4,
|
||||
ECP_SERVICE_OPTION_DELEGATION = 8,
|
||||
} ECPServiceOptions;
|
||||
|
||||
typedef struct am_req_cfg_rec {
|
||||
char *cookie_value;
|
||||
#ifdef HAVE_ECP
|
||||
bool ecp_authn_req;
|
||||
ECPServiceOptions ecp_service_options;
|
||||
#endif /* HAVE_ECP */
|
||||
#ifdef ENABLE_DIAGNOSTICS
|
||||
bool diag_emitted;
|
||||
#endif
|
||||
} am_req_cfg_rec;
|
||||
|
||||
typedef struct am_cache_storage_t {
|
||||
apr_size_t ptr;
|
||||
} am_cache_storage_t;
|
||||
|
||||
typedef struct am_cache_env_t {
|
||||
am_cache_storage_t varname;
|
||||
am_cache_storage_t value;
|
||||
char varname[AM_CACHE_VARSIZE];
|
||||
char value[AM_CACHE_VALSIZE];
|
||||
} am_cache_env_t;
|
||||
|
||||
typedef struct am_cache_entry_t {
|
||||
char key[AM_CACHE_KEYSIZE];
|
||||
am_cache_storage_t cookie_token;
|
||||
apr_time_t access;
|
||||
apr_time_t expires;
|
||||
int logged_in;
|
||||
unsigned short size;
|
||||
am_cache_storage_t user;
|
||||
char user[AM_CACHE_USERSIZE];
|
||||
|
||||
/* Variables used to store lasso state between login requests
|
||||
*and logout requests.
|
||||
*/
|
||||
am_cache_storage_t lasso_identity;
|
||||
am_cache_storage_t lasso_session;
|
||||
am_cache_storage_t lasso_saml_response;
|
||||
char lasso_identity[AM_CACHE_MAX_LASSO_IDENTITY_SIZE];
|
||||
char lasso_session[AM_CACHE_MAX_LASSO_SESSION_SIZE];
|
||||
char lasso_saml_response[AM_CACHE_MAX_LASSO_SAML_RESPONSE_SIZE];
|
||||
|
||||
am_cache_env_t env[AM_CACHE_ENVSIZE];
|
||||
|
||||
apr_size_t pool_size;
|
||||
apr_size_t pool_used;
|
||||
char pool[];
|
||||
} am_cache_entry_t;
|
||||
|
||||
typedef enum {
|
||||
|
@ -373,94 +253,31 @@ typedef enum {
|
|||
AM_CACHE_NAMEID
|
||||
} am_cache_key_t;
|
||||
|
||||
/* Type for configuring environment variable names */
|
||||
typedef struct am_envattr_conf_t {
|
||||
// Name of the variable
|
||||
const char *name;
|
||||
// Should a prefix be added
|
||||
int prefixed;
|
||||
} am_envattr_conf_t;
|
||||
|
||||
extern const command_rec auth_mellon_commands[];
|
||||
|
||||
typedef struct am_error_map_t {
|
||||
int lasso_error;
|
||||
int http_error;
|
||||
} am_error_map_t;
|
||||
|
||||
extern const am_error_map_t auth_mellon_errormap[];
|
||||
|
||||
/* When using a value from a directory configuration structure, a special value is used
|
||||
* to state "inherit" from parent, when reading a value and the value is still inherit from, it
|
||||
* means that no value has ever been set for this directive, in this case, we use the default
|
||||
* value.
|
||||
*
|
||||
* This macro expects that if your variable is called "name" there is a static const variable named
|
||||
* "default_name" which holds the default value for this variable.
|
||||
*/
|
||||
#define CFG_VALUE(container, name) \
|
||||
(container->name == inherit_##name ? default_##name : container->name)
|
||||
|
||||
#define CFG_MERGE(add_cfg, base_cfg, name) \
|
||||
(add_cfg->name == inherit_##name ? base_cfg->name : add_cfg->name)
|
||||
|
||||
/** Default and inherit value for SubjectConfirmationData Address check setting.
|
||||
*/
|
||||
static const int default_subject_confirmation_data_address_check = 1;
|
||||
static const int inherit_subject_confirmation_data_address_check = -1;
|
||||
|
||||
/** Default values for seting the cache-control header
|
||||
*/
|
||||
static const int default_send_cache_control_header = 1;
|
||||
static const int inherit_send_cache_control_header = -1;
|
||||
|
||||
/* Default and inherit values for MellonPostReplay option. */
|
||||
static const int default_post_replay = 0;
|
||||
static const int inherit_post_replay = -1;
|
||||
|
||||
/* Whether to send an ECP client a list of IdP's */
|
||||
static const int default_ecp_send_idplist = 0;
|
||||
static const int inherit_ecp_send_idplist = -1;
|
||||
|
||||
/* Algorithm to use when signing Mellon SAML messages */
|
||||
static const LassoSignatureMethod default_signature_method =
|
||||
#if HAVE_DECL_LASSO_SIGNATURE_METHOD_RSA_SHA256
|
||||
LASSO_SIGNATURE_METHOD_RSA_SHA256;
|
||||
#else
|
||||
LASSO_SIGNATURE_METHOD_RSA_SHA1;
|
||||
#endif
|
||||
static const int inherit_signature_method = -1;
|
||||
|
||||
void *auth_mellon_dir_config(apr_pool_t *p, char *d);
|
||||
void *auth_mellon_dir_merge(apr_pool_t *p, void *base, void *add);
|
||||
void *auth_mellon_server_config(apr_pool_t *p, server_rec *s);
|
||||
void *auth_mellon_srv_merge(apr_pool_t *p, void *base, void *add);
|
||||
|
||||
|
||||
const char *am_cookie_get(request_rec *r);
|
||||
void am_cookie_set(request_rec *r, const char *id);
|
||||
void am_cookie_delete(request_rec *r);
|
||||
const char *am_cookie_token(request_rec *r);
|
||||
|
||||
|
||||
void am_cache_init(am_mod_cfg_rec *mod_cfg);
|
||||
am_cache_entry_t *am_cache_lock(request_rec *r,
|
||||
am_cache_entry_t *am_cache_lock(server_rec *s,
|
||||
am_cache_key_t type, const char *key);
|
||||
const char *am_cache_entry_get_string(am_cache_entry_t *e,
|
||||
am_cache_storage_t *slot);
|
||||
am_cache_entry_t *am_cache_new(request_rec *r,
|
||||
const char *key,
|
||||
const char *cookie_token);
|
||||
void am_cache_unlock(request_rec *r, am_cache_entry_t *entry);
|
||||
am_cache_entry_t *am_cache_new(server_rec *s, const char *key);
|
||||
void am_cache_unlock(server_rec *s, am_cache_entry_t *entry);
|
||||
|
||||
void am_cache_update_expires(request_rec *r, am_cache_entry_t *t, apr_time_t expires);
|
||||
void am_cache_update_expires(am_cache_entry_t *t, apr_time_t expires);
|
||||
|
||||
void am_cache_env_populate(request_rec *r, am_cache_entry_t *session);
|
||||
int am_cache_env_append(am_cache_entry_t *session,
|
||||
const char *var, const char *val);
|
||||
const char *am_cache_env_fetch_first(am_cache_entry_t *t,
|
||||
const char *var);
|
||||
void am_cache_delete(request_rec *r, am_cache_entry_t *session);
|
||||
void am_cache_delete(server_rec *s, am_cache_entry_t *session);
|
||||
|
||||
int am_cache_set_lasso_state(am_cache_entry_t *session,
|
||||
const char *lasso_identity,
|
||||
|
@ -479,9 +296,8 @@ void am_delete_request_session(request_rec *r, am_cache_entry_t *session);
|
|||
|
||||
|
||||
char *am_reconstruct_url(request_rec *r);
|
||||
int am_validate_redirect_url(request_rec *r, const char *url);
|
||||
int am_check_permissions(request_rec *r, am_cache_entry_t *session);
|
||||
void am_set_cache_control_headers(request_rec *r);
|
||||
void am_set_nocache(request_rec *r);
|
||||
int am_read_post_data(request_rec *r, char **data, apr_size_t *length);
|
||||
char *am_extract_query_parameter(apr_pool_t *pool,
|
||||
const char *query_string,
|
||||
|
@ -489,12 +305,8 @@ char *am_extract_query_parameter(apr_pool_t *pool,
|
|||
char *am_urlencode(apr_pool_t *pool, const char *str);
|
||||
int am_urldecode(char *data);
|
||||
int am_check_url(request_rec *r, const char *url);
|
||||
char *am_generate_id(request_rec *r);
|
||||
am_file_data_t *am_file_data_new(apr_pool_t *pool, const char *path);
|
||||
am_file_data_t *am_file_data_copy(apr_pool_t *pool,
|
||||
am_file_data_t *src_file_data);
|
||||
apr_status_t am_file_read(am_file_data_t *file_data);
|
||||
apr_status_t am_file_stat(am_file_data_t *file_data);
|
||||
char *am_generate_session_id(request_rec *r);
|
||||
char *am_getfile(apr_pool_t *conf, server_rec *s, const char *file);
|
||||
char *am_get_endpoint_url(request_rec *r);
|
||||
int am_postdir_cleanup(request_rec *s);
|
||||
char *am_htmlencode(request_rec *r, const char *str);
|
||||
|
@ -512,30 +324,17 @@ const char *am_get_mime_header(request_rec *r, const char *m, const char *h);
|
|||
const char *am_get_mime_body(request_rec *r, const char *mime);
|
||||
char *am_get_service_url(request_rec *r,
|
||||
LassoProfile *profile, char *service_name);
|
||||
bool am_parse_paos_header(request_rec *r, const char *header, ECPServiceOptions *options_return);
|
||||
bool am_header_has_media_type(request_rec *r, const char *header,
|
||||
const char *media_type);
|
||||
const char *am_get_config_langstring(apr_hash_t *h, const char *lang);
|
||||
int am_get_boolean_query_parameter(request_rec *r, const char *name,
|
||||
int *return_value, int default_value);
|
||||
char *am_get_assertion_consumer_service_by_binding(LassoProvider *provider, const char *binding);
|
||||
|
||||
#ifdef HAVE_ECP
|
||||
char *am_ecp_service_options_str(apr_pool_t *pool, ECPServiceOptions options);
|
||||
bool am_is_paos_request(request_rec *r, int *error_code);
|
||||
#endif /* HAVE_ECP */
|
||||
|
||||
char *
|
||||
am_saml_response_status_str(request_rec *r, LassoNode *node);
|
||||
|
||||
int am_auth_mellon_user(request_rec *r);
|
||||
int am_check_uid(request_rec *r);
|
||||
int am_handler(request_rec *r);
|
||||
int am_fixup(request_rec *r);
|
||||
|
||||
|
||||
int am_httpclient_get(request_rec *r, const char *uri,
|
||||
void **buffer, apr_size_t *size,
|
||||
int timeout, long *status);
|
||||
apr_time_t timeout, long *status);
|
||||
int am_httpclient_post(request_rec *r, const char *uri,
|
||||
const void *post_data, apr_size_t post_length,
|
||||
const char *content_type,
|
||||
|
@ -548,95 +347,4 @@ int am_httpclient_post_str(request_rec *r, const char *uri,
|
|||
|
||||
extern module AP_MODULE_DECLARE_DATA auth_mellon_module;
|
||||
|
||||
#ifdef ENABLE_DIAGNOSTICS
|
||||
|
||||
#if AP_SERVER_MAJORVERSION_NUMBER < 2 || \
|
||||
(AP_SERVER_MAJORVERSION_NUMBER == 2 && AP_SERVER_MINORVERSION_NUMBER < 4)
|
||||
#error "Diagnostics requires Apache version 2.4 or newer."
|
||||
#endif
|
||||
|
||||
/* Initializing an apr_time_t to 0x7fffffffffffffffLL yields an
|
||||
* iso 8601 time with 1 second precision of "294247-01-10T04:00:54Z"
|
||||
* this is 22 characters, +1 for null terminator. */
|
||||
#define ISO_8601_BUF_SIZE 23
|
||||
|
||||
typedef struct {
|
||||
bool req_headers_written;
|
||||
} am_diag_request_data;
|
||||
|
||||
const char *
|
||||
am_diag_cache_key_type_str(am_cache_key_t key_type);
|
||||
|
||||
const char *
|
||||
am_diag_cond_str(request_rec *r, const am_cond_t *cond);
|
||||
|
||||
int
|
||||
am_diag_finalize_request(request_rec *r);
|
||||
|
||||
const char *
|
||||
am_diag_lasso_http_method_str(LassoHttpMethod http_method);
|
||||
|
||||
void
|
||||
am_diag_log_cache_entry(request_rec *r, int level, am_cache_entry_t *entry,
|
||||
const char *fmt, ...)
|
||||
__attribute__((format(printf,4,5)));
|
||||
|
||||
void
|
||||
am_diag_log_file_data(request_rec *r, int level, am_file_data_t *file_data,
|
||||
const char *fmt, ...)
|
||||
__attribute__((format(printf,4,5)));
|
||||
|
||||
int
|
||||
am_diag_log_init(apr_pool_t *pc, apr_pool_t *p, apr_pool_t *pt, server_rec *s);
|
||||
|
||||
void
|
||||
am_diag_log_lasso_node(request_rec *r, int level, LassoNode *node,
|
||||
const char *fmt, ...)
|
||||
__attribute__((format(printf,4,5)));
|
||||
|
||||
void
|
||||
am_diag_log_saml_status_response(request_rec *r, int level, LassoNode *node,
|
||||
const char *fmt, ...)
|
||||
__attribute__((format(printf,4,5)));
|
||||
|
||||
void
|
||||
am_diag_log_profile(request_rec *r, int level, LassoProfile *profile,
|
||||
const char *fmt, ...)
|
||||
__attribute__((format(printf,4,5)));
|
||||
|
||||
void
|
||||
am_diag_printf(request_rec *r, const char *fmt, ...)
|
||||
__attribute__((format(printf,2,3)));
|
||||
|
||||
void
|
||||
am_diag_rerror(const char *file, int line, int module_index,
|
||||
int level, apr_status_t status,
|
||||
request_rec *r, const char *fmt, ...);
|
||||
|
||||
char *
|
||||
am_diag_time_t_to_8601(request_rec *r, apr_time_t t);
|
||||
|
||||
/* Define AM_LOG_RERROR log to both the Apache log and diagnostics log */
|
||||
#define AM_LOG_RERROR(...) AM_LOG_RERROR__(__VA_ARGS__)
|
||||
/* need additional step to expand macros */
|
||||
#define AM_LOG_RERROR__(file, line, mi, level, status, r, ...) \
|
||||
{ \
|
||||
ap_log_rerror(file, line, mi, level, status, r, __VA_ARGS__); \
|
||||
am_diag_rerror(file, line, mi, level, status, r, __VA_ARGS__); \
|
||||
}
|
||||
|
||||
#else /* ENABLE_DIAGNOSTICS */
|
||||
|
||||
#define am_diag_log_cache_entry(...) do {} while(0)
|
||||
#define am_diag_log_file_data(...) do {} while(0)
|
||||
#define am_diag_log_lasso_node(...) do {} while(0)
|
||||
#define am_diag_log_saml_status_response(...) do {} while(0)
|
||||
#define am_diag_log_profile(...) do {} while(0)
|
||||
#define am_diag_printf(...) do {} while(0)
|
||||
|
||||
/* Define AM_LOG_RERROR log only to the Apache log */
|
||||
#define AM_LOG_RERROR(...) ap_log_rerror(__VA_ARGS__)
|
||||
|
||||
#endif /* ENABLE_DIAGNOSTICS */
|
||||
|
||||
#endif /* MOD_AUTH_MELLON_H */
|
||||
|
|
|
@ -21,69 +21,26 @@
|
|||
|
||||
#include "auth_mellon.h"
|
||||
|
||||
#ifdef APLOG_USE_MODULE
|
||||
APLOG_USE_MODULE(auth_mellon);
|
||||
#endif
|
||||
|
||||
/* Calculate the pointer to a cache entry.
|
||||
*
|
||||
* Parameters:
|
||||
* am_mod_cfg_rec *mod_cfg The module configuration.
|
||||
* void *table The base pointer for the table.
|
||||
* apr_size_t index The index we are looking for.
|
||||
*
|
||||
* Returns:
|
||||
* The session entry with the given index.
|
||||
*/
|
||||
static inline am_cache_entry_t *am_cache_entry_ptr(am_mod_cfg_rec *mod_cfg,
|
||||
void *table, apr_size_t index)
|
||||
{
|
||||
uint8_t *table_calc;
|
||||
table_calc = table;
|
||||
return (am_cache_entry_t *)&table_calc[mod_cfg->init_entry_size * index];
|
||||
}
|
||||
|
||||
/* Initialize the session table.
|
||||
*
|
||||
* Parameters:
|
||||
* am_mod_cfg_rec *mod_cfg The module configuration.
|
||||
*
|
||||
* Returns:
|
||||
* Nothing.
|
||||
*/
|
||||
void am_cache_init(am_mod_cfg_rec *mod_cfg)
|
||||
{
|
||||
void *table;
|
||||
apr_size_t i;
|
||||
/* Initialize the session table. */
|
||||
table = apr_shm_baseaddr_get(mod_cfg->cache);
|
||||
for (i = 0; i < mod_cfg->init_cache_size; i++) {
|
||||
am_cache_entry_t *e = am_cache_entry_ptr(mod_cfg, table, i);
|
||||
e->key[0] = '\0';
|
||||
e->access = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* This function locks the session table and locates a session entry.
|
||||
* Unlocks the table and returns NULL if the entry wasn't found.
|
||||
* If a entry was found, then you _must_ unlock it with am_cache_unlock
|
||||
* after you are done with it.
|
||||
*
|
||||
* Parameters:
|
||||
* request_rec *r The request we are processing.
|
||||
* am_cache_key_t type AM_CACHE_SESSION or AM_CACHE_NAMEID
|
||||
* server_rec *s The current server.
|
||||
* const char *key The session key or user
|
||||
* am_cache_key_t type AM_CACHE_SESSION or AM_CACHE_NAMEID
|
||||
*
|
||||
* Returns:
|
||||
* The session entry on success or NULL on failure.
|
||||
*/
|
||||
am_cache_entry_t *am_cache_lock(request_rec *r,
|
||||
am_cache_entry_t *am_cache_lock(server_rec *s,
|
||||
am_cache_key_t type,
|
||||
const char *key)
|
||||
{
|
||||
am_mod_cfg_rec *mod_cfg;
|
||||
void *table;
|
||||
apr_size_t i;
|
||||
am_cache_entry_t *table;
|
||||
int i;
|
||||
int rv;
|
||||
char buffer[512];
|
||||
|
||||
|
@ -94,24 +51,26 @@ am_cache_entry_t *am_cache_lock(request_rec *r,
|
|||
|
||||
switch (type) {
|
||||
case AM_CACHE_SESSION:
|
||||
if (strlen(key) != AM_ID_LENGTH)
|
||||
if (strlen(key) != AM_SESSION_ID_LENGTH)
|
||||
return NULL;
|
||||
break;
|
||||
case AM_CACHE_NAMEID:
|
||||
if (strlen(key) > AM_CACHE_MAX_LASSO_IDENTITY_SIZE)
|
||||
return NULL;
|
||||
break;
|
||||
default:
|
||||
return NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
mod_cfg = am_get_mod_cfg(r->server);
|
||||
mod_cfg = am_get_mod_cfg(s);
|
||||
|
||||
|
||||
/* Lock the table. */
|
||||
if((rv = apr_global_mutex_lock(mod_cfg->lock)) != APR_SUCCESS) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"apr_global_mutex_lock() failed [%d]: %s",
|
||||
rv, apr_strerror(rv, buffer, sizeof(buffer)));
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
|
||||
"apr_global_mutex_lock() failed [%d]: %s",
|
||||
rv, apr_strerror(rv, buffer, sizeof(buffer)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -119,21 +78,15 @@ am_cache_entry_t *am_cache_lock(request_rec *r,
|
|||
|
||||
|
||||
for(i = 0; i < mod_cfg->init_cache_size; i++) {
|
||||
am_cache_entry_t *e = am_cache_entry_ptr(mod_cfg, table, i);
|
||||
const char *tablekey;
|
||||
|
||||
if (e->key[0] == '\0') {
|
||||
/* This entry is empty. Skip it. */
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (type) {
|
||||
case AM_CACHE_SESSION:
|
||||
tablekey = e->key;
|
||||
tablekey = table[i].key;
|
||||
break;
|
||||
case AM_CACHE_NAMEID:
|
||||
/* tablekey may be NULL */
|
||||
tablekey = am_cache_env_fetch_first(e, "NAME_ID");
|
||||
tablekey = am_cache_env_fetch_first(&table[i], "NAME_ID");
|
||||
break;
|
||||
default:
|
||||
tablekey = NULL;
|
||||
|
@ -144,16 +97,10 @@ am_cache_entry_t *am_cache_lock(request_rec *r,
|
|||
continue;
|
||||
|
||||
if(strcmp(tablekey, key) == 0) {
|
||||
apr_time_t now = apr_time_now();
|
||||
/* We found the entry. */
|
||||
if(e->expires > now) {
|
||||
if(table[i].expires > apr_time_now()) {
|
||||
/* And it hasn't expired. */
|
||||
return e;
|
||||
}
|
||||
else {
|
||||
am_diag_log_cache_entry(r, 0, e,
|
||||
"found expired session, now %s\n",
|
||||
am_diag_time_t_to_8601(r, now));
|
||||
return &table[i];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -166,109 +113,6 @@ am_cache_entry_t *am_cache_lock(request_rec *r,
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static inline bool am_cache_entry_slot_is_empty(am_cache_storage_t *slot)
|
||||
{
|
||||
return (slot->ptr == 0);
|
||||
}
|
||||
|
||||
static inline void am_cache_storage_null(am_cache_storage_t *slot)
|
||||
{
|
||||
slot->ptr = 0;
|
||||
}
|
||||
|
||||
static inline void am_cache_entry_env_null(am_cache_entry_t *e)
|
||||
{
|
||||
for (int i = 0; i < AM_CACHE_ENVSIZE; i++) {
|
||||
am_cache_storage_null(&e->env[i].varname);
|
||||
am_cache_storage_null(&e->env[i].value);
|
||||
}
|
||||
}
|
||||
|
||||
static inline apr_size_t am_cache_entry_pool_left(am_cache_entry_t *e)
|
||||
{
|
||||
return e->pool_size - e->pool_used;
|
||||
}
|
||||
|
||||
static inline apr_size_t am_cache_entry_pool_size(am_mod_cfg_rec *cfg)
|
||||
{
|
||||
return cfg->init_entry_size - sizeof(am_cache_entry_t);
|
||||
}
|
||||
|
||||
/* This function sets a string into the specified storage on the entry.
|
||||
*
|
||||
* NOTE: The string pointer may be NULL, in that case storage is freed
|
||||
* and set to NULL.
|
||||
*
|
||||
* Parametrs:
|
||||
* am_cache_entry_t *entry Pointer to an entry
|
||||
* am_cache_storage_t *slot Pointer to storage
|
||||
* const char *string Pointer to a replacement string
|
||||
*
|
||||
* Returns:
|
||||
* 0 on success, HTTP_INTERNAL_SERVER_ERROR on error.
|
||||
*/
|
||||
static int am_cache_entry_store_string(am_cache_entry_t *entry,
|
||||
am_cache_storage_t *slot,
|
||||
const char *string)
|
||||
{
|
||||
char *datastr = NULL;
|
||||
apr_size_t datalen = 0;
|
||||
apr_size_t str_len = 0;
|
||||
|
||||
if (string == NULL) return 0;
|
||||
|
||||
if (slot->ptr != 0) {
|
||||
datastr = &entry->pool[slot->ptr];
|
||||
datalen = strlen(datastr) + 1;
|
||||
}
|
||||
str_len = strlen(string) + 1;
|
||||
if (str_len - datalen <= 0) {
|
||||
memcpy(datastr, string, str_len);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* recover space if slot happens to point to the last allocated space */
|
||||
if (slot->ptr + datalen == entry->pool_used) {
|
||||
entry->pool_used -= datalen;
|
||||
slot->ptr = 0;
|
||||
}
|
||||
|
||||
if (am_cache_entry_pool_left(entry) < str_len) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
||||
"apr_cache_entry_store_string() asked %zd available: %zd. "
|
||||
"It may be a good idea to increase MellonCacheEntrySize.",
|
||||
str_len, am_cache_entry_pool_left(entry));
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
slot->ptr = entry->pool_used;
|
||||
datastr = &entry->pool[slot->ptr];
|
||||
memcpy(datastr, string, str_len);
|
||||
entry->pool_used += str_len;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Returns a pointer to the string in the storage slot specified
|
||||
*
|
||||
*
|
||||
* Parametrs:
|
||||
* am_cache_entry_t *entry Pointer to an entry
|
||||
* am_cache_storage_t *slot Pointer to storage slot
|
||||
*
|
||||
* Returns:
|
||||
* A string or NULL if the slot is empty.
|
||||
*/
|
||||
const char *am_cache_entry_get_string(am_cache_entry_t *e,
|
||||
am_cache_storage_t *slot)
|
||||
{
|
||||
char *ret = NULL;
|
||||
|
||||
if (slot->ptr != 0) {
|
||||
ret = &e->pool[slot->ptr];
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This function locks the session table and creates a new session entry.
|
||||
* It will first attempt to locate a free session. If it doesn't find a
|
||||
|
@ -277,21 +121,18 @@ const char *am_cache_entry_get_string(am_cache_entry_t *e,
|
|||
* Remember to unlock the table with am_cache_unlock(...) afterwards.
|
||||
*
|
||||
* Parameters:
|
||||
* request_rec *r The request we are processing.
|
||||
* server_rec *s The current server.
|
||||
* const char *key The key of the session to allocate.
|
||||
* const char *cookie_token The cookie token to tie the session to.
|
||||
*
|
||||
* Returns:
|
||||
* The new session entry on success. NULL if key is a invalid session
|
||||
* key.
|
||||
*/
|
||||
am_cache_entry_t *am_cache_new(request_rec *r,
|
||||
const char *key,
|
||||
const char *cookie_token)
|
||||
am_cache_entry_t *am_cache_new(server_rec *s, const char *key)
|
||||
{
|
||||
am_cache_entry_t *t;
|
||||
am_mod_cfg_rec *mod_cfg;
|
||||
void *table;
|
||||
am_cache_entry_t *table;
|
||||
apr_time_t current_time;
|
||||
int i;
|
||||
apr_time_t age;
|
||||
|
@ -299,19 +140,19 @@ am_cache_entry_t *am_cache_new(request_rec *r,
|
|||
char buffer[512];
|
||||
|
||||
/* Check if we have a valid session key. We abort if we don't. */
|
||||
if(key == NULL || strlen(key) != AM_ID_LENGTH) {
|
||||
if(key == NULL || strlen(key) != AM_SESSION_ID_LENGTH) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
mod_cfg = am_get_mod_cfg(r->server);
|
||||
mod_cfg = am_get_mod_cfg(s);
|
||||
|
||||
|
||||
/* Lock the table. */
|
||||
if((rv = apr_global_mutex_lock(mod_cfg->lock)) != APR_SUCCESS) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"apr_global_mutex_lock() failed [%d]: %s",
|
||||
rv, apr_strerror(rv, buffer, sizeof(buffer)));
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
|
||||
"apr_global_mutex_lock() failed [%d]: %s",
|
||||
rv, apr_strerror(rv, buffer, sizeof(buffer)));
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -326,7 +167,7 @@ am_cache_entry_t *am_cache_new(request_rec *r,
|
|||
* initalize it to the first entry in the table to simplify the
|
||||
* following code (saves test for t == NULL).
|
||||
*/
|
||||
t = am_cache_entry_ptr(mod_cfg, table, 0);
|
||||
t = &table[0];
|
||||
|
||||
/* Iterate over the session table. Update 't' to match the "best"
|
||||
* entry (the least recently used). 't' will point a free entry
|
||||
|
@ -334,30 +175,25 @@ am_cache_entry_t *am_cache_new(request_rec *r,
|
|||
* used entry.
|
||||
*/
|
||||
for(i = 0; i < mod_cfg->init_cache_size; i++) {
|
||||
am_cache_entry_t *e = am_cache_entry_ptr(mod_cfg, table, i);
|
||||
if (e->key[0] == '\0') {
|
||||
if(table[i].key[0] == '\0') {
|
||||
/* This entry is free. Update 't' to this entry
|
||||
* and exit loop.
|
||||
*/
|
||||
t = e;
|
||||
t = &table[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if (e->expires <= current_time) {
|
||||
if(table[i].expires <= current_time) {
|
||||
/* This entry is expired, and is therefore free.
|
||||
* Update 't' and exit loop.
|
||||
*/
|
||||
t = e;
|
||||
am_diag_log_cache_entry(r, 0, e,
|
||||
"%s ejecting expired sessions, now %s\n",
|
||||
__func__,
|
||||
am_diag_time_t_to_8601(r, current_time));
|
||||
t = &table[i];
|
||||
break;
|
||||
}
|
||||
|
||||
if (e->access < t->access) {
|
||||
if(table[i].access < t->access) {
|
||||
/* This entry is older than 't' - update 't'. */
|
||||
t = e;
|
||||
t = &table[i];
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -367,11 +203,11 @@ am_cache_entry_t *am_cache_new(request_rec *r,
|
|||
age = (current_time - t->access) / 1000000;
|
||||
|
||||
if(age < 3600) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_NOTICE, 0, r,
|
||||
"Dropping LRU entry entry with age = %" APR_TIME_T_FMT
|
||||
"s, which is less than one hour. It may be a good"
|
||||
" idea to increase MellonCacheSize.",
|
||||
age);
|
||||
ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, s,
|
||||
"Dropping LRU entry entry with age = %" APR_TIME_T_FMT
|
||||
"s, which is less than one hour. It may be a good"
|
||||
" idea to increase MellonCacheSize.",
|
||||
age);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -386,34 +222,10 @@ am_cache_entry_t *am_cache_new(request_rec *r,
|
|||
|
||||
t->logged_in = 0;
|
||||
t->size = 0;
|
||||
t->user[0] = '\0';
|
||||
|
||||
am_cache_storage_null(&t->cookie_token);
|
||||
am_cache_storage_null(&t->user);
|
||||
am_cache_storage_null(&t->lasso_identity);
|
||||
am_cache_storage_null(&t->lasso_session);
|
||||
am_cache_storage_null(&t->lasso_saml_response);
|
||||
am_cache_entry_env_null(t);
|
||||
|
||||
t->pool_size = am_cache_entry_pool_size(mod_cfg);
|
||||
t->pool[0] = '\0';
|
||||
t->pool_used = 1;
|
||||
|
||||
rv = am_cache_entry_store_string(t, &t->cookie_token, cookie_token);
|
||||
if (rv != 0) {
|
||||
/* For some strange reason our cookie token is too big to fit in the
|
||||
* session. This should never happen outside of absurd configurations.
|
||||
*/
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Unable to store cookie token in new session.");
|
||||
t->key[0] = '\0'; /* Mark the entry as free. */
|
||||
apr_global_mutex_unlock(mod_cfg->lock);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
am_diag_printf(r, "%s created new session, id=%s at %s"
|
||||
" cookie_token=\"%s\"\n",
|
||||
__func__, t->key, am_diag_time_t_to_8601(r, current_time),
|
||||
cookie_token);
|
||||
t->lasso_identity[0] = '\0';
|
||||
t->lasso_session[0] = '\0';
|
||||
|
||||
return t;
|
||||
}
|
||||
|
@ -422,20 +234,20 @@ am_cache_entry_t *am_cache_new(request_rec *r,
|
|||
/* This function unlocks a session entry.
|
||||
*
|
||||
* Parameters:
|
||||
* request_rec *r The request we are processing.
|
||||
* server_rec *s The current server.
|
||||
* am_cache_entry_t *entry The session entry.
|
||||
*
|
||||
* Returns:
|
||||
* Nothing.
|
||||
*/
|
||||
void am_cache_unlock(request_rec *r, am_cache_entry_t *entry)
|
||||
void am_cache_unlock(server_rec *s, am_cache_entry_t *entry)
|
||||
{
|
||||
am_mod_cfg_rec *mod_cfg;
|
||||
|
||||
/* Update access time. */
|
||||
entry->access = apr_time_now();
|
||||
|
||||
mod_cfg = am_get_mod_cfg(r->server);
|
||||
mod_cfg = am_get_mod_cfg(s);
|
||||
apr_global_mutex_unlock(mod_cfg->lock);
|
||||
}
|
||||
|
||||
|
@ -444,14 +256,13 @@ void am_cache_unlock(request_rec *r, am_cache_entry_t *entry)
|
|||
* timestamp is earlier than the previous.
|
||||
*
|
||||
* Parameters:
|
||||
* request_rec *r The request we are processing.
|
||||
* am_cache_entry_t *t The current session.
|
||||
* apr_time_t expires The new timestamp.
|
||||
*
|
||||
* Returns:
|
||||
* Nothing.
|
||||
*/
|
||||
void am_cache_update_expires(request_rec *r, am_cache_entry_t *t, apr_time_t expires)
|
||||
void am_cache_update_expires(am_cache_entry_t *t, apr_time_t expires)
|
||||
{
|
||||
/* Check if we should update the expires timestamp. */
|
||||
if(t->expires == 0 || t->expires > expires) {
|
||||
|
@ -475,36 +286,27 @@ void am_cache_update_expires(request_rec *r, am_cache_entry_t *t, apr_time_t exp
|
|||
int am_cache_env_append(am_cache_entry_t *t,
|
||||
const char *var, const char *val)
|
||||
{
|
||||
int status;
|
||||
|
||||
/* Make sure that the name and value will fit inside the
|
||||
* fixed size buffer.
|
||||
*/
|
||||
if(strlen(val) >= AM_CACHE_VALSIZE ||
|
||||
strlen(var) >= AM_CACHE_VARSIZE) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
||||
"Unable to store session data because it is to big. "
|
||||
"Name = \"%s\"; Value = \"%s\".", var, val);
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
if(t->size >= AM_CACHE_ENVSIZE) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
||||
"Unable to store attribute value because we have"
|
||||
" reached the maximum number of name-value pairs for"
|
||||
" this session. The maximum number is %d.",
|
||||
AM_CACHE_ENVSIZE);
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
status = am_cache_entry_store_string(t, &t->env[t->size].varname, var);
|
||||
if (status != 0) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
||||
"Unable to store session data because there is no more "
|
||||
"space in the session. Attribute Name = \"%s\".", var);
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
status = am_cache_entry_store_string(t, &t->env[t->size].value, val);
|
||||
if (status != 0) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
||||
"Unable to store session data because there is no more "
|
||||
"space in the session. Attribute Value = \"%s\".", val);
|
||||
" this session.");
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
strcpy(t->env[t->size].varname, var);
|
||||
strcpy(t->env[t->size].value, val);
|
||||
t->size++;
|
||||
|
||||
return OK;
|
||||
|
@ -523,15 +325,11 @@ int am_cache_env_append(am_cache_entry_t *t,
|
|||
const char *am_cache_env_fetch_first(am_cache_entry_t *t,
|
||||
const char *var)
|
||||
{
|
||||
const char *str;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < t->size; i++) {
|
||||
str = am_cache_entry_get_string(t, &t->env[i].varname);
|
||||
if (str == NULL)
|
||||
break;
|
||||
if (strcmp(str, var) == 0)
|
||||
return am_cache_entry_get_string(t, &t->env[i].value);
|
||||
for (i = 0; t->size; i++) {
|
||||
if (strcmp(t->env[i].varname, var) == 0)
|
||||
return t->env[i].value;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
@ -553,30 +351,19 @@ void am_cache_env_populate(request_rec *r, am_cache_entry_t *t)
|
|||
am_dir_cfg_rec *d;
|
||||
int i;
|
||||
apr_hash_t *counters;
|
||||
am_envattr_conf_t *env_varname_conf;
|
||||
const char *varname;
|
||||
const char *varname_prefix;
|
||||
const char *env_varname;
|
||||
const char *value;
|
||||
const char *prefixed_varname;
|
||||
int *count;
|
||||
int status;
|
||||
|
||||
d = am_get_dir_cfg(r);
|
||||
|
||||
/* Check if the user attribute has been set, and set it if it
|
||||
* hasn't been set. */
|
||||
if (am_cache_entry_slot_is_empty(&t->user)) {
|
||||
if(t->user[0] == '\0') {
|
||||
for(i = 0; i < t->size; ++i) {
|
||||
varname = am_cache_entry_get_string(t, &t->env[i].varname);
|
||||
if (strcasecmp(varname, d->userattr) == 0) {
|
||||
value = am_cache_entry_get_string(t, &t->env[i].value);
|
||||
status = am_cache_entry_store_string(t, &t->user, value);
|
||||
if (status != 0) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_NOTICE, 0, r,
|
||||
"Unable to store the user name because there"
|
||||
" is no more space in the session. "
|
||||
"Username = \"%s\".", value);
|
||||
}
|
||||
if(strcmp(t->env[i].varname, d->userattr) == 0) {
|
||||
strcpy(t->user, t->env[i].value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -588,37 +375,22 @@ void am_cache_env_populate(request_rec *r, am_cache_entry_t *t)
|
|||
* received from the IdP.
|
||||
*/
|
||||
for(i = 0; i < t->size; ++i) {
|
||||
varname = am_cache_entry_get_string(t, &t->env[i].varname);
|
||||
varname_prefix = d->env_prefix;
|
||||
varname = t->env[i].varname;
|
||||
|
||||
/* Check if we should map this name into another name. */
|
||||
env_varname_conf = (am_envattr_conf_t *)apr_hash_get(
|
||||
env_varname = (const char*)apr_hash_get(
|
||||
d->envattr, varname, APR_HASH_KEY_STRING);
|
||||
|
||||
if(env_varname_conf != NULL) {
|
||||
varname = env_varname_conf->name;
|
||||
if (!env_varname_conf->prefixed) {
|
||||
varname_prefix = "";
|
||||
}
|
||||
if(env_varname != NULL) {
|
||||
varname = env_varname;
|
||||
}
|
||||
|
||||
value = am_cache_entry_get_string(t, &t->env[i].value);
|
||||
value = t->env[i].value;
|
||||
|
||||
/*
|
||||
* If we find a variable remapping to MellonUser, use it.
|
||||
*/
|
||||
if (am_cache_entry_slot_is_empty(&t->user) &&
|
||||
(strcasecmp(varname, d->userattr) == 0)) {
|
||||
status = am_cache_entry_store_string(t, &t->user, value);
|
||||
if (status != 0) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_NOTICE, 0, r,
|
||||
"Unable to store the user name because there"
|
||||
" is no more space in the session. "
|
||||
"Username = \"%s\".", value);
|
||||
}
|
||||
}
|
||||
|
||||
prefixed_varname = apr_pstrcat(r->pool, varname_prefix, varname, NULL);
|
||||
if ((t->user[0] == '\0') && (strcmp(varname, d->userattr) == 0))
|
||||
strcpy(t->user, value);
|
||||
|
||||
/* Find the number of times this variable has been set. */
|
||||
count = apr_hash_get(counters, varname, APR_HASH_KEY_STRING);
|
||||
|
@ -630,56 +402,29 @@ void am_cache_env_populate(request_rec *r, am_cache_entry_t *t)
|
|||
apr_hash_set(counters, varname, APR_HASH_KEY_STRING, count);
|
||||
|
||||
/* Add the variable without a suffix. */
|
||||
apr_table_set(r->subprocess_env,prefixed_varname,value);
|
||||
}
|
||||
|
||||
/* Check if merging of environment variables is disabled.
|
||||
* This is either if it is NULL (default value if not configured
|
||||
* by user) or an empty string (if specifically disabled by the user).
|
||||
*/
|
||||
if (d->merge_env_vars == NULL || *d->merge_env_vars == '\0') {
|
||||
|
||||
/* Add the variable with a suffix indicating how many times it has
|
||||
* been added before.
|
||||
*/
|
||||
apr_table_set(r->subprocess_env,
|
||||
apr_psprintf(r->pool, "%s_%d", prefixed_varname,
|
||||
(d->env_vars_index_start > -1
|
||||
? *count + d->env_vars_index_start
|
||||
: *count)),
|
||||
apr_pstrcat(r->pool, "MELLON_", varname, NULL),
|
||||
value);
|
||||
|
||||
} else if (*count > 0) {
|
||||
|
||||
/*
|
||||
* Merge multiple values, separating by default with ";"
|
||||
* this makes auth_mellon work same way mod_shib is:
|
||||
* https://wiki.shibboleth.net/confluence/display/SHIB2/NativeSPAttributeAccess
|
||||
*/
|
||||
apr_table_set(r->subprocess_env,
|
||||
prefixed_varname,
|
||||
apr_pstrcat(r->pool,
|
||||
apr_table_get(r->subprocess_env,prefixed_varname),
|
||||
d->merge_env_vars, value, NULL));
|
||||
}
|
||||
|
||||
|
||||
/* Add the variable with a suffix indicating how many times it has
|
||||
* been added before.
|
||||
*/
|
||||
apr_table_set(r->subprocess_env,
|
||||
apr_psprintf(r->pool, "MELLON_%s_%d", varname, *count),
|
||||
value);
|
||||
|
||||
/* Increase the count. */
|
||||
++(*count);
|
||||
|
||||
if (d->env_vars_count_in_n > 0) {
|
||||
apr_table_set(r->subprocess_env,
|
||||
apr_pstrcat(r->pool, prefixed_varname, "_N", NULL),
|
||||
apr_itoa(r->pool, *count));
|
||||
}
|
||||
}
|
||||
|
||||
if (!am_cache_entry_slot_is_empty(&t->user)) {
|
||||
if(t->user[0] != '\0') {
|
||||
/* We have a user-"name". Set r->user and r->ap_auth_type. */
|
||||
r->user = apr_pstrdup(r->pool, am_cache_entry_get_string(t, &t->user));
|
||||
r->user = apr_pstrdup(r->pool, t->user);
|
||||
r->ap_auth_type = apr_pstrdup(r->pool, "Mellon");
|
||||
} else {
|
||||
/* We don't have a user-"name". Log error. */
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_NOTICE, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_NOTICE, 0, r,
|
||||
"Didn't find the attribute \"%s\" in the attributes"
|
||||
" which were received from the IdP. Cannot set a user"
|
||||
" for this request without a valid user attribute.",
|
||||
|
@ -690,37 +435,33 @@ void am_cache_env_populate(request_rec *r, am_cache_entry_t *t)
|
|||
/* Populate with the session? */
|
||||
if (d->dump_session) {
|
||||
char *session;
|
||||
const char *srcstr;
|
||||
int srclen, dstlen;
|
||||
|
||||
srcstr = am_cache_entry_get_string(t, &t->lasso_session);
|
||||
srclen = strlen(srcstr);
|
||||
srclen = strlen(t->lasso_session);
|
||||
dstlen = apr_base64_encode_len(srclen);
|
||||
|
||||
session = apr_palloc(r->pool, dstlen);
|
||||
(void)apr_base64_encode(session, srcstr, srclen);
|
||||
(void)apr_base64_encode(session, t->lasso_session, srclen);
|
||||
apr_table_set(r->subprocess_env, "MELLON_SESSION", session);
|
||||
}
|
||||
|
||||
if (d->dump_saml_response) {
|
||||
const char *sr = am_cache_entry_get_string(t, &t->lasso_saml_response);
|
||||
if (sr) {
|
||||
apr_table_set(r->subprocess_env, "MELLON_SAML_RESPONSE", sr);
|
||||
}
|
||||
}
|
||||
if (d->dump_saml_response)
|
||||
apr_table_set(r->subprocess_env,
|
||||
"MELLON_SAML_RESPONSE",
|
||||
t->lasso_saml_response);
|
||||
}
|
||||
|
||||
|
||||
/* This function deletes a given key from the session store.
|
||||
*
|
||||
* Parameters:
|
||||
* request_rec *r The request we are processing.
|
||||
* server_rec *s The current server.
|
||||
* am_cache_entry_t *cache The entry we are deleting.
|
||||
*
|
||||
* Returns:
|
||||
* Nothing.
|
||||
*/
|
||||
void am_cache_delete(request_rec *r, am_cache_entry_t *cache)
|
||||
void am_cache_delete(server_rec *s, am_cache_entry_t *cache)
|
||||
{
|
||||
/* We write a null-byte at the beginning of the key to
|
||||
* mark this slot as unused.
|
||||
|
@ -728,7 +469,7 @@ void am_cache_delete(request_rec *r, am_cache_entry_t *cache)
|
|||
cache->key[0] = '\0';
|
||||
|
||||
/* Unlock the entry. */
|
||||
am_cache_unlock(r, cache);
|
||||
am_cache_unlock(s, cache);
|
||||
}
|
||||
|
||||
|
||||
|
@ -749,39 +490,56 @@ int am_cache_set_lasso_state(am_cache_entry_t *session,
|
|||
const char *lasso_session,
|
||||
const char *lasso_saml_response)
|
||||
{
|
||||
int status;
|
||||
|
||||
status = am_cache_entry_store_string(session,
|
||||
&session->lasso_identity,
|
||||
lasso_identity);
|
||||
if (status != 0) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
||||
"Lasso identity is too big for storage. Size of lasso"
|
||||
" identity is %" APR_SIZE_T_FMT ".",
|
||||
(apr_size_t)strlen(lasso_identity));
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
if(lasso_identity != NULL) {
|
||||
if(strlen(lasso_identity) < AM_CACHE_MAX_LASSO_IDENTITY_SIZE) {
|
||||
strcpy(session->lasso_identity, lasso_identity);
|
||||
} else {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
||||
"Lasso identity is to big for storage. Size of lasso"
|
||||
" identity is %" APR_SIZE_T_FMT ", max size is %"
|
||||
APR_SIZE_T_FMT ".",
|
||||
(apr_size_t)strlen(lasso_identity),
|
||||
(apr_size_t)AM_CACHE_MAX_LASSO_IDENTITY_SIZE - 1);
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
} else {
|
||||
/* No identity dump to save. */
|
||||
strcpy(session->lasso_identity, "");
|
||||
}
|
||||
|
||||
status = am_cache_entry_store_string(session,
|
||||
&session->lasso_session,
|
||||
lasso_session);
|
||||
if (status != 0) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
||||
"Lasso session is too big for storage. Size of lasso"
|
||||
" session is %" APR_SIZE_T_FMT ".",
|
||||
(apr_size_t)strlen(lasso_session));
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
|
||||
if(lasso_session != NULL) {
|
||||
if(strlen(lasso_session) < AM_CACHE_MAX_LASSO_SESSION_SIZE) {
|
||||
strcpy(session->lasso_session, lasso_session);
|
||||
} else {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
||||
"Lasso session is to big for storage. Size of lasso"
|
||||
" session is %" APR_SIZE_T_FMT ", max size is %"
|
||||
APR_SIZE_T_FMT ".",
|
||||
(apr_size_t)strlen(lasso_session),
|
||||
(apr_size_t)AM_CACHE_MAX_LASSO_SESSION_SIZE - 1);
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
} else {
|
||||
/* No session dump to save. */
|
||||
strcpy(session->lasso_session, "");
|
||||
}
|
||||
|
||||
status = am_cache_entry_store_string(session,
|
||||
&session->lasso_saml_response,
|
||||
lasso_saml_response);
|
||||
if (status != 0) {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
||||
"Lasso SAML response is too big for storage. Size of "
|
||||
"lasso SAML Response is %" APR_SIZE_T_FMT ".",
|
||||
(apr_size_t)strlen(lasso_saml_response));
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
if(lasso_saml_response != NULL) {
|
||||
if(strlen(lasso_saml_response) < AM_CACHE_MAX_LASSO_SAML_RESPONSE_SIZE) {
|
||||
strcpy(session->lasso_saml_response, lasso_saml_response);
|
||||
} else {
|
||||
ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
|
||||
"Lasso SAML response is to big for storage. "
|
||||
"Size of lasso session is %" APR_SIZE_T_FMT
|
||||
", max size is %" APR_SIZE_T_FMT ".",
|
||||
(apr_size_t)strlen(lasso_saml_response),
|
||||
(apr_size_t)AM_CACHE_MAX_LASSO_SAML_RESPONSE_SIZE - 1);
|
||||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
} else {
|
||||
/* No session dump to save. */
|
||||
strcpy(session->lasso_saml_response, "");
|
||||
}
|
||||
|
||||
return OK;
|
||||
|
@ -798,7 +556,11 @@ int am_cache_set_lasso_state(am_cache_entry_t *session,
|
|||
*/
|
||||
const char *am_cache_get_lasso_identity(am_cache_entry_t *session)
|
||||
{
|
||||
return am_cache_entry_get_string(session, &session->lasso_identity);
|
||||
if(strlen(session->lasso_identity) == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return session->lasso_identity;
|
||||
}
|
||||
|
||||
|
||||
|
@ -812,5 +574,9 @@ const char *am_cache_get_lasso_identity(am_cache_entry_t *session)
|
|||
*/
|
||||
const char *am_cache_get_lasso_session(am_cache_entry_t *session)
|
||||
{
|
||||
return am_cache_entry_get_string(session, &session->lasso_session);
|
||||
if(strlen(session->lasso_session) == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return session->lasso_session;
|
||||
}
|
||||
|
|
|
@ -1,57 +0,0 @@
|
|||
#ifndef AUTH_MELLON_COMPAT_H
|
||||
#define AUTH_MELLON_COMPAT_H
|
||||
|
||||
#include <glib.h>
|
||||
|
||||
#include "ap_config.h"
|
||||
#include "ap_release.h"
|
||||
#ifdef AP_NEED_SET_MUTEX_PERMS
|
||||
#include "unixd.h"
|
||||
#endif
|
||||
|
||||
/* Old glib compatibility */
|
||||
#if (GLIB_MAJOR_VERSION == 2) && (GLIB_MINOR_VERSION < 14)
|
||||
|
||||
static void g_hash_table_get_keys_helper(gpointer key, gpointer value,
|
||||
gpointer user_data)
|
||||
{
|
||||
GList **out = user_data;
|
||||
|
||||
*out = g_list_prepend(*out, key);
|
||||
}
|
||||
|
||||
static GList *g_hash_table_get_keys(GHashTable *ht)
|
||||
{
|
||||
GList *ret = NULL;
|
||||
|
||||
g_hash_table_foreach(ht, g_hash_table_get_keys_helper, &ret);
|
||||
|
||||
return g_list_reverse(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
/* "remote_ip" in struct conn_rec changed name to "client_ip" in Apache 2.4.
|
||||
* This function retrieves the corrent member depending on the Apache version.
|
||||
*/
|
||||
static inline const char *am_compat_request_ip(request_rec *r) {
|
||||
#if (AP_SERVER_MAJORVERSION_NUMBER == 2) && (AP_SERVER_MINORVERSION_NUMBER < 4)
|
||||
return r->connection->remote_ip;
|
||||
#else
|
||||
return r->connection->client_ip;
|
||||
#endif
|
||||
}
|
||||
|
||||
/* unixd_set_global_mutex_perms changed name to ap_unixd_set_global_mutex_perms
|
||||
* in Apache 2.4. This function provides a wrapper with the new name for old
|
||||
* versions.
|
||||
*/
|
||||
#ifdef AP_NEED_SET_MUTEX_PERMS
|
||||
#if (AP_SERVER_MAJORVERSION_NUMBER == 2) && (AP_SERVER_MINORVERSION_NUMBER < 4)
|
||||
static inline apr_status_t ap_unixd_set_global_mutex_perms(apr_global_mutex_t *gmutex) {
|
||||
return unixd_set_global_mutex_perms(gmutex);
|
||||
}
|
||||
#endif
|
||||
#endif /* AP_NEED_SET_MUTEX_PERMS */
|
||||
|
||||
#endif /* AUTH_MELLON_COMPAT_H */
|
File diff suppressed because it is too large
Load Diff
|
@ -21,9 +21,6 @@
|
|||
|
||||
#include "auth_mellon.h"
|
||||
|
||||
#ifdef APLOG_USE_MODULE
|
||||
APLOG_USE_MODULE(auth_mellon);
|
||||
#endif
|
||||
|
||||
/* This function retrieves the name of our cookie.
|
||||
*
|
||||
|
@ -44,49 +41,6 @@ static const char *am_cookie_name(request_rec *r)
|
|||
}
|
||||
|
||||
|
||||
/* Calculate the cookie parameters.
|
||||
*
|
||||
* Parameters:
|
||||
* request_rec *r The request we should set the cookie in.
|
||||
*
|
||||
* Returns:
|
||||
* The cookie parameters as a string.
|
||||
*/
|
||||
static const char *am_cookie_params(request_rec *r)
|
||||
{
|
||||
int secure_cookie;
|
||||
int http_only_cookie;
|
||||
const char *cookie_domain = ap_get_server_name(r);
|
||||
const char *cookie_path = "/";
|
||||
const char *cookie_samesite = "";
|
||||
am_dir_cfg_rec *cfg = am_get_dir_cfg(r);
|
||||
|
||||
if (cfg->cookie_domain) {
|
||||
cookie_domain = cfg->cookie_domain;
|
||||
}
|
||||
|
||||
if (cfg->cookie_path) {
|
||||
cookie_path = cfg->cookie_path;
|
||||
}
|
||||
|
||||
if (cfg->cookie_samesite == am_samesite_lax) {
|
||||
cookie_samesite = "; SameSite=Lax";
|
||||
} else if (cfg->cookie_samesite == am_samesite_strict) {
|
||||
cookie_samesite = "; SameSite=Strict";
|
||||
}
|
||||
|
||||
secure_cookie = cfg->secure;
|
||||
http_only_cookie = cfg->http_only;
|
||||
|
||||
return apr_psprintf(r->pool,
|
||||
"Version=1; Path=%s; Domain=%s%s%s%s",
|
||||
cookie_path, cookie_domain,
|
||||
http_only_cookie ? "; HttpOnly" : "",
|
||||
secure_cookie ? "; secure" : "",
|
||||
cookie_samesite);
|
||||
}
|
||||
|
||||
|
||||
/* This functions finds the value of our cookie.
|
||||
*
|
||||
* Parameters:
|
||||
|
@ -97,7 +51,6 @@ static const char *am_cookie_params(request_rec *r)
|
|||
*/
|
||||
const char *am_cookie_get(request_rec *r)
|
||||
{
|
||||
am_req_cfg_rec *req_cfg;
|
||||
const char *name;
|
||||
const char *value;
|
||||
const char *cookie;
|
||||
|
@ -111,8 +64,8 @@ const char *am_cookie_get(request_rec *r)
|
|||
}
|
||||
|
||||
/* Check if we have added a note on the current request. */
|
||||
req_cfg = am_get_req_cfg(r);
|
||||
value = req_cfg->cookie_value;
|
||||
value = (const char *)ap_get_module_config(r->request_config,
|
||||
&auth_mellon_module);
|
||||
if(value != NULL) {
|
||||
return value;
|
||||
}
|
||||
|
@ -160,17 +113,7 @@ const char *am_cookie_get(request_rec *r)
|
|||
*/
|
||||
value += strlen(name) + 1;
|
||||
|
||||
/* The cookie value may be double-quoted. */
|
||||
if(*value == '"') {
|
||||
value += 1;
|
||||
}
|
||||
|
||||
buffer = apr_pstrdup(r->pool, value);
|
||||
end = strchr(buffer, '"');
|
||||
if(end) {
|
||||
/* Double-quoted string. */
|
||||
*end = '\0';
|
||||
}
|
||||
end = strchr(buffer, ';');
|
||||
if(end) {
|
||||
*end = '\0';
|
||||
|
@ -195,31 +138,47 @@ const char *am_cookie_get(request_rec *r)
|
|||
*/
|
||||
void am_cookie_set(request_rec *r, const char *id)
|
||||
{
|
||||
am_req_cfg_rec *req_cfg;
|
||||
const char *name;
|
||||
const char *cookie_params;
|
||||
char *cookie;
|
||||
int secure_cookie;
|
||||
const char *cookie_domain = ap_get_server_name(r);
|
||||
const char *cookie_path = "/";
|
||||
am_dir_cfg_rec *cfg = am_get_dir_cfg(r);
|
||||
|
||||
if (id == NULL)
|
||||
return;
|
||||
|
||||
name = am_cookie_name(r);
|
||||
cookie_params = am_cookie_params(r);
|
||||
if (cfg->cookie_domain) {
|
||||
cookie_domain = cfg->cookie_domain;
|
||||
}
|
||||
|
||||
cookie = apr_psprintf(r->pool, "%s=%s; %s", name, id, cookie_params);
|
||||
if (cfg->cookie_path) {
|
||||
cookie_path = cfg->cookie_path;
|
||||
}
|
||||
|
||||
secure_cookie = cfg->secure;
|
||||
name = am_cookie_name(r);
|
||||
|
||||
cookie = apr_psprintf(r->pool,
|
||||
"%s=%s; Version=1; Path=%s; Domain=%s%s;",
|
||||
name, id, cookie_path, cookie_domain,
|
||||
secure_cookie ? "; HttpOnly; secure" : "");
|
||||
ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, r->server,
|
||||
"cookie_set: %s", cookie);
|
||||
|
||||
/* Setting the headers inn err_headers_out ensures that they will be
|
||||
* sent for all responses.
|
||||
/* For now we're setting the cookie in both header tables since
|
||||
* it is unclear which the user will be sent. After a minor release
|
||||
* this suddenly changed from headers_out to err_headers_out, so to
|
||||
* be on the safe side...
|
||||
*/
|
||||
apr_table_addn(r->headers_out, "Set-Cookie", cookie);
|
||||
apr_table_addn(r->err_headers_out, "Set-Cookie", cookie);
|
||||
|
||||
/* Add a note on the current request, to allow us to retrieve this
|
||||
* cookie in the current request.
|
||||
*/
|
||||
req_cfg = am_get_req_cfg(r);
|
||||
req_cfg->cookie_value = apr_pstrdup(r->pool, id);
|
||||
ap_set_module_config(r->request_config, &auth_mellon_module,
|
||||
apr_pstrdup(r->pool, id));
|
||||
}
|
||||
|
||||
|
||||
|
@ -235,48 +194,20 @@ void am_cookie_set(request_rec *r, const char *id)
|
|||
void am_cookie_delete(request_rec *r)
|
||||
{
|
||||
const char *name;
|
||||
const char *cookie_params;
|
||||
char *cookie;
|
||||
|
||||
name = am_cookie_name(r);
|
||||
cookie_params = am_cookie_params(r);
|
||||
|
||||
|
||||
/* Format a cookie. To delete a cookie we set the expires-timestamp
|
||||
* to the past.
|
||||
*/
|
||||
cookie = apr_psprintf(r->pool, "%s=NULL;"
|
||||
" version=1;"
|
||||
" expires=Thu, 01-Jan-1970 00:00:00 GMT;"
|
||||
" %s",
|
||||
name, cookie_params);
|
||||
" path=/",
|
||||
name);
|
||||
|
||||
apr_table_addn(r->headers_out, "Set-Cookie", cookie);
|
||||
apr_table_addn(r->err_headers_out, "Set-Cookie", cookie);
|
||||
}
|
||||
|
||||
/* Get string that is used to tie a session to a specific cookie.
|
||||
*
|
||||
* request_rec *r The current request.
|
||||
* Returns:
|
||||
* The cookie token, as a fixed length byte buffer.
|
||||
*/
|
||||
const char *am_cookie_token(request_rec *r)
|
||||
{
|
||||
const char *cookie_name = am_cookie_name(r);
|
||||
const char *cookie_domain = ap_get_server_name(r);
|
||||
const char *cookie_path = "/";
|
||||
am_dir_cfg_rec *cfg = am_get_dir_cfg(r);
|
||||
|
||||
if (cfg->cookie_domain) {
|
||||
cookie_domain = cfg->cookie_domain;
|
||||
}
|
||||
|
||||
if (cfg->cookie_path) {
|
||||
cookie_path = cfg->cookie_path;
|
||||
}
|
||||
|
||||
return apr_psprintf(r->pool, "Name='%s' Domain='%s' Path='%s'",
|
||||
cookie_name,
|
||||
cookie_domain,
|
||||
cookie_path
|
||||
);
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -19,16 +19,15 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "auth_mellon.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
|
||||
/* The size of the blocks we will allocate. */
|
||||
#define AM_HC_BLOCK_SIZE 1000
|
||||
|
||||
#ifdef APLOG_USE_MODULE
|
||||
APLOG_USE_MODULE(auth_mellon);
|
||||
#endif
|
||||
|
||||
/* This structure describes a single-linked list of downloaded blocks. */
|
||||
typedef struct am_hc_block_s {
|
||||
|
@ -98,25 +97,24 @@ static am_hc_block_t *am_hc_block_write(
|
|||
{
|
||||
apr_size_t num_cpy;
|
||||
|
||||
while(size > 0) {
|
||||
/* Find the number of bytes we should write to this block. */
|
||||
num_cpy = AM_HC_BLOCK_SIZE - block->used;
|
||||
if(num_cpy == 0) {
|
||||
/* This block is full -- allocate a new block. */
|
||||
block->next = am_hc_block_alloc(pool);
|
||||
block = block->next;
|
||||
num_cpy = AM_HC_BLOCK_SIZE;
|
||||
}
|
||||
if(num_cpy > size) {
|
||||
num_cpy = size;
|
||||
}
|
||||
/* Find the number of bytes we should write to this block. */
|
||||
num_cpy = AM_HC_BLOCK_SIZE - block->used;
|
||||
if(num_cpy > size) {
|
||||
num_cpy = size;
|
||||
}
|
||||
|
||||
/* Copy data to this block. */
|
||||
memcpy(&block->data[block->used], data, num_cpy);
|
||||
block->used += num_cpy;
|
||||
/* Copy data to this block. */
|
||||
memcpy(&block->data[block->used], data, num_cpy);
|
||||
block->used += num_cpy;
|
||||
|
||||
size -= num_cpy;
|
||||
data += num_cpy;
|
||||
if(block->used == AM_HC_BLOCK_SIZE) {
|
||||
/* This block is full. Allocate a new block, and continue
|
||||
* filling it.
|
||||
*/
|
||||
block->next = am_hc_block_alloc(pool);
|
||||
|
||||
return am_hc_block_write(block->next, pool, &data[num_cpy],
|
||||
size - num_cpy);
|
||||
}
|
||||
|
||||
/* The next write should be to this block. */
|
||||
|
@ -255,7 +253,7 @@ static CURL *am_httpclient_init_curl(request_rec *r, const char *uri,
|
|||
/* Initialize the curl object. */
|
||||
curl = curl_easy_init();
|
||||
if(curl == NULL) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to initialize a curl object.");
|
||||
return NULL;
|
||||
}
|
||||
|
@ -264,7 +262,7 @@ static CURL *am_httpclient_init_curl(request_rec *r, const char *uri,
|
|||
/* Set up error reporting. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_error);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to set curl error buffer: [%u]\n", res);
|
||||
goto cleanup_fail;
|
||||
}
|
||||
|
@ -272,7 +270,7 @@ static CURL *am_httpclient_init_curl(request_rec *r, const char *uri,
|
|||
/* Disable progress reporting. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to disable curl progress reporting: [%u] %s",
|
||||
res, curl_error);
|
||||
goto cleanup_fail;
|
||||
|
@ -281,7 +279,7 @@ static CURL *am_httpclient_init_curl(request_rec *r, const char *uri,
|
|||
/* Disable use of signals. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to disable signals in curl: [%u] %s",
|
||||
res, curl_error);
|
||||
goto cleanup_fail;
|
||||
|
@ -290,19 +288,37 @@ static CURL *am_httpclient_init_curl(request_rec *r, const char *uri,
|
|||
/* Set the timeout of the transfer. It is currently set to two minutes. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_TIMEOUT, 120L);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to set the timeout of the curl download:"
|
||||
" [%u] %s", res, curl_error);
|
||||
goto cleanup_fail;
|
||||
}
|
||||
|
||||
/* Enable SSL peer certificate verification. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1L);
|
||||
if(res != CURLE_OK) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to enable SSL peer certificate verification:"
|
||||
" [%u] %s", res, curl_error);
|
||||
goto cleanup_fail;
|
||||
}
|
||||
|
||||
/* Enable SSL peer hostname verification. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 1L);
|
||||
if(res != CURLE_OK) {
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to enable SSL peer hostname verification:"
|
||||
" [%u] %s", res, curl_error);
|
||||
goto cleanup_fail;
|
||||
}
|
||||
|
||||
/* If we have a CA configured, try to use it */
|
||||
if (cfg->idp_ca_file != NULL) {
|
||||
res = curl_easy_setopt(curl, CURLOPT_CAINFO, cfg->idp_ca_file->path);
|
||||
res = curl_easy_setopt(curl, CURLOPT_CAINFO, cfg->idp_ca_file);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to set SSL CA info %s:"
|
||||
" [%u] %s", cfg->idp_ca_file->path, res, curl_error);
|
||||
" [%u] %s", cfg->idp_ca_file, res, curl_error);
|
||||
goto cleanup_fail;
|
||||
}
|
||||
}
|
||||
|
@ -310,7 +326,7 @@ static CURL *am_httpclient_init_curl(request_rec *r, const char *uri,
|
|||
/* Enable fail on http error. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_FAILONERROR, 1L);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to enable failure on http error: [%u] %s",
|
||||
res, curl_error);
|
||||
goto cleanup_fail;
|
||||
|
@ -319,7 +335,7 @@ static CURL *am_httpclient_init_curl(request_rec *r, const char *uri,
|
|||
/* Select which uri we should download. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_URL, uri);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to set curl download uri to \"%s\": [%u] %s",
|
||||
uri, res, curl_error);
|
||||
goto cleanup_fail;
|
||||
|
@ -331,7 +347,7 @@ static CURL *am_httpclient_init_curl(request_rec *r, const char *uri,
|
|||
/* Set curl write function. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, am_hc_data_write);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to set the curl write function: [%u] %s",
|
||||
res, curl_error);
|
||||
goto cleanup_fail;
|
||||
|
@ -340,7 +356,7 @@ static CURL *am_httpclient_init_curl(request_rec *r, const char *uri,
|
|||
/* Set the curl write function parameter. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_WRITEDATA, bh);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to set the curl write function data: [%u] %s",
|
||||
res, curl_error);
|
||||
goto cleanup_fail;
|
||||
|
@ -367,7 +383,7 @@ static CURL *am_httpclient_init_curl(request_rec *r, const char *uri,
|
|||
* apr_size_t *size This is a pointer to where we will store the length
|
||||
* of the downloaded data, not including the
|
||||
* null-terminator we add. This parameter can be NULL.
|
||||
* int timeout Timeout in seconds, 0 for no timeout.
|
||||
* apr_time_t timeout Timeout in seconds, 0 for no timeout.
|
||||
* long *status Pointer to HTTP status code.
|
||||
*
|
||||
* Returns:
|
||||
|
@ -376,7 +392,7 @@ static CURL *am_httpclient_init_curl(request_rec *r, const char *uri,
|
|||
*/
|
||||
int am_httpclient_get(request_rec *r, const char *uri,
|
||||
void **buffer, apr_size_t *size,
|
||||
int timeout, long *status)
|
||||
apr_time_t timeout, long *status)
|
||||
{
|
||||
am_hc_block_header_t bh;
|
||||
CURL *curl;
|
||||
|
@ -392,18 +408,18 @@ int am_httpclient_get(request_rec *r, const char *uri,
|
|||
return HTTP_INTERNAL_SERVER_ERROR;
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(curl, CURLOPT_TIMEOUT, (long)timeout);
|
||||
res = curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to download data from the uri \"%s\", "
|
||||
"cannot set timeout to %ld: [%u] %s",
|
||||
uri, (long)timeout, res, curl_error);
|
||||
goto cleanup_fail;
|
||||
}
|
||||
|
||||
res = curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, (long)timeout);
|
||||
res = curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, timeout);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to download data from the uri \"%s\", "
|
||||
"cannot set connect timeout to %ld: [%u] %s",
|
||||
uri, (long)timeout, res, curl_error);
|
||||
|
@ -413,7 +429,7 @@ int am_httpclient_get(request_rec *r, const char *uri,
|
|||
/* Do the download. */
|
||||
res = curl_easy_perform(curl);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to download data from the uri \"%s\", "
|
||||
"transaction aborted: [%u] %s",
|
||||
uri, res, curl_error);
|
||||
|
@ -423,7 +439,7 @@ int am_httpclient_get(request_rec *r, const char *uri,
|
|||
if (status != NULL) {
|
||||
res = curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, status);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to download data from the uri \"%s\", "
|
||||
"no status report: [%u] %s",
|
||||
uri, res, curl_error);
|
||||
|
@ -496,7 +512,7 @@ int am_httpclient_post(request_rec *r, const char *uri,
|
|||
/* Enable POST request. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_POST, 1L);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to enable POST request: [%u] %s",
|
||||
res, curl_error);
|
||||
goto cleanup_fail;
|
||||
|
@ -505,7 +521,7 @@ int am_httpclient_post(request_rec *r, const char *uri,
|
|||
/* Set POST data size. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE, post_length);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to set the POST data length: [%u] %s",
|
||||
res, curl_error);
|
||||
goto cleanup_fail;
|
||||
|
@ -514,7 +530,7 @@ int am_httpclient_post(request_rec *r, const char *uri,
|
|||
/* Set POST data. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_POSTFIELDS, post_data);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to set the POST data: [%u] %s",
|
||||
res, curl_error);
|
||||
goto cleanup_fail;
|
||||
|
@ -540,7 +556,7 @@ int am_httpclient_post(request_rec *r, const char *uri,
|
|||
/* Set headers. */
|
||||
res = curl_easy_setopt(curl, CURLOPT_HTTPHEADER, ctheader);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to set content-type header to \"%s\": [%u] %s",
|
||||
content_type, res, curl_error);
|
||||
goto cleanup_fail;
|
||||
|
@ -550,7 +566,7 @@ int am_httpclient_post(request_rec *r, const char *uri,
|
|||
/* Do the download. */
|
||||
res = curl_easy_perform(curl);
|
||||
if(res != CURLE_OK) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Failed to download data from the uri \"%s\": [%u] %s",
|
||||
uri, res, curl_error);
|
||||
goto cleanup_fail;
|
||||
|
|
|
@ -21,54 +21,6 @@
|
|||
|
||||
#include "auth_mellon.h"
|
||||
|
||||
#ifdef APLOG_USE_MODULE
|
||||
APLOG_USE_MODULE(auth_mellon);
|
||||
#endif
|
||||
|
||||
/* Retrieve a session from the cache and validate its cookie settings
|
||||
*
|
||||
* Parameters:
|
||||
* request_rec *r The request we received from the user.
|
||||
* am_cache_key_t type AM_CACHE_SESSION or AM_CACHE_NAMEID
|
||||
* const char *key The session key or user
|
||||
*
|
||||
* Returns:
|
||||
* The session associated, or NULL if unable to retrieve the given session.
|
||||
*/
|
||||
am_cache_entry_t *am_lock_and_validate(request_rec *r,
|
||||
am_cache_key_t type,
|
||||
const char *key)
|
||||
{
|
||||
am_cache_entry_t *session = NULL;
|
||||
|
||||
am_diag_printf(r, "searching for session with key %s (%s) ... ",
|
||||
key, am_diag_cache_key_type_str(type));
|
||||
|
||||
session = am_cache_lock(r, type, key);
|
||||
if (session == NULL) {
|
||||
am_diag_printf(r, "not found\n");
|
||||
return NULL;
|
||||
} else {
|
||||
am_diag_printf(r, "found.\n");
|
||||
am_diag_log_cache_entry(r, 0, session, "Session Cache Entry");
|
||||
}
|
||||
|
||||
const char *cookie_token_session = am_cache_entry_get_string(
|
||||
session, &session->cookie_token);
|
||||
const char *cookie_token_target = am_cookie_token(r);
|
||||
if (strcmp(cookie_token_session, cookie_token_target)) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Session cookie parameter mismatch. "
|
||||
"Session created with {%s}, but current "
|
||||
"request has {%s}.",
|
||||
cookie_token_session,
|
||||
cookie_token_target);
|
||||
am_cache_unlock(r, session);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return session;
|
||||
}
|
||||
|
||||
/* This function gets the session associated with a user, using a cookie
|
||||
*
|
||||
|
@ -90,7 +42,7 @@ am_cache_entry_t *am_get_request_session(request_rec *r)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
return am_lock_and_validate(r, AM_CACHE_SESSION, session_id);
|
||||
return am_cache_lock(r->server, AM_CACHE_SESSION, session_id);
|
||||
}
|
||||
|
||||
/* This function gets the session associated with a user, using a NameID
|
||||
|
@ -105,7 +57,7 @@ am_cache_entry_t *am_get_request_session(request_rec *r)
|
|||
*/
|
||||
am_cache_entry_t *am_get_request_session_by_nameid(request_rec *r, char *nameid)
|
||||
{
|
||||
return am_lock_and_validate(r, AM_CACHE_NAMEID, nameid);
|
||||
return am_cache_lock(r->server, AM_CACHE_NAMEID, nameid);
|
||||
}
|
||||
|
||||
/* This function creates a new session.
|
||||
|
@ -121,22 +73,18 @@ am_cache_entry_t *am_new_request_session(request_rec *r)
|
|||
const char *session_id;
|
||||
|
||||
/* Generate session id. */
|
||||
session_id = am_generate_id(r);
|
||||
session_id = am_generate_session_id(r);
|
||||
if(session_id == NULL) {
|
||||
AM_LOG_RERROR(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
ap_log_rerror(APLOG_MARK, APLOG_ERR, 0, r,
|
||||
"Error creating session id.");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* Set session id. */
|
||||
am_cookie_set(r, session_id);
|
||||
|
||||
const char *cookie_token = am_cookie_token(r);
|
||||
|
||||
am_diag_printf(r, "%s id=%s cookie_token=\"%s\"\n",
|
||||
__func__, session_id, cookie_token);
|
||||
|
||||
return am_cache_new(r, session_id, cookie_token);
|
||||
return am_cache_new(r->server, session_id);
|
||||
}
|
||||
|
||||
|
||||
|
@ -152,7 +100,7 @@ am_cache_entry_t *am_new_request_session(request_rec *r)
|
|||
*/
|
||||
void am_release_request_session(request_rec *r, am_cache_entry_t *session)
|
||||
{
|
||||
am_cache_unlock(r, session);
|
||||
am_cache_unlock(r->server, session);
|
||||
}
|
||||
|
||||
|
||||
|
@ -168,8 +116,6 @@ void am_release_request_session(request_rec *r, am_cache_entry_t *session)
|
|||
*/
|
||||
void am_delete_request_session(request_rec *r, am_cache_entry_t *session)
|
||||
{
|
||||
am_diag_log_cache_entry(r, 0, session, "delete session");
|
||||
|
||||
/* Delete the cookie. */
|
||||
am_cookie_delete(r);
|
||||
|
||||
|
@ -178,5 +124,5 @@ void am_delete_request_session(request_rec *r, am_cache_entry_t *session)
|
|||
}
|
||||
|
||||
/* Delete session from the session store. */
|
||||
am_cache_delete(r, session);
|
||||
am_cache_delete(r->server, session);
|
||||
}
|
||||
|
|
1572
auth_mellon_util.c
1572
auth_mellon_util.c
File diff suppressed because it is too large
Load Diff
|
@ -1,4 +1,3 @@
|
|||
#!/bin/sh
|
||||
autoreconf --force --install
|
||||
rm -rf autom4te.cache/
|
||||
./configure "$@"
|
||||
|
|
55
configure.ac
55
configure.ac
|
@ -1,8 +1,4 @@
|
|||
AC_INIT([mod_auth_mellon],m4_esyscmd([tools/git-version-gen .tarball-version]),[olav.morken@uninett.no])
|
||||
AC_CONFIG_HEADERS([config.h])
|
||||
|
||||
# We require support for C99.
|
||||
AC_PROG_CC_C99
|
||||
AC_INIT([mod_auth_mellon],[0.4.0],[olav.morken@uninett.no])
|
||||
|
||||
AC_SUBST(NAMEVER, AC_PACKAGE_TARNAME()-AC_PACKAGE_VERSION())
|
||||
|
||||
|
@ -42,16 +38,6 @@ The executable may also be named 'apxs'.
|
|||
])
|
||||
fi
|
||||
|
||||
AC_ARG_ENABLE(
|
||||
[diagnostics],
|
||||
[AS_HELP_STRING([--enable-diagnostics],
|
||||
[Build with diagnostic support])],
|
||||
[],
|
||||
[enable_diagnostics=no])
|
||||
|
||||
AS_IF([test "x$enable_diagnostics" != xno],
|
||||
[AC_DEFINE([ENABLE_DIAGNOSTICS],[],[build with diagnostics])])
|
||||
|
||||
# Replace any occurances of @APXS2@ with the value of $APXS2 in the Makefile.
|
||||
AC_SUBST(APXS2)
|
||||
|
||||
|
@ -59,17 +45,9 @@ AC_SUBST(APXS2)
|
|||
PKG_CHECK_MODULES(LASSO, lasso)
|
||||
saved_LIBS=$LIBS; LIBS="$LIBS $LASSO_LIBS";
|
||||
AC_CHECK_LIB(lasso, lasso_server_new_from_buffers,
|
||||
[AC_DEFINE([HAVE_lasso_server_new_from_buffers],[],
|
||||
[lasso library exports lasso_server_new_from_buffers])])
|
||||
LASSO_CFLAGS="$LASSO_CFLAGS -DHAVE_lasso_server_new_from_buffers")
|
||||
AC_CHECK_LIB(lasso, lasso_server_load_metadata,
|
||||
[AC_DEFINE([HAVE_lasso_server_load_metadata],[],
|
||||
[lasso library exports lasso_server_load_metadata])])
|
||||
AC_CHECK_LIB(lasso, lasso_profile_set_signature_verify_hint,
|
||||
[AC_DEFINE([HAVE_lasso_profile_set_signature_verify_hint],[],
|
||||
[lasso library exports lasso_profile_set_signature_verify_hint])])
|
||||
AC_CHECK_LIB(lasso, lasso_ecp_request_new,
|
||||
[AC_DEFINE([HAVE_ECP],[],
|
||||
[lasso library supports ECP profile])])
|
||||
LASSO_CFLAGS="$LASSO_CFLAGS -DHAVE_lasso_server_load_metadata")
|
||||
LIBS=$saved_LIBS;
|
||||
AC_SUBST(LASSO_CFLAGS)
|
||||
AC_SUBST(LASSO_LIBS)
|
||||
|
@ -84,32 +62,9 @@ PKG_CHECK_MODULES(OPENSSL, openssl)
|
|||
AC_SUBST(OPENSSL_CFLAGS)
|
||||
AC_SUBST(OPENSSL_LIBS)
|
||||
|
||||
# We need at least version 2.12 of GLib.
|
||||
PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.12])
|
||||
AC_SUBST(GLIB_CFLAGS)
|
||||
AC_SUBST(GLIB_LIBS)
|
||||
# We need at least version 2.14 of GLib.
|
||||
PKG_CHECK_MODULES([GLIB], [glib-2.0 >= 2.14])
|
||||
|
||||
AC_SUBST(MELLON_CFLAGS)
|
||||
|
||||
# Test to see if we can include lasso/utils.h
|
||||
# AC_CHECK_HEADER won't work correctly unless we specifiy the include directories
|
||||
# found in the LASSO_CFLAGS. Save and restore CFLAGS and CPPFLAGS.
|
||||
saved_CFLAGS=$CFLAGS
|
||||
saved_CPPFLAGS=$CPPFLAGS
|
||||
CFLAGS="$CFLAGS $pkg_cv_LASSO_CFLAGS"
|
||||
CPPFLAGS="$CPPFLAGS $pkg_cv_LASSO_CFLAGS"
|
||||
AC_CHECK_HEADER([lasso/utils.h], LASSO_CFLAGS="$LASSO_CFLAGS -DHAVE_LASSO_UTILS_H")
|
||||
CFLAGS=$saved_CFLAGS
|
||||
CPPFLAGS=$saved_CPPFLAGS
|
||||
|
||||
# Determine what definitions exist in Lasso
|
||||
saved_CFLAGS=$CFLAGS
|
||||
CFLAGS="$CFLAGS $pkg_cv_LASSO_CFLAGS"
|
||||
AC_CHECK_DECLS([LASSO_SIGNATURE_METHOD_RSA_SHA256,
|
||||
LASSO_SIGNATURE_METHOD_RSA_SHA384,
|
||||
LASSO_SIGNATURE_METHOD_RSA_SHA512,
|
||||
], [], [], [#include <lasso/xml/xml.h>])
|
||||
CFLAGS=$saved_CFLAGS
|
||||
|
||||
# Create Makefile from Makefile.in
|
||||
AC_CONFIG_FILES([Makefile])
|
||||
|
|
|
@ -1,9 +1,3 @@
|
|||
libapache2-mod-auth-mellon (0.5.0-1) unstable; urgency=low
|
||||
|
||||
* Update version to 0.5.0.
|
||||
|
||||
-- Olav Morken <olav.morken@uninett.no> Fri, 09 Mar 2012 12:11:29 +0100
|
||||
|
||||
libapache2-mod-auth-mellon (0.4.0-1) unstable; urgency=low
|
||||
|
||||
* Update version to 0.4.0.
|
||||
|
|
|
@ -2,7 +2,7 @@ Source: libapache2-mod-auth-mellon
|
|||
Section: web
|
||||
Priority: extra
|
||||
Maintainer: Olav Morken <olavmrk@gmail.com>
|
||||
Build-Depends: debhelper (>= 5), autotools-dev, automake, autoconf, apache2-dev, libcurl3-dev, liblasso3-dev (>= 2.1.0)
|
||||
Build-Depends: debhelper (>= 5), autotools-dev, apache2-prefork-dev (>= 2.0.55), libcurl3-dev, liblasso3-dev (>= 2.1.0)
|
||||
Standards-Version: 3.7.2
|
||||
|
||||
Package: libapache2-mod-auth-mellon
|
||||
|
@ -17,5 +17,5 @@ Description: A SAML 2.0 authentication module for Apache
|
|||
|
||||
Package: libapache2-mod-auth-mellon-dbg
|
||||
Architecture: any
|
||||
Depends: libapache2-mod-auth-mellon
|
||||
Depends: libapache2-mod-auth-mellon (=${Source-Version})
|
||||
Description: Debug symbols for libapache2-mod-auth-mellon.
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
NEWS
|
||||
README
|
||||
TODO
|
||||
|
|
|
@ -1,25 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Convert urn:mace:shibboleth:2.0:attribute-map to MellonSetEnv statements
|
||||
|
||||
Author: Pat Riehecky <riehecky@fnal.gov>
|
||||
Copyright (2019). Fermi Research Alliance, LLC
|
||||
-->
|
||||
<xsl:stylesheet version="1.0"
|
||||
xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
|
||||
xmlns:map="urn:mace:shibboleth:2.0:attribute-map"
|
||||
>
|
||||
<xsl:output method="text" omit-xml-declaration="yes" indent="no"/>
|
||||
|
||||
<xsl:template match="/map:Attributes">
|
||||
<xsl:apply-templates select="map:Attribute">
|
||||
<xsl:sort select="@id" data-type="text" />
|
||||
<xsl:sort select="@name" data-type="text" order="descending"/>
|
||||
</xsl:apply-templates>
|
||||
</xsl:template>
|
||||
|
||||
<xsl:template match='map:Attribute'>
|
||||
<xsl:value-of select="concat('MellonSetEnvNoPrefix ', @id, ' ' , @name)"/><xsl:text>
</xsl:text>
|
||||
</xsl:template>
|
||||
|
||||
</xsl:stylesheet>
|
|
@ -1,11 +0,0 @@
|
|||
Bundler.require :default
|
||||
|
||||
guard 'shell' do
|
||||
watch(/^mellon_user_guide\.adoc$/) {|m|
|
||||
Asciidoctor.convert_file m[0]
|
||||
}
|
||||
end
|
||||
|
||||
guard 'livereload' do
|
||||
watch(%r{^.+\.(css|js|html)$})
|
||||
end
|
|
@ -1,21 +0,0 @@
|
|||
This is the mod_auth_mellon User Guide. It is written in AsciiDoc
|
||||
which is a popular plaintext markup language much like markdown or
|
||||
reStructuredText. You can find extensive documentation on AsciiDoc and
|
||||
AsciiDoctor on the web. AsciiDoc can be rendered into a variety of
|
||||
formats, but one of it's great advantages is the ability to produece
|
||||
DocBook.
|
||||
|
||||
There are many ways to render AsciiDoc, but the simplest to produce
|
||||
html is this:
|
||||
|
||||
% asciidoctor -a data-uri mellon_user_guide.adoc
|
||||
|
||||
Note: the "-a data-uri" causes the images to be inlined in the HTML
|
||||
output so that everything is contained in one HTML file.
|
||||
|
||||
If you want to edit the source it can be very useful to be able to see
|
||||
the rendered version as you work. This link is a guide on how to do
|
||||
that. Included in this directory is a Guardfile which can be used in
|
||||
conjuction with the live preview discussed in the link.
|
||||
|
||||
http://asciidoctor.org/docs/editing-asciidoc-with-live-preview/
|
Binary file not shown.
Before Width: | Height: | Size: 243 KiB |
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 302 KiB |
Binary file not shown.
Before Width: | Height: | Size: 133 KiB |
File diff suppressed because it is too large
Load Diff
Before Width: | Height: | Size: 164 KiB |
|
@ -1,812 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
width="6.776546in"
|
||||
height="5.968811in"
|
||||
viewBox="0 0 172.12427 151.6078"
|
||||
version="1.1"
|
||||
id="svg8"
|
||||
inkscape:version="0.92+devel unknown"
|
||||
sodipodi:docname="saml-web-sso.svg">
|
||||
<defs
|
||||
id="defs2">
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker13542"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path13540"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker12194"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lend">
|
||||
<path
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path12192"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker12008"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path12006"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker11121"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lend">
|
||||
<path
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path11119"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker10561"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path10559"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker10367"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path10365"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker10183"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path10181"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker10047"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path10045"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker9929"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lend">
|
||||
<path
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path9927"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker9811"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lend">
|
||||
<path
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path9809"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker9639"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path9637"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Lstart"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Lstart"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4364"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
|
||||
transform="matrix(0.8,0,0,0.8,10,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker9453"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path9451"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker9359"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path9357"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker9176"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lend">
|
||||
<path
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path9174"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker8948"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path8946"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
id="path4373"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker8521"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path8519"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="marker8133"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path8131"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
id="path4385"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
inkscape:connector-curvature="0" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend-6"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true"
|
||||
inkscape:collect="always">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4385-2"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow2Lend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow2Lend-9"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4385-0"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:isstock="true"
|
||||
style="overflow:visible"
|
||||
id="marker9176-2"
|
||||
refX="0"
|
||||
refY="0"
|
||||
orient="auto"
|
||||
inkscape:stockid="Arrow2Lend">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
transform="matrix(-1.1,0,0,-1.1,-1.1,0)"
|
||||
d="M 8.7185878,4.0337352 -2.2072895,0.01601326 8.7185884,-4.0017078 c -1.7454984,2.3720609 -1.7354408,5.6174519 -6e-7,8.035443 z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.625;stroke-linejoin:round;stroke-opacity:1"
|
||||
id="path9174-1" />
|
||||
</marker>
|
||||
<marker
|
||||
inkscape:stockid="Arrow1Mend"
|
||||
orient="auto"
|
||||
refY="0"
|
||||
refX="0"
|
||||
id="Arrow1Mend-1"
|
||||
style="overflow:visible"
|
||||
inkscape:isstock="true">
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4373-6"
|
||||
d="M 0,0 5,-5 -12.5,0 5,5 Z"
|
||||
style="fill:#000000;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:1.00000003pt;stroke-opacity:1"
|
||||
transform="matrix(-0.4,0,0,-0.4,-4,0)" />
|
||||
</marker>
|
||||
</defs>
|
||||
<sodipodi:namedview
|
||||
id="base"
|
||||
pagecolor="#ffffff"
|
||||
bordercolor="#666666"
|
||||
borderopacity="1.0"
|
||||
inkscape:pageopacity="0.0"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:zoom="0.98994949"
|
||||
inkscape:cx="289.16938"
|
||||
inkscape:cy="283.98371"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-rotation="0"
|
||||
showgrid="true"
|
||||
inkscape:window-width="1920"
|
||||
inkscape:window-height="1103"
|
||||
inkscape:window-x="0"
|
||||
inkscape:window-y="27"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:snap-text-baseline="true"
|
||||
units="in">
|
||||
<inkscape:grid
|
||||
type="xygrid"
|
||||
id="grid4267"
|
||||
originx="-123.04236"
|
||||
originy="-320.37079" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
inkscape:label="Layer 1"
|
||||
inkscape:groupmode="layer"
|
||||
id="layer1"
|
||||
transform="translate(-14.490125,-16.188666)">
|
||||
<g
|
||||
id="g8094">
|
||||
<g
|
||||
id="g4349">
|
||||
<rect
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.70599997;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4269"
|
||||
width="36.459583"
|
||||
height="15.875"
|
||||
x="14.843125"
|
||||
y="16.541666" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:3.96875px;line-height:125%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="32.880096"
|
||||
y="21.833294"
|
||||
id="text4273"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4271"
|
||||
x="32.880096"
|
||||
y="21.833294"
|
||||
style="stroke-width:0.26458332px">Browser</tspan></text>
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4362"
|
||||
d="M 33.068256,32.416668 V 167.35417"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend)"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
id="g8114">
|
||||
<g
|
||||
id="g4355">
|
||||
<rect
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.70599997;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4269-2"
|
||||
width="36.459583"
|
||||
height="15.875"
|
||||
x="82.311874"
|
||||
y="16.541666" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:3.96875px;line-height:125%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="100.34885"
|
||||
y="21.833294"
|
||||
id="text4273-5"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4271-8"
|
||||
x="100.34885"
|
||||
y="21.833294"
|
||||
style="stroke-width:0.26458332px">Service Provider</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="100.34885"
|
||||
y="26.794231"
|
||||
style="stroke-width:0.26458332px"
|
||||
id="tspan4325">(e.g. Mellon)</tspan></text>
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4362-9"
|
||||
d="M 100.53701,32.416668 V 167.35417"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend-6)"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<g
|
||||
id="g8127">
|
||||
<g
|
||||
id="g4360">
|
||||
<rect
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.70599997;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect4269-6"
|
||||
width="36.501942"
|
||||
height="15.875"
|
||||
x="149.75945"
|
||||
y="16.541666" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:3.96875px;line-height:125%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="167.8176"
|
||||
y="21.833294"
|
||||
id="text4273-2"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan4271-84"
|
||||
x="167.8176"
|
||||
y="21.833294"
|
||||
style="stroke-width:0.26458332px">Identity Provider</tspan></text>
|
||||
</g>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path4362-8"
|
||||
d="M 168.00576,32.416668 V 167.35417"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;marker-end:url(#Arrow2Lend-9)"
|
||||
sodipodi:nodetypes="cc" />
|
||||
</g>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.40569443;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker8133)"
|
||||
d="m 32.980878,46.524449 67.243102,-0.07039"
|
||||
id="path8129"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="41.003376"
|
||||
y="39.734055"
|
||||
id="text8173"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan8171"
|
||||
x="41.003376"
|
||||
y="39.734055"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start"
|
||||
id="tspan8930">1.</tspan> User attempts to access</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="41.003376"
|
||||
y="43.702805"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan8175">resource at SP</tspan></text>
|
||||
<g
|
||||
id="g14165">
|
||||
<rect
|
||||
y="37.235371"
|
||||
x="106.86239"
|
||||
height="9.3031454"
|
||||
width="52.736366"
|
||||
id="rect8177"
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.17638889;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1" />
|
||||
<text
|
||||
id="text8181"
|
||||
y="40.92421"
|
||||
x="108.40961"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan8183"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
y="40.92421"
|
||||
x="108.40961"
|
||||
sodipodi:role="line">Is there a session for this user?</tspan><tspan
|
||||
id="tspan8187"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
y="44.89296"
|
||||
x="108.40961"
|
||||
sodipodi:role="line">No, then create one.</tspan></text>
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-weight:normal;font-size:3.96875px;line-height:125%;font-family:sans-serif;text-align:center;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:middle;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="130.88298"
|
||||
y="43.221416"
|
||||
id="text8191"><tspan
|
||||
sodipodi:role="line"
|
||||
id="tspan8189"
|
||||
x="130.88298"
|
||||
y="46.73283"
|
||||
style="stroke-width:0.26458332px"></tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.40569443;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker8521)"
|
||||
d="M 100.54167,56.229167 H 29.104167 v 7.9375 l 137.873523,0.475306"
|
||||
id="path8511"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="108.40961"
|
||||
y="54.901424"
|
||||
id="text8173-5"><tspan
|
||||
sodipodi:role="line"
|
||||
x="108.40961"
|
||||
y="54.901424"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan8922"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start"
|
||||
id="tspan8928">2.</tspan> SP determines IdP. Creates</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="108.40961"
|
||||
y="58.870174"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan8926"><AuthnRequest> message and</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="108.40961"
|
||||
y="62.838924"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan8920">embeds it in URL redirect to IdP.</tspan></text>
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.40569443;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker10367)"
|
||||
d="M 168.01456,78.093696 H 33.390649"
|
||||
id="path9166"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.40569443;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker9929)"
|
||||
d="M 33.235937,92.461912 H 167.55173"
|
||||
id="path10513"
|
||||
inkscape:connector-curvature="0" />
|
||||
<path
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.40569443;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker10561)"
|
||||
d="M 167.9244,107.65285 H 28.971263 l 0.132904,9.43048 h 71.437503"
|
||||
id="path10551"
|
||||
inkscape:connector-curvature="0"
|
||||
sodipodi:nodetypes="cccc" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="41.003376"
|
||||
y="75.538948"
|
||||
id="text8173-5-1"><tspan
|
||||
sodipodi:role="line"
|
||||
x="41.003376"
|
||||
y="75.538948"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan8920-7">Login form sent to user</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="41.003376"
|
||||
y="89.566666"
|
||||
id="text8173-5-1-7"><tspan
|
||||
sodipodi:role="line"
|
||||
x="41.003376"
|
||||
y="89.566666"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan8920-7-7">User replies with userid & password</tspan></text>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="108.40961"
|
||||
y="86.209251"
|
||||
id="text8173-5-0"><tspan
|
||||
sodipodi:role="line"
|
||||
x="108.40961"
|
||||
y="86.209251"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan8920-1"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan8928-5">3.</tspan> IdP authenticates principal.</tspan></text>
|
||||
<g
|
||||
id="g11956"
|
||||
transform="translate(-1.0583333)">
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path11111"
|
||||
d="M 108.47917,85.333333 103.1875,80.041667"
|
||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.40569443;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend)" />
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path11111-8"
|
||||
d="M 108.47917,85.333333 103.1875,90.625"
|
||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.40569443;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#Arrow1Mend-1)" />
|
||||
</g>
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="108.40961"
|
||||
y="97.234795"
|
||||
id="text8173-5-04"><tspan
|
||||
sodipodi:role="line"
|
||||
x="108.40961"
|
||||
y="97.234795"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan8920-2"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan8928-4">4.</tspan> IdP responds with <Assertion></tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="108.40961"
|
||||
y="101.20354"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan11994">embedded in form which</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="108.40961"
|
||||
y="105.17229"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan11996">automatically posts to SP.</tspan></text>
|
||||
<path
|
||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.40569443;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker12008)"
|
||||
d="M 100.54167,130.3125 H 34.395833"
|
||||
id="path11998"
|
||||
inkscape:connector-curvature="0" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="41.003376"
|
||||
y="123.87157"
|
||||
id="text8173-4"><tspan
|
||||
sodipodi:role="line"
|
||||
x="41.003376"
|
||||
y="123.87157"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan8175-4"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan8930-5">6.</tspan> SP replies with redirect for</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="41.003376"
|
||||
y="127.84032"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan12182">original resource (RelayState)</tspan></text>
|
||||
<path
|
||||
sodipodi:nodetypes="cc"
|
||||
inkscape:connector-curvature="0"
|
||||
id="path12190"
|
||||
d="m 32.980878,143.36225 67.243102,-0.0704"
|
||||
style="fill:none;fill-rule:evenodd;stroke:#000000;stroke-width:0.40569443;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1;marker-end:url(#marker12194)" />
|
||||
<text
|
||||
id="text13526"
|
||||
y="137.62979"
|
||||
x="41.003376"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan13524"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
y="137.62979"
|
||||
x="41.003376"
|
||||
sodipodi:role="line"><tspan
|
||||
id="tspan13520"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start">7.</tspan> SP accesses resource again</tspan></text>
|
||||
<path
|
||||
inkscape:connector-curvature="0"
|
||||
id="path13538"
|
||||
d="M 100.54167,156.771 H 34.395833"
|
||||
style="opacity:1;vector-effect:none;fill:none;fill-opacity:1;fill-rule:evenodd;stroke:#000000;stroke-width:0.40569443;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;marker-end:url(#marker13542)" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="41.003376"
|
||||
y="152.97542"
|
||||
id="text14118"><tspan
|
||||
sodipodi:role="line"
|
||||
x="41.003376"
|
||||
y="152.97542"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan14116"><tspan
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start"
|
||||
id="tspan14114">8.</tspan> SP responds with resource</tspan></text>
|
||||
<text
|
||||
id="text14128"
|
||||
y="116.28479"
|
||||
x="108.40961"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
xml:space="preserve"><tspan
|
||||
id="tspan14122"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
y="116.28479"
|
||||
x="108.40961"
|
||||
sodipodi:role="line"><tspan
|
||||
id="tspan14120"
|
||||
style="font-style:normal;font-variant:normal;font-weight:bold;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Bold';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px">5.</tspan> SP validates <Assertion></tspan><tspan
|
||||
id="tspan14126"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
y="120.25354"
|
||||
x="108.40961"
|
||||
sodipodi:role="line">and creates user session.</tspan></text>
|
||||
<g
|
||||
id="g14171">
|
||||
<rect
|
||||
style="opacity:1;fill:none;fill-opacity:1;stroke:#000000;stroke-width:0.17638889;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1"
|
||||
id="rect14132"
|
||||
width="52.736366"
|
||||
height="9.3031454"
|
||||
x="106.81046"
|
||||
y="133.54376" />
|
||||
<text
|
||||
xml:space="preserve"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;line-height:125%;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;letter-spacing:0px;word-spacing:0px;writing-mode:lr-tb;text-anchor:start;fill:#000000;fill-opacity:1;stroke:none;stroke-width:0.26458332px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1"
|
||||
x="108.40961"
|
||||
y="137.2326"
|
||||
id="text14138"><tspan
|
||||
sodipodi:role="line"
|
||||
x="108.40961"
|
||||
y="137.2326"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan14134">Is there a session for this user?</tspan><tspan
|
||||
sodipodi:role="line"
|
||||
x="108.40961"
|
||||
y="141.20135"
|
||||
style="font-style:normal;font-variant:normal;font-weight:normal;font-stretch:normal;font-size:3.17499995px;font-family:sans-serif;-inkscape-font-specification:'sans-serif, Normal';font-variant-ligatures:normal;font-variant-caps:normal;font-variant-numeric:normal;font-feature-settings:normal;text-align:start;writing-mode:lr-tb;text-anchor:start;stroke-width:0.26458332px"
|
||||
id="tspan14136">Yes, validate & return resource.</tspan></text>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
Before Width: | Height: | Size: 46 KiB |
File diff suppressed because one or more lines are too long
|
@ -1,62 +0,0 @@
|
|||
#ifdef HAVE_LASSO_UTILS_H
|
||||
|
||||
#include <lasso/utils.h>
|
||||
|
||||
#else
|
||||
|
||||
#define lasso_assign_string(dest,src) \
|
||||
{ \
|
||||
char *__tmp = g_strdup(src); \
|
||||
lasso_release_string(dest); \
|
||||
dest = __tmp; \
|
||||
}
|
||||
|
||||
#define lasso_release_string(dest) \
|
||||
lasso_release_full(dest, g_free)
|
||||
|
||||
#define lasso_release_full(dest, free_function) \
|
||||
{ \
|
||||
if (dest) { \
|
||||
free_function(dest); dest = NULL; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define lasso_check_type_equality(a,b)
|
||||
|
||||
#define lasso_release_full2(dest, free_function, type) \
|
||||
{ \
|
||||
lasso_check_type_equality(dest, type); \
|
||||
if (dest) { \
|
||||
free_function(dest); dest = NULL; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define lasso_release_list(dest) \
|
||||
lasso_release_full2(dest, g_list_free, GList*)
|
||||
|
||||
#define lasso_release_list_of_full(dest, free_function) \
|
||||
{ \
|
||||
GList **__tmp = &(dest); \
|
||||
if (*__tmp) { \
|
||||
g_list_foreach(*__tmp, (GFunc)free_function, NULL); \
|
||||
lasso_release_list(*__tmp); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define lasso_release_list_of_strings(dest) \
|
||||
lasso_release_list_of_full(dest, g_free)
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef LASSO_SAML2_ECP_PROFILE_WANT_AUTHN_SIGNED
|
||||
#define LASSO_SAML2_ECP_PROFILE_WANT_AUTHN_SIGNED "urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp:2.0:WantAuthnRequestsSigned"
|
||||
#endif
|
||||
|
||||
#ifndef LASSO_SAML2_CONDITIONS_DELEGATION
|
||||
#define LASSO_SAML2_CONDITIONS_DELEGATION "urn:oasis:names:tc:SAML:2.0:conditions:delegation"
|
||||
#endif
|
||||
|
||||
#ifndef LASSO_SAML_EXT_CHANNEL_BINDING
|
||||
#define LASSO_SAML_EXT_CHANNEL_BINDING "urn:oasis:names:tc:SAML:protocol:ext:channel-binding"
|
||||
#endif
|
|
@ -33,10 +33,10 @@ if ! echo "$BASEURL" | grep -q '^https\?://'; then
|
|||
exit 1
|
||||
fi
|
||||
|
||||
HOST="$(echo "$BASEURL" | sed 's#^[a-z]*://\([^:/]*\).*#\1#')"
|
||||
HOST="$(echo "$BASEURL" | sed 's#^[a-z]*://\([^/]*\).*#\1#')"
|
||||
BASEURL="$(echo "$BASEURL" | sed 's#/$##')"
|
||||
|
||||
OUTFILE="$(echo "$ENTITYID" | sed 's/[^0-9A-Za-z.]/_/g' | sed 's/__*/_/g')"
|
||||
OUTFILE="$(echo "$ENTITYID" | sed 's/[^A-Za-z.]/_/g' | sed 's/__*/_/g')"
|
||||
echo "Output files:"
|
||||
echo "Private key: $OUTFILE.key"
|
||||
echo "Certificate: $OUTFILE.cert"
|
||||
|
|
|
@ -19,14 +19,16 @@
|
|||
*
|
||||
*/
|
||||
|
||||
|
||||
#include "auth_mellon.h"
|
||||
|
||||
#include <curl/curl.h>
|
||||
|
||||
#ifdef APLOG_USE_MODULE
|
||||
APLOG_USE_MODULE(auth_mellon);
|
||||
#ifdef AP_NEED_SET_MUTEX_PERMS
|
||||
#include "unixd.h"
|
||||
#endif
|
||||
|
||||
|
||||
/* This function is called after the configuration of the server is parsed
|
||||
* (it's a post-config hook).
|
||||
*
|
||||
|
@ -48,9 +50,10 @@ APLOG_USE_MODULE(auth_mellon);
|
|||
static int am_global_init(apr_pool_t *conf, apr_pool_t *log,
|
||||
apr_pool_t *tmp, server_rec *s)
|
||||
{
|
||||
am_cache_entry_t *table;
|
||||
apr_size_t mem_size;
|
||||
am_mod_cfg_rec *mod;
|
||||
int rv;
|
||||
int rv, i;
|
||||
const char userdata_key[] = "auth_mellon_init";
|
||||
char buffer[512];
|
||||
void *data;
|
||||
|
@ -90,13 +93,9 @@ static int am_global_init(apr_pool_t *conf, apr_pool_t *log,
|
|||
*/
|
||||
mod->init_cache_size = mod->cache_size;
|
||||
mod->init_lock_file = apr_pstrdup(conf, mod->lock_file);
|
||||
mod->init_entry_size = mod->entry_size;
|
||||
if (mod->init_entry_size < AM_CACHE_MIN_ENTRY_SIZE) {
|
||||
mod->init_entry_size = AM_CACHE_MIN_ENTRY_SIZE;
|
||||
}
|
||||
|
||||
/* find out the memory size of the cache */
|
||||
mem_size = mod->init_entry_size * mod->init_cache_size;
|
||||
mem_size = sizeof(am_cache_entry_t) * mod->init_cache_size;
|
||||
|
||||
|
||||
/* Create the shared memory, exit if it fails. */
|
||||
|
@ -110,7 +109,11 @@ static int am_global_init(apr_pool_t *conf, apr_pool_t *log,
|
|||
}
|
||||
|
||||
/* Initialize the session table. */
|
||||
am_cache_init(mod);
|
||||
table = apr_shm_baseaddr_get(mod->cache);
|
||||
for (i = 0; i < mod->cache_size; i++) {
|
||||
table[i].key[0] = '\0';
|
||||
table[i].access = 0;
|
||||
}
|
||||
|
||||
/* Now create the mutex that we need for locking the shared memory, then
|
||||
* test for success. we really need this, so we exit on failure. */
|
||||
|
@ -130,7 +133,7 @@ static int am_global_init(apr_pool_t *conf, apr_pool_t *log,
|
|||
/* On some platforms the mutex is implemented as a file. To allow child
|
||||
* processes running as a different user to open it, it is necessary to
|
||||
* change the permissions on it. */
|
||||
rv = ap_unixd_set_global_mutex_perms(mod->lock);
|
||||
rv = unixd_set_global_mutex_perms(mod->lock);
|
||||
if (rv != APR_SUCCESS) {
|
||||
ap_log_error(APLOG_MARK, APLOG_CRIT, rv, s,
|
||||
"Failed to set permissions on session table lock;"
|
||||
|
@ -185,55 +188,16 @@ static void am_child_init(apr_pool_t *p, server_rec *s)
|
|||
}
|
||||
|
||||
|
||||
static int am_create_request(request_rec *r)
|
||||
{
|
||||
am_req_cfg_rec *req_cfg;
|
||||
|
||||
req_cfg = apr_pcalloc(r->pool, sizeof(am_req_cfg_rec));
|
||||
|
||||
req_cfg->cookie_value = NULL;
|
||||
#ifdef HAVE_ECP
|
||||
req_cfg->ecp_authn_req = false;
|
||||
#endif /* HAVE_ECP */
|
||||
#ifdef ENABLE_DIAGNOSTICS
|
||||
req_cfg->diag_emitted = false;
|
||||
#endif
|
||||
|
||||
ap_set_module_config(r->request_config, &auth_mellon_module, req_cfg);
|
||||
|
||||
return OK;
|
||||
}
|
||||
|
||||
|
||||
static void register_hooks(apr_pool_t *p)
|
||||
{
|
||||
/* Our handler needs to run before mod_proxy so that it can properly
|
||||
* return ECP AuthnRequest messages when running as a reverse proxy.
|
||||
* See: https://github.com/Uninett/mod_auth_mellon/pull/196
|
||||
*/
|
||||
static const char * const run_handler_before[]={ "mod_proxy.c", NULL };
|
||||
|
||||
static char const * const hook_fixup_before[] = { "mod_ssl.c", NULL };
|
||||
ap_hook_access_checker(am_auth_mellon_user, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
ap_hook_check_user_id(am_check_uid, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
ap_hook_post_config(am_global_init, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
ap_hook_child_init(am_child_init, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
ap_hook_create_request(am_create_request, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
|
||||
/* Add the hook to handle requests to the mod_auth_mellon endpoint.
|
||||
*
|
||||
* This is APR_HOOK_FIRST because we do not expect nor require users
|
||||
* to add a SetHandler option for the endpoint. Instead, simply
|
||||
* setting MellonEndpointPath should be enough.
|
||||
*
|
||||
* Therefore this hook must run before any handler that may check
|
||||
* r->handler and decide that it is the only handler for this URL.
|
||||
*/
|
||||
ap_hook_handler(am_handler, NULL, run_handler_before, APR_HOOK_FIRST);
|
||||
|
||||
#ifdef ENABLE_DIAGNOSTICS
|
||||
ap_hook_open_logs(am_diag_log_init,NULL,NULL,APR_HOOK_MIDDLE);
|
||||
ap_hook_log_transaction(am_diag_finalize_request,NULL,NULL,APR_HOOK_REALLY_LAST);
|
||||
#endif
|
||||
ap_hook_handler(am_handler, NULL, NULL, APR_HOOK_MIDDLE);
|
||||
ap_hook_fixups(am_fixup, hook_fixup_before, NULL, APR_HOOK_MIDDLE);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
@ -243,7 +207,7 @@ module AP_MODULE_DECLARE_DATA auth_mellon_module =
|
|||
auth_mellon_dir_config,
|
||||
auth_mellon_dir_merge,
|
||||
auth_mellon_server_config,
|
||||
auth_mellon_srv_merge,
|
||||
NULL,
|
||||
auth_mellon_commands,
|
||||
register_hooks
|
||||
};
|
||||
|
|
|
@ -1,226 +0,0 @@
|
|||
#!/bin/sh
|
||||
# Print a version string.
|
||||
scriptversion=2012-12-31.23; # UTC
|
||||
|
||||
# Copyright (C) 2007-2013 Free Software Foundation, Inc.
|
||||
#
|
||||
# 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 <http://www.gnu.org/licenses/>.
|
||||
|
||||
# This script is derived from GIT-VERSION-GEN from GIT: http://git.or.cz/.
|
||||
# It may be run two ways:
|
||||
# - from a git repository in which the "git describe" command below
|
||||
# produces useful output (thus requiring at least one signed tag)
|
||||
# - from a non-git-repo directory containing a .tarball-version file, which
|
||||
# presumes this script is invoked like "./git-version-gen .tarball-version".
|
||||
|
||||
# In order to use intra-version strings in your project, you will need two
|
||||
# separate generated version string files:
|
||||
#
|
||||
# .tarball-version - present only in a distribution tarball, and not in
|
||||
# a checked-out repository. Created with contents that were learned at
|
||||
# the last time autoconf was run, and used by git-version-gen. Must not
|
||||
# be present in either $(srcdir) or $(builddir) for git-version-gen to
|
||||
# give accurate answers during normal development with a checked out tree,
|
||||
# but must be present in a tarball when there is no version control system.
|
||||
# Therefore, it cannot be used in any dependencies. GNUmakefile has
|
||||
# hooks to force a reconfigure at distribution time to get the value
|
||||
# correct, without penalizing normal development with extra reconfigures.
|
||||
#
|
||||
# .version - present in a checked-out repository and in a distribution
|
||||
# tarball. Usable in dependencies, particularly for files that don't
|
||||
# want to depend on config.h but do want to track version changes.
|
||||
# Delete this file prior to any autoconf run where you want to rebuild
|
||||
# files to pick up a version string change; and leave it stale to
|
||||
# minimize rebuild time after unrelated changes to configure sources.
|
||||
#
|
||||
# As with any generated file in a VC'd directory, you should add
|
||||
# /.version to .gitignore, so that you don't accidentally commit it.
|
||||
# .tarball-version is never generated in a VC'd directory, so needn't
|
||||
# be listed there.
|
||||
#
|
||||
# Use the following line in your configure.ac, so that $(VERSION) will
|
||||
# automatically be up-to-date each time configure is run (and note that
|
||||
# since configure.ac no longer includes a version string, Makefile rules
|
||||
# should not depend on configure.ac for version updates).
|
||||
#
|
||||
# AC_INIT([GNU project],
|
||||
# m4_esyscmd([build-aux/git-version-gen .tarball-version]),
|
||||
# [bug-project@example])
|
||||
#
|
||||
# Then use the following lines in your Makefile.am, so that .version
|
||||
# will be present for dependencies, and so that .version and
|
||||
# .tarball-version will exist in distribution tarballs.
|
||||
#
|
||||
# EXTRA_DIST = $(top_srcdir)/.version
|
||||
# BUILT_SOURCES = $(top_srcdir)/.version
|
||||
# $(top_srcdir)/.version:
|
||||
# echo $(VERSION) > $@-t && mv $@-t $@
|
||||
# dist-hook:
|
||||
# echo $(VERSION) > $(distdir)/.tarball-version
|
||||
|
||||
|
||||
me=$0
|
||||
|
||||
version="git-version-gen $scriptversion
|
||||
|
||||
Copyright 2011 Free Software Foundation, Inc.
|
||||
There is NO warranty. You may redistribute this software
|
||||
under the terms of the GNU General Public License.
|
||||
For more information about these matters, see the files named COPYING."
|
||||
|
||||
usage="\
|
||||
Usage: $me [OPTION]... \$srcdir/.tarball-version [TAG-NORMALIZATION-SED-SCRIPT]
|
||||
Print a version string.
|
||||
|
||||
Options:
|
||||
|
||||
--prefix prefix of git tags (default 'v')
|
||||
--fallback fallback version to use if \"git --version\" fails
|
||||
|
||||
--help display this help and exit
|
||||
--version output version information and exit
|
||||
|
||||
Running without arguments will suffice in most cases."
|
||||
|
||||
prefix=v
|
||||
fallback=
|
||||
|
||||
while test $# -gt 0; do
|
||||
case $1 in
|
||||
--help) echo "$usage"; exit 0;;
|
||||
--version) echo "$version"; exit 0;;
|
||||
--prefix) shift; prefix="$1";;
|
||||
--fallback) shift; fallback="$1";;
|
||||
-*)
|
||||
echo "$0: Unknown option '$1'." >&2
|
||||
echo "$0: Try '--help' for more information." >&2
|
||||
exit 1;;
|
||||
*)
|
||||
if test "x$tarball_version_file" = x; then
|
||||
tarball_version_file="$1"
|
||||
elif test "x$tag_sed_script" = x; then
|
||||
tag_sed_script="$1"
|
||||
else
|
||||
echo "$0: extra non-option argument '$1'." >&2
|
||||
exit 1
|
||||
fi;;
|
||||
esac
|
||||
shift
|
||||
done
|
||||
|
||||
if test "x$tarball_version_file" = x; then
|
||||
echo "$usage"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
tag_sed_script="${tag_sed_script:-s/x/x/}"
|
||||
|
||||
nl='
|
||||
'
|
||||
|
||||
# Avoid meddling by environment variable of the same name.
|
||||
v=
|
||||
v_from_git=
|
||||
|
||||
# First see if there is a tarball-only version file.
|
||||
# then try "git describe", then default.
|
||||
if test -f $tarball_version_file
|
||||
then
|
||||
v=`cat $tarball_version_file` || v=
|
||||
case $v in
|
||||
*$nl*) v= ;; # reject multi-line output
|
||||
[0-9]*) ;;
|
||||
*) v= ;;
|
||||
esac
|
||||
test "x$v" = x \
|
||||
&& echo "$0: WARNING: $tarball_version_file is missing or damaged" 1>&2
|
||||
fi
|
||||
|
||||
if test "x$v" != x
|
||||
then
|
||||
: # use $v
|
||||
# Otherwise, if there is at least one git commit involving the working
|
||||
# directory, and "git describe" output looks sensible, use that to
|
||||
# derive a version string.
|
||||
elif test "`git log -1 --pretty=format:x . 2>&1`" = x \
|
||||
&& v=`git describe --abbrev=4 --match="$prefix*" HEAD 2>/dev/null \
|
||||
|| git describe --abbrev=4 HEAD 2>/dev/null` \
|
||||
&& v=`printf '%s\n' "$v" | sed "$tag_sed_script"` \
|
||||
&& case $v in
|
||||
$prefix[0-9]*) ;;
|
||||
*) (exit 1) ;;
|
||||
esac
|
||||
then
|
||||
# Is this a new git that lists number of commits since the last
|
||||
# tag or the previous older version that did not?
|
||||
# Newer: v6.10-77-g0f8faeb
|
||||
# Older: v6.10-g0f8faeb
|
||||
case $v in
|
||||
*-*-*) : git describe is okay three part flavor ;;
|
||||
*-*)
|
||||
: git describe is older two part flavor
|
||||
# Recreate the number of commits and rewrite such that the
|
||||
# result is the same as if we were using the newer version
|
||||
# of git describe.
|
||||
vtag=`echo "$v" | sed 's/-.*//'`
|
||||
commit_list=`git rev-list "$vtag"..HEAD 2>/dev/null` \
|
||||
|| { commit_list=failed;
|
||||
echo "$0: WARNING: git rev-list failed" 1>&2; }
|
||||
numcommits=`echo "$commit_list" | wc -l`
|
||||
v=`echo "$v" | sed "s/\(.*\)-\(.*\)/\1-$numcommits-\2/"`;
|
||||
test "$commit_list" = failed && v=UNKNOWN
|
||||
;;
|
||||
esac
|
||||
|
||||
# Change the first '-' to a '.', so version-comparing tools work properly.
|
||||
# Remove the "g" in git describe's output string, to save a byte.
|
||||
v=`echo "$v" | sed 's/-/./;s/\(.*\)-g/\1.g/'`;
|
||||
v_from_git=1
|
||||
elif test "x$fallback" = x || git --version >/dev/null 2>&1; then
|
||||
v=UNKNOWN
|
||||
else
|
||||
v=$fallback
|
||||
fi
|
||||
|
||||
v=`echo "$v" |sed "s/^$prefix//"`
|
||||
|
||||
# Test whether to append the "-dirty" suffix only if the version
|
||||
# string we're using came from git. I.e., skip the test if it's "UNKNOWN"
|
||||
# or if it came from .tarball-version.
|
||||
if test "x$v_from_git" != x; then
|
||||
# Don't declare a version "dirty" merely because a time stamp has changed.
|
||||
git update-index --refresh > /dev/null 2>&1
|
||||
|
||||
dirty=`exec 2>/dev/null;git diff-index --name-only HEAD` || dirty=
|
||||
|
||||
case "$dirty" in
|
||||
'') ;;
|
||||
*) # Append the suffix only if there isn't one already.
|
||||
case $v in
|
||||
*-dirty) ;;
|
||||
*) v="$v-dirty" ;;
|
||||
esac ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
# Omit the trailing newline, so that m4_esyscmd can use the result directly.
|
||||
echo "$v" | tr -d "$nl"
|
||||
|
||||
# Local variables:
|
||||
# eval: (add-hook 'write-file-hooks 'time-stamp)
|
||||
# time-stamp-start: "scriptversion="
|
||||
# time-stamp-format: "%:y-%02m-%02d.%02H"
|
||||
# time-stamp-time-zone: "UTC"
|
||||
# time-stamp-end: "; # UTC"
|
||||
# End:
|
Loading…
Reference in New Issue