ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
sspmod_negotiate_Auth_Source_Negotiate Class Reference
+ Inheritance diagram for sspmod_negotiate_Auth_Source_Negotiate:
+ Collaboration diagram for sspmod_negotiate_Auth_Source_Negotiate:

Public Member Functions

 __construct ($info, $config)
 Constructor for this authentication source. More...
 
 authenticate (&$state)
 The inner workings of the module. More...
 
 spDisabledInMetadata ($spMetadata)
 
 checkMask ()
 checkMask() looks up the subnet config option and verifies that the client is within that range. More...
 
 logout (&$state)
 Log out from this authentication source. More...
 
- Public Member Functions inherited from SimpleSAML_Auth_Source
 __construct ($info, &$config)
 Constructor for an authentication source. More...
 
 getAuthId ()
 Retrieve the ID of this authentication source. More...
 
 authenticate (&$state)
 Process a request. More...
 
 reauthenticate (array &$state)
 Reauthenticate an user. More...
 
 initLogin ($return, $errorURL=null, array $params=array())
 Start authentication. More...
 
 logout (&$state)
 Log out from this authentication source. More...
 

Static Public Member Functions

static fallBack (&$state)
 Passes control of the login process to a different module. More...
 
- Static Public Member Functions inherited from SimpleSAML_Auth_Source
static getSourcesOfType ($type)
 Get sources of a specific type. More...
 
static completeAuth (&$state)
 Complete authentication. More...
 
static loginCompleted ($state)
 Called when a login operation has finished. More...
 
static completeLogout (&$state)
 Complete logout. More...
 
static getById ($authId, $type=null)
 Retrieve authentication source. More...
 
static logoutCallback ($state)
 Called when the authentication source receives an external logout request. More...
 
static getSources ()
 Retrieve list of authentication sources. More...
 

Data Fields

const STAGEID = 'sspmod_negotiate_Auth_Source_Negotiate.StageId'
 

Protected Member Functions

 sendNegotiate ($params)
 Send the actual headers and body of the 401. More...
 
 lookupUserData ($user)
 Strips away the realm of the Kerberos identifier, looks up what attributes to fetch from SP metadata and searches the directory. More...
 
 adminBind ()
 Elevates the LDAP connection to allow restricted lookups if so configured. More...
 
- Protected Member Functions inherited from SimpleSAML_Auth_Source
 addLogoutCallback ($assoc, $state)
 Add a logout callback association. More...
 
 callLogoutCallback ($assoc)
 Call a logout callback based on association. More...
 

Protected Attributes

 $ldap = null
 
 $backend = ''
 
 $hostname = ''
 
 $port = 389
 
 $referrals = true
 
 $enableTLS = false
 
 $debugLDAP = false
 
 $timeout = 30
 
 $keytab = ''
 
 $base = array()
 
 $attr = 'uid'
 
 $subnet = null
 
 $admin_user = null
 
 $admin_pw = null
 
 $attributes = null
 
- Protected Attributes inherited from SimpleSAML_Auth_Source
 $authId
 

Additional Inherited Members

- Static Protected Member Functions inherited from SimpleSAML_Auth_Source
static validateSource ($source, $id)
 Make sure that the first element of an auth source is its identifier. More...
 

Detailed Description

Definition at line 10 of file Negotiate.php.

Constructor & Destructor Documentation

◆ __construct()

sspmod_negotiate_Auth_Source_Negotiate::__construct (   $info,
  $config 
)

Constructor for this authentication source.

Parameters
array$infoInformation about this authentication source.
array$configThe configuration of the module
Exceptions
ExceptionIf the KRB5 extension is not installed or active.

Definition at line 41 of file Negotiate.php.

References $config, $info, base(), and SimpleSAML_Configuration\loadFromArray().

42  {
43  assert(is_array($info));
44  assert(is_array($config));
45 
46  if (!extension_loaded('krb5')) {
47  throw new Exception('KRB5 Extension not installed');
48  }
49 
50  // call the parent constructor first, as required by the interface
51  parent::__construct($info, $config);
52 
54 
55  $this->backend = $config->getString('fallback');
56  $this->hostname = $config->getString('hostname');
57  $this->port = $config->getInteger('port', 389);
58  $this->referrals = $config->getBoolean('referrals', true);
59  $this->enableTLS = $config->getBoolean('enable_tls', false);
60  $this->debugLDAP = $config->getBoolean('debugLDAP', false);
61  $this->timeout = $config->getInteger('timeout', 30);
62  $this->keytab = $config->getString('keytab');
63  $this->base = $config->getArrayizeString('base');
64  $this->attr = $config->getString('attr', 'uid');
65  $this->subnet = $config->getArray('subnet', null);
66  $this->admin_user = $config->getString('adminUser', null);
67  $this->admin_pw = $config->getString('adminPassword', null);
68  $this->attributes = $config->getArray('attributes', null);
69  }
$config
Definition: bootstrap.php:15
base()
Definition: base.php:2
$info
Definition: index.php:5
static loadFromArray($config, $location='[ARRAY]', $instance=null)
Loads a configuration from the given array.
+ Here is the call graph for this function:

