Exemplo n.º 1
0
 /**
  * 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));
 }
 /**
  * Get the NameID value.
  *
  * @param array $state The state array.
  * @return string|null The NameID value.
  */
 protected function getValue(array &$state)
 {
     if (!isset($state['Destination']['entityid'])) {
         SimpleSAML\Logger::warning('No SP entity ID - not generating persistent NameID.');
         return null;
     }
     $spEntityId = $state['Destination']['entityid'];
     if (!isset($state['Source']['entityid'])) {
         SimpleSAML\Logger::warning('No IdP entity ID - not generating persistent NameID.');
         return null;
     }
     $idpEntityId = $state['Source']['entityid'];
     if (!isset($state['Attributes'][$this->attribute]) || count($state['Attributes'][$this->attribute]) === 0) {
         SimpleSAML\Logger::warning('Missing attribute ' . var_export($this->attribute, true) . ' on user - not generating persistent NameID.');
         return null;
     }
     if (count($state['Attributes'][$this->attribute]) > 1) {
         SimpleSAML\Logger::warning('More than one value in attribute ' . var_export($this->attribute, true) . ' on user - not generating persistent NameID.');
         return null;
     }
     $uid = array_values($state['Attributes'][$this->attribute]);
     // just in case the first index is no longer 0
     $uid = $uid[0];
     if (empty($uid)) {
         SimpleSAML\Logger::warning('Empty value in attribute ' . var_export($this->attribute, true) . ' on user - not generating persistent NameID.');
         return null;
     }
     $secretSalt = SimpleSAML\Utils\Config::getSecretSalt();
     $uidData = 'uidhashbase' . $secretSalt;
     $uidData .= strlen($idpEntityId) . ':' . $idpEntityId;
     $uidData .= strlen($spEntityId) . ':' . $spEntityId;
     $uidData .= strlen($uid) . ':' . $uid;
     $uidData .= $secretSalt;
     return sha1($uidData);
 }
function oauth2_hook_cron(&$croninfo)
{
    assert('is_array($croninfo)');
    assert('array_key_exists("summary", $croninfo)');
    assert('array_key_exists("tag", $croninfo)');
    $oauth2config = SimpleSAML_Configuration::getOptionalConfig('module_oauth2.php');
    if (is_null($oauth2config->getValue('cron_tag', 'hourly'))) {
        return;
    }
    if ($oauth2config->getValue('cron_tag', NULL) !== $croninfo['tag']) {
        return;
    }
    try {
        $store = SimpleSAML_Store::getInstance();
        if (!$store instanceof \SimpleSAML\Modules\DBAL\Store\DBAL) {
            throw new \SimpleSAML_Error_Exception('OAuth2 module: Only DBAL Store is supported');
        }
        $accessTokenRepository = new AccessTokenRepository();
        $accessTokenRepository->removeExpiredAccessTokens();
        $authTokenRepository = new AuthCodeRepository();
        $authTokenRepository->removeExpiredAuthCodes();
        $refreshTokenRepository = new RefreshTokenRepository();
        $refreshTokenRepository->removeExpiredRefreshTokens();
        $croninfo['summary'][] = 'OAuth2 clean up. Removed expired entries from OAuth2 storage.';
    } catch (Exception $e) {
        $message = 'OAuth2 clean up cron script failed: ' . $e->getMessage();
        SimpleSAML\Logger::warning($message);
        $croninfo['summary'][] = $message;
    }
}
Exemplo n.º 4
0
/**
 * Hook to run a cron job.
 *
 * @param array &$croninfo  Output
 */
function statistics_hook_cron(&$croninfo)
{
    assert('is_array($croninfo)');
    assert('array_key_exists("summary", $croninfo)');
    assert('array_key_exists("tag", $croninfo)');
    $statconfig = SimpleSAML_Configuration::getConfig('module_statistics.php');
    if (is_null($statconfig->getValue('cron_tag', NULL))) {
        return;
    }
    if ($statconfig->getValue('cron_tag', NULL) !== $croninfo['tag']) {
        return;
    }
    $maxtime = $statconfig->getInteger('time_limit', NULL);
    if ($maxtime) {
        set_time_limit($maxtime);
    }
    try {
        $aggregator = new sspmod_statistics_Aggregator();
        $results = $aggregator->aggregate();
        if (empty($results)) {
            SimpleSAML\Logger::notice('Output from statistics aggregator was empty.');
        } else {
            $aggregator->store($results);
        }
    } catch (Exception $e) {
        $message = 'Loganalyzer threw exception: ' . $e->getMessage();
        SimpleSAML\Logger::warning($message);
        $croninfo['summary'][] = $message;
    }
}
 /**
  * Process a authentication response.
  *
  * This function checks how long it is since the last time the user was authenticated.
  * If it is to short a while since, we will show a warning to the user.
  *
  * @param array $state  The state of the response.
  */
 public function process(&$state)
 {
     assert('is_array($state)');
     if (!array_key_exists('PreviousSSOTimestamp', $state)) {
         /*
          * No timestamp from the previous SSO to this SP. This is the first
          * time during this session.
          */
         return;
     }
     $timeDelta = time() - $state['PreviousSSOTimestamp'];
     if ($timeDelta >= 10) {
         // At least 10 seconds since last attempt
         return;
     }
     if (array_key_exists('Destination', $state) && array_key_exists('entityid', $state['Destination'])) {
         $entityId = $state['Destination']['entityid'];
     } else {
         $entityId = 'UNKNOWN';
     }
     SimpleSAML\Logger::warning('WarnShortSSOInterval: Only ' . $timeDelta . ' seconds since last SSO for this user from the SP ' . var_export($entityId, TRUE));
     // Save state and redirect
     $id = SimpleSAML_Auth_State::saveState($state, 'core:short_sso_interval');
     $url = SimpleSAML\Module::getModuleURL('core/short_sso_interval.php');
     \SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id));
 }
