コード例 #1
0
ファイル: XML.php プロジェクト: tractorcow/simplesamlphp
 /**
  * This function performs some sanity checks on XML documents, and optionally validates them against their schema
  * if the 'debug.validatexml' option is enabled. A warning will be printed to the log if validation fails.
  *
  * @param string $message The SAML document we want to check.
  * @param string $type The type of document. Can be one of:
  * - 'saml20'
  * - 'saml11'
  * - 'saml-meta'
  *
  * @throws \InvalidArgumentException If $message is not a string or $type is not a string containing one of the
  *     values allowed.
  * @throws \SimpleSAML_Error_Exception If $message contains a doctype declaration.
  *
  * @author Olav Morken, UNINETT AS <*****@*****.**>
  * @author Jaime Perez, UNINETT AS <*****@*****.**>
  */
 public static function checkSAMLMessage($message, $type)
 {
     $allowed_types = array('saml20', 'saml11', 'saml-meta');
     if (!(is_string($message) && in_array($type, $allowed_types))) {
         throw new \InvalidArgumentException('Invalid input parameters.');
     }
     // a SAML message should not contain a doctype-declaration
     if (strpos($message, '<!DOCTYPE') !== false) {
         throw new \SimpleSAML_Error_Exception('XML contained a doctype declaration.');
     }
     $enabled = \SimpleSAML_Configuration::getInstance()->getBoolean('debug.validatexml', null);
     if (!$enabled) {
         return;
     }
     $result = true;
     switch ($type) {
         case 'saml11':
             $result = self::isValid($message, 'oasis-sstc-saml-schema-protocol-1.1.xsd');
             break;
         case 'saml20':
             $result = self::isValid($message, 'saml-schema-protocol-2.0.xsd');
             break;
         case 'saml-meta':
             $result = self::isValid($message, 'saml-schema-metadata-2.0.xsd');
     }
     if ($result !== true) {
         \SimpleSAML_Logger::warning($result);
     }
 }
コード例 #2
0
 /**
  * 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_Utilities::redirectTrustedURL($url, array('StateId' => $id));
 }
コード例 #3
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));
 }
コード例 #4
0
 /**
  * Get the NameID value.
  *
  * @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];
     $secretSalt = SimpleSAML_Utilities::getSecretSalt();
     $uidData = 'uidhashbase' . $secretSalt;
     $uidData .= strlen($idpEntityId) . ':' . $idpEntityId;
     $uidData .= strlen($spEntityId) . ':' . $spEntityId;
     $uidData .= strlen($uid) . ':' . $uid;
     $uidData .= $secretSalt;
     return sha1($uidData);
 }
コード例 #5
0
ファイル: Utilities.php プロジェクト: odin-public/saml2-utils
 /**
  * This function generates a binary string containing random bytes.
  *
  * It will use /dev/urandom if available, and fall back to the builtin mt_rand()-function if not.
  *
  * @param $length  The number of random bytes to return.
  * @return A string of lenght $length with random bytes.
  */
 public static function generateRandomBytes($length, $fallback = TRUE)
 {
     static $fp = NULL;
     assert('is_int($length)');
     if ($fp === NULL) {
         if (file_exists('/dev/urandom')) {
             $fp = fopen('/dev/urandom', 'rb');
         } else {
             $fp = FALSE;
         }
     }
     if ($fp !== FALSE) {
         /* Read random bytes from /dev/urandom. */
         $data = fread($fp, $length);
         if ($data === FALSE) {
             throw new Exception('Error reading random data.');
         }
         if (strlen($data) != $length) {
             SimpleSAML_Logger::warning('Did not get requested number of bytes from random source. Requested (' . $length . ') got (' . strlen($data) . ')');
             if ($fallback) {
                 $data = self::generateRandomBytesMTrand($length);
             } else {
                 throw new Exception('Did not get requested number of bytes from random source. Requested (' . $length . ') got (' . strlen($data) . ')');
             }
         }
     } else {
         /* Use mt_rand to generate $length random bytes. */
         $data = self::generateRandomBytesMTrand($length);
     }
     return $data;
 }
コード例 #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 . '.');
     }
 }
