This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
spkitlasso/include/lassospkit_helper.inc.php

210 lines
7.3 KiB
PHP

<?php
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) {
#lassospkit_debuglog("load dump " . $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 $attributes. */
static function assertionExtractAttributes($assertion) {
$attributes = array();
if ($assertion->attributeStatement && count($assertion->attributeStatement)) {
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 $attributes;
}
/** 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) {
self::saveDumps($profile,$session);
$session->saveFederation();
}
/** 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);
self::saveDumps($profile,$session);
$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) {
return 0;
}
self::restoreDumps($profile,$session);
return 1;
}
/** Post some datas to given host */
static function postToHost($host, $path, $data_to_send, $ssl = false, &$code) {
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);
preg_match('/HTTP\/[0-9]+\.[0-9]+ ([0-9]+) .*/', $res, $matches);
$code = $matches[1];
$res = substr(strstr($res, "\r\n\r\n"), 4);
return $res;
}
static public function soapCall($url, $msg, &$code) {
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, false, $code);
return $response;
}
/** Make a SOAP call using parameters found in profile. */
static public function SoapCallWithProfile(LassoProfile $profile, &$code) {
return self::soapCall($profile->msgUrl, $profile->msgBody, $code);
}
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) {
if ($federation) {
$nameIDs[$rid] = $federation->localNameIdentifier->content;
}
}
return $nameIDs;
}
}