Exemplo n.º 6
0
 /**
  * Apply this filter.
  *
  * @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->sourceAttribute])) {
         return;
     }
     // will not overwrite existing attribute
     if (isset($attributes[$this->targetAttribute])) {
         return;
     }
     $sourceAttrVal = $attributes[$this->sourceAttribute][0];
     /* the last position of an @ is usually the beginning of the scope
      * string */
     $scopeIndex = strrpos($sourceAttrVal, '@');
     if ($scopeIndex !== FALSE) {
         $attributes[$this->targetAttribute] = array();
         $scope = substr($sourceAttrVal, $scopeIndex + 1);
         $attributes[$this->targetAttribute][] = $scope;
         SimpleSAML\Logger::debug('ScopeFromAttribute: Inserted new attribute ' . $this->targetAttribute . ', with scope ' . $scope);
     } else {
         SimpleSAML\Logger::warning('ScopeFromAttribute: The configured source attribute ' . $this->sourceAttribute . ' does not have a scope. Did not add attribute ' . $this->targetAttribute . '.');
     }
 }
Exemplo n.º 7
0
/**
 * This temporary autoloader allows loading classes with their old-style names (SimpleSAML_Path_Something) even if they
 * have been migrated to namespaces, by registering an alias for the new class. If the class has not yet been migrated,
 * the autoloader will then try to load it.
 *
 * @param string $class The full name of the class using underscores to separate the elements of the path, and starting
 * with 'SimpleSAML_'.
 * @deprecated This function will be removed in SSP 2.0.
 */
function temporaryLoader($class)
{
    if (!strstr($class, 'SimpleSAML_')) {
        return;
        // not a valid class name for old classes
    }
    $original = $class;
    // list of classes that have been renamed or moved
    $renamed = array('SimpleSAML_Metadata_MetaDataStorageHandlerMDX' => 'SimpleSAML_Metadata_Sources_MDQ', 'SimpleSAML_Logger_LoggingHandlerSyslog' => 'SimpleSAML_Logger_SyslogLoggingHandler', 'SimpleSAML_Logger_LoggingHandlerErrorLog' => 'SimpleSAML_Logger_ErrorLogLoggingHandler', 'SimpleSAML_Logger_LoggingHandlerFile' => 'SimpleSAML_Logger_FileLoggingHandler', 'SimpleSAML_Logger_LoggingHandler' => 'SimpleSAML_Logger_LoggingHandlerInterface');
    if (array_key_exists($class, $renamed)) {
        // the class has been renamed, try to load it and create an alias
        $class = $renamed[$class];
    }
    // try to load it from the corresponding file
    $path = explode('_', $class);
    $file = dirname(__FILE__) . DIRECTORY_SEPARATOR . join(DIRECTORY_SEPARATOR, $path) . '.php';
    if (file_exists($file)) {
        require_once $file;
    }
    // it exists, so it's not yet migrated to namespaces
    if (class_exists($class, false) || interface_exists($class, false)) {
        return;
    }
    // it didn't exist, try to see if it was migrated to namespaces
    $new = join('\\', $path);
    if (class_exists($new, false) || interface_exists($new, false)) {
        // do not try to autoload it if it doesn't exist! It should!
        class_alias($new, $original);
        SimpleSAML\Logger::warning("The class or interface '{$original}' is now using namespaces, please use '{$new}'.");
    }
}
Exemplo n.º 8
0
 /**
  * Redirect to page setting CDC.
  *
  * @param array &$state  The request state.
  */
 public function process(&$state)
 {
     assert('is_array($state)');
     if (!isset($state['Source']['entityid'])) {
         SimpleSAML\Logger::warning('saml:CDC: Could not find IdP entityID.');
         return;
     }
     // Save state and build request
     $id = SimpleSAML_Auth_State::saveState($state, 'cdc:resume');
     $returnTo = SimpleSAML\Module::getModuleURL('cdc/resume.php', array('domain' => $this->domain));
     $params = array('id' => $id, 'entityID' => $state['Source']['entityid']);
     $this->client->sendRequest($returnTo, 'append', $params);
 }
Exemplo n.º 9
0
 /**
  * Get the NameID value.
  *
  * @param array $state The state array.
  * @return string|null The NameID value.
  */
 protected function getValue(array &$state)
 {
     if (!isset($state['Attributes'][$this->attribute]) || count($state['Attributes'][$this->attribute]) === 0) {
         SimpleSAML\Logger::warning('Missing attribute ' . var_export($this->attribute, true) . ' on user - not generating attribute NameID.');
         return null;
     }
     if (count($state['Attributes'][$this->attribute]) > 1) {
         SimpleSAML\Logger::warning('More than one value in attribute ' . var_export($this->attribute, true) . ' on user - not generating attribute NameID.');
     }
     $value = array_values($state['Attributes'][$this->attribute]);
     // just in case the first index is no longer 0
     $value = $value[0];
     return $value;
 }
Exemplo n.º 10
0
 /**
  * Attempt to log in using the given username and password.
  *
  * @param string $username  The username the user wrote.
  * @param string $password  The password the user wrote.
  * @param string $org  The organization the user chose.
  * @return array  Associative array with the users attributes.
  */
 protected function login($username, $password, $org, array $sasl_args = null)
 {
     assert('is_string($username)');
     assert('is_string($password)');
     assert('is_string($org)');
     if (!array_key_exists($org, $this->ldapOrgs)) {
         // The user has selected an organization which doesn't exist anymore.
         SimpleSAML\Logger::warning('Authentication source ' . var_export($this->authId, true) . ': Organization seems to have disappeared while the user logged in.' . ' Organization was ' . var_export($org, true));
         throw new SimpleSAML_Error_Error('WRONGUSERPASS');
     }
     if ($this->includeOrgInUsername) {
         $username = $username . '@' . $org;
     }
     return $this->ldapOrgs[$org]->login($username, $password, $sasl_args);
 }
