If the configuration option is a string, it will be converted to an array with a single string
public getArrayizeString ( string $name, mixed $default = self::REQUIRED_OPTION ) : array | ||
$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 | The option with the given name, or $default if the option isn't found and $default is specified. |
/** * @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; }
/** * Get public key or certificate from metadata. * * This function implements a function to retrieve the public key or certificate from * a metadata array. * * It will search for the following elements in the metadata: * 'certData' The certificate as a base64-encoded string. * 'certificate' A file with a certificate or public key in PEM-format. * 'certFingerprint' The fingerprint of the certificate. Can be a single fingerprint, * or an array of multiple valid fingerprints. * * This function will return an array with these elements: * 'PEM' The public key/certificate in PEM-encoding. * 'certData' The certificate data, base64 encoded, on a single line. (Only * present if this is a certificate.) * 'certFingerprint' Array of valid certificate fingerprints. (Only present * if this is a certificate.) * * @param SimpleSAML_Configuration $metadata The metadata. * @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 Public key or certificate data, or NULL if no public key or * certificate was found. */ public static function loadPublicKey(SimpleSAML_Configuration $metadata, $required = FALSE, $prefix = '') { assert('is_bool($required)'); assert('is_string($prefix)'); $keys = $metadata->getPublicKeys(NULL, FALSE, $prefix); if ($keys !== NULL) { foreach ($keys as $key) { if ($key['type'] !== 'X509Certificate') { continue; } if ($key['signing'] !== TRUE) { continue; } $certData = $key['X509Certificate']; $pem = "-----BEGIN CERTIFICATE-----\n" . chunk_split($certData, 64) . "-----END CERTIFICATE-----\n"; $certFingerprint = strtolower(sha1(base64_decode($certData))); return array('certData' => $certData, 'PEM' => $pem, 'certFingerprint' => array($certFingerprint)); } /* No valid key found. */ } elseif ($metadata->hasValue($prefix . 'certFingerprint')) { /* We only have a fingerprint available. */ $fps = $metadata->getArrayizeString($prefix . 'certFingerprint'); /* Normalize fingerprint(s) - lowercase and no colons. */ foreach ($fps as &$fp) { assert('is_string($fp)'); $fp = strtolower(str_replace(':', '', $fp)); } /* We can't build a full certificate from a fingerprint, and may as well * return an array with only the fingerprint(s) immediately. */ return array('certFingerprint' => $fps); } /* No public key/certificate available. */ if ($required) { throw new Exception('No public key / certificate found in metadata.'); } else { return NULL; } }
/** * Build an authentication request based on information in the metadata. * * @param SimpleSAML_Configuration $spMetadata The metadata of the service provider. * @param SimpleSAML_Configuration $idpMetadata The metadata of the identity provider. */ public static function buildAuthnRequest(SimpleSAML_Configuration $spMetadata, SimpleSAML_Configuration $idpMetadata) { $ar = new \SAML2\AuthnRequest(); // get the NameIDPolicy to apply. IdP metadata has precedence. $nameIdPolicy = array(); if ($idpMetadata->hasValue('NameIDPolicy')) { $nameIdPolicy = $idpMetadata->getValue('NameIDPolicy'); } elseif ($spMetadata->hasValue('NameIDPolicy')) { $nameIdPolicy = $spMetadata->getValue('NameIDPolicy'); } if (!is_array($nameIdPolicy)) { // handle old configurations where 'NameIDPolicy' was used to specify just the format $nameIdPolicy = array('Format' => $nameIdPolicy); } $nameIdPolicy_cf = SimpleSAML_Configuration::loadFromArray($nameIdPolicy); $policy = array('Format' => $nameIdPolicy_cf->getString('Format', \SAML2\Constants::NAMEID_TRANSIENT), 'AllowCreate' => $nameIdPolicy_cf->getBoolean('AllowCreate', true)); $spNameQualifier = $nameIdPolicy_cf->getString('SPNameQualifier', false); if ($spNameQualifier !== false) { $policy['SPNameQualifier'] = $spNameQualifier; } $ar->setNameIdPolicy($policy); $ar->setForceAuthn($spMetadata->getBoolean('ForceAuthn', FALSE)); $ar->setIsPassive($spMetadata->getBoolean('IsPassive', FALSE)); $protbind = $spMetadata->getValueValidate('ProtocolBinding', array(\SAML2\Constants::BINDING_HTTP_POST, \SAML2\Constants::BINDING_HOK_SSO, \SAML2\Constants::BINDING_HTTP_ARTIFACT, \SAML2\Constants::BINDING_HTTP_REDIRECT), \SAML2\Constants::BINDING_HTTP_POST); /* Shoaib - setting the appropriate binding based on parameter in sp-metadata defaults to HTTP_POST */ $ar->setProtocolBinding($protbind); $ar->setIssuer($spMetadata->getString('entityid')); $ar->setAssertionConsumerServiceIndex($spMetadata->getInteger('AssertionConsumerServiceIndex', NULL)); $ar->setAttributeConsumingServiceIndex($spMetadata->getInteger('AttributeConsumingServiceIndex', NULL)); if ($spMetadata->hasValue('AuthnContextClassRef')) { $accr = $spMetadata->getArrayizeString('AuthnContextClassRef'); $comp = $spMetadata->getValueValidate('AuthnContextComparison', array(\SAML2\Constants::COMPARISON_EXACT, \SAML2\Constants::COMPARISON_MINIMUM, \SAML2\Constants::COMPARISON_MAXIMUM, \SAML2\Constants::COMPARISON_BETTER), \SAML2\Constants::COMPARISON_EXACT); $ar->setRequestedAuthnContext(array('AuthnContextClassRef' => $accr, 'Comparison' => $comp)); } self::addRedirectSign($spMetadata, $idpMetadata, $ar); return $ar; }
/** * Build an authentication request based on information in the metadata. * * @param SimpleSAML_Configuration $spMetadata The metadata of the service provider. * @param SimpleSAML_Configuration $idpMetadata The metadata of the identity provider. */ public static function buildAuthnRequest(SimpleSAML_Configuration $spMetadata, SimpleSAML_Configuration $idpMetadata) { $ar = new SAML2_AuthnRequest(); if ($spMetadata->hasValue('NameIDPolicy')) { $nameIdPolicy = $spMetadata->getString('NameIDPolicy', NULL); } else { $nameIdPolicy = $spMetadata->getString('NameIDFormat', SAML2_Const::NAMEID_TRANSIENT); } if ($nameIdPolicy !== NULL) { $ar->setNameIdPolicy(array('Format' => $nameIdPolicy, 'AllowCreate' => TRUE)); } $ar->setForceAuthn($spMetadata->getBoolean('ForceAuthn', FALSE)); $ar->setIsPassive($spMetadata->getBoolean('IsPassive', FALSE)); $protbind = $spMetadata->getValueValidate('ProtocolBinding', array(SAML2_Const::BINDING_HTTP_POST, SAML2_Const::BINDING_HOK_SSO, SAML2_Const::BINDING_HTTP_ARTIFACT, SAML2_Const::BINDING_HTTP_REDIRECT), SAML2_Const::BINDING_HTTP_POST); /* Shoaib - setting the appropriate binding based on parameter in sp-metadata defaults to HTTP_POST */ $ar->setProtocolBinding($protbind); $ar->setIssuer($spMetadata->getString('entityid')); $ar->setAssertionConsumerServiceIndex($spMetadata->getInteger('AssertionConsumerServiceIndex', NULL)); $ar->setAttributeConsumingServiceIndex($spMetadata->getInteger('AttributeConsumingServiceIndex', NULL)); if ($spMetadata->hasValue('AuthnContextClassRef')) { $accr = $spMetadata->getArrayizeString('AuthnContextClassRef'); $ar->setRequestedAuthnContext(array('AuthnContextClassRef' => $accr)); } self::addRedirectSign($spMetadata, $idpMetadata, $ar); return $ar; }
/** * Checks the authsource, if defined, for configuration values * to the LDAP server. Then sets up the LDAP connection for the * instance/object and stores everything in class members. * * @throws SimpleSAML_Error_Exception * @param array $config * @param $reserved */ public function __construct(&$config, $reserved) { parent::__construct($config, $reserved); // Change the class $title to match it's true name // This way if the class is extended the proper name is used $classname = get_class($this); $classname = explode('_', $classname); $this->title = 'ldap:' . end($classname) . ' : '; // Log the construction SimpleSAML\Logger::debug($this->title . 'Creating and configuring the filter.'); // If an authsource was defined (an not empty string)... if (isset($config['authsource']) && $config['authsource']) { // Log the authsource request SimpleSAML\Logger::debug($this->title . 'Attempting to get configuration values from authsource [' . $config['authsource'] . ']'); // Get the authsources file, which should contain the config $authsource = SimpleSAML_Configuration::getConfig('authsources.php'); // Verify that the authsource config exists if (!$authsource->hasValue($config['authsource'])) { throw new SimpleSAML_Error_Exception($this->title . 'Authsource [' . $config['authsource'] . '] defined in filter parameters not found in authsources.php'); } // Get just the specified authsource config values $authsource = $authsource->getConfigItem($config['authsource']); $authsource = $authsource->toArray(); // Make sure it is an ldap source // TODO: Support ldap:LDAPMulti, if possible if (@$authsource[0] != 'ldap:LDAP') { throw new SimpleSAML_Error_Exception($this->title . 'Authsource [' . $config['authsource'] . '] specified in filter parameters is not an ldap:LDAP type'); } // Build the authsource config $authconfig = array(); $authconfig['ldap.hostname'] = @$authsource['hostname']; $authconfig['ldap.enable_tls'] = @$authsource['enable_tls']; $authconfig['ldap.port'] = @$authsource['port']; $authconfig['ldap.timeout'] = @$authsource['timeout']; $authconfig['ldap.debug'] = @$authsource['debug']; $authconfig['ldap.basedn'] = @$authsource['search.enable'] ? @$authsource['search.base'] : null; $authconfig['ldap.username'] = @$authsource['search.enable'] ? @$authsource['search.username'] : null; $authconfig['ldap.password'] = @$authsource['search.enable'] ? @$authsource['search.password'] : null; $authconfig['ldap.username'] = @$authsource['priv.read'] ? @$authsource['priv.username'] : $authconfig['ldap.username']; $authconfig['ldap.password'] = @$authsource['priv.read'] ? @$authsource['priv.password'] : $authconfig['ldap.password']; // Only set the username attribute if the authsource specifies one attribute if (@$authsource['search.enable'] && is_array(@$authsource['search.attributes']) && count($authsource['search.attributes']) == 1) { $authconfig['attribute.username'] = reset($authsource['search.attributes']); } // Merge the authsource config with the filter config, // but have the filter config override the authsource config $config = array_merge($authconfig, $config); // Authsource complete SimpleSAML\Logger::debug($this->title . 'Retrieved authsource [' . $config['authsource'] . '] configuration values: ' . $this->var_export($authconfig)); } // Convert the config array to a config class, // that way we can verify type and define defaults. // Store in the instance in-case needed later, by a child class. $this->config = SimpleSAML_Configuration::loadFromArray($config, 'ldap:AuthProcess'); // Set all the filter values, setting defaults if needed $this->base_dn = $this->config->getArrayizeString('ldap.basedn', ''); $this->product = $this->config->getString('ldap.product', ''); // Cleanup the directory service, so that it is easier for // child classes to determine service name consistently $this->product = trim($this->product); $this->product = strtoupper($this->product); // Log the member values retrieved above SimpleSAML\Logger::debug($this->title . 'Configuration values retrieved;' . ' BaseDN: ' . $this->var_export($this->base_dn) . ' Product: ' . $this->var_export($this->product)); // Setup the attribute map which will be used to search LDAP $this->attribute_map = array('dn' => $this->config->getString('attribute.dn', 'distinguishedName'), 'groups' => $this->config->getString('attribute.groups', 'groups'), 'member' => $this->config->getString('attribute.member', 'member'), 'memberof' => $this->config->getString('attribute.memberof', 'memberOf'), 'name' => $this->config->getString('attribute.groupname', 'name'), 'type' => $this->config->getString('attribute.type', 'objectClass'), 'username' => $this->config->getString('attribute.username', 'sAMAccountName')); // Log the attribute map SimpleSAML\Logger::debug($this->title . 'Attribute map created: ' . $this->var_export($this->attribute_map)); // Setup the object type map which is used to determine a DNs' type $this->type_map = array('group' => $this->config->getString('type.group', 'group'), 'user' => $this->config->getString('type.user', 'user')); // Log the type map SimpleSAML\Logger::debug($this->title . 'Type map created: ' . $this->var_export($this->type_map)); }
/** * Build an authentication request based on information in the metadata. * * @param SimpleSAML_Configuration $spMetadata The metadata of the service provider. * @param SimpleSAML_Configuration $idpMetadata The metadata of the identity provider. */ public static function buildAuthnRequest(SimpleSAML_Configuration $spMetadata, SimpleSAML_Configuration $idpMetadata) { $ar = new SAML2_AuthnRequest(); if ($spMetadata->hasValue('NameIDPolicy')) { $nameIdPolicy = $spMetadata->getString('NameIDPolicy', NULL); } else { $nameIdPolicy = $spMetadata->getString('NameIDFormat', SAML2_Const::NAMEID_TRANSIENT); } if ($nameIdPolicy !== NULL) { $ar->setNameIdPolicy(array('Format' => $nameIdPolicy, 'AllowCreate' => TRUE)); } $ar->setIssuer($spMetadata->getString('entityid')); $ar->setDestination($idpMetadata->getString('SingleSignOnService')); $ar->setForceAuthn($spMetadata->getBoolean('ForceAuthn', FALSE)); $ar->setIsPassive($spMetadata->getBoolean('IsPassive', FALSE)); if ($spMetadata->hasValue('AuthnContextClassRef')) { $accr = $spMetadata->getArrayizeString('AuthnContextClassRef'); $ar->setRequestedAuthnContext(array('AuthnContextClassRef' => $accr)); } self::addRedirectSign($spMetadata, $idpMetadata, $ar); return $ar; }
/** * Get public key or certificate from metadata. * * This function implements a function to retrieve the public key or certificate from a metadata array. * * It will search for the following elements in the metadata: * - 'certData': The certificate as a base64-encoded string. * - 'certificate': A file with a certificate or public key in PEM-format. * - 'certFingerprint': The fingerprint of the certificate. Can be a single fingerprint, or an array of multiple * valid fingerprints. * * This function will return an array with these elements: * - 'PEM': The public key/certificate in PEM-encoding. * - 'certData': The certificate data, base64 encoded, on a single line. (Only present if this is a certificate.) * - 'certFingerprint': Array of valid certificate fingerprints. (Only present if this is a certificate.) * * @param \SimpleSAML_Configuration $metadata The metadata. * @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 Public key or certificate data, or NULL if no public key or certificate was found. * @throws \InvalidArgumentException If $metadata is not an instance of \SimpleSAML_Configuration, $required is not * boolean or $prefix is not a string. * @throws \SimpleSAML_Error_Exception If no private key is found in the metadata, or it was not possible to load * it. * * @author Andreas Solberg, UNINETT AS <*****@*****.**> * @author Olav Morken, UNINETT AS <*****@*****.**> * @author Lasse Birnbaum Jensen */ public static function loadPublicKey(\SimpleSAML_Configuration $metadata, $required = false, $prefix = '') { if (!is_bool($required) || !is_string($prefix)) { throw new \InvalidArgumentException('Invalid input parameters.'); } $keys = $metadata->getPublicKeys(null, false, $prefix); if ($keys !== null) { foreach ($keys as $key) { if ($key['type'] !== 'X509Certificate') { continue; } if ($key['signing'] !== true) { continue; } $certData = $key['X509Certificate']; $pem = "-----BEGIN CERTIFICATE-----\n" . chunk_split($certData, 64) . "-----END CERTIFICATE-----\n"; $certFingerprint = strtolower(sha1(base64_decode($certData))); return array('certData' => $certData, 'PEM' => $pem, 'certFingerprint' => array($certFingerprint)); } // no valid key found } elseif ($metadata->hasValue($prefix . 'certFingerprint')) { // we only have a fingerprint available $fps = $metadata->getArrayizeString($prefix . 'certFingerprint'); // normalize fingerprint(s) - lowercase and no colons foreach ($fps as &$fp) { assert('is_string($fp)'); $fp = strtolower(str_replace(':', '', $fp)); } // We can't build a full certificate from a fingerprint, and may as well return an array with only the //fingerprint(s) immediately. return array('certFingerprint' => $fps); } // no public key/certificate available if ($required) { throw new \SimpleSAML_Error_Exception('No public key / certificate found in metadata.'); } else { return null; } }