Member Function Documentation

◆ adminBind()

sspmod_negotiate_Auth_Source_Negotiate::adminBind ( )
protected

Elevates the LDAP connection to allow restricted lookups if so configured.

Does nothing if not.

Definition at line 323 of file Negotiate.php.

References SimpleSAML\Logger\debug(), and SimpleSAML\Logger\error().

Referenced by lookupUserData().

324  {
325  if ($this->admin_user === null) {
326  // no admin user
327  return;
328  }
330  'Negotiate - authenticate(): Binding as system user '.var_export($this->admin_user, true)
331  );
332 
333  if (!$this->ldap->bind($this->admin_user, $this->admin_pw)) {
334  $msg = 'Unable to authenticate system user (LDAP_INVALID_CREDENTIALS) '.var_export($this->admin_user, true);
335  SimpleSAML\Logger::error('Negotiate - authenticate(): '.$msg);
336  throw new SimpleSAML_Error_AuthSource('negotiate', $msg);
337  }
338  }
static debug($string)
Definition: Logger.php:211
static error($string)
Definition: Logger.php:166
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ authenticate()

sspmod_negotiate_Auth_Source_Negotiate::authenticate ( $state)

The inner workings of the module.

Checks to see if client is in the defined subnets (if defined in config). Sends the client a 401 Negotiate and responds to the result. If the client fails to provide a proper Kerberos ticket, the login process is handed over to the 'fallback' module defined in the config.

LDAP is used as a user metadata source.

Parameters
array&$stateInformation about the current authentication.

Definition at line 83 of file Negotiate.php.

References $_COOKIE, $_SERVER, $auth, SimpleSAML_Auth_Source\$authId, $id, $mask, PHPMailer\PHPMailer\$params, $session, $state, $user, checkMask(), SimpleSAML_Auth_Source\completeAuth(), SimpleSAML\Logger\debug(), SimpleSAML\Logger\error(), exit, fallBack(), SimpleSAML_Session\getSessionFromRequest(), SimpleSAML\Logger\info(), lookupUserData(), SimpleSAML_Auth_State\saveState(), sendNegotiate(), and spDisabledInMetadata().