Exemplo n.º 11
0
 /**
  * Continue the logout operation.
  *
  * This function will never return.
  *
  * @param string $assocId The association that is terminated.
  * @param string|null $relayState The RelayState from the start of the logout.
  * @param SimpleSAML_Error_Exception|null $error The error that occurred during session termination (if any).
  *
  * @throws SimpleSAML_Error_Exception If the RelayState was lost during logout.
  */
 public function onResponse($assocId, $relayState, SimpleSAML_Error_Exception $error = null)
 {
     assert('is_string($assocId)');
     assert('is_string($relayState) || is_null($relayState)');
     if ($relayState === null) {
         throw new SimpleSAML_Error_Exception('RelayState lost during logout.');
     }
     $state = SimpleSAML_Auth_State::loadState($relayState, 'core:LogoutTraditional');
     if ($error === null) {
         SimpleSAML\Logger::info('Logged out of ' . var_export($assocId, true) . '.');
         $this->idp->terminateAssociation($assocId);
     } else {
         SimpleSAML\Logger::warning('Error received from ' . var_export($assocId, true) . ' during logout:');
         $error->logWarning();
         $state['core:Failed'] = true;
     }
     self::logoutNextSP($state);
 }
 /**
  * Store a NameID to attribute.
  *
  * @param array &$state The request state.
  */
 public function process(&$state)
 {
     assert('is_array($state)');
     if (!isset($state['saml:NameID'][SAML2_Const::NAMEID_PERSISTENT])) {
         SimpleSAML\Logger::warning('Unable to generate eduPersonTargetedID because no persistent NameID was available.');
         return;
     }
     $nameID = $state['saml:NameID'][SAML2_Const::NAMEID_PERSISTENT];
     if ($this->nameId) {
         $doc = SAML2_DOMDocumentFactory::create();
         $root = $doc->createElement('root');
         $doc->appendChild($root);
         SAML2_Utils::addNameId($root, $nameID);
         $value = $doc->saveXML($root->firstChild);
     } else {
         $value = $nameID['Value'];
     }
     $state['Attributes'][$this->attribute] = array($value);
 }
Exemplo n.º 13
0
/**
 * Hook to run a cron job.
 *
 * @param array &$croninfo  Output
 */
function riak_hook_cron(&$croninfo)
{
    assert('is_array($croninfo)');
    assert('array_key_exists("summary", $croninfo)');
    assert('array_key_exists("tag", $croninfo)');
    if ($croninfo['tag'] !== 'hourly') {
        return;
    }
    try {
        $store = new sspmod_riak_Store_Store();
        $result = $store->bucket->indexSearch('expires', 'int', 1, time() - 30);
        foreach ($result as $link) {
            $link->getBinary()->delete();
        }
        SimpleSAML\Logger::info(sprintf("deleted %s riak key%s", sizeof($result), sizeof($result) == 1 ? '' : 's'));
    } catch (Exception $e) {
        $message = 'riak threw exception: ' . $e->getMessage();
        SimpleSAML\Logger::warning($message);
        $croninfo['summary'][] = $message;
    }
}
Exemplo n.º 14
0
/**
 * Hook to run a cron job.
 *
 * @param array &$croninfo  Output
 */
function oauth_hook_cron(&$croninfo)
{
    assert('is_array($croninfo)');
    assert('array_key_exists("summary", $croninfo)');
    assert('array_key_exists("tag", $croninfo)');
    $oauthconfig = SimpleSAML_Configuration::getOptionalConfig('module_statistics.php');
    if (is_null($oauthconfig->getValue('cron_tag', 'hourly'))) {
        return;
    }
    if ($oauthconfig->getValue('cron_tag', NULL) !== $croninfo['tag']) {
        return;
    }
    try {
        $store = new sspmod_core_Storage_SQLPermanentStorage('oauth');
        $cleaned = $store->removeExpired();
        #		if ($cleaned > 0)
        $croninfo['summary'][] = 'OAuth clean up. Removed ' . $cleaned . ' expired entries from OAuth storage.';
    } catch (Exception $e) {
        $message = 'OAuth clean up cron script failed: ' . $e->getMessage();
        SimpleSAML\Logger::warning($message);
        $croninfo['summary'][] = $message;
    }
}
 /**
  * Initialize the PHP session handling. This constructor is protected because it should only be called from
  * SimpleSAML_SessionHandler::createSessionHandler(...).
  */
 protected function __construct()
 {
     // call the parent constructor in case it should become necessary in the future
     parent::__construct();
     $config = SimpleSAML_Configuration::getInstance();
     $this->cookie_name = $config->getString('session.phpsession.cookiename', null);
     if (function_exists('session_status') && defined('PHP_SESSION_ACTIVE')) {
         // PHP >= 5.4
         $previous_session = session_status() === PHP_SESSION_ACTIVE;
     } else {
         $previous_session = session_id() !== '' && session_name() !== $this->cookie_name;
     }
     if ($previous_session) {
         if (session_name() === $this->cookie_name || $this->cookie_name === null) {
             SimpleSAML\Logger::warning('There is already a PHP session with the same name as SimpleSAMLphp\'s session, or the ' . "'session.phpsession.cookiename' configuration option is not set. Make sure to set " . "SimpleSAMLphp's cookie name with a value not used by any other applications.");
         }
         /*
          * We shouldn't have a session at this point, so it might be an application session. Save the details to
          * retrieve it later and commit.
          */
         $this->previous_session['cookie_params'] = session_get_cookie_params();
         $this->previous_session['id'] = session_id();
         $this->previous_session['name'] = session_name();
         session_write_close();
     }
     if (!empty($this->cookie_name)) {
         session_name($this->cookie_name);
     } else {
         $this->cookie_name = session_name();
     }
     $params = $this->getCookieParams();
     session_set_cookie_params($params['lifetime'], $params['path'], $params['domain'], $params['secure'], $params['httponly']);
     $savepath = $config->getString('session.phpsession.savepath', null);
     if (!empty($savepath)) {
         session_save_path($savepath);
     }
 }
