/** * Process an authentication response. * * This function saves the state, and if necessary redirects the user to the page where the user * is informed about the expiry date of his/her certificate. * * @param array $state The state of the response. */ public function process(&$state) { assert('is_array($state)'); if (isset($state['isPassive']) && $state['isPassive'] === TRUE) { // We have a passive request. Skip the warning return; } if (!isset($_SERVER['SSL_CLIENT_CERT']) || $_SERVER['SSL_CLIENT_CERT'] == '') { return; } $client_cert = $_SERVER['SSL_CLIENT_CERT']; $client_cert_data = openssl_x509_parse($client_cert); if ($client_cert_data == FALSE) { SimpleSAML\Logger::error('authX509: invalid cert'); return; } $validTo = $client_cert_data['validTo_time_t']; $now = time(); $daysleft = (int) (($validTo - $now) / (24 * 60 * 60)); if ($daysleft > $this->warndaysbefore) { // We have a certificate that will be valid for some time. Skip the warning return; } SimpleSAML\Logger::warning('authX509: user certificate expires in ' . $daysleft . ' days'); $state['daysleft'] = $daysleft; $state['renewurl'] = $this->renewurl; /* Save state and redirect. */ $id = SimpleSAML_Auth_State::saveState($state, 'warning:expire'); $url = SimpleSAML\Module::getModuleURL('authX509/expirywarning.php'); \SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id)); }
/** * When the process logic determines that the user is not * authorized for this service, then forward the user to * an 403 unauthorized page. * * Separated this code into its own method so that child * classes can override it and change the action. Forward * thinking in case a "chained" ACL is needed, more complex * permission logic. * * @param array $request */ protected function unauthorized(&$request) { SimpleSAML\Logger::error('ExpectedAuthnContextClassRef: Invalid authentication context: ' . $this->AuthnContextClassRef . '. Accepted values are: ' . var_export($this->accepted, true)); $id = SimpleSAML_Auth_State::saveState($request, 'saml:ExpectedAuthnContextClassRef:unauthorized'); $url = SimpleSAML\Module::getModuleURL('saml/sp/wrong_authncontextclassref.php'); \SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id)); }
/** * Delete a metadata entry. * * @param string $entityId The entityId of the metadata entry. * @param string $set The metadata set this metadata entry belongs to. */ public function deleteMetadata($entityId, $set) { assert('is_string($entityId)'); assert('is_string($set)'); $filePath = $this->getMetadataPath($entityId, $set); if (!file_exists($filePath)) { SimpleSAML\Logger::warning('Attempted to erase nonexistent metadata entry ' . var_export($entityId, true) . ' in set ' . var_export($set, true) . '.'); return; } $res = unlink($filePath); if ($res === false) { $error = error_get_last(); SimpleSAML\Logger::error('Failed to delete file ' . $filePath . ': ' . $error['message']); } }
/** * Create consent table. * * This function creates the table with consent data. * * @return True if successful, false if not. * * @TODO Remove this function since it is not used */ private function _createTable() { $db = $this->_getDB(); if ($db === false) { return false; } $res = $this->db->exec('CREATE TABLE ' . $this->_table . ' (consent_date TIMESTAMP NOT null, usage_date TIMESTAMP NOT null,' . 'hashed_user_id VARCHAR(80) NOT null, service_id VARCHAR(255) NOT null, attribute VARCHAR(80) NOT null,' . 'UNIQUE (hashed_user_id, service_id)'); if ($res === false) { SimpleSAML\Logger::error('consent:Database - Failed to create table \'' . $this->_table . '\'.'); return false; } return true; }
/** * Insert or update into a table. * * Since various databases implement different methods for doing this, * we abstract it away here. * * @param string $table The table we should update. * @param array $key The key columns. * @param array $data Associative array with columns. */ public function insertOrUpdate($table, array $keys, array $data) { assert('is_string($table)'); $colNames = '(' . implode(', ', array_keys($data)) . ')'; $values = 'VALUES(:' . implode(', :', array_keys($data)) . ')'; switch ($this->driver) { case 'mysql': $query = 'REPLACE INTO ' . $table . ' ' . $colNames . ' ' . $values; $query = $this->pdo->prepare($query); $query->execute($data); return; case 'sqlite': $query = 'INSERT OR REPLACE INTO ' . $table . ' ' . $colNames . ' ' . $values; $query = $this->pdo->prepare($query); $query->execute($data); return; } // Default implementation. Try INSERT, and UPDATE if that fails. $insertQuery = 'INSERT INTO ' . $table . ' ' . $colNames . ' ' . $values; $insertQuery = $this->pdo->prepare($insertQuery); try { $insertQuery->execute($data); return; } catch (PDOException $e) { $ecode = (string) $e->getCode(); switch ($ecode) { case '23505': // PostgreSQL break; default: SimpleSAML\Logger::error('Error while saving data: ' . $e->getMessage()); throw $e; } } $updateCols = array(); $condCols = array(); foreach ($data as $col => $value) { $tmp = $col . ' = :' . $col; if (in_array($col, $keys, TRUE)) { $condCols[] = $tmp; } else { $updateCols[] = $tmp; } } $updateQuery = 'UPDATE ' . $table . ' SET ' . implode(',', $updateCols) . ' WHERE ' . implode(' AND ', $condCols); $updateQuery = $this->pdo->prepare($updateQuery); $updateQuery->execute($data); }
<p>Report ID: <tt>%s</tt></p> <p>Referer: <tt>%s</tt></p> <hr /> <div class="footer"> This message was sent using SimpleSAMLphp. Visit the <a href="http://simplesamlphp.org/">SimpleSAMLphp homepage</a>. </div> MESSAGE; $message = sprintf($message, htmlspecialchars($text), $data['exceptionMsg'], $data['exceptionTrace'], $data['url'], $data['url'], htmlspecialchars(php_uname('n')), dirname(dirname(__FILE__)), $data['trackId'], $data['version'], $data['reportId'], $data['referer']); // add the email address of the submitter as the Reply-To address $email = trim($email); // check that it looks like a valid email address if (!preg_match('/\\s/', $email) && strpos($email, '@') !== false) { $replyto = $email; $from = $email; } else { $replyto = null; $from = '*****@*****.**'; } // send the email $toAddress = $config->getString('technicalcontact_email', '*****@*****.**'); if ($config->getBoolean('errorreporting', true) && $toAddress !== '*****@*****.**') { $email = new SimpleSAML_XHTML_EMail($toAddress, 'SimpleSAMLphp error report', $from); $email->setBody($message); $email->send(); SimpleSAML\Logger::error('Report with id ' . $reportId . ' sent to <' . $toAddress . '>.'); } // redirect the user back to this page to clear the POST request \SimpleSAML\Utils\HTTP::redirectTrustedURL(\SimpleSAML\Utils\HTTP::getSelfURLNoQuery());
exit; } } $summary = array(); $croninfo = array('summary' => &$summary, 'tag' => $_REQUEST['tag']); $url = \SimpleSAML\Utils\HTTP::getSelfURL(); $time = date(DATE_RFC822); SimpleSAML\Module::callHooks('cron', $croninfo); foreach ($summary as $s) { SimpleSAML\Logger::debug('Cron - Summary: ' . $s); } if ($cronconfig->getValue('sendemail', TRUE) && count($summary) > 0) { $message = '<h1>Cron report</h1><p>Cron ran at ' . $time . '</p>' . '<p>URL: <tt>' . $url . '</tt></p>' . '<p>Tag: ' . $croninfo['tag'] . "</p>\n\n" . '<ul><li>' . join('</li><li>', $summary) . '</li></ul>'; $toaddress = $config->getString('technicalcontact_email', '*****@*****.**'); if ($toaddress == '*****@*****.**') { SimpleSAML\Logger::error('Cron - Could not send email. [technicalcontact_email] not set in config.'); } else { // Use $toaddress for both TO and FROM $email = new SimpleSAML_XHTML_EMail($toaddress, 'SimpleSAMLphp cron report', $toaddress); $email->setBody($message); $email->send(); } } if (isset($_REQUEST['output']) && $_REQUEST['output'] == "xhtml") { $t = new SimpleSAML_XHTML_Template($config, 'cron:croninfo-result.php', 'cron:cron'); $t->data['tag'] = $croninfo['tag']; $t->data['time'] = $time; $t->data['url'] = $url; $t->data['summary'] = $summary; $t->show(); }
/** * Save the session to the store. * * This method saves the session to the session handler in case it has been marked as dirty. * * WARNING: please do not use this method directly unless you really need to and know what you are doing. Use * markDirty() instead. */ public function save() { if (!$this->dirty) { // session hasn't changed, don't bother saving it return; } $this->dirty = false; $this->callback_registered = false; $sh = SimpleSAML_SessionHandler::getSessionHandler(); try { $sh->saveSession($this); } catch (Exception $e) { if (!$e instanceof SimpleSAML_Error_Exception) { $e = new SimpleSAML_Error_UnserializableException($e); } SimpleSAML\Logger::error('Unable to save session.'); $e->logError(); } }
/** * Save an error report. * * @return array The array with the error report data. */ protected function saveError() { $data = $this->format(); $emsg = array_shift($data); $etrace = implode("\n", $data); $reportId = bin2hex(openssl_random_pseudo_bytes(4)); SimpleSAML\Logger::error('Error report with id ' . $reportId . ' generated.'); $config = SimpleSAML_Configuration::getInstance(); $session = SimpleSAML_Session::getSessionFromRequest(); if (isset($_SERVER['HTTP_REFERER'])) { $referer = $_SERVER['HTTP_REFERER']; // remove anything after the first '?' or ';', just in case it contains any sensitive data $referer = explode('?', $referer, 2); $referer = $referer[0]; $referer = explode(';', $referer, 2); $referer = $referer[0]; } else { $referer = 'unknown'; } $errorData = array('exceptionMsg' => $emsg, 'exceptionTrace' => $etrace, 'reportId' => $reportId, 'trackId' => $session->getTrackID(), 'url' => \SimpleSAML\Utils\HTTP::getSelfURLNoQuery(), 'version' => $config->getVersion(), 'referer' => $referer); $session->setData('core:errorreport', $reportId, $errorData); return $errorData; }
/** * Print the exception to the log with log level error. * * This function will write this exception to the log, including a full backtrace. */ public function logError() { $lines = $this->format(); foreach ($lines as $line) { SimpleSAML\Logger::error($line); } }
/** * Print the exception to the log with log level error. * * This function will write this exception to the log, including a full backtrace. */ public function logError() { SimpleSAML\Logger::error($this->getClass() . ': ' . $this->getMessage()); $this->logBacktrace(\SimpleSAML\Logger::ERR); }
/** * Attempt to log in using the given username and password. * * On a successful login, this function should return the users attributes. On failure, * it should throw an exception. If the error was caused by the user entering the wrong * username or password, a SimpleSAML_Error_Error('WRONGUSERPASS') should be thrown. * * Note that both the username and the password are UTF-8 encoded. * * @param string $username The username the user wrote. * @param string $password The password the user wrote. * @return array Associative array with the users attributes. */ protected function login($username, $password) { assert('is_string($username)'); assert('is_string($password)'); $db = $this->connect(); try { $sth = $db->prepare($this->query); } catch (PDOException $e) { throw new Exception('sqlauth:' . $this->authId . ': - Failed to prepare query: ' . $e->getMessage()); } try { $res = $sth->execute(array('username' => $username, 'password' => $password)); } catch (PDOException $e) { throw new Exception('sqlauth:' . $this->authId . ': - Failed to execute query: ' . $e->getMessage()); } try { $data = $sth->fetchAll(PDO::FETCH_ASSOC); } catch (PDOException $e) { throw new Exception('sqlauth:' . $this->authId . ': - Failed to fetch result set: ' . $e->getMessage()); } SimpleSAML\Logger::info('sqlauth:' . $this->authId . ': Got ' . count($data) . ' rows from database'); if (count($data) === 0) { /* No rows returned - invalid username/password. */ SimpleSAML\Logger::error('sqlauth:' . $this->authId . ': No rows in result set. Probably wrong username/password.'); throw new SimpleSAML_Error_Error('WRONGUSERPASS'); } /* Extract attributes. We allow the resultset to consist of multiple rows. Attributes * which are present in more than one row will become multivalued. NULL values and * duplicate values will be skipped. All values will be converted to strings. */ $attributes = array(); foreach ($data as $row) { foreach ($row as $name => $value) { if ($value === NULL) { continue; } $value = (string) $value; if (!array_key_exists($name, $attributes)) { $attributes[$name] = array(); } if (in_array($value, $attributes[$name], TRUE)) { /* Value already exists in attribute. */ continue; } $attributes[$name][] = $value; } } SimpleSAML\Logger::info('sqlauth:' . $this->authId . ': Attributes: ' . implode(',', array_keys($attributes))); return $attributes; }
/** * Convenience method to create an LDAPException as well as log the * description. * * @param string $description * The exception's description * @return Exception */ private function makeException($description, $type = NULL) { $errNo = 0x0; // Log LDAP code and description, if possible if (empty($this->ldap)) { SimpleSAML\Logger::error($description); } else { $errNo = @ldap_errno($this->ldap); } // Decide exception type and return if ($type) { if ($errNo !== 0) { // Only log real LDAP errors; not success SimpleSAML\Logger::error($description . '; cause: \'' . ldap_error($this->ldap) . '\' (0x' . dechex($errNo) . ')'); } else { SimpleSAML\Logger::error($description); } switch ($type) { case ERR_INTERNAL: // 1 - ExInternal return new SimpleSAML_Error_Exception($description, $errNo); case ERR_NO_USER: // 2 - ExUserNotFound return new SimpleSAML_Error_UserNotFound($description, $errNo); case ERR_WRONG_PW: // 3 - ExInvalidCredential return new SimpleSAML_Error_InvalidCredential($description, $errNo); case ERR_AS_DATA_INCONSIST: // 4 - ExAsDataInconsist return new SimpleSAML_Error_AuthSource('ldap', $description); case ERR_AS_INTERNAL: // 5 - ExAsInternal return new SimpleSAML_Error_AuthSource('ldap', $description); } } else { if ($errNo !== 0) { $description .= '; cause: \'' . ldap_error($this->ldap) . '\' (0x' . dechex($errNo) . ')'; if (@ldap_get_option($this->ldap, LDAP_OPT_DIAGNOSTIC_MESSAGE, $extendedError) && !empty($extendedError)) { $description .= '; additional: \'' . $extendedError . '\''; } } switch ($errNo) { case 0x20: //LDAP_NO_SUCH_OBJECT SimpleSAML\Logger::warning($description); return new SimpleSAML_Error_UserNotFound($description, $errNo); case 0x31: //LDAP_INVALID_CREDENTIALS SimpleSAML\Logger::info($description); return new SimpleSAML_Error_InvalidCredential($description, $errNo); case -1: //NO_SERVER_CONNECTION SimpleSAML\Logger::error($description); return new SimpleSAML_Error_AuthSource('ldap', $description); default: SimpleSAML\Logger::error($description); return new SimpleSAML_Error_AuthSource('ldap', $description); } } }
$statsInfo = array('remember' => array_key_exists('saveconsent', $_REQUEST)); if (isset($state['Destination']['entityid'])) { $statsInfo['spEntityID'] = $state['Destination']['entityid']; } SimpleSAML_Stats::log('consent:accept', $statsInfo); if (array_key_exists('consent:store', $state) && array_key_exists('saveconsent', $_REQUEST) && $_REQUEST['saveconsent'] === '1') { // Save consent $store = $state['consent:store']; $userId = $state['consent:store.userId']; $targetedId = $state['consent:store.destination']; $attributeSet = $state['consent:store.attributeSet']; SimpleSAML\Logger::debug('Consent - saveConsent() : [' . $userId . '|' . $targetedId . '|' . $attributeSet . ']'); try { $store->saveConsent($userId, $targetedId, $attributeSet); } catch (Exception $e) { SimpleSAML\Logger::error('Consent: Error writing to storage: ' . $e->getMessage()); } } SimpleSAML_Auth_ProcessingChain::resumeProcessing($state); } // Prepare attributes for presentation $attributes = $state['Attributes']; $noconsentattributes = $state['consent:noconsentattributes']; // Remove attributes that do not require consent foreach ($attributes as $attrkey => $attrval) { if (in_array($attrkey, $noconsentattributes)) { unset($attributes[$attrkey]); } } $para = array('attributes' => &$attributes); // Reorder attributes according to attributepresentation hooks
/** * Calculate the NameID value that should be used. * * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP. * @param SimpleSAML_Configuration $dstMetadata The metadata of the SP. * @param array &$state The authentication state of the user. * @return string The NameID value. */ private static function generateNameIdValue(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata, array &$state) { $attribute = $spMetadata->getString('simplesaml.nameidattribute', NULL); if ($attribute === NULL) { $attribute = $idpMetadata->getString('simplesaml.nameidattribute', NULL); if ($attribute === NULL) { if (!isset($state['UserID'])) { SimpleSAML\Logger::error('Unable to generate NameID. Check the userid.attribute option.'); } $attributeValue = $state['UserID']; $idpEntityId = $idpMetadata->getString('entityid'); $spEntityId = $spMetadata->getString('entityid'); $secretSalt = SimpleSAML\Utils\Config::getSecretSalt(); $uidData = 'uidhashbase' . $secretSalt; $uidData .= strlen($idpEntityId) . ':' . $idpEntityId; $uidData .= strlen($spEntityId) . ':' . $spEntityId; $uidData .= strlen($attributeValue) . ':' . $attributeValue; $uidData .= $secretSalt; return hash('sha1', $uidData); } } $attributes = $state['Attributes']; if (!array_key_exists($attribute, $attributes)) { SimpleSAML\Logger::error('Unable to add NameID: Missing ' . var_export($attribute, TRUE) . ' in the attributes of the user.'); return NULL; } return $attributes[$attribute][0]; }
/** * Retrieve the metadata file. * * This function will check its cached copy, to see whether it can be used. * * @return SAML2_XML_md_EntityDescriptor|SAML2_XML_md_EntitiesDescriptor|NULL The downloaded metadata. */ public function getMetadata() { if ($this->metadata !== NULL) { /* We have already downloaded the metdata. */ return $this->metadata; } if (!$this->aggregator->isCacheValid($this->cacheId, $this->cacheTag)) { $this->updateCache(); if ($this->metadata !== NULL) { return $this->metadata; } /* We were unable to update the cache - use cached metadata. */ } $cacheFile = $this->aggregator->getCacheFile($this->cacheId); if (!file_exists($cacheFile)) { SimpleSAML\Logger::error($this->logLoc . 'No cached metadata available.'); return NULL; } SimpleSAML\Logger::debug($this->logLoc . 'Using cached metadata from ' . var_export($cacheFile, TRUE)); $metadata = file_get_contents($cacheFile); if ($metadata !== NULL) { $this->metadata = unserialize($metadata); return $this->metadata; } return NULL; }
/** * Process a authentication response * * This function saves the state, and redirects the user to the page where * the user can authorize the release of the attributes. * If storage is used and the consent has already been given the user is * passed on. * * @param array &$state The state of the response. * * @return void */ public function process(&$state) { assert('is_array($state)'); assert('array_key_exists("UserID", $state)'); assert('array_key_exists("Destination", $state)'); assert('array_key_exists("entityid", $state["Destination"])'); assert('array_key_exists("metadata-set", $state["Destination"])'); assert('array_key_exists("entityid", $state["Source"])'); assert('array_key_exists("metadata-set", $state["Source"])'); $spEntityId = $state['Destination']['entityid']; $idpEntityId = $state['Source']['entityid']; $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); /** * If the consent module is active on a bridge $state['saml:sp:IdP'] * will contain an entry id for the remote IdP. If not, then the * consent module is active on a local IdP and nothing needs to be * done. */ if (isset($state['saml:sp:IdP'])) { $idpEntityId = $state['saml:sp:IdP']; $idpmeta = $metadata->getMetaData($idpEntityId, 'saml20-idp-remote'); $state['Source'] = $idpmeta; } $statsData = array('spEntityID' => $spEntityId); // Do not use consent if disabled if (isset($state['Source']['consent.disable']) && self::checkDisable($state['Source']['consent.disable'], $spEntityId)) { SimpleSAML\Logger::debug('Consent: Consent disabled for entity ' . $spEntityId . ' with IdP ' . $idpEntityId); SimpleSAML_Stats::log('consent:disabled', $statsData); return; } if (isset($state['Destination']['consent.disable']) && self::checkDisable($state['Destination']['consent.disable'], $idpEntityId)) { SimpleSAML\Logger::debug('Consent: Consent disabled for entity ' . $spEntityId . ' with IdP ' . $idpEntityId); SimpleSAML_Stats::log('consent:disabled', $statsData); return; } if ($this->_store !== null) { $source = $state['Source']['metadata-set'] . '|' . $idpEntityId; $destination = $state['Destination']['metadata-set'] . '|' . $spEntityId; $attributes = $state['Attributes']; // Remove attributes that do not require consent foreach ($attributes as $attrkey => $attrval) { if (in_array($attrkey, $this->_noconsentattributes)) { unset($attributes[$attrkey]); } } SimpleSAML\Logger::debug('Consent: userid: ' . $state['UserID']); SimpleSAML\Logger::debug('Consent: source: ' . $source); SimpleSAML\Logger::debug('Consent: destination: ' . $destination); $userId = self::getHashedUserID($state['UserID'], $source); $targetedId = self::getTargetedID($state['UserID'], $source, $destination); $attributeSet = self::getAttributeHash($attributes, $this->_includeValues); SimpleSAML\Logger::debug('Consent: hasConsent() [' . $userId . '|' . $targetedId . '|' . $attributeSet . ']'); try { if ($this->_store->hasConsent($userId, $targetedId, $attributeSet)) { // Consent already given SimpleSAML\Logger::stats('Consent: Consent found'); SimpleSAML_Stats::log('consent:found', $statsData); return; } SimpleSAML\Logger::stats('Consent: Consent notfound'); SimpleSAML_Stats::log('consent:notfound', $statsData); $state['consent:store'] = $this->_store; $state['consent:store.userId'] = $userId; $state['consent:store.destination'] = $targetedId; $state['consent:store.attributeSet'] = $attributeSet; } catch (Exception $e) { SimpleSAML\Logger::error('Consent: Error reading from storage: ' . $e->getMessage()); SimpleSAML\Logger::stats('Consent: Failed'); SimpleSAML_Stats::log('consent:failed', $statsData); } } else { SimpleSAML\Logger::stats('Consent: No storage'); SimpleSAML_Stats::log('consent:nostorage', $statsData); } $state['consent:focus'] = $this->_focus; $state['consent:checked'] = $this->_checked; $state['consent:hiddenAttributes'] = $this->_hiddenAttributes; $state['consent:noconsentattributes'] = $this->_noconsentattributes; $state['consent:showNoConsentAboutService'] = $this->_showNoConsentAboutService; // User interaction nessesary. Throw exception on isPassive request if (isset($state['isPassive']) && $state['isPassive'] === true) { SimpleSAML_Stats::log('consent:nopassive', $statsData); throw new SimpleSAML_Error_NoPassive('Unable to give consent on passive request.'); } // Save state and redirect $id = SimpleSAML_Auth_State::saveState($state, 'consent:request'); $url = SimpleSAML\Module::getModuleURL('consent/getconsent.php'); \SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id)); }
/** * Validate certificate and login * * This function try to validate the certificate. * On success, the user is logged in without going through * o login page. * On failure, The authX509:X509error.php template is * loaded. * * @param array &$state Information about the current authentication. */ public function authenticate(&$state) { assert('is_array($state)'); $ldapcf = $this->ldapcf; if (!isset($_SERVER['SSL_CLIENT_CERT']) || $_SERVER['SSL_CLIENT_CERT'] == '') { $state['authX509.error'] = "NOCERT"; $this->authFailed($state); assert('false'); // NOTREACHED return; } $client_cert = $_SERVER['SSL_CLIENT_CERT']; $client_cert_data = openssl_x509_parse($client_cert); if ($client_cert_data == false) { SimpleSAML\Logger::error('authX509: invalid cert'); $state['authX509.error'] = "INVALIDCERT"; $this->authFailed($state); assert('false'); // NOTREACHED return; } $dn = null; foreach ($this->x509attributes as $x509_attr => $ldap_attr) { /* value is scalar */ if (array_key_exists($x509_attr, $client_cert_data['subject'])) { $value = $client_cert_data['subject'][$x509_attr]; SimpleSAML\Logger::info('authX509: cert ' . $x509_attr . ' = ' . $value); $dn = $ldapcf->searchfordn($ldap_attr, $value, true); if ($dn !== null) { break; } } } if ($dn === null) { SimpleSAML\Logger::error('authX509: cert has ' . 'no matching user in LDAP'); $state['authX509.error'] = "UNKNOWNCERT"; $this->authFailed($state); assert('false'); /* NOTREACHED */ return; } if ($this->ldapusercert === null) { // do not check for certificate match $attributes = $ldapcf->getAttributes($dn); assert('is_array($attributes)'); $state['Attributes'] = $attributes; $this->authSuccesful($state); assert('false'); /* NOTREACHED */ return; } $ldap_certs = $ldapcf->getAttributes($dn, $this->ldapusercert); if ($ldap_certs === false) { SimpleSAML\Logger::error('authX509: no certificate ' . 'found in LDAP for dn=' . $dn); $state['authX509.error'] = "UNKNOWNCERT"; $this->authFailed($state); assert('false'); /* NOTREACHED */ return; } $merged_ldapcerts = array(); foreach ($this->ldapusercert as $attr) { $merged_ldapcerts = array_merge($merged_ldapcerts, $ldap_certs[$attr]); } $ldap_certs = $merged_ldapcerts; foreach ($ldap_certs as $ldap_cert) { $pem = $this->der2pem($ldap_cert); $ldap_cert_data = openssl_x509_parse($pem); if ($ldap_cert_data == false) { SimpleSAML\Logger::error('authX509: cert in ' . 'LDAP in invalid for ' . 'dn = ' . $dn); continue; } if ($ldap_cert_data === $client_cert_data) { $attributes = $ldapcf->getAttributes($dn); assert('is_array($attributes)'); $state['Attributes'] = $attributes; $this->authSuccesful($state); assert('false'); /* NOTREACHED */ return; } } SimpleSAML\Logger::error('authX509: no matching cert in ' . 'LDAP for dn = ' . $dn); $state['authX509.error'] = "UNKNOWNCERT"; $this->authFailed($state); assert('false'); /* NOTREACHED */ return; }
<?php /** * * * @author Mathias Meisfjordskar, University of Oslo. * <*****@*****.**> * @package SimpleSAMLphp */ $state = SimpleSAML_Auth_State::loadState($_REQUEST['AuthState'], sspmod_negotiate_Auth_Source_Negotiate::STAGEID); $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpid = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted', 'metaindex'); $idpmeta = $metadata->getMetaData($idpid, 'saml20-idp-hosted'); if (isset($idpmeta['auth'])) { $source = SimpleSAML_Auth_Source::getById($idpmeta['auth']); if ($source === NULL) { throw new SimpleSAML_Error_BadRequest('Invalid AuthId "' . $idpmeta['auth'] . '" - not found.'); } $session = SimpleSAML_Session::getSessionFromRequest(); $session->setData('negotiate:disable', 'session', FALSE, 24 * 60 * 60); SimpleSAML\Logger::debug('Negotiate(retry) - session enabled, retrying.'); $source->authenticate($state); assert('FALSE'); } else { SimpleSAML\Logger::error('Negotiate - retry - no "auth" parameter found in IdP metadata.'); assert('FALSE'); }