An exception will be thrown if this option isn't a string, or if this option isn't found, and no default value
is given.
public getString ( string $name, mixed $default = self::REQUIRED_OPTION ) : string | mixed | ||
$name | string | The name of the option. |
$default | mixed | A default value which will be returned if the option isn't found. The option will be required if this parameter isn't given. The default value can be any value, including null. |
Результат | string | mixed | The option with the given name, or $default if the option isn't found and $default is specified. |
/** * Constructor * * @param \SimpleSAML_Configuration $configuration Configuration object */ public function __construct(\SimpleSAML_Configuration $configuration) { $this->configuration = $configuration; $this->localeDir = $this->configuration->resolvePath('locales'); $this->language = new Language($configuration); $this->langcode = $this->language->getPosixLanguage($this->language->getLanguage()); $this->i18nBackend = $this->configuration->getString('language.i18n.backend', self::SSP_I18N_BACKEND); $this->setupL10N(); }
/** * Check that the user has access to the statistics. * * If the user doesn't have access, send the user to the login page. */ public static function checkAccess(SimpleSAML_Configuration $statconfig) { $protected = $statconfig->getBoolean('protected', FALSE); $authsource = $statconfig->getString('auth', NULL); $allowedusers = $statconfig->getValue('allowedUsers', NULL); $useridattr = $statconfig->getString('useridattr', 'eduPersonPrincipalName'); $acl = $statconfig->getValue('acl', NULL); if ($acl !== NULL && !is_string($acl) && !is_array($acl)) { throw new SimpleSAML_Error_Exception('Invalid value for \'acl\'-option. Should be an array or a string.'); } if (!$protected) { return; } if (SimpleSAML\Utils\Auth::isAdmin()) { // User logged in as admin. OK. SimpleSAML_Logger::debug('Statistics auth - logged in as admin, access granted'); return; } if (!isset($authsource)) { // If authsource is not defined, init admin login. SimpleSAML\Utils\Auth::requireAdmin(); } /* We are using an authsource for login. */ $as = new SimpleSAML_Auth_Simple($authsource); $as->requireAuth(); // User logged in with auth source. SimpleSAML_Logger::debug('Statistics auth - valid login with auth source [' . $authsource . ']'); // Retrieving attributes $attributes = $as->getAttributes(); if (!empty($allowedusers)) { // Check if userid exists if (!isset($attributes[$useridattr][0])) { throw new Exception('User ID is missing'); } // Check if userid is allowed access.. if (in_array($attributes[$useridattr][0], $allowedusers)) { SimpleSAML_Logger::debug('Statistics auth - User granted access by user ID [' . $attributes[$useridattr][0] . ']'); return; } SimpleSAML_Logger::debug('Statistics auth - User denied access by user ID [' . $attributes[$useridattr][0] . ']'); } else { SimpleSAML_Logger::debug('Statistics auth - no allowedUsers list.'); } if (!is_null($acl)) { $acl = new sspmod_core_ACL($acl); if ($acl->allows($attributes)) { SimpleSAML_Logger::debug('Statistics auth - allowed access by ACL.'); return; } SimpleSAML_Logger::debug('Statistics auth - denied access by ACL.'); } else { SimpleSAML_Logger::debug('Statistics auth - no ACL configured.'); } throw new SimpleSAML_Error_Exception('Access denied to the current user.'); }
/** * Initializes this discovery service. * * The constructor does the parsing of the request. If this is an invalid request, it will throw an exception. * * @param array $metadataSets Array with metadata sets we find remote entities in. * @param string $instance The name of this instance of the discovery service. */ public function __construct(array $metadataSets, $instance) { parent::__construct($metadataSets, $instance); $this->discoconfig = SimpleSAML_Configuration::getConfig('module_discopower.php'); $this->cdcDomain = $this->discoconfig->getString('cdc.domain', null); if ($this->cdcDomain !== null && $this->cdcDomain[0] !== '.') { // ensure that the CDC domain starts with a dot ('.') as required by the spec $this->cdcDomain = '.' . $this->cdcDomain; } $this->cdcLifetime = $this->discoconfig->getInteger('cdc.lifetime', null); }
/** * Constructor * * @param \SimpleSAML_Configuration $configuration Configuration object */ public function __construct(\SimpleSAML_Configuration $configuration) { $this->configuration = $configuration; $this->availableLanguages = $this->configuration->getArray('language.available', array('en')); $this->defaultLanguage = $this->configuration->getString('language.default', 'en'); $this->languageParameterName = $this->configuration->getString('language.parameter.name', 'language'); $this->customFunction = $this->configuration->getArray('language.get_language_function', null); $this->rtlLanguages = $this->configuration->getArray('language.rtl', array()); if (isset($_GET[$this->languageParameterName])) { $this->setLanguage($_GET[$this->languageParameterName], $this->configuration->getBoolean('language.parameter.setcookie', true)); } }
/** * Initialize this EntitySource. * * @param SimpleSAML_Configuration $config The configuration. */ public function __construct(sspmod_aggregator2_Aggregator $aggregator, SimpleSAML_Configuration $config) { $this->logLoc = 'aggregator2:' . $aggregator->getId() . ': '; $this->aggregator = $aggregator; $this->url = $config->getString('url'); $this->sslCAFile = $config->getString('ssl.cafile', NULL); if ($this->sslCAFile === NULL) { $this->sslCAFile = $aggregator->getCAFile(); } $this->certificate = $config->getString('cert', NULL); $this->cacheId = sha1($this->url); $this->cacheTag = sha1(serialize($config)); }
private static function enrichForDecryptionProvider(SimpleSAML_Configuration $configuration, array &$baseConfiguration) { if ($configuration->has('sharedKey')) { $baseConfiguration['sharedKey'] = $configuration->getString('sharedKey', NULL); } if ($configuration->has('new_privatekey')) { $baseConfiguration['privateKeys'][] = new SAML2_Configuration_PrivateKey($configuration->getString('new_privatekey'), SAML2_Configuration_PrivateKey::NAME_NEW, $configuration->getString('new_privatekey_pass', NULL)); } if ($configuration->getBoolean('assertion.encryption', FALSE)) { $baseConfiguration['privateKeys'][] = new SAML2_Configuration_PrivateKey($configuration->getString('privatekey'), SAML2_Configuration_PrivateKey::NAME_DEFAULT, $configuration->getString('privatekey_pass', NULL)); if ($configuration->has('encryption.blacklisted-algorithms')) { $baseConfiguration['blacklistedEncryptionAlgorithms'] = $configuration->get('encryption.blacklisted-algorithms'); } } }
/** * Build a new logging handler based on files. */ public function __construct(\SimpleSAML_Configuration $config) { // get the metadata handler option from the configuration $this->logFile = $config->getPathValue('loggingdir', 'log/') . $config->getString('logging.logfile', 'simplesamlphp.log'); $this->processname = $config->getString('logging.processname', 'SimpleSAMLphp'); if (@file_exists($this->logFile)) { if (!@is_writeable($this->logFile)) { throw new \Exception("Could not write to logfile: " . $this->logFile); } } else { if (!@touch($this->logFile)) { throw new \Exception("Could not create logfile: " . $this->logFile . " The logging directory is not writable for the web server user."); } } \SimpleSAML\Utils\Time::initTimezone(); }
/** * Subscribe to an address * * @param int $uid Uid of user * @param string $subscription The address to subscribe * @param string $type Type of subscription * * @return bool Return true on success and false on error */ public function subscribe($uid, $subscription, $type = null) { if (is_null($type)) { $type = $this->_config->getString('messenger.default', 'INBOX'); } // Check if subscription already exists $st = self::execute('SELECT * FROM `' . self::$prefix . 'subscription` WHERE `uid` = ? AND `subscription` = ?', array($uid, $subscription)); if ($st === false) { return false; } if ($st->rowCount() > 0) { return false; } // Insert new subscription $st = self::execute('INSERT INTO `' . self::$prefix . 'subscription` (`uid`, `subscription`, `type`, `created`, `ip`) VALUES (?, ?, ?, ?, ?);', array($uid, $subscription, $type, date('c'), $_SERVER['REMOTE_ADDR'])); if ($st === false) { SimpleSAML_Logger::error('JANUS: Error fetching all entities'); return false; } return self::$db->lastInsertId(); }
/** * Create an output from a configuration object. * * @param SimpleSAML_Configuration $config The configuration object. * @return */ private static function createOutput(SimpleSAML_Configuration $config) { $cls = $config->getString('class'); $cls = SimpleSAML_Module::resolveClass($cls, 'Stats_Output', 'SimpleSAML_Stats_Output'); $output = new $cls($config); return $output; }
/** * Initialize the output. * * @param SimpleSAML_Configuration $config The configuration for this output. */ public function __construct(SimpleSAML_Configuration $config) { $logLevel = $config->getString('level', 'notice'); $this->logger = array('SimpleSAML_Logger', $logLevel); if (!is_callable($this->logger)) { throw new Exception('Invalid log level: ' . var_export($logLevel, TRUE)); } }
/** * Create new entity with parsed entityid * * Create a new entity and give the user access to the entity. * * @param string $entityid Entity id for the new entity * @param string $type Entity type * * @return sspmod_janus_Entity|bool Returns the entity or false on error. * @since Method available since Release 1.0.0 */ public function createNewEntity($entityid, $type) { assert('is_string($entityid)'); assert('is_string($type)'); if ($this->isEntityIdInUse($entityid, $errorMessage)) { return $errorMessage; } if ($this->hasEntityIdBeenUsed($entityid, $errorMessage)) { return $errorMessage; } $startstate = $this->_config->getString('workflowstate.default'); // Get the default ARP $default_arp = '0'; $st = $this->execute("SELECT aid FROM " . self::$prefix . "arp WHERE is_default = TRUE AND deleted = ''"); if ($st) { $rows = $st->fetchAll(); if (count($rows) === 1) { $default_arp = $rows[0]['aid']; } } // Instantiate a new entity $entity = new sspmod_janus_Entity($this->_config, true); $entity->setEntityid($entityid); $entity->setWorkflow($startstate); $entity->setType($type); $entity->setArp($default_arp); $entity->setUser($this->_user->getUid()); $entity->setRevisionnote('Entity created.'); $entity->save(); $st = $this->execute('INSERT INTO ' . self::$prefix . 'hasEntity (`uid`, `eid`, `created`, `ip`) VALUES (?, ?, ?, ?);', array($this->_user->getUid(), $entity->getEid(), date('c'), $_SERVER['REMOTE_ADDR'])); if ($st === false) { return 'error_db'; } $ec = new sspmod_janus_EntityController($this->_config); $ec->setEntity($entity); $update = false; // Get metadatafields for new type $nm_mb = new sspmod_janus_MetadatafieldBuilder($this->_config->getArray('metadatafields.' . $type)); $metadatafields = $nm_mb->getMetadatafields(); // Add all required fileds foreach ($metadatafields as $mf) { if (isset($mf->required) && $mf->required === true) { $ec->addMetadata($mf->name, $mf->default); $update = true; } } if ($update === true) { $ec->saveEntity(); } // Reset list of entities $this->_entities = null; $this->_loadEntities(); return $entity->getEid(); }
/** * Build a new logging handler based on syslog. */ public function __construct(\SimpleSAML_Configuration $config) { $facility = $config->getInteger('logging.facility', defined('LOG_LOCAL5') ? constant('LOG_LOCAL5') : LOG_USER); $processname = $config->getString('logging.processname', 'SimpleSAMLphp'); // Setting facility to LOG_USER (only valid in Windows), enable log level rewrite on windows systems if (System::getOS() === System::WINDOWS) { $this->isWindows = true; $facility = LOG_USER; } openlog($processname, LOG_PID, $facility); }
/** * Receive a SAML 2 message sent using the HTTP-Artifact binding. * * Throws an exception if it is unable receive the message. * * @return SAML2_Message The received message. * @throws Exception */ public function receive() { if (array_key_exists('SAMLart', $_REQUEST)) { $artifact = base64_decode($_REQUEST['SAMLart']); $endpointIndex = bin2hex(substr($artifact, 2, 2)); $sourceId = bin2hex(substr($artifact, 4, 20)); } else { throw new Exception('Missing SAMLArt parameter.'); } $metadataHandler = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $idpMetadata = $metadataHandler->getMetaDataConfigForSha1($sourceId, 'saml20-idp-remote'); if ($idpMetadata === NULL) { throw new Exception('No metadata found for remote provider with SHA1 ID: ' . var_export($sourceId, TRUE)); } $endpoint = NULL; foreach ($idpMetadata->getEndpoints('ArtifactResolutionService') as $ep) { if ($ep['index'] === hexdec($endpointIndex)) { $endpoint = $ep; break; } } if ($endpoint === NULL) { throw new Exception('No ArtifactResolutionService with the correct index.'); } SAML2_Utils::getContainer()->getLogger()->debug("ArtifactResolutionService endpoint being used is := " . $endpoint['Location']); //Construct the ArtifactResolve Request $ar = new SAML2_ArtifactResolve(); /* Set the request attributes */ $ar->setIssuer($this->spMetadata->getString('entityid')); $ar->setArtifact($_REQUEST['SAMLart']); $ar->setDestination($endpoint['Location']); require_once realpath(__DIR__ . '/../../../simplesamlphp/modules/saml/lib/Message.php'); /* Sign the request */ sspmod_saml_Message::addSign($this->spMetadata, $idpMetadata, $ar); // Shoaib - moved from the SOAPClient. $soap = new SAML2_SOAPClient(); // Send message through SoapClient /** @var SAML2_ArtifactResponse $artifactResponse */ $artifactResponse = $soap->send($ar, $this->spMetadata); if (!$artifactResponse->isSuccess()) { return false; } $xml = $artifactResponse->getAny(); if ($xml === NULL) { /* Empty ArtifactResponse - possibly because of Artifact replay? */ return NULL; } $samlResponse = SAML2_Message::fromXML($xml); $samlResponse->addValidator(array(get_class($this), 'validateSignature'), $artifactResponse); if (isset($_REQUEST['RelayState'])) { $samlResponse->setRelayState($_REQUEST['RelayState']); } return $samlResponse; }
/** * Initialize an IdP. * * @param string $id The identifier of this IdP. */ private function __construct($id) { assert('is_string($id)'); $this->id = $id; $metadata = SimpleSAML_Metadata_MetaDataStorageHandler::getMetadataHandler(); $globalConfig = SimpleSAML_Configuration::getInstance(); if (substr($id, 0, 6) === 'saml2:') { if (!$globalConfig->getBoolean('enable.saml20-idp', FALSE)) { throw new SimpleSAML_Error_Exception('enable.saml20-idp disabled in config.php.'); } $this->config = $metadata->getMetaDataConfig(substr($id, 6), 'saml20-idp-hosted'); } elseif (substr($id, 0, 6) === 'saml1:') { if (!$globalConfig->getBoolean('enable.shib13-idp', FALSE)) { throw new SimpleSAML_Error_Exception('enable.shib13-idp disabled in config.php.'); } $this->config = $metadata->getMetaDataConfig(substr($id, 6), 'shib13-idp-hosted'); } elseif (substr($id, 0, 5) === 'adfs:') { if (!$globalConfig->getBoolean('enable.adfs-idp', FALSE)) { throw new SimpleSAML_Error_Exception('enable.adfs-idp disabled in config.php.'); } $this->config = $metadata->getMetaDataConfig(substr($id, 5), 'adfs-idp-hosted'); try { /* This makes the ADFS IdP use the same SP associations as the SAML 2.0 IdP. */ $saml2EntityId = $metadata->getMetaDataCurrentEntityID('saml20-idp-hosted'); $this->associationGroup = 'saml2:' . $saml2EntityId; } catch (Exception $e) { /* Probably no SAML 2 IdP configured for this host. Ignore the error. */ } } else { assert(FALSE); } if ($this->associationGroup === NULL) { $this->associationGroup = $this->id; } $auth = $this->config->getString('auth'); if (SimpleSAML_Auth_Source::getById($auth) !== NULL) { $this->authSource = new SimpleSAML_Auth_Simple($auth); } else { $this->authSource = new SimpleSAML_Auth_BWC($auth, $this->config->getString('authority', NULL)); } }
/** * This functions finds what key & certificate files should be used to sign the metadata * for the given entity. * * @param SimpleSAML_Configuration $config Our SimpleSAML_Configuration instance. * @param array $entityMetadata The metadata of the entity. * @param string $type A string which describes the type entity this is, e.g. 'SAML 2 IdP' or * 'Shib 1.3 SP'. * * @return array An associative array with the keys 'privatekey', 'certificate', and optionally 'privatekey_pass'. * @throws Exception If the key and certificate used to sign is unknown. */ private static function findKeyCert($config, $entityMetadata, $type) { // first we look for metadata.privatekey and metadata.certificate in the metadata if (array_key_exists('metadata.sign.privatekey', $entityMetadata) || array_key_exists('metadata.sign.certificate', $entityMetadata)) { if (!array_key_exists('metadata.sign.privatekey', $entityMetadata) || !array_key_exists('metadata.sign.certificate', $entityMetadata)) { throw new Exception('Missing either the "metadata.sign.privatekey" or the' . ' "metadata.sign.certificate" configuration option in the metadata for' . ' the ' . $type . ' "' . $entityMetadata['entityid'] . '". If one of' . ' these options is specified, then the other must also be specified.'); } $ret = array('privatekey' => $entityMetadata['metadata.sign.privatekey'], 'certificate' => $entityMetadata['metadata.sign.certificate']); if (array_key_exists('metadata.sign.privatekey_pass', $entityMetadata)) { $ret['privatekey_pass'] = $entityMetadata['metadata.sign.privatekey_pass']; } return $ret; } // then we look for default values in the global configuration $privatekey = $config->getString('metadata.sign.privatekey', null); $certificate = $config->getString('metadata.sign.certificate', null); if ($privatekey !== null || $certificate !== null) { if ($privatekey === null || $certificate === null) { throw new Exception('Missing either the "metadata.sign.privatekey" or the' . ' "metadata.sign.certificate" configuration option in the global' . ' configuration. If one of these options is specified, then the other' . ' must also be specified.'); } $ret = array('privatekey' => $privatekey, 'certificate' => $certificate); $privatekey_pass = $config->getString('metadata.sign.privatekey_pass', null); if ($privatekey_pass !== null) { $ret['privatekey_pass'] = $privatekey_pass; } return $ret; } // as a last resort we attempt to use the privatekey and certificate option from the metadata if (array_key_exists('privatekey', $entityMetadata) || array_key_exists('certificate', $entityMetadata)) { if (!array_key_exists('privatekey', $entityMetadata) || !array_key_exists('certificate', $entityMetadata)) { throw new Exception('Both the "privatekey" and the "certificate" option must' . ' be set in the metadata for the ' . $type . ' "' . $entityMetadata['entityid'] . '" before it is possible to sign metadata' . ' from this entity.'); } $ret = array('privatekey' => $entityMetadata['privatekey'], 'certificate' => $entityMetadata['certificate']); if (array_key_exists('privatekey_pass', $entityMetadata)) { $ret['privatekey_pass'] = $entityMetadata['privatekey_pass']; } return $ret; } throw new Exception('Could not find what key & certificate should be used to sign the metadata' . ' for the ' . $type . ' "' . $entityMetadata['entityid'] . '".'); }
/** * Find template path. * * This function locates the given template based on the template name. It will first search for the template in * the current theme directory, and then the default theme. * * The template name may be on the form <module name>:<template path>, in which case it will search for the * template file in the given module. * * @param string $template The relative path from the theme directory to the template file. * * @return string The absolute path to the template file. * * @throws Exception If the template file couldn't be found. */ private function findTemplatePath($template, $throw_exception = true) { assert('is_string($template)'); $result = $this->findModuleAndTemplateName($template); $templateModule = $result[0] ? $result[0] : 'default'; $templateName = $result[1]; $tmp = explode(':', $this->configuration->getString('theme.use', 'default'), 2); if (count($tmp) === 2) { $themeModule = $tmp[0]; $themeName = $tmp[1]; } else { $themeModule = null; $themeName = $tmp[0]; } // first check the current theme if ($themeModule !== null) { // .../module/<themeModule>/themes/<themeName>/<templateModule>/<templateName> $filename = \SimpleSAML\Module::getModuleDir($themeModule) . '/themes/' . $themeName . '/' . $templateModule . '/' . $templateName; } elseif ($templateModule !== 'default') { // .../module/<templateModule>/templates/<templateName> $filename = \SimpleSAML\Module::getModuleDir($templateModule) . '/templates/' . $templateName; } else { // .../templates/<theme>/<templateName> $filename = $this->configuration->getPathValue('templatedir', 'templates/') . $templateName; } if (file_exists($filename)) { return $filename; } // not found in current theme \SimpleSAML\Logger::debug($_SERVER['PHP_SELF'] . ' - Template: Could not find template file [' . $template . '] at [' . $filename . '] - now trying the base template'); // try default theme if ($templateModule !== 'default') { // .../module/<templateModule>/templates/<templateName> $filename = \SimpleSAML\Module::getModuleDir($templateModule) . '/templates/' . $templateName; } else { // .../templates/<templateName> $filename = $this->configuration->getPathValue('templatedir', 'templates/') . '/' . $templateName; } if (file_exists($filename)) { return $filename; } // not found in default template if ($throw_exception) { // log error and throw exception $error = 'Template: Could not find template file [' . $template . '] at [' . $filename . ']'; \SimpleSAML\Logger::critical($_SERVER['PHP_SELF'] . ' - ' . $error); throw new Exception($error); } else { // missing template expected, return NULL return null; } }
/** * Translate the name of an attribute. * * @param string $name The attribute name. * * @return string The translated attribute name, or the original attribute name if no translation was found. */ public function getAttributeTranslation($name) { // normalize attribute name $normName = strtolower($name); $normName = str_replace(":", "_", $normName); // check for an extra dictionary $extraDict = $this->configuration->getString('attributes.extradictionary', null); if ($extraDict !== null) { $dict = $this->getDictionary($extraDict); if (array_key_exists($normName, $dict)) { return $this->getPreferredTranslation($dict[$normName]); } } // search the default attribute dictionary $dict = $this->getDictionary('attributes'); if (array_key_exists('attribute_' . $normName, $dict)) { return $this->getPreferredTranslation($dict['attribute_' . $normName]); } // no translations found return $name; }
/** * Handles a request to this discovery service. * * The IdP disco parameters should be set before calling this function. */ public function handleRequest() { $this->start(); // no choice made. Show discovery service page $idpList = $this->getIdPList(); $idpList = $this->filterList($idpList); $preferredIdP = $this->getRecommendedIdP(); $idpintersection = array_intersect(array_keys($idpList), $this->getScopedIDPList()); if (sizeof($idpintersection) > 0) { $idpList = array_intersect_key($idpList, array_fill_keys($idpintersection, null)); } $idpintersection = array_values($idpintersection); if (sizeof($idpintersection) == 1) { $this->log('Choice made [' . $idpintersection[0] . '] (Redirecting the user back. returnIDParam=' . $this->returnIdParam . ')'); \SimpleSAML\Utils\HTTP::redirectTrustedURL($this->returnURL, array($this->returnIdParam => $idpintersection[0])); } /* * Make use of an XHTML template to present the select IdP choice to the user. Currently the supported options * is either a drop down menu or a list view. */ switch ($this->config->getString('idpdisco.layout', 'links')) { case 'dropdown': $templateFile = 'selectidp-dropdown.php'; break; case 'links': $templateFile = 'selectidp-links.php'; break; default: throw new Exception('Invalid value for the \'idpdisco.layout\' option.'); } $t = new SimpleSAML_XHTML_Template($this->config, $templateFile, 'disco'); $t->data['idplist'] = $idpList; $t->data['preferredidp'] = $preferredIdP; $t->data['return'] = $this->returnURL; $t->data['returnIDParam'] = $this->returnIdParam; $t->data['entityID'] = $this->spEntityId; $t->data['urlpattern'] = htmlspecialchars(\SimpleSAML\Utils\HTTP::getSelfURLNoQuery()); $t->data['rememberenabled'] = $this->config->getBoolean('idpdisco.enableremember', false); $t->show(); }
/** * Getter for the LDAP connection object. Created this getter * rather than setting in the constructor to avoid unnecessarily * connecting to LDAP when it might not be needed. * * @return sspmod_ldap_LdapConnection */ protected function getLdap() { // Check if already connected if ($this->ldap) { return $this->ldap; } // Get the connection specific options $hostname = $this->config->getString('ldap.hostname'); $port = $this->config->getInteger('ldap.port', 389); $enable_tls = $this->config->getBoolean('ldap.enable_tls', false); $debug = $this->config->getBoolean('ldap.debug', false); $timeout = $this->config->getInteger('ldap.timeout', 0); $username = $this->config->getString('ldap.username', null); $password = $this->config->getString('ldap.password', null); // Log the LDAP connection SimpleSAML\Logger::debug($this->title . 'Connecting to LDAP server;' . ' Hostname: ' . $hostname . ' Port: ' . $port . ' Enable TLS: ' . ($enable_tls ? 'Yes' : 'No') . ' Debug: ' . ($debug ? 'Yes' : 'No') . ' Timeout: ' . $timeout . ' Username: '******' Password: '******'*', strlen($password))); // Connect to the LDAP server to be queried during processing $this->ldap = new SimpleSAML_Auth_LDAP($hostname, $enable_tls, $debug, $timeout, $port); $this->ldap->bind($username, $password); // All done return $this->ldap; }
/** * Build a authentication response. * * @param array $idp Metadata for the IdP the response is sent from. * @param array $sp Metadata for the SP the response is sent to. * @param string $shire The endpoint on the SP the response is sent to. * @param array|NULL $attributes The attributes which should be included in the response. * @return string The response. */ public function generate(SimpleSAML_Configuration $idp, SimpleSAML_Configuration $sp, $shire, $attributes) { assert('is_string($shire)'); assert('$attributes === NULL || is_array($attributes)'); if ($sp->hasValue('scopedattributes')) { $scopedAttributes = $sp->getArray('scopedattributes'); } elseif ($idp->hasValue('scopedattributes')) { $scopedAttributes = $idp->getArray('scopedattributes'); } else { $scopedAttributes = array(); } $id = SimpleSAML\Utils\Random::generateID(); $issueInstant = SimpleSAML\Utils\Time::generateTimestamp(); // 30 seconds timeskew back in time to allow differing clocks. $notBefore = SimpleSAML\Utils\Time::generateTimestamp(time() - 30); $assertionExpire = SimpleSAML\Utils\Time::generateTimestamp(time() + 60 * 5); # 5 minutes $assertionid = SimpleSAML\Utils\Random::generateID(); $spEntityId = $sp->getString('entityid'); $audience = $sp->getString('audience', $spEntityId); $base64 = $sp->getBoolean('base64attributes', FALSE); $namequalifier = $sp->getString('NameQualifier', $spEntityId); $nameid = SimpleSAML\Utils\Random::generateID(); $subjectNode = '<Subject>' . '<NameIdentifier' . ' Format="urn:mace:shibboleth:1.0:nameIdentifier"' . ' NameQualifier="' . htmlspecialchars($namequalifier) . '"' . '>' . htmlspecialchars($nameid) . '</NameIdentifier>' . '<SubjectConfirmation>' . '<ConfirmationMethod>' . 'urn:oasis:names:tc:SAML:1.0:cm:bearer' . '</ConfirmationMethod>' . '</SubjectConfirmation>' . '</Subject>'; $encodedattributes = ''; if (is_array($attributes)) { $encodedattributes .= '<AttributeStatement>'; $encodedattributes .= $subjectNode; foreach ($attributes as $name => $value) { $encodedattributes .= $this->enc_attribute($name, $value, $base64, $scopedAttributes); } $encodedattributes .= '</AttributeStatement>'; } /* * The SAML 1.1 response message */ $response = '<Response xmlns="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:saml="urn:oasis:names:tc:SAML:1.0:assertion" xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" IssueInstant="' . $issueInstant . '" MajorVersion="1" MinorVersion="1" Recipient="' . htmlspecialchars($shire) . '" ResponseID="' . $id . '"> <Status> <StatusCode Value="samlp:Success" /> </Status> <Assertion xmlns="urn:oasis:names:tc:SAML:1.0:assertion" AssertionID="' . $assertionid . '" IssueInstant="' . $issueInstant . '" Issuer="' . htmlspecialchars($idp->getString('entityid')) . '" MajorVersion="1" MinorVersion="1"> <Conditions NotBefore="' . $notBefore . '" NotOnOrAfter="' . $assertionExpire . '"> <AudienceRestrictionCondition> <Audience>' . htmlspecialchars($audience) . '</Audience> </AudienceRestrictionCondition> </Conditions> <AuthenticationStatement AuthenticationInstant="' . $issueInstant . '" AuthenticationMethod="urn:oasis:names:tc:SAML:1.0:am:unspecified">' . $subjectNode . ' </AuthenticationStatement> ' . $encodedattributes . ' </Assertion> </Response>'; return $response; }
/** * Load private key from metadata. * * This function loads a private key from a metadata array. It searches for the * following elements: * 'privatekey' Name of a private key file in the cert-directory. * 'privatekey_pass' Password for the private key. * * It returns and array with the following elements: * 'PEM' Data for the private key, in PEM-format * 'password' Password for the private key. * * @param SimpleSAML_Configuration $metadata The metadata array the private key should be loaded from. * @param bool $required Whether the private key is required. If this is TRUE, a * missing key will cause an exception. Default is FALSE. * @param string $prefix The prefix which should be used when reading from the metadata * array. Defaults to ''. * @return array|NULL Extracted private key, or NULL if no private key is present. */ public static function loadPrivateKey(SimpleSAML_Configuration $metadata, $required = FALSE, $prefix = '') { assert('is_bool($required)'); assert('is_string($prefix)'); $file = $metadata->getString($prefix . 'privatekey', NULL); if ($file === NULL) { /* No private key found. */ if ($required) { throw new Exception('No private key found in metadata.'); } else { return NULL; } } $file = SimpleSAML_Utilities::resolveCert($file); $data = @file_get_contents($file); if ($data === FALSE) { throw new Exception('Unable to load private key from file "' . $file . '"'); } $ret = array('PEM' => $data); if ($metadata->hasValue($prefix . 'privatekey_pass')) { $ret['password'] = $metadata->getString($prefix . 'privatekey_pass'); } return $ret; }
/** * Add a certificate. * * Helper function for adding a certificate to the metadata. * * @param \SAML2\XML\md\RoleDescriptor $rd The RoleDescriptor the certificate should be added to. * @param SimpleSAML_Configuration $metadata The metadata of the entity. */ private function addCertificate(\SAML2\XML\md\RoleDescriptor $rd, SimpleSAML_Configuration $metadata) { $keys = $metadata->getPublicKeys(); if ($keys !== null) { foreach ($keys as $key) { if ($key['type'] !== 'X509Certificate') { continue; } if (!isset($key['signing']) || $key['signing'] === true) { $this->addX509KeyDescriptor($rd, 'signing', $key['X509Certificate']); } if (!isset($key['encryption']) || $key['encryption'] === true) { $this->addX509KeyDescriptor($rd, 'encryption', $key['X509Certificate']); } } } if ($metadata->hasValue('https.certData')) { $this->addX509KeyDescriptor($rd, 'signing', $metadata->getString('https.certData')); } }
/** * Build a authentication response 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 string $consumerURL The Destination URL of the response. */ private static function buildResponse(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata, $consumerURL) { $signResponse = $spMetadata->getBoolean('saml20.sign.response', NULL); if ($signResponse === NULL) { $signResponse = $idpMetadata->getBoolean('saml20.sign.response', TRUE); } $r = new SAML2_Response(); $r->setIssuer($idpMetadata->getString('entityid')); $r->setDestination($consumerURL); if ($signResponse) { sspmod_saml_Message::addSign($idpMetadata, $spMetadata, $r); } return $r; }
/** * This function sends the SOAP message to the service location and returns SOAP response * * @param SAML2_Message $m The request that should be sent. * @param SimpleSAML_Configuration $srcMetadata The metadata of the issuer of the message. * @param SimpleSAML_Configuration $dstMetadata The metadata of the destination of the message. * @return SAML2_Message The response we received. */ public function send(SAML2_Message $msg, SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata = NULL) { $issuer = $msg->getIssuer(); $ctxOpts = array('ssl' => array('capture_peer_cert' => TRUE)); // Determine if we are going to do a MutualSSL connection between the IdP and SP - Shoaib if ($srcMetadata->hasValue('saml.SOAPClient.certificate')) { $ctxOpts['ssl']['local_cert'] = SimpleSAML_Utilities::resolveCert($srcMetadata->getString('saml.SOAPClient.certificate')); if ($srcMetadata->hasValue('saml.SOAPClient.privatekey_pass')) { $ctxOpts['ssl']['passphrase'] = $srcMetadata->getString('saml.SOAPClient.privatekey_pass'); } } else { /* Use the SP certificate and privatekey if it is configured. */ $privateKey = SimpleSAML_Utilities::loadPrivateKey($srcMetadata); $publicKey = SimpleSAML_Utilities::loadPublicKey($srcMetadata); if ($privateKey !== NULL && $publicKey !== NULL && isset($publicKey['PEM'])) { $keyCertData = $privateKey['PEM'] . $publicKey['PEM']; $file = SimpleSAML_Utilities::getTempDir() . '/' . sha1($keyCertData) . '.pem'; if (!file_exists($file)) { SimpleSAML_Utilities::writeFile($file, $keyCertData); } $ctxOpts['ssl']['local_cert'] = $file; if (isset($privateKey['password'])) { $ctxOpts['ssl']['passphrase'] = $privateKey['password']; } } } // do peer certificate verification if ($dstMetadata !== NULL) { $peerPublicKeys = $dstMetadata->getPublicKeys('signing', TRUE); $certData = ''; foreach ($peerPublicKeys as $key) { if ($key['type'] !== 'X509Certificate') { continue; } $certData .= "-----BEGIN CERTIFICATE-----\n" . chunk_split($key['X509Certificate'], 64) . "-----END CERTIFICATE-----\n"; } $peerCertFile = SimpleSAML_Utilities::getTempDir() . '/' . sha1($certData) . '.pem'; if (!file_exists($peerCertFile)) { SimpleSAML_Utilities::writeFile($peerCertFile, $certData); } // create ssl context $ctxOpts['ssl']['verify_peer'] = TRUE; $ctxOpts['ssl']['verify_depth'] = 1; $ctxOpts['ssl']['cafile'] = $peerCertFile; } $context = stream_context_create($ctxOpts); if ($context === NULL) { throw new Exception('Unable to create SSL stream context'); } $options = array('uri' => $issuer, 'location' => $msg->getDestination(), 'stream_context' => $context); $x = new SoapClient(NULL, $options); // Add soap-envelopes $request = $msg->toSignedXML(); $request = self::START_SOAP_ENVELOPE . $request->ownerDocument->saveXML($request) . self::END_SOAP_ENVELOPE; SimpleSAML_Utilities::debugMessage($request, 'out'); $action = 'http://www.oasis-open.org/committees/security'; $version = '1.1'; $destination = $msg->getDestination(); /* Perform SOAP Request over HTTP */ $soapresponsexml = $x->__doRequest($request, $destination, $action, $version); if ($soapresponsexml === NULL || $soapresponsexml === "") { throw new Exception('Empty SOAP response, check peer certificate.'); } SimpleSAML_Utilities::debugMessage($soapresponsexml, 'in'); // Convert to SAML2_Message (DOMElement) $dom = new DOMDocument(); if (!$dom->loadXML($soapresponsexml)) { throw new Exception('Not a SOAP response.'); } $soapfault = $this->getSOAPFault($dom); if (isset($soapfault)) { throw new Exception($soapfault); } //Extract the message from the response $xml = $dom->firstChild; /* Soap Envelope */ $samlresponse = SAML2_Utils::xpQuery($dom->firstChild, '/soap-env:Envelope/soap-env:Body/*[1]'); $samlresponse = SAML2_Message::fromXML($samlresponse[0]); /* Add validator to message which uses the SSL context. */ self::addSSLValidator($samlresponse, $context); SimpleSAML_Logger::debug("Valid ArtifactResponse received from IdP"); return $samlresponse; }
/** * Build a authentication response based on information in the metadata. * * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender (IdP). * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient (SP). */ public static function buildResponse(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata, $consumerURL) { $signResponse = $dstMetadata->getBoolean('saml20.sign.response', NULL); if ($signResponse === NULL) { $signResponse = $srcMetadata->getBoolean('saml20.sign.response', TRUE); } $r = new SAML2_Response(); $r->setIssuer($srcMetadata->getString('entityid')); $r->setDestination($consumerURL); if ($signResponse) { self::addSign($srcMetadata, $dstMetadata, $r); } return $r; }
/** * This function receives a SAML 1.1 artifact. * * @param SimpleSAML_Configuration $spMetadata The metadata of the SP. * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP. * @return string The <saml1p:Response> element, as an XML string. */ public static function receive(SimpleSAML_Configuration $spMetadata, SimpleSAML_Configuration $idpMetadata) { $artifacts = self::getArtifacts(); $request = self::buildRequest($artifacts); \SimpleSAML\Utils\XML::debugSAMLMessage($request, 'out'); $url = $idpMetadata->getDefaultEndpoint('ArtifactResolutionService', array('urn:oasis:names:tc:SAML:1.0:bindings:SOAP-binding')); $url = $url['Location']; $peerPublicKeys = $idpMetadata->getPublicKeys('signing', TRUE); $certData = ''; foreach ($peerPublicKeys as $key) { if ($key['type'] !== 'X509Certificate') { continue; } $certData .= "-----BEGIN CERTIFICATE-----\n" . chunk_split($key['X509Certificate'], 64) . "-----END CERTIFICATE-----\n"; } $file = SimpleSAML\Utils\System::getTempDir() . DIRECTORY_SEPARATOR . sha1($certData) . '.crt'; if (!file_exists($file)) { SimpleSAML\Utils\System::writeFile($file, $certData); } $spKeyCertFile = \SimpleSAML\Utils\Config::getCertPath($spMetadata->getString('privatekey')); $opts = array('ssl' => array('verify_peer' => TRUE, 'cafile' => $file, 'local_cert' => $spKeyCertFile, 'capture_peer_cert' => TRUE, 'capture_peer_chain' => TRUE), 'http' => array('method' => 'POST', 'content' => $request, 'header' => 'SOAPAction: http://www.oasis-open.org/committees/security' . "\r\n" . 'Content-Type: text/xml')); // Fetch the artifact $response = \SimpleSAML\Utils\HTTP::fetch($url, $opts); if ($response === FALSE) { throw new SimpleSAML_Error_Exception('Failed to retrieve assertion from IdP.'); } \SimpleSAML\Utils\XML::debugSAMLMessage($response, 'in'); // Find the response in the SOAP message $response = self::extractResponse($response); return $response; }
/** * Retrieve the encryption key for the given entity. * * @param SimpleSAML_Configuration $metadata The metadata of the entity. * @return XMLSecurityKey The encryption key. */ public static function getEncryptionKey(SimpleSAML_Configuration $metadata) { $sharedKey = $metadata->getString('sharedkey', NULL); if ($sharedKey !== NULL) { $key = new XMLSecurityKey(XMLSecurityKey::AES128_CBC); $key->loadKey($sharedKey); return $key; } $keys = $metadata->getPublicKeys('encryption', TRUE); foreach ($keys as $key) { switch ($key['type']) { case 'X509Certificate': $pemKey = "-----BEGIN CERTIFICATE-----\n" . chunk_split($key['X509Certificate'], 64) . "-----END CERTIFICATE-----\n"; $key = new XMLSecurityKey(XMLSecurityKey::RSA_OAEP_MGF1P, array('type' => 'public')); $key->loadKey($pemKey); return $key; } } throw new SimpleSAML_Error_Exception('No supported encryption key in ' . var_export($metadata->getString('entityid'), TRUE)); }
/** * Send a SAML1 SSO request to an IdP. * * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP. * @param array $state The state array for the current authentication. */ private function startSSO1(SimpleSAML_Configuration $idpMetadata, array $state) { $idpEntityId = $idpMetadata->getString('entityid'); $state['saml:idp'] = $idpEntityId; $ar = new SimpleSAML_XML_Shib13_AuthnRequest(); $ar->setIssuer($this->entityId); $id = SimpleSAML_Auth_State::saveState($state, 'saml:sp:sso'); $ar->setRelayState($id); $useArtifact = $idpMetadata->getBoolean('saml1.useartifact', NULL); if ($useArtifact === NULL) { $useArtifact = $this->metadata->getBoolean('saml1.useartifact', FALSE); } if ($useArtifact) { $shire = SimpleSAML\Module::getModuleURL('saml/sp/saml1-acs.php/' . $this->authId . '/artifact'); } else { $shire = SimpleSAML\Module::getModuleURL('saml/sp/saml1-acs.php/' . $this->authId); } $url = $ar->createRedirect($idpEntityId, $shire); SimpleSAML\Logger::debug('Starting SAML 1 SSO to ' . var_export($idpEntityId, TRUE) . ' from ' . var_export($this->entityId, TRUE) . '.'); \SimpleSAML\Utils\HTTP::redirectTrustedURL($url); }
/** * Generate an Instance ID based on the database configuration. * * @param \SimpleSAML_Configuration $config Configuration class * * @return string $instanceId */ private static function generateInstanceId($config) { $assembledConfig = array('master' => array('database.dsn' => $config->getString('database.dsn'), 'database.username' => $config->getString('database.username', null), 'database.password' => $config->getString('database.password', null), 'database.prefix' => $config->getString('database.prefix', ''), 'database.persistent' => $config->getBoolean('database.persistent', false)), 'slaves' => $config->getArray('database.slaves', array())); return sha1(serialize($assembledConfig)); }
/** * Initialize this aggregator. * * @param string $id The id of this aggregator. * @param SimpleSAML_Configuration $config The configuration for this aggregator. */ protected function __construct($id, SimpleSAML_Configuration $config) { assert('is_string($id)'); $this->id = $id; $this->logLoc = 'aggregator2:' . $this->id . ': '; $this->cronTag = $config->getString('cron.tag', NULL); $this->cacheDirectory = $config->getString('cache.directory', NULL); if ($this->cacheDirectory !== NULL) { $this->cacheDirectory = SimpleSAML_Utilities::resolvePath($this->cacheDirectory); } $this->cacheGenerated = $config->getInteger('cache.generated', NULL); if ($this->cacheGenerated !== NULL) { $this->cacheId = sha1($this->id); $this->cacheTag = sha1(serialize($config)); } // configure entity IDs excluded by default $this->excludeEntities($config->getArrayize('exclude', null)); // configure filters $this->setFilters($config->getArrayize('filter', null)); $this->validLength = $config->getInteger('valid.length', 7 * 24 * 60 * 60); $globalConfig = SimpleSAML_Configuration::getInstance(); $certDir = $globalConfig->getPathValue('certdir', 'cert/'); $signKey = $config->getString('sign.privatekey', NULL); if ($signKey !== NULL) { $signKey = SimpleSAML_Utilities::resolvePath($signKey, $certDir); $this->signKey = @file_get_contents($signKey); if ($this->signKey === NULL) { throw new SimpleSAML_Error_Exception('Unable to load private key from ' . var_export($signKey, TRUE)); } } $this->signKeyPass = $config->getString('sign.privatekey_pass', NULL); $signCert = $config->getString('sign.certificate', NULL); if ($signCert !== NULL) { $signCert = SimpleSAML_Utilities::resolvePath($signCert, $certDir); $this->signCert = @file_get_contents($signCert); if ($this->signCert === NULL) { throw new SimpleSAML_Error_Exception('Unable to load certificate file from ' . var_export($signCert, TRUE)); } } $this->sslCAFile = $config->getString('ssl.cafile', NULL); $this->regInfo = $config->getArray('RegistrationInfo', NULL); $this->initSources($config->getConfigList('sources')); }