/** * Construct * * @param array $authSourceconfig Configuration array for the selected authsource * @param array $ldapWriteConfig Configuration array for the selected catalogue backend * @param array $attributes The user attributes to be saved */ public function __construct($authSourceConfig, $ldapWriteConfig, $attributes) { $asc = SimpleSAML_Configuration::loadFromArray($authSourceConfig); parent::__construct($asc->getString('hostname'), $asc->getBoolean('enable_tls', FALSE), $asc->getBoolean('debug', FALSE), $asc->getInteger('timeout', 0)); $this->searchBase = $asc->getArrayize('search.base'); $this->dnPattern = $asc->getString('dnpattern'); $this->searchDn = $asc->getString('search.username', NULL); $this->searchPw = $asc->getString('search.password', NULL); $lwc = SimpleSAML_Configuration::loadFromArray($ldapWriteConfig); $this->adminDn = $lwc->getString('admin.dn'); $this->adminPw = $lwc->getString('admin.pw'); $this->objectClass = $lwc->getArray('objectClass'); $this->userIdAttr = $lwc->getString('user.id.param', 'uid'); $this->pswEncrypt = $lwc->getString('psw.encrypt', 'sha1'); $this->attributes = $attributes; }
if (!array_key_exists('RelayState', $_REQUEST)) { SimpleSAML_Utilities::fatalError($session->getTrackID(), 'NORELAYSTATE'); } if (isset($_POST['username'])) { try { $ldapconfig = $ldapmulti[$_POST['org']]; if ($ldapconfig['search.enable'] === TRUE) { if (!$ldap->bind($ldapconfig['search.username'], $ldapconfig['search.password'])) { throw new Exception('Error authenticating using search username & password.'); } $dn = $ldap->searchfordn($ldapconfig['search.base'], $ldapconfig['search.attributes'], $_POST['username']); } else { $dn = str_replace('%username%', $_POST['username'], $ldapconfig['dnpattern']); } $pwd = $_POST['password']; $ldap = new SimpleSAML_Auth_LDAP($ldapconfig['hostname'], $ldapconfig['enable_tls']); if ($pwd == "" or !$ldap->bind($dn, $pwd)) { SimpleSAML_Logger::info('AUTH - ldap-multi: ' . $_POST['username'] . ' failed to authenticate. DN=' . $dn); throw new Exception('Wrong username or password'); } $attributes = $ldap->getAttributes($dn, $ldapconfig['attributes']); SimpleSAML_Logger::info('AUTH - ldap-multi: ' . $_POST['username'] . ' successfully authenticated'); $session->doLogin('login-ldapmulti'); $session->setAttributes($attributes); $session->setNameID(array('value' => SimpleSAML_Utilities::generateID(), 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient')); /** * Create a statistics log entry for every successfull login attempt. * Also log a specific attribute as set in the config: statistics.authlogattr */ $authlogattr = $config->getValue('statistics.authlogattr', null); if ($authlogattr && array_key_exists($authlogattr, $attributes)) {
} $ldapconfig = $casldapconfig[$idpentityid]['ldap']; } catch (Exception $exception) { throw new SimpleSAML_Error_Error('METADATA', $exception); } /* * Load the RelayState argument. The RelayState argument contains the address * we should redirect the user to after a successful authentication. */ if (!array_key_exists('RelayState', $_REQUEST)) { throw new SimpleSAML_Error_Error('NORELAYSTATE'); } $relaystate = SimpleSAML_Utilities::checkURLAllowed($_REQUEST['RelayState']); if ($username = $_POST['username']) { try { $ldap = new SimpleSAML_Auth_LDAP($ldapconfig['servers'], $ldapconfig['enable_tls']); $attributes = $ldap->validate($ldapconfig, $username, $_POST['password']); if ($attributes === FALSE) { $error = "LDAP_INVALID_CREDENTIALS"; } else { $session->doLogin('login-wayf-ldap'); $session->setAttributes($attributes); $session->setNameID(array('value' => SimpleSAML_Utilities::generateID(), 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient')); SimpleSAML_Utilities::redirectTrustedURL($relaystate); } } catch (Exception $e) { throw new SimpleSAML_Error_Error('LDAPERROR', $e); } } $t = new SimpleSAML_XHTML_Template($config, $ldapconfig['template']); $t->data['header'] = 'simpleSAMLphp: Enter username and password';
/** * Add attributes from an LDAP server. * * @param array &$request The current request */ public function process(&$request) { assert('is_array($request)'); assert('array_key_exists("Attributes", $request)'); $attributes =& $request['Attributes']; // perform a merge on the ldap_search_filter // loop over the attributes and build the search and replace arrays foreach ($attributes as $attr => $val) { $arrSearch[] = '%' . $attr . '%'; if (strlen($val[0]) > 0) { $arrReplace[] = SimpleSAML_Auth_LDAP::escape_filter_value($val[0]); } else { $arrReplace[] = ''; } } // merge the attributes into the ldap_search_filter $filter = str_replace($arrSearch, $arrReplace, $this->search_filter); if (strpos($filter, '%') !== FALSE) { SimpleSAML_Logger::info('AttributeAddFromLDAP: There are non-existing attributes in the search filter. (' . $this->search_filter . ')'); return; } if (!in_array($this->attr_policy, array('merge', 'replace', 'add'))) { SimpleSAML_Logger::warning("AttributeAddFromLDAP: 'attribute.policy' must be one of 'merge'," . "'replace' or 'add'."); return; } // search for matching entries try { $entries = $this->getLdap()->searchformultiple($this->base_dn, $filter, array_values($this->search_attributes), TRUE, FALSE); } catch (Exception $e) { return; // silent fail, error is still logged by LDAP search } // handle [multiple] values foreach ($entries as $entry) { foreach ($this->search_attributes as $target => $name) { if (is_numeric($target)) { $target = $name; } if (isset($attributes[$target]) && $this->attr_policy === 'replace') { unset($attributes[$target]); } $name = strtolower($name); if (isset($entry[$name])) { unset($entry[$name]['count']); if (isset($attributes[$target])) { foreach (array_values($entry[$name]) as $value) { if ($this->attr_policy === 'merge') { if (!in_array($value, $attributes[$target])) { $attributes[$target][] = $value; } } else { $attributes[$target][] = $value; } } } else { $attributes[$target] = array_values($entry[$name]); } } } } }
public function getAttributes($dn, $attributes = NULL) { if ($attributes == NULL) { $attributes = $this->attributes; } $ldap = new SimpleSAML_Auth_LDAP($this->hostname, $this->enableTLS, $this->debug, $this->timeout, $this->port, $this->referrals); /* Are privs needed to get the attributes? */ if ($this->privRead) { /* Yes, rebind with privs */ if (!$ldap->bind($this->privUsername, $this->privPassword)) { throw new Exception('Error authenticating using privileged DN & password.'); } } return $ldap->getAttributes($dn, $attributes); }
} $casusername = $success->item(0)->textContent; return array($casusername, $attributes); } } else { throw new Exception("validate or serviceValidate not specified"); } /** * First request, will redirect the user to the CAS server for authentication. */ } else { SimpleSAML_Logger::info("AUTH - cas-ldap: redirecting to {$cas['login']}"); SimpleSAML_Utilities::redirectTrustedURL($cas['login'], array('service' => $service)); } } try { list($username, $casattributes) = casValidate($casconfig); SimpleSAML_Logger::info('AUTH - cas-ldap: ' . $username . ' authenticated by ' . $casconfig['validate']); $ldapattributes = array(); if ($ldapconfig['servers']) { $ldap = new SimpleSAML_Auth_LDAP($ldapconfig['servers'], $ldapconfig['enable_tls']); $ldapattributes = $ldap->validate($ldapconfig, $username); } $attributes = array_merge_recursive($casattributes, $ldapattributes); $session->doLogin('login-cas-ldap'); $session->setAttributes($attributes); $session->setNameID(array('value' => SimpleSAML_Utilities::generateID(), 'Format' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient')); SimpleSAML_Utilities::redirectUntrustedURL($_REQUEST['RelayState']); } catch (Exception $exception) { throw new SimpleSAML_Error_Error('CASERROR', $exception); }
public function getAttributes($dn, $attributes = NULL) { if ($attributes == NULL) { $attributes = $this->attributes; } $ldap = new SimpleSAML_Auth_LDAP($this->hostname, $this->enableTLS, $this->debug, $this->timeout); return $ldap->getAttributes($dn, $attributes); }
/** * Attempt to log in using the given username and password. * * Will throw a SimpleSAML_Error_Error('WRONGUSERPASS') if the username or password is wrong. * If there is a configuration problem, an Exception will be thrown. * * @param string $username The username the user wrote. * @param string $password The password the user wrote. * @param arrray $sasl_args Array of SASL options for LDAP bind. * @return array Associative array with the users attributes. */ public function login($username, $password, array $sasl_args = NULL) { assert('is_string($username)'); assert('is_string($password)'); if (empty($password)) { SimpleSAML_Logger::info($this->location . ': Login with empty password disallowed.'); throw new SimpleSAML_Error_Error('WRONGUSERPASS'); } $ldap = new SimpleSAML_Auth_LDAP($this->hostname, $this->enableTLS, $this->debug, $this->timeout, $this->port, $this->referrals); if (!$this->searchEnable) { $ldapusername = addcslashes($username, ',+"\\<>;*'); $dn = str_replace('%username%', $ldapusername, $this->dnPattern); } else { if ($this->searchUsername !== NULL) { if (!$ldap->bind($this->searchUsername, $this->searchPassword)) { throw new Exception('Error authenticating using search username & password.'); } } $dn = $ldap->searchfordn($this->searchBase, $this->searchAttributes, $username, TRUE); if ($dn === NULL) { /* User not found with search. */ SimpleSAML_Logger::info($this->location . ': Unable to find users DN. username=\'' . $username . '\''); throw new SimpleSAML_Error_Error('WRONGUSERPASS'); } } $qaLogin = SimpleSAML_Auth_Source::getById('auth2factor'); if (!$ldap->bind($dn, $password, $sasl_args)) { SimpleSAML_Logger::info($this->location . ': ' . $username . ' failed to authenticate. DN=' . $dn); /* Account lockout feature */ // we need mail attributes so that we can notify user of locked account $attributes = $ldap->getAttributes($dn, $this->searchAttributes); // TODO what if these attributes are not available for search or not set in config? $qaLogin->failedLoginAttempt($username, 'login_count', array('name' => $attributes['givenName'][0], 'mail' => $attributes['mail'][0], 'uid' => $attributes['uid'][0])); $failedAttempts = $qaLogin->getFailedAttempts($username); $loginCount = (int) (!empty($failedAttempts)) ? $failedAttempts[0]['login_count'] : 0; $answerCount = (int) (!empty($failedAttempts)) ? $failedAttempts[0]['answer_count'] : 0; $failCount = $loginCount + $answerCount; // TODO this is bad! what if maxFailLogin is not set (i.e 0) or less than 3? instant lock? $firstFailCount = $qaLogin->getmaxFailLogin() - 2; $secondFailCount = $qaLogin->getmaxFailLogin() - 1; if ($failCount == $firstFailCount) { throw new SimpleSAML_Error_Error('2FAILEDATTEMPTWARNING'); } if ($failCount == $secondFailCount) { throw new SimpleSAML_Error_Error('1FAILEDATTEMPTWARNING'); } if ($qaLogin->isLocked($username)) { throw new SimpleSAML_Error_Error('ACCOUNTLOCKED'); } throw new SimpleSAML_Error_Error('WRONGUSERPASS'); } /* In case of SASL bind, authenticated and authorized DN may differ */ if (isset($sasl_args)) { $dn = $ldap->whoami($this->searchBase, $this->searchAttributes); } /* Are privs needed to get the attributes? */ if ($this->privRead) { /* Yes, rebind with privs */ if (!$ldap->bind($this->privUsername, $this->privPassword)) { throw new Exception('Error authenticating using privileged DN & password.'); } } // if we are here - we must have logged in successfully .. therefore reset login attempts $qaLogin->resetFailedLoginAttempts($username, 'login_count'); return $ldap->getAttributes($dn, $this->attributes); }
/** * Called by linkback, to finish validate/ finish logging in. * @param state $state * @return list username, casattributes/ldap attributes */ public function finalStep(&$state) { $ticket = $state['cas:ticket']; $stateID = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT); $service = SimpleSAML_Module::getModuleURL('cas/linkback.php', array('stateID' => $stateID)); list($username, $casattributes) = $this->casValidation($ticket, $service); $ldapattributes = array(); if ($this->_ldapConfig['servers']) { $ldap = new SimpleSAML_Auth_LDAP($this->_ldapConfig['servers'], $this->_ldapConfig['enable_tls']); $ldapattributes = $ldap->validate($this->_ldapConfig, $username); } $attributes = array_merge_recursive($casattributes, $ldapattributes); $state['Attributes'] = $attributes; SimpleSAML_Auth_Source::completeAuth($state); }
/** * Attempt to log in using the given username and password. * * Will throw a SimpleSAML_Error_Error('WRONGUSERPASS') if the username or password is wrong. * If there is a configuration problem, an Exception will be thrown. * * @param string $username The username the user wrote. * @param string $password The password the user wrote. * @param arrray $sasl_args Array of SASL options for LDAP bind. * @return array Associative array with the users attributes. */ public function login($username, $password, array $sasl_args = NULL) { assert('is_string($username)'); assert('is_string($password)'); if (empty($password)) { SimpleSAML_Logger::info($this->location . ': Login with empty password disallowed.'); throw new SimpleSAML_Error_Error('WRONGUSERPASS'); } $ldap = new SimpleSAML_Auth_LDAP($this->hostname, $this->enableTLS, $this->debug, $this->timeout); if (!$this->searchEnable) { $ldapusername = addcslashes($username, ',+"\\<>;*'); $dn = str_replace('%username%', $ldapusername, $this->dnPattern); } else { if ($this->searchUsername !== NULL) { if (!$ldap->bind($this->searchUsername, $this->searchPassword)) { throw new Exception('Error authenticating using search username & password.'); } } $dn = $ldap->searchfordn($this->searchBase, $this->searchAttributes, $username, TRUE); if ($dn === NULL) { /* User not found with search. */ SimpleSAML_Logger::info($this->location . ': Unable to find users DN. username=\'' . $username . '\''); throw new SimpleSAML_Error_Error('WRONGUSERPASS'); } } if (!$ldap->bind($dn, $password, $sasl_args)) { SimpleSAML_Logger::info($this->location . ': ' . $username . ' failed to authenticate. DN=' . $dn); throw new SimpleSAML_Error_Error('WRONGUSERPASS'); } /* In case of SASL bind, authenticated and authorized DN may differ */ if (isset($sasl_args)) { $dn = $ldap->whoami($this->searchBase, $this->searchAttributes); } /* Are privs needed to get the attributes? */ if ($this->privRead) { /* Yes, rebind with privs */ if (!$ldap->bind($this->privUsername, $this->privPassword)) { throw new Exception('Error authenticating using privileged DN & password.'); } } return $ldap->getAttributes($dn, $this->attributes); }
if (!array_key_exists('password', $_POST)) { $error = 'error_nopassword'; continue; } $username = $_POST['username']; $password = $_POST['password']; /* Escape any characters with a special meaning in LDAP. The following * characters have a special meaning (according to RFC 2253): * ',', '+', '"', '\', '<', '>', ';', '*' * These characters are escaped by prefixing them with '\'. */ $ldapusername = addcslashes($username, ',+"\\<>;*'); /* * Connecting to LDAP. */ $ldap = new SimpleSAML_Auth_LDAP($ldapconfig->getValue('auth.ldap.hostname'), $ldapconfig->getValue('auth.ldap.enable_tls')); if ($ldapconfig->getValue('auth.ldap.search.enable', FALSE)) { /* We are configured to search for the users dn. */ $searchUsername = $ldapconfig->getValue('auth.ldap.search.username', NULL); if ($searchUsername !== NULL) { /* Log in with username & password for searching. */ $searchPassword = $ldapconfig->getValue('auth.ldap.search.password', NULL); if ($searchPassword === NULL) { throw new Exception('"auth.ldap.search.username" is configured, but not' . ' "auth.ldap.search.password".'); } if (!$ldap->bind($searchUsername, $searchPassword)) { throw new Exception('Error authenticating using search username & password.'); } } $searchBase = $ldapconfig->getValue('auth.ldap.search.base', NULL); $searchAttributes = $ldapconfig->getValue('auth.ldap.search.attributes', NULL);
/** * Add attributes from an LDAP server. * * @param array &$request The current request */ public function process(&$request) { assert('is_array($request)'); assert('array_key_exists("Attributes", $request)'); $attributes =& $request['Attributes']; $map =& $this->attribute_map; if (!isset($attributes[$map['username']])) { throw new Exception('The user\'s identity does not have an attribute called "' . $map['username'] . '"'); } // perform a merge on the ldap_search_filter // loop over the attributes and build the search and replace arrays foreach ($attributes as $attr => $val) { $arrSearch[] = '%' . $attr . '%'; if (strlen($val[0]) > 0) { $arrReplace[] = SimpleSAML_Auth_LDAP::escape_filter_value($val[0]); } else { $arrReplace[] = ''; } } // merge the attributes into the ldap_search_filter $filter = str_replace($arrSearch, $arrReplace, $this->search_filter); // search for matching entries $entries = $this->getLdap()->searchformultiple($this->base_dn, $filter, (array) $this->search_attribute, TRUE, FALSE); // handle [multiple] values if (is_array($entries) && is_array($entries[0])) { $results = array(); foreach ($entries as $entry) { $entry = $entry[strtolower($this->search_attribute)]; for ($i = 0; $i < $entry['count']; $i++) { $results[] = $entry[$i]; } } $attributes[$this->new_attribute] = array_values($results); } }
/** * Add attributes from an LDAP server. * * @param array &$request The current request */ public function process(&$request) { assert('is_array($request)'); assert('array_key_exists("Attributes", $request)'); $attributes =& $request['Attributes']; if (!isset($attributes[$this->config['userid_attribute']])) { throw new Exception('The user\'s identity does not have an attribute called "' . $this->config['userid_attribute'] . '"'); } // perform a merge on the ldap_search_filter // loop over the attributes and build the search and replace arrays foreach ($attributes as $attr => $val) { $arrSearch[] = '%' . $attr . '%'; if (strlen($val[0]) > 0) { $arrReplace[] = SimpleSAML_Auth_LDAP::escape_filter_value($val[0]); } else { $arrReplace[] = ''; } } // merge the attributes into the ldap_search_filter $merged_ldap_search_filter = str_replace($arrSearch, $arrReplace, $this->config['ldap_search_filter']); // connect to the LDAP directory $ds = ldap_connect($this->config['ldap_host'], $this->config['ldap_port']); if (!$ds) { throw new Exception('Failed to initialize LDAP connection parameters (' . ldap_error(NULL) . ')'); } ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, 3); // if we're supposed to bind as a specified user if (isset($this->config['ldap_bind_user']) && $this->config['ldap_bind_user'] && (isset($this->config['ldap_bind_pwd']) && $this->config['ldap_bind_pwd'])) { // bind to the directory as the specified user if (!ldap_bind($ds, $this->config['ldap_bind_user'], $this->config['ldap_bind_pwd'])) { throw new Exception($this->config['ldap_bind_user'] . ' failed to bind against ' . $this->config['ldap_host'] . ' (' . ldap_error($ds) . ')'); } } else { // bind to the directory anonymously if (!ldap_bind($ds)) { throw new Exception('Failed to anonymously bind against ' . $this->config['ldap_host'] . ' (' . ldap_error($ds) . ')'); } } // search for matching entries $sr = ldap_search($ds, $this->config['ldap_search_base_dn'], $merged_ldap_search_filter, array($this->config['ldap_search_attribute'])); $entries = ldap_get_entries($ds, $sr); // handle [multiple] values if (is_array($entries) && is_array($entries[0])) { $entry = $entries[0][strtolower($this->config['ldap_search_attribute'])]; $results = array(); for ($i = 0; $i < $entry['count']; $i++) { $results[] = $entry[$i]; } $attributes[$this->config['new_attribute_name']] = array_values($results); } ldap_unbind($ds); }
} $orgconfig = $ldaporgconfig[$requestedOrg]; /* * Checking password parameter. */ if (empty($_REQUEST['password'])) { throw new Exception('The password field was left empty. Please fill in a valid password.'); } $password = $_REQUEST['password']; if (!preg_match('/^[a-zA-Z0-9.]+$/', $password)) { throw new Exception('Illegal characters in password.'); } /* * Connecting to LDAP. */ $ldap = new SimpleSAML_Auth_LDAP($orgconfig['hostname'], $orgconfig['enable_tls']); /* * Search for eduPersonPrincipalName. */ if (isset($orgconfig['adminUser'])) { $ldap->bind($orgconfig['adminUser'], $orgconfig['adminPassword']); } $eppn = $requestedUser . "@" . $requestedOrg; $dn = $ldap->searchfordn($orgconfig['searchbase'], 'eduPersonPrincipalName', $eppn); /* * Do LDAP bind using DN found from the search on ePPN. */ if (!$ldap->bind($dn, $password)) { SimpleSAML_Logger::info('AUTH - ldap-feide: ' . $requestedUser . ' failed to authenticate. DN=' . $dn); throw new Exception('Wrong username or password'); }