Exemplo n.º 16
0
 /**
  * Parse an Extensions element. Extensions may appear in multiple elements and certain extension may get inherited
  * from a parent element.
  *
  * @param mixed $element The element which contains the Extensions element.
  * @param array $parentExtensions An optional array of extensions from the parent element.
  *
  * @return array An associative array with the extensions parsed.
  */
 private static function processExtensions($element, $parentExtensions = array())
 {
     $ret = array('scope' => array(), 'tags' => array(), 'EntityAttributes' => array(), 'RegistrationInfo' => array(), 'UIInfo' => array(), 'DiscoHints' => array());
     // Some extensions may get inherited from a parent element
     if (($element instanceof \SAML2\XML\md\EntityDescriptor || $element instanceof \SAML2\XML\md\EntitiesDescriptor) && !empty($parentExtensions['RegistrationInfo'])) {
         $ret['RegistrationInfo'] = $parentExtensions['RegistrationInfo'];
     }
     foreach ($element->Extensions as $e) {
         if ($e instanceof \SAML2\XML\shibmd\Scope) {
             $ret['scope'][] = $e->scope;
             continue;
         }
         // Entity Attributes are only allowed at entity level extensions and not at RoleDescriptor level
         if ($element instanceof \SAML2\XML\md\EntityDescriptor || $element instanceof \SAML2\XML\md\EntitiesDescriptor) {
             if ($e instanceof \SAML2\XML\mdrpi\RegistrationInfo) {
                 // Registration Authority cannot be overridden (warn only if override attempts to change the value)
                 if (isset($ret['RegistrationInfo']['registrationAuthority']) && $ret['RegistrationInfo']['registrationAuthority'] !== $e->registrationAuthority) {
                     SimpleSAML\Logger::warning('Invalid attempt to override registrationAuthority \'' . $ret['RegistrationInfo']['registrationAuthority'] . "' with '{$e->registrationAuthority}'");
                 } else {
                     $ret['RegistrationInfo']['registrationAuthority'] = $e->registrationAuthority;
                 }
             }
             if ($e instanceof \SAML2\XML\mdattr\EntityAttributes && !empty($e->children)) {
                 foreach ($e->children as $attr) {
                     // only saml:Attribute are currently supported here. The specifications also allows
                     // saml:Assertions, which more complex processing
                     if ($attr instanceof \SAML2\XML\saml\Attribute) {
                         if (empty($attr->Name) || empty($attr->AttributeValue)) {
                             continue;
                         }
                         // attribute names that is not URI is prefixed as this: '{nameformat}name'
                         $name = $attr->Name;
                         if (empty($attr->NameFormat)) {
                             $name = '{' . \SAML2\Constants::NAMEFORMAT_UNSPECIFIED . '}' . $attr->Name;
                         } elseif ($attr->NameFormat !== 'urn:oasis:names:tc:SAML:2.0:attrname-format:uri') {
                             $name = '{' . $attr->NameFormat . '}' . $attr->Name;
                         }
                         $values = array();
                         foreach ($attr->AttributeValue as $attrvalue) {
                             $values[] = $attrvalue->getString();
                         }
                         $ret['EntityAttributes'][$name] = $values;
                     }
                 }
             }
         }
         // UIInfo elements are only allowed at RoleDescriptor level extensions
         if ($element instanceof \SAML2\XML\md\RoleDescriptor) {
             if ($e instanceof \SAML2\XML\mdui\UIInfo) {
                 $ret['UIInfo']['DisplayName'] = $e->DisplayName;
                 $ret['UIInfo']['Description'] = $e->Description;
                 $ret['UIInfo']['InformationURL'] = $e->InformationURL;
                 $ret['UIInfo']['PrivacyStatementURL'] = $e->PrivacyStatementURL;
                 foreach ($e->Keywords as $uiItem) {
                     if (!$uiItem instanceof \SAML2\XML\mdui\Keywords || empty($uiItem->Keywords) || empty($uiItem->lang)) {
                         continue;
                     }
                     $ret['UIInfo']['Keywords'][$uiItem->lang] = $uiItem->Keywords;
                 }
                 foreach ($e->Logo as $uiItem) {
                     if (!$uiItem instanceof \SAML2\XML\mdui\Logo || empty($uiItem->url) || empty($uiItem->height) || empty($uiItem->width)) {
                         continue;
                     }
                     $logo = array('url' => $uiItem->url, 'height' => $uiItem->height, 'width' => $uiItem->width);
                     if (!empty($uiItem->lang)) {
                         $logo['lang'] = $uiItem->lang;
                     }
                     $ret['UIInfo']['Logo'][] = $logo;
                 }
             }
         }
         // DiscoHints elements are only allowed at IDPSSODescriptor level extensions
         if ($element instanceof \SAML2\XML\md\IDPSSODescriptor) {
             if ($e instanceof \SAML2\XML\mdui\DiscoHints) {
                 $ret['DiscoHints']['IPHint'] = $e->IPHint;
                 $ret['DiscoHints']['DomainHint'] = $e->DomainHint;
                 $ret['DiscoHints']['GeolocationHint'] = $e->GeolocationHint;
             }
         }
         if (!$e instanceof \SAML2\XML\Chunk) {
             continue;
         }
         if ($e->localName === 'Attribute' && $e->namespaceURI === \SAML2\Constants::NS_SAML) {
             $attribute = $e->getXML();
             $name = $attribute->getAttribute('Name');
             $values = array_map(array('SimpleSAML\\Utils\\XML', 'getDOMText'), SimpleSAML\Utils\XML::getDOMChildren($attribute, 'AttributeValue', '@saml2'));
             if ($name === 'tags') {
                 foreach ($values as $tagname) {
                     if (!empty($tagname)) {
                         $ret['tags'][] = $tagname;
                     }
                 }
             }
         }
     }
     return $ret;
 }