コード例 #7
0
ファイル: Module.php プロジェクト: mrvanes/simplesamlphp
 /**
  * Autoload function for SimpleSAMLphp modules following PSR-0.
  *
  * @param string $className Name of the class.
  * @deprecated This method will be removed in SSP 2.0.
  *
  * TODO: this autoloader should be removed once everything has been migrated to namespaces.
  */
 public static function autoloadPSR0($className)
 {
     $modulePrefixLength = strlen('sspmod_');
     $classPrefix = substr($className, 0, $modulePrefixLength);
     if ($classPrefix !== 'sspmod_') {
         return;
     }
     $modNameEnd = strpos($className, '_', $modulePrefixLength);
     $module = substr($className, $modulePrefixLength, $modNameEnd - $modulePrefixLength);
     $path = explode('_', substr($className, $modNameEnd + 1));
     if (!self::isModuleEnabled($module)) {
         return;
     }
     $file = self::getModuleDir($module) . '/lib/' . join('/', $path) . '.php';
     if (!file_exists($file)) {
         return;
     }
     require_once $file;
     if (!class_exists($className, false)) {
         // the file exists, but the class is not defined. Is it using namespaces?
         $nspath = join('\\', $path);
         if (class_exists('SimpleSAML\\Module\\' . $module . '\\' . $nspath)) {
             // the class has been migrated, create an alias and warn about it
             \SimpleSAML_Logger::warning("The class '{$className}' is now using namespaces, please use 'SimpleSAML\\Module\\{$module}\\" . "{$nspath}' instead.");
             class_alias("SimpleSAML\\Module\\{$module}\\{$nspath}", $className);
         }
     }
 }
コード例 #8
0
 protected function login($username, $password)
 {
     /* Connect to the database. */
     $dsn = 'mysql:host=' . $_ENV["DB_HOST"] . ';dbname=twofactor';
     $username = $_ENV["DB_USER"];
     $password = $_ENV["DB_PASS"];
     $db = new PDO($dsn, $username, $password);
     $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
     /* Ensure that we are operating with UTF-8 encoding.
      * This command is for MySQL. Other databases may need different commands.
      */
     $db->exec("SET NAMES 'utf8'");
     /* With PDO we use prepared statements. This saves us from having to escape
      * the username in the database query.
      */
     $st = $db->prepare('SELECT username, password_hash, full_name FROM userdb WHERE username=:username');
     if (!$st->execute(array('username' => $username))) {
         throw new Exception('Failed to query database for user.');
     }
     /* Retrieve the row from the database. */
     $row = $st->fetch(PDO::FETCH_ASSOC);
     if (!$row) {
         /* User not found. */
         SimpleSAML_Logger::warning('MyAuth: Could not find user ' . var_export($username, TRUE) . '.');
         throw new SimpleSAML_Error_Error('WRONGUSERPASS');
     }
     /* Check the password. */
     if (!$this->checkPassword($row['password_hash'], $password)) {
         /* Invalid password. */
         SimpleSAML_Logger::warning('MyAuth: Wrong password for user ' . var_export($username, TRUE) . '.');
         throw new SimpleSAML_Error_Error('WRONGUSERPASS');
     }
     /* Create the attribute array of the user. */
     $attributes = array('uid' => array($username), 'urn:dk:ddl:borger:displayName' => array($row['full_name']), 'urn:dk:gov:saml:cprNumberIdentifier' => array('0102031AB2'));
 }
コード例 #9
0
ファイル: hook_cron.php プロジェクト: PitcherAG/simplesamlphp
/**
 * 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;
    }
}
コード例 #10
0
/**
 * This function retrieves the logout info with the given ID.
 *
 * @param $id  The identifier of the logout info.
 */
function fetchLogoutInfo($id)
{
    global $session;
    global $logoutInfo;
    $logoutInfo = $session->getData('idplogoutresponsedata', $id);
    if ($logoutInfo === NULL) {
        SimpleSAML_Logger::warning('SAML2.0 - IdP.SingleLogoutService: Lost logout information.');
    }
}
コード例 #11
0
 /**
  * Apply filter to add or replace attributes.
  *
  * Add or replace existing attributes with the configured values.
  *
  * @param array &$request  The current request
  */
 public function process(&$request)
 {
     assert('is_array($request)');
     assert('array_key_exists("Attributes", $request)');
     SimpleSAML_Logger::warning('You are using the deprecated smartnameattribute:SmartName filter. You should replace it with smartattributes:SmartName instead.');
     $attributes =& $request['Attributes'];
     $fullname = $this->getFullName($attributes);
     if (isset($fullname)) {
         $request['Attributes']['smartname-fullname'] = array($fullname);
     }
 }
