An exception will be thrown if this option isn't an array, or if this option isn't found, and no
default value is given.
public getArray ( string $name, mixed $default = self::REQUIRED_OPTION ) : array | 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. |
return | array | 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->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)); } }
/** * @param SimpleSAML_Configuration $configuration * @param string $prefix * * @return array */ private static function pluckConfiguration(SimpleSAML_Configuration $configuration, $prefix = '') { $extracted = array(); // ported from // https://github.com/simplesamlphp/simplesamlphp/blob/3d735912342767d391297cc5e13272a76730aca0/lib/SimpleSAML/Configuration.php#L1092 if ($configuration->hasValue($prefix . 'keys')) { $extracted['keys'] = $configuration->getArray($prefix . 'keys'); } // ported from // https://github.com/simplesamlphp/simplesamlphp/blob/3d735912342767d391297cc5e13272a76730aca0/lib/SimpleSAML/Configuration.php#L1108 if ($configuration->hasValue($prefix . 'certData')) { $extracted['certificateData'] = $configuration->getString($prefix . 'certData'); } // ported from // https://github.com/simplesamlphp/simplesamlphp/blob/3d735912342767d391297cc5e13272a76730aca0/lib/SimpleSAML/Configuration.php#L1119 if ($configuration->hasValue($prefix . 'certificate')) { $extracted['certificateData'] = $configuration->getString($prefix . 'certificate'); } // ported from // https://github.com/simplesamlphp/simplesamlphp/blob/3d735912342767d391297cc5e13272a76730aca0/modules/saml/lib/Message.php#L161 if ($configuration->hasValue($prefix . 'certFingerprint')) { $extracted['certificateFingerprint'] = $configuration->getArrayizeString('certFingerprint'); } $extracted['assertionEncryptionEnabled'] = $configuration->getBoolean('assertion.encryption', FALSE); if ($configuration->has('sharedKey')) { $extracted['sharedKey'] = $configuration->getString('sharedKey'); } return $extracted; }
/** * 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(); }
/** * Wash configured (available) languages against installed languages * * @return array The set of langauges both in 'language.available' and $this->language_names */ private function getInstalledLanguages() { $configuredAvailableLanguages = $this->configuration->getArray('language.available', array('en')); $availableLanguages = array(); foreach ($configuredAvailableLanguages as $code) { if (array_key_exists($code, $this->language_names) && isset($this->language_names[$code])) { $availableLanguages[] = $code; } else { \SimpleSAML\Logger::error("Language \"{$code}\" not installed. Check config."); } } return $availableLanguages; }
/** * Get all addresses in JANUS * * @return array All addresses in JANUS */ public function getSubscriptionList() { // Predifined subscriptions $subscriptionList = array('ENTITYUPDATE', 'USER', 'USER-NEW', 'ENTITYCREATE'); // Get all existing subscriptions $st = self::execute('SELECT DISTINCT(`subscription`) AS `subscription` FROM `' . self::$prefix . 'subscription`;'); if ($st === false) { SimpleSAML_Logger::error('JANUS: Error fetching subscriptions'); return false; } while ($row = $st->fetch(PDO::FETCH_ASSOC)) { $subscriptionList[] = $row['subscription']; } $st = null; // Get subscription to all active users $st = self::execute('SELECT `uid` FROM `' . self::$prefix . 'user` WHERE `active` = ?;', array('yes')); if ($st === false) { SimpleSAML_Logger::error('JANUS: Error fetching subscriptions'); return false; } while ($row = $st->fetch(PDO::FETCH_ASSOC)) { $subscriptionList[] = 'USER-' . $row['uid']; } $st = null; // Get subscription to all active users $st = self::execute('SELECT `eid` FROM `' . self::$prefix . 'entity`;'); if ($st === false) { SimpleSAML_Logger::error('JANUS: Error fetching subscriptions'); return false; } while ($row = $st->fetch(PDO::FETCH_ASSOC)) { $subscriptionList[] = 'ENTITYUPDATE-' . $row['eid']; } $workflowstates = $this->_config->getArray('workflowstates'); foreach ($workflowstates as $key => $value) { $subscriptionList[] = 'ENTITYUPDATE-#-CHANGESTATE-' . $key; } $subscriptionList[] = 'ENTITYUPDATE-#-CHANGESTATE'; // Remove dublicates $sl = array_unique($subscriptionList); asort($sl); return $sl; }
/** * 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; }
/** * Add an AttributeConsumingService element to the metadata. * * @param \SAML2\XML\md\SPSSODescriptor $spDesc The SPSSODescriptor element. * @param SimpleSAML_Configuration $metadata The metadata. */ private function addAttributeConsumingService(\SAML2\XML\md\SPSSODescriptor $spDesc, SimpleSAML_Configuration $metadata) { $attributes = $metadata->getArray('attributes', array()); $name = $metadata->getLocalizedString('name', null); if ($name === null || count($attributes) == 0) { // we cannot add an AttributeConsumingService without name and attributes return; } $attributesrequired = $metadata->getArray('attributes.required', array()); /* * Add an AttributeConsumingService element with information as name and description and list * of requested attributes */ $attributeconsumer = new \SAML2\XML\md\AttributeConsumingService(); $attributeconsumer->index = 0; $attributeconsumer->ServiceName = $name; $attributeconsumer->ServiceDescription = $metadata->getLocalizedString('description', array()); $nameFormat = $metadata->getString('attributes.NameFormat', \SAML2\Constants::NAMEFORMAT_UNSPECIFIED); foreach ($attributes as $friendlyName => $attribute) { $t = new \SAML2\XML\md\RequestedAttribute(); $t->Name = $attribute; if (!is_int($friendlyName)) { $t->FriendlyName = $friendlyName; } if ($nameFormat !== \SAML2\Constants::NAMEFORMAT_UNSPECIFIED) { $t->NameFormat = $nameFormat; } if (in_array($attribute, $attributesrequired)) { $t->isRequired = true; } $attributeconsumer->RequestedAttribute[] = $t; } $spDesc->AttributeConsumingService[] = $attributeconsumer; }
/** * Helper function for encoding attributes. * * @param SimpleSAML_Configuration $idpMetadata The metadata of the IdP. * @param SimpleSAML_Configuration $spMetadata The metadata of the SP. * @param array $attributes The attributes of the user * @return array The encoded attributes. */ private static function encodeAttributes(SimpleSAML_Configuration $idpMetadata, SimpleSAML_Configuration $spMetadata, array $attributes) { $base64Attributes = $spMetadata->getBoolean('base64attributes', NULL); if ($base64Attributes === NULL) { $base64Attributes = $idpMetadata->getBoolean('base64attributes', FALSE); } if ($base64Attributes) { $defaultEncoding = 'base64'; } else { $defaultEncoding = 'string'; } $srcEncodings = $idpMetadata->getArray('attributeencodings', array()); $dstEncodings = $spMetadata->getArray('attributeencodings', array()); /* * Merge the two encoding arrays. Encodings specified in the target metadata * takes precedence over the source metadata. */ $encodings = array_merge($srcEncodings, $dstEncodings); $ret = array(); foreach ($attributes as $name => $values) { $ret[$name] = array(); if (array_key_exists($name, $encodings)) { $encoding = $encodings[$name]; } else { $encoding = $defaultEncoding; } foreach ($values as $value) { // allow null values if ($value === null) { $ret[$name][] = $value; continue; } switch ($encoding) { case 'string': $value = (string) $value; break; case 'base64': $value = base64_encode((string) $value); break; case 'raw': if (is_string($value)) { $doc = SAML2_DOMDocumentFactory::fromString('<root>' . $value . '</root>'); $value = $doc->firstChild->childNodes; } assert('$value instanceof DOMNodeList'); break; default: throw new SimpleSAML_Error_Exception('Invalid encoding for attribute ' . var_export($name, TRUE) . ': ' . var_export($encoding, TRUE)); } $ret[$name][] = $value; } } return $ret; }
/** * Retrieve blacklisted algorithms. * * Remote configuration overrides local configuration. * * @param SimpleSAML_Configuration $srcMetadata The metadata of the sender. * @param SimpleSAML_Configuration $dstMetadata The metadata of the recipient. * @return array Array of blacklisted algorithms. */ public static function getBlacklistedAlgorithms(SimpleSAML_Configuration $srcMetadata, SimpleSAML_Configuration $dstMetadata) { $blacklist = $srcMetadata->getArray('encryption.blacklisted-algorithms', NULL); if ($blacklist === NULL) { $blacklist = $dstMetadata->getArray('encryption.blacklisted-algorithms', array(XMLSecurityKey::RSA_1_5)); } return $blacklist; }
/** * Add an AttributeConsumingService element to the metadata. * * @param DOMElement $spDesc The SPSSODescriptor element. * @param SimpleSAML_Configuration $metadata The metadata. */ private function addAttributeConsumingService(SAML2_XML_md_SPSSODescriptor $spDesc, SimpleSAML_Configuration $metadata) { $attributes = $metadata->getArray('attributes', array()); $name = $metadata->getLocalizedString('name', NULL); if ($name === NULL || count($attributes) == 0) { /* We cannot add an AttributeConsumingService without name and attributes. */ return; } /* * Add an AttributeConsumingService element with information as name and description and list * of requested attributes */ $attributeconsumer = new SAML2_XML_md_AttributeConsumingService(); $attributeconsumer->index = 0; $attributeconsumer->ServiceName = $name; $attributeconsumer->ServiceDescription = $metadata->getLocalizedString('description', array()); $nameFormat = $metadata->getString('attributes.NameFormat', SAML2_Const::NAMEFORMAT_UNSPECIFIED); foreach ($attributes as $attribute) { $t = new SAML2_XML_md_RequestedAttribute(); $t->Name = $attribute; if ($nameFormat !== SAML2_Const::NAMEFORMAT_UNSPECIFIED) { $t->NameFormat = $nameFormat; } $attributeconsumer->RequestedAttribute[] = $t; } $spDesc->AttributeConsumingService[] = $attributeconsumer; }
/** * 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)); }
/** * Get all metadata for the entity * * @return false|array Array with metadata or false on error */ public function getMetaArray() { if (empty($this->_metadata)) { if (!$this->_loadMetadata()) { return false; } } if (empty($this->_arp)) { if (!$this->_loadArp()) { return false; } } $metaArray = array(); foreach ($this->_metadata as $data) { if (strpos($data->getKey(), ':')) { $keys = explode(':', $data->getKey()); $val = $data->getValue(); while (!empty($keys)) { $array = array(); $newkey = array_pop($keys); $array[$newkey] = $val; $val = $array; } $metaArray = self::arrayMergeRecursiveFixed($array, $metaArray); } else { $metaArray[$data->getKey()] = $data->getValue(); } } $metaArray['entityid'] = $this->_entity->getEntityid(); /* * The expiration field in the entity table is not for metadata * expiration, but for telling when the entity can no longer be accessed * via JANUS. * To set expiration on metadata a metadata field called expiration * should be set */ /* $expiration = $this->getEntity()->getExpiration(); if ($expiration) { $metaArray['expire'] = SimpleSAML_Utilities::parseSAML2Time($expiration); } */ $entity_type = $this->_entity->getType(); $metaArray['metadata-set'] = $this->_entity->getType() . '-remote'; if (!array_key_exists('NameIDFormat', $metaArray)) { if ($entity_type == 'saml20-idp' || $entity_type == 'saml20-sp') { $metaArray['NameIDFormat'] = 'urn:oasis:names:tc:SAML:2.0:nameid-format:transient'; } else { if ($entity_type == 'shib13-idp' || $entity_type == 'shib13-idp') { $metaArray['NameIDFormat'] = 'urn:mace:shibboleth:1.0:nameIdentifier'; } } } if ($entity_type == 'saml20-sp') { if (!is_null($this->_arp)) { $metaArray['attributes'] = array(); foreach ($this->_arp->getAttributes() as $attr) { $metaArray['attributes'][] = $attr; } } else { $defaultarp = $this->_config->getArray('entity.defaultarp', 'NOTDEFINED'); if ($defaultarp != 'NOTDEFINED') { $metaArray['attributes'] = $defaultarp; } } } if (!isset($metaArray['name'])) { $metaArray['name']['en'] = $this->_entity->getEntityid(); } if (isset($metaArray['certData2']) && isset($metaArray['certData'])) { $keys = array(); $keys[0] = array('encryption' => FALSE, 'signing' => TRUE, 'type' => 'X509Certificate', 'X509Certificate' => $metaArray['certData']); $keys[1] = array('encryption' => TRUE, 'signing' => FALSE, 'type' => 'X509Certificate', 'X509Certificate' => $metaArray['certData']); $keys[2] = array('encryption' => FALSE, 'signing' => TRUE, 'type' => 'X509Certificate', 'X509Certificate' => $metaArray['certData2']); unset($metaArray['certData2']); $metaArray['keys'] = $keys; } return $metaArray; }