Exemplo n.º 17
0
 /**
  * Build an assertion based on information in the metadata.
  *
  * @param SimpleSAML_Configuration $idpMetadata  The metadata of the IdP.
  * @param SimpleSAML_Configuration $spMetadata  The metadata of the SP.
  * @param array &$state  The state array with information about the request.
  * @return SAML2_Assertion  The assertion.
  */
 private static function buildAssertion(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata, array &$state)
 {
     assert('isset($state["Attributes"])');
     assert('isset($state["saml:ConsumerURL"])');
     $now = time();
     $signAssertion = $spMetadata->getBoolean('saml20.sign.assertion', NULL);
     if ($signAssertion === NULL) {
         $signAssertion = $idpMetadata->getBoolean('saml20.sign.assertion', TRUE);
     }
     $config = SimpleSAML_Configuration::getInstance();
     $a = new SAML2_Assertion();
     if ($signAssertion) {
         sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $a);
     }
     $a->setIssuer($idpMetadata->getString('entityid'));
     $a->setValidAudiences(array($spMetadata->getString('entityid')));
     $a->setNotBefore($now - 30);
     $assertionLifetime = $spMetadata->getInteger('assertion.lifetime', NULL);
     if ($assertionLifetime === NULL) {
         $assertionLifetime = $idpMetadata->getInteger('assertion.lifetime', 300);
     }
     $a->setNotOnOrAfter($now + $assertionLifetime);
     if (isset($state['saml:AuthnContextClassRef'])) {
         $a->setAuthnContext($state['saml:AuthnContextClassRef']);
     } else {
         $a->setAuthnContext(SAML2_Const::AC_PASSWORD);
     }
     $sessionStart = $now;
     if (isset($state['AuthnInstant'])) {
         $a->setAuthnInstant($state['AuthnInstant']);
         $sessionStart = $state['AuthnInstant'];
     }
     $sessionLifetime = $config->getInteger('session.duration', 8 * 60 * 60);
     $a->setSessionNotOnOrAfter($sessionStart + $sessionLifetime);
     $a->setSessionIndex(SimpleSAML\Utils\Random::generateID());
     $sc = new SAML2_XML_saml_SubjectConfirmation();
     $sc->SubjectConfirmationData = new SAML2_XML_saml_SubjectConfirmationData();
     $sc->SubjectConfirmationData->NotOnOrAfter = $now + $assertionLifetime;
     $sc->SubjectConfirmationData->Recipient = $state['saml:ConsumerURL'];
     $sc->SubjectConfirmationData->InResponseTo = $state['saml:RequestId'];
     /* ProtcolBinding of SP's <AuthnRequest> overwrites IdP hosted metadata configuration. */
     $hokAssertion = NULL;
     if ($state['saml:Binding'] === SAML2_Const::BINDING_HOK_SSO) {
         $hokAssertion = TRUE;
     }
     if ($hokAssertion === NULL) {
         $hokAssertion = $idpMetadata->getBoolean('saml20.hok.assertion', FALSE);
     }
     if ($hokAssertion) {
         /* Holder-of-Key */
         $sc->Method = SAML2_Const::CM_HOK;
         if (\SimpleSAML\Utils\HTTP::isHTTPS()) {
             if (isset($_SERVER['SSL_CLIENT_CERT']) && !empty($_SERVER['SSL_CLIENT_CERT'])) {
                 /* Extract certificate data (if this is a certificate). */
                 $clientCert = $_SERVER['SSL_CLIENT_CERT'];
                 $pattern = '/^-----BEGIN CERTIFICATE-----([^-]*)^-----END CERTIFICATE-----/m';
                 if (preg_match($pattern, $clientCert, $matches)) {
                     /* We have a client certificate from the browser which we add to the HoK assertion. */
                     $x509Certificate = new SAML2_XML_ds_X509Certificate();
                     $x509Certificate->certificate = str_replace(array("\r", "\n", " "), '', $matches[1]);
                     $x509Data = new SAML2_XML_ds_X509Data();
                     $x509Data->data[] = $x509Certificate;
                     $keyInfo = new SAML2_XML_ds_KeyInfo();
                     $keyInfo->info[] = $x509Data;
                     $sc->SubjectConfirmationData->info[] = $keyInfo;
                 } else {
                     throw new SimpleSAML_Error_Exception('Error creating HoK assertion: No valid client certificate provided during TLS handshake with IdP');
                 }
             } else {
                 throw new SimpleSAML_Error_Exception('Error creating HoK assertion: No client certificate provided during TLS handshake with IdP');
             }
         } else {
             throw new SimpleSAML_Error_Exception('Error creating HoK assertion: No HTTPS connection to IdP, but required for Holder-of-Key SSO');
         }
     } else {
         /* Bearer */
         $sc->Method = SAML2_Const::CM_BEARER;
     }
     $a->setSubjectConfirmation(array($sc));
     /* Add attributes. */
     if ($spMetadata->getBoolean('simplesaml.attributes', TRUE)) {
         $attributeNameFormat = self::getAttributeNameFormat($idpMetadata, $spMetadata);
         $a->setAttributeNameFormat($attributeNameFormat);
         $attributes = self::encodeAttributes($idpMetadata, $spMetadata, $state['Attributes']);
         $a->setAttributes($attributes);
     }
     /* Generate the NameID for the assertion. */
     if (isset($state['saml:NameIDFormat'])) {
         $nameIdFormat = $state['saml:NameIDFormat'];
     } else {
         $nameIdFormat = NULL;
     }
     if ($nameIdFormat === NULL || !isset($state['saml:NameID'][$nameIdFormat])) {
         /* Either not set in request, or not set to a format we supply. Fall back to old generation method. */
         $nameIdFormat = $spMetadata->getString('NameIDFormat', NULL);
         if ($nameIdFormat === NULL) {
             $nameIdFormat = $idpMetadata->getString('NameIDFormat', SAML2_Const::NAMEID_TRANSIENT);
         }
     }
     if (isset($state['saml:NameID'][$nameIdFormat])) {
         $nameId = $state['saml:NameID'][$nameIdFormat];
         $nameId['Format'] = $nameIdFormat;
     } else {
         $spNameQualifier = $spMetadata->getString('SPNameQualifier', NULL);
         if ($spNameQualifier === NULL) {
             $spNameQualifier = $spMetadata->getString('entityid');
         }
         if ($nameIdFormat === SAML2_Const::NAMEID_TRANSIENT) {
             /* generate a random id */
             $nameIdValue = SimpleSAML\Utils\Random::generateID();
         } else {
             /* this code will end up generating either a fixed assigned id (via nameid.attribute)
                or random id if not assigned/configured */
             $nameIdValue = self::generateNameIdValue($idpMetadata, $spMetadata, $state);
             if ($nameIdValue === NULL) {
                 SimpleSAML\Logger::warning('Falling back to transient NameID.');
                 $nameIdFormat = SAML2_Const::NAMEID_TRANSIENT;
                 $nameIdValue = SimpleSAML\Utils\Random::generateID();
             }
         }
         $nameId = array('Format' => $nameIdFormat, 'Value' => $nameIdValue, 'SPNameQualifier' => $spNameQualifier);
     }
     $state['saml:idp:NameID'] = $nameId;
     $a->setNameId($nameId);
     $encryptNameId = $spMetadata->getBoolean('nameid.encryption', NULL);
     if ($encryptNameId === NULL) {
         $encryptNameId = $idpMetadata->getBoolean('nameid.encryption', FALSE);
     }
     if ($encryptNameId) {
         $a->encryptNameId(sspmod_saml_Message::getEncryptionKey($spMetadata));
     }
     return $a;
 }
 /**
  * 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']);
     }
 }
Exemplo n.º 19
0
 /**
  * Find data stored with a given key.
  *
  * @param string $key The key of the data.
  *
  * @return mixed The data stored with the given key, or null if no data matching the key was found.
  */
 public static function get($key)
 {
     SimpleSAML\Logger::debug("loading key {$key} from memcache");
     $latestInfo = null;
     $latestTime = 0.0;
     $latestData = null;
     $mustUpdate = false;
     $allDown = true;
     // search all the servers for the given id
     foreach (self::getMemcacheServers() as $server) {
         $serializedInfo = $server->get($key);
         if ($serializedInfo === false) {
             // either the server is down, or we don't have the value stored on that server
             $mustUpdate = true;
             $up = $server->getstats();
             if ($up !== false) {
                 $allDown = false;
             }
             continue;
         }
         $allDown = false;
         // unserialize the object
         $info = unserialize($serializedInfo);
         /*
          * Make sure that this is an array with two keys:
          * - 'timestamp': The time the data was saved.
          * - 'data': The data.
          */
         if (!is_array($info)) {
             SimpleSAML\Logger::warning('Retrieved invalid data from a memcache server. Data was not an array.');
             continue;
         }
         if (!array_key_exists('timestamp', $info)) {
             SimpleSAML\Logger::warning('Retrieved invalid data from a memcache server. Missing timestamp.');
             continue;
         }
         if (!array_key_exists('data', $info)) {
             SimpleSAML\Logger::warning('Retrieved invalid data from a memcache server. Missing data.');
             continue;
         }
         if ($latestInfo === null) {
             // first info found
             $latestInfo = $serializedInfo;
             $latestTime = $info['timestamp'];
             $latestData = $info['data'];
             continue;
         }
         if ($info['timestamp'] === $latestTime && $serializedInfo === $latestInfo) {
             // this data matches the data from the other server(s)
             continue;
         }
         // different data from different servers. We need to update at least one of them to maintain sync
         $mustUpdate = true;
         // update if data in $info is newer than $latestData
         if ($latestTime < $info['timestamp']) {
             $latestInfo = $serializedInfo;
             $latestTime = $info['timestamp'];
             $latestData = $info['data'];
         }
     }
     if ($latestData === null) {
         if ($allDown) {
             // all servers are down, panic!
             $e = new SimpleSAML_Error_Error('MEMCACHEDOWN', null, 503);
             throw new SimpleSAML_Error_Exception('All memcache servers are down', 503, $e);
         }
         // we didn't find any data matching the key
         SimpleSAML\Logger::debug("key {$key} not found in memcache");
         return null;
     }
     if ($mustUpdate) {
         // we found data matching the key, but some of the servers need updating
         SimpleSAML\Logger::debug("Memcache servers out of sync for {$key}, forcing sync");
         self::set($key, $latestData);
     }
     return $latestData;
 }