84  {
85  assert(is_array($state));
86 
87  // set the default backend to config
88  $state['LogoutState'] = array(
89  'negotiate:backend' => $this->backend,
90  );
91  $state['negotiate:authId'] = $this->authId;
92 
93 
94  // check for disabled SPs. The disable flag is store in the SP metadata
95  if (array_key_exists('SPMetadata', $state) && $this->spDisabledInMetadata($state['SPMetadata'])) {
96  $this->fallBack($state);
97  }
98  /* Go straight to fallback if Negotiate is disabled or if you are sent back to the IdP directly from the SP
99  after having logged out. */
101  $disabled = $session->getData('negotiate:disable', 'session');
102 
103  if ($disabled ||
104  (!empty($_COOKIE['NEGOTIATE_AUTOLOGIN_DISABLE_PERMANENT']) &&
105  $_COOKIE['NEGOTIATE_AUTOLOGIN_DISABLE_PERMANENT'] == 'True')
106  ) {
107  SimpleSAML\Logger::debug('Negotiate - session disabled. falling back');
108  $this->fallBack($state);
109  // never executed
110  assert(false);
111  }
112  $mask = $this->checkMask();
113  if (!$mask) {
114  $this->fallBack($state);
115  // never executed
116  assert(false);
117  }
118 
119  SimpleSAML\Logger::debug('Negotiate - authenticate(): looking for Negotiate');
120  if (!empty($_SERVER['HTTP_AUTHORIZATION'])) {
121  SimpleSAML\Logger::debug('Negotiate - authenticate(): Negotiate found');
122  $this->ldap = new SimpleSAML_Auth_LDAP(
123  $this->hostname,
124  $this->enableTLS,
125  $this->debugLDAP,
126  $this->timeout,
127  $this->port,
128  $this->referrals
129  );
130 
131  list($mech,) = explode(' ', $_SERVER['HTTP_AUTHORIZATION'], 2);
132  if (strtolower($mech) == 'basic') {
133  SimpleSAML\Logger::debug('Negotiate - authenticate(): Basic found. Skipping.');
134  } else {
135  if (strtolower($mech) != 'negotiate') {
136  SimpleSAML\Logger::debug('Negotiate - authenticate(): No "Negotiate" found. Skipping.');
137  }
138  }
139 
140  $auth = new KRB5NegotiateAuth($this->keytab);
141  // attempt Kerberos authentication
142  try {
143  $reply = $auth->doAuthentication();
144  } catch (Exception $e) {
145  SimpleSAML\Logger::error('Negotiate - authenticate(): doAuthentication() exception: '.$e->getMessage());
146  $reply = null;
147  }
148 
149  if ($reply) {
150  // success! krb TGS received
151  $user = $auth->getAuthenticatedUser();
152  SimpleSAML\Logger::info('Negotiate - authenticate(): '.$user.' authenticated.');
153  $lookup = $this->lookupUserData($user);
154  if ($lookup !== null) {
155  $state['Attributes'] = $lookup;
156  // Override the backend so logout will know what to look for
157  $state['LogoutState'] = array(
158  'negotiate:backend' => null,
159  );
160  SimpleSAML\Logger::info('Negotiate - authenticate(): '.$user.' authorized.');
162  // Never reached.
163  assert(false);
164  }
165  } else {
166  // Some error in the received ticket. Expired?
167  SimpleSAML\Logger::info('Negotiate - authenticate(): Kerberos authN failed. Skipping.');
168  }
169  } else {
170  // No auth token. Send it.
171  SimpleSAML\Logger::debug('Negotiate - authenticate(): Sending Negotiate.');
172  // Save the $state array, so that we can restore if after a redirect
173  SimpleSAML\Logger::debug('Negotiate - fallback: '.$state['LogoutState']['negotiate:backend']);
174  $id = SimpleSAML_Auth_State::saveState($state, self::STAGEID);
175  $params = array('AuthState' => $id);
176 
177  $this->sendNegotiate($params);
178  exit;
179  }
180 
181  SimpleSAML\Logger::info('Negotiate - authenticate(): Client failed Negotiate. Falling back');
182  $this->fallBack($state);
183  /* The previous function never returns, so this code is never
184  executed */
185  assert(false);
186  }
$_COOKIE['client_id']
Definition: server.php:9
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
static debug($string)
Definition: Logger.php:211
$session
if(!array_key_exists('StateId', $_REQUEST)) $id
$auth
Definition: fileserver.php:48
sendNegotiate($params)
Send the actual headers and body of the 401.
Definition: Negotiate.php:238
lookupUserData($user)
Strips away the realm of the Kerberos identifier, looks up what attributes to fetch from SP metadata ...
Definition: Negotiate.php:299
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
static info($string)
Definition: Logger.php:199
$mask
Definition: example_042.php:90
static error($string)
Definition: Logger.php:166
$user
Definition: migrateto20.php:57
exit
Definition: backend.php:16
static completeAuth(&$state)
Complete authentication.
Definition: Source.php:136
checkMask()
checkMask() looks up the subnet config option and verifies that the client is within that range...
Definition: Negotiate.php:213
static getSessionFromRequest()
Retrieves the current session.
Definition: Session.php:241
static saveState(&$state, $stage, $rawId=false)
Save the state.
Definition: State.php:194
static fallBack(&$state)
Passes control of the login process to a different module.
Definition: Negotiate.php:268
+ Here is the call graph for this function:

◆ checkMask()

sspmod_negotiate_Auth_Source_Negotiate::checkMask ( )

checkMask() looks up the subnet config option and verifies that the client is within that range.

Will return TRUE if no subnet option is configured.

Returns
boolean

Definition at line 213 of file Negotiate.php.

References $_SERVER, $ret, SimpleSAML\Logger\debug(), and SimpleSAML\Utils\Net\ipCIDRcheck().

Referenced by authenticate().

214  {
215  // No subnet means all clients are accepted.
216  if ($this->subnet === null) {
217  return true;
218  }
219  $ip = $_SERVER['REMOTE_ADDR'];
220  foreach ($this->subnet as $cidr) {
222  if ($ret) {
223  SimpleSAML\Logger::debug('Negotiate: Client "'.$ip.'" matched subnet.');
224  return true;
225  }
226  }
227  SimpleSAML\Logger::debug('Negotiate: Client "'.$ip.'" did not match subnet.');
228  return false;
229  }
if((!isset($_SERVER['DOCUMENT_ROOT'])) OR(empty($_SERVER['DOCUMENT_ROOT']))) $_SERVER['DOCUMENT_ROOT']
static debug($string)
Definition: Logger.php:211
static ipCIDRcheck($cidr, $ip=null)
Check whether an IP address is part of a CIDR.
Definition: Net.php:26
$ret
Definition: parser.php:6
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ fallBack()