コード例 #12
0
ファイル: CDC.php プロジェクト: tractorcow/simplesamlphp
 /**
  * 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);
 }
コード例 #13
0
 /**
  * Get the NameID value.
  *
  * @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;
 }
コード例 #14
0
 /**
  * This function is used to find an existing storage object. It will return NULL if no storage object
  * with the given id is found.
  *
  * @param $id  The id of the storage object we are looking for. A id consists of lowercase
  *             alphanumeric characters.
  * @return The corresponding MemcacheStorage object if the data is found or NULL if it isn't found.
  */
 public static function find($id)
 {
     assert(self::isValidID($id));
     $serializedData = SimpleSAML_Memcache::get($id);
     if ($serializedData === NULL) {
         return NULL;
     }
     $data = unserialize($serializedData);
     if (!$data instanceof self) {
         SimpleSAML_Logger::warning('Retrieved key from memcache did not contain a MemcacheStore object.');
         return NULL;
     }
     return $data;
 }
コード例 #15
0
ファイル: PHP.php プロジェクト: kensnyder/simplesamlphp
 /**
  * Initialize this filter, parse configuration
  *
  * @param array $config Configuration information about this filter.
  * @param mixed $reserved For future use.
  */
 public function __construct($config, $reserved)
 {
     parent::__construct($config, $reserved);
     assert('is_array($config)');
     if (isset($config['function'])) {
         $this->function = $config['function'];
     } else {
         // TODO: remove this branch after removing the 'code' option.
         if (!isset($config['code'])) {
             throw new SimpleSAML_Error_Exception("core:PHP: Neither 'function' nor 'code' options defined.");
         }
         SimpleSAML_Logger::warning("Deprecated 'code' configuration option in PHP authentication processing filter.");
         $this->code = (string) $config['code'];
     }
 }
コード例 #16
0
ファイル: LDAPMulti.php プロジェクト: PitcherAG/simplesamlphp
 /**
  * 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);
 }
コード例 #17
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
    }
    $path = explode('_', $class);
    $new = join('\\', $path);
    if (class_exists($new, false)) {
        SimpleSAML_Logger::warning("The class '{$class}' is now using namespaces, please use '{$new}'.");
        class_alias($new, $class);
    }
    $file = dirname(__FILE__) . DIRECTORY_SEPARATOR . join(DIRECTORY_SEPARATOR, $path) . '.php';
    if (file_exists($file)) {
        require_once $file;
    }
}
コード例 #18
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);
 }
コード例 #19
0
 /**
  * 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 = new DOMDocument();
         $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);
 }
コード例 #20
0
 /**
  * Get the NameID value.
  *
  * @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;
     }
     $spEntityId = $state['Destination']['entityid'];
     if (!isset($state['Source']['entityid'])) {
         SimpleSAML_Logger::warning('No IdP entity ID - not generating persistent NameID.');
         return;
     }
     $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;
     }
     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;
     }
     $uid = array_values($state['Attributes'][$this->attribute]);
     /* Just in case the first index is no longer 0. */
     $uid = $uid[0];
     $secretSalt = SimpleSAML_Utilities::getSecretSalt();
     $uidData = $spEntityId . '!' . $uid . '!' . $secretSalt;
     $uid = base64_encode(hash('sha1', $uidData, true));
     // Convert the targeted ID to a SAML 2.0 name identifier element.
     $nameId = array('Format' => SAML2_Const::NAMEID_PERSISTENT, 'Value' => $uid);
     if (isset($state['Source']['entityid'])) {
         $nameId['NameQualifier'] = $state['Source']['entityid'];
     }
     if (isset($state['Destination']['entityid'])) {
         $nameId['SPNameQualifier'] = $state['Destination']['entityid'];
     }
     $doc = new DOMDocument();
     $root = $doc->createElement('root');
     $doc->appendChild($root);
     SAML2_Utils::addNameId($root, $nameId);
     $uid = $doc->saveXML($root->firstChild);
     $state['Attributes']['eduPersonTargetedID'] = array($uid);
 }