Exemplo n.º 20
0
 /**
  * Print the exception to the log with log level warning.
  *
  * This function will write this exception to the log, including a full backtrace.
  */
 public function logWarning()
 {
     $lines = $this->format();
     foreach ($lines as $line) {
         SimpleSAML\Logger::warning($line);
     }
 }
Exemplo n.º 21
0
 /**
  * Save metadata for loading with the 'serialize' metadata loader.
  *
  * @param string $outputDir  The directory we should save the metadata to.
  */
 public function writeMetadataSerialize($outputDir)
 {
     assert('is_string($outputDir)');
     $metaHandler = new SimpleSAML_Metadata_MetaDataStorageHandlerSerialize(array('directory' => $outputDir));
     /* First we add all the metadata entries to the metadata handler. */
     foreach ($this->metadata as $set => $elements) {
         foreach ($elements as $m) {
             $entityId = $m['metadata']['entityid'];
             SimpleSAML\Logger::debug('metarefresh: Add metadata entry ' . var_export($entityId, TRUE) . ' in set ' . var_export($set, TRUE) . '.');
             $metaHandler->saveMetadata($entityId, $set, $m['metadata']);
         }
     }
     /* Then we delete old entries which should no longer exist. */
     $ct = time();
     foreach ($metaHandler->getMetadataSets() as $set) {
         foreach ($metaHandler->getMetadataSet($set) as $entityId => $metadata) {
             if (!array_key_exists('expire', $metadata)) {
                 SimpleSAML\Logger::warning('metarefresh: Metadata entry without expire timestamp: ' . var_export($entityId, TRUE) . ' in set ' . var_export($set, TRUE) . '.');
                 continue;
             }
             if ($metadata['expire'] > $ct) {
                 continue;
             }
             SimpleSAML\Logger::debug('metarefresh: ' . $entityId . ' expired ' . date('l jS \\of F Y h:i:s A', $metadata['expire']));
             SimpleSAML\Logger::debug('metarefresh: Delete expired metadata entry ' . var_export($entityId, TRUE) . ' in set ' . var_export($set, TRUE) . '. (' . ($ct - $metadata['expire']) . ' sec)');
             $metaHandler->deleteMetadata($entityId, $set);
         }
     }
 }
