From 5e0bbe1777d85c48c11a754bf2d5109ff47ce742 Mon Sep 17 00:00:00 2001 From: "Stefan E. Funk" <funk@textgrid-esx1.gwdg.de> Date: Fri, 6 Nov 2015 13:37:18 +0100 Subject: [PATCH] Reset to old LDAP usage, now we can: - use Shib with the EDS.php - use old LDAP login screen for SADE and Co. using WebAuthN2.php - and use WebAuthN.php for new LDAP only access (puppet) All right? Gerat! Have a nice day! --- .../WebAuthN/TextGrid-WebAuth.php | 1 + .../WebAuthN/TextGrid-WebAuth.php_BACK | 163 ++++++++++++ .../WebAuthN/WebAuthN2.php | 84 +++++++ .../tglib/LDAP.class.php | 178 +++++++++++++ .../tglib/RBAC.Class.php_BACK | 233 ++++++++++++++++++ .../tglib/RBAC.class.php | 169 ++++++++++++- 6 files changed, 824 insertions(+), 4 deletions(-) create mode 100644 info.textgrid.middleware.tgauth.webauth/WebAuthN/TextGrid-WebAuth.php_BACK create mode 100644 info.textgrid.middleware.tgauth.webauth/WebAuthN/WebAuthN2.php create mode 100644 info.textgrid.middleware.tgauth.webauth/tglib/LDAP.class.php create mode 100644 info.textgrid.middleware.tgauth.webauth/tglib/RBAC.Class.php_BACK diff --git a/info.textgrid.middleware.tgauth.webauth/WebAuthN/TextGrid-WebAuth.php b/info.textgrid.middleware.tgauth.webauth/WebAuthN/TextGrid-WebAuth.php index 3cff6ce..f00011c 100644 --- a/info.textgrid.middleware.tgauth.webauth/WebAuthN/TextGrid-WebAuth.php +++ b/info.textgrid.middleware.tgauth.webauth/WebAuthN/TextGrid-WebAuth.php @@ -41,6 +41,7 @@ if (isset ($_REQUEST["loginname"]) && strlen($_REQUEST["loginname"]) > 0 } $ProvidedAttributes = $ldap->getUserAttributes(); $_SERVER["REMOTE_USER"] = $AuthNResult["TGID"]; + error_log("found user: " . $AuthNResult["TGID"]); } diff --git a/info.textgrid.middleware.tgauth.webauth/WebAuthN/TextGrid-WebAuth.php_BACK b/info.textgrid.middleware.tgauth.webauth/WebAuthN/TextGrid-WebAuth.php_BACK new file mode 100644 index 0000000..3cff6ce --- /dev/null +++ b/info.textgrid.middleware.tgauth.webauth/WebAuthN/TextGrid-WebAuth.php_BACK @@ -0,0 +1,163 @@ +<?php +// ####################################################### +// Author: Martin Haase / DAASI International GmbH / TextGrid +// Creation date: 2010-09-23 +// Modification date: 2010-10-19 +// Version: 0.2 +// ####################################################### + +include("../tglib/LDAP.class.php"); +include("../tglib/RBAC.class.php"); +include("../tglib/WebUtils.class.php"); + +$configfile = "/etc/textgrid/tgauth/conf/config_tgwebauth.xml"; + +$util = new WebUtils; + +$authZinstance = $_REQUEST["authZinstance"]; + +if ( !(isset($authZinstance)) || strlen($authZinstance) <= 0 ) { + $util->printAuthFailure("no_tgauth_instance_heading", + "no_tgauth_instance_detail", + null, + null ); + exit; +} + +$rbac = new RBAC ( $configfile, $authZinstance ); + +// Variant 1: Authentication at Community LDAP +if (isset ($_REQUEST["loginname"]) && strlen($_REQUEST["loginname"]) > 0 + && isset ($_REQUEST["password"]) && strlen($_REQUEST["password"]) > 0) { + // now authenticating + $ldap = new LDAP ( $configfile ); + $AuthNResult = $ldap->authenticate($_REQUEST["loginname"], $_REQUEST["password"]); + if (! $AuthNResult["success"]) { + $util->printAuthFailure("authn_failure_heading", + $AuthNResult["detail"], + $_REQUEST["loginname"], + null ); + exit; + } + $ProvidedAttributes = $ldap->getUserAttributes(); + $_SERVER["REMOTE_USER"] = $AuthNResult["TGID"]; +} + + +// Variant 2: Shibboleth gave us the right REMOTE_USER. +// We create a Session here in RBAC, also for Variant1 +if (isset ($_SERVER["REMOTE_USER"])) { // this holds for both shib and ldap authN + + // now creating session, activating roles, etc, in RBAC + + $CSResult = $rbac->createSession( $_SERVER["REMOTE_USER"] ); + if (isset ($AuthNResult)) { + $CSResult["rbachash"]["identity_provider"] = $AuthNResult["LDAPname"]; + } else { + $CSResult["rbachash"]["identity_provider"] = $_SERVER["Shib-Identity-Provider"]; + } + + if (!$CSResult["success"]) { + $util->printAuthFailure("sid_create_failure_heading", + $CSResult["detail"], + $_REQUEST["loginname"], + $CSResult["rbachash"] + ); + exit; + } + $Sid = $CSResult["rbachash"]["Sid"]; + + $AttributeMap = Array ('surname' => 'sn', + 'organisation' => 'o', + 'givenname' => 'givenName', + 'displayname' => 'cn', + 'mail' => 'mail' + ); + if (!isset ($ldap)) { + $ProvidedAttributes = Array(); + // this is the list of attributes Shibboleth might give to us except from remote_user + foreach (array ("o", "sn", "givenName", "cn", "mail") as $a) { + if (isset($_SERVER[$a])) { $ProvidedAttributes[$a] = $_SERVER[$a];} + } + } +} +// This is Variant 3: No Session Creation, but just a desire to see (and update) User Attributes +else if (isset ($_REQUEST["Sid"]) && strlen($_REQUEST["Sid"]) > 0 ) { +// we might have come directly here using the sid and use an earlier session + $Sid = $_REQUEST["Sid"]; +} +// not enough information, exiting. + else + { + + // check if we came via Shibboleth, but without an eduPersonPrincipalName + // (which would have been the REMOTE_USER) + if (isset( $_SERVER['Shib-Session-ID'] )) { + $util->printAuthFailure("shib_login_failure_heading", + "shib_login_failure_detail", + "(Shibboleth login, but no ePPN provided)", + null ); + exit; + } + else + { + $missing = 0; + if (!isset($_REQUEST["loginname"]) || strlen($_REQUEST["loginname"]) == 0) { + $missing = 1; + } + if (!isset($_REQUEST["password"]) || strlen($_REQUEST["password"]) == 0) { + $missing = $missing + 2; + } + + if ($missing == 0) { + $util->printAuthFailure("authn_failure_heading", + "authn_failure_detail_nothing_to_do", + $_REQUEST["loginname"], + null ); + trigger_error("WebAuth does not know what to do (no login or password provided, no remote user, and no session Id), exiting.", E_USER_WARNING); + } else if ($missing == 1) { + $util->printAuthFailure("authn_failure_heading", + "authn_failure_detail_id_missing", + '(null)', + null ); + } else if ($missing == 2) { + $util->printAuthFailure("authn_failure_heading", + "authn_failure_detail_password_missing", + $_REQUEST["loginname"], + null ); + } else if ($missing == 3) { + $util->printAuthFailure("authn_failure_heading", + "authn_failure_detail_both_missing", + '(null)', + null ); + } + exit; + } + } + +// no matter where we came from we need to retrieve attributes from RBAC +$attributes = $rbac->getUserAttributes( $Sid ); + +// if we already have enough attributes and just created a session, possibly update +// them if there came different ones, and then finally print welcome screen causing +// the TextGridLab to take over the Sid +if ($rbac->enoughUserAttributes( $Sid ) && isset ($_SERVER["REMOTE_USER"])) { + $util->printAuthSuccess("authn_succeeded_heading", + isset($_REQUEST["loginname"]) ? $_REQUEST["loginname"] : $_SERVER["REMOTE_USER"], + $CSResult["rbachash"], + $rbac->slcData() + ); + $rbac->updateAttributes ( $ProvidedAttributes, $AttributeMap, $Sid ); // not vital and second-order +} else { + // now presenting the form, let JavaScript take care for the non-empty-check and the help + // the form will return either displaying the Sid or just an ACK + if (isset ($_SERVER["REMOTE_USER"])) { + $util->printAttributeForm( $attributes, $ProvidedAttributes, $AttributeMap, $Sid, $authZinstance, $_SERVER["REMOTE_USER"], $rbac->ToUversion, $rbac->ToUtext); + } else if (isset ($_REQUEST["ePPN"])) { // direct invocation of userdata modification dialogue + $util->printAttributeForm( $attributes, null, null, $Sid, $authZinstance, $_REQUEST["ePPN"], $rbac->ToUversion, $rbac->ToUtext); + } else { + echo "Could not modify attributes, not enough information"; + } +} + +?> diff --git a/info.textgrid.middleware.tgauth.webauth/WebAuthN/WebAuthN2.php b/info.textgrid.middleware.tgauth.webauth/WebAuthN/WebAuthN2.php new file mode 100644 index 0000000..636909e --- /dev/null +++ b/info.textgrid.middleware.tgauth.webauth/WebAuthN/WebAuthN2.php @@ -0,0 +1,84 @@ +<?php +// ####################################################### +// Author: Martin Haase / DAASI International GmbH +// Creation date: 02.12.2008 +// Modification date: 06/06/2012 +// Version: 2.0 +// ####################################################### + +ob_start(); +require_once '../i18n_inc/class.I18Nbase.inc.php'; +$t = new I18Ntranslator(); + + +header("Content-Type: text/html; charset=UTF-8"); + +$authZinstance = $_REQUEST["authZinstance"]; +if ($authZinstance == null) { + echo $t->_('no_tgauth_instance_heading') . "\n"; + echo $t->_('no_tgauth_instance_detail'); + exit; +} +?> +<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"> + +<html> +<head> +<meta http-equiv="content-type" content="text/html; charset=UTF-8"> +<title>TextGrid WebAuth</title> +</head> +<body> +<div style="font-family:Helvetica,Arial,sans-serif;"> + +<h2><?php echo $t->_('login_heading');?></h2> +<table border="1" rules="cols" cellpadding="4" style="background: #EEEEEE;"> +<tr> +<td align="center" valign="top"> +<h3><?php echo $t->_('login_option_ldap');?></h3> +</td> + +<td align="center" valign="top"> +<h3><?php echo $t->_('login_option_shib');?></h3> +</td> +</tr> + +<tr> +<td rowspan="2"> +<form action="TextGrid-WebAuth.php" method="post" name="textgriddeform"> + <p><?php echo $t->_('login_label_id');?><br><input style="-webkit-appearance:none;" name="loginname" type="text" size="30" maxlength="30" value="Login ID" onclick="MachLeer()"></p> + <p><?php echo $t->_('login_label_password');?><br><input style="-webkit-appearance:none;" name="password" type="password" size="30" maxlength="30"></p> +<?php + echo "<input name=\"authZinstance\" type=\"hidden\" value=\"". $authZinstance . "\">"; +?> + <input type="submit" value="log in"> +</form> +<script type="text/javascript"> +document.textgriddeform.loginname.focus(); +document.textgriddeform.loginname.select(); +function MachLeer () { + if (document.textgriddeform.loginname.value == "Login ID") + document.textgriddeform.loginname.value = ""; +} +</script> +</td> + + +<td align="center" valign="top"> +<form action="../secure/TextGrid-WebAuth.php"> +<?php + echo "<input name=\"authZinstance\" type=\"hidden\" value=\"". $authZinstance . "\">"; + echo "<input type=\"submit\" value=\"".$t->_('login_button_shib')."\">"; +?> +</form> +</td> +</tr> + +<tr> +<td><?php +echo $t->_('login_shib_explanation'); +?></td> +</tr> +</table> +</div> +</body> +</html> diff --git a/info.textgrid.middleware.tgauth.webauth/tglib/LDAP.class.php b/info.textgrid.middleware.tgauth.webauth/tglib/LDAP.class.php new file mode 100644 index 0000000..5d95879 --- /dev/null +++ b/info.textgrid.middleware.tgauth.webauth/tglib/LDAP.class.php @@ -0,0 +1,178 @@ +<?php +// ####################################################### +// Author: Martin Haase / DAASI International GmbH / TextGrid +// Creation date: 2010-09-23 +// Modification date: 2010-09-03 +// Version: 0.1 +// based on authenticate.php +// ####################################################### + +mb_internal_encoding("UTF-8"); + +class LDAP { + + // Global variables + protected $UserAttributes = array(); + protected $ldaphost; + protected $ldapport; + protected $binddn; + protected $filter; + protected $IDattribute; + protected $LDAPname; + public $availableAttributes = array("o", "sn", "givenName", "cn", "mail"); + public $AttributeMap = Array ('surname' => 'sn', +// StefanS will 'o' nicht User-Modifizierbar; daher wird +// es nur in RBAC und nicht in DARIAH LDAP geschrieben +// 'organisation' => 'o', + 'givenname' => 'givenName', + 'displayname' => 'cn', + 'mail' => 'mail', + 'orgunit' => 'ou', + 'street' => 'street', + 'plz' => 'postalCode', + 'city' => 'l', + 'tel' => 'telephoneNumber', + 'interest' => 'dariahResearchInterests', + 'personid' => 'dariahResearcherId' + ); + + public function __construct( $configfilepath ) { + $config = new DOMDocument(); + $config->load($configfilepath); + $xpath = new DOMXPath($config); + $xpath->registerNamespace("c", "http://textgrid.info/namespaces/middleware/tgwebauth"); + + $this->ldaphost = $xpath->query("/c:conf/c:authn[@type='community']/c:key[@name='host']")->item(0)->nodeValue; + $this->ldapport = $xpath->query("/c:conf/c:authn[@type='community']/c:key[@name='port']")->item(0)->nodeValue; + $this->binddn = $xpath->query("/c:conf/c:authn[@type='community']/c:key[@name='binddn']")->item(0)->nodeValue; + $this->basedn = $xpath->query("/c:conf/c:authn[@type='community']/c:key[@name='basedn']")->item(0)->nodeValue; + $this->filter = $xpath->query("/c:conf/c:authn[@type='community']/c:key[@name='filter']")->item(0)->nodeValue; + $this->IDattribute = $xpath->query("/c:conf/c:authn[@type='community']/c:key[@name='IDattribute']")->item(0)->nodeValue; + $this->LDAPname = $xpath->query("/c:conf/c:authn[@type='community']/c:key[@name='name']")->item(0)->nodeValue; + $this->setAttributesDN = $xpath->query("/c:conf/c:authn[@type='community']/c:key[@name='setAttributesDN']")->item(0)->nodeValue; + $this->setAttributesPW = $xpath->query("/c:conf/c:authn[@type='community']/c:key[@name='setAttributesPW']")->item(0)->nodeValue; + + $this->IDattribute = explode ( ";", $this->IDattribute ); + } + + public function authenticate ($login, $password) { + $ldapconn = ldap_connect( $this->ldaphost, $this->ldapport ); + // ldap_connect always returns a handle, does not connect yet + // or return array("success" => FALSE, "detail" => "Cannot connect to {$ldaphost}!"); + + ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); +// $return = ldap_start_tls( $ldapconn ); +// $file = fopen ("/tmp/ssstls", "a+"); +// fwrite ($file, serialize($return)); +// fclose($file); + + $binddn = preg_replace ('/\${login}/', $login, $this->binddn); + $bound = ldap_bind($ldapconn, $binddn , $password); + if (!$bound) { + return array("success" => FALSE, + "detail" => "Authentication failed, reason: " . ldap_error ($ldapconn)); + } else { + //echo "Could bind as user ${login}!"; + $filter = preg_replace ('/\${login}/', $login, $this->filter); + $result = ldap_search( $ldapconn, $this->basedn, $filter); + $entry = ldap_first_entry( $ldapconn , $result ); + + $this->UserAttributes = ldap_get_attributes ($ldapconn , $entry); + + foreach ( $this->IDattribute as $idattr ) { + if ( isset ( $this->UserAttributes[$idattr] ) ) { + $TGID = $this->UserAttributes[$idattr][0]; + break; + } + } + +// $TGID = $this->UserAttributes[$this->IDattribute][0]; + + return array("success" => TRUE, "TGID" => $TGID, "LDAPname" => $this->LDAPname); + } + } + + public function getUserAttributes () { + $rethash = array(); + foreach ($this->availableAttributes as $a) { + if ( isset($this->UserAttributes[$a])) { + $vals = array(); + for ($i=0; $i<$this->UserAttributes[$a]['count']; $i++) { + $vals[] = $this->UserAttributes[$a][$i]; + } + $rethash[$a] = implode (';', $vals); + } + } + return $rethash; + } + +// Users will be modified via DARIAH SelfService at a later stage + public function setUserAttributes ($attrHash, $remote_user) { + + $arrModify = Array(); + $needsModification = FALSE; + $sendOutMail = FALSE; + + foreach ($attrHash as $a) { + if (is_object($a) && in_array($a->name, array_keys ($this->AttributeMap))) { + $arrModify[$this->AttributeMap[$a->name]][] = $a->value; + $needsModification = TRUE; + if ($a->name === "mail") { + $sendOutMail = $a->value; + } + } + } + + if (! $needsModification ) { + return array("success" => TRUE, + "detail" => "Nothing to do"); + } + + + $ldapconn = ldap_connect( $this->ldaphost, $this->ldapport ); + // ldap_connect always returns a handle, does not connect yet + // or return array("success" => FALSE, "detail" => "Cannot connect to {$ldaphost}!"); + + ldap_set_option($ldapconn, LDAP_OPT_PROTOCOL_VERSION, 3); + //ldap_start_tls( $ldapconn ); + + $bound = ldap_bind($ldapconn, $this->setAttributesDN , $this->setAttributesPW); + if (!$bound) { + return array("success" => FALSE, + "detail" => "Authentication failed, reason: " . ldap_error ($ldapconn)); + } else { + + $filter = "(|"; + foreach ( $this->IDattribute as $idattr ) { + $filter .= "(". $idattr."=".$remote_user.")"; + } + $filter .= ")"; + + $result = ldap_search( $ldapconn, $this->basedn, $filter); + if ($result === FALSE ) { + return array("success" => FALSE, + "detail" => "Could not find this user with the filter: ".$filter . ldap_error ($ldapconn)); + } + $entry = ldap_first_entry( $ldapconn , $result ); + $oldmailsArr = ldap_get_values ($ldapconn, $entry, "mail"); + if ($sendOutMail !== FALSE) { + $this->sendmailOut($oldmailsArr, $sendOutMail ); + } + + $modifyResult = ldap_modify($ldapconn, ldap_get_dn($ldapconn, $entry), $arrModify); + + if ($modifyResult == FALSE ) { + return array("success" => FALSE, + "detail" => "Could not modify this user:" . ldap_error ($ldapconn)); + } + return array("success" => TRUE, "detail" => "Alles bestens"); + } + } + + public function sendmailOut($oldmailsArr, $newMail ) { + + } + +} + +?> diff --git a/info.textgrid.middleware.tgauth.webauth/tglib/RBAC.Class.php_BACK b/info.textgrid.middleware.tgauth.webauth/tglib/RBAC.Class.php_BACK new file mode 100644 index 0000000..d380a85 --- /dev/null +++ b/info.textgrid.middleware.tgauth.webauth/tglib/RBAC.Class.php_BACK @@ -0,0 +1,233 @@ +<?php +// ####################################################### +// Author: Martin Haase / DAASI International GmbH / TextGrid +// Creation date: 2010-10-13 +// Modification date: 2010-10-13 +// Version: 0.1 +// based on TextGrid-Webauth.php +// ####################################################### + +mb_internal_encoding("UTF-8"); + +class RBAC { + + // Global variables + protected $authZinstance; + + protected $rbacbase; + protected $sessionCreatorUid; + protected $sessionCreatorPw; + protected $setnamessecret; + public $ToUversion; + protected $ToUFileName; + public $ToUtext; + + protected $soapExtra; + protected $soapPolicy; + protected $soapReview; + protected $soapAdministration; + + public function __construct( $configfilepath , $authZinstance ) { + require_once( "soapTypes.inc.php" ); + + $config = new DOMDocument(); + $config->load($configfilepath); + $xpath = new DOMXPath($config); + $xpath->registerNamespace("c", "http://textgrid.info/namespaces/middleware/tgwebauth"); + + $this->rbacbase = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:rbacbase")->item(0)->nodeValue; + if (!isset ($this->rbacbase) || strlen($this->rbacbase) == 0) { + echo "Error: '${authZinstance}' has no RBAC base configured!<br/>\n"; + return null; + } + $this->authZinstance = $authZinstance; + $this->sessionCreatorUid = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:sessioncreator/c:user")->item(0)->nodeValue; + $this->sessionCreatorPw = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:sessioncreator/c:password")->item(0)->nodeValue; + $this->setnamessecret = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:setnamessecret")->item(0)->nodeValue; + + // ----------------------------------------------------- + // You'll need these services + // ----------------------------------------------------- + + $this->soapExtra = new SoapClient( $this->rbacbase . "wsdl/tgextra.wsdl" ); + $this->soapPolicy = new SoapClient( $this->rbacbase . "wsdl/tgsystem.wsdl" ); + $this->soapReview = new SoapClient( $this->rbacbase . "wsdl/tgreview.wsdl" ); + $this->soapAdministration = new SoapClient( $this->rbacbase . "wsdl/tgadministration.wsdl" ); + + } + + public function createSession ( $remote_user ) { + + $rbachash = array("scstatus" => "", // will collect all messages during authentication + "Sid" => "none", // this will hold the final sessionId then + "rbacbase" => $this->rbacbase, + 'authZinstance' => $this->authZinstance + ); + + // ------------------------------------------------------------ + // check whether remote_user is set and has user@domain format + if (preg_match('/([^@]+)@([^@]+)/', $remote_user, $matches) == 1) { + $identified_user = array("authnmethod" => "eduPersonPrincipalName", + "user" => $matches[1], + "scope" => $matches[2] ); + + $rbachash["identified_user"] = $identified_user; + $rbachash["remote_user"] = $remote_user; // TG User ID + + } else { + return array("success" => FALSE, + "detail" => "User ID not given by home institution.<br/>\n" + ."Your school (its Identity Provider) did not provide a useable User ID to TextGrid (".$remote_user .").<br/>\n" + ."Please contact your school's computing centre and ask them to release to TextGrid's Service Provider " + ."the eduPersonPrincipalName attribute.<br/>Thank you.", + "rbachash" => $rbachash); + exit; + } + $rbachash["scstatus"] .= "Authentication Method: ". $identified_user['authnmethod'] . "; "; + + + // ----------------------------------------------------- + // Before you can create a session you have to + // authenticate. If this was successful you get a + // session-ID that you should keep + // ----------------------------------------------------- + $serviceAuthReq = new authenticateRequest(); + $serviceAuthReq->username = $this->sessionCreatorUid; + $serviceAuthReq->password = $this->sessionCreatorPw; + + try { + $serviceAuthResponse = $this->soapExtra->authenticate( $serviceAuthReq ); + + if( preg_match( "/[0-9a-z]{2,}/i", $serviceAuthResponse->auth ) ) { + $rbachash["scstatus"] .= "WebAuth authenticated at RBAC, received a service SessionId. " ; + } + + } catch( SoapFault $f ) { + return array("success" => FALSE, + "detail" => "SOAP FAULT (authenticate)!: " . $f->faultcode . " / " . $f->faultstring, + "rbachash" => $rbachash); + exit; + } + + + // ----------------------------------------------------- + // Now you can try to add an active role to your session creator session + // ----------------------------------------------------- + $addRoleReq = new addActiveRoleRequest(); + $addRoleReq->username = $this->sessionCreatorUid; + $addRoleReq->role = "sessionCreator,Anwendung"; + $addRoleReq->auth = $serviceAuthResponse->auth; + + try { + $addRoleResponse = $this->soapExtra->tgAddActiveRole( $addRoleReq ); + + if( $addRoleResponse->result ) { + $rbachash["scstatus"] .= "Added active role of application; "; + } else { + return array("success" => FALSE, + "rbachash" => $rbachash, + "detail" => "Internal Error, Could not add Role for application."); + exit; + } + } catch( SoapFault $f ) { + return array("success" => FALSE, + "rbachash" => $rbachash, + "detail" => "SOAP FAULT (tgAddActiveRole)!: " . $f->faultcode . " / " . $f->faultstring); + exit; + } + + // ----------------------------------------------------- + // Check whether user exists already in RBAC + // ----------------------------------------------------- + // ---> we do not need this anymore since users are in DARIAH + + + // ----------------------------------------------------- + // If this was successful you can create the session for remote_user + // need to add active roles to the session + // ----------------------------------------------------- + $creReq = new createSessionRequest(); + $creReq->intSid = $serviceAuthResponse->auth; + //$creReq->username = "mhaase@uni-tuebingen.de"; + $creReq->username = $remote_user; + + //$creReq->roleset = Array( "Projektleiter,Projekt-1,Projekt-Teilnehmer" ); + //$creReq->roleset = Array( "Bearbeiter,Projekt-1,Projekt-Teilnehmer" ); + + //--------------------------- + // get ALL available roles... + $rolesobject = new authorizedRolesRequest(); + $rolesobject->intSid = $serviceAuthResponse->auth; + $rolesobject->username = $remote_user; + + try { + $roleResponse = $this->soapReview->authorizedRoles($rolesobject); + + $rbachash["scstatus"] .= "Received all available roles for user; "; + } catch (Soapfault $f) { + return array("success" => FALSE, + "rbachash" => $rbachash, + "detail" => "SOAP FAULT (authorizedRoles)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->getTraceAsString()); + exit; + } + if (!isset($roleResponse->role)) { + $creReq->roleset = Array(); + } elseif (is_Array($roleResponse->role)) { + $creReq->roleset = $roleResponse->role; + } elseif (is_string($roleResponse->role)) { + $creReq->roleset = Array($roleResponse->role); + } else { + $creReq->roleset = Array(); + } + + // ------------------------------------------------ + // Get a newly generated sid from the RBAC system + try { + $Sid = $this->soapExtra->getSid(); + $Sid = $Sid->sid; + $rbachash["Sid"] = $Sid; + } catch (Soapfault $f) { + return array("success" => FALSE, + "rbachash" => $rbachash, + "detail" => "RBAC down? Could not generate a new SessionID!" ); + exit; + } + + // ------------------------------------- + // Creating the session... + $creReq->sid = $Sid; + // $file=fopen("/tmp/creq", "a+"); + //fwrite ($file, "--------------\n"); + //fwrite ($file, serialize ($creReq)); + //fwrite ($file, "\n"); + //fclose($file); + + try { + $creResponse = $this->soapPolicy->createSession( $creReq ); + + if( $creResponse->result ) { + + $rbachash["scstatus"] .= "Created sessions with active roles; "; + } else { + return array("success" => FALSE, + "rbachash" => $rbachash, + "detail" => "Failed to create a new Session!" ); + exit; + } + + } catch (SoapFault $f) { + return array("success" => FALSE, + "rbachash" => $rbachash, + "detail" => "SOAP FAULT (CreateSession)!: " . $f->faultcode . " / " . $f->faultstring); + exit; + } + + // -------------------------------------------------------- + // now all went well, createSession worked, return success + return array("success" => TRUE, + "rbachash" => $rbachash); + } + +} + +?> diff --git a/info.textgrid.middleware.tgauth.webauth/tglib/RBAC.class.php b/info.textgrid.middleware.tgauth.webauth/tglib/RBAC.class.php index d380a85..7156e04 100644 --- a/info.textgrid.middleware.tgauth.webauth/tglib/RBAC.class.php +++ b/info.textgrid.middleware.tgauth.webauth/tglib/RBAC.class.php @@ -7,6 +7,8 @@ // based on TextGrid-Webauth.php // ####################################################### +include( "ESoapClient.php"); + mb_internal_encoding("UTF-8"); class RBAC { @@ -27,9 +29,15 @@ class RBAC { protected $soapReview; protected $soapAdministration; + protected $userAttributes; + + protected $SLCdata; + public function __construct( $configfilepath , $authZinstance ) { require_once( "soapTypes.inc.php" ); + error_log("rbac construct called"); + $config = new DOMDocument(); $config->load($configfilepath); $xpath = new DOMXPath($config); @@ -44,11 +52,33 @@ class RBAC { $this->sessionCreatorUid = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:sessioncreator/c:user")->item(0)->nodeValue; $this->sessionCreatorPw = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:sessioncreator/c:password")->item(0)->nodeValue; $this->setnamessecret = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:setnamessecret")->item(0)->nodeValue; + $this->ToUversion = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:termsOfUse/c:version")->item(0)->nodeValue; + $this->ToUFileName = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:termsOfUse/c:text")->item(0)->nodeValue; + $this->ToUtext = file_get_contents ( $this->ToUFileName ); + + $this->SLCdata = array(); + $slcSupportEnabling = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/@enable"); + if ($slcSupportEnabling->length > 0 && $slcSupportEnabling->item(0)->nodeValue === 'true') { + $this->SLCdata['slcMode'] = TRUE; + $this->SLCdata['slcEntitlementAttributeName'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:entitlementAttr/@name")->item(0)->nodeValue; + $this->SLCdata['slcEntitlementAttributeValue'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:entitlementAttr")->item(0)->nodeValue; + $this->SLCdata['slcPortalDelegationURL'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:portalDelegationURL")->item(0)->nodeValue; + $this->SLCdata['slcNoDelegationURL'] = $xpath->query("/c:conf/c:authz[@instance='${authZinstance}']/c:SLCsupport/c:noDelegationURL")->item(0)->nodeValue; + } else { + $this->SLCdata['slcMode'] = FALSE; + } + // ----------------------------------------------------- // You'll need these services // ----------------------------------------------------- +// error_log("using rbacbase: " . $this->rbacbase); +// $this->soapExtra = new SoapClient( $this->rbacbase . "wsdl/tgextra.local.wsdl" ); +// $this->soapPolicy = new SoapClient( $this->rbacbase . "wsdl/tgsystem.local.wsdl" ); +// $this->soapReview = new SoapClient( $this->rbacbase . "wsdl/tgreview.local.wsdl" ); +// $this->soapAdministration = new SoapClient( $this->rbacbase . "wsdl/tgadministration.wsdl" ); + $this->soapExtra = new SoapClient( $this->rbacbase . "wsdl/tgextra.wsdl" ); $this->soapPolicy = new SoapClient( $this->rbacbase . "wsdl/tgsystem.wsdl" ); $this->soapReview = new SoapClient( $this->rbacbase . "wsdl/tgreview.wsdl" ); @@ -56,7 +86,13 @@ class RBAC { } + public function slcData() { + return $this->SLCdata; + } + public function createSession ( $remote_user ) { + + error_log("createSession calles for " . $remote_user); $rbachash = array("scstatus" => "", // will collect all messages during authentication "Sid" => "none", // this will hold the final sessionId then @@ -71,6 +107,11 @@ class RBAC { "user" => $matches[1], "scope" => $matches[2] ); + $identified_user['user'] = $this->escapeForDN ($identified_user['user']); + $identified_user['scope'] = $this->escapeForDN ($identified_user['scope']); + + $remote_user = $identified_user['user'] . "@" . $identified_user['scope']; + $rbachash["identified_user"] = $identified_user; $rbachash["remote_user"] = $remote_user; // TG User ID @@ -95,6 +136,8 @@ class RBAC { $serviceAuthReq->username = $this->sessionCreatorUid; $serviceAuthReq->password = $this->sessionCreatorPw; + error_log("r-bug: suid: " . $this->sessionCreatorUid); + try { $serviceAuthResponse = $this->soapExtra->authenticate( $serviceAuthReq ); @@ -104,7 +147,7 @@ class RBAC { } catch( SoapFault $f ) { return array("success" => FALSE, - "detail" => "SOAP FAULT (authenticate)!: " . $f->faultcode . " / " . $f->faultstring, + "detail" => "SOAP FAULT (authenticate)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail, "rbachash" => $rbachash); exit; } @@ -132,15 +175,54 @@ class RBAC { } catch( SoapFault $f ) { return array("success" => FALSE, "rbachash" => $rbachash, - "detail" => "SOAP FAULT (tgAddActiveRole)!: " . $f->faultcode . " / " . $f->faultstring); + "detail" => "SOAP FAULT (tgAddActiveRole)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail); exit; } // ----------------------------------------------------- // Check whether user exists already in RBAC // ----------------------------------------------------- - // ---> we do not need this anymore since users are in DARIAH + $userexistreq = new userExistsRequest(); + $userexistreq->auth = $serviceAuthResponse->auth; + $userexistreq->username = $remote_user; + try { + $existresult = $this->soapExtra->userExists($userexistreq); + if (! $existresult->result) { + + // ----------------------------------------------- + // User does not exist, so add 'em + $adduserrequest = new addUserRequest(); + $adduserrequest->intSid = $serviceAuthResponse->auth; + $adduserrequest->username = $remote_user; + $adduserrequest->password = "gnuelpfix"; // this is not relevant and will never be checked + + try { + $addedUser = $this->soapAdministration->addUser($adduserrequest); + if ($addedUser) { + $rbachash["scstatus"] .= "Added user information to authorization database; "; + } else { + return array("success" => FALSE, + "rbachash" => $rbachash, + "detail" => "Could not add your user ID to authorization database." ); + exit; + } + + } catch(SoapFault $f) { + return array("success" => FALSE, + "rbachash" => $rbachash, + "detail" => "SOAP FAULT (AddUser)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); + exit; + } + } else { + $rbachash["scstatus"] .= "user exists in authentication database; "; + } + } catch (SoapFault $f) { + return array("success" => FALSE, + "rbachash" => $rbachash, + "detail" => "SOAP FAULT (UserExists)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); + exit; + } // ----------------------------------------------------- // If this was successful you can create the session for remote_user @@ -165,6 +247,7 @@ class RBAC { $rbachash["scstatus"] .= "Received all available roles for user; "; } catch (Soapfault $f) { + //print_r($f->getTraceAsString()); return array("success" => FALSE, "rbachash" => $rbachash, "detail" => "SOAP FAULT (authorizedRoles)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->getTraceAsString()); @@ -218,7 +301,7 @@ class RBAC { } catch (SoapFault $f) { return array("success" => FALSE, "rbachash" => $rbachash, - "detail" => "SOAP FAULT (CreateSession)!: " . $f->faultcode . " / " . $f->faultstring); + "detail" => "SOAP FAULT (CreateSession)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); exit; } @@ -228,6 +311,84 @@ class RBAC { "rbachash" => $rbachash); } + // see RFC XYZ, DN Syntax + function escapeForDN ($string) { + return preg_replace('/[";+<>,\\\]/', "X", $string); + } + + function getUserAttributes ( $Sid ) { + $getMyUAR = new StdClass(); + $getMyUAR->auth = $Sid; + + try { + $ua = $this->soapExtra->getMyUserAttributes($getMyUAR); + $this->userAttributes = $ua->attribute; + return $ua->attribute; + } catch (SoapFault $f) { + return array("success" => FALSE, + "detail" => "SOAP FAULT (getMyUserAttributes)!: " . serialize ($f) ); + } + + } + + function enoughUserAttributes ( $Sid ) { + if (!isset($this->userAttributes)) { + $this->getUserAttributes( $Sid ); + } + // $file = fopen ("/tmp/xxxR.log", "w+"); + // fwrite ($file, serialize ($this->userAttributes ) ."\n"); + // fclose ($file); + + foreach ($this->userAttributes as $a) { + if ($a->name == "ToUversion" && $a->value != $this->ToUversion ) { + return FALSE; + } + if ($a->mandatory) { + if (!isset($a->value)) { + return FALSE; + } else { + if (is_string($a->value) && strlen($a->value) < 1) { + return FALSE; + } + } + } + } + + return TRUE; + } + + function updateAttributes ( $attrs, $map, $Sid ) { + $newattributes = array(); + foreach ($map as $name => $value) { + if (isset($attrs[$value])) { + $na = new StdClass(); + $na->name = $name; + $na->value = $attrs[$value]; + $newattributes[] = $na; + } + } + return $this->setAttributes ($newattributes, $Sid, TRUE); + } + + function setAttributes ( $attrs, $Sid, $loginmode ) { + $setMyUserAttributesRequest = new StdClass(); + $setMyUserAttributesRequest->attribute = $attrs; + $setMyUserAttributesRequest->auth = $Sid; + if ($loginmode) { + $setMyUserAttributesRequest->webAuthSecret = $this->setnamessecret; + } else { + $setMyUserAttributesRequest->webAuthSecret = ""; + } + + try { + $res = $this->soapExtra->setMyUserAttributes($setMyUserAttributesRequest); + return $res; + } catch (SoapFault $f) { + return array("success" => FALSE, + "detail" => "SOAP FAULT (setMyUserAttributes)!: " . $f->faultcode . " / " . $f->faultstring . " / " . $f->detail ); + } + } + } ?> -- GitLab