コード例 #21
0
 /**
  * Get the NameID value.
  *
  * @return string|NULL  The NameID value.
  */
 protected function getValue(array &$state)
 {
     if (!isset($state['saml:NameIDFormat']) || $state['saml:NameIDFormat'] !== $this->format) {
         SimpleSAML_Logger::debug('SQLPersistentNameID: Request did not specify persistent NameID format -  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']) {
         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 = SimpleSAML_Utilities::stringToHex(SimpleSAML_Utilities::generateRandomBytes(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;
 }
コード例 #22
0
ファイル: hook_cron.php プロジェクト: PitcherAG/simplesamlphp
/**
 * 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;
    }
}
コード例 #23
0
ファイル: SSOService.php プロジェクト: hukumonline/yii
/**
 * Helper function for handling exception/errors.
 *
 * This function will send an error response to the SP which contacted this IdP.
 *
 * @param Exception $exception  The exception.
 */
function handleError(Exception $exception)
{
    global $requestcache, $config, $metadata, $idpentityid;
    assert('is_array($requestcache)');
    assert('array_key_exists("Issuer", $requestcache)');
    $issuer = $requestcache['Issuer'];
    if (array_key_exists('RequestID', $requestcache)) {
        $requestID = $requestcache['RequestID'];
    } else {
        $requestID = NULL;
    }
    if (array_key_exists('RelayState', $requestcache)) {
        $relayState = $requestcache['RelayState'];
    } else {
        $relayState = NULL;
    }
    $error = sspmod_saml2_Error::fromException($exception);
    SimpleSAML_Logger::warning('Returning error to sp: ' . var_export($issuer, TRUE));
    $error->logWarning();
    try {
        $idpMetadata = $metadata->getMetaDataConfig($idpentityid, 'saml20-idp-hosted');
        $spMetadata = $metadata->getMetaDataConfig($issuer, 'saml20-sp-remote');
        if (array_key_exists('ConsumerURL', $requestcache)) {
            $consumerURL = $requestcache['ConsumerURL'];
        } else {
            $urlArray = $spMetadata->getArrayizeString('AssertionConsumerService');
            $consumerURL = $urlArray[0];
        }
        $ar = sspmod_saml2_Message::buildResponse($idpMetadata, $spMetadata, $consumerURL);
        $ar->setInResponseTo($requestID);
        $ar->setRelayState($relayState);
        $ar->setStatus(array('Code' => $error->getStatus(), 'SubCode' => $error->getSubStatus(), 'Message' => $error->getStatusMessage()));
        $binding = new SAML2_HTTPPost();
        $binding->setDestination(sspmod_SAML2_Message::getDebugDestination());
        $binding->send($ar);
    } catch (Exception $e) {
        SimpleSAML_Utilities::fatalError($session->getTrackID(), 'GENERATEAUTHNRESPONSE', $e);
    }
}
コード例 #24
0
 public static function redirectUri($url)
 {
     /* Set the HTTP result code. This is either 303 See Other or
      * 302 Found. HTTP 303 See Other is sent if the HTTP version
      * is HTTP/1.1 and the request type was a POST request.
      */
     if ($_SERVER['SERVER_PROTOCOL'] === 'HTTP/1.1' && $_SERVER['REQUEST_METHOD'] === 'POST') {
         $code = 303;
     } else {
         $code = 302;
     }
     if (strlen($url) > 2048) {
         SimpleSAML_Logger::warning('Redirecting to a URL longer than 2048 bytes.');
     }
     /* Set the location header. */
     header('Location: ' . $url, true, $code);
     /* Disable caching of this response. */
     header('Pragma: no-cache');
     header('Cache-Control: no-cache, must-revalidate');
     /* Show a minimal web page with a clickable link to the URL. */
     echo '<?xml version="1.0" encoding="UTF-8"?>' . "\n";
     echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"' . ' "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">' . "\n";
     echo '<html xmlns="http://www.w3.org/1999/xhtml">';
     echo '<head>
   					<meta http-equiv="content-type" content="text/html; charset=utf-8">
   					<title>Redirect</title>
   				</head>';
     echo '<body>';
     echo '<h1>Redirect</h1>';
     echo '<p>';
     echo 'You were redirected to: ';
     echo '<a id="redirlink" href="' . htmlspecialchars($url) . '">' . htmlspecialchars($url) . '</a>';
     echo '<script type="text/javascript">document.getElementById("redirlink").focus();</script>';
     echo '</p>';
     echo '</body>';
     echo '</html>';
     /* End script execution. */
     exit;
 }
コード例 #25
0
ファイル: hook_cron.php プロジェクト: PitcherAG/simplesamlphp
/**
 * 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;
    }
}
コード例 #26
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).
  */
 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.');
     }
     // sanitize the input
     $sid = SimpleSAML_Utilities::parseStateID($relayState);
     if (!is_null($sid['url'])) {
         SimpleSAML_Utilities::checkURLAllowed($sid['url']);
     }
     $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);
 }
 /**
  * Initialize this filter, parse configuration.
  *
  * @param array $config Configuration information about this filter.
  * @param mixed $reserved For future use.
  * @throws SimpleSAML_Error_Exception
  */
 public function __construct($config, $reserved)
 {
     parent::__construct($config, $reserved);
     assert('is_array($config)');
     foreach ($config as $origName => $newName) {
         if (is_int($origName)) {
             switch ($newName) {
                 case '%replace':
                     $this->replace = true;
                     break;
                 case '%ignore':
                     $this->ignore = true;
                     break;
                 case '%skipsource':
                 case '%sourceskip':
                     array_push($this->skip, 'Source');
                     break;
                 case '%skipdest':
                 case '%destskip':
                     array_push($this->skip, 'Destination');
                     break;
                 default:
                     /* might want to make this handle loadable maps, a`la core:AttributeMap */
             }
         } elseif (is_string($origName)) {
             $this->map[$origName] = $newName;
         } else {
             throw new SimpleSAML_Error_Exception('AttributeFromEntity: invalid config object, cannot create map');
         }
     }
     if ($this->replace and $this->ignore) {
         SimpleSAML_Logger::warning('AttributeFromEntity: %replace and %ignore are mutually exclusive, behaving as though only %replace was given.');
     }
     if (count($this->map) === 0) {
         throw new SimpleSAML_Error_Exception('AttributeFromEntity: attribute map is empty. Config error?');
     }
 }