Exemplo n.º 22
0
 /**
  * Verify signed data.
  *
  * This function verifies signed data.
  *
  * @param string $signedData The data which is signed.
  *
  * @return string|false The data, or false if the signature is invalid.
  */
 private static function _verify($signedData)
 {
     assert('is_string($signedData)');
     $data = explode(':', $signedData, 2);
     if (count($data) !== 2) {
         SimpleSAML\Logger::warning('Consent cookie: Missing signature.');
         return false;
     }
     $data = $data[1];
     $newSignedData = self::_sign($data);
     if ($newSignedData !== $signedData) {
         SimpleSAML\Logger::warning('Consent cookie: Invalid signature.');
         return false;
     }
     return $data;
 }
Exemplo n.º 23
0
 /**
  * Get a session from the session handler.
  *
  * @param string|null $sessionId The session we should get, or null to get the current session.
  *
  * @return SimpleSAML_Session The session that is stored in the session handler, or null if the session wasn't
  * found.
  */
 public static function getSession($sessionId = null)
 {
     assert('is_string($sessionId) || is_null($sessionId)');
     $sh = SimpleSAML_SessionHandler::getSessionHandler();
     if ($sessionId === null) {
         $checkToken = true;
         $sessionId = $sh->getCookieSessionId();
         if ($sessionId === null) {
             return null;
         }
     } else {
         $checkToken = false;
     }
     if (array_key_exists($sessionId, self::$sessions)) {
         return self::$sessions[$sessionId];
     }
     $session = $sh->loadSession($sessionId);
     if ($session === null) {
         return null;
     }
     assert('$session instanceof self');
     if ($checkToken) {
         $globalConfig = SimpleSAML_Configuration::getInstance();
         if ($session->authToken !== null) {
             $authTokenCookieName = $globalConfig->getString('session.authtoken.cookiename', 'SimpleSAMLAuthToken');
             if (!isset($_COOKIE[$authTokenCookieName])) {
                 SimpleSAML\Logger::warning('Missing AuthToken cookie.');
                 return null;
             }
             if ($_COOKIE[$authTokenCookieName] !== $session->authToken) {
                 SimpleSAML\Logger::warning('Invalid AuthToken cookie.');
                 return null;
             }
         }
         // run session check function if defined
         $checkFunction = $globalConfig->getArray('session.check_function', null);
         if (isset($checkFunction)) {
             assert('is_callable($checkFunction)');
             $check = call_user_func($checkFunction, $session);
             if ($check !== true) {
                 SimpleSAML\Logger::warning('Session did not pass check function.');
                 return null;
             }
         }
     }
     self::$sessions[$sessionId] = $session;
     return $session;
 }
Exemplo n.º 24
0
 /**
  * Get the NameID value.
  *
  * @param array $state The state array.
  * @return string|null The NameID value.
  *
  * @throws sspmod_saml_Error if the NameID creation policy is invalid.
  */
 protected function getValue(array &$state)
 {
     if (!isset($state['saml:NameIDFormat']) && !$this->allowUnspecified) {
         SimpleSAML\Logger::debug('SQLPersistentNameID: Request did not specify persistent NameID format, ' . 'not generating persistent NameID.');
         return null;
     }
     $validNameIdFormats = @array_filter(array($state['saml:NameIDFormat'], $state['SPMetadata']['NameIDPolicy'], $state['SPMetadata']['NameIDFormat']));
     if (count($validNameIdFormats) && !in_array($this->format, $validNameIdFormats) && !$this->allowDifferent) {
         SimpleSAML\Logger::debug('SQLPersistentNameID: SP expects different NameID format (' . implode(', ', $validNameIdFormats) . '),  not generating persistent NameID.');
         return null;
     }
     if (!isset($state['Destination']['entityid'])) {
         SimpleSAML\Logger::warning('SQLPersistentNameID: No SP entity ID - not generating persistent NameID.');
         return null;
     }
     $spEntityId = $state['Destination']['entityid'];
     if (!isset($state['Source']['entityid'])) {
         SimpleSAML\Logger::warning('SQLPersistentNameID: No IdP entity ID - not generating persistent NameID.');
         return null;
     }
     $idpEntityId = $state['Source']['entityid'];
     if (!isset($state['Attributes'][$this->attribute]) || count($state['Attributes'][$this->attribute]) === 0) {
         SimpleSAML\Logger::warning('SQLPersistentNameID: Missing attribute ' . var_export($this->attribute, true) . ' on user - not generating persistent NameID.');
         return null;
     }
     if (count($state['Attributes'][$this->attribute]) > 1) {
         SimpleSAML\Logger::warning('SQLPersistentNameID: More than one value in attribute ' . var_export($this->attribute, true) . ' on user - not generating persistent NameID.');
         return null;
     }
     $uid = array_values($state['Attributes'][$this->attribute]);
     // just in case the first index is no longer 0
     $uid = $uid[0];
     $value = sspmod_saml_IdP_SQLNameID::get($idpEntityId, $spEntityId, $uid);
     if ($value !== null) {
         SimpleSAML\Logger::debug('SQLPersistentNameID: Found persistent NameID ' . var_export($value, true) . ' for user ' . var_export($uid, true) . '.');
         return $value;
     }
     if ((!isset($state['saml:AllowCreate']) || !$state['saml:AllowCreate']) && !$this->alwaysCreate) {
         SimpleSAML\Logger::warning('SQLPersistentNameID: Did not find persistent NameID for user, and not allowed to create new NameID.');
         throw new sspmod_saml_Error(SAML2_Const::STATUS_RESPONDER, 'urn:oasis:names:tc:SAML:2.0:status:InvalidNameIDPolicy');
     }
     $value = bin2hex(openssl_random_pseudo_bytes(20));
     SimpleSAML\Logger::debug('SQLPersistentNameID: Created persistent NameID ' . var_export($value, true) . ' for user ' . var_export($uid, true) . '.');
     sspmod_saml_IdP_SQLNameID::add($idpEntityId, $spEntityId, $uid, $value);
     return $value;
 }