static sspmod_negotiate_Auth_Source_Negotiate::fallBack ( $state)
static

Passes control of the login process to a different module.

Parameters
array$stateInformation about the current authentication.
Exceptions
SimpleSAML_Error_ErrorIf couldn't determine the auth source.
SimpleSAML_Error_Exception
Exception

Definition at line 268 of file Negotiate.php.

References SimpleSAML_Auth_Source\$authId, $source, $state, SimpleSAML\Logger\debug(), SimpleSAML_Auth_Source\getById(), and SimpleSAML_Auth_State\throwException().

Referenced by authenticate().

269  {
270  $authId = $state['LogoutState']['negotiate:backend'];
271 
272  if ($authId === null) {
273  throw new SimpleSAML_Error_Error(array(500, "Unable to determine auth source."));
274  }
276 
277  try {
278  $source->authenticate($state);
279  } catch (SimpleSAML_Error_Exception $e) {
281  } catch (Exception $e) {
284  }
285  // fallBack never returns after loginCompleted()
286  SimpleSAML\Logger::debug('Negotiate: backend returned');
287  self::loginCompleted($state);
288  }
static throwException($state, SimpleSAML_Error_Exception $exception)
Throw exception to the state exception handler.
Definition: State.php:343
static debug($string)
Definition: Logger.php:211
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
$source
Definition: linkback.php:22
static getById($authId, $type=null)
Retrieve authentication source.
Definition: Source.php:340
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ logout()

sspmod_negotiate_Auth_Source_Negotiate::logout ( $state)

Log out from this authentication source.

This method either logs the user out from Negotiate or passes the logout call to the fallback module.

Parameters
array&$stateInformation about the current logout operation.

Definition at line 349 of file Negotiate.php.

References SimpleSAML_Auth_Source\$authId, $session, $source, $state, SimpleSAML\Logger\debug(), SimpleSAML_Auth_Source\getById(), and SimpleSAML_Session\getSessionFromRequest().

350  {
351  assert(is_array($state));
352  // get the source that was used to authenticate
353  $authId = $state['negotiate:backend'];
354  SimpleSAML\Logger::debug('Negotiate - logout has the following authId: "'.$authId.'"');
355 
356  if ($authId === null) {
358  $session->setData('negotiate:disable', 'session', true, 24 * 60 * 60);
359  parent::logout($state);
360  } else {
362  $source->logout($state);
363  }
364  }
static debug($string)
Definition: Logger.php:211
$session
if(!array_key_exists('stateid', $_REQUEST)) $state
Handle linkback() response from LinkedIn.
Definition: linkback.php:10
$source
Definition: linkback.php:22
static getById($authId, $type=null)
Retrieve authentication source.
Definition: Source.php:340
static getSessionFromRequest()
Retrieves the current session.
Definition: Session.php:241
+ Here is the call graph for this function:

◆ lookupUserData()

sspmod_negotiate_Auth_Source_Negotiate::lookupUserData (   $user)
protected

Strips away the realm of the Kerberos identifier, looks up what attributes to fetch from SP metadata and searches the directory.

Parameters
string$userThe Kerberos user identifier.
Returns
string The DN to the user or NULL if not found.

Definition at line 299 of file Negotiate.php.

References $user, adminBind(), base(), and SimpleSAML\Logger\debug().

Referenced by authenticate().

300  {
301  // Kerberos user names include realm. Strip that away.
302  $pos = strpos($user, '@');
303  if ($pos === false) {
304  return null;
305  }
306  $uid = substr($user, 0, $pos);
307 
308  $this->adminBind();
309  try {
310  $dn = $this->ldap->searchfordn($this->base, $this->attr, $uid);
311  return $this->ldap->getAttributes($dn, $this->attributes);
312  } catch (SimpleSAML_Error_Exception $e) {
313  SimpleSAML\Logger::debug('Negotiate - ldap lookup failed: '.$e);
314  return null;
315  }
316  }
static debug($string)
Definition: Logger.php:211
base()
Definition: base.php:2
$user
Definition: migrateto20.php:57
adminBind()
Elevates the LDAP connection to allow restricted lookups if so configured.
Definition: Negotiate.php:323
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ sendNegotiate()

sspmod_negotiate_Auth_Source_Negotiate::sendNegotiate (   $params)
protected