コード例 #28
0
ファイル: SP.php プロジェクト: hukumonline/yii
 /**
  * Constructor for SAML 2.0 SP authentication source.
  *
  * @param array $info  Information about this authentication source.
  * @param array $config  Configuration.
  */
 public function __construct($info, $config)
 {
     assert('is_array($info)');
     assert('is_array($config)');
     /* Call the parent constructor first, as required by the interface. */
     parent::__construct($info, $config);
     /* For compatibility with code that assumes that $metadata->getString('entityid') gives the entity id. */
     if (array_key_exists('entityId', $config)) {
         $config['entityid'] = $config['entityId'];
     } else {
         $config['entityid'] = SimpleSAML_Module::getModuleURL('saml2/sp/metadata.php?source=' . urlencode($this->authId));
     }
     /* For backwards-compatibility with configuration in saml20-sp-hosted. */
     try {
         $metadataHandler = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler();
         $oldMetadata = $metadataHandler->getMetaData($config['entityid'], 'saml20-sp-hosted');
         SimpleSAML_Logger::warning('Depreceated metadata for ' . var_export($config['entityid'], TRUE) . ' in saml20-sp-hosted. The metadata in should be moved into authsources.php.');
         $config = array_merge($oldMetadata, $config);
     } catch (Exception $e) {
     }
     $this->metadata = SimpleSAML_Configuration::loadFromArray($config, 'authsources[' . var_export($this->authId, TRUE) . ']');
     $this->entityId = $this->metadata->getString('entityid');
     $this->idp = $this->metadata->getString('idp', NULL);
 }