Exemplo n.º 25
0
 /**
  * Set the HTTP return code for this error.
  *
  * This should be overridden by subclasses who want a different return code than 500 Internal Server Error.
  */
 protected function setHTTPCode()
 {
     // Some mostly used HTTP codes
     $httpCodesMap = array(400 => 'HTTP/1.0 400 Bad Request', 403 => 'HTTP/1.0 403 Forbidden', 404 => 'HTTP/1.0 404 Not Found', 405 => 'HTTP/1.0 405 Method Not Allowed', 500 => 'HTTP/1.0 500 Internal Server Error', 501 => 'HTTP/1.0 501 Method Not Implemented', 503 => 'HTTP/1.0 503 Service Temporarily Unavailable');
     $httpCode = $this->httpCode;
     if (function_exists('http_response_code')) {
         http_response_code($httpCode);
         return;
     }
     if (!array_key_exists($this->httpCode, $httpCodesMap)) {
         $httpCode = 500;
         SimpleSAML\Logger::warning('HTTP response code not defined: ' . var_export($this->httpCode, true));
     }
     header($httpCodesMap[$httpCode]);
 }
 /**
  * This function lists all known metadata in the given set. It is returned as an associative array
  * where the key is the entity id.
  *
  * @param string $set The set we want to list metadata from.
  *
  * @return array An associative array with the metadata from from the given set.
  */
 public function getList($set = 'saml20-idp-remote')
 {
     assert('is_string($set)');
     $result = array();
     foreach ($this->sources as $source) {
         $srcList = $source->getMetadataSet($set);
         foreach ($srcList as $key => $le) {
             if (array_key_exists('expire', $le)) {
                 if ($le['expire'] < time()) {
                     unset($srcList[$key]);
                     SimpleSAML\Logger::warning("Dropping metadata entity " . var_export($key, true) . ", expired " . SimpleSAML\Utils\Time::generateTimestamp($le['expire']) . ".");
                 }
             }
         }
         /* $result is the last argument to array_merge because we want the content already
          * in $result to have precedence.
          */
         $result = array_merge($srcList, $result);
     }
     return $result;
 }
Exemplo n.º 27
0
 /**
  * Re-authenticate an user.
  *
  * This function is called by the IdP to give the authentication source a chance to
  * interact with the user even in the case when the user is already authenticated.
  *
  * @param array &$state  Information about the current authentication.
  */
 public function reauthenticate(array &$state)
 {
     assert('is_array($state)');
     $session = SimpleSAML_Session::getSessionFromRequest();
     $data = $session->getAuthState($this->authId);
     foreach ($data as $k => $v) {
         $state[$k] = $v;
     }
     // check if we have an IDPList specified in the request
     if (isset($state['saml:IDPList']) && sizeof($state['saml:IDPList']) > 0 && !in_array($state['saml:sp:IdP'], $state['saml:IDPList'], true)) {
         /*
          * The user has an existing, valid session. However, the SP provided a list of IdPs it accepts for
          * authentication, and the IdP the existing session is related to is not in that list.
          *
          * First, check if we recognize any of the IdPs requested.
          */
         $mdh = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
         $known_idps = $mdh->getList();
         $intersection = array_intersect($state['saml:IDPList'], array_keys($known_idps));
         if (empty($intersection)) {
             // all requested IdPs are unknown
             throw new SimpleSAML\Module\saml\Error\NoSupportedIDP(\SAML2\Constants::STATUS_REQUESTER, 'None of the IdPs requested are supported by this proxy.');
         }
         /*
          * We have at least one IdP in the IDPList that we recognize, and it's not the one currently in use. Let's
          * see if this proxy enforces the use of one single IdP.
          */
         if (!is_null($this->idp) && !in_array($this->idp, $intersection)) {
             // an IdP is enforced but not requested
             throw new SimpleSAML\Module\saml\Error\NoAvailableIDP(\SAML2\Constants::STATUS_REQUESTER, 'None of the IdPs requested are available to this proxy.');
         }
         /*
          * We need to inform the user, and ask whether we should logout before starting the authentication process
          * again with a different IdP, or cancel the current SSO attempt.
          */
         SimpleSAML\Logger::warning("Reauthentication after logout is needed. The IdP '{$state['saml:sp:IdP']}' is not in the IDPList " . "provided by the Service Provider '{$state['core:SP']}'.");
         $state['saml:sp:IdPMetadata'] = $this->getIdPMetadata($state['saml:sp:IdP']);
         $state['saml:sp:AuthId'] = $this->authId;
         self::askForIdPChange($state);
     }
 }
 /**
  * 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]);
                 }
             }
         }
     }
 }
Exemplo n.º 29
0
 /**
  * Add a specific type of metadata to an entity.
  *
  * @param string $set The metadata set this metadata comes from.
  * @param array  $metadata The metadata.
  */
 public function addMetadata($set, $metadata)
 {
     assert('is_string($set)');
     assert('is_array($metadata)');
     $this->setExpiration($metadata);
     switch ($set) {
         case 'saml20-sp-remote':
             $this->addMetadataSP20($metadata);
             break;
         case 'saml20-idp-remote':
             $this->addMetadataIdP20($metadata);
             break;
         case 'shib13-sp-remote':
             $this->addMetadataSP11($metadata);
             break;
         case 'shib13-idp-remote':
             $this->addMetadataIdP11($metadata);
             break;
         case 'attributeauthority-remote':
             $this->addAttributeAuthority($metadata);
             break;
         default:
             SimpleSAML\Logger::warning('Unable to generate metadata for unknown type \'' . $set . '\'.');
     }
 }
Exemplo n.º 30
0
 /**
  * Delete all consents.
  *
  * @param string $userId The hash identifying the user at an IdP.
  *
  * @return int Number of consents deleted
  */
 public function deleteAllConsents($userId)
 {
     assert('is_string($userId)');
     $st = $this->_execute('DELETE FROM ' . $this->_table . ' WHERE hashed_user_id = ?', array($userId));
     if ($st === false) {
         return;
     }
     if ($st->rowCount() > 0) {
         SimpleSAML\Logger::debug('consent:Database - Deleted (' . $st->rowCount() . ') consent(s).');
         return $st->rowCount();
     } else {
         SimpleSAML\Logger::warning('consent:Database - Attempted to delete nonexistent consent');
     }
 }