/** * 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)); }
/** * 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 . '.'); } }
public function getAttributes($nameId, $attributes = array()) { // Set up config $config = $this->config; // Setup cURL $url = $this->as_config['api_url'] . '/' . $nameId; $ch = curl_init($url); curl_setopt_array($ch, array(CURLOPT_CUSTOMREQUEST => 'GET', CURLOPT_RETURNTRANSFER => true, CURLOPT_HTTPHEADER => array('Content-Type: application/json'))); // Send the request $response = curl_exec($ch); $http_response = curl_getinfo($ch, CURLINFO_HTTP_CODE); // Check for error; not even redirects are allowed here if ($http_response == 507) { throw new SimpleSAML_Error_Exception("Out of resources: " . $response); } elseif ($response === false || !($http_response >= 200 && $http_response < 300)) { SimpleSAML_Logger::error('[afra] API query failed: HTTP response code: ' . $http_response . ', curl error: "' . curl_error($ch)) . '"'; SimpleSAML_Logger::debug('[afra] API query failed: curl info: ' . var_export(curl_getinfo($ch), 1)); SimpleSAML_Logger::debug('[afra] API query failed: HTTP response: ' . var_export($response, 1)); throw new SimpleSAML_Error_Exception("Error at REST API response: " . $response . $http_response); } else { $data = json_decode($response, true); SimpleSAML_Logger::info('[afra] got reply from API'); SimpleSAML_Logger::debug('[afra] API query url: ' . var_export($url, true)); SimpleSAML_Logger::debug('[afra] API query result: ' . var_export($data, true)); } $attributes = $data['data']; return $attributes; }
protected function _mailTechnicalContact($tag, sspmod_janus_Cron_Logger $logger) { $errorHtml = $this->_getHtmlForMessages($logger->getNamespacedErrors(), 'errors'); $warningHtml = $this->_getHtmlForMessages($logger->getNamespacedWarnings(), 'warnings'); $noticeHtml = $this->_getHtmlForMessages($logger->getNamespacedNotices(), 'notices'); $config = SimpleSAML_Configuration::getInstance(); $time = date(DATE_RFC822); $url = SimpleSAML_Utilities::selfURL(); $message = <<<MESSAGE <h1>Cron report</h1> <p>Cron ran at {$time}</p> <p>URL: <tt>{$url}</tt></p> <p>Tag: {$tag}</p> <h2>Errors</h2> {$errorHtml} <h2>Warnings</h2> {$warningHtml} <h2>Notices</h2> {$noticeHtml} MESSAGE; $toAddress = $config->getString('technicalcontact_email', '*****@*****.**'); if ($toAddress == '*****@*****.**') { SimpleSAML_Logger::error('Cron - Could not send email. [technicalcontact_email] not set in config.'); } else { $email = new SimpleSAML_XHTML_EMail($toAddress, 'JANUS cron report', '*****@*****.**'); $email->setBody($message); $email->send(); } }
public function finalStep(&$state) { $requestToken = unserialize($state['requestToken']); #echo '<pre>'; print_r($requestToken); exit; $consumer = new sspmod_oauth_Consumer($this->key, $this->secret); SimpleSAML_Logger::debug("oauth: Using this request token [" . $requestToken->key . "] with the secret [" . $requestToken->secret . "]"); // Replace the request token with an access token $accessToken = $consumer->getAccessToken('http://twitter.com/oauth/access_token', $requestToken); SimpleSAML_Logger::debug("Got an access token from the OAuth service provider [" . $accessToken->key . "] with the secret [" . $accessToken->secret . "]"); $userdata = $consumer->getUserInfo('http://twitter.com/account/verify_credentials.json', $accessToken); $attributes = array(); foreach ($userdata as $key => $value) { if (is_string($value)) { $attributes['twitter.' . $key] = array((string) $value); } } if (array_key_exists('screen_name', $userdata)) { $attributes['twitter_at_screen_name'] = array('@' . $userdata['screen_name']); $attributes['twitter_screen_n_realm'] = array($userdata['screen_name'] . '@twitter.com'); } if (array_key_exists('id_str', $userdata)) { $attributes['twitter_targetedID'] = array('http://twitter.com!' . $userdata['id_str']); } $state['Attributes'] = $attributes; }
/** * Returns a list of entities with metadata */ public function getSources() { $sourcesDef = $this->aConfig->getArray('sources'); try { $sources = SimpleSAML_Metadata_MetaDataStorageSource::parseSources($sourcesDef); } catch (Exception $e) { throw new Exception('Invalid aggregator source configuration for aggregator ' . var_export($id, TRUE) . ': ' . $e->getMessage()); } #echo $exclude; exit; /* Find list of all available entities. */ $entities = array(); #echo '<pre>'; print_r($this->sets); exit; foreach ($sources as $source) { foreach ($this->sets as $set) { foreach ($source->getMetadataSet($set) as $entityId => $metadata) { if (isset($metadata['tags']) && count(array_intersect($this->excludeTags, $metadata['tags'])) > 0) { SimpleSAML_Logger::debug('Excluding entity ID [' . $entityId . '] becuase it is tagged with one of [' . var_export($this->excludeTags, TRUE) . ']'); continue; } else { #echo('<pre>'); print_r($metadata); exit; } if (!array_key_exists($entityId, $entities)) { $entities[$entityId] = array(); } if (array_key_exists($set, $entities[$entityId])) { /* Entity already has metadata for the given set. */ continue; } $entities[$entityId][$set] = $metadata; } } } return $entities; }
/** * 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; } }
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')); }
public function getAttributes($nameId, $spid, $attributes = array()) { // Generate API key $time = new \DateTime(); date_timezone_set($time, new \DateTimeZone('UTC')); $stamp = $time->format('Y-m-d H:i'); $apiKey = hash('sha256', $this->as_config['hexaa_master_secret'] . $stamp); // Make the call // The data to send to the API $postData = array("apikey" => $apiKey, "fedid" => $nameId, "entityid" => $spid); // Setup cURL $ch = curl_init($this->as_config['hexaa_api_url'] . '/attributes.json'); curl_setopt_array($ch, array(CURLOPT_CUSTOMREQUEST => "POST", CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_HTTPHEADER => array('Content-Type: application/json'), CURLOPT_POSTFIELDS => json_encode($postData), CURLOPT_FOLLOWLOCATION => TRUE, CURLOPT_POSTREDIR => 3)); // Send the request $response = curl_exec($ch); $http_response = curl_getinfo($ch, CURLINFO_HTTP_CODE); // Check for error; not even redirects are allowed here if ($response === FALSE || !($http_response >= 200 && $http_response < 300)) { SimpleSAML_Logger::error('[aa] HEXAA API query failed: HTTP response code: ' . $http_response . ', curl error: "' . curl_error($ch)) . '"'; SimpleSAML_Logger::debug('[aa] HEXAA API query failed: curl info: ' . var_export(curl_getinfo($ch), 1)); SimpleSAML_Logger::debug('[aa] HEXAA API query failed: HTTP response: ' . var_export($response, 1)); $data = array(); } else { $data = json_decode($response, true); SimpleSAML_Logger::info('[aa] got reply from HEXAA API'); SimpleSAML_Logger::debug('[aa] HEXAA API query postData: ' . var_export($postData, TRUE)); SimpleSAML_Logger::debug('[aa] HEXAA API query result: ' . var_export($data, TRUE)); } return $data; }
/** * Determine whether a module is enabled. * * Will return false if the given module doesn't exists. * * @param string $module Name of the module * * @return bool True if the given module is enabled, false otherwise. * * @throws Exception If module.enable is set and is not boolean. */ public static function isModuleEnabled($module) { $moduleDir = self::getModuleDir($module); if (!is_dir($moduleDir)) { return false; } $globalConfig = SimpleSAML_Configuration::getOptionalConfig(); $moduleEnable = $globalConfig->getArray('module.enable', array()); if (isset($moduleEnable[$module])) { if (is_bool($moduleEnable[$module]) === true) { return $moduleEnable[$module]; } throw new Exception("Invalid module.enable value for for the module {$module}"); } if (assert_options(ASSERT_ACTIVE) && !file_exists($moduleDir . '/default-enable') && !file_exists($moduleDir . '/default-disable')) { SimpleSAML_Logger::error("Missing default-enable or default-disable file for the module {$module}"); } if (file_exists($moduleDir . '/enable')) { return true; } if (!file_exists($moduleDir . '/disable') && file_exists($moduleDir . '/default-enable')) { return true; } return false; }
public function finalStep(&$state) { $requestToken = $state['authtwitter:authdata:requestToken']; $parameters = array(); if (!isset($_REQUEST['oauth_token'])) { throw new SimpleSAML_Error_BadRequest("Missing oauth_token parameter."); } if ($requestToken->key !== (string) $_REQUEST['oauth_token']) { throw new SimpleSAML_Error_BadRequest("Invalid oauth_token parameter."); } if (!isset($_REQUEST['oauth_verifier'])) { throw new SimpleSAML_Error_BadRequest("Missing oauth_verifier parameter."); } $parameters['oauth_verifier'] = (string) $_REQUEST['oauth_verifier']; $consumer = new sspmod_oauth_Consumer($this->key, $this->secret); SimpleSAML_Logger::debug("oauth: Using this request token [" . $requestToken->key . "] with the secret [" . $requestToken->secret . "]"); // Replace the request token with an access token $accessToken = $consumer->getAccessToken('https://api.twitter.com/oauth/access_token', $requestToken, $parameters); SimpleSAML_Logger::debug("Got an access token from the OAuth service provider [" . $accessToken->key . "] with the secret [" . $accessToken->secret . "]"); $userdata = $consumer->getUserInfo('https://api.twitter.com/1.1/account/verify_credentials.json', $accessToken); if (!isset($userdata['id_str']) || !isset($userdata['screen_name'])) { throw new SimpleSAML_Error_AuthSource($this->authId, 'Authentication error: id_str and screen_name not set.'); } $attributes = array(); foreach ($userdata as $key => $value) { if (is_string($value)) { $attributes['twitter.' . $key] = array((string) $value); } } $attributes['twitter_at_screen_name'] = array('@' . $userdata['screen_name']); $attributes['twitter_screen_n_realm'] = array($userdata['screen_name'] . '@twitter.com'); $attributes['twitter_targetedID'] = array('http://twitter.com!' . $userdata['id_str']); $state['Attributes'] = $attributes; }
/** * Attempt to log in using the given username and password. * * On a successful login, this function should return the username as 'uid' attribute, * and merged attributes from the configuration file. * On failure, it should throw an exception. A SimpleSAML_Error_Error('WRONGUSERPASS') * should be thrown in case of a wrong username OR a wrong password, to prevent the * enumeration of usernames. * * @param string $username The username the user wrote. * @param string $password The password the user wrote. * @return array Associative array with the users attributes. */ protected function login($username, $password) { assert('is_string($username)'); assert('is_string($password)'); foreach ($this->users as $userpass) { $matches = explode(':', $userpass, 2); if ($matches[0] == $username) { $crypted = $matches[1]; // This is about the only attribute we can add $attributes = array_merge(array('uid' => array($username)), $this->attributes); // Traditional crypt(3) if (crypt($password, $crypted) == $crypted) { SimpleSAML_Logger::debug('User ' . $username . ' authenticated successfully'); return $attributes; } // Apache's custom MD5 if (SimpleSAML_Utils_Crypto::apr1Md5Valid($crypted, $password)) { SimpleSAML_Logger::debug('User ' . $username . ' authenticated successfully'); return $attributes; } // SHA1 or plain-text if (SimpleSAML_Utils_Crypto::pwValid($crypted, $password)) { SimpleSAML_Logger::debug('User ' . $username . ' authenticated successfully'); return $attributes; } throw new SimpleSAML_Error_Error('WRONGUSERPASS'); } } throw new SimpleSAML_Error_Error('WRONGUSERPASS'); }
function driveProcessingChain($idp_metadata, $source, $sp_metadata, $sp_entityid, $attributes, $userid, $hashAttributes = FALSE) { /* * Create a new processing chain */ $pc = new SimpleSAML_Auth_ProcessingChain($idp_metadata, $sp_metadata, 'idp'); /* * Construct the state. * REMEMBER: Do not set Return URL if you are calling processStatePassive */ $authProcState = array('Attributes' => $attributes, 'Destination' => $sp_metadata, 'Source' => $idp_metadata, 'isPassive' => TRUE); /* * Call processStatePAssive. * We are not interested in any user interaction, only modifications to the attributes */ $pc->processStatePassive($authProcState); $attributes = $authProcState['Attributes']; /* * Generate identifiers and hashes */ $destination = $sp_metadata['metadata-set'] . '|' . $sp_entityid; $targeted_id = sspmod_consent_Auth_Process_Consent::getTargetedID($userid, $source, $destination); $attribute_hash = sspmod_consent_Auth_Process_Consent::getAttributeHash($attributes, $hashAttributes); SimpleSAML_Logger::info('consentAdmin: user: '******'consentAdmin: target: ' . $targeted_id); SimpleSAML_Logger::info('consentAdmin: attribute: ' . $attribute_hash); /* Return values */ return array($targeted_id, $attribute_hash, $attributes); }
/** * Log line. * * @param array &$state The current state. */ public function process(&$state) { assert('is_array($state)'); assert('array_key_exists("Attributes", $state)'); $logAttribute = 'NA'; $source = 'NA'; $dest = 'NA'; if (array_key_exists($this->attribute, $state['Attributes'])) { $logAttribute = $state['Attributes'][$this->attribute][0]; } if (array_key_exists('Source', $state)) { if (isset($state['Source']['core:statistics-id'])) { $source = $state['Source']['core:statistics-id']; } else { $source = $state['Source']['entityid']; } } if (array_key_exists('Destination', $state)) { if (isset($state['Destination']['core:statistics-id'])) { $dest = $state['Destination']['core:statistics-id']; } else { $dest = $state['Destination']['entityid']; } } if (!array_key_exists('PreviousSSOTimestamp', $state)) { /* The user hasn't authenticated with this SP earlier in this session. */ SimpleSAML_Logger::stats($this->typeTag . '-first ' . $dest . ' ' . $source . ' ' . $logAttribute); } SimpleSAML_Logger::stats($this->typeTag . ' ' . $dest . ' ' . $source . ' ' . $logAttribute); }
/** * Log-in using Facebook cronus * * @param array &$state Information about the current authentication. */ public function authenticate(&$state) { assert('is_array($state)'); /* We are going to need the authId in order to retrieve this authentication source later. */ $state[self::AUTHID] = $this->authId; $stateID = SimpleSAML_Auth_State::saveState($state, self::STAGE_INIT); SimpleSAML_Logger::debug('facebook auth state id = ' . $stateID); $facebook = new Facebook($this->api_key, $this->secret); $u = $facebook->require_login(SimpleSAML_Module::getModuleUrl('authfacebook') . '/linkback.php?next=' . $stateID); # http://developers.facebook.com/documentation.php?v=1.0&method=users.getInfo /* Causes an notice / warning... if ($facebook->api_client->error_code) { throw new Exception('Unable to load profile from facebook'); } */ // http://developers.facebook.com/docs/reference/rest/users.getInfo $info = $facebook->api_client->users_getInfo($u, array('uid', 'first_name', 'middle_name', 'last_name', 'name', 'locale', 'current_location', 'affiliations', 'pic_square', 'profile_url', 'sex', 'email', 'pic', 'username', 'about_me', 'status', 'profile_blurb')); $attributes = array(); foreach ($info[0] as $key => $value) { if (is_string($value) && !empty($value)) { $attributes['facebook.' . $key] = array((string) $value); } } if (array_key_exists('username', $info[0])) { $attributes['facebook_user'] = array($info[0]['username'] . '@facebook.com'); } else { $attributes['facebook_user'] = array($u . '@facebook.com'); } $attributes['facebook_targetedID'] = array('http://facebook.com!' . $u); $attributes['facebook_cn'] = array($info[0]['name']); SimpleSAML_Logger::debug('Facebook Returned Attributes: ' . implode(", ", array_keys($attributes))); $state['Attributes'] = $attributes; }
/** * Notifies managing contact about updated metadata of entity * * @param sspmod_janus_Entity $entity * @param string $metadataXml * @return void */ protected function _mailUpdatedMetaData(sspmod_janus_Entity $entity, $metadataXml) { $config = SimpleSAML_Configuration::getInstance(); $time = date(DATE_RFC822); $entityName = $entity->getPrettyname(); $entityId = $entity->getEntityId(); $message = <<<MESSAGE <h1>Metadata Change detected</h1> <p>Cron ran at {$time}</p> <p>Name: {$entityName}</p> <p>EntityId: {$entityId}</p> MESSAGE; $toAddress = $config->getString('managingcontact_email'); if (empty($toAddress)) { SimpleSAML_Logger::error('Cron - Could not send email. [managingcontact_email] not set in config.'); } $fromAddress = '*****@*****.**'; $subject = "Metadata Change detected for entity " . $entity->getPrettyname() . " (" . $entity->getEntityId() . "])"; $email = new SimpleSAML_XHTML_EMail($toAddress, $subject, $fromAddress); $email->setBody($message); // Add gzipped metadata $attachmentContent = gzencode($metadataXml); $attachmentFileName = 'metadata-' . $entityName . '.xml.gz'; $email->addAttachment($attachmentContent, $attachmentFileName, 'application/zip'); $email->send(); }
/** * Apply filter to add groups attribute. * * @param array &$request The current request */ public function process(&$request) { assert('is_array($request)'); assert('array_key_exists("Attributes", $request)'); $groups = array(); $attributes =& $request['Attributes']; $realm = self::getRealm($attributes); if ($realm !== NULL) { $groups[] = 'realm-' . $realm; } foreach ($this->generateGroupsFrom as $name) { if (!array_key_exists($name, $attributes)) { SimpleSAML_Logger::debug('GenerateGroups - attribute \'' . $name . '\' not found.'); /* Attribute not present. */ continue; } foreach ($attributes[$name] as $value) { $value = self::escapeIllegalChars($value); $groups[] = $name . '-' . $value; if ($realm !== NULL) { $groups[] = $name . '-' . $realm . '-' . $value; } } } if (count($groups) > 0) { $attributes['groups'] = $groups; } }
/** * Hook to run a cron job. * * @param array &$croninfo Output */ function sanitycheck_hook_cron(&$croninfo) { assert('is_array($croninfo)'); assert('array_key_exists("summary", $croninfo)'); assert('array_key_exists("tag", $croninfo)'); SimpleSAML_Logger::info('cron [sanitycheck]: Running cron in cron tag [' . $croninfo['tag'] . '] '); try { $sconfig = SimpleSAML_Configuration::getOptionalConfig('config-sanitycheck.php'); $cronTag = $sconfig->getString('cron_tag', NULL); if ($cronTag === NULL || $cronTag !== $croninfo['tag']) { return; } $info = array(); $errors = array(); $hookinfo = array('info' => &$info, 'errors' => &$errors); SimpleSAML_Module::callHooks('sanitycheck', $hookinfo); if (count($errors) > 0) { foreach ($errors as $err) { $croninfo['summary'][] = 'Sanitycheck error: ' . $err; } } } catch (Exception $e) { $croninfo['summary'][] = 'Error executing sanity check: ' . $e->getMessage(); } }
function handleResponse() { try { $binding = SAML2_Binding::getCurrentBinding(); $response = $binding->receive(); } catch (Exception $e) { return; } SimpleSAML_Logger::debug('attributequery - received message.'); if (!$response instanceof SAML2_Response) { throw new SimpleSAML_Error_Exception('Unexpected message received to attribute query example.'); } $idpEntityId = $response->getIssuer(); if ($idpEntityId === NULL) { throw new SimpleSAML_Error_Exception('Missing issuer in response.'); } $idpMetadata = $GLOBALS['metadata']->getMetaDataConfig($idpEntityId, 'saml20-idp-remote'); $spMetadata = $GLOBALS['metadata']->getMetaDataConfig($GLOBALS['spEntityId'], 'saml20-sp-hosted'); $assertion = sspmod_saml_Message::processResponse($spMetadata, $idpMetadata, $response); if (count($assertion) > 1) { throw new SimpleSAML_Error_Exception('More than one assertion in received response.'); } $assertion = $assertion[0]; $dataId = $response->getRelayState(); if ($dataId === NULL) { throw new SimpleSAML_Error_Exception('RelayState was lost during request.'); } $data = $GLOBALS['session']->getData('attributequeryexample:data', $dataId); $data['attributes'] = $assertion->getAttributes(); $GLOBALS['session']->setData('attributequeryexample:data', $dataId, $data, 3600); SimpleSAML_Utilities::redirect(SimpleSAML_Utilities::selfURLNoQuery(), array('dataId' => $dataId)); }
public function finalStep(&$state) { $requestToken = unserialize($state['requestToken']); #echo '<pre>'; print_r($requestToken); exit; $consumer = new sspmod_oauth_Consumer($this->key, $this->secret); SimpleSAML_Logger::debug("oauth: Using this request token [" . $requestToken->key . "] with the secret [" . $requestToken->secret . "]"); // Replace the request token with an access token $accessToken = $consumer->getAccessToken('http://twitter.com/oauth/access_token', $requestToken); SimpleSAML_Logger::debug("Got an access token from the OAuth service provider [" . $accessToken->key . "] with the secret [" . $accessToken->secret . "]"); $userdata = $consumer->getUserInfo('http://twitter.com/account/verify_credentials.json', $accessToken); $attributes = array(); foreach ($userdata as $key => $value) { if (is_string($value)) { $attributes[$key] = array((string) $value); } } if (array_key_exists('screen_name', $userdata)) { $attributes['eduPersonPrincipalName'] = array('@' . $userdata['screen_name']); } if (array_key_exists('name', $userdata)) { $attributes['displayName'] = array($userdata['name']); } if (array_key_exists('profile_image_url', $userdata)) { $attributes['jpegPhoto'] = array(base64_encode(file_get_contents($userdata['profile_image_url']))); } if (array_key_exists('url', $userdata)) { $attributes['labeledURI'] = array($userdata['url']); } $state['Attributes'] = $attributes; }
/** * When the process logic determines that the user is not * authorized for this service, then forward the user to * an 403 unauthorized page. * * Separated this code into its own method so that child * classes can override it and change the action. Forward * thinking in case a "chained" ACL is needed, more complex * permission logic. * * @param array $request */ protected function unauthorized(&$request) { SimpleSAML_Logger::error('ExpectedAuthnContextClassRef: Invalid authentication context: ' . $this->AuthnContextClassRef . '. Accepted values are: ' . var_export($this->accepted, true)); $id = SimpleSAML_Auth_State::saveState($request, 'saml:ExpectedAuthnContextClassRef:unauthorized'); $url = SimpleSAML_Module::getModuleURL('saml/sp/wrong_authncontextclassref.php'); \SimpleSAML\Utils\HTTP::redirectTrustedURL($url, array('StateId' => $id)); }
/** * 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; }
public static function receiveAuthnRequest(SimpleSAML_IdP $idp) { try { // accomodate for disfunctional $_GET "windows" slash decoding in PHP $wctx = $_GET['wctx']; foreach (explode('&', $_SERVER['REQUEST_URI']) as $e) { $a = explode('=', $e); if ($a[0] == 'wctx') { $wctx = urldecode($a[1]); } } $requestid = $wctx; $issuer = $_GET['wtrealm']; $requestcache = array('RequestID' => $requestid, 'Issuer' => $issuer, 'RelayState' => $requestid); $spEntityId = $requestcache['Issuer']; $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $spMetadata = $metadata->getMetaDataConfig($spEntityId, 'adfs-sp-remote'); SimpleSAML_Logger::info('ADFS - IdP.prp: Incoming Authentication request: ' . $issuer . ' id ' . $requestid); } catch (Exception $exception) { throw new SimpleSAML_Error_Error('PROCESSAUTHNREQUEST', $exception); } $sessionLostURL = NULL; // TODO? $forceAuthn = FALSE; $isPassive = FALSE; $state = array('Responder' => array('sspmod_adfs_IdP_ADFS', 'sendResponse'), 'SPMetadata' => $spMetadata->toArray(), 'ForceAuthn' => $forceAuthn, 'isPassive' => $isPassive, 'adfs:wctx' => $wctx); $idp->handleAuthenticationRequest($state); }
/** * 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)); }
/** * 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); }
/** * 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. * @return array Associative array with the users attributes. */ protected function login($username, $password) { assert('is_string($username)'); assert('is_string($password)'); $curl_instance = curl_init(); $escPassword = urlencode($password); $escUsername = urlencode($username); $url = $this->privacyideaserver . '/validate/samlcheck?user='******'&pass='******'&realm=' . $this->realm; //throw new Exception("url: ". $url); SimpleSAML_Logger::debug("privacyidea URL:" . $url); curl_setopt($curl_instance, CURLOPT_URL, $url); curl_setopt($curl_instance, CURLOPT_HEADER, TRUE); curl_setopt($curl_instance, CURLOPT_RETURNTRANSFER, TRUE); if ($this->sslverifyhost) { curl_setopt($curl_instance, CURLOPT_SSL_VERIFYHOST, 1); } else { curl_setopt($curl_instance, CURLOPT_SSL_VERIFYHOST, 0); } if ($this->sslverifypeer) { curl_setopt($curl_instance, CURLOPT_SSL_VERIFYPEER, 1); } else { curl_setopt($curl_instance, CURLOPT_SSL_VERIFYPEER, 0); } $response = curl_exec($curl_instance); $header_size = curl_getinfo($curl_instance, CURLINFO_HEADER_SIZE); $body = json_decode(substr($response, $header_size)); $status = True; $value = True; try { $status = $body->result->status; $value = $body->result->value->auth; } catch (Exception $e) { throw new SimpleSAML_Error_BadRequest("We were not able to read the response from the privacyidea server:" . $e); } if (False === $status) { /* We got a valid JSON respnse, but the STATUS is false */ throw new SimpleSAML_Error_BadRequest("Valid JSON response, but some internal error occured in privacyidea server."); } else { /* The STATUS is true, so we need to check the value */ if (False === $value) { throw new SimpleSAML_Error_Error("WRONGUSERPASS"); } } /* status and value are true * We can go on and fill attributes */ /* If we get this far, we have a valid login. */ $attributes = array(); $arr = array("username", "surname", "email", "givenname", "mobile", "phone", "realm", "resolver"); reset($arr); foreach ($arr as $key) { if (array_key_exists($key, $this->attributemap)) { $attributes[$this->attributemap[$key]] = array($body->result->value->attributes->{$key}); } else { $attributes[$key] = array($body->result->value->attributes->{$key}); } } return $attributes; }
function new_access_token($requestToken, $consumer) { SimpleSAML_Logger::info('OAuth new_access_token(' . $requestToken . ',' . $consumer . ')'); $token = new OAuthToken(SimpleSAML_Utilities::generateID(), SimpleSAML_Utilities::generateID()); // SimpleSAML_Logger::info('OAuth new_access_token(' . $requestToken . ',' . $consumer . ',' . $token . ')'); $this->store->set('access', $token->key, $consumer->key, $token, $this->config->getValue('accessTokenDuration', 60 * 60 * 24)); return $token; }
public function serve($entityId) { if (!$this->_loadEntity($entityId)) { SimpleSAML_Logger::debug('No entity found!'); return $this->_sendResponse(); } $this->_checkMetadataValidity(); return $this->_sendResponse(); }
public function log($str) { if ($this->debugOutput) { echo '<p>' . $str; } else { SimpleSAML_Logger::debug($str); } flush(); }
/** * 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.'); } }