コード例 #29
0
ファイル: State.php プロジェクト: hukumonline/yii
 /**
  * Retrieve saved state.
  *
  * This function retrieves saved state information. If the state information has been lost,
  * it will attempt to restart the request by calling the restart URL which is embedded in the
  * state information. If there is no restart information available, an exception will be thrown.
  *
  * @param string $id  State identifier (with embedded restart information).
  * @param string $stage  The stage the state should have been saved in.
  * @return array  State information.
  */
 public static function loadState($id, $stage)
 {
     assert('is_string($id)');
     assert('is_string($stage)');
     $tmp = explode(':', $id, 2);
     $id = $tmp[0];
     if (count($tmp) === 2) {
         $restartURL = $tmp[1];
     } else {
         $restartURL = NULL;
     }
     $session = SimpleSAML_Session::getInstance();
     $state = $session->getData('SimpleSAML_Auth_State', $id);
     if ($state === NULL) {
         /* Could not find saved data. Attempt to restart. */
         if ($restartURL === NULL) {
             throw new Exception('State information lost, and no way to restart the request.');
         }
         SimpleSAML_Utilities::redirect($restartURL);
     }
     $state = unserialize($state);
     assert('is_array($state)');
     assert('array_key_exists(self::ID, $state)');
     assert('array_key_exists(self::STAGE, $state)');
     /* Verify stage. */
     if ($state[self::STAGE] !== $stage) {
         /* This could be a user trying to bypass security, but most likely it is just
          * someone using the back-button in the browser. We try to restart the
          * request if that is possible. If not, show an error.
          */
         $msg = 'Wrong stage in state. Was \'' . $state[self::STAGE] . '\', shoud be \'' . $stage . '\'.';
         SimpleSAML_Logger::warning($msg);
         if ($restartURL === NULL) {
             throw new Exception($msg);
         }
         SimpleSAML_Utilities::redirect($restartURL);
     }
     return $state;
 }
コード例 #30
0
ファイル: LDAP.php プロジェクト: danielkjfrog/docker
 /**
  * Search a given DN for attributes, and return the resulting associative
  * array.
  *
  * @param string $dn
  * The DN of an element.
  * @param string|array $attributes
  * The names of the attribute(s) to retrieve. Defaults to NULL; that is,
  * all available attributes. Note that this is not very effective.
  * @param int $maxsize
  * The maximum size of any attribute's value(s). If exceeded, the attribute
  * will not be returned.
  * @return array
  * The array of attributes and their values.
  * @see http://no.php.net/manual/en/function.ldap-read.php
  */
 public function getAttributes($dn, $attributes = NULL, $maxsize = NULL)
 {
     // Preparations, including a pretty debug message...
     $description = 'all attributes';
     if (is_array($attributes)) {
         $description = '\'' . join(',', $attributes) . '\'';
     } else {
         // Get all attributes...
         // TODO: Verify that this originally was the intended behaviour. Could $attributes be a string?
         $attributes = array();
     }
     SimpleSAML_Logger::debug('Library - LDAP getAttributes(): Getting ' . $description . ' from DN \'' . $dn . '\'');
     // Attempt to get attributes.
     // TODO: Should aliases be dereferenced?
     $result = @ldap_read($this->ldap, $dn, 'objectClass=*', $attributes, 0, 0, $this->timeout);
     if ($result === false) {
         throw $this->makeException('Library - LDAP getAttributes(): Failed to get attributes from DN \'' . $dn . '\'');
     }
     $entry = @ldap_first_entry($this->ldap, $result);
     if ($entry === false) {
         throw $this->makeException('Library - LDAP getAttributes(): Could not get first entry from DN \'' . $dn . '\'');
     }
     $attributes = @ldap_get_attributes($this->ldap, $entry);
     // Recycling $attributes... Possibly bad practice.
     if ($attributes === false) {
         throw $this->makeException('Library - LDAP getAttributes(): Could not get attributes of first entry from DN \'' . $dn . '\'');
     }
     // Parsing each found attribute into our result set.
     $result = array();
     // Recycling $result... Possibly bad practice.
     for ($i = 0; $i < $attributes['count']; $i++) {
         // Ignore attributes that exceed the maximum allowed size.
         $name = $attributes[$i];
         $attribute = $attributes[$name];
         // Deciding whether to base64 encode.
         $values = array();
         for ($j = 0; $j < $attribute['count']; $j++) {
             $value = $attribute[$j];
             if (!empty($maxsize) && strlen($value) >= $maxsize) {
                 // Ignoring and warning.
                 SimpleSAML_Logger::warning('Library - LDAP getAttributes(): Attribute \'' . $name . '\' exceeded maximum allowed size by ' + ($maxsize - strlen($value)));
                 continue;
             }
             // Base64 encode jpegPhoto.
             if (strtolower($name) === 'jpegphoto') {
                 $values[] = base64_encode($value);
             } else {
                 $values[] = $value;
             }
         }
         // Adding.
         $result[$name] = $values;
     }
     // We're done.
     SimpleSAML_Logger::debug('Library - LDAP getAttributes(): Found attributes \'(' . join(',', array_keys($result)) . ')\'');
     return $result;
 }