premier commit
This commit is contained in:
commit
4cebb47113
|
@ -0,0 +1,47 @@
|
|||
= Installation =
|
||||
|
||||
The Makefile is minimal and support two targets for installation: install and
|
||||
zip.
|
||||
|
||||
== The zip target ==
|
||||
|
||||
The zip target create a standalone zipfile containing useful files for a
|
||||
mono-application usage of the spkit. In this case you will have to modify
|
||||
include/lassospkit_datadir.inc.php to return the correct path Vto the directory
|
||||
where the spkit will save its datas.
|
||||
|
||||
== The install target ==
|
||||
|
||||
It supports three parameters $(DOCPREFIX), $(DATAPREFIX) and $(DESTDIR).
|
||||
|
||||
DESTDIR will be prefixed to any install path destination, it is there to help
|
||||
packaging using a staging area before install.
|
||||
|
||||
DATAPREFIX is the directory where non-platform dependant datas are stored.
|
||||
example: /usr/share.
|
||||
|
||||
DOCPREFIX is the directory where documentation is stored
|
||||
xample: /usr/share/doc
|
||||
|
||||
= Usage =
|
||||
|
||||
== Shared ==
|
||||
|
||||
In the shared install case you just have to add
|
||||
"require_once('lassospkit/lassospkit_public_api.inc.php')" to your code and to
|
||||
map the $(DATAPREFIX)/spkitlasso/endpoints/ to somewhere inside your
|
||||
application URL space. For example via a symbolic link if your HTTP server is
|
||||
permitted to follow them or via an "Alias" if you are using apache. By default
|
||||
configuration and datas for the spkit will be saved inside
|
||||
/var/lib/spkitlasso/$(DOMAIN), so if you application appear on multiple domains
|
||||
do not forget to create appropriate symbolic or otherwise you will have
|
||||
competing configuration and data directories.
|
||||
|
||||
== Monousage ==
|
||||
|
||||
You will have to create or find a protected directory where to store
|
||||
configuration and data from the spkit. The absolute path to this directory must
|
||||
be returned by the function lasso_datadir() inside
|
||||
"include/lassospkit_datadir.inc.php". After you just have to add
|
||||
require_once('path_to_include/lassospkit_public_api.inc.php'); inside you
|
||||
application.
|
|
@ -0,0 +1,42 @@
|
|||
VERSION=0.1
|
||||
NAME=spkitlasso
|
||||
DIR:=$(shell basename `pwd`)
|
||||
FULL=$(NAME)-$(VERSION)
|
||||
ZIP=$(FULL).zip
|
||||
TGZ=$(FULL).tar.gz
|
||||
DATAPREFIX=/usr/share/
|
||||
DATADIR=$(DATAPREFIX)/$(NAME)
|
||||
PHPINCLUDEDIR=/usr/share/php/
|
||||
DOCPREFIX=/usr/share/doc/
|
||||
DOCDIR=$(DOCPREFIX)/$(NAME)
|
||||
|
||||
.PHONY: zip distclean dist install all clean
|
||||
|
||||
all:
|
||||
|
||||
|
||||
zip:
|
||||
cd .. && rm -f $(ZIP) && zip -r $(ZIP) $(DIR) -x \*Makefile -x \*.bzr\* -x .\* -x \*.swp -x \*/debian\* -x \*{TODO,Makefile}
|
||||
|
||||
dist: distclean
|
||||
mkdir $(FULL)
|
||||
cp -R debian doc exemples endpoints include README Makefile INSTALL TODO $(FULL)
|
||||
rm -f ../$(TGZ)
|
||||
tar cvzf ../$(TGZ) $(FULL)
|
||||
|
||||
|
||||
install:
|
||||
install -d $(DESTDIR)$(DATADIR) $(DESTDIR)$(DATADIR)/include $(DESTDIR)$(DATADIR)/endpoints $(DESTDIR)$(PHPINCLUDEDIR) $(DESTDIR)$(DOCDIR)/exemples
|
||||
install -d $(DESTDIR)$(DOCDIR)/html
|
||||
install -m 644 -t $(DESTDIR)$(DATADIR)/include include/*
|
||||
install -m 644 -t $(DESTDIR)$(DATADIR)/endpoints endpoints/*
|
||||
install -m 644 -t $(DESTDIR)$(DOCDIR)/exemples exemples/*
|
||||
install -d $(DESTDIR)$(DOCDIR)
|
||||
ln -sf $(DATADIR)/include $(DESTDIR)$(PHPINCLUDEDIR)/$(NAME)
|
||||
install -m 644 -t $(DESTDIR)$(DOCDIR)/html doc/*.html
|
||||
install -m 644 -t $(DESTDIR)$(DOCDIR) README INSTALL
|
||||
|
||||
distclean:
|
||||
rm -rf $(FULL)
|
||||
|
||||
clean:
|
|
@ -0,0 +1,66 @@
|
|||
Lasso SPKit PHP v0.1
|
||||
|
||||
This library contains code to ease the usage of the PHP bindings of the lasso
|
||||
library inside a service provider, usually an existing web application where
|
||||
you wish to handle some of the profile of the Liberty Alliance or SAML 2.0
|
||||
protocols.
|
||||
|
||||
The API is procedural, minimal and easy to comprehend. Depending
|
||||
upon the configuration
|
||||
|
||||
= Description of the API =
|
||||
|
||||
General idea: Initiation of SAML request is done via redirection to a local
|
||||
page and transmission of parameters to this pages are done via PHP sessions.
|
||||
The $relay parameters are the url where user should be redirected at the end of
|
||||
the SAML request whatever the result is.
|
||||
|
||||
function lassospkit_nameid()
|
||||
|
||||
* return the nameid found during the last SSO request in the current session.
|
||||
If it is non-null, it usually means that we are logged to an SAML IdP.
|
||||
|
||||
function lassospkit_set_nameid($nameid)
|
||||
* Set the nameid that the next SAML profile should use. Use it before
|
||||
presenting link for defederation or single logout. It has no effect if redirecting toward SSO.
|
||||
|
||||
function lassospkit_userid()
|
||||
* When automated storage of the federation is activated this parameter will
|
||||
contain the last userID associated with the current nameID. The association
|
||||
is done by calling setUserID then making a successul SSO request (via a
|
||||
redirection to lassospki_websso_redirect).
|
||||
When automated storage is inactivated, it always returns null and set_userid
|
||||
is ignored by the backend code.
|
||||
|
||||
function lassospkit_error()
|
||||
* When non-null gives a human readable explaination of the last unsucessful
|
||||
SAML request. Can be an error or a normal event like the user refusing to
|
||||
federate is identity in the context of an SSO request.
|
||||
|
||||
function lassospkit_federation()
|
||||
* Return an opaque blob containing informations on the federation created with an IdP
|
||||
afer a succesful request. If you intend to handle yourself storage of the federation,
|
||||
you must save this together with local user account/sessions informations and restores
|
||||
it before any future redirection to a logout/defederation request. If you user automated
|
||||
persistence you can ignore it.
|
||||
|
||||
function lassospkit_set_federation($federation)
|
||||
* Restore the opaque blob needed to initalize SAML requests. See previous function.
|
||||
|
||||
function lassospkit_websso_redirect($relay)
|
||||
* URL to the local page intiating SSO exchanges with the IdP. Use the baseUrl
|
||||
configuration option to construct this URL.
|
||||
|
||||
function lassospkit_set_userid()
|
||||
* Set the userID (can be any string) to persist together
|
||||
with the nameId when using automatized persistence of federations.
|
||||
|
||||
function lassospkit_defederation_redirect($relay)
|
||||
* Return the URL to the local page initiating defederation exchanges with the
|
||||
IdP. It appends the endpoint suffix to the baseUrl configuration option to
|
||||
build this URL.
|
||||
|
||||
function lassospkit_logout_redirect($relay)
|
||||
* Return the URL to the local page initiating logout exchanges with the
|
||||
IdP. It appends the endpoint suffix to the baseUrl configuration option to
|
||||
build this URL.
|
|
@ -0,0 +1,7 @@
|
|||
- simplify LassoSPKitUtilsSession using generic getters/setters.
|
||||
- implements id-ff 1.2 version of all functionalities.
|
||||
- support full nameidmanagement protocol.
|
||||
- move metadata support into LassoSPKitMetatada class.
|
||||
- endpoints to retrieve metadatas.
|
||||
- use LassoSPKitUtilsSession in findFederation, saveFederation et changeFederation.
|
||||
- create LassoSPKitEndpoint to share implementation between liberty and SAML 2
|
|
@ -0,0 +1,6 @@
|
|||
spkitlasso (0.1-1) unstable; urgency=low
|
||||
|
||||
* Initial release
|
||||
|
||||
-- Benjamin Dauvergne <bdauvergne@entrouvert.com> Thu, 20 Mar 2008 14:23:09 +0100
|
||||
|
|
@ -0,0 +1 @@
|
|||
5
|
|
@ -0,0 +1,15 @@
|
|||
Source: spkitlasso
|
||||
Section: unknown
|
||||
Priority: extra
|
||||
Maintainer: Benjamin Dauvergne <bdauvergne@entrouvert.com>
|
||||
Build-Depends: cdbs, debhelper (>= 5)
|
||||
Standards-Version: 3.7.2
|
||||
|
||||
Package: spkitlasso
|
||||
Architecture: any
|
||||
Depends: lasso-php
|
||||
Description: Simple library to use Lasso PHP bindings inside service providers
|
||||
This package provides PHP 5 classes and a procedural API to use Lasso basic
|
||||
protocols like SSO, Identity Federation, Identity Defederation and SLO,
|
||||
without having to handle transport and persistence of SAML 2.0 or
|
||||
ID-FF 1.2 assertions.
|
|
@ -0,0 +1,22 @@
|
|||
This package was debianized by Benjamin Dauvergne <bdauvergne@entrouvert.com> on
|
||||
Thu, 20 Mar 2008 14:23:09 +0100.
|
||||
|
||||
It was downloaded from <url://example.com>
|
||||
|
||||
Upstream Author(s):
|
||||
|
||||
Benjamin Dauvergne <bdauvergne@entrouvert.com>
|
||||
|
||||
Copyright:
|
||||
|
||||
Copyright (C) 2008 Entr'Ouvert
|
||||
|
||||
License:
|
||||
|
||||
This software is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
|
||||
|
||||
The Debian packaging is (C) 2008, Benjamin Dauvergne <bdauvergne@entrouvert.com> and
|
||||
is licensed under the GPL, see `/usr/share/common-licenses/GPL'.
|
||||
|
||||
# Please also look if there are files or directories which have a
|
||||
# different copyright/license attached and list them here.
|
|
@ -0,0 +1,4 @@
|
|||
usr/share/spkitlasso
|
||||
usr/share/doc
|
||||
usr/share/php
|
||||
usr/share/
|
|
@ -0,0 +1,3 @@
|
|||
INSTALL
|
||||
README
|
||||
TODO
|
|
@ -0,0 +1,10 @@
|
|||
#!/usr/bin/make -f
|
||||
|
||||
|
||||
include /usr/share/cdbs/1/rules/debhelper.mk
|
||||
include /usr/share/cdbs/1/class/makefile.mk
|
||||
|
||||
# Add here any variable or target overrides you need.
|
||||
DEB_MAKE_INSTALL_TARGET := install DESTDIR=$(CURDIR)/debian/tmp/
|
||||
DEB_MAKE_CHECK_TARGET :=
|
||||
DEB_DH_INSTALL_ARGS:=--autodest
|
|
@ -0,0 +1,13 @@
|
|||
Document: spkitlasso
|
||||
Title: Debian spkitlasso Manual
|
||||
Author: Benjamin Dauvergne <bdauvergne@entrouvert.com>
|
||||
Abstract: This manual describes what spkitlasso is
|
||||
and how it can be used to
|
||||
manage online manuals on Debian systems.
|
||||
Section: unknown
|
||||
|
||||
Format: HTML
|
||||
Index: /usr/share/doc/spkitlasso/html/index.html
|
||||
Files: /usr/share/doc/spkitlasso/html/*.html
|
||||
|
||||
|
|
@ -0,0 +1 @@
|
|||
debian/tmp/usr/*
|
|
@ -0,0 +1,5 @@
|
|||
# Automatically added by dh_installdocs
|
||||
if [ "$1" = configure ] && which install-docs >/dev/null 2>&1; then
|
||||
install-docs -i /usr/share/doc-base/spkitlasso
|
||||
fi
|
||||
# End automatically added section
|
|
@ -0,0 +1,6 @@
|
|||
# Automatically added by dh_installdocs
|
||||
if [ "$1" = remove ] || [ "$1" = upgrade ] && \
|
||||
which install-docs >/dev/null 2>&1; then
|
||||
install-docs -r spkitlasso
|
||||
fi
|
||||
# End automatically added section
|
|
@ -0,0 +1,5 @@
|
|||
<html>
|
||||
<body>
|
||||
To do!
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,53 @@
|
|||
<?php
|
||||
require_once('../include/lassospkit_configgen.inc.php');
|
||||
require_once('../include/lassospkit_config.inc.php');
|
||||
require_once('../include/lassospkit_debug.inc.php');
|
||||
require_once('../include/lassospkit_metadata.inc.php');
|
||||
require_once('../include/lassospkit_utils.inc.php');
|
||||
|
||||
$configgen = new LassoSPKitConfigUIGen();
|
||||
$error = null;
|
||||
|
||||
if (isset($_POST)) {
|
||||
if (isset($_POST['clean'])) {
|
||||
unlink(SP_METADATA);
|
||||
unlink(PRIVATE_KEY);
|
||||
unlink(IDP_METADATA);
|
||||
}
|
||||
if (isset($_POST['organization'])
|
||||
&& (isset($_POST['idp_metadata'])
|
||||
|| isset($_POST['idp_metadata_url'])))
|
||||
{
|
||||
$ret = $configgen->makeConfig(
|
||||
$_POST['organization'],
|
||||
$_POST['idp_metadata'],
|
||||
$_POST['idp_metadata_url'],
|
||||
isset($_POST['clear_pkey']),
|
||||
$error);
|
||||
|
||||
if ($ret) {
|
||||
try {
|
||||
$configgen->importConfigFromPost($_POST);
|
||||
} catch (Exception $e) {
|
||||
lassospkit_showCode($e);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
print "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
|
||||
?>
|
||||
<html>
|
||||
<head>
|
||||
<link type="text/css" rel="stylesheet" href="style.css">
|
||||
</head>
|
||||
<body>
|
||||
<?
|
||||
if ($error) {
|
||||
?><span class="error"> <em>Error:</em> <? echo $error?></span><?
|
||||
}
|
||||
$configgen->render_form();
|
||||
|
||||
?>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,63 @@
|
|||
<?php
|
||||
require_once("../include/lassospkit_helper.inc.php");
|
||||
require_once("../include/lassospkit_dispatcher.inc.php");
|
||||
require_once("../include/lassospkit_metadata.inc.php");
|
||||
require_once("../include/lassospkit_utils.inc.php");
|
||||
|
||||
session_start()
|
||||
dispatch(array('/login' => login,
|
||||
'/federate' => federate,
|
||||
'/ssoAssertionConsumer' => ssoAssertionConsumer,
|
||||
'/sloInit' => sloInit,
|
||||
'/sloSoap' => sloSoap,
|
||||
'/sloRedirect' => sloRedirect,
|
||||
'/sloResponse' => sloResponse,
|
||||
'/defederate' => defederate,
|
||||
'/defederateReturn' => defederateReturn,
|
||||
'/defederateNotification' => defederateNotification,
|
||||
'/metadata' => metadata));
|
||||
// TODO fill implementation
|
||||
function login() {
|
||||
$saml2 = new LassoSPKitLiberty(new LassoSPKitDummySession());
|
||||
$params = LassoSPKitUtilsSession::getParams('login');
|
||||
$federate = TRUE;
|
||||
if (isset($params['federate'])) {
|
||||
$federate = $params['federate'];
|
||||
}
|
||||
$saml2->sso(TRUE, $federate);
|
||||
}
|
||||
function federate() {
|
||||
$saml2 = new LassoSPKitLiberty(new LassoSPKitDummySession());
|
||||
$saml2->sso(TRUE, TRUE);
|
||||
}
|
||||
function ssoAssertionConsumer() {
|
||||
}
|
||||
function sloInit() {
|
||||
}
|
||||
function sloSoap() {
|
||||
}
|
||||
function sloRedirect() {
|
||||
}
|
||||
function sloResponse() {
|
||||
}
|
||||
function defederate() {
|
||||
}
|
||||
function defederateReturn() {
|
||||
}
|
||||
function defederateNotification() {
|
||||
}
|
||||
function metadata() {
|
||||
header('Content-type: text/xml');
|
||||
$datadir = LassoSPKitHelper::getMetadataDir(LASSO_PROTOCOL_LIBERTY_1_2);
|
||||
$pkey = $datadir . "/" . PRIVATE_KEY;
|
||||
LassoSPKitUtils::extractPublicKey($pkey, $publickey, $error);
|
||||
try {
|
||||
$content = LassoSPKitMetadataLiberty::generateMetadata(dirname(LassoSPKitUtils::mydir()), LassoSPKitConfig::get('organization'), $publickey);
|
||||
if ($content) {
|
||||
header('Content-type: text/xml');
|
||||
echo $content;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
<?php
|
||||
require_once("../include/lassospkit_helper.inc.php");
|
||||
require_once("../include/lassospkit_dispatcher.inc.php");
|
||||
require_once("../include/lassospkit_saml2.inc.php");
|
||||
require_once("../include/lassospkit_metadata.inc.php");
|
||||
require_once("../include/lassospkit_utils.inc.php");
|
||||
require_once("../include/lassospkit_utils_session.inc.php");
|
||||
require_once("../include/lassospkit_dummysession.inc.php");
|
||||
require_once("../include/lassospkit_autopersistentsession.inc.php");
|
||||
|
||||
session_start();
|
||||
|
||||
function verifyReferer() {
|
||||
if (isset($_SERVER['HTTP_REFERER'])) {
|
||||
$host = $_SERVER['HTTP_REFERER'];
|
||||
$host = strstr('//', $host);
|
||||
$pos = strpos($host, '/');
|
||||
if ($pos !== FALSE) {
|
||||
$host = substr($host, 0, $pos);
|
||||
}
|
||||
|
||||
if ($host && isset($_SERVER['HTTP_HOST']) && $host != $_SERVER['HTTP_HOST']) {
|
||||
echo "Bad referer '$host' != '" . $_SERVER['HTTP_HOST'] . "'";
|
||||
exit(1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
dispatch(array('/login' => 'login',
|
||||
'/federate' => 'federate',
|
||||
'/ssoAssertionConsumer' => 'ssoAssertionConsumer',
|
||||
'/slo' => 'slo',
|
||||
'/sloSoap' => 'sloSoap',
|
||||
'/sloRedirect' => 'sloRedirect',
|
||||
'/sloResponse' => 'sloResponse',
|
||||
'/defederate' => 'defederate',
|
||||
'/nidManagementInit' => 'nidManagementInit',
|
||||
'/nidManagementSoap' => 'nidManagementSoap',
|
||||
'/nidManagementRedirect' => 'nidManagementRedirect',
|
||||
'/nidManagementResponse' => 'nidManagementResponse',
|
||||
'/metadata' => 'metadata'));
|
||||
} catch (Exception $e) {
|
||||
lassospkit_showCode($e);
|
||||
lassospkit_showCode(var_export($_SESSION,1));
|
||||
}
|
||||
// TODO fill implementation
|
||||
function finishRequest($method, $profileStr, $session, $ret) {
|
||||
if ($method == LASSO_HTTP_METHOD_SOAP) {
|
||||
if (! $ret) {
|
||||
$session->doRedirect(LassoSPKitUtilsSession::getRelayState($profileStr));
|
||||
} else {
|
||||
$session->doRedirect(LassoSPKitUtilsSession::getRelayState('error'));
|
||||
}
|
||||
} else {
|
||||
if (! $ret) {
|
||||
$session->doRedirect(LassoSPKitUtilsSession::getRelayState('error'));
|
||||
}
|
||||
}
|
||||
}
|
||||
function finishResponse($profileSTR, $session, $ret) {
|
||||
if (! $ret) {
|
||||
$session->doRedirect(LassoSPKitUtilsSession::getRelayState($profileSTR));
|
||||
} else {
|
||||
$session->doRedirect(LassoSPKitUtilsSession::getRelayState('error'));
|
||||
}
|
||||
}
|
||||
function getSession() {
|
||||
$session_class = "LassoSPKit" . LassoSPKitConfig::get('session');
|
||||
return new $session_class();
|
||||
}
|
||||
function detectMethodAssertionConsumer() {
|
||||
}
|
||||
function login() {
|
||||
verifyReferer();
|
||||
$saml2 = new LassoSPKitSAML2(new LassoSPKitDummySession());
|
||||
$params = LassoSPKitUtilsSession::getParams('login');
|
||||
$federate = TRUE;
|
||||
if (isset($params['federate'])) {
|
||||
$federate = $params['federate'];
|
||||
}
|
||||
$saml2->sso(FALSE, $federate);
|
||||
LassoSPKitUtilsSession::setRelayState('sso',LassoSPKitUtilsSession::getRelayState('login'));
|
||||
}
|
||||
function federate() {
|
||||
verifyReferer();
|
||||
$saml2 = new LassoSPKitSAML2(new LassoSPKitDummySession());
|
||||
$saml2->sso(TRUE, TRUE);
|
||||
LassoSPKitUtilsSession::setRelayState('sso',LassoSPKitUtilsSession::getRelayState('federate'));
|
||||
}
|
||||
function ssoAssertionConsumer() {
|
||||
$session = getSession();
|
||||
$saml2 = new LassoSPKitSAML2($session);
|
||||
if (isset($_GET)) {
|
||||
$ok = $saml2->ssoConsumer(LASSO_HTTP_METHOD_ARTIFACT_GET, $_SERVER['QUERY_STRING']);
|
||||
} elseif (isset($_POST)) {
|
||||
$ok = $saml2->ssoConsumer(LASSO_HTTP_METHOD_ARTIFACT_POST, $_SERVER['QUERY_STRING']);
|
||||
}
|
||||
if ($ok) {
|
||||
$session->doRedirect(LassoSPKitUtilsSession::getRelayState('sso'));
|
||||
} else {
|
||||
$session->doRedirect(LassoSPKitUtilsSession::getRelayState('error'));
|
||||
}
|
||||
}
|
||||
function slo() {
|
||||
$session = getSession();
|
||||
$saml2 = new LassoSPKitSAML2($session);
|
||||
$method = LASSO_HTTP_METHOD_REDIRECT;
|
||||
$ret = $saml2->initiateSLO($method);
|
||||
$headers = headers_list();
|
||||
finishRequest($method, 'slo', $session, $ret);
|
||||
}
|
||||
function sloSoap() {
|
||||
$session = getSession();
|
||||
$saml2 = new LassoSPKitSAML2($session);
|
||||
if ($saml2->processSOAPRequestSLO() == 0) {
|
||||
lassospkit_debuglog("SLO SOAP Request handler: fatal error");
|
||||
}
|
||||
}
|
||||
function sloRedirect() {
|
||||
}
|
||||
function sloResponse() {
|
||||
$session = getSession();
|
||||
$saml2 = new LassoSPKitSAML2($session);
|
||||
$ret = $saml2->processRedirectResponseSLO();
|
||||
finishResponse('slo', $session, $ret);
|
||||
}
|
||||
function defederate() {
|
||||
$session = getSession();
|
||||
$saml2 = new LassoSPKitSAML2($session);
|
||||
$method = LASSO_HTTP_METHOD_REDIRECT;
|
||||
$ret = $saml2->initiateFTNotification($method);
|
||||
finishRequest($method, 'defederation', $session, $ret);
|
||||
LassoSPKitUtilsSession::setRelayState('nidmanagement',LassoSPKitUtilsSession::getRelayState('defederation'));
|
||||
|
||||
}
|
||||
function nidManagementInit() {
|
||||
}
|
||||
function nidManagementSoap() {
|
||||
}
|
||||
function nidManagementRedirect() {
|
||||
}
|
||||
// NidManagement Redirect Response
|
||||
function nidManagementResponse() {
|
||||
$session = getSession();
|
||||
$saml2 = new LassoSPKitSAML2($session);
|
||||
$method = LASSO_HTTP_METHOD_REDIRECT;
|
||||
$ret = $saml2->processRedirectResponseNameIdManagement();
|
||||
finishResponse('defederation', $session, $ret);
|
||||
}
|
||||
function metadata() {
|
||||
$datadir = LassoSPKitHelper::getMetadataDir(LASSO_PROTOCOL_SAML_2_0);
|
||||
$pkey = $datadir . "/" . PRIVATE_KEY;
|
||||
LassoSPKitUtils::extractPublicKey($pkey, $publickey, $error);
|
||||
try {
|
||||
$content = LassoSPKitMetadataSAML2::generateMetadata(dirname(LassoSPKitUtils::mydir()), LassoSPKitConfig::get('organization'), $publickey);
|
||||
if ($content) {
|
||||
header('Content-type: text/xml');
|
||||
echo $content;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
throw $e;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
.error { width: auto; color: red; border: 1px solid red; padding: 2px; }
|
||||
pre,.code { background: #BBB; border: 1px solid black; padding: 1ex;white-space: pre; overflow: scroll }
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
session_start();
|
||||
|
||||
echo '<?xml version="1.0" encoding="UTF-8"?>';
|
||||
require_once('spkitlasso/include/lassospkit_public_api.inc.php');
|
||||
require_once('spkitlasso/include/lassospkit_debug.inc.php');
|
||||
require_once('spkitlasso/include/lassospkit_utils.inc.php');
|
||||
|
||||
function show($a) {
|
||||
echo "<li><a href='$a'>";
|
||||
echo $a;
|
||||
echo "</a></li>";
|
||||
}
|
||||
?>
|
||||
|
||||
<html>
|
||||
<head>
|
||||
<link type="text/css" rel="stylesheet" href="endpoints/style.css">
|
||||
</head>
|
||||
<h1>Points d'accés</h1>
|
||||
<ul>
|
||||
<?
|
||||
$myself = LassoSPKitUtils::myself();
|
||||
show(lassospkit_login_redirect($myself));
|
||||
show(lassospkit_federate_redirect($myself));
|
||||
show(lassospkit_logout_redirect($myself));
|
||||
show(lassospkit_defederation_redirect($myself));
|
||||
show('endpoints/configure');
|
||||
|
||||
$nameid = lassospkit_nameid();
|
||||
$userid = lassospkit_userid();
|
||||
$error = lassospkit_error();
|
||||
$federation = lassospkit_federation();
|
||||
if ($federation) {
|
||||
lassospkit_set_federation($federation);
|
||||
}
|
||||
?>
|
||||
<li>NameId: <? echo lassospkit_showCode(var_export($nameid,1)) ?></li>
|
||||
<li>UserId: <? echo lassospkit_showCode($userid) ?></li>
|
||||
<li>Error: <? echo lassospkit_showCode($error) ?></li>
|
||||
<li>Federation: <? echo lassospkit_showCode($federation) ?></li>
|
||||
</ul>
|
||||
|
||||
</html>
|
|
@ -0,0 +1,48 @@
|
|||
<?php
|
||||
require_once('lassospkit_generic_session.inc.php');
|
||||
require_once('lassospkit_utils_session.inc.php');
|
||||
require_once('lassospkit_debug.inc.php');
|
||||
require_once('lassospkit_file.inc.php');
|
||||
require_once('lassospkit_config.inc.php');
|
||||
require_once('lassospkit_generic_session.inc.php');
|
||||
|
||||
class LassoSPKitAutoPersistentSession extends LassoSPKitGenericSession {
|
||||
private $storage;
|
||||
function __construct() {
|
||||
$storage_class = "LassoSPKit" . LassoSPKitConfig::get('storage') . "Store";
|
||||
$this->storage = @new $storage_class();
|
||||
if ($this->storage == null) {
|
||||
throw new Exception("Config error: storage class $storage_class does not exist");
|
||||
}
|
||||
}
|
||||
function findFederation($nameID) {
|
||||
if (! $nameID) {
|
||||
return 0;
|
||||
}
|
||||
$blob = $this->storage->get($nameID);
|
||||
if ($blob == null) {
|
||||
return 0;
|
||||
}
|
||||
return $this->explodeFederationBlob($blob);
|
||||
}
|
||||
function saveFederation() {
|
||||
$nameIDs = $this->getNameIDs();
|
||||
$firstID = array_pop($nameIDs);
|
||||
if ($firstID == null) {
|
||||
throw new Exception("save federation has no nameIDs to create keys");
|
||||
}
|
||||
$blob = $this->getFederationBlob();
|
||||
$this->storage->set($firstID, $blob);
|
||||
foreach ($nameIDs as $otherID) {
|
||||
$this->storage->alias($firstID, $otherID);
|
||||
}
|
||||
parent::saveFederation();
|
||||
}
|
||||
function changeFederation($oldID, $newID) {
|
||||
if ($newID) {
|
||||
$this->storage->rename($oldID, $newID);
|
||||
} else {
|
||||
$this->storage->delete($oldID);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
<?
|
||||
require_once('lassospkit_datadir.inc.php');
|
||||
|
||||
/** This class represents the non-SAML-metadata part
|
||||
* of the config of the spkit. */
|
||||
class LassoSPKitConfig {
|
||||
static $default_values = array(
|
||||
'federate' => 'file', /* Does the backend persist federation ? no, file or mysql. */
|
||||
'mysql_host'=> 'localhost', /* Configuration of the MySql connection if federate = mysql */
|
||||
'mysql_user' => '',
|
||||
'mysql_password' => '',
|
||||
'mysql_database' => '',
|
||||
'mysql_table' => '_lassospkit_userid2nameid',
|
||||
'lasso_lib' => 'lasso.php', /* Where is lasso PHP binding ? */
|
||||
'debug' => '0', /* Activate extra debugging */
|
||||
'organization' => "", /* Nom de l'organisation */
|
||||
'conformance' => "",
|
||||
'idp_metadata_url' => "",
|
||||
'baseUrl' => "",
|
||||
'session' => "DummySession",
|
||||
'storage' => "File"
|
||||
);
|
||||
private static $instance = null;
|
||||
private static $file;
|
||||
|
||||
function __construct() {
|
||||
}
|
||||
static function init() {
|
||||
self::$file = lassospkit_datadir() . '/lassospkit_config.ini';
|
||||
if (! self::$instance) {
|
||||
self::$instance = array();
|
||||
$ph = @dba_open(self::$file, 'rl', 'inifile');
|
||||
if ($ph) {
|
||||
try {
|
||||
foreach (self::$default_values as $k => $v) {
|
||||
if (dba_exists($k, $ph)) {
|
||||
self::$instance[$k] = dba_fetch($k, $ph);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
dba_close($ph);
|
||||
throw $e;
|
||||
}
|
||||
dba_close($ph);
|
||||
}
|
||||
}
|
||||
}
|
||||
static function commit() {
|
||||
$ph = dba_open(self::$file, 'nl', 'inifile');
|
||||
if (! $ph) {
|
||||
throw Exception('Cannot open the config file for writing');
|
||||
}
|
||||
try {
|
||||
foreach (self::$instance as $k => $v) {
|
||||
if (isset(self::$default_values[$k])) {
|
||||
dba_replace($k, $v, $ph);
|
||||
}
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
dba_close($ph);
|
||||
throw $e;
|
||||
}
|
||||
dba_close($ph);
|
||||
}
|
||||
function setDefault($name) {
|
||||
self::init();
|
||||
unset(self::$instance[$name]);
|
||||
}
|
||||
static function get($name) {
|
||||
self::init();
|
||||
if (! isset(self::$default_values[$name])) {
|
||||
throw new Exception('Try to read an unknown config field');
|
||||
}
|
||||
if (isset(self::$instance[$name])) {
|
||||
return self::$instance[$name];
|
||||
}
|
||||
return self::$default_values[$name];
|
||||
}
|
||||
static function set($name, $value) {
|
||||
self::init();
|
||||
if (! isset(self::$default_values[$name])) {
|
||||
throw new Exception('Try to write an unknown config field');
|
||||
}
|
||||
self::$instance[$name] = $value;
|
||||
}
|
||||
public function keys() {
|
||||
return array_keys(self::$default_values);
|
||||
}
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,267 @@
|
|||
<?php
|
||||
require_once('lassospkit_datadir.inc.php');
|
||||
require_once('lassospkit_helper.inc.php');
|
||||
|
||||
/** This class generate the WebUI for configuring the SP kit. */
|
||||
class LassoSPKitConfigUIGen
|
||||
{
|
||||
private $special_input;
|
||||
private $default_input;
|
||||
private $base;
|
||||
|
||||
function __construct() {
|
||||
$this->special_input = array(
|
||||
'organization' =>
|
||||
array('Nom du service',
|
||||
'text'),
|
||||
'baseUrl' =>
|
||||
array('Base des URLS des points d\'accés', 'text'),
|
||||
'gruik' =>
|
||||
array('URL des métadatas SAML 2.0 du SP',
|
||||
'url',
|
||||
LassoSPKitUtils::relativePathToURL("saml2/metadata")),
|
||||
'gruik2' =>
|
||||
array('URL des métadatas Liberty 1.2 du SP',
|
||||
'url',
|
||||
LassoSPKitUtils::relativePathToURL("liberty/metadata")),
|
||||
'idp_metadata_url' =>
|
||||
array('URL des métadatas du service d\'authentification',
|
||||
'text'),
|
||||
'idp_metadata' =>
|
||||
array('Métadatas de l\'IdP',
|
||||
'textarea'),
|
||||
'clear_pkey' =>
|
||||
array('Génère une clé privée, même si une existe déjà',
|
||||
'checkbox'),
|
||||
'federate' =>
|
||||
array('Stockage de la fédération',
|
||||
'select',
|
||||
array('no' => 'Non',
|
||||
'MySql' => 'Via MySql',
|
||||
'File' => 'Via le filesystem')),
|
||||
'mysql_host' => array('Host de la base MySql'),
|
||||
'mysql_user' => array('Identifiant sur la base'),
|
||||
'mysql_password' => array('Mot de passe sur la base', 'password'),
|
||||
'mysql_database' => array('Nom de la base'),
|
||||
'mysql_table' => array('Nom de la table'),
|
||||
'lasso_lib' => array('Emplacement de la bibliothèque Lasso PHP'));
|
||||
}
|
||||
function itype($name) {
|
||||
if (isset($this->special_input[$name][1])) {
|
||||
return $this->special_input[$name][1];
|
||||
}
|
||||
return 'text';
|
||||
}
|
||||
function icaption($name) {
|
||||
if (isset($this->special_input[$name][0])) {
|
||||
return $this->special_input[$name][0];
|
||||
}
|
||||
return $name;
|
||||
}
|
||||
function value($name) {
|
||||
switch ($name) {
|
||||
case 'idp_metadata':
|
||||
return @file_get_contents(LassoSPKitHelper::getIdpMetadataFile());
|
||||
case 'baseUrl':
|
||||
return LassoSPKitUtils::mydir();
|
||||
}
|
||||
if (isset(LassoSPKitConfig::$default_values[$name])) {
|
||||
return LassoSPKitConfig::get($name);
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function msg($mess) {
|
||||
echo htmlspecialchars(gettext($mess));
|
||||
}
|
||||
function render_form() {
|
||||
echo '<head>', "\n";
|
||||
echo '<title>';
|
||||
$this->msg('Configuration du SP-Kit LassoSPKit');
|
||||
echo '</title>', "\n";
|
||||
echo '<body>', "\n";
|
||||
echo '<h1>', "\n";
|
||||
$this->msg('Configuration du SP-kit LassoSPKit');
|
||||
echo '</h1>', "\n";
|
||||
echo '<form action="' . htmlspecialchars(LassoSPKitUtils::myself()) . '" method="post">', "\n";
|
||||
echo ' <table>', "\n";
|
||||
foreach ($this->special_input as $k => $v) {
|
||||
echo '<tr><td>';
|
||||
$this->msg($this->icaption($k));
|
||||
echo '</td><td>';
|
||||
$actual = $this->value($k);
|
||||
$type = $this->itype($k);
|
||||
switch ($type) {
|
||||
case 'textarea':
|
||||
echo '<textarea name="' . $k . '" cols="80" row="20">';
|
||||
$this->msg($actual);
|
||||
echo '</textarea>';
|
||||
break;
|
||||
case 'select':
|
||||
echo '<select name="' . $k . '" size="1">';
|
||||
foreach ($v[2] as $x => $y) {
|
||||
|
||||
echo '<option value="' . $x . '"';
|
||||
if ($actual == $x) {
|
||||
echo ' selected ';
|
||||
}
|
||||
echo '>';
|
||||
$this->msg($y);
|
||||
echo '</option>';
|
||||
}
|
||||
echo '</select>';
|
||||
break;
|
||||
case 'text':
|
||||
echo '<input name="' . $k . '"';
|
||||
echo 'type="text" size="80" value="' . $actual . '"/>';
|
||||
break;
|
||||
case 'url':
|
||||
echo '<a href="';
|
||||
$this->msg($v[2]);
|
||||
echo '">';
|
||||
$this->msg($v[2]);
|
||||
echo '</a>';
|
||||
break;
|
||||
default:
|
||||
echo '<input name="' . $k . '"';
|
||||
echo 'type="' . $type . '" ';
|
||||
if ($actual) {
|
||||
echo 'value="' . $actual . '" ';
|
||||
}
|
||||
echo '/>';
|
||||
break;
|
||||
}
|
||||
echo '</td></tr>', "\n";
|
||||
}
|
||||
echo '<tr><td/><td><input type="submit" value="Modifier"/></td></tr>', "\n";
|
||||
echo '</table>', "\n";
|
||||
echo '</body>', "\n";
|
||||
}
|
||||
function importConfigFromPost($post) {
|
||||
foreach (LassoSPKitConfig::keys() as $k) {
|
||||
if (isset($post[$k]))
|
||||
{
|
||||
LassoSPKitConfig::set($k, $post[$k]);
|
||||
}
|
||||
}
|
||||
LassoSPKitConfig::commit();
|
||||
}
|
||||
|
||||
function validateMetadata($file) {
|
||||
return LassoSPKitHelper::getConformance($file);
|
||||
}
|
||||
function getIdpMeta($idpMeta, $idpMetaUrl, &$conformance, &$error) {
|
||||
if (! $idpMeta && ! $idpMetaUrl) {
|
||||
throw new Exception("illegal argument");
|
||||
}
|
||||
$file = tempnam(TEMPDIR, "idp-metadata-temp");
|
||||
$ok = 0;
|
||||
if ($idpMetaUrl) {
|
||||
$idpMeta = @file_get_contents($idpMetaUrl);
|
||||
$ok = ($idpMeta != null);
|
||||
if ($ok) {
|
||||
$ok = @file_put_contents($file, $idpMeta);
|
||||
if ($ok) {
|
||||
$conformance = $this->validateMetadata($file);
|
||||
$ok = ($conformance != -1);
|
||||
if (! $ok) {
|
||||
$error = "GetIDPMeta: Retrieved metadatas non conformant";
|
||||
}
|
||||
} else {
|
||||
$error = "GetIDPMeta: Cannot store retrieved IdP metadatas";
|
||||
}
|
||||
} else {
|
||||
$error = "GetIDPMeta: Cannot retrieve metadatas from the given URL: $idpMetaUrl";
|
||||
}
|
||||
}
|
||||
if (! $ok && $idpMeta) {
|
||||
$ok = @file_put_contents($file, $idpMeta);
|
||||
if ($ok) {
|
||||
$conformance = $this->validateMetadata($file);
|
||||
$ok = ($conformance != -1);
|
||||
if (! $ok) {
|
||||
$error = "GetIDPMeta: Metadatas non conformant";
|
||||
}
|
||||
} else {
|
||||
$error = "GetIDPMeta: Cannot store given IdP metadatas";
|
||||
}
|
||||
}
|
||||
if ($ok) {
|
||||
return $file;
|
||||
} else {
|
||||
@unlink($file);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
}
|
||||
function generateSPMetadata($conformance, $organization, $publickey, &$error) {
|
||||
$spmeta = LassoSPKitHelper::getMetadataDir($conformance) . "/" . SP_METADATA;
|
||||
$base = LassoSPKitConfig::get('baseUrl');
|
||||
switch ($conformance) {
|
||||
case LASSO_PROTOCOL_SAML_2_0:
|
||||
$meta = LassoSPKitMetadataSAML2::generateMetadata($base, $organization, $publickey);
|
||||
LassoSPKitConfig::set('conformance', 'saml2');
|
||||
break;
|
||||
case LASSO_PROTOCOL_LIBERTY_1_0:
|
||||
case LASSO_PROTOCOL_LIBERTY_1_1:
|
||||
case LASSO_PROTOCOL_LIBERTY_1_2:
|
||||
$meta = LassoSPKitMetadataLiberty::generateMetadata($base, $organization, $publickey);
|
||||
LassoSPKitConfig::set('conformance', 'liberty');
|
||||
break;
|
||||
default:
|
||||
throw new Exception("illegal argument");
|
||||
}
|
||||
$ok = file_put_contents($spmeta, $meta);
|
||||
if (! $ok) {
|
||||
$error = "GenerateSPMetadata: Cannot save generated sp metadatas in $spmeta ";
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
function makeConfig($organization, $idpMeta, $idpMetaUrl, $removePrivateKey, &$error) {
|
||||
$base = lassospkit_datadir();
|
||||
// Get idp metadatas
|
||||
$file = $this->getIdpMeta($idpMeta, $idpMetaUrl, $conformance, $error);
|
||||
if (! $file) {
|
||||
return 0;
|
||||
}
|
||||
$metabase = LassoSPKitHelper::getMetadataDir($conformance);
|
||||
if (! is_dir($metabase)) {
|
||||
if (! @mkdir($metabase)) {
|
||||
$error = "MakeConfig: Cannot create directory $metabase";
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (! LassoSPKitUtils::checkCanWrite($metabase, $error)) {
|
||||
return 0;
|
||||
}
|
||||
if (! LassoSPKitUtils::checkCanWrite($base, $error)) {
|
||||
return 0;
|
||||
}
|
||||
$idpmeta = LassoSPKitHelper::getIdpMetadataFile();
|
||||
if (! ($contents = @file_get_contents($file)) || ! @file_put_contents($idpmeta, $contents)) {
|
||||
$error = "MakeConfig: Cannot move idp temporary files to final place";
|
||||
return 0;
|
||||
}
|
||||
@unlink($file);
|
||||
// Create local metadatas
|
||||
$pkey = $metabase . "/" . PRIVATE_KEY;
|
||||
if (! is_file($pkey) || $removePrivateKey) {
|
||||
@unlink($pkey);
|
||||
if (! LassoSPKitUtils::generatePrivateKey($pkey, $error)) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
$publickey = null; // Will contain the publickey
|
||||
if (! LassoSPKitUtils::extractPublicKey($pkey, $publickey, $error)) {
|
||||
return 0;
|
||||
}
|
||||
if (! $this->generateSPMetadata($conformance,
|
||||
LassoSPKitConfig::get('organization'),
|
||||
$publickey,
|
||||
$error)) {
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,11 @@
|
|||
<?php
|
||||
/** Function for getting the place of the config file, the federation files when autofederation is activated.
|
||||
* Change this function to change way of find kit position. When using lassospkit
|
||||
* in an unique directory with you application, you can just make it return "../data".
|
||||
*/
|
||||
function lassospkit_datadir() {
|
||||
// return '/var/lib/lassospkit/' . $_SERVER['HTTP_HOST'];
|
||||
return "/home/bdauvergne/public_html/data";
|
||||
// return $_SERVER['DOCUMENT_ROOT'] . '/data';
|
||||
|
||||
}
|
|
@ -0,0 +1,57 @@
|
|||
<?php
|
||||
require_once('lassospkit_config.inc.php');
|
||||
libxml_use_internal_errors(true);
|
||||
error_reporting(E_ALL);
|
||||
|
||||
function lassospkit_debuglog($msg, $level = 0) {
|
||||
$lassospkit_debug_level = LassoSPKitConfig::get('debug');
|
||||
if ($level <= $lassospkit_debug_level) {
|
||||
openlog("LassoPHP.SP.Kit", LOG_PID, LOG_AUTHPRIV);
|
||||
syslog(LOG_DEBUG, $msg);
|
||||
closelog();
|
||||
}
|
||||
}
|
||||
|
||||
function lassospkit_showCode($code) {
|
||||
echo '<pre class="code">';
|
||||
echo htmlspecialchars($code);
|
||||
echo '</pre>';
|
||||
}
|
||||
|
||||
// function lassospkit_errorhandler($errno, $errstr, $errfile, $errline)
|
||||
//{
|
||||
// if (error_reporting()==0) {
|
||||
// return false;
|
||||
// }
|
||||
// switch ($errno) {
|
||||
// case E_USER_ERROR:
|
||||
// bigdebug("Mon ERREUR [$errno] $errstr\n".
|
||||
// "\n" . var_export(debug_backtrace(),1) .
|
||||
// " Erreur fatale sur la ligne $errline dans le fichier $errfile".
|
||||
// ", PHP " . PHP_VERSION . " (" . PHP_OS . ")\n".
|
||||
// "Arrêt...");
|
||||
// exit(1);
|
||||
// break;
|
||||
//
|
||||
// case E_USER_WARNING:
|
||||
// bigdebug("Mon ALERTE [$errno] $errstr"
|
||||
// . "\n" . var_export(debug_backtrace(),1)
|
||||
// . " Erreur fatale sur la ligne $errline dans le fichier $errfile");
|
||||
// break;
|
||||
//
|
||||
// case E_USER_NOTICE:
|
||||
// bigdebug("Mon AVERTISSEMENT [$errno] $errstr"
|
||||
// . "\n" . var_export(debug_backtrace(),1)
|
||||
// . " Erreur fatale sur la ligne $errline dans le fichier $errfile");
|
||||
// break;
|
||||
//
|
||||
// default:
|
||||
// bigdebug("Type d'erreur inconnu : [$errno] $errstr"
|
||||
// . "\n" . var_export(debug_backtrace(),1)
|
||||
// . " Erreur fatale sur la ligne $errline dans le fichier $errfile");
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// /* Ne pas exécuter le gestionnaire interne de PHP */
|
||||
// return true;
|
||||
//}
|
|
@ -0,0 +1,9 @@
|
|||
<?
|
||||
/** Magic constants... */
|
||||
define("SP_METADATA", "sp_metadata.xml");
|
||||
define("IDP_METADATA","idp_metadata.xml");
|
||||
define("PRIVATE_KEY", "private.key");
|
||||
define("OPENSSL_BIN", "/usr/bin/openssl");
|
||||
define("TEMPDIR","/tmp");
|
||||
define("_CHECK_FILENAME", ".654564XDSFSTEST");
|
||||
?>
|
|
@ -0,0 +1,13 @@
|
|||
<?
|
||||
function dispatch ($urls) {
|
||||
$path_info = $_SERVER['PATH_INFO'];
|
||||
$fname = $urls[$path_info];
|
||||
if ($fname) {
|
||||
$fname();
|
||||
exit(0);
|
||||
} else {
|
||||
header("HTTP/1.0 404 Not Found");
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,29 @@
|
|||
<?php
|
||||
require_once('lassospkit_generic_session.inc.php');
|
||||
require_once('lassospkit_utils_session.inc.php');
|
||||
require_once('lassospkit_debug.inc.php');
|
||||
|
||||
class LassoSPKitDummySession extends LassoSPKitGenericSession {
|
||||
/** Save the federation into the SESSION object */
|
||||
function saveFederation() {
|
||||
LassoSPKitUtilsSession::setFederation(
|
||||
serialize($this->getFederationBlob()));
|
||||
parent::saveFederation();
|
||||
}
|
||||
/** Use the nameID as a hint to validate the stored dumps.
|
||||
It not present use them directly. */
|
||||
function findFederation($nameID) {
|
||||
$federation = LassoSPKitUtilsSession::getFederation();
|
||||
$ret = explodeFederationBlob($federation);
|
||||
if ($ret == 1 && $nameID) {
|
||||
$nameIDs = $this->getNameIDs();
|
||||
if (! @in_array($nameID, $nameIDs)) {
|
||||
$this->setSessionDump(null);
|
||||
$this->setIdentityDump(null);
|
||||
LassoSPKitUtilsSession::setUserId(null);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,56 @@
|
|||
<?
|
||||
require_once('lassospkit_storage.inc.php');
|
||||
require_once('lassospkit_datadir.inc.php');
|
||||
|
||||
/** Hard links needs to be supported on the filesystem. */
|
||||
class LassoSPKitFileStore implements LassoSPKitStore {
|
||||
public $base = '';
|
||||
function __construct() {
|
||||
$this->base = lassospkit_datadir();
|
||||
}
|
||||
private function filepath($key) {
|
||||
return $this->base . '/' . $this->filename($key);
|
||||
}
|
||||
private function filename($key) {
|
||||
return 'lib_session_' . $key;
|
||||
}
|
||||
function get($key) {
|
||||
$content = @file_get_contents($this->filepath($key));
|
||||
if ($content === FALSE) {
|
||||
return null;
|
||||
}
|
||||
return @unserialize($content);
|
||||
}
|
||||
function set($key, $value) {
|
||||
if ($key && $key != "") {
|
||||
$ret = @file_put_contents($this->filepath($key), @serialize($value));
|
||||
$this->debug($ret, "cannot set contents of file " . $this->filepath($key));
|
||||
} else {
|
||||
throw new Exception("Bad usage of FileStore::set, key is null");
|
||||
}
|
||||
}
|
||||
function delete($key) {
|
||||
@unlink($this->filepath($key));
|
||||
}
|
||||
function alias($key,$alias) {
|
||||
$target = $this->filename($key);
|
||||
$sym = $this->filepath($alias);
|
||||
@unlink($sym);
|
||||
$ret = @link($target,$sym);
|
||||
$this->debug($ret, "could not alias key $key => $alias");
|
||||
return $ret;
|
||||
}
|
||||
function rename($old,$new) {
|
||||
$old_path = $this->filename($old);
|
||||
$new_path = $this->filename($new);
|
||||
$ret = @rename($old_path, $new_path);
|
||||
$this->debug($ret, "could not rename key $old => $new");
|
||||
return $ret;
|
||||
}
|
||||
function debug($ret, $mesg) {
|
||||
if ($ret === FALSE) {
|
||||
lassospkit_debuglog("SPKit File Storage: " . $mesg);
|
||||
}
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,71 @@
|
|||
<?php
|
||||
|
||||
/** This class implements dummy methods for
|
||||
generic handling of SSO session i.e storage
|
||||
of federation data (identity_dump and
|
||||
session_dump), retrieval of attributes,
|
||||
etc.. */
|
||||
class LassoSPKitGenericSession {
|
||||
public $exception;
|
||||
private $session_dump;
|
||||
private $identity_dump;
|
||||
|
||||
function processAttributes(array $attributes) {
|
||||
}
|
||||
function doRedirect($url) {
|
||||
header("Location: $url");
|
||||
}
|
||||
function doResponse($mimeType, $content) {
|
||||
header("Content-type: $mimeType");
|
||||
echo $content;
|
||||
}
|
||||
function logout() {
|
||||
}
|
||||
/** Save session_dump and identity_dump,
|
||||
use any mean to link them to a local session.
|
||||
The default implementation just report the list of nameIDs
|
||||
in the nameIDs session variable.
|
||||
*/
|
||||
function saveFederation() {
|
||||
$identity_dump = $this->getIdentityDump();
|
||||
$nameIDs = LassoSPKitHelper::getNameIDsFromDump($identity_dump);
|
||||
LassoSPKitUtilsSession::setNameID($nameIDs);
|
||||
}
|
||||
function findFederation($nameID) {
|
||||
}
|
||||
function changeFederation($nameID, $NewID) {
|
||||
}
|
||||
function setSessionDump($dump) {
|
||||
$this->session_dump = $dump;
|
||||
}
|
||||
function setIdentityDump($dump) {
|
||||
$this->identity_dump = $dump;
|
||||
}
|
||||
function getSessionDump() {
|
||||
return $this->session_dump;
|
||||
}
|
||||
function getIdentityDump() {
|
||||
return $this->identity_dump;
|
||||
}
|
||||
function getNameIDs() {
|
||||
$identity_dump = $this->getIdentityDump();
|
||||
return LassoSPKitHelper::getNameIDsFromDump($identity_dump);
|
||||
}
|
||||
function getFederationBlob() {
|
||||
$userid = LassoSPKitUtilsSession::getUserID();
|
||||
return array(
|
||||
'identity'=> $this->getIdentityDump(),
|
||||
'session' => $this->getSessionDump(),
|
||||
'userid'=>$userid);
|
||||
}
|
||||
function explodeFederationBlob($blob) {
|
||||
$federation = @unserialize($blob);
|
||||
if ($federation === FALSE) {
|
||||
$this->debug(FALSE, "Could not unserialize content of key file for key $nameID");
|
||||
return 0;
|
||||
}
|
||||
$this->setSessionDump($federation['session']);
|
||||
$this->setIdentityDump($federation['identity']);
|
||||
LassoSPKitUtilsSession::setUserID($federation['userid']);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,204 @@
|
|||
<?
|
||||
require_once('lassospkit_datadir.inc.php');
|
||||
require_once('lassospkit_config.inc.php');
|
||||
require_once('lassospkit_lib.inc.php');
|
||||
require_once('lassospkit_debug.inc.php');
|
||||
|
||||
|
||||
class LassoSPKitHelper {
|
||||
/** If session_dump and identity_dump are present in the
|
||||
session object, use then to initialize the profile */
|
||||
static function restoreDumps(LassoProfile $profile,
|
||||
LassoSPKitGenericSession $session) {
|
||||
$sessionDump = $session->getSessionDump();
|
||||
$identityDump = $session->getIdentityDump();
|
||||
|
||||
if ($sessionDump) {
|
||||
$profile->setSessionFromDump($sessionDump);
|
||||
}
|
||||
if ($identityDump) {
|
||||
$profile->setIdentityFromDump($identityDump);
|
||||
}
|
||||
}
|
||||
/** If identity or session is dirty save them in the session
|
||||
object using setIdentyDump and setSessionDump.
|
||||
|
||||
Returns the dirtiness statute ('or' of the two dirty flag).
|
||||
*/
|
||||
static function saveDumps(LassoProfile $profile,
|
||||
LassoSPKitGenericSession $session) {
|
||||
$ok = 0;
|
||||
if ($profile->hasDirtyIdentity()) {
|
||||
if ($profile->identity) {
|
||||
$session->setIdentityDump($profile->identity->dump());
|
||||
} else {
|
||||
$session->setIdentityDump(null);
|
||||
}
|
||||
$ok = 1;
|
||||
}
|
||||
if ($profile->hasDirtySession()) {
|
||||
if ($profile->session) {
|
||||
$session->setSessionDump($profile->session->dump());
|
||||
} else {
|
||||
$session->setSessionDump(null);
|
||||
}
|
||||
$ok = 1;
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
/** Extract attributes values and keys from an assertion,
|
||||
and copy them into array $arr. */
|
||||
static function assertionExtractAttributes(LassoAssertion $assertion, &$attributes) {
|
||||
foreach ($assertion->attributeStatement[0]->attribute
|
||||
as $attribute) {
|
||||
if ($attribute->name == LASSO_SAML2_ATTRIBUTE_NAME_EPR) {
|
||||
continue;
|
||||
}
|
||||
$arr = array();
|
||||
foreach ($attribute->attributeValue as $value) {
|
||||
array_push($arr, $value->any[0]->content);
|
||||
}
|
||||
$attributes[$attribute->name] = $arr;
|
||||
}
|
||||
}
|
||||
/** Return the NameID found in profile->nameIdentifier. If throw is TRUE
|
||||
* and we cannot find a nameIdentifier then throws IDENTIFIER_NOT_FOUND. */
|
||||
static function profileGetNameID(LassoProfile $profile) {
|
||||
$nameIdentifier = $profile->nameIdentifier;
|
||||
if (! $nameIdentifier || ! $content = $nameIdentifier->content) {
|
||||
return null;
|
||||
}
|
||||
return $content;
|
||||
}
|
||||
/** This should handle removing of federation, identity == null, ask
|
||||
for federation termination on the session. */
|
||||
static function saveFederation(LassoProfile $profile,
|
||||
LassoSPKitGenericSession $session) {
|
||||
$nameID = self::profileGetNameID($profile);
|
||||
if (self::saveDumps($profile,$session)) {
|
||||
$session->saveFederation($nameID);
|
||||
}
|
||||
}
|
||||
/** Contract is that if NewID is null, session should forget about
|
||||
the current federation, if it is not then the link between local id
|
||||
and nameID should be changed to point to NewID. */
|
||||
static function changeFederation(LassoProfile $profile,
|
||||
LassoSPKitGenericSession $session,
|
||||
$NewID) {
|
||||
$nameID = self::profileGetNameID($profile);
|
||||
$session->changeFederation($nameID, $NewID);
|
||||
}
|
||||
/** Try to restore the federation informations from the profile.
|
||||
* The contract with the session object is that after findFederation
|
||||
* if it returned TRUE, then $session->identity_dump et
|
||||
* $session->session_dump contains valid dumps.
|
||||
*/
|
||||
static function findFederation(LassoProfile $profile,
|
||||
LassoSPKitGenericSession $session) {
|
||||
$nameID = self::profileGetNameID($profile);
|
||||
if ($session->findFederation($nameID) == 0) {
|
||||
if ($nameID) {
|
||||
throw new LassoProfileFederationNotFoundError();
|
||||
} else {
|
||||
throw new LassoProfileNameIdentifierNotFoundError($profile->dump());
|
||||
}
|
||||
}
|
||||
self::restoreDumps($profile,$session);
|
||||
return 1;
|
||||
}
|
||||
static function postToHost($host, $path, $data_to_send, $ssl = false) {
|
||||
if ($ssl) {
|
||||
$fp = fsockopen('tls://' . $host, 443);
|
||||
} else {
|
||||
$fp = fsockopen($host, 80);
|
||||
}
|
||||
fputs($fp, "POST $path HTTP/1.1\n");
|
||||
fputs($fp, "Host: $host\n");
|
||||
fputs($fp, "Content-type: text/xml\n");
|
||||
fputs($fp, "Content-length: ".strlen($data_to_send)."\n");
|
||||
fputs($fp, "Connection: close\n\n");
|
||||
fputs($fp, "$data_to_send\n");
|
||||
$res = '';
|
||||
while(!feof($fp)) {
|
||||
$res .= fgets($fp, 128);
|
||||
}
|
||||
fclose($fp);
|
||||
|
||||
$res = substr(strstr($res, "\r\n\r\n"), 4);
|
||||
|
||||
return $res;
|
||||
}
|
||||
static public function soapCall($url, $msg) {
|
||||
if (strstr($url, 'http://') != $url)
|
||||
return "";
|
||||
$short_url = substr($url, 7);
|
||||
$url_tokens = explode("/", $short_url);
|
||||
$host = $url_tokens[0];
|
||||
unset($url_tokens[0]);
|
||||
$query = implode("/", $url_tokens);
|
||||
$query = "/" . $query;
|
||||
|
||||
$response = self::postToHost($host, $query, $msg);
|
||||
|
||||
return $response;
|
||||
|
||||
|
||||
}
|
||||
/** Make a SOAP call using parameters found in profile. */
|
||||
static public function SoapCallWithProfile(LassoProfile $profile) {
|
||||
return self::soapCall($profile->msgUrl, $profile->msgBody);
|
||||
}
|
||||
static public function notImplemented() {
|
||||
LassoError::throw_on_rc(LASSO_PROFILE_ERROR_UNSUPPORTED_PROFILE);
|
||||
}
|
||||
/** Return the directory where metadatas are stored */
|
||||
static public function getMetadataDir($conformance) {
|
||||
$base = lassospkit_datadir();
|
||||
switch ($conformance) {
|
||||
case LASSO_PROTOCOL_SAML_2_0:
|
||||
$base .= "/saml2";
|
||||
break;
|
||||
case LASSO_PROTOCOL_LIBERTY_1_0:
|
||||
case LASSO_PROTOCOL_LIBERTY_1_1:
|
||||
case LASSO_PROTOCOL_LIBERTY_1_2:
|
||||
$base .= "/liberty";
|
||||
break;
|
||||
default:
|
||||
throw new Exception("illegal argument");
|
||||
}
|
||||
return $base;
|
||||
}
|
||||
static function getConformance($file) {
|
||||
try {
|
||||
$server = new LassoProvider(LASSO_PROVIDER_ROLE_IDP
|
||||
, $file, null, null);
|
||||
if ($server) {
|
||||
return $server->protocolConformance;
|
||||
} else {
|
||||
return -1;
|
||||
}
|
||||
} catch (Exception $e) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
static function getIdpMetadataFile() {
|
||||
return lassospkit_datadir() . "/" . IDP_METADATA;
|
||||
|
||||
}
|
||||
static function getNameIDsFromDump($dump) {
|
||||
$identity = LassoIdentity::newFromDump($dump);
|
||||
if (! $identity) {
|
||||
return array();
|
||||
}
|
||||
$nameIDs = self::getNameIDs($identity);
|
||||
return $nameIDs;
|
||||
}
|
||||
static function getNameIDs(LassoIdentity $identity) {
|
||||
$nameIDs = array();
|
||||
foreach ($identity->federations as $rid => $federation) {
|
||||
$nameIDs[$rid] = $federation->remoteNameIdentifier->content;
|
||||
}
|
||||
return $nameIDs;
|
||||
}
|
||||
}
|
||||
?>
|
|
@ -0,0 +1,5 @@
|
|||
<?php
|
||||
require_once('lassospkit_config.inc.php');
|
||||
$lasso_lib = LassoSPKitConfig::get('lasso_lib');
|
||||
require_once($lasso_lib);
|
||||
lasso_init();
|
|
@ -0,0 +1,17 @@
|
|||
<?
|
||||
require_once('lassospkit_config.inc.php');
|
||||
require_once('lassospkit_debug.inc.php');
|
||||
require_once('lassospkit_saml_common.inc.php');
|
||||
require_once('lassospkit_lib.inc.php');
|
||||
|
||||
class LassoSPKitLiberty extends LassoSPKitSAMLCommon {
|
||||
public function __construct(LassoSPKitGenericSession $session) {
|
||||
parent::__construct($session);
|
||||
$this->initServer(lassospkit_datadir() . "/liberty");
|
||||
}
|
||||
/** Overloaded method to serve as callback to common SSO method. */
|
||||
protected ssoNameIdPolicyConfig(LassoLogin $login, $blob) {
|
||||
$request = $login->request;
|
||||
$request->NameIDPolicy = $blob;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,76 @@
|
|||
<?php
|
||||
|
||||
class LassoSPKitMetadataSAML2 {
|
||||
static function generateMetadata($baseUrl, $orgname, $publickey) {
|
||||
$meta = '<?xml version="1.0"?>
|
||||
<EntityDescriptor xmlns="urn:oasis:names:tc:SAML:2.0:metadata"
|
||||
xmlns:saml="urn:oasis:names:tc:SAML:2.0:assertion"
|
||||
xmlns:ds="http://www.w3.org/2000/09/xmldsig#"
|
||||
entityID="' . $baseUrl . '/saml2/metadata">
|
||||
<SPSSODescriptor
|
||||
AuthnRequestsSigned="true"
|
||||
protocolSupportEnumeration="urn:oasis:names:tc:SAML:2.0:protocol">
|
||||
<KeyDescriptor use="signing">
|
||||
<ds:KeyInfo xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
<ds:KeyValue>' . $publickey . '</ds:KeyValue>
|
||||
</ds:KeyInfo>
|
||||
</KeyDescriptor>
|
||||
|
||||
<AssertionConsumerService isDefault="true" index="0"
|
||||
Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact"
|
||||
Location="' . $baseUrl . '/saml2/ssoAssertionConsumer" />
|
||||
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="' . $baseUrl . '/saml2/sloSoap"/>
|
||||
<SingleLogoutService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="' . $baseUrl . '/saml2/sloRedirect" ResponseLocation="' . $baseUrl . '/saml2/sloResponse"/>
|
||||
|
||||
<ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:SOAP" Location="' . $baseUrl . '/saml2/nidManagementSoap"/>
|
||||
<ManageNameIDService Binding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" Location="'. $baseUrl .'/saml2/nidManagementRedirect" ResponseLocation="'. $baseUrl .'/saml2/nidManagementResponse"/>
|
||||
|
||||
</SPSSODescriptor>
|
||||
<Organization>
|
||||
<OrganizationName xml:lang="en">' . $orgname . '</OrganizationName>
|
||||
</Organization>
|
||||
</EntityDescriptor>';
|
||||
return $meta;
|
||||
}
|
||||
}
|
||||
|
||||
class LassoSPKitMetadataLiberty {
|
||||
static function generateMetadata($baseUrl, $orgname, $publickey) {
|
||||
$meta = "";
|
||||
$meta .=
|
||||
'<?xml version="1.0"?>
|
||||
<EntityDescriptor
|
||||
providerID="' . $baseUrl . '/liberty/metadata" xmlns="urn:liberty:metadata:2003-08" xmlns:ds="http://www.w3.org/2000/09/xmldsig#">
|
||||
<SPDescriptor>';
|
||||
// Public key
|
||||
$meta .=
|
||||
'<KeyDescriptor use="signing">
|
||||
<ds:KeyInfo>
|
||||
<ds:KeyValue>' . htmlspecialchars($publickey) . '</ds:KeyValue>
|
||||
</ds:KeyInfo>
|
||||
</KeyDescriptor>';
|
||||
// Endpoints
|
||||
$meta .=
|
||||
'<SOAPEndpoint>' . $baseUrl .'/liberty/soap</SOAPEndpoint>
|
||||
<SingleLogoutServiceURL>' . $baseUrl . '/liberty/sloRedirect</SingleLogoutServiceURL>
|
||||
<SingleLogoutServiceReturnURL>'. $baseUrl .'/liberty/sloResponse</SingleLogoutServiceReturnURL>
|
||||
<FederationTerminationServiceURL>'. $baseUrl.'/liberty/defederateNotification</FederationTerminationServiceURL>
|
||||
<FederationTerminationServiceReturnURL>'. $baseUrl.'/liberty/defederateReturn</FederationTerminationServiceReturnURL>
|
||||
<AssertionConsumerServiceURL>' . $baseUrl . '/liberty/ssoAssertionConsumer</AssertionConsumerServiceURL>
|
||||
';
|
||||
// TODO select supported profiles by config
|
||||
$meta .= "<SingleLogoutProtocolProfile>http://projectliberty.org/profiles/slo-sp-http</SingleLogoutProtocolProfile>\n";
|
||||
$meta .= "<SingleLogoutProtocolProfile>http://projectliberty.org/profiles/slo-sp-soap</SingleLogoutProtocolProfile>\n";
|
||||
$meta .= "<SingleLogoutProtocolProfile>http://projectliberty.org/profiles/slo-idp-http</SingleLogoutProtocolProfile>\n";
|
||||
$meta .= "<SingleLogoutProtocolProfile>http://projectliberty.org/profiles/slo-idp-soap</SingleLogoutProtocolProfile>\n";
|
||||
$meta .= "<FederationTerminationNotificationProtocolProfile>http://projectliberty.org/profiles/fedterm-sp-http</FederationTerminationNotificationProtocolProfile>\n";
|
||||
$meta .= "<FederationTerminationNotificationProtocolProfile>http://projectliberty.org/profiles/fedterm-sp-soap</FederationTerminationNotificationProtocolProfile>\n";
|
||||
$meta .= "<FederationTerminationNotificationProtocolProfile>http://projectliberty.org/profiles/fedterm-idp-http</FederationTerminationNotificationProtocolProfile>\n";
|
||||
$meta .= "<FederationTerminationNotificationProtocolProfile>http://projectliberty.org/profiles/fedterm-idp-soap</FederationTerminationNotificationProtocolProfile>\n";
|
||||
$meta .= "<AuthnRequestsSigned>true</AuthnRequestsSigned>
|
||||
</SPDescriptor>
|
||||
</EntityDescriptor>";
|
||||
|
||||
return $meta;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,44 @@
|
|||
<?php
|
||||
require_once('lassospkit_storage.inc.php');
|
||||
|
||||
class LassoSPKitMySqlStore implements LassoSPKitStore {
|
||||
private $db;
|
||||
private $table;
|
||||
|
||||
function __construct() {
|
||||
$host = LassoSPKitConfig::get('mysql_host');
|
||||
$user = LassoSPKitConfig::get('mysql_user');
|
||||
$password = LassoSPKitConfig::get('mysql_password');
|
||||
$database = LassoSPKitConfig::get('mysql_database');
|
||||
$this->table = $table = LassoSPKitConfig::get('mysql_table');
|
||||
$this->db = mysql_connect($host, $user, $password);
|
||||
mysql_select_db($database);
|
||||
mysql_query('CREATE TABLE IF NOT EXISTS ' . $table . '(nameid varchar(50), record varchar(2000), PRIMARY KEY (nameid))', $this->db);
|
||||
}
|
||||
function get($key) {
|
||||
$result = mysql_query('SELECT record FROM ' . $this->table, $this->db);
|
||||
if ($result) {
|
||||
return @unserialize(mysql_result($result, 0));
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
function __destruct() {
|
||||
mysql_close($this->db);
|
||||
}
|
||||
function set($key,$value) {
|
||||
$sql = sprintf("REPLACE %s VALUES ('%s','%s')",
|
||||
$this->table,
|
||||
mysql_real_escape_string($key),
|
||||
mysql_real_escape_string(serialize($record)));
|
||||
$result = mysql_query($sql, $this->db);
|
||||
}
|
||||
function delete($key) {
|
||||
$sql = sprintf("DELETE FROM %s WHERE nameid = '%s'",
|
||||
$this->table,
|
||||
mysql_real_escape_string($key));
|
||||
mysql_query($sql, $this->db);
|
||||
}
|
||||
function alias($key,$alias) {
|
||||
}
|
||||
}
|
|
@ -0,0 +1,90 @@
|
|||
<?php
|
||||
require_once('lassospkit_utils_session.inc.php');
|
||||
require_once('lassospkit_config.inc.php');
|
||||
|
||||
/** This file contains the public front-end API
|
||||
to the LassoSPKit for PHP.
|
||||
|
||||
The idea is to limit interaction at the minimum.
|
||||
If lassospkit_nameid() is null the you are not logged
|
||||
to an IdP.
|
||||
To obtain the nameID associated with login to an IdP,
|
||||
just redirect the user's browser using
|
||||
lassospkit_websso_redirect($allowCreate). The allowCreate
|
||||
defines if you want a new federation created or only accept
|
||||
previously defined federation (the case if you wan to retrieve
|
||||
a previously established federation).
|
||||
*/
|
||||
|
||||
/** If this session contains the result of a recent WebSSO return
|
||||
the retrieved nameID. */
|
||||
function lassospkit_nameid() {
|
||||
return LassoSPKitUtilsSession::getNameID();
|
||||
}
|
||||
|
||||
function lassospkit_set_nameid($nameid) {
|
||||
LassoSPKitUtilsSession::setNameID($nameid);
|
||||
}
|
||||
|
||||
/** Returns the userid associated to the current, if any. */
|
||||
function lassospkit_userid() {
|
||||
return LassoSPKitUtilsSession::getUserID();
|
||||
}
|
||||
|
||||
/** If last interaction resulted in an error,
|
||||
* return a human readable description. */
|
||||
function lassospkit_error() {
|
||||
return LassoSPKitUtilsSession::getLastError();
|
||||
}
|
||||
|
||||
/** Return an opaque string representing
|
||||
federation informations as result of the last
|
||||
liberty exchange.
|
||||
*/
|
||||
function lassospkit_federation() {
|
||||
return LassoSPKitUtilsSession::getFederation();
|
||||
}
|
||||
|
||||
/** Set the opaque string representing
|
||||
federation informations as result of the last
|
||||
liberty exchange.
|
||||
*/
|
||||
function lassospkit_set_federation($federation) {
|
||||
LassoSPKitUtilsSession::setFederation($federation);
|
||||
}
|
||||
|
||||
/* Return the URL where to redirect a user when liberty authentification
|
||||
* is required for existing federation or to get a transient one.
|
||||
*/
|
||||
function lassospkit_login_redirect($relay, $federate = TRUE) {
|
||||
LassoSPKitUtilsSession::setRelayState('login',$relay);
|
||||
LassoSPKitUtilsSession::setParams('login',array('federate'=>$federate));
|
||||
return LassoSPKitConfig::get('baseUrl') . "/" . LassoSPKitConfig::get('conformance') . '/login';
|
||||
}
|
||||
|
||||
/* Return the URL where to redirect a user to create a new federation, or
|
||||
* get an existing one.
|
||||
* Eventually pass a username to auto-store the new federation.
|
||||
*/
|
||||
function lassospkit_federate_redirect($relay) {
|
||||
LassoSPKitUtilsSession::setRelayState('federate',$relay);
|
||||
return LassoSPKitConfig::get('baseUrl') . "/" . LassoSPKitConfig::get('conformance') . '/federate';
|
||||
}
|
||||
|
||||
/** Sets the userid to associate to this nameID, during
|
||||
the next WebSSO interaction.
|
||||
Only useful if you activated autofederation. */
|
||||
function lassospkit_set_userid() {
|
||||
LassoSPKitUtilsSession::setUserID($nameid);
|
||||
}
|
||||
|
||||
/* Return the URL where to redirect a user to initiated defederation of the current nameid. */
|
||||
function lassospkit_defederation_redirect($relay) {
|
||||
LassoSPKitUtilsSession::setRelayState('defederation',$relay);
|
||||
return LassoSPKitConfig::get('baseUrl') . "/" . LassoSPKitConfig::get('conformance') . '/defederate';
|
||||
}
|
||||
function lassospkit_logout_redirect($relay) {
|
||||
LassoSPKitUtilsSession::setRelayState('slo',$relay);
|
||||
return LassoSPKitConfig::get('baseUrl') . "/" . LassoSPKitConfig::get('conformance') . '/slo';
|
||||
}
|
||||
LassoSPKitUtilsSession::setRelayState('error', '../..');
|
|
@ -0,0 +1,158 @@
|
|||
<?php
|
||||
require_once('lassospkit_datadir.inc.php');
|
||||
require_once('lassospkit_config.inc.php');
|
||||
require_once('lassospkit_debug.inc.php');
|
||||
require_once('lassospkit_saml_common.inc.php');
|
||||
require_once('lassospkit_lib.inc.php');
|
||||
|
||||
class LassoSPKitSaml2 extends LassoSPKitSAMLCommon {
|
||||
public function __construct(LassoSPKitGenericSession $session) {
|
||||
parent::__construct($session);
|
||||
if (!$this->initServer(lassospkit_datadir() . "/saml2")) {
|
||||
throw new Exception("Construction de l'objet SAML2 impossible");
|
||||
}
|
||||
}
|
||||
/** Overloaded method to serve as callback to common SSO method. */
|
||||
protected function ssoNameIdPolicyConfig(LassoLogin $login, $blob) {
|
||||
$request = $login->request;
|
||||
$nameidpolicy = $request->NameIDPolicy;
|
||||
$nameidpolicy->format = $blob['nameIDFormat'];
|
||||
$nameidpolicy->allowCreate = $blob['allowCreate'];
|
||||
}
|
||||
public function sso($create = TRUE, $federate = TRUE) {
|
||||
if ($federate) {
|
||||
$format = LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT;
|
||||
} else {
|
||||
$format = LASSO_SAML2_NAME_IDENTIFIER_FORMAT_TRANSIENT;
|
||||
}
|
||||
return $this->ssoInit($create,$format);
|
||||
}
|
||||
public function ssoInit(
|
||||
$allowCreate = TRUE,
|
||||
$nameIDFormat = LASSO_SAML2_NAME_IDENTIFIER_FORMAT_PERSISTENT,
|
||||
$remoteID = null,
|
||||
$method = LASSO_HTTP_METHOD_REDIRECT,
|
||||
$isConsentObtained = FALSE,
|
||||
$forceAuthn = FALSE,
|
||||
$isPassive = FALSE)
|
||||
{
|
||||
$login = null;
|
||||
return parent::ssoCommon($login, $remoteID, $method, $isConsentObtained, $forceAuthn, $isPassive, array('nameIDFormat'=>$nameIDFormat, 'allowCreate' => $allowCreate));
|
||||
}
|
||||
/** Defederation, convert to NameIdManagement protocol **/
|
||||
public function initiateFTNotification($method = LASSO_HTTP_METHOD_SOAP,$remoteID = null)
|
||||
{
|
||||
$ok = $this->initiateNameIdManagement(null, $method, $remoteID);
|
||||
parent::initiateFTNotification($method,$remoteID);
|
||||
return $ok;
|
||||
}
|
||||
/** Name Id Management, SP inititated */
|
||||
/* Request */
|
||||
public function initiateNameIdManagement($newNameID, $method = LASSO_HTTP_METHOD_SOAP, $remoteID = null) {
|
||||
$ret = 0;
|
||||
lassospkit_debuglog("initiateNIDManagement NNID: $newNameID Meth: $method RID: $remoteID ");
|
||||
$ok = 1 && $nidmanagement = new LassoNameIdManagement($this->server);
|
||||
$this->findFederation($nidmanagement);
|
||||
$ok = $ok && ! $ret = $nidmanagement->initRequest($remoteID, $newNameID, $method);
|
||||
$ok = $ok && ! $ret = $nidmanagement->buildRequestMsg();
|
||||
switch ($method) {
|
||||
case LASSO_HTTP_METHOD_REDIRECT:
|
||||
$this->keepProfile($nidmanagement);
|
||||
$this->finishRedirectRequest($nidmanagement, $ret, $ok);
|
||||
break;
|
||||
case LASSO_HTTP_METHOD_SOAP:
|
||||
$this->finishSOAPRequest($nidmanagement, $ret, $ok, $response);
|
||||
$ok = $ok && $this->processResponseNameIdManagement($response, $nidmanagement);
|
||||
break;
|
||||
case LASSO_HTTP_METHOD_ARTIFACT_GET:
|
||||
case LASSO_HTTP_METHOD_ARTIFACT_POST:
|
||||
case LASSO_HTTP_METHOD_POST:
|
||||
default:
|
||||
LassoSPKitHelper::notImplemented();
|
||||
}
|
||||
if (! $ok) {
|
||||
lassospkit_debuglog("NID failed Ret: $ret Exp: " . $this->exception);
|
||||
$this->status = gettext('La défédération a échoué');
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
function processRedirectResponseNameIdManagement() {
|
||||
$ret = 0;
|
||||
$nidmanagement = null;
|
||||
$ok = $this->processResponseNameIdManagement($_SERVER['QUERY_STRING'], $nidmanagement);
|
||||
return $ok;
|
||||
}
|
||||
/** Response **/
|
||||
public function processResponseNameIdManagement($message, &$nidmanagement)
|
||||
{
|
||||
$ret = 0;
|
||||
$ok = 1;
|
||||
lassospkit_debuglog("NameIdManagement SP initiated Response");
|
||||
if ($nidmanagement == null) {
|
||||
$ok = $ok && $nidmanagement = LassoNameIdManagement::newFromDump($this->server, $this->restoreProfile());
|
||||
if ($ok) {
|
||||
$this->findFederation($nidmanagement);
|
||||
}
|
||||
}
|
||||
$ok = $ok && ! $ret = $nidmanagement->processResponseMsg($message);
|
||||
if ($ok || $ret > 0) {
|
||||
$this->saveFederation($nidmanagement);
|
||||
}
|
||||
if ($ret != 0) {
|
||||
$this->setRet($ret);
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
/** Name Id Management request IdP iniated */
|
||||
public function processRedirectRequestNameIdManagement() {
|
||||
return processRequestNameIdManagement(LASSO_HTTP_METHOD_REDIRECT,
|
||||
$_SERVER['QUERY_STRING']);
|
||||
}
|
||||
public function processSOAPRequestSLO() {
|
||||
$contents = $this->receiveSoapMessage();
|
||||
return processRequestSLO(LASSO_HTTP_METHOD_SOAP,
|
||||
$contents);
|
||||
}
|
||||
private function processRequestNameIdManagement($method, $message)
|
||||
{
|
||||
lassospkit_debuglog("NameIdManagement request handling");
|
||||
$ret = 0;
|
||||
$ok = 1;
|
||||
$ok = $ok && $nidmanagement = new LassoNameIdManagement($this->server);
|
||||
$ok = $ok && ! $ret = $nidmanagement->processRequestMsg($message);
|
||||
$this->findFederation($nidmanagement);
|
||||
$ok = $ok && ! $ret = $nidmanagement->validateRequest();
|
||||
if ($ok) {
|
||||
LassoSPKitHelper::changeFederation($nidmanagement, $this->session, $nidmanagement->request->NewID);
|
||||
}
|
||||
$this->finishResponse($method, $nidmanagement, $ret, $ok);
|
||||
if (! $ok) {
|
||||
$this->status = gettext('La requête de défédération a échoué');
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
function keepProfile(LassoProfile $profile) {
|
||||
$fed = @unserialize(LassoSPKitUtilsSession::getFederation());
|
||||
if ($fed == null) {
|
||||
$fed = array();
|
||||
}
|
||||
$fed['profile'] = $profile->dump();
|
||||
LassoSPKitUtilsSession::setFederation(serialize($fed));
|
||||
}
|
||||
function restoreProfile() {
|
||||
$fed = LassoSPKitUtilsSession::getFederation();
|
||||
if ($fed == null)
|
||||
return null;
|
||||
$fed = @unserialize($fed);
|
||||
if ($fed == null)
|
||||
return null;
|
||||
if (isset($fed['profile'])) {
|
||||
$profile = @$fed['profile'];
|
||||
unset($fed['profile']);
|
||||
} else {
|
||||
return null;
|
||||
}
|
||||
LassoSPKitUtilsSession::setFederation(serialize($fed));
|
||||
return $profile;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,354 @@
|
|||
<?
|
||||
require_once('lassospkit_config.inc.php');
|
||||
require_once('lassospkit_debug.inc.php');
|
||||
require_once('lassospkit_lib.inc.php');
|
||||
require_once('lassospkit_generic_session.inc.php');
|
||||
/**
|
||||
* TODO: initServer();
|
||||
*/
|
||||
class LassoSPKitSAMLCommon {
|
||||
protected $session;
|
||||
protected $server;
|
||||
|
||||
/** Error handling */
|
||||
protected $reset_status = 0;
|
||||
protected $human_status = "";
|
||||
protected $ret = 0;
|
||||
public $ret_str = "";
|
||||
protected $exception = null;
|
||||
|
||||
public function __construct(LassoSPKitGenericSession $session) {
|
||||
$this->session = $session;
|
||||
}
|
||||
/* Accessors */
|
||||
/* Status is a human readable and translatable string. */
|
||||
protected function setStatus($str) {
|
||||
$this->human_status = gettext($str);
|
||||
}
|
||||
protected function getStatus() {
|
||||
return $this->human_status;
|
||||
}
|
||||
/* Ret is the return code from the last error returning
|
||||
lasso function. */
|
||||
protected function setRet($ret, $prefix = "") {
|
||||
$this->ret = $ret;
|
||||
if ($ret != 0) {
|
||||
$this->ret_str = strError($ret);
|
||||
LassoSPKitUtilsSession::setLastError($prefix . $this->ret_str);
|
||||
} else {
|
||||
$this->ret_str = "";
|
||||
}
|
||||
}
|
||||
protected function getRet() {
|
||||
return $this->ret . ":" . $this->ret_str;
|
||||
}
|
||||
/** Create the server object by retrieving the configuration from
|
||||
the data object. */
|
||||
function initServer($base) {
|
||||
if ($this->server) {
|
||||
return 1;
|
||||
}
|
||||
$spmeta = $base . "/" . SP_METADATA;
|
||||
$idpmeta = $base . "/../" . IDP_METADATA;
|
||||
$pkey = $base . "/" . PRIVATE_KEY;
|
||||
$ok = $this->checkFile($spmeta);
|
||||
$ok = $ok && $this->checkFile($idpmeta);
|
||||
$ok = $ok && $this->checkFile($pkey);
|
||||
$ok = $ok
|
||||
&& $server = new LassoServer($spmeta, $pkey, NULL, NULL);
|
||||
$ok = $ok
|
||||
&& ! $ret = $server->addProvider(LASSO_PROVIDER_ROLE_IDP
|
||||
,$idpmeta,null, null);
|
||||
if (! $ok) {
|
||||
lassospkit_debuglog("Erreur création serveur: Ret=$ret Msg=" . strError($ret));
|
||||
return 0;
|
||||
} else {
|
||||
$this->server = $server;
|
||||
return $server;
|
||||
}
|
||||
}
|
||||
protected static function checkFile($file) {
|
||||
if (! file_exists($file)) {
|
||||
lassospkit_debuglog("File " . $file . " is absent, can't construct server object");
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
/*** Helper functions ***/
|
||||
protected function ssoNameIdPolicyConfig($blob) {
|
||||
throw new Exception("Must be overloaded!!");
|
||||
}
|
||||
/** Helper function to do redirects. */
|
||||
protected function doRedirect(LassoProfile $profile) {
|
||||
$this->session->doRedirect($profile->msgUrl);
|
||||
}
|
||||
/** Return a normal HTTP response, for SOAP Response binding */
|
||||
protected function doResponse(LassoProfile $profile) {
|
||||
$this->session->doResponse('text/xml', $profile->msgBody);
|
||||
}
|
||||
/** Read a soap message from stdin */
|
||||
protected function receiveSOAPMessage() {
|
||||
$contents = file_get_contents("php://input");
|
||||
return $contents;
|
||||
}
|
||||
/** Retrieve the response message associated to an artifact string,
|
||||
method is the method used to transmit the artifact.
|
||||
This method makes a soap call to resolve the artifact, it is synchronous
|
||||
so can potentially take times.
|
||||
*/
|
||||
protected function artifactResolve(LassoProfile $profile, $query, $method, &$ok, &$ret) {
|
||||
$ok = $ok && ! $ret = $profile->initRequest($query, $method);
|
||||
$ok = $ok && ! $ret = $profile->buildRequestMsg();
|
||||
$ok = $ok && $content = LassoSPKitHelper::SoapCallWithProfile($profile);
|
||||
$ok = $ok && ! $ret = $profile->processResponseMsg($content);
|
||||
if (! $ok) {
|
||||
$this->setRet($ret);
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
/** Finish a request with a redirect transport */
|
||||
protected function finishRedirectRequest(LassoProfile $profile, &$ret, &$ok) {
|
||||
if ($ok) {
|
||||
$this->doRedirect($profile);
|
||||
}
|
||||
}
|
||||
/** Finish a request with a SOAP transport */
|
||||
protected function finishSOAPRequest(LassoProfile $profile, &$ret, &$ok, &$response) {
|
||||
if ($ok) {
|
||||
$response = LassoSPKitHelper::SoapCallWithProfile($profile);
|
||||
}
|
||||
}
|
||||
|
||||
protected function finishResponse(LassoProfile $profile, $method, &$ret, &$ok) {
|
||||
$ok = $ok && ! $ret = $profile->buildResponse();
|
||||
switch ($method) {
|
||||
case LASSO_HTTP_METHOD_REDIRECT:
|
||||
$this->doRedirect($profile);
|
||||
break;
|
||||
case LASSO_HTTP_METHOD_SOAP:
|
||||
$this->doResponse($profile);
|
||||
break;
|
||||
default:
|
||||
LassoSPKitHelper::notImplemented();
|
||||
}
|
||||
}
|
||||
|
||||
/** Web SSO protocol */
|
||||
|
||||
/** Start a WebSSO interaction. Initiate the redirect using
|
||||
the doRedirect method of the session object.
|
||||
Calls ssoNameIdPolicyConfig on the session object to initialize.
|
||||
*/
|
||||
protected function ssoCommon(&$login,
|
||||
$remoteID,
|
||||
$method,
|
||||
$isConsentObtained,
|
||||
$forceAuthn,
|
||||
$isPassive,
|
||||
$blob) {
|
||||
lassospkit_debuglog("SSO request initiated RID: $remoteID Meth: $method Consent: $isConsentObtained ForceAuthn: $forceAuthn Passive: $isPassive " . var_export($blob,1) );
|
||||
$ok = 1 && $login = new LassoLogin($this->server);
|
||||
$ok = $ok && ! $ret = $login->initAuthnRequest($remoteID,$method);
|
||||
$ok = $ok && $request = $login->request;
|
||||
$ok = $ok && $nameidpolicy = $request->NameIDPolicy;
|
||||
if ($ok) {
|
||||
$this->ssoNameIdPolicyConfig($login, $blob);
|
||||
$request->consent = $isConsentObtained;
|
||||
$request->ForceAuthn = $forceAuthn;
|
||||
$request->IsPassive = $isPassive;
|
||||
}
|
||||
$ok = $ok && ! $ret = $login->buildAuthnRequestMsg();
|
||||
if (! $ok) {
|
||||
lassospkit_debuglog("SSO request failed ErrCode: $ret");
|
||||
$this->setStatus("Erreur durant l'authentification");
|
||||
$this->setRet($ret);
|
||||
} else {
|
||||
switch($method) {
|
||||
case LASSO_HTTP_METHOD_REDIRECT:
|
||||
$this->doRedirect($login);
|
||||
break;
|
||||
default:
|
||||
LassoSPKitHelper::notImplemented();
|
||||
}
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
/** Method to consume response to auth requests. */
|
||||
function ssoConsumer($method, $message) {
|
||||
$ret = 0;
|
||||
lassospkit_debuglog("Consuming SSO assertion");
|
||||
$ok = 1 && $login = new LassoLogin($this->server);
|
||||
switch ($method) {
|
||||
case LASSO_HTTP_METHOD_ARTIFACT_GET:
|
||||
case LASSO_HTTP_METHOD_ARTIFACT_POST:
|
||||
$ok = $ok && $this->artifactResolve($login,
|
||||
$message,
|
||||
$method, $ok, $ret);
|
||||
break;
|
||||
case LASSO_HTTP_METHOD_POST:
|
||||
$ok = $ok && ! $ret = $this->processResponseMsg($message);
|
||||
break;
|
||||
}
|
||||
if ($ok) {
|
||||
try {
|
||||
$this->findFederation($login);
|
||||
} catch (LassoProfileFederationNotFoundError $error) {
|
||||
} catch (LassoProfileNameIdentifierNotFoundError $error) {
|
||||
$ok = 0;
|
||||
$ret = LASSO_PROFILE_ERROR_NAME_IDENTIFIER_NOT_FOUND;
|
||||
}
|
||||
}
|
||||
$ok = $ok && ! $ret = $login->acceptSso();
|
||||
if ($login->assertion) {
|
||||
LassoSPKitHelper::assertionExtractAttributes($login->assertion, $attributes);
|
||||
$this->session->processAttributes($attributes);
|
||||
}
|
||||
|
||||
if ($ok) {
|
||||
$this->saveFederation($login);
|
||||
}
|
||||
if (! $ok) {
|
||||
$this->setStatus("Le SSO a échoué");
|
||||
$this->setRet($ret);
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
|
||||
/** Web SLO methods */
|
||||
/* SP initiated */
|
||||
public function initiateSLO($method = LASSO_HTTP_METHOD_SOAP, $remoteID = null)
|
||||
{
|
||||
$ret = 0;
|
||||
lassospkit_debuglog("SLO SP initiated request");
|
||||
$ok = 1 && $logout = new LassoLogout($this->server);
|
||||
$this->findFederation($logout);
|
||||
$ok = $ok && ! $ret = $logout->initRequest($remoteID, $method);
|
||||
$ok = $ok && ! $ret = $logout->buildRequestMsg();
|
||||
if ($ok) {
|
||||
switch ($method) {
|
||||
case LASSO_HTTP_METHOD_REDIRECT:
|
||||
$this->finishRedirectRequest($logout, $ret, $ok);
|
||||
break;
|
||||
case LASSO_HTTP_METHOD_SOAP:
|
||||
$this->finishSOAPRequest($logout, $ret, $ok, $response);
|
||||
$ok = $ok && $this->processResponseSLO($logout, $response);
|
||||
break;
|
||||
case LASSO_HTTP_METHOD_ARTIFACT_GET:
|
||||
case LASSO_HTTP_METHOD_ARTIFACT_POST:
|
||||
case LASSO_HTTP_METHOD_POST:
|
||||
default:
|
||||
LassoSPKitHelper::notImplemented();
|
||||
}
|
||||
}
|
||||
if (! $ok) {
|
||||
lassospkit_debuglog("SLO SP initiated request failed ErrCode: $ret");
|
||||
$this->setStatus("Le SSO a échoué");
|
||||
$this->setRet($ret);
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
public function processRedirectResponseSLO() {
|
||||
$ret = 0;
|
||||
$logout = null;
|
||||
$ok = $this->processResponseSLO($logout, $_SERVER['QUERY_STRING']);
|
||||
if (! $ok) {
|
||||
lassospkit_debuglog("SLO SP initiated response failed ErrCode: $ret");
|
||||
$this->setStatus("Le SLO a échoué");
|
||||
$this->setRet($ret);
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
protected function processResponseSLO(&$logout, $message) {
|
||||
$ret = 0;
|
||||
$ok = 1;
|
||||
lassospkit_debuglog("SLO SP initiated Response");
|
||||
if (! $logout) {
|
||||
$ok = $ok && $logout = new LassoLogout($this->server);
|
||||
$this->findFederation($logout);
|
||||
}
|
||||
$ok = $ok && ! $ret = $logout->processResponseMsg($message);
|
||||
$prefix = "";
|
||||
switch ($ret) {
|
||||
case 0:
|
||||
break;
|
||||
case LASSO_DS_ERROR_INVALID_SIGNATURE:
|
||||
lassospkit_debuglog("Logout warn: invalid signature");
|
||||
$prefix = "Warning: ";
|
||||
$ok = 1;
|
||||
break;
|
||||
case LASSO_LOGOUT_ERROR_REQUEST_DENIED:
|
||||
lassospkit_debuglog("Logout warn: request denied");
|
||||
$prefix = "Warning: ";
|
||||
$ok = 1;
|
||||
break;
|
||||
case LASSO_LOGOUT_ERROR_UNKNOWN_PRINCIPAL:
|
||||
lassospkit_debuglog("Unknown principal on logout, probably session stopped already on IdP");
|
||||
$prefix = "Warning: ";
|
||||
$ok = 1;
|
||||
break;
|
||||
case LASSO_PROFILE_ERROR_INVALID_QUERY:
|
||||
lassospkit_debuglog("Invalid response");
|
||||
$prefix = "Error: ";
|
||||
$ok = 0;
|
||||
break;
|
||||
default:
|
||||
lassospkit_debuglog("SLO Response ErrCode: $ret");
|
||||
$prefix = "Error: ";
|
||||
$ok = 0;
|
||||
break;
|
||||
}
|
||||
if ($ok == 1) {
|
||||
$this->saveFederation($logout);
|
||||
$this->session->logout();
|
||||
}
|
||||
if ($ret != 0) {
|
||||
$this->setRet($ret, $prefix);
|
||||
lassospkit_debuglog("SLO Res Code: $ret");
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
/** IDP initiated SLO **/
|
||||
public function processRedirectRequestSLO() {
|
||||
return processRequestSLO(LASSO_HTTP_METHOD_REDIRECT,
|
||||
$_SERVER['QUERY_STRING']);
|
||||
}
|
||||
public function processSOAPRequestSLO() {
|
||||
$contents = $this->receiveSoapMessage();
|
||||
return processRequestSLO(LASSO_HTTP_METHOD_SOAP,
|
||||
$contents);
|
||||
}
|
||||
protected function processRequestSLO(&$method, $message) {
|
||||
lassospkit_debuglog("SLO Request handling");
|
||||
$ret = 0;
|
||||
$ok = $ok && $logout = new LassoLogout($this->server);
|
||||
$ok = $ok && ! $ret = $logout->processRequestMsg($content);
|
||||
$this->findFederation($logout);
|
||||
$ok = $ok && ! $ret = $logout->validateRequest();
|
||||
if ($ok) {
|
||||
if ($method == LASSO_HTTP_METHOD_ANY) {
|
||||
$method = $logout->http_request_method;
|
||||
} else {
|
||||
$ok = ($method == $logout->http_request_method);
|
||||
}
|
||||
}
|
||||
$this->finishResponse($method, $logout, $ret, $ok);
|
||||
if (! $ok) {
|
||||
lassospkit_debuglog("SLO Request handling failed ErrCode: $ret");
|
||||
$this->setStatus("Le SLO a échoué");
|
||||
$this->setRet($ret);
|
||||
} else {
|
||||
$this->session->logout();
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
protected function saveFederation(LassoProfile $profile) {
|
||||
LassoSPKitHelper::saveFederation($profile, $this->session);
|
||||
}
|
||||
protected function findFederation(LassoProfile $profile) {
|
||||
LassoSPKitHelper::findFederation($profile, $this->session);
|
||||
}
|
||||
/** Federation termination **/
|
||||
public function initiateFTNotification($method = LASSO_HTTP_METHOD_SOAP, $remoteID = null) {
|
||||
$this->session->changeFederation(null, null);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<?
|
||||
interface LassoSPKitStore {
|
||||
public function get($key);
|
||||
public function set($key, $value);
|
||||
public function delete($key);
|
||||
public function alias($key1,$key2);
|
||||
public function rename($key1, $key2);
|
||||
}
|
||||
|
||||
?>
|
|
@ -0,0 +1,65 @@
|
|||
<?php
|
||||
require_once('lassospkit_defines.inc.php');
|
||||
|
||||
class LassoSPKitUtils {
|
||||
static public function myself() {
|
||||
return 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'];
|
||||
}
|
||||
static public function mydir() {
|
||||
return 'http://' . $_SERVER['HTTP_HOST'] . dirname($_SERVER['PHP_SELF']);
|
||||
}
|
||||
static public function relativePathToURL($rel) {
|
||||
$abs = "";
|
||||
if (isset($_SERVER['HTTPS'])) {
|
||||
$abs = "https://";
|
||||
} else {
|
||||
$abs = "http://";
|
||||
}
|
||||
$abs = $abs . $_SERVER['HTTP_HOST'];
|
||||
$abs = $abs . dirname($_SERVER['PHP_SELF']) . "/";
|
||||
$abs = $abs . $rel;
|
||||
return $abs;
|
||||
}
|
||||
static function checkCanWrite($dir, &$error) {
|
||||
$path = $dir . "/" . _CHECK_FILENAME;
|
||||
$ok = ! file_exists($path) || unlink($path);
|
||||
$ok = $ok && $file = fopen($path,"w");
|
||||
$ok = $ok && fclose($file);
|
||||
unlink($path);
|
||||
if (! $ok) {
|
||||
$error = "Cannot write into " . $dir;
|
||||
}
|
||||
return $ok;
|
||||
}
|
||||
static function generatePrivateKey($file,&$error) {
|
||||
if (! is_file(OPENSSL_BIN)) {
|
||||
$error = "SSL Generate: Can't find OpenSSL at " . OPENSSL_BIN;
|
||||
return 0;
|
||||
}
|
||||
exec('/usr/bin/openssl genrsa -out ' . $file . ' 2048', $foo, $ret);
|
||||
if ($ret != 0) {
|
||||
$error = "SSL Generate: OpenSSL returned non-0 while computing the private key, check your ssl installation.";
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
public static function extractPublicKey($file,&$public,&$error) {
|
||||
if (! is_file(OPENSSL_BIN)) {
|
||||
$error = "SSL Generate: Can't find OpenSSL at " . OPENSSL_BIN;
|
||||
return 0;
|
||||
}
|
||||
$tempfname = tempnam(TEMPDIR, "lassospkit-public-key");
|
||||
$cmdline = '/usr/bin/openssl rsa -in ' . $file . ' -pubout -out ' . $tempfname;
|
||||
exec($cmdline, $foo, $ret);
|
||||
if ($ret != 0) {
|
||||
$error = "SSL Generate: OpenSSL return non-0 while extracting the public key from the private key file, check your ssl installation. $cmdline";
|
||||
return 0;
|
||||
}
|
||||
if (! $public = file_get_contents($tempfname)) {
|
||||
$error = "SSL Generate: Extracted public key is empty. See $tempfname.";
|
||||
return 0;
|
||||
}
|
||||
@unlink($tempfname);
|
||||
return 1;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,175 @@
|
|||
<?php
|
||||
|
||||
/** This object encapsulate the communication between the frontend and the
|
||||
backend of the LassoSPkit.
|
||||
|
||||
If you use autofederation, i.e if you let the backend store relations between
|
||||
NameID and your local userId, you would only use get/setUserID().
|
||||
|
||||
If not you must store Federation,NameID and UserID together in the application
|
||||
code.
|
||||
|
||||
*/
|
||||
class LassoSPKitUtilsSession {
|
||||
private static $key = "__LassoSPKitSessionObject";
|
||||
private static $THIS;
|
||||
private $vars;
|
||||
|
||||
/** If we getted the last error, clear it. */
|
||||
private $clears = array();
|
||||
/** The supported keys */
|
||||
static $keys = array(
|
||||
'NameID'=>0,
|
||||
'UserID'=>0,
|
||||
'Federation'=>0,
|
||||
'LastError'=>0,
|
||||
'loginRelayState'=>0,
|
||||
'federateRelayState'=>0,
|
||||
'ssoRelayState'=>0,
|
||||
'sloRelayState'=>0,
|
||||
'defederationRelayState'=>0,
|
||||
'nidmanagementRelayState'=>0,
|
||||
'errorRelayState'=>0,
|
||||
'loginParams'=>0,
|
||||
'federateParams'=>0,
|
||||
'sloParams'=>0,
|
||||
'defederationParams'=>0);
|
||||
/** The keys that must not survive one communication (one set followed by one get). */
|
||||
static $keysToClearAfterGet = array(
|
||||
'LastError'=>0,
|
||||
'loginRelayState'=>0,
|
||||
'federateRelayState'=>0,
|
||||
'ssoRelayState'=>0,
|
||||
'sloRelayState'=>0,
|
||||
'defederationRelayState'=>0,
|
||||
'nidmanagementRelayState'=>0,
|
||||
'errorRelayState'=>0,
|
||||
'loginParams'=>0,
|
||||
'federateParams'=>0,
|
||||
'sloParams'=>0,
|
||||
'defederationParams'=>0);
|
||||
|
||||
private function __construct() {
|
||||
if (! isset($_SESSION)) {
|
||||
throw new Exception("LassoSPKit cannot work without sessions.");
|
||||
}
|
||||
if (isset($_SESSION[self::$key])) {
|
||||
$t = @unserialize($_SESSION[self::$key]);
|
||||
if ($t && is_array($t)) {
|
||||
$this->vars = $t;
|
||||
} else {
|
||||
// Malformed session object, reset
|
||||
$this->vars = array();
|
||||
self::clear();
|
||||
}
|
||||
} else {
|
||||
$this->vars = array();
|
||||
}
|
||||
}
|
||||
/** In the finalizer, reset one-shot keys, then
|
||||
store the rest in the PHP session */
|
||||
function __destruct() {
|
||||
foreach ($this->clears as $k => $v) {
|
||||
unset($this->vars[$k]);
|
||||
}
|
||||
$_SESSION[self::$key] = serialize($this->vars);
|
||||
}
|
||||
|
||||
/** Get the singleton object to communicate
|
||||
with the backend/fronted of the LassoSPKit. */
|
||||
public static function getSingleton() {
|
||||
if (! self::$THIS) {
|
||||
self::$THIS = new LassoSPKitUtilsSession();
|
||||
}
|
||||
return self::$THIS;
|
||||
}
|
||||
function get($key) {
|
||||
if (! isset(self::$keys[$key])) {
|
||||
throw new Exception("The key $key is not supported by LassoSPKitUtilsSession");
|
||||
}
|
||||
if (isset(self::$keysToClearAfterGet[$key])) {
|
||||
$this->clearAtShutdown($key);
|
||||
}
|
||||
if (isset($this->vars[$key])) {
|
||||
return $this->vars[$key];
|
||||
}
|
||||
return null;
|
||||
}
|
||||
function set($key, $value) {
|
||||
if (! isset(self::$keys[$key])) {
|
||||
throw new Exception("The key $key is not supported by LassoSPKitUtilsSession");
|
||||
}
|
||||
if (isset(self::$keysToClearAfterGet[$key])) {
|
||||
$this->doNotClearAtShutdown($key);
|
||||
}
|
||||
$this->vars[$key] = $value;
|
||||
}
|
||||
function clearAtShutdown($key) {
|
||||
$this->clears[$key] = 1;
|
||||
}
|
||||
function doNotClearAtShutdown($key) {
|
||||
unset($this->clears[$key]);
|
||||
}
|
||||
/** Return the NameID resulting
|
||||
* of the last WebSSO or passed from the
|
||||
* application to other profiles thant SSO,
|
||||
* like SLO, FederationTermination or
|
||||
* NameIdManagement. */
|
||||
static function getNameID() {
|
||||
$athis = self::getSingleton();
|
||||
return $athis->get('NameID');
|
||||
}
|
||||
|
||||
/* Helper static functions */
|
||||
|
||||
/** Clear the session object of all communication
|
||||
from the LassoSPKit. */
|
||||
static function clear() {
|
||||
unset($_SESSION[self::$key]);
|
||||
}
|
||||
/** Set the NameID to transmit. */
|
||||
static function setNameID($NameID) {
|
||||
$athis = self::getSingleton();
|
||||
$athis->set('NameID',$NameID);
|
||||
}
|
||||
static function getUserID() {
|
||||
$athis = self::getSingleton();
|
||||
return $athis->get('UserID');
|
||||
}
|
||||
static function setUserID($UserID) {
|
||||
$athis = self::getSingleton();
|
||||
$athis->set('UserID',$UserID);
|
||||
}
|
||||
static function getLastError() {
|
||||
$athis = self::getSingleton();
|
||||
return $athis->get('LastError');
|
||||
}
|
||||
static function setLastError($LastError) {
|
||||
$athis = self::getSingleton();
|
||||
$athis->set('LastError',$LastError);
|
||||
}
|
||||
static function getFederation() {
|
||||
$athis = self::getSingleton();
|
||||
return $athis->get('Federation');
|
||||
}
|
||||
static function setFederation($Federation) {
|
||||
$athis = self::getSingleton();
|
||||
$athis->set('Federation',$Federation);
|
||||
}
|
||||
static function getRelayState($profile) {
|
||||
$athis = self::getSingleton();
|
||||
return $athis->get($profile . "RelayState");
|
||||
}
|
||||
static function setRelayState($profile, $RelayState) {
|
||||
$athis = self::getSingleton();
|
||||
$athis->set($profile."RelayState", $RelayState);
|
||||
}
|
||||
static function getParams($profile) {
|
||||
$athis = self::getSingleton();
|
||||
return $athis->get($profile . "Params");
|
||||
}
|
||||
static function setParams($profile, $Params) {
|
||||
$athis = self::getSingleton();
|
||||
$athis->set($profile ."Params", $Params);
|
||||
}
|
||||
}
|
Reference in New Issue