Send the actual headers and body of the 401.

Embedded in the body is a post that is triggered by JS if the client wants to show the 401 message.

Parameters
array$paramsadditional parameters to the URL in the URL in the body.

Definition at line 238 of file Negotiate.php.

References PHPMailer\PHPMailer\$params, $url, EOF, and html().

Referenced by authenticate().

239  {
240  $url = htmlspecialchars(SimpleSAML\Module::getModuleURL('negotiate/backend.php', $params));
241  $json_url = json_encode($url);
242 
243  header('HTTP/1.1 401 Unauthorized');
244  header('WWW-Authenticate: Negotiate', false);
245  echo <<<EOF
246 <html>
247  <head>
248  <script type="text/javascript">window.location = $json_url</script>
249  <title>Redirect to login</title>
250  </head>
251 <body>
252  <p>Your browser seems to have Javascript disabled. Please click <a href="$url">here</a>.</p>
253 </body>
254 </html>
255 EOF;
256  }
Attribute-related utility methods.
html()
$url
const EOF
How fgetc() reports an End Of File.
Definition: JSMin_lib.php:92
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

◆ spDisabledInMetadata()

sspmod_negotiate_Auth_Source_Negotiate::spDisabledInMetadata (   $spMetadata)

Definition at line 189 of file Negotiate.php.

References $spMetadata, and SimpleSAML\Logger\debug().

Referenced by authenticate().

190  {
191  if (array_key_exists('negotiate:disable', $spMetadata)) {
192  if ($spMetadata['negotiate:disable'] == true) {
193  SimpleSAML\Logger::debug('Negotiate - SP disabled. falling back');
194  return true;
195  } else {
196  SimpleSAML\Logger::debug('Negotiate - SP disable flag found but set to FALSE');
197  }
198  } else {
199  SimpleSAML\Logger::debug('Negotiate - SP disable flag not found');
200  }
201  return false;
202  }
static debug($string)
Definition: Logger.php:211
$spMetadata
+ Here is the call graph for this function:
+ Here is the caller graph for this function:

Field Documentation

◆ $admin_pw

sspmod_negotiate_Auth_Source_Negotiate::$admin_pw = null
protected

Definition at line 29 of file Negotiate.php.

◆ $admin_user

sspmod_negotiate_Auth_Source_Negotiate::$admin_user = null
protected

Definition at line 28 of file Negotiate.php.

◆ $attr

sspmod_negotiate_Auth_Source_Negotiate::$attr = 'uid'
protected

Definition at line 26 of file Negotiate.php.

◆ $attributes

sspmod_negotiate_Auth_Source_Negotiate::$attributes = null
protected

Definition at line 30 of file Negotiate.php.

◆ $backend

sspmod_negotiate_Auth_Source_Negotiate::$backend = ''
protected

Definition at line 17 of file Negotiate.php.

◆ $base

sspmod_negotiate_Auth_Source_Negotiate::$base = array()
protected

Definition at line 25 of file Negotiate.php.

◆ $debugLDAP

sspmod_negotiate_Auth_Source_Negotiate::$debugLDAP = false
protected

Definition at line 22 of file Negotiate.php.

◆ $enableTLS

sspmod_negotiate_Auth_Source_Negotiate::$enableTLS = false
protected

Definition at line 21 of file Negotiate.php.

◆ $hostname

sspmod_negotiate_Auth_Source_Negotiate::$hostname = ''
protected

Definition at line 18 of file Negotiate.php.

◆ $keytab

sspmod_negotiate_Auth_Source_Negotiate::$keytab = ''
protected

Definition at line 24 of file Negotiate.php.

◆ $ldap

sspmod_negotiate_Auth_Source_Negotiate::$ldap = null
protected

Definition at line 16 of file Negotiate.php.

◆ $port

sspmod_negotiate_Auth_Source_Negotiate::$port = 389
protected

Definition at line 19 of file Negotiate.php.

◆ $referrals

sspmod_negotiate_Auth_Source_Negotiate::$referrals = true
protected

Definition at line 20 of file Negotiate.php.

◆ $subnet

sspmod_negotiate_Auth_Source_Negotiate::$subnet = null
protected

Definition at line 27 of file Negotiate.php.

◆ $timeout

sspmod_negotiate_Auth_Source_Negotiate::$timeout = 30
protected

Definition at line 23 of file Negotiate.php.

◆ STAGEID

const sspmod_negotiate_Auth_Source_Negotiate::STAGEID = 'sspmod_negotiate_Auth_Source_Negotiate.StageId'

Definition at line 14 of file Negotiate.php.


The documentation for this class was